Merge remote-tracking branch 'origin/qds/dev'

Change-Id: I907e067abba640d27313ce03bc41326d3ed750f0
This commit is contained in:
Tim Jenssen
2024-08-06 19:04:41 +02:00
603 changed files with 41253 additions and 6404 deletions

View File

@@ -29,6 +29,7 @@ endif()
add_subdirectory(processlauncher)
if (WITH_QMLDESIGNER)
add_subdirectory(qml2puppet)
add_subdirectory(sqlitetester)
endif()
add_subdirectory(qtcdebugger) ## windows only
# add_subdirectory(qtcrashhandler)

View File

@@ -498,7 +498,6 @@ View3D {
targetNode: viewRoot.selectedNode
globalOrientation: viewRoot.globalOrientation
visible: viewRoot.selectedNode && viewRoot.transformMode === EditView3D.TransformMode.Move
&& overlayView.isActive
view3D: overlayView
dragHelper: gizmoDragHelper
property var propertyNames: ["position"]
@@ -523,7 +522,6 @@ View3D {
highlightOnHover: true
targetNode: viewRoot.selectedNode
visible: viewRoot.selectedNode && viewRoot.transformMode === EditView3D.TransformMode.Scale
&& overlayView.isActive
view3D: overlayView
dragHelper: gizmoDragHelper
property var propertyNames: ["scale"]
@@ -550,7 +548,6 @@ View3D {
targetNode: viewRoot.selectedNode
globalOrientation: viewRoot.globalOrientation
visible: viewRoot.selectedNode && viewRoot.transformMode === EditView3D.TransformMode.Rotate
&& overlayView.isActive
view3D: overlayView
dragHelper: gizmoDragHelper
property var propertyNames: ["eulerRotation"]
@@ -588,7 +585,6 @@ View3D {
Line3D {
id: pivotLine
visible: viewRoot.selectedNode && viewRoot.selectedNode !== viewRoot.multiSelectionNode
&& overlayView.isActive
name: "3D Edit View Pivot Line"
color: "#ddd600"

View File

@@ -989,6 +989,12 @@ bool MouseArea3D::eventFilter(QObject *, QEvent *event)
break;
}
case QEvent::HoverLeave: {
setHovering(false);
if (s_mouseGrab == this && !dragging())
s_mouseGrab = nullptr;
break;
}
default:
break;
}

View File

@@ -382,18 +382,20 @@ void NodeInstanceServer::reparentInstances(const QVector<ReparentContainer> &con
ServerNodeInstance instance = instanceForId(container.instanceId());
if (instance.isValid()) {
ServerNodeInstance newParent = instanceForId(container.newParentInstanceId());
PropertyName newParentProperty = container.newParentProperty();
if (!isInformationServer()) {
// Children of the component wraps are left out of the node tree to avoid
// incorrectly rendering them
if (newParent.isComponentWrap()) {
newParent = {};
newParentProperty.clear();
if (newParent.isValid()) {
PropertyName newParentProperty = container.newParentProperty();
if (!isInformationServer()) {
// Children of the component wraps are left out of the node tree to avoid
// incorrectly rendering them
if (newParent.isComponentWrap()) {
newParent = {};
newParentProperty.clear();
}
}
instance.reparent(instanceForId(container.oldParentInstanceId()),
container.oldParentProperty(),
newParent, newParentProperty);
}
instance.reparent(instanceForId(container.oldParentInstanceId()),
container.oldParentProperty(),
newParent, newParentProperty);
}
}
}

View File

@@ -173,6 +173,11 @@ bool ObjectNodeInstance::isPropertyChange() const
return false;
}
bool ObjectNodeInstance::isComposedEffect() const
{
return false;
}
bool ObjectNodeInstance::equalGraphicsItem(QGraphicsItem * /*item*/) const
{
return false;

View File

@@ -83,6 +83,7 @@ public:
virtual bool isLayoutable() const;
virtual bool isRenderable() const;
virtual bool isPropertyChange() const;
virtual bool isComposedEffect() const;
virtual bool equalGraphicsItem(QGraphicsItem *item) const;

View File

@@ -17,11 +17,13 @@
#include <QQmlProperty>
#include <private/qquickdesignersupport_p.h>
#ifdef QUICK3D_MODULE
#include <private/qquick3dnode_p.h>
#include <private/qquick3dviewport_p.h>
#include <private/qquick3dcamera_p.h>
#include <private/qquickdesignersupport_p.h>
#include <private/qquick3dperspectivecamera_p.h>
#endif
namespace QmlDesigner {
@@ -35,7 +37,7 @@ Qt5Import3dNodeInstanceServer::Qt5Import3dNodeInstanceServer(NodeInstanceClientI
#ifdef QUICK3D_MODULE
m_generalHelper = new Internal::GeneralHelper();
QObject::connect(m_generalHelper, &Internal::GeneralHelper::requestRender, this, [this]() {
startRenderTimer();
addCurrentNodeToRenderQueue();
});
#endif
}
@@ -51,7 +53,25 @@ void Qt5Import3dNodeInstanceServer::createScene(const CreateSceneCommand &comman
registerFonts(command.resourceUrl);
setTranslationLanguage(command.language);
setupScene(command);
startRenderTimer();
#ifdef QUICK3D_MODULE
QObject *obj = rootItem();
auto initView = [&obj, this](const QString &viewId, QQuick3DViewport *&view3D) {
QQmlProperty viewProp(obj, viewId, context());
QObject *viewObj = viewProp.read().value<QObject *>();
view3D = qobject_cast<QQuick3DViewport *>(viewObj);
};
initView("view3d", m_view3D);
initView("iconView3d", m_iconView3D);
if (m_view3D) {
QQmlProperty sceneNodeProp(obj, "sceneNode", context());
m_sceneNode = sceneNodeProp.read().value<QQuick3DNode *>();
m_defaultCameraRotation = m_view3D->camera()->rotation();
m_defaultCameraPosition = m_view3D->camera()->position();
addInitToRenderQueue();
}
#endif
}
void Qt5Import3dNodeInstanceServer::view3DAction([[maybe_unused]] const View3DActionCommand &command)
@@ -66,9 +86,14 @@ void Qt5Import3dNodeInstanceServer::view3DAction([[maybe_unused]] const View3DAc
QQmlProperty hProp(obj, "height", context());
wProp.write(size.width());
hProp.write(size.height());
if (auto camera = qobject_cast<QQuick3DPerspectiveCamera *>(m_view3D->camera())) {
if (size.width() >= size.height())
camera->setFieldOfViewOrientation(QQuick3DPerspectiveCamera::Vertical);
else
camera->setFieldOfViewOrientation(QQuick3DPerspectiveCamera::Horizontal);
}
resizeCanvasToRootItem();
startRenderTimer();
addCurrentNodeToRenderQueue();
}
break;
}
@@ -76,15 +101,80 @@ void Qt5Import3dNodeInstanceServer::view3DAction([[maybe_unused]] const View3DAc
QObject *obj = rootItem();
QQmlProperty sceneNodeProp(obj, "sceneNode", context());
auto sceneNode = sceneNodeProp.read().value<QQuick3DNode *>();
if (sceneNode) {
if (sceneNode && m_previewData.contains(m_currentNode)) {
PreviewData &data = m_previewData[m_currentNode];
QPointF delta = command.value().toPointF();
m_generalHelper->orbitCamera(m_view3D->camera(), m_view3D->camera()->eulerRotation(),
m_lookAt, {}, {float(delta.x()), float(delta.y()), 0.f});
m_keepRendering = true;
startRenderTimer();
data.lookAt, {}, {float(delta.x()), float(delta.y()), 0.f});
// Add 2 renders to keep render timer alive for smooth rotation
addCurrentNodeToRenderQueue(2);
data.cameraRotation = m_view3D->camera()->rotation();
data.cameraPosition = m_view3D->camera()->position();
}
break;
}
case View3DActionType::Import3dAddPreviewModel: {
const QVariantHash cmd = command.value().toHash();
const QString name = cmd["name"].toString();
const QString qmlName = cmd["qmlName"].toString();
const QString folder = cmd["folder"].toString();
bool isUpdate = m_previewData.contains(name);
if (isUpdate) {
QQuick3DNode *node = m_previewData[name].node;
if (node) {
node->setParentItem({});
node->setParent({});
node->deleteLater();
}
}
PreviewData &data = m_previewData[name];
data.name = name;
data.lookAt = {};
if (!isUpdate) {
data.cameraRotation = m_defaultCameraRotation;
data.cameraPosition = m_defaultCameraPosition;
}
QFileInfo fi(fileUrl().toLocalFile());
QString compPath = fi.absolutePath() + '/' + folder + '/' + qmlName + ".qml";
QQmlComponent comp(engine(), compPath, QQmlComponent::PreferSynchronous);
data.node = qobject_cast<QQuick3DNode *>(comp.create(context()));
if (data.node) {
engine()->setObjectOwnership(data.node, QJSEngine::CppOwnership);
data.node->setParentItem(m_sceneNode);
data.node->setParent(m_sceneNode);
addInitToRenderQueue();
if (m_currentNode == name)
addCurrentNodeToRenderQueue();
addIconToRenderQueue(name);
}
break;
}
case View3DActionType::Import3dSetCurrentPreviewModel: {
QString newName = command.value().toString();
if (m_previewData.contains(newName) && m_currentNode != newName) {
QQuick3DCamera *camera = m_view3D->camera();
if (m_previewData.contains(m_currentNode)) {
PreviewData &oldData = m_previewData[m_currentNode];
oldData.cameraPosition = camera->position();
oldData.cameraRotation = camera->rotation();
}
m_currentNode = newName;
const PreviewData &newData = m_previewData[m_currentNode];
camera->setPosition(newData.cameraPosition);
camera->setRotation(newData.cameraRotation);
addInitToRenderQueue();
addCurrentNodeToRenderQueue();
}
break;
}
default:
break;
}
@@ -93,8 +183,10 @@ void Qt5Import3dNodeInstanceServer::view3DAction([[maybe_unused]] const View3DAc
void Qt5Import3dNodeInstanceServer::startRenderTimer()
{
if (m_keepRendering && timerMode() == TimerMode::NormalTimer)
#ifdef QUICK3D_MODULE
if (!m_renderQueue.isEmpty() && timerMode() == TimerMode::NormalTimer)
return;
#endif
NodeInstanceServer::startRenderTimer();
}
@@ -102,16 +194,52 @@ void Qt5Import3dNodeInstanceServer::startRenderTimer()
void Qt5Import3dNodeInstanceServer::cleanup()
{
#ifdef QUICK3D_MODULE
delete m_previewNode;
for (const PreviewData &data : std::as_const(m_previewData))
delete data.node;
m_previewData.clear();
delete m_generalHelper;
#endif
}
void Qt5Import3dNodeInstanceServer::finish()
#ifdef QUICK3D_MODULE
void Qt5Import3dNodeInstanceServer::addInitToRenderQueue()
{
cleanup();
startRenderTimer();
// "Init" render is simply a rendering of the entire scene without producing any images.
// This is done to make sure everything is initialized properly for subsequent renders.
if (m_renderQueue.isEmpty() || m_renderQueue[0] != RenderType::Init)
m_renderQueue.prepend(RenderType::Init);
}
void Qt5Import3dNodeInstanceServer::addCurrentNodeToRenderQueue(int count)
{
startRenderTimer();
int remaining = count;
for (const RenderType &type : std::as_const(m_renderQueue)) {
if (type == RenderType::CurrentNode && --remaining <= 0)
return;
}
int index = !m_renderQueue.isEmpty() && m_renderQueue[0] == RenderType::Init ? 1 : 0;
while (remaining > 0) {
m_renderQueue.insert(index, RenderType::CurrentNode);
--remaining;
}
}
void Qt5Import3dNodeInstanceServer::addIconToRenderQueue(const QString &assetName)
{
startRenderTimer();
m_generateIconQueue.append(assetName);
m_renderQueue.append(RenderType::NextIcon);
}
#endif
void Qt5Import3dNodeInstanceServer::collectItemChangesAndSendChangeCommands()
{
static bool inFunction = false;
@@ -133,75 +261,113 @@ void Qt5Import3dNodeInstanceServer::collectItemChangesAndSendChangeCommands()
void Qt5Import3dNodeInstanceServer::render()
{
#ifdef QUICK3D_MODULE
++m_renderCount;
if (m_renderQueue.isEmpty() || !m_view3D || !m_iconView3D)
return;
if (m_renderCount == 1) {
QObject *obj = rootItem();
QQmlProperty viewProp(obj, "view3d", context());
QObject *viewObj = viewProp.read().value<QObject *>();
m_view3D = qobject_cast<QQuick3DViewport *>(viewObj);
if (m_view3D) {
QQmlProperty sceneModelNameProp(obj, "sceneModelName", context());
QQmlProperty sceneNodeProp(obj, "sceneNode", context());
auto sceneNode = sceneNodeProp.read().value<QQuick3DNode *>();
if (sceneNode) {
QString sceneModelName = sceneModelNameProp.read().toString();
QFileInfo fi(fileUrl().toLocalFile());
QString compPath = fi.absolutePath() + '/' + sceneModelName + ".qml";
QQmlComponent comp(engine(), compPath, QQmlComponent::PreferSynchronous);
m_previewNode = qobject_cast<QQuick3DNode *>(comp.create(context()));
if (m_previewNode) {
engine()->setObjectOwnership(m_previewNode, QJSEngine::CppOwnership);
m_previewNode->setParentItem(sceneNode);
m_previewNode->setParent(sceneNode);
RenderType currentType = m_renderQueue.takeFirst();
PreviewData data;
QQuick3DViewport *currentView = m_view3D;
QVector3D cameraPosition = m_view3D->camera()->position();
QQuaternion cameraRotation = m_view3D->camera()->rotation();
if (currentType == RenderType::Init) {
m_view3D->setVisible(true);
m_iconView3D->setVisible(true);
} else {
auto showNode = [this](const QString &name) {
for (const PreviewData &data : std::as_const(m_previewData))
data.node->setVisible(data.name == name);
};
if (currentType == RenderType::CurrentNode) {
if (m_previewData.contains(m_currentNode)) {
showNode(m_currentNode);
data = m_previewData[m_currentNode];
m_view3D->setVisible(true);
m_iconView3D->setVisible(false);
}
} else if (currentType == RenderType::NextIcon) {
if (!m_generateIconQueue.isEmpty()) {
const QString assetName = m_generateIconQueue.takeFirst();
if (m_previewData.contains(assetName)) {
m_view3D->setVisible(false);
m_iconView3D->setVisible(true);
showNode(assetName);
data = m_previewData[assetName];
m_refocus = true;
currentView = m_iconView3D;
currentView->camera()->setRotation(m_defaultCameraRotation);
currentView->camera()->setPosition(m_defaultCameraPosition);
}
}
}
if (m_refocus && data.node) {
m_generalHelper->calculateBoundsAndFocusCamera(currentView->camera(), data.node,
currentView, 1050, false, data.lookAt,
data.extents);
if (currentType == RenderType::CurrentNode) {
auto getExtentStr = [&data](int idx) -> QString {
int prec = 0;
float val = data.extents[idx];
if (val == 0.f) {
prec = 1;
} else {
while (val < 100.f) {
++prec;
val *= 10.f;
}
}
// Strip unnecessary zeroes after decimal separator
if (prec > 0) {
QString checkStr = QString::number(data.extents[idx], 'f', prec);
while (prec > 0 && (checkStr.last(1) == "0" || checkStr.last(1) == ".")) {
--prec;
checkStr.chop(1);
}
}
QString retval = QLocale().toString(data.extents[idx], 'f', prec);
return retval;
};
QQmlProperty extentsProp(rootItem(), "extents", context());
extentsProp.write(tr("Dimensions: %1 x %2 x %3").arg(getExtentStr(0))
.arg(getExtentStr(1))
.arg(getExtentStr(2)));
}
}
}
// Render scene once to ensure geometries are intialized so bounds calculations work correctly
if (m_renderCount == 2 && m_view3D) {
QVector3D extents;
m_generalHelper->calculateBoundsAndFocusCamera(m_view3D->camera(), m_previewNode,
m_view3D, 1050, false, m_lookAt, extents);
auto getExtentStr = [&extents](int idx) -> QString {
int prec = 0;
float val = extents[idx];
while (val < 100.f) {
++prec;
val *= 10.f;
}
// Strip unnecessary zeroes after decimal separator
if (prec > 0) {
QString checkStr = QString::number(extents[idx], 'f', prec);
while (prec > 0 && (checkStr.last(1) == "0" || checkStr.last(1) == ".")) {
--prec;
checkStr.chop(1);
}
}
QString retval = QLocale().toString(extents[idx], 'f', prec);
return retval;
};
QQmlProperty extentsProp(rootItem(), "extents", context());
extentsProp.write(tr("Dimensions: %1 x %2 x %3").arg(getExtentStr(0))
.arg(getExtentStr(1))
.arg(getExtentStr(2)));
}
rootNodeInstance().updateDirtyNodeRecursive();
currentView->update();
QImage renderImage = grabWindow();
if (m_renderCount >= 2) {
ImageContainer imgContainer(0, renderImage, m_renderCount);
nodeInstanceClient()->handlePuppetToCreatorCommand(
{PuppetToCreatorCommand::Import3DPreviewImage,
QVariant::fromValue(imgContainer)});
if (!m_keepRendering)
slowDownRenderTimer();
m_keepRendering = false;
if (currentType == RenderType::Init) {
m_refocus = true;
} else if (currentType == RenderType::CurrentNode) {
if (m_previewData.contains(m_currentNode)) {
ImageContainer imgContainer(0, renderImage, 1000000);
nodeInstanceClient()->handlePuppetToCreatorCommand(
{PuppetToCreatorCommand::Import3DPreviewImage, QVariant::fromValue(imgContainer)});
}
} else if (currentType == RenderType::NextIcon) {
if (!data.name.isEmpty()) {
QSizeF iconSize = m_iconView3D->size();
QImage iconImage = renderImage.copy(0, 0, iconSize.width(), iconSize.height());
static qint32 renderId = 1000001;
ImageContainer imgContainer(0, iconImage, ++renderId);
QVariantList cmdData;
cmdData.append(data.name);
cmdData.append(QVariant::fromValue(imgContainer));
nodeInstanceClient()->handlePuppetToCreatorCommand(
{PuppetToCreatorCommand::Import3DPreviewIcon, cmdData});
}
m_refocus = true;
currentView->camera()->setRotation(cameraRotation);
currentView->camera()->setPosition(cameraPosition);
}
if (m_renderQueue.isEmpty())
slowDownRenderTimer();
#else
slowDownRenderTimer();
#endif

View File

@@ -8,9 +8,12 @@
#endif
#include "qt5nodeinstanceserver.h"
#ifdef QUICK3D_MODULE
#include "generalhelper.h"
QT_BEGIN_NAMESPACE
class QQuick3DNode;
QT_END_NAMESPACE
#endif
namespace QmlDesigner {
@@ -33,17 +36,42 @@ protected:
void startRenderTimer() override;
private:
void finish();
void cleanup();
int m_renderCount = 0;
bool m_keepRendering = false;
#ifdef QUICK3D_MODULE
void addInitToRenderQueue();
void addCurrentNodeToRenderQueue(int count = 1);
void addIconToRenderQueue(const QString &assetName);
QQuick3DViewport *m_view3D = nullptr;
QQuick3DViewport *m_iconView3D = nullptr;
Internal::GeneralHelper *m_generalHelper = nullptr;
QQuick3DNode *m_previewNode = nullptr;
QVector3D m_lookAt;
struct PreviewData
{
QString name;
QVector3D lookAt;
QVector3D extents;
QQuick3DNode *node = {};
QQuaternion cameraRotation;
QVector3D cameraPosition;
};
QHash<QString, PreviewData> m_previewData;
enum class RenderType
{
Init,
CurrentNode,
NextIcon
};
QList<RenderType> m_renderQueue;
bool m_refocus = false;
QString m_currentNode;
QQuick3DNode *m_sceneNode = {};
QStringList m_generateIconQueue;
QQuaternion m_defaultCameraRotation;
QVector3D m_defaultCameraPosition;
#endif
};

View File

@@ -1377,6 +1377,7 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView(
// Key number is selected so that it is unlikely to conflict other ImageContainer use.
ImageContainer imgContainer(cmd.instanceId(), {}, 2100000001 + cmd.instanceId());
imgContainer.setImage(renderImage);
imgContainer.setRequestId(cmd.requestId());
// send the rendered image to creator process
nodeInstanceClient()->handlePuppetToCreatorCommand(
@@ -1472,6 +1473,7 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode2DImageView(const Reques
if (!renderImage.isNull()) {
imgContainer.setImage(renderImage);
imgContainer.setRequestId(cmd.requestId());
// send the rendered image to creator process
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::RenderModelNodePreviewImage,

View File

@@ -89,6 +89,7 @@ void Qt5NodeInstanceServer::initializeView()
m_viewData.renderControl = new QQuickRenderControl;
m_viewData.window = new QQuickWindow(m_viewData.renderControl);
m_viewData.window->setColor(Qt::transparent);
setPipelineCacheConfig(m_viewData.window);
m_viewData.renderControl->initialize();
m_qmlEngine = new QQmlEngine;
@@ -379,9 +380,11 @@ QImage Qt5NodeInstanceServer::grabRenderControl([[maybe_unused]] RenderViewData
QRhiReadbackResult readResult;
readResult.completed = [&] {
readCompleted = true;
QImage wrapperImage(reinterpret_cast<const uchar *>(readResult.data.constData()),
readResult.pixelSize.width(), readResult.pixelSize.height(),
QImage::Format_RGBA8888_Premultiplied);
QImage wrapperImage(
reinterpret_cast<const uchar *>(readResult.data.constData()),
readResult.pixelSize.width(),
readResult.pixelSize.height(),
QImage::Format_RGBA8888_Premultiplied);
if (viewData.rhi->isYUpInFramebuffer())
renderImage = wrapperImage.mirrored();
else

View File

@@ -239,7 +239,7 @@ void Qt5RenderNodeInstanceServer::changePropertyValues(const ChangeValuesCommand
instance = instanceForObject(targetObject);
}
if (instance.hasParent() && instance.propertyNames().contains("_isEffectItem"))
if (instance.hasParent() && instance.isComposedEffect())
makeDirtyRecursive(instance.parent());
} else if (container.isDynamic() && hasInstanceForId(container.instanceId())) {
// Changes to dynamic properties are not always noticed by normal signal spy mechanism
@@ -263,13 +263,68 @@ void Qt5RenderNodeInstanceServer::changePropertyBindings(const ChangeBindingsCom
}
}
void Qt5RenderNodeInstanceServer::makeDirtyRecursive(const ServerNodeInstance &instance)
void Qt5RenderNodeInstanceServer::reparentInstances(const ReparentInstancesCommand &command)
{
const QList<ServerNodeInstance> children = instance.childItems();
for (const auto &child : children) {
m_dirtyInstanceSet.insert(child);
makeDirtyRecursive(child);
ServerNodeInstance effectNode;
ServerNodeInstance oldParent;
const QVector<ReparentContainer> containers = command.reparentInstances();
for (const ReparentContainer &container : containers) {
if (hasInstanceForId(container.instanceId())) {
ServerNodeInstance instance = instanceForId(container.instanceId());
if (instance.isComposedEffect()) {
oldParent = instance.parent();
effectNode = instance;
break;
}
}
}
Qt5NodeInstanceServer::reparentInstances(command);
if (oldParent.isValid())
makeDirtyRecursive(oldParent);
if (effectNode.isValid()) {
ServerNodeInstance newParent = effectNode.parent();
if (newParent.isValid()) {
// This is a hack to work around Image elements sometimes losing their textures when
// used as children of an effect. Toggling the visibility of the affected node seems
// to be the only way to fix this issue.
// Note that just marking the children's visibility dirty doesn't fix this issue.
QQuickItem *parentItem = newParent.rootQuickItem();
if (parentItem && parentItem->isVisible()) {
parentItem->setVisible(false);
parentItem->setVisible(true);
}
}
}
}
void Qt5RenderNodeInstanceServer::removeInstances(const RemoveInstancesCommand &command)
{
ServerNodeInstance oldParent;
const QVector<qint32> ids = command.instanceIds();
for (qint32 id : ids) {
if (hasInstanceForId(id)) {
ServerNodeInstance instance = instanceForId(id);
if (instance.isComposedEffect()) {
oldParent = instance.parent();
break;
}
}
}
Qt5NodeInstanceServer::removeInstances(command);
if (oldParent.isValid())
makeDirtyRecursive(oldParent);
}
void Qt5RenderNodeInstanceServer::makeDirtyRecursive(const ServerNodeInstance &instance)
{
m_dirtyInstanceSet.insert(instance);
const QList<ServerNodeInstance> children = instance.childItems();
for (const auto &child : children)
makeDirtyRecursive(child);
}
} // namespace QmlDesigner

View File

@@ -19,6 +19,8 @@ public:
void removeSharedMemory(const RemoveSharedMemoryCommand &command) override;
void changePropertyValues(const ChangeValuesCommand &command) override;
void changePropertyBindings(const ChangeBindingsCommand &command) override;
void reparentInstances(const ReparentInstancesCommand &command) override;
void removeInstances(const RemoveInstancesCommand &command) override;
protected:
void collectItemChangesAndSendChangeCommands() override;

View File

@@ -150,8 +150,6 @@ void QuickItemNodeInstance::initialize(const ObjectNodeInstance::Pointer &object
if (instanceId() == 0)
nodeInstanceServer()->setRootItem(quickItem());
else
quickItem()->setParentItem(nodeInstanceServer()->rootItem());
ObjectNodeInstance::initialize(objectNodeInstance, flags);
}
@@ -181,6 +179,10 @@ void QuickItemNodeInstance::doComponentComplete()
if (contentItemProperty.isValid())
m_contentItem = contentItemProperty.read().value<QQuickItem*>();
QQmlProperty composedEffectProperty(quickItem(), "_isEffectItem", engine());
if (composedEffectProperty.isValid())
m_isComposedEffect = true;
quickItem()->update();
}
@@ -490,6 +492,11 @@ bool QuickItemNodeInstance::isRenderable() const
return quickItem() && (!s_unifiedRenderPath || isRootNodeInstance());
}
bool QuickItemNodeInstance::isComposedEffect() const
{
return m_isComposedEffect;
}
QList<ServerNodeInstance> QuickItemNodeInstance::stateInstances() const
{
QList<ServerNodeInstance> instanceList;

View File

@@ -75,6 +75,7 @@ public:
bool isMovable() const override;
bool isQuickItem() const override;
bool isRenderable() const override;
bool isComposedEffect() const override;
QList<ServerNodeInstance> stateInstances() const override;
@@ -123,6 +124,7 @@ private: //variables
double m_width;
double m_height;
bool m_hidden = false;
bool m_isComposedEffect = false;
static bool s_createEffectItem;
static bool s_unifiedRenderPath;
};

View File

@@ -158,6 +158,11 @@ bool ServerNodeInstance::isComponentWrap() const
return m_nodeInstance->isComponentWrap();
}
bool ServerNodeInstance::isComposedEffect() const
{
return m_nodeInstance->isComposedEffect();
}
QQuickItem *ServerNodeInstance::contentItem() const
{
return m_nodeInstance->contentItem();

View File

@@ -54,6 +54,7 @@ public:
friend class Qt5BakeLightsNodeInstanceServer;
friend class Qt5PreviewNodeInstanceServer;
friend class Qt5CapturePreviewNodeInstanceServer;
friend class Qt5RenderNodeInstanceServer;
friend class Qt5TestNodeInstanceServer;
friend class QHash<qint32, ServerNodeInstance>;
friend QHashValueType qHash(const ServerNodeInstance &instance);
@@ -160,6 +161,7 @@ public:
bool holdsGraphical() const;
bool isComponentWrap() const;
bool isComposedEffect() const;
QQuickItem *contentItem() const;

View File

@@ -124,13 +124,13 @@ void QmlPuppet::initQmlRunner()
QString options = m_coreApp->arguments().at(4);
Import3D::import3D(sourceAsset, outDir, options);
} else {
startCrashpad(QCoreApplication::applicationDirPath()
+ '/' + RELATIVE_LIBEXEC_PATH, crashReportsPath());
new QmlDesigner::Qt5NodeInstanceClientProxy(m_coreApp.get());
}
startCrashpad(QCoreApplication::applicationDirPath()
+ '/' + RELATIVE_LIBEXEC_PATH, crashReportsPath());
new QmlDesigner::Qt5NodeInstanceClientProxy(m_coreApp.get());
#if defined(Q_OS_WIN) && defined(QT_NO_DEBUG)
SetErrorMode(SEM_NOGPFAULTERRORBOX); //We do not want to see any message boxes
#endif

View File

@@ -90,19 +90,7 @@ static QQuickDesignerSupport::PropertyNameList propertyNameListForWritableProper
QMetaType jsType = QMetaType::fromType<QJSValue>();
int userType = value.userType();
//qDebug() << jsType << jsType.id();
//qDebug() << "tp" << value.typeName();
//qDebug() << "ut" << userType;
if (userType == jsType.id()) {
qDebug() << "js value found";
//QJSValue jsValue = value.value<QJSValue>(); //crashes
//qDebug() << jsValue.isObject();
//qDebug() << jsValue.isQObject();
} else {
if (userType != jsType.id()) {
valueType->setValue(value);
propertyNameList.append(propertyNameListForWritablePropertiesInternal(valueType,
baseName + QQuickDesignerSupport::PropertyName(metaProperty.name())
@@ -175,36 +163,12 @@ static QQuickDesignerSupport::PropertyNameList allPropertyNamesFork(QObject *obj
propertyNameList.append(baseName + QQuickDesignerSupport::PropertyName(metaProperty.name()));
const QJsonValue jsonValue = value.toJsonValue();
if (!jsonValue.isNull()) {
qDebug() << "llokhere";
qDebug() << "name" << metaProperty.name();
qDebug() << "value" << value;
qDebug() << jsonValue;
}
if (value.isValid() && jsonValue.isNull()) {
//qDebug() << "llokhere crash";
//qDebug() << "name" << metaProperty.name();
//qDebug() << "value" << value;
//qDebug() << jsonValue;
QMetaType jsType = QMetaType::fromType<QJSValue>();
int userType = value.userType();
//qDebug() << jsType << jsType.id();
//qDebug() << "tp" << value.typeName();
//qDebug() << "ut" << userType;
if (userType == jsType.id()) {
qDebug() << "js value found";
//QJSValue jsValue = value.value<QJSValue>(); //crashes
//qDebug() << jsValue.isObject();
//qDebug() << jsValue.isQObject();
} else {
if (userType != jsType.id()) {
valueType->setValue(value);
propertyNameList.append(allPropertyNamesFork(valueType,
baseName

View File

@@ -0,0 +1,37 @@
cmake_minimum_required(VERSION 3.16)
# standalone build
if (NOT QT_CREATOR_API_DEFINED)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../cmake")
project(sqlitetester)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(DESTINATION DESTINATION .)
include(QtCreatorIDEBranding)
include(QtCreatorAPI)
qtc_handle_compiler_cache_support()
find_package(Qt6
COMPONENTS Core Gui Widgets
REQUIRED
)
endif()
add_qtc_executable(sqlitetester
${DESTINATION}
CONDITION WINDOWS AND BUILD_DESIGNSTUDIO
DEPENDS
Sqlite
Qt::Core Qt::Widgets
INCLUDES
${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
SOURCES
main.cpp
)

View File

@@ -0,0 +1,137 @@
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
#include <sqlitedatabase.h>
#include <sqlitelibraryinitializer.h>
#include <QApplication>
#include <QWidget>
#include <QVBoxLayout>
#include <QLineEdit>
#include <QPushButton>
#include <QTextBrowser>
#include <QTemporaryFile>
#include <QDir>
#include <windows.h>
class DatabaseApp : public QWidget {
Q_OBJECT
public:
DatabaseApp(QWidget *parent = nullptr);
private slots:
void onSetDirectoryClicked();
void createDatabase(const QString &dirPath);
private:
void deleteFileIfExist(const QString &filePath);
void logMessage(const QString &message);
void logDetailedWindowsError();
QLineEdit *directoryLineEdit;
QTextBrowser *logBrowser;
QString databaseDirectory;
};
DatabaseApp::DatabaseApp(QWidget *parent) : QWidget(parent) {
QVBoxLayout *layout = new QVBoxLayout(this);
directoryLineEdit = new QLineEdit(this);
directoryLineEdit->setPlaceholderText("Enter database directory path");
layout->addWidget(directoryLineEdit);
QPushButton *setDirectoryButton = new QPushButton("Set Directory and Create Database", this);
layout->addWidget(setDirectoryButton);
logBrowser = new QTextBrowser(this);
layout->addWidget(logBrowser);
connect(setDirectoryButton, &QPushButton::clicked, this, &DatabaseApp::onSetDirectoryClicked);
}
void DatabaseApp::onSetDirectoryClicked() {
QString dirPath = directoryLineEdit->text();
if (dirPath.isEmpty()) {
logMessage("Directory path is empty.");
return;
}
QDir dir(dirPath);
if (!dir.exists()) {
logMessage("Directory does not exist.");
return;
}
QTemporaryFile tempFile(dirPath + "/tempfileXXXXXX");
if (!tempFile.open()) {
logMessage("Cannot create temporary file in the directory: " + tempFile.errorString());
logDetailedWindowsError();
return;
}
tempFile.close();
createDatabase(dirPath);
}
void DatabaseApp::deleteFileIfExist(const QString &filePath) {
if (QFile::exists(filePath)) {
if (!QFile::remove(filePath)) {
logMessage(QString("Failed to delete existing file %1 before creating database").arg(filePath));
logDetailedWindowsError();
return;
}
}
}
void DatabaseApp::createDatabase(const QString &dirPath) {
databaseDirectory = dirPath;
QString dbPath = dirPath + "/mysqlitetester.db";
dbPath.replace("\\", "/");
deleteFileIfExist(dbPath);
try {
Sqlite::Database database{Utils::PathString{dbPath}};
} catch (const Sqlite::Exception &e) {
logMessage(QString("Cannot create %1: %2").arg(dbPath, QString::fromUtf8(e.what())));
logDetailedWindowsError();
}
deleteFileIfExist(dbPath);
logMessage(QString("Test with %1 was successful.").arg(dbPath));
}
void DatabaseApp::logMessage(const QString &message) {
logBrowser->append(message);
}
void DatabaseApp::logDetailedWindowsError() {
DWORD errorCode = GetLastError();
if (errorCode != 0) {
LPVOID errorMsg;
DWORD size = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR)&errorMsg, 0, NULL);
if (size) {
QString detailedMessage = QString::fromWCharArray((LPWSTR)errorMsg, size);
logMessage("Windows error: " + detailedMessage);
LocalFree(errorMsg);
}
}
}
int main(int argc, char *argv[]) {
Sqlite::LibraryInitializer::initialize();
QApplication app(argc, argv);
DatabaseApp window;
window.setWindowTitle("SQLite Write Database Tester");
window.resize(400, 300);
window.show();
return app.exec();
}
#include "main.moc"