summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2022-09-27 10:03:37 +0200
committerEike Ziller <eike.ziller@qt.io>2022-09-27 10:03:37 +0200
commit7eaa36e6e58a7c4ff8ec8a691c2a5abc39ae5f30 (patch)
tree872b997978f8065ec1d58df52301d9e1b308683c
parent21c5d3499ba143f4ff703410174e27c11f7ddda3 (diff)
parent4da66867051b27354b71ff6b4690d4e2d1e53bd6 (diff)
downloadqt-creator-7eaa36e6e58a7c4ff8ec8a691c2a5abc39ae5f30.tar.gz
Merge remote-tracking branch 'origin/8.0' into 9.0
Conflicts: src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp src/plugins/qmldesigner/designercore/imagecache/meshimagecachecollector.cpp Change-Id: I38f196e8f42cf11f7b613e7a723745600e35c5e9
-rw-r--r--doc/qtdesignstudio/images/3d-view-context-menu.pngbin0 -> 4571 bytes
-rw-r--r--doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-camera.qdoc16
-rw-r--r--doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc10
-rw-r--r--doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc11
-rw-r--r--doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-model.qdoc17
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp2
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp16
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.h4
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.cpp11
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.h3
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp8
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h1
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.cpp9
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.h4
-rw-r--r--share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp14
-rw-r--r--share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml4
-rw-r--r--share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml4
-rw-r--r--share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml4
-rw-r--r--share/qtcreator/qmldesigner/newstateseditor/Main.qml83
-rw-r--r--share/qtcreator/qmldesigner/newstateseditor/StateScrollBar.qml10
-rw-r--r--share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml42
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQml/TimerSpecifics.qml109
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml1
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml9
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml9
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/qmldir1
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SearchBox.qml (renamed from share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SearchBox.qml)4
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml34
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/qmldir1
-rw-r--r--share/qtcreator/themes/dark.creatortheme4
-rw-r--r--share/qtcreator/themes/design.creatortheme4
-rw-r--r--share/qtcreator/themes/flat-dark.creatortheme4
-rw-r--r--share/qtcreator/themes/flat.creatortheme4
-rw-r--r--src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp2
-rw-r--r--src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h2
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp64
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/actioneditor.h5
-rw-r--r--src/plugins/qmldesigner/components/componentcore/componentcore_constants.h3
-rw-r--r--src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp302
-rw-r--r--src/plugins/qmldesigner/components/debugview/debugview.cpp10
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp2
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h2
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp9
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/bundlematerial.cpp8
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/bundlematerial.h5
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp20
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp9
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp164
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h5
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp2
-rw-r--r--src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h2
-rw-r--r--src/plugins/qmldesigner/components/stateseditornew/stateseditorview.cpp5
-rw-r--r--src/plugins/qmldesigner/designercore/imagecache/meshimagecachecollector.cpp10
-rw-r--r--src/plugins/qmldesigner/designercore/include/stylesheetmerger.h6
-rw-r--r--src/plugins/qmldesigner/designercore/model/rewriterview.cpp2
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/images/timer-16px.pngbin0 -> 339 bytes
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/images/timer-24px.pngbin0 -> 712 bytes
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/images/timer-24px@2x.pngbin0 -> 1305 bytes
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc3
-rw-r--r--src/plugins/qmldesigner/qtquickplugin/quick.metainfo19
-rw-r--r--src/plugins/studiowelcome/userpresets.cpp15
61 files changed, 932 insertions, 201 deletions
diff --git a/doc/qtdesignstudio/images/3d-view-context-menu.png b/doc/qtdesignstudio/images/3d-view-context-menu.png
new file mode 100644
index 0000000000..c2e35e0019
--- /dev/null
+++ b/doc/qtdesignstudio/images/3d-view-context-menu.png
Binary files differ
diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-camera.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-camera.qdoc
index 303a713a63..202249188d 100644
--- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-camera.qdoc
+++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-camera.qdoc
@@ -16,10 +16,18 @@
\image studio-qtquick-3d-components.png "Qt Quick 3D components in Components"
- Add a camera by dragging-and-dropping one of the camera components from
- \uicontrol Components > \uicontrol {Qt Quick 3D} > \uicontrol
- {Qt Quick 3D} to the \l {3D} view or to a 3D view in \l Navigator.
- If the cameras are not displayed in \uicontrol {Components}, add the
+ To add a camera component to your UI, do one of the following:
+ \list
+ \li Drag a camera component from \uicontrol Components >
+ \uicontrol {Qt Quick 3D} to the \l {3D} view or to
+ \l Navigator > \uicontrol {View3D} > \uicontrol Scene.
+ \li Right-click in the \uicontrol 3D view and select
+ \uicontrol Create > \uicontrol Cameras from the context menu.
+ \note You can only create \uicontrol {Camera Perspective} and
+ \uicontrol {Camera Ortographic} this way.
+ \endlist
+
+ If you cannot find the camera components in \uicontrol {Components}, add the
\uicontrol QtQuick3D module to your project, as described in
\l {Adding and Removing Modules}.
diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc
index e7487a7709..810692e89b 100644
--- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc
+++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc
@@ -48,6 +48,16 @@
Additionally, you can toggle the visibility of the grid, selection boxes,
icon gizmos, and camera frustums in the 3D scene.
+ There is a context menu in the \uicontrol 3D view. To open it, right-click
+ in the \uicontrol 3D view. From the context menu you can:
+ \list
+ \li Create cameras, lights, and models.
+ \li Open \uicontrol {Material Editor} and edit materials.
+ \li Delete components
+ \endlist
+
+ \image 3d-view-context-menu.png
+
To refresh the contents of the \uicontrol{3D} view, press \key P or
select the \inlineimage icons/reset.png
(\uicontrol {Reset View}) button.
diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc
index 4ce143c8ce..4bd44874ab 100644
--- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc
+++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc
@@ -12,9 +12,14 @@
As a secondary light source, you can use \l{Setting the Light Probe}
{image-based lighting}.
- To add light components to your UI, drag-and-drop them from
- \uicontrol Components > \uicontrol {Qt Quick 3D} to the \l {3D} view or to
- \l Navigator > \uicontrol {Scene Environment} > \uicontrol Scene.
+ To add a light component to your UI, do one of the following:
+ \list
+ \li Drag a light component from \uicontrol Components >
+ \uicontrol {Qt Quick 3D} to the \l {3D} view or to
+ \l Navigator > \uicontrol {View3D} > \uicontrol Scene.
+ \li Right-click in the \uicontrol 3D view and select
+ \uicontrol Create > \uicontrol Lights from the context menu.
+ \endlist
If you cannot find the light components in \uicontrol {Components}, add the
\uicontrol {Qt Quick 3D} module to your project as instructed in
diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-model.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-model.qdoc
index 629a628490..9070ef0835 100644
--- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-model.qdoc
+++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-model.qdoc
@@ -13,14 +13,21 @@
\image studio-3d-models.png "Various 3D models in the 3D view"
- A Model component loads mesh data from a file. You can modify how the
+ A model component loads mesh data from a file. You can modify how the
component is shaded by using materials. For more information, see
\l {Materials and Shaders} and \l {Creating Custom Materials}.
- You can drag-and-drop a model from \uicontrol Components
- > \uicontrol {Qt Quick 3D} > \uicontrol {Qt Quick 3D} to the \l {3D} view or
- to \l Navigator > \uicontrol {Scene Environment} > \uicontrol Scene. If the
- models are not displayed in \uicontrol {Components}, you should add the
+ To add a model component to your UI, do one of the following:
+ \list
+ \li Drag a model component from \uicontrol Components >
+ \uicontrol {Qt Quick 3D} to the \l {3D} view or to
+ \l Navigator > \uicontrol {View3D} > \uicontrol Scene.
+ \li Right-click in the \uicontrol 3D view and select
+ \uicontrol Create > \uicontrol Primitives from the context menu.
+ \note You can not create \uicontrol Empty models this way.
+ \endlist
+
+ If you cannot find the model components in \uicontrol {Components}, add the
\uicontrol QtQuick3D module to your project, as described in
\l {Adding and Removing Modules}.
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp
index d1b7beda4e..9fe970f8c7 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp
@@ -511,7 +511,7 @@ void NodeInstanceServer::setupOnlyWorkingImports(const QStringList &workingImpor
quickView()->setContent(fileUrl(), m_importComponent, quickView()->rootObject());
m_importComponent->setData(componentCode.append("\nItem {}\n"), fileUrl());
- m_importComponentObject = m_importComponent->create();
+ m_importComponentObject = m_importComponent->create(engine()->rootContext());
Q_ASSERT(m_importComponent && m_importComponentObject);
Q_ASSERT_X(m_importComponent->errors().isEmpty(), __FUNCTION__, m_importComponent->errorString().toLatin1());
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp
index f2f869de19..e60ca48da7 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp
@@ -94,5 +94,21 @@ bool QmlStateNodeInstance::resetStateProperty(const ObjectNodeInstance::Pointer
return QmlPrivateGate::States::resetStateProperty(object(), target->object(), propertyName, resetValue);
}
+void QmlStateNodeInstance::reparent(const ObjectNodeInstance::Pointer &oldParentInstance,
+ const PropertyName &oldParentProperty,
+ const ObjectNodeInstance::Pointer &newParentInstance,
+ const PropertyName &newParentProperty)
+{
+ ServerNodeInstance oldState = nodeInstanceServer()->activeStateInstance();
+
+ ObjectNodeInstance::reparent(oldParentInstance,
+ oldParentProperty,
+ newParentInstance,
+ newParentProperty);
+
+ if (oldState.isValid())
+ oldState.activateState();
+}
+
} // namespace Internal
} // namespace QmlDesigner
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.h
index 0564ffbc40..95fce95c1b 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.h
@@ -27,6 +27,10 @@ public:
bool updateStateBinding(const ObjectNodeInstance::Pointer &target, const PropertyName &propertyName, const QString &expression) override;
bool resetStateProperty(const ObjectNodeInstance::Pointer &target, const PropertyName &propertyName, const QVariant &resetValue) override;
+ void reparent(const ObjectNodeInstance::Pointer &oldParentInstance,
+ const PropertyName &oldParentProperty,
+ const ObjectNodeInstance::Pointer &newParentInstance,
+ const PropertyName &newParentProperty) override;
protected:
QmlStateNodeInstance(QObject *object);
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.cpp
index 0ed2d71028..d518fa6ae5 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.cpp
@@ -15,12 +15,13 @@ Quick3DMaterialNodeInstance::~Quick3DMaterialNodeInstance()
{
}
-void Quick3DMaterialNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance,
- InstanceContainer::NodeFlags flags)
+void Quick3DMaterialNodeInstance::invokeDummyViewCreate() const
{
- m_dummyRootViewCreateFunction = "createViewForMaterial";
-
- Quick3DRenderableNodeInstance::initialize(objectNodeInstance, flags);
+ QMetaObject::invokeMethod(m_dummyRootView, "createViewForMaterial",
+ Q_ARG(QVariant, QVariant::fromValue(object())),
+ Q_ARG(QVariant, ""),
+ Q_ARG(QVariant, ""),
+ Q_ARG(QVariant, ""));
}
Quick3DMaterialNodeInstance::Pointer Quick3DMaterialNodeInstance::create(QObject *object)
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.h
index 8a3fd97237..84edfc2ea0 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.h
@@ -19,11 +19,10 @@ public:
~Quick3DMaterialNodeInstance() override;
static Pointer create(QObject *objectToBeWrapped);
- void initialize(const ObjectNodeInstance::Pointer &objectNodeInstance,
- InstanceContainer::NodeFlags flags) override;
protected:
explicit Quick3DMaterialNodeInstance(QObject *node);
+ void invokeDummyViewCreate() const override;
};
} // namespace Internal
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp
index 4755c8d416..95e4a8281b 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp
@@ -24,6 +24,12 @@ Quick3DNodeInstance::Quick3DNodeInstance(QObject *node)
{
}
+void Quick3DNodeInstance::invokeDummyViewCreate() const
+{
+ QMetaObject::invokeMethod(m_dummyRootView, "createViewForNode",
+ Q_ARG(QVariant, QVariant::fromValue(object())));
+}
+
Quick3DNodeInstance::~Quick3DNodeInstance()
{
}
@@ -58,8 +64,6 @@ void Quick3DNodeInstance::initialize(
}
}
- m_dummyRootViewCreateFunction = "createViewForNode";
-
Quick3DRenderableNodeInstance::initialize(objectNodeInstance, flags);
#endif // QUICK3D_MODULE
}
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h
index 2c1f6372bc..b8120a9092 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h
@@ -25,6 +25,7 @@ public:
protected:
explicit Quick3DNodeInstance(QObject *node);
+ void invokeDummyViewCreate() const override;
private:
QQuick3DNode *quick3DNode() const;
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.cpp
index ce6e94b4ae..67741db5de 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.cpp
@@ -28,7 +28,7 @@ Quick3DRenderableNodeInstance::~Quick3DRenderableNodeInstance()
}
void Quick3DRenderableNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance,
- InstanceContainer::NodeFlags flags)
+ InstanceContainer::NodeFlags flags)
{
#ifdef QUICK3D_MODULE
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
@@ -45,8 +45,7 @@ void Quick3DRenderableNodeInstance::initialize(const ObjectNodeInstance::Pointer
component.loadUrl(QUrl("qrc:/qtquickplugin/mockfiles/qt6/ModelNode3DImageView.qml"));
m_dummyRootView = qobject_cast<QQuickItem *>(component.create());
- QMetaObject::invokeMethod(m_dummyRootView, m_dummyRootViewCreateFunction,
- Q_ARG(QVariant, QVariant::fromValue(object())));
+ invokeDummyViewCreate();
nodeInstanceServer()->setRootItem(m_dummyRootView);
}
@@ -192,6 +191,10 @@ Qt5NodeInstanceServer *Quick3DRenderableNodeInstance::qt5NodeInstanceServer() co
return qobject_cast<Qt5NodeInstanceServer *>(nodeInstanceServer());
}
+void Quick3DRenderableNodeInstance::invokeDummyViewCreate() const
+{
+}
+
} // namespace Internal
} // namespace QmlDesigner
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.h
index 8c82eed987..98fba654d8 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.h
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.h
@@ -35,10 +35,8 @@ public:
protected:
explicit Quick3DRenderableNodeInstance(QObject *node);
Qt5NodeInstanceServer *qt5NodeInstanceServer() const;
+ virtual void invokeDummyViewCreate() const;
- QByteArray m_dummyRootViewCreateFunction;
-
-private:
QQuickItem *m_dummyRootView = nullptr;
};
diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp
index 2e6ccead54..918e147798 100644
--- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp
+++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp
@@ -846,6 +846,10 @@ void QuickItemNodeInstance::setPropertyVariant(const PropertyName &name, const Q
void QuickItemNodeInstance::setPropertyBinding(const PropertyName &name, const QString &expression)
{
+ static QList<PropertyName> anchorsTargets = {"anchors.top",
+ "acnhors.bottom",
+ "anchors.left",
+ "achors.right"};
if (ignoredProperties().contains(name))
return;
@@ -857,7 +861,15 @@ void QuickItemNodeInstance::setPropertyBinding(const PropertyName &name, const Q
markRepeaterParentDirty();
- ObjectNodeInstance::setPropertyBinding(name, expression);
+ if (anchorsTargets.contains(name)) {
+ //When resolving anchor targets we have to provide the root context the ids are defined in.
+ QmlPrivateGate::setPropertyBinding(object(),
+ context()->engine()->rootContext(),
+ name,
+ expression);
+ } else {
+ ObjectNodeInstance::setPropertyBinding(name, expression);
+ }
refresh();
diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml
index afe81c3b8f..1b9a284ce1 100644
--- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml
+++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml
@@ -414,10 +414,12 @@ Item {
width: parent.width
- SearchBox {
+ StudioControls.SearchBox {
id: searchBox
width: parent.width - addAssetButton.width - 5
+
+ onSearchChanged: (searchText) => rootView.handleSearchFilterChanged(searchText)
}
IconButton {
diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml
index c62a4cc82e..c523fb7b70 100644
--- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml
+++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml
@@ -199,10 +199,12 @@ Item {
Row {
width: parent.width
- SearchBox {
+ StudioControls.SearchBox {
id: searchBox
width: parent.width - addModuleButton.width - 5
+
+ onSearchChanged: (searchText) => rootView.handleSearchFilterChanged(searchText)
}
IconButton {
diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml
index bda29dcb13..ba72ef03a8 100644
--- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml
+++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml
@@ -208,10 +208,12 @@ Item {
width: root.width
enabled: !materialBrowserModel.hasMaterialRoot && materialBrowserModel.hasQuick3DImport
- SearchBox {
+ StudioControls.SearchBox {
id: searchBox
width: root.width - addMaterialButton.width
+
+ onSearchChanged: (searchText) => rootView.handleSearchFilterChanged(searchText)
}
IconButton {
diff --git a/share/qtcreator/qmldesigner/newstateseditor/Main.qml b/share/qtcreator/qmldesigner/newstateseditor/Main.qml
index 8f50d8f336..29feb5741d 100644
--- a/share/qtcreator/qmldesigner/newstateseditor/Main.qml
+++ b/share/qtcreator/qmldesigner/newstateseditor/Main.qml
@@ -26,6 +26,7 @@
import QtQuick
import QtQuick.Controls
import StatesEditor
+import HelperWidgets 2.0 as HelperWidgets
import StudioControls 1.0 as StudioControls
import StudioTheme as StudioTheme
@@ -369,6 +370,23 @@ Rectangle {
width: stateGroupLabel.visible ? StudioTheme.Values.defaultControlWidth
: root.width - 2 * root.padding
+ HelperWidgets.Tooltip { id: comboBoxTooltip }
+
+ Timer {
+ interval: 1000
+ running: stateGroupComboBox.hovered
+ onTriggered: comboBoxTooltip.showText(stateGroupComboBox,
+ hoverHandler.point.position,
+ qsTr("Switch State Group"))
+ }
+
+ onHoverChanged: {
+ if (!stateGroupComboBox.hovered)
+ comboBoxTooltip.hideText()
+ }
+
+ HoverHandler { id: hoverHandler }
+
popup.onOpened: editDialog.close()
// currentIndex needs special treatment, because if model is changed, it will be
@@ -398,25 +416,28 @@ Rectangle {
spacing: StudioTheme.Values.toolbarSpacing
leftPadding: toolBar.doubleRow ? root.padding : 0
- StudioControls.AbstractButton {
+ HelperWidgets.AbstractButton {
buttonIcon: StudioTheme.Constants.plus
anchors.verticalCenter: parent.verticalCenter
+ tooltip: qsTr("Create State Group")
onClicked: statesEditorModel.addStateGroup("stateGroup")
}
- StudioControls.AbstractButton {
+ HelperWidgets.AbstractButton {
buttonIcon: StudioTheme.Constants.minus
anchors.verticalCenter: parent.verticalCenter
enabled: statesEditorModel.activeStateGroupIndex !== 0
+ tooltip: qsTr("Remove State Group")
onClicked: statesEditorModel.removeStateGroup()
}
- StudioControls.AbstractButton {
+ HelperWidgets.AbstractButton {
id: editButton
buttonIcon: StudioTheme.Constants.edit
anchors.verticalCenter: parent.verticalCenter
enabled: statesEditorModel.activeStateGroupIndex !== 0
checked: editDialog.visible
+ tooltip: qsTr("Rename State Group")
onClicked: {
if (editDialog.opened)
editDialog.close()
@@ -439,20 +460,22 @@ Rectangle {
spacing: StudioTheme.Values.toolbarSpacing
rightPadding: root.padding
- StudioControls.AbstractButton {
+ HelperWidgets.AbstractButton {
buttonIcon: StudioTheme.Constants.gridView
anchors.verticalCenter: parent.verticalCenter
enabled: !root.tinyMode
+ tooltip: qsTr("Show thumbnails")
onClicked: {
for (var i = 0; i < statesRepeater.count; ++i)
statesRepeater.itemAt(i).setPropertyChangesVisible(false)
}
}
- StudioControls.AbstractButton {
+ HelperWidgets.AbstractButton {
buttonIcon: StudioTheme.Constants.textFullJustification
anchors.verticalCenter: parent.verticalCenter
enabled: !root.tinyMode
+ tooltip: qsTr("Show property changes")
onClicked: {
for (var i = 0; i < statesRepeater.count; ++i)
statesRepeater.itemAt(i).setPropertyChangesVisible(true)
@@ -503,6 +526,7 @@ Rectangle {
anchors.leftMargin: root.leftMargin
ScrollBar.horizontal: StateScrollBar {
+ id: horizontalBar
parent: scrollView
x: scrollView.leftPadding
y: scrollView.height - height
@@ -511,6 +535,7 @@ Rectangle {
}
ScrollBar.vertical: StateScrollBar {
+ id: verticalBar
parent: scrollView
x: scrollView.mirrored ? 0 : scrollView.width - width
y: scrollView.topPadding
@@ -568,6 +593,7 @@ Rectangle {
NumberAnimation {
properties: "x,y"
easing.type: Easing.OutQuad
+ duration: 100
}
}
@@ -576,11 +602,6 @@ Rectangle {
property int grabIndex: -1
- function executeDrop(from, to) {
- statesEditorModel.drop(from, to)
- statesRepeater.grabIndex = -1
- }
-
model: statesEditorModel
onItemAdded: root.responsiveResize(root.width, root.height)
@@ -623,24 +644,27 @@ Rectangle {
return
}
- statesEditorModel.move(
- (drag.source as StateThumbnail).visualIndex,
- stateThumbnail.visualIndex)
+ statesEditorModel.move(dragSource.visualIndex,
+ stateThumbnail.visualIndex)
}
onDropped: function (drop) {
- let dragSource = (drop.source as StateThumbnail)
+ let dropSource = (drop.source as StateThumbnail)
- if (dragSource === undefined)
+ if (dropSource === undefined)
return
- if (dragSource.extendString !== stateThumbnail.extendString
+ if (dropSource.extendString !== stateThumbnail.extendString
|| stateThumbnail.extendedState) {
return
}
- statesRepeater.executeDrop(statesRepeater.grabIndex,
- stateThumbnail.visualIndex)
+ if (statesRepeater.grabIndex === dropSource.visualIndex)
+ return
+
+ statesEditorModel.drop(statesRepeater.grabIndex,
+ dropSource.visualIndex)
+ statesRepeater.grabIndex = -1
}
// Extend Groups Visualization
@@ -742,6 +766,10 @@ Rectangle {
hasWhenCondition: delegateRoot.hasWhenCondition
+ scrollViewActive: horizontalBar.active || verticalBar.active
+
+ dragParent: scrollView
+
// Fix ScrollView taking over the dragging event
onGrabbing: {
frame.interactive = false
@@ -749,14 +777,6 @@ Rectangle {
}
onLetGo: frame.interactive = true
- // Fix for ScrollView clipping while dragging of StateThumbnail
- onDragActiveChanged: {
- if (stateThumbnail.dragActive)
- parent = scrollViewWrapper
- else
- parent = delegateRoot
- }
-
stateName: delegateRoot.stateName
thumbnailImageSource: delegateRoot.stateImageSource
whenCondition: delegateRoot.whenConditionString
@@ -771,15 +791,16 @@ Rectangle {
onClone: root.cloneState(delegateRoot.internalNodeId)
onExtend: root.extendState(delegateRoot.internalNodeId)
- onRemove: root.deleteState(delegateRoot.internalNodeId)
+ onRemove: {
+ if (delegateRoot.isDefault)
+ statesEditorModel.resetDefaultState()
+
+ root.deleteState(delegateRoot.internalNodeId)
+ }
onStateNameFinished: statesEditorModel.renameState(
delegateRoot.internalNodeId,
stateThumbnail.stateName)
-
- onWhenConditionFinished: statesEditorModel.setWhenCondition(
- delegateRoot.internalNodeId,
- stateThumbnail.whenCondition)
}
}
}
diff --git a/share/qtcreator/qmldesigner/newstateseditor/StateScrollBar.qml b/share/qtcreator/qmldesigner/newstateseditor/StateScrollBar.qml
index a284131bad..1591d3ecb7 100644
--- a/share/qtcreator/qmldesigner/newstateseditor/StateScrollBar.qml
+++ b/share/qtcreator/qmldesigner/newstateseditor/StateScrollBar.qml
@@ -36,19 +36,19 @@ T.ScrollBar {
implicitContentHeight + topPadding + bottomPadding)
contentItem: Rectangle {
- implicitWidth: scrollBar.interactive ? 6 : 2
- implicitHeight: scrollBar.interactive ? 6 : 2
+ implicitWidth: scrollBar.interactive ? 14 : 8
+ implicitHeight: scrollBar.interactive ? 14 : 8
radius: width / 2
opacity: 0.0
- color: scrollBar.pressed ? StudioTheme.Values.themeSliderActiveTrackHover
- : StudioTheme.Values.themeSliderHandle
+ color: scrollBar.pressed ? StudioTheme.Values.themeScrollBarHandle //"#4C4C4C"//DARK
+ : StudioTheme.Values.themeScrollBarTrack //"#3E3E3E"//DARK
states: State {
name: "active"
when: scrollBar.active && scrollBar.size < 1.0
PropertyChanges {
target: scrollBar.contentItem
- opacity: 0.75
+ opacity: 0.9
}
}
diff --git a/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml b/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml
index 642ebd972d..ce95aa2198 100644
--- a/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml
+++ b/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml
@@ -25,9 +25,9 @@
import QtQuick
import QtQuick.Controls
-import StudioTheme 1.0 as StudioTheme
+import HelperWidgets 2.0 as HelperWidgets
import StudioControls 1.0 as StudioControls
-import QtQuick.Layouts 6.0
+import StudioTheme 1.0 as StudioTheme
Item {
id: root
@@ -55,6 +55,10 @@ Item {
property bool hasWhenCondition: false
+ property bool scrollViewActive: false
+
+ property Item dragParent
+
property int visualIndex: 0
property int internalNodeId
@@ -65,7 +69,6 @@ Item {
signal extend
signal remove
signal stateNameFinished
- signal whenConditionFinished
signal grabbing
signal letGo
@@ -88,7 +91,7 @@ Item {
DragHandler {
id: dragHandler
- enabled: !root.baseState && !root.extendedState
+ enabled: !root.baseState && !root.extendedState && !root.scrollViewActive
onGrabChanged: function (transition, point) {
if (transition === PointerDevice.GrabPassive
|| transition === PointerDevice.GrabExclusive)
@@ -148,13 +151,14 @@ Item {
rows: 1
spacing: stateBackground.thumbSpacing
- StudioControls.AbstractButton {
+ HelperWidgets.AbstractButton {
id: defaultButton
width: 50
height: stateBackground.controlHeight
checkedInverted: true
buttonIcon: qsTr("Default")
iconFont: StudioTheme.Constants.font
+ tooltip: qsTr("Set State as default")
onClicked: {
root.defaultClicked()
root.focusSignal()
@@ -607,8 +611,16 @@ Item {
running: false
interval: 50
repeat: false
- onTriggered: statesEditorModel.setWhenCondition(root.internalNodeId,
- bindingEditor.newWhenCondition)
+ onTriggered: {
+ if (whenCondition.previousCondition === bindingEditor.newWhenCondition)
+ return
+
+ if ( bindingEditor.newWhenCondition !== "")
+ statesEditorModel.setWhenCondition(root.internalNodeId,
+ bindingEditor.newWhenCondition)
+ else
+ statesEditorModel.resetWhenCondition(root.internalNodeId)
+ }
}
stateModelNodeProperty: statesEditorModel.stateModelNode(root.internalNodeId)
@@ -634,6 +646,8 @@ Item {
indicatorVisible: true
indicator.icon.text: StudioTheme.Constants.edit
indicator.onClicked: {
+ whenCondition.previousCondition = whenCondition.text
+
bindingEditor.showWidget()
bindingEditor.text = whenCondition.text
bindingEditor.prepareBindings()
@@ -650,13 +664,18 @@ Item {
}
onEditingFinished: {
- if (whenCondition.previousCondition === whenCondition.text)
+ // The check for contenxtMenuAboutToShow is necessary in order to make a the
+ // popup stay open if the when condition was changed. Otherwise editingFinished
+ // will be called and the model will be reset. The popup will trigger a focus
+ // change and editingFinished is triggered.
+ if (whenCondition.previousCondition === whenCondition.text
+ || whenCondition.contextMenuAboutToShow)
return
whenCondition.previousCondition = whenCondition.text
if (whenCondition.text !== "")
- root.whenConditionFinished()
+ statesEditorModel.setWhenCondition(root.internalNodeId, root.whenCondition)
else
statesEditorModel.resetWhenCondition(root.internalNodeId)
@@ -750,6 +769,11 @@ Item {
name: "drag"
when: dragHandler.active
+ ParentChange {
+ target: root
+ parent: root.dragParent
+ }
+
AnchorChanges {
target: root
anchors.horizontalCenter: undefined
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQml/TimerSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQml/TimerSpecifics.qml
new file mode 100644
index 0000000000..9ff90a2b9f
--- /dev/null
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQml/TimerSpecifics.qml
@@ -0,0 +1,109 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+
+import QtQuick
+import QtQuick.Layouts
+import HelperWidgets 2.0
+import StudioControls 1.0 as StudioControls
+import StudioTheme 1.0 as StudioTheme
+
+Column {
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ Section {
+ caption: qsTr("Timer")
+
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ SectionLayout {
+ PropertyLabel {
+ text: qsTr("Interval")
+ tooltip: qsTr("Sets the interval between triggers, in milliseconds.")
+ }
+
+ SecondColumnLayout {
+ SpinBox {
+ implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ + StudioTheme.Values.actionIndicatorWidth
+ minimumValue: 0
+ maximumValue: 9999999
+ backendValue: backendValues.interval
+ }
+
+ ExpandingSpacer {}
+ }
+
+ PropertyLabel {
+ text: qsTr("Repeat")
+ tooltip: qsTr("Sets whether the timer is triggered repeatedly at the specified interval or just once.")
+ }
+
+ SecondColumnLayout {
+ CheckBox {
+ text: backendValues.repeat.valueToString
+ implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ + StudioTheme.Values.actionIndicatorWidth
+ backendValue: backendValues.repeat
+ }
+
+ ExpandingSpacer {}
+ }
+
+ PropertyLabel {
+ text: qsTr("Running")
+ tooltip: qsTr("Sets whether the timer is running or not.")
+ }
+
+ SecondColumnLayout {
+ CheckBox {
+ text: backendValues.running.valueToString
+ implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ + StudioTheme.Values.actionIndicatorWidth
+ backendValue: backendValues.running
+ }
+
+ ExpandingSpacer {}
+ }
+
+ PropertyLabel {
+ text: qsTr("Triggered on start")
+ tooltip: qsTr("Sets the timer to trigger when started.")
+ }
+
+ SecondColumnLayout {
+ CheckBox {
+ text: backendValues.triggeredOnStart.valueToString
+ implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ + StudioTheme.Values.actionIndicatorWidth
+ backendValue: backendValues.triggeredOnStart
+ }
+
+ ExpandingSpacer {}
+ }
+ }
+ }
+}
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml
index e5b0b8f928..e2ab61056b 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml
@@ -135,6 +135,7 @@ Section {
BoolButtonRowButton {
visible: section.showEasingCurve
buttonIcon: StudioTheme.Constants.curveDesigner
+ checkable: false
EasingCurveEditor {
id: easingCurveEditor
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml
index 6db3bb22f7..a8459c29ea 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml
@@ -266,15 +266,6 @@ SecondColumnLayout {
id: spacer
}
- StudioControls.Menu {
- id: contextMenu
-
- StudioControls.MenuItem {
- text: qsTr("Open Color Dialog")
- onTriggered: colorPalette.showColorDialog(colorEditor.color)
- }
- }
-
Component.onCompleted: popupLoader.determineActiveColorMode()
onBackendValueChanged: {
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml
index fca7cbef21..af47d06a66 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml
@@ -178,6 +178,15 @@ T.Popup {
}
}
+ StudioControls.Menu {
+ id: contextMenu
+
+ StudioControls.MenuItem {
+ text: qsTr("Open Color Dialog")
+ onTriggered: colorPalette.showColorDialog(colorEditor.color)
+ }
+ }
+
GradientModel {
id: gradientModel
anchorBackendProperty: anchorBackend
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/qmldir b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/qmldir
index 5a18d24846..f145b09877 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/qmldir
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/qmldir
@@ -61,7 +61,6 @@ RoundedPanel 2.0 RoundedPanel.qml
ScrollView 2.0 ScrollView.qml
SecondColumnLayout 2.0 SecondColumnLayout.qml
Section 2.0 Section.qml
-SearchBox 2.0 SearchBox.qml
SectionLayout 2.0 SectionLayout.qml
Spacer 2.0 Spacer.qml
SpinBox 2.0 SpinBox.qml
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SearchBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SearchBox.qml
index 65968b9bfe..158f49f6c3 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SearchBox.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SearchBox.qml
@@ -11,6 +11,8 @@ Item {
property alias text: searchFilterText.text
+ signal searchChanged(string searchText);
+
function clear()
{
searchFilterText.text = "";
@@ -58,7 +60,7 @@ Item {
selectByMouse: true
hoverEnabled: true
- onTextChanged: rootView.handleSearchfilterChanged(text)
+ onTextChanged: root.searchChanged(text)
Label {
text: StudioTheme.Constants.search
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml
index 2ac98abbfc..4911bf1180 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml
@@ -28,6 +28,8 @@ T.TextField {
property string preFocusText: ""
+ property bool contextMenuAboutToShow: false
+
horizontalAlignment: Qt.AlignLeft
verticalAlignment: Qt.AlignVCenter
@@ -40,7 +42,7 @@ T.TextField {
readOnly: false
selectByMouse: true
- persistentSelection: focus // QTBUG-73807
+ persistentSelection: contextMenu.visible || root.focus
clip: true
width: StudioTheme.Values.defaultControlWidth
@@ -56,28 +58,28 @@ T.TextField {
enabled: true
hoverEnabled: true
propagateComposedEvents: true
- acceptedButtons: Qt.LeftButton | Qt.RightButton
+ acceptedButtons: Qt.NoButton
cursorShape: Qt.PointingHandCursor
- onPressed: function(mouse) {
- if (mouse.button === Qt.RightButton)
- contextMenu.popup(root)
-
- mouse.accepted = false
- }
}
- onPersistentSelectionChanged: {
- if (!persistentSelection)
- root.deselect()
+ onPressed: function(event) {
+ if (event.button === Qt.RightButton)
+ contextMenu.popup(root)
}
ContextMenu {
id: contextMenu
myTextEdit: root
+
+ onClosed: root.forceActiveFocus()
+ onAboutToShow: root.contextMenuAboutToShow = true
+ onAboutToHide: root.contextMenuAboutToShow = false
}
onActiveFocusChanged: {
- if (root.activeFocus)
+ // OtherFocusReason in this case means, if the TextField gets focus after the context menu
+ // was closed due to an menu item click.
+ if (root.activeFocus && root.focusReason !== Qt.OtherFocusReason)
root.preFocusText = root.text
}
@@ -143,7 +145,7 @@ T.TextField {
states: [
State {
name: "default"
- when: root.enabled && !root.hover && !root.edit
+ when: root.enabled && !root.hover && !root.edit && !contextMenu.visible
PropertyChanges {
target: textFieldBackground
color: StudioTheme.Values.themeControlBackground
@@ -162,7 +164,7 @@ T.TextField {
State {
name: "globalHover"
when: (actionIndicator.hover || translationIndicator.hover || indicator.hover)
- && !root.edit && root.enabled
+ && !root.edit && root.enabled && !contextMenu.visible
PropertyChanges {
target: textFieldBackground
color: StudioTheme.Values.themeControlBackgroundGlobalHover
@@ -177,7 +179,7 @@ T.TextField {
State {
name: "hover"
when: mouseArea.containsMouse && !actionIndicator.hover && !translationIndicator.hover
- && !indicator.hover && !root.edit && root.enabled
+ && !indicator.hover && !root.edit && root.enabled && !contextMenu.visible
PropertyChanges {
target: textFieldBackground
color: StudioTheme.Values.themeControlBackgroundHover
@@ -191,7 +193,7 @@ T.TextField {
},
State {
name: "edit"
- when: root.edit
+ when: root.edit || contextMenu.visible
PropertyChanges {
target: textFieldBackground
color: StudioTheme.Values.themeControlBackgroundInteraction
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/qmldir b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/qmldir
index 878b2307c3..fea940d878 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/qmldir
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/qmldir
@@ -30,6 +30,7 @@ RealSpinBoxIndicator 1.0 RealSpinBoxIndicator.qml
RealSpinBoxInput 1.0 RealSpinBoxInput.qml
ScrollBar 1.0 ScrollBar.qml
ScrollView 1.0 ScrollView.qml
+SearchBox 1.0 SearchBox.qml
SecondColumnLayout 1.0 SecondColumnLayout.qml
Section 1.0 Section.qml
SectionLabel 1.0 SectionLabel.qml
diff --git a/share/qtcreator/themes/dark.creatortheme b/share/qtcreator/themes/dark.creatortheme
index bb1d7bfec8..b762ccdcc9 100644
--- a/share/qtcreator/themes/dark.creatortheme
+++ b/share/qtcreator/themes/dark.creatortheme
@@ -84,8 +84,8 @@ DSsliderHandleHover=ff606060
DSsliderHandleFocus=ff0492c9
DSsliderHandleInteraction=ff2aafd3
-DSscrollBarTrack=ff404040
-DSscrollBarHandle=ff505050
+DSscrollBarTrack=ff3E3E3E
+DSscrollBarHandle=ff4C4C4C
DSsectionHeadBackground=ff1f1f1f
diff --git a/share/qtcreator/themes/design.creatortheme b/share/qtcreator/themes/design.creatortheme
index d0a2c1b3d6..9335513217 100644
--- a/share/qtcreator/themes/design.creatortheme
+++ b/share/qtcreator/themes/design.creatortheme
@@ -86,8 +86,8 @@ DSsliderHandleHover=ff606060
DSsliderHandleFocus=ff0492c9
DSsliderHandleInteraction=ff2aafd3
-DSscrollBarTrack=ff404040
-DSscrollBarHandle=ff505050
+DSscrollBarTrack=ff3E3E3E
+DSscrollBarHandle=ff4C4C4C
DSsectionHeadBackground=ff1f1f1f
diff --git a/share/qtcreator/themes/flat-dark.creatortheme b/share/qtcreator/themes/flat-dark.creatortheme
index 203ab5e415..1e28230331 100644
--- a/share/qtcreator/themes/flat-dark.creatortheme
+++ b/share/qtcreator/themes/flat-dark.creatortheme
@@ -88,8 +88,8 @@ DSsliderHandleHover=ff606060
DSsliderHandleFocus=ff0492c9
DSsliderHandleInteraction=ff2aafd3
-DSscrollBarTrack=ff404040
-DSscrollBarHandle=ff505050
+DSscrollBarTrack=ff3E3E3E
+DSscrollBarHandle=ff4C4C4C
DSsectionHeadBackground=ff1f1f1f
diff --git a/share/qtcreator/themes/flat.creatortheme b/share/qtcreator/themes/flat.creatortheme
index 7d4c6d9608..45ffe8537d 100644
--- a/share/qtcreator/themes/flat.creatortheme
+++ b/share/qtcreator/themes/flat.creatortheme
@@ -82,8 +82,8 @@ DSsliderHandleHover=ff606060
DSsliderHandleFocus=ff0492c9
DSsliderHandleInteraction=ff2aafd3
-DSscrollBarTrack=ff404040
-DSscrollBarHandle=ff505050
+DSscrollBarTrack=ff3E3E3E
+DSscrollBarHandle=ff4C4C4C
DSsectionHeadBackground=ff1f1f1f
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp
index c1108ffc5e..4d5c0b2cd2 100644
--- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp
+++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp
@@ -166,7 +166,7 @@ QList<QToolButton *> AssetsLibraryWidget::createToolBarWidgets()
return {};
}
-void AssetsLibraryWidget::handleSearchfilterChanged(const QString &filterText)
+void AssetsLibraryWidget::handleSearchFilterChanged(const QString &filterText)
{
if (filterText == m_filterText || (m_assetsModel->isEmpty() && filterText.contains(m_filterText)))
return;
diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h
index f361c58e1a..d78345460f 100644
--- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h
+++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h
@@ -56,7 +56,7 @@ 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 handleSearchFilterChanged(const QString &filterText);
Q_INVOKABLE void handleExtFilesDrop(const QList<QUrl> &simpleFilePaths,
const QList<QUrl> &complexFilePaths,
const QString &targetDirPath = {});
diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp
index ba507e2458..1d09f30d18 100644
--- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp
+++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp
@@ -292,4 +292,68 @@ void ActionEditor::updateWindowName(const QString &targetName)
}
}
+void ActionEditor::invokeEditor(SignalHandlerProperty signalHandler,
+ std::function<void(SignalHandlerProperty)> onReject,
+ QObject * parent)
+{
+ if (!signalHandler.isValid())
+ return;
+
+ ModelNode connectionNode = signalHandler.parentModelNode();
+ if (!connectionNode.isValid())
+ return;
+
+ if (!connectionNode.bindingProperty("target").isValid())
+ return;
+
+ ModelNode targetNode = connectionNode.bindingProperty("target").resolveToModelNode();
+ if (!targetNode.isValid())
+ return;
+
+ const QString source = signalHandler.source();
+
+ QPointer<ActionEditor> editor = new ActionEditor(parent);
+
+ editor->showWidget();
+ editor->setModelNode(connectionNode);
+ editor->setConnectionValue(source);
+ editor->prepareConnections();
+ editor->updateWindowName(targetNode.validId() + "." + signalHandler.name());
+
+ QObject::connect(editor, &ActionEditor::accepted, [=]() {
+ if (!editor)
+ return;
+ if (editor->m_modelNode.isValid()) {
+ editor->m_modelNode.view()->executeInTransaction("ActionEditor::"
+ "invokeEditorAccepted",
+ [=]() {
+ editor->m_modelNode
+ .signalHandlerProperty(
+ signalHandler.name())
+ .setSource(
+ editor->connectionValue());
+ });
+ }
+
+ //closing editor widget somewhy triggers rejected() signal. Lets disconect before it affects us:
+ editor->disconnect();
+ editor->deleteLater();
+ });
+
+ QObject::connect(editor, &ActionEditor::rejected, [=]() {
+ if (!editor)
+ return;
+
+ if (onReject) {
+ editor->m_modelNode.view()->executeInTransaction("ActionEditor::"
+ "invokeEditorOnRejectFunc",
+ [=]() { onReject(signalHandler); });
+ }
+
+ //closing editor widget somewhy triggers rejected() signal 2nd time. Lets disconect before it affects us:
+ editor->disconnect();
+ editor->deleteLater();
+ });
+}
+
} // QmlDesigner namespace
diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h
index ec2f8fb9c1..3cab2cef63 100644
--- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h
+++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h
@@ -7,6 +7,7 @@
#include <bindingeditor/actioneditordialog.h>
#include <qmldesignercorelib_global.h>
#include <modelnode.h>
+#include <signalhandlerproperty.h>
#include <QtQml>
#include <QObject>
@@ -44,6 +45,10 @@ public:
Q_INVOKABLE void updateWindowName(const QString &targetName = {});
+ static void invokeEditor(SignalHandlerProperty signalHandler,
+ std::function<void(SignalHandlerProperty)> onReject = nullptr,
+ QObject *parent = nullptr);
+
signals:
void accepted();
void rejected();
diff --git a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h
index 1133af1065..c876ea170d 100644
--- a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h
+++ b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h
@@ -12,6 +12,7 @@ namespace ComponentCoreConstants {
const char rootCategory[] = "";
const char selectionCategory[] = "Selection";
+const char connectionsCategory[] = "Connections";
const char arrangeCategory[] = "Arrange";
const char qmlPreviewCategory[] = "QmlPreview";
const char editCategory[] = "Edit";
@@ -76,6 +77,7 @@ const char openSignalDialogCommandId[] = "OpenSignalDialog";
const char update3DAssetCommandId[] = "Update3DAsset";
const char selectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Selection");
+const char connectionsCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connections");
const char flowConnectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connect");
const char selectEffectDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Select Effect");
const char arrangeCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Arrange");
@@ -183,6 +185,7 @@ const char editListModelDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMen
const int priorityFirst = 280;
const int prioritySelectionCategory = 220;
+const int priorityConnectionsCategory = 210;
const int priorityQmlPreviewCategory = 200;
const int priorityStackCategory = 180;
const int priorityEditCategory = 160;
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
index 72b6f704c4..fb64084076 100644
--- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp
@@ -22,6 +22,7 @@
#include <documentmanager.h>
#include <qmldesignerplugin.h>
#include <viewmanager.h>
+#include <actioneditor.h>
#include <listmodeleditor/listmodeleditordialog.h>
#include <listmodeleditor/listmodeleditormodel.h>
@@ -433,6 +434,302 @@ public:
}
};
+QString prependSignal(QString signalHandlerName)
+{
+ if (signalHandlerName.isNull() || signalHandlerName.isEmpty())
+ return {};
+
+ QChar firstChar = signalHandlerName.at(0).toUpper();
+ signalHandlerName[0] = firstChar;
+ signalHandlerName.prepend(QLatin1String("on"));
+
+ return signalHandlerName;
+}
+
+QStringList getSignalsList(const ModelNode &node)
+{
+ if (!node.isValid())
+ return {};
+
+ if (!node.hasMetaInfo())
+ return {};
+
+ QStringList signalsList;
+ NodeMetaInfo nodeMetaInfo = node.metaInfo();
+
+ for (const auto &signalName : nodeMetaInfo.signalNames()) {
+ signalsList << QString::fromUtf8(signalName);
+ }
+
+ //on...Changed are the most regular signals, we assign them the lowest priority,
+ //we don't need them right now
+// QStringList signalsWithChanged = signalsList.filter("Changed");
+
+ //these are item specific, like MouseArea.clicked, they have higher priority
+ QStringList signalsWithoutChanged = signalsList;
+ signalsWithoutChanged.removeIf([](QString str) {
+ if (str.endsWith("Changed"))
+ return true;
+ return false;
+ });
+
+ QStringList finalResult;
+ finalResult.append(signalsWithoutChanged);
+
+
+ if (finalResult.isEmpty())
+ finalResult = signalsList;
+
+ finalResult.removeDuplicates();
+
+ return finalResult;
+}
+
+struct SlotEntry
+{
+ QString category;
+ QString name;
+ std::function<void(SignalHandlerProperty)> action;
+};
+
+QList<SlotEntry> getSlotsLists(const ModelNode &node)
+{
+ if (!node.isValid())
+ return {};
+
+ if (!node.view()->rootModelNode().isValid())
+ return {};
+
+ QList<SlotEntry> resultList;
+
+ ModelNode rootNode = node.view()->rootModelNode();
+ QmlObjectNode rootObjectNode(rootNode);
+
+ const QString stateCategory = "Change State";
+
+ //For now we are using category as part of the state name
+ //We should change it, once we extend number of categories
+ const SlotEntry defaultState = {stateCategory,
+ (stateCategory + " to " + "Default State"),
+ [rootNode](SignalHandlerProperty signalHandler) {
+ signalHandler.setSource(
+ QString("%1.state = \"\"").arg(rootNode.id()));
+ }};
+ resultList.push_back(defaultState);
+
+ for (const auto &stateName : rootObjectNode.states().names()) {
+ SlotEntry entry = {stateCategory,
+ (stateCategory + " to " + stateName),
+ [rootNode, stateName](SignalHandlerProperty signalHandler) {
+ signalHandler.setSource(
+ QString("%1.state = \"%2\"").arg(rootNode.id(), stateName));
+ }};
+
+ resultList.push_back(entry);
+ }
+
+ return resultList;
+}
+
+//creates connection without signalHandlerProperty
+ModelNode createNewConnection(ModelNode targetNode)
+{
+ NodeMetaInfo connectionsMetaInfo = targetNode.view()->model()->metaInfo("QtQuick.Connections");
+ ModelNode newConnectionNode = targetNode.view()
+ ->createModelNode("QtQuick.Connections",
+ connectionsMetaInfo.majorVersion(),
+ connectionsMetaInfo.minorVersion());
+ if (QmlItemNode::isValidQmlItemNode(targetNode))
+ targetNode.nodeAbstractProperty("data").reparentHere(newConnectionNode);
+
+ newConnectionNode.bindingProperty("target").setExpression(targetNode.id());
+
+ return newConnectionNode;
+}
+
+void removeSignal(SignalHandlerProperty signalHandler)
+{
+ auto connectionNode = signalHandler.parentModelNode();
+ auto connectionSignals = connectionNode.signalProperties();
+ if (connectionSignals.size() > 1) {
+ if (connectionSignals.contains(signalHandler))
+ connectionNode.removeProperty(signalHandler.name());
+ } else {
+ connectionNode.destroy();
+ }
+}
+
+class ConnectionsModelNodeActionGroup : public ActionGroup
+{
+public:
+ ConnectionsModelNodeActionGroup(const QString &displayName,
+ const QByteArray &menuId,
+ int priority)
+ : ActionGroup(displayName,
+ menuId,
+ priority,
+ &SelectionContextFunctors::always,
+ &SelectionContextFunctors::selectionEnabled)
+ {}
+
+ void updateContext() override
+ {
+ menu()->clear();
+
+ const auto selection = selectionContext();
+ if (!selection.isValid())
+ return;
+ if (!selection.singleNodeIsSelected())
+ return;
+ if (!action()->isEnabled())
+ return;
+
+ ModelNode currentNode = selection.currentSingleSelectedNode();
+ QmlObjectNode currentObjectNode(currentNode);
+
+ QStringList signalsList = getSignalsList(currentNode);
+ QList<SlotEntry> slotsList = getSlotsLists(currentNode);
+ currentNode.validId();
+
+ for (const ModelNode &connectionNode : currentObjectNode.getAllConnections()) {
+ for (const AbstractProperty &property : connectionNode.properties()) {
+ if (property.isSignalHandlerProperty() && property.name() != "target") {
+ const auto signalHandler = property.toSignalHandlerProperty();
+
+ const QString propertyName = QString::fromUtf8(signalHandler.name());
+
+ QMenu *activeSignalHandlerGroup = new QMenu(propertyName, menu());
+
+ QMenu *editSignalGroup = new QMenu("Change Signal", menu());
+
+ for (const auto &signalStr : signalsList) {
+ if (prependSignal(signalStr).toUtf8() == signalHandler.name())
+ continue;
+
+ ActionTemplate *newSignalAction = new ActionTemplate(
+ (signalStr + "Id").toLatin1(),
+ signalStr,
+ [signalStr, signalHandler](const SelectionContext &) {
+ signalHandler.parentModelNode().view()->executeInTransaction(
+ "ConnectionsModelNodeActionGroup::"
+ "changeSignal",
+ [signalStr, signalHandler]() {
+ auto connectionNode = signalHandler.parentModelNode();
+ auto newHandler = connectionNode.signalHandlerProperty(
+ prependSignal(signalStr).toLatin1());
+ newHandler.setSource(signalHandler.source());
+ connectionNode.removeProperty(signalHandler.name());
+ });
+ });
+ editSignalGroup->addAction(newSignalAction);
+ }
+
+ activeSignalHandlerGroup->addMenu(editSignalGroup);
+
+ if (!slotsList.isEmpty()) {
+ QMenu *editSlotGroup = new QMenu("Change Slot", menu());
+
+ for (const auto &slot : slotsList) {
+ ActionTemplate *newSlotAction = new ActionTemplate(
+ (slot.name + "Id").toLatin1(),
+ slot.name,
+ [slot, signalHandler](const SelectionContext &) {
+ signalHandler.parentModelNode()
+ .view()
+ ->executeInTransaction("ConnectionsModelNodeActionGroup::"
+ "changeSlot",
+ [slot, signalHandler]() {
+ slot.action(signalHandler);
+ });
+ });
+ editSlotGroup->addAction(newSlotAction);
+ }
+ activeSignalHandlerGroup->addMenu(editSlotGroup);
+ }
+
+ ActionTemplate *openEditorAction = new ActionTemplate(
+ (propertyName + "OpenEditorId").toLatin1(),
+ QString(
+ QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Open Connections Editor")),
+ [=](const SelectionContext &) {
+ signalHandler.parentModelNode().view()->executeInTransaction(
+ "ConnectionsModelNodeActionGroup::"
+ "openConnectionsEditor",
+ [signalHandler]() { ActionEditor::invokeEditor(signalHandler); });
+ });
+
+ activeSignalHandlerGroup->addAction(openEditorAction);
+
+ ActionTemplate *removeSignalHandlerAction = new ActionTemplate(
+ (propertyName + "RemoveSignalHandlerId").toLatin1(),
+ QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Remove this handler")),
+ [signalHandler](const SelectionContext &) {
+ signalHandler.parentModelNode().view()->executeInTransaction(
+ "ConnectionsModelNodeActionGroup::"
+ "removeSignalHandler",
+ [signalHandler]() {
+ removeSignal(signalHandler);
+ });
+ });
+
+ activeSignalHandlerGroup->addAction(removeSignalHandlerAction);
+
+ menu()->addMenu(activeSignalHandlerGroup);
+ }
+ }
+ }
+
+ //singular add connection:
+ QMenu *addConnection = new QMenu(QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
+ "Add signal handler")),
+ menu());
+
+ for (const auto &signalStr : signalsList) {
+ QMenu *newSignal = new QMenu(signalStr, addConnection);
+
+ for (const auto &slot : slotsList) {
+ ActionTemplate *newSlot = new ActionTemplate(
+ QString(signalStr + slot.name + "Id").toLatin1(),
+ slot.name,
+ [=](const SelectionContext &) {
+ currentNode.view()->executeInTransaction(
+ "ConnectionsModelNodeActionGroup::addConnection", [=]() {
+ ModelNode newConnectionNode = createNewConnection(currentNode);
+ slot.action(newConnectionNode.signalHandlerProperty(
+ prependSignal(signalStr).toLatin1()));
+ });
+ });
+ newSignal->addAction(newSlot);
+ }
+
+ ActionTemplate *openEditorAction = new ActionTemplate(
+ (signalStr + "OpenEditorId").toLatin1(),
+ QString(QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Open Connections Editor")),
+ [=](const SelectionContext &) {
+ currentNode.view()->executeInTransaction(
+ "ConnectionsModelNodeActionGroup::"
+ "openConnectionsEditor",
+ [=]() {
+ ModelNode newConnectionNode = createNewConnection(currentNode);
+
+ SignalHandlerProperty newHandler
+ = newConnectionNode.signalHandlerProperty(
+ prependSignal(signalStr).toLatin1());
+
+ newHandler.setSource(
+ QString("console.log(\"%1.%2\")").arg(currentNode.id(), signalStr));
+ ActionEditor::invokeEditor(newHandler, removeSignal);
+ });
+ });
+ newSignal->addAction(openEditorAction);
+
+ addConnection->addMenu(newSignal);
+ }
+
+ menu()->addMenu(addConnection);
+ }
+};
+
class DocumentError : public std::exception
{
public:
@@ -953,6 +1250,11 @@ void DesignerActionManager::createDefaultDesignerActions()
selectionCategory,
prioritySelectionCategory));
+ addDesignerAction(new ConnectionsModelNodeActionGroup(
+ connectionsCategoryDisplayName,
+ connectionsCategory,
+ priorityConnectionsCategory));
+
addDesignerAction(new ActionGroup(
arrangeCategoryDisplayName,
arrangeCategory,
diff --git a/src/plugins/qmldesigner/components/debugview/debugview.cpp b/src/plugins/qmldesigner/components/debugview/debugview.cpp
index 48ef33ca39..fd6ef9f435 100644
--- a/src/plugins/qmldesigner/components/debugview/debugview.cpp
+++ b/src/plugins/qmldesigner/components/debugview/debugview.cpp
@@ -527,9 +527,17 @@ void DebugView::instancesToken(const QString &/*tokenName*/, int /*tokenNumber*/
}
-void DebugView::currentStateChanged(const ModelNode &/*node*/)
+void DebugView::currentStateChanged(const ModelNode &node)
{
+ if (isDebugViewEnabled()) {
+ QTextStream message;
+ QString string;
+ message.setString(&string);
+ message << node;
+
+ log("::currentStateChanged:", string);
+ }
}
void DebugView::nodeOrderChanged([[maybe_unused]] const NodeListProperty &listProperty)
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp
index 5a359693f2..cb955174af 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp
@@ -205,7 +205,7 @@ QList<QToolButton *> ItemLibraryWidget::createToolBarWidgets()
}
-void ItemLibraryWidget::handleSearchfilterChanged(const QString &filterText)
+void ItemLibraryWidget::handleSearchFilterChanged(const QString &filterText)
{
if (filterText != m_filterText) {
m_filterText = filterText;
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h
index 696ce9f168..16673849be 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h
@@ -69,7 +69,7 @@ public:
Q_INVOKABLE void startDragAndDrop(const QVariant &itemLibEntry, const QPointF &mousePos);
Q_INVOKABLE void removeImport(const QString &importUrl);
Q_INVOKABLE void addImportForItem(const QString &importUrl);
- Q_INVOKABLE void handleSearchfilterChanged(const QString &filterText);
+ Q_INVOKABLE void handleSearchFilterChanged(const QString &filterText);
Q_INVOKABLE void handleAddImport(int index);
Q_INVOKABLE void goIntoComponent(const QString &source);
diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp b/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp
index 422288c8b2..7dae1e900f 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp
+++ b/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp
@@ -97,8 +97,9 @@ QString BundleImporter::importComponent(const QString &qmlFile,
FilePath qmlSourceFile = bundleImportPath.resolvePath(FilePath::fromString(qmlFile));
const bool qmlFileExists = qmlSourceFile.exists();
const QString qmlType = qmlSourceFile.baseName();
- m_pendingTypes.append(QStringLiteral("%1.%2")
- .arg(QLatin1String(Constants::COMPONENT_BUNDLES_FOLDER).mid(1), qmlType));
+ m_pendingTypes.append(QStringLiteral("%1.%2.%3")
+ .arg(QLatin1String(Constants::COMPONENT_BUNDLES_FOLDER).mid(1),
+ m_bundleId, qmlType));
if (!qmldirContent.contains(qmlFile)) {
qmldirContent.append(qmlType);
qmldirContent.append(" 1.0 ");
@@ -159,10 +160,6 @@ QString BundleImporter::importComponent(const QString &qmlFile,
// If import is not yet possible, import statement needs to be added asynchronously to
// avoid errors, as code model update takes a while.
m_importAddPending = true;
-
- // Full reset is not necessary if new import directory appearing will trigger scanning,
- // but if directory existed but was not valid possible import, we need to do a reset.
- m_fullReset = bundleImportPathExists;
}
}
m_importTimerCount = 0;
diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.cpp b/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.cpp
index 75549945f4..b5bc19e785 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.cpp
+++ b/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.cpp
@@ -30,9 +30,10 @@ namespace QmlDesigner {
BundleMaterial::BundleMaterial(QObject *parent,
const QString &name,
const QString &qml,
+ const TypeName &type,
const QUrl &icon,
const QStringList &files)
- : QObject(parent), m_name(name), m_qml(qml), m_icon(icon), m_files(files) {}
+ : QObject(parent), m_name(name), m_qml(qml), m_type(type), m_icon(icon), m_files(files) {}
bool BundleMaterial::filter(const QString &searchText)
{
@@ -54,6 +55,11 @@ QString BundleMaterial::qml() const
return m_qml;
}
+TypeName BundleMaterial::type() const
+{
+ return m_type;
+}
+
QStringList BundleMaterial::files() const
{
return m_files;
diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.h b/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.h
index 04f4ae2656..ae74a13d75 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.h
+++ b/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.h
@@ -25,6 +25,8 @@
#pragma once
+#include "qmldesignercorelib_global.h"
+
#include <QDataStream>
#include <QObject>
#include <QUrl>
@@ -43,6 +45,7 @@ public:
BundleMaterial(QObject *parent,
const QString &name,
const QString &qml,
+ const TypeName &type,
const QUrl &icon,
const QStringList &files);
@@ -50,6 +53,7 @@ public:
QUrl icon() const;
QString qml() const;
+ TypeName type() const;
QStringList files() const;
bool visible() const;
@@ -59,6 +63,7 @@ signals:
private:
QString m_name;
QString m_qml;
+ TypeName m_type;
QUrl m_icon;
QStringList m_files;
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp
index 452093aba0..4e70008f1a 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp
@@ -28,6 +28,7 @@
#include "bundleimporter.h"
#include "bundlematerial.h"
#include "bundlematerialcategory.h"
+#include "qmldesignerconstants.h"
#include "utils/qtcassert.h"
#include <QCoreApplication>
@@ -121,6 +122,8 @@ void MaterialBrowserBundleModel::loadMaterialBundle()
m_matBundleExists = true;
+ const QString bundleId = m_matBundleObj.value("id").toString();
+
const QJsonObject catsObj = m_matBundleObj.value("categories").toObject();
const QStringList categories = catsObj.keys();
for (const QString &cat : categories) {
@@ -136,8 +139,14 @@ void MaterialBrowserBundleModel::loadMaterialBundle()
for (const auto /*QJson{Const,}ValueRef*/ &asset : assetsArr)
files.append(asset.toString());
- auto bundleMat = new BundleMaterial(category, mat, matObj.value("qml").toString(),
- QUrl::fromLocalFile(matBundleDir.filePath(matObj.value("icon").toString())), files);
+ QUrl icon = QUrl::fromLocalFile(matBundleDir.filePath(matObj.value("icon").toString()));
+ QString qml = matObj.value("qml").toString();
+ TypeName type = QLatin1String("%1.%2.%3").arg(
+ QLatin1String(Constants::COMPONENT_BUNDLES_FOLDER).mid(1),
+ bundleId,
+ qml.chopped(4)).toLatin1(); // chopped(4): remove .qml
+
+ auto bundleMat = new BundleMaterial(category, mat, qml, type, icon, files);
category->addBundleMaterial(bundleMat);
}
@@ -149,7 +158,7 @@ void MaterialBrowserBundleModel::loadMaterialBundle()
for (const auto /*QJson{Const,}ValueRef*/ &file : sharedFilesArr)
sharedFiles.append(file.toString());
- m_importer = new Internal::BundleImporter(matBundleDir.path(), "MaterialBundle", sharedFiles);
+ m_importer = new Internal::BundleImporter(matBundleDir.path(), bundleId, sharedFiles);
connect(m_importer, &Internal::BundleImporter::importFinished, this, [&](const QmlDesigner::NodeMetaInfo &metaInfo) {
if (metaInfo.isValid())
emit addBundleMaterialToProjectRequested(metaInfo);
@@ -223,7 +232,10 @@ void MaterialBrowserBundleModel::applyToSelected(BundleMaterial *mat, bool add)
void MaterialBrowserBundleModel::addMaterial(BundleMaterial *mat)
{
- m_importer->importComponent(mat->qml(), mat->files());
+ QString err = m_importer->importComponent(mat->qml(), mat->files());
+
+ if (!err.isEmpty())
+ qWarning() << __FUNCTION__ << err;
}
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp
index bbe47ec94c..1f1dff4eef 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp
@@ -266,8 +266,7 @@ void MaterialBrowserModel::removeMaterial(const ModelNode &material)
void MaterialBrowserModel::deleteSelectedMaterial()
{
- if (isValidIndex(m_selectedIndex))
- m_materialList[m_selectedIndex].destroy();
+ deleteMaterial(m_selectedIndex);
}
void MaterialBrowserModel::updateSelectedMaterial()
@@ -365,7 +364,11 @@ void MaterialBrowserModel::pasteMaterialProperties(int idx)
void MaterialBrowserModel::deleteMaterial(int idx)
{
- m_materialList[idx].destroy();
+ if (isValidIndex(idx)) {
+ ModelNode node = m_materialList[idx];
+ if (node.isValid())
+ QmlObjectNode(node).destroy();
+ }
}
void MaterialBrowserModel::renameMaterial(int idx, const QString &newName)
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
index f0bdf4d906..791b42a059 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp
@@ -93,6 +93,8 @@ WidgetInfo MaterialBrowserView::widgetInfo()
mat.setVariantProperty(prop.name(), prop.toVariantProperty().value());
else if (prop.isBindingProperty())
mat.setBindingProperty(prop.name(), prop.toBindingProperty().expression());
+ else if (!all)
+ mat.removeProperty(prop.name());
}
});
});
@@ -105,70 +107,23 @@ WidgetInfo MaterialBrowserView::widgetInfo()
MaterialBrowserBundleModel *matBrowserBundleModel = m_widget->materialBrowserBundleModel().data();
connect(matBrowserBundleModel, &MaterialBrowserBundleModel::applyToSelectedTriggered, this,
- [&] (BundleMaterial *material, bool add) {
+ [&] (BundleMaterial *bundleMat, bool add) {
if (!m_selectedModel.isValid())
return;
m_bundleMaterialDropTarget = m_selectedModel;
m_bundleMaterialAddToSelected = add;
- m_widget->materialBrowserBundleModel()->addMaterial(material);
+
+ ModelNode defaultMat = getBundleMaterialDefaultInstance(bundleMat->type());
+ if (defaultMat.isValid())
+ applyBundleMaterialToDropTarget(defaultMat);
+ else
+ m_widget->materialBrowserBundleModel()->addMaterial(bundleMat);
});
connect(matBrowserBundleModel, &MaterialBrowserBundleModel::addBundleMaterialToProjectRequested, this,
[&] (const QmlDesigner::NodeMetaInfo &metaInfo) {
- ModelNode matLib = materialLibraryNode();
- if (!matLib.isValid())
- return;
-
- executeInTransaction("MaterialBrowserView::widgetInfo", [&] {
- 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();
- QString newId = model()->generateIdFromName(newName, "material");
- newMatNode.setIdWithRefactoring(newId);
-
- VariantProperty objNameProp = newMatNode.variantProperty("objectName");
- objNameProp.setValue(newName);
-
- if (m_bundleMaterialDropTarget.isValid()) {
- QmlObjectNode qmlObjNode(m_bundleMaterialDropTarget);
- if (m_bundleMaterialAddToSelected) {
- // TODO: unify this logic as it exist elsewhere also
- auto expToList = [](const QString &exp) {
- QString copy = exp;
- copy = copy.remove("[").remove("]");
-
- QStringList tmp = copy.split(',', Qt::SkipEmptyParts);
- for (QString &str : tmp)
- str = str.trimmed();
-
- return tmp;
- };
-
- auto listToExp = [](QStringList &stringList) {
- if (stringList.size() > 1)
- return QString("[" + stringList.join(",") + "]");
-
- if (stringList.size() == 1)
- return stringList.first();
-
- return QString();
- };
- QStringList matList = expToList(qmlObjNode.expression("materials"));
- matList.append(newMatNode.id());
- QString updatedExp = listToExp(matList);
- qmlObjNode.setBindingProperty("materials", updatedExp);
- } else {
- qmlObjNode.setBindingProperty("materials", newMatNode.id());
- }
- m_bundleMaterialDropTarget = {};
- }
-
- m_bundleMaterialAddToSelected = false;
- });
+ applyBundleMaterialToDropTarget({}, metaInfo);
});
}
@@ -179,6 +134,74 @@ WidgetInfo MaterialBrowserView::widgetInfo()
tr("Material Browser"));
}
+void MaterialBrowserView::applyBundleMaterialToDropTarget(const ModelNode &bundleMat,
+ const NodeMetaInfo &metaInfo)
+{
+ if (!bundleMat.isValid() && !metaInfo.isValid())
+ return;
+
+ ModelNode matLib = materialLibraryNode();
+ if (!matLib.isValid())
+ return;
+
+ executeInTransaction("MaterialBrowserView::applyBundleMaterialToDropTarget", [&] {
+ ModelNode newMatNode;
+ if (metaInfo.isValid()) {
+ 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()->generateIdFromName(newName, "material");
+ newMatNode.setIdWithRefactoring(newId);
+
+ VariantProperty objNameProp = newMatNode.variantProperty("objectName");
+ objNameProp.setValue(newName);
+ } else {
+ newMatNode = bundleMat;
+ }
+
+ if (m_bundleMaterialDropTarget.isValid()) {
+ QmlObjectNode qmlObjNode(m_bundleMaterialDropTarget);
+ if (m_bundleMaterialAddToSelected) {
+ // TODO: unify this logic as it exist elsewhere also
+ auto expToList = [](const QString &exp) {
+ QString copy = exp;
+ copy = copy.remove("[").remove("]");
+
+ QStringList tmp = copy.split(',', Qt::SkipEmptyParts);
+ for (QString &str : tmp)
+ str = str.trimmed();
+
+ return tmp;
+ };
+
+ auto listToExp = [](QStringList &stringList) {
+ if (stringList.size() > 1)
+ return QString("[" + stringList.join(",") + "]");
+
+ if (stringList.size() == 1)
+ return stringList.first();
+
+ return QString();
+ };
+ QStringList matList = expToList(qmlObjNode.expression("materials"));
+ matList.append(newMatNode.id());
+ QString updatedExp = listToExp(matList);
+ qmlObjNode.setBindingProperty("materials", updatedExp);
+ } else {
+ qmlObjNode.setBindingProperty("materials", newMatNode.id());
+ }
+
+ m_bundleMaterialDropTarget = {};
+ m_bundleMaterialAddToSelected = false;
+ }
+ });
+}
+
void MaterialBrowserView::modelAttached(Model *model)
{
AbstractView::modelAttached(model);
@@ -347,6 +370,28 @@ void QmlDesigner::MaterialBrowserView::loadPropertyGroups()
m_propertyGroupsLoaded = m_widget->materialBrowserModel()->loadPropertyGroups(matPropsPath);
}
+ModelNode MaterialBrowserView::getBundleMaterialDefaultInstance(const TypeName &type)
+{
+ const QList<ModelNode> materials = m_widget->materialBrowserModel()->materials();
+ for (const ModelNode &mat : materials) {
+ if (mat.type() == type) {
+ bool isDefault = true;
+ const QList<AbstractProperty> props = mat.properties();
+ for (const AbstractProperty &prop : props) {
+ if (prop.name() != "objectName") {
+ isDefault = false;
+ break;
+ }
+ }
+
+ if (isDefault)
+ return mat;
+ }
+ }
+
+ return {};
+}
+
void MaterialBrowserView::importsChanged([[maybe_unused]] const QList<Import> &addedImports,
[[maybe_unused]] const QList<Import> &removedImports)
{
@@ -383,7 +428,14 @@ void MaterialBrowserView::customNotification(const AbstractView *view,
m_widget->materialBrowserModel()->deleteSelectedMaterial();
} else if (identifier == "drop_bundle_material") {
m_bundleMaterialDropTarget = nodeList.first();
- m_widget->materialBrowserBundleModel()->addMaterial(m_draggedBundleMaterial);
+
+
+ ModelNode defaultMat = getBundleMaterialDefaultInstance(m_draggedBundleMaterial->type());
+ if (defaultMat.isValid())
+ applyBundleMaterialToDropTarget(defaultMat);
+ else
+ m_widget->materialBrowserBundleModel()->addMaterial(m_draggedBundleMaterial);
+
m_draggedBundleMaterial = nullptr;
}
}
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h
index d163b5fa3f..31b0310f4c 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h
@@ -3,7 +3,8 @@
#pragma once
-#include <abstractview.h>
+#include "abstractview.h"
+#include "nodemetainfo.h"
#include <QPointer>
@@ -45,6 +46,8 @@ private:
void refreshModel(bool updateImages);
bool isMaterial(const ModelNode &node) const;
void loadPropertyGroups();
+ void applyBundleMaterialToDropTarget(const ModelNode &bundleMat, const NodeMetaInfo &metaInfo = {});
+ ModelNode getBundleMaterialDefaultInstance(const TypeName &type);
QPointer<MaterialBrowserWidget> m_widget;
ModelNode m_bundleMaterialDropTarget;
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp
index c8473e5856..9df4a39b6e 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp
@@ -192,7 +192,7 @@ void MaterialBrowserWidget::contextHelp(const Core::IContext::HelpCallback &call
callback({});
}
-void MaterialBrowserWidget::handleSearchfilterChanged(const QString &filterText)
+void MaterialBrowserWidget::handleSearchFilterChanged(const QString &filterText)
{
if (filterText != m_filterText) {
m_filterText = filterText;
diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h
index 1767286b49..925e7bc260 100644
--- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h
+++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h
@@ -51,7 +51,7 @@ public:
QPointer<MaterialBrowserBundleModel> materialBrowserBundleModel() const;
void updateMaterialPreview(const ModelNode &node, const QPixmap &pixmap);
- Q_INVOKABLE void handleSearchfilterChanged(const QString &filterText);
+ Q_INVOKABLE void handleSearchFilterChanged(const QString &filterText);
Q_INVOKABLE void startDragMaterial(int index, const QPointF &mousePos);
Q_INVOKABLE void startDragBundleMaterial(QmlDesigner::BundleMaterial *bundleMat, const QPointF &mousePos);
diff --git a/src/plugins/qmldesigner/components/stateseditornew/stateseditorview.cpp b/src/plugins/qmldesigner/components/stateseditornew/stateseditorview.cpp
index 65d021eb05..a8e28f62e0 100644
--- a/src/plugins/qmldesigner/components/stateseditornew/stateseditorview.cpp
+++ b/src/plugins/qmldesigner/components/stateseditornew/stateseditorview.cpp
@@ -720,7 +720,7 @@ void StatesEditorView::propertiesRemoved(const QList<AbstractProperty>& property
for (const AbstractProperty &property : propertyList) {
if (property.name() == "states" && property.parentModelNode() == activeStateGroup().modelNode())
resetModel();
- if (property.name() == "when"
+ if ((property.name() == "when" || property.name() == "name")
&& QmlModelState::isValidQmlModelState(property.parentModelNode()))
resetModel();
if (property.name() == "extend")
@@ -848,7 +848,8 @@ void StatesEditorView::variantPropertiesChanged(const QList<VariantProperty> &pr
auto guard = qScopeGuard([&]() { m_block = false; });
for (const VariantProperty &property : propertyList) {
- if (property.name() == "name" && QmlModelState::isValidQmlModelState(property.parentModelNode()))
+ if (property.name() == "name"
+ && QmlModelState::isValidQmlModelState(property.parentModelNode()))
resetModel();
else if (property.name() == "state"
&& property.parentModelNode() == activeStateGroup().modelNode())
diff --git a/src/plugins/qmldesigner/designercore/imagecache/meshimagecachecollector.cpp b/src/plugins/qmldesigner/designercore/imagecache/meshimagecachecollector.cpp
index 88aa4efd40..0a9cd7d6d3 100644
--- a/src/plugins/qmldesigner/designercore/imagecache/meshimagecachecollector.cpp
+++ b/src/plugins/qmldesigner/designercore/imagecache/meshimagecachecollector.cpp
@@ -35,10 +35,12 @@ void MeshImageCacheCollector::start(Utils::SmallStringView name,
if (file.open()) {
QString qtQuickVersion;
QString qtQuick3DVersion;
- QtSupport::QtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(target()->kit());
- if (qtVersion && qtVersion->qtVersion() < QVersionNumber(6, 0, 0)) {
- qtQuickVersion = "2.15";
- qtQuick3DVersion = "1.15";
+ if (target()) {
+ QtSupport::QtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(target()->kit());
+ if (qtVersion && qtVersion->qtVersion() < QVersionNumber(6, 0, 0)) {
+ qtQuickVersion = "2.15";
+ qtQuick3DVersion = "1.15";
+ }
}
QString content{
diff --git a/src/plugins/qmldesigner/designercore/include/stylesheetmerger.h b/src/plugins/qmldesigner/designercore/include/stylesheetmerger.h
index 547a660361..e4dc67cd5d 100644
--- a/src/plugins/qmldesigner/designercore/include/stylesheetmerger.h
+++ b/src/plugins/qmldesigner/designercore/include/stylesheetmerger.h
@@ -3,6 +3,8 @@
#ifndef STYLESHEETMERGER_H
#define STYLESHEETMERGER_H
+#include "qmldesignercorelib_global.h"
+
#include <QString>
#include <QHash>
#include <modelnode.h>
@@ -19,8 +21,8 @@ struct ReparentInfo {
bool alreadyReparented;
};
-
-class StylesheetMerger {
+class QMLDESIGNERCORE_EXPORT StylesheetMerger
+{
public:
StylesheetMerger(AbstractView*, AbstractView*);
void merge();
diff --git a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp
index aac2e6fd11..f3790dad83 100644
--- a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp
+++ b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp
@@ -5,13 +5,13 @@
#include "texttomodelmerger.h"
#include "modeltotextmerger.h"
+#include "model_p.h"
#include <bindingproperty.h>
#include <customnotifications.h>
#include <filemanager/astobjecttextextractor.h>
#include <filemanager/firstdefinitionfinder.h>
#include <filemanager/objectlengthcalculator.h>
-#include <model_p.h>
#include <modelnode.h>
#include <modelnodepositionstorage.h>
#include <nodeproperty.h>
diff --git a/src/plugins/qmldesigner/qtquickplugin/images/timer-16px.png b/src/plugins/qmldesigner/qtquickplugin/images/timer-16px.png
new file mode 100644
index 0000000000..c675d5a707
--- /dev/null
+++ b/src/plugins/qmldesigner/qtquickplugin/images/timer-16px.png
Binary files differ
diff --git a/src/plugins/qmldesigner/qtquickplugin/images/timer-24px.png b/src/plugins/qmldesigner/qtquickplugin/images/timer-24px.png
new file mode 100644
index 0000000000..bd9419aaa0
--- /dev/null
+++ b/src/plugins/qmldesigner/qtquickplugin/images/timer-24px.png
Binary files differ
diff --git a/src/plugins/qmldesigner/qtquickplugin/images/timer-24px@2x.png b/src/plugins/qmldesigner/qtquickplugin/images/timer-24px@2x.png
new file mode 100644
index 0000000000..ff2d487cc9
--- /dev/null
+++ b/src/plugins/qmldesigner/qtquickplugin/images/timer-24px@2x.png
Binary files differ
diff --git a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc b/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc
index 7cdc3309cb..1e78c02b77 100644
--- a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc
+++ b/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc
@@ -98,5 +98,8 @@
<file>images/timeline-16px.png</file>
<file>images/keyframe-16px.png</file>
<file>images/timeline-animation-16px.png</file>
+ <file>images/timer-16px.png</file>
+ <file>images/timer-24px.png</file>
+ <file>images/timer-24px@2x.png</file>
</qresource>
</RCC>
diff --git a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo
index 4b766f715c..c45db41b8d 100644
--- a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo
+++ b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo
@@ -488,6 +488,25 @@ MetaInfo {
}
Type {
+ name: "QtQml.Timer"
+ icon: ":/qtquickplugin/images/timer-16px.png"
+
+ Hints {
+ visibleInNavigator: true
+ canBeDroppedInNavigator: true
+ canBeDroppedInFormEditor: false
+ canBeContainer: false
+ }
+
+ ItemLibraryEntry {
+ name: "Timer"
+ category: "d.Qt Quick - Animation"
+ libraryIcon: ":/qtquickplugin/images/timer-24px.png"
+ version: "2.0"
+ }
+ }
+
+ Type {
name: "QtQml.Component"
icon: ":/qtquickplugin/images/component-icon16.png"
diff --git a/src/plugins/studiowelcome/userpresets.cpp b/src/plugins/studiowelcome/userpresets.cpp
index a643df3fdd..86fdb2e557 100644
--- a/src/plugins/studiowelcome/userpresets.cpp
+++ b/src/plugins/studiowelcome/userpresets.cpp
@@ -21,7 +21,14 @@ FileStoreIo::FileStoreIo(const QString &fileName)
QByteArray FileStoreIo::read() const
{
- m_file->open(QFile::ReadOnly | QFile::Text);
+ if (!m_file->exists())
+ return {};
+
+ if (!m_file->open(QFile::ReadOnly | QFile::Text)) {
+ qWarning() << "Cannot load User Preset(s)";
+ return {};
+ }
+
QByteArray data = m_file->readAll();
m_file->close();
@@ -30,7 +37,11 @@ QByteArray FileStoreIo::read() const
void FileStoreIo::write(const QByteArray &data)
{
- m_file->open(QFile::WriteOnly | QFile::Text);
+ if (!m_file->open(QFile::WriteOnly | QFile::Text)) {
+ qWarning() << "Cannot save User Preset(s)";
+ return;
+ }
+
m_file->write(data);
m_file->close();
}