From 739bda82df13a8efe9c703c414c5a281e9b9c7e2 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 6 Aug 2024 16:54:16 +0300 Subject: [PATCH 001/193] QmlDesigner: Remove unnecessary namespace Change-Id: I1cefbe295871f23c34477d71d8632b641737f055 Reviewed-by: Mahmoud Badri --- .../components/materialeditor/materialeditorview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index 2b6d321b57f..cfbf0aaf41e 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -1136,7 +1136,7 @@ void MaterialEditorView::nodeRemoved([[maybe_unused]] const ModelNode &removedNo m_textureAboutToBeRemoved = false; } -void QmlDesigner::MaterialEditorView::highlightSupportedProperties(bool highlight) +void MaterialEditorView::highlightSupportedProperties(bool highlight) { if (!m_selectedMaterial.isValid()) return; From 0d259984937b1d945e775fa9c45a0eded21f6935 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 6 Aug 2024 16:49:24 +0200 Subject: [PATCH 002/193] QmlDesigner: Fix view attachment Originally attaching and detaching should be checked. But because the design document has not architecture, it attaches and detaches randomly. So this check prevents double attachments or detachments. Change-Id: I4f8a69d54604c40c1e0fd3a060f3344b54000d71 Reviewed-by: Tim Jenssen --- src/plugins/qmldesigner/designercore/model/model.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 8d06929f119..2fc8ac6cf77 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -898,11 +898,15 @@ void ModelPrivate::attachView(AbstractView *view) m_viewList.append(view); - view->modelAttached(m_model); + if (!view->isAttached()) + view->modelAttached(m_model); } void ModelPrivate::detachView(AbstractView *view, bool notifyView) { + if (!view->isAttached()) + return; + if (notifyView) view->modelAboutToBeDetached(m_model); m_viewList.removeOne(view); From 9f55f5e63ae385f0a39ff2b17cf5cef05afb3e9c Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 7 Aug 2024 12:50:13 +0200 Subject: [PATCH 003/193] QmlDesigner: Detach/attach [non] shown views Originally all views were enabled. With the dock widget design views could be disabled. But in the background they still got notifications. The view will be detached if they are disabled and will be attached if they are enabled again. Task-number: QDS-13325 Change-Id: If755627a760896fc430c71200bb6a23fce245216 Reviewed-by: Tim Jenssen --- .../components/componentcore/viewmanager.cpp | 43 ++++++++++++++++++- .../components/componentcore/viewmanager.h | 5 +++ .../components/edit3d/edit3dview.h | 1 + .../components/formeditor/formeditorview.h | 1 + .../stateseditor/stateseditorview.h | 1 + .../components/texteditor/texteditorview.h | 1 + .../designercore/include/abstractview.h | 26 ++++++++++- .../designercore/model/abstractview.cpp | 18 ++++---- .../qmldesigner/designercore/model/model.cpp | 6 ++- src/plugins/qmldesigner/designmodewidget.cpp | 12 +++++- src/plugins/qmldesigner/qmldesignerplugin.cpp | 3 ++ 11 files changed, 101 insertions(+), 16 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp index 3af7b99af13..486d22d9273 100644 --- a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp @@ -125,6 +125,8 @@ ViewManager::ViewManager(AsynchronousImageCache &imageCache, designModeWidget->showDockWidget("TextEditor"); }); + registerViewActions(); + registerNanotraceActions(); } @@ -282,6 +284,40 @@ void ViewManager::registerNanotraceActions() } } +void ViewManager::registerViewActions() +{ + for (auto view : views()) { + if (view->hasWidget()) + registerViewAction(*view); + } +} + +void ViewManager::registerViewAction(AbstractView &view) +{ + auto viewAction = view.action(); + viewAction->setCheckable(true); + QObject::connect(view.action(), + &AbstractViewAction::viewCheckedChanged, + [&](bool checkable, AbstractView &view) { + if (checkable) + enableView(view); + else + disableView(view); + }); +} + +void ViewManager::enableView(AbstractView &view) +{ + if (auto model = currentModel()) + model->attachView(&view); +} + +void ViewManager::disableView(AbstractView &view) +{ + if (auto model = currentModel()) + model->detachView(&view); +} + void ViewManager::resetPropertyEditorView() { d->propertyEditorView.resetView(); @@ -488,7 +524,10 @@ void ViewManager::qmlJSEditorContextHelp(const Core::IContext::HelpCallback &cal Model *ViewManager::currentModel() const { - return currentDesignDocument()->currentModel(); + if (auto document = currentDesignDocument()) + return document->currentModel(); + + return nullptr; } Model *ViewManager::documentModel() const @@ -530,6 +569,7 @@ void ViewManager::enableStandardViews() void ViewManager::jumpToCodeInTextEditor(const ModelNode &modelNode) { + d->textEditorView.action()->setChecked(true); ADS::DockWidget *dockWidget = qobject_cast( d->textEditorView.widgetInfo().widget->parentWidget()); if (dockWidget) @@ -540,6 +580,7 @@ void ViewManager::jumpToCodeInTextEditor(const ModelNode &modelNode) void ViewManager::addView(std::unique_ptr &&view) { d->additionalViews.push_back(std::move(view)); + registerViewAction(*d->additionalViews.back()); } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.h b/src/plugins/qmldesigner/components/componentcore/viewmanager.h index 65a0155ae2e..7047ecdd01d 100644 --- a/src/plugins/qmldesigner/components/componentcore/viewmanager.h +++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.h @@ -113,6 +113,11 @@ private: // functions void registerNanotraceActions(); + void registerViewActions(); + void registerViewAction(AbstractView &view); + void enableView(AbstractView &view); + void disableView(AbstractView &view); + private: // variables std::unique_ptr d; }; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h index 9e9bce13587..f0ebc69dddb 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h @@ -56,6 +56,7 @@ public: Edit3DView(ExternalDependenciesInterface &externalDependencies); + bool hasWidget() const override { return true; } WidgetInfo widgetInfo() override; Edit3DWidget *edit3DWidget() const; diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.h b/src/plugins/qmldesigner/components/formeditor/formeditorview.h index d3c6cb21dbd..3b5e0980988 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.h @@ -79,6 +79,7 @@ public: void currentStateChanged(const ModelNode &node) override; // FormEditorView + bool hasWidget() const override { return true; } WidgetInfo widgetInfo() override; FormEditorWidget *formEditorWidget(); diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h index 919518683ea..3f9b9a4562d 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h @@ -77,6 +77,7 @@ public: void instancesPreviewImageChanged(const QVector &nodeList) override; + bool hasWidget() const override { return true; } WidgetInfo widgetInfo() override; void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion) override; diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorview.h b/src/plugins/qmldesigner/components/texteditor/texteditorview.h index 35a33863fab..c87d212efd8 100644 --- a/src/plugins/qmldesigner/components/texteditor/texteditorview.h +++ b/src/plugins/qmldesigner/components/texteditor/texteditorview.h @@ -48,6 +48,7 @@ public: void documentMessagesChanged(const QList &errors, const QList &warnings) override; // TextEditorView + bool hasWidget() const override { return true; } WidgetInfo widgetInfo() override; void qmlJSEditorContextHelp(const Core::IContext::HelpCallback &callback) const; diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index b5fd8e12433..8b105fe0f4f 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -8,6 +8,9 @@ #include "qmldesignercorelib_global.h" #include +#include + +#include #include #include @@ -57,6 +60,20 @@ public: DesignerWidgetFlags widgetFlags = DesignerWidgetFlags::DisableOnError; }; +class QMLDESIGNERCORE_EXPORT AbstractViewAction : public QAction +{ + Q_OBJECT + +public: + AbstractViewAction(class AbstractView &view); + +signals: + void viewCheckedChanged(bool checkable, AbstractView &view); + +private: + AbstractView &m_view; +}; + class QMLDESIGNERCORE_EXPORT AbstractView : public QObject { Q_OBJECT @@ -73,6 +90,7 @@ public: AbstractView(ExternalDependenciesInterface &externalDependencies) : m_externalDependencies{externalDependencies} + , m_action{Utils::makeUniqueObjectPtr(*this)} {} ~AbstractView() override; @@ -265,8 +283,11 @@ public: using OperationBlock = std::function; bool executeInTransaction(const QByteArray &identifier, const OperationBlock &lambda); - bool isEnabled() const; - void setEnabled(bool b); + bool isEnabled() const { return m_enabled && (hasWidget() ? m_action->isChecked() : true); } + + void setEnabled(bool enabled) { m_enabled = enabled; } + + AbstractViewAction *action() const { return m_action.get(); } ExternalDependenciesInterface &externalDependencies() const { return m_externalDependencies; } @@ -303,6 +324,7 @@ private: QPointer m_model; ExternalDependenciesInterface &m_externalDependencies; + Utils::UniqueObjectPtr m_action; bool m_enabled = true; bool m_isBlockingNotifications = false; }; diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index 75c15c72738..67e7de6f552 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -622,16 +622,6 @@ bool AbstractView::executeInTransaction(const QByteArray &identifier, const Oper return true; } -bool AbstractView::isEnabled() const -{ - return m_enabled; -} - -void AbstractView::setEnabled(bool b) -{ - m_enabled = b; -} - QList AbstractView::allModelNodes() const { QTC_ASSERT(model(), return {}); @@ -883,4 +873,12 @@ int AbstractView::minorQtQuickVersion() const #endif } +AbstractViewAction::AbstractViewAction(AbstractView &view) + : m_view{view} +{ + connect(this, &QAction::toggled, [&](bool isChecked) { + emit viewCheckedChanged(isChecked, view); + }); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 2fc8ac6cf77..5563147da41 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -891,7 +891,11 @@ void ModelPrivate::resetModelByRewriter(const QString &description) void ModelPrivate::attachView(AbstractView *view) { - Q_ASSERT(view); + if (!view) + return; + + if (!view->isEnabled()) + return; if (m_viewList.contains(view)) return; diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index cf6d1f7c9b2..e81fdc331a2 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -329,7 +329,12 @@ void DesignModeWidget::setup() } // Afterwards get all the other widgets - for (const WidgetInfo &widgetInfo : viewManager().widgetInfos()) { + for (const auto &view : viewManager().views()) { + if (!view->hasWidget()) + continue; + + auto widgetInfo = view->widgetInfo(); + ensureMinimumSize(widgetInfo.widget); auto dockWidget = createDockWidget(widgetInfo.widget, @@ -342,7 +347,10 @@ void DesignModeWidget::setup() m_viewWidgets.append(widgetInfo.widget); // Create menu action - auto command = Core::ActionManager::registerAction(dockWidget->toggleViewAction(), + auto viewAction = view->action(); + viewAction->setText(widgetInfo.uniqueId); + dockWidget->setToggleViewAction(viewAction); + auto command = Core::ActionManager::registerAction(viewAction, actionToggle.withSuffix( widgetInfo.uniqueId + "Widget"), designContext); diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 1426c513734..1f2f321f47c 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -556,6 +556,9 @@ void QmlDesignerPlugin::selectModelNodeUnderTextCursor() void QmlDesignerPlugin::activateAutoSynchronization() { + viewManager().detachViewsExceptRewriterAndComponetView(); + viewManager().detachComponentView(); + // text editor -> visual editor if (!currentDesignDocument()->isDocumentLoaded()) currentDesignDocument()->loadDocument(currentDesignDocument()->plainTextEdit()); From 0eb7553676165c3f877b2d97f58b7bdcd51972fd Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Wed, 7 Aug 2024 20:07:27 +0300 Subject: [PATCH 004/193] QmlDesigner: Don't clear bundleId when saving content lib item's icon This fixes the issue in the tickets but there is still an issue with updating added component's icon. To be handled separately. Fixes: QDS-13307 Fixes: QDS-13308 Change-Id: If82b803bb53fae4eccd4f62284bc68daf46ce673 Reviewed-by: Miikka Heikkinen --- .../components/contentlibrary/contentlibraryusermodel.cpp | 2 ++ .../components/contentlibrary/contentlibraryview.cpp | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp index 89fb4a0a7d1..643913d1791 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp @@ -95,6 +95,8 @@ void ContentLibraryUserModel::addItem(const QString &bundleId, const QString &na void ContentLibraryUserModel::refreshSection(const QString &bundleId) { + QTC_ASSERT(!bundleId.isEmpty(), return); + SectionIndex sectionIdx = bundleIdToSectionIndex(bundleId); emit dataChanged(index(sectionIdx), index(sectionIdx), {ItemsRole, EmptyRole}); updateIsEmpty(); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index d301460aab0..fdcb5c29b9f 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -1048,7 +1048,6 @@ void ContentLibraryView::saveIconToBundle(const auto &image) { // auto: QImage o qWarning() << __FUNCTION__ << ": icon save failed"; m_iconSavePath.clear(); - m_bundleId.clear(); }; void ContentLibraryView::importBundleToContentLib() From 25e60ba20f1596f1b0f19f8d425137ce905d124a Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 6 Aug 2024 16:50:03 +0300 Subject: [PATCH 005/193] QmlDesigner: Properly support texture combo boxes in property view Now texture combo boxes in property view work similarly to those in material editor: - Can drag images/textures into them - Combo box model updated when texture is created/deleted/changes id Task-number: QDS-12138 Change-Id: I1384b63916c062c3755c181ef7cbebc40e44cc2d Reviewed-by: Mahmoud Badri Reviewed-by: Ali Kianian --- .../propertyeditorqmlbackend.cpp | 5 ++ .../propertyeditor/propertyeditorqmlbackend.h | 2 + .../propertyeditor/propertyeditorvalue.cpp | 3 +- .../propertyeditor/propertyeditorview.cpp | 72 ++++++++++++++++--- .../propertyeditor/propertyeditorview.h | 6 +- 5 files changed, 76 insertions(+), 12 deletions(-) diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp index 3798deb3cb1..c0ff56e39e7 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp @@ -919,6 +919,11 @@ NodeMetaInfo PropertyEditorQmlBackend::findCommonAncestor(const ModelNode &node) return node.metaInfo(); } +void PropertyEditorQmlBackend::refreshBackendModel() +{ + m_backendModelNode.refresh(); +} + #ifndef QDS_USE_PROJECTSTORAGE TypeName PropertyEditorQmlBackend::qmlFileName(const NodeMetaInfo &nodeInfo) { diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h index c9afbe91bd5..bf298010bda 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.h @@ -87,6 +87,8 @@ public: static NodeMetaInfo findCommonAncestor(const ModelNode &node); + void refreshBackendModel(); + private: void createPropertyEditorValue(const QmlObjectNode &qmlObjectNode, PropertyNameView name, diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp index a85287f6735..74a01b92dd9 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp @@ -516,8 +516,7 @@ bool PropertyEditorValue::idListReplace(int idx, const QString &value) void PropertyEditorValue::commitDrop(const QString &dropData) { - if (m_modelNode.metaInfo().isQtQuick3DMaterial() - && m_modelNode.metaInfo().property(m_name).propertyType().isQtQuick3DTexture()) { + if (m_modelNode.metaInfo().property(m_name).propertyType().isQtQuick3DTexture()) { m_modelNode.view()->executeInTransaction(__FUNCTION__, [&] { ModelNode texture = m_modelNode.view()->modelNodeForInternalId(dropData.toInt()); if (!texture || !texture.metaInfo().isQtQuick3DTexture()) { diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp index af3f3601e7f..16d3df91b9d 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp @@ -8,6 +8,7 @@ #include "propertyeditorvalue.h" #include "propertyeditorwidget.h" +#include #include #include #include @@ -57,6 +58,19 @@ static bool propertyIsAttachedInsightProperty(PropertyNameView propertyName) return propertyName.contains("InsightCategory."); } +static bool containsTexture(const ModelNode &node) +{ + if (node.metaInfo().isQtQuick3DTexture()) + return true; + + const ModelNodes children = node.allSubModelNodes(); + for (const ModelNode &child : children) { + if (child.metaInfo().isQtQuick3DTexture()) + return true; + } + return false; +} + PropertyEditorView::PropertyEditorView(AsynchronousImageCache &imageCache, ExternalDependenciesInterface &externalDependencies) : AbstractView(externalDependencies) @@ -739,6 +753,18 @@ void PropertyEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode) { if (m_selectedNode.isValid() && removedNode.isValid() && m_selectedNode == removedNode) select(); + if (containsTexture(removedNode)) + m_textureAboutToBeRemoved = true; +} + +void PropertyEditorView::nodeRemoved(const ModelNode &removedNode, + const NodeAbstractProperty &parentProperty, + PropertyChangeFlags propertyChange) +{ + if (m_qmlBackEndForCurrentType && m_textureAboutToBeRemoved) + m_qmlBackEndForCurrentType->refreshBackendModel(); + + m_textureAboutToBeRemoved = false; } void PropertyEditorView::modelAttached(Model *model) @@ -940,10 +966,11 @@ void PropertyEditorView::nodeIdChanged(const ModelNode& node, const QString& new if (!QmlObjectNode(m_selectedNode).isValid()) return; - if (node == m_selectedNode) { - - if (m_qmlBackEndForCurrentType) + if (m_qmlBackEndForCurrentType) { + if (node == m_selectedNode) setValue(node, "id", newId); + if (node.metaInfo().isQtQuick3DTexture()) + m_qmlBackEndForCurrentType->refreshBackendModel(); } } @@ -1051,23 +1078,50 @@ void PropertyEditorView::nodeReparented(const ModelNode &node, { if (node == m_selectedNode) m_qmlBackEndForCurrentType->backendAnchorBinding().setup(QmlItemNode(m_selectedNode)); + if (containsTexture(node)) + m_qmlBackEndForCurrentType->refreshBackendModel(); +} + +void PropertyEditorView::highlightTextureProperties(bool highlight) +{ + NodeMetaInfo metaInfo = m_selectedNode.metaInfo(); + QTC_ASSERT(metaInfo.isValid(), return); + + DesignerPropertyMap &propMap = m_qmlBackEndForCurrentType->backendValuesPropertyMap(); + const QStringList propNames = propMap.keys(); + for (const QString &propName : propNames) { + if (metaInfo.property(propName.toUtf8()).propertyType().isQtQuick3DTexture()) { + QObject *propEditorValObj = propMap.value(propName).value(); + PropertyEditorValue *propEditorVal = qobject_cast(propEditorValObj); + propEditorVal->setHasActiveDrag(highlight); + } + } } void PropertyEditorView::dragStarted(QMimeData *mimeData) { - if (!mimeData->hasFormat(Constants::MIME_TYPE_ASSETS)) - return; + if (mimeData->hasFormat(Constants::MIME_TYPE_ASSETS)) { + const QString assetPath = QString::fromUtf8(mimeData->data(Constants::MIME_TYPE_ASSETS)) + .split(',')[0]; + const QString suffix = "*." + assetPath.split('.').last().toLower(); - const QString assetPath = QString::fromUtf8(mimeData->data(Constants::MIME_TYPE_ASSETS)) - .split(',')[0]; - const QString suffix = "*." + assetPath.split('.').last().toLower(); + m_qmlBackEndForCurrentType->contextObject()->setActiveDragSuffix(suffix); - m_qmlBackEndForCurrentType->contextObject()->setActiveDragSuffix(suffix); + Asset asset(assetPath); + if (!asset.isValidTextureSource()) + return; + + highlightTextureProperties(); + } else if (mimeData->hasFormat(Constants::MIME_TYPE_TEXTURE) + || mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_TEXTURE)) { + highlightTextureProperties(); + } } void PropertyEditorView::dragEnded() { m_qmlBackEndForCurrentType->contextObject()->setActiveDragSuffix(""); + highlightTextureProperties(false); } void PropertyEditorView::setValue(const QmlObjectNode &qmlObjectNode, diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h index 128914cfb6e..f4bbbf22a81 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h @@ -41,7 +41,9 @@ public: void selectedNodesChanged(const QList &selectedNodeList, const QList &lastSelectedNodeList) override; void nodeAboutToBeRemoved(const ModelNode &removedNode) override; - + void nodeRemoved(const ModelNode &removedNode, + const NodeAbstractProperty &parentProperty, + PropertyChangeFlags propertyChange) override; void propertiesRemoved(const QList& propertyList) override; void modelAttached(Model *model) override; @@ -116,6 +118,7 @@ private: //functions void removePropertyFromModel(PropertyNameView propertyName); bool noValidSelection() const; + void highlightTextureProperties(bool highlight = true); private: //variables AsynchronousImageCache &m_imageCache; @@ -131,6 +134,7 @@ private: //variables bool m_locked; bool m_setupCompleted; QTimer *m_singleShotTimer; + bool m_textureAboutToBeRemoved = false; }; } //QmlDesigner From ccea03de81e773077908d0f451293f3b3e982f0b Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 8 Aug 2024 10:31:14 +0200 Subject: [PATCH 006/193] GoogleTest: Update to 1.15.2 Change-Id: I277d5b00007286e96bf057f5e617a103fdb1a9c0 Reviewed-by: Tim Jenssen --- src/libs/3rdparty/googletest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/3rdparty/googletest b/src/libs/3rdparty/googletest index f8d7d77c069..b514bdc898e 160000 --- a/src/libs/3rdparty/googletest +++ b/src/libs/3rdparty/googletest @@ -1 +1 @@ -Subproject commit f8d7d77c06936315286eb55f8de22cd23c188571 +Subproject commit b514bdc898e2951020cbdca1304b75f5950d1f59 From 1339e041e19da6dbab1b2130720bbe1f449004f3 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 8 Aug 2024 12:47:46 +0300 Subject: [PATCH 007/193] QmlDesigner: Fix dragging images into navigator Highlight all supported node types as possible drag targets. Properly move the newly created texture under material library instead of leaving it under the target node. Fixes: QDS-13339 Change-Id: Ia565ef7b9166c73377825959a1328cdaf120d09c Reviewed-by: Mahmoud Badri --- .../componentcore/modelnodeoperations.cpp | 23 +++++++++++-------- .../components/navigator/nameitemdelegate.cpp | 14 ++++++++--- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index d114d2dc151..cb5b4a46fbb 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -1912,16 +1913,18 @@ bool dropAsImage3dTexture(const ModelNode &targetNode, AbstractView *view = targetNode.view(); QTC_ASSERT(view, return {}); - auto bindToProperty = [&](const PropertyName &propName, bool sibling) { + auto bindToProperty = [&](const PropertyName &propName) { view->executeInTransaction("NavigatorTreeModel::dropAsImage3dTexture", [&] { newNode = createTextureNode(targetProp, imagePath); if (newNode.isValid()) { - targetNode.bindingProperty(propName).setExpression(newNode.validId()); - - // If dropping an image on e.g. TextureInput, create a texture on the same level as - // target, as the target doesn't support Texture children (QTBUG-86219) - if (sibling) - outMoveNodesAfter = !moveNodeToParent(targetProp, newNode); + BindingProperty bindProp = targetNode.bindingProperty(propName); + bindProp.setExpression(newNode.validId()); + ModelNode matLib = Utils3D::materialLibraryNode(view); + if (matLib.isValid()) { + NodeAbstractProperty matLibProp = matLib.defaultNodeAbstractProperty(); + matLibProp.reparentHere(newNode); + outMoveNodesAfter = false; + } } }); }; @@ -1952,13 +1955,13 @@ bool dropAsImage3dTexture(const ModelNode &targetNode, delete dialog; return true; } else if (targetNode.metaInfo().isQtQuick3DTextureInput()) { - bindToProperty("texture", true); + bindToProperty("texture"); return newNode.isValid(); } else if (targetNode.metaInfo().isQtQuick3DParticles3DSpriteParticle3D()) { - bindToProperty("sprite", false); + bindToProperty("sprite"); return newNode.isValid(); } else if (targetNode.metaInfo().isQtQuick3DSceneEnvironment()) { - bindToProperty("lightProbe", false); + bindToProperty("lightProbe"); return newNode.isValid(); } else if (targetNode.metaInfo().isQtQuick3DTexture()) { // if dropping an image on an existing texture, set the source diff --git a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp index 7dd73fac1cb..e3a74031bca 100644 --- a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp +++ b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp @@ -216,14 +216,22 @@ void NameItemDelegate::paint(QPainter *painter, QByteArray dragType = widget->dragType(); const NodeMetaInfo metaInfo = node.metaInfo(); + auto isValid3dTextureTarget = [&metaInfo]() -> bool { + return metaInfo.isQtQuick3DModel() + || metaInfo.isQtQuick3DTexture() + || metaInfo.isQtQuick3DSceneEnvironment() + || metaInfo.isQtQuick3DTextureInput() + || metaInfo.isQtQuick3DParticles3DSpriteParticle3D(); + }; + bool validDrop = false; if (dragType == Constants::MIME_TYPE_BUNDLE_TEXTURE) { validDrop = metaInfo.isQtQuick3DModel(); } else if (dragType == Constants::MIME_TYPE_ASSET_TEXTURE3D) { - validDrop = metaInfo.isQtQuick3DModel() || metaInfo.isQtQuick3DTexture(); + validDrop = isValid3dTextureTarget(); } else if (dragType == Constants::MIME_TYPE_ASSET_IMAGE) { - validDrop = metaInfo.isQtQuick3DModel() || metaInfo.isQtQuick3DTexture() - || metaInfo.isQtQuickImage() || metaInfo.isQtQuickBorderImage(); + validDrop = isValid3dTextureTarget() + || metaInfo.isQtQuickImage() || metaInfo.isQtQuickBorderImage(); } else { const NodeMetaInfo dragInfo = node.model()->metaInfo(dragType); ChooseFromPropertyListFilter *filter = new ChooseFromPropertyListFilter(dragInfo, metaInfo, true); From ef280833f2c59a9196e7bba8027e6a43b87a8396 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 8 Aug 2024 13:36:37 +0200 Subject: [PATCH 008/193] QmlDesigner: Fix compile error for unused arguments Change-Id: I91a7572ce1028d999ceb8b5a67a0751c23c2d840 Reviewed-by: Miikka Heikkinen --- .../components/propertyeditor/propertyeditorview.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp index 16d3df91b9d..33151f403ac 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp @@ -757,9 +757,7 @@ void PropertyEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode) m_textureAboutToBeRemoved = true; } -void PropertyEditorView::nodeRemoved(const ModelNode &removedNode, - const NodeAbstractProperty &parentProperty, - PropertyChangeFlags propertyChange) +void PropertyEditorView::nodeRemoved(const ModelNode &, const NodeAbstractProperty &, PropertyChangeFlags) { if (m_qmlBackEndForCurrentType && m_textureAboutToBeRemoved) m_qmlBackEndForCurrentType->refreshBackendModel(); From 0ad4c96ccc4cbb3947d7852ac1e859695ebf252a Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 8 Aug 2024 14:05:26 +0300 Subject: [PATCH 009/193] QmlDesigner: Allow dragging hdr images into texture source field This was already supported in properties view, but not in texture editor. Change-Id: I336bcfabacccc4397ebc51c9e835a4cb974a9189 Reviewed-by: Mahmoud Badri --- .../components/textureeditor/textureeditorview.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp index 53bc8fb89e8..eae0a7ff56c 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp @@ -878,8 +878,11 @@ void TextureEditorView::dragStarted(QMimeData *mimeData) const QString assetPath = QString::fromUtf8(mimeData->data(Constants::MIME_TYPE_ASSETS)).split(',')[0]; QString assetType = AssetsLibraryWidget::getAssetTypeAndData(assetPath).first; - if (assetType != Constants::MIME_TYPE_ASSET_IMAGE) // currently only image assets have dnd-supported properties + // Currently only image assets have dnd-supported properties + if (assetType != Constants::MIME_TYPE_ASSET_IMAGE + && assetType != Constants::MIME_TYPE_ASSET_TEXTURE3D) { return; + } highlightSupportedProperties(); From 8f11362a5a9f52df4c74e705e0f1fe685f81450d Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 8 Aug 2024 14:30:18 +0300 Subject: [PATCH 010/193] QmlDesigner: Show initializing message at start of lights baking If the baked scene is large, it may take some time before quick3d baking process gives any progress notification, which can lead to user thinking nothing is happening. Added "Initialiging bake..." message at scene creation so user gets feedback that something is actually happening. Change-Id: I698d828efb5d0c8ded1d3080774a7c4c05645ad1 Reviewed-by: Mahmoud Badri --- .../qml2puppet/instances/qt5bakelightsnodeinstanceserver.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5bakelightsnodeinstanceserver.cpp b/src/tools/qml2puppet/qml2puppet/instances/qt5bakelightsnodeinstanceserver.cpp index 2a1aff912ac..770eabdaa8d 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/qt5bakelightsnodeinstanceserver.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/qt5bakelightsnodeinstanceserver.cpp @@ -39,6 +39,11 @@ Qt5BakeLightsNodeInstanceServer::~Qt5BakeLightsNodeInstanceServer() void Qt5BakeLightsNodeInstanceServer::createScene(const CreateSceneCommand &command) { + nodeInstanceClient()->handlePuppetToCreatorCommand( + {PuppetToCreatorCommand::BakeLightsProgress, + tr("Initializing bake...")}); + nodeInstanceClient()->flush(); + initializeView(); registerFonts(command.resourceUrl); setTranslationLanguage(command.language); From 34ca4b9af75c5374eb6f0c6ed7493675c4a790fe Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Thu, 8 Aug 2024 15:29:39 +0300 Subject: [PATCH 011/193] QmlDesigner: Fix resolving component path in content lib Regression introduced by d079385d8147df8848898f6f7d8c688dd6599ab6 Change-Id: I1c60ac385e514ce8ff77503eedde52a97249b218 Reviewed-by: Miikka Heikkinen --- .../components/contentlibrary/contentlibraryview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index fdcb5c29b9f..a82179e72e1 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -505,7 +505,7 @@ Utils::FilePath componentPath([[maybe_unused]] const NodeMetaInfo &metaInfo) // TODO return {}; #else - return Utils::FilePath::fromString(metaInfo.importDirectoryPath()); + return Utils::FilePath::fromString(metaInfo.componentFileName()); #endif } From eba6a4fd250a90a2f5b777260084fc5547085808 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 26 Jul 2024 13:48:39 +0200 Subject: [PATCH 012/193] QmlDesigner: Hopefully improve ModelResourceManagement readability Inspired by the Layout design NodeActions was extended and now set the base member instead of use the action constructor. That should make the actions more readable. Change-Id: I282a64c71fcc607224fa7641a378fc8584c5dd43 Reviewed-by: Tim Jenssen --- .../model/modelresourcemanagement.cpp | 140 ++++++++++-------- 1 file changed, 79 insertions(+), 61 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp b/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp index 27ac2e67abb..302a0c86def 100644 --- a/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp @@ -30,10 +30,7 @@ void forEachAction(NodeActions &nodeActions, ActionCall actionCall); struct Base { - Base(ModelResourceSet &resourceSet, NodeActions &nodeActions) - : resourceSet{resourceSet} - , nodeActions{nodeActions} - {} + Base() = default; void removeNodes(ModelNodes newModelNodes, CheckRecursive checkRecursive) { @@ -53,7 +50,7 @@ struct Base std::sort(newModelNodes.begin(), newModelNodes.end()); - checkNewModelNodes(newModelNodes, resourceSet.removeModelNodes); + checkNewModelNodes(newModelNodes, resourceSet->removeModelNodes); } void removeProperties(AbstractProperties newProperties, CheckRecursive checkRecursive) @@ -69,7 +66,7 @@ struct Base void addSetExpressions(ModelResourceSet::SetExpressions newSetExpressions) { - auto &setExpressions = resourceSet.setExpressions; + auto &setExpressions = resourceSet->setExpressions; setExpressions.append(std::move(newSetExpressions)); } @@ -79,6 +76,12 @@ struct Base void finally() {} + void setNodeActionsAndModelResourceSet(NodeActions &actions, ModelResourceSet &resources) + { + nodeActions = &actions; + resourceSet = &resources; + } + private: ModelNodes removeNodes(ModelNodes &newModelNodes) { @@ -87,15 +90,15 @@ private: newModelNodes.erase(std::unique(newModelNodes.begin(), newModelNodes.end()), newModelNodes.end()); - auto oldModelNodes = std::move(resourceSet.removeModelNodes); - resourceSet.removeModelNodes = {}; - resourceSet.removeModelNodes.reserve(oldModelNodes.size() + newModelNodes.size()); + auto oldModelNodes = std::move(resourceSet->removeModelNodes); + resourceSet->removeModelNodes = {}; + resourceSet->removeModelNodes.reserve(oldModelNodes.size() + newModelNodes.size()); std::set_union(newModelNodes.begin(), newModelNodes.end(), oldModelNodes.begin(), oldModelNodes.end(), - std::back_inserter(resourceSet.removeModelNodes)); + std::back_inserter(resourceSet->removeModelNodes)); return oldModelNodes; } @@ -107,15 +110,15 @@ private: newProperties.erase(std::unique(newProperties.begin(), newProperties.end()), newProperties.end()); - auto oldProperties = std::move(resourceSet.removeProperties); - resourceSet.removeProperties = {}; - resourceSet.removeProperties.reserve(oldProperties.size() + newProperties.size()); + auto oldProperties = std::move(resourceSet->removeProperties); + resourceSet->removeProperties = {}; + resourceSet->removeProperties.reserve(oldProperties.size() + newProperties.size()); std::set_union(newProperties.begin(), newProperties.end(), oldProperties.begin(), oldProperties.end(), - std::back_inserter(resourceSet.removeProperties)); + std::back_inserter(resourceSet->removeProperties)); return oldProperties; } @@ -132,7 +135,7 @@ private: std::back_inserter(addedModelNodes)); if (addedModelNodes.size()) - forEachAction(nodeActions, [&](auto &action) { action.handleNodes(addedModelNodes); }); + forEachAction(*nodeActions, [&](auto &action) { action.handleNodes(addedModelNodes); }); } void checkNewProperties(const AbstractProperties &newProperties, @@ -148,13 +151,13 @@ private: std::back_inserter(addedProperties)); if (addedProperties.size()) - forEachAction(nodeActions, + forEachAction(*nodeActions, [&](auto &action) { action.handleProperties(addedProperties); }); } private: - ModelResourceSet &resourceSet; - NodeActions &nodeActions; + ModelResourceSet *resourceSet = nullptr; + NodeActions *nodeActions = nullptr; }; struct CheckChildNodes : public Base @@ -295,11 +298,8 @@ using NodesProperties = std::vector; struct RemoveDependentBindings : public Base { - RemoveDependentBindings(ModelResourceSet &resourceSet, - NodeActions &nodeActions, - BindingDependencies dependencies) - : Base{resourceSet, nodeActions} - , dependencies{std::move(dependencies)} + RemoveDependentBindings(BindingDependencies dependencies) + : dependencies{std::move(dependencies)} {} AbstractProperties collectProperties(const ModelNodes &nodes) @@ -326,11 +326,8 @@ struct RemoveDependentBindings : public Base struct RemoveDependencies : public Base { - RemoveDependencies(ModelResourceSet &resourceSet, - NodeActions &nodeActions, - NodeDependencies dependencies) - : Base{resourceSet, nodeActions} - , dependencies{std::move(dependencies)} + RemoveDependencies(NodeDependencies dependencies) + : dependencies{std::move(dependencies)} {} ModelNodes collectNodes(const ModelNodes &nodes) const @@ -357,12 +354,8 @@ struct RemoveDependencies : public Base struct RemoveTargetsSources : public Base { - RemoveTargetsSources(ModelResourceSet &resourceSet, - NodeActions &nodeActions, - NodeDependencies dependencies, - NodesProperties nodesProperties) - : Base{resourceSet, nodeActions} - , dependencies{std::move(dependencies)} + RemoveTargetsSources(NodeDependencies dependencies, NodesProperties nodesProperties) + : dependencies{std::move(dependencies)} , nodesProperties{std::move(nodesProperties)} {} @@ -722,12 +715,45 @@ using NodeActionsTuple = std::tuple + NodeActions(ModelResourceSet &modelResourceSet, Actions &&...actions) + : NodeActionsTuple(std::forward(actions)...) + , modelResourceSet{modelResourceSet} + { + forEachAction(*this, [&](auto &action) { + action.setNodeActionsAndModelResourceSet(*this, modelResourceSet); + }); + } + NodeActions(const NodeActions &) = delete; NodeActions &opertor(const NodeActions &) = delete; NodeActions(NodeActions &&) = delete; NodeActions &opertor(NodeActions &&) = delete; - using NodeActionsTuple::NodeActionsTuple; + void removeProperties(const AbstractProperties &properties, CheckRecursive checkRecursive) + { + Base base; + base.setNodeActionsAndModelResourceSet(*this, modelResourceSet); + + base.removeProperties(properties, checkRecursive); + } + + void removeNodes(const ModelNodes &nodes, CheckRecursive checkRecursive) + { + Base base; + base.setNodeActionsAndModelResourceSet(*this, modelResourceSet); + + base.removeNodes(nodes, checkRecursive); + } + + ~NodeActions() + { + forEachAction(*this, [&](auto &action) { action.finally(); }); + } + +private: + ModelResourceSet &modelResourceSet; }; template @@ -747,20 +773,16 @@ ModelResourceSet ModelResourceManagement::removeNodes(ModelNodes nodes, Model *m DependenciesSet set = createDependenciesSet(model); - NodeActions nodeActions = { - CheckChildNodes{resourceSet, nodeActions}, - CheckNodesInNodeAbstractProperties{resourceSet, nodeActions}, - RemoveLayerEnabled{resourceSet, nodeActions}, - RemoveDependentBindings{resourceSet, nodeActions, std::move(set.bindingDependencies)}, - RemoveDependencies{resourceSet, nodeActions, std::move(set.nodeDependencies)}, - RemoveTargetsSources{resourceSet, - nodeActions, - std::move(set.targetsDependencies), - std::move(set.targetsNodesProperties)}}; + NodeActions nodeActions = {resourceSet, + CheckChildNodes{}, + CheckNodesInNodeAbstractProperties{}, + RemoveLayerEnabled{}, + RemoveDependentBindings{std::move(set.bindingDependencies)}, + RemoveDependencies{std::move(set.nodeDependencies)}, + RemoveTargetsSources{std::move(set.targetsDependencies), + std::move(set.targetsNodesProperties)}}; - Base{resourceSet, nodeActions}.removeNodes(nodes, CheckRecursive::Yes); - - forEachAction(nodeActions, [&](auto &action) { action.finally(); }); + nodeActions.removeNodes(nodes, CheckRecursive::Yes); return resourceSet; } @@ -774,20 +796,16 @@ ModelResourceSet ModelResourceManagement::removeProperties(AbstractProperties pr DependenciesSet set = createDependenciesSet(model); - NodeActions nodeActions = { - CheckChildNodes{resourceSet, nodeActions}, - CheckNodesInNodeAbstractProperties{resourceSet, nodeActions}, - RemoveLayerEnabled{resourceSet, nodeActions}, - RemoveDependentBindings{resourceSet, nodeActions, std::move(set.bindingDependencies)}, - RemoveDependencies{resourceSet, nodeActions, std::move(set.nodeDependencies)}, - RemoveTargetsSources{resourceSet, - nodeActions, - std::move(set.targetsDependencies), - std::move(set.targetsNodesProperties)}}; + NodeActions nodeActions = {resourceSet, + CheckChildNodes{}, + CheckNodesInNodeAbstractProperties{}, + RemoveLayerEnabled{}, + RemoveDependentBindings{std::move(set.bindingDependencies)}, + RemoveDependencies{std::move(set.nodeDependencies)}, + RemoveTargetsSources{std::move(set.targetsDependencies), + std::move(set.targetsNodesProperties)}}; - Base{resourceSet, nodeActions}.removeProperties(properties, CheckRecursive::Yes); - - forEachAction(nodeActions, [&](auto &action) { action.finally(); }); + nodeActions.removeProperties(properties, CheckRecursive::Yes); return resourceSet; } From fe73b1893ba0e100672e712063b0f07786e3f3ae Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 26 Jul 2024 01:49:49 +0200 Subject: [PATCH 013/193] QmlDesigner: Modernize ownership in binding editor Using raw pointer for ownership is hard to track. std::unqiue_ptr and Utils::UniqueObjectPtr takes care of it. We have random crashes too, because parents are only deleted in the QObject destructor. So the call back to a half destructed instance. Change-Id: Ibb3c14e388b923e1f565b8d4a0f14e2ea13ba644 Reviewed-by: Tim Jenssen --- .../components/bindingeditor/signallist.cpp | 8 ++---- .../components/bindingeditor/signallist.h | 2 +- .../bindingeditor/signallistdelegate.cpp | 4 --- .../bindingeditor/signallistdelegate.h | 2 -- .../bindingeditor/signallistdialog.cpp | 28 ++++++++++--------- .../bindingeditor/signallistdialog.h | 9 ++++-- 6 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/plugins/qmldesigner/components/bindingeditor/signallist.cpp b/src/plugins/qmldesigner/components/bindingeditor/signallist.cpp index 12a605e58a0..ef554339bca 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/signallist.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/signallist.cpp @@ -73,7 +73,7 @@ void SignalList::prepareDialog() m_dialog->setWindowTitle(::QmlDesigner::SignalList::tr("Signal List for %1") .arg(m_modelNode.validId())); - auto *delegate = static_cast(m_dialog->tableView()->itemDelegate()); + auto delegate = m_dialog->signalListDelegate(); connect(delegate, &SignalListDelegate::connectClicked, this, &SignalList::connectClicked); } @@ -88,11 +88,9 @@ void SignalList::hideWidget() { if (m_dialog) m_dialog->close(); - - m_dialog = nullptr; } -SignalList* SignalList::showWidget(const ModelNode &modelNode) +void SignalList::showWidget(const ModelNode &modelNode) { auto signalList = new SignalList; signalList->setModelNode(modelNode); @@ -102,8 +100,6 @@ SignalList* SignalList::showWidget(const ModelNode &modelNode) connect(signalList->m_dialog.get(), &QDialog::destroyed, [signalList]() { signalList->deleteLater(); }); - - return signalList; } void SignalList::setModelNode(const ModelNode &modelNode) diff --git a/src/plugins/qmldesigner/components/bindingeditor/signallist.h b/src/plugins/qmldesigner/components/bindingeditor/signallist.h index 5842d445bb6..55d277bd57c 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/signallist.h +++ b/src/plugins/qmldesigner/components/bindingeditor/signallist.h @@ -55,7 +55,7 @@ public: explicit SignalList(QObject *parent = nullptr); ~SignalList(); - static SignalList* showWidget(const ModelNode &modelNode); + static void showWidget(const ModelNode &modelNode); void setModelNode(const ModelNode &modelNode); void connectClicked(const QModelIndex &modelIndex); diff --git a/src/plugins/qmldesigner/components/bindingeditor/signallistdelegate.cpp b/src/plugins/qmldesigner/components/bindingeditor/signallistdelegate.cpp index 331db9c42bd..8b2aca7ae0f 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/signallistdelegate.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/signallistdelegate.cpp @@ -12,10 +12,6 @@ namespace QmlDesigner { -SignalListDelegate::SignalListDelegate(QObject *parent) - : QStyledItemDelegate(parent) -{} - QWidget *SignalListDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const diff --git a/src/plugins/qmldesigner/components/bindingeditor/signallistdelegate.h b/src/plugins/qmldesigner/components/bindingeditor/signallistdelegate.h index dee68ce67df..9e7071968fd 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/signallistdelegate.h +++ b/src/plugins/qmldesigner/components/bindingeditor/signallistdelegate.h @@ -15,8 +15,6 @@ signals: void connectClicked(const QModelIndex &modelIndex) const; public: - SignalListDelegate(QObject *parent = nullptr); - QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; diff --git a/src/plugins/qmldesigner/components/bindingeditor/signallistdialog.cpp b/src/plugins/qmldesigner/components/bindingeditor/signallistdialog.cpp index 9be6894073f..07952f6f491 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/signallistdialog.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/signallistdialog.cpp @@ -20,9 +20,11 @@ #include #include +#include + namespace QmlDesigner { -QWidget *createFilterWidget(Utils::FancyLineEdit *lineEdit) +std::unique_ptr createFilterWidget(Utils::FancyLineEdit *lineEdit) { const QString unicode = Theme::getIconUnicode(Theme::Icon::search); const QString fontName = "qtds_propertyIconFont.ttf"; @@ -38,7 +40,7 @@ QWidget *createFilterWidget(Utils::FancyLineEdit *lineEdit) auto *box = new QHBoxLayout; box->addWidget(label); box->addWidget(lineEdit); - auto *widget = new QWidget; + auto widget = std::make_unique(); widget->setLayout(box); return widget; } @@ -52,24 +54,24 @@ void modifyPalette(QTableView *view, const QColor &selectionColor) view->setAlternatingRowColors(true); } - SignalListDialog::SignalListDialog(QWidget *parent) : QDialog(parent) - , m_table(new QTableView()) - , m_searchLine(new Utils::FancyLineEdit()) + , m_signalListDelegate{Utils::makeUniqueObjectPtr()} + , m_table(Utils::makeUniqueObjectPtr()) + , m_searchLine(Utils::makeUniqueObjectPtr()) { - auto *signalListDelegate = new SignalListDelegate(m_table); - m_table->setItemDelegate(signalListDelegate); + m_table->setItemDelegate(m_signalListDelegate.get()); m_table->setFocusPolicy(Qt::NoFocus); m_table->setSelectionMode(QAbstractItemView::NoSelection); m_table->setSelectionBehavior(QAbstractItemView::SelectRows); m_table->verticalHeader()->hide(); - modifyPalette(m_table, QColor("#d87b00")); + modifyPalette(m_table.get(), QColor("#d87b00")); auto *layout = new QVBoxLayout; - layout->addWidget(createFilterWidget(m_searchLine)); - layout->addWidget(m_table); + auto filterWidget = createFilterWidget(m_searchLine.get()); + layout->addWidget(filterWidget.release()); + layout->addWidget(m_table.get()); setLayout(layout); setWindowFlag(Qt::Tool, true); @@ -105,12 +107,12 @@ void SignalListDialog::initialize(QStandardItemModel *model) QRegularExpression(QRegularExpression::escape(str), option)); } }; - connect(m_searchLine, &Utils::FancyLineEdit::filterChanged, eventFilterFun); + connect(m_searchLine.get(), &Utils::FancyLineEdit::filterChanged, eventFilterFun); } -QTableView *SignalListDialog::tableView() const +SignalListDelegate *SignalListDialog::signalListDelegate() const { - return m_table; + return m_signalListDelegate.get(); } } // QmlDesigner namespace diff --git a/src/plugins/qmldesigner/components/bindingeditor/signallistdialog.h b/src/plugins/qmldesigner/components/bindingeditor/signallistdialog.h index cc16c204b43..869debd24a4 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/signallistdialog.h +++ b/src/plugins/qmldesigner/components/bindingeditor/signallistdialog.h @@ -3,6 +3,8 @@ #pragma once +#include + #include QT_BEGIN_NAMESPACE @@ -26,11 +28,12 @@ public: void initialize(QStandardItemModel *model); - QTableView *tableView() const; + class SignalListDelegate *signalListDelegate() const; private: - QTableView *m_table; - Utils::FancyLineEdit *m_searchLine; + Utils::UniqueObjectPtr m_signalListDelegate; + Utils::UniqueObjectPtr m_table; + Utils::UniqueObjectPtr m_searchLine; }; } // QmlDesigner namespace From 2b7fb2dba61ac967cf2e44bea7540844ea692fce Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 26 Jul 2024 01:32:07 +0200 Subject: [PATCH 014/193] QmlDesigner: Modernize ownership for MimeData Using raw pointer for ownership is hard to track. std::unqiue_ptr and Utils::UniqueObjectPtr take care of it. Change-Id: I163a97db0d8aabc7b9a75659e94d6562ea8dc969 Reviewed-by: Tim Jenssen --- .../assetslibrary/assetslibraryview.cpp | 22 ++++++++++--------- .../assetslibrary/assetslibraryview.h | 4 +++- .../assetslibrary/assetslibrarywidget.cpp | 13 ++++++++--- .../assetslibrary/assetslibrarywidget.h | 2 +- .../contentlibrary/contentlibrarywidget.cpp | 14 +++++------- .../itemlibrary/itemlibrarymodel.cpp | 4 ++-- .../components/itemlibrary/itemlibrarymodel.h | 2 +- .../itemlibrary/itemlibrarywidget.cpp | 3 ++- .../materialbrowser/materialbrowserwidget.cpp | 12 ++++++---- .../qmldesigner/designercore/include/model.h | 3 ++- .../qmldesigner/designercore/model/model.cpp | 15 ++++++------- .../qmldesigner/designercore/model/model_p.h | 5 ++++- 12 files changed, 58 insertions(+), 41 deletions(-) diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp index a8e06b31129..c757e41a408 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp @@ -58,16 +58,17 @@ bool AssetsLibraryView::hasWidget() const WidgetInfo AssetsLibraryView::widgetInfo() { - if (m_widget.isNull()) { - m_widget = new AssetsLibraryWidget{imageCacheData()->asynchronousFontImageCache, - imageCacheData()->synchronousFontImageCache, - this}; + if (!m_widget) { + m_widget = Utils::makeUniqueObjectPtr( + imageCacheData()->asynchronousFontImageCache, + imageCacheData()->synchronousFontImageCache, + this); - auto context = new Internal::AssetsLibraryContext(m_widget.data()); + auto context = new Internal::AssetsLibraryContext(m_widget.get()); Core::ICore::addContextObject(context); } - return createWidgetInfo(m_widget.data(), "Assets", WidgetInfo::LeftPane, tr("Assets")); + return createWidgetInfo(m_widget.get(), "Assets", WidgetInfo::LeftPane, tr("Assets")); } void AssetsLibraryView::customNotification(const AbstractView * /*view*/, @@ -101,10 +102,11 @@ void AssetsLibraryView::setResourcePath(const QString &resourcePath) m_lastResourcePath = resourcePath; - if (m_widget.isNull()) { - m_widget = new AssetsLibraryWidget{imageCacheData()->asynchronousFontImageCache, - imageCacheData()->synchronousFontImageCache, - this}; + if (!m_widget) { + m_widget = Utils::makeUniqueObjectPtr( + imageCacheData()->asynchronousFontImageCache, + imageCacheData()->synchronousFontImageCache, + this); } m_widget->setResourcePath(resourcePath); diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.h index f1a408c303f..ea8ac648d81 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.h @@ -5,6 +5,8 @@ #include "abstractview.h" +#include + #include #include @@ -40,7 +42,7 @@ private: std::once_flag imageCacheFlag; std::unique_ptr m_imageCacheData; - QPointer m_widget; + Utils::UniqueObjectPtr m_widget; QString m_lastResourcePath; }; diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp index dcba0cedd52..317b844cca3 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp @@ -43,6 +43,8 @@ #include #include +#include + namespace QmlDesigner { static QString propertyEditorResourcesPath() @@ -63,7 +65,7 @@ bool AssetsLibraryWidget::eventFilter(QObject *obj, QEvent *event) if (!m_assetsToDrag.isEmpty() && m_assetsView->model()) { QMouseEvent *me = static_cast(event); if ((me->globalPosition().toPoint() - m_dragStartPoint).manhattanLength() > 10) { - QMimeData *mimeData = new QMimeData; + auto mimeData = std::make_unique(); mimeData->setData(Constants::MIME_TYPE_ASSETS, m_assetsToDrag.join(',').toUtf8()); QList urlsToDrag = Utils::transform(m_assetsToDrag, [](const QString &path) { @@ -72,8 +74,11 @@ bool AssetsLibraryWidget::eventFilter(QObject *obj, QEvent *event) mimeData->setUrls(urlsToDrag); - m_assetsView->model()->startDrag(mimeData, m_assetsIconProvider->requestPixmap( - m_assetsToDrag[0], nullptr, {128, 128})); + m_assetsView->model()->startDrag(std::move(mimeData), + m_assetsIconProvider->requestPixmap(m_assetsToDrag[0], + nullptr, + {128, 128}), + this); m_assetsToDrag.clear(); } @@ -160,6 +165,8 @@ AssetsLibraryWidget::AssetsLibraryWidget(AsynchronousImageCache &asynchronousFon setFocusProxy(m_assetsWidget->quickWidget()); } +AssetsLibraryWidget::~AssetsLibraryWidget() = default; + void AssetsLibraryWidget::contextHelp(const Core::IContext::HelpCallback &callback) const { if (m_assetsView) diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h index f2d476c8427..01802196634 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h @@ -53,7 +53,7 @@ class AssetsLibraryWidget : public QFrame public: AssetsLibraryWidget(AsynchronousImageCache &asynchronousFontImageCache, SynchronousImageCache &synchronousFontImageCache, AssetsLibraryView *view); - ~AssetsLibraryWidget() = default; + ~AssetsLibraryWidget(); QList createToolBarWidgets(); void contextHelp(const Core::IContext::HelpCallback &callback) const; diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp index 1dfc496c787..52672b5c56d 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp @@ -72,13 +72,13 @@ bool ContentLibraryWidget::eventFilter(QObject *obj, QEvent *event) QMouseEvent *me = static_cast(event); if ((me->globalPos() - m_dragStartPoint).manhattanLength() > 20) { QByteArray data; - QMimeData *mimeData = new QMimeData; + auto mimeData = std::make_unique(); QDataStream stream(&data, QIODevice::WriteOnly); stream << m_itemToDrag->type(); mimeData->setData(Constants::MIME_TYPE_BUNDLE_ITEM, data); emit bundleItemDragStarted(m_itemToDrag); - model->startDrag(mimeData, m_itemToDrag->icon().toLocalFile()); + model->startDrag(std::move(mimeData), m_itemToDrag->icon().toLocalFile(), this); m_itemToDrag = nullptr; } } else if (m_materialToDrag) { @@ -86,21 +86,21 @@ bool ContentLibraryWidget::eventFilter(QObject *obj, QEvent *event) if ((me->globalPosition().toPoint() - m_dragStartPoint).manhattanLength() > 20 && m_materialsModel->isMaterialDownloaded(m_materialToDrag)) { QByteArray data; - QMimeData *mimeData = new QMimeData; + auto mimeData = std::make_unique(); QDataStream stream(&data, QIODevice::WriteOnly); stream << m_materialToDrag->type(); mimeData->setData(Constants::MIME_TYPE_BUNDLE_MATERIAL, data); mimeData->removeFormat("text/plain"); emit bundleMaterialDragStarted(m_materialToDrag); - model->startDrag(mimeData, m_materialToDrag->icon().toLocalFile()); + model->startDrag(std::move(mimeData), m_materialToDrag->icon().toLocalFile(), this); m_materialToDrag = nullptr; } } else if (m_textureToDrag) { QMouseEvent *me = static_cast(event); if ((me->globalPosition().toPoint() - m_dragStartPoint).manhattanLength() > 20 && m_textureToDrag->isDownloaded()) { - QMimeData *mimeData = new QMimeData; + auto mimeData = std::make_unique(); mimeData->setData(Constants::MIME_TYPE_BUNDLE_TEXTURE, {m_textureToDrag->texturePath().toUtf8()}); @@ -108,7 +108,7 @@ bool ContentLibraryWidget::eventFilter(QObject *obj, QEvent *event) mimeData->setUrls({QUrl::fromLocalFile(m_textureToDrag->texturePath())}); emit bundleTextureDragStarted(m_textureToDrag); - model->startDrag(mimeData, m_textureToDrag->icon().toLocalFile()); + model->startDrag(std::move(mimeData), m_textureToDrag->icon().toLocalFile(), this); m_textureToDrag = nullptr; } } @@ -438,8 +438,6 @@ QStringList ContentLibraryWidget::saveNewTextures(const QDir &bundleDir, const Q bool hasFile = (o["file"] == file); return hasFile; - - return false; }); return !contains; }); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index cf2ca4b74e7..4720f26a938 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -486,9 +486,9 @@ void ItemLibraryModel::update(Model *model) endResetModel(); } -QMimeData *ItemLibraryModel::getMimeData(const ItemLibraryEntry &itemLibraryEntry) +std::unique_ptr ItemLibraryModel::getMimeData(const ItemLibraryEntry &itemLibraryEntry) { - auto mimeData = new QMimeData(); + auto mimeData = std::make_unique(); QByteArray data; QDataStream stream(&data, QIODevice::WriteOnly); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h index b04ea492d2a..29d80f1fa8a 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h @@ -40,7 +40,7 @@ public: void update(Model *model); void updateUsedImports(const Imports &usedImports); - QMimeData *getMimeData(const ItemLibraryEntry &itemLibraryEntry); + std::unique_ptr getMimeData(const ItemLibraryEntry &itemLibraryEntry); void setSearchText(const QString &searchText); void setFlowMode(bool); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 16b1a43eb36..c0328afcc77 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -96,7 +96,8 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event) if (model) { model->startDrag(m_itemLibraryModel->getMimeData(entry), ::Utils::StyleHelper::dpiSpecificImageFile( - entry.libraryEntryIconPath())); + entry.libraryEntryIconPath()), + this); } m_itemToDrag = {}; diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp index 87b24306a8a..dd442e3ccc2 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp @@ -104,14 +104,18 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event) QMouseEvent *me = static_cast(event); if ((me->globalPosition().toPoint() - m_dragStartPoint).manhattanLength() > 20) { bool isMaterial = m_materialToDrag.isValid(); - QMimeData *mimeData = new QMimeData; + auto mimeData = std::make_unique(); QByteArray internalId; if (isMaterial) { internalId.setNum(m_materialToDrag.internalId()); mimeData->setData(Constants::MIME_TYPE_MATERIAL, internalId); - model->startDrag(mimeData, m_previewImageProvider->requestPixmap( - QString::number(m_materialToDrag.internalId()), nullptr, {128, 128})); + model->startDrag(std::move(mimeData), + m_previewImageProvider->requestPixmap( + QString::number(m_materialToDrag.internalId()), + nullptr, + {128, 128}), + this); } else { internalId.setNum(m_textureToDrag.internalId()); mimeData->setData(Constants::MIME_TYPE_TEXTURE, internalId); @@ -129,7 +133,7 @@ bool MaterialBrowserWidget::eventFilter(QObject *obj, QEvent *event) pixmap = Utils::StyleHelper::dpiSpecificImageFile(iconPath); if (pixmap.isNull()) pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/textureeditor/images/texture_default.png"); - model->startDrag(mimeData, pixmap.scaled({128, 128})); + model->startDrag(std::move(mimeData), pixmap.scaled({128, 128}), this); } m_materialToDrag = {}; m_textureToDrag = {}; diff --git a/src/plugins/qmldesigner/designercore/include/model.h b/src/plugins/qmldesigner/designercore/include/model.h index 98de7bb587f..3f3cf3a1cda 100644 --- a/src/plugins/qmldesigner/designercore/include/model.h +++ b/src/plugins/qmldesigner/designercore/include/model.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -258,7 +259,7 @@ public: QString generateNewId(const QString &prefixName, const QString &fallbackPrefix = "element") const; - void startDrag(QMimeData *mimeData, const QPixmap &icon); + void startDrag(std::unique_ptr mimeData, const QPixmap &icon, QWidget *sourceWidget); void endDrag(); void setCurrentStateNode(const ModelNode &node); diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 5563147da41..04510e6ce90 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -1906,22 +1906,21 @@ QString Model::generateNewId(const QString &prefixName, const QString &fallbackP }); } -void Model::startDrag(QMimeData *mimeData, const QPixmap &icon) +void Model::startDrag(std::unique_ptr mimeData, const QPixmap &icon, QWidget *dragSource) { - d->notifyDragStarted(mimeData); + d->notifyDragStarted(mimeData.get()); - auto drag = new QDrag(this); - drag->setPixmap(icon); - drag->setMimeData(mimeData); - if (drag->exec() == Qt::IgnoreAction) + d->drag = Utils::makeUniqueObjectPtr(dragSource); + d->drag->setPixmap(icon); + d->drag->setMimeData(mimeData.release()); + if (d->drag->exec() == Qt::IgnoreAction) endDrag(); - - drag->deleteLater(); } void Model::endDrag() { d->notifyDragEnded(); + d->drag.reset(); } void Model::setCurrentStateNode(const ModelNode &node) diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h index d32a0973d62..b375576211e 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/designercore/model/model_p.h @@ -16,6 +16,9 @@ #include +#include + +#include #include #include #include @@ -381,7 +384,7 @@ private: QPointer m_nodeInstanceView; QPointer m_metaInfoProxyModel; QHash> m_nodeMetaInfoCache; - + Utils::UniqueObjectPtr drag; bool m_writeLock = false; qint32 m_internalIdCounter = 1; }; From 3c7bffb13750d04b94780988951c968cc8d0542f Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Thu, 8 Aug 2024 17:41:31 +0200 Subject: [PATCH 015/193] QmlDesigner: Remove forgotten debug return * Fix sub selection wrapper in order to make effects work * Code cleanup Change-Id: Iefb72645752e2ee8a573843b6ea02d76cd92aeab Reviewed-by: Marco Bubke --- .../components/propertyeditor/propertyeditorvalue.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp index 74a01b92dd9..252f8c2a9ff 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp @@ -765,14 +765,18 @@ void PropertyEditorSubSelectionWrapper::createPropertyEditorValue(const QmlObjec { Utils::SmallString propertyName = name.toByteArray(); propertyName.replace('.', '_'); - auto valueObject = qobject_cast(variantToQObject(m_valuesPropertyMap.value(QString::fromUtf8(propertyName)))); + + const QString propertyNameQString = QString::fromUtf8(propertyName); + + auto valueObject = qobject_cast( + variantToQObject(m_valuesPropertyMap.value(propertyNameQString))); if (!valueObject) { valueObject = new PropertyEditorValue(&m_valuesPropertyMap); QObject::connect(valueObject, &PropertyEditorValue::valueChanged, this, &PropertyEditorSubSelectionWrapper::changeValue); QObject::connect(valueObject, &PropertyEditorValue::expressionChanged, this, &PropertyEditorSubSelectionWrapper::changeExpression); QObject::connect(valueObject, &PropertyEditorValue::exportPropertyAsAliasRequested, this, &PropertyEditorSubSelectionWrapper::exportPropertyAsAlias); QObject::connect(valueObject, &PropertyEditorValue::removeAliasExportRequested, this, &PropertyEditorSubSelectionWrapper::removeAliasExport); - m_valuesPropertyMap.insert(QString::fromUtf8(propertyName), QVariant::fromValue(valueObject)); + m_valuesPropertyMap.insert(propertyNameQString, QVariant::fromValue(valueObject)); } valueObject->setName(name); valueObject->setModelNode(qmlObjectNode); @@ -835,8 +839,6 @@ PropertyEditorSubSelectionWrapper::PropertyEditorSubSelectionWrapper(const Model { QmlObjectNode qmlObjectNode(modelNode); - return; - QTC_ASSERT(qmlObjectNode.isValid(), return ); for (const auto &property : From 364d6f6777cd35d3db092ce1c9b6d503f691a035 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Tue, 9 Jul 2024 17:26:26 +0200 Subject: [PATCH 016/193] QmlDesigner: Make hinting optional in FontSection * Add property in FontSection to show/hide hinting * Cleanup code Task-number: QDS-13304 Change-Id: Ib313e132fb3f75fc03ba3758ec63a2d9cf6e170f Reviewed-by: Tim Jenssen --- .../imports/HelperWidgets/FontSection.qml | 150 ++++++++++-------- 1 file changed, 84 insertions(+), 66 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml index f1f7dfc07fd..626cfb52a38 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/FontSection.qml @@ -8,7 +8,7 @@ import StudioControls 1.0 as StudioControls import StudioTheme 1.0 as StudioTheme Section { - id: fontSection + id: root anchors.left: parent.left anchors.right: parent.right caption: qsTr("Font") @@ -16,19 +16,20 @@ Section { property string fontName: "font" property bool showStyle: false + property bool showHinting: true function getBackendValue(name) { - return backendValues[fontSection.fontName + "_" + name] + return backendValues[root.fontName + "_" + name] } - property variant fontFamily: getBackendValue("family") - property variant pointSize: getBackendValue("pointSize") - property variant pixelSize: getBackendValue("pixelSize") + property variant fontFamily: root.getBackendValue("family") + property variant pointSize: root.getBackendValue("pointSize") + property variant pixelSize: root.getBackendValue("pixelSize") - property variant boldStyle: getBackendValue("bold") - property variant italicStyle: getBackendValue("italic") - property variant underlineStyle: getBackendValue("underline") - property variant strikeoutStyle: getBackendValue("strikeout") + property variant boldStyle: root.getBackendValue("bold") + property variant italicStyle: root.getBackendValue("italic") + property variant underlineStyle: root.getBackendValue("underline") + property variant strikeoutStyle: root.getBackendValue("strikeout") onPointSizeChanged: sizeWidget.setPointPixelSize() onPixelSizeChanged: sizeWidget.setPointPixelSize() @@ -42,11 +43,13 @@ Section { SecondColumnLayout { FontComboBox { id: fontComboBox - property string familyName: backendValue.value - backendValue: fontSection.fontFamily + + property string familyName: fontComboBox.backendValue.value + + backendValue: root.fontFamily implicitWidth: StudioTheme.Values.singleControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - width: implicitWidth + width: fontComboBox.implicitWidth } ExpandingSpacer {} @@ -59,8 +62,8 @@ Section { SecondColumnLayout { id: sizeWidget - property bool selectionFlag: selectionChanged + property bool selectionFlag: selectionChanged property bool pixelSize: sizeType.currentText === "px" property bool isSetup @@ -68,7 +71,7 @@ Section { sizeWidget.isSetup = true sizeType.currentIndex = 1 - if (fontSection.pixelSize.isInModel) + if (root.pixelSize.isInModel) sizeType.currentIndex = 0 sizeWidget.isSetup = false @@ -77,31 +80,33 @@ Section { onSelectionFlagChanged: sizeWidget.setPointPixelSize() Item { + id: sizeSpinBoxItem implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - width: implicitWidth - height: sizeSpinBox.height + width: sizeSpinBoxItem.implicitWidth + height: sizeSpinBoxPoint.height SpinBox { - id: sizeSpinBox + id: sizeSpinBoxPoint implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - width: implicitWidth + width: sizeSpinBoxPoint.implicitWidth minimumValue: 0 visible: !sizeWidget.pixelSize z: !sizeWidget.pixelSize ? 1 : 0 maximumValue: 400 - backendValue: pointSize + backendValue: root.pointSize } SpinBox { + id: sizeSpinBoxPixel implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - width: implicitWidth + width: sizeSpinBoxPixel.implicitWidth minimumValue: 0 visible: sizeWidget.pixelSize z: sizeWidget.pixelSize ? 1 : 0 maximumValue: 400 - backendValue: pixelSize + backendValue: root.pixelSize } } @@ -113,7 +118,7 @@ Section { StudioControls.ComboBox { id: sizeType implicitWidth: StudioTheme.Values.twoControlColumnWidth - width: implicitWidth + width: sizeType.implicitWidth model: ["px", "pt"] actionIndicatorVisible: false @@ -122,10 +127,10 @@ Section { return if (sizeType.currentText === "px") { - pointSize.resetValue() - pixelSize.value = 8 + root.pointSize.resetValue() + root.pixelSize.value = 8 } else { - pixelSize.resetValue() + root.pixelSize.resetValue() } } } @@ -136,35 +141,36 @@ Section { PropertyLabel { text: qsTr("Emphasis") tooltip: qsTr("Sets the text to bold, italic, underlined, or strikethrough.") - blockedByTemplate: !fontSection.boldStyle.isAvailable - && !fontSection.italicStyle.isAvailable - && !fontSection.underlineStyle.isAvailable - && !fontSection.strikeoutStyle.isAvailable + blockedByTemplate: !root.boldStyle.isAvailable + && !root.italicStyle.isAvailable + && !root.underlineStyle.isAvailable + && !root.strikeoutStyle.isAvailable } FontStyleButtons { - bold: fontSection.boldStyle - italic: fontSection.italicStyle - underline: fontSection.underlineStyle - strikeout: fontSection.strikeoutStyle + bold: root.boldStyle + italic: root.italicStyle + underline: root.underlineStyle + strikeout: root.strikeoutStyle enabled: !styleNameComboBox.styleSet } PropertyLabel { text: qsTr("Capitalization") tooltip: qsTr("Sets capitalization rules for the text.") - blockedByTemplate: !getBackendValue("capitalization").isAvailable + blockedByTemplate: !root.getBackendValue("capitalization").isAvailable } SecondColumnLayout { ComboBox { + id: capitalizationComboBox implicitWidth: StudioTheme.Values.singleControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - width: implicitWidth - backendValue: getBackendValue("capitalization") + width: capitalizationComboBox.implicitWidth + backendValue: root.getBackendValue("capitalization") scope: "Font" model: ["MixedCase", "AllUppercase", "AllLowercase", "SmallCaps", "Capitalize"] - enabled: backendValue.isAvailable + enabled: capitalizationComboBox.backendValue.isAvailable } ExpandingSpacer {} @@ -178,10 +184,11 @@ Section { SecondColumnLayout { ComboBox { + id: weightComboBox implicitWidth: StudioTheme.Values.singleControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - width: implicitWidth - backendValue: getBackendValue("weight") + width: weightComboBox.implicitWidth + backendValue: root.getBackendValue("weight") model: ["Normal", "Light", "ExtraLight", "Thin", "Medium", "DemiBold", "Bold", "ExtraBold", "Black"] scope: "Font" enabled: !styleNameComboBox.styleSet @@ -199,38 +206,41 @@ Section { SecondColumnLayout { ComboBox { id: styleNameComboBox + property bool styleSet: backendValue.isInModel + implicitWidth: StudioTheme.Values.singleControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - width: implicitWidth - backendValue: getBackendValue("styleName") + width: styleNameComboBox.implicitWidth + backendValue: root.getBackendValue("styleName") model: styleNamesForFamily(fontComboBox.familyName) valueType: ComboBox.String - enabled: backendValue.isAvailable + enabled: styleNameComboBox.backendValue.isAvailable } ExpandingSpacer {} } PropertyLabel { - visible: fontSection.showStyle + visible: root.showStyle text: qsTr("Style") tooltip: qsTr("Sets the font style.") blockedByTemplate: !styleComboBox.enabled } SecondColumnLayout { - visible: fontSection.showStyle + visible: root.showStyle + ComboBox { id: styleComboBox implicitWidth: StudioTheme.Values.singleControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - width: implicitWidth + width: styleComboBox.implicitWidth backendValue: (backendValues.style === undefined) ? dummyBackendValue : backendValues.style scope: "Text" model: ["Normal", "Outline", "Raised", "Sunken"] - enabled: backendValue.isAvailable + enabled: styleComboBox.backendValue.isAvailable } ExpandingSpacer {} @@ -239,30 +249,34 @@ Section { PropertyLabel { text: qsTr("Style color") tooltip: qsTr("Sets the color for the font style.") - visible: fontSection.showStyle && backendValues.styleColor.isAvailable + visible: root.showStyle && backendValues.styleColor.isAvailable } ColorEditor { - visible: fontSection.showStyle && backendValues.styleColor.isAvailable + visible: root.showStyle && backendValues.styleColor.isAvailable backendValue: backendValues.styleColor supportGradient: false } PropertyLabel { + visible: root.showHinting text: qsTr("Hinting") tooltip: qsTr("Sets how to interpolate the text to render it more clearly when scaled.") - blockedByTemplate: !getBackendValue("hintingPreference").isAvailable + blockedByTemplate: !root.getBackendValue("hintingPreference").isAvailable } SecondColumnLayout { + visible: root.showHinting + ComboBox { + id: hintingPreferenceComboBox implicitWidth: StudioTheme.Values.singleControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - width: implicitWidth - backendValue: getBackendValue("hintingPreference") + width: hintingPreferenceComboBox.implicitWidth + backendValue: root.getBackendValue("hintingPreference") scope: "Font" model: ["PreferDefaultHinting", "PreferNoHinting", "PreferVerticalHinting", "PreferFullHinting"] - enabled: backendValue.isAvailable + enabled: hintingPreferenceComboBox.backendValue.isAvailable } ExpandingSpacer {} @@ -271,19 +285,20 @@ Section { PropertyLabel { text: qsTr("Letter spacing") tooltip: qsTr("Sets the letter spacing for the text.") - blockedByTemplate: !getBackendValue("letterSpacing").isAvailable + blockedByTemplate: !root.getBackendValue("letterSpacing").isAvailable } SecondColumnLayout { SpinBox { + id: letterSpacingSpinBox implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - backendValue: getBackendValue("letterSpacing") + backendValue: root.getBackendValue("letterSpacing") decimals: 2 minimumValue: -500 maximumValue: 500 stepSize: 0.1 - enabled: backendValue.isAvailable + enabled: letterSpacingSpinBox.backendValue.isAvailable } ExpandingSpacer {} @@ -292,19 +307,20 @@ Section { PropertyLabel { text: qsTr("Word spacing") tooltip: qsTr("Sets the word spacing for the text.") - blockedByTemplate: !getBackendValue("wordSpacing").isAvailable + blockedByTemplate: !root.getBackendValue("wordSpacing").isAvailable } SecondColumnLayout { SpinBox { + id: wordSpacingSpinBox implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - backendValue: getBackendValue("wordSpacing") + backendValue: root.getBackendValue("wordSpacing") decimals: 2 minimumValue: -500 maximumValue: 500 stepSize: 0.1 - enabled: backendValue.isAvailable + enabled: wordSpacingSpinBox.backendValue.isAvailable } ExpandingSpacer {} @@ -313,16 +329,17 @@ Section { PropertyLabel { text: qsTr("Auto kerning") tooltip: qsTr("Resolves the gap between texts if turned true.") - blockedByTemplate: !getBackendValue("kerning").isAvailable + blockedByTemplate: !root.getBackendValue("kerning").isAvailable } SecondColumnLayout { CheckBox { - text: backendValue.valueToString + id: kerningCheckBox + text: kerningCheckBox.backendValue.valueToString implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - backendValue: getBackendValue("kerning") - enabled: backendValue.isAvailable + backendValue: root.getBackendValue("kerning") + enabled: kerningCheckBox.backendValue.isAvailable } ExpandingSpacer {} @@ -331,16 +348,17 @@ Section { PropertyLabel { text: qsTr("Prefer shaping") tooltip: qsTr("Toggles the disables font-specific special features.") - blockedByTemplate: !getBackendValue("preferShaping").isAvailable + blockedByTemplate: !root.getBackendValue("preferShaping").isAvailable } SecondColumnLayout { CheckBox { - text: backendValue.valueToString + id: preferShapingCheckBox + text: preferShapingCheckBox.backendValue.valueToString implicitWidth: StudioTheme.Values.twoControlColumnWidth + StudioTheme.Values.actionIndicatorWidth - backendValue: getBackendValue("preferShaping") - enabled: backendValue.isAvailable + backendValue: root.getBackendValue("preferShaping") + enabled: preferShapingCheckBox.backendValue.isAvailable } ExpandingSpacer {} From c39453cb1ea5a84044f71acffc3bdef946421453 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Wed, 7 Aug 2024 09:57:29 +0200 Subject: [PATCH 017/193] QmlDesigner: Fix warning in PopupDialog Some functions were only partially annotated hence the warnings. Change-Id: I396b3e778abfcf9ccc310f3b087c6a200e5462e4 Reviewed-by: Tim Jenssen --- .../imports/StudioControls/PopupDialog.qml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/PopupDialog.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/PopupDialog.qml index 821ba3a8491..4ac288cd997 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/PopupDialog.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/PopupDialog.qml @@ -45,7 +45,7 @@ QtObject { window.raise() } - function show(target: Item) { + function show(target: Item): void { var originGlobal = target.mapToGlobal(0, 0) root.__itemGlobal = Qt.rect(originGlobal.x, originGlobal.y, target.width, target.height) //root.chevronVisible = true @@ -154,7 +154,7 @@ QtObject { return true } - function getRegions(source: rect, target: rect) { + function getRegions(source: rect, target: rect): var { var edges = {} // Overlaps or Inside @@ -229,7 +229,7 @@ QtObject { return edges } - function popoverGeometry(edge: int, anchor: point, region: rect) { + function popoverGeometry(edge: int, anchor: point, region: rect): rect { if (edge === Qt.TopEdge) { let height = Math.min(window.height, region.height) return Qt.rect(Math.max(region.x, From 87b1388e1416a6dbb73950ed72777ec20ca706d5 Mon Sep 17 00:00:00 2001 From: Shrief Gabr Date: Mon, 5 Aug 2024 12:44:12 +0300 Subject: [PATCH 018/193] QmlDesigner: Fix Content Library search box messages Also disables the search box if the corresponding bundle does not exist Fixes: QDS-12922 Fixes: QDS-12920 Change-Id: I4e26b193d6f38e6d34af774068b8ab34bfd00bb3 Reviewed-by: Ali Kianian Reviewed-by: Mahmoud Badri --- .../ContentLibrary.qml | 30 +++++++++++++++---- .../ContentLibraryEffectsView.qml | 4 +-- .../ContentLibraryMaterialsView.qml | 4 +-- .../ContentLibraryTexturesView.qml | 4 +-- .../contentlibraryeffectsmodel.cpp | 12 ++++++-- .../contentlibraryeffectsmodel.h | 1 + .../contentlibrarymaterialsmodel.cpp | 14 +++++++-- .../contentlibrarymaterialsmodel.h | 7 +++-- .../contentlibrarytexturesmodel.cpp | 3 +- .../contentlibrarytexturesmodel.h | 5 ++-- 10 files changed, 61 insertions(+), 23 deletions(-) diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml index 94de88fc138..d7f3d80698d 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml @@ -17,6 +17,14 @@ Item { // and set the ads focus on it. objectName: "__mainSrollView" + enum TabIndex { + MaterialsTab, + TexturesTab, + EnvironmentsTab, + EffectsTab, + UserAssetsTab + } + // Called also from C++ to close context menu on focus out function closeContextMenu() { materialsView.closeContextMenu() @@ -90,12 +98,22 @@ Item { width: parent.width style: StudioTheme.Values.searchControlStyle enabled: { - if (tabBar.currIndex === 0) { // Materials tab - ContentLibraryBackend.materialsModel.matBundleExists - && ContentLibraryBackend.rootView.hasMaterialLibrary - && ContentLibraryBackend.materialsModel.hasRequiredQuick3DImport - } else { // Textures / Environments tabs - ContentLibraryBackend.texturesModel.texBundleExists + switch (tabBar.currIndex) { + case ContentLibrary.TabIndex.MaterialsTab: + return ContentLibraryBackend.materialsModel.hasRequiredQuick3DImport + && ContentLibraryBackend.rootView.hasMaterialLibrary + && ContentLibraryBackend.materialsModel.bundleExists + case ContentLibrary.TabIndex.TexturesTab: + case ContentLibrary.TabIndex.EnvironmentsTab: + return ContentLibraryBackend.texturesModel.bundleExists + case ContentLibrary.TabIndex.EffectsTab: + return ContentLibraryBackend.effectsModel.hasRequiredQuick3DImport + && ContentLibraryBackend.effectsModel.bundleExists + case ContentLibrary.TabIndex.UserAssetsTab: + return ContentLibraryBackend.rootView.hasQuick3DImport + && !ContentLibraryBackend.userModel.isEmpty + default: + return false } } diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffectsView.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffectsView.qml index e373f3c1aa4..aa85425617d 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffectsView.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryEffectsView.qml @@ -112,12 +112,12 @@ HelperWidgets.ScrollView { qsTr("Content Library effects are not supported in Qt5 projects.") else if (!ContentLibraryBackend.rootView.hasQuick3DImport) qsTr("To use Content Library, first add the QtQuick3D module in the Components view.") - else if (!ContentLibraryBackend.effectsModel.bundleExists) - qsTr("No effects available.") else if (!ContentLibraryBackend.effectsModel.hasRequiredQuick3DImport) qsTr("To use Content Library, version 6.4 or later of the QtQuick3D module is required.") else if (!ContentLibraryBackend.rootView.hasMaterialLibrary) qsTr("Content Library is disabled inside a non-visual component.") + else if (!ContentLibraryBackend.effectsModel.bundleExists) + qsTr("No effects available.") else if (!searchBox.isEmpty()) qsTr("No match found.") else diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterialsView.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterialsView.qml index 89860232867..c7b2f5a0822 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterialsView.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryMaterialsView.qml @@ -121,8 +121,8 @@ HelperWidgets.ScrollView { qsTr("To use Content Library, version 6.3 or later of the QtQuick3D module is required.") else if (!ContentLibraryBackend.rootView.hasMaterialLibrary) qsTr("Content Library is disabled inside a non-visual component.") - else if (!root.materialsModel.matBundleExists) - qsTr("No materials available. Make sure you have internet connection.") + else if (!root.materialsModel.bundleExists) + qsTr("No materials available. Make sure you have an internet connection.") else if (!searchBox.isEmpty()) qsTr("No match found.") else diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexturesView.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexturesView.qml index 617b724e664..5e1daa56b33 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexturesView.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibraryTexturesView.qml @@ -109,8 +109,8 @@ HelperWidgets.ScrollView { Text { id: infoText text: { - if (!root.model.texBundleExists) - qsTr("No textures available. Make sure you have internet connection.") + if (!root.model.bundleExists) + qsTr("No textures available. Make sure you have an internet connection.") else if (!searchBox.isEmpty()) qsTr("No match found.") else diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.cpp index d9f8bd4950d..1be5940c76d 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.cpp @@ -101,7 +101,7 @@ void ContentLibraryEffectsModel::loadBundle(bool force) // clean up qDeleteAll(m_bundleCategories); m_bundleCategories.clear(); - m_bundleExists = false; + setBundleExists(false); m_isEmpty = true; m_probeBundleDir = false; m_bundleObj = {}; @@ -180,7 +180,7 @@ void ContentLibraryEffectsModel::loadBundle(bool force) m_bundleSharedFiles = m_bundleObj.value("sharedFiles").toVariant().toStringList(); m_bundlePath = bundleDir.path(); - m_bundleExists = true; + setBundleExists(true); updateIsEmpty(); resetModel(); } @@ -269,4 +269,12 @@ void ContentLibraryEffectsModel::removeFromProject(ContentLibraryItem *bundleIte qWarning() << __FUNCTION__ << err; } +void ContentLibraryEffectsModel::setBundleExists(bool exists) +{ + if (m_bundleExists == exists) + return; + m_bundleExists = exists; + emit bundleExistsChanged(); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.h index 2063668ba99..47782f1a7f1 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.h @@ -37,6 +37,7 @@ public: bool hasRequiredQuick3DImport() const; bool bundleExists() const; + void setBundleExists(bool exists); void resetModel(); void updateIsEmpty(); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp index d162857fbb7..b5d67acc8ad 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp @@ -221,7 +221,7 @@ void ContentLibraryMaterialsModel::loadMaterialBundle(bool forceReload) // clean up qDeleteAll(m_bundleCategories); m_bundleCategories.clear(); - m_bundleExists = false; + setBundleExists(false); m_isEmpty = true; m_bundleObj = {}; m_bundleId.clear(); @@ -289,7 +289,7 @@ void ContentLibraryMaterialsModel::loadMaterialBundle(bool forceReload) } } - m_bundleExists = true; + setBundleExists(true); updateIsEmpty(); resetModel(); } @@ -299,7 +299,7 @@ bool ContentLibraryMaterialsModel::hasRequiredQuick3DImport() const return m_widget->hasQuick3DImport() && m_quick3dVersion >= Version{6, 3}; } -bool ContentLibraryMaterialsModel::matBundleExists() const +bool ContentLibraryMaterialsModel::bundleExists() const { return m_bundleExists; } @@ -395,4 +395,12 @@ bool ContentLibraryMaterialsModel::isMaterialDownloaded(ContentLibraryMaterial * return m_bundlePath.pathAppended(mat->qml()).exists(); } +void ContentLibraryMaterialsModel::setBundleExists(bool exists) +{ + if (m_bundleExists == exists) + return; + m_bundleExists = exists; + emit bundleExistsChanged(); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.h index 68c79607941..3d05d1f3325 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.h @@ -19,7 +19,7 @@ class ContentLibraryMaterialsModel : public QAbstractListModel { Q_OBJECT - Q_PROPERTY(bool matBundleExists READ matBundleExists NOTIFY matBundleExistsChanged) + Q_PROPERTY(bool bundleExists READ bundleExists NOTIFY bundleExistsChanged) Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged) Q_PROPERTY(bool hasRequiredQuick3DImport READ hasRequiredQuick3DImport NOTIFY hasRequiredQuick3DImportChanged) Q_PROPERTY(QString baseWebUrl MEMBER m_baseUrl CONSTANT) @@ -38,7 +38,7 @@ public: void setQuick3DImportVersion(int major, int minor); bool hasRequiredQuick3DImport() const; - bool matBundleExists() const; + bool bundleExists() const; QString bundlePath() const; @@ -52,13 +52,14 @@ public: Q_INVOKABLE bool isMaterialDownloaded(QmlDesigner::ContentLibraryMaterial *mat) const; QString bundleId() const; + void setBundleExists(bool exists); signals: void isEmptyChanged(); void hasRequiredQuick3DImportChanged(); void materialVisibleChanged(); void applyToSelectedTriggered(QmlDesigner::ContentLibraryMaterial *mat, bool add = false); - void matBundleExistsChanged(); + void bundleExistsChanged(); private: void loadMaterialBundle(bool forceReload = false); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.cpp index b575b6b9b2b..e6cc6edb1c9 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.cpp @@ -145,6 +145,7 @@ void ContentLibraryTexturesModel::loadTextureBundle(const QString &textureBundle dimensions, sizeInBytes, hasUpdate, isNew); } m_bundleCategories.append(category); + emit bundleChanged(); } resetModel(); @@ -197,7 +198,7 @@ void ContentLibraryTexturesModel::markTextureHasNoUpdates(const QString &subcate categ->markTextureHasNoUpdate(textureKey); } -bool ContentLibraryTexturesModel::texBundleExists() const +bool ContentLibraryTexturesModel::bundleExists() const { return !m_bundleCategories.isEmpty(); } diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.h index 94e223a2519..c4bb68cbb8a 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexturesmodel.h @@ -13,7 +13,7 @@ class ContentLibraryTexturesModel : public QAbstractListModel { Q_OBJECT - Q_PROPERTY(bool texBundleExists READ texBundleExists CONSTANT) + Q_PROPERTY(bool bundleExists READ bundleExists NOTIFY bundleChanged) Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged) Q_PROPERTY(bool hasSceneEnv READ hasSceneEnv NOTIFY hasSceneEnvChanged) @@ -31,7 +31,7 @@ public: QString removeModifiedFileEntry(const QString &key); void markTextureHasNoUpdates(const QString &subcategory, const QString &textureKey); - bool texBundleExists() const; + bool bundleExists() const; bool hasSceneEnv() const; void setHasSceneEnv(bool b); @@ -44,6 +44,7 @@ signals: void isEmptyChanged(); void materialVisibleChanged(); void hasSceneEnvChanged(); + void bundleChanged(); private: bool isValidIndex(int idx) const; From 6d634d05751199cddefc7df5de9a93517a9f9dde Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Fri, 9 Aug 2024 11:24:26 +0300 Subject: [PATCH 019/193] Doc: Remove unexpected endif MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I8c6b9e78cb8fe0d4da7338e0575bfdecb3a51ace Reviewed-by: Johanna Vanhatapio Reviewed-by: Teea Põldsam --- .../src/how-to/qtdesignstudio-live-preview-desktop.qdoc | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/qtdesignstudio/src/how-to/qtdesignstudio-live-preview-desktop.qdoc b/doc/qtdesignstudio/src/how-to/qtdesignstudio-live-preview-desktop.qdoc index b047265f09e..9424731fb62 100644 --- a/doc/qtdesignstudio/src/how-to/qtdesignstudio-live-preview-desktop.qdoc +++ b/doc/qtdesignstudio/src/how-to/qtdesignstudio-live-preview-desktop.qdoc @@ -46,5 +46,4 @@ To preview the design on a device, see \l {Previewing on Devices}. - \endif */ From eede2925e043052b35280601409b123c90fd1a2c Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Fri, 9 Aug 2024 14:39:11 +0300 Subject: [PATCH 020/193] QmlDesigner: Correct an issue in getBundleComponentDependencies() Change-Id: Ia84208448616304a3f45fd0c78d81996b4dea79c Reviewed-by: Miikka Heikkinen --- .../components/contentlibrary/contentlibraryview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index a82179e72e1..96a8cd016ff 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -1244,7 +1244,7 @@ QSet ContentLibraryView::getBundleComponentDependencies(const ModelNo { const QString compFileName = node.simplifiedTypeName() + ".qml"; - Utils::FilePath compPath = componentPath(node.metaInfo()); + Utils::FilePath compPath = componentPath(node.metaInfo()).parentDir(); QTC_ASSERT(compPath.exists(), return {}); From a1b656b2d614828c646083a2a1483892cbcade2c Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Thu, 8 Aug 2024 13:19:17 +0200 Subject: [PATCH 021/193] QmlDesigner: remove import versions + isQt6Project checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QDS-13057 Change-Id: I07197b1dddf9ae8dbf7effff7601fc7e61269006 Reviewed-by: Henning Gründl --- .../studio_templates/files/custombutton/file.qml.tpl | 4 ++-- .../files/customcheckbox/file.qml.tpl | 4 ++-- .../studio_templates/files/customdial/file.qml.tpl | 4 ++-- .../studio_templates/files/customslider/file.qml.tpl | 4 ++-- .../files/customspinbox/file.qml.tpl | 4 ++-- .../studio_templates/files/customswitch/file.qml.tpl | 4 ++-- .../studio_templates/files/flowitem/file.qml.tpl | 6 +++--- .../studio_templates/files/flowview/file.qml.tpl | 4 ++-- .../studio_templates/files/listmodel/file.qml.tpl | 2 +- .../studio_templates/files/pane/file.qml.tpl | 6 +++--- .../studio_templates/files/qtquickfile/file.qml.tpl | 4 ++-- .../studio_templates/files/qtquickfile/wizard.json | 2 +- .../files/qtquickviews/DataModel.qml.tpl | 2 +- .../files/qtquickviews/GridDelegate.ui.qml.tpl | 2 +- .../files/qtquickviews/GridView.ui.qml.tpl | 2 +- .../files/qtquickviews/ListDelegate.ui.qml.tpl | 2 +- .../files/qtquickviews/ListView.ui.qml.tpl | 2 +- .../files/qtuiquickfile/file.qml.tpl | 4 ++-- .../studio_templates/files/qtuiquickfile/wizard.json | 2 +- .../files/qtuiquickform/file.qml.tpl | 2 +- .../files/qtuiquickform/fileForm.ui.qml.tpl | 4 ++-- .../files/stackedlayout/file.qml.tpl | 6 +++--- .../studio_templates/files/swipeview/file.qml.tpl | 6 +++--- .../projects/application-3d/Screen01.ui.qml.tpl | 10 +++++----- .../application-3d/contentmodule.main.qml.tpl | 7 ++----- .../projects/application-3d/wizard.json | 6 ++---- .../application-extended-3d/Screen01.ui.qml.tpl | 12 ++++++------ .../contentmodule.main.qml.tpl | 7 ++----- .../projects/application-extended-3d/wizard.json | 6 ++---- .../projects/application/Screen01.ui.qml.tpl | 6 +++--- .../projects/application/wizard.json | 6 ++---- .../studio_templates/projects/common/App.qml.tpl | 9 +++------ .../projects/common/app.qmlproject.tpl | 12 ------------ .../projects/desktop-launcher/Screen01.ui.qml.tpl | 6 +++--- .../projects/desktop-launcher/wizard.json | 4 +--- .../projects/mobile-scroll/Screen01.ui.qml.tpl | 6 +++--- .../projects/mobile-scroll/wizard.json | 6 ++---- .../projects/mobile-stack/App.qml.tpl | 9 +++------ .../projects/mobile-stack/Screen01.ui.qml.tpl | 6 +++--- .../projects/mobile-stack/Screen02.ui.qml.tpl | 4 ++-- .../projects/mobile-stack/wizard.json | 6 ++---- .../projects/mobile-swipe/App.qml.tpl | 9 +++------ .../projects/mobile-swipe/Screen01.ui.qml.tpl | 6 +++--- .../projects/mobile-swipe/Screen02.ui.qml.tpl | 6 +++--- .../projects/mobile-swipe/wizard.json | 6 ++---- .../projects/shared-plugin/name/Constants.qml.tpl | 12 +----------- .../shared-plugin/name/DirectoryFontLoader.qml.tpl | 4 ++-- .../shared-plugin/name/EventListModel.qml.tpl | 2 +- .../shared-plugin/name/EventListSimulator.qml.tpl | 6 +++--- .../projects/shared-plugin/name/JsonData.qml.tpl | 6 +++--- 50 files changed, 108 insertions(+), 159 deletions(-) diff --git a/share/qtcreator/qmldesigner/studio_templates/files/custombutton/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/custombutton/file.qml.tpl index 80749182e65..7704dc46c92 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/custombutton/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/custombutton/file.qml.tpl @@ -5,8 +5,8 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick 2.15 -import QtQuick.Controls 2.15 +import QtQuick +import QtQuick.Controls Button { id: control diff --git a/share/qtcreator/qmldesigner/studio_templates/files/customcheckbox/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/customcheckbox/file.qml.tpl index e295083958c..ed22ae41044 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/customcheckbox/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/customcheckbox/file.qml.tpl @@ -5,8 +5,8 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick 2.15 -import QtQuick.Controls 2.15 +import QtQuick +import QtQuick.Controls CheckBox { id: control diff --git a/share/qtcreator/qmldesigner/studio_templates/files/customdial/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/customdial/file.qml.tpl index 7faa6c38be8..8b8268f4752 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/customdial/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/customdial/file.qml.tpl @@ -5,8 +5,8 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick 2.15 -import QtQuick.Controls 2.15 +import QtQuick +import QtQuick.Controls Dial { id: control diff --git a/share/qtcreator/qmldesigner/studio_templates/files/customslider/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/customslider/file.qml.tpl index d742e03b5d5..311d9a457ef 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/customslider/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/customslider/file.qml.tpl @@ -5,8 +5,8 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick 2.15 -import QtQuick.Controls 2.15 +import QtQuick +import QtQuick.Controls Slider { id: control diff --git a/share/qtcreator/qmldesigner/studio_templates/files/customspinbox/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/customspinbox/file.qml.tpl index 5031b5bd596..c6dfd545e6b 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/customspinbox/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/customspinbox/file.qml.tpl @@ -5,8 +5,8 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick 2.15 -import QtQuick.Controls 2.15 +import QtQuick +import QtQuick.Controls SpinBox { id: control diff --git a/share/qtcreator/qmldesigner/studio_templates/files/customswitch/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/customswitch/file.qml.tpl index 69e09a6205f..02aa01517f7 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/customswitch/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/customswitch/file.qml.tpl @@ -5,8 +5,8 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick 2.15 -import QtQuick.Controls 2.15 +import QtQuick +import QtQuick.Controls Switch { id: control diff --git a/share/qtcreator/qmldesigner/studio_templates/files/flowitem/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/flowitem/file.qml.tpl index c9fa8671cda..2a5913bdb47 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/flowitem/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/flowitem/file.qml.tpl @@ -5,14 +5,14 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick 2.15 +import QtQuick @if %{UseQtQuickControls2} -import QtQuick.Controls 2.15 +import QtQuick.Controls @endif @if %{UseImport} import %{ApplicationImport} @endif -import FlowView 1.0 +import FlowView FlowItem { @if %{UseImport} diff --git a/share/qtcreator/qmldesigner/studio_templates/files/flowview/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/flowview/file.qml.tpl index 1c8d7f0a075..eb095cf4894 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/flowview/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/flowview/file.qml.tpl @@ -5,11 +5,11 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick 2.15 +import QtQuick @if %{UseImport} import %{ApplicationImport} @endif -import FlowView 1.0 +import FlowView FlowView { @if %{UseImport} diff --git a/share/qtcreator/qmldesigner/studio_templates/files/listmodel/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/listmodel/file.qml.tpl index 684f85ce4c3..c44a28c9407 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/listmodel/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/listmodel/file.qml.tpl @@ -1,4 +1,4 @@ -import QtQuick 2.15 +import QtQuick ListModel { ListElement { diff --git a/share/qtcreator/qmldesigner/studio_templates/files/pane/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/pane/file.qml.tpl index 55d0f2b37e9..dd4014bd6b8 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/pane/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/pane/file.qml.tpl @@ -1,6 +1,6 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import %{ApplicationImport} Pane { diff --git a/share/qtcreator/qmldesigner/studio_templates/files/qtquickfile/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/qtquickfile/file.qml.tpl index 996d474208d..00cfa452f71 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/qtquickfile/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/qtquickfile/file.qml.tpl @@ -1,6 +1,6 @@ -import QtQuick 2.15 +import QtQuick @if %{UseQtQuickControls2} -import QtQuick.Controls 2.15 +import QtQuick.Controls @endif @if %{UseImport} import %{ApplicationImport} diff --git a/share/qtcreator/qmldesigner/studio_templates/files/qtquickfile/wizard.json b/share/qtcreator/qmldesigner/studio_templates/files/qtquickfile/wizard.json index 480a728a36e..7056f3bdfe1 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/qtquickfile/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/files/qtquickfile/wizard.json @@ -3,7 +3,7 @@ "supportedProjectTypes": [ ], "id": "B.QtStudio.Qml.2", "category": "B.StudioQtQuickFiles", - "trDescription": "Creates a component file (.qml) with boilerplate code, starting with \"import QtQuick 2.15\".", + "trDescription": "Creates a component file (.qml) with boilerplate code, starting with \"import QtQuick\".", "trDisplayName": "Qt Quick File", "trDisplayCategory": "Qt Quick Files", "icon": "file_qml.png", diff --git a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/DataModel.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/DataModel.qml.tpl index 684f85ce4c3..c44a28c9407 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/DataModel.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/DataModel.qml.tpl @@ -1,4 +1,4 @@ -import QtQuick 2.15 +import QtQuick ListModel { ListElement { diff --git a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/GridDelegate.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/GridDelegate.ui.qml.tpl index 867324eb121..3deeea07123 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/GridDelegate.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/GridDelegate.ui.qml.tpl @@ -1,4 +1,4 @@ -import QtQuick 2.15 +import QtQuick Item { id: delegate diff --git a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/GridView.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/GridView.ui.qml.tpl index 513543f0597..18240e71f24 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/GridView.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/GridView.ui.qml.tpl @@ -5,7 +5,7 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick 2.15 +import QtQuick GridView { width: 420 diff --git a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListDelegate.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListDelegate.ui.qml.tpl index 4a8ea4bc4ac..fb686fddd75 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListDelegate.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListDelegate.ui.qml.tpl @@ -5,7 +5,7 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick 2.15 +import QtQuick Item { id: delegate diff --git a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListView.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListView.ui.qml.tpl index 6ce5dccccc5..e76afcf0cd2 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListView.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/qtquickviews/ListView.ui.qml.tpl @@ -5,7 +5,7 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick 2.15 +import QtQuick ListView { id: view diff --git a/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickfile/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickfile/file.qml.tpl index e7e86e9ffa5..db24d31f3e8 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickfile/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickfile/file.qml.tpl @@ -5,9 +5,9 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick 2.15 +import QtQuick @if %{UseQtQuickControls2} -import QtQuick.Controls 2.15 +import QtQuick.Controls @endif @if %{UseImport} import %{ApplicationImport} diff --git a/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickfile/wizard.json b/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickfile/wizard.json index a70c2008932..970a33baede 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickfile/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickfile/wizard.json @@ -3,7 +3,7 @@ "supportedProjectTypes": [ ], "id": "Q.QtStudio.QmlUI.2", "category": "B.StudioQtQuickFiles", - "trDescription": "Creates a UI file (.ui.qml) with boilerplate code, starting with \"import QtQuick 2.15\".", + "trDescription": "Creates a UI file (.ui.qml) with boilerplate code, starting with \"import QtQuick\".", "trDisplayName": "Qt Quick UI File", "trDisplayCategory": "Qt Quick Files", "icon": "file_ui.png", diff --git a/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickform/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickform/file.qml.tpl index 7bd94416c44..0f66686aea9 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickform/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickform/file.qml.tpl @@ -1,4 +1,4 @@ -import QtQuick 2.15 +import QtQuick %{FormClass} { button.onClicked: console.log("Button Pressed") diff --git a/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickform/fileForm.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickform/fileForm.ui.qml.tpl index 1fcbbe97566..48f8c8b258f 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickform/fileForm.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/qtuiquickform/fileForm.ui.qml.tpl @@ -5,9 +5,9 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick 2.15 +import QtQuick @if %{UseQtQuickControls2} -import QtQuick.Controls 2.15 +import QtQuick.Controls @endif @if %{UseImport} import %{ApplicationImport} diff --git a/share/qtcreator/qmldesigner/studio_templates/files/stackedlayout/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/stackedlayout/file.qml.tpl index d4b196965f3..b4270f3a4d5 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/stackedlayout/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/stackedlayout/file.qml.tpl @@ -1,6 +1,6 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import %{ApplicationImport} Item { diff --git a/share/qtcreator/qmldesigner/studio_templates/files/swipeview/file.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/files/swipeview/file.qml.tpl index b0554bd0760..5782f1c839f 100644 --- a/share/qtcreator/qmldesigner/studio_templates/files/swipeview/file.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/files/swipeview/file.qml.tpl @@ -1,6 +1,6 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.15 -import QtQuick.Controls 2.15 +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls import %{ApplicationImport} Item { diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/Screen01.ui.qml.tpl index 8c72c47af2d..464bfae4e23 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/Screen01.ui.qml.tpl @@ -5,11 +5,11 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick %{QtQuickVersion} -import QtQuick.Controls %{QtQuickVersion} -import QtQuick3D %{QtQuick3DVersion} -import QtQuick3D.Effects %{QtQuick3DVersion} -import %{ImportModuleName} %{ImportModuleVersion} +import QtQuick +import QtQuick.Controls +import QtQuick3D +import QtQuick3D.Effects +import %{ImportModuleName} Rectangle { width: Constants.width diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/contentmodule.main.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/contentmodule.main.qml.tpl index 96f5dbaa36c..a5004b82200 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/contentmodule.main.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/contentmodule.main.qml.tpl @@ -1,10 +1,7 @@ -import QtQuick %{QtQuickVersion} -@if !%{IsQt6Project} -import QtQuick.Window %{QtQuickVersion} -@endif +import QtQuick import %{ApplicationImport} @if %{UseVirtualKeyboard} -import QtQuick.VirtualKeyboard %{QtQuickVersion} +import QtQuick.VirtualKeyboard @endif Window { diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json index bbdb40dcd22..81c0baae42d 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json @@ -18,7 +18,6 @@ { "key": "ProjectPluginName", "value": "%{ProjectName}plugin" }, { "key": "ProjectPluginClassName", "value": "%{ProjectName}Plugin" }, { "key": "QmlProjectFileName", "value": "%{JS: Util.fileName('%{ProjectName}', 'qmlproject')}" }, - { "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" }, { "key": "AssetDir", "value": "Generated" }, { "key": "ContentDir", "value": "%{ProjectName}Content" }, { "key": "ImportModuleName", "value": "%{ProjectName}" }, @@ -28,13 +27,12 @@ { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }, { "key": "QtQuickControlsStyle", "value": "Basic" }, { "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" }, - { "key": "ApplicationImport", "value": "%{JS: value('IsQt6Project') === 'true' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" }, + { "key": "ApplicationImport", "value": "%{ImportModuleName}" }, { "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" }, { "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" }, { "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" }, { "key": "UseVirtualKeyboardDefault", "value": "%{JS: false}" }, - { "key": "QtQuick3DVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuick3DVersion}" }, - { "key": "ImportModuleVersion", "value": "%{JS: value('IsQt6Project') === 'true' ? '' : '1.0'}" } + { "key": "QtQuick3DVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuick3DVersion}" } ], "pages": diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/Screen01.ui.qml.tpl index 41d562fb53e..14a27734bba 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/Screen01.ui.qml.tpl @@ -5,12 +5,12 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick %{QtQuickVersion} -import QtQuick.Controls %{QtQuickVersion} -import QtQuick3D %{QtQuick3DVersion} -import QtQuick3D.Effects %{QtQuick3DVersion} -import QtQuick3D.Helpers %{QtQuick3DVersion} -import %{ImportModuleName} %{ImportModuleVersion} +import QtQuick +import QtQuick.Controls +import QtQuick3D +import QtQuick3D.Effects +import QtQuick3D.Helpers +import %{ImportModuleName} Rectangle { width: Constants.width diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/contentmodule.main.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/contentmodule.main.qml.tpl index 96f5dbaa36c..a5004b82200 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/contentmodule.main.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/contentmodule.main.qml.tpl @@ -1,10 +1,7 @@ -import QtQuick %{QtQuickVersion} -@if !%{IsQt6Project} -import QtQuick.Window %{QtQuickVersion} -@endif +import QtQuick import %{ApplicationImport} @if %{UseVirtualKeyboard} -import QtQuick.VirtualKeyboard %{QtQuickVersion} +import QtQuick.VirtualKeyboard @endif Window { diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/wizard.json index d328dedb779..fa7677fa5ea 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/wizard.json @@ -18,7 +18,6 @@ { "key": "ProjectPluginName", "value": "%{ProjectName}plugin" }, { "key": "ProjectPluginClassName", "value": "%{ProjectName}Plugin" }, { "key": "QmlProjectFileName", "value": "%{JS: Util.fileName('%{ProjectName}', 'qmlproject')}" }, - { "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" }, { "key": "AssetDir", "value": "Generated" }, { "key": "ContentDir", "value": "%{ProjectName}Content" }, { "key": "ImportModuleName", "value": "%{ProjectName}" }, @@ -28,13 +27,12 @@ { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }, { "key": "QtQuickControlsStyle", "value": "Basic" }, { "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" }, - { "key": "ApplicationImport", "value": "%{JS: value('IsQt6Project') === 'true' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" }, + { "key": "ApplicationImport", "value": "%{ImportModuleName}" }, { "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" }, { "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" }, { "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" }, { "key": "UseVirtualKeyboardDefault", "value": "%{JS: false}" }, - { "key": "QtQuick3DVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuick3DVersion}" }, - { "key": "ImportModuleVersion", "value": "%{JS: value('IsQt6Project') === 'true' ? '' : '1.0'}" } + { "key": "QtQuick3DVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuick3DVersion}" } ], "pages": diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/application/Screen01.ui.qml.tpl index a25bcb9d17a..886fe0d06a4 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application/Screen01.ui.qml.tpl @@ -5,9 +5,9 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick %{QtQuickVersion} -import QtQuick.Controls %{QtQuickVersion} -import %{ImportModuleName} %{ImportModuleVersion} +import QtQuick +import QtQuick.Controls +import %{ImportModuleName} Rectangle { id: rectangle diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json index 168ab5b66de..5c2ee9ab3bd 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json @@ -22,18 +22,16 @@ { "key": "ImportModuleName", "value": "%{ProjectName}" }, { "key": "UIClassName", "value": "Screen01" }, { "key": "UIClassFileName", "value": "%{JS: Util.fileName('%{UIClassName}', 'ui.qml')}" }, - { "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" }, { "key": "QtQuickVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuickVersion}" }, { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }, { "key": "QtQuickControlsStyle", "value": "Basic" }, { "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" }, - { "key": "ApplicationImport", "value": "%{JS: value('IsQt6Project') === 'true' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" }, + { "key": "ApplicationImport", "value": "%{ImportModuleName}" }, { "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" }, { "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" }, { "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" }, { "key": "UseVirtualKeyboardDefault", "value": "%{JS: false}" }, - { "key": "DefaultStyle", "value": "Basic" }, - { "key": "ImportModuleVersion", "value": "%{JS: value('IsQt6Project') === 'true' ? '' : '1.0'}" } + { "key": "DefaultStyle", "value": "Basic" } ], "pages": diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/common/App.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/common/App.qml.tpl index 8fa8b6e4c7d..5a440eddccc 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/common/App.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/common/App.qml.tpl @@ -1,13 +1,10 @@ // Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only -import QtQuick %{QtQuickVersion} -@if !%{IsQt6Project} -import QtQuick.Window %{QtQuickVersion} -@endif -import %{ImportModuleName} %{ImportModuleVersion} +import QtQuick +import %{ImportModuleName} @if %{UseVirtualKeyboard} -import QtQuick.VirtualKeyboard %{QtQuickVersion} +import QtQuick.VirtualKeyboard @endif Window { diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl index 6d346818e41..dd2d4fb5efa 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl @@ -1,8 +1,4 @@ -@if %{IsQt6Project} import QmlProject -@else -import QmlProject 1.1 -@endif Project { mainFile: "%{ContentDir}/App.qml" @@ -85,10 +81,6 @@ Project { QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf" QT_AUTO_SCREEN_SCALE_FACTOR: "1" QML_COMPAT_RESOLVE_URLS_ON_ASSIGNMENT: "1" -@if %{IsQt6Project} -@else - QMLSCENE_CORE_PROFILE: "true" // Required for macOS, but can create issues on embedded Linux -@endif @if %{UseVirtualKeyboard} QT_IM_MODULE: "qtvirtualkeyboard" QT_VIRTUALKEYBOARD_DESKTOP_DISABLE: 1 @@ -103,9 +95,7 @@ Project { */ } -@if %{IsQt6Project} qt6Project: true -@endif /* List of plugin directories passed to QML runtime */ importPaths: [ "." ] @@ -117,7 +107,6 @@ Project { quickVersion: "%{QtQuickVersion}" -@if %{IsQt6Project} /* If any modules the project imports require widgets (e.g. QtCharts), widgetApp must be true */ widgetApp: true @@ -129,7 +118,6 @@ Project { args: "-s --glsl \\\"100 es,120,150\\\" --hlsl 50 --msl 12" files: [ "%{ContentDir}/shaders/*" ] } -@endif multilanguageSupport: true supportedLanguages: ["en"] diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/Screen01.ui.qml.tpl index 1527710b087..dbb9e39d440 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/Screen01.ui.qml.tpl @@ -5,9 +5,9 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick %{QtQuickVersion} -import QtQuick.Controls %{QtQuickVersion} -import %{ImportModuleName} %{ImportModuleVersion} +import QtQuick +import QtQuick.Controls +import %{ImportModuleName} Rectangle { width: Constants.width diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json index 4ddc07a83a6..da47ce36111 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json @@ -22,17 +22,15 @@ { "key": "ImportModuleName", "value": "%{ProjectName}" }, { "key": "UIClassName", "value": "Screen01" }, { "key": "UIClassFileName", "value": "%{JS: Util.fileName('%{UIClassName}', 'ui.qml')}" }, - { "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" }, { "key": "QtQuickVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuickVersion}" }, { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }, { "key": "QtQuickControlsStyle", "value": "Basic" }, { "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" }, - { "key": "ApplicationImport", "value": "%{JS: value('IsQt6Project') === 'true' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" }, + { "key": "ApplicationImport", "value": "%{ImportModuleName}" }, { "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" }, { "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" }, { "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" }, { "key": "UseVirtualKeyboardDefault", "value": "%{JS: false}" }, - { "key": "ImportModuleVersion", "value": "%{JS: value('IsQt6Project') === 'true' ? '' : '1.0'}" } ], "pages": diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/Screen01.ui.qml.tpl index 97f9fdd87c9..dde29354b0f 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/Screen01.ui.qml.tpl @@ -5,9 +5,9 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick %{QtQuickVersion} -import QtQuick.Controls %{QtQuickVersion} -import %{ImportModuleName} %{ImportModuleVersion} +import QtQuick +import QtQuick.Controls +import %{ImportModuleName} Rectangle { width: Constants.width diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json index 7828254ea61..4206c05b5b7 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json @@ -22,17 +22,15 @@ { "key": "ImportModuleName", "value": "%{ProjectName}" }, { "key": "UIClassName", "value": "Screen01" }, { "key": "UIClassFileName", "value": "%{JS: Util.fileName('%{UIClassName}', 'ui.qml')}" }, - { "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" }, { "key": "QtQuickVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuickVersion}" }, { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }, { "key": "QtQuickControlsStyle", "value": "Basic" }, { "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" }, - { "key": "ApplicationImport", "value": "%{JS: value('IsQt6Project') === 'true' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" }, + { "key": "ApplicationImport", "value": "%{ImportModuleName}" }, { "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" }, { "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" }, { "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" }, - { "key": "UseVirtualKeyboard", "value": "%{JS: false}" }, - { "key": "ImportModuleVersion", "value": "%{JS: value('IsQt6Project') === 'true' ? '' : '1.0'}" } + { "key": "UseVirtualKeyboard", "value": "%{JS: false}" } ], "pages": diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/App.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/App.qml.tpl index abddf3d0c11..8b7a78b0311 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/App.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/App.qml.tpl @@ -1,9 +1,6 @@ -import QtQuick %{QtQuickVersion} -import QtQuick.Controls %{QtQuickVersion} -@if !%{IsQt6Project} -import QtQuick.Window %{QtQuickVersion} -@endif -import %{ImportModuleName} %{ImportModuleVersion} +import QtQuick +import QtQuick.Controls +import %{ImportModuleName} Window { id: root diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen01.ui.qml.tpl index 40c91d79f37..df9d324d0b1 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen01.ui.qml.tpl @@ -5,9 +5,9 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick %{QtQuickVersion} -import QtQuick.Controls %{QtQuickVersion} -import %{ImportModuleName} %{ImportModuleVersion} +import QtQuick +import QtQuick.Controls +import %{ImportModuleName} Rectangle { width: Constants.width diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen02.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen02.ui.qml.tpl index 100fef9bb99..d2e81451f04 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen02.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/Screen02.ui.qml.tpl @@ -5,8 +5,8 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick %{QtQuickVersion} -import %{ImportModuleName} %{ImportModuleVersion} +import QtQuick +import %{ImportModuleName} Rectangle { width: Constants.width diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json index 988d3a6575d..322a83cc8bf 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json @@ -20,17 +20,15 @@ { "key": "AssetDir", "value": "Generated" }, { "key": "ContentDir", "value": "%{ProjectName}Content" }, { "key": "ImportModuleName", "value": "%{ProjectName}" }, - { "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" }, { "key": "QtQuickVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuickVersion}" }, { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }, { "key": "QtQuickControlsStyle", "value": "Basic" }, { "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" }, - { "key": "ApplicationImport", "value": "%{JS: value('IsQt6Project') === 'true' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" }, + { "key": "ApplicationImport", "value": "%{ImportModuleName}" }, { "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" }, { "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" }, { "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" }, - { "key": "UseVirtualKeyboard", "value": "%{JS: false}" }, - { "key": "ImportModuleVersion", "value": "%{JS: value('IsQt6Project') === 'true' ? '' : '1.0'}" } + { "key": "UseVirtualKeyboard", "value": "%{JS: false}" } ], "pages": diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/App.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/App.qml.tpl index 0937e1288eb..c466977dc81 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/App.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/App.qml.tpl @@ -1,9 +1,6 @@ -import QtQuick %{QtQuickVersion} -import QtQuick.Controls %{QtQuickVersion} -@if !%{IsQt6Project} -import QtQuick.Window %{QtQuickVersion} -@endif -import %{ImportModuleName} %{ImportModuleVersion} +import QtQuick +import QtQuick.Controls +import %{ImportModuleName} Window { width: Constants.width diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen01.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen01.ui.qml.tpl index 3816fb7a001..d80d241ed35 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen01.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen01.ui.qml.tpl @@ -5,9 +5,9 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick %{QtQuickVersion} -import QtQuick.Controls %{QtQuickVersion} -import %{ImportModuleName} %{ImportModuleVersion} +import QtQuick +import QtQuick.Controls +import %{ImportModuleName} Rectangle { width: Constants.width diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen02.ui.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen02.ui.qml.tpl index 9e741b11627..6678c379356 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen02.ui.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/Screen02.ui.qml.tpl @@ -5,9 +5,9 @@ this file manually, you might introduce QML code that is not supported by Qt Des Check out https://doc.qt.io/qtcreator/creator-quick-ui-forms.html for details on .ui.qml files. */ -import QtQuick %{QtQuickVersion} -import QtQuick.Controls %{QtQuickVersion} -import %{ImportModuleName} %{ImportModuleVersion} +import QtQuick +import QtQuick.Controls +import %{ImportModuleName} Rectangle { width: Constants.width diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json index daa20961b76..9eb1b367c0b 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json @@ -20,17 +20,15 @@ { "key": "AssetDir", "value": "Generated" }, { "key": "ContentDir", "value": "%{ProjectName}Content" }, { "key": "ImportModuleName", "value": "%{ProjectName}" }, - { "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" }, { "key": "QtQuickVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuickVersion}" }, { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }, { "key": "QtQuickControlsStyle", "value": "Basic" }, { "key": "QtQuickControlsStyleTheme", "value": "%{JS: %{ControlsStyle}.QtQuickControlsStyleTheme}" }, - { "key": "ApplicationImport", "value": "%{JS: value('IsQt6Project') === 'true' ? '%{ImportModuleName}' : '%{ImportModuleName} 1.0'}" }, + { "key": "ApplicationImport", "value": "%{ImportModuleName}" }, { "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" }, { "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" }, { "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" }, - { "key": "UseVirtualKeyboard", "value": "%{JS: false}" }, - { "key": "ImportModuleVersion", "value": "%{JS: value('IsQt6Project') === 'true' ? '' : '1.0'}" } + { "key": "UseVirtualKeyboard", "value": "%{JS: false}" } ], "pages": diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/Constants.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/Constants.qml.tpl index 2d0b96dd04b..6beb24f6456 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/Constants.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/Constants.qml.tpl @@ -1,9 +1,5 @@ pragma Singleton -import QtQuick %{QtQuickVersion} -@if %{IsQt6Project} -import QtQuick.Studio.Application -@else -@endif +import QtQuick QtObject { readonly property int width: %{ScreenWidth} @@ -24,13 +20,7 @@ QtObject { readonly property color backgroundColor: "#EAEAEA" -@if %{IsQt6Project} property StudioApplication application: StudioApplication { fontPath: Qt.resolvedUrl("../%{ContentDir}/" + relativeFontDirectory) } -@else - property DirectoryFontLoader directoryFontLoader: DirectoryFontLoader { - id: directoryFontLoader - } -@endif } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/DirectoryFontLoader.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/DirectoryFontLoader.qml.tpl index 56ecc9f2f8f..756b8f9d06d 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/DirectoryFontLoader.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/DirectoryFontLoader.qml.tpl @@ -1,8 +1,8 @@ // Copyright (C) 2019 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only -import QtQuick %{QtQuickVersion} -import Qt.labs.folderlistmodel %{QtQuickVersion} +import QtQuick +import Qt.labs.folderlistmodel QtObject { id: loader diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/EventListModel.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/EventListModel.qml.tpl index 25b6dc33772..c5cf4391360 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/EventListModel.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/EventListModel.qml.tpl @@ -1,7 +1,7 @@ // Copyright (C) 2018 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only -import QtQuick %{QtQuickVersion} +import QtQuick ListModel { id: eventListModel diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/EventListSimulator.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/EventListSimulator.qml.tpl index 08b490abd88..a2250ad5aa5 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/EventListSimulator.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/EventListSimulator.qml.tpl @@ -1,9 +1,9 @@ // Copyright (C) 2018 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only -import QtQuick %{QtQuickVersion} -import QtQuick.Studio.EventSimulator 1.0 -import QtQuick.Studio.EventSystem 1.0 +import QtQuick +import QtQuick.Studio.EventSimulator +import QtQuick.Studio.EventSystem QtObject { id: simulator diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/JsonData.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/JsonData.qml.tpl index a49600e2704..c9d975c80ce 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/JsonData.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/JsonData.qml.tpl @@ -1,6 +1,6 @@ -import QtQuick 2.15 -import QtQuick.Controls 2.15 -import QtQuick.Studio.Utils 1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Studio.Utils JsonBackend { property string name: "someName" From aff1e397b86b6a855776f804890126c276c734a5 Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Mon, 12 Aug 2024 15:30:52 +0200 Subject: [PATCH 022/193] QmlDesigner: fix missing import QtQuick.Studio.Application Got accidentally removed Change-Id: I3a8eec4f1b47851846eb58ea819a702b543bcdcd Reviewed-by: Tim Jenssen --- .../projects/shared-plugin/name/Constants.qml.tpl | 1 + 1 file changed, 1 insertion(+) diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/Constants.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/Constants.qml.tpl index 6beb24f6456..6e1c8b753a5 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/Constants.qml.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/Constants.qml.tpl @@ -1,5 +1,6 @@ pragma Singleton import QtQuick +import QtQuick.Studio.Application QtObject { readonly property int width: %{ScreenWidth} From 1d791cc0a1000c6b2a6cc891d0a5bfdf465b8275 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 12 Aug 2024 15:46:31 +0300 Subject: [PATCH 023/193] EffectComposer: Fix error message Line number is now properly replaced in template string. Change-Id: Ie05b3bc0529df13576d527ff4b960243400f9a15 Reviewed-by: Mahmoud Badri --- src/plugins/effectcomposer/effectcomposermodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/effectcomposer/effectcomposermodel.cpp b/src/plugins/effectcomposer/effectcomposermodel.cpp index 41ad13b2485..d9c329b1f38 100644 --- a/src/plugins/effectcomposer/effectcomposermodel.cpp +++ b/src/plugins/effectcomposer/effectcomposermodel.cpp @@ -427,7 +427,7 @@ void EffectComposerModel::setEffectError(const QString &errorMessage, int type, QString additionalErrorInfo = detectErrorMessage(errorMessage); error.m_message = additionalErrorInfo + errorMessage; m_effectErrors.insert(type, error); - qWarning() << QString("Effect error (line: %2): %1").arg(error.m_message, error.m_line); + qWarning() << QString("Effect error (line: %2): %1").arg(error.m_message).arg(error.m_line); Q_EMIT effectErrorChanged(); } From 9bb6683e76e16dcc9320b73a9e30d73999c1bfda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Jen=C3=9Fen?= Date: Mon, 12 Aug 2024 10:53:21 +0200 Subject: [PATCH 024/193] QmlDesigner: fix crash in ADS Ownership of the DockAreaWidget and m_widget is not clear. So use QPointer to be save. Task-number: QDS-12111 Change-Id: I048ed72f7e8a119a83c36bfdeee8b1e60108f564 Reviewed-by: Marco Bubke --- src/libs/advanceddockingsystem/dockwidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/advanceddockingsystem/dockwidget.cpp b/src/libs/advanceddockingsystem/dockwidget.cpp index a46fae58bef..aa240fdd587 100644 --- a/src/libs/advanceddockingsystem/dockwidget.cpp +++ b/src/libs/advanceddockingsystem/dockwidget.cpp @@ -44,11 +44,11 @@ public: DockWidget *q = nullptr; QBoxLayout *m_layout = nullptr; - QWidget *m_widget = nullptr; + QPointer m_widget; DockWidgetTab *m_tabWidget = nullptr; DockWidget::DockWidgetFeatures m_features = DockWidget::DefaultDockWidgetFeatures; DockManager *m_dockManager = nullptr; - DockAreaWidget *m_dockArea = nullptr; + QPointer m_dockArea; QAction *m_toggleViewAction = nullptr; bool m_closed = false; bool m_focused = false; From a53ebfcc441013ba06b69b89a3dd2b113fcbc26a Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Mon, 12 Aug 2024 15:58:14 +0200 Subject: [PATCH 025/193] Revert "QmlDesigner: Remove initial reparenting of all items to root item" This creates problems with anchors: QQuickText: Cannot anchor to an item that isn't a parent or sibling. This reverts commit 778839be5f612f4a1486d215b0a86d2c17d7e077. Task-number: QDS-13294 Change-Id: I8cd8695e3f376f15b92c75a67d81c4742e2c56b3 Reviewed-by: Tim Jenssen --- .../qml2puppet/qml2puppet/instances/quickitemnodeinstance.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.cpp b/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.cpp index 87ce62e61d4..945c66f31d7 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.cpp @@ -150,6 +150,8 @@ void QuickItemNodeInstance::initialize(const ObjectNodeInstance::Pointer &object if (instanceId() == 0) nodeInstanceServer()->setRootItem(quickItem()); + else + quickItem()->setParentItem(nodeInstanceServer()->rootItem()); ObjectNodeInstance::initialize(objectNodeInstance, flags); } From 1d27ae8e215e0b823025d4ad5c0082a01ecb3dc6 Mon Sep 17 00:00:00 2001 From: Shrief Gabr Date: Mon, 12 Aug 2024 17:39:58 +0300 Subject: [PATCH 026/193] QmlDesigner: Shift Assets View thumbnail to prevent clipping Fixes: QDS-13350 Change-Id: I43dba7229be86f6cdb53938f594a845ad12a0af8 Reviewed-by: Mahmoud Badri --- .../qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml index bb59e197442..2877c4061bf 100644 --- a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml +++ b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml @@ -315,7 +315,7 @@ TreeViewDelegate { id: thumbnailImage visible: !root.__isDirectory y: StudioTheme.Values.border - x: bg.x + x: bg.x + StudioTheme.Values.border width: 48 height: 48 cache: false From f759e71dc7f88be05e1e96976b8494a13bbc436b Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 12 Aug 2024 15:49:50 +0300 Subject: [PATCH 027/193] EffectComposer: Better UX for opening effect compositions Now a composed effect can be opened with these additional ways: - Right click on composed effect in navigator or assets view and select "Edit in Effect Composer" - Drag composed effect from navigator or assets view into Effect Composer view. Fixes: QDS-13343 Change-Id: I70a12a44dcb08cbbaf06b9df52a34300fa8e6e81 Reviewed-by: Mahmoud Badri --- .../AssetsContextMenu.qml | 9 +++ .../EffectComposer.qml | 27 ++++++++ .../effectcomposer/effectcomposerwidget.cpp | 61 +++++++++++++++---- .../effectcomposer/effectcomposerwidget.h | 8 ++- .../assetslibrary/assetslibrarymodel.cpp | 7 +++ .../assetslibrary/assetslibrarymodel.h | 1 + .../componentcore/componentcore_constants.h | 3 + .../componentcore/designeractionmanager.cpp | 13 +++- .../modelnodecontextmenu_helper.h | 9 +++ .../componentcore/modelnodeoperations.cpp | 47 +++++++++++++- .../componentcore/modelnodeoperations.h | 2 + src/plugins/qmldesigner/utils/asset.h | 4 +- 12 files changed, 172 insertions(+), 19 deletions(-) diff --git a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsContextMenu.qml b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsContextMenu.qml index fe22d7ce51f..3402c56aa8c 100644 --- a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsContextMenu.qml +++ b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsContextMenu.qml @@ -120,6 +120,15 @@ StudioControls.Menu { height: visible ? StudioTheme.Values.border : 0 } + StudioControls.MenuItem { + id: editInEffectComposerItem + text: qsTr("Edit in Effect Composer") + visible: root.__fileIndex && root.__selectedAssetPathsList.length === 1 + && root.assetsModel.allFilePathsAreComposedEffects(root.__selectedAssetPathsList) + height: editInEffectComposerItem.visible ? editInEffectComposerItem.implicitHeight : 0 + onTriggered: AssetsLibraryBackend.rootView.openEffectComposer(root.__selectedAssetPathsList[0]) + } + StudioControls.MenuItem { id: addTexturesItem text: qsTr("Add Texture") diff --git a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposer.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposer.qml index b327c1049d3..c32ed10a36d 100644 --- a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposer.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposer.qml @@ -383,4 +383,31 @@ ColumnLayout { root.handleDragMove() } } // Timer + + DropArea { + id: dropArea + + anchors.fill: parent + + onEntered: (drag) => { + let accepted = false + if (drag.formats[0] === "application/vnd.qtdesignstudio.assets" && drag.hasUrls) { + accepted = EffectComposerBackend.rootView.isEffectAsset(drag.urls[0]) + } else if (drag.formats[0] === "application/vnd.qtdesignstudio.modelnode.list") { + accepted = EffectComposerBackend.rootView.isEffectNode( + drag.getDataAsArrayBuffer("application/vnd.qtdesignstudio.modelnode.list")) + } + drag.accepted = accepted + } + + onDropped: (drop) => { + if (drop.formats[0] === "application/vnd.qtdesignstudio.assets" && drop.hasUrls) { + EffectComposerBackend.rootView.dropAsset(drop.urls[0]) + } else if (drop.formats[0] === "application/vnd.qtdesignstudio.modelnode.list") { + EffectComposerBackend.rootView.dropNode( + drop.getDataAsArrayBuffer("application/vnd.qtdesignstudio.modelnode.list")) + } + drop.accept() + } + } } diff --git a/src/plugins/effectcomposer/effectcomposerwidget.cpp b/src/plugins/effectcomposer/effectcomposerwidget.cpp index 48bb5e410e1..ea96d7cd363 100644 --- a/src/plugins/effectcomposer/effectcomposerwidget.cpp +++ b/src/plugins/effectcomposer/effectcomposerwidget.cpp @@ -10,6 +10,8 @@ #include "effectutils.h" #include "propertyhandler.h" +#include +#include #include #include @@ -19,6 +21,7 @@ #include #include #include +#include #include #include @@ -45,6 +48,23 @@ static QString propertyEditorResourcesPath() return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString(); } +static QList modelNodesFromMimeData(const QByteArray &mimeData, + QmlDesigner::AbstractView *view) +{ + QByteArray encodedModelNodeData = mimeData; + QDataStream modelNodeStream(&encodedModelNodeData, QIODevice::ReadOnly); + + QList modelNodeList; + while (!modelNodeStream.atEnd()) { + qint32 internalId; + modelNodeStream >> internalId; + if (view->hasModelNodeForInternalId(internalId)) + modelNodeList.append(view->modelNodeForInternalId(internalId)); + } + + return modelNodeList; +} + EffectComposerWidget::EffectComposerWidget(EffectComposerView *view) : m_effectComposerModel{new EffectComposerModel(this)} , m_effectComposerNodesModel{new EffectComposerNodesModel(this)} @@ -54,8 +74,6 @@ EffectComposerWidget::EffectComposerWidget(EffectComposerView *view) setWindowTitle(tr("Effect Composer", "Title of effect composer widget")); setMinimumWidth(250); - m_quickWidget->quickWidget()->installEventFilter(this); - // create the inner widget m_quickWidget->quickWidget()->setObjectName(QmlDesigner::Constants::OBJECT_NAME_EFFECT_COMPOSER); m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView); @@ -130,17 +148,6 @@ EffectComposerWidget::EffectComposerWidget(EffectComposerView *view) }); } - -bool EffectComposerWidget::eventFilter(QObject *obj, QEvent *event) -{ - Q_UNUSED(obj) - Q_UNUSED(event) - - // TODO - - return false; -} - void EffectComposerWidget::contextHelp(const Core::IContext::HelpCallback &callback) const { Q_UNUSED(callback) @@ -201,6 +208,34 @@ QString EffectComposerWidget::imagesPath() const return Core::ICore::resourcePath("qmldesigner/effectComposerNodes/images").toString(); } +bool EffectComposerWidget::isEffectAsset(const QUrl &url) const +{ + return QmlDesigner::Asset(url.toLocalFile()).isEffect(); +} + +void EffectComposerWidget::dropAsset(const QUrl &url) +{ + if (isEffectAsset(url)) + openComposition(url.toLocalFile()); +} + +bool EffectComposerWidget::isEffectNode(const QByteArray &mimeData) const +{ + QList nodes = modelNodesFromMimeData(mimeData, m_effectComposerView); + if (!nodes.isEmpty()) + return QmlDesigner::QmlItemNode(nodes.last()).isEffectItem(); + return false; +} + +void EffectComposerWidget::dropNode(const QByteArray &mimeData) +{ + QList nodes = modelNodesFromMimeData(mimeData, m_effectComposerView); + if (!nodes.isEmpty() && QmlDesigner::QmlItemNode(nodes.last()).isEffectItem()) { + Utils::FilePath path = QmlDesigner::ModelNodeOperations::findEffectFile(nodes.last()); + openComposition(path.toFSPathString()); + } +} + QSize EffectComposerWidget::sizeHint() const { return {420, 420}; diff --git a/src/plugins/effectcomposer/effectcomposerwidget.h b/src/plugins/effectcomposer/effectcomposerwidget.h index aa9cb750d8e..081627e9509 100644 --- a/src/plugins/effectcomposer/effectcomposerwidget.h +++ b/src/plugins/effectcomposer/effectcomposerwidget.h @@ -10,6 +10,7 @@ #include #include +#include class StudioQuickWidget; @@ -53,12 +54,13 @@ public: Q_INVOKABLE QString uniformDefaultImage(const QString &nodeName, const QString &uniformName) const; Q_INVOKABLE QString imagesPath() const; + Q_INVOKABLE bool isEffectAsset(const QUrl &url) const; + Q_INVOKABLE void dropAsset(const QUrl &url); + Q_INVOKABLE bool isEffectNode(const QByteArray &mimeData) const; + Q_INVOKABLE void dropNode(const QByteArray &mimeData); QSize sizeHint() const override; -protected: - bool eventFilter(QObject *obj, QEvent *event) override; - private: void reloadQmlSource(); void handleImportScanTimer(); diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp index 7f488bd6153..2a496f6bf38 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp @@ -188,6 +188,13 @@ bool AssetsLibraryModel::allFilePathsAreTextures(const QStringList &filePaths) c }); } +bool AssetsLibraryModel::allFilePathsAreComposedEffects(const QStringList &filePaths) const +{ + return Utils::allOf(filePaths, [](const QString &path) { + return Asset(path).isEffect(); + }); +} + bool AssetsLibraryModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { QString path = m_sourceFsModel->filePath(sourceParent); diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h index f08578651af..986ad4cc205 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h @@ -49,6 +49,7 @@ public: Q_INVOKABLE QString addNewFolder(const QString &folderPath); Q_INVOKABLE bool deleteFolderRecursively(const QModelIndex &folderIndex); Q_INVOKABLE bool allFilePathsAreTextures(const QStringList &filePaths) const; + Q_INVOKABLE bool allFilePathsAreComposedEffects(const QStringList &filePaths) const; int columnCount(const QModelIndex &parent = QModelIndex()) const override { diff --git a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h index 644a7227498..e21ed39d6fb 100644 --- a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h +++ b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h @@ -86,6 +86,7 @@ inline constexpr char fitSelectionToScreenCommandId[] = "FitSelectionToScreen"; inline constexpr char editAnnotationsCommandId[] = "EditAnnotation"; inline constexpr char addMouseAreaFillCommandId[] = "AddMouseAreaFill"; inline constexpr char editIn3dViewCommandId[] = "editIn3dView"; +inline constexpr char editInEffectComposerCommandId[] = "editInEffectComposer"; inline constexpr char openSignalDialogCommandId[] = "OpenSignalDialog"; inline constexpr char update3DAssetCommandId[] = "Update3DAsset"; @@ -173,6 +174,8 @@ inline constexpr char addMouseAreaFillDisplayName[] = QT_TRANSLATE_NOOP("QmlDesi "Add Mouse Area"); inline constexpr char editIn3dViewDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit in 3D View"); +inline constexpr char editInEffectComposerDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", + "Edit in Effect Composer"); inline constexpr char openSignalDialogDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Open Signal Dialog"); diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index c39c9b9e68f..301940e39ff 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -1909,7 +1909,7 @@ void DesignerActionManager::createDefaultDesignerActions() contextIcon(DesignerIcons::EnterComponentIcon), rootCategory, QKeySequence(Qt::Key_F2), - Priorities::ComponentActions + 3, + Priorities::ComponentActions + 4, &goIntoComponentOperation, &selectionIsEditableComponent)); @@ -1978,6 +1978,17 @@ void DesignerActionManager::createDefaultDesignerActions() &singleSelection, &singleSelection)); + addDesignerAction(new ModelNodeContextMenuAction( + editInEffectComposerCommandId, + editInEffectComposerDisplayName, + contextIcon(DesignerIcons::EditIcon), + rootCategory, + QKeySequence(), + Priorities::ComponentActions + 3, + &editInEffectComposer, + &SelectionContextFunctors::always, // If action is visible, it is usable + &singleSelectionEffectComposer)); + addDesignerAction(new ModelNodeContextMenuAction( importComponentCommandId, importComponentDisplayName, diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h index 98ea60f7690..e728f54adae 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h @@ -135,6 +135,15 @@ inline bool singleSelectionView3D(const SelectionContext &selectionState) return false; } +inline bool singleSelectionEffectComposer(const SelectionContext &selectionState) +{ + if (selectionState.hasSingleSelectedModelNode()) { + QmlItemNode targetNode = selectionState.currentSingleSelectedNode(); + return targetNode.isEffectItem(); + } + return false; +} + inline bool selectionHasProperty(const SelectionContext &selectionState, const char *property) { for (const ModelNode &modelNode : selectionState.selectedModelNodes()) diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index cb5b4a46fbb..d2b94e47b44 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -1718,6 +1718,51 @@ void editIn3dView(const SelectionContext &selectionContext) } } +Utils::FilePath findEffectFile(const ModelNode &effectNode) +{ + const QString effectFile = effectNode.simplifiedTypeName() + ".qep"; + Utils::FilePath effectPath = Utils::FilePath::fromString(getEffectsDefaultDirectory() + + '/' + effectFile); + if (!effectPath.exists()) { + // Scan the project's content folder for a matching effect + Utils::FilePath contentPath = QmlDesignerPlugin::instance()->documentManager().currentResourcePath(); + const Utils::FilePaths matches = contentPath.dirEntries({{effectFile}, QDir::Files, + QDirIterator::Subdirectories}); + if (matches.isEmpty()) { + QMessageBox msgBox; + msgBox.setText(QObject::tr("Effect file %1 not found in the project.").arg(effectFile)); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setDefaultButton(QMessageBox::Ok); + msgBox.setIcon(QMessageBox::Warning); + msgBox.exec(); + return {}; + } + effectPath = matches[0]; + } + + return effectPath; +} + +void editInEffectComposer(const SelectionContext &selectionContext) +{ + if (!selectionContext.view()) + return; + + QmlItemNode targetNode; + + if (selectionContext.hasSingleSelectedModelNode()) { + targetNode = selectionContext.currentSingleSelectedNode(); + if (!targetNode.isEffectItem()) + return; + } + + if (targetNode.isValid()) { + Utils::FilePath effectPath = findEffectFile(targetNode); + if (!effectPath.isEmpty()) + openEffectComposer(effectPath.toFSPathString()); + } +} + bool isEffectComposerActivated() { const ExtensionSystem::PluginSpecs specs = ExtensionSystem::PluginManager::plugins(); @@ -1731,9 +1776,9 @@ bool isEffectComposerActivated() void openEffectComposer(const QString &filePath) { if (ModelNodeOperations::isEffectComposerActivated()) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("EffectComposer", true); QmlDesignerPlugin::instance()->viewManager() .emitCustomNotification("open_effectcomposer_composition", {}, {filePath}); - QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("EffectComposer", true); } else { ModelNodeOperations::openOldEffectMaker(filePath); } diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h index fb8ff5826d5..d8fe9c7906d 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h @@ -127,6 +127,8 @@ void addMouseAreaFill(const SelectionContext &selectionContext); void openSignalDialog(const SelectionContext &selectionContext); void updateImported3DAsset(const SelectionContext &selectionContext); void editIn3dView(const SelectionContext &selectionContext); +QMLDESIGNERCOMPONENTS_EXPORT Utils::FilePath findEffectFile(const ModelNode &effectNode); +void editInEffectComposer(const SelectionContext &selectionContext); QMLDESIGNERCOMPONENTS_EXPORT Utils::FilePath getEffectsImportDirectory(); QMLDESIGNERCOMPONENTS_EXPORT QString getEffectsDefaultDirectory(const QString &defaultDir = {}); diff --git a/src/plugins/qmldesigner/utils/asset.h b/src/plugins/qmldesigner/utils/asset.h index a5c5899f34f..1deafd11b78 100644 --- a/src/plugins/qmldesigner/utils/asset.h +++ b/src/plugins/qmldesigner/utils/asset.h @@ -3,6 +3,8 @@ #pragma once +#include "qmldesignerutils_global.h" + #include #include @@ -10,7 +12,7 @@ QT_FORWARD_DECLARE_CLASS(QPixmap) namespace QmlDesigner { -class Asset +class QMLDESIGNERUTILS_EXPORT Asset { public: enum Type { Unknown, From 53184f2ca507db81c4350000ff44a0e15f703908 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 9 Aug 2024 13:02:27 +0200 Subject: [PATCH 028/193] QmlDesigner: Remove forward declaration in model resource management Using concepts makes it much more readable to provide actions by parameter and not member. That removes the need of a forward declaration of the NodeACtion class. So now the declaration of NodeActions is automatically created by CTAD. So adding new actions should be easier. The NodeAction concept is providing early errors. So the interface of an action is defined. Cleanup forgotten metainfo. Change-Id: Iee1bd36af556d5b753aaeb6b8ab7295f3f3378c1 Reviewed-by: Aleksei German --- .../model/modelresourcemanagement.cpp | 288 +++++++++--------- 1 file changed, 136 insertions(+), 152 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp b/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp index 302a0c86def..eb5373b35a2 100644 --- a/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp @@ -15,24 +15,51 @@ #include #include +#include #include +QT_WARNING_DISABLE_GCC("-Wmissing-field-initializers") + namespace QmlDesigner { namespace { enum class CheckRecursive { No, Yes }; -class NodeActions; +struct Base; -template -void forEachAction(NodeActions &nodeActions, ActionCall actionCall); +template +concept NodeAction = std::derived_from + && requires(T t, + ModelNodes nodes, + AbstractProperties properties, + ModelResourceSet &resources, + CheckRecursive checkRecursive, + std::tuple &actions) { + t.removeNodes(nodes, checkRecursive, actions); + t.checkModelNodes(nodes, actions); + t.removeProperties(properties, checkRecursive, actions); + t.finally(); + t.handleNodes(nodes, actions); + t.handleProperties(properties, actions); + t.setModelResourceSet(resources); + }; + +template +concept NodeActions = requires(T nodeActions) { + std::apply([](NodeAction auto &...) {}, nodeActions); +}; + +void forEachAction(NodeActions auto &nodeActions, auto &&actionCall) +{ + std::apply([&](NodeAction auto &...action) { (actionCall(action), ...); }, nodeActions); +} struct Base { - Base() = default; - - void removeNodes(ModelNodes newModelNodes, CheckRecursive checkRecursive) + void removeNodes(ModelNodes newModelNodes, + CheckRecursive checkRecursive, + NodeActions auto &nodeActions) { if (newModelNodes.empty()) return; @@ -40,20 +67,22 @@ struct Base auto oldModelNodes = removeNodes(newModelNodes); if (checkRecursive == CheckRecursive::Yes) - checkNewModelNodes(newModelNodes, oldModelNodes); + checkNewModelNodes(newModelNodes, oldModelNodes, nodeActions); } - void checkModelNodes(ModelNodes newModelNodes) + void checkModelNodes(ModelNodes newModelNodes, NodeActions auto &nodeActions) { if (newModelNodes.empty()) return; std::sort(newModelNodes.begin(), newModelNodes.end()); - checkNewModelNodes(newModelNodes, resourceSet->removeModelNodes); + checkNewModelNodes(newModelNodes, resourceSet->removeModelNodes, nodeActions); } - void removeProperties(AbstractProperties newProperties, CheckRecursive checkRecursive) + void removeProperties(AbstractProperties newProperties, + CheckRecursive checkRecursive, + NodeActions auto &nodeActions) { if (newProperties.empty()) return; @@ -61,26 +90,18 @@ struct Base auto oldProperties = removeProperties(newProperties); if (checkRecursive == CheckRecursive::Yes) - checkNewProperties(newProperties, oldProperties); + checkNewProperties(newProperties, oldProperties, nodeActions); } - void addSetExpressions(ModelResourceSet::SetExpressions newSetExpressions) - { - auto &setExpressions = resourceSet->setExpressions; - setExpressions.append(std::move(newSetExpressions)); - } + auto &setExpressions() { return resourceSet->setExpressions; } - void handleNodes(const ModelNodes &) {} + void handleNodes(const ModelNodes &, [[maybe_unused]] NodeActions auto &actions) {} - void handleProperties(const AbstractProperties &) {} + void handleProperties(const AbstractProperties &, [[maybe_unused]] NodeActions auto &actions) {} void finally() {} - void setNodeActionsAndModelResourceSet(NodeActions &actions, ModelResourceSet &resources) - { - nodeActions = &actions; - resourceSet = &resources; - } + void setModelResourceSet(ModelResourceSet &resources) { resourceSet = &resources; } private: ModelNodes removeNodes(ModelNodes &newModelNodes) @@ -123,7 +144,9 @@ private: return oldProperties; } - void checkNewModelNodes(const ModelNodes &newModelNodes, const ModelNodes &oldModelNodes) + void checkNewModelNodes(const ModelNodes &newModelNodes, + const ModelNodes &oldModelNodes, + NodeActions auto &nodeActions) { ModelNodes addedModelNodes; addedModelNodes.reserve(newModelNodes.size()); @@ -135,11 +158,14 @@ private: std::back_inserter(addedModelNodes)); if (addedModelNodes.size()) - forEachAction(*nodeActions, [&](auto &action) { action.handleNodes(addedModelNodes); }); + forEachAction(nodeActions, [&](NodeAction auto &action) { + action.handleNodes(addedModelNodes, nodeActions); + }); } void checkNewProperties(const AbstractProperties &newProperties, - const AbstractProperties &oldProperties) + const AbstractProperties &oldProperties, + NodeActions auto &nodeActions) { AbstractProperties addedProperties; addedProperties.reserve(newProperties.size()); @@ -151,26 +177,26 @@ private: std::back_inserter(addedProperties)); if (addedProperties.size()) - forEachAction(*nodeActions, - [&](auto &action) { action.handleProperties(addedProperties); }); + forEachAction(nodeActions, [&](NodeAction auto &action) { + action.handleProperties(addedProperties, nodeActions); + }); } private: ModelResourceSet *resourceSet = nullptr; - NodeActions *nodeActions = nullptr; }; struct CheckChildNodes : public Base { using Base::Base; - void handleNodes(const ModelNodes &nodes) + void handleNodes(const ModelNodes &nodes, NodeActions auto &actions) { ModelNodes childNodes; for (const ModelNode &node : nodes) childNodes.append(node.directSubModelNodes()); - checkModelNodes(childNodes); + checkModelNodes(std::move(childNodes), actions); } }; @@ -190,9 +216,9 @@ struct CheckNodesInNodeAbstractProperties : public Base return modelNodes; } - void handleProperties(const AbstractProperties &properties) + void handleProperties(const AbstractProperties &properties, auto &actions) { - checkModelNodes(collectNodes(properties)); + checkModelNodes(collectNodes(properties), actions); } }; @@ -216,9 +242,9 @@ struct RemoveLayerEnabled : public Base return properties; } - void handleNodes(const ModelNodes &nodes) + void handleNodes(const ModelNodes &nodes, auto &actions) { - removeProperties(collectProperties(nodes), CheckRecursive::No); + removeProperties(collectProperties(nodes), CheckRecursive::No, actions); } }; @@ -298,10 +324,6 @@ using NodesProperties = std::vector; struct RemoveDependentBindings : public Base { - RemoveDependentBindings(BindingDependencies dependencies) - : dependencies{std::move(dependencies)} - {} - AbstractProperties collectProperties(const ModelNodes &nodes) { AbstractProperties properties; @@ -316,9 +338,9 @@ struct RemoveDependentBindings : public Base return properties; } - void handleNodes(const ModelNodes &nodes) + void handleNodes(const ModelNodes &nodes, auto &actions) { - removeProperties(collectProperties(nodes), CheckRecursive::No); + removeProperties(collectProperties(nodes), CheckRecursive::No, actions); } BindingDependencies dependencies; @@ -326,9 +348,6 @@ struct RemoveDependentBindings : public Base struct RemoveDependencies : public Base { - RemoveDependencies(NodeDependencies dependencies) - : dependencies{std::move(dependencies)} - {} ModelNodes collectNodes(const ModelNodes &nodes) const { @@ -344,9 +363,9 @@ struct RemoveDependencies : public Base return targetNodes; } - void handleNodes(const ModelNodes &nodes) + void handleNodes(const ModelNodes &nodes, auto &actions) { - removeNodes(collectNodes(nodes), CheckRecursive::No); + removeNodes(collectNodes(nodes), CheckRecursive::No, actions); } NodeDependencies dependencies; @@ -354,11 +373,6 @@ struct RemoveDependencies : public Base struct RemoveTargetsSources : public Base { - RemoveTargetsSources(NodeDependencies dependencies, NodesProperties nodesProperties) - : dependencies{std::move(dependencies)} - , nodesProperties{std::move(nodesProperties)} - {} - static void removeDependency(NodesProperties &removedTargetNodesInProperties, const NodeDependency &dependency) { @@ -426,9 +440,9 @@ struct RemoveTargetsSources : public Base return nodesToBeRemoved; } - void handleNodes(const ModelNodes &nodes) + void handleNodes(const ModelNodes &nodes, auto &actions) { - removeNodes(collectNodesToBeRemoved(nodes), CheckRecursive::No); + removeNodes(collectNodesToBeRemoved(nodes), CheckRecursive::No, actions); } QString createExpression(const NodesProperty &nodesProperty) @@ -447,16 +461,13 @@ struct RemoveTargetsSources : public Base void finally() { - ModelResourceSet::SetExpressions setExpressions; for (const NodesProperty &nodesProperty : nodesProperties) { if (nodesProperty.isChanged && nodesProperty.targets.size()) { - setExpressions.push_back({nodesProperty.source.bindingProperty(nodesProperty.name), - createExpression(nodesProperty)}); + setExpressions().push_back({nodesProperty.source.bindingProperty(nodesProperty.name), + createExpression(nodesProperty)}); } } - - addSetExpressions(std::move(setExpressions)); } NodeDependencies dependencies; @@ -473,12 +484,6 @@ struct DependenciesSet struct BindingFilter { - BindingFilter(BindingDependencies &dependencies, Model *model) - : dependencies{dependencies} - , idModelNodeDict{model->idModelNodeDict()} - , wordsRegex{"[[:<:]](\\w+)[[:>:]]"} - {} - void filterBindingProperty(const BindingProperty &property) { const QString &expression = property.expression(); @@ -502,19 +507,11 @@ struct BindingFilter BindingDependencies &dependencies; QHash idModelNodeDict; - QRegularExpression wordsRegex; + QRegularExpression wordsRegex{"[[:<:]](\\w+)[[:>:]]"}; }; struct TargetFilter { - TargetFilter(NodeDependencies &dependencies, Model *model) - : flowViewFlowTransitionMetaInfo{model->flowViewFlowTransitionMetaInfo()} - , qtQuickPropertyChangesMetaInfo{model->qtQuickPropertyChangesMetaInfo()} - , qtQuickTimelineKeyframeGroupMetaInfo{model->qtQuickTimelineKeyframeGroupMetaInfo()} - , qtQuickPropertyAnimationMetaInfo{model->qtQuickPropertyAnimationMetaInfo()} - , dependencies{dependencies} - {} - static std::optional resolveBinding(const ModelNode &node, const PropertyName &propertyName) { @@ -531,7 +528,6 @@ struct TargetFilter { return metaInfo.isBasedOn(qtQuickPropertyChangesMetaInfo, qtQuickTimelineKeyframeGroupMetaInfo, - flowViewFlowActionAreaMetaInfo, qtQuickPropertyAnimationMetaInfo); } @@ -555,7 +551,6 @@ struct TargetFilter void finally() { std::sort(dependencies.begin(), dependencies.end()); } - NodeMetaInfo flowViewFlowActionAreaMetaInfo; NodeMetaInfo flowViewFlowTransitionMetaInfo; NodeMetaInfo qtQuickPropertyChangesMetaInfo; NodeMetaInfo qtQuickTimelineKeyframeGroupMetaInfo; @@ -563,7 +558,7 @@ struct TargetFilter NodeDependencies &dependencies; }; -template +template Predicate> struct TargetsFilter { TargetsFilter(Predicate predicate, @@ -617,10 +612,6 @@ void addDependency(NameNodes &dependencies, const ModelNode &node, const Propert struct StateFilter { - StateFilter(NameNodes &dependencies) - : dependencies{dependencies} - {} - void operator()(const NodeMetaInfo &metaInfo, const ModelNode &node) { if (metaInfo.isQtQuickState()) @@ -634,11 +625,6 @@ struct StateFilter struct TransitionFilter { - TransitionFilter(NodeDependencies &dependencies, NameNodes &stateNodes) - : stateNodes{stateNodes} - , dependencies{dependencies} - {} - void operator()(const NodeMetaInfo &metaInfo, const ModelNode &node) { if (metaInfo.isQtQuickTransition()) { @@ -664,11 +650,21 @@ struct TransitionFilter std::sort(dependencies.begin(), dependencies.end()); } - NameNodes transitionNodes; + NameNodes transitionNodes = {}; NameNodes &stateNodes; NodeDependencies &dependencies; }; +template +concept Filter = std::invocable + && requires(T t) { t.finally(); }; + +template +void forEachFilter(std::tuple &filters, auto &&call) +{ + std::apply([&](Filter auto &...filter) { (call(filter), ...); }, filters); +} + DependenciesSet createDependenciesSet(Model *model) { const ModelNodes nodes = model->allModelNodesUnordered(); @@ -676,91 +672,101 @@ DependenciesSet createDependenciesSet(Model *model) DependenciesSet set; NameNodes stateNames; - auto flowViewFlowActionAreaMetaInfo = model->flowViewFlowActionAreaMetaInfo(); auto flowViewFlowDecisionMetaInfo = model->flowViewFlowDecisionMetaInfo(); auto flowViewFlowWildcardMetaInfo = model->flowViewFlowWildcardMetaInfo(); + auto flowViewFlowTransitionMetaInfo = model->flowViewFlowTransitionMetaInfo(); auto qtQuickPropertyChangesMetaInfo = model->qtQuickPropertyChangesMetaInfo(); auto qtQuickTimelineKeyframeGroupMetaInfo = model->qtQuickTimelineKeyframeGroupMetaInfo(); auto qtQuickPropertyAnimationMetaInfo = model->qtQuickPropertyAnimationMetaInfo(); - auto filters = std::make_tuple( - TargetFilter{set.nodeDependencies, model}, - TargetsFilter{[&](auto &&metaInfo) { + std::tuple filters = { + TargetFilter{.flowViewFlowTransitionMetaInfo = flowViewFlowTransitionMetaInfo, + .qtQuickPropertyChangesMetaInfo = qtQuickPropertyChangesMetaInfo, + .qtQuickTimelineKeyframeGroupMetaInfo = qtQuickTimelineKeyframeGroupMetaInfo, + .qtQuickPropertyAnimationMetaInfo = qtQuickPropertyAnimationMetaInfo, + .dependencies = set.nodeDependencies}, + TargetsFilter{[&](const auto &metaInfo) { return metaInfo.isBasedOn(flowViewFlowDecisionMetaInfo, flowViewFlowWildcardMetaInfo, qtQuickPropertyAnimationMetaInfo); }, set.targetsDependencies, set.targetsNodesProperties}, - StateFilter{stateNames}, - TransitionFilter{set.nodeDependencies, stateNames}, - BindingFilter{set.bindingDependencies, model}); + StateFilter{.dependencies = stateNames}, + TransitionFilter{.stateNodes = stateNames, .dependencies = set.nodeDependencies}, + BindingFilter{.dependencies = set.bindingDependencies, + .idModelNodeDict = model->idModelNodeDict()}}; for (const ModelNode &node : nodes) { auto metaInfo = node.metaInfo(); - std::apply([&](auto &&...filter) { (filter(metaInfo, node), ...); }, filters); + forEachFilter(filters, [&](Filter auto &&filter) { filter(metaInfo, node); }); } - std::apply([&](auto &&...filter) { (filter.finally(), ...); }, filters); + forEachFilter(filters, [](Filter auto &&filter) { filter.finally(); }); return set; } -using NodeActionsTuple = std::tuple; - -class NodeActions : public NodeActionsTuple +template +class Dispatcher { public: - template - NodeActions(ModelResourceSet &modelResourceSet, Actions &&...actions) - : NodeActionsTuple(std::forward(actions)...) - , modelResourceSet{modelResourceSet} + template + Dispatcher(ActionTypes &&...actions) + : actions{std::forward(actions)...} { - forEachAction(*this, [&](auto &action) { - action.setNodeActionsAndModelResourceSet(*this, modelResourceSet); + forEachAction(this->actions, [&](NodeAction auto &action) { + action.setModelResourceSet(modelResourceSet); }); } - NodeActions(const NodeActions &) = delete; - NodeActions &opertor(const NodeActions &) = delete; - NodeActions(NodeActions &&) = delete; - NodeActions &opertor(NodeActions &&) = delete; + Dispatcher(const Dispatcher &) = delete; + Dispatcher &opertor(const Dispatcher &) = delete; + Dispatcher(Dispatcher &&) = delete; + Dispatcher &opertor(Dispatcher &&) = delete; void removeProperties(const AbstractProperties &properties, CheckRecursive checkRecursive) { Base base; - base.setNodeActionsAndModelResourceSet(*this, modelResourceSet); + base.setModelResourceSet(modelResourceSet); - base.removeProperties(properties, checkRecursive); + base.removeProperties(properties, checkRecursive, actions); } void removeNodes(const ModelNodes &nodes, CheckRecursive checkRecursive) { Base base; - base.setNodeActionsAndModelResourceSet(*this, modelResourceSet); + base.setModelResourceSet(modelResourceSet); - base.removeNodes(nodes, checkRecursive); + base.removeNodes(nodes, checkRecursive, actions); } - ~NodeActions() + ModelResourceSet &takeModelResourceSet() { - forEachAction(*this, [&](auto &action) { action.finally(); }); + forEachAction(actions, [&](NodeAction auto &action) { action.finally(); }); + + return modelResourceSet; } private: - ModelResourceSet &modelResourceSet; + std::tuple actions; + ModelResourceSet modelResourceSet; }; -template -void forEachAction(NodeActions &nodeActions, ActionCall actionCall) +template +Dispatcher(Actions &&...actions) -> Dispatcher; + +auto createDispatcher(Model *model) { - std::apply([&](auto &...action) { (actionCall(action), ...); }, - static_cast(nodeActions)); + DependenciesSet set = createDependenciesSet(model); + + return Dispatcher{CheckChildNodes{}, + CheckNodesInNodeAbstractProperties{}, + RemoveLayerEnabled{}, + RemoveDependentBindings{.dependencies = std::move(set.bindingDependencies)}, + RemoveDependencies{.dependencies = std::move(set.nodeDependencies)}, + RemoveTargetsSources{.dependencies = std::move(set.targetsDependencies), + .nodesProperties = std::move(set.targetsNodesProperties)}}; } } // namespace @@ -769,22 +775,11 @@ ModelResourceSet ModelResourceManagement::removeNodes(ModelNodes nodes, Model *m { std::sort(nodes.begin(), nodes.end()); - ModelResourceSet resourceSet; + Dispatcher dispatcher = createDispatcher(model); - DependenciesSet set = createDependenciesSet(model); + dispatcher.removeNodes(nodes, CheckRecursive::Yes); - NodeActions nodeActions = {resourceSet, - CheckChildNodes{}, - CheckNodesInNodeAbstractProperties{}, - RemoveLayerEnabled{}, - RemoveDependentBindings{std::move(set.bindingDependencies)}, - RemoveDependencies{std::move(set.nodeDependencies)}, - RemoveTargetsSources{std::move(set.targetsDependencies), - std::move(set.targetsNodesProperties)}}; - - nodeActions.removeNodes(nodes, CheckRecursive::Yes); - - return resourceSet; + return dispatcher.takeModelResourceSet(); } ModelResourceSet ModelResourceManagement::removeProperties(AbstractProperties properties, @@ -792,22 +787,11 @@ ModelResourceSet ModelResourceManagement::removeProperties(AbstractProperties pr { std::sort(properties.begin(), properties.end()); - ModelResourceSet resourceSet; + Dispatcher dispatcher = createDispatcher(model); - DependenciesSet set = createDependenciesSet(model); + dispatcher.removeProperties(properties, CheckRecursive::Yes); - NodeActions nodeActions = {resourceSet, - CheckChildNodes{}, - CheckNodesInNodeAbstractProperties{}, - RemoveLayerEnabled{}, - RemoveDependentBindings{std::move(set.bindingDependencies)}, - RemoveDependencies{std::move(set.nodeDependencies)}, - RemoveTargetsSources{std::move(set.targetsDependencies), - std::move(set.targetsNodesProperties)}}; - - nodeActions.removeProperties(properties, CheckRecursive::Yes); - - return resourceSet; + return dispatcher.takeModelResourceSet(); } } // namespace QmlDesigner From 415fec3ed7f235bb8e6c265d552a6434e5bf4674 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Tue, 13 Aug 2024 15:21:14 +0300 Subject: [PATCH 029/193] QmlDesigner: Fix content lib added component's icon Fixes: QDS-13348 Fixes: QDS-13336 Change-Id: I49f559084b63ea10c20459f03007a305e460ab7c Reviewed-by: Miikka Heikkinen --- .../components/contentlibrary/contentlibraryview.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index 96a8cd016ff..b0f1108ae19 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -696,13 +696,9 @@ void ContentLibraryView::addLib3DComponent(const ModelNode &node) m_widget->userModel()->removeItemByName(compFileName, m_bundleId); } - // generate and save icon QString iconPath = QLatin1String("icons/%1").arg(UniqueName::generateId(compBaseName) + ".png"); m_iconSavePath = bundlePath.pathAppended(iconPath); m_iconSavePath.parentDir().ensureWritableDir(); - getImageFromCache(compDir.pathAppended(compFileName).path(), [&](const QImage &image) { - saveIconToBundle(image); - }); const Utils::FilePaths sourceFiles = compDir.dirEntries({{}, QDir::Files, QDirIterator::Subdirectories}); const QStringList ignoreList {"_importdata.json", "qmldir", compBaseName + ".hints"}; @@ -742,6 +738,11 @@ void ContentLibraryView::addLib3DComponent(const ModelNode &node) m_widget->userModel()->addItem(m_bundleId, compBaseName, compFileName, m_iconSavePath.toUrl(), filesList); + + // generate and save icon + getImageFromCache(compDir.pathAppended(compFileName).path(), [&](const QImage &image) { + saveIconToBundle(image); + }); } void ContentLibraryView::exportLib3DComponent(const ModelNode &node) From c9ba64cefca94b8a4aa98d5b0ce4349c4cffd1ad Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 13 Aug 2024 15:50:41 +0200 Subject: [PATCH 030/193] QmlDesigner: Use tab name instead of uniqueId Fixes the text in the view menu. Change-Id: I78fa6ab96d956075d41366063dcaa3ea44b8f205 Reviewed-by: Thomas Hartmann --- src/plugins/qmldesigner/designmodewidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index e81fdc331a2..6a366b877a3 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -348,7 +348,7 @@ void DesignModeWidget::setup() // Create menu action auto viewAction = view->action(); - viewAction->setText(widgetInfo.uniqueId); + viewAction->setText(widgetInfo.tabName); dockWidget->setToggleViewAction(viewAction); auto command = Core::ActionManager::registerAction(viewAction, actionToggle.withSuffix( From 886700cf188fb8cb8253e2b424ea2ff9b6aea582 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 13 Aug 2024 13:06:41 +0200 Subject: [PATCH 031/193] QmlDesigner: Attach/detach for visibility changes Instead of ignoring views the view is properly detached and attached. So it can be always in a valid state. Task-number: QDS-13346 Change-Id: I94edddca7503ec93a2f64338d50f38ce033ca280 Reviewed-by: Miikka Heikkinen Reviewed-by: Thomas Hartmann --- .../components/componentcore/viewmanager.cpp | 16 +++++++-- .../components/componentcore/viewmanager.h | 3 ++ .../curveeditor/curveeditorview.cpp | 17 ++++++---- .../components/formeditor/formeditorview.cpp | 3 -- .../formeditor/formeditorwidget.cpp | 4 +-- .../timelineeditor/timelineview.cpp | 4 --- .../timelineeditor/timelinewidget.cpp | 4 +-- .../transitioneditor/transitioneditorview.cpp | 3 -- .../transitioneditorwidget.cpp | 4 +-- .../designercore/include/abstractview.h | 6 ++-- .../qmldesigner/designercore/model/model.cpp | 33 ++++++++----------- .../qmldesigner/designercore/model/model_p.h | 21 ------------ 12 files changed, 50 insertions(+), 68 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp index 486d22d9273..94b7b7e6acd 100644 --- a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp @@ -208,6 +208,18 @@ QList ViewManager::views() const return list; } +void ViewManager::hideView(AbstractView &view) +{ + disableView(view); + view.setVisibility(false); +} + +void ViewManager::showView(AbstractView &view) +{ + view.setVisibility(true); + enableView(view); +} + QList ViewManager::standardViews() const { #ifndef QTC_USE_QML_DESIGNER_LITE @@ -298,8 +310,8 @@ void ViewManager::registerViewAction(AbstractView &view) viewAction->setCheckable(true); QObject::connect(view.action(), &AbstractViewAction::viewCheckedChanged, - [&](bool checkable, AbstractView &view) { - if (checkable) + [&](bool checked, AbstractView &view) { + if (checked) enableView(view); else disableView(view); diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.h b/src/plugins/qmldesigner/components/componentcore/viewmanager.h index 7047ecdd01d..e2bb2c833fc 100644 --- a/src/plugins/qmldesigner/components/componentcore/viewmanager.h +++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.h @@ -93,6 +93,9 @@ public: void jumpToCodeInTextEditor(const ModelNode &modelNode); QList views() const; + void hideView(AbstractView &view); + void showView(AbstractView &view); + private: // functions Q_DISABLE_COPY(ViewManager) diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp index 48f8780b456..2ef7fde36f1 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp @@ -13,9 +13,10 @@ #include #include #include -#include +#include #include #include +#include #include @@ -32,12 +33,15 @@ CurveEditorView::CurveEditorView(ExternalDependenciesInterface &externalDepoende connect(m_model, &CurveEditorModel::commitEndFrame, this, &CurveEditorView::commitEndFrame); connect(m_model, &CurveEditorModel::curveChanged, this, &CurveEditorView::commitKeyframes); - connect(m_editor, &CurveEditor::viewEnabledChanged, this, [this](bool enabled){ - setEnabled(enabled); - if (enabled) + connect(m_editor, &CurveEditor::viewEnabledChanged, this, [this](bool enabled) { + if (enabled) { + QmlDesignerPlugin::viewManager().showView(*this); init(); + } else { + QmlDesignerPlugin::viewManager().hideView(*this); + } }); - setEnabled(false); + } CurveEditorView::~CurveEditorView() {} @@ -56,8 +60,7 @@ void CurveEditorView::modelAttached(Model *model) { AbstractView::modelAttached(model); - if (isEnabled()) - init(); + init(); } void CurveEditorView::modelAboutToBeDetached(Model *model) diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp index e047773d132..1087e88db0f 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorview.cpp @@ -64,9 +64,6 @@ void FormEditorView::modelAttached(Model *model) { AbstractView::modelAttached(model); - if (!isEnabled()) - return; - m_formEditorWidget->setBackgoundImage({}); temporaryBlockView(); diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp index 89f65febd6c..312c56c990a 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp @@ -634,7 +634,7 @@ void FormEditorWidget::hideEvent(QHideEvent *event) { QWidget::hideEvent(event); - m_formEditorView->setEnabled(false); + QmlDesignerPlugin::viewManager().hideView(*m_formEditorView); } void FormEditorWidget::showEvent(QShowEvent *event) @@ -642,7 +642,7 @@ void FormEditorWidget::showEvent(QShowEvent *event) QWidget::showEvent(event); const bool wasEnabled = m_formEditorView->isEnabled(); - m_formEditorView->setEnabled(true); + QmlDesignerPlugin::viewManager().showView(*m_formEditorView); if (!wasEnabled && m_formEditorView->model()) { m_formEditorView->cleanupToolsAndScene(); diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp index 0d4f27707f8..28af2fd25e1 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp @@ -52,7 +52,6 @@ TimelineView::TimelineView(ExternalDependenciesInterface &externalDepoendencies) , m_timelineWidget(nullptr) { EasingCurve::registerStreamOperators(); - setEnabled(false); } TimelineView::~TimelineView() = default; @@ -61,9 +60,6 @@ void TimelineView::modelAttached(Model *model) { AbstractView::modelAttached(model); - if (!isEnabled()) - return; - if (m_timelineWidget) m_timelineWidget->init(); } diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp index 592cf0dff93..e540e92414d 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp @@ -606,7 +606,7 @@ void TimelineWidget::showEvent([[maybe_unused]] QShowEvent *event) { int zoom = m_toolbar->scaleFactor(); - m_timelineView->setEnabled(true); + QmlDesignerPlugin::viewManager().showView(*m_timelineView); graphicsScene()->setWidth(m_graphicsView->viewport()->width()); graphicsScene()->invalidateScene(); @@ -629,7 +629,7 @@ void TimelineWidget::resizeEvent(QResizeEvent *event) void TimelineWidget::hideEvent(QHideEvent *event) { - m_timelineView->setEnabled(false); + QmlDesignerPlugin::viewManager().hideView(*m_timelineView); QWidget::hideEvent(event); } diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp index 8a7681d82ec..910e535a675 100644 --- a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp +++ b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorview.cpp @@ -53,9 +53,6 @@ void TransitionEditorView::modelAttached(Model *model) { AbstractView::modelAttached(model); - if (!isEnabled()) - return; - if (m_transitionEditorWidget) m_transitionEditorWidget->init(); } diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.cpp index 57bb295d0ca..083c395f91f 100644 --- a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.cpp +++ b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.cpp @@ -396,7 +396,7 @@ void TransitionEditorWidget::setupScrollbar(int min, int max, int current) void TransitionEditorWidget::showEvent([[maybe_unused]] QShowEvent *event) { - m_transitionEditorView->setEnabled(true); + QmlDesignerPlugin::viewManager().showView(*m_transitionEditorView); if (m_transitionEditorView->model()) init(m_toolbar->scaleFactor()); @@ -411,7 +411,7 @@ void TransitionEditorWidget::showEvent([[maybe_unused]] QShowEvent *event) void TransitionEditorWidget::hideEvent(QHideEvent *event) { - m_transitionEditorView->setEnabled(false); + QmlDesignerPlugin::viewManager().hideView(*m_transitionEditorView); QWidget::hideEvent(event); } diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index 8b105fe0f4f..792a0dcf52e 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -283,9 +283,9 @@ public: using OperationBlock = std::function; bool executeInTransaction(const QByteArray &identifier, const OperationBlock &lambda); - bool isEnabled() const { return m_enabled && (hasWidget() ? m_action->isChecked() : true); } + bool isEnabled() const { return m_visible && (hasWidget() ? m_action->isChecked() : true); } - void setEnabled(bool enabled) { m_enabled = enabled; } + void setVisibility(bool visible) { m_visible = visible; } AbstractViewAction *action() const { return m_action.get(); } @@ -325,7 +325,7 @@ private: QPointer m_model; ExternalDependenciesInterface &m_externalDependencies; Utils::UniqueObjectPtr m_action; - bool m_enabled = true; + bool m_visible = true; bool m_isBlockingNotifications = false; }; diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 04510e6ce90..0352b0345ab 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -232,7 +232,7 @@ void ModelPrivate::notifyImportsChanged(const Imports &addedImports, const Impor if (nodeInstanceView()) nodeInstanceView()->importsChanged(addedImports, removedImports); - for (const QPointer &view : enabledViews()) + for (const QPointer &view : std::as_const(m_viewList)) view->importsChanged(addedImports, removedImports); if (resetModel) @@ -241,7 +241,7 @@ void ModelPrivate::notifyImportsChanged(const Imports &addedImports, const Impor void ModelPrivate::notifyPossibleImportsChanged(const Imports &possibleImports) { - for (const QPointer &view : enabledViews()) { + for (const QPointer &view : std::as_const(m_viewList)) { Q_ASSERT(view != nullptr); view->possibleImportsChanged(possibleImports); } @@ -249,7 +249,7 @@ void ModelPrivate::notifyPossibleImportsChanged(const Imports &possibleImports) void ModelPrivate::notifyUsedImportsChanged(const Imports &usedImports) { - for (const QPointer &view : enabledViews()) { + for (const QPointer &view : std::as_const(m_viewList)) { Q_ASSERT(view != nullptr); view->usedImportsChanged(usedImports); } @@ -371,11 +371,6 @@ void ModelPrivate::removeNodeFromModel(const InternalNodePointer &node) m_internalIdNodeHash.remove(node->internalId); } -EnabledViewRange ModelPrivate::enabledViews() const -{ - return EnabledViewRange{m_viewList}; -} - namespace { QT_WARNING_PUSH QT_WARNING_DISABLE_CLANG("-Wunneeded-internal-declaration") @@ -550,13 +545,13 @@ void ModelPrivate::notifyNodeInstanceViewLast(Callable call) resetModel = true; } - for (const QPointer &view : enabledViews()) { - try { - if (!view->isBlockingNotifications()) - call(view.data()); - } catch (const Exception &e) { - e.showException(tr("Exception thrown by view %1.").arg(view->widgetInfo().tabName)); - } + for (const QPointer &view : std::as_const(m_viewList)) { + try { + if (!view->isBlockingNotifications()) + call(view.data()); + } catch (const Exception &e) { + e.showException(tr("Exception thrown by view %1.").arg(view->widgetInfo().tabName)); + } } if (nodeInstanceView() && !nodeInstanceView()->isBlockingNotifications()) @@ -583,7 +578,7 @@ void ModelPrivate::notifyNormalViewsLast(Callable call) if (nodeInstanceView() && !nodeInstanceView()->isBlockingNotifications()) call(nodeInstanceView()); - for (const QPointer &view : enabledViews()) { + for (const QPointer &view : std::as_const(m_viewList)) { if (!view->isBlockingNotifications()) call(view.data()); } @@ -595,7 +590,7 @@ void ModelPrivate::notifyNormalViewsLast(Callable call) template void ModelPrivate::notifyInstanceChanges(Callable call) { - for (const QPointer &view : enabledViews()) { + for (const QPointer &view : std::as_const(m_viewList)) { if (!view->isBlockingNotifications()) call(view.data()); } @@ -831,7 +826,7 @@ void ModelPrivate::notifyPropertiesAboutToBeRemoved(const QList &view : enabledViews()) { + for (const QPointer &view : std::as_const(m_viewList)) { QList propertyList; Q_ASSERT(view != nullptr); for (auto property : internalPropertyList) { @@ -1258,7 +1253,7 @@ QList> ModelPrivate::toInternalBi void ModelPrivate::changeSelectedNodes(const QList &newSelectedNodeList, const QList &oldSelectedNodeList) { - for (const QPointer &view : enabledViews()) { + for (const QPointer &view : std::as_const(m_viewList)) { Q_ASSERT(view != nullptr); view->selectedNodesChanged(toModelNodeList(newSelectedNodeList, view.data()), toModelNodeList(oldSelectedNodeList, view.data())); diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h index b375576211e..5e24d82e1f2 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/designercore/model/model_p.h @@ -71,26 +71,6 @@ private: QPointer m_model; }; -struct Increment -{ - using iterator = QList>::const_iterator; - auto operator()(iterator current) { - return std::find_if(std::next(current), - end, - [] (iterator::reference &view) { return view && view->isEnabled(); }); - } - - iterator end; -}; - -class EnabledViewRange : public SkipRange>, Increment> -{ -public: - EnabledViewRange(const container &views) - : base{views, Increment{views.end()}} - {} -}; - class ModelPrivate : public QObject, protected ProjectStorageObserver { @@ -351,7 +331,6 @@ private: static QList toInternalProperties(const AbstractProperties &properties); static QList> toInternalBindingProperties(const ModelResourceSet::SetExpressions &setExpressions); - EnabledViewRange enabledViews() const; ImportedTypeNameId importedTypeNameId(Utils::SmallStringView typeName); void setTypeId(InternalNode *node, Utils::SmallStringView typeName); From 6d5c01f6d3fde4fa0a8d37f191a1578b3d18c950 Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Fri, 9 Aug 2024 10:22:14 +0300 Subject: [PATCH 032/193] Doc: Document managing user assets Task-number: QDS-13317 Change-Id: Iee17876f689119638d9ae999d9afdc3bc325c100 Reviewed-by: Johanna Vanhatapio Reviewed-by: Mats Honkamaa Reviewed-by: Mahmoud Badri --- .../images/content-library.webp | Bin 26724 -> 25886 bytes doc/qtdesignstudio/images/user-assets.webp | Bin 0 -> 17648 bytes .../src/views/studio-content-library.qdoc | 63 +++++++++++++++++- 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 doc/qtdesignstudio/images/user-assets.webp diff --git a/doc/qtdesignstudio/images/content-library.webp b/doc/qtdesignstudio/images/content-library.webp index 6c6a7628fc86afb1e5a149df50b9ae3bfa2490fb..8efc53d21ff66d6afc0182d872afb46a4aa95a5f 100644 GIT binary patch literal 25886 zcmWIYbaN9+Wnc(*bqWXzu!!JdfB%Z#1=C9nh=bx@${6F<)```Kh>bKZU z-n;zm`6JigMFszm-`nr{f95~=zv|!5=h)w^-~8vszr(Nl&-lOI_hO%uz4X8If4hI} zf3jRf@9TfzfBRR&@05@GU-~cplmElRANC*n75h#5pZlHrH^e{NzmR|Xe`kH_59xpP zzv|Eb&#*uI|IRn2f2n_q|M`EP|7HK?`6~0@|DXL|`FH8N)i3A&t$$(1xPNYaRaREN%u1%9p`x-v7K_tcCC2LT@&V0Rgw#3(kB)2ryBKVyWThVW%x9&EyG>%$sFgK zK8tT%EI)hM!NUG&-=0pX;uvq!PxBH!CH&~^J2dZ9#mf&*E`PZH@v!M)8-+w>4he@t zYyt+2Ej(x(@%H>Ao)>!~G}IH=V!z(JDtr_V+)+}&sbE;Z9T2O&ZqKscYp2yc>N2@; ztuQz9L+#pIck`F<%y>7KwaoWcOBT-r)m3g=&Hv8&=UACo-rK{UKj*~#pv;IFO%F<( z8fwip?K^VdWI@WVKgt?6-A(j}fviG+vO*5}lfJ#o&U4ww6MlX#yXF7gbC>d7|6NhccIMD7 z?O%(h2r^rK(QF7>K2yQOYn!p~lO3svjZ@c7^R%9|LSbp!ou7;3WySleSITU2Oq!y1 z{hQyzt!r}jEm2I|Tlq*a)%Ze5SFXhsuYE2&&o3-v^my}c^$M=dAVW&rmhZ@oUa_3z z&hKRoix0YfDLM0VN%pMh)%P8YeJjpwh)td{r@nV%lWzoD$DFu587U+d}xZP@7ZKn_4QJ!)@S?YTu0(2 z%zu8ir!QCFLF(e07gI0za~TCVA1-^GnP|A(Al>oT%Tt$*UQ&Cs{KBPe)0^6YpWmER zB>Tm4-IRBpPj~01{wv~&-F;;1J?@}wa<6|SDFn^g%HNFf*?EGAdPHNe56`T1Le;WA+Fm8@KQQUhspOy= zKKFdsypOG`oX=8wm;G|L#>Uf~%I%{6n@#PT807=Mb-9H8OPs{BJ^06=pqM$5r}h_V zbp0y0dB9%Dtb4L}m+(dAu(^D)=hm*aJs1B}+(K(cPlv>wj^q>GkNsc&ic0g@X7Y*I z-`ZqT!{^@@L)DFEE;E?1<(uF|VHutehrW8PU-N6-$r;N7PW$_o<*RSddKaX5PVvR& zC-Z!(_J8{2nUw$N>2bzmrLK+_ZqIkT;ysJ;P4b66zUK)s4*V0WGwY@*HuA@=ekdI^ zY17}o9ksQ-XN)_ZnPo7$a9#Un$+I=xf4}>YkBsg+R1f@n=reooize^&FSyeWUR%(% zafh+(!~@atin+FVyG!%;$lX3&CRG1RZXtVru5r?e$2liX$eLO_s&zW*d-D0GvmY)_ zeg3s6PU&me!Qkb45-SulB37F`-8zNe{DAn5KT2iFGtVkLobXO)SxrjtB?pDelG7_v zmcO54yRj#>+w0QKYk5oCT4VbzSa02@6l(OT)QGLB>#&CIo`5TlPoH3zKXv}CoTUZ_ z<?9{i}0uaoc^LBF;80GvWNQ+eR1ktNt8O+EG5m)3|kNYrvEhmm*4^Z5OtGRPP}E zFZH(CiiwfS)_&j%G<@VDXTSYJRPu$_J8oL+ktpdszok}&;hy94`&;9#x7xc+p0dBh zd~WIy(fq5s1TyOE7_t_6>nwb8;YorL=l?%X+)au_<{I?4aJx-ZPIYK6QV7^r5M{C0 zW@=8D=e+=KLxblkGutdzf7^KZW|_*Di<-Ol%+$HdbKGv8zl&Lt{N`mT_s_}fOOJQi z&&qrB-TlcjjLTTXo41C}=v6rT@9N=+H@3;vSkFuOt?}&N&D4_Yxuq6n><71$Ki?hn z?VeF`@QEY0G4Xr*3|1IjO`c`HP+w<36oP4ee_y&Y=h1S}?UR?f zwRkMne7{GwHg}a)ncn;OJyW-K?Td8f4!o8eT=wf;nwm=S0j(KMN%vy?L@!=%Uik7) z)64U})oe{H)E?(9pMLglEaOh?kixf9FUE3p^Iv-~f2D%0q5YzGvkPC9=XVBgiagS> z>&j=3pFOqTmc0BsVf%xHF}X)8ou<1~GO1dy-w4`xZ-V`oi3RJY3w1K3UlCkonX{tZ z-~R3TGt>Ao4g_$OGlun;@qIN6*c|75-Y4TgcJLpy5Y`T-Z9;+DS7(RaDVGX+<*@Q* zi_@ezSR9Q5*|Mc%zyJZFzek?wPnAZ12JlSczdA#q~r{T z9ikKD9=U8?V#cynq*7{UP`)Tiw}s-on#wr)1CSdh;b>O8Uo$Uhm@$ zn|JSD{^jXU$C+{K-}?IKe%NX;@lUhCda)Ec)BZ;`d*^sn6bF?uZ-7?8;9o! z?%L$FwlZat=E8Yz4$dv$iav4N)K@EqkNtKy6W{FJH+C$&+i3YNFmqbBP_J1NQ`^7U zCw`jD32>;tpsQND?p;>)QGK%$OTO*D=N}y~_1{I7z3iR8Q{9eUR$@K`F|AuvY<9&sxe#^i39S)S2`+l#l^O+B>k}`?e^{i~uvp%L&*soRH6c#D zrz@XMtMxx|lhLFj@?pgRzPR+ZoqxQU7oRvprnYNHKVhg5mku zjW3LSkKZYa;L%^9B*K61`kp)ysfzzAE;-0-`{So-acFr>g|WV*>~6kWn`@HK9{)38 zO}eto^C>4*Kd{cwV4iW@X-}A-0^hHTDYD_ctA4y}-2JdrUekB=`_)HYzdfcSywz0G zA?DEsvyJONmefz4e^lws(PdJ{Ui|ReX!b|tSmft7q6u1YvyzjfgY+Klr}U@q`dI1I-)i2CaDz$Xm#qqVp@j`__v6$M>whJm+Z|U)_F1?Msb5@6ubpPq&|( zKUdv(=RUtTg~hQ;6c#zZUHy0Y;@@odY(Lr0lr!Q9c=0T9i$tB6V!q9SO}{4S={Ii6 zI{2_x%VJBnK<ViEXbJ=xYm8n^>#VFfH}99Z zKTB%!#%T7^V}JaDHBJ66kzBIhW&J;)=P7S(x-QH+dFNB5MZ(s6{^!cOZ#U^W@;+@T zH}~4KK(TX8qTY2eiN{VN_*e1YZ3%GR{Gw!pBMdR=eK0e z<*p6$tm{`lxVfT5MIc0GUExNxrTY7W(*@o!d?~Kh(vN7GcI4BIu5bBIst!M%)FkL; zJmb>tow6t1xi7KOIocGzR9f>9sJj@y<|C-%DD(2;ru|-K8Vn5o%$04f*({f?Km9{l zRR6==|NnT|H^gt-I_=E+T_@kA_s#$R;rzz^QZaQ+W>t6BANl&R{oRtucD`N5tPi^W zw%7C*u6kLqF_l+v?y96a`Lm)-Hxvsj4Ego2u5smNZI7$6%O7ZT`(?b5-Tq*j+P^rQv1I>+5CWZKfR%Iw)iOa3{^cfKAI{THlfdb#ndyy5yz#Sf)ornw1w%8q`W z@pPFtTP}0c;)|zq6eous7ia(Sy>$AG#|{S zU|aRA#bxc{=iz6UykEhzYQB4e&7a?$em6c`t32*BGoscpF?zx0IX6SM>8Q+b2u*7? zoW=1<&bd;5+HKy0jltnrix#NOc(LOA+?+c{7_PG4&yiX6z&V!vZm0TZ8;ir2eWz`I zu+2#GjrwjcmlvzKo0j=EXVx5Y>@m|QRA2sJs?WWn{ER%WjDK!%dcM9w{>k5?dN(o^ z9RD~(JztTP)FD@4|L~2%`~QdJl`CG0pEi5*WTR%I&|5jZ+{J%y^+?LUoKvgKX?Uf2 zg@j}A&q9Yy&f9IAWS*T`^Wa(3IlJPm8=W^#PTZ5{HrF(L(Y_}e4j3dpTEF7dt>lu$ z55BgoR#E+AApanYS3F*Sl8eA?m zaYJH;(VxV!-mt%$_X!>Ty7k9%i|3r~_ov31TyWTDwvi<_nq}HjhL@A9{^-d+F#CAN zZ;#$-v6Ba%tF=tgF5AB{L*?DFpNxI?-O57eCKyOM>xX3Qo;`!-&^(shB#v9_*?aCL z|9D*EfAIUJZI$Z<|J*$hbu>RG!uwKrg87!uI-lc|f9{^Jwd>xE4bzvrJCL9GEb`eN z_s`{u*`j+lChB|MZMb*&%;vKd{m++T+z^t%cwOp;xDqXa|u}91Cg-Qr14(!e}(vVQRL0_YMw_FarZ4PrUSef6s3Q4@wf29ys>%QMdo+ zrOVHK<`VlnUHku<-^)+T)%f#oxwZ?R?mtrorQ{n2lLLRr8Gf64Qpl*l!M{tYRIO0y z`pr$wUZqQ#O#EEhnO-@s+qO$Dy+7p3^Onm#Pxef2`|f!tQup1`^_Dr4r!a5RnBx#; zD!A?uhxhxGE6uj4ORv8Q|9I`f?Gq0cHoW9}d)wlR=bME4411>ZoX>#e^DW=ze{B8KPRo===Z$v;r)@^Cs&N(Z1wbN=wC$1RR6&hXLyoKhyeLh@?-pWFUhe7_&~ z-*D*Zx1`nCd%iIVLb~TTz`9qYhTpbEj6nTs4PlwcyYgsd)v1)YE#x6*Erfef4R<_{mTj` zge{G0z9D_cl6|hi_LJ-L-m;!qX|eXbNZ9?x+yuK^-QfH2hj%y2#?|~SxH0MNp5;p( zU1bnR$njJocY3^PvGi}@@U8rszGb!T+1vhCB1PM-Rd?jmlUOCN1&NK@ZhGHKns1-H_Usjg@EzWBv@ zhRv2u8=3As{1fc&BT`rO+WN%Kl0Ez8o{CxZba!Y)Xm823jc0S5p44+x%f<2k?%ee6 z&w`%BtE`XzT$}4NMV&c#3Clvml~?ZA73_3UJ|%nIIL*3J_r<#l1zI~VIsO$|v*Et= zx911s3>3I_r*)f`)jqna^!mHvX=BxQZIO@vgs$IlJz?qDERK8P|9n)V{?6L^@D)F^ zOvm)~f9E{8ax*T#y>d&l?0l8S< z)^8q8dATZ2?vKdxO^P1uvb#(4N{`9b#C*NWoYeVxnz5OcL;u?6oDYvZwex9zQr3Of zMOWV?hrzw;W23G@2*cc)tjcWe&*LvicB+3e$Tx4Cb7N-Ij%b!ff0M&nmmkV(T2@-9 z&pUO8TmFr*suSt&gpOEwf8bdzHfh_fGfRS_-11MA|1gO$Yt=db$(ecQtfb>pZvWD( z4|}xo(2BkPA1w9I}NZkZPR``yk>rtD51pWBL6MgHD@YjI3C z`_66ekE+z&SfdcS=4IeUURmK3{Y~pL#a^YaIx@Z8_y5BOlMhW)`IRYN6Lod&yvrhT zXV$&E{`=XFjv0H8tn%^;aQ=CcTh6j4m`A~fCHMTp+PCgr)74Yz)0Qkwk^XYWRL)Dq zGxFBy+I5z-MJlI*97xgRi_7maew>`M$Ykb~ z8;k$X%M&9CWttZ>yk(YeI^j@-2|GhPzS4Upm8pIUM` zLCwWESo+TudoP>W1w8J*BeS+&e1EoJ^ZB~#m20L(J%7V9>u_?|=hFAnuRHe5{4aNu z(N_3+;fD(gf_iIGCcGBWWZxcQP{Gq3&k%g?&!&n~4N+$WOnih6ww--`&tZkR{q|(x zR~4&+(j)Gu%zo1~|I0(Mj7RYSDy()Xo5}|pAzV^;2XqNBkeO_y(SycBbZ?*bG3pQ`YC$Apv{UFFQ z^+|QswdR#hR+2h*6`QB&-#u>eQaxf%>>TbV*QZ)cOFXbVv^rMD=gh?ZZw#lCmz@^X zE?%fm=W}P_m9*6=#@`+-uy*s6-DlV#ynM^v?wY&vcFsPx?omKOe1>mnG<&7C!_Ax@ zriC+4`AEGJtjHEplU-ZrbarAxNUGJj>wg0ZKa_E@?u!26Tl=!zK{;ifQ)-}x&I1Mp zMv;ehVeY*>0U!8M*Re%KEZ)M%JpgIEw60$o zKF@p0g3o0g5)+C#UT0@I8s=xFtjw)FoH9$PpIh(wx}!I@)w@fvW`yk*Soi&TW~$A} z>M$MlB!_D&?q*)#T-RzMczKb^Luu25tchRmKM<2%_@p6j+x@8<@8tXLKCN>mhr}Ccbey{iMEoJ*|uu)^zqbrABFBS@jo@&j?eslintLyjj}NtbCDNQ>-D~tFm8*r|HG^`Z>>S?rUL$7vu_rkpQArtJw@ib z-=w(htCwi3n6_te@?}Qfe*x?a?^dmrnY*p~TI2dx47*&ygkEkm>gHHie@j(uzf0cy zT`9hkF0A5z%JHsXZNZGDCxYs(+za*VC&oXy`~Px>%lW(2lFPRqJ>>w7YDUfKMN(zO zUvEpF|K+40b;d(4^vYI^gWg*&GoM-;tM_=tvCY1ACY`5kVxo3uFy$q?W+||&yl|s_ zllp9klb z?{f0}FDEi@JYscukDK=4KUT_pE9>m92k^JPmS41a@sYn;DT`7jR(S|S{C0Yp_3iJi zyET#Dx!;}0Jl^`f$O_?IxQgvkRi%rlewguwN}rGQ1_ zd7n7}g{zhw2s=0bWvxbVAS={!O0{AN|IOUHD?64{7dL*Gotv4+DBfK4w)gp8MFD|7 zQs0j!s-!QNeC&2b_TO=AE7nF1*X$hpT6^Kf1KAZmYeZpXlEh+0v>)x8kFX zOvmTV@ZGj$Lqqq$y=BKf|C`XJzj1HTE6Y1-4>UH|Eao;0i*~ycx=o-<{_E{$x(AoA zUp2dT!_~7mx6SUSf7Hfr`noO6SF@b5t_3OW&ENOw^)Is|PM3uF;)croQ^F%{9;B*> zt)IX7`i48R4G;Fs^I|dKO25uC`(xjfm60x9JQg=r#OrM9x6EZxPe z{JJ!y^5S#d1uZPGUCB=y7&bzFT`GC`|2z1>Fa)$z)-=&RQ-nK=dt5A);G`4SCl{U4XTjU)e5b;ugMe@5zyYP-@Qo_|%EgtO?|K#gFDF2!oxWMYrU-ql-oF{uW+N_!>cFynNx<%JM z7zvubxe|GMqkQc-&GJ`lw}b91t>kV?Yn=Cffo0%pZwt*UM~tQ|eEUOA@J7$xAAQF) z4K6*8?e0x@@E}*f_H-3zl;Cj#K2tkBwFZuf-Bz~?e7NfwzL}iLY&m%Oje}RA)M71* zi5Wi}^F9c2u=R9FSMo)8O5M8MDR`om(|NP;q@9+&8~(dVh*C|&X5|Zcs z-oaEUbw_#Otloe%v41_!r2d?%{_#V#^%?J*+AD4}SYO(Zvsu!lN)_cdRuYDYymrty!n?7~J=O#7Ng{l81RDaRojCuQISEoXg z$c9^M)?HMJ-8^-HdR6P*M@$?1JuTinkb3$|{zXhAi}m4I2AVncR|=NeSFZ4t*&Y)1 zneClNwtk|~9;5i_*13`48((WH>gUV;{U4*YLqfi64KI_WVYf~)>uTRM{m=i1`m=uD z!R+$zz0%jj=L#QgcAw%~e8{w??Mm5~m8$}tCi3;Id!U)tAfQm4aMG#IDdn)kF$cN( z;&myjf6xDWb??*UwM!k8e($dQ)5y4D{ayEjtM7H5zrLMvcahpW$>>$yDlyxO*R}6b z+v2e==~w-`EU%B78fMl`Ep?bT_157k6Y(^sIidZ+t3IwVH1~|WxZ=*&#H+$yYxyg+ z*X-rYRx+4H_(dG6~M z`Fl65;d?VFbbpiO>|N{Eq&&5#mNUBZ|I>>|p-ld??J7$*Z=J*FRPO(q>#$U8`pl(` zH{Q?L5#hjAa=u0HrryUl+0J#Q@6Hw+ckuo!=G?=&Y+F?A^xb7sKZw6!PX6z#y=7KP z#arR^R%~+$k`*+5?}^-7XU-~;QgLACp?s&#Y0}f{vJ(HjwbOfGXFoq(z&;>o`u*eA z&sNU7ozoKi^iG1wWsbMAR(4p&ntx;2+xts>DTCppDSmIWtj#C>?mIi-iNo8QcjcBX zd>`@WRmk!ZYmd^KA#W#dZ(3Ur+SL;A>BJjm=|j0{r$Tggma`sgtml{=PG_(mmaH?CYf!WtzjO|r0pn^gXzA}b{L^p^O0{Ig=?y*K|QdsuZ@!o-(%wUei=(FhDm>|u?+e~qY5Dee zW#SBb(eACym!|elVDR{F>SSYRbM)Nt(ian^P4->q99F$tu%V_pt>f6zJ62wI^SH`p ze~)hb(C4CF)OmbTj9#Jd@~hK-1!ri_|E0L4>Q}Vr3x&ilOZCD}+--S!!+iCtu4AS1 z6OTvaZogs_QE;C|792eDF%-fe_lBMg3rx$1fH-zrMUP%InVwrMrHg z5;EAT?H0(aR=;khSzBxszVuT{(2X@bYAsra)1FRUcs@r)k+=t$6M2ms2ITJ3XAN(=30io}a+-j<2#(bGf|u zf=gzK-{ur1mVDd$?!8HQS{TRQXwLzyM`Hr1~zn{3;W`MJ6nSFH!#VzqPmWwpzaKTl zzkY7#Wrf8;HEdG<3oVw-_h`L%A=&Tq8D6HTTgq637QIG&%LygHffNGI1rA?Nt>y zPt?z~zhr8tOVOy!YgxPWvd!zcY=u@ep$75{8u}sUlWm#~bSSFsYRYAG{A97!oMm6} zwa5Ls28x>uYvSfT+mtcu#gDf6Ve#UhFZ-Tc{D>zm*=(`T#_hk0noiGa?p&jn`g0HG zsblOfIX^r#tUOYbck*Mi#RR_6$;zD%dXx@2SogMAmhX$1eBkwT(Tj1?^XAtH3b3s% znG;)`agdj5(*Fj3eTIn_eoAB;RTdwTzYuc&WO?PB^_KEeEX1CklK&G>T{?y7NACre z_8HrwymuXO7e2n=>)ClZktc6kTWnnIP|P`rY3s_VQt$F(Yk5n*&F+-dHr*w$XvrD7 z<&UIJxh_Af&K2j@{^X5&sB`W;`GMCTG%~}_n3M8!FFLUy-c_6%YJ%RPfl#U zr!vb%;P)9tTLTNtgR3TZOi4Yne&Rdx-Yp60G2a&ii!$67-mf{+{*C9yquv_wsv`AE zy$sEm`+wy8-*q%<^7HxyhQ>YVk&}ux-(d5OEcE=o;h=y{-{c$1Hd}MuFAQgrnUTxq zF8s#)m7XJep5|LdlUQNi1Tj_=h-u-KgI_%B*E z@y)T)yrhQhaxNya^Zp&+&Rb-1;?G$VsViCU>bNf$A35dkc=OJ|S2i5BIxBf}u5B+Y zi*UTTv`{?6P>^GinE7H)d>L3(W71ITX-3JE-&jhE~R7mt@!Q zEt)3&Ed>vsJ8S#Y&Odh$)ZhSbDMo8$Rx9fI1Id^(Y~dPYss#FK?5`S!{u zpA=E5mY%a{FYBdu;V&QeZT7wNSub_MpJ}(JpIZL=RMMgHJAn;lo0_yaWuI9}70-Lg zajjwD{8!~!Z=ao0_%~ryd~VX3Kl(O?H{S*}wut@_J-Q^~q_&H_oEFu-gsa!x6`!9 zAjJQDPpkR&@J&n$x7jUpbA6?JNOehC=KhoS)3?1!Y51o2W|q#Ba|h;5)#_WsXUwG` zw>)1VuQkF#=fcxReK)kPC(gew(P6o6n`e>ZwkN!=;+MxT=g76)7j}3(QR8;4Q;2`X zO{s0(+oW%9m0|npz4iGCZ@(9kDy_kf9F8yRtvwrkZeFHaRI!rl|9Q#}Bj;*4`>33n z(cQ3%DQ#<&(o)+s=caOPu{fisSjwGc^vY@J#wGIm)s0<*EWJ98xri~cH*Z+H_I*%s z{^Ok)2TxwQ{-EyPy^Y~Al58#->q|GQOHXNw6`b=Y)bsx5wH2kwQ_b4;%ru<4D1EKk zw8_&y@oV48SorlghvXFR349!lJKRja^F35iby=|RhQ_AZ8|S~8U~uj`AJYq_+yjnR zW~kY%4$skXYyH1(<;LjaM-Iq-s(qqj^h)&#ca%u7?EZ7JzMYcJ4zb>^;~~s$`tW=xBT;cuq{&L4}XTt8N z+prw?u}-FBVd07eb37z2`aR|-d&l){^{VbdQ_m=_S?jMn-ngk?uCs^qlnrqwoGW)& zz6`b3<=e;b(Uf`5hUq`MbpM8QGf1lM*nReLYQyS3zjyqMxWDwXLh3rzlw}84-T&!) zU6EJSW*BksTIR89W;5Ql^;>3qig46BUr~6pyzx_C_JdnF7mlg#3hBD^dOOqc9L@B5 zjxNiMR^3tS^Z&W`whM=kk#wAzPkP48H~o7`-TrRXxoGz`{>}fjldJRptvyusb$Nl- z@sv`QlbhXTzTcUDS>TXL)zL`HaMOJO8*F@cU)FfMbeFXUi{@X=l~+R6Ui$lg{@UP@ znb#KDKm4=%gXop~ZMBJVYcehF7WI|$PdvK)&1+rrF9I0{CSJXiHM37LN2fO0xx{6< zqob{OjNrcspMpN6avZpwD%JXi|8cmN+{5O`qL*jQ7Jar9+H>jR`WfOo`hG-9R!(M- zGuiF&(|oF{!@{c4r&)yDISgIo&?&+F>%^5<>p^h=%Ukr}Y& zsi#Sq(Vq!UEfS~e)Kq>&=w(c3=d-dB;M6P;%Dty^`jq`X#(?_&0aF)jI(lh-S?9bH zzmJFH-wrw}pmlTofvdc=JVvc?9<9;m1vkX__s6e)Cc*x=QsYf*c^6y5a<2Q&N}gF6 zRKDVRYu%`s>d{8a5mBi@scX!j?Rd+=@1-O|TLp-MGNiFvF{NA}w ze)XQ)4b3anH=O(GZ+!aIEm_?;2d|tsIcsX5p5tnXM&2Yl)i>SGXYs6-Ji2V&g#G9C zNjDlXYKq&XIF&Ln$gor{V$Q%of@anYUd+S6g{X5}+nGTF?VzOeSH2v5 z_ulBr#`SLvoxQp)-AwaYa_aHDU4o*A@A}T`%(b{>zz~-AF{dW;P6cn!r<#pN?rc|^ zH^-ZKaZbcd?~at|9ll2!Pei}xJskF5Q6{^L@rhYc4&#QNJ^y9c_FrHxP8OSfdo>^H z$3#{I!3nDBHS3nlEPH+AP@CPZ*z5CW-h1p&9Q!`4@m8qm{JmFK)Eo$UGUM@2-Mb=Q zO7_iDUQIaZC-5)wWKzV_+e%E+Y)+=D>1$PNbhUV5^;Ls)^#-kktqSpe+P8Zrm_1pz zzjpuH4==@BOeO4?KlZ#=Jfu~2V#-McH?dg?o0G!xLuPsHW4`+_I`dB76060VGw&O0 zJzCq5xk`W9`2{^!Vqz-}X1)oy(znXzRlDS~-rutrUh3`4dcOBl+JvW~%18g~VSjdi z{<5E^YGcn&&(gUgxTNab?{91kqK~s3HeJ5A-DUD)kIR>r{P3Qlbvmnuq3OqynG9iX1*`d7S^dHSqg z@Uy62@5*NQok>t#bx}!yy?Upqd{ZTR`ys}D<~H@n4J;A-SJ+G|Es|Z`uV@)fF%~$K z^{}Hw@lUb9u|M`6^GkgF=eq1U8++wy%aL0DpF$J8zn(o7$voeHTX|)Km(geU#v^+D z6Am_B2nqH7#KYNs;?ZpP$$IPNnoloodADiR@{Q775__C_wKb+xgdCDts%p<75S7Fz zvBM&X`&$c>FO$Z_-(7Oq9xEAzU+xZAkQABDu5BO3%XY&xBwK3A$~Cof_Qi|+Eoxp` z{$)aA-x{sM)d|8y_kAj5j~$)3MNTVQML$)gMQUQoQM`ab1GL)C^=vo_3rruJp`VO`~vS56z*9d#M_8XEse zDsH}4Rd>B6)Aigdb*r-4<^`K4s)XEJUVq)nmHn|8yXU1&j;O{-Ay|^m5w7nxc=lIBqFxChvXv?NHaU_`Dsy$1gXoIeT^D!5mWt zV-d}ow@lLyTT zXTGbQ>q2#}%>Pq-WkYesamN~`><+67Uh4HL+$Ub_bDq8SUY41CUxhE5%pZ#>_N#QG zx}8^8XB_rR2`&(@HcC=mlvH<;>81X(n>!9a&~m>ve~$)(smq(zr0cFOq4V@k`!AMt zZ`i#5`7Wmw2m5y^iq-wdO22;0LfG+Hp6@=vb6WGVAHU^jmu6c$Y14;-g|F_uoKRdS z;}Gn;>X*}R4y&urEmKb@uGzV2@q}p=|NqC{{Gt2%QKvxu{NNU^d0goR_5LQSr2gC9 z+xb42t(J#r(dI|{&n8H%+wWX^mwAKFo<&yD zn`WNNUojy$uplK&n!Bdt{ETxPi$m6)X1L2QxaWkDdrt~$?y(p0s@gRVWOCZ|SzFq3 z?DGS3CpTzKuWH;nxv*lo#!tnof7`b@vjmENdh}N_;@PKd(N+(_1cl@F#4oXUW~6!0 zF5$ynHm9t_xWJ&Agk5&eQ}X|PtZ&MBy0}%GU$5oDl{+c|4qa@EWlxDTY|x%1m3VH7 zzOg}idyCe(n&9FziwE!6<|Wv2JDs{EGU*pNJF zdSH|9v23&ZEwg!Mt88Lh_#of9|G}Q+5uB9*|5ZCwpI0^s{8Y+0-Ti{=DgWok8{B3D z>%JDc#(dz!yDbm$RyHIY-mTN*yk|%H0s9@yo<#w_-Dho$v|ZJ<DcAo`pxuE2W&z{*RYHZeWwqtkMeXF*z3?%#}p@BS)Ubyr`&>!fnwljZ(t-9B^8%$@dM+*rqX zZ^`XHpHoWpHFr%6Qux_DX^QjVCmXQL5)K^ z+wLj&v~pgmSUV-~p+LrY&Ur`8(*&Y-|FKHFswDY6uJG=$C2mQ3+V{E_I^O4WUMBc? z{r(O%&+Y4&?Hvv**XCLN_LE{8tH=}q#VO7zLQ3nL+9oz0S1>t!bV7H*?t^A0?Kiw$ z&&|W2ncVZ~Z_dm^+YvX46*lw?xebM{;_0s$xedREtS&4I>7xBI@5m+O#a30J4 zB+pr@yoz@0HkZm8+Esfe-MV?*M_501<>RSbOcu}LwwPY@7rve&uz1U)c!Q-`m$nP5 z-MF}-=!jyF`}VCoVyYdPF;lHh&f!Usc-49G+l?tYH5-*CX-doqwtA|!^Xe5-z0CQ? zA0D`1=r?6i>f{usnMp|6m3AmXKd$>K$8gJ@gT5hal^6RME9Y!%u@$h$^0aULc;Ch_Kvwal3X|9F zw1tsje1Xi&_hp@LhQC>RCY^zSfkD6oL_#r>fuzhfFAEhu1_p)`(#cIqEnABi>ADW{kdNYk{OI2O<-U5EUb<7(2~uY-E}rCm3I-k^I4bmwv9|^U5}n|NY%nM zPy@v$ELHSpNMII>67x@FS;4XI%u<^JT1OjmER5W8_DSqC|8|=1^gLCi244PWT=EYR z*Dn(6)%o;aa7&}+qu%4I*Q76B7`*vhu5yS$1^>>&Z>HErf2sSkuA+=04fl z%6PLB-F|!fWJiEsePhQPrRYr>MlVWOy}pF|rltPMy2V+3d&vy-)v~{zC2!|yiZfo2 zqpBHn{knhorn5yM5Jyg*_F>Y#@8J$N`16kay+7rpbkSw06U9f{qqC*b4}avC`QzDB zflb%i-a1}>I9F^@T~^{>j`J({0_=}{zGb@Nz3%o24I3;>7QdBu)%#H7@nWT-z`u@y zjWe7cUR-1_FL3D%rP>=Wnu|=EcqXN;)-3pO<@-%1=dUmI|0dWi*Od2rnIsx1wAeMl z&qOe$Ftn1%LNZ#@*UqZ=lpxnuyT9^Np5K_XqTl_*lL+Om8SfcGW+j=)ywf-KF^O9H z^bTK*v||33y$_e#{499CWz*I4J?o#82pql@_weS4c+c~Dm$d9D@(b9ssA}~Vnaq#J z!Y|HXf5W)WW2y6w+%pM+S>ZJXZ=yNbS6ykj6Hpt$UhzVjY3-AahpW6r+paNnF7|o6 zA?^3gr3viDqJmR4-*`UVe4Dh?hL_(@Zegrns`WXqpV=|);_>n=DxDG;p~f;FX6!k+ zyx~EM0JjONj&Jj(qjjfNWJJzT&a3b~Bsuv+f?|SKCfliSt64LDPQP{dXj$+oLA8R7 zSB{*Nc$NEj;+%+zoLG-dQx0>O&N$%TsJ-f#l-h&(pS!=t+sa*$UwHo5R7KX>Z;}`E z-+umh(tfd{m0@dr2Cwa-5BF6*SRSnlYGx5?WmA;cu|@sm{nV7FD|1=?e!WuFy=&{8 zz1QCbnX0=#pStJy4DTt|&d4N{0!D?02{HB;e&uE$;5PAmBZ z+Cr8)Bvu91*H~~gS%`eoNPa!R=J-p(i6^)(elVm)AMLPIDM)l)+q}2tL+!!|A@LhkC0fH0WV11EPgC?Sv%v7|MgRcMf~f$%Y`NT|Ib)+QMP$g(7Dqg z+Da$lZ8VC5HXPg{F?Gw{Kjx>UwmPX7{95Bty>{ue3kKIFs93vIE}8#H-!njIR?V83 zJtq&j`>RfNQ1_XCGeehsZTYG9h6^TamRqyKJ33>HHw)iF=}XF~Pv=GUzIUvX;JdCJXmTXA#N4&ws~ zO`AAp#4KAdG4}qFyzEQMB)nuVT$tvVs`9ey?x z-!>Z$&A4zo=+fg&pFc<6;1!HMcFl2lXJoTU^t8(@_afQv&10IGHGSSCdnJ#}^XDra z`EgPA%HOH!_m&@b+L_H0d8KHg;psp6>?bpK>A2lEKl|>oU6rbHrsziAde#{1@86ia zO5(|D)}2pJ@4d_TO8%%D^WAf^CSI%kkV-G`ah#T8gs z26*O$H}Snb`^+Ka@M6uw*7e4L_oAdzwhA>`*alk)78$6SmoGY^RA+iCgM*Lxmnl#2 zr;2#PwSRl3g$dc}olfVRv#hM@{9mvCg2_kLTs?niU5=!Lfc$O#pOSa%J&iv5NbeJx z*>2&nro1epinaL1>3W^zjvpo@uhHAoRpfr4JvVjBwtN}hf`26uizRR7e&kk|el+Eb z+MU};oeWl;H)ZR3r(Q1L3p_k0_fL6>^jRyP-F2z5cdqU#@DzB;TGhJwhgbIb<})np zLB*j}s^#uQMkfNxZr3~g>j{ccXW#YAtn&5rsii(Luih;7`Rw37|C{OU*FSoG{@q$2 z?vZ)m^X%UepAXzxf1yL5O(5^k%FZq9YB3=$yAIZ!J0|^qhEjE$`NS9cPoFTl2d)!~ytwJ9AlDFNx4l(a89-05I|8jQz1ZkrOu1=qX{Um4kJWXD+ z-kw{&2`%}wq-DwD6y?af>c2c6n6QSTxr$+xL zo}b%ouBk*teOPg6Dc1zvP>Uz4udOR`kH59?O}jvB$&=G8^Bi}+@a3GO!SPREUEBBS zODEG`Z!UA;StRss{w&|0*Uvr4t$V4zZFcmcrv@tF= zORdD<(TTrP&%V@BN&U6|%8Qtn0*4+5E!y;7{dxNCK+dirKSQCb)=8Vw=KkDo@lpNN zsWzE8Uu)m0rRM6H*`(Om`c!MpBs<5h!W(UKkG*=rVJ6XRB*Zhbh4iMSYKo5%GE*AiIGbB)lEJg=c}r-@}HS0nN+zy6r0WZT_NoaoP{}Uv+W@SJhL3Gi%yE%rBqQ_9}D#xxdzn zR2zzae?QG}!f{FJbpO{*KX{J(uswGmwBeJ*8`JEGg?~cV_BoyK_jq;jq0g<_;?q|T z3TuT-jN1Np>gF(;zGwLczwVqhu8|e|EIX;`HrF}N%e$R4PibFGbP=)qQM}CbvY>76 z3$e{Ni~{=@o~y0BFw^79-=j(Am~^Tl_$GS4&X@j^Yq&;8=t+pmjyJk}{L_TmRxYT2 zxbEh%Sy5?eM-C-<{Pa2I{k$URf^S*GQK2&*-MgN@UNy;XO1_m)L-?r$?RLG9U2?_h z)%*)5^)a5lVk}^==||{7_xPE|Z?eT%{QbA!{OUtoZ#yGh*k{IDwC#}G@gZYM-jT0X zYi)nH+e!p)RdX_q%QEHQ)XU{7IpOp3NZY@4QX-Yh+j;paxJ_>VdXTY1c9o5iCR@Dz z$CHy2S3Tj=_>tt`^ZA~krqqpHLEn-%loTz$FFdEPf@f3zY29G8EZOi~46N>xk5nsv zJygu`{`C5z_k9wB_)j*8?cWxDBd|sA!gChMr1~;Fwl{CYyZyD41eg9w_P5*k(fR<- zqZ>(opDwmFIv1&VAl&%g>niEr?l}w(O17!KQNO5P6|6Z&HDKA#Pb;@wSTjN8(YrZY z*b)!4G{`^RG)HoG?zuP1U9I`|;uUfi0G z#moX1SsT0TugYAU^Em~WHjRDm z&jf5&t=PF*F8ZlS>Xv_PFWfXYY&0rA>n;?wR#ZhdvpVpu760zOTbThNofBtXKKo1X z`?00%(;U99@^AWk^;**Ake!e3PAc@;HLG1Yb;jJU@5>fWD!j2v>V`FU^W~}SxmE7p z?uv(B71)^fWBaMFrSn#N-<0wsH9hUZOaJFs!pT7F+esJ@| zLke$IoVRRWpLR1~A>%5c!Uduc=hVzj3H&z~5ET_U-)dkWs(rUV;HTo__@(8C{<}o1 zUr~GGcHNpKPkW~`8Z&!bocedg-v8Tbs!v zxYN&f0{Q75Ix0RoWXTYzc9-TkG$T#ggY z@N5vDdHu4@m98!4)u*mfXLuXO{_700Nc#$XvvchS{9`_-t1vgFIO@Edv~D|V7;EIl zZjHNh-`L-ot*dnMYd`m`!iFSXy}~|=X?(|TKR(^Ye*M}-{}rLje_!Og#`XW7K(^QM zZ2dXbmxX4%VUHJKlMGP0bdsQ7k?VT zZfBBvTl~g~Xt6`TcULiX-*S_-R6F=nDgD=drTa|(lqYE2c($jH^{nAl!Lt zZyv>!-7@R?9sYj3Yu&NHkB2A4eJ;wapLNtO@u!Oo%g46p!w0k%3A9gXDz1ND@gt~g z<=YL*?0)P?zI#~LMZ_Ju4J$2%NXY00|_FAz{ZgH!aBwN$1 zMW0_Eu<*z&ZTb9%clT00J6Wa^^HZO0lXKDN`DpCZcDCp$@1vfn$Bid^*eLG(-Rb<2 zS4>>p3jbNB7Psrw&ML1A(XOtlm@Akd?zB(XetU+1&D96@AA3hCw~H@W_1Ih|$L)V! zoR4+U(`6qv=a#bxEV$gKz;@YZ!;PgYjw@bMJ+>_K;;D;~dg7baoGx5#y`#C~zvAb= zNlPB=k4asmZMI+!bNYREcJqc=3)U%3e|@z@;6>z2n{CApe}~#k=Uj8xZT{z$s%udn z>yF=>(ezVQO*=8`*P~hWSMG27z0zWJ^3KW0oDA)LJO-_4OD6RNZ;lZbV!y5-x64}e z`PDi6{j2UyV3;iU;+5*>uTf8>&R^-VX^G%FZ|)^mFyV^IUH#e3H?wLxThpDnwuNRY z*CqYEc>S@FaMwT+6s3|!HBjg^02wKhKIRT_8a zQ?OF%&9i$?W;lDw`FO0ZsQ=G;L4H&6*P5zqmKetqD;|H1o%<|&>$2lV+1Xw;P7tm* z#IGThBI|yVMWz4KhEJ)xFC40PHn;D5$m(@p*F9M-x#-ey`H5xTw_~?GubKax-|v&V z<~*gtCrcVF!xwEgx^nJ8@N&)%xkfobyTfn(m%sbJ_j`WPt8IHT<|kdf81+g*k#kdz zzBMaLOKQHlZta#N?!&!tEL;cxmyqSsSL!<7eD=#$H9` zQKfa*pM-el^fKjZcZ~NKT7X+_Jv zmoDOE(pBMD6Y8*jufOZrGsoDC`TsguPc)8Y3~lGeiBD-twxh zh}!3P>E_9IYmcoIT zn&Hg79#{6iy;`@wR=j^lrNc7`hihG5Ki%Wp)Kf5fk$>>hH#2!tL%$`wmne-a`d%CF z=i9M--)y;0E1o6U#J*W<^ObY%oeZ9E7e3+{F+)>2}JeSmx6Wi_*&e zboQ^Ff6?Tk2A^u|2hYA&S|9!?m1c%q;>c~fW0-rSk!_b!&)P`yxBFKgc{siFAEot?8Ro(yXtM| z$vzILAGi(0YYpg9w zefom4Wh%|Zu4Sq4ynh=TsqtmwZI>5a;AXx zF@p1DLg%Vw))kWi^>SEc?2n~5&3W=Ya^c_BmxuJEq^y6`R<2k46Bg7`YO5a5_xHo0 zI5(?9Iz_K#vQ8aW_*k|teP(QW4NuWM-Nn1DjdwJ19=o--aEh4~-?PqAot4Y8&d9y} zcxczZZnJQg`BzWw`&}z5m89;kmn-q|mTy(yuH)PC+855rp6y!WZ?1h(pk{T1=zY!E zX)XO<=iI;ayJWK6qKMYl?NYAG3>O}5_fJ;+e!Qx43ghA*izhCApXw#|{eArWnyF9p zOOKa6pUWrSQYY89=i|Q}ZR=OK=1x1<)+m^4U$Hikudegao=c_|Cse*va*J$S@pOl_ zI&fQUyFZvoP9X&`%B+PC5n9# zzh0d>DpIDoLZ}n$hYdf4=6L*%Jo{IFyNB1+?`j3JsiY8Sz zt|@0dtFvaoh1H)f`{-Cd_Hj(Bbz2;(AkeyOlABqV@4TQnqS1G<<{a`gcM^M_x8Y~O zk+&aqxLrwHJ6qUB-!zZY>dZUFxwn3G-t?`lR}u;g*z!J3V3H$Gdi&y6qQ@Uu>jfmf zcGZ3V=-Bp@T^qKsN_>ov<=L}iw!UQh$=Dw&qtDsp1f>0VmT+V95&4#TzsrB`74)c> z-xN`3y{qbTZu$1D)#4RTgqnePo~UjL5}Tsx6(vx2@T~JF)4GrP(!BFV5BT zxx~uX6&~{{v|qTdX@j2Hq?=t2o0;+|IA?p=*XK0M6|HV7tYa4n-EKJJCA*-Ewz5=U z?3vAGTJIv3YIb|P>|~$z?$C~)UALpe-_LW_@4tVC*ke>bjmFBu1U+}y(+P_BKR6rt1 zs@yuu^PFSA(bI)LK#LOXH-zf!o3P%~rR2Er-RmN&^%bhrCF*{s#Lqt?uJ+OBa`PIF zI0o(Z*~e}f%(%ZhYl8oD53RE&thc2l{lSnH;&!T0jxc~JIDv)NHT-{J=UoE=e3`ZdvC zf+sIuSia(EW&c{H2QM#)yySYYY4K;qI_obIFYkxEeQ{c$;2-<@o|O2re+=FA`WElg z-HhX>CuZB$^lIX>OrPC5 z4|2D0z5mKwHGf-3F-IeK#|A8Vje#Im&1^oi4BIGp&(RRgsIAAIW$Q_iabFC7cN{NRFx z`TIwm^Btyr@QVxY%Gk=GXq6wh<(a)?fIIt<`O0-4=ic}fr}d&c>Ph03o!m*A&2BU_ zci(@uzEkGkT<%GK&Fu3(?{#{*v*ztG{gRcUORwkgMBJL?(5crTZ@qW7_e}jw^}J6! zB|@ub^o1{A-#qtnef%8XR_)q(#{a!%+%b&1T_37+fX(xr-sh5=;kC2X&1b56Jt>J4 zWV@01%yr+&7mWe?ja^orD@xz;I9u9Z?hVV-Slj6vi{=Z~JHKa0iMRi+{C?@TgV#H% z{1<#P&9yP)ZRaj&E4uo8D$~iYpH48bZt^NSopIqx^_|p14-1_1syjcoPk33jg8RY! zl)V8LT`qsSve~VNKizuSzrEKVtc-s1asIFB@80R=7H&Hf7RV%aE3Y!GO>pR{y}{^(&&~cpHS1A{T88k1 zpK-!#@4n^k(Ay{b;cl3c3e&Xvlh@jEI(55zJUMCGSUFvmPas*4hN|#E{{j6mv zuq~?V&=vka(}JWL?rq&^A89D!#K*7adm||1to+Pl6ZK0EtUGWw@!$rlRi;%J#bq~G z?TirJ6@T{L^>6;h-*X}(?zD7ty18V&tW_)7T997ycEN?xr%!86EmZll{4;y)4AspN zZ#mN+wf{Mn`DRyD&!0zZKaK_ce)K6)a+hDqp2_uVrtkAV_)S^!=(n8=`zjotdRy=; z*1tPhIwfh-i#0l{_HoWJa=C5pdc=T@-RSGC`>pHp<~18Ty`E^Fukp)IPi%Kap!+gT zcHgP|svl}pcE~>rQh8-zb#B>Kp+yr4=dJqu&oAK1gj2`(9P_3xTsOP-+)<;c#ck6c z3qF&onp}1*}!ex4vdZ;nV?nd&>=+KWPOlLO{t)>kXItdk&wP9jS{CMg&>@acp+ZSm_aD^G7y4aebMXtNZDt zou==qxmYL9IUu<6<%QtG^Zm`QJ~}gff}(Bd2JH>z5d}qwX_7HX9&3+oka3KAp`)pA z#v`!o|Fy$8J2h4c%J#gOJ3DB}wSdfzB1@mxK62}h=xuwD_Vs&`dN|WAuRYx76*p-; zbqq<`s$ud!ub}3o@AsDptryQ+dAOk}KQv>;YLoq^Q~kC|m25vbdruMjb*muH<#*@z zPfOI^R$j`KO4 zpO+TDShc`0FLjaM?gwdh?;V1i-KXBmv#LLLq;K8B+l!y|{Mz<2uH(qGc-I5x?!DM_ zcFMYt2V4{POD1%4M)ES;SZU*OjQjudkJ5TZx9JAWwba^2e49CLA!hDAoO-+{|toz6sa z_6VMy?h+OCpwLb?;@0swJqeLPXFr^NP-!!lZ_+gXN@I()mQ~9(ES9N0FPEnC@|Kdg z^+zUoy9B3tCFf1ItyiWRGH?TEO+;R`!!$xsMWV(9^WUShF|uVnQZntmAp&sUC~(q&$&G{;m->GebKt& zCpe|zWVK^Mc$zP##EmA6g;zNeR($RiKfPdWN!PDU{9899B#1^XV&5z+$9n#L?v~vL zq7!q@tj$V#U$C0zv#`6-O6^6pZ`tn7&)R0cu0uO-h1R>I(uCFWJMZRc^hN6zD&BvP zWcK3b{NI`Z>M5d@rwp&!uH{L3YN|gqa^bZ-C0n=NV=N4--8nOU2Y21>HQK!9tKQAY zer|eBEG79-@WM&E%Ij0&T&-fB?&8_M>e^F5)(JuHgw}q!WEmQHak}>PIVP>Enqyrq z`TS3cF8HT^>EiR_(l3(2w|y{NYJc#G$g)TBpK8mm?6))3S(PNqdwfqvMfJzpb@A;? z3!E2h<9WGv(>$#+3s;A+>nN^%k;M^u>dBw^ho5iG3;OZsTHf60`S;)FYaO_>Bqy?Q zqwN;{>HO0c-@UY^&$|3#oI_b(lZ}d6_msaN`+}-O zBGWfadv|5O*cX$}Pa6wWHq$MDVJLV|Gge`X4}d2k40uC_P*QvxWN#sUX{p@Y)LIAWm0r&nq|%}s=5`5rU+fI1^ofxTuf1Ys z+>vPxJlmI`0=p@MYoP z71g>;6E*W$1y`p@)b_tzcH>HTbY=}tVG7gV=bNP0zgaaqeAZpb`TBp}U72IEWXgHB z^PQ8tzOa3~9%r%j>FW2F9rYevTB7kqT`+fHck2&-2vhc(OXuB0F`- zeBNL_zXRO!cmn>dGmyU1~L;0@pC*(C9-Q_%A z$#gRJ7Dk_B)HN}Q3|y`dow~uusUy~Lj=@jSSKPG$HZNA+k~qiN9Ddz{QF-pwNwN%$ zYJrx!66T(t6aCBL!^i7Eoo5b}7vDXVev0+UrN%j1mH%{?%ytE-ew8q|*1kY~EJupLeejesQRu`_I$44$pTn${uQ#dOKbF z%$>Zjzs?WzGfr_%-8(oEIi@#JMX zUrJ)0O`Ny%%!=f5jh%*d8&&3Ry?$ZC{weD@zR$7PyW=g_JccmwTbVUG_^lpVsD@-~ zoz8t9-&=YjZrd^$MMbNU-k!Im&&#D=)K)d5?QVT_MEY0*WCak632B>GHUU#Ok=dmHJRqV zMA>kus)*Gs1K!T`ydT1K&p&_NYbc@`sJrRx*K_Z8%zyT5`K0NUf4?6nu1#k@c)tJB zre=SS`Um!9RzIp{eb)cY{#*6E;7jM;E_YJN`NU*ZFnz8~!W)+y1WmiSoz&&+OmWudDMaip#J6`2X#% z*5BP<|9`K4_Wx|%u|Ed?^nbqhsXOxj=U2-_x}0+t@4lc zf9wv#pV_~@{`kMo|C+ybKUw`x{`36D^|`e-YK{M||MUHT`RDns?Z4R{{hj;&|995k zSO5RN8~>gE|Nnms`~TWKU4EnJvg)4yH=IMZCX0u?{UdXC_PqQ09l393F1cRakh*-; zpS@e6|*jJu%Pa@%5Jj@r#5-HB%BRH8Yz6)N5E-P|d5D0hy>HsPGh5oa^B zw|qIpcz#V{{l5bLlZVU-5<_l3+q-JH^ZnnUe(n3et(wbU|2EW0?*FY-CAR;!hP0QIK{hqYgKCkGHo5Yl?nt1K+n+P*&-(uM?J6%W@x3isnJXmIM zSqIci%Aa}R-JFp0c~=hm^&0P3$Riw(w}xd>`4Yy|TUI+Rwuf=^Ub?d|*(usgBxlz5 z*;0G2-bgudvv1RNsn$lZqw6P4`yrXX$4s|o%Ju`NYaedRezJ5^S;nildAugFS1u@Q zn7|hB_VV*v&l+b{e&^^&&^+cGdgabDP&c}5iiNMVg)B`6Rce%`0l?RRk- zkE`G=S zMdH^*&I^kfyUk|LjaOw2-XeH%QkVL}9SU<6beM_Md?>L>wdmNTWY_rpdi`-Hw}WOE zZn=IHQ8qMENf2iFb9HWy&Z@7Hrq8GC-sHVtRI@B6K}&d?=eSwNxjVpYPKRuNXz6h5Y9d{+wTRP2o-Hdb75rSr$4u%3X>^^;MUq zuQ=_#ZA0OKbZge|y^|MJv$Bg{+Elye;ipF|n;mmkuunKJ^PgyksNC$nUy0Q_OpTt% z1leud+dN~jJo8GnB|TjypBV1`eEh@h2lLZ@HT!r^>fOZA>Qh@9zw-RfSjjUh<(l|( z>c3xV`c{3HQGY(y%g#qvznR9IUfz67V-<^mTIMtD%kx*U8_ZrT-hZxgThE%m-_I?4 z8O=F`O>}=ev99A9$|u&2a1Piu|12+p_y@tA@u#bsvvy zkz)Vu^vzZ7mj9S`r*=kkS;0Y-3yVva_!X=E*ciz_ZTY`o4o

XC-+g_`liCOws7h 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 diff --git a/doc/qtdesignstudio/images/user-assets.webp b/doc/qtdesignstudio/images/user-assets.webp new file mode 100644 index 0000000000000000000000000000000000000000..ed829f1538e969f0f5a05a8181b4cc58eb620fa6 GIT binary patch literal 17648 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%0A0}>DwE63Sulodb;$N+s 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 N!x;q_*chTfd;rhjZGiv) literal 0 HcmV?d00001 diff --git a/doc/qtdesignstudio/src/views/studio-content-library.qdoc b/doc/qtdesignstudio/src/views/studio-content-library.qdoc index b3dbb28065a..4e4119f0fc4 100644 --- a/doc/qtdesignstudio/src/views/studio-content-library.qdoc +++ b/doc/qtdesignstudio/src/views/studio-content-library.qdoc @@ -21,6 +21,11 @@ have added an asset from \uicontrol {Content Library}, you can use it in your project. + You can also add assets to the \uicontrol {Content Library} > \uicontrol {User Assets}. + + Assets added to \uicontrol {User Assets} are always available in \uicontrol {Content Library} + regardless of what project you are working on. + \image content-library.webp \section1 Adding a Material to Your Project @@ -28,7 +33,7 @@ You can use materials on 3D models. To add a material from the \uicontrol {Content Library} view to your - project, do one of the following: + project, download the material and then do one of the following: \list \li Select the \inlineimage icons/plus.png @@ -79,4 +84,60 @@ \uicontrol Navigator view. \endlist + \section1 User Assets + + \image user-assets.webp + + Add assets to \uicontrol {User Assets} to access them in any project. + + You can add 3D objects (such as 3D models, cameras, and lights), materials, and images to + \uicontrol {User Assets}. + + \section2 Adding an Asset to User Assets + + Add assets to \uicontrol{User Assets} in the following ways: + + \list + \li In the \uicontrol {Assets} view, right-click an asset and select + \uicontrol {Add to Content Library}. + \li In the \uicontrol {3D} view, right-click an asset and select + \uicontrol {Add to Content Library}. + \li In the \uicontrol {Navigator} view, right-click an asset and select + \uicontrol {Add to Content Library}. + \li In the \uicontrol {Material Browser} view, right-click a material and select + \uicontrol {Add to Content Library}. + \endlist + + \section2 Using Assets from User Assets + + \section3 Adding a Material + + Add a material to your project in the following ways: + + \list + \li Right-click the material and select \uicontrol {Add an instance to project}. This + adds the material to the \uicontrol {Material Browser} view. + \li Drag a material to a 3D model in the \uicontrol 3D or \uicontrol Navigator view. + \endlist + + \section3 Adding a 3D component + + Add a 3D component to your project in the following ways: + + \list + \li Drag the 3D component to the \uicontrol 3D or \uicontrol Navigator view. + \li Right-click the 3D component and select \uicontrol {Add an instance to project}. + \endlist + + \section3 Adding a Texture + + Add a texture to your project in the following ways: + + \list + \li Right-click a texture and select \uicontrol {Add image}, \uicontrol{Add texture}, or + \uicontrol {Add light probe}. + \li Drag a texture to a 3D model in the \uicontrol 3D, \uicontrol {2D}, or + \uicontrol {Navigator} view to add it as a texture to that 3D model. + \li Drag a texture to the \uicontrol Assets view. + \endlist */ From ee23c8807bb9baea1197e46bae863e67033455a4 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 14 Aug 2024 13:03:45 +0200 Subject: [PATCH 033/193] QmlDesigner: Fix syntax mistake in wizard This was introduced by a1b656b2d614828c646083a2a1483892cbcade2. Task-number: QDS-13375 Change-Id: I0df7970499338ab0874efd9c363c2c026f1c9e99 Reviewed-by: Marco Bubke --- .../studio_templates/projects/desktop-launcher/wizard.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json index da47ce36111..82bafe5b56b 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json @@ -30,7 +30,7 @@ { "key": "UseStandardResolution", "value": "%{JS: value('CustomScreenWidth') === '' || value('CustomScreenHeight') === ''}" }, { "key": "ScreenWidth", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenWidth : value('CustomScreenWidth')}" }, { "key": "ScreenHeight", "value": "%{JS: value('UseStandardResolution') === 'true' ? %{ScreenFactor}.ScreenHeight : value('CustomScreenHeight')}" }, - { "key": "UseVirtualKeyboardDefault", "value": "%{JS: false}" }, + { "key": "UseVirtualKeyboardDefault", "value": "%{JS: false}" } ], "pages": From c49163dad720c491b4ca3f95f149f36dd40fe5d9 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 14 Aug 2024 13:08:35 +0200 Subject: [PATCH 034/193] Fix crash if no errorString is provided Wizards do not provice an error string. Task-number: QDS-13209 Change-Id: I0d96ff8f59abf05041832c1e036db219e655adda Reviewed-by: Marco Bubke --- src/libs/utils/textfileformat.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libs/utils/textfileformat.cpp b/src/libs/utils/textfileformat.cpp index 9257931b143..fa0e81572c8 100644 --- a/src/libs/utils/textfileformat.cpp +++ b/src/libs/utils/textfileformat.cpp @@ -193,7 +193,10 @@ TextFileFormat::ReadResult readTextFile(const FilePath &filePath, const QTextCod return TextFileFormat::ReadIOError; data = reader.data(); } catch (const std::bad_alloc &) { - *errorString = Tr::tr("Out of memory."); + if (errorString) + *errorString = Tr::tr("Out of memory."); + else + qWarning() << Q_FUNC_INFO << "Out of memory in" << filePath; return TextFileFormat::ReadMemoryAllocationError; } @@ -204,7 +207,10 @@ TextFileFormat::ReadResult readTextFile(const FilePath &filePath, const QTextCod format->codec = defaultCodec ? defaultCodec : QTextCodec::codecForLocale(); if (!format->decode(data, target)) { - *errorString = Tr::tr("An encoding error was encountered."); + if (errorString) + *errorString = Tr::tr("An encoding error was encountered."); + else + qWarning() << Q_FUNC_INFO << "An encoding error was encountered in" << filePath; if (decodingErrorSampleIn) *decodingErrorSampleIn = TextFileFormat::decodingErrorSample(data); return TextFileFormat::ReadEncodingError; From 3ef51a5d025177de1c11d3eed511d7da924cbb45 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 14 Aug 2024 16:10:24 +0200 Subject: [PATCH 035/193] QmlDesigner: Do not take screenshot if view is not attached Views can be detached. This fixes a crash. Task-number: QDS-13359 Change-Id: I2ea5453c3ef8f278111731648b01acc8e933d7f7 Reviewed-by: Thomas Hartmann --- .../qmldesigner/components/formeditor/formeditorwidget.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp index 312c56c990a..8834f77fcb7 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp @@ -544,6 +544,9 @@ void FormEditorWidget::exportAsImage(const QRectF &boundingRect) QImage FormEditorWidget::takeFormEditorScreenshot() { + if (!m_formEditorView->isAttached()) + return {}; + if (!m_formEditorView->scene()->rootFormEditorItem()) return {}; From f28077decc258c1a5a913f1f934720da6d925e12 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 13 Aug 2024 16:49:19 +0200 Subject: [PATCH 036/193] QmlDesigner: Use transparent background as default Task-number: QDS-13305 Change-Id: If6c46127d47945177ac1cd79811c4baf2a326736 Reviewed-by: Thomas Hartmann --- .../formeditor/formeditorwidget.cpp | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp index 8834f77fcb7..fb43695f94c 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp @@ -374,30 +374,25 @@ void FormEditorWidget::initialize() void FormEditorWidget::updateActions() { if (m_formEditorView->model() && m_formEditorView->rootModelNode().isValid()) { - if (auto data = m_formEditorView->rootModelNode().auxiliaryData(widthProperty)) { + if (auto data = m_formEditorView->rootModelNode().auxiliaryData(widthProperty)) m_rootWidthAction->setLineEditText(data->toString()); - } else { + else m_rootWidthAction->clearLineEditText(); - } - if (auto data = m_formEditorView->rootModelNode().auxiliaryData(heightProperty)) { + if (auto data = m_formEditorView->rootModelNode().auxiliaryData(heightProperty)) m_rootHeightAction->setLineEditText(data->toString()); - } else { + else m_rootHeightAction->clearLineEditText(); - } - if (auto data = m_formEditorView->rootModelNode().auxiliaryData(formeditorColorProperty)) { + if (auto data = m_formEditorView->rootModelNode().auxiliaryData(formeditorColorProperty)) m_backgroundAction->setColor(data->value()); - } else { + else m_backgroundAction->setColor(Qt::transparent); - } - if (m_formEditorView->rootModelNode().hasAuxiliaryData(contextImageProperty)) { + if (m_formEditorView->rootModelNode().hasAuxiliaryData(contextImageProperty)) m_backgroundAction->setColorEnabled(BackgroundAction::ContextImage, true); - m_backgroundAction->setColor(BackgroundAction::ContextImage); - } else { + else m_backgroundAction->setColorEnabled(BackgroundAction::ContextImage, false); - } } else { m_rootWidthAction->clearLineEditText(); From b40766f09f6b293d39f5d77eab1c093830efffb5 Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Tue, 13 Aug 2024 14:56:02 +0300 Subject: [PATCH 037/193] QmlDesigner: Use Studio Color editor for material editor preview Also fixes that it opens the color dialog by any change on color Fixes: QDS-13333 Change-Id: If05fbd49d66900a01f4e23d22c37bf4883c8bcc7 Reviewed-by: Mahmoud Badri Reviewed-by: Miikka Heikkinen --- .../ColorEditorPopup.qml | 63 +++++++++ .../MaterialEditorPane.qml | 8 +- .../MaterialEditorPreview.qml | 128 ++++++++++++++---- .../materialeditor/materialeditorview.cpp | 37 +---- .../materialeditor/materialeditorview.h | 1 - 5 files changed, 176 insertions(+), 61 deletions(-) create mode 100644 share/qtcreator/qmldesigner/materialEditorQmlSources/ColorEditorPopup.qml diff --git a/share/qtcreator/qmldesigner/materialEditorQmlSources/ColorEditorPopup.qml b/share/qtcreator/qmldesigner/materialEditorQmlSources/ColorEditorPopup.qml new file mode 100644 index 00000000000..7f2250c5940 --- /dev/null +++ b/share/qtcreator/qmldesigner/materialEditorQmlSources/ColorEditorPopup.qml @@ -0,0 +1,63 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import HelperWidgets as HelperWidgets +import StudioControls as StudioControls + +StudioControls.PopupDialog { + id: colorPopup + + property QtObject loaderItem: loader.item + property color originalColor + required property color currentColor + + signal activateColor(color : color) + + width: 260 + + onOriginalColorChanged: loader.updateOriginalColor() + onClosing: loader.active = false + + function open(showItem) { + loader.ensureActive() + colorPopup.show(showItem) + + loader.updateOriginalColor() + } + + Loader { + id: loader + + function ensureActive() { + if (!loader.active) + loader.active = true + } + + function updateOriginalColor() { + if (loader.status === Loader.Ready) + loader.item.originalColor = colorPopup.originalColor + } + + sourceComponent: StudioControls.ColorEditorPopup { + width: colorPopup.contentWidth + visible: colorPopup.visible + + onActivateColor: (color) => { + colorPopup.activateColor(color) + } + } + + Binding { + target: loader.item + property: "color" + value: colorPopup.currentColor + when: loader.status === Loader.Ready + } + + onLoaded: { + loader.updateOriginalColor() + colorPopup.titleBar = loader.item.titleBarContent + } + } +} diff --git a/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorPane.qml b/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorPane.qml index 5010017f2b0..300c453c674 100644 --- a/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorPane.qml +++ b/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorPane.qml @@ -134,12 +134,16 @@ Item { onPreviewEnvChanged: root.previewEnvChanged(previewEnv) onPreviewModelChanged: root.previewModelChanged(previewModel) - previewEnv: root.__previewEnv - previewModel: root.__previewModel pinned: settings.dockMode showPinButton: !leftSideView.visible onPinnedChanged: settings.dockMode = previewItem.pinned + Binding { + previewItem.previewEnv: root.__previewEnv + previewItem.previewModel: root.__previewModel + delayed: true + } + Connections { target: root diff --git a/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorPreview.qml b/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorPreview.qml index fe95e33d900..c3c7ff5a973 100644 --- a/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorPreview.qml +++ b/share/qtcreator/qmldesigner/materialEditorQmlSources/MaterialEditorPreview.qml @@ -45,6 +45,8 @@ Rectangle { image.source = "image://materialEditor/preview" } + onPreviewEnvChanged: envMenu.updateEnvParams(root.previewEnv) + Image { id: image @@ -107,6 +109,7 @@ Rectangle { StudioControls.Menu { id: modelMenu + closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside ListModel { @@ -146,40 +149,111 @@ Rectangle { StudioControls.Menu { id: envMenu + + property string previewEnvName + property string previewEnvValue + + signal envParametersChanged() + closePolicy: StudioControls.Menu.CloseOnEscape | StudioControls.Menu.CloseOnPressOutside - ListModel { - id: envMenuModel - ListElement { - envName: qsTr("Basic") - envStr: "Basic" - } - ListElement { - envName: qsTr("Color") - envStr: "Color" - } - ListElement { - envName: qsTr("Studio") - envStr: "SkyBox=preview_studio" - } - ListElement { - envName: qsTr("Landscape") - envStr: "SkyBox=preview_landscape" + Component.onCompleted: envMenu.updateEnvParams(root.previewEnv) + + function updateEnvParams(str: string) { + let eqFound = str.lastIndexOf("=") + let newEnvName = (eqFound > 0) ? str.substr(0, eqFound) : str + let newEnvValue = (eqFound > 0) ? str.substr(eqFound + 1, str.length - eqFound) : "" + + if (envMenu.previewEnvName !== newEnvName + || envMenu.previewEnvValue !== newEnvValue) { + envMenu.previewEnvName = newEnvName + envMenu.previewEnvValue = newEnvValue + envMenu.envParametersChanged() } } - Repeater { - model: envMenuModel - StudioControls.MenuItemWithIcon { - text: envName - onClicked: { - // Force property change notifications to keep check mark when reselected - root.previewEnv = "" - root.previewEnv = envStr + EnvMenuItem { + envName: qsTr("Basic") + envStr: "Basic" + } + + EnvMenuItem { + id: colorItem + + property color color + property bool colorIsValid: false + + envName: qsTr("Color") + envStr: "Color" + checked: false + + Component.onCompleted: update() + onColorIsValidChanged: updatePopupOriginalColor() + + onClicked: { + colorItem.updatePopupOriginalColor() + colorPopup.open(colorItem) + } + + onColorChanged: { + colorItem.envStr = colorItem.checked + ? "Color=" + color.toString() + : "Color" + colorItem.commit() + } + + function updatePopupOriginalColor() { + if (colorItem.colorIsValid) + colorPopup.originalColor = colorItem.color + } + + function update() { + colorItem.checked = envMenu.previewEnvName === "Color" + if (colorItem.checked && envMenu.previewEnvValue) { + colorItem.color = envMenu.previewEnvValue + colorItem.colorIsValid = true + } else { + colorItem.colorIsValid = false + } + } + + Connections { + target: envMenu + function onEnvParametersChanged() { + colorItem.update(); } - checkable: true - checked: root.previewEnv === envStr } } + + EnvMenuItem { + envName: qsTr("Studio") + envStr: "SkyBox=preview_studio" + } + + EnvMenuItem { + envName: qsTr("Landscape") + envStr: "SkyBox=preview_landscape" + } + } + + ColorEditorPopup { + id: colorPopup + + currentColor: colorItem.color + onActivateColor: (color) => colorItem.color = color + } + + component EnvMenuItem: StudioControls.MenuItemWithIcon { + required property string envName + property string envStr + + function commit() { + root.previewEnv = envStr + } + + text: envName + onClicked: commit() + checkable: false + checked: root.previewEnv === envStr } } diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index cfbf0aaf41e..d3df9bdece1 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -469,40 +469,15 @@ void MaterialEditorView::handlePreviewEnvChanged(const QString &envAndValue) }; if (env == "Color") { - m_colorDialog.clear(); - - // Store color to separate property to persist selection over non-color env changes auto oldColorPropVal = rootModelNode().auxiliaryData(materialPreviewColorDocProperty); - auto oldEnvPropVal = rootModelNode().auxiliaryData(materialPreviewEnvDocProperty); - auto oldValuePropVal = rootModelNode().auxiliaryData(materialPreviewEnvValueDocProperty); QString oldColor = oldColorPropVal ? oldColorPropVal->toString() : ""; - QString oldEnv = oldEnvPropVal ? oldEnvPropVal->toString() : ""; - QString oldValue = oldValuePropVal ? oldValuePropVal->toString() : ""; - m_colorDialog = new QColorDialog(Core::ICore::dialogParent()); - m_colorDialog->setModal(true); - m_colorDialog->setAttribute(Qt::WA_DeleteOnClose); - m_colorDialog->setCurrentColor(QColor(oldColor)); - m_colorDialog->show(); - - QObject::connect(m_colorDialog, &QColorDialog::currentColorChanged, - m_colorDialog, [=](const QColor &color) { - renderPreviews(env, color.name()); - }); - - QObject::connect(m_colorDialog, &QColorDialog::colorSelected, - m_colorDialog, [this, renderPreviews, env](const QColor &color) { - renderPreviews(env, color.name()); - rootModelNode().setAuxiliaryData(materialPreviewColorDocProperty, color.name()); - }); - - QObject::connect(m_colorDialog, &QColorDialog::rejected, m_colorDialog, - [this, renderPreviews, oldEnv, oldValue] { - renderPreviews(oldEnv, oldValue); - initPreviewData(); - }); - return; + if (value.isEmpty()) + value = oldColor; + else + rootModelNode().setAuxiliaryData(materialPreviewColorDocProperty, value); } + renderPreviews(env, value); } @@ -677,7 +652,7 @@ void MaterialEditorView::initPreviewData() } }); - if (!envValue.isEmpty() && env != "Color" && env != "Basic") { + if (!envValue.isEmpty() && env != "Basic") { env += '='; env += envValue; } diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h index 8c9247ee784..8f0e98f1f31 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h @@ -139,7 +139,6 @@ private: QSize m_previewSize; QByteArray m_previewRequestId; - QPointer m_colorDialog; QPointer m_itemLibraryInfo; DynamicPropertiesModel *m_dynamicPropertiesModel = nullptr; }; From 0d16b9c9012599332ae9ba6bc9284eb2454108d2 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 15 Aug 2024 14:26:07 +0200 Subject: [PATCH 038/193] QmlDesigner: Use insert_or_assign Since this is used for notifiers, we have to use insert_or_assign. Task-number: QDS-13297 Change-Id: I840afc984cd6ef3028a82da3560932fc1dcab7a9 Reviewed-by: Marco Bubke --- .../designercore/instances/nodeinstance.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp index 2290ce5e0d9..17104f645f5 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp @@ -478,12 +478,12 @@ void NodeInstance::setProperty(PropertyNameView name, const QVariant &value) newValueVar = newValue; } if (update) { - d->propertyValues.emplace(parentPropName, newValueVar); + d->propertyValues.insert_or_assign(parentPropName, newValueVar); return; } } - d->propertyValues.emplace(name, value); + d->propertyValues.insert_or_assign(name, value); } QPixmap NodeInstance::renderPixmap() const @@ -689,7 +689,7 @@ InformationName NodeInstance::setInformationHasAnchor(PropertyNameView sourceAnc { if (auto found = d->hasAnchors.find(sourceAnchorLine); found == d->hasAnchors.end() || found->second != hasAnchor) { - d->hasAnchors.emplace_hint(found, sourceAnchorLine, hasAnchor); + d->hasAnchors.insert_or_assign(found, sourceAnchorLine, hasAnchor); return HasAnchor; } @@ -704,7 +704,7 @@ InformationName NodeInstance::setInformationAnchor(PropertyNameView sourceAnchor targetInstanceId); if (auto found = d->anchors.find(sourceAnchorLine); found == d->anchors.end() || found->second != anchorPair) { - d->anchors.emplace_hint(found, sourceAnchorLine, anchorPair); + d->anchors.insert_or_assign(found, sourceAnchorLine, anchorPair); return Anchor; } @@ -716,7 +716,7 @@ InformationName NodeInstance::setInformationInstanceTypeForProperty(PropertyName { if (auto found = d->instanceTypes.find(property); found == d->instanceTypes.end() || found->second != type) { - d->instanceTypes.emplace_hint(found, property, type); + d->instanceTypes.insert_or_assign(found, property, type); return InstanceTypeForProperty; } @@ -728,7 +728,7 @@ InformationName NodeInstance::setInformationHasBindingForProperty(PropertyNameVi { if (auto found = d->hasBindingForProperty.find(property); found == d->hasBindingForProperty.end() || found->second != hasProperty) { - d->hasBindingForProperty.emplace_hint(found, property, hasProperty); + d->hasBindingForProperty.insert_or_assign(found, property, hasProperty); return HasBindingForProperty; } From 33245891b5cfcbca7e267ede6ad427834f68f5ee Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 13 Aug 2024 17:54:54 +0300 Subject: [PATCH 039/193] QmlDesigner: Fix custom notifications to hidden views Hidden views are detached, so custom notifications to those views don't get handled, which in many cases leads to desired outcome not happening. Fixing most cases by simply forcing the handling view visible before emitting custom notification. Fixes: QDS-13349 Change-Id: I65842ac429bcdb1caa4b1f60d4f4fdb4a48f8742 Reviewed-by: Mahmoud Badri Reviewed-by: Marco Bubke --- .../ContentLibrary.qml | 7 ++++ .../assetslibrary/assetslibrarywidget.cpp | 2 + .../componentcore/designeractionmanager.cpp | 3 ++ .../componentcore/modelnodeoperations.cpp | 9 ++++- .../components/componentcore/viewmanager.cpp | 5 +-- .../contentlibrary/contentlibraryview.cpp | 3 ++ .../contentlibrary/contentlibrarywidget.cpp | 5 +++ .../contentlibrary/contentlibrarywidget.h | 13 ++++++ .../qmldesigner/components/createtexture.cpp | 24 ++++++----- .../edit3d/edit3dmaterialsaction.cpp | 1 + .../components/edit3d/edit3dview.cpp | 40 ++++++++++--------- .../components/edit3d/edit3dwidget.cpp | 4 ++ .../itemlibrary/itemlibraryassetimporter.cpp | 1 + .../materialbrowser/materialbrowserview.cpp | 38 ++++++++++++------ .../materialbrowser/materialbrowserview.h | 1 + .../materialbrowser/materialbrowserwidget.cpp | 26 +++++++----- .../materialeditor/materialeditorview.cpp | 15 +++++-- .../navigator/navigatortreemodel.cpp | 5 ++- .../propertyeditor/propertyeditorvalue.cpp | 1 + .../textureeditor/textureeditorview.cpp | 3 +- .../designercore/include/rewriterview.h | 3 -- .../designercore/rewriter/rewriterview.cpp | 9 ----- 22 files changed, 143 insertions(+), 75 deletions(-) diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml index d7f3d80698d..e72ffd9471d 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml @@ -75,6 +75,13 @@ Item { root.numColumns = numColumns } + Connections { + target: ContentLibraryBackend.rootView + function onRequestTab(tabIndex) { + tabBar.currIndex = tabIndex + } + } + Column { id: col anchors.fill: parent diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp index 317b844cca3..3bd8b468407 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -662,6 +663,7 @@ void AssetsLibraryWidget::addResources(const QStringList &files, bool showDialog void AssetsLibraryWidget::addAssetsToContentLibrary(const QStringList &assetPaths) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); m_assetsView->emitCustomNotification("add_assets_to_content_lib", {}, {assetPaths}); } diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index 301940e39ff..8537afb1927 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -8,6 +8,7 @@ #include "designeractionmanagerview.h" #include "designericons.h" #include "designermcumanager.h" +#include "designmodewidget.h" #include "formatoperation.h" #include "groupitemaction.h" #include "modelnodecontextmenu_helper.h" @@ -730,6 +731,7 @@ public: (propertyName + "OpenEditorId").toLatin1(), QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit the Connection")), [=](const SelectionContext &) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ConnectionView"); signalHandler.view() ->emitCustomNotification(EditConnectionNotification, {signalHandler.parentModelNode()}, @@ -811,6 +813,7 @@ public: (signalStr + "OpenEditorId").toLatin1(), QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Add new Connection")), [=](const SelectionContext &) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ConnectionView"); currentNode.view()->emitCustomNotification(AddConnectionNotification, {currentNode}, {signalStr}); diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index d2b94e47b44..1832ca9fdea 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -801,17 +801,20 @@ void moveToComponent(const SelectionContext &selectionContext) void add3DAssetToContentLibrary(const SelectionContext &selectionContext) { ModelNode node = selectionContext.currentSingleSelectedNode(); + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); selectionContext.view()->emitCustomNotification("add_3d_to_content_lib", {node}); } void importComponent(const SelectionContext &selectionContext) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); selectionContext.view()->emitCustomNotification("import_bundle_to_project"); } void exportComponent(const SelectionContext &selectionContext) { ModelNode node = selectionContext.currentSingleSelectedNode(); + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); selectionContext.view()->emitCustomNotification("export_item_as_bundle", {node}); } @@ -857,7 +860,8 @@ void editMaterial(const SelectionContext &selectionContext) } if (material.isValid()) { - QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor"); + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor", true); // to MaterialBrowser... view->emitCustomNotification("select_material", {material}); @@ -1676,6 +1680,7 @@ void openSignalDialog(const SelectionContext &selectionContext) void updateImported3DAsset(const SelectionContext &selectionContext) { if (selectionContext.view()) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("Components"); selectionContext.view()->emitCustomNotification( "UpdateImported3DAsset", {selectionContext.currentSingleSelectedNode()}); } @@ -2016,6 +2021,7 @@ bool dropAsImage3dTexture(const ModelNode &targetNode, QTimer::singleShot(0, view, [targetNode, imagePath, view]() { if (view && targetNode.isValid()) { // To MaterialBrowserView. Done async to avoid custom notification in transaction + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); view->emitCustomNotification("apply_asset_to_model3D", {targetNode}, {DocumentManager::currentFilePath() @@ -2069,6 +2075,7 @@ void handleTextureDrop(const QMimeData *mimeData, const ModelNode &targetModelNo QTC_ASSERT(texNode.isValid(), return ); if (targetNode.modelNode().metaInfo().isQtQuick3DModel()) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); view->emitCustomNotification("apply_texture_to_model3D", {targetNode, texNode}); } else { auto *dialog = ChooseFromPropertyListDialog::createIfNeeded(targetNode, diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp index 94b7b7e6acd..77a82be6892 100644 --- a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp @@ -119,10 +119,9 @@ ViewManager::ViewManager(AsynchronousImageCache &imageCache, : d(std::make_unique(imageCache, externalDependencies)) { d->formEditorView.setGotoErrorCallback([this](int line, int column) { + if (Internal::DesignModeWidget *w = QmlDesignerPlugin::instance()->mainWidget()) + w->showDockWidget("TextEditor"); d->textEditorView.gotoCursorPosition(line, column); - if (Internal::DesignModeWidget *designModeWidget = QmlDesignerPlugin::instance() - ->mainWidget()) - designModeWidget->showDockWidget("TextEditor"); }); registerViewActions(); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index b0f1108ae19..f39535a43e8 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -386,13 +386,16 @@ void ContentLibraryView::customNotification(const AbstractView *view, QTC_ASSERT(nodeList.size() == 1 && data.size() == 1, return); addLibItem(nodeList.first(), data.first().value()); + m_widget->showTab(ContentLibraryWidget::TabIndex::UserAssetsTab); } else if (identifier == "add_assets_to_content_lib") { addLibAssets(data.first().toStringList()); + m_widget->showTab(ContentLibraryWidget::TabIndex::UserAssetsTab); } else if (identifier == "add_3d_to_content_lib") { if (nodeList.first().isComponent()) addLib3DComponent(nodeList.first()); else addLibItem(nodeList.first()); + m_widget->showTab(ContentLibraryWidget::TabIndex::UserAssetsTab); } else if (identifier == "export_item_as_bundle") { // TODO: support exporting 2D items if (nodeList.first().isComponent()) diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp index 52672b5c56d..3a7de7001d0 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp @@ -221,6 +221,11 @@ ContentLibraryIconProvider *ContentLibraryWidget::iconProvider() const return m_iconProvider.get(); } +void ContentLibraryWidget::showTab(TabIndex tabIndex) +{ + emit requestTab(int(tabIndex)); +} + void ContentLibraryWidget::updateImportedState(const QString &bundleId) { if (!m_importer) diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h index cec47c8917f..545923316fc 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h @@ -47,6 +47,16 @@ class ContentLibraryWidget : public QFrame Q_PROPERTY(bool isDragging MEMBER m_isDragging NOTIFY isDraggingChanged) public: + + enum class TabIndex { + MaterialsTab, + TexturesTab, + EnvironmentsTab, + EffectsTab, + UserAssetsTab + }; + Q_ENUM(TabIndex) + ContentLibraryWidget(); ~ContentLibraryWidget(); @@ -97,6 +107,8 @@ public: ContentLibraryBundleImporter *importer() const; ContentLibraryIconProvider *iconProvider() const; + void showTab(TabIndex tabIndex); + signals: void bundleItemDragStarted(QmlDesigner::ContentLibraryItem *item); void bundleMaterialDragStarted(QmlDesigner::ContentLibraryMaterial *bundleMat); @@ -111,6 +123,7 @@ signals: void importerRunningChanged(); void hasModelSelectionChanged(); void importBundle(); + void requestTab(int tabIndex); protected: bool eventFilter(QObject *obj, QEvent *event) override; diff --git a/src/plugins/qmldesigner/components/createtexture.cpp b/src/plugins/qmldesigner/components/createtexture.cpp index c6cbe64e5df..0e0882d0a50 100644 --- a/src/plugins/qmldesigner/components/createtexture.cpp +++ b/src/plugins/qmldesigner/components/createtexture.cpp @@ -3,15 +3,17 @@ #include "createtexture.h" -#include "abstractview.h" -#include "asset.h" -#include "documentmanager.h" -#include "modelnode.h" -#include "modelnodeoperations.h" -#include "nodelistproperty.h" -#include "nodemetainfo.h" -#include "qmlobjectnode.h" -#include "variantproperty.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -109,8 +111,10 @@ ModelNode CreateTexture::execute(const QString &filePath, AddTextureMode mode, i assignTextureAsLightProbe(texture, sceneId); QTimer::singleShot(0, m_view, [this, texture]() { - if (m_view->model()) + if (m_view->model()) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); m_view->emitCustomNotification("select_texture", {texture}, {true}); + } }); return texture; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dmaterialsaction.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dmaterialsaction.cpp index 970791b2db6..143282c77f7 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dmaterialsaction.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dmaterialsaction.cpp @@ -180,6 +180,7 @@ QAction *Edit3DMaterialsAction::createMaterialAction(const ModelNode &material, QAction *editMaterialAction = new QAction(tr("Edit"), menu); connect(editMaterialAction, &QAction::triggered, menu, [material] { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor", true); if (auto materialView = material.view()) materialView->emitCustomNotification("select_material", {material}); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index ef6620ba54d..b971d828c50 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -6,29 +6,30 @@ #include "backgroundcolorselection.h" #include "bakelights.h" #include "cameraspeedconfiguration.h" -#include "designeractionmanager.h" -#include "designericons.h" -#include "designersettings.h" -#include "designmodecontext.h" #include "edit3dcanvas.h" #include "edit3dviewconfig.h" #include "edit3dwidget.h" -#include "materialutils.h" -#include "metainfo.h" -#include "nodeabstractproperty.h" -#include "nodehints.h" -#include "nodeinstanceview.h" -#include "qmldesignerconstants.h" -#include "qmldesignerplugin.h" -#include "qmlitemnode.h" -#include "qmlvisualnode.h" -#include "seekerslider.h" #include "snapconfiguration.h" -#include "variantproperty.h" #include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include #include #include @@ -435,9 +436,7 @@ void Edit3DView::customNotification([[maybe_unused]] const AbstractView *view, [[maybe_unused]] const QList &nodeList, [[maybe_unused]] const QList &data) { - if (identifier == "asset_import_update") { - resetPuppet(); - } else if (identifier == "pick_3d_node_from_2d_scene" && data.size() == 1 && nodeList.size() == 1) { + if (identifier == "pick_3d_node_from_2d_scene" && data.size() == 1 && nodeList.size() == 1) { // Pick via 2D view, data has pick coordinates in main scene coordinates QTimer::singleShot(0, this, [=, self = QPointer{this}]() { if (!self) @@ -491,11 +490,14 @@ void Edit3DView::nodeAtPosReady(const ModelNode &modelNode, const QVector3D &pos } else if (m_nodeAtPosReqType == NodeAtPosReqType::BundleEffectDrop) { emitCustomNotification("drop_bundle_item", {modelNode}, {pos3d}); // To ContentLibraryView } else if (m_nodeAtPosReqType == NodeAtPosReqType::TextureDrop) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); emitCustomNotification("apply_texture_to_model3D", {modelNode, m_droppedModelNode}); } else if (m_nodeAtPosReqType == NodeAtPosReqType::AssetDrop) { bool isModel = modelNode.metaInfo().isQtQuick3DModel(); - if (!m_droppedFile.isEmpty() && isModel) + if (!m_droppedFile.isEmpty() && isModel) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); emitCustomNotification("apply_asset_to_model3D", {modelNode}, {m_droppedFile}); // To MaterialBrowserView + } } else if (m_nodeAtPosReqType == NodeAtPosReqType::MainScenePick) { if (modelNode.isValid()) setSelectedModelNode(modelNode); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index ad9b8d6b125..c4a8de2a962 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -363,18 +364,21 @@ void Edit3DWidget::createContextMenu() m_addToContentLibAction = m_contextMenu->addAction( contextIcon(DesignerIcons::CreateIcon), // TODO: placeholder icon tr("Add to Content Library"), [&] { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); view()->emitCustomNotification("add_3d_to_content_lib", {m_contextMenuTarget}); // To ContentLibrary }); m_importBundleAction = m_contextMenu->addAction( contextIcon(DesignerIcons::CreateIcon), // TODO: placeholder icon tr("Import Component"), [&] { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); view()->emitCustomNotification("import_bundle_to_project"); // To ContentLibrary }); m_exportBundleAction = m_contextMenu->addAction( contextIcon(DesignerIcons::CreateIcon), // TODO: placeholder icon tr("Export Component"), [&] { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); view()->emitCustomNotification("export_item_as_bundle", {m_contextMenuTarget}); // To ContentLibrary }); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp index 5c14c46d183..44d451b94e7 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp @@ -747,6 +747,7 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport() } else if (counter >= 50) { for (const ParseData &pd : std::as_const(m_parseData)) { if (!pd.overwrittenImports.isEmpty()) { + model->rewriterView()->resetPuppet(); model->rewriterView()->emitCustomNotification("asset_import_update"); break; } diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index fa3a385fb12..4f62a2c8026 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -3,19 +3,22 @@ #include "materialbrowserview.h" -#include "bindingproperty.h" -#include "createtexture.h" -#include "designmodecontext.h" -#include "externaldependenciesinterface.h" #include "materialbrowsermodel.h" #include "materialbrowsertexturesmodel.h" #include "materialbrowserwidget.h" -#include "nodeabstractproperty.h" -#include "nodeinstanceview.h" -#include "nodemetainfo.h" -#include "qmldesignerconstants.h" -#include "qmlobjectnode.h" -#include "variantproperty.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -75,20 +78,24 @@ WidgetInfo MaterialBrowserView::widgetInfo() connect(matBrowserModel, &MaterialBrowserModel::applyToSelectedTriggered, this, [&] (const ModelNode &material, bool add) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor"); emitCustomNotification("apply_to_selected_triggered", {material}, {add}); }); connect(matBrowserModel, &MaterialBrowserModel::renameMaterialTriggered, this, [&] (const ModelNode &material, const QString &newName) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor"); emitCustomNotification("rename_material", {material}, {newName}); }); connect(matBrowserModel, &MaterialBrowserModel::addNewMaterialTriggered, this, [&] { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor"); emitCustomNotification("add_new_material"); }); connect(matBrowserModel, &MaterialBrowserModel::duplicateMaterialTriggered, this, [&] (const ModelNode &material) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor"); emitCustomNotification("duplicate_material", {material}); }); @@ -170,6 +177,7 @@ WidgetInfo MaterialBrowserView::widgetInfo() }); connect(texturesModel, &MaterialBrowserTexturesModel::duplicateTextureTriggered, this, [&] (const ModelNode &texture) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("TextureEditor"); emitCustomNotification("duplicate_texture", {texture}); }); @@ -189,6 +197,7 @@ WidgetInfo MaterialBrowserView::widgetInfo() }); connect(texturesModel, &MaterialBrowserTexturesModel::addNewTextureTriggered, this, [&] { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("TextureEditor"); emitCustomNotification("add_new_texture"); }); @@ -235,6 +244,7 @@ void MaterialBrowserView::modelAttached(Model *model) { AbstractView::modelAttached(model); + m_pendingTextureSelection = {}; m_widget->clearSearchFilter(); m_widget->materialBrowserModel()->setHasMaterialLibrary(false); m_hasQuick3DImport = model->hasImport("QtQuick3D"); @@ -245,6 +255,10 @@ void MaterialBrowserView::modelAttached(Model *model) QTimer::singleShot(1000, model, [this] { refreshModel(true); loadPropertyGroups(); // Needs the delay because it uses metaInfo + + if (m_pendingTextureSelection.isValid()) + emitCustomNotification("select_texture", {m_pendingTextureSelection}, {true}); + m_pendingTextureSelection = {}; }); m_sceneId = Utils3D::active3DSceneId(model); @@ -559,6 +573,8 @@ void MaterialBrowserView::customNotification(const AbstractView *view, m_widget->materialBrowserTexturesModel()->refreshSearch(); if (!data.isEmpty() && data[0].toBool()) m_widget->focusMaterialSection(false); + } else { + m_pendingTextureSelection = nodeList.first(); } } else if (identifier == "refresh_material_browser") { QTimer::singleShot(0, model(), [this] { @@ -571,8 +587,6 @@ void MaterialBrowserView::customNotification(const AbstractView *view, applyTextureToModel3D(nodeList.at(0)); } else if (identifier == "apply_texture_to_model3D") { applyTextureToModel3D(nodeList.at(0), nodeList.at(1)); - } else if (identifier == "apply_texture_to_material") { - applyTextureToMaterial({nodeList.at(0)}, nodeList.at(1)); } else if (identifier == "focus_material_section") { m_widget->focusMaterialSection(true); } diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h index b6470ee1617..a2582fe0ac7 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h @@ -101,6 +101,7 @@ private: QString m_appliedTextureId; QString m_appliedTexturePath; // defers texture creation until dialog apply int m_sceneId = -1; + ModelNode m_pendingTextureSelection; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp index dd442e3ccc2..f9f5636a295 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp @@ -3,23 +3,24 @@ #include "materialbrowserwidget.h" -#include "asset.h" -#include "assetimageprovider.h" -#include "createtexture.h" -#include "documentmanager.h" -#include "hdrimage.h" #include "materialbrowsermodel.h" #include "materialbrowsertexturesmodel.h" #include "materialbrowserview.h" -#include "qmldesignerconstants.h" -#include "qmldesignerplugin.h" -#include "theme.h" -#include "variantproperty.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include - #include #include #include @@ -371,6 +372,7 @@ void MaterialBrowserWidget::focusMaterialSection(bool focusMatSec) void MaterialBrowserWidget::addMaterialToContentLibrary() { ModelNode mat = m_materialBrowserModel->selectedMaterial(); + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); m_materialBrowserView->emitCustomNotification("add_material_to_content_lib", {mat}, {m_previewImageProvider->getPixmap(mat)}); // to ContentLibrary } @@ -378,11 +380,13 @@ void MaterialBrowserWidget::addMaterialToContentLibrary() void MaterialBrowserWidget::importMaterial() { ModelNode mat = m_materialBrowserModel->selectedMaterial(); + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); m_materialBrowserView->emitCustomNotification("import_bundle_to_project"); // to ContentLibrary } void MaterialBrowserWidget::exportMaterial() { ModelNode mat = m_materialBrowserModel->selectedMaterial(); + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); m_materialBrowserView->emitCustomNotification("export_material_as_bundle", {mat}, {m_previewImageProvider->getPixmap(mat)}); // to ContentLibrary } diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index d3df9bdece1..e05acb7646d 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -715,6 +715,8 @@ void MaterialEditorView::modelAttached(Model *model) } resetView(); + selectedNodesChanged(selectedModelNodes(), {}); + m_locked = false; } @@ -1056,17 +1058,22 @@ void MaterialEditorView::customNotification([[maybe_unused]] const AbstractView const QList &nodeList, const QList &data) { - if (identifier == "selected_material_changed") { - if (!m_hasMaterialRoot) { + auto changeSelected = [&]() { + if (!m_hasMaterialRoot && m_selectedMaterial != nodeList.first()) { m_selectedMaterial = nodeList.first(); m_dynamicPropertiesModel->setSelectedNode(m_selectedMaterial); QTimer::singleShot(0, this, &MaterialEditorView::resetView); } + }; + + if (identifier == "selected_material_changed") { + changeSelected(); } else if (identifier == "apply_to_selected_triggered") { + changeSelected(); applyMaterialToSelectedModels(nodeList.first(), data.first().toBool()); } else if (identifier == "rename_material") { - if (m_selectedMaterial == nodeList.first()) - renameMaterial(m_selectedMaterial, data.first().toString()); + changeSelected(); + renameMaterial(m_selectedMaterial, data.first().toString()); } else if (identifier == "add_new_material") { handleToolBarAction(MaterialEditorContextObject::AddNewMaterial); } else if (identifier == "duplicate_material") { diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 9ed9f24e42d..658ba0c50a2 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -565,8 +566,10 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData, ModelNodeOperations::handleMaterialDrop(mimeData, targetNode); } else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_TEXTURE)) { QByteArray filePath = mimeData->data(Constants::MIME_TYPE_BUNDLE_TEXTURE); - if (targetNode.metaInfo().isQtQuick3DModel()) + if (targetNode.metaInfo().isQtQuick3DModel()) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); m_view->emitCustomNotification("apply_asset_to_model3D", {targetNode}, {filePath}); // To MaterialBrowserView + } } else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)) { if (targetNode.isValid()) m_view->emitCustomNotification("drop_bundle_material", {targetNode}); // To ContentLibraryView diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp index 252f8c2a9ff..3c2fa6a32e9 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp @@ -535,6 +535,7 @@ void PropertyEditorValue::commitDrop(const QString &dropData) void PropertyEditorValue::openMaterialEditor(int idx) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor", true); m_modelNode.view()->emitCustomNotification("select_material", {}, {idx}); } diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp index eae0a7ff56c..c3e84a5fea8 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp @@ -364,6 +364,7 @@ void TextureEditorView::applyTextureToSelectedModel(const ModelNode &texture) QTC_ASSERT(texture.isValid(), return); + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); emitCustomNotification("apply_texture_to_model3D", {m_selectedModel, m_selectedTexture}); } @@ -837,8 +838,6 @@ void TextureEditorView::customNotification([[maybe_unused]] const AbstractView * m_dynamicPropertiesModel->setSelectedNode(m_selectedTexture); QTimer::singleShot(0, this, &TextureEditorView::resetView); } - } else if (identifier == "apply_texture_to_selected_model") { - applyTextureToSelectedModel(nodeList.first()); } else if (identifier == "add_new_texture") { handleToolBarAction(TextureEditorContextObject::AddNewTexture); } else if (identifier == "duplicate_texture") { diff --git a/src/plugins/qmldesigner/designercore/include/rewriterview.h b/src/plugins/qmldesigner/designercore/include/rewriterview.h index 46e67116634..fdc61916ce8 100644 --- a/src/plugins/qmldesigner/designercore/include/rewriterview.h +++ b/src/plugins/qmldesigner/designercore/include/rewriterview.h @@ -77,9 +77,6 @@ public: void nodeOrderChanged(const NodeListProperty &listProperty) override; void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion) override; void nodeTypeChanged(const ModelNode& node, const TypeName &type, int majorVersion, int minorVersion) override; - void customNotification(const AbstractView *view, const QString &identifier, - const QList &nodeList, - const QList &data) override; void rewriterBeginTransaction() override; void rewriterEndTransaction() override; diff --git a/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp b/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp index 6565208385c..48d8e9fb15f 100644 --- a/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp +++ b/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp @@ -385,15 +385,6 @@ void RewriterView::nodeTypeChanged(const ModelNode &node, applyChanges(); } -void RewriterView::customNotification(const AbstractView * /*view*/, - const QString &identifier, - const QList & /* nodeList */, - const QList & /*data */) -{ - if (identifier == StartRewriterAmend || identifier == EndRewriterAmend) - return; // we emitted this ourselves, so just ignore these notifications. -} - void RewriterView::rewriterBeginTransaction() { transactionLevel++; From e8e6b0c53c0130dab51930c50f77b37ec61d7350 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 13 Aug 2024 12:02:07 +0200 Subject: [PATCH 040/193] ADS: Fix undocking widget An undocked widget got disabled. That is a little bit surpising. Task-number: QDS-13346 Change-Id: I154a5e11f0a88364fd24718dc82767dcfb5a466b Reviewed-by: Miikka Heikkinen Reviewed-by: Thomas Hartmann --- src/libs/advanceddockingsystem/dockwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/advanceddockingsystem/dockwidget.cpp b/src/libs/advanceddockingsystem/dockwidget.cpp index aa240fdd587..faa749c9aef 100644 --- a/src/libs/advanceddockingsystem/dockwidget.cpp +++ b/src/libs/advanceddockingsystem/dockwidget.cpp @@ -624,7 +624,7 @@ void DockWidget::toggleViewInternal(bool open) void DockWidget::setDockArea(DockAreaWidget *dockArea) { d->m_dockArea = dockArea; - d->m_toggleViewAction->setChecked(dockArea != nullptr && !isClosed()); + d->m_toggleViewAction->setChecked(!isClosed()); setParent(dockArea); } From 72858a073922b22b582bbd38761697f844417d45 Mon Sep 17 00:00:00 2001 From: Shrief Gabr Date: Fri, 9 Aug 2024 16:29:51 +0300 Subject: [PATCH 041/193] QmlDesigner: Modify ICore::askForRestart() to return bool * Also accepts an additional string to customize the secondary button Change-Id: I37c45bf0fceff7c5478d1b88598f33a3a4fb0c0d Reviewed-by: Thomas Hartmann --- src/plugins/coreplugin/icore.cpp | 11 +++++++++-- src/plugins/coreplugin/icore.h | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index 09a36cbf76d..2fbc28d94a5 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -226,6 +226,8 @@ const char windowStateKey[] = "WindowState"; const char modeSelectorLayoutKey[] = "ModeSelectorLayout"; const char menubarVisibleKey[] = "MenubarVisible"; +const char DEFAULT_ALT_BUTTON_TEXT[] = QT_TRANSLATE_NOOP("QtC::Core", "Later"); + namespace Internal { class MainWindow : public AppMainWindow @@ -909,17 +911,22 @@ Utils::InfoBar *ICore::infoBar() Uses \a text as the main text in the dialog, and triggers a restart of \QC if the user chooses that option. */ -void ICore::askForRestart(const QString &text) +bool ICore::askForRestart(const QString &text, const QString &altButtonText) { QMessageBox mb(dialogParent()); mb.setWindowTitle(Tr::tr("Restart Required")); mb.setText(text); mb.setIcon(QMessageBox::Information); - mb.addButton(Tr::tr("Later"), QMessageBox::NoRole); + + QString translatedAltButtonText = altButtonText.isEmpty() ? Tr::tr(DEFAULT_ALT_BUTTON_TEXT) : altButtonText; + + mb.addButton(translatedAltButtonText, QMessageBox::NoRole); mb.addButton(Tr::tr("Restart Now"), QMessageBox::YesRole); mb.connect(&mb, &QDialog::accepted, ICore::instance(), &ICore::restart, Qt::QueuedConnection); mb.exec(); + + return mb.buttonRole(mb.clickedButton()) == QMessageBox::YesRole; } /*! diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h index 74a59e8c808..5c829fbaf05 100644 --- a/src/plugins/coreplugin/icore.h +++ b/src/plugins/coreplugin/icore.h @@ -82,7 +82,7 @@ public: static QWidget *dialogParent(); static Utils::InfoBar *infoBar(); - static void askForRestart(const QString &text); + static bool askForRestart(const QString &text, const QString &altButtonText = {}); static void raiseWindow(QWidget *widget); static void raiseMainWindow(); From 7cf92c7814b5497801f5afe81752b8b2cf398ec5 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 15 Aug 2024 16:57:51 +0200 Subject: [PATCH 042/193] QmlDesigner: Fix possible "memory leak" Actually it cannot leak because it has the lifetime of the node. But it can lead to strange behaviour. Change-Id: I4fba73e26120d0f20ef8ebd1a5533c83020675a5 Reviewed-by: Thomas Hartmann --- .../qmldesigner/designercore/model/internalnode_p.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/model/internalnode_p.h b/src/plugins/qmldesigner/designercore/model/internalnode_p.h index 9e3a32ef7f6..4129ff98a07 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnode_p.h +++ b/src/plugins/qmldesigner/designercore/model/internalnode_p.h @@ -146,11 +146,13 @@ public: template Type *addProperty(PropertyNameView name) { - auto newProperty = std::make_shared(name, shared_from_this()); - auto pointer = newProperty.get(); - m_nameProperties.try_emplace(name, std::move(newProperty)); + auto [iter, inserted] = m_nameProperties.try_emplace( + name, std::make_shared(name, shared_from_this())); - return pointer; + if (inserted) + return static_cast(iter->second.get()); + + return nullptr; } auto addBindingProperty(PropertyNameView name) From 4ba6cf43ee2f6554bd502cb2d53e8888a3b5776f Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Tue, 6 Aug 2024 11:44:31 +0300 Subject: [PATCH 043/193] Doc: Fix reference to qml translation methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QDS-13319 Change-Id: I7da77b4382145441e60d37e60c7c79c83c785eaa Reviewed-by: Teea Põldsam Reviewed-by: Thomas Hartmann --- doc/qtcreator/src/qtquick/qtquick-ui-forms.qdoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/qtcreator/src/qtquick/qtquick-ui-forms.qdoc b/doc/qtcreator/src/qtquick/qtquick-ui-forms.qdoc index 7ff6d416d02..13317a7336e 100644 --- a/doc/qtcreator/src/qtquick/qtquick-ui-forms.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-ui-forms.qdoc @@ -144,10 +144,10 @@ \list \li \l{Qt::}{qsTr()} \li \l{Qt::}{qsTranslate()} - \li \l{Qt::}{qsTranslateNoOp()} + \li \l{Qt::}{QT_TRANSLATE_NOOP()} \li \l{Qt::}{qsTrId()} - \li \l{Qt::}{qsTrIdNoOp()} - \li \l{Qt::}{qsTrNoOp()} + \li \l{Qt::}{QT_TRID_NOOP()} + \li \l{Qt::}{QT_TR_NOOP()} \endlist \note Do not mix translation methods in a UI file. From 8e8754407f77be421a302c756b9fdf35d171b43a Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 16 Aug 2024 12:46:44 +0300 Subject: [PATCH 044/193] Refactor things that do not belong to item library out of there Item library view can be detached, which can cause 3D asset type registrations and some other critical things not happen. Moving relevant functionality to ComponentView which is always there. Fixes: QDS-13390 Change-Id: I82391a7f2be8f95b1e01895b3e6c512ceb61cab5 Reviewed-by: Mahmoud Badri --- src/plugins/qmldesigner/CMakeLists.txt | 28 ++-- .../componentcore/modelnodeoperations.cpp | 1 - .../assetimportupdatedialog.cpp | 2 +- .../assetimportupdatedialog.h | 2 +- .../assetimportupdatedialog.ui | 0 .../assetimportupdatetreeitem.cpp | 2 +- .../assetimportupdatetreeitem.h | 2 +- .../assetimportupdatetreeitemdelegate.cpp | 2 +- .../assetimportupdatetreeitemdelegate.h | 2 +- .../assetimportupdatetreemodel.cpp | 2 +- .../assetimportupdatetreemodel.h | 2 +- .../assetimportupdatetreeview.cpp | 2 +- .../assetimportupdatetreeview.h | 2 +- .../import3dcanvas.cpp | 0 .../import3dcanvas.h | 0 .../import3dconnectionmanager.cpp | 0 .../import3dconnectionmanager.h | 0 .../import3ddialog.cpp} | 144 +++++++++--------- .../import3ddialog.h} | 34 ++--- .../import3ddialog.ui} | 4 +- .../import3dimporter.cpp} | 87 +++++------ .../import3dimporter.h} | 9 +- .../components/integration/componentview.cpp | 116 +++++++++++++- .../components/integration/componentview.h | 7 + .../itemlibrary/itemlibraryview.cpp | 101 +----------- .../components/itemlibrary/itemlibraryview.h | 3 - 26 files changed, 289 insertions(+), 265 deletions(-) rename src/plugins/qmldesigner/components/{itemlibrary => import3d}/assetimportupdatedialog.cpp (98%) rename src/plugins/qmldesigner/components/{itemlibrary => import3d}/assetimportupdatedialog.h (95%) rename src/plugins/qmldesigner/components/{itemlibrary => import3d}/assetimportupdatedialog.ui (100%) rename src/plugins/qmldesigner/components/{itemlibrary => import3d}/assetimportupdatetreeitem.cpp (97%) rename src/plugins/qmldesigner/components/{itemlibrary => import3d}/assetimportupdatetreeitem.h (96%) rename src/plugins/qmldesigner/components/{itemlibrary => import3d}/assetimportupdatetreeitemdelegate.cpp (98%) rename src/plugins/qmldesigner/components/{itemlibrary => import3d}/assetimportupdatetreeitemdelegate.h (96%) rename src/plugins/qmldesigner/components/{itemlibrary => import3d}/assetimportupdatetreemodel.cpp (99%) rename src/plugins/qmldesigner/components/{itemlibrary => import3d}/assetimportupdatetreemodel.h (97%) rename src/plugins/qmldesigner/components/{itemlibrary => import3d}/assetimportupdatetreeview.cpp (95%) rename src/plugins/qmldesigner/components/{itemlibrary => import3d}/assetimportupdatetreeview.h (93%) rename src/plugins/qmldesigner/components/{itemlibrary => import3d}/import3dcanvas.cpp (100%) rename src/plugins/qmldesigner/components/{itemlibrary => import3d}/import3dcanvas.h (100%) rename src/plugins/qmldesigner/components/{itemlibrary => import3d}/import3dconnectionmanager.cpp (100%) rename src/plugins/qmldesigner/components/{itemlibrary => import3d}/import3dconnectionmanager.h (100%) rename src/plugins/qmldesigner/components/{itemlibrary/itemlibraryassetimportdialog.cpp => import3d/import3ddialog.cpp} (91%) rename src/plugins/qmldesigner/components/{itemlibrary/itemlibraryassetimportdialog.h => import3d/import3ddialog.h} (77%) rename src/plugins/qmldesigner/components/{itemlibrary/itemlibraryassetimportdialog.ui => import3d/import3ddialog.ui} (97%) rename src/plugins/qmldesigner/components/{itemlibrary/itemlibraryassetimporter.cpp => import3d/import3dimporter.cpp} (89%) rename src/plugins/qmldesigner/components/{itemlibrary/itemlibraryassetimporter.h => import3d/import3dimporter.h} (95%) diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index fe3a5d00f97..caeefbb92d9 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -518,6 +518,7 @@ add_qtc_plugin(QmlDesigner $<$:QTC_USE_QML_DESIGNER_LITE> INCLUDES ${CMAKE_CURRENT_LIST_DIR}/components + ${CMAKE_CURRENT_LIST_DIR}/components/import3d ${CMAKE_CURRENT_LIST_DIR}/components/assetslibrary ${CMAKE_CURRENT_LIST_DIR}/components/debugview ${CMAKE_CURRENT_LIST_DIR}/components/edit3d @@ -758,14 +759,6 @@ extend_qtc_plugin(QmlDesigner extend_qtc_plugin(QmlDesigner SOURCES_PREFIX components/itemlibrary SOURCES - assetimportupdatedialog.cpp assetimportupdatedialog.h - assetimportupdatedialog.ui - assetimportupdatetreeitem.cpp assetimportupdatetreeitem.h - assetimportupdatetreeitemdelegate.cpp assetimportupdatetreeitemdelegate.h - assetimportupdatetreemodel.cpp assetimportupdatetreemodel.h - assetimportupdatetreeview.cpp assetimportupdatetreeview.h - import3dcanvas.cpp import3dcanvas.h - import3dconnectionmanager.cpp import3dconnectionmanager.h itemlibrary.qrc itemlibraryconstants.h itemlibraryimageprovider.cpp itemlibraryimageprovider.h @@ -775,15 +768,28 @@ extend_qtc_plugin(QmlDesigner itemlibraryitemsmodel.cpp itemlibraryitemsmodel.h itemlibraryview.cpp itemlibraryview.h itemlibrarywidget.cpp itemlibrarywidget.h - itemlibraryassetimportdialog.cpp itemlibraryassetimportdialog.h - itemlibraryassetimportdialog.ui - itemlibraryassetimporter.cpp itemlibraryassetimporter.h itemlibraryiconimageprovider.cpp itemlibraryiconimageprovider.h itemlibraryimport.cpp itemlibraryimport.h itemlibrarycategoriesmodel.cpp itemlibrarycategoriesmodel.h itemlibraryaddimportmodel.cpp itemlibraryaddimportmodel.h ) +extend_qtc_plugin(QmlDesigner + SOURCES_PREFIX components/import3d + SOURCES + assetimportupdatedialog.cpp assetimportupdatedialog.h + assetimportupdatedialog.ui + assetimportupdatetreeitem.cpp assetimportupdatetreeitem.h + assetimportupdatetreeitemdelegate.cpp assetimportupdatetreeitemdelegate.h + assetimportupdatetreemodel.cpp assetimportupdatetreemodel.h + assetimportupdatetreeview.cpp assetimportupdatetreeview.h + import3dcanvas.cpp import3dcanvas.h + import3dconnectionmanager.cpp import3dconnectionmanager.h + import3ddialog.cpp import3ddialog.h + import3ddialog.ui + import3dimporter.cpp import3dimporter.h +) + extend_qtc_plugin(QmlDesigner SOURCES_PREFIX components/assetslibrary SOURCES diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index 1832ca9fdea..cbe48ff5207 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -1680,7 +1680,6 @@ void openSignalDialog(const SelectionContext &selectionContext) void updateImported3DAsset(const SelectionContext &selectionContext) { if (selectionContext.view()) { - QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("Components"); selectionContext.view()->emitCustomNotification( "UpdateImported3DAsset", {selectionContext.currentSingleSelectedNode()}); } diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.cpp b/src/plugins/qmldesigner/components/import3d/assetimportupdatedialog.cpp similarity index 98% rename from src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.cpp rename to src/plugins/qmldesigner/components/import3d/assetimportupdatedialog.cpp index a85130725c7..fc6279db5aa 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.cpp +++ b/src/plugins/qmldesigner/components/import3d/assetimportupdatedialog.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// 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 "assetimportupdatedialog.h" #include "ui_assetimportupdatedialog.h" diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.h b/src/plugins/qmldesigner/components/import3d/assetimportupdatedialog.h similarity index 95% rename from src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.h rename to src/plugins/qmldesigner/components/import3d/assetimportupdatedialog.h index 18158d50748..00444bed143 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.h +++ b/src/plugins/qmldesigner/components/import3d/assetimportupdatedialog.h @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.ui b/src/plugins/qmldesigner/components/import3d/assetimportupdatedialog.ui similarity index 100% rename from src/plugins/qmldesigner/components/itemlibrary/assetimportupdatedialog.ui rename to src/plugins/qmldesigner/components/import3d/assetimportupdatedialog.ui diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.cpp b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreeitem.cpp similarity index 97% rename from src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.cpp rename to src/plugins/qmldesigner/components/import3d/assetimportupdatetreeitem.cpp index a5d84605dd2..28c61f3ef14 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.cpp +++ b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreeitem.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// 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 "assetimportupdatetreeitem.h" diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.h b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreeitem.h similarity index 96% rename from src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.h rename to src/plugins/qmldesigner/components/import3d/assetimportupdatetreeitem.h index 050624b901f..b1a426d54b6 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitem.h +++ b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreeitem.h @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitemdelegate.cpp b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreeitemdelegate.cpp similarity index 98% rename from src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitemdelegate.cpp rename to src/plugins/qmldesigner/components/import3d/assetimportupdatetreeitemdelegate.cpp index 8e85b61ec23..e4152a97eab 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitemdelegate.cpp +++ b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreeitemdelegate.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// 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 "assetimportupdatetreeitemdelegate.h" diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitemdelegate.h b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreeitemdelegate.h similarity index 96% rename from src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitemdelegate.h rename to src/plugins/qmldesigner/components/import3d/assetimportupdatetreeitemdelegate.h index da6d13861f1..a275c27367a 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeitemdelegate.h +++ b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreeitemdelegate.h @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreemodel.cpp b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreemodel.cpp similarity index 99% rename from src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreemodel.cpp rename to src/plugins/qmldesigner/components/import3d/assetimportupdatetreemodel.cpp index 5b6d1a564bc..505746ddc9f 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreemodel.cpp +++ b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreemodel.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// 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 "assetimportupdatetreemodel.h" diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreemodel.h b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreemodel.h similarity index 97% rename from src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreemodel.h rename to src/plugins/qmldesigner/components/import3d/assetimportupdatetreemodel.h index c69a08930bd..fb787620c0b 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreemodel.h +++ b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreemodel.h @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeview.cpp b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreeview.cpp similarity index 95% rename from src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeview.cpp rename to src/plugins/qmldesigner/components/import3d/assetimportupdatetreeview.cpp index a683ab2b8b3..2baa3c80368 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeview.cpp +++ b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreeview.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// 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 "assetimportupdatetreeview.h" diff --git a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeview.h b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreeview.h similarity index 93% rename from src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeview.h rename to src/plugins/qmldesigner/components/import3d/assetimportupdatetreeview.h index d86c99457d0..fb0a46f5595 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/assetimportupdatetreeview.h +++ b/src/plugins/qmldesigner/components/import3d/assetimportupdatetreeview.h @@ -1,4 +1,4 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once diff --git a/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.cpp b/src/plugins/qmldesigner/components/import3d/import3dcanvas.cpp similarity index 100% rename from src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.cpp rename to src/plugins/qmldesigner/components/import3d/import3dcanvas.cpp diff --git a/src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.h b/src/plugins/qmldesigner/components/import3d/import3dcanvas.h similarity index 100% rename from src/plugins/qmldesigner/components/itemlibrary/import3dcanvas.h rename to src/plugins/qmldesigner/components/import3d/import3dcanvas.h diff --git a/src/plugins/qmldesigner/components/itemlibrary/import3dconnectionmanager.cpp b/src/plugins/qmldesigner/components/import3d/import3dconnectionmanager.cpp similarity index 100% rename from src/plugins/qmldesigner/components/itemlibrary/import3dconnectionmanager.cpp rename to src/plugins/qmldesigner/components/import3d/import3dconnectionmanager.cpp diff --git a/src/plugins/qmldesigner/components/itemlibrary/import3dconnectionmanager.h b/src/plugins/qmldesigner/components/import3d/import3dconnectionmanager.h similarity index 100% rename from src/plugins/qmldesigner/components/itemlibrary/import3dconnectionmanager.h rename to src/plugins/qmldesigner/components/import3d/import3dconnectionmanager.h diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp b/src/plugins/qmldesigner/components/import3d/import3ddialog.cpp similarity index 91% rename from src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp rename to src/plugins/qmldesigner/components/import3d/import3ddialog.cpp index b9252a874f7..27dead7d6d0 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp +++ b/src/plugins/qmldesigner/components/import3d/import3ddialog.cpp @@ -1,8 +1,8 @@ -// Copyright (C) 2019 The Qt Company Ltd. +// 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 "itemlibraryassetimportdialog.h" -#include "ui_itemlibraryassetimportdialog.h" +#include "import3ddialog.h" +#include "ui_import3ddialog.h" #include "import3dcanvas.h" #include "import3dconnectionmanager.h" @@ -90,13 +90,13 @@ constexpr QStringView expandValuesKey{u"expandValueComponents"}; } // namespace -ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog( +Import3dDialog::Import3dDialog( const QStringList &importFiles, const QString &defaulTargetDirectory, const QVariantMap &supportedExts, const QVariantMap &supportedOpts, const QJsonObject &defaultOpts, const QSet &preselectedFilesForOverwrite, AbstractView *view, QWidget *parent) : QDialog(parent) - , ui(new Ui::ItemLibraryAssetImportDialog) + , ui(new Ui::Import3dDialog) , m_view(view) , m_importer(this) , m_preselectedFilesForOverwrite(preselectedFilesForOverwrite) @@ -133,7 +133,7 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog( if (m_quick3DFiles.size() != importFiles.size()) addWarning("Cannot import 3D and other assets simultaneously. Skipping non-3D assets."); - connect(ui->importButton, &QPushButton::clicked, this, &ItemLibraryAssetImportDialog::onImport); + connect(ui->importButton, &QPushButton::clicked, this, &Import3dDialog::onImport); ui->importButton->setDefault(true); @@ -235,38 +235,38 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog( } connect(ui->closeButton, &QPushButton::clicked, - this, &ItemLibraryAssetImportDialog::onClose); + this, &Import3dDialog::onClose); connect(ui->tabWidget, &QTabWidget::currentChanged, - this, &ItemLibraryAssetImportDialog::updateUi); + this, &Import3dDialog::updateUi); connect(canvas(), &Import3dCanvas::requestImageUpdate, - this, &ItemLibraryAssetImportDialog::onRequestImageUpdate); + this, &Import3dDialog::onRequestImageUpdate); connect(canvas(), &Import3dCanvas::requestRotation, - this, &ItemLibraryAssetImportDialog::onRequestRotation); + this, &Import3dDialog::onRequestRotation); - connect(&m_importer, &ItemLibraryAssetImporter::errorReported, - this, &ItemLibraryAssetImportDialog::addError); - connect(&m_importer, &ItemLibraryAssetImporter::warningReported, - this, &ItemLibraryAssetImportDialog::addWarning); - connect(&m_importer, &ItemLibraryAssetImporter::infoReported, - this, &ItemLibraryAssetImportDialog::addInfo); - connect(&m_importer, &ItemLibraryAssetImporter::importNearlyFinished, - this, &ItemLibraryAssetImportDialog::onImportNearlyFinished); - connect(&m_importer, &ItemLibraryAssetImporter::importFinished, - this, &ItemLibraryAssetImportDialog::onImportFinished); - connect(&m_importer, &ItemLibraryAssetImporter::progressChanged, - this, &ItemLibraryAssetImportDialog::setImportProgress); - connect(&m_importer, &ItemLibraryAssetImporter::importReadyForPreview, - this, &ItemLibraryAssetImportDialog::onImportReadyForPreview); + connect(&m_importer, &Import3dImporter::errorReported, + this, &Import3dDialog::addError); + connect(&m_importer, &Import3dImporter::warningReported, + this, &Import3dDialog::addWarning); + connect(&m_importer, &Import3dImporter::infoReported, + this, &Import3dDialog::addInfo); + connect(&m_importer, &Import3dImporter::importNearlyFinished, + this, &Import3dDialog::onImportNearlyFinished); + connect(&m_importer, &Import3dImporter::importFinished, + this, &Import3dDialog::onImportFinished); + connect(&m_importer, &Import3dImporter::progressChanged, + this, &Import3dDialog::setImportProgress); + connect(&m_importer, &Import3dImporter::importReadyForPreview, + this, &Import3dDialog::onImportReadyForPreview); connect(ui->advancedSettingsButton, &QPushButton::clicked, - this, &ItemLibraryAssetImportDialog::toggleAdvanced); + this, &Import3dDialog::toggleAdvanced); connect(ui->importList, &QListWidget::currentItemChanged, - this, &ItemLibraryAssetImportDialog::onCurrentItemChanged); + this, &Import3dDialog::onCurrentItemChanged); - QTimer::singleShot(0, this, &ItemLibraryAssetImportDialog::updateUi); + QTimer::singleShot(0, this, &Import3dDialog::updateUi); addInfo(tr("Importing:")); - QTimer::singleShot(0, this, &ItemLibraryAssetImportDialog::onImport); + QTimer::singleShot(0, this, &Import3dDialog::onImport); for (const auto &file : std::as_const(m_quick3DFiles)) addInfo(file); @@ -274,16 +274,16 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog( m_updatingControlStates = false; } -ItemLibraryAssetImportDialog::~ItemLibraryAssetImportDialog() +Import3dDialog::~Import3dDialog() { cleanupPreviewPuppet(); delete ui; } -void ItemLibraryAssetImportDialog::updateImport(AbstractView *view, - const ModelNode &updateNode, - const QVariantMap &supportedExts, - const QVariantMap &supportedOpts) +void Import3dDialog::updateImport(AbstractView *view, + const ModelNode &updateNode, + const QVariantMap &supportedExts, + const QVariantMap &supportedOpts) { QString errorMsg; const ModelNode &node = updateNode; @@ -366,7 +366,7 @@ void ItemLibraryAssetImportDialog::updateImport(AbstractView *view, source = QDir{compFileInfo.absolutePath()}.absoluteFilePath(source); preselectedFiles.insert(source); } - auto importDlg = new ItemLibraryAssetImportDialog( + auto importDlg = new Import3dDialog( {sourceInfo.absoluteFilePath()}, node.model()->fileUrl().toLocalFile(), supportedExts, supportedOpts, options, @@ -404,7 +404,7 @@ void ItemLibraryAssetImportDialog::updateImport(AbstractView *view, } } -void ItemLibraryAssetImportDialog::keyPressEvent(QKeyEvent *event) +void Import3dDialog::keyPressEvent(QKeyEvent *event) { if ((event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete) && ui->importList->currentItem()) { @@ -413,8 +413,8 @@ void ItemLibraryAssetImportDialog::keyPressEvent(QKeyEvent *event) return QDialog::keyPressEvent(event); } -void ItemLibraryAssetImportDialog::createTab(const QString &tabLabel, int optionsIndex, - const QJsonObject &groups) +void Import3dDialog::createTab(const QString &tabLabel, int optionsIndex, + const QJsonObject &groups) { auto optionsArea = new QScrollArea(ui->tabWidget); optionsArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -451,7 +451,7 @@ void ItemLibraryAssetImportDialog::createTab(const QString &tabLabel, int option ui->tabWidget->addTab(optionsArea, tr("%1 options").arg(tabLabel)); } -QGridLayout *ItemLibraryAssetImportDialog::createOptionsGrid( +QGridLayout *Import3dDialog::createOptionsGrid( QWidget *contentWidget, bool advanced, int optionsIndex, const QJsonObject &groups) { auto layout = new QGridLayout(); @@ -839,7 +839,7 @@ QGridLayout *ItemLibraryAssetImportDialog::createOptionsGrid( return layout; } -void ItemLibraryAssetImportDialog::updateUi() +void Import3dDialog::updateUi() { auto optionsArea = qobject_cast(ui->tabWidget->currentWidget()); if (optionsArea) { @@ -858,7 +858,7 @@ void ItemLibraryAssetImportDialog::updateUi() } } -QString ItemLibraryAssetImportDialog::assetNameForListItem(QListWidgetItem *item) +QString Import3dDialog::assetNameForListItem(QListWidgetItem *item) { for (const ImportData &data : std::as_const(m_importData)) { if (data.listItem == item) @@ -867,7 +867,7 @@ QString ItemLibraryAssetImportDialog::assetNameForListItem(QListWidgetItem *item return {}; } -bool ItemLibraryAssetImportDialog::isSimpleGroup(const QString &id) +bool Import3dDialog::isSimpleGroup(const QString &id) { static QStringList simpleGroups { "globalScale" @@ -876,7 +876,7 @@ bool ItemLibraryAssetImportDialog::isSimpleGroup(const QString &id) return simpleGroups.contains(id); } -bool ItemLibraryAssetImportDialog::isSimpleOption(const QString &id) +bool Import3dDialog::isSimpleOption(const QString &id) { static QStringList simpleOptions { "globalScale", @@ -886,7 +886,7 @@ bool ItemLibraryAssetImportDialog::isSimpleOption(const QString &id) return simpleOptions.contains(id); } -bool ItemLibraryAssetImportDialog::isHiddenOption(const QString &id) +bool Import3dDialog::isHiddenOption(const QString &id) { static QList hiddenOptions { qdsWorkaroundsKey, @@ -896,7 +896,7 @@ bool ItemLibraryAssetImportDialog::isHiddenOption(const QString &id) return hiddenOptions.contains(id); } -bool ItemLibraryAssetImportDialog::optionsChanged() +bool Import3dDialog::optionsChanged() { for (const ImportData &data : std::as_const(m_importData)) { if (data.previewData.renderedOptions != data.previewData.currentOptions) @@ -905,7 +905,7 @@ bool ItemLibraryAssetImportDialog::optionsChanged() return false; } -void ItemLibraryAssetImportDialog::startPreview() +void Import3dDialog::startPreview() { cleanupPreviewPuppet(); @@ -1039,7 +1039,7 @@ Rectangle { const QString errorMsg(tr("Preview generation process crashed.")); addWarning(errorMsg); canvas()->displayError(errorMsg); - QTimer::singleShot(0, this, &ItemLibraryAssetImportDialog::cleanupPreviewPuppet); + QTimer::singleShot(0, this, &Import3dDialog::cleanupPreviewPuppet); }; m_connectionManager->setPreviewIconCallback(std::move(previewIconCallback)); @@ -1049,7 +1049,7 @@ Rectangle { m_model->setNodeInstanceView(m_nodeInstanceView); } -void ItemLibraryAssetImportDialog::cleanupPreviewPuppet() +void Import3dDialog::cleanupPreviewPuppet() { if (m_model) { m_model->setNodeInstanceView({}); @@ -1070,12 +1070,12 @@ void ItemLibraryAssetImportDialog::cleanupPreviewPuppet() delete m_connectionManager; } -Import3dCanvas *ItemLibraryAssetImportDialog::canvas() +Import3dCanvas *Import3dDialog::canvas() { return ui->import3dcanvas; } -void ItemLibraryAssetImportDialog::resetOptionControls() +void Import3dDialog::resetOptionControls() { const QString currentName = assetNameForListItem(ui->importList->currentItem()); if (!m_importData.contains(currentName)) @@ -1100,19 +1100,19 @@ void ItemLibraryAssetImportDialog::resetOptionControls() updatePreviewOptions(); } -void ItemLibraryAssetImportDialog::resizeEvent(QResizeEvent *event) +void Import3dDialog::resizeEvent(QResizeEvent *event) { m_dialogHeight = event->size().height(); updateUi(); } -void ItemLibraryAssetImportDialog::setCloseButtonState(bool importing) +void Import3dDialog::setCloseButtonState(bool importing) { ui->closeButton->setEnabled(true); ui->closeButton->setText(importing ? tr("Cancel") : tr("Close")); } -void ItemLibraryAssetImportDialog::updatePreviewOptions() +void Import3dDialog::updatePreviewOptions() { if (m_updatingControlStates) return; @@ -1128,24 +1128,24 @@ void ItemLibraryAssetImportDialog::updatePreviewOptions() ui->importButton->setText(optionsChanged() ? tr("Import") : tr("Accept")); } -void ItemLibraryAssetImportDialog::addError(const QString &error, const QString &srcPath) +void Import3dDialog::addError(const QString &error, const QString &srcPath) { m_closeOnFinish = false; addFormattedMessage(m_outputFormatter, error, srcPath, Utils::StdErrFormat); } -void ItemLibraryAssetImportDialog::addWarning(const QString &warning, const QString &srcPath) +void Import3dDialog::addWarning(const QString &warning, const QString &srcPath) { m_closeOnFinish = false; addFormattedMessage(m_outputFormatter, warning, srcPath, Utils::StdOutFormat); } -void ItemLibraryAssetImportDialog::addInfo(const QString &info, const QString &srcPath) +void Import3dDialog::addInfo(const QString &info, const QString &srcPath) { addFormattedMessage(m_outputFormatter, info, srcPath, Utils::NormalMessageFormat); } -void ItemLibraryAssetImportDialog::onImport() +void Import3dDialog::onImport() { ui->importButton->setEnabled(false); ui->tabWidget->setEnabled(false); @@ -1179,7 +1179,7 @@ void ItemLibraryAssetImportDialog::onImport() } } -void ItemLibraryAssetImportDialog::setImportProgress(int value, const QString &text) +void Import3dDialog::setImportProgress(int value, const QString &text) { ui->progressLabel->setText(text); if (value < 0) @@ -1189,8 +1189,8 @@ void ItemLibraryAssetImportDialog::setImportProgress(int value, const QString &t ui->progressBar->setValue(value); } -void ItemLibraryAssetImportDialog::onImportReadyForPreview( - const QString &path, const QList &previewData) +void Import3dDialog::onImportReadyForPreview( + const QString &path, const QList &previewData) { if (previewData.isEmpty()) { m_importer.cancelImport(); @@ -1204,7 +1204,7 @@ void ItemLibraryAssetImportDialog::onImportReadyForPreview( const QString tallStr = "Wj\nWj\nWj"; QStringList assetNames; - for (const ItemLibraryAssetImporter::PreviewData &data : previewData) { + for (const Import3dImporter::PreviewData &data : previewData) { const QString assetName = data.name; assetNames.append(assetName); if (!m_importData.contains(assetName)) { @@ -1277,7 +1277,7 @@ void ItemLibraryAssetImportDialog::onImportReadyForPreview( if (m_previewFile.isEmpty()) { m_previewFile = Utils::FilePath::fromString(path).pathAppended(m_importer.previewFileName()); - QTimer::singleShot(0, this, &ItemLibraryAssetImportDialog::startPreview); + QTimer::singleShot(0, this, &Import3dDialog::startPreview); } QTimer::singleShot(0, this, [this, assetNames]() { @@ -1303,25 +1303,25 @@ void ItemLibraryAssetImportDialog::onImportReadyForPreview( ui->importList->setCurrentRow(0); } -void ItemLibraryAssetImportDialog::onRequestImageUpdate() +void Import3dDialog::onRequestImageUpdate() { if (m_nodeInstanceView) m_nodeInstanceView->view3DAction(View3DActionType::Import3dUpdatePreviewImage, canvas()->size()); } -void ItemLibraryAssetImportDialog::onRequestRotation(const QPointF &delta) +void Import3dDialog::onRequestRotation(const QPointF &delta) { if (m_nodeInstanceView) m_nodeInstanceView->view3DAction(View3DActionType::Import3dRotatePreviewModel, delta); } -void ItemLibraryAssetImportDialog::onImportNearlyFinished() +void Import3dDialog::onImportNearlyFinished() { // Canceling import is no longer doable ui->closeButton->setEnabled(false); } -void ItemLibraryAssetImportDialog::onImportFinished() +void Import3dDialog::onImportFinished() { setCloseButtonState(false); if (m_importer.isCancelled()) { @@ -1329,19 +1329,19 @@ void ItemLibraryAssetImportDialog::onImportFinished() addError(interruptStr); setImportProgress(0, interruptStr); if (m_explicitClose) - QTimer::singleShot(1000, this, &ItemLibraryAssetImportDialog::doClose); + QTimer::singleShot(1000, this, &Import3dDialog::doClose); } else { QString doneStr = tr("Import done."); addInfo(doneStr); setImportProgress(100, doneStr); if (m_closeOnFinish) { // Add small delay to allow user to visually confirm import finishing - QTimer::singleShot(1000, this, &ItemLibraryAssetImportDialog::doClose); + QTimer::singleShot(1000, this, &Import3dDialog::doClose); } } } -void ItemLibraryAssetImportDialog::onCurrentItemChanged(QListWidgetItem *current, QListWidgetItem *) +void Import3dDialog::onCurrentItemChanged(QListWidgetItem *current, QListWidgetItem *) { if (!current) return; @@ -1372,14 +1372,14 @@ void ItemLibraryAssetImportDialog::onCurrentItemChanged(QListWidgetItem *current }); } -void ItemLibraryAssetImportDialog::onClose() +void Import3dDialog::onClose() { ui->importButton->setEnabled(false); m_explicitClose = true; doClose(); } -void ItemLibraryAssetImportDialog::doClose() +void Import3dDialog::doClose() { if (m_importer.isImporting()) { addInfo(tr("Canceling import.")); @@ -1394,7 +1394,7 @@ void ItemLibraryAssetImportDialog::doClose() } } -void ItemLibraryAssetImportDialog::toggleAdvanced() +void Import3dDialog::toggleAdvanced() { m_advancedMode = !m_advancedMode; for (const auto &widget : std::as_const(m_simpleData.contentWidgets)) { @@ -1417,7 +1417,7 @@ void ItemLibraryAssetImportDialog::toggleAdvanced() updateUi(); } -void ItemLibraryAssetImportDialog::onRemoveAsset(const QString &assetName) +void Import3dDialog::onRemoveAsset(const QString &assetName) { m_importer.removeAssetFromImport(assetName); if (m_importData.contains(assetName)) { diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.h b/src/plugins/qmldesigner/components/import3d/import3ddialog.h similarity index 77% rename from src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.h rename to src/plugins/qmldesigner/components/import3d/import3ddialog.h index 17df31502b3..df7dd7c27d5 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.h +++ b/src/plugins/qmldesigner/components/import3d/import3ddialog.h @@ -1,8 +1,8 @@ -// Copyright (C) 2019 The Qt Company Ltd. +// Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once -#include "itemlibraryassetimporter.h" +#include "import3dimporter.h" #include @@ -32,23 +32,23 @@ class NodeInstanceView; class RewriterView; namespace Ui { -class ItemLibraryAssetImportDialog; +class Import3dDialog; } -class ItemLibraryAssetImportDialog : public QDialog +class Import3dDialog : public QDialog { Q_OBJECT public: - explicit ItemLibraryAssetImportDialog(const QStringList &importFiles, - const QString &defaulTargetDirectory, - const QVariantMap &supportedExts, - const QVariantMap &supportedOpts, - const QJsonObject &defaultOpts, - const QSet &preselectedFilesForOverwrite, - AbstractView *view, - QWidget *parent = nullptr); - ~ItemLibraryAssetImportDialog(); + explicit Import3dDialog(const QStringList &importFiles, + const QString &defaulTargetDirectory, + const QVariantMap &supportedExts, + const QVariantMap &supportedOpts, + const QJsonObject &defaultOpts, + const QSet &preselectedFilesForOverwrite, + AbstractView *view, + QWidget *parent = nullptr); + ~Import3dDialog(); static void updateImport(AbstractView *view, const ModelNode &updateNode, @@ -72,7 +72,7 @@ private: QLabel *iconLabel = {}; QLabel *infoLabel = {}; QPushButton *removeButton = {}; - ItemLibraryAssetImporter::PreviewData previewData; + Import3dImporter::PreviewData previewData; }; struct OptionsData @@ -88,7 +88,7 @@ private: void onImport(); void setImportProgress(int value, const QString &text); void onImportReadyForPreview(const QString &path, - const QList &previewData); + const QList &previewData); void onRequestImageUpdate(); void onRequestRotation(const QPointF &delta); void onImportNearlyFinished(); @@ -115,7 +115,7 @@ private: Import3dCanvas *canvas(); void resetOptionControls(); - Ui::ItemLibraryAssetImportDialog *ui = nullptr; + Ui::Import3dDialog *ui = nullptr; Utils::OutputFormatter *m_outputFormatter = nullptr; QPointer m_connectionManager; QPointer m_nodeInstanceView; @@ -128,7 +128,7 @@ private: QStringList m_quick3DFiles; QString m_quick3DImportPath; - ItemLibraryAssetImporter m_importer; + Import3dImporter m_importer; QVector m_importOptions; QHash m_extToImportOptionsMap; QSet m_preselectedFilesForOverwrite; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.ui b/src/plugins/qmldesigner/components/import3d/import3ddialog.ui similarity index 97% rename from src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.ui rename to src/plugins/qmldesigner/components/import3d/import3ddialog.ui index 62f31283119..f91cc1d9ea4 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.ui +++ b/src/plugins/qmldesigner/components/import3d/import3ddialog.ui @@ -1,7 +1,7 @@ - QmlDesigner::ItemLibraryAssetImportDialog - + QmlDesigner::Import3dDialog + 0 diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp b/src/plugins/qmldesigner/components/import3d/import3dimporter.cpp similarity index 89% rename from src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp rename to src/plugins/qmldesigner/components/import3d/import3dimporter.cpp index 44d451b94e7..2cdf1510b5c 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp +++ b/src/plugins/qmldesigner/components/import3d/import3dimporter.cpp @@ -1,6 +1,6 @@ -// Copyright (C) 2019 The Qt Company Ltd. +// 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 "itemlibraryassetimporter.h" +#include "import3dimporter.h" #include "assetimportupdatedialog.h" #include "qmldesignerplugin.h" @@ -38,26 +38,27 @@ namespace { -static Q_LOGGING_CATEGORY(importerLog, "qtc.itemlibrary.assetImporter", QtWarningMsg) +static Q_LOGGING_CATEGORY(importerLog, "qtc.itemlibrary.Import3dImporter", QtWarningMsg) } namespace QmlDesigner { -ItemLibraryAssetImporter::ItemLibraryAssetImporter(QObject *parent) : - QObject (parent) +Import3dImporter::Import3dImporter(QObject *parent) + : QObject (parent) { } -ItemLibraryAssetImporter::~ItemLibraryAssetImporter() { +Import3dImporter::~Import3dImporter() +{ cancelImport(); delete m_tempDir; }; -void ItemLibraryAssetImporter::importQuick3D(const QStringList &inputFiles, - const QString &importPath, - const QVector &options, - const QHash &extToImportOptionsMap, - const QSet &preselectedFilesForOverwrite) +void Import3dImporter::importQuick3D(const QStringList &inputFiles, + const QString &importPath, + const QVector &options, + const QHash &extToImportOptionsMap, + const QSet &preselectedFilesForOverwrite) { reset(); m_isImporting = true; @@ -91,7 +92,7 @@ void ItemLibraryAssetImporter::importQuick3D(const QStringList &inputFiles, } } -void ItemLibraryAssetImporter::reImportQuick3D(const QHash &importOptions) +void Import3dImporter::reImportQuick3D(const QHash &importOptions) { m_isImporting = false; m_cancelled = false; @@ -148,38 +149,38 @@ void ItemLibraryAssetImporter::reImportQuick3D(const QHash startNextImportProcess(); } -bool ItemLibraryAssetImporter::isImporting() const +bool Import3dImporter::isImporting() const { return m_isImporting; } -void ItemLibraryAssetImporter::cancelImport() +void Import3dImporter::cancelImport() { m_cancelled = true; if (m_isImporting) notifyFinished(); } -void ItemLibraryAssetImporter::addError(const QString &errMsg, const QString &srcPath) +void Import3dImporter::addError(const QString &errMsg, const QString &srcPath) { qCDebug(importerLog) << "Error: "<< errMsg << srcPath; emit errorReported(errMsg, srcPath); } -void ItemLibraryAssetImporter::addWarning(const QString &warningMsg, const QString &srcPath) +void Import3dImporter::addWarning(const QString &warningMsg, const QString &srcPath) { qCDebug(importerLog) << "Warning: " << warningMsg << srcPath; emit warningReported(warningMsg, srcPath); } -void ItemLibraryAssetImporter::addInfo(const QString &infoMsg, const QString &srcPath) +void Import3dImporter::addInfo(const QString &infoMsg, const QString &srcPath) { qCDebug(importerLog) << "Info: " << infoMsg << srcPath; emit infoReported(infoMsg, srcPath); } -void ItemLibraryAssetImporter::importProcessFinished([[maybe_unused]] int exitCode, - QProcess::ExitStatus exitStatus) +void Import3dImporter::importProcessFinished([[maybe_unused]] int exitCode, + QProcess::ExitStatus exitStatus) { m_puppetProcess.reset(); @@ -218,19 +219,19 @@ void ItemLibraryAssetImporter::importProcessFinished([[maybe_unused]] int exitCo if (m_puppetQueue.isEmpty() && !m_puppetProcess) { notifyProgress(100); - QTimer::singleShot(0, this, &ItemLibraryAssetImporter::postImport); + QTimer::singleShot(0, this, &Import3dImporter::postImport); } else { notifyProgress(int(100. * (double(finishedCount) / double(m_importIdToAssetNameMap.size())))); } } -void ItemLibraryAssetImporter::notifyFinished() +void Import3dImporter::notifyFinished() { m_isImporting = false; emit importFinished(); } -void ItemLibraryAssetImporter::reset() +void Import3dImporter::reset() { m_isImporting = false; m_cancelled = false; @@ -246,10 +247,10 @@ void ItemLibraryAssetImporter::reset() m_importIdToAssetNameMap.clear(); } -void ItemLibraryAssetImporter::parseFiles(const QStringList &filePaths, - const QVector &options, - const QHash &extToImportOptionsMap, - const QSet &preselectedFilesForOverwrite) +void Import3dImporter::parseFiles(const QStringList &filePaths, + const QVector &options, + const QHash &extToImportOptionsMap, + const QSet &preselectedFilesForOverwrite) { if (isCancelled()) return; @@ -275,8 +276,8 @@ void ItemLibraryAssetImporter::parseFiles(const QStringList &filePaths, } } -bool ItemLibraryAssetImporter::preParseQuick3DAsset(const QString &file, ParseData &pd, - const QSet &preselectedFilesForOverwrite) +bool Import3dImporter::preParseQuick3DAsset(const QString &file, ParseData &pd, + const QSet &preselectedFilesForOverwrite) { pd.targetDir = QDir(m_importPath); pd.outDir = QDir(m_tempDir->path()); @@ -360,7 +361,7 @@ bool ItemLibraryAssetImporter::preParseQuick3DAsset(const QString &file, ParseDa return true; } -void ItemLibraryAssetImporter::postParseQuick3DAsset(ParseData &pd) +void Import3dImporter::postParseQuick3DAsset(ParseData &pd) { QDir outDir = pd.outDir; if (pd.originalAssetName != pd.assetName) { @@ -495,7 +496,7 @@ void ItemLibraryAssetImporter::postParseQuick3DAsset(ParseData &pd) m_importFiles.insert(pd.assetName, assetFiles); } -void ItemLibraryAssetImporter::copyImportedFiles() +void Import3dImporter::copyImportedFiles() { QHash allOverwrites; for (const ParseData &pd: std::as_const(m_parseData)) @@ -553,37 +554,37 @@ void ItemLibraryAssetImporter::copyImportedFiles() } } -void ItemLibraryAssetImporter::notifyProgress(int value, const QString &text) +void Import3dImporter::notifyProgress(int value, const QString &text) { m_progressTitle = text; emit progressChanged(value, m_progressTitle); keepUiAlive(); } -void ItemLibraryAssetImporter::notifyProgress(int value) +void Import3dImporter::notifyProgress(int value) { notifyProgress(value, m_progressTitle); } -void ItemLibraryAssetImporter::keepUiAlive() const +void Import3dImporter::keepUiAlive() const { QApplication::processEvents(); } -QString ItemLibraryAssetImporter::generateAssetFolderName(const QString &assetName) const +QString Import3dImporter::generateAssetFolderName(const QString &assetName) const { static int counter = 0; return assetName + "_QDS_" + QString::number(counter++); } -QString ItemLibraryAssetImporter::generateRequiredImportForAsset(const QString &assetName) const +QString Import3dImporter::generateRequiredImportForAsset(const QString &assetName) const { return QStringLiteral("%1.%2").arg( QmlDesignerPlugin::instance()->documentManager() .generatedComponentUtils().import3dTypePrefix(), assetName); } -ItemLibraryAssetImporter::OverwriteResult ItemLibraryAssetImporter::confirmAssetOverwrite(const QString &assetName) +Import3dImporter::OverwriteResult Import3dImporter::confirmAssetOverwrite(const QString &assetName) { const QString title = tr("Overwrite Existing Asset?"); const QString question = tr("Asset already exists. Overwrite existing or skip?\n\"%1\"").arg(assetName); @@ -605,7 +606,7 @@ ItemLibraryAssetImporter::OverwriteResult ItemLibraryAssetImporter::confirmAsset return OverwriteResult::Skip; } -void ItemLibraryAssetImporter::startNextImportProcess() +void Import3dImporter::startNextImportProcess() { if (m_puppetQueue.isEmpty()) return; @@ -649,7 +650,7 @@ void ItemLibraryAssetImporter::startNextImportProcess() } } -void ItemLibraryAssetImporter::postImport() +void Import3dImporter::postImport() { QTC_ASSERT(m_puppetQueue.isEmpty() && !m_puppetProcess, return); @@ -688,7 +689,7 @@ void ItemLibraryAssetImporter::postImport() } } -void ItemLibraryAssetImporter::finalizeQuick3DImport() +void Import3dImporter::finalizeQuick3DImport() { if (!isCancelled()) { // Don't allow cancel anymore as existing asset overwrites are not trivially recoverable. @@ -736,7 +737,7 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport() model->rewriterView()->forceAmend(); try { RewriterTransaction transaction = model->rewriterView()->beginRewriterTransaction( - QByteArrayLiteral("ItemLibraryAssetImporter::finalizeQuick3DImport")); + QByteArrayLiteral("Import3dImporter::finalizeQuick3DImport")); bool success = ModelUtils::addImportsWithCheck(m_requiredImports, model); if (!success) addError(tr("Failed to insert import statement into qml document.")); @@ -766,19 +767,19 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport() } } -void ItemLibraryAssetImporter::removeAssetFromImport(const QString &assetName) +void Import3dImporter::removeAssetFromImport(const QString &assetName) { m_parseData.remove(assetName); m_importFiles.remove(assetName); m_requiredImports.removeOne(generateRequiredImportForAsset(assetName)); } -QString ItemLibraryAssetImporter::sourceSceneTargetFilePath(const ParseData &pd) +QString Import3dImporter::sourceSceneTargetFilePath(const ParseData &pd) { return pd.targetDirPath + QStringLiteral("/source scene/") + pd.sourceInfo.fileName(); } -bool ItemLibraryAssetImporter::isCancelled() const +bool Import3dImporter::isCancelled() const { keepUiAlive(); return m_cancelled; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h b/src/plugins/qmldesigner/components/import3d/import3dimporter.h similarity index 95% rename from src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h rename to src/plugins/qmldesigner/components/import3d/import3dimporter.h index dcdc1150a6b..594a1c98603 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h +++ b/src/plugins/qmldesigner/components/import3d/import3dimporter.h @@ -1,4 +1,4 @@ -// Copyright (C) 2019 The Qt Company Ltd. +// Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once @@ -14,19 +14,18 @@ #include QT_BEGIN_NAMESPACE -class QSSGAssetImportManager; class QTemporaryDir; QT_END_NAMESPACE namespace QmlDesigner { -class ItemLibraryAssetImporter : public QObject +class Import3dImporter : public QObject { Q_OBJECT public: - ItemLibraryAssetImporter(QObject *parent = nullptr); - ~ItemLibraryAssetImporter(); + Import3dImporter(QObject *parent = nullptr); + ~Import3dImporter(); void importQuick3D(const QStringList &inputFiles, const QString &importPath, const QVector &options, diff --git a/src/plugins/qmldesigner/components/integration/componentview.cpp b/src/plugins/qmldesigner/components/integration/componentview.cpp index 6862204633d..a62c12991d1 100644 --- a/src/plugins/qmldesigner/components/integration/componentview.cpp +++ b/src/plugins/qmldesigner/components/integration/componentview.cpp @@ -4,11 +4,16 @@ #include "componentview.h" #include "componentaction.h" +#include +#include +#include +#include #include +#include + +#include #include - -#include #include // silence gcc warnings about unused parameters @@ -232,4 +237,111 @@ void ComponentView::nodeSourceChanged(const ModelNode &node, const QString &/*ne maybeRemoveMasterDocument(); } } + +void ComponentView::customNotification(const AbstractView *view, const QString &identifier, + const QList &nodeList, const QList &) +{ + if (identifier == "UpdateImported3DAsset" && nodeList.size() > 0) { + Import3dDialog::updateImport(this, nodeList[0], + m_importableExtensions3DMap, + m_importOptions3DMap); + } +} + +void ComponentView::updateImport3DSupport(const QVariantMap &supportMap) +{ + QVariantMap extMap = qvariant_cast(supportMap.value("extensions")); + if (m_importableExtensions3DMap != extMap) { + DesignerActionManager *actionManager = + &QmlDesignerPlugin::instance()->viewManager().designerActionManager(); + + if (!m_importableExtensions3DMap.isEmpty()) + actionManager->unregisterAddResourceHandlers(ComponentCoreConstants::add3DAssetsDisplayString); + + m_importableExtensions3DMap = extMap; + + AddResourceOperation import3DModelOperation = [this](const QStringList &fileNames, + const QString &defaultDir, + bool showDialog) -> AddFilesResult { + Q_UNUSED(showDialog) + + auto importDlg = new Import3dDialog(fileNames, defaultDir, + m_importableExtensions3DMap, + m_importOptions3DMap, {}, {}, + this, Core::ICore::dialogParent()); + int result = importDlg->exec(); + + return result == QDialog::Accepted ? AddFilesResult::succeeded() : AddFilesResult::cancelled(); + }; + + auto add3DHandler = [&](const QString &group, const QString &ext) { + const QString filter = QStringLiteral("*.%1").arg(ext); + actionManager->registerAddResourceHandler( + AddResourceHandler(group, filter, + import3DModelOperation, 10)); + }; + + const QHash groupNames { + {"3D Scene", ComponentCoreConstants::add3DAssetsDisplayString}, + {"Qt 3D Studio Presentation", ComponentCoreConstants::addQt3DSPresentationsDisplayString} + }; + + const auto groups = extMap.keys(); + for (const auto &group : groups) { + const QStringList exts = extMap[group].toStringList(); + const QString grp = groupNames.contains(group) ? groupNames.value(group) : group; + for (const auto &ext : exts) + add3DHandler(grp, ext); + } + } + + m_importOptions3DMap = qvariant_cast(supportMap.value("options")); +} + +void ComponentView::importsChanged(const Imports &addedImports, const Imports &removedImports) +{ +#ifndef QDS_USE_PROJECTSTORAGE + DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); + for (const auto &import : addedImports) + document->addSubcomponentManagerImport(import); +#endif + + // TODO: generalize the logic below to allow adding/removing any Qml component when its import is added/removed + bool simulinkImportAdded = std::any_of(addedImports.cbegin(), addedImports.cend(), [](const Import &import) { + return import.url() == "SimulinkConnector"; + }); + if (simulinkImportAdded) { + // add SLConnector component when SimulinkConnector import is added + ModelNode node = createModelNode("SLConnector", 1, 0); + node.bindingProperty("root").setExpression(rootModelNode().validId()); + rootModelNode().defaultNodeListProperty().reparentHere(node); + } else { + bool simulinkImportRemoved = std::any_of(removedImports.cbegin(), removedImports.cend(), [](const Import &import) { + return import.url() == "SimulinkConnector"; + }); + + if (simulinkImportRemoved) { + // remove SLConnector component when SimulinkConnector import is removed + const QList slConnectors = Utils::filtered(rootModelNode().directSubModelNodes(), + [](const ModelNode &node) { + return node.type() == "SLConnector" || node.type() == "SimulinkConnector.SLConnector"; + }); + + for (ModelNode node : slConnectors) + node.destroy(); + + resetPuppet(); + } + } +} + +void ComponentView::possibleImportsChanged(const Imports &possibleImports) +{ +#ifndef QDS_USE_PROJECTSTORAGE + DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); + for (const auto &import : possibleImports) + document->addSubcomponentManagerImport(import); +#endif +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/integration/componentview.h b/src/plugins/qmldesigner/components/integration/componentview.h index c315ceb4270..1226e7dd614 100644 --- a/src/plugins/qmldesigner/components/integration/componentview.h +++ b/src/plugins/qmldesigner/components/integration/componentview.h @@ -41,6 +41,10 @@ public: AbstractView::PropertyChangeFlags propertyChange) override; void nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId) override; void nodeSourceChanged(const ModelNode &node, const QString &newNodeSource) override; + void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data) override; + void updateImport3DSupport(const QVariantMap &supportMap) override; + void importsChanged(const Imports &addedImports, const Imports &removedImports) override; + void possibleImportsChanged(const Imports &possibleImports) override; QStandardItemModel *standardItemModel() const; @@ -71,6 +75,9 @@ private: //functions private: QStandardItemModel *m_standardItemModel; ComponentAction *m_componentAction; + + QVariantMap m_importableExtensions3DMap; + QVariantMap m_importOptions3DMap; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp index 9ff1f8e8e70..707370e7e7a 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "itemlibraryview.h" -#include "itemlibraryassetimportdialog.h" #include "itemlibrarywidget.h" #include "metainfo.h" #include @@ -10,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -76,52 +74,12 @@ void ItemLibraryView::modelAboutToBeDetached(Model *model) void ItemLibraryView::importsChanged(const Imports &addedImports, const Imports &removedImports) { -#ifndef QDS_USE_PROJECTSTORAGE - DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); - for (const auto &import : addedImports) - document->addSubcomponentManagerImport(import); -#endif - updateImports(); m_widget->updatePossibleImports(model()->possibleImports()); - - // TODO: generalize the logic below to allow adding/removing any Qml component when its import is added/removed - bool simulinkImportAdded = std::any_of(addedImports.cbegin(), addedImports.cend(), [](const Import &import) { - return import.url() == "SimulinkConnector"; - }); - if (simulinkImportAdded) { - // add SLConnector component when SimulinkConnector import is added - ModelNode node = createModelNode("SLConnector", 1, 0); - node.bindingProperty("root").setExpression(rootModelNode().validId()); - rootModelNode().defaultNodeListProperty().reparentHere(node); - } else { - bool simulinkImportRemoved = std::any_of(removedImports.cbegin(), removedImports.cend(), [](const Import &import) { - return import.url() == "SimulinkConnector"; - }); - - if (simulinkImportRemoved) { - // remove SLConnector component when SimulinkConnector import is removed - const QList slConnectors = Utils::filtered(rootModelNode().directSubModelNodes(), - [](const ModelNode &node) { - return node.type() == "SLConnector" || node.type() == "SimulinkConnector.SLConnector"; - }); - - for (ModelNode node : slConnectors) - node.destroy(); - - resetPuppet(); - } - } } void ItemLibraryView::possibleImportsChanged(const Imports &possibleImports) { -#ifndef QDS_USE_PROJECTSTORAGE - DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); - for (const auto &import : possibleImports) - document->addSubcomponentManagerImport(import); -#endif - m_widget->updatePossibleImports(possibleImports); } @@ -143,69 +101,14 @@ void ItemLibraryView::updateImports() m_widget->delayedUpdateModel(); } -void ItemLibraryView::updateImport3DSupport(const QVariantMap &supportMap) -{ - QVariantMap extMap = qvariant_cast(supportMap.value("extensions")); - if (m_importableExtensions3DMap != extMap) { - DesignerActionManager *actionManager = - &QmlDesignerPlugin::instance()->viewManager().designerActionManager(); - - if (!m_importableExtensions3DMap.isEmpty()) - actionManager->unregisterAddResourceHandlers(ComponentCoreConstants::add3DAssetsDisplayString); - - m_importableExtensions3DMap = extMap; - - AddResourceOperation import3DModelOperation = [this](const QStringList &fileNames, - const QString &defaultDir, - bool showDialog) -> AddFilesResult { - Q_UNUSED(showDialog) - - auto importDlg = new ItemLibraryAssetImportDialog(fileNames, defaultDir, - m_importableExtensions3DMap, - m_importOptions3DMap, {}, {}, - this, Core::ICore::dialogParent()); - int result = importDlg->exec(); - - return result == QDialog::Accepted ? AddFilesResult::succeeded() : AddFilesResult::cancelled(); - }; - - auto add3DHandler = [&](const QString &group, const QString &ext) { - const QString filter = QStringLiteral("*.%1").arg(ext); - actionManager->registerAddResourceHandler( - AddResourceHandler(group, filter, - import3DModelOperation, 10)); - }; - - const QHash groupNames { - {"3D Scene", ComponentCoreConstants::add3DAssetsDisplayString}, - {"Qt 3D Studio Presentation", ComponentCoreConstants::addQt3DSPresentationsDisplayString} - }; - - const auto groups = extMap.keys(); - for (const auto &group : groups) { - const QStringList exts = extMap[group].toStringList(); - const QString grp = groupNames.contains(group) ? groupNames.value(group) : group; - for (const auto &ext : exts) - add3DHandler(grp, ext); - } - } - - m_importOptions3DMap = qvariant_cast(supportMap.value("options")); -} void ItemLibraryView::customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data) { - if (identifier == "UpdateImported3DAsset" && nodeList.size() > 0) { - ItemLibraryAssetImportDialog::updateImport(this, nodeList[0], - m_importableExtensions3DMap, - m_importOptions3DMap); - - } else if (identifier == UpdateItemlibrary) { + if (identifier == UpdateItemlibrary) updateImports(); - } else { + else AbstractView::customNotification(view, identifier, nodeList, data); - } } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h index 43287ae0e5a..d18a38029b4 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.h @@ -30,7 +30,6 @@ public: void possibleImportsChanged(const Imports &possibleImports) override; void usedImportsChanged(const Imports &usedImports) override; void documentMessagesChanged(const QList &errors, const QList &warnings) override; - void updateImport3DSupport(const QVariantMap &supportMap) override; void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data) override; @@ -41,8 +40,6 @@ private: AsynchronousImageCache &m_imageCache; QPointer m_widget; bool m_hasErrors = false; - QVariantMap m_importableExtensions3DMap; - QVariantMap m_importOptions3DMap; }; } From f3a04bdc88b804c76d2d92306d4708b505aa0ca5 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Mon, 19 Aug 2024 15:09:28 +0300 Subject: [PATCH 045/193] QmlDesigner: Correct title in confirm remove content lib item dialog Also in the unimport dialog Fixes: QDS-13399 Change-Id: Ia49cb76f88748cf389138e17189350c070afb799 Reviewed-by: Miikka Heikkinen --- .../qmldesigner/contentLibraryQmlSource/ContentLibrary.qml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml index e72ffd9471d..557a13e32bb 100644 --- a/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml +++ b/share/qtcreator/qmldesigner/contentLibraryQmlSource/ContentLibrary.qml @@ -265,14 +265,16 @@ Item { onUnimport: (bundleItem) => { confirmUnimportDialog.targetBundleItem = bundleItem - confirmUnimportDialog.targetBundleLabel = "material" + confirmUnimportDialog.targetBundleLabel = bundleItem.bundleId === "MaterialBundle" + ? qsTr("material") : qsTr("item") confirmUnimportDialog.targetBundleModel = ContentLibraryBackend.userModel confirmUnimportDialog.open() } onRemoveFromContentLib: (bundleItem) => { confirmDeleteDialog.targetBundleItem = bundleItem - confirmDeleteDialog.targetBundleLabel = "material" + confirmDeleteDialog.targetBundleLabel = bundleItem.bundleId === "MaterialBundle" + ? qsTr("material") : qsTr("item") confirmDeleteDialog.open() } From 315d11be527f4992298c838c49299184c916cdb9 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 19 Aug 2024 15:37:16 +0200 Subject: [PATCH 046/193] QmlDesigner: Fix unused parameter Change-Id: I2788a28f59e7f8b27d28102f9b4b3728ba6c78e8 Reviewed-by: Thomas Hartmann --- .../qmldesigner/components/integration/componentview.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/components/integration/componentview.cpp b/src/plugins/qmldesigner/components/integration/componentview.cpp index a62c12991d1..455f7918618 100644 --- a/src/plugins/qmldesigner/components/integration/componentview.cpp +++ b/src/plugins/qmldesigner/components/integration/componentview.cpp @@ -238,8 +238,10 @@ void ComponentView::nodeSourceChanged(const ModelNode &node, const QString &/*ne } } -void ComponentView::customNotification(const AbstractView *view, const QString &identifier, - const QList &nodeList, const QList &) +void ComponentView::customNotification(const AbstractView *, + const QString &identifier, + const QList &nodeList, + const QList &) { if (identifier == "UpdateImported3DAsset" && nodeList.size() > 0) { Import3dDialog::updateImport(this, nodeList[0], From 7166f792ddf9897c8e4d0b63daa803f57399f302 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 19 Aug 2024 15:57:34 +0200 Subject: [PATCH 047/193] QmlDesigner: Fix unused warnings Change-Id: Ib9ead94361ac5db7e05857d41c143d9541fe7341 Reviewed-by: Thomas Hartmann --- .../qmldesigner/components/integration/componentview.cpp | 2 +- .../qmldesigner/components/itemlibrary/itemlibraryview.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/components/integration/componentview.cpp b/src/plugins/qmldesigner/components/integration/componentview.cpp index 455f7918618..09dff0c5c20 100644 --- a/src/plugins/qmldesigner/components/integration/componentview.cpp +++ b/src/plugins/qmldesigner/components/integration/componentview.cpp @@ -337,7 +337,7 @@ void ComponentView::importsChanged(const Imports &addedImports, const Imports &r } } -void ComponentView::possibleImportsChanged(const Imports &possibleImports) +void ComponentView::possibleImportsChanged([[maybe_unused]] const Imports &possibleImports) { #ifndef QDS_USE_PROJECTSTORAGE DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument(); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp index 707370e7e7a..101a6de8b8c 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp @@ -72,7 +72,7 @@ void ItemLibraryView::modelAboutToBeDetached(Model *model) m_widget->setModel(nullptr); } -void ItemLibraryView::importsChanged(const Imports &addedImports, const Imports &removedImports) +void ItemLibraryView::importsChanged(const Imports &, const Imports &) { updateImports(); m_widget->updatePossibleImports(model()->possibleImports()); From 4450ee5a5abfc22133083574d758a4ed789d795a Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 12 Aug 2024 12:19:29 +0200 Subject: [PATCH 048/193] Nanotrace: Make TracerLiteral consteval So the user literal is not anymore needed. Change-Id: I578ce60933ab471a2feda2e2b6d92e144f60f2d1 Reviewed-by: Thomas Hartmann --- src/libs/nanotrace/nanotracehr.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/nanotrace/nanotracehr.h b/src/libs/nanotrace/nanotracehr.h index 15f8109fe91..03e44b4f5fc 100644 --- a/src/libs/nanotrace/nanotracehr.h +++ b/src/libs/nanotrace/nanotracehr.h @@ -53,7 +53,11 @@ using ArgumentsString = StaticString<3700>; namespace Literals { struct TracerLiteral { - friend constexpr TracerLiteral operator""_t(const char *text, size_t size); + consteval TracerLiteral(std::string_view text) + : text{text} + {} + + friend consteval TracerLiteral operator""_t(const char *text, size_t size); constexpr operator std::string_view() const { return text; } @@ -62,14 +66,10 @@ struct TracerLiteral operator Utils::SmallString() const { return text; } private: - constexpr TracerLiteral(std::string_view text) - : text{text} - {} - std::string_view text; }; -constexpr TracerLiteral operator""_t(const char *text, size_t size) +consteval TracerLiteral operator""_t(const char *text, size_t size) { return {std::string_view{text, size}}; } From f6933fb47645211296ca53a25306430385a65f74 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 14 Aug 2024 16:36:59 +0200 Subject: [PATCH 049/193] QmlDesigner: Refresh model node ids Types can get be removed or added again. The model node type ids have to be updated. The node type id can be get null. So the type is added later, the new type id has to be updated. Task-number: QDS-13378 Change-Id: I304fcf0171b0d607980bb8f7a591df179fd0c0f5 Reviewed-by: Thomas Hartmann --- src/libs/utils/set_algorithm.h | 93 +++++++++++++++---- .../designercore/include/abstractview.h | 7 +- .../designercore/include/modelnode.h | 4 +- .../designercore/model/abstractview.cpp | 14 +-- .../qmldesigner/designercore/model/model.cpp | 50 +++++++--- .../qmldesigner/designercore/model/model_p.h | 8 +- .../model/modelresourcemanagement.cpp | 66 +++++-------- .../model/modelresourcemanagementinterface.h | 2 +- .../model/nodeabstractproperty.cpp | 6 +- .../projectstorage/projectstorage.cpp | 29 +++++- .../projectstorage/projectstorage.h | 9 +- .../projectstorage/projectstorageobserver.h | 1 + tests/unit/tests/mocks/projectstoragemock.cpp | 17 +++- tests/unit/tests/mocks/projectstoragemock.h | 3 +- .../tests/mocks/projectstorageobservermock.h | 1 + .../unit/tests/unittests/model/model-test.cpp | 64 ++++++++++++- .../projectstorage/projectstorage-test.cpp | 40 +++++++- 17 files changed, 307 insertions(+), 107 deletions(-) diff --git a/src/libs/utils/set_algorithm.h b/src/libs/utils/set_algorithm.h index f6d3f73fedf..92b6ae0a37a 100644 --- a/src/libs/utils/set_algorithm.h +++ b/src/libs/utils/set_algorithm.h @@ -4,6 +4,9 @@ #pragma once #include +#include +#include +#include namespace Utils { @@ -13,7 +16,7 @@ class function_output_iterator public: typedef std::output_iterator_tag iterator_category; typedef void value_type; - typedef void difference_type; + typedef std::ptrdiff_t difference_type; typedef void pointer; typedef void reference; @@ -108,23 +111,6 @@ bool set_greedy_intersection_compare( return false; } -template -constexpr OutputIt set_greedy_intersection( - InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, OutputIt result) -{ - while (first1 != last1 && first2 != last2) - if (*first1 < *first2) - ++first1; - else if (*first2 < *first1) - ++first2; - else { - *result = *first1; - ++first1; - ++result; - } - return result; -} - template void set_greedy_difference( InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable call, Compare comp) @@ -143,6 +129,77 @@ void set_greedy_difference( call(*first1++); } +template +concept callmergeable = std::input_iterator && std::input_iterator + && std::indirect_strict_weak_order, + std::projected>; + +template +using set_intersection_result = std::ranges::set_intersection_result; + +struct set_greedy_intersection_functor +{ + template Sentinel1, + std::input_iterator Iterator2, + std::sentinel_for Sentinel2, + std::invocable &> Callable, + typename Comp = std::ranges::less, + typename Projection1 = std::identity, + typename Projection2 = std::identity> + requires callmergeable + constexpr void operator()(Iterator1 first1, + Sentinel1 last1, + Iterator2 first2, + Sentinel2 last2, + Callable callable, + Comp comp = {}, + Projection1 proj1 = {}, + Projection2 proj2 = {}) const + { + while (first1 != last1 && first2 != last2) + if (std::invoke(comp, std::invoke(proj1, *first1), std::invoke(proj2, *first2))) + ++first1; + else if (std::invoke(comp, std::invoke(proj2, *first2), std::invoke(proj1, *first1))) + ++first2; + else { + std::invoke(callable, *first1); + ++first1; + } + } + + template &> Callable, + typename Comp = std::ranges::less, + typename Projection1 = std::identity, + typename Projection2 = std::identity> + requires callmergeable, std::ranges::iterator_t, Comp, Projection1, Projection2> + constexpr void operator()(Range1 &&range1, + Range2 &&range2, + Callable callable, + Comp comp = {}, + Projection1 proj1 = {}, + Projection2 proj2 = {}) const + { + (*this)(std::ranges::begin(range1), + std::ranges::end(range1), + std::ranges::begin(range2), + std::ranges::end(range2), + std::move(callable), + std::move(comp), + std::move(proj1), + std::move(proj2)); + } +}; + +inline constexpr set_greedy_intersection_functor set_greedy_intersection{}; + template Value mismatch_collect(InputIt1 first1, InputIt1 last1, diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index 792a0dcf52e..f696f597c61 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -8,6 +8,7 @@ #include "qmldesignercorelib_global.h" #include +#include #include #include @@ -320,7 +321,7 @@ protected: DesignerWidgetFlags widgetFlags = DesignerWidgetFlags::DisableOnError); private: - QList toModelNodeList(const QList &nodeList) const; + QList toModelNodeList(Utils::span nodeList) const; QPointer m_model; ExternalDependenciesInterface &m_externalDependencies; @@ -331,5 +332,7 @@ private: QMLDESIGNERCORE_EXPORT QList toInternalNodeList(const QList &nodeList); QMLDESIGNERCORE_EXPORT QList toModelNodeList( - const QList &nodeList, Model *model, AbstractView *view); + Utils::span nodeList, + Model *model, + AbstractView *view = nullptr); } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/modelnode.h b/src/plugins/qmldesigner/designercore/include/modelnode.h index b0e5eeb7308..ba429b66e62 100644 --- a/src/plugins/qmldesigner/designercore/include/modelnode.h +++ b/src/plugins/qmldesigner/designercore/include/modelnode.h @@ -260,9 +260,9 @@ public: return !(firstNode == secondNode); } - friend bool operator<(const ModelNode &firstNode, const ModelNode &secondNode) + friend std::weak_ordering operator<=>(const ModelNode &firstNode, const ModelNode &secondNode) { - return firstNode.m_internalNode < secondNode.m_internalNode; + return firstNode.m_internalNode <=> secondNode.m_internalNode; } private: // functions diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index 67e7de6f552..b67e87390f9 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -18,8 +18,9 @@ #include "rewritertransaction.h" #include "variantproperty.h" -#include #include +#include +#include #include @@ -394,18 +395,19 @@ void AbstractView::view3DAction(View3DActionType, const QVariant &) {} void AbstractView::dragStarted(QMimeData * /*mimeData*/) {} void AbstractView::dragEnded() {} -QList AbstractView::toModelNodeList(const QList &nodeList) const +QList AbstractView::toModelNodeList(Utils::span nodes) const { - return QmlDesigner::toModelNodeList(nodeList, m_model, const_cast(this)); + return QmlDesigner::toModelNodeList(nodes, m_model, const_cast(this)); } -QList toModelNodeList(const QList &nodeList, +QList toModelNodeList(Utils::span nodes, Model *model, AbstractView *view) { QList newNodeList; - for (const Internal::InternalNode::Pointer &node : nodeList) - newNodeList.append(ModelNode(node, model, view)); + newNodeList.reserve(std::ssize(nodes)); + for (const Internal::InternalNode::Pointer &node : nodes) + newNodeList.emplace_back(node, model, view); return newNodeList; } diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 0352b0345ab..1a7cd269306 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -367,7 +367,7 @@ void ModelPrivate::removeNodeFromModel(const InternalNodePointer &node) m_idNodeHash.remove(node->id); node->isValid = false; node->traceToken.end(); - m_nodes.removeOne(node); + std::erase(m_nodes, node); m_internalIdNodeHash.remove(node->internalId); } @@ -424,6 +424,12 @@ void ModelPrivate::setTypeId(InternalNode *node, Utils::SmallStringView typeName } } +void ModelPrivate::refreshTypeId(InternalNode *node) +{ + if constexpr (useProjectStorage()) + node->typeId = projectStorage->typeId(node->importedTypeNameId); +} + void ModelPrivate::handleResourceSet(const ModelResourceSet &resourceSet) { for (const ModelNode &node : resourceSet.removeModelNodes) { @@ -436,11 +442,32 @@ void ModelPrivate::handleResourceSet(const ModelResourceSet &resourceSet) setBindingProperties(resourceSet.setExpressions); } +void ModelPrivate::updateModelNodeTypeIds(const TypeIds &removedTypeIds) +{ + auto nodes = m_nodes; + + std::ranges::sort(nodes, {}, &InternalNode::typeId); + + auto refeshNodeTypeId = [&](auto &node) { refreshTypeId(node.get()); }; + + Utils::set_greedy_intersection(nodes, removedTypeIds, refeshNodeTypeId, {}, &InternalNode::typeId); +} + void ModelPrivate::removedTypeIds(const TypeIds &removedTypeIds) { + updateModelNodeTypeIds(removedTypeIds); + notifyNodeInstanceViewLast([&](AbstractView *view) { view->refreshMetaInfos(removedTypeIds); }); } +void ModelPrivate::exportedTypesChanged() +{ + for (auto &node : m_nodes) { + if (!node->typeId) + refreshTypeId(node.get()); + } +} + void ModelPrivate::removeAllSubNodes(const InternalNodePointer &node) { for (const InternalNodePointer &subNode : node->allSubNodes()) @@ -1267,7 +1294,7 @@ void ModelPrivate::changeSelectedNodes(const QList &newSele QList ModelPrivate::selectedNodes() const { - for (const InternalNodePointer &node : std::as_const(m_selectedInternalNodeList)) { + for (const InternalNodePointer &node : m_selectedInternalNodeList) { if (!node->isValid) return {}; } @@ -1661,11 +1688,15 @@ QList ModelPrivate::allNodesOrdered() const nodeList.append(m_rootInternalNode); nodeList.append(m_rootInternalNode->allSubNodes()); // FIXME: This is horribly expensive compared to a loop. - nodeList.append(Utils::toList(Utils::toSet(m_nodes) - Utils::toSet(nodeList))); + + auto nodesSorted = nodeList; + std::ranges::sort(nodesSorted); + std::ranges::set_difference(m_nodes, nodesSorted, std::back_inserter(nodeList)); return nodeList; } -QList ModelPrivate::allNodesUnordered() const + +std::vector ModelPrivate::allNodesUnordered() const { return m_nodes; } @@ -2660,17 +2691,6 @@ void Model::detachView(AbstractView *view, ViewNotification emitDetachNotify) d->detachView(view, emitNotify); } -namespace { -QList toModelNodeList(const QList &nodeList, Model *model) -{ - QList newNodeList; - for (const Internal::InternalNode::Pointer &node : nodeList) - newNodeList.append(ModelNode(node, model, nullptr)); - - return newNodeList; -} -} // namespace - QList Model::allModelNodesUnordered() { return toModelNodeList(d->allNodesUnordered(), this); diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h index 5e24d82e1f2..471da6ea80b 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/designercore/model/model_p.h @@ -293,7 +293,7 @@ public: InternalNodePointer nodeForInternalId(qint32 internalId) const; bool hasNodeForInternalId(qint32 internalId) const; - QList allNodesUnordered() const; + std::vector allNodesUnordered() const; QList allNodesOrdered() const; bool isWriteLocked() const; @@ -316,8 +316,11 @@ public: return m_nodeMetaInfoCache; } + void updateModelNodeTypeIds(const TypeIds &removedTypeIds); + protected: void removedTypeIds(const TypeIds &removedTypeIds) override; + void exportedTypesChanged() override; void removeNode(const InternalNodePointer &node); private: @@ -333,6 +336,7 @@ private: toInternalBindingProperties(const ModelResourceSet::SetExpressions &setExpressions); ImportedTypeNameId importedTypeNameId(Utils::SmallStringView typeName); void setTypeId(InternalNode *node, Utils::SmallStringView typeName); + void refreshTypeId(InternalNode *node); public: NotNullPointer projectStorage = nullptr; @@ -351,7 +355,7 @@ private: QList m_selectedInternalNodeList; QHash m_idNodeHash; QHash m_internalIdNodeHash; - QList m_nodes; + std::vector m_nodes; InternalNodePointer m_currentStateNode; InternalNodePointer m_rootInternalNode; InternalNodePointer m_currentTimelineNode; diff --git a/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp b/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp index eb5373b35a2..5dc72fad1d3 100644 --- a/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp @@ -22,6 +22,8 @@ QT_WARNING_DISABLE_GCC("-Wmissing-field-initializers") namespace QmlDesigner { +ModelResourceManagementInterface::~ModelResourceManagementInterface() = default; + namespace { enum class CheckRecursive { No, Yes }; @@ -257,16 +259,6 @@ struct NodeDependency { return std::tie(first.target, first.source) < std::tie(second.target, second.source); } - - friend bool operator<(const NodeDependency &first, const ModelNode &second) - { - return first.target < second; - } - - friend bool operator<(const ModelNode &first, const NodeDependency &second) - { - return first < second.target; - } }; using NodeDependencies = std::vector; @@ -280,16 +272,6 @@ struct BindingDependency { return std::tie(first.target, first.property) < std::tie(second.target, second.property); } - - friend bool operator<(const BindingDependency &first, const ModelNode &second) - { - return first.target < second; - } - - friend bool operator<(const ModelNode &first, const BindingDependency &second) - { - return first < second.target; - } }; using BindingDependencies = std::vector; @@ -322,18 +304,18 @@ struct NodesProperty using NodesProperties = std::vector; +#include struct RemoveDependentBindings : public Base { AbstractProperties collectProperties(const ModelNodes &nodes) { AbstractProperties properties; - ::Utils::set_greedy_intersection(dependencies.begin(), - dependencies.end(), - nodes.begin(), - nodes.end(), - ::Utils::make_iterator([&](const BindingDependency &dependency) { - properties.push_back(dependency.property); - })); + Utils::set_greedy_intersection( + dependencies, + nodes, + [&](const BindingDependency &dependency) { properties.push_back(dependency.property); }, + {}, + &BindingDependency::target); return properties; } @@ -352,13 +334,12 @@ struct RemoveDependencies : public Base ModelNodes collectNodes(const ModelNodes &nodes) const { ModelNodes targetNodes; - ::Utils::set_greedy_intersection(dependencies.begin(), - dependencies.end(), - nodes.begin(), - nodes.end(), - ::Utils::make_iterator([&](const NodeDependency &dependency) { - targetNodes.push_back(dependency.source); - })); + ::Utils::set_greedy_intersection( + dependencies, + nodes, + [&](const NodeDependency &dependency) { targetNodes.push_back(dependency.source); }, + {}, + &NodeDependency::target); return targetNodes; } @@ -392,15 +373,14 @@ struct RemoveTargetsSources : public Base { NodesProperties removedTargetNodesInProperties; - ModelNodes targetNodes; - ::Utils::set_greedy_intersection(dependencies.begin(), - dependencies.end(), - nodes.begin(), - nodes.end(), - ::Utils::make_iterator([&](const NodeDependency &dependency) { - removeDependency(removedTargetNodesInProperties, - dependency); - })); + Utils::set_greedy_intersection( + dependencies, + nodes, + [&](const NodeDependency &dependency) { + removeDependency(removedTargetNodesInProperties, dependency); + }, + {}, + &NodeDependency::target); std::sort(removedTargetNodesInProperties.begin(), removedTargetNodesInProperties.end()); diff --git a/src/plugins/qmldesigner/designercore/model/modelresourcemanagementinterface.h b/src/plugins/qmldesigner/designercore/model/modelresourcemanagementinterface.h index 94047d95b0d..8e467b1b593 100644 --- a/src/plugins/qmldesigner/designercore/model/modelresourcemanagementinterface.h +++ b/src/plugins/qmldesigner/designercore/model/modelresourcemanagementinterface.h @@ -16,7 +16,7 @@ class QMLDESIGNERCORE_EXPORT ModelResourceManagementInterface { public: ModelResourceManagementInterface() = default; - virtual ~ModelResourceManagementInterface() = default; + virtual ~ModelResourceManagementInterface(); ModelResourceManagementInterface(const ModelResourceManagementInterface &) = delete; ModelResourceManagementInterface &operator=(const ModelResourceManagementInterface &) = delete; diff --git a/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp b/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp index 66d9974f217..668959f0a18 100644 --- a/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp @@ -177,11 +177,9 @@ QList NodeAbstractProperty::directSubNodes() const switch (property->type()) { case PropertyType::Node: - return QmlDesigner::toModelNodeList({property->to()->node()}, - model(), - view()); + return ModelNodes{ModelNode(property->to()->node(), model(), view())}; case PropertyType::NodeList: - return QmlDesigner::toModelNodeList({property->to()->nodes()}, + return QmlDesigner::toModelNodeList(property->to()->nodes(), model(), view()); case PropertyType::Binding: diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp index cd1647c4034..698829aac26 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp @@ -1298,6 +1298,8 @@ void ProjectStorage::synchronize(Storage::Synchronization::SynchronizationPackag NanotraceHR::Tracer tracer{"synchronize"_t, projectStorageCategory()}; TypeIds deletedTypeIds; + ExportedTypesChanged exportedTypesChanged = ExportedTypesChanged::No; + Sqlite::withImmediateTransaction(database, [&] { AliasPropertyDeclarations aliasPropertyDeclarationsToLink; @@ -1329,6 +1331,7 @@ void ProjectStorage::synchronize(Storage::Synchronization::SynchronizationPackag relinkablePropertyDeclarations, relinkablePrototypes, relinkableExtensions, + exportedTypesChanged, package.updatedSourceIds); synchronizeTypeAnnotations(package.typeAnnotations, package.updatedTypeAnnotationSourceIds); synchronizePropertyEditorQmlPaths(package.propertyEditorQmlPaths, @@ -1358,7 +1361,7 @@ void ProjectStorage::synchronize(Storage::Synchronization::SynchronizationPackag commonTypeCache_.resetTypeIds(); }); - callRefreshMetaInfoCallback(deletedTypeIds); + callRefreshMetaInfoCallback(deletedTypeIds, exportedTypesChanged); } void ProjectStorage::synchronizeDocumentImports(Storage::Imports imports, SourceId sourceId) @@ -2383,6 +2386,7 @@ void ProjectStorage::resetForTestsOnly() database.clearAllTablesForTestsOnly(); commonTypeCache_.clearForTestsOnly(); moduleCache.clearForTestOnly(); + observers.clear(); } ModuleId ProjectStorage::fetchModuleId(Utils::SmallStringView moduleName, @@ -2425,7 +2429,8 @@ ProjectStorage::ModuleCacheEntries ProjectStorage::fetchAllModules() const return s->selectAllModulesStatement.valuesWithTransaction(); } -void ProjectStorage::callRefreshMetaInfoCallback(const TypeIds &deletedTypeIds) +void ProjectStorage::callRefreshMetaInfoCallback(TypeIds &deletedTypeIds, + ExportedTypesChanged &exportedTypesChanged) { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"call refresh meta info callback"_t, @@ -2433,9 +2438,16 @@ void ProjectStorage::callRefreshMetaInfoCallback(const TypeIds &deletedTypeIds) keyValue("type ids", deletedTypeIds)}; if (deletedTypeIds.size()) { + std::ranges::sort(deletedTypeIds); + for (ProjectStorageObserver *observer : observers) observer->removedTypeIds(deletedTypeIds); } + + if (exportedTypesChanged == ExportedTypesChanged::Yes) { + for (ProjectStorageObserver *observer : observers) + observer->exportedTypesChanged(); + } } SourceIds ProjectStorage::filterSourceIdsWithoutType(const SourceIds &updatedSourceIds, @@ -2598,6 +2610,7 @@ void ProjectStorage::synchronizeTypes(Storage::Synchronization::Types &types, PropertyDeclarations &relinkablePropertyDeclarations, Prototypes &relinkablePrototypes, Prototypes &relinkableExtensions, + ExportedTypesChanged &exportedTypesChanged, const SourceIds &updatedSourceIds) { NanotraceHR::Tracer tracer{"synchronize types"_t, projectStorageCategory()}; @@ -2641,7 +2654,8 @@ void ProjectStorage::synchronizeTypes(Storage::Synchronization::Types &types, relinkableAliasPropertyDeclarations, relinkablePropertyDeclarations, relinkablePrototypes, - relinkableExtensions); + relinkableExtensions, + exportedTypesChanged); syncPrototypesAndExtensions(types, relinkablePrototypes, relinkableExtensions); resetDefaultPropertiesIfChanged(types); @@ -3393,7 +3407,8 @@ void ProjectStorage::synchronizeExportedTypes(const TypeIds &updatedTypeIds, AliasPropertyDeclarations &relinkableAliasPropertyDeclarations, PropertyDeclarations &relinkablePropertyDeclarations, Prototypes &relinkablePrototypes, - Prototypes &relinkableExtensions) + Prototypes &relinkableExtensions, + ExportedTypesChanged &exportedTypesChanged) { using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"synchronize exported types"_t, projectStorageCategory()}; @@ -3474,6 +3489,8 @@ void ProjectStorage::synchronizeExportedTypes(const TypeIds &updatedTypeIds, relinkableAliasPropertyDeclarations); handlePrototypesWithExportedTypeNameAndTypeId(type.name, unresolvedTypeId, relinkablePrototypes); handleExtensionsWithExportedTypeNameAndTypeId(type.name, unresolvedTypeId, relinkableExtensions); + + exportedTypesChanged = ExportedTypesChanged::Yes; }; auto update = [&](const Storage::Synchronization::ExportedTypeView &view, @@ -3492,6 +3509,8 @@ void ProjectStorage::synchronizeExportedTypes(const TypeIds &updatedTypeIds, handlePrototypes(view.typeId, relinkablePrototypes); handleExtensions(view.typeId, relinkableExtensions); s->updateExportedTypeNameTypeIdStatement.write(view.exportedTypeNameId, type.typeId); + exportedTypesChanged = ExportedTypesChanged::Yes; + return Sqlite::UpdateChange::Update; } return Sqlite::UpdateChange::No; @@ -3511,6 +3530,8 @@ void ProjectStorage::synchronizeExportedTypes(const TypeIds &updatedTypeIds, handleExtensions(view.typeId, relinkableExtensions); s->deleteExportedTypeNameStatement.write(view.exportedTypeNameId); + + exportedTypesChanged = ExportedTypesChanged::Yes; }; Sqlite::insertUpdateDelete(range, exportedTypes, compareKey, insert, update, remove); diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h index 7e3a214f53d..3da9305e04b 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h @@ -339,7 +339,10 @@ private: ModuleCacheEntries fetchAllModules() const; - void callRefreshMetaInfoCallback(const TypeIds &deletedTypeIds); + enum class ExportedTypesChanged { No, Yes }; + + void callRefreshMetaInfoCallback(TypeIds &deletedTypeIds, + ExportedTypesChanged &exportedTypesChanged); class AliasPropertyDeclaration { @@ -610,6 +613,7 @@ private: PropertyDeclarations &relinkablePropertyDeclarations, Prototypes &relinkablePrototypes, Prototypes &relinkableExtensions, + ExportedTypesChanged &exportedTypesChanged, const SourceIds &updatedSourceIds); void synchronizeDirectoryInfos(Storage::Synchronization::DirectoryInfos &directoryInfos, @@ -710,7 +714,8 @@ private: AliasPropertyDeclarations &relinkableAliasPropertyDeclarations, PropertyDeclarations &relinkablePropertyDeclarations, Prototypes &relinkablePrototypes, - Prototypes &relinkableExtensions); + Prototypes &relinkableExtensions, + ExportedTypesChanged &exportedTypesChanged); void synchronizePropertyDeclarationsInsertAlias( AliasPropertyDeclarations &insertedAliasPropertyDeclarations, diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageobserver.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageobserver.h index c3393c91d4c..5beadc0472d 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageobserver.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageobserver.h @@ -11,5 +11,6 @@ class ProjectStorageObserver { public: virtual void removedTypeIds(const TypeIds &removedTypeIds) = 0; + virtual void exportedTypesChanged() = 0; }; } // namespace QmlDesigner diff --git a/tests/unit/tests/mocks/projectstoragemock.cpp b/tests/unit/tests/mocks/projectstoragemock.cpp index d4a28d1ae6f..1d3a5f58cd2 100644 --- a/tests/unit/tests/mocks/projectstoragemock.cpp +++ b/tests/unit/tests/mocks/projectstoragemock.cpp @@ -63,9 +63,8 @@ ModuleId ProjectStorageMock::createModule(Utils::SmallStringView moduleName, QmlDesigner::ImportedTypeNameId ProjectStorageMock::createImportedTypeNameId( SourceId sourceId, Utils::SmallStringView typeName, TypeId typeId) { - if (auto id = importedTypeNameId(sourceId, typeName)) { + if (auto id = importedTypeNameId(sourceId, typeName)) return id; - } static ImportedTypeNameId importedTypeNameId; incrementBasicId(importedTypeNameId); @@ -78,6 +77,12 @@ QmlDesigner::ImportedTypeNameId ProjectStorageMock::createImportedTypeNameId( return importedTypeNameId; } +void ProjectStorageMock::refreshImportedTypeNameId(QmlDesigner::ImportedTypeNameId importedTypeId, + TypeId typeId) +{ + ON_CALL(*this, typeId(importedTypeId)).WillByDefault(Return(typeId)); +} + QmlDesigner::ImportedTypeNameId ProjectStorageMock::createImportedTypeNameId( QmlDesigner::SourceId sourceId, Utils::SmallStringView typeName, QmlDesigner::ModuleId moduleId) { @@ -382,6 +387,14 @@ ProjectStorageMock::ProjectStorageMock() ON_CALL(*this, exportedTypeNames(_, _)).WillByDefault([&](TypeId typeId, SourceId sourceId) { return exportedTypeNameBySourceId[{typeId, sourceId}]; }); + + ON_CALL(*this, addObserver(_)).WillByDefault([&](auto observer) { + observers.push_back(observer); + }); + + ON_CALL(*this, removeObserver(_)).WillByDefault([&](auto observer) { + std::erase(observers, observer); + }); } void ProjectStorageMock::setupQtQuick() diff --git a/tests/unit/tests/mocks/projectstoragemock.h b/tests/unit/tests/mocks/projectstoragemock.h index b74949510b6..ef9b4e87b20 100644 --- a/tests/unit/tests/mocks/projectstoragemock.h +++ b/tests/unit/tests/mocks/projectstoragemock.h @@ -29,7 +29,6 @@ public: QmlDesigner::ImportedTypeNameId createImportedTypeNameId(QmlDesigner::SourceId sourceId, Utils::SmallStringView typeName, QmlDesigner::TypeId typeId); - QmlDesigner::ImportedTypeNameId createImportedTypeNameId(QmlDesigner::SourceId sourceId, Utils::SmallStringView typeName, QmlDesigner::ModuleId moduleId); @@ -37,6 +36,7 @@ public: QmlDesigner::ImportedTypeNameId createImportedTypeNameId(QmlDesigner::ImportId importId, Utils::SmallStringView typeName, QmlDesigner::TypeId typeId); + void refreshImportedTypeNameId(QmlDesigner::ImportedTypeNameId, QmlDesigner::TypeId typeId); QmlDesigner::ImportId createImportId( QmlDesigner::ModuleId moduleId, @@ -357,6 +357,7 @@ public: std::map exportedTypeName; std::map, QmlDesigner::Storage::Info::ExportedTypeNames> exportedTypeNameBySourceId; + std::vector observers; }; class ProjectStorageMockWithQtQuick : public ProjectStorageMock diff --git a/tests/unit/tests/mocks/projectstorageobservermock.h b/tests/unit/tests/mocks/projectstorageobservermock.h index 93a14bc09d0..1f98ecae3bb 100644 --- a/tests/unit/tests/mocks/projectstorageobservermock.h +++ b/tests/unit/tests/mocks/projectstorageobservermock.h @@ -11,4 +11,5 @@ class ProjectStorageObserverMock : public QmlDesigner::ProjectStorageObserver { public: MOCK_METHOD(void, removedTypeIds, (const QmlDesigner::TypeIds &), (override)); + MOCK_METHOD(void, exportedTypesChanged, (), (override)); }; diff --git a/tests/unit/tests/unittests/model/model-test.cpp b/tests/unit/tests/unittests/model/model-test.cpp index 3c70993681f..7b93b21bb35 100644 --- a/tests/unit/tests/unittests/model/model-test.cpp +++ b/tests/unit/tests/unittests/model/model-test.cpp @@ -128,10 +128,11 @@ protected: resourceManagementMock)}; NiceMock viewMock; QmlDesigner::SourceId filePathId = pathCacheMock.sourceId; - QmlDesigner::TypeId itemTypeId = projectStorageMock.typeId( - projectStorageMock.moduleId("QtQuick", ModuleKind::QmlLibrary), - "Item", - QmlDesigner::Storage::Version{}); + QmlDesigner::ModuleId qtQuickModuleId = projectStorageMock.moduleId("QtQuick", + ModuleKind::QmlLibrary); + QmlDesigner::TypeId itemTypeId = projectStorageMock.typeId(qtQuickModuleId, + "Item", + QmlDesigner::Storage::Version{}); QmlDesigner::ImportedTypeNameId itemTypeNameId = projectStorageMock.createImportedTypeNameId( filePathId, "Item", itemTypeId); ModelNode rootNode; @@ -1039,4 +1040,59 @@ TEST_F(Model, item_library_entries) ElementsAre(u"/extra/file/path")))); } +TEST_F(Model, create_node_resolved_meta_type) +{ + auto node = model.createModelNode("Item"); + + ASSERT_THAT(node.metaInfo(), model.qtQuickItemMetaInfo()); +} + +TEST_F(Model, create_node_has_unresolved_meta_type_for_invalid_type_name) +{ + auto node = model.createModelNode("Foo"); + + ASSERT_THAT(node.metaInfo(), IsFalse()); +} + +TEST_F(Model, refresh_type_id_if_project_storage_removed_type_id) +{ + auto node = model.createModelNode("Item"); + projectStorageMock.removeType(qtQuickModuleId, "Item"); + auto observer = projectStorageMock.observers.front(); + auto itemTypeId2 = projectStorageMock.createObject(qtQuickModuleId, "Item"); + projectStorageMock.refreshImportedTypeNameId(itemTypeNameId, itemTypeId2); + + observer->removedTypeIds({itemTypeId}); + + ASSERT_THAT(node.metaInfo().id(), itemTypeId2); +} + +TEST_F(Model, set_null_type_id_if_project_storage_removed_type_id_cannot_be_refreshed) +{ + auto node = model.createModelNode("Item"); + projectStorageMock.removeType(qtQuickModuleId, "Item"); + projectStorageMock.refreshImportedTypeNameId(itemTypeNameId, QmlDesigner::TypeId{}); + + auto observer = projectStorageMock.observers.front(); + + observer->removedTypeIds({itemTypeId}); + + ASSERT_THAT(node.metaInfo().id(), IsFalse()); +} + +TEST_F(Model, null_type_id_are_refreshed_if_exported_types_are_updated) +{ + auto node = model.createModelNode("Item"); + projectStorageMock.removeType(qtQuickModuleId, "Item"); + projectStorageMock.refreshImportedTypeNameId(itemTypeNameId, QmlDesigner::TypeId{}); + auto observer = projectStorageMock.observers.front(); + observer->removedTypeIds({itemTypeId}); + auto itemTypeId2 = projectStorageMock.createObject(qtQuickModuleId, "Item"); + projectStorageMock.refreshImportedTypeNameId(itemTypeNameId, itemTypeId2); + + observer->exportedTypesChanged(); + + ASSERT_THAT(node.metaInfo().id(), itemTypeId2); +} + } // namespace diff --git a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp index 5b9d0c8d059..2fa1042929a 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp @@ -8256,7 +8256,7 @@ TEST_F(ProjectStorage, synchronize_property_editor_with_non_existing_type_name) TEST_F(ProjectStorage, call_remove_type_ids_in_observer_after_synchronization) { auto package{createSimpleSynchronizationPackage()}; - ProjectStorageObserverMock observerMock; + NiceMock observerMock; storage.addObserver(&observerMock); storage.synchronize(package); package.types.clear(); @@ -8967,4 +8967,42 @@ TEST_F(ProjectStorage, added_document_import_fixes_unresolved_extension) ASSERT_THAT(fetchType(sourceId1, "QQuickItem"), HasExtensionId(fetchTypeId(sourceId2, "QObject"))); } +TEST_F(ProjectStorage, added_export_is_notifing_changed_exported_types) +{ + auto package{createSimpleSynchronizationPackage()}; + storage.synchronize(package); + package.types[1].exportedTypes.emplace_back(qmlNativeModuleId, "Objec"); + NiceMock observerMock; + storage.addObserver(&observerMock); + + EXPECT_CALL(observerMock, exportedTypesChanged()); + + storage.synchronize(std::move(package)); +} + +TEST_F(ProjectStorage, removed_export_is_notifing_changed_exported_types) +{ + auto package{createSimpleSynchronizationPackage()}; + storage.synchronize(package); + package.types[1].exportedTypes.pop_back(); + NiceMock observerMock; + storage.addObserver(&observerMock); + + EXPECT_CALL(observerMock, exportedTypesChanged()); + + storage.synchronize(std::move(package)); +} + +TEST_F(ProjectStorage, changed_export_is_notifing_changed_exported_types) +{ + auto package{createSimpleSynchronizationPackage()}; + storage.synchronize(package); + package.types[1].exportedTypes[1].name = "Obj2"; + NiceMock observerMock; + storage.addObserver(&observerMock); + + EXPECT_CALL(observerMock, exportedTypesChanged()); + + storage.synchronize(std::move(package)); +} } // namespace From e1936788e7d0210a99463f8f118ca53b2fc5a01d Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 14 Aug 2024 21:24:20 +0200 Subject: [PATCH 050/193] QmlDesigner: Use ranges::find C++ 20 ranges have projections and can handle ranges/containers. That can make find much more readable. Projections like std::ranges::find(preservedItems, curve->id(), &CurveItem::id) make it much more clear, that the member id in CurveItem is used for comparison. Some special code is needed because equal_to demands that types have a common reference. Because some types don't have, a specialization of std::basic_common_reference is needed. Change-Id: Ibcac7cae3d8e392712c206db9fcb9982826633c0 Reviewed-by: Thomas Hartmann --- src/libs/utils/smallstring.h | 9 ++++++ .../componentcore/changestyleaction.cpp | 18 +++++------ .../componentcore/modelnodeoperations.cpp | 9 +++--- .../propertycomponentgenerator.cpp | 4 +-- .../componentcore/svgpasteaction.cpp | 4 +-- .../components/componentcore/zoomaction.cpp | 8 +++-- .../components/curveeditor/animationcurve.cpp | 6 +--- .../curveeditor/detail/curveitem.cpp | 3 +- .../curveeditor/detail/graphicsview.cpp | 3 +- .../propertyeditor/gradientmodel.cpp | 4 +-- .../timelineeditor/timelinewidget.cpp | 9 ++---- .../designercoreutils/modelutils.cpp | 2 +- .../imagecache/imagecachegenerator.cpp | 2 +- .../designercore/include/auxiliarydata.h | 16 ++++++++-- .../designercore/metainfo/nodemetainfo.cpp | 8 ++--- .../designercore/model/abstractview.cpp | 9 ++---- .../designercore/model/internalnode.cpp | 30 ++++--------------- .../qmldesigner/designercore/model/model.cpp | 4 +-- .../model/modelresourcemanagement.cpp | 8 ++--- .../projectstorage/qmltypesparser.cpp | 8 ++--- .../qmldesigner/puppetenvironmentbuilder.cpp | 17 +++++------ 21 files changed, 76 insertions(+), 105 deletions(-) diff --git a/src/libs/utils/smallstring.h b/src/libs/utils/smallstring.h index f475186c486..56ab91a2f48 100644 --- a/src/libs/utils/smallstring.h +++ b/src/libs/utils/smallstring.h @@ -931,4 +931,13 @@ SmallString operator+(const char(&first)[Size], SmallStringView second) } // namespace Utils +namespace std { + +template class TQual, template class UQual> +struct basic_common_reference, Utils::BasicSmallString, TQual, UQual> +{ + using type = Utils::SmallStringView; +}; +} // namespace std + Q_DECLARE_METATYPE(Utils::SmallString) diff --git a/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp b/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp index 2bf06c1a1a6..51574c1195f 100644 --- a/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp +++ b/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp @@ -25,18 +25,16 @@ static QString styleConfigFileName(const QString &qmlFileName) if (qmlBuild) { const auto &environment = qmlBuild->environment(); - const auto &envVar = std::find_if( - std::begin(environment), std::end(environment), [](const auto &envVar) { - return (envVar.name == u"QT_QUICK_CONTROLS_CONF" - && envVar.operation != Utils::EnvironmentItem::SetDisabled); - }); + const auto &envVar = std::ranges::find_if(environment, [](const auto &envVar) { + return envVar.name == u"QT_QUICK_CONTROLS_CONF" + && envVar.operation != Utils::EnvironmentItem::SetDisabled; + }); if (envVar != std::end(environment)) { const auto &fileNames = currentProject->files(ProjectExplorer::Project::SourceFiles); - const auto &foundFile = std::find_if(std::begin(fileNames), - std::end(fileNames), - [&](const auto &fileName) { - return fileName.fileName() == envVar->value; - }); + const auto &foundFile = std::ranges::find(fileNames, + envVar->value, + &Utils::FilePath::fileName); + if (foundFile != std::end(fileNames)) return foundFile->toString(); } diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index cbe48ff5207..eb6c98ec3bc 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -1770,10 +1770,11 @@ void editInEffectComposer(const SelectionContext &selectionContext) bool isEffectComposerActivated() { const ExtensionSystem::PluginSpecs specs = ExtensionSystem::PluginManager::plugins(); - return std::find_if(specs.begin(), specs.end(), - [](ExtensionSystem::PluginSpec *spec) { - return spec->name() == "EffectComposer" && spec->isEffectivelyEnabled(); - }) + return std::ranges::find_if(specs, + [](ExtensionSystem::PluginSpec *spec) { + return spec->name() == "EffectComposer" + && spec->isEffectivelyEnabled(); + }) != specs.end(); } diff --git a/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp b/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp index 58326dc77a3..ce6fd7b4da9 100644 --- a/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp +++ b/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp @@ -311,9 +311,7 @@ void PropertyComponentGenerator::refreshMetaInfos(const TypeIds &deletedTypeIds) const PropertyComponentGenerator::Entry *PropertyComponentGenerator::findEntry(const NodeMetaInfo &type) const { - auto found = std::find_if(m_entries.begin(), m_entries.end(), [&](const auto &entry) { - return entry.type == type; - }); + auto found = std::ranges::find(m_entries, type, &Entry::type); if (found != m_entries.end()) return std::addressof(*found); diff --git a/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp b/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp index 7bcd6050869..358e3dd5bee 100644 --- a/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp +++ b/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp @@ -600,9 +600,7 @@ bool contains(const Container &c, const QStringView &stringView) { template auto findKey(const Container &c, const QStringView &key) { - return std::find_if(std::begin(c), std::end(c), [&](const auto &pair){ - return pair.first == key; - }); + return std::ranges::find(c, key, &std::iter_value_t::first); } template diff --git a/src/plugins/qmldesigner/components/componentcore/zoomaction.cpp b/src/plugins/qmldesigner/components/componentcore/zoomaction.cpp index a389442ec96..2fb05f23fdc 100644 --- a/src/plugins/qmldesigner/components/componentcore/zoomaction.cpp +++ b/src/plugins/qmldesigner/components/componentcore/zoomaction.cpp @@ -14,6 +14,7 @@ #include #include +#include namespace QmlDesigner { @@ -46,7 +47,7 @@ std::array ZoomAction::zoomLevels() int ZoomAction::indexOf(double zoom) { auto finder = [zoom](double val) { return qFuzzyCompare(val, zoom); }; - if (auto iter = std::find_if(m_zooms.begin(), m_zooms.end(), finder); iter != m_zooms.end()) + if (auto iter = std::ranges::find_if(m_zooms, finder); iter != m_zooms.end()) return static_cast(std::distance(m_zooms.begin(), iter)); return -1; @@ -77,7 +78,7 @@ double ZoomAction::setNextZoomFactor(double zoom) return zoom; auto greater = [zoom](double val) { return val > zoom; }; - if (auto iter = std::find_if(m_zooms.begin(), m_zooms.end(), greater); iter != m_zooms.end()) { + if (auto iter = std::ranges::find_if(m_zooms, greater); iter != m_zooms.end()) { auto index = std::distance(m_zooms.begin(), iter); m_combo->setCurrentIndex(static_cast(index)); m_combo->setToolTip(m_combo->currentText()); @@ -92,7 +93,8 @@ double ZoomAction::setPreviousZoomFactor(double zoom) return zoom; auto smaller = [zoom](double val) { return val < zoom; }; - if (auto iter = std::find_if(m_zooms.rbegin(), m_zooms.rend(), smaller); iter != m_zooms.rend()) { + if (auto iter = std::ranges::find_if(m_zooms | std::views::reverse, smaller); + iter != m_zooms.rend()) { auto index = std::distance(iter, m_zooms.rend() - 1); m_combo->setCurrentIndex(static_cast(index)); m_combo->setToolTip(m_combo->currentText()); diff --git a/src/plugins/qmldesigner/components/curveeditor/animationcurve.cpp b/src/plugins/qmldesigner/components/curveeditor/animationcurve.cpp index 712cb32c8da..e10d6d11f26 100644 --- a/src/plugins/qmldesigner/components/curveeditor/animationcurve.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/animationcurve.cpp @@ -331,11 +331,7 @@ void AnimationCurve::insert(double time) return; auto insertFrames = [this](std::array &&frames) { - auto samePosition = [frames](const Keyframe &frame) { - return frame.position() == frames[0].position(); - }; - - auto iter = std::find_if(m_frames.begin(), m_frames.end(), samePosition); + auto iter = std::ranges::find(m_frames, frames[0].position(), &Keyframe::position); if (iter != m_frames.end()) { auto erased = m_frames.erase(iter, iter + 2); m_frames.insert(erased, frames.begin(), frames.end()); diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp index da59b49884d..86916454ac0 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/curveitem.cpp @@ -299,8 +299,7 @@ QList CurveItem::handles() const CurveSegment CurveItem::segment(const KeyframeItem *keyframe, HandleItem::Slot slot) const { - auto finder = [keyframe](KeyframeItem *item) { return item == keyframe; }; - const auto iter = std::find_if(m_keyframes.cbegin(), m_keyframes.cend(), finder); + const auto iter = std::ranges::find(m_keyframes, keyframe); if (iter == m_keyframes.cend()) return CurveSegment(); diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp index be1b10d8655..385ebf62b61 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp @@ -303,8 +303,7 @@ void GraphicsView::updateSelection() std::vector preservedItems = m_scene->takePinnedItems(); std::vector deleteItems; for (auto *curve : m_model->selectedCurves()) { - auto finder = [curve](CurveItem *item) { return curve->id() == item->id(); }; - auto iter = std::find_if(preservedItems.begin(), preservedItems.end(), finder); + auto iter = std::ranges::find(preservedItems, curve->id(), &CurveItem::id); if (iter == preservedItems.end()) preservedItems.push_back(curve); else diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp index 8bedabd83a7..715d71db85b 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/gradientmodel.cpp @@ -216,9 +216,7 @@ template const ShapeGradientPropertyData *findGradientInArray(const GradientArrayType &array, const QmlDesigner::PropertyNameView propName) { - const auto found = std::find_if(std::begin(array), std::end(array), [&](const auto &entry) { - return entry.name == propName; - }); + const auto found = std::ranges::find(array, propName, &std::iter_value_t::name); if (found != std::end(array)) return std::addressof(*found); diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp index e540e92414d..1220712cf41 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp @@ -66,9 +66,7 @@ public: static qreal next(const QVector &vector, qreal current) { - auto iter = std::find_if(vector.cbegin(), vector.cend(), [&](qreal val) { - return val > current; - }); + auto iter = std::ranges::find_if(vector, [&](qreal val) { return val > current; }); if (iter != vector.end()) return *iter; return current; @@ -76,9 +74,8 @@ static qreal next(const QVector &vector, qreal current) static qreal previous(const QVector &vector, qreal current) { - auto iter = std::find_if(vector.rbegin(), vector.rend(), [&](qreal val) { - return val < current; - }); + auto iter = std::ranges::find_if(vector | std::views::reverse, + [&](qreal val) { return val < current; }); if (iter != vector.rend()) return *iter; return current; diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.cpp b/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.cpp index e392bffe730..36730ea5f8a 100644 --- a/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.cpp +++ b/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.cpp @@ -203,7 +203,7 @@ constexpr auto createBannedQmlIds() if (hasImport) return ::Utils::make_unexpected(ImportError::HasAlreadyImport); - auto foundModule = std::find_if(modules.begin(), modules.end(), [&](const Import &import) { + auto foundModule = std::ranges::find_if(modules, [&](const Import &import) { return hasName(import) && predicate(import); }); diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.cpp b/src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.cpp index 60b51130312..dd64ecdeb2b 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.cpp +++ b/src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.cpp @@ -51,7 +51,7 @@ void ImageCacheGenerator::generateImage(Utils::SmallStringView name, ensureThreadIsRunning(); - auto found = std::find_if(m_tasks.begin(), m_tasks.end(), [&](const Task &task) { + auto found = std::ranges::find_if(m_tasks, [&](const Task &task) { return task.filePath == name && task.extraId == extraId; }); diff --git a/src/plugins/qmldesigner/designercore/include/auxiliarydata.h b/src/plugins/qmldesigner/designercore/include/auxiliarydata.h index 6ed0ab8fa27..e5d9403d2cb 100644 --- a/src/plugins/qmldesigner/designercore/include/auxiliarydata.h +++ b/src/plugins/qmldesigner/designercore/include/auxiliarydata.h @@ -32,6 +32,8 @@ public: , name{NameType{other.name}} {} + operator BasicAuxiliaryDataKey() const { return {type, name}; } + public: AuxiliaryDataType type = AuxiliaryDataType::None; NameType name; @@ -57,8 +59,9 @@ bool operator!=(const BasicAuxiliaryDataKey &first, const BasicAuxiliaryD using AuxiliaryDataKey = BasicAuxiliaryDataKey; using AuxiliaryDataKeyView = BasicAuxiliaryDataKey; -using AuxiliaryDatas = std::vector>; -using AuxiliaryDatasView = Utils::span>; +using AuxiliaryData = std::pair; +using AuxiliaryDatas = std::vector; +using AuxiliaryDatasView = Utils::span; using AuxiliaryDatasForType = std::vector>; using PropertyValue = std::variant; @@ -93,3 +96,12 @@ QVariant getDefaultValueAsQVariant(const Type &key) } } // namespace QmlDesigner + +namespace std { + +template class TQual, template class UQual> +struct basic_common_reference, QmlDesigner::BasicAuxiliaryDataKey, TQual, UQual> +{ + using type = QmlDesigner::AuxiliaryDataKeyView; +}; +} // namespace std diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index 0a0e9e88604..4971f1bb80a 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -4569,11 +4569,9 @@ NodeMetaInfo NodeMetaInfo::commonBase(const NodeMetaInfo &metaInfo) const if (isValid() && metaInfo) { const auto firstTypeIds = m_projectStorage->prototypeAndSelfIds(m_typeId); const auto secondTypeIds = m_projectStorage->prototypeAndSelfIds(metaInfo.m_typeId); - auto found - = std::find_if(firstTypeIds.begin(), firstTypeIds.end(), [&](TypeId firstTypeId) { - return std::find(secondTypeIds.begin(), secondTypeIds.end(), firstTypeId) - != secondTypeIds.end(); - }); + auto found = std::ranges::find_if(firstTypeIds, [&](TypeId firstTypeId) { + return std::ranges::find(secondTypeIds, firstTypeId) != secondTypeIds.end(); + }); if (found != firstTypeIds.end()) { return NodeMetaInfo{*found, m_projectStorage}; diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index b67e87390f9..339b3234b6c 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -28,6 +28,7 @@ namespace QmlDesigner { using namespace NanotraceHR::Literals; using NanotraceHR::keyValue; +using namespace Qt::StringLiterals; /*! \class QmlDesigner::AbstractView @@ -798,9 +799,7 @@ static int getMinorVersionFromImport(const Model *model) { const Imports &imports = model->imports(); - auto found = std::find_if(imports.begin(), imports.end(), [](const auto &import) { - return import.url() == "QtQuick"; - }); + auto found = std::ranges::find(imports, "QtQuick"_L1, &Import::url); if (found != imports.end()) return found->minorVersion(); @@ -812,9 +811,7 @@ static int getMajorVersionFromImport(const Model *model) { const Imports &imports = model->imports(); - auto found = std::find_if(imports.begin(), imports.end(), [](const auto &import) { - return import.url() == "QtQuick"; - }); + auto found = std::ranges::find(imports, "QtQuick"_L1, &Import::url); if (found != imports.end()) return found->majorVersion(); diff --git a/src/plugins/qmldesigner/designercore/model/internalnode.cpp b/src/plugins/qmldesigner/designercore/model/internalnode.cpp index 4211633d7c6..04bbe5154d9 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnode.cpp @@ -41,29 +41,9 @@ void InternalNode::resetParentProperty() m_parentProperty.reset(); } -namespace { - -template -auto find(Type &&auxiliaryDatas, AuxiliaryDataKeyView key) -{ - return std::find_if(auxiliaryDatas.begin(), auxiliaryDatas.end(), [&](const auto &element) { - return element.first == key; - }); -} - -template -auto find(Type &&auxiliaryDatas, AuxiliaryDataType type) -{ - return std::find_if(auxiliaryDatas.begin(), auxiliaryDatas.end(), [&](const auto &element) { - return element.first.type == type; - }); -} - -} // namespace - std::optional InternalNode::auxiliaryData(AuxiliaryDataKeyView key) const { - auto found = find(m_auxiliaryDatas, key); + auto found = std::ranges::find(m_auxiliaryDatas, key, &AuxiliaryData::first); if (found != m_auxiliaryDatas.end()) return found->second; @@ -73,7 +53,7 @@ std::optional InternalNode::auxiliaryData(AuxiliaryDataKeyView key) co bool InternalNode::setAuxiliaryData(AuxiliaryDataKeyView key, const QVariant &data) { - auto found = find(m_auxiliaryDatas, key); + auto found = std::ranges::find(m_auxiliaryDatas, key, &AuxiliaryData::first); if (found != m_auxiliaryDatas.end()) { if (found->second == data) @@ -88,7 +68,7 @@ bool InternalNode::setAuxiliaryData(AuxiliaryDataKeyView key, const QVariant &da bool InternalNode::removeAuxiliaryData(AuxiliaryDataKeyView key) { - auto found = find(m_auxiliaryDatas, key); + auto found = std::ranges::find(m_auxiliaryDatas, key, &AuxiliaryData::first); if (found == m_auxiliaryDatas.end()) return false; @@ -102,14 +82,14 @@ bool InternalNode::removeAuxiliaryData(AuxiliaryDataKeyView key) bool InternalNode::hasAuxiliaryData(AuxiliaryDataKeyView key) const { - auto found = find(m_auxiliaryDatas, key); + auto found = std::ranges::find(m_auxiliaryDatas, key, &AuxiliaryData::first); return found != m_auxiliaryDatas.end(); } bool InternalNode::hasAuxiliaryData(AuxiliaryDataType type) const { - auto found = find(m_auxiliaryDatas, type); + auto found = std::ranges::find(m_auxiliaryDatas, type, [](const auto &e) { return e.first.type; }); return found != m_auxiliaryDatas.end(); } diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 1a7cd269306..32b797626ee 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -395,9 +395,7 @@ ImportedTypeNameId ModelPrivate::importedTypeNameId(Utils::SmallStringView typeN if (moduleName.size()) { QString aliasName = QString{moduleName}; - auto found = std::find_if(m_imports.begin(), m_imports.end(), [&](const Import &import) { - return import.alias() == aliasName; - }); + auto found = std::ranges::find(m_imports, aliasName, &Import::alias); if (found != m_imports.end()) { using Storage::ModuleKind; auto moduleKind = found->isLibraryImport() ? ModuleKind::QmlLibrary diff --git a/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp b/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp index 5dc72fad1d3..3199a06326d 100644 --- a/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp @@ -357,11 +357,9 @@ struct RemoveTargetsSources : public Base static void removeDependency(NodesProperties &removedTargetNodesInProperties, const NodeDependency &dependency) { - auto found = std::find_if(removedTargetNodesInProperties.begin(), - removedTargetNodesInProperties.end(), - [&](const auto &nodeProperty) { - return nodeProperty.source == dependency.source; - }); + auto found = std::ranges::find(removedTargetNodesInProperties, + dependency.source, + &NodesProperty::source); if (found == removedTargetNodesInProperties.end()) removedTargetNodesInProperties.push_back({dependency.source, "", {dependency.target}}); diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp index 228609a9ce8..0907c846cf6 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp @@ -66,9 +66,7 @@ const Storage::Import &appendImports(Storage::Imports &imports, SourceId sourceId, QmlTypesParser::ProjectStorage &storage) { - auto spaceFound = std::find_if(dependency.begin(), dependency.end(), [](QChar c) { - return c.isSpace(); - }); + auto spaceFound = std::ranges::find_if(dependency, [](QChar c) { return c.isSpace(); }); Utils::PathString moduleName{QStringView(dependency.begin(), spaceFound)}; ModuleId cppModuleId = storage.moduleId(moduleName, ModuleKind::CppLibrary); @@ -242,9 +240,7 @@ Storage::Synchronization::PropertyDeclarations createProperties( TypeNameString propertyTypeName{ fullyQualifiedTypeName(qmlProperty.typeName(), componentNameWithoutNamespace)}; - auto found = find_if(enumerationTypes.begin(), enumerationTypes.end(), [&](auto &entry) { - return entry.name == propertyTypeName; - }); + auto found = std::ranges::find(enumerationTypes, propertyTypeName, &EnumerationType::name); if (found != enumerationTypes.end()) propertyTypeName = found->full; diff --git a/src/plugins/qmldesigner/puppetenvironmentbuilder.cpp b/src/plugins/qmldesigner/puppetenvironmentbuilder.cpp index 41f9fd80067..edf8aee6198 100644 --- a/src/plugins/qmldesigner/puppetenvironmentbuilder.cpp +++ b/src/plugins/qmldesigner/puppetenvironmentbuilder.cpp @@ -86,19 +86,16 @@ QString PuppetEnvironmentBuilder::getStyleConfigFileName() const m_target->buildSystem()); if (qmlBuild) { const auto &environment = qmlBuild->environment(); - const auto &envVar = std::find_if( - std::begin(environment), std::end(environment), [](const auto &envVar) { - return (envVar.name == u"QT_QUICK_CONTROLS_CONF" - && envVar.operation != Utils::EnvironmentItem::SetDisabled); - }); + const auto &envVar = std::ranges::find_if(environment, [](const auto &envVar) { + return envVar.name == u"QT_QUICK_CONTROLS_CONF" + && envVar.operation != Utils::EnvironmentItem::SetDisabled; + }); if (envVar != std::end(environment)) { const auto &sourceFiles = m_target->project()->files( ProjectExplorer::Project::SourceFiles); - const auto &foundFile = std::find_if(std::begin(sourceFiles), - std::end(sourceFiles), - [&](const auto &fileName) { - return fileName.fileName() == envVar->value; - }); + const auto &foundFile = std::ranges::find(sourceFiles, + envVar->value, + &Utils::FilePath::fileName); if (foundFile != std::end(sourceFiles)) return foundFile->toString(); } From d323d8aeb60f80f04d282a44191969f563925ec2 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 15 Aug 2024 08:10:35 +0200 Subject: [PATCH 051/193] QmlDesigner: Use more set_greedy_intersection overloads Change-Id: I224a5e577545d7dab3825a6b728bbc88c6e8c6b5 Reviewed-by: Thomas Hartmann --- src/libs/utils/set_algorithm.h | 82 ++++++++++++------- .../model/modelresourcemanagement.cpp | 10 +-- 2 files changed, 57 insertions(+), 35 deletions(-) diff --git a/src/libs/utils/set_algorithm.h b/src/libs/utils/set_algorithm.h index 92b6ae0a37a..5c6f8d675eb 100644 --- a/src/libs/utils/set_algorithm.h +++ b/src/libs/utils/set_algorithm.h @@ -82,35 +82,6 @@ bool set_intersection_compare( return false; } -template -bool set_greedy_intersection_compare( - InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable call, Compare comp) -{ - while (first1 != last1 && first2 != last2) { - if (comp(*first1, *first2)) { - ++first1; - } else { - if (!comp(*first2, *first1)) { - if constexpr (std::is_void_v>) { - call(*first1, *first2); - ++first1; - } else { - auto success = call(*first1, *first2); - ++first1; - if (success) - return true; - } - } else { - ++first2; - } - } - } - - return false; -} - template void set_greedy_difference( InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable call, Compare comp) @@ -196,6 +167,59 @@ struct set_greedy_intersection_functor std::move(proj1), std::move(proj2)); } + + template Sentinel1, + std::input_iterator Iterator2, + std::sentinel_for Sentinel2, + std::invocable &, std::iter_value_t &> Callable, + typename Comp = std::ranges::less, + typename Projection1 = std::identity, + typename Projection2 = std::identity> + requires callmergeable + constexpr void operator()(Iterator1 first1, + Sentinel1 last1, + Iterator2 first2, + Sentinel2 last2, + Callable callable, + Comp comp = {}, + Projection1 proj1 = {}, + Projection2 proj2 = {}) const + { + while (first1 != last1 && first2 != last2) + if (std::invoke(comp, std::invoke(proj1, *first1), std::invoke(proj2, *first2))) + ++first1; + else if (std::invoke(comp, std::invoke(proj2, *first2), std::invoke(proj1, *first1))) + ++first2; + else { + std::invoke(callable, *first1, *first2); + ++first1; + } + } + + template &, std::iter_value_t &> Callable, + typename Comp = std::ranges::less, + typename Projection1 = std::identity, + typename Projection2 = std::identity> + requires callmergeable, std::ranges::iterator_t, Comp, Projection1, Projection2> + constexpr void operator()(Range1 &&range1, + Range2 &&range2, + Callable callable, + Comp comp = {}, + Projection1 proj1 = {}, + Projection2 proj2 = {}) const + { + (*this)(std::ranges::begin(range1), + std::ranges::end(range1), + std::ranges::begin(range2), + std::ranges::end(range2), + std::move(callable), + std::move(comp), + std::move(proj1), + std::move(proj2)); + } }; inline constexpr set_greedy_intersection_functor set_greedy_intersection{}; diff --git a/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp b/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp index 3199a06326d..550d5a2626c 100644 --- a/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp @@ -619,12 +619,10 @@ struct TransitionFilter dependencies.push_back({second.node, first.node}); }; - ::Utils::set_greedy_intersection_compare(transitionNodes.begin(), - transitionNodes.end(), - stateNodes.begin(), - stateNodes.end(), - removeTransition, - std::less{}); + Utils::set_greedy_intersection(transitionNodes, + stateNodes, + removeTransition, + std::less{}); std::sort(dependencies.begin(), dependencies.end()); } From aa497b03e364bf06c08e54ca04e1f4ccf94ac5de Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 15 Aug 2024 09:13:28 +0200 Subject: [PATCH 052/193] QmlDesigner: Split source path storage from project storage The source ids are never resolved internally in the project storage. They are an opaque integer handle. Sharing the source ids between different projects can reduce the storage size and prevents bugs by accidential sharing of worng source ids between projects. Task-number: QDS-13388 Change-Id: I9e3c839cc1b07cef01d6147847026f57845d5a91 Reviewed-by: Thomas Hartmann --- src/libs/nanotrace/nanotracehr.h | 5 + src/plugins/qmldesigner/CMakeLists.txt | 43 ++- .../propertyeditorqmlbackend.cpp | 2 +- .../propertyeditor/propertyeditorview.cpp | 2 +- .../designercoreutils/modelutils.cpp | 3 +- .../include/externaldependenciesinterface.h | 4 + .../designercore/include/modelfwd.h | 4 +- .../designercore/include/projectstorageids.h | 45 +-- .../designercore/include/sourcepathids.h | 35 +++ .../qmldesigner/designercore/model/model.cpp | 4 +- .../projectstorage/filesystem.cpp | 2 +- .../designercore/projectstorage/filesystem.h | 13 +- .../projectstorage/projectstorage.cpp | 234 +-------------- .../projectstorage/projectstorage.h | 29 +- .../projectstorageerrornotifier.cpp | 2 +- .../projectstorageexceptions.cpp | 40 --- .../projectstorage/projectstorageexceptions.h | 28 -- .../projectstorage/projectstoragefwd.h | 1 - .../projectstoragepathwatcher.h | 3 +- .../projectstorage/projectstorageupdater.cpp | 4 +- .../projectstorage/projectstorageupdater.h | 7 +- .../projectstorage/qmldocumentparser.cpp | 2 +- .../projectstorage/qmldocumentparser.h | 7 +- .../projectstorage/qmltypesparser.h | 2 +- .../nonlockingmutex.h | 0 .../sourcepath.h | 0 .../sourcepathcache.h | 20 +- .../sourcepathcacheinterface.h | 0 .../sourcepathcachetypes.h | 0 .../sourcepathexceptions.cpp | 59 ++++ .../sourcepathstorage/sourcepathexceptions.h | 51 ++++ .../sourcepathstorage/sourcepathstorage.cpp | 277 ++++++++++++++++++ .../sourcepathstorage/sourcepathstorage.h | 65 ++++ .../sourcepathview.h | 0 .../storagecache.h | 3 +- .../storagecacheentry.h | 0 .../storagecachefwd.h | 0 .../tracing/qmldesignertracing.cpp | 11 + .../designercore/tracing/qmldesignertracing.h | 16 + .../qmldesignerexternaldependencies.cpp | 5 + .../qmldesignerexternaldependencies.h | 1 + .../qmldesigner/qmldesignerprojectmanager.cpp | 71 +++-- .../qmldesigner/qmldesignerprojectmanager.h | 2 + .../qmldesigner/coretests/tst_testcore.cpp | 3 + .../tests/mocks/externaldependenciesmock.h | 1 + tests/unit/tests/mocks/projectstoragemock.h | 2 +- tests/unit/tests/mocks/sourcepathcachemock.h | 6 +- .../tests/mocks/sqlitereadstatementmock.h | 2 +- .../tests/printers/gtest-creator-printing.cpp | 2 +- .../tests/testdesignercore/CMakeLists.txt | 22 +- tests/unit/tests/unittests/CMakeLists.txt | 1 + .../unittests/projectstorage/CMakeLists.txt | 4 - .../projectstorage/projectstorage-test.cpp | 182 +----------- .../projectstoragepathwatcher-test.cpp | 9 +- .../projectstorageupdater-test.cpp | 17 +- .../projectstorage/qmldocumentparser-test.cpp | 8 +- .../projectstorage/qmltypesparser-test.cpp | 8 +- .../typeannotationreader-test.cpp | 2 +- .../sourcepathstorage/CMakeLists.txt | 11 + .../sourcepath-test.cpp | 2 +- .../sourcepathcache-test.cpp | 2 +- .../sourcepathstorage-test.cpp | 211 +++++++++++++ .../sourcepathview-test.cpp | 2 +- .../storagecache-test.cpp | 4 +- 64 files changed, 946 insertions(+), 657 deletions(-) create mode 100644 src/plugins/qmldesigner/designercore/include/sourcepathids.h rename src/plugins/qmldesigner/designercore/{projectstorage => sourcepathstorage}/nonlockingmutex.h (100%) rename src/plugins/qmldesigner/designercore/{projectstorage => sourcepathstorage}/sourcepath.h (100%) rename src/plugins/qmldesigner/designercore/{projectstorage => sourcepathstorage}/sourcepathcache.h (92%) rename src/plugins/qmldesigner/designercore/{projectstorage => sourcepathstorage}/sourcepathcacheinterface.h (100%) rename src/plugins/qmldesigner/designercore/{projectstorage => sourcepathstorage}/sourcepathcachetypes.h (100%) create mode 100644 src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathexceptions.cpp create mode 100644 src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathexceptions.h create mode 100644 src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathstorage.cpp create mode 100644 src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathstorage.h rename src/plugins/qmldesigner/designercore/{projectstorage => sourcepathstorage}/sourcepathview.h (100%) rename src/plugins/qmldesigner/designercore/{projectstorage => sourcepathstorage}/storagecache.h (99%) rename src/plugins/qmldesigner/designercore/{projectstorage => sourcepathstorage}/storagecacheentry.h (100%) rename src/plugins/qmldesigner/designercore/{projectstorage => sourcepathstorage}/storagecachefwd.h (100%) create mode 100644 tests/unit/tests/unittests/sourcepathstorage/CMakeLists.txt rename tests/unit/tests/unittests/{projectstorage => sourcepathstorage}/sourcepath-test.cpp (97%) rename tests/unit/tests/unittests/{projectstorage => sourcepathstorage}/sourcepathcache-test.cpp (99%) create mode 100644 tests/unit/tests/unittests/sourcepathstorage/sourcepathstorage-test.cpp rename tests/unit/tests/unittests/{projectstorage => sourcepathstorage}/sourcepathview-test.cpp (97%) rename tests/unit/tests/unittests/{projectstorage => sourcepathstorage}/storagecache-test.cpp (99%) diff --git a/src/libs/nanotrace/nanotracehr.h b/src/libs/nanotrace/nanotracehr.h index 03e44b4f5fc..cf260adab28 100644 --- a/src/libs/nanotrace/nanotracehr.h +++ b/src/libs/nanotrace/nanotracehr.h @@ -57,6 +57,11 @@ struct TracerLiteral : text{text} {} + template + consteval TracerLiteral(const char (&text)[size]) + : text{text} + {} + friend consteval TracerLiteral operator""_t(const char *text, size_t size); constexpr operator std::string_view() const { return text; } diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index caeefbb92d9..a85b3010ff2 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -16,8 +16,12 @@ option(USE_PROJECTSTORAGE "Use ProjectStorage" ${QTC_USE_QML_DESIGNER_LITE}) env_with_default("QTC_ENABLE_PROJECT_STORAGE_TRACING" ENV_QTC_ENABLE_PROJECT_STORAGE_TRACING OFF) -option(ENABLE_PROJECT_STORAGE_TRACING "Enable sqlite tracing" ${ENV_QTC_ENABLE_PROJECT_STORAGE_TRACING}) -add_feature_info("Sqlite tracing" ${ENABLE_PROJECT_STORAGE_TRACING} "") +option(ENABLE_PROJECT_STORAGE_TRACING "Enable project storage tracing" ${ENV_QTC_ENABLE_PROJECT_STORAGE_TRACING}) +add_feature_info("Project storage tracing" ${ENABLE_PROJECT_STORAGE_TRACING} "") + +env_with_default("QTC_ENABLE_SOURCE_PATH_STORAGE_TRACING" ENV_QTC_ENABLE_SOURCE_PATH_STORAGE_TRACING OFF) +option(ENABLE_SOURCE_PATH_STORAGE_TRACING "Enable source path storage tracing" ${ENV_QTC_ENABLE_SOURCE_PATH_STORAGE_TRACING}) +add_feature_info("Source path storage tracing" ${ENABLE_SOURCE_PATH_STORAGE_TRACING} "") env_with_default("QTC_ENABLE_IMAGE_CACHE_TRACING" ENV_QTC_ENABLE_IMAGE_CACHE_TRACING OFF) option(ENABLE_IMAGE_CACHE_TRACING "Enable image cache tracing" ${ENV_QTC_ENABLE_IMAGE_CACHE_TRACING}) @@ -109,12 +113,13 @@ extend_qtc_library(QmlDesignerCore ) extend_qtc_library(QmlDesignerCore - CONDITION ENABLE_PROJECT_STORAGE_TRACING OR ENABLE_IMAGE_CACHE_TRACING OR ENABLE_MODEL_TRACING OR ENABLE_METAINFO_TRACING + CONDITION ENABLE_PROJECT_STORAGE_TRACING OR ENABLE_SOURCE_PATH_STORAGE_TRACING OR ENABLE_IMAGE_CACHE_TRACING OR ENABLE_MODEL_TRACING OR ENABLE_METAINFO_TRACING PUBLIC_DEPENDS Nanotrace PUBLIC_DEFINES ENABLE_QMLDESIGNER_TRACING DEFINES - $<$:ENABLE_PROJECT_STORAGE_TRACING> + $<$:ENABLE_PROJECT_STORAGE_TRACING> + $<$:ENABLE_SOURCE_PATH_STORAGE_TRACING> $<$:ENABLE_IMAGE_CACHE_TRACING> $<$:ENABLE_MODEL_TRACING> $<$:ENABLE_METAINFO_TRACING> @@ -454,6 +459,26 @@ extend_qtc_library(QmlDesignerCore widgetpluginpath.h ) +extend_qtc_library(QmlDesignerCore + SOURCES_PREFIX designercore/sourcepathstorage + PUBLIC_INCLUDES designercore/sourcepathstorage + SOURCES_PROPERTIES SKIP_AUTOGEN ON + SOURCES + nonlockingmutex.h + sourcepath.h + sourcepathcache.h + sourcepathcacheinterface.h + sourcepathcachetypes.h + sourcepathexceptions.cpp + sourcepathexceptions.h + sourcepathstorage.cpp + sourcepathstorage.h + sourcepathview.h + storagecache.h + storagecacheentry.h + storagecachefwd.h +) + extend_qtc_library(QmlDesignerCore SOURCES_PREFIX designercore/projectstorage PUBLIC_INCLUDES designercore/projectstorage @@ -467,7 +492,6 @@ extend_qtc_library(QmlDesignerCore filestatus.h filestatuscache.cpp filestatuscache.h modulescanner.cpp modulescanner.h - nonlockingmutex.h projectstorageexceptions.cpp projectstorageexceptions.h projectstorageinterface.h projectstoragefwd.h @@ -484,14 +508,6 @@ extend_qtc_library(QmlDesignerCore projectstorage.cpp projectstorage.h projectstorageerrornotifierinterface.h projectstorageerrornotifier.cpp projectstorageerrornotifier.h - sourcepath.h - sourcepathcache.h - sourcepathcacheinterface.h - sourcepathcachetypes.h - sourcepathview.h - storagecache.h - storagecacheentry.h - storagecachefwd.h typeannotationreader.cpp typeannotationreader.h qmldocumentparserinterface.h qmltypesparserinterface.h @@ -947,6 +963,7 @@ extend_qtc_plugin(QmlDesigner include/objectpropertybinding.h include/projectstorageids.h include/propertybinding.h + include/sourcepathids.h include/qml3dnode.h include/qmlvisualnode.h ) diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp index c0ff56e39e7..f5cdc75ee94 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp @@ -11,11 +11,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp index 33151f403ac..2c886017a09 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp @@ -21,7 +21,7 @@ #include #include -#include +#include #include diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.cpp b/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.cpp index 36730ea5f8a..355ce2f179e 100644 --- a/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.cpp +++ b/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.cpp @@ -6,8 +6,7 @@ #include #include #include -#include -#include +#include #include diff --git a/src/plugins/qmldesigner/designercore/include/externaldependenciesinterface.h b/src/plugins/qmldesigner/designercore/include/externaldependenciesinterface.h index 9055f51b6a1..3adaeb40514 100644 --- a/src/plugins/qmldesigner/designercore/include/externaldependenciesinterface.h +++ b/src/plugins/qmldesigner/designercore/include/externaldependenciesinterface.h @@ -48,6 +48,10 @@ public: virtual bool isQtForMcusProject() const = 0; virtual QString qtQuickVersion() const = 0; virtual Utils::FilePath resourcePath(const QString &relativePath) const = 0; + virtual QString userResourcePath(QStringView relativePath) const = 0; + +protected: + ~ExternalDependenciesInterface() = default; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/modelfwd.h b/src/plugins/qmldesigner/designercore/include/modelfwd.h index a168a780560..7cbfdba616a 100644 --- a/src/plugins/qmldesigner/designercore/include/modelfwd.h +++ b/src/plugins/qmldesigner/designercore/include/modelfwd.h @@ -42,10 +42,12 @@ constexpr bool useProjectStorage() #ifdef QDS_MODEL_USE_PROJECTSTORAGEINTERFACE using ProjectStorageType = ProjectStorageInterface; +class SourcePathCacheInterface; using PathCacheType = SourcePathCacheInterface; #else using ProjectStorageType = ProjectStorage; -using PathCacheType = SourcePathCache; +class SourcePathStorage; +using PathCacheType = SourcePathCache; #endif struct ProjectStorageDependencies diff --git a/src/plugins/qmldesigner/designercore/include/projectstorageids.h b/src/plugins/qmldesigner/designercore/include/projectstorageids.h index 6a8c5b95a87..a5f8ad35a9d 100644 --- a/src/plugins/qmldesigner/designercore/include/projectstorageids.h +++ b/src/plugins/qmldesigner/designercore/include/projectstorageids.h @@ -3,15 +3,11 @@ #pragma once -#include - -#include - -#include +#include "sourcepathids.h" namespace QmlDesigner { -enum class BasicIdType { +enum class ProjectStorageIdType { Type, PropertyType, PropertyDeclaration, @@ -29,55 +25,40 @@ enum class BasicIdType { ModuleExportedImport }; -using TypeId = Sqlite::BasicId; +using TypeId = Sqlite::BasicId; using TypeIds = std::vector; template using SmallTypeIds = QVarLengthArray; -using PropertyDeclarationId = Sqlite::BasicId; +using PropertyDeclarationId = Sqlite::BasicId; using PropertyDeclarationIds = std::vector; -using FunctionDeclarationId = Sqlite::BasicId; +using FunctionDeclarationId = Sqlite::BasicId; using FunctionDeclarationIds = std::vector; -using SignalDeclarationId = Sqlite::BasicId; +using SignalDeclarationId = Sqlite::BasicId; using SignalDeclarationIds = std::vector; -using EnumerationDeclarationId = Sqlite::BasicId; +using EnumerationDeclarationId = Sqlite::BasicId; using EnumerationDeclarationIds = std::vector; -using SourceContextId = Sqlite::BasicId; -using SourceContextIds = std::vector; -template -using SmallSourceContextIds = QVarLengthArray; - -using SourceNameId = Sqlite::BasicId; -using SourceNameIds = std::vector; -template -using SmallSourceNameIds = QVarLengthArray; - -using ModuleId = Sqlite::BasicId; +using ModuleId = Sqlite::BasicId; using ModuleIds = std::vector; using ModuleIdSpan = Utils::span; -using ProjectPartId = Sqlite::BasicId; +using ProjectPartId = Sqlite::BasicId; using ProjectPartIds = std::vector; -using ImportId = Sqlite::BasicId; +using ImportId = Sqlite::BasicId; using ImportIds = std::vector; -using ImportedTypeNameId = Sqlite::BasicId; +using ImportedTypeNameId = Sqlite::BasicId; using ImportedTypeNameIds = std::vector; -using ExportedTypeNameId = Sqlite::BasicId; +using ExportedTypeNameId = Sqlite::BasicId; using ExportedTypeNameIds = std::vector; -using ModuleExportedImportId = Sqlite::BasicId; +using ModuleExportedImportId = Sqlite::BasicId; using ModuleExportedImportIds = std::vector; -using SourceId = Sqlite::CompoundBasicId; -using SourceIds = std::vector; -template -using SmallSourceIds = QVarLengthArray; - } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/sourcepathids.h b/src/plugins/qmldesigner/designercore/include/sourcepathids.h new file mode 100644 index 00000000000..7bac16dcd50 --- /dev/null +++ b/src/plugins/qmldesigner/designercore/include/sourcepathids.h @@ -0,0 +1,35 @@ +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +#include + +#include + +namespace QmlDesigner { + +enum class SourcePathIdType { + SourceName, + SourceContext, + +}; + +using SourceContextId = Sqlite::BasicId; +using SourceContextIds = std::vector; +template +using SmallSourceContextIds = QVarLengthArray; + +using SourceNameId = Sqlite::BasicId; +using SourceNameIds = std::vector; +template +using SmallSourceNameIds = QVarLengthArray; + +using SourceId = Sqlite::CompoundBasicId; +using SourceIds = std::vector; +template +using SmallSourceIds = QVarLengthArray; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 32b797626ee..f0e3246fbbe 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -7,8 +7,6 @@ #include "modelutils.h" #include -#include "../projectstorage/sourcepath.h" -#include "../projectstorage/sourcepathcache.h" #include "abstractview.h" #include "internalbindingproperty.h" #include "internalnodeabstractproperty.h" @@ -18,6 +16,8 @@ #include "internalsignalhandlerproperty.h" #include "internalvariantproperty.h" #include "itemlibraryentry.h" +#include "sourcepathstorage/sourcepath.h" +#include "sourcepathstorage/sourcepathcache.h" #ifndef QDS_USE_PROJECTSTORAGE # include "metainfo.h" #endif diff --git a/src/plugins/qmldesigner/designercore/projectstorage/filesystem.cpp b/src/plugins/qmldesigner/designercore/projectstorage/filesystem.cpp index d11190fdc74..0286b6e130c 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/filesystem.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/filesystem.cpp @@ -4,7 +4,7 @@ #include "filesystem.h" #include "projectstorage.h" #include "projectstorageids.h" -#include "sourcepathcache.h" +#include "sourcepathstorage/sourcepathcache.h" #include "sqlitedatabase.h" #include diff --git a/src/plugins/qmldesigner/designercore/projectstorage/filesystem.h b/src/plugins/qmldesigner/designercore/projectstorage/filesystem.h index 1c881741c6a..37ab2069da4 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/filesystem.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/filesystem.h @@ -5,21 +5,18 @@ #include "filestatuscache.h" #include "filesysteminterface.h" -#include "nonlockingmutex.h" -#include "projectstoragefwd.h" - -namespace Sqlite { -class Database; -} +#include "sourcepathstorage/nonlockingmutex.h" namespace QmlDesigner { -template +class SourcePathStorage; + +template class SourcePathCache; class FileSystem : public FileSystemInterface { - using PathCache = SourcePathCache; + using PathCache = SourcePathCache; public: FileSystem(PathCache &sourcePathCache) diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp index 698829aac26..ff7d406cf21 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp @@ -73,22 +73,6 @@ struct ProjectStorage::Statements "WHERE propertyDeclarationId=?1 " "LIMIT 1", database}; - mutable Sqlite::ReadStatement<1, 1> selectSourceContextIdFromSourceContextsBySourceContextPathStatement{ - "SELECT sourceContextId FROM sourceContexts WHERE sourceContextPath = ?", database}; - mutable Sqlite::ReadStatement<1, 1> selectSourceContextPathFromSourceContextsBySourceContextIdStatement{ - "SELECT sourceContextPath FROM sourceContexts WHERE sourceContextId = ?", database}; - mutable Sqlite::ReadStatement<2> selectAllSourceContextsStatement{ - "SELECT sourceContextPath, sourceContextId FROM sourceContexts", database}; - Sqlite::WriteStatement<1> insertIntoSourceContextsStatement{ - "INSERT INTO sourceContexts(sourceContextPath) VALUES (?)", database}; - mutable Sqlite::ReadStatement<1, 1> selectSourceNameIdFromSourceNamesBySourceNameStatement{ - "SELECT sourceNameId FROM sourceNames WHERE sourceName = ?", database}; - mutable Sqlite::ReadStatement<1, 1> selectSourceNameFromSourceNamesBySourceNameIdStatement{ - "SELECT sourceName FROM sourceNames WHERE sourceNameId = ?", database}; - Sqlite::WriteStatement<1> insertIntoSourcesStatement{ - "INSERT INTO sourceNames(sourceName) VALUES (?)", database}; - mutable Sqlite::ReadStatement<2> selectAllSourcesStatement{ - "SELECT sourceName, sourceNameId FROM sourceNames", database}; mutable Sqlite::ReadStatement<8, 1> selectTypeByTypeIdStatement{ "SELECT sourceId, t.name, t.typeId, prototypeId, extensionId, traits, annotationTraits, " "pd.name " @@ -619,8 +603,6 @@ struct ProjectStorage::Statements "ORDER BY itn.kind, etn.majorVersion DESC NULLS FIRST, etn.minorVersion DESC NULLS FIRST " "LIMIT 1", database}; - Sqlite::WriteStatement<0> deleteAllSourceNamesStatement{"DELETE FROM sourceNames", database}; - Sqlite::WriteStatement<0> deleteAllSourceContextsStatement{"DELETE FROM sourceContexts", database}; mutable Sqlite::ReadStatement<6, 1> selectExportedTypesForSourceIdsStatement{ "SELECT moduleId, name, ifnull(majorVersion, -1), ifnull(minorVersion, -1), typeId, " "exportedTypeNameId FROM exportedTypeNames WHERE typeId in carray(?1) ORDER BY moduleId, " @@ -894,8 +876,7 @@ public: { if (!isInitialized) { auto moduleIdColumn = createModulesTable(database); - createSourceContextsTable(database); - createSourceNamesTable(database); + createTypesAndePropertyDeclarationsTables(database, moduleIdColumn); createExportedTypeNamesTable(database, moduleIdColumn); createImportedTypeNamesTable(database); @@ -912,31 +893,6 @@ public: database.setIsInitialized(true); } - void createSourceContextsTable(Database &database) - { - Sqlite::Table table; - table.setUseIfNotExists(true); - table.setName("sourceContexts"); - table.addColumn("sourceContextId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}}); - const Sqlite::Column &sourceContextPathColumn = table.addColumn("sourceContextPath"); - - table.addUniqueIndex({sourceContextPathColumn}); - - table.initialize(database); - } - - void createSourceNamesTable(Database &database) - { - Sqlite::StrictTable table; - table.setUseIfNotExists(true); - table.setName("sourceNames"); - table.addColumn("sourceNameId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}}); - const auto &sourceNameColumn = table.addColumn("sourceName", Sqlite::StrictColumnType::Text); - table.addUniqueIndex({sourceNameColumn}); - - table.initialize(database); - } - void createTypesAndePropertyDeclarationsTables( Database &database, [[maybe_unused]] const Sqlite::StrictColumn &foreignModuleIdColumn) { @@ -2120,132 +2076,6 @@ Storage::Synchronization::Types ProjectStorage::fetchTypes() return types; } -SourceContextId ProjectStorage::fetchSourceContextIdUnguarded(Utils::SmallStringView sourceContextPath) -{ - using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"fetch source context id unguarded"_t, projectStorageCategory()}; - - auto sourceContextId = readSourceContextId(sourceContextPath); - - return sourceContextId ? sourceContextId : writeSourceContextId(sourceContextPath); -} - -SourceContextId ProjectStorage::fetchSourceContextId(Utils::SmallStringView sourceContextPath) -{ - using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"fetch source context id"_t, - projectStorageCategory(), - keyValue("source context path", sourceContextPath)}; - - SourceContextId sourceContextId; - try { - sourceContextId = Sqlite::withDeferredTransaction(database, [&] { - return fetchSourceContextIdUnguarded(sourceContextPath); - }); - } catch (const Sqlite::ConstraintPreventsModification &) { - sourceContextId = fetchSourceContextId(sourceContextPath); - } - - tracer.end(keyValue("source context id", sourceContextId)); - - return sourceContextId; -} - -Utils::PathString ProjectStorage::fetchSourceContextPath(SourceContextId sourceContextId) const -{ - using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"fetch source context path"_t, - projectStorageCategory(), - keyValue("source context id", sourceContextId)}; - - auto path = Sqlite::withDeferredTransaction(database, [&] { - auto optionalSourceContextPath = s->selectSourceContextPathFromSourceContextsBySourceContextIdStatement - .optionalValue(sourceContextId); - - if (!optionalSourceContextPath) - throw SourceContextIdDoesNotExists(); - - return std::move(*optionalSourceContextPath); - }); - - tracer.end(keyValue("source context path", path)); - - return path; -} - -Cache::SourceContexts ProjectStorage::fetchAllSourceContexts() const -{ - NanotraceHR::Tracer tracer{"fetch all source contexts"_t, projectStorageCategory()}; - - return s->selectAllSourceContextsStatement.valuesWithTransaction(); -} - -SourceNameId ProjectStorage::fetchSourceNameId(Utils::SmallStringView sourceName) -{ - using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"fetch source id"_t, - projectStorageCategory(), - keyValue("source name", sourceName)}; - - auto sourceNameId = Sqlite::withDeferredTransaction(database, [&] { - return fetchSourceNameIdUnguarded(sourceName); - }); - - tracer.end(keyValue("source name id", sourceNameId)); - - return sourceNameId; -} - -Utils::SmallString ProjectStorage::fetchSourceName(SourceNameId sourceNameId) const -{ - using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"fetch source name and source context id"_t, - projectStorageCategory(), - keyValue("source name id", sourceNameId)}; - - auto sourceName = s->selectSourceNameFromSourceNamesBySourceNameIdStatement - .valueWithTransaction(sourceNameId); - - if (sourceName.empty()) - throw SourceNameIdDoesNotExists(); - - tracer.end(keyValue("source name", sourceName)); - - return sourceName; -} - -void ProjectStorage::clearSources() -{ - Sqlite::withImmediateTransaction(database, [&] { - s->deleteAllSourceContextsStatement.execute(); - s->deleteAllSourceNamesStatement.execute(); - }); -} - -Cache::SourceNames ProjectStorage::fetchAllSourceNames() const -{ - NanotraceHR::Tracer tracer{"fetch all sources"_t, projectStorageCategory()}; - - return s->selectAllSourcesStatement.valuesWithTransaction(); -} - -SourceNameId ProjectStorage::fetchSourceNameIdUnguarded(Utils::SmallStringView sourceName) -{ - using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"fetch source id unguarded"_t, - projectStorageCategory(), - keyValue("source name", sourceName)}; - - auto sourceId = readSourceNameId(sourceName); - - if (!sourceId) - sourceId = writeSourceNameId(sourceName); - - tracer.end(keyValue("source id", sourceId)); - - return sourceId; -} - FileStatuses ProjectStorage::fetchAllFileStatuses() const { NanotraceHR::Tracer tracer{"fetch all file statuses"_t, projectStorageCategory()}; @@ -4859,68 +4689,6 @@ PropertyDeclarationId ProjectStorage::fetchPropertyDeclarationIdByTypeIdAndNameU return propertyDeclarationId; } -SourceContextId ProjectStorage::readSourceContextId(Utils::SmallStringView sourceContextPath) -{ - using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"read source context id"_t, - projectStorageCategory(), - keyValue("source context path", sourceContextPath)}; - - auto sourceContextId = s->selectSourceContextIdFromSourceContextsBySourceContextPathStatement - .value(sourceContextPath); - - tracer.end(keyValue("source context id", sourceContextId)); - - return sourceContextId; -} - -SourceContextId ProjectStorage::writeSourceContextId(Utils::SmallStringView sourceContextPath) -{ - using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"write source context id"_t, - projectStorageCategory(), - keyValue("source context path", sourceContextPath)}; - - s->insertIntoSourceContextsStatement.write(sourceContextPath); - - auto sourceContextId = SourceContextId::create(static_cast(database.lastInsertedRowId())); - - tracer.end(keyValue("source context id", sourceContextId)); - - return sourceContextId; -} - -SourceNameId ProjectStorage::writeSourceNameId(Utils::SmallStringView sourceName) -{ - using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"write source id"_t, - projectStorageCategory(), - keyValue("source name", sourceName)}; - - s->insertIntoSourcesStatement.write(sourceName); - - auto sourceNameId = SourceNameId::create(static_cast(database.lastInsertedRowId())); - - tracer.end(keyValue("source name id", sourceNameId)); - - return sourceNameId; -} - -SourceNameId ProjectStorage::readSourceNameId(Utils::SmallStringView sourceName) -{ - using NanotraceHR::keyValue; - NanotraceHR::Tracer tracer{"read source id"_t, - projectStorageCategory(), - keyValue("source name", sourceName)}; - - auto sourceNameId = s->selectSourceNameIdFromSourceNamesBySourceNameStatement.value( - sourceName); - - tracer.end(keyValue("source id", sourceNameId)); - - return sourceNameId; -} - Storage::Synchronization::ExportedTypes ProjectStorage::fetchExportedTypes(TypeId typeId) { using NanotraceHR::keyValue; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h index 3da9305e04b..f5697192c78 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h @@ -8,8 +8,7 @@ #include "projectstorageexceptions.h" #include "projectstorageinterface.h" #include "projectstoragetypes.h" -#include "sourcepathcachetypes.h" -#include "storagecache.h" +#include "sourcepathstorage/storagecache.h" #include @@ -215,24 +214,6 @@ public: Storage::Synchronization::Types fetchTypes(); - SourceContextId fetchSourceContextIdUnguarded(Utils::SmallStringView sourceContextPath); - - SourceContextId fetchSourceContextId(Utils::SmallStringView sourceContextPath); - - Utils::PathString fetchSourceContextPath(SourceContextId sourceContextId) const; - - Cache::SourceContexts fetchAllSourceContexts() const; - - SourceNameId fetchSourceNameId(Utils::SmallStringView sourceName); - - Utils::SmallString fetchSourceName(SourceNameId sourceId) const; - - void clearSources(); - - Cache::SourceNames fetchAllSourceNames() const; - - SourceNameId fetchSourceNameIdUnguarded(Utils::SmallStringView sourceName); - FileStatuses fetchAllFileStatuses() const; FileStatus fetchFileStatus(SourceId sourceId) const override; @@ -1007,14 +988,6 @@ private: PropertyDeclarationId fetchPropertyDeclarationIdByTypeIdAndNameUngarded(TypeId typeId, Utils::SmallStringView name); - SourceContextId readSourceContextId(Utils::SmallStringView sourceContextPath); - - SourceContextId writeSourceContextId(Utils::SmallStringView sourceContextPath); - - SourceNameId writeSourceNameId(Utils::SmallStringView sourceName); - - SourceNameId readSourceNameId(Utils::SmallStringView sourceName); - Storage::Synchronization::ExportedTypes fetchExportedTypes(TypeId typeId); Storage::Synchronization::PropertyDeclarations fetchPropertyDeclarations(TypeId typeId); diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.cpp index 6d59ebb3884..a5646d39895 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.cpp @@ -3,7 +3,7 @@ #include "projectstorageerrornotifier.h" -#include "sourcepathcache.h" +#include "sourcepathstorage/sourcepathcache.h" namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.cpp index 938a9fac4d4..948a8d42d6d 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.cpp @@ -17,46 +17,6 @@ auto &category() } } // namespace -NoSourcePathForInvalidSourceId::NoSourcePathForInvalidSourceId() -{ - category().threadEvent("NoSourcePathForInvalidSourceId"_t); -} - -const char *NoSourcePathForInvalidSourceId::what() const noexcept -{ - return "You cannot get a file path for an invalid file path id!"; -} - -NoSourceContextPathForInvalidSourceContextId::NoSourceContextPathForInvalidSourceContextId() -{ - category().threadEvent("NoSourceContextPathForInvalidSourceContextId"_t); -} - -const char *NoSourceContextPathForInvalidSourceContextId::what() const noexcept -{ - return "You cannot get a directory path for an invalid directory path id!"; -} - -SourceContextIdDoesNotExists::SourceContextIdDoesNotExists() -{ - category().threadEvent("SourceContextIdDoesNotExists"_t); -} - -const char *SourceContextIdDoesNotExists::what() const noexcept -{ - return "The source context id does not exist in the database!"; -} - -SourceNameIdDoesNotExists::SourceNameIdDoesNotExists() -{ - category().threadEvent("SourceNameIdDoesNotExists"_t); -} - -const char *SourceNameIdDoesNotExists::what() const noexcept -{ - return "The source id does not exist in the database!"; -} - TypeHasInvalidSourceId::TypeHasInvalidSourceId() { category().threadEvent("TypeHasInvalidSourceId"_t); diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h index 5ab71b3c247..465e02663e7 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h @@ -34,34 +34,6 @@ public: std::string errorMessage; }; -class QMLDESIGNERCORE_EXPORT NoSourcePathForInvalidSourceId : public ProjectStorageError -{ -public: - NoSourcePathForInvalidSourceId(); - const char *what() const noexcept override; -}; - -class QMLDESIGNERCORE_EXPORT NoSourceContextPathForInvalidSourceContextId : public ProjectStorageError -{ -public: - NoSourceContextPathForInvalidSourceContextId(); - const char *what() const noexcept override; -}; - -class QMLDESIGNERCORE_EXPORT SourceContextIdDoesNotExists : public ProjectStorageError -{ -public: - SourceContextIdDoesNotExists(); - const char *what() const noexcept override; -}; - -class QMLDESIGNERCORE_EXPORT SourceNameIdDoesNotExists : public ProjectStorageError -{ -public: - SourceNameIdDoesNotExists(); - const char *what() const noexcept override; -}; - class QMLDESIGNERCORE_EXPORT TypeHasInvalidSourceId : public ProjectStorageError { public: diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragefwd.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragefwd.h index cbb7d4265ae..273cce7e8af 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragefwd.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragefwd.h @@ -9,7 +9,6 @@ class Database; namespace QmlDesigner { class ProjectStorageInterface; -class SourcePathCacheInterface; class ProjectStorage; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatcher.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatcher.h index 63816b5cb55..88d2d14eb3f 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatcher.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatcher.h @@ -8,7 +8,8 @@ #include "projectstoragepathwatcherinterface.h" #include "projectstoragepathwatchernotifierinterface.h" #include "projectstoragepathwatchertypes.h" -#include "storagecache.h" + +#include #include diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp index 88110223755..267304ab4fd 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp @@ -9,8 +9,8 @@ #include "projectstoragepathwatcherinterface.h" #include "qmldocumentparserinterface.h" #include "qmltypesparserinterface.h" -#include "sourcepath.h" -#include "sourcepathcache.h" +#include "sourcepathstorage/sourcepath.h" +#include "sourcepathstorage/sourcepathcache.h" #include "typeannotationreader.h" #include diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h index 3995c97800b..3a36b201828 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h @@ -4,12 +4,12 @@ #pragma once #include "filestatus.h" -#include "nonlockingmutex.h" #include "projectstorageids.h" #include "projectstoragepathwatchernotifierinterface.h" #include "projectstoragepathwatchertypes.h" #include "projectstoragetypes.h" -#include "sourcepath.h" +#include "sourcepathstorage/nonlockingmutex.h" +#include "sourcepathstorage/sourcepath.h" #include @@ -35,11 +35,12 @@ class FileStatusCache; class ProjectStorage; class QmlDocumentParserInterface; class QmlTypesParserInterface; +class SourcePathStorage; class ProjectStorageUpdater final : public ProjectStoragePathWatcherNotifierInterface { public: - using PathCache = SourcePathCache; + using PathCache = SourcePathCache; ProjectStorageUpdater(FileSystemInterface &fileSystem, ProjectStorageType &projectStorage, diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp index 0469809ac17..d72f49b33a4 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp @@ -6,8 +6,8 @@ #include "projectstorage.h" #include "projectstorageexceptions.h" -#include "sourcepathcache.h" +#include #include #include diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h index 1b494a2f693..1ad55d094fd 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h @@ -3,20 +3,21 @@ #pragma once -#include "nonlockingmutex.h" #include "projectstoragefwd.h" #include "qmldocumentparserinterface.h" +#include "sourcepathstorage/nonlockingmutex.h" namespace QmlDesigner { -template +template class SourcePathCache; +class SourcePathStorage; class QmlDocumentParser final : public QmlDocumentParserInterface { public: using ProjectStorage = QmlDesigner::ProjectStorage; - using PathCache = QmlDesigner::SourcePathCache; + using PathCache = QmlDesigner::SourcePathCache; #ifdef QDS_BUILD_QMLPARSER QmlDocumentParser(ProjectStorage &storage, PathCache &pathCache) diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h index c73a429f912..1dd71dcce98 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h @@ -3,9 +3,9 @@ #pragma once -#include "nonlockingmutex.h" #include "projectstoragefwd.h" #include "qmltypesparserinterface.h" +#include "sourcepathstorage/nonlockingmutex.h" namespace Sqlite { class Database; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/nonlockingmutex.h b/src/plugins/qmldesigner/designercore/sourcepathstorage/nonlockingmutex.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/nonlockingmutex.h rename to src/plugins/qmldesigner/designercore/sourcepathstorage/nonlockingmutex.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/sourcepath.h b/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepath.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/sourcepath.h rename to src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepath.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcache.h b/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathcache.h similarity index 92% rename from src/plugins/qmldesigner/designercore/projectstorage/sourcepathcache.h rename to src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathcache.h index 4ce7ae43b59..47877803e3b 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcache.h +++ b/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathcache.h @@ -3,16 +3,16 @@ #pragma once -#include "projectstorage.h" -#include "projectstorageexceptions.h" -#include "projectstorageids.h" #include "sourcepath.h" #include "sourcepathcacheinterface.h" #include "sourcepathcachetypes.h" +#include "sourcepathexceptions.h" +#include "sourcepathstorage.h" #include "sourcepathview.h" #include "storagecache.h" #include +#include #include #include @@ -20,19 +20,19 @@ namespace QmlDesigner { -template +template class SourcePathCache final : public SourcePathCacheInterface { SourcePathCache(const SourcePathCache &) = default; SourcePathCache &operator=(const SourcePathCache &) = default; - template + template friend class SourcePathCache; public: - SourcePathCache(ProjectStorage &projectStorage) - : m_sourceContextStorageAdapter{projectStorage} - , m_sourceNameStorageAdapter{projectStorage} + SourcePathCache(Storage &storage) + : m_sourceContextStorageAdapter{storage} + , m_sourceNameStorageAdapter{storage} { populateIfEmpty(); @@ -118,7 +118,7 @@ private: auto fetchAll() { return storage.fetchAllSourceContexts(); } - ProjectStorage &storage; + Storage &storage; }; class SourceNameStorageAdapter @@ -133,7 +133,7 @@ private: auto fetchAll() { return storage.fetchAllSourceNames(); } - ProjectStorage &storage; + Storage &storage; }; static bool sourceLess(Utils::SmallStringView first, Utils::SmallStringView second) noexcept diff --git a/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcacheinterface.h b/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathcacheinterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/sourcepathcacheinterface.h rename to src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathcacheinterface.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/sourcepathcachetypes.h b/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathcachetypes.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/sourcepathcachetypes.h rename to src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathcachetypes.h diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathexceptions.cpp b/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathexceptions.cpp new file mode 100644 index 00000000000..48c1af71a7c --- /dev/null +++ b/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathexceptions.cpp @@ -0,0 +1,59 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#include "sourcepathexceptions.h" + +#include + + namespace QmlDesigner { + +using namespace NanotraceHR::Literals; +using NanotraceHR::keyValue; +using SourcePathStorageTracing::category; + +const char *SourcePathError::what() const noexcept +{ + return "Source path error!"; +} + +NoSourcePathForInvalidSourceId::NoSourcePathForInvalidSourceId() +{ + category().threadEvent("NoSourcePathForInvalidSourceId"); +} + +const char *NoSourcePathForInvalidSourceId::what() const noexcept +{ + return "You cannot get a file path for an invalid file path id!"; +} + +NoSourceContextPathForInvalidSourceContextId::NoSourceContextPathForInvalidSourceContextId() +{ + category().threadEvent("NoSourceContextPathForInvalidSourceContextId"); +} + +const char *NoSourceContextPathForInvalidSourceContextId::what() const noexcept +{ + return "You cannot get a directory path for an invalid directory path id!"; +} + +SourceContextIdDoesNotExists::SourceContextIdDoesNotExists() +{ + category().threadEvent("SourceContextIdDoesNotExists"); +} + +const char *SourceContextIdDoesNotExists::what() const noexcept +{ + return "The source context id does not exist in the database!"; +} + +SourceNameIdDoesNotExists::SourceNameIdDoesNotExists() +{ + category().threadEvent("SourceNameIdDoesNotExists"); +} + +const char *SourceNameIdDoesNotExists::what() const noexcept +{ + return "The source id does not exist in the database!"; +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathexceptions.h b/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathexceptions.h new file mode 100644 index 00000000000..12dcd1d7700 --- /dev/null +++ b/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathexceptions.h @@ -0,0 +1,51 @@ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "../include/qmldesignercorelib_global.h" + +#include + +namespace QmlDesigner { + +using namespace std::literals::string_view_literals; + +class QMLDESIGNERCORE_EXPORT SourcePathError : public std::exception +{ +protected: + SourcePathError() = default; + +public: + const char *what() const noexcept override; +}; + +class QMLDESIGNERCORE_EXPORT NoSourcePathForInvalidSourceId : public SourcePathError +{ +public: + NoSourcePathForInvalidSourceId(); + const char *what() const noexcept override; +}; + +class QMLDESIGNERCORE_EXPORT NoSourceContextPathForInvalidSourceContextId : public SourcePathError +{ +public: + NoSourceContextPathForInvalidSourceContextId(); + const char *what() const noexcept override; +}; + +class QMLDESIGNERCORE_EXPORT SourceContextIdDoesNotExists : public SourcePathError +{ +public: + SourceContextIdDoesNotExists(); + const char *what() const noexcept override; +}; + +class QMLDESIGNERCORE_EXPORT SourceNameIdDoesNotExists : public SourcePathError +{ +public: + SourceNameIdDoesNotExists(); + const char *what() const noexcept override; +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathstorage.cpp b/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathstorage.cpp new file mode 100644 index 00000000000..e1f8beaab51 --- /dev/null +++ b/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathstorage.cpp @@ -0,0 +1,277 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "sourcepathstorage.h" + +#include "sourcepathexceptions.h" + +#include + +namespace QmlDesigner { + +using SourcePathStorageTracing::category; + +struct SourcePathStorage::Statements +{ + Statements(Sqlite::Database &database) + : database{database} + {} + + Sqlite::Database &database; + mutable Sqlite::ReadStatement<1, 1> selectSourceContextIdFromSourceContextsBySourceContextPathStatement{ + "SELECT sourceContextId FROM sourceContexts WHERE sourceContextPath = ?", database}; + mutable Sqlite::ReadStatement<1, 1> selectSourceContextPathFromSourceContextsBySourceContextIdStatement{ + "SELECT sourceContextPath FROM sourceContexts WHERE sourceContextId = ?", database}; + mutable Sqlite::ReadStatement<2> selectAllSourceContextsStatement{ + "SELECT sourceContextPath, sourceContextId FROM sourceContexts", database}; + Sqlite::WriteStatement<1> insertIntoSourceContextsStatement{ + "INSERT INTO sourceContexts(sourceContextPath) VALUES (?)", database}; + mutable Sqlite::ReadStatement<1, 1> selectSourceNameIdFromSourceNamesBySourceNameStatement{ + "SELECT sourceNameId FROM sourceNames WHERE sourceName = ?", database}; + mutable Sqlite::ReadStatement<1, 1> selectSourceNameFromSourceNamesBySourceNameIdStatement{ + "SELECT sourceName FROM sourceNames WHERE sourceNameId = ?", database}; + Sqlite::WriteStatement<1> insertIntoSourcesStatement{ + "INSERT INTO sourceNames(sourceName) VALUES (?)", database}; + mutable Sqlite::ReadStatement<2> selectAllSourcesStatement{ + "SELECT sourceName, sourceNameId FROM sourceNames", database}; + Sqlite::WriteStatement<0> deleteAllSourceNamesStatement{"DELETE FROM sourceNames", database}; + Sqlite::WriteStatement<0> deleteAllSourceContextsStatement{"DELETE FROM sourceContexts", database}; +}; + +class SourcePathStorage::Initializer +{ +public: + Initializer(Database &database, bool isInitialized) + { + if (!isInitialized) { + createSourceContextsTable(database); + createSourceNamesTable(database); + } + } + + void createSourceContextsTable(Database &database) + { + Sqlite::Table table; + table.setUseIfNotExists(true); + table.setName("sourceContexts"); + table.addColumn("sourceContextId", Sqlite::ColumnType::Integer, {Sqlite::PrimaryKey{}}); + const Sqlite::Column &sourceContextPathColumn = table.addColumn("sourceContextPath"); + + table.addUniqueIndex({sourceContextPathColumn}); + + table.initialize(database); + } + + void createSourceNamesTable(Database &database) + { + Sqlite::StrictTable table; + table.setUseIfNotExists(true); + table.setName("sourceNames"); + table.addColumn("sourceNameId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}}); + const auto &sourceNameColumn = table.addColumn("sourceName", Sqlite::StrictColumnType::Text); + table.addUniqueIndex({sourceNameColumn}); + + table.initialize(database); + } +}; + +SourcePathStorage::SourcePathStorage(Database &database, bool isInitialized) + : database{database} + , exclusiveTransaction{database} + , initializer{std::make_unique(database, isInitialized)} + , s{std::make_unique(database)} +{ + NanotraceHR::Tracer tracer{"initialize", category()}; + + exclusiveTransaction.commit(); +} + +SourcePathStorage::~SourcePathStorage() = default; + +SourceContextId SourcePathStorage::fetchSourceContextIdUnguarded(Utils::SmallStringView sourceContextPath) +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"fetch source context id unguarded", category()}; + + auto sourceContextId = readSourceContextId(sourceContextPath); + + return sourceContextId ? sourceContextId : writeSourceContextId(sourceContextPath); +} + +SourceContextId SourcePathStorage::fetchSourceContextId(Utils::SmallStringView sourceContextPath) +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"fetch source context id", + category(), + keyValue("source context path", sourceContextPath)}; + + SourceContextId sourceContextId; + try { + sourceContextId = Sqlite::withDeferredTransaction(database, [&] { + return fetchSourceContextIdUnguarded(sourceContextPath); + }); + } catch (const Sqlite::ConstraintPreventsModification &) { + sourceContextId = fetchSourceContextId(sourceContextPath); + } + + tracer.end(keyValue("source context id", sourceContextId)); + + return sourceContextId; +} + +Utils::PathString SourcePathStorage::fetchSourceContextPath(SourceContextId sourceContextId) const +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"fetch source context path", + category(), + keyValue("source context id", sourceContextId)}; + + auto path = Sqlite::withDeferredTransaction(database, [&] { + auto optionalSourceContextPath = s->selectSourceContextPathFromSourceContextsBySourceContextIdStatement + .optionalValue(sourceContextId); + + if (!optionalSourceContextPath) + throw SourceContextIdDoesNotExists(); + + return std::move(*optionalSourceContextPath); + }); + + tracer.end(keyValue("source context path", path)); + + return path; +} + +Cache::SourceContexts SourcePathStorage::fetchAllSourceContexts() const +{ + NanotraceHR::Tracer tracer{"fetch all source contexts", category()}; + + return s->selectAllSourceContextsStatement.valuesWithTransaction(); +} + +SourceNameId SourcePathStorage::fetchSourceNameId(Utils::SmallStringView sourceName) +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"fetch source id", category(), keyValue("source name", sourceName)}; + + auto sourceNameId = Sqlite::withDeferredTransaction(database, [&] { + return fetchSourceNameIdUnguarded(sourceName); + }); + + tracer.end(keyValue("source name id", sourceNameId)); + + return sourceNameId; +} + +Utils::SmallString SourcePathStorage::fetchSourceName(SourceNameId sourceNameId) const +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"fetch source name and source context id", + category(), + keyValue("source name id", sourceNameId)}; + + auto sourceName = s->selectSourceNameFromSourceNamesBySourceNameIdStatement + .valueWithTransaction(sourceNameId); + + if (sourceName.empty()) + throw SourceNameIdDoesNotExists(); + + tracer.end(keyValue("source name", sourceName)); + + return sourceName; +} + +void SourcePathStorage::clearSources() +{ + Sqlite::withImmediateTransaction(database, [&] { + s->deleteAllSourceContextsStatement.execute(); + s->deleteAllSourceNamesStatement.execute(); + }); +} + +Cache::SourceNames SourcePathStorage::fetchAllSourceNames() const +{ + NanotraceHR::Tracer tracer{"fetch all sources", category()}; + + return s->selectAllSourcesStatement.valuesWithTransaction(); +} + +SourceNameId SourcePathStorage::fetchSourceNameIdUnguarded(Utils::SmallStringView sourceName) +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"fetch source id unguarded", + category(), + keyValue("source name", sourceName)}; + + auto sourceId = readSourceNameId(sourceName); + + if (!sourceId) + sourceId = writeSourceNameId(sourceName); + + tracer.end(keyValue("source id", sourceId)); + + return sourceId; +} + +SourceContextId SourcePathStorage::readSourceContextId(Utils::SmallStringView sourceContextPath) +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"read source context id", + category(), + keyValue("source context path", sourceContextPath)}; + + auto sourceContextId = s->selectSourceContextIdFromSourceContextsBySourceContextPathStatement + .value(sourceContextPath); + + tracer.end(keyValue("source context id", sourceContextId)); + + return sourceContextId; +} + +SourceContextId SourcePathStorage::writeSourceContextId(Utils::SmallStringView sourceContextPath) +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"write source context id", + category(), + keyValue("source context path", sourceContextPath)}; + + s->insertIntoSourceContextsStatement.write(sourceContextPath); + + auto sourceContextId = SourceContextId::create(static_cast(database.lastInsertedRowId())); + + tracer.end(keyValue("source context id", sourceContextId)); + + return sourceContextId; +} + +SourceNameId SourcePathStorage::writeSourceNameId(Utils::SmallStringView sourceName) +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"write source id", category(), keyValue("source name", sourceName)}; + + s->insertIntoSourcesStatement.write(sourceName); + + auto sourceNameId = SourceNameId::create(static_cast(database.lastInsertedRowId())); + + tracer.end(keyValue("source name id", sourceNameId)); + + return sourceNameId; +} + +SourceNameId SourcePathStorage::readSourceNameId(Utils::SmallStringView sourceName) +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"read source id", category(), keyValue("source name", sourceName)}; + + auto sourceNameId = s->selectSourceNameIdFromSourceNamesBySourceNameStatement.value( + sourceName); + + tracer.end(keyValue("source id", sourceNameId)); + + return sourceNameId; +} + +void SourcePathStorage::resetForTestsOnly() +{ + database.clearAllTablesForTestsOnly(); +} +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathstorage.h b/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathstorage.h new file mode 100644 index 00000000000..2fc5896a320 --- /dev/null +++ b/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathstorage.h @@ -0,0 +1,65 @@ + +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "sourcepathcachetypes.h" +#include "sourcepathexceptions.h" + +#include + +#include + +namespace QmlDesigner { + +class QMLDESIGNERCORE_EXPORT SourcePathStorage final +{ + using Database = Sqlite::Database; + +public: + SourcePathStorage(Database &database, bool isInitialized); + ~SourcePathStorage(); + + SourceContextId fetchSourceContextIdUnguarded(Utils::SmallStringView sourceContextPath); + + SourceContextId fetchSourceContextId(Utils::SmallStringView sourceContextPath); + + Utils::PathString fetchSourceContextPath(SourceContextId sourceContextId) const; + + Cache::SourceContexts fetchAllSourceContexts() const; + + SourceNameId fetchSourceNameId(Utils::SmallStringView sourceName); + + Utils::SmallString fetchSourceName(SourceNameId sourceId) const; + + void clearSources(); + + Cache::SourceNames fetchAllSourceNames() const; + + SourceNameId fetchSourceNameIdUnguarded(Utils::SmallStringView sourceName); + + void resetForTestsOnly(); + +private: + SourceContextId readSourceContextId(Utils::SmallStringView sourceContextPath); + + SourceContextId writeSourceContextId(Utils::SmallStringView sourceContextPath); + + SourceNameId writeSourceNameId(Utils::SmallStringView sourceName); + + SourceNameId readSourceNameId(Utils::SmallStringView sourceName); + + class Initializer; + + struct Statements; + +public: + Database &database; + Sqlite::ExclusiveNonThrowingDestructorTransaction exclusiveTransaction; + std::unique_ptr initializer; + std::unique_ptr s; +}; + + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/projectstorage/sourcepathview.h b/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathview.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/sourcepathview.h rename to src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathview.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/storagecache.h b/src/plugins/qmldesigner/designercore/sourcepathstorage/storagecache.h similarity index 99% rename from src/plugins/qmldesigner/designercore/projectstorage/storagecache.h rename to src/plugins/qmldesigner/designercore/sourcepathstorage/storagecache.h index 32ecb1c3f7e..1a3e3ec3a05 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/storagecache.h +++ b/src/plugins/qmldesigner/designercore/sourcepathstorage/storagecache.h @@ -4,10 +4,11 @@ #pragma once #include "nonlockingmutex.h" -#include "projectstorageids.h" #include "storagecacheentry.h" #include "storagecachefwd.h" +#include + #include #include #include diff --git a/src/plugins/qmldesigner/designercore/projectstorage/storagecacheentry.h b/src/plugins/qmldesigner/designercore/sourcepathstorage/storagecacheentry.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/storagecacheentry.h rename to src/plugins/qmldesigner/designercore/sourcepathstorage/storagecacheentry.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/storagecachefwd.h b/src/plugins/qmldesigner/designercore/sourcepathstorage/storagecachefwd.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/storagecachefwd.h rename to src/plugins/qmldesigner/designercore/sourcepathstorage/storagecachefwd.h diff --git a/src/plugins/qmldesigner/designercore/tracing/qmldesignertracing.cpp b/src/plugins/qmldesigner/designercore/tracing/qmldesignertracing.cpp index cbe7b0ec384..e0bdcd8c860 100644 --- a/src/plugins/qmldesigner/designercore/tracing/qmldesignertracing.cpp +++ b/src/plugins/qmldesigner/designercore/tracing/qmldesignertracing.cpp @@ -88,6 +88,17 @@ Category &projectStorageUpdaterCategory() } // namespace ProjectStorageTracing +namespace SourcePathStorageTracing { +Category &category() +{ + thread_local Category category_{"project storage updater"_t, + Tracing::eventQueueWithStringArguments(), + category}; + + return category_; +} +} // namespace SourcePathStorageTracing + namespace MetaInfoTracing { Category &category() { diff --git a/src/plugins/qmldesigner/designercore/tracing/qmldesignertracing.h b/src/plugins/qmldesigner/designercore/tracing/qmldesignertracing.h index 899ceb6cd2c..7edc50c10f8 100644 --- a/src/plugins/qmldesigner/designercore/tracing/qmldesignertracing.h +++ b/src/plugins/qmldesigner/designercore/tracing/qmldesignertracing.h @@ -63,6 +63,22 @@ using Category = NanotraceHR::StringViewWithStringArgumentsCategory; + +[[gnu::pure]] Category &category(); + +} // namespace SourcePathStorageTracing + namespace MetaInfoTracing { constexpr NanotraceHR::Tracing tracingStatus() { diff --git a/src/plugins/qmldesigner/qmldesignerexternaldependencies.cpp b/src/plugins/qmldesigner/qmldesignerexternaldependencies.cpp index 97b2b46e7d5..913564c46b5 100644 --- a/src/plugins/qmldesigner/qmldesignerexternaldependencies.cpp +++ b/src/plugins/qmldesigner/qmldesignerexternaldependencies.cpp @@ -275,4 +275,9 @@ Utils::FilePath ExternalDependencies::resourcePath(const QString &relativePath) return Core::ICore::resourcePath(relativePath); } +QString ExternalDependencies::userResourcePath(QStringView relativePath) const +{ + return Core::ICore::userResourcePath(relativePath.toString()).path(); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/qmldesignerexternaldependencies.h b/src/plugins/qmldesigner/qmldesignerexternaldependencies.h index 6a49e4b5516..b4944175a01 100644 --- a/src/plugins/qmldesigner/qmldesignerexternaldependencies.h +++ b/src/plugins/qmldesigner/qmldesignerexternaldependencies.h @@ -41,6 +41,7 @@ public: bool isQtForMcusProject() const override; QString qtQuickVersion() const override; Utils::FilePath resourcePath(const QString &relativePath) const override; + QString userResourcePath(QStringView relativePath) const override; private: const DesignerSettings &m_designerSettings; diff --git a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp index f4d94af5234..6b3a499d8f0 100644 --- a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp +++ b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp @@ -5,22 +5,23 @@ #include #include +#include #include #include #include #include #include -#include #include #include #include #include #include #include -#include #include #include #include +#include +#include #include #include @@ -176,36 +177,40 @@ namespace { class ProjectStorageData { public: - ProjectStorageData(::ProjectExplorer::Project *project) + ProjectStorageData(::ProjectExplorer::Project *project, PathCacheType &pathCache) : database{project->projectDirectory().pathAppended("projectstorage.db").toString()} + , errorNotifier{pathCache} + , fileSystem{pathCache} + , qmlDocumentParser{storage, pathCache} + , pathWatcher{pathCache, fileSystem, &updater} , projectPartId{ProjectPartId::create( pathCache.sourceId(SourcePath{project->projectDirectory().toString() + "/."}).internalId())} + , updater{fileSystem, + storage, + fileStatusCache, + pathCache, + qmlDocumentParser, + qmlTypesParser, + pathWatcher, + projectPartId} {} Sqlite::Database database; - ProjectStorageErrorNotifier errorNotifier{pathCache}; + ProjectStorageErrorNotifier errorNotifier; ProjectStorage storage{database, errorNotifier, database.isInitialized()}; - PathCacheType pathCache{storage}; - FileSystem fileSystem{pathCache}; + FileSystem fileSystem; FileStatusCache fileStatusCache{fileSystem}; - QmlDocumentParser qmlDocumentParser{storage, pathCache}; + QmlDocumentParser qmlDocumentParser; QmlTypesParser qmlTypesParser{storage}; - ProjectStoragePathWatcher - pathWatcher{pathCache, fileSystem, &updater}; + ProjectStoragePathWatcher pathWatcher; ProjectPartId projectPartId; - ProjectStorageUpdater updater{fileSystem, - storage, - fileStatusCache, - pathCache, - qmlDocumentParser, - qmlTypesParser, - pathWatcher, - projectPartId}; + ProjectStorageUpdater updater; }; -std::unique_ptr createProjectStorageData(::ProjectExplorer::Project *project) +std::unique_ptr createProjectStorageData(::ProjectExplorer::Project *project, + PathCacheType &pathCache) { if constexpr (useProjectStorage()) { - return std::make_unique(project); + return std::make_unique(project, pathCache); } else { return {}; } @@ -217,6 +222,7 @@ class QmlDesignerProjectManager::QmlDesignerProjectManagerProjectData public: QmlDesignerProjectManagerProjectData(ImageCacheStorage &storage, ::ProjectExplorer::Project *project, + PathCacheType &pathCache, ExternalDependenciesInterface &externalDependencies) : collector{connectionManager, QSize{300, 300}, @@ -224,7 +230,7 @@ public: externalDependencies, ImageCacheCollectorNullImageHandling::CaptureNullImage} , factory{storage, timeStampProvider, collector} - , projectStorageData{createProjectStorageData(project)} + , projectStorageData{createProjectStorageData(project, pathCache)} {} ImageCacheConnectionManager connectionManager; @@ -235,8 +241,23 @@ public: QPointer<::ProjectExplorer::Target> activeTarget; }; +class QmlDesignerProjectManager::Data +{ +public: + Data(ExternalDependenciesInterface &externalDependencies) + : sourcePathDatabase{externalDependencies.userResourcePath(u"source_path.db")} + {} + +public: + Sqlite::Database sourcePathDatabase; + QmlDesigner::SourcePathStorage sourcePathStorage{sourcePathDatabase, + sourcePathDatabase.isInitialized()}; + PathCacheType pathCache{sourcePathStorage}; +}; + QmlDesignerProjectManager::QmlDesignerProjectManager(ExternalDependenciesInterface &externalDependencies) - : m_previewImageCacheData{std::make_unique(externalDependencies)} + : m_data{std::make_unique(externalDependencies)} + , m_previewImageCacheData{std::make_unique(externalDependencies)} , m_externalDependencies{externalDependencies} { auto editorManager = ::Core::EditorManager::instance(); @@ -303,8 +324,7 @@ namespace { ProjectStorageDependencies QmlDesignerProjectManager::projectStorageDependencies() { if constexpr (useProjectStorage()) { - return {m_projectData->projectStorageData->storage, - m_projectData->projectStorageData->pathCache}; + return {m_projectData->projectStorageData->storage, m_data->pathCache}; } else { return {*dummyProjectStorage(), *dummyPathCache()}; } @@ -456,9 +476,8 @@ QString qtCreatorItemLibraryPath() void QmlDesignerProjectManager::projectAdded(::ProjectExplorer::Project *project) { - m_projectData = std::make_unique(m_previewImageCacheData->storage, - project, - m_externalDependencies); + m_projectData = std::make_unique( + m_previewImageCacheData->storage, project, m_data->pathCache, m_externalDependencies); m_projectData->activeTarget = project->activeTarget(); QObject::connect(project, &::ProjectExplorer::Project::fileListChanged, [&]() { diff --git a/src/plugins/qmldesigner/qmldesignerprojectmanager.h b/src/plugins/qmldesigner/qmldesignerprojectmanager.h index 1e5cec2e3e3..10c0bd42618 100644 --- a/src/plugins/qmldesigner/qmldesignerprojectmanager.h +++ b/src/plugins/qmldesigner/qmldesignerprojectmanager.h @@ -33,6 +33,7 @@ class QmlDesignerProjectManager class QmlDesignerProjectManagerProjectData; class PreviewImageCacheData; class ImageCacheData; + class Data; public: QmlDesignerProjectManager(ExternalDependenciesInterface &externalDependencies); @@ -63,6 +64,7 @@ private: void update(); private: + std::unique_ptr m_data; std::once_flag imageCacheFlag; std::unique_ptr m_imageCacheData; std::unique_ptr m_previewImageCacheData; diff --git a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp index d37b639cd0c..40da278ef3e 100644 --- a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp +++ b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp @@ -166,8 +166,11 @@ public: bool isQt6Project() const override { return {}; } bool isQtForMcusProject() const override { return {}; } QString qtQuickVersion() const override { return {}; } + Utils::FilePath resourcePath(const QString &) const override { return {}; } + QString userResourcePath(QStringView) const override { return {}; } + public: Utils::QtcSettings qsettings; QmlDesigner::DesignerSettings settings{&qsettings}; diff --git a/tests/unit/tests/mocks/externaldependenciesmock.h b/tests/unit/tests/mocks/externaldependenciesmock.h index df70a7fcdb3..f7375af2a3d 100644 --- a/tests/unit/tests/mocks/externaldependenciesmock.h +++ b/tests/unit/tests/mocks/externaldependenciesmock.h @@ -41,4 +41,5 @@ public: MOCK_METHOD(bool, isQtForMcusProject, (), (const, override)); MOCK_METHOD(QString, qtQuickVersion, (), (const, override)); MOCK_METHOD(Utils::FilePath, resourcePath, (const QString &relativePath), (const, override)); + MOCK_METHOD(QString, userResourcePath, (QStringView relativePath), (const, override)); }; diff --git a/tests/unit/tests/mocks/projectstoragemock.h b/tests/unit/tests/mocks/projectstoragemock.h index ef9b4e87b20..9e06db5aef5 100644 --- a/tests/unit/tests/mocks/projectstoragemock.h +++ b/tests/unit/tests/mocks/projectstoragemock.h @@ -11,7 +11,7 @@ #include #include #include -#include +#include class ProjectStorageMock : public QmlDesigner::ProjectStorageInterface { diff --git a/tests/unit/tests/mocks/sourcepathcachemock.h b/tests/unit/tests/mocks/sourcepathcachemock.h index 3e151607235..3e04ce98600 100644 --- a/tests/unit/tests/mocks/sourcepathcachemock.h +++ b/tests/unit/tests/mocks/sourcepathcachemock.h @@ -5,9 +5,9 @@ #include "../utils/googletest.h" -#include -#include -#include +#include +#include +#include class SourcePathCacheMock : public QmlDesigner::SourcePathCacheInterface { diff --git a/tests/unit/tests/mocks/sqlitereadstatementmock.h b/tests/unit/tests/mocks/sqlitereadstatementmock.h index 45c30d46290..aaeb9df94b4 100644 --- a/tests/unit/tests/mocks/sqlitereadstatementmock.h +++ b/tests/unit/tests/mocks/sqlitereadstatementmock.h @@ -7,8 +7,8 @@ #include #include -#include #include +#include #include #include #include diff --git a/tests/unit/tests/printers/gtest-creator-printing.cpp b/tests/unit/tests/printers/gtest-creator-printing.cpp index 4d70b5b68bf..fac58b7bd90 100644 --- a/tests/unit/tests/printers/gtest-creator-printing.cpp +++ b/tests/unit/tests/printers/gtest-creator-printing.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/tests/unit/tests/testdesignercore/CMakeLists.txt b/tests/unit/tests/testdesignercore/CMakeLists.txt index a06525bccb7..691b6723932 100644 --- a/tests/unit/tests/testdesignercore/CMakeLists.txt +++ b/tests/unit/tests/testdesignercore/CMakeLists.txt @@ -122,7 +122,7 @@ add_qtc_library(TestDesignerCore OBJECT projectstorage/filestatus.h projectstorage/filestatuscache.cpp projectstorage/filestatuscache.h projectstorage/modulescanner.cpp projectstorage/modulescanner.h - projectstorage/nonlockingmutex.h + sourcepathstorage/nonlockingmutex.h projectstorage/projectstorageexceptions.cpp projectstorage/projectstorageexceptions.h projectstorage/projectstorageinterface.h projectstorage/projectstorageobserver.h @@ -136,14 +136,18 @@ add_qtc_library(TestDesignerCore OBJECT projectstorage/projectstoragepathwatchertypes.h projectstorage/projectstoragetypes.h projectstorage/projectstorageupdater.cpp projectstorage/projectstorageupdater.h - projectstorage/sourcepath.h - projectstorage/sourcepathcache.h - projectstorage/sourcepathcache.h - projectstorage/sourcepathcachetypes.h - projectstorage/sourcepathview.h - projectstorage/storagecache.h - projectstorage/storagecacheentry.h - projectstorage/storagecachefwd.h + sourcepathstorage/sourcepath.h + sourcepathstorage/sourcepathcache.h + sourcepathstorage/sourcepathcache.h + sourcepathstorage/sourcepathcachetypes.h + sourcepathstorage/sourcepathview.h + sourcepathstorage/storagecache.h + sourcepathstorage/storagecacheentry.h + sourcepathstorage/storagecachefwd.h + sourcepathstorage/sourcepathexceptions.cpp + sourcepathstorage/sourcepathexceptions.h + sourcepathstorage/sourcepathstorage.cpp + sourcepathstorage/sourcepathstorage.h projectstorage/typeannotationreader.cpp projectstorage/typeannotationreader.h projectstorage/qmldocumentparserinterface.h diff --git a/tests/unit/tests/unittests/CMakeLists.txt b/tests/unit/tests/unittests/CMakeLists.txt index 0c5f8bfd5ed..c1ad2c3a996 100644 --- a/tests/unit/tests/unittests/CMakeLists.txt +++ b/tests/unit/tests/unittests/CMakeLists.txt @@ -52,5 +52,6 @@ add_subdirectory(metainfo) add_subdirectory(model) add_subdirectory(sqlite) add_subdirectory(projectstorage) +add_subdirectory(sourcepathstorage) add_subdirectory(qmlprojectmanager) add_subdirectory(utils) diff --git a/tests/unit/tests/unittests/projectstorage/CMakeLists.txt b/tests/unit/tests/unittests/projectstorage/CMakeLists.txt index 2f7aaccf7a3..69818ff6a44 100644 --- a/tests/unit/tests/unittests/projectstorage/CMakeLists.txt +++ b/tests/unit/tests/unittests/projectstorage/CMakeLists.txt @@ -7,10 +7,6 @@ extend_qtc_test(unittest projectstorage-test.cpp projectstoragepathwatcher-test.cpp projectstorageupdater-test.cpp - sourcepath-test.cpp - sourcepathcache-test.cpp - sourcepathview-test.cpp - storagecache-test.cpp typeannotationreader-test.cpp ) diff --git a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp index 2fa1042929a..521381aa840 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include #include @@ -19,14 +19,11 @@ namespace { -using QmlDesigner::Cache::SourceContext; -using QmlDesigner::Cache::SourceName; using QmlDesigner::FileStatus; using QmlDesigner::FileStatuses; using QmlDesigner::FlagIs; using QmlDesigner::ModuleId; using QmlDesigner::PropertyDeclarationId; -using QmlDesigner::SourceContextId; using QmlDesigner::SourceId; using QmlDesigner::SourceIds; using QmlDesigner::SourceNameId; @@ -57,16 +54,6 @@ auto IsModule(Utils::SmallStringView name, ModuleKind kind) Field(&QmlDesigner::Storage::Module::kind, kind)); } -MATCHER_P2(IsSourceContext, - id, - value, - std::string(negation ? "isn't " : "is ") + PrintToString(SourceContext{value, id})) -{ - const SourceContext &sourceContext = arg; - - return sourceContext.id == id && sourceContext.value == value; -} - MATCHER_P4(IsStorageType, sourceId, typeName, @@ -319,8 +306,11 @@ protected: struct StaticData { Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + Sqlite::Database sourcePathDatabase{":memory:", Sqlite::JournalMode::Memory}; NiceMock errorNotifierMock; QmlDesigner::ProjectStorage storage{database, errorNotifierMock, database.isInitialized()}; + QmlDesigner::SourcePathStorage sourcePathStorage{sourcePathDatabase, + sourcePathDatabase.isInitialized()}; }; static void SetUpTestSuite() { staticData = std::make_unique(); } @@ -331,26 +321,6 @@ protected: ~ProjectStorage() { storage.resetForTestsOnly(); } - template - static auto toValues(Range &&range) - { - using Type = typename std::decay_t; - - return std::vector{range.begin(), range.end()}; - } - - void addSomeDummyData() - { - storage.fetchSourceContextId("/path/dummy"); - storage.fetchSourceContextId("/path/dummy2"); - storage.fetchSourceContextId("/path/"); - - storage.fetchSourceNameId("foo"); - storage.fetchSourceNameId("dummy"); - storage.fetchSourceNameId("bar"); - storage.fetchSourceNameId("bar"); - } - auto createVerySimpleSynchronizationPackage() { SynchronizationPackage package; @@ -1229,7 +1199,8 @@ protected: Sqlite::Database &database = staticData->database; QmlDesigner::ProjectStorage &storage = staticData->storage; NiceMock errorNotifierMock; - QmlDesigner::SourcePathCache sourcePathCache{storage}; + QmlDesigner::SourcePathCache sourcePathCache{ + staticData->sourcePathStorage}; QmlDesigner::SourcePathView path1{"/path1/to"}; QmlDesigner::SourcePathView path2{"/path2/to"}; QmlDesigner::SourcePathView path3{"/path3/to"}; @@ -1269,147 +1240,6 @@ protected: Storage::Imports moduleDependenciesSourceId5; }; -TEST_F(ProjectStorage, fetch_source_context_id_returns_always_the_same_id_for_the_same_path) -{ - auto sourceContextId = storage.fetchSourceContextId("/path/to"); - - auto newSourceContextId = storage.fetchSourceContextId("/path/to"); - - ASSERT_THAT(newSourceContextId, Eq(sourceContextId)); -} - -TEST_F(ProjectStorage, fetch_source_context_id_returns_not_the_same_id_for_different_path) -{ - auto sourceContextId = storage.fetchSourceContextId("/path/to"); - - auto newSourceContextId = storage.fetchSourceContextId("/path/to2"); - - ASSERT_THAT(newSourceContextId, Ne(sourceContextId)); -} - -TEST_F(ProjectStorage, fetch_source_context_path) -{ - auto sourceContextId = storage.fetchSourceContextId("/path/to"); - - auto path = storage.fetchSourceContextPath(sourceContextId); - - ASSERT_THAT(path, Eq("/path/to")); -} - -TEST_F(ProjectStorage, fetch_unknown_source_context_path_throws) -{ - ASSERT_THROW(storage.fetchSourceContextPath(SourceContextId::create(323)), - QmlDesigner::SourceContextIdDoesNotExists); -} - -TEST_F(ProjectStorage, fetch_all_source_contexts_are_empty_if_no_source_contexts_exists) -{ - storage.clearSources(); - - auto sourceContexts = storage.fetchAllSourceContexts(); - - ASSERT_THAT(toValues(sourceContexts), IsEmpty()); -} - -TEST_F(ProjectStorage, fetch_all_source_contexts) -{ - storage.clearSources(); - auto sourceContextId = storage.fetchSourceContextId("/path/to"); - auto sourceContextId2 = storage.fetchSourceContextId("/path/to2"); - - auto sourceContexts = storage.fetchAllSourceContexts(); - - ASSERT_THAT(toValues(sourceContexts), - UnorderedElementsAre(IsSourceContext(sourceContextId, "/path/to"), - IsSourceContext(sourceContextId2, "/path/to2"))); -} - -TEST_F(ProjectStorage, fetch_source_id_first_time) -{ - addSomeDummyData(); - - auto sourceNameId = storage.fetchSourceNameId("foo"); - - ASSERT_TRUE(sourceNameId.isValid()); -} - -TEST_F(ProjectStorage, fetch_existing_source_id) -{ - addSomeDummyData(); - auto createdSourceNameId = storage.fetchSourceNameId("foo"); - - auto sourceNameId = storage.fetchSourceNameId("foo"); - - ASSERT_THAT(sourceNameId, createdSourceNameId); -} - -TEST_F(ProjectStorage, fetch_source_id_with_different_name_are_not_equal) -{ - addSomeDummyData(); - auto sourceNameId2 = storage.fetchSourceNameId("foo"); - - auto sourceNameId = storage.fetchSourceNameId("foo2"); - - ASSERT_THAT(sourceNameId, Ne(sourceNameId2)); -} - -TEST_F(ProjectStorage, fetch_source_name_and_source_context_id_for_non_existing_source_id) -{ - ASSERT_THROW(storage.fetchSourceName(SourceNameId::create(212)), - QmlDesigner::SourceNameIdDoesNotExists); -} - -TEST_F(ProjectStorage, fetch_source_name_for_non_existing_entry) -{ - addSomeDummyData(); - auto sourceNameId = storage.fetchSourceNameId("foo"); - - auto sourceName = storage.fetchSourceName(sourceNameId); - - ASSERT_THAT(sourceName, Eq("foo")); -} - -TEST_F(ProjectStorage, fetch_all_sources) -{ - storage.clearSources(); - - auto sources = storage.fetchAllSourceNames(); - - ASSERT_THAT(toValues(sources), IsEmpty()); -} - -TEST_F(ProjectStorage, fetch_source_id_unguarded_first_time) -{ - addSomeDummyData(); - std::lock_guard lock{database}; - - auto sourceId = storage.fetchSourceNameIdUnguarded("foo"); - - ASSERT_TRUE(sourceId.isValid()); -} - -TEST_F(ProjectStorage, fetch_existing_source_id_unguarded) -{ - addSomeDummyData(); - std::lock_guard lock{database}; - auto createdSourceId = storage.fetchSourceNameIdUnguarded("foo"); - - auto sourceId = storage.fetchSourceNameIdUnguarded("foo"); - - ASSERT_THAT(sourceId, createdSourceId); -} - -TEST_F(ProjectStorage, fetch_source_id_unguarded_with_different_name_are_not_equal) -{ - addSomeDummyData(); - std::lock_guard lock{database}; - auto sourceId2 = storage.fetchSourceNameIdUnguarded("foo"); - - auto sourceId = storage.fetchSourceNameIdUnguarded("foo2"); - - ASSERT_THAT(sourceId, Ne(sourceId2)); -} - TEST_F(ProjectStorage, synchronize_types_adds_new_types) { auto package{createSimpleSynchronizationPackage()}; diff --git a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp index 8e07782046e..879c3ce3ee0 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstoragepathwatcher-test.cpp @@ -11,13 +11,13 @@ #include #include -#include +#include #include #include namespace { -using SourcePathCache = QmlDesigner::SourcePathCache; +using SourcePathCache = QmlDesigner::SourcePathCache; using Watcher = QmlDesigner::ProjectStoragePathWatcher, NiceMock, SourcePathCache>; @@ -43,8 +43,11 @@ protected: struct StaticData { Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + Sqlite::Database sourcePathDatabase{":memory:", Sqlite::JournalMode::Memory}; ProjectStorageErrorNotifierMock errorNotifierMock; QmlDesigner::ProjectStorage storage{database, errorNotifierMock, database.isInitialized()}; + QmlDesigner::SourcePathStorage sourcePathStorage{sourcePathDatabase, + sourcePathDatabase.isInitialized()}; }; static void SetUpTestSuite() { staticData = std::make_unique(); } @@ -80,7 +83,7 @@ protected: inline static std::unique_ptr staticData; Sqlite::Database &database = staticData->database; QmlDesigner::ProjectStorage &storage = staticData->storage; - SourcePathCache pathCache{storage}; + SourcePathCache pathCache{staticData->sourcePathStorage}; Watcher watcher{pathCache, mockFileSystem, ¬ifier}; NiceMock &mockQFileSytemWatcher = watcher.fileSystemWatcher(); ProjectChunkId projectChunkId1{ProjectPartId::create(2), SourceType::Qml}; diff --git a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp index 0a072d9fcd1..60d617635da 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorageupdater-test.cpp @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include namespace { @@ -146,8 +146,11 @@ public: struct StaticData { Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + Sqlite::Database sourcePathDatabase{":memory:", Sqlite::JournalMode::Memory}; NiceMock errorNotifierMock; QmlDesigner::ProjectStorage storage{database, errorNotifierMock, database.isInitialized()}; + QmlDesigner::SourcePathStorage sourcePathStorage{sourcePathDatabase, + sourcePathDatabase.isInitialized()}; }; static void SetUpTestSuite() { staticData = std::make_unique(); } @@ -331,8 +334,8 @@ protected: inline static std::unique_ptr staticData; Sqlite::Database &database = staticData->database; QmlDesigner::ProjectStorage &storage = staticData->storage; - QmlDesigner::SourcePathCache sourcePathCache{ - storage}; + QmlDesigner::SourcePathCache sourcePathCache{ + staticData->sourcePathStorage}; NiceMock patchWatcherMock; QmlDesigner::ProjectPartId projectPartId = QmlDesigner::ProjectPartId::create(1); QmlDesigner::ProjectPartId otherProjectPartId = QmlDesigner::ProjectPartId::create(0); @@ -3491,7 +3494,7 @@ TEST_F(ProjectStorageUpdater, errors_for_watcher_updates_are_handled) setContent(u"/path/qmldir", qmldir); ON_CALL(projectStorageMock, synchronize(_)) - .WillByDefault(Throw(QmlDesigner::NoSourcePathForInvalidSourceId{})); + .WillByDefault(Throw(QmlDesigner::TypeHasInvalidSourceId{})); ASSERT_NO_THROW(updater.pathsWithIdsChanged({{directoryProjectChunkId, {directoryPathSourceId}}})); } @@ -3509,7 +3512,7 @@ TEST_F(ProjectStorageUpdater, input_is_reused_next_call_if_an_error_happens) {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); setFilesDontChanged({directoryPathSourceId, qmlDirPathSourceId}); ON_CALL(projectStorageMock, synchronize(_)) - .WillByDefault(Throw(QmlDesigner::NoSourcePathForInvalidSourceId{})); + .WillByDefault(Throw(QmlDesigner::TypeHasInvalidSourceId{})); updater.pathsWithIdsChanged( {{qmltypesProjectChunkId, {qmltypesPathSourceId, qmltypes2PathSourceId}}}); ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Return()); @@ -3569,7 +3572,7 @@ TEST_F(ProjectStorageUpdater, input_is_reused_next_call_if_an_error_happens_and_ {directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}}); setFilesDontChanged({directoryPathSourceId, qmlDirPathSourceId}); ON_CALL(projectStorageMock, synchronize(_)) - .WillByDefault(Throw(QmlDesigner::NoSourcePathForInvalidSourceId{})); + .WillByDefault(Throw(QmlDesigner::TypeHasInvalidSourceId{})); updater.pathsWithIdsChanged( {{qmltypesProjectChunkId, {qmltypesPathSourceId, qmltypes2PathSourceId}}}); ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Return()); @@ -3632,7 +3635,7 @@ TEST_F(ProjectStorageUpdater, input_is_reused_next_call_if_an_error_happens_and_ {directoryPathSourceId, qmlDocumentSourceId1, QmlDesigner::ModuleId{}, FileType::QmlDocument}}); setFilesDontChanged({directoryPathSourceId, qmlDirPathSourceId}); ON_CALL(projectStorageMock, synchronize(_)) - .WillByDefault(Throw(QmlDesigner::NoSourcePathForInvalidSourceId{})); + .WillByDefault(Throw(QmlDesigner::TypeHasInvalidSourceId{})); updater.pathsWithIdsChanged( {{qmlDocumentProjectChunkId, {qmlDocumentSourceId1, qmlDocumentSourceId2}}}); ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Return()); diff --git a/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp b/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp index 47f9bfdf86d..ee5ba836c2a 100644 --- a/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include namespace { @@ -151,8 +151,10 @@ protected: Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; ProjectStorageErrorNotifierMock errorNotifierMock; QmlDesigner::ProjectStorage storage{database, errorNotifierMock, database.isInitialized()}; - QmlDesigner::SourcePathCache sourcePathCache{ - storage}; + Sqlite::Database sourcePathDatabase{":memory:", Sqlite::JournalMode::Memory}; + QmlDesigner::SourcePathStorage sourcePathStorage{sourcePathDatabase, + sourcePathDatabase.isInitialized()}; + QmlDesigner::SourcePathCache sourcePathCache{sourcePathStorage}; QmlDesigner::QmlDocumentParser parser{storage, sourcePathCache}; Storage::Imports imports; SourceId qmlFileSourceId{sourcePathCache.sourceId("/path/to/qmlfile.qml")}; diff --git a/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp b/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp index 8b55eca7d3a..c33bcbf068f 100644 --- a/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include namespace { @@ -173,8 +173,10 @@ protected: Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; ProjectStorageErrorNotifierMock errorNotifierMock; QmlDesigner::ProjectStorage storage{database, errorNotifierMock, database.isInitialized()}; - QmlDesigner::SourcePathCache sourcePathCache{ - storage}; + Sqlite::Database sourcePathDatabase{":memory:", Sqlite::JournalMode::Memory}; + QmlDesigner::SourcePathStorage sourcePathStorage{sourcePathDatabase, + sourcePathDatabase.isInitialized()}; + QmlDesigner::SourcePathCache sourcePathCache{sourcePathStorage}; QmlDesigner::QmlTypesParser parser{storage}; Storage::Imports imports; Synchronization::Types types; diff --git a/tests/unit/tests/unittests/projectstorage/typeannotationreader-test.cpp b/tests/unit/tests/unittests/projectstorage/typeannotationreader-test.cpp index d55c368f6ee..b91a89bbaf7 100644 --- a/tests/unit/tests/unittests/projectstorage/typeannotationreader-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/typeannotationreader-test.cpp @@ -8,8 +8,8 @@ #include #include -#include #include +#include namespace { diff --git a/tests/unit/tests/unittests/sourcepathstorage/CMakeLists.txt b/tests/unit/tests/unittests/sourcepathstorage/CMakeLists.txt new file mode 100644 index 00000000000..6a2ec39146c --- /dev/null +++ b/tests/unit/tests/unittests/sourcepathstorage/CMakeLists.txt @@ -0,0 +1,11 @@ +# qmldesigner/designercore/projectstorage +extend_qtc_test(unittest + SOURCES + sourcepathstorage-test.cpp + sourcepath-test.cpp + sourcepathcache-test.cpp + sourcepathview-test.cpp + storagecache-test.cpp +) + +unittest_copy_data_folder() diff --git a/tests/unit/tests/unittests/projectstorage/sourcepath-test.cpp b/tests/unit/tests/unittests/sourcepathstorage/sourcepath-test.cpp similarity index 97% rename from tests/unit/tests/unittests/projectstorage/sourcepath-test.cpp rename to tests/unit/tests/unittests/sourcepathstorage/sourcepath-test.cpp index ffa4aa84d14..7092b965014 100644 --- a/tests/unit/tests/unittests/projectstorage/sourcepath-test.cpp +++ b/tests/unit/tests/unittests/sourcepathstorage/sourcepath-test.cpp @@ -3,7 +3,7 @@ #include "../utils/googletest.h" -#include +#include namespace { diff --git a/tests/unit/tests/unittests/projectstorage/sourcepathcache-test.cpp b/tests/unit/tests/unittests/sourcepathstorage/sourcepathcache-test.cpp similarity index 99% rename from tests/unit/tests/unittests/projectstorage/sourcepathcache-test.cpp rename to tests/unit/tests/unittests/sourcepathstorage/sourcepathcache-test.cpp index 7e2fdd17696..572d0f57f99 100644 --- a/tests/unit/tests/unittests/projectstorage/sourcepathcache-test.cpp +++ b/tests/unit/tests/unittests/sourcepathstorage/sourcepathcache-test.cpp @@ -6,7 +6,7 @@ #include "../mocks/projectstoragemock.h" #include "../mocks/sqlitedatabasemock.h" -#include +#include namespace { diff --git a/tests/unit/tests/unittests/sourcepathstorage/sourcepathstorage-test.cpp b/tests/unit/tests/unittests/sourcepathstorage/sourcepathstorage-test.cpp new file mode 100644 index 00000000000..abc08bf21b1 --- /dev/null +++ b/tests/unit/tests/unittests/sourcepathstorage/sourcepathstorage-test.cpp @@ -0,0 +1,211 @@ +// 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 "../utils/googletest.h" + +#include + +namespace { + +using QmlDesigner::Cache::SourceContext; +using QmlDesigner::Cache::SourceName; +using QmlDesigner::SourceContextId; +using QmlDesigner::SourceId; +using QmlDesigner::SourceIds; +using QmlDesigner::SourceNameId; + +MATCHER_P2(IsSourceContext, + id, + value, + std::string(negation ? "isn't " : "is ") + PrintToString(SourceContext{value, id})) +{ + const SourceContext &sourceContext = arg; + + return sourceContext.id == id && sourceContext.value == value; +} + +class SourcePathStorage : public testing::Test +{ +protected: + struct StaticData + { + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + QmlDesigner::SourcePathStorage storage{database, database.isInitialized()}; + }; + + static void SetUpTestSuite() { staticData = std::make_unique(); } + + static void TearDownTestSuite() { staticData.reset(); } + + SourcePathStorage() = default; + + ~SourcePathStorage() { storage.resetForTestsOnly(); } + + void addSomeDummyData() + { + storage.fetchSourceContextId("/path/dummy"); + storage.fetchSourceContextId("/path/dummy2"); + storage.fetchSourceContextId("/path/"); + + storage.fetchSourceNameId("foo"); + storage.fetchSourceNameId("dummy"); + storage.fetchSourceNameId("bar"); + storage.fetchSourceNameId("bar"); + } + + template + static auto toValues(Range &&range) + { + using Type = typename std::decay_t; + + return std::vector{range.begin(), range.end()}; + } + +protected: + inline static std::unique_ptr staticData; + QmlDesigner::SourcePathStorage &storage = staticData->storage; + Sqlite::Database &database = staticData->database; +}; + +TEST_F(SourcePathStorage, fetch_source_context_id_returns_always_the_same_id_for_the_same_path) + +{ + auto sourceContextId = storage.fetchSourceContextId("/path/to"); + + auto newSourceContextId = storage.fetchSourceContextId("/path/to"); + + ASSERT_THAT(newSourceContextId, Eq(sourceContextId)); +} + +TEST_F(SourcePathStorage, fetch_source_context_id_returns_not_the_same_id_for_different_path) +{ + auto sourceContextId = storage.fetchSourceContextId("/path/to"); + + auto newSourceContextId = storage.fetchSourceContextId("/path/to2"); + + ASSERT_THAT(newSourceContextId, Ne(sourceContextId)); +} + +TEST_F(SourcePathStorage, fetch_source_context_path) +{ + auto sourceContextId = storage.fetchSourceContextId("/path/to"); + + auto path = storage.fetchSourceContextPath(sourceContextId); + + ASSERT_THAT(path, Eq("/path/to")); +} + +TEST_F(SourcePathStorage, fetch_unknown_source_context_path_throws) +{ + ASSERT_THROW(storage.fetchSourceContextPath(SourceContextId::create(323)), + QmlDesigner::SourceContextIdDoesNotExists); +} + +TEST_F(SourcePathStorage, fetch_all_source_contexts_are_empty_if_no_source_contexts_exists) +{ + storage.clearSources(); + + auto sourceContexts = storage.fetchAllSourceContexts(); + + ASSERT_THAT(toValues(sourceContexts), IsEmpty()); +} + +TEST_F(SourcePathStorage, fetch_all_source_contexts) +{ + storage.clearSources(); + auto sourceContextId = storage.fetchSourceContextId("/path/to"); + auto sourceContextId2 = storage.fetchSourceContextId("/path/to2"); + + auto sourceContexts = storage.fetchAllSourceContexts(); + + ASSERT_THAT(toValues(sourceContexts), + UnorderedElementsAre(IsSourceContext(sourceContextId, "/path/to"), + IsSourceContext(sourceContextId2, "/path/to2"))); +} + +TEST_F(SourcePathStorage, fetch_source_id_first_time) +{ + addSomeDummyData(); + + auto sourceNameId = storage.fetchSourceNameId("foo"); + + ASSERT_TRUE(sourceNameId.isValid()); +} + +TEST_F(SourcePathStorage, fetch_existing_source_id) +{ + addSomeDummyData(); + auto createdSourceNameId = storage.fetchSourceNameId("foo"); + + auto sourceNameId = storage.fetchSourceNameId("foo"); + + ASSERT_THAT(sourceNameId, createdSourceNameId); +} + +TEST_F(SourcePathStorage, fetch_source_id_with_different_name_are_not_equal) +{ + addSomeDummyData(); + auto sourceNameId2 = storage.fetchSourceNameId("foo"); + + auto sourceNameId = storage.fetchSourceNameId("foo2"); + + ASSERT_THAT(sourceNameId, Ne(sourceNameId2)); +} + +TEST_F(SourcePathStorage, fetch_source_name_and_source_context_id_for_non_existing_source_id) +{ + ASSERT_THROW(storage.fetchSourceName(SourceNameId::create(212)), + QmlDesigner::SourceNameIdDoesNotExists); +} + +TEST_F(SourcePathStorage, fetch_source_name_for_non_existing_entry) +{ + addSomeDummyData(); + auto sourceNameId = storage.fetchSourceNameId("foo"); + + auto sourceName = storage.fetchSourceName(sourceNameId); + + ASSERT_THAT(sourceName, Eq("foo")); +} + +TEST_F(SourcePathStorage, fetch_all_sources) +{ + storage.clearSources(); + + auto sources = storage.fetchAllSourceNames(); + + ASSERT_THAT(toValues(sources), IsEmpty()); +} + +TEST_F(SourcePathStorage, fetch_source_id_unguarded_first_time) +{ + addSomeDummyData(); + std::lock_guard lock{database}; + + auto sourceId = storage.fetchSourceNameIdUnguarded("foo"); + + ASSERT_TRUE(sourceId.isValid()); +} + +TEST_F(SourcePathStorage, fetch_existing_source_id_unguarded) +{ + addSomeDummyData(); + std::lock_guard lock{database}; + auto createdSourceId = storage.fetchSourceNameIdUnguarded("foo"); + + auto sourceId = storage.fetchSourceNameIdUnguarded("foo"); + + ASSERT_THAT(sourceId, createdSourceId); +} + +TEST_F(SourcePathStorage, fetch_source_id_unguarded_with_different_name_are_not_equal) +{ + addSomeDummyData(); + std::lock_guard lock{database}; + auto sourceId2 = storage.fetchSourceNameIdUnguarded("foo"); + + auto sourceId = storage.fetchSourceNameIdUnguarded("foo2"); + + ASSERT_THAT(sourceId, Ne(sourceId2)); +} +} // namespace diff --git a/tests/unit/tests/unittests/projectstorage/sourcepathview-test.cpp b/tests/unit/tests/unittests/sourcepathstorage/sourcepathview-test.cpp similarity index 97% rename from tests/unit/tests/unittests/projectstorage/sourcepathview-test.cpp rename to tests/unit/tests/unittests/sourcepathstorage/sourcepathview-test.cpp index a05d91ac159..c5f35f921c9 100644 --- a/tests/unit/tests/unittests/projectstorage/sourcepathview-test.cpp +++ b/tests/unit/tests/unittests/sourcepathstorage/sourcepathview-test.cpp @@ -3,7 +3,7 @@ #include "../utils/googletest.h" -#include +#include namespace { diff --git a/tests/unit/tests/unittests/projectstorage/storagecache-test.cpp b/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp similarity index 99% rename from tests/unit/tests/unittests/projectstorage/storagecache-test.cpp rename to tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp index d9c8383ad9f..4b4850e26ae 100644 --- a/tests/unit/tests/unittests/projectstorage/storagecache-test.cpp +++ b/tests/unit/tests/unittests/sourcepathstorage/storagecache-test.cpp @@ -7,8 +7,8 @@ #include "../mocks/projectstoragemock.h" #include "../mocks/sqlitedatabasemock.h" -#include -#include +#include +#include #include From 6c45817004f98518e6152856be91bf4c88c8cfe5 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 19 Aug 2024 14:45:21 +0200 Subject: [PATCH 053/193] QmlDesigner: Move files to componentcore Change-Id: I9bea81b1d340978ec49e9d55ee009abfad832021 Reviewed-by: Thomas Hartmann --- src/plugins/qmldesigner/CMakeLists.txt | 13 ++++--------- .../{ => componentcore}/createtexture.cpp | 0 .../components/{ => componentcore}/createtexture.h | 0 .../qmldesignercomponents_global.h | 0 4 files changed, 4 insertions(+), 9 deletions(-) rename src/plugins/qmldesigner/components/{ => componentcore}/createtexture.cpp (100%) rename src/plugins/qmldesigner/components/{ => componentcore}/createtexture.h (100%) rename src/plugins/qmldesigner/components/{ => componentcore}/qmldesignercomponents_global.h (100%) diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index a85b3010ff2..435d68e2b5e 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -554,6 +554,7 @@ add_qtc_plugin(QmlDesigner ${CMAKE_CURRENT_LIST_DIR}/designercore #can not be a public dependency -> EXCLUDE_FROM_INSTALL in QmlDesignerCore ${CMAKE_CURRENT_LIST_DIR}/designercore/include #iwidgetplugin.h is used by other plugins ${CMAKE_CURRENT_LIST_DIR}/designercore/designercoreutils + ${CMAKE_CURRENT_LIST_DIR}/components SOURCES designmodecontext.cpp designmodecontext.h designmodewidget.cpp designmodewidget.h @@ -631,18 +632,10 @@ if (QTC_STATIC_BUILD AND TARGET QmlDesigner) extend_qtc_target(QmlDesigner PUBLIC_DEPENDS TextEditor) endif() -extend_qtc_plugin(QmlDesigner - SOURCES_PREFIX components - PUBLIC_INCLUDES components - DEFINES QMLDESIGNERCOMPONENTS_LIBRARY - SOURCES - createtexture.cpp createtexture.h - qmldesignercomponents_global.h -) - extend_qtc_plugin(QmlDesigner SOURCES_PREFIX components/componentcore PUBLIC_INCLUDES components/componentcore + DEFINES QMLDESIGNERCOMPONENTS_LIBRARY SOURCES abstractaction.cpp abstractaction.h abstractactiongroup.cpp abstractactiongroup.h @@ -652,6 +645,7 @@ extend_qtc_plugin(QmlDesigner changestyleaction.cpp changestyleaction.h componentcore.qrc componentcore_constants.h + createtexture.cpp createtexture.h crumblebar.cpp crumblebar.h designeractionmanager.cpp designeractionmanager.h designeractionmanagerview.cpp designeractionmanagerview.h @@ -667,6 +661,7 @@ extend_qtc_plugin(QmlDesigner propertyeditorcomponentgenerator.cpp propertyeditorcomponentgenerator.h propertycomponentgenerator.cpp propertycomponentgenerator.h propertycomponentgeneratorinterface.h + qmldesignercomponents_global.h qmldesignericonprovider.cpp qmldesignericonprovider.h qmleditormenu.cpp qmleditormenu.h resourcegenerator.cpp resourcegenerator.h diff --git a/src/plugins/qmldesigner/components/createtexture.cpp b/src/plugins/qmldesigner/components/componentcore/createtexture.cpp similarity index 100% rename from src/plugins/qmldesigner/components/createtexture.cpp rename to src/plugins/qmldesigner/components/componentcore/createtexture.cpp diff --git a/src/plugins/qmldesigner/components/createtexture.h b/src/plugins/qmldesigner/components/componentcore/createtexture.h similarity index 100% rename from src/plugins/qmldesigner/components/createtexture.h rename to src/plugins/qmldesigner/components/componentcore/createtexture.h diff --git a/src/plugins/qmldesigner/components/qmldesignercomponents_global.h b/src/plugins/qmldesigner/components/componentcore/qmldesignercomponents_global.h similarity index 100% rename from src/plugins/qmldesigner/components/qmldesignercomponents_global.h rename to src/plugins/qmldesigner/components/componentcore/qmldesignercomponents_global.h From f52edeb2fec45f69c10f8625a458c9c5b5b1219d Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 15 Aug 2024 16:27:42 +0200 Subject: [PATCH 054/193] QmlDesigner: Remove unused function Change-Id: I3118ce07e81221ee99cf0bc5fb2bdd0e53a9b930 Reviewed-by: Thomas Hartmann --- src/plugins/qmldesigner/CMakeLists.txt | 35 -------------------------- 1 file changed, 35 deletions(-) diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 435d68e2b5e..9542a9a7a9b 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -589,41 +589,6 @@ extend_qtc_plugin(QmlDesigner PUBLIC_COMPILE_OPTIONS $<$:-Wno-error=maybe-uninitialized> ) -function(get_and_add_as_subdirectory name repository git_tag build_dir source_dir source_subdir) - # make the configuration in the build dir - file(MAKE_DIRECTORY ${build_dir}/${name}) - file(WRITE ${build_dir}/${name}/CMakeLists.txt - " cmake_minimum_required(VERSION 3.16)\n" - " project(${name}-download NONE)\n" - " \n" - " include(ExternalProject)\n" - " ExternalProject_Add(${name}\n" - " UPDATE_DISCONNECTED FALSE\n" - " GIT_REPOSITORY \"${repository}\"\n" - " GIT_SUBMODULES \"\"\n" - " GIT_TAG \"${git_tag}\"\n" - " SOURCE_SUBDIR \"\"\n" - " GIT_SHALLOW TRUE\n" - " GIT_PROGRESS TRUE\n" - " SOURCE_DIR \"${source_dir}/${name}\"\n" - " CONFIGURE_COMMAND \"\"\n" - " BUILD_COMMAND \"\"\n" - " INSTALL_COMMAND \"\"\n" - " TEST_COMMAND \"\"\n" - " USES_TERMINAL_DOWNLOAD YES\n" - " USES_TERMINAL_UPDATE YES\n" - " )\n" - ) - execute_process(COMMAND "${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" "${build_dir}/${name}" - WORKING_DIRECTORY "${build_dir}/${name}" - ${QTC_COMMAND_ERROR_IS_FATAL} - ) - execute_process(COMMAND "${CMAKE_COMMAND}" --build "${build_dir}/${name}" - ${QTC_COMMAND_ERROR_IS_FATAL} - ) - add_subdirectory(${source_dir}/${name}/${source_subdir} ${name}) -endfunction() - if (QTC_STATIC_BUILD AND TARGET QmlDesigner) get_target_property(_designerType Qt::Designer TYPE) if (${_designerType} STREQUAL "STATIC_LIBRARY") From 9d4c50640c6406c0c33582234c7bad4ec2b1fce9 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 16 Aug 2024 18:17:19 +0200 Subject: [PATCH 055/193] QmlDesigner: Some more reserves and emplace_backs Change-Id: I0480b5f596d39dcd0bf77e54c7beaa8e0bf3fc3f Reviewed-by: Thomas Hartmann --- .../qmldesigner/designercore/model/model.cpp | 55 ++++++++++--------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index f0e3246fbbe..edc0400eb8a 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -663,8 +663,9 @@ void ModelPrivate::notifyInstanceErrorChange(const QVector &instanceIds) { notifyInstanceChanges([&](AbstractView *view) { QVector errorNodeList; + errorNodeList.reserve(instanceIds.size()); for (qint32 instanceId : instanceIds) - errorNodeList.append(ModelNode(m_model->d->nodeForInternalId(instanceId), m_model, view)); + errorNodeList.emplace_back(m_model->d->nodeForInternalId(instanceId), m_model, view); view->instanceErrorChanged(errorNodeList); }); } @@ -819,10 +820,8 @@ void ModelPrivate::notifyPropertiesRemoved(const QList &propertyPa notifyNormalViewsLast([&](AbstractView *view) { QList propertyList; propertyList.reserve(propertyPairList.size()); - for (const PropertyPair &propertyPair : propertyPairList) { - AbstractProperty newProperty(propertyPair.second, propertyPair.first, m_model, view); - propertyList.append(newProperty); - } + for (const PropertyPair &propertyPair : propertyPairList) + propertyList.emplace_back(propertyPair.second, propertyPair.first, m_model, view); view->propertiesRemoved(propertyList); }); @@ -989,11 +988,12 @@ void ModelPrivate::notifyBindingPropertiesAboutToBeChanged( { notifyNodeInstanceViewLast([&](AbstractView *view) { QList propertyList; + propertyList.reserve(internalPropertyList.size()); for (auto bindingProperty : internalPropertyList) { - propertyList.append(BindingProperty(bindingProperty->name(), - bindingProperty->propertyOwner(), - m_model, - view)); + propertyList.emplace_back(bindingProperty->name(), + bindingProperty->propertyOwner(), + m_model, + view); } view->bindingPropertiesAboutToBeChanged(propertyList); }); @@ -1004,11 +1004,12 @@ void ModelPrivate::notifyBindingPropertiesChanged(const QList propertyList; + propertyList.reserve(internalPropertyList.size()); for (auto bindingProperty : internalPropertyList) { - propertyList.append(BindingProperty(bindingProperty->name(), - bindingProperty->propertyOwner(), - m_model, - view)); + propertyList.emplace_back(bindingProperty->name(), + bindingProperty->propertyOwner(), + m_model, + view); } view->bindingPropertiesChanged(propertyList, propertyChange); }); @@ -1020,11 +1021,12 @@ void ModelPrivate::notifySignalHandlerPropertiesChanged( { notifyNodeInstanceViewLast([&](AbstractView *view) { QVector propertyList; + propertyList.reserve(internalPropertyList.size()); for (auto signalHandlerProperty : internalPropertyList) { - propertyList.append(SignalHandlerProperty(signalHandlerProperty->name(), - signalHandlerProperty->propertyOwner(), - m_model, - view)); + propertyList.emplace_back(signalHandlerProperty->name(), + signalHandlerProperty->propertyOwner(), + m_model, + view); } view->signalHandlerPropertiesChanged(propertyList, propertyChange); }); @@ -1036,11 +1038,12 @@ void ModelPrivate::notifySignalDeclarationPropertiesChanged( { notifyNodeInstanceViewLast([&](AbstractView *view) { QVector propertyList; + propertyList.reserve(internalPropertyList.size()); for (auto signalHandlerProperty : internalPropertyList) { - propertyList.append(SignalDeclarationProperty(signalHandlerProperty->name(), - signalHandlerProperty->propertyOwner(), - m_model, - view)); + propertyList.emplace_back(signalHandlerProperty->name(), + signalHandlerProperty->propertyOwner(), + m_model, + view); } view->signalDeclarationPropertiesChanged(propertyList, propertyChange); }); @@ -1060,10 +1063,9 @@ void ModelPrivate::notifyVariantPropertiesChanged(const InternalNodePointer &nod { notifyNodeInstanceViewLast([&](AbstractView *view) { QList propertyList; - for (PropertyNameView propertyName : propertyNameViews) { - VariantProperty property(propertyName, node, m_model, view); - propertyList.append(property); - } + propertyList.reserve(propertyNameViews.size()); + for (PropertyNameView propertyName : propertyNameViews) + propertyList.emplace_back(propertyName, node, m_model, view); view->variantPropertiesChanged(propertyList, propertyChange); }); @@ -1216,8 +1218,9 @@ QList ModelPrivate::toModelNodeList(const QList QVector ModelPrivate::toModelNodeVector(const QVector &nodeVector, AbstractView *view) const { QVector modelNodeVector; + modelNodeVector.reserve(nodeVector.size()); for (const InternalNodePointer &node : nodeVector) - modelNodeVector.append(ModelNode(node, m_model, view)); + modelNodeVector.emplace_back(node, m_model, view); return modelNodeVector; } From 418191b884a85c0e8bd704714bd5f85978d1d1af Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Sat, 17 Aug 2024 01:28:36 +0200 Subject: [PATCH 056/193] QmlDesigner: More ranges Use ranges instead of iterators. Use predicates and projections instead of lambdas. auto is_equal_to(auto &&value) { return std::bind_front(std::ranges::equal_to{}, value); } Could be moved to Utils in the long run. Change-Id: I0241c432fee13e51b557fb3db855ccf8cdc65752 Reviewed-by: Thomas Hartmann --- src/libs/sqlite/sqliteids.h | 48 +-------- .../qmldesigner/designercore/model/model.cpp | 23 +++-- .../projectstorage/projectstorage.cpp | 99 ++++++++----------- .../projectstorage/projectstorage.h | 14 +-- 4 files changed, 65 insertions(+), 119 deletions(-) diff --git a/src/libs/sqlite/sqliteids.h b/src/libs/sqlite/sqliteids.h index f8a735de937..4e8eba801a4 100644 --- a/src/libs/sqlite/sqliteids.h +++ b/src/libs/sqlite/sqliteids.h @@ -44,23 +44,7 @@ public: return first.id == second.id; } - constexpr friend bool operator==(BasicId first, BasicId second) - { - return first.id == second.id && first.isValid() && second.isValid(); - } - - constexpr friend bool operator!=(BasicId first, BasicId second) { return !(first == second); } - - constexpr friend bool operator<(BasicId first, BasicId second) { return first.id < second.id; } - constexpr friend bool operator>(BasicId first, BasicId second) { return first.id > second.id; } - constexpr friend bool operator<=(BasicId first, BasicId second) - { - return first.id <= second.id; - } - constexpr friend bool operator>=(BasicId first, BasicId second) - { - return first.id >= second.id; - } + friend constexpr auto operator<=>(BasicId first, BasicId second) = default; constexpr friend InternalIntegerType operator-(BasicId first, BasicId second) { @@ -137,35 +121,7 @@ public: return first.id, second.id; } - friend constexpr bool operator==(CompoundBasicId first, CompoundBasicId second) - { - return first.id == second.id; - } - - friend constexpr bool operator!=(CompoundBasicId first, CompoundBasicId second) - { - return !(first == second); - } - - friend constexpr bool operator<(CompoundBasicId first, CompoundBasicId second) - { - return first.id < second.id; - } - - friend constexpr bool operator>(CompoundBasicId first, CompoundBasicId second) - { - return first.id > second.id; - } - - friend constexpr bool operator<=(CompoundBasicId first, CompoundBasicId second) - { - return first.id <= second.id; - } - - friend constexpr bool operator>=(CompoundBasicId first, CompoundBasicId second) - { - return first.id >= second.id; - } + friend constexpr auto operator<=>(CompoundBasicId first, CompoundBasicId second) = default; friend constexpr long long operator-(CompoundBasicId first, CompoundBasicId second) { diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index edc0400eb8a..ef96f8a6ef0 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -49,6 +49,9 @@ #include #include +#include +#include + /*! \defgroup CoreModel */ @@ -64,6 +67,14 @@ Components that want to be informed about changes in the model can register a su \see QmlDesigner::ModelNode, QmlDesigner::AbstractProperty, QmlDesigner::AbstractView */ +namespace { + +auto is_equal_to(auto &&value) +{ + return std::bind_front(std::ranges::equal_to{}, value); +} +} // namespace + namespace QmlDesigner { using NanotraceHR::keyValue; @@ -1919,9 +1930,7 @@ bool Model::hasId(const QString &id) const bool Model::hasImport(const QString &importUrl) const { - return Utils::anyOf(imports(), [&](const Import &import) { - return import.url() == importUrl; - }); + return std::ranges::any_of(imports(), is_equal_to(importUrl), &Import::url); } QString Model::generateNewId(const QString &prefixName, const QString &fallbackPrefix) const @@ -2749,8 +2758,7 @@ void Model::changeRootNodeType(const TypeName &type) void Model::removeModelNodes(ModelNodes nodes, BypassModelResourceManagement bypass) { - nodes.erase(std::remove_if(nodes.begin(), nodes.end(), [](auto &&node) { return !node; }), - nodes.end()); + nodes.removeIf(std::logical_not{}); if (nodes.empty()) return; @@ -2769,10 +2777,7 @@ void Model::removeModelNodes(ModelNodes nodes, BypassModelResourceManagement byp void Model::removeProperties(AbstractProperties properties, BypassModelResourceManagement bypass) { - properties.erase(std::remove_if(properties.begin(), - properties.end(), - [](auto &&property) { return !property; }), - properties.end()); + properties.removeIf(std::logical_not{}); if (properties.empty()) return; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp index ff7d406cf21..8e76356c6d8 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp @@ -7,6 +7,10 @@ namespace QmlDesigner { +using Storage::Synchronization::EnumerationDeclaration; +using Storage::Synchronization::Type; +using Storage::Synchronization::TypeAnnotation; + enum class SpecialIdState { Unresolved = -1 }; constexpr TypeId unresolvedTypeId = TypeId::createSpecialState(SpecialIdState::Unresolved); @@ -1269,7 +1273,7 @@ void ProjectStorage::synchronize(Storage::Synchronization::SynchronizationPackag TypeIds typeIdsToBeDeleted; - std::sort(package.updatedSourceIds.begin(), package.updatedSourceIds.end()); + std::ranges::sort(package.updatedSourceIds); synchronizeFileStatuses(package.fileStatuses, package.updatedFileStatusSourceIds); synchronizeImports(package.imports, @@ -1553,7 +1557,7 @@ QVarLengthArray ProjectStorage::propertyDeclarationI return fetchPropertyDeclarationIds(typeId); }); - std::sort(propertyDeclarationIds.begin(), propertyDeclarationIds.end()); + std::ranges::sort(propertyDeclarationIds); tracer.end(keyValue("property declaration ids", propertyDeclarationIds)); @@ -2283,7 +2287,7 @@ void ProjectStorage::callRefreshMetaInfoCallback(TypeIds &deletedTypeIds, SourceIds ProjectStorage::filterSourceIdsWithoutType(const SourceIds &updatedSourceIds, SourceIds &sourceIdsOfTypes) { - std::sort(sourceIdsOfTypes.begin(), sourceIdsOfTypes.end()); + std::ranges::sort(sourceIdsOfTypes); SourceIds sourceIdsWithoutTypeSourceIds; sourceIdsWithoutTypeSourceIds.reserve(updatedSourceIds.size()); @@ -2308,7 +2312,7 @@ TypeIds ProjectStorage::fetchTypeIds(const SourceIds &sourceIds) void ProjectStorage::unique(SourceIds &sourceIds) { - std::sort(sourceIds.begin(), sourceIds.end()); + std::ranges::sort(sourceIds); auto newEnd = std::unique(sourceIds.begin(), sourceIds.end()); sourceIds.erase(newEnd, sourceIds.end()); } @@ -2333,10 +2337,10 @@ void ProjectStorage::updateTypeIdInTypeAnnotations(Storage::Synchronization::Typ annotation.typeName); } - typeAnnotations.erase(std::remove_if(typeAnnotations.begin(), - typeAnnotations.end(), - [](const auto &annotation) { return !annotation.typeId; }), - typeAnnotations.end()); + auto [begin, end] = std::ranges::remove_if(typeAnnotations, + std::logical_not{}, + &TypeAnnotation::typeId); + typeAnnotations.erase(begin, end); } void ProjectStorage::synchronizeTypeAnnotations(Storage::Synchronization::TypeAnnotations &typeAnnotations, @@ -2344,15 +2348,12 @@ void ProjectStorage::synchronizeTypeAnnotations(Storage::Synchronization::TypeAn { NanotraceHR::Tracer tracer{"synchronize type annotations"_t, projectStorageCategory()}; - using Storage::Synchronization::TypeAnnotation; updateTypeIdInTypeAnnotations(typeAnnotations); auto compareKey = [](auto &&first, auto &&second) { return first.typeId - second.typeId; }; - std::sort(typeAnnotations.begin(), typeAnnotations.end(), [&](auto &&first, auto &&second) { - return first.typeId < second.typeId; - }); + std::ranges::sort(typeAnnotations, std::ranges::less{}, &TypeAnnotation::typeId); auto range = s->selectTypeAnnotationsForSourceIdsStatement.range( toIntegers(updatedTypeAnnotationSourceIds)); @@ -2468,9 +2469,7 @@ void ProjectStorage::synchronizeTypes(Storage::Synchronization::Types &types, } } - std::sort(types.begin(), types.end(), [](const auto &first, const auto &second) { - return first.typeId < second.typeId; - }); + std::ranges::sort(types, std::ranges::less{}, &Type::typeId); unique(exportedSourceIds); @@ -2507,7 +2506,7 @@ void ProjectStorage::synchronizeDirectoryInfos(Storage::Synchronization::Directo return first.sourceId - second.sourceId; }; - std::sort(directoryInfos.begin(), directoryInfos.end(), [&](auto &&first, auto &&second) { + std::ranges::sort(directoryInfos, [&](auto &&first, auto &&second) { return std::tie(first.directorySourceId, first.sourceId) < std::tie(second.directorySourceId, second.sourceId); }); @@ -2572,9 +2571,7 @@ void ProjectStorage::synchronizeFileStatuses(FileStatuses &fileStatuses, auto compareKey = [](auto &&first, auto &&second) { return first.sourceId - second.sourceId; }; - std::sort(fileStatuses.begin(), fileStatuses.end(), [&](auto &&first, auto &&second) { - return first.sourceId < second.sourceId; - }); + std::ranges::sort(fileStatuses, std::ranges::less{}, &FileStatus::sourceId); auto range = s->selectFileStatusesForSourceIdsStatement.range( toIntegers(updatedSourceIds)); @@ -2658,12 +2655,10 @@ void ProjectStorage::synchromizeModuleExportedImports( const ModuleIds &updatedModuleIds) { NanotraceHR::Tracer tracer{"synchronize module exported imports"_t, projectStorageCategory()}; - std::sort(moduleExportedImports.begin(), - moduleExportedImports.end(), - [](auto &&first, auto &&second) { - return std::tie(first.moduleId, first.exportedModuleId) - < std::tie(second.moduleId, second.exportedModuleId); - }); + std::ranges::sort(moduleExportedImports, [](auto &&first, auto &&second) { + return std::tie(first.moduleId, first.exportedModuleId) + < std::tie(second.moduleId, second.exportedModuleId); + }); auto range = s->selectModuleExportedImportsForSourceIdStatement .range( @@ -2961,7 +2956,7 @@ void ProjectStorage::relinkAliasPropertyDeclarations(AliasPropertyDeclarations & keyValue("alias property declarations", aliasPropertyDeclarations), keyValue("deleted type ids", deletedTypeIds)}; - std::sort(aliasPropertyDeclarations.begin(), aliasPropertyDeclarations.end()); + std::ranges::sort(aliasPropertyDeclarations); // todo remove duplicates Utils::set_greedy_difference( @@ -3006,7 +3001,7 @@ void ProjectStorage::relinkPropertyDeclarations(PropertyDeclarations &relinkable relinkablePropertyDeclaration), keyValue("deleted type ids", deletedTypeIds)}; - std::sort(relinkablePropertyDeclaration.begin(), relinkablePropertyDeclaration.end()); + std::ranges::sort(relinkablePropertyDeclaration); relinkablePropertyDeclaration.erase(std::unique(relinkablePropertyDeclaration.begin(), relinkablePropertyDeclaration.end()), relinkablePropertyDeclaration.end()); @@ -3043,9 +3038,9 @@ void ProjectStorage::relinkPrototypes(Prototypes &relinkablePrototypes, keyValue("relinkable prototypes", relinkablePrototypes), keyValue("deleted type ids", deletedTypeIds)}; - std::sort(relinkablePrototypes.begin(), relinkablePrototypes.end()); - relinkablePrototypes.erase(std::unique(relinkablePrototypes.begin(), relinkablePrototypes.end()), - relinkablePrototypes.end()); + std::ranges::sort(relinkablePrototypes); + auto [begin, end] = std::ranges::unique(relinkablePrototypes); + relinkablePrototypes.erase(begin, end); Utils::set_greedy_difference( relinkablePrototypes.cbegin(), @@ -3105,7 +3100,7 @@ void ProjectStorage::relink(AliasPropertyDeclarations &relinkableAliasPropertyDe { NanotraceHR::Tracer tracer{"relink"_t, projectStorageCategory()}; - std::sort(deletedTypeIds.begin(), deletedTypeIds.end()); + std::ranges::sort(deletedTypeIds); relinkPrototypes(relinkablePrototypes, deletedTypeIds, [&](TypeId typeId, TypeId prototypeId) { s->updateTypePrototypeStatement.write(typeId, prototypeId); @@ -3243,7 +3238,7 @@ void ProjectStorage::synchronizeExportedTypes(const TypeIds &updatedTypeIds, using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"synchronize exported types"_t, projectStorageCategory()}; - std::sort(exportedTypes.begin(), exportedTypes.end(), [](auto &&first, auto &&second) { + std::ranges::sort(exportedTypes, [](auto &&first, auto &&second) { if (first.moduleId < second.moduleId) return true; else if (first.moduleId > second.moduleId) @@ -3570,7 +3565,7 @@ void ProjectStorage::synchronizePropertyDeclarations( { NanotraceHR::Tracer tracer{"synchronize property declaration"_t, projectStorageCategory()}; - std::sort(propertyDeclarations.begin(), propertyDeclarations.end(), [](auto &&first, auto &&second) { + std::ranges::sort(propertyDeclarations, [](auto &&first, auto &&second) { return Sqlite::compare(first.name, second.name) < 0; }); @@ -3643,9 +3638,7 @@ void ProjectStorage::resetRemovedAliasPropertyDeclarationsToNull( Storage::Synchronization::PropertyDeclarations &aliasDeclarations = type.propertyDeclarations; - std::sort(aliasDeclarations.begin(), aliasDeclarations.end(), [](auto &&first, auto &&second) { - return Sqlite::compare(first.name, second.name) < 0; - }); + std::ranges::sort(aliasDeclarations, {}, &Storage::Synchronization::PropertyDeclaration::name); auto range = s->selectPropertyDeclarationsWithAliasForTypeIdStatement .range(type.typeId); @@ -3807,7 +3800,7 @@ void ProjectStorage::synchronizeDocumentImports(Storage::Imports &imports, Prototypes &relinkablePrototypes, Prototypes &relinkableExtensions) { - std::sort(imports.begin(), imports.end(), [](auto &&first, auto &&second) { + std::ranges::sort(imports, [](auto &&first, auto &&second) { return std::tie(first.sourceId, first.moduleId, first.version) < std::tie(second.sourceId, second.moduleId, second.version); }); @@ -3965,9 +3958,7 @@ void ProjectStorage::synchronizePropertyEditorPaths(Storage::Synchronization::Pr SourceIds updatedPropertyEditorQmlPathsSourceIds) { using Storage::Synchronization::PropertyEditorQmlPath; - std::sort(paths.begin(), paths.end(), [](auto &&first, auto &&second) { - return first.typeId < second.typeId; - }); + std::ranges::sort(paths, std::ranges::less{}, &PropertyEditorQmlPath::typeId); auto range = s->selectPropertyEditorPathsForForSourceIdsStatement.range( toIntegers(updatedPropertyEditorQmlPathsSourceIds)); @@ -4031,20 +4022,18 @@ void ProjectStorage::synchronizeFunctionDeclarations( { NanotraceHR::Tracer tracer{"synchronize function declaration"_t, projectStorageCategory()}; - std::sort(functionsDeclarations.begin(), - functionsDeclarations.end(), - [](auto &&first, auto &&second) { - auto compare = Sqlite::compare(first.name, second.name); + std::ranges::sort(functionsDeclarations, [](auto &&first, auto &&second) { + auto compare = Sqlite::compare(first.name, second.name); - if (compare == 0) { - Utils::PathString firstSignature{createJson(first.parameters)}; - Utils::PathString secondSignature{createJson(second.parameters)}; + if (compare == 0) { + Utils::PathString firstSignature{createJson(first.parameters)}; + Utils::PathString secondSignature{createJson(second.parameters)}; - return Sqlite::compare(firstSignature, secondSignature) < 0; - } + return Sqlite::compare(firstSignature, secondSignature) < 0; + } - return compare < 0; - }); + return compare < 0; + }); auto range = s->selectFunctionDeclarationsForTypeIdStatement .range(typeId); @@ -4108,7 +4097,7 @@ void ProjectStorage::synchronizeSignalDeclarations( { NanotraceHR::Tracer tracer{"synchronize signal declaration"_t, projectStorageCategory()}; - std::sort(signalDeclarations.begin(), signalDeclarations.end(), [](auto &&first, auto &&second) { + std::ranges::sort(signalDeclarations, [](auto &&first, auto &&second) { auto compare = Sqlite::compare(first.name, second.name); if (compare == 0) { @@ -4197,11 +4186,7 @@ void ProjectStorage::synchronizeEnumerationDeclarations( { NanotraceHR::Tracer tracer{"synchronize enumeration declaration"_t, projectStorageCategory()}; - std::sort(enumerationDeclarations.begin(), - enumerationDeclarations.end(), - [](auto &&first, auto &&second) { - return Sqlite::compare(first.name, second.name) < 0; - }); + std::ranges::sort(enumerationDeclarations, {}, &EnumerationDeclaration::name); auto range = s->selectEnumerationDeclarationsForTypeIdStatement .range(typeId); diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h index f5697192c78..4bc422fd772 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h @@ -359,11 +359,11 @@ private: , sourceId{sourceId} {} - friend bool operator<(const AliasPropertyDeclaration &first, - const AliasPropertyDeclaration &second) + friend auto operator<=>(const AliasPropertyDeclaration &first, + const AliasPropertyDeclaration &second) { return std::tie(first.typeId, first.propertyDeclarationId) - < std::tie(second.typeId, second.propertyDeclarationId); + <=> std::tie(second.typeId, second.propertyDeclarationId); } friend bool operator==(const AliasPropertyDeclaration &first, @@ -429,10 +429,10 @@ private: == std::tie(second.typeId, second.propertyDeclarationId); } - friend bool operator<(const PropertyDeclaration &first, const PropertyDeclaration &second) + friend auto operator<=>(const PropertyDeclaration &first, const PropertyDeclaration &second) { return std::tie(first.typeId, first.propertyDeclarationId) - < std::tie(second.typeId, second.propertyDeclarationId); + <=> std::tie(second.typeId, second.propertyDeclarationId); } template @@ -465,9 +465,9 @@ private: , prototypeNameId{std::move(prototypeNameId)} {} - friend bool operator<(Prototype first, Prototype second) + friend auto operator<=>(Prototype first, Prototype second) { - return first.typeId < second.typeId; + return first.typeId <=> second.typeId; } friend bool operator==(Prototype first, Prototype second) From e48a57b082def4a8b3e72c8c79e6594153fd53ce Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 19 Aug 2024 12:37:22 +0200 Subject: [PATCH 057/193] QmlDesigner: Detach disabled views optionally Because there are too many depdendecies between the views we need more time to fix it. Change-Id: I2d61e1923f700b33de3484ec71eb2e1309c3dac6 Reviewed-by: Mahmoud Badri Reviewed-by: Miikka Heikkinen --- src/plugins/qmldesigner/CMakeLists.txt | 7 ++++--- .../qmldesigner/components/componentcore/viewmanager.cpp | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 9542a9a7a9b..813352c227d 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -13,7 +13,7 @@ option(QTC_USE_QML_DESIGNER_LITE "Use Qml Designer Lite" ${BUILD_NOT_DESIGNSTUDI add_feature_info("Qml Designer Lite" ${QTC_USE_QML_DESIGNER_LITE} "") option(USE_PROJECTSTORAGE "Use ProjectStorage" ${QTC_USE_QML_DESIGNER_LITE}) - +option(DETACH_DISABLED_VIEWS "Detach disabled views" OFF) env_with_default("QTC_ENABLE_PROJECT_STORAGE_TRACING" ENV_QTC_ENABLE_PROJECT_STORAGE_TRACING OFF) option(ENABLE_PROJECT_STORAGE_TRACING "Enable project storage tracing" ${ENV_QTC_ENABLE_PROJECT_STORAGE_TRACING}) @@ -118,8 +118,8 @@ extend_qtc_library(QmlDesignerCore PUBLIC_DEFINES ENABLE_QMLDESIGNER_TRACING DEFINES - $<$:ENABLE_PROJECT_STORAGE_TRACING> - $<$:ENABLE_SOURCE_PATH_STORAGE_TRACING> + $<$:ENABLE_PROJECT_STORAGE_TRACING> + $<$:ENABLE_SOURCE_PATH_STORAGE_TRACING> $<$:ENABLE_IMAGE_CACHE_TRACING> $<$:ENABLE_MODEL_TRACING> $<$:ENABLE_METAINFO_TRACING> @@ -532,6 +532,7 @@ add_qtc_plugin(QmlDesigner SHARE_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../../../share/qtcreator/qmldesigner" $<$:QDS_USE_PROJECTSTORAGE> $<$:QTC_USE_QML_DESIGNER_LITE> + $<$:DETACH_DISABLED_VIEWS> INCLUDES ${CMAKE_CURRENT_LIST_DIR}/components ${CMAKE_CURRENT_LIST_DIR}/components/import3d diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp index 77a82be6892..293e3838189 100644 --- a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp @@ -307,6 +307,7 @@ void ViewManager::registerViewAction(AbstractView &view) { auto viewAction = view.action(); viewAction->setCheckable(true); +#ifdef DETACH_DISABLED_VIEWS QObject::connect(view.action(), &AbstractViewAction::viewCheckedChanged, [&](bool checked, AbstractView &view) { @@ -315,6 +316,7 @@ void ViewManager::registerViewAction(AbstractView &view) else disableView(view); }); +#endif } void ViewManager::enableView(AbstractView &view) From 478e3166d5e4565475b0184e345cbc9f4e0cf352 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Tue, 20 Aug 2024 11:34:17 +0300 Subject: [PATCH 058/193] QmlDesigner: Dont open content lib when DETACH_DISABLED_VIEWS is false Don't open content lib for actions that doesn't change it, such as import/export to project. Fixes: QDS-13392 Change-Id: Ib55bbf4a85ee85d31f20c3e29eb00abbba6f69b6 Reviewed-by: Miikka Heikkinen --- .../components/componentcore/modelnodeoperations.cpp | 8 ++++++-- .../qmldesigner/components/edit3d/edit3dwidget.cpp | 4 ++++ .../materialbrowser/materialbrowserwidget.cpp | 10 +++++++--- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index eb6c98ec3bc..a914db9c9a6 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -800,21 +800,25 @@ void moveToComponent(const SelectionContext &selectionContext) void add3DAssetToContentLibrary(const SelectionContext &selectionContext) { - ModelNode node = selectionContext.currentSingleSelectedNode(); QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); + ModelNode node = selectionContext.currentSingleSelectedNode(); selectionContext.view()->emitCustomNotification("add_3d_to_content_lib", {node}); } void importComponent(const SelectionContext &selectionContext) { +#ifdef DETACH_DISABLED_VIEWS QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); +#endif selectionContext.view()->emitCustomNotification("import_bundle_to_project"); } void exportComponent(const SelectionContext &selectionContext) { - ModelNode node = selectionContext.currentSingleSelectedNode(); +#ifdef DETACH_DISABLED_VIEWS QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); +#endif + ModelNode node = selectionContext.currentSingleSelectedNode(); selectionContext.view()->emitCustomNotification("export_item_as_bundle", {node}); } diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index c4a8de2a962..9c716781ac1 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -371,14 +371,18 @@ void Edit3DWidget::createContextMenu() m_importBundleAction = m_contextMenu->addAction( contextIcon(DesignerIcons::CreateIcon), // TODO: placeholder icon tr("Import Component"), [&] { +#ifdef DETACH_DISABLED_VIEWS QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); +#endif view()->emitCustomNotification("import_bundle_to_project"); // To ContentLibrary }); m_exportBundleAction = m_contextMenu->addAction( contextIcon(DesignerIcons::CreateIcon), // TODO: placeholder icon tr("Export Component"), [&] { +#ifdef DETACH_DISABLED_VIEWS QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); +#endif view()->emitCustomNotification("export_item_as_bundle", {m_contextMenuTarget}); // To ContentLibrary }); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp index f9f5636a295..d463f9f02c2 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp @@ -371,22 +371,26 @@ void MaterialBrowserWidget::focusMaterialSection(bool focusMatSec) void MaterialBrowserWidget::addMaterialToContentLibrary() { - ModelNode mat = m_materialBrowserModel->selectedMaterial(); QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); + ModelNode mat = m_materialBrowserModel->selectedMaterial(); m_materialBrowserView->emitCustomNotification("add_material_to_content_lib", {mat}, {m_previewImageProvider->getPixmap(mat)}); // to ContentLibrary } void MaterialBrowserWidget::importMaterial() { - ModelNode mat = m_materialBrowserModel->selectedMaterial(); +#ifdef DETACH_DISABLED_VIEWS QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); +#endif + ModelNode mat = m_materialBrowserModel->selectedMaterial(); m_materialBrowserView->emitCustomNotification("import_bundle_to_project"); // to ContentLibrary } void MaterialBrowserWidget::exportMaterial() { - ModelNode mat = m_materialBrowserModel->selectedMaterial(); +#ifdef DETACH_DISABLED_VIEWS QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); +#endif + ModelNode mat = m_materialBrowserModel->selectedMaterial(); m_materialBrowserView->emitCustomNotification("export_material_as_bundle", {mat}, {m_previewImageProvider->getPixmap(mat)}); // to ContentLibrary } From 94b9bb204a9a12976a8779a8578757ddd2d3e047 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Sun, 18 Aug 2024 15:24:20 +0200 Subject: [PATCH 059/193] QmlDesigner: Add more range algorithm Using projection and ranges improves readability. Change-Id: I4c6b28d2df5310bcabbd7dd80488365a7e509424 Reviewed-by: Thomas Hartmann --- src/libs/utils/set_algorithm.h | 130 +++++++++--------- .../model/modelresourcemanagement.cpp | 30 ++-- .../projectstorage/projectstorage.cpp | 77 +++++------ .../projectstorage/projectstorage.h | 49 ++----- 4 files changed, 125 insertions(+), 161 deletions(-) diff --git a/src/libs/utils/set_algorithm.h b/src/libs/utils/set_algorithm.h index 5c6f8d675eb..d66a9cae61d 100644 --- a/src/libs/utils/set_algorithm.h +++ b/src/libs/utils/set_algorithm.h @@ -54,52 +54,6 @@ function_output_iterator make_iterator(const Callable &callable) return function_output_iterator(callable); } -template -bool set_intersection_compare( - InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable call, Compare comp) -{ - while (first1 != last1 && first2 != last2) { - if (comp(*first1, *first2)) { - ++first1; - } else { - if (!comp(*first2, *first1)) { - if constexpr (std::is_void_v>) { - call(*first1, *first2); - ++first1; - } else { - auto success = call(*first1, *first2); - ++first1; - if (success) - return true; - } - } - ++first2; - } - } - - return false; -} - -template -void set_greedy_difference( - InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, Callable call, Compare comp) -{ - while (first1 != last1 && first2 != last2) { - if (comp(*first1, *first2)) { - call(*first1++); - } else if (comp(*first2, *first1)) { - ++first2; - } else { - ++first1; - } - } - - while (first1 != last1) - call(*first1++); -} - template(callable), std::move(comp), std::move(proj1), std::move(proj2)); @@ -181,7 +135,7 @@ struct set_greedy_intersection_functor Sentinel1 last1, Iterator2 first2, Sentinel2 last2, - Callable callable, + Callable &&callable, Comp comp = {}, Projection1 proj1 = {}, Projection2 proj2 = {}) const @@ -206,7 +160,7 @@ struct set_greedy_intersection_functor requires callmergeable, std::ranges::iterator_t, Comp, Projection1, Projection2> constexpr void operator()(Range1 &&range1, Range2 &&range2, - Callable callable, + Callable &&callable, Comp comp = {}, Projection1 proj1 = {}, Projection2 proj2 = {}) const @@ -215,7 +169,7 @@ struct set_greedy_intersection_functor std::ranges::end(range1), std::ranges::begin(range2), std::ranges::end(range2), - std::move(callable), + std::forward(callable), std::move(comp), std::move(proj1), std::move(proj2)); @@ -224,22 +178,68 @@ struct set_greedy_intersection_functor inline constexpr set_greedy_intersection_functor set_greedy_intersection{}; -template -Value mismatch_collect(InputIt1 first1, - InputIt1 last1, - InputIt2 first2, - InputIt2 last2, - Value value, - BinaryPredicate predicate, - Callable callable) +struct set_greedy_difference_functor { - while (first1 != last1 && first2 != last2) { - if (predicate(*first1, *first2)) - value = callable(*first1, *first2, value); - ++first1, ++first2; + template Sentinel1, + std::input_iterator Iterator2, + std::sentinel_for Sentinel2, + std::invocable &> Callable, + typename Comp = std::ranges::less, + typename Projection1 = std::identity, + typename Projection2 = std::identity> + requires callmergeable + constexpr void operator()(Iterator1 first1, + Sentinel1 last1, + Iterator2 first2, + Sentinel2 last2, + Callable &&callable, + Comp comp = {}, + Projection1 proj1 = {}, + Projection2 proj2 = {}) const + { + while (first1 != last1 && first2 != last2) { + if (std::invoke(comp, std::invoke(proj1, *first1), std::invoke(proj2, *first2))) { + std::invoke(callable, *first1); + ++first1; + } else if (std::invoke(comp, std::invoke(proj2, *first2), std::invoke(proj1, *first1))) { + ++first2; + } else { + ++first1; + } + } + + while (first1 != last1) { + std::invoke(callable, *first1); + ++first1; + } } - return value; -} + template &> Callable, + typename Comp = std::ranges::less, + typename Projection1 = std::identity, + typename Projection2 = std::identity> + requires callmergeable, std::ranges::iterator_t, Comp, Projection1, Projection2> + constexpr void operator()(Range1 &&range1, + Range2 &&range2, + Callable &&callable, + Comp comp = {}, + Projection1 proj1 = {}, + Projection2 proj2 = {}) const + { + (*this)(std::ranges::begin(range1), + std::ranges::end(range1), + std::ranges::begin(range2), + std::ranges::end(range2), + std::forward(callable), + std::move(comp), + std::move(proj1), + std::move(proj2)); + } +}; + +inline constexpr set_greedy_difference_functor set_greedy_difference{}; } // namespace Utils diff --git a/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp b/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp index 550d5a2626c..b2d9efd9d89 100644 --- a/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp @@ -19,6 +19,7 @@ #include QT_WARNING_DISABLE_GCC("-Wmissing-field-initializers") +QT_WARNING_DISABLE_CLANG("-Wunneeded-internal-declaration") // can be removed with newer clang versions namespace QmlDesigner { @@ -255,10 +256,7 @@ struct NodeDependency ModelNode target; ModelNode source; - friend bool operator<(const NodeDependency &first, const NodeDependency &second) - { - return std::tie(first.target, first.source) < std::tie(second.target, second.source); - } + friend std::weak_ordering operator<=>(const NodeDependency &first, const NodeDependency &second) = default; }; using NodeDependencies = std::vector; @@ -296,9 +294,11 @@ struct NodesProperty ModelNodes targets; bool isChanged = false; - friend bool operator<(const NodesProperty &first, const NodesProperty &second) + friend bool operator==(const NodesProperty &first, const NodesProperty &second) = default; + + friend std::weak_ordering operator<=>(const NodesProperty &first, const NodesProperty &second) { - return first.source < second.source; + return first.source <=> second.source; } }; @@ -380,7 +380,7 @@ struct RemoveTargetsSources : public Base {}, &NodeDependency::target); - std::sort(removedTargetNodesInProperties.begin(), removedTargetNodesInProperties.end()); + std::ranges::sort(removedTargetNodesInProperties); return removedTargetNodesInProperties; } @@ -408,12 +408,12 @@ struct RemoveTargetsSources : public Base }; NodesProperties removedTargetNodesInProperties = collectRemovedDependencies(nodes); - ::Utils::set_intersection_compare(nodesProperties.begin(), - nodesProperties.end(), - removedTargetNodesInProperties.begin(), - removedTargetNodesInProperties.end(), - removeTargets, - std::less{}); + Utils::set_greedy_intersection(nodesProperties, + removedTargetNodesInProperties, + removeTargets, + {}, + &NodesProperty::source, + &NodesProperty::source); return nodesToBeRemoved; } @@ -570,8 +570,8 @@ struct TargetsFilter void finally() { - std::sort(dependencies.begin(), dependencies.end()); - std::sort(targetsNodesProperties.begin(), targetsNodesProperties.end()); + std::ranges::sort(dependencies); + std::ranges::sort(targetsNodesProperties); } Predicate predicate; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp index 8e76356c6d8..752d3c0db89 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp @@ -2959,36 +2959,35 @@ void ProjectStorage::relinkAliasPropertyDeclarations(AliasPropertyDeclarations & std::ranges::sort(aliasPropertyDeclarations); // todo remove duplicates - Utils::set_greedy_difference( - aliasPropertyDeclarations.cbegin(), - aliasPropertyDeclarations.cend(), - deletedTypeIds.begin(), - deletedTypeIds.end(), - [&](const AliasPropertyDeclaration &alias) { - auto typeId = fetchTypeId(alias.aliasImportedTypeNameId); + auto relink = [&](const AliasPropertyDeclaration &alias) { + auto typeId = fetchTypeId(alias.aliasImportedTypeNameId); - if (typeId) { - auto propertyDeclaration = fetchPropertyDeclarationByTypeIdAndNameUngarded( - typeId, alias.aliasPropertyName); - if (propertyDeclaration) { - auto [propertyImportedTypeNameId, propertyTypeId, aliasId, propertyTraits] = *propertyDeclaration; + if (typeId) { + auto propertyDeclaration = fetchPropertyDeclarationByTypeIdAndNameUngarded( + typeId, alias.aliasPropertyName); + if (propertyDeclaration) { + auto [propertyImportedTypeNameId, propertyTypeId, aliasId, propertyTraits] = *propertyDeclaration; - s->updatePropertyDeclarationWithAliasAndTypeStatement - .write(alias.propertyDeclarationId, - propertyTypeId, - propertyTraits, - propertyImportedTypeNameId, - aliasId); - return; - } + s->updatePropertyDeclarationWithAliasAndTypeStatement.write(alias.propertyDeclarationId, + propertyTypeId, + propertyTraits, + propertyImportedTypeNameId, + aliasId); + return; } + } - errorNotifier->typeNameCannotBeResolved(fetchImportedTypeName(alias.aliasImportedTypeNameId), - fetchTypeSourceId(alias.typeId)); - s->resetAliasPropertyDeclarationStatement.write(alias.propertyDeclarationId, - Storage::PropertyDeclarationTraits{}); - }, - TypeCompare{}); + errorNotifier->typeNameCannotBeResolved(fetchImportedTypeName(alias.aliasImportedTypeNameId), + fetchTypeSourceId(alias.typeId)); + s->resetAliasPropertyDeclarationStatement.write(alias.propertyDeclarationId, + Storage::PropertyDeclarationTraits{}); + }; + + Utils::set_greedy_difference(aliasPropertyDeclarations, + deletedTypeIds, + relink, + {}, + &AliasPropertyDeclaration::typeId); } void ProjectStorage::relinkPropertyDeclarations(PropertyDeclarations &relinkablePropertyDeclaration, @@ -3007,10 +3006,8 @@ void ProjectStorage::relinkPropertyDeclarations(PropertyDeclarations &relinkable relinkablePropertyDeclaration.end()); Utils::set_greedy_difference( - relinkablePropertyDeclaration.cbegin(), - relinkablePropertyDeclaration.cend(), - deletedTypeIds.begin(), - deletedTypeIds.end(), + relinkablePropertyDeclaration, + deletedTypeIds, [&](const PropertyDeclaration &property) { TypeId propertyTypeId = fetchTypeId(property.importedTypeNameId); @@ -3024,7 +3021,8 @@ void ProjectStorage::relinkPropertyDeclarations(PropertyDeclarations &relinkable s->updatePropertyDeclarationTypeStatement.write(property.propertyDeclarationId, propertyTypeId); }, - TypeCompare{}); + {}, + &PropertyDeclaration::typeId); } template @@ -3043,10 +3041,8 @@ void ProjectStorage::relinkPrototypes(Prototypes &relinkablePrototypes, relinkablePrototypes.erase(begin, end); Utils::set_greedy_difference( - relinkablePrototypes.cbegin(), - relinkablePrototypes.cend(), - deletedTypeIds.begin(), - deletedTypeIds.end(), + relinkablePrototypes, + deletedTypeIds, [&](const Prototype &prototype) { TypeId prototypeId = fetchTypeId(prototype.prototypeNameId); @@ -3057,7 +3053,8 @@ void ProjectStorage::relinkPrototypes(Prototypes &relinkablePrototypes, updateStatement(prototype.typeId, prototypeId); checkForPrototypeChainCycle(prototype.typeId); }, - TypeCompare{}); + {}, + &Prototype::typeId); } void ProjectStorage::deleteNotUpdatedTypes(const TypeIds &updatedTypeIds, @@ -3682,7 +3679,7 @@ void ProjectStorage::resetRemovedAliasPropertyDeclarationsToNull( removeRelinkableEntries(relinkableAliasPropertyDeclarations, propertyDeclarationIds, - PropertyCompare{}); + &AliasPropertyDeclaration::propertyDeclarationId); } void ProjectStorage::handlePrototypesWithSourceIdAndPrototypeId(SourceId sourceId, @@ -4307,7 +4304,7 @@ void ProjectStorage::syncDeclarations(Storage::Synchronization::Types &types, removeRelinkableEntries(relinkablePropertyDeclarations, propertyDeclarationIds, - PropertyCompare{}); + &PropertyDeclaration::propertyDeclarationId); } void ProjectStorage::syncDefaultProperties(Storage::Synchronization::Types &types) @@ -4515,8 +4512,8 @@ void ProjectStorage::syncPrototypesAndExtensions(Storage::Synchronization::Types for (auto &type : types) syncPrototypeAndExtension(type, typeIds); - removeRelinkableEntries(relinkablePrototypes, typeIds, TypeCompare{}); - removeRelinkableEntries(relinkableExtensions, typeIds, TypeCompare{}); + removeRelinkableEntries(relinkablePrototypes, typeIds, &Prototype::typeId); + removeRelinkableEntries(relinkableExtensions, typeIds, &Prototype::typeId); } ImportId ProjectStorage::fetchImportId(SourceId sourceId, const Storage::Import &import) const diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h index 4bc422fd772..a2339599456 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h @@ -493,38 +493,6 @@ private: using Prototypes = std::vector; - template - struct TypeCompare - { - bool operator()(const Type &type, TypeId typeId) { return type.typeId < typeId; } - - bool operator()(TypeId typeId, const Type &type) { return typeId < type.typeId; } - - bool operator()(const Type &first, const Type &second) - { - return first.typeId < second.typeId; - } - }; - - template - struct PropertyCompare - { - bool operator()(const Property &property, PropertyDeclarationId id) - { - return property.propertyDeclarationId < id; - } - - bool operator()(PropertyDeclarationId id, const Property &property) - { - return id < property.propertyDeclarationId; - } - - bool operator()(const Property &first, const Property &second) - { - return first.propertyDeclarationId < second.propertyDeclarationId; - } - }; - SourceIds filterSourceIdsWithoutType(const SourceIds &updatedSourceIds, SourceIds &sourceIdsOfTypes); @@ -864,24 +832,23 @@ private: AliasPropertyDeclarations &aliasPropertyDeclarationsToLink, PropertyDeclarationIds &propertyDeclarationIds); - template - void removeRelinkableEntries(std::vector &relinkables, Ids &ids, Compare compare) + template + void removeRelinkableEntries(std::vector &relinkables, auto &ids, auto projection) { NanotraceHR::Tracer tracer{"remove relinkable entries"_t, projectStorageCategory()}; std::vector newRelinkables; newRelinkables.reserve(relinkables.size()); - std::sort(ids.begin(), ids.end()); - std::sort(relinkables.begin(), relinkables.end(), compare); + std::ranges::sort(ids); + std::ranges::sort(relinkables, {}, projection); Utils::set_greedy_difference( - relinkables.begin(), - relinkables.end(), - ids.cbegin(), - ids.cend(), + relinkables, + ids, [&](Relinkable &entry) { newRelinkables.push_back(std::move(entry)); }, - compare); + {}, + projection); relinkables = std::move(newRelinkables); } From 79e54668886cea5094af1ede314d618c129f9578 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Tue, 20 Aug 2024 15:31:09 +0300 Subject: [PATCH 060/193] QmlDesigner: Add another 3D Editor pan shortcut (Shift + LMB) To help on devices that don't have a middle mouse button. Fixes: QDS-2047 Change-Id: I85e0e25ea8a5c325d493c85cafb0ba33f389ecce Reviewed-by: Miikka Heikkinen --- .../qml2puppet/mockfiles/qt6/EditCameraController.qml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml b/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml index 36d67c534d1..27f1f717034 100644 --- a/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml +++ b/src/tools/qml2puppet/mockfiles/qt6/EditCameraController.qml @@ -282,18 +282,19 @@ Item { hoverEnabled: false anchors.fill: parent onPositionChanged: (mouse) => { - if (cameraCtrl.camera && mouse.modifiers === Qt.AltModifier && cameraCtrl._dragging) { + if (cameraCtrl.camera && cameraCtrl._dragging) { var currentPoint = Qt.vector3d(mouse.x, mouse.y, 0); - if (cameraCtrl._button == Qt.LeftButton) { + if (cameraCtrl._button == Qt.LeftButton && mouse.modifiers === Qt.AltModifier) { _generalHelper.orbitCamera(cameraCtrl.camera, cameraCtrl._startRotation, cameraCtrl._lookAtPoint, cameraCtrl._pressPoint, currentPoint); - } else if (cameraCtrl._button == Qt.MiddleButton) { + } else if ((cameraCtrl._button == Qt.MiddleButton && mouse.modifiers === Qt.AltModifier) + || (cameraCtrl._button == Qt.LeftButton && mouse.modifiers === Qt.ShiftModifier)) { cameraCtrl._lookAtPoint = _generalHelper.panCamera( cameraCtrl.camera, cameraCtrl._startTransform, cameraCtrl._startPosition, cameraCtrl._startLookAtPoint, cameraCtrl._pressPoint, currentPoint, _zoomFactor); - } else if (cameraCtrl._button == Qt.RightButton) { + } else if (cameraCtrl._button == Qt.RightButton && mouse.modifiers === Qt.AltModifier) { cameraCtrl.zoomRelative(currentPoint.y - cameraCtrl._prevPoint.y) cameraCtrl._prevPoint = currentPoint; } @@ -303,7 +304,7 @@ Item { if (cameraCtrl.flyMode) return; viewRoot.activeSplit = cameraCtrl.splitId - if (cameraCtrl.camera && mouse.modifiers === Qt.AltModifier) { + if (cameraCtrl.camera && (mouse.modifiers & (Qt.AltModifier | Qt.ShiftModifier))) { cameraCtrl._dragging = true; cameraCtrl._startRotation = cameraCtrl.camera.eulerRotation; cameraCtrl._startPosition = cameraCtrl.camera.position; From 2156db3dbd8e30a66412760544f13a6c60e9efd8 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 20 Aug 2024 13:25:27 +0300 Subject: [PATCH 061/193] QmlDesigner: Refactor selected material and texture handling Selected material and texture are now stored in auxiliary properties instead of syncing the selection between various views using custom notifications. This makes the selection independent of any view's attach state. Fixes: QDS-13373 Change-Id: Ibcf1b4ee995a4a2bc7479afc2348a7d1a3e9b7de Reviewed-by: Marco Bubke --- .../componentcore/createtexture.cpp | 4 +- .../componentcore/modelnodeoperations.cpp | 5 +- .../components/componentcore/utils3d.cpp | 62 +++++++++ .../components/componentcore/utils3d.h | 13 ++ .../edit3d/edit3dmaterialsaction.cpp | 5 +- .../components/integration/componentview.cpp | 30 ++++- .../materialbrowser/materialbrowsermodel.cpp | 12 +- .../materialbrowsertexturesmodel.cpp | 12 +- .../materialbrowser/materialbrowserview.cpp | 119 +++++++++++------- .../materialbrowser/materialbrowserview.h | 8 +- .../materialeditor/materialeditorview.cpp | 45 ++++--- .../propertyeditor/propertyeditorvalue.cpp | 8 +- .../textureeditor/textureeditorview.cpp | 42 ++++--- 13 files changed, 260 insertions(+), 105 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/createtexture.cpp b/src/plugins/qmldesigner/components/componentcore/createtexture.cpp index 0e0882d0a50..35bc3a0d18b 100644 --- a/src/plugins/qmldesigner/components/componentcore/createtexture.cpp +++ b/src/plugins/qmldesigner/components/componentcore/createtexture.cpp @@ -111,9 +111,9 @@ ModelNode CreateTexture::execute(const QString &filePath, AddTextureMode mode, i assignTextureAsLightProbe(texture, sceneId); QTimer::singleShot(0, m_view, [this, texture]() { - if (m_view->model()) { + if (m_view->model() && texture.isValid()) { QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); - m_view->emitCustomNotification("select_texture", {texture}, {true}); + Utils3D::selectTexture(texture); } }); diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index a914db9c9a6..4d49887b07d 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -864,11 +864,8 @@ void editMaterial(const SelectionContext &selectionContext) } if (material.isValid()) { - QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor", true); - - // to MaterialBrowser... - view->emitCustomNotification("select_material", {material}); + Utils3D::selectMaterial(material); } } diff --git a/src/plugins/qmldesigner/components/componentcore/utils3d.cpp b/src/plugins/qmldesigner/components/componentcore/utils3d.cpp index 3983dcb13ca..401925296cd 100644 --- a/src/plugins/qmldesigner/components/componentcore/utils3d.cpp +++ b/src/plugins/qmldesigner/components/componentcore/utils3d.cpp @@ -7,8 +7,11 @@ #include #include #include +#include #include +#include + namespace QmlDesigner { namespace Utils3D { @@ -153,5 +156,64 @@ QString activeView3dId(AbstractView *view) return {}; } +ModelNode getMaterialOfModel(const ModelNode &model, int idx) +{ + QTC_ASSERT(model.isValid(), return {}); + + QmlObjectNode qmlObjNode(model); + QString matExp = qmlObjNode.expression("materials"); + if (matExp.isEmpty()) + return {}; + + const QStringList mats = matExp.remove('[').remove(']').split(',', Qt::SkipEmptyParts); + if (mats.isEmpty()) + return {}; + + ModelNode mat = model.model()->modelNodeForId(mats.at(idx)); + + QTC_CHECK(mat); + + return mat; +} + +void selectMaterial(const ModelNode &material) +{ + if (material.metaInfo().isQtQuick3DMaterial()) { + material.model()->rootModelNode().setAuxiliaryData(Utils3D::matLibSelectedMaterialProperty, + material.id()); + } +} + +void selectTexture(const ModelNode &texture) +{ + if (texture.metaInfo().isQtQuick3DTexture()) { + texture.model()->rootModelNode().setAuxiliaryData(Utils3D::matLibSelectedTextureProperty, + texture.id()); + } +} + +ModelNode selectedMaterial(AbstractView *view) +{ + if (!view) + return {}; + + ModelNode root = view->rootModelNode(); + + if (auto selectedProperty = root.auxiliaryData(Utils3D::matLibSelectedMaterialProperty)) + return view->modelNodeForId(selectedProperty->toString()); + return {}; +} + +ModelNode selectedTexture(AbstractView *view) +{ + if (!view) + return {}; + + ModelNode root = view->rootModelNode(); + if (auto selectedProperty = root.auxiliaryData(Utils3D::matLibSelectedTextureProperty)) + return view->modelNodeForId(selectedProperty->toString()); + return {}; +} + } // namespace Utils3D } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/utils3d.h b/src/plugins/qmldesigner/components/componentcore/utils3d.h index 0e582c0fb4a..7f3dae8dafb 100644 --- a/src/plugins/qmldesigner/components/componentcore/utils3d.h +++ b/src/plugins/qmldesigner/components/componentcore/utils3d.h @@ -12,6 +12,10 @@ namespace Utils3D { inline constexpr AuxiliaryDataKeyView active3dSceneProperty{AuxiliaryDataType::Temporary, "active3dScene"}; +inline constexpr AuxiliaryDataKeyView matLibSelectedMaterialProperty{AuxiliaryDataType::Temporary, + "matLibSelMat"}; +inline constexpr AuxiliaryDataKeyView matLibSelectedTextureProperty{AuxiliaryDataType::Temporary, + "matLibSelTex"}; ModelNode active3DSceneNode(AbstractView *view); qint32 active3DSceneId(Model *model); @@ -24,5 +28,14 @@ ModelNode getTextureDefaultInstance(const QString &source, AbstractView *view); ModelNode activeView3dNode(AbstractView *view); QString activeView3dId(AbstractView *view); +ModelNode getMaterialOfModel(const ModelNode &model, int idx = 0); + +// These methods handle selection of material library items for various material library views. +// This is separate selection from the normal selection handling. +void selectMaterial(const ModelNode &material); +void selectTexture(const ModelNode &texture); +ModelNode selectedMaterial(AbstractView *view); +ModelNode selectedTexture(AbstractView *view); + } // namespace Utils3D } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dmaterialsaction.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dmaterialsaction.cpp index 143282c77f7..bc2dba44a3f 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dmaterialsaction.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dmaterialsaction.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -180,10 +181,8 @@ QAction *Edit3DMaterialsAction::createMaterialAction(const ModelNode &material, QAction *editMaterialAction = new QAction(tr("Edit"), menu); connect(editMaterialAction, &QAction::triggered, menu, [material] { - QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor", true); - if (auto materialView = material.view()) - materialView->emitCustomNotification("select_material", {material}); + Utils3D::selectMaterial(material); }); menu->addAction(editMaterialAction); diff --git a/src/plugins/qmldesigner/components/integration/componentview.cpp b/src/plugins/qmldesigner/components/integration/componentview.cpp index 09dff0c5c20..e52aea5bc11 100644 --- a/src/plugins/qmldesigner/components/integration/componentview.cpp +++ b/src/plugins/qmldesigner/components/integration/componentview.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -220,9 +221,36 @@ void ComponentView::nodeReparented(const ModelNode &node, const NodeAbstractProp updateDescription(node); } -void ComponentView::nodeIdChanged(const ModelNode& node, const QString& /*newId*/, const QString& /*oldId*/) +void ComponentView::nodeIdChanged(const ModelNode& node, const QString& newId, const QString& oldId) { updateDescription(node); + + if (oldId.isEmpty()) + return; + + // Material/texture id handling is done here as ComponentView is guaranteed to always be + // attached, unlike the views actually related to material/texture handling. + auto metaInfo = node.metaInfo(); + auto rootNode = rootModelNode(); + auto model = AbstractView::model(); + + if (metaInfo == model->qtQuick3DMaterialMetaInfo()) { + if (auto property = rootNode.auxiliaryData(Utils3D::matLibSelectedMaterialProperty)) { + if (oldId == property->toString()) { + QTimer::singleShot(0, this, [rootNode, newId]() { + rootNode.setAuxiliaryData(Utils3D::matLibSelectedMaterialProperty, newId); + }); + } + } + } else if (metaInfo == model->qtQuick3DTextureMetaInfo()) { + if (auto property = rootNode.auxiliaryData(Utils3D::matLibSelectedTextureProperty)) { + if (oldId == property->toString()) { + QTimer::singleShot(0, this, [rootNode, newId]() { + rootNode.setAuxiliaryData(Utils3D::matLibSelectedTextureProperty, newId); + }); + } + } + } } void ComponentView::nodeSourceChanged(const ModelNode &node, const QString &/*newNodeSource*/) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp index f01424e96e8..c34ba7167a8 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp @@ -10,6 +10,8 @@ #include "variantproperty.h" #include "qmltimelinekeyframegroup.h" +#include + #include namespace QmlDesigner { @@ -314,6 +316,11 @@ void MaterialBrowserModel::deleteSelectedMaterial() void MaterialBrowserModel::updateSelectedMaterial() { + if (!m_materialList.isEmpty() && m_selectedIndex < 0) { + ModelNode mat = Utils3D::selectedMaterial(m_view); + m_selectedIndex = materialIndex(mat); + } + selectMaterial(m_selectedIndex, true); } @@ -326,10 +333,7 @@ void MaterialBrowserModel::updateMaterialName(const ModelNode &material) int MaterialBrowserModel::materialIndex(const ModelNode &material) const { - if (m_materialIndexHash.contains(material.internalId())) - return m_materialIndexHash.value(material.internalId()); - - return -1; + return m_materialIndexHash.value(material.internalId(), -1); } ModelNode MaterialBrowserModel::materialAt(int idx) const diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.cpp index e34cc9825e3..ea898446420 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsertexturesmodel.cpp @@ -10,6 +10,8 @@ #include "qmlobjectnode.h" #include "variantproperty.h" +#include + #include namespace QmlDesigner { @@ -238,15 +240,17 @@ void MaterialBrowserTexturesModel::updateAllTexturesSources() void MaterialBrowserTexturesModel::updateSelectedTexture() { + if (!m_textureList.isEmpty() && m_selectedIndex < 0) { + ModelNode tex = Utils3D::selectedTexture(m_view); + m_selectedIndex = textureIndex(tex); + } + selectTexture(m_selectedIndex, true); } int MaterialBrowserTexturesModel::textureIndex(const ModelNode &texture) const { - if (m_textureIndexHash.contains(texture.internalId())) - return m_textureIndexHash.value(texture.internalId()); - - return -1; + return m_textureIndexHash.value(texture.internalId(), -1); } ModelNode MaterialBrowserTexturesModel::textureAt(int idx) const diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 4f62a2c8026..9cd19daa32b 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -50,6 +50,9 @@ MaterialBrowserView::MaterialBrowserView(AsynchronousImageCache &imageCache, { m_previewTimer.setSingleShot(true); connect(&m_previewTimer, &QTimer::timeout, this, &MaterialBrowserView::requestPreviews); + + m_selectionTimer.setSingleShot(true); + connect(&m_selectionTimer, &QTimer::timeout, this, &MaterialBrowserView::handleModelSelectionChange); } MaterialBrowserView::~MaterialBrowserView() @@ -72,8 +75,10 @@ WidgetInfo MaterialBrowserView::widgetInfo() MaterialBrowserModel *matBrowserModel = m_widget->materialBrowserModel().data(); connect(matBrowserModel, &MaterialBrowserModel::selectedIndexChanged, this, [&] (int idx) { - ModelNode matNode = m_widget->materialBrowserModel()->materialAt(idx); - emitCustomNotification("selected_material_changed", {matNode}, {}); + if (!model()) + return; + m_pendingMaterialIndex = idx; + m_selectionTimer.start(0); }); connect(matBrowserModel, &MaterialBrowserModel::applyToSelectedTriggered, this, @@ -172,8 +177,10 @@ WidgetInfo MaterialBrowserView::widgetInfo() // custom notifications below are sent to the TextureEditor MaterialBrowserTexturesModel *texturesModel = m_widget->materialBrowserTexturesModel().data(); connect(texturesModel, &MaterialBrowserTexturesModel::selectedIndexChanged, this, [&] (int idx) { - ModelNode texNode = m_widget->materialBrowserTexturesModel()->textureAt(idx); - emitCustomNotification("selected_texture_changed", {texNode}); + if (!model()) + return; + m_pendingTextureIndex = idx; + m_selectionTimer.start(0); }); connect(texturesModel, &MaterialBrowserTexturesModel::duplicateTextureTriggered, this, [&] (const ModelNode &texture) { @@ -210,7 +217,7 @@ WidgetInfo MaterialBrowserView::widgetInfo() connect(texturesModel, &MaterialBrowserTexturesModel::updateModelSelectionStateRequested, this, [&]() { bool hasModel = false; if (m_selectedModels.size() == 1) - hasModel = getMaterialOfModel(m_selectedModels.at(0)).isValid(); + hasModel = Utils3D::getMaterialOfModel(m_selectedModels.at(0)).isValid(); m_widget->materialBrowserTexturesModel()->setHasSingleModelSelection(hasModel); }); @@ -244,7 +251,6 @@ void MaterialBrowserView::modelAttached(Model *model) { AbstractView::modelAttached(model); - m_pendingTextureSelection = {}; m_widget->clearSearchFilter(); m_widget->materialBrowserModel()->setHasMaterialLibrary(false); m_hasQuick3DImport = model->hasImport("QtQuick3D"); @@ -255,10 +261,6 @@ void MaterialBrowserView::modelAttached(Model *model) QTimer::singleShot(1000, model, [this] { refreshModel(true); loadPropertyGroups(); // Needs the delay because it uses metaInfo - - if (m_pendingTextureSelection.isValid()) - emitCustomNotification("select_texture", {m_pendingTextureSelection}, {true}); - m_pendingTextureSelection = {}; }); m_sceneId = Utils3D::active3DSceneId(model); @@ -289,6 +291,9 @@ void MaterialBrowserView::refreshModel(bool updateImages) if (updateImages) updateMaterialsPreview(); + + updateMaterialSelection(); + updateTextureSelection(); } void MaterialBrowserView::updateMaterialsPreview() @@ -345,6 +350,8 @@ void MaterialBrowserView::modelAboutToBeDetached(Model *model) m_widget->materialBrowserModel()->setMaterials({}, m_hasQuick3DImport); m_widget->materialBrowserModel()->setHasMaterialLibrary(false); m_widget->clearPreviewCache(); + m_pendingMaterialIndex = -1; + m_pendingTextureIndex = -1; if (m_propertyGroupsLoaded) { m_propertyGroupsLoaded = false; @@ -370,7 +377,7 @@ void MaterialBrowserView::selectedNodesChanged(const QList &selectedN if (selectedNodeList.size() > 1 || m_selectedModels.isEmpty()) return; - ModelNode mat = getMaterialOfModel(m_selectedModels.at(0)); + ModelNode mat = Utils3D::getMaterialOfModel(m_selectedModels.at(0)); if (!mat.isValid()) return; @@ -511,21 +518,57 @@ void MaterialBrowserView::requestPreviews() m_previewRequests.clear(); } -ModelNode MaterialBrowserView::getMaterialOfModel(const ModelNode &model, int idx) +void MaterialBrowserView::updateMaterialSelection() { - QmlObjectNode qmlObjNode(model); - QString matExp = qmlObjNode.expression("materials"); - if (matExp.isEmpty()) - return {}; + QTC_ASSERT(model(), return); - const QStringList mats = matExp.remove('[').remove(']').split(',', Qt::SkipEmptyParts); - if (mats.isEmpty()) - return {}; + ModelNode node = Utils3D::selectedMaterial(this); + int idx = m_widget->materialBrowserModel()->materialIndex(node); + if (idx == -1 && !m_widget->materialBrowserModel()->isEmpty()) + idx = 0; + if (idx != -1) { + m_widget->materialBrowserModel()->selectMaterial(idx); + m_widget->focusMaterialSection(true); + } +} - ModelNode mat = modelNodeForId(mats.at(idx)); - QTC_ASSERT(mat.isValid(), return {}); +void MaterialBrowserView::updateTextureSelection() +{ + QTC_ASSERT(model(), return); - return mat; + ModelNode node = Utils3D::selectedTexture(this); + int idx = m_widget->materialBrowserTexturesModel()->textureIndex(node); + if (idx == -1 && !m_widget->materialBrowserTexturesModel()->isEmpty()) + idx = 0; + if (idx != -1) { + m_widget->materialBrowserTexturesModel()->selectTexture(idx); + m_widget->materialBrowserTexturesModel()->refreshSearch(); + m_widget->focusMaterialSection(false); + } +} + +// This method is asynchronously called in response to a selection change in the material and +// texture models to update the selection state to the main scene model. +void MaterialBrowserView::handleModelSelectionChange() +{ + if (!model()) + return; + + if (m_pendingMaterialIndex >= 0) { + ModelNode matNode = m_widget->materialBrowserModel()->materialAt(m_pendingMaterialIndex); + ModelNode current = Utils3D::selectedMaterial(this); + if (current != matNode) + Utils3D::selectMaterial(matNode); + m_pendingMaterialIndex = -1; + } + + if (m_pendingTextureIndex >= 0) { + ModelNode texNode = m_widget->materialBrowserTexturesModel()->textureAt(m_pendingTextureIndex); + ModelNode current = Utils3D::selectedTexture(this); + if (current != texNode) + Utils3D::selectTexture(texNode); + m_pendingTextureIndex = -1; + } } void MaterialBrowserView::importsChanged([[maybe_unused]] const Imports &addedImports, @@ -549,34 +592,10 @@ void MaterialBrowserView::customNotification(const AbstractView *view, const QList &nodeList, const QList &data) { - if (view == this && identifier != "select_texture") + if (view == this) return; - if (identifier == "select_material") { - ModelNode matNode; - if (!data.isEmpty() && !m_selectedModels.isEmpty()) { - ModelNode model3D = m_selectedModels.at(0); - QTC_ASSERT(model3D.isValid(), return); - matNode = getMaterialOfModel(model3D, data[0].toInt()); - } else { - matNode = nodeList.first(); - } - QTC_ASSERT(matNode.isValid(), return); - - int idx = m_widget->materialBrowserModel()->materialIndex(matNode); - if (idx != -1) - m_widget->materialBrowserModel()->selectMaterial(idx); - } else if (identifier == "select_texture") { - int idx = m_widget->materialBrowserTexturesModel()->textureIndex(nodeList.first()); - if (idx != -1) { - m_widget->materialBrowserTexturesModel()->selectTexture(idx); - m_widget->materialBrowserTexturesModel()->refreshSearch(); - if (!data.isEmpty() && data[0].toBool()) - m_widget->focusMaterialSection(false); - } else { - m_pendingTextureSelection = nodeList.first(); - } - } else if (identifier == "refresh_material_browser") { + if (identifier == "refresh_material_browser") { QTimer::singleShot(0, model(), [this] { refreshModel(true); }); @@ -643,6 +662,10 @@ void MaterialBrowserView::auxiliaryDataChanged(const ModelNode &, { if (type == Utils3D::active3dSceneProperty) active3DSceneChanged(data.toInt()); + else if (type == Utils3D::matLibSelectedMaterialProperty) + updateMaterialSelection(); + else if ( type == Utils3D::matLibSelectedTextureProperty) + updateTextureSelection(); } void MaterialBrowserView::applyTextureToModel3D(const QmlObjectNode &model3D, const ModelNode &texture) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h index a2582fe0ac7..be1092e7f3f 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h @@ -83,7 +83,9 @@ private: void loadPropertyGroups(); void requestPreviews(); ModelNode resolveSceneEnv(); - ModelNode getMaterialOfModel(const ModelNode &model, int idx = 0); + void updateMaterialSelection(); + void updateTextureSelection(); + void handleModelSelectionChange(); AsynchronousImageCache &m_imageCache; QPointer m_widget; @@ -95,13 +97,15 @@ private: bool m_propertyGroupsLoaded = false; QTimer m_previewTimer; + QTimer m_selectionTimer; // Compress selection and avoid illegal callbacks to model QSet m_previewRequests; QPointer m_chooseMatPropsView; QHash> m_textureModels; QString m_appliedTextureId; QString m_appliedTexturePath; // defers texture creation until dialog apply int m_sceneId = -1; - ModelNode m_pendingTextureSelection; + int m_pendingMaterialIndex = -1; + int m_pendingTextureIndex = -1; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index e05acb7646d..4980a20bcc4 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -72,10 +72,21 @@ MaterialEditorView::MaterialEditorView(ExternalDependenciesInterface &externalDe DesignDocument *doc = QmlDesignerPlugin::instance()->currentDesignDocument(); if (doc && !doc->inFileComponentModelActive()) Utils3D::ensureMaterialLibraryNode(this); + ModelNode matLib = Utils3D::materialLibraryNode(this); if (m_qmlBackEnd && m_qmlBackEnd->contextObject()) - m_qmlBackEnd->contextObject()->setHasMaterialLibrary( - Utils3D::materialLibraryNode(this).isValid()); + m_qmlBackEnd->contextObject()->setHasMaterialLibrary(matLib.isValid()); m_ensureMatLibTimer.stop(); + + ModelNode mat = Utils3D::selectedMaterial(this); + if (!mat.isValid()) { + const QList matLibNodes = matLib.directSubModelNodes(); + for (const ModelNode &node : matLibNodes) { + if (node.metaInfo().isQtQuick3DMaterial()) { + Utils3D::selectMaterial(node); + break; + } + } + } } }); @@ -707,6 +718,7 @@ void MaterialEditorView::modelAttached(Model *model) // Creating the material library node on model attach causes errors as long as the type // information is not complete yet, so we keep checking until type info is complete. m_ensureMatLibTimer.start(500); + m_selectedMaterial = Utils3D::selectedMaterial(this); } if (!m_setupCompleted) { @@ -819,11 +831,18 @@ void MaterialEditorView::auxiliaryDataChanged(const ModelNode &node, AuxiliaryDataKeyView key, const QVariant &) { + if (!noValidSelection() && node.isSelected()) + m_qmlBackEnd->setValueforAuxiliaryProperties(m_selectedMaterial, key); - if (noValidSelection() || !node.isSelected()) - return; - - m_qmlBackEnd->setValueforAuxiliaryProperties(m_selectedMaterial, key); + if (!m_hasMaterialRoot) { + if (key == Utils3D::matLibSelectedMaterialProperty) { + if (ModelNode selNode = Utils3D::selectedMaterial(this)) { + m_selectedMaterial = selNode; + m_dynamicPropertiesModel->setSelectedNode(m_selectedMaterial); + QTimer::singleShot(0, this, &MaterialEditorView::resetView); + } + } + } } void MaterialEditorView::propertiesAboutToBeRemoved(const QList &propertyList) @@ -1058,21 +1077,9 @@ void MaterialEditorView::customNotification([[maybe_unused]] const AbstractView const QList &nodeList, const QList &data) { - auto changeSelected = [&]() { - if (!m_hasMaterialRoot && m_selectedMaterial != nodeList.first()) { - m_selectedMaterial = nodeList.first(); - m_dynamicPropertiesModel->setSelectedNode(m_selectedMaterial); - QTimer::singleShot(0, this, &MaterialEditorView::resetView); - } - }; - - if (identifier == "selected_material_changed") { - changeSelected(); - } else if (identifier == "apply_to_selected_triggered") { - changeSelected(); + if (identifier == "apply_to_selected_triggered") { applyMaterialToSelectedModels(nodeList.first(), data.first().toBool()); } else if (identifier == "rename_material") { - changeSelected(); renameMaterial(m_selectedMaterial, data.first().toString()); } else if (identifier == "add_new_material") { handleToolBarAction(MaterialEditorContextObject::AddNewMaterial); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp index 3c2fa6a32e9..41648b23979 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp @@ -19,6 +19,7 @@ #include "rewritingexception.h" #include +#include #include @@ -535,9 +536,10 @@ void PropertyEditorValue::commitDrop(const QString &dropData) void PropertyEditorValue::openMaterialEditor(int idx) { - QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); - QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor", true); - m_modelNode.view()->emitCustomNotification("select_material", {}, {idx}); + if (ModelNode material = Utils3D::getMaterialOfModel(m_modelNode, idx)) { + QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor", true); + Utils3D::selectMaterial(material); + } } void PropertyEditorValue::setForceBound(bool b) diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp index c3e84a5fea8..14e3fa75f00 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp @@ -70,10 +70,21 @@ TextureEditorView::TextureEditorView(AsynchronousImageCache &imageCache, DesignDocument *doc = QmlDesignerPlugin::instance()->currentDesignDocument(); if (doc && !doc->inFileComponentModelActive()) Utils3D::ensureMaterialLibraryNode(this); + ModelNode matLib = Utils3D::materialLibraryNode(this); if (m_qmlBackEnd && m_qmlBackEnd->contextObject()) - m_qmlBackEnd->contextObject()->setHasMaterialLibrary( - Utils3D::materialLibraryNode(this).isValid()); + m_qmlBackEnd->contextObject()->setHasMaterialLibrary(matLib.isValid()); m_ensureMatLibTimer.stop(); + + ModelNode tex = Utils3D::selectedTexture(this); + if (!tex.isValid()) { + const QList matLibNodes = matLib.directSubModelNodes(); + for (const ModelNode &node : matLibNodes) { + if (node.metaInfo().isQtQuick3DTexture()) { + Utils3D::selectTexture(node); + break; + } + } + } } }); @@ -534,6 +545,7 @@ void TextureEditorView::modelAttached(Model *model) // Creating the material library node on model attach causes errors as long as the type // information is not complete yet, so we keep checking until type info is complete. m_ensureMatLibTimer.start(500); + m_selectedTexture = Utils3D::selectedTexture(this); } if (!m_setupCompleted) { @@ -656,11 +668,18 @@ void TextureEditorView::auxiliaryDataChanged(const ModelNode &node, AuxiliaryDataKeyView key, const QVariant &) { + if (!noValidSelection() && node.isSelected()) + m_qmlBackEnd->setValueforAuxiliaryProperties(m_selectedTexture, key); - if (noValidSelection() || !node.isSelected()) - return; - - m_qmlBackEnd->setValueforAuxiliaryProperties(m_selectedTexture, key); + if (!m_hasTextureRoot) { + if (key == Utils3D::matLibSelectedTextureProperty) { + if (ModelNode selNode = Utils3D::selectedTexture(this)) { + m_selectedTexture = selNode; + m_dynamicPropertiesModel->setSelectedNode(m_selectedTexture); + QTimer::singleShot(0, this, &TextureEditorView::resetView); + } + } + } } void TextureEditorView::propertiesAboutToBeRemoved(const QList &propertyList) @@ -832,17 +851,10 @@ void TextureEditorView::customNotification([[maybe_unused]] const AbstractView * const QList &nodeList, [[maybe_unused]] const QList &data) { - if (identifier == "selected_texture_changed") { - if (!m_hasTextureRoot) { - m_selectedTexture = nodeList.first(); - m_dynamicPropertiesModel->setSelectedNode(m_selectedTexture); - QTimer::singleShot(0, this, &TextureEditorView::resetView); - } - } else if (identifier == "add_new_texture") { + if (identifier == "add_new_texture") handleToolBarAction(TextureEditorContextObject::AddNewTexture); - } else if (identifier == "duplicate_texture") { + else if (identifier == "duplicate_texture") duplicateTexture(nodeList.first()); - } } void QmlDesigner::TextureEditorView::highlightSupportedProperties(bool highlight) From 907e4f40ed765e6849d78a60c80e26f98a2e872e Mon Sep 17 00:00:00 2001 From: Knud Dollereder Date: Tue, 13 Aug 2024 15:19:49 +0200 Subject: [PATCH 062/193] QmlDesigner: Add qml notification system Change-Id: I2fbea503c229f520d8936b86a288eadd58c183e0 Reviewed-by: Knud Dollereder Reviewed-by: Thomas Hartmann --- .../qmldesigner/statusbar/CloseButton.qml | 66 ++++ .../statusbar/IconButtonCheckable.qml | 72 ++++ .../statusbar/IssuesOutputPanel.qml | 154 ++++++++ .../statusbar/IssuesOutputToolBar.qml | 104 ++++++ .../qmldesigner/statusbar/IssuesPanel.qml | 79 ++++ .../qtcreator/qmldesigner/statusbar/Main.qml | 54 ++- .../statusbar/MyLinkTextButton.ui.qml | 50 +++ .../statusbar/NotificationButton.ui.qml | 351 ++++++++++++++++++ .../qmldesigner/statusbar/OutputPanel.qml | 85 +++++ .../qmldesigner/statusbar/TabBarButton.ui.qml | 56 +++ .../qmldesigner/statusbar/images/CodeView.png | Bin 0 -> 24757 bytes .../statusbar/images/OutputView.png | Bin 0 -> 9351 bytes .../statusbar/images/delete_trash.png | Bin 0 -> 299 bytes .../statusbar/images/errorActive.png | Bin 0 -> 403 bytes .../statusbar/images/errorPassive.png | Bin 0 -> 342 bytes .../statusbar/images/outputIcon.png | Bin 0 -> 244 bytes .../qmldesigner/statusbar/images/thinBin.png | Bin 0 -> 216 bytes .../statusbar/images/warningsActive.png | Bin 0 -> 403 bytes .../statusbar/images/warningsPassive.png | Bin 0 -> 286 bytes src/plugins/qmldesigner/CMakeLists.txt | 4 + .../components/toolbar/appoutputmodel.cpp | 251 +++++++++++++ .../components/toolbar/appoutputmodel.h | 146 ++++++++ .../components/toolbar/messagemodel.cpp | 137 +++++++ .../components/toolbar/messagemodel.h | 50 +++ .../components/toolbar/toolbarbackend.cpp | 7 + 25 files changed, 1665 insertions(+), 1 deletion(-) create mode 100644 share/qtcreator/qmldesigner/statusbar/CloseButton.qml create mode 100644 share/qtcreator/qmldesigner/statusbar/IconButtonCheckable.qml create mode 100644 share/qtcreator/qmldesigner/statusbar/IssuesOutputPanel.qml create mode 100644 share/qtcreator/qmldesigner/statusbar/IssuesOutputToolBar.qml create mode 100644 share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml create mode 100644 share/qtcreator/qmldesigner/statusbar/MyLinkTextButton.ui.qml create mode 100644 share/qtcreator/qmldesigner/statusbar/NotificationButton.ui.qml create mode 100644 share/qtcreator/qmldesigner/statusbar/OutputPanel.qml create mode 100644 share/qtcreator/qmldesigner/statusbar/TabBarButton.ui.qml create mode 100644 share/qtcreator/qmldesigner/statusbar/images/CodeView.png create mode 100644 share/qtcreator/qmldesigner/statusbar/images/OutputView.png create mode 100644 share/qtcreator/qmldesigner/statusbar/images/delete_trash.png create mode 100644 share/qtcreator/qmldesigner/statusbar/images/errorActive.png create mode 100644 share/qtcreator/qmldesigner/statusbar/images/errorPassive.png create mode 100644 share/qtcreator/qmldesigner/statusbar/images/outputIcon.png create mode 100644 share/qtcreator/qmldesigner/statusbar/images/thinBin.png create mode 100644 share/qtcreator/qmldesigner/statusbar/images/warningsActive.png create mode 100644 share/qtcreator/qmldesigner/statusbar/images/warningsPassive.png create mode 100644 src/plugins/qmldesigner/components/toolbar/appoutputmodel.cpp create mode 100644 src/plugins/qmldesigner/components/toolbar/appoutputmodel.h create mode 100644 src/plugins/qmldesigner/components/toolbar/messagemodel.cpp create mode 100644 src/plugins/qmldesigner/components/toolbar/messagemodel.h diff --git a/share/qtcreator/qmldesigner/statusbar/CloseButton.qml b/share/qtcreator/qmldesigner/statusbar/CloseButton.qml new file mode 100644 index 00000000000..a330b93ed35 --- /dev/null +++ b/share/qtcreator/qmldesigner/statusbar/CloseButton.qml @@ -0,0 +1,66 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T + +T.Button { + id: root + width: 29 + height: 29 + + Item { + id: closeButton + anchors.fill: parent + state: "idle" + + Item { + id: closeIcon + width: 15 + height: 15 + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + rotation: 45 + + Rectangle { + id: rectangle + width: 1 + height: 15 + color: "#ffffff" + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + } + + Rectangle { + id: rectangle1 + width: 1 + height: 15 + color: "#ffffff" + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + rotation: 90 + } + } + } + + states: [ + State { + name: "idle" + when: !root.hovered && !root.pressed + + PropertyChanges { + target: rectangle + color: "#b2b2b2" + } + + PropertyChanges { + target: rectangle1 + color: "#b2b2b2" + } + }, + State { + name: "hoverPress" + when: (root.hovered || root.pressed) + } + ] +} diff --git a/share/qtcreator/qmldesigner/statusbar/IconButtonCheckable.qml b/share/qtcreator/qmldesigner/statusbar/IconButtonCheckable.qml new file mode 100644 index 00000000000..cbf7a71dcde --- /dev/null +++ b/share/qtcreator/qmldesigner/statusbar/IconButtonCheckable.qml @@ -0,0 +1,72 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T + +T.Button { + id: root + width: 29 + height: 29 + state: "idle" + property alias imageSource: image.source + property color idleBack: "#202020" + property color hoverBack: "#2d2d2d" + + Rectangle { + id: bkg + color: root.idleBack + radius: 5 + border.color: "#424242" + anchors.fill: parent + } + + Image { + id: image + width: 15 + height: 15 + anchors.verticalCenter: parent.verticalCenter + source: "qrc:/qtquickplugin/images/template_image.png" + anchors.horizontalCenter: parent.horizontalCenter + fillMode: Image.PreserveAspectFit + } + states: [ + State { + name: "idle" + when: !root.hovered && !root.pressed && !root.checked + && root.enabled + }, + State { + name: "hover" + when: root.hovered && !root.pressed && !root.checked && root.enabled + PropertyChanges { + target: bkg + color: root.hoverBack + } + }, + State { + name: "pressCheck" + when: (root.pressed || root.checked) && root.enabled + + PropertyChanges { + target: bkg + color: root.hoverBack + border.color: "#57b9fc" + } + }, + State { + name: "blocked" + when: !root.enabled + + PropertyChanges { + target: bkg + border.color: "#3a3a3a" + } + + PropertyChanges { + target: image + opacity: 0.404 + } + } + ] +} diff --git a/share/qtcreator/qmldesigner/statusbar/IssuesOutputPanel.qml b/share/qtcreator/qmldesigner/statusbar/IssuesOutputPanel.qml new file mode 100644 index 00000000000..6aaad1f2ff8 --- /dev/null +++ b/share/qtcreator/qmldesigner/statusbar/IssuesOutputPanel.qml @@ -0,0 +1,154 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +import QtQuick 6.7 +import QtQuick.Controls +import QtQuick.Layouts + +import StudioControls as StudioControls + +import ToolBar + +StudioControls.PopupDialog { + + id: root + width: 1024 + + property Item targetItem + + property alias warningCount: issuesPanel.warningCount + property alias errorCount: issuesPanel.errorCount + + function toggleShowIssuesPanel() { + + if (!root.visible) { + issuesButton.checked = true + outputPanel.visible = false + issuesPanel.visible = true + root.show(root.targetItem) + } else { + root.visible = false + root.close() + } + } + + function toggleShowOutputPanel() { + if (!root.visible) { + outputButton.checked = true + issuesPanel.visible = false + outputPanel.visible = true + root.visible = true + } else { + root.visible = false + } + } + + titleBar: RowLayout { + id: toolBar + + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 15 + anchors.rightMargin: 10 + + RowLayout { + id: leftAlignedButtons + Layout.alignment: Qt.AlignLeft + + TabBarButton { + id: issuesButton + autoExclusive: true + checked: true + + Connections { + target: issuesButton + function onClicked() { + if (issuesButton.checked) { + issuesPanel.visible = true + outputPanel.visible = false + } else { return } + } + } + } + + TabBarButton { + id: outputButton + labelText: "Output" + autoExclusive: true + + Connections { + target: outputButton + function onClicked() { + if (outputButton.checked) { + issuesPanel.visible = false + outputPanel.visible = true + } else { return } + } + } + } + } + RowLayout { + id: rightAlignedButtons + Layout.alignment: Qt.AlignRight + + // IconButton { + // id: showOutputView + // imageSource: "images/outputIcon.png" + // idleBack: "#282828" + // hoverBack: "#3a3a3a" + // Connections { + // target: showOutputView + // function onClicked() { + // root.showOutputViewSignal() + // } + // } + // } + + IconButtonCheckable { + id: clearIssuesButton + visible: issuesButton.checked + hoverBack: "#3a3a3a" + idleBack: "#282828" + imageSource: "images/thinBin.png" + Connections { + target: clearIssuesButton + function onClicked() { + issuesPanel.clearIssues() + } + } + } + + IconButtonCheckable { + id: clearOutputButton + visible: outputButton.checked + hoverBack: "#3a3a3a" + idleBack: "#282828" + imageSource: "images/thinBin.png" + Connections { + target: clearOutputButton + function onClicked() { + outputPanel.clearOutput() + } + } + } + } + } + + Item { + id: panels + width: parent.width + height: 500 + + IssuesPanel { + id: issuesPanel + visible: false + anchors.fill: panels + } + + OutputPanel { + id: outputPanel + visible: false + anchors.fill: panels + } + } +} diff --git a/share/qtcreator/qmldesigner/statusbar/IssuesOutputToolBar.qml b/share/qtcreator/qmldesigner/statusbar/IssuesOutputToolBar.qml new file mode 100644 index 00000000000..eda61d32a74 --- /dev/null +++ b/share/qtcreator/qmldesigner/statusbar/IssuesOutputToolBar.qml @@ -0,0 +1,104 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +import QtQuick 6.7 +import QtQuick.Controls +import QtQuick.Layouts + +Rectangle { + id: root + height: 41 + color: "#282828" + + signal popupClosed + signal issuesCheckedSignal + signal outputCheckedSignal + signal issuesClearedSignal + signal outputClearedSignal + + property alias showOutputViewEnabled: showOutputView.enabled + property alias clearOutputEnabled: clearOutputButton.enabled + property alias clearIssuesEnabled: clearIssuesButton.enabled + + property alias outputChecked: outputButton.checked + property alias issuesChecked: issuesButton.checked + + RowLayout { + id: tabBar + + anchors.verticalCenter: root.verticalCenter + anchors.left: root.left + anchors.leftMargin: 15 + + TabBarButton { + id: issuesButton + autoExclusive: true + checked: true + + Connections { + target: issuesButton + function onClicked() { + if (issuesButton.checked) { + root.issuesCheckedSignal() + } else + return + } + } + } + + TabBarButton { + id: outputButton + labelText: "Output" + autoExclusive: true + + Connections { + target: outputButton + function onClicked() { + if (outputButton.checked) { root.outputCheckedSignal() } + else { return } + } + } + } + } + + RowLayout { + anchors.right: root.right + anchors.rightMargin: 10 + + IconButton { + id: showOutputView + imageSource: "images/outputIcon.png" + idleBack: "#282828" + hoverBack: "#3a3a3a" + Connections { + target: showOutputView + function onClicked() { root.showOutputViewSignal() } + } + } + + IconButton { + id: clearIssuesButton + visible: issuesButton.checked + hoverBack: "#3a3a3a" + idleBack: "#282828" + imageSource: "images/thinBin.png" + Connections { + target: clearIssuesButton + function onClicked() { + root.issuesClearedSignal() + } + } + } + + IconButton { + id: clearOutputButton + visible: outputButton.checked + hoverBack: "#3a3a3a" + idleBack: "#282828" + imageSource: "images/thinBin.png" + Connections { + target: clearOutputButton + function onClicked() { root.outputClearedSignal() } + } + } + } +} diff --git a/share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml b/share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml new file mode 100644 index 00000000000..33d92642d6c --- /dev/null +++ b/share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml @@ -0,0 +1,79 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +import QtQuick 6.7 +import QtQuick.Controls +import QtQuick.Layouts +import ToolBar +import OutputPane +import StudioControls as StudioControls +import StudioTheme as StudioTheme + +ScrollView { + + id: issuesPanel + + signal showCodeViewSignal + + property int warningCount: messageModel.warningCount + property int errorCount: messageModel.errorCount + + function clearIssues() { messageModel.resetModel() } + + ScrollBar.vertical: StudioControls.TransientScrollBar { + id: verticalScrollBar + style: StudioTheme.Values.viewStyle + parent: issuesPanel + x: issuesPanel.width - verticalScrollBar.width + y: 0 + height: issuesPanel.availableHeight + orientation: Qt.Vertical + + show: (issuesPanel.hovered || issuesPanel.focus) + && verticalScrollBar.isNeeded + } + + ColumnLayout { + Repeater { + id: listView + + model: MessageModel { + id: messageModel + } + + delegate: RowLayout { + spacing: 10 + Image { + id: typeImage + source: { + if (type == "Warning") { "images/warningsActive.png" } + else { "images/errorActive.png" } + } + fillMode: Image.PreserveAspectFit + } + + MyLinkTextButton { + id: linkTextWarning + linkText: location + Layout.preferredHeight: 18 + + Connections { + target: linkTextWarning + function onClicked() { messageModel.jumpToCode(index) } + } + } + + Text { + id: historyTime6 + color: { + if (type == "Warning") { "#ffbb0c" } + else { "#ff4848" } + } + text: qsTr(message) + font.pixelSize: 12 + verticalAlignment: Text.AlignTop + Layout.preferredHeight: 18 + } + } + } + } +} diff --git a/share/qtcreator/qmldesigner/statusbar/Main.qml b/share/qtcreator/qmldesigner/statusbar/Main.qml index da18cf67938..f849cc19327 100644 --- a/share/qtcreator/qmldesigner/statusbar/Main.qml +++ b/share/qtcreator/qmldesigner/statusbar/Main.qml @@ -1,8 +1,9 @@ // Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 - import QtQuick import QtQuick.Controls +import QtQuick.Layouts + import StudioControls 1.0 as StudioControls import StudioTheme 1.0 as StudioTheme import "../toolbar" @@ -95,5 +96,56 @@ Item { onCurrentStyleIndexChanged: styles.currentIndex = backend.currentStyle } } + + RowLayout { + id: buttonRow + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 10 + spacing: 10 + + NotificationButton { + id: issuesNotification + warningCount: popupPanel.warningCount + errorCount: popupPanel.errorCount + + Layout.alignment: Qt.AlignVCenter + + + + Connections { + target: issuesNotification + function onClicked() { + popupPanel.toggleShowIssuesPanel() + } + } + } + + IconButtonCheckable { + id: outputButton + imageSource: "images/outputIcon.png" + checkable: true + + Connections { + target: outputButton + function onClicked() { + popupPanel.toggleShowOutputPanel() + } + } + } + } } + + Item { + id: popupTarget + y: -282 //magic number + anchors.right: parent.right + } + + IssuesOutputPanel { + targetItem: popupTarget + id: popupPanel + keepOpen: true + } + } diff --git a/share/qtcreator/qmldesigner/statusbar/MyLinkTextButton.ui.qml b/share/qtcreator/qmldesigner/statusbar/MyLinkTextButton.ui.qml new file mode 100644 index 00000000000..a9763aa5468 --- /dev/null +++ b/share/qtcreator/qmldesigner/statusbar/MyLinkTextButton.ui.qml @@ -0,0 +1,50 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T + +T.Button { + id: root + width: childrenRect.width + state: "idle" + property alias linkText: linkTextLabel.text + + Text { + id: linkTextLabel + color: "#57b9fc" + text: qsTr("Screen01.ui.qml - Line 8") + font.pixelSize: 12 + verticalAlignment: Text.AlignVCenter + } + + Rectangle { + id: rectangle + width: linkTextLabel.width + height: 1 + color: "#57b9fc" + anchors.left: parent.left + anchors.bottom: parent.bottom + anchors.bottomMargin: 2 + } + states: [ + State { + name: "idle" + when: !root.hovered && !root.pressed + + PropertyChanges { + target: rectangle + visible: false + } + }, + State { + name: "hoverClick" + when: (root.hovered || root.pressed) + + PropertyChanges { + target: rectangle + visible: true + } + } + ] +} diff --git a/share/qtcreator/qmldesigner/statusbar/NotificationButton.ui.qml b/share/qtcreator/qmldesigner/statusbar/NotificationButton.ui.qml new file mode 100644 index 00000000000..2f8adef1d91 --- /dev/null +++ b/share/qtcreator/qmldesigner/statusbar/NotificationButton.ui.qml @@ -0,0 +1,351 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T + +T.Button { + id: root + + property int warningCount: 0 + property int errorCount: 0 + + property bool hasWarnings: warningCount > 0 + property bool hasErrors: errorCount > 0 + + width: 136 + height: 29 + checkable: true + state: "idleEmpty" + + Rectangle { + id: bck + color: "#202020" + radius: 5 + border.color: "#444444" + anchors.fill: parent + + Text { + id: warningNumLabel + color: "#ffffff" + text: root.warningCount + anchors.verticalCenter: parent.verticalCenter + anchors.right: warningsIcon.left + anchors.rightMargin: 8 + font.pixelSize: 12 + horizontalAlignment: Text.AlignRight + } + + Text { + id: errorNumLabel + color: "#ffffff" + text: root.errorCount + anchors.verticalCenter: parent.verticalCenter + anchors.left: errorIcon.right + anchors.leftMargin: 8 + font.pixelSize: 12 + horizontalAlignment: Text.AlignLeft + } + + Image { + id: errorIcon + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 47 + source: "images/errorPassive.png" + fillMode: Image.PreserveAspectFit + } + + Image { + id: warningsIcon + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 47 + source: "images/warningsPassive.png" + fillMode: Image.PreserveAspectFit + } + } + states: [ + State { + name: "idleEmpty" + when: !root.hovered && !root.checked && !root.pressed + && !root.hasErrors && !root.hasWarnings + + PropertyChanges { + target: warningNumLabel + text: "0" + } + + PropertyChanges { + target: errorNumLabel + text: "0" + } + }, + State { + name: "idleHover" + when: root.hovered && !(root.checked || root.pressed) + && !root.hasErrors && !root.hasWarnings + PropertyChanges { + target: warningNumLabel + text: "0" + } + + PropertyChanges { + target: errorNumLabel + text: "0" + } + + PropertyChanges { + target: bck + color: "#2d2d2d" + } + }, + + State { + name: "pressCheck" + when: (root.checked || root.pressed) && !root.hasErrors && !root.hasWarnings + PropertyChanges { + target: warningNumLabel + text: "0" + } + + PropertyChanges { + target: errorNumLabel + text: "0" + } + + PropertyChanges { + target: bck + color: "#2d2d2d" + border.color: "#2eb0f9" + } + }, + + State { + name: "idleWarningsOnly" + when: !root.hovered && !root.checked && !root.pressed + && !root.hasErrors && root.hasWarnings + + PropertyChanges { + target: warningsIcon + source: "images/warningsActive.png" + } + + PropertyChanges { + target: warningNumLabel + color: "#ffbb0c" + } + + PropertyChanges { + target: errorNumLabel + text: "0" + } + }, + State { + name: "hoverWarningsOnly" + when: root.hovered && !root.checked && !root.pressed + && !root.hasErrors && root.hasWarnings + PropertyChanges { + target: warningsIcon + source: "images/warningsActive.png" + } + + PropertyChanges { + target: warningNumLabel + color: "#ffbb0c" + } + + PropertyChanges { + target: errorNumLabel + text: "0" + } + + PropertyChanges { + target: bck + color: "#2d2d2d" + } + }, + + State { + name: "pressCheckWarningsOnly" + when: (root.checked || root.pressed) && !root.hasErrors + && root.hasWarnings + PropertyChanges { + target: warningsIcon + source: "images/warningsActive.png" + } + + PropertyChanges { + target: warningNumLabel + color: "#ffbb0c" + } + + PropertyChanges { + target: errorNumLabel + text: "0" + } + + PropertyChanges { + target: bck + color: "#2d2d2d" + border.color: "#57b9fc" + } + }, + + State { + name: "idleErrorsOnly" + when: !root.hovered && !root.checked && !root.pressed + && root.hasErrors && !root.hasWarnings + + PropertyChanges { + target: warningNumLabel + text: "0" + } + + PropertyChanges { + target: errorIcon + source: "images/errorActive.png" + } + + PropertyChanges { + target: errorNumLabel + color: "#ff4848" + } + }, + State { + name: "hoverErrorsOnly" + when: root.hovered && !root.checked && !root.pressed + && root.hasErrors && !root.hasWarnings + PropertyChanges { + target: warningNumLabel + text: "0" + } + + PropertyChanges { + target: errorIcon + source: "images/errorActive.png" + } + + PropertyChanges { + target: errorNumLabel + color: "#ff4848" + } + + PropertyChanges { + target: bck + color: "#2d2d2d" + } + }, + + State { + name: "pressCheckErrorsOnly" + when: (root.checked || root.pressed) && root.hasErrors + && !root.hasWarnings + PropertyChanges { + target: warningNumLabel + text: "0" + } + + PropertyChanges { + target: errorIcon + source: "images/errorActive.png" + } + + PropertyChanges { + target: errorNumLabel + color: "#ff4848" + } + + PropertyChanges { + target: bck + color: "#2d2d2d" + border.color: "#57b9fc" + } + }, + + State { + name: "idlesErrorsAndWarnings" + when: !root.hovered && !root.checked && !root.pressed + && root.hasErrors && root.hasWarnings + + PropertyChanges { + target: warningNumLabel + color: "#ffbb0c" + } + + PropertyChanges { + target: warningsIcon + source: "images/warningsActive.png" + } + + PropertyChanges { + target: errorNumLabel + color: "#ff4848" + } + + PropertyChanges { + target: errorIcon + source: "images/errorActive.png" + } + }, + State { + name: "hoverErrorsAndWarnings" + when: root.hovered && !root.checked && !root.pressed + && root.hasErrors && root.hasWarnings + PropertyChanges { + target: warningNumLabel + color: "#ffbb0c" + } + + PropertyChanges { + target: warningsIcon + source: "images/warningsActive.png" + } + + PropertyChanges { + target: errorNumLabel + color: "#ff4848" + } + + PropertyChanges { + target: errorIcon + source: "images/errorActive.png" + } + + PropertyChanges { + target: bck + color: "#2d2d2d" + } + }, + State { + name: "pressCheckWarningsErrors" + when: (root.checked || root.pressed) && root.hasErrors + && root.hasWarnings + PropertyChanges { + target: warningNumLabel + color: "#ffbb0c" + } + + PropertyChanges { + target: warningsIcon + source: "images/warningsActive.png" + } + + PropertyChanges { + target: errorNumLabel + color: "#ff4848" + } + + PropertyChanges { + target: errorIcon + source: "images/errorActive.png" + } + + PropertyChanges { + target: bck + color: "#2d2d2d" + border.color: "#2eb0f9" + } + } + ] +} diff --git a/share/qtcreator/qmldesigner/statusbar/OutputPanel.qml b/share/qtcreator/qmldesigner/statusbar/OutputPanel.qml new file mode 100644 index 00000000000..781fc159ae9 --- /dev/null +++ b/share/qtcreator/qmldesigner/statusbar/OutputPanel.qml @@ -0,0 +1,85 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import OutputPane +import StudioControls as StudioControls +import StudioTheme as StudioTheme + +ScrollView { + id: root + + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + + function clearOutput() { + parentListModel.resetModel() + } + + clip: true + + ScrollBar.vertical: StudioControls.TransientScrollBar { + id: verticalScrollBar + style: StudioTheme.Values.viewStyle + parent: root + x: root.width - verticalScrollBar.width + y: 0 + height: root.availableHeight + orientation: Qt.Vertical + + show: (root.hovered || root.focus) + && verticalScrollBar.isNeeded + } + + ColumnLayout { + id: clayout + + Repeater { + id: parentList + model: AppOutputParentModel { + id: parentListModel + historyColor: "grey" + messageColor: "#007b7b" + errorColor: "#ff6666" + } + + delegate: ColumnLayout { + id: parentDelegate + spacing: 0 + + required property int index + required property string run + required property color blockColor + + Text { + id: timeStampText + text: run + color: blockColor + } + + Repeater { + id: childList + + model: AppOutputChildModel { + id: childListModel + parentModel: parentListModel + row: parentDelegate.index + } + + delegate: Column { + id: childDelegate + + required property string message + required property color messageColor + Text { + wrapMode: Text.WordWrap + text: message + color: messageColor + width: root.width - verticalScrollBar.width + } + } + } + } + } + } +} diff --git a/share/qtcreator/qmldesigner/statusbar/TabBarButton.ui.qml b/share/qtcreator/qmldesigner/statusbar/TabBarButton.ui.qml new file mode 100644 index 00000000000..9bcff61bb19 --- /dev/null +++ b/share/qtcreator/qmldesigner/statusbar/TabBarButton.ui.qml @@ -0,0 +1,56 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +import QtQuick +import QtQuick.Controls +import QtQuick.Templates as T + +T.Button { + id: root + width: 100 + height: 29 + property alias labelText: label.text + state: "idle" + checkable: true + + Rectangle { + id: background + color: "#282828" + radius: 5 + border.color: "#424242" + anchors.fill: parent + } + + Text { + id: label + color: "#ffffff" + text: qsTr("Issues") + anchors.verticalCenter: parent.verticalCenter + font.pixelSize: 12 + anchors.horizontalCenter: parent.horizontalCenter + } + states: [ + State { + name: "idle" + when: !root.hovered && !root.pressed & !root.checked + }, + State { + name: "hover" + when: root.hovered && !root.pressed & !root.checked + + PropertyChanges { + target: background + color: "#2f2f2f" + } + }, + State { + name: "pressCheck" + when: (root.pressed || root.checked) + + PropertyChanges { + target: background + color: "#57b9fc" + border.color: "#57b9fc" + } + } + ] +} diff --git a/share/qtcreator/qmldesigner/statusbar/images/CodeView.png b/share/qtcreator/qmldesigner/statusbar/images/CodeView.png new file mode 100644 index 0000000000000000000000000000000000000000..56107927f4f1ecafd1e9453f10c1eb004b882cc9 GIT binary patch literal 24757 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 TESk%}z`)??>gTe~DWM4f#LO)7 literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/statusbar/images/OutputView.png b/share/qtcreator/qmldesigner/statusbar/images/OutputView.png new file mode 100644 index 0000000000000000000000000000000000000000..6b8cadc39aab6e58d6e8f94c1aaae9bf0896a1de GIT binary patch literal 9351 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 Xq)!P+Z5Lx;U|{fc^>bP0l+XkK^>4OD literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/statusbar/images/delete_trash.png b/share/qtcreator/qmldesigner/statusbar/images/delete_trash.png new file mode 100644 index 0000000000000000000000000000000000000000..3dd7cd401af953d70f1e25c453b29d6c53699806 GIT binary patch literal 299 zcmeAS@N?(olHy`uVBq!ia0y~yVBlt8VBqIqV_;w~vNbheU|`@Z@Q5sCVBi)8VMc~o zb0ioT7#NF#+?^QKos)UVz`($g?&#~tz_78O`%fY(0|UbWPZ!6K3dXGy6L}9A2(;c# zWqQ`|FhL`MZ$*nG1E&HbD>M5725wizsRry%ZFjUSHc|ZZKsA2X*L$)0<<~ThN>s~e zUufWbvv#YaG+TkNmzQDq;r9nG)=b|XwD;&nw%CIr2m0Pd7{)C*ADosG(&+li((6)t zh5pBdhyEWvl3uWpb@2?h4S|<4Uat`lPJi{=cj`~a|HjX4s~fFmKR*>8wD>jmQHl2| z?{U5Bi_~<|xvhdp7V1NBiCqE933A zpEh<$)HF5hzse92Q)&_8!F_@6y^q}|Tc=gs4%@Wj)~mUs=JeK0kRXk^Q zr*UI^O7KyYr@{p@K6K~GzAxMyY8sfM*tyq8f?;jV$=`1(Q`i^W;(cj2Womq~u=20M z1ZkI_*LAp4_p>uCQ?RW(+gW{hwm0{MK5Z3waiPD5-wSemI(^~RnoY-(xoX??*PeQ{ z{j9KVf!66Fy~e}a=c+C5ciDP7?~BQ_Y4KNu&u^Nb7{^&t!N9=4;OXk;vd$@?2>`7X Bn-2g0 literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/statusbar/images/errorPassive.png b/share/qtcreator/qmldesigner/statusbar/images/errorPassive.png new file mode 100644 index 0000000000000000000000000000000000000000..0b5749c630e4b275066bdd9994c0b11d9e7db181 GIT binary patch literal 342 zcmeAS@N?(olHy`uVBq!ia0y~yVBiN~4mJh`2J356y%-o6I14-?iy0WWg+Z8+Vb&Z8 z1_lPk;vjb?hIQv;UNSH+u%tWsIx;Y9?C1WI$jZRL@Y>VGF{FZVYA`qNAp?QELM$Op zfd^y^R2DQ?GH_bl2yh5!XnDvWV<3{lcgni#?5$<0k5%>m-rc?Jebge3Yqz*^4&Li~ zks5P!<0)ZD6Y~kTjeoGPN2Wb=`xU)3_wd2j<0~ri+ z4L7=N)_Z2<=d@fo{mXNsw`nfUrKU+OJ&G&-3;OAANh%Ia3JLk@R)1ADXO_MDR1U!n t%a5&2Vc2kEhO&K;wn56CoLP@2?q=NJ;LiBs6&uKr44$rjF6*2UngEy=P;~$R literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/statusbar/images/thinBin.png b/share/qtcreator/qmldesigner/statusbar/images/thinBin.png new file mode 100644 index 0000000000000000000000000000000000000000..5df002cf896e8856048ec2fd81a7328bd5e45fb7 GIT binary patch literal 216 zcmeAS@N?(olHy`uVBq!ia0y~yVBiF?IoKE&7^)duKonU}oXkrG1_qXNM_)$E)e-c?47#MOrT^vIy7}o|gavo6Nd3}uUV{_#x zyBX?Lr}i8Wwpp0%-lBBsn1O)QswJ7?Y2RE*ILfbdY4}8$U-o(6e_}^)#E$+o?^zzQ zvH9_a7)Z%^Z<&?*Vb{&88Bs5ppVe-f`N+Zk<>}L$o4OjJzb;^V$fokCk@rLLqmv8_ O3=E#GelF{r5}E*C4M}YP literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/statusbar/images/warningsActive.png b/share/qtcreator/qmldesigner/statusbar/images/warningsActive.png new file mode 100644 index 0000000000000000000000000000000000000000..aed92e6933095bb8bc5ae61e6fe52359e225cf27 GIT binary patch literal 403 zcmeAS@N?(olHy`uVBq!ia0y~yVBlw9VBq6mV_;zT(B<}?fq{Xuz$3Dlfq`2Xgc%uT z&5>YWU|=i`a(7}_cTVOd0|Ns~x}&cn1H;CC?mvmF3=E7Ko-U3d6^v7Z-ufOk5ZLQ| zcz@U_4!NZqD~0|iFk3kuV#!o*@N+PGQNLnJ-v!=Tf=Y@iEZh3i&D}C*)!DvWbmQdR z>bmnTwiAp3KN;!-Hl2FOvFKiGa*FKp=A(?9P|m1)eWtSv|Diss#% zA#~o<-;R6#zux(tDhuW3&dvFjqtsPm!+N_p`N{8HhnBPc^V$6-&^xaw)bC7deuCE@ zg?5X&R(8|Ox!;YW=T0g$V*k9(X5ZTETQjF`J=@*nnK4K3wyU!6;U!GbU+oi~AC%fE zFMIA=+vmKOJTj~Ond;u;n_S#t6HqJ8@?TWZO8xiI*&>TLf0RW<%3iq7vq?bKI;^YW zRQcRzmp@IHh%wF+NLnyuUF%c#Jhk3~>-6$W$_`Ine^!2L-^}nu*P8Pg7#J8lUHx3v IIVCg!0K1u^r2qf` literal 0 HcmV?d00001 diff --git a/share/qtcreator/qmldesigner/statusbar/images/warningsPassive.png b/share/qtcreator/qmldesigner/statusbar/images/warningsPassive.png new file mode 100644 index 0000000000000000000000000000000000000000..4d3ad8521190c49ac1e6c5a2f9c77f266e26de51 GIT binary patch literal 286 zcmeAS@N?(olHy`uVBq!ia0y~yVBlw9VBq6mV_;zT(B<}?fq{Xuz$3Dlfq`2Xgc%uT z&5>YWU|=i`a(7}_cTVOd0|Ns~x}&cn1H;CC?mvmF3=9mLJzX3_Dj4Smatj_-;9+I= zaNrV}(9mMJfX|HmjH9YTVyOY=;PFPUI^=WY1%oqk8+>kn1f oJcx2V{lAyL{!q>4YkBdzS9 +#include + +AppOutputChildModel::AppOutputChildModel(QObject *parent) + : QAbstractListModel(parent) +{} + +int AppOutputChildModel::row() const +{ + return m_row; +} + +void AppOutputChildModel::setRow(int row) +{ + m_row = row; +} + +QAbstractListModel *AppOutputChildModel::parentModel() const +{ + return m_parentModel; +} + +void AppOutputChildModel::setParentModel(QAbstractListModel *model) +{ + if (AppOutputParentModel *sm = qobject_cast(model)) { + if (m_parentModel != sm) { + m_parentModel = sm; + connect(m_parentModel, + &AppOutputParentModel::messageAdded, + this, + &AppOutputChildModel::addMessage); + emit parentModelChanged(); + } + } +} + +void AppOutputChildModel::addMessage(int row, const QString &message, const QColor &color) +{ + if (row != m_row) + return; + + if (!m_parentModel) + return; + + if (AppOutputParentModel::Run *run = m_parentModel->run(m_row)) { + int at = run->messages.size(); + beginInsertRows(QModelIndex(), at, at); + run->messages.push_back({message, color}); + endInsertRows(); + } +} + +int AppOutputChildModel::rowCount(const QModelIndex &) const +{ + if (m_parentModel) + return m_parentModel->messageCount(m_row); + return 0; +} + +QHash AppOutputChildModel::roleNames() const +{ + QHash out; + out[MessageRole] = "message"; + out[ColorRole] = "messageColor"; + return out; +} + +QVariant AppOutputChildModel::data(const QModelIndex &index, int role) const +{ + if (m_parentModel) + return m_parentModel->runData(m_row, index.row(), role); + + return {}; +} + + +AppOutputParentModel::Run *AppOutputParentModel::run(int row) +{ + if (row < static_cast(m_runs.size()) && row >= 0) + return &m_runs.at(row); + + return nullptr; +} + +AppOutputParentModel::AppOutputParentModel(QObject *parent) + : QAbstractListModel(parent) +{ + setupRunControls(); +} + +QColor AppOutputParentModel::historyColor() const +{ + return m_historyColor; +} + +void AppOutputParentModel::setHistoryColor(const QColor &color) +{ + if (m_historyColor != color) { + m_historyColor = color; + emit colorChanged(); + } +} + +QColor AppOutputParentModel::messageColor() const +{ + return m_messageColor; +} + +void AppOutputParentModel::setMessageColor(const QColor &color) +{ + if (m_messageColor != color) { + m_messageColor = color; + emit colorChanged(); + } +} + +QColor AppOutputParentModel::errorColor() const +{ + return m_errorColor; +} + +void AppOutputParentModel::setErrorColor(const QColor &color) +{ + if (m_errorColor != color) { + m_errorColor = color; + emit colorChanged(); + } +} + +QColor AppOutputParentModel::debugColor() const +{ + return m_debugColor; +} + +void AppOutputParentModel::setDebugColor(const QColor &color) +{ + if (m_debugColor != color) { + m_debugColor = color; + emit colorChanged(); + } +} + +void AppOutputParentModel::resetModel() +{ + beginResetModel(); + m_runs.clear(); + endResetModel(); + emit modelChanged(); +} + +int AppOutputParentModel::messageCount(int row) const +{ + if (row < static_cast(m_runs.size()) && row >= 0) + return m_runs.at(row).messages.size(); + + return 0; +} + +int AppOutputParentModel::rowCount(const QModelIndex &) const +{ + return m_runs.size(); +} + +QHash AppOutputParentModel::roleNames() const +{ + QHash out; + out[RunRole] = "run"; + out[ColorRole] = "blockColor"; + return out; +} + +QVariant AppOutputParentModel::runData(int runIdx, int msgIdx, int role) const +{ + if (runIdx < static_cast(m_runs.size()) && runIdx >= 0) { + if (msgIdx < static_cast(m_runs.at(runIdx).messages.size()) && msgIdx >= 0) { + if (role == AppOutputChildModel::MessageRole) + return m_runs.at(runIdx).messages.at(msgIdx).message; + else if (role == AppOutputChildModel::ColorRole) { + if (runIdx == static_cast(m_runs.size()) - 1) + return m_runs.at(runIdx).messages.at(msgIdx).color; + else + return m_historyColor; + } + } + } + return {}; +} + +QVariant AppOutputParentModel::data(const QModelIndex &index, int role) const +{ + if (index.isValid() && index.row() < rowCount()) { + int row = index.row(); + if (role == RunRole) { + return m_runs.at(row).timestamp.c_str(); + } else if (role == ColorRole) { + int last = static_cast(m_runs.size()) - 1; + return row < last ? m_historyColor : m_messageColor; + } else { + qWarning() << Q_FUNC_INFO << "invalid role"; + } + } else { + qWarning() << Q_FUNC_INFO << "invalid index"; + } + return {}; +} + +void AppOutputParentModel::setupRunControls() +{ + auto *explorerPlugin = ProjectExplorer::ProjectExplorerPlugin::instance(); + connect(explorerPlugin, + &ProjectExplorer::ProjectExplorerPlugin::runControlStarted, + [this](ProjectExplorer::RunControl *rc) { + AppOutputParentModel::Run run; + run.timestamp = QTime::currentTime().toString().toStdString(); + run.messages.push_back({rc->commandLine().displayName(), m_messageColor}); + + beginResetModel(); + m_runs.push_back(run); + endResetModel(); + + connect(rc, + &ProjectExplorer::RunControl::appendMessage, + [this](const QString &out, Utils::OutputFormat format) { + if (!m_runs.empty()) { + int row = static_cast(m_runs.size()) - 1; + emit messageAdded(row, out.trimmed(), colorFromFormat(format)); + } + }); + }); +} + +QColor AppOutputParentModel::colorFromFormat(Utils::OutputFormat format) const +{ + switch (format) { + case Utils::NormalMessageFormat: + case Utils::LogMessageFormat: + case Utils::StdOutFormat: + case Utils::GeneralMessageFormat: + return m_messageColor; + case Utils::DebugFormat: + return m_debugColor; + case Utils::StdErrFormat: + return m_errorColor; + default: + return m_messageColor; + } +} diff --git a/src/plugins/qmldesigner/components/toolbar/appoutputmodel.h b/src/plugins/qmldesigner/components/toolbar/appoutputmodel.h new file mode 100644 index 00000000000..011e4b26ee4 --- /dev/null +++ b/src/plugins/qmldesigner/components/toolbar/appoutputmodel.h @@ -0,0 +1,146 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#pragma once + +#include +#include + +#include + +class AppOutputParentModel; + +class AppOutputChildModel : public QAbstractListModel +{ + Q_OBJECT + QML_ELEMENT + QML_SINGLETON + + Q_PROPERTY(QAbstractListModel *parentModel READ parentModel WRITE setParentModel NOTIFY parentModelChanged) + Q_PROPERTY(int row READ row WRITE setRow NOTIFY rowChanged) + +signals: + void rowChanged(); + void parentModelChanged(); + +public: + enum { + MessageRole = Qt::DisplayRole, + ColorRole = Qt::UserRole, + }; + + AppOutputChildModel(QObject *parent = nullptr); + + int row() const; + void setRow(int row); + + QAbstractListModel *parentModel() const; + void setParentModel(QAbstractListModel *model); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QHash roleNames() const override; + QVariant data(const QModelIndex &index, int role = MessageRole) const override; + + void addMessage(int row, const QString &message, const QColor &color); + +private: + int m_row = 0; + AppOutputParentModel *m_parentModel = nullptr; +}; + +class AppOutputParentModel : public QAbstractListModel +{ + Q_OBJECT + QML_ELEMENT + + enum { RunRole = Qt::DisplayRole, ColorRole = Qt::UserRole }; + + Q_PROPERTY(QColor historyColor READ historyColor WRITE setHistoryColor NOTIFY colorChanged) + Q_PROPERTY(QColor messageColor READ messageColor WRITE setMessageColor NOTIFY colorChanged) + Q_PROPERTY(QColor errorColor READ errorColor WRITE setErrorColor NOTIFY colorChanged) + Q_PROPERTY(QColor debugColor READ debugColor WRITE setDebugColor NOTIFY colorChanged) + +signals: + void colorChanged(); + void modelChanged(); + void messageAdded(int row, const QString &message, const QColor &color); + +public: + struct Message + { + QString message; + QColor color; + }; + + struct Run + { + std::string timestamp; + std::vector messages; + }; + + AppOutputParentModel(QObject *parent = nullptr); + + Q_INVOKABLE void resetModel(); + + QColor historyColor() const; + void setHistoryColor(const QColor &color); + + QColor messageColor() const; + void setMessageColor(const QColor &color); + + QColor errorColor() const; + void setErrorColor(const QColor &color); + + QColor debugColor() const; + void setDebugColor(const QColor &color); + + int messageCount(int row) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QHash roleNames() const override; + + QVariant runData(int runIdx, int msgIdx, int role) const; + QVariant data(const QModelIndex &index, int role = RunRole) const override; + + Run *run(int row); + +private: + void setupRunControls(); + QColor colorFromFormat(Utils::OutputFormat format) const; + + QColor m_historyColor = Qt::gray; + QColor m_messageColor = Qt::green; + QColor m_errorColor = Qt::red; + QColor m_debugColor = Qt::magenta; + +#if 1 + std::vector m_runs = {}; +#else + std::vector m_runs = { + {"04.04.2024 10:30am", {{"line 1", "grey"}, {"line 2", "grey"}, {"line 3", "grey"}}}, + {"04.04.2024 11:30am", {{"line 4", "grey"}, {"line 5", "grey"}, {"line 6", "grey"}}}, + {"04.04.2024 12:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, + {"04.04.2024 13:40am", + {{"line 7", "grey"}, + {"line 8", "grey"}, + {"line 9", "grey"}, + {"line 7", "grey"}, + {"line 8", "grey"}, + {"line 9", "grey"}, + {"line 7", "grey"}, + {"line 8", "grey"}, + {"line 9", "grey"}, + {"line 7", "grey"}, + {"line 8", "grey"}, + {"line 9", "grey"}}}, + {"04.04.2024 14:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, + {"04.04.2024 15:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, + {"04.04.2024 16:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, + {"04.04.2024 17:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, + {"04.04.2024 18:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, + {"04.04.2024 19:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, + {"04.04.2024 20:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, + {"04.04.2024 21:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, + {"04.04.2024 22:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, + }; +#endif +}; diff --git a/src/plugins/qmldesigner/components/toolbar/messagemodel.cpp b/src/plugins/qmldesigner/components/toolbar/messagemodel.cpp new file mode 100644 index 00000000000..e0a2fa9b2d8 --- /dev/null +++ b/src/plugins/qmldesigner/components/toolbar/messagemodel.cpp @@ -0,0 +1,137 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +#include "messagemodel.h" + +#include +#include + +MessageModel::MessageModel(QObject *parent) + : QAbstractListModel(parent) +{ + setupTaskHub(); +} + +int MessageModel::errorCount() const +{ + int count = 0; + for (const auto &task : m_tasks) { + if (task.type == ProjectExplorer::Task::TaskType::Error) + count++; + } + return count; +} + +int MessageModel::warningCount() const +{ + int count = 0; + for (const auto &task : m_tasks) { + if (task.type == ProjectExplorer::Task::TaskType::Warning) + count++; + } + return count; +} + +void MessageModel::resetModel() +{ + auto *hub = &ProjectExplorer::taskHub(); + hub->clearTasks(); + + beginResetModel(); + m_tasks.clear(); + endResetModel(); + emit modelChanged(); +} + +void MessageModel::jumpToCode(const QVariant &index) +{ + bool ok = false; + if (int idx = index.toInt(&ok); ok) { + if (idx >= 0 && idx < static_cast(m_tasks.size())) { + // TODO: + // - Check why this does not jump to line/column + // - Only call this when sure that the task, file row etc are valid. + ProjectExplorer::Task task = m_tasks.at(idx); + const int column = task.column ? task.column - 1 : 0; + + Utils::Link link(task.file, task.line, column); + Core::EditorManager::openEditorAt(link, + {}, + Core::EditorManager::SwitchSplitIfAlreadyVisible); + } + } +} + +int MessageModel::rowCount(const QModelIndex &) const +{ + return m_tasks.size(); +} + +QHash MessageModel::roleNames() const +{ + QHash out; + out[MessageRole] = "message"; + out[FileNameRole] = "location"; + out[TypeRole] = "type"; + return out; +} + +QVariant MessageModel::data(const QModelIndex &index, int role) const +{ + if (index.isValid() && index.row() < rowCount()) { + int row = index.row(); + if (role == MessageRole) { + return m_tasks.at(row).description(); + } else if (role == FileNameRole) { + Utils::FilePath path = m_tasks.at(row).file; + return path.fileName(); + } else if (role == TypeRole) { + ProjectExplorer::Task::TaskType type = m_tasks.at(row).type; + if (type == ProjectExplorer::Task::TaskType::Error) + return "Error"; + else if (type == ProjectExplorer::Task::TaskType::Warning) + return "Warning"; + else + return "Unknown"; + } else { + qWarning() << Q_FUNC_INFO << "invalid role"; + } + } else { + qWarning() << Q_FUNC_INFO << "invalid index"; + } + return QVariant(); +} + +void MessageModel::setupTaskHub() +{ + auto *hub = &ProjectExplorer::taskHub(); + connect(hub, &ProjectExplorer::TaskHub::categoryAdded, this, &MessageModel::addCategory); + connect(hub, &ProjectExplorer::TaskHub::taskAdded, this, &MessageModel::addTask); + connect(hub, &ProjectExplorer::TaskHub::taskRemoved, this, &MessageModel::removeTask); +} + +void MessageModel::addCategory(const ProjectExplorer::TaskCategory &category) +{ + m_categories[category.id.uniqueIdentifier()] = category; +} + +void MessageModel::addTask(const ProjectExplorer::Task &task) +{ + int at = m_tasks.size(); + beginInsertRows(QModelIndex(), at, at); + m_tasks.push_back(task); + endInsertRows(); + emit modelChanged(); +} + +void MessageModel::removeTask(const ProjectExplorer::Task &task) +{ + for (int i = 0; i < static_cast(m_tasks.size()); i++) { + if (m_tasks.at(i) == task) { + beginRemoveRows(QModelIndex(), i, i); + m_tasks.erase(m_tasks.begin() + i); + endRemoveRows(); + emit modelChanged(); + return; + } + } +} diff --git a/src/plugins/qmldesigner/components/toolbar/messagemodel.h b/src/plugins/qmldesigner/components/toolbar/messagemodel.h new file mode 100644 index 00000000000..e6748910589 --- /dev/null +++ b/src/plugins/qmldesigner/components/toolbar/messagemodel.h @@ -0,0 +1,50 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#pragma once + +#include +#include + +#include +#include + +class MessageModel : public QAbstractListModel +{ + Q_OBJECT + QML_ELEMENT + QML_SINGLETON + + Q_PROPERTY(int errorCount READ errorCount NOTIFY modelChanged) + Q_PROPERTY(int warningCount READ warningCount NOTIFY modelChanged) + + enum { + TypeRole = Qt::DecorationRole, + MessageRole = Qt::DisplayRole, + FileNameRole = Qt::UserRole, + }; + +signals: + void modelChanged(); + +public: + MessageModel(QObject *parent = nullptr); + + int errorCount() const; + int warningCount() const; + Q_INVOKABLE void resetModel(); + Q_INVOKABLE void jumpToCode(const QVariant &index); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QHash roleNames() const override; + QVariant data(const QModelIndex &index, int role = MessageRole) const override; + +private: + void setupTaskHub(); + void addCategory(const ProjectExplorer::TaskCategory &category); + void addTask(const ProjectExplorer::Task &task); + void removeTask(const ProjectExplorer::Task &task); + + std::vector m_tasks = {}; + std::unordered_map m_categories = {}; +}; diff --git a/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp b/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp index 47465ebe7bf..0a85e860bdd 100644 --- a/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp +++ b/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp @@ -3,6 +3,9 @@ #include "toolbarbackend.h" +#include "messagemodel.h" +#include "appoutputmodel.h" + #include #include #include @@ -407,6 +410,10 @@ void ToolBarBackend::registerDeclarativeType() qmlRegisterType("ToolBar", 1, 0, "ActionSubscriber"); qmlRegisterType("ToolBar", 1, 0, "CrumbleBarModel"); qmlRegisterType("ToolBar", 1, 0, "WorkspaceModel"); + + qmlRegisterType("OutputPane", 1, 0, "MessageModel"); + qmlRegisterType("OutputPane", 1, 0, "AppOutputParentModel"); + qmlRegisterType("OutputPane", 1, 0, "AppOutputChildModel"); } void ToolBarBackend::triggerModeChange() From 87d60e6bc3f8eb4ab021ec3890c394a5a5919bd8 Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Wed, 21 Aug 2024 08:20:09 +0300 Subject: [PATCH 063/193] Doc: Add panning shortcut key MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I00e1e013c3cd14bbc76c4167a541388cd07e4e33 Reviewed-by: Mahmoud Badri Reviewed-by: Teea Põldsam --- .../qtquick3d-editor/qtdesignstudio-3d-editor.qdoc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc index 00f513e7fcf..9bf1320bffe 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc @@ -89,11 +89,14 @@ camera: \list - \li To pan, press \key Alt (or \key Option on \macos) and use the - wheel button to drag anywhere in the \uicontrol 3D view to - slide the view around. Alternatively, press and hold \key - {right mouse button} and \key {left mouse button} and drag - anywhere in the view to pan. + \li To pan, do one of the following and drag anywhere in the view to pan: + \list + \li Press and hold \key Alt (or \key Option on \macos) and + \key {middle mouse button}. + \li Press and hold \key {right mouse button}, and then press and hold + \key {left mouse button}. + \li Press and hold \key Shift and \key {left mouse button}. + \endlist \li To orbit, press \key Alt and and drag anywhere in the \uicontrol 3D view to rotate the view. \li To zoom, use the mouse wheel or press \key Alt and right-click From 46ff94c6cc26a49d83543b101d5cd439d21bafd7 Mon Sep 17 00:00:00 2001 From: Knud Dollereder Date: Wed, 21 Aug 2024 11:48:17 +0200 Subject: [PATCH 064/193] Fix linux build and minor cleanup Change-Id: If5e10841e387a42a4a7c16eb3cad80e6a41d5688 Reviewed-by: Marco Bubke --- .../components/toolbar/appoutputmodel.cpp | 2 ++ .../components/toolbar/appoutputmodel.h | 32 ++----------------- 2 files changed, 4 insertions(+), 30 deletions(-) diff --git a/src/plugins/qmldesigner/components/toolbar/appoutputmodel.cpp b/src/plugins/qmldesigner/components/toolbar/appoutputmodel.cpp index 5b5de5e78af..86a47ba2d48 100644 --- a/src/plugins/qmldesigner/components/toolbar/appoutputmodel.cpp +++ b/src/plugins/qmldesigner/components/toolbar/appoutputmodel.cpp @@ -5,6 +5,8 @@ #include #include +#include + AppOutputChildModel::AppOutputChildModel(QObject *parent) : QAbstractListModel(parent) {} diff --git a/src/plugins/qmldesigner/components/toolbar/appoutputmodel.h b/src/plugins/qmldesigner/components/toolbar/appoutputmodel.h index 011e4b26ee4..08772abfd17 100644 --- a/src/plugins/qmldesigner/components/toolbar/appoutputmodel.h +++ b/src/plugins/qmldesigner/components/toolbar/appoutputmodel.h @@ -8,6 +8,8 @@ #include +#include + class AppOutputParentModel; class AppOutputChildModel : public QAbstractListModel @@ -112,35 +114,5 @@ private: QColor m_errorColor = Qt::red; QColor m_debugColor = Qt::magenta; -#if 1 std::vector m_runs = {}; -#else - std::vector m_runs = { - {"04.04.2024 10:30am", {{"line 1", "grey"}, {"line 2", "grey"}, {"line 3", "grey"}}}, - {"04.04.2024 11:30am", {{"line 4", "grey"}, {"line 5", "grey"}, {"line 6", "grey"}}}, - {"04.04.2024 12:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, - {"04.04.2024 13:40am", - {{"line 7", "grey"}, - {"line 8", "grey"}, - {"line 9", "grey"}, - {"line 7", "grey"}, - {"line 8", "grey"}, - {"line 9", "grey"}, - {"line 7", "grey"}, - {"line 8", "grey"}, - {"line 9", "grey"}, - {"line 7", "grey"}, - {"line 8", "grey"}, - {"line 9", "grey"}}}, - {"04.04.2024 14:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, - {"04.04.2024 15:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, - {"04.04.2024 16:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, - {"04.04.2024 17:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, - {"04.04.2024 18:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, - {"04.04.2024 19:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, - {"04.04.2024 20:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, - {"04.04.2024 21:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, - {"04.04.2024 22:30am", {{"line 7", "grey"}, {"line 8", "grey"}, {"line 9", "grey"}}}, - }; -#endif }; From 7fbc2136f9bef61b6906bd2b9a91a2d2a4a5869f Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 14 Aug 2024 18:41:28 +0200 Subject: [PATCH 065/193] Sqlite: Update to 3.46.1 Change-Id: Iff2c201340f6ba4cd97a0b5c15c90f3bd887dfc3 Reviewed-by: Thomas Hartmann --- src/libs/3rdparty/sqlite/sqlite3.c | 154 +++++++++++++++-------------- src/libs/3rdparty/sqlite/sqlite3.h | 6 +- 2 files changed, 83 insertions(+), 77 deletions(-) diff --git a/src/libs/3rdparty/sqlite/sqlite3.c b/src/libs/3rdparty/sqlite/sqlite3.c index eaa24a13107..946815f13ec 100644 --- a/src/libs/3rdparty/sqlite/sqlite3.c +++ b/src/libs/3rdparty/sqlite/sqlite3.c @@ -1,6 +1,6 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.46.0. By combining all the individual C code files into this +** version 3.46.1. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -18,7 +18,7 @@ ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in -** 96c92aba00c8375bc32fafcdf12429c58bd8. +** c9c2ab54ba1f5f46360f1b4f35d849cd3f08. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -459,9 +459,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.46.0" -#define SQLITE_VERSION_NUMBER 3046000 -#define SQLITE_SOURCE_ID "2024-05-23 13:25:27 96c92aba00c8375bc32fafcdf12429c58bd8aabfcadab6683e35bbb9cdebf19e" +#define SQLITE_VERSION "3.46.1" +#define SQLITE_VERSION_NUMBER 3046001 +#define SQLITE_SOURCE_ID "2024-08-13 09:16:08 c9c2ab54ba1f5f46360f1b4f35d849cd3f080e6fc2b6c60e91b16c63f69a1e33" /* ** CAPI3REF: Run-Time Library Version Numbers @@ -19361,7 +19361,7 @@ struct SrcList { #define WHERE_AGG_DISTINCT 0x0400 /* Query is "SELECT agg(DISTINCT ...)" */ #define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ #define WHERE_RIGHT_JOIN 0x1000 /* Processing a RIGHT JOIN */ - /* 0x2000 not currently used */ +#define WHERE_KEEP_ALL_JOINS 0x2000 /* Do not do the omit-noop-join opt */ #define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ /* 0x8000 not currently used */ @@ -90173,7 +90173,8 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff assert( iVar>0 ); if( v ){ Mem *pMem = &v->aVar[iVar-1]; - assert( (v->db->flags & SQLITE_EnableQPSG)==0 ); + assert( (v->db->flags & SQLITE_EnableQPSG)==0 + || (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 ); if( 0==(pMem->flags & MEM_Null) ){ sqlite3_value *pRet = sqlite3ValueNew(v->db); if( pRet ){ @@ -90193,7 +90194,8 @@ SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff */ SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ assert( iVar>0 ); - assert( (v->db->flags & SQLITE_EnableQPSG)==0 ); + assert( (v->db->flags & SQLITE_EnableQPSG)==0 + || (v->db->mDbFlags & DBFLAG_InternalFunc)!=0 ); if( iVar>=32 ){ v->expmask |= 0x80000000; }else{ @@ -106950,7 +106952,7 @@ static void extendFJMatch( static SQLITE_NOINLINE int isValidSchemaTableName( const char *zTab, /* Name as it appears in the SQL */ Table *pTab, /* The schema table we are trying to match */ - Schema *pSchema /* non-NULL if a database qualifier is present */ + const char *zDb /* non-NULL if a database qualifier is present */ ){ const char *zLegacy; assert( pTab!=0 ); @@ -106961,7 +106963,7 @@ static SQLITE_NOINLINE int isValidSchemaTableName( if( sqlite3StrICmp(zTab+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){ return 1; } - if( pSchema==0 ) return 0; + if( zDb==0 ) return 0; if( sqlite3StrICmp(zTab+7, &LEGACY_SCHEMA_TABLE[7])==0 ) return 1; if( sqlite3StrICmp(zTab+7, &PREFERRED_SCHEMA_TABLE[7])==0 ) return 1; }else{ @@ -107144,7 +107146,7 @@ static int lookupName( } }else if( sqlite3StrICmp(zTab, pTab->zName)!=0 ){ if( pTab->tnum!=1 ) continue; - if( !isValidSchemaTableName(zTab, pTab, pSchema) ) continue; + if( !isValidSchemaTableName(zTab, pTab, zDb) ) continue; } assert( ExprUseYTab(pExpr) ); if( IN_RENAME_OBJECT && pItem->zAlias ){ @@ -108876,6 +108878,9 @@ SQLITE_PRIVATE int sqlite3ResolveExprNames( ** Resolve all names for all expression in an expression list. This is ** just like sqlite3ResolveExprNames() except that it works for an expression ** list rather than a single expression. +** +** The return value is SQLITE_OK (0) for success or SQLITE_ERROR (1) for a +** failure. */ SQLITE_PRIVATE int sqlite3ResolveExprListNames( NameContext *pNC, /* Namespace to resolve expressions in. */ @@ -108884,7 +108889,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames( int i; int savedHasAgg = 0; Walker w; - if( pList==0 ) return WRC_Continue; + if( pList==0 ) return SQLITE_OK; w.pParse = pNC->pParse; w.xExprCallback = resolveExprStep; w.xSelectCallback = resolveSelectStep; @@ -108898,7 +108903,7 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames( #if SQLITE_MAX_EXPR_DEPTH>0 w.pParse->nHeight += pExpr->nHeight; if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){ - return WRC_Abort; + return SQLITE_ERROR; } #endif sqlite3WalkExprNN(&w, pExpr); @@ -108915,10 +108920,10 @@ SQLITE_PRIVATE int sqlite3ResolveExprListNames( (NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin|NC_OrderAgg); } - if( w.pParse->nErr>0 ) return WRC_Abort; + if( w.pParse->nErr>0 ) return SQLITE_ERROR; } pNC->ncFlags |= savedHasAgg; - return WRC_Continue; + return SQLITE_OK; } /* @@ -117457,7 +117462,7 @@ static int renameResolveTrigger(Parse *pParse){ /* ALWAYS() because if the table of the trigger does not exist, the ** error would have been hit before this point */ if( ALWAYS(pParse->pTriggerTab) ){ - rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab); + rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab)!=0; } /* Resolve symbols in WHEN clause */ @@ -124426,8 +124431,9 @@ create_view_fail: #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) /* ** The Table structure pTable is really a VIEW. Fill in the names of -** the columns of the view in the pTable structure. Return the number -** of errors. If an error is seen leave an error message in pParse->zErrMsg. +** the columns of the view in the pTable structure. Return non-zero if +** there are errors. If an error is seen an error message is left +** in pParse->zErrMsg. */ static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){ Table *pSelTab; /* A fake table from which we get the result set */ @@ -124550,7 +124556,7 @@ static SQLITE_NOINLINE int viewGetColumnNames(Parse *pParse, Table *pTable){ sqlite3DeleteColumnNames(db, pTable); } #endif /* SQLITE_OMIT_VIEW */ - return nErr; + return nErr + pParse->nErr; } SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ assert( pTable!=0 ); @@ -130848,6 +130854,8 @@ static void groupConcatValue(sqlite3_context *context){ sqlite3_result_error_toobig(context); }else if( pAccum->accError==SQLITE_NOMEM ){ sqlite3_result_error_nomem(context); + }else if( pGCC->nAccum>0 && pAccum->nChar==0 ){ + sqlite3_result_text(context, "", 1, SQLITE_STATIC); }else{ const char *zText = sqlite3_str_value(pAccum); sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT); @@ -133602,6 +133610,7 @@ SQLITE_PRIVATE Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList pRet->pSrc->nSrc = 1; pRet->pPrior = pLeft->pPrior; pRet->op = pLeft->op; + if( pRet->pPrior ) pRet->selFlags |= SF_Values; pLeft->pPrior = 0; pLeft->op = TK_SELECT; assert( pLeft->pNext==0 ); @@ -166067,7 +166076,9 @@ static int whereLoopAddBtree( " according to whereIsCoveringIndex()\n", pProbe->zName)); } } - }else if( m==0 ){ + }else if( m==0 + && (HasRowid(pTab) || pWInfo->pSelect!=0 || sqlite3FaultSim(700)) + ){ WHERETRACE(0x200, ("-> %s a covering index according to bitmasks\n", pProbe->zName, m==0 ? "is" : "is not")); @@ -167956,6 +167967,10 @@ static void showAllWhereLoops(WhereInfo *pWInfo, WhereClause *pWC){ ** the right-most table of a subquery that was flattened into the ** main query and that subquery was the right-hand operand of an ** inner join that held an ON or USING clause. +** 6) The ORDER BY clause has 63 or fewer terms +** 7) The omit-noop-join optimization is enabled. +** +** Items (1), (6), and (7) are checked by the caller. ** ** For example, given: ** @@ -168369,6 +168384,7 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( if( pOrderBy && pOrderBy->nExpr>=BMS ){ pOrderBy = 0; wctrlFlags &= ~WHERE_WANT_DISTINCT; + wctrlFlags |= WHERE_KEEP_ALL_JOINS; /* Disable omit-noop-join opt */ } /* The number of tables in the FROM clause is limited by the number of @@ -168669,10 +168685,10 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( ** in-line sqlite3WhereCodeOneLoopStart() for performance reasons. */ notReady = ~(Bitmask)0; - if( pWInfo->nLevel>=2 - && pResultSet!=0 /* these two combine to guarantee */ - && 0==(wctrlFlags & WHERE_AGG_DISTINCT) /* condition (1) above */ - && OptimizationEnabled(db, SQLITE_OmitNoopJoin) + if( pWInfo->nLevel>=2 /* Must be a join, or this opt8n is pointless */ + && pResultSet!=0 /* Condition (1) */ + && 0==(wctrlFlags & (WHERE_AGG_DISTINCT|WHERE_KEEP_ALL_JOINS)) /* (1),(6) */ + && OptimizationEnabled(db, SQLITE_OmitNoopJoin) /* (7) */ ){ notReady = whereOmitNoopJoin(pWInfo, notReady); nTabList = pWInfo->nLevel; @@ -168992,26 +169008,6 @@ whereBeginError: } #endif -#ifdef SQLITE_DEBUG -/* -** Return true if cursor iCur is opened by instruction k of the -** bytecode. Used inside of assert() only. -*/ -static int cursorIsOpen(Vdbe *v, int iCur, int k){ - while( k>=0 ){ - VdbeOp *pOp = sqlite3VdbeGetOp(v,k--); - if( pOp->p1!=iCur ) continue; - if( pOp->opcode==OP_Close ) return 0; - if( pOp->opcode==OP_OpenRead ) return 1; - if( pOp->opcode==OP_OpenWrite ) return 1; - if( pOp->opcode==OP_OpenDup ) return 1; - if( pOp->opcode==OP_OpenAutoindex ) return 1; - if( pOp->opcode==OP_OpenEphemeral ) return 1; - } - return 0; -} -#endif /* SQLITE_DEBUG */ - /* ** Generate the end of the WHERE loop. See comments on ** sqlite3WhereBegin() for additional information. @@ -169311,16 +169307,10 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ ** reference. Verify that this is harmless - that the ** table being referenced really is open. */ -#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC - assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 - || cursorIsOpen(v,pOp->p1,k) - || pOp->opcode==OP_Offset - ); -#else - assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 - || cursorIsOpen(v,pOp->p1,k) - ); -#endif + if( pLoop->wsFlags & WHERE_IDX_ONLY ){ + sqlite3ErrorMsg(pParse, "internal query planner error"); + pParse->rc = SQLITE_INTERNAL; + } } }else if( pOp->opcode==OP_Rowid ){ pOp->p1 = pLevel->iIdxCur; @@ -172591,9 +172581,9 @@ static void updateDeleteLimitError( break; } } - if( (p->selFlags & SF_MultiValue)==0 && - (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 && - cnt>mxSelect + if( (p->selFlags & (SF_MultiValue|SF_Values))==0 + && (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 + && cnt>mxSelect ){ sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); } @@ -237004,7 +236994,11 @@ static int sqlite3Fts5ExprNew( } sqlite3_free(sParse.apPhrase); - *pzErr = sParse.zErr; + if( 0==*pzErr ){ + *pzErr = sParse.zErr; + }else{ + sqlite3_free(sParse.zErr); + } return sParse.rc; } @@ -239132,6 +239126,7 @@ static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( assert( pRight->eType==FTS5_STRING || pRight->eType==FTS5_TERM || pRight->eType==FTS5_EOF + || (pRight->eType==FTS5_AND && pParse->bPhraseToAnd) ); if( pLeft->eType==FTS5_AND ){ @@ -251299,6 +251294,7 @@ static int fts5UpdateMethod( rc = SQLITE_ERROR; }else{ rc = fts5SpecialDelete(pTab, apVal); + bUpdateOrDelete = 1; } }else{ rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]); @@ -252473,14 +252469,16 @@ static int sqlite3Fts5GetTokenizer( if( pMod==0 ){ assert( nArg>0 ); rc = SQLITE_ERROR; - *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); + if( pzErr ) *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); }else{ rc = pMod->x.xCreate( pMod->pUserData, (azArg?&azArg[1]:0), (nArg?nArg-1:0), &pConfig->pTok ); pConfig->pTokApi = &pMod->x; if( rc!=SQLITE_OK ){ - if( pzErr ) *pzErr = sqlite3_mprintf("error in tokenizer constructor"); + if( pzErr && rc!=SQLITE_NOMEM ){ + *pzErr = sqlite3_mprintf("error in tokenizer constructor"); + } }else{ pConfig->ePattern = sqlite3Fts5TokenizerPattern( pMod->x.xCreate, pConfig->pTok @@ -252539,7 +252537,7 @@ static void fts5SourceIdFunc( ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - sqlite3_result_text(pCtx, "fts5: 2024-05-23 13:25:27 96c92aba00c8375bc32fafcdf12429c58bd8aabfcadab6683e35bbb9cdebf19e", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2024-08-13 09:16:08 c9c2ab54ba1f5f46360f1b4f35d849cd3f080e6fc2b6c60e91b16c63f69a1e33", -1, SQLITE_TRANSIENT); } /* @@ -252574,17 +252572,23 @@ static int fts5IntegrityMethod( assert( pzErr!=0 && *pzErr==0 ); UNUSED_PARAM(isQuick); + assert( pTab->p.pConfig->pzErrmsg==0 ); + pTab->p.pConfig->pzErrmsg = pzErr; rc = sqlite3Fts5StorageIntegrity(pTab->pStorage, 0); - if( (rc&0xff)==SQLITE_CORRUPT ){ - *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s", - zSchema, zTabname); - rc = (*pzErr) ? SQLITE_OK : SQLITE_NOMEM; - }else if( rc!=SQLITE_OK ){ - *pzErr = sqlite3_mprintf("unable to validate the inverted index for" - " FTS5 table %s.%s: %s", - zSchema, zTabname, sqlite3_errstr(rc)); + if( *pzErr==0 && rc!=SQLITE_OK ){ + if( (rc&0xff)==SQLITE_CORRUPT ){ + *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s", + zSchema, zTabname); + rc = (*pzErr) ? SQLITE_OK : SQLITE_NOMEM; + }else{ + *pzErr = sqlite3_mprintf("unable to validate the inverted index for" + " FTS5 table %s.%s: %s", + zSchema, zTabname, sqlite3_errstr(rc)); + } } + sqlite3Fts5IndexCloseReader(pTab->p.pIndex); + pTab->p.pConfig->pzErrmsg = 0; return rc; } @@ -254018,7 +254022,7 @@ static int fts5AsciiCreate( int i; memset(p, 0, sizeof(AsciiTokenizer)); memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); - for(i=0; rc==SQLITE_OK && ibFold = 1; pNew->iFoldParam = 0; - for(i=0; rc==SQLITE_OK && iiFoldParam!=0 && pNew->bFold==0 ){ rc = SQLITE_ERROR; diff --git a/src/libs/3rdparty/sqlite/sqlite3.h b/src/libs/3rdparty/sqlite/sqlite3.h index 57df8dcf202..f64ca017278 100644 --- a/src/libs/3rdparty/sqlite/sqlite3.h +++ b/src/libs/3rdparty/sqlite/sqlite3.h @@ -146,9 +146,9 @@ extern "C" { ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ -#define SQLITE_VERSION "3.46.0" -#define SQLITE_VERSION_NUMBER 3046000 -#define SQLITE_SOURCE_ID "2024-05-23 13:25:27 96c92aba00c8375bc32fafcdf12429c58bd8aabfcadab6683e35bbb9cdebf19e" +#define SQLITE_VERSION "3.46.1" +#define SQLITE_VERSION_NUMBER 3046001 +#define SQLITE_SOURCE_ID "2024-08-13 09:16:08 c9c2ab54ba1f5f46360f1b4f35d849cd3f080e6fc2b6c60e91b16c63f69a1e33" /* ** CAPI3REF: Run-Time Library Version Numbers From d8a7d54fd80cde8e61cded692739ee4a6ae4390f Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Sun, 18 Aug 2024 16:11:59 +0200 Subject: [PATCH 066/193] QmlDesigner: Use set_has_common_element Use an explicit algorithm to show the intent better, that at least one element between the both sets is shared. Change-Id: Idc528f3404406cebbc9551f60604f624e5d022bd Reviewed-by: Thomas Hartmann --- src/libs/utils/set_algorithm.h | 52 +++++++++++++++++++ .../propertycomponentgenerator.cpp | 19 +------ 2 files changed, 53 insertions(+), 18 deletions(-) diff --git a/src/libs/utils/set_algorithm.h b/src/libs/utils/set_algorithm.h index d66a9cae61d..0d220bcc46d 100644 --- a/src/libs/utils/set_algorithm.h +++ b/src/libs/utils/set_algorithm.h @@ -242,4 +242,56 @@ struct set_greedy_difference_functor inline constexpr set_greedy_difference_functor set_greedy_difference{}; +struct set_has_common_element_functor +{ + template Sentinel1, + std::input_iterator Iterator2, + std::sentinel_for Sentinel2, + typename Comp = std::ranges::less, + typename Projection1 = std::identity, + typename Projection2 = std::identity> + requires callmergeable + constexpr bool operator()(Iterator1 first1, + Sentinel1 last1, + Iterator2 first2, + Sentinel2 last2, + Comp comp = {}, + Projection1 proj1 = {}, + Projection2 proj2 = {}) const + { + while (first1 != last1 && first2 != last2) + if (std::invoke(comp, std::invoke(proj1, *first1), std::invoke(proj2, *first2))) + ++first1; + else if (std::invoke(comp, std::invoke(proj2, *first2), std::invoke(proj1, *first1))) + ++first2; + else + return true; + + return false; + } + + template + requires callmergeable, std::ranges::iterator_t, Comp, Projection1, Projection2> + constexpr bool operator()(Range1 &&range1, + Range2 &&range2, + Comp comp = {}, + Projection1 proj1 = {}, + Projection2 proj2 = {}) const + { + return (*this)(std::ranges::begin(range1), + std::ranges::end(range1), + std::ranges::begin(range2), + std::ranges::end(range2), + std::move(comp), + std::move(proj1), + std::move(proj2)); + } +}; + +inline constexpr set_has_common_element_functor set_has_common_element{}; } // namespace Utils diff --git a/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp b/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp index ce6fd7b4da9..3e28e217479 100644 --- a/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp +++ b/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp @@ -270,23 +270,6 @@ void PropertyComponentGenerator::setModel(Model *model) m_model = model; } -namespace { - -bool insect(const TypeIds &first, const TypeIds &second) -{ - bool intersecting = false; - - std::set_intersection(first.begin(), - first.end(), - second.begin(), - second.end(), - Utils::make_iterator([&](const auto &) { intersecting = true; })); - - return intersecting; -} - -} // namespace - void PropertyComponentGenerator::setEntries(QmlJS::SimpleReaderNode::Ptr templateConfiguration, Model *model, const QString &propertyTemplatesPath) @@ -303,7 +286,7 @@ void PropertyComponentGenerator::setEntries(QmlJS::SimpleReaderNode::Ptr templat void PropertyComponentGenerator::refreshMetaInfos(const TypeIds &deletedTypeIds) { - if (!insect(deletedTypeIds, m_entryTypeIds) && !m_hasInvalidTemplates) + if (!Utils::set_has_common_element(deletedTypeIds, m_entryTypeIds) && !m_hasInvalidTemplates) return; setEntries(m_templateConfiguration, m_model, m_propertyTemplatesPath); From 55f91ffe32709293e51f94e683b79326177efbcd Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Sun, 18 Aug 2024 16:12:50 +0200 Subject: [PATCH 067/193] Utils:: Remove useless constraint It is already contraint by the template parameter. Change-Id: I11e1e276bdb88adbe2ecec41cdf6f1c5ef56b69e Reviewed-by: Thomas Hartmann --- src/libs/utils/set_algorithm.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libs/utils/set_algorithm.h b/src/libs/utils/set_algorithm.h index 0d220bcc46d..4c595717050 100644 --- a/src/libs/utils/set_algorithm.h +++ b/src/libs/utils/set_algorithm.h @@ -59,10 +59,9 @@ template -concept callmergeable = std::input_iterator && std::input_iterator - && std::indirect_strict_weak_order, - std::projected>; +concept callmergeable = std::indirect_strict_weak_order, + std::projected>; template using set_intersection_result = std::ranges::set_intersection_result; From 55975fb3a5c41dc70ad250e579f9beaa3fe6e2f2 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Sun, 18 Aug 2024 01:40:19 +0200 Subject: [PATCH 068/193] QmlDesigner: Add some experimantal predicates We can later move them to Utils, if needed. Change-Id: I4e9608e76466e7f2e4acc8fee401ccac3e8bae60 Reviewed-by: Thomas Hartmann --- src/plugins/qmldesigner/CMakeLists.txt | 1 + .../designercoreutils/predicate.h | 49 +++++++++++++++++++ .../qmldesigner/designercore/model/model.cpp | 9 +--- .../projectstorage/projectstorage.cpp | 6 +-- 4 files changed, 53 insertions(+), 12 deletions(-) create mode 100644 src/plugins/qmldesigner/designercore/designercoreutils/predicate.h diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index a2560347716..a2e9fc943a7 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -110,6 +110,7 @@ extend_qtc_library(QmlDesignerCore skipiterator.h stylesheetmerger.cpp stylesheetmerger.h uniquename.cpp uniquename.h + predicate.h ) extend_qtc_library(QmlDesignerCore diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/predicate.h b/src/plugins/qmldesigner/designercore/designercoreutils/predicate.h new file mode 100644 index 00000000000..2c45ad51525 --- /dev/null +++ b/src/plugins/qmldesigner/designercore/designercoreutils/predicate.h @@ -0,0 +1,49 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +namespace QmlDesigner { + +template +auto compare_to(auto compare, Value &&value, Projection projection = {}) +{ + return [compare = std::move(compare), + projection = std::move(projection), + compareValue = std::forward(value)](Value2 &&value) { + return std::invoke(compare, compareValue, std::invoke(projection, std::forward(value))); + }; +} + +template +auto is_equal_to(Value &&value, Projection projection = {}) +{ + return compare_to(std::ranges::equal_to{}, std::forward(value), std::move(projection)); +} + +template +auto compare_with(auto compare, Projection1 projection1 = {}, Projection1 projection2 = {}) +{ + return [compare = std::move(compare), + projection1 = std::move(projection1), + projection2 = std::move(projection2)](Value1 &&value1, + Value2 &&value2) { + return std::invoke(compare, + std::invoke(projection1, std::forward(value1)), + std::invoke(projection2, std::forward(value2))); + }; +} + +template +auto logical(auto compare, Projection projection = {}) +{ + return [=](auto &&value) { + return std::invoke(compare, std::invoke(projection, std::forward(value))); + }; +} + +template +auto is_null(Projection projection = {}) +{ + return logical(std::logical_not{}, projection); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index ef96f8a6ef0..e02e02befbe 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -33,6 +33,7 @@ #include "signalhandlerproperty.h" #include "variantproperty.h" +#include #include #include @@ -67,14 +68,6 @@ Components that want to be informed about changes in the model can register a su \see QmlDesigner::ModelNode, QmlDesigner::AbstractProperty, QmlDesigner::AbstractView */ -namespace { - -auto is_equal_to(auto &&value) -{ - return std::bind_front(std::ranges::equal_to{}, value); -} -} // namespace - namespace QmlDesigner { using NanotraceHR::keyValue; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp index 752d3c0db89..2a92487cbc9 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp @@ -3,6 +3,7 @@ #include "projectstorage.h" +#include #include namespace QmlDesigner { @@ -2337,10 +2338,7 @@ void ProjectStorage::updateTypeIdInTypeAnnotations(Storage::Synchronization::Typ annotation.typeName); } - auto [begin, end] = std::ranges::remove_if(typeAnnotations, - std::logical_not{}, - &TypeAnnotation::typeId); - typeAnnotations.erase(begin, end); + std::erase_if(typeAnnotations, is_null(&TypeAnnotation::typeId)); } void ProjectStorage::synchronizeTypeAnnotations(Storage::Synchronization::TypeAnnotations &typeAnnotations, From 5f6d8f84bf9ef4c48e2c67b9a6a5eb22da706134 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 19 Aug 2024 13:07:09 +0200 Subject: [PATCH 069/193] QmlDesigner: Use three way comparison instead of minus operator The minus operator was always a hack. The <=> operator make it much more clear that we need a three way comparison. Change-Id: Ie496d08a0d6a28951241459c2252b16ec4b28151 Reviewed-by: Thomas Hartmann --- .../projectstorage/projectstorage.cpp | 86 +++++++------------ 1 file changed, 31 insertions(+), 55 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp index 2a92487cbc9..1a46a30c1f2 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp @@ -6,6 +6,8 @@ #include #include +#include + namespace QmlDesigner { using Storage::Synchronization::EnumerationDeclaration; @@ -2349,7 +2351,7 @@ void ProjectStorage::synchronizeTypeAnnotations(Storage::Synchronization::TypeAn updateTypeIdInTypeAnnotations(typeAnnotations); - auto compareKey = [](auto &&first, auto &&second) { return first.typeId - second.typeId; }; + auto compareKey = [](auto &&first, auto &&second) { return first.typeId <=> second.typeId; }; std::ranges::sort(typeAnnotations, std::ranges::less{}, &TypeAnnotation::typeId); @@ -2497,11 +2499,8 @@ void ProjectStorage::synchronizeDirectoryInfos(Storage::Synchronization::Directo NanotraceHR::Tracer tracer{"synchronize directory infos"_t, projectStorageCategory()}; auto compareKey = [](auto &&first, auto &&second) { - auto directorySourceIdDifference = first.directorySourceId - second.directorySourceId; - if (directorySourceIdDifference != 0) - return directorySourceIdDifference; - - return first.sourceId - second.sourceId; + return std::tie(first.directorySourceId, first.sourceId) + <=> std::tie(second.directorySourceId, second.sourceId); }; std::ranges::sort(directoryInfos, [&](auto &&first, auto &&second) { @@ -2567,7 +2566,7 @@ void ProjectStorage::synchronizeFileStatuses(FileStatuses &fileStatuses, { NanotraceHR::Tracer tracer{"synchronize file statuses"_t, projectStorageCategory()}; - auto compareKey = [](auto &&first, auto &&second) { return first.sourceId - second.sourceId; }; + auto compareKey = [](auto &&first, auto &&second) { return first.sourceId <=> second.sourceId; }; std::ranges::sort(fileStatuses, std::ranges::less{}, &FileStatus::sourceId); @@ -2663,12 +2662,9 @@ void ProjectStorage::synchromizeModuleExportedImports( toIntegers(updatedModuleIds)); auto compareKey = [](const Storage::Synchronization::ModuleExportedImportView &view, - const Storage::Synchronization::ModuleExportedImport &import) -> long long { - auto moduleIdDifference = view.moduleId - import.moduleId; - if (moduleIdDifference != 0) - return moduleIdDifference; - - return view.exportedModuleId - import.exportedModuleId; + const Storage::Synchronization::ModuleExportedImport &import) { + return std::tie(view.moduleId, view.exportedModuleId) + <=> std::tie(import.moduleId, import.exportedModuleId); }; auto insert = [&](const Storage::Synchronization::ModuleExportedImport &import) { @@ -3253,20 +3249,9 @@ void ProjectStorage::synchronizeExportedTypes(const TypeIds &updatedTypeIds, .range(toIntegers(updatedTypeIds)); auto compareKey = [](const Storage::Synchronization::ExportedTypeView &view, - const Storage::Synchronization::ExportedType &type) -> long long { - auto moduleIdDifference = view.moduleId - type.moduleId; - if (moduleIdDifference != 0) - return moduleIdDifference; - - auto nameDifference = Sqlite::compare(view.name, type.name); - if (nameDifference != 0) - return nameDifference; - - auto versionDifference = view.version.major.value - type.version.major.value; - if (versionDifference != 0) - return versionDifference; - - return view.version.minor.value - type.version.minor.value; + const Storage::Synchronization::ExportedType &type) { + return std::tie(view.moduleId, view.name, view.version.major.value, view.version.minor.value) + <=> std::tie(type.moduleId, type.name, type.version.major.value, type.version.minor.value); }; auto insert = [&](const Storage::Synchronization::ExportedType &type) { @@ -3569,7 +3554,7 @@ void ProjectStorage::synchronizePropertyDeclarations( auto compareKey = [](const Storage::Synchronization::PropertyDeclarationView &view, const Storage::Synchronization::PropertyDeclaration &value) { - return Sqlite::compare(view.name, value.name); + return view.name <=> value.name; }; auto insert = [&](const Storage::Synchronization::PropertyDeclaration &value) { @@ -3640,7 +3625,7 @@ void ProjectStorage::resetRemovedAliasPropertyDeclarationsToNull( auto compareKey = [](const AliasPropertyDeclarationView &view, const Storage::Synchronization::PropertyDeclaration &value) { - return Sqlite::compare(view.name, value.name); + return view.name <=> value.name; }; auto insert = [&](const Storage::Synchronization::PropertyDeclaration &) {}; @@ -3805,20 +3790,12 @@ void ProjectStorage::synchronizeDocumentImports(Storage::Imports &imports, importKind); auto compareKey = [](const Storage::Synchronization::ImportView &view, - const Storage::Import &import) -> long long { - auto sourceIdDifference = view.sourceId - import.sourceId; - if (sourceIdDifference != 0) - return sourceIdDifference; - - auto moduleIdDifference = view.moduleId - import.moduleId; - if (moduleIdDifference != 0) - return moduleIdDifference; - - auto versionDifference = view.version.major.value - import.version.major.value; - if (versionDifference != 0) - return versionDifference; - - return view.version.minor.value - import.version.minor.value; + const Storage::Import &import) { + return std::tie(view.sourceId, view.moduleId, view.version.major.value, view.version.minor.value) + <=> std::tie(import.sourceId, + import.moduleId, + import.version.major.value, + import.version.minor.value); }; auto insert = [&](const Storage::Import &import) { @@ -3958,9 +3935,8 @@ void ProjectStorage::synchronizePropertyEditorPaths(Storage::Synchronization::Pr auto range = s->selectPropertyEditorPathsForForSourceIdsStatement.range( toIntegers(updatedPropertyEditorQmlPathsSourceIds)); - auto compareKey = [](const PropertyEditorQmlPathView &view, - const PropertyEditorQmlPath &value) -> long long { - return view.typeId - value.typeId; + auto compareKey = [](const PropertyEditorQmlPathView &view, const PropertyEditorQmlPath &value) { + return view.typeId <=> value.typeId; }; auto insert = [&](const PropertyEditorQmlPath &path) { @@ -4035,13 +4011,13 @@ void ProjectStorage::synchronizeFunctionDeclarations( auto compareKey = [](const Storage::Synchronization::FunctionDeclarationView &view, const Storage::Synchronization::FunctionDeclaration &value) { - auto nameKey = Sqlite::compare(view.name, value.name); - if (nameKey != 0) + auto nameKey = view.name <=> value.name; + if (nameKey != std::strong_ordering::equal) return nameKey; Utils::PathString valueSignature{createJson(value.parameters)}; - return Sqlite::compare(view.signature, valueSignature); + return view.signature <=> valueSignature; }; auto insert = [&](const Storage::Synchronization::FunctionDeclaration &value) { @@ -4110,13 +4086,13 @@ void ProjectStorage::synchronizeSignalDeclarations( auto compareKey = [](const Storage::Synchronization::SignalDeclarationView &view, const Storage::Synchronization::SignalDeclaration &value) { - auto nameKey = Sqlite::compare(view.name, value.name); - if (nameKey != 0) + auto nameKey = view.name <=> value.name; + if (nameKey != std::strong_ordering::equal) return nameKey; Utils::PathString valueSignature{createJson(value.parameters)}; - return Sqlite::compare(view.signature, valueSignature); + return view.signature <=> valueSignature; }; auto insert = [&](const Storage::Synchronization::SignalDeclaration &value) { @@ -4188,7 +4164,7 @@ void ProjectStorage::synchronizeEnumerationDeclarations( auto compareKey = [](const Storage::Synchronization::EnumerationDeclarationView &view, const Storage::Synchronization::EnumerationDeclaration &value) { - return Sqlite::compare(view.name, value.name); + return view.name <=> value.name; }; auto insert = [&](const Storage::Synchronization::EnumerationDeclaration &value) { @@ -4313,7 +4289,7 @@ void ProjectStorage::syncDefaultProperties(Storage::Synchronization::Types &type auto compareKey = [](const TypeWithDefaultPropertyView &view, const Storage::Synchronization::Type &value) { - return view.typeId - value.typeId; + return view.typeId <=> value.typeId; }; auto insert = [&](const Storage::Synchronization::Type &) { @@ -4367,7 +4343,7 @@ void ProjectStorage::resetDefaultPropertiesIfChanged(Storage::Synchronization::T auto compareKey = [](const TypeWithDefaultPropertyView &view, const Storage::Synchronization::Type &value) { - return view.typeId - value.typeId; + return view.typeId <=> value.typeId; }; auto insert = [&](const Storage::Synchronization::Type &) { From 71b9f7de7836c674ebc623109a7b35f4a4cf6c54 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 19 Aug 2024 17:43:40 +0200 Subject: [PATCH 070/193] QmlDesigner: Remove Rewriter::sanitizeModel() The model resource manager removes them already. Change-Id: Iaad7d18bce2ccfa8cdc4113c437e278fcb38c1c8 Reviewed-by: Thomas Hartmann --- .../components/integration/designdocument.cpp | 2 -- .../designercore/include/rewriterview.h | 2 -- .../designercore/rewriter/rewriterview.cpp | 33 ------------------- 3 files changed, 37 deletions(-) diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp index aa2dfd3b28a..df792810a48 100644 --- a/src/plugins/qmldesigner/components/integration/designdocument.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp @@ -692,8 +692,6 @@ void DesignDocument::setEditor(Core::IEditor *editor) this, [this](Core::IDocument *document) { if (m_textEditor && m_textEditor->document() == document) { if (m_documentModel && m_documentModel->rewriterView()) { - if (fileName().completeSuffix() == "ui.qml") - m_documentModel->rewriterView()->sanitizeModel(); m_documentModel->rewriterView()->writeAuxiliaryData(); } } diff --git a/src/plugins/qmldesigner/designercore/include/rewriterview.h b/src/plugins/qmldesigner/designercore/include/rewriterview.h index fdc61916ce8..81c2a057380 100644 --- a/src/plugins/qmldesigner/designercore/include/rewriterview.h +++ b/src/plugins/qmldesigner/designercore/include/rewriterview.h @@ -158,8 +158,6 @@ public: ModelNode getNodeForCanonicalIndex(int index); - void sanitizeModel(); - void setAllowComponentRoot(bool allow); bool allowComponentRoot() const; diff --git a/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp b/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp index 48d8e9fb15f..16f8301a3a8 100644 --- a/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp +++ b/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp @@ -19,8 +19,6 @@ #include #include #include -#include -#include #include #include #include @@ -636,37 +634,6 @@ ModelNode RewriterView::getNodeForCanonicalIndex(int index) return m_canonicalIntModelNode.value(index); } -void RewriterView::sanitizeModel() -{ - if (inErrorState()) - return; - - QmlObjectNode root = rootModelNode(); - - QTC_ASSERT(root.isValid(), return); - - QList danglingNodes; - - const auto danglingStates = root.allInvalidStateOperations(); - const auto danglingKeyframeGroups = QmlTimelineKeyframeGroup::allInvalidTimelineKeyframeGroups( - this); - - std::transform(danglingStates.begin(), - danglingStates.end(), - std::back_inserter(danglingNodes), - [](const auto &node) { return node.modelNode(); }); - - std::transform(danglingKeyframeGroups.begin(), - danglingKeyframeGroups.end(), - std::back_inserter(danglingNodes), - [](const auto &node) { return node.modelNode(); }); - - executeInTransaction("RewriterView::sanitizeModel", [&]() { - for (auto node : std::as_const(danglingNodes)) - node.destroy(); - }); -} - void RewriterView::setAllowComponentRoot(bool allow) { m_allowComponentRoot = allow; From b163271e9953c18963edf588ea0a8d1205996c65 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 19 Aug 2024 14:39:27 +0200 Subject: [PATCH 071/193] UnitTests: Add categories to model tests The model is quite large and organizing the tests into categories makes it easier to understand them. Task-number: QDS-13406 Change-Id: I9f8610a6433808e6d5b07e5f58384cea9b24b811 Reviewed-by: Thomas Hartmann --- .../unit/tests/unittests/model/model-test.cpp | 350 +++++++++++------- 1 file changed, 223 insertions(+), 127 deletions(-) diff --git a/tests/unit/tests/unittests/model/model-test.cpp b/tests/unit/tests/unittests/model/model-test.cpp index 7b93b21bb35..4ea64c3ba33 100644 --- a/tests/unit/tests/unittests/model/model-test.cpp +++ b/tests/unit/tests/unittests/model/model-test.cpp @@ -76,7 +76,6 @@ class Model : public ::testing::Test protected: Model() { - model.setFileUrl(QUrl::fromLocalFile(pathCacheMock.path.toQString())); model.attachView(&viewMock); rootNode = viewMock.rootModelNode(); ON_CALL(resourceManagementMock, removeNodes(_, _)).WillByDefault([](auto nodes, auto) { @@ -123,7 +122,7 @@ protected: QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, "Item", imports, - pathCacheMock.path.toQString(), + QUrl::fromLocalFile(pathCacheMock.path.toQString()), std::make_unique( resourceManagementMock)}; NiceMock viewMock; @@ -138,7 +137,73 @@ protected: ModelNode rootNode; }; -TEST_F(Model, model_node_destroy_is_calling_model_resource_management_remove_node) +class Model_Creation : public Model +{}; + +TEST_F(Model_Creation, root_node_has_item_type_name) +{ + auto model = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, + "Item", + imports, + QUrl::fromLocalFile(pathCacheMock.path.toQString()), + std::make_unique( + resourceManagementMock)); + + ASSERT_THAT(model->rootModelNode().type(), Eq("Item")); +} + +TEST_F(Model_Creation, root_node_has_item_meta_info) +{ + auto model = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, + "Item", + imports, + QUrl::fromLocalFile(pathCacheMock.path.toQString()), + std::make_unique( + resourceManagementMock)); + + ASSERT_THAT(model->rootModelNode().metaInfo(), model->qtQuickItemMetaInfo()); +} + +TEST_F(Model_Creation, file_url) +{ + auto model = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, + "Item", + imports, + QUrl::fromLocalFile(pathCacheMock.path.toQString()), + std::make_unique( + resourceManagementMock)); + + ASSERT_THAT(model->fileUrl().toLocalFile(), Eq(pathCacheMock.path.toQString())); +} + +TEST_F(Model_Creation, file_url_source_id) +{ + auto model = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, + "Item", + imports, + QUrl::fromLocalFile(pathCacheMock.path.toQString()), + std::make_unique( + resourceManagementMock)); + + ASSERT_THAT(model->fileUrlSourceId(), pathCacheMock.sourceId); +} + +TEST_F(Model_Creation, imports) +{ + auto model = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, + "Item", + imports, + QUrl::fromLocalFile(pathCacheMock.path.toQString()), + std::make_unique( + resourceManagementMock)); + + ASSERT_THAT(model->imports(), UnorderedElementsAreArray(imports)); +} + +class Model_ResourceManagment : public Model +{}; + +TEST_F(Model_ResourceManagment, model_node_destroy_is_calling_model_resource_management_remove_node) { auto node = createNodeWithParent(rootNode); @@ -147,7 +212,8 @@ TEST_F(Model, model_node_destroy_is_calling_model_resource_management_remove_nod node.destroy(); } -TEST_F(Model, model_node_remove_propery_is_calling_model_resource_management_remove_property) +TEST_F(Model_ResourceManagment, + model_node_remove_propery_is_calling_model_resource_management_remove_property) { auto property = rootNode.variantProperty("foo"); property.setValue(4); @@ -157,7 +223,8 @@ TEST_F(Model, model_node_remove_propery_is_calling_model_resource_management_rem rootNode.removeProperty("foo"); } -TEST_F(Model, node_abstract_property_reparent_here_is_calling_model_resource_management_remove_property) +TEST_F(Model_ResourceManagment, + node_abstract_property_reparent_here_is_calling_model_resource_management_remove_property) { auto node = createNodeWithParent(rootNode); auto property = rootNode.variantProperty("foo"); @@ -168,7 +235,8 @@ TEST_F(Model, node_abstract_property_reparent_here_is_calling_model_resource_man rootNode.nodeListProperty("foo").reparentHere(node); } -TEST_F(Model, node_property_set_model_node_is_calling_model_resource_management_remove_property) +TEST_F(Model_ResourceManagment, + node_property_set_model_node_is_calling_model_resource_management_remove_property) { auto node = createNodeWithParent(rootNode); auto property = rootNode.variantProperty("foo"); @@ -179,7 +247,8 @@ TEST_F(Model, node_property_set_model_node_is_calling_model_resource_management_ rootNode.nodeProperty("foo").setModelNode(node); } -TEST_F(Model, variant_property_set_value_is_calling_model_resource_management_remove_property) +TEST_F(Model_ResourceManagment, + variant_property_set_value_is_calling_model_resource_management_remove_property) { auto property = rootNode.bindingProperty("foo"); property.setExpression("blah"); @@ -189,7 +258,7 @@ TEST_F(Model, variant_property_set_value_is_calling_model_resource_management_re rootNode.variantProperty("foo").setValue(7); } -TEST_F(Model, +TEST_F(Model_ResourceManagment, variant_property_set_dynamic_type_name_and_enumeration_is_calling_model_resource_management_remove_property) { auto property = rootNode.bindingProperty("foo"); @@ -200,7 +269,8 @@ TEST_F(Model, rootNode.variantProperty("foo").setDynamicTypeNameAndEnumeration("int", "Ha"); } -TEST_F(Model, variant_property_set_dynamic_type_name_and_value_is_calling_model_resource_management_remove_property) +TEST_F(Model_ResourceManagment, + variant_property_set_dynamic_type_name_and_value_is_calling_model_resource_management_remove_property) { auto property = rootNode.bindingProperty("foo"); property.setExpression("blah"); @@ -210,7 +280,8 @@ TEST_F(Model, variant_property_set_dynamic_type_name_and_value_is_calling_model_ rootNode.variantProperty("foo").setDynamicTypeNameAndValue("int", 7); } -TEST_F(Model, binding_property_set_expression_is_calling_model_resource_management_remove_property) +TEST_F(Model_ResourceManagment, + binding_property_set_expression_is_calling_model_resource_management_remove_property) { auto property = rootNode.variantProperty("foo"); property.setValue(4); @@ -220,7 +291,7 @@ TEST_F(Model, binding_property_set_expression_is_calling_model_resource_manageme rootNode.bindingProperty("foo").setExpression("blah"); } -TEST_F(Model, +TEST_F(Model_ResourceManagment, binding_property_set_dynamic_type_name_and_expression_is_calling_model_resource_management_remove_property) { auto property = rootNode.variantProperty("foo"); @@ -231,7 +302,8 @@ TEST_F(Model, rootNode.bindingProperty("foo").setDynamicTypeNameAndExpression("int", "blah"); } -TEST_F(Model, signal_handler_property_set_source_is_calling_model_resource_management_remove_property) +TEST_F(Model_ResourceManagment, + signal_handler_property_set_source_is_calling_model_resource_management_remove_property) { auto property = rootNode.bindingProperty("foo"); property.setExpression("blah"); @@ -241,7 +313,8 @@ TEST_F(Model, signal_handler_property_set_source_is_calling_model_resource_manag rootNode.signalHandlerProperty("foo").setSource("blah"); } -TEST_F(Model, signal_declaration_property_set_signature_is_calling_model_resource_management_remove_property) +TEST_F(Model_ResourceManagment, + signal_declaration_property_set_signature_is_calling_model_resource_management_remove_property) { auto property = rootNode.bindingProperty("foo"); property.setExpression("blah"); @@ -251,7 +324,7 @@ TEST_F(Model, signal_declaration_property_set_signature_is_calling_model_resourc rootNode.signalDeclarationProperty("foo").setSignature("blah"); } -TEST_F(Model, model_node_destroy_is_calling_abstract_view_node_about_to_be_removed) +TEST_F(Model_ResourceManagment, model_node_destroy_is_calling_abstract_view_node_about_to_be_removed) { auto node = createNodeWithParent(rootNode); auto node2 = createNodeWithParent(rootNode); @@ -264,7 +337,7 @@ TEST_F(Model, model_node_destroy_is_calling_abstract_view_node_about_to_be_remov node.destroy(); } -TEST_F(Model, model_node_destroy_is_calling_abstract_view_node_removed) +TEST_F(Model_ResourceManagment, model_node_destroy_is_calling_abstract_view_node_removed) { auto node = createNodeWithParent(rootNode); auto node2 = createNodeWithParent(rootNode); @@ -277,7 +350,8 @@ TEST_F(Model, model_node_destroy_is_calling_abstract_view_node_removed) node.destroy(); } -TEST_F(Model, model_node_destroy_is_calling_abstract_view_node_removed_with_valid_nodes) +TEST_F(Model_ResourceManagment, + model_node_destroy_is_calling_abstract_view_node_removed_with_valid_nodes) { auto node = createNodeWithParent(rootNode); auto node2 = createNodeWithParent(rootNode); @@ -290,7 +364,8 @@ TEST_F(Model, model_node_destroy_is_calling_abstract_view_node_removed_with_vali node.destroy(); } -TEST_F(Model, model_node_destroy_is_calling_abstract_view_properties_about_to_be_removed) +TEST_F(Model_ResourceManagment, + model_node_destroy_is_calling_abstract_view_properties_about_to_be_removed) { auto node = createNodeWithParent(rootNode); auto property = createProperty(rootNode, "foo"); @@ -303,7 +378,7 @@ TEST_F(Model, model_node_destroy_is_calling_abstract_view_properties_about_to_be node.destroy(); } -TEST_F(Model, model_node_destroy_is_calling_abstract_view_properties_removed) +TEST_F(Model_ResourceManagment, model_node_destroy_is_calling_abstract_view_properties_removed) { auto node = createNodeWithParent(rootNode); auto property = createProperty(rootNode, "foo"); @@ -316,7 +391,8 @@ TEST_F(Model, model_node_destroy_is_calling_abstract_view_properties_removed) node.destroy(); } -TEST_F(Model, model_node_destroy_is_calling_abstract_view_properties_removed_only_with_valid_properties) +TEST_F(Model_ResourceManagment, + model_node_destroy_is_calling_abstract_view_properties_removed_only_with_valid_properties) { auto node = createNodeWithParent(rootNode); auto property = createProperty(rootNode, "foo"); @@ -329,7 +405,8 @@ TEST_F(Model, model_node_destroy_is_calling_abstract_view_properties_removed_onl node.destroy(); } -TEST_F(Model, model_node_destroy_is_calling_abstract_view_binding_properties_about_to_be_changed) +TEST_F(Model_ResourceManagment, + model_node_destroy_is_calling_abstract_view_binding_properties_about_to_be_changed) { auto node = createNodeWithParent(rootNode); auto property = createBindingProperty(rootNode, "foo"); @@ -343,7 +420,7 @@ TEST_F(Model, model_node_destroy_is_calling_abstract_view_binding_properties_abo node.destroy(); } -TEST_F(Model, model_node_destroy_is_calling_abstract_view_binding_properties_changed) +TEST_F(Model_ResourceManagment, model_node_destroy_is_calling_abstract_view_binding_properties_changed) { auto node = createNodeWithParent(rootNode); auto property = createBindingProperty(rootNode, "foo"); @@ -356,7 +433,7 @@ TEST_F(Model, model_node_destroy_is_calling_abstract_view_binding_properties_cha node.destroy(); } -TEST_F(Model, model_node_destroy_is_changing_binding_property_expression) +TEST_F(Model_ResourceManagment, model_node_destroy_is_changing_binding_property_expression) { auto node = createNodeWithParent(rootNode); auto property = createBindingProperty(rootNode, "foo"); @@ -370,7 +447,7 @@ TEST_F(Model, model_node_destroy_is_changing_binding_property_expression) ASSERT_THAT(property2.expression(), "er"); } -TEST_F(Model, model_node_destroy_is_only_changing_existing_binding_property) +TEST_F(Model_ResourceManagment, model_node_destroy_is_only_changing_existing_binding_property) { auto node = createNodeWithParent(rootNode); auto property = rootNode.bindingProperty("foo"); @@ -382,7 +459,8 @@ TEST_F(Model, model_node_destroy_is_only_changing_existing_binding_property) ASSERT_FALSE(rootNode.hasBindingProperty("foo")); } -TEST_F(Model, model_node_destroy_is_calling_abstract_view_binding_properties_changed_only_with_existing_properties) +TEST_F(Model_ResourceManagment, + model_node_destroy_is_calling_abstract_view_binding_properties_changed_only_with_existing_properties) { auto node = createNodeWithParent(rootNode); auto property = createBindingProperty(rootNode, "foo"); @@ -396,7 +474,8 @@ TEST_F(Model, model_node_destroy_is_calling_abstract_view_binding_properties_cha node.destroy(); } -TEST_F(Model, model_node_remove_property_is_calling_abstract_view_node_about_to_be_removed) +TEST_F(Model_ResourceManagment, + model_node_remove_property_is_calling_abstract_view_node_about_to_be_removed) { auto property = createProperty(rootNode, "foo"); auto node = createNodeWithParent(rootNode); @@ -410,7 +489,7 @@ TEST_F(Model, model_node_remove_property_is_calling_abstract_view_node_about_to_ rootNode.removeProperty("foo"); } -TEST_F(Model, model_node_remove_property_is_calling_abstract_view_node_removed) +TEST_F(Model_ResourceManagment, model_node_remove_property_is_calling_abstract_view_node_removed) { auto property = createProperty(rootNode, "foo"); auto node = createNodeWithParent(rootNode); @@ -424,7 +503,8 @@ TEST_F(Model, model_node_remove_property_is_calling_abstract_view_node_removed) rootNode.removeProperty("foo"); } -TEST_F(Model, model_node_remove_property_is_calling_abstract_view_node_removed_with_valid_nodes) +TEST_F(Model_ResourceManagment, + model_node_remove_property_is_calling_abstract_view_node_removed_with_valid_nodes) { auto property = createProperty(rootNode, "foo"); auto node = createNodeWithParent(rootNode); @@ -438,7 +518,8 @@ TEST_F(Model, model_node_remove_property_is_calling_abstract_view_node_removed_w rootNode.removeProperty("foo"); } -TEST_F(Model, model_node_remove_property_is_calling_abstract_view_properties_about_to_be_removed) +TEST_F(Model_ResourceManagment, + model_node_remove_property_is_calling_abstract_view_properties_about_to_be_removed) { auto property = createProperty(rootNode, "yi"); auto property2 = createProperty(rootNode, "er"); @@ -450,7 +531,7 @@ TEST_F(Model, model_node_remove_property_is_calling_abstract_view_properties_abo rootNode.removeProperty("yi"); } -TEST_F(Model, model_node_remove_property_is_calling_abstract_view_properties_removed) +TEST_F(Model_ResourceManagment, model_node_remove_property_is_calling_abstract_view_properties_removed) { auto property = createProperty(rootNode, "yi"); auto property2 = createProperty(rootNode, "er"); @@ -462,7 +543,8 @@ TEST_F(Model, model_node_remove_property_is_calling_abstract_view_properties_rem rootNode.removeProperty("yi"); } -TEST_F(Model, model_node_remove_property_is_calling_abstract_view_properties_removed_only_with_valid_properties) +TEST_F(Model_ResourceManagment, + model_node_remove_property_is_calling_abstract_view_properties_removed_only_with_valid_properties) { auto property = createProperty(rootNode, "yi"); auto property2 = createProperty(rootNode, "er"); @@ -474,7 +556,8 @@ TEST_F(Model, model_node_remove_property_is_calling_abstract_view_properties_rem rootNode.removeProperty("yi"); } -TEST_F(Model, model_node_remove_property_is_calling_abstract_view_binding_properties_about_to_be_changed) +TEST_F(Model_ResourceManagment, + model_node_remove_property_is_calling_abstract_view_binding_properties_about_to_be_changed) { auto property = createProperty(rootNode, "yi"); auto property1 = createBindingProperty(rootNode, "foo"); @@ -488,7 +571,8 @@ TEST_F(Model, model_node_remove_property_is_calling_abstract_view_binding_proper rootNode.removeProperty("yi"); } -TEST_F(Model, model_node_remove_property_is_calling_abstract_view_binding_properties_changed) +TEST_F(Model_ResourceManagment, + model_node_remove_property_is_calling_abstract_view_binding_properties_changed) { auto property = createProperty(rootNode, "yi"); auto property1 = createBindingProperty(rootNode, "foo"); @@ -502,7 +586,7 @@ TEST_F(Model, model_node_remove_property_is_calling_abstract_view_binding_proper rootNode.removeProperty("yi"); } -TEST_F(Model, +TEST_F(Model_ResourceManagment, model_node_remove_property_is_calling_abstract_view_binding_properties_changed_only_with_valid_properties) { auto property = createProperty(rootNode, "yi"); @@ -517,7 +601,7 @@ TEST_F(Model, rootNode.removeProperty("yi"); } -TEST_F(Model, by_default_remove_model_node_removes_node) +TEST_F(Model_ResourceManagment, by_default_remove_model_node_removes_node) { QmlDesigner::Model newModel{{projectStorageMock, pathCacheMock}, "QtQuick.Item"}; NiceMock viewMock; @@ -529,7 +613,7 @@ TEST_F(Model, by_default_remove_model_node_removes_node) node.destroy(); } -TEST_F(Model, by_default_remove_properties_removes_property) +TEST_F(Model_ResourceManagment, by_default_remove_properties_removes_property) { QmlDesigner::Model newModel{{projectStorageMock, pathCacheMock}, "QtQuick.Item"}; NiceMock viewMock; @@ -542,7 +626,7 @@ TEST_F(Model, by_default_remove_properties_removes_property) rootNode.removeProperty("yi"); } -TEST_F(Model, by_default_remove_model_node_in_factory_method_calls_removes_node) +TEST_F(Model_ResourceManagment, by_default_remove_model_node_in_factory_method_calls_removes_node) { model.detachView(&viewMock); auto newModel = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, @@ -557,7 +641,7 @@ TEST_F(Model, by_default_remove_model_node_in_factory_method_calls_removes_node) node.destroy(); } -TEST_F(Model, by_default_remove_properties_in_factory_method_calls_remove_property) +TEST_F(Model_ResourceManagment, by_default_remove_properties_in_factory_method_calls_remove_property) { model.detachView(&viewMock); auto newModel = QmlDesigner::Model::create({projectStorageMock, pathCacheMock}, @@ -573,7 +657,7 @@ TEST_F(Model, by_default_remove_properties_in_factory_method_calls_remove_proper rootNode.removeProperty("yi"); } -TEST_F(Model, remove_model_nodes) +TEST_F(Model_ResourceManagment, remove_model_nodes) { auto node = createNodeWithParent(rootNode, "yi"); auto node2 = createNodeWithParent(rootNode, "er"); @@ -584,7 +668,7 @@ TEST_F(Model, remove_model_nodes) model.removeModelNodes({node, node2}); } -TEST_F(Model, remove_model_nodes_filters_invalid_model_nodes) +TEST_F(Model_ResourceManagment, remove_model_nodes_filters_invalid_model_nodes) { auto node = createNodeWithParent(rootNode, "yi"); @@ -593,14 +677,14 @@ TEST_F(Model, remove_model_nodes_filters_invalid_model_nodes) model.removeModelNodes({{}, node}); } -TEST_F(Model, remove_model_nodes_for_only_invalid_model_nodes_does_nothing) +TEST_F(Model_ResourceManagment, remove_model_nodes_for_only_invalid_model_nodes_does_nothing) { EXPECT_CALL(resourceManagementMock, removeNodes(_, _)).Times(0); model.removeModelNodes({{}}); } -TEST_F(Model, remove_model_nodes_reverse) +TEST_F(Model_ResourceManagment, remove_model_nodes_reverse) { auto node = createNodeWithParent(rootNode, "yi"); auto node2 = createNodeWithParent(rootNode, "er"); @@ -611,7 +695,7 @@ TEST_F(Model, remove_model_nodes_reverse) model.removeModelNodes({node2, node}); } -TEST_F(Model, remove_model_nodes_calls_notifier) +TEST_F(Model_ResourceManagment, remove_model_nodes_calls_notifier) { auto node = createNodeWithParent(rootNode, "yi"); auto node2 = createNodeWithParent(rootNode, "er"); @@ -632,7 +716,7 @@ TEST_F(Model, remove_model_nodes_calls_notifier) model.removeModelNodes({node, node2}); } -TEST_F(Model, remove_model_nodes_bypasses_model_resource_management) +TEST_F(Model_ResourceManagment, remove_model_nodes_bypasses_model_resource_management) { auto node = createNodeWithParent(rootNode, "yi"); auto node2 = createNodeWithParent(rootNode, "er"); @@ -652,7 +736,7 @@ TEST_F(Model, remove_model_nodes_bypasses_model_resource_management) model.removeModelNodes({node, node2}, QmlDesigner::BypassModelResourceManagement::Yes); } -TEST_F(Model, by_default_remove_model_nodes_in_factory_method_calls_removes_node) +TEST_F(Model_ResourceManagment, by_default_remove_model_nodes_in_factory_method_calls_removes_node) { QmlDesigner::Model newModel{{projectStorageMock, pathCacheMock}, "QtQuick.Item"}; NiceMock viewMock; @@ -667,7 +751,7 @@ TEST_F(Model, by_default_remove_model_nodes_in_factory_method_calls_removes_node newModel.removeModelNodes({node, node2}); } -TEST_F(Model, remove_properties) +TEST_F(Model_ResourceManagment, remove_properties) { auto property = createProperty(rootNode, "yi"); auto property2 = createProperty(rootNode, "er"); @@ -678,7 +762,7 @@ TEST_F(Model, remove_properties) model.removeProperties({property, property2}); } -TEST_F(Model, remove_properties_filters_invalid_properties) +TEST_F(Model_ResourceManagment, remove_properties_filters_invalid_properties) { auto property = createProperty(rootNode, "yi"); @@ -687,14 +771,14 @@ TEST_F(Model, remove_properties_filters_invalid_properties) model.removeProperties({{}, property}); } -TEST_F(Model, remove_properties_for_only_invalid_properties_does_nothing) +TEST_F(Model_ResourceManagment, remove_properties_for_only_invalid_properties_does_nothing) { EXPECT_CALL(resourceManagementMock, removeProperties(_, _)).Times(0); model.removeProperties({{}}); } -TEST_F(Model, remove_properties_reverse) +TEST_F(Model_ResourceManagment, remove_properties_reverse) { auto property = createProperty(rootNode, "yi"); auto property2 = createProperty(rootNode, "er"); @@ -705,7 +789,7 @@ TEST_F(Model, remove_properties_reverse) model.removeProperties({property2, property}); } -TEST_F(Model, remove_properties_calls_notifier) +TEST_F(Model_ResourceManagment, remove_properties_calls_notifier) { auto node = createNodeWithParent(rootNode, "yi"); auto node2 = createNodeWithParent(rootNode, "er"); @@ -726,7 +810,7 @@ TEST_F(Model, remove_properties_calls_notifier) model.removeProperties({property, property3}); } -TEST_F(Model, remove_properties_bypasses_model_resource_management) +TEST_F(Model_ResourceManagment, remove_properties_bypasses_model_resource_management) { auto node = createNodeWithParent(rootNode, "yi"); auto node2 = createNodeWithParent(rootNode, "er"); @@ -745,7 +829,7 @@ TEST_F(Model, remove_properties_bypasses_model_resource_management) model.removeProperties({property, property3}, QmlDesigner::BypassModelResourceManagement::Yes); } -TEST_F(Model, by_default_remove_properties_in_factory_method_calls_removes_properties) +TEST_F(Model_ResourceManagment, by_default_remove_properties_in_factory_method_calls_removes_properties) { model.detachView(&viewMock); QmlDesigner::Model newModel{{projectStorageMock, pathCacheMock}, "QtQuick.Item"}; @@ -759,7 +843,10 @@ TEST_F(Model, by_default_remove_properties_in_factory_method_calls_removes_prope newModel.removeProperties({property, property2}); } -TEST_F(Model, change_imports_is_synchronizing_imports_with_project_storage) +class Model_Imports : public Model +{}; + +TEST_F(Model_Imports, change_imports_is_synchronizing_imports_with_project_storage) { QmlDesigner::SourceId directoryPathId = QmlDesigner::SourceId::create(2); ON_CALL(pathCacheMock, sourceId(Eq("/path/foo/."))).WillByDefault(Return(directoryPathId)); @@ -780,7 +867,7 @@ TEST_F(Model, change_imports_is_synchronizing_imports_with_project_storage) model.changeImports({qtQuickImport, qtQmlModelsImport}, {}); } -TEST_F(Model, +TEST_F(Model_Imports, change_imports_is_not_synchronizing_imports_with_project_storage_if_no_new_imports_are_added) { QmlDesigner::SourceId directoryPathId = QmlDesigner::SourceId::create(2); @@ -795,7 +882,7 @@ TEST_F(Model, model.changeImports({qtQuickImport, qtQmlModelsImport}, {}); } -TEST_F(Model, change_imports_is_adding_import_in_project_storage) +TEST_F(Model_Imports, change_imports_is_adding_import_in_project_storage) { QmlDesigner::SourceId directoryPathId = QmlDesigner::SourceId::create(2); ON_CALL(pathCacheMock, sourceId(Eq("/path/foo/."))).WillByDefault(Return(directoryPathId)); @@ -817,7 +904,7 @@ TEST_F(Model, change_imports_is_adding_import_in_project_storage) model.changeImports({qtQuickImport}, {}); } -TEST_F(Model, change_imports_is_removing_import_in_project_storage) +TEST_F(Model_Imports, change_imports_is_removing_import_in_project_storage) { QmlDesigner::SourceId directoryPathId = QmlDesigner::SourceId::create(2); ON_CALL(pathCacheMock, sourceId(Eq("/path/foo/."))).WillByDefault(Return(directoryPathId)); @@ -837,7 +924,7 @@ TEST_F(Model, change_imports_is_removing_import_in_project_storage) model.changeImports({}, {qtQuickImport}); } -TEST_F(Model, +TEST_F(Model_Imports, change_imports_is_not_removing_import_in_project_storage_if_import_is_not_in_model_imports) { QmlDesigner::SourceId directoryPathId = QmlDesigner::SourceId::create(2); @@ -852,7 +939,7 @@ TEST_F(Model, model.changeImports({}, {qtQmlModelsImport}); } -TEST_F(Model, change_imports_is_changing_import_version_with_project_storage) +TEST_F(Model_Imports, change_imports_is_changing_import_version_with_project_storage) { QmlDesigner::SourceId directoryPathId = QmlDesigner::SourceId::create(2); ON_CALL(pathCacheMock, sourceId(Eq("/path/foo/."))).WillByDefault(Return(directoryPathId)); @@ -875,14 +962,17 @@ TEST_F(Model, change_imports_is_changing_import_version_with_project_storage) model.changeImports({qtQuickImport}, {}); } -TEST_F(Model, create_model_node_has_meta_info) +class Model_Node : public Model +{}; + +TEST_F(Model_Node, create_model_node_has_meta_info) { auto node = model.createModelNode("Item"); ASSERT_THAT(node.metaInfo(), model.qtQuickItemMetaInfo()); } -TEST_F(Model, create_qualified_model_node_has_meta_info) +TEST_F(Model_Node, create_qualified_model_node_has_meta_info) { auto qtQmlModelsImport = QmlDesigner::Import::createLibraryImport("QtQml.Models", "", "Foo"); auto qtQmlModelsModulesId = projectStorageMock.moduleId("QtQml.Models", ModuleKind::QmlLibrary); @@ -898,7 +988,7 @@ TEST_F(Model, create_qualified_model_node_has_meta_info) ASSERT_THAT(node.metaInfo(), model.qtQmlModelsListModelMetaInfo()); } -TEST_F(Model, change_root_node_type_changes_meta_info) +TEST_F(Model_Node, change_root_node_type_changes_meta_info) { projectStorageMock.createImportedTypeNameId(filePathId, "QtObject", @@ -909,28 +999,31 @@ TEST_F(Model, change_root_node_type_changes_meta_info) ASSERT_THAT(rootNode.metaInfo(), model.qmlQtObjectMetaInfo()); } -TEST_F(Model, meta_info) +class Model_MetaInfo : public Model +{}; + +TEST_F(Model_MetaInfo, get_meta_info_for_type_name) { auto meta_info = model.metaInfo("QtObject"); ASSERT_THAT(meta_info, model.qmlQtObjectMetaInfo()); } -TEST_F(Model, meta_info_of_not_existing_type_is_invalid) +TEST_F(Model_MetaInfo, meta_info_of_not_existing_type_is_invalid) { auto meta_info = model.metaInfo("Foo"); ASSERT_THAT(meta_info, IsFalse()); } -TEST_F(Model, module_is_valid) +TEST_F(Model_MetaInfo, module_is_valid) { auto module = model.module("QML", ModuleKind::QmlLibrary); ASSERT_THAT(module, IsTrue()); } -TEST_F(Model, module_returns_always_the_same) +TEST_F(Model_MetaInfo, module_returns_always_the_same) { auto oldModule = model.module("QML", ModuleKind::QmlLibrary); @@ -939,7 +1032,7 @@ TEST_F(Model, module_returns_always_the_same) ASSERT_THAT(module, oldModule); } -TEST_F(Model, get_meta_info_by_module) +TEST_F(Model_MetaInfo, get_meta_info_by_module) { auto module = model.module("QML", ModuleKind::QmlLibrary); @@ -948,7 +1041,7 @@ TEST_F(Model, get_meta_info_by_module) ASSERT_THAT(metaInfo, model.qmlQtObjectMetaInfo()); } -TEST_F(Model, get_invalid_meta_info_by_module_for_wrong_name) +TEST_F(Model_MetaInfo, get_invalid_meta_info_by_module_for_wrong_name) { auto module = model.module("QML", ModuleKind::QmlLibrary); @@ -957,7 +1050,7 @@ TEST_F(Model, get_invalid_meta_info_by_module_for_wrong_name) ASSERT_THAT(metaInfo, IsFalse()); } -TEST_F(Model, get_invalid_meta_info_by_module_for_wrong_module) +TEST_F(Model_MetaInfo, get_invalid_meta_info_by_module_for_wrong_module) { auto module = model.module("Qml", ModuleKind::QmlLibrary); @@ -966,21 +1059,21 @@ TEST_F(Model, get_invalid_meta_info_by_module_for_wrong_module) ASSERT_THAT(metaInfo, IsFalse()); } -TEST_F(Model, add_project_storage_observer_to_project_storage) +TEST_F(Model_MetaInfo, add_project_storage_observer_to_project_storage) { EXPECT_CALL(projectStorageMock, addObserver(_)); QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, "Item", -1, -1, nullptr, {}}; } -TEST_F(Model, remove_project_storage_observer_from_project_storage) +TEST_F(Model_MetaInfo, remove_project_storage_observer_from_project_storage) { EXPECT_CALL(projectStorageMock, removeObserver(_)).Times(2); // the fixture model is calling it too QmlDesigner::Model model{{projectStorageMock, pathCacheMock}, "Item", -1, -1, nullptr, {}}; } -TEST_F(Model, refresh_callback_is_calling_abstract_view) +TEST_F(Model_MetaInfo, refresh_callback_is_calling_abstract_view) { const QmlDesigner::TypeIds typeIds = {QmlDesigner::TypeId::create(3), QmlDesigner::TypeId::create(1)}; @@ -996,7 +1089,7 @@ TEST_F(Model, refresh_callback_is_calling_abstract_view) observer->removedTypeIds(typeIds); } -TEST_F(Model, meta_infos_for_mdoule) +TEST_F(Model_MetaInfo, meta_infos_for_mdoule) { projectStorageMock.createModule("Foo", ModuleKind::QmlLibrary); auto module = model.module("Foo", ModuleKind::QmlLibrary); @@ -1009,7 +1102,65 @@ TEST_F(Model, meta_infos_for_mdoule) ASSERT_THAT(types, ElementsAre(Eq(QmlDesigner::NodeMetaInfo{typeId, &projectStorageMock}))); } -TEST_F(Model, item_library_entries) +TEST_F(Model_MetaInfo, create_node_resolved_meta_type) +{ + auto node = model.createModelNode("Item"); + + ASSERT_THAT(node.metaInfo(), model.qtQuickItemMetaInfo()); +} + +TEST_F(Model_MetaInfo, create_node_has_unresolved_meta_type_for_invalid_type_name) +{ + auto node = model.createModelNode("Foo"); + + ASSERT_THAT(node.metaInfo(), IsFalse()); +} + +TEST_F(Model_MetaInfo, refresh_type_id_if_project_storage_removed_type_id) +{ + auto node = model.createModelNode("Item"); + projectStorageMock.removeType(qtQuickModuleId, "Item"); + auto observer = projectStorageMock.observers.front(); + auto itemTypeId2 = projectStorageMock.createObject(qtQuickModuleId, "Item"); + projectStorageMock.refreshImportedTypeNameId(itemTypeNameId, itemTypeId2); + + observer->removedTypeIds({itemTypeId}); + + ASSERT_THAT(node.metaInfo().id(), itemTypeId2); +} + +TEST_F(Model_MetaInfo, set_null_type_id_if_project_storage_removed_type_id_cannot_be_refreshed) +{ + auto node = model.createModelNode("Item"); + projectStorageMock.removeType(qtQuickModuleId, "Item"); + projectStorageMock.refreshImportedTypeNameId(itemTypeNameId, QmlDesigner::TypeId{}); + + auto observer = projectStorageMock.observers.front(); + + observer->removedTypeIds({itemTypeId}); + + ASSERT_THAT(node.metaInfo().id(), IsFalse()); +} + +TEST_F(Model_MetaInfo, null_type_id_are_refreshed_if_exported_types_are_updated) +{ + auto node = model.createModelNode("Item"); + projectStorageMock.removeType(qtQuickModuleId, "Item"); + projectStorageMock.refreshImportedTypeNameId(itemTypeNameId, QmlDesigner::TypeId{}); + auto observer = projectStorageMock.observers.front(); + observer->removedTypeIds({itemTypeId}); + auto itemTypeId2 = projectStorageMock.createObject(qtQuickModuleId, "Item"); + projectStorageMock.refreshImportedTypeNameId(itemTypeNameId, itemTypeId2); + + observer->exportedTypesChanged(); + + ASSERT_THAT(node.metaInfo().id(), itemTypeId2); +} + +class Model_TypeAnnotation : public Model +{}; + +TEST_F(Model_TypeAnnotation, item_library_entries) { using namespace Qt::StringLiterals; QmlDesigner::Storage::Info::ItemLibraryEntries storageEntries{{itemTypeId, @@ -1040,59 +1191,4 @@ TEST_F(Model, item_library_entries) ElementsAre(u"/extra/file/path")))); } -TEST_F(Model, create_node_resolved_meta_type) -{ - auto node = model.createModelNode("Item"); - - ASSERT_THAT(node.metaInfo(), model.qtQuickItemMetaInfo()); -} - -TEST_F(Model, create_node_has_unresolved_meta_type_for_invalid_type_name) -{ - auto node = model.createModelNode("Foo"); - - ASSERT_THAT(node.metaInfo(), IsFalse()); -} - -TEST_F(Model, refresh_type_id_if_project_storage_removed_type_id) -{ - auto node = model.createModelNode("Item"); - projectStorageMock.removeType(qtQuickModuleId, "Item"); - auto observer = projectStorageMock.observers.front(); - auto itemTypeId2 = projectStorageMock.createObject(qtQuickModuleId, "Item"); - projectStorageMock.refreshImportedTypeNameId(itemTypeNameId, itemTypeId2); - - observer->removedTypeIds({itemTypeId}); - - ASSERT_THAT(node.metaInfo().id(), itemTypeId2); -} - -TEST_F(Model, set_null_type_id_if_project_storage_removed_type_id_cannot_be_refreshed) -{ - auto node = model.createModelNode("Item"); - projectStorageMock.removeType(qtQuickModuleId, "Item"); - projectStorageMock.refreshImportedTypeNameId(itemTypeNameId, QmlDesigner::TypeId{}); - - auto observer = projectStorageMock.observers.front(); - - observer->removedTypeIds({itemTypeId}); - - ASSERT_THAT(node.metaInfo().id(), IsFalse()); -} - -TEST_F(Model, null_type_id_are_refreshed_if_exported_types_are_updated) -{ - auto node = model.createModelNode("Item"); - projectStorageMock.removeType(qtQuickModuleId, "Item"); - projectStorageMock.refreshImportedTypeNameId(itemTypeNameId, QmlDesigner::TypeId{}); - auto observer = projectStorageMock.observers.front(); - observer->removedTypeIds({itemTypeId}); - auto itemTypeId2 = projectStorageMock.createObject(qtQuickModuleId, "Item"); - projectStorageMock.refreshImportedTypeNameId(itemTypeNameId, itemTypeId2); - - observer->exportedTypesChanged(); - - ASSERT_THAT(node.metaInfo().id(), itemTypeId2); -} - } // namespace From cc20d66f60ec45cd9feaf1e578c8d38631242fd5 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 19 Aug 2024 20:07:47 +0200 Subject: [PATCH 072/193] Sqlite: Fix equal operator Two null id should be not equal, Like to null sql values are not equal. That has the advantage that a null type is not matching a null type in the database. It simply should return no type. Change-Id: Iad205aba330e1a3ca721a7fea211eecb06879d2c Reviewed-by: Thomas Hartmann --- src/libs/sqlite/sqliteids.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/libs/sqlite/sqliteids.h b/src/libs/sqlite/sqliteids.h index 4e8eba801a4..4816cd67d7c 100644 --- a/src/libs/sqlite/sqliteids.h +++ b/src/libs/sqlite/sqliteids.h @@ -44,6 +44,11 @@ public: return first.id == second.id; } + friend constexpr bool operator==(BasicId first, BasicId second) + { + return first.id == second.id && first.isValid(); + } + friend constexpr auto operator<=>(BasicId first, BasicId second) = default; constexpr friend InternalIntegerType operator-(BasicId first, BasicId second) @@ -121,13 +126,13 @@ public: return first.id, second.id; } - friend constexpr auto operator<=>(CompoundBasicId first, CompoundBasicId second) = default; - - friend constexpr long long operator-(CompoundBasicId first, CompoundBasicId second) + friend constexpr bool operator==(CompoundBasicId first, CompoundBasicId second) { - return first.id - second.id; + return first.id == second.id && first.isValid(); } + friend constexpr auto operator<=>(CompoundBasicId first, CompoundBasicId second) = default; + constexpr bool isValid() const { return id != 0; } constexpr bool isNull() const { return id == 0; } From 064580e837ae0c82ae90753124c78fa2393c3534 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 19 Aug 2024 20:11:35 +0200 Subject: [PATCH 073/193] QmlDesigner: Fix <=> operator for model node It should return strong ordering. A null model node was always equal to a null model node. Maybe we should changed it, but that is a different discussion. Change-Id: I85cbf88daec9cb1db1f74515e2955959247d0b9c Reviewed-by: Thomas Hartmann --- src/plugins/qmldesigner/designercore/include/modelnode.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/include/modelnode.h b/src/plugins/qmldesigner/designercore/include/modelnode.h index ba429b66e62..df2f7113f27 100644 --- a/src/plugins/qmldesigner/designercore/include/modelnode.h +++ b/src/plugins/qmldesigner/designercore/include/modelnode.h @@ -255,12 +255,7 @@ public: return firstNode.m_internalNode == secondNode.m_internalNode; } - friend bool operator!=(const ModelNode &firstNode, const ModelNode &secondNode) - { - return !(firstNode == secondNode); - } - - friend std::weak_ordering operator<=>(const ModelNode &firstNode, const ModelNode &secondNode) + friend auto operator<=>(const ModelNode &firstNode, const ModelNode &secondNode) { return firstNode.m_internalNode <=> secondNode.m_internalNode; } From bf76b3f6a78c68998ca1c7d813829bd3ec08653b Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 21 Aug 2024 12:23:20 +0200 Subject: [PATCH 074/193] QmlDesigner: Fix potential crash When moving items into components we sometimes get an offset larger than the actual file. This avodis a crash/assert in this case. Change-Id: I8edd19639357d8cab41dacf8abc513764f08c1e5 Reviewed-by: Knud Dollereder --- src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp b/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp index 16f8301a3a8..a48927d548a 100644 --- a/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp +++ b/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp @@ -842,7 +842,8 @@ ModelNode RewriterView::nodeAtTextCursorPositionHelper(const ModelNode &root, in for (const myPair &pair : data) { ModelNode node = pair.first; - const int nodeTextOffset = nodeOffset(node); + const int textLength = m_textModifier->text().length(); + const int nodeTextOffset = std::max(nodeOffset(node), textLength); const int nodeTextLength = findEvenClosingBrace(m_textModifier->text().sliced(nodeTextOffset)) - 1; From eaaa241fd498d092164de55c634f23bb09837917 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 21 Aug 2024 12:21:27 +0200 Subject: [PATCH 075/193] QmlJSCheck: Allow new translation macros in designer Change-Id: I16a871a919f9f36d219f8b55e1c4601860b79dfe Reviewed-by: Thomas Hartmann --- src/libs/qmljs/qmljscheck.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp index 959f2721c8c..c97fc10c55b 100644 --- a/src/libs/qmljs/qmljscheck.cpp +++ b/src/libs/qmljs/qmljscheck.cpp @@ -1853,9 +1853,16 @@ bool Check::visit(CallExpression *ast) const QString namespaceName = functionNamespace(ast->base); // We have to allow the translation functions - - static const QStringList translationFunctions = {"qsTr", "qsTrId", "qsTranslate", - "qsTrNoOp", "qsTrIdNoOp", "qsTranslateNoOp"}; + static const QStringList translationFunctions + = {"qsTr", + "qsTrId", + "qsTranslate", + "qsTrNoOp", + "qsTrIdNoOp", + "qsTranslateNoOp", + "QT_TR_NOOP", + " QT_TRANSLATE_NOOP", + "QT_TRID_NOOP"}; static const QStringList whiteListedFunctions = { "toString", "toFixed", "toExponential", "toPrecision", "isFinite", From 3d2c1970543f57080cd935c3cb752d21fd750606 Mon Sep 17 00:00:00 2001 From: Knud Dollereder Date: Fri, 16 Aug 2024 12:10:46 +0200 Subject: [PATCH 076/193] Add PythonGenerator to simplify DS to Python workflow There is now a new Menu entry: "Export Project"->"Enable Python Generator". When checked it will create a simple Python file that can be used as starting point for python development. Alternatively one can also use the qmlproject variable "enablePythonGeneration" to enable the python generator. also, took the opportunity to refactor the code. - Improved names from the original implementation. (cmakegen -> QmlProjectExporter) - Bundled the cmake generator and the python generator in one class Exporter. - Moved common functionality of both generators into one base class (FileGenerator). Change-Id: Ie5948a115148ee1ddce78d827d5ce4498ea5d558 Reviewed-by: Thomas Hartmann --- .../componentcore/resourcegenerator.cpp | 2 +- src/plugins/qmlprojectmanager/CMakeLists.txt | 9 +- .../buildsystem/projectitem/converters.cpp | 6 +- .../projectitem/qmlprojectitem.cpp | 12 ++ .../buildsystem/projectitem/qmlprojectitem.h | 3 + .../buildsystem/qmlbuildsystem.cpp | 32 +++-- .../buildsystem/qmlbuildsystem.h | 7 +- .../boilerplate.qrc | 0 .../cmakegenerator.cpp | 135 +++++------------- .../cmakegenerator.h | 23 ++- .../cmakewriter.cpp | 30 ++-- .../cmakewriter.h | 6 +- .../cmakewriterv0.cpp | 4 +- .../cmakewriterv0.h | 4 +- .../cmakewriterv1.cpp | 4 +- .../cmakewriterv1.h | 4 +- .../qmlprojectexporter/exporter.cpp | 41 ++++++ .../qmlprojectexporter/exporter.h | 30 ++++ .../qmlprojectexporter/filegenerator.cpp | 92 ++++++++++++ .../qmlprojectexporter/filegenerator.h | 46 ++++++ .../filetypes.cpp | 0 .../filetypes.h | 0 .../qmlprojectexporter/pythongenerator.cpp | 114 +++++++++++++++ .../qmlprojectexporter/pythongenerator.h | 32 +++++ .../templates/cmakelists_txt_shared.tpl | 0 .../templates/cmakemodule_v1.tpl | 0 .../templates/cmakeroot_v0.tpl | 0 .../templates/cmakeroot_v1.tpl | 0 .../templates/environment_h.tpl | 0 .../templates/import_qml_components_h.tpl | 0 .../templates/insight.tpl | 0 .../templates/main_cpp_v0.tpl | 0 .../templates/main_cpp_v1.tpl | 0 .../templates/qmlcomponents.tpl | 0 .../templates/qtquickcontrols2_conf.tpl | 0 .../qmlprojectgen/qmlprojectgenerator.cpp | 4 +- .../qmlprojectmanager/qmlprojectmanager.qbs | 10 +- .../qmlprojectmanager/qmlprojectplugin.cpp | 6 +- .../converter/test-set-1/testfile.jsontoqml | 1 + .../converter/test-set-2/testfile.jsontoqml | 1 + .../converter/test-set-3/testfile.jsontoqml | 1 + .../test-set-mcu-1/testfile.jsontoqml | 1 + .../test-set-mcu-2/testfile.jsontoqml | 1 + 43 files changed, 494 insertions(+), 167 deletions(-) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/boilerplate.qrc (100%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/cmakegenerator.cpp (87%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/cmakegenerator.h (76%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/cmakewriter.cpp (98%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/cmakewriter.h (95%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/cmakewriterv0.cpp (98%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/cmakewriterv0.h (91%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/cmakewriterv1.cpp (99%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/cmakewriterv1.h (91%) create mode 100644 src/plugins/qmlprojectmanager/qmlprojectexporter/exporter.cpp create mode 100644 src/plugins/qmlprojectmanager/qmlprojectexporter/exporter.h create mode 100644 src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.cpp create mode 100644 src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.h rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/filetypes.cpp (100%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/filetypes.h (100%) create mode 100644 src/plugins/qmlprojectmanager/qmlprojectexporter/pythongenerator.cpp create mode 100644 src/plugins/qmlprojectmanager/qmlprojectexporter/pythongenerator.h rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/templates/cmakelists_txt_shared.tpl (100%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/templates/cmakemodule_v1.tpl (100%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/templates/cmakeroot_v0.tpl (100%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/templates/cmakeroot_v1.tpl (100%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/templates/environment_h.tpl (100%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/templates/import_qml_components_h.tpl (100%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/templates/insight.tpl (100%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/templates/main_cpp_v0.tpl (100%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/templates/main_cpp_v1.tpl (100%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/templates/qmlcomponents.tpl (100%) rename src/plugins/qmlprojectmanager/{cmakegen => qmlprojectexporter}/templates/qtquickcontrols2_conf.tpl (100%) diff --git a/src/plugins/qmldesigner/components/componentcore/resourcegenerator.cpp b/src/plugins/qmldesigner/components/componentcore/resourcegenerator.cpp index 97a00a10f40..e9874246ddd 100644 --- a/src/plugins/qmldesigner/components/componentcore/resourcegenerator.cpp +++ b/src/plugins/qmldesigner/components/componentcore/resourcegenerator.cpp @@ -13,7 +13,7 @@ #include #include -#include +#include #include diff --git a/src/plugins/qmlprojectmanager/CMakeLists.txt b/src/plugins/qmlprojectmanager/CMakeLists.txt index 2cbf409e041..73dd37d8289 100644 --- a/src/plugins/qmlprojectmanager/CMakeLists.txt +++ b/src/plugins/qmlprojectmanager/CMakeLists.txt @@ -39,13 +39,16 @@ extend_qtc_plugin(QmlProjectManager ) extend_qtc_plugin(QmlProjectManager - PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/cmakegen - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/cmakegen + PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/qmlprojectexporter + SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/qmlprojectexporter SOURCES + pythongenerator.cpp pythongenerator.h cmakegenerator.cpp cmakegenerator.h cmakewriter.cpp cmakewriter.h cmakewriterv0.cpp cmakewriterv0.h cmakewriterv1.cpp cmakewriterv1.h + exporter.cpp exporter.h + filegenerator.cpp filegenerator.h filetypes.cpp filetypes.h boilerplate.qrc ) @@ -62,5 +65,5 @@ add_qtc_library(QmlProjectManagerLib OBJECT buildsystem/projectitem/filefilteritems.cpp buildsystem/projectitem/filefilteritems.h buildsystem/projectitem/qmlprojectitem.cpp buildsystem/projectitem/qmlprojectitem.h buildsystem/projectitem/converters.cpp buildsystem/projectitem/converters.h - cmakegen/filetypes.cpp cmakegen/filetypes.h + qmlprojectexporter/filetypes.cpp qmlprojectexporter/filetypes.h ) diff --git a/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp b/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp index e98a8446091..2fa96af8c27 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp @@ -3,7 +3,7 @@ #include "converters.h" #include "utils/algorithm.h" -#include "cmakegen/filetypes.h" +#include "qmlprojectexporter/filetypes.h" #include @@ -144,6 +144,7 @@ QString jsonToQmlProject(const QJsonObject &rootObject) appendString("mainUiFile", runConfig["mainUiFile"].toString()); appendString("targetDirectory", deploymentConfig["targetDirectory"].toString()); appendBool("enableCMakeGeneration", deploymentConfig["enableCMakeGeneration"].toBool()); + appendBool("enablePythonGeneration", deploymentConfig["enablePythonGeneration"].toBool()); appendBool("widgetApp", runConfig["widgetApp"].toBool()); appendStringArray("importPaths", rootObject["importPaths"].toVariant().toStringList()); appendBreak(); @@ -384,7 +385,8 @@ QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile) || propName.contains("forcefreetype", Qt::CaseInsensitive)) { currentObj = &runConfigObject; } else if (propName.contains("targetdirectory", Qt::CaseInsensitive) - || propName.contains("enableCMakeGeneration", Qt::CaseInsensitive)) { + || propName.contains("enableCMakeGeneration", Qt::CaseInsensitive) + || propName.contains("enablePythonGeneration", Qt::CaseInsensitive)) { currentObj = &deploymentObject; } else if (propName.contains("qtformcus", Qt::CaseInsensitive)) { qtForMCUs = value.toBool(); diff --git a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp index 067ada48f03..12436f08ce4 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp @@ -436,4 +436,16 @@ void QmlProjectItem::setEnableCMakeGeneration(bool enable) insertAndUpdateProjectFile("deployment", obj); } +bool QmlProjectItem::enablePythonGeneration() const +{ + return m_project["deployment"].toObject()["enablePythonGeneration"].toBool(); +} + +void QmlProjectItem::setEnablePythonGeneration(bool enable) +{ + QJsonObject obj = m_project["deployment"].toObject(); + obj["enablePythonGeneration"] = enable; + insertAndUpdateProjectFile("deployment", obj); +} + } // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.h b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.h index bcbc3ddadc5..36ee8ef5316 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.h +++ b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.h @@ -93,6 +93,9 @@ public: bool enableCMakeGeneration() const; void setEnableCMakeGeneration(bool enable); + bool enablePythonGeneration() const; + void setEnablePythonGeneration(bool enable); + signals: void filesChanged(const QSet &, const QSet &); diff --git a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp index 6fa944f0753..e66acd36e45 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp @@ -78,7 +78,7 @@ void updateMcuBuildStep(Target *target, bool mcuEnabled) QmlBuildSystem::QmlBuildSystem(Target *target) : BuildSystem(target) - , m_cmakeGen(new GenerateCmake::CMakeGenerator(this, this)) + , m_fileGen(new QmlProjectExporter::Exporter(this)) { // refresh first - project information is used e.g. to decide the default RC's refresh(RefreshOptions::Project); @@ -88,13 +88,13 @@ QmlBuildSystem::QmlBuildSystem(Target *target) connect(target->project(), &Project::activeTargetChanged, this, [this](Target *target) { refresh(RefreshOptions::NoFileRefresh); - m_cmakeGen->initialize(qmlProject()); + m_fileGen->updateProject(qmlProject()); updateMcuBuildStep(target, qtForMCUs()); }); connect(target->project(), &Project::projectFileIsDirty, this, [this] { refresh(RefreshOptions::Project); - m_cmakeGen->initialize(qmlProject()); - m_cmakeGen->updateMenuAction(); + m_fileGen->updateProject(qmlProject()); + m_fileGen->updateMenuAction(); updateMcuBuildStep(project()->activeTarget(), qtForMCUs()); }); @@ -221,13 +221,7 @@ void QmlBuildSystem::initProjectItem() m_projectItem.reset(new QmlProjectItem{projectFilePath()}); connect(m_projectItem.data(), &QmlProjectItem::filesChanged, this, &QmlBuildSystem::refreshFiles); - connect(m_projectItem.data(), - &QmlProjectItem::filesChanged, - m_cmakeGen, - &GenerateCmake::CMakeGenerator::update); - - m_cmakeGen->setEnabled(m_projectItem->enableCMakeGeneration()); - + m_fileGen->updateProjectItem(m_projectItem.data(), true); initMcuProjectItems(); } @@ -243,10 +237,7 @@ void QmlBuildSystem::initMcuProjectItems() m_mcuProjectItems.append(qmlProjectItem); connect(qmlProjectItem.data(), &QmlProjectItem::filesChanged, this, &QmlBuildSystem::refreshFiles); - connect(qmlProjectItem.data(), - &QmlProjectItem::filesChanged, - m_cmakeGen, - &GenerateCmake::CMakeGenerator::update); + m_fileGen->updateProjectItem(m_projectItem.data(), false); m_mcuProjectFilesWatcher.addFile(mcuProjectFile, Utils::FileSystemWatcher::WatchModifiedDate); @@ -550,6 +541,17 @@ void QmlBuildSystem::setEnableCMakeGeneration(bool enable) m_projectItem->setEnableCMakeGeneration(enable); } +bool QmlBuildSystem::enablePythonGeneration() const +{ + return m_projectItem->enablePythonGeneration(); +} + +void QmlBuildSystem::setEnablePythonGeneration(bool enable) +{ + if (enable != enablePythonGeneration()) + m_projectItem->setEnablePythonGeneration(enable); +} + void QmlBuildSystem::refreshFiles(const QSet & /*added*/, const QSet &removed) { if (m_blockFilesUpdate) { diff --git a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h index d91f60cdd12..22ea4e443e6 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h +++ b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h @@ -10,7 +10,7 @@ #include #include -#include "qmlprojectmanager/cmakegen/cmakegenerator.h" +#include "qmlprojectmanager/qmlprojectexporter/exporter.h" namespace QmlProjectManager { @@ -87,6 +87,9 @@ public: bool enableCMakeGeneration() const; void setEnableCMakeGeneration(bool enable); + bool enablePythonGeneration() const; + void setEnablePythonGeneration(bool enable); + bool forceFreeType() const; bool widgetApp() const; @@ -133,7 +136,7 @@ private: void updateDeploymentData(); friend class FilesUpdateBlocker; - GenerateCmake::CMakeGenerator* m_cmakeGen; + QmlProjectExporter::Exporter* m_fileGen; }; } // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/cmakegen/boilerplate.qrc b/src/plugins/qmlprojectmanager/qmlprojectexporter/boilerplate.qrc similarity index 100% rename from src/plugins/qmlprojectmanager/cmakegen/boilerplate.qrc rename to src/plugins/qmlprojectmanager/qmlprojectexporter/boilerplate.qrc diff --git a/src/plugins/qmlprojectmanager/cmakegen/cmakegenerator.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.cpp similarity index 87% rename from src/plugins/qmlprojectmanager/cmakegen/cmakegenerator.cpp rename to src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.cpp index 4f81763f39b..063811ea9d0 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/cmakegenerator.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.cpp @@ -5,46 +5,26 @@ #include "filetypes.h" #include "qmlprojectmanager/qmlproject.h" -#include "qmlprojectmanager/qmlprojectconstants.h" #include "qmlprojectmanager/qmlprojectmanagertr.h" #include "projectexplorer/projectmanager.h" #include "projectexplorer/projectnodes.h" -#include "projectexplorer/taskhub.h" #include "utils/filenamevalidatinglineedit.h" -#include "coreplugin/actionmanager/actionmanager.h" -#include "coreplugin/actionmanager/actioncontainer.h" - #include #include -#include #include #include namespace QmlProjectManager { - -namespace GenerateCmake { +namespace QmlProjectExporter { void CMakeGenerator::createMenuAction(QObject *parent) { - Core::ActionContainer *fileMenu = Core::ActionManager::actionContainer( - Core::Constants::M_FILE); - Core::ActionContainer *exportMenu = Core::ActionManager::createMenu( - QmlProjectManager::Constants::EXPORT_MENU); - - exportMenu->menu()->setTitle(Tr::tr("Export Project")); - exportMenu->appendGroup(QmlProjectManager::Constants::G_EXPORT_GENERATE); - fileMenu->addMenu(exportMenu, Core::Constants::G_FILE_EXPORT); - - auto action = new QAction(Tr::tr("Enable Automatic CMake Generation"), parent); - action->setEnabled(false); - action->setCheckable(true); - - Core::Command *cmd = Core::ActionManager::registerAction(action, "QmlProject.EnableCMakeGeneration"); - exportMenu->addAction(cmd, QmlProjectManager::Constants::G_EXPORT_GENERATE); + QAction *action = FileGenerator::createMenuAction( + parent, Tr::tr("Enable CMake Generator"), "QmlProject.EnableCMakeGeneration"); QObject::connect( ProjectExplorer::ProjectManager::instance(), @@ -63,82 +43,21 @@ void CMakeGenerator::createMenuAction(QObject *parent) }); } -void CMakeGenerator::logIssue(ProjectExplorer::Task::TaskType type, const QString &text, const Utils::FilePath &file) -{ - ProjectExplorer::BuildSystemTask task(type, text, file); - ProjectExplorer::TaskHub::addTask(task); - ProjectExplorer::TaskHub::requestPopup(); -} - -void CMakeGenerator::updateMenuAction() -{ - QTC_ASSERT(buildSystem(), return); - - Core::Command *cmd = Core::ActionManager::command("QmlProject.EnableCMakeGeneration"); - if (!cmd) - return; - - QAction *action = cmd->action(); - if (!action) - return; - - bool enabled = buildSystem()->enableCMakeGeneration(); - if (enabled != action->isChecked()) - action->setChecked(enabled); -} - -CMakeGenerator::CMakeGenerator(QmlBuildSystem *bs, QObject *parent) - : QObject(parent) - , m_buildSystem(bs) +CMakeGenerator::CMakeGenerator(QmlBuildSystem *bs) + : FileGenerator(bs) , m_root(std::make_shared()) {} -const QmlProject *CMakeGenerator::qmlProject() const +void CMakeGenerator::updateMenuAction() { - if (m_buildSystem) - return m_buildSystem->qmlProject(); - return nullptr; + FileGenerator::updateMenuAction( + "QmlProject.EnableCMakeGeneration", + [this](){ return buildSystem()->enableCMakeGeneration(); }); } -const QmlBuildSystem *CMakeGenerator::buildSystem() const +void CMakeGenerator::updateProject(QmlProject *project) { - return m_buildSystem; -} - -bool CMakeGenerator::findFile(const Utils::FilePath& file) const -{ - return findFile(m_root, file); -} - -bool CMakeGenerator::isRootNode(const NodePtr &node) const -{ - return node->name == "Main"; -} - -bool CMakeGenerator::hasChildModule(const NodePtr &node) const -{ - for (const NodePtr &child : node->subdirs) { - if (child->type == Node::Type::Module) - return true; - if (hasChildModule(child)) - return true; - } - return false; -} - -QString CMakeGenerator::projectName() const -{ - return m_projectName; -} - -void CMakeGenerator::setEnabled(bool enabled) -{ - m_enabled = enabled; -} - -void CMakeGenerator::initialize(QmlProject *project) -{ - if (!m_enabled) + if (!isEnabled()) return; m_moduleNames.clear(); @@ -162,13 +81,37 @@ void CMakeGenerator::initialize(QmlProject *project) compareWithFileSystem(m_root); } +QString CMakeGenerator::projectName() const +{ + return m_projectName; +} + +bool CMakeGenerator::findFile(const Utils::FilePath& file) const +{ + return findFile(m_root, file); +} + +bool CMakeGenerator::isRootNode(const NodePtr &node) const +{ + return node->name == "Main"; +} + +bool CMakeGenerator::hasChildModule(const NodePtr &node) const +{ + for (const NodePtr &child : node->subdirs) { + if (child->type == Node::Type::Module) + return true; + if (hasChildModule(child)) + return true; + } + return false; +} + void CMakeGenerator::update(const QSet &added, const QSet &removed) { - if (!m_enabled) + if (!isEnabled() || !m_writer) return; - QTC_ASSERT(m_writer, return); - std::set dirtyModules; for (const QString &add : added) { const Utils::FilePath path = Utils::FilePath::fromString(add); @@ -551,5 +494,5 @@ void CMakeGenerator::compareWithFileSystem(const NodePtr &node) const logIssue(ProjectExplorer::Task::Warning, text, file); } -} // namespace GenerateCmake +} // namespace QmlProjectExporter } // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/cmakegen/cmakegenerator.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.h similarity index 76% rename from src/plugins/qmlprojectmanager/cmakegen/cmakegenerator.h rename to src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.h index e552f154203..e3b8a8a1085 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/cmakegenerator.h +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.h @@ -2,10 +2,10 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once +#include "filegenerator.h" #include "cmakewriter.h" #include "utils/filepath.h" -#include "projectexplorer/task.h" #include @@ -18,31 +18,26 @@ namespace QmlProjectManager { class QmlProject; class QmlBuildSystem; -namespace GenerateCmake { +namespace QmlProjectExporter { -class CMakeGenerator : public QObject +class CMakeGenerator : public FileGenerator { Q_OBJECT public: static void createMenuAction(QObject *parent); - static void logIssue(ProjectExplorer::Task::TaskType type, const QString &text, const Utils::FilePath &file); - CMakeGenerator(QmlBuildSystem *bs, QObject *parent = nullptr); + CMakeGenerator(QmlBuildSystem *bs); + + void updateProject(QmlProject *project) override; + void updateMenuAction() override; QString projectName() const; - - const QmlProject *qmlProject() const; - const QmlBuildSystem *buildSystem() const; - bool findFile(const Utils::FilePath &file) const; bool isRootNode(const NodePtr &node) const; bool hasChildModule(const NodePtr &node) const; - void setEnabled(bool enabled); - void initialize(QmlProject *project); void update(const QSet &added, const QSet &removed); - void updateMenuAction(); private: bool ignore(const Utils::FilePath &path) const; @@ -68,8 +63,6 @@ private: void compareWithFileSystem(const NodePtr &node) const; - bool m_enabled = false; - QmlBuildSystem *m_buildSystem = nullptr; CMakeWriter::Ptr m_writer = {}; QString m_projectName = {}; @@ -77,5 +70,5 @@ private: QStringList m_moduleNames = {}; }; -} // namespace GenerateCmake +} // namespace QmlProjectExporter } // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/cmakegen/cmakewriter.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp similarity index 98% rename from src/plugins/qmlprojectmanager/cmakegen/cmakewriter.cpp rename to src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp index 81701cd4bc0..966714981a0 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/cmakewriter.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp @@ -15,7 +15,7 @@ namespace QmlProjectManager { -namespace GenerateCmake { +namespace QmlProjectExporter { const char TEMPLATE_BIG_RESOURCES[] = R"( qt6_add_resources(%1 %2 @@ -51,6 +51,19 @@ QString CMakeWriter::readTemplate(const QString &templatePath) return content; } +void CMakeWriter::writeFile(const Utils::FilePath &path, const QString &content) +{ + QFile fileHandle(path.toString()); + if (fileHandle.open(QIODevice::WriteOnly)) { + QTextStream stream(&fileHandle); + stream << content; + } else { + QString text("Failed to write"); + CMakeGenerator::logIssue(ProjectExplorer::Task::Error, text, path); + } + fileHandle.close(); +} + CMakeWriter::CMakeWriter(CMakeGenerator *parent) : m_parent(parent) {} @@ -257,19 +270,6 @@ std::tuple CMakeWriter::makeResourcesBlocks(const NodePtr &nod return {resourcesOut, bigResourcesOut}; } -void CMakeWriter::writeFile(const Utils::FilePath &path, const QString &content) const -{ - QFile fileHandle(path.toString()); - if (fileHandle.open(QIODevice::WriteOnly)) { - QTextStream stream(&fileHandle); - stream << content; - } else { - QString text("Failed to write"); - CMakeGenerator::logIssue(ProjectExplorer::Task::Error, text, path); - } - fileHandle.close(); -} - void CMakeWriter::collectPlugins(const NodePtr &node, std::vector &out) const { if (isPlugin(node)) @@ -278,6 +278,6 @@ void CMakeWriter::collectPlugins(const NodePtr &node, std::vector &out) collectPlugins(child, out); } -} // End namespace GenerateCmake. +} // End namespace QmlProjectExporter. } // End namespace QmlProjectManager. diff --git a/src/plugins/qmlprojectmanager/cmakegen/cmakewriter.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.h similarity index 95% rename from src/plugins/qmlprojectmanager/cmakegen/cmakewriter.h rename to src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.h index 14eb512f9c4..0fbee120f79 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/cmakewriter.h +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.h @@ -11,7 +11,7 @@ namespace QmlProjectManager { class QmlProject; class QmlBuildSystem; -namespace GenerateCmake { +namespace QmlProjectExporter { struct Node { @@ -60,6 +60,7 @@ public: static Ptr create(CMakeGenerator *parent); static QString readTemplate(const QString &templatePath); + static void writeFile(const Utils::FilePath &path, const QString &content); CMakeWriter(CMakeGenerator *parent); const CMakeGenerator *parent() const; @@ -90,13 +91,12 @@ protected: QString makeSetEnvironmentFn() const; std::tuple makeResourcesBlocks(const NodePtr &node) const; - void writeFile(const Utils::FilePath &path, const QString &content) const; private: void collectPlugins(const NodePtr &node, std::vector &out) const; const CMakeGenerator *m_parent = nullptr; }; -} // End namespace GenerateCmake. +} // End namespace QmlProjectExporter. } // End namespace QmlProjectManager. diff --git a/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv0.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.cpp similarity index 98% rename from src/plugins/qmlprojectmanager/cmakegen/cmakewriterv0.cpp rename to src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.cpp index b6861a4493d..257a549b264 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv0.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.cpp @@ -5,7 +5,7 @@ namespace QmlProjectManager { -namespace GenerateCmake { +namespace QmlProjectExporter { const char TEMPLATE_ADD_QML_MODULE[] = R"( qt6_add_qml_module(%1 @@ -176,5 +176,5 @@ void CMakeWriterV0::writeSourceFiles(const NodePtr &node, const NodePtr &root) c writeFile(headerFilePath, importPluginsHeader); } -} // namespace GenerateCmake +} // namespace QmlProjectExporter } // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv0.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.h similarity index 91% rename from src/plugins/qmlprojectmanager/cmakegen/cmakewriterv0.h rename to src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.h index a1cd16d0fce..b7f47f0d547 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv0.h +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.h @@ -6,7 +6,7 @@ namespace QmlProjectManager { -namespace GenerateCmake { +namespace QmlProjectExporter { class CMakeWriterV0 final : public CMakeWriter { @@ -21,5 +21,5 @@ public: void writeSourceFiles(const NodePtr &node, const NodePtr &root) const override; }; -} // namespace GenerateCmake +} // namespace QmlProjectExporter } // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv1.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.cpp similarity index 99% rename from src/plugins/qmlprojectmanager/cmakegen/cmakewriterv1.cpp rename to src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.cpp index 0ff2f23da4e..8c3178beb53 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv1.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.cpp @@ -7,7 +7,7 @@ namespace QmlProjectManager { -namespace GenerateCmake { +namespace QmlProjectExporter { const char TEMPLATE_SRC_CMAKELISTS[] = R"( target_sources(${CMAKE_PROJECT_NAME} PUBLIC @@ -183,5 +183,5 @@ void CMakeWriterV1::writeSourceFiles(const NodePtr &node, const NodePtr &root) c writeFile(headerPath, headerTemplate.arg(environmentPrefix, environmentPostfix)); } -} // namespace GenerateCmake +} // namespace QmlProjectExporter } // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv1.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.h similarity index 91% rename from src/plugins/qmlprojectmanager/cmakegen/cmakewriterv1.h rename to src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.h index 2a6a05b07be..ed51eb070e6 100644 --- a/src/plugins/qmlprojectmanager/cmakegen/cmakewriterv1.h +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.h @@ -6,7 +6,7 @@ namespace QmlProjectManager { -namespace GenerateCmake { +namespace QmlProjectExporter { class CMakeWriterV1 final : public CMakeWriter { @@ -21,5 +21,5 @@ public: void writeSourceFiles(const NodePtr &node, const NodePtr &root) const override; }; -} // namespace GenerateCmake +} // namespace QmlProjectExporter } // namespace QmlProjectManager diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/exporter.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/exporter.cpp new file mode 100644 index 00000000000..d4f7b752588 --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/exporter.cpp @@ -0,0 +1,41 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#include "exporter.h" +#include "qmlbuildsystem.h" + +#include "projectitem/qmlprojectitem.h" + +namespace QmlProjectManager { +namespace QmlProjectExporter { + +Exporter::Exporter(QmlBuildSystem *bs) + : QObject(bs) + , m_cmakeGen(new CMakeGenerator(bs)) + , m_pythonGen(new PythonGenerator(bs)) +{} + +void Exporter::updateMenuAction() +{ + m_cmakeGen->updateMenuAction(); + m_pythonGen->updateMenuAction(); +} + +void Exporter::updateProject(QmlProject *project) +{ + m_cmakeGen->updateProject(project); + m_pythonGen->updateProject(project); +} + +void Exporter::updateProjectItem(QmlProjectItem *item, bool updateEnabled) +{ + connect(item, &QmlProjectItem::filesChanged, m_cmakeGen, &CMakeGenerator::update); + + if (updateEnabled) { + m_cmakeGen->setEnabled(item->enableCMakeGeneration()); + m_pythonGen->setEnabled(item->enablePythonGeneration()); + } +} + +} // namespace QmlProjectExporter. +} // namespace QmlProjectManager. diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/exporter.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/exporter.h new file mode 100644 index 00000000000..2e3e1343e6e --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/exporter.h @@ -0,0 +1,30 @@ + +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#pragma once + +#include "cmakegenerator.h" +#include "pythongenerator.h" + +namespace QmlProjectManager { +namespace QmlProjectExporter { + +class Exporter : public QObject +{ + Q_OBJECT + +public: + Exporter(QmlBuildSystem *bs = nullptr); + virtual ~Exporter() = default; + + void updateMenuAction(); + void updateProject(QmlProject *project); + void updateProjectItem(QmlProjectItem *item, bool updateEnabled); + +private: + CMakeGenerator *m_cmakeGen; + PythonGenerator *m_pythonGen; +}; + +} // namespace QmlProjectExporter. +} // namespace QmlProjectManager. diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.cpp new file mode 100644 index 00000000000..392b18f4ccc --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.cpp @@ -0,0 +1,92 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#include "filegenerator.h" +#include "qmlbuildsystem.h" + +#include + +#include +#include + +#include +#include + +#include + +namespace QmlProjectManager { +namespace QmlProjectExporter { + +QAction *FileGenerator::createMenuAction(QObject *parent, const QString &name, const Utils::Id &id) +{ + Core::ActionContainer *fileMenu = Core::ActionManager::actionContainer(Core::Constants::M_FILE); + Core::ActionContainer *exportMenu = Core::ActionManager::createMenu( + QmlProjectManager::Constants::EXPORT_MENU); + + exportMenu->menu()->setTitle(Tr::tr("Export Project")); + exportMenu->appendGroup(QmlProjectManager::Constants::G_EXPORT_GENERATE); + fileMenu->addMenu(exportMenu, Core::Constants::G_FILE_EXPORT); + + auto action = new QAction(name, parent); + action->setEnabled(false); + action->setCheckable(true); + + Core::Command *cmd = Core::ActionManager::registerAction(action, id); + exportMenu->addAction(cmd, QmlProjectManager::Constants::G_EXPORT_GENERATE); + + return action; +} + +void FileGenerator::logIssue(ProjectExplorer::Task::TaskType type, + const QString &text, + const Utils::FilePath &file) +{ + ProjectExplorer::BuildSystemTask task(type, text, file); + ProjectExplorer::TaskHub::addTask(task); + ProjectExplorer::TaskHub::requestPopup(); +} + +FileGenerator::FileGenerator(QmlBuildSystem *bs) + : QObject(bs) + , m_buildSystem(bs) +{} + +const QmlProject *FileGenerator::qmlProject() const +{ + if (m_buildSystem) + return m_buildSystem->qmlProject(); + return nullptr; +} + +const QmlBuildSystem *FileGenerator::buildSystem() const +{ + return m_buildSystem; +} + +bool FileGenerator::isEnabled() const +{ + return m_enabled; +} + +void FileGenerator::setEnabled(bool enabled) +{ + m_enabled = enabled; +} + +void FileGenerator::updateMenuAction(const Utils::Id &id, std::function isEnabled) +{ + Core::Command *cmd = Core::ActionManager::command(id); + if (!cmd) + return; + + QAction *action = cmd->action(); + if (!action) + return; + + bool enabled = isEnabled(); + if (enabled != action->isChecked()) + action->setChecked(enabled); +} + +} // namespace QmlProjectExporter. +} // namespace QmlProjectManager. diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.h new file mode 100644 index 00000000000..da86e3130eb --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/filegenerator.h @@ -0,0 +1,46 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#pragma once + +#include +#include + +namespace QmlProjectManager { + +class QmlProject; +class QmlProjectItem; +class QmlBuildSystem; + +namespace QmlProjectExporter { + +class FileGenerator : public QObject +{ + Q_OBJECT + +public: + static QAction *createMenuAction(QObject *parent, const QString &name, const Utils::Id &id); + static void logIssue( + ProjectExplorer::Task::TaskType type, const QString &text, const Utils::FilePath &file); + + FileGenerator(QmlBuildSystem *bs = nullptr); + virtual ~FileGenerator() = default; + + virtual void updateMenuAction() = 0; + virtual void updateProject(QmlProject *project) = 0; + + const QmlProject *qmlProject() const; + const QmlBuildSystem *buildSystem() const; + + bool isEnabled() const; + void setEnabled(bool enabled); + +protected: + void updateMenuAction(const Utils::Id &id, std::function isEnabled); + +private: + bool m_enabled = false; + QmlBuildSystem *m_buildSystem = nullptr; +}; + +} // namespace QmlProjectExporter. +} // namespace QmlProjectManager. diff --git a/src/plugins/qmlprojectmanager/cmakegen/filetypes.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/filetypes.cpp similarity index 100% rename from src/plugins/qmlprojectmanager/cmakegen/filetypes.cpp rename to src/plugins/qmlprojectmanager/qmlprojectexporter/filetypes.cpp diff --git a/src/plugins/qmlprojectmanager/cmakegen/filetypes.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/filetypes.h similarity index 100% rename from src/plugins/qmlprojectmanager/cmakegen/filetypes.h rename to src/plugins/qmlprojectmanager/qmlprojectexporter/filetypes.h diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/pythongenerator.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/pythongenerator.cpp new file mode 100644 index 00000000000..11ae25fd2ce --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/pythongenerator.cpp @@ -0,0 +1,114 @@ +// 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 "pythongenerator.h" +#include "cmakewriter.h" + +#include "projectexplorer/projectmanager.h" +#include "qmlprojectmanager/qmlproject.h" + +#include + +namespace QmlProjectManager { + +namespace QmlProjectExporter { + +const char *PYTHON_MAIN_FILE_TEMPLATE = R"( +import os +import sys +from pathlib import Path + +from PySide6.QtGui import QGuiApplication +from PySide6.QtQml import QQmlApplicationEngine + +from autogen.settings import url, import_paths + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + engine = QQmlApplicationEngine() + + app_dir = Path(__file__).parent.parent + + engine.addImportPath(os.fspath(app_dir)) + for path in import_paths: + engine.addImportPath(os.fspath(app_dir / path)) + + engine.load(os.fspath(app_dir/url)) + if not engine.rootObjects(): + sys.exit(-1) + sys.exit(app.exec()) +)"; + +void PythonGenerator::createMenuAction(QObject *parent) +{ + QAction *action = FileGenerator::createMenuAction(parent, + "Enable Python Generator", + "QmlProject.EnablePythonGenerator"); + + QObject::connect(ProjectExplorer::ProjectManager::instance(), + &ProjectExplorer::ProjectManager::startupProjectChanged, + [action]() { + if (auto buildSystem = QmlBuildSystem::getStartupBuildSystem()) { + action->setEnabled(!buildSystem->qtForMCUs()); + action->setChecked(buildSystem->enablePythonGeneration()); + } + }); + + QObject::connect(action, &QAction::toggled, [](bool checked) { + if (auto buildSystem = QmlBuildSystem::getStartupBuildSystem()) + buildSystem->setEnablePythonGeneration(checked); + }); +} + +PythonGenerator::PythonGenerator(QmlBuildSystem *bs) + : FileGenerator(bs) +{} + +void PythonGenerator::updateMenuAction() +{ + FileGenerator::updateMenuAction( + "QmlProject.EnablePythonGenerator", + [this]() { return buildSystem()->enablePythonGeneration(); }); +} + +void PythonGenerator::updateProject(QmlProject *project) +{ + if (!isEnabled()) + return; + + Utils::FilePath projectPath = project->rootProjectDirectory(); + Utils::FilePath pythonPath = projectPath.pathAppended("Python"); + if (!pythonPath.exists()) + pythonPath.createDir(); + + Utils::FilePath mainFile = pythonPath.pathAppended("main.py"); + if (!mainFile.exists()) { + const QString mainContent = QString::fromUtf8(PYTHON_MAIN_FILE_TEMPLATE); + CMakeWriter::writeFile(mainFile, mainContent); + } + + Utils::FilePath autogenPath = pythonPath.pathAppended("autogen"); + if (!autogenPath.exists()) + autogenPath.createDir(); + + Utils::FilePath settingsPath = autogenPath.pathAppended("settings.py"); + CMakeWriter::writeFile(settingsPath, settingsFileContent()); +} + +QString PythonGenerator::settingsFileContent() const +{ + QTC_ASSERT(buildSystem(), return {}); + + QString content("\n"); + content.append("url = \"" + buildSystem()->mainFile() + "\"\n"); + + content.append("import_paths = [\n"); + for (const QString &path : buildSystem()->importPaths()) + content.append("\t\"" + path + "\",\n"); + content.append("]\n"); + + return content; +} + +} // namespace QmlProjectExporter. +} // namespace QmlProjectManager. diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/pythongenerator.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/pythongenerator.h new file mode 100644 index 00000000000..7c0a5810df5 --- /dev/null +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/pythongenerator.h @@ -0,0 +1,32 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#pragma once + +#include "filegenerator.h" +#include + +namespace QmlProjectManager { + +class QmlProject; +class QmlProjectItem; +class QmlBuildSystem; + +namespace QmlProjectExporter { + +class PythonGenerator : public FileGenerator +{ + Q_OBJECT + +public: + static void createMenuAction(QObject *parent); + + PythonGenerator(QmlBuildSystem *bs); + void updateMenuAction() override; + void updateProject(QmlProject *project) override; + +private: + QString settingsFileContent() const; +}; + +} // namespace QmlProjectExporter. +} // namespace QmlProjectManager. diff --git a/src/plugins/qmlprojectmanager/cmakegen/templates/cmakelists_txt_shared.tpl b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/cmakelists_txt_shared.tpl similarity index 100% rename from src/plugins/qmlprojectmanager/cmakegen/templates/cmakelists_txt_shared.tpl rename to src/plugins/qmlprojectmanager/qmlprojectexporter/templates/cmakelists_txt_shared.tpl diff --git a/src/plugins/qmlprojectmanager/cmakegen/templates/cmakemodule_v1.tpl b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/cmakemodule_v1.tpl similarity index 100% rename from src/plugins/qmlprojectmanager/cmakegen/templates/cmakemodule_v1.tpl rename to src/plugins/qmlprojectmanager/qmlprojectexporter/templates/cmakemodule_v1.tpl diff --git a/src/plugins/qmlprojectmanager/cmakegen/templates/cmakeroot_v0.tpl b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/cmakeroot_v0.tpl similarity index 100% rename from src/plugins/qmlprojectmanager/cmakegen/templates/cmakeroot_v0.tpl rename to src/plugins/qmlprojectmanager/qmlprojectexporter/templates/cmakeroot_v0.tpl diff --git a/src/plugins/qmlprojectmanager/cmakegen/templates/cmakeroot_v1.tpl b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/cmakeroot_v1.tpl similarity index 100% rename from src/plugins/qmlprojectmanager/cmakegen/templates/cmakeroot_v1.tpl rename to src/plugins/qmlprojectmanager/qmlprojectexporter/templates/cmakeroot_v1.tpl diff --git a/src/plugins/qmlprojectmanager/cmakegen/templates/environment_h.tpl b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/environment_h.tpl similarity index 100% rename from src/plugins/qmlprojectmanager/cmakegen/templates/environment_h.tpl rename to src/plugins/qmlprojectmanager/qmlprojectexporter/templates/environment_h.tpl diff --git a/src/plugins/qmlprojectmanager/cmakegen/templates/import_qml_components_h.tpl b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/import_qml_components_h.tpl similarity index 100% rename from src/plugins/qmlprojectmanager/cmakegen/templates/import_qml_components_h.tpl rename to src/plugins/qmlprojectmanager/qmlprojectexporter/templates/import_qml_components_h.tpl diff --git a/src/plugins/qmlprojectmanager/cmakegen/templates/insight.tpl b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/insight.tpl similarity index 100% rename from src/plugins/qmlprojectmanager/cmakegen/templates/insight.tpl rename to src/plugins/qmlprojectmanager/qmlprojectexporter/templates/insight.tpl diff --git a/src/plugins/qmlprojectmanager/cmakegen/templates/main_cpp_v0.tpl b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/main_cpp_v0.tpl similarity index 100% rename from src/plugins/qmlprojectmanager/cmakegen/templates/main_cpp_v0.tpl rename to src/plugins/qmlprojectmanager/qmlprojectexporter/templates/main_cpp_v0.tpl diff --git a/src/plugins/qmlprojectmanager/cmakegen/templates/main_cpp_v1.tpl b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/main_cpp_v1.tpl similarity index 100% rename from src/plugins/qmlprojectmanager/cmakegen/templates/main_cpp_v1.tpl rename to src/plugins/qmlprojectmanager/qmlprojectexporter/templates/main_cpp_v1.tpl diff --git a/src/plugins/qmlprojectmanager/cmakegen/templates/qmlcomponents.tpl b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/qmlcomponents.tpl similarity index 100% rename from src/plugins/qmlprojectmanager/cmakegen/templates/qmlcomponents.tpl rename to src/plugins/qmlprojectmanager/qmlprojectexporter/templates/qmlcomponents.tpl diff --git a/src/plugins/qmlprojectmanager/cmakegen/templates/qtquickcontrols2_conf.tpl b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/qtquickcontrols2_conf.tpl similarity index 100% rename from src/plugins/qmlprojectmanager/cmakegen/templates/qtquickcontrols2_conf.tpl rename to src/plugins/qmlprojectmanager/qmlprojectexporter/templates/qtquickcontrols2_conf.tpl diff --git a/src/plugins/qmlprojectmanager/qmlprojectgen/qmlprojectgenerator.cpp b/src/plugins/qmlprojectmanager/qmlprojectgen/qmlprojectgenerator.cpp index 0270a290fdd..633c2365eb7 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectgen/qmlprojectgenerator.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectgen/qmlprojectgenerator.cpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qmlprojectgenerator.h" -#include "../cmakegen/cmakewriter.h" +#include "../qmlprojectexporter/cmakewriter.h" #include "../qmlprojectmanagertr.h" #include @@ -61,7 +61,7 @@ bool QmlProjectFileGenerator::execute() importDirs.removeAll("content"); const QString importPaths = createDirArrayEntry("importPaths", importDirs); - const QString fileContent = GenerateCmake::CMakeWriter::readTemplate(QMLPROJECT_FILE_TEMPLATE_PATH) + const QString fileContent = QmlProjectExporter::CMakeWriter::readTemplate(QMLPROJECT_FILE_TEMPLATE_PATH) .arg(contentEntry, imageEntry, jsEntry, assetEntry, importPaths); QFile file(m_targetFile.toString()); diff --git a/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs b/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs index b723fe4a4c1..0dc8d399854 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs +++ b/src/plugins/qmlprojectmanager/qmlprojectmanager.qbs @@ -45,13 +45,17 @@ QtcPlugin { Group { name: "CMake Generator" - prefix: "cmakegen/" + prefix: "qmlprojectexporter/" files: [ + "pythongenerator.cpp", "pythongenerator.h", "cmakegenerator.cpp", "cmakegenerator.h", "cmakewriter.cpp", "cmakewriter.h", "cmakewriterv0.cpp", "cmakewriterv0.h", - "cmakewriterv1.cpp", "cmakewriterv1.h" - "filetypes.cpp", "filetypes.h" + "cmakewriterv1.cpp", "cmakewriterv1.h", + "exporter.cpp", "exporter.h", + "filegenerator.cpp", "filegenerator.h", + "filetypes.cpp", "filetypes.h", + "boilerplate.qrc" ] } diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp index 1bc61c3b825..a30aec37830 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp @@ -9,7 +9,8 @@ #include "qmlprojectmanagertr.h" #include "qmlprojectrunconfiguration.h" #include "projectfilecontenttools.h" -#include "cmakegen/cmakegenerator.h" +#include "qmlprojectexporter/cmakegenerator.h" +#include "qmlprojectexporter/pythongenerator.h" #include #include @@ -402,7 +403,8 @@ void QmlProjectPlugin::initialize() != fileNode->filePath()); }); - GenerateCmake::CMakeGenerator::createMenuAction(this); + QmlProjectExporter::CMakeGenerator::createMenuAction(this); + QmlProjectExporter::PythonGenerator::createMenuAction(this); } } diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.jsontoqml b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.jsontoqml index 90c980cda1b..ec698ec1d6a 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.jsontoqml +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-1/testfile.jsontoqml @@ -8,6 +8,7 @@ Project { mainUiFile: "content/Screen01.ui.qml" targetDirectory: "/opt/UntitledProject13" enableCMakeGeneration: false + enablePythonGeneration: false widgetApp: true importPaths: [ "imports","asset_imports" ] diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.jsontoqml b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.jsontoqml index 16617e015dc..fbdc7d78980 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.jsontoqml +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-2/testfile.jsontoqml @@ -7,6 +7,7 @@ Project { mainFile: "fileSelectors.qml" targetDirectory: "/opt/fileSelectors" enableCMakeGeneration: false + enablePythonGeneration: false widgetApp: false importPaths: [ "imports" ] diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.jsontoqml b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.jsontoqml index 90c980cda1b..ec698ec1d6a 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.jsontoqml +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-3/testfile.jsontoqml @@ -8,6 +8,7 @@ Project { mainUiFile: "content/Screen01.ui.qml" targetDirectory: "/opt/UntitledProject13" enableCMakeGeneration: false + enablePythonGeneration: false widgetApp: true importPaths: [ "imports","asset_imports" ] diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.jsontoqml b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.jsontoqml index 0b5989a7719..be7fde31218 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.jsontoqml +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-1/testfile.jsontoqml @@ -7,6 +7,7 @@ Project { mainFile: "Main.qml" targetDirectory: "/opt/UntitledProject13" enableCMakeGeneration: false + enablePythonGeneration: false widgetApp: true importPaths: [ "imports","asset_imports","mcu-modules" ] diff --git a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-2/testfile.jsontoqml b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-2/testfile.jsontoqml index ad0102201fc..1e6c1deb206 100644 --- a/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-2/testfile.jsontoqml +++ b/tests/unit/tests/unittests/qmlprojectmanager/data/converter/test-set-mcu-2/testfile.jsontoqml @@ -5,6 +5,7 @@ import QmlProject Project { enableCMakeGeneration: false + enablePythonGeneration: false widgetApp: false qt6Project: false From f4c51613d4ba9421e7e9ebc6bd6dd67be879153f Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 22 Aug 2024 12:34:40 +0300 Subject: [PATCH 077/193] QmlDesigner: Remove import version numbers from IssuesPanel Releases are not built with 6.7 yet. Fixes: QDS-13441 Change-Id: I4c63df701a3e4a99314cd35daead65db8e7af4ee Reviewed-by: Knud Dollereder --- share/qtcreator/qmldesigner/statusbar/IssuesOutputPanel.qml | 2 +- share/qtcreator/qmldesigner/statusbar/IssuesOutputToolBar.qml | 2 +- share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/share/qtcreator/qmldesigner/statusbar/IssuesOutputPanel.qml b/share/qtcreator/qmldesigner/statusbar/IssuesOutputPanel.qml index 6aaad1f2ff8..3088fac2e07 100644 --- a/share/qtcreator/qmldesigner/statusbar/IssuesOutputPanel.qml +++ b/share/qtcreator/qmldesigner/statusbar/IssuesOutputPanel.qml @@ -1,6 +1,6 @@ // Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -import QtQuick 6.7 +import QtQuick import QtQuick.Controls import QtQuick.Layouts diff --git a/share/qtcreator/qmldesigner/statusbar/IssuesOutputToolBar.qml b/share/qtcreator/qmldesigner/statusbar/IssuesOutputToolBar.qml index eda61d32a74..26019023258 100644 --- a/share/qtcreator/qmldesigner/statusbar/IssuesOutputToolBar.qml +++ b/share/qtcreator/qmldesigner/statusbar/IssuesOutputToolBar.qml @@ -1,6 +1,6 @@ // Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -import QtQuick 6.7 +import QtQuick import QtQuick.Controls import QtQuick.Layouts diff --git a/share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml b/share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml index 33d92642d6c..e59aa345b90 100644 --- a/share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml +++ b/share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml @@ -1,6 +1,6 @@ // Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -import QtQuick 6.7 +import QtQuick import QtQuick.Controls import QtQuick.Layouts import ToolBar From ae7ee0289ddbfe7693828147734762f2156d0fe3 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 22 Aug 2024 10:39:45 +0200 Subject: [PATCH 078/193] QmlDesigner: Fix warning for integer arithmetics Change-Id: I542adb65f46132d6ce4495e0ff386af9821c5469 Reviewed-by: Knud Dollereder --- .../components/toolbar/appoutputmodel.cpp | 14 +++++++------- .../components/toolbar/messagemodel.cpp | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/plugins/qmldesigner/components/toolbar/appoutputmodel.cpp b/src/plugins/qmldesigner/components/toolbar/appoutputmodel.cpp index 86a47ba2d48..ecef4cf6abd 100644 --- a/src/plugins/qmldesigner/components/toolbar/appoutputmodel.cpp +++ b/src/plugins/qmldesigner/components/toolbar/appoutputmodel.cpp @@ -49,7 +49,7 @@ void AppOutputChildModel::addMessage(int row, const QString &message, const QCol return; if (AppOutputParentModel::Run *run = m_parentModel->run(m_row)) { - int at = run->messages.size(); + int at = static_cast(run->messages.size()); beginInsertRows(QModelIndex(), at, at); run->messages.push_back({message, color}); endInsertRows(); @@ -82,7 +82,7 @@ QVariant AppOutputChildModel::data(const QModelIndex &index, int role) const AppOutputParentModel::Run *AppOutputParentModel::run(int row) { - if (row < static_cast(m_runs.size()) && row >= 0) + if (std::cmp_less(row, m_runs.size()) && row >= 0) return &m_runs.at(row); return nullptr; @@ -156,15 +156,15 @@ void AppOutputParentModel::resetModel() int AppOutputParentModel::messageCount(int row) const { - if (row < static_cast(m_runs.size()) && row >= 0) - return m_runs.at(row).messages.size(); + if (std::cmp_less(row, m_runs.size()) && row >= 0) + return static_cast(m_runs.at(row).messages.size()); return 0; } int AppOutputParentModel::rowCount(const QModelIndex &) const { - return m_runs.size(); + return static_cast(m_runs.size()); } QHash AppOutputParentModel::roleNames() const @@ -177,8 +177,8 @@ QHash AppOutputParentModel::roleNames() const QVariant AppOutputParentModel::runData(int runIdx, int msgIdx, int role) const { - if (runIdx < static_cast(m_runs.size()) && runIdx >= 0) { - if (msgIdx < static_cast(m_runs.at(runIdx).messages.size()) && msgIdx >= 0) { + if (std::cmp_less(runIdx, m_runs.size()) && runIdx >= 0) { + if (std::cmp_less(msgIdx, m_runs.at(runIdx).messages.size()) && msgIdx >= 0) { if (role == AppOutputChildModel::MessageRole) return m_runs.at(runIdx).messages.at(msgIdx).message; else if (role == AppOutputChildModel::ColorRole) { diff --git a/src/plugins/qmldesigner/components/toolbar/messagemodel.cpp b/src/plugins/qmldesigner/components/toolbar/messagemodel.cpp index e0a2fa9b2d8..ae2755a603e 100644 --- a/src/plugins/qmldesigner/components/toolbar/messagemodel.cpp +++ b/src/plugins/qmldesigner/components/toolbar/messagemodel.cpp @@ -46,7 +46,7 @@ void MessageModel::jumpToCode(const QVariant &index) { bool ok = false; if (int idx = index.toInt(&ok); ok) { - if (idx >= 0 && idx < static_cast(m_tasks.size())) { + if (idx >= 0 && std::cmp_less(idx, m_tasks.size())) { // TODO: // - Check why this does not jump to line/column // - Only call this when sure that the task, file row etc are valid. @@ -63,7 +63,7 @@ void MessageModel::jumpToCode(const QVariant &index) int MessageModel::rowCount(const QModelIndex &) const { - return m_tasks.size(); + return static_cast(m_tasks.size()); } QHash MessageModel::roleNames() const @@ -116,7 +116,7 @@ void MessageModel::addCategory(const ProjectExplorer::TaskCategory &category) void MessageModel::addTask(const ProjectExplorer::Task &task) { - int at = m_tasks.size(); + int at = static_cast(m_tasks.size()); beginInsertRows(QModelIndex(), at, at); m_tasks.push_back(task); endInsertRows(); @@ -125,7 +125,7 @@ void MessageModel::addTask(const ProjectExplorer::Task &task) void MessageModel::removeTask(const ProjectExplorer::Task &task) { - for (int i = 0; i < static_cast(m_tasks.size()); i++) { + for (int i = 0; std::cmp_less(i, m_tasks.size()); i++) { if (m_tasks.at(i) == task) { beginRemoveRows(QModelIndex(), i, i); m_tasks.erase(m_tasks.begin() + i); From 937abac84af67aea72c36092cf21458221f4992b Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 22 Aug 2024 15:51:29 +0200 Subject: [PATCH 079/193] QmlDesigner: Fix DETACH_DISABLED_VIEWS We also have to ignore the action when checking for enabled. Task-number: QDS-13442 Change-Id: I67f78bfa55a985bf2c24187d6f832638e65d6bf2 Reviewed-by: Marco Bubke --- .../qmldesigner/designercore/include/abstractview.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/designercore/include/abstractview.h index f696f597c61..f1046bfd55b 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/designercore/include/abstractview.h @@ -284,7 +284,14 @@ public: using OperationBlock = std::function; bool executeInTransaction(const QByteArray &identifier, const OperationBlock &lambda); - bool isEnabled() const { return m_visible && (hasWidget() ? m_action->isChecked() : true); } + bool isEnabled() const + { +#ifdef DETACH_DISABLED_VIEWS + return m_visible && (hasWidget() ? m_action->isChecked() : true); +#else + return m_visible; +#endif + } void setVisibility(bool visible) { m_visible = visible; } From 2894226b398aac326475e261bb10af1da3b2381c Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 22 Aug 2024 14:15:49 +0300 Subject: [PATCH 080/193] QmlDesigner: Prevent deadlock in drag handling in item library model->startDrag() starts a new event loop and doesn't exit until the drag is over, so in the old implementation m_itemToDrag was not cleared until the drag was complete. However, in some cases it is possible to receive another move event while drag is still ongoing, which would then get interpreted as start of another drag as m_itemToDrag was still valid, causing nested drag event loops, which caused a deadlock in gui thread. This issue is prevented by clearing m_itemToDrag before drag starts. Fixes: QDS-13380 Change-Id: I6395949998ede4bae08b286d3ab4a1575be82551 Reviewed-by: Mahmoud Badri --- .../qmldesigner/components/itemlibrary/itemlibrarywidget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index c0328afcc77..749701f508d 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -85,6 +85,8 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event) QMouseEvent *me = static_cast(event); if ((me->globalPosition().toPoint() - m_dragStartPoint).manhattanLength() > 10) { ItemLibraryEntry entry = m_itemToDrag.value(); + m_itemToDrag = {}; + // For drag to be handled correctly, we must have the component properly imported // beforehand, so we import the module immediately when the drag starts if (!entry.requiredImport().isEmpty() @@ -99,8 +101,6 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event) entry.libraryEntryIconPath()), this); } - - m_itemToDrag = {}; } } } else if (event->type() == QMouseEvent::MouseButtonRelease) { From 8d76dd2b4990610c11499b5f857c948e5eb5075f Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Thu, 22 Aug 2024 22:58:14 +0300 Subject: [PATCH 081/193] QmlDesigner: Disable effect composer in QtCreator's design mode Effect composer is a QDS feature. Fixes: QDS-13424 Change-Id: I655364a0e34acebf23cfba9550171af5b1953ef8 Reviewed-by: Thomas Hartmann Reviewed-by: Miikka Heikkinen --- .../assetsLibraryQmlSources/AssetsContextMenu.qml | 1 + src/plugins/effectcomposer/effectcomposerplugin.cpp | 3 ++- .../components/assetslibrary/assetslibrarywidget.cpp | 3 +++ .../qmldesigner/components/componentcore/groupitemaction.cpp | 1 + .../components/componentcore/modelnodecontextmenu_helper.h | 5 ++++- 5 files changed, 11 insertions(+), 2 deletions(-) diff --git a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsContextMenu.qml b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsContextMenu.qml index 3402c56aa8c..40cdac85bbb 100644 --- a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsContextMenu.qml +++ b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsContextMenu.qml @@ -125,6 +125,7 @@ StudioControls.Menu { text: qsTr("Edit in Effect Composer") visible: root.__fileIndex && root.__selectedAssetPathsList.length === 1 && root.assetsModel.allFilePathsAreComposedEffects(root.__selectedAssetPathsList) + && root.rootView.canCreateEffects() height: editInEffectComposerItem.visible ? editInEffectComposerItem.implicitHeight : 0 onTriggered: AssetsLibraryBackend.rootView.openEffectComposer(root.__selectedAssetPathsList[0]) } diff --git a/src/plugins/effectcomposer/effectcomposerplugin.cpp b/src/plugins/effectcomposer/effectcomposerplugin.cpp index be37b1c6c42..13c29bb943d 100644 --- a/src/plugins/effectcomposer/effectcomposerplugin.cpp +++ b/src/plugins/effectcomposer/effectcomposerplugin.cpp @@ -4,6 +4,7 @@ #include #include +#include #include @@ -12,7 +13,7 @@ namespace EffectComposer { static bool enableEffectComposer() { - return true; + return Core::ICore::isQtDesignStudio(); } class EffectComposerPlugin : public ExtensionSystem::IPlugin diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp index 3bd8b468407..40c1c68d356 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp @@ -203,6 +203,9 @@ bool AssetsLibraryWidget::createNewEffect(const QString &effectPath, bool openIn bool AssetsLibraryWidget::canCreateEffects() const { + if (!Core::ICore::isQtDesignStudio()) + return false; + #ifdef LICENSECHECKER return checkLicense() == FoundLicense::enterprise; #else diff --git a/src/plugins/qmldesigner/components/componentcore/groupitemaction.cpp b/src/plugins/qmldesigner/components/componentcore/groupitemaction.cpp index 69fb52e264a..5028d1d5c03 100644 --- a/src/plugins/qmldesigner/components/componentcore/groupitemaction.cpp +++ b/src/plugins/qmldesigner/components/componentcore/groupitemaction.cpp @@ -4,6 +4,7 @@ #include "groupitemaction.h" #include "designermcumanager.h" +#include "modelnodeoperations.h" #include "nodeabstractproperty.h" #include "nodelistproperty.h" diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h index e728f54adae..5affb7adf8d 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodecontextmenu_helper.h @@ -3,7 +3,6 @@ #pragma once -#include "modelnodeoperations.h" #include "abstractaction.h" #include "bindingproperty.h" #include "abstractactiongroup.h" @@ -12,6 +11,7 @@ #include #include +#include #include @@ -137,6 +137,9 @@ inline bool singleSelectionView3D(const SelectionContext &selectionState) inline bool singleSelectionEffectComposer(const SelectionContext &selectionState) { + if (!Core::ICore::isQtDesignStudio()) + return false; + if (selectionState.hasSingleSelectedModelNode()) { QmlItemNode targetNode = selectionState.currentSingleSelectedNode(); return targetNode.isEffectItem(); From b44fa31655a7a8a6f2178ffeac3bc7c413a82d53 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Fri, 23 Aug 2024 11:23:11 +0000 Subject: [PATCH 082/193] QmlDesigner: Remove initial reparenting of all items to root item This reverts commit a53ebfcc441013ba06b69b89a3dd2b113fcbc26a. This is reverting a revert. Reason for revert: The revert did fix the issue in first glance, but was not the proper fix and only hid the most obvious side effect of the issue. Task-number: QDS-13294 Change-Id: Ief08cf4ffe4944522a315f0ad999c39ab552bb1f Reviewed-by: Miikka Heikkinen --- .../qml2puppet/qml2puppet/instances/quickitemnodeinstance.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.cpp b/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.cpp index 945c66f31d7..87ce62e61d4 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/quickitemnodeinstance.cpp @@ -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); } From 626572fa732e01d73c8649276380b6a3d12e170a Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 23 Aug 2024 13:33:25 +0300 Subject: [PATCH 083/193] QmlDesigner: Fix binding properties in material and texture editors Binding properties were handled incorrectly when removing or changing property value. This issue was previously fixed in property view (e2e53896f990b8b955d20bce731640fc74007a38). The same fix was adapted for material and texture editors. Fixes: QDS-13425 Change-Id: I78e14e1bef9086e00df3f9812c2a645d0acfbafb Reviewed-by: Mahmoud Badri --- .../materialeditorqmlbackend.cpp | 7 ++++ .../materialeditor/materialeditorqmlbackend.h | 1 + .../materialeditor/materialeditorview.cpp | 28 +++++++++++---- .../textureeditor/textureeditorqmlbackend.cpp | 7 ++++ .../textureeditor/textureeditorqmlbackend.h | 1 + .../textureeditor/textureeditorview.cpp | 34 ++++++++++++------- 6 files changed, 60 insertions(+), 18 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.cpp index d2338ce280f..fc486bf1db0 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.cpp @@ -149,6 +149,13 @@ void MaterialEditorQmlBackend::setValue(const QmlObjectNode &, } } +void MaterialEditorQmlBackend::setExpression(PropertyNameView propName, const QString &exp) +{ + PropertyEditorValue *propertyValue = propertyValueForName(QString::fromUtf8(propName)); + if (propertyValue) + propertyValue->setExpression(exp); +} + QQmlContext *MaterialEditorQmlBackend::context() const { return m_quickWidget->rootContext(); diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.h b/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.h index c8dc64b045f..249f073de03 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.h +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.h @@ -37,6 +37,7 @@ public: void setup(const QmlObjectNode &selectedMaterialNode, const QString &stateName, const QUrl &qmlSpecificsFile, MaterialEditorView *materialEditor); void setValue(const QmlObjectNode &fxObjectNode, PropertyNameView name, const QVariant &value); + void setExpression(PropertyNameView propName, const QString &exp); QQmlContext *context() const; MaterialEditorContextObject *contextObject() const; diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index 4980a20bcc4..32af9bc9145 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -757,7 +757,24 @@ void MaterialEditorView::propertiesRemoved(const QList &proper m_qmlBackEnd->contextObject()->setHasAliasExport(QmlObjectNode(m_selectedMaterial).isAliasExported()); if (node == m_selectedMaterial || QmlObjectNode(m_selectedMaterial).propertyChangeForCurrentState() == node) { - setValue(m_selectedMaterial, property.name(), QmlObjectNode(m_selectedMaterial).instanceValue(property.name())); + m_locked = true; + + const PropertyName propertyName = property.name().toByteArray(); + PropertyName convertedpropertyName = propertyName; + + convertedpropertyName.replace('.', '_'); + + PropertyEditorValue *value = m_qmlBackEnd->propertyValueForName( + QString::fromUtf8(convertedpropertyName)); + + if (value) { + value->resetValue(); + m_qmlBackEnd + ->setValue(m_selectedMaterial, + propertyName, + QmlObjectNode(m_selectedMaterial).instanceValue(propertyName)); + } + m_locked = false; changed = true; } @@ -813,11 +830,10 @@ void MaterialEditorView::bindingPropertiesChanged(const QList & if (node == m_selectedMaterial || QmlObjectNode(m_selectedMaterial).propertyChangeForCurrentState() == node) { if (property.isDynamic()) m_dynamicPropertiesModel->updateItem(property); - if (QmlObjectNode(m_selectedMaterial).modelNode().property(property.name()).isBindingProperty()) - setValue(m_selectedMaterial, property.name(), QmlObjectNode(m_selectedMaterial).instanceValue(property.name())); - else - setValue(m_selectedMaterial, property.name(), QmlObjectNode(m_selectedMaterial).modelValue(property.name())); - + m_locked = true; + QString exp = QmlObjectNode(m_selectedMaterial).bindingProperty(property.name()).expression(); + m_qmlBackEnd->setExpression(property.name(), exp); + m_locked = false; changed = true; } diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp index 57eb7237d47..6afe6deb75f 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp @@ -155,6 +155,13 @@ void TextureEditorQmlBackend::setValue(const QmlObjectNode &, } } +void TextureEditorQmlBackend::setExpression(PropertyNameView propName, const QString &exp) +{ + PropertyEditorValue *propertyValue = propertyValueForName(QString::fromUtf8(propName)); + if (propertyValue) + propertyValue->setExpression(exp); +} + QQmlContext *TextureEditorQmlBackend::context() const { return m_quickWidget->rootContext(); diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h index 954017c7987..4c7ecd75083 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.h @@ -38,6 +38,7 @@ public: void setup(const QmlObjectNode &selectedTextureNode, const QString &stateName, const QUrl &qmlSpecificsFile, TextureEditorView *textureEditor); void setValue(const QmlObjectNode &fxObjectNode, PropertyNameView name, const QVariant &value); + void setExpression(PropertyNameView propName, const QString &exp); QQmlContext *context() const; TextureEditorContextObject *contextObject() const; diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp index 14e3fa75f00..2f0a92f253a 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp @@ -584,9 +584,24 @@ void TextureEditorView::propertiesRemoved(const QList &propert if (node.metaInfo().property(property.name()).propertyType().isUrl()) { resetPuppet(); } else { - setValue(m_selectedTexture, - propertyName, - QmlObjectNode(m_selectedTexture).instanceValue(propertyName)); + m_locked = true; + + const PropertyName propertyName = property.name().toByteArray(); + PropertyName convertedpropertyName = propertyName; + + convertedpropertyName.replace('.', '_'); + + PropertyEditorValue *value = m_qmlBackEnd->propertyValueForName( + QString::fromUtf8(convertedpropertyName)); + + if (value) { + value->resetValue(); + m_qmlBackEnd + ->setValue(m_selectedTexture, + propertyName, + QmlObjectNode(m_selectedTexture).instanceValue(propertyName)); + } + m_locked = false; } } @@ -642,15 +657,10 @@ void TextureEditorView::bindingPropertiesChanged(const QList &p if (node == m_selectedTexture || QmlObjectNode(m_selectedTexture).propertyChangeForCurrentState() == node) { if (property.isDynamic()) m_dynamicPropertiesModel->updateItem(property); - if (QmlObjectNode(m_selectedTexture).modelNode().property(propertyName).isBindingProperty()) { - setValue(m_selectedTexture, - propertyName, - QmlObjectNode(m_selectedTexture).instanceValue(propertyName)); - } else { - setValue(m_selectedTexture, - propertyName, - QmlObjectNode(m_selectedTexture).modelValue(propertyName)); - } + m_locked = true; + QString exp = QmlObjectNode(m_selectedTexture).bindingProperty(property.name()).expression(); + m_qmlBackEnd->setExpression(property.name(), exp); + m_locked = false; } if (propertyName == "materials" From 133554186e4888f623588131bc77bea9cc640a3e Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 23 Aug 2024 15:01:34 +0300 Subject: [PATCH 084/193] EffectComposer: Fix effect composer view layout We shouldn't use anchors on an item that is part of the layout, so inserted an Item for root item and moved all non-Item elements there, as well as the DropArea that needs the anchors. Change-Id: I722eca191b092b2b2b65df7b1b59b881688dcc59 Reviewed-by: Mahmoud Badri --- .../EffectComposer.qml | 534 +++++++++--------- 1 file changed, 269 insertions(+), 265 deletions(-) diff --git a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposer.qml b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposer.qml index c32ed10a36d..16525678be8 100644 --- a/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposer.qml +++ b/share/qtcreator/qmldesigner/effectComposerQmlSources/EffectComposer.qml @@ -10,11 +10,9 @@ import StudioControls as StudioControls import StudioTheme as StudioTheme import EffectComposerBackend -ColumnLayout { +Item { id: root - spacing: 1 - readonly property var backendModel: EffectComposerBackend.effectComposerModel property var draggedSec: null @@ -36,281 +34,26 @@ ColumnLayout { // Invoked from C++ side before resetting the model to store current expanded state of nodes function storeExpandStates() { - expandStates = new Map() + root.expandStates = new Map() for (let i = 0; i < repeater.count; ++i) { var curItem = repeater.itemAt(i) - expandStates.set(curItem.caption, curItem.expanded) + root.expandStates.set(curItem.caption, curItem.expanded) } } // Invoked after model has been reset to restore expanded state for nodes function restoreExpandStates() { - if (expandStates) { + if (root.expandStates) { for (let i = 0; i < repeater.count; ++i) { var curItem = repeater.itemAt(i) - if (expandStates.has(curItem.caption)) - curItem.expanded = expandStates.get(curItem.caption) + if (root.expandStates.has(curItem.caption)) + curItem.expanded = root.expandStates.get(curItem.caption) } - expandStates = null + root.expandStates = null } } - Connections { - target: root.backendModel - function onIsEmptyChanged() { - if (root.backendModel.isEmpty) - saveAsDialog.close() - } - } - - SaveAsDialog { - id: saveAsDialog - anchors.centerIn: parent - } - - SaveChangesDialog { - id: saveChangesDialog - anchors.centerIn: parent - - onSave: { - if (root.backendModel.currentComposition === "") { - // if current composition is unsaved, show save as dialog and clear afterwards - saveAsDialog.clearOnClose = true - saveAsDialog.open() - } else { - root.onSaveChangesCallback() - } - } - - onDiscard: { - root.onSaveChangesCallback() - } - } - - ConfirmClearAllDialog { - id: confirmClearAllDialog - anchors.centerIn: parent - } - - EffectComposerTopBar { - Layout.fillWidth: true - - onAddClicked: { - root.onSaveChangesCallback = () => { root.backendModel.clear(true) } - - if (root.backendModel.hasUnsavedChanges) - saveChangesDialog.open() - else - root.backendModel.clear(true) - } - - onSaveClicked: { - let name = root.backendModel.currentComposition - - if (name === "") - saveAsDialog.open() - else - root.backendModel.saveComposition(name) - } - - onSaveAsClicked: saveAsDialog.open() - - onAssignToSelectedClicked: { - root.backendModel.assignToSelected() - } - } - - SplitView { - id: splitView - - Layout.fillWidth: true - Layout.fillHeight: true - - orientation: root.width > root.height ? Qt.Horizontal : Qt.Vertical - - handle: Rectangle { - implicitWidth: splitView.orientation === Qt.Horizontal ? StudioTheme.Values.splitterThickness : splitView.width - implicitHeight: splitView.orientation === Qt.Horizontal ? splitView.height : StudioTheme.Values.splitterThickness - color: T.SplitHandle.pressed ? StudioTheme.Values.themeSliderHandleInteraction - : (T.SplitHandle.hovered ? StudioTheme.Values.themeSliderHandleHover - : "transparent") - } - - EffectComposerPreview { - mainRoot: root - - SplitView.minimumWidth: 250 - SplitView.minimumHeight: 200 - SplitView.preferredWidth: 300 - SplitView.preferredHeight: 300 - Layout.fillWidth: true - Layout.fillHeight: true - - FrameAnimation { - id: previewFrameTimer - running: true - paused: !previewAnimationRunning - } - } - - Column { - spacing: 1 - - SplitView.minimumWidth: 250 - SplitView.minimumHeight: 100 - - Component.onCompleted: HelperWidgets.Controller.mainScrollView = scrollView - - Rectangle { - width: parent.width - height: StudioTheme.Values.toolbarHeight - color: StudioTheme.Values.themeToolbarBackground - - EffectNodesComboBox { - id: nodesComboBox - - mainRoot: root - - anchors.verticalCenter: parent.verticalCenter - x: 5 - width: parent.width - 50 - } - - HelperWidgets.AbstractButton { - anchors.right: parent.right - anchors.rightMargin: 5 - anchors.verticalCenter: parent.verticalCenter - - style: StudioTheme.Values.viewBarButtonStyle - buttonIcon: StudioTheme.Constants.clearList_medium - tooltip: qsTr("Remove all effect nodes.") - enabled: root.backendModel ? !root.backendModel.isEmpty : false - - onClicked: { - if (root.backendModel.hasUnsavedChanges) - confirmClearAllDialog.open() - else - root.backendModel.clear() - } - } - - HelperWidgets.AbstractButton { - anchors.right: parent.right - anchors.rightMargin: 5 - anchors.verticalCenter: parent.verticalCenter - - style: StudioTheme.Values.viewBarButtonStyle - buttonIcon: StudioTheme.Constants.code - tooltip: qsTr("Open Shader in Code Editor.") - visible: false // TODO: to be implemented - - onClicked: {} // TODO - } - } - - Item { - width: parent.width - height: parent.height - y - - HelperWidgets.ScrollView { - id: scrollView - - readonly property int dragScrollMargin: 50 - - anchors.fill: parent - clip: true - interactive: !HelperWidgets.Controller.contextMenuOpened - - onContentHeightChanged: { - // Expand states are stored before full model reset. - // Content height change indicates the model has been updated after full - // reset, so we restore expand states if any are stored. - root.restoreExpandStates() - - // If content height change was because a recent node addition, we want to - // scroll to the end of the content so the newly added item is visible. - if (nodesComboBox.nodeJustAdded && scrollView.contentItem.height > scrollView.height) { - let lastItemH = repeater.itemAt(repeater.count - 1).height - scrollView.contentY = scrollView.contentItem.height - lastItemH - nodesComboBox.nodeJustAdded = false - } - } - - Column { - id: nodesCol - width: scrollView.width - spacing: 1 - - Repeater { - id: repeater - - width: parent.width - model: root.backendModel - - onCountChanged: { - HelperWidgets.Controller.setCount("EffectComposer", repeater.count) - } - - delegate: EffectCompositionNode { - width: parent.width - modelIndex: index - - property bool wasExpanded: false - - Behavior on y { - id: dragAnimation - PropertyAnimation { - duration: 300 - easing.type: Easing.InOutQuad - } - } - - onStartDrag: (section) => { - root.draggedSec = section - root.moveFromIdx = index - // We only need to animate non-dragged sections - dragAnimation.enabled = false - wasExpanded = expanded - expanded = false - highlightBorder = true - root.secsY = [] - } - - onStopDrag: { - if (root.secsY.length !== 0) { - if (root.moveFromIdx === root.moveToIdx) - root.draggedSec.y = root.secsY[root.moveFromIdx] - else - root.backendModel.moveNode(root.moveFromIdx, root.moveToIdx) - } - - highlightBorder = false - root.draggedSec = null - expanded = wasExpanded - dragAnimation.enabled = true - } - } - } // Repeater - } // Column - } // ScrollView - - Text { - text: root.backendModel ? root.backendModel.isEnabled - ? qsTr("Add an effect node to start") - : qsTr("Effect Composer is disabled on MCU projects") - : "" - color: StudioTheme.Values.themeTextColor - font.pixelSize: StudioTheme.Values.baseFontSize - - anchors.centerIn: parent - - visible: root.backendModel ? root.backendModel.isEmpty : false - } - } // Item - } // Column - } // SplitView - function handleDragMove() { dragTimer.stop() if (root.secsY.length === 0) { @@ -362,6 +105,43 @@ ColumnLayout { } } + Connections { + target: root.backendModel + function onIsEmptyChanged() { + if (root.backendModel.isEmpty) + saveAsDialog.close() + } + } + + SaveAsDialog { + id: saveAsDialog + anchors.centerIn: parent + } + + SaveChangesDialog { + id: saveChangesDialog + anchors.centerIn: parent + + onSave: { + if (root.backendModel.currentComposition === "") { + // if current composition is unsaved, show save as dialog and clear afterwards + saveAsDialog.clearOnClose = true + saveAsDialog.open() + } else { + root.onSaveChangesCallback() + } + } + + onDiscard: { + root.onSaveChangesCallback() + } + } + + ConfirmClearAllDialog { + id: confirmClearAllDialog + anchors.centerIn: parent + } + Connections { id: dragConnection target: root.draggedSec @@ -382,7 +162,231 @@ ColumnLayout { root.draggedSec.y = targetY root.handleDragMove() } - } // Timer + } + + ColumnLayout { + anchors.fill: parent + + spacing: 1 + + EffectComposerTopBar { + Layout.fillWidth: true + + onAddClicked: { + root.onSaveChangesCallback = () => { root.backendModel.clear(true) } + + if (root.backendModel.hasUnsavedChanges) + saveChangesDialog.open() + else + root.backendModel.clear(true) + } + + onSaveClicked: { + let name = root.backendModel.currentComposition + + if (name === "") + saveAsDialog.open() + else + root.backendModel.saveComposition(name) + } + + onSaveAsClicked: saveAsDialog.open() + + onAssignToSelectedClicked: { + root.backendModel.assignToSelected() + } + } + + SplitView { + id: splitView + + Layout.fillWidth: true + Layout.fillHeight: true + + orientation: root.width > root.height ? Qt.Horizontal : Qt.Vertical + + handle: Rectangle { + implicitWidth: splitView.orientation === Qt.Horizontal ? StudioTheme.Values.splitterThickness : splitView.width + implicitHeight: splitView.orientation === Qt.Horizontal ? splitView.height : StudioTheme.Values.splitterThickness + color: T.SplitHandle.pressed ? StudioTheme.Values.themeSliderHandleInteraction + : (T.SplitHandle.hovered ? StudioTheme.Values.themeSliderHandleHover + : "transparent") + } + + EffectComposerPreview { + mainRoot: root + + SplitView.minimumWidth: 250 + SplitView.minimumHeight: 200 + SplitView.preferredWidth: 300 + SplitView.preferredHeight: 300 + Layout.fillWidth: true + Layout.fillHeight: true + + FrameAnimation { + id: previewFrameTimer + running: true + paused: !root.previewAnimationRunning + } + } + + Column { + spacing: 1 + + SplitView.minimumWidth: 250 + SplitView.minimumHeight: 100 + + Component.onCompleted: HelperWidgets.Controller.mainScrollView = scrollView + + Rectangle { + width: parent.width + height: StudioTheme.Values.toolbarHeight + color: StudioTheme.Values.themeToolbarBackground + + EffectNodesComboBox { + id: nodesComboBox + + mainRoot: root + + anchors.verticalCenter: parent.verticalCenter + x: 5 + width: parent.width - 50 + } + + HelperWidgets.AbstractButton { + anchors.right: parent.right + anchors.rightMargin: 5 + anchors.verticalCenter: parent.verticalCenter + + style: StudioTheme.Values.viewBarButtonStyle + buttonIcon: StudioTheme.Constants.clearList_medium + tooltip: qsTr("Remove all effect nodes.") + enabled: root.backendModel ? !root.backendModel.isEmpty : false + + onClicked: { + if (root.backendModel.hasUnsavedChanges) + confirmClearAllDialog.open() + else + root.backendModel.clear() + } + } + + HelperWidgets.AbstractButton { + anchors.right: parent.right + anchors.rightMargin: 5 + anchors.verticalCenter: parent.verticalCenter + + style: StudioTheme.Values.viewBarButtonStyle + buttonIcon: StudioTheme.Constants.code + tooltip: qsTr("Open Shader in Code Editor.") + visible: false // TODO: to be implemented + + onClicked: {} // TODO + } + } + + Item { + width: parent.width + height: parent.height - y + + HelperWidgets.ScrollView { + id: scrollView + + readonly property int dragScrollMargin: 50 + + anchors.fill: parent + clip: true + interactive: !HelperWidgets.Controller.contextMenuOpened + + onContentHeightChanged: { + // Expand states are stored before full model reset. + // Content height change indicates the model has been updated after full + // reset, so we restore expand states if any are stored. + root.restoreExpandStates() + + // If content height change was because a recent node addition, we want to + // scroll to the end of the content so the newly added item is visible. + if (nodesComboBox.nodeJustAdded && scrollView.contentItem.height > scrollView.height) { + let lastItemH = repeater.itemAt(repeater.count - 1).height + scrollView.contentY = scrollView.contentItem.height - lastItemH + nodesComboBox.nodeJustAdded = false + } + } + + Column { + id: nodesCol + width: scrollView.width + spacing: 1 + + Repeater { + id: repeater + + width: parent.width + model: root.backendModel + + onCountChanged: { + HelperWidgets.Controller.setCount("EffectComposer", repeater.count) + } + + delegate: EffectCompositionNode { + width: parent.width + modelIndex: index + + property bool wasExpanded: false + + Behavior on y { + id: dragAnimation + PropertyAnimation { + duration: 300 + easing.type: Easing.InOutQuad + } + } + + onStartDrag: (section) => { + root.draggedSec = section + root.moveFromIdx = index + // We only need to animate non-dragged sections + dragAnimation.enabled = false + wasExpanded = expanded + expanded = false + highlightBorder = true + root.secsY = [] + } + + onStopDrag: { + if (root.secsY.length !== 0) { + if (root.moveFromIdx === root.moveToIdx) + root.draggedSec.y = root.secsY[root.moveFromIdx] + else + root.backendModel.moveNode(root.moveFromIdx, root.moveToIdx) + } + + highlightBorder = false + root.draggedSec = null + expanded = wasExpanded + dragAnimation.enabled = true + } + } + } // Repeater + } // Column + } // ScrollView + + Text { + text: root.backendModel ? root.backendModel.isEnabled + ? qsTr("Add an effect node to start") + : qsTr("Effect Composer is disabled on MCU projects") + : "" + color: StudioTheme.Values.themeTextColor + font.pixelSize: StudioTheme.Values.baseFontSize + + anchors.centerIn: parent + + visible: root.backendModel ? root.backendModel.isEmpty : false + } + } // Item + } // Column + } // SplitView + } // ColumnLayout DropArea { id: dropArea From ee78ccc7dc8fe4b8c7577f21d3232347f9c35b16 Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Fri, 2 Aug 2024 18:19:21 +0300 Subject: [PATCH 085/193] QmlDesigner: Add a camera view to 3d editor view Task-number: QDS-13275 Fixes: QDS-13352 Change-Id: I9b583a273a0aa7fc0d2c72b274fca243cc65546e Reviewed-by: Miikka Heikkinen --- .../interfaces/nodeinstanceglobal.h | 1 + src/plugins/qmldesigner/CMakeLists.txt | 1 + .../edit3d/cameraviewwidgetaction.cpp | 105 +++++++++++ .../edit3d/cameraviewwidgetaction.h | 46 +++++ .../components/edit3d/edit3dactions.cpp | 25 +++ .../components/edit3d/edit3dactions.h | 8 + .../components/edit3d/edit3dview.cpp | 50 ++++-- .../components/edit3d/edit3dview.h | 1 + src/tools/qml2puppet/editor3d_qt6.qrc | 1 + .../qml2puppet/mockfiles/qt6/CameraView.qml | 164 ++++++++++++++++++ .../qml2puppet/mockfiles/qt6/EditView3D.qml | 37 ++++ .../qml2puppet/editor3d/generalhelper.cpp | 32 ++++ .../qml2puppet/editor3d/generalhelper.h | 14 ++ .../qt5informationnodeinstanceserver.cpp | 34 ++++ .../qt5informationnodeinstanceserver.h | 1 + 15 files changed, 503 insertions(+), 17 deletions(-) create mode 100644 src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp create mode 100644 src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.h create mode 100644 src/tools/qml2puppet/mockfiles/qt6/CameraView.qml diff --git a/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h b/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h index d5647a0740b..a05d9681f64 100644 --- a/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h +++ b/src/libs/qmlpuppetcommunication/interfaces/nodeinstanceglobal.h @@ -44,6 +44,7 @@ enum class View3DActionType { ShowSelectionBox, ShowIconGizmo, ShowCameraFrustum, + CameraViewMode, ShowParticleEmitter, Edit3DParticleModeToggle, ParticlesPlay, diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index a2e9fc943a7..7c2f81c10ab 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -652,6 +652,7 @@ extend_qtc_plugin(QmlDesigner extend_qtc_plugin(QmlDesigner SOURCES_PREFIX components/edit3d SOURCES + cameraviewwidgetaction.cpp cameraviewwidgetaction.h edit3dview.cpp edit3dview.h edit3dviewconfig.h edit3dwidget.cpp edit3dwidget.h diff --git a/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp b/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp new file mode 100644 index 00000000000..8f9e025dc0a --- /dev/null +++ b/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp @@ -0,0 +1,105 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +#include "cameraviewwidgetaction.h" + +#include +#include + +#include + +namespace QmlDesigner { + +struct CameraActionsModel::DataItem +{ + QString name; + QString tooltip; + QString mode; +}; + +const QList CameraActionsModel::m_data{ + {tr("Hide Camera View"), tr("Never show the camera view."), "CameraOff"}, + {tr("Show Selected Camera View"), + tr("Show the selected camera in the camera view."), + "ShowSelectedCamera"}, + {tr("Always Show Camera View"), + tr("Show the last selected camera in the camera view."), + "AlwaysShowCamera"}, +}; + +CameraViewWidgetAction::CameraViewWidgetAction(QObject *parent) + : QWidgetAction(parent) +{ + QComboBox *defaultComboBox = new QComboBox(); + CameraActionsModel *comboBoxModel = new CameraActionsModel(defaultComboBox); + + defaultComboBox->setModel(comboBoxModel); + setDefaultWidget(defaultComboBox); + connect(defaultComboBox, &QComboBox::currentIndexChanged, this, [this] { + emit currentModeChanged(currentMode()); + }); +} + +QString CameraViewWidgetAction::currentMode() const +{ + QComboBox *defaultComboBox = qobject_cast(defaultWidget()); + QTC_ASSERT(defaultComboBox, return "CameraOff"); + + return defaultComboBox->currentData(CameraActionsModel::ModeRole).toString(); +} + +void CameraViewWidgetAction::setMode(const QString &mode) +{ + QComboBox *defaultComboBox = qobject_cast(defaultWidget()); + QTC_ASSERT(defaultComboBox, return); + defaultComboBox->setCurrentIndex(CameraActionsModel::modeIndex(mode)); +} + +QWidget *CameraViewWidgetAction::createWidget(QWidget *parent) +{ + QComboBox *defaultComboBox = qobject_cast(defaultWidget()); + QTC_ASSERT(defaultComboBox, return nullptr); + + QComboBox *newComboBox = new QComboBox(parent); + newComboBox->setModel(defaultComboBox->model()); + connect(defaultComboBox, &QComboBox::currentIndexChanged, newComboBox, &QComboBox::setCurrentIndex); + connect(newComboBox, &QComboBox::currentIndexChanged, defaultComboBox, &QComboBox::setCurrentIndex); + newComboBox->setCurrentIndex(defaultComboBox->currentIndex()); + return newComboBox; +} + +CameraActionsModel::CameraActionsModel(QObject *parent) + : QAbstractListModel(parent) +{} + +CameraActionsModel::~CameraActionsModel() = default; + +int CameraActionsModel::rowCount([[maybe_unused]] const QModelIndex &parent) const +{ + return m_data.size(); +} + +QVariant CameraActionsModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return {}; + + const DataItem &data = m_data.at(index.row()); + switch (role) { + case Qt::DisplayRole: + return data.name; + case Qt::ToolTipRole: + return data.tooltip; + case ExtendedDataRoles::ModeRole: + return data.mode; + default: + return {}; + } +} + +int CameraActionsModel::modeIndex(const QString &mode) +{ + int idx = Utils::indexOf(m_data, Utils::equal(&DataItem::mode, mode)); + return std::max(0, idx); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.h b/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.h new file mode 100644 index 00000000000..e368a41b032 --- /dev/null +++ b/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.h @@ -0,0 +1,46 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 +#pragma once + +#include +#include +#include + +namespace QmlDesigner { + +class CameraViewWidgetAction : public QWidgetAction +{ + Q_OBJECT + +public: + explicit CameraViewWidgetAction(QObject *parent = nullptr); + QString currentMode() const; + void setMode(const QString &mode); + +protected: + QWidget *createWidget(QWidget *parent) override; + +signals: + void currentModeChanged(QString); +}; + +class CameraActionsModel : public QAbstractListModel +{ + Q_DECLARE_TR_FUNCTIONS(CameraActionsModel) + +public: + enum ExtendedDataRoles { ModeRole = Qt::UserRole + 1 }; + + explicit CameraActionsModel(QObject *parent); + virtual ~CameraActionsModel(); + + int rowCount(const QModelIndex &parent = {}) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + static int modeIndex(const QString &mode); + +private: + struct DataItem; + static const QList m_data; +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp index 83299a485d5..272b5994193 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp @@ -3,6 +3,7 @@ #include "edit3dactions.h" +#include "cameraviewwidgetaction.h" #include "edit3dview.h" #include "indicatoractionwidget.h" #include "qmldesignerconstants.h" @@ -11,6 +12,7 @@ #include #include +#include namespace QmlDesigner { @@ -198,4 +200,27 @@ bool Edit3DIndicatorButtonAction::isEnabled(const SelectionContext &) const return m_buttonAction->isEnabled(); } +Edit3DCameraViewAction::Edit3DCameraViewAction(const QByteArray &menuId, + View3DActionType type, + Edit3DView *view) + : Edit3DAction(menuId, type, view, new Edit3DWidgetActionTemplate(new CameraViewWidgetAction(view))) +{ + CameraViewWidgetAction *widgetAction = qobject_cast(action()); + Q_ASSERT(widgetAction); + + QObject::connect(widgetAction, + &CameraViewWidgetAction::currentModeChanged, + view, + [this, edit3dview = std::move(view)](const QString &newState) { + edit3dview->emitView3DAction(actionType(), newState); + }); +} + +void Edit3DCameraViewAction::setMode(const QString &mode) +{ + CameraViewWidgetAction *widgetAction = qobject_cast(action()); + QTC_ASSERT(widgetAction, return); + widgetAction->setMode(mode); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dactions.h b/src/plugins/qmldesigner/components/edit3d/edit3dactions.h index 03aeb22902a..63c9d3b41e8 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dactions.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dactions.h @@ -150,4 +150,12 @@ private: Edit3DView *m_view = nullptr; }; +class Edit3DCameraViewAction : public Edit3DAction +{ +public: + Edit3DCameraViewAction(const QByteArray &menuId, View3DActionType type, Edit3DView *view); + + void setMode(const QString &mode); +}; + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index b971d828c50..9d9e9848ff0 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -45,6 +45,11 @@ #include #include +static const QByteArray operator""_actionId(const char *text, size_t size) +{ + return QString("QmlDesigner.Edit3D.%1").arg(QLatin1String(text, size)).toLatin1(); +} + namespace QmlDesigner { inline static QIcon contextIcon(const DesignerIcons::IconId &iconId) @@ -127,23 +132,24 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState) m_activeSplit = 0; } - const QString sceneKey = QStringLiteral("sceneInstanceId"); - const QString selectKey = QStringLiteral("selectionMode"); - const QString transformKey = QStringLiteral("transformMode"); - const QString perspectiveKey = QStringLiteral("usePerspective"); - const QString orientationKey = QStringLiteral("globalOrientation"); - const QString editLightKey = QStringLiteral("showEditLight"); - const QString gridKey = QStringLiteral("showGrid"); - const QString showLookAtKey = QStringLiteral("showLookAt"); - const QString selectionBoxKey = QStringLiteral("showSelectionBox"); - const QString iconGizmoKey = QStringLiteral("showIconGizmo"); - const QString cameraFrustumKey = QStringLiteral("showCameraFrustum"); - const QString particleEmitterKey = QStringLiteral("showParticleEmitter"); - const QString particlesPlayKey = QStringLiteral("particlePlay"); - const QString syncEnvBgKey = QStringLiteral("syncEnvBackground"); - const QString splitViewKey = QStringLiteral("splitView"); - const QString matOverrideKey = QStringLiteral("matOverride"); - const QString showWireframeKey = QStringLiteral("showWireframe"); + const QString sceneKey = QStringLiteral("sceneInstanceId"); + const QString selectKey = QStringLiteral("selectionMode"); + const QString transformKey = QStringLiteral("transformMode"); + const QString perspectiveKey = QStringLiteral("usePerspective"); + const QString orientationKey = QStringLiteral("globalOrientation"); + const QString editLightKey = QStringLiteral("showEditLight"); + const QString gridKey = QStringLiteral("showGrid"); + const QString showLookAtKey = QStringLiteral("showLookAt"); + const QString selectionBoxKey = QStringLiteral("showSelectionBox"); + const QString iconGizmoKey = QStringLiteral("showIconGizmo"); + const QString cameraFrustumKey = QStringLiteral("showCameraFrustum"); + const QString cameraViewModeKey = QStringLiteral("cameraViewMode"); + const QString particleEmitterKey = QStringLiteral("showParticleEmitter"); + const QString particlesPlayKey = QStringLiteral("particlePlay"); + const QString syncEnvBgKey = QStringLiteral("syncEnvBackground"); + const QString splitViewKey = QStringLiteral("splitView"); + const QString matOverrideKey = QStringLiteral("matOverride"); + const QString showWireframeKey = QStringLiteral("showWireframe"); if (sceneState.contains(sceneKey)) { qint32 newActiveScene = sceneState[sceneKey].value(); @@ -209,6 +215,11 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState) else m_showCameraFrustumAction->action()->setChecked(false); + if (sceneState.contains(cameraViewModeKey)) + m_cameraViewAction->setMode(sceneState[cameraViewModeKey].toString()); + else + m_cameraViewAction->setMode(""); + if (sceneState.contains(particleEmitterKey)) m_showParticleEmitterAction->action()->setChecked(sceneState[particleEmitterKey].toBool()); else @@ -1100,6 +1111,10 @@ void Edit3DView::createEdit3DActions() "Toggle between always showing the camera frustum visualization and only showing it " "when the camera is selected.")); + m_cameraViewAction = std::make_unique("CamerView"_actionId, + View3DActionType::CameraViewMode, + this); + m_showParticleEmitterAction = std::make_unique( QmlDesigner::Constants::EDIT3D_EDIT_SHOW_PARTICLE_EMITTER, View3DActionType::ShowParticleEmitter, @@ -1368,6 +1383,7 @@ void Edit3DView::createEdit3DActions() m_visibilityToggleActions << m_showSelectionBoxAction.get(); m_visibilityToggleActions << m_showIconGizmoAction.get(); m_visibilityToggleActions << m_showCameraFrustumAction.get(); + m_visibilityToggleActions << m_cameraViewAction.get(); m_visibilityToggleActions << m_showParticleEmitterAction.get(); createSyncEnvBackgroundAction(); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h index f0ebc69dddb..8560fd6b45a 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h @@ -177,6 +177,7 @@ private: std::unique_ptr m_showSelectionBoxAction; std::unique_ptr m_showIconGizmoAction; std::unique_ptr m_showCameraFrustumAction; + std::unique_ptr m_cameraViewAction; std::unique_ptr m_showParticleEmitterAction; std::unique_ptr m_particleViewModeAction; std::unique_ptr m_particlesPlayAction; diff --git a/src/tools/qml2puppet/editor3d_qt6.qrc b/src/tools/qml2puppet/editor3d_qt6.qrc index 85df241f162..e1de7a0903d 100644 --- a/src/tools/qml2puppet/editor3d_qt6.qrc +++ b/src/tools/qml2puppet/editor3d_qt6.qrc @@ -26,6 +26,7 @@ mockfiles/qt6/AutoScaleHelper.qml mockfiles/qt6/CameraFrustum.qml mockfiles/qt6/CameraGizmo.qml + mockfiles/qt6/CameraView.qml mockfiles/qt6/DirectionalDraggable.qml mockfiles/qt6/EditCameraController.qml mockfiles/qt6/EditView3D.qml diff --git a/src/tools/qml2puppet/mockfiles/qt6/CameraView.qml b/src/tools/qml2puppet/mockfiles/qt6/CameraView.qml new file mode 100644 index 00000000000..3bc67468099 --- /dev/null +++ b/src/tools/qml2puppet/mockfiles/qt6/CameraView.qml @@ -0,0 +1,164 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +import QtQuick +import QtQuick3D + +Item { + id: cameraView + + required property bool showCameraView + required property bool alwaysOn + property bool snapLeft: true + property Node targetNode + property size preferredSize + property size viewPortSize + property var activeScene + property var activeSceneEnvironment + property var preferredCamera + + width: loader.width + height: loader.height + anchors.bottom: parent.bottom + anchors.margins: 10 + visible: loader.active + + onTargetNodeChanged: loader.updateCamera() + onAlwaysOnChanged: loader.updateCamera() + onPreferredCameraChanged: loader.updateCamera() + onActiveSceneChanged: forceReload() + Component.onCompleted: loader.updateCamera() + + function forceReload() { + loader.forceDeactive = true + loader.oldCamera = null + loader.updateCamera() + loader.forceDeactive = false + } + + Loader { + id: loader + + property Camera camera + property Camera oldCamera + property bool forceDeactive: false + + active: !forceDeactive && (cameraView.alwaysOn || cameraView.showCameraView) && loader.camera + + function updateCamera() { + loader.camera = activeCamera() + } + + function activeCamera() { + if (cameraView.alwaysOn) { + if (_generalHelper.isCamera(cameraView.targetNode)) + return cameraView.targetNode + else if (loader.oldCamera) + return loader.oldCamera + else + return cameraView.preferredCamera + } else if (_generalHelper.isCamera(cameraView.targetNode)) { + return cameraView.targetNode + } + return null + } + + onCameraChanged: { + if (loader.camera) + loader.oldCamera = loader.camera + } + + sourceComponent: Rectangle { + id: cameraRect + + implicitWidth: view3D.dispSize.width + 2 + implicitHeight: view3D.dispSize.height + 2 + border.width: 1 + border.color: "lightslategray" + color: "black" + + View3D { + id: view3D + + readonly property bool isOrthographicCamera: _generalHelper.isOrthographicCamera(view3D.camera) + property size dispSize: calculateSize(cameraView.viewPortSize, cameraView.preferredSize) + readonly property real magnificationFactor: cameraView.viewPortSize.width === 0 + ? 1.0 + : (view3D.dispSize.width / cameraView.viewPortSize.width) + + transformOrigin: Item.Center + anchors.centerIn: parent + + camera: loader.camera + importScene: cameraView.activeScene + environment: cameraView.activeSceneEnvironment ?? defaultSceneEnvironment + + function calculateSize(viewPortSize: size, preferredSize : size){ + if (_generalHelper.fuzzyCompare(viewPortSize.width, 0) + || _generalHelper.fuzzyCompare(viewPortSize.height, 0)) + return Qt.size(0, 0) + + let aspectRatio = viewPortSize.height / viewPortSize.width + var calculatedHeight = preferredSize.width * aspectRatio + if (calculatedHeight <= preferredSize.height) + return Qt.size(preferredSize.width, calculatedHeight) + + var calculatedWidth = preferredSize.height / aspectRatio; + return Qt.size(calculatedWidth, preferredSize.height); + } + + states: [ + State { + name: "orthoCamera" + when: view3D.isOrthographicCamera + PropertyChanges { + target: view3D + + width: cameraView.viewPortSize.width + height: cameraView.viewPortSize.height + scale: view3D.magnificationFactor + } + }, + State { + name: "nonOrthoCamera" + when: !view3D.isOrthographicCamera + PropertyChanges { + target: view3D + + width: view3D.dispSize.width + height: view3D.dispSize.height + scale: 1.0 + } + } + ] + } + } + } + + SceneEnvironment { + id: defaultSceneEnvironment + + antialiasingMode: SceneEnvironment.MSAA + antialiasingQuality: SceneEnvironment.High + } + + states: [ + State { + name: "default" + when: cameraView.snapLeft + AnchorChanges { + target: cameraView + anchors.left: parent.left + anchors.right: undefined + } + }, + State { + name: "snapRight" + when: !cameraView.snapLeft + AnchorChanges { + target: cameraView + anchors.left: undefined + anchors.right: parent.right + } + } + ] +} diff --git a/src/tools/qml2puppet/mockfiles/qt6/EditView3D.qml b/src/tools/qml2puppet/mockfiles/qt6/EditView3D.qml index 751d21c0e8a..e159b532c34 100644 --- a/src/tools/qml2puppet/mockfiles/qt6/EditView3D.qml +++ b/src/tools/qml2puppet/mockfiles/qt6/EditView3D.qml @@ -40,6 +40,7 @@ Item { property bool splitView: false property bool flyMode: false property bool showCameraSpeed: false + property string cameraViewMode enum SelectionMode { Item, Group } enum TransformMode { Move, Rotate, Scale } @@ -72,6 +73,7 @@ Item { onShowSelectionBoxChanged: _generalHelper.storeToolState(sceneId, "showSelectionBox", showSelectionBox); onShowIconGizmoChanged: _generalHelper.storeToolState(sceneId, "showIconGizmo", showIconGizmo); onShowCameraFrustumChanged: _generalHelper.storeToolState(sceneId, "showCameraFrustum", showCameraFrustum); + onCameraViewModeChanged: _generalHelper.storeToolState(sceneId, "cameraViewMode", cameraViewMode) onShowParticleEmitterChanged: _generalHelper.storeToolState(sceneId, "showParticleEmitter", showParticleEmitter); onSelectionModeChanged: _generalHelper.storeToolState(sceneId, "selectionMode", selectionMode); onTransformModeChanged: _generalHelper.storeToolState(sceneId, "transformMode", transformMode); @@ -334,6 +336,11 @@ Item { else if (resetToDefault) showCameraFrustum = false; + if ("cameraViewMode" in toolStates) + cameraViewMode = toolStates.cameraViewMode + else if (resetToDefault) + cameraViewMode = "CameraOff" + if ("showParticleEmitter" in toolStates) showParticleEmitter = toolStates.showParticleEmitter; else if (resetToDefault) @@ -405,6 +412,7 @@ Item { _generalHelper.storeToolState(sceneId, "showSelectionBox", showSelectionBox) _generalHelper.storeToolState(sceneId, "showIconGizmo", showIconGizmo) _generalHelper.storeToolState(sceneId, "showCameraFrustum", showCameraFrustum) + _generalHelper.storeToolState(sceneId, "cameraViewMode", cameraViewMode) _generalHelper.storeToolState(sceneId, "showParticleEmitter", showParticleEmitter) _generalHelper.storeToolState(sceneId, "usePerspective", usePerspective) _generalHelper.storeToolState(sceneId, "globalOrientation", globalOrientation) @@ -1083,6 +1091,35 @@ Item { anchors.centerIn: parent } } + + CameraView { + id: cameraView + + showCameraView: viewRoot.cameraViewMode === "ShowSelectedCamera" + alwaysOn: viewRoot.cameraViewMode === "AlwaysShowCamera" + targetNode: viewRoot.selectedNode + activeScene: viewRoot.activeScene + activeSceneEnvironment: viewRoot.activeEditView.sceneEnv + preferredCamera: _generalHelper.activeScenePreferredCamera + preferredSize: Qt.size(viewRoot.width * 0.3, viewRoot.height * 0.3) + viewPortSize: Qt.size(viewRoot.viewPortRect.width, viewRoot.viewPortRect.height) + + function updateSnapping() { + if (!viewRoot.splitView) + cameraView.snapLeft = true + else if (viewRoot.activeSplit === 2) + cameraView.snapLeft = false + else if (viewRoot.activeSplit === 3) + cameraView.snapLeft = true + } + + Connections { + target: viewRoot + + onSplitViewChanged: cameraView.updateSnapping() + onActiveSplitChanged: cameraView.updateSnapping() + } + } } Text { diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp index 3baf91c1464..e58192e54f8 100644 --- a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp +++ b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp @@ -682,6 +682,16 @@ bool GeneralHelper::isPickable(QQuick3DNode *node) const return true; } +bool GeneralHelper::isCamera(QQuick3DNode *node) const +{ + return node && qobject_cast(node); +} + +bool GeneralHelper::isOrthographicCamera(QQuick3DNode *node) const +{ + return node && qobject_cast(node); +} + // Emitter gizmo model creation is done in C++ as creating dynamic properties and // assigning materials to dynamically created models is lot simpler in C++ QQuick3DNode *GeneralHelper::createParticleEmitterGizmoModel(QQuick3DNode *emitter, @@ -1546,6 +1556,28 @@ void GeneralHelper::requestTimerEvent(const QString &timerId, qint64 delay) } } +QQuick3DCamera *GeneralHelper::activeScenePreferredCamera() const +{ + return m_activeScenePreferredCamera.get(); +} + +void GeneralHelper::setActiveScenePreferredCamera(QQuick3DCamera *camera) +{ + if (m_activeScenePreferredCamera.get() != camera) { + if (m_activeScenePreferredCamera) + disconnect(m_activeScenePreferredCamera.get(), &QObject::destroyed, this, 0); + + m_activeScenePreferredCamera = camera; + + connect( + m_activeScenePreferredCamera.get(), + &QObject::destroyed, + this, + &GeneralHelper::requestActiveScenePreferredCamera); + + emit activeScenePreferredCameraChanged(); + } +} } } diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h index f1b57f4122f..4aa66bd7419 100644 --- a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h +++ b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h @@ -40,6 +40,11 @@ class GeneralHelper : public QObject Q_PROPERTY(double minGridStep READ minGridStep NOTIFY minGridStepChanged FINAL) Q_PROPERTY(double cameraSpeed READ cameraSpeed NOTIFY cameraSpeedChanged FINAL) + Q_PROPERTY( + QQuick3DCamera *activeScenePreferredCamera + READ activeScenePreferredCamera + NOTIFY activeScenePreferredCameraChanged FINAL) + public: GeneralHelper(); @@ -90,6 +95,8 @@ public: Q_INVOKABLE bool isLocked(QQuick3DNode *node) const; Q_INVOKABLE bool isHidden(QQuick3DNode *node) const; Q_INVOKABLE bool isPickable(QQuick3DNode *node) const; + Q_INVOKABLE bool isCamera(QQuick3DNode *node) const; + Q_INVOKABLE bool isOrthographicCamera(QQuick3DNode *node) const; Q_INVOKABLE QQuick3DNode *createParticleEmitterGizmoModel(QQuick3DNode *emitter, QQuick3DMaterial *material) const; @@ -168,6 +175,9 @@ public: Q_INVOKABLE void requestTimerEvent(const QString &timerId, qint64 delay); + QQuick3DCamera *activeScenePreferredCamera() const; + void setActiveScenePreferredCamera(QQuick3DCamera *camera); + signals: void overlayUpdateNeeded(); void toolStateChanged(const QString &sceneId, const QString &tool, const QVariant &toolState); @@ -180,8 +190,10 @@ signals: void sceneEnvDataChanged(); void requestCameraMove(QQuick3DCamera *camera, const QVector3D &moveVector); void requestRender(); + void requestActiveScenePreferredCamera(); void cameraSpeedChanged(); void requestedTimerEvent(const QString &timerId); + void activeScenePreferredCameraChanged(); private: void handlePendingToolStateUpdate(); @@ -229,6 +241,8 @@ private: QList m_multiSelectConnections; bool m_blockMultiSelectionNodePositioning = false; + QPointer m_activeScenePreferredCamera; + bool m_snapAbsolute = true; bool m_snapPosition = false; bool m_snapRotation = false; diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index d81a0aa5644..39f29d5a9f5 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -300,6 +300,30 @@ void Qt5InformationNodeInstanceServer::resolveImportSupport() #endif } +void Qt5InformationNodeInstanceServer::updateActiveScenePreferredCamera() +{ +#ifdef QUICK3D_MODULE + auto preferredCamera = [&]() -> QQuick3DCamera * { + if (auto activeView = qobject_cast(m_active3DView)) { + if (auto camera = activeView->camera()) { + if (hasInstanceForObject(camera) && find3DSceneRoot(camera) == m_active3DScene) + return camera; + } + } + + const QList allCameras = allCameraInstances(); + for (const auto &camera : allCameras) { + if (find3DSceneRoot(camera) == m_active3DScene) + return qobject_cast(camera.internalObject()); + } + return nullptr; + }; + + auto helper = qobject_cast(m_3dHelper); + helper->setActiveScenePreferredCamera(preferredCamera()); +#endif +} + void Qt5InformationNodeInstanceServer::updateMaterialPreviewData( const QVector &valueChanges) { @@ -535,6 +559,11 @@ void Qt5InformationNodeInstanceServer::createEditView3D() QObject::connect(helper, &QmlDesigner::Internal::GeneralHelper::requestRender, this, [this]() { render3DEditView(1); }); + QObject::connect( + helper, + &QmlDesigner::Internal::GeneralHelper::requestActiveScenePreferredCamera, + this, + &Qt5InformationNodeInstanceServer::updateActiveScenePreferredCamera); engine()->rootContext()->setContextProperty("_generalHelper", helper); engine()->addImageProvider(QLatin1String("IconGizmoImageProvider"), new QmlDesigner::Internal::IconGizmoImageProvider); @@ -1035,6 +1064,8 @@ void Qt5InformationNodeInstanceServer::updateActiveSceneToEditView3D([[maybe_unu activeSceneVar = objectToVariant(sceneRoot); } + updateActiveScenePreferredCamera(); + QMetaObject::invokeMethod(m_editView3DData.rootItem, "setActiveScene", Qt::QueuedConnection, Q_ARG(QVariant, activeSceneVar), Q_ARG(QVariant, QVariant::fromValue(sceneId))); @@ -2549,6 +2580,9 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c case View3DActionType::ShowCameraFrustum: updatedToolState.insert("showCameraFrustum", command.isEnabled()); break; + case View3DActionType::CameraViewMode: + updatedToolState.insert("cameraViewMode", command.value()); + break; case View3DActionType::SyncEnvBackground: updatedToolState.insert("syncEnvBackground", command.isEnabled()); break; diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.h b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.h index 321751cf238..60eebe488ae 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.h +++ b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.h @@ -122,6 +122,7 @@ private: void updateLockedAndHiddenStates(const QSet &instances); void handleInputEvents(); void resolveImportSupport(); + void updateActiveScenePreferredCamera(); void updateMaterialPreviewData(const QVector &valueChanges); void updateRotationBlocks(const QVector &valueChanges); void updateSnapAndCameraSettings(const QVector &valueChanges); From f38e3ed0face9a8633f2260996f9fe4a108ed41d Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 23 Aug 2024 16:43:36 +0300 Subject: [PATCH 086/193] QmlDesigner: Don't force show MaterialEditor on apply to model Moved applying material to model to Utils3D, so that it can be easily used from any view. This allows removal of the related custom notification and requirement for MaterialEditor to be shown in detached hidden views case. Fixes: QDS-13426 Change-Id: If5fa994b44e1bc37071eadbd63a3116581da68e7 Reviewed-by: Mahmoud Badri --- .../components/componentcore/utils3d.cpp | 35 ++++++++++++++ .../components/componentcore/utils3d.h | 4 ++ .../materialbrowser/materialbrowserview.cpp | 26 +++++----- .../materialbrowser/materialbrowserview.h | 1 - .../materialeditor/materialeditorview.cpp | 48 +++---------------- .../materialeditor/materialeditorview.h | 2 - 6 files changed, 59 insertions(+), 57 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/utils3d.cpp b/src/plugins/qmldesigner/components/componentcore/utils3d.cpp index 401925296cd..1319401bec9 100644 --- a/src/plugins/qmldesigner/components/componentcore/utils3d.cpp +++ b/src/plugins/qmldesigner/components/componentcore/utils3d.cpp @@ -3,6 +3,7 @@ #include "utils3d.h" +#include #include #include #include @@ -215,5 +216,39 @@ ModelNode selectedTexture(AbstractView *view) return {}; } +QList getSelectedModels(AbstractView *view) +{ + if (!view || !view->model()) + return {}; + + return Utils::filtered(view->selectedModelNodes(), [](const ModelNode &node) { + return node.metaInfo().isQtQuick3DModel(); + }); +} + +void applyMaterialToModels(AbstractView *view, const ModelNode &material, + const QList &models, bool add) +{ + if (models.isEmpty() || !view) + return; + + QTC_CHECK(material); + + view->executeInTransaction(__FUNCTION__, [&] { + for (const ModelNode &node : std::as_const(models)) { + QmlObjectNode qmlObjNode(node); + if (add) { + QStringList matList = ModelUtils::expressionToList( + qmlObjNode.expression("materials")); + matList.append(material.id()); + QString updatedExp = ModelUtils::listToExpression(matList); + qmlObjNode.setBindingProperty("materials", updatedExp); + } else { + qmlObjNode.setBindingProperty("materials", material.id()); + } + } + }); +} + } // namespace Utils3D } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/utils3d.h b/src/plugins/qmldesigner/components/componentcore/utils3d.h index 7f3dae8dafb..5019b7b3ab6 100644 --- a/src/plugins/qmldesigner/components/componentcore/utils3d.h +++ b/src/plugins/qmldesigner/components/componentcore/utils3d.h @@ -37,5 +37,9 @@ void selectTexture(const ModelNode &texture); ModelNode selectedMaterial(AbstractView *view); ModelNode selectedTexture(AbstractView *view); +QList getSelectedModels(AbstractView *view); +void applyMaterialToModels(AbstractView *view, const ModelNode &material, + const QList &models, bool add = false); + } // namespace Utils3D } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 9cd19daa32b..2e4f1756f87 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -83,8 +83,7 @@ WidgetInfo MaterialBrowserView::widgetInfo() connect(matBrowserModel, &MaterialBrowserModel::applyToSelectedTriggered, this, [&] (const ModelNode &material, bool add) { - QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialEditor"); - emitCustomNotification("apply_to_selected_triggered", {material}, {add}); + Utils3D::applyMaterialToModels(this, material, Utils3D::getSelectedModels(this), add); }); connect(matBrowserModel, &MaterialBrowserModel::renameMaterialTriggered, this, @@ -198,9 +197,11 @@ WidgetInfo MaterialBrowserView::widgetInfo() connect(texturesModel, &MaterialBrowserTexturesModel::applyToSelectedModelTriggered, this, [&] (const ModelNode &texture) { - if (m_selectedModels.size() != 1) + const QList selectedModels = Utils3D::getSelectedModels(this); + + if (selectedModels.size() != 1) return; - applyTextureToModel3D(m_selectedModels[0], texture); + applyTextureToModel3D(selectedModels[0], texture); }); connect(texturesModel, &MaterialBrowserTexturesModel::addNewTextureTriggered, this, [&] { @@ -216,8 +217,9 @@ WidgetInfo MaterialBrowserView::widgetInfo() connect(texturesModel, &MaterialBrowserTexturesModel::updateModelSelectionStateRequested, this, [&]() { bool hasModel = false; - if (m_selectedModels.size() == 1) - hasModel = Utils3D::getMaterialOfModel(m_selectedModels.at(0)).isValid(); + const QList selectedModels = Utils3D::getSelectedModels(this); + if (selectedModels.size() == 1) + hasModel = Utils3D::getMaterialOfModel(selectedModels.at(0)).isValid(); m_widget->materialBrowserTexturesModel()->setHasSingleModelSelection(hasModel); }); @@ -361,23 +363,21 @@ void MaterialBrowserView::modelAboutToBeDetached(Model *model) AbstractView::modelAboutToBeDetached(model); } -void MaterialBrowserView::selectedNodesChanged(const QList &selectedNodeList, +void MaterialBrowserView::selectedNodesChanged([[maybe_unused]] const QList &selectedNodeList, [[maybe_unused]] const QList &lastSelectedNodeList) { - m_selectedModels = Utils::filtered(selectedNodeList, [](const ModelNode &node) { - return node.metaInfo().isQtQuick3DModel(); - }); + const QList selectedModels = Utils3D::getSelectedModels(this); - m_widget->materialBrowserModel()->setHasModelSelection(!m_selectedModels.isEmpty()); + m_widget->materialBrowserModel()->setHasModelSelection(!selectedModels.isEmpty()); // the logic below selects the material of the first selected model if auto selection is on if (!m_autoSelectModelMaterial) return; - if (selectedNodeList.size() > 1 || m_selectedModels.isEmpty()) + if (selectedNodeList.size() > 1 || selectedModels.isEmpty()) return; - ModelNode mat = Utils3D::getMaterialOfModel(m_selectedModels.at(0)); + ModelNode mat = Utils3D::getMaterialOfModel(selectedModels.at(0)); if (!mat.isValid()) return; diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h index be1092e7f3f..e316a66555d 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h @@ -89,7 +89,6 @@ private: AsynchronousImageCache &m_imageCache; QPointer m_widget; - QList m_selectedModels; // selected 3D model nodes bool m_hasQuick3DImport = false; bool m_autoSelectModelMaterial = false; // TODO: wire this to some action diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index 32af9bc9145..79e545decc6 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -24,7 +24,6 @@ #include "qmldesignerplugin.h" #include "qmltimeline.h" #include "variantproperty.h" -#include #include #include @@ -380,41 +379,18 @@ QString MaterialEditorView::materialEditorResourcesPath() return Core::ICore::resourcePath("qmldesigner/materialEditorQmlSources").toString(); } -void MaterialEditorView::applyMaterialToSelectedModels(const ModelNode &material, bool add) -{ - if (m_selectedModels.isEmpty()) - return; - - QTC_ASSERT(material.isValid(), return); - - executeInTransaction(__FUNCTION__, [&] { - for (const ModelNode &node : std::as_const(m_selectedModels)) { - QmlObjectNode qmlObjNode(node); - if (add) { - QStringList matList = ModelUtils::expressionToList( - qmlObjNode.expression("materials")); - matList.append(material.id()); - QString updatedExp = ModelUtils::listToExpression(matList); - qmlObjNode.setBindingProperty("materials", updatedExp); - } else { - qmlObjNode.setBindingProperty("materials", material.id()); - } - } - }); -} - void MaterialEditorView::handleToolBarAction(int action) { QTC_ASSERT(m_hasQuick3DImport, return); switch (action) { case MaterialEditorContextObject::ApplyToSelected: { - applyMaterialToSelectedModels(m_selectedMaterial); + Utils3D::applyMaterialToModels(this, m_selectedMaterial, Utils3D::getSelectedModels(this)); break; } case MaterialEditorContextObject::ApplyToSelectedAdd: { - applyMaterialToSelectedModels(m_selectedMaterial, true); + Utils3D::applyMaterialToModels(this, m_selectedMaterial, Utils3D::getSelectedModels(this), true); break; } @@ -895,18 +871,11 @@ WidgetInfo MaterialEditorView::widgetInfo() tr("Material Editor view")); } -void MaterialEditorView::selectedNodesChanged(const QList &selectedNodeList, +void MaterialEditorView::selectedNodesChanged([[maybe_unused]] const QList &selectedNodeList, [[maybe_unused]] const QList &lastSelectedNodeList) { - m_selectedModels.clear(); - - for (const ModelNode &node : selectedNodeList) { - if (node.metaInfo().isQtQuick3DModel()) - m_selectedModels.append(node); - } - if (m_qmlBackEnd) - m_qmlBackEnd->contextObject()->setHasModelSelection(!m_selectedModels.isEmpty()); + m_qmlBackEnd->contextObject()->setHasModelSelection(!Utils3D::getSelectedModels(this).isEmpty()); } void MaterialEditorView::currentStateChanged(const ModelNode &node) @@ -1093,15 +1062,12 @@ void MaterialEditorView::customNotification([[maybe_unused]] const AbstractView const QList &nodeList, const QList &data) { - if (identifier == "apply_to_selected_triggered") { - applyMaterialToSelectedModels(nodeList.first(), data.first().toBool()); - } else if (identifier == "rename_material") { + if (identifier == "rename_material") renameMaterial(m_selectedMaterial, data.first().toString()); - } else if (identifier == "add_new_material") { + else if (identifier == "add_new_material") handleToolBarAction(MaterialEditorContextObject::AddNewMaterial); - } else if (identifier == "duplicate_material") { + else if (identifier == "duplicate_material") duplicateMaterial(nodeList.first()); - } } void MaterialEditorView::nodeReparented(const ModelNode &node, diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h index 8f0e98f1f31..aab2a624642 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h @@ -107,7 +107,6 @@ private: void highlightSupportedProperties(bool highlight = true); void requestPreviewRender(); - void applyMaterialToSelectedModels(const ModelNode &material, bool add = false); void setupQmlBackend(); @@ -127,7 +126,6 @@ private: QShortcut *m_updateShortcut = nullptr; int m_timerId = 0; QStackedWidget *m_stackedWidget = nullptr; - QList m_selectedModels; QHash m_qmlBackendHash; MaterialEditorQmlBackend *m_qmlBackEnd = nullptr; bool m_locked = false; From 486dee6e3892e18337f1761ef84275ad60a7b0d6 Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Fri, 23 Aug 2024 19:31:34 +0300 Subject: [PATCH 087/193] QmlDesigner: Update qml preview data after changes in aux properties Fixes: QDS-13456 Change-Id: I71605b4f45fe40a9c4e0b12920b2521b334f90c9 Reviewed-by: Miikka Heikkinen --- .../materialeditor/materialeditorview.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index 79e545decc6..e9986344db1 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -57,6 +57,23 @@ static bool containsTexture(const ModelNode &node) return false; }; +static bool isPreviewAuxiliaryKey(AuxiliaryDataKeyView key) +{ + static const QVector previewKeys = [] { + QVector previewKeys{ + materialPreviewEnvDocProperty, + materialPreviewEnvValueDocProperty, + materialPreviewModelDocProperty, + materialPreviewEnvProperty, + materialPreviewEnvValueProperty, + materialPreviewModelProperty, + }; + std::sort(previewKeys.begin(), previewKeys.end()); + return previewKeys; + }(); + return Utils::containsInSorted(previewKeys, key); +} + MaterialEditorView::MaterialEditorView(ExternalDependenciesInterface &externalDependencies) : AbstractView{externalDependencies} , m_stackedWidget(new QStackedWidget) @@ -833,6 +850,8 @@ void MaterialEditorView::auxiliaryDataChanged(const ModelNode &node, m_dynamicPropertiesModel->setSelectedNode(m_selectedMaterial); QTimer::singleShot(0, this, &MaterialEditorView::resetView); } + } else if (isPreviewAuxiliaryKey(key)) { + QTimer::singleShot(0, this, &MaterialEditorView::initPreviewData); } } } From a69f9786d7716a65b78991a75431dc7bb5fe2186 Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Fri, 23 Aug 2024 10:12:52 +0300 Subject: [PATCH 088/193] Doc: Document importing and exporting bundles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QDS-13318 Change-Id: If3ca685e5342de3751e9d8dbb4d22a5c4c93a846 Reviewed-by: Teea Põldsam Reviewed-by: Mats Honkamaa Reviewed-by: Mahmoud Badri --- .../src/qtdesignstudio-sharing-assets.qdoc | 34 +++++++++++++++++++ .../src/qtdesignstudio-toc.qdoc | 1 + 2 files changed, 35 insertions(+) create mode 100644 doc/qtdesignstudio/src/qtdesignstudio-sharing-assets.qdoc diff --git a/doc/qtdesignstudio/src/qtdesignstudio-sharing-assets.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-sharing-assets.qdoc new file mode 100644 index 00000000000..a968c8aeac0 --- /dev/null +++ b/doc/qtdesignstudio/src/qtdesignstudio-sharing-assets.qdoc @@ -0,0 +1,34 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \previouspage qt-using-effect-maker-effects.html + \page sharing-assets.html + \nextpage qtquick-motion-design.html + \sa {Content Library} + + \title Sharing Assets + With \QDS Bundle files (\e{.qdsbundle}), you can import and export 3D components (such as + cameras, lights, and models) and materials easily. + + \section1 Exporting Bundles + To export a 3D component or material as a bundle, do one of the following: + + \list + \li In the \uicontrol 3D or \uicontrol Navigator view, right-click a 3D component and select + \uicontrol {Export Component}. + \li In the \uicontrol {Material Browser} view, right-click a material and select + \uicontrol {Export Material}. + \endlist + + \section1 Importing Bundles + To import a 3D component or material bundle, do one of the following: + \list + \li In the \uicontrol {3D}, \uicontrol {2D}, or \uicontrol {Navigator} view, right-click + and select \uicontrol {Import Component}. If you use this method to import a bundle of 3D + components, the 3D components are added to the 3D scene. + \li In \uicontrol {Content Library} > \uicontrol {User Assets}, right-click and select + \uicontrol {Import Bundle}. If you use this method to import a bundle of 3D + components, the 3D components are added to \uicontrol {User Assets}. + \endlist +*/ diff --git a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc index 2584279e540..abc575e8d9b 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc @@ -191,6 +191,7 @@ \endlist \li \l{Exporting Components} \li \l{Using Qt Quick Effect Maker Effects} + \li \l{Sharing Assets} \endlist \endlist \li \l{Motion Design} From 996b7c111985dba818d65803284d3155da3c8400 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 26 Aug 2024 12:06:04 +0300 Subject: [PATCH 089/193] QmlDesigner: Prevent deadlock in drag handling in content library model->startDrag() starts a new event loop and doesn't exit until the drag is over, so in the old implementation m_*ToDrag were not cleared until the drag was complete. However, in some cases it is possible to receive another move event while drag is still ongoing, which would then get interpreted as start of another drag as m_*ToDrag were still valid, causing nested drag event loops, which caused a deadlock in gui thread. This issue is prevented by clearing m_*ToDrag before drag starts. Change-Id: I2554332d449a4913779c00d1cdcaf67ba6f6a512 Reviewed-by: Mahmoud Badri --- .../components/contentlibrary/contentlibrarywidget.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp index 3a7de7001d0..a5fe776fb86 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp @@ -78,8 +78,9 @@ bool ContentLibraryWidget::eventFilter(QObject *obj, QEvent *event) mimeData->setData(Constants::MIME_TYPE_BUNDLE_ITEM, data); emit bundleItemDragStarted(m_itemToDrag); - model->startDrag(std::move(mimeData), m_itemToDrag->icon().toLocalFile(), this); + const QString iconPath = m_itemToDrag->icon().toLocalFile(); m_itemToDrag = nullptr; + model->startDrag(std::move(mimeData), iconPath, this); } } else if (m_materialToDrag) { QMouseEvent *me = static_cast(event); @@ -93,8 +94,9 @@ bool ContentLibraryWidget::eventFilter(QObject *obj, QEvent *event) mimeData->removeFormat("text/plain"); emit bundleMaterialDragStarted(m_materialToDrag); - model->startDrag(std::move(mimeData), m_materialToDrag->icon().toLocalFile(), this); + const QString iconPath = m_materialToDrag->icon().toLocalFile(); m_materialToDrag = nullptr; + model->startDrag(std::move(mimeData), iconPath, this); } } else if (m_textureToDrag) { QMouseEvent *me = static_cast(event); @@ -108,8 +110,9 @@ bool ContentLibraryWidget::eventFilter(QObject *obj, QEvent *event) mimeData->setUrls({QUrl::fromLocalFile(m_textureToDrag->texturePath())}); emit bundleTextureDragStarted(m_textureToDrag); - model->startDrag(std::move(mimeData), m_textureToDrag->icon().toLocalFile(), this); + const QString iconPath = m_textureToDrag->icon().toLocalFile(); m_textureToDrag = nullptr; + model->startDrag(std::move(mimeData), iconPath, this); } } } else if (event->type() == QMouseEvent::MouseButtonRelease) { From c5a6532fe6374bbc83810fca73fde1399258ecaa Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 26 Aug 2024 14:18:36 +0300 Subject: [PATCH 090/193] QmlDesigner: Fix material selection on id change and new material When material id changes, now properly check also for material subclasses for a match. Just to be on the safe side, same was done for texture case, even though textures usually are not subclassed. Also now explicitly select the newly created material/texture after creation instead of relying on selection changing via other handlers. Fixes: QDS-13447 Change-Id: Id108631e6f1d2a78fbaec3f2792800c1cfdc3102 Reviewed-by: Mahmoud Badri --- .../componentcore/createtexture.cpp | 4 +++ .../components/integration/componentview.cpp | 28 ++++++++----------- .../materialeditor/materialeditorview.cpp | 6 +++- 3 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/createtexture.cpp b/src/plugins/qmldesigner/components/componentcore/createtexture.cpp index 35bc3a0d18b..2d86c77bb4b 100644 --- a/src/plugins/qmldesigner/components/componentcore/createtexture.cpp +++ b/src/plugins/qmldesigner/components/componentcore/createtexture.cpp @@ -84,6 +84,10 @@ ModelNode CreateTexture::execute() matLib.defaultNodeListProperty().reparentHere(newTextureNode); }); + QTimer::singleShot(0, m_view, [newTextureNode]() { + Utils3D::selectTexture(newTextureNode); + }); + return newTextureNode; } diff --git a/src/plugins/qmldesigner/components/integration/componentview.cpp b/src/plugins/qmldesigner/components/integration/componentview.cpp index e52aea5bc11..59f8273fda8 100644 --- a/src/plugins/qmldesigner/components/integration/componentview.cpp +++ b/src/plugins/qmldesigner/components/integration/componentview.cpp @@ -230,27 +230,23 @@ void ComponentView::nodeIdChanged(const ModelNode& node, const QString& newId, c // Material/texture id handling is done here as ComponentView is guaranteed to always be // attached, unlike the views actually related to material/texture handling. - auto metaInfo = node.metaInfo(); - auto rootNode = rootModelNode(); - auto model = AbstractView::model(); - if (metaInfo == model->qtQuick3DMaterialMetaInfo()) { - if (auto property = rootNode.auxiliaryData(Utils3D::matLibSelectedMaterialProperty)) { + auto maybeSetAuxData = [this, &oldId, &newId](AuxiliaryDataKeyView key) { + auto rootNode = rootModelNode(); + if (auto property = rootNode.auxiliaryData(key)) { if (oldId == property->toString()) { - QTimer::singleShot(0, this, [rootNode, newId]() { - rootNode.setAuxiliaryData(Utils3D::matLibSelectedMaterialProperty, newId); + QTimer::singleShot(0, this, [rootNode, newId, key]() { + rootNode.setAuxiliaryData(key, newId); }); } } - } else if (metaInfo == model->qtQuick3DTextureMetaInfo()) { - if (auto property = rootNode.auxiliaryData(Utils3D::matLibSelectedTextureProperty)) { - if (oldId == property->toString()) { - QTimer::singleShot(0, this, [rootNode, newId]() { - rootNode.setAuxiliaryData(Utils3D::matLibSelectedTextureProperty, newId); - }); - } - } - } + }; + + auto metaInfo = node.metaInfo(); + if (metaInfo.isQtQuick3DMaterial()) + maybeSetAuxData(Utils3D::matLibSelectedMaterialProperty); + else if (metaInfo.isQtQuick3DTexture()) + maybeSetAuxData(Utils3D::matLibSelectedTextureProperty); } void ComponentView::nodeSourceChanged(const ModelNode &node, const QString &/*newNodeSource*/) diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index e9986344db1..9afb0fce457 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -414,6 +414,7 @@ void MaterialEditorView::handleToolBarAction(int action) case MaterialEditorContextObject::AddNewMaterial: { if (!model()) break; + ModelNode newMatNode; executeInTransaction(__FUNCTION__, [&] { ModelNode matLib = Utils3D::materialLibraryNode(this); if (!matLib.isValid()) @@ -422,13 +423,16 @@ void MaterialEditorView::handleToolBarAction(int action) ModelNode newMatNode = createModelNode("PrincipledMaterial"); #else NodeMetaInfo metaInfo = model()->qtQuick3DPrincipledMaterialMetaInfo(); - ModelNode newMatNode = createModelNode("QtQuick3D.PrincipledMaterial", + newMatNode = createModelNode("QtQuick3D.PrincipledMaterial", metaInfo.majorVersion(), metaInfo.minorVersion()); #endif renameMaterial(newMatNode, "New Material"); matLib.defaultNodeListProperty().reparentHere(newMatNode); }); + QTimer::singleShot(0, this, [newMatNode]() { + Utils3D::selectMaterial(newMatNode); + }); break; } From 5c7787c1d1c42046d6ce9afb86e8c36af418ad64 Mon Sep 17 00:00:00 2001 From: Shrief Gabr Date: Tue, 13 Aug 2024 19:09:53 +0300 Subject: [PATCH 091/193] QmlDesigner: Enable Drag & Drop between Assets Library folders Fixes: QDS-11287 Change-Id: Ieeb61b46e24206fa6a7527559576fee39f3cca9c Reviewed-by: Mahmoud Badri --- .../assetsLibraryQmlSources/AssetDelegate.qml | 47 +++++++- .../assetsLibraryQmlSources/Assets.qml | 19 +++- .../assetsLibraryQmlSources/AssetsView.qml | 107 ------------------ .../assetslibrary/assetslibrarywidget.cpp | 71 ++++++++++-- .../assetslibrary/assetslibrarywidget.h | 5 +- 5 files changed, 125 insertions(+), 124 deletions(-) diff --git a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml index 2877c4061bf..9346cb62e06 100644 --- a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml +++ b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml @@ -288,7 +288,7 @@ TreeViewDelegate { function __toggleExpandCurrentRow() { if (!root.__isDirectory) - return + return let index = root.assetsView.__modelIndex(root.__currentRow) // if the user manually clicked on a directory, then this is definitely not a @@ -336,4 +336,49 @@ TreeViewDelegate { assetTooltip.refresh() } } + + DropArea { + anchors.fill: parent + anchors.bottomMargin: -assetsView.rowSpacing + + function updateParentHighlight(highlight) { + let index = root.assetsView.__modelIndex(root.__currentRow) + let parentItem = assetsView.__getDelegateParentForIndex(index) + if (parentItem) + parentItem.isHighlighted = highlight + + // highlights the root folder canvas area when dragging over child + if (root.depth === 1 && !root.__isDirectory) + assetsRoot.highlightCanvas = highlight + } + + onEntered: (drag) => { + root.assetsRoot.updateDropExtFiles(drag) + + drag.accepted |= (drag.formats[0] === "application/vnd.qtdesignstudio.assets") + + if (root.__isDirectory) + isHighlighted = drag.accepted + else + updateParentHighlight(drag.accepted) + } + + onDropped: (drag) => { + if (drag.formats[0] === "application/vnd.qtdesignstudio.assets") { + rootView.invokeAssetsDrop(drag.urls, root.getDirPath()) + } else { + rootView.emitExtFilesDrop(root.assetsRoot.dropSimpleExtFiles, + root.assetsRoot.dropComplexExtFiles, + root.getDirPath()) + } + + isHighlighted = true + updateParentHighlight(true) + } + + onExited: { + isHighlighted = false + updateParentHighlight(false) + } + } } diff --git a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/Assets.qml b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/Assets.qml index 26bef6f8e91..9a9ae4c0919 100644 --- a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/Assets.qml +++ b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/Assets.qml @@ -21,6 +21,7 @@ Item { readonly property int qtVersion: rootView.qtVersion() property bool __searchBoxEmpty: true + property bool highlightCanvas: false AssetsContextMenu { id: contextMenu @@ -58,14 +59,21 @@ Item { height: parent.height - y onEntered: (drag) => { - root.updateDropExtFiles(drag) + if (drag.formats[0] === "application/vnd.qtdesignstudio.assets") + drag.accepted = drag.urls.length > 0 + else + root.updateDropExtFiles(drag) } onDropped: (drag) => { drag.accept() - rootView.handleExtFilesDrop(root.dropSimpleExtFiles, - root.dropComplexExtFiles, - assetsModel.rootPath()) + if (drag.formats[0] === "application/vnd.qtdesignstudio.assets") { + rootView.handleAssetsDrop(drag.urls, assetsModel.rootPath()) + } else { + rootView.handleExtFilesDrop(root.dropSimpleExtFiles, + root.dropComplexExtFiles, + assetsModel.rootPath()) + } } Canvas { // marker for the drop area @@ -73,8 +81,7 @@ Item { y: 5 width: parent.width height: parent.height - y - visible: dropArea.containsDrag && root.dropSimpleExtFiles.length > 0 - + visible: dropArea.containsDrag || root.highlightCanvas onWidthChanged: dropCanvas.requestPaint() onHeightChanged: dropCanvas.requestPaint() diff --git a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsView.qml b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsView.qml index 8513c29a298..698011db367 100644 --- a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsView.qml +++ b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsView.qml @@ -278,36 +278,6 @@ TreeView { return "" } - function startDropHoverOver(row) - { - let index = root.__modelIndex(row) - if (assetsModel.isDirectory(index)) { - let item = root.__getDelegateItemForIndex(index) - if (item) - item.isHighlighted = true - return - } - - let parentItem = root.__getDelegateParentForIndex(index) - if (parentItem) - parentItem.hasChildWithDropHover = true - } - - function endDropHover(row) - { - let index = root.__modelIndex(row) - if (assetsModel.isDirectory(index)) { - let item = root.__getDelegateItemForIndex(index) - if (item) - item.isHighlighted = false - return - } - - let parentItem = root.__getDelegateParentForIndex(index) - if (parentItem) - parentItem.hasChildWithDropHover = false - } - function isAssetSelected(itemPath) { return root.selectedAssets[itemPath] ? true : false @@ -331,12 +301,6 @@ TreeView { return root.itemAtCell(parentCell) } - function __getDelegateItemForIndex(index) - { - let cell = root.cellAtIndex(index) - return root.itemAtCell(cell) - } - function __modelIndex(row) { // The modelIndex() function exists since 6.3. In Qt 6.3, this modelIndex() function was a @@ -405,77 +369,6 @@ TreeView { onClosed: confirmDeleteFiles.files = [] } - DropArea { - id: dropArea - enabled: true - anchors.fill: parent - - property bool __isHoveringDrop: false - property int __rowHoveringOver: -1 - - function __rowAndItem(drag) - { - let pos = dropArea.mapToItem(root, drag.x, drag.y) - let cell = root.cellAtPos(pos.x, pos.y, true) - let item = root.itemAtCell(cell) - - return [cell.y, item] - } - - onEntered: (drag) => { - root.assetsRoot.updateDropExtFiles(drag) - - let [row, item] = dropArea.__rowAndItem(drag) - dropArea.__isHoveringDrop = drag.accepted && root.assetsRoot.dropSimpleExtFiles.length > 0 - - if (item && dropArea.__isHoveringDrop) - root.startDropHoverOver(row) - - dropArea.__rowHoveringOver = row - } - - onDropped: (drag) => { - let [row, item] = dropArea.__rowAndItem(drag) - - if (item) { - drag.accept() - root.endDropHover(row) - - let dirPath = item.getDirPath() - - rootView.emitExtFilesDrop(root.assetsRoot.dropSimpleExtFiles, - root.assetsRoot.dropComplexExtFiles, - dirPath) - } - - dropArea.__isHoveringDrop = false - dropArea.__rowHoveringOver = -1 - } - - onPositionChanged: (drag) => { - let [row, item] = dropArea.__rowAndItem(drag) - - if (dropArea.__rowHoveringOver !== row && dropArea.__rowHoveringOver > -1) { - root.endDropHover(dropArea.__rowHoveringOver) - - if (item) - root.startDropHoverOver(row) - } - - dropArea.__rowHoveringOver = row - } - - onExited: { - if (!dropArea.__isHoveringDrop || dropArea.__rowHoveringOver === -1) - return - - root.endDropHover(dropArea.__rowHoveringOver) - - dropArea.__isHoveringDrop = false - dropArea.__rowHoveringOver = -1 - } - } - delegate: AssetDelegate { assetsView: root assetsRoot: root.assetsRoot diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp index 40c1c68d356..ef7876923e5 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp @@ -65,6 +65,7 @@ bool AssetsLibraryWidget::eventFilter(QObject *obj, QEvent *event) } else if (event->type() == QMouseEvent::MouseMove) { if (!m_assetsToDrag.isEmpty() && m_assetsView->model()) { QMouseEvent *me = static_cast(event); + if ((me->globalPosition().toPoint() - m_dragStartPoint).manhattanLength() > 10) { auto mimeData = std::make_unique(); mimeData->setData(Constants::MIME_TYPE_ASSETS, m_assetsToDrag.join(',').toUtf8()); @@ -73,15 +74,16 @@ bool AssetsLibraryWidget::eventFilter(QObject *obj, QEvent *event) return QUrl::fromLocalFile(path); }); + QString draggedAsset = m_assetsToDrag[0]; + + m_assetsToDrag.clear(); mimeData->setUrls(urlsToDrag); m_assetsView->model()->startDrag(std::move(mimeData), - m_assetsIconProvider->requestPixmap(m_assetsToDrag[0], + m_assetsIconProvider->requestPixmap(draggedAsset, nullptr, {128, 128}), this); - - m_assetsToDrag.clear(); } } } else if (event->type() == QMouseEvent::MouseButtonRelease) { @@ -370,6 +372,62 @@ bool AssetsLibraryWidget::assetIsImageOrTexture(const QString &id) return Asset(id).isValidTextureSource(); } +// needed to deal with "Object 0xXXXX destroyed while one of its QML signal handlers is in progress..." error which would lead to a crash +void AssetsLibraryWidget::invokeAssetsDrop(const QList &urls, const QString &targetDir) +{ + QMetaObject::invokeMethod(this, "handleAssetsDrop", Qt::QueuedConnection, Q_ARG(QList, urls), Q_ARG(QString, targetDir)); +} + +void AssetsLibraryWidget::handleAssetsDrop(const QList &urls, const QString &targetDir) +{ + if (urls.isEmpty() || targetDir.isEmpty()) + return; + + Utils::FilePath destDir = Utils::FilePath::fromUserInput(targetDir); + + QString resourceFolder = DocumentManager::currentResourcePath().toString(); + + if (destDir.isFile()) + destDir = destDir.parentDir(); + + QMessageBox mb; + mb.setInformativeText("What would you like to do with the existing asset?"); + mb.addButton("Keep Both", QMessageBox::AcceptRole); + mb.addButton("Replace", QMessageBox::ResetRole); + mb.addButton("Cancel", QMessageBox::RejectRole); + + for (const QUrl &url : urls) { + Utils::FilePath src = Utils::FilePath::fromUrl(url); + Utils::FilePath dest = destDir.pathAppended(src.fileName()); + + if (destDir == src.parentDir() || !src.startsWith(resourceFolder)) + continue; + + if (dest.exists()) { + mb.setText("An asset named " + dest.fileName() + " already exists."); + mb.exec(); + int userAction = mb.buttonRole(mb.clickedButton()); + + if (userAction == QMessageBox::AcceptRole) { // "Keep Both" + dest = Utils::FilePath::fromString(UniqueName::generatePath(dest.toString())); + } else if (userAction == QMessageBox::ResetRole && dest.exists()) { // "Replace" + if (!dest.removeFile()) { + qWarning() << __FUNCTION__ << "Failed to remove existing file" << dest; + continue; + } + } else if (userAction == QMessageBox::RejectRole) { // "Cancel" + continue; + } + } + + if (!src.renameFile(dest)) + qWarning() << __FUNCTION__ << "Failed to move asset from" << src << "to" << dest; + } + + if (m_assetsView->model()) + m_assetsView->model()->endDrag(); +} + QList AssetsLibraryWidget::createToolBarWidgets() { return {}; @@ -411,12 +469,11 @@ void AssetsLibraryWidget::handleExtFilesDrop(const QList &simpleFilePaths, if (!simpleFilePathStrings.isEmpty()) { if (targetDirPath.isEmpty()) { - addResources(simpleFilePathStrings); + addResources(simpleFilePathStrings, false); } else { - bool isDropOnRoot = m_assetsModel->rootPath() == targetDirPath; AddFilesResult result = ModelNodeOperations::addFilesToProject(simpleFilePathStrings, targetDirPath, - isDropOnRoot); + false); if (result.status() == AddFilesResult::Failed) { QWidget *w = Core::AsynchronousMessageBox::warning(tr("Failed to Add Files"), tr("Could not add %1 to project.") @@ -430,7 +487,7 @@ void AssetsLibraryWidget::handleExtFilesDrop(const QList &simpleFilePaths, } if (!complexFilePathStrings.empty()) - addResources(complexFilePathStrings); + addResources(complexFilePathStrings, false); m_assetsView->model()->endDrag(); } diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h index 01802196634..79deeb9efd3 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h @@ -72,7 +72,8 @@ public: Q_INVOKABLE void startDragAsset(const QStringList &assetPaths, const QPointF &mousePos); Q_INVOKABLE void handleAddAsset(); Q_INVOKABLE void handleSearchFilterChanged(const QString &filterText); - + Q_INVOKABLE void invokeAssetsDrop(const QList &urls, const QString &targetDir); + Q_INVOKABLE void handleAssetsDrop(const QList &urls, const QString &targetDir); Q_INVOKABLE void handleExtFilesDrop(const QList &simpleFilePaths, const QList &complexFilePaths, const QString &targetDirPath); @@ -80,7 +81,6 @@ public: Q_INVOKABLE void emitExtFilesDrop(const QList &simpleFilePaths, const QList &complexFilePaths, const QString &targetDirPath = {}); - Q_INVOKABLE QSet supportedAssetSuffixes(bool complex); Q_INVOKABLE void openEffectComposer(const QString &filePath); Q_INVOKABLE int qtVersion() const; @@ -88,7 +88,6 @@ public: Q_INVOKABLE QSize imageSize(const QString &id); Q_INVOKABLE QString assetFileSize(const QString &id); Q_INVOKABLE bool assetIsImageOrTexture(const QString &id); - Q_INVOKABLE void addTextures(const QStringList &filePaths); Q_INVOKABLE void addLightProbe(const QString &filePaths); Q_INVOKABLE void updateContextMenuActionsEnableState(); From 06e7b16e971c842253eb1b19ed2954563c3761a6 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 27 Aug 2024 13:28:52 +0300 Subject: [PATCH 092/193] QmlDesigner: Update material and texture editors on delete If the material or texture shown in the respective editor is deleted, now properly update the editor content. Fixes: QDS-13420 Change-Id: Ifd0475faf4d249ba5c7aba901dc3aa542e66cf4a Reviewed-by: Ali Kianian Reviewed-by: Mahmoud Badri --- .../materialeditor/materialeditorview.cpp | 76 ++++++++++++++++--- .../materialeditor/materialeditorview.h | 3 + .../textureeditor/textureeditorview.cpp | 68 +++++++++++++++-- .../textureeditor/textureeditorview.h | 6 ++ 4 files changed, 139 insertions(+), 14 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index 9afb0fce457..7d27b93e67a 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -357,8 +357,22 @@ MaterialEditorView *MaterialEditorView::instance() void MaterialEditorView::timerEvent(QTimerEvent *timerEvent) { - if (m_timerId == timerEvent->timerId()) - resetView(); + if (m_timerId == timerEvent->timerId()) { + if (m_selectedMaterialChanged) { + m_selectedMaterialChanged = false; + Utils3D::selectMaterial(m_newSelectedMaterial); + m_newSelectedMaterial = {}; + } else { + resetView(); + } + } +} + +void MaterialEditorView::asyncResetView() +{ + if (m_timerId) + killTimer(m_timerId); + m_timerId = startTimer(0); } void MaterialEditorView::resetView() @@ -852,7 +866,7 @@ void MaterialEditorView::auxiliaryDataChanged(const ModelNode &node, if (ModelNode selNode = Utils3D::selectedMaterial(this)) { m_selectedMaterial = selNode; m_dynamicPropertiesModel->setSelectedNode(m_selectedMaterial); - QTimer::singleShot(0, this, &MaterialEditorView::resetView); + asyncResetView(); } } else if (isPreviewAuxiliaryKey(key)) { QTimer::singleShot(0, this, &MaterialEditorView::initPreviewData); @@ -1098,10 +1112,26 @@ void MaterialEditorView::nodeReparented(const ModelNode &node, [[maybe_unused]] const NodeAbstractProperty &oldPropertyParent, [[maybe_unused]] PropertyChangeFlags propertyChange) { - if (node.id() == Constants::MATERIAL_LIB_ID && m_qmlBackEnd && m_qmlBackEnd->contextObject()) + if (node.id() == Constants::MATERIAL_LIB_ID && m_qmlBackEnd && m_qmlBackEnd->contextObject()) { m_qmlBackEnd->contextObject()->setHasMaterialLibrary(true); - else if (m_qmlBackEnd && containsTexture(node)) - m_qmlBackEnd->refreshBackendModel(); + asyncResetView(); + } else { + if (!m_selectedMaterial && node.metaInfo().isQtQuick3DMaterial() + && node.parentProperty().parentModelNode() == Utils3D::materialLibraryNode(this)) { + ModelNode currentSelection = Utils3D::selectedMaterial(this); + if (currentSelection) { + m_selectedMaterial = currentSelection; + asyncResetView(); + } else { + QTimer::singleShot(0, this, [node]() { + Utils3D::selectMaterial(node); + }); + } + } + + if (m_qmlBackEnd && containsTexture(node)) + m_qmlBackEnd->refreshBackendModel(); + } } void MaterialEditorView::nodeIdChanged(const ModelNode &node, @@ -1114,10 +1144,35 @@ void MaterialEditorView::nodeIdChanged(const ModelNode &node, void MaterialEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode) { - if (removedNode.id() == Constants::MATERIAL_LIB_ID && m_qmlBackEnd && m_qmlBackEnd->contextObject()) + if (removedNode.id() == Constants::MATERIAL_LIB_ID && m_qmlBackEnd && m_qmlBackEnd->contextObject()) { + m_selectedMaterial = {}; m_qmlBackEnd->contextObject()->setHasMaterialLibrary(false); - else if (containsTexture(removedNode)) - m_textureAboutToBeRemoved = true; + asyncResetView(); + } else { + if (removedNode == m_selectedMaterial) { + ModelNode matLib = Utils3D::materialLibraryNode(this); + QTC_ASSERT(matLib.isValid(), return); + + const QList mats = matLib.directSubModelNodesOfType( + model()->qtQuick3DMaterialMetaInfo()); + bool selectedNodeFound = false; + m_newSelectedMaterial = {}; + for (const ModelNode &mat : mats) { + if (selectedNodeFound) { + m_newSelectedMaterial = mat; + break; + } + if (m_selectedMaterial == mat) + selectedNodeFound = true; + else + m_newSelectedMaterial = mat; + } + m_selectedMaterialChanged = true; + } + + if (containsTexture(removedNode)) + m_textureAboutToBeRemoved = true; + } } void MaterialEditorView::nodeRemoved([[maybe_unused]] const ModelNode &removedNode, @@ -1128,6 +1183,9 @@ void MaterialEditorView::nodeRemoved([[maybe_unused]] const ModelNode &removedNo m_qmlBackEnd->refreshBackendModel(); m_textureAboutToBeRemoved = false; + + if (m_selectedMaterialChanged) + asyncResetView(); } void MaterialEditorView::highlightSupportedProperties(bool highlight) diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h index aab2a624642..e5f7a446ed0 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h @@ -120,6 +120,7 @@ private: void initPreviewData(); void updatePossibleTypes(); + void asyncResetView(); ModelNode m_selectedMaterial; QTimer m_ensureMatLibTimer; @@ -134,6 +135,8 @@ private: bool m_hasMaterialRoot = false; bool m_initializingPreviewData = false; bool m_textureAboutToBeRemoved = false; + ModelNode m_newSelectedMaterial; + bool m_selectedMaterialChanged = false; QSize m_previewSize; QByteArray m_previewRequestId; diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp index 2f0a92f253a..b6090c9c2f0 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp @@ -333,8 +333,15 @@ TextureEditorView *TextureEditorView::instance() void TextureEditorView::timerEvent(QTimerEvent *timerEvent) { - if (m_timerId == timerEvent->timerId()) - resetView(); + if (m_timerId == timerEvent->timerId()) { + if (m_selectedTextureChanged) { + m_selectedTextureChanged = false; + Utils3D::selectTexture(m_newSelectedTexture); + m_newSelectedTexture = {}; + } else { + resetView(); + } + } } void TextureEditorView::resetView() @@ -530,6 +537,13 @@ bool TextureEditorView::noValidSelection() const return !QmlObjectNode::isValidQmlObjectNode(m_selectedTexture); } +void TextureEditorView::asyncResetView() +{ + if (m_timerId) + killTimer(m_timerId); + m_timerId = startTimer(0); +} + void TextureEditorView::modelAttached(Model *model) { AbstractView::modelAttached(model); @@ -686,7 +700,7 @@ void TextureEditorView::auxiliaryDataChanged(const ModelNode &node, if (ModelNode selNode = Utils3D::selectedTexture(this)) { m_selectedTexture = selNode; m_dynamicPropertiesModel->setSelectedNode(m_selectedTexture); - QTimer::singleShot(0, this, &TextureEditorView::resetView); + asyncResetView(); } } } @@ -703,14 +717,58 @@ void TextureEditorView::nodeReparented(const ModelNode &node, [[maybe_unused]] const NodeAbstractProperty &oldPropertyParent, [[maybe_unused]] PropertyChangeFlags propertyChange) { - if (node.id() == Constants::MATERIAL_LIB_ID && m_qmlBackEnd && m_qmlBackEnd->contextObject()) + if (node.id() == Constants::MATERIAL_LIB_ID && m_qmlBackEnd && m_qmlBackEnd->contextObject()) { m_qmlBackEnd->contextObject()->setHasMaterialLibrary(true); + asyncResetView(); + } else { + if (!m_selectedTexture && node.metaInfo().isQtQuick3DTexture() + && node.parentProperty().parentModelNode() == Utils3D::materialLibraryNode(this)) { + ModelNode currentSelection = Utils3D::selectedTexture(this); + if (currentSelection) { + m_selectedTexture = currentSelection; + asyncResetView(); + } else { + QTimer::singleShot(0, this, [node]() { + Utils3D::selectTexture(node); + }); + } + } + } } void TextureEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode) { - if (removedNode.id() == Constants::MATERIAL_LIB_ID && m_qmlBackEnd && m_qmlBackEnd->contextObject()) + if (removedNode.id() == Constants::MATERIAL_LIB_ID && m_qmlBackEnd && m_qmlBackEnd->contextObject()) { m_qmlBackEnd->contextObject()->setHasMaterialLibrary(false); + asyncResetView(); + } else if (removedNode == m_selectedTexture) { + ModelNode matLib = Utils3D::materialLibraryNode(this); + QTC_ASSERT(matLib.isValid(), return); + + const QList textures = matLib.directSubModelNodesOfType( + model()->qtQuick3DTextureMetaInfo()); + bool selectedNodeFound = false; + m_newSelectedTexture = {}; + for (const ModelNode &tex : textures) { + if (selectedNodeFound) { + m_newSelectedTexture = tex; + break; + } + if (m_selectedTexture == tex) + selectedNodeFound = true; + else + m_newSelectedTexture = tex; + } + m_selectedTextureChanged = true; + } +} + +void TextureEditorView::nodeRemoved([[maybe_unused]] const ModelNode &removedNode, + [[maybe_unused]] const NodeAbstractProperty &parentProperty, + [[maybe_unused]] PropertyChangeFlags propertyChange) +{ + if (m_selectedTextureChanged) + asyncResetView(); } bool TextureEditorView::hasWidget() const diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h index 28f76448538..bc5806879b4 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h @@ -53,6 +53,9 @@ public: const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange) override; void nodeAboutToBeRemoved(const ModelNode &removedNode) override; + void nodeRemoved(const ModelNode &removedNode, + const NodeAbstractProperty &parentProperty, + PropertyChangeFlags propertyChange) override; void resetView(); void currentStateChanged(const ModelNode &node) override; @@ -102,6 +105,7 @@ private: void duplicateTexture(const ModelNode &texture); bool noValidSelection() const; + void asyncResetView(); AsynchronousImageCache &m_imageCache; ModelNode m_selectedTexture; @@ -117,6 +121,8 @@ private: bool m_hasQuick3DImport = false; bool m_hasTextureRoot = false; bool m_initializingPreviewData = false; + ModelNode m_newSelectedTexture; + bool m_selectedTextureChanged = false; QPointer m_colorDialog; QPointer m_createTexture; From 8f97c61aa8db5410e72e452ad1a244f975c9f439 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Fri, 23 Aug 2024 16:52:12 +0200 Subject: [PATCH 093/193] QmlProject: Open a fake project if a single .ui.qml file is opened If a single ui.qml file is opened in Qt Design Studio we open a fake project that includes the folder of the opened ui.qml file. If a .ui.qml file is opened and no project is opened in Qt Design Studio we open a "fake" project with the specific name, that provides a default. We can later extend this to supporting import paths and other advanced features. Task-number: QDS-13171 Change-Id: Icecb669d7149c4850da7dd908e9b3e1619d74c7d Reviewed-by: Burak Hancerli Reviewed-by: Thomas Hartmann --- .../buildsystem/projectitem/converters.cpp | 15 ++++++++++++++- .../buildsystem/projectitem/qmlprojectitem.cpp | 14 ++++++++++++++ .../buildsystem/qmlbuildsystem.cpp | 8 ++++++-- src/plugins/qmlprojectmanager/qmlproject.cpp | 10 +++++++++- .../qmlprojectmanager/qmlprojectconstants.h | 2 ++ .../qmlprojectmanager/qmlprojectplugin.cpp | 15 ++++++++++++++- 6 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp b/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp index 2fa96af8c27..515c80de40e 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp @@ -321,7 +321,20 @@ QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile) { QmlJS::SimpleReader simpleQmlJSReader; - const QmlJS::SimpleReaderNode::Ptr rootNode = simpleQmlJSReader.readFile(projectFile.toFSPathString()); + QmlJS::SimpleReaderNode::Ptr rootNode; + + if (!projectFile.isEmpty()) { + rootNode = simpleQmlJSReader.readFile(projectFile.toFSPathString()); + } else { + rootNode = simpleQmlJSReader.readFromSource("import QmlProject 1.1\n" + + "Project {\n" + "QmlFiles {\n" + "directory: \".\"\n" + "}\n" + "qt6Project: true\n" + "}\n"); + } if (!simpleQmlJSReader.errors().isEmpty() || !rootNode->isValid()) { qCritical() << "Unable to parse:" << projectFile; diff --git a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp index 12436f08ce4..77221c3a5e0 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp @@ -8,6 +8,9 @@ #include "converters.h" +#include +#include + #include #include #include @@ -28,6 +31,17 @@ QmlProjectItem::QmlProjectItem(const Utils::FilePath &filePath, const bool skipR bool QmlProjectItem::initProjectObject() { + if (m_projectFile.endsWith(Constants::fakeProjectName)) { + auto uiFile = m_projectFile.toString(); + uiFile.remove(Constants::fakeProjectName); + + auto parentDir = Utils::FilePath::fromString(uiFile).parentDir(); + m_projectFile = parentDir.pathAppended(Constants::fakeProjectName); + m_project = Converters::qmlProjectTojson({}); + + return true; + } + auto contents = m_projectFile.fileContents(); if (!contents) { qWarning() << "Cannot open project file. Path:" << m_projectFile.fileName(); diff --git a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp index e66acd36e45..0813e1dd03d 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp @@ -218,7 +218,9 @@ void QmlBuildSystem::refresh(RefreshOptions options) void QmlBuildSystem::initProjectItem() { - m_projectItem.reset(new QmlProjectItem{projectFilePath()}); + auto projectPath = projectFilePath(); + + m_projectItem.reset(new QmlProjectItem{projectPath}); connect(m_projectItem.data(), &QmlProjectItem::filesChanged, this, &QmlBuildSystem::refreshFiles); m_fileGen->updateProjectItem(m_projectItem.data(), true); @@ -281,6 +283,7 @@ void QmlBuildSystem::generateProjectTree() const FileType fileType = (file == projectFilePath()) ? FileType::Project : FileNode::fileTypeForFileName(file); + newRoot->addNestedNode(std::make_unique(file, fileType)); } @@ -293,7 +296,8 @@ void QmlBuildSystem::generateProjectTree() newRoot->addNestedNode(std::make_unique(file, fileType)); } } - newRoot->addNestedNode(std::make_unique(projectFilePath(), FileType::Project)); + if (!projectFilePath().endsWith(Constants::fakeProjectName)) + newRoot->addNestedNode(std::make_unique(projectFilePath(), FileType::Project)); setRootProjectNode(std::move(newRoot)); updateDeploymentData(); diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index 388169b3756..22aac059b05 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -54,12 +54,20 @@ QmlProject::QmlProject(const Utils::FilePath &fileName) setBuildSystemCreator([](Target *t) { return new QmlBuildSystem(t); }); if (Core::ICore::isQtDesignStudio()) { - if (allowOnlySingleProject()) { + if (allowOnlySingleProject() && !fileName.endsWith(Constants::fakeProjectName)) { EditorManager::closeAllDocuments(); ProjectManager::closeAllProjects(); } } + if (fileName.endsWith(Constants::fakeProjectName)) { + auto uiFile = fileName.toString(); + uiFile.remove(Constants::fakeProjectName); + auto parentDir = Utils::FilePath::fromString(uiFile).parentDir(); + + setDisplayName(parentDir.completeBaseName()); + } + connect(this, &QmlProject::anyParsingFinished, this, &QmlProject::parsingFinished); } diff --git a/src/plugins/qmlprojectmanager/qmlprojectconstants.h b/src/plugins/qmlprojectmanager/qmlprojectconstants.h index ad779481056..0d0a35e884a 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectconstants.h +++ b/src/plugins/qmlprojectmanager/qmlprojectconstants.h @@ -35,4 +35,6 @@ const char EXPORT_MENU[] = "QmlDesigner.ExportMenu"; const char G_EXPORT_GENERATE[] = "QmlDesigner.Group.GenerateProject"; const char G_EXPORT_CONVERT[] = "QmlDesigner.Group.ConvertProject"; +const char fakeProjectName[] = "fake85673.qmlproject"; + } // QmlProjectManager::Constants diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp index a30aec37830..2f8ce7c7f42 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp @@ -25,12 +25,12 @@ #include +#include #include #include #include #include #include -#include #include #include @@ -403,6 +403,19 @@ void QmlProjectPlugin::initialize() != fileNode->filePath()); }); + connect(EditorManager::instance(), + &EditorManager::documentOpened, + this, + [](Core::IDocument *document) { + if (!ProjectManager::startupProject() + && document->filePath().completeSuffix() == "ui.qml") { + const Utils::FilePath fileName = Utils::FilePath::fromString( + document->filePath().toString() + Constants::fakeProjectName); + auto result = ProjectExplorer::ProjectExplorerPlugin::openProjects({fileName}); + QTC_ASSERT(result.project(), return); + } + }); + QmlProjectExporter::CMakeGenerator::createMenuAction(this); QmlProjectExporter::PythonGenerator::createMenuAction(this); } From bd659cba562da6126d455e87af81e4e6d6f113fe Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 20 Aug 2024 15:55:35 +0200 Subject: [PATCH 094/193] TextEditor: Move TabSettings to library TabSettings are used in designer core, which is a library. So it needs to be in a library too. Change-Id: I3c750e108a531c1666af0ecbeb1d06eb4b95f56d Reviewed-by: David Schulz --- src/plugins/texteditor/CMakeLists.txt | 10 ++++++++-- src/plugins/texteditor/tabsettings.cpp | 7 +------ src/plugins/texteditor/texteditorplugin.cpp | 3 +++ 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/plugins/texteditor/CMakeLists.txt b/src/plugins/texteditor/CMakeLists.txt index 22abf9d8a1e..064e1bc75b7 100644 --- a/src/plugins/texteditor/CMakeLists.txt +++ b/src/plugins/texteditor/CMakeLists.txt @@ -4,9 +4,16 @@ else() set(KSYNTAXHIGHLIGHTING_TARGET KF5::SyntaxHighlighting) endif() +add_qtc_library(TextEditorSupport STATIC + DEPENDS Utils + DEFINES TEXTEDITOR_LIBRARY + SOURCES + tabsettings.cpp tabsettings.h +) + add_qtc_plugin(TextEditor DEPENDS Qt::Concurrent Qt::Network Qt::PrintSupport Qt::Xml - PUBLIC_DEPENDS ${KSYNTAXHIGHLIGHTING_TARGET} + PUBLIC_DEPENDS ${KSYNTAXHIGHLIGHTING_TARGET} TextEditorSupport PLUGIN_DEPENDS Core SOURCES autocompleter.cpp autocompleter.h @@ -95,7 +102,6 @@ add_qtc_plugin(TextEditor snippets/snippetssettingspage.cpp snippets/snippetssettingspage.h storagesettings.cpp storagesettings.h syntaxhighlighter.cpp syntaxhighlighter.h - tabsettings.cpp tabsettings.h tabsettingswidget.cpp tabsettingswidget.h textdocument.cpp textdocument.h textdocumentlayout.cpp textdocumentlayout.h diff --git a/src/plugins/texteditor/tabsettings.cpp b/src/plugins/texteditor/tabsettings.cpp index 222335133d5..6c01907958e 100644 --- a/src/plugins/texteditor/tabsettings.cpp +++ b/src/plugins/texteditor/tabsettings.cpp @@ -3,9 +3,6 @@ #include "tabsettings.h" -#include "icodestylepreferences.h" -#include "texteditorsettings.h" - #include #include #include @@ -350,9 +347,7 @@ bool TabSettings::equals(const TabSettings &ts) const && m_continuationAlignBehavior == ts.m_continuationAlignBehavior; } -static TabSettings::Retriever g_retriever = [](const FilePath &) { - return TextEditorSettings::codeStyle()->tabSettings(); -}; +static TabSettings::Retriever g_retriever = [](const FilePath &) { return TabSettings{}; }; void TabSettings::setRetriever(const Retriever &retriever) { g_retriever = retriever; } diff --git a/src/plugins/texteditor/texteditorplugin.cpp b/src/plugins/texteditor/texteditorplugin.cpp index 047f0a3f973..b5c208e39c6 100644 --- a/src/plugins/texteditor/texteditorplugin.cpp +++ b/src/plugins/texteditor/texteditorplugin.cpp @@ -105,6 +105,9 @@ void TextEditorPlugin::initialize() // FIXME: This kind of dependency should not exist. setupTextEditorSettings(); + TabSettings::setRetriever( + [](const FilePath &) { return TextEditorSettings::codeStyle()->tabSettings(); }); + setupTextMarkRegistry(this); setupOutlineFactory(); setupTypeHierarchyFactory(); From ef7a8dcec3cf8e26823faf5fd1e35efb60e88a7a Mon Sep 17 00:00:00 2001 From: Shrief Gabr Date: Tue, 27 Aug 2024 11:16:31 +0300 Subject: [PATCH 095/193] QmlDesigner: List folders before files in Assets Library Fixes: QDS-8932 Change-Id: I5ad19185a6a04cb1be26c8d4b779ffd612d4685d Reviewed-by: Ali Kianian Reviewed-by: Mahmoud Badri --- .../assetslibrary/assetslibrarymodel.cpp | 20 +++++++++++++++++-- .../assetslibrary/assetslibrarymodel.h | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp index 2a496f6bf38..e776f8abe74 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp @@ -24,8 +24,7 @@ AssetsLibraryModel::AssetsLibraryModel(QObject *parent) : QSortFilterProxyModel{parent} { createBackendModel(); - - setRecursiveFilteringEnabled(true); + sort(0); } void AssetsLibraryModel::createBackendModel() @@ -336,4 +335,21 @@ QString AssetsLibraryModel::parentDirPath(const QString &path) const return filePath(parentIdx); } +bool AssetsLibraryModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +{ + bool leftIsDir = m_sourceFsModel->isDir(left); + bool rightIsDir = m_sourceFsModel->isDir(right); + + if (leftIsDir && !rightIsDir) + return true; + + if (!leftIsDir && rightIsDir) + return false; + + const QString leftName = m_sourceFsModel->fileName(left); + const QString rightName = m_sourceFsModel->fileName(right); + + return QString::localeAwareCompare(leftName, rightName) < 0; +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h index 986ad4cc205..d1a78bcaf57 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h @@ -69,6 +69,7 @@ signals: private: void setHasFiles(bool value); bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; + bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; void resetModel(); void createBackendModel(); void destroyBackendModel(); From 1712e86e665c68200ccf405e2694d70a6d2b64bd Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Wed, 28 Aug 2024 12:39:25 +0300 Subject: [PATCH 096/193] Doc: Document camera view MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QDS-13467 Change-Id: I4a4832649da0db31cf444eb01f2bc8a2323346ca Reviewed-by: Ali Kianian Reviewed-by: Teea Põldsam Reviewed-by: Mats Honkamaa --- .../images/3d-view-camera-view.webp | Bin 0 -> 49170 bytes .../qtdesignstudio-3d-editor.qdoc | 24 ++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 doc/qtdesignstudio/images/3d-view-camera-view.webp diff --git a/doc/qtdesignstudio/images/3d-view-camera-view.webp b/doc/qtdesignstudio/images/3d-view-camera-view.webp new file mode 100644 index 0000000000000000000000000000000000000000..a949afb94dd4b1410277961b6fca64f4fa71c4bd GIT binary patch literal 49170 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 XU_C6(U^ZVsQffG(00SFC6o?N1Sx5@O literal 0 HcmV?d00001 diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc index 9bf1320bffe..69a3f70ef58 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc @@ -182,6 +182,30 @@ \li Set a value multiplier for the speed slider. \endlist + \section1 Toggling Camera View + + In the 3D view, you can show a small window displaying the camera view. + + \image 3d-view-camera-view.webp + + To toggle this view, + select \inlineimage icons/visibilityon.png + and then one of the options: + + \table + \row + \li \uicontrol {Hide Camera View} + \li Never shows the camera view. + \row + \li \uicontrol {Show Selected Camera View} + \li Shows the camera view of the selected camera. If no camera is selected, the camera + view is hidden. + \row + \li \uicontrol {Always Show Camera View} + \li Always shows the camera view of the camera that was selected last, even if no camera + is currently selected. + \endtable + \section1 Using Global and Local Orientation In \uicontrol 3D view, you view the scene in global or local orientation From ce5e4b6d7cc3d1fbe273794a0ad03dec7c82f066 Mon Sep 17 00:00:00 2001 From: Shrief Gabr Date: Tue, 27 Aug 2024 14:00:21 +0300 Subject: [PATCH 097/193] QmlDesigner: Fix Assets Library root canvas highlight issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Root canvas or parent directory would stay higlighted if drag dropped an item but did not exit drop area. Fixes: QDS-11287 Change-Id: Iee449da38e92c4b8ae22d84f1a0fe4583c7266e6 Reviewed-by: Henning Gründl Reviewed-by: Mahmoud Badri --- .../assetsLibraryQmlSources/AssetDelegate.qml | 24 ++++++++++--------- .../assetsLibraryQmlSources/Assets.qml | 4 ++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml index 9346cb62e06..7128e8b09e0 100644 --- a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml +++ b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml @@ -338,6 +338,8 @@ TreeViewDelegate { } DropArea { + id: dropArea + anchors.fill: parent anchors.bottomMargin: -assetsView.rowSpacing @@ -349,7 +351,7 @@ TreeViewDelegate { // highlights the root folder canvas area when dragging over child if (root.depth === 1 && !root.__isDirectory) - assetsRoot.highlightCanvas = highlight + root.assetsRoot.highlightCanvas = highlight } onEntered: (drag) => { @@ -358,27 +360,27 @@ TreeViewDelegate { drag.accepted |= (drag.formats[0] === "application/vnd.qtdesignstudio.assets") if (root.__isDirectory) - isHighlighted = drag.accepted + root.isHighlighted = drag.accepted else - updateParentHighlight(drag.accepted) + dropArea.updateParentHighlight(drag.accepted) } onDropped: (drag) => { if (drag.formats[0] === "application/vnd.qtdesignstudio.assets") { - rootView.invokeAssetsDrop(drag.urls, root.getDirPath()) + root.rootView.invokeAssetsDrop(drag.urls, root.getDirPath()) } else { - rootView.emitExtFilesDrop(root.assetsRoot.dropSimpleExtFiles, - root.assetsRoot.dropComplexExtFiles, - root.getDirPath()) + root.rootView.emitExtFilesDrop(root.assetsRoot.dropSimpleExtFiles, + root.assetsRoot.dropComplexExtFiles, + root.getDirPath()) } - isHighlighted = true - updateParentHighlight(true) + root.isHighlighted = false + dropArea.updateParentHighlight(false) } onExited: { - isHighlighted = false - updateParentHighlight(false) + root.isHighlighted = false + dropArea.updateParentHighlight(false) } } } diff --git a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/Assets.qml b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/Assets.qml index 9a9ae4c0919..0514f3dfaef 100644 --- a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/Assets.qml +++ b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/Assets.qml @@ -68,9 +68,9 @@ Item { onDropped: (drag) => { drag.accept() if (drag.formats[0] === "application/vnd.qtdesignstudio.assets") { - rootView.handleAssetsDrop(drag.urls, assetsModel.rootPath()) + root.rootView.handleAssetsDrop(drag.urls, assetsModel.rootPath()) } else { - rootView.handleExtFilesDrop(root.dropSimpleExtFiles, + root.rootView.handleExtFilesDrop(root.dropSimpleExtFiles, root.dropComplexExtFiles, assetsModel.rootPath()) } From c57e0a905fe5c69468e16f418aa1168959a86dd3 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Tue, 27 Aug 2024 16:54:13 +0200 Subject: [PATCH 098/193] QmlDesigner: Fix insight activation Fix insight activation in the insight view. Task-number: QDS-13481 Change-Id: Ib704c98f8519f2ff587d47e9649b9a49f87b5f4f Reviewed-by: Thomas Hartmann --- src/plugins/insight/insightmodel.cpp | 53 ++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/src/plugins/insight/insightmodel.cpp b/src/plugins/insight/insightmodel.cpp index 282020349e0..50474ffecff 100644 --- a/src/plugins/insight/insightmodel.cpp +++ b/src/plugins/insight/insightmodel.cpp @@ -16,6 +16,8 @@ #include #include +#include + #include #include @@ -98,12 +100,25 @@ void setNodeEnabled(const ModelNode &node, bool value) if (node.hasSignalHandlerProperty(signalHandler.toUtf8())) { SignalHandlerProperty property = node.signalHandlerProperty(signalHandler.toUtf8()); - QString src = property.source(); + QString src = property.source().trimmed(); + const QRegularExpression re(regExp.toString()); QRegularExpressionMatch match = re.match(src); - if (match.hasMatch() && !match.capturedView(1).isEmpty()) + if (match.hasMatch() && !match.capturedView(1).isEmpty()) { + // InsightTracker.enabled was found, replace the rhs with value. src.replace(match.capturedStart(1), match.capturedLength(1), valueAsStr); + } else { + // InsightTracker.enabled was NOT found, append it to the source. + if (!src.isEmpty()) { + if (src.endsWith("}")) { + src.insert(src.length() - 1, "\nInsightTracker.enabled = " + valueAsStr + "\n}"); + } else { + src.prepend("{\n"); + src.append("\nInsightTracker.enabled = " + valueAsStr + "\n}"); + } + } + } property.setSource(src); } else { @@ -275,9 +290,28 @@ void InsightModel::setup() if (m_initialized) return; - const QString projectUrl = m_externalDependencies.projectUrl().toLocalFile(); + auto project = ProjectExplorer::ProjectManager::startupProject(); + if (!project) { + qWarning() << "Could not find a startup project."; + return; + } - m_mainQmlInfo = QFileInfo(projectUrl + "/main.qml"); + if (!project->activeTarget()) { + qWarning() << "Could not find an active target."; + return; + } + + auto qmlBuildSystem = qobject_cast( + project->activeTarget()->buildSystem()); + + if (!qmlBuildSystem) { + qWarning() << "Could not find a build system."; + return; + } + + const QString projectUrl = qmlBuildSystem->canonicalProjectDir().path(); + + m_mainQmlInfo = qmlBuildSystem->mainFilePath().toFileInfo(); m_configInfo = QFileInfo(projectUrl + "/" + insightConfFile); m_qtdsConfigInfo = QFileInfo(projectUrl + "/" + qtdsConfFile); @@ -303,12 +337,11 @@ void InsightModel::setup() writeJSON(m_qtdsConfigInfo.absoluteFilePath(), m_qtdsConfig); } - m_fileSystemWatcher->addFile(m_mainQmlInfo.absoluteFilePath(), - Utils::FileSystemWatcher::WatchModifiedDate); - m_fileSystemWatcher->addFile(m_configInfo.absoluteFilePath(), - Utils::FileSystemWatcher::WatchModifiedDate); - m_fileSystemWatcher->addFile(m_qtdsConfigInfo.absoluteFilePath(), - Utils::FileSystemWatcher::WatchModifiedDate); + m_fileSystemWatcher->addFiles( + {m_mainQmlInfo.absoluteFilePath(), + m_configInfo.absoluteFilePath(), + m_qtdsConfigInfo.absoluteFilePath()}, + Utils::FileSystemWatcher::WatchModifiedDate); m_initialized = true; } From 7ecf88678cbb79ad6600c5b88003a0ca4b3d70df Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 28 Aug 2024 17:21:16 +0200 Subject: [PATCH 099/193] QmlDesigner: It is min instead of max We want to limit the offset to the text length. Change-Id: I7514162863b079a217b163850405d64b60bf00d2 Reviewed-by: Marco Bubke --- src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp b/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp index a48927d548a..0033c3bb4e3 100644 --- a/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp +++ b/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp @@ -843,7 +843,7 @@ ModelNode RewriterView::nodeAtTextCursorPositionHelper(const ModelNode &root, in ModelNode node = pair.first; const int textLength = m_textModifier->text().length(); - const int nodeTextOffset = std::max(nodeOffset(node), textLength); + const int nodeTextOffset = std::min(nodeOffset(node), textLength); const int nodeTextLength = findEvenClosingBrace(m_textModifier->text().sliced(nodeTextOffset)) - 1; From 2faf60f5e7a8e629d52925af81564f580140c51a Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 27 Aug 2024 21:45:31 +0200 Subject: [PATCH 100/193] TextEditor: Improve linking of TextEditorSupport Instead of exporting symbols in the static library, We use the WHOLE_ARCHIVE linker option. It is exporting all symbols of the static library to the shared library. CMake 3.24 is supporting a shorter syntax: $ which can simply be added to DEPENDS. Change-Id: I854a16306aabbfca918d197b12da8a5446152d9f Reviewed-by: David Schulz Reviewed-by: Aleksei German --- src/plugins/texteditor/CMakeLists.txt | 14 ++++++++++++-- src/plugins/texteditor/tabsettings.h | 4 ++-- src/plugins/texteditor/texteditorsupport_global.h | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 src/plugins/texteditor/texteditorsupport_global.h diff --git a/src/plugins/texteditor/CMakeLists.txt b/src/plugins/texteditor/CMakeLists.txt index 064e1bc75b7..62e1c2d77bf 100644 --- a/src/plugins/texteditor/CMakeLists.txt +++ b/src/plugins/texteditor/CMakeLists.txt @@ -6,14 +6,14 @@ endif() add_qtc_library(TextEditorSupport STATIC DEPENDS Utils - DEFINES TEXTEDITOR_LIBRARY SOURCES + texteditorsupport_global.h tabsettings.cpp tabsettings.h ) add_qtc_plugin(TextEditor DEPENDS Qt::Concurrent Qt::Network Qt::PrintSupport Qt::Xml - PUBLIC_DEPENDS ${KSYNTAXHIGHLIGHTING_TARGET} TextEditorSupport + PUBLIC_DEPENDS ${KSYNTAXHIGHLIGHTING_TARGET} PLUGIN_DEPENDS Core SOURCES autocompleter.cpp autocompleter.h @@ -130,3 +130,13 @@ extend_qtc_plugin(TextEditor texteditor_test.cpp texteditor_test.h ) + +# from cmake 3.24 $ is supported which can be added to DEPENDS +if (MSVC) + qtc_output_binary_dir(_output_binary_dir) + set_target_properties(TextEditor PROPERTIES LINK_FLAGS "/WHOLEARCHIVE:${_output_binary_dir}/${IDE_BIN_PATH}/TextEditorSupport.lib") +elseif (APPLE) + target_link_libraries(TextEditor PRIVATE -Wl,-force_load $) +else () + target_link_libraries(TextEditor PRIVATE -Wl,--whole-archive $ -Wl,--no-whole-archive) +endif () diff --git a/src/plugins/texteditor/tabsettings.h b/src/plugins/texteditor/tabsettings.h index 6d9c08e6264..0a8e4305713 100644 --- a/src/plugins/texteditor/tabsettings.h +++ b/src/plugins/texteditor/tabsettings.h @@ -3,7 +3,7 @@ #pragma once -#include "texteditor_global.h" +#include "texteditorsupport_global.h" #include #include @@ -17,7 +17,7 @@ namespace TextEditor { // Tab settings: Data type the GeneralSettingsPage acts on // with some convenience functions for formatting. -class TEXTEDITOR_EXPORT TabSettings +class TEXTEDITORSUPPORT_EXPORT TabSettings { public: diff --git a/src/plugins/texteditor/texteditorsupport_global.h b/src/plugins/texteditor/texteditorsupport_global.h new file mode 100644 index 00000000000..de4480aface --- /dev/null +++ b/src/plugins/texteditor/texteditorsupport_global.h @@ -0,0 +1,14 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +#if defined(TEXTEDITORSUPPORT_LIBRARY) +# define TEXTEDITORSUPPORT_EXPORT Q_DECL_EXPORT +#elif defined(TEXTEDITORSUPPORT_STATIC_LIBRARY) +# define TEXTEDITORSUPPORT_EXPORT +#else +# define TEXTEDITORSUPPORT_EXPORT Q_DECL_IMPORT +#endif From 5bb5166d2c22a4816b864e3ccd537c23a1b7df27 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 20 Aug 2024 17:23:02 +0200 Subject: [PATCH 101/193] QmlDesigner: Fix false dependencies We want to get the rewriter under tests. And we want to use the designer core in other projects. There we cannot use plugins. So there should be no dependency on any plugins. There is a follow up patch which ensures, that there cannot any dependency on a plugin in a library. Task-number: QDS-13406 Change-Id: I9a944fb12f7d206252946e6fe9c721c56f8536cf Reviewed-by: Thomas Hartmann --- .../effectcomposer/effectcomposerview.cpp | 6 +- .../effectcomposer/effectcomposerview.h | 4 +- .../effectcomposer/effectcomposerwidget.cpp | 4 +- src/plugins/qmldesigner/CMakeLists.txt | 605 +++--------------- .../assetslibraryiconprovider.cpp | 4 +- .../assetslibrary/assetslibrarymodel.cpp | 2 +- .../assetslibrary/assetslibraryview.cpp | 8 +- .../assetslibrary/assetslibrarywidget.cpp | 2 +- .../bindingeditor/bindingeditorwidget.cpp | 2 +- .../componentcore/designeractionmanager.cpp | 14 +- .../componentcore/modelnodeoperations.cpp | 20 +- .../componentcore/selectioncontext.cpp | 10 +- .../componentcore/selectioncontext.h | 1 + .../connectioneditor/connectionmodel.cpp | 4 +- .../dynamicpropertiesitem.cpp | 2 +- .../contentlibrarymaterialsmodel.h | 2 +- .../contentlibrary/contentlibraryview.cpp | 16 +- .../contentlibrary/contentlibrarywidget.cpp | 6 +- .../curveeditor/curveeditorview.cpp | 2 +- .../components/edit3d/bakelights.cpp | 7 +- .../components/edit3d/edit3dactions.cpp | 4 +- .../components/edit3d/edit3dcanvas.cpp | 15 +- .../components/edit3d/edit3dview.cpp | 15 +- .../components/edit3d/edit3dview.h | 1 + .../components/edit3d/edit3dwidget.cpp | 4 +- .../formeditor/formeditorwidget.cpp | 22 +- .../components/formeditor/movetool.cpp | 2 +- .../components/import3d/import3ddialog.cpp | 4 +- .../itemlibraryiconimageprovider.cpp | 2 +- .../itemlibraryiconimageprovider.h | 6 +- .../itemlibrary/itemlibrarymodel.cpp | 2 +- .../itemlibrary/itemlibraryview.cpp | 7 +- .../materialbrowser/materialbrowserview.cpp | 5 +- .../materialbrowser/materialbrowserview.h | 1 + .../materialbrowser/materialbrowserwidget.cpp | 2 +- .../materialeditorcontextobject.cpp | 2 +- .../materialeditor/materialeditorview.cpp | 9 +- .../materialeditor/materialeditorview.h | 1 + .../navigator/navigatortreemodel.cpp | 2 +- .../components/navigator/navigatorview.cpp | 6 +- .../propertyeditor/assetimageprovider.cpp | 4 +- .../dynamicpropertiesproxymodel.cpp | 27 +- .../propertyeditorcontextobject.cpp | 2 +- .../propertyeditorqmlbackend.cpp | 6 +- .../propertyeditor/propertyeditorvalue.cpp | 2 +- .../propertyeditor/propertyeditorvalue.h | 5 +- .../propertyeditor/propertyeditorview.cpp | 10 +- .../propertyeditor/propertyeditorview.h | 1 + .../propertyeditor/qmlanchorbindingproxy.h | 2 +- .../propertyeditor/qmlmodelnodeproxy.h | 2 +- .../stateseditorimageprovider.cpp | 11 +- .../stateseditor/stateseditorimageprovider.h | 4 +- .../stateseditor/stateseditorview.cpp | 5 + .../stateseditor/stateseditorview.h | 1 + .../stateseditor/stateseditorwidget.cpp | 2 +- .../stateseditor/stateseditorwidget.h | 3 +- .../texteditor/texteditorwidget.cpp | 2 +- .../textureeditorcontextobject.cpp | 2 +- .../textureeditor/textureeditorqmlbackend.cpp | 4 +- .../textureeditor/textureeditorview.cpp | 3 +- .../textureeditor/textureeditorview.h | 1 + .../timelineeditor/timelinegraphicsscene.cpp | 5 +- .../timelineeditor/timelineview.cpp | 40 +- .../components/timelineeditor/timelineview.h | 4 + .../timelineeditor/timelinewidget.cpp | 8 +- .../designercoreutils/skipiterator.h | 77 --- .../designercore/include/nodeanchors.h | 85 --- src/plugins/qmldesigner/designmodecontext.cpp | 18 +- .../imagecachecollector.cpp | 0 .../imagecachecollector.h | 2 +- .../imagecacheconnectionmanager.cpp | 0 .../imagecacheconnectionmanager.h | 2 +- .../imagecachefontcollector.cpp | 0 .../imagecachefontcollector.h | 2 +- .../meshimagecachecollector.cpp | 0 .../meshimagecachecollector.h | 1 - .../textureimagecachecollector.cpp | 4 +- .../textureimagecachecollector.h | 2 +- .../instances/baseconnectionmanager.cpp | 0 .../instances/baseconnectionmanager.h | 3 +- .../instances/capturingconnectionmanager.cpp | 0 .../instances/capturingconnectionmanager.h | 4 +- .../instances/connectionmanager.cpp | 0 .../instances/connectionmanager.h | 2 +- .../instances/connectionmanagerinterface.cpp | 0 .../instances/connectionmanagerinterface.h | 6 +- .../interactiveconnectionmanager.cpp | 5 +- .../instances/interactiveconnectionmanager.h | 0 .../instances/nodeinstance.cpp | 0 .../include => instances}/nodeinstance.h | 0 .../instances/nodeinstanceserverproxy.cpp | 0 .../instances/nodeinstanceserverproxy.h | 0 .../instances/nodeinstanceview.cpp | 147 +++-- .../include => instances}/nodeinstanceview.h | 25 +- .../instances/puppetstarter.cpp | 0 .../instances/puppetstarter.h | 0 .../instances/qprocessuniqueptr.h | 0 src/plugins/qmldesigner/libs/CMakeLists.txt | 2 + .../libs/designercore/CMakeLists.txt | 405 ++++++++++++ .../generatedcomponentutils.cpp | 106 +-- .../generatedcomponentutils.h | 0 .../designercoreutils/modelmerger.cpp | 0 .../designercoreutils/modelmerger.h | 0 .../designercoreutils/modelutils.cpp | 1 - .../designercoreutils/modelutils.h | 0 .../designercoreutils/predicate.h | 0 .../designercoreutils/stylesheetmerger.cpp | 0 .../designercoreutils/stylesheetmerger.h | 0 .../designercoreutils/uniquename.cpp | 2 +- .../designercoreutils/uniquename.h | 5 +- .../designercore/exceptions/exception.cpp | 0 .../exceptions/invalidargumentexception.cpp | 0 .../exceptions/invalididexception.cpp | 0 .../exceptions/invalidmetainfoexception.cpp | 0 .../exceptions/invalidmodelnodeexception.cpp | 0 .../exceptions/invalidmodelstateexception.cpp | 0 .../exceptions/invalidpropertyexception.cpp | 0 .../exceptions/invalidqmlsourceexception.cpp | 0 .../invalidreparentingexception.cpp | 0 .../exceptions/invalidslideindexexception.cpp | 0 .../exceptions/notimplementedexception.cpp | 0 .../exceptions/removebasestateexception.cpp | 0 .../exceptions/rewritingexception.cpp | 0 .../filemanager/addarraymembervisitor.cpp | 0 .../filemanager/addarraymembervisitor.h | 0 .../filemanager/addobjectvisitor.cpp | 0 .../filemanager/addobjectvisitor.h | 0 .../filemanager/addpropertyvisitor.cpp | 0 .../filemanager/addpropertyvisitor.h | 0 .../filemanager/astobjecttextextractor.cpp | 0 .../filemanager/astobjecttextextractor.h | 0 .../filemanager/changeimportsvisitor.cpp | 0 .../filemanager/changeimportsvisitor.h | 0 .../filemanager/changeobjecttypevisitor.cpp | 0 .../filemanager/changeobjecttypevisitor.h | 0 .../filemanager/changepropertyvisitor.cpp | 0 .../filemanager/changepropertyvisitor.h | 0 .../filemanager/firstdefinitionfinder.cpp | 0 .../filemanager/firstdefinitionfinder.h | 0 .../moveobjectbeforeobjectvisitor.cpp | 0 .../moveobjectbeforeobjectvisitor.h | 0 .../filemanager/moveobjectvisitor.cpp | 0 .../filemanager/moveobjectvisitor.h | 0 .../filemanager/objectlengthcalculator.cpp | 0 .../filemanager/objectlengthcalculator.h | 0 .../filemanager/qmlrefactoring.cpp | 0 .../designercore/filemanager/qmlrefactoring.h | 0 .../designercore/filemanager/qmlrewriter.cpp | 0 .../designercore/filemanager/qmlrewriter.h | 0 .../filemanager/removepropertyvisitor.cpp | 0 .../filemanager/removepropertyvisitor.h | 0 .../removeuiobjectmembervisitor.cpp | 0 .../filemanager/removeuiobjectmembervisitor.h | 0 .../asynchronousexplicitimagecache.cpp | 0 .../imagecache/asynchronousimagecache.cpp | 0 .../imagecache/asynchronousimagefactory.cpp | 2 +- .../imagecache/asynchronousimagefactory.h | 3 +- .../explicitimagecacheimageprovider.cpp | 0 .../explicitimagecacheimageprovider.h | 4 +- .../imagecache/imagecachecollectorinterface.h | 0 .../imagecache/imagecachedispatchcollector.h | 0 .../imagecache/imagecachegenerator.cpp | 0 .../imagecache/imagecachegenerator.h | 3 +- .../imagecache/imagecachegeneratorinterface.h | 0 .../imagecache/imagecacheimageresponse.cpp | 0 .../imagecache/imagecacheimageresponse.h | 4 +- .../imagecache/imagecachestorage.h | 0 .../imagecache/imagecachestorageinterface.h | 0 .../imagecache/midsizeimagecacheprovider.cpp | 0 .../imagecache/midsizeimagecacheprovider.h | 4 +- .../imagecache/smallimagecacheprovider.cpp | 0 .../imagecache/smallimagecacheprovider.h | 4 +- .../imagecache/synchronousimagecache.cpp | 0 .../designercore/imagecache/taskqueue.h | 0 .../imagecache/timestampprovider.cpp | 0 .../imagecache/timestampprovider.h | 4 +- .../imagecache/timestampproviderinterface.h | 0 .../designercore/include/abstractproperty.h | 2 - .../designercore/include/abstractview.h | 61 +- .../designercore/include/annotation.h | 8 +- .../include/asynchronousexplicitimagecache.h | 3 +- .../include/asynchronousimagecache.h | 3 +- .../include/asynchronousimagecacheinterface.h | 0 .../designercore/include/auxiliarydata.h | 0 .../include/auxiliarydataproperties.h | 0 .../designercore/include/bindingproperty.h | 0 .../designercore/include/bytearraymodifier.h | 0 .../include/componenttextmodifier.h | 2 +- .../include/customnotificationpackage.h | 23 + .../include/customnotifications.h | 0 .../designercore/include/documentmessage.h | 0 .../include/enumerationmetainfo.h | 0 .../designercore/include/exception.h | 0 .../include/externaldependenciesinterface.h | 3 +- .../include/filesystemfacadeinterface.h | 0 .../designercore/include/forwardview.h | 0 .../include/imagecacheauxiliarydata.h | 0 .../{ => libs}/designercore/include/import.h | 0 .../include/invalidargumentexception.h | 0 .../designercore/include/invalididexception.h | 0 .../include/invalidmetainfoexception.h | 0 .../include/invalidmodelnodeexception.h | 0 .../include/invalidmodelstateexception.h | 0 .../include/invalidpropertyexception.h | 0 .../include/invalidqmlsourceexception.h | 0 .../include/invalidreparentingexception.h | 0 .../include/invalidslideindexexception.h | 0 .../designercore/include/itemlibraryentry.h | 0 .../designercore/include/itemlibraryinfo.h | 0 .../designercore/include/iwidgetplugin.h | 0 .../designercore/include/mathutils.h | 0 .../designercore/include/metainfo.h | 0 .../designercore/include/metainforeader.h | 0 .../{ => libs}/designercore/include/model.h | 49 +- .../designercore/include/modelcache.h | 0 .../designercore/include/modelfwd.h | 0 .../designercore/include/modelnode.h | 0 .../include/modificationgroupexception.h | 0 .../include/modificationgrouptoken.h | 0 .../{ => libs}/designercore/include/module.h | 0 .../include/nodeabstractproperty.h | 0 .../designercore/include/nodehints.h | 0 .../designercore/include/nodelistproperty.h | 1 - .../designercore/include/nodemetainfo.h | 0 .../designercore/include/nodeproperty.h | 0 .../include/notimplementedexception.h | 0 .../include/objectpropertybinding.h | 0 .../include/plaintexteditmodifier.h | 11 +- .../designercore/include/projectstorageids.h | 0 .../designercore/include/propertybinding.h | 0 .../designercore/include/propertycontainer.h | 0 .../designercore/include/propertymetainfo.h | 0 .../designercore/include/propertynode.h | 0 .../designercore/include/propertyparser.h | 0 .../designercore/include}/puppetstartdata.h | 0 .../include/qmldesignercoreconstants.h | 13 + .../include/qmldesignercorelib_exports.h | 0 .../include/qmldesignercorelib_global.h | 0 .../include/removebasestateexception.h | 0 .../include/rewritertransaction.h | 6 +- .../designercore/include/rewriterview.h | 0 .../designercore/include/rewritingexception.h | 0 .../include/signalhandlerproperty.h | 0 .../designercore/include/sourcepathids.h | 0 .../designercore/include/stringutils.h | 0 .../include/subcomponentmanager.h | 0 .../include/synchronousimagecache.h | 3 +- .../designercore/include/textmodifier.h | 0 .../designercore/include/variantproperty.h | 0 .../metainfo/itemlibraryentry.cpp | 0 .../designercore/metainfo/itemlibraryinfo.cpp | 2 - .../designercore/metainfo/metainfo.cpp | 24 +- .../designercore/metainfo/metainforeader.cpp | 0 .../designercore/metainfo/nodehints.cpp | 0 .../designercore/metainfo/nodemetainfo.cpp | 0 .../metainfo/propertycontainer.cpp | 0 .../metainfo/subcomponentmanager.cpp | 12 +- .../designercore/model/abstractproperty.cpp | 8 - .../designercore/model/abstractview.cpp | 175 +---- .../designercore/model/annotation.cpp | 0 .../model/auxiliarypropertystorageview.cpp | 0 .../model/auxiliarypropertystorageview.h | 2 +- .../designercore/model/bindingproperty.cpp | 0 .../designercore/model/documentmessage.cpp | 0 .../{ => libs}/designercore/model/import.cpp | 2 +- .../model/internalbindingproperty.cpp | 0 .../model/internalbindingproperty.h | 0 .../designercore/model/internalnode.cpp | 0 .../designercore/model/internalnode_p.h | 0 .../model/internalnodeabstractproperty.cpp | 0 .../model/internalnodeabstractproperty.h | 0 .../model/internalnodelistproperty.cpp | 0 .../model/internalnodelistproperty.h | 0 .../model/internalnodeproperty.cpp | 0 .../designercore/model/internalnodeproperty.h | 0 .../designercore/model/internalproperty.cpp | 0 .../designercore/model/internalproperty.h | 0 .../model/internalsignalhandlerproperty.cpp | 0 .../model/internalsignalhandlerproperty.h | 0 .../model/internalvariantproperty.cpp | 0 .../model/internalvariantproperty.h | 0 .../{ => libs}/designercore/model/model.cpp | 178 +++++- .../{ => libs}/designercore/model/model_p.h | 15 +- .../designercore/model/modelnode.cpp | 2 +- .../model/modelresourcemanagement.cpp | 0 .../model/modelresourcemanagement.h | 2 +- .../model/modelresourcemanagementfwd.h | 0 .../model/modelresourcemanagementinterface.h | 0 .../model/nodeabstractproperty.cpp | 0 .../designercore/model/nodelistproperty.cpp | 15 - .../designercore/model/nodeproperty.cpp | 0 .../model/signalhandlerproperty.cpp | 0 .../designercore/model/variantproperty.cpp | 0 .../pluginmanager/widgetpluginmanager.cpp | 0 .../pluginmanager/widgetpluginmanager.h | 0 .../pluginmanager/widgetpluginpath.cpp | 0 .../pluginmanager/widgetpluginpath.h | 0 .../projectstorage/commontypecache.h | 0 .../projectstorage/directorypathcompressor.h | 0 .../designercore/projectstorage/filestatus.h | 0 .../projectstorage/filestatuscache.cpp | 0 .../projectstorage/filestatuscache.h | 5 +- .../projectstorage/filesystem.cpp | 0 .../designercore/projectstorage/filesystem.h | 2 +- .../projectstorage/filesysteminterface.h | 0 .../projectstorage/modulescanner.cpp | 0 .../projectstorage/modulescanner.h | 0 .../projectstorage/projectstorage.cpp | 0 .../projectstorage/projectstorage.h | 2 +- .../projectstorageerrornotifier.cpp | 0 .../projectstorageerrornotifier.h | 4 +- .../projectstorageerrornotifierinterface.h | 0 .../projectstorageexceptions.cpp | 0 .../projectstorage/projectstorageexceptions.h | 0 .../projectstorage/projectstoragefwd.h | 0 .../projectstorage/projectstorageinfotypes.h | 0 .../projectstorage/projectstorageinterface.h | 0 .../projectstorage/projectstorageobserver.h | 0 .../projectstoragepathwatcher.h | 0 .../projectstoragepathwatcherinterface.h | 0 ...ojectstoragepathwatchernotifierinterface.h | 0 .../projectstoragepathwatchertypes.h | 0 .../projectstorage/projectstorageprinting.h | 0 .../projectstorage/projectstoragetypes.h | 0 .../projectstorage/projectstorageupdater.cpp | 0 .../projectstorage/projectstorageupdater.h | 3 +- .../projectstorage/qmldocumentparser.cpp | 0 .../projectstorage/qmldocumentparser.h | 4 +- .../qmldocumentparserinterface.h | 0 .../projectstorage/qmltypesparser.cpp | 0 .../projectstorage/qmltypesparser.h | 4 +- .../projectstorage/qmltypesparserinterface.h | 0 .../projectstorage/typeannotationreader.cpp | 0 .../projectstorage/typeannotationreader.h | 0 .../rewriter/componenttextmodifier.cpp | 0 .../modelnodepositionrecalculator.cpp | 0 .../rewriter/modelnodepositionrecalculator.h | 0 .../rewriter/modelnodepositionstorage.cpp | 0 .../rewriter/modelnodepositionstorage.h | 0 .../rewriter/modeltotextmerger.cpp | 0 .../designercore/rewriter/modeltotextmerger.h | 0 .../rewriter/plaintexteditmodifier.cpp | 27 - .../rewriter/propertycontainer.cpp | 0 .../designercore/rewriter/propertynode.cpp | 0 .../designercore/rewriter/propertyparser.cpp | 0 .../rewriter}/qmltextgenerator.cpp | 0 .../designercore/rewriter}/qmltextgenerator.h | 0 .../designercore/rewriter/rewriteaction.cpp | 0 .../designercore/rewriter/rewriteaction.h | 0 .../rewriter/rewriteactioncompressor.cpp | 0 .../rewriter/rewriteactioncompressor.h | 0 .../rewriter/rewritertransaction.cpp | 30 +- .../designercore/rewriter/rewriterview.cpp | 5 +- .../designercore/rewriter/textmodifier.cpp | 0 .../rewriter/texttomodelmerger.cpp | 0 .../designercore/rewriter/texttomodelmerger.h | 0 .../sourcepathstorage/nonlockingmutex.h | 0 .../sourcepathstorage/sourcepath.h | 0 .../sourcepathstorage/sourcepathcache.h | 0 .../sourcepathcacheinterface.h | 0 .../sourcepathstorage/sourcepathcachetypes.h | 0 .../sourcepathexceptions.cpp | 0 .../sourcepathstorage/sourcepathexceptions.h | 0 .../sourcepathstorage/sourcepathstorage.cpp | 0 .../sourcepathstorage/sourcepathstorage.h | 0 .../sourcepathstorage/sourcepathview.h | 0 .../sourcepathstorage/storagecache.h | 0 .../sourcepathstorage/storagecacheentry.h | 0 .../sourcepathstorage/storagecachefwd.h | 0 .../tracing/qmldesignertracing.cpp | 0 .../designercore/tracing/qmldesignertracing.h | 0 .../libs/qmldesignerutils/CMakeLists.txt | 25 + .../qmldesignerutils}/asset.cpp | 0 .../{utils => libs/qmldesignerutils}/asset.h | 0 .../qmldesignerutils}/designeralgorithm.h | 0 .../qmldesignerutils}/filedownloader.cpp | 0 .../qmldesignerutils}/filedownloader.h | 0 .../qmldesignerutils}/fileextractor.cpp | 0 .../qmldesignerutils}/fileextractor.h | 0 .../qmldesignerutils}/hdrimage.cpp | 0 .../qmldesignerutils}/hdrimage.h | 0 .../qmldesignerutils}/imageutils.cpp | 0 .../qmldesignerutils}/imageutils.h | 0 .../qmldesignerutils}/ktximage.cpp | 0 .../qmldesignerutils}/ktximage.h | 0 .../qmldesignerutils}/multifiledownloader.cpp | 0 .../qmldesignerutils}/multifiledownloader.h | 0 .../qmldesignerutils_global.h | 0 .../qmldesignerutils}/version.cpp | 0 .../qmldesignerutils}/version.h | 0 .../qmldesigner/qmldesignerconstants.h | 50 +- .../qmldesignerexternaldependencies.cpp | 5 + .../qmldesignerexternaldependencies.h | 1 + src/plugins/qmldesigner/qmldesignerplugin.cpp | 12 +- .../qmldesigner/qmldesignerprojectmanager.cpp | 10 +- .../model => qmltools}/anchorline.cpp | 0 .../include => qmltools}/anchorline.h | 4 +- .../{designercore => }/qmltools/qml3dnode.cpp | 0 .../include => qmltools}/qml3dnode.h | 10 +- .../qmltools/qmlanchors.cpp | 0 .../include => qmltools}/qmlanchors.h | 6 +- .../qmltools/qmlchangeset.cpp | 0 .../include => qmltools}/qmlchangeset.h | 7 +- .../qmltools/qmlconnections.cpp | 0 .../include => qmltools}/qmlconnections.h | 3 +- .../qmltools/qmlitemnode.cpp | 0 .../include => qmltools}/qmlitemnode.h | 18 +- .../qmltools/qmlmodelnodefacade.cpp | 10 +- .../include => qmltools}/qmlmodelnodefacade.h | 6 +- .../qmltools/qmlobjectnode.cpp | 10 +- .../include => qmltools}/qmlobjectnode.h | 7 +- .../{designercore => }/qmltools/qmlstate.cpp | 0 .../include => qmltools}/qmlstate.h | 3 +- .../qmltools/qmltimeline.cpp | 2 +- .../include => qmltools}/qmltimeline.h | 3 +- .../qmltools/qmltimelinekeyframegroup.cpp | 0 .../qmltimelinekeyframegroup.h | 3 +- .../qmltools/qmlvisualnode.cpp | 0 .../include => qmltools}/qmlvisualnode.h | 11 +- src/plugins/qmldesigner/shortcutmanager.cpp | 37 +- .../basetexteditmodifier.cpp | 0 .../basetexteditmodifier.h | 7 +- .../indentingtexteditormodifier.cpp | 36 ++ .../indentingtexteditormodifier.h | 19 + src/plugins/qmldesignerbase/CMakeLists.txt | 30 +- .../qmldesignerbase/qmldesignerbaseplugin.cpp | 3 +- .../{utils => settings}/designersettings.cpp | 0 .../{utils => settings}/designersettings.h | 4 +- .../settings/qmldesignersettings_global.h | 14 + src/plugins/qmlprojectmanager/CMakeLists.txt | 2 +- src/plugins/saferenderer/CMakeLists.txt | 2 +- src/plugins/studiowelcome/examplecheckout.cpp | 2 +- src/plugins/studiowelcome/examplecheckout.h | 2 +- tests/auto/qml/qmldesigner/CMakeLists.txt | 2 +- .../qml/qmldesigner/coretests/CMakeLists.txt | 1 + tests/unit/tests/CMakeLists.txt | 9 +- .../tests/mocks/externaldependenciesmock.h | 1 + .../tests/printers/gtest-creator-printing.h | 2 +- .../clangcompletionassistinterface.h | 32 - .../designercore/include/documentmessage.h | 48 -- .../designercore/include/itemlibraryitem.h | 42 -- .../designercore/include/nodeinstanceview.h | 86 --- .../designercore/include/qmlmodelnodefacade.h | 40 -- .../designercore/include/qmlobjectnode.h | 20 - .../designercore/include/qmlstate.h | 17 - .../designercore/include/qmltimeline.h | 24 - .../designercore/include/rewriterview.h | 155 ----- .../tests/testdesignercore/CMakeLists.txt | 500 ++++++++++----- tests/unit/tests/unittests/CMakeLists.txt | 4 +- .../designercoreutils/version-test.cpp | 2 +- .../unittests/listmodeleditor/CMakeLists.txt | 8 +- .../listmodeleditor/listmodeleditor-test.cpp | 12 +- .../tests/unittests/model/import-test.cpp | 2 +- .../unittests/projectstorage/CMakeLists.txt | 2 +- .../unit/tests/unittests/utils/CMakeLists.txt | 7 +- .../unittests/utils/matchingtext-test.cpp | 307 --------- 456 files changed, 1945 insertions(+), 2376 deletions(-) delete mode 100644 src/plugins/qmldesigner/designercore/designercoreutils/skipiterator.h delete mode 100644 src/plugins/qmldesigner/designercore/include/nodeanchors.h rename src/plugins/qmldesigner/{designercore/imagecache => imagecachecollectors}/imagecachecollector.cpp (100%) rename src/plugins/qmldesigner/{designercore/imagecache => imagecachecollectors}/imagecachecollector.h (97%) rename src/plugins/qmldesigner/{designercore/imagecache => imagecachecollectors}/imagecacheconnectionmanager.cpp (100%) rename src/plugins/qmldesigner/{designercore/imagecache => imagecachecollectors}/imagecacheconnectionmanager.h (92%) rename src/plugins/qmldesigner/{designercore/imagecache => imagecachecollectors}/imagecachefontcollector.cpp (100%) rename src/plugins/qmldesigner/{designercore/imagecache => imagecachecollectors}/imagecachefontcollector.h (95%) rename src/plugins/qmldesigner/{designercore/imagecache => imagecachecollectors}/meshimagecachecollector.cpp (100%) rename src/plugins/qmldesigner/{designercore/imagecache => imagecachecollectors}/meshimagecachecollector.h (97%) rename src/plugins/qmldesigner/{designercore/imagecache => imagecachecollectors}/textureimagecachecollector.cpp (96%) rename src/plugins/qmldesigner/{designercore/imagecache => imagecachecollectors}/textureimagecachecollector.h (95%) rename src/plugins/qmldesigner/{designercore => }/instances/baseconnectionmanager.cpp (100%) rename src/plugins/qmldesigner/{designercore => }/instances/baseconnectionmanager.h (91%) rename src/plugins/qmldesigner/{designercore => }/instances/capturingconnectionmanager.cpp (100%) rename src/plugins/qmldesigner/{designercore => }/instances/capturingconnectionmanager.h (84%) rename src/plugins/qmldesigner/{designercore => }/instances/connectionmanager.cpp (100%) rename src/plugins/qmldesigner/{designercore => }/instances/connectionmanager.h (95%) rename src/plugins/qmldesigner/{designercore => }/instances/connectionmanagerinterface.cpp (100%) rename src/plugins/qmldesigner/{designercore => }/instances/connectionmanagerinterface.h (92%) rename src/plugins/qmldesigner/{designercore => }/instances/interactiveconnectionmanager.cpp (95%) rename src/plugins/qmldesigner/{designercore => }/instances/interactiveconnectionmanager.h (100%) rename src/plugins/qmldesigner/{designercore => }/instances/nodeinstance.cpp (100%) rename src/plugins/qmldesigner/{designercore/include => instances}/nodeinstance.h (100%) rename src/plugins/qmldesigner/{designercore => }/instances/nodeinstanceserverproxy.cpp (100%) rename src/plugins/qmldesigner/{designercore => }/instances/nodeinstanceserverproxy.h (100%) rename src/plugins/qmldesigner/{designercore => }/instances/nodeinstanceview.cpp (95%) rename src/plugins/qmldesigner/{designercore/include => instances}/nodeinstanceview.h (91%) rename src/plugins/qmldesigner/{designercore => }/instances/puppetstarter.cpp (100%) rename src/plugins/qmldesigner/{designercore => }/instances/puppetstarter.h (100%) rename src/plugins/qmldesigner/{designercore => }/instances/qprocessuniqueptr.h (100%) create mode 100644 src/plugins/qmldesigner/libs/CMakeLists.txt create mode 100644 src/plugins/qmldesigner/libs/designercore/CMakeLists.txt rename src/plugins/qmldesigner/{ => libs}/designercore/designercoreutils/generatedcomponentutils.cpp (66%) rename src/plugins/qmldesigner/{ => libs}/designercore/designercoreutils/generatedcomponentutils.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/designercoreutils/modelmerger.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/designercoreutils/modelmerger.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/designercoreutils/modelutils.cpp (99%) rename src/plugins/qmldesigner/{ => libs}/designercore/designercoreutils/modelutils.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/designercoreutils/predicate.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/designercoreutils/stylesheetmerger.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/designercoreutils/stylesheetmerger.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/designercoreutils/uniquename.cpp (99%) rename src/plugins/qmldesigner/{ => libs}/designercore/designercoreutils/uniquename.h (75%) rename src/plugins/qmldesigner/{ => libs}/designercore/exceptions/exception.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/exceptions/invalidargumentexception.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/exceptions/invalididexception.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/exceptions/invalidmetainfoexception.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/exceptions/invalidmodelnodeexception.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/exceptions/invalidmodelstateexception.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/exceptions/invalidpropertyexception.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/exceptions/invalidqmlsourceexception.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/exceptions/invalidreparentingexception.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/exceptions/invalidslideindexexception.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/exceptions/notimplementedexception.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/exceptions/removebasestateexception.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/exceptions/rewritingexception.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/addarraymembervisitor.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/addarraymembervisitor.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/addobjectvisitor.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/addobjectvisitor.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/addpropertyvisitor.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/addpropertyvisitor.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/astobjecttextextractor.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/astobjecttextextractor.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/changeimportsvisitor.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/changeimportsvisitor.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/changeobjecttypevisitor.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/changeobjecttypevisitor.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/changepropertyvisitor.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/changepropertyvisitor.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/firstdefinitionfinder.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/firstdefinitionfinder.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/moveobjectbeforeobjectvisitor.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/moveobjectbeforeobjectvisitor.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/moveobjectvisitor.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/moveobjectvisitor.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/objectlengthcalculator.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/objectlengthcalculator.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/qmlrefactoring.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/qmlrefactoring.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/qmlrewriter.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/qmlrewriter.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/removepropertyvisitor.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/removepropertyvisitor.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/removeuiobjectmembervisitor.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/filemanager/removeuiobjectmembervisitor.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/asynchronousexplicitimagecache.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/asynchronousimagecache.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/asynchronousimagefactory.cpp (98%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/asynchronousimagefactory.h (96%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/explicitimagecacheimageprovider.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/explicitimagecacheimageprovider.h (86%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/imagecachecollectorinterface.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/imagecachedispatchcollector.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/imagecachegenerator.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/imagecachegenerator.h (95%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/imagecachegeneratorinterface.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/imagecacheimageresponse.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/imagecacheimageresponse.h (82%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/imagecachestorage.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/imagecachestorageinterface.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/midsizeimagecacheprovider.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/midsizeimagecacheprovider.h (84%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/smallimagecacheprovider.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/smallimagecacheprovider.h (85%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/synchronousimagecache.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/taskqueue.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/timestampprovider.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/timestampprovider.h (76%) rename src/plugins/qmldesigner/{ => libs}/designercore/imagecache/timestampproviderinterface.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/abstractproperty.h (98%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/abstractview.h (84%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/annotation.h (90%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/asynchronousexplicitimagecache.h (97%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/asynchronousimagecache.h (96%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/asynchronousimagecacheinterface.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/auxiliarydata.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/auxiliarydataproperties.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/bindingproperty.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/bytearraymodifier.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/componenttextmodifier.h (95%) create mode 100644 src/plugins/qmldesigner/libs/designercore/include/customnotificationpackage.h rename src/plugins/qmldesigner/{ => libs}/designercore/include/customnotifications.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/documentmessage.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/enumerationmetainfo.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/exception.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/externaldependenciesinterface.h (96%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/filesystemfacadeinterface.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/forwardview.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/imagecacheauxiliarydata.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/import.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/invalidargumentexception.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/invalididexception.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/invalidmetainfoexception.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/invalidmodelnodeexception.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/invalidmodelstateexception.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/invalidpropertyexception.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/invalidqmlsourceexception.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/invalidreparentingexception.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/invalidslideindexexception.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/itemlibraryentry.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/itemlibraryinfo.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/iwidgetplugin.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/mathutils.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/metainfo.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/metainforeader.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/model.h (79%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/modelcache.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/modelfwd.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/modelnode.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/modificationgroupexception.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/modificationgrouptoken.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/module.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/nodeabstractproperty.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/nodehints.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/nodelistproperty.h (99%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/nodemetainfo.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/nodeproperty.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/notimplementedexception.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/objectpropertybinding.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/plaintexteditmodifier.h (90%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/projectstorageids.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/propertybinding.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/propertycontainer.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/propertymetainfo.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/propertynode.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/propertyparser.h (100%) rename src/plugins/qmldesigner/{designercore/instances => libs/designercore/include}/puppetstartdata.h (100%) create mode 100644 src/plugins/qmldesigner/libs/designercore/include/qmldesignercoreconstants.h rename src/plugins/qmldesigner/{ => libs}/designercore/include/qmldesignercorelib_exports.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/qmldesignercorelib_global.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/removebasestateexception.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/rewritertransaction.h (93%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/rewriterview.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/rewritingexception.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/signalhandlerproperty.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/sourcepathids.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/stringutils.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/subcomponentmanager.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/synchronousimagecache.h (95%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/textmodifier.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/include/variantproperty.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/metainfo/itemlibraryentry.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/metainfo/itemlibraryinfo.cpp (99%) rename src/plugins/qmldesigner/{ => libs}/designercore/metainfo/metainfo.cpp (89%) rename src/plugins/qmldesigner/{ => libs}/designercore/metainfo/metainforeader.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/metainfo/nodehints.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/metainfo/nodemetainfo.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/metainfo/propertycontainer.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/metainfo/subcomponentmanager.cpp (98%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/abstractproperty.cpp (97%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/abstractview.cpp (80%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/annotation.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/auxiliarypropertystorageview.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/auxiliarypropertystorageview.h (91%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/bindingproperty.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/documentmessage.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/import.cpp (99%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalbindingproperty.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalbindingproperty.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalnode.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalnode_p.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalnodeabstractproperty.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalnodeabstractproperty.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalnodelistproperty.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalnodelistproperty.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalnodeproperty.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalnodeproperty.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalproperty.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalproperty.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalsignalhandlerproperty.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalsignalhandlerproperty.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalvariantproperty.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/internalvariantproperty.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/model.cpp (94%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/model_p.h (97%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/modelnode.cpp (99%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/modelresourcemanagement.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/modelresourcemanagement.h (83%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/modelresourcemanagementfwd.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/modelresourcemanagementinterface.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/nodeabstractproperty.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/nodelistproperty.cpp (93%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/nodeproperty.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/signalhandlerproperty.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/model/variantproperty.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/pluginmanager/widgetpluginmanager.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/pluginmanager/widgetpluginmanager.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/pluginmanager/widgetpluginpath.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/pluginmanager/widgetpluginpath.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/commontypecache.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/directorypathcompressor.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/filestatus.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/filestatuscache.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/filestatuscache.h (92%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/filesystem.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/filesystem.h (94%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/filesysteminterface.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/modulescanner.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/modulescanner.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstorage.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstorage.h (99%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstorageerrornotifier.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstorageerrornotifier.h (84%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstorageerrornotifierinterface.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstorageexceptions.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstorageexceptions.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstoragefwd.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstorageinfotypes.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstorageinterface.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstorageobserver.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstoragepathwatcher.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstoragepathwatcherinterface.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstoragepathwatchernotifierinterface.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstoragepathwatchertypes.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstorageprinting.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstoragetypes.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstorageupdater.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/projectstorageupdater.h (98%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/qmldocumentparser.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/qmldocumentparser.h (90%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/qmldocumentparserinterface.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/qmltypesparser.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/qmltypesparser.h (88%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/qmltypesparserinterface.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/typeannotationreader.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/projectstorage/typeannotationreader.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/componenttextmodifier.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/modelnodepositionrecalculator.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/modelnodepositionrecalculator.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/modelnodepositionstorage.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/modelnodepositionstorage.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/modeltotextmerger.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/modeltotextmerger.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/plaintexteditmodifier.cpp (85%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/propertycontainer.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/propertynode.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/propertyparser.cpp (100%) rename src/plugins/qmldesigner/{designercore/qmltools => libs/designercore/rewriter}/qmltextgenerator.cpp (100%) rename src/plugins/qmldesigner/{designercore/qmltools => libs/designercore/rewriter}/qmltextgenerator.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/rewriteaction.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/rewriteaction.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/rewriteactioncompressor.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/rewriteactioncompressor.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/rewritertransaction.cpp (86%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/rewriterview.cpp (99%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/textmodifier.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/texttomodelmerger.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/rewriter/texttomodelmerger.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/sourcepathstorage/nonlockingmutex.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/sourcepathstorage/sourcepath.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/sourcepathstorage/sourcepathcache.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/sourcepathstorage/sourcepathcacheinterface.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/sourcepathstorage/sourcepathcachetypes.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/sourcepathstorage/sourcepathexceptions.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/sourcepathstorage/sourcepathexceptions.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/sourcepathstorage/sourcepathstorage.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/sourcepathstorage/sourcepathstorage.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/sourcepathstorage/sourcepathview.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/sourcepathstorage/storagecache.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/sourcepathstorage/storagecacheentry.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/sourcepathstorage/storagecachefwd.h (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/tracing/qmldesignertracing.cpp (100%) rename src/plugins/qmldesigner/{ => libs}/designercore/tracing/qmldesignertracing.h (100%) create mode 100644 src/plugins/qmldesigner/libs/qmldesignerutils/CMakeLists.txt rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/asset.cpp (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/asset.h (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/designeralgorithm.h (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/filedownloader.cpp (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/filedownloader.h (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/fileextractor.cpp (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/fileextractor.h (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/hdrimage.cpp (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/hdrimage.h (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/imageutils.cpp (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/imageutils.h (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/ktximage.cpp (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/ktximage.h (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/multifiledownloader.cpp (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/multifiledownloader.h (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/qmldesignerutils_global.h (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/version.cpp (100%) rename src/plugins/qmldesigner/{utils => libs/qmldesignerutils}/version.h (100%) rename src/plugins/qmldesigner/{designercore/model => qmltools}/anchorline.cpp (100%) rename src/plugins/qmldesigner/{designercore/include => qmltools}/anchorline.h (88%) rename src/plugins/qmldesigner/{designercore => }/qmltools/qml3dnode.cpp (100%) rename src/plugins/qmldesigner/{designercore/include => qmltools}/qml3dnode.h (77%) rename src/plugins/qmldesigner/{designercore => }/qmltools/qmlanchors.cpp (100%) rename src/plugins/qmldesigner/{designercore/include => qmltools}/qmlanchors.h (96%) rename src/plugins/qmldesigner/{designercore => }/qmltools/qmlchangeset.cpp (100%) rename src/plugins/qmldesigner/{designercore/include => qmltools}/qmlchangeset.h (85%) rename src/plugins/qmldesigner/{designercore => }/qmltools/qmlconnections.cpp (100%) rename src/plugins/qmldesigner/{designercore/include => qmltools}/qmlconnections.h (87%) rename src/plugins/qmldesigner/{designercore => }/qmltools/qmlitemnode.cpp (100%) rename src/plugins/qmldesigner/{designercore/include => qmltools}/qmlitemnode.h (92%) rename src/plugins/qmldesigner/{designercore => }/qmltools/qmlmodelnodefacade.cpp (85%) rename src/plugins/qmldesigner/{designercore/include => qmltools}/qmlmodelnodefacade.h (93%) rename src/plugins/qmldesigner/{designercore => }/qmltools/qmlobjectnode.cpp (98%) rename src/plugins/qmldesigner/{designercore/include => qmltools}/qmlobjectnode.h (93%) rename src/plugins/qmldesigner/{designercore => }/qmltools/qmlstate.cpp (100%) rename src/plugins/qmldesigner/{designercore/include => qmltools}/qmlstate.h (94%) rename src/plugins/qmldesigner/{designercore => }/qmltools/qmltimeline.cpp (99%) rename src/plugins/qmldesigner/{designercore/include => qmltools}/qmltimeline.h (94%) rename src/plugins/qmldesigner/{designercore => }/qmltools/qmltimelinekeyframegroup.cpp (100%) rename src/plugins/qmldesigner/{designercore/include => qmltools}/qmltimelinekeyframegroup.h (93%) rename src/plugins/qmldesigner/{designercore => }/qmltools/qmlvisualnode.cpp (100%) rename src/plugins/qmldesigner/{designercore/include => qmltools}/qmlvisualnode.h (91%) rename src/plugins/qmldesigner/{designercore/rewriter => textmodifier}/basetexteditmodifier.cpp (100%) rename src/plugins/qmldesigner/{designercore/include => textmodifier}/basetexteditmodifier.h (84%) create mode 100644 src/plugins/qmldesigner/textmodifier/indentingtexteditormodifier.cpp create mode 100644 src/plugins/qmldesigner/textmodifier/indentingtexteditormodifier.h rename src/plugins/qmldesignerbase/{utils => settings}/designersettings.cpp (100%) rename src/plugins/qmldesignerbase/{utils => settings}/designersettings.h (98%) create mode 100644 src/plugins/qmldesignerbase/settings/qmldesignersettings_global.h delete mode 100644 tests/unit/tests/stubs/clangcodemodel/clangcompletionassistinterface.h delete mode 100644 tests/unit/tests/stubs/qmldesigner/designercore/include/documentmessage.h delete mode 100644 tests/unit/tests/stubs/qmldesigner/designercore/include/itemlibraryitem.h delete mode 100644 tests/unit/tests/stubs/qmldesigner/designercore/include/nodeinstanceview.h delete mode 100644 tests/unit/tests/stubs/qmldesigner/designercore/include/qmlmodelnodefacade.h delete mode 100644 tests/unit/tests/stubs/qmldesigner/designercore/include/qmlobjectnode.h delete mode 100644 tests/unit/tests/stubs/qmldesigner/designercore/include/qmlstate.h delete mode 100644 tests/unit/tests/stubs/qmldesigner/designercore/include/qmltimeline.h delete mode 100644 tests/unit/tests/stubs/qmldesigner/designercore/include/rewriterview.h delete mode 100644 tests/unit/tests/unittests/utils/matchingtext-test.cpp diff --git a/src/plugins/effectcomposer/effectcomposerview.cpp b/src/plugins/effectcomposer/effectcomposerview.cpp index 6a7a57eb67e..a9726f55182 100644 --- a/src/plugins/effectcomposer/effectcomposerview.cpp +++ b/src/plugins/effectcomposer/effectcomposerview.cpp @@ -21,12 +21,14 @@ namespace EffectComposer { +constexpr char qmlEffectComposerContextId[] = "QmlDesigner::EffectComposer"; + EffectComposerContext::EffectComposerContext(QWidget *widget) : IContext(widget) { setWidget(widget); - setContext(Core::Context(QmlDesigner::Constants::C_QMLEFFECTCOMPOSER, - QmlDesigner::Constants::C_QT_QUICK_TOOLS_MENU)); + setContext( + Core::Context(qmlEffectComposerContextId, QmlDesigner::Constants::qtQuickToolsMenuContextId)); } void EffectComposerContext::contextHelp(const HelpCallback &callback) const diff --git a/src/plugins/effectcomposer/effectcomposerview.h b/src/plugins/effectcomposer/effectcomposerview.h index 0e84abbfffd..b8b130f3de3 100644 --- a/src/plugins/effectcomposer/effectcomposerview.h +++ b/src/plugins/effectcomposer/effectcomposerview.h @@ -3,8 +3,8 @@ #pragma once -#include "abstractview.h" -#include "modelnode.h" +#include +#include #include #include diff --git a/src/plugins/effectcomposer/effectcomposerwidget.cpp b/src/plugins/effectcomposer/effectcomposerwidget.cpp index ea96d7cd363..5f7d40d8a87 100644 --- a/src/plugins/effectcomposer/effectcomposerwidget.cpp +++ b/src/plugins/effectcomposer/effectcomposerwidget.cpp @@ -17,11 +17,11 @@ #include #include +#include #include #include #include -#include -#include +#include #include #include diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 7c2f81c10ab..876658a1d95 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -35,499 +35,27 @@ env_with_default("QTC_ENABLE_METAINFO_TRACING" ENV_QTC_ENABLE_METAINFO_TRACING O option(ENABLE_METAINFO_TRACING "Enable meta info tracing" ${ENV_QTC_ENABLE_METAINFO_TRACING}) add_feature_info("Meta info tracing" ${ENABLE_METAINFO_TRACING} "") -add_qtc_library(QmlDesignerUtils STATIC - DEPENDS - Qt::Gui Utils Qt::QmlPrivate - PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/utils - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/utils - PUBLIC_COMPILE_OPTIONS - $<$:-Wno-unneeded-internal-declaration> - SOURCES - asset.cpp asset.h - designeralgorithm.h - filedownloader.cpp filedownloader.h - multifiledownloader.cpp multifiledownloader.h - fileextractor.cpp fileextractor.h - hdrimage.cpp hdrimage.h - ktximage.cpp ktximage.h - imageutils.cpp imageutils.h - qmldesignerutils_global.h - version.cpp version.h -) - -extend_qtc_library(QmlDesignerUtils - CONDITION ENABLE_COMPILE_WARNING_AS_ERROR - PROPERTIES COMPILE_WARNING_AS_ERROR ON - PUBLIC_COMPILE_OPTIONS - $<$:-Wno-error=maybe-uninitialized> -) - -add_qtc_library(QmlDesignerCore STATIC - CONDITION TARGET QmlDesignerBase AND TARGET Qt6::QmlPrivate AND TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate - EXCLUDE_FROM_INSTALL - PROPERTIES SKIP_AUTOUIC ON - DEPENDS - Threads::Threads - Qt::CorePrivate - CPlusPlus - Utils - Qt::Widgets - Qt::Qml - Qt::QmlPrivate - Qt6::QmlDomPrivate - Qt6::QmlCompilerPrivate - Core - ProjectExplorer - QmakeProjectManager - QmlJS - QmlJSEditor - QmlJSTools - QmlProjectManager - QtSupport - PUBLIC_DEPENDS - QmlDesignerBase - QmlPuppetCommunication - QmlDesignerUtils - TextEditor - Sqlite - DEFINES - $<$:QDS_USE_PROJECTSTORAGE> - $<$:QTC_USE_QML_DESIGNER_LITE> - INCLUDES - ${CMAKE_CURRENT_LIST_DIR} - PUBLIC_INCLUDES - ${CMAKE_CURRENT_LIST_DIR}/designercore - ${CMAKE_CURRENT_LIST_DIR}/designercore/include -) - -extend_qtc_library(QmlDesignerCore - PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/designercore/designercoreutils - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/designercoreutils - SOURCES - generatedcomponentutils.cpp generatedcomponentutils.h - modelmerger.cpp modelmerger.h - modelutils.cpp modelutils.h - skipiterator.h - stylesheetmerger.cpp stylesheetmerger.h - uniquename.cpp uniquename.h - predicate.h -) - -extend_qtc_library(QmlDesignerCore - CONDITION ENABLE_PROJECT_STORAGE_TRACING OR ENABLE_SOURCE_PATH_STORAGE_TRACING OR ENABLE_IMAGE_CACHE_TRACING OR ENABLE_MODEL_TRACING OR ENABLE_METAINFO_TRACING - PUBLIC_DEPENDS Nanotrace - PUBLIC_DEFINES - ENABLE_QMLDESIGNER_TRACING - DEFINES - $<$:ENABLE_PROJECT_STORAGE_TRACING> - $<$:ENABLE_SOURCE_PATH_STORAGE_TRACING> - $<$:ENABLE_IMAGE_CACHE_TRACING> - $<$:ENABLE_MODEL_TRACING> - $<$:ENABLE_METAINFO_TRACING> -) - -extend_qtc_library(QmlDesignerCore - CONDITION ENABLE_COMPILE_WARNING_AS_ERROR - PROPERTIES COMPILE_WARNING_AS_ERROR ON - PUBLIC_COMPILE_OPTIONS $<$:-Wno-error=maybe-uninitialized> -) - -extend_qtc_library(QmlDesignerCore - CONDITION IS_SUPPORTED_PROJECTSTORAGE_QT - PUBLIC_DEFINES QDS_BUILD_QMLPARSER -) -extend_qtc_library(QmlDesignerCore - CONDITION UNIX AND NOT APPLE - PUBLIC_DEPENDS rt -) - -extend_qtc_library(QmlDesignerCore - INCLUDES ${CMAKE_CURRENT_LIST_DIR}/designercore/exceptions - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/exceptions - SOURCES - exception.cpp - invalidargumentexception.cpp - invalididexception.cpp - invalidmetainfoexception.cpp - invalidmodelnodeexception.cpp - invalidmodelstateexception.cpp - invalidpropertyexception.cpp - invalidqmlsourceexception.cpp - invalidreparentingexception.cpp - invalidslideindexexception.cpp - notimplementedexception.cpp - removebasestateexception.cpp - rewritingexception.cpp -) - -extend_qtc_library(QmlDesignerCore - INCLUDES ${CMAKE_CURRENT_LIST_DIR}/designercore/filemanager - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/filemanager - SOURCES - addarraymembervisitor.cpp - addarraymembervisitor.h - addobjectvisitor.cpp - addobjectvisitor.h - addpropertyvisitor.cpp - addpropertyvisitor.h - astobjecttextextractor.cpp - astobjecttextextractor.h - changeimportsvisitor.cpp - changeimportsvisitor.h - changeobjecttypevisitor.cpp - changeobjecttypevisitor.h - changepropertyvisitor.cpp - changepropertyvisitor.h - firstdefinitionfinder.cpp - firstdefinitionfinder.h - moveobjectbeforeobjectvisitor.cpp - moveobjectbeforeobjectvisitor.h - moveobjectvisitor.cpp - moveobjectvisitor.h - objectlengthcalculator.cpp - objectlengthcalculator.h - qmlrefactoring.cpp - qmlrefactoring.h - qmlrewriter.cpp - qmlrewriter.h - removepropertyvisitor.cpp - removepropertyvisitor.h - removeuiobjectmembervisitor.cpp - removeuiobjectmembervisitor.h -) - -extend_qtc_library(QmlDesignerCore - INCLUDES ${CMAKE_CURRENT_LIST_DIR}/designercore/imagecache - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/imagecache - SOURCES - asynchronousexplicitimagecache.cpp - asynchronousimagecache.cpp - asynchronousimagefactory.cpp - asynchronousimagefactory.h - imagecachecollector.cpp - imagecachecollector.h - imagecachedispatchcollector.h - imagecachecollectorinterface.h - imagecacheconnectionmanager.cpp - imagecacheconnectionmanager.h - imagecachefontcollector.cpp - imagecachefontcollector.h - imagecachegenerator.cpp - imagecachegenerator.h - imagecachegeneratorinterface.h - imagecachestorage.h - imagecachestorageinterface.h - meshimagecachecollector.cpp - meshimagecachecollector.h - synchronousimagecache.cpp - taskqueue.h - textureimagecachecollector.cpp - textureimagecachecollector.h - timestampprovider.cpp - timestampprovider.h - timestampproviderinterface.h -) - -extend_qtc_library(QmlDesignerCore - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/tracing - SOURCES - qmldesignertracing.cpp qmldesignertracing.h -) - -extend_qtc_library(QmlDesignerCore - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/include - SOURCES - abstractview.h - basetexteditmodifier.h - bytearraymodifier.h - componenttextmodifier.h - forwardview.h - itemlibraryentry.h - model.h - nodehints.h - plaintexteditmodifier.h - nodeinstanceview.h - propertyparser.h - rewriterview.h - textmodifier.h -) - -extend_qtc_library(QmlDesignerCore - CONDITION NOT USE_PROJECTSTORAGE - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/include - SOURCES - itemlibraryinfo.h - metainforeader.h - subcomponentmanager.h - metainfo.h -) - -extend_qtc_library(QmlDesignerCore - SOURCES_PROPERTIES SKIP_AUTOGEN ON - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/include - SOURCES - abstractproperty.h - anchorline.h - annotation.h - asynchronousexplicitimagecache.h - asynchronousimagecache.h - auxiliarydata.h - auxiliarydataproperties.h - bindingproperty.h - customnotifications.h - documentmessage.h - enumerationmetainfo.h - exception.h - externaldependenciesinterface.h - imagecacheauxiliarydata.h - import.h - invalidargumentexception.h - invalididexception.h - invalidmetainfoexception.h - invalidmodelnodeexception.h - invalidmodelstateexception.h - invalidpropertyexception.h - invalidqmlsourceexception.h - invalidreparentingexception.h - invalidslideindexexception.h - mathutils.h - modelfwd.h - modelnode.h - module.h - nodeabstractproperty.h - nodeinstance.h - nodelistproperty.h - nodemetainfo.h - nodeproperty.h - notimplementedexception.h - propertycontainer.h - propertymetainfo.h - propertynode.h - qmlanchors.h - qmlchangeset.h - qmlconnections.h - qmldesignercorelib_exports.h - qmldesignercorelib_global.h - qmlitemnode.h - qmlmodelnodefacade.h - qmlobjectnode.h - qmlstate.h - qmltimeline.h - qmltimelinekeyframegroup.h - removebasestateexception.h - rewritingexception.h - rewritertransaction.h - signalhandlerproperty.h - stringutils.h - synchronousimagecache.h - variantproperty.h -) - -extend_qtc_library(QmlDesignerCore - INCLUDES - ${CMAKE_CURRENT_LIST_DIR}/designercore/metainfo - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/metainfo - DEFINES SHARE_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../../../share/qtcreator/qmldesigner" - SOURCES - itemlibraryentry.cpp - nodehints.cpp - nodemetainfo.cpp -) - -extend_qtc_library(QmlDesignerCore - CONDITION NOT USE_PROJECTSTORAGE - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/metainfo - SOURCES - itemlibraryinfo.cpp - metainfo.cpp - metainforeader.cpp - subcomponentmanager.cpp -) - - -extend_qtc_library(QmlDesignerCore - PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/designercore/instances - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/instances - SOURCES - baseconnectionmanager.cpp - baseconnectionmanager.h - connectionmanager.cpp - connectionmanager.h - connectionmanagerinterface.cpp - connectionmanagerinterface.h - nodeinstance.cpp - nodeinstanceserverproxy.cpp - nodeinstanceserverproxy.h - nodeinstanceview.cpp - puppetstartdata.h - puppetstarter.cpp - puppetstarter.h - qprocessuniqueptr.h -) - -extend_qtc_library(QmlDesignerCore - INCLUDES ${CMAKE_CURRENT_LIST_DIR}/designercore/model - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/model - SOURCES - abstractproperty.cpp - abstractview.cpp - anchorline.cpp - annotation.cpp - auxiliarypropertystorageview.cpp auxiliarypropertystorageview.h - bindingproperty.cpp - documentmessage.cpp - import.cpp - internalbindingproperty.cpp - internalbindingproperty.h - internalnode.cpp - internalnode_p.h - internalnodeabstractproperty.cpp - internalnodeabstractproperty.h - internalnodelistproperty.cpp - internalnodelistproperty.h - internalnodeproperty.cpp - internalnodeproperty.h - internalproperty.cpp - internalproperty.h - internalsignalhandlerproperty.cpp - internalsignalhandlerproperty.h - internalvariantproperty.cpp - internalvariantproperty.h - model.cpp - model_p.h - modelnode.cpp - modelresourcemanagementinterface.h - modelresourcemanagementfwd.h - modelresourcemanagement.cpp modelresourcemanagement.h - nodeabstractproperty.cpp - nodelistproperty.cpp - nodeproperty.cpp - signalhandlerproperty.cpp - variantproperty.cpp -) - -extend_qtc_library(QmlDesignerCore - INCLUDES ${CMAKE_CURRENT_LIST_DIR}/designercore/rewriter - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/rewriter - SOURCES - componenttextmodifier.cpp - modelnodepositionrecalculator.cpp - modelnodepositionrecalculator.h - modelnodepositionstorage.cpp - modelnodepositionstorage.h - modeltotextmerger.cpp - modeltotextmerger.h - plaintexteditmodifier.cpp - propertycontainer.cpp - propertynode.cpp - propertyparser.cpp - rewriteaction.cpp - rewriteaction.h - rewriteactioncompressor.cpp - rewriteactioncompressor.h - rewritertransaction.cpp - rewriterview.cpp - textmodifier.cpp - texttomodelmerger.cpp - texttomodelmerger.h -) -extend_qtc_library(QmlDesignerCore - INCLUDES ${CMAKE_CURRENT_LIST_DIR}/designercore/qmltools - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/qmltools - SOURCES - qml3dnode.cpp - qmlanchors.cpp - qmlchangeset.cpp - qmlconnections.cpp - qmlitemnode.cpp - qmlmodelnodefacade.cpp - qmlobjectnode.cpp - qmlstate.cpp - qmltextgenerator.cpp - qmltextgenerator.h - qmltimeline.cpp - qmltimelinekeyframegroup.cpp - qmlvisualnode.cpp -) - -extend_qtc_library(QmlDesignerCore - INCLUDES ${CMAKE_CURRENT_LIST_DIR}/designercore/pluginmanager - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/designercore/pluginmanager - SOURCES - widgetpluginmanager.cpp - widgetpluginmanager.h - widgetpluginpath.cpp - widgetpluginpath.h -) - -extend_qtc_library(QmlDesignerCore - SOURCES_PREFIX designercore/sourcepathstorage - PUBLIC_INCLUDES designercore/sourcepathstorage - SOURCES_PROPERTIES SKIP_AUTOGEN ON - SOURCES - nonlockingmutex.h - sourcepath.h - sourcepathcache.h - sourcepathcacheinterface.h - sourcepathcachetypes.h - sourcepathexceptions.cpp - sourcepathexceptions.h - sourcepathstorage.cpp - sourcepathstorage.h - sourcepathview.h - storagecache.h - storagecacheentry.h - storagecachefwd.h -) - -extend_qtc_library(QmlDesignerCore - SOURCES_PREFIX designercore/projectstorage - PUBLIC_INCLUDES designercore/projectstorage - SOURCES_PROPERTIES SKIP_AUTOGEN ON - DEFINES QML_DOM_MSVC2019_COMPAT # can be removed for Qt 6.8 - SOURCES - commontypecache.h - directorypathcompressor.h - filesysteminterface.h - filesystem.cpp filesystem.h - filestatus.h - filestatuscache.cpp filestatuscache.h - modulescanner.cpp modulescanner.h - projectstorageexceptions.cpp projectstorageexceptions.h - projectstorageinterface.h - projectstoragefwd.h - projectstorageinfotypes.h - projectstorageobserver.h - projectstoragepathwatcher.h - projectstoragepathwatcherinterface.h - projectstoragepathwatchernotifierinterface.h - projectstoragepathwatcher.h - projectstoragepathwatchertypes.h - projectstorageprinting.h - projectstoragetypes.h - projectstorageupdater.cpp projectstorageupdater.h - projectstorage.cpp projectstorage.h - projectstorageerrornotifierinterface.h - projectstorageerrornotifier.cpp projectstorageerrornotifier.h - typeannotationreader.cpp typeannotationreader.h - qmldocumentparserinterface.h - qmltypesparserinterface.h - qmltypesparser.cpp qmltypesparser.h - qmldocumentparser.cpp qmldocumentparser.h -) +add_subdirectory(libs) add_qtc_plugin(QmlDesigner PLUGIN_RECOMMENDS QmlPreview CONDITION TARGET QmlDesignerCore AND TARGET Qt::QuickWidgets AND TARGET Qt::Svg PLUGIN_DEPENDS - Core ProjectExplorer QmlDesignerBase QmlJSEditor QmakeProjectManager QmlProjectManager + Core + ProjectExplorer + QmlDesignerBase + QmlJSEditor + QmakeProjectManager + QmlProjectManager QtSupport + TextEditor + QmlDesignerBase PLUGIN_MANUAL_DEPENDS LicenseChecker ${IDE_VERSION} optional DEPENDS QmlJS LanguageUtils QmlEditorWidgets AdvancedDockingSystem - Qt::QuickWidgets Qt::CorePrivate Qt::Xml Qt::Svg QmlDesignerCore Sqlite Zip + Qt::QuickWidgets Qt::CorePrivate Qt::Xml Qt::Svg Sqlite Zip PUBLIC_DEPENDS - QmlDesignerUtils QmlPuppetCommunication QmlDesignerBase + QmlDesignerUtils QmlPuppetCommunication QmlDesignerCore DEFINES IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\" SHARE_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../../../share/qtcreator/qmldesigner" @@ -535,6 +63,7 @@ add_qtc_plugin(QmlDesigner $<$:QTC_USE_QML_DESIGNER_LITE> $<$:DETACH_DISABLED_VIEWS> INCLUDES + ${CMAKE_CURRENT_LIST_DIR}/libs ${CMAKE_CURRENT_LIST_DIR}/components ${CMAKE_CURRENT_LIST_DIR}/components/import3d ${CMAKE_CURRENT_LIST_DIR}/components/assetslibrary @@ -553,9 +82,6 @@ add_qtc_plugin(QmlDesigner ${CMAKE_CURRENT_LIST_DIR}/components/designsystem PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR} - ${CMAKE_CURRENT_LIST_DIR}/designercore #can not be a public dependency -> EXCLUDE_FROM_INSTALL in QmlDesignerCore - ${CMAKE_CURRENT_LIST_DIR}/designercore/include #iwidgetplugin.h is used by other plugins - ${CMAKE_CURRENT_LIST_DIR}/designercore/designercoreutils ${CMAKE_CURRENT_LIST_DIR}/components SOURCES designmodecontext.cpp designmodecontext.h @@ -599,6 +125,61 @@ if (QTC_STATIC_BUILD AND TARGET QmlDesigner) extend_qtc_target(QmlDesigner PUBLIC_DEPENDS TextEditor) endif() +extend_qtc_plugin(QmlDesigner + PUBLIC_INCLUDES instances + SOURCES_PREFIX instances + SOURCES + baseconnectionmanager.cpp + baseconnectionmanager.h + capturingconnectionmanager.cpp + capturingconnectionmanager.h + connectionmanager.cpp + connectionmanager.h + connectionmanagerinterface.cpp + connectionmanagerinterface.h + interactiveconnectionmanager.cpp + interactiveconnectionmanager.h + nodeinstance.cpp + nodeinstance.h + nodeinstanceserverproxy.cpp + nodeinstanceserverproxy.h + nodeinstanceview.cpp + nodeinstanceview.h + puppetstarter.cpp + puppetstarter.h + qprocessuniqueptr.h +) + +extend_qtc_plugin(QmlDesigner + PUBLIC_INCLUDES qmltools + SOURCES_PREFIX qmltools + SOURCES + anchorline.cpp + anchorline.h + qml3dnode.cpp + qml3dnode.h + qmlanchors.cpp + qmlanchors.h + qmlchangeset.cpp + qmlchangeset.h + qmlconnections.cpp + qmlconnections.h + qmlitemnode.cpp + qmlitemnode.h + qmlmodelnodefacade.cpp + qmlmodelnodefacade.h + qmlobjectnode.cpp + qmlobjectnode.h + qmlstate.cpp + qmlstate.h + qmltimeline.cpp + qmltimeline.h + qmltimelinekeyframegroup.cpp + qmltimelinekeyframegroup.h + qmlvisualnode.cpp + qmlvisualnode.h +) + extend_qtc_plugin(QmlDesigner SOURCES_PREFIX components/componentcore PUBLIC_INCLUDES components/componentcore @@ -915,47 +496,29 @@ extend_qtc_plugin(QmlDesigner ) extend_qtc_plugin(QmlDesigner - SOURCES_PREFIX designercore + SOURCES_PREFIX imagecachecollectors SOURCES - include/asynchronousimagecacheinterface.h - include/bytearraymodifier.h - include/iwidgetplugin.h - include/modificationgroupexception.h - include/modificationgrouptoken.h - include/nodeanchors.h - include/objectpropertybinding.h - include/projectstorageids.h - include/propertybinding.h - include/sourcepathids.h - include/qml3dnode.h - include/qmlvisualnode.h + imagecachecollector.cpp + imagecachecollector.h + imagecacheconnectionmanager.cpp + imagecacheconnectionmanager.h + imagecachefontcollector.cpp + imagecachefontcollector.h + meshimagecachecollector.cpp + meshimagecachecollector.h + textureimagecachecollector.cpp + textureimagecachecollector.h ) extend_qtc_plugin(QmlDesigner - SOURCES_PREFIX designercore/instances + SOURCES_PREFIX textmodifier + PUBLIC_INCLUDES textmodifier SOURCES - capturingconnectionmanager.cpp capturingconnectionmanager.h - interactiveconnectionmanager.cpp interactiveconnectionmanager.h -) + basetexteditmodifier.cpp + basetexteditmodifier.h + indentingtexteditormodifier.cpp + indentingtexteditormodifier.h -extend_qtc_plugin(QmlDesigner - SOURCES_PREFIX designercore/imagecache - SOURCES - explicitimagecacheimageprovider.cpp - explicitimagecacheimageprovider.h - imagecacheimageresponse.cpp - imagecacheimageresponse.h - midsizeimagecacheprovider.cpp - midsizeimagecacheprovider.h - smallimagecacheprovider.cpp - smallimagecacheprovider.h -) - -extend_qtc_plugin(QmlDesigner - SOURCES_PREFIX designercore - PUBLIC_INCLUDES designercore - SOURCES - rewriter/basetexteditmodifier.cpp ) extend_qtc_plugin(QmlDesigner diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp index b821cc65957..6ea038777ae 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp @@ -4,9 +4,9 @@ #include "assetslibraryiconprovider.h" #include +#include +#include #include -#include -#include #include namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp index e776f8abe74..6c9720271f9 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp @@ -9,8 +9,8 @@ #include +#include #include -#include #include #include diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp index c757e41a408..3200a02234e 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryview.cpp @@ -10,22 +10,22 @@ #include #include #include -#include -#include -#include #include #include #include +#include +#include +#include #include #include #include #include #include +#include #include #include #include #include -#include namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp index ef7876923e5..e233c9a7425 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp index b067dc8d46f..07497c935e0 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp @@ -3,7 +3,7 @@ #include "bindingeditorwidget.h" -#include +#include #include #include diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index 8537afb1927..bca9a07fa8a 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -109,11 +109,11 @@ void DesignerActionManager::polishActions() const QList actions = Utils::filtered(designerActions(), [](ActionInterface *action) { return action->type() != ActionInterface::ContextMenu; }); - Core::Context qmlDesignerFormEditorContext(Constants::C_QMLFORMEDITOR); - Core::Context qmlDesignerEditor3DContext(Constants::C_QMLEDITOR3D); - Core::Context qmlDesignerNavigatorContext(Constants::C_QMLNAVIGATOR); - Core::Context qmlDesignerMaterialBrowserContext(Constants::C_QMLMATERIALBROWSER); - Core::Context qmlDesignerAssetsLibraryContext(Constants::C_QMLASSETSLIBRARY); + Core::Context qmlDesignerFormEditorContext(Constants::qmlFormEditorContextId); + Core::Context qmlDesignerEditor3DContext(Constants::qml3DEditorContextId); + Core::Context qmlDesignerNavigatorContext(Constants::qmlNavigatorContextId); + Core::Context qmlDesignerMaterialBrowserContext(Constants::qmlMaterialBrowserContextId); + Core::Context qmlDesignerAssetsLibraryContext(Constants::qmlAssetsLibraryContextId); Core::Context qmlDesignerUIContext; qmlDesignerUIContext.add(qmlDesignerFormEditorContext); @@ -2128,8 +2128,8 @@ void DesignerActionManager::createDefaultModelNodePreviewImageHandlers() ModelNodePreviewImageHandler("QtQuick3D.Texture", ModelNodeOperations::previewImageDataForImageNode)); registerModelNodePreviewHandler( - ModelNodePreviewImageHandler("QtQuick3D.Material", - ModelNodeOperations::previewImageDataForGenericNode)); + ModelNodePreviewImageHandler("QtQuick3D.Material", + ModelNodeOperations::previewImageDataForGenericNode)); registerModelNodePreviewHandler( ModelNodePreviewImageHandler("QtQuick3D.Model", ModelNodeOperations::previewImageDataForGenericNode)); diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index 4d49887b07d..cd2908d1e08 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -954,13 +954,14 @@ static void setIndexProperty(const AbstractProperty &property, const QVariant &v { if (!property.exists() || property.isVariantProperty()) { /* Using QmlObjectNode ensures we take states into account. */ - property.parentQmlObjectNode().setVariantProperty(property.name(), value); + QmlObjectNode{property.parentModelNode()}.setVariantProperty(property.name(), value); return; } else if (property.isBindingProperty()) { /* Track one binding to the original source, incase a TabBar is attached */ const AbstractProperty orignalProperty = property.toBindingProperty().resolveToProperty(); if (orignalProperty.isValid() && (orignalProperty.isVariantProperty() || !orignalProperty.exists())) { - orignalProperty.parentQmlObjectNode().setVariantProperty(orignalProperty.name(), value); + QmlObjectNode{orignalProperty.parentModelNode()}.setVariantProperty(orignalProperty.name(), + value); return; } } @@ -1658,15 +1659,20 @@ void addMouseAreaFill(const SelectionContext &selectionContext) QVariant previewImageDataForGenericNode(const ModelNode &modelNode) { - if (modelNode.isValid()) - return modelNode.model()->nodeInstanceView()->previewImageDataForGenericNode(modelNode, {}); + if (auto model = modelNode.model()) { + if (auto view = model->nodeInstanceView()) + return static_cast(view)->previewImageDataForGenericNode(modelNode, + {}); + } return {}; } QVariant previewImageDataForImageNode(const ModelNode &modelNode) { - if (modelNode.isValid()) - return modelNode.model()->nodeInstanceView()->previewImageDataForImageNode(modelNode); + if (auto model = modelNode.model()) { + if (auto view = model->nodeInstanceView()) + return static_cast(view)->previewImageDataForImageNode(modelNode); + } return {}; } @@ -1715,7 +1721,7 @@ void editIn3dView(const SelectionContext &selectionContext) if (targetNode.isValid()) { QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("Editor3D", true); if (scenePos.isNull()) { - selectionContext.view()->emitView3DAction(View3DActionType::AlignViewToCamera, true); + selectionContext.model()->emitView3DAction(View3DActionType::AlignViewToCamera, true); } else { selectionContext.view()->emitCustomNotification("pick_3d_node_from_2d_scene", {targetNode}, {scenePos}); diff --git a/src/plugins/qmldesigner/components/componentcore/selectioncontext.cpp b/src/plugins/qmldesigner/components/componentcore/selectioncontext.cpp index c59f75b06e1..1c61d69b1aa 100644 --- a/src/plugins/qmldesigner/components/componentcore/selectioncontext.cpp +++ b/src/plugins/qmldesigner/components/componentcore/selectioncontext.cpp @@ -36,7 +36,7 @@ bool SelectionContext::singleNodeIsSelected() const bool SelectionContext::isInBaseState() const { - return view()->currentState().isBaseState(); + return QmlModelState::isBaseState(view()->currentStateNode()); } ModelNode SelectionContext::currentSingleSelectedNode() const @@ -65,6 +65,14 @@ AbstractView *SelectionContext::view() const return m_view.data(); } +Model *SelectionContext::model() const +{ + if (m_view && m_view->isAttached()) + return m_view->model(); + + return nullptr; +} + void SelectionContext::setShowSelectionTools(bool show) { m_showSelectionTools = show; diff --git a/src/plugins/qmldesigner/components/componentcore/selectioncontext.h b/src/plugins/qmldesigner/components/componentcore/selectioncontext.h index 3990dd95e85..2433b25355c 100644 --- a/src/plugins/qmldesigner/components/componentcore/selectioncontext.h +++ b/src/plugins/qmldesigner/components/componentcore/selectioncontext.h @@ -38,6 +38,7 @@ public: bool hasSingleSelectedModelNode() const; AbstractView *view() const; + Model *model() const; void setShowSelectionTools(bool show); bool showSelectionTools() const; diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp index 50782eda7bc..e9a6d96c247 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp @@ -9,12 +9,12 @@ #include #include #include -#include +#include #include +#include #include #include #include -#include #include #include #include diff --git a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesitem.cpp b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesitem.cpp index 53e668be65e..a45b0e115d8 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesitem.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesitem.cpp @@ -46,7 +46,7 @@ PropertyName DynamicPropertiesItem::propertyName() const std::optional parentIfNotDefaultState(const AbstractProperty &property) { const QmlObjectNode objectNode = QmlObjectNode(property.parentModelNode()); - if (objectNode.isValid() && !objectNode.view()->currentState().isBaseState()) + if (objectNode.isValid() && !QmlModelState::isBaseState(objectNode.view()->currentStateNode())) return objectNode; return std::nullopt; } diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.h index 3d05d1f3325..2a7644ddf05 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.h @@ -3,8 +3,8 @@ #pragma once +#include #include -#include #include #include diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index f39535a43e8..2316d7b2f3a 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -923,10 +923,12 @@ void ContentLibraryView::addLibItem(const ModelNode &node, const QPixmap &iconPi else iconPixmapToSave = iconPixmap; - if (iconPixmapToSave.isNull()) - model()->nodeInstanceView()->previewImageDataForGenericNode(node, {}, {}, ADD_ITEM_REQ_ID); - else + if (iconPixmapToSave.isNull()) { + static_cast(model()->nodeInstanceView()) + ->previewImageDataForGenericNode(node, {}, {}, ADD_ITEM_REQ_ID); + } else { saveIconToBundle(iconPixmapToSave); + } } QString ContentLibraryView::getExportPath(const ModelNode &node) const @@ -1028,10 +1030,12 @@ void ContentLibraryView::exportLibItem(const ModelNode &node, const QPixmap &ico iconPixmapToSave = iconPixmap; m_iconSavePath = targetPath.pathAppended(iconPath); - if (iconPixmapToSave.isNull()) - model()->nodeInstanceView()->previewImageDataForGenericNode(node, {}, {}, EXPORT_ITEM_REQ_ID); - else + if (iconPixmapToSave.isNull()) { + static_cast(model()->nodeInstanceView()) + ->previewImageDataForGenericNode(node, {}, {}, EXPORT_ITEM_REQ_ID); + } else { addIconAndCloseZip(iconPixmapToSave); + } } void ContentLibraryView::addIconAndCloseZip(const auto &image) { // auto: QImage or QPixmap diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp index a5fe776fb86..d4d3bba5c1b 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp @@ -13,9 +13,9 @@ #include "contentlibrarytexturesmodel.h" #include "contentlibraryusermodel.h" -#include "utils/filedownloader.h" -#include "utils/fileextractor.h" -#include "utils/multifiledownloader.h" +#include +#include +#include #include #include diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp index 2ef7fde36f1..32881af1f5a 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp @@ -174,7 +174,7 @@ QmlTimeline CurveEditorView::activeTimeline() const if (!isAttached()) return {}; - QmlModelState state = currentState(); + QmlModelState state = currentStateNode(); if (state.isBaseState()) { for (const ModelNode &node : allModelNodesOfType(model()->qtQuickTimelineTimelineMetaInfo())) { if (QmlTimeline::isValidQmlTimeline(node)) { diff --git a/src/plugins/qmldesigner/components/edit3d/bakelights.cpp b/src/plugins/qmldesigner/components/edit3d/bakelights.cpp index 606f4f4255c..b516eeb0ec0 100644 --- a/src/plugins/qmldesigner/components/edit3d/bakelights.cpp +++ b/src/plugins/qmldesigner/components/edit3d/bakelights.cpp @@ -9,17 +9,18 @@ #include #include #include -#include +#include #include +#include #include #include #include -#include #include #include #include #include +#include #include @@ -140,7 +141,7 @@ void BakeLights::bakeLights() return; } - m_nodeInstanceView->setTarget(m_view->nodeInstanceView()->target()); + m_nodeInstanceView->setTarget(ProjectExplorer::ProjectManager::startupTarget()); auto progressCallback = [this](const QString &msg) { emit progress(msg); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp index 272b5994193..9bb1622cae8 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dactions.cpp @@ -28,8 +28,8 @@ Edit3DActionTemplate::Edit3DActionTemplate(const QString &description, void Edit3DActionTemplate::actionTriggered(bool b) { - if (m_type != View3DActionType::Empty) - m_view->emitView3DAction(m_type, b); + if (m_type != View3DActionType::Empty && m_view->isAttached()) + m_view->model()->emitView3DAction(m_type, b); if (m_action) m_action(m_selectionContext); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp index 553d8cb7b3d..14344a03be5 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.cpp @@ -193,11 +193,13 @@ void Edit3DCanvas::mouseMoveEvent(QMouseEvent *e) // edit camera mouse area. This also simplifies split view handling. QPointF diff = m_isQDSTrusted ? (m_hiddenCursorPos - e->globalPos()) : (m_lastCursorPos - e->globalPos()); - if (e->buttons() == (Qt::LeftButton | Qt::RightButton)) { - m_parent->view()->emitView3DAction(View3DActionType::EditCameraMove, - QVector3D{float(-diff.x()), float(-diff.y()), 0.f}); - } else { - m_parent->view()->emitView3DAction(View3DActionType::EditCameraRotation, diff / 6.); + if (auto model = m_parent->view()->model()) { + if (e->buttons() == (Qt::LeftButton | Qt::RightButton)) { + model->emitView3DAction(View3DActionType::EditCameraMove, + QVector3D{float(-diff.x()), float(-diff.y()), 0.f}); + } else { + model->emitView3DAction(View3DActionType::EditCameraRotation, diff / 6.); + } } } else { // Skip first move to avoid undesirable jump occasionally when initiating flight mode @@ -266,7 +268,8 @@ void Edit3DCanvas::focusOutEvent(QFocusEvent *focusEvent) m_usageTimer.elapsed()); setFlyMode(false); - m_parent->view()->emitView3DAction(View3DActionType::EditCameraStopAllMoves, {}); + if (auto model = m_parent->view()->model()) + model->emitView3DAction(View3DActionType::EditCameraStopAllMoves, {}); QWidget::focusOutEvent(focusEvent); } diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index 9d9e9848ff0..8a177e4441a 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -12,6 +12,7 @@ #include "snapconfiguration.h" #include +#include #include #include #include @@ -417,6 +418,12 @@ void Edit3DView::setActive3DSceneId(qint32 sceneId) rootModelNode().setAuxiliaryData(Utils3D::active3dSceneProperty, sceneId); } +void Edit3DView::emitView3DAction(View3DActionType type, const QVariant &value) +{ + if (isAttached()) + model()->emitView3DAction(type, value); +} + void Edit3DView::modelAboutToBeDetached(Model *model) { m_isBakingLightsSupported = false; @@ -554,14 +561,14 @@ void Edit3DView::variantPropertiesChanged(const QList &property void Edit3DView::sendInputEvent(QEvent *e) const { - if (nodeInstanceView()) - nodeInstanceView()->sendInputEvent(e); + if (isAttached()) + model()->sendCustomNotificationToNodeInstanceView(InputEvent{e}); } void Edit3DView::edit3DViewResized(const QSize &size) const { - if (nodeInstanceView()) - nodeInstanceView()->edit3DViewResized(size); + if (isAttached()) + model()->sendCustomNotificationToNodeInstanceView(Resize3DCanvas{size}); } QSize Edit3DView::canvasSize() const diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h index 8560fd6b45a..62d05a3f663 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h @@ -115,6 +115,7 @@ public: int activeSplit() const; bool isSplitView() const; void setFlyMode(bool enabled); + void emitView3DAction(View3DActionType type, const QVariant &value); private slots: void onEntriesChanged(); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index 9c716781ac1..4530c855fa4 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -39,7 +39,7 @@ #include -#include +#include #include #include @@ -86,7 +86,7 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) QByteArray sheet = Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css"); setStyleSheet(Theme::replaceCssColors(QString::fromUtf8(sheet))); - Core::Context context(Constants::C_QMLEDITOR3D); + Core::Context context(Constants::qml3DEditorContextId); m_context = new Core::IContext(this); m_context->setContext(context); m_context->setWidget(this); diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp index fb43695f94c..e99ed6c615b 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp @@ -53,7 +53,7 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) { setAcceptDrops(true); - Core::Context context(Constants::C_QMLFORMEDITOR); + Core::Context context(Constants::qmlFormEditorContextId); m_context = new Core::IContext(this); m_context->setContext(context); m_context->setWidget(this); @@ -75,8 +75,9 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) m_noSnappingAction->setCheckable(true); m_noSnappingAction->setChecked(true); + static constexpr char formEditorNoSnappingActionId[] = "QmlDesigner.FormEditor.NoSnapping"; registerActionAsCommand(m_noSnappingAction, - Constants::FORMEDITOR_NO_SNAPPING, + formEditorNoSnappingActionId, QKeySequence(Qt::Key_T), ComponentCoreConstants::snappingCategory, 1); @@ -85,8 +86,10 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) m_snappingAndAnchoringAction->setCheckable(true); m_snappingAndAnchoringAction->setChecked(true); + static constexpr char formEditorNoSnappingAndAnchoringActionId[] + = "QmlDesigner.FormEditor.NoSnappingAndAnchoring"; registerActionAsCommand(m_snappingAndAnchoringAction, - Constants::FORMEDITOR_NO_SNAPPING_AND_ANCHORING, + formEditorNoSnappingAndAnchoringActionId, QKeySequence(Qt::Key_W), ComponentCoreConstants::snappingCategory, 2); @@ -95,8 +98,9 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) m_snappingAction->setCheckable(true); m_snappingAction->setChecked(true); + static constexpr char formEditorSnappingActionId[] = "QmlDesigner.FormEditor.Snapping"; registerActionAsCommand(m_snappingAction, - Constants::FORMEDITOR_SNAPPING, + formEditorSnappingActionId, QKeySequence(Qt::Key_E), ComponentCoreConstants::snappingCategory, 3); @@ -108,8 +112,11 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) m_showBoundingRectAction->setChecked(false); m_showBoundingRectAction->setIcon( DesignerActionManager::instance().contextIcon(DesignerIcons::ShowBoundsIcon)); + + static constexpr char formEditorShowBoundingRctangeActionId[] + = "QmlDesigner.FormEditor.ShowBoundingRectangle"; registerActionAsCommand(m_showBoundingRectAction, - Constants::FORMEDITOR_NO_SHOW_BOUNDING_RECTANGLE, + formEditorShowBoundingRctangeActionId, QKeySequence(Qt::Key_A), ComponentCoreConstants::rootCategory, ComponentCoreConstants::Priorities::ShowBoundingRect); @@ -269,8 +276,9 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) connect(m_zoomSelectionAction.data(), &QAction::triggered, frameSelection); m_resetAction = new QAction(reloadIcon, tr("Reload View"), this); + static constexpr char formEditorRefreshActionId[] = "QmlDesigner.FormEditor.Refresh"; registerActionAsCommand(m_resetAction, - Constants::FORMEDITOR_REFRESH, + formEditorRefreshActionId, QKeySequence(Qt::Key_R), ComponentCoreConstants::rootCategory, ComponentCoreConstants::Priorities::ResetView); @@ -337,7 +345,7 @@ void FormEditorWidget::changeBackgound(const QColor &color) void FormEditorWidget::registerActionAsCommand( QAction *action, Utils::Id id, const QKeySequence &, const QByteArray &category, int priority) { - Core::Context context(Constants::C_QMLFORMEDITOR); + Core::Context context(Constants::qmlFormEditorContextId); Core::Command *command = Core::ActionManager::registerAction(action, id, context); diff --git a/src/plugins/qmldesigner/components/formeditor/movetool.cpp b/src/plugins/qmldesigner/components/formeditor/movetool.cpp index 7aa66c2390a..4460ba9ce6f 100644 --- a/src/plugins/qmldesigner/components/formeditor/movetool.cpp +++ b/src/plugins/qmldesigner/components/formeditor/movetool.cpp @@ -86,7 +86,7 @@ void MoveTool::mouseMoveEvent(const QList &itemList, m_bindingIndicator.hide(); FormEditorItem *containerItem = containerFormEditorItem(itemList, m_movingItems); - if (containerItem && view()->currentState().isBaseState()) { + if (containerItem && QmlModelState::isBaseState(view()->currentStateNode())) { if (containerItem != m_movingItems.constFirst()->parentItem() && event->modifiers().testFlag(Qt::ControlModifier) && event->modifiers().testFlag(Qt::ShiftModifier)) { diff --git a/src/plugins/qmldesigner/components/import3d/import3ddialog.cpp b/src/plugins/qmldesigner/components/import3d/import3ddialog.cpp index 27dead7d6d0..94902b8fb1b 100644 --- a/src/plugins/qmldesigner/components/import3d/import3ddialog.cpp +++ b/src/plugins/qmldesigner/components/import3d/import3ddialog.cpp @@ -298,8 +298,8 @@ void Import3dDialog::updateImport(AbstractView *view, QFileInfo compFileInfo{compFileName}; // Find to top asset folder - const QString oldAssetFolder = QLatin1String(Constants::OLD_QUICK_3D_ASSETS_FOLDER); - QString assetFolder = QLatin1String(Constants::QUICK_3D_COMPONENTS_FOLDER); + const QString oldAssetFolder = Constants::oldQuick3dAssetsFolder; + QString assetFolder = Constants::quick3DComponentsFolder; const QStringList parts = compFileName.split('/'); int i = parts.size() - 1; int previousSize = 0; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryiconimageprovider.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryiconimageprovider.cpp index 304aa5716ff..0f5e0d5f734 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryiconimageprovider.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryiconimageprovider.cpp @@ -3,7 +3,7 @@ #include "itemlibraryiconimageprovider.h" -#include +#include #include #include diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryiconimageprovider.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryiconimageprovider.h index 6638bae4333..87d97d65d43 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryiconimageprovider.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryiconimageprovider.h @@ -6,13 +6,13 @@ #include #include -#include #include -#include -#include +#include #include #include #include +#include +#include #include diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index 4720f26a938..1d9bbf5cd34 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -16,9 +16,9 @@ #include #include #include +#include #include #include -#include #include #include diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp index 101a6de8b8c..cf0643f838c 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp @@ -101,9 +101,10 @@ void ItemLibraryView::updateImports() m_widget->delayedUpdateModel(); } - -void ItemLibraryView::customNotification(const AbstractView *view, const QString &identifier, - const QList &nodeList, const QList &data) +void ItemLibraryView::customNotification(const AbstractView *view, + const QString &identifier, + const QList &nodeList, + const QList &data) { if (identifier == UpdateItemlibrary) updateImports(); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 2e4f1756f87..8d28cea7ca3 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -145,7 +145,7 @@ WidgetInfo MaterialBrowserView::widgetInfo() for (const QmlDesigner::MaterialBrowserModel::PropertyCopyData &propData : propDatas) { if (propData.isValid) { const bool isDynamic = !propData.dynamicTypeName.isEmpty(); - const bool isBaseState = currentState().isBaseState(); + const bool isBaseState = QmlModelState::isBaseState(currentStateNode()); const bool hasProperty = mat.hasProperty(propData.name); if (propData.isBinding) { if (isDynamic && (!hasProperty || isBaseState)) { @@ -513,7 +513,8 @@ void MaterialBrowserView::requestPreviews() { if (model() && model()->nodeInstanceView()) { for (const auto &node : std::as_const(m_previewRequests)) - model()->nodeInstanceView()->previewImageDataForGenericNode(node, {}); + static_cast(model()->nodeInstanceView()) + ->previewImageDataForGenericNode(node, {}); } m_previewRequests.clear(); } diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h index e316a66555d..c14bf1ade3a 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h @@ -16,6 +16,7 @@ QT_END_NAMESPACE namespace QmlDesigner { class MaterialBrowserWidget; +class QmlObjectNode; class MaterialBrowserView : public AbstractView { diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp index d463f9f02c2..973051b8ec6 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp @@ -165,7 +165,7 @@ MaterialBrowserWidget::MaterialBrowserWidget(AsynchronousImageCache &imageCache, setWindowTitle(tr("Material Browser", "Title of material browser widget")); setMinimumWidth(120); - Core::Context context(Constants::C_QMLMATERIALBROWSER); + Core::Context context(Constants::qmlMaterialBrowserContextId); m_context = new Core::IContext(this); m_context->setContext(context); m_context->setWidget(this); diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp index fa3469254f5..dca37a1f895 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp @@ -260,7 +260,7 @@ void MaterialEditorContextObject::insertKeyframe(const QString &propertyName) // If we add more code here we have to forward the material editor view RewriterView *rewriterView = m_model->rewriterView(); - QmlTimeline timeline = rewriterView->currentTimeline(); + QmlTimeline timeline = rewriterView->currentTimelineNode(); QTC_ASSERT(timeline.isValid(), return); diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index 7d27b93e67a..59101f56f35 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -568,7 +568,8 @@ void MaterialEditorView::setupQmlBackend() MaterialEditorQmlBackend *currentQmlBackend = m_qmlBackendHash.value(qmlPaneUrl.toString()); - QString currentStateName = currentState().isBaseState() ? currentState().name() : "invalid state"; + QmlModelState currentState = currentStateNode(); + QString currentStateName = currentState.isBaseState() ? currentState.name() : "invalid state"; if (!currentQmlBackend) { currentQmlBackend = new MaterialEditorQmlBackend(this); @@ -887,10 +888,8 @@ void MaterialEditorView::requestPreviewRender() static int requestId = 0; m_previewRequestId = QByteArray(MATERIAL_EDITOR_IMAGE_REQUEST_ID) + QByteArray::number(++requestId); - model()->nodeInstanceView()->previewImageDataForGenericNode(m_selectedMaterial, - {}, - m_previewSize, - m_previewRequestId); + static_cast(model()->nodeInstanceView()) + ->previewImageDataForGenericNode(m_selectedMaterial, {}, m_previewSize, m_previewRequestId); } } diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h index e5f7a446ed0..c35d884f808 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.h @@ -22,6 +22,7 @@ namespace QmlDesigner { class DynamicPropertiesModel; class ItemLibraryInfo; class MaterialEditorQmlBackend; +class QmlObjectNode; class MaterialEditorView : public AbstractView { diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 658ba0c50a2..1e71f1efbd4 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -93,7 +93,7 @@ static void removePosition(const ModelNode &node) static void setScenePosition(const QmlDesigner::ModelNode &modelNode,const QPointF &positionInSceneSpace) { if (modelNode.hasParentProperty() && QmlDesigner::QmlItemNode::isValidQmlItemNode(modelNode.parentProperty().parentModelNode())) { - QmlDesigner::QmlItemNode parentNode = modelNode.parentProperty().parentQmlObjectNode().toQmlItemNode(); + QmlDesigner::QmlItemNode parentNode = modelNode.parentProperty().parentModelNode(); QPointF positionInLocalSpace = parentNode.instanceSceneContentItemTransform().inverted().map(positionInSceneSpace); modelNode.variantProperty("x").setValue(positionInLocalSpace.toPoint().x()); modelNode.variantProperty("y").setValue(positionInLocalSpace.toPoint().y()); diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index 8e6819c0384..fadccd41f37 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -46,7 +46,7 @@ inline static void setScenePos(const QmlDesigner::ModelNode &modelNode, const QPointF &pos) { if (modelNode.hasParentProperty() && QmlDesigner::QmlItemNode::isValidQmlItemNode(modelNode.parentProperty().parentModelNode())) { - QmlDesigner::QmlItemNode parentNode = modelNode.parentProperty().parentQmlObjectNode().toQmlItemNode(); + QmlDesigner::QmlItemNode parentNode = modelNode.parentProperty().parentModelNode(); if (!parentNode.modelNode().metaInfo().isLayoutable()) { QPointF localPos = parentNode.instanceSceneTransform().inverted().map(pos); @@ -693,9 +693,7 @@ void NavigatorView::updateItemSelection() itemSelection.select(beginIndex, endIndex); } else { // if the node index is invalid expand ancestors manually if they are valid. - ModelNode parentNode = node; - while (parentNode.hasParentProperty()) { - parentNode = parentNode.parentProperty().parentQmlObjectNode(); + while (ModelNode parentNode = node.parentProperty().parentModelNode()) { QModelIndex parentIndex = indexForModelNode(parentNode); if (parentIndex.isValid()) treeWidget()->expand(parentIndex); diff --git a/src/plugins/qmldesigner/components/propertyeditor/assetimageprovider.cpp b/src/plugins/qmldesigner/components/propertyeditor/assetimageprovider.cpp index 5ecf048ab15..10e92b8316e 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/assetimageprovider.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/assetimageprovider.cpp @@ -4,10 +4,10 @@ #include "assetimageprovider.h" #include -#include +#include #include -#include +#include #include #include diff --git a/src/plugins/qmldesigner/components/propertyeditor/dynamicpropertiesproxymodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/dynamicpropertiesproxymodel.cpp index b1b693b4329..8ba6b22ac0f 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/dynamicpropertiesproxymodel.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/dynamicpropertiesproxymodel.cpp @@ -33,9 +33,10 @@ #include #include -#include #include #include +#include +#include #include #include @@ -108,13 +109,13 @@ QVariant DynamicPropertiesProxyModel::data(const QModelIndex &index, int role) c return property.dynamicTypeName(); if (role == propertyValueRole) { - QmlObjectNode objectNode = property.parentQmlObjectNode(); + QmlObjectNode objectNode = property.parentModelNode(); return objectNode.modelValue(property.name()); } if (role == propertyBindingRole) { if (property.isBindingProperty()) - return property.parentQmlObjectNode().expression(property.name()); + return QmlObjectNode{property.parentModelNode()}.expression(property.name()); return {}; } @@ -301,9 +302,9 @@ void DynamicPropertyRow::setupBackendValue() if (node != m_backendValue->modelNode()) m_backendValue->setModelNode(node); - QVariant modelValue = property.parentQmlObjectNode().modelValue(property.name()); + QVariant modelValue = QmlObjectNode{property.parentModelNode()}.modelValue(property.name()); - const bool isBound = property.parentQmlObjectNode().hasBindingProperty(property.name()); + const bool isBound = QmlObjectNode{property.parentModelNode()}.hasBindingProperty(property.name()); if (modelValue != m_backendValue->value()) { m_backendValue->setValue({}); @@ -311,7 +312,7 @@ void DynamicPropertyRow::setupBackendValue() } if (isBound) { - QString expression = property.parentQmlObjectNode().expression(property.name()); + QString expression = QmlObjectNode{property.parentModelNode()}.expression(property.name()); if (m_backendValue->expression() != expression) m_backendValue->setExpression(expression); } @@ -346,9 +347,9 @@ void DynamicPropertyRow::commitValue(const QVariant &value) convertBindingToVariantProperty(property.toBindingProperty(), value); } else if (property.isVariantProperty()) { VariantProperty variantProperty = property.toVariantProperty(); - QmlObjectNode objectNode = variantProperty.parentQmlObjectNode(); - if (view->currentState().isBaseState() - && !(objectNode.timelineIsActive() && objectNode.currentTimeline().isRecording())) { + QmlObjectNode objectNode = variantProperty.parentModelNode(); + if (QmlModelState::isBaseState(view->currentStateNode()) + && !(objectNode.timelineIsActive() && objectNode.currentTimeline().isRecording())) { if (variantProperty.value() != value) variantProperty.setDynamicTypeNameAndValue(variantProperty.dynamicTypeName(), value); } else { @@ -392,13 +393,13 @@ void DynamicPropertyRow::commitExpression(const QString &expression) if (theExpression.isEmpty()) theExpression = "null"; - if (view->currentState().isBaseState()) { + if (QmlModelState::isBaseState(view->currentStateNode())) { if (bindingProperty.expression() != theExpression) { bindingProperty.setDynamicTypeNameAndExpression(bindingProperty.dynamicTypeName(), theExpression); } } else { - QmlObjectNode objectNode = bindingProperty.parentQmlObjectNode(); + QmlObjectNode objectNode = bindingProperty.parentModelNode(); QTC_CHECK(objectNode.isValid()); PropertyNameView name = bindingProperty.name(); if (objectNode.isValid() && objectNode.expression(name) != theExpression) @@ -428,7 +429,7 @@ void DynamicPropertyRow::resetValue() AbstractProperty property = propertiesModel->propertyForRow(m_row); TypeName typeName = property.dynamicTypeName(); - if (view->currentState().isBaseState()) { + if (QmlModelState::isBaseState(view->currentStateNode())) { if (isDynamicVariantPropertyType(typeName)) { QVariant value = defaultValueForType(typeName); commitValue(value); @@ -442,7 +443,7 @@ void DynamicPropertyRow::resetValue() RewriterTransaction transaction = view->beginRewriterTransaction(__FUNCTION__); try { - QmlObjectNode objectNode = property.parentQmlObjectNode(); + QmlObjectNode objectNode = property.parentModelNode(); QTC_CHECK(objectNode.isValid()); PropertyNameView name = property.name(); if (objectNode.isValid() && objectNode.propertyAffectedByCurrentState(name)) diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp index b1bde8fb0f3..2fdd5416b71 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp @@ -305,7 +305,7 @@ void PropertyEditorContextObject::insertKeyframe(const QString &propertyName) ModelNode selectedNode = rewriterView->selectedModelNodes().constFirst(); - QmlTimeline timeline = rewriterView->currentTimeline(); + QmlTimeline timeline = rewriterView->currentTimelineNode(); QTC_ASSERT(timeline.isValid(), return ); QTC_ASSERT(selectedNode.isValid(), return ); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp index f5cdc75ee94..24ab8337410 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp @@ -1030,9 +1030,11 @@ QString PropertyEditorQmlBackend::locateQmlFile(const NodeMetaInfo &info, const { static const QDir fileSystemDir(PropertyEditorQmlBackend::propertyEditorResourcesPath()); + constexpr QLatin1String qmlDesignerSubfolder{"/designer/"}; const QDir resourcesDir(QStringLiteral(":/propertyEditorQmlSources")); - const QDir importDir(info.importDirectoryPath() + Constants::QML_DESIGNER_SUBFOLDER); - const QDir importDirVersion(info.importDirectoryPath() + QStringLiteral(".") + QString::number(info.majorVersion()) + Constants::QML_DESIGNER_SUBFOLDER); + const QDir importDir(info.importDirectoryPath() + qmlDesignerSubfolder); + const QDir importDirVersion(info.importDirectoryPath() + QStringLiteral(".") + + QString::number(info.majorVersion()) + qmlDesignerSubfolder); const QString relativePathWithoutEnding = relativePath.left(relativePath.size() - 4); const QString relativePathWithVersion = QString("%1_%2_%3.qml").arg(relativePathWithoutEnding diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp index 41648b23979..bfc1a2a55b5 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp @@ -559,7 +559,7 @@ void PropertyEditorValue::insertKeyframe() /*If we add more code here we have to forward the property editor view */ AbstractView *view = m_modelNode.view(); - QmlTimeline timeline = view->currentTimeline(); + QmlTimeline timeline = view->currentTimelineNode(); QTC_ASSERT(timeline.isValid(), return ); QTC_ASSERT(m_modelNode.isValid(), return ); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h index 5f734d59733..997640d377e 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.h @@ -4,7 +4,7 @@ #pragma once #include "modelnode.h" -#include "qmldesignercorelib_global.h" +#include "qmldesigner_global.h" #include #include @@ -12,6 +12,7 @@ namespace QmlDesigner { +class QmlObjectNode; class PropertyEditorValue; class PropertyEditorSubSelectionWrapper : public QObject @@ -90,7 +91,7 @@ private: PropertyEditorValue *m_editorValue = nullptr; }; -class QMLDESIGNERCORE_EXPORT PropertyEditorValue : public QObject +class QMLDESIGNER_EXPORT PropertyEditorValue : public QObject { Q_OBJECT diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp index 2c886017a09..ce680284a3c 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp @@ -640,7 +640,7 @@ void PropertyEditorView::setupQmlBackend() setupCurrentQmlBackend(currentQmlBackend, m_selectedNode, QUrl::fromLocalFile(QString{specificsPath}), - currentState(), + currentStateNode(), this, specificQmlData); @@ -665,8 +665,12 @@ void PropertyEditorView::setupQmlBackend() m_stackedWidget, this); - setupCurrentQmlBackend( - currentQmlBackend, m_selectedNode, qmlSpecificsFile, currentState(), this, specificQmlData); + setupCurrentQmlBackend(currentQmlBackend, + m_selectedNode, + qmlSpecificsFile, + currentStateNode(), + this, + specificQmlData); setupWidget(currentQmlBackend, this, m_stackedWidget); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h index f4bbbf22a81..3492888e9a9 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.h @@ -25,6 +25,7 @@ class ModelNode; class PropertyEditorQmlBackend; class PropertyEditorView; class PropertyEditorWidget; +class QmlObjectNode; class PropertyEditorView : public AbstractView { diff --git a/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.h b/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.h index 2bb38980790..82dac6d508b 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.h +++ b/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.h @@ -13,7 +13,7 @@ namespace QmlDesigner { class NodeInstanceView; -class QMLDESIGNERCORE_EXPORT QmlAnchorBindingProxy : public QObject +class QMLDESIGNER_EXPORT QmlAnchorBindingProxy : public QObject { Q_OBJECT diff --git a/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.h b/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.h index 0d613694715..09e597e84d5 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.h +++ b/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.h @@ -11,7 +11,7 @@ namespace QmlDesigner { -class QMLDESIGNERCORE_EXPORT QmlModelNodeProxy : public QObject +class QMLDESIGNER_EXPORT QmlModelNodeProxy : public QObject { Q_OBJECT diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorimageprovider.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorimageprovider.cpp index f0a7d0bf86f..761e32a262f 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorimageprovider.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorimageprovider.cpp @@ -18,16 +18,15 @@ QImage StatesEditorImageProvider::requestImage(const QString &id, QSize *size, c { QImage image; - bool nodeInstanceViewIsDetached = m_nodeInstanceView.isNull() || !m_nodeInstanceView->model(); - if (!nodeInstanceViewIsDetached) { + if (auto view = static_cast(m_nodeInstanceView.data())) { QString imageId = id.split(QLatin1Char('-')).constFirst(); if (imageId == QLatin1String("baseState")) { - image = m_nodeInstanceView->statePreviewImage(m_nodeInstanceView->rootModelNode()); + image = view->statePreviewImage(m_nodeInstanceView->rootModelNode()); } else { bool canBeConverted; int instanceId = imageId.toInt(&canBeConverted); if (canBeConverted && m_nodeInstanceView->hasModelNodeForInternalId(instanceId)) { - image = m_nodeInstanceView->statePreviewImage(m_nodeInstanceView->modelNodeForInternalId(instanceId)); + image = view->statePreviewImage(m_nodeInstanceView->modelNodeForInternalId(instanceId)); } } } @@ -48,9 +47,9 @@ QImage StatesEditorImageProvider::requestImage(const QString &id, QSize *size, c return image; } -void StatesEditorImageProvider::setNodeInstanceView(const NodeInstanceView *nodeInstanceView) +void StatesEditorImageProvider::setNodeInstanceView(const AbstractView *nodeInstanceView) { - m_nodeInstanceView = nodeInstanceView; + m_nodeInstanceView = static_cast(nodeInstanceView); } } // namespace Internal diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorimageprovider.h b/src/plugins/qmldesigner/components/stateseditor/stateseditorimageprovider.h index 1bd4432a956..cc94d335abd 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorimageprovider.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorimageprovider.h @@ -20,10 +20,10 @@ public: QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override; - void setNodeInstanceView(const NodeInstanceView *nodeInstanceView); + void setNodeInstanceView(const AbstractView *nodeInstanceView); private: - QPointer m_nodeInstanceView; + QPointer m_nodeInstanceView; }; } // namespace Internal diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp index 8b906854558..eddd8615c46 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp @@ -971,4 +971,9 @@ void StatesEditorView::moveStates(int from, int to) }); } +QmlModelState StatesEditorView::currentState() const +{ + return QmlModelState(currentStateNode()); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h index 3f9b9a4562d..9b50b346819 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.h @@ -42,6 +42,7 @@ public: QmlModelStateGroup activeStateGroup() const; void moveStates(int from, int to); + QmlModelState currentState() const; // AbstractView void modelAttached(Model *model) override; diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp index 08c36778691..e82f9aaa809 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp @@ -59,7 +59,7 @@ void StatesEditorWidget::setCurrentStateInternalId(int internalId) rootObject()->setProperty("currentStateInternalId", internalId); } -void StatesEditorWidget::setNodeInstanceView(const NodeInstanceView *nodeInstanceView) +void StatesEditorWidget::setNodeInstanceView(const AbstractView *nodeInstanceView) { m_imageProvider->setNodeInstanceView(nodeInstanceView); } diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h index 395cdbfac21..d709b2aeac5 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.h @@ -17,6 +17,7 @@ namespace QmlDesigner { class NodeInstanceView; +class AbstractView; class StatesEditorModel; class StatesEditorView; @@ -32,7 +33,7 @@ public: int currentStateInternalId() const; void setCurrentStateInternalId(int internalId); - void setNodeInstanceView(const NodeInstanceView *nodeInstanceView); + void setNodeInstanceView(const AbstractView *nodeInstanceView); static QString qmlSourcesPath(); diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp b/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp index e70ddb68d84..96b518fab35 100644 --- a/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp +++ b/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp @@ -153,7 +153,7 @@ void TextEditorWidget::jumpTextCursorToSelectedModelNode() selectedNode = m_textEditorView->selectedModelNodes().constFirst(); if (selectedNode.isValid()) { - auto currentState = m_textEditorView->currentState(); + QmlModelState currentState = m_textEditorView->currentStateNode(); if (currentState.isBaseState()) { jumpToModelNode(selectedNode); } else { diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorcontextobject.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorcontextobject.cpp index 30f276a48db..a684872f1d4 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorcontextobject.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorcontextobject.cpp @@ -80,7 +80,7 @@ void TextureEditorContextObject::insertKeyframe(const QString &propertyName) // If we add more code here we have to forward the material editor view RewriterView *rewriterView = m_model->rewriterView(); - QmlTimeline timeline = rewriterView->currentTimeline(); + QmlTimeline timeline = rewriterView->currentTimelineNode(); QTC_ASSERT(timeline.isValid(), return); diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp index 6afe6deb75f..adaa0410505 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorqmlbackend.cpp @@ -11,15 +11,15 @@ #include "qmldesignerconstants.h" #include "qmlobjectnode.h" #include "qmltimeline.h" -#include "textureeditortransaction.h" #include "textureeditorcontextobject.h" +#include "textureeditortransaction.h" #include +#include #include #include #include -#include #include #include diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp index b6090c9c2f0..531ae8850b1 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp @@ -456,7 +456,8 @@ void TextureEditorView::setupQmlBackend() TextureEditorQmlBackend *currentQmlBackend = m_qmlBackendHash.value(qmlPaneUrl.toString()); - QString currentStateName = currentState().isBaseState() ? currentState().name() : "invalid state"; + QmlModelState currentState = currentStateNode(); + QString currentStateName = currentState.isBaseState() ? currentState.name() : "invalid state"; if (!currentQmlBackend) { currentQmlBackend = new TextureEditorQmlBackend(this, m_imageCache); diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h index bc5806879b4..5611cf3ab6b 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.h @@ -21,6 +21,7 @@ namespace QmlDesigner { class CreateTexture; class DynamicPropertiesModel; class ModelNode; +class QmlObjectNode; class TextureEditorQmlBackend; class TextureEditorView : public AbstractView diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp index 63169e8ff5f..04f77af1fec 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinegraphicsscene.cpp @@ -487,9 +487,10 @@ QmlTimeline TimelineGraphicsScene::currentTimeline() const { QmlTimeline timeline(timelineModelNode()); if (timeline.isValid()) { - QTC_ASSERT(timeline == timelineView()->currentTimeline(), ;); + QTC_CHECK(timeline == timelineView()->currentTimelineNode()); } - return timelineView()->currentTimeline(); + + return timelineView()->currentTimelineNode(); } QRectF AbstractScrollGraphicsScene::selectionBounds() const diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp index 28af2fd25e1..4cfc6f03207 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp @@ -152,7 +152,7 @@ void TimelineView::nodeReparented(const ModelNode &node, void TimelineView::instancePropertyChanged(const QList> &propertyList) { - QmlTimeline timeline = currentTimeline(); + QmlTimeline timeline = currentTimelineNode(); bool updated = false; bool keyframeChangeFlag = false; for (const auto &pair : propertyList) { @@ -287,7 +287,7 @@ QList getAllStates(TimelineView* view) QString getStateName(TimelineView* view, bool& enableInBaseState) { QString currentStateName; - if (QmlModelState state = view->currentState(); state.isValid()) { + if (QmlModelState state = view->currentStateNode(); state.isValid()) { if (!state.isBaseState()) { enableInBaseState = false; return state.name(); @@ -435,9 +435,28 @@ void TimelineView::openSettingsDialog() dialog->show(); } +void TimelineView::activateTimelineRecording(const ModelNode &timeline) +{ + if (QmlTimeline currentTimeline = currentTimelineNode()) + currentTimeline.toogleRecording(true); + + if (isAttached()) + model()->setCurrentTimelineNode(timeline); +} + +void TimelineView::deactivateTimelineRecording() +{ + if (QmlTimeline currentTimeline = currentTimelineNode()) { + currentTimeline.toogleRecording(false); + currentTimeline.resetGroupRecording(); + } + if (isAttached()) + model()->setCurrentTimelineNode({}); +} + void TimelineView::setTimelineRecording(bool value) { - const ModelNode node = timelineForState(currentState()).modelNode(); + const ModelNode node = timelineForState(currentStateNode()).modelNode(); if (value && node.isValid()) { activateTimelineRecording(node); @@ -447,6 +466,15 @@ void TimelineView::setTimelineRecording(bool value) } } +void TimelineView::setCurrentTimeline(const ModelNode &timeline) +{ + if (QmlTimeline currentTimeline = currentTimelineNode()) { + currentTimeline.toogleRecording(false); + + model()->setCurrentTimelineNode(timeline); + } +} + void TimelineView::customNotification(const AbstractView * /*view*/, const QString &identifier, [[maybe_unused]] const QList &nodeList, @@ -461,9 +489,9 @@ void TimelineView::customNotification(const AbstractView * /*view*/, void TimelineView::insertKeyframe(const ModelNode &target, const PropertyName &propertyName) { - QmlTimeline timeline = currentTimeline(); + QmlTimeline timeline = currentTimelineNode(); - if (timeline.isValid() && target.isValid() && QmlObjectNode::isValidQmlObjectNode(target)) { + if (timeline && target && QmlObjectNode::isValidQmlObjectNode(target)) { executeInTransaction("TimelineView::insertKeyframe", [=, &timeline, &target]() { timeline.insertKeyframe(target, propertyName); }); @@ -682,7 +710,7 @@ void TimelineView::updateAnimationCurveEditor() if (!m_timelineWidget) return; - QmlTimeline currentTimeline = timelineForState(currentState()); + QmlTimeline currentTimeline = timelineForState(currentStateNode()); if (currentTimeline.isValid()) m_timelineWidget->toolBar()->setCurrentTimeline(currentTimeline); else diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineview.h b/src/plugins/qmldesigner/components/timelineeditor/timelineview.h index f75ac4690cd..4db54b68129 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelineview.h +++ b/src/plugins/qmldesigner/components/timelineeditor/timelineview.h @@ -60,7 +60,11 @@ public: void addNewTimelineDialog(); void openSettingsDialog(); + void activateTimelineRecording(const ModelNode &timeline); + void deactivateTimelineRecording(); + void setTimelineRecording(bool b); + void setCurrentTimeline(const ModelNode &timeline); void customNotification(const AbstractView *view, const QString &identifier, diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp index 1220712cf41..0e425574a0c 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp @@ -458,7 +458,7 @@ void TimelineWidget::contextHelp(const Core::IContext::HelpCallback &callback) c void TimelineWidget::init(int zoom) { - QmlTimeline currentTimeline = m_timelineView->timelineForState(m_timelineView->currentState()); + QmlTimeline currentTimeline = m_timelineView->timelineForState(m_timelineView->currentStateNode()); if (currentTimeline.isValid()) { setTimelineId(currentTimeline.modelNode().id()); m_statusBar->setText( @@ -498,7 +498,7 @@ TimelineToolBar *TimelineWidget::toolBar() const void TimelineWidget::invalidateTimelineDuration(const QmlTimeline &timeline) { if (timelineView() && timelineView()->model()) { - QmlTimeline currentTimeline = timelineView()->currentTimeline(); + QmlTimeline currentTimeline = timelineView()->currentTimelineNode(); if (currentTimeline.isValid() && currentTimeline == timeline) { m_toolbar->setStartFrame(timeline.startKeyframe()); m_toolbar->setEndFrame(timeline.endKeyframe()); @@ -522,7 +522,7 @@ void TimelineWidget::invalidateTimelineDuration(const QmlTimeline &timeline) void TimelineWidget::invalidateTimelinePosition(const QmlTimeline &timeline) { if (timelineView() && timelineView()->model()) { - QmlTimeline currentTimeline = timelineView()->currentTimeline(); + QmlTimeline currentTimeline = timelineView()->currentTimelineNode(); if (currentTimeline.isValid() && currentTimeline == timeline) { qreal frame = getcurrentFrame(timeline); m_toolbar->setCurrentFrame(frame); @@ -548,7 +548,7 @@ void TimelineWidget::setupScrollbar(int min, int max, int current) void TimelineWidget::setTimelineId(const QString &id) { - auto currentState = m_timelineView->currentState(); + QmlModelState currentState = m_timelineView->currentStateNode(); auto timelineOfState = m_timelineView->timelineForState(currentState.modelNode()); bool active = false; diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/skipiterator.h b/src/plugins/qmldesigner/designercore/designercoreutils/skipiterator.h deleted file mode 100644 index 11efb7d97f0..00000000000 --- a/src/plugins/qmldesigner/designercore/designercoreutils/skipiterator.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (C) 2023 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace QmlDesigner { - -template -class SkipIterator -{ -public: - using iterator_category = std::forward_iterator_tag; - using difference_type = qsizetype; - using value_type = typename BaseIterator::value_type; - using pointer = typename BaseIterator::pointer; - using reference = typename BaseIterator::reference; - - SkipIterator() = default; - SkipIterator(BaseIterator current, Increment increment) - : m_current{current} - , m_increment{std::move(increment)} - {} - - SkipIterator operator++() - { - m_current = m_increment(m_current); - return *this; - } - - SkipIterator operator++(int) - { - auto tmp = *this; - m_current = m_increment(m_current); - return tmp; - } - - reference operator*() const { return *m_current; } - pointer operator->() const { return m_current.operator->(); } - - friend bool operator==(const SkipIterator &first, const SkipIterator &second) - { - return first.m_current == second.m_current; - } - - friend bool operator!=(const SkipIterator &first, const SkipIterator &second) - { - return first.m_current != second.m_current; - } - -private: - BaseIterator m_current = {}; - Increment m_increment; -}; - -template -class SkipRange -{ -public: - using container = Container; - using base = SkipRange; - using iterator = SkipIterator; - - SkipRange(const Container &container, Increment increment) - : m_begin{container.begin(), increment} - , m_end{container.end(), increment} - {} - - iterator begin() const { return m_begin; } - iterator end() const { return m_end; } - -private: - iterator m_begin; - iterator m_end; -}; -} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/nodeanchors.h b/src/plugins/qmldesigner/designercore/include/nodeanchors.h deleted file mode 100644 index 7baec79c1c4..00000000000 --- a/src/plugins/qmldesigner/designercore/include/nodeanchors.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - - -#include -#include -#include "corelib_global.h" -#include -#include - -namespace QmlDesigner { - class Model; - class NodeState; - - namespace Internal { - class InternalNode; - using InternalNodePointer = std::shared_ptr; - using InternalNodeWeakPointer = QWeakPointer; - - class InternalNodeState; - using InternalNodeStatePointer = QSharedPointer; - - class TextToModelMerger; - } -} - -namespace QmlDesigner { - -class CORESHARED_EXPORT NodeAnchors -{ - friend class NodeState; - friend class ModelNode; - friend class Internal::TextToModelMerger; - -public: - explicit NodeAnchors(const NodeState &nodeState); - - NodeAnchors(const NodeAnchors &other); - NodeAnchors& operator=(const NodeAnchors &other); - ~NodeAnchors(); - - ModelNode modelNode() const; - NodeState nodeState() const; - - bool isValid() const; - - void setAnchor(AnchorLine::Type sourceAnchorLineType, - const ModelNode &targetModelNode, - AnchorLine::Type targetAnchorLineType); - bool canAnchor(AnchorLine::Type sourceAnchorLineType, - const ModelNode &targetModelNode, - AnchorLine::Type targetAnchorLineType) const; - bool canAnchor(const ModelNode &targetModelNode) const; - AnchorLine::Type possibleAnchorLines(AnchorLine::Type sourceAnchorLineType, - const ModelNode &targetModelNode) const; - AnchorLine localAnchor(AnchorLine::Type anchorLineType) const; - AnchorLine anchor(AnchorLine::Type anchorLineType) const; - void removeAnchor(AnchorLine::Type sourceAnchorLineType); - void removeAnchors(); - bool hasLocalAnchor(AnchorLine::Type sourceAnchorLineType) const; - bool hasAnchor(AnchorLine::Type sourceAnchorLineType) const; - bool hasLocalAnchors() const; - bool hasAnchors() const; - void setMargin(AnchorLine::Type sourceAnchorLineType, double margin) const; - bool hasMargin(AnchorLine::Type sourceAnchorLineType) const; - double localMargin(AnchorLine::Type sourceAnchorLineType) const; - double margin(AnchorLine::Type sourceAnchorLineType) const; - void removeMargin(AnchorLine::Type sourceAnchorLineType); - void removeMargins(); - -private: // functions - NodeAnchors(const Internal::InternalNodeStatePointer &internalNodeState, Model *model); - -private: //variables - Internal::InternalNodePointer m_internalNode; - Internal::InternalNodeStatePointer m_internalNodeState; - QPointer m_model; -}; - -CORESHARED_EXPORT QDebug operator<<(QDebug debug, const NodeAnchors &anchors); -CORESHARED_EXPORT QTextStream& operator<<(QTextStream &stream, const NodeAnchors &anchors); - -} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designmodecontext.cpp b/src/plugins/qmldesigner/designmodecontext.cpp index 2d73a01839b..336df96a87f 100644 --- a/src/plugins/qmldesigner/designmodecontext.cpp +++ b/src/plugins/qmldesigner/designmodecontext.cpp @@ -17,7 +17,7 @@ DesignModeContext::DesignModeContext(QWidget *widget) : IContext(widget) { setWidget(widget); - setContext(Core::Context(Constants::C_QMLDESIGNER, Constants::C_QT_QUICK_TOOLS_MENU)); + setContext(Core::Context(Constants::qmlDesignerContextId, Constants::qtQuickToolsMenuContextId)); } void DesignModeContext::contextHelp(const HelpCallback &callback) const @@ -29,7 +29,7 @@ FormEditorContext::FormEditorContext(QWidget *widget) : IContext(widget) { setWidget(widget); - setContext(Core::Context(Constants::C_QMLFORMEDITOR, Constants::C_QT_QUICK_TOOLS_MENU)); + setContext(Core::Context(Constants::qmlFormEditorContextId, Constants::qtQuickToolsMenuContextId)); } void FormEditorContext::contextHelp(const HelpCallback &callback) const @@ -41,7 +41,7 @@ Editor3DContext::Editor3DContext(QWidget *widget) : IContext(widget) { setWidget(widget); - setContext(Core::Context(Constants::C_QMLEDITOR3D, Constants::C_QT_QUICK_TOOLS_MENU)); + setContext(Core::Context(Constants::qml3DEditorContextId, Constants::qtQuickToolsMenuContextId)); } void Editor3DContext::contextHelp(const HelpCallback &callback) const @@ -53,7 +53,8 @@ MaterialBrowserContext::MaterialBrowserContext(QWidget *widget) : IContext(widget) { setWidget(widget); - setContext(Core::Context(Constants::C_QMLMATERIALBROWSER, Constants::C_QT_QUICK_TOOLS_MENU)); + setContext(Core::Context(Constants::qmlMaterialBrowserContextId, + Constants::qtQuickToolsMenuContextId)); } void MaterialBrowserContext::contextHelp(const HelpCallback &callback) const @@ -65,7 +66,8 @@ AssetsLibraryContext::AssetsLibraryContext(QWidget *widget) : IContext(widget) { setWidget(widget); - setContext(Core::Context(Constants::C_QMLASSETSLIBRARY, Constants::C_QT_QUICK_TOOLS_MENU)); + setContext( + Core::Context(Constants::qmlAssetsLibraryContextId, Constants::qtQuickToolsMenuContextId)); } void AssetsLibraryContext::contextHelp(const HelpCallback &callback) const @@ -77,7 +79,7 @@ NavigatorContext::NavigatorContext(QWidget *widget) : IContext(widget) { setWidget(widget); - setContext(Core::Context(Constants::C_QMLNAVIGATOR, Constants::C_QT_QUICK_TOOLS_MENU)); + setContext(Core::Context(Constants::qmlNavigatorContextId, Constants::qtQuickToolsMenuContextId)); } void NavigatorContext::contextHelp(const HelpCallback &callback) const @@ -89,7 +91,9 @@ TextEditorContext::TextEditorContext(TextEditorWidget *parent) : IContext(parent) , m_parent(parent) { - setContext(Core::Context(Constants::C_QMLTEXTEDITOR, Constants::C_QT_QUICK_TOOLS_MENU)); + static constexpr char qmlTextEditorContextId[] = "QmlDesigner::TextEditor"; + + setContext(Core::Context(qmlTextEditorContextId, Constants::qtQuickToolsMenuContextId)); } void TextEditorContext::contextHelp(const HelpCallback &callback) const diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachecollector.cpp b/src/plugins/qmldesigner/imagecachecollectors/imagecachecollector.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/imagecachecollector.cpp rename to src/plugins/qmldesigner/imagecachecollectors/imagecachecollector.cpp diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachecollector.h b/src/plugins/qmldesigner/imagecachecollectors/imagecachecollector.h similarity index 97% rename from src/plugins/qmldesigner/designercore/imagecache/imagecachecollector.h rename to src/plugins/qmldesigner/imagecachecollectors/imagecachecollector.h index fec68c28949..e6250393b2a 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/imagecachecollector.h +++ b/src/plugins/qmldesigner/imagecachecollectors/imagecachecollector.h @@ -3,7 +3,7 @@ #pragma once -#include "imagecachecollectorinterface.h" +#include #include diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecacheconnectionmanager.cpp b/src/plugins/qmldesigner/imagecachecollectors/imagecacheconnectionmanager.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/imagecacheconnectionmanager.cpp rename to src/plugins/qmldesigner/imagecachecollectors/imagecacheconnectionmanager.cpp diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecacheconnectionmanager.h b/src/plugins/qmldesigner/imagecachecollectors/imagecacheconnectionmanager.h similarity index 92% rename from src/plugins/qmldesigner/designercore/imagecache/imagecacheconnectionmanager.h rename to src/plugins/qmldesigner/imagecachecollectors/imagecacheconnectionmanager.h index 276916b4a12..0a881665293 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/imagecacheconnectionmanager.h +++ b/src/plugins/qmldesigner/imagecachecollectors/imagecacheconnectionmanager.h @@ -3,7 +3,7 @@ #pragma once -#include +#include namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachefontcollector.cpp b/src/plugins/qmldesigner/imagecachecollectors/imagecachefontcollector.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/imagecachefontcollector.cpp rename to src/plugins/qmldesigner/imagecachecollectors/imagecachefontcollector.cpp diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachefontcollector.h b/src/plugins/qmldesigner/imagecachecollectors/imagecachefontcollector.h similarity index 95% rename from src/plugins/qmldesigner/designercore/imagecache/imagecachefontcollector.h rename to src/plugins/qmldesigner/imagecachecollectors/imagecachefontcollector.h index 104e48e9b2f..352d226189d 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/imagecachefontcollector.h +++ b/src/plugins/qmldesigner/imagecachecollectors/imagecachefontcollector.h @@ -3,7 +3,7 @@ #pragma once -#include "imagecachecollectorinterface.h" +#include namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/designercore/imagecache/meshimagecachecollector.cpp b/src/plugins/qmldesigner/imagecachecollectors/meshimagecachecollector.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/meshimagecachecollector.cpp rename to src/plugins/qmldesigner/imagecachecollectors/meshimagecachecollector.cpp diff --git a/src/plugins/qmldesigner/designercore/imagecache/meshimagecachecollector.h b/src/plugins/qmldesigner/imagecachecollectors/meshimagecachecollector.h similarity index 97% rename from src/plugins/qmldesigner/designercore/imagecache/meshimagecachecollector.h rename to src/plugins/qmldesigner/imagecachecollectors/meshimagecachecollector.h index 98c2e84605e..9836e625e76 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/meshimagecachecollector.h +++ b/src/plugins/qmldesigner/imagecachecollectors/meshimagecachecollector.h @@ -3,7 +3,6 @@ #pragma once -#include "imagecachecollectorinterface.h" #include "imagecachecollector.h" namespace ProjectExplorer { diff --git a/src/plugins/qmldesigner/designercore/imagecache/textureimagecachecollector.cpp b/src/plugins/qmldesigner/imagecachecollectors/textureimagecachecollector.cpp similarity index 96% rename from src/plugins/qmldesigner/designercore/imagecache/textureimagecachecollector.cpp rename to src/plugins/qmldesigner/imagecachecollectors/textureimagecachecollector.cpp index 9ec83c0e5b3..8a19f74b5f3 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/textureimagecachecollector.cpp +++ b/src/plugins/qmldesigner/imagecachecollectors/textureimagecachecollector.cpp @@ -3,8 +3,8 @@ #include "textureimagecachecollector.h" -#include -#include +#include +#include #include #include diff --git a/src/plugins/qmldesigner/designercore/imagecache/textureimagecachecollector.h b/src/plugins/qmldesigner/imagecachecollectors/textureimagecachecollector.h similarity index 95% rename from src/plugins/qmldesigner/designercore/imagecache/textureimagecachecollector.h rename to src/plugins/qmldesigner/imagecachecollectors/textureimagecachecollector.h index fa8885b4d4a..0663294acb4 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/textureimagecachecollector.h +++ b/src/plugins/qmldesigner/imagecachecollectors/textureimagecachecollector.h @@ -3,7 +3,7 @@ #pragma once -#include "imagecachecollectorinterface.h" +#include namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/designercore/instances/baseconnectionmanager.cpp b/src/plugins/qmldesigner/instances/baseconnectionmanager.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/instances/baseconnectionmanager.cpp rename to src/plugins/qmldesigner/instances/baseconnectionmanager.cpp diff --git a/src/plugins/qmldesigner/designercore/instances/baseconnectionmanager.h b/src/plugins/qmldesigner/instances/baseconnectionmanager.h similarity index 91% rename from src/plugins/qmldesigner/designercore/instances/baseconnectionmanager.h rename to src/plugins/qmldesigner/instances/baseconnectionmanager.h index a101ebc376e..e00a11f8de5 100644 --- a/src/plugins/qmldesigner/designercore/instances/baseconnectionmanager.h +++ b/src/plugins/qmldesigner/instances/baseconnectionmanager.h @@ -19,7 +19,8 @@ namespace QmlDesigner { class AbstractView; -class QMLDESIGNERCORE_EXPORT BaseConnectionManager : public QObject, public ConnectionManagerInterface +class QMLDESIGNER_EXPORT BaseConnectionManager : public QObject, + public ConnectionManagerInterface { Q_OBJECT diff --git a/src/plugins/qmldesigner/designercore/instances/capturingconnectionmanager.cpp b/src/plugins/qmldesigner/instances/capturingconnectionmanager.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/instances/capturingconnectionmanager.cpp rename to src/plugins/qmldesigner/instances/capturingconnectionmanager.cpp diff --git a/src/plugins/qmldesigner/designercore/instances/capturingconnectionmanager.h b/src/plugins/qmldesigner/instances/capturingconnectionmanager.h similarity index 84% rename from src/plugins/qmldesigner/designercore/instances/capturingconnectionmanager.h rename to src/plugins/qmldesigner/instances/capturingconnectionmanager.h index 72d693b98f3..d0a29d06855 100644 --- a/src/plugins/qmldesigner/designercore/instances/capturingconnectionmanager.h +++ b/src/plugins/qmldesigner/instances/capturingconnectionmanager.h @@ -3,11 +3,11 @@ #pragma once -#include +#include "interactiveconnectionmanager.h" namespace QmlDesigner { -class QMLDESIGNERCORE_EXPORT CapturingConnectionManager : public InteractiveConnectionManager +class QMLDESIGNER_EXPORT CapturingConnectionManager : public InteractiveConnectionManager { Q_OBJECT diff --git a/src/plugins/qmldesigner/designercore/instances/connectionmanager.cpp b/src/plugins/qmldesigner/instances/connectionmanager.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/instances/connectionmanager.cpp rename to src/plugins/qmldesigner/instances/connectionmanager.cpp diff --git a/src/plugins/qmldesigner/designercore/instances/connectionmanager.h b/src/plugins/qmldesigner/instances/connectionmanager.h similarity index 95% rename from src/plugins/qmldesigner/designercore/instances/connectionmanager.h rename to src/plugins/qmldesigner/instances/connectionmanager.h index fc289fe4f71..87ad570d235 100644 --- a/src/plugins/qmldesigner/designercore/instances/connectionmanager.h +++ b/src/plugins/qmldesigner/instances/connectionmanager.h @@ -17,7 +17,7 @@ QT_END_NAMESPACE namespace QmlDesigner { -class QMLDESIGNERCORE_EXPORT ConnectionManager : public BaseConnectionManager +class QMLDESIGNER_EXPORT ConnectionManager : public BaseConnectionManager { Q_OBJECT diff --git a/src/plugins/qmldesigner/designercore/instances/connectionmanagerinterface.cpp b/src/plugins/qmldesigner/instances/connectionmanagerinterface.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/instances/connectionmanagerinterface.cpp rename to src/plugins/qmldesigner/instances/connectionmanagerinterface.cpp diff --git a/src/plugins/qmldesigner/designercore/instances/connectionmanagerinterface.h b/src/plugins/qmldesigner/instances/connectionmanagerinterface.h similarity index 92% rename from src/plugins/qmldesigner/designercore/instances/connectionmanagerinterface.h rename to src/plugins/qmldesigner/instances/connectionmanagerinterface.h index c41771e019c..2154eec17c2 100644 --- a/src/plugins/qmldesigner/designercore/instances/connectionmanagerinterface.h +++ b/src/plugins/qmldesigner/instances/connectionmanagerinterface.h @@ -2,7 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qprocessuniqueptr.h" -#include +#include #include @@ -21,10 +21,10 @@ class NodeInstanceServerInterface; class AbstractView; class ExternalDependenciesInterface; -class QMLDESIGNERCORE_EXPORT ConnectionManagerInterface +class QMLDESIGNER_EXPORT ConnectionManagerInterface { public: - class QMLDESIGNERCORE_EXPORT Connection final + class QMLDESIGNER_EXPORT Connection final { public: Connection(const QString &name, const QString &mode); diff --git a/src/plugins/qmldesigner/designercore/instances/interactiveconnectionmanager.cpp b/src/plugins/qmldesigner/instances/interactiveconnectionmanager.cpp similarity index 95% rename from src/plugins/qmldesigner/designercore/instances/interactiveconnectionmanager.cpp rename to src/plugins/qmldesigner/instances/interactiveconnectionmanager.cpp index 07ae483d9a1..2c3de8082a3 100644 --- a/src/plugins/qmldesigner/designercore/instances/interactiveconnectionmanager.cpp +++ b/src/plugins/qmldesigner/instances/interactiveconnectionmanager.cpp @@ -62,8 +62,9 @@ void InteractiveConnectionManager::showCannotConnectToPuppetWarningAndSwitchToEd "Switching to another kit might help.")); QmlDesignerPlugin::instance()->switchToTextModeDeferred(); - if (m_view) - m_view->emitDocumentMessage(tr("Cannot Connect to QML Emulation Layer (QML Puppet)")); + if (m_view && m_view->isAttached()) + m_view->model()->emitDocumentMessage( + tr("Cannot Connect to QML Emulation Layer (QML Puppet)")); } void InteractiveConnectionManager::dispatchCommand(const QVariant &command, Connection &connection) diff --git a/src/plugins/qmldesigner/designercore/instances/interactiveconnectionmanager.h b/src/plugins/qmldesigner/instances/interactiveconnectionmanager.h similarity index 100% rename from src/plugins/qmldesigner/designercore/instances/interactiveconnectionmanager.h rename to src/plugins/qmldesigner/instances/interactiveconnectionmanager.h diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp b/src/plugins/qmldesigner/instances/nodeinstance.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp rename to src/plugins/qmldesigner/instances/nodeinstance.cpp diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstance.h b/src/plugins/qmldesigner/instances/nodeinstance.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/nodeinstance.h rename to src/plugins/qmldesigner/instances/nodeinstance.h diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp b/src/plugins/qmldesigner/instances/nodeinstanceserverproxy.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.cpp rename to src/plugins/qmldesigner/instances/nodeinstanceserverproxy.cpp diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h b/src/plugins/qmldesigner/instances/nodeinstanceserverproxy.h similarity index 100% rename from src/plugins/qmldesigner/designercore/instances/nodeinstanceserverproxy.h rename to src/plugins/qmldesigner/instances/nodeinstanceserverproxy.h diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/instances/nodeinstanceview.cpp similarity index 95% rename from src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp rename to src/plugins/qmldesigner/instances/nodeinstanceview.cpp index d965b9ae177..60802c95aa3 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/instances/nodeinstanceview.cpp @@ -66,7 +66,7 @@ #include -#include +#include #include #include @@ -137,6 +137,8 @@ NodeInstanceView::NodeInstanceView(ConnectionManagerInterface &connectionManager , m_fileSystemWatcher(new QFileSystemWatcher(this)) , m_qsbEnabled(qsbEnabled) { + setKind(Kind::NodeInstance); + m_baseStatePreviewImage.fill(0xFFFFFF); // Interval > 0 is used for QFileSystemWatcher related timers to allow all notifications @@ -299,11 +301,14 @@ void NodeInstanceView::handleCrash() #ifdef QT_DEBUG forceRestartTime = 10000; #endif - if (elaspsedTimeSinceLastCrash > forceRestartTime) + if (elaspsedTimeSinceLastCrash > forceRestartTime) { restartProcess(); - else - emitDocumentMessage( - ::QmlDesigner::NodeInstanceView::tr("Qt Quick emulation layer crashed.")); + } else { + if (isAttached()) { + model()->emitDocumentMessage( + ::QmlDesigner::NodeInstanceView::tr("Qt Quick emulation layer crashed.")); + } + } emitCustomNotification(QStringLiteral("puppet crashed")); } @@ -344,7 +349,8 @@ void NodeInstanceView::restartProcess() { clearErrors(); emitInstanceErrorChange({}); - emitDocumentMessage({}, {}); + if (isAttached()) + model()->emitDocumentMessage({}, {}); if (m_restartProcessTimerId) killTimer(m_restartProcessTimerId); @@ -689,7 +695,7 @@ void NodeInstanceView::auxiliaryDataChanged(const ModelNode &node, m_nodeInstanceServer->changePropertyBindings({{container}}); } } - }; + } break; case AuxiliaryDataType::Temporary: @@ -703,7 +709,7 @@ void NodeInstanceView::auxiliaryDataChanged(const ModelNode &node, } else if (key.name == "previewSize") { m_nodeInstanceServer->changePreviewImageSize(value.toSize()); } - }; + } break; default: @@ -711,12 +717,23 @@ void NodeInstanceView::auxiliaryDataChanged(const ModelNode &node, } } -void NodeInstanceView::customNotification(const AbstractView *view, const QString &identifier, const QList &, const QList &) +void NodeInstanceView::customNotification(const AbstractView *view, + const QString &identifier, + const QList &, + const QList &) { if (view && identifier == QStringLiteral("reset QmlPuppet")) delayedRestartProcess(); } +void NodeInstanceView::customNotification(const CustomNotificationPackage &package) +{ + if (auto inputEvent = std::get_if(&package)) + sendInputEvent(inputEvent->event); + else if (auto resize3DCanvas = std::get_if(&package)) + edit3DViewResized(resize3DCanvas->size); +} + void NodeInstanceView::nodeSourceChanged(const ModelNode &node, const QString & newNodeSource) { QTC_ASSERT(m_nodeInstanceServer, return); @@ -906,10 +923,13 @@ void NodeInstanceView::updatePosition(const QList &propertyList { QMultiHash informationChangeHash; + QmlModelState currentState = currentStateNode(); + bool isBaseState = currentState.isBaseState(); + for (const VariantProperty &variantProperty : propertyList) { if (variantProperty.name() == "x") { const ModelNode modelNode = variantProperty.parentModelNode(); - if (!currentState().isBaseState() && QmlPropertyChanges::isValidQmlPropertyChanges(modelNode)) { + if (!isBaseState && QmlPropertyChanges::isValidQmlPropertyChanges(modelNode)) { ModelNode targetModelNode = QmlPropertyChanges(modelNode).target(); if (targetModelNode.isValid()) { NodeInstance instance = instanceForModelNode(targetModelNode); @@ -921,7 +941,7 @@ void NodeInstanceView::updatePosition(const QList &propertyList } } else if (variantProperty.name() == "y") { const ModelNode modelNode = variantProperty.parentModelNode(); - if (!currentState().isBaseState() && QmlPropertyChanges::isValidQmlPropertyChanges(modelNode)) { + if (!isBaseState && QmlPropertyChanges::isValidQmlPropertyChanges(modelNode)) { ModelNode targetModelNode = QmlPropertyChanges(modelNode).target(); if (targetModelNode.isValid()) { NodeInstance instance = instanceForModelNode(targetModelNode); @@ -931,11 +951,11 @@ void NodeInstanceView::updatePosition(const QList &propertyList NodeInstance instance = instanceForModelNode(modelNode); setYValue(instance, variantProperty, informationChangeHash); } - } else if (currentTimeline().isValid() + } else if (QmlTimeline::isValidQmlTimeline(currentTimelineNode()) && variantProperty.name() == "value" - && QmlTimelineKeyframeGroup::isValidKeyframe(variantProperty.parentModelNode())) { - - QmlTimelineKeyframeGroup frames = QmlTimelineKeyframeGroup::keyframeGroupForKeyframe(variantProperty.parentModelNode()); + && QmlTimelineKeyframeGroup::isValidKeyframe(variantProperty.parentModelNode())) { + QmlTimelineKeyframeGroup frames = QmlTimelineKeyframeGroup::keyframeGroupForKeyframe( + variantProperty.parentModelNode()); if (frames.propertyName() == "x" && frames.target().isValid()) { NodeInstance instance = instanceForModelNode(frames.target()); @@ -1366,8 +1386,9 @@ ChangeValuesCommand NodeInstanceView::createChangeValueCommand(const QList containerList; - bool reflectionFlag = m_puppetTransaction.isValid() - && (!currentTimeline().isValid() || !currentTimeline().isRecording()); + QmlTimeline timeline = currentTimelineNode(); + + bool reflectionFlag = m_puppetTransaction.isValid() && (!timeline || !timeline.isRecording()); for (const VariantProperty &property : propertyList) { ModelNode node = property.parentModelNode(); @@ -1620,6 +1641,9 @@ void NodeInstanceView::informationChanged(const InformationChangedCommand &comma QImage NodeInstanceView::statePreviewImage(const ModelNode &stateNode) const { + if (!isAttached()) + return {}; + if (stateNode == rootModelNode()) return m_baseStatePreviewImage; @@ -1730,14 +1754,15 @@ void NodeInstanceView::token(const TokenCommand &command) nodeVector.append(modelNodeForInternalId(instanceId)); } - emitInstanceToken(command.tokenName(), command.tokenNumber(), nodeVector); + if (isAttached()) + model()->emitInstanceToken(this, command.tokenName(), command.tokenNumber(), nodeVector); } void NodeInstanceView::debugOutput(const DebugOutputCommand & command) { DocumentMessage error(::QmlDesigner::NodeInstanceView::tr("Qt Quick emulation layer crashed.")); - if (command.instanceIds().isEmpty()) { - emitDocumentMessage(command.text()); + if (command.instanceIds().isEmpty() && isAttached()) { + model()->emitDocumentMessage(command.text()); } else { QVector instanceIdsWithChangedErrors; const QVector instanceIds = command.instanceIds(); @@ -1746,8 +1771,8 @@ void NodeInstanceView::debugOutput(const DebugOutputCommand & command) if (instance.isValid()) { if (instance.setError(command.text())) instanceIdsWithChangedErrors.append(instanceId); - } else { - emitDocumentMessage(command.text()); + } else if (isAttached()) { + model()->emitDocumentMessage(command.text()); } } emitInstanceErrorChange(instanceIdsWithChangedErrors); @@ -1790,16 +1815,18 @@ void NodeInstanceView::handlePuppetToCreatorCommand(const PuppetToCreatorCommand } } else if (command.type() == PuppetToCreatorCommand::Render3DView) { ImageContainer container = qvariant_cast(command.data()); - if (!container.image().isNull()) - emitRenderImage3DChanged(container.image()); + if (!container.image().isNull() && isAttached()) + model()->emitRenderImage3DChanged(this, container.image()); } else if (command.type() == PuppetToCreatorCommand::ActiveSceneChanged) { const auto sceneState = qvariant_cast(command.data()); - emitUpdateActiveScene3D(sceneState); + if (isAttached()) + model()->emitUpdateActiveScene3D(this, sceneState); } else if (command.type() == PuppetToCreatorCommand::ActiveSplitChanged) { // Active split change is a special case of active scene change QVariantMap splitState; splitState.insert("activeSplit", command.data()); - emitUpdateActiveScene3D(splitState); + if (isAttached()) + model()->emitUpdateActiveScene3D(this, splitState); } else if (command.type() == PuppetToCreatorCommand::RenderModelNodePreviewImage) { ImageContainer container = qvariant_cast(command.data()); QImage image = container.image(); @@ -1815,13 +1842,15 @@ void NodeInstanceView::handlePuppetToCreatorCommand(const PuppetToCreatorCommand QVariantMap supportMap; if (externalDependencies().isQt6Project()) supportMap = qvariant_cast(command.data()); - emitImport3DSupportChanged(supportMap); + if (isAttached()) + model()->emitImport3DSupportChanged(this, supportMap); } else if (command.type() == PuppetToCreatorCommand::NodeAtPos) { auto data = qvariant_cast(command.data()); if (data.size() == 2) { ModelNode modelNode = modelNodeForInternalId(data[0].toInt()); QVector3D pos3d = data[1].value(); - emitNodeAtPosResult(modelNode, pos3d); + if (isAttached()) + model()->emitNodeAtPosResult(this, modelNode, pos3d); } } } @@ -1841,9 +1870,9 @@ void NodeInstanceView::selectedNodesChanged(const QList &selectedNode m_rotBlockTimer.start(); } -void NodeInstanceView::sendInputEvent(QEvent *e) const +void NodeInstanceView::sendInputEvent(QEvent *event) { - m_nodeInstanceServer->inputEvent(InputEventCommand(e)); + m_nodeInstanceServer->inputEvent(InputEventCommand(event)); } void NodeInstanceView::view3DAction(View3DActionType type, const QVariant &value) @@ -1851,6 +1880,8 @@ void NodeInstanceView::view3DAction(View3DActionType type, const QVariant &value m_nodeInstanceServer->view3DAction({type, value}); } +constexpr double previewImageDimensions = 150.; + void NodeInstanceView::requestModelNodePreviewImage(const ModelNode &node, const ModelNode &renderNode, const QSize &size, @@ -1877,7 +1908,7 @@ void NodeInstanceView::requestModelNodePreviewImage(const ModelNode &node, if (size.isValid()) { imageSize = size * ratio; } else { - const int dim = Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * ratio; + const int dim = std::lround(previewImageDimensions * ratio); imageSize = {dim, dim}; } @@ -1887,7 +1918,7 @@ void NodeInstanceView::requestModelNodePreviewImage(const ModelNode &node, } } -void NodeInstanceView::edit3DViewResized(const QSize &size) const +void NodeInstanceView::edit3DViewResized(const QSize &size) { m_nodeInstanceServer->update3DViewState(Update3dViewStateCommand(size)); } @@ -1898,6 +1929,49 @@ void NodeInstanceView::timerEvent(QTimerEvent *event) restartProcess(); } +void NodeInstanceView::emitInstancePropertyChange(const QList> &propertyList) +{ + if (isAttached()) + model()->emitInstancePropertyChange(this, propertyList); +} + +void NodeInstanceView::emitInstanceErrorChange(const QVector &instanceIds) +{ + if (isAttached()) + model()->emitInstanceErrorChange(this, instanceIds); +} + +void NodeInstanceView::emitInstancesCompleted(const QVector &nodeVector) +{ + if (isAttached()) + model()->emitInstancesCompleted(this, nodeVector); +} + +void NodeInstanceView::emitInstanceInformationsChange( + const QMultiHash &informationChangeHash) +{ + if (isAttached()) + model()->emitInstanceInformationsChange(this, informationChangeHash); +} + +void NodeInstanceView::emitInstancesRenderImageChanged(const QVector &nodeVector) +{ + if (isAttached()) + model()->emitInstancesRenderImageChanged(this, nodeVector); +} + +void NodeInstanceView::emitInstancesPreviewImageChanged(const QVector &nodeVector) +{ + if (isAttached()) + model()->emitInstancesPreviewImageChanged(this, nodeVector); +} + +void NodeInstanceView::emitInstancesChildrenChanged(const QVector &nodeVector) +{ + if (isAttached()) + model()->emitInstancesChildrenChanged(this, nodeVector); +} + QVariant NodeInstanceView::modelNodePreviewImageDataToVariant(const ModelNodePreviewImageData &imageData) const { static QPixmap placeHolder; @@ -1948,7 +2022,7 @@ QVariant NodeInstanceView::previewImageDataForImageNode(const ModelNode &modelNo return previewImageDataForGenericNode(modelNode, boundNode); } else { QmlItemNode itemNode(boundNode); - const int dim = Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * ratio; + const int dim = std::lround(previewImageDimensions * ratio); imageData.pixmap = itemNode.instanceRenderPixmap().scaled(dim, dim, Qt::KeepAspectRatio); @@ -2001,7 +2075,7 @@ QVariant NodeInstanceView::previewImageDataForImageNode(const ModelNode &modelNo originalPixmap.load(imageSource); } if (!originalPixmap.isNull()) { - const int dim = Constants::MODELNODE_PREVIEW_IMAGE_DIMENSIONS * ratio; + const int dim = std::lround(previewImageDimensions * ratio); imageData.pixmap = originalPixmap.scaled(dim, dim, Qt::KeepAspectRatio); imageData.pixmap.setDevicePixelRatio(ratio); imageData.time = modified; @@ -2062,7 +2136,8 @@ void NodeInstanceView::updatePreviewImageForNode(const ModelNode &modelNode, QPixmap pixmap = QPixmap::fromImage(image); if (m_imageDataMap.contains(modelNode.id())) m_imageDataMap[modelNode.id()].pixmap = pixmap; - emitModelNodelPreviewPixmapChanged(modelNode, pixmap, requestId); + if (isAttached()) + model()->emitModelNodelPreviewPixmapChanged(this, modelNode, pixmap, requestId); } void NodeInstanceView::updateWatcher(const QString &path) @@ -2207,7 +2282,7 @@ void NodeInstanceView::updateQsbPathToFilterMap() // Separate files to path and file name (called filter here as it can contain wildcards) // and group filters by paths. Blank path indicates project-wide file wildcard. for (const auto &file : shaderToolFiles) { - int idx = file.lastIndexOf('/'); + auto idx = file.lastIndexOf('/'); QString key; QString filter; if (idx >= 0) { diff --git a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h b/src/plugins/qmldesigner/instances/nodeinstanceview.h similarity index 91% rename from src/plugins/qmldesigner/designercore/include/nodeinstanceview.h rename to src/plugins/qmldesigner/instances/nodeinstanceview.h index 24e2a9258e2..44e792b9e39 100644 --- a/src/plugins/qmldesigner/designercore/include/nodeinstanceview.h +++ b/src/plugins/qmldesigner/instances/nodeinstanceview.h @@ -3,9 +3,9 @@ #pragma once -#include "qmldesignercorelib_global.h" #include "abstractview.h" #include "modelcache.h" +#include "qmldesigner_global.h" #include "rewritertransaction.h" #include @@ -57,7 +57,8 @@ class TokenCommand; class ConnectionManagerInterface; class ExternalDependenciesInterface; -class QMLDESIGNERCORE_EXPORT NodeInstanceView : public AbstractView, public NodeInstanceClientInterface +class QMLDESIGNER_EXPORT NodeInstanceView : public AbstractView, + public NodeInstanceClientInterface { Q_OBJECT @@ -90,7 +91,11 @@ public: void auxiliaryDataChanged(const ModelNode &node, AuxiliaryDataKeyView key, const QVariant &data) override; - void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data) override; + void customNotification(const AbstractView *view, + const QString &identifier, + const QList &nodeList, + const QList &data) override; + void customNotification(const CustomNotificationPackage &) override; void nodeSourceChanged(const ModelNode &modelNode, const QString &newNodeSource) override; void capturedData(const CapturedDataCommand &capturedData) override; void currentStateChanged(const ModelNode &node) override; @@ -132,13 +137,11 @@ public: void selectedNodesChanged(const QList &selectedNodeList, const QList &lastSelectedNodeList) override; - void sendInputEvent(QEvent *e) const; void view3DAction(View3DActionType type, const QVariant &value) override; void requestModelNodePreviewImage(const ModelNode &node, const ModelNode &renderNode, const QSize &size = {}, const QByteArray &requestId = {}) const; - void edit3DViewResized(const QSize &size) const; void handlePuppetToCreatorCommand(const PuppetToCreatorCommand &command) override; @@ -166,7 +169,19 @@ public: protected: void timerEvent(QTimerEvent *event) override; + void emitInstancePropertyChange(const QList> &propertyList); + void emitInstanceErrorChange(const QVector &instanceIds); + void emitInstancesCompleted(const QVector &nodeList); + void emitInstanceInformationsChange( + const QMultiHash &informationChangeHash); + void emitInstancesRenderImageChanged(const QVector &nodeList); + void emitInstancesPreviewImageChanged(const QVector &nodeList); + void emitInstancesChildrenChanged(const QVector &nodeList); + private: // functions + void sendInputEvent(QEvent *e); + void edit3DViewResized(const QSize &size); + std::unique_ptr createNodeInstanceServerProxy(); void activateState(const NodeInstance &instance); void activateBaseState(); diff --git a/src/plugins/qmldesigner/designercore/instances/puppetstarter.cpp b/src/plugins/qmldesigner/instances/puppetstarter.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/instances/puppetstarter.cpp rename to src/plugins/qmldesigner/instances/puppetstarter.cpp diff --git a/src/plugins/qmldesigner/designercore/instances/puppetstarter.h b/src/plugins/qmldesigner/instances/puppetstarter.h similarity index 100% rename from src/plugins/qmldesigner/designercore/instances/puppetstarter.h rename to src/plugins/qmldesigner/instances/puppetstarter.h diff --git a/src/plugins/qmldesigner/designercore/instances/qprocessuniqueptr.h b/src/plugins/qmldesigner/instances/qprocessuniqueptr.h similarity index 100% rename from src/plugins/qmldesigner/designercore/instances/qprocessuniqueptr.h rename to src/plugins/qmldesigner/instances/qprocessuniqueptr.h diff --git a/src/plugins/qmldesigner/libs/CMakeLists.txt b/src/plugins/qmldesigner/libs/CMakeLists.txt new file mode 100644 index 00000000000..7cac0a93a3d --- /dev/null +++ b/src/plugins/qmldesigner/libs/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(designercore) +add_subdirectory(qmldesignerutils) diff --git a/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt b/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt new file mode 100644 index 00000000000..61ed67663f8 --- /dev/null +++ b/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt @@ -0,0 +1,405 @@ +add_qtc_library(QmlDesignerCore + CONDITION TARGET Qt6::QmlPrivate AND TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate + PROPERTIES SKIP_AUTOUIC ON + DEPENDS + Threads::Threads + Utils + Qt::Widgets + Qt::Qml + Qt::QmlPrivate + Qt::Quick + Qt6::QmlDomPrivate + Qt6::QmlCompilerPrivate + QmlJS + TextEditorSupport + QmlDesignerSettings + PUBLIC_DEPENDS + QmlPuppetCommunication + QmlDesignerUtils + Sqlite + DEFINES + $<$:QDS_USE_PROJECTSTORAGE> + $<$:QTC_USE_QML_DESIGNER_LITE> + PUBLIC_INCLUDES + ${CMAKE_CURRENT_LIST_DIR} + include +) + +extend_qtc_library(QmlDesignerCore + PUBLIC_INCLUDES designercoreutils + SOURCES_PREFIX designercoreutils + SOURCES + generatedcomponentutils.cpp + generatedcomponentutils.h + modelmerger.cpp + modelmerger.h + modelutils.cpp + modelutils.h + predicate.h + stylesheetmerger.cpp + stylesheetmerger.h + uniquename.cpp + uniquename.h +) + +extend_qtc_library(QmlDesignerCore + CONDITION ENABLE_PROJECT_STORAGE_TRACING OR ENABLE_SOURCE_PATH_STORAGE_TRACING OR ENABLE_IMAGE_CACHE_TRACING OR ENABLE_MODEL_TRACING OR ENABLE_METAINFO_TRACING + PUBLIC_DEPENDS Nanotrace + PUBLIC_DEFINES + ENABLE_QMLDESIGNER_TRACING + DEFINES + $<$:ENABLE_PROJECT_STORAGE_TRACING> + $<$:ENABLE_SOURCE_PATH_STORAGE_TRACING> + $<$:ENABLE_IMAGE_CACHE_TRACING> + $<$:ENABLE_MODEL_TRACING> + $<$:ENABLE_METAINFO_TRACING> +) + +extend_qtc_library(QmlDesignerCore + CONDITION ENABLE_COMPILE_WARNING_AS_ERROR + PROPERTIES COMPILE_WARNING_AS_ERROR ON + PUBLIC_COMPILE_OPTIONS $<$:-Wno-error=maybe-uninitialized> +) + +extend_qtc_library(QmlDesignerCore + CONDITION IS_SUPPORTED_PROJECTSTORAGE_QT + PUBLIC_DEFINES QDS_BUILD_QMLPARSER +) +extend_qtc_library(QmlDesignerCore + CONDITION UNIX AND NOT APPLE + PUBLIC_DEPENDS rt +) + +extend_qtc_library(QmlDesignerCore + INCLUDES exceptions + SOURCES_PREFIX exceptions + SOURCES + exception.cpp + invalidargumentexception.cpp + invalididexception.cpp + invalidmetainfoexception.cpp + invalidmodelnodeexception.cpp + invalidmodelstateexception.cpp + invalidpropertyexception.cpp + invalidqmlsourceexception.cpp + invalidreparentingexception.cpp + invalidslideindexexception.cpp + notimplementedexception.cpp + removebasestateexception.cpp + rewritingexception.cpp +) + +extend_qtc_library(QmlDesignerCore + INCLUDES filemanager + SOURCES_PREFIX filemanager + SOURCES + addarraymembervisitor.cpp + addarraymembervisitor.h + addobjectvisitor.cpp + addobjectvisitor.h + addpropertyvisitor.cpp + addpropertyvisitor.h + astobjecttextextractor.cpp + astobjecttextextractor.h + changeimportsvisitor.cpp + changeimportsvisitor.h + changeobjecttypevisitor.cpp + changeobjecttypevisitor.h + changepropertyvisitor.cpp + changepropertyvisitor.h + firstdefinitionfinder.cpp + firstdefinitionfinder.h + moveobjectbeforeobjectvisitor.cpp + moveobjectbeforeobjectvisitor.h + moveobjectvisitor.cpp + moveobjectvisitor.h + objectlengthcalculator.cpp + objectlengthcalculator.h + qmlrefactoring.cpp + qmlrefactoring.h + qmlrewriter.cpp + qmlrewriter.h + removepropertyvisitor.cpp + removepropertyvisitor.h + removeuiobjectmembervisitor.cpp + removeuiobjectmembervisitor.h +) + +extend_qtc_library(QmlDesignerCore + INCLUDES imagecache + SOURCES_PREFIX imagecache + SOURCES + asynchronousexplicitimagecache.cpp + asynchronousimagecache.cpp + asynchronousimagefactory.cpp + asynchronousimagefactory.h + explicitimagecacheimageprovider.cpp + explicitimagecacheimageprovider.h + imagecachecollectorinterface.h + imagecachedispatchcollector.h + imagecachegenerator.cpp + imagecachegenerator.h + imagecachegeneratorinterface.h + imagecacheimageresponse.cpp + imagecacheimageresponse.h + imagecachestorage.h + imagecachestorageinterface.h + midsizeimagecacheprovider.cpp + midsizeimagecacheprovider.h + smallimagecacheprovider.cpp + smallimagecacheprovider.h + synchronousimagecache.cpp + taskqueue.h + timestampprovider.cpp + timestampprovider.h + timestampproviderinterface.h +) + +extend_qtc_library(QmlDesignerCore + SOURCES_PREFIX tracing + SOURCES + qmldesignertracing.cpp qmldesignertracing.h +) + +extend_qtc_library(QmlDesignerCore + SOURCES_PREFIX include + SOURCES + abstractview.h + bytearraymodifier.h + componenttextmodifier.h + forwardview.h + itemlibraryentry.h + model.h + nodehints.h + plaintexteditmodifier.h + propertyparser.h + rewriterview.h + textmodifier.h +) + +extend_qtc_library(QmlDesignerCore + CONDITION NOT USE_PROJECTSTORAGE + SOURCES_PREFIX include + SOURCES + itemlibraryinfo.h + metainforeader.h + subcomponentmanager.h + metainfo.h +) + +extend_qtc_library(QmlDesignerCore + SOURCES_PROPERTIES SKIP_AUTOGEN ON + SOURCES_PREFIX include + SOURCES + abstractproperty.h + annotation.h + asynchronousexplicitimagecache.h + asynchronousimagecache.h + asynchronousimagecacheinterface.h + auxiliarydata.h + auxiliarydataproperties.h + bindingproperty.h + bytearraymodifier.h + customnotifications.h + customnotificationpackage.h + documentmessage.h + enumerationmetainfo.h + exception.h + externaldependenciesinterface.h + imagecacheauxiliarydata.h + import.h + invalidargumentexception.h + invalididexception.h + invalidmetainfoexception.h + invalidmodelnodeexception.h + invalidmodelstateexception.h + invalidpropertyexception.h + invalidqmlsourceexception.h + invalidreparentingexception.h + invalidslideindexexception.h + iwidgetplugin.h + mathutils.h + modelfwd.h + modelnode.h + modificationgroupexception.h + modificationgrouptoken.h + module.h + nodeabstractproperty.h + nodelistproperty.h + nodemetainfo.h + nodeproperty.h + notimplementedexception.h + objectpropertybinding.h + projectstorageids.h + propertybinding.h + propertycontainer.h + propertymetainfo.h + propertynode.h + puppetstartdata.h + qmldesignercorelib_exports.h + qmldesignercorelib_global.h + qmldesignercoreconstants.h + removebasestateexception.h + rewritertransaction.h + rewritingexception.h + signalhandlerproperty.h + sourcepathids.h + stringutils.h + synchronousimagecache.h + variantproperty.h +) + +extend_qtc_library(QmlDesignerCore + INCLUDES + metainfo + SOURCES_PREFIX metainfo + DEFINES SHARE_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../../../../../share/qtcreator/qmldesigner" + SOURCES + itemlibraryentry.cpp + nodehints.cpp + nodemetainfo.cpp +) + +extend_qtc_library(QmlDesignerCore + CONDITION NOT USE_PROJECTSTORAGE + SOURCES_PREFIX metainfo + SOURCES + itemlibraryinfo.cpp + metainfo.cpp + metainforeader.cpp + subcomponentmanager.cpp +) + +extend_qtc_library(QmlDesignerCore + INCLUDES model + SOURCES_PREFIX model + SOURCES + abstractproperty.cpp + abstractview.cpp + annotation.cpp + auxiliarypropertystorageview.cpp auxiliarypropertystorageview.h + bindingproperty.cpp + documentmessage.cpp + import.cpp + internalbindingproperty.cpp + internalbindingproperty.h + internalnode.cpp + internalnode_p.h + internalnodeabstractproperty.cpp + internalnodeabstractproperty.h + internalnodelistproperty.cpp + internalnodelistproperty.h + internalnodeproperty.cpp + internalnodeproperty.h + internalproperty.cpp + internalproperty.h + internalsignalhandlerproperty.cpp + internalsignalhandlerproperty.h + internalvariantproperty.cpp + internalvariantproperty.h + model.cpp + model_p.h + modelnode.cpp + modelresourcemanagementinterface.h + modelresourcemanagementfwd.h + modelresourcemanagement.cpp modelresourcemanagement.h + nodeabstractproperty.cpp + nodelistproperty.cpp + nodeproperty.cpp + signalhandlerproperty.cpp + variantproperty.cpp +) + +extend_qtc_library(QmlDesignerCore + INCLUDES rewriter + SOURCES_PREFIX rewriter + SOURCES + componenttextmodifier.cpp + modelnodepositionrecalculator.cpp + modelnodepositionrecalculator.h + modelnodepositionstorage.cpp + modelnodepositionstorage.h + modeltotextmerger.cpp + modeltotextmerger.h + plaintexteditmodifier.cpp + propertycontainer.cpp + propertynode.cpp + propertyparser.cpp + qmltextgenerator.cpp + qmltextgenerator.h + rewriteaction.cpp + rewriteaction.h + rewriteactioncompressor.cpp + rewriteactioncompressor.h + rewritertransaction.cpp + rewriterview.cpp + textmodifier.cpp + texttomodelmerger.cpp + texttomodelmerger.h +) + +extend_qtc_library(QmlDesignerCore + INCLUDES pluginmanager + SOURCES_PREFIX pluginmanager + SOURCES + widgetpluginmanager.cpp + widgetpluginmanager.h + widgetpluginpath.cpp + widgetpluginpath.h +) + +extend_qtc_library(QmlDesignerCore + SOURCES_PREFIX sourcepathstorage + PUBLIC_INCLUDES sourcepathstorage + SOURCES_PROPERTIES SKIP_AUTOGEN ON + SOURCES + nonlockingmutex.h + sourcepath.h + sourcepathcache.h + sourcepathcacheinterface.h + sourcepathcachetypes.h + sourcepathexceptions.cpp + sourcepathexceptions.h + sourcepathstorage.cpp + sourcepathstorage.h + sourcepathview.h + storagecache.h + storagecacheentry.h + storagecachefwd.h +) + +extend_qtc_library(QmlDesignerCore + SOURCES_PREFIX projectstorage + PUBLIC_INCLUDES projectstorage + SOURCES_PROPERTIES SKIP_AUTOGEN ON + DEFINES QML_DOM_MSVC2019_COMPAT # can be removed for Qt 6.8 + SOURCES + commontypecache.h + directorypathcompressor.h + filesysteminterface.h + filesystem.cpp filesystem.h + filestatus.h + filestatuscache.cpp filestatuscache.h + modulescanner.cpp modulescanner.h + projectstorageexceptions.cpp projectstorageexceptions.h + projectstorageinterface.h + projectstoragefwd.h + projectstorageinfotypes.h + projectstorageobserver.h + projectstoragepathwatcher.h + projectstoragepathwatcherinterface.h + projectstoragepathwatchernotifierinterface.h + projectstoragepathwatcher.h + projectstoragepathwatchertypes.h + projectstorageprinting.h + projectstoragetypes.h + projectstorageupdater.cpp projectstorageupdater.h + projectstorage.cpp projectstorage.h + projectstorageerrornotifierinterface.h + projectstorageerrornotifier.cpp projectstorageerrornotifier.h + typeannotationreader.cpp typeannotationreader.h + qmldocumentparserinterface.h + qmltypesparserinterface.h + qmltypesparser.cpp qmltypesparser.h + qmldocumentparser.cpp qmldocumentparser.h +) diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/generatedcomponentutils.cpp b/src/plugins/qmldesigner/libs/designercore/designercoreutils/generatedcomponentutils.cpp similarity index 66% rename from src/plugins/qmldesigner/designercore/designercoreutils/generatedcomponentutils.cpp rename to src/plugins/qmldesigner/libs/designercore/designercoreutils/generatedcomponentutils.cpp index 75f4cbf4aa2..ca5ee39e1bd 100644 --- a/src/plugins/qmldesigner/designercore/designercoreutils/generatedcomponentutils.cpp +++ b/src/plugins/qmldesigner/libs/designercore/designercoreutils/generatedcomponentutils.cpp @@ -2,10 +2,23 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "generatedcomponentutils.h" -#include + +#include namespace QmlDesigner { +constexpr QLatin1String componentBundlesMaterialBundleType{"Materials"}; +constexpr QLatin1String componentBundlesType{"Bundles"}; +constexpr QLatin1String componentBundlesUserMaterialBundleType{"UserMaterials"}; +constexpr QLatin1String composedEffectType{"Effects"}; +constexpr QLatin1String generatedComponentsFolder{"Generated"}; +constexpr QLatin1String oldAssetImportFolder{"asset_imports"}; +constexpr QLatin1String oldComponentBundleType{"ComponentBundles"}; +constexpr QLatin1String oldComponentsBundlesMaterialBundleType{"MaterialBundle"}; +constexpr QLatin1String oldEffectFolder{"Effects"}; + +namespace Constants {} // namespace Constants + bool couldBeProjectModule(const Utils::FilePath &path, const QString &projectName) { if (!path.exists()) @@ -43,11 +56,11 @@ Utils::FilePath GeneratedComponentUtils::generatedComponentsPath() const if (projectPath.isEmpty()) return {}; - Utils::FilePath assetImportsPath = projectPath.resolvePath(QLatin1String(Constants::OLD_ASSET_IMPORT_FOLDER)); + Utils::FilePath assetImportsPath = projectPath.resolvePath(oldAssetImportFolder); if (assetImportsPath.exists()) return assetImportsPath; - Utils::FilePath componentsPath = projectPath.resolvePath(QLatin1String(Constants::GENERATED_COMPONENTS_FOLDER)); + Utils::FilePath componentsPath = projectPath.resolvePath(generatedComponentsFolder); if (!componentsPath.exists()) componentsPath.createDir(); @@ -61,10 +74,10 @@ Utils::FilePath GeneratedComponentUtils::composedEffectsBasePath() const return {}; QString effectsImportPath; - if (basePath.endsWith(Constants::OLD_ASSET_IMPORT_FOLDER)) - effectsImportPath = Constants::OLD_EFFECTS_FOLDER; + if (basePath.endsWith(oldAssetImportFolder)) + effectsImportPath = oldEffectFolder; else - effectsImportPath = Constants::COMPOSED_EFFECTS_TYPE; + effectsImportPath = composedEffectType; return basePath.resolvePath(effectsImportPath); } @@ -85,10 +98,10 @@ Utils::FilePath GeneratedComponentUtils::componentBundlesBasePath() const if (basePath.isEmpty()) return {}; - if (basePath.endsWith(Constants::GENERATED_COMPONENTS_FOLDER)) - return basePath.resolvePath(QLatin1String(Constants::COMPONENT_BUNDLES_TYPE)); + if (basePath.endsWith(generatedComponentsFolder)) + return basePath.resolvePath(componentBundlesType); - return basePath.resolvePath(QLatin1String(Constants::OLD_COMPONENT_BUNDLES_TYPE)); + return basePath.resolvePath(oldComponentBundleType); } Utils::FilePath GeneratedComponentUtils::import3dBasePath() const @@ -99,10 +112,10 @@ Utils::FilePath GeneratedComponentUtils::import3dBasePath() const return {}; Utils::FilePath import3dPath; - if (basePath.endsWith(Constants::OLD_ASSET_IMPORT_FOLDER)) - return basePath.resolvePath(QLatin1String(Constants::OLD_QUICK_3D_ASSETS_FOLDER)); + if (basePath.endsWith(oldAssetImportFolder)) + return basePath.resolvePath(Constants::oldQuick3dAssetsFolder); - return basePath.resolvePath(QLatin1String(Constants::QUICK_3D_COMPONENTS_FOLDER)); + return basePath.resolvePath(Constants::quick3DComponentsFolder); } Utils::FilePath GeneratedComponentUtils::materialBundlePath() const @@ -112,10 +125,10 @@ Utils::FilePath GeneratedComponentUtils::materialBundlePath() const if (basePath.isEmpty()) return {}; - if (basePath.endsWith(Constants::OLD_COMPONENT_BUNDLES_TYPE)) - return basePath.resolvePath(QLatin1String(Constants::OLD_COMPONENT_BUNDLES_MATERIAL_BUNDLE_TYPE)); + if (basePath.endsWith(Constants::quick3DComponentsFolder)) + return basePath.resolvePath(oldComponentsBundlesMaterialBundleType); - return basePath.resolvePath(QLatin1String(Constants::COMPONENT_BUNDLES_MATERIAL_BUNDLE_TYPE)); + return basePath.resolvePath(QLatin1String(componentBundlesMaterialBundleType)); } Utils::FilePath GeneratedComponentUtils::effectBundlePath() const @@ -125,10 +138,10 @@ Utils::FilePath GeneratedComponentUtils::effectBundlePath() const if (basePath.isEmpty()) return {}; - if (basePath.endsWith(Constants::OLD_COMPONENT_BUNDLES_TYPE)) - return basePath.resolvePath(QLatin1String(Constants::OLD_COMPONENT_BUNDLES_EFFECT_BUNDLE_TYPE)); + if (basePath.endsWith(Constants::quick3DComponentsFolder)) + return basePath.resolvePath(componentBundlesMaterialBundleType); - return basePath.resolvePath(QLatin1String(Constants::COMPONENT_BUNDLES_EFFECT_BUNDLE_TYPE)); + return basePath.resolvePath(componentBundlesMaterialBundleType); } Utils::FilePath GeneratedComponentUtils::userBundlePath(const QString &bundleId) const @@ -138,13 +151,13 @@ Utils::FilePath GeneratedComponentUtils::userBundlePath(const QString &bundleId) return {}; if (bundleId == userMaterialsBundleId()) - return basePath.pathAppended(Constants::COMPONENT_BUNDLES_USER_MATERIAL_BUNDLE_TYPE); + return basePath.pathAppended(componentBundlesUserMaterialBundleType); if (bundleId == userEffectsBundleId()) - return basePath.pathAppended(Constants::COMPONENT_BUNDLES_USER_EFFECT_BUNDLE_TYPE); + return basePath.pathAppended(componentBundlesUserMaterialBundleType); if (bundleId == user3DBundleId()) - return basePath.pathAppended(Constants::COMPONENT_BUNDLES_USER_3D_BUNDLE_TYPE); + return basePath.pathAppended(componentBundlesUserMaterialBundleType); qWarning() << __FUNCTION__ << "no bundleType for bundleId:" << bundleId; return {}; @@ -182,16 +195,15 @@ Utils::FilePath GeneratedComponentUtils::projectModulePath(bool generateIfNotExi bool GeneratedComponentUtils::isImport3dPath(const QString &path) const { - return path.contains('/' + QLatin1String(Constants::OLD_QUICK_3D_ASSETS_FOLDER)) - || path.contains(QLatin1String(Constants::GENERATED_COMPONENTS_FOLDER) + '/' - + QLatin1String(Constants::QUICK_3D_COMPONENTS_FOLDER)); + return path.contains('/' + QLatin1String(Constants::oldQuick3dAssetsFolder)) + || path.contains(generatedComponentsFolder + '/' + + QLatin1String(Constants::quick3DComponentsFolder)); } bool GeneratedComponentUtils::isComposedEffectPath(const QString &path) const { - return path.contains(Constants::OLD_EFFECTS_IMPORT_FOLDER) - || path.contains(QLatin1String(Constants::GENERATED_COMPONENTS_FOLDER) + '/' - + QLatin1String(Constants::COMPOSED_EFFECTS_TYPE)); + return path.contains(oldAssetImportFolder) + || path.contains(generatedComponentsFolder + '/' + composedEffectType); } bool GeneratedComponentUtils::isBundlePath(const QString &path) const @@ -208,20 +220,20 @@ bool GeneratedComponentUtils::isGeneratedPath(const QString &path) const QString GeneratedComponentUtils::generatedComponentTypePrefix() const { Utils::FilePath basePath = generatedComponentsPath(); - if (basePath.isEmpty() || basePath.endsWith(Constants::OLD_ASSET_IMPORT_FOLDER)) + if (basePath.isEmpty() || basePath.endsWith(oldAssetImportFolder)) return {}; - return Constants::GENERATED_COMPONENTS_FOLDER; + return generatedComponentsFolder; } QString GeneratedComponentUtils::import3dTypePrefix() const { QString basePrefix = generatedComponentTypePrefix(); - if (basePrefix == Constants::GENERATED_COMPONENTS_FOLDER) - return basePrefix + '.' + QLatin1String(Constants::QUICK_3D_COMPONENTS_FOLDER); + if (basePrefix == generatedComponentsFolder) + return basePrefix + '.' + Constants::quick3DComponentsFolder; - return Constants::OLD_QUICK_3D_ASSETS_FOLDER; + return Constants::oldQuick3dAssetsFolder; } QString GeneratedComponentUtils::import3dTypePath() const @@ -235,51 +247,51 @@ QString GeneratedComponentUtils::componentBundlesTypePrefix() const { QString basePrefix = generatedComponentTypePrefix(); - if (basePrefix.endsWith(Constants::GENERATED_COMPONENTS_FOLDER)) - return basePrefix + '.' + QLatin1String(Constants::COMPONENT_BUNDLES_TYPE); + if (basePrefix.endsWith(generatedComponentsFolder)) + return basePrefix + '.' + componentBundlesType; - return Constants::OLD_COMPONENT_BUNDLES_TYPE; + return componentBundlesType; } QString GeneratedComponentUtils::composedEffectsTypePrefix() const { QString basePrefix = generatedComponentTypePrefix(); - if (basePrefix == Constants::GENERATED_COMPONENTS_FOLDER) - return basePrefix + '.' + QLatin1String(Constants::COMPOSED_EFFECTS_TYPE); + if (basePrefix == generatedComponentsFolder) + return basePrefix + '.' + composedEffectType; - return Constants::OLD_EFFECTS_FOLDER; + return oldEffectFolder; } QString GeneratedComponentUtils::materialsBundleId() const { - bool isNewImportDir = generatedComponentTypePrefix().endsWith(Constants::GENERATED_COMPONENTS_FOLDER); + bool isNewImportDir = generatedComponentTypePrefix().endsWith(generatedComponentsFolder); - return QLatin1String(isNewImportDir ? Constants::COMPONENT_BUNDLES_MATERIAL_BUNDLE_TYPE - : Constants::OLD_COMPONENT_BUNDLES_MATERIAL_BUNDLE_TYPE); + return isNewImportDir ? componentBundlesMaterialBundleType + : oldComponentsBundlesMaterialBundleType; } QString GeneratedComponentUtils::effectsBundleId() const { - bool isNewImportDir = generatedComponentTypePrefix().endsWith(Constants::GENERATED_COMPONENTS_FOLDER); + bool isNewImportDir = generatedComponentTypePrefix().endsWith(generatedComponentsFolder); - return QLatin1String(isNewImportDir ? Constants::COMPONENT_BUNDLES_EFFECT_BUNDLE_TYPE - : Constants::OLD_COMPONENT_BUNDLES_EFFECT_BUNDLE_TYPE); + return QLatin1String(isNewImportDir ? componentBundlesMaterialBundleType + : componentBundlesMaterialBundleType); } QString GeneratedComponentUtils::userMaterialsBundleId() const { - return QLatin1String(Constants::COMPONENT_BUNDLES_USER_MATERIAL_BUNDLE_TYPE); + return componentBundlesMaterialBundleType; } QString GeneratedComponentUtils::userEffectsBundleId() const { - return QLatin1String(Constants::COMPONENT_BUNDLES_USER_EFFECT_BUNDLE_TYPE); + return componentBundlesUserMaterialBundleType; } QString GeneratedComponentUtils::user3DBundleId() const { - return QLatin1String(Constants::COMPONENT_BUNDLES_USER_3D_BUNDLE_TYPE); + return componentBundlesMaterialBundleType; } QString GeneratedComponentUtils::materialsBundleType() const diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/generatedcomponentutils.h b/src/plugins/qmldesigner/libs/designercore/designercoreutils/generatedcomponentutils.h similarity index 100% rename from src/plugins/qmldesigner/designercore/designercoreutils/generatedcomponentutils.h rename to src/plugins/qmldesigner/libs/designercore/designercoreutils/generatedcomponentutils.h diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/modelmerger.cpp b/src/plugins/qmldesigner/libs/designercore/designercoreutils/modelmerger.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/designercoreutils/modelmerger.cpp rename to src/plugins/qmldesigner/libs/designercore/designercoreutils/modelmerger.cpp diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/modelmerger.h b/src/plugins/qmldesigner/libs/designercore/designercoreutils/modelmerger.h similarity index 100% rename from src/plugins/qmldesigner/designercore/designercoreutils/modelmerger.h rename to src/plugins/qmldesigner/libs/designercore/designercoreutils/modelmerger.h diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.cpp b/src/plugins/qmldesigner/libs/designercore/designercoreutils/modelutils.cpp similarity index 99% rename from src/plugins/qmldesigner/designercore/designercoreutils/modelutils.cpp rename to src/plugins/qmldesigner/libs/designercore/designercoreutils/modelutils.cpp index 355ce2f179e..5e13043b7e2 100644 --- a/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.cpp +++ b/src/plugins/qmldesigner/libs/designercore/designercoreutils/modelutils.cpp @@ -8,7 +8,6 @@ #include #include -#include #include #include diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/modelutils.h b/src/plugins/qmldesigner/libs/designercore/designercoreutils/modelutils.h similarity index 100% rename from src/plugins/qmldesigner/designercore/designercoreutils/modelutils.h rename to src/plugins/qmldesigner/libs/designercore/designercoreutils/modelutils.h diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/predicate.h b/src/plugins/qmldesigner/libs/designercore/designercoreutils/predicate.h similarity index 100% rename from src/plugins/qmldesigner/designercore/designercoreutils/predicate.h rename to src/plugins/qmldesigner/libs/designercore/designercoreutils/predicate.h diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/stylesheetmerger.cpp b/src/plugins/qmldesigner/libs/designercore/designercoreutils/stylesheetmerger.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/designercoreutils/stylesheetmerger.cpp rename to src/plugins/qmldesigner/libs/designercore/designercoreutils/stylesheetmerger.cpp diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/stylesheetmerger.h b/src/plugins/qmldesigner/libs/designercore/designercoreutils/stylesheetmerger.h similarity index 100% rename from src/plugins/qmldesigner/designercore/designercoreutils/stylesheetmerger.h rename to src/plugins/qmldesigner/libs/designercore/designercoreutils/stylesheetmerger.h diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/uniquename.cpp b/src/plugins/qmldesigner/libs/designercore/designercoreutils/uniquename.cpp similarity index 99% rename from src/plugins/qmldesigner/designercore/designercoreutils/uniquename.cpp rename to src/plugins/qmldesigner/libs/designercore/designercoreutils/uniquename.cpp index e22ab6cb985..d372b6cfb92 100644 --- a/src/plugins/qmldesigner/designercore/designercoreutils/uniquename.cpp +++ b/src/plugins/qmldesigner/libs/designercore/designercoreutils/uniquename.cpp @@ -3,7 +3,7 @@ #include "uniquename.h" -#include +#include "modelutils.h" #include #include diff --git a/src/plugins/qmldesigner/designercore/designercoreutils/uniquename.h b/src/plugins/qmldesigner/libs/designercore/designercoreutils/uniquename.h similarity index 75% rename from src/plugins/qmldesigner/designercore/designercoreutils/uniquename.h rename to src/plugins/qmldesigner/libs/designercore/designercoreutils/uniquename.h index 20bcacefdd1..6c25cc4065c 100644 --- a/src/plugins/qmldesigner/designercore/designercoreutils/uniquename.h +++ b/src/plugins/qmldesigner/libs/designercore/designercoreutils/uniquename.h @@ -9,8 +9,9 @@ namespace QmlDesigner::UniqueName { -QString generate(const QString &name, std::function predicate); -QString generatePath(const QString &path); +QMLDESIGNERCORE_EXPORT QString generate(const QString &name, + std::function predicate); +QMLDESIGNERCORE_EXPORT QString generatePath(const QString &path); QMLDESIGNERCORE_EXPORT QString generateId(QStringView id, std::function predicate = {}); diff --git a/src/plugins/qmldesigner/designercore/exceptions/exception.cpp b/src/plugins/qmldesigner/libs/designercore/exceptions/exception.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/exceptions/exception.cpp rename to src/plugins/qmldesigner/libs/designercore/exceptions/exception.cpp diff --git a/src/plugins/qmldesigner/designercore/exceptions/invalidargumentexception.cpp b/src/plugins/qmldesigner/libs/designercore/exceptions/invalidargumentexception.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/exceptions/invalidargumentexception.cpp rename to src/plugins/qmldesigner/libs/designercore/exceptions/invalidargumentexception.cpp diff --git a/src/plugins/qmldesigner/designercore/exceptions/invalididexception.cpp b/src/plugins/qmldesigner/libs/designercore/exceptions/invalididexception.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/exceptions/invalididexception.cpp rename to src/plugins/qmldesigner/libs/designercore/exceptions/invalididexception.cpp diff --git a/src/plugins/qmldesigner/designercore/exceptions/invalidmetainfoexception.cpp b/src/plugins/qmldesigner/libs/designercore/exceptions/invalidmetainfoexception.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/exceptions/invalidmetainfoexception.cpp rename to src/plugins/qmldesigner/libs/designercore/exceptions/invalidmetainfoexception.cpp diff --git a/src/plugins/qmldesigner/designercore/exceptions/invalidmodelnodeexception.cpp b/src/plugins/qmldesigner/libs/designercore/exceptions/invalidmodelnodeexception.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/exceptions/invalidmodelnodeexception.cpp rename to src/plugins/qmldesigner/libs/designercore/exceptions/invalidmodelnodeexception.cpp diff --git a/src/plugins/qmldesigner/designercore/exceptions/invalidmodelstateexception.cpp b/src/plugins/qmldesigner/libs/designercore/exceptions/invalidmodelstateexception.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/exceptions/invalidmodelstateexception.cpp rename to src/plugins/qmldesigner/libs/designercore/exceptions/invalidmodelstateexception.cpp diff --git a/src/plugins/qmldesigner/designercore/exceptions/invalidpropertyexception.cpp b/src/plugins/qmldesigner/libs/designercore/exceptions/invalidpropertyexception.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/exceptions/invalidpropertyexception.cpp rename to src/plugins/qmldesigner/libs/designercore/exceptions/invalidpropertyexception.cpp diff --git a/src/plugins/qmldesigner/designercore/exceptions/invalidqmlsourceexception.cpp b/src/plugins/qmldesigner/libs/designercore/exceptions/invalidqmlsourceexception.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/exceptions/invalidqmlsourceexception.cpp rename to src/plugins/qmldesigner/libs/designercore/exceptions/invalidqmlsourceexception.cpp diff --git a/src/plugins/qmldesigner/designercore/exceptions/invalidreparentingexception.cpp b/src/plugins/qmldesigner/libs/designercore/exceptions/invalidreparentingexception.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/exceptions/invalidreparentingexception.cpp rename to src/plugins/qmldesigner/libs/designercore/exceptions/invalidreparentingexception.cpp diff --git a/src/plugins/qmldesigner/designercore/exceptions/invalidslideindexexception.cpp b/src/plugins/qmldesigner/libs/designercore/exceptions/invalidslideindexexception.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/exceptions/invalidslideindexexception.cpp rename to src/plugins/qmldesigner/libs/designercore/exceptions/invalidslideindexexception.cpp diff --git a/src/plugins/qmldesigner/designercore/exceptions/notimplementedexception.cpp b/src/plugins/qmldesigner/libs/designercore/exceptions/notimplementedexception.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/exceptions/notimplementedexception.cpp rename to src/plugins/qmldesigner/libs/designercore/exceptions/notimplementedexception.cpp diff --git a/src/plugins/qmldesigner/designercore/exceptions/removebasestateexception.cpp b/src/plugins/qmldesigner/libs/designercore/exceptions/removebasestateexception.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/exceptions/removebasestateexception.cpp rename to src/plugins/qmldesigner/libs/designercore/exceptions/removebasestateexception.cpp diff --git a/src/plugins/qmldesigner/designercore/exceptions/rewritingexception.cpp b/src/plugins/qmldesigner/libs/designercore/exceptions/rewritingexception.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/exceptions/rewritingexception.cpp rename to src/plugins/qmldesigner/libs/designercore/exceptions/rewritingexception.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/addarraymembervisitor.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/addarraymembervisitor.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/addarraymembervisitor.cpp rename to src/plugins/qmldesigner/libs/designercore/filemanager/addarraymembervisitor.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/addarraymembervisitor.h b/src/plugins/qmldesigner/libs/designercore/filemanager/addarraymembervisitor.h similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/addarraymembervisitor.h rename to src/plugins/qmldesigner/libs/designercore/filemanager/addarraymembervisitor.h diff --git a/src/plugins/qmldesigner/designercore/filemanager/addobjectvisitor.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/addobjectvisitor.cpp rename to src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/addobjectvisitor.h b/src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.h similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/addobjectvisitor.h rename to src/plugins/qmldesigner/libs/designercore/filemanager/addobjectvisitor.h diff --git a/src/plugins/qmldesigner/designercore/filemanager/addpropertyvisitor.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/addpropertyvisitor.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/addpropertyvisitor.cpp rename to src/plugins/qmldesigner/libs/designercore/filemanager/addpropertyvisitor.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/addpropertyvisitor.h b/src/plugins/qmldesigner/libs/designercore/filemanager/addpropertyvisitor.h similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/addpropertyvisitor.h rename to src/plugins/qmldesigner/libs/designercore/filemanager/addpropertyvisitor.h diff --git a/src/plugins/qmldesigner/designercore/filemanager/astobjecttextextractor.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/astobjecttextextractor.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/astobjecttextextractor.cpp rename to src/plugins/qmldesigner/libs/designercore/filemanager/astobjecttextextractor.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/astobjecttextextractor.h b/src/plugins/qmldesigner/libs/designercore/filemanager/astobjecttextextractor.h similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/astobjecttextextractor.h rename to src/plugins/qmldesigner/libs/designercore/filemanager/astobjecttextextractor.h diff --git a/src/plugins/qmldesigner/designercore/filemanager/changeimportsvisitor.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/changeimportsvisitor.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/changeimportsvisitor.cpp rename to src/plugins/qmldesigner/libs/designercore/filemanager/changeimportsvisitor.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/changeimportsvisitor.h b/src/plugins/qmldesigner/libs/designercore/filemanager/changeimportsvisitor.h similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/changeimportsvisitor.h rename to src/plugins/qmldesigner/libs/designercore/filemanager/changeimportsvisitor.h diff --git a/src/plugins/qmldesigner/designercore/filemanager/changeobjecttypevisitor.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/changeobjecttypevisitor.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/changeobjecttypevisitor.cpp rename to src/plugins/qmldesigner/libs/designercore/filemanager/changeobjecttypevisitor.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/changeobjecttypevisitor.h b/src/plugins/qmldesigner/libs/designercore/filemanager/changeobjecttypevisitor.h similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/changeobjecttypevisitor.h rename to src/plugins/qmldesigner/libs/designercore/filemanager/changeobjecttypevisitor.h diff --git a/src/plugins/qmldesigner/designercore/filemanager/changepropertyvisitor.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/changepropertyvisitor.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/changepropertyvisitor.cpp rename to src/plugins/qmldesigner/libs/designercore/filemanager/changepropertyvisitor.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/changepropertyvisitor.h b/src/plugins/qmldesigner/libs/designercore/filemanager/changepropertyvisitor.h similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/changepropertyvisitor.h rename to src/plugins/qmldesigner/libs/designercore/filemanager/changepropertyvisitor.h diff --git a/src/plugins/qmldesigner/designercore/filemanager/firstdefinitionfinder.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/firstdefinitionfinder.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/firstdefinitionfinder.cpp rename to src/plugins/qmldesigner/libs/designercore/filemanager/firstdefinitionfinder.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/firstdefinitionfinder.h b/src/plugins/qmldesigner/libs/designercore/filemanager/firstdefinitionfinder.h similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/firstdefinitionfinder.h rename to src/plugins/qmldesigner/libs/designercore/filemanager/firstdefinitionfinder.h diff --git a/src/plugins/qmldesigner/designercore/filemanager/moveobjectbeforeobjectvisitor.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectbeforeobjectvisitor.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/moveobjectbeforeobjectvisitor.cpp rename to src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectbeforeobjectvisitor.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/moveobjectbeforeobjectvisitor.h b/src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectbeforeobjectvisitor.h similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/moveobjectbeforeobjectvisitor.h rename to src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectbeforeobjectvisitor.h diff --git a/src/plugins/qmldesigner/designercore/filemanager/moveobjectvisitor.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectvisitor.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/moveobjectvisitor.cpp rename to src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectvisitor.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/moveobjectvisitor.h b/src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectvisitor.h similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/moveobjectvisitor.h rename to src/plugins/qmldesigner/libs/designercore/filemanager/moveobjectvisitor.h diff --git a/src/plugins/qmldesigner/designercore/filemanager/objectlengthcalculator.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/objectlengthcalculator.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/objectlengthcalculator.cpp rename to src/plugins/qmldesigner/libs/designercore/filemanager/objectlengthcalculator.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/objectlengthcalculator.h b/src/plugins/qmldesigner/libs/designercore/filemanager/objectlengthcalculator.h similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/objectlengthcalculator.h rename to src/plugins/qmldesigner/libs/designercore/filemanager/objectlengthcalculator.h diff --git a/src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.cpp rename to src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.h b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.h similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/qmlrefactoring.h rename to src/plugins/qmldesigner/libs/designercore/filemanager/qmlrefactoring.h diff --git a/src/plugins/qmldesigner/designercore/filemanager/qmlrewriter.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/qmlrewriter.cpp rename to src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/qmlrewriter.h b/src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.h similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/qmlrewriter.h rename to src/plugins/qmldesigner/libs/designercore/filemanager/qmlrewriter.h diff --git a/src/plugins/qmldesigner/designercore/filemanager/removepropertyvisitor.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/removepropertyvisitor.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/removepropertyvisitor.cpp rename to src/plugins/qmldesigner/libs/designercore/filemanager/removepropertyvisitor.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/removepropertyvisitor.h b/src/plugins/qmldesigner/libs/designercore/filemanager/removepropertyvisitor.h similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/removepropertyvisitor.h rename to src/plugins/qmldesigner/libs/designercore/filemanager/removepropertyvisitor.h diff --git a/src/plugins/qmldesigner/designercore/filemanager/removeuiobjectmembervisitor.cpp b/src/plugins/qmldesigner/libs/designercore/filemanager/removeuiobjectmembervisitor.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/removeuiobjectmembervisitor.cpp rename to src/plugins/qmldesigner/libs/designercore/filemanager/removeuiobjectmembervisitor.cpp diff --git a/src/plugins/qmldesigner/designercore/filemanager/removeuiobjectmembervisitor.h b/src/plugins/qmldesigner/libs/designercore/filemanager/removeuiobjectmembervisitor.h similarity index 100% rename from src/plugins/qmldesigner/designercore/filemanager/removeuiobjectmembervisitor.h rename to src/plugins/qmldesigner/libs/designercore/filemanager/removeuiobjectmembervisitor.h diff --git a/src/plugins/qmldesigner/designercore/imagecache/asynchronousexplicitimagecache.cpp b/src/plugins/qmldesigner/libs/designercore/imagecache/asynchronousexplicitimagecache.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/asynchronousexplicitimagecache.cpp rename to src/plugins/qmldesigner/libs/designercore/imagecache/asynchronousexplicitimagecache.cpp diff --git a/src/plugins/qmldesigner/designercore/imagecache/asynchronousimagecache.cpp b/src/plugins/qmldesigner/libs/designercore/imagecache/asynchronousimagecache.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/asynchronousimagecache.cpp rename to src/plugins/qmldesigner/libs/designercore/imagecache/asynchronousimagecache.cpp diff --git a/src/plugins/qmldesigner/designercore/imagecache/asynchronousimagefactory.cpp b/src/plugins/qmldesigner/libs/designercore/imagecache/asynchronousimagefactory.cpp similarity index 98% rename from src/plugins/qmldesigner/designercore/imagecache/asynchronousimagefactory.cpp rename to src/plugins/qmldesigner/libs/designercore/imagecache/asynchronousimagefactory.cpp index 6feaea8150d..83fd238f1db 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/asynchronousimagefactory.cpp +++ b/src/plugins/qmldesigner/libs/designercore/imagecache/asynchronousimagefactory.cpp @@ -3,7 +3,7 @@ #include "asynchronousimagefactory.h" -#include "imagecachecollector.h" +#include "imagecachecollectorinterface.h" #include "imagecachegenerator.h" #include "imagecachestorage.h" #include "timestampproviderinterface.h" diff --git a/src/plugins/qmldesigner/designercore/imagecache/asynchronousimagefactory.h b/src/plugins/qmldesigner/libs/designercore/imagecache/asynchronousimagefactory.h similarity index 96% rename from src/plugins/qmldesigner/designercore/imagecache/asynchronousimagefactory.h rename to src/plugins/qmldesigner/libs/designercore/imagecache/asynchronousimagefactory.h index bfd76a5ccac..1b9d62884d2 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/asynchronousimagefactory.h +++ b/src/plugins/qmldesigner/libs/designercore/imagecache/asynchronousimagefactory.h @@ -6,6 +6,7 @@ #include "imagecacheauxiliarydata.h" #include +#include #include @@ -21,7 +22,7 @@ class TimeStampProviderInterface; class ImageCacheStorageInterface; class ImageCacheCollectorInterface; -class AsynchronousImageFactory +class QMLDESIGNERCORE_EXPORT AsynchronousImageFactory { public: AsynchronousImageFactory(ImageCacheStorageInterface &storage, diff --git a/src/plugins/qmldesigner/designercore/imagecache/explicitimagecacheimageprovider.cpp b/src/plugins/qmldesigner/libs/designercore/imagecache/explicitimagecacheimageprovider.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/explicitimagecacheimageprovider.cpp rename to src/plugins/qmldesigner/libs/designercore/imagecache/explicitimagecacheimageprovider.cpp diff --git a/src/plugins/qmldesigner/designercore/imagecache/explicitimagecacheimageprovider.h b/src/plugins/qmldesigner/libs/designercore/imagecache/explicitimagecacheimageprovider.h similarity index 86% rename from src/plugins/qmldesigner/designercore/imagecache/explicitimagecacheimageprovider.h rename to src/plugins/qmldesigner/libs/designercore/imagecache/explicitimagecacheimageprovider.h index bef22d68a7e..cd551cf2a21 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/explicitimagecacheimageprovider.h +++ b/src/plugins/qmldesigner/libs/designercore/imagecache/explicitimagecacheimageprovider.h @@ -3,6 +3,8 @@ #pragma once +#include + #include #include @@ -10,7 +12,7 @@ namespace QmlDesigner { class AsynchronousExplicitImageCache; -class ExplicitImageCacheImageProvider : public QQuickAsyncImageProvider +class QMLDESIGNERCORE_EXPORT ExplicitImageCacheImageProvider : public QQuickAsyncImageProvider { public: ExplicitImageCacheImageProvider(AsynchronousExplicitImageCache &imageCache, diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachecollectorinterface.h b/src/plugins/qmldesigner/libs/designercore/imagecache/imagecachecollectorinterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/imagecachecollectorinterface.h rename to src/plugins/qmldesigner/libs/designercore/imagecache/imagecachecollectorinterface.h diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachedispatchcollector.h b/src/plugins/qmldesigner/libs/designercore/imagecache/imagecachedispatchcollector.h similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/imagecachedispatchcollector.h rename to src/plugins/qmldesigner/libs/designercore/imagecache/imagecachedispatchcollector.h diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.cpp b/src/plugins/qmldesigner/libs/designercore/imagecache/imagecachegenerator.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.cpp rename to src/plugins/qmldesigner/libs/designercore/imagecache/imagecachegenerator.cpp diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.h b/src/plugins/qmldesigner/libs/designercore/imagecache/imagecachegenerator.h similarity index 95% rename from src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.h rename to src/plugins/qmldesigner/libs/designercore/imagecache/imagecachegenerator.h index 1846eff557c..14d15fe137c 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/imagecachegenerator.h +++ b/src/plugins/qmldesigner/libs/designercore/imagecache/imagecachegenerator.h @@ -6,6 +6,7 @@ #include "imagecachegeneratorinterface.h" #include +#include #include #include @@ -23,7 +24,7 @@ namespace QmlDesigner { class ImageCacheCollectorInterface; class ImageCacheStorageInterface; -class ImageCacheGenerator final : public ImageCacheGeneratorInterface +class QMLDESIGNERCORE_EXPORT ImageCacheGenerator final : public ImageCacheGeneratorInterface { public: ImageCacheGenerator(ImageCacheCollectorInterface &collector, ImageCacheStorageInterface &storage); diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachegeneratorinterface.h b/src/plugins/qmldesigner/libs/designercore/imagecache/imagecachegeneratorinterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/imagecachegeneratorinterface.h rename to src/plugins/qmldesigner/libs/designercore/imagecache/imagecachegeneratorinterface.h diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecacheimageresponse.cpp b/src/plugins/qmldesigner/libs/designercore/imagecache/imagecacheimageresponse.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/imagecacheimageresponse.cpp rename to src/plugins/qmldesigner/libs/designercore/imagecache/imagecacheimageresponse.cpp diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecacheimageresponse.h b/src/plugins/qmldesigner/libs/designercore/imagecache/imagecacheimageresponse.h similarity index 82% rename from src/plugins/qmldesigner/designercore/imagecache/imagecacheimageresponse.h rename to src/plugins/qmldesigner/libs/designercore/imagecache/imagecacheimageresponse.h index 1a4400e9893..3bfb3cebfc0 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/imagecacheimageresponse.h +++ b/src/plugins/qmldesigner/libs/designercore/imagecache/imagecacheimageresponse.h @@ -3,13 +3,15 @@ #pragma once +#include + #include namespace QmlDesigner { class AsynchronousImageCache; -class ImageCacheImageResponse : public QQuickImageResponse +class QMLDESIGNERCORE_EXPORT ImageCacheImageResponse : public QQuickImageResponse { public: ImageCacheImageResponse(const QImage &defaultImage = {}) diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachestorage.h b/src/plugins/qmldesigner/libs/designercore/imagecache/imagecachestorage.h similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/imagecachestorage.h rename to src/plugins/qmldesigner/libs/designercore/imagecache/imagecachestorage.h diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachestorageinterface.h b/src/plugins/qmldesigner/libs/designercore/imagecache/imagecachestorageinterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/imagecachestorageinterface.h rename to src/plugins/qmldesigner/libs/designercore/imagecache/imagecachestorageinterface.h diff --git a/src/plugins/qmldesigner/designercore/imagecache/midsizeimagecacheprovider.cpp b/src/plugins/qmldesigner/libs/designercore/imagecache/midsizeimagecacheprovider.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/midsizeimagecacheprovider.cpp rename to src/plugins/qmldesigner/libs/designercore/imagecache/midsizeimagecacheprovider.cpp diff --git a/src/plugins/qmldesigner/designercore/imagecache/midsizeimagecacheprovider.h b/src/plugins/qmldesigner/libs/designercore/imagecache/midsizeimagecacheprovider.h similarity index 84% rename from src/plugins/qmldesigner/designercore/imagecache/midsizeimagecacheprovider.h rename to src/plugins/qmldesigner/libs/designercore/imagecache/midsizeimagecacheprovider.h index b3a84f0abd2..e49e2a2aceb 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/midsizeimagecacheprovider.h +++ b/src/plugins/qmldesigner/libs/designercore/imagecache/midsizeimagecacheprovider.h @@ -3,13 +3,15 @@ #pragma once +#include + #include namespace QmlDesigner { class AsynchronousImageCache; -class MidSizeImageCacheProvider : public QQuickAsyncImageProvider +class QMLDESIGNERCORE_EXPORT MidSizeImageCacheProvider : public QQuickAsyncImageProvider { public: MidSizeImageCacheProvider(AsynchronousImageCache &imageCache, const QImage &defaultImage = {}) diff --git a/src/plugins/qmldesigner/designercore/imagecache/smallimagecacheprovider.cpp b/src/plugins/qmldesigner/libs/designercore/imagecache/smallimagecacheprovider.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/smallimagecacheprovider.cpp rename to src/plugins/qmldesigner/libs/designercore/imagecache/smallimagecacheprovider.cpp diff --git a/src/plugins/qmldesigner/designercore/imagecache/smallimagecacheprovider.h b/src/plugins/qmldesigner/libs/designercore/imagecache/smallimagecacheprovider.h similarity index 85% rename from src/plugins/qmldesigner/designercore/imagecache/smallimagecacheprovider.h rename to src/plugins/qmldesigner/libs/designercore/imagecache/smallimagecacheprovider.h index 40b542ebe41..283defbaed8 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/smallimagecacheprovider.h +++ b/src/plugins/qmldesigner/libs/designercore/imagecache/smallimagecacheprovider.h @@ -3,13 +3,15 @@ #pragma once +#include + #include namespace QmlDesigner { class AsynchronousImageCache; -class SmallImageCacheProvider : public QQuickAsyncImageProvider +class QMLDESIGNERCORE_EXPORT SmallImageCacheProvider : public QQuickAsyncImageProvider { public: SmallImageCacheProvider(AsynchronousImageCache &imageCache, const QImage &defaultImage = {}) diff --git a/src/plugins/qmldesigner/designercore/imagecache/synchronousimagecache.cpp b/src/plugins/qmldesigner/libs/designercore/imagecache/synchronousimagecache.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/synchronousimagecache.cpp rename to src/plugins/qmldesigner/libs/designercore/imagecache/synchronousimagecache.cpp diff --git a/src/plugins/qmldesigner/designercore/imagecache/taskqueue.h b/src/plugins/qmldesigner/libs/designercore/imagecache/taskqueue.h similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/taskqueue.h rename to src/plugins/qmldesigner/libs/designercore/imagecache/taskqueue.h diff --git a/src/plugins/qmldesigner/designercore/imagecache/timestampprovider.cpp b/src/plugins/qmldesigner/libs/designercore/imagecache/timestampprovider.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/timestampprovider.cpp rename to src/plugins/qmldesigner/libs/designercore/imagecache/timestampprovider.cpp diff --git a/src/plugins/qmldesigner/designercore/imagecache/timestampprovider.h b/src/plugins/qmldesigner/libs/designercore/imagecache/timestampprovider.h similarity index 76% rename from src/plugins/qmldesigner/designercore/imagecache/timestampprovider.h rename to src/plugins/qmldesigner/libs/designercore/imagecache/timestampprovider.h index 96d1ae165f2..8c1353a3f1e 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/timestampprovider.h +++ b/src/plugins/qmldesigner/libs/designercore/imagecache/timestampprovider.h @@ -5,9 +5,11 @@ #include "timestampproviderinterface.h" +#include + namespace QmlDesigner { -class TimeStampProvider : public TimeStampProviderInterface +class QMLDESIGNERCORE_EXPORT TimeStampProvider : public TimeStampProviderInterface { public: Sqlite::TimeStamp timeStamp(Utils::SmallStringView name) const override; diff --git a/src/plugins/qmldesigner/designercore/imagecache/timestampproviderinterface.h b/src/plugins/qmldesigner/libs/designercore/imagecache/timestampproviderinterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/imagecache/timestampproviderinterface.h rename to src/plugins/qmldesigner/libs/designercore/imagecache/timestampproviderinterface.h diff --git a/src/plugins/qmldesigner/designercore/include/abstractproperty.h b/src/plugins/qmldesigner/libs/designercore/include/abstractproperty.h similarity index 98% rename from src/plugins/qmldesigner/designercore/include/abstractproperty.h rename to src/plugins/qmldesigner/libs/designercore/include/abstractproperty.h index 67a8b0084ee..a94cd3a635f 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractproperty.h +++ b/src/plugins/qmldesigner/libs/designercore/include/abstractproperty.h @@ -35,7 +35,6 @@ class QMLDESIGNERCORE_EXPORT BindingProperty; class QMLDESIGNERCORE_EXPORT NodeProperty; class QMLDESIGNERCORE_EXPORT SignalHandlerProperty; class QMLDESIGNERCORE_EXPORT SignalDeclarationProperty; -class QmlObjectNode; namespace Internal { @@ -67,7 +66,6 @@ public: explicit operator bool() const { return isValid(); } bool exists() const; ModelNode parentModelNode() const; - QmlObjectNode parentQmlObjectNode() const; bool isDefaultProperty() const; VariantProperty toVariantProperty() const; diff --git a/src/plugins/qmldesigner/designercore/include/abstractview.h b/src/plugins/qmldesigner/libs/designercore/include/abstractview.h similarity index 84% rename from src/plugins/qmldesigner/designercore/include/abstractview.h rename to src/plugins/qmldesigner/libs/designercore/include/abstractview.h index f1046bfd55b..c621b9d3bac 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/libs/designercore/include/abstractview.h @@ -83,9 +83,9 @@ public: Q_FLAGS(PropertyChangeFlag PropertyChangeFlags) enum PropertyChangeFlag { - NoAdditionalChanges = 0x0, - PropertiesAdded = 0x1, - EmptyPropertiesRemoved = 0x2 + NoAdditionalChanges = 0x0, + PropertiesAdded = 0x1, + EmptyPropertiesRemoved = 0x2 }; Q_DECLARE_FLAGS(PropertyChangeFlags, PropertyChangeFlag) @@ -99,6 +99,10 @@ public: Model *model() const { return m_model.data(); } bool isAttached() const; + enum class Kind { Other, Rewriter, NodeInstance }; + + Kind kind() const { return m_kind; } + RewriterTransaction beginRewriterTransaction(const QByteArray &identifier); ModelNode createModelNode(const TypeName &typeName); @@ -147,30 +151,6 @@ public: QList allModelNodesUnordered() const; QList allModelNodesOfType(const NodeMetaInfo &typeName) const; - void emitDocumentMessage(const QList &errors, const QList &warnings = {}); - void emitDocumentMessage(const QString &error); - void emitCustomNotification(const QString &identifier, const QList &nodeList = {}, - const QList &data = {}); - - void emitInstancePropertyChange(const QList > &propertyList); - void emitInstanceErrorChange(const QVector &instanceIds); - void emitInstancesCompleted(const QVector &nodeList); - void emitInstanceInformationsChange(const QMultiHash &informationChangeHash); - void emitInstancesRenderImageChanged(const QVector &nodeList); - void emitInstancesPreviewImageChanged(const QVector &nodeList); - void emitInstancesChildrenChanged(const QVector &nodeList); - void emitRewriterBeginTransaction(); - void emitRewriterEndTransaction(); - void emitInstanceToken(const QString &token, int number, const QVector &nodeVector); - void emitRenderImage3DChanged(const QImage &image); - void emitUpdateActiveScene3D(const QVariantMap &sceneState); - void emitModelNodelPreviewPixmapChanged(const ModelNode &node, - const QPixmap &pixmap, - const QByteArray &requestId); - void emitImport3DSupportChanged(const QVariantMap &supportMap); - void emitNodeAtPosResult(const ModelNode &modelNode, const QVector3D &pos3d); - void emitView3DAction(View3DActionType type, const QVariant &value); - virtual void modelAttached(Model *model); virtual void modelAboutToBeDetached(Model *model); @@ -233,7 +213,12 @@ public: AuxiliaryDataKeyView type, const QVariant &data); - virtual void customNotification(const AbstractView *view, const QString &identifier, const QList &nodeList, const QList &data); + virtual void customNotification(const AbstractView *view, + const QString &identifier, + const QList &nodeList, + const QList &data); + + virtual void customNotification(const CustomNotificationPackage &); virtual void scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList); @@ -256,13 +241,20 @@ public: void changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion); - const NodeInstanceView *nodeInstanceView() const; + void emitCustomNotification(const QString &identifier, + const QList &nodeList = {}, + const QList &data = {}) + { + if (isAttached()) + model()->emitCustomNotification(this, identifier, nodeList, data); + } + + const AbstractView *nodeInstanceView() const; RewriterView *rewriterView() const; void setCurrentStateNode(const ModelNode &node); ModelNode currentStateNode() const; - QmlModelState currentState() const; - QmlTimeline currentTimeline() const; + ModelNode currentTimelineNode() const; int majorQtQuickVersion() const; int minorQtQuickVersion() const; @@ -277,10 +269,6 @@ public: QString contextHelpId() const; - void setCurrentTimeline(const ModelNode &timeline); - void activateTimelineRecording(const ModelNode &timeline); - void deactivateTimelineRecording(); - using OperationBlock = std::function; bool executeInTransaction(const QByteArray &identifier, const OperationBlock &lambda); @@ -327,6 +315,8 @@ protected: const QString &feedbackDisplayName = QString(), DesignerWidgetFlags widgetFlags = DesignerWidgetFlags::DisableOnError); + void setKind(Kind kind) { m_kind = kind; } + private: QList toModelNodeList(Utils::span nodeList) const; @@ -335,6 +325,7 @@ private: Utils::UniqueObjectPtr m_action; bool m_visible = true; bool m_isBlockingNotifications = false; + Kind m_kind = Kind::Other; }; QMLDESIGNERCORE_EXPORT QList toInternalNodeList(const QList &nodeList); diff --git a/src/plugins/qmldesigner/designercore/include/annotation.h b/src/plugins/qmldesigner/libs/designercore/include/annotation.h similarity index 90% rename from src/plugins/qmldesigner/designercore/include/annotation.h rename to src/plugins/qmldesigner/libs/designercore/include/annotation.h index 647c1dafda1..1fccd2ada07 100644 --- a/src/plugins/qmldesigner/designercore/include/annotation.h +++ b/src/plugins/qmldesigner/libs/designercore/include/annotation.h @@ -72,7 +72,7 @@ public: QJsonValue toJsonValue() const; bool fromJsonValue(QJsonValue const &); - friend QDebug &operator<<(QDebug &stream, const Comment &comment); + QMLDESIGNERCORE_EXPORT friend QDebug &operator<<(QDebug &stream, const Comment &comment); QMLDESIGNERCORE_EXPORT friend QDataStream &operator<<(QDataStream &stream, const Comment &comment); @@ -108,7 +108,7 @@ public: QJsonValue toJsonValue() const; bool fromJsonValue(QJsonValue const &); - friend QDebug &operator<<(QDebug &stream, const Annotation &annotation); + QMLDESIGNERCORE_EXPORT friend QDebug &operator<<(QDebug &stream, const Annotation &annotation); QMLDESIGNERCORE_EXPORT friend QDataStream &operator<<(QDataStream &stream, const Annotation &annotation); @@ -119,8 +119,8 @@ private: QVector m_comments; }; -QDebug &operator<<(QDebug &stream, const Comment &comment); -QDebug &operator<<(QDebug &stream, const Annotation &annotation); +QMLDESIGNERCORE_EXPORT QDebug &operator<<(QDebug &stream, const Comment &comment); +QMLDESIGNERCORE_EXPORT QDebug &operator<<(QDebug &stream, const Annotation &annotation); QMLDESIGNERCORE_EXPORT QDataStream &operator<<(QDataStream &stream, const Comment &comment); QMLDESIGNERCORE_EXPORT QDataStream &operator>>(QDataStream &stream, Comment &comment); diff --git a/src/plugins/qmldesigner/designercore/include/asynchronousexplicitimagecache.h b/src/plugins/qmldesigner/libs/designercore/include/asynchronousexplicitimagecache.h similarity index 97% rename from src/plugins/qmldesigner/designercore/include/asynchronousexplicitimagecache.h rename to src/plugins/qmldesigner/libs/designercore/include/asynchronousexplicitimagecache.h index 72d4746944e..35d6495abce 100644 --- a/src/plugins/qmldesigner/designercore/include/asynchronousexplicitimagecache.h +++ b/src/plugins/qmldesigner/libs/designercore/include/asynchronousexplicitimagecache.h @@ -6,6 +6,7 @@ #include "asynchronousimagecacheinterface.h" #include +#include #include #include @@ -18,7 +19,7 @@ namespace QmlDesigner { class ImageCacheStorageInterface; -class AsynchronousExplicitImageCache +class QMLDESIGNERCORE_EXPORT AsynchronousExplicitImageCache { public: ~AsynchronousExplicitImageCache(); diff --git a/src/plugins/qmldesigner/designercore/include/asynchronousimagecache.h b/src/plugins/qmldesigner/libs/designercore/include/asynchronousimagecache.h similarity index 96% rename from src/plugins/qmldesigner/designercore/include/asynchronousimagecache.h rename to src/plugins/qmldesigner/libs/designercore/include/asynchronousimagecache.h index c3fc7bcd153..a5e64c2b21d 100644 --- a/src/plugins/qmldesigner/designercore/include/asynchronousimagecache.h +++ b/src/plugins/qmldesigner/libs/designercore/include/asynchronousimagecache.h @@ -8,6 +8,7 @@ #include "asynchronousimagecacheinterface.h" #include +#include #include #include @@ -23,7 +24,7 @@ class ImageCacheStorageInterface; class ImageCacheGeneratorInterface; class ImageCacheCollectorInterface; -class AsynchronousImageCache final : public AsynchronousImageCacheInterface +class QMLDESIGNERCORE_EXPORT AsynchronousImageCache final : public AsynchronousImageCacheInterface { public: ~AsynchronousImageCache(); diff --git a/src/plugins/qmldesigner/designercore/include/asynchronousimagecacheinterface.h b/src/plugins/qmldesigner/libs/designercore/include/asynchronousimagecacheinterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/asynchronousimagecacheinterface.h rename to src/plugins/qmldesigner/libs/designercore/include/asynchronousimagecacheinterface.h diff --git a/src/plugins/qmldesigner/designercore/include/auxiliarydata.h b/src/plugins/qmldesigner/libs/designercore/include/auxiliarydata.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/auxiliarydata.h rename to src/plugins/qmldesigner/libs/designercore/include/auxiliarydata.h diff --git a/src/plugins/qmldesigner/designercore/include/auxiliarydataproperties.h b/src/plugins/qmldesigner/libs/designercore/include/auxiliarydataproperties.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/auxiliarydataproperties.h rename to src/plugins/qmldesigner/libs/designercore/include/auxiliarydataproperties.h diff --git a/src/plugins/qmldesigner/designercore/include/bindingproperty.h b/src/plugins/qmldesigner/libs/designercore/include/bindingproperty.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/bindingproperty.h rename to src/plugins/qmldesigner/libs/designercore/include/bindingproperty.h diff --git a/src/plugins/qmldesigner/designercore/include/bytearraymodifier.h b/src/plugins/qmldesigner/libs/designercore/include/bytearraymodifier.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/bytearraymodifier.h rename to src/plugins/qmldesigner/libs/designercore/include/bytearraymodifier.h diff --git a/src/plugins/qmldesigner/designercore/include/componenttextmodifier.h b/src/plugins/qmldesigner/libs/designercore/include/componenttextmodifier.h similarity index 95% rename from src/plugins/qmldesigner/designercore/include/componenttextmodifier.h rename to src/plugins/qmldesigner/libs/designercore/include/componenttextmodifier.h index a65e934c46a..6046ac65cea 100644 --- a/src/plugins/qmldesigner/designercore/include/componenttextmodifier.h +++ b/src/plugins/qmldesigner/libs/designercore/include/componenttextmodifier.h @@ -7,7 +7,7 @@ namespace QmlDesigner { -class ComponentTextModifier: public TextModifier +class QMLDESIGNERCORE_EXPORT ComponentTextModifier : public TextModifier { Q_OBJECT public: diff --git a/src/plugins/qmldesigner/libs/designercore/include/customnotificationpackage.h b/src/plugins/qmldesigner/libs/designercore/include/customnotificationpackage.h new file mode 100644 index 00000000000..07782f8014a --- /dev/null +++ b/src/plugins/qmldesigner/libs/designercore/include/customnotificationpackage.h @@ -0,0 +1,23 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include +#include + +namespace QmlDesigner { + +struct InputEvent +{ + QEvent *event; +}; + +struct Resize3DCanvas +{ + QSize size; +}; + +using CustomNotificationPackage = std::variant; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/customnotifications.h b/src/plugins/qmldesigner/libs/designercore/include/customnotifications.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/customnotifications.h rename to src/plugins/qmldesigner/libs/designercore/include/customnotifications.h diff --git a/src/plugins/qmldesigner/designercore/include/documentmessage.h b/src/plugins/qmldesigner/libs/designercore/include/documentmessage.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/documentmessage.h rename to src/plugins/qmldesigner/libs/designercore/include/documentmessage.h diff --git a/src/plugins/qmldesigner/designercore/include/enumerationmetainfo.h b/src/plugins/qmldesigner/libs/designercore/include/enumerationmetainfo.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/enumerationmetainfo.h rename to src/plugins/qmldesigner/libs/designercore/include/enumerationmetainfo.h diff --git a/src/plugins/qmldesigner/designercore/include/exception.h b/src/plugins/qmldesigner/libs/designercore/include/exception.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/exception.h rename to src/plugins/qmldesigner/libs/designercore/include/exception.h diff --git a/src/plugins/qmldesigner/designercore/include/externaldependenciesinterface.h b/src/plugins/qmldesigner/libs/designercore/include/externaldependenciesinterface.h similarity index 96% rename from src/plugins/qmldesigner/designercore/include/externaldependenciesinterface.h rename to src/plugins/qmldesigner/libs/designercore/include/externaldependenciesinterface.h index 3adaeb40514..0d9ac2eaeed 100644 --- a/src/plugins/qmldesigner/designercore/include/externaldependenciesinterface.h +++ b/src/plugins/qmldesigner/libs/designercore/include/externaldependenciesinterface.h @@ -3,7 +3,7 @@ #pragma once -#include +#include #include #include @@ -49,6 +49,7 @@ public: virtual QString qtQuickVersion() const = 0; virtual Utils::FilePath resourcePath(const QString &relativePath) const = 0; virtual QString userResourcePath(QStringView relativePath) const = 0; + virtual QWidget *mainWindow() const = 0; protected: ~ExternalDependenciesInterface() = default; diff --git a/src/plugins/qmldesigner/designercore/include/filesystemfacadeinterface.h b/src/plugins/qmldesigner/libs/designercore/include/filesystemfacadeinterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/filesystemfacadeinterface.h rename to src/plugins/qmldesigner/libs/designercore/include/filesystemfacadeinterface.h diff --git a/src/plugins/qmldesigner/designercore/include/forwardview.h b/src/plugins/qmldesigner/libs/designercore/include/forwardview.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/forwardview.h rename to src/plugins/qmldesigner/libs/designercore/include/forwardview.h diff --git a/src/plugins/qmldesigner/designercore/include/imagecacheauxiliarydata.h b/src/plugins/qmldesigner/libs/designercore/include/imagecacheauxiliarydata.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/imagecacheauxiliarydata.h rename to src/plugins/qmldesigner/libs/designercore/include/imagecacheauxiliarydata.h diff --git a/src/plugins/qmldesigner/designercore/include/import.h b/src/plugins/qmldesigner/libs/designercore/include/import.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/import.h rename to src/plugins/qmldesigner/libs/designercore/include/import.h diff --git a/src/plugins/qmldesigner/designercore/include/invalidargumentexception.h b/src/plugins/qmldesigner/libs/designercore/include/invalidargumentexception.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/invalidargumentexception.h rename to src/plugins/qmldesigner/libs/designercore/include/invalidargumentexception.h diff --git a/src/plugins/qmldesigner/designercore/include/invalididexception.h b/src/plugins/qmldesigner/libs/designercore/include/invalididexception.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/invalididexception.h rename to src/plugins/qmldesigner/libs/designercore/include/invalididexception.h diff --git a/src/plugins/qmldesigner/designercore/include/invalidmetainfoexception.h b/src/plugins/qmldesigner/libs/designercore/include/invalidmetainfoexception.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/invalidmetainfoexception.h rename to src/plugins/qmldesigner/libs/designercore/include/invalidmetainfoexception.h diff --git a/src/plugins/qmldesigner/designercore/include/invalidmodelnodeexception.h b/src/plugins/qmldesigner/libs/designercore/include/invalidmodelnodeexception.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/invalidmodelnodeexception.h rename to src/plugins/qmldesigner/libs/designercore/include/invalidmodelnodeexception.h diff --git a/src/plugins/qmldesigner/designercore/include/invalidmodelstateexception.h b/src/plugins/qmldesigner/libs/designercore/include/invalidmodelstateexception.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/invalidmodelstateexception.h rename to src/plugins/qmldesigner/libs/designercore/include/invalidmodelstateexception.h diff --git a/src/plugins/qmldesigner/designercore/include/invalidpropertyexception.h b/src/plugins/qmldesigner/libs/designercore/include/invalidpropertyexception.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/invalidpropertyexception.h rename to src/plugins/qmldesigner/libs/designercore/include/invalidpropertyexception.h diff --git a/src/plugins/qmldesigner/designercore/include/invalidqmlsourceexception.h b/src/plugins/qmldesigner/libs/designercore/include/invalidqmlsourceexception.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/invalidqmlsourceexception.h rename to src/plugins/qmldesigner/libs/designercore/include/invalidqmlsourceexception.h diff --git a/src/plugins/qmldesigner/designercore/include/invalidreparentingexception.h b/src/plugins/qmldesigner/libs/designercore/include/invalidreparentingexception.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/invalidreparentingexception.h rename to src/plugins/qmldesigner/libs/designercore/include/invalidreparentingexception.h diff --git a/src/plugins/qmldesigner/designercore/include/invalidslideindexexception.h b/src/plugins/qmldesigner/libs/designercore/include/invalidslideindexexception.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/invalidslideindexexception.h rename to src/plugins/qmldesigner/libs/designercore/include/invalidslideindexexception.h diff --git a/src/plugins/qmldesigner/designercore/include/itemlibraryentry.h b/src/plugins/qmldesigner/libs/designercore/include/itemlibraryentry.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/itemlibraryentry.h rename to src/plugins/qmldesigner/libs/designercore/include/itemlibraryentry.h diff --git a/src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h b/src/plugins/qmldesigner/libs/designercore/include/itemlibraryinfo.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/itemlibraryinfo.h rename to src/plugins/qmldesigner/libs/designercore/include/itemlibraryinfo.h diff --git a/src/plugins/qmldesigner/designercore/include/iwidgetplugin.h b/src/plugins/qmldesigner/libs/designercore/include/iwidgetplugin.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/iwidgetplugin.h rename to src/plugins/qmldesigner/libs/designercore/include/iwidgetplugin.h diff --git a/src/plugins/qmldesigner/designercore/include/mathutils.h b/src/plugins/qmldesigner/libs/designercore/include/mathutils.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/mathutils.h rename to src/plugins/qmldesigner/libs/designercore/include/mathutils.h diff --git a/src/plugins/qmldesigner/designercore/include/metainfo.h b/src/plugins/qmldesigner/libs/designercore/include/metainfo.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/metainfo.h rename to src/plugins/qmldesigner/libs/designercore/include/metainfo.h diff --git a/src/plugins/qmldesigner/designercore/include/metainforeader.h b/src/plugins/qmldesigner/libs/designercore/include/metainforeader.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/metainforeader.h rename to src/plugins/qmldesigner/libs/designercore/include/metainforeader.h diff --git a/src/plugins/qmldesigner/designercore/include/model.h b/src/plugins/qmldesigner/libs/designercore/include/model.h similarity index 79% rename from src/plugins/qmldesigner/designercore/include/model.h rename to src/plugins/qmldesigner/libs/designercore/include/model.h index 3f3cf3a1cda..13754e56d10 100644 --- a/src/plugins/qmldesigner/designercore/include/model.h +++ b/src/plugins/qmldesigner/libs/designercore/include/model.h @@ -5,7 +5,10 @@ #include +#include +#include #include +#include #include #include #include @@ -19,7 +22,7 @@ #include #include -#include +#include #ifdef QDS_USE_PROJECTSTORAGE # define DEPRECATED_OLD_CREATE_MODELNODE \ @@ -49,7 +52,6 @@ class MetaInfo; class NodeMetaInfo; class NodeMetaInfoPrivate; class ModelState; -class NodeAnchors; class AbstractProperty; class RewriterView; class NodeInstanceView; @@ -241,8 +243,8 @@ public: RewriterView *rewriterView() const; void setRewriterView(RewriterView *rewriterView); - const NodeInstanceView *nodeInstanceView() const; - void setNodeInstanceView(NodeInstanceView *nodeInstanceView); + const AbstractView *nodeInstanceView() const; + void setNodeInstanceView(AbstractView *nodeInstanceView); Model *metaInfoProxyModel() const; @@ -265,12 +267,49 @@ public: void setCurrentStateNode(const ModelNode &node); ModelNode currentStateNode(AbstractView *view = nullptr); - void setCurrentTimeline(const ModelNode &timeline); + void setCurrentTimelineNode(const ModelNode &timeline); NotNullPointer projectStorage() const; const PathCacheType &pathCache() const; PathCacheType &pathCache(); + void emitInstancePropertyChange(AbstractView *view, + const QList> &propertyList); + void emitInstanceErrorChange(AbstractView *view, const QVector &instanceIds); + void emitInstancesCompleted(AbstractView *view, const QVector &nodeList); + void emitInstanceInformationsChange( + AbstractView *view, const QMultiHash &informationChangeHash); + void emitInstancesRenderImageChanged(AbstractView *view, const QVector &nodeList); + void emitInstancesPreviewImageChanged(AbstractView *view, const QVector &nodeList); + void emitInstancesChildrenChanged(AbstractView *view, const QVector &nodeList); + void emitInstanceToken(AbstractView *view, + const QString &token, + int number, + const QVector &nodeVector); + void emitRenderImage3DChanged(AbstractView *view, const QImage &image); + void emitUpdateActiveScene3D(AbstractView *view, const QVariantMap &sceneState); + void emitModelNodelPreviewPixmapChanged(AbstractView *view, + const ModelNode &node, + const QPixmap &pixmap, + const QByteArray &requestId); + void emitImport3DSupportChanged(AbstractView *view, const QVariantMap &supportMap); + void emitNodeAtPosResult(AbstractView *view, const ModelNode &modelNode, const QVector3D &pos3d); + void emitView3DAction(View3DActionType type, const QVariant &value); + + void emitDocumentMessage(const QList &errors, + const QList &warnings = {}); + void emitDocumentMessage(const QString &error); + void emitCustomNotification(AbstractView *view, + const QString &identifier, + const QList &nodeList = {}, + const QList &data = {}); + + void sendCustomNotificationTo(AbstractView *to, const CustomNotificationPackage &package); + void sendCustomNotificationToNodeInstanceView(const CustomNotificationPackage &package); + + void emitRewriterBeginTransaction(); + void emitRewriterEndTransaction(); + private: template NodeMetaInfo createNodeMetaInfo() const; diff --git a/src/plugins/qmldesigner/designercore/include/modelcache.h b/src/plugins/qmldesigner/libs/designercore/include/modelcache.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/modelcache.h rename to src/plugins/qmldesigner/libs/designercore/include/modelcache.h diff --git a/src/plugins/qmldesigner/designercore/include/modelfwd.h b/src/plugins/qmldesigner/libs/designercore/include/modelfwd.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/modelfwd.h rename to src/plugins/qmldesigner/libs/designercore/include/modelfwd.h diff --git a/src/plugins/qmldesigner/designercore/include/modelnode.h b/src/plugins/qmldesigner/libs/designercore/include/modelnode.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/modelnode.h rename to src/plugins/qmldesigner/libs/designercore/include/modelnode.h diff --git a/src/plugins/qmldesigner/designercore/include/modificationgroupexception.h b/src/plugins/qmldesigner/libs/designercore/include/modificationgroupexception.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/modificationgroupexception.h rename to src/plugins/qmldesigner/libs/designercore/include/modificationgroupexception.h diff --git a/src/plugins/qmldesigner/designercore/include/modificationgrouptoken.h b/src/plugins/qmldesigner/libs/designercore/include/modificationgrouptoken.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/modificationgrouptoken.h rename to src/plugins/qmldesigner/libs/designercore/include/modificationgrouptoken.h diff --git a/src/plugins/qmldesigner/designercore/include/module.h b/src/plugins/qmldesigner/libs/designercore/include/module.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/module.h rename to src/plugins/qmldesigner/libs/designercore/include/module.h diff --git a/src/plugins/qmldesigner/designercore/include/nodeabstractproperty.h b/src/plugins/qmldesigner/libs/designercore/include/nodeabstractproperty.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/nodeabstractproperty.h rename to src/plugins/qmldesigner/libs/designercore/include/nodeabstractproperty.h diff --git a/src/plugins/qmldesigner/designercore/include/nodehints.h b/src/plugins/qmldesigner/libs/designercore/include/nodehints.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/nodehints.h rename to src/plugins/qmldesigner/libs/designercore/include/nodehints.h diff --git a/src/plugins/qmldesigner/designercore/include/nodelistproperty.h b/src/plugins/qmldesigner/libs/designercore/include/nodelistproperty.h similarity index 99% rename from src/plugins/qmldesigner/designercore/include/nodelistproperty.h rename to src/plugins/qmldesigner/libs/designercore/include/nodelistproperty.h index d056957adcb..3e6df272905 100644 --- a/src/plugins/qmldesigner/designercore/include/nodelistproperty.h +++ b/src/plugins/qmldesigner/libs/designercore/include/nodelistproperty.h @@ -174,7 +174,6 @@ public: : NodeAbstractProperty(propertyName, internalNode, model, view) {} QList toModelNodeList() const; - QList toQmlObjectNodeList() const; void slide(int, int) const; void swap(int, int) const; void reparentHere(const ModelNode &modelNode); diff --git a/src/plugins/qmldesigner/designercore/include/nodemetainfo.h b/src/plugins/qmldesigner/libs/designercore/include/nodemetainfo.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/nodemetainfo.h rename to src/plugins/qmldesigner/libs/designercore/include/nodemetainfo.h diff --git a/src/plugins/qmldesigner/designercore/include/nodeproperty.h b/src/plugins/qmldesigner/libs/designercore/include/nodeproperty.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/nodeproperty.h rename to src/plugins/qmldesigner/libs/designercore/include/nodeproperty.h diff --git a/src/plugins/qmldesigner/designercore/include/notimplementedexception.h b/src/plugins/qmldesigner/libs/designercore/include/notimplementedexception.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/notimplementedexception.h rename to src/plugins/qmldesigner/libs/designercore/include/notimplementedexception.h diff --git a/src/plugins/qmldesigner/designercore/include/objectpropertybinding.h b/src/plugins/qmldesigner/libs/designercore/include/objectpropertybinding.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/objectpropertybinding.h rename to src/plugins/qmldesigner/libs/designercore/include/objectpropertybinding.h diff --git a/src/plugins/qmldesigner/designercore/include/plaintexteditmodifier.h b/src/plugins/qmldesigner/libs/designercore/include/plaintexteditmodifier.h similarity index 90% rename from src/plugins/qmldesigner/designercore/include/plaintexteditmodifier.h rename to src/plugins/qmldesigner/libs/designercore/include/plaintexteditmodifier.h index 2c5b429c0aa..aced84b811c 100644 --- a/src/plugins/qmldesigner/designercore/include/plaintexteditmodifier.h +++ b/src/plugins/qmldesigner/libs/designercore/include/plaintexteditmodifier.h @@ -95,13 +95,4 @@ protected: TextEditor::TabSettings m_tabSettings; }; -class QMLDESIGNERCORE_EXPORT IndentingTextEditModifier : public NotIndentingTextEditModifier -{ -public: - IndentingTextEditModifier(QTextDocument *document, const QTextCursor &textCursor); - - void indent(int offset, int length) override; - void indentLines(int startLine, int endLine) override; -}; - -} +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/include/projectstorageids.h b/src/plugins/qmldesigner/libs/designercore/include/projectstorageids.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/projectstorageids.h rename to src/plugins/qmldesigner/libs/designercore/include/projectstorageids.h diff --git a/src/plugins/qmldesigner/designercore/include/propertybinding.h b/src/plugins/qmldesigner/libs/designercore/include/propertybinding.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/propertybinding.h rename to src/plugins/qmldesigner/libs/designercore/include/propertybinding.h diff --git a/src/plugins/qmldesigner/designercore/include/propertycontainer.h b/src/plugins/qmldesigner/libs/designercore/include/propertycontainer.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/propertycontainer.h rename to src/plugins/qmldesigner/libs/designercore/include/propertycontainer.h diff --git a/src/plugins/qmldesigner/designercore/include/propertymetainfo.h b/src/plugins/qmldesigner/libs/designercore/include/propertymetainfo.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/propertymetainfo.h rename to src/plugins/qmldesigner/libs/designercore/include/propertymetainfo.h diff --git a/src/plugins/qmldesigner/designercore/include/propertynode.h b/src/plugins/qmldesigner/libs/designercore/include/propertynode.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/propertynode.h rename to src/plugins/qmldesigner/libs/designercore/include/propertynode.h diff --git a/src/plugins/qmldesigner/designercore/include/propertyparser.h b/src/plugins/qmldesigner/libs/designercore/include/propertyparser.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/propertyparser.h rename to src/plugins/qmldesigner/libs/designercore/include/propertyparser.h diff --git a/src/plugins/qmldesigner/designercore/instances/puppetstartdata.h b/src/plugins/qmldesigner/libs/designercore/include/puppetstartdata.h similarity index 100% rename from src/plugins/qmldesigner/designercore/instances/puppetstartdata.h rename to src/plugins/qmldesigner/libs/designercore/include/puppetstartdata.h diff --git a/src/plugins/qmldesigner/libs/designercore/include/qmldesignercoreconstants.h b/src/plugins/qmldesigner/libs/designercore/include/qmldesignercoreconstants.h new file mode 100644 index 00000000000..1266c8a7878 --- /dev/null +++ b/src/plugins/qmldesigner/libs/designercore/include/qmldesignercoreconstants.h @@ -0,0 +1,13 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +namespace QmlDesigner::Constants { + +constexpr QLatin1String oldQuick3dAssetsFolder{"Quick3DAssets"}; +constexpr QLatin1String quick3DComponentsFolder{"QtQuick3D"}; + +} // namespace QmlDesigner::Constants diff --git a/src/plugins/qmldesigner/designercore/include/qmldesignercorelib_exports.h b/src/plugins/qmldesigner/libs/designercore/include/qmldesignercorelib_exports.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/qmldesignercorelib_exports.h rename to src/plugins/qmldesigner/libs/designercore/include/qmldesignercorelib_exports.h diff --git a/src/plugins/qmldesigner/designercore/include/qmldesignercorelib_global.h b/src/plugins/qmldesigner/libs/designercore/include/qmldesignercorelib_global.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/qmldesignercorelib_global.h rename to src/plugins/qmldesigner/libs/designercore/include/qmldesignercorelib_global.h diff --git a/src/plugins/qmldesigner/designercore/include/removebasestateexception.h b/src/plugins/qmldesigner/libs/designercore/include/removebasestateexception.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/removebasestateexception.h rename to src/plugins/qmldesigner/libs/designercore/include/removebasestateexception.h diff --git a/src/plugins/qmldesigner/designercore/include/rewritertransaction.h b/src/plugins/qmldesigner/libs/designercore/include/rewritertransaction.h similarity index 93% rename from src/plugins/qmldesigner/designercore/include/rewritertransaction.h rename to src/plugins/qmldesigner/libs/designercore/include/rewritertransaction.h index d63e7162537..12e40b2e06e 100644 --- a/src/plugins/qmldesigner/designercore/include/rewritertransaction.h +++ b/src/plugins/qmldesigner/libs/designercore/include/rewritertransaction.h @@ -26,8 +26,10 @@ public: void ignoreSemanticChecks(); -protected: - AbstractView *view(); +private: + void beginTransaction(); + void endTransaction(); + private: QPointer m_view; QByteArray m_identifier; diff --git a/src/plugins/qmldesigner/designercore/include/rewriterview.h b/src/plugins/qmldesigner/libs/designercore/include/rewriterview.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/rewriterview.h rename to src/plugins/qmldesigner/libs/designercore/include/rewriterview.h diff --git a/src/plugins/qmldesigner/designercore/include/rewritingexception.h b/src/plugins/qmldesigner/libs/designercore/include/rewritingexception.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/rewritingexception.h rename to src/plugins/qmldesigner/libs/designercore/include/rewritingexception.h diff --git a/src/plugins/qmldesigner/designercore/include/signalhandlerproperty.h b/src/plugins/qmldesigner/libs/designercore/include/signalhandlerproperty.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/signalhandlerproperty.h rename to src/plugins/qmldesigner/libs/designercore/include/signalhandlerproperty.h diff --git a/src/plugins/qmldesigner/designercore/include/sourcepathids.h b/src/plugins/qmldesigner/libs/designercore/include/sourcepathids.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/sourcepathids.h rename to src/plugins/qmldesigner/libs/designercore/include/sourcepathids.h diff --git a/src/plugins/qmldesigner/designercore/include/stringutils.h b/src/plugins/qmldesigner/libs/designercore/include/stringutils.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/stringutils.h rename to src/plugins/qmldesigner/libs/designercore/include/stringutils.h diff --git a/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h b/src/plugins/qmldesigner/libs/designercore/include/subcomponentmanager.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/subcomponentmanager.h rename to src/plugins/qmldesigner/libs/designercore/include/subcomponentmanager.h diff --git a/src/plugins/qmldesigner/designercore/include/synchronousimagecache.h b/src/plugins/qmldesigner/libs/designercore/include/synchronousimagecache.h similarity index 95% rename from src/plugins/qmldesigner/designercore/include/synchronousimagecache.h rename to src/plugins/qmldesigner/libs/designercore/include/synchronousimagecache.h index a2d7a13410b..4aaf2e56e61 100644 --- a/src/plugins/qmldesigner/designercore/include/synchronousimagecache.h +++ b/src/plugins/qmldesigner/libs/designercore/include/synchronousimagecache.h @@ -5,6 +5,7 @@ #include "imagecacheauxiliarydata.h" +#include #include #include @@ -22,7 +23,7 @@ class ImageCacheStorageInterface; class ImageCacheGeneratorInterface; class ImageCacheCollectorInterface; -class SynchronousImageCache +class QMLDESIGNERCORE_EXPORT SynchronousImageCache { public: using CaptureImageCallback = std::function; diff --git a/src/plugins/qmldesigner/designercore/include/textmodifier.h b/src/plugins/qmldesigner/libs/designercore/include/textmodifier.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/textmodifier.h rename to src/plugins/qmldesigner/libs/designercore/include/textmodifier.h diff --git a/src/plugins/qmldesigner/designercore/include/variantproperty.h b/src/plugins/qmldesigner/libs/designercore/include/variantproperty.h similarity index 100% rename from src/plugins/qmldesigner/designercore/include/variantproperty.h rename to src/plugins/qmldesigner/libs/designercore/include/variantproperty.h diff --git a/src/plugins/qmldesigner/designercore/metainfo/itemlibraryentry.cpp b/src/plugins/qmldesigner/libs/designercore/metainfo/itemlibraryentry.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/metainfo/itemlibraryentry.cpp rename to src/plugins/qmldesigner/libs/designercore/metainfo/itemlibraryentry.cpp diff --git a/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp b/src/plugins/qmldesigner/libs/designercore/metainfo/itemlibraryinfo.cpp similarity index 99% rename from src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp rename to src/plugins/qmldesigner/libs/designercore/metainfo/itemlibraryinfo.cpp index 9f8b43f9209..fc4a7b147ae 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/itemlibraryinfo.cpp +++ b/src/plugins/qmldesigner/libs/designercore/metainfo/itemlibraryinfo.cpp @@ -13,8 +13,6 @@ ItemLibraryInfo::ItemLibraryInfo(QObject *parent) { } - - QList ItemLibraryInfo::entriesForType(const QByteArray &typeName, int majorVersion, int minorVersion) const { QList entries; diff --git a/src/plugins/qmldesigner/designercore/metainfo/metainfo.cpp b/src/plugins/qmldesigner/libs/designercore/metainfo/metainfo.cpp similarity index 89% rename from src/plugins/qmldesigner/designercore/metainfo/metainfo.cpp rename to src/plugins/qmldesigner/libs/designercore/metainfo/metainfo.cpp index abecca1788a..25acf6c484e 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/metainfo.cpp +++ b/src/plugins/qmldesigner/libs/designercore/metainfo/metainfo.cpp @@ -3,16 +3,14 @@ #include "metainfo.h" -#include "modelnode.h" -#include "metainforeader.h" +#include "itemlibraryinfo.h" #include "iwidgetplugin.h" +#include "metainforeader.h" +#include "modelnode.h" #include #include -#include -#include - #include #include @@ -115,10 +113,10 @@ void MetaInfoPrivate::parseItemLibraryDescriptions(const ExternalDependenciesInt qWarning() << e.description(); const QString errorMessage = plugin->metaInfo() + QLatin1Char('\n') + QLatin1Char('\n') + reader.errors().join(QLatin1Char('\n')); - Core::AsynchronousMessageBox::warning( - QCoreApplication::translate("QmlDesigner::Internal::MetaInfoPrivate", - "Invalid meta info"), - errorMessage); + QMessageBox::warning(nullptr, + QCoreApplication::translate( + "QmlDesigner::Internal::MetaInfoPrivate", "Invalid meta info"), + errorMessage); // not nice but the code will be removed in the near future #endif } } @@ -133,10 +131,10 @@ void MetaInfoPrivate::parseItemLibraryDescriptions(const ExternalDependenciesInt qWarning() << e.description(); const QString errorMessage = path.toString() + QLatin1Char('\n') + QLatin1Char('\n') + reader.errors().join(QLatin1Char('\n')); - Core::AsynchronousMessageBox::warning( - QCoreApplication::translate("QmlDesigner::Internal::MetaInfoPrivate", - "Invalid meta info"), - errorMessage); + QMessageBox::warning(nullptr, + QCoreApplication::translate( + "QmlDesigner::Internal::MetaInfoPrivate", "Invalid meta info"), + errorMessage); // not nice but the code will be removed in the near future #endif } } diff --git a/src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp b/src/plugins/qmldesigner/libs/designercore/metainfo/metainforeader.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/metainfo/metainforeader.cpp rename to src/plugins/qmldesigner/libs/designercore/metainfo/metainforeader.cpp diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodehints.cpp b/src/plugins/qmldesigner/libs/designercore/metainfo/nodehints.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/metainfo/nodehints.cpp rename to src/plugins/qmldesigner/libs/designercore/metainfo/nodehints.cpp diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/libs/designercore/metainfo/nodemetainfo.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp rename to src/plugins/qmldesigner/libs/designercore/metainfo/nodemetainfo.cpp diff --git a/src/plugins/qmldesigner/designercore/metainfo/propertycontainer.cpp b/src/plugins/qmldesigner/libs/designercore/metainfo/propertycontainer.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/metainfo/propertycontainer.cpp rename to src/plugins/qmldesigner/libs/designercore/metainfo/propertycontainer.cpp diff --git a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp b/src/plugins/qmldesigner/libs/designercore/metainfo/subcomponentmanager.cpp similarity index 98% rename from src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp rename to src/plugins/qmldesigner/libs/designercore/metainfo/subcomponentmanager.cpp index 29a093f199e..d90a6a22731 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp +++ b/src/plugins/qmldesigner/libs/designercore/metainfo/subcomponentmanager.cpp @@ -7,11 +7,10 @@ #include #include #include -#include +#include #include #include -#include #include #include @@ -198,7 +197,7 @@ void SubComponentManager::parseDirectory(const QString &canonicalDirPath, bool a return; } - QDir designerDir(canonicalDirPath + QLatin1String(Constants::QML_DESIGNER_SUBFOLDER)); + QDir designerDir(canonicalDirPath + QLatin1String("/designer/")); if (designerDir.exists()) { QStringList filter; filter << QLatin1String("*.metainfo"); @@ -215,8 +214,11 @@ void SubComponentManager::parseDirectory(const QString &canonicalDirPath, bool a } catch (const InvalidMetaInfoException &e) { qWarning() << e.description(); const QString errorMessage = metaInfoFile.absoluteFilePath() + QLatin1Char('\n') + QLatin1Char('\n') + reader.errors().join(QLatin1Char('\n')); - Core::AsynchronousMessageBox::warning(QCoreApplication::translate("SubComponentManager::parseDirectory", "Invalid meta info"), - errorMessage); + QMessageBox::warning( + m_externalDependencies.mainWindow(), + QCoreApplication::translate("SubComponentManager::parseDirectory", + "Invalid meta info"), + errorMessage); } } } diff --git a/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/abstractproperty.cpp similarity index 97% rename from src/plugins/qmldesigner/designercore/model/abstractproperty.cpp rename to src/plugins/qmldesigner/libs/designercore/model/abstractproperty.cpp index 82ffc76943f..fd30daf6d5f 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/abstractproperty.cpp @@ -13,7 +13,6 @@ #include "nodeabstractproperty.h" #include "nodelistproperty.h" #include -#include #include @@ -103,13 +102,6 @@ ModelNode AbstractProperty::parentModelNode() const return ModelNode(m_internalNode, m_model.data(), m_view); } -/*! - Returns the QmlObjectNode to which the property belongs. -*/ -QmlObjectNode AbstractProperty::parentQmlObjectNode() const -{ - return QmlObjectNode(parentModelNode()); -} /*! Returns whether the property is the default property for the model node. */ diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/libs/designercore/model/abstractview.cpp similarity index 80% rename from src/plugins/qmldesigner/designercore/model/abstractview.cpp rename to src/plugins/qmldesigner/libs/designercore/model/abstractview.cpp index 339b3234b6c..31d49b79915 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/abstractview.cpp @@ -3,21 +3,17 @@ #include "abstractview.h" -#include "auxiliarydataproperties.h" #include "bindingproperty.h" #include "internalnode_p.h" #include "model.h" #include "model_p.h" -#include "modelutils.h" -#include "nodeinstanceview.h" #include "nodelistproperty.h" #include "nodemetainfo.h" -#include "qmldesignerconstants.h" -#include "qmlstate.h" -#include "qmltimeline.h" #include "rewritertransaction.h" #include "variantproperty.h" +#include + #include #include #include @@ -357,6 +353,8 @@ void AbstractView::customNotification(const AbstractView * /*view*/, const QStri { } +void AbstractView::customNotification(const CustomNotificationPackage &) {} + void AbstractView::scriptFunctionsChanged(const ModelNode &/*node*/, const QStringList &/*scriptFunctionList*/) { } @@ -512,9 +510,9 @@ bool AbstractView::hasModelNodeForInternalId(qint32 internalId) const return model()->d->hasNodeForInternalId(internalId); } -const NodeInstanceView *AbstractView::nodeInstanceView() const +const AbstractView *AbstractView::nodeInstanceView() const { - if (model()) + if (isAttached()) return model()->d->nodeInstanceView(); return nullptr; @@ -581,36 +579,6 @@ QString AbstractView::contextHelpId() const return id; } -void AbstractView::setCurrentTimeline(const ModelNode &timeline) -{ - if (currentTimeline().isValid()) - currentTimeline().toogleRecording(false); - - if (m_model) - m_model->setCurrentTimeline(timeline); -} - -void AbstractView::activateTimelineRecording(const ModelNode &timeline) -{ - if (currentTimeline().isValid()) - currentTimeline().toogleRecording(true); - - Internal::WriteLocker locker(m_model.data()); - - if (m_model) - m_model->setCurrentTimeline(timeline); -} - -void AbstractView::deactivateTimelineRecording() -{ - if (currentTimeline().isValid()) { - currentTimeline().toogleRecording(false); - currentTimeline().resetGroupRecording(); - } - if (m_model) - m_model->setCurrentTimeline({}); -} - bool AbstractView::executeInTransaction(const QByteArray &identifier, const OperationBlock &lambda) { try { @@ -642,122 +610,6 @@ QList AbstractView::allModelNodesOfType(const NodeMetaInfo &type) con [&](const ModelNode &node) { return node.metaInfo().isBasedOn(type); }); } -void AbstractView::emitDocumentMessage(const QString &error) -{ - emitDocumentMessage({DocumentMessage(error)}); -} - -void AbstractView::emitDocumentMessage(const QList &errors, const QList &warnings) -{ - if (model()) - model()->d->setDocumentMessages(errors, warnings); -} - -void AbstractView::emitCustomNotification(const QString &identifier, const QList &nodeList, - const QList &data) -{ - if (model()) - model()->d->notifyCustomNotification(this, identifier, nodeList, data); -} - -void AbstractView::emitInstancePropertyChange(const QList > &propertyList) -{ - if (model() && nodeInstanceView() == this) - model()->d->notifyInstancePropertyChange(propertyList); -} - -void AbstractView::emitInstanceErrorChange(const QVector &instanceIds) -{ - if (model() && nodeInstanceView() == this) - model()->d->notifyInstanceErrorChange(instanceIds); -} - -void AbstractView::emitInstancesCompleted(const QVector &nodeVector) -{ - if (model() && nodeInstanceView() == this) - model()->d->notifyInstancesCompleted(nodeVector); -} - -void AbstractView::emitInstanceInformationsChange(const QMultiHash &informationChangeHash) -{ - if (model() && nodeInstanceView() == this) - model()->d->notifyInstancesInformationsChange(informationChangeHash); -} - -void AbstractView::emitInstancesRenderImageChanged(const QVector &nodeVector) -{ - if (model() && nodeInstanceView() == this) - model()->d->notifyInstancesRenderImageChanged(nodeVector); -} - -void AbstractView::emitInstancesPreviewImageChanged(const QVector &nodeVector) -{ - if (model() && nodeInstanceView() == this) - model()->d->notifyInstancesPreviewImageChanged(nodeVector); -} - -void AbstractView::emitInstancesChildrenChanged(const QVector &nodeVector) -{ - if (model() && nodeInstanceView() == this) - model()->d->notifyInstancesChildrenChanged(nodeVector); -} - -void AbstractView::emitRewriterBeginTransaction() -{ - if (model()) - model()->d->notifyRewriterBeginTransaction(); -} - -void AbstractView::emitInstanceToken(const QString &token, int number, const QVector &nodeVector) -{ - if (nodeInstanceView()) - model()->d->notifyInstanceToken(token, number, nodeVector); -} - -void AbstractView::emitRenderImage3DChanged(const QImage &image) -{ - if (model()) - model()->d->notifyRenderImage3DChanged(image); -} - -void AbstractView::emitUpdateActiveScene3D(const QVariantMap &sceneState) -{ - if (model()) - model()->d->notifyUpdateActiveScene3D(sceneState); -} - -void AbstractView::emitModelNodelPreviewPixmapChanged(const ModelNode &node, - const QPixmap &pixmap, - const QByteArray &requestId) -{ - if (model()) - model()->d->notifyModelNodePreviewPixmapChanged(node, pixmap, requestId); -} - -void AbstractView::emitImport3DSupportChanged(const QVariantMap &supportMap) -{ - if (model()) - model()->d->notifyImport3DSupportChanged(supportMap); -} - -void AbstractView::emitNodeAtPosResult(const ModelNode &modelNode, const QVector3D &pos3d) -{ - if (model()) - model()->d->notifyNodeAtPosResult(modelNode, pos3d); -} - -void AbstractView::emitView3DAction(View3DActionType type, const QVariant &value) -{ - if (model()) - model()->d->notifyView3DAction(type, value); -} - -void AbstractView::emitRewriterEndTransaction() -{ - if (model()) - model()->d->notifyRewriterEndTransaction(); -} - void AbstractView::setCurrentStateNode(const ModelNode &node) { if (m_model) @@ -779,17 +631,12 @@ ModelNode AbstractView::currentStateNode() const return {}; } -QmlModelState AbstractView::currentState() const +ModelNode AbstractView::currentTimelineNode() const { - return QmlModelState(currentStateNode()); -} - -QmlTimeline AbstractView::currentTimeline() const -{ - if (model()) { - return QmlTimeline(ModelNode(m_model.data()->d->currentTimelineNode(), - m_model.data(), - const_cast(this))); + if (isAttached()) { + return ModelNode(m_model.data()->d->currentTimelineNode(), + m_model.data(), + const_cast(this)); } return {}; diff --git a/src/plugins/qmldesigner/designercore/model/annotation.cpp b/src/plugins/qmldesigner/libs/designercore/model/annotation.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/annotation.cpp rename to src/plugins/qmldesigner/libs/designercore/model/annotation.cpp diff --git a/src/plugins/qmldesigner/designercore/model/auxiliarypropertystorageview.cpp b/src/plugins/qmldesigner/libs/designercore/model/auxiliarypropertystorageview.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/auxiliarypropertystorageview.cpp rename to src/plugins/qmldesigner/libs/designercore/model/auxiliarypropertystorageview.cpp diff --git a/src/plugins/qmldesigner/designercore/model/auxiliarypropertystorageview.h b/src/plugins/qmldesigner/libs/designercore/model/auxiliarypropertystorageview.h similarity index 91% rename from src/plugins/qmldesigner/designercore/model/auxiliarypropertystorageview.h rename to src/plugins/qmldesigner/libs/designercore/model/auxiliarypropertystorageview.h index 2096afe9596..c6e44af30fd 100644 --- a/src/plugins/qmldesigner/designercore/model/auxiliarypropertystorageview.h +++ b/src/plugins/qmldesigner/libs/designercore/model/auxiliarypropertystorageview.h @@ -6,7 +6,7 @@ #include namespace QmlDesigner { -class AuxiliaryPropertyStorageView final : public AbstractView +class QMLDESIGNERCORE_EXPORT AuxiliaryPropertyStorageView final : public AbstractView { public: AuxiliaryPropertyStorageView(Sqlite::Database &database, diff --git a/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/bindingproperty.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/bindingproperty.cpp rename to src/plugins/qmldesigner/libs/designercore/model/bindingproperty.cpp diff --git a/src/plugins/qmldesigner/designercore/model/documentmessage.cpp b/src/plugins/qmldesigner/libs/designercore/model/documentmessage.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/documentmessage.cpp rename to src/plugins/qmldesigner/libs/designercore/model/documentmessage.cpp diff --git a/src/plugins/qmldesigner/designercore/model/import.cpp b/src/plugins/qmldesigner/libs/designercore/model/import.cpp similarity index 99% rename from src/plugins/qmldesigner/designercore/model/import.cpp rename to src/plugins/qmldesigner/libs/designercore/model/import.cpp index 06e277f8fa8..feb68609027 100644 --- a/src/plugins/qmldesigner/designercore/model/import.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/import.cpp @@ -3,7 +3,7 @@ #include "import.h" -#include +#include #include diff --git a/src/plugins/qmldesigner/designercore/model/internalbindingproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/internalbindingproperty.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalbindingproperty.cpp rename to src/plugins/qmldesigner/libs/designercore/model/internalbindingproperty.cpp diff --git a/src/plugins/qmldesigner/designercore/model/internalbindingproperty.h b/src/plugins/qmldesigner/libs/designercore/model/internalbindingproperty.h similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalbindingproperty.h rename to src/plugins/qmldesigner/libs/designercore/model/internalbindingproperty.h diff --git a/src/plugins/qmldesigner/designercore/model/internalnode.cpp b/src/plugins/qmldesigner/libs/designercore/model/internalnode.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalnode.cpp rename to src/plugins/qmldesigner/libs/designercore/model/internalnode.cpp diff --git a/src/plugins/qmldesigner/designercore/model/internalnode_p.h b/src/plugins/qmldesigner/libs/designercore/model/internalnode_p.h similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalnode_p.h rename to src/plugins/qmldesigner/libs/designercore/model/internalnode_p.h diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/internalnodeabstractproperty.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.cpp rename to src/plugins/qmldesigner/libs/designercore/model/internalnodeabstractproperty.cpp diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h b/src/plugins/qmldesigner/libs/designercore/model/internalnodeabstractproperty.h similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h rename to src/plugins/qmldesigner/libs/designercore/model/internalnodeabstractproperty.h diff --git a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/internalnodelistproperty.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp rename to src/plugins/qmldesigner/libs/designercore/model/internalnodelistproperty.cpp diff --git a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h b/src/plugins/qmldesigner/libs/designercore/model/internalnodelistproperty.h similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h rename to src/plugins/qmldesigner/libs/designercore/model/internalnodelistproperty.h diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/internalnodeproperty.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp rename to src/plugins/qmldesigner/libs/designercore/model/internalnodeproperty.cpp diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h b/src/plugins/qmldesigner/libs/designercore/model/internalnodeproperty.h similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalnodeproperty.h rename to src/plugins/qmldesigner/libs/designercore/model/internalnodeproperty.h diff --git a/src/plugins/qmldesigner/designercore/model/internalproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/internalproperty.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalproperty.cpp rename to src/plugins/qmldesigner/libs/designercore/model/internalproperty.cpp diff --git a/src/plugins/qmldesigner/designercore/model/internalproperty.h b/src/plugins/qmldesigner/libs/designercore/model/internalproperty.h similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalproperty.h rename to src/plugins/qmldesigner/libs/designercore/model/internalproperty.h diff --git a/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/internalsignalhandlerproperty.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.cpp rename to src/plugins/qmldesigner/libs/designercore/model/internalsignalhandlerproperty.cpp diff --git a/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.h b/src/plugins/qmldesigner/libs/designercore/model/internalsignalhandlerproperty.h similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.h rename to src/plugins/qmldesigner/libs/designercore/model/internalsignalhandlerproperty.h diff --git a/src/plugins/qmldesigner/designercore/model/internalvariantproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/internalvariantproperty.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalvariantproperty.cpp rename to src/plugins/qmldesigner/libs/designercore/model/internalvariantproperty.cpp diff --git a/src/plugins/qmldesigner/designercore/model/internalvariantproperty.h b/src/plugins/qmldesigner/libs/designercore/model/internalvariantproperty.h similarity index 100% rename from src/plugins/qmldesigner/designercore/model/internalvariantproperty.h rename to src/plugins/qmldesigner/libs/designercore/model/internalvariantproperty.h diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp similarity index 94% rename from src/plugins/qmldesigner/designercore/model/model.cpp rename to src/plugins/qmldesigner/libs/designercore/model/model.cpp index e02e02befbe..6150d8e70b3 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -4,8 +4,9 @@ #include "model.h" #include "internalnode_p.h" #include "model_p.h" -#include "modelutils.h" + #include +#include #include "abstractview.h" #include "internalbindingproperty.h" @@ -21,7 +22,6 @@ #ifndef QDS_USE_PROJECTSTORAGE # include "metainfo.h" #endif -#include "nodeinstanceview.h" #include "nodemetainfo.h" #include "abstractproperty.h" @@ -40,8 +40,8 @@ #include +#include #include -#include #include #include @@ -819,6 +819,13 @@ void ModelPrivate::notifyCustomNotification(const AbstractView *senderView, }); } +void ModelPrivate::notifyCustomNotificationTo(AbstractView *view, + const CustomNotificationPackage &package) +{ + if (view) + view->customNotification(package); +} + void ModelPrivate::notifyPropertiesRemoved(const QList &propertyPairList) { notifyNormalViewsLast([&](AbstractView *view) { @@ -1625,6 +1632,9 @@ void ModelPrivate::setRewriterView(RewriterView *rewriterView) Q_ASSERT(!(rewriterView && m_rewriterView)); + if (rewriterView && rewriterView->kind() != AbstractView::Kind::Rewriter) + return; + if (m_rewriterView) m_rewriterView->modelAboutToBeDetached(m_model); @@ -1639,9 +1649,12 @@ RewriterView *ModelPrivate::rewriterView() const return m_rewriterView.data(); } -void ModelPrivate::setNodeInstanceView(NodeInstanceView *nodeInstanceView) +void ModelPrivate::setNodeInstanceView(AbstractView *nodeInstanceView) { - if (nodeInstanceView == m_nodeInstanceView.data()) + if (nodeInstanceView == m_nodeInstanceView) + return; + + if (nodeInstanceView && nodeInstanceView->kind() != AbstractView::Kind::NodeInstance) return; if (m_nodeInstanceView) @@ -1653,7 +1666,7 @@ void ModelPrivate::setNodeInstanceView(NodeInstanceView *nodeInstanceView) nodeInstanceView->modelAttached(m_model); } -NodeInstanceView *ModelPrivate::nodeInstanceView() const +AbstractView *ModelPrivate::nodeInstanceView() const { return m_nodeInstanceView.data(); } @@ -1964,8 +1977,10 @@ ModelNode Model::currentStateNode(AbstractView *view) return ModelNode(d->currentStateNode(), this, view); } -void Model::setCurrentTimeline(const ModelNode &timeline) +void Model::setCurrentTimelineNode(const ModelNode &timeline) { + Internal::WriteLocker locker(this); // unsure about this locker + d->m_currentTimelineNode = timeline.internalNode(); d->notifyCurrentTimelineChanged(timeline); @@ -1986,6 +2001,137 @@ PathCacheType &Model::pathCache() return *d->pathCache; } +void Model::emitInstancePropertyChange(AbstractView *view, + const QList> &propertyList) +{ + if (d->nodeInstanceView() == view) // never remove check + d->notifyInstancePropertyChange(propertyList); +} + +void Model::emitInstanceErrorChange(AbstractView *view, const QVector &instanceIds) +{ + if (d->nodeInstanceView() == view) // never remove check + d->notifyInstanceErrorChange(instanceIds); +} + +void Model::emitInstancesCompleted(AbstractView *view, const QVector &nodeVector) +{ + if (d->nodeInstanceView() == view) // never remove check + d->notifyInstancesCompleted(nodeVector); +} + +void Model::emitInstanceInformationsChange( + AbstractView *view, const QMultiHash &informationChangeHash) +{ + if (d->nodeInstanceView() == view) // never remove check + d->notifyInstancesInformationsChange(informationChangeHash); +} + +void Model::emitInstancesRenderImageChanged(AbstractView *view, const QVector &nodeVector) +{ + if (d->nodeInstanceView() == view) // never remove check + d->notifyInstancesRenderImageChanged(nodeVector); +} + +void Model::emitInstancesPreviewImageChanged(AbstractView *view, const QVector &nodeVector) +{ + if (d->nodeInstanceView() == view) // never remove check + d->notifyInstancesPreviewImageChanged(nodeVector); +} + +void Model::emitInstancesChildrenChanged(AbstractView *view, const QVector &nodeVector) +{ + if (d->nodeInstanceView() == view) // never remove check + d->notifyInstancesChildrenChanged(nodeVector); +} + +void Model::emitInstanceToken(AbstractView *view, + const QString &token, + int number, + const QVector &nodeVector) +{ + if (d->nodeInstanceView() == view) // never remove check + d->notifyInstanceToken(token, number, nodeVector); +} + +void Model::emitRenderImage3DChanged(AbstractView *view, const QImage &image) +{ + if (d->nodeInstanceView() == view) // never remove check + d->notifyRenderImage3DChanged(image); +} + +void Model::emitUpdateActiveScene3D(AbstractView *view, const QVariantMap &sceneState) +{ + if (d->nodeInstanceView() == view) // never remove check + d->notifyUpdateActiveScene3D(sceneState); +} + +void Model::emitModelNodelPreviewPixmapChanged(AbstractView *view, + const ModelNode &node, + const QPixmap &pixmap, + const QByteArray &requestId) +{ + if (d->nodeInstanceView() == view) // never remove check + d->notifyModelNodePreviewPixmapChanged(node, pixmap, requestId); +} + +void Model::emitImport3DSupportChanged(AbstractView *view, const QVariantMap &supportMap) +{ + if (d->nodeInstanceView() == view) // never remove check + d->notifyImport3DSupportChanged(supportMap); +} + +void Model::emitNodeAtPosResult(AbstractView *view, const ModelNode &modelNode, const QVector3D &pos3d) +{ + if (d->nodeInstanceView() == view) // never remove check + d->notifyNodeAtPosResult(modelNode, pos3d); +} + +void Model::emitView3DAction(View3DActionType type, const QVariant &value) +{ + d->notifyView3DAction(type, value); +} + +void Model::emitDocumentMessage(const QString &error) +{ + emitDocumentMessage({DocumentMessage(error)}); +} + +void Model::emitDocumentMessage(const QList &errors, + const QList &warnings) +{ + d->setDocumentMessages(errors, warnings); +} + +void Model::emitCustomNotification(AbstractView *view, + const QString &identifier, + const QList &nodeList, + const QList &data) +{ + d->notifyCustomNotification(view, identifier, nodeList, data); +} + +void Model::sendCustomNotificationTo(AbstractView *to, const CustomNotificationPackage &package) +{ + d->notifyCustomNotificationTo(to, package); +} + +void Model::sendCustomNotificationToNodeInstanceView(const CustomNotificationPackage &package) +{ + if (auto view = d->nodeInstanceView()) + d->notifyCustomNotificationTo(view, package); +} + +void Model::emitRewriterBeginTransaction() +{ + d->notifyRewriterBeginTransaction(); +} + +void Model::emitRewriterEndTransaction() +{ + d->notifyRewriterEndTransaction(); +} + void ModelDeleter::operator()(class Model *model) { model->detachAllViews(); @@ -2058,12 +2204,12 @@ void Model::setRewriterView(RewriterView *rewriterView) d->setRewriterView(rewriterView); } -const NodeInstanceView *Model::nodeInstanceView() const +const AbstractView *Model::nodeInstanceView() const { return d->nodeInstanceView(); } -void Model::setNodeInstanceView(NodeInstanceView *nodeInstanceView) +void Model::setNodeInstanceView(AbstractView *nodeInstanceView) { d->setNodeInstanceView(nodeInstanceView); } @@ -2650,8 +2796,8 @@ void Model::attachView(AbstractView *view) std::string_view{view->metaObject()->className()})); // Internal::WriteLocker locker(d); - auto castedRewriterView = qobject_cast(view); - if (castedRewriterView) { + if (view->kind() == AbstractView::Kind::NodeInstance) { + auto castedRewriterView = qobject_cast(view); if (rewriterView() == castedRewriterView) return; @@ -2659,8 +2805,7 @@ void Model::attachView(AbstractView *view) return; } - auto nodeInstanceView = qobject_cast(view); - if (nodeInstanceView) + if (view->kind() == AbstractView::Kind::NodeInstance) return; d->attachView(view); @@ -2683,12 +2828,7 @@ void Model::detachView(AbstractView *view, ViewNotification emitDetachNotify) // Internal::WriteLocker locker(d); bool emitNotify = (emitDetachNotify == NotifyView); - auto rewriterView = qobject_cast(view); - if (rewriterView) - return; - - auto nodeInstanceView = qobject_cast(view); - if (nodeInstanceView) + if (view->kind() != AbstractView::Kind::Other) return; d->detachView(view, emitNotify); diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/libs/designercore/model/model_p.h similarity index 97% rename from src/plugins/qmldesigner/designercore/model/model_p.h rename to src/plugins/qmldesigner/libs/designercore/model/model_p.h index 471da6ea80b..a23a6f52182 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/libs/designercore/model/model_p.h @@ -12,7 +12,6 @@ # include "metainfo.h" #endif #include "modelnode.h" -#include "skipiterator.h" #include @@ -191,8 +190,12 @@ public: void notifyRootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion); - void notifyCustomNotification(const AbstractView *senderView, const QString &identifier, const QList &modelNodeList, const QList &data); - void notifyInstancePropertyChange(const QList > &propertyList); + void notifyCustomNotification(const AbstractView *senderView, + const QString &identifier, + const QList &modelNodeList, + const QList &data); + void notifyCustomNotificationTo(AbstractView *view, const CustomNotificationPackage &package); + void notifyInstancePropertyChange(const QList> &propertyList); void notifyInstanceErrorChange(const QVector &instanceIds); void notifyInstancesCompleted(const QVector &modelNodeVector); void notifyInstancesInformationsChange(const QMultiHash &informationChangeHash); @@ -303,8 +306,8 @@ public: void setRewriterView(RewriterView *rewriterView); RewriterView *rewriterView() const; - void setNodeInstanceView(NodeInstanceView *nodeInstanceView); - NodeInstanceView *nodeInstanceView() const; + void setNodeInstanceView(AbstractView *nodeInstanceView); + AbstractView *nodeInstanceView() const; InternalNodePointer currentStateNode() const; InternalNodePointer currentTimelineNode() const; @@ -364,7 +367,7 @@ private: Utils::PathString m_localPath; SourceId m_sourceId; QPointer m_rewriterView; - QPointer m_nodeInstanceView; + QPointer m_nodeInstanceView; QPointer m_metaInfoProxyModel; QHash> m_nodeMetaInfoCache; Utils::UniqueObjectPtr drag; diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/libs/designercore/model/modelnode.cpp similarity index 99% rename from src/plugins/qmldesigner/designercore/model/modelnode.cpp rename to src/plugins/qmldesigner/libs/designercore/model/modelnode.cpp index f5bce0d96ee..a9bf091327e 100644 --- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/modelnode.cpp @@ -7,7 +7,6 @@ #include "bindingproperty.h" #include "internalnode_p.h" #include "model_p.h" -#include "modelutils.h" #include "nodeabstractproperty.h" #include "nodelistproperty.h" #include "nodeproperty.h" @@ -16,6 +15,7 @@ #include #include +#include #include #include diff --git a/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp b/src/plugins/qmldesigner/libs/designercore/model/modelresourcemanagement.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/modelresourcemanagement.cpp rename to src/plugins/qmldesigner/libs/designercore/model/modelresourcemanagement.cpp diff --git a/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.h b/src/plugins/qmldesigner/libs/designercore/model/modelresourcemanagement.h similarity index 83% rename from src/plugins/qmldesigner/designercore/model/modelresourcemanagement.h rename to src/plugins/qmldesigner/libs/designercore/model/modelresourcemanagement.h index 4d505047263..adcc5ad9852 100644 --- a/src/plugins/qmldesigner/designercore/model/modelresourcemanagement.h +++ b/src/plugins/qmldesigner/libs/designercore/model/modelresourcemanagement.h @@ -10,7 +10,7 @@ namespace QmlDesigner { -class ModelResourceManagement final : public ModelResourceManagementInterface +class QMLDESIGNERCORE_EXPORT ModelResourceManagement final : public ModelResourceManagementInterface { public: ModelResourceSet removeNodes(ModelNodes nodes, Model *model) const override; diff --git a/src/plugins/qmldesigner/designercore/model/modelresourcemanagementfwd.h b/src/plugins/qmldesigner/libs/designercore/model/modelresourcemanagementfwd.h similarity index 100% rename from src/plugins/qmldesigner/designercore/model/modelresourcemanagementfwd.h rename to src/plugins/qmldesigner/libs/designercore/model/modelresourcemanagementfwd.h diff --git a/src/plugins/qmldesigner/designercore/model/modelresourcemanagementinterface.h b/src/plugins/qmldesigner/libs/designercore/model/modelresourcemanagementinterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/model/modelresourcemanagementinterface.h rename to src/plugins/qmldesigner/libs/designercore/model/modelresourcemanagementinterface.h diff --git a/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/nodeabstractproperty.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp rename to src/plugins/qmldesigner/libs/designercore/model/nodeabstractproperty.cpp diff --git a/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/nodelistproperty.cpp similarity index 93% rename from src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp rename to src/plugins/qmldesigner/libs/designercore/model/nodelistproperty.cpp index 3f9e54bd975..c1462b45dbd 100644 --- a/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/nodelistproperty.cpp @@ -7,7 +7,6 @@ #include "internalnode_p.h" #include "model.h" #include "model_p.h" -#include #include @@ -61,20 +60,6 @@ QList NodeListProperty::toModelNodeList() const return {}; } -QList NodeListProperty::toQmlObjectNodeList() const -{ - if (model()->nodeInstanceView()) - return {}; - - QList qmlObjectNodeList; - - const QList modelNodeList = toModelNodeList(); - for (const ModelNode &modelNode : modelNodeList) - qmlObjectNodeList.append(QmlObjectNode(modelNode)); - - return qmlObjectNodeList; -} - void NodeListProperty::slide(int from, int to) const { Internal::WriteLocker locker(model()); diff --git a/src/plugins/qmldesigner/designercore/model/nodeproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/nodeproperty.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/nodeproperty.cpp rename to src/plugins/qmldesigner/libs/designercore/model/nodeproperty.cpp diff --git a/src/plugins/qmldesigner/designercore/model/signalhandlerproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/signalhandlerproperty.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/signalhandlerproperty.cpp rename to src/plugins/qmldesigner/libs/designercore/model/signalhandlerproperty.cpp diff --git a/src/plugins/qmldesigner/designercore/model/variantproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/variantproperty.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/variantproperty.cpp rename to src/plugins/qmldesigner/libs/designercore/model/variantproperty.cpp diff --git a/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginmanager.cpp b/src/plugins/qmldesigner/libs/designercore/pluginmanager/widgetpluginmanager.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginmanager.cpp rename to src/plugins/qmldesigner/libs/designercore/pluginmanager/widgetpluginmanager.cpp diff --git a/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginmanager.h b/src/plugins/qmldesigner/libs/designercore/pluginmanager/widgetpluginmanager.h similarity index 100% rename from src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginmanager.h rename to src/plugins/qmldesigner/libs/designercore/pluginmanager/widgetpluginmanager.h diff --git a/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginpath.cpp b/src/plugins/qmldesigner/libs/designercore/pluginmanager/widgetpluginpath.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginpath.cpp rename to src/plugins/qmldesigner/libs/designercore/pluginmanager/widgetpluginpath.cpp diff --git a/src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginpath.h b/src/plugins/qmldesigner/libs/designercore/pluginmanager/widgetpluginpath.h similarity index 100% rename from src/plugins/qmldesigner/designercore/pluginmanager/widgetpluginpath.h rename to src/plugins/qmldesigner/libs/designercore/pluginmanager/widgetpluginpath.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/commontypecache.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/commontypecache.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/commontypecache.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/commontypecache.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/directorypathcompressor.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/directorypathcompressor.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/directorypathcompressor.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/directorypathcompressor.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/filestatus.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatus.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/filestatus.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/filestatus.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/filestatuscache.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatuscache.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/filestatuscache.cpp rename to src/plugins/qmldesigner/libs/designercore/projectstorage/filestatuscache.cpp diff --git a/src/plugins/qmldesigner/designercore/projectstorage/filestatuscache.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatuscache.h similarity index 92% rename from src/plugins/qmldesigner/designercore/projectstorage/filestatuscache.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/filestatuscache.h index e46e9c9a36e..957961e14a8 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/filestatuscache.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/filestatuscache.h @@ -5,14 +5,13 @@ #include "filestatus.h" #include "filesysteminterface.h" - -#include +#include QT_FORWARD_DECLARE_CLASS(QFileInfo) namespace QmlDesigner { -class FileStatusCache +class QMLDESIGNERCORE_EXPORT FileStatusCache { public: using size_type = FileStatuses::size_type; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/filesystem.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/filesystem.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/filesystem.cpp rename to src/plugins/qmldesigner/libs/designercore/projectstorage/filesystem.cpp diff --git a/src/plugins/qmldesigner/designercore/projectstorage/filesystem.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/filesystem.h similarity index 94% rename from src/plugins/qmldesigner/designercore/projectstorage/filesystem.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/filesystem.h index 37ab2069da4..8e83cd2ff04 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/filesystem.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/filesystem.h @@ -14,7 +14,7 @@ class SourcePathStorage; template class SourcePathCache; -class FileSystem : public FileSystemInterface +class QMLDESIGNERCORE_EXPORT FileSystem : public FileSystemInterface { using PathCache = SourcePathCache; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/filesysteminterface.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/filesysteminterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/filesysteminterface.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/filesysteminterface.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/modulescanner.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/modulescanner.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/modulescanner.cpp rename to src/plugins/qmldesigner/libs/designercore/projectstorage/modulescanner.cpp diff --git a/src/plugins/qmldesigner/designercore/projectstorage/modulescanner.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/modulescanner.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/modulescanner.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/modulescanner.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstorage.cpp rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h similarity index 99% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h index a2339599456..b98ffcfece2 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h @@ -33,7 +33,7 @@ using namespace NanotraceHR::Literals; using ProjectStorageTracing::projectStorageCategory; -class ProjectStorage final : public ProjectStorageInterface +class QMLDESIGNERCORE_EXPORT ProjectStorage final : public ProjectStorageInterface { using Database = Sqlite::Database; friend Storage::Info::CommonTypeCache; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageerrornotifier.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.cpp rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageerrornotifier.cpp diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageerrornotifier.h similarity index 84% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageerrornotifier.h index ab1bdd51366..f3afcd0c459 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifier.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageerrornotifier.h @@ -6,10 +6,12 @@ #include "projectstorageerrornotifierinterface.h" #include +#include namespace QmlDesigner { -class ProjectStorageErrorNotifier final : public ProjectStorageErrorNotifierInterface +class QMLDESIGNERCORE_EXPORT ProjectStorageErrorNotifier final + : public ProjectStorageErrorNotifierInterface { public: ProjectStorageErrorNotifier(PathCacheType &pathCache) diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifierinterface.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageerrornotifierinterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstorageerrornotifierinterface.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageerrornotifierinterface.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageexceptions.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.cpp rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageexceptions.cpp diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageexceptions.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstorageexceptions.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageexceptions.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragefwd.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragefwd.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstoragefwd.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragefwd.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinfotypes.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinfotypes.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstorageinfotypes.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinfotypes.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstorageinterface.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageobserver.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageobserver.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstorageobserver.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageobserver.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatcher.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatcher.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatcherinterface.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcherinterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatcherinterface.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcherinterface.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatchernotifierinterface.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchernotifierinterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatchernotifierinterface.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchernotifierinterface.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatchertypes.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstoragepathwatchertypes.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatchertypes.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageprinting.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageprinting.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstorageprinting.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageprinting.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragetypes.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstoragetypes.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragetypes.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.cpp rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.h similarity index 98% rename from src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.h index 3a36b201828..344b0543a27 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorageupdater.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.h @@ -37,7 +37,8 @@ class QmlDocumentParserInterface; class QmlTypesParserInterface; class SourcePathStorage; -class ProjectStorageUpdater final : public ProjectStoragePathWatcherNotifierInterface +class QMLDESIGNERCORE_EXPORT ProjectStorageUpdater final + : public ProjectStoragePathWatcherNotifierInterface { public: using PathCache = SourcePathCache; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/qmldocumentparser.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.cpp rename to src/plugins/qmldesigner/libs/designercore/projectstorage/qmldocumentparser.cpp diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/qmldocumentparser.h similarity index 90% rename from src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/qmldocumentparser.h index 1ad55d094fd..7b64322ab4f 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparser.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/qmldocumentparser.h @@ -7,13 +7,15 @@ #include "qmldocumentparserinterface.h" #include "sourcepathstorage/nonlockingmutex.h" +#include + namespace QmlDesigner { template class SourcePathCache; class SourcePathStorage; -class QmlDocumentParser final : public QmlDocumentParserInterface +class QMLDESIGNERCORE_EXPORT QmlDocumentParser final : public QmlDocumentParserInterface { public: using ProjectStorage = QmlDesigner::ProjectStorage; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparserinterface.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/qmldocumentparserinterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/qmldocumentparserinterface.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/qmldocumentparserinterface.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/qmltypesparser.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.cpp rename to src/plugins/qmldesigner/libs/designercore/projectstorage/qmltypesparser.cpp diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/qmltypesparser.h similarity index 88% rename from src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/qmltypesparser.h index 1dd71dcce98..b2c40fddd38 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparser.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/qmltypesparser.h @@ -7,6 +7,8 @@ #include "qmltypesparserinterface.h" #include "sourcepathstorage/nonlockingmutex.h" +#include + namespace Sqlite { class Database; } @@ -16,7 +18,7 @@ namespace QmlDesigner { template class SourcePathCache; -class QmlTypesParser final : public QmlTypesParserInterface +class QMLDESIGNERCORE_EXPORT QmlTypesParser final : public QmlTypesParserInterface { public: using ProjectStorage = QmlDesigner::ProjectStorage; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/qmltypesparserinterface.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/qmltypesparserinterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/qmltypesparserinterface.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/qmltypesparserinterface.h diff --git a/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/typeannotationreader.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.cpp rename to src/plugins/qmldesigner/libs/designercore/projectstorage/typeannotationreader.cpp diff --git a/src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/typeannotationreader.h similarity index 100% rename from src/plugins/qmldesigner/designercore/projectstorage/typeannotationreader.h rename to src/plugins/qmldesigner/libs/designercore/projectstorage/typeannotationreader.h diff --git a/src/plugins/qmldesigner/designercore/rewriter/componenttextmodifier.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/componenttextmodifier.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/componenttextmodifier.cpp rename to src/plugins/qmldesigner/libs/designercore/rewriter/componenttextmodifier.cpp diff --git a/src/plugins/qmldesigner/designercore/rewriter/modelnodepositionrecalculator.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/modelnodepositionrecalculator.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/modelnodepositionrecalculator.cpp rename to src/plugins/qmldesigner/libs/designercore/rewriter/modelnodepositionrecalculator.cpp diff --git a/src/plugins/qmldesigner/designercore/rewriter/modelnodepositionrecalculator.h b/src/plugins/qmldesigner/libs/designercore/rewriter/modelnodepositionrecalculator.h similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/modelnodepositionrecalculator.h rename to src/plugins/qmldesigner/libs/designercore/rewriter/modelnodepositionrecalculator.h diff --git a/src/plugins/qmldesigner/designercore/rewriter/modelnodepositionstorage.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/modelnodepositionstorage.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/modelnodepositionstorage.cpp rename to src/plugins/qmldesigner/libs/designercore/rewriter/modelnodepositionstorage.cpp diff --git a/src/plugins/qmldesigner/designercore/rewriter/modelnodepositionstorage.h b/src/plugins/qmldesigner/libs/designercore/rewriter/modelnodepositionstorage.h similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/modelnodepositionstorage.h rename to src/plugins/qmldesigner/libs/designercore/rewriter/modelnodepositionstorage.h diff --git a/src/plugins/qmldesigner/designercore/rewriter/modeltotextmerger.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/modeltotextmerger.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/modeltotextmerger.cpp rename to src/plugins/qmldesigner/libs/designercore/rewriter/modeltotextmerger.cpp diff --git a/src/plugins/qmldesigner/designercore/rewriter/modeltotextmerger.h b/src/plugins/qmldesigner/libs/designercore/rewriter/modeltotextmerger.h similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/modeltotextmerger.h rename to src/plugins/qmldesigner/libs/designercore/rewriter/modeltotextmerger.h diff --git a/src/plugins/qmldesigner/designercore/rewriter/plaintexteditmodifier.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/plaintexteditmodifier.cpp similarity index 85% rename from src/plugins/qmldesigner/designercore/rewriter/plaintexteditmodifier.cpp rename to src/plugins/qmldesigner/libs/designercore/rewriter/plaintexteditmodifier.cpp index f37c9a6841d..4ddd654377a 100644 --- a/src/plugins/qmldesigner/designercore/rewriter/plaintexteditmodifier.cpp +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/plaintexteditmodifier.cpp @@ -5,10 +5,6 @@ #include -#include -#include -#include - #include #include @@ -166,26 +162,3 @@ void PlainTextEditModifier::reactivateChangeSignals() } } -IndentingTextEditModifier::IndentingTextEditModifier(QTextDocument *document, const QTextCursor &textCursor) - : NotIndentingTextEditModifier{document, textCursor} -{ - m_tabSettings = QmlJSTools::QmlJSToolsSettings::globalCodeStyle()->tabSettings(); -} - -void IndentingTextEditModifier::indent(int offset, int length) -{ - if (length == 0 || offset < 0 || offset + length >= text().length()) - return; - - int startLine = getLineInDocument(textDocument(), offset); - int endLine = getLineInDocument(textDocument(), offset + length); - - if (startLine > -1 && endLine > -1) - indentLines(startLine, endLine); -} - -void IndentingTextEditModifier::indentLines(int startLine, int endLine) -{ - QmlJSEditor::indentQmlJs(textDocument(), startLine, endLine, m_tabSettings); -} - diff --git a/src/plugins/qmldesigner/designercore/rewriter/propertycontainer.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/propertycontainer.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/propertycontainer.cpp rename to src/plugins/qmldesigner/libs/designercore/rewriter/propertycontainer.cpp diff --git a/src/plugins/qmldesigner/designercore/rewriter/propertynode.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/propertynode.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/propertynode.cpp rename to src/plugins/qmldesigner/libs/designercore/rewriter/propertynode.cpp diff --git a/src/plugins/qmldesigner/designercore/rewriter/propertyparser.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/propertyparser.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/propertyparser.cpp rename to src/plugins/qmldesigner/libs/designercore/rewriter/propertyparser.cpp diff --git a/src/plugins/qmldesigner/designercore/qmltools/qmltextgenerator.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/qmltextgenerator.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/qmltools/qmltextgenerator.cpp rename to src/plugins/qmldesigner/libs/designercore/rewriter/qmltextgenerator.cpp diff --git a/src/plugins/qmldesigner/designercore/qmltools/qmltextgenerator.h b/src/plugins/qmldesigner/libs/designercore/rewriter/qmltextgenerator.h similarity index 100% rename from src/plugins/qmldesigner/designercore/qmltools/qmltextgenerator.h rename to src/plugins/qmldesigner/libs/designercore/rewriter/qmltextgenerator.h diff --git a/src/plugins/qmldesigner/designercore/rewriter/rewriteaction.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteaction.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/rewriteaction.cpp rename to src/plugins/qmldesigner/libs/designercore/rewriter/rewriteaction.cpp diff --git a/src/plugins/qmldesigner/designercore/rewriter/rewriteaction.h b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteaction.h similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/rewriteaction.h rename to src/plugins/qmldesigner/libs/designercore/rewriter/rewriteaction.h diff --git a/src/plugins/qmldesigner/designercore/rewriter/rewriteactioncompressor.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteactioncompressor.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/rewriteactioncompressor.cpp rename to src/plugins/qmldesigner/libs/designercore/rewriter/rewriteactioncompressor.cpp diff --git a/src/plugins/qmldesigner/designercore/rewriter/rewriteactioncompressor.h b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriteactioncompressor.h similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/rewriteactioncompressor.h rename to src/plugins/qmldesigner/libs/designercore/rewriter/rewriteactioncompressor.h diff --git a/src/plugins/qmldesigner/designercore/rewriter/rewritertransaction.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/rewritertransaction.cpp similarity index 86% rename from src/plugins/qmldesigner/designercore/rewriter/rewritertransaction.cpp rename to src/plugins/qmldesigner/libs/designercore/rewriter/rewritertransaction.cpp index 95bd193e52f..ae12e54e567 100644 --- a/src/plugins/qmldesigner/designercore/rewriter/rewritertransaction.cpp +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/rewritertransaction.cpp @@ -27,7 +27,6 @@ RewriterTransaction::RewriterTransaction(AbstractView *_view, const QByteArray & m_identifier(identifier), m_valid(true) { - Q_ASSERT(view()); static int identifierNumber = 0; m_identifierNumber = identifierNumber++; @@ -37,7 +36,7 @@ RewriterTransaction::RewriterTransaction(AbstractView *_view, const QByteArray & m_identifierList.append(m_identifier + QByteArrayLiteral("-") + QByteArray::number(m_identifierNumber)); } - view()->emitRewriterBeginTransaction(); + beginTransaction(); } RewriterTransaction::~RewriterTransaction() @@ -60,12 +59,24 @@ void RewriterTransaction::ignoreSemanticChecks() m_ignoreSemanticChecks = true; } +void RewriterTransaction::beginTransaction() +{ + if (m_view && m_view->isAttached()) + m_view->model()->emitRewriterBeginTransaction(); +} + +void RewriterTransaction::endTransaction() +{ + if (m_view && m_view->isAttached()) + m_view->model()->emitRewriterBeginTransaction(); +} + void RewriterTransaction::commit() { if (m_valid) { m_valid = false; - RewriterView *rewriterView = view()->rewriterView(); + RewriterView *rewriterView = m_view->rewriterView(); QTC_ASSERT(rewriterView, qWarning() << Q_FUNC_INFO << "No rewriter attached"); @@ -76,10 +87,10 @@ void RewriterTransaction::commit() rewriterView->setCheckSemanticErrors(false); } - view()->emitRewriterEndTransaction(); + endTransaction(); if (rewriterView) - view()->rewriterView()->setCheckSemanticErrors(oldSemanticChecks); + m_view->rewriterView()->setCheckSemanticErrors(oldSemanticChecks); if (m_activeIdentifier) { qDebug() << "Commit RewriterTransaction:" << m_identifier << m_identifierNumber; @@ -95,9 +106,9 @@ void RewriterTransaction::rollback() // TODO: should be implemented with a function in the rewriter if (m_valid) { m_valid = false; - view()->emitRewriterEndTransaction(); + endTransaction(); - view()->externalDependencies().undoOnCurrentDesignDocument(); + m_view->externalDependencies().undoOnCurrentDesignDocument(); if (m_activeIdentifier) { qDebug() << "Rollback RewriterTransaction:" << m_identifier << m_identifierNumber; m_identifierList.removeOne(m_identifier + QByteArrayLiteral("-") + QByteArray::number(m_identifierNumber)); @@ -105,11 +116,6 @@ void RewriterTransaction::rollback() } } -AbstractView *RewriterTransaction::view() -{ - return m_view.data(); -} - RewriterTransaction::RewriterTransaction(const RewriterTransaction &other) : m_valid(false) { diff --git a/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriterview.cpp similarity index 99% rename from src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp rename to src/plugins/qmldesigner/libs/designercore/rewriter/rewriterview.cpp index 0033c3bb4e3..25cbc2d1852 100644 --- a/src/plugins/qmldesigner/designercore/rewriter/rewriterview.cpp +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriterview.cpp @@ -60,6 +60,8 @@ RewriterView::RewriterView(ExternalDependenciesInterface &externalDependencies, , m_modelToTextMerger(std::make_unique(this)) , m_textToModelMerger(std::make_unique(this)) { + setKind(Kind::Rewriter); + m_amendTimer.setSingleShot(true); m_amendTimer.setInterval(800); @@ -528,7 +530,8 @@ void RewriterView::notifyErrorsAndWarnings(const QList &errors) if (m_setWidgetStatusCallback) m_setWidgetStatusCallback(errors.isEmpty()); - emitDocumentMessage(errors, m_warnings); + if (isAttached()) + model()->emitDocumentMessage(errors, m_warnings); } static QString replaceIllegalPropertyNameChars(const QString &str) diff --git a/src/plugins/qmldesigner/designercore/rewriter/textmodifier.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/textmodifier.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/textmodifier.cpp rename to src/plugins/qmldesigner/libs/designercore/rewriter/textmodifier.cpp diff --git a/src/plugins/qmldesigner/designercore/rewriter/texttomodelmerger.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/texttomodelmerger.cpp rename to src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.cpp diff --git a/src/plugins/qmldesigner/designercore/rewriter/texttomodelmerger.h b/src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.h similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/texttomodelmerger.h rename to src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.h diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/nonlockingmutex.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/nonlockingmutex.h similarity index 100% rename from src/plugins/qmldesigner/designercore/sourcepathstorage/nonlockingmutex.h rename to src/plugins/qmldesigner/libs/designercore/sourcepathstorage/nonlockingmutex.h diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepath.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepath.h similarity index 100% rename from src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepath.h rename to src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepath.h diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathcache.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h similarity index 100% rename from src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathcache.h rename to src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcache.h diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathcacheinterface.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcacheinterface.h similarity index 100% rename from src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathcacheinterface.h rename to src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcacheinterface.h diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathcachetypes.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcachetypes.h similarity index 100% rename from src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathcachetypes.h rename to src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathcachetypes.h diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathexceptions.cpp b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathexceptions.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathexceptions.cpp rename to src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathexceptions.cpp diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathexceptions.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathexceptions.h similarity index 100% rename from src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathexceptions.h rename to src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathexceptions.h diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathstorage.cpp b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathstorage.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathstorage.cpp rename to src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathstorage.cpp diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathstorage.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathstorage.h similarity index 100% rename from src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathstorage.h rename to src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathstorage.h diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathview.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathview.h similarity index 100% rename from src/plugins/qmldesigner/designercore/sourcepathstorage/sourcepathview.h rename to src/plugins/qmldesigner/libs/designercore/sourcepathstorage/sourcepathview.h diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/storagecache.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecache.h similarity index 100% rename from src/plugins/qmldesigner/designercore/sourcepathstorage/storagecache.h rename to src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecache.h diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/storagecacheentry.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecacheentry.h similarity index 100% rename from src/plugins/qmldesigner/designercore/sourcepathstorage/storagecacheentry.h rename to src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecacheentry.h diff --git a/src/plugins/qmldesigner/designercore/sourcepathstorage/storagecachefwd.h b/src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecachefwd.h similarity index 100% rename from src/plugins/qmldesigner/designercore/sourcepathstorage/storagecachefwd.h rename to src/plugins/qmldesigner/libs/designercore/sourcepathstorage/storagecachefwd.h diff --git a/src/plugins/qmldesigner/designercore/tracing/qmldesignertracing.cpp b/src/plugins/qmldesigner/libs/designercore/tracing/qmldesignertracing.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/tracing/qmldesignertracing.cpp rename to src/plugins/qmldesigner/libs/designercore/tracing/qmldesignertracing.cpp diff --git a/src/plugins/qmldesigner/designercore/tracing/qmldesignertracing.h b/src/plugins/qmldesigner/libs/designercore/tracing/qmldesignertracing.h similarity index 100% rename from src/plugins/qmldesigner/designercore/tracing/qmldesignertracing.h rename to src/plugins/qmldesigner/libs/designercore/tracing/qmldesignertracing.h diff --git a/src/plugins/qmldesigner/libs/qmldesignerutils/CMakeLists.txt b/src/plugins/qmldesigner/libs/qmldesignerutils/CMakeLists.txt new file mode 100644 index 00000000000..4759aba5e5c --- /dev/null +++ b/src/plugins/qmldesigner/libs/qmldesignerutils/CMakeLists.txt @@ -0,0 +1,25 @@ +add_qtc_library(QmlDesignerUtils STATIC + DEPENDS + Qt::Gui Utils Qt::QmlPrivate + PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR} + PUBLIC_COMPILE_OPTIONS + $<$:-Wno-unneeded-internal-declaration> + SOURCES + asset.cpp asset.h + designeralgorithm.h + filedownloader.cpp filedownloader.h + multifiledownloader.cpp multifiledownloader.h + fileextractor.cpp fileextractor.h + hdrimage.cpp hdrimage.h + ktximage.cpp ktximage.h + imageutils.cpp imageutils.h + qmldesignerutils_global.h + version.cpp version.h +) + +extend_qtc_library(QmlDesignerUtils + CONDITION ENABLE_COMPILE_WARNING_AS_ERROR + PROPERTIES COMPILE_WARNING_AS_ERROR ON + PUBLIC_COMPILE_OPTIONS + $<$:-Wno-error=maybe-uninitialized> +) diff --git a/src/plugins/qmldesigner/utils/asset.cpp b/src/plugins/qmldesigner/libs/qmldesignerutils/asset.cpp similarity index 100% rename from src/plugins/qmldesigner/utils/asset.cpp rename to src/plugins/qmldesigner/libs/qmldesignerutils/asset.cpp diff --git a/src/plugins/qmldesigner/utils/asset.h b/src/plugins/qmldesigner/libs/qmldesignerutils/asset.h similarity index 100% rename from src/plugins/qmldesigner/utils/asset.h rename to src/plugins/qmldesigner/libs/qmldesignerutils/asset.h diff --git a/src/plugins/qmldesigner/utils/designeralgorithm.h b/src/plugins/qmldesigner/libs/qmldesignerutils/designeralgorithm.h similarity index 100% rename from src/plugins/qmldesigner/utils/designeralgorithm.h rename to src/plugins/qmldesigner/libs/qmldesignerutils/designeralgorithm.h diff --git a/src/plugins/qmldesigner/utils/filedownloader.cpp b/src/plugins/qmldesigner/libs/qmldesignerutils/filedownloader.cpp similarity index 100% rename from src/plugins/qmldesigner/utils/filedownloader.cpp rename to src/plugins/qmldesigner/libs/qmldesignerutils/filedownloader.cpp diff --git a/src/plugins/qmldesigner/utils/filedownloader.h b/src/plugins/qmldesigner/libs/qmldesignerutils/filedownloader.h similarity index 100% rename from src/plugins/qmldesigner/utils/filedownloader.h rename to src/plugins/qmldesigner/libs/qmldesignerutils/filedownloader.h diff --git a/src/plugins/qmldesigner/utils/fileextractor.cpp b/src/plugins/qmldesigner/libs/qmldesignerutils/fileextractor.cpp similarity index 100% rename from src/plugins/qmldesigner/utils/fileextractor.cpp rename to src/plugins/qmldesigner/libs/qmldesignerutils/fileextractor.cpp diff --git a/src/plugins/qmldesigner/utils/fileextractor.h b/src/plugins/qmldesigner/libs/qmldesignerutils/fileextractor.h similarity index 100% rename from src/plugins/qmldesigner/utils/fileextractor.h rename to src/plugins/qmldesigner/libs/qmldesignerutils/fileextractor.h diff --git a/src/plugins/qmldesigner/utils/hdrimage.cpp b/src/plugins/qmldesigner/libs/qmldesignerutils/hdrimage.cpp similarity index 100% rename from src/plugins/qmldesigner/utils/hdrimage.cpp rename to src/plugins/qmldesigner/libs/qmldesignerutils/hdrimage.cpp diff --git a/src/plugins/qmldesigner/utils/hdrimage.h b/src/plugins/qmldesigner/libs/qmldesignerutils/hdrimage.h similarity index 100% rename from src/plugins/qmldesigner/utils/hdrimage.h rename to src/plugins/qmldesigner/libs/qmldesignerutils/hdrimage.h diff --git a/src/plugins/qmldesigner/utils/imageutils.cpp b/src/plugins/qmldesigner/libs/qmldesignerutils/imageutils.cpp similarity index 100% rename from src/plugins/qmldesigner/utils/imageutils.cpp rename to src/plugins/qmldesigner/libs/qmldesignerutils/imageutils.cpp diff --git a/src/plugins/qmldesigner/utils/imageutils.h b/src/plugins/qmldesigner/libs/qmldesignerutils/imageutils.h similarity index 100% rename from src/plugins/qmldesigner/utils/imageutils.h rename to src/plugins/qmldesigner/libs/qmldesignerutils/imageutils.h diff --git a/src/plugins/qmldesigner/utils/ktximage.cpp b/src/plugins/qmldesigner/libs/qmldesignerutils/ktximage.cpp similarity index 100% rename from src/plugins/qmldesigner/utils/ktximage.cpp rename to src/plugins/qmldesigner/libs/qmldesignerutils/ktximage.cpp diff --git a/src/plugins/qmldesigner/utils/ktximage.h b/src/plugins/qmldesigner/libs/qmldesignerutils/ktximage.h similarity index 100% rename from src/plugins/qmldesigner/utils/ktximage.h rename to src/plugins/qmldesigner/libs/qmldesignerutils/ktximage.h diff --git a/src/plugins/qmldesigner/utils/multifiledownloader.cpp b/src/plugins/qmldesigner/libs/qmldesignerutils/multifiledownloader.cpp similarity index 100% rename from src/plugins/qmldesigner/utils/multifiledownloader.cpp rename to src/plugins/qmldesigner/libs/qmldesignerutils/multifiledownloader.cpp diff --git a/src/plugins/qmldesigner/utils/multifiledownloader.h b/src/plugins/qmldesigner/libs/qmldesignerutils/multifiledownloader.h similarity index 100% rename from src/plugins/qmldesigner/utils/multifiledownloader.h rename to src/plugins/qmldesigner/libs/qmldesignerutils/multifiledownloader.h diff --git a/src/plugins/qmldesigner/utils/qmldesignerutils_global.h b/src/plugins/qmldesigner/libs/qmldesignerutils/qmldesignerutils_global.h similarity index 100% rename from src/plugins/qmldesigner/utils/qmldesignerutils_global.h rename to src/plugins/qmldesigner/libs/qmldesignerutils/qmldesignerutils_global.h diff --git a/src/plugins/qmldesigner/utils/version.cpp b/src/plugins/qmldesigner/libs/qmldesignerutils/version.cpp similarity index 100% rename from src/plugins/qmldesigner/utils/version.cpp rename to src/plugins/qmldesigner/libs/qmldesignerutils/version.cpp diff --git a/src/plugins/qmldesigner/utils/version.h b/src/plugins/qmldesigner/libs/qmldesignerutils/version.h similarity index 100% rename from src/plugins/qmldesigner/utils/version.h rename to src/plugins/qmldesigner/libs/qmldesignerutils/version.h diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 04b2320e838..c6c073ce91d 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -3,42 +3,23 @@ #pragma once +#include + namespace QmlDesigner { namespace Constants { -inline constexpr char C_BACKSPACE[] = "QmlDesigner.Backspace"; -inline constexpr char C_DELETE[] = "QmlDesigner.Delete"; -inline constexpr char C_DUPLICATE[] = "QmlDesigner.Duplicate"; - // Context -inline constexpr char C_QMLDESIGNER[] = "QmlDesigner::QmlDesignerMain"; -inline constexpr char C_QMLFORMEDITOR[] = "QmlDesigner::FormEditor"; -inline constexpr char C_QMLEDITOR3D[] = "QmlDesigner::Editor3D"; -inline constexpr char C_QMLEFFECTCOMPOSER[] = "QmlDesigner::EffectComposer"; -inline constexpr char C_QMLNAVIGATOR[] = "QmlDesigner::Navigator"; -inline constexpr char C_QMLTEXTEDITOR[] = "QmlDesigner::TextEditor"; -inline constexpr char C_QMLMATERIALBROWSER[] = "QmlDesigner::MaterialBrowser"; -inline constexpr char C_QMLASSETSLIBRARY[] = "QmlDesigner::AssetsLibrary"; +inline constexpr char qmlDesignerContextId[] = "QmlDesigner::QmlDesignerMain"; +inline constexpr char qmlFormEditorContextId[] = "QmlDesigner::FormEditor"; +inline constexpr char qml3DEditorContextId[] = "QmlDesigner::Editor3D"; +inline constexpr char qmlNavigatorContextId[] = "QmlDesigner::Navigator"; +inline constexpr char qmlMaterialBrowserContextId[] = "QmlDesigner::MaterialBrowser"; +inline constexpr char qmlAssetsLibraryContextId[] = "QmlDesigner::AssetsLibrary"; // Special context for preview menu, shared b/w designer and text editor -inline constexpr char C_QT_QUICK_TOOLS_MENU[] = "QmlDesigner::ToolsMenu"; +inline constexpr char qtQuickToolsMenuContextId[] = "QmlDesigner::ToolsMenu"; // Actions -inline constexpr char SWITCH_TEXT_DESIGN[] = "QmlDesigner.SwitchTextDesign"; -inline constexpr char RESTORE_DEFAULT_VIEW[] = "QmlDesigner.RestoreDefaultView"; -inline constexpr char TOGGLE_LEFT_SIDEBAR[] = "QmlDesigner.ToggleLeftSideBar"; -inline constexpr char TOGGLE_RIGHT_SIDEBAR[] = "QmlDesigner.ToggleRightSideBar"; -inline constexpr char TOGGLE_STATES_EDITOR[] = "QmlDesigner.ToggleStatesEditor"; -inline constexpr char GO_INTO_COMPONENT[] = "QmlDesigner.GoIntoComponent"; -inline constexpr char EXPORT_AS_IMAGE[] = "QmlDesigner.ExportAsImage"; -inline constexpr char TAKE_SCREENSHOT[] = "QmlDesigner.TakeScreenshot"; -inline constexpr char FORMEDITOR_REFRESH[] = "QmlDesigner.FormEditor.Refresh"; -inline constexpr char FORMEDITOR_SNAPPING[] = "QmlDesigner.FormEditor.Snapping"; -inline constexpr char FORMEDITOR_NO_SNAPPING[] = "QmlDesigner.FormEditor.NoSnapping"; -inline constexpr char FORMEDITOR_NO_SNAPPING_AND_ANCHORING[] - = "QmlDesigner.FormEditor.NoSnappingAndAnchoring"; -inline constexpr char FORMEDITOR_NO_SHOW_BOUNDING_RECTANGLE[] - = "QmlDesigner.FormEditor.ShowBoundingRectangle"; inline constexpr char EDIT3D_SELECTION_MODE[] = "QmlDesigner.Editor3D.SelectionModeToggle"; inline constexpr char EDIT3D_MOVE_TOOL[] = "QmlDesigner.Editor3D.MoveTool"; inline constexpr char EDIT3D_ROTATE_TOOL[] = "QmlDesigner.Editor3D.RotateTool"; @@ -77,30 +58,18 @@ inline constexpr char EDIT3D_SNAP_TOGGLE[] = "QmlDesigner.Editor3D.SnapToggle"; inline constexpr char EDIT3D_SNAP_CONFIG[] = "QmlDesigner.Editor3D.SnapConfig"; inline constexpr char EDIT3D_CAMERA_SPEED_CONFIG[] = "QmlDesigner.Editor3D.CameraSpeedConfig"; -inline constexpr char QML_DESIGNER_SUBFOLDER[] = "/designer/"; inline constexpr char BUNDLE_JSON_FILENAME[] = "bundle.json"; inline constexpr char BUNDLE_SUFFIX[] = "qdsbundle"; -inline constexpr char COMPONENT_BUNDLES_TYPE[] = "Bundles"; -inline constexpr char COMPONENT_BUNDLES_MATERIAL_BUNDLE_TYPE[] = "Materials"; inline constexpr char COMPONENT_BUNDLES_EFFECT_BUNDLE_TYPE[] = "Effects"; -inline constexpr char COMPONENT_BUNDLES_USER_MATERIAL_BUNDLE_TYPE[] = "UserMaterials"; inline constexpr char COMPONENT_BUNDLES_USER_EFFECT_BUNDLE_TYPE[] = "UserEffects"; inline constexpr char COMPONENT_BUNDLES_USER_3D_BUNDLE_TYPE[] = "User3D"; -inline constexpr char GENERATED_COMPONENTS_FOLDER[] = "Generated"; inline constexpr char COMPONENT_BUNDLES_ASSET_REF_FILE[] = "_asset_ref.json"; -inline constexpr char OLD_QUICK_3D_ASSETS_FOLDER[] = "Quick3DAssets"; -inline constexpr char QUICK_3D_COMPONENTS_FOLDER[] = "QtQuick3D"; inline constexpr char QUICK_3D_ASSET_LIBRARY_ICON_SUFFIX[] = "_libicon"; inline constexpr char QUICK_3D_ASSET_IMPORT_DATA_NAME[] = "_importdata.json"; inline constexpr char QUICK_3D_ASSET_IMPORT_DATA_OPTIONS_KEY[] = "import_options"; inline constexpr char QUICK_3D_ASSET_IMPORT_DATA_SOURCE_KEY[] = "source_scene"; -inline constexpr char OLD_ASSET_IMPORT_FOLDER[] = "asset_imports"; inline constexpr char OLD_EFFECTS_IMPORT_FOLDER[] = "/asset_imports/Effects"; -inline constexpr char OLD_EFFECTS_FOLDER[] = "Effects"; -inline constexpr char OLD_COMPONENT_BUNDLES_TYPE[] = "ComponentBundles"; -inline constexpr char OLD_COMPONENT_BUNDLES_MATERIAL_BUNDLE_TYPE[] = "MaterialBundle"; inline constexpr char OLD_COMPONENT_BUNDLES_EFFECT_BUNDLE_TYPE[] = "EffectBundle"; -inline constexpr char COMPOSED_EFFECTS_TYPE[] = "Effects"; inline constexpr char MATERIAL_LIB_ID[] = "__materialLibrary__"; inline constexpr char MIME_TYPE_ITEM_LIBRARY_INFO[] @@ -124,7 +93,6 @@ inline constexpr char MIME_TYPE_ASSET_EFFECT[] = "application/vnd.qtdesignstudio // Menus inline constexpr char M_VIEW_WORKSPACES[] = "QmlDesigner.Menu.View.Workspaces"; -const int MODELNODE_PREVIEW_IMAGE_DIMENSIONS = 150; inline constexpr char EVENT_TIMELINE_ADDED[] = "timelineAdded"; inline constexpr char EVENT_TRANSITION_ADDED[] = "transitionAdded"; diff --git a/src/plugins/qmldesigner/qmldesignerexternaldependencies.cpp b/src/plugins/qmldesigner/qmldesignerexternaldependencies.cpp index 913564c46b5..f2ad1163e9e 100644 --- a/src/plugins/qmldesigner/qmldesignerexternaldependencies.cpp +++ b/src/plugins/qmldesigner/qmldesignerexternaldependencies.cpp @@ -280,4 +280,9 @@ QString ExternalDependencies::userResourcePath(QStringView relativePath) const return Core::ICore::userResourcePath(relativePath.toString()).path(); } +QWidget *ExternalDependencies::mainWindow() const +{ + return Core::ICore::mainWindow(); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/qmldesignerexternaldependencies.h b/src/plugins/qmldesigner/qmldesignerexternaldependencies.h index b4944175a01..42c88b922c0 100644 --- a/src/plugins/qmldesigner/qmldesignerexternaldependencies.h +++ b/src/plugins/qmldesigner/qmldesignerexternaldependencies.h @@ -42,6 +42,7 @@ public: QString qtQuickVersion() const override; Utils::FilePath resourcePath(const QString &relativePath) const override; QString userResourcePath(QStringView relativePath) const override; + QWidget *mainWindow() const override; private: const DesignerSettings &m_designerSettings; diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 1f2f321f47c..68d3c7071f8 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -401,12 +401,12 @@ void QmlDesignerPlugin::integrateIntoQtCreator(QWidget *modeWidget) { auto context = new Internal::DesignModeContext(modeWidget); Core::ICore::addContextObject(context); - Core::Context qmlDesignerMainContext(Constants::C_QMLDESIGNER); - Core::Context qmlDesignerFormEditorContext(Constants::C_QMLFORMEDITOR); - Core::Context qmlDesignerEditor3dContext(Constants::C_QMLEDITOR3D); - Core::Context qmlDesignerNavigatorContext(Constants::C_QMLNAVIGATOR); - Core::Context qmlDesignerMaterialBrowserContext(Constants::C_QMLMATERIALBROWSER); - Core::Context qmlDesignerAssetsLibraryContext(Constants::C_QMLASSETSLIBRARY); + Core::Context qmlDesignerMainContext(Constants::qmlDesignerContextId); + Core::Context qmlDesignerFormEditorContext(Constants::qmlFormEditorContextId); + Core::Context qmlDesignerEditor3dContext(Constants::qml3DEditorContextId); + Core::Context qmlDesignerNavigatorContext(Constants::qmlNavigatorContextId); + Core::Context qmlDesignerMaterialBrowserContext(Constants::qmlMaterialBrowserContextId); + Core::Context qmlDesignerAssetsLibraryContext(Constants::qmlAssetsLibraryContextId); d->shortCutManager.registerActions(qmlDesignerMainContext, qmlDesignerFormEditorContext, qmlDesignerEditor3dContext, qmlDesignerNavigatorContext); diff --git a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp index 6b3a499d8f0..34296390793 100644 --- a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp +++ b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp @@ -28,16 +28,16 @@ #include #include #include -#include -#include #include #include #include -#include -#include #include +#include +#include +#include +#include -#include +#include #include diff --git a/src/plugins/qmldesigner/designercore/model/anchorline.cpp b/src/plugins/qmldesigner/qmltools/anchorline.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/model/anchorline.cpp rename to src/plugins/qmldesigner/qmltools/anchorline.cpp diff --git a/src/plugins/qmldesigner/designercore/include/anchorline.h b/src/plugins/qmldesigner/qmltools/anchorline.h similarity index 88% rename from src/plugins/qmldesigner/designercore/include/anchorline.h rename to src/plugins/qmldesigner/qmltools/anchorline.h index 6db7c350067..b19ce968938 100644 --- a/src/plugins/qmldesigner/designercore/include/anchorline.h +++ b/src/plugins/qmldesigner/qmltools/anchorline.h @@ -3,13 +3,13 @@ #pragma once -#include +#include #include "qmlitemnode.h" namespace QmlDesigner { -class QMLDESIGNERCORE_EXPORT AnchorLine +class QMLDESIGNER_EXPORT AnchorLine { public: AnchorLine(); diff --git a/src/plugins/qmldesigner/designercore/qmltools/qml3dnode.cpp b/src/plugins/qmldesigner/qmltools/qml3dnode.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/qmltools/qml3dnode.cpp rename to src/plugins/qmldesigner/qmltools/qml3dnode.cpp diff --git a/src/plugins/qmldesigner/designercore/include/qml3dnode.h b/src/plugins/qmldesigner/qmltools/qml3dnode.h similarity index 77% rename from src/plugins/qmldesigner/designercore/include/qml3dnode.h rename to src/plugins/qmldesigner/qmltools/qml3dnode.h index 7dbabac046a..df367a7098f 100644 --- a/src/plugins/qmldesigner/designercore/include/qml3dnode.h +++ b/src/plugins/qmldesigner/qmltools/qml3dnode.h @@ -3,11 +3,11 @@ #pragma once -#include -#include #include "qmlobjectnode.h" #include "qmlstate.h" #include "qmlvisualnode.h" +#include +#include #include #include @@ -19,7 +19,7 @@ class QmlModelStateGroup; class QmlAnchors; class ItemLibraryEntry; -class QMLDESIGNERCORE_EXPORT Qml3DNode : public QmlVisualNode +class QMLDESIGNER_EXPORT Qml3DNode : public QmlVisualNode { friend class QmlAnchors; public: @@ -39,7 +39,7 @@ private: void handleEulerRotationSet(); }; -QMLDESIGNERCORE_EXPORT QList toModelNodeList(const QList &fxItemNodeList); -QMLDESIGNERCORE_EXPORT QList toQml3DNodeList(const QList &modelNodeList); +QMLDESIGNER_EXPORT QList toModelNodeList(const QList &fxItemNodeList); +QMLDESIGNER_EXPORT QList toQml3DNodeList(const QList &modelNodeList); } //QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/qmltools/qmlanchors.cpp b/src/plugins/qmldesigner/qmltools/qmlanchors.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/qmltools/qmlanchors.cpp rename to src/plugins/qmldesigner/qmltools/qmlanchors.cpp diff --git a/src/plugins/qmldesigner/designercore/include/qmlanchors.h b/src/plugins/qmldesigner/qmltools/qmlanchors.h similarity index 96% rename from src/plugins/qmldesigner/designercore/include/qmlanchors.h rename to src/plugins/qmldesigner/qmltools/qmlanchors.h index 2d47c042aec..da0f9c9debc 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlanchors.h +++ b/src/plugins/qmldesigner/qmltools/qmlanchors.h @@ -3,13 +3,13 @@ #pragma once -#include -#include #include "anchorline.h" +#include + namespace QmlDesigner { -class QMLDESIGNERCORE_EXPORT QmlAnchors +class QMLDESIGNER_EXPORT QmlAnchors { public: QmlAnchors(const QmlItemNode &fxItemNode); diff --git a/src/plugins/qmldesigner/designercore/qmltools/qmlchangeset.cpp b/src/plugins/qmldesigner/qmltools/qmlchangeset.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/qmltools/qmlchangeset.cpp rename to src/plugins/qmldesigner/qmltools/qmlchangeset.cpp diff --git a/src/plugins/qmldesigner/designercore/include/qmlchangeset.h b/src/plugins/qmldesigner/qmltools/qmlchangeset.h similarity index 85% rename from src/plugins/qmldesigner/designercore/include/qmlchangeset.h rename to src/plugins/qmldesigner/qmltools/qmlchangeset.h index bc2043809f4..6c796e0b0cc 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlchangeset.h +++ b/src/plugins/qmldesigner/qmltools/qmlchangeset.h @@ -3,13 +3,12 @@ #pragma once -#include -#include #include "qmlmodelnodefacade.h" +#include namespace QmlDesigner { -class QMLDESIGNERCORE_EXPORT QmlModelStateOperation : public QmlModelNodeFacade +class QMLDESIGNER_EXPORT QmlModelStateOperation : public QmlModelNodeFacade { public: QmlModelStateOperation() : QmlModelNodeFacade() {} @@ -26,7 +25,7 @@ public: static bool isValidQmlModelStateOperation(const ModelNode &modelNode); }; -class QMLDESIGNERCORE_EXPORT QmlPropertyChanges : public QmlModelStateOperation +class QMLDESIGNER_EXPORT QmlPropertyChanges : public QmlModelStateOperation { public: QmlPropertyChanges() : QmlModelStateOperation() {} diff --git a/src/plugins/qmldesigner/designercore/qmltools/qmlconnections.cpp b/src/plugins/qmldesigner/qmltools/qmlconnections.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/qmltools/qmlconnections.cpp rename to src/plugins/qmldesigner/qmltools/qmlconnections.cpp diff --git a/src/plugins/qmldesigner/designercore/include/qmlconnections.h b/src/plugins/qmldesigner/qmltools/qmlconnections.h similarity index 87% rename from src/plugins/qmldesigner/designercore/include/qmlconnections.h rename to src/plugins/qmldesigner/qmltools/qmlconnections.h index 5dfc33ce619..88b6a498a91 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlconnections.h +++ b/src/plugins/qmldesigner/qmltools/qmlconnections.h @@ -3,7 +3,6 @@ #pragma once -#include #include "qmlmodelnodefacade.h" #include @@ -12,7 +11,7 @@ namespace QmlDesigner { class StatesEditorView; -class QMLDESIGNERCORE_EXPORT QmlConnections : public QmlModelNodeFacade +class QMLDESIGNER_EXPORT QmlConnections : public QmlModelNodeFacade { friend StatesEditorView; diff --git a/src/plugins/qmldesigner/designercore/qmltools/qmlitemnode.cpp b/src/plugins/qmldesigner/qmltools/qmlitemnode.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/qmltools/qmlitemnode.cpp rename to src/plugins/qmldesigner/qmltools/qmlitemnode.cpp diff --git a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h b/src/plugins/qmldesigner/qmltools/qmlitemnode.h similarity index 92% rename from src/plugins/qmldesigner/designercore/include/qmlitemnode.h rename to src/plugins/qmldesigner/qmltools/qmlitemnode.h index c2ac5579900..eb0ba97983f 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h +++ b/src/plugins/qmldesigner/qmltools/qmlitemnode.h @@ -3,7 +3,6 @@ #pragma once -#include #include #include "qmlobjectnode.h" #include "qmlstate.h" @@ -20,7 +19,7 @@ class QmlModelStateGroup; class QmlAnchors; class ItemLibraryEntry; -class QMLDESIGNERCORE_EXPORT QmlItemNode : public QmlVisualNode +class QMLDESIGNER_EXPORT QmlItemNode : public QmlVisualNode { friend QmlAnchors; @@ -148,7 +147,7 @@ public: class QmlFlowItemNode; class QmlFlowViewNode; -class QMLDESIGNERCORE_EXPORT QmlFlowTargetNode final : public QmlItemNode +class QMLDESIGNER_EXPORT QmlFlowTargetNode final : public QmlItemNode { public: QmlFlowTargetNode(const ModelNode &modelNode) : QmlItemNode(modelNode) {} @@ -164,7 +163,7 @@ public: void removeTransitions(); }; -class QMLDESIGNERCORE_EXPORT QmlFlowActionAreaNode final : public QmlItemNode +class QMLDESIGNER_EXPORT QmlFlowActionAreaNode final : public QmlItemNode { public: QmlFlowActionAreaNode(const ModelNode &modelNode) : QmlItemNode(modelNode) {} @@ -178,7 +177,7 @@ private: void destroyTarget(); }; -class QMLDESIGNERCORE_EXPORT QmlFlowItemNode final : public QmlItemNode +class QMLDESIGNER_EXPORT QmlFlowItemNode final : public QmlItemNode { public: QmlFlowItemNode(const ModelNode &modelNode) : QmlItemNode(modelNode) {} @@ -191,7 +190,7 @@ public: static ModelNode decisionNodeForTransition(const ModelNode &transition); }; -class QMLDESIGNERCORE_EXPORT QmlFlowViewNode final : public QmlItemNode +class QMLDESIGNER_EXPORT QmlFlowViewNode final : public QmlItemNode { public: QmlFlowViewNode(const ModelNode &modelNode) : QmlItemNode(modelNode) {} @@ -220,9 +219,8 @@ private: static PropertyNameList s_mouseSignals; }; - -QMLDESIGNERCORE_EXPORT QList toModelNodeList(const QList &fxItemNodeList); -QMLDESIGNERCORE_EXPORT QList toQmlItemNodeList(const QList &modelNodeList); -QMLDESIGNERCORE_EXPORT QList toQmlItemNodeListKeppInvalid(const QList &modelNodeList); +QMLDESIGNER_EXPORT QList toModelNodeList(const QList &fxItemNodeList); +QMLDESIGNER_EXPORT QList toQmlItemNodeList(const QList &modelNodeList); +QMLDESIGNER_EXPORT QList toQmlItemNodeListKeppInvalid(const QList &modelNodeList); } //QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/qmltools/qmlmodelnodefacade.cpp b/src/plugins/qmldesigner/qmltools/qmlmodelnodefacade.cpp similarity index 85% rename from src/plugins/qmldesigner/designercore/qmltools/qmlmodelnodefacade.cpp rename to src/plugins/qmldesigner/qmltools/qmlmodelnodefacade.cpp index 7e3bc793247..85b35128553 100644 --- a/src/plugins/qmldesigner/designercore/qmltools/qmlmodelnodefacade.cpp +++ b/src/plugins/qmldesigner/qmltools/qmlmodelnodefacade.cpp @@ -19,9 +19,17 @@ Model *QmlModelNodeFacade::model() const return m_modelNode.model(); } +const NodeInstanceView *nodeInstanceView(const ModelNode &node) +{ + if (auto model = node.model()) + return static_cast(model->nodeInstanceView()); + + return nullptr; +} + const NodeInstanceView *QmlModelNodeFacade::nodeInstanceView(const ModelNode &modelNode) { - return modelNode.model()->nodeInstanceView(); + return QmlDesigner::nodeInstanceView(modelNode); } const NodeInstanceView *QmlModelNodeFacade::nodeInstanceView() const diff --git a/src/plugins/qmldesigner/designercore/include/qmlmodelnodefacade.h b/src/plugins/qmldesigner/qmltools/qmlmodelnodefacade.h similarity index 93% rename from src/plugins/qmldesigner/designercore/include/qmlmodelnodefacade.h rename to src/plugins/qmldesigner/qmltools/qmlmodelnodefacade.h index 0a81e00c904..2de42e1b249 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlmodelnodefacade.h +++ b/src/plugins/qmldesigner/qmltools/qmlmodelnodefacade.h @@ -3,7 +3,7 @@ #pragma once -#include +#include #include #include @@ -13,7 +13,7 @@ namespace QmlDesigner { class AbstractView; class NodeInstanceView; -class QMLDESIGNERCORE_EXPORT QmlModelNodeFacade +class QMLDESIGNER_EXPORT QmlModelNodeFacade { public: operator ModelNode() const { return m_modelNode; } @@ -77,4 +77,6 @@ private: ModelNode m_modelNode; }; +QMLDESIGNER_EXPORT const NodeInstanceView *nodeInstanceView(const ModelNode &node); + } //QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/qmltools/qmlobjectnode.cpp b/src/plugins/qmldesigner/qmltools/qmlobjectnode.cpp similarity index 98% rename from src/plugins/qmldesigner/designercore/qmltools/qmlobjectnode.cpp rename to src/plugins/qmldesigner/qmltools/qmlobjectnode.cpp index a4153fc4464..fcb65295115 100644 --- a/src/plugins/qmldesigner/designercore/qmltools/qmlobjectnode.cpp +++ b/src/plugins/qmldesigner/qmltools/qmlobjectnode.cpp @@ -107,9 +107,9 @@ QmlModelState QmlObjectNode::currentState() const QmlTimeline QmlObjectNode::currentTimeline() const { if (isValid()) - return view()->currentTimeline(); - else - return QmlTimeline(); + return view()->currentTimelineNode(); + + return {}; } bool QmlObjectNode::isRootModelNode() const @@ -529,8 +529,8 @@ bool QmlObjectNode::isAncestorOf(const QmlObjectNode &objectNode) const QVariant QmlObjectNode::instanceValue(const ModelNode &modelNode, PropertyNameView name) { - Q_ASSERT(modelNode.view()->nodeInstanceView()->hasInstanceForModelNode(modelNode)); - return modelNode.view()->nodeInstanceView()->instanceForModelNode(modelNode).property(name); + Q_ASSERT(nodeInstanceView(modelNode)->hasInstanceForModelNode(modelNode)); + return nodeInstanceView(modelNode)->instanceForModelNode(modelNode).property(name); } QString QmlObjectNode::generateTranslatableText([[maybe_unused]] const QString &text, diff --git a/src/plugins/qmldesigner/designercore/include/qmlobjectnode.h b/src/plugins/qmldesigner/qmltools/qmlobjectnode.h similarity index 93% rename from src/plugins/qmldesigner/designercore/include/qmlobjectnode.h rename to src/plugins/qmldesigner/qmltools/qmlobjectnode.h index 71adf56e69d..90424adf626 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlobjectnode.h +++ b/src/plugins/qmldesigner/qmltools/qmlobjectnode.h @@ -3,7 +3,6 @@ #pragma once -#include #include "qmlmodelnodefacade.h" #include "qmlstate.h" #include "qmltimeline.h" @@ -19,7 +18,7 @@ class MoveManipulator; class QmlVisualNode; class DesignerSettings; -class QMLDESIGNERCORE_EXPORT QmlObjectNode : public QmlModelNodeFacade +class QMLDESIGNER_EXPORT QmlObjectNode : public QmlModelNodeFacade { friend QmlItemNode; friend MoveManipulator; @@ -129,6 +128,6 @@ protected: QmlItemNode itemForInstance(const NodeInstance &instance) const; }; -QMLDESIGNERCORE_EXPORT QList toModelNodeList(const QList &fxObjectNodeList); -QMLDESIGNERCORE_EXPORT QList toQmlObjectNodeList(const QList &modelNodeList); +QMLDESIGNER_EXPORT QList toModelNodeList(const QList &fxObjectNodeList); +QMLDESIGNER_EXPORT QList toQmlObjectNodeList(const QList &modelNodeList); }// QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/qmltools/qmlstate.cpp b/src/plugins/qmldesigner/qmltools/qmlstate.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/qmltools/qmlstate.cpp rename to src/plugins/qmldesigner/qmltools/qmlstate.cpp diff --git a/src/plugins/qmldesigner/designercore/include/qmlstate.h b/src/plugins/qmldesigner/qmltools/qmlstate.h similarity index 94% rename from src/plugins/qmldesigner/designercore/include/qmlstate.h rename to src/plugins/qmldesigner/qmltools/qmlstate.h index 58515aff3b1..2a153aad17a 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlstate.h +++ b/src/plugins/qmldesigner/qmltools/qmlstate.h @@ -3,7 +3,6 @@ #pragma once -#include #include "qmlmodelnodefacade.h" #include "qmlchangeset.h" @@ -20,7 +19,7 @@ namespace Experimental { class StatesEditorView; } -class QMLDESIGNERCORE_EXPORT QmlModelState final : public QmlModelNodeFacade +class QMLDESIGNER_EXPORT QmlModelState final : public QmlModelNodeFacade { friend StatesEditorView; diff --git a/src/plugins/qmldesigner/designercore/qmltools/qmltimeline.cpp b/src/plugins/qmldesigner/qmltools/qmltimeline.cpp similarity index 99% rename from src/plugins/qmldesigner/designercore/qmltools/qmltimeline.cpp rename to src/plugins/qmldesigner/qmltools/qmltimeline.cpp index 85c4db30c5f..676d712be63 100644 --- a/src/plugins/qmldesigner/designercore/qmltools/qmltimeline.cpp +++ b/src/plugins/qmldesigner/qmltools/qmltimeline.cpp @@ -200,7 +200,7 @@ bool QmlTimeline::hasActiveTimeline(AbstractView *view) if (!view->model()->hasImport(Import::createLibraryImport("QtQuick.Timeline", "1.0"), true, true)) return false; - return view->currentTimeline().isValid(); + return isValidQmlTimeline(view->currentTimelineNode()); } return false; diff --git a/src/plugins/qmldesigner/designercore/include/qmltimeline.h b/src/plugins/qmldesigner/qmltools/qmltimeline.h similarity index 94% rename from src/plugins/qmldesigner/designercore/include/qmltimeline.h rename to src/plugins/qmldesigner/qmltools/qmltimeline.h index 2cad8d2b901..7f85ad26c1f 100644 --- a/src/plugins/qmldesigner/designercore/include/qmltimeline.h +++ b/src/plugins/qmldesigner/qmltools/qmltimeline.h @@ -3,7 +3,6 @@ #pragma once -#include #include "qmlmodelnodefacade.h" namespace QmlDesigner { @@ -13,7 +12,7 @@ class QmlObjectNode; class QmlModelStateGroup; class QmlTimelineKeyframeGroup; -class QMLDESIGNERCORE_EXPORT QmlTimeline final : public QmlModelNodeFacade +class QMLDESIGNER_EXPORT QmlTimeline final : public QmlModelNodeFacade { public: diff --git a/src/plugins/qmldesigner/designercore/qmltools/qmltimelinekeyframegroup.cpp b/src/plugins/qmldesigner/qmltools/qmltimelinekeyframegroup.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/qmltools/qmltimelinekeyframegroup.cpp rename to src/plugins/qmldesigner/qmltools/qmltimelinekeyframegroup.cpp diff --git a/src/plugins/qmldesigner/designercore/include/qmltimelinekeyframegroup.h b/src/plugins/qmldesigner/qmltools/qmltimelinekeyframegroup.h similarity index 93% rename from src/plugins/qmldesigner/designercore/include/qmltimelinekeyframegroup.h rename to src/plugins/qmldesigner/qmltools/qmltimelinekeyframegroup.h index 632ea93f212..d27be27a194 100644 --- a/src/plugins/qmldesigner/designercore/include/qmltimelinekeyframegroup.h +++ b/src/plugins/qmldesigner/qmltools/qmltimelinekeyframegroup.h @@ -5,7 +5,6 @@ #include "qmlchangeset.h" #include "qmlmodelnodefacade.h" -#include namespace QmlDesigner { @@ -13,7 +12,7 @@ class AbstractViewAbstractVieweGroup; class QmlObjectNode; class QmlTimeline; -class QMLDESIGNERCORE_EXPORT QmlTimelineKeyframeGroup final : public QmlModelNodeFacade +class QMLDESIGNER_EXPORT QmlTimelineKeyframeGroup final : public QmlModelNodeFacade { public: QmlTimelineKeyframeGroup(); diff --git a/src/plugins/qmldesigner/designercore/qmltools/qmlvisualnode.cpp b/src/plugins/qmldesigner/qmltools/qmlvisualnode.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/qmltools/qmlvisualnode.cpp rename to src/plugins/qmldesigner/qmltools/qmlvisualnode.cpp diff --git a/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h b/src/plugins/qmldesigner/qmltools/qmlvisualnode.h similarity index 91% rename from src/plugins/qmldesigner/designercore/include/qmlvisualnode.h rename to src/plugins/qmldesigner/qmltools/qmlvisualnode.h index f155f4f4687..4aea4872495 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h +++ b/src/plugins/qmldesigner/qmltools/qmlvisualnode.h @@ -3,10 +3,9 @@ #pragma once -#include -#include #include "qmlobjectnode.h" #include "qmlstate.h" +#include #include #include @@ -21,7 +20,7 @@ class ItemLibraryEntry; inline constexpr AuxiliaryDataKeyView invisibleProperty{AuxiliaryDataType::Document, "invisible"}; -class QMLDESIGNERCORE_EXPORT QmlVisualNode : public QmlObjectNode +class QMLDESIGNER_EXPORT QmlVisualNode : public QmlObjectNode { friend class QmlAnchors; public: @@ -103,7 +102,7 @@ private: void setDoubleProperty(PropertyNameView name, double value); }; -class QMLDESIGNERCORE_EXPORT QmlModelStateGroup +class QMLDESIGNER_EXPORT QmlModelStateGroup { friend class QmlObjectNode; @@ -124,7 +123,7 @@ private: ModelNode m_modelNode; }; -QMLDESIGNERCORE_EXPORT QList toModelNodeList(const QList &fxItemNodeList); -QMLDESIGNERCORE_EXPORT QList toQmlVisualNodeList(const QList &modelNodeList); +QMLDESIGNER_EXPORT QList toModelNodeList(const QList &fxItemNodeList); +QMLDESIGNER_EXPORT QList toQmlVisualNodeList(const QList &modelNodeList); } //QmlDesigner diff --git a/src/plugins/qmldesigner/shortcutmanager.cpp b/src/plugins/qmldesigner/shortcutmanager.cpp index 661ff3f271f..8292a830bd2 100644 --- a/src/plugins/qmldesigner/shortcutmanager.cpp +++ b/src/plugins/qmldesigner/shortcutmanager.cpp @@ -45,6 +45,9 @@ namespace QmlDesigner { +constexpr char deleteActionId[] = "QmlDesigner.Delete"; +constexpr char duplicateActionId[] = "QmlDesigner.Duplicate"; + static DesignDocument *currentDesignDocument() { return QmlDesignerPlugin::instance()->currentDesignDocument(); @@ -107,7 +110,10 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex connect(&m_saveAsAction, &QAction::triggered, em, &Core::EditorManager::saveDocumentAs); //Export as Image - command = Core::ActionManager::registerAction(&m_exportAsImageAction, QmlDesigner::Constants::EXPORT_AS_IMAGE, qmlDesignerMainContext); + static constexpr char exportAsImageActionId[] = "QmlDesigner.ExportAsImage"; + command = Core::ActionManager::registerAction(&m_exportAsImageAction, + exportAsImageActionId, + qmlDesignerMainContext); command->setAttribute(Core::Command::CA_Hide); connect(&m_exportAsImageAction, &QAction::triggered, [] { QmlDesignerPlugin::instance()->viewManager().exportAsImage(); @@ -124,8 +130,8 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex }); action->setEnabled(false); - command = Core::ActionManager::registerAction(&m_takeScreenshotAction, - QmlDesigner::Constants::TAKE_SCREENSHOT); + static constexpr char takeScreenShotActionId[] = "QmlDesigner.TakeScreenshot"; + command = Core::ActionManager::registerAction(&m_takeScreenshotAction, takeScreenShotActionId); connect(&m_takeScreenshotAction, &QAction::triggered, [] { const auto folder = Utils::FilePath::fromString( QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)) @@ -176,7 +182,9 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex m_deleteAction.setIcon(QIcon::fromTheme(QLatin1String("edit-cut"), Utils::Icons::EDIT_CLEAR_TOOLBAR.icon())); - command = Core::ActionManager::registerAction(&m_deleteAction, QmlDesigner::Constants::C_DELETE, qmlDesignerMainContext); + command = Core::ActionManager::registerAction(&m_deleteAction, + deleteActionId, + qmlDesignerMainContext); command->setDefaultKeySequences({Qt::Key_Backspace, Qt::Key_Delete}); command->setAttribute(Core::Command::CA_Hide); // don't show delete in other modes @@ -205,9 +213,15 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE); designerActionManager.addCreatorCommand(command, ComponentCoreConstants::editCategory, 12, Utils::Icons::PASTE_TOOLBAR.icon()); - Core::ActionManager::registerAction(&m_duplicateAction, Constants::C_DUPLICATE, qmlDesignerFormEditorContext); - Core::ActionManager::registerAction(&m_duplicateAction, Constants::C_DUPLICATE, qmlDesignerEditor3DContext); - command = Core::ActionManager::registerAction(&m_duplicateAction, Constants::C_DUPLICATE, qmlDesignerMainContext); + Core::ActionManager::registerAction(&m_duplicateAction, + duplicateActionId, + qmlDesignerFormEditorContext); + Core::ActionManager::registerAction(&m_duplicateAction, + duplicateActionId, + qmlDesignerEditor3DContext); + command = Core::ActionManager::registerAction(&m_duplicateAction, + duplicateActionId, + qmlDesignerMainContext); editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE); designerActionManager.addCreatorCommand(command, ComponentCoreConstants::editCategory, 15); @@ -230,11 +244,12 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex }); connect(Core::ICore::instance(), &Core::ICore::contextChanged, this, [&](const Core::Context &context) { - isMatBrowserActive = context.contains(Constants::C_QMLMATERIALBROWSER); - isAssetsLibraryActive = context.contains(Constants::C_QMLASSETSLIBRARY); + isMatBrowserActive = context.contains(Constants::qmlMaterialBrowserContextId); + isAssetsLibraryActive = context.contains(Constants::qmlAssetsLibraryContextId); - if (!context.contains(Constants::C_QMLFORMEDITOR) && !context.contains(Constants::C_QMLEDITOR3D) - && !context.contains(Constants::C_QMLNAVIGATOR)) { + if (!context.contains(Constants::qmlFormEditorContextId) + && !context.contains(Constants::qml3DEditorContextId) + && !context.contains(Constants::qmlNavigatorContextId)) { m_deleteAction.setEnabled(isMatBrowserActive || isAssetsLibraryActive); m_cutAction.setEnabled(false); m_copyAction.setEnabled(false); diff --git a/src/plugins/qmldesigner/designercore/rewriter/basetexteditmodifier.cpp b/src/plugins/qmldesigner/textmodifier/basetexteditmodifier.cpp similarity index 100% rename from src/plugins/qmldesigner/designercore/rewriter/basetexteditmodifier.cpp rename to src/plugins/qmldesigner/textmodifier/basetexteditmodifier.cpp diff --git a/src/plugins/qmldesigner/designercore/include/basetexteditmodifier.h b/src/plugins/qmldesigner/textmodifier/basetexteditmodifier.h similarity index 84% rename from src/plugins/qmldesigner/designercore/include/basetexteditmodifier.h rename to src/plugins/qmldesigner/textmodifier/basetexteditmodifier.h index 23b8dc30bda..e5dde2f72bf 100644 --- a/src/plugins/qmldesigner/designercore/include/basetexteditmodifier.h +++ b/src/plugins/qmldesigner/textmodifier/basetexteditmodifier.h @@ -3,8 +3,9 @@ #pragma once -#include "qmldesignercorelib_global.h" -#include "plaintexteditmodifier.h" +#include + +#include #include @@ -14,7 +15,7 @@ namespace QmlJS { class Snapshot; } namespace QmlDesigner { -class QMLDESIGNERCORE_EXPORT BaseTextEditModifier: public PlainTextEditModifier +class QMLDESIGNER_EXPORT BaseTextEditModifier : public PlainTextEditModifier { public: BaseTextEditModifier(TextEditor::TextEditorWidget *textEdit); diff --git a/src/plugins/qmldesigner/textmodifier/indentingtexteditormodifier.cpp b/src/plugins/qmldesigner/textmodifier/indentingtexteditormodifier.cpp new file mode 100644 index 00000000000..f0f80200ac9 --- /dev/null +++ b/src/plugins/qmldesigner/textmodifier/indentingtexteditormodifier.cpp @@ -0,0 +1,36 @@ +// 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 "indentingtexteditormodifier.h" + +#include +#include +#include + +namespace QmlDesigner { + +IndentingTextEditModifier::IndentingTextEditModifier(QTextDocument *document, + const QTextCursor &textCursor) + : NotIndentingTextEditModifier{document, textCursor} +{ + m_tabSettings = QmlJSTools::QmlJSToolsSettings::globalCodeStyle()->tabSettings(); +} + +void IndentingTextEditModifier::indent(int offset, int length) +{ + if (length == 0 || offset < 0 || offset + length >= text().length()) + return; + + int startLine = getLineInDocument(textDocument(), offset); + int endLine = getLineInDocument(textDocument(), offset + length); + + if (startLine > -1 && endLine > -1) + indentLines(startLine, endLine); +} + +void IndentingTextEditModifier::indentLines(int startLine, int endLine) +{ + QmlJSEditor::indentQmlJs(textDocument(), startLine, endLine, m_tabSettings); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/textmodifier/indentingtexteditormodifier.h b/src/plugins/qmldesigner/textmodifier/indentingtexteditormodifier.h new file mode 100644 index 00000000000..5e55d7726a1 --- /dev/null +++ b/src/plugins/qmldesigner/textmodifier/indentingtexteditormodifier.h @@ -0,0 +1,19 @@ +// 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 + +#include + +namespace QmlDesigner { + +class QMLDESIGNER_EXPORT IndentingTextEditModifier : public NotIndentingTextEditModifier +{ +public: + IndentingTextEditModifier(QTextDocument *document, const QTextCursor &textCursor); + + void indent(int offset, int length) override; + void indentLines(int startLine, int endLine) override; +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesignerbase/CMakeLists.txt b/src/plugins/qmldesignerbase/CMakeLists.txt index 40fe8bbb134..2cee711a35c 100644 --- a/src/plugins/qmldesignerbase/CMakeLists.txt +++ b/src/plugins/qmldesignerbase/CMakeLists.txt @@ -8,10 +8,20 @@ env_with_default("QDS_ENABLE_COMPILE_WARNING_AS_ERROR" ENV_ENABLE_COMPILE_WARNIN option(ENABLE_COMPILE_WARNING_AS_ERROR "Treat warnings as errors in QmlDesigner" ${ENV_ENABLE_COMPILE_WARNING_AS_ERROR}) add_feature_info("Treat warnings as errors in QmlDesigner" ${ENABLE_COMPILE_WARNING_AS_ERROR} "") +add_qtc_library(QmlDesignerSettings STATIC + DEPENDS Utils + PUBLIC_INCLUDES settings + SOURCES_PREFIX settings + SOURCES + qmldesignersettings_global.h + designersettings.cpp designersettings.h +) + add_qtc_plugin(QmlDesignerBase CONDITION TARGET Qt::QuickWidgets DEPENDS Qt::Core Qt::QuickWidgets PLUGIN_DEPENDS Core ProjectExplorer QtSupport + PUBLIC_INCLUDES settings SOURCES qmldesignerbase_global.h qmldesignerbaseplugin.cpp qmldesignerbaseplugin.h @@ -23,21 +33,31 @@ extend_qtc_plugin(QmlDesignerBase ) extend_qtc_plugin(QmlDesignerBase - PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/utils - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/utils + PUBLIC_INCLUDES utils + SOURCES_PREFIX utils SOURCES designerpaths.cpp designerpaths.h - designersettings.cpp designersettings.h qmlpuppetpaths.cpp qmlpuppetpaths.h windowmanager.cpp windowmanager.h ) extend_qtc_plugin(QmlDesignerBase - PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR}/studio - SOURCES_PREFIX ${CMAKE_CURRENT_LIST_DIR}/studio + PUBLIC_INCLUDES studio + SOURCES_PREFIX studio SOURCES studiostyle.cpp studiostyle.h studiostyle_p.cpp studiostyle_p.h studioquickwidget.cpp studioquickwidget.h studiosettingspage.cpp studiosettingspage.h ) + + +# from cmake 3.24 $ is supported which can be added to DEPENDS +if (MSVC) + qtc_output_binary_dir(_output_binary_dir) + set_target_properties(QmlDesignerBase PROPERTIES LINK_FLAGS "/WHOLEARCHIVE:${_output_binary_dir}/${IDE_BIN_PATH}/QmlDesignerSettings.lib") +elseif (APPLE) + target_link_libraries(QmlDesignerBase PRIVATE -Wl,-force_load $) +else () + target_link_libraries(QmlDesignerBase PRIVATE -Wl,--whole-archive $ -Wl,--no-whole-archive) +endif () diff --git a/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp b/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp index e024de6761c..ec3b47063a2 100644 --- a/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp +++ b/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp @@ -6,7 +6,8 @@ #include "studio/studiosettingspage.h" #include "studio/studiostyle.h" -#include "utils/designersettings.h" + +#include #include #include diff --git a/src/plugins/qmldesignerbase/utils/designersettings.cpp b/src/plugins/qmldesignerbase/settings/designersettings.cpp similarity index 100% rename from src/plugins/qmldesignerbase/utils/designersettings.cpp rename to src/plugins/qmldesignerbase/settings/designersettings.cpp diff --git a/src/plugins/qmldesignerbase/utils/designersettings.h b/src/plugins/qmldesignerbase/settings/designersettings.h similarity index 98% rename from src/plugins/qmldesignerbase/utils/designersettings.h rename to src/plugins/qmldesignerbase/settings/designersettings.h index 7bb82555fc5..d93495e608d 100644 --- a/src/plugins/qmldesignerbase/utils/designersettings.h +++ b/src/plugins/qmldesignerbase/settings/designersettings.h @@ -3,7 +3,7 @@ #pragma once -#include "../qmldesignerbase_global.h" +#include "qmldesignersettings_global.h" #include #include @@ -70,7 +70,7 @@ inline constexpr char DOWNLOADABLE_BUNDLES_URL[] = "DownloadableBundlesLocation" inline constexpr char CONTENT_LIBRARY_NEW_FLAG_EXPIRATION_DAYS[] = "ContentLibraryNewFlagExpirationInDays"; } -class QMLDESIGNERBASE_EXPORT DesignerSettings +class QMLDESIGNERSETTINGS_EXPORT DesignerSettings { public: DesignerSettings(Utils::QtcSettings *settings); diff --git a/src/plugins/qmldesignerbase/settings/qmldesignersettings_global.h b/src/plugins/qmldesignerbase/settings/qmldesignersettings_global.h new file mode 100644 index 00000000000..6bf51a6618a --- /dev/null +++ b/src/plugins/qmldesignerbase/settings/qmldesignersettings_global.h @@ -0,0 +1,14 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +#if defined(QMLDESIGNERSETTINGS_LIBRARY) +# define QMLDESIGNERSETTINGS_EXPORT Q_DECL_EXPORT +#elif defined(QMLDESIGNERSETTINGS_STATIC_LIBRARY) +# define QMLDESIGNERSETTINGS_EXPORT +#else +# define QMLDESIGNERSETTINGS_EXPORT Q_DECL_IMPORT +#endif diff --git a/src/plugins/qmlprojectmanager/CMakeLists.txt b/src/plugins/qmlprojectmanager/CMakeLists.txt index 73dd37d8289..5e237cccc89 100644 --- a/src/plugins/qmlprojectmanager/CMakeLists.txt +++ b/src/plugins/qmlprojectmanager/CMakeLists.txt @@ -58,7 +58,7 @@ add_qtc_library(QmlProjectManagerLib OBJECT EXCLUDE_FROM_INSTALL DEFINES QMLPROJECTMANAGER_STATIC_LIBRARY DEPENDS - QmlJS Utils ProjectExplorer + QmlJS Utils INCLUDES ${CMAKE_CURRENT_LIST_DIR} SOURCES diff --git a/src/plugins/saferenderer/CMakeLists.txt b/src/plugins/saferenderer/CMakeLists.txt index 739332de42d..1a0928c8528 100644 --- a/src/plugins/saferenderer/CMakeLists.txt +++ b/src/plugins/saferenderer/CMakeLists.txt @@ -1,5 +1,5 @@ add_qtc_plugin(SafeRenderer - DEPENDS + PLUGIN_DEPENDS QtCreator::Core QtCreator::ProjectExplorer SOURCES saferenderer.qrc diff --git a/src/plugins/studiowelcome/examplecheckout.cpp b/src/plugins/studiowelcome/examplecheckout.cpp index ea3b964c8c0..940d7442cf5 100644 --- a/src/plugins/studiowelcome/examplecheckout.cpp +++ b/src/plugins/studiowelcome/examplecheckout.cpp @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include diff --git a/src/plugins/studiowelcome/examplecheckout.h b/src/plugins/studiowelcome/examplecheckout.h index 4726796bfe2..622f4b08f36 100644 --- a/src/plugins/studiowelcome/examplecheckout.h +++ b/src/plugins/studiowelcome/examplecheckout.h @@ -3,8 +3,8 @@ #pragma once +#include #include -#include #include #include diff --git a/tests/auto/qml/qmldesigner/CMakeLists.txt b/tests/auto/qml/qmldesigner/CMakeLists.txt index c03e09799e8..aa53dbf9fd4 100644 --- a/tests/auto/qml/qmldesigner/CMakeLists.txt +++ b/tests/auto/qml/qmldesigner/CMakeLists.txt @@ -1,2 +1,2 @@ -add_subdirectory(coretests) +# add_subdirectory(coretests) # add_subdirectory(wizard) diff --git a/tests/auto/qml/qmldesigner/coretests/CMakeLists.txt b/tests/auto/qml/qmldesigner/coretests/CMakeLists.txt index 7cb456d03fc..000a92054c5 100644 --- a/tests/auto/qml/qmldesigner/coretests/CMakeLists.txt +++ b/tests/auto/qml/qmldesigner/coretests/CMakeLists.txt @@ -7,6 +7,7 @@ add_qtc_test(tst_qml_testcore QmlDesignerCore Qt::Widgets Qt::Qml + QmlJSTools DEFINES QT_CREATOR IDE_PLUGIN_PATH="${PROJECT_BINARY_DIR}/${IDE_PLUGIN_PATH}" diff --git a/tests/unit/tests/CMakeLists.txt b/tests/unit/tests/CMakeLists.txt index bd7ec6ce3d6..811a9e8f3a5 100644 --- a/tests/unit/tests/CMakeLists.txt +++ b/tests/unit/tests/CMakeLists.txt @@ -6,12 +6,13 @@ elseif (MINGW) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj") endif() -set(QtCreatorLibsDir "${QtCreator_SOURCE_DIR}/src/libs") -set(QtCreatorPluginsDir "${QtCreator_SOURCE_DIR}/src/plugins") +set(QT_CREATOR_LIBS_DIRECTORY "${QtCreator_SOURCE_DIR}/src/libs") +set(QT_CREATOR_PLUGINS_DIRECTORY "${QtCreator_SOURCE_DIR}/src/plugins") set(QtCreatorResourcesDir "${QtCreator_SOURCE_DIR}/share/qtcreator") -set(QmlDesignerDir "${QtCreatorPluginsDir}/qmldesigner") +set(QML_DESIGNER_DIRECTORY "${QT_CREATOR_PLUGINS_DIRECTORY}/qmldesigner") +set(QML_DESIGNER_CORE_DIRECTORY "${QML_DESIGNER_DIRECTORY}/libs/designercore") -set(UnittestStubsDir "${CMAKE_CURRENT_SOURCE_DIR}/stubs") +set(UNITTEST_STUB_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/stubs") set(UnittestUtilsDir "${CMAKE_CURRENT_SOURCE_DIR}/utils") set(UnittestPrintersDir "${CMAKE_CURRENT_SOURCE_DIR}/printers") diff --git a/tests/unit/tests/mocks/externaldependenciesmock.h b/tests/unit/tests/mocks/externaldependenciesmock.h index f7375af2a3d..bcb4a4a896e 100644 --- a/tests/unit/tests/mocks/externaldependenciesmock.h +++ b/tests/unit/tests/mocks/externaldependenciesmock.h @@ -42,4 +42,5 @@ public: MOCK_METHOD(QString, qtQuickVersion, (), (const, override)); MOCK_METHOD(Utils::FilePath, resourcePath, (const QString &relativePath), (const, override)); MOCK_METHOD(QString, userResourcePath, (QStringView relativePath), (const, override)); + MOCK_METHOD(QWidget *, mainWindow, (), (const, override)); }; diff --git a/tests/unit/tests/printers/gtest-creator-printing.h b/tests/unit/tests/printers/gtest-creator-printing.h index 8ca7595d0c5..23c76832974 100644 --- a/tests/unit/tests/printers/gtest-creator-printing.h +++ b/tests/unit/tests/printers/gtest-creator-printing.h @@ -3,7 +3,7 @@ #pragma once -#include +#include #include #include #include diff --git a/tests/unit/tests/stubs/clangcodemodel/clangcompletionassistinterface.h b/tests/unit/tests/stubs/clangcodemodel/clangcompletionassistinterface.h deleted file mode 100644 index 06f3e9033d7..00000000000 --- a/tests/unit/tests/stubs/clangcodemodel/clangcompletionassistinterface.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -#include - -namespace ClangCodeModel { -namespace Internal { - -enum class CompletionType { FunctionHint, Other }; - -class ClangCompletionAssistInterface: public TextEditor::AssistInterface -{ -public: - ClangCompletionAssistInterface(const QByteArray &text, - int position) - : TextEditor::AssistInterface(text, position), - languageFeatures_(CPlusPlus::LanguageFeatures::defaultFeatures()) - {} - - CompletionType type() const { return CompletionType::Other; } - CPlusPlus::LanguageFeatures languageFeatures() const { return languageFeatures_; } - -private: - CPlusPlus::LanguageFeatures languageFeatures_; -}; - -} // namespace Internal -} // namespace ClangCodeModel diff --git a/tests/unit/tests/stubs/qmldesigner/designercore/include/documentmessage.h b/tests/unit/tests/stubs/qmldesigner/designercore/include/documentmessage.h deleted file mode 100644 index b1b2ff846c2..00000000000 --- a/tests/unit/tests/stubs/qmldesigner/designercore/include/documentmessage.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include "exception.h" - -#include - -#include -#include - -namespace QmlJS { -class DiagnosticMessage; -} - -namespace QmlDesigner { - -class DocumentMessage -{ -public: - enum Type { NoError = 0, InternalError = 1, ParseError = 2 }; - -public: - DocumentMessage() {} - DocumentMessage(const QString &) {} - - Type type() const { return m_type; } - - int line() const { return m_line; } - - int column() const { return m_column; } - - QString description() const { return m_description; } - - QUrl url() const { return m_url; } - - QString toString() const { return {}; } - -private: - Type m_type; - int m_line; - int m_column; - QString m_description; - QUrl m_url; -}; - -} // namespace QmlDesigner diff --git a/tests/unit/tests/stubs/qmldesigner/designercore/include/itemlibraryitem.h b/tests/unit/tests/stubs/qmldesigner/designercore/include/itemlibraryitem.h deleted file mode 100644 index e1aad8da1ce..00000000000 --- a/tests/unit/tests/stubs/qmldesigner/designercore/include/itemlibraryitem.h +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include -#include -#include -#include - -#include "itemlibraryinfo.h" - -namespace QmlDesigner { - -class ItemLibraryItem : public QObject -{ - Q_OBJECT - - Q_PROPERTY(QVariant itemLibraryEntry READ itemLibraryEntry FINAL) - Q_PROPERTY(QString itemName READ itemName FINAL) - Q_PROPERTY(QString itemLibraryIconPath READ itemLibraryIconPath FINAL) - Q_PROPERTY(bool itemVisible READ isVisible NOTIFY visibilityChanged FINAL) - -public: - ItemLibraryItem(QObject *) {} - ~ItemLibraryItem() override {} - - QString itemName() const { return {}; } - QString typeName() const { return {}; } - QString itemLibraryIconPath() const { return {}; } - - bool setVisible(bool) { return {}; } - bool isVisible() const { return {}; } - - void setItemLibraryEntry(const ItemLibraryEntry &) {} - QVariant itemLibraryEntry() const { return {}; } - -signals: - void visibilityChanged(); -}; - -} // namespace QmlDesigner diff --git a/tests/unit/tests/stubs/qmldesigner/designercore/include/nodeinstanceview.h b/tests/unit/tests/stubs/qmldesigner/designercore/include/nodeinstanceview.h deleted file mode 100644 index 6fa68c3fac9..00000000000 --- a/tests/unit/tests/stubs/qmldesigner/designercore/include/nodeinstanceview.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include "qmldesignercorelib_global.h" -#include "abstractview.h" - -namespace ProjectExplorer { -class Target; -} - -namespace QmlDesigner { - -class NodeInstanceView : public AbstractView -{ - Q_OBJECT - -public: - NodeInstanceView(ExternalDependenciesInterface &externalDependencies) - : AbstractView{externalDependencies} - {} - ~NodeInstanceView() override {} - - void modelAttached([[maybe_unused]] Model *model) override {} - void modelAboutToBeDetached([[maybe_unused]] Model *model) override {} - void nodeCreated([[maybe_unused]] const ModelNode &createdNode) override {} - void nodeRemoved([[maybe_unused]] const ModelNode &removedNode, - [[maybe_unused]] const NodeAbstractProperty &parentProperty, - [[maybe_unused]] PropertyChangeFlags propertyChange) override - {} - void propertiesAboutToBeRemoved([[maybe_unused]] const QList &propertyList) override - {} - void propertiesRemoved([[maybe_unused]] const QList &propertyList) override {} - void variantPropertiesChanged([[maybe_unused]] const QList &propertyList, - [[maybe_unused]] PropertyChangeFlags propertyChange) override - {} - void bindingPropertiesChanged([[maybe_unused]] const QList &propertyList, - [[maybe_unused]] PropertyChangeFlags propertyChange) override - {} - void signalHandlerPropertiesChanged([[maybe_unused]] const QVector &propertyList, - [[maybe_unused]] PropertyChangeFlags propertyChange) override - {} - void nodeReparented([[maybe_unused]] const ModelNode &node, - [[maybe_unused]] const NodeAbstractProperty &newPropertyParent, - [[maybe_unused]] const NodeAbstractProperty &oldPropertyParent, - [[maybe_unused]] AbstractView::PropertyChangeFlags propertyChange) override - {} - void nodeIdChanged([[maybe_unused]] const ModelNode &node, - [[maybe_unused]] const QString &newId, - [[maybe_unused]] const QString &oldId) override - {} - void nodeOrderChanged([[maybe_unused]] const NodeListProperty &listProperty) override {} - void rootNodeTypeChanged([[maybe_unused]] const QString &type, - [[maybe_unused]] int majorVersion, - [[maybe_unused]] int minorVersion) override - {} - void nodeTypeChanged([[maybe_unused]] const ModelNode &node, - [[maybe_unused]] const TypeName &type, - [[maybe_unused]] int majorVersion, - [[maybe_unused]] int minorVersion) override - {} - void customNotification([[maybe_unused]] const AbstractView *view, - [[maybe_unused]] const QString &identifier, - [[maybe_unused]] const QList &nodeList, - [[maybe_unused]] const QList &data) override - {} - - void rewriterBeginTransaction() override {} - void rewriterEndTransaction() override {} - - void importsChanged([[maybe_unused]] const QList &addedImports, - [[maybe_unused]] const QList &removedImports) override - {} - - void requestModelNodePreviewImage([[maybe_unused]] const ModelNode &node) {} - - void sendToken([[maybe_unused]] const QString &token, - [[maybe_unused]] int number, - [[maybe_unused]] const QVector &nodeVector) - {} - void setTarget([[maybe_unused]] ProjectExplorer::Target *newTarget) {} - void setCrashCallback(std::function) {} -}; - -} // namespace QmlDesigner diff --git a/tests/unit/tests/stubs/qmldesigner/designercore/include/qmlmodelnodefacade.h b/tests/unit/tests/stubs/qmldesigner/designercore/include/qmlmodelnodefacade.h deleted file mode 100644 index 32a980e011f..00000000000 --- a/tests/unit/tests/stubs/qmldesigner/designercore/include/qmlmodelnodefacade.h +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include -#include - -namespace QmlDesigner { - -class AbstractView; -class NodeInstanceView; - -class QmlModelNodeFacade -{ -public: - operator ModelNode() const { return {}; } - ModelNode modelNode() { return {}; } - const ModelNode modelNode() const { return {}; } - bool hasModelNode() const { return {}; } - static bool isValidQmlModelNodeFacade([[maybe_unused]] const ModelNode &modelNode) - { - return {}; - } - virtual bool isValid() const { return {}; } - - AbstractView *view() const { return {}; } - static NodeInstanceView *nodeInstanceView([[maybe_unused]] const ModelNode &modelNode) - { - return {}; - } - NodeInstanceView *nodeInstanceView() const { return {}; } - bool isRootNode() const { return {}; } - - QmlModelNodeFacade(const ModelNode &) {} - QmlModelNodeFacade() {} - ~QmlModelNodeFacade(){}; -}; - -} // namespace QmlDesigner diff --git a/tests/unit/tests/stubs/qmldesigner/designercore/include/qmlobjectnode.h b/tests/unit/tests/stubs/qmldesigner/designercore/include/qmlobjectnode.h deleted file mode 100644 index 3b4b3231062..00000000000 --- a/tests/unit/tests/stubs/qmldesigner/designercore/include/qmlobjectnode.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include "qmlmodelnodefacade.h" -#include - -#include - -namespace QmlDesigner { - -class QMLDESIGNERCORE_EXPORT QmlObjectNode : public QmlModelNodeFacade -{ -public: - QmlObjectNode() {} - QmlObjectNode([[maybe_unused]] const ModelNode &modelNode){}; -}; - -} // namespace QmlDesigner diff --git a/tests/unit/tests/stubs/qmldesigner/designercore/include/qmlstate.h b/tests/unit/tests/stubs/qmldesigner/designercore/include/qmlstate.h deleted file mode 100644 index b2b6f81d337..00000000000 --- a/tests/unit/tests/stubs/qmldesigner/designercore/include/qmlstate.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include "qmlmodelnodefacade.h" - -namespace QmlDesigner { - -class QmlModelState : public QmlModelNodeFacade -{ -public: - QmlModelState(); - QmlModelState(const ModelNode &) {} -}; - -} // namespace QmlDesigner diff --git a/tests/unit/tests/stubs/qmldesigner/designercore/include/qmltimeline.h b/tests/unit/tests/stubs/qmldesigner/designercore/include/qmltimeline.h deleted file mode 100644 index f8f3c16f018..00000000000 --- a/tests/unit/tests/stubs/qmldesigner/designercore/include/qmltimeline.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include "qmlmodelnodefacade.h" -#include - -namespace QmlDesigner { - -class QmlTimeline : public QmlModelNodeFacade -{ -public: - QmlTimeline() {} - QmlTimeline(const ModelNode &) {} - - bool isValid() const override { return {}; } - - void toogleRecording(bool) const {} - - void resetGroupRecording() const {} -}; - -} // namespace QmlDesigner diff --git a/tests/unit/tests/stubs/qmldesigner/designercore/include/rewriterview.h b/tests/unit/tests/stubs/qmldesigner/designercore/include/rewriterview.h deleted file mode 100644 index 4c59440b0f8..00000000000 --- a/tests/unit/tests/stubs/qmldesigner/designercore/include/rewriterview.h +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include "qmldesignercorelib_global.h" -#include "abstractview.h" - -namespace QmlJS { -class Document; -class ScopeChain; -} - -namespace QmlDesigner { - -class TextModifier; - -namespace Internal { - -class TextToModelMerger; -class ModelToTextMerger; -class ModelNodePositionStorage; - -} //Internal - -struct CppTypeData -{ - QString superClassName; - QString importUrl; - QString versionString; - QString cppClassName; - QString typeName; - bool isSingleton = false; -}; - -class RewriterView : public AbstractView -{ - Q_OBJECT - -public: - enum DifferenceHandling { - Validate, - Amend - }; - -public: - RewriterView(DifferenceHandling, ExternalDependenciesInterface &externalDependencies) - : AbstractView{externalDependencies} - {} - ~RewriterView() override {} - - void modelAttached(Model *) override {} - void modelAboutToBeDetached(Model *) override {} - void nodeCreated(const ModelNode &) override {} - void nodeRemoved(const ModelNode &, const NodeAbstractProperty &, PropertyChangeFlags) override - {} - void propertiesAboutToBeRemoved(const QList &) override {} - void propertiesRemoved(const QList &) override {} - void variantPropertiesChanged(const QList &, PropertyChangeFlags) override {} - void bindingPropertiesChanged(const QList &, PropertyChangeFlags) override {} - void signalHandlerPropertiesChanged(const QVector &, - PropertyChangeFlags) override - {} - void nodeReparented(const ModelNode &, - const NodeAbstractProperty &, - const NodeAbstractProperty &, - AbstractView::PropertyChangeFlags) override - {} - void nodeIdChanged(const ModelNode &, const QString &, const QString &) override {} - void nodeOrderChanged(const NodeListProperty &) override {} - void rootNodeTypeChanged(const QString &, int, int) override {} - void nodeTypeChanged(const ModelNode &, const TypeName &, int, int) override {} - void customNotification(const AbstractView *, - const QString &, - const QList &, - const QList &) override - {} - - void rewriterBeginTransaction() override {} - void rewriterEndTransaction() override {} - - void importsChanged(const QList &, const QList &) override {} - - TextModifier *textModifier() const { return {}; } - void setTextModifier(TextModifier *) {} - QString textModifierContent() const { return {}; } - - void reactivateTextMofifierChangeSignals() {} - void deactivateTextMofifierChangeSignals() {} - - void auxiliaryDataChanged([[maybe_unused]] const ModelNode &node, - [[maybe_unused]] AuxiliaryDataKeyView key, - [[maybe_unused]] const QVariant &data) override - {} - - Internal::ModelNodePositionStorage *positionStorage() const { return nullptr; } - - QList warnings() const { return {}; } - QList errors() const { return {}; } - void clearErrorAndWarnings() {} - void setErrors(const QList &) {} - void setWarnings(const QList &) {} - void setIncompleteTypeInformation(bool) {} - bool hasIncompleteTypeInformation() const { return false; } - void addError(const DocumentMessage &) {} - - void enterErrorState(const QString &) {} - bool inErrorState() const { return false; } - void leaveErrorState() {} - void resetToLastCorrectQml() {} - - QMap extractText(const QList &) const; - int nodeOffset(const ModelNode &) const; - int nodeLength(const ModelNode &) const; - int firstDefinitionInsideOffset(const ModelNode &) const { return {}; } - int firstDefinitionInsideLength(const ModelNode &) const { return {}; } - bool modificationGroupActive() { return {}; } - ModelNode nodeAtTextCursorPosition(int) const { return {}; } - - bool renameId(const QString &, const QString &) { return {}; } - - const QmlJS::Document *document() const { return {}; } - const QmlJS::ScopeChain *scopeChain() const { return {}; } - - QString convertTypeToImportAlias(const QString &) const { return {}; } - - bool checkSemanticErrors() const { return {}; } - - void setCheckSemanticErrors(bool) {} - - QStringList importDirectories() const { return {}; } - - QSet> qrcMapping() const { return {}; } - - void moveToComponent(const ModelNode &) {} - - QStringList autoComplete(const QString &, int, bool = true) { return {}; } - - QList getCppTypes() { return {}; } - - void setWidgetStatusCallback(std::function setWidgetStatusCallback); - - void qmlTextChanged() {} - void delayedSetup() {} - - void writeAuxiliaryData() {} - void restoreAuxiliaryData() {} - - QString getRawAuxiliaryData() const { return {}; } - QString auxiliaryDataAsQML() const { return {}; } - - ModelNode getNodeForCanonicalIndex(int) { return {}; } -}; - -} //QmlDesigner diff --git a/tests/unit/tests/testdesignercore/CMakeLists.txt b/tests/unit/tests/testdesignercore/CMakeLists.txt index 691b6723932..269029a20f6 100644 --- a/tests/unit/tests/testdesignercore/CMakeLists.txt +++ b/tests/unit/tests/testdesignercore/CMakeLists.txt @@ -1,24 +1,36 @@ add_qtc_library(TestDesignerCore OBJECT + CONDITION TARGET TextEditorSupport EXCLUDE_FROM_INSTALL PUBLIC_INCLUDES ${CMAKE_CURRENT_LIST_DIR} PROPERTIES SKIP_AUTOGEN ON DEPENDS - Qt::Core Qt::Network Qt::Widgets - Qt::Xml Qt::Concurrent Qt::QmlPrivate Qt::Gui - Qt::Core5Compat Utils QmlJS Sqlite + Utils + Qt::Widgets + Qt::Qml + Qt::QmlPrivate + Qt6::QmlDomPrivate + Qt6::QmlCompilerPrivate + QmlJS PUBLIC_DEPENDS + Threads::Threads + Qt::Quick QmlPuppetCommunication - SOURCES_PREFIX ${QmlDesignerDir}/designercore + QmlDesignerUtils + Sqlite + QmlDesignerSettings + TextEditorSupport + SOURCES_PREFIX ${QML_DESIGNER_DIRECTORY}/libs/designercore PUBLIC_INCLUDES - ${UnittestStubsDir} - ${UnittestStubsDir}/qmldesigner/designercore/include - ${QtCreatorLibsDir} - ${QtCreatorPluginsDir} - ${QmlDesignerDir} - ${QmlDesignerDir}/designercore - ${QmlDesignerDir}/designercore/include - ${QmlDesignerDir}/designercore/imagecache - ${QmlDesignerDir}/designercore/designercoreutils + ${UNITTEST_STUB_DIRECTORY} + ${UNITTEST_STUB_DIRECTORY}/qmldesigner/libs/designercore/include + ${QT_CREATOR_LIBS_DIRECTORY} + ${QT_CREATOR_PLUGINS_DIRECTORY} + ${QML_DESIGNER_DIRECTORY} + ${QML_DESIGNER_DIRECTORY}/libs + ${QML_DESIGNER_CORE_DIRECTORY} + ${QML_DESIGNER_CORE_DIRECTORY}/include + ${QML_DESIGNER_CORE_DIRECTORY}/imagecache + ${QML_DESIGNER_CORE_DIRECTORY}/designercoreutils PUBLIC_DEFINES UNIT_TESTS DONT_CHECK_MESSAGE_COUNTER @@ -27,150 +39,338 @@ add_qtc_library(TestDesignerCore OBJECT QDS_USE_PROJECTSTORAGE QMLDESIGNERCORE_STATIC_LIBRARY QMLDESIGNER_STATIC_LIBRARY - SOURCES - exceptions/exception.cpp - exceptions/invalidargumentexception.cpp - exceptions/invalididexception.cpp - exceptions/invalidmetainfoexception.cpp - exceptions/invalidmodelnodeexception.cpp - exceptions/invalidmodelstateexception.cpp - exceptions/invalidpropertyexception.cpp - exceptions/invalidqmlsourceexception.cpp - exceptions/invalidreparentingexception.cpp - exceptions/invalidslideindexexception.cpp - exceptions/notimplementedexception.cpp - exceptions/removebasestateexception.cpp - exceptions/rewritingexception.cpp - imagecache/asynchronousexplicitimagecache.cpp - imagecache/asynchronousimagecache.cpp - imagecache/asynchronousimagefactory.cpp - imagecache/asynchronousimagefactory.h - imagecache/imagecachecollectorinterface.h - imagecache/imagecachegenerator.cpp - imagecache/imagecachegenerator.h - imagecache/imagecachegeneratorinterface.h - imagecache/imagecachestorage.h - imagecache/imagecachedispatchcollector.h - imagecache/imagecachestorageinterface.h - imagecache/synchronousimagecache.cpp - imagecache/taskqueue.h - imagecache/timestampproviderinterface.h - include/abstractproperty.h - include/asynchronousexplicitimagecache.h - include/asynchronousimagecache.h - include/asynchronousimagecacheinterface.h - include/bindingproperty.h - include/imagecacheauxiliarydata.h - include/import.h - include/itemlibraryentry.h - include/modelnode.h - include/module.h - include/nodeabstractproperty.h - include/nodelistproperty.h - include/nodemetainfo.h - include/nodeproperty.h - include/projectstorageids.h - include/propertymetainfo.h - include/propertycontainer.h - include/propertyparser.h - include/qmldesignercorelib_global.h - include/signalhandlerproperty.h - include/synchronousimagecache.h - include/variantproperty.h - metainfo/itemlibraryentry.cpp - metainfo/nodemetainfo.cpp - model/abstractproperty.cpp - model/abstractview.cpp - model/auxiliarypropertystorageview.cpp model/auxiliarypropertystorageview.h - model/annotation.cpp - model/bindingproperty.cpp - model/import.cpp - model/internalbindingproperty.cpp - model/internalbindingproperty.h - model/internalnode.cpp - model/internalnode_p.h - model/internalnodeabstractproperty.cpp - model/internalnodeabstractproperty.h - model/internalnodelistproperty.cpp - model/internalnodelistproperty.h - model/internalnodeproperty.cpp - model/internalnodeproperty.h - model/internalproperty.cpp - model/internalproperty.h - model/internalsignalhandlerproperty.cpp - model/internalsignalhandlerproperty.h - model/internalvariantproperty.cpp - model/internalvariantproperty.h - model/model.cpp - model/model_p.h - model/modelnode.cpp - model/modelresourcemanagementinterface.h - model/modelresourcemanagement.cpp model/modelresourcemanagement.h - designercoreutils/modelutils.cpp designercoreutils/modelutils.h - rewriter/propertycontainer.cpp - rewriter/propertyparser.cpp - model/nodeabstractproperty.cpp - model/nodelistproperty.cpp - model/nodeproperty.cpp - model/signalhandlerproperty.cpp - model/variantproperty.cpp - pluginmanager/widgetpluginmanager.h pluginmanager/widgetpluginmanager.cpp - pluginmanager/widgetpluginpath.h pluginmanager/widgetpluginpath.cpp - projectstorage/directorypathcompressor.h - projectstorage/filesysteminterface.h - projectstorage/filesystem.cpp projectstorage/filesystem.h - projectstorage/filestatus.h - projectstorage/filestatuscache.cpp projectstorage/filestatuscache.h - projectstorage/modulescanner.cpp projectstorage/modulescanner.h - sourcepathstorage/nonlockingmutex.h - projectstorage/projectstorageexceptions.cpp projectstorage/projectstorageexceptions.h - projectstorage/projectstorageinterface.h - projectstorage/projectstorageobserver.h - projectstorage/projectstorage.cpp projectstorage/projectstorage.h - projectstorage/projectstorageerrornotifierinterface.h - projectstorage/projectstorageerrornotifier.cpp projectstorage/projectstorageerrornotifier.h - projectstorage/projectstoragepathwatcher.h - projectstorage/projectstoragepathwatcherinterface.h - projectstorage/projectstoragepathwatchernotifierinterface.h - projectstorage/projectstoragepathwatcher.h - projectstorage/projectstoragepathwatchertypes.h - projectstorage/projectstoragetypes.h - projectstorage/projectstorageupdater.cpp projectstorage/projectstorageupdater.h - sourcepathstorage/sourcepath.h - sourcepathstorage/sourcepathcache.h - sourcepathstorage/sourcepathcache.h - sourcepathstorage/sourcepathcachetypes.h - sourcepathstorage/sourcepathview.h - sourcepathstorage/storagecache.h - sourcepathstorage/storagecacheentry.h - sourcepathstorage/storagecachefwd.h - sourcepathstorage/sourcepathexceptions.cpp - sourcepathstorage/sourcepathexceptions.h - sourcepathstorage/sourcepathstorage.cpp - sourcepathstorage/sourcepathstorage.h - projectstorage/typeannotationreader.cpp - projectstorage/typeannotationreader.h - projectstorage/qmldocumentparserinterface.h - projectstorage/qmltypesparserinterface.h - tracing/qmldesignertracing.cpp tracing/qmldesignertracing.h - rewriter/rewritertransaction.cpp - include/rewritertransaction.h - designercoreutils/uniquename.cpp - designercoreutils/uniquename.h ) extend_qtc_library(TestDesignerCore - SOURCES_PREFIX ${QmlDesignerDir}/designercore/include - SOURCES_PROPERTIES AUTOMOC ON + CONDITION IS_SUPPORTED_PROJECTSTORAGE_QT + PUBLIC_DEFINES QDS_BUILD_QMLPARSER +) + +extend_qtc_library(TestDesignerCore + PUBLIC_INCLUDES ${QML_DESIGNER_CORE_DIRECTORY}/designercoreutils + SOURCES_PREFIX ${QML_DESIGNER_CORE_DIRECTORY}/designercoreutils + SOURCES + generatedcomponentutils.cpp + generatedcomponentutils.h + modelmerger.cpp + modelmerger.h + modelutils.cpp + modelutils.h + predicate.h + stylesheetmerger.cpp + stylesheetmerger.h + uniquename.cpp + uniquename.h +) + +extend_qtc_library(TestDesignerCore + INCLUDES ${QML_DESIGNER_CORE_DIRECTORY}/exceptions + SOURCES_PREFIX ${QML_DESIGNER_CORE_DIRECTORY}/exceptions + SOURCES + exception.cpp + invalidargumentexception.cpp + invalididexception.cpp + invalidmetainfoexception.cpp + invalidmodelnodeexception.cpp + invalidmodelstateexception.cpp + invalidpropertyexception.cpp + invalidqmlsourceexception.cpp + invalidreparentingexception.cpp + invalidslideindexexception.cpp + notimplementedexception.cpp + removebasestateexception.cpp + rewritingexception.cpp +) + +extend_qtc_library(TestDesignerCore + INCLUDES ${QML_DESIGNER_CORE_DIRECTORY}/filemanager + SOURCES_PREFIX ${QML_DESIGNER_CORE_DIRECTORY}/filemanager + SOURCES + addarraymembervisitor.cpp + addarraymembervisitor.h + addobjectvisitor.cpp + addobjectvisitor.h + addpropertyvisitor.cpp + addpropertyvisitor.h + astobjecttextextractor.cpp + astobjecttextextractor.h + changeimportsvisitor.cpp + changeimportsvisitor.h + changeobjecttypevisitor.cpp + changeobjecttypevisitor.h + changepropertyvisitor.cpp + changepropertyvisitor.h + firstdefinitionfinder.cpp + firstdefinitionfinder.h + moveobjectbeforeobjectvisitor.cpp + moveobjectbeforeobjectvisitor.h + moveobjectvisitor.cpp + moveobjectvisitor.h + objectlengthcalculator.cpp + objectlengthcalculator.h + qmlrefactoring.cpp + qmlrefactoring.h + qmlrewriter.cpp + qmlrewriter.h + removepropertyvisitor.cpp + removepropertyvisitor.h + removeuiobjectmembervisitor.cpp + removeuiobjectmembervisitor.h +) + +extend_qtc_library(TestDesignerCore + INCLUDES ${QML_DESIGNER_CORE_DIRECTORY}/imagecache + SOURCES_PREFIX ${QML_DESIGNER_CORE_DIRECTORY}/imagecache + SOURCES + asynchronousexplicitimagecache.cpp + asynchronousimagecache.cpp + asynchronousimagefactory.cpp + asynchronousimagefactory.h + explicitimagecacheimageprovider.cpp + explicitimagecacheimageprovider.h + imagecachecollectorinterface.h + imagecachedispatchcollector.h + imagecachegenerator.cpp + imagecachegenerator.h + imagecachegeneratorinterface.h + imagecacheimageresponse.cpp + imagecacheimageresponse.h + imagecachestorage.h + imagecachestorageinterface.h + midsizeimagecacheprovider.cpp + midsizeimagecacheprovider.h + smallimagecacheprovider.cpp + smallimagecacheprovider.h + synchronousimagecache.cpp + taskqueue.h + timestampprovider.cpp + timestampprovider.h + timestampproviderinterface.h +) + +extend_qtc_library(TestDesignerCore + SOURCES_PREFIX ${QML_DESIGNER_CORE_DIRECTORY}/tracing + SOURCES + qmldesignertracing.cpp qmldesignertracing.h +) + +extend_qtc_library(TestDesignerCore + SOURCES_PREFIX ${QML_DESIGNER_CORE_DIRECTORY}/include SOURCES - model.h abstractview.h + bytearraymodifier.h + componenttextmodifier.h + forwardview.h + itemlibraryentry.h + model.h + nodehints.h + plaintexteditmodifier.h + propertyparser.h + rewriterview.h + textmodifier.h ) extend_qtc_library(TestDesignerCore - SOURCES_PROPERTIES AUTOMOC ON - SOURCES_PREFIX ../stubs/qmldesigner/designercore/include + SOURCES_PROPERTIES SKIP_AUTOGEN ON + SOURCES_PREFIX ${QML_DESIGNER_CORE_DIRECTORY}/include SOURCES - nodeinstanceview.h - rewriterview.h + abstractproperty.h + annotation.h + asynchronousexplicitimagecache.h + asynchronousimagecache.h + asynchronousimagecacheinterface.h + auxiliarydata.h + auxiliarydataproperties.h + bindingproperty.h + bytearraymodifier.h + customnotificationpackage.h + customnotifications.h + documentmessage.h + enumerationmetainfo.h + exception.h + externaldependenciesinterface.h + imagecacheauxiliarydata.h + import.h + invalidargumentexception.h + invalididexception.h + invalidmetainfoexception.h + invalidmodelnodeexception.h + invalidmodelstateexception.h + invalidpropertyexception.h + invalidqmlsourceexception.h + invalidreparentingexception.h + invalidslideindexexception.h + iwidgetplugin.h + mathutils.h + modelfwd.h + modelnode.h + modificationgroupexception.h + modificationgrouptoken.h + module.h + nodeabstractproperty.h + nodelistproperty.h + nodemetainfo.h + nodeproperty.h + notimplementedexception.h + objectpropertybinding.h + projectstorageids.h + propertybinding.h + propertycontainer.h + propertymetainfo.h + propertynode.h + puppetstartdata.h + qmldesignercorelib_exports.h + qmldesignercorelib_global.h + qmldesignercoreconstants.h + removebasestateexception.h + rewritertransaction.h + rewritingexception.h + signalhandlerproperty.h + sourcepathids.h + stringutils.h + synchronousimagecache.h + variantproperty.h +) + +extend_qtc_library(TestDesignerCore + INCLUDES + metainfo + SOURCES_PREFIX ${QML_DESIGNER_CORE_DIRECTORY}/metainfo + DEFINES SHARE_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../../../../../share/qtcreator/qmldesigner" + SOURCES + itemlibraryentry.cpp + nodehints.cpp + nodemetainfo.cpp +) + +extend_qtc_library(TestDesignerCore + INCLUDES ${QML_DESIGNER_CORE_DIRECTORY}/model + SOURCES_PREFIX ${QML_DESIGNER_CORE_DIRECTORY}/model + SOURCES + abstractproperty.cpp + abstractview.cpp + annotation.cpp + auxiliarypropertystorageview.cpp auxiliarypropertystorageview.h + bindingproperty.cpp + documentmessage.cpp + import.cpp + internalbindingproperty.cpp + internalbindingproperty.h + internalnode.cpp + internalnode_p.h + internalnodeabstractproperty.cpp + internalnodeabstractproperty.h + internalnodelistproperty.cpp + internalnodelistproperty.h + internalnodeproperty.cpp + internalnodeproperty.h + internalproperty.cpp + internalproperty.h + internalsignalhandlerproperty.cpp + internalsignalhandlerproperty.h + internalvariantproperty.cpp + internalvariantproperty.h + model.cpp + model_p.h + modelnode.cpp + modelresourcemanagementinterface.h + modelresourcemanagementfwd.h + modelresourcemanagement.cpp modelresourcemanagement.h + nodeabstractproperty.cpp + nodelistproperty.cpp + nodeproperty.cpp + signalhandlerproperty.cpp + variantproperty.cpp +) + +extend_qtc_library(TestDesignerCore + INCLUDES ${QML_DESIGNER_CORE_DIRECTORY}/rewriter + SOURCES_PREFIX ${QML_DESIGNER_CORE_DIRECTORY}/rewriter + SOURCES + componenttextmodifier.cpp + modelnodepositionrecalculator.cpp + modelnodepositionrecalculator.h + modelnodepositionstorage.cpp + modelnodepositionstorage.h + modeltotextmerger.cpp + modeltotextmerger.h + plaintexteditmodifier.cpp + propertycontainer.cpp + propertynode.cpp + propertyparser.cpp + qmltextgenerator.cpp + qmltextgenerator.h + rewriteaction.cpp + rewriteaction.h + rewriteactioncompressor.cpp + rewriteactioncompressor.h + rewritertransaction.cpp + rewriterview.cpp + textmodifier.cpp + texttomodelmerger.cpp + texttomodelmerger.h +) + +extend_qtc_library(TestDesignerCore + INCLUDES ${QML_DESIGNER_CORE_DIRECTORY}/pluginmanager + SOURCES_PREFIX ${QML_DESIGNER_CORE_DIRECTORY}/pluginmanager + SOURCES + widgetpluginmanager.cpp + widgetpluginmanager.h + widgetpluginpath.cpp + widgetpluginpath.h +) + +extend_qtc_library(TestDesignerCore + SOURCES_PREFIX ${QML_DESIGNER_CORE_DIRECTORY}/sourcepathstorage + PUBLIC_INCLUDES ${QML_DESIGNER_CORE_DIRECTORY}/sourcepathstorage + SOURCES_PROPERTIES SKIP_AUTOGEN ON + SOURCES + nonlockingmutex.h + sourcepath.h + sourcepathcache.h + sourcepathcacheinterface.h + sourcepathcachetypes.h + sourcepathexceptions.cpp + sourcepathexceptions.h + sourcepathstorage.cpp + sourcepathstorage.h + sourcepathview.h + storagecache.h + storagecacheentry.h + storagecachefwd.h +) + +extend_qtc_library(TestDesignerCore + SOURCES_PREFIX ${QML_DESIGNER_CORE_DIRECTORY}/projectstorage + PUBLIC_INCLUDES ${QML_DESIGNER_CORE_DIRECTORY}/projectstorage + SOURCES_PROPERTIES SKIP_AUTOGEN ON + DEFINES QML_DOM_MSVC2019_COMPAT # can be removed for Qt 6.8 + SOURCES + commontypecache.h + directorypathcompressor.h + filesysteminterface.h + filesystem.cpp filesystem.h + filestatus.h + filestatuscache.cpp filestatuscache.h + modulescanner.cpp modulescanner.h + projectstorageexceptions.cpp projectstorageexceptions.h + projectstorageinterface.h + projectstoragefwd.h + projectstorageinfotypes.h + projectstorageobserver.h + projectstoragepathwatcher.h + projectstoragepathwatcherinterface.h + projectstoragepathwatchernotifierinterface.h + projectstoragepathwatcher.h + projectstoragepathwatchertypes.h + projectstorageprinting.h + projectstoragetypes.h + projectstorageupdater.cpp projectstorageupdater.h + projectstorage.cpp projectstorage.h + projectstorageerrornotifierinterface.h + projectstorageerrornotifier.cpp projectstorageerrornotifier.h + typeannotationreader.cpp typeannotationreader.h + qmldocumentparserinterface.h + qmltypesparserinterface.h ) diff --git a/tests/unit/tests/unittests/CMakeLists.txt b/tests/unit/tests/unittests/CMakeLists.txt index c1ad2c3a996..1aabede38f2 100644 --- a/tests/unit/tests/unittests/CMakeLists.txt +++ b/tests/unit/tests/unittests/CMakeLists.txt @@ -6,8 +6,8 @@ add_qtc_test(unittest GTEST PROPERTIES SKIP_AUTOGEN ON DEPENDS Qt::Core Qt::Network Qt::Widgets - Qt::Xml Qt::Concurrent Qt::QmlPrivate Qt::Gui - Qt::Core5Compat Utils QmlJS Sqlite + Qt::Xml Qt::Concurrent Qt::QmlPrivate Qt::Gui Qt::Quick + Qt::Core5Compat Utils QmlJS Sqlite QmlDesignerSettings TextEditorSupport Googletest TestDesignerCore TestUtils TestMatchers TestPrinters TestMocks DEFINES GTEST_INTERNAL_HAS_STRING_VIEW diff --git a/tests/unit/tests/unittests/designercoreutils/version-test.cpp b/tests/unit/tests/unittests/designercoreutils/version-test.cpp index 00fca5e8fb9..7ab6f46c891 100644 --- a/tests/unit/tests/unittests/designercoreutils/version-test.cpp +++ b/tests/unit/tests/unittests/designercoreutils/version-test.cpp @@ -2,7 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include -#include +#include namespace { diff --git a/tests/unit/tests/unittests/listmodeleditor/CMakeLists.txt b/tests/unit/tests/unittests/listmodeleditor/CMakeLists.txt index 639a6fca290..b91507b7a88 100644 --- a/tests/unit/tests/unittests/listmodeleditor/CMakeLists.txt +++ b/tests/unit/tests/unittests/listmodeleditor/CMakeLists.txt @@ -5,14 +5,14 @@ extend_qtc_test(unittest ) extend_qtc_test(unittest SOURCES_PREFIX - "${QmlDesignerDir}" + "${QML_DESIGNER_DIRECTORY}" SOURCES components/listmodeleditor/listmodeleditormodel.cpp components/listmodeleditor/listmodeleditormodel.h ) extend_qtc_test(unittest SOURCES - ${QtCreatorLibsDir}/qmlpuppetcommunication/interfaces/commondefines.h - ${QmlDesignerDir}/components/listmodeleditor/listmodeleditormodel.cpp - ${QmlDesignerDir}/components/listmodeleditor/listmodeleditormodel.h + ${QT_CREATOR_LIBS_DIRECTORY}/qmlpuppetcommunication/interfaces/commondefines.h + ${QML_DESIGNER_DIRECTORY}/components/listmodeleditor/listmodeleditormodel.cpp + ${QML_DESIGNER_DIRECTORY}/components/listmodeleditor/listmodeleditormodel.h ) diff --git a/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp b/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp index e866ad81c7f..0fc335b551a 100644 --- a/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp +++ b/tests/unit/tests/unittests/listmodeleditor/listmodeleditor-test.cpp @@ -7,13 +7,13 @@ #include #include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include +#include namespace { diff --git a/tests/unit/tests/unittests/model/import-test.cpp b/tests/unit/tests/unittests/model/import-test.cpp index c1ff4a6a935..d897e712ce0 100644 --- a/tests/unit/tests/unittests/model/import-test.cpp +++ b/tests/unit/tests/unittests/model/import-test.cpp @@ -4,7 +4,7 @@ #include "../utils/googletest.h" #include -#include +#include namespace { diff --git a/tests/unit/tests/unittests/projectstorage/CMakeLists.txt b/tests/unit/tests/unittests/projectstorage/CMakeLists.txt index 69818ff6a44..3e1e2850527 100644 --- a/tests/unit/tests/unittests/projectstorage/CMakeLists.txt +++ b/tests/unit/tests/unittests/projectstorage/CMakeLists.txt @@ -20,7 +20,7 @@ extend_qtc_test(unittest extend_qtc_test(unittest CONDITION TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate AND IS_SUPPORTED_PROJECTSTORAGE_QT - SOURCES_PREFIX "${QmlDesignerDir}/designercore" + SOURCES_PREFIX "${QML_DESIGNER_DIRECTORY}/libs/designercore" DEPENDS Qt6::QmlDomPrivate Qt6::QmlCompilerPrivate DEFINES QDS_BUILD_QMLPARSER QML_DOM_MSVC2019_COMPAT # QML_DOM_MSVC2019_COMPAT can be revmoved for Qt 6.8 SOURCES diff --git a/tests/unit/tests/unittests/utils/CMakeLists.txt b/tests/unit/tests/unittests/utils/CMakeLists.txt index d4e8e56e2e4..ce186a95d56 100644 --- a/tests/unit/tests/unittests/utils/CMakeLists.txt +++ b/tests/unit/tests/unittests/utils/CMakeLists.txt @@ -1,9 +1,8 @@ # QtCreator Utils Tests extend_qtc_test(unittest - SOURCES - matchingtext-test.cpp - sizedarray-test.cpp - smallstring-test.cpp + SOURCES + sizedarray-test.cpp + smallstring-test.cpp ) extend_qtc_test(unittest diff --git a/tests/unit/tests/unittests/utils/matchingtext-test.cpp b/tests/unit/tests/unittests/utils/matchingtext-test.cpp deleted file mode 100644 index 716eb7ff8b8..00000000000 --- a/tests/unit/tests/unittests/utils/matchingtext-test.cpp +++ /dev/null @@ -1,307 +0,0 @@ -// Copyright (C) 2017 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "../utils/googletest.h" - -#include - -#include -#include - -#include - -#include - -namespace { - -class Document { -public: - Document(const QString &documentText, char marker = '@') - { - QString text = documentText; - const int markerIndex = documentText.indexOf(marker); - if (markerIndex == -1) - return; - - text.replace(markerIndex, 1, ""); - - document.reset(new QTextDocument(text)); - cursor = QTextCursor(document.get()); - cursor.setPosition(markerIndex); - } - - std::unique_ptr document; - QTextCursor cursor; -}; - -using MT = CPlusPlus::MatchingText; -using IsNextBlockDeeperIndented = MT::IsNextBlockDeeperIndented; - -class MatchingText : public testing::Test { -protected: - const IsNextBlockDeeperIndented nextBlockIsIndented = [](const QTextBlock &) { return true; }; -}; - -TEST_F(MatchingText, context_allows_auto_parentheses_for_no_input) -{ - const Document document("@"); - - ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_in_empty_line) -{ - const Document document("@"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_initializer) -{ - const Document document("Type object@"); - - ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_after_function_declarator_same_line) -{ - const Document document("void g() @"); - - ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_after_function_declarator_new_line) -{ - const Document document("void g()\n" - "@"); - - ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_after_function_declarator_new_line_and_more) -{ - const Document document("void g()\n" - "@\n" - "1+1;"); - - ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_after_lambda_declarator) -{ - const Document document("[]() @"); - - ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_before_opening_curly_brace) -{ - const Document document("@{"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_before_closing_curly_brace) -{ - const Document document("@}"); - - ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_before_closing_bracket) -{ - const Document document("@]"); - - ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_before_closing_paren) -{ - const Document document("@)"); - - ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_before_semicolon) -{ - const Document document("@;"); - - ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_before_comma) -{ - const Document document("@,"); - - ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_in_cpp_comment) -{ - const Document document("// @"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_in_cpp_doxygen_comment) -{ - const Document document("//! @"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_before_indented) -{ - const Document document("@\n" - " 1+1;"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{", nextBlockIsIndented)); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_before_indented_with_following_comment) -{ - const Document document("@\n // comment" - " 1+1;"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{", nextBlockIsIndented)); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_before_indented_with_text_in_front) -{ - const Document document("if (true) @\n" - " 1+1;"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{", nextBlockIsIndented)); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_before_indented_on_empty_line1) -{ - const Document document("if (true)\n" - "@\n" - " 1+1;"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{", nextBlockIsIndented)); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_before_indented_on_empty_line2) -{ - const Document document("if (true)\n" - " @\n" - " 1+1;"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{", nextBlockIsIndented)); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_in_the_middle) -{ - const Document document("if (true) @ true;"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_after_control_flow_while_and_friends) -{ - const Document document("while (true) @"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_after_control_flow_do_and_friends) -{ - const Document document("do @"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_invalid_code_unbalanced_parens) -{ - const Document document(") @"); - - ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_invalid_code_unbalanced_parens2) -{ - const Document document("while true) @"); - - ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_invalid_code_only_balanced_parens) -{ - const Document document("() @"); - - ASSERT_TRUE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_before_named_namespace) -{ - const Document document("namespace X @"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_before_named_namespace_with_attribute_specifier) -{ - const Document document("namespace [[xyz]] X @"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_before_unnamed_namespace) -{ - const Document document("namespace @"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_before_unnamed_namespace_with_attribute_specifier) -{ - const Document document("namespace [[xyz]] @"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_before_nested_namespace) -{ - const Document document("namespace X::Y::Z @"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_before_class) -{ - const Document document("class X @"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_before_struct) -{ - const Document document("struct X @"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_before_enum) -{ - const Document document("enum X @"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_before_union) -{ - const Document document("union X @"); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -TEST_F(MatchingText, context_allows_auto_parentheses_curly_brace_not_within_string) -{ - const Document document("\"a@b\""); - - ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); -} - -} // anonymous From 3809729f79ad73279e97970c896200377033c41a Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 22 Aug 2024 16:12:34 +0200 Subject: [PATCH 102/193] QmlDesigner: Fix unused warning Change-Id: Ie6389f64806647a8425ec373035280e1f7b09d1c Reviewed-by: Thomas Hartmann --- .../qml2puppet/instances/qt5informationnodeinstanceserver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 39f29d5a9f5..7b845d2db07 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -2516,7 +2516,7 @@ void Qt5InformationNodeInstanceServer::inputEvent(const InputEventCommand &comma } } -void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &command) +void Qt5InformationNodeInstanceServer::view3DAction([[maybe_unused]] const View3DActionCommand &command) { if (!m_editView3DSetupDone) return; From 7bc330d4ac9a0768550b7258d2dca6814b788b71 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 29 Aug 2024 10:49:54 +0200 Subject: [PATCH 103/193] QmlDesigner: Make source path database shared Fixes: QDS-13499 Change-Id: I0ef103c09e286f43f807c2cb218ca188683dedae Reviewed-by: Thomas Hartmann --- src/plugins/qmldesigner/qmldesignerprojectmanager.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp index 34296390793..f46e6ba9d63 100644 --- a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp +++ b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp @@ -245,7 +245,9 @@ class QmlDesignerProjectManager::Data { public: Data(ExternalDependenciesInterface &externalDependencies) - : sourcePathDatabase{externalDependencies.userResourcePath(u"source_path.db")} + : sourcePathDatabase{externalDependencies.userResourcePath(u"source_path.db"), + Sqlite::JournalMode::Wal, + Sqlite::LockingMode::Normal} {} public: From 612e11dc50d3bbfb8a8de113cbd7553d9d367b17 Mon Sep 17 00:00:00 2001 From: Shrief Gabr Date: Thu, 29 Aug 2024 12:16:04 +0300 Subject: [PATCH 104/193] QmlDesigner: Search Assets Library folders recursively Fixes: QDS-13497 Change-Id: I44f9645ca86d82be3ab2e2d7a14e952ecd44c418 Reviewed-by: Mahmoud Badri --- .../qmldesigner/components/assetslibrary/assetslibrarymodel.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp index 6c9720271f9..396c3e274aa 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp @@ -24,6 +24,7 @@ AssetsLibraryModel::AssetsLibraryModel(QObject *parent) : QSortFilterProxyModel{parent} { createBackendModel(); + setRecursiveFilteringEnabled(true); sort(0); } From f5bb913c9da376fed78caff2639eb2f1f2f3765e Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 22 Aug 2024 12:56:33 +0200 Subject: [PATCH 105/193] Enforce that plugins can't be used as library dependencies We want to use the libraries in different projects where the plugins are not present. Change-Id: Ia3b183dcf57c7c63c75a17e9d5e3c3ef672e668e Reviewed-by: Eike Ziller --- cmake/QtCreatorAPI.cmake | 12 ++++++++++++ cmake/QtCreatorAPIInternal.cmake | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/cmake/QtCreatorAPI.cmake b/cmake/QtCreatorAPI.cmake index 5d39157b020..a0876c40086 100644 --- a/cmake/QtCreatorAPI.cmake +++ b/cmake/QtCreatorAPI.cmake @@ -129,6 +129,9 @@ function(add_qtc_library name) "CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;SYSTEM_INCLUDES;PUBLIC_INCLUDES;PUBLIC_SYSTEM_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES;PRIVATE_COMPILE_OPTIONS;PUBLIC_COMPILE_OPTIONS" ${ARGN} ) + check_library_dependencies(${_arg_DEPENDS}) + check_library_dependencies(${_arg_PUBLIC_DEPENDS}) + get_default_defines(default_defines_copy ${_arg_ALLOW_ASCII_CASTS}) if (${_arg_UNPARSED_ARGUMENTS}) @@ -336,6 +339,9 @@ function(add_qtc_plugin target_name) ${ARGN} ) + check_library_dependencies(${_arg_DEPENDS}) + check_library_dependencies(${_arg_PUBLIC_DEPENDS}) + if (${_arg_UNPARSED_ARGUMENTS}) message(FATAL_ERROR "add_qtc_plugin had unparsed arguments") endif() @@ -615,6 +621,9 @@ function(extend_qtc_plugin target_name) return() endif() + check_library_dependencies(${_arg_DEPENDS}) + check_library_dependencies(${_arg_PUBLIC_DEPENDS}) + extend_qtc_target(${target_name} ${ARGN}) endfunction() @@ -624,6 +633,9 @@ function(extend_qtc_library target_name) return() endif() + check_library_dependencies(${_arg_DEPENDS}) + check_library_dependencies(${_arg_PUBLIC_DEPENDS}) + extend_qtc_target(${target_name} ${ARGN}) endfunction() diff --git a/cmake/QtCreatorAPIInternal.cmake b/cmake/QtCreatorAPIInternal.cmake index 06d53a992c8..928c7fc22e8 100644 --- a/cmake/QtCreatorAPIInternal.cmake +++ b/cmake/QtCreatorAPIInternal.cmake @@ -361,6 +361,10 @@ function(find_dependent_plugins varName) if(NOT TARGET ${i}) continue() endif() + get_property(_class_name TARGET "${i}" PROPERTY QTC_PLUGIN_CLASS_NAME) + if (NOT _class_name) + message(SEND_ERROR "${i} is a library, not a plugin!") + endif() set(_dep) get_property(_dep TARGET "${i}" PROPERTY _arg_DEPENDS) if (_dep) @@ -377,6 +381,18 @@ function(find_dependent_plugins varName) set("${varName}" ${_RESULT} PARENT_SCOPE) endfunction() +function(check_library_dependencies) + foreach(i ${ARGN}) + if (NOT TARGET ${i}) + continue() + endif() + get_property(_class_name TARGET "${i}" PROPERTY QTC_PLUGIN_CLASS_NAME) + if (_class_name) + message(SEND_ERROR "${i} is a plugin, not a library!") + endif() + endforeach() +endfunction() + function(enable_pch target) if (BUILD_WITH_PCH) # Skip PCH for targets that do not use the expected visibility settings: From 32181cdb96654edb0fea1c5007c9405b8715e77e Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Tue, 27 Aug 2024 16:11:04 +0300 Subject: [PATCH 106/193] QmlDesigner: Refactor .qdsbundle importing out of content lib Refactoring exporting is to be done in a separate commit. Task-number: QDS-13389 Change-Id: I4712673fc4af6b654fde50babcf629d500b2389e Reviewed-by: Miikka Heikkinen --- src/plugins/qmldesigner/CMakeLists.txt | 3 +- .../components/componentcore/bundlehelper.cpp | 203 ++++++++++++++++++ .../components/componentcore/bundlehelper.h | 39 ++++ .../bundleimporter.cpp} | 25 ++- .../bundleimporter.h} | 6 +- .../componentcore/designeractionmanager.cpp | 8 +- .../componentcore/designeractionmanager.h | 4 +- .../componentcore/modelnodeoperations.cpp | 47 ++-- .../componentcore/modelnodeoperations.h | 1 - .../components/componentcore/utils3d.cpp | 55 +++++ .../components/componentcore/utils3d.h | 9 + .../contentlibraryeffectsmodel.cpp | 2 +- .../contentlibrarymaterialsmodel.cpp | 2 +- .../contentlibraryusermodel.cpp | 2 +- .../contentlibrary/contentlibraryview.cpp | 156 ++------------ .../contentlibrary/contentlibraryview.h | 7 +- .../contentlibrary/contentlibrarywidget.cpp | 24 +-- .../contentlibrary/contentlibrarywidget.h | 6 +- .../components/edit3d/edit3dview.cpp | 2 + .../components/edit3d/edit3dwidget.cpp | 8 +- .../components/edit3d/edit3dwidget.h | 24 ++- .../materialbrowser/materialbrowserwidget.cpp | 8 +- .../materialbrowser/materialbrowserwidget.h | 2 + .../generatedcomponentutils.cpp | 10 +- .../qmldesigner/qmldesignerconstants.h | 2 - 25 files changed, 411 insertions(+), 244 deletions(-) create mode 100644 src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp create mode 100644 src/plugins/qmldesigner/components/componentcore/bundlehelper.h rename src/plugins/qmldesigner/components/{contentlibrary/contentlibrarybundleimporter.cpp => componentcore/bundleimporter.cpp} (94%) rename src/plugins/qmldesigner/components/{contentlibrary/contentlibrarybundleimporter.h => componentcore/bundleimporter.h} (93%) diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 876658a1d95..cc9243d84b4 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -190,6 +190,8 @@ extend_qtc_plugin(QmlDesigner actioninterface.h addimagesdialog.cpp addimagesdialog.h addsignalhandlerdialog.cpp addsignalhandlerdialog.h addsignalhandlerdialog.ui + bundlehelper.cpp bundlehelper.h + bundleimporter.cpp bundleimporter.h changestyleaction.cpp changestyleaction.h componentcore.qrc componentcore_constants.h @@ -411,7 +413,6 @@ extend_qtc_plugin(QmlDesigner extend_qtc_plugin(QmlDesigner SOURCES_PREFIX components/contentlibrary SOURCES - contentlibrarybundleimporter.cpp contentlibrarybundleimporter.h contentlibraryview.cpp contentlibraryview.h contentlibrarywidget.cpp contentlibrarywidget.h contentlibrarytexturesmodel.cpp contentlibrarytexturesmodel.h diff --git a/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp b/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp new file mode 100644 index 00000000000..d1764842e9d --- /dev/null +++ b/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp @@ -0,0 +1,203 @@ +// 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 "bundlehelper.h" + +#include "bundleimporter.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace QmlDesigner { + +BundleHelper::BundleHelper(AbstractView *view, QWidget *widget) + : m_view(view) + , m_widget(widget) +{ + createImporter(); +} + +BundleHelper::~BundleHelper() +{} + +void BundleHelper::createImporter() +{ + m_importer = Utils::makeUniqueObjectPtr(); + +#ifdef QDS_USE_PROJECTSTORAGE + QObject::connect(m_importer, &BundleImporter::importFinished, m_widget, + [&](const QmlDesigner::TypeName &typeName, const QString &bundleId) { + QTC_ASSERT(typeName.size(), return); + if (isMaterialBundle(bundleId)) { + m_view->executeInTransaction("BundleHelper::createImporter", [&] { + Utils3D::createMaterial(m_view, typeName); + }); + } else if (isItemBundle(bundleId)) { + ModelNode target = Utils3D::active3DSceneNode(m_view); + if (!target) + target = m_view->rootModelNode(); + QTC_ASSERT(target, return); + + m_view->executeInTransaction("BundleHelper::createImporter", [&] { + ModelNode newNode = m_view->createModelNode(typeName, -1, -1); + target.defaultNodeListProperty().reparentHere(newNode); + newNode.setIdWithoutRefactoring(m_view->model()->generateNewId( + newNode.simplifiedTypeName(), "node")); + m_view->clearSelectedModelNodes(); + m_view->selectModelNode(newNode); + }); + } + }); +#else + QObject::connect(m_importer.get(), &BundleImporter::importFinished, m_widget, + [&](const QmlDesigner::NodeMetaInfo &metaInfo, const QString &bundleId) { + QTC_ASSERT(metaInfo.isValid(), return); + if (isMaterialBundle(bundleId)) { + m_view->executeInTransaction("BundleHelper::createImporter", [&] { + Utils3D::createMaterial(m_view, metaInfo); + }); + } else if (isItemBundle(bundleId)) { + + ModelNode target = Utils3D::active3DSceneNode(m_view); + if (!target) + target = m_view->rootModelNode(); + QTC_ASSERT(target, return); + + m_view->executeInTransaction("BundleHelper::createImporter", [&] { + ModelNode newNode = m_view->createModelNode(metaInfo.typeName(), + metaInfo.majorVersion(), + metaInfo.minorVersion()); + target.defaultNodeListProperty().reparentHere(newNode); + newNode.setIdWithoutRefactoring(m_view->model()->generateNewId( + newNode.simplifiedTypeName(), "node")); + m_view->clearSelectedModelNodes(); + m_view->selectModelNode(newNode); + }); + } + }); +#endif +} + +void BundleHelper::importBundleToProject() +{ + QString importPath = getImportPath(); + if (importPath.isEmpty()) + return; + + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + + ZipReader zipReader(importPath); + + QByteArray bundleJsonContent = zipReader.fileData(Constants::BUNDLE_JSON_FILENAME); + QTC_ASSERT(!bundleJsonContent.isEmpty(), return); + + const QJsonObject importedJsonObj = QJsonDocument::fromJson(bundleJsonContent).object(); + const QJsonArray importedItemsArr = importedJsonObj.value("items").toArray(); + QTC_ASSERT(!importedItemsArr.isEmpty(), return); + + QString bundleVersion = importedJsonObj.value("version").toString(); + bool bundleVersionOk = !bundleVersion.isEmpty() && bundleVersion == BUNDLE_VERSION; + if (!bundleVersionOk) { + QMessageBox::warning(m_widget, QObject::tr("Unsupported bundle file"), + QObject::tr("The chosen bundle was created with an incompatible version" + " of Qt Design Studio")); + return; + } + QString bundleId = importedJsonObj.value("id").toString(); + + QTemporaryDir tempDir; + QTC_ASSERT(tempDir.isValid(), return); + auto bundlePath = Utils::FilePath::fromString(tempDir.path()); + + const QStringList existingQmls = Utils::transform(compUtils.userBundlePath(bundleId) + .dirEntries(QDir::Files), [](const Utils::FilePath &path) { + return path.fileName(); + }); + + for (const QJsonValueConstRef &itemRef : importedItemsArr) { + QJsonObject itemObj = itemRef.toObject(); + QString qml = itemObj.value("qml").toString(); + + // confirm overwrite if an item with same name exists + if (existingQmls.contains(qml)) { + auto reply = QMessageBox::question(m_widget, QObject::tr("Component Exists"), + QObject::tr("A component with the same name '%1' " + "already exists in the project, are you " + "sure you want to overwrite it?") + .arg(qml), QMessageBox::Yes | QMessageBox::No); + if (reply == QMessageBox::No) + continue; + + // TODO: before overwriting remove old item's dependencies (not harmful but for cleanup) + } + + // add entry to model + QStringList files = itemObj.value("files").toVariant().toStringList(); + QString icon = itemObj.value("icon").toString(); + + // copy files + QStringList allFiles = files; + allFiles << qml << icon; + for (const QString &file : std::as_const(allFiles)) { + Utils::FilePath filePath = bundlePath.pathAppended(file); + filePath.parentDir().ensureWritableDir(); + QTC_ASSERT_EXPECTED(filePath.writeFileContents(zipReader.fileData(file)),); + } + + QString typePrefix = compUtils.userBundleType(bundleId); + TypeName type = QLatin1String("%1.%2").arg(typePrefix, qml.chopped(4)).toLatin1(); + + QString err = m_importer->importComponent(bundlePath.toFSPathString(), type, qml, files); + + if (!err.isEmpty()) + qWarning() << __FUNCTION__ << err; + } + + zipReader.close(); +} + +QString BundleHelper::getImportPath() const +{ + Utils::FilePath projectFP = DocumentManager::currentProjectDirPath(); + if (projectFP.isEmpty()) { + projectFP = QmlDesignerPlugin::instance()->documentManager() + .currentDesignDocument()->fileName().parentDir(); + } + + return QFileDialog::getOpenFileName(m_widget, QObject::tr("Import Component"), + projectFP.toFSPathString(), + QObject::tr("Qt Design Studio Bundle Files (*.%1)") + .arg(Constants::BUNDLE_SUFFIX)); +} + +bool BundleHelper::isMaterialBundle(const QString &bundleId) const +{ + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + return bundleId == compUtils.materialsBundleId() || bundleId == compUtils.userMaterialsBundleId(); +} + +// item bundle includes effects and 3D components +bool BundleHelper::isItemBundle(const QString &bundleId) const +{ + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + return bundleId == compUtils.effectsBundleId() || bundleId == compUtils.userEffectsBundleId() + || bundleId == compUtils.user3DBundleId(); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/bundlehelper.h b/src/plugins/qmldesigner/components/componentcore/bundlehelper.h new file mode 100644 index 00000000000..47f038a4672 --- /dev/null +++ b/src/plugins/qmldesigner/components/componentcore/bundlehelper.h @@ -0,0 +1,39 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +#include + +QT_FORWARD_DECLARE_CLASS(QString) +QT_FORWARD_DECLARE_CLASS(QWidget) + +namespace QmlDesigner { + +class AbstractView; +class BundleImporter; + +class BundleHelper +{ +public: + BundleHelper(AbstractView *view, QWidget *widget); + ~BundleHelper(); + + void importBundleToProject(); + QString getImportPath() const; + +private: + void createImporter(); + bool isMaterialBundle(const QString &bundleId) const; + bool isItemBundle(const QString &bundleId) const; + + QPointer m_view; + QPointer m_widget; + Utils::UniqueObjectPtr m_importer; + + static constexpr char BUNDLE_VERSION[] = "1.0"; +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.cpp b/src/plugins/qmldesigner/components/componentcore/bundleimporter.cpp similarity index 94% rename from src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.cpp rename to src/plugins/qmldesigner/components/componentcore/bundleimporter.cpp index 364a092a538..8f68f47e647 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.cpp +++ b/src/plugins/qmldesigner/components/componentcore/bundleimporter.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "contentlibrarybundleimporter.h" +#include "bundleimporter.h" #include #include @@ -25,20 +25,20 @@ namespace QmlDesigner { static constexpr int normalImportDelay = 200; -ContentLibraryBundleImporter::ContentLibraryBundleImporter(QObject *parent) +BundleImporter::BundleImporter(QObject *parent) : QObject(parent) { - connect(&m_importTimer, &QTimer::timeout, this, &ContentLibraryBundleImporter::handleImportTimer); + connect(&m_importTimer, &QTimer::timeout, this, &BundleImporter::handleImportTimer); } // Returns empty string on success or an error message on failure. // Note that there is also an asynchronous portion to the import, which will only // be done if this method returns success. Once the asynchronous portion of the // import is completed, importFinished signal will be emitted. -QString ContentLibraryBundleImporter::importComponent(const QString &bundleDir, - const TypeName &type, - const QString &qmlFile, - const QStringList &files) +QString BundleImporter::importComponent(const QString &bundleDir, + const TypeName &type, + const QString &qmlFile, + const QStringList &files) { QString module = QString::fromLatin1(type.left(type.lastIndexOf('.'))); m_bundleId = module.mid(module.lastIndexOf('.') + 1); @@ -145,7 +145,7 @@ QString ContentLibraryBundleImporter::importComponent(const QString &bundleDir, return {}; } -void ContentLibraryBundleImporter::handleImportTimer() +void BundleImporter::handleImportTimer() { auto handleFailure = [this] { m_importTimer.stop(); @@ -294,7 +294,7 @@ void ContentLibraryBundleImporter::handleImportTimer() } } -QVariantHash ContentLibraryBundleImporter::loadAssetRefMap(const FilePath &bundlePath) +QVariantHash BundleImporter::loadAssetRefMap(const FilePath &bundlePath) { FilePath assetRefPath = bundlePath.resolvePath(QLatin1String(Constants::COMPONENT_BUNDLES_ASSET_REF_FILE)); const expected_str content = assetRefPath.fileContents(); @@ -311,8 +311,7 @@ QVariantHash ContentLibraryBundleImporter::loadAssetRefMap(const FilePath &bundl return {}; } -void ContentLibraryBundleImporter::writeAssetRefMap(const FilePath &bundlePath, - const QVariantHash &assetRefMap) +void BundleImporter::writeAssetRefMap(const FilePath &bundlePath, const QVariantHash &assetRefMap) { FilePath assetRefPath = bundlePath.resolvePath(QLatin1String(Constants::COMPONENT_BUNDLES_ASSET_REF_FILE)); QJsonObject jsonObj = QJsonObject::fromVariantHash(assetRefMap); @@ -322,7 +321,7 @@ void ContentLibraryBundleImporter::writeAssetRefMap(const FilePath &bundlePath, } } -QString ContentLibraryBundleImporter::unimportComponent(const TypeName &type, const QString &qmlFile) +QString BundleImporter::unimportComponent(const TypeName &type, const QString &qmlFile) { QString module = QString::fromLatin1(type.left(type.lastIndexOf('.'))); m_bundleId = module.mid(module.lastIndexOf('.') + 1); @@ -417,7 +416,7 @@ QString ContentLibraryBundleImporter::unimportComponent(const TypeName &type, co return {}; } -FilePath ContentLibraryBundleImporter::resolveBundleImportPath(const QString &bundleId) +FilePath BundleImporter::resolveBundleImportPath(const QString &bundleId) { FilePath bundleImportPath = QmlDesignerPlugin::instance()->documentManager() .generatedComponentUtils().componentBundlesBasePath(); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.h b/src/plugins/qmldesigner/components/componentcore/bundleimporter.h similarity index 93% rename from src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.h rename to src/plugins/qmldesigner/components/componentcore/bundleimporter.h index dc3fdf4c8c8..7e3463adc38 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarybundleimporter.h +++ b/src/plugins/qmldesigner/components/componentcore/bundleimporter.h @@ -15,13 +15,13 @@ namespace QmlDesigner { class NodeMetaInfo; -class ContentLibraryBundleImporter : public QObject +class BundleImporter : public QObject { Q_OBJECT public: - ContentLibraryBundleImporter(QObject *parent = nullptr); - ~ContentLibraryBundleImporter() = default; + BundleImporter(QObject *parent = nullptr); + ~BundleImporter() = default; QString importComponent(const QString &bundleDir, const TypeName &type, const QString &qmlFile, const QStringList &files); diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index bca9a07fa8a..a11f420258a 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -4,6 +4,7 @@ #include "designeractionmanager.h" #include "anchoraction.h" +#include "bundlehelper.h" #include "changestyleaction.h" #include "designeractionmanagerview.h" #include "designericons.h" @@ -1999,7 +2000,7 @@ void DesignerActionManager::createDefaultDesignerActions() rootCategory, QKeySequence(), Priorities::ImportComponent, - &importComponent)); + [&](const SelectionContext &) { m_bundleHelper->importBundleToProject(); })); addDesignerAction(new ModelNodeContextMenuAction( exportComponentCommandId, @@ -2188,9 +2189,12 @@ ActionInterface *DesignerActionManager::actionByMenuId(const QByteArray &id) return nullptr; } -DesignerActionManager::DesignerActionManager(DesignerActionManagerView *designerActionManagerView, ExternalDependenciesInterface &externalDependencies) +DesignerActionManager::DesignerActionManager(DesignerActionManagerView *designerActionManagerView, + ExternalDependenciesInterface &externalDependencies) : m_designerActionManagerView(designerActionManagerView) , m_externalDependencies(externalDependencies) + , m_bundleHelper(std::make_unique(designerActionManagerView, + QmlDesignerPlugin::instance()->mainWidget())) { setupIcons(); } diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h index 89505fcbe85..ec49ff60403 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h @@ -24,6 +24,7 @@ QT_END_NAMESPACE namespace QmlDesigner { +class BundleHelper; class DesignerActionManagerView; class DesignerIcons; @@ -140,6 +141,7 @@ private: ExternalDependenciesInterface &m_externalDependencies; std::unique_ptr m_designerIcons; QList m_callBacks; + std::unique_ptr m_bundleHelper; }; -} //QmlDesigner +} // QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index cd2908d1e08..f12d07d1fc5 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -2,17 +2,19 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "modelnodeoperations.h" -#include "coreplugin/coreplugintr.h" -#include "designmodewidget.h" -#include "modelnodecontextmenu_helper.h" -#include "addimagesdialog.h" -#include "layoutingridlayout.h" -#include "findimplementation.h" +#include "addimagesdialog.h" #include "addsignalhandlerdialog.h" +#include "componentcore_constants.h" +#include "findimplementation.h" +#include "layoutingridlayout.h" +#include "modelnodecontextmenu_helper.h" +#include "utils3d.h" #include #include +#include +#include #include #include #include @@ -27,40 +29,34 @@ #include #include #include -#include +#include #include -#include -#include - -#include #include #include -#include -#include +#include #include -#include +#include #include +#include +#include #include #include -#include - -#include - #include #include #include #include "projectexplorer/target.h" +#include + #include #include #include -#include #include #include #include @@ -68,17 +64,14 @@ #include #include #include -#include #include -#include #include -#include #include #include +#include #include #include -#include #include #include @@ -805,14 +798,6 @@ void add3DAssetToContentLibrary(const SelectionContext &selectionContext) selectionContext.view()->emitCustomNotification("add_3d_to_content_lib", {node}); } -void importComponent(const SelectionContext &selectionContext) -{ -#ifdef DETACH_DISABLED_VIEWS - QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); -#endif - selectionContext.view()->emitCustomNotification("import_bundle_to_project"); -} - void exportComponent(const SelectionContext &selectionContext) { #ifdef DETACH_DISABLED_VIEWS diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h index d8fe9c7906d..45006067f02 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h @@ -97,7 +97,6 @@ void removeLayout(const SelectionContext &selectionContext); void removePositioner(const SelectionContext &selectionContext); void moveToComponent(const SelectionContext &selectionContext); void add3DAssetToContentLibrary(const SelectionContext &selectionContext); -void importComponent(const SelectionContext &selectionContext); void exportComponent(const SelectionContext &selectionContext); PropertyName getIndexPropertyName(const ModelNode &modelNode); void addItemToStackedContainer(const SelectionContext &selectionContext); diff --git a/src/plugins/qmldesigner/components/componentcore/utils3d.cpp b/src/plugins/qmldesigner/components/componentcore/utils3d.cpp index 1319401bec9..6d0486131b5 100644 --- a/src/plugins/qmldesigner/components/componentcore/utils3d.cpp +++ b/src/plugins/qmldesigner/components/componentcore/utils3d.cpp @@ -13,6 +13,8 @@ #include +#include + namespace QmlDesigner { namespace Utils3D { @@ -250,5 +252,58 @@ void applyMaterialToModels(AbstractView *view, const ModelNode &material, }); } +// This method should be executed within a transaction as it performs multiple modifications to the model +#ifdef QDS_USE_PROJECTSTORAGE +ModelNode createMaterial(AbstractView *view, const TypeName &typeName) +{ + ModelNode matLib = Utils3D::materialLibraryNode(this); + if (!matLib.isValid() || !typeName.size()) + return {}; + + ModelNode newMatNode = view->createModelNode(typeName, -1, -1); + matLib.defaultNodeListProperty().reparentHere(newMatNode); + + static QRegularExpression rgx("([A-Z])([a-z]*)"); + QString newName = QString::fromUtf8(typeName).replace(rgx, " \\1\\2").trimmed(); + if (newName.endsWith(" Material")) + newName.chop(9); // remove trailing " Material" + QString newId = view->model()->generateNewId(newName, "material"); + newMatNode.setIdWithRefactoring(newId); + + VariantProperty objNameProp = newMatNode.variantProperty("objectName"); + objNameProp.setValue(newName); + + view->emitCustomNotification("focus_material_section", {}); + + return newMatNode; +} +#else +ModelNode createMaterial(AbstractView *view, const NodeMetaInfo &metaInfo) +{ + ModelNode matLib = Utils3D::materialLibraryNode(view); + if (!matLib.isValid() || !metaInfo.isValid()) + return {}; + + ModelNode newMatNode = view->createModelNode(metaInfo.typeName(), + metaInfo.majorVersion(), + metaInfo.minorVersion()); + matLib.defaultNodeListProperty().reparentHere(newMatNode); + + static QRegularExpression rgx("([A-Z])([a-z]*)"); + QString newName = QString::fromLatin1(metaInfo.simplifiedTypeName()).replace(rgx, " \\1\\2").trimmed(); + if (newName.endsWith(" Material")) + newName.chop(9); // remove trailing " Material" + QString newId = view->model()->generateNewId(newName, "material"); + newMatNode.setIdWithRefactoring(newId); + + VariantProperty objNameProp = newMatNode.variantProperty("objectName"); + objNameProp.setValue(newName); + + view->emitCustomNotification("focus_material_section", {}); + + return newMatNode; +} +#endif + } // namespace Utils3D } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/utils3d.h b/src/plugins/qmldesigner/components/componentcore/utils3d.h index 5019b7b3ab6..546c90f8e70 100644 --- a/src/plugins/qmldesigner/components/componentcore/utils3d.h +++ b/src/plugins/qmldesigner/components/componentcore/utils3d.h @@ -8,6 +8,9 @@ #include namespace QmlDesigner { + +class NodeMetaInfo; + namespace Utils3D { inline constexpr AuxiliaryDataKeyView active3dSceneProperty{AuxiliaryDataType::Temporary, @@ -41,5 +44,11 @@ QList getSelectedModels(AbstractView *view); void applyMaterialToModels(AbstractView *view, const ModelNode &material, const QList &models, bool add = false); +#ifdef QDS_USE_PROJECTSTORAGE +ModelNode createMaterial(AbstractView *view, const TypeName &typeName); +#else +ModelNode createMaterial(AbstractView *view, const NodeMetaInfo &metaInfo); +#endif + } // namespace Utils3D } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.cpp index 1be5940c76d..eb2b70122b2 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryeffectsmodel.cpp @@ -3,11 +3,11 @@ #include "contentlibraryeffectsmodel.h" -#include "contentlibrarybundleimporter.h" #include "contentlibraryeffectscategory.h" #include "contentlibraryitem.h" #include "contentlibrarywidget.h" +#include #include #include #include diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp index b5d67acc8ad..e407a851340 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp @@ -3,7 +3,6 @@ #include "contentlibrarymaterialsmodel.h" -#include "contentlibrarybundleimporter.h" #include "contentlibrarymaterial.h" #include "contentlibrarymaterialscategory.h" #include "contentlibrarywidget.h" @@ -13,6 +12,7 @@ #include "fileextractor.h" #include "multifiledownloader.h" +#include #include #include diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp index 643913d1791..4c5161c3c2e 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryusermodel.cpp @@ -5,11 +5,11 @@ #include "useritemcategory.h" #include "usertexturecategory.h" -#include "contentlibrarybundleimporter.h" #include "contentlibraryitem.h" #include "contentlibrarytexture.h" #include "contentlibrarywidget.h" +#include #include #include #include diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index 2316d7b2f3a..fa7836870f5 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -3,7 +3,6 @@ #include "contentlibraryview.h" -#include "contentlibrarybundleimporter.h" #include "contentlibraryiconprovider.h" #include "contentlibraryitem.h" #include "contentlibraryeffectsmodel.h" @@ -16,6 +15,7 @@ #include #include +#include #include #include #include @@ -152,7 +152,7 @@ void ContentLibraryView::connectImporter() { #ifdef QDS_USE_PROJECTSTORAGE connect(m_widget->importer(), - &ContentLibraryBundleImporter::importFinished, + &BundleImporter::importFinished, this, [&](const QmlDesigner::TypeName &typeName, const QString &bundleId) { QTC_ASSERT(typeName.size(), return); @@ -179,7 +179,7 @@ void ContentLibraryView::connectImporter() }); #else connect(m_widget->importer(), - &ContentLibraryBundleImporter::importFinished, + &BundleImporter::importFinished, this, [&](const QmlDesigner::NodeMetaInfo &metaInfo, const QString &bundleId) { QTC_ASSERT(metaInfo.isValid(), return); @@ -214,7 +214,7 @@ void ContentLibraryView::connectImporter() }); #endif - connect(m_widget->importer(), &ContentLibraryBundleImporter::aboutToUnimport, this, + connect(m_widget->importer(), &BundleImporter::aboutToUnimport, this, [&] (const QmlDesigner::TypeName &type, const QString &bundleId) { if (isMaterialBundle(bundleId)) { // delete instances of the bundle material that is about to be unimported @@ -349,14 +349,17 @@ void ContentLibraryView::customNotification(const AbstractView *view, ModelNode defaultMat = getBundleMaterialDefaultInstance(m_draggedBundleMaterial->type()); if (defaultMat.isValid()) { - if (m_bundleMaterialTargets.isEmpty()) // if no drop target, create a duplicate material + if (m_bundleMaterialTargets.isEmpty()) { // if no drop target, create a duplicate material + executeInTransaction(__FUNCTION__, [&] { #ifdef QDS_USE_PROJECTSTORAGE - createMaterial(m_draggedBundleMaterial->type()); + Utils3D::createMaterial(this, m_draggedBundleMaterial->type()); #else - createMaterial(defaultMat.metaInfo()); + Utils3D::createMaterial(this, defaultMat.metaInfo()); #endif - else + }); + } else { applyBundleMaterialToDropTarget(defaultMat); + } } else { m_widget->materialsModel()->addToProject(m_draggedBundleMaterial); } @@ -404,8 +407,6 @@ void ContentLibraryView::customNotification(const AbstractView *view, exportLibItem(nodeList.first()); } else if (identifier == "export_material_as_bundle") { exportLibItem(nodeList.first(), data.first().value()); - } else if (identifier == "import_bundle_to_project") { - importBundleToProject(); } } @@ -450,7 +451,7 @@ void ContentLibraryView::applyBundleMaterialToDropTarget(const ModelNode &bundle return; executeInTransaction("ContentLibraryView::applyBundleMaterialToDropTarget", [&] { - ModelNode newMatNode = typeName.size() ? createMaterial(typeName) : bundleMat; + ModelNode newMatNode = typeName.size() ? Utils3D::createMaterial(this, typeName) : bundleMat; for (const ModelNode &target : std::as_const(m_bundleMaterialTargets)) { if (target.isValid() && target.metaInfo().isQtQuick3DModel()) { QmlObjectNode qmlObjNode(target); @@ -478,7 +479,7 @@ void ContentLibraryView::applyBundleMaterialToDropTarget(const ModelNode &bundle return; executeInTransaction("ContentLibraryView::applyBundleMaterialToDropTarget", [&] { - ModelNode newMatNode = metaInfo.isValid() ? createMaterial(metaInfo) : bundleMat; + ModelNode newMatNode = metaInfo.isValid() ? Utils3D::createMaterial(this, metaInfo) : bundleMat; for (const ModelNode &target : std::as_const(m_bundleMaterialTargets)) { if (target.isValid() && target.metaInfo().isQtQuick3DModel()) { @@ -1144,85 +1145,6 @@ void ContentLibraryView::importBundleToContentLib() QTC_ASSERT_EXPECTED(result,); } -void ContentLibraryView::importBundleToProject() -{ - QString importPath = getImportPath(); - if (importPath.isEmpty()) - return; - - auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); - - ZipReader zipReader(importPath); - - QByteArray bundleJsonContent = zipReader.fileData(Constants::BUNDLE_JSON_FILENAME); - QTC_ASSERT(!bundleJsonContent.isEmpty(), return); - - const QJsonObject importedJsonObj = QJsonDocument::fromJson(bundleJsonContent).object(); - const QJsonArray importedItemsArr = importedJsonObj.value("items").toArray(); - QTC_ASSERT(!importedItemsArr.isEmpty(), return); - - QString bundleVersion = importedJsonObj.value("version").toString(); - bool bundleVersionOk = !bundleVersion.isEmpty() && bundleVersion == BUNDLE_VERSION; - if (!bundleVersionOk) { - QMessageBox::warning(m_widget, tr("Unsupported bundle file"), - tr("The chosen bundle was created with an incompatible version of Qt Design Studio")); - return; - } - QString bundleId = importedJsonObj.value("id").toString(); - - QTemporaryDir tempDir; - QTC_ASSERT(tempDir.isValid(), return); - auto bundlePath = Utils::FilePath::fromString(tempDir.path()); - - const QStringList existingQmls = Utils::transform(compUtils.userBundlePath(bundleId) - .dirEntries(QDir::Files), [](const Utils::FilePath &path) { - return path.fileName(); - }); - - for (const QJsonValueConstRef &itemRef : importedItemsArr) { - QJsonObject itemObj = itemRef.toObject(); - QString qml = itemObj.value("qml").toString(); - - // confirm overwrite if an item with same name exists - if (existingQmls.contains(qml)) { - QMessageBox::StandardButton reply = QMessageBox::question(m_widget, tr("Component Exists"), - tr("A component with the same name '%1' already " - "exists in the project, are you sure " - "you want to overwrite it?") - .arg(qml), QMessageBox::Yes | QMessageBox::No); - if (reply == QMessageBox::No) - continue; - - // TODO: before overwriting remove old item's dependencies (not harmful but for cleanup) - } - - // add entry to model - QStringList files = itemObj.value("files").toVariant().toStringList(); - QString icon = itemObj.value("icon").toString(); - - // copy files - QStringList allFiles = files; - allFiles << qml << icon; - for (const QString &file : std::as_const(allFiles)) { - Utils::FilePath filePath = bundlePath.pathAppended(file); - filePath.parentDir().ensureWritableDir(); - QTC_ASSERT_EXPECTED(filePath.writeFileContents(zipReader.fileData(file)),); - } - - QString typePrefix = compUtils.userBundleType(bundleId); - TypeName type = QLatin1String("%1.%2").arg(typePrefix, qml.chopped(4)).toLatin1(); - - QString err = m_widget->importer()->importComponent(bundlePath.toFSPathString(), type, qml, files); - - if (err.isEmpty()) - m_widget->setImporterRunning(true); - else - qWarning() << __FUNCTION__ << err; - } - - zipReader.close(); -} - /** * @brief Generates an icon image from a qml component * @param qmlPath path to the qml component file to be rendered @@ -1309,58 +1231,6 @@ ModelNode ContentLibraryView::getBundleMaterialDefaultInstance(const TypeName &t return {}; } -#ifdef QDS_USE_PROJECTSTORAGE -ModelNode ContentLibraryView::createMaterial(const TypeName &typeName) -{ - ModelNode matLib = Utils3D::materialLibraryNode(this); - if (!matLib.isValid() || !typeName.size()) - return {}; - - ModelNode newMatNode = createModelNode(typeName, -1, -1); - matLib.defaultNodeListProperty().reparentHere(newMatNode); - - static QRegularExpression rgx("([A-Z])([a-z]*)"); - QString newName = QString::fromUtf8(typeName).replace(rgx, " \\1\\2").trimmed(); - if (newName.endsWith(" Material")) - newName.chop(9); // remove trailing " Material" - QString newId = model()->generateNewId(newName, "material"); - newMatNode.setIdWithRefactoring(newId); - - VariantProperty objNameProp = newMatNode.variantProperty("objectName"); - objNameProp.setValue(newName); - - emitCustomNotification("focus_material_section", {}); - - return newMatNode; -} -#else -ModelNode ContentLibraryView::createMaterial(const NodeMetaInfo &metaInfo) -{ - ModelNode matLib = Utils3D::materialLibraryNode(this); - if (!matLib.isValid() || !metaInfo.isValid()) - return {}; - - ModelNode newMatNode = createModelNode(metaInfo.typeName(), - metaInfo.majorVersion(), - metaInfo.minorVersion()); - matLib.defaultNodeListProperty().reparentHere(newMatNode); - - static QRegularExpression rgx("([A-Z])([a-z]*)"); - QString newName = QString::fromLatin1(metaInfo.simplifiedTypeName()).replace(rgx, " \\1\\2").trimmed(); - if (newName.endsWith(" Material")) - newName.chop(9); // remove trailing " Material" - QString newId = model()->generateNewId(newName, "material"); - newMatNode.setIdWithRefactoring(newId); - - VariantProperty objNameProp = newMatNode.variantProperty("objectName"); - objNameProp.setValue(newName); - - emitCustomNotification("focus_material_section", {}); - - return newMatNode; -} -#endif - void ContentLibraryView::updateBundlesQuick3DVersion() { bool hasImport = false; diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h index 5a2878eca31..fc5288389ad 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h @@ -91,7 +91,6 @@ private: void addLibItem(const ModelNode &node, const QPixmap &iconPixmap = {}); void exportLibItem(const ModelNode &node, const QPixmap &iconPixmap = {}); void importBundleToContentLib(); - void importBundleToProject(); void getImageFromCache(const QString &qmlPath, std::function successCallback); QSet getBundleComponentDependencies(const ModelNode &node) const; @@ -109,11 +108,7 @@ private: const NodeMetaInfo &metaInfo = {}); #endif ModelNode getBundleMaterialDefaultInstance(const TypeName &type); -#ifdef QDS_USE_PROJECTSTORAGE - ModelNode createMaterial(const TypeName &typeName); -#else - ModelNode createMaterial(const NodeMetaInfo &metaInfo); -#endif + QPointer m_widget; QList m_bundleMaterialTargets; ModelNode m_bundleItemTarget; // target of the dropped bundle item diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp index d4d3bba5c1b..d7850a695c8 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp @@ -3,7 +3,6 @@ #include "contentlibrarywidget.h" -#include "contentlibrarybundleimporter.h" #include "contentlibraryeffectsmodel.h" #include "contentlibraryiconprovider.h" #include "contentlibraryitem.h" @@ -13,19 +12,20 @@ #include "contentlibrarytexturesmodel.h" #include "contentlibraryusermodel.h" -#include -#include -#include - -#include +#include #include #include #include #include - #include #include +#include + +#include +#include +#include + #include #include #include @@ -190,10 +190,10 @@ ContentLibraryWidget::~ContentLibraryWidget() void ContentLibraryWidget::createImporter() { - m_importer = new ContentLibraryBundleImporter(); + m_importer = new BundleImporter(); #ifdef QDS_USE_PROJECTSTORAGE connect(m_importer, - &ContentLibraryBundleImporter::importFinished, + &BundleImporter::importFinished, this, [&](const QmlDesigner::TypeName &typeName, const QString &bundleId) { setImporterRunning(false); @@ -202,7 +202,7 @@ void ContentLibraryWidget::createImporter() }); #else connect(m_importer, - &ContentLibraryBundleImporter::importFinished, + &BundleImporter::importFinished, this, [&](const QmlDesigner::NodeMetaInfo &metaInfo, const QString &bundleId) { setImporterRunning(false); @@ -211,7 +211,7 @@ void ContentLibraryWidget::createImporter() }); #endif - connect(m_importer, &ContentLibraryBundleImporter::unimportFinished, this, + connect(m_importer, &BundleImporter::unimportFinished, this, [&](const QmlDesigner::NodeMetaInfo &metaInfo, const QString &bundleId) { Q_UNUSED(metaInfo) setImporterRunning(false); @@ -251,7 +251,7 @@ void ContentLibraryWidget::updateImportedState(const QString &bundleId) m_userModel->updateImportedState(importedItems, bundleId); } -ContentLibraryBundleImporter *ContentLibraryWidget::importer() const +BundleImporter *ContentLibraryWidget::importer() const { return m_importer; } diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h index 545923316fc..ca380fe57e5 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.h @@ -22,7 +22,7 @@ class StudioQuickWidget; namespace QmlDesigner { -class ContentLibraryBundleImporter; +class BundleImporter; class ContentLibraryEffectsModel; class ContentLibraryIconProvider; class ContentLibraryItem; @@ -104,7 +104,7 @@ public: QSize sizeHint() const override; - ContentLibraryBundleImporter *importer() const; + BundleImporter *importer() const; ContentLibraryIconProvider *iconProvider() const; void showTab(TabIndex tabIndex); @@ -152,7 +152,7 @@ private: QPointer m_effectsModel; QPointer m_userModel; - ContentLibraryBundleImporter *m_importer = nullptr; + BundleImporter *m_importer = nullptr; QShortcut *m_qmlSourceUpdateShortcut = nullptr; QString m_filterText; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index 8a177e4441a..8f9d5fd9cbd 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -44,6 +44,8 @@ #include #include #include + +#include #include static const QByteArray operator""_actionId(const char *text, size_t size) diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index 4530c855fa4..07ff875b89a 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -46,6 +46,8 @@ #include #include #include +#include +#include #include #include @@ -80,6 +82,7 @@ static QIcon getEntryIcon(const ItemLibraryEntry &entry) Edit3DWidget::Edit3DWidget(Edit3DView *view) : m_view(view) + , m_bundleHelper(std::make_unique(view, this)) { setAcceptDrops(true); @@ -371,10 +374,7 @@ void Edit3DWidget::createContextMenu() m_importBundleAction = m_contextMenu->addAction( contextIcon(DesignerIcons::CreateIcon), // TODO: placeholder icon tr("Import Component"), [&] { -#ifdef DETACH_DISABLED_VIEWS - QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); -#endif - view()->emitCustomNotification("import_bundle_to_project"); // To ContentLibrary + m_bundleHelper->importBundleToProject(); }); m_exportBundleAction = m_contextMenu->addAction( diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h index cfed01669e3..d5fe2f1d207 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h @@ -2,15 +2,20 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #pragma once -#include -#include +#include +#include +#include + +#include + #include #include #include -#include -#include -#include +#include + +QT_FORWARD_DECLARE_CLASS(QLabel) +QT_FORWARD_DECLARE_CLASS(QMenu) namespace Core { class Command; @@ -18,19 +23,17 @@ class Command; namespace QmlDesigner { -class Edit3DView; class Edit3DCanvas; -class ToolBox; class Edit3DMaterialsAction; +class Edit3DView; +class ToolBox; struct ItemLibraryDetails { QString name; QIcon icon; QList entryList; - ItemLibraryDetails( - const QString &name = QString(), - const QIcon &icon = QIcon()) + ItemLibraryDetails(const QString &name = QString(), const QIcon &icon = QIcon()) : name (name) , icon(icon) {} @@ -111,6 +114,7 @@ private: QHash m_nameToEntry; ItemLibraryEntry m_draggedEntry; QHash m_actionToCommandHash; + std::unique_ptr m_bundleHelper; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp index 973051b8ec6..775ae4f6a94 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -157,6 +158,7 @@ MaterialBrowserWidget::MaterialBrowserWidget(AsynchronousImageCache &imageCache, , m_materialBrowserTexturesModel(new MaterialBrowserTexturesModel(view, this)) , m_quickWidget(Utils::makeUniqueObjectPtr(this)) , m_previewImageProvider(new PreviewImageProvider()) + , m_bundleHelper(std::make_unique(view, this)) { QImage defaultImage; defaultImage.load(Utils::StyleHelper::dpiSpecificImageFile(":/textureeditor/images/texture_default.png")); @@ -379,11 +381,7 @@ void MaterialBrowserWidget::addMaterialToContentLibrary() void MaterialBrowserWidget::importMaterial() { -#ifdef DETACH_DISABLED_VIEWS - QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); -#endif - ModelNode mat = m_materialBrowserModel->selectedMaterial(); - m_materialBrowserView->emitCustomNotification("import_bundle_to_project"); // to ContentLibrary + m_bundleHelper->importBundleToProject(); } void MaterialBrowserWidget::exportMaterial() { diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h index 36cb40ac0d2..7ebec0b622c 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h @@ -22,6 +22,7 @@ class StudioQuickWidget; namespace QmlDesigner { class AssetImageProvider; +class BundleHelper; class MaterialBrowserView; class MaterialBrowserModel; class MaterialBrowserTexturesModel; @@ -94,6 +95,7 @@ private: PreviewImageProvider *m_previewImageProvider = nullptr; AssetImageProvider *m_textureImageProvider = nullptr; Core::IContext *m_context = nullptr; + std::unique_ptr m_bundleHelper; QString m_filterText; diff --git a/src/plugins/qmldesigner/libs/designercore/designercoreutils/generatedcomponentutils.cpp b/src/plugins/qmldesigner/libs/designercore/designercoreutils/generatedcomponentutils.cpp index ca5ee39e1bd..bd628ea9bfe 100644 --- a/src/plugins/qmldesigner/libs/designercore/designercoreutils/generatedcomponentutils.cpp +++ b/src/plugins/qmldesigner/libs/designercore/designercoreutils/generatedcomponentutils.cpp @@ -9,6 +9,8 @@ namespace QmlDesigner { constexpr QLatin1String componentBundlesMaterialBundleType{"Materials"}; constexpr QLatin1String componentBundlesType{"Bundles"}; +constexpr QLatin1String componentBundlesUser3DBundleType{"User3D"}; +constexpr QLatin1String componentBundlesUserEffectsBundleType{"UserEffects"}; constexpr QLatin1String componentBundlesUserMaterialBundleType{"UserMaterials"}; constexpr QLatin1String composedEffectType{"Effects"}; constexpr QLatin1String generatedComponentsFolder{"Generated"}; @@ -154,10 +156,10 @@ Utils::FilePath GeneratedComponentUtils::userBundlePath(const QString &bundleId) return basePath.pathAppended(componentBundlesUserMaterialBundleType); if (bundleId == userEffectsBundleId()) - return basePath.pathAppended(componentBundlesUserMaterialBundleType); + return basePath.pathAppended(componentBundlesUserEffectsBundleType); if (bundleId == user3DBundleId()) - return basePath.pathAppended(componentBundlesUserMaterialBundleType); + return basePath.pathAppended(componentBundlesUser3DBundleType); qWarning() << __FUNCTION__ << "no bundleType for bundleId:" << bundleId; return {}; @@ -286,12 +288,12 @@ QString GeneratedComponentUtils::userMaterialsBundleId() const QString GeneratedComponentUtils::userEffectsBundleId() const { - return componentBundlesUserMaterialBundleType; + return componentBundlesUserEffectsBundleType; } QString GeneratedComponentUtils::user3DBundleId() const { - return componentBundlesMaterialBundleType; + return componentBundlesUser3DBundleType; } QString GeneratedComponentUtils::materialsBundleType() const diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index c6c073ce91d..116dc94dcca 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -61,8 +61,6 @@ inline constexpr char EDIT3D_CAMERA_SPEED_CONFIG[] = "QmlDesigner.Editor3D.Camer inline constexpr char BUNDLE_JSON_FILENAME[] = "bundle.json"; inline constexpr char BUNDLE_SUFFIX[] = "qdsbundle"; inline constexpr char COMPONENT_BUNDLES_EFFECT_BUNDLE_TYPE[] = "Effects"; -inline constexpr char COMPONENT_BUNDLES_USER_EFFECT_BUNDLE_TYPE[] = "UserEffects"; -inline constexpr char COMPONENT_BUNDLES_USER_3D_BUNDLE_TYPE[] = "User3D"; inline constexpr char COMPONENT_BUNDLES_ASSET_REF_FILE[] = "_asset_ref.json"; inline constexpr char QUICK_3D_ASSET_LIBRARY_ICON_SUFFIX[] = "_libicon"; inline constexpr char QUICK_3D_ASSET_IMPORT_DATA_NAME[] = "_importdata.json"; From 0dd40a41d68bf6d1b22baa8782e30e235e4cb5b8 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 29 Aug 2024 14:11:52 +0200 Subject: [PATCH 107/193] QmlProject: Delay the opening of the fake project There are cases e.g. when restarting QDS when the correct .qmlproject will be opened anyway. Task-number: QDS-13495 Change-Id: I04e13d148484c3afa8e08fe2a43eb700c615720a Reviewed-by: Burak Hancerli Reviewed-by: Thomas Hartmann --- src/plugins/qmlprojectmanager/qmlprojectplugin.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp index 2f8ce7c7f42..d195c2b5e4a 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp @@ -409,10 +409,16 @@ void QmlProjectPlugin::initialize() [](Core::IDocument *document) { if (!ProjectManager::startupProject() && document->filePath().completeSuffix() == "ui.qml") { - const Utils::FilePath fileName = Utils::FilePath::fromString( - document->filePath().toString() + Constants::fakeProjectName); - auto result = ProjectExplorer::ProjectExplorerPlugin::openProjects({fileName}); - QTC_ASSERT(result.project(), return); + QTimer::singleShot(1000, [document]() { + if (ProjectManager::startupProject()) + return; + + const Utils::FilePath fileName = Utils::FilePath::fromString( + document->filePath().toString() + Constants::fakeProjectName); + auto result = ProjectExplorer::ProjectExplorerPlugin::openProjects( + {fileName}); + QTC_ASSERT(result.project(), return); + }); } }); From 72ff574978405d53089d03445a3dd84cead19fe7 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 29 Aug 2024 17:17:20 +0200 Subject: [PATCH 108/193] QmlDesigner: Fix end transaction Fixes: QDS-13504 Change-Id: I87fcc8e431cb64662fb0df6083cad7e30973d5b8 Reviewed-by: Thomas Hartmann --- .../libs/designercore/rewriter/rewritertransaction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/libs/designercore/rewriter/rewritertransaction.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/rewritertransaction.cpp index ae12e54e567..c9a71ddb858 100644 --- a/src/plugins/qmldesigner/libs/designercore/rewriter/rewritertransaction.cpp +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/rewritertransaction.cpp @@ -68,7 +68,7 @@ void RewriterTransaction::beginTransaction() void RewriterTransaction::endTransaction() { if (m_view && m_view->isAttached()) - m_view->model()->emitRewriterBeginTransaction(); + m_view->model()->emitRewriterEndTransaction(); } void RewriterTransaction::commit() From b630f96d4c4d2dc1d7c45b5fbc2c7ca7c871643f Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 29 Aug 2024 16:06:07 +0200 Subject: [PATCH 109/193] QmlDesigner: Fix rewriter attachment Change-Id: I7153fb6cc95fde914ce4dd4cd82ae80f0f85955f Reviewed-by: Thomas Hartmann --- src/plugins/qmldesigner/libs/designercore/model/model.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index 6150d8e70b3..183bc58d493 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -2796,7 +2796,7 @@ void Model::attachView(AbstractView *view) std::string_view{view->metaObject()->className()})); // Internal::WriteLocker locker(d); - if (view->kind() == AbstractView::Kind::NodeInstance) { + if (view->kind() == AbstractView::Kind::Rewriter) { auto castedRewriterView = qobject_cast(view); if (rewriterView() == castedRewriterView) return; From a875bb6ff063019ac4c2def3d258add57021de67 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 29 Aug 2024 17:43:36 +0200 Subject: [PATCH 110/193] QmlDesigner: Do not registerNodeInstanceMetaObject by default This is not required since the meta object is created lazily. This seems to hide the issue. Task-number: QDS-13379 Change-Id: Id1f7f4c9c29c59155b97db259468dae0e99b5162 Reviewed-by: Thomas Hartmann --- src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.cpp b/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.cpp index 69e791f0dd9..d2f8f16a19d 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.cpp +++ b/src/tools/qml2puppet/qml2puppet/instances/objectnodeinstance.cpp @@ -117,7 +117,6 @@ void ObjectNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNod InstanceContainer::NodeFlags /*flags*/) { initializePropertyWatcher(objectNodeInstance); - QmlPrivateGate::registerNodeInstanceMetaObject(objectNodeInstance->object(), objectNodeInstance->nodeInstanceServer()->engine()); } void ObjectNodeInstance::setId(const QString &id) From 6ecb6f1e1cd45219d9cfb243bb0a1712de0af9e6 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 29 Aug 2024 16:18:26 +0200 Subject: [PATCH 111/193] QmlDesigner: Fix endless loop Change-Id: If2f219bb1fd5d2173f4fd38c4854f6fbf1f32d93 Reviewed-by: Miikka Heikkinen Reviewed-by: Thomas Hartmann --- .../qmldesigner/components/navigator/navigatorview.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index fadccd41f37..afb5ad6286f 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -693,12 +693,14 @@ void NavigatorView::updateItemSelection() itemSelection.select(beginIndex, endIndex); } else { // if the node index is invalid expand ancestors manually if they are valid. - while (ModelNode parentNode = node.parentProperty().parentModelNode()) { + ModelNode parentNode = node.parentProperty().parentModelNode(); + while (parentNode) { QModelIndex parentIndex = indexForModelNode(parentNode); if (parentIndex.isValid()) treeWidget()->expand(parentIndex); else break; + parentNode = parentNode.parentProperty().parentModelNode(); } } } From 6d2d3a4eceef79ca6756263f0d1441644fabcd6a Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Thu, 29 Aug 2024 10:51:12 +0300 Subject: [PATCH 112/193] QmlDesigner: Refactor .qdsbundle exporting out of content lib Task-number: QDS-13389 Change-Id: Ie9e3edb634f94973e4a6157b991bc4af9608e19b Reviewed-by: Miikka Heikkinen --- .../components/componentcore/bundlehelper.cpp | 374 ++++++++++++++++- .../components/componentcore/bundlehelper.h | 42 ++ .../componentcore/designeractionmanager.cpp | 4 +- .../componentcore/modelnodeoperations.cpp | 9 - .../componentcore/modelnodeoperations.h | 1 - .../contentlibrary/contentlibraryview.cpp | 390 +----------------- .../contentlibrary/contentlibraryview.h | 38 +- .../components/edit3d/edit3dwidget.cpp | 5 +- .../materialbrowser/materialbrowserwidget.cpp | 6 +- 9 files changed, 429 insertions(+), 440 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp b/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp index d1764842e9d..09d756365d3 100644 --- a/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp +++ b/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp @@ -4,19 +4,26 @@ #include "bundlehelper.h" #include "bundleimporter.h" +#include "utils3d.h" #include +#include +#include #include #include #include #include -#include +#include +#include + +#include #include #include #include +#include #include #include #include @@ -172,6 +179,353 @@ void BundleHelper::importBundleToProject() zipReader.close(); } +void BundleHelper::exportBundle(const ModelNode &node, const QPixmap &iconPixmap) +{ + if (node.isComponent()) + export3DComponent(node); + else + exportItem(node, iconPixmap); +} + +void BundleHelper::export3DComponent(const ModelNode &node) +{ + QString exportPath = getExportPath(node); + if (exportPath.isEmpty()) + return; + + // targetPath is a temp path for collecting and zipping assets, actual export target is where + // the user chose to export (i.e. exportPath) + QTemporaryDir tempDir; + QTC_ASSERT(tempDir.isValid(), return); + auto targetPath = Utils::FilePath::fromString(tempDir.path()); + + m_zipWriter = std::make_unique(exportPath); + + QString compBaseName = node.simplifiedTypeName(); + QString compFileName = compBaseName + ".qml"; + + auto compDir = Utils::FilePath::fromString(ModelUtils::componentFilePath(node)).parentDir(); + + QString iconPath = QLatin1String("icons/%1").arg(UniqueName::generateId(compBaseName) + ".png"); + + const Utils::FilePaths sourceFiles = compDir.dirEntries({{}, QDir::Files, QDirIterator::Subdirectories}); + const QStringList ignoreList {"_importdata.json", "qmldir", compBaseName + ".hints"}; + QStringList filesList; // 3D component's assets (dependencies) + + for (const Utils::FilePath &sourcePath : sourceFiles) { + Utils::FilePath relativePath = sourcePath.relativePathFrom(compDir); + if (ignoreList.contains(sourcePath.fileName()) || relativePath.startsWith("source scene")) + continue; + + m_zipWriter->addFile(relativePath.toFSPathString(), sourcePath.fileContents().value_or("")); + + if (sourcePath.fileName() != compFileName) // skip component file (only collect dependencies) + filesList.append(relativePath.path()); + } + + // add the item to the bundle json + QJsonObject jsonObj; + QJsonArray itemsArr; + itemsArr.append(QJsonObject { + {"name", node.simplifiedTypeName()}, + {"qml", compFileName}, + {"icon", iconPath}, + {"files", QJsonArray::fromStringList(filesList)} + }); + + jsonObj["items"] = itemsArr; + + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + jsonObj["id"] = compUtils.user3DBundleId(); + jsonObj["version"] = BUNDLE_VERSION; + + Utils::FilePath jsonFilePath = targetPath.pathAppended(Constants::BUNDLE_JSON_FILENAME); + m_zipWriter->addFile(jsonFilePath.fileName(), QJsonDocument(jsonObj).toJson()); + + // add icon + m_iconSavePath = targetPath.pathAppended(iconPath); + m_iconSavePath.parentDir().ensureWritableDir(); + getImageFromCache(compDir.pathAppended(compFileName).path(), [&](const QImage &image) { + addIconAndCloseZip(image); + }); +} + +void BundleHelper::exportItem(const ModelNode &node, const QPixmap &iconPixmap) +{ + QString exportPath = getExportPath(node); + if (exportPath.isEmpty()) + return; + + // targetPath is a temp path for collecting and zipping assets, actual export target is where + // the user chose to export (i.e. exportPath) + m_tempDir = std::make_unique(); + QTC_ASSERT(m_tempDir->isValid(), return); + auto targetPath = Utils::FilePath::fromString(m_tempDir->path()); + + m_zipWriter = std::make_unique(exportPath); + + QString name = node.variantProperty("objectName").value().toString(); + if (name.isEmpty()) + name = node.displayName(); + + QString qml = nodeNameToComponentFileName(name); + QString iconBaseName = UniqueName::generateId(name); + + // generate and save Qml file + auto [qmlString, depAssets] = modelNodeToQmlString(node); + const QList depAssetsList = depAssets.values(); + + QStringList depAssetsRelativePaths; + for (const AssetPath &assetPath : depAssetsList) + depAssetsRelativePaths.append(assetPath.relativePath); + + auto qmlFilePath = targetPath.pathAppended(qml); + auto result = qmlFilePath.writeFileContents(qmlString.toUtf8()); + QTC_ASSERT_EXPECTED(result, return); + m_zipWriter->addFile(qmlFilePath.fileName(), qmlString.toUtf8()); + + QString iconPath = QLatin1String("icons/%1.png").arg(iconBaseName); + + // add the item to the bundle json + QJsonObject jsonObj; + QJsonArray itemsArr; + itemsArr.append(QJsonObject { + {"name", name}, + {"qml", qml}, + {"icon", iconPath}, + {"files", QJsonArray::fromStringList(depAssetsRelativePaths)} + }); + + jsonObj["items"] = itemsArr; + + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + jsonObj["id"] = node.metaInfo().isQtQuick3DMaterial() ? compUtils.userMaterialsBundleId() + : compUtils.user3DBundleId(); + jsonObj["version"] = BUNDLE_VERSION; + + Utils::FilePath jsonFilePath = targetPath.pathAppended(Constants::BUNDLE_JSON_FILENAME); + m_zipWriter->addFile(jsonFilePath.fileName(), QJsonDocument(jsonObj).toJson()); + + // add item's dependency assets to the bundle zip + for (const AssetPath &assetPath : depAssetsList) + m_zipWriter->addFile(assetPath.relativePath, assetPath.absFilPath().fileContents().value_or("")); + + // add icon + QPixmap iconPixmapToSave; + + if (node.metaInfo().isQtQuick3DCamera()) { + iconPixmapToSave = Core::ICore::resourcePath("qmldesigner/contentLibraryImages/camera.png") + .toFSPathString(); + } else if (node.metaInfo().isQtQuick3DLight()) { + iconPixmapToSave = Core::ICore::resourcePath("qmldesigner/contentLibraryImages/light.png") + .toFSPathString(); + } else { + iconPixmapToSave = iconPixmap; + } + + m_iconSavePath = targetPath.pathAppended(iconPath); + if (iconPixmapToSave.isNull()) { + getImageFromCache(qmlFilePath.toFSPathString(), [&](const QImage &image) { + addIconAndCloseZip(image); + }); + } else { + addIconAndCloseZip(iconPixmapToSave); + } +} + +QPair> BundleHelper::modelNodeToQmlString(const ModelNode &node, int depth) +{ + static QStringList depListIds; + + QString qml; + QSet assets; + + if (depth == 0) { + qml.append("import QtQuick\nimport QtQuick3D\n\n"); + depListIds.clear(); + } + + QString indent = QString(" ").repeated(depth * 4); + + qml += indent + node.simplifiedTypeName() + " {\n"; + + indent = QString(" ").repeated((depth + 1) * 4); + + qml += indent + "id: " + (depth == 0 ? "root" : node.id()) + " \n\n"; + + const QList excludedProps = {"x", "y", "z", "eulerRotation.x", "eulerRotation.y", + "eulerRotation.z", "scale.x", "scale.y", "scale.z", + "pivot.x", "pivot.y", "pivot.z"}; + const QList matProps = node.properties(); + for (const AbstractProperty &p : matProps) { + if (excludedProps.contains(p.name())) + continue; + + if (p.isVariantProperty()) { + QVariant pValue = p.toVariantProperty().value(); + QString val; + + if (!pValue.typeName()) { + // dynamic property with no value assigned + } else if (strcmp(pValue.typeName(), "QString") == 0 || strcmp(pValue.typeName(), "QColor") == 0) { + val = QLatin1String("\"%1\"").arg(pValue.toString()); + } else if (strcmp(pValue.typeName(), "QUrl") == 0) { + QString pValueStr = pValue.toString(); + val = QLatin1String("\"%1\"").arg(pValueStr); + if (!pValueStr.startsWith("#")) { + assets.insert({DocumentManager::currentResourcePath().toFSPathString(), + pValue.toString()}); + } + } else if (strcmp(pValue.typeName(), "QmlDesigner::Enumeration") == 0) { + val = pValue.value().toString(); + } else { + val = pValue.toString(); + } + if (p.isDynamic()) { + QString valWithColon = val.isEmpty() ? QString() : (": " + val); + qml += indent + "property " + p.dynamicTypeName() + " " + p.name() + valWithColon + "\n"; + } else { + qml += indent + p.name() + ": " + val + "\n"; + } + } else if (p.isBindingProperty()) { + ModelNode depNode = m_view->modelNodeForId(p.toBindingProperty().expression()); + QTC_ASSERT(depNode.isValid(), continue); + + if (p.isDynamic()) + qml += indent + "property " + p.dynamicTypeName() + " " + p.name() + ": " + depNode.id() + "\n"; + else + qml += indent + p.name() + ": " + depNode.id() + "\n"; + + if (depNode && !depListIds.contains(depNode.id())) { + depListIds.append(depNode.id()); + auto [depQml, depAssets] = modelNodeToQmlString(depNode, depth + 1); + qml += "\n" + depQml + "\n"; + assets.unite(depAssets); + } + } + } + + // add child nodes + const ModelNodes nodeChildren = node.directSubModelNodes(); + for (const ModelNode &childNode : nodeChildren) { + if (childNode && !depListIds.contains(childNode.id())) { + depListIds.append(childNode.id()); + auto [depQml, depAssets] = modelNodeToQmlString(childNode, depth + 1); + qml += "\n" + depQml + "\n"; + assets.unite(depAssets); + } + } + + indent = QString(" ").repeated(depth * 4); + + qml += indent + "}\n"; + + if (node.isComponent()) { + auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); + bool isBundle = node.type().startsWith(compUtils.componentBundlesTypePrefix().toLatin1()); + + if (depth > 0) { + // add component file to the dependency assets + Utils::FilePath compFilePath = componentPath(node.metaInfo()); + assets.insert({compFilePath.parentDir().path(), compFilePath.fileName()}); + } + + if (isBundle) + assets.unite(getBundleComponentDependencies(node)); + } + + return {qml, assets}; +} + +QSet BundleHelper::getBundleComponentDependencies(const ModelNode &node) const +{ + const QString compFileName = node.simplifiedTypeName() + ".qml"; + + Utils::FilePath compPath = componentPath(node.metaInfo()).parentDir(); + + QTC_ASSERT(compPath.exists(), return {}); + + QSet depList; + + Utils::FilePath assetRefPath = compPath.pathAppended(Constants::COMPONENT_BUNDLES_ASSET_REF_FILE); + + Utils::expected_str assetRefContents = assetRefPath.fileContents(); + if (!assetRefContents.has_value()) { + qWarning() << __FUNCTION__ << assetRefContents.error(); + return {}; + } + + QJsonDocument jsonDoc = QJsonDocument::fromJson(assetRefContents.value()); + if (jsonDoc.isNull()) { + qWarning() << __FUNCTION__ << "Invalid json file" << assetRefPath; + return {}; + } + + const QJsonObject rootObj = jsonDoc.object(); + const QStringList bundleAssets = rootObj.keys(); + + for (const QString &asset : bundleAssets) { + if (rootObj.value(asset).toArray().contains(compFileName)) + depList.insert({compPath.toFSPathString(), asset}); + } + + return depList; +} + +Utils::FilePath BundleHelper::componentPath([[maybe_unused]] const NodeMetaInfo &metaInfo) const +{ +#ifdef QDS_USE_PROJECTSTORAGE + // TODO + return {}; +#else + return Utils::FilePath::fromString(metaInfo.componentFileName()); +#endif +} + +QString BundleHelper::nodeNameToComponentFileName(const QString &name) const +{ + QString fileName = UniqueName::generateId(name, "Component"); + fileName[0] = fileName.at(0).toUpper(); + fileName.prepend("My"); + + return fileName + ".qml"; +} + +/** + * @brief Generates an icon image from a qml component + * @param qmlPath path to the qml component file to be rendered + * @param iconPath output save path of the generated icon + */ +void BundleHelper::getImageFromCache(const QString &qmlPath, + std::function successCallback) +{ + QmlDesignerPlugin::imageCache().requestSmallImage( + Utils::PathString{qmlPath}, + successCallback, + [&](ImageCache::AbortReason abortReason) { + if (abortReason == ImageCache::AbortReason::Abort) { + qWarning() << QLatin1String("ContentLibraryView::getImageFromCache(): icon generation " + "failed for path %1, reason: Abort").arg(qmlPath); + } else if (abortReason == ImageCache::AbortReason::Failed) { + qWarning() << QLatin1String("ContentLibraryView::getImageFromCache(): icon generation " + "failed for path %1, reason: Failed").arg(qmlPath); + } else if (abortReason == ImageCache::AbortReason::NoEntry) { + qWarning() << QLatin1String("ContentLibraryView::getImageFromCache(): icon generation " + "failed for path %1, reason: NoEntry").arg(qmlPath); + } + }); +} + +void BundleHelper::addIconAndCloseZip(const auto &image) { // auto: QImage or QPixmap + QByteArray iconByteArray; + QBuffer buffer(&iconByteArray); + buffer.open(QIODevice::WriteOnly); + image.save(&buffer, "PNG"); + + m_zipWriter->addFile("icons/" + m_iconSavePath.fileName(), iconByteArray); + m_zipWriter->close(); +}; + QString BundleHelper::getImportPath() const { Utils::FilePath projectFP = DocumentManager::currentProjectDirPath(); @@ -186,6 +540,24 @@ QString BundleHelper::getImportPath() const .arg(Constants::BUNDLE_SUFFIX)); } +QString BundleHelper::getExportPath(const ModelNode &node) const +{ + QString defaultExportFileName = QLatin1String("%1.%2").arg(node.displayName(), + Constants::BUNDLE_SUFFIX); + Utils::FilePath projectFP = DocumentManager::currentProjectDirPath(); + if (projectFP.isEmpty()) { + projectFP = QmlDesignerPlugin::instance()->documentManager() + .currentDesignDocument()->fileName().parentDir(); + } + + QString dialogTitle = node.metaInfo().isQtQuick3DMaterial() ? QObject::tr("Export Material") + : QObject::tr("Export Component"); + return QFileDialog::getSaveFileName(m_widget, dialogTitle, + projectFP.pathAppended(defaultExportFileName).toFSPathString(), + QObject::tr("Qt Design Studio Bundle Files (*.%1)") + .arg(Constants::BUNDLE_SUFFIX)); +} + bool BundleHelper::isMaterialBundle(const QString &bundleId) const { auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); diff --git a/src/plugins/qmldesigner/components/componentcore/bundlehelper.h b/src/plugins/qmldesigner/components/componentcore/bundlehelper.h index 47f038a4672..de70dfc60f1 100644 --- a/src/plugins/qmldesigner/components/componentcore/bundlehelper.h +++ b/src/plugins/qmldesigner/components/componentcore/bundlehelper.h @@ -3,17 +3,45 @@ #pragma once +#include #include +#include #include QT_FORWARD_DECLARE_CLASS(QString) +QT_FORWARD_DECLARE_CLASS(QTemporaryDir) QT_FORWARD_DECLARE_CLASS(QWidget) +class ZipWriter; + namespace QmlDesigner { class AbstractView; class BundleImporter; +class ModelNode; +class NodeMetaInfo; + +struct AssetPath +{ + QString basePath; + QString relativePath; + + Utils::FilePath absFilPath() const + { + return Utils::FilePath::fromString(basePath).pathAppended(relativePath); + } + + bool operator==(const AssetPath &other) const + { + return basePath == other.basePath && relativePath == other.relativePath; + } + + friend size_t qHash(const AssetPath &asset) + { + return ::qHash(asset.relativePath); + } +}; class BundleHelper { @@ -22,16 +50,30 @@ public: ~BundleHelper(); void importBundleToProject(); + void exportBundle(const ModelNode &node, const QPixmap &iconPixmap = QPixmap()); + void getImageFromCache(const QString &qmlPath, + std::function successCallback); + QString nodeNameToComponentFileName(const QString &name) const; + QPair> modelNodeToQmlString(const ModelNode &node, int depth = 0); QString getImportPath() const; private: void createImporter(); + QString getExportPath(const ModelNode &node) const; bool isMaterialBundle(const QString &bundleId) const; bool isItemBundle(const QString &bundleId) const; + void addIconAndCloseZip(const auto &image); + Utils::FilePath componentPath(const NodeMetaInfo &metaInfo) const; + QSet getBundleComponentDependencies(const ModelNode &node) const; + void export3DComponent(const ModelNode &node); + void exportItem(const ModelNode &node, const QPixmap &iconPixmap = QPixmap()); QPointer m_view; QPointer m_widget; Utils::UniqueObjectPtr m_importer; + std::unique_ptr m_zipWriter; + std::unique_ptr m_tempDir; + Utils::FilePath m_iconSavePath; static constexpr char BUNDLE_VERSION[] = "1.0"; }; diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index a11f420258a..9b9b7f75a91 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -2009,7 +2009,9 @@ void DesignerActionManager::createDefaultDesignerActions() rootCategory, QKeySequence(), Priorities::ExportComponent, - &exportComponent, + [&](const SelectionContext &context) { + m_bundleHelper->exportBundle(context.currentSingleSelectedNode()); + }, &is3DNode, &is3DNode)); diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index f12d07d1fc5..9b4f6b134dd 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -798,15 +798,6 @@ void add3DAssetToContentLibrary(const SelectionContext &selectionContext) selectionContext.view()->emitCustomNotification("add_3d_to_content_lib", {node}); } -void exportComponent(const SelectionContext &selectionContext) -{ -#ifdef DETACH_DISABLED_VIEWS - QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); -#endif - ModelNode node = selectionContext.currentSingleSelectedNode(); - selectionContext.view()->emitCustomNotification("export_item_as_bundle", {node}); -} - void goImplementation(const SelectionContext &selectionState) { addSignalHandlerOrGotoImplementation(selectionState, false); diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h index 45006067f02..d8cf8fe6230 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h @@ -97,7 +97,6 @@ void removeLayout(const SelectionContext &selectionContext); void removePositioner(const SelectionContext &selectionContext); void moveToComponent(const SelectionContext &selectionContext); void add3DAssetToContentLibrary(const SelectionContext &selectionContext); -void exportComponent(const SelectionContext &selectionContext); PropertyName getIndexPropertyName(const ModelNode &modelNode); void addItemToStackedContainer(const SelectionContext &selectionContext); void increaseIndexOfStackedContainer(const SelectionContext &selectionContext); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index fa7836870f5..16f550e9385 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -31,7 +32,6 @@ #include #include -#include #include @@ -43,14 +43,12 @@ #include #endif -#include #include #include #include #include #include #include -#include #include namespace QmlDesigner { @@ -75,6 +73,8 @@ WidgetInfo ContentLibraryView::widgetInfo() if (m_widget.isNull()) { m_widget = new ContentLibraryWidget(); + m_bundleHelper = std::make_unique(this, m_widget); + connect(m_widget, &ContentLibraryWidget::bundleMaterialDragStarted, this, [&] (QmlDesigner::ContentLibraryMaterial *mat) { m_draggedBundleMaterial = mat; @@ -399,14 +399,6 @@ void ContentLibraryView::customNotification(const AbstractView *view, else addLibItem(nodeList.first()); m_widget->showTab(ContentLibraryWidget::TabIndex::UserAssetsTab); - } else if (identifier == "export_item_as_bundle") { - // TODO: support exporting 2D items - if (nodeList.first().isComponent()) - exportLib3DComponent(nodeList.first()); - else - exportLibItem(nodeList.first()); - } else if (identifier == "export_material_as_bundle") { - exportLibItem(nodeList.first(), data.first().value()); } } @@ -439,8 +431,6 @@ void ContentLibraryView::modelNodePreviewPixmapChanged(const ModelNode &, { if (requestId == ADD_ITEM_REQ_ID) saveIconToBundle(pixmap); - else if (requestId == EXPORT_ITEM_REQ_ID) - addIconAndCloseZip(pixmap); } #ifdef QDS_USE_PROJECTSTORAGE @@ -502,123 +492,6 @@ void ContentLibraryView::applyBundleMaterialToDropTarget(const ModelNode &bundle } #endif -namespace { -Utils::FilePath componentPath([[maybe_unused]] const NodeMetaInfo &metaInfo) -{ -#ifdef QDS_USE_PROJECTSTORAGE - // TODO - return {}; -#else - return Utils::FilePath::fromString(metaInfo.componentFileName()); -#endif -} - -} // namespace - -QPair> ContentLibraryView::modelNodeToQmlString(const ModelNode &node, int depth) -{ - static QStringList depListIds; - - QString qml; - QSet assets; - - if (depth == 0) { - qml.append("import QtQuick\nimport QtQuick3D\n\n"); - depListIds.clear(); - } - - QString indent = QString(" ").repeated(depth * 4); - - qml += indent + node.simplifiedTypeName() + " {\n"; - - indent = QString(" ").repeated((depth + 1) * 4); - - qml += indent + "id: " + (depth == 0 ? "root" : node.id()) + " \n\n"; - - const QList excludedProps = {"x", "y", "z", "eulerRotation.x", "eulerRotation.y", - "eulerRotation.z", "scale.x", "scale.y", "scale.z", - "pivot.x", "pivot.y", "pivot.z"}; - const QList matProps = node.properties(); - for (const AbstractProperty &p : matProps) { - if (excludedProps.contains(p.name())) - continue; - - if (p.isVariantProperty()) { - QVariant pValue = p.toVariantProperty().value(); - QString val; - - if (!pValue.typeName()) { - // dynamic property with no value assigned - } else if (strcmp(pValue.typeName(), "QString") == 0 || strcmp(pValue.typeName(), "QColor") == 0) { - val = QLatin1String("\"%1\"").arg(pValue.toString()); - } else if (strcmp(pValue.typeName(), "QUrl") == 0) { - QString pValueStr = pValue.toString(); - val = QLatin1String("\"%1\"").arg(pValueStr); - if (!pValueStr.startsWith("#")) { - assets.insert({DocumentManager::currentResourcePath().toFSPathString(), - pValue.toString()}); - } - } else if (strcmp(pValue.typeName(), "QmlDesigner::Enumeration") == 0) { - val = pValue.value().toString(); - } else { - val = pValue.toString(); - } - if (p.isDynamic()) { - QString valWithColon = val.isEmpty() ? QString() : (": " + val); - qml += indent + "property " + p.dynamicTypeName() + " " + p.name() + valWithColon + "\n"; - } else { - qml += indent + p.name() + ": " + val + "\n"; - } - } else if (p.isBindingProperty()) { - ModelNode depNode = modelNodeForId(p.toBindingProperty().expression()); - QTC_ASSERT(depNode.isValid(), continue); - - if (p.isDynamic()) - qml += indent + "property " + p.dynamicTypeName() + " " + p.name() + ": " + depNode.id() + "\n"; - else - qml += indent + p.name() + ": " + depNode.id() + "\n"; - - if (depNode && !depListIds.contains(depNode.id())) { - depListIds.append(depNode.id()); - auto [depQml, depAssets] = modelNodeToQmlString(depNode, depth + 1); - qml += "\n" + depQml + "\n"; - assets.unite(depAssets); - } - } - } - - // add child nodes - const ModelNodes nodeChildren = node.directSubModelNodes(); - for (const ModelNode &childNode : nodeChildren) { - if (childNode && !depListIds.contains(childNode.id())) { - depListIds.append(childNode.id()); - auto [depQml, depAssets] = modelNodeToQmlString(childNode, depth + 1); - qml += "\n" + depQml + "\n"; - assets.unite(depAssets); - } - } - - indent = QString(" ").repeated(depth * 4); - - qml += indent + "}\n"; - - if (node.isComponent()) { - auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); - bool isBundle = node.type().startsWith(compUtils.componentBundlesTypePrefix().toLatin1()); - - if (depth > 0) { - // add component file to the dependency assets - Utils::FilePath compFilePath = componentPath(node.metaInfo()); - assets.insert({compFilePath.parentDir().path(), compFilePath.fileName()}); - } - - if (isBundle) - assets.unite(getBundleComponentDependencies(node)); - } - - return {qml, assets}; -} - void ContentLibraryView::addLibAssets(const QStringList &paths) { auto bundlePath = Utils::FilePath::fromString(Paths::bundlesPathSetting() + "/User/textures"); @@ -744,83 +617,11 @@ void ContentLibraryView::addLib3DComponent(const ModelNode &node) filesList); // generate and save icon - getImageFromCache(compDir.pathAppended(compFileName).path(), [&](const QImage &image) { + m_bundleHelper->getImageFromCache(compDir.pathAppended(compFileName).path(), [&](const QImage &image) { saveIconToBundle(image); }); } -void ContentLibraryView::exportLib3DComponent(const ModelNode &node) -{ - QString exportPath = getExportPath(node); - if (exportPath.isEmpty()) - return; - - // targetPath is a temp path for collecting and zipping assets, actual export target is where - // the user chose to export (i.e. exportPath) - QTemporaryDir tempDir; - QTC_ASSERT(tempDir.isValid(), return); - auto targetPath = Utils::FilePath::fromString(tempDir.path()); - - m_zipWriter = std::make_unique(exportPath); - - QString compBaseName = node.simplifiedTypeName(); - QString compFileName = compBaseName + ".qml"; - - auto compDir = Utils::FilePath::fromString(ModelUtils::componentFilePath(node)).parentDir(); - - QString iconPath = QLatin1String("icons/%1").arg(UniqueName::generateId(compBaseName) + ".png"); - - const Utils::FilePaths sourceFiles = compDir.dirEntries({{}, QDir::Files, QDirIterator::Subdirectories}); - const QStringList ignoreList {"_importdata.json", "qmldir", compBaseName + ".hints"}; - QStringList filesList; // 3D component's assets (dependencies) - - for (const Utils::FilePath &sourcePath : sourceFiles) { - Utils::FilePath relativePath = sourcePath.relativePathFrom(compDir); - if (ignoreList.contains(sourcePath.fileName()) || relativePath.startsWith("source scene")) - continue; - - m_zipWriter->addFile(relativePath.toFSPathString(), sourcePath.fileContents().value_or("")); - - if (sourcePath.fileName() != compFileName) // skip component file (only collect dependencies) - filesList.append(relativePath.path()); - } - - // add the item to the bundle json - QJsonObject jsonObj; - QJsonArray itemsArr; - itemsArr.append(QJsonObject { - {"name", node.simplifiedTypeName()}, - {"qml", compFileName}, - {"icon", iconPath}, - {"files", QJsonArray::fromStringList(filesList)} - }); - - jsonObj["items"] = itemsArr; - - auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); - jsonObj["id"] = compUtils.user3DBundleId(); - jsonObj["version"] = BUNDLE_VERSION; - - Utils::FilePath jsonFilePath = targetPath.pathAppended(Constants::BUNDLE_JSON_FILENAME); - m_zipWriter->addFile(jsonFilePath.fileName(), QJsonDocument(jsonObj).toJson()); - - // add icon - m_iconSavePath = targetPath.pathAppended(iconPath); - m_iconSavePath.parentDir().ensureWritableDir(); - getImageFromCache(compDir.pathAppended(compFileName).path(), [&](const QImage &image) { - addIconAndCloseZip(image); - }); -} - -QString ContentLibraryView::nodeNameToComponentFileName(const QString &name) const -{ - QString fileName = UniqueName::generateId(name, "Component"); - fileName[0] = fileName.at(0).toUpper(); - fileName.prepend("My"); - - return fileName + ".qml"; -} - void ContentLibraryView::addLibItem(const ModelNode &node, const QPixmap &iconPixmap) { auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); @@ -849,7 +650,7 @@ void ContentLibraryView::addLibItem(const ModelNode &node, const QPixmap &iconPi QJsonObject &jsonRef = m_widget->userModel()->bundleObjectRef(m_bundleId); QJsonArray itemsArr = jsonRef.value("items").toArray(); - QString qml = nodeNameToComponentFileName(name); + QString qml = m_bundleHelper->nodeNameToComponentFileName(name); // confirm overwrite if an item with same name exists if (m_widget->userModel()->jsonPropertyExists("qml", qml, m_bundleId)) { @@ -866,7 +667,7 @@ void ContentLibraryView::addLibItem(const ModelNode &node, const QPixmap &iconPi } // generate and save Qml file - auto [qmlString, depAssets] = modelNodeToQmlString(node); + auto [qmlString, depAssets] = m_bundleHelper->modelNodeToQmlString(node); const QList depAssetsList = depAssets.values(); QStringList depAssetsRelativePaths; @@ -932,123 +733,6 @@ void ContentLibraryView::addLibItem(const ModelNode &node, const QPixmap &iconPi } } -QString ContentLibraryView::getExportPath(const ModelNode &node) const -{ - QString defaultExportFileName = QLatin1String("%1.%2").arg(node.displayName(), - Constants::BUNDLE_SUFFIX); - Utils::FilePath projectFP = DocumentManager::currentProjectDirPath(); - if (projectFP.isEmpty()) { - projectFP = QmlDesignerPlugin::instance()->documentManager() - .currentDesignDocument()->fileName().parentDir(); - } - - QString dialogTitle = node.metaInfo().isQtQuick3DMaterial() ? tr("Export Material") - : tr("Export Component"); - return QFileDialog::getSaveFileName(m_widget, dialogTitle, - projectFP.pathAppended(defaultExportFileName).toFSPathString(), - tr("Qt Design Studio Bundle Files (*.%1)").arg(Constants::BUNDLE_SUFFIX)); -} - -QString ContentLibraryView::getImportPath() const -{ - Utils::FilePath projectFP = DocumentManager::currentProjectDirPath(); - if (projectFP.isEmpty()) { - projectFP = QmlDesignerPlugin::instance()->documentManager() - .currentDesignDocument()->fileName().parentDir(); - } - - return QFileDialog::getOpenFileName(m_widget, tr("Import Component"), projectFP.toFSPathString(), - tr("Qt Design Studio Bundle Files (*.%1)").arg(Constants::BUNDLE_SUFFIX)); -} - -void ContentLibraryView::exportLibItem(const ModelNode &node, const QPixmap &iconPixmap) -{ - QString exportPath = getExportPath(node); - if (exportPath.isEmpty()) - return; - - // targetPath is a temp path for collecting and zipping assets, actual export target is where - // the user chose to export (i.e. exportPath) - m_tempDir = std::make_unique(); - QTC_ASSERT(m_tempDir->isValid(), return); - auto targetPath = Utils::FilePath::fromString(m_tempDir->path()); - - m_zipWriter = std::make_unique(exportPath); - - QString name = node.variantProperty("objectName").value().toString(); - if (name.isEmpty()) - name = node.displayName(); - - QString qml = nodeNameToComponentFileName(name); - QString iconBaseName = UniqueName::generateId(name); - - // generate and save Qml file - auto [qmlString, depAssets] = modelNodeToQmlString(node); - const QList depAssetsList = depAssets.values(); - - QStringList depAssetsRelativePaths; - for (const AssetPath &assetPath : depAssetsList) - depAssetsRelativePaths.append(assetPath.relativePath); - - auto qmlFilePath = targetPath.pathAppended(qml); - auto result = qmlFilePath.writeFileContents(qmlString.toUtf8()); - QTC_ASSERT_EXPECTED(result, return); - m_zipWriter->addFile(qmlFilePath.fileName(), qmlString.toUtf8()); - - QString iconPath = QLatin1String("icons/%1.png").arg(iconBaseName); - - // add the item to the bundle json - QJsonObject jsonObj; - QJsonArray itemsArr; - itemsArr.append(QJsonObject { - {"name", name}, - {"qml", qml}, - {"icon", iconPath}, - {"files", QJsonArray::fromStringList(depAssetsRelativePaths)} - }); - - jsonObj["items"] = itemsArr; - - auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); - jsonObj["id"] = node.metaInfo().isQtQuick3DMaterial() ? compUtils.userMaterialsBundleId() - : compUtils.user3DBundleId(); - jsonObj["version"] = BUNDLE_VERSION; - - Utils::FilePath jsonFilePath = targetPath.pathAppended(Constants::BUNDLE_JSON_FILENAME); - m_zipWriter->addFile(jsonFilePath.fileName(), QJsonDocument(jsonObj).toJson()); - - // add item's dependency assets to the bundle zip - for (const AssetPath &assetPath : depAssetsList) - m_zipWriter->addFile(assetPath.relativePath, assetPath.absFilPath().fileContents().value_or("")); - - // add icon - QPixmap iconPixmapToSave; - if (node.metaInfo().isQtQuick3DCamera()) - iconPixmapToSave = m_widget->iconProvider()->requestPixmap("camera.png", nullptr, {}); - else if (node.metaInfo().isQtQuick3DLight()) - iconPixmapToSave = m_widget->iconProvider()->requestPixmap("light.png", nullptr, {}); - else - iconPixmapToSave = iconPixmap; - - m_iconSavePath = targetPath.pathAppended(iconPath); - if (iconPixmapToSave.isNull()) { - static_cast(model()->nodeInstanceView()) - ->previewImageDataForGenericNode(node, {}, {}, EXPORT_ITEM_REQ_ID); - } else { - addIconAndCloseZip(iconPixmapToSave); - } -} - -void ContentLibraryView::addIconAndCloseZip(const auto &image) { // auto: QImage or QPixmap - QByteArray iconByteArray; - QBuffer buffer(&iconByteArray); - buffer.open(QIODevice::WriteOnly); - image.save(&buffer, "PNG"); - - m_zipWriter->addFile("icons/" + m_iconSavePath.fileName(), iconByteArray); - m_zipWriter->close(); -}; - void ContentLibraryView::saveIconToBundle(const auto &image) { // auto: QImage or QPixmap bool iconSaved = image.save(m_iconSavePath.toFSPathString()); if (iconSaved) @@ -1061,7 +745,7 @@ void ContentLibraryView::saveIconToBundle(const auto &image) { // auto: QImage o void ContentLibraryView::importBundleToContentLib() { - QString importPath = getImportPath(); + QString importPath = m_bundleHelper->getImportPath(); if (importPath.isEmpty()) return; @@ -1145,66 +829,6 @@ void ContentLibraryView::importBundleToContentLib() QTC_ASSERT_EXPECTED(result,); } -/** - * @brief Generates an icon image from a qml component - * @param qmlPath path to the qml component file to be rendered - * @param iconPath output save path of the generated icon - */ -void ContentLibraryView::getImageFromCache(const QString &qmlPath, - std::function successCallback) -{ - m_imageCache.requestSmallImage( - Utils::PathString{qmlPath}, - successCallback, - [&](ImageCache::AbortReason abortReason) { - if (abortReason == ImageCache::AbortReason::Abort) { - qWarning() << QLatin1String("ContentLibraryView::getImageFromCache(): icon generation " - "failed for path %1, reason: Abort").arg(qmlPath); - } else if (abortReason == ImageCache::AbortReason::Failed) { - qWarning() << QLatin1String("ContentLibraryView::getImageFromCache(): icon generation " - "failed for path %1, reason: Failed").arg(qmlPath); - } else if (abortReason == ImageCache::AbortReason::NoEntry) { - qWarning() << QLatin1String("ContentLibraryView::getImageFromCache(): icon generation " - "failed for path %1, reason: NoEntry").arg(qmlPath); - } - }); -} - -QSet ContentLibraryView::getBundleComponentDependencies(const ModelNode &node) const -{ - const QString compFileName = node.simplifiedTypeName() + ".qml"; - - Utils::FilePath compPath = componentPath(node.metaInfo()).parentDir(); - - QTC_ASSERT(compPath.exists(), return {}); - - QSet depList; - - Utils::FilePath assetRefPath = compPath.pathAppended(Constants::COMPONENT_BUNDLES_ASSET_REF_FILE); - - Utils::expected_str assetRefContents = assetRefPath.fileContents(); - if (!assetRefContents.has_value()) { - qWarning() << __FUNCTION__ << assetRefContents.error(); - return {}; - } - - QJsonDocument jsonDoc = QJsonDocument::fromJson(assetRefContents.value()); - if (jsonDoc.isNull()) { - qWarning() << __FUNCTION__ << "Invalid json file" << assetRefPath; - return {}; - } - - const QJsonObject rootObj = jsonDoc.object(); - const QStringList bundleAssets = rootObj.keys(); - - for (const QString &asset : bundleAssets) { - if (rootObj.value(asset).toArray().contains(compFileName)) - depList.insert({compPath.toFSPathString(), asset}); - } - - return depList; -} - ModelNode ContentLibraryView::getBundleMaterialDefaultInstance(const TypeName &type) { ModelNode matLib = Utils3D::materialLibraryNode(this); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h index fc5288389ad..deba7b93a61 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.h @@ -13,41 +13,19 @@ #include #include -class ZipWriter; - QT_FORWARD_DECLARE_CLASS(QImage) QT_FORWARD_DECLARE_CLASS(QPixmap) QT_FORWARD_DECLARE_CLASS(QTemporaryDir) namespace QmlDesigner { +class BundleHelper; class ContentLibraryItem; class ContentLibraryMaterial; class ContentLibraryTexture; class ContentLibraryWidget; class Model; -struct AssetPath -{ - QString basePath; - QString relativePath; - - Utils::FilePath absFilPath() const - { - return Utils::FilePath::fromString(basePath).pathAppended(relativePath); - } - - bool operator==(const AssetPath &other) const - { - return basePath == other.basePath && relativePath == other.relativePath; - } - - friend size_t qHash(const AssetPath &asset) - { - return ::qHash(asset.relativePath); - } -}; - class ContentLibraryView : public AbstractView { Q_OBJECT @@ -87,18 +65,8 @@ private: void updateBundlesQuick3DVersion(); void addLibAssets(const QStringList &paths); void addLib3DComponent(const ModelNode &node); - void exportLib3DComponent(const ModelNode &node); void addLibItem(const ModelNode &node, const QPixmap &iconPixmap = {}); - void exportLibItem(const ModelNode &node, const QPixmap &iconPixmap = {}); void importBundleToContentLib(); - void getImageFromCache(const QString &qmlPath, - std::function successCallback); - QSet getBundleComponentDependencies(const ModelNode &node) const; - QString getExportPath(const ModelNode &node) const; - QString getImportPath() const; - QString nodeNameToComponentFileName(const QString &name) const; - QPair> modelNodeToQmlString(const ModelNode &node, int depth = 0); - void addIconAndCloseZip(const auto &image); void saveIconToBundle(const auto &image); #ifdef QDS_USE_PROJECTSTORAGE @@ -117,6 +85,7 @@ private: ContentLibraryMaterial *m_draggedBundleMaterial = nullptr; ContentLibraryTexture *m_draggedBundleTexture = nullptr; ContentLibraryItem *m_draggedBundleItem = nullptr; + std::unique_ptr m_bundleHelper; AsynchronousImageCache &m_imageCache; bool m_bundleMaterialAddToSelected = false; bool m_hasQuick3DImport = false; @@ -125,12 +94,9 @@ private: Utils::FilePath m_iconSavePath; QString m_generatedFolderName; QString m_bundleId; - std::unique_ptr m_zipWriter; - std::unique_ptr m_tempDir; static constexpr char BUNDLE_VERSION[] = "1.0"; static constexpr char ADD_ITEM_REQ_ID[] = "AddItemReqId"; - static constexpr char EXPORT_ITEM_REQ_ID[] = "ExportItemReqId"; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index 07ff875b89a..3bb04e2301c 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -380,10 +380,7 @@ void Edit3DWidget::createContextMenu() m_exportBundleAction = m_contextMenu->addAction( contextIcon(DesignerIcons::CreateIcon), // TODO: placeholder icon tr("Export Component"), [&] { -#ifdef DETACH_DISABLED_VIEWS - QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); -#endif - view()->emitCustomNotification("export_item_as_bundle", {m_contextMenuTarget}); // To ContentLibrary + m_bundleHelper->exportBundle(m_contextMenuTarget); }); m_contextMenu->addSeparator(); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp index 775ae4f6a94..bb22c9b5959 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp @@ -385,12 +385,8 @@ void MaterialBrowserWidget::importMaterial() } void MaterialBrowserWidget::exportMaterial() { -#ifdef DETACH_DISABLED_VIEWS - QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("ContentLibrary"); -#endif ModelNode mat = m_materialBrowserModel->selectedMaterial(); - m_materialBrowserView->emitCustomNotification("export_material_as_bundle", {mat}, - {m_previewImageProvider->getPixmap(mat)}); // to ContentLibrary + m_bundleHelper->exportBundle(mat, m_previewImageProvider->getPixmap(mat)); } QString MaterialBrowserWidget::qmlSourcesPath() From 88323e429ff5d3affeae10b504be1f6d55431684 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Fri, 30 Aug 2024 11:23:48 +0000 Subject: [PATCH 113/193] Revert "Enforce that plugins can't be used as library dependencies" This reverts commit f5bb913c9da376fed78caff2639eb2f1f2f3765e. Reason for revert: This breaks snapshots build for the license plugin Change-Id: I52a9f0b40081d648de68a5bdc3d9b3962e19061a Reviewed-by: Thomas Hartmann --- cmake/QtCreatorAPI.cmake | 12 ------------ cmake/QtCreatorAPIInternal.cmake | 16 ---------------- 2 files changed, 28 deletions(-) diff --git a/cmake/QtCreatorAPI.cmake b/cmake/QtCreatorAPI.cmake index a0876c40086..5d39157b020 100644 --- a/cmake/QtCreatorAPI.cmake +++ b/cmake/QtCreatorAPI.cmake @@ -129,9 +129,6 @@ function(add_qtc_library name) "CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;SYSTEM_INCLUDES;PUBLIC_INCLUDES;PUBLIC_SYSTEM_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES;PRIVATE_COMPILE_OPTIONS;PUBLIC_COMPILE_OPTIONS" ${ARGN} ) - check_library_dependencies(${_arg_DEPENDS}) - check_library_dependencies(${_arg_PUBLIC_DEPENDS}) - get_default_defines(default_defines_copy ${_arg_ALLOW_ASCII_CASTS}) if (${_arg_UNPARSED_ARGUMENTS}) @@ -339,9 +336,6 @@ function(add_qtc_plugin target_name) ${ARGN} ) - check_library_dependencies(${_arg_DEPENDS}) - check_library_dependencies(${_arg_PUBLIC_DEPENDS}) - if (${_arg_UNPARSED_ARGUMENTS}) message(FATAL_ERROR "add_qtc_plugin had unparsed arguments") endif() @@ -621,9 +615,6 @@ function(extend_qtc_plugin target_name) return() endif() - check_library_dependencies(${_arg_DEPENDS}) - check_library_dependencies(${_arg_PUBLIC_DEPENDS}) - extend_qtc_target(${target_name} ${ARGN}) endfunction() @@ -633,9 +624,6 @@ function(extend_qtc_library target_name) return() endif() - check_library_dependencies(${_arg_DEPENDS}) - check_library_dependencies(${_arg_PUBLIC_DEPENDS}) - extend_qtc_target(${target_name} ${ARGN}) endfunction() diff --git a/cmake/QtCreatorAPIInternal.cmake b/cmake/QtCreatorAPIInternal.cmake index 928c7fc22e8..06d53a992c8 100644 --- a/cmake/QtCreatorAPIInternal.cmake +++ b/cmake/QtCreatorAPIInternal.cmake @@ -361,10 +361,6 @@ function(find_dependent_plugins varName) if(NOT TARGET ${i}) continue() endif() - get_property(_class_name TARGET "${i}" PROPERTY QTC_PLUGIN_CLASS_NAME) - if (NOT _class_name) - message(SEND_ERROR "${i} is a library, not a plugin!") - endif() set(_dep) get_property(_dep TARGET "${i}" PROPERTY _arg_DEPENDS) if (_dep) @@ -381,18 +377,6 @@ function(find_dependent_plugins varName) set("${varName}" ${_RESULT} PARENT_SCOPE) endfunction() -function(check_library_dependencies) - foreach(i ${ARGN}) - if (NOT TARGET ${i}) - continue() - endif() - get_property(_class_name TARGET "${i}" PROPERTY QTC_PLUGIN_CLASS_NAME) - if (_class_name) - message(SEND_ERROR "${i} is a plugin, not a library!") - endif() - endforeach() -endfunction() - function(enable_pch target) if (BUILD_WITH_PCH) # Skip PCH for targets that do not use the expected visibility settings: From ecf5fca803ce64574174ce184ee7379b3ba1dc56 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Fri, 30 Aug 2024 16:19:46 +0200 Subject: [PATCH 114/193] QmlDesigner: Fix include The designersettings have been moved. Change-Id: Id3d9cfbf99aa086b64e1927c4a1395b1f56a9708 Reviewed-by: Knud Dollereder --- src/plugins/qmldesigner/qmldesignerplugin.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/qmldesignerplugin.h b/src/plugins/qmldesigner/qmldesignerplugin.h index ebb2e2bda9c..797250766a9 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.h +++ b/src/plugins/qmldesigner/qmldesignerplugin.h @@ -6,13 +6,13 @@ #include "documentmanager.h" #include "qmldesigner_global.h" -#include -#include #include +#include #include #include +#include #include From b37f8cfca2a9fcc67cf04f74633131b8ad656729 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Fri, 30 Aug 2024 20:31:47 +0200 Subject: [PATCH 115/193] QmlDesigner: Remove include for designersettings from qmldesignerplugin.h The designersettings are now part of qmldesignerbase. Change-Id: Ic0583b21a1c8d8276e50cc215e8bbf428a2a890e Reviewed-by: Thomas Hartmann --- .../qmldesigner/components/assetslibrary/assetslibrarymodel.cpp | 2 ++ src/plugins/qmldesigner/components/componentcore/crumblebar.cpp | 2 ++ .../qmldesigner/components/componentcore/viewmanager.cpp | 2 ++ .../components/contentlibrary/contentlibrarymaterialsmodel.cpp | 2 ++ .../components/contentlibrary/contentlibrarywidget.cpp | 2 ++ src/plugins/qmldesigner/components/debugview/debugview.cpp | 2 ++ src/plugins/qmldesigner/components/edit3d/edit3dviewconfig.h | 2 ++ .../qmldesigner/components/itemlibrary/itemlibrarywidget.cpp | 2 ++ .../components/propertyeditor/propertyeditorcontextobject.cpp | 2 ++ .../components/propertyeditor/propertyeditorqmlbackend.cpp | 2 ++ src/plugins/qmldesigner/designmodewidget.cpp | 1 + src/plugins/qmldesigner/documentwarningwidget.cpp | 2 ++ .../qmldesigner/instances/interactiveconnectionmanager.cpp | 2 ++ src/plugins/qmldesigner/openuiqmlfiledialog.cpp | 2 ++ src/plugins/qmldesigner/qmldesignerplugin.h | 1 - 15 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp index 396c3e274aa..11eb4b27162 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp @@ -7,6 +7,8 @@ #include #include +#include + #include #include diff --git a/src/plugins/qmldesigner/components/componentcore/crumblebar.cpp b/src/plugins/qmldesigner/components/componentcore/crumblebar.cpp index 005e353be25..c6843b5b4f7 100644 --- a/src/plugins/qmldesigner/components/componentcore/crumblebar.cpp +++ b/src/plugins/qmldesigner/components/componentcore/crumblebar.cpp @@ -8,6 +8,8 @@ #include #include +#include + #include #include #include diff --git a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp index 293e3838189..9694aa4802d 100644 --- a/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/viewmanager.cpp @@ -30,6 +30,8 @@ #include #include +#include + #include #include diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp index e407a851340..20635706cf4 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarymaterialsmodel.cpp @@ -15,6 +15,8 @@ #include #include +#include + #include #include #include diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp index d7850a695c8..7e24114318c 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarywidget.cpp @@ -20,6 +20,8 @@ #include #include +#include + #include #include diff --git a/src/plugins/qmldesigner/components/debugview/debugview.cpp b/src/plugins/qmldesigner/components/debugview/debugview.cpp index 6635f06f376..059c203c8a6 100644 --- a/src/plugins/qmldesigner/components/debugview/debugview.cpp +++ b/src/plugins/qmldesigner/components/debugview/debugview.cpp @@ -6,6 +6,8 @@ #include +#include + #include #include #include diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dviewconfig.h b/src/plugins/qmldesigner/components/edit3d/edit3dviewconfig.h index 33d40b332e7..1e53768957b 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dviewconfig.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dviewconfig.h @@ -6,6 +6,8 @@ #include #include +#include + #include #include diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 749701f508d..e2bac7f26da 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -29,6 +29,8 @@ # include #endif +#include + #include #include #include diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp index 2fdd5416b71..48135109c11 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp @@ -14,6 +14,8 @@ #include "qmlobjectnode.h" #include "qmltimeline.h" +#include + #include #include #include diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp index 24ab8337410..0c28e5503df 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp @@ -20,6 +20,8 @@ #include +#include + #include #include #include diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index 6a366b877a3..ea0f4ad8e40 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/src/plugins/qmldesigner/documentwarningwidget.cpp b/src/plugins/qmldesigner/documentwarningwidget.cpp index a1cc12d8254..cdd06b7bb28 100644 --- a/src/plugins/qmldesigner/documentwarningwidget.cpp +++ b/src/plugins/qmldesigner/documentwarningwidget.cpp @@ -8,6 +8,8 @@ #include #include +#include + #include #include #include diff --git a/src/plugins/qmldesigner/instances/interactiveconnectionmanager.cpp b/src/plugins/qmldesigner/instances/interactiveconnectionmanager.cpp index 2c3de8082a3..b6c045f763f 100644 --- a/src/plugins/qmldesigner/instances/interactiveconnectionmanager.cpp +++ b/src/plugins/qmldesigner/instances/interactiveconnectionmanager.cpp @@ -7,6 +7,8 @@ #include +#include + #include #include diff --git a/src/plugins/qmldesigner/openuiqmlfiledialog.cpp b/src/plugins/qmldesigner/openuiqmlfiledialog.cpp index eacb81aa000..3c62c593c12 100644 --- a/src/plugins/qmldesigner/openuiqmlfiledialog.cpp +++ b/src/plugins/qmldesigner/openuiqmlfiledialog.cpp @@ -5,6 +5,8 @@ #include +#include + #include #include diff --git a/src/plugins/qmldesigner/qmldesignerplugin.h b/src/plugins/qmldesigner/qmldesignerplugin.h index 797250766a9..7487420a1f8 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.h +++ b/src/plugins/qmldesigner/qmldesignerplugin.h @@ -12,7 +12,6 @@ #include #include -#include #include From 40f462cf07e7ed421d91ec33207bc53bb26cf4ff Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 22 Aug 2024 12:56:33 +0200 Subject: [PATCH 116/193] Enforce that plugins can't be used as library dependencies We want to use the libraries in different projects where the plugins are not present. Change-Id: I51382ac7cfcf06871ac99a6b53b84840ca39bf00 Reviewed-by: Cristian Adam Reviewed-by: Alexandru Croitor --- cmake/QtCreatorAPI.cmake | 14 ++++++++++++++ cmake/QtCreatorAPIInternal.cmake | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/cmake/QtCreatorAPI.cmake b/cmake/QtCreatorAPI.cmake index 5d39157b020..6e3ff0e1661 100644 --- a/cmake/QtCreatorAPI.cmake +++ b/cmake/QtCreatorAPI.cmake @@ -129,6 +129,9 @@ function(add_qtc_library name) "CONDITION;DEPENDS;PUBLIC_DEPENDS;DEFINES;PUBLIC_DEFINES;INCLUDES;SYSTEM_INCLUDES;PUBLIC_INCLUDES;PUBLIC_SYSTEM_INCLUDES;SOURCES;EXPLICIT_MOC;SKIP_AUTOMOC;EXTRA_TRANSLATIONS;PROPERTIES;PRIVATE_COMPILE_OPTIONS;PUBLIC_COMPILE_OPTIONS" ${ARGN} ) + check_library_dependencies(${_arg_DEPENDS}) + check_library_dependencies(${_arg_PUBLIC_DEPENDS}) + get_default_defines(default_defines_copy ${_arg_ALLOW_ASCII_CASTS}) if (${_arg_UNPARSED_ARGUMENTS}) @@ -336,6 +339,9 @@ function(add_qtc_plugin target_name) ${ARGN} ) + check_library_dependencies(${_arg_DEPENDS}) + check_library_dependencies(${_arg_PUBLIC_DEPENDS}) + if (${_arg_UNPARSED_ARGUMENTS}) message(FATAL_ERROR "add_qtc_plugin had unparsed arguments") endif() @@ -560,6 +566,8 @@ function(add_qtc_plugin target_name) ${_arg_PROPERTIES} ) + set_property(TARGET ${target_name} APPEND PROPERTY EXPORT_PROPERTIES "QTC_PLUGIN_CLASS_NAME") + if (NOT _arg_SKIP_PCH) enable_pch(${target_name}) endif() @@ -615,6 +623,9 @@ function(extend_qtc_plugin target_name) return() endif() + check_library_dependencies(${_arg_DEPENDS}) + check_library_dependencies(${_arg_PUBLIC_DEPENDS}) + extend_qtc_target(${target_name} ${ARGN}) endfunction() @@ -624,6 +635,9 @@ function(extend_qtc_library target_name) return() endif() + check_library_dependencies(${_arg_DEPENDS}) + check_library_dependencies(${_arg_PUBLIC_DEPENDS}) + extend_qtc_target(${target_name} ${ARGN}) endfunction() diff --git a/cmake/QtCreatorAPIInternal.cmake b/cmake/QtCreatorAPIInternal.cmake index 06d53a992c8..928c7fc22e8 100644 --- a/cmake/QtCreatorAPIInternal.cmake +++ b/cmake/QtCreatorAPIInternal.cmake @@ -361,6 +361,10 @@ function(find_dependent_plugins varName) if(NOT TARGET ${i}) continue() endif() + get_property(_class_name TARGET "${i}" PROPERTY QTC_PLUGIN_CLASS_NAME) + if (NOT _class_name) + message(SEND_ERROR "${i} is a library, not a plugin!") + endif() set(_dep) get_property(_dep TARGET "${i}" PROPERTY _arg_DEPENDS) if (_dep) @@ -377,6 +381,18 @@ function(find_dependent_plugins varName) set("${varName}" ${_RESULT} PARENT_SCOPE) endfunction() +function(check_library_dependencies) + foreach(i ${ARGN}) + if (NOT TARGET ${i}) + continue() + endif() + get_property(_class_name TARGET "${i}" PROPERTY QTC_PLUGIN_CLASS_NAME) + if (_class_name) + message(SEND_ERROR "${i} is a plugin, not a library!") + endif() + endforeach() +endfunction() + function(enable_pch target) if (BUILD_WITH_PCH) # Skip PCH for targets that do not use the expected visibility settings: From 8dfe44db93f959d3ccb5a43c82a370f9c60eecf9 Mon Sep 17 00:00:00 2001 From: Knud Dollereder Date: Tue, 3 Sep 2024 11:54:57 +0200 Subject: [PATCH 117/193] Respect the task hubs tasksCleared signal Fixes: QDS-13528 Change-Id: I86b620e31f5a3e718ea9e1d56d50dc2d20a96708 Reviewed-by: Thomas Hartmann --- .../qmldesigner/components/toolbar/messagemodel.cpp | 13 ++++++++++++- .../qmldesigner/components/toolbar/messagemodel.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/toolbar/messagemodel.cpp b/src/plugins/qmldesigner/components/toolbar/messagemodel.cpp index ae2755a603e..49ff3b8aaff 100644 --- a/src/plugins/qmldesigner/components/toolbar/messagemodel.cpp +++ b/src/plugins/qmldesigner/components/toolbar/messagemodel.cpp @@ -107,6 +107,7 @@ void MessageModel::setupTaskHub() connect(hub, &ProjectExplorer::TaskHub::categoryAdded, this, &MessageModel::addCategory); connect(hub, &ProjectExplorer::TaskHub::taskAdded, this, &MessageModel::addTask); connect(hub, &ProjectExplorer::TaskHub::taskRemoved, this, &MessageModel::removeTask); + connect(hub, &ProjectExplorer::TaskHub::tasksCleared, this, &MessageModel::clearTasks); } void MessageModel::addCategory(const ProjectExplorer::TaskCategory &category) @@ -126,7 +127,7 @@ void MessageModel::addTask(const ProjectExplorer::Task &task) void MessageModel::removeTask(const ProjectExplorer::Task &task) { for (int i = 0; std::cmp_less(i, m_tasks.size()); i++) { - if (m_tasks.at(i) == task) { + if (m_tasks[static_cast(i)] == task) { beginRemoveRows(QModelIndex(), i, i); m_tasks.erase(m_tasks.begin() + i); endRemoveRows(); @@ -135,3 +136,13 @@ void MessageModel::removeTask(const ProjectExplorer::Task &task) } } } + +void MessageModel::clearTasks(const Utils::Id &categoryId) +{ + beginResetModel(); + std::erase_if(m_tasks, [categoryId](const ProjectExplorer::Task& task) { + return task.category == categoryId; + }); + endResetModel(); + emit modelChanged(); +} diff --git a/src/plugins/qmldesigner/components/toolbar/messagemodel.h b/src/plugins/qmldesigner/components/toolbar/messagemodel.h index e6748910589..ccba4f66b68 100644 --- a/src/plugins/qmldesigner/components/toolbar/messagemodel.h +++ b/src/plugins/qmldesigner/components/toolbar/messagemodel.h @@ -44,6 +44,7 @@ private: void addCategory(const ProjectExplorer::TaskCategory &category); void addTask(const ProjectExplorer::Task &task); void removeTask(const ProjectExplorer::Task &task); + void clearTasks(const Utils::Id &categoryId); std::vector m_tasks = {}; std::unordered_map m_categories = {}; From 3998ba94a7e8fc584eee343455eb2eb9b96add55 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 3 Sep 2024 12:33:18 +0200 Subject: [PATCH 118/193] QmlDesigner: Fix timeline recording We have to set the new timeline even if the current was invalid. Task-number: QDS-13532 Change-Id: I7cf1ed33248d89c87107b924733ae31335d20edb Reviewed-by: Marco Bubke --- .../qmldesigner/components/timelineeditor/timelineview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp index 4cfc6f03207..97b59eb2491 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp @@ -468,11 +468,11 @@ void TimelineView::setTimelineRecording(bool value) void TimelineView::setCurrentTimeline(const ModelNode &timeline) { - if (QmlTimeline currentTimeline = currentTimelineNode()) { + if (QmlTimeline currentTimeline = currentTimelineNode()) currentTimeline.toogleRecording(false); + if (isAttached()) model()->setCurrentTimelineNode(timeline); - } } void TimelineView::customNotification(const AbstractView * /*view*/, From 4e95d171e2851b08bfab4032ef8a93ce331b90e3 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 30 Aug 2024 17:38:50 +0300 Subject: [PATCH 119/193] QmlDesigner: Fix triggering "Edit in 3D view" from 2D view If activating another view hides 2D view, 2D view detaches, which caused custom notification to not be sent as view no longer had model. Refactored the relevant cases to store node's internal id before the view gets detached and emit notification directly via model pointer. Fixes: QDS-13402 Change-Id: I21400646aed8871474a4618da69ba8a001bad361 Reviewed-by: Mahmoud Badri --- .../components/componentcore/modelnodeoperations.cpp | 9 ++++++--- src/plugins/qmldesigner/components/edit3d/edit3dview.cpp | 6 +++--- .../qmldesigner/components/formeditor/view3dtool.cpp | 6 ++++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index 9b4f6b134dd..c17926b9283 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -1695,12 +1695,15 @@ void editIn3dView(const SelectionContext &selectionContext) } if (targetNode.isValid()) { + qint32 id = targetNode.internalId(); + Model *model = selectionContext.model(); QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("Editor3D", true); if (scenePos.isNull()) { - selectionContext.model()->emitView3DAction(View3DActionType::AlignViewToCamera, true); + model->emitView3DAction(View3DActionType::AlignViewToCamera, true); } else { - selectionContext.view()->emitCustomNotification("pick_3d_node_from_2d_scene", - {targetNode}, {scenePos}); + model->emitCustomNotification(selectionContext.view(), + "pick_3d_node_from_2d_scene", + {}, {scenePos, id}); } } } diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index 8f9d5fd9cbd..ed86218d37b 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -456,16 +456,16 @@ void Edit3DView::customNotification([[maybe_unused]] const AbstractView *view, [[maybe_unused]] const QList &nodeList, [[maybe_unused]] const QList &data) { - if (identifier == "pick_3d_node_from_2d_scene" && data.size() == 1 && nodeList.size() == 1) { + if (identifier == "pick_3d_node_from_2d_scene" && data.size() == 2) { // Pick via 2D view, data has pick coordinates in main scene coordinates QTimer::singleShot(0, this, [=, self = QPointer{this}]() { if (!self) return; self->emitView3DAction(View3DActionType::GetNodeAtMainScenePos, - QVariantList{data[0], nodeList[0].internalId()}); + QVariantList{data[0], data[1]}); self->m_nodeAtPosReqType = NodeAtPosReqType::MainScenePick; - self->m_pickView3dNode = nodeList[0]; + self->m_pickView3dNode = self->modelNodeForInternalId(qint32(data[1].toInt())); }); } } diff --git a/src/plugins/qmldesigner/components/formeditor/view3dtool.cpp b/src/plugins/qmldesigner/components/formeditor/view3dtool.cpp index a494d467752..841c68b8633 100644 --- a/src/plugins/qmldesigner/components/formeditor/view3dtool.cpp +++ b/src/plugins/qmldesigner/components/formeditor/view3dtool.cpp @@ -54,9 +54,11 @@ void View3DTool::mouseReleaseEvent(const QList &, QGraphicsSceneMouseEvent *event) { if (m_view3dNode.isValid()) { + Model *model = view()->model(); + qint32 id = m_view3dNode.internalId(); QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("Editor3D", true); - view()->emitCustomNotification("pick_3d_node_from_2d_scene", - {m_view3dNode}, {event->scenePos()}); + model->emitCustomNotification(view(), "pick_3d_node_from_2d_scene", + {}, {event->scenePos(), id}); } view()->changeToSelectionTool(); From 23b2d3720b926e26db66deef27883b2589012a53 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Thu, 29 Aug 2024 18:38:02 +0200 Subject: [PATCH 120/193] QmlDesigner: Cleanup new IssuesOutputPanel * Add highlight functionality to StudioControls.AbstractButton * Add new icon font * Use icon font instead of PNGs for icons * Remove unnecessary files * Fix IssuesOutputPanel opening/closing logic * Adapt IssuesOutputPanel to theming * Add scroll to bottom when new messages are added * Fix application closing signal to close IssuesOutputPanel Change-Id: Ibdefbbc9980881575c9de8deac26efacd08ab0da Reviewed-by: Thomas Hartmann --- .../imports/StudioControls/AbstractButton.qml | 30 +- .../imports/StudioTheme/InternalConstants.qml | 449 +++++++++--------- .../imports/StudioTheme/icons.ttf | Bin 66776 -> 65872 bytes .../qmldesigner/statusbar/CloseButton.qml | 66 --- .../statusbar/IconButtonCheckable.qml | 72 --- .../statusbar/IssuesOutputPanel.qml | 116 ++--- .../statusbar/IssuesOutputToolBar.qml | 104 ---- .../qmldesigner/statusbar/IssuesPanel.qml | 65 +-- .../qtcreator/qmldesigner/statusbar/Main.qml | 70 +-- .../statusbar/MyLinkTextButton.ui.qml | 50 -- .../statusbar/NotificationButton.qml | 244 ++++++++++ .../statusbar/NotificationButton.ui.qml | 351 -------------- .../qmldesigner/statusbar/OutputPanel.qml | 40 +- .../qmldesigner/statusbar/TabBarButton.qml | 167 +++++++ .../qmldesigner/statusbar/TabBarButton.ui.qml | 56 --- .../qmldesigner/statusbar/images/CodeView.png | Bin 24757 -> 0 bytes .../statusbar/images/OutputView.png | Bin 9351 -> 0 bytes .../statusbar/images/delete_trash.png | Bin 299 -> 0 bytes .../statusbar/images/errorActive.png | Bin 403 -> 0 bytes .../statusbar/images/errorPassive.png | Bin 342 -> 0 bytes .../statusbar/images/outputIcon.png | Bin 244 -> 0 bytes .../qmldesigner/statusbar/images/thinBin.png | Bin 216 -> 0 bytes .../statusbar/images/warningsActive.png | Bin 403 -> 0 bytes .../statusbar/images/warningsPassive.png | Bin 286 -> 0 bytes .../components/componentcore/theme.h | 3 + .../qmldesignerbase/utils/windowmanager.cpp | 12 +- 26 files changed, 833 insertions(+), 1062 deletions(-) delete mode 100644 share/qtcreator/qmldesigner/statusbar/CloseButton.qml delete mode 100644 share/qtcreator/qmldesigner/statusbar/IconButtonCheckable.qml delete mode 100644 share/qtcreator/qmldesigner/statusbar/IssuesOutputToolBar.qml delete mode 100644 share/qtcreator/qmldesigner/statusbar/MyLinkTextButton.ui.qml create mode 100644 share/qtcreator/qmldesigner/statusbar/NotificationButton.qml delete mode 100644 share/qtcreator/qmldesigner/statusbar/NotificationButton.ui.qml create mode 100644 share/qtcreator/qmldesigner/statusbar/TabBarButton.qml delete mode 100644 share/qtcreator/qmldesigner/statusbar/TabBarButton.ui.qml delete mode 100644 share/qtcreator/qmldesigner/statusbar/images/CodeView.png delete mode 100644 share/qtcreator/qmldesigner/statusbar/images/OutputView.png delete mode 100644 share/qtcreator/qmldesigner/statusbar/images/delete_trash.png delete mode 100644 share/qtcreator/qmldesigner/statusbar/images/errorActive.png delete mode 100644 share/qtcreator/qmldesigner/statusbar/images/errorPassive.png delete mode 100644 share/qtcreator/qmldesigner/statusbar/images/outputIcon.png delete mode 100644 share/qtcreator/qmldesigner/statusbar/images/thinBin.png delete mode 100644 share/qtcreator/qmldesigner/statusbar/images/warningsActive.png delete mode 100644 share/qtcreator/qmldesigner/statusbar/images/warningsPassive.png diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/AbstractButton.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/AbstractButton.qml index 79f27ddaf27..703591887aa 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/AbstractButton.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/AbstractButton.qml @@ -3,7 +3,7 @@ import QtQuick import QtQuick.Templates as T -import StudioTheme 1.0 as StudioTheme +import StudioTheme as StudioTheme T.AbstractButton { id: control @@ -111,6 +111,34 @@ T.AbstractButton { } } + function highlight() { + // Only run the highlight animation if not running already and if default state is active + if (highlightAnimation.running || control.state !== "default") + return + + highlightAnimation.start() + } + + component MyColorAnimation: ColorAnimation { + target: buttonBackground + property: "color" + duration: 750 + } + + SequentialAnimation { + id: highlightAnimation + running: false + + MyColorAnimation { to: StudioTheme.Values.themeConnectionEditorButtonBorder_hover } + MyColorAnimation { to: control.style.background.idle } + MyColorAnimation { to: StudioTheme.Values.themeConnectionEditorButtonBorder_hover } + MyColorAnimation { to: control.style.background.idle } + MyColorAnimation { to: StudioTheme.Values.themeConnectionEditorButtonBorder_hover } + MyColorAnimation { to: control.style.background.idle } + } + + onStateChanged: highlightAnimation.stop() + states: [ State { name: "default" diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml index 3c74243f684..3eb90118374 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml @@ -156,229 +156,232 @@ QtObject { readonly property string edit_medium: "\u00AF" readonly property string edit_small: "\u00B0" readonly property string effects: "\u00B1" - readonly property string events_small: "\u00B2" - readonly property string export_medium: "\u00B3" - readonly property string eyeDropper: "\u00B4" - readonly property string favorite: "\u00B5" - readonly property string fitAll_medium: "\u00B6" - readonly property string fitSelected_small: "\u00B7" - readonly property string fitSelection_medium: "\u00B8" - readonly property string fitToView_medium: "\u00B9" - readonly property string flowAction: "\u00BA" - readonly property string flowTransition: "\u00BB" - readonly property string fontStyleBold: "\u00BC" - readonly property string fontStyleItalic: "\u00BD" - readonly property string fontStyleStrikethrough: "\u00BE" - readonly property string fontStyleUnderline: "\u00BF" - readonly property string forward_medium: "\u00C0" - readonly property string globalOrient_medium: "\u00C1" - readonly property string gradient: "\u00C2" - readonly property string gridView: "\u00C3" - readonly property string grid_medium: "\u00C4" - readonly property string group_small: "\u00C5" - readonly property string help: "\u00C6" - readonly property string home_large: "\u00C7" - readonly property string idAliasOff: "\u00C8" - readonly property string idAliasOn: "\u00C9" - readonly property string import_medium: "\u00CA" - readonly property string imported: "\u00CB" - readonly property string importedModels_small: "\u00CC" - readonly property string infinity: "\u00CD" - readonly property string invisible_medium: "\u00CE" - readonly property string invisible_small: "\u00CF" - readonly property string jumpToCode_medium: "\u00D0" - readonly property string jumpToCode_small: "\u00D1" - readonly property string keyframe: "\u00D2" - readonly property string languageList_medium: "\u00D3" - readonly property string layouts_small: "\u00D4" - readonly property string lights_small: "\u00D5" - readonly property string linear_medium: "\u00D6" - readonly property string linkTriangle: "\u00D7" - readonly property string linked: "\u00D8" - readonly property string listView: "\u00D9" - readonly property string listView_medium: "\u00DA" - readonly property string list_medium: "\u00DB" - readonly property string localOrient_medium: "\u00DC" - readonly property string lockOff: "\u00DD" - readonly property string lockOn: "\u00DE" - readonly property string loopPlayback_medium: "\u00DF" - readonly property string materialBrowser_medium: "\u00E0" - readonly property string materialPreviewEnvironment: "\u00E1" - readonly property string materialPreviewModel: "\u00E2" - readonly property string material_medium: "\u00E3" - readonly property string maxBar_small: "\u00E4" - readonly property string mergeCells: "\u00E5" - readonly property string merge_small: "\u00E6" - readonly property string minus: "\u00E7" - readonly property string mirror: "\u00E8" - readonly property string more_medium: "\u00E9" - readonly property string mouseArea_small: "\u00EA" - readonly property string moveDown_medium: "\u00EB" - readonly property string moveInwards_medium: "\u00EC" - readonly property string moveUp_medium: "\u00ED" - readonly property string moveUpwards_medium: "\u00EE" - readonly property string move_medium: "\u00EF" - readonly property string newMaterial: "\u00F0" - readonly property string nextFile_large: "\u00F1" - readonly property string normalBar_small: "\u00F2" - readonly property string openLink: "\u00F3" - readonly property string openMaterialBrowser: "\u00F4" - readonly property string orientation: "\u00F5" - readonly property string orthCam_medium: "\u00F6" - readonly property string orthCam_small: "\u00F7" - readonly property string paddingEdge: "\u00F8" - readonly property string paddingFrame: "\u00F9" - readonly property string particleAnimation_medium: "\u00FA" - readonly property string pasteStyle: "\u00FB" - readonly property string paste_small: "\u00FC" - readonly property string pause: "\u00FD" - readonly property string pause_medium: "\u00FE" - readonly property string perspectiveCam_medium: "\u00FF" - readonly property string perspectiveCam_small: "\u0100" - readonly property string pin: "\u0101" - readonly property string plane_medium: "\u0102" - readonly property string plane_small: "\u0103" - readonly property string play: "\u0104" - readonly property string playFill_medium: "\u0105" - readonly property string playOutline_medium: "\u0106" - readonly property string plus: "\u0107" - readonly property string pointLight_small: "\u0108" - readonly property string positioners_small: "\u0109" - readonly property string previewEnv_medium: "\u010A" - readonly property string previousFile_large: "\u010B" - readonly property string promote: "\u010C" - readonly property string properties_medium: "\u010D" - readonly property string readOnly: "\u010E" - readonly property string recent_medium: "\u010F" - readonly property string recordFill_medium: "\u0110" - readonly property string recordOutline_medium: "\u0111" - readonly property string redo: "\u0112" - readonly property string reload_medium: "\u0113" - readonly property string remove_medium: "\u0114" - readonly property string remove_small: "\u0115" - readonly property string rename_small: "\u0116" - readonly property string replace_small: "\u0117" - readonly property string resetView_small: "\u0118" - readonly property string restartParticles_medium: "\u0119" - readonly property string reverseOrder_medium: "\u011A" - readonly property string roatate_medium: "\u011B" - readonly property string rotationFill: "\u011C" - readonly property string rotationOutline: "\u011D" - readonly property string runProjFill_large: "\u011E" - readonly property string runProjOutline_large: "\u011F" - readonly property string s_anchors: "\u0120" - readonly property string s_annotations: "\u0121" - readonly property string s_arrange: "\u0122" - readonly property string s_boundingBox: "\u0123" - readonly property string s_component: "\u0124" - readonly property string s_connections: "\u0125" - readonly property string s_edit: "\u0126" - readonly property string s_enterComponent: "\u0127" - readonly property string s_eventList: "\u0128" - readonly property string s_group: "\u0129" - readonly property string s_layouts: "\u012A" - readonly property string s_merging: "\u012B" - readonly property string s_mouseArea: "\u012C" - readonly property string s_positioners: "\u012D" - readonly property string s_selection: "\u012E" - readonly property string s_snapping: "\u012F" - readonly property string s_timeline: "\u0130" - readonly property string s_visibility: "\u0131" - readonly property string saveAs_medium: "\u0132" - readonly property string saveLogs_medium: "\u0133" - readonly property string save_medium: "\u0134" - readonly property string scale_medium: "\u0135" - readonly property string search: "\u0136" - readonly property string search_small: "\u0137" - readonly property string sectionToggle: "\u0138" - readonly property string selectFill_medium: "\u0139" - readonly property string selectOutline_medium: "\u013A" - readonly property string selectParent_small: "\u013B" - readonly property string selection_small: "\u013C" - readonly property string settings_medium: "\u013D" - readonly property string signal_small: "\u013E" - readonly property string snapping_conf_medium: "\u013F" - readonly property string snapping_medium: "\u0140" - readonly property string snapping_small: "\u0141" - readonly property string sortascending_medium: "\u0142" - readonly property string sortdescending_medium: "\u0143" - readonly property string sphere_medium: "\u0144" - readonly property string sphere_small: "\u0145" - readonly property string splitColumns: "\u0146" - readonly property string splitRows: "\u0147" - readonly property string splitScreen_medium: "\u0148" - readonly property string spotLight_small: "\u0149" - readonly property string stackedContainer_small: "\u014A" - readonly property string startNode: "\u014B" - readonly property string step_medium: "\u014C" - readonly property string stop_medium: "\u014D" - readonly property string tableView_medium: "\u014E" - readonly property string testIcon: "\u014F" - readonly property string textAlignBottom: "\u0150" - readonly property string textAlignCenter: "\u0151" - readonly property string textAlignJustified: "\u0152" - readonly property string textAlignLeft: "\u0153" - readonly property string textAlignMiddle: "\u0154" - readonly property string textAlignRight: "\u0155" - readonly property string textAlignTop: "\u0156" - readonly property string textBulletList: "\u0157" - readonly property string textFullJustification: "\u0158" - readonly property string textNumberedList: "\u0159" - readonly property string textures_medium: "\u015A" - readonly property string tickIcon: "\u015B" - readonly property string tickMark_small: "\u015C" - readonly property string timeline_small: "\u015D" - readonly property string toEndFrame_medium: "\u015E" - readonly property string toNextFrame_medium: "\u015F" - readonly property string toPrevFrame_medium: "\u0160" - readonly property string toStartFrame_medium: "\u0161" - readonly property string topToolbar_annotations: "\u0162" - readonly property string topToolbar_closeFile: "\u0163" - readonly property string topToolbar_designMode: "\u0164" - readonly property string topToolbar_enterComponent: "\u0165" - readonly property string topToolbar_home: "\u0166" - readonly property string topToolbar_makeComponent: "\u0167" - readonly property string topToolbar_navFile: "\u0168" - readonly property string topToolbar_runProject: "\u0169" - readonly property string translationCreateFiles: "\u016A" - readonly property string translationCreateReport: "\u016B" - readonly property string translationExport: "\u016C" - readonly property string translationImport: "\u016D" - readonly property string translationSelectLanguages: "\u016E" - readonly property string translationTest: "\u016F" - readonly property string transparent: "\u0170" - readonly property string triState: "\u0171" - readonly property string triangleArcA: "\u0172" - readonly property string triangleArcB: "\u0173" - readonly property string triangleCornerA: "\u0174" - readonly property string triangleCornerB: "\u0175" - readonly property string unLinked: "\u0176" - readonly property string undo: "\u0177" - readonly property string unify_medium: "\u0178" - readonly property string unpin: "\u0179" - readonly property string upDownIcon: "\u017A" - readonly property string upDownSquare2: "\u017B" - readonly property string updateAvailable_medium: "\u017C" - readonly property string updateContent_medium: "\u017D" - readonly property string visibilityOff: "\u017E" - readonly property string visibilityOn: "\u017F" - readonly property string visible_medium: "\u0180" - readonly property string visible_small: "\u0181" - readonly property string warning_medium: "\u0182" - readonly property string wildcard: "\u0183" - readonly property string wizardsAutomotive: "\u0184" - readonly property string wizardsDesktop: "\u0185" - readonly property string wizardsGeneric: "\u0186" - readonly property string wizardsMcuEmpty: "\u0187" - readonly property string wizardsMcuGraph: "\u0188" - readonly property string wizardsMobile: "\u0189" - readonly property string wizardsUnknown: "\u018A" - readonly property string zoomAll: "\u018B" - readonly property string zoomIn: "\u018C" - readonly property string zoomIn_medium: "\u018D" - readonly property string zoomOut: "\u018E" - readonly property string zoomOut_medium: "\u018F" - readonly property string zoomSelection: "\u0190" + readonly property string error_medium: "\u00B2" + readonly property string events_small: "\u00B3" + readonly property string export_medium: "\u00B4" + readonly property string eyeDropper: "\u00B5" + readonly property string favorite: "\u00B6" + readonly property string fitAll_medium: "\u00B7" + readonly property string fitSelected_small: "\u00B8" + readonly property string fitSelection_medium: "\u00B9" + readonly property string fitToView_medium: "\u00BA" + readonly property string flowAction: "\u00BB" + readonly property string flowTransition: "\u00BC" + readonly property string fontStyleBold: "\u00BD" + readonly property string fontStyleItalic: "\u00BE" + readonly property string fontStyleStrikethrough: "\u00BF" + readonly property string fontStyleUnderline: "\u00C0" + readonly property string forward_medium: "\u00C1" + readonly property string globalOrient_medium: "\u00C2" + readonly property string gradient: "\u00C3" + readonly property string gridView: "\u00C4" + readonly property string grid_medium: "\u00C5" + readonly property string group_small: "\u00C6" + readonly property string help: "\u00C7" + readonly property string home_large: "\u00C8" + readonly property string idAliasOff: "\u00C9" + readonly property string idAliasOn: "\u00CA" + readonly property string import_medium: "\u00CB" + readonly property string imported: "\u00CC" + readonly property string importedModels_small: "\u00CD" + readonly property string infinity: "\u00CE" + readonly property string invisible_medium: "\u00CF" + readonly property string invisible_small: "\u00D0" + readonly property string jumpToCode_medium: "\u00D1" + readonly property string jumpToCode_small: "\u00D2" + readonly property string keyframe: "\u00D3" + readonly property string languageList_medium: "\u00D4" + readonly property string layouts_small: "\u00D5" + readonly property string lights_small: "\u00D6" + readonly property string linear_medium: "\u00D7" + readonly property string linkTriangle: "\u00D8" + readonly property string linked: "\u00D9" + readonly property string listView: "\u00DA" + readonly property string listView_medium: "\u00DB" + readonly property string list_medium: "\u00DC" + readonly property string localOrient_medium: "\u00DD" + readonly property string lockOff: "\u00DE" + readonly property string lockOn: "\u00DF" + readonly property string loopPlayback_medium: "\u00E0" + readonly property string materialBrowser_medium: "\u00E1" + readonly property string materialPreviewEnvironment: "\u00E2" + readonly property string materialPreviewModel: "\u00E3" + readonly property string material_medium: "\u00E4" + readonly property string maxBar_small: "\u00E5" + readonly property string mergeCells: "\u00E6" + readonly property string merge_small: "\u00E7" + readonly property string minus: "\u00E8" + readonly property string mirror: "\u00E9" + readonly property string more_medium: "\u00EA" + readonly property string mouseArea_small: "\u00EB" + readonly property string moveDown_medium: "\u00EC" + readonly property string moveInwards_medium: "\u00ED" + readonly property string moveUp_medium: "\u00EE" + readonly property string moveUpwards_medium: "\u00EF" + readonly property string move_medium: "\u00F0" + readonly property string newMaterial: "\u00F1" + readonly property string nextFile_large: "\u00F2" + readonly property string normalBar_small: "\u00F3" + readonly property string openLink: "\u00F4" + readonly property string openMaterialBrowser: "\u00F5" + readonly property string orientation: "\u00F6" + readonly property string orthCam_medium: "\u00F7" + readonly property string orthCam_small: "\u00F8" + readonly property string paddingEdge: "\u00F9" + readonly property string paddingFrame: "\u00FA" + readonly property string particleAnimation_medium: "\u00FB" + readonly property string pasteStyle: "\u00FC" + readonly property string paste_small: "\u00FD" + readonly property string pause: "\u00FE" + readonly property string pause_medium: "\u00FF" + readonly property string perspectiveCam_medium: "\u0100" + readonly property string perspectiveCam_small: "\u0101" + readonly property string pin: "\u0102" + readonly property string plane_medium: "\u0103" + readonly property string plane_small: "\u0104" + readonly property string play: "\u0105" + readonly property string playFill_medium: "\u0106" + readonly property string playOutline_medium: "\u0107" + readonly property string plus: "\u0108" + readonly property string pointLight_small: "\u0109" + readonly property string positioners_small: "\u010A" + readonly property string previewEnv_medium: "\u010B" + readonly property string previousFile_large: "\u010C" + readonly property string promote: "\u010D" + readonly property string properties_medium: "\u010E" + readonly property string readOnly: "\u010F" + readonly property string recent_medium: "\u0110" + readonly property string recordFill_medium: "\u0111" + readonly property string recordOutline_medium: "\u0112" + readonly property string redo: "\u0113" + readonly property string reload_medium: "\u0114" + readonly property string remove_medium: "\u0115" + readonly property string remove_small: "\u0116" + readonly property string rename_small: "\u0117" + readonly property string replace_small: "\u0118" + readonly property string resetView_small: "\u0119" + readonly property string restartParticles_medium: "\u011A" + readonly property string reverseOrder_medium: "\u011B" + readonly property string roatate_medium: "\u011C" + readonly property string rotationFill: "\u011D" + readonly property string rotationOutline: "\u011E" + readonly property string runProjFill_large: "\u011F" + readonly property string runProjOutline_large: "\u0120" + readonly property string s_anchors: "\u0121" + readonly property string s_annotations: "\u0122" + readonly property string s_arrange: "\u0123" + readonly property string s_boundingBox: "\u0124" + readonly property string s_component: "\u0125" + readonly property string s_connections: "\u0126" + readonly property string s_edit: "\u0127" + readonly property string s_enterComponent: "\u0128" + readonly property string s_eventList: "\u0129" + readonly property string s_group: "\u012A" + readonly property string s_layouts: "\u012B" + readonly property string s_merging: "\u012C" + readonly property string s_mouseArea: "\u012D" + readonly property string s_positioners: "\u012E" + readonly property string s_selection: "\u012F" + readonly property string s_snapping: "\u0130" + readonly property string s_timeline: "\u0131" + readonly property string s_visibility: "\u0132" + readonly property string saveAs_medium: "\u0133" + readonly property string saveLogs_medium: "\u0134" + readonly property string save_medium: "\u0135" + readonly property string scale_medium: "\u0136" + readonly property string search: "\u0137" + readonly property string search_small: "\u0138" + readonly property string sectionToggle: "\u0139" + readonly property string selectFill_medium: "\u013A" + readonly property string selectOutline_medium: "\u013B" + readonly property string selectParent_small: "\u013C" + readonly property string selection_small: "\u013D" + readonly property string settings_medium: "\u013E" + readonly property string signal_small: "\u013F" + readonly property string snapping_conf_medium: "\u0140" + readonly property string snapping_medium: "\u0141" + readonly property string snapping_small: "\u0142" + readonly property string sortascending_medium: "\u0143" + readonly property string sortdescending_medium: "\u0144" + readonly property string sphere_medium: "\u0145" + readonly property string sphere_small: "\u0146" + readonly property string splitColumns: "\u0147" + readonly property string splitRows: "\u0148" + readonly property string splitScreen_medium: "\u0149" + readonly property string spotLight_small: "\u014A" + readonly property string stackedContainer_small: "\u014B" + readonly property string startNode: "\u014C" + readonly property string step_medium: "\u014D" + readonly property string stop_medium: "\u014E" + readonly property string tableView_medium: "\u014F" + readonly property string testIcon: "\u0150" + readonly property string textAlignBottom: "\u0151" + readonly property string textAlignCenter: "\u0152" + readonly property string textAlignJustified: "\u0153" + readonly property string textAlignLeft: "\u0154" + readonly property string textAlignMiddle: "\u0155" + readonly property string textAlignRight: "\u0156" + readonly property string textAlignTop: "\u0157" + readonly property string textBulletList: "\u0158" + readonly property string textFullJustification: "\u0159" + readonly property string textNumberedList: "\u015A" + readonly property string textures_medium: "\u015B" + readonly property string tickIcon: "\u015C" + readonly property string tickMark_small: "\u015D" + readonly property string timeline_small: "\u015E" + readonly property string toEndFrame_medium: "\u015F" + readonly property string toNextFrame_medium: "\u0160" + readonly property string toPrevFrame_medium: "\u0161" + readonly property string toStartFrame_medium: "\u0162" + readonly property string topToolbar_annotations: "\u0163" + readonly property string topToolbar_closeFile: "\u0164" + readonly property string topToolbar_designMode: "\u0165" + readonly property string topToolbar_enterComponent: "\u0166" + readonly property string topToolbar_home: "\u0167" + readonly property string topToolbar_makeComponent: "\u0168" + readonly property string topToolbar_navFile: "\u0169" + readonly property string topToolbar_runProject: "\u016A" + readonly property string translationCreateFiles: "\u016B" + readonly property string translationCreateReport: "\u016C" + readonly property string translationExport: "\u016D" + readonly property string translationImport: "\u016E" + readonly property string translationSelectLanguages: "\u016F" + readonly property string translationTest: "\u0170" + readonly property string transparent: "\u0171" + readonly property string trash_medium: "\u0172" + readonly property string triState: "\u0173" + readonly property string triangleArcA: "\u0174" + readonly property string triangleArcB: "\u0175" + readonly property string triangleCornerA: "\u0176" + readonly property string triangleCornerB: "\u0177" + readonly property string unLinked: "\u0178" + readonly property string undo: "\u0179" + readonly property string unify_medium: "\u017A" + readonly property string unpin: "\u017B" + readonly property string upDownIcon: "\u017C" + readonly property string upDownSquare2: "\u017D" + readonly property string updateAvailable_medium: "\u017E" + readonly property string updateContent_medium: "\u017F" + readonly property string visibilityOff: "\u0180" + readonly property string visibilityOn: "\u0181" + readonly property string visible_medium: "\u0182" + readonly property string visible_small: "\u0183" + readonly property string warning2_medium: "\u0184" + readonly property string warning_medium: "\u0185" + readonly property string wildcard: "\u0186" + readonly property string wizardsAutomotive: "\u0187" + readonly property string wizardsDesktop: "\u0188" + readonly property string wizardsGeneric: "\u0189" + readonly property string wizardsMcuEmpty: "\u018A" + readonly property string wizardsMcuGraph: "\u018B" + readonly property string wizardsMobile: "\u018C" + readonly property string wizardsUnknown: "\u018D" + readonly property string zoomAll: "\u018E" + readonly property string zoomIn: "\u018F" + readonly property string zoomIn_medium: "\u0190" + readonly property string zoomOut: "\u0191" + readonly property string zoomOut_medium: "\u0192" + readonly property string zoomSelection: "\u0193" readonly property font iconFont: Qt.font({ "family": controlIcons.name, diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf index cdce3eeefd96cd16836d674b6d9d2dd9320946cc..485c4bbf4d7ab38c88c5316a8bd75ea9dcea04f2 100644 GIT binary patch delta 6791 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 delta 7721 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 R-D4Bd$^(fbCP)uV006!SXeR&w diff --git a/share/qtcreator/qmldesigner/statusbar/CloseButton.qml b/share/qtcreator/qmldesigner/statusbar/CloseButton.qml deleted file mode 100644 index a330b93ed35..00000000000 --- a/share/qtcreator/qmldesigner/statusbar/CloseButton.qml +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2024 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -import QtQuick -import QtQuick.Controls -import QtQuick.Templates as T - -T.Button { - id: root - width: 29 - height: 29 - - Item { - id: closeButton - anchors.fill: parent - state: "idle" - - Item { - id: closeIcon - width: 15 - height: 15 - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - rotation: 45 - - Rectangle { - id: rectangle - width: 1 - height: 15 - color: "#ffffff" - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - } - - Rectangle { - id: rectangle1 - width: 1 - height: 15 - color: "#ffffff" - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - rotation: 90 - } - } - } - - states: [ - State { - name: "idle" - when: !root.hovered && !root.pressed - - PropertyChanges { - target: rectangle - color: "#b2b2b2" - } - - PropertyChanges { - target: rectangle1 - color: "#b2b2b2" - } - }, - State { - name: "hoverPress" - when: (root.hovered || root.pressed) - } - ] -} diff --git a/share/qtcreator/qmldesigner/statusbar/IconButtonCheckable.qml b/share/qtcreator/qmldesigner/statusbar/IconButtonCheckable.qml deleted file mode 100644 index cbf7a71dcde..00000000000 --- a/share/qtcreator/qmldesigner/statusbar/IconButtonCheckable.qml +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (C) 2024 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -import QtQuick -import QtQuick.Controls -import QtQuick.Templates as T - -T.Button { - id: root - width: 29 - height: 29 - state: "idle" - property alias imageSource: image.source - property color idleBack: "#202020" - property color hoverBack: "#2d2d2d" - - Rectangle { - id: bkg - color: root.idleBack - radius: 5 - border.color: "#424242" - anchors.fill: parent - } - - Image { - id: image - width: 15 - height: 15 - anchors.verticalCenter: parent.verticalCenter - source: "qrc:/qtquickplugin/images/template_image.png" - anchors.horizontalCenter: parent.horizontalCenter - fillMode: Image.PreserveAspectFit - } - states: [ - State { - name: "idle" - when: !root.hovered && !root.pressed && !root.checked - && root.enabled - }, - State { - name: "hover" - when: root.hovered && !root.pressed && !root.checked && root.enabled - PropertyChanges { - target: bkg - color: root.hoverBack - } - }, - State { - name: "pressCheck" - when: (root.pressed || root.checked) && root.enabled - - PropertyChanges { - target: bkg - color: root.hoverBack - border.color: "#57b9fc" - } - }, - State { - name: "blocked" - when: !root.enabled - - PropertyChanges { - target: bkg - border.color: "#3a3a3a" - } - - PropertyChanges { - target: image - opacity: 0.404 - } - } - ] -} diff --git a/share/qtcreator/qmldesigner/statusbar/IssuesOutputPanel.qml b/share/qtcreator/qmldesigner/statusbar/IssuesOutputPanel.qml index 3088fac2e07..e0e97ca651e 100644 --- a/share/qtcreator/qmldesigner/statusbar/IssuesOutputPanel.qml +++ b/share/qtcreator/qmldesigner/statusbar/IssuesOutputPanel.qml @@ -1,54 +1,71 @@ // Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + import QtQuick import QtQuick.Controls import QtQuick.Layouts import StudioControls as StudioControls +import StudioTheme as StudioTheme import ToolBar StudioControls.PopupDialog { - id: root - width: 1024 + width: 800 property Item targetItem property alias warningCount: issuesPanel.warningCount property alias errorCount: issuesPanel.errorCount - function toggleShowIssuesPanel() { + property alias unreadOutput: outputPanel.unreadMessages + readonly property bool issuesVisible: issuesPanel.visible && root.visible + readonly property bool outputVisible: outputPanel.visible && root.visible + + function toggleShowIssuesPanel() { if (!root.visible) { - issuesButton.checked = true outputPanel.visible = false issuesPanel.visible = true root.show(root.targetItem) } else { - root.visible = false - root.close() + if (issuesPanel.visible) { + root.close() + } else { + outputPanel.visible = false + issuesPanel.visible = true + } } } function toggleShowOutputPanel() { if (!root.visible) { - outputButton.checked = true issuesPanel.visible = false outputPanel.visible = true - root.visible = true + root.show(root.targetItem) } else { - root.visible = false + if (outputPanel.visible) { + root.close() + } else { + issuesPanel.visible = false + outputPanel.visible = true + } } } + onClosing: { + issuesPanel.visible = false + outputPanel.visible = false + } + titleBar: RowLayout { id: toolBar anchors.verticalCenter: parent.verticalCenter anchors.left: parent.left anchors.right: parent.right - anchors.leftMargin: 15 + anchors.leftMargin: 0 anchors.rightMargin: 10 RowLayout { @@ -57,78 +74,49 @@ StudioControls.PopupDialog { TabBarButton { id: issuesButton - autoExclusive: true - checked: true + style: StudioTheme.Values.statusbarButtonStyle + text: qsTr("Issues") + checked: issuesPanel.visible + checkedInverted: true - Connections { - target: issuesButton - function onClicked() { - if (issuesButton.checked) { - issuesPanel.visible = true - outputPanel.visible = false - } else { return } + onClicked: { + if (!issuesPanel.visible) { + outputPanel.visible = false + issuesPanel.visible = true } } } TabBarButton { id: outputButton - labelText: "Output" - autoExclusive: true + style: StudioTheme.Values.statusbarButtonStyle + text: qsTr("Output") + checked: outputPanel.visible + checkedInverted: true - Connections { - target: outputButton - function onClicked() { - if (outputButton.checked) { - issuesPanel.visible = false - outputPanel.visible = true - } else { return } + onClicked: { + if (!outputPanel.visible) { + issuesPanel.visible = false + outputPanel.visible = true } } } } + RowLayout { id: rightAlignedButtons Layout.alignment: Qt.AlignRight - // IconButton { - // id: showOutputView - // imageSource: "images/outputIcon.png" - // idleBack: "#282828" - // hoverBack: "#3a3a3a" - // Connections { - // target: showOutputView - // function onClicked() { - // root.showOutputViewSignal() - // } - // } - // } - - IconButtonCheckable { - id: clearIssuesButton - visible: issuesButton.checked - hoverBack: "#3a3a3a" - idleBack: "#282828" - imageSource: "images/thinBin.png" - Connections { - target: clearIssuesButton - function onClicked() { + StudioControls.IconIndicator { + id: clearButton + icon: StudioTheme.Constants.trash_medium + pixelSize: StudioTheme.Values.myIconFontSize * 1.4 + toolTip: qsTr("Clear") + onClicked: { + if (issuesPanel.visible) issuesPanel.clearIssues() - } - } - } - - IconButtonCheckable { - id: clearOutputButton - visible: outputButton.checked - hoverBack: "#3a3a3a" - idleBack: "#282828" - imageSource: "images/thinBin.png" - Connections { - target: clearOutputButton - function onClicked() { + else outputPanel.clearOutput() - } } } } diff --git a/share/qtcreator/qmldesigner/statusbar/IssuesOutputToolBar.qml b/share/qtcreator/qmldesigner/statusbar/IssuesOutputToolBar.qml deleted file mode 100644 index 26019023258..00000000000 --- a/share/qtcreator/qmldesigner/statusbar/IssuesOutputToolBar.qml +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (C) 2024 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts - -Rectangle { - id: root - height: 41 - color: "#282828" - - signal popupClosed - signal issuesCheckedSignal - signal outputCheckedSignal - signal issuesClearedSignal - signal outputClearedSignal - - property alias showOutputViewEnabled: showOutputView.enabled - property alias clearOutputEnabled: clearOutputButton.enabled - property alias clearIssuesEnabled: clearIssuesButton.enabled - - property alias outputChecked: outputButton.checked - property alias issuesChecked: issuesButton.checked - - RowLayout { - id: tabBar - - anchors.verticalCenter: root.verticalCenter - anchors.left: root.left - anchors.leftMargin: 15 - - TabBarButton { - id: issuesButton - autoExclusive: true - checked: true - - Connections { - target: issuesButton - function onClicked() { - if (issuesButton.checked) { - root.issuesCheckedSignal() - } else - return - } - } - } - - TabBarButton { - id: outputButton - labelText: "Output" - autoExclusive: true - - Connections { - target: outputButton - function onClicked() { - if (outputButton.checked) { root.outputCheckedSignal() } - else { return } - } - } - } - } - - RowLayout { - anchors.right: root.right - anchors.rightMargin: 10 - - IconButton { - id: showOutputView - imageSource: "images/outputIcon.png" - idleBack: "#282828" - hoverBack: "#3a3a3a" - Connections { - target: showOutputView - function onClicked() { root.showOutputViewSignal() } - } - } - - IconButton { - id: clearIssuesButton - visible: issuesButton.checked - hoverBack: "#3a3a3a" - idleBack: "#282828" - imageSource: "images/thinBin.png" - Connections { - target: clearIssuesButton - function onClicked() { - root.issuesClearedSignal() - } - } - } - - IconButton { - id: clearOutputButton - visible: outputButton.checked - hoverBack: "#3a3a3a" - idleBack: "#282828" - imageSource: "images/thinBin.png" - Connections { - target: clearOutputButton - function onClicked() { root.outputClearedSignal() } - } - } - } -} diff --git a/share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml b/share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml index e59aa345b90..432a6f9c2cf 100644 --- a/share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml +++ b/share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml @@ -1,15 +1,16 @@ // Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + import QtQuick import QtQuick.Controls import QtQuick.Layouts -import ToolBar -import OutputPane + import StudioControls as StudioControls import StudioTheme as StudioTheme -ScrollView { +import OutputPane +ScrollView { id: issuesPanel signal showCodeViewSignal @@ -27,50 +28,54 @@ ScrollView { y: 0 height: issuesPanel.availableHeight orientation: Qt.Vertical - - show: (issuesPanel.hovered || issuesPanel.focus) - && verticalScrollBar.isNeeded + show: (issuesPanel.hovered || issuesPanel.focus) && verticalScrollBar.isNeeded } ColumnLayout { Repeater { id: listView - model: MessageModel { - id: messageModel - } + model: MessageModel { id: messageModel } delegate: RowLayout { spacing: 10 - Image { - id: typeImage - source: { - if (type == "Warning") { "images/warningsActive.png" } - else { "images/errorActive.png" } - } - fillMode: Image.PreserveAspectFit + + required property int index + required property string message + required property string location + required property string type + + Text { + font.family: StudioTheme.Constants.iconFont.family + font.pixelSize: StudioTheme.Values.baseIconFontSize + color: (type == "Warning") ? StudioTheme.Values.themeAmberLight + : StudioTheme.Values.themeRedLight + text: (type == "Warning") ? StudioTheme.Constants.warning2_medium + : StudioTheme.Constants.error_medium } - MyLinkTextButton { - id: linkTextWarning - linkText: location + Text { + text: location + color: "#57b9fc" + font.pixelSize: 12 + verticalAlignment: Text.AlignVCenter Layout.preferredHeight: 18 + font.underline: mouseArea.containsMouse ? true : false - Connections { - target: linkTextWarning - function onClicked() { messageModel.jumpToCode(index) } + MouseArea { + id: mouseArea + anchors.fill: parent + hoverEnabled: true + cursorShape: mouseArea.containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor } } Text { - id: historyTime6 - color: { - if (type == "Warning") { "#ffbb0c" } - else { "#ff4848" } - } - text: qsTr(message) - font.pixelSize: 12 - verticalAlignment: Text.AlignTop + color: (type == "Warning") ? StudioTheme.Values.themeAmberLight + : StudioTheme.Values.themeRedLight + text: message + font.pixelSize: StudioTheme.Values.baseFontSize + verticalAlignment: Text.AlignVCenter Layout.preferredHeight: 18 } } diff --git a/share/qtcreator/qmldesigner/statusbar/Main.qml b/share/qtcreator/qmldesigner/statusbar/Main.qml index f849cc19327..75b64a93bc0 100644 --- a/share/qtcreator/qmldesigner/statusbar/Main.qml +++ b/share/qtcreator/qmldesigner/statusbar/Main.qml @@ -1,15 +1,15 @@ // Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + import QtQuick import QtQuick.Controls -import QtQuick.Layouts -import StudioControls 1.0 as StudioControls -import StudioTheme 1.0 as StudioTheme +import StudioControls as StudioControls +import StudioTheme as StudioTheme import "../toolbar" -import HelperWidgets 2.0 +import HelperWidgets -import ToolBar 1.0 +import ToolBar Item { id: toolbarContainer @@ -26,8 +26,10 @@ Item { anchors.fill: parent Row { - anchors.fill: parent + anchors.top: parent.top + anchors.bottom: parent.bottom anchors.topMargin: 3 + anchors.left: parent.left anchors.leftMargin: 4 spacing: 29 @@ -51,6 +53,7 @@ Item { horizontalAlignment: Text.AlignRight verticalAlignment: Text.AlignVCenter elide: Text.ElideRight + ToolTipArea { anchors.fill: parent tooltip: qsTr("Choose a predefined kit for the runtime configuration of the project.") @@ -78,6 +81,7 @@ Item { horizontalAlignment: Text.AlignRight verticalAlignment: Text.AlignVCenter elide: Text.ElideRight + ToolTipArea { anchors.fill: parent tooltip: qsTr("Choose a style for the Qt Quick Controls of the project.") @@ -97,55 +101,61 @@ Item { } } - RowLayout { + Row { id: buttonRow - anchors.verticalCenter: parent.verticalCenter + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.topMargin: 3 anchors.right: parent.right - anchors.rightMargin: 10 + anchors.rightMargin: 4 spacing: 10 NotificationButton { id: issuesNotification + style: StudioTheme.Values.statusbarButtonStyle + warningCount: popupPanel.warningCount errorCount: popupPanel.errorCount - Layout.alignment: Qt.AlignVCenter + checkable: true + checkedInverted: true + checked: popupPanel.issuesVisible + width: 136 + enabled: backend.projectOpened + tooltip: qsTr("Show issues.") - - Connections { - target: issuesNotification - function onClicked() { - popupPanel.toggleShowIssuesPanel() - } - } + onClicked: popupPanel.toggleShowIssuesPanel() } - IconButtonCheckable { + ToolbarButton { id: outputButton - imageSource: "images/outputIcon.png" + style: StudioTheme.Values.statusbarButtonStyle + buttonIcon: StudioTheme.Constants.import_medium + iconRotation: -90 checkable: true + checkedInverted: true + checked: popupPanel.outputVisible + enabled: backend.projectOpened + tooltip: qsTr("Show application output.") + + onClicked: popupPanel.toggleShowOutputPanel() Connections { - target: outputButton - function onClicked() { - popupPanel.toggleShowOutputPanel() + target: popupPanel + function onUnreadOutputChanged() { + if (popupPanel.unreadOutput) + outputButton.highlight() } } } } } - Item { - id: popupTarget - y: -282 //magic number - anchors.right: parent.right - } - IssuesOutputPanel { - targetItem: popupTarget id: popupPanel + targetItem: buttonRow + edge: Qt.TopEdge keepOpen: true } - } diff --git a/share/qtcreator/qmldesigner/statusbar/MyLinkTextButton.ui.qml b/share/qtcreator/qmldesigner/statusbar/MyLinkTextButton.ui.qml deleted file mode 100644 index a9763aa5468..00000000000 --- a/share/qtcreator/qmldesigner/statusbar/MyLinkTextButton.ui.qml +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2024 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -import QtQuick -import QtQuick.Controls -import QtQuick.Templates as T - -T.Button { - id: root - width: childrenRect.width - state: "idle" - property alias linkText: linkTextLabel.text - - Text { - id: linkTextLabel - color: "#57b9fc" - text: qsTr("Screen01.ui.qml - Line 8") - font.pixelSize: 12 - verticalAlignment: Text.AlignVCenter - } - - Rectangle { - id: rectangle - width: linkTextLabel.width - height: 1 - color: "#57b9fc" - anchors.left: parent.left - anchors.bottom: parent.bottom - anchors.bottomMargin: 2 - } - states: [ - State { - name: "idle" - when: !root.hovered && !root.pressed - - PropertyChanges { - target: rectangle - visible: false - } - }, - State { - name: "hoverClick" - when: (root.hovered || root.pressed) - - PropertyChanges { - target: rectangle - visible: true - } - } - ] -} diff --git a/share/qtcreator/qmldesigner/statusbar/NotificationButton.qml b/share/qtcreator/qmldesigner/statusbar/NotificationButton.qml new file mode 100644 index 00000000000..3eaf29588dd --- /dev/null +++ b/share/qtcreator/qmldesigner/statusbar/NotificationButton.qml @@ -0,0 +1,244 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Templates as T + +import StudioTheme as StudioTheme +import HelperWidgets + +T.AbstractButton { + id: control + + property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle + + property bool globalHover: false + property bool hover: control.hovered + property bool press: control.pressed + + property alias backgroundVisible: buttonBackground.visible + property alias backgroundRadius: buttonBackground.radius + + // Inverts the checked style + property bool checkedInverted: false + + property int warningCount: 0 + property int errorCount: 0 + + property bool hasWarnings: control.warningCount > 0 + property bool hasErrors: control.errorCount > 0 + + property alias tooltip: toolTipArea.tooltip + + ToolTipArea { + id: toolTipArea + anchors.fill: parent + // Without setting the acceptedButtons property the clicked event won't + // reach the AbstractButton, it will be consumed by the ToolTipArea + acceptedButtons: Qt.NoButton + } + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + width: control.style.squareControlSize.width + height: control.style.squareControlSize.height + z: control.checked ? 10 : 3 + activeFocusOnTab: false + + background: Rectangle { + id: buttonBackground + color: control.style.background.idle + border.color: control.style.border.idle + border.width: control.style.borderWidth + radius: control.style.radius + } + + component CustomLabel : T.Label { + id: customLabel + color: control.style.icon.idle + font.pixelSize: control.style.baseIconFontSize + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + + property bool active: false + property color activeColor: "red" + + states: [ + State { + name: "default" + when: control.enabled && !control.press && !control.checked && !control.hover + PropertyChanges { + target: customLabel + color: customLabel.active ? customLabel.activeColor : control.style.icon.idle + } + }, + State { + name: "hover" + when: control.enabled && !control.press && !control.checked && control.hover + PropertyChanges { + target: customLabel + color: customLabel.active ? customLabel.activeColor : control.style.icon.hover + } + }, + State { + name: "press" + when: control.enabled && control.press + PropertyChanges { + target: customLabel + color: control.style.icon.interaction + } + }, + State { + name: "check" + when: control.enabled && !control.press && control.checked + PropertyChanges { + target: customLabel + color: control.checkedInverted ? control.style.text.selectedText // TODO rather something in icon + : control.style.icon.selected + } + }, + State { + name: "disable" + when: !control.enabled + PropertyChanges { + target: customLabel + color: control.style.icon.disabled + } + } + ] + } + + indicator: Item { + x: 0 + y: 0 + width: control.width + height: control.height + + Row { + anchors.verticalCenter: parent.verticalCenter + anchors.horizontalCenter: parent.horizontalCenter + spacing: 8 + + CustomLabel { + height: control.height + font.pixelSize: StudioTheme.Values.baseFontSize + text: control.warningCount + active: control.hasWarnings + activeColor: StudioTheme.Values.themeAmberLight + } + + CustomLabel { + height: control.height + text: StudioTheme.Constants.warning2_medium + font.family: StudioTheme.Constants.iconFont.family + active: control.hasWarnings + activeColor: StudioTheme.Values.themeAmberLight + } + + CustomLabel { + height: control.height + text: StudioTheme.Constants.error_medium + font.family: StudioTheme.Constants.iconFont.family + active: control.hasErrors + activeColor: StudioTheme.Values.themeRedLight + } + + CustomLabel { + height: control.height + font.pixelSize: StudioTheme.Values.baseFontSize + text: control.errorCount + active: control.hasErrors + activeColor: StudioTheme.Values.themeRedLight + } + } + } + + states: [ + State { + name: "default" + when: control.enabled && !control.globalHover && !control.hover + && !control.press && !control.checked + PropertyChanges { + target: buttonBackground + color: control.style.background.idle + border.color: control.style.border.idle + } + PropertyChanges { + target: control + z: 3 + } + }, + State { + name: "globalHover" + when: control.globalHover && !control.hover && !control.press && control.enabled + PropertyChanges { + target: buttonBackground + color: control.style.background.idle + border.color: control.style.border.idle + } + }, + State { + name: "hover" + when: !control.checked && control.hover && !control.press && control.enabled + PropertyChanges { + target: buttonBackground + color: control.style.background.hover + border.color: control.style.border.hover + } + PropertyChanges { + target: control + z: 100 + } + }, + State { + name: "hoverCheck" + when: control.checked && control.hover && !control.press && control.enabled + PropertyChanges { + target: buttonBackground + color: control.checkedInverted ? control.style.interactionHover + : control.style.background.hover + border.color: control.checkedInverted ? control.style.interactionHover + : control.style.border.hover + } + PropertyChanges { + target: control + z: 100 + } + }, + State { + name: "press" + when: control.hover && control.press && control.enabled + PropertyChanges { + target: buttonBackground + color: control.style.interaction + border.color: control.style.interaction + } + PropertyChanges { + target: control + z: 100 + } + }, + State { + name: "check" + when: control.enabled && !control.press && control.checked + PropertyChanges { + target: buttonBackground + color: control.checkedInverted ? control.style.interaction + : control.style.background.idle + border.color: control.checkedInverted ? control.style.interaction + : control.style.border.idle + } + }, + State { + name: "disable" + when: !control.enabled + PropertyChanges { + target: buttonBackground + color: control.style.background.disabled + border.color: control.style.border.disabled + } + } + ] +} diff --git a/share/qtcreator/qmldesigner/statusbar/NotificationButton.ui.qml b/share/qtcreator/qmldesigner/statusbar/NotificationButton.ui.qml deleted file mode 100644 index 2f8adef1d91..00000000000 --- a/share/qtcreator/qmldesigner/statusbar/NotificationButton.ui.qml +++ /dev/null @@ -1,351 +0,0 @@ -// Copyright (C) 2024 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -import QtQuick -import QtQuick.Controls -import QtQuick.Templates as T - -T.Button { - id: root - - property int warningCount: 0 - property int errorCount: 0 - - property bool hasWarnings: warningCount > 0 - property bool hasErrors: errorCount > 0 - - width: 136 - height: 29 - checkable: true - state: "idleEmpty" - - Rectangle { - id: bck - color: "#202020" - radius: 5 - border.color: "#444444" - anchors.fill: parent - - Text { - id: warningNumLabel - color: "#ffffff" - text: root.warningCount - anchors.verticalCenter: parent.verticalCenter - anchors.right: warningsIcon.left - anchors.rightMargin: 8 - font.pixelSize: 12 - horizontalAlignment: Text.AlignRight - } - - Text { - id: errorNumLabel - color: "#ffffff" - text: root.errorCount - anchors.verticalCenter: parent.verticalCenter - anchors.left: errorIcon.right - anchors.leftMargin: 8 - font.pixelSize: 12 - horizontalAlignment: Text.AlignLeft - } - - Image { - id: errorIcon - anchors.verticalCenter: parent.verticalCenter - anchors.right: parent.right - anchors.rightMargin: 47 - source: "images/errorPassive.png" - fillMode: Image.PreserveAspectFit - } - - Image { - id: warningsIcon - anchors.verticalCenter: parent.verticalCenter - anchors.left: parent.left - anchors.leftMargin: 47 - source: "images/warningsPassive.png" - fillMode: Image.PreserveAspectFit - } - } - states: [ - State { - name: "idleEmpty" - when: !root.hovered && !root.checked && !root.pressed - && !root.hasErrors && !root.hasWarnings - - PropertyChanges { - target: warningNumLabel - text: "0" - } - - PropertyChanges { - target: errorNumLabel - text: "0" - } - }, - State { - name: "idleHover" - when: root.hovered && !(root.checked || root.pressed) - && !root.hasErrors && !root.hasWarnings - PropertyChanges { - target: warningNumLabel - text: "0" - } - - PropertyChanges { - target: errorNumLabel - text: "0" - } - - PropertyChanges { - target: bck - color: "#2d2d2d" - } - }, - - State { - name: "pressCheck" - when: (root.checked || root.pressed) && !root.hasErrors && !root.hasWarnings - PropertyChanges { - target: warningNumLabel - text: "0" - } - - PropertyChanges { - target: errorNumLabel - text: "0" - } - - PropertyChanges { - target: bck - color: "#2d2d2d" - border.color: "#2eb0f9" - } - }, - - State { - name: "idleWarningsOnly" - when: !root.hovered && !root.checked && !root.pressed - && !root.hasErrors && root.hasWarnings - - PropertyChanges { - target: warningsIcon - source: "images/warningsActive.png" - } - - PropertyChanges { - target: warningNumLabel - color: "#ffbb0c" - } - - PropertyChanges { - target: errorNumLabel - text: "0" - } - }, - State { - name: "hoverWarningsOnly" - when: root.hovered && !root.checked && !root.pressed - && !root.hasErrors && root.hasWarnings - PropertyChanges { - target: warningsIcon - source: "images/warningsActive.png" - } - - PropertyChanges { - target: warningNumLabel - color: "#ffbb0c" - } - - PropertyChanges { - target: errorNumLabel - text: "0" - } - - PropertyChanges { - target: bck - color: "#2d2d2d" - } - }, - - State { - name: "pressCheckWarningsOnly" - when: (root.checked || root.pressed) && !root.hasErrors - && root.hasWarnings - PropertyChanges { - target: warningsIcon - source: "images/warningsActive.png" - } - - PropertyChanges { - target: warningNumLabel - color: "#ffbb0c" - } - - PropertyChanges { - target: errorNumLabel - text: "0" - } - - PropertyChanges { - target: bck - color: "#2d2d2d" - border.color: "#57b9fc" - } - }, - - State { - name: "idleErrorsOnly" - when: !root.hovered && !root.checked && !root.pressed - && root.hasErrors && !root.hasWarnings - - PropertyChanges { - target: warningNumLabel - text: "0" - } - - PropertyChanges { - target: errorIcon - source: "images/errorActive.png" - } - - PropertyChanges { - target: errorNumLabel - color: "#ff4848" - } - }, - State { - name: "hoverErrorsOnly" - when: root.hovered && !root.checked && !root.pressed - && root.hasErrors && !root.hasWarnings - PropertyChanges { - target: warningNumLabel - text: "0" - } - - PropertyChanges { - target: errorIcon - source: "images/errorActive.png" - } - - PropertyChanges { - target: errorNumLabel - color: "#ff4848" - } - - PropertyChanges { - target: bck - color: "#2d2d2d" - } - }, - - State { - name: "pressCheckErrorsOnly" - when: (root.checked || root.pressed) && root.hasErrors - && !root.hasWarnings - PropertyChanges { - target: warningNumLabel - text: "0" - } - - PropertyChanges { - target: errorIcon - source: "images/errorActive.png" - } - - PropertyChanges { - target: errorNumLabel - color: "#ff4848" - } - - PropertyChanges { - target: bck - color: "#2d2d2d" - border.color: "#57b9fc" - } - }, - - State { - name: "idlesErrorsAndWarnings" - when: !root.hovered && !root.checked && !root.pressed - && root.hasErrors && root.hasWarnings - - PropertyChanges { - target: warningNumLabel - color: "#ffbb0c" - } - - PropertyChanges { - target: warningsIcon - source: "images/warningsActive.png" - } - - PropertyChanges { - target: errorNumLabel - color: "#ff4848" - } - - PropertyChanges { - target: errorIcon - source: "images/errorActive.png" - } - }, - State { - name: "hoverErrorsAndWarnings" - when: root.hovered && !root.checked && !root.pressed - && root.hasErrors && root.hasWarnings - PropertyChanges { - target: warningNumLabel - color: "#ffbb0c" - } - - PropertyChanges { - target: warningsIcon - source: "images/warningsActive.png" - } - - PropertyChanges { - target: errorNumLabel - color: "#ff4848" - } - - PropertyChanges { - target: errorIcon - source: "images/errorActive.png" - } - - PropertyChanges { - target: bck - color: "#2d2d2d" - } - }, - State { - name: "pressCheckWarningsErrors" - when: (root.checked || root.pressed) && root.hasErrors - && root.hasWarnings - PropertyChanges { - target: warningNumLabel - color: "#ffbb0c" - } - - PropertyChanges { - target: warningsIcon - source: "images/warningsActive.png" - } - - PropertyChanges { - target: errorNumLabel - color: "#ff4848" - } - - PropertyChanges { - target: errorIcon - source: "images/errorActive.png" - } - - PropertyChanges { - target: bck - color: "#2d2d2d" - border.color: "#2eb0f9" - } - } - ] -} diff --git a/share/qtcreator/qmldesigner/statusbar/OutputPanel.qml b/share/qtcreator/qmldesigner/statusbar/OutputPanel.qml index 781fc159ae9..56b1083ee80 100644 --- a/share/qtcreator/qmldesigner/statusbar/OutputPanel.qml +++ b/share/qtcreator/qmldesigner/statusbar/OutputPanel.qml @@ -1,21 +1,34 @@ // Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + import QtQuick import QtQuick.Controls import QtQuick.Layouts -import OutputPane + import StudioControls as StudioControls import StudioTheme as StudioTheme +import OutputPane + ScrollView { id: root + property int unreadMessages: 0 + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff function clearOutput() { parentListModel.resetModel() + root.markMessagesRead() } + onVisibleChanged: { + if (root.visible === true) + root.markMessagesRead() + } + + function markMessagesRead() { root.unreadMessages = 0 } + clip: true ScrollBar.vertical: StudioControls.TransientScrollBar { @@ -26,21 +39,25 @@ ScrollView { y: 0 height: root.availableHeight orientation: Qt.Vertical - - show: (root.hovered || root.focus) - && verticalScrollBar.isNeeded + show: (root.hovered || root.focus) && verticalScrollBar.isNeeded } - ColumnLayout { + Column { id: clayout Repeater { id: parentList + model: AppOutputParentModel { id: parentListModel historyColor: "grey" messageColor: "#007b7b" errorColor: "#ff6666" + + onMessageAdded: { + if (!root.visible) + root.unreadMessages++ + } } delegate: ColumnLayout { @@ -53,8 +70,8 @@ ScrollView { Text { id: timeStampText - text: run - color: blockColor + text: parentDelegate.run + color: parentDelegate.blockColor } Repeater { @@ -66,16 +83,19 @@ ScrollView { row: parentDelegate.index } + onItemAdded: verticalScrollBar.position = 1.0 // Scroll to bottom + delegate: Column { id: childDelegate required property string message required property color messageColor + Text { wrapMode: Text.WordWrap - text: message - color: messageColor - width: root.width - verticalScrollBar.width + text: childDelegate.message + color: childDelegate.messageColor + width: root.width } } } diff --git a/share/qtcreator/qmldesigner/statusbar/TabBarButton.qml b/share/qtcreator/qmldesigner/statusbar/TabBarButton.qml new file mode 100644 index 00000000000..883babc78e9 --- /dev/null +++ b/share/qtcreator/qmldesigner/statusbar/TabBarButton.qml @@ -0,0 +1,167 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +import QtQuick +import QtQuick.Templates as T +import StudioTheme as StudioTheme + +T.AbstractButton { + id: control + + property StudioTheme.ControlStyle style: StudioTheme.Values.controlStyle + + property bool hover: control.hovered + property bool press: control.pressed + + // Inverts the checked style + property bool checkedInverted: false + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + implicitContentWidth + leftPadding + rightPadding) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + implicitContentHeight + topPadding + bottomPadding) + width: 100 + height: control.style.squareControlSize.height + activeFocusOnTab: false + + background: Rectangle { + id: buttonBackground + color: control.style.background.idle + border.color: control.style.border.idle + border.width: control.style.borderWidth + radius: control.style.radius + } + + indicator: T.Label { + id: buttonIcon + text: control.text + color: control.style.icon.idle + font.pixelSize: control.style.baseFontSize + width: control.width + height: control.height + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + states: [ + State { + name: "default" + when: control.enabled && !control.press && !control.checked && !control.hover + PropertyChanges { + target: buttonIcon + color: control.style.icon.idle + } + }, + State { + name: "hover" + when: control.enabled && !control.press && !control.checked && control.hover + PropertyChanges { + target: buttonIcon + color: control.style.icon.hover + } + }, + State { + name: "press" + when: control.enabled && control.press + PropertyChanges { + target: buttonIcon + color: control.style.icon.interaction + } + }, + State { + name: "check" + when: control.enabled && !control.press && control.checked + PropertyChanges { + target: buttonIcon + color: control.checkedInverted ? control.style.text.selectedText // TODO rather something in icon + : control.style.icon.selected + } + }, + State { + name: "disable" + when: !control.enabled + PropertyChanges { + target: buttonIcon + color: control.style.icon.disabled + } + } + ] + } + + states: [ + State { + name: "default" + when: control.enabled && !control.hover + && !control.press && !control.checked + PropertyChanges { + target: buttonBackground + color: control.style.background.idle + border.color: control.style.border.idle + } + PropertyChanges { + target: control + z: 3 + } + }, + State { + name: "hover" + when: !control.checked && control.hover && !control.press && control.enabled + PropertyChanges { + target: buttonBackground + color: control.style.background.hover + border.color: control.style.border.hover + } + PropertyChanges { + target: control + z: 100 + } + }, + State { + name: "hoverCheck" + when: control.checked && control.hover && !control.press && control.enabled + PropertyChanges { + target: buttonBackground + color: control.checkedInverted ? control.style.interactionHover + : control.style.background.hover + border.color: control.checkedInverted ? control.style.interactionHover + : control.style.border.hover + } + PropertyChanges { + target: control + z: 100 + } + }, + State { + name: "press" + when: control.hover && control.press && control.enabled + PropertyChanges { + target: buttonBackground + color: control.style.interaction + border.color: control.style.interaction + } + PropertyChanges { + target: control + z: 100 + } + }, + State { + name: "check" + when: control.enabled && !control.press && control.checked + PropertyChanges { + target: buttonBackground + color: control.checkedInverted ? control.style.interaction + : control.style.background.idle + border.color: control.checkedInverted ? control.style.interaction + : control.style.border.idle + } + }, + State { + name: "disable" + when: !control.enabled + PropertyChanges { + target: buttonBackground + color: control.style.background.disabled + border.color: control.style.border.disabled + } + } + ] +} diff --git a/share/qtcreator/qmldesigner/statusbar/TabBarButton.ui.qml b/share/qtcreator/qmldesigner/statusbar/TabBarButton.ui.qml deleted file mode 100644 index 9bcff61bb19..00000000000 --- a/share/qtcreator/qmldesigner/statusbar/TabBarButton.ui.qml +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2024 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 -import QtQuick -import QtQuick.Controls -import QtQuick.Templates as T - -T.Button { - id: root - width: 100 - height: 29 - property alias labelText: label.text - state: "idle" - checkable: true - - Rectangle { - id: background - color: "#282828" - radius: 5 - border.color: "#424242" - anchors.fill: parent - } - - Text { - id: label - color: "#ffffff" - text: qsTr("Issues") - anchors.verticalCenter: parent.verticalCenter - font.pixelSize: 12 - anchors.horizontalCenter: parent.horizontalCenter - } - states: [ - State { - name: "idle" - when: !root.hovered && !root.pressed & !root.checked - }, - State { - name: "hover" - when: root.hovered && !root.pressed & !root.checked - - PropertyChanges { - target: background - color: "#2f2f2f" - } - }, - State { - name: "pressCheck" - when: (root.pressed || root.checked) - - PropertyChanges { - target: background - color: "#57b9fc" - border.color: "#57b9fc" - } - } - ] -} diff --git a/share/qtcreator/qmldesigner/statusbar/images/CodeView.png b/share/qtcreator/qmldesigner/statusbar/images/CodeView.png deleted file mode 100644 index 56107927f4f1ecafd1e9453f10c1eb004b882cc9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24757 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 TESk%}z`)??>gTe~DWM4f#LO)7 diff --git a/share/qtcreator/qmldesigner/statusbar/images/OutputView.png b/share/qtcreator/qmldesigner/statusbar/images/OutputView.png deleted file mode 100644 index 6b8cadc39aab6e58d6e8f94c1aaae9bf0896a1de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9351 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 Xq)!P+Z5Lx;U|{fc^>bP0l+XkK^>4OD diff --git a/share/qtcreator/qmldesigner/statusbar/images/delete_trash.png b/share/qtcreator/qmldesigner/statusbar/images/delete_trash.png deleted file mode 100644 index 3dd7cd401af953d70f1e25c453b29d6c53699806..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 299 zcmeAS@N?(olHy`uVBq!ia0y~yVBlt8VBqIqV_;w~vNbheU|`@Z@Q5sCVBi)8VMc~o zb0ioT7#NF#+?^QKos)UVz`($g?&#~tz_78O`%fY(0|UbWPZ!6K3dXGy6L}9A2(;c# zWqQ`|FhL`MZ$*nG1E&HbD>M5725wizsRry%ZFjUSHc|ZZKsA2X*L$)0<<~ThN>s~e zUufWbvv#YaG+TkNmzQDq;r9nG)=b|XwD;&nw%CIr2m0Pd7{)C*ADosG(&+li((6)t zh5pBdhyEWvl3uWpb@2?h4S|<4Uat`lPJi{=cj`~a|HjX4s~fFmKR*>8wD>jmQHl2| z?{U5Bi_~<|xvhdp7V1NBiCqE933A zpEh<$)HF5hzse92Q)&_8!F_@6y^q}|Tc=gs4%@Wj)~mUs=JeK0kRXk^Q zr*UI^O7KyYr@{p@K6K~GzAxMyY8sfM*tyq8f?;jV$=`1(Q`i^W;(cj2Womq~u=20M z1ZkI_*LAp4_p>uCQ?RW(+gW{hwm0{MK5Z3waiPD5-wSemI(^~RnoY-(xoX??*PeQ{ z{j9KVf!66Fy~e}a=c+C5ciDP7?~BQ_Y4KNu&u^Nb7{^&t!N9=4;OXk;vd$@?2>`7X Bn-2g0 diff --git a/share/qtcreator/qmldesigner/statusbar/images/errorPassive.png b/share/qtcreator/qmldesigner/statusbar/images/errorPassive.png deleted file mode 100644 index 0b5749c630e4b275066bdd9994c0b11d9e7db181..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 342 zcmeAS@N?(olHy`uVBq!ia0y~yVBiN~4mJh`2J356y%-o6I14-?iy0WWg+Z8+Vb&Z8 z1_lPk;vjb?hIQv;UNSH+u%tWsIx;Y9?C1WI$jZRL@Y>VGF{FZVYA`qNAp?QELM$Op zfd^y^R2DQ?GH_bl2yh5!XnDvWV<3{lcgni#?5$<0k5%>m-rc?Jebge3Yqz*^4&Li~ zks5P!<0)ZD6Y~kTjeoGPN2Wb=`xU)3_wd2j<0~ri+ z4L7=N)_Z2<=d@fo{mXNsw`nfUrKU+OJ&G&-3;OAANh%Ia3JLk@R)1ADXO_MDR1U!n t%a5&2Vc2kEhO&K;wn56CoLP@2?q=NJ;LiBs6&uKr44$rjF6*2UngEy=P;~$R diff --git a/share/qtcreator/qmldesigner/statusbar/images/thinBin.png b/share/qtcreator/qmldesigner/statusbar/images/thinBin.png deleted file mode 100644 index 5df002cf896e8856048ec2fd81a7328bd5e45fb7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 216 zcmeAS@N?(olHy`uVBq!ia0y~yVBiF?IoKE&7^)duKonU}oXkrG1_qXNM_)$E)e-c?47#MOrT^vIy7}o|gavo6Nd3}uUV{_#x zyBX?Lr}i8Wwpp0%-lBBsn1O)QswJ7?Y2RE*ILfbdY4}8$U-o(6e_}^)#E$+o?^zzQ zvH9_a7)Z%^Z<&?*Vb{&88Bs5ppVe-f`N+Zk<>}L$o4OjJzb;^V$fokCk@rLLqmv8_ O3=E#GelF{r5}E*C4M}YP diff --git a/share/qtcreator/qmldesigner/statusbar/images/warningsActive.png b/share/qtcreator/qmldesigner/statusbar/images/warningsActive.png deleted file mode 100644 index aed92e6933095bb8bc5ae61e6fe52359e225cf27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 403 zcmeAS@N?(olHy`uVBq!ia0y~yVBlw9VBq6mV_;zT(B<}?fq{Xuz$3Dlfq`2Xgc%uT z&5>YWU|=i`a(7}_cTVOd0|Ns~x}&cn1H;CC?mvmF3=E7Ko-U3d6^v7Z-ufOk5ZLQ| zcz@U_4!NZqD~0|iFk3kuV#!o*@N+PGQNLnJ-v!=Tf=Y@iEZh3i&D}C*)!DvWbmQdR z>bmnTwiAp3KN;!-Hl2FOvFKiGa*FKp=A(?9P|m1)eWtSv|Diss#% zA#~o<-;R6#zux(tDhuW3&dvFjqtsPm!+N_p`N{8HhnBPc^V$6-&^xaw)bC7deuCE@ zg?5X&R(8|Ox!;YW=T0g$V*k9(X5ZTETQjF`J=@*nnK4K3wyU!6;U!GbU+oi~AC%fE zFMIA=+vmKOJTj~Ond;u;n_S#t6HqJ8@?TWZO8xiI*&>TLf0RW<%3iq7vq?bKI;^YW zRQcRzmp@IHh%wF+NLnyuUF%c#Jhk3~>-6$W$_`Ine^!2L-^}nu*P8Pg7#J8lUHx3v IIVCg!0K1u^r2qf` diff --git a/share/qtcreator/qmldesigner/statusbar/images/warningsPassive.png b/share/qtcreator/qmldesigner/statusbar/images/warningsPassive.png deleted file mode 100644 index 4d3ad8521190c49ac1e6c5a2f9c77f266e26de51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 286 zcmeAS@N?(olHy`uVBq!ia0y~yVBlw9VBq6mV_;zT(B<}?fq{Xuz$3Dlfq`2Xgc%uT z&5>YWU|=i`a(7}_cTVOd0|Ns~x}&cn1H;CC?mvmF3=9mLJzX3_Dj4Smatj_-;9+I= zaNrV}(9mMJfX|HmjH9YTVyOY=;PFPUI^=WY1%oqk8+>kn1f oJcx2V{lAyL{!q>4YkBdzS9 WindowManager::m_instance = nullptr; WindowManager::WindowManager() { connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &WindowManager::focusWindowChanged); - connect(qGuiApp, &QGuiApplication::aboutToQuit, this, &WindowManager::aboutToQuit); - connect(Core::ICore::instance()->mainWindow()->windowHandle(), - &QWindow::visibleChanged, - this, - &WindowManager::mainWindowVisibleChanged); + connect( + Core::ICore::instance(), &Core::ICore::coreAboutToClose, this, &WindowManager::aboutToQuit); + connect( + Core::ICore::instance()->mainWindow()->windowHandle(), + &QWindow::visibleChanged, + this, + &WindowManager::mainWindowVisibleChanged); } void WindowManager::registerDeclarativeType() From 442ab445c73cb7121e40fd4b282848a6bd4a94a1 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 3 Sep 2024 17:15:37 +0200 Subject: [PATCH 121/193] QmlDesigner: Consolidate context help MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move one singular implementation to the texteditor. Define a fallback help URL if no type is found. Change-Id: Ieccbeb449c22ff14060d1fb57dfd629770baf6f1 Reviewed-by: Henning Gründl --- .../components/navigator/navigatorwidget.cpp | 16 --------------- .../components/texteditor/texteditorview.cpp | 20 +++++++++++++++++++ 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp b/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp index 60e0b4c90c9..ae07b7b42c0 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp @@ -181,23 +181,7 @@ QToolBar *NavigatorWidget::createToolBar() void NavigatorWidget::contextHelp(const Core::IContext::HelpCallback &callback) const { if (auto view = navigatorView()) { - QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_HELP_REQUESTED - + view->contextHelpId()); -#ifndef QDS_USE_PROJECTSTORAGE - ModelNode selectedNode = view->firstSelectedModelNode(); - if (!selectedNode) - selectedNode = view->rootModelNode(); - - // TODO: Needs to be fixed for projectstorage. - const Core::HelpItem helpItem({QString::fromUtf8("QML." + selectedNode.type()), - "QML." + selectedNode.simplifiedTypeName()}, - {}, - {}, - Core::HelpItem::QmlComponent); - callback(helpItem); -#else QmlDesignerPlugin::contextHelp(callback, view->contextHelpId()); -#endif } else { callback({}); } diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp b/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp index c834f57257f..3d9cc2cf6ac 100644 --- a/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp +++ b/src/plugins/qmldesigner/components/texteditor/texteditorview.cpp @@ -142,10 +142,30 @@ WidgetInfo TextEditorView::widgetInfo() void TextEditorView::qmlJSEditorContextHelp(const Core::IContext::HelpCallback &callback) const { +#ifndef QDS_USE_PROJECTSTORAGE + ModelNode selectedNode = firstSelectedModelNode(); + if (!selectedNode) + selectedNode = rootModelNode(); + + // TODO: Needs to be fixed for projectstorage. + Core::HelpItem helpItem({QString::fromUtf8("QML." + selectedNode.type()), + "QML." + selectedNode.simplifiedTypeName()}, + {}, + {}, + Core::HelpItem::QmlComponent); + + if (!helpItem.isValid()) { + helpItem = Core::HelpItem( + QUrl("qthelp://org.qt-project.qtdesignstudio/doc/quick-preset-components.html")); + } + + callback(helpItem); +#else if (m_widget->textEditor()) m_widget->textEditor()->contextHelp(callback); else callback({}); +#endif } void TextEditorView::nodeIdChanged(const ModelNode& /*node*/, const QString &/*newId*/, const QString &/*oldId*/) From f594fe63eceb39f8a198e5e73569e247cfaa1525 Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Mon, 2 Sep 2024 13:48:08 +0300 Subject: [PATCH 122/193] Doc: Document ways to open effect composer effects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QDS-13464 Change-Id: I55311741eca71c66af801a87e570b66879fc8b25 Reviewed-by: Teea Põldsam Reviewed-by: Miikka Heikkinen --- .../src/views/qtquick-effect-maker-view.qdoc | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/doc/qtdesignstudio/src/views/qtquick-effect-maker-view.qdoc b/doc/qtdesignstudio/src/views/qtquick-effect-maker-view.qdoc index f0de1a35222..cc89cef7db5 100644 --- a/doc/qtdesignstudio/src/views/qtquick-effect-maker-view.qdoc +++ b/doc/qtdesignstudio/src/views/qtquick-effect-maker-view.qdoc @@ -43,9 +43,8 @@ \image studio-effect-composer-assets.webp "Effect Composer and the Assets view" - The saved custom effects appear in the \uicontrol {Assets} view. Double-click a - custom effect in \uicontrol Assets to view and edit it in \uicontrol {Effect Composer}. - To delete a custom effect, right-click it in the \uicontrol {Assets} view, and then + The saved custom effects appear in the \uicontrol {Assets} view. To delete a custom effect, + right-click it in the \uicontrol {Assets} view, and then select \uicontrol {Delete File}. \section1 Assigning a Custom Effect to a Component @@ -63,6 +62,18 @@ \note To assign an effect to a component, you need to save it first. + \section1 Editing Effects + + To open an effect in the \uicontrol {Effect Composer} to edit it, do one of the following: + + \list + \li In the \uicontrol Assets view, double-click the effect. + \li In the \uicontrol Navigator or \uicontrol Assets view, right-click and select + \uicontrol {Edit in Effect Composer}. + \li Drag the effect from the \uicontrol Navigator or \uicontrol Assets view to the + \uicontrol {Effect Composer} view. + \endlist + \section1 Stacking Effects To compose complex custom effects, add multiple effects to your stack in From 4e913b3d37bcc691c2a760ebda8137b4db483c70 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 4 Sep 2024 09:56:46 +0200 Subject: [PATCH 123/193] QmlDesigner: Do not set size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setting the icon size will lead to the icon font being used in Qt 6.7.3. We would have to set the complete font object. Change-Id: Ie770416c4a6c55c08259fce29367c59af17cf8ba Reviewed-by: Henning Gründl --- .../newprojectdialog/imports/NewProjectDialog/Details.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml index d85aab300d7..75677cbffcc 100644 --- a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml +++ b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml @@ -440,7 +440,7 @@ Item { width: StudioTheme.Values.singleControlColumnWidth buttonIcon: qsTr("Save Custom Preset") iconFont: StudioTheme.Constants.font - iconSize: DialogValues.defaultPixelSize + anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter From fd4214205eb5896809d5afc2ef3d95ef8c74110f Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Wed, 4 Sep 2024 11:41:37 +0200 Subject: [PATCH 124/193] QmlDesigner: Extend SVG paste color parsing Extend the SVG paste color parsing to support the following values rgb(255,255,255) and rgba(255,255,255,1.0). Task-number: QDS-13508 Change-Id: Id7750617b45a94b1541f5a40f31d610de56dbaee Reviewed-by: Thomas Hartmann --- .../componentcore/svgpasteaction.cpp | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp b/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp index 358e3dd5bee..f1b4dbb3f45 100644 --- a/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp +++ b/src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp @@ -814,8 +814,29 @@ QVariant convertValue(const QByteArray &key, const QString &value) return value.toInt(); } else if (key == "opacity") { return value.toFloat(); - } else if ((key == "fillColor" || key == "strokeColor") && value == "none") { - return "transparent"; + } else if ((key == "fillColor" || key == "strokeColor")) { + if (value == "none") + return QColor(0, 0, 0, 0); + + static const QRegularExpression reRGB( + R"(^rgb\((?\d{1,3}),\s*(?\d{1,3}),\s*(?\d{1,3})\)$)"); + QRegularExpressionMatch match = reRGB.match(value); + if (match.hasMatch()) { + return QColor(match.captured("red").toInt(), + match.captured("green").toInt(), + match.captured("blue").toInt()); + } + + static const QRegularExpression reRGBA( + R"(^rgba\((?\d{1,3}),\s*(?\d{1,3}),\s*(?\d{1,3}),\s*(?\d*(?:\.\d+))\)$)"); + match = reRGBA.match(value); + if (match.hasMatch()) { + QColor color(match.captured("red").toInt(), + match.captured("green").toInt(), + match.captured("blue").toInt()); + color.setAlphaF(match.captured("alpha").toFloat()); + return color; + } } return value; From 80ff1f90fdb15c74b36335a3398039808a2c287a Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Wed, 4 Sep 2024 13:50:49 +0200 Subject: [PATCH 125/193] QmlDesigner: Remove wrong font family alias * Remove wrong font family alias from AbstractButton and replace it with the correct one * Change the Contants font to the system/application font * Change warning color in PropertyEditor Change-Id: I1a33ced8ffc34aafa78f75100b2531845ddff5ef Reviewed-by: Thomas Hartmann --- .../ConnectionsDialogForm.qml | 8 ++++---- .../newprojectdialog/NewProjectDialog.qml | 4 ++-- .../imports/NewProjectDialog/Details.qml | 5 +++-- .../QtQuick/AlignDistributeSection.qml | 7 +++---- .../QtQuick/EffectsSection.qml | 4 ++-- .../imports/HelperWidgets/ComponentButton.qml | 2 +- .../imports/HelperWidgets/ComponentSection.qml | 2 +- .../HelperWidgets/DynamicPropertiesSection.qml | 2 +- .../imports/StudioControls/AbstractButton.qml | 12 ++++++++---- .../imports/StudioTheme/InternalConstants.qml | 18 +++++++++--------- .../stateseditor/StateThumbnail.qml | 2 +- share/qtcreator/qmldesigner/toolbar/Main.qml | 6 +++--- 12 files changed, 38 insertions(+), 34 deletions(-) diff --git a/share/qtcreator/qmldesigner/connectionseditor/ConnectionsDialogForm.qml b/share/qtcreator/qmldesigner/connectionseditor/ConnectionsDialogForm.qml index a799165375f..5ca4ed28d25 100644 --- a/share/qtcreator/qmldesigner/connectionseditor/ConnectionsDialogForm.qml +++ b/share/qtcreator/qmldesigner/connectionseditor/ConnectionsDialogForm.qml @@ -120,7 +120,7 @@ Column { buttonIcon: qsTr("Add Condition") tooltip: qsTr("Sets a logical condition for the selected Signal. It works with the properties of the Target component.") iconSize: StudioTheme.Values.baseFontSize - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family anchors.horizontalCenter: parent.horizontalCenter visible: action.currentValue !== ConnectionModelStatementDelegate.Custom && !backend.hasCondition @@ -133,7 +133,7 @@ Column { buttonIcon: qsTr("Remove Condition") tooltip: qsTr("Removes the logical condition for the Target component.") iconSize: StudioTheme.Values.baseFontSize - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family anchors.horizontalCenter: parent.horizontalCenter visible: action.currentValue !== ConnectionModelStatementDelegate.Custom && backend.hasCondition @@ -184,7 +184,7 @@ Column { buttonIcon: qsTr("Add Else Statement") tooltip: qsTr("Sets an alternate condition for the previously defined logical condition.") iconSize: StudioTheme.Values.baseFontSize - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family anchors.horizontalCenter: parent.horizontalCenter visible: action.currentValue !== ConnectionModelStatementDelegate.Custom && backend.hasCondition && !backend.hasElse @@ -198,7 +198,7 @@ Column { buttonIcon: qsTr("Remove Else Statement") tooltip: qsTr("Removes the alternate logical condition for the previously defined logical condition.") iconSize: StudioTheme.Values.baseFontSize - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family anchors.horizontalCenter: parent.horizontalCenter visible: action.currentValue !== ConnectionModelStatementDelegate.Custom && backend.hasCondition && backend.hasElse diff --git a/share/qtcreator/qmldesigner/newprojectdialog/NewProjectDialog.qml b/share/qtcreator/qmldesigner/newprojectdialog/NewProjectDialog.qml index ce298f7a2f8..bc3679a06cf 100644 --- a/share/qtcreator/qmldesigner/newprojectdialog/NewProjectDialog.qml +++ b/share/qtcreator/qmldesigner/newprojectdialog/NewProjectDialog.qml @@ -321,7 +321,7 @@ Item { visible: true buttonIcon: qsTr("Cancel") iconSize: DialogValues.defaultPixelSize - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family onClicked: { BackendApi.reject(); @@ -337,7 +337,7 @@ Item { buttonIcon: qsTr("Create") iconSize: DialogValues.defaultPixelSize enabled: BackendApi.fieldsValid - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family onClicked: { BackendApi.accept(); diff --git a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml index 75677cbffcc..f905191eff9 100644 --- a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml +++ b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml @@ -121,7 +121,7 @@ Item { iconSize: 20 visible: true buttonIcon: "…" - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family onClicked: { var newLocation = BackendApi.chooseProjectLocation() @@ -439,7 +439,8 @@ Item { id: savePresetButton width: StudioTheme.Values.singleControlColumnWidth buttonIcon: qsTr("Save Custom Preset") - iconFont: StudioTheme.Constants.font + iconSize: DialogValues.defaultPixelSize + iconFontFamily: StudioTheme.Constants.font.family anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AlignDistributeSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AlignDistributeSection.qml index 401c9c66af5..aa15697850d 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AlignDistributeSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AlignDistributeSection.qml @@ -337,7 +337,6 @@ Section { PropertyLabel { text: qsTr("Warning") visible: root.warningVisible - font.weight: Font.Bold } SecondColumnLayout { @@ -354,7 +353,7 @@ Section { Layout.fillWidth: true font.family: StudioTheme.Constants.font.family font.pixelSize: StudioTheme.Values.myFontSize - color: StudioTheme.Values.themeTextColor + color: StudioTheme.Values.themeAmberLight wrapMode: Text.WordWrap text: qsTr("- The selection contains the root component.") } @@ -365,7 +364,7 @@ Section { Layout.fillWidth: true font.family: StudioTheme.Constants.font.family font.pixelSize: StudioTheme.Values.myFontSize - color: StudioTheme.Values.themeTextColor + color: StudioTheme.Values.themeAmberLight wrapMode: Text.WordWrap text: qsTr("- The selection contains a non-visual component.") } @@ -376,7 +375,7 @@ Section { Layout.fillWidth: true font.family: StudioTheme.Constants.font.family font.pixelSize: StudioTheme.Values.myFontSize - color: StudioTheme.Values.themeTextColor + color: StudioTheme.Values.themeAmberLight wrapMode: Text.WordWrap text: qsTr("- A component in the selection uses anchors.") } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/EffectsSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/EffectsSection.qml index 59111572806..e6bd6193c67 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/EffectsSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/EffectsSection.qml @@ -62,7 +62,7 @@ Section { implicitWidth: StudioTheme.Values.singleControlColumnWidth width: StudioTheme.Values.singleControlColumnWidth buttonIcon: root.hasDesignerEffect ? qsTr("Remove Effects") : qsTr("Add Effects") - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family tooltip: qsTr("Adds visual effects on the component.") onClicked: { if (root.hasDesignerEffect) { @@ -535,7 +535,7 @@ Section { implicitWidth: StudioTheme.Values.singleControlColumnWidth width: StudioTheme.Values.singleControlColumnWidth buttonIcon: qsTr("Add Shadow Effect") - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family tooltip: qsTr("Adds Drop Shadow or Inner Shadow effects to a component.") onClicked: { modelNodeBackend.createModelNode(root.effectNode, diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentButton.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentButton.qml index 12c003af638..e8bea7b0bee 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentButton.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentButton.qml @@ -28,7 +28,7 @@ Column { AbstractButton { implicitWidth: 180 buttonIcon: qsTr("Edit Component") - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family onClicked: goIntoComponent() } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentSection.qml index a29bda0ba57..f3b460e0994 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ComponentSection.qml @@ -246,7 +246,7 @@ Section { width: StudioTheme.Values.singleControlColumnWidth visible: !annotationEditor.hasAuxData buttonIcon: qsTr("Add Annotation") - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family tooltip: qsTr("Adds a note with a title to explain the component.") onClicked: annotationEditor.showWidget() onHoveredChanged: annotationEditor.checkAux() diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DynamicPropertiesSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DynamicPropertiesSection.qml index 9ddec119153..dea81cab815 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DynamicPropertiesSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/DynamicPropertiesSection.qml @@ -732,7 +732,7 @@ Section { id: acceptButton buttonIcon: qsTr("Add Property") - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family width: cePopup.width / 3 enabled: textField.acceptableInput diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/AbstractButton.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/AbstractButton.qml index 703591887aa..a8781707361 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/AbstractButton.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/AbstractButton.qml @@ -16,8 +16,10 @@ T.AbstractButton { property alias buttonIcon: buttonIcon.text property alias iconColor: buttonIcon.color - property alias iconFont: buttonIcon.font.family - property alias iconSize: buttonIcon.font.pixelSize + + property string iconFontFamily: StudioTheme.Constants.iconFont.family + property int iconSize: control.style.baseIconFontSize + property alias iconItalic: buttonIcon.font.italic property alias iconBold: buttonIcon.font.bold property alias iconRotation: buttonIcon.rotation @@ -58,8 +60,10 @@ T.AbstractButton { T.Label { id: buttonIcon color: control.style.icon.idle - font.family: StudioTheme.Constants.iconFont.family - font.pixelSize: control.style.baseIconFontSize + font { + family: control.iconFontFamily + pixelSize: control.iconSize + } verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter anchors.fill: parent diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml index 3eb90118374..e606d48b30f 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml @@ -384,17 +384,17 @@ QtObject { readonly property string zoomSelection: "\u0193" readonly property font iconFont: Qt.font({ - "family": controlIcons.name, - "pixelSize": 12 - }) + family: controlIcons.name, + pixelSize: 12 + }) readonly property font font: Qt.font({ - "family": "Arial", - "pointSize": Qt.application.font.pixelSize - }) + family: Qt.application.font.family, + pointSize: Qt.application.font.pixelSize + }) readonly property font largeFont: Qt.font({ - "family": "Arial", - "pointSize": Qt.application.font.pixelSize * 1.6 - }) + family: "Arial", + pointSize: Qt.application.font.pixelSize * 1.6 + }) } diff --git a/share/qtcreator/qmldesigner/stateseditor/StateThumbnail.qml b/share/qtcreator/qmldesigner/stateseditor/StateThumbnail.qml index 703bc3e7ed0..ccbb5d3d0e6 100644 --- a/share/qtcreator/qmldesigner/stateseditor/StateThumbnail.qml +++ b/share/qtcreator/qmldesigner/stateseditor/StateThumbnail.qml @@ -168,7 +168,7 @@ Item { height: stateBackground.controlHeight checkedInverted: true buttonIcon: qsTr("Default") - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family tooltip: qsTr("Set State as default") onClicked: { root.defaultClicked() diff --git a/share/qtcreator/qmldesigner/toolbar/Main.qml b/share/qtcreator/qmldesigner/toolbar/Main.qml index 5cdc2f4d516..c69a0205e4c 100644 --- a/share/qtcreator/qmldesigner/toolbar/Main.qml +++ b/share/qtcreator/qmldesigner/toolbar/Main.qml @@ -153,7 +153,7 @@ Rectangle { anchors.verticalCenter: parent.verticalCenter anchors.left: runProject.right anchors.leftMargin: 10 - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family buttonIcon: qsTr("Live Preview") onClicked: { @@ -340,7 +340,7 @@ Rectangle { anchors.verticalCenter: parent.verticalCenter anchors.right: moreItems.left anchors.rightMargin: 8 - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family buttonIcon: qsTr("Share") visible: !root.flyoutEnabled && backend.isSharingEnabled enabled: backend.isSharingEnabled @@ -466,7 +466,7 @@ Rectangle { anchors.verticalCenter: parent.verticalCenter style: StudioTheme.Values.primaryToolbarStyle width: shareButton.width - iconFont: StudioTheme.Constants.font + iconFontFamily: StudioTheme.Constants.font.family buttonIcon: qsTr("Share") enabled: backend.isSharingEnabled tooltip: shareButton.enabled ? qsTr("Share your project online.") : qsTr("Sharing your project online is disabled in the Community Version.") From 0a94c3214b13e9ab4c5d80c212e31d2c19a7967b Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 4 Sep 2024 18:57:59 +0200 Subject: [PATCH 126/193] QmlDesigner: Fix project storage build Change-Id: Ifdfefa6a9dc84c95b8fc9c9a06490325bb3584f9 Reviewed-by: Mahmoud Badri --- .../qmldesigner/components/componentcore/bundlehelper.cpp | 5 ++++- src/plugins/qmldesigner/components/componentcore/utils3d.cpp | 2 +- src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp b/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp index 09d756365d3..0c3d52c081c 100644 --- a/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp +++ b/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp @@ -48,7 +48,10 @@ void BundleHelper::createImporter() m_importer = Utils::makeUniqueObjectPtr(); #ifdef QDS_USE_PROJECTSTORAGE - QObject::connect(m_importer, &BundleImporter::importFinished, m_widget, + QObject::connect( + m_importer.get(), + &BundleImporter::importFinished, + m_widget, [&](const QmlDesigner::TypeName &typeName, const QString &bundleId) { QTC_ASSERT(typeName.size(), return); if (isMaterialBundle(bundleId)) { diff --git a/src/plugins/qmldesigner/components/componentcore/utils3d.cpp b/src/plugins/qmldesigner/components/componentcore/utils3d.cpp index 6d0486131b5..7ddd0997cdf 100644 --- a/src/plugins/qmldesigner/components/componentcore/utils3d.cpp +++ b/src/plugins/qmldesigner/components/componentcore/utils3d.cpp @@ -256,7 +256,7 @@ void applyMaterialToModels(AbstractView *view, const ModelNode &material, #ifdef QDS_USE_PROJECTSTORAGE ModelNode createMaterial(AbstractView *view, const TypeName &typeName) { - ModelNode matLib = Utils3D::materialLibraryNode(this); + ModelNode matLib = Utils3D::materialLibraryNode(view); if (!matLib.isValid() || !typeName.size()) return {}; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index 3bb04e2301c..8b28e4b55de 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -805,7 +805,7 @@ void Edit3DWidget::dropEvent(QDropEvent *dropEvent) auto moduleId = model->module(import3dTypePrefix, Storage::ModuleKind::QmlLibrary); auto metaInfo = model->metaInfo(moduleId, fileName.toUtf8()); if (auto entries = metaInfo.itemLibrariesEntries(); entries.size()) { - auto entry = ItemLibraryEntry{entries.front()}; + auto entry = ItemLibraryEntry::create(entries.front()); QmlVisualNode::createQml3DNode(view(), entry, m_canvas->activeScene(), {}, false); } } From e8d0c613d3c64a2395e0e6aee70eed8262a854e1 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 4 Sep 2024 20:10:27 +0200 Subject: [PATCH 127/193] QmlDesigner: Fix call to the future There was an patch in the stack. So the fix broke qds/dev. Change-Id: Ia2177780ee33b6ded2643d0b05ed46165a894c3d Reviewed-by: Marco Bubke --- src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index 8b28e4b55de..43ba5db6686 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -805,7 +805,7 @@ void Edit3DWidget::dropEvent(QDropEvent *dropEvent) auto moduleId = model->module(import3dTypePrefix, Storage::ModuleKind::QmlLibrary); auto metaInfo = model->metaInfo(moduleId, fileName.toUtf8()); if (auto entries = metaInfo.itemLibrariesEntries(); entries.size()) { - auto entry = ItemLibraryEntry::create(entries.front()); + auto entry = ItemLibraryEntry(entries.front()); QmlVisualNode::createQml3DNode(view(), entry, m_canvas->activeScene(), {}, false); } } From 992da71da09cbd2294dd28f12d423da3f4169778 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Mon, 2 Sep 2024 17:18:50 +0300 Subject: [PATCH 128/193] QmlDesigner: Properly parse components in BundleHelper Instead of taking assets in the same folder as the component (which can cause issues, for example, if the component is in the project rather than an imported component), the component is properly parsed (recursively) and its dependencies are collected. There are some minor limitations due to the inherent complexity of qml. Also, some relevant fixes and tweaks. Fixes: QDS-13369 Fixes: QDS-13539 Fixes: QDS-13538 Change-Id: I6da9ce5cf14fb30c556fd521b6b452c3ab558f64 Reviewed-by: Miikka Heikkinen --- .../components/componentcore/bundlehelper.cpp | 185 ++++++++++++++---- .../components/componentcore/bundlehelper.h | 17 +- .../generatedcomponentutils.cpp | 21 +- 3 files changed, 162 insertions(+), 61 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp b/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp index 0c3d52c081c..702a3013757 100644 --- a/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp +++ b/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp @@ -33,6 +33,11 @@ namespace QmlDesigner { +Utils::FilePath AssetPath::absFilPath() const +{ + return basePath.pathAppended(relativePath); +} + BundleHelper::BundleHelper(AbstractView *view, QWidget *widget) : m_view(view) , m_widget(widget) @@ -51,7 +56,7 @@ void BundleHelper::createImporter() QObject::connect( m_importer.get(), &BundleImporter::importFinished, - m_widget, + m_view, [&](const QmlDesigner::TypeName &typeName, const QString &bundleId) { QTC_ASSERT(typeName.size(), return); if (isMaterialBundle(bundleId)) { @@ -75,7 +80,7 @@ void BundleHelper::createImporter() } }); #else - QObject::connect(m_importer.get(), &BundleImporter::importFinished, m_widget, + QObject::connect(m_importer.get(), &BundleImporter::importFinished, m_view, [&](const QmlDesigner::NodeMetaInfo &metaInfo, const QString &bundleId) { QTC_ASSERT(metaInfo.isValid(), return); if (isMaterialBundle(bundleId)) { @@ -185,12 +190,12 @@ void BundleHelper::importBundleToProject() void BundleHelper::exportBundle(const ModelNode &node, const QPixmap &iconPixmap) { if (node.isComponent()) - export3DComponent(node); + exportComponent(node); else - exportItem(node, iconPixmap); + exportNode(node, iconPixmap); } -void BundleHelper::export3DComponent(const ModelNode &node) +void BundleHelper::exportComponent(const ModelNode &node) { QString exportPath = getExportPath(node); if (exportPath.isEmpty()) @@ -204,26 +209,22 @@ void BundleHelper::export3DComponent(const ModelNode &node) m_zipWriter = std::make_unique(exportPath); - QString compBaseName = node.simplifiedTypeName(); - QString compFileName = compBaseName + ".qml"; - - auto compDir = Utils::FilePath::fromString(ModelUtils::componentFilePath(node)).parentDir(); + Utils::FilePath compFilePath = Utils::FilePath::fromString(ModelUtils::componentFilePath(node)); + Utils::FilePath compDir = compFilePath.parentDir(); + QString compBaseName = compFilePath.completeBaseName(); + QString compFileName = compFilePath.fileName(); QString iconPath = QLatin1String("icons/%1").arg(UniqueName::generateId(compBaseName) + ".png"); - const Utils::FilePaths sourceFiles = compDir.dirEntries({{}, QDir::Files, QDirIterator::Subdirectories}); - const QStringList ignoreList {"_importdata.json", "qmldir", compBaseName + ".hints"}; - QStringList filesList; // 3D component's assets (dependencies) + const QSet compDependencies = getComponentDependencies(compFilePath, compDir); - for (const Utils::FilePath &sourcePath : sourceFiles) { - Utils::FilePath relativePath = sourcePath.relativePathFrom(compDir); - if (ignoreList.contains(sourcePath.fileName()) || relativePath.startsWith("source scene")) - continue; + QStringList filesList; + for (const AssetPath &asset : compDependencies) { + Utils::FilePath assetAbsPath = asset.absFilPath(); + m_zipWriter->addFile(asset.relativePath, assetAbsPath.fileContents().value_or("")); - m_zipWriter->addFile(relativePath.toFSPathString(), sourcePath.fileContents().value_or("")); - - if (sourcePath.fileName() != compFileName) // skip component file (only collect dependencies) - filesList.append(relativePath.path()); + if (assetAbsPath.fileName() != compFileName) // skip component file (only collect dependencies) + filesList.append(asset.relativePath); } // add the item to the bundle json @@ -248,12 +249,12 @@ void BundleHelper::export3DComponent(const ModelNode &node) // add icon m_iconSavePath = targetPath.pathAppended(iconPath); m_iconSavePath.parentDir().ensureWritableDir(); - getImageFromCache(compDir.pathAppended(compFileName).path(), [&](const QImage &image) { + getImageFromCache(compFilePath.path(), [&](const QImage &image) { addIconAndCloseZip(image); }); } -void BundleHelper::exportItem(const ModelNode &node, const QPixmap &iconPixmap) +void BundleHelper::exportNode(const ModelNode &node, const QPixmap &iconPixmap) { QString exportPath = getExportPath(node); if (exportPath.isEmpty()) @@ -309,9 +310,15 @@ void BundleHelper::exportItem(const ModelNode &node, const QPixmap &iconPixmap) Utils::FilePath jsonFilePath = targetPath.pathAppended(Constants::BUNDLE_JSON_FILENAME); m_zipWriter->addFile(jsonFilePath.fileName(), QJsonDocument(jsonObj).toJson()); - // add item's dependency assets to the bundle zip - for (const AssetPath &assetPath : depAssetsList) - m_zipWriter->addFile(assetPath.relativePath, assetPath.absFilPath().fileContents().value_or("")); + // add item's dependency assets to the bundle zip and target path (for icon generation) + for (const AssetPath &assetPath : depAssetsList) { + auto assetContent = assetPath.absFilPath().fileContents().value_or(""); + m_zipWriter->addFile(assetPath.relativePath, assetContent); + + Utils::FilePath assetTargetPath = targetPath.pathAppended(assetPath.relativePath); + assetTargetPath.parentDir().ensureWritableDir(); + assetTargetPath.writeFileContents(assetContent); + } // add icon QPixmap iconPixmapToSave; @@ -359,8 +366,8 @@ QPair> BundleHelper::modelNodeToQmlString(const ModelNo const QList excludedProps = {"x", "y", "z", "eulerRotation.x", "eulerRotation.y", "eulerRotation.z", "scale.x", "scale.y", "scale.z", "pivot.x", "pivot.y", "pivot.z"}; - const QList matProps = node.properties(); - for (const AbstractProperty &p : matProps) { + const QList nodeProps = node.properties(); + for (const AbstractProperty &p : nodeProps) { if (excludedProps.contains(p.name())) continue; @@ -372,13 +379,11 @@ QPair> BundleHelper::modelNodeToQmlString(const ModelNo // dynamic property with no value assigned } else if (strcmp(pValue.typeName(), "QString") == 0 || strcmp(pValue.typeName(), "QColor") == 0) { val = QLatin1String("\"%1\"").arg(pValue.toString()); - } else if (strcmp(pValue.typeName(), "QUrl") == 0) { + } else if (std::string_view{pValue.typeName()} == "QUrl") { QString pValueStr = pValue.toString(); val = QLatin1String("\"%1\"").arg(pValueStr); - if (!pValueStr.startsWith("#")) { - assets.insert({DocumentManager::currentResourcePath().toFSPathString(), - pValue.toString()}); - } + if (!pValueStr.startsWith("#")) + assets.insert({DocumentManager::currentFilePath().parentDir(), pValue.toString()}); } else if (strcmp(pValue.typeName(), "QmlDesigner::Enumeration") == 0) { val = pValue.value().toString(); } else { @@ -391,19 +396,25 @@ QPair> BundleHelper::modelNodeToQmlString(const ModelNo qml += indent + p.name() + ": " + val + "\n"; } } else if (p.isBindingProperty()) { - ModelNode depNode = m_view->modelNodeForId(p.toBindingProperty().expression()); - QTC_ASSERT(depNode.isValid(), continue); + const QString pExp = p.toBindingProperty().expression(); + const QStringList depNodesIds = ModelUtils::expressionToList(pExp); + QTC_ASSERT(!depNodesIds.isEmpty(), continue); if (p.isDynamic()) - qml += indent + "property " + p.dynamicTypeName() + " " + p.name() + ": " + depNode.id() + "\n"; + qml += indent + "property " + p.dynamicTypeName() + " " + p.name() + ": " + pExp + "\n"; else - qml += indent + p.name() + ": " + depNode.id() + "\n"; + qml += indent + p.name() + ": " + pExp + "\n"; - if (depNode && !depListIds.contains(depNode.id())) { - depListIds.append(depNode.id()); - auto [depQml, depAssets] = modelNodeToQmlString(depNode, depth + 1); - qml += "\n" + depQml + "\n"; - assets.unite(depAssets); + for (const QString &id : depNodesIds) { + ModelNode depNode = m_view->modelNodeForId(id); + QTC_ASSERT(depNode.isValid(), continue); + + if (depNode && !depListIds.contains(depNode.id())) { + depListIds.append(depNode.id()); + auto [depQml, depAssets] = modelNodeToQmlString(depNode, depth + 1); + qml += "\n" + depQml + "\n"; + assets.unite(depAssets); + } } } } @@ -430,9 +441,10 @@ QPair> BundleHelper::modelNodeToQmlString(const ModelNo if (depth > 0) { // add component file to the dependency assets Utils::FilePath compFilePath = componentPath(node.metaInfo()); - assets.insert({compFilePath.parentDir().path(), compFilePath.fileName()}); + assets.insert({compFilePath.parentDir(), compFilePath.fileName()}); } + // TODO: use getComponentDependencies() and remove getBundleComponentDependencies() if (isBundle) assets.unite(getBundleComponentDependencies(node)); } @@ -469,7 +481,7 @@ QSet BundleHelper::getBundleComponentDependencies(const ModelNode &no for (const QString &asset : bundleAssets) { if (rootObj.value(asset).toArray().contains(compFileName)) - depList.insert({compPath.toFSPathString(), asset}); + depList.insert({compPath, asset}); } return depList; @@ -575,4 +587,91 @@ bool BundleHelper::isItemBundle(const QString &bundleId) const || bundleId == compUtils.user3DBundleId(); } +namespace { + +// library imported Components won't be detected. TODO: find a feasible solution for detecting them +// and either add them as dependencies or warn the user +Utils::FilePath getComponentFilePath(const QString &nodeType, const Utils::FilePath &compDir) +{ + Utils::FilePath compFilePath = compDir.pathAppended(QLatin1String("%1.qml").arg(nodeType)); + if (compFilePath.exists()) + return compFilePath; + + compFilePath = compDir.pathAppended(QLatin1String("%1.ui.qml").arg(nodeType)); + if (compFilePath.exists()) + return compFilePath; + + const Utils::FilePaths subDirs = compDir.dirEntries(QDir::Dirs | QDir::NoDotAndDotDot); + for (const Utils::FilePath &dir : subDirs) { + compFilePath = getComponentFilePath(nodeType, dir); + if (compFilePath.exists()) + return compFilePath; + } + + return {}; +} + +} // namespace + +QSet BundleHelper::getComponentDependencies(const Utils::FilePath &filePath, + const Utils::FilePath &mainCompDir) +{ + QSet depList; + + depList.insert({mainCompDir, filePath.relativePathFrom(mainCompDir).toFSPathString()}); + + ModelPointer model = Model::create("Item"); + Utils::FileReader reader; + QTC_ASSERT(reader.fetch(filePath), return {}); + + QPlainTextEdit textEdit; + textEdit.setPlainText(QString::fromUtf8(reader.data())); + NotIndentingTextEditModifier modifier(&textEdit); + modifier.setParent(model.get()); + RewriterView rewriterView(m_view->externalDependencies(), RewriterView::Validate); + rewriterView.setCheckSemanticErrors(false); + rewriterView.setTextModifier(&modifier); + model->attachView(&rewriterView); + rewriterView.restoreAuxiliaryData(); + ModelNode rootNode = rewriterView.rootModelNode(); + QTC_ASSERT(rootNode.isValid(), return {}); + + std::function parseNode; + parseNode = [&](const ModelNode &node) { + // workaround node.isComponent() as it is not working here + QString nodeType = QString::fromLatin1(node.type()); + if (!nodeType.startsWith("QtQuick")) { + Utils::FilePath compFilPath = getComponentFilePath(nodeType, mainCompDir); + if (!compFilPath.isEmpty()) { + depList.unite(getComponentDependencies(compFilPath, mainCompDir)); + return; + } + } + + const QList nodeProps = node.properties(); + for (const AbstractProperty &p : nodeProps) { + if (p.isVariantProperty()) { + QVariant pValue = p.toVariantProperty().value(); + if (std::string_view{pValue.typeName()} == "QUrl") { + QString pValueStr = pValue.toString(); + if (!pValueStr.isEmpty() && !pValueStr.startsWith("#")) { + Utils::FilePath assetPath = filePath.parentDir().resolvePath(pValueStr); + Utils::FilePath assetPathRelative = assetPath.relativePathFrom(mainCompDir); + depList.insert({mainCompDir, assetPathRelative.toFSPathString()}); + } + } + } + } + + // parse child nodes + const QList childNodes = node.directSubModelNodes(); + for (const ModelNode &childNode : childNodes) + parseNode(childNode); + }; + + parseNode(rootNode); + + return depList; +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/bundlehelper.h b/src/plugins/qmldesigner/components/componentcore/bundlehelper.h index de70dfc60f1..270109cd0b4 100644 --- a/src/plugins/qmldesigner/components/componentcore/bundlehelper.h +++ b/src/plugins/qmldesigner/components/componentcore/bundlehelper.h @@ -22,21 +22,20 @@ class BundleImporter; class ModelNode; class NodeMetaInfo; -struct AssetPath +class AssetPath { - QString basePath; +public: + Utils::FilePath basePath; QString relativePath; - Utils::FilePath absFilPath() const - { - return Utils::FilePath::fromString(basePath).pathAppended(relativePath); - } + Utils::FilePath absFilPath() const; bool operator==(const AssetPath &other) const { return basePath == other.basePath && relativePath == other.relativePath; } +private: friend size_t qHash(const AssetPath &asset) { return ::qHash(asset.relativePath); @@ -65,8 +64,10 @@ private: void addIconAndCloseZip(const auto &image); Utils::FilePath componentPath(const NodeMetaInfo &metaInfo) const; QSet getBundleComponentDependencies(const ModelNode &node) const; - void export3DComponent(const ModelNode &node); - void exportItem(const ModelNode &node, const QPixmap &iconPixmap = QPixmap()); + QSet getComponentDependencies(const Utils::FilePath &filePath, + const Utils::FilePath &mainCompDir); + void exportComponent(const ModelNode &node); + void exportNode(const ModelNode &node, const QPixmap &iconPixmap = QPixmap()); QPointer m_view; QPointer m_widget; diff --git a/src/plugins/qmldesigner/libs/designercore/designercoreutils/generatedcomponentutils.cpp b/src/plugins/qmldesigner/libs/designercore/designercoreutils/generatedcomponentutils.cpp index bd628ea9bfe..b1b7161c31c 100644 --- a/src/plugins/qmldesigner/libs/designercore/designercoreutils/generatedcomponentutils.cpp +++ b/src/plugins/qmldesigner/libs/designercore/designercoreutils/generatedcomponentutils.cpp @@ -8,6 +8,7 @@ namespace QmlDesigner { constexpr QLatin1String componentBundlesMaterialBundleType{"Materials"}; +constexpr QLatin1String componentBundlesEffectBundleType{"Effects"}; constexpr QLatin1String componentBundlesType{"Bundles"}; constexpr QLatin1String componentBundlesUser3DBundleType{"User3D"}; constexpr QLatin1String componentBundlesUserEffectsBundleType{"UserEffects"}; @@ -16,7 +17,8 @@ constexpr QLatin1String composedEffectType{"Effects"}; constexpr QLatin1String generatedComponentsFolder{"Generated"}; constexpr QLatin1String oldAssetImportFolder{"asset_imports"}; constexpr QLatin1String oldComponentBundleType{"ComponentBundles"}; -constexpr QLatin1String oldComponentsBundlesMaterialBundleType{"MaterialBundle"}; +constexpr QLatin1String oldComponentBundlesMaterialBundleType{"MaterialBundle"}; +constexpr QLatin1String oldComponentBundlesEffectBundleType{"EffectBundle"}; constexpr QLatin1String oldEffectFolder{"Effects"}; namespace Constants {} // namespace Constants @@ -128,9 +130,9 @@ Utils::FilePath GeneratedComponentUtils::materialBundlePath() const return {}; if (basePath.endsWith(Constants::quick3DComponentsFolder)) - return basePath.resolvePath(oldComponentsBundlesMaterialBundleType); + return basePath.resolvePath(oldComponentBundlesMaterialBundleType); - return basePath.resolvePath(QLatin1String(componentBundlesMaterialBundleType)); + return basePath.resolvePath(componentBundlesMaterialBundleType); } Utils::FilePath GeneratedComponentUtils::effectBundlePath() const @@ -141,9 +143,9 @@ Utils::FilePath GeneratedComponentUtils::effectBundlePath() const return {}; if (basePath.endsWith(Constants::quick3DComponentsFolder)) - return basePath.resolvePath(componentBundlesMaterialBundleType); + return basePath.resolvePath(oldComponentBundlesEffectBundleType); - return basePath.resolvePath(componentBundlesMaterialBundleType); + return basePath.resolvePath(componentBundlesEffectBundleType); } Utils::FilePath GeneratedComponentUtils::userBundlePath(const QString &bundleId) const @@ -218,7 +220,6 @@ bool GeneratedComponentUtils::isGeneratedPath(const QString &path) const return path.startsWith(generatedComponentsPath().toFSPathString()); } - QString GeneratedComponentUtils::generatedComponentTypePrefix() const { Utils::FilePath basePath = generatedComponentsPath(); @@ -270,20 +271,20 @@ QString GeneratedComponentUtils::materialsBundleId() const bool isNewImportDir = generatedComponentTypePrefix().endsWith(generatedComponentsFolder); return isNewImportDir ? componentBundlesMaterialBundleType - : oldComponentsBundlesMaterialBundleType; + : oldComponentBundlesMaterialBundleType; } QString GeneratedComponentUtils::effectsBundleId() const { bool isNewImportDir = generatedComponentTypePrefix().endsWith(generatedComponentsFolder); - return QLatin1String(isNewImportDir ? componentBundlesMaterialBundleType - : componentBundlesMaterialBundleType); + return isNewImportDir ? componentBundlesEffectBundleType + : oldComponentBundlesEffectBundleType; } QString GeneratedComponentUtils::userMaterialsBundleId() const { - return componentBundlesMaterialBundleType; + return componentBundlesUserMaterialBundleType; } QString GeneratedComponentUtils::userEffectsBundleId() const From 21d8df14d479846140462f3edd2ce658a3155f52 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 5 Sep 2024 16:16:45 +0300 Subject: [PATCH 129/193] QmlDesigner: Remove unused function Change-Id: I213198baaf545a063f5c15559450f3dbf9dc34b0 Reviewed-by: Mahmoud Badri --- .../qml2puppet/instances/qt5informationnodeinstanceserver.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.h b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.h index 60eebe488ae..feb4939c8f8 100644 --- a/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.h +++ b/src/tools/qml2puppet/qml2puppet/instances/qt5informationnodeinstanceserver.h @@ -89,7 +89,6 @@ private: void handleSelectionChangeTimeout(); void handleDynamicAddObjectTimeout(); void createEditView3D(); - void create3DPreviewView(); void setup3DEditView(const QList &instanceList, const CreateSceneCommand &command); void createGizmos(const QList &instanceList) const; From 52c7d2b0f0d0bf75e3ea443ad57fd40e57932c58 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 5 Sep 2024 16:22:36 +0300 Subject: [PATCH 130/193] QmlDesigner: Fix targetTexture getting invalidated after menu open In some situation the targetTexture gets invalidated after the context menu opens. This is likely related to texture model changing the selection, but the exact cause is not known. Worked around the issue by already storing the texture internal id at menu open. Fixes: QDS-13461 Change-Id: Ib0e29a59b22ab9ccf244de3dcd4e7d2d1ee0fd7b Reviewed-by: Mahmoud Badri --- .../TextureBrowserContextMenu.qml | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureBrowserContextMenu.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureBrowserContextMenu.qml index 714c0043703..99f398c8fbb 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureBrowserContextMenu.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/TextureBrowserContextMenu.qml @@ -10,16 +10,17 @@ import MaterialBrowserBackend StudioControls.Menu { id: root - property var targetTexture: null - property int copiedTextureInternalId: -1 + property int textureInternalId: -1 property var materialBrowserTexturesModel: MaterialBrowserBackend.materialBrowserTexturesModel function popupMenu(targetTexture = null) { - this.targetTexture = targetTexture + root.textureInternalId = targetTexture ? targetTexture.textureInternalId : -1 + materialBrowserTexturesModel.updateSceneEnvState() materialBrowserTexturesModel.updateModelSelectionState() + popup() } @@ -27,33 +28,33 @@ StudioControls.Menu { StudioControls.MenuItem { text: qsTr("Apply to selected model") - enabled: root.targetTexture && materialBrowserTexturesModel.hasSingleModelSelection - onTriggered: materialBrowserTexturesModel.applyToSelectedModel(root.targetTexture.textureInternalId) + enabled: root.textureInternalId >= 0 && materialBrowserTexturesModel.hasSingleModelSelection + onTriggered: materialBrowserTexturesModel.applyToSelectedModel(root.textureInternalId) } StudioControls.MenuItem { text: qsTr("Apply to selected material") - enabled: root.targetTexture && MaterialBrowserBackend.materialBrowserModel.selectedIndex >= 0 - onTriggered: materialBrowserTexturesModel.applyToSelectedMaterial(root.targetTexture.textureInternalId) + enabled: root.textureInternalId >= 0 && MaterialBrowserBackend.materialBrowserModel.selectedIndex >= 0 + onTriggered: materialBrowserTexturesModel.applyToSelectedMaterial(root.textureInternalId) } StudioControls.MenuItem { text: qsTr("Apply as light probe") - enabled: root.targetTexture && materialBrowserTexturesModel.hasSceneEnv - onTriggered: materialBrowserTexturesModel.applyAsLightProbe(root.targetTexture.textureInternalId) + enabled: root.textureInternalId >= 0 && materialBrowserTexturesModel.hasSceneEnv + onTriggered: materialBrowserTexturesModel.applyAsLightProbe(root.textureInternalId) } StudioControls.MenuSeparator {} StudioControls.MenuItem { text: qsTr("Duplicate") - enabled: root.targetTexture + enabled: root.textureInternalId >= 0 onTriggered: materialBrowserTexturesModel.duplicateTexture(materialBrowserTexturesModel.selectedIndex) } StudioControls.MenuItem { text: qsTr("Delete") - enabled: root.targetTexture + enabled: root.textureInternalId >= 0 onTriggered: materialBrowserTexturesModel.deleteTexture(materialBrowserTexturesModel.selectedIndex) } From 340f1ce19afc73a6232b870121ac3782c3134bbd Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Fri, 30 Aug 2024 16:23:19 +0300 Subject: [PATCH 131/193] QmlDesigner: Don't display the camera, if it has no scene Fixes: QDS-13490 Change-Id: I82bf07866f667dd39773f7e5e172ebd36c36e46e Reviewed-by: Mahmoud Badri --- src/tools/qml2puppet/editor3d_qt6.qrc | 1 + .../mockfiles/qt6/CameraDisplay.qml | 82 ++++++++++ .../qml2puppet/mockfiles/qt6/CameraView.qml | 149 +++++++----------- .../qml2puppet/editor3d/generalhelper.cpp | 14 ++ .../qml2puppet/editor3d/generalhelper.h | 1 + 5 files changed, 156 insertions(+), 91 deletions(-) create mode 100644 src/tools/qml2puppet/mockfiles/qt6/CameraDisplay.qml diff --git a/src/tools/qml2puppet/editor3d_qt6.qrc b/src/tools/qml2puppet/editor3d_qt6.qrc index e1de7a0903d..e75e671e7e0 100644 --- a/src/tools/qml2puppet/editor3d_qt6.qrc +++ b/src/tools/qml2puppet/editor3d_qt6.qrc @@ -24,6 +24,7 @@ mockfiles/qt6/AdjustableArrow.qml mockfiles/qt6/Arrow.qml mockfiles/qt6/AutoScaleHelper.qml + mockfiles/qt6/CameraDisplay.qml mockfiles/qt6/CameraFrustum.qml mockfiles/qt6/CameraGizmo.qml mockfiles/qt6/CameraView.qml diff --git a/src/tools/qml2puppet/mockfiles/qt6/CameraDisplay.qml b/src/tools/qml2puppet/mockfiles/qt6/CameraDisplay.qml new file mode 100644 index 00000000000..f1eb741c7a9 --- /dev/null +++ b/src/tools/qml2puppet/mockfiles/qt6/CameraDisplay.qml @@ -0,0 +1,82 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +import QtQuick +import QtQuick3D + +Item { + id: cameraDisplay + + required property Camera camera + required property size preferredSize + required property size viewPortSize + required property var activeScene + required property var activeSceneEnvironment + + implicitWidth: view3D.dispSize.width + implicitHeight: view3D.dispSize.height + clip: true + + View3D { + id: view3D + + readonly property bool isOrthographicCamera: _generalHelper.isOrthographicCamera(view3D.camera) + property size dispSize: calculateSize(cameraDisplay.viewPortSize, cameraDisplay.preferredSize) + readonly property real magnificationFactor: cameraDisplay.viewPortSize.width === 0 + ? 1.0 + : (view3D.dispSize.width / cameraDisplay.viewPortSize.width) + + transformOrigin: Item.Center + anchors.centerIn: parent + + camera: cameraDisplay.camera + importScene: cameraDisplay.activeScene + environment: cameraDisplay.activeSceneEnvironment ?? defaultSceneEnvironment + + function calculateSize(viewPortSize: size, preferredSize : size) { + if (_generalHelper.fuzzyCompare(viewPortSize.width, 0) + || _generalHelper.fuzzyCompare(viewPortSize.height, 0)) { + return Qt.size(0, 0) + } + + let aspectRatio = viewPortSize.height / viewPortSize.width + var calculatedHeight = preferredSize.width * aspectRatio + if (calculatedHeight <= preferredSize.height) + return Qt.size(preferredSize.width, calculatedHeight) + + var calculatedWidth = preferredSize.height / aspectRatio; + return Qt.size(calculatedWidth, preferredSize.height); + } + } + + SceneEnvironment { + id: defaultSceneEnvironment + + antialiasingMode: SceneEnvironment.MSAA + antialiasingQuality: SceneEnvironment.High + } + + states: [ + State { + name: "orthoCamera" + when: view3D.isOrthographicCamera + PropertyChanges { + target: view3D + + width: cameraDisplay.viewPortSize.width + height: cameraDisplay.viewPortSize.height + scale: view3D.magnificationFactor + } + }, + State { + name: "nonOrthoCamera" + when: !view3D.isOrthographicCamera + PropertyChanges { + target: view3D + + width: view3D.dispSize.width + height: view3D.dispSize.height + scale: 1.0 + } + } + ] +} diff --git a/src/tools/qml2puppet/mockfiles/qt6/CameraView.qml b/src/tools/qml2puppet/mockfiles/qt6/CameraView.qml index 3bc67468099..fe886a71d68 100644 --- a/src/tools/qml2puppet/mockfiles/qt6/CameraView.qml +++ b/src/tools/qml2puppet/mockfiles/qt6/CameraView.qml @@ -3,7 +3,7 @@ import QtQuick import QtQuick3D -Item { +Rectangle { id: cameraView required property bool showCameraView @@ -16,44 +16,57 @@ Item { property var activeSceneEnvironment property var preferredCamera - width: loader.width - height: loader.height + width: priv.loaderSize.width + 2 + height: priv.loaderSize.height + 2 + anchors.bottom: parent.bottom anchors.margins: 10 - visible: loader.active - onTargetNodeChanged: loader.updateCamera() - onAlwaysOnChanged: loader.updateCamera() - onPreferredCameraChanged: loader.updateCamera() + visible: priv.cameraViewIsOn + + onTargetNodeChanged: priv.updateCamera() + onAlwaysOnChanged: priv.updateCamera() + onPreferredCameraChanged: priv.updateCamera() onActiveSceneChanged: forceReload() - Component.onCompleted: loader.updateCamera() + Component.onCompleted: priv.updateCamera() + + border.width: 1 + border.color: "lightslategray" + color: "black" function forceReload() { - loader.forceDeactive = true - loader.oldCamera = null - loader.updateCamera() - loader.forceDeactive = false + priv.forceDeactive = true + priv.oldCamera = null + priv.updateCamera() + priv.forceDeactive = false } - Loader { - id: loader + QtObject { + id: priv property Camera camera property Camera oldCamera + property bool view3dRootNodeExists property bool forceDeactive: false - - active: !forceDeactive && (cameraView.alwaysOn || cameraView.showCameraView) && loader.camera + readonly property bool cameraViewIsOn: !forceDeactive && (cameraView.alwaysOn || cameraView.showCameraView) && priv.camera + readonly property bool cameraHasValidScene: priv.cameraViewIsOn && priv.view3dRootNodeExists + property Loader activeLoader + readonly property size loaderSize: activeLoader && activeLoader.active + ? Qt.size(activeLoader.width, activeLoader.height) + : Qt.size(-2, -2) function updateCamera() { - loader.camera = activeCamera() + let activeCam = activeCamera() + priv.camera = activeCam + priv.view3dRootNodeExists = _generalHelper.view3dRootNode(activeCam) } function activeCamera() { if (cameraView.alwaysOn) { if (_generalHelper.isCamera(cameraView.targetNode)) return cameraView.targetNode - else if (loader.oldCamera) - return loader.oldCamera + else if (priv.oldCamera) + return priv.oldCamera else return cameraView.preferredCamera } else if (_generalHelper.isCamera(cameraView.targetNode)) { @@ -63,82 +76,36 @@ Item { } onCameraChanged: { - if (loader.camera) - loader.oldCamera = loader.camera - } - - sourceComponent: Rectangle { - id: cameraRect - - implicitWidth: view3D.dispSize.width + 2 - implicitHeight: view3D.dispSize.height + 2 - border.width: 1 - border.color: "lightslategray" - color: "black" - - View3D { - id: view3D - - readonly property bool isOrthographicCamera: _generalHelper.isOrthographicCamera(view3D.camera) - property size dispSize: calculateSize(cameraView.viewPortSize, cameraView.preferredSize) - readonly property real magnificationFactor: cameraView.viewPortSize.width === 0 - ? 1.0 - : (view3D.dispSize.width / cameraView.viewPortSize.width) - - transformOrigin: Item.Center - anchors.centerIn: parent - - camera: loader.camera - importScene: cameraView.activeScene - environment: cameraView.activeSceneEnvironment ?? defaultSceneEnvironment - - function calculateSize(viewPortSize: size, preferredSize : size){ - if (_generalHelper.fuzzyCompare(viewPortSize.width, 0) - || _generalHelper.fuzzyCompare(viewPortSize.height, 0)) - return Qt.size(0, 0) - - let aspectRatio = viewPortSize.height / viewPortSize.width - var calculatedHeight = preferredSize.width * aspectRatio - if (calculatedHeight <= preferredSize.height) - return Qt.size(preferredSize.width, calculatedHeight) - - var calculatedWidth = preferredSize.height / aspectRatio; - return Qt.size(calculatedWidth, preferredSize.height); - } - - states: [ - State { - name: "orthoCamera" - when: view3D.isOrthographicCamera - PropertyChanges { - target: view3D - - width: cameraView.viewPortSize.width - height: cameraView.viewPortSize.height - scale: view3D.magnificationFactor - } - }, - State { - name: "nonOrthoCamera" - when: !view3D.isOrthographicCamera - PropertyChanges { - target: view3D - - width: view3D.dispSize.width - height: view3D.dispSize.height - scale: 1.0 - } - } - ] - } + if (priv.camera) + priv.oldCamera = priv.camera } } - SceneEnvironment { - id: defaultSceneEnvironment + Loader { + id: cameraLoader - antialiasingMode: SceneEnvironment.MSAA - antialiasingQuality: SceneEnvironment.High + active: priv.cameraViewIsOn && priv.cameraHasValidScene + onLoaded: priv.activeLoader = this + sourceComponent: CameraDisplay { + camera: priv.camera + preferredSize: cameraView.preferredSize + viewPortSize: cameraView.viewPortSize + activeScene: cameraView.activeScene + activeSceneEnvironment: cameraView.activeSceneEnvironment + } + } + + Loader { + id: errorLoader + + active: priv.cameraViewIsOn && !priv.cameraHasValidScene + onLoaded: priv.activeLoader = this + sourceComponent: Text { + font.pixelSize: 14 + color: "yellow" + text: qsTr("Camera does not have a valid view") + padding: 10 + } } states: [ diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp index e58192e54f8..9392787e4c6 100644 --- a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp +++ b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp @@ -692,6 +692,20 @@ bool GeneralHelper::isOrthographicCamera(QQuick3DNode *node) const return node && qobject_cast(node); } +QQuick3DNode *GeneralHelper::view3dRootNode(QQuick3DNode *node) const +{ + if (!node) + return nullptr; + + QQuick3DNode *parentNode = node->parentNode(); + while (parentNode) { + if (parentNode->inherits("QQuick3DSceneRootNode")) + return parentNode; + parentNode = parentNode->parentNode(); + } + return nullptr; +} + // Emitter gizmo model creation is done in C++ as creating dynamic properties and // assigning materials to dynamically created models is lot simpler in C++ QQuick3DNode *GeneralHelper::createParticleEmitterGizmoModel(QQuick3DNode *emitter, diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h index 4aa66bd7419..aec9c4970e6 100644 --- a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h +++ b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h @@ -97,6 +97,7 @@ public: Q_INVOKABLE bool isPickable(QQuick3DNode *node) const; Q_INVOKABLE bool isCamera(QQuick3DNode *node) const; Q_INVOKABLE bool isOrthographicCamera(QQuick3DNode *node) const; + Q_INVOKABLE QQuick3DNode *view3dRootNode(QQuick3DNode *node) const; Q_INVOKABLE QQuick3DNode *createParticleEmitterGizmoModel(QQuick3DNode *emitter, QQuick3DMaterial *material) const; From 6a50339e67c7d1f54829f3bfa9f96e69cdeb7200 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 6 Sep 2024 11:56:42 +0300 Subject: [PATCH 132/193] QmlDesigner: Optimize some metainfo checks Use isBasedOn() when checking for multiple types. Change-Id: I37751c4b3e6238caf39e705f7b68fb1800f2549d Reviewed-by: Marco Bubke --- .../components/navigator/nameitemdelegate.cpp | 18 +++++---- .../libs/designercore/include/model.h | 4 ++ .../libs/designercore/model/model.cpp | 40 +++++++++++++++++++ 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp index e3a74031bca..01e4ead915f 100644 --- a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp +++ b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp @@ -216,12 +216,13 @@ void NameItemDelegate::paint(QPainter *painter, QByteArray dragType = widget->dragType(); const NodeMetaInfo metaInfo = node.metaInfo(); - auto isValid3dTextureTarget = [&metaInfo]() -> bool { - return metaInfo.isQtQuick3DModel() - || metaInfo.isQtQuick3DTexture() - || metaInfo.isQtQuick3DSceneEnvironment() - || metaInfo.isQtQuick3DTextureInput() - || metaInfo.isQtQuick3DParticles3DSpriteParticle3D(); + auto isValid3dTextureTarget = [&metaInfo, &node]() -> bool { + Model *model = node.model(); + return metaInfo.isBasedOn(model->qtQuick3DModelMetaInfo(), + model->qtQuick3DTextureMetaInfo(), + model->qtQuick3DSceneEnvironmentMetaInfo(), + model->qtQuick3DTextureInputMetaInfo(), + model->qtQuick3DParticles3DSpriteParticle3DMetaInfo()); }; bool validDrop = false; @@ -230,8 +231,9 @@ void NameItemDelegate::paint(QPainter *painter, } else if (dragType == Constants::MIME_TYPE_ASSET_TEXTURE3D) { validDrop = isValid3dTextureTarget(); } else if (dragType == Constants::MIME_TYPE_ASSET_IMAGE) { - validDrop = isValid3dTextureTarget() - || metaInfo.isQtQuickImage() || metaInfo.isQtQuickBorderImage(); + Model *model = node.model(); + validDrop = isValid3dTextureTarget() || metaInfo.isBasedOn(model->qtQuickImageMetaInfo(), + model->qtQuickBorderImageMetaInfo()); } else { const NodeMetaInfo dragInfo = node.model()->metaInfo(dragType); ChooseFromPropertyListFilter *filter = new ChooseFromPropertyListFilter(dragInfo, metaInfo, true); diff --git a/src/plugins/qmldesigner/libs/designercore/include/model.h b/src/plugins/qmldesigner/libs/designercore/include/model.h index 13754e56d10..534c0d7ed00 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/model.h +++ b/src/plugins/qmldesigner/libs/designercore/include/model.h @@ -177,11 +177,15 @@ public: NodeMetaInfo qtQuick3DModelMetaInfo() const; NodeMetaInfo qtQuick3DNodeMetaInfo() const; NodeMetaInfo qtQuick3DOrthographicCameraMetaInfo() const; + NodeMetaInfo qtQuick3DParticles3DSpriteParticle3DMetaInfo() const; NodeMetaInfo qtQuick3DPerspectiveCameraMetaInfo() const; NodeMetaInfo qtQuick3DPointLightMetaInfo() const; NodeMetaInfo qtQuick3DPrincipledMaterialMetaInfo() const; + NodeMetaInfo qtQuick3DSceneEnvironmentMetaInfo() const; NodeMetaInfo qtQuick3DSpotLightMetaInfo() const; NodeMetaInfo qtQuick3DTextureMetaInfo() const; + NodeMetaInfo qtQuick3DTextureInputMetaInfo() const; + NodeMetaInfo qtQuickBorderImageMetaInfo() const; NodeMetaInfo qtQuickControlsTextAreaMetaInfo() const; NodeMetaInfo qtQuickImageMetaInfo() const; NodeMetaInfo qtQuickItemMetaInfo() const; diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index 183bc58d493..fbe59c06460 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -2545,6 +2545,16 @@ NodeMetaInfo Model::qtQuick3DOrthographicCameraMetaInfo() const } } +NodeMetaInfo Model::qtQuick3DParticles3DSpriteParticle3DMetaInfo() const +{ + if constexpr (useProjectStorage()) { + using namespace Storage::Info; + return createNodeMetaInfo(); + } else { + return metaInfo("QtQuick3D.Particles3D.SpriteParticle3D"); + } +} + NodeMetaInfo Model::qtQuick3DPerspectiveCameraMetaInfo() const { if constexpr (useProjectStorage()) { @@ -2564,6 +2574,26 @@ NodeMetaInfo Model::qtQuick3DTextureMetaInfo() const } } +NodeMetaInfo Model::qtQuick3DTextureInputMetaInfo() const +{ + if constexpr (useProjectStorage()) { + using namespace Storage::Info; + return createNodeMetaInfo(); + } else { + return metaInfo("QtQuick3D.TextureInput"); + } +} + +NodeMetaInfo Model::qtQuickBorderImageMetaInfo() const +{ + if constexpr (useProjectStorage()) { + using namespace Storage::Info; + return createNodeMetaInfo(); + } else { + return metaInfo("QtQuick.BorderImage"); + } +} + NodeMetaInfo Model::qtQuick3DBakedLightmapMetaInfo() const { if constexpr (useProjectStorage()) { @@ -2614,6 +2644,16 @@ NodeMetaInfo Model::qtQuick3DPrincipledMaterialMetaInfo() const } } +NodeMetaInfo Model::qtQuick3DSceneEnvironmentMetaInfo() const +{ + if constexpr (useProjectStorage()) { + using namespace Storage::Info; + return createNodeMetaInfo(); + } else { + return metaInfo("QtQuick3D.SceneEnvironment"); + } +} + NodeMetaInfo Model::qtQuickTimelineTimelineMetaInfo() const { if constexpr (useProjectStorage()) { From a949d50f33d2076c6ce252628e5dfaf5fd75d029 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Jen=C3=9Fen?= Date: Thu, 5 Sep 2024 20:31:59 +0200 Subject: [PATCH 133/193] QmlDesigner: fix build with MSVC2022 Change-Id: Ifef972c0b8ef0f4810c7c55d87d1d21cdc0d1801 Reviewed-by: Marco Bubke --- cmake/Utils.cmake | 18 ++++++++++++++++++ .../libs/designercore/CMakeLists.txt | 6 +++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/cmake/Utils.cmake b/cmake/Utils.cmake index e7fa26d918d..766b6ff755e 100644 --- a/cmake/Utils.cmake +++ b/cmake/Utils.cmake @@ -100,4 +100,22 @@ function(configure_qml_designer Qt6_VERSION) env_with_default("QTC_IS_SUPPORTED_PROJECTSTORAGE_QT" ENV_QTC_IS_SUPPORTED_PROJECTSTORAGE_QT ${QTC_IS_SUPPORTED_PROJECTSTORAGE_QT_DEFAULT}) option(IS_SUPPORTED_PROJECTSTORAGE_QT "IS_SUPPORTED_PROJECTSTORAGE_QT" ${ENV_QTC_IS_SUPPORTED_PROJECTSTORAGE_QT}) add_feature_info("IS_SUPPORTED_PROJECTSTORAGE_QT" ${IS_SUPPORTED_PROJECTSTORAGE_QT} "is ${IS_SUPPORTED_PROJECTSTORAGE_QT}") + + # to enable define QML_DOM_MSVC2019_COMPAT if necessary, see QTBUG-127761 + if(NOT DEFINED QT_BUILT_WITH_MSVC2019) + get_target_property(QT_QMAKE_EXECUTABLE Qt6::qmake IMPORTED_LOCATION) + + execute_process( + COMMAND dumpbin /headers ${QT_QMAKE_EXECUTABLE} | findstr /c:"linker version" + OUTPUT_VARIABLE DUMPBIN_OUTPUT + ) + + string(FIND "${DUMPBIN_OUTPUT}" "14.2" QT_BUILT_WITH_MSVC2019) + + if(QT_BUILT_WITH_MSVC2019 GREATER -1) + set(QT_BUILT_WITH_MSVC2019 TRUE CACHE BOOL "Qt was built with MSVC 2019") + else() + set(QT_BUILT_WITH_MSVC2019 FALSE CACHE BOOL "Qt was not built with MSVC 2019") + endif() + endif() endfunction() diff --git a/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt b/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt index 61ed67663f8..fbca41645d5 100644 --- a/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt +++ b/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt @@ -368,11 +368,15 @@ extend_qtc_library(QmlDesignerCore storagecachefwd.h ) +extend_qtc_library(QmlDesignerCore + CONDITION QT_BUILT_WITH_MSVC2019 + DEFINES QML_DOM_MSVC2019_COMPAT +) + extend_qtc_library(QmlDesignerCore SOURCES_PREFIX projectstorage PUBLIC_INCLUDES projectstorage SOURCES_PROPERTIES SKIP_AUTOGEN ON - DEFINES QML_DOM_MSVC2019_COMPAT # can be removed for Qt 6.8 SOURCES commontypecache.h directorypathcompressor.h From 04155ac5a16809687d593fa9f2d362d72dd86839 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 9 Sep 2024 12:40:36 +0200 Subject: [PATCH 134/193] QmlDesigner: Fix project build The code has to be fixed in the future. But I am unsure if it even needed for the project storage. Change-Id: Iabff94678df56b3c2ac58959e5dead0fea92e86e Reviewed-by: Tim Jenssen --- .../qmldesigner/components/componentcore/bundlehelper.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp b/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp index 702a3013757..c49e4746bf1 100644 --- a/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp +++ b/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp @@ -620,7 +620,12 @@ QSet BundleHelper::getComponentDependencies(const Utils::FilePath &fi depList.insert({mainCompDir, filePath.relativePathFrom(mainCompDir).toFSPathString()}); +#ifdef QDS_USE_PROJECTSTORAGE + // TODO add model with ProjectStorageDependencies + ModelPointer model; +#else ModelPointer model = Model::create("Item"); +#endif Utils::FileReader reader; QTC_ASSERT(reader.fetch(filePath), return {}); From 989eae166774b73eb90d91b89a1ce24f0112b741 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Tue, 3 Sep 2024 16:46:37 +0200 Subject: [PATCH 135/193] QmlDesigner: EyeDropper use platform service Task-number: QDS-12517 Change-Id: I1fdbdf3aa0992826d109d0e24e92d15c7576fb93 Reviewed-by: Tim Jenssen --- .../imports/HelperWidgets/ColorEditor.qml | 12 +- .../HelperWidgets/ColorEditorPopup.qml | 11 +- .../imports/StudioControls/ColorEditor.qml | 3 + .../StudioControls/impl/ColorEditorPopup.qml | 6 +- src/plugins/qmldesigner/CMakeLists.txt | 2 +- .../propertyeditor/colorpalettebackend.cpp | 295 ++++++++++-------- .../propertyeditor/colorpalettebackend.h | 108 ++++--- 7 files changed, 254 insertions(+), 183 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml index cc8247d7063..1a7291a441d 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml @@ -39,7 +39,7 @@ SecondColumnLayout { property bool shapeGradients: false - //for now, gradients on MCUs are limited to Basic and Shape Linear Gradient: + // Gradients on MCUs are limited to Basic and Shape Linear Gradient. property bool mcuGradients: false property color originalColor @@ -91,9 +91,9 @@ SecondColumnLayout { if (colorEditor.backendValue !== undefined) { if (colorEditor.isVector3D) - colorEditor.backendValue.value = Qt.vector3d( - colorEditor.color.r, colorEditor.color.g, - colorEditor.color.b) + colorEditor.backendValue.value = Qt.vector3d(colorEditor.color.r, + colorEditor.color.g, + colorEditor.color.b) else colorEditor.backendValue.value = colorEditor.color } @@ -223,10 +223,8 @@ SecondColumnLayout { function open() { popupDialog.ensureLoader() - popupDialog.show(preview) - - popupDialog.loaderItem.aboutToBeShown() //need it for now + popupDialog.loaderItem.aboutToBeShown() // need it for now } function determineActiveColorMode() { diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml index bced56a89dc..126b9a0dac2 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml @@ -12,10 +12,9 @@ import QtQuickDesignerColorPalette Column { id: root - // There seems to be an issue on Windows and MacOS with ColorPickers - // Canvases not being painted on initialization - // because ColorEditorPopup is invisible at init time, - // so we use this signal to explicitly pass visibility status + // There seems to be an issue on Windows and macOS with ColorPickers canvas not being painted + // on initialization, because ColorEditorPopup is invisible at init time, so we use this signal + // to explicitly pass visibility status. signal aboutToBeShown property bool eyeDropperActive: ColorPaletteBackend.eyeDropperActive @@ -23,7 +22,7 @@ Column { property bool supportGradient: false property bool shapeGradients: false - //for now, gradients on MCUs are limited to Basic and Shape Linear Gradient: + // Gradients on MCUs are limited to Basic and Shape Linear Gradient. property bool mcuGradients: false property alias gradientLine: gradientLine @@ -188,7 +187,7 @@ Column { icon: StudioTheme.Constants.eyeDropper pixelSize: StudioTheme.Values.myIconFontSize * 1.4 tooltip: qsTr("Eye Dropper") - onClicked: ColorPaletteBackend.eyeDropper() + onClicked: ColorPaletteBackend.invokeEyeDropper() } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ColorEditor.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ColorEditor.qml index 640f21de9e2..4100ecf934c 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ColorEditor.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ColorEditor.qml @@ -69,6 +69,8 @@ Item { property QtObject loaderItem: loader.item + keepOpen: loader.item?.eyeDropperActive ?? false + width: 260 function ensureLoader() { @@ -91,6 +93,7 @@ Item { id: popup width: popupDialog.contentWidth visible: popupDialog.visible + parentWindow: popupDialog.window onActivateColor: function(color) { colorBackend.activateColor(color) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/impl/ColorEditorPopup.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/impl/ColorEditorPopup.qml index 4f46b356f3a..0674a156a0a 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/impl/ColorEditorPopup.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/impl/ColorEditorPopup.qml @@ -12,9 +12,13 @@ import QtQuickDesignerColorPalette Column { id: root + property bool eyeDropperActive: ColorPaletteBackend.eyeDropperActive + property color color property color originalColor + property Window parentWindow: null + readonly property real twoColumnWidth: (colorColumn.width - StudioTheme.Values.controlGap) * 0.5 readonly property real fourColumnWidth: (colorColumn.width - (3 * StudioTheme.Values.controlGap)) * 0.25 @@ -42,7 +46,7 @@ Column { icon: StudioTheme.Constants.eyeDropper pixelSize: StudioTheme.Values.myIconFontSize * 1.4 toolTip: qsTr("Eye Dropper") - onClicked: ColorPaletteBackend.eyeDropper() + onClicked: ColorPaletteBackend.invokeEyeDropper() } } diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index cc9243d84b4..0f0a0c70414 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -53,7 +53,7 @@ add_qtc_plugin(QmlDesigner PLUGIN_MANUAL_DEPENDS LicenseChecker ${IDE_VERSION} optional DEPENDS QmlJS LanguageUtils QmlEditorWidgets AdvancedDockingSystem - Qt::QuickWidgets Qt::CorePrivate Qt::Xml Qt::Svg Sqlite Zip + Qt::QuickWidgets Qt::CorePrivate Qt::Xml Qt::Svg Sqlite Zip Qt::GuiPrivate PUBLIC_DEPENDS QmlDesignerUtils QmlPuppetCommunication QmlDesignerCore DEFINES diff --git a/src/plugins/qmldesigner/components/propertyeditor/colorpalettebackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/colorpalettebackend.cpp index fc5b9c6ebb3..7ca01e3d2bd 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/colorpalettebackend.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/colorpalettebackend.cpp @@ -9,9 +9,14 @@ #include #include #include +#include #include #include +#include +#include +#include + namespace QmlDesigner { QPointer ColorPaletteBackend::m_instance = nullptr; @@ -19,7 +24,7 @@ QPointer ColorPaletteBackend::m_instance = nullptr; ColorPaletteBackend::ColorPaletteBackend() : m_currentPalette() , m_data() - , m_colorPickingEventFilter(nullptr) + , m_eyeDropperEventFilter(nullptr) #ifdef Q_OS_WIN32 , updateTimer(0) #endif @@ -43,6 +48,8 @@ ColorPaletteBackend::ColorPaletteBackend() ColorPaletteBackend::~ColorPaletteBackend() { //writePalettes(); // TODO crash on QtDS close + if (m_eyeDropperActive) + eyeDropperLeave(QCursor::pos(), EyeDropperEventFilter::LeaveReason::Default); } void ColorPaletteBackend::readPalettes() @@ -204,67 +211,129 @@ void ColorPaletteBackend::showDialog(QColor color) QTimer::singleShot(0, [colorDialog](){ colorDialog->exec(); }); } -void ColorPaletteBackend::eyeDropper() +void ColorPaletteBackend::invokeEyeDropper() { - QWidget *widget = Core::ICore::mainWindow(); - if (!widget) - return; - - m_eyeDropperActive = true; - emit eyeDropperActiveChanged(); - - if (!m_colorPickingEventFilter) - m_colorPickingEventFilter = new QColorPickingEventFilter(this); - - widget->installEventFilter(m_colorPickingEventFilter); -#ifndef QT_NO_CURSOR - widget->grabMouse(/*Qt::CrossCursor*/); -#else - widget->grabMouse(); -#endif -#ifdef Q_OS_WIN32 // excludes WinRT - // On Windows mouse tracking doesn't work over other processes's windows - updateTimer->start(30); - // HACK: Because mouse grabbing doesn't work across processes, we have to have a dummy, - // invisible window to catch the mouse click, otherwise we will click whatever we clicked - // and loose focus. - dummyTransparentWindow.show(); -#endif - widget->grabKeyboard(); - /* With setMouseTracking(true) the desired color can be more precisely picked up, - * and continuously pushing the mouse button is not necessary. - */ - widget->setMouseTracking(true); - - QGuiApplication::setOverrideCursor(QCursor()); - - updateEyeDropperPosition(QCursor::pos()); + eyeDropperEnter(); } -const int g_cursorWidth = 64; -const int g_cursorHeight = 64; -const int g_screenGrabWidth = 7; -const int g_screenGrabHeight = 7; -const int g_pixelX = 3; -const int g_pixelY = 3; +void ColorPaletteBackend::eyeDropperEnter() +{ + if (m_eyeDropperActive) + return; + + QPointer window = Core::ICore::mainWindow()->windowHandle(); + + if (m_eyeDropperWindow.isNull()) { + if (window.isNull()) { + qWarning() << "No window found, cannot enter eyeDropperMode."; + return; + } + + m_eyeDropperWindow = window; + } + + if (auto *platformServices = QGuiApplicationPrivate::platformIntegration()->services(); + platformServices + && platformServices->hasCapability(QPlatformServices::Capability::ColorPicking)) { + if (auto *colorPickerService = platformServices->colorPicker(m_eyeDropperWindow)) { + connect(colorPickerService, + &QPlatformServiceColorPicker::colorPicked, + this, + [this, colorPickerService](const QColor &color) { + colorPickerService->deleteLater(); + // When the service was canceled by pressing escape the color returned will + // be QColor(ARGB, 0, 0, 0, 0), so we test for alpha to avoid setting the color. + // https://codereview.qt-project.org/c/qt/qtbase/+/589113 + if (color.alpha() != 0 || !color.isValid()) + emit currentColorChanged(color); + m_eyeDropperActive = false; + emit eyeDropperActiveChanged(); + }); + m_eyeDropperActive = true; + emit eyeDropperActiveChanged(); + colorPickerService->pickColor(); + return; + } + } + + m_eyeDropperPreviousColor = m_eyeDropperCurrentColor; + + if (!bool(m_eyeDropperEventFilter)) + m_eyeDropperEventFilter.reset(new EyeDropperEventFilter( + [this](QPoint pos, EyeDropperEventFilter::LeaveReason c) { eyeDropperLeave(pos, c); }, + [this](QPoint pos) { eyeDropperPointerMoved(pos); })); + + if (m_eyeDropperWindow->setMouseGrabEnabled(true) + && m_eyeDropperWindow->setKeyboardGrabEnabled(true)) { +#if QT_CONFIG(cursor) + QGuiApplication::setOverrideCursor(QCursor()); + updateEyeDropperPosition(QCursor::pos()); +#endif + m_eyeDropperWindow->installEventFilter(m_eyeDropperEventFilter.get()); + m_eyeDropperActive = true; + emit eyeDropperActiveChanged(); + } +} + +void ColorPaletteBackend::eyeDropperLeave(const QPoint &pos, + EyeDropperEventFilter::LeaveReason actionOnLeave) +{ + if (!m_eyeDropperActive) + return; + + if (!m_eyeDropperWindow) { + qWarning() << "Window not set, cannot leave eyeDropperMode."; + return; + } + + if (actionOnLeave != EyeDropperEventFilter::LeaveReason::Cancel) { + m_eyeDropperCurrentColor = grabScreenColor(pos); + + emit currentColorChanged(m_eyeDropperCurrentColor); + } + + m_eyeDropperWindow->removeEventFilter(m_eyeDropperEventFilter.get()); + m_eyeDropperWindow->setMouseGrabEnabled(false); + m_eyeDropperWindow->setKeyboardGrabEnabled(false); +#if QT_CONFIG(cursor) + QGuiApplication::restoreOverrideCursor(); +#endif + + m_eyeDropperActive = false; + emit eyeDropperActiveChanged(); + m_eyeDropperWindow.clear(); +} + +void ColorPaletteBackend::eyeDropperPointerMoved(const QPoint &pos) +{ + m_eyeDropperCurrentColor = grabScreenColor(pos); + updateEyeDropperPosition(pos); +} + +const QSize g_cursorSize(64, 64); +const QSize g_halfCursorSize = g_cursorSize / 2; +const QSize g_screenGrabSize(11, 11); +const QSize g_previewSize(12, 12); +const QSize g_halfPreviewSize = g_previewSize / 2; QColor ColorPaletteBackend::grabScreenColor(const QPoint &p) { - return grabScreenRect(p).pixel(g_pixelX, g_pixelY); + return grabScreenRect(QRect(p, QSize(1, 1))).pixel(0, 0); } -QImage ColorPaletteBackend::grabScreenRect(const QPoint &p) +QImage ColorPaletteBackend::grabScreenRect(const QRect &r) { - QScreen *screen = QGuiApplication::screenAt(p); + QScreen *screen = QGuiApplication::screenAt(r.topLeft()); if (!screen) screen = QGuiApplication::primaryScreen(); const QRect screenRect = screen->geometry(); const QPixmap pixmap = screen->grabWindow(0, - p.x() - screenRect.x(), - p.y() - screenRect.y(), - g_screenGrabWidth, - g_screenGrabHeight); + r.x() - screenRect.x(), + r.y() - screenRect.y(), + r.width(), + r.height()); + return pixmap.toImage(); } @@ -272,7 +341,7 @@ void ColorPaletteBackend::updateEyeDropper() { #ifndef QT_NO_CURSOR static QPoint lastGlobalPos; - QPoint newGlobalPos = QCursor::pos(); + const QPoint newGlobalPos = QCursor::pos(); if (lastGlobalPos == newGlobalPos) return; @@ -287,102 +356,70 @@ void ColorPaletteBackend::updateEyeDropper() void ColorPaletteBackend::updateEyeDropperPosition(const QPoint &globalPos) { - updateCursor(grabScreenRect(globalPos)); +#if QT_CONFIG(cursor) + QPoint topLeft = globalPos - QPoint(g_halfCursorSize.width(), g_halfCursorSize.height()); + updateCursor(grabScreenRect(QRect(topLeft, g_cursorSize))); +#endif } void ColorPaletteBackend::updateCursor(const QImage &image) { - QWidget *widget = Core::ICore::mainWindow(); - if (!widget) + QWindow *window = Core::ICore::mainWindow()->windowHandle(); + if (!window) return; - QPixmap pixmap(QSize(g_cursorWidth, g_cursorHeight)); + QPixmap pixmap(g_cursorSize); + pixmap.fill(Qt::transparent); + QPainter painter(&pixmap); + painter.setRenderHint(QPainter::Antialiasing); + + QPainterPath clipPath; + clipPath.addEllipse(QRect(QPoint(0, 0), g_cursorSize).adjusted(1, 1, -1, -1)); + + painter.setClipPath(clipPath, Qt::IntersectClip); + + const QPoint topLeft = QPoint(g_halfCursorSize.width(), g_halfCursorSize.height()) + - QPoint(qFloor(g_screenGrabSize.width() / 2), + qFloor(g_screenGrabSize.height() / 2)); + + const QColor topCenter = image.pixelColor(g_halfCursorSize.width(), 0); + const QColor bottomCenter = image.pixelColor(g_halfCursorSize.width(), g_cursorSize.height() - 1); + const QColor leftCenter = image.pixelColor(0, g_halfCursorSize.height()); + const QColor rightCenter = image.pixelColor(g_cursorSize.width() - 1, g_halfCursorSize.height()); + + // Find the mean gray value of top, bottom, left and right center + int borderGray = (qGray(topCenter.rgb()) + qGray(bottomCenter.rgb()) + qGray(leftCenter.rgb()) + + qGray(rightCenter.rgb())) + / 4; + // Draw the magnified image/screen grab - QRect r(QPoint(), pixmap.size()); - painter.drawImage(r, image, QRect(0, 0, g_screenGrabWidth, g_screenGrabHeight)); + const QRect r(QPoint(), pixmap.size()); + painter.drawImage(r, image, QRect(topLeft, g_screenGrabSize)); - const int pixelWidth = (g_cursorWidth - 1) / g_screenGrabWidth; - const int pixelHeight = (g_cursorHeight - 1) / g_screenGrabHeight; - // Draw the pixel lines - painter.setPen(QPen(QColor(192, 192, 192, 150), 1.0, Qt::SolidLine)); - for (int i = 1; i != g_screenGrabWidth; ++i) { - int x = pixelWidth * i; - painter.drawLine(x, 0, x, g_cursorHeight); - } + painter.setClipping(false); - for (int i = 1; i != g_screenGrabHeight; ++i) { - int y = pixelHeight * i; - painter.drawLine(0, y, g_cursorWidth, y); - } - // Draw the sorounding border - painter.setPen(QPen(Qt::black, 1.0, Qt::SolidLine)); - painter.drawRect(r.adjusted(0, 0, -1, -1)); + QPen pen(borderGray < 128 ? Qt::white : Qt::black, 2.0, Qt::SolidLine); - const QColor color = image.pixel(g_pixelX, g_pixelY); - QRect centerRect = QRect(2 * pixelWidth, 2 * pixelHeight, 3 * pixelWidth, 3 * pixelHeight); - // Draw the center rectangle with the current eye dropper color - painter.setBrush(QBrush(color, Qt::SolidPattern)); - painter.drawRect(centerRect); + // Draw the surrounding border + painter.setPen(pen); + painter.drawPath(clipPath); + + pen.setWidth(1); + painter.setPen(pen); + + const QRect previewRect(QPoint(g_halfCursorSize.width() - g_halfPreviewSize.width(), + g_halfCursorSize.height() - g_halfPreviewSize.height()), + g_previewSize); + + painter.fillRect(previewRect, m_eyeDropperCurrentColor); + painter.drawRect(previewRect); painter.end(); + QGuiApplication::changeOverrideCursor(QCursor(pixmap)); } -void ColorPaletteBackend::releaseEyeDropper() -{ - QWidget *widget = Core::ICore::mainWindow(); - if (!widget) - return; - - m_eyeDropperActive = false; - emit eyeDropperActiveChanged(); - - widget->removeEventFilter(m_colorPickingEventFilter); - widget->releaseMouse(); -#ifdef Q_OS_WIN32 - updateTimer->stop(); - dummyTransparentWindow.setVisible(false); -#endif - widget->releaseKeyboard(); - widget->setMouseTracking(false); - - QGuiApplication::restoreOverrideCursor(); -} - -bool ColorPaletteBackend::handleEyeDropperMouseMove(QMouseEvent *e) -{ - updateEyeDropperPosition(e->globalPosition().toPoint()); - return true; -} - -bool ColorPaletteBackend::handleEyeDropperMouseButtonRelease(QMouseEvent *e) -{ - if (e->button() == Qt::LeftButton) - emit currentColorChanged(grabScreenColor(e->globalPosition().toPoint())); - else - emit eyeDropperRejected(); - - releaseEyeDropper(); - return true; -} - -bool ColorPaletteBackend::handleEyeDropperKeyPress(QKeyEvent *e) -{ -#if QT_CONFIG(shortcut) - if (e->matches(QKeySequence::Cancel)) { - emit eyeDropperRejected(); - releaseEyeDropper(); - } //else -#endif - //if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) { - // emit currentColorChanged(grabScreenColor(e->globalPosition().toPoint())); - // releaseEyeDropper(); - //} - e->accept(); - return true; -} - bool ColorPaletteBackend::eyeDropperActive() const { return m_eyeDropperActive; diff --git a/src/plugins/qmldesigner/components/propertyeditor/colorpalettebackend.h b/src/plugins/qmldesigner/components/propertyeditor/colorpalettebackend.h index 9ab60d7c9e6..1d88fd4de39 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/colorpalettebackend.h +++ b/src/plugins/qmldesigner/components/propertyeditor/colorpalettebackend.h @@ -18,12 +18,62 @@ namespace QmlDesigner { -class QColorPickingEventFilter; - const int g_maxPaletteSize = 8; const QString g_recent = "Recent"; const QString g_favorite = "Favorite"; +class EyeDropperEventFilter : public QObject +{ +public: + enum class LeaveReason { Default, Cancel }; + + explicit EyeDropperEventFilter(std::function callOnLeave, + std::function callOnUpdate) + : m_leave(callOnLeave) + , m_update(callOnUpdate) + {} + + bool eventFilter(QObject *obj, QEvent *event) override + { + switch (event->type()) { + case QEvent::MouseMove: { + m_lastPosition = static_cast(event)->globalPosition().toPoint(); + m_update(m_lastPosition); + return true; + } + case QEvent::MouseButtonRelease: { + m_lastPosition = static_cast(event)->globalPosition().toPoint(); + m_leave(m_lastPosition, EyeDropperEventFilter::LeaveReason::Default); + return true; + } + case QEvent::MouseButtonPress: + return true; + case QEvent::KeyPress: { + auto keyEvent = static_cast(event); +#if QT_CONFIG(shortcut) + if (keyEvent->matches(QKeySequence::Cancel)) + m_leave(m_lastPosition, EyeDropperEventFilter::LeaveReason::Cancel); + else +#endif + if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) { + m_leave(m_lastPosition, EyeDropperEventFilter::LeaveReason::Default); + } else if (keyEvent->key() == Qt::Key_Escape) { + m_leave(m_lastPosition, EyeDropperEventFilter::LeaveReason::Cancel); + } + keyEvent->accept(); + return true; + } + default: + return QObject::eventFilter(obj, event); + } + } + +private: + std::function m_leave; + std::function m_update; + QPoint m_lastPosition; +}; + struct Palette { Palette() @@ -100,20 +150,22 @@ public: Q_INVOKABLE void showDialog(QColor color); - Q_INVOKABLE void eyeDropper(); + //Q_INVOKABLE void eyeDropper(); + + Q_INVOKABLE void invokeEyeDropper(); QColor grabScreenColor(const QPoint &p); - QImage grabScreenRect(const QPoint &p); + QImage grabScreenRect(const QRect &r); void updateEyeDropper(); void updateEyeDropperPosition(const QPoint &globalPos); void updateCursor(const QImage &image); - void releaseEyeDropper(); - - bool handleEyeDropperMouseMove(QMouseEvent *e); - bool handleEyeDropperMouseButtonRelease(QMouseEvent *e); - bool handleEyeDropperKeyPress(QKeyEvent *e); + //void releaseEyeDropper(); + // + //bool handleEyeDropperMouseMove(QMouseEvent *e); + //bool handleEyeDropperMouseButtonRelease(QMouseEvent *e); + //bool handleEyeDropperKeyPress(QKeyEvent *e); bool eyeDropperActive() const; @@ -134,13 +186,20 @@ signals: private: ColorPaletteBackend(); + void eyeDropperEnter(); + void eyeDropperLeave(const QPoint &pos, EyeDropperEventFilter::LeaveReason actionOnLeave); + void eyeDropperPointerMoved(const QPoint &pos); + private: static QPointer m_instance; QString m_currentPalette; QStringList m_currentPaletteColors; QHash m_data; - QColorPickingEventFilter *m_colorPickingEventFilter; + std::unique_ptr m_eyeDropperEventFilter; + QPointer m_eyeDropperWindow; + QColor m_eyeDropperCurrentColor; + QColor m_eyeDropperPreviousColor; bool m_eyeDropperActive = false; #ifdef Q_OS_WIN32 QTimer *updateTimer; @@ -148,35 +207,6 @@ private: #endif }; -class QColorPickingEventFilter : public QObject { -public: - explicit QColorPickingEventFilter(ColorPaletteBackend *colorPalette) - : QObject(colorPalette) - , m_colorPalette(colorPalette) - {} - - bool eventFilter(QObject *, QEvent *event) override - { - switch (event->type()) { - case QEvent::MouseMove: - return m_colorPalette->handleEyeDropperMouseMove( - static_cast(event)); - case QEvent::MouseButtonRelease: - return m_colorPalette->handleEyeDropperMouseButtonRelease( - static_cast(event)); - case QEvent::KeyPress: - return m_colorPalette->handleEyeDropperKeyPress( - static_cast(event)); - default: - break; - } - return false; - } - -private: - ColorPaletteBackend *m_colorPalette; -}; - } // namespace QmlDesigner QML_DECLARE_TYPE(QmlDesigner::ColorPaletteBackend) From e3842cf23676e3a9739d8348f8cbffa143e903ef Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Mon, 9 Sep 2024 17:11:53 +0200 Subject: [PATCH 136/193] QmlDesigner: Fix SpinBox showing group separator In Qt 6.7.3 the StudioControls SpinBoxes were showing group separators caused by the validator fixup function which takes the system locale to generated the presented string. We fix this with a design studio specific locale that is assigned to the controls that show numbers. Task-number: QDS-13536 Change-Id: I26682b08a8e29cd5dc09b3ff09212568bfa4fe52 Reviewed-by: Marco Bubke --- .../imports/StudioControls/RealSpinBox.qml | 3 ++ .../imports/StudioControls/SpinBox.qml | 3 ++ src/plugins/qmldesigner/qmldesignerplugin.cpp | 2 - src/plugins/qmldesignerbase/CMakeLists.txt | 1 + .../qmldesignerbase/qmldesignerbaseplugin.cpp | 5 +++ .../studio/studioquickutils.cpp | 31 +++++++++++++++ .../qmldesignerbase/studio/studioquickutils.h | 39 +++++++++++++++++++ .../qmldesignerbase/utils/windowmanager.cpp | 6 +-- .../qmldesignerbase/utils/windowmanager.h | 6 +-- 9 files changed, 86 insertions(+), 10 deletions(-) create mode 100644 src/plugins/qmldesignerbase/studio/studioquickutils.cpp create mode 100644 src/plugins/qmldesignerbase/studio/studioquickutils.h diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBox.qml index 9072a2de8ae..c83be5bd2b4 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBox.qml @@ -4,6 +4,7 @@ import QtQuick import QtQuick.Templates as T import StudioTheme 1.0 as StudioTheme +import StudioQuickUtils T.SpinBox { id: control @@ -71,6 +72,8 @@ T.SpinBox { signal dragging signal indicatorPressed + locale: Utils.locale + // Use custom wheel handling due to bugs property bool __wheelEnabled: false wheelEnabled: false diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml index ffde6e4ad16..8a07e4bc478 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml @@ -4,6 +4,7 @@ import QtQuick import QtQuick.Templates as T import StudioTheme 1.0 as StudioTheme +import StudioQuickUtils T.SpinBox { id: control @@ -54,6 +55,8 @@ T.SpinBox { signal dragEnded signal dragging + locale: Utils.locale + // Use custom wheel handling due to bugs property bool __wheelEnabled: false wheelEnabled: false diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 68d3c7071f8..a158ba43098 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #ifndef QDS_USE_PROJECTSTORAGE # include #endif @@ -311,7 +310,6 @@ bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *e //TODO Move registering those types out of the property editor, since they are used also in the states editor Quick2PropertyEditorView::registerQmlTypes(); StudioQuickWidget::registerDeclarativeType(); - QmlDesignerBase::WindowManager::registerDeclarativeType(); Exception::setWarnAboutException(!QmlDesignerPlugin::instance() ->settings() diff --git a/src/plugins/qmldesignerbase/CMakeLists.txt b/src/plugins/qmldesignerbase/CMakeLists.txt index 2cee711a35c..4fe7d952f70 100644 --- a/src/plugins/qmldesignerbase/CMakeLists.txt +++ b/src/plugins/qmldesignerbase/CMakeLists.txt @@ -45,6 +45,7 @@ extend_qtc_plugin(QmlDesignerBase PUBLIC_INCLUDES studio SOURCES_PREFIX studio SOURCES + studioquickutils.cpp studioquickutils.h studiostyle.cpp studiostyle.h studiostyle_p.cpp studiostyle_p.h studioquickwidget.cpp studioquickwidget.h diff --git a/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp b/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp index ec3b47063a2..626fa9f17df 100644 --- a/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp +++ b/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp @@ -8,6 +8,8 @@ #include "studio/studiostyle.h" #include +#include +#include #include #include @@ -89,6 +91,9 @@ bool QmlDesignerBasePlugin::initialize(const QStringList &arguments, QString *) if (arguments.contains("-qml-lite-designer")) enbableLiteMode(); + WindowManager::registerDeclarativeType(); + StudioQuickUtils::registerDeclarativeType(); + d = std::make_unique(); if (Core::ICore::settings()->value("QML/Designer/StandAloneMode", false).toBool()) d->studioConfigSettingsPage = std::make_unique(); diff --git a/src/plugins/qmldesignerbase/studio/studioquickutils.cpp b/src/plugins/qmldesignerbase/studio/studioquickutils.cpp new file mode 100644 index 00000000000..11af253732d --- /dev/null +++ b/src/plugins/qmldesignerbase/studio/studioquickutils.cpp @@ -0,0 +1,31 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "studioquickutils.h" + +#include + +namespace QmlDesigner { + +StudioQuickUtils::StudioQuickUtils() +{ + m_locale = QLocale("DesignStudioLocale"); + m_locale.setNumberOptions(QLocale::OmitGroupSeparator); +} + +void StudioQuickUtils::registerDeclarativeType() +{ + qmlRegisterSingletonType( + "StudioQuickUtils", 1, 0, "Utils", [](QQmlEngine *, QJSEngine *) { + return new StudioQuickUtils(); + }); +} + +const QLocale &StudioQuickUtils::locale() const +{ + return m_locale; +} + +StudioQuickUtils::~StudioQuickUtils() {} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesignerbase/studio/studioquickutils.h b/src/plugins/qmldesignerbase/studio/studioquickutils.h new file mode 100644 index 00000000000..b7f298cebf1 --- /dev/null +++ b/src/plugins/qmldesignerbase/studio/studioquickutils.h @@ -0,0 +1,39 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "../qmldesignerbase_global.h" + +#include + +#include + +namespace QmlDesigner { + +class QMLDESIGNERBASE_EXPORT StudioQuickUtils : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QLocale locale READ locale NOTIFY localeChanged) + +public: + ~StudioQuickUtils(); + + StudioQuickUtils(const StudioQuickUtils &) = delete; + void operator=(const StudioQuickUtils &) = delete; + + static void registerDeclarativeType(); + + const QLocale &locale() const; + +signals: + void localeChanged(); + +private: + StudioQuickUtils(); + + QLocale m_locale; +}; + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesignerbase/utils/windowmanager.cpp b/src/plugins/qmldesignerbase/utils/windowmanager.cpp index aa0b0772f9e..e00a19fb6d9 100644 --- a/src/plugins/qmldesignerbase/utils/windowmanager.cpp +++ b/src/plugins/qmldesignerbase/utils/windowmanager.cpp @@ -11,9 +11,7 @@ #include #include -namespace QmlDesignerBase { - -QPointer WindowManager::m_instance = nullptr; +namespace QmlDesigner { WindowManager::WindowManager() { @@ -56,4 +54,4 @@ QRect WindowManager::getScreenGeometry(QPoint point) return screen->geometry(); } -} // namespace QmlDesignerBase +} // namespace QmlDesigner diff --git a/src/plugins/qmldesignerbase/utils/windowmanager.h b/src/plugins/qmldesignerbase/utils/windowmanager.h index 87a0b701463..01444ce43dc 100644 --- a/src/plugins/qmldesignerbase/utils/windowmanager.h +++ b/src/plugins/qmldesignerbase/utils/windowmanager.h @@ -10,7 +10,7 @@ QT_FORWARD_DECLARE_CLASS(QWindow) -namespace QmlDesignerBase { +namespace QmlDesigner { class QMLDESIGNERBASE_EXPORT WindowManager : public QObject { @@ -34,8 +34,6 @@ signals: private: WindowManager(); - - static QPointer m_instance; }; -} // namespace QmlDesignerBase +} // namespace QmlDesigner From db5acbb381ef6a61d7b4605268e5b427ab6078e3 Mon Sep 17 00:00:00 2001 From: Shrief Gabr Date: Fri, 9 Aug 2024 17:02:48 +0300 Subject: [PATCH 137/193] QmlDesigner: Enable Telemetry simple settings page from qmlDesignerPlugin Change-Id: I7939cb8985c2ee0dfe9bd7dfa7fe08ce78f4ac62 Reviewed-by: Tim Jenssen --- src/plugins/qmldesigner/qmldesignerplugin.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index a158ba43098..d9a510769cd 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -324,6 +324,14 @@ bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *e if (Core::ICore::isQtDesignStudio()) { d->toolBar = ToolBar::create(); d->statusBar = ToolBar::createStatusBar(); + + // uses simplified Telemetry settings page in case of Qt Design Studio + ExtensionSystem::PluginSpec *usageStatistic = Utils::findOrDefault(ExtensionSystem::PluginManager::plugins(), [](ExtensionSystem::PluginSpec *p) { + return p->name() == "UsageStatistic"; + }); + + if (usageStatistic && usageStatistic->plugin()) + QMetaObject::invokeMethod(usageStatistic->plugin(), "useSimpleUi", true); } return true; From 02ed7f77f77fe5690143188767d0ead1be8bdf48 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Mon, 9 Sep 2024 15:59:35 +0300 Subject: [PATCH 138/193] QmlDesigner: Handle absolute and web urls when exporting a bundle Properly handle absolute paths: added to the root of the exported bundle. Skip web urls for now (they are not working for textures anyway) Change-Id: I4bb9e8bfbe28bd2a11b36ca1e1dae876dc9bce22 Reviewed-by: Miikka Heikkinen --- .../components/componentcore/bundlehelper.cpp | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp b/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp index c49e4746bf1..cd1f84c62ea 100644 --- a/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp +++ b/src/plugins/qmldesigner/components/componentcore/bundlehelper.cpp @@ -660,9 +660,24 @@ QSet BundleHelper::getComponentDependencies(const Utils::FilePath &fi if (std::string_view{pValue.typeName()} == "QUrl") { QString pValueStr = pValue.toString(); if (!pValueStr.isEmpty() && !pValueStr.startsWith("#")) { - Utils::FilePath assetPath = filePath.parentDir().resolvePath(pValueStr); - Utils::FilePath assetPathRelative = assetPath.relativePathFrom(mainCompDir); - depList.insert({mainCompDir, assetPathRelative.toFSPathString()}); + Utils::FilePath pValuePath = Utils::FilePath::fromString(pValueStr); + Utils::FilePath assetPathBase; + QString assetPathRelative; + + if (!pValuePath.toUrl().isLocalFile() || pValuePath.startsWith("www.")) { + qWarning() << "BundleHelper::getComponentDependencies(): Web urls are not" + " supported. Skipping " << pValuePath; + continue; + } else if (pValuePath.isAbsolutePath()) { + assetPathRelative = pValuePath.fileName(); + assetPathBase = pValuePath.parentDir(); + } else { + Utils::FilePath assetPath = filePath.parentDir().resolvePath(pValueStr); + assetPathRelative = assetPath.relativePathFrom(mainCompDir).toFSPathString(); + assetPathBase = mainCompDir; + } + + depList.insert({assetPathBase, assetPathRelative}); } } } From 7d7e3807c2c1db7784d2dbf56b7c7e32ed809691 Mon Sep 17 00:00:00 2001 From: Teea Poldsam Date: Thu, 20 Jun 2024 10:00:48 +0300 Subject: [PATCH 139/193] Doc: Document the effect composer example Task-number: QDS-13028 Change-Id: Ib6c34a6ffe9c815e89ca030b2020983fa15791bd Reviewed-by: Mats Honkamaa --- .../examples/doc/effectComposerExample.qdoc | 74 ++++++++++++++++++ .../images/effect-composer-example.webp | Bin 0 -> 17222 bytes 2 files changed, 74 insertions(+) create mode 100644 doc/qtdesignstudio/examples/doc/effectComposerExample.qdoc create mode 100644 doc/qtdesignstudio/images/effect-composer-example.webp diff --git a/doc/qtdesignstudio/examples/doc/effectComposerExample.qdoc b/doc/qtdesignstudio/examples/doc/effectComposerExample.qdoc new file mode 100644 index 00000000000..d8e347b898f --- /dev/null +++ b/doc/qtdesignstudio/examples/doc/effectComposerExample.qdoc @@ -0,0 +1,74 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \page effect-composer-example.html + \ingroup studioexamples + + \title Effect Composer Example + \brief Illustrates how to work with the Effect Composer effects. + + \image effect-composer-example.webp {The Effect Composer example project} + + The \e {Effect Composer Example} illustrates how to work with the \uicontrol {Effect Composer} + effects. Use the example project to experiment with effects and get familiar with + \uicontrol {Effect Composer}. To learn more, see \l {Effect Composer}. + + The example consists of a 3D model and four \uicontrol {Effect Composer} effects. You can show + and hide the effects from the scene with buttons. To modify the effect properties, select an + effect and then use the sliders. To visualize the effects better, rotate the 3D model by + dragging it and zoom it with the mouse wheel. + + The example project has a scalable design. When you resize the window to fit your screen, some + components will adjust automatically. + + \section1 Running the Example + + To run the example in \QDS, go to the \uicontrol Welcome screen and select the example + from the \uicontrol Examples tab. + + \section1 The Effects + + The following table introduces the effects in this example. + + \table + \header + \li Effect Name + \li Description + \row + \li \uicontrol {Displace} + \li A displace effect, the pixels move according to a displacement map. + \row + \li \uicontrol {Glow} and \uicontrol {Swirl} + \li A combination of two effects, a soft glowing effect and a swirl distortion effect. + \row + \li \uicontrol {Noise} + \li An animated effect with RGB noise. + \row + \li \uicontrol {Rain} and \uicontrol {Thunder} + \li A weather effect, a combination of a rain effect and a thunder effect. + \endtable + + \section1 The Structure of the Example + + In addition to the effects, the example project also includes the following components: + + \list + \li A \l {3D} scene + \list + \li \l {Importing 3D Assets}{A 3D model} + \li \l {Lights}{A directional light} + \li \l {Cameras}{A scene camera} + \li \l {OrbitCameraController} + \endlist + \li \l {Text} components + \li \l {Rectangle} components + \li \l {Shapes#Border}{Border} components + \li \l {Creating Buttons}{Custom Buttons} + \li \l {Creating Custom Components}{Custom Sliders} + \endlist + + The example project also uses \uicontrol States and \uicontrol Transitions. To learn more, see + \l {Working with States} and \l {Transitions}. + +*/ diff --git a/doc/qtdesignstudio/images/effect-composer-example.webp b/doc/qtdesignstudio/images/effect-composer-example.webp new file mode 100644 index 0000000000000000000000000000000000000000..faeab3e9ef05d3e9ccc9d6acd576f378dc987648 GIT binary patch literal 17222 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%0D$+br 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 literal 0 HcmV?d00001 From 269694eb102ea4d6e2c65b0dace6ee7b1a7acd0a Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 5 Sep 2024 17:04:11 +0200 Subject: [PATCH 140/193] QmlJSCheck: Do not allow object in when condition This is syntactically correct and can be hard to spot, but is not valid QtQuick. Task-number: QDS-13452 Change-Id: I010e44e33147c97edbd992c3452ba1c086fb42cb Reviewed-by: Marco Bubke Reviewed-by: Ulf Hermann --- src/libs/qmljs/qmljscheck.cpp | 7 +++++++ src/libs/qmljs/qmljsstaticanalysismessage.cpp | 1 + src/libs/qmljs/qmljsstaticanalysismessage.h | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp index c97fc10c55b..53796d0acdd 100644 --- a/src/libs/qmljs/qmljscheck.cpp +++ b/src/libs/qmljs/qmljscheck.cpp @@ -953,6 +953,13 @@ bool Check::visit(UiObjectBinding *ast) //addMessage(ErrBehavioursNotSupportedInQmlUi, locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation())); } + if (!m_typeStack.isEmpty() && m_typeStack.last() == "State" + && toString(ast->qualifiedId) == "when") { + addMessage( + ErrWhenConditionCannotBeObject, + locationFromRange(ast->firstSourceLocation(), ast->lastSourceLocation())); + } + visitQmlObject(ast, ast->qualifiedTypeNameId, ast->initializer); return false; } diff --git a/src/libs/qmljs/qmljsstaticanalysismessage.cpp b/src/libs/qmljs/qmljsstaticanalysismessage.cpp index a58bf43765b..fc4579245db 100644 --- a/src/libs/qmljs/qmljsstaticanalysismessage.cpp +++ b/src/libs/qmljs/qmljsstaticanalysismessage.cpp @@ -238,6 +238,7 @@ StaticAnalysisMessages::StaticAnalysisMessages() Tr::tr("Do not reference the root item as alias.")); newMsg(WarnAliasReferRootHierarchy, Warning, Tr::tr("Avoid referencing the root item in a hierarchy.")); + newMsg(ErrWhenConditionCannotBeObject, Error, Tr::tr("When condtion cannot contain an object.")); } } // anonymous namespace diff --git a/src/libs/qmljs/qmljsstaticanalysismessage.h b/src/libs/qmljs/qmljsstaticanalysismessage.h index 97dd95c5eb9..b26eab2bd25 100644 --- a/src/libs/qmljs/qmljsstaticanalysismessage.h +++ b/src/libs/qmljs/qmljsstaticanalysismessage.h @@ -113,7 +113,8 @@ enum Type { WarnComponentRequiresChildren = 327, WarnDuplicateImport = 400, ErrAliasReferRoot = 401, - WarnAliasReferRootHierarchy = 402 + WarnAliasReferRootHierarchy = 402, + ErrWhenConditionCannotBeObject = 403, }; class QMLJS_EXPORT PrototypeMessageData { From cce0bf2a657334b654568fef31c5d09774210fbb Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 5 Sep 2024 16:13:03 +0200 Subject: [PATCH 141/193] QmlDesigner: Do not open another QML file in fake project mode If a fake project is is opened the user has already opened the "correct" .ui.qml file. We do not have to open another one. Change-Id: Ib7e838118a9162cdc7b7aba05c51a9271503a103 Reviewed-by: Burak Hancerli Reviewed-by: Thomas Hartmann --- src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp index 0813e1dd03d..5a64c8b7de0 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp @@ -380,6 +380,9 @@ Utils::FilePath QmlBuildSystem::getStartupQmlFileWithFallback() const if (!target()) return {}; + if (projectFilePath().endsWith(Constants::fakeProjectName)) + return {}; + const auto getFirstFittingFile = [](const Utils::FilePaths &files) -> Utils::FilePath { for (const auto &file : files) { if (file.exists()) From 318c6ceda3b0029a3deac56105879940220234ab Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 10 Sep 2024 16:01:23 +0200 Subject: [PATCH 142/193] QmlDesigner: Bump version in wizard Change-Id: If2e051705f2f18ac0fea2dc191e020f000b2ce1e Reviewed-by: Knud Dollereder --- .../studio_templates/projects/common/app.qmlproject.tpl | 2 +- .../qmlprojectexporter/templates/qmlcomponents.tpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl index dd2d4fb5efa..58afba69c34 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl @@ -103,7 +103,7 @@ Project { /* Required for deployment */ targetDirectory: "/opt/%{ProjectName}" - qdsVersion: "4.5" + qdsVersion: "4.6" quickVersion: "%{QtQuickVersion}" diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/qmlcomponents.tpl b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/qmlcomponents.tpl index 0308c2ab745..cf1d159a7e1 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/qmlcomponents.tpl +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/qmlcomponents.tpl @@ -9,7 +9,7 @@ set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml") include(FetchContent) FetchContent_Declare( ds - GIT_TAG qds-4.5 + GIT_TAG qds-4.6 GIT_REPOSITORY https://code.qt.io/qt-labs/qtquickdesigner-components.git ) From 7d5cf6e3e0c2207f8fba3381fcda348f2f3f6b66 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 29 Aug 2024 15:49:40 +0200 Subject: [PATCH 143/193] QmlDesigner: Use AppLocalDataLocation for source_path.db Change-Id: I3ff160cea5dead12c1fbf28eb156d50097ca51f5 Reviewed-by: Thomas Hartmann --- .../qmldesigner/qmldesignerprojectmanager.cpp | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp index f46e6ba9d63..6bba6c12369 100644 --- a/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp +++ b/src/plugins/qmldesigner/qmldesignerprojectmanager.cpp @@ -45,6 +45,7 @@ #include #include #include +#include using namespace std::chrono; using namespace std::chrono_literals; @@ -215,6 +216,21 @@ std::unique_ptr createProjectStorageData(::ProjectExplorer:: return {}; } } + +Utils::PathString createDatabasePath(std::string_view name) +{ + auto directory = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation); + + QDir{}.mkpath(directory); + + Utils::PathString path = directory; + + path.append('/'); + path.append(name); + + return path; +} + } // namespace class QmlDesignerProjectManager::QmlDesignerProjectManagerProjectData @@ -244,21 +260,16 @@ public: class QmlDesignerProjectManager::Data { public: - Data(ExternalDependenciesInterface &externalDependencies) - : sourcePathDatabase{externalDependencies.userResourcePath(u"source_path.db"), - Sqlite::JournalMode::Wal, - Sqlite::LockingMode::Normal} - {} - -public: - Sqlite::Database sourcePathDatabase; + Sqlite::Database sourcePathDatabase{createDatabasePath("source_path.db"), + Sqlite::JournalMode::Wal, + Sqlite::LockingMode::Normal}; QmlDesigner::SourcePathStorage sourcePathStorage{sourcePathDatabase, sourcePathDatabase.isInitialized()}; PathCacheType pathCache{sourcePathStorage}; }; QmlDesignerProjectManager::QmlDesignerProjectManager(ExternalDependenciesInterface &externalDependencies) - : m_data{std::make_unique(externalDependencies)} + : m_data{std::make_unique()} , m_previewImageCacheData{std::make_unique(externalDependencies)} , m_externalDependencies{externalDependencies} { From ebd03070f0679902c387fc36c5e3c83a63efb773 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 29 Aug 2024 18:05:39 +0200 Subject: [PATCH 144/193] QmlDesigner: Simplify transforms Use function pointer to avoid boilerplate code. Use ranges where it has advantages. Change-Id: I01059a1c92fc919bbd73caf5ecea9efa0fe91a76 Reviewed-by: Miikka Heikkinen Reviewed-by: Thomas Hartmann --- .../assetslibrary/assetslibrarywidget.cpp | 12 +++---- .../componentcore/designeractionmanager.cpp | 4 +-- .../componentcore/modelnodeoperations.cpp | 4 +-- .../propertycomponentgenerator.cpp | 3 +- .../connectioneditor/connectionmodel.cpp | 4 +-- .../connectioneditor/propertytreemodel.cpp | 16 +++------ .../contentlibrary/contentlibrarytexture.cpp | 4 +-- .../contentlibrary/contentlibraryview.cpp | 4 +-- .../components/edit3d/edit3dviewconfig.h | 4 +-- .../components/edit3d/edit3dwidget.cpp | 2 +- .../components/formeditor/formeditoritem.cpp | 14 ++++---- .../components/formeditor/formeditorscene.cpp | 23 +++++++------ .../materialbrowser/materialbrowserwidget.cpp | 2 +- .../materialeditorcontextobject.cpp | 2 +- .../navigator/navigatortreemodel.cpp | 5 ++- .../gradientpresetcustomlistmodel.cpp | 6 ++-- .../propertyeditorcontextobject.cpp | 3 +- .../propertyeditorqmlbackend.cpp | 6 ++-- .../propertyeditor/propertyeditorutils.cpp | 6 ++-- .../propertyeditor/propertyeditorutils.h | 2 +- .../propertyeditor/propertyeditorvalue.cpp | 4 +-- .../propertyeditor/qmlmodelnodeproxy.cpp | 2 +- .../stateseditor/stateseditormodel.cpp | 2 +- .../components/toolbar/toolbarbackend.cpp | 2 +- .../designercore/include/itemlibraryentry.h | 3 +- .../libs/designercore/include/nodemetainfo.h | 11 ++++++ .../designercore/include/propertymetainfo.h | 11 ++++++ .../metainfo/itemlibraryentry.cpp | 11 +++--- .../designercore/metainfo/nodemetainfo.cpp | 34 ++++++------------- .../libs/designercore/model/internalnode.cpp | 12 +++---- .../libs/designercore/model/model.cpp | 11 +++--- .../projectstoragepathwatcher.h | 2 +- .../projectstorage/projectstorageupdater.cpp | 3 +- .../designercore/rewriter/rewriterview.cpp | 6 ++-- .../libs/qmldesignerutils/designeralgorithm.h | 15 ++++++++ .../qmldesigner/qmltools/qmlitemnode.cpp | 23 ++++++++----- .../qmldesigner/qmltools/qmlitemnode.h | 2 ++ 37 files changed, 142 insertions(+), 138 deletions(-) diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp index e233c9a7425..50dbbc878e1 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp @@ -70,9 +70,7 @@ bool AssetsLibraryWidget::eventFilter(QObject *obj, QEvent *event) auto mimeData = std::make_unique(); mimeData->setData(Constants::MIME_TYPE_ASSETS, m_assetsToDrag.join(',').toUtf8()); - QList urlsToDrag = Utils::transform(m_assetsToDrag, [](const QString &path) { - return QUrl::fromLocalFile(path); - }); + QList urlsToDrag = Utils::transform(m_assetsToDrag, &QUrl::fromLocalFile); QString draggedAsset = m_assetsToDrag[0]; @@ -462,10 +460,10 @@ void AssetsLibraryWidget::handleExtFilesDrop(const QList &simpleFilePaths, const QList &complexFilePaths, const QString &targetDirPath) { - auto toLocalFile = [](const QUrl &url) { return url.toLocalFile(); }; - - QStringList simpleFilePathStrings = Utils::transform(simpleFilePaths, toLocalFile); - QStringList complexFilePathStrings = Utils::transform(complexFilePaths, toLocalFile); + QStringList simpleFilePathStrings = Utils::transform(simpleFilePaths, + &QUrl::toLocalFile); + QStringList complexFilePathStrings = Utils::transform(complexFilePaths, + &QUrl::toLocalFile); if (!simpleFilePathStrings.isEmpty()) { if (targetDirPath.isEmpty()) { diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index 9b9b7f75a91..28eda391acb 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -2178,9 +2178,7 @@ QList > DesignerActionManager::actionsForTargetV QList DesignerActionManager::designerActions() const { - return Utils::transform(m_designerActions, [](const QSharedPointer &pointer) { - return pointer.data(); - }); + return Utils::transform(m_designerActions, &QSharedPointer::get); } ActionInterface *DesignerActionManager::actionByMenuId(const QByteArray &id) diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index c17926b9283..db23abc4697 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -553,9 +553,7 @@ void layoutGridLayout(const SelectionContext &selectionContext) static PropertyNameList sortedPropertyNameList(const PropertyMetaInfos &properties) { - auto propertyNames = Utils::transform(properties, [](const auto &property) { - return property.name(); - }); + auto propertyNames = Utils::transform(properties, &PropertyMetaInfo::name); std::sort(propertyNames.begin(), propertyNames.end()); diff --git a/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp b/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp index 3e28e217479..1b9e7c409e2 100644 --- a/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp +++ b/src/plugins/qmldesigner/components/componentcore/propertycomponentgenerator.cpp @@ -227,8 +227,7 @@ std::tuple createEntries( QStringList createImports(QmlJS::SimpleReaderNode *templateConfiguration) { auto property = templateConfiguration->property("imports"); - return Utils::transform(property.value.toList(), - [](const auto &entry) { return entry.toString(); }); + return Utils::transform(property.value.toList(), &QVariant::toString); } } // namespace diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp index e9a6d96c247..5d94ca85867 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp @@ -1568,14 +1568,14 @@ void ConnectionModelStatementDelegate::setupChangeState() && !item.allStateNames().isEmpty(); }); - QStringList itemIds = Utils::transform(items, [](const ModelNode &node) { return node.id(); }); + QStringList itemIds = Utils::transform(items, &ModelNode::id); const auto groups = m_model->connectionView()->allModelNodesOfType( model->qtQuickStateGroupMetaInfo()); const auto rootId = m_model->connectionView()->rootModelNode().id(); itemIds.removeAll(rootId); - QStringList groupIds = Utils::transform(groups, [](const ModelNode &node) { return node.id(); }); + QStringList groupIds = Utils::transform(groups, &ModelNode::id); Utils::sort(itemIds); Utils::sort(groupIds); diff --git a/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.cpp index d9d4e04eac7..463286e6956 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/propertytreemodel.cpp @@ -520,8 +520,8 @@ const std::vector PropertyTreeModel::getDynamicProperties( const ModelNode &modelNode) const { auto dynamicProperties = modelNode.dynamicProperties(); - auto dynamicPropertyNames = Utils::transform( - dynamicProperties, [](const AbstractProperty &property) { return property.name(); }); + auto dynamicPropertyNames = Utils::transform(dynamicProperties, + &AbstractProperty::name); auto filtered = Utils::filtered(dynamicPropertyNames, [this, modelNode](PropertyNameView propertyName) { TypeName propertyType = modelNode.property(propertyName).dynamicTypeName(); @@ -546,9 +546,7 @@ const std::vector PropertyTreeModel::getDynamicProperties( auto sorted = Utils::sorted(filtered); - return Utils::transform>(sorted, [](PropertyNameView propertyName) { - return propertyName.toByteArray(); - }); + return Utils::transform>(sorted, &PropertyNameView::toByteArray); } const std::vector PropertyTreeModel::getDynamicSignals(const ModelNode &modelNode) const @@ -581,10 +579,7 @@ const std::vector PropertyTreeModel::sortedAndFilteredPropertyName return filterProperty(name, metaInfo, recursive); }); - auto sorted = Utils::sorted( - Utils::transform(filtered, [](const PropertyMetaInfo &metaInfo) -> PropertyName { - return metaInfo.name(); - })); + auto sorted = Utils::sorted(Utils::transform(filtered, &PropertyMetaInfo::name)); std::set set(std::make_move_iterator(sorted.begin()), std::make_move_iterator(sorted.end())); @@ -909,8 +904,7 @@ void PropertyTreeModelDelegate::setPropertyType(PropertyTreeModel::PropertyTypes void PropertyTreeModelDelegate::setup(const QString &id, const QString &name, bool *nameExists) { m_model.resetModel(); - QStringList idLists = Utils::transform(m_model.nodeList(), - [](const ModelNode &node) { return node.id(); }); + QStringList idLists = Utils::transform(m_model.nodeList(), &ModelNode::id); if (!idLists.contains(id)) idLists.prepend(id); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.cpp index 90ab7698a77..602ac021aca 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibrarytexture.cpp @@ -65,9 +65,7 @@ QString ContentLibraryTexture::resolveSuffix() if (textureFiles.size() > 1) { qWarning() << "Found multiple textures with the same name in the same directories: " - << Utils::transform(textureFiles, [](const QFileInfo &fi) { - return fi.fileName(); - }); + << Utils::transform(textureFiles, &QFileInfo::fileName); } return '.' + textureFiles.at(0).completeSuffix(); diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index 16f550e9385..44c70ce8ece 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -500,9 +500,7 @@ void ContentLibraryView::addLibAssets(const QStringList &paths) QStringList fileNamesToRemove; const QStringList existingAssetsFileNames = Utils::transform(bundlePath.dirEntries(QDir::Files), - [](const Utils::FilePath &path) { - return path.fileName(); - }); + &Utils::FilePath::fileName); for (const QString &path : paths) { auto assetFilePath = Utils::FilePath::fromString(path); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dviewconfig.h b/src/plugins/qmldesigner/components/edit3d/edit3dviewconfig.h index 1e53768957b..41e26f6e139 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dviewconfig.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dviewconfig.h @@ -35,9 +35,7 @@ public: auto colorNameList = var.value(); - return Utils::transform(colorNameList, [](const QString &colorName) { - return QColor{colorName}; - }); + return Utils::transform(colorNameList, &QColor::fromString); } static QVariant load(const QByteArray &key, const QVariant &defaultValue = {}) diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index 43ba5db6686..8b28e4b55de 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -805,7 +805,7 @@ void Edit3DWidget::dropEvent(QDropEvent *dropEvent) auto moduleId = model->module(import3dTypePrefix, Storage::ModuleKind::QmlLibrary); auto metaInfo = model->metaInfo(moduleId, fileName.toUtf8()); if (auto entries = metaInfo.itemLibrariesEntries(); entries.size()) { - auto entry = ItemLibraryEntry(entries.front()); + auto entry = ItemLibraryEntry::create(entries.front()); QmlVisualNode::createQml3DNode(view(), entry, m_canvas->activeScene(), {}, false); } } diff --git a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp index e8f8846466b..35f52c86eda 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditoritem.cpp @@ -826,20 +826,18 @@ public: { if (node.modelNode().hasBindingProperty("from")) { if (node.modelNode().bindingProperty("from").isList()) - from = Utils::transform(node.modelNode().bindingProperty("from").resolveToModelNodeList(), - [](const ModelNode &node) { - return QmlItemNode(node); - }); + from = Utils::transform( + node.modelNode().bindingProperty("from").resolveToModelNodeList(), + &QmlItemNode::create); else from = QList({node.modelNode().bindingProperty("from").resolveToModelNode()}); } if (node.modelNode().hasBindingProperty("to")) { if (node.modelNode().bindingProperty("to").isList()) - to = Utils::transform(node.modelNode().bindingProperty("to").resolveToModelNodeList(), - [](const ModelNode &node) { - return QmlItemNode(node); - }); + to = Utils::transform( + node.modelNode().bindingProperty("to").resolveToModelNodeList(), + &QmlItemNode::create); else to = QList({node.modelNode().bindingProperty("to").resolveToModelNode()}); } diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp index 24522f41453..198ba819fcc 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp @@ -2,13 +2,14 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "formeditorscene.h" +#include "formeditoritem.h" #include "formeditorview.h" #include "formeditorwidget.h" -#include "formeditoritem.h" +#include +#include #include #include #include -#include #include @@ -83,9 +84,9 @@ double FormEditorScene::canvasHeight() const QList FormEditorScene::itemsForQmlItemNodes(const QList &nodeList) const { - return Utils::filtered(Utils::transform(nodeList, [this](const QmlItemNode &qmlItemNode) { - return itemForQmlItemNode(qmlItemNode); - }), [] (FormEditorItem* item) { return item; }); + return CoreUtils::to( + nodeList | std::views::transform(std::bind_front(&FormEditorScene::itemForQmlItemNode, this)) + | std::views::filter(std::identity{})); } QList FormEditorScene::allFormEditorItems() const @@ -395,15 +396,15 @@ FormEditorItem* FormEditorScene::rootFormEditorItem() const void FormEditorScene::clearFormEditorItems() { - const QList itemList(items()); + const QList itemList(items()); - const QList formEditorItemsTransformed = - Utils::transform(itemList, [](QGraphicsItem *item) { return qgraphicsitem_cast(item); }); + auto cast = [](QGraphicsItem *item) { return qgraphicsitem_cast(item); }; + + auto formEditorItems = itemList | std::views::transform(cast) + | std::views::filter(std::identity{}); - const QList formEditorItems = Utils::filtered(formEditorItemsTransformed, - [](FormEditorItem *item) { return item; }); for (FormEditorItem *item : formEditorItems) - item->setParentItem(nullptr); + item->setParentItem(nullptr); for (FormEditorItem *item : formEditorItems) delete item; diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp index bb22c9b5959..a97bf591459 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp @@ -318,7 +318,7 @@ void MaterialBrowserWidget::acceptBundleTextureDropOnMaterial(int matIndex, cons void MaterialBrowserWidget::acceptAssetsDrop(const QList &urls) { - QStringList assetPaths = Utils::transform(urls, [](const QUrl &url) { return url.toLocalFile(); }); + QStringList assetPaths = Utils::transform(urls, &QUrl::toLocalFile); m_materialBrowserView->createTextures(assetPaths); if (m_materialBrowserView->model()) m_materialBrowserView->model()->endDrag(); diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp index dca37a1f895..a27924532dd 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorcontextobject.cpp @@ -89,7 +89,7 @@ void MaterialEditorContextObject::changeTypeName(const QString &typeName) // Create a list of properties available for the new type PropertyNameList propertiesAndSignals = Utils::transform( - metaInfo.properties(), [](const auto &property) { return property.name(); }); + metaInfo.properties(), &PropertyMetaInfo::name); // Add signals to the list const PropertyNameList signalNames = metaInfo.signalNames(); for (const PropertyName &signal : signalNames) { diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index 1e71f1efbd4..c197f244b42 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -974,9 +974,8 @@ static QList collectParents(const QList &modelNodes) QList NavigatorTreeModel::nodesToPersistentIndex(const QList &modelNodes) { - return ::Utils::transform(modelNodes, [this](const ModelNode &modelNode) { - return QPersistentModelIndex(indexForModelNode(modelNode)); - }); + return ::Utils::transform>( + modelNodes, std::bind_front(&NavigatorTreeModel::indexForModelNode, this)); } void NavigatorTreeModel::notifyModelNodesRemoved(const QList &modelNodes) diff --git a/src/plugins/qmldesigner/components/propertyeditor/gradientpresetcustomlistmodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetcustomlistmodel.cpp index 238e45ac789..bb019ffd6ee 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/gradientpresetcustomlistmodel.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/gradientpresetcustomlistmodel.cpp @@ -54,10 +54,8 @@ QString GradientPresetCustomListModel::getFilename() void GradientPresetCustomListModel::storePresets(const QString &filename, const QList &items) { - const QList presets - = Utils::transform>(items, [](const GradientPresetItem &item) { - return QVariant::fromValue(item); - }); + const QList presets = Utils::transform>( + items, [](const GradientPresetItem &item) { return QVariant::fromValue(item); }); QSettings settings(filename, QSettings::IniFormat); settings.clear(); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp index 48135109c11..4202beb19bd 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp @@ -208,8 +208,7 @@ void PropertyEditorContextObject::changeTypeName(const QString &typeName) // Create a list of properties available for the new type auto propertiesAndSignals = Utils::transform( - PropertyEditorUtils::filteredPropertes(metaInfo), - [](const auto &property) { return property.name(); }); + PropertyEditorUtils::filteredProperties(metaInfo), &PropertyMetaInfo::name); // Add signals to the list for (const auto &signal : metaInfo.signalNames()) { if (signal.isEmpty()) diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp index 0c28e5503df..63471bb4bf9 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp @@ -464,7 +464,7 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q if (propertyEditorBenchmark().isInfoEnabled()) time.start(); - for (const auto &property : PropertyEditorUtils::filteredPropertes(qmlObjectNode.metaInfo())) { + for (const auto &property : PropertyEditorUtils::filteredProperties(qmlObjectNode.metaInfo())) { auto propertyName = property.name(); createPropertyEditorValue(qmlObjectNode, propertyName, @@ -574,7 +574,7 @@ void PropertyEditorQmlBackend::initialSetup(const TypeName &typeName, const QUrl { NodeMetaInfo metaInfo = propertyEditor->model()->metaInfo(typeName); - for (const auto &property : PropertyEditorUtils::filteredPropertes(metaInfo)) { + for (const auto &property : PropertyEditorUtils::filteredProperties(metaInfo)) { setupPropertyEditorValue(property.name(), propertyEditor, property.propertyType()); } @@ -695,7 +695,7 @@ QString PropertyEditorQmlBackend::templateGeneration(const NodeMetaInfo &metaTyp PropertyMetaInfos separateSectionProperties; // Iterate over all properties and isolate the properties which have their own template - for (const auto &property : PropertyEditorUtils::filteredPropertes(metaType)) { + for (const auto &property : PropertyEditorUtils::filteredProperties(metaType)) { const auto &propertyName = property.name(); if (propertyName.startsWith("__")) continue; // private API diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorutils.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorutils.cpp index 3af4c1abe83..b26e98da13d 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorutils.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorutils.cpp @@ -29,14 +29,12 @@ static bool checkIfUnkownTypeProperty(const std::vector &propertyN #endif //QDS_USE_PROJECTSTORAGE -PropertyMetaInfos filteredPropertes(const NodeMetaInfo &metaInfo) +PropertyMetaInfos filteredProperties(const NodeMetaInfo &metaInfo) { auto properties = metaInfo.properties(); #ifndef QDS_USE_PROJECTSTORAGE - std::vector names = Utils::transform(properties, [](const PropertyMetaInfo &info) { - return info.name(); - }); + std::vector names = Utils::transform(properties, &PropertyMetaInfo::name); std::vector itemProperties; diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorutils.h b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorutils.h index 2d675d37ba2..d9c9a2fd2aa 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorutils.h +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorutils.h @@ -9,7 +9,7 @@ namespace QmlDesigner { namespace PropertyEditorUtils { -PropertyMetaInfos filteredPropertes(const NodeMetaInfo &metaInfo); +PropertyMetaInfos filteredProperties(const NodeMetaInfo &metaInfo); } // End namespace PropertyEditorUtils. diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp index bfc1a2a55b5..767d97be673 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorvalue.cpp @@ -716,7 +716,7 @@ void PropertyEditorNodeWrapper::setup() qDeleteAll(m_valuesPropertyMap.children()); if (QmlObjectNode qmlObjectNode = m_modelNode) { - const PropertyMetaInfos props = PropertyEditorUtils::filteredPropertes( + const PropertyMetaInfos props = PropertyEditorUtils::filteredProperties( m_modelNode.metaInfo()); for (const auto &property : props) { const auto &propertyName = property.name(); @@ -845,7 +845,7 @@ PropertyEditorSubSelectionWrapper::PropertyEditorSubSelectionWrapper(const Model QTC_ASSERT(qmlObjectNode.isValid(), return ); for (const auto &property : - PropertyEditorUtils::filteredPropertes(qmlObjectNode.modelNode().metaInfo())) { + PropertyEditorUtils::filteredProperties(qmlObjectNode.modelNode().metaInfo())) { auto propertyName = property.name(); createPropertyEditorValue(qmlObjectNode, propertyName, diff --git a/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp b/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp index 2799773c01e..76dc3c8a22e 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/qmlmodelnodeproxy.cpp @@ -93,7 +93,7 @@ QString QmlModelNodeProxy::simplifiedTypeName() const static QList toInternalIdList(const QList &nodes) { - return Utils::transform(nodes, [](const ModelNode &node) { return node.internalId(); }); + return Utils::transform(nodes, &ModelNode::internalId); } QList QmlModelNodeProxy::allChildren(int internalId) const diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp index afdeb95d3ad..df969197d9a 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditormodel.cpp @@ -277,7 +277,7 @@ QStringList StatesEditorModel::stateGroups() const const auto groupMetaInfo = m_statesEditorView->model()->qtQuickStateGroupMetaInfo(); auto stateGroups = Utils::transform(m_statesEditorView->allModelNodesOfType(groupMetaInfo), - [](const ModelNode &node) { return node.displayName(); }); + &ModelNode::displayName); stateGroups.prepend(tr("Default")); return stateGroups; } diff --git a/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp b/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp index 0a85e860bdd..1460eb00e95 100644 --- a/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp +++ b/src/plugins/qmldesigner/components/toolbar/toolbarbackend.cpp @@ -713,7 +713,7 @@ QStringList ToolBarBackend::kits() const /*&& kit->isAutoDetected() */; }); - return Utils::transform(kits, [](ProjectExplorer::Kit *kit) { return kit->displayName(); }); + return Utils::transform(kits, &ProjectExplorer::Kit::displayName); } int ToolBarBackend::currentKit() const diff --git a/src/plugins/qmldesigner/libs/designercore/include/itemlibraryentry.h b/src/plugins/qmldesigner/libs/designercore/include/itemlibraryentry.h index 2d0f2ef31e5..f3d5ebd437f 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/itemlibraryentry.h +++ b/src/plugins/qmldesigner/libs/designercore/include/itemlibraryentry.h @@ -46,9 +46,10 @@ public: ItemLibraryEntry &operator=(const ItemLibraryEntry &) = default; ItemLibraryEntry(ItemLibraryEntry &&) = default; ItemLibraryEntry &operator=(ItemLibraryEntry &&) = default; - explicit ItemLibraryEntry(const Storage::Info::ItemLibraryEntry &entry); ~ItemLibraryEntry(); + static ItemLibraryEntry create(const Storage::Info::ItemLibraryEntry &entry); + QString name() const; TypeName typeName() const; TypeId typeId() const; diff --git a/src/plugins/qmldesigner/libs/designercore/include/nodemetainfo.h b/src/plugins/qmldesigner/libs/designercore/include/nodemetainfo.h index ceb5fe8eff2..43c2eebb651 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/nodemetainfo.h +++ b/src/plugins/qmldesigner/libs/designercore/include/nodemetainfo.h @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -68,6 +69,16 @@ public: NodeMetaInfo &operator=(NodeMetaInfo &&); ~NodeMetaInfo(); + static NodeMetaInfo create(NotNullPointer projectStorage, TypeId typeId) + { + return {typeId, projectStorage}; + } + + static auto bind(NotNullPointer projectStorage) + { + return std::bind_front(&NodeMetaInfo::create, projectStorage); + } + bool isValid() const; explicit operator bool() const { return isValid(); } diff --git a/src/plugins/qmldesigner/libs/designercore/include/propertymetainfo.h b/src/plugins/qmldesigner/libs/designercore/include/propertymetainfo.h index 4221d5eb8d7..8784329854e 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/propertymetainfo.h +++ b/src/plugins/qmldesigner/libs/designercore/include/propertymetainfo.h @@ -42,6 +42,17 @@ public: PropertyMetaInfo &operator=(PropertyMetaInfo &&); ~PropertyMetaInfo(); + static PropertyMetaInfo create(NotNullPointer projectStorage, + PropertyDeclarationId id) + { + return {id, projectStorage}; + } + + static auto bind(NotNullPointer projectStorage) + { + return std::bind_front(&PropertyMetaInfo::create, projectStorage); + } + explicit operator bool() const { return isValid(); } bool isValid() const diff --git a/src/plugins/qmldesigner/libs/designercore/metainfo/itemlibraryentry.cpp b/src/plugins/qmldesigner/libs/designercore/metainfo/itemlibraryentry.cpp index 2aec7660026..745b46c91e3 100644 --- a/src/plugins/qmldesigner/libs/designercore/metainfo/itemlibraryentry.cpp +++ b/src/plugins/qmldesigner/libs/designercore/metainfo/itemlibraryentry.cpp @@ -64,9 +64,10 @@ ItemLibraryEntry::ItemLibraryEntry() : m_data(std::make_shared()) {} -ItemLibraryEntry::ItemLibraryEntry(const Storage::Info::ItemLibraryEntry &entry) - : ItemLibraryEntry{} +ItemLibraryEntry ItemLibraryEntry::create(const Storage::Info::ItemLibraryEntry &entry) { + ItemLibraryEntry itemLibraryEntry; + auto &m_data = itemLibraryEntry.m_data; m_data->name = entry.name.toQString(); m_data->typeId = entry.typeId; m_data->typeName = entry.typeName.toQByteArray(); @@ -85,6 +86,8 @@ ItemLibraryEntry::ItemLibraryEntry(const Storage::Info::ItemLibraryEntry &entry) m_data->extraFilePaths.reserve(Utils::ssize(entry.extraFilePaths)); for (const auto &extraFilePath : entry.extraFilePaths) m_data->extraFilePaths.emplace_back(extraFilePath.toQString()); + + return itemLibraryEntry; } ItemLibraryEntry::~ItemLibraryEntry() = default; @@ -303,9 +306,7 @@ QDebug operator<<(QDebug debug, const ItemLibraryEntry &itemLibraryEntry) QList toItemLibraryEntries(const Storage::Info::ItemLibraryEntries &entries) { - return Utils::transform>(entries, [&](const auto &entry) { - return ItemLibraryEntry{entry}; - }); + return Utils::transform>(entries, &ItemLibraryEntry::create); } } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/libs/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/libs/designercore/metainfo/nodemetainfo.cpp index 4971f1bb80a..d276f555337 100644 --- a/src/plugins/qmldesigner/libs/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/libs/designercore/metainfo/nodemetainfo.cpp @@ -1867,10 +1867,8 @@ PropertyMetaInfos NodeMetaInfo::properties() const using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"get properties"_t, category(), keyValue("type id", m_typeId)}; - return Utils::transform( - m_projectStorage->propertyDeclarationIds(m_typeId), [&](auto id) { - return PropertyMetaInfo{id, m_projectStorage}; - }); + return Utils::transform(m_projectStorage->propertyDeclarationIds(m_typeId), + PropertyMetaInfo::bind(m_projectStorage)); } else { const auto &properties = m_privateData->properties(); @@ -1894,10 +1892,9 @@ PropertyMetaInfos NodeMetaInfo::localProperties() const using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"get local properties"_t, category(), keyValue("type id", m_typeId)}; - return Utils::transform( - m_projectStorage->localPropertyDeclarationIds(m_typeId), [&](auto id) { - return PropertyMetaInfo{id, m_projectStorage}; - }); + return Utils::transform(m_projectStorage->localPropertyDeclarationIds( + m_typeId), + PropertyMetaInfo::bind(m_projectStorage)); } else { const auto &properties = m_privateData->localProperties(); @@ -1943,9 +1940,7 @@ PropertyNameList NodeMetaInfo::signalNames() const NanotraceHR::Tracer tracer{"get signal names"_t, category(), keyValue("type id", m_typeId)}; return Utils::transform(m_projectStorage->signalDeclarationNames(m_typeId), - [&](const auto &name) { - return name.toQByteArray(); - }); + &Utils::SmallString::toQByteArray); } else { return m_privateData->signalNames(); @@ -1961,9 +1956,7 @@ PropertyNameList NodeMetaInfo::slotNames() const using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"get slot names"_t, category(), keyValue("type id", m_typeId)}; return Utils::transform(m_projectStorage->functionDeclarationNames(m_typeId), - [&](const auto &name) { - return name.toQByteArray(); - }); + &Utils::SmallString::toQByteArray); } else { return m_privateData->slotNames(); } @@ -2038,9 +2031,7 @@ std::vector NodeMetaInfo::selfAndPrototypes() const keyValue("type id", m_typeId)}; return Utils::transform(m_projectStorage->prototypeAndSelfIds(m_typeId), - [&](TypeId typeId) { - return NodeMetaInfo{typeId, m_projectStorage}; - }); + NodeMetaInfo::bind(m_projectStorage)); } else { NodeMetaInfos hierarchy = {*this}; Model *model = m_privateData->model(); @@ -2066,9 +2057,7 @@ NodeMetaInfos NodeMetaInfo::prototypes() const using NanotraceHR::keyValue; NanotraceHR::Tracer tracer{"get prototypes"_t, category(), keyValue("type id", m_typeId)}; return Utils::transform(m_projectStorage->prototypeIds(m_typeId), - [&](TypeId typeId) { - return NodeMetaInfo{typeId, m_projectStorage}; - }); + NodeMetaInfo::bind(m_projectStorage)); } else { NodeMetaInfos hierarchy; @@ -4592,9 +4581,8 @@ NodeMetaInfo::NodeMetaInfos NodeMetaInfo::heirs() const { if constexpr (useProjectStorage()) { if (isValid()) { - return Utils::transform(m_projectStorage->heirIds(m_typeId), [&](TypeId typeId) { - return NodeMetaInfo{typeId, m_projectStorage}; - }); + return Utils::transform(m_projectStorage->heirIds(m_typeId), + NodeMetaInfo::bind(m_projectStorage)); } } diff --git a/src/plugins/qmldesigner/libs/designercore/model/internalnode.cpp b/src/plugins/qmldesigner/libs/designercore/model/internalnode.cpp index 04bbe5154d9..a601cc21605 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/internalnode.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/internalnode.cpp @@ -10,11 +10,13 @@ #include "internalsignalhandlerproperty.h" #include "internalvariantproperty.h" +#include #include #include #include +#include #include namespace QmlDesigner { @@ -109,17 +111,13 @@ AuxiliaryDatasForType InternalNode::auxiliaryData(AuxiliaryDataType type) const PropertyNameList InternalNode::propertyNameList() const { - return Utils::transform(m_nameProperties, [](const auto &entry) { - return entry.first.toQByteArray(); - }); + return CoreUtils::to(m_nameProperties | std::views::keys + | std::views::transform(&Utils::SmallString::toQByteArray)); } PropertyNameViews InternalNode::propertyNameViews() const { - return Utils::transform(m_nameProperties, - [](const auto &entry) -> PropertyNameView { - return entry.first; - }); + return CoreUtils::to(m_nameProperties | std::views::keys); } QList InternalNode::allSubNodes() const diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index fbe59c06460..58a2acdda59 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -33,6 +33,7 @@ #include "signalhandlerproperty.h" #include "variantproperty.h" +#include #include #include @@ -1416,8 +1417,9 @@ void ModelPrivate::setBindingProperties(const ModelResourceSet::SetExpressions & AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; auto bindingPropertiesWithExpressions = toInternalBindingProperties(setExpressions); - auto bindingProperties = Utils::transform(bindingPropertiesWithExpressions, - [](const auto &entry) { return std::get<0>(entry); }); + + auto bindingProperties = CoreUtils::to(bindingPropertiesWithExpressions | std::views::keys); + notifyBindingPropertiesAboutToBeChanged(bindingProperties); for (const auto &[bindingProperty, expression] : bindingPropertiesWithExpressions) bindingProperty->setExpression(expression); @@ -2728,10 +2730,9 @@ QVarLengthArray Model::metaInfosForModule(Module module) cons { if constexpr (useProjectStorage()) { using namespace Storage::Info; + return Utils::transform>( - d->projectStorage->typeIds(module.id()), [&](TypeId id) { - return NodeMetaInfo{id, d->projectStorage}; - }); + d->projectStorage->typeIds(module.id()), NodeMetaInfo::bind(d->projectStorage)); } else { return {}; } diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h index 88d2d14eb3f..0fe9040c4d4 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstoragepathwatcher.h @@ -183,7 +183,7 @@ public: QStringList convertWatcherEntriesToDirectoryPathList(const WatcherEntries &watcherEntries) const { SourceContextIds sourceContextIds = Utils::transform( - watcherEntries, [&](WatcherEntry entry) { return entry.sourceContextId; }); + watcherEntries, &WatcherEntry::sourceContextId); std::sort(sourceContextIds.begin(), sourceContextIds.end()); sourceContextIds.erase(std::unique(sourceContextIds.begin(), sourceContextIds.end()), diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp index 267304ab4fd..85d795a5bcf 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp @@ -826,8 +826,7 @@ void ProjectStorageUpdater::updatePropertyEditorFilePath( namespace { SourceContextIds filterUniqueSourceContextIds(const SourceIds &sourceIds) { - auto sourceContextIds = Utils::transform(sourceIds, - [](SourceId sourceId) { return sourceId.contextId(); }); + auto sourceContextIds = Utils::transform(sourceIds, &SourceId::contextId); std::sort(sourceContextIds.begin(), sourceContextIds.end()); auto newEnd = std::unique(sourceContextIds.begin(), sourceContextIds.end()); diff --git a/src/plugins/qmldesigner/libs/designercore/rewriter/rewriterview.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriterview.cpp index 25cbc2d1852..b79ddcbe087 100644 --- a/src/plugins/qmldesigner/libs/designercore/rewriter/rewriterview.cpp +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriterview.cpp @@ -993,10 +993,8 @@ QString RewriterView::convertTypeToImportAlias(const QString &type) const QStringList RewriterView::importDirectories() const { - const QList list(m_textToModelMerger->vContext().paths.begin(), - m_textToModelMerger->vContext().paths.end()); - - return Utils::transform(list, [](const Utils::FilePath &p) { return p.toString(); }); + return Utils::transform(m_textToModelMerger->vContext().paths, + &Utils::FilePath::path); } QSet> RewriterView::qrcMapping() const diff --git a/src/plugins/qmldesigner/libs/qmldesignerutils/designeralgorithm.h b/src/plugins/qmldesigner/libs/qmldesignerutils/designeralgorithm.h index 94d84c8b0be..4d23db49239 100644 --- a/src/plugins/qmldesigner/libs/qmldesignerutils/designeralgorithm.h +++ b/src/plugins/qmldesigner/libs/qmldesignerutils/designeralgorithm.h @@ -5,6 +5,8 @@ #include +#include + namespace QmlDesigner::CoreUtils { template @@ -19,4 +21,17 @@ __forceinline return ((element == elements) || ...); } +template typename Container, std::ranges::view View> +constexpr auto to(View &&view) +{ + return Container>>(std::ranges::begin(view), + std::ranges::end(view)); +} + +template +constexpr auto to(View &&view) +{ + return Container(std::ranges::begin(view), std::ranges::end(view)); +} + } // namespace QmlDesigner::CoreUtils diff --git a/src/plugins/qmldesigner/qmltools/qmlitemnode.cpp b/src/plugins/qmldesigner/qmltools/qmlitemnode.cpp index eb1b2329af3..d12998aae14 100644 --- a/src/plugins/qmldesigner/qmltools/qmlitemnode.cpp +++ b/src/plugins/qmldesigner/qmltools/qmlitemnode.cpp @@ -10,20 +10,22 @@ #include "qmlanchors.h" #include +#include #include #include #include +#include +#include +#include + #include #include #include #include #include -#include -#include - namespace QmlDesigner { bool QmlItemNode::isItemOrWindow(const ModelNode &modelNode) @@ -1037,9 +1039,7 @@ QList QmlFlowViewNode::getAssociatedConnections(const ModelNode AbstractView *view = node.view(); - return Utils::transform>(Utils::filtered(view->allModelNodes(), - [&node](const ModelNode &n) { - const QmlConnections connection(n); + auto filter = [&](const QmlConnections &connection) { if (!connection.isValid()) return false; @@ -1060,9 +1060,14 @@ QList QmlFlowViewNode::getAssociatedConnections(const ModelNode } return false; - }), [](const ModelNode &n) { - return QmlConnections(n); - }); + }; + + auto convert = [](const ModelNode &n) { return QmlConnections(n); }; + + auto nodes = view->allModelNodes(); + + return CoreUtils::to>(Utils::span{nodes} | std::views::transform(convert) + | std::views::filter(filter)); } } //QmlDesigner diff --git a/src/plugins/qmldesigner/qmltools/qmlitemnode.h b/src/plugins/qmldesigner/qmltools/qmlitemnode.h index eb0ba97983f..f19a89902f0 100644 --- a/src/plugins/qmldesigner/qmltools/qmlitemnode.h +++ b/src/plugins/qmldesigner/qmltools/qmlitemnode.h @@ -32,6 +32,8 @@ public: static bool isItemOrWindow(const ModelNode &modelNode); + static QmlItemNode create(const ModelNode &modelNode) { return QmlItemNode{modelNode}; } + static QmlItemNode createQmlItemNode(AbstractView *view, const ItemLibraryEntry &itemLibraryEntry, const QPointF &position, From cea72ef6309206d36c653744cae2b5fa3408e6ab Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 29 Aug 2024 16:58:42 +0200 Subject: [PATCH 145/193] QmlDesigner: Avoid indirect call rewriterView() Use m_rewriterView directly. Change-Id: I1eda57fc62cb7c6cf4fce1710064f65a270c1588 Reviewed-by: Thomas Hartmann --- .../libs/designercore/model/model.cpp | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index 58a2acdda59..f77bab2a3c4 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -225,8 +225,8 @@ void ModelPrivate::notifyImportsChanged(const Imports &addedImports, const Impor QString description; try { - if (rewriterView()) - rewriterView()->importsChanged(addedImports, removedImports); + if (m_rewriterView) + m_rewriterView->importsChanged(addedImports, removedImports); } catch (const RewritingException &e) { description = e.description(); resetModel = true; @@ -568,8 +568,8 @@ void ModelPrivate::notifyNodeInstanceViewLast(Callable call) QString description; try { - if (rewriterView() && !rewriterView()->isBlockingNotifications()) - call(rewriterView()); + if (m_rewriterView && !m_rewriterView->isBlockingNotifications()) + call(m_rewriterView); } catch (const RewritingException &e) { description = e.description(); resetModel = true; @@ -598,8 +598,8 @@ void ModelPrivate::notifyNormalViewsLast(Callable call) QString description; try { - if (rewriterView() && !rewriterView()->isBlockingNotifications()) - call(rewriterView()); + if (m_rewriterView && !m_rewriterView->isBlockingNotifications()) + call(m_rewriterView); } catch (const RewritingException &e) { description = e.description(); resetModel = true; @@ -845,17 +845,17 @@ void ModelPrivate::notifyPropertiesAboutToBeRemoved(const QList propertyList; for (InternalProperty *property : internalPropertyList) { - AbstractProperty newProperty(property->name(), - property->propertyOwner(), - m_model, - rewriterView()); - propertyList.append(newProperty); + AbstractProperty newProperty(property->name(), + property->propertyOwner(), + m_model, + m_rewriterView); + propertyList.append(newProperty); } - rewriterView()->propertiesAboutToBeRemoved(propertyList); + m_rewriterView->propertiesAboutToBeRemoved(propertyList); } } catch (const RewritingException &e) { description = e.description(); @@ -909,8 +909,8 @@ void ModelPrivate::setAuxiliaryData(const InternalNodePointer &node, void ModelPrivate::resetModelByRewriter(const QString &description) { - if (rewriterView()) { - rewriterView()->resetToLastCorrectQml(); + if (m_rewriterView) { + m_rewriterView->resetToLastCorrectQml(); throw RewritingException(__LINE__, __FUNCTION__, From 9e5b6bb1c9e23c3962472d77dd6cf433a60e0008 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 29 Aug 2024 18:03:47 +0200 Subject: [PATCH 146/193] Use cmake support for WHOLE_ARCHIVE If the CMake version is new enough use $. Change-Id: I2b3fcd39319db2dfb923e41213b696877f7dc32c Reviewed-by: Thomas Hartmann --- src/plugins/qmldesignerbase/CMakeLists.txt | 16 ++++++++++------ src/plugins/texteditor/CMakeLists.txt | 16 ++++++++++------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/plugins/qmldesignerbase/CMakeLists.txt b/src/plugins/qmldesignerbase/CMakeLists.txt index 4fe7d952f70..ca9e53bcbad 100644 --- a/src/plugins/qmldesignerbase/CMakeLists.txt +++ b/src/plugins/qmldesignerbase/CMakeLists.txt @@ -54,11 +54,15 @@ extend_qtc_plugin(QmlDesignerBase # from cmake 3.24 $ is supported which can be added to DEPENDS -if (MSVC) - qtc_output_binary_dir(_output_binary_dir) - set_target_properties(QmlDesignerBase PROPERTIES LINK_FLAGS "/WHOLEARCHIVE:${_output_binary_dir}/${IDE_BIN_PATH}/QmlDesignerSettings.lib") -elseif (APPLE) - target_link_libraries(QmlDesignerBase PRIVATE -Wl,-force_load $) +if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") + target_link_libraries(TextEditor PRIVATE $) else () - target_link_libraries(QmlDesignerBase PRIVATE -Wl,--whole-archive $ -Wl,--no-whole-archive) + if (MSVC) + qtc_output_binary_dir(_output_binary_dir) + set_target_properties(QmlDesignerBase PROPERTIES LINK_FLAGS "/WHOLEARCHIVE:${_output_binary_dir}/${IDE_BIN_PATH}/QmlDesignerSettings.lib") + elseif (APPLE) + target_link_libraries(QmlDesignerBase PRIVATE -Wl,-force_load $) + else () + target_link_libraries(QmlDesignerBase PRIVATE -Wl,--whole-archive $ -Wl,--no-whole-archive) + endif () endif () diff --git a/src/plugins/texteditor/CMakeLists.txt b/src/plugins/texteditor/CMakeLists.txt index 62e1c2d77bf..ac25e02a94d 100644 --- a/src/plugins/texteditor/CMakeLists.txt +++ b/src/plugins/texteditor/CMakeLists.txt @@ -132,11 +132,15 @@ extend_qtc_plugin(TextEditor ) # from cmake 3.24 $ is supported which can be added to DEPENDS -if (MSVC) - qtc_output_binary_dir(_output_binary_dir) - set_target_properties(TextEditor PROPERTIES LINK_FLAGS "/WHOLEARCHIVE:${_output_binary_dir}/${IDE_BIN_PATH}/TextEditorSupport.lib") -elseif (APPLE) - target_link_libraries(TextEditor PRIVATE -Wl,-force_load $) +if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") + target_link_libraries(TextEditor PRIVATE $) else () - target_link_libraries(TextEditor PRIVATE -Wl,--whole-archive $ -Wl,--no-whole-archive) + if (MSVC) + qtc_output_binary_dir(_output_binary_dir) + set_target_properties(TextEditor PROPERTIES LINK_FLAGS "/WHOLEARCHIVE:${_output_binary_dir}/${IDE_BIN_PATH}/TextEditorSupport.lib") + elseif (APPLE) + target_link_libraries(TextEditor PRIVATE -Wl,-force_load $) + else () + target_link_libraries(TextEditor PRIVATE -Wl,--whole-archive $ -Wl,--no-whole-archive) + endif () endif () From 1717a386bacc6f45626d0140dac09d99723c8967 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Tue, 10 Sep 2024 17:28:38 +0200 Subject: [PATCH 147/193] QmlDesigner: Add custom int and double validator Add custom/studio int and double validator in order to be able to set a locale directly and not via using a name/string. Use a copy of the system locale with omit group separator set. Task-number: QDS-13536 Change-Id: I61c995b4d1f2575fcb53e327f35e4781cebc28ca Reviewed-by: Thomas Hartmann Reviewed-by: Marco Bubke --- .../imports/StudioControls/RealSpinBox.qml | 6 +-- .../imports/StudioControls/SpinBox.qml | 6 +-- src/plugins/qmldesignerbase/CMakeLists.txt | 1 + .../qmldesignerbase/qmldesignerbaseplugin.cpp | 3 ++ .../studio/studioquickutils.cpp | 4 +- .../studio/studiovalidator.cpp | 54 +++++++++++++++++++ .../qmldesignerbase/studio/studiovalidator.h | 49 +++++++++++++++++ 7 files changed, 115 insertions(+), 8 deletions(-) create mode 100644 src/plugins/qmldesignerbase/studio/studiovalidator.cpp create mode 100644 src/plugins/qmldesignerbase/studio/studiovalidator.h diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBox.qml index c83be5bd2b4..2671949dee8 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/RealSpinBox.qml @@ -3,7 +3,7 @@ import QtQuick import QtQuick.Templates as T -import StudioTheme 1.0 as StudioTheme +import StudioTheme as StudioTheme import StudioQuickUtils T.SpinBox { @@ -100,7 +100,7 @@ T.SpinBox { DoubleValidator { id: doubleValidator - locale: control.locale.name + locale: control.locale notation: DoubleValidator.StandardNotation decimals: control.decimals bottom: Math.min(control.realFrom, control.realTo) @@ -109,7 +109,7 @@ T.SpinBox { IntValidator { id: intValidator - locale: control.locale.name + locale: control.locale bottom: Math.round(Math.min(control.realFrom, control.realTo)) top: Math.round(Math.max(control.realFrom, control.realTo)) } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml index 8a07e4bc478..e2628459d4e 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SpinBox.qml @@ -3,7 +3,7 @@ import QtQuick import QtQuick.Templates as T -import StudioTheme 1.0 as StudioTheme +import StudioTheme as StudioTheme import StudioQuickUtils T.SpinBox { @@ -79,7 +79,7 @@ T.SpinBox { DoubleValidator { id: doubleValidator - locale: control.locale.name + locale: control.locale notation: DoubleValidator.StandardNotation decimals: control.decimals bottom: Math.min(control.from, control.to) / control.factor @@ -88,7 +88,7 @@ T.SpinBox { IntValidator { id: intValidator - locale: control.locale.name + locale: control.locale bottom: Math.min(control.from, control.to) top: Math.max(control.from, control.to) } diff --git a/src/plugins/qmldesignerbase/CMakeLists.txt b/src/plugins/qmldesignerbase/CMakeLists.txt index ca9e53bcbad..e5d06b7d14d 100644 --- a/src/plugins/qmldesignerbase/CMakeLists.txt +++ b/src/plugins/qmldesignerbase/CMakeLists.txt @@ -50,6 +50,7 @@ extend_qtc_plugin(QmlDesignerBase studiostyle_p.cpp studiostyle_p.h studioquickwidget.cpp studioquickwidget.h studiosettingspage.cpp studiosettingspage.h + studiovalidator.cpp studiovalidator.h ) diff --git a/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp b/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp index 626fa9f17df..888b3fa0397 100644 --- a/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp +++ b/src/plugins/qmldesignerbase/qmldesignerbaseplugin.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -93,6 +94,8 @@ bool QmlDesignerBasePlugin::initialize(const QStringList &arguments, QString *) WindowManager::registerDeclarativeType(); StudioQuickUtils::registerDeclarativeType(); + StudioIntValidator::registerDeclarativeType(); + StudioDoubleValidator::registerDeclarativeType(); d = std::make_unique(); if (Core::ICore::settings()->value("QML/Designer/StandAloneMode", false).toBool()) diff --git a/src/plugins/qmldesignerbase/studio/studioquickutils.cpp b/src/plugins/qmldesignerbase/studio/studioquickutils.cpp index 11af253732d..0a98c3b52e7 100644 --- a/src/plugins/qmldesignerbase/studio/studioquickutils.cpp +++ b/src/plugins/qmldesignerbase/studio/studioquickutils.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2023 The Qt Company Ltd. +// 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 "studioquickutils.h" @@ -9,7 +9,7 @@ namespace QmlDesigner { StudioQuickUtils::StudioQuickUtils() { - m_locale = QLocale("DesignStudioLocale"); + m_locale = QLocale(QLocale::system()); m_locale.setNumberOptions(QLocale::OmitGroupSeparator); } diff --git a/src/plugins/qmldesignerbase/studio/studiovalidator.cpp b/src/plugins/qmldesignerbase/studio/studiovalidator.cpp new file mode 100644 index 00000000000..19259f9226e --- /dev/null +++ b/src/plugins/qmldesignerbase/studio/studiovalidator.cpp @@ -0,0 +1,54 @@ +// 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 "studiovalidator.h" + +#include + +namespace QmlDesigner { + +StudioIntValidator::StudioIntValidator(QObject *parent) + : QIntValidator(parent) +{} + +void StudioIntValidator::registerDeclarativeType() +{ + qmlRegisterType("StudioQuickUtils", 1, 0, "IntValidator"); +} + +QLocale StudioIntValidator::locale() const +{ + return QIntValidator::locale(); +} + +void StudioIntValidator::setLocale(const QLocale &locale) +{ + if (QIntValidator::locale() != locale) { + QIntValidator::setLocale(locale); + emit localeChanged(); + } +} + +StudioDoubleValidator::StudioDoubleValidator(QObject *parent) + : QDoubleValidator(parent) +{} + +void StudioDoubleValidator::registerDeclarativeType() +{ + qmlRegisterType("StudioQuickUtils", 1, 0, "DoubleValidator"); +} + +QLocale StudioDoubleValidator::locale() const +{ + return QDoubleValidator::locale(); +} + +void StudioDoubleValidator::setLocale(const QLocale &locale) +{ + if (QDoubleValidator::locale() != locale) { + QDoubleValidator::setLocale(locale); + emit localeChanged(); + } +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesignerbase/studio/studiovalidator.h b/src/plugins/qmldesignerbase/studio/studiovalidator.h new file mode 100644 index 00000000000..e8e8d276959 --- /dev/null +++ b/src/plugins/qmldesignerbase/studio/studiovalidator.h @@ -0,0 +1,49 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "../qmldesignerbase_global.h" + +#include + +#include +#include + +namespace QmlDesigner { + +class QMLDESIGNERBASE_EXPORT StudioIntValidator : public QIntValidator +{ + Q_OBJECT + Q_PROPERTY(QLocale locale READ locale WRITE setLocale NOTIFY localeChanged FINAL) + +public: + StudioIntValidator(QObject *parent = nullptr); + + static void registerDeclarativeType(); + + QLocale locale() const; + void setLocale(const QLocale &locale); + +signals: + void localeChanged(); +}; + +class QMLDESIGNERBASE_EXPORT StudioDoubleValidator : public QDoubleValidator +{ + Q_OBJECT + Q_PROPERTY(QLocale locale READ locale WRITE setLocale NOTIFY localeChanged FINAL) + +public: + StudioDoubleValidator(QObject *parent = nullptr); + + static void registerDeclarativeType(); + + QLocale locale() const; + void setLocale(const QLocale &locale); + +signals: + void localeChanged(); +}; + +} // namespace QmlDesigner From 000bb9c01257e29305ee6c58999945b0d09b2670 Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Fri, 16 Aug 2024 09:56:31 +0300 Subject: [PATCH 148/193] Doc: Update landing page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QDS-13383 Change-Id: Ie1172360f9fa7338b18c2d470fc5ddfbc6329b22 Reviewed-by: Leena Miettinen Reviewed-by: Teea Põldsam --- doc/qtdesignstudio/src/qtdesignstudio.qdoc | 178 ++++++++++----------- 1 file changed, 86 insertions(+), 92 deletions(-) diff --git a/doc/qtdesignstudio/src/qtdesignstudio.qdoc b/doc/qtdesignstudio/src/qtdesignstudio.qdoc index b4bbf9a0e78..e90e733c631 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio.qdoc @@ -1,104 +1,98 @@ -// Copyright (C) 2021 The Qt Company Ltd. +// Copyright (C) 2024 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only /*! \page index.html \nextpage studio-getting-started.html - \title Qt Design Studio Manual + \keyword {Qt Design Studio Manual} + \title Qt Design Studio Documentation - Define the look and feel of the UI from wireframe to final implementation - with preset UI components. Import UI design files from 2D and 3D tools to - \QDS, which can turn them into code for developers. \QDS prototyping - features bring your designs to life and simulate and validate interactions - and dynamic behavior. You can test, preview, and fine-tune your designs to - pixel-perfection live on the desktop or target device. + \raw HTML + + \endraw - View \l{All Topics}{all topics} or select a topic from below. + \div {class="main-navigation"} + \table borderless 100% + \row + \li \inlineimage icons/installation.png + \li \inlineimage icons/getting-started.png + \li \inlineimage icons/tutorials.png + \row + \li \b {INSTALLATION} - \table - \row - \li \inlineimage qds-front-gs.png - \li \inlineimage qds-front-ui.png - \li \inlineimage qds-studio-3d-scenes.png - \li \inlineimage qds-studio-animation.png - \row - \li \b {\l{Getting Started}} - \list - \li \l{Installing \QDS} - \li \l{Tutorials} - \li \l{User Interface} - \li \l{Creating Projects} - \li \l{Use Cases} - \li \l{Concepts and Terms} - \li \l{Best Practices} - \li \l{Examples} - \endlist - \li \b {\l{Wireframing}} - \list - \li \l{Designing Application Flows} - \li \l{Using Components} - \li \l{Specifying Component Properties} - \li \l{Scalable Layouts} - \li \l{Annotating Designs} - \endlist - \li \b {\l{Prototyping}} - \list - \li \l{Creating UI Logic} - \li \l{Effects} - \li \l{Simulating Complex Experiences} - \li \l{Dynamic Behaviors} - \li \l{Validating with Target Hardware} - \li \l{Asset Creation with Other Tools} - \endlist - \li \b {\l{Motion Design}} - \list - \li \l{Introduction to Animation Techniques} - \li \l{Creating Timeline Animations} - \li \l{Editing Easing Curves} - \li \l{Production Quality} - \li \l{Optimizing Designs} - \endlist - \row - \li \inlineimage qds-front-preview.png - \li \inlineimage qds-front-advanced.png - \li \inlineimage qds-front-projects.png - \li \inlineimage qds-front-help.png - \row - \li \b {\l{Implementing Applications}} - \list - \li \l{Designer-Developer Workflow} - \li \l{Code}{Coding} - \li \l{Debugging and Profiling} - \endlist - \li \b {\l{Advanced Designer Topics}} - \list - \li \l{UI Files} - \li \l {Manage Data Collection} - \li \l{Packaging Applications} - \endlist - \li \b {\l{Developer Topics}} - \list - \li \l{Using Git} - \li \l{Converting Qt 5 Projects into Qt 6 Projects} - \li \l{Converting UI Projects to Applications} - \li \l{Use external tools}{Using External Tools} - \li \l{\QDS on MCUs} - \endlist - \li \b {\l Help} - \list - \li \l{Get help}{Getting Help} - \li \l{Supported Platforms} - \endlist - \row - \li {4,1} \note To report bugs and suggestions to the - \l{https://bugreports.qt.io/}{Qt Project Bug Tracker}, - select \uicontrol {Help > Report Bug} in \QDS. - To copy and paste detailed information about your system to the - bug report, select \uicontrol Help > - \uicontrol {System Information}. + \QDS is available with \e commercial, \e evaluation, and \e educational licenses + on Windows, \macOs, and Linux. - For credits and a list of third-party libraries, see - \l {Acknowledgements}. + \l {Installing \QDS} + \li \b {GETTING STARTED} + + Learn about the \QDS features, UI and how to get started with + your first project. + + \l{Getting Started} + \li \b {TUTORIALS} + + Follow the tutorials to learn how to create \QDS applications. + + \l{Tutorials} \endtable + \enddiv + + \section1 About + + \QDS transforms your designs into a fully functional user interface. It's no longer a + click-through mockup. Test, preview, and fine-tune your designs to pixel-perfection, + live on target devices. + + A single unified framework, one common language, fewer feedback loops, and faster iterations, + \QDS closes the gap between designers and developers. + + \b {LEARN MORE} + + \raw HTML + + \endraw + + \div {class="link-list"} + \table 100% + \row + \li \inlineimage icons/demo-32x32.png + \li \inlineimage icons/build-32x32.png + \li \inlineimage icons/settings-32x32.png + \row + \li Key Concepts + \list + \li \l{Introduction to Animation Techniques}{Animation Techniques} + \li \l{Asset Creation with Other Tools}{Creating Assets with Other Tools} + \li \l{Creating UI Logic} + \li \l{Using Components}{Components} + \li \l{Designer-Developer Workflow} + \li \l{Qt Design Studio on MCUs} + \endlist + \li Best Practices + \list + \li \l{Converting Qt 5 Projects into Qt 6 Projects} + \li \l{Converting UI Projects to Applications} + \li \l{Creating Glow and Bloom Effects} + \li \l{Creating Optimized 3D Scenes} + \li \l{Optimizing Designs} + \li \l{Production Quality}{Achieving Production Quality} + \endlist + \li Online Courses + \list + \li \l{https://qurious.qt.io/enrollments/197683855/details}{Getting Started} + \li \l{https://qurious.qt.io/catalog/courses/3910783}{Creating Your First App} + \li \l{https://qurious.qt.io/enrollments/154647839/details}{Introduction to 2D UI Design} + \li \l{https://qurious.qt.io/enrollments/167005403/details}{Introduction to 3D Design} + \li \l{https://qurious.qt.io/catalog/courses/3910791}{Using Qt Bridge for Figma} + \endlist + \endtable + \enddiv */ From 795949f2dae6883cfdf89f8641c5c3ccc07fcb81 Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Wed, 11 Sep 2024 12:51:41 +0300 Subject: [PATCH 149/193] Doc: Fix qdocconf file Replace "Manual" with "Documentation" Change-Id: Icbb434e83a6158b19688c9affb4f6947222ba3a5 Reviewed-by: Leena Miettinen --- doc/qtdesignstudio/config/qtdesignstudio.qdocconf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/qtdesignstudio/config/qtdesignstudio.qdocconf b/doc/qtdesignstudio/config/qtdesignstudio.qdocconf index 95d1475cf15..0ab6506489c 100644 --- a/doc/qtdesignstudio/config/qtdesignstudio.qdocconf +++ b/doc/qtdesignstudio/config/qtdesignstudio.qdocconf @@ -1,5 +1,5 @@ project = $IDE_ID -description = "$IDE_DISPLAY_NAME Manual" +description = "$IDE_DISPLAY_NAME Documentation" url = https://doc.qt.io/qtdesignstudio version = $QTC_VERSION @@ -102,14 +102,14 @@ qhp.projects = qtdesignstudio qhp.qtdesignstudio.file = qtdesignstudio.qhp qhp.qtdesignstudio.namespace = org.qt-project.$IDE_ID.$QTC_VERSION_TAG qhp.qtdesignstudio.virtualFolder = doc -qhp.qtdesignstudio.indexTitle = $IDE_DISPLAY_NAME Manual $QTC_VERSION +qhp.qtdesignstudio.indexTitle = $IDE_DISPLAY_NAME Documentation $QTC_VERSION qhp.qtdesignstudio.filterAttributes = $IDE_ID $QTC_VERSION qhp.qtdesignstudio.customFilters.qtdesignstudio.name = $IDE_DISPLAY_NAME $QTC_VERSION qhp.qtdesignstudio.customFilters.qtdesignstudio.filterAttributes = $IDE_ID $QTC_VERSION qhp.qtdesignstudio.indexRoot = qhp.qtdesignstudio.subprojects = manual -qhp.qtdesignstudio.subprojects.manual.title = $IDE_DISPLAY_NAME Manual +qhp.qtdesignstudio.subprojects.manual.title = $IDE_DISPLAY_NAME Documentation qhp.qtdesignstudio.subprojects.manual.indexTitle = All Topics qhp.qtdesignstudio.subprojects.manual.type = manual @@ -119,10 +119,10 @@ macro.see = "\\sa" macro.function = "\\fn" macro.QMLD = "Qt Design Studio" -navigation.landingpage = "$IDE_DISPLAY_NAME Manual" +navigation.landingpage = "$IDE_DISPLAY_NAME Documentation" # Auto-generate navigation linking based on "All Topics": navigation.toctitles = "All Topics" navigation.toctitles.inclusive = false -buildversion = "$IDE_DISPLAY_NAME Manual $QTC_VERSION" +buildversion = "$IDE_DISPLAY_NAME Documentation $QTC_VERSION" From d8a3b1daed4eff3cfe48d05642b42aeced9479ce Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 11 Sep 2024 10:47:58 +0200 Subject: [PATCH 150/193] QmlDesigner: Cleanup QmlDom requirements Change-Id: I6247388f6b685b71815d355f4768c823defcdc1f Reviewed-by: Tim Jenssen --- src/plugins/qmldesigner/CMakeLists.txt | 3 --- src/plugins/qmldesigner/libs/designercore/CMakeLists.txt | 8 +++++--- tests/unit/tests/unittests/projectstorage/CMakeLists.txt | 4 ++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index 0f0a0c70414..e6081e954de 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -1,8 +1,5 @@ #only if the plugin is requested by qtc_plugin_enabled continue if not stop as early as possible - -find_package(Qt6 COMPONENTS QmlDomPrivate QmlCompilerPrivate QUIET) - set(QmlDesignerPluginInstallPrefix "${IDE_PLUGIN_PATH}/qmldesigner") if (APPLE) set(QmlDesignerPluginInstallPrefix "${IDE_PLUGIN_PATH}/QmlDesigner") diff --git a/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt b/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt index fbca41645d5..977bced8f23 100644 --- a/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt +++ b/src/plugins/qmldesigner/libs/designercore/CMakeLists.txt @@ -1,5 +1,8 @@ +if (IS_SUPPORTED_PROJECTSTORAGE_QT) + find_package(Qt6 COMPONENTS QmlDomPrivate QmlCompiler REQUIRED) +endif() + add_qtc_library(QmlDesignerCore - CONDITION TARGET Qt6::QmlPrivate AND TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate PROPERTIES SKIP_AUTOUIC ON DEPENDS Threads::Threads @@ -8,8 +11,6 @@ add_qtc_library(QmlDesignerCore Qt::Qml Qt::QmlPrivate Qt::Quick - Qt6::QmlDomPrivate - Qt6::QmlCompilerPrivate QmlJS TextEditorSupport QmlDesignerSettings @@ -63,6 +64,7 @@ extend_qtc_library(QmlDesignerCore extend_qtc_library(QmlDesignerCore CONDITION IS_SUPPORTED_PROJECTSTORAGE_QT + DEPENDS Qt6::QmlDomPrivate Qt6::QmlCompilerPrivate PUBLIC_DEFINES QDS_BUILD_QMLPARSER ) extend_qtc_library(QmlDesignerCore diff --git a/tests/unit/tests/unittests/projectstorage/CMakeLists.txt b/tests/unit/tests/unittests/projectstorage/CMakeLists.txt index 3e1e2850527..e9a3e08b5f8 100644 --- a/tests/unit/tests/unittests/projectstorage/CMakeLists.txt +++ b/tests/unit/tests/unittests/projectstorage/CMakeLists.txt @@ -11,7 +11,7 @@ extend_qtc_test(unittest ) extend_qtc_test(unittest - CONDITION TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate AND IS_SUPPORTED_PROJECTSTORAGE_QT + CONDITION IS_SUPPORTED_PROJECTSTORAGE_QT DEPENDS Qt6::QmlDomPrivate Qt6::QmlCompilerPrivate SOURCES qmldocumentparser-test.cpp @@ -19,7 +19,7 @@ extend_qtc_test(unittest ) extend_qtc_test(unittest - CONDITION TARGET Qt6::QmlDomPrivate AND TARGET Qt6::QmlCompilerPrivate AND IS_SUPPORTED_PROJECTSTORAGE_QT + CONDITION IS_SUPPORTED_PROJECTSTORAGE_QT SOURCES_PREFIX "${QML_DESIGNER_DIRECTORY}/libs/designercore" DEPENDS Qt6::QmlDomPrivate Qt6::QmlCompilerPrivate DEFINES QDS_BUILD_QMLPARSER QML_DOM_MSVC2019_COMPAT # QML_DOM_MSVC2019_COMPAT can be revmoved for Qt 6.8 From d9ad1dbac0d10647e380d65931ad13304df040f6 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Wed, 11 Sep 2024 12:57:44 +0200 Subject: [PATCH 151/193] QmlDesigner: Remove isArray() hacks The text role data can be retrieved with model[textRole] in all cases these days. The delegate components should be bound and the model and index properties should be required. Task-number: QDS-13577 Change-Id: I219c509128d4ca9ea09a4d214e96105b7c134078 Reviewed-by: Thomas Hartmann --- .../imports/StudioControls/ComboBox.qml | 17 +++++++---------- .../imports/StudioControls/TopLevelComboBox.qml | 10 +++++----- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml index 006bb9037ca..cbd82028cfd 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/ComboBox.qml @@ -131,23 +131,23 @@ T.ComboBox { delegate: ItemDelegate { id: itemDelegate + required property var model + required property int index + width: comboBoxPopup.width - comboBoxPopup.leftPadding - comboBoxPopup.rightPadding height: control.style.controlSize.height - 2 * control.style.borderWidth padding: 0 - enabled: model.enabled === undefined ? true : model.enabled + enabled: itemDelegate.model["enabled"] === undefined ? true : itemDelegate.model["enabled"] contentItem: Text { leftPadding: 8 rightPadding: verticalScrollBar.style.scrollBarThicknessHover - text: control.textRole ? (Array.isArray(control.model) - ? modelData[control.textRole] - : model[control.textRole]) - : modelData + text: itemDelegate.model[control.textRole] color: { if (!itemDelegate.enabled) return control.style.text.disabled - if (control.currentIndex === index) + if (control.currentIndex === itemDelegate.index) return control.style.text.selectedText return control.style.text.idle @@ -158,10 +158,7 @@ T.ComboBox { ToolTipArea { anchors.fill: parent - text: control.tooltipRole ? (Array.isArray(control.model) - ? modelData[control.tooltipRole] - : model[control.tooltipRole]) - : "" + text: control.tooltipRole ? itemDelegate.model[control.tooltipRole] : "" enabled: text onClicked: itemDelegate.clicked() onDoubleClicked: itemDelegate.doubleClicked() diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TopLevelComboBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TopLevelComboBox.qml index 284e32a7b25..3ee49b56ad8 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TopLevelComboBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TopLevelComboBox.qml @@ -156,6 +156,9 @@ T.ComboBox { delegate: ItemDelegate { id: itemDelegate + required property var model + required property int index + onClicked: { // Necessary to keep the transient parent open otherwise it will change the focus // to the main window "Utils::AppMainWindowClassWindow" and closes the transient @@ -169,15 +172,12 @@ T.ComboBox { width: control.width height: control.style.controlSize.height padding: 0 - enabled: model.enabled === undefined ? true : model.enabled + enabled: itemDelegate.model["enabled"] === undefined ? true : itemDelegate.model["enabled"] contentItem: Text { leftPadding: 8 rightPadding: verticalScrollBar.style.scrollBarThicknessHover - text: control.textRole ? (Array.isArray(control.model) - ? modelData[control.textRole] - : model[control.textRole]) - : modelData + text: itemDelegate.model[control.textRole] color: { if (!itemDelegate.enabled) return control.style.text.disabled From 2dc3c87758e55f475deb9bb90b765db5f6ebf9a5 Mon Sep 17 00:00:00 2001 From: Shrief Gabr Date: Mon, 9 Sep 2024 11:43:00 +0300 Subject: [PATCH 152/193] QmlDesigner: Edit splash screen for Telemetry and Insight - Change also affects crash reporting Fixes: QDS-13585 Change-Id: Ia5587016bcb75bab111056166db2a848f0d94682 Reviewed-by: Thomas Hartmann --- .../qml/splashscreen/Welcome_splash.qml | 9 --- .../studiowelcome/studiowelcomeplugin.cpp | 56 +++---------------- 2 files changed, 8 insertions(+), 57 deletions(-) diff --git a/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml b/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml index 005c367cd9e..1e0d63c3a09 100644 --- a/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml +++ b/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml @@ -6,7 +6,6 @@ import QtQuick.Layouts 1.15 import StudioFonts 1.0 import projectmodel 1.0 import usagestatistics 1.0 -import studiousagestatistics 1.0 import QtQuick.Shapes 1.0 Rectangle { @@ -160,10 +159,6 @@ Rectangle { UsageStatisticModel { id: usageStatisticModel } - - StudioUsageStatisticModel { - id: studioUsageStatisticModel - } } //DOF seems to do nothing, we should probably just remove it. @@ -207,9 +202,7 @@ Rectangle { text: qsTr("Turn Off") fontpixelSize: 14 onClicked: { - studioUsageStatisticModel.setInsightEnabled(false) usageStatisticModel.setTelemetryEnabled(false) - usageStatisticModel.setCrashReporterEnabled(false) welcome_splash.closeClicked() } } @@ -219,9 +212,7 @@ Rectangle { forceHover: false fontpixelSize: 14 onClicked: { - studioUsageStatisticModel.setInsightEnabled(true) usageStatisticModel.setTelemetryEnabled(true) - usageStatisticModel.setCrashReporterEnabled(true) welcome_splash.closeClicked() } } diff --git a/src/plugins/studiowelcome/studiowelcomeplugin.cpp b/src/plugins/studiowelcome/studiowelcomeplugin.cpp index 0a856fcccf2..0f143dee0fc 100644 --- a/src/plugins/studiowelcome/studiowelcomeplugin.cpp +++ b/src/plugins/studiowelcome/studiowelcomeplugin.cpp @@ -87,9 +87,7 @@ static void openOpenProjectDialog() const char DO_NOT_SHOW_SPLASHSCREEN_AGAIN_KEY[] = "StudioSplashScreen"; -const char DETAILED_USAGE_STATISTICS[] = "DetailedUsageStatistics"; -const char STATISTICS_COLLECTION_MODE[] = "StatisticsCollectionMode"; -const char NO_TELEMETRY[] = "NoTelemetry"; +const char TELEMETRY_INSIGHT_SETTING[] = "Telemetry"; const char CRASH_REPORTER_SETTING[] = "CrashReportingEnabled"; QPointer s_viewWindow = nullptr; @@ -157,40 +155,24 @@ public: void setupModel() { - auto settings = makeUserFeedbackSettings(); - QVariant value = settings->value(STATISTICS_COLLECTION_MODE); - m_usageStatisticEnabled = value.isValid() && value.toString() == DETAILED_USAGE_STATISTICS; - + m_usageStatisticEnabled = Core::ICore::settings()->value(TELEMETRY_INSIGHT_SETTING, false).toBool(); m_crashReporterEnabled = Core::ICore::settings()->value(CRASH_REPORTER_SETTING, false).toBool(); emit usageStatisticChanged(); emit crashReporterEnabledChanged(); } - - Q_INVOKABLE void setCrashReporterEnabled(bool b) - { - if (m_crashReporterEnabled == b) - return; - - Core::ICore::settings()->setValue(CRASH_REPORTER_SETTING, b); - - Core::ICore::askForRestart(tr("The change will take effect after restart.")); - - setupModel(); - } - Q_INVOKABLE void setTelemetryEnabled(bool b) { - if (m_usageStatisticEnabled == b) + if (m_usageStatisticEnabled == b && m_crashReporterEnabled == b) return; - auto settings = makeUserFeedbackSettings(); + bool restartPending = ICore::askForRestart(tr("The change will take effect after restart.")); - settings->setValue(STATISTICS_COLLECTION_MODE, b ? DETAILED_USAGE_STATISTICS : NO_TELEMETRY); + ICore::settings()->setValue(TELEMETRY_INSIGHT_SETTING, b); + ICore::settings()->setValue(CRASH_REPORTER_SETTING, b); - Core::ICore::askForRestart(tr("The change will take effect after restart.")); - - setupModel(); + if (restartPending) + ICore::restart(); } signals: @@ -203,27 +185,6 @@ private: QString m_versionString; }; -class StudioUsageStatisticPluginModel : public QObject -{ - Q_OBJECT -public: - explicit StudioUsageStatisticPluginModel(QObject *parent = nullptr) - : QObject(parent) - { - } - - Q_INVOKABLE void setInsightEnabled(bool b) - { - bool currentTrackingStatus = Core::ICore::settings()->value("InsightTracking", false).toBool(); - - if (currentTrackingStatus == b) - return; - - Core::ICore::settings()->setValue("InsightTracking", b); - Core::ICore::askForRestart(tr("The change will take effect after restart.")); - } -}; - class ProjectModel : public QAbstractListModel { Q_OBJECT @@ -599,7 +560,6 @@ void StudioWelcomePlugin::initialize() { qmlRegisterType("projectmodel", 1, 0, "ProjectModel"); qmlRegisterType("usagestatistics", 1, 0, "UsageStatisticModel"); - qmlRegisterType("studiousagestatistics", 1, 0, "StudioUsageStatisticModel"); m_welcomeMode = new WelcomeMode; } From 6ec3c8f9c9fddfd0b44574a638be06ed592ef8d5 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 11 Sep 2024 12:14:43 +0200 Subject: [PATCH 153/193] Fix documentation build if include paths contain generator expressions We already filtered them out for the translation targets, also do that for the developer documentation. Change-Id: I256ddc80471176a7ba1b53d1a28e1d5eacf6fb86 Reviewed-by: Cristian Adam --- cmake/QtCreatorTranslations.cmake | 6 +++--- cmake/Utils.cmake | 8 ++++++++ doc/CMakeLists.txt | 3 +++ src/CMakeLists.txt | 2 ++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/cmake/QtCreatorTranslations.cmake b/cmake/QtCreatorTranslations.cmake index 7379f1e60cc..f7774194ce8 100644 --- a/cmake/QtCreatorTranslations.cmake +++ b/cmake/QtCreatorTranslations.cmake @@ -1,5 +1,7 @@ # Defines function add_translation_targets +include(${CMAKE_CURRENT_LIST_DIR}/Utils.cmake) + function(_extract_ts_data_from_targets outprefix) set(_sources "") set(_includes "") @@ -18,9 +20,7 @@ function(_extract_ts_data_from_targets outprefix) if (NOT _skip_translation) if(_include_dirs) - list(FILTER _include_dirs EXCLUDE REGEX "\\$]+)>" "\\1") + remove_generator_expressions(_include_dirs ${_include_dirs}) list(APPEND _includes ${_include_dirs}) endif() diff --git a/cmake/Utils.cmake b/cmake/Utils.cmake index 766b6ff755e..eca19a7dd0b 100644 --- a/cmake/Utils.cmake +++ b/cmake/Utils.cmake @@ -119,3 +119,11 @@ function(configure_qml_designer Qt6_VERSION) endif() endif() endfunction() + +function(remove_generator_expressions out_var list) + set(result ${list}) + list(FILTER result EXCLUDE REGEX "\\$]+)>" "\\1") + set(${out_var} ${result} PARENT_SCOPE) +endfunction() diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 1100fc0733a..8d53d759d81 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -1,5 +1,7 @@ # Generate documentation +include(Utils) + option(BUILD_DEVELOPER_DOCS "Include developer documentation" OFF) add_feature_info("Include developer documentation" BUILD_DEVELOPER_DOCS "") @@ -15,6 +17,7 @@ function(_find_all_includes _ret_includes _ret_framework_paths) string(FIND "${_include}" "/src/libs/" _in_libs) string(FIND "${_include}" "${CMAKE_BINARY_DIR}" _in_build) if(_in_plugins LESS 0 AND _in_libs LESS 0 AND _in_build LESS 0) + remove_generator_expressions(_include ${_include}) list(APPEND _all_includes ${_include}) endif() endforeach() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f537d8b9c4f..edc23e5ed03 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -91,6 +91,7 @@ file(COPY ${PROJECT_SOURCE_DIR}/cmake/Config.cmake.in ${PROJECT_SOURCE_DIR}/cmake/QtcSeparateDebugInfo.cmake ${PROJECT_SOURCE_DIR}/cmake/QtcSeparateDebugInfo.Info.plist.in + ${PROJECT_SOURCE_DIR}/cmake/Utils.cmake DESTINATION ${CMAKE_BINARY_DIR}/cmake ) @@ -105,6 +106,7 @@ install( ${PROJECT_SOURCE_DIR}/cmake/Config.cmake.in ${PROJECT_SOURCE_DIR}/cmake/QtcSeparateDebugInfo.cmake ${PROJECT_SOURCE_DIR}/cmake/QtcSeparateDebugInfo.Info.plist.in + ${PROJECT_SOURCE_DIR}/cmake/Utils.cmake ${CMAKE_BINARY_DIR}/cmake/QtCreatorConfig.cmake DESTINATION ${IDE_CMAKE_INSTALL_PATH}/QtCreator COMPONENT Devel EXCLUDE_FROM_ALL From 9f6221d3cd3ecc49664460ade2bacf6ccddf0edf Mon Sep 17 00:00:00 2001 From: Knud Dollereder Date: Wed, 11 Sep 2024 13:13:21 +0200 Subject: [PATCH 154/193] Introduce mockImports and allow resources in the root folder mockImports is a secial import path which is only considered by Design Studio and ignored by the cmake exporter. This prevents name clashes between qml mock modules and their c++/python counter parts. Fixes: QDS-13466 Fixes: QDS-13469 Change-Id: I64026ea9d8823f3d5e818a352ccb565fa29c1933 Reviewed-by: Thomas Hartmann --- .../buildsystem/projectitem/converters.cpp | 3 + .../projectitem/qmlprojectitem.cpp | 10 +++ .../buildsystem/projectitem/qmlprojectitem.h | 3 + .../buildsystem/qmlbuildsystem.cpp | 12 ++- .../buildsystem/qmlbuildsystem.h | 2 + .../qmlprojectexporter/cmakegenerator.cpp | 20 ++++- .../qmlprojectexporter/cmakegenerator.h | 1 + .../qmlprojectexporter/cmakewriter.cpp | 78 +++++++++++++++---- .../qmlprojectexporter/cmakewriter.h | 8 +- .../qmlprojectexporter/cmakewriterv0.cpp | 2 +- .../qmlprojectexporter/cmakewriterv1.cpp | 15 +++- .../qmlprojectexporter/filetypes.cpp | 2 +- 12 files changed, 131 insertions(+), 25 deletions(-) diff --git a/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp b/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp index 515c80de40e..51ee81c7d54 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp @@ -147,6 +147,7 @@ QString jsonToQmlProject(const QJsonObject &rootObject) appendBool("enablePythonGeneration", deploymentConfig["enablePythonGeneration"].toBool()); appendBool("widgetApp", runConfig["widgetApp"].toBool()); appendStringArray("importPaths", rootObject["importPaths"].toVariant().toStringList()); + appendStringArray("mockImports", rootObject["mockImports"].toVariant().toStringList()); appendBreak(); appendString("qdsVersion", versionConfig["designStudio"].toString()); appendString("quickVersion", versionConfig["qtQuick"].toString()); @@ -411,6 +412,8 @@ QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile) } else if (propName.contains("importpaths", Qt::CaseInsensitive)) { objKey = "importPaths"; importPaths = value.toVariant().toStringList(); + } else if (propName.contains("mockImports", Qt::CaseInsensitive)) { + objKey = "mockImports"; } else { currentObj = &otherProperties; objKey = propName; // With prefix diff --git a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp index 77221c3a5e0..65c310ce497 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp @@ -212,6 +212,16 @@ void QmlProjectItem::setImportPaths(const QStringList &importPaths) insertAndUpdateProjectFile("importPaths", QJsonArray::fromStringList(importPaths)); } +QStringList QmlProjectItem::mockImports() const +{ + return m_project["mockImports"].toVariant().toStringList(); +} + +void QmlProjectItem::setMockImports(const QStringList &paths) +{ + insertAndUpdateProjectFile("mockImports", QJsonArray::fromStringList(paths)); +} + void QmlProjectItem::addImportPath(const QString &importPath) { QJsonArray importPaths = m_project["importPaths"].toArray(); diff --git a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.h b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.h index 36ee8ef5316..fa6d700291a 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.h +++ b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.h @@ -46,6 +46,9 @@ public: void setImportPaths(const QStringList &paths); void addImportPath(const QString &importPath); + QStringList mockImports() const; + void setMockImports(const QStringList &paths); + QStringList qmlProjectModules() const; QStringList fileSelectors() const; diff --git a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp index 5a64c8b7de0..79b20f3c82a 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp @@ -716,14 +716,24 @@ QStringList QmlBuildSystem::shaderToolFiles() const return m_projectItem->shaderToolFiles(); } +QStringList QmlBuildSystem::allImports() const +{ + return m_projectItem->importPaths() + m_projectItem->mockImports(); +} + QStringList QmlBuildSystem::importPaths() const { return m_projectItem->importPaths(); } +QStringList QmlBuildSystem::mockImports() const +{ + return m_projectItem->mockImports(); +} + QStringList QmlBuildSystem::absoluteImportPaths() const { - return Utils::transform(m_projectItem->importPaths(), [&](const QString &importPath) { + return Utils::transform(allImports(), [&](const QString &importPath) { Utils::FilePath filePath = Utils::FilePath::fromString(importPath); if (!filePath.isAbsolutePath()) return (projectDirectory() / importPath).toString(); diff --git a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h index 22ea4e443e6..3907e8741ed 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h +++ b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h @@ -73,7 +73,9 @@ public: Utils::EnvironmentItems environment() const; + QStringList allImports() const; QStringList importPaths() const; + QStringList mockImports() const; QStringList absoluteImportPaths() const; QStringList fileSelectors() const; diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.cpp index 063811ea9d0..c529f012eef 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.cpp @@ -172,7 +172,7 @@ bool CMakeGenerator::checkUri(const QString& uri, const Utils::FilePath &path) c Utils::FilePath relative = path.relativeChildPath(m_root->dir); QList pathComponents = relative.pathView().split('/', Qt::SkipEmptyParts); - for (const auto& import : buildSystem()->importPaths()) { + for (const auto& import : buildSystem()->allImports()) { Utils::FilePath importPath = Utils::FilePath::fromUserInput(import); for (const auto& component : importPath.pathView().split('/', Qt::SkipEmptyParts)) { if (component == pathComponents.first()) @@ -219,9 +219,25 @@ void CMakeGenerator::createSourceFiles() const m_writer->writeSourceFiles(sourceNode, m_root); } +bool CMakeGenerator::isMockModule(const NodePtr &node) const +{ + QTC_ASSERT(buildSystem(), return false); + + Utils::FilePath dir = node->dir.parentDir(); + QString mockDir = dir.relativeChildPath(m_root->dir).path(); + for (const QString &import : buildSystem()->mockImports()) { + if (import == mockDir) + return true; + } + return false; +} + void CMakeGenerator::readQmlDir(const Utils::FilePath &filePath, NodePtr &node) const { - node->type = Node::Type::Module; + if (isMockModule(node)) + node->type = Node::Type::MockModule; + else + node->type = Node::Type::Module; QFile f(filePath.toString()); f.open(QIODevice::ReadOnly); diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.h index e3b8a8a1085..43257e17815 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.h +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakegenerator.h @@ -42,6 +42,7 @@ public: private: bool ignore(const Utils::FilePath &path) const; bool checkUri(const QString& uri, const Utils::FilePath &path) const; + bool isMockModule(const NodePtr &node) const; void createCMakeFiles(const NodePtr &node) const; void createSourceFiles() const; diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp index 966714981a0..857a30ce330 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp @@ -17,6 +17,13 @@ namespace QmlProjectManager { namespace QmlProjectExporter { +const char TEMPLATE_RESOURCES[] = R"( +qt6_add_resources(%1 %2 + PREFIX "%3" + VERSION 1.0 + FILES %4 +))"; + const char TEMPLATE_BIG_RESOURCES[] = R"( qt6_add_resources(%1 %2 BIG_RESOURCES @@ -235,36 +242,64 @@ QString CMakeWriter::makeSetEnvironmentFn() const return out; } -std::tuple CMakeWriter::makeResourcesBlocks(const NodePtr &node) const +std::tuple CMakeWriter::makeResourcesBlocksRoot(const NodePtr &node) const { QString resourcesOut; QString bigResourcesOut; - QString resourceFiles; - std::vector bigResources; - for (const Utils::FilePath &path : assets(node)) { - if (path.fileSize() > 5000000) { - bigResources.push_back(makeRelative(node, path)); - continue; - } - resourceFiles.append(QString("\t\t%1\n").arg(makeRelative(node, path))); + QStringList res; + QStringList bigRes; + collectResources(node, res, bigRes); + + if (!res.isEmpty()) { + QString resourceContent; + for (const QString &r : res) + resourceContent.append(QString("\n\t\t%1").arg(r)); + + const QString resourceName = node->name + "Resource"; + resourcesOut = QString::fromUtf8(TEMPLATE_RESOURCES, -1) + .arg("${CMAKE_PROJECT_NAME}", resourceName, "/qt/qml", resourceContent); } - if (!resourceFiles.isEmpty()) - resourcesOut.append(QString("\tRESOURCES\n%1").arg(resourceFiles)); + if (!bigRes.isEmpty()) { + QString bigResourceContent; + for (const QString &r : bigRes) + bigResourceContent.append(QString("\n\t\t%1").arg(r)); - QString templatePostfix; - if (!bigResources.empty()) { + const QString resourceName = node->name + "BigResource"; + bigResourcesOut = QString::fromUtf8(TEMPLATE_BIG_RESOURCES, -1) + .arg("${CMAKE_PROJECT_NAME}", resourceName, "/qt/qml", bigResourceContent); + } + + return {resourcesOut, bigResourcesOut}; +} + +std::tuple CMakeWriter::makeResourcesBlocksModule(const NodePtr &node) const +{ + QString resourcesOut; + QString bigResourcesOut; + + QStringList res; + QStringList bigRes; + collectResources(node, res, bigRes); + + if (!res.isEmpty()) { + resourcesOut = "\tRESOURCES\n"; + for (const QString &r : res) + resourcesOut.append(QString("\t\t%1\n").arg(r)); + } + + if (!bigRes.isEmpty()) { QString resourceContent; - for (const QString &res : bigResources) - resourceContent.append(QString("\n %1").arg(res)); + for (const QString &res : bigRes) + resourceContent.append(QString("\n\t\t%1").arg(res)); const QString prefixPath = QString(node->uri).replace('.', '/'); const QString prefix = "/qt/qml/" + prefixPath; const QString resourceName = node->name + "BigResource"; bigResourcesOut = QString::fromUtf8(TEMPLATE_BIG_RESOURCES, -1) - .arg(node->name, resourceName, prefix, resourceContent); + .arg(node->name, resourceName, prefix, resourceContent); } return {resourcesOut, bigResourcesOut}; @@ -278,6 +313,17 @@ void CMakeWriter::collectPlugins(const NodePtr &node, std::vector &out) collectPlugins(child, out); } +void CMakeWriter::collectResources(const NodePtr &node, QStringList &res, QStringList &bigRes) const +{ + for (const Utils::FilePath &path : assets(node)) { + if (path.fileSize() > 5000000) { + bigRes.push_back(makeRelative(node, path)); + } else { + res.append(makeRelative(node, path)); + } + } +} + } // End namespace QmlProjectExporter. } // End namespace QmlProjectManager. diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.h b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.h index 0fbee120f79..e783a3ca4d9 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.h +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.h @@ -20,6 +20,7 @@ struct Node Module, Library, Folder, + MockModule }; std::shared_ptr parent = nullptr; @@ -63,6 +64,8 @@ public: static void writeFile(const Utils::FilePath &path, const QString &content); CMakeWriter(CMakeGenerator *parent); + virtual ~CMakeWriter() = default; + const CMakeGenerator *parent() const; virtual bool isPlugin(const NodePtr &node) const; @@ -89,11 +92,12 @@ protected: QString makeSingletonBlock(const NodePtr &node) const; QString makeSubdirectoriesBlock(const NodePtr &node) const; QString makeSetEnvironmentFn() const; - std::tuple makeResourcesBlocks(const NodePtr &node) const; - + std::tuple makeResourcesBlocksRoot(const NodePtr &node) const; + std::tuple makeResourcesBlocksModule(const NodePtr &node) const; private: void collectPlugins(const NodePtr &node, std::vector &out) const; + void collectResources(const NodePtr &node, QStringList &res, QStringList &bigRes) const; const CMakeGenerator *m_parent = nullptr; }; diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.cpp index 257a549b264..35f7fc9b82e 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv0.cpp @@ -106,7 +106,7 @@ void CMakeWriterV0::writeModuleCMakeFile(const NodePtr &node, const NodePtr &roo QString qmlModulesContent; qmlModulesContent.append(makeQmlFilesBlock(node)); - auto [resources, bigResources] = makeResourcesBlocks(node); + auto [resources, bigResources] = makeResourcesBlocksModule(node); qmlModulesContent.append(resources); if (!qmlModulesContent.isEmpty()) { diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.cpp index 8c3178beb53..0e76546c6f3 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriterv1.cpp @@ -88,7 +88,17 @@ void CMakeWriterV1::writeModuleCMakeFile(const NodePtr &node, const NodePtr &) c const Utils::FilePath userFile = node->dir.pathAppended("qds.cmake"); QString userFileContent(DO_NOT_EDIT_FILE); userFileContent.append(makeSubdirectoriesBlock(node)); - userFileContent.append("\n"); + + auto [resources, bigResources] = makeResourcesBlocksRoot(node); + if (!resources.isEmpty()) { + userFileContent.append(resources); + userFileContent.append("\n"); + } + + if (!bigResources.isEmpty()) { + userFileContent.append(bigResources); + userFileContent.append("\n"); + } QString pluginNames; std::vector plugs = plugins(node); @@ -102,6 +112,7 @@ void CMakeWriterV1::writeModuleCMakeFile(const NodePtr &node, const NodePtr &) c "target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE\n" "%1)"); + userFileContent.append("\n"); userFileContent.append(linkLibrariesTemplate.arg(pluginNames)); writeFile(userFile, userFileContent); return; @@ -119,7 +130,7 @@ void CMakeWriterV1::writeModuleCMakeFile(const NodePtr &node, const NodePtr &) c prefix.append(makeSubdirectoriesBlock(node)); prefix.append(makeSingletonBlock(node)); - auto [resources, bigResources] = makeResourcesBlocks(node); + auto [resources, bigResources] = makeResourcesBlocksModule(node); QString moduleContent; moduleContent.append(makeQmlFilesBlock(node)); moduleContent.append(resources); diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/filetypes.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/filetypes.cpp index a6ee4cd15f6..c69afd9a70c 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/filetypes.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/filetypes.cpp @@ -33,7 +33,7 @@ bool isAssetFile(const Utils::FilePath &path) { static const QStringList suffixes = { "js", "ts", "json", "hints", "mesh", "qad", "qsb", "frag", - "frag.qsb", "vert", "vert.qsb", "mng" + "frag.qsb", "vert", "vert.qsb", "mng", "wav" }; return suffixes.contains(path.suffix(), Qt::CaseInsensitive) || From 45cebed3894c330f99130e2292b512003b57cab3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sivert=20Kr=C3=B8vel?= Date: Thu, 15 Aug 2024 15:31:49 +0200 Subject: [PATCH 155/193] Qmldesigner: Simplify template CMakeLists.txt The CMakeLists.txt file generated with a new MCU project in QDS was made to work with many older Qt for MCUs versions. Since some of these are more than 2 years old now, we can simplify the file to work with the newer versions only. Task-number: QDS-13049 Change-Id: I63e5464aa7c8ebcb5d443c4eed189f5e8e595f72 Reviewed-by: Aleksei German Reviewed-by: Yasser Grimes --- .../projects/application-mcu/CMakeLists.txt | 80 ++----------------- 1 file changed, 7 insertions(+), 73 deletions(-) diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/CMakeLists.txt b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/CMakeLists.txt index 42693c255d4..11f10fbec91 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/CMakeLists.txt +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/CMakeLists.txt @@ -6,77 +6,11 @@ if (NOT TARGET Qul::Core) find_package(Qul) endif() -if (Qul_VERSION VERSION_GREATER_EQUAL "2.4") - qul_add_target(%{ProjectName} QML_PROJECT %{ProjectName}.qmlproject GENERATE_ENTRYPOINT) - app_target_setup_os(%{ProjectName}) -else() - if (Qul_VERSION VERSION_GREATER_EQUAL "1.7") - qul_add_target(%{ProjectName}) - else() - add_executable(%{ProjectName}) - target_link_libraries(%{ProjectName} - Qul::QuickUltralite - Qul::QuickUltralitePlatform) - endif() - - if (Qul_VERSION VERSION_GREATER_EQUAL "2.0") - file(GLOB_RECURSE fontSources "${CMAKE_CURRENT_SOURCE_DIR}/fonts/*.ttf") - set_property(TARGET %{ProjectName} APPEND PROPERTY QUL_FONT_FILES ${fontSources}) - elseif (Qul_VERSION VERSION_GREATER_EQUAL "1.7") - set_property(TARGET %{ProjectName} APPEND PROPERTY QUL_FONTS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/fonts") - else() - set(QUL_FONTS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/fonts,${QUL_FONTS_DIR}") - endif() - - # Using recurse search to find image files in project directory - # Excluding MCUDefaultStyle because it exists for compatibility purposes with QDS - file(GLOB_RECURSE imgSources "*.png" "*.svg" "*.jpg" "*.jpeg") - list(FILTER imgSources EXCLUDE REGEX ".*/MCUDefaultStyle/.*") - - if(imgSources) - qul_add_resource(%{ProjectName} FILES ${imgSources}) - endif() - - # Registering singletons as qml module - qul_add_qml_module(ConstantsModule - URI Constants - QML_FILES - imports/Constants/Constants.qml - ) - - message(WARNING "It is recommended to replace the recursive search with the actual list of .qml files in your project.") - file(GLOB_RECURSE qmlSources "*.qml") - # Excluding Constants folder because it is part of another qml module - list(FILTER qmlSources EXCLUDE REGEX ".*/imports/Constants/.*") - # Excluding MCUDefaultStyle because it exists for compatibility purposes with QDS - list(FILTER qmlSources EXCLUDE REGEX ".*/MCUDefaultStyle/.*") - # Excluding binary directory because it can break builds in source dir - list(FILTER qmlSources EXCLUDE REGEX "${CMAKE_CURRENT_BINARY_DIR}/.*") - qul_target_qml_sources(%{ProjectName} ${qmlSources}) - - if (Qul_VERSION VERSION_GREATER_EQUAL "2.0") - target_link_libraries(%{ProjectName} PRIVATE - Qul::Timeline - Qul::Controls - Qul::Shapes - ConstantsModule) - else() - target_link_libraries(%{ProjectName} - Qul::QuickUltraliteTimeline - Qul::QuickUltraliteControlsStyleDefault - ConstantsModule) - - if (Qul_VERSION VERSION_GREATER_EQUAL "1.8") - target_link_libraries(%{ProjectName} - Qul::QuickUltraliteShapes) - endif() - endif() - - app_target_setup_os(%{ProjectName}) - - if (Qul_VERSION VERSION_GREATER_EQUAL "1.7") - app_target_default_entrypoint(%{ProjectName} %{RootItemName}) - else() - app_target_default_main(%{ProjectName} %{RootItemName}) - endif() +if (Qul_VERSION LESS "2.4") + message(WARNING "The current Qt for MCUs version is '${Qul_VERSION}'." + "This CMake project was made for Qt for MCUs 2.4 and newer, " + "and might not work as expected.") endif() + +qul_add_target(%{ProjectName} QML_PROJECT %{ProjectName}.qmlproject GENERATE_ENTRYPOINT) +app_target_setup_os(%{ProjectName}) From bb25a4d1969a344e0c13a1b58178531dc6b0f7ee Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Tue, 10 Sep 2024 15:56:19 +0300 Subject: [PATCH 156/193] QmlDesigner: Camera should be a scene object SceneManager should exist for the camera node. Otherwise, we shouldn't show the camera display. Fixes: QDS-13582 Fixes: QDS-13583 Pick-to: 4.6 Change-Id: I03984172c6ac2faffa5381f7fb227396076e7527 Reviewed-by: Miikka Heikkinen --- .../qml2puppet/mockfiles/qt6/CameraView.qml | 6 +++--- .../qml2puppet/editor3d/generalhelper.cpp | 19 ++++++++++--------- .../qml2puppet/editor3d/generalhelper.h | 2 +- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/tools/qml2puppet/mockfiles/qt6/CameraView.qml b/src/tools/qml2puppet/mockfiles/qt6/CameraView.qml index fe886a71d68..53040ec318f 100644 --- a/src/tools/qml2puppet/mockfiles/qt6/CameraView.qml +++ b/src/tools/qml2puppet/mockfiles/qt6/CameraView.qml @@ -46,10 +46,10 @@ Rectangle { property Camera camera property Camera oldCamera - property bool view3dRootNodeExists + property bool cameraIsSceneObject property bool forceDeactive: false readonly property bool cameraViewIsOn: !forceDeactive && (cameraView.alwaysOn || cameraView.showCameraView) && priv.camera - readonly property bool cameraHasValidScene: priv.cameraViewIsOn && priv.view3dRootNodeExists + readonly property bool cameraHasValidScene: priv.cameraViewIsOn && priv.cameraIsSceneObject property Loader activeLoader readonly property size loaderSize: activeLoader && activeLoader.active ? Qt.size(activeLoader.width, activeLoader.height) @@ -58,7 +58,7 @@ Rectangle { function updateCamera() { let activeCam = activeCamera() priv.camera = activeCam - priv.view3dRootNodeExists = _generalHelper.view3dRootNode(activeCam) + priv.cameraIsSceneObject = _generalHelper.isSceneObject(activeCam) } function activeCamera() { diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp index 9392787e4c6..4d57c0d1646 100644 --- a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp +++ b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.cpp @@ -692,18 +692,19 @@ bool GeneralHelper::isOrthographicCamera(QQuick3DNode *node) const return node && qobject_cast(node); } -QQuick3DNode *GeneralHelper::view3dRootNode(QQuick3DNode *node) const +bool GeneralHelper::isSceneObject(QQuick3DNode *node) const { if (!node) - return nullptr; + return false; - QQuick3DNode *parentNode = node->parentNode(); - while (parentNode) { - if (parentNode->inherits("QQuick3DSceneRootNode")) - return parentNode; - parentNode = parentNode->parentNode(); - } - return nullptr; + const auto objectPrivate = QQuick3DObjectPrivate::get(node); + const QQuick3DSceneManager *importSceneManager = objectPrivate->sceneManager; + if (!importSceneManager) + return false; + + const QQuick3DObject *sceneObject + = importSceneManager->m_nodeMap.value(objectPrivate->spatialNode, nullptr); + return sceneObject != nullptr; } // Emitter gizmo model creation is done in C++ as creating dynamic properties and diff --git a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h index aec9c4970e6..3a2082f8179 100644 --- a/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h +++ b/src/tools/qml2puppet/qml2puppet/editor3d/generalhelper.h @@ -97,7 +97,7 @@ public: Q_INVOKABLE bool isPickable(QQuick3DNode *node) const; Q_INVOKABLE bool isCamera(QQuick3DNode *node) const; Q_INVOKABLE bool isOrthographicCamera(QQuick3DNode *node) const; - Q_INVOKABLE QQuick3DNode *view3dRootNode(QQuick3DNode *node) const; + Q_INVOKABLE bool isSceneObject(QQuick3DNode *node) const; Q_INVOKABLE QQuick3DNode *createParticleEmitterGizmoModel(QQuick3DNode *emitter, QQuick3DMaterial *material) const; From db5a7d28fab9d157a166dc61ef36af3eae067435 Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Thu, 12 Sep 2024 11:58:31 +0200 Subject: [PATCH 157/193] qds: add requested FakeVim plugin Change-Id: I897db5233a227e2806b4acd3bf31792b0b5e3fb9 Reviewed-by: Marco Bubke --- dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake b/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake index ebbd7edfe94..998ca9c53a2 100644 --- a/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake +++ b/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake @@ -30,6 +30,7 @@ set(DESIGNSTUDIO_PLUGINS Designer DiffEditor EffectComposer + FakeVim Help Insight LanguageClient From 3b067973741d7d1f74e049241d0358a10fd1d618 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 12 Sep 2024 11:31:04 +0200 Subject: [PATCH 158/193] QmlProject: Use FetchContent_Populate for CMake 3.3 Since CMake 3.30, FetchContent_Populate() with only one argument is deprecated, and will generate a configure time warning. We use FetchContent_MakeAvailable instead which already includes the add_subdirectory. Task-number: QDS-13600 Change-Id: I8c1ed45468e620813c66f4981753c046526531dc Reviewed-by: Knud Dollereder --- .../qmlprojectexporter/templates/qmlcomponents.tpl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/qmlcomponents.tpl b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/qmlcomponents.tpl index cf1d159a7e1..feb6797f9f1 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/qmlcomponents.tpl +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/templates/qmlcomponents.tpl @@ -14,7 +14,13 @@ FetchContent_Declare( ) FetchContent_GetProperties(ds) -FetchContent_Populate(ds) + +if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.30") + FetchContent_MakeAvailable(ds) +else () + FetchContent_Populate(ds) + add_subdirectory(${ds_SOURCE_DIR} ${ds_BINARY_DIR}) +endif() target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE QuickStudioComponentsplugin @@ -29,8 +35,6 @@ target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE QuickStudioUtilsplugin ) -add_subdirectory(${ds_SOURCE_DIR} ${ds_BINARY_DIR}) - target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE BUILD_QDS_COMPONENTS=true ) From ccf6b7032f13317d87790c406f05c2d262c11475 Mon Sep 17 00:00:00 2001 From: Shrief Gabr Date: Thu, 29 Aug 2024 22:27:13 +0300 Subject: [PATCH 159/193] QmlDesigner: Allow folders drag & drop in Asset Library Fixes: QDS-13465 Change-Id: Ib9f30f18cf927417037dfa4c79b53534d2ad8e86 Reviewed-by: Mahmoud Badri --- .../assetsLibraryQmlSources/AssetDelegate.qml | 61 ++++++++---------- .../assetsLibraryQmlSources/AssetsView.qml | 4 +- .../assetslibrary/assetslibrary.qrc | 2 + .../assetslibraryiconprovider.cpp | 2 + .../assetslibrary/assetslibrarymodel.cpp | 8 +++ .../assetslibrary/assetslibrarymodel.h | 1 + .../assetslibrary/images/asset_folder.png | Bin 0 -> 180 bytes .../assetslibrary/images/asset_folder@2x.png | Bin 0 -> 232 bytes .../libs/qmldesignerutils/asset.cpp | 10 ++- .../qmldesigner/libs/qmldesignerutils/asset.h | 4 +- 10 files changed, 53 insertions(+), 39 deletions(-) create mode 100644 src/plugins/qmldesigner/components/assetslibrary/images/asset_folder.png create mode 100644 src/plugins/qmldesigner/components/assetslibrary/images/asset_folder@2x.png diff --git a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml index 7128e8b09e0..53caf73cbfe 100644 --- a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml +++ b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetDelegate.qml @@ -101,20 +101,8 @@ TreeViewDelegate { : "transparent" } border.width: StudioTheme.Values.border - border.color: { - if (root.__isDirectory && (root.isHighlighted || root.hasChildWithDropHover)) - return StudioTheme.Values.themeInteraction - - if (!root.__isDirectory && root.assetsView.selectedAssets[root.__itemPath]) - return StudioTheme.Values.themeInteraction - - if (mouseArea.containsMouse) - return StudioTheme.Values.themeSectionHeadBackground - - return root.__isDirectory - ? StudioTheme.Values.themeSectionHeadBackground - : "transparent" - } + border.color: root.assetsView.selectedAssets[root.__itemPath] ? StudioTheme.Values.themeInteraction + : "transparent" } contentItem: Text { @@ -158,26 +146,31 @@ TreeViewDelegate { mouseArea.allowTooltip = false AssetsLibraryBackend.tooltipBackend.hideTooltip() - if (root.__isDirectory) - return - var ctrlDown = mouse.modifiers & Qt.ControlModifier - if (mouse.button === Qt.LeftButton) { - if (!root.assetsView.isAssetSelected(root.__itemPath) && !ctrlDown) - root.assetsView.clearSelectedAssets() - root.currFileSelected = ctrlDown ? !root.assetsView.isAssetSelected(root.__itemPath) : true - root.assetsView.setAssetSelected(root.__itemPath, root.currFileSelected) - if (root.currFileSelected) { - let selectedPaths = root.assetsView.selectedPathsAsList() - AssetsLibraryBackend.rootView.startDragAsset(selectedPaths, mapToGlobal(mouse.x, mouse.y)) - } - } else { - if (!root.assetsView.isAssetSelected(root.__itemPath) && !ctrlDown) - root.assetsView.clearSelectedAssets() - root.currFileSelected = root.assetsView.isAssetSelected(root.__itemPath) || !ctrlDown - root.assetsView.setAssetSelected(root.__itemPath, root.currFileSelected) - } + if (mouse.button === Qt.LeftButton) { + if (root.__isDirectory) { + // ensure only one directory can be selected + root.assetsView.clearSelectedAssets() + root.currFileSelected = true + } else { + if (!root.assetsView.isAssetSelected(root.__itemPath) && !ctrlDown) + root.assetsView.clearSelectedAssets() + root.currFileSelected = ctrlDown ? !root.assetsView.isAssetSelected(root.__itemPath) : true + } + + root.assetsView.setAssetSelected(root.__itemPath, root.currFileSelected) + + if (root.currFileSelected) { + let selectedPaths = root.assetsView.selectedPathsAsList() + AssetsLibraryBackend.rootView.startDragAsset(selectedPaths, mapToGlobal(mouse.x, mouse.y)) + } + } else { + if (!root.assetsView.isAssetSelected(root.__itemPath) && !ctrlDown) + root.assetsView.clearSelectedAssets() + root.currFileSelected = root.assetsView.isAssetSelected(root.__itemPath) || !ctrlDown + root.assetsView.setAssetSelected(root.__itemPath, root.currFileSelected) + } } onReleased: (mouse) => { @@ -356,8 +349,8 @@ TreeViewDelegate { onEntered: (drag) => { root.assetsRoot.updateDropExtFiles(drag) - - drag.accepted |= (drag.formats[0] === "application/vnd.qtdesignstudio.assets") + drag.accepted |= drag.formats[0] === "application/vnd.qtdesignstudio.assets" + && !root.assetsModel.isSameOrDescendantPath(drag.urls[0], root.__itemPath) if (root.__isDirectory) root.isHighlighted = drag.accepted diff --git a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsView.qml b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsView.qml index 698011db367..307d3637521 100644 --- a/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsView.qml +++ b/share/qtcreator/qmldesigner/assetsLibraryQmlSources/AssetsView.qml @@ -83,9 +83,7 @@ TreeView { interval: 200 repeat: false - onTriggered: { - root.updateRows() - } + onTriggered: root.updateRows() } Connections { diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrary.qrc b/src/plugins/qmldesigner/components/assetslibrary/assetslibrary.qrc index fb4255cdf6f..6f92dd861cf 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrary.qrc +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrary.qrc @@ -22,5 +22,7 @@ images/asset_ktx.png images/asset_ktx@2x.png images/asset_ktx_128.png + images/asset_folder.png + images/asset_folder@2x.png diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp index 6ea038777ae..15e67b74aa1 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibraryiconprovider.cpp @@ -110,6 +110,8 @@ QPair AssetsLibraryIconProvider::fetchPixmap(const QString &id, type = "video"; else if (asset.isEffect()) type = QmlDesigner::ModelNodeOperations::getEffectIcon(id); + else if (asset.isFolder()) + type = "folder"; QString pathTemplate = QString(":/AssetsLibrary/images/asset_%1%2.png").arg(type); QString path = pathTemplate.arg('_' + QString::number(requestedSize.width())); diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp index 11eb4b27162..d12d824ddc8 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp @@ -197,6 +197,14 @@ bool AssetsLibraryModel::allFilePathsAreComposedEffects(const QStringList &fileP }); } +bool AssetsLibraryModel::isSameOrDescendantPath(const QUrl &source, const QString &target) const +{ + Utils::FilePath srcPath = Utils::FilePath::fromUrl(source); + Utils::FilePath targetPath = Utils::FilePath::fromString(target); + + return targetPath.isChildOf(srcPath); +} + bool AssetsLibraryModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { QString path = m_sourceFsModel->filePath(sourceParent); diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h index d1a78bcaf57..27b5eb77f27 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h @@ -50,6 +50,7 @@ public: Q_INVOKABLE bool deleteFolderRecursively(const QModelIndex &folderIndex); Q_INVOKABLE bool allFilePathsAreTextures(const QStringList &filePaths) const; Q_INVOKABLE bool allFilePathsAreComposedEffects(const QStringList &filePaths) const; + Q_INVOKABLE bool isSameOrDescendantPath(const QUrl &source, const QString &target) const; int columnCount(const QModelIndex &parent = QModelIndex()) const override { diff --git a/src/plugins/qmldesigner/components/assetslibrary/images/asset_folder.png b/src/plugins/qmldesigner/components/assetslibrary/images/asset_folder.png new file mode 100644 index 0000000000000000000000000000000000000000..4258ef5876141084d639b1ed00cbff2b4df7c694 GIT binary patch literal 180 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|7G?$p2BAoW(+ms@iUB?$t_%ze%VA&{7%X4D zeA%*P%a<=-zkdC)Wy@O1{mU5`7`RG;{DK+oE7ZR~zdyi1K)7aY2m=Fyg{O;Sh{WaO z1H4yQSX&>?SrNKAO!9!m>V|}kLJ~dXvJOBUy literal 0 HcmV?d00001 diff --git a/src/plugins/qmldesigner/components/assetslibrary/images/asset_folder@2x.png b/src/plugins/qmldesigner/components/assetslibrary/images/asset_folder@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..bd59f52551f9c93b9ff41ac7319828b6d029f1db GIT binary patch literal 232 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-7G?$phNU`BwlFX-=mz+NxH2#>EJp&%mMvSp zeEBjkSh{p6mEpI^S?d(sYi*gh-7JR*v|D1UY!PC{xWt~$(695HfS3Lj# literal 0 HcmV?d00001 diff --git a/src/plugins/qmldesigner/libs/qmldesignerutils/asset.cpp b/src/plugins/qmldesigner/libs/qmldesignerutils/asset.cpp index ec1e4312e41..445a0e4fb8b 100644 --- a/src/plugins/qmldesigner/libs/qmldesignerutils/asset.cpp +++ b/src/plugins/qmldesigner/libs/qmldesignerutils/asset.cpp @@ -207,10 +207,18 @@ bool Asset::isValidTextureSource() return isImage() || isTexture3D(); } +bool Asset::isFolder() const +{ + return m_type == Asset::Type::Folder; +} + void Asset::resolveType() { - if (m_suffix.isEmpty()) + if (m_suffix.isEmpty()) { + m_type = Asset::Type::Folder; + return; + } if (supportedImageSuffixes().contains(m_suffix)) m_type = Asset::Type::Image; diff --git a/src/plugins/qmldesigner/libs/qmldesignerutils/asset.h b/src/plugins/qmldesigner/libs/qmldesignerutils/asset.h index 1deafd11b78..e85c1462a40 100644 --- a/src/plugins/qmldesigner/libs/qmldesignerutils/asset.h +++ b/src/plugins/qmldesigner/libs/qmldesignerutils/asset.h @@ -24,7 +24,8 @@ public: Audio, Video, Texture3D, - Effect }; + Effect, + Folder }; Asset(const QString &filePath); @@ -60,6 +61,7 @@ public: bool isEffect() const; bool isSupported() const; bool isValidTextureSource(); + bool isFolder() const; private: void resolveType(); From 1cc793d02d3c1dc1b1ae12d6188c3cc81164e240 Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Thu, 12 Sep 2024 15:26:36 +0300 Subject: [PATCH 160/193] QmlDesigner: Fix [None] item not visible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix [None] item not visible in ComboBox drop down menu. * valueRole of items shouldn't be removed when textRole is empty. * Regex is modified for searching in ComboBoxes when it has idAndName role. Fixes: QDS-13655 Change-Id: I5c82c418bca1bb5dd9f389741422841a58a44c41 Reviewed-by: Henning Gründl --- .../HelperWidgets/ItemFilterComboBox.qml | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ItemFilterComboBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ItemFilterComboBox.qml index bb7d1307d81..638634043c9 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ItemFilterComboBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ItemFilterComboBox.qml @@ -2,7 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only import QtQuick -import HelperWidgets 2.0 as HelperWidgets +import HelperWidgets as HelperWidgets HelperWidgets.ComboBox { id: comboBox @@ -15,7 +15,10 @@ HelperWidgets.ComboBox { valueRole: "id" textRole: (comboBox.typeFilter === "QtQuick3D.Texture") ? "idAndName" : "id" - validator: RegularExpressionValidator { regularExpression: /(^$|^[a-z_]\w*)/ } + validator: RegularExpressionValidator { + regularExpression: (comboBox.textRole !== "id") ? /^(\w+\s)*\w+\s\[[a-z_]\w*\]/ + : /(^$|^[a-z_]\w*)/ + } HelperWidgets.ItemFilterModel { id: itemFilterModel @@ -89,8 +92,8 @@ HelperWidgets.ComboBox { comboBox.backendValue.resetValue() } else { let valueData = (comboBox.valueRole === "") - ? comboBox.editText - : itemFilterModel.modelItemData(comboBox.currentIndex - 1)[comboBox.valueRole] + ? comboBox.editText + : comboBox.model[comboBox.currentIndex][comboBox.valueRole] if (comboBox.backendValue.expression !== valueData) comboBox.backendValue.expression = valueData @@ -98,28 +101,29 @@ HelperWidgets.ComboBox { comboBox.dirty = false } - Repeater { + QtObject { id: optionsList - property var localModel: [] + property var model function updateModel() { - optionsList.localModel = [] + let localModel = [] - if (comboBox.textRole !== "" && comboBox.valueRole !== "") { + if (comboBox.textRole !== "") { let defaultItem = {} defaultItem[comboBox.textRole] = comboBox.defaultItem - defaultItem[comboBox.valueRole] = "" - optionsList.localModel.push(defaultItem) + if (comboBox.valueRole !== "" && comboBox.textRole !== comboBox.valueRole) + defaultItem[comboBox.valueRole] = "" + localModel.push(defaultItem) } else { - optionsList.localModel.push(comboBox.defaultItem) + localModel.push(comboBox.defaultItem) } let rows = itemFilterModel.rowCount() for (let i = 0; i < rows; ++i) - optionsList.localModel.push(itemFilterModel.modelItemData(i)) + localModel.push(itemFilterModel.modelItemData(i)) - optionsList.model = optionsList.localModel // trigger on change handler + optionsList.model = localModel // trigger on change handler } } } From 322120ba8f73170c991b8bc28d5cb0b663f8923f Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Tue, 3 Sep 2024 15:02:50 +0300 Subject: [PATCH 161/193] QmlDesigner: Highlight the camera view action on the menu Fixes: QDS-13492 Change-Id: I828570d372822c854e6d388bdef0ecaf501bdb7a Reviewed-by: Mahmoud Badri Reviewed-by: Miikka Heikkinen --- .../edit3d/cameraviewwidgetaction.cpp | 42 +++++++++-- .../edit3d/cameraviewwidgetaction.h | 19 +++++ src/plugins/qmldesignerbase/CMakeLists.txt | 2 +- .../qmldesignerbase/studio/studiostyle.cpp | 72 +++++++++++++++++-- 4 files changed, 122 insertions(+), 13 deletions(-) diff --git a/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp b/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp index 8f9e025dc0a..7b56190e686 100644 --- a/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp +++ b/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp @@ -5,8 +5,6 @@ #include #include -#include - namespace QmlDesigner { struct CameraActionsModel::DataItem @@ -29,19 +27,22 @@ const QList CameraActionsModel::m_data{ CameraViewWidgetAction::CameraViewWidgetAction(QObject *parent) : QWidgetAction(parent) { - QComboBox *defaultComboBox = new QComboBox(); + ComboBoxAction *defaultComboBox = new ComboBoxAction(); CameraActionsModel *comboBoxModel = new CameraActionsModel(defaultComboBox); defaultComboBox->setModel(comboBoxModel); setDefaultWidget(defaultComboBox); + connect(defaultComboBox, &QComboBox::currentIndexChanged, this, [this] { emit currentModeChanged(currentMode()); }); + + connect(defaultComboBox, &ComboBoxAction::hovered, this, &CameraViewWidgetAction::onWidgetHovered); } QString CameraViewWidgetAction::currentMode() const { - QComboBox *defaultComboBox = qobject_cast(defaultWidget()); + ComboBoxAction *defaultComboBox = qobject_cast(defaultWidget()); QTC_ASSERT(defaultComboBox, return "CameraOff"); return defaultComboBox->currentData(CameraActionsModel::ModeRole).toString(); @@ -49,24 +50,33 @@ QString CameraViewWidgetAction::currentMode() const void CameraViewWidgetAction::setMode(const QString &mode) { - QComboBox *defaultComboBox = qobject_cast(defaultWidget()); + ComboBoxAction *defaultComboBox = qobject_cast(defaultWidget()); QTC_ASSERT(defaultComboBox, return); defaultComboBox->setCurrentIndex(CameraActionsModel::modeIndex(mode)); } QWidget *CameraViewWidgetAction::createWidget(QWidget *parent) { - QComboBox *defaultComboBox = qobject_cast(defaultWidget()); + ComboBoxAction *defaultComboBox = qobject_cast(defaultWidget()); QTC_ASSERT(defaultComboBox, return nullptr); - QComboBox *newComboBox = new QComboBox(parent); + ComboBoxAction *newComboBox = new ComboBoxAction(parent); newComboBox->setModel(defaultComboBox->model()); connect(defaultComboBox, &QComboBox::currentIndexChanged, newComboBox, &QComboBox::setCurrentIndex); connect(newComboBox, &QComboBox::currentIndexChanged, defaultComboBox, &QComboBox::setCurrentIndex); newComboBox->setCurrentIndex(defaultComboBox->currentIndex()); + + connect(newComboBox, &ComboBoxAction::hovered, this, &CameraViewWidgetAction::onWidgetHovered); + newComboBox->setProperty("_qdss_hoverFrame", true); + return newComboBox; } +void CameraViewWidgetAction::onWidgetHovered() +{ + activate(Hover); +} + CameraActionsModel::CameraActionsModel(QObject *parent) : QAbstractListModel(parent) {} @@ -102,4 +112,22 @@ int CameraActionsModel::modeIndex(const QString &mode) return std::max(0, idx); } +ComboBoxAction::ComboBoxAction(QWidget *parent) + : QComboBox(parent) +{ + setMouseTracking(true); +} + +void ComboBoxAction::enterEvent(QEnterEvent *event) +{ + QComboBox::enterEvent(event); + emit hovered(); +} + +void ComboBoxAction::moveEvent(QMoveEvent *event) +{ + QComboBox::moveEvent(event); + emit hovered(); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.h b/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.h index e368a41b032..f017f8e478e 100644 --- a/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.h +++ b/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.h @@ -3,6 +3,7 @@ #pragma once #include +#include #include #include @@ -20,6 +21,9 @@ public: protected: QWidget *createWidget(QWidget *parent) override; +private slots: + void onWidgetHovered(); + signals: void currentModeChanged(QString); }; @@ -43,4 +47,19 @@ private: static const QList m_data; }; +class ComboBoxAction : public QComboBox +{ + Q_OBJECT + +public: + explicit ComboBoxAction(QWidget *parent = nullptr); + +protected: + void enterEvent(QEnterEvent *event) override; + void moveEvent(QMoveEvent *event) override; + +signals: + void hovered(); +}; + } // namespace QmlDesigner diff --git a/src/plugins/qmldesignerbase/CMakeLists.txt b/src/plugins/qmldesignerbase/CMakeLists.txt index e5d06b7d14d..aa1a89da4b3 100644 --- a/src/plugins/qmldesignerbase/CMakeLists.txt +++ b/src/plugins/qmldesignerbase/CMakeLists.txt @@ -19,7 +19,7 @@ add_qtc_library(QmlDesignerSettings STATIC add_qtc_plugin(QmlDesignerBase CONDITION TARGET Qt::QuickWidgets - DEPENDS Qt::Core Qt::QuickWidgets + DEPENDS Qt::Core Qt::QuickWidgets Qt::GuiPrivate PLUGIN_DEPENDS Core ProjectExplorer QtSupport PUBLIC_INCLUDES settings SOURCES diff --git a/src/plugins/qmldesignerbase/studio/studiostyle.cpp b/src/plugins/qmldesignerbase/studio/studiostyle.cpp index 8bb92ccc88c..a828dcf1880 100644 --- a/src/plugins/qmldesignerbase/studio/studiostyle.cpp +++ b/src/plugins/qmldesignerbase/studio/studiostyle.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #define ANIMATE_SCROLLBARS QT_CONFIG(animation) using namespace Utils; @@ -109,6 +111,17 @@ bool isQmlEditorMenu(const QWidget *widget) return false; } +bool hasHoverFrame(const QStyleOption *option) +{ + return option->styleObject && option->styleObject->property("_qdss_hoverFrame").toBool(); +} + +bool isHovered(const QStyleOption *option) +{ + return option->state + && option->state.testFlags({QStyle::State_Enabled, QStyle::State_MouseOver}); +} + inline QPixmap getPixmapFromIcon( const QIcon &icon, const QSize &size, bool enabled, bool active, bool checked) { @@ -135,6 +148,37 @@ inline QRect expandScrollRect(const QRect &ref, } } +namespace FusionStyleHelper { +bool isMacSystemPalette(const QPalette &pal) +{ + if (!Utils::HostOsInfo::isMacHost()) + return false; + + const QPalette *themePalette = QGuiApplicationPrivate::platformTheme()->palette(); + return themePalette + && themePalette->color(QPalette::Normal, QPalette::Highlight) + == pal.color(QPalette::Normal, QPalette::Highlight) + && themePalette->color(QPalette::Normal, QPalette::HighlightedText) + == pal.color(QPalette::Normal, QPalette::HighlightedText); +} + +QColor highlight(const QPalette &pal) +{ + if (isMacSystemPalette(pal)) + return QColor(60, 140, 230); + return pal.color(QPalette::Highlight); +} + +QColor highlightedOutline(const QPalette &pal) +{ + QColor highlightedOutline = highlight(pal).darker(125); + if (highlightedOutline.value() > 160) + highlightedOutline.setHsl(highlightedOutline.hue(), highlightedOutline.saturation(), 160); + return highlightedOutline; +} + +} // namespace FusionStyleHelper + } // namespace StudioStyle::StudioStyle(QStyle *style) @@ -192,10 +236,20 @@ void StudioStyle::drawPrimitive( Super::drawPrimitive(element, option, painter, widget); break; - case PE_PanelButtonCommand: - if (!isQmlEditorMenu(widget)) - Super::drawPrimitive(element, option, painter, widget); - break; + case PE_PanelButtonCommand: { + if (isQmlEditorMenu(widget)) + break; + + if (hasHoverFrame(option) && isHovered(option)) { + painter->save(); + painter->setPen(FusionStyleHelper::highlightedOutline(option->palette)); + painter->setBrush(Qt::NoBrush); + painter->drawRect(QRectF(option->rect).adjusted(0.5, 0.5, -0.5, -0.5)); + painter->restore(); + break; + } + Super::drawPrimitive(element, option, painter, widget); + } break; case PE_FrameDefaultButton: { if (const auto button = qstyleoption_cast(option)) { bool enabled = button->state & QStyle::State_Enabled; @@ -594,7 +648,15 @@ void StudioStyle::drawComplexControl( } } break; case CC_ComboBox: { - painter->fillRect(option->rect, standardPalette().brush(QPalette::ColorRole::Base)); + if (hasHoverFrame(option)) { + if (isHovered(option)) { + painter->fillRect( + QRectF(option->rect).adjusted(0.5, 0.5, -0.5, -0.5), + FusionStyleHelper::highlight(option->palette)); + } + } else { + painter->fillRect(option->rect, standardPalette().brush(QPalette::ColorRole::Base)); + } Super::drawComplexControl(control, option, painter, widget); } break; From 94bc04e60ef5d096bec4c6ff01ac29a769c0c480 Mon Sep 17 00:00:00 2001 From: Przemyslaw Lewandowski Date: Wed, 11 Sep 2024 14:27:06 +0200 Subject: [PATCH 162/193] QmlDesigner: Generate MCU compatible design system module Task-number: QDS-13599 Change-Id: Iff8121bd8c4df44e0700d141497792de39a29668 Reviewed-by: Vikas Pachdha --- .../components/designsystem/dsthemegroup.cpp | 37 +++++++++++++------ .../components/designsystem/dsthemegroup.h | 7 +++- .../designsystem/dsthememanager.cpp | 25 +++++++++---- .../components/designsystem/dsthememanager.h | 3 +- 4 files changed, 51 insertions(+), 21 deletions(-) diff --git a/src/plugins/qmldesigner/components/designsystem/dsthemegroup.cpp b/src/plugins/qmldesigner/components/designsystem/dsthemegroup.cpp index aa2b5c78a23..4a26fef5ec9 100644 --- a/src/plugins/qmldesigner/components/designsystem/dsthemegroup.cpp +++ b/src/plugins/qmldesigner/components/designsystem/dsthemegroup.cpp @@ -150,38 +150,51 @@ void DSThemeGroup::duplicateValues(ThemeId from, ThemeId to) } } -void DSThemeGroup::decorate(ThemeId theme, ModelNode themeNode) +void DSThemeGroup::decorate(ThemeId theme, ModelNode themeNode, DECORATION_CONTEXT decorationContext) { if (!count(theme)) return; // No props for this theme in this group. - const auto groupName = GroupId(m_type); + ModelNode *targetNode = &themeNode; const auto typeName = groupTypeName(m_type); - auto groupNode = themeNode.model()->createModelNode("QtObject"); - auto groupProperty = themeNode.nodeProperty(groupName); - if (!groupProperty || !typeName || !groupNode) { - qCDebug(dsLog) << "Adding group node failed." << groupName << theme; - return; + if (decorationContext == DECORATION_CONTEXT::MPU) { + // Create a group node + const auto groupName = GroupId(m_type); + auto groupNode = themeNode.model()->createModelNode("QtObject"); + auto groupProperty = themeNode.nodeProperty(groupName); + + if (!groupProperty || !typeName || !groupNode) { + qCDebug(dsLog) << "Adding group node failed." << groupName << theme; + return; + } + groupProperty.setDynamicTypeNameAndsetModelNode("QtObject", groupNode); + targetNode = &groupNode; } + // Add properties for (auto itr = m_values.begin(); itr != m_values.end(); ++itr) { auto &[propName, values] = *itr; auto themeValue = values.find(theme); if (themeValue != values.end()) { auto &propData = themeValue->second; if (propData.isBinding) { - auto bindingProp = groupNode.bindingProperty(propName); + auto bindingProp = targetNode->bindingProperty(propName); if (bindingProp) - bindingProp.setDynamicTypeNameAndExpression(*typeName, propData.value.toString()); + bindingProp.setDynamicTypeNameAndExpression(*typeName, + propData.value.toString()); } else { - auto nodeProp = groupNode.variantProperty(propName); - if (nodeProp) + auto nodeProp = targetNode->variantProperty(propName); + if (!nodeProp) + continue; + + if (decorationContext == DECORATION_CONTEXT::MCU) + nodeProp.setValue(propData.value); + else nodeProp.setDynamicTypeNameAndValue(*typeName, propData.value); } } } - groupProperty.setDynamicTypeNameAndsetModelNode("QtObject", groupNode); } } diff --git a/src/plugins/qmldesigner/components/designsystem/dsthemegroup.h b/src/plugins/qmldesigner/components/designsystem/dsthemegroup.h index 9b795115ab1..b76e2f3d504 100644 --- a/src/plugins/qmldesigner/components/designsystem/dsthemegroup.h +++ b/src/plugins/qmldesigner/components/designsystem/dsthemegroup.h @@ -12,6 +12,11 @@ #include namespace QmlDesigner { +enum class DECORATION_CONTEXT { + MCU, + MPU, + COMPONENT_THEME, +}; class QMLDESIGNERCOMPONENTS_EXPORT DSThemeGroup { @@ -50,7 +55,7 @@ public: void removeTheme(ThemeId theme); void duplicateValues(ThemeId from, ThemeId to); - void decorate(ThemeId theme, ModelNode themeNode); + void decorate(ThemeId theme, ModelNode themeNode, DECORATION_CONTEXT decorationContext); private: const GroupType m_type; diff --git a/src/plugins/qmldesigner/components/designsystem/dsthememanager.cpp b/src/plugins/qmldesigner/components/designsystem/dsthememanager.cpp index 652c0080cd3..8e6513392d4 100644 --- a/src/plugins/qmldesigner/components/designsystem/dsthememanager.cpp +++ b/src/plugins/qmldesigner/components/designsystem/dsthememanager.cpp @@ -130,27 +130,38 @@ void DSThemeManager::updateProperty(ThemeId id, dsGroup->updateProperty(id, newName, p); } -void DSThemeManager::decorate(ModelNode rootNode) const +void DSThemeManager::decorate(ModelNode rootNode, const QByteArray &nodeType, bool isMCU) const { if (!m_themes.size()) return; auto p = rootNode.bindingProperty("currentTheme"); - p.setDynamicTypeNameAndExpression("QtObject", QString::fromLatin1(m_themes.begin()->second)); - addGroupAliases(rootNode); - + p.setDynamicTypeNameAndExpression(nodeType, QString::fromLatin1(m_themes.begin()->second)); + if (!isMCU) + addGroupAliases(rootNode); auto model = rootNode.model(); + for (auto itr = m_themes.begin(); itr != m_themes.end(); ++itr) { - auto themeNode = model->createModelNode("QtObject"); + auto themeNode = model->createModelNode(nodeType); auto themeProperty = model->rootModelNode().nodeProperty(itr->second); - themeProperty.setDynamicTypeNameAndsetModelNode("QtObject", themeNode); + themeProperty.setDynamicTypeNameAndsetModelNode(nodeType, themeNode); // Add property groups for (auto groupItr = m_groups.begin(); groupItr != m_groups.end(); ++groupItr) - groupItr->second->decorate(itr->first, themeNode); + groupItr->second->decorate(itr->first, themeNode, isMCU ? DECORATION_CONTEXT::MCU : DECORATION_CONTEXT::MPU); } } +void DSThemeManager::decorateThemeComponent(ModelNode rootNode) const +{ + if (!m_themes.size()) + return; + + auto itr = m_themes.begin(); + for (auto groupItr = m_groups.begin(); groupItr != m_groups.end(); ++groupItr) + groupItr->second->decorate(itr->first, rootNode, DECORATION_CONTEXT::COMPONENT_THEME); +} + DSThemeGroup *DSThemeManager::propertyGroup(GroupType type) { auto itr = m_groups.find(type); diff --git a/src/plugins/qmldesigner/components/designsystem/dsthememanager.h b/src/plugins/qmldesigner/components/designsystem/dsthememanager.h index a28bf232c1c..e3ac9e2e4c9 100644 --- a/src/plugins/qmldesigner/components/designsystem/dsthememanager.h +++ b/src/plugins/qmldesigner/components/designsystem/dsthememanager.h @@ -43,7 +43,8 @@ public: void updateProperty(ThemeId id, GroupType gType, const ThemeProperty &p); void updateProperty(ThemeId id, GroupType gType, const ThemeProperty &p, const PropertyName &newName); - void decorate(ModelNode rootNode) const; + void decorate(ModelNode rootNode, const QByteArray& nodeType, bool isMCU) const; + void decorateThemeComponent(ModelNode rootNode) const; private: DSThemeGroup *propertyGroup(GroupType type); From 432ae3dabc3a6bd2030d4862c1f1d9e4c2db5127 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Thu, 12 Sep 2024 13:13:31 +0200 Subject: [PATCH 163/193] Use newer cmake to fix whole library with minggw Change-Id: I400fb6ebdcc6ab6be4674a68546491eb56ae62c1 Reviewed-by: Tim Jenssen Reviewed-by: Cristian Adam --- .github/workflows/build_cmake.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml index e07bcb0669f..41cd8f3490d 100644 --- a/.github/workflows/build_cmake.yml +++ b/.github/workflows/build_cmake.yml @@ -11,7 +11,7 @@ env: MACOS_DEPLOYMENT_TARGET: 11.0 CLANG_VERSION: 18.1.7 ELFUTILS_VERSION: 0.175 - CMAKE_VERSION: 3.21.1 + CMAKE_VERSION: 3.30.3 NINJA_VERSION: 1.10.2 BUILD_TYPE: Release CCACHE_VERSION: 4.9 From eb3d8f544426fa407dccb52b992f0249e2eca2b1 Mon Sep 17 00:00:00 2001 From: Knud Dollereder Date: Thu, 12 Sep 2024 14:51:58 +0200 Subject: [PATCH 164/193] Remove DirectoryFontLoader.qml from the project templates Fixes: QDS-13018 Change-Id: I0aba89b91166de9f149792549dd5ae293b495ddb Reviewed-by: Alessandro Portale Reviewed-by: Thomas Hartmann --- .../projects/application-3d/wizard.json | 4 --- .../application-extended-3d/wizard.json | 4 --- .../projects/application/wizard.json | 4 --- .../projects/desktop-launcher/wizard.json | 4 --- .../projects/mobile-scroll/wizard.json | 4 --- .../projects/mobile-stack/wizard.json | 4 --- .../projects/mobile-swipe/wizard.json | 4 --- .../name/CMakeLists.importmodule.txt.tpl | 1 - .../name/DirectoryFontLoader.qml.tpl | 34 ------------------- .../name/importmodule.qmldir.tpl | 1 - .../projects/shared-plugin/name/qmldir | 4 --- .../projects/qtquickapplication/wizard.json | 5 --- 12 files changed, 73 deletions(-) delete mode 100644 share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/DirectoryFontLoader.qml.tpl delete mode 100644 share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/qmldir diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json index 81c0baae42d..afb00fa253c 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json @@ -343,10 +343,6 @@ "source": "../shared-plugin/name/Constants.qml.tpl", "target": "%{ProjectDirectory}/%{ImportModuleName}/Constants.qml" }, - { - "source": "../shared-plugin/name/DirectoryFontLoader.qml.tpl", - "target": "%{ProjectDirectory}/%{ImportModuleName}/DirectoryFontLoader.qml" - }, { "source": "../shared-plugin/name/EventListModel.qml.tpl", "target": "%{ProjectDirectory}/%{ImportModuleName}/EventListModel.qml" diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/wizard.json index fa7677fa5ea..ccfcd01a983 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-extended-3d/wizard.json @@ -319,10 +319,6 @@ "source": "../shared-plugin/name/Constants.qml.tpl", "target": "%{ProjectDirectory}/%{ImportModuleName}/Constants.qml" }, - { - "source": "../shared-plugin/name/DirectoryFontLoader.qml.tpl", - "target": "%{ProjectDirectory}/%{ImportModuleName}/DirectoryFontLoader.qml" - }, { "source": "../shared-plugin/name/EventListModel.qml.tpl", "target": "%{ProjectDirectory}/%{ImportModuleName}/EventListModel.qml" diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json index 5c2ee9ab3bd..0aab9b601f3 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json @@ -341,10 +341,6 @@ "source": "../shared-plugin/name/Constants.qml.tpl", "target": "%{ProjectDirectory}/%{ImportModuleName}/Constants.qml" }, - { - "source": "../shared-plugin/name/DirectoryFontLoader.qml.tpl", - "target": "%{ProjectDirectory}/%{ImportModuleName}/DirectoryFontLoader.qml" - }, { "source": "../shared-plugin/name/EventListModel.qml.tpl", "target": "%{ProjectDirectory}/%{ImportModuleName}/EventListModel.qml" diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json index 82bafe5b56b..2fc56890b39 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json @@ -340,10 +340,6 @@ "source": "../shared-plugin/name/Constants.qml.tpl", "target": "%{ProjectDirectory}/%{ImportModuleName}/Constants.qml" }, - { - "source": "../shared-plugin/name/DirectoryFontLoader.qml.tpl", - "target": "%{ProjectDirectory}/%{ImportModuleName}/DirectoryFontLoader.qml" - }, { "source": "../shared-plugin/name/EventListModel.qml.tpl", "target": "%{ProjectDirectory}/%{ImportModuleName}/EventListModel.qml" diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json index 4206c05b5b7..96a35076775 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json @@ -299,10 +299,6 @@ "source": "../shared-plugin/name/Constants.qml.tpl", "target": "%{ProjectDirectory}/%{ImportModuleName}/Constants.qml" }, - { - "source": "../shared-plugin/name/DirectoryFontLoader.qml.tpl", - "target": "%{ProjectDirectory}/%{ImportModuleName}/DirectoryFontLoader.qml" - }, { "source": "../shared-plugin/name/EventListModel.qml.tpl", "target": "%{ProjectDirectory}/%{ImportModuleName}/EventListModel.qml" diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json index 322a83cc8bf..6a0d9455aa1 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json @@ -301,10 +301,6 @@ "source": "../shared-plugin/name/Constants.qml.tpl", "target": "%{ProjectDirectory}/%{ImportModuleName}/Constants.qml" }, - { - "source": "../shared-plugin/name/DirectoryFontLoader.qml.tpl", - "target": "%{ProjectDirectory}/%{ImportModuleName}/DirectoryFontLoader.qml" - }, { "source": "../shared-plugin/name/EventListModel.qml.tpl", "target": "%{ProjectDirectory}/%{ImportModuleName}/EventListModel.qml" diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json index 9eb1b367c0b..f7be95e0e37 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json @@ -301,10 +301,6 @@ "source": "../shared-plugin/name/Constants.qml.tpl", "target": "%{ProjectDirectory}/%{ImportModuleName}/Constants.qml" }, - { - "source": "../shared-plugin/name/DirectoryFontLoader.qml.tpl", - "target": "%{ProjectDirectory}/%{ImportModuleName}/DirectoryFontLoader.qml" - }, { "source": "../shared-plugin/name/EventListModel.qml.tpl", "target": "%{ProjectDirectory}/%{ImportModuleName}/EventListModel.qml" diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/CMakeLists.importmodule.txt.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/CMakeLists.importmodule.txt.tpl index e3cc78f3421..c978c969699 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/CMakeLists.importmodule.txt.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/CMakeLists.importmodule.txt.tpl @@ -13,7 +13,6 @@ qt6_add_qml_module(%{ImportModuleName} RESOURCE_PREFIX "/qt/qml" QML_FILES Constants.qml - DirectoryFontLoader.qml EventListModel.qml EventListSimulator.qml ) diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/DirectoryFontLoader.qml.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/DirectoryFontLoader.qml.tpl deleted file mode 100644 index 756b8f9d06d..00000000000 --- a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/DirectoryFontLoader.qml.tpl +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only - -import QtQuick -import Qt.labs.folderlistmodel - -QtObject { - id: loader - - property url fontDirectory: Qt.resolvedUrl("../../%{ContentDir}/" + relativeFontDirectory) - property string relativeFontDirectory: "fonts" - - function loadFont(url) { - var fontLoader = Qt.createQmlObject('import QtQuick 2.15; FontLoader { source: "' + url + '"; }', - loader, - "dynamicFontLoader"); - } - - property FolderListModel folderModel: FolderListModel { - id: folderModel - folder: loader.fontDirectory - nameFilters: [ "*.ttf", "*.otf" ] - showDirs: false - - onStatusChanged: { - if (folderModel.status == FolderListModel.Ready) { - var i - for (i = 0; i < count; i++) { - loadFont(folderModel.get(i, "fileURL")) - } - } - } - } -} diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/importmodule.qmldir.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/importmodule.qmldir.tpl index be4e251f8c2..74a0005e5ef 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/importmodule.qmldir.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/importmodule.qmldir.tpl @@ -2,4 +2,3 @@ module %{ImportModuleName} singleton Constants 1.0 Constants.qml EventListSimulator 1.0 EventListSimulator.qml EventListModel 1.0 EventListModel.qml -DirectoryFontLoader 1.0 DirectoryFontLoader.qml diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/qmldir b/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/qmldir deleted file mode 100644 index 3ba5adcc643..00000000000 --- a/share/qtcreator/qmldesigner/studio_templates/projects/shared-plugin/name/qmldir +++ /dev/null @@ -1,4 +0,0 @@ -singleton Constants 1.0 Constants.qml -EventListModel 1.0 EventListModel.qml -EventListSimulator 1.0 EventListSimulator.qml -DirectoryFontLoader 1.0 DirectoryFontLoader.qml diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/wizard.json b/share/qtcreator/templates/wizards/projects/qtquickapplication/wizard.json index a41ee12e516..14e1c60b8fc 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/wizard.json @@ -242,11 +242,6 @@ "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/Constants.qml", "condition": "%{QdsProjectStyle}" }, - { - "source": "%{QdsWizardPath}/shared-plugin/name/DirectoryFontLoader.qml.tpl", - "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/DirectoryFontLoader.qml", - "condition": "%{QdsProjectStyle}" - }, { "source": "%{QdsWizardPath}/shared-plugin/name/EventListModel.qml.tpl", "target": "%{ProjectDirectory}/imports/%{ImportModuleName}/EventListModel.qml", From 0c102015453c5301d308182d8e5e718fa50ea458 Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Fri, 30 Aug 2024 16:45:08 +0300 Subject: [PATCH 165/193] QmlDesigner: Add a tooltip for camera view action Fixes: QDS-13491 Change-Id: Ibb11f0058c505445ed25a43c49c39651caa5661c Reviewed-by: Mats Honkamaa --- .../qmldesigner/components/edit3d/cameraviewwidgetaction.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp b/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp index 7b56190e686..cd0342f222e 100644 --- a/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp +++ b/src/plugins/qmldesigner/components/edit3d/cameraviewwidgetaction.cpp @@ -27,6 +27,7 @@ const QList CameraActionsModel::m_data{ CameraViewWidgetAction::CameraViewWidgetAction(QObject *parent) : QWidgetAction(parent) { + setToolTip(CameraActionsModel::tr("Camera view settings")); ComboBoxAction *defaultComboBox = new ComboBoxAction(); CameraActionsModel *comboBoxModel = new CameraActionsModel(defaultComboBox); From ed56c326455352f10d84a4591587dce75c0bc4d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Jen=C3=9Fen?= Date: Mon, 16 Sep 2024 14:12:53 +0200 Subject: [PATCH 166/193] QmlDesigner: register all existing qch files Change-Id: Ic992df270f8285a350db08d305213ad651f87716 Reviewed-by: Marco Bubke --- src/plugins/studiowelcome/studiowelcomeplugin.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/plugins/studiowelcome/studiowelcomeplugin.cpp b/src/plugins/studiowelcome/studiowelcomeplugin.cpp index 0f143dee0fc..68e8deb8277 100644 --- a/src/plugins/studiowelcome/studiowelcomeplugin.cpp +++ b/src/plugins/studiowelcome/studiowelcomeplugin.cpp @@ -799,17 +799,12 @@ WelcomeMode::WelcomeMode() boxLayout->addWidget(m_quickWidget); setWidget(m_modeWidget); - QStringList designStudioQchPathes - = {Core::HelpManager::documentationPath() + "/qtdesignstudio.qch", - Core::HelpManager::documentationPath() + "/qtquick.qch", - Core::HelpManager::documentationPath() + "/qtquickcontrols.qch", - Core::HelpManager::documentationPath() + "/qtquicktimeline.qch", - Core::HelpManager::documentationPath() + "/qtquick3d.qch", - Core::HelpManager::documentationPath() + "/qtqml.qch"}; + QStringList designStudioQchPathes; + QDir qchDir(Core::HelpManager::documentationPath()); + for (const QFileInfo &fileInfo : qchDir.entryInfoList({"*.qch"}, QDir::Files)) + designStudioQchPathes.append(fileInfo.absoluteFilePath()); - Core::HelpManager::registerDocumentation( - Utils::filtered(designStudioQchPathes, - [](const QString &path) { return QFileInfo::exists(path); })); + Core::HelpManager::registerDocumentation(designStudioQchPathes); } WelcomeMode::~WelcomeMode() From e20e37033a2f17b443b2a27e2ca909be8c24ef7d Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 9 Sep 2024 17:57:55 +0200 Subject: [PATCH 167/193] QmlDesigner: Add singleton support to the QmlTypesParser Task-number: QDS-13602 Change-Id: Ie3506ffe36ba232dcd3fa888cc29064bdb44f872 Reviewed-by: Tim Jenssen --- .../projectstorage/projectstorageinfotypes.h | 4 +- .../projectstorage/qmltypesparser.cpp | 11 ++++- .../projectstorage/qmltypesparser-test.cpp | 44 ++++++++++++++++++- 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinfotypes.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinfotypes.h index 010c9a7e1cc..7d1598191d6 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinfotypes.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinfotypes.h @@ -132,6 +132,7 @@ struct TypeTraits , isEnum{false} , isFileComponent{false} , usesCustomParser{false} + , isSingleton{false} , dummy{0U} , canBeContainer{FlagIs::False} , forceClip{FlagIs::False} @@ -204,7 +205,8 @@ struct TypeTraits unsigned int isEnum : 1; unsigned int isFileComponent : 1; unsigned int usesCustomParser : 1; - unsigned int dummy : 25; + unsigned int isSingleton : 1; + unsigned int dummy : 24; }; unsigned int type; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/qmltypesparser.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/qmltypesparser.cpp index 0907c846cf6..052d38809d2 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/qmltypesparser.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/qmltypesparser.cpp @@ -118,13 +118,18 @@ Storage::TypeTraits createAccessTypeTraits(QQmlJSScope::AccessSemantics accessSe return Storage::TypeTraitsKind::None; } -Storage::TypeTraits createTypeTraits(QQmlJSScope::AccessSemantics accessSematics, bool hasCustomParser) +Storage::TypeTraits createTypeTraits(QQmlJSScope::AccessSemantics accessSematics, + bool hasCustomParser, + bool isSingleton) { auto typeTrait = createAccessTypeTraits(accessSematics); if (hasCustomParser) typeTrait.usesCustomParser = true; + if (isSingleton) + typeTrait.isSingleton = true; + return typeTrait; } @@ -451,7 +456,9 @@ void addType(Storage::Synchronization::Types &types, Utils::SmallStringView{typeName}, Storage::Synchronization::ImportedType{TypeNameString{component.baseTypeName()}}, Storage::Synchronization::ImportedType{TypeNameString{component.extensionTypeName()}}, - createTypeTraits(component.accessSemantics(), component.hasCustomParser()), + createTypeTraits(component.accessSemantics(), + component.hasCustomParser(), + component.isSingleton()), sourceId, createExports(exports, typeName, storage, cppModuleId), createProperties(component.ownProperties(), enumerationTypes, componentNameWithoutNamespace), diff --git a/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp b/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp index c33bcbf068f..9e359a76d0d 100644 --- a/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/qmltypesparser-test.cpp @@ -63,13 +63,20 @@ MATCHER_P(HasFlag, flag, std::string(negation ? "hasn't " : "has ") + PrintToStr MATCHER_P(UsesCustomParser, value, - std::string(negation ? "don't used custom parser " : "uses custom parser")) + std::string(negation ? "don't used custom parser " : "uses custom parser ")) { const Storage::TypeTraits &traits = arg; return traits.usesCustomParser == value; } +MATCHER_P(IsSingleton, value, std::string(negation ? "isn't singleton " : "is singleton ")) +{ + const Storage::TypeTraits &traits = arg; + + return traits.isSingleton == value; +} + template auto IsTypeTrait(const Matcher &matcher) { @@ -878,4 +885,39 @@ TEST_F(QmlTypesParser, skip_template_item) qmltypesFileSourceId))); } +TEST_F(QmlTypesParser, is_singleton) +{ + QString source{R"(import QtQuick.tooling 1.2 + Module{ + Component { name: "QObject" + isSingleton: true}})"}; + + parser.parse(source, imports, types, directoryInfo); + + ASSERT_THAT(types, ElementsAre(IsTypeTrait(IsSingleton(true)))); +} + +TEST_F(QmlTypesParser, is_not_singleton) +{ + QString source{R"(import QtQuick.tooling 1.2 + Module{ + Component { name: "QObject" + isSingleton: false}})"}; + + parser.parse(source, imports, types, directoryInfo); + + ASSERT_THAT(types, ElementsAre(IsTypeTrait(IsSingleton(false)))); +} + +TEST_F(QmlTypesParser, is_by_default_not_singleton) +{ + QString source{R"(import QtQuick.tooling 1.2 + Module{ + Component { name: "QObject"}})"}; + + parser.parse(source, imports, types, directoryInfo); + + ASSERT_THAT(types, ElementsAre(IsTypeTrait(IsSingleton(false)))); +} + } // namespace From e91fe4dea72f60bc5358c843275b30d9db772e7b Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Mon, 9 Sep 2024 18:41:15 +0200 Subject: [PATCH 168/193] QmlDesigner: Add singleton support to QmlDocumentParser Task-number: QDS-13602 Change-Id: I0af54c5949b20e840c0b07f13ec213db8dc40d7e Reviewed-by: Tim Jenssen --- .../projectstorage/qmldocumentparser.cpp | 17 ++++++++++++--- .../projectstorage/qmldocumentparser-test.cpp | 21 +++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/qmldocumentparser.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/qmldocumentparser.cpp index d72f49b33a4..b571cebac3d 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/qmldocumentparser.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/qmldocumentparser.cpp @@ -30,6 +30,8 @@ using Tracer = ProjectStorageTracing::Category::TracerType; namespace QmlDom = QQmlJS::Dom; namespace Synchronization = Storage::Synchronization; +using namespace Qt::StringLiterals; + namespace { using QualifiedImports = std::map; @@ -297,12 +299,21 @@ void addEnumeraton(Storage::Synchronization::Type &type, const QmlDom::Component } } -Storage::TypeTraits createTypeTraits() +bool isSingleton(const QmlDom::QmlFile *qmlFile) +{ + const auto &pragmas = qmlFile->pragmas(); + + return std::ranges::find(pragmas, "Singleton"_L1, &QQmlJS::Dom::Pragma::name) != pragmas.end(); +} + +Storage::TypeTraits createTypeTraits(const QmlDom::QmlFile *qmlFile) { Storage::TypeTraits traits = Storage::TypeTraitsKind::Reference; traits.isFileComponent = true; + traits.isSingleton = isSingleton(qmlFile); + return traits; } @@ -353,7 +364,7 @@ Storage::Synchronization::Type QmlDocumentParser::parse(const QString &sourceCon QmlDom::DomItem file = items.field(QmlDom::Fields::currentItem); const QmlDom::QmlFile *qmlFile = file.as(); const auto &components = qmlFile->components(); - + qmlFile->pragmas(); if (components.empty()) return type; @@ -372,7 +383,7 @@ Storage::Synchronization::Type QmlDocumentParser::parse(const QString &sourceCon directoryPath, m_storage); - type.traits = createTypeTraits(); + type.traits = createTypeTraits(qmlFile); type.prototype = createImportedTypeName(qmlObject.name(), qualifiedImports); type.defaultPropertyName = qmlObject.localDefaultPropertyName(); addImports(imports, qmlFile->imports(), sourceId, directoryPath, m_storage); diff --git a/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp b/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp index ee5ba836c2a..0db9dbed702 100644 --- a/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/qmldocumentparser-test.cpp @@ -543,4 +543,25 @@ TEST_F(QmlDocumentParser, has_is_reference_trait) ASSERT_THAT(type.traits.kind, QmlDesigner::Storage::TypeTraitsKind::Reference); } +TEST_F(QmlDocumentParser, is_singleton) +{ + QString component = R"(pragma Singleton + Item{ + })"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); + + ASSERT_TRUE(type.traits.isSingleton); +} + +TEST_F(QmlDocumentParser, is_not_singleton) +{ + QString component = R"(Item{ + })"; + + auto type = parser.parse(component, imports, qmlFileSourceId, directoryPath); + + ASSERT_FALSE(type.traits.isSingleton); +} + } // namespace From fae113f5f83aac8a6242dc169124417f409730d9 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 10 Sep 2024 15:56:36 +0200 Subject: [PATCH 169/193] QmlDesigner: Add singletons to project storage Task-number: QDS-13601 Change-Id: I6a39c5a4ddc267f6fabebcaa411ae61635e4e311 Reviewed-by: Tim Jenssen --- .../projectstorage/projectstorage.cpp | 52 +++++++++++++++++-- .../projectstorage/projectstorage.h | 4 +- .../projectstorage/projectstorageinterface.h | 3 +- tests/unit/tests/mocks/projectstoragemock.h | 6 ++- .../projectstorage/projectstorage-test.cpp | 48 +++++++++++++++++ 5 files changed, 107 insertions(+), 6 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp index 1a46a30c1f2..37dc5189379 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.cpp @@ -18,6 +18,7 @@ enum class SpecialIdState { Unresolved = -1 }; constexpr TypeId unresolvedTypeId = TypeId::createSpecialState(SpecialIdState::Unresolved); +namespace { class UnresolvedTypeId : public TypeId { public: @@ -33,6 +34,25 @@ public: } }; +auto createSingletonTypeTraitMask() +{ + Storage::TypeTraits traits; + traits.type = 0; + traits.isSingleton = true; + + return traits.type; +} + +auto createSingletonTraitsExpression() +{ + Utils::SmallString traitsExpression = "traits & "; + traitsExpression.append(Utils::SmallString::number(createSingletonTypeTraitMask())); + + return traitsExpression; +} + +} // namespace + struct ProjectStorage::Statements { Statements(Sqlite::Database &database) @@ -874,6 +894,14 @@ struct ProjectStorage::Statements " propertyImportedTypeNameId IS NULL " "LIMIT 1", database}; + mutable Sqlite::ReadStatement<1, 1> selectSingletonTypeIdsBySourceIdStatement{ + "SELECT DISTINCT typeId " + "FROM types " + " JOIN exportedTypeNames USING (typeId) " + " JOIN documentImports AS di USING(moduleId) " + "WHERE di.sourceId=?1 AND " + + createSingletonTraitsExpression(), + database}; }; class ProjectStorage::Initializer @@ -909,7 +937,7 @@ public: typesTable.addColumn("typeId", Sqlite::StrictColumnType::Integer, {Sqlite::PrimaryKey{}}); auto &sourceIdColumn = typesTable.addColumn("sourceId", Sqlite::StrictColumnType::Integer); auto &typesNameColumn = typesTable.addColumn("name", Sqlite::StrictColumnType::Text); - typesTable.addColumn("traits", Sqlite::StrictColumnType::Integer); + auto &traitsColumn = typesTable.addColumn("traits", Sqlite::StrictColumnType::Integer); auto &prototypeIdColumn = typesTable.addColumn("prototypeId", Sqlite::StrictColumnType::Integer); auto &prototypeNameIdColumn = typesTable.addColumn("prototypeNameId", @@ -927,6 +955,9 @@ public: typesTable.addIndex({extensionIdColumn, sourceIdColumn}); typesTable.addIndex({prototypeNameIdColumn}); typesTable.addIndex({extensionNameIdColumn}); + Utils::SmallString traitsExpression = "traits & "; + traitsExpression.append(Utils::SmallString::number(createSingletonTypeTraitMask())); + typesTable.addIndex({traitsColumn}, traitsExpression); typesTable.initialize(database); @@ -1453,8 +1484,23 @@ QVarLengthArray ProjectStorage::typeIds(ModuleId moduleId) const projectStorageCategory(), keyValue("module id", moduleId)}; - auto typeIds = s->selectTypeIdsByModuleIdStatement - .valuesWithTransaction>(moduleId); + auto typeIds = s->selectTypeIdsByModuleIdStatement.valuesWithTransaction>( + moduleId); + + tracer.end(keyValue("type ids", typeIds)); + + return typeIds; +} + +SmallTypeIds<256> ProjectStorage::singletonTypeIds(SourceId sourceId) const +{ + using NanotraceHR::keyValue; + NanotraceHR::Tracer tracer{"get singleton type ids by source id", + projectStorageCategory(), + keyValue("source id", sourceId)}; + + auto typeIds = s->selectSingletonTypeIdsBySourceIdStatement.valuesWithTransaction>( + sourceId); tracer.end(keyValue("type ids", typeIds)); diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h index b98ffcfece2..b3723bfa01d 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorage.h @@ -70,7 +70,9 @@ public: TypeId typeId(ImportedTypeNameId typeNameId) const override; - QVarLengthArray typeIds(ModuleId moduleId) const override; + SmallTypeIds<256> typeIds(ModuleId moduleId) const override; + + SmallTypeIds<256> singletonTypeIds(SourceId sourceId) const override; Storage::Info::ExportedTypeNames exportedTypeNames(TypeId typeId) const override; diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h index 4d840d2a5c5..69674ffc8bf 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageinterface.h @@ -40,7 +40,8 @@ public: Storage::Version version) const = 0; virtual TypeId typeId(ImportedTypeNameId typeNameId) const = 0; - virtual QVarLengthArray typeIds(ModuleId moduleId) const = 0; + virtual SmallTypeIds<256> typeIds(ModuleId moduleId) const = 0; + virtual SmallTypeIds<256> singletonTypeIds(SourceId sourceId) const = 0; virtual Storage::Info::ExportedTypeNames exportedTypeNames(TypeId typeId) const = 0; virtual Storage::Info::ExportedTypeNames exportedTypeNames(TypeId typeId, SourceId sourceId) const diff --git a/tests/unit/tests/mocks/projectstoragemock.h b/tests/unit/tests/mocks/projectstoragemock.h index 9e06db5aef5..6131924db16 100644 --- a/tests/unit/tests/mocks/projectstoragemock.h +++ b/tests/unit/tests/mocks/projectstoragemock.h @@ -153,10 +153,14 @@ public: ::Utils::SmallStringView exportedTypeName, QmlDesigner::Storage::Version version), (const, override)); - MOCK_METHOD((QVarLengthArray), + MOCK_METHOD((QmlDesigner::SmallTypeIds<256>), typeIds, (QmlDesigner::ModuleId moduleId), (const, override)); + MOCK_METHOD((QmlDesigner::SmallTypeIds<256>), + singletonTypeIds, + (QmlDesigner::SourceId sourceId), + (const, override)); MOCK_METHOD(QmlDesigner::Storage::Info::ExportedTypeNames, exportedTypeNames, (QmlDesigner::TypeId), diff --git a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp index 521381aa840..45b7e146756 100644 --- a/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp +++ b/tests/unit/tests/unittests/projectstorage/projectstorage-test.cpp @@ -8835,4 +8835,52 @@ TEST_F(ProjectStorage, changed_export_is_notifing_changed_exported_types) storage.synchronize(std::move(package)); } + +TEST_F(ProjectStorage, get_unqiue_singleton_type_ids) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types.back().traits.isSingleton = true; + Storage::Imports imports; + imports.emplace_back(qmlModuleId, Storage::Version{}, sourceId5); + imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId5); + storage.synchronizeDocumentImports(imports, sourceId5); + storage.synchronize(package); + + auto singletonTypeIds = storage.singletonTypeIds(sourceId5); + + ASSERT_THAT(singletonTypeIds, ElementsAre(fetchTypeId(sourceId2, "QObject"))); +} + +TEST_F(ProjectStorage, get_only_singleton_type_ids_for_document_imports) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types.back().traits.isSingleton = true; + package.types.front().traits.isSingleton = true; + Storage::Imports imports; + imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId5); + storage.synchronizeDocumentImports(imports, sourceId5); + storage.synchronize(package); + + auto singletonTypeIds = storage.singletonTypeIds(sourceId5); + + ASSERT_THAT(singletonTypeIds, ElementsAre(fetchTypeId(sourceId1, "QQuickItem"))); +} + +TEST_F(ProjectStorage, get_only_singleton_type_ids_exported_types) +{ + auto package{createSimpleSynchronizationPackage()}; + package.types.back().traits.isSingleton = true; + package.types.back().exportedTypes.clear(); + package.types.front().traits.isSingleton = true; + Storage::Imports imports; + imports.emplace_back(qmlModuleId, Storage::Version{}, sourceId5); + imports.emplace_back(qtQuickModuleId, Storage::Version{}, sourceId5); + storage.synchronizeDocumentImports(imports, sourceId5); + storage.synchronize(package); + + auto singletonTypeIds = storage.singletonTypeIds(sourceId5); + + ASSERT_THAT(singletonTypeIds, ElementsAre(fetchTypeId(sourceId1, "QQuickItem"))); +} + } // namespace From ae1de420939f42c4eaf539ece4e5c5c3f6090f05 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 10 Sep 2024 18:26:08 +0200 Subject: [PATCH 170/193] QmlDesigner: Add singleton getter to model Task-number: QDS-13601 Change-Id: Iaf97f18f98435b05a801453a7d253eba73eaa237 Reviewed-by: Tim Jenssen --- .../libs/designercore/include/model.h | 8 +++++++- .../libs/designercore/include/nodemetainfo.h | 2 ++ .../libs/designercore/model/model.cpp | 17 +++++++++++++---- tests/unit/tests/unittests/model/model-test.cpp | 12 +++++++++++- 4 files changed, 33 insertions(+), 6 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/include/model.h b/src/plugins/qmldesigner/libs/designercore/include/model.h index 534c0d7ed00..48ec5c7c4c0 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/model.h +++ b/src/plugins/qmldesigner/libs/designercore/include/model.h @@ -59,6 +59,8 @@ class TextModifier; class ItemLibraryEntry; using PropertyListType = QList>; +template +using SmallNodeMetaInfos = QVarLengthArray; enum class BypassModelResourceManagement { No, Yes }; @@ -201,7 +203,11 @@ public: NodeMetaInfo vector2dMetaInfo() const; NodeMetaInfo vector3dMetaInfo() const; NodeMetaInfo vector4dMetaInfo() const; - QVarLengthArray metaInfosForModule(Module module) const; + +#ifdef QDS_USE_PROJECTSTORAGE + SmallNodeMetaInfos<256> metaInfosForModule(Module module) const; + SmallNodeMetaInfos<256> singletonMetaInfos() const; +#endif QList itemLibraryEntries() const; diff --git a/src/plugins/qmldesigner/libs/designercore/include/nodemetainfo.h b/src/plugins/qmldesigner/libs/designercore/include/nodemetainfo.h index 43c2eebb651..149adfc37e9 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/nodemetainfo.h +++ b/src/plugins/qmldesigner/libs/designercore/include/nodemetainfo.h @@ -293,6 +293,8 @@ private: }; using NodeMetaInfos = std::vector; +template +using SmallNodeMetaInfos = QVarLengthArray; } //QmlDesigner diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index f77bab2a3c4..ed933550008 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -2726,18 +2726,27 @@ NodeMetaInfo Model::vector4dMetaInfo() const } } +#ifdef QDS_USE_PROJECTSTORAGE + QVarLengthArray Model::metaInfosForModule(Module module) const { - if constexpr (useProjectStorage()) { using namespace Storage::Info; return Utils::transform>( d->projectStorage->typeIds(module.id()), NodeMetaInfo::bind(d->projectStorage)); - } else { - return {}; - } } +SmallNodeMetaInfos<256> Model::singletonMetaInfos() const +{ + using namespace Storage::Info; + + return Utils::transform>(d->projectStorage->singletonTypeIds( + d->m_sourceId), + NodeMetaInfo::bind(d->projectStorage)); +} + +#endif + QList Model::itemLibraryEntries() const { #ifdef QDS_USE_PROJECTSTORAGE diff --git a/tests/unit/tests/unittests/model/model-test.cpp b/tests/unit/tests/unittests/model/model-test.cpp index 4ea64c3ba33..b6d453e74de 100644 --- a/tests/unit/tests/unittests/model/model-test.cpp +++ b/tests/unit/tests/unittests/model/model-test.cpp @@ -1095,13 +1095,23 @@ TEST_F(Model_MetaInfo, meta_infos_for_mdoule) auto module = model.module("Foo", ModuleKind::QmlLibrary); auto typeId = projectStorageMock.createObject(module.id(), "Bar"); ON_CALL(projectStorageMock, typeIds(module.id())) - .WillByDefault(Return(QVarLengthArray{typeId})); + .WillByDefault(Return(QmlDesigner::SmallTypeIds<256>{typeId})); auto types = model.metaInfosForModule(module); ASSERT_THAT(types, ElementsAre(Eq(QmlDesigner::NodeMetaInfo{typeId, &projectStorageMock}))); } +TEST_F(Model_MetaInfo, singleton_meta_infos) +{ + ON_CALL(projectStorageMock, singletonTypeIds(filePathId)) + .WillByDefault(Return(QmlDesigner::SmallTypeIds<256>{itemTypeId})); + + auto types = model.singletonMetaInfos(); + + ASSERT_THAT(types, ElementsAre(Eq(QmlDesigner::NodeMetaInfo{itemTypeId, &projectStorageMock}))); +} + TEST_F(Model_MetaInfo, create_node_resolved_meta_type) { auto node = model.createModelNode("Item"); From 38b215097032f4d19831ccaeae14dc4ef5da070e Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 11 Sep 2024 17:15:06 +0200 Subject: [PATCH 171/193] QmlDesigner: Integrate Model::singletonMetaInfos() THe backend model is removed because it is not anymore used. Task-number: QDS-13603 Change-Id: I9e9857e8698d450e81246009d6f463c50d4ae392 Reviewed-by: Tim Jenssen --- src/plugins/qmldesigner/CMakeLists.txt | 1 - .../components/bindingeditor/actioneditor.cpp | 37 +- .../bindingeditor/bindingeditor.cpp | 24 +- .../connectioneditor/backendmodel.cpp | 318 ------------------ .../connectioneditor/backendmodel.h | 48 --- .../connectioneditorutils.cpp | 66 +++- .../connectioneditor/connectioneditorutils.h | 2 + .../connectioneditor/connectionmodel.cpp | 212 +++++++----- .../connectioneditor/connectionview.cpp | 18 - .../connectioneditor/connectionview.h | 4 - .../instances/nodeinstanceview.cpp | 2 + .../libs/designercore/include/nodemetainfo.h | 2 +- .../libs/designercore/include/rewriterview.h | 2 + .../designercore/metainfo/nodemetainfo.cpp | 2 +- .../designercore/rewriter/rewriterview.cpp | 2 + 15 files changed, 256 insertions(+), 484 deletions(-) delete mode 100644 src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp delete mode 100644 src/plugins/qmldesigner/components/connectioneditor/backendmodel.h diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index e6081e954de..6ec60cc2159 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -558,7 +558,6 @@ extend_qtc_plugin(QmlDesigner SOURCES_PREFIX components/connectioneditor SOURCES addnewbackenddialog.cpp addnewbackenddialog.h addnewbackenddialog.ui - backendmodel.cpp backendmodel.h bindingmodel.cpp bindingmodel.h bindingmodelitem.cpp bindingmodelitem.h connectioneditor.qrc diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp index bd63742d5e7..f226fa0798e 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp @@ -305,6 +305,31 @@ void ActionEditor::prepareConnections() } // Singletons +#ifdef QDS_USE_PROJECTSTORAGE + if (auto model = m_modelNode.model()) { + for (const auto &metaInfo : model->singletonMetaInfos()) { + if (metaInfo.isValid()) { + ActionEditorDialog::SingletonOption singelton; + for (const auto &property : metaInfo.properties()) { + if (isSkippedType(property.propertyType())) + continue; + auto exportedTypeName = model + ->exportedTypeNameForMetaInfo(property.propertyType()) + .name.toQByteArray(); + singelton.properties.append( + ActionEditorDialog::PropertyOption(QString::fromUtf8(property.name()), + exportedTypeName, + property.isWritable())); + } + + if (!singelton.properties.isEmpty()) { + singelton.item = metaInfo.displayName(); + singletons.append(singelton); + } + } + } + } +#else if (RewriterView *rv = m_modelNode.view()->rewriterView()) { for (const QmlTypeData &data : rv->getQMLTypes()) { if (!data.typeName.isEmpty()) { @@ -314,21 +339,10 @@ void ActionEditor::prepareConnections() for (const auto &property : metaInfo.properties()) { if (isSkippedType(property.propertyType())) continue; -#ifdef QDS_USE_PROJECTSTORAGE - auto exportedTypeName = model - ->exportedTypeNameForMetaInfo( - property.propertyType()) - .name.toQByteArray(); - singelton.properties.append( - ActionEditorDialog::PropertyOption(QString::fromUtf8(property.name()), - exportedTypeName, - property.isWritable())); -#else singelton.properties.append(ActionEditorDialog::PropertyOption( QString::fromUtf8(property.name()), skipCpp(property.propertyType().typeName()), property.isWritable())); -#endif } if (!singelton.properties.isEmpty()) { @@ -339,6 +353,7 @@ void ActionEditor::prepareConnections() } } } +#endif // States for (const QmlModelState &state : QmlItemNode(m_modelNode.view()->rootModelNode()).states().allStates()) diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp index 6a77b6235eb..bb98db869c4 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp @@ -246,6 +246,26 @@ void BindingEditor::prepareBindings() } //singletons: +#ifdef QDS_USE_PROJECTSTORAGE + if (auto model = m_modelNode.view()->model()) { + for (const auto &metaInfo : model->singletonMetaInfos()) { + BindingEditorDialog::BindingOption binding; + + for (const auto &property : metaInfo.properties()) { + const auto propertyType = property.propertyType(); + + if (compareTypes(m_backendValueType, propertyType)) { + binding.properties.append(QString::fromUtf8(property.name())); + } + } + + if (!binding.properties.isEmpty()) { + binding.item = metaInfo.displayName(); + bindings.append(binding); + } + } + } +#else if (RewriterView *rv = m_modelNode.view()->rewriterView()) { for (const QmlTypeData &data : rv->getQMLTypes()) { if (!data.typeName.isEmpty()) { @@ -270,7 +290,7 @@ void BindingEditor::prepareBindings() } } } - +#endif if (!bindings.isEmpty() && m_dialog) m_dialog->setAllBindings(bindings, m_backendValueType); } @@ -289,7 +309,7 @@ void BindingEditor::updateWindowName() } else { #ifdef QDS_USE_PROJECTSTORAGE targetString = " [" + (m_targetName.isEmpty() ? QString() : (m_targetName + ": ")) - + QString::fromUtf8(m_backendValueType.displayName()) + "]"; + + m_backendValueType.displayName() + "]"; #else targetString = " [" + (m_targetName.isEmpty() ? QString() : (m_targetName + ": ")) + QString::fromUtf8(m_backendValueType.simplifiedTypeName()) + "]"; diff --git a/src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp deleted file mode 100644 index 398fa968e45..00000000000 --- a/src/plugins/qmldesigner/components/connectioneditor/backendmodel.cpp +++ /dev/null @@ -1,318 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include - -#include "backendmodel.h" - -#include "bindingproperty.h" -#include "connectioneditorutils.h" -#include "connectionview.h" -#include "exception.h" -#include "nodemetainfo.h" -#include "nodeproperty.h" -#include "rewriterview.h" - -#include "addnewbackenddialog.h" - -#include -#include - -namespace QmlDesigner { - -BackendModel::BackendModel(ConnectionView *view) - : m_connectionView(view) -{ - connect(this, &QStandardItemModel::dataChanged, this, &BackendModel::handleDataChanged); -} - -ConnectionView *BackendModel::connectionView() const -{ - return m_connectionView; -} - -void BackendModel::resetModel() -{ - if (!m_connectionView->model()) - return; - - RewriterView *rewriterView = m_connectionView->model()->rewriterView(); - - m_lock = true; - - beginResetModel(); - clear(); - - setHorizontalHeaderLabels(QStringList({ tr("Type"), tr("Name"), tr("Singleton"), tr("Local") })); - - ModelNode rootNode = connectionView()->rootModelNode(); - - static const PropertyTypeList simpleTypes = {"int", "real", "color", "string"}; - - if (rewriterView) - for (const QmlTypeData &cppTypeData : rewriterView->getQMLTypes()) - if (cppTypeData.isSingleton) { - NodeMetaInfo metaInfo = m_connectionView->model()->metaInfo( - cppTypeData.typeName.toUtf8()); - if (metaInfo.isValid() && !metaInfo.isQtQuickItem()) { - auto type = new QStandardItem(cppTypeData.typeName); - type->setData(cppTypeData.typeName, Qt::UserRole + 1); - type->setData(true, Qt::UserRole + 2); - type->setEditable(false); - - auto name = new QStandardItem(cppTypeData.typeName); - name->setEditable(false); - - QStandardItem *singletonItem = new QStandardItem(""); - singletonItem->setCheckState(Qt::Checked); - - singletonItem->setCheckable(true); - singletonItem->setEnabled(false); - - QStandardItem *inlineItem = new QStandardItem(""); - - inlineItem->setCheckState(Qt::Unchecked); - - inlineItem->setCheckable(true); - inlineItem->setEnabled(false); - - appendRow({type, name, singletonItem, inlineItem}); - } - } - - if (rootNode.isValid()) { - const QList properties = rootNode.properties(); - for (const AbstractProperty &property : properties) - if (property.isDynamic() && !simpleTypes.contains(property.dynamicTypeName())) { - - NodeMetaInfo metaInfo = m_connectionView->model()->metaInfo(property.dynamicTypeName()); - if (metaInfo.isValid() && !metaInfo.isQtQuickItem()) { - QStandardItem *type = new QStandardItem(QString::fromUtf8(property.dynamicTypeName())); - type->setEditable(false); - - type->setData(QString::fromUtf8(property.name()), Qt::UserRole + 1); - type->setData(false, Qt::UserRole + 2); - QStandardItem *name = new QStandardItem(QString::fromUtf8(property.name())); - - QStandardItem *singletonItem = new QStandardItem(""); - singletonItem->setCheckState(Qt::Unchecked); - - singletonItem->setCheckable(true); - singletonItem->setEnabled(false); - - QStandardItem *inlineItem = new QStandardItem(""); - - inlineItem->setCheckState(property.isNodeProperty() ? Qt::Checked : Qt::Unchecked); - - inlineItem->setCheckable(true); - inlineItem->setEnabled(false); - - appendRow({ type, name, singletonItem, inlineItem }); - } - } - } - - m_lock = false; - - endResetModel(); -} - -QStringList BackendModel::possibleCppTypes() const -{ - RewriterView *rewriterView = m_connectionView->model()->rewriterView(); - - QStringList list; - - if (rewriterView) { - const QList cppTypes = rewriterView->getQMLTypes(); - for (const QmlTypeData &cppTypeData : cppTypes) - list.append(cppTypeData.typeName); - } - - return list; -} - -QmlTypeData BackendModel::cppTypeDataForType(const QString &typeName) const -{ - RewriterView *rewriterView = m_connectionView->model()->rewriterView(); - - if (!rewriterView) - return QmlTypeData(); - - return Utils::findOr(rewriterView->getQMLTypes(), QmlTypeData(), [&typeName](const QmlTypeData &data) { - return typeName == data.typeName; - }); -} - -void BackendModel::deletePropertyByRow(int rowNumber) -{ - Model *model = m_connectionView->model(); - if (!model) - return; - - /* singleton case remove the import */ - if (data(index(rowNumber, 0), Qt::UserRole + 1).toBool()) { - const QString typeName = data(index(rowNumber, 0), Qt::UserRole + 1).toString(); - QmlTypeData cppTypeData = cppTypeDataForType(typeName); - - if (cppTypeData.isSingleton) { - - Import import = Import::createLibraryImport(cppTypeData.importUrl, cppTypeData.versionString); - - try { - if (model->hasImport(import)) - model->changeImports({}, {import}); - } catch (const Exception &e) { - e.showException(); - } - } - } else { - const QString propertyName = data(index(rowNumber, 0), Qt::UserRole + 1).toString(); - - ModelNode modelNode = connectionView()->rootModelNode(); - - try { - modelNode.removeProperty(propertyName.toUtf8()); - } catch (const Exception &e) { - e.showException(); - } - } - - resetModel(); -} - -void BackendModel::addNewBackend() -{ - Model *model = m_connectionView->model(); - if (!model) - return; - - AddNewBackendDialog dialog(Core::ICore::dialogParent()); - - RewriterView *rewriterView = model->rewriterView(); - - QStringList availableTypes; - - if (rewriterView) - dialog.setupPossibleTypes(Utils::filtered(rewriterView->getQMLTypes(), [model](const QmlTypeData &cppTypeData) { - return !cppTypeData.isSingleton || !model->metaInfo(cppTypeData.typeName.toUtf8()).isValid(); - /* Only show singletons if the import is missing */ - })); - - dialog.exec(); - - if (dialog.applied()) { - QStringList importSplit = dialog.importString().split(" "); - if (importSplit.size() != 2) { - qCWarning(ConnectionEditorLog) << __FUNCTION__ << "invalid import" << importSplit; - QTC_ASSERT(false, return); - } - - QString typeName = dialog.type(); - - Import import = Import::createLibraryImport(importSplit.constFirst(), importSplit.constLast()); - - /* We cannot add an import and add a node from that import in a single transaction. - * We need the import to have the meta info available. - */ - - if (!model->hasImport(import)) - model->changeImports({import}, {}); - - QString propertyName = m_connectionView->model()->generateNewId(typeName); - - NodeMetaInfo metaInfo = model->metaInfo(typeName.toUtf8()); - - QTC_ASSERT(metaInfo.isValid(), return); - - /* Add a property for non singleton types. For singletons just adding the import is enough. */ - if (!dialog.isSingleton()) { - m_connectionView->executeInTransaction("BackendModel::addNewBackend", - [this, metaInfo, typeName, propertyName, &dialog] { - - if (dialog.localDefinition()) { -#ifdef QDS_USE_PROJECTSTORAGE - ModelNode newNode = m_connectionView->createModelNode(typeName.toUtf8()); -#else - int minorVersion = metaInfo.minorVersion(); - int majorVersion = metaInfo.majorVersion(); - ModelNode newNode = m_connectionView->createModelNode(metaInfo.typeName(), - majorVersion, - minorVersion); -#endif - m_connectionView->rootModelNode().nodeProperty(propertyName.toUtf8()).setDynamicTypeNameAndsetModelNode( - typeName.toUtf8(), newNode); - } else { - m_connectionView->rootModelNode().bindingProperty( - propertyName.toUtf8()).setDynamicTypeNameAndExpression(typeName.toUtf8(), "null"); - } - }); - } - } - resetModel(); -} - -void BackendModel::updatePropertyName(int rowNumber) -{ - const PropertyName newName = data(index(rowNumber, 1)).toString().toUtf8(); - const PropertyName oldName = data(index(rowNumber, 0), Qt::UserRole + 1).toString().toUtf8(); - - m_connectionView->executeInTransaction("BackendModel::updatePropertyName", [this, newName, oldName](){ - - ModelNode rootModelNode = m_connectionView->rootModelNode(); - if (rootModelNode.property(oldName).isNodeProperty()) { - - const TypeName typeName = rootModelNode.nodeProperty(oldName).dynamicTypeName(); - const ModelNode targetModelNode = rootModelNode.nodeProperty(oldName).modelNode(); - const TypeName fullTypeName = targetModelNode.type(); - const int majorVersion = targetModelNode.majorVersion(); - const int minorVersion = targetModelNode.minorVersion(); - - rootModelNode.removeProperty(oldName); - ModelNode newNode = m_connectionView->createModelNode(fullTypeName, majorVersion, minorVersion); - m_connectionView->rootModelNode().nodeProperty(newName).setDynamicTypeNameAndsetModelNode(typeName, newNode); - - } else if (rootModelNode.property(oldName).isBindingProperty()) { - const QString expression = rootModelNode.bindingProperty(oldName).expression(); - const TypeName typeName = rootModelNode.bindingProperty(oldName).dynamicTypeName(); - - rootModelNode.removeProperty(oldName); - rootModelNode.bindingProperty(newName).setDynamicTypeNameAndExpression(typeName, expression); - } else { - qCWarning(ConnectionEditorLog) << __FUNCTION__ << oldName << newName << "failed..."; - QTC_ASSERT(false, return); - } - }); -} - -void BackendModel::handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) -{ - if (m_lock) - return; - - if (topLeft != bottomRight) { - qCWarning(ConnectionEditorLog) << __FUNCTION__ << "multi edit?"; - return; - } - - m_lock = true; - - int currentColumn = topLeft.column(); - int currentRow = topLeft.row(); - - switch (currentColumn) { - case 0: { - //updating user data - } break; - case 1: { - updatePropertyName(currentRow); - } break; - - default: - qCWarning(ConnectionEditorLog) << __FUNCTION__ << "column" << currentColumn; - } - - m_lock = false; -} - -} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/connectioneditor/backendmodel.h b/src/plugins/qmldesigner/components/connectioneditor/backendmodel.h deleted file mode 100644 index 9feaff91943..00000000000 --- a/src/plugins/qmldesigner/components/connectioneditor/backendmodel.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once -#include - -#include "rewriterview.h" - -namespace QmlDesigner { - -class ConnectionView; - -class BackendModel : public QStandardItemModel -{ - Q_OBJECT -public: - enum ColumnRoles { - TypeNameColumn = 0, - PropertyNameColumn = 1, - IsSingletonColumn = 2, - IsLocalColumn = 3, - }; - - BackendModel(ConnectionView *view); - - ConnectionView *connectionView() const; - - void resetModel(); - - QStringList possibleCppTypes() const; - QmlTypeData cppTypeDataForType(const QString &typeName) const; - - void deletePropertyByRow(int rowNumber); - - void addNewBackend(); - -protected: - void updatePropertyName(int rowNumber); - -private: - void handleDataChanged(const QModelIndex &topLeft, const QModelIndex& bottomRight); - -private: - ConnectionView *m_connectionView; - bool m_lock = false; -}; - -} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.cpp index b96e000f8cd..fcedbc9876c 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.cpp @@ -277,12 +277,12 @@ std::pair splitExpression(const QString &expression) return {sourceNode, propertyName}; } +#ifndef QDS_USE_PROJECTSTORAGE QStringList singletonsFromView(AbstractView *view) { RewriterView *rv = view->rewriterView(); if (!rv) return {}; - QStringList out; for (const QmlTypeData &data : rv->getQMLTypes()) { if (data.isSingleton && !data.typeName.isEmpty()) @@ -301,6 +301,7 @@ std::vector propertiesFromSingleton(const QString &name, Abstr return {}; } +#endif QList dynamicPropertiesFromNode(const ModelNode &node) { @@ -317,9 +318,30 @@ QList dynamicPropertiesFromNode(const ModelNode &node) return dynamicProperties; } +#ifdef QDS_USE_PROJECTSTORAGE +QStringList availableSources(AbstractView *view) +{ + if (!view->isAttached()) + return {}; + + QStringList sourceNodes; + + for (const auto &metaInfo : view->model()->singletonMetaInfos()) + sourceNodes.push_back(metaInfo.displayName()); + + for (const ModelNode &modelNode : view->allModelNodes()) { + if (auto id = modelNode.id(); !id.isEmpty()) + sourceNodes.append(id); + } + + std::sort(sourceNodes.begin(), sourceNodes.end()); + return sourceNodes; +} +#else QStringList availableSources(AbstractView *view) { QStringList sourceNodes; + for (const ModelNode &modelNode : view->allModelNodes()) { if (!modelNode.id().isEmpty()) sourceNodes.append(modelNode.id()); @@ -327,6 +349,7 @@ QStringList availableSources(AbstractView *view) std::sort(sourceNodes.begin(), sourceNodes.end()); return singletonsFromView(view) + sourceNodes; } +#endif QStringList availableTargetProperties(const BindingProperty &bindingProperty) { @@ -351,6 +374,8 @@ QStringList availableTargetProperties(const BindingProperty &bindingProperty) return {}; } +namespace { + ModelNode getNodeByIdOrParent(AbstractView *view, const QString &id, const ModelNode &targetNode) { if (id != QLatin1String("parent")) @@ -362,6 +387,35 @@ ModelNode getNodeByIdOrParent(AbstractView *view, const QString &id, const Model return {}; } +#ifdef QDS_USE_PROJECTSTORAGE +NodeMetaInfo singletonMetaInfoForId(const QString &id, AbstractView *view) +{ + using Storage::Info::ExportedTypeName; + const auto model = view->model(); + + if (!model) + return {}; + + const Utils::SmallString name = id; + + const auto singletonMetaInfos = model->singletonMetaInfos(); + + const auto sourceId = model->fileUrlSourceId(); + + auto found = std::ranges::find_if(singletonMetaInfos, [&](const auto &metaInfo) { + auto exportedTypeNames = metaInfo.exportedTypeNamesForSourceId(sourceId); + return std::ranges::find(exportedTypeNames, name, &ExportedTypeName::name) + != exportedTypeNames.end(); + }); + + if (found == singletonMetaInfos.end()) + return {}; + + return *found; +} +#endif +} // namespace + QStringList availableSourceProperties(const QString &id, const BindingProperty &targetProperty, AbstractView *view) @@ -378,6 +432,15 @@ QStringList availableSourceProperties(const QString &id, QStringList possibleProperties; if (!modelNode.isValid()) { +#ifdef QDS_USE_PROJECTSTORAGE + if (auto singletonMetaInfo = singletonMetaInfoForId(id, view)) { + for (const auto &property : singletonMetaInfo.properties()) { + if (metaInfoIsCompatible(targetType, property)) + possibleProperties.push_back(QString::fromUtf8(property.name())); + } + return possibleProperties; + } +#else QStringList singletons = singletonsFromView(view); if (singletons.contains(id)) { for (const auto &property : propertiesFromSingleton(id, view)) { @@ -386,6 +449,7 @@ QStringList availableSourceProperties(const QString &id, } return possibleProperties; } +#endif qCWarning(ConnectionEditorLog) << __FUNCTION__ << "invalid model node:" << id; return {}; } diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.h b/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.h index 501968a642a..220fdc9e11d 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.h +++ b/src/plugins/qmldesigner/components/connectioneditor/connectioneditorutils.h @@ -40,8 +40,10 @@ QVariant defaultValueForType(const TypeName &type); QString defaultExpressionForType(const TypeName &type); std::pair splitExpression(const QString &expression); +#ifndef QDS_USE_PROJECTSTORAGE QStringList singletonsFromView(AbstractView *view); std::vector propertiesFromSingleton(const QString &name, AbstractView *view); +#endif QList dynamicPropertiesFromNode(const ModelNode &node); QStringList availableSources(AbstractView *view); diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp index 5d94ca85867..6fd43f9c37f 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp @@ -40,10 +40,10 @@ const char defaultCondition[] = "condition"; QStringList propertyNameListToStringList(const QmlDesigner::PropertyNameList &propertyNameList) { QStringList stringList; + stringList.reserve(propertyNameList.size()); for (const QmlDesigner::PropertyName &propertyName : propertyNameList) - stringList << QString::fromUtf8(propertyName); + stringList.push_back(QString::fromUtf8(propertyName)); - stringList.removeDuplicates(); return stringList; } @@ -206,6 +206,62 @@ void ConnectionModel::updateSignalName(int rowNumber) } } +namespace { +#ifdef QDS_USE_PROJECTSTORAGE +bool isSingleton(AbstractView *view, bool isAlias, QStringView newTarget) +{ + using Storage::Info::ExportedTypeName; + + auto model = view->model(); + + if (!model) + return false; + + const auto sourceId = model->fileUrlSourceId(); + const Utils::SmallString name = newTarget; + const Utils::SmallString aliasName = newTarget.split(u'.').front(); + auto hasTargetExportedTypeName = [&](const auto &metaInfo) { + const auto exportedTypeNames = metaInfo.exportedTypeNamesForSourceId(sourceId); + if (std::ranges::find(exportedTypeNames, name, &ExportedTypeName::name) + != exportedTypeNames.end()) + return true; + if (isAlias) { + if (std::ranges::find(exportedTypeNames, aliasName, &ExportedTypeName::name) + != exportedTypeNames.end()) + return true; + } + return false; + }; + + auto singletonMetaInfos = model->singletonMetaInfos(); + return std::ranges::find_if(singletonMetaInfos, hasTargetExportedTypeName) + != singletonMetaInfos.end(); +} +#else +bool isSingleton(AbstractView *view, bool isAlias, const QString &newTarget) +{ + if (RewriterView *rv = view->rewriterView()) { + for (const QmlTypeData &data : rv->getQMLTypes()) { + if (!data.typeName.isEmpty()) { + if (data.typeName == newTarget) { + if (view->model()->metaInfo(data.typeName.toUtf8()).isValid()) + return true; + + } else if (isAlias) { + if (data.typeName == newTarget.split(".").constFirst()) { + if (view->model()->metaInfo(data.typeName.toUtf8()).isValid()) + return true; + } + } + } + } + } + + return false; +} +#endif +} // namespace + void ConnectionModel::updateTargetNode(int rowNumber) { SignalHandlerProperty signalHandlerProperty = signalHandlerPropertyForRow(rowNumber); @@ -213,27 +269,7 @@ void ConnectionModel::updateTargetNode(int rowNumber) ModelNode connectionNode = signalHandlerProperty.parentModelNode(); const bool isAlias = newTarget.contains("."); - bool isSingleton = false; - - if (RewriterView* rv = connectionView()->rewriterView()) { - for (const QmlTypeData &data : rv->getQMLTypes()) { - if (!data.typeName.isEmpty()) { - if (data.typeName == newTarget) { - if (connectionView()->model()->metaInfo(data.typeName.toUtf8()).isValid()) { - isSingleton = true; - break; - } - } else if (isAlias) { - if (data.typeName == newTarget.split(".").constFirst()) { - if (connectionView()->model()->metaInfo(data.typeName.toUtf8()).isValid()) { - isSingleton = true; - break; - } - } - } - } - } - } + bool isSingleton = QmlDesigner::isSingleton(m_connectionView, isAlias, newTarget); if (!newTarget.isEmpty()) { //if it's a singleton, then let's reparent connections to rootNode, @@ -595,78 +631,96 @@ QStringList ConnectionModel::getflowActionTriggerForRow(int row) const return stringList; } +namespace {} + QStringList ConnectionModel::getPossibleSignalsForConnection(const ModelNode &connection) const { + if (!connection) + return {}; + QStringList stringList; - auto getAliasMetaSignals = [&](QString aliasPart, NodeMetaInfo metaInfo) { - if (metaInfo.isValid() && metaInfo.hasProperty(aliasPart.toUtf8())) { - NodeMetaInfo propertyMetaInfo = metaInfo.property(aliasPart.toUtf8()).propertyType(); - if (propertyMetaInfo.isValid()) { - return propertyNameListToStringList(propertyMetaInfo.signalNames()); - } - } - return QStringList(); + auto getAliasMetaSignals = [&](PropertyNameView aliasPart, NodeMetaInfo metaInfo) -> QStringList { + if (NodeMetaInfo propertyMetaInfo = metaInfo.property(aliasPart).propertyType()) + return propertyNameListToStringList(propertyMetaInfo.signalNames()); + + return {}; }; - if (connection.isValid()) { - //separate check for singletons - if (connection.hasBindingProperty("target")) { - const BindingProperty bp = connection.bindingProperty("target"); + //separate check for singletons + if (const BindingProperty bp = connection.bindingProperty("target")) { +#ifdef QDS_USE_PROJECTSTORAGE + if (auto model = m_connectionView->model()) { + const Utils::SmallString bindExpression = bp.expression(); + using Storage::Info::ExportedTypeName; + const auto sourceId = model->fileUrlSourceId(); + for (const auto &metaInfo : model->singletonMetaInfos()) { + const auto exportedTypeNames = metaInfo.exportedTypeNamesForSourceId(sourceId); + if (std::ranges::find(exportedTypeNames, bindExpression, &ExportedTypeName::name) + != exportedTypeNames.end()) { + stringList.append(propertyNameListToStringList(metaInfo.signalNames())); + } else { + std::string_view expression = bindExpression; + auto index = expression.find('.'); + if (index == std::string_view::npos) + continue; - if (bp.isValid()) { - const QString bindExpression = bp.expression(); + expression.remove_prefix(index); - if (const RewriterView * const rv = connectionView()->rewriterView()) { - for (const QmlTypeData &data : rv->getQMLTypes()) { - if (!data.typeName.isEmpty()) { - if (data.typeName == bindExpression) { - NodeMetaInfo metaInfo = connectionView()->model()->metaInfo(data.typeName.toUtf8()); - if (metaInfo.isValid()) { - stringList << propertyNameListToStringList(metaInfo.signalNames()); - break; - } - } else if (bindExpression.contains(".")) { - //if it doesn't fit the same name, maybe it's an alias? - QStringList expression = bindExpression.split("."); - if ((expression.size() > 1) && (expression.constFirst() == data.typeName)) { - expression.removeFirst(); + stringList.append(getAliasMetaSignals(expression, metaInfo)); + } + } + } +#else + const QString bindExpression = bp.expression(); - stringList << getAliasMetaSignals( - expression.join("."), - connectionView()->model()->metaInfo(data.typeName.toUtf8())); - break; - } - } + if (const RewriterView *const rv = connectionView()->rewriterView()) { + for (const QmlTypeData &data : rv->getQMLTypes()) { + if (!data.typeName.isEmpty()) { + if (data.typeName == bindExpression) { + NodeMetaInfo metaInfo = connectionView()->model()->metaInfo( + data.typeName.toUtf8()); + if (metaInfo.isValid()) { + stringList << propertyNameListToStringList(metaInfo.signalNames()); + break; + } + } else if (bindExpression.contains(".")) { + //if it doesn't fit the same name, maybe it's an alias? + QStringList expression = bindExpression.split("."); + if ((expression.size() > 1) && (expression.constFirst() == data.typeName)) { + expression.removeFirst(); + + stringList << getAliasMetaSignals(expression.join(".").toUtf8(), + connectionView()->model()->metaInfo( + data.typeName.toUtf8())); + break; } } } } } +#endif + std::ranges::sort(stringList); + stringList.erase(std::ranges::unique(stringList).begin(), stringList.end()); + } - ModelNode targetNode = getTargetNodeForConnection(connection); - if (targetNode.isValid() && targetNode.metaInfo().isValid()) { - stringList.append(propertyNameListToStringList(targetNode.metaInfo().signalNames())); - } else { - //most likely it's component's internal alias: + ModelNode targetNode = getTargetNodeForConnection(connection); + if (auto metaInfo = targetNode.metaInfo()) { + stringList.append(propertyNameListToStringList(metaInfo.signalNames())); + } else { + //most likely it's component's internal alias: - if (connection.hasBindingProperty("target")) { - const BindingProperty bp = connection.bindingProperty("target"); - - if (bp.isValid()) { - QStringList expression = bp.expression().split("."); - if (expression.size() > 1) { - const QString itemId = expression.constFirst(); - if (connectionView()->hasId(itemId)) { - ModelNode parentItem = connectionView()->modelNodeForId(itemId); - if (parentItem.isValid() - && parentItem.hasMetaInfo() - && parentItem.metaInfo().isValid()) { - expression.removeFirst(); - stringList << getAliasMetaSignals(expression.join("."), - parentItem.metaInfo()); - } - } + if (const BindingProperty bp = connection.bindingProperty("target")) { + QStringList expression = bp.expression().split("."); + if (expression.size() > 1) { + const QString itemId = expression.constFirst(); + if (connectionView()->hasId(itemId)) { + ModelNode parentItem = connectionView()->modelNodeForId(itemId); + if (parentItem.isValid() && parentItem.hasMetaInfo() + && parentItem.metaInfo().isValid()) { + expression.removeFirst(); + stringList << getAliasMetaSignals(expression.join(".").toUtf8(), + parentItem.metaInfo()); } } } diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp index 8f0c9ebe62e..47d70395ba7 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionview.cpp @@ -3,7 +3,6 @@ #include "connectionview.h" -#include "backendmodel.h" #include "bindingmodel.h" #include "connectionmodel.h" #include "dynamicpropertiesmodel.h" @@ -146,7 +145,6 @@ struct ConnectionView::ConnectionViewData : connectionModel{view} , bindingModel{view} , dynamicPropertiesModel{false, view} - , backendModel{view} , propertyTreeModel{view} , connectionViewQuickWidget{Utils::makeUniqueObjectPtr( view, &connectionModel, &bindingModel, &dynamicPropertiesModel)} @@ -155,7 +153,6 @@ struct ConnectionView::ConnectionViewData ConnectionModel connectionModel; BindingModel bindingModel; DynamicPropertiesModel dynamicPropertiesModel; - BackendModel backendModel; PropertyTreeModel propertyTreeModel; int currentIndex = 0; @@ -177,7 +174,6 @@ void ConnectionView::modelAttached(Model *model) d->bindingModel.reset(); d->dynamicPropertiesModel.reset(); d->connectionModel.resetModel(); - d->backendModel.resetModel(); } void ConnectionView::modelAboutToBeDetached(Model *model) @@ -249,8 +245,6 @@ void ConnectionView::variantPropertiesChanged(const QList &prop for (const VariantProperty &variantProperty : propertyList) { if (variantProperty.isDynamic()) d->dynamicPropertiesModel.updateItem(variantProperty); - if (variantProperty.isDynamic() && variantProperty.parentModelNode().isRootNode()) - d->backendModel.resetModel(); d->connectionModel.variantPropertyChanged(variantProperty); @@ -265,8 +259,6 @@ void ConnectionView::bindingPropertiesChanged(const QList &prop d->bindingModel.updateItem(bindingProperty); if (bindingProperty.isDynamic()) d->dynamicPropertiesModel.updateItem(bindingProperty); - if (bindingProperty.isDynamic() && bindingProperty.parentModelNode().isRootNode()) - d->backendModel.resetModel(); d->connectionModel.bindingPropertyChanged(bindingProperty); @@ -288,11 +280,6 @@ void ConnectionView::selectedNodesChanged(const QList & selectedNodeL d->dynamicPropertiesModel.reset(); } -void ConnectionView::importsChanged(const Imports & /*addedImports*/, const Imports & /*removedImports*/) -{ - d->backendModel.resetModel(); -} - void ConnectionView::currentStateChanged(const ModelNode &) { d->dynamicPropertiesModel.reset(); @@ -332,11 +319,6 @@ DynamicPropertiesModel *ConnectionView::dynamicPropertiesModel() const return &d->dynamicPropertiesModel; } -BackendModel *ConnectionView::backendModel() const -{ - return &d->backendModel; -} - int ConnectionView::currentIndex() const { return d->currentIndex; diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionview.h b/src/plugins/qmldesigner/components/connectioneditor/connectionview.h index 1cf3aa26dd1..debf78ae2e7 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionview.h +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionview.h @@ -21,7 +21,6 @@ class ConnectionViewWidget; class BindingModel; class ConnectionModel; class DynamicPropertiesModel; -class BackendModel; class ConnectionViewQuickWidget; class PropertyTreeModel; class PropertyListProxyModel; @@ -55,8 +54,6 @@ public: void selectedNodesChanged(const QList &selectedNodeList, const QList &lastSelectedNodeList) override; - void importsChanged(const Imports &addedImports, const Imports &removedImports) override; - void currentStateChanged(const ModelNode &node) override; WidgetInfo widgetInfo() override; @@ -67,7 +64,6 @@ public: ConnectionModel *connectionModel() const; BindingModel *bindingModel() const; - BackendModel *backendModel() const; int currentIndex() const; void setCurrentIndex(int i); diff --git a/src/plugins/qmldesigner/instances/nodeinstanceview.cpp b/src/plugins/qmldesigner/instances/nodeinstanceview.cpp index 60802c95aa3..cb2f5b3420d 100644 --- a/src/plugins/qmldesigner/instances/nodeinstanceview.cpp +++ b/src/plugins/qmldesigner/instances/nodeinstanceview.cpp @@ -1208,6 +1208,7 @@ CreateSceneCommand NodeInstanceView::createCreateSceneCommand() QVector mockupTypesVector; +#ifndef QDS_USE_PROJECTSTORAGE for (const QmlTypeData &cppTypeData : model()->rewriterView()->getQMLTypes()) { const QString versionString = cppTypeData.versionString; int majorVersion = -1; @@ -1242,6 +1243,7 @@ CreateSceneCommand NodeInstanceView::createCreateSceneCommand() mockupTypesVector.append(mockupType); } } +#endif QString lastUsedLanguage; if (auto multiLanguageAspect = QmlProjectManager::QmlMultiLanguageAspect::current(m_currentTarget)) diff --git a/src/plugins/qmldesigner/libs/designercore/include/nodemetainfo.h b/src/plugins/qmldesigner/libs/designercore/include/nodemetainfo.h index 149adfc37e9..fdb29cb10f3 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/nodemetainfo.h +++ b/src/plugins/qmldesigner/libs/designercore/include/nodemetainfo.h @@ -117,7 +117,7 @@ public: bool defaultPropertyIsComponent() const; - TypeName displayName() const; + QString displayName() const; DEPRECATED_TYPENAME TypeName typeName() const; DEPRECATED_TYPENAME TypeName simplifiedTypeName() const; DEPRECATED_VERSION_NUMBER int majorVersion() const; diff --git a/src/plugins/qmldesigner/libs/designercore/include/rewriterview.h b/src/plugins/qmldesigner/libs/designercore/include/rewriterview.h index 81c2a057380..1fdb6837238 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/rewriterview.h +++ b/src/plugins/qmldesigner/libs/designercore/include/rewriterview.h @@ -143,7 +143,9 @@ public: QStringList autoComplete(const QString &text, int pos, bool explicitComplete = true); +#ifndef QDS_USE_PROJECTSTORAGE QList getQMLTypes() const; +#endif void setWidgetStatusCallback(std::function setWidgetStatusCallback); diff --git a/src/plugins/qmldesigner/libs/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/libs/designercore/metainfo/nodemetainfo.cpp index d276f555337..e340bc2c357 100644 --- a/src/plugins/qmldesigner/libs/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/libs/designercore/metainfo/nodemetainfo.cpp @@ -2106,7 +2106,7 @@ bool NodeMetaInfo::defaultPropertyIsComponent() const } } -TypeName NodeMetaInfo::displayName() const +QString NodeMetaInfo::displayName() const { return {}; } diff --git a/src/plugins/qmldesigner/libs/designercore/rewriter/rewriterview.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriterview.cpp index b79ddcbe087..dd55bd2ef67 100644 --- a/src/plugins/qmldesigner/libs/designercore/rewriter/rewriterview.cpp +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/rewriterview.cpp @@ -1102,6 +1102,7 @@ QStringList RewriterView::autoComplete(const QString &text, int pos, bool explic return list; } +#ifndef QDS_USE_PROJECTSTORAGE QList RewriterView::getQMLTypes() const { QList qmlDataList; @@ -1127,6 +1128,7 @@ QList RewriterView::getQMLTypes() const return qmlDataList; } +#endif void RewriterView::setWidgetStatusCallback(std::function setWidgetStatusCallback) { From dffad8e859695bdd7ffbeb0adfd0ce4a6a85def1 Mon Sep 17 00:00:00 2001 From: Pranta Dastider Date: Mon, 12 Aug 2024 13:48:41 +0200 Subject: [PATCH 172/193] QmlDesigner: Update the Qt runtime versions document Qt Design Studio uses a specific Qt Runtime version to run the projects. This update include the Qt runtime versions used for QDS 4.6 releases in the document. Fixes: QDS-12880 Change-Id: I61d3591ec5e101af6757c61af15f8a14bee8a2ee Reviewed-by: Thomas Hartmann --- .../src/qtdesignstudio-finding-qt-runtime-version.qdoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/qtdesignstudio/src/qtdesignstudio-finding-qt-runtime-version.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-finding-qt-runtime-version.qdoc index 5f2bc9bdada..10f780ce468 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-finding-qt-runtime-version.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-finding-qt-runtime-version.qdoc @@ -37,5 +37,8 @@ \row \li 4.5 \li 6.7.0 (with additional Quick3D features) + \row + \li 4.6 + \li 6.8.0 \endtable */ From ca3b41acb454930a14c72d278a14f933f53db5fc Mon Sep 17 00:00:00 2001 From: Shrief Gabr Date: Tue, 10 Sep 2024 15:34:18 +0300 Subject: [PATCH 173/193] QmlDesigner: Allow saving effects to non-default folder Fixes: QDS-13573 Change-Id: Ia441534597752ad32b5f013aabb3299632628525 Reviewed-by: Miikka Heikkinen Reviewed-by: Mahmoud Badri --- .../effectcomposer/effectcomposermodel.cpp | 42 ++++++++++++++----- .../effectcomposer/effectcomposermodel.h | 4 ++ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/plugins/effectcomposer/effectcomposermodel.cpp b/src/plugins/effectcomposer/effectcomposermodel.cpp index d9c329b1f38..3561f46a3f0 100644 --- a/src/plugins/effectcomposer/effectcomposermodel.cpp +++ b/src/plugins/effectcomposer/effectcomposermodel.cpp @@ -14,6 +14,7 @@ #include +#include #include #include @@ -202,8 +203,10 @@ void EffectComposerModel::clear(bool clearName) m_nodes.clear(); endResetModel(); - if (clearName) + if (clearName) { setCurrentComposition(""); + setCompositionPath(""); + } setHasUnsavedChanges(!m_currentComposition.isEmpty()); @@ -221,20 +224,19 @@ void EffectComposerModel::assignToSelected() QString EffectComposerModel::getUniqueEffectName() const { const QString effectsDir = QmlDesigner::ModelNodeOperations::getEffectsDefaultDirectory(); - const QString path = effectsDir + '/' + "Effect%1.qep"; + const QString path = !m_compositionPath.isEmpty() ? m_compositionPath.parentDir().pathAppended("%1.qep").toString() + : effectsDir + '/' + "%1" + ".qep"; - int num = 0; - - while (QFile::exists(path.arg(++num, 2, 10, QChar('0')))) - ; // empty body - - return QString("Effect%1").arg(num, 2, 10, QChar('0')); + return QmlDesigner::UniqueName::generate("Effect01", [&] (const QString &effectName) { + return QFile::exists(path.arg(effectName)); + }); } bool EffectComposerModel::nameExists(const QString &name) const { const QString effectsDir = QmlDesigner::ModelNodeOperations::getEffectsDefaultDirectory(); - const QString path = effectsDir + '/' + "%1" + ".qep"; + const QString path = !m_compositionPath.isEmpty() ? m_compositionPath.parentDir().pathAppended("%1.qep").toString() + : effectsDir + '/' + "%1" + ".qep"; return QFile::exists(path.arg(name)); } @@ -947,7 +949,10 @@ void EffectComposerModel::saveComposition(const QString &name) } const QString effectsAssetsDir = QmlDesigner::ModelNodeOperations::getEffectsDefaultDirectory(); - const QString path = effectsAssetsDir + '/' + name + ".qep"; + + const QString path = !m_compositionPath.isEmpty() ? m_compositionPath.parentDir().pathAppended(name + ".qep").toString() + : effectsAssetsDir + '/' + name + ".qep"; + auto saveFile = QFile(path); if (!saveFile.open(QIODevice::WriteOnly)) { QString error = QString("Error: Couldn't save composition file: '%1'").arg(path); @@ -977,7 +982,9 @@ void EffectComposerModel::saveComposition(const QString &name) saveFile.write(jsonDoc.toJson()); saveFile.close(); + setCurrentComposition(name); + setCompositionPath(Utils::FilePath::fromString(path)); saveResources(name); setHasUnsavedChanges(false); @@ -988,7 +995,9 @@ void EffectComposerModel::openComposition(const QString &path) clear(true); const QString effectName = QFileInfo(path).baseName(); + setCurrentComposition(effectName); + setCompositionPath(Utils::FilePath::fromString(path)); QFile compFile(path); if (!compFile.open(QIODevice::ReadOnly)) { @@ -2044,6 +2053,19 @@ void EffectComposerModel::setCurrentComposition(const QString &newCurrentComposi emit currentCompositionChanged(); } +Utils::FilePath EffectComposerModel::compositionPath() const +{ + return m_compositionPath; +} + +void EffectComposerModel::setCompositionPath(const Utils::FilePath &newCompositionPath) +{ + if (m_compositionPath == newCompositionPath) + return; + + m_compositionPath = newCompositionPath; +} + bool EffectComposerModel::hasUnsavedChanges() const { return m_hasUnsavedChanges; diff --git a/src/plugins/effectcomposer/effectcomposermodel.h b/src/plugins/effectcomposer/effectcomposermodel.h index b377ae06180..098cc730069 100644 --- a/src/plugins/effectcomposer/effectcomposermodel.h +++ b/src/plugins/effectcomposer/effectcomposermodel.h @@ -105,6 +105,9 @@ public: QString currentComposition() const; void setCurrentComposition(const QString &newCurrentComposition); + Utils::FilePath compositionPath() const; + void setCompositionPath(const Utils::FilePath &newCompositionPath); + bool hasUnsavedChanges() const; void setHasUnsavedChanges(bool val); @@ -226,6 +229,7 @@ private: QTimer m_rebakeTimer; int m_extraMargin = 0; QString m_effectTypePrefix; + Utils::FilePath m_compositionPath; const QRegularExpression m_spaceReg = QRegularExpression("\\s+"); }; From facc504c7f8ea2295e209da9a996eff804074ce3 Mon Sep 17 00:00:00 2001 From: Knud Dollereder Date: Tue, 17 Sep 2024 12:19:07 +0200 Subject: [PATCH 174/193] QmlProjectExporter: Use native line endings and spaces instead of tab Fixes: QDS-13648 Change-Id: I1822a31047f119e649062f341ab7dd1fc0415331 Reviewed-by: Thomas Hartmann --- .../qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp index 857a30ce330..83f956e0313 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp @@ -51,7 +51,7 @@ CMakeWriter::Ptr CMakeWriter::create(CMakeGenerator *parent) QString CMakeWriter::readTemplate(const QString &templatePath) { QFile templatefile(templatePath); - templatefile.open(QIODevice::ReadOnly); + templatefile.open(QIODevice::ReadOnly | QIODevice::Text); QTextStream stream(&templatefile); QString content = stream.readAll(); templatefile.close(); @@ -61,9 +61,12 @@ QString CMakeWriter::readTemplate(const QString &templatePath) void CMakeWriter::writeFile(const Utils::FilePath &path, const QString &content) { QFile fileHandle(path.toString()); - if (fileHandle.open(QIODevice::WriteOnly)) { + if (fileHandle.open(QIODevice::WriteOnly | QIODevice::Text)) { + QString cpy = content; + cpy.replace("\t", " "); + QTextStream stream(&fileHandle); - stream << content; + stream << cpy; } else { QString text("Failed to write"); CMakeGenerator::logIssue(ProjectExplorer::Task::Error, text, path); From c433f8bc7a49bf02cc0406ca6eb43a9066909f7d Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Wed, 18 Sep 2024 11:58:22 +0300 Subject: [PATCH 175/193] Disable Connection Editor test by default Change-Id: I4734a34e0aefa46a981be4734b60246473b28225 Reviewed-by: Tim Jenssen --- tests/auto/qml/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/auto/qml/CMakeLists.txt b/tests/auto/qml/CMakeLists.txt index cb692ff48a4..40ca50c7d37 100644 --- a/tests/auto/qml/CMakeLists.txt +++ b/tests/auto/qml/CMakeLists.txt @@ -2,8 +2,9 @@ if (NOT TARGET QmlJSTools) return() endif() +option(BUILD_TEST_TST_CONNECTION_EDITOR "Builds Test Connection View" OFF) + add_subdirectory(codemodel) -add_subdirectory(connectioneditor) add_subdirectory(persistenttrie) add_subdirectory(qmldesigner) add_subdirectory(qmleditor) @@ -11,3 +12,7 @@ add_subdirectory(qmljssimplereader) add_subdirectory(qmljsutils) add_subdirectory(qrcparser) add_subdirectory(reformatter) + +if ({BUILD_TEST_TST_CONNECTION_EDITOR}) + add_subdirectory(connectioneditor) +endif() From a30134cf840e11e07f549e3d797d59442cfe8265 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 18 Sep 2024 14:31:39 +0200 Subject: [PATCH 176/193] QmlDesigner: Add missing comma Task-number: QDS-11061 Change-Id: Ie86affe6b9fe3d28a4bc49c012cd7287225085e0 Reviewed-by: Knud Dollereder --- src/libs/qmljs/qmljscheck.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/libs/qmljs/qmljscheck.cpp b/src/libs/qmljs/qmljscheck.cpp index 53796d0acdd..92e4b8ad1db 100644 --- a/src/libs/qmljs/qmljscheck.cpp +++ b/src/libs/qmljs/qmljscheck.cpp @@ -628,12 +628,8 @@ class UnsupportedRootObjectTypesByVisualDesigner : public QStringList { public: UnsupportedRootObjectTypesByVisualDesigner() - : QStringList({"QtObject" - "ListModel" - "Component" - "Timer" - "Package", - "ApplicationWindow"}) + : QStringList( + {"QtObject", "ListModel", "Component", "Timer", "Package", "ApplicationWindow"}) {} }; From 5960b320b9e76aa9c0e0f76f20a4877fccb85cb8 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 18 Sep 2024 13:22:43 +0200 Subject: [PATCH 177/193] QmlJsCheck: Improve error message for M222 Task-number: QDS-11981 Change-Id: I2ce984f88fe738561871fdae450430963e851a9e Reviewed-by: Thomas Hartmann Reviewed-by: Pranta Ghosh Dastider --- src/libs/qmljs/qmljsstaticanalysismessage.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libs/qmljs/qmljsstaticanalysismessage.cpp b/src/libs/qmljs/qmljsstaticanalysismessage.cpp index fc4579245db..db539099c64 100644 --- a/src/libs/qmljs/qmljsstaticanalysismessage.cpp +++ b/src/libs/qmljs/qmljsstaticanalysismessage.cpp @@ -209,8 +209,10 @@ StaticAnalysisMessages::StaticAnalysisMessages() Tr::tr("This type (%1) is not supported as a root element of a UI file (.ui.qml)."), 1); newMsg(ErrUnsupportedTypeInQmlUi, Error, Tr::tr("This type (%1) is not supported in a UI file (.ui.qml)."), 1); - newMsg(ErrFunctionsNotSupportedInQmlUi, Error, - Tr::tr("Functions are not supported in a UI file (.ui.qml).")); + newMsg( + ErrFunctionsNotSupportedInQmlUi, + Error, + Tr::tr("Arbitrary functions and function calls outside of a Connections object are not supported in a UI file (.ui.qml).")); newMsg(ErrBlocksNotSupportedInQmlUi, Error, Tr::tr("JavaScript blocks are not supported in a UI file (.ui.qml).")); newMsg(ErrBehavioursNotSupportedInQmlUi, Error, From 1c8fbc5c3fdc0bc591c7fbfecf491ccc408fad90 Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Tue, 17 Sep 2024 15:45:16 +0300 Subject: [PATCH 178/193] QmlDesigner: Set id and name for the duplicate textures * Also fixes a bug in UniqueName. Case `_4KScartchySurface6` can be a valid id now. Fixes: QDS-13682 Change-Id: Idc1ae984a48c44dd531fe5458184fc61d655826d Reviewed-by: Mahmoud Badri --- .../componentcore/createtexture.cpp | 88 ++++++++++++++++++- .../components/componentcore/createtexture.h | 1 + .../textureeditor/textureeditorview.cpp | 69 +-------------- .../designercoreutils/uniquename.cpp | 2 +- .../designercoreutils/uniquename-test.cpp | 10 +++ 5 files changed, 100 insertions(+), 70 deletions(-) diff --git a/src/plugins/qmldesigner/components/componentcore/createtexture.cpp b/src/plugins/qmldesigner/components/componentcore/createtexture.cpp index 2d86c77bb4b..f595e0e47e7 100644 --- a/src/plugins/qmldesigner/components/componentcore/createtexture.cpp +++ b/src/plugins/qmldesigner/components/componentcore/createtexture.cpp @@ -9,12 +9,14 @@ #include #include #include +#include #include #include #include #include -#include +#include #include +#include #include @@ -124,6 +126,90 @@ ModelNode CreateTexture::execute(const QString &filePath, AddTextureMode mode, i return texture; } +/*! + * \brief Duplicates a texture node. + * The duplicate keeps a copy of all of the source node properties. + * It also generates a unique id, and also a name based on its id. + * \param texture The source texture + * \return Duplicate texture + */ +ModelNode CreateTexture::execute(const ModelNode &texture) +{ + QTC_ASSERT(texture.isValid(), return {}); + + if (!m_view || !m_view->model()) + return {}; + + TypeName matType = texture.type(); + QmlObjectNode sourceTexture(texture); + ModelNode duplicateTextureNode; + QList dynamicProps; + + m_view->executeInTransaction(__FUNCTION__, [&] { + ModelNode matLib = Utils3D::materialLibraryNode(m_view); + if (!matLib.isValid()) + return; + + // create the duplicate texture +#ifdef QDS_USE_PROJECTSTORAGE + QmlObjectNode duplicateTex = m_view->createModelNode(matType); +#else + NodeMetaInfo metaInfo = m_view->model()->metaInfo(matType); + QmlObjectNode duplicateTex = m_view->createModelNode(matType, metaInfo.majorVersion(), metaInfo.minorVersion()); +#endif + duplicateTextureNode = duplicateTex.modelNode(); + + // sync properties. Only the base state is duplicated. + const QList props = texture.properties(); + for (const AbstractProperty &prop : props) { + if (prop.name() == "objectName" || prop.name() == "data") + continue; + + if (prop.isVariantProperty()) { + if (prop.isDynamic()) + dynamicProps.append(prop); + else + duplicateTex.setVariantProperty(prop.name(), prop.toVariantProperty().value()); + } else if (prop.isBindingProperty()) { + if (prop.isDynamic()) { + dynamicProps.append(prop); + } else { + duplicateTex.setBindingProperty(prop.name(), + prop.toBindingProperty().expression()); + } + } + } + + const QString preferredId = m_view->model()->generateNewId(sourceTexture.id(), "Texture"); + duplicateTextureNode.setIdWithoutRefactoring(preferredId); + duplicateTextureNode.ensureIdExists(); + duplicateTex.setVariantProperty("objectName", nameFromId(duplicateTex.id(), "Texture"_L1)); + + matLib.defaultNodeListProperty().reparentHere(duplicateTex); + }); + + // For some reason, creating dynamic properties in the same transaction doesn't work, so + // let's do it in separate transaction. + // TODO: Fix the issue and merge transactions (QDS-8094) + if (!dynamicProps.isEmpty()) { + m_view->executeInTransaction(__FUNCTION__, [&] { + for (const AbstractProperty &prop : std::as_const(dynamicProps)) { + if (prop.isVariantProperty()) { + VariantProperty variantProp = duplicateTextureNode.variantProperty(prop.name()); + variantProp.setDynamicTypeNameAndValue(prop.dynamicTypeName(), + prop.toVariantProperty().value()); + } else if (prop.isBindingProperty()) { + BindingProperty bindingProp = duplicateTextureNode.bindingProperty(prop.name()); + bindingProp.setDynamicTypeNameAndExpression(prop.dynamicTypeName(), + prop.toBindingProperty().expression()); + } + } + }); + } + + return duplicateTextureNode; +} + bool CreateTexture::addFileToProject(const QString &filePath) { AddFilesResult result = ModelNodeOperations::addImageToProject( diff --git a/src/plugins/qmldesigner/components/componentcore/createtexture.h b/src/plugins/qmldesigner/components/componentcore/createtexture.h index 0f276cdbcd2..450a7f7a0db 100644 --- a/src/plugins/qmldesigner/components/componentcore/createtexture.h +++ b/src/plugins/qmldesigner/components/componentcore/createtexture.h @@ -27,6 +27,7 @@ public: ModelNode execute(const QString &filePath, AddTextureMode mode = AddTextureMode::Texture, int sceneId = -1); + ModelNode execute(const ModelNode &texture); ModelNode resolveSceneEnv(int sceneId); void assignTextureAsLightProbe(const ModelNode &texture, int sceneId); diff --git a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp index 531ae8850b1..94c150626d6 100644 --- a/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp +++ b/src/plugins/qmldesigner/components/textureeditor/textureeditorview.cpp @@ -845,74 +845,7 @@ void TextureEditorView::importsChanged([[maybe_unused]] const Imports &addedImpo void TextureEditorView::duplicateTexture(const ModelNode &texture) { QTC_ASSERT(texture.isValid(), return); - - if (!model()) - return; - - TypeName matType = texture.type(); - QmlObjectNode sourceTexture(texture); - ModelNode duplicateTextureNode; - QList dynamicProps; - - executeInTransaction(__FUNCTION__, [&] { - ModelNode matLib = Utils3D::materialLibraryNode(this); - if (!matLib.isValid()) - return; - - // create the duplicate texture -#ifdef QDS_USE_PROJECTSTORAGE - QmlObjectNode duplicateTex = createModelNode(matType); -#else - NodeMetaInfo metaInfo = model()->metaInfo(matType); - QmlObjectNode duplicateTex = createModelNode(matType, metaInfo.majorVersion(), metaInfo.minorVersion()); -#endif - duplicateTextureNode = duplicateTex .modelNode(); - duplicateTextureNode.ensureIdExists(); - - // sync properties. Only the base state is duplicated. - const QList props = texture.properties(); - for (const AbstractProperty &prop : props) { - if (prop.name() == "objectName" || prop.name() == "data") - continue; - - if (prop.isVariantProperty()) { - if (prop.isDynamic()) { - dynamicProps.append(prop); - } else { - duplicateTextureNode.variantProperty(prop.name()) - .setValue(prop.toVariantProperty().value()); - } - } else if (prop.isBindingProperty()) { - if (prop.isDynamic()) { - dynamicProps.append(prop); - } else { - duplicateTextureNode.bindingProperty(prop.name()) - .setExpression(prop.toBindingProperty().expression()); - } - } - } - - matLib.defaultNodeListProperty().reparentHere(duplicateTex); - }); - - // For some reason, creating dynamic properties in the same transaction doesn't work, so - // let's do it in separate transaction. - // TODO: Fix the issue and merge transactions (QDS-8094) - if (!dynamicProps.isEmpty()) { - executeInTransaction(__FUNCTION__, [&] { - for (const AbstractProperty &prop : std::as_const(dynamicProps)) { - if (prop.isVariantProperty()) { - duplicateTextureNode.variantProperty(prop.name()) - .setDynamicTypeNameAndValue(prop.dynamicTypeName(), - prop.toVariantProperty().value()); - } else if (prop.isBindingProperty()) { - duplicateTextureNode.bindingProperty(prop.name()) - .setDynamicTypeNameAndExpression(prop.dynamicTypeName(), - prop.toBindingProperty().expression()); - } - } - }); - } + m_createTexture->execute(texture); } void TextureEditorView::customNotification([[maybe_unused]] const AbstractView *view, diff --git a/src/plugins/qmldesigner/libs/designercore/designercoreutils/uniquename.cpp b/src/plugins/qmldesigner/libs/designercore/designercoreutils/uniquename.cpp index d372b6cfb92..7a6e889be47 100644 --- a/src/plugins/qmldesigner/libs/designercore/designercoreutils/uniquename.cpp +++ b/src/plugins/qmldesigner/libs/designercore/designercoreutils/uniquename.cpp @@ -82,7 +82,7 @@ QString generate(const QString &name, std::function predi return name; // match prefix and number (including zero padding) parts - static QRegularExpression rgx("(\\D*?)(\\d+)$"); + static const QRegularExpression rgx(R"((\D\w*?)(\d+)$)"); QRegularExpressionMatch match = rgx.match(name); QString prefix; diff --git a/tests/unit/tests/unittests/designercoreutils/uniquename-test.cpp b/tests/unit/tests/unittests/designercoreutils/uniquename-test.cpp index 5967936713e..5a42888b116 100644 --- a/tests/unit/tests/unittests/designercoreutils/uniquename-test.cpp +++ b/tests/unit/tests/unittests/designercoreutils/uniquename-test.cpp @@ -90,6 +90,16 @@ TEST(UniqueName, generateId_stable_captilzation) ASSERT_THAT(uniqueId, "aCaMeLCAsE"); } +TEST(UniqueName, generateId_contains_number_in_prefix_and_suffix) +{ + QString id = "_4KScartchySurface6"; + auto pred = [&](const QString &str) -> bool { return str == id; }; + + QString uniqueId = UniqueName::generateId(id, pred); + + ASSERT_THAT(uniqueId, "_4KScartchySurface7"); +} + TEST(UniqueName, generateId_begins_with_non_latin) { QString id = "😂_saneId"; From 3c4db581a3d620097609346ed156da33d367f77d Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Thu, 19 Sep 2024 13:22:08 +0300 Subject: [PATCH 179/193] QmlDesigner: Enable user material drag from content library Fixes: QDS-13377 Change-Id: I88303f10809da132bf3f2e6e9736cd13770b5089 Reviewed-by: Miikka Heikkinen Reviewed-by: Ali Kianian --- .../contentlibrary/contentlibraryview.cpp | 41 +++++++++++++++---- .../components/edit3d/edit3dview.cpp | 2 +- .../components/edit3d/edit3dview.h | 2 +- .../components/edit3d/edit3dwidget.cpp | 2 +- 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp index 44c70ce8ece..4bcf9e7fd9e 100644 --- a/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp +++ b/src/plugins/qmldesigner/components/contentlibrary/contentlibraryview.cpp @@ -220,8 +220,7 @@ void ContentLibraryView::connectImporter() // delete instances of the bundle material that is about to be unimported executeInTransaction("ContentLibraryView::connectImporter", [&] { ModelNode matLib = Utils3D::materialLibraryNode(this); - if (!matLib.isValid()) - return; + QTC_ASSERT(matLib.isValid(), return); Utils::reverseForeach(matLib.directSubModelNodes(), [&](const ModelNode &mat) { if (mat.isValid() && mat.type() == type) @@ -342,8 +341,7 @@ void ContentLibraryView::customNotification(const AbstractView *view, if (identifier == "drop_bundle_material") { ModelNode matLib = Utils3D::materialLibraryNode(this); - if (!matLib.isValid()) - return; + QTC_ASSERT(matLib.isValid(), return); m_bundleMaterialTargets = nodeList; @@ -367,8 +365,7 @@ void ContentLibraryView::customNotification(const AbstractView *view, m_draggedBundleMaterial = nullptr; } else if (identifier == "drop_bundle_texture") { ModelNode matLib = Utils3D::materialLibraryNode(this); - if (!matLib.isValid()) - return; + QTC_ASSERT(matLib.isValid(), return); m_widget->addTexture(m_draggedBundleTexture); @@ -377,13 +374,39 @@ void ContentLibraryView::customNotification(const AbstractView *view, QTC_ASSERT(nodeList.size() == 1, return); auto compUtils = QmlDesignerPlugin::instance()->documentManager().generatedComponentUtils(); - bool is3D = m_draggedBundleItem->type().startsWith(compUtils.user3DBundleType().toLatin1()); + bool isUser3D = m_draggedBundleItem->type().startsWith(compUtils.user3DBundleType().toLatin1()); + bool isUserMaterial = m_draggedBundleItem->type().startsWith(compUtils.userMaterialsBundleType().toLatin1()); m_bundleItemPos = data.size() == 1 ? data.first() : QVariant(); - if (is3D) + if (isUser3D) { m_widget->userModel()->addToProject(m_draggedBundleItem); - else + } else if (isUserMaterial) { + ModelNode matLib = Utils3D::materialLibraryNode(this); + QTC_ASSERT(matLib.isValid(), return); + + m_bundleMaterialTargets = nodeList; + + ModelNode defaultMat = getBundleMaterialDefaultInstance(m_draggedBundleItem->type()); + if (defaultMat.isValid()) { + if (m_bundleMaterialTargets.isEmpty()) { // if no drop target, create a duplicate material + executeInTransaction(__FUNCTION__, [&] { +#ifdef QDS_USE_PROJECTSTORAGE + Utils3D::createMaterial(this, m_draggedBundleItem->type()); +#else + Utils3D::createMaterial(this, defaultMat.metaInfo()); +#endif + }); + } else { + applyBundleMaterialToDropTarget(defaultMat); + } + } else { + m_widget->userModel()->addToProject(m_draggedBundleItem); + } + + m_draggedBundleItem = nullptr; + } else { m_widget->effectsModel()->addInstance(m_draggedBundleItem); + } m_bundleItemTarget = nodeList.first() ? nodeList.first() : Utils3D::active3DSceneNode(this); } else if (identifier == "add_material_to_content_lib") { QTC_ASSERT(nodeList.size() == 1 && data.size() == 1, return); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index ed86218d37b..24cbc7670dc 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -1472,7 +1472,7 @@ void Edit3DView::dropBundleMaterial(const QPointF &pos) emitView3DAction(View3DActionType::GetNodeAtPos, pos); } -void Edit3DView::dropBundleEffect(const QPointF &pos) +void Edit3DView::dropBundleItem(const QPointF &pos) { m_nodeAtPosReqType = NodeAtPosReqType::BundleEffectDrop; emitView3DAction(View3DActionType::GetNodeAtPos, pos); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.h b/src/plugins/qmldesigner/components/edit3d/edit3dview.h index 62d05a3f663..108a689a06e 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.h @@ -98,7 +98,7 @@ public: void showContextMenu(); void dropMaterial(const ModelNode &matNode, const QPointF &pos); void dropBundleMaterial(const QPointF &pos); - void dropBundleEffect(const QPointF &pos); + void dropBundleItem(const QPointF &pos); void dropTexture(const ModelNode &textureNode, const QPointF &pos); void dropComponent(const ItemLibraryEntry &entry, const QPointF &pos); void dropAsset(const QString &file, const QPointF &pos); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index 8b28e4b55de..933e7728354 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -764,7 +764,7 @@ void Edit3DWidget::dropEvent(QDropEvent *dropEvent) // handle dropping bundle items if (dropEvent->mimeData()->hasFormat(Constants::MIME_TYPE_BUNDLE_ITEM)) { - m_view->dropBundleEffect(pos); + m_view->dropBundleItem(pos); m_view->model()->endDrag(); return; } From a65ac94f678c7eb88ae06e9693b84c48d1dd2fe0 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Thu, 19 Sep 2024 16:37:15 +0200 Subject: [PATCH 180/193] QmlDesigner: Fix issues panel word wrap Change-Id: I392985ed7a2a47a0414ea4f4094f7c0ce4fba955 Reviewed-by: Thomas Hartmann --- .../qmldesigner/statusbar/IssuesPanel.qml | 38 ++++++++++++------- .../qmldesigner/statusbar/OutputPanel.qml | 2 - 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml b/share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml index 432a6f9c2cf..36e90d024a6 100644 --- a/share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml +++ b/share/qtcreator/qmldesigner/statusbar/IssuesPanel.qml @@ -11,7 +11,7 @@ import StudioTheme as StudioTheme import OutputPane ScrollView { - id: issuesPanel + id: root signal showCodeViewSignal @@ -23,12 +23,12 @@ ScrollView { ScrollBar.vertical: StudioControls.TransientScrollBar { id: verticalScrollBar style: StudioTheme.Values.viewStyle - parent: issuesPanel - x: issuesPanel.width - verticalScrollBar.width + parent: root + x: root.width - verticalScrollBar.width y: 0 - height: issuesPanel.availableHeight + height: root.availableHeight orientation: Qt.Vertical - show: (issuesPanel.hovered || issuesPanel.focus) && verticalScrollBar.isNeeded + show: (root.hovered || root.focus) && verticalScrollBar.isNeeded } ColumnLayout { @@ -37,46 +37,58 @@ ScrollView { model: MessageModel { id: messageModel } - delegate: RowLayout { - spacing: 10 + delegate: Row { + id: row required property int index required property string message required property string location required property string type + width: root.width + spacing: 10 + Text { + id: labelIcon font.family: StudioTheme.Constants.iconFont.family font.pixelSize: StudioTheme.Values.baseIconFontSize color: (type == "Warning") ? StudioTheme.Values.themeAmberLight : StudioTheme.Values.themeRedLight text: (type == "Warning") ? StudioTheme.Constants.warning2_medium : StudioTheme.Constants.error_medium + width: 18 + height: 18 + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter } Text { + id: labelLocation text: location color: "#57b9fc" - font.pixelSize: 12 + font.pixelSize: StudioTheme.Values.baseFontSize verticalAlignment: Text.AlignVCenter - Layout.preferredHeight: 18 - font.underline: mouseArea.containsMouse ? true : false + font.underline: mouseArea.containsMouse + height: 18 MouseArea { id: mouseArea anchors.fill: parent hoverEnabled: true - cursorShape: mouseArea.containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor + cursorShape: mouseArea.containsMouse ? Qt.PointingHandCursor + : Qt.ArrowCursor } } Text { + id: labelInfo color: (type == "Warning") ? StudioTheme.Values.themeAmberLight : StudioTheme.Values.themeRedLight text: message font.pixelSize: StudioTheme.Values.baseFontSize - verticalAlignment: Text.AlignVCenter - Layout.preferredHeight: 18 + verticalAlignment: Text.AlignTop + wrapMode: Text.WordWrap + width: row.width - labelIcon.width - labelLocation.width - row.spacing * 2 } } } diff --git a/share/qtcreator/qmldesigner/statusbar/OutputPanel.qml b/share/qtcreator/qmldesigner/statusbar/OutputPanel.qml index 56b1083ee80..f54e96290ea 100644 --- a/share/qtcreator/qmldesigner/statusbar/OutputPanel.qml +++ b/share/qtcreator/qmldesigner/statusbar/OutputPanel.qml @@ -43,8 +43,6 @@ ScrollView { } Column { - id: clayout - Repeater { id: parentList From 4ca84d844cc01f9059e8cd0879a440fe19963461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Jen=C3=9Fen?= Date: Thu, 19 Sep 2024 18:21:13 +0200 Subject: [PATCH 181/193] QmlProjectManager: fix importPaths on device We have converted all import paths to absolute paths, which works on the host but causes issues on the target. To resolve this, we introduce targetImportPaths() Task-number: QDS-12948 Change-Id: I02e32badeaf386e66a6d0806979692439d685450 Reviewed-by: Thomas Hartmann --- .../buildsystem/qmlbuildsystem.cpp | 20 +++++++++++++++---- .../buildsystem/qmlbuildsystem.h | 1 + .../qmlprojectrunconfiguration.cpp | 2 +- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp index 79b20f3c82a..b2f61dc30bb 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp @@ -527,6 +527,7 @@ Utils::FilePath QmlBuildSystem::targetFile(const Utils::FilePath &sourceFile) co const Utils::FilePath relative = sourceFile.relativePathFrom(sourceDir); return targetDirectory().resolvePath(relative); } + void QmlBuildSystem::setSupportedLanguages(QStringList languages) { m_projectItem->setSupportedLanguages(languages); @@ -733,11 +734,22 @@ QStringList QmlBuildSystem::mockImports() const QStringList QmlBuildSystem::absoluteImportPaths() const { - return Utils::transform(allImports(), [&](const QString &importPath) { + return Utils::transform(m_projectItem->importPaths(), [&](const QString &importPath) { Utils::FilePath filePath = Utils::FilePath::fromString(importPath); - if (!filePath.isAbsolutePath()) - return (projectDirectory() / importPath).toString(); - return projectDirectory().resolvePath(importPath).toString(); + if (filePath.isAbsolutePath()) + return projectDirectory().resolvePath(importPath).path(); + return (projectDirectory() / importPath).path(); + }); +} + +QStringList QmlBuildSystem::targetImportPaths() const +{ + return Utils::transform(allImports(), [&](const QString &importPath) { + const Utils::FilePath filePath = Utils::FilePath::fromString(importPath); + if (filePath.isAbsolutePath()) { + return importPath; + } + return (targetDirectory() / importPath).path(); }); } diff --git a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h index 3907e8741ed..e76d8ba75c9 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h +++ b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.h @@ -77,6 +77,7 @@ public: QStringList importPaths() const; QStringList mockImports() const; QStringList absoluteImportPaths() const; + QStringList targetImportPaths() const; QStringList fileSelectors() const; bool multilanguageSupport() const; diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp index 503738eba52..29fb4aac3fc 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp @@ -97,7 +97,7 @@ QmlProjectRunConfiguration::QmlProjectRunConfiguration(Target *target, Id id) // arguments from .qmlproject file const QmlBuildSystem *bs = qobject_cast(target->buildSystem()); - for (const QString &importPath : bs->absoluteImportPaths()) { + for (const QString &importPath : bs->targetImportPaths()) { cmd.addArg("-I"); cmd.addArg(importPath); } From 60096814b43247876f91a587a3fa6b627efb8de7 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Thu, 19 Sep 2024 14:47:11 +0200 Subject: [PATCH 182/193] QmlProject: Add warning for old projects Task-number: QDS-13705 Change-Id: Ief8af59611d71e46bf6cfa5fd171e759c5c82fdc Reviewed-by: Jarko Vihriala Reviewed-by: Pranta Ghosh Dastider Reviewed-by: Tim Jenssen --- .../qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp index 83f956e0313..050097f6514 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectexporter/cmakewriter.cpp @@ -45,6 +45,14 @@ CMakeWriter::Ptr CMakeWriter::create(CMakeGenerator *parent) if (float version = versionString.toFloat(&ok); ok && version > 4.4) return std::make_unique(parent); + CMakeGenerator::logIssue( + ProjectExplorer::Task::Warning, + "The project was created with a Qt Design Studio version earlier than Qt Design Studio " + "4.5. Due to limitations of the project structure in earlier Qt Design Studio versions, " + "the resulting application might not display all the assets. Referring to " + "assets between different QML modules does not work in the compiled application.", + buildSystem->projectFilePath()); + return std::make_unique(parent); } From f6ff374cb5890c323aa5a7ce27ae9c49762181d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Jen=C3=9Fen?= Date: Fri, 20 Sep 2024 11:00:04 +0200 Subject: [PATCH 183/193] QmlProjectManager: use new allImports method Change-Id: I1fd27d88d993187724a4535def616482508504ee Reviewed-by: Tim Jenssen --- src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp index b2f61dc30bb..701da75dd57 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp @@ -734,7 +734,7 @@ QStringList QmlBuildSystem::mockImports() const QStringList QmlBuildSystem::absoluteImportPaths() const { - return Utils::transform(m_projectItem->importPaths(), [&](const QString &importPath) { + return Utils::transform(allImports(), [&](const QString &importPath) { Utils::FilePath filePath = Utils::FilePath::fromString(importPath); if (filePath.isAbsolutePath()) return projectDirectory().resolvePath(importPath).path(); From aedd6ba09798862db63c69e0675dbfe88996dc52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Jen=C3=9Fen?= Date: Sun, 22 Sep 2024 12:13:49 +0200 Subject: [PATCH 184/193] qds: increase version to 4.7.0 Change-Id: I4c06f6769bf81e113d5f71d570d18dbdd6aac813 Reviewed-by: Tim Jenssen --- dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake b/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake index 998ca9c53a2..456815ba389 100644 --- a/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake +++ b/dist/branding/qtdesignstudio/QtCreatorIDEBranding.cmake @@ -1,6 +1,6 @@ -set(IDE_VERSION "4.6.0") # The IDE version. -set(IDE_VERSION_COMPAT "4.6.0") # The IDE Compatibility version. -set(IDE_VERSION_DISPLAY "4.6") # The IDE display version. +set(IDE_VERSION "4.7.0") # The IDE version. +set(IDE_VERSION_COMPAT "4.7.0") # The IDE Compatibility version. +set(IDE_VERSION_DISPLAY "4.7") # The IDE display version. set(IDE_COPYRIGHT_YEAR "2024") # The IDE current copyright year. set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation. From d25d40a198182e6f72f523c76791d06e988bff1e Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 20 Sep 2024 08:16:50 +0200 Subject: [PATCH 185/193] QmlProjectManager: Save cycles in QmlPRunConfiguration::isEnabled() No need to create the full command line when only the executable is needed. Change-Id: If2a6aec6c47d388878441330773121562923525b Reviewed-by: Tim Jenssen --- src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp index 29fb4aac3fc..d5debe0211c 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp @@ -309,7 +309,7 @@ void QmlProjectRunConfiguration::setupQtVersionAspect() bool QmlProjectRunConfiguration::isEnabled(Id) const { return const_cast(this)->qmlMainFile.isQmlFilePresent() - && !commandLine().executable().isEmpty() + && !qmlRuntimeFilePath().isEmpty() && activeBuildSystem()->hasParsingData(); } From 0bc8421616ce4a8714351f29e75e493e93388302 Mon Sep 17 00:00:00 2001 From: Shrief Gabr Date: Thu, 19 Sep 2024 15:12:55 +0300 Subject: [PATCH 186/193] QmlDesigner: Allow dropping content library textures in Navigator Fixes: QDS-13575 Change-Id: Idefa22696a859919f6932854039c06a992ce4d46 Reviewed-by: Mahmoud Badri --- .../components/navigator/nameitemdelegate.cpp | 7 ++--- .../navigator/navigatortreemodel.cpp | 31 +++++++++++++++++-- .../components/navigator/navigatortreemodel.h | 9 ++++-- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp index 01e4ead915f..317ff794061 100644 --- a/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp +++ b/src/plugins/qmldesigner/components/navigator/nameitemdelegate.cpp @@ -226,11 +226,10 @@ void NameItemDelegate::paint(QPainter *painter, }; bool validDrop = false; - if (dragType == Constants::MIME_TYPE_BUNDLE_TEXTURE) { - validDrop = metaInfo.isQtQuick3DModel(); - } else if (dragType == Constants::MIME_TYPE_ASSET_TEXTURE3D) { + if (dragType == Constants::MIME_TYPE_ASSET_TEXTURE3D) { validDrop = isValid3dTextureTarget(); - } else if (dragType == Constants::MIME_TYPE_ASSET_IMAGE) { + } else if (dragType == Constants::MIME_TYPE_ASSET_IMAGE + || dragType == Constants::MIME_TYPE_BUNDLE_TEXTURE) { Model *model = node.model(); validDrop = isValid3dTextureTarget() || metaInfo.isBasedOn(model->qtQuickImageMetaInfo(), model->qtQuickBorderImageMetaInfo()); diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index c197f244b42..341f3694857 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -2,12 +2,14 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "navigatortreemodel.h" + +#include "assetslibrarywidget.h" +#include "choosefrompropertylistdialog.h" +#include "createtexture.h" #include "navigatorview.h" #include "navigatorwidget.h" -#include "choosefrompropertylistdialog.h" #include "qmldesignerconstants.h" #include "qmldesignerplugin.h" -#include "assetslibrarywidget.h" #include #include @@ -176,6 +178,7 @@ static void reparentModelNodeToNodeProperty(NodeAbstractProperty &parentProperty } NavigatorTreeModel::NavigatorTreeModel(QObject *parent) : QAbstractItemModel(parent) + , m_createTextures(Utils::makeUniqueObjectPtr(m_view)) { m_actionManager = &QmlDesignerPlugin::instance()->viewManager().designerActionManager(); } @@ -569,6 +572,30 @@ bool NavigatorTreeModel::dropMimeData(const QMimeData *mimeData, if (targetNode.metaInfo().isQtQuick3DModel()) { QmlDesignerPlugin::instance()->mainWidget()->showDockWidget("MaterialBrowser"); m_view->emitCustomNotification("apply_asset_to_model3D", {targetNode}, {filePath}); // To MaterialBrowserView + } else { + QString texturePath = QString::fromUtf8(mimeData->data(Constants::MIME_TYPE_BUNDLE_TEXTURE)); + NodeAbstractProperty targetProperty; + + const QModelIndex rowModelIndex = dropModelIndex.sibling(dropModelIndex.row(), 0); + int targetRowNumber = rowNumber; + bool foundTarget = findTargetProperty(rowModelIndex, this, &targetProperty, &targetRowNumber); + if (foundTarget) { + bool moveNodesAfter = false; + + m_view->executeInTransaction(__FUNCTION__, [&] { + m_createTextures->execute(QStringList{texturePath}, + AddTextureMode::Image, + Utils3D::active3DSceneId(m_view->model())); + QString textureName = Utils::FilePath::fromString(texturePath).fileName(); + QString textureAbsolutePath = DocumentManager::currentResourcePath() + .pathAppended("images/" + textureName).toString(); + ModelNodeOperations::handleItemLibraryImageDrop(textureAbsolutePath, + targetProperty, + modelNodeForIndex( + rowModelIndex), + moveNodesAfter); + }); + } } } else if (mimeData->hasFormat(Constants::MIME_TYPE_BUNDLE_MATERIAL)) { if (targetNode.isValid()) diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h index 25a4d9637e7..7e6df8b2ec1 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.h @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -16,10 +17,11 @@ QT_FORWARD_DECLARE_CLASS(QPixmap) namespace QmlDesigner { -class Model; -class NavigatorView; -class ModelNode; +class CreateTextures; class DesignerActionManager; +class Model; +class ModelNode; +class NavigatorView; class NavigatorTreeModel : public QAbstractItemModel, public NavigatorModelInterface { @@ -103,6 +105,7 @@ private: bool moveNodeToParent(const NodeAbstractProperty &targetProperty, const ModelNode &newModelNode); QPointer m_view; + Utils::UniqueObjectPtr m_createTextures; mutable QHash m_nodeIndexHash; mutable QHash > m_rowCache; bool m_showOnlyVisibleItems = true; From acb7ef39aa0a06af7705d147a167a1e20e9a197d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20Jen=C3=9Fen?= Date: Mon, 12 Aug 2024 10:54:36 +0200 Subject: [PATCH 187/193] QmlDesigner: do not hide kit settings if debug build Change-Id: I9ea1591d2d088071f951c63212bf551046f944d1 Reviewed-by: Thomas Hartmann --- src/plugins/coreplugin/dialogs/settingsdialog.cpp | 8 ++++---- src/plugins/projectexplorer/projectwindow.cpp | 8 +++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/plugins/coreplugin/dialogs/settingsdialog.cpp b/src/plugins/coreplugin/dialogs/settingsdialog.cpp index 74fe67d8175..440912efdef 100644 --- a/src/plugins/coreplugin/dialogs/settingsdialog.cpp +++ b/src/plugins/coreplugin/dialogs/settingsdialog.cpp @@ -249,16 +249,16 @@ protected: bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; }; -const char SETTING_HIDE_OPTION_CATEGORIES[] = "HideOptionCategories"; - static bool categoryVisible(const Id &id) { +#ifdef QT_NO_DEBUG + static QStringList list - = Core::ICore::settings()->value(SETTING_HIDE_OPTION_CATEGORIES).toStringList(); + = Core::ICore::settings()->value("HideOptionCategories").toStringList(); if (anyOf(list, [id](const QString &str) { return id.toString().contains(str); })) return false; - +#endif return true; } diff --git a/src/plugins/projectexplorer/projectwindow.cpp b/src/plugins/projectexplorer/projectwindow.cpp index c3214b64984..702c68f652e 100644 --- a/src/plugins/projectexplorer/projectwindow.cpp +++ b/src/plugins/projectexplorer/projectwindow.cpp @@ -736,8 +736,11 @@ public: innerLayout->setSpacing(10); innerLayout->setContentsMargins(PanelsWidget::PanelVMargin, innerLayout->spacing(), PanelsWidget::PanelVMargin, 0); - - QStringList list = Core::ICore::settings()->value("HideOptionCategories").toStringList(); +#ifdef QT_NO_DEBUG + const QStringList list = Core::ICore::settings()->value("HideOptionCategories").toStringList(); +#else + const QStringList list; +#endif if (!list.contains("Kits")) { auto manageKits = new QPushButton(Tr::tr("Manage Kits...")); connect(manageKits, &QPushButton::clicked, @@ -746,7 +749,6 @@ public: innerLayout->addWidget(manageKits); innerLayout->addSpacerItem(new QSpacerItem(10, 30, QSizePolicy::Maximum, QSizePolicy::Maximum)); } - innerLayout->addWidget(activeLabel); innerLayout->addWidget(m_projectSelection); innerLayout->addWidget(m_importBuild); From 03c2c3c365bd10888e1b64b53381ca5017cbdbb2 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Wed, 11 Sep 2024 18:26:46 +0200 Subject: [PATCH 188/193] QmlDesigner: Fix compilation for GCC 10 QList and std::span don't interact well on GCC 10. GCC 11 is fixing it but we still have to support old compiler. QVarLengthArray is fixing it. It has the advantage to reduce allocations too. Change-Id: I4d17aee334258776de7d40aaa248e815f988fb0c Reviewed-by: Tim Jenssen --- .../libs/designercore/include/abstractview.h | 1 - .../libs/designercore/include/modelnode.h | 12 +- .../libs/designercore/model/abstractview.cpp | 13 +-- .../libs/designercore/model/internalnode.cpp | 26 +++-- .../libs/designercore/model/internalnode_p.h | 14 ++- .../model/internalnodelistproperty.cpp | 31 +++--- .../model/internalnodelistproperty.h | 32 +++--- .../model/internalnodeproperty.cpp | 6 +- .../designercore/model/internalnodeproperty.h | 6 +- .../libs/designercore/model/model.cpp | 103 ++++++++---------- .../libs/designercore/model/model_p.h | 25 +++-- .../libs/designercore/model/modelnode.cpp | 15 +++ .../designercore/model/nodelistproperty.cpp | 6 +- .../projectstorage/projectstorageupdater.cpp | 5 +- 14 files changed, 155 insertions(+), 140 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/include/abstractview.h b/src/plugins/qmldesigner/libs/designercore/include/abstractview.h index c621b9d3bac..c6f25e7bad1 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/abstractview.h +++ b/src/plugins/qmldesigner/libs/designercore/include/abstractview.h @@ -328,7 +328,6 @@ private: Kind m_kind = Kind::Other; }; -QMLDESIGNERCORE_EXPORT QList toInternalNodeList(const QList &nodeList); QMLDESIGNERCORE_EXPORT QList toModelNodeList( Utils::span nodeList, Model *model, diff --git a/src/plugins/qmldesigner/libs/designercore/include/modelnode.h b/src/plugins/qmldesigner/libs/designercore/include/modelnode.h index df2f7113f27..91f05a4d5ca 100644 --- a/src/plugins/qmldesigner/libs/designercore/include/modelnode.h +++ b/src/plugins/qmldesigner/libs/designercore/include/modelnode.h @@ -45,7 +45,13 @@ class GlobalAnnotationStatus; class Comment; class Annotation; -QMLDESIGNERCORE_EXPORT QList toInternalNodeList(const QList &nodeList); +template> +QMLDESIGNERCORE_EXPORT Result toInternalNodeList(const QList &nodeList); + +extern template QMLDESIGNERCORE_EXPORT QVarLengthArray +toInternalNodeList>(const QList &nodeList); +extern template QMLDESIGNERCORE_EXPORT QVarLengthArray +toInternalNodeList>(const QList &nodeList); using PropertyListType = QList >; using AuxiliaryPropertyListType = QList>; @@ -59,7 +65,9 @@ inline constexpr AuxiliaryDataKeyView transitionExpandedPropery{AuxiliaryDataTyp class QMLDESIGNERCORE_EXPORT ModelNode { friend QMLDESIGNERCORE_EXPORT QDebug operator<<(QDebug debug, const ModelNode &modelNode); - friend QMLDESIGNERCORE_EXPORT QList toInternalNodeList(const QList &nodeList); + template + friend QMLDESIGNERCORE_EXPORT Result toInternalNodeList(const QList &nodeList); + friend Model; friend AbstractView; friend NodeListProperty; diff --git a/src/plugins/qmldesigner/libs/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/libs/designercore/model/abstractview.cpp index 31d49b79915..acc8be0f9b0 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/abstractview.cpp @@ -411,15 +411,6 @@ QList toModelNodeList(Utils::span toInternalNodeList(const QList &nodeList) -{ - QList newNodeList; - for (const ModelNode &node : nodeList) - newNodeList.append(node.internalNode()); - - return newNodeList; -} - /*! Sets the list of nodes to the actual selected nodes specified by \a selectedNodeList if the node or its ancestors are not locked. @@ -466,7 +457,7 @@ QList AbstractView::selectedModelNodes() const ModelNode AbstractView::firstSelectedModelNode() const { if (hasSelectedModelNodes()) - return ModelNode(model()->d->selectedNodes().constFirst(), model(), this); + return ModelNode(model()->d->selectedNodes().front(), model(), this); return ModelNode(); } @@ -474,7 +465,7 @@ ModelNode AbstractView::firstSelectedModelNode() const ModelNode AbstractView::singleSelectedModelNode() const { if (hasSingleSelectedModelNode()) - return ModelNode(model()->d->selectedNodes().constFirst(), model(), this); + return ModelNode(model()->d->selectedNodes().front(), model(), this); return ModelNode(); } diff --git a/src/plugins/qmldesigner/libs/designercore/model/internalnode.cpp b/src/plugins/qmldesigner/libs/designercore/model/internalnode.cpp index a601cc21605..ef84007b997 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/internalnode.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/internalnode.cpp @@ -120,9 +120,9 @@ PropertyNameViews InternalNode::propertyNameViews() const return CoreUtils::to(m_nameProperties | std::views::keys); } -QList InternalNode::allSubNodes() const +InternalNode::ManyNodes InternalNode::allSubNodes() const { - QList nodes; + ManyNodes nodes; nodes.reserve(1024); addSubNodes(nodes); @@ -130,7 +130,7 @@ QList InternalNode::allSubNodes() const return nodes; } -void InternalNode::addSubNodes(QList &nodes, const InternalProperty *property) +void InternalNode::addSubNodes(ManyNodes &nodes, const InternalProperty *property) { switch (property->type()) { case PropertyType::NodeList: @@ -148,24 +148,30 @@ void InternalNode::addSubNodes(QList &nodes, const Internal } } -void InternalNode::addSubNodes(QList &nodes) const +void InternalNode::addSubNodes(ManyNodes &nodes) const { for (const auto &entry : m_nameProperties) addSubNodes(nodes, entry.second.get()); } -void InternalNode::addDirectSubNodes(QList &nodes) const +void InternalNode::addDirectSubNodes(ManyNodes &nodes) const { for (const auto &entry : m_nameProperties) addDirectSubNodes(nodes, entry.second.get()); } -void InternalNode::addDirectSubNodes(QList &nodes, - const InternalProperty *property) +namespace { +void append(InternalNode::ManyNodes &nodes, auto &appendNodes) +{ + std::copy(appendNodes.begin(), appendNodes.end(), std::back_inserter(nodes)); +} +} // namespace + +void InternalNode::addDirectSubNodes(ManyNodes &nodes, const InternalProperty *property) { switch (property->type()) { case PropertyType::NodeList: - nodes.append(property->to()->nodes()); + append(nodes, property->to()->nodes()); break; case PropertyType::Node: nodes.append(property->to()->node()); @@ -179,9 +185,9 @@ void InternalNode::addDirectSubNodes(QList &nodes, } } -QList InternalNode::allDirectSubNodes() const +InternalNode::ManyNodes InternalNode::allDirectSubNodes() const { - QList nodes; + ManyNodes nodes; nodes.reserve(96); addDirectSubNodes(nodes); diff --git a/src/plugins/qmldesigner/libs/designercore/model/internalnode_p.h b/src/plugins/qmldesigner/libs/designercore/model/internalnode_p.h index 4129ff98a07..a850ead3ae1 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/internalnode_p.h +++ b/src/plugins/qmldesigner/libs/designercore/model/internalnode_p.h @@ -50,6 +50,8 @@ class InternalNode : public std::enable_shared_from_this public: using Pointer = std::shared_ptr; using WeakPointer = std::weak_ptr; + using FewNodes = QVarLengthArray; + using ManyNodes = QVarLengthArray; explicit InternalNode(TypeNameView typeName, int majorVersion, @@ -193,12 +195,12 @@ public: bool hasProperties() const { return m_nameProperties.size(); } - QList allSubNodes() const; - QList allDirectSubNodes() const; - void addSubNodes(QList &nodes) const; - void addDirectSubNodes(QList &nodes) const; - static void addSubNodes(QList &nodes, const InternalProperty *property); - static void addDirectSubNodes(QList &nodes, const InternalProperty *property); + ManyNodes allSubNodes() const; + ManyNodes allDirectSubNodes() const; + void addSubNodes(ManyNodes &nodes) const; + void addDirectSubNodes(ManyNodes &nodes) const; + static void addSubNodes(ManyNodes &nodes, const InternalProperty *property); + static void addDirectSubNodes(ManyNodes &nodes, const InternalProperty *property); friend bool operator<(const InternalNode::Pointer &firstNode, const InternalNode::Pointer &secondNode) diff --git a/src/plugins/qmldesigner/libs/designercore/model/internalnodelistproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/internalnodelistproperty.cpp index 49fa67f9c2c..a7ed51b18c3 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/internalnodelistproperty.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/internalnodelistproperty.cpp @@ -21,12 +21,12 @@ bool InternalNodeListProperty::isValid() const bool InternalNodeListProperty::isEmpty() const { - return m_nodeList.isEmpty(); + return m_nodes.isEmpty(); } int InternalNodeListProperty::count() const { - return m_nodeList.size(); + return m_nodes.size(); } int InternalNodeListProperty::indexOf(const InternalNode::Pointer &node) const @@ -34,53 +34,54 @@ int InternalNodeListProperty::indexOf(const InternalNode::Pointer &node) const if (!node) return -1; - return m_nodeList.indexOf(node); + return m_nodes.indexOf(node); } void InternalNodeListProperty::add(const InternalNode::Pointer &internalNode) { - Q_ASSERT(!m_nodeList.contains(internalNode)); + Q_ASSERT(!m_nodes.contains(internalNode)); auto flowToken = traceToken.tickWithFlow("add node"_t); internalNode->traceToken.tick(flowToken, "node added"_t); - m_nodeList.append(internalNode); + m_nodes.append(internalNode); } void InternalNodeListProperty::remove(const InternalNodePointer &internalNode) { - Q_ASSERT(m_nodeList.contains(internalNode)); + Q_ASSERT(m_nodes.contains(internalNode)); auto flowToken = traceToken.tickWithFlow("remove node"_t); internalNode->traceToken.tick(flowToken, "node removed"_t); - m_nodeList.removeAll(internalNode); + m_nodes.removeAll(internalNode); } -const QList &InternalNodeListProperty::nodeList() const +const InternalNodeListProperty::FewNodes &InternalNodeListProperty::nodeList() const { - return m_nodeList; + return m_nodes; } void InternalNodeListProperty::slide(int from, int to) { traceToken.tick("slide"_t, keyValue("from", from), keyValue("to", to)); - InternalNode::Pointer internalNode = m_nodeList.takeAt(from); - m_nodeList.insert(to, internalNode); + InternalNode::Pointer internalNode = m_nodes.at(from); + m_nodes.remove(from); + m_nodes.insert(to, internalNode); } -void InternalNodeListProperty::addSubNodes(QList &container) const +void InternalNodeListProperty::addSubNodes(ManyNodes &container) const { - for (const auto &node : std::as_const(m_nodeList)) { + for (const auto &node : std::as_const(m_nodes)) { container.push_back(node); node->addSubNodes(container); } } -QList InternalNodeListProperty::allSubNodes() const +InternalNodeListProperty::ManyNodes InternalNodeListProperty::allSubNodes() const { - QList nodes; + ManyNodes nodes; nodes.reserve(1024); addSubNodes(nodes); diff --git a/src/plugins/qmldesigner/libs/designercore/model/internalnodelistproperty.h b/src/plugins/qmldesigner/libs/designercore/model/internalnodelistproperty.h index 9072e571afc..3f91d74a3de 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/internalnodelistproperty.h +++ b/src/plugins/qmldesigner/libs/designercore/model/internalnodelistproperty.h @@ -15,6 +15,9 @@ class InternalNodeListProperty final : public InternalNodeAbstractProperty { public: using Pointer = std::shared_ptr; + using FewNodes = QVarLengthArray; + using ManyNodes = QVarLengthArray; + static constexpr PropertyType type = PropertyType::NodeList; InternalNodeListProperty(PropertyNameView name, const InternalNodePointer &propertyOwner); @@ -22,46 +25,49 @@ public: bool isValid() const override; bool isEmpty() const override; - int size() const { return m_nodeList.size(); } + + int size() const { return m_nodes.size(); } + int count() const override; int indexOf(const InternalNodePointer &node) const override; + const InternalNodePointer &at(int index) const { - Q_ASSERT(index >= 0 && index < m_nodeList.size()); - return m_nodeList[index]; + Q_ASSERT(index >= 0 && index < m_nodes.size()); + return m_nodes[index]; } InternalNodePointer &at(int index) { - Q_ASSERT(index >= 0 && index < m_nodeList.size()); - return m_nodeList[index]; + Q_ASSERT(index >= 0 && index < m_nodes.size()); + return m_nodes[index]; } InternalNodePointer &find(InternalNodePointer node) { - auto found = std::find(m_nodeList.begin(), m_nodeList.end(), node); + auto found = std::find(m_nodes.begin(), m_nodes.end(), node); return *found; } - QList allSubNodes() const; - const QList &nodeList() const; + ManyNodes allSubNodes() const; + const FewNodes &nodeList() const; void slide(int from, int to); - void addSubNodes(QList &container) const; + void addSubNodes(ManyNodes &container) const; - QList::iterator begin() { return m_nodeList.begin(); } + FewNodes::iterator begin() { return m_nodes.begin(); } - QList::iterator end() { return m_nodeList.end(); } + FewNodes::iterator end() { return m_nodes.end(); } - const QList &nodes() const { return m_nodeList; } + const FewNodes &nodes() const { return m_nodes; } protected: void add(const InternalNodePointer &node) override; void remove(const InternalNodePointer &node) override; private: - QList m_nodeList; + FewNodes m_nodes; }; } // namespace Internal diff --git a/src/plugins/qmldesigner/libs/designercore/model/internalnodeproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/internalnodeproperty.cpp index d6bf0daf68a..235f8855fd0 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/internalnodeproperty.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/internalnodeproperty.cpp @@ -60,9 +60,9 @@ void InternalNodeProperty::add(const InternalNode::Pointer &node) m_node = node; } -QList InternalNodeProperty::allSubNodes() const +InternalNodeProperty::ManyNodes InternalNodeProperty::allSubNodes() const { - QList nodes; + ManyNodes nodes; nodes.reserve(1024); addSubNodes(nodes); @@ -70,7 +70,7 @@ QList InternalNodeProperty::allSubNodes() const return nodes; } -void InternalNodeProperty::addSubNodes(QList &container) const +void InternalNodeProperty::addSubNodes(ManyNodes &container) const { container.push_back(m_node); m_node->addSubNodes(container); diff --git a/src/plugins/qmldesigner/libs/designercore/model/internalnodeproperty.h b/src/plugins/qmldesigner/libs/designercore/model/internalnodeproperty.h index b1572962c25..f38db531294 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/internalnodeproperty.h +++ b/src/plugins/qmldesigner/libs/designercore/model/internalnodeproperty.h @@ -12,6 +12,8 @@ class InternalNodeProperty : public InternalNodeAbstractProperty { public: using Pointer = std::shared_ptr; + using ManyNodes = QVarLengthArray; + static constexpr PropertyType type = PropertyType::Node; InternalNodeProperty(PropertyNameView name, const InternalNodePointer &node); @@ -21,8 +23,8 @@ public: int count() const override; int indexOf(const InternalNodePointer &node) const override; - QList allSubNodes() const; - void addSubNodes(QList &container) const; + ManyNodes allSubNodes() const; + void addSubNodes(ManyNodes &container) const; const InternalNodePointer &node() const { return m_node; } diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index ed933550008..6bc7b683150 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -367,12 +367,12 @@ void ModelPrivate::removeNodeFromModel(const InternalNodePointer &node) node->resetParentProperty(); - m_selectedInternalNodeList.removeAll(node); + m_selectedInternalNodes.removeAll(node); if (!node->id.isEmpty()) m_idNodeHash.remove(node->id); node->isValid = false; node->traceToken.end(); - std::erase(m_nodes, node); + m_nodes.removeOne(node); m_internalIdNodeHash.remove(node->internalId); } @@ -677,10 +677,10 @@ void ModelPrivate::notifyInstanceErrorChange(const QVector &instanceIds) void ModelPrivate::notifyInstancesCompleted(const QVector &modelNodeVector) { - QVector internalVector(toInternalNodeVector(modelNodeVector)); + auto internalNodes = toInternalNodeList(modelNodeVector); notifyInstanceChanges([&](AbstractView *view) { - view->instancesCompleted(toModelNodeVector(internalVector, view)); + view->instancesCompleted(toModelNodeList(internalNodes, view)); }); } @@ -707,28 +707,28 @@ void ModelPrivate::notifyInstancesInformationsChange( void ModelPrivate::notifyInstancesRenderImageChanged(const QVector &modelNodeVector) { - QVector internalVector(toInternalNodeVector(modelNodeVector)); + auto internalNodes = toInternalNodeList(modelNodeVector); notifyInstanceChanges([&](AbstractView *view) { - view->instancesRenderImageChanged(toModelNodeVector(internalVector, view)); + view->instancesRenderImageChanged(toModelNodeList(internalNodes, view)); }); } void ModelPrivate::notifyInstancesPreviewImageChanged(const QVector &modelNodeVector) { - QVector internalVector(toInternalNodeVector(modelNodeVector)); + auto internalNodes = toInternalNodeList(modelNodeVector); notifyInstanceChanges([&](AbstractView *view) { - view->instancesPreviewImageChanged(toModelNodeVector(internalVector, view)); + view->instancesPreviewImageChanged(toModelNodeList(internalNodes, view)); }); } void ModelPrivate::notifyInstancesChildrenChanged(const QVector &modelNodeVector) { - QVector internalVector(toInternalNodeVector(modelNodeVector)); + auto internalNodes = toInternalNodeList(modelNodeVector); notifyInstanceChanges([&](AbstractView *view) { - view->instancesChildrenChanged(toModelNodeVector(internalVector, view)); + view->instancesChildrenChanged(toModelNodeList(internalNodes, view)); }); } @@ -802,10 +802,10 @@ void ModelPrivate::notifyRewriterEndTransaction() void ModelPrivate::notifyInstanceToken(const QString &token, int number, const QVector &modelNodeVector) { - QVector internalVector(toInternalNodeVector(modelNodeVector)); + auto internalNodes = toInternalNodeList(modelNodeVector); notifyInstanceChanges([&](AbstractView *view) { - view->instancesToken(token, number, toModelNodeVector(internalVector, view)); + view->instancesToken(token, number, toModelNodeList(internalNodes, view)); }); } @@ -814,7 +814,7 @@ void ModelPrivate::notifyCustomNotification(const AbstractView *senderView, const QList &modelNodeList, const QList &data) { - QList internalList(toInternalNodeList(modelNodeList)); + auto internalList = toInternalNodeList(modelNodeList); notifyNodeInstanceViewLast([&](AbstractView *view) { view->customNotification(senderView, identifier, toModelNodeList(internalList, view), data); }); @@ -1159,7 +1159,7 @@ void ModelPrivate::notifyNodeOrderChanged(const InternalNodeListProperty *intern }); } -void ModelPrivate::setSelectedNodes(const QList &selectedNodeList) +void ModelPrivate::setSelectedNodes(const FewNodes &selectedNodeList) { auto sortedSelectedList = Utils::filtered(selectedNodeList, [](const auto &node) { return node && node->isValid; @@ -1169,7 +1169,7 @@ void ModelPrivate::setSelectedNodes(const QList &selectedNo sortedSelectedList.erase(std::unique(sortedSelectedList.begin(), sortedSelectedList.end()), sortedSelectedList.end()); - if (sortedSelectedList == m_selectedInternalNodeList) + if (sortedSelectedList == m_selectedInternalNodes) return; auto flowToken = traceToken.tickWithFlow("selected model nodes"_t); @@ -1177,21 +1177,21 @@ void ModelPrivate::setSelectedNodes(const QList &selectedNo if constexpr (decltype(traceToken)::categoryIsActive()) { // the compiler should optimize it away but to be sure std::set_difference(sortedSelectedList.begin(), sortedSelectedList.end(), - m_selectedInternalNodeList.begin(), - m_selectedInternalNodeList.end(), + m_selectedInternalNodes.begin(), + m_selectedInternalNodes.end(), Utils::make_iterator([&](const auto &node) { node->traceToken.tick(flowToken, "select model node"_t); })); } - const QList lastSelectedNodeList = m_selectedInternalNodeList; - m_selectedInternalNodeList = sortedSelectedList; + const auto lastSelectedNodeList = std::move(m_selectedInternalNodes); + m_selectedInternalNodes = sortedSelectedList; if constexpr (decltype(traceToken)::categoryIsActive()) { // the compiler should optimize it away but to be sure std::set_difference(lastSelectedNodeList.begin(), lastSelectedNodeList.end(), - m_selectedInternalNodeList.begin(), - m_selectedInternalNodeList.end(), + m_selectedInternalNodes.begin(), + m_selectedInternalNodes.end(), Utils::make_iterator([&](const auto &node) { node->traceToken.tick(flowToken, "deselect model node"_t); })); @@ -1204,9 +1204,9 @@ void ModelPrivate::clearSelectedNodes() { auto tracer = traceToken.begin("clear selected model nodes"_t); - const QList lastSelectedNodeList = m_selectedInternalNodeList; - m_selectedInternalNodeList.clear(); - changeSelectedNodes(m_selectedInternalNodeList, lastSelectedNodeList); + auto lastSelectedNodeList = m_selectedInternalNodes; + m_selectedInternalNodes.clear(); + changeSelectedNodes(m_selectedInternalNodes, lastSelectedNodeList); } void ModelPrivate::removeAuxiliaryData(const InternalNodePointer &node, const AuxiliaryDataKeyView &key) @@ -1217,7 +1217,8 @@ void ModelPrivate::removeAuxiliaryData(const InternalNodePointer &node, const Au notifyAuxiliaryDataChanged(node, key, QVariant()); } -QList ModelPrivate::toModelNodeList(const QList &nodeList, AbstractView *view) const +QList ModelPrivate::toModelNodeList(std::span nodeList, + AbstractView *view) const { QList modelNodeList; modelNodeList.reserve(nodeList.size()); @@ -1227,19 +1228,9 @@ QList ModelPrivate::toModelNodeList(const QList return modelNodeList; } -QVector ModelPrivate::toModelNodeVector(const QVector &nodeVector, AbstractView *view) const +ModelPrivate::ManyNodes ModelPrivate::toInternalNodeList(const QList &modelNodeList) const { - QVector modelNodeVector; - modelNodeVector.reserve(nodeVector.size()); - for (const InternalNodePointer &node : nodeVector) - modelNodeVector.emplace_back(node, m_model, view); - - return modelNodeVector; -} - -QList ModelPrivate::toInternalNodeList(const QList &modelNodeList) const -{ - QList newNodeList; + ManyNodes newNodeList; newNodeList.reserve(modelNodeList.size()); for (const ModelNode &modelNode : modelNodeList) newNodeList.append(modelNode.internalNode()); @@ -1247,16 +1238,6 @@ QList ModelPrivate::toInternalNodeList(const QList ModelPrivate::toInternalNodeVector(const QVector &modelNodeVector) const -{ - QVector newNodeVector; - newNodeVector.reserve(modelNodeVector.size()); - for (const ModelNode &modelNode : modelNodeVector) - newNodeVector.append(modelNode.internalNode()); - - return newNodeVector; -} - QList ModelPrivate::toInternalProperties(const AbstractProperties &properties) { QList internalProperties; @@ -1290,8 +1271,8 @@ QList> ModelPrivate::toInternalBi return internalProperties; } -void ModelPrivate::changeSelectedNodes(const QList &newSelectedNodeList, - const QList &oldSelectedNodeList) +void ModelPrivate::changeSelectedNodes(const FewNodes &newSelectedNodeList, + const FewNodes &oldSelectedNodeList) { for (const QPointer &view : std::as_const(m_viewList)) { Q_ASSERT(view != nullptr); @@ -1305,14 +1286,15 @@ void ModelPrivate::changeSelectedNodes(const QList &newSele } } -QList ModelPrivate::selectedNodes() const +const ModelPrivate::FewNodes &ModelPrivate::selectedNodes() const { - for (const InternalNodePointer &node : m_selectedInternalNodeList) { + static FewNodes empty; + for (const InternalNodePointer &node : m_selectedInternalNodes) { if (!node->isValid) - return {}; + return empty; } - return m_selectedInternalNodeList; + return m_selectedInternalNodes; } void ModelPrivate::selectNode(const InternalNodePointer &node) @@ -1320,14 +1302,14 @@ void ModelPrivate::selectNode(const InternalNodePointer &node) if (selectedNodes().contains(node)) return; - QList selectedNodeList(selectedNodes()); + FewNodes selectedNodeList(selectedNodes()); selectedNodeList += node; setSelectedNodes(selectedNodeList); } void ModelPrivate::deselectNode(const InternalNodePointer &node) { - QList selectedNodeList(selectedNodes()); + FewNodes selectedNodeList(selectedNodes()); bool isRemoved = selectedNodeList.removeOne(node); if (isRemoved) @@ -1697,16 +1679,17 @@ bool ModelPrivate::hasNodeForInternalId(qint32 internalId) const { return m_internalIdNodeHash.contains(internalId); } -QList ModelPrivate::allNodesOrdered() const + +ModelPrivate::ManyNodes ModelPrivate::allNodesOrdered() const { if (!m_rootInternalNode || !m_rootInternalNode->isValid) return {}; // the nodes must be ordered. - QList nodeList; + ManyNodes nodeList; nodeList.append(m_rootInternalNode); - nodeList.append(m_rootInternalNode->allSubNodes()); + m_rootInternalNode->addSubNodes(nodeList); // FIXME: This is horribly expensive compared to a loop. auto nodesSorted = nodeList; @@ -1716,7 +1699,7 @@ QList ModelPrivate::allNodesOrdered() const return nodeList; } -std::vector ModelPrivate::allNodesUnordered() const +ModelPrivate::ManyNodes ModelPrivate::allNodesUnordered() const { return m_nodes; } @@ -2251,7 +2234,7 @@ void Model::setSelectedModelNodes(const QList &selectedNodeList) unlockedNodes.push_back(modelNode); } - d->setSelectedNodes(toInternalNodeList(unlockedNodes)); + d->setSelectedNodes(toInternalNodeList(unlockedNodes)); } void Model::clearMetaInfoCache() diff --git a/src/plugins/qmldesigner/libs/designercore/model/model_p.h b/src/plugins/qmldesigner/libs/designercore/model/model_p.h index a23a6f52182..030e6104ca2 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/libs/designercore/model/model_p.h @@ -79,6 +79,9 @@ class ModelPrivate : public QObject, friend Internal::WriteLocker; public: + using FewNodes = QVarLengthArray; + using ManyNodes = QVarLengthArray; + ModelPrivate(Model *model, ProjectStorageDependencies m_projectStorageDependencies, const TypeName &type, @@ -226,13 +229,12 @@ public: void notifyRewriterBeginTransaction(); void notifyRewriterEndTransaction(); - void setSelectedNodes(const QList &selectedNodeList); + void setSelectedNodes(const FewNodes &selectedNodeList); void clearSelectedNodes(); - QList selectedNodes() const; + const FewNodes &selectedNodes() const; void selectNode(const InternalNodePointer &node); void deselectNode(const InternalNodePointer &node); - void changeSelectedNodes(const QList &newSelectedNodeList, - const QList &oldSelectedNodeList); + void changeSelectedNodes(const FewNodes &newSelectedNodeList, const FewNodes &oldSelectedNodeList); void setAuxiliaryData(const InternalNodePointer &node, const AuxiliaryDataKeyView &key, @@ -296,8 +298,8 @@ public: InternalNodePointer nodeForInternalId(qint32 internalId) const; bool hasNodeForInternalId(qint32 internalId) const; - std::vector allNodesUnordered() const; - QList allNodesOrdered() const; + ManyNodes allNodesUnordered() const; + ManyNodes allNodesOrdered() const; bool isWriteLocked() const; @@ -330,10 +332,9 @@ private: void removePropertyWithoutNotification(InternalProperty *property); void removeAllSubNodes(const InternalNodePointer &node); void removeNodeFromModel(const InternalNodePointer &node); - QList toInternalNodeList(const QList &modelNodeList) const; - QList toModelNodeList(const QList &nodeList, AbstractView *view) const; - QVector toModelNodeVector(const QVector &nodeVector, AbstractView *view) const; - QVector toInternalNodeVector(const QVector &modelNodeVector) const; + ManyNodes toInternalNodeList(const QList &modelNodeList) const; + QList toModelNodeList(std::span nodeList, + AbstractView *view) const; static QList toInternalProperties(const AbstractProperties &properties); static QList> toInternalBindingProperties(const ModelResourceSet::SetExpressions &setExpressions); @@ -355,10 +356,10 @@ private: Imports m_possibleImportList; Imports m_usedImportList; QList> m_viewList; - QList m_selectedInternalNodeList; + FewNodes m_selectedInternalNodes; QHash m_idNodeHash; QHash m_internalIdNodeHash; - std::vector m_nodes; + ManyNodes m_nodes; InternalNodePointer m_currentStateNode; InternalNodePointer m_rootInternalNode; InternalNodePointer m_currentTimelineNode; diff --git a/src/plugins/qmldesigner/libs/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/libs/designercore/model/modelnode.cpp index a9bf091327e..8eba7549bf5 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/modelnode.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/modelnode.cpp @@ -1399,4 +1399,19 @@ QString ModelNode::behaviorPropertyName() const return m_internalNode->behaviorPropertyName; } +template +Result toInternalNodeList(const QList &nodeList) +{ + Result newNodeList; + for (const ModelNode &node : nodeList) + newNodeList.append(node.internalNode()); + + return newNodeList; +} + +template QMLDESIGNERCORE_EXPORT QVarLengthArray toInternalNodeList< + QVarLengthArray>(const QList &nodeList); +template QMLDESIGNERCORE_EXPORT QVarLengthArray toInternalNodeList< + QVarLengthArray>(const QList &nodeList); + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/libs/designercore/model/nodelistproperty.cpp b/src/plugins/qmldesigner/libs/designercore/model/nodelistproperty.cpp index c1462b45dbd..c1d307fab44 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/nodelistproperty.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/nodelistproperty.cpp @@ -40,12 +40,12 @@ Internal::InternalNodeListPropertyPointer &NodeListProperty::internalNodeListPro return m_internalNodeListProperty; } -static QList internalNodesToModelNodes(const QList &inputList, Model* model, AbstractView *view) +static QList internalNodesToModelNodes(const auto &inputList, Model *model, AbstractView *view) { QList modelNodeList; - for (const Internal::InternalNode::Pointer &internalNode : inputList) { + for (const Internal::InternalNode::Pointer &internalNode : inputList) modelNodeList.append(ModelNode(internalNode, model, view)); - } + return modelNodeList; } diff --git a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp index 85d795a5bcf..6f4fde65f61 100644 --- a/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp +++ b/src/plugins/qmldesigner/libs/designercore/projectstorage/projectstorageupdater.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -273,8 +274,8 @@ void ProjectStorageUpdater::update(Update update) keyValue("qml types paths", qmlTypesPaths)}; Storage::Synchronization::SynchronizationPackage package; - WatchedSourceIdsIds watchedSourceIds{Utils::span{directories}.size()}; - NotUpdatedSourceIds notUpdatedSourceIds{Utils::span{directories}.size()}; + WatchedSourceIdsIds watchedSourceIds{Utils::usize(directories)}; + NotUpdatedSourceIds notUpdatedSourceIds{Utils::usize(directories)}; updateDirectories(directories, package, notUpdatedSourceIds, watchedSourceIds); updateQmlTypes(qmlTypesPaths, package, notUpdatedSourceIds, watchedSourceIds); From f880edb808560c75416c75e3b805fd8b0e18327e Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 24 Sep 2024 12:51:31 +0200 Subject: [PATCH 189/193] QmlDesigner: Fix std::span to Utils::span Change-Id: I13a5c1ba4a6212d80a7edeb69067702261c2ed75 Reviewed-by: Tim Jenssen --- src/plugins/qmldesigner/libs/designercore/model/model.cpp | 2 +- src/plugins/qmldesigner/libs/designercore/model/model_p.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/libs/designercore/model/model.cpp b/src/plugins/qmldesigner/libs/designercore/model/model.cpp index 6bc7b683150..d38040a62d6 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/libs/designercore/model/model.cpp @@ -1217,7 +1217,7 @@ void ModelPrivate::removeAuxiliaryData(const InternalNodePointer &node, const Au notifyAuxiliaryDataChanged(node, key, QVariant()); } -QList ModelPrivate::toModelNodeList(std::span nodeList, +QList ModelPrivate::toModelNodeList(Utils::span nodeList, AbstractView *view) const { QList modelNodeList; diff --git a/src/plugins/qmldesigner/libs/designercore/model/model_p.h b/src/plugins/qmldesigner/libs/designercore/model/model_p.h index 030e6104ca2..feb9777e150 100644 --- a/src/plugins/qmldesigner/libs/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/libs/designercore/model/model_p.h @@ -333,7 +333,7 @@ private: void removeAllSubNodes(const InternalNodePointer &node); void removeNodeFromModel(const InternalNodePointer &node); ManyNodes toInternalNodeList(const QList &modelNodeList) const; - QList toModelNodeList(std::span nodeList, + QList toModelNodeList(Utils::span nodeList, AbstractView *view) const; static QList toInternalProperties(const AbstractProperties &properties); static QList> From b3c5c748c39dc66d0ed04e7baf6614d3bbf5f524 Mon Sep 17 00:00:00 2001 From: Vikas Pachdha Date: Mon, 23 Sep 2024 11:24:01 +0200 Subject: [PATCH 190/193] QmlDesigner: Fix incorrect bindings created for MCU Fixes: QDS-13714 Change-Id: I2e4708156d6b58e7e92788e1928f389f04d044eb Reviewed-by: Thomas Hartmann --- .../components/designsystem/dsthemegroup.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmldesigner/components/designsystem/dsthemegroup.cpp b/src/plugins/qmldesigner/components/designsystem/dsthemegroup.cpp index 4a26fef5ec9..ec55d234a91 100644 --- a/src/plugins/qmldesigner/components/designsystem/dsthemegroup.cpp +++ b/src/plugins/qmldesigner/components/designsystem/dsthemegroup.cpp @@ -180,9 +180,14 @@ void DSThemeGroup::decorate(ThemeId theme, ModelNode themeNode, DECORATION_CONTE auto &propData = themeValue->second; if (propData.isBinding) { auto bindingProp = targetNode->bindingProperty(propName); - if (bindingProp) - bindingProp.setDynamicTypeNameAndExpression(*typeName, - propData.value.toString()); + if (!bindingProp) + continue; + + if (decorationContext == DECORATION_CONTEXT::MCU) + bindingProp.setExpression(propData.value.toString()); + else + bindingProp.setDynamicTypeNameAndExpression(*typeName, propData.value.toString()); + } else { auto nodeProp = targetNode->variantProperty(propName); if (!nodeProp) From 49d1c12277c563ed5ce5f30ad64c7080a4d9ccbc Mon Sep 17 00:00:00 2001 From: Pranta Dastider Date: Fri, 20 Sep 2024 15:38:45 +0200 Subject: [PATCH 191/193] QmlDesigner: Update the document for Qt Design Studio and Python workflow You can now export the design made with Qt Design Studio for Python. This update tries to explain how that works. It also fixes some older text. Fixes: QDS-13486 Change-Id: Ibfc533ab0a319c209f60f3569ad31788de8eae69 Reviewed-by: Mats Honkamaa --- .../images/studio-project-export-cmake.webp | Bin 0 -> 10990 bytes .../studio-project-export-python-file.webp | Bin 0 -> 2368 bytes .../studio-project-export-python-folder.webp | Bin 0 -> 5116 bytes .../images/studio-project-export-python.webp | Bin 0 -> 10924 bytes .../images/studio-project-export.webp | Bin 10078 -> 0 bytes .../studio-designer-developer-workflow.qdoc | 102 ++++++++++++++++-- 6 files changed, 92 insertions(+), 10 deletions(-) create mode 100644 doc/qtdesignstudio/images/studio-project-export-cmake.webp create mode 100644 doc/qtdesignstudio/images/studio-project-export-python-file.webp create mode 100644 doc/qtdesignstudio/images/studio-project-export-python-folder.webp create mode 100644 doc/qtdesignstudio/images/studio-project-export-python.webp delete mode 100644 doc/qtdesignstudio/images/studio-project-export.webp diff --git a/doc/qtdesignstudio/images/studio-project-export-cmake.webp b/doc/qtdesignstudio/images/studio-project-export-cmake.webp new file mode 100644 index 0000000000000000000000000000000000000000..2590310bba4daed485b159b679928bb49b544f69 GIT binary patch literal 10990 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�L8 zF6M^il9%ZuGPK&+(m*qn#ir~HoB7)_aUCv+q0)5&{V z)KtWu%@a#?oSt!pf8SR=^VuBIsqZH&J1D&^{J-YeE9N=jg7a8oml>A-5;`jSKk_Bd zT|OyY-uWw5>pE2Io;vs4=d`~Z|JienRV{YzcHZ9X=6zV*ZC$&^wU_%OM6Z{%n9gUF zTKP~o`N5B^*^653b0$Z~np|r0pYll0&!xE`q4!Gc;b^5k6JO@cO%~V06xtUk3i7|S ziIgm~%6P&%Uqezy>+QWw_IIN{zk9@zA@WXYOZKyH^~8FP8N5rn?XDV5d%IwwdCelH z^Dlq2bi1`l)xT{iu6f_9oVI=8?2KjH5(PT99T#8t&^gheO{!e*LEo}Hs&-+X{Fg+} zO|G@h5RtMA>{{|%W_I82Z5i)ptmA!|)5AA$-MyWiP|4I!KX$JDaI`anU*OgS`8xrh zPksEsvW2bV#&6{h*Rq%HI4Y z+c)N@1bvuU=CE`^z@L@IW=SO)J@c*Z7-;_Ru|5#wp_b>CuJg1yQKypkX-CxTc@NfK zn#AO-xKM33W9-Xp&5TeF_kd>G+q_$N(?sRP8%=7K$qM!FyS`YtR`=QVhqnaX*0#5{ zrsf)~zUFy2{TAa_l@AYtcS|(n%O>ZaKD=P{#J=-enDtw4L`>XzbJED0&Q*5o-FxSy}%;#f946hHS6|%)qQ_6+^gE` z#+Us^KTUI;5-q&_!?w5oD}MftpSG`F{=c5cgnRrcvWXvhB2HiY0m@Q6M?BdQ7tT59 zE3$ws-<)wnf%=`7;*725C(p^)wmCCwECX)?k{h4guvxR47PsV}Lj1QlD)~C-jPcmI8#4c@hGS*S) zP2XAL3m?~I2zk#uXm!$g&JOW!D`rdF;Ny*(^zti@yKmmw-<`)Zo2Dw2H&~lg%z63M z=lbFI?$O*IWTk43p7dFKgs-5Tt)D%8xp~l1#p*XNRLT$ftWV!@c=_U6mgf1^*SIJ3 z{ZG5@uhhqMXW_xaKI@=@mv1(ZmrOabFxMX);u3BHFc#t zu+mGkyAUb3`tI3x8xO93$7Ywi!c{Tp{!8AHYsa$6jlb=lAH}@Dx}cuRj=R)u`>ne? z|DIg3J@DLI>cdp-(z0V&<)2sczc4>h!oc7f;pt|?$iU$1%b*2bSjo;P#K6qJz`)4B z$iToT#lQ+?GcY7EO2gS%j2ciiObiT+h73#$3=9ek3=Bn#MqsuG0|UdP_DlvAsNNL} z3=CHo_?9s+FsKW_XvdWNq*R4~jQo=P;*9(P1tU{ELn8%^@XWlF{PJQ=1|tI_6DtEt zD?M^8Tn1_lc!PhaM@U^M~^31AhBFd8Js kq5+oUVPIfjvi|^PgY~dDgW0?RNvYwC0t~E-pipE00C|^-RR910 literal 0 HcmV?d00001 diff --git a/doc/qtdesignstudio/images/studio-project-export-python-file.webp b/doc/qtdesignstudio/images/studio-project-export-python-file.webp new file mode 100644 index 0000000000000000000000000000000000000000..c4db72ebb9a27ebff35a38ed3dfdfad42e31a028 GIT binary patch literal 2368 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 E0OyU|&;S4c literal 0 HcmV?d00001 diff --git a/doc/qtdesignstudio/images/studio-project-export-python-folder.webp b/doc/qtdesignstudio/images/studio-project-export-python-folder.webp new file mode 100644 index 0000000000000000000000000000000000000000..a465f5160243834b11b546e20d2f2fb093d163ff GIT binary patch literal 5116 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 literal 0 HcmV?d00001 diff --git a/doc/qtdesignstudio/images/studio-project-export-python.webp b/doc/qtdesignstudio/images/studio-project-export-python.webp new file mode 100644 index 0000000000000000000000000000000000000000..647ec7426349c2d919f8d38c6150a697c2210045 GIT binary patch literal 10924 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 diff --git a/doc/qtdesignstudio/src/developers/studio-designer-developer-workflow.qdoc b/doc/qtdesignstudio/src/developers/studio-designer-developer-workflow.qdoc index e214b7709e3..5b59d665971 100644 --- a/doc/qtdesignstudio/src/developers/studio-designer-developer-workflow.qdoc +++ b/doc/qtdesignstudio/src/developers/studio-designer-developer-workflow.qdoc @@ -27,14 +27,19 @@ \e CMakeLists.txt file as the project file. This enables you to share your project as a fully working C++ application with developers. - To export a \QDS project for Qt Creator, you need: + You can also enable \QDS projects for Python development. When enabled, + \QDS creates a Python folder within the project folder with the file + \e {main.py}. Use this file to start the development in Python for the UI + made with \QDS. - \list - \li Qt Creator 13.0 or above. - \li \QDS 4.5 or above. - \endlist + \section1 Exporting a \QDS Project for C++ Development - \section1 Exporting a \QDS Project + To export a \QDS project for Qt Creator, you need: + + \list + \li Qt Creator 13.0 or above. + \li \QDS 4.5 or above. + \endlist \list 1 \li \l {Creating a Project} {Create} or open your \QDS project with \QDS 4.5 or above. @@ -44,14 +49,14 @@ used in your Qt Creator. \li Go to \uicontrol {File} > \uicontrol {Export Project} - > \uicontrol {Enable Automatic CMake Generation}. This creates a + > \uicontrol {Enable CMake Generator}. This creates a \e {CMakeLists.txt} file in your project folder. - \note Enabling this option tracks the changes made to the project in Qt Creator - and automatically updates in \QDS. The connection works unless you + \note Enabling this option tracks the changes made to the project in \QDS + and automatically updates in Qt Creator. The connection works unless you deactivate the option. - \image studio-project-export.webp "Exporting Qt Design Studio project" + \image studio-project-export-cmake.webp "Exporting Qt Design Studio project to CMake" \endlist \section1 Opening the \QDS Project in Qt Creator @@ -76,4 +81,81 @@ \image qtcreator-qt-design-studio-project.webp "Qt Design studio projects in Qt Creator after successful import" \li To run the project, select \uicontrol Run. \endlist + + \note \QDS 4.4 and earlier versions have a project structure where + different explicit import paths such as \e imports or \e asset_imports + reference assets such as images or mesh files separately in their own + scope. So, linking them from one module to another does not work in the + generated CMake-based C++ application. Such cross-modular references are + not considered good practice. Since \QDS 4.5, this issue has been solved. + All the import assets are now bundled in the same folder, so the CMake + generation works properly. + + \section1 Exporting a \QDS Project for Python Development + + \list 1 + \li \l {Creating a Project} {Create} a project with \QDS 4.5 or above. + Then open your \QDS project with \QDS 4.6 or above. + + \note You cannot export a project created with \QDS 4.4 or an + earlier version of \QDS for Python development. + + \li Go to \uicontrol {File} > \uicontrol {Export Project} + > \uicontrol {Enable Python Generator}. This creates a + Python folder in your project folder. You can find the + \e {main.py} file in the Python folder. This file is + necessary for working in Python. + + \note Do not modify the contents of the \e {autogen} folder inside + the Python folder manually; they are overwritten with each + change you make in the project. + + \image studio-project-export-python.webp "Exporting Qt Design Studio project to Python" + \endlist + + \section1 Opening the \QDS Project with Python + + After your project have the Python folder and the \e {main.py} file + available, you can start setting up your Python environment for developing + with \QDS projects. + + \table + \row + \li {2,1} \image studio-project-export-python-folder.webp "The generated Python folder in the Qt Design Studio project" + \li {2,2} \image studio-project-export-python-file.webp "The generated Python file in the Qt Design Studio project" + \endtable + \list 1 + \li If you don't have Python installed on your computer, install it. + The latest version of Python is available + \l {https://www.python.org/downloads/} {here}. + + \li Next, follow the steps from this document to + \l {https://doc.qt.io/qtforpython-6/quickstart.html} {install PySide6}. + You need this for working with Qt in Python. + + \note You need Python version between 3.8 and 3.13 to install + PySide6. + + \li After installing PySide6, install \QDS packages for PySide6. Stay + in the virtual environment that was accessed for installing + PySide6. From there, execute the command in the command prompt. + \code + pip install PySide6_DS + \endcode + + \li Go to your project folder in the command prompt. + \code + cd path/to/your/project/folder + \endcode + + \li Finally, run the command below in the command prompt to open the + \e {main.py} file from your project. + \code + python Python\main.py + \endcode + \endlist + + Your \QDS project now runs in Python. Use Python to add more + functionalities to the project. Go to \l {Qt for Python} to learn more + about developing Qt projects using Python. */ From fa8b15679553a981664674941ac68ca50c3309b1 Mon Sep 17 00:00:00 2001 From: Przemyslaw Lewandowski Date: Tue, 24 Sep 2024 16:01:28 +0200 Subject: [PATCH 192/193] AssetImporter: Fix design system bindings for newly created types Change-Id: I576db008bc309ee5715cc2247f9f3f06d81c0818 Reviewed-by: Thomas Hartmann --- .../libs/designercore/rewriter/texttomodelmerger.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.cpp b/src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.cpp index b91434d78d2..b61330aa5ec 100644 --- a/src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/libs/designercore/rewriter/texttomodelmerger.cpp @@ -1432,6 +1432,9 @@ QmlDesigner::PropertyName TextToModelMerger::syncScriptBinding(ModelNode &modelN prefix, script->qualifiedId, astValue); + // Can happen if the type was just created and was not fully processed yet + const bool newlyCreatedTypeCase = !modelNode.metaInfo().properties().size(); + if (enumValue.isValid()) { // It is a qualified enum: AbstractProperty modelProperty = modelNode.property(astPropertyName.toUtf8()); syncVariantProperty(modelProperty, enumValue, TypeName(), differenceHandler); // TODO: parse type @@ -1439,7 +1442,8 @@ QmlDesigner::PropertyName TextToModelMerger::syncScriptBinding(ModelNode &modelN } else { // Not an enum, so: if (isPropertyChangesType(modelNode.type()) || isConnectionsType(modelNode.type()) || isSupportedAttachedProperties(astPropertyName) - || modelNode.metaInfo().hasProperty(astPropertyName.toUtf8())) { + || modelNode.metaInfo().hasProperty(astPropertyName.toUtf8()) + || newlyCreatedTypeCase) { AbstractProperty modelProperty = modelNode.property(astPropertyName.toUtf8()); syncExpressionProperty(modelProperty, astValue, TypeName(), differenceHandler); // TODO: parse type return astPropertyName.toUtf8(); From 6068df5540ddb0d38580be982af3bd1c9a154900 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 24 Sep 2024 11:19:54 +0200 Subject: [PATCH 193/193] Utils: Update span The last snapshot had probems with ranges. Change-Id: I338c4d7a5d82fd65d4500cebec605a4652de0c1c Reviewed-by: Tim Jenssen --- qt_attributions.json | 1 + src/libs/3rdparty/span/README.md | 2 +- src/libs/3rdparty/span/span.hpp | 10 +++++----- src/libs/utils/span.h | 3 +++ 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/qt_attributions.json b/qt_attributions.json index 37dabd8e7fc..5f9e1e5343d 100644 --- a/qt_attributions.json +++ b/qt_attributions.json @@ -335,6 +335,7 @@ "Path": "src/libs/3rdparty/span", "Description": "A single-header implementation of C++20's std::span, conforming to the C++20 committee draft.", "Homepage": "https://github.com/martinmoene/span-lite", + "Version": "00afc28", "License": "Boost Software License 1.0", "LicenseFile": "src/libs/3rdparty/span/LICENSE_1_0.txt", "Copyright": "Copyright 2018-2021 Martin Moene" diff --git a/src/libs/3rdparty/span/README.md b/src/libs/3rdparty/span/README.md index dcc95ab6cea..6debd010a3c 100644 --- a/src/libs/3rdparty/span/README.md +++ b/src/libs/3rdparty/span/README.md @@ -1,7 +1,7 @@ # span lite: A single-file header-only version of a C++20-like span for C++98, C++11 and later -[![Language](https://img.shields.io/badge/C%2B%2B-98/11/14/17/20-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) [![License](https://img.shields.io/badge/license-BSL-blue.svg)](https://opensource.org/licenses/BSL-1.0) [![Build Status](https://github.com/martinmoene/span-lite/actions/workflows/ci.yml/badge.svg)](https://github.com/martinmoene/span-lite/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/1ha3wnxtam547m8p?svg=true)](https://ci.appveyor.com/project/martinmoene/span-lite) [![Version](https://badge.fury.io/gh/martinmoene%2Fspan-lite.svg)](https://github.com/martinmoene/span-lite/releases) [![download](https://img.shields.io/badge/latest-download-blue.svg)](https://github.com/martinmoene/span-lite/blob/master/include/nonstd/span.hpp) [![Conan](https://img.shields.io/badge/on-conan-blue.svg)](https://conan.io/center/span-lite) [![Try it on wandbox](https://img.shields.io/badge/on-wandbox-blue.svg)](https://wandbox.org/permlink/venR3Ko2Q4tlvcVk) [![Try it on godbolt online](https://img.shields.io/badge/on-godbolt-blue.svg)](https://godbolt.org/z/htwpnb) +[![Language](https://img.shields.io/badge/C%2B%2B-98/11/14/17/20-blue.svg)](https://en.wikipedia.org/wiki/C%2B%2B#Standardization) [![License](https://img.shields.io/badge/license-BSL-blue.svg)](https://opensource.org/licenses/BSL-1.0) [![Build Status](https://github.com/martinmoene/span-lite/actions/workflows/ci.yml/badge.svg)](https://github.com/martinmoene/span-lite/actions/workflows/ci.yml) [![Build status](https://ci.appveyor.com/api/projects/status/1ha3wnxtam547m8p?svg=true)](https://ci.appveyor.com/project/martinmoene/span-lite) [![Version](https://badge.fury.io/gh/martinmoene%2Fspan-lite.svg)](https://github.com/martinmoene/span-lite/releases) [![download](https://img.shields.io/badge/latest-download-blue.svg)](https://github.com/martinmoene/span-lite/blob/master/include/nonstd/span.hpp) [![Conan](https://img.shields.io/badge/on-conan-blue.svg)](https://conan.io/center/span-lite) [![Vcpkg](https://img.shields.io/badge/on-vcpkg-blue.svg)](https://vcpkg.link/ports/span-lite) [![Try it on wandbox](https://img.shields.io/badge/on-wandbox-blue.svg)](https://wandbox.org/permlink/venR3Ko2Q4tlvcVk) [![Try it on godbolt online](https://img.shields.io/badge/on-godbolt-blue.svg)](https://godbolt.org/z/htwpnb) **Contents** diff --git a/src/libs/3rdparty/span/span.hpp b/src/libs/3rdparty/span/span.hpp index fa6e51735f9..9a7182f5b0b 100644 --- a/src/libs/3rdparty/span/span.hpp +++ b/src/libs/3rdparty/span/span.hpp @@ -12,8 +12,8 @@ #define NONSTD_SPAN_HPP_INCLUDED #define span_lite_MAJOR 0 -#define span_lite_MINOR 10 -#define span_lite_PATCH 3 +#define span_lite_MINOR 11 +#define span_lite_PATCH 0 #define span_lite_VERSION span_STRINGIFY(span_lite_MAJOR) "." span_STRINGIFY(span_lite_MINOR) "." span_STRINGIFY(span_lite_PATCH) @@ -346,6 +346,7 @@ span_DISABLE_MSVC_WARNINGS( 26439 26440 26472 26473 26481 26490 ) #define span_HAVE_IS_DEFAULT span_CPP11_140 #define span_HAVE_IS_DELETE span_CPP11_140 #define span_HAVE_NOEXCEPT span_CPP11_140 +#define span_HAVE_NORETURN ( span_CPP11_140 && ! span_BETWEEN( span_COMPILER_GNUC_VERSION, 1, 480 ) ) #define span_HAVE_NULLPTR span_CPP11_100 #define span_HAVE_STATIC_ASSERT span_CPP11_100 @@ -357,7 +358,6 @@ span_DISABLE_MSVC_WARNINGS( 26439 26440 26472 26473 26481 26490 ) #define span_HAVE_DEPRECATED span_CPP17_000 #define span_HAVE_NODISCARD span_CPP17_000 -#define span_HAVE_NORETURN span_CPP17_000 // MSVC: template parameter deduction guides since Visual Studio 2017 v15.7 @@ -1870,7 +1870,7 @@ using span_lite::byte_span; #endif // span_FEATURE( BYTE_SPAN ) -#if span_HAVE( STRUCT_BINDING ) +#if !span_USES_STD_SPAN && span_HAVE( STRUCT_BINDING ) #if span_CPP14_OR_GREATER # include @@ -1938,7 +1938,7 @@ span_constexpr ElementType const & get( nonstd::span const } // end namespace std -#endif // span_HAVE( STRUCT_BINDING ) +#endif // !span_USES_STD_SPAN && span_HAVE( STRUCT_BINDING ) #if ! span_USES_STD_SPAN span_RESTORE_WARNINGS() diff --git a/src/libs/utils/span.h b/src/libs/utils/span.h index d21bb9ab00b..f2c545940b7 100644 --- a/src/libs/utils/span.h +++ b/src/libs/utils/span.h @@ -32,7 +32,10 @@ QT_WARNING_PUSH #include <3rdparty/span/span.hpp> namespace Utils { using namespace nonstd; + } +template +inline constexpr bool std::ranges::enable_borrowed_range> = true; QT_WARNING_POP #endif