From 9ac27ad8aadbc96c8d2edcbbd168ba48e40403d1 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 21 Sep 2022 14:44:23 +0200 Subject: [PATCH 01/37] QmlDesigner: Compile fix after source-incompatible changes in Qt The use of 'auto' here is the simplest way out and should not be taked a precedence for other code. Change-Id: I4435e7211139bccfca4b10ed2407ba39afe0b400 Reviewed-by: Eike Ziller (cherry picked from commit b8528867639f00b3870a1b9b6fa8078c7fe407ac) Reviewed-by: hjk --- .../components/materialbrowser/materialbrowserbundlemodel.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp index 1632fc14fab..452093aba08 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp @@ -133,7 +133,7 @@ void MaterialBrowserBundleModel::loadMaterialBundle() QStringList files; const QJsonArray assetsArr = matObj.value("files").toArray(); - for (const QJsonValueRef &asset : assetsArr) + for (const auto /*QJson{Const,}ValueRef*/ &asset : assetsArr) files.append(asset.toString()); auto bundleMat = new BundleMaterial(category, mat, matObj.value("qml").toString(), @@ -146,7 +146,7 @@ void MaterialBrowserBundleModel::loadMaterialBundle() QStringList sharedFiles; const QJsonArray sharedFilesArr = m_matBundleObj.value("sharedFiles").toArray(); - for (const QJsonValueRef &file : sharedFilesArr) + for (const auto /*QJson{Const,}ValueRef*/ &file : sharedFilesArr) sharedFiles.append(file.toString()); m_importer = new Internal::BundleImporter(matBundleDir.path(), "MaterialBundle", sharedFiles); From 061ae8b02c0a07f37251ad35235ed4555ada7283 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 22 Sep 2022 11:53:11 +0300 Subject: [PATCH 02/37] QmlDesigner: Delete material properly via material browser Deleting is now made the same way as deleting a selected node, so dangling references to the deleted material are removed. Fixes: QDS-7716 Change-Id: I552c328eb928bfc20e3e33caa0e817f6d22162cc Reviewed-by: Mahmoud Badri Reviewed-by: Reviewed-by: Qt CI Bot --- .../components/materialbrowser/materialbrowsermodel.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp index fea4a430a61..b5d85a4cb8b 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp @@ -288,8 +288,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() @@ -387,7 +386,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) From 1f6061e88ab239426a6daed0d6f73059f05237ec Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 22 Sep 2022 12:51:19 +0300 Subject: [PATCH 03/37] QmlDesigner: Reset code model always when importing new bundle material Apparently we can't rely on code model picking up the import addition in all cases, so always do code model reset if a new material is imported from bundle. Fixes: QDS-7750 Change-Id: Idba05cd9ce0af4165cb933515ada8ed7bd3f64c9 Reviewed-by: Mahmoud Badri --- .../qmldesigner/components/materialbrowser/bundleimporter.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp b/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp index 046bd9f48ff..38aded76458 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp @@ -159,10 +159,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; From be3444924798602eedf6f4c22985fe01cb6cf1de Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Mon, 19 Sep 2022 10:32:36 +0300 Subject: [PATCH 04/37] Doc: Add info about 3D view context menu Task-number: QDS-7494 Change-Id: Ic6fce90317e2ff5736ba20996ba30b1f338c36ac Reviewed-by: Leena Miettinen --- .../images/3d-view-context-menu.png | Bin 0 -> 4571 bytes .../qtdesignstudio-3d-camera.qdoc | 16 ++++++++++++---- .../qtdesignstudio-3d-editor.qdoc | 10 ++++++++++ .../qtdesignstudio-3d-lights.qdoc | 11 ++++++++--- .../qtdesignstudio-3d-model.qdoc | 17 ++++++++++++----- 5 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 doc/qtdesignstudio/images/3d-view-context-menu.png 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 0000000000000000000000000000000000000000..c2e35e001987cbea031473cd2b7cd8abe9934b56 GIT binary patch literal 4571 zcmeAS@N?(olHy`uVBq!ia0y~yV6BcsIn+;_8&Oc1`U_|U*>g;0)@(i)WyT&thB z&KCF1l$s>e5hCK1^fXp=$*LgHr7nRYp-zGEOD0Nv4S8y}d$aZL`L=1t9$S|0xBuH( zc75~ds&e~(_SVOZH`+OQhzLDaRbW}&BJh39HzB7*0&9etLY+9mI1g$ms!R#1=1>d- zaaQfsk&3x;_5M+7M-P@Y=PXQ{%bNtaSO0GEdy|v%OZxJ6L8miITMn+`(QK|X=HOf( zs@bs7%VWx#AU0v4tkqH>xgXL5lG>iWd~m69NAOmy@cC*jBAye%ve~jiRtK@Me=^a# zex>JF(z9lMF3s%KO~R{NTn?<_3YCsfRVfK8=6b-ee^b&_m&31u8J8{y)oecgO~G{f z){7TEwmnWyI{qrSg=OvmyVjopTMffjuhL9U+UT_*%0#x^sw;A;yyZ5n@Qq#@UR5&o zggTvBV<+iSwC&oHn$)fTEx5(wf_zVgvim=~bf|S&*nAb07c8GOb=bi6iiAC8e{57a z%V+H-hA>XfqkCor^Y^cOS9yJO?FZVZ>uLa@JKwg=zn?|d zHcb%n-Lm%B31RJVxw|V8>yDmRPnbGEVJ+9u^ZzW~9{Be&cjg)Y z)F`!$5pQnzCx6!a>(I7<_m%2|SBti9FE1$gaARZgrMq*^vuIkcessZR(}5TENt5;O z>nGoS(N_M?SY2Ra($}BQ=kG6idaC;U-tre06zzmnmV|w;5DpaI+~puTe^+Sl>NCfx z|Mc$RO8UCE->&Na-|zhLc6-_<1gJd|46&a4>f`^b-TqfsnU%%gX$*Dxvtd{6=aAE$ zU(a0ioOPyVwO#j7EzS7VyB%`fb*;TsgSC{p_&W(~)50A_* z`S9Ri`n<|xqN_JO*?iuv`oRH4J98C=)pzrb3uPVMXsPAuz53RTue0AK*Q$MbEo)iy z-T<}6=M+Tvt8?Tqpz5C)t475gO|6px3^}SEB-r{y87zXtJA`Y1#WG5<*>%5 zx#`uJna1<$|Lx=qw+=I1@yq$7%USn!mm8~OS6EJd6|uH2G^cN4Q;hD~Ta^M%i&CyK zhNOqxeY$GuDRKQcoBDr$iqG4!hXg$elMUJbc%zlt#%cFbt{-}Qy#KUa+oe|143zn{`xe&E0QKmuPK|*-`ND z*4FIs^>I^;ejMo(zUB94Q-j(4Q%nx3OB1f1Te2!IU~6Wn)<;zd4e`~h!`GL^{Edp5 zYg{gO_;TY_jmX-Rnu+GOZ)&NoX*=>tSw%^5`qfpdRu%fKia4tE@$jo33zI}wA1Pj4 zrWRVfw0i%YyXKqL|GxT8cmEw7@h4hgf4A?d{rzpOb@{tnTeH8vyIaAr^{Q~6lJ$|i zZC>wZ);8Byt-K*&VLV~}!Fc)0;s;jQhoy$=-cZNJ@ES?6oE!fR)C-q#b+f9G92Agk`4_rmkbv;QSe zQeyPJsODvebM^n2U~_8cyg9e4&x`K3cyPjTNy#qp-+_zH$F43dE%o*Fjg5`Hy)E~$ zR-(|kBYPUM_IYIm5W%Xf9FlOBX8Zl7ggzUW+CQE<|W6qdDmQCn6lT)1%Y zV&>JVsil7=ukx8uw&q${{e$^eQ{Jw+dc@g_cTR|Uz-2?RrJ5DBubh{9EPtQ6VoUIr zAk)oaxsChIFfW%^{Mz8mnOiBlva98;A28=(nA9V} zY0eXN_F3pmmCZ%JggnpOtbY1GGvHZh>c%T;KhDuV@KYglZ(j7;l`92Tf2^o^eQoWn zW70zBZfyPa?)KDacR9aK+yBftOm?R8RI8h(OTCX(Zv8$dXja*iGpohIjJu!4nEG|T z+?~EwYw{Yq%TiiTbUdEwcbjcY7F|7U$$o$poX;+LaHh@*@xDaS)hZsVcSUr18m^h^bJbC`Cv=UF`Px-Us&*YmwZb|NzT$JQ zv=E)Fzp<>(=y;aI8oihu8}{wnw|8%BU*DwU$npsr)Xe5t&+guOQ=DmagzCKLuOT{N z8@*z-y_y)YCTXg~n!IvTy{@CH=7(Kh7rQ(2vYO?UG;7Z6q&S-uJ0l)uxq}qjY=6}S zQv4&ObWYO7uFyxTLyv>#qz${y9uEl#nX$es=xEYa`PJNFIuZM7Dx;%sAM2HVx?xAI z%9_rf|Kp>&j%tN@YOL|M!m zJ98sV-^X@^21SLHZj3hb6Wj7>{Sp7wV!72Dy_`}@vonl-T=M$5s{Ze^OH&KB+4z;m z2CjM4+Z4Q^`1b#_-D0!EuP)qTRsZi#>gj1~BR8iVZsRSAxDzIH?TFLwGk>nN zvQJ>ht;H|9HBW0VxtqDJKeXxUp|H!o%vYC83#_VN<+;<;YorCcWej%gj#VqP6_R4a@#3>2V8 zUOn5uw)$Vh+I8#JtzIp>`t`N7lMg>Ko4kPytY~9bXj3R#*y(exmTgG88-3qsk6du4 zexa+&inVrIvS&PexuD|X@(P%dk|1+8zB=;i7)ZOW&UJ>AZydL<57_Pf@F423sUT$vgRHGX^ukt4Lnupo%S>_;n zyko}Iq?o-MqgGUgN=E1&3ypiSYSk)L?`d1MY$+)z$;h4|v*gSgzIwx|zlZZC!T%G~HFPKb;?RUTuo8-59lmeOHi3`tJulJYO^a z7EU_5&M0@lz+|z9LrP*e$b7yY;-}?Tpis@?Bok>>{8RtBlo?ZGS zZI^`KE?GUZ%2$^+eNt|mwKIR?epbbezrJMJuZc1%yCU9^er4(G*q6N*i+{(yEPv^J zXUD|<4`#BRb3FGv;%i~t*yxL8u3pL7^XE_^rp%YjW#c@ry=B6=rXJ?F7hdDh8|S~E-j z_fNlW&h`)Nl*r`@@u6G3WqjIX{riLanJkyd`Js=a_9vxo@aI__p?WRs|JV2b+0KcA z*{b*Jet%Ec32OUH3q5%~{=ccix_c3!d~R3yoptZ6IJn6^nDYyJ+3_rP&ZN7OX06}% ztGhsVVX61du(@A?v~O+EobVb9p z^S;U)%{sCsD2sFJt{=%;OV+#! zc=~F}O8(kUC*QZOj^QZF`g(oU$8St?-KU<8TGOuS%h^@aHwcRBD-kw>rq&DtKJ1ceb?1h`NTdyVkj@0QaWO{uS9 z`z&8i`?O}+bdk@BZ+}@Yt5w|Kbtv=d+~AO@m+HLVMdYfd&Uvs#Yx#Cf{?$cU#V@BQ zEH|4TJAKaH$cUq>))&9*?GWD*p(>Nz7rI7hP14kasSoF0-MXZwIkbMwxw+Qio3+mV zO}Va`o-YPY*FtNIHh67_Dhs>qA<4daUu5itgo9n8+ELNbspyJ8MZKHG+I5PlGVlB2 zbxRCp5butPWh;aHl`j7_FRoa9>6oge z`gfI0e-j?Pl%D!-iC1^$9=}63v+iWSdS>gs(aR}6)Fkb8v3BdmOPj5idSvR%(w)8e z?1d?nrp1dFYG&?wy8WJr+TK0=XMg|Quxr+o!aecZr~KTsYLnr))x}+zCfirVPjL6P z^(gywRXu&J?+*Rgxo5H;+}xZV9v-eAz0JojS8sLGTyUuBKi^z|gdOdB^(QQ$Wv{DPw zTEqM__9y*UBR8johK63fdiCVXNvU5aZ8qm#9nmTr#u+9Vp&D^i z>!6nMl(1+|N%qzMBIa5ar=_Moy|mQ(>6hTMXV0Fyr?Y0-?$Afh8@!Iq7E69IS>-lE z>iJMhv#3+sW*%93;jE@?&Y<>++z$N$^mWza*N TYfl&$7#KWV{an^LB{Ts59~mxh literal 0 HcmV?d00001 diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-camera.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-camera.qdoc index a501eecfd08..2f6c05b24a8 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-camera.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-camera.qdoc @@ -40,10 +40,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 8f0628aef0d..5c2bf4f14bd 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc @@ -70,6 +70,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 + \list + + \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 deb6edbb640..d8fca3e3461 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc @@ -36,9 +36,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 e4253f0bb60..0893eadd975 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-model.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-model.qdoc @@ -37,14 +37,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}. From f50a6b04d80992db9990ac0ed258a8f63c2b1916 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 22 Sep 2022 13:14:31 +0200 Subject: [PATCH 05/37] QmlDesigner: Fix include Change-Id: I85ae8e863cb297396d05e9934b2208213d51f366 Reviewed-by: Christian Stenger --- src/plugins/qmldesigner/designercore/model/rewriterview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp index 66438fa6d54..4c27b645a67 100644 --- a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp +++ b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp @@ -27,13 +27,13 @@ #include "texttomodelmerger.h" #include "modeltotextmerger.h" +#include "model_p.h" #include #include #include #include #include -#include #include #include #include From 03714788363dd1594d367e73719fd28a65f81682 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 22 Sep 2022 15:13:32 +0300 Subject: [PATCH 06/37] QmlDesigner: Fix bundle imported material's metainfo type Fixes: QDS-7749 Change-Id: I50993304b3cae7452ff3fcb4d37af0f8663c0199 Reviewed-by: Mahmoud Badri --- .../components/materialbrowser/bundleimporter.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp b/src/plugins/qmldesigner/components/materialbrowser/bundleimporter.cpp index 38aded76458..67559e08299 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 "); From 70c4acae67c1f65a8e1ea2111cffd067991f1c03 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Thu, 22 Sep 2022 15:04:04 +0300 Subject: [PATCH 07/37] QmlDesigner: Avoid duplicate bundle material instance creation When apply a material from the material bundle directly to a model in the 3D scene, check frist if there is an existing material that has no properties set, if so apply it instead of creating a new instance. Also few tweaks. Change-Id: I4ddadfd84442164b671645af5e4f5d9e8dcb7cb0 Reviewed-by: Miikka Heikkinen --- .../materialbrowser/bundlematerial.cpp | 8 +- .../materialbrowser/bundlematerial.h | 5 + .../materialbrowserbundlemodel.cpp | 20 ++- .../materialbrowser/materialbrowserview.cpp | 160 ++++++++++++------ .../materialbrowser/materialbrowserview.h | 5 +- 5 files changed, 136 insertions(+), 62 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.cpp b/src/plugins/qmldesigner/components/materialbrowser/bundlematerial.cpp index 75549945f41..b5bc19e785c 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 04f4ae26568..ae74a13d75c 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 #include #include @@ -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 452093aba08..4e70008f1ab 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 @@ -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/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 7a4da256e53..db460eabbb4 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -129,70 +129,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); }); } @@ -203,6 +156,72 @@ 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(); + 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); @@ -382,6 +401,28 @@ void QmlDesigner::MaterialBrowserView::loadPropertyGroups() m_propertyGroupsLoaded = m_widget->materialBrowserModel()->loadPropertyGroups(matPropsPath); } +ModelNode MaterialBrowserView::getBundleMaterialDefaultInstance(const TypeName &type) +{ + const QList materials = m_widget->materialBrowserModel()->materials(); + for (const ModelNode &mat : materials) { + if (mat.type() == type) { + bool isDefault = true; + const QList props = mat.properties(); + for (const AbstractProperty &prop : props) { + if (prop.name() != "objectName") { + isDefault = false; + break; + } + } + + if (isDefault) + return mat; + } + } + + return {}; +} + void MaterialBrowserView::importsChanged(const QList &addedImports, const QList &removedImports) { Q_UNUSED(addedImports) @@ -420,7 +461,14 @@ void MaterialBrowserView::customNotification(const AbstractView *view, const QSt 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 09f2c99033c..d1a4c85db6d 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h @@ -25,7 +25,8 @@ #pragma once -#include +#include "abstractview.h" +#include "nodemetainfo.h" #include @@ -67,6 +68,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 m_widget; ModelNode m_bundleMaterialDropTarget; From 0ae9b14911060f2018049027edf547b3be833184 Mon Sep 17 00:00:00 2001 From: Vikas Pachdha Date: Wed, 21 Sep 2022 21:43:31 +0200 Subject: [PATCH 08/37] Export StyleSheetMerger class Used in assetImporter plugin Task-number: QDS-7652 Change-Id: I2caff28f6a9effbcb2312f120f2ccdc2d0a82a86 Reviewed-by: Thomas Hartmann --- .../qmldesigner/designercore/include/stylesheetmerger.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/include/stylesheetmerger.h b/src/plugins/qmldesigner/designercore/include/stylesheetmerger.h index 8a4b3bec30c..86f48f06776 100644 --- a/src/plugins/qmldesigner/designercore/include/stylesheetmerger.h +++ b/src/plugins/qmldesigner/designercore/include/stylesheetmerger.h @@ -25,6 +25,8 @@ #ifndef STYLESHEETMERGER_H #define STYLESHEETMERGER_H +#include "qmldesignercorelib_global.h" + #include #include #include @@ -41,8 +43,8 @@ struct ReparentInfo { bool alreadyReparented; }; - -class StylesheetMerger { +class QMLDESIGNERCORE_EXPORT StylesheetMerger +{ public: StylesheetMerger(AbstractView*, AbstractView*); void merge(); From 1664a5f4e245fcedc1f88eb7fe2d22241be9a308 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Thu, 22 Sep 2022 16:36:53 +0300 Subject: [PATCH 09/37] QmlDesigner: Remove "Material" word from the bundle material instances TO save space and make material names clearer. Change-Id: I1cea8787ca03a37adca6e4a0f352732d50bc1b40 Reviewed-by: Miikka Heikkinen --- .../components/materialbrowser/materialbrowserview.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index db460eabbb4..7dd0a913195 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -175,6 +175,8 @@ void MaterialBrowserView::applyBundleMaterialToDropTarget(const ModelNode &bundl 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); From e28810b50c196cf1fd4035685f882ff02a504b09 Mon Sep 17 00:00:00 2001 From: Brook Cronin Date: Thu, 22 Sep 2022 12:59:39 +0200 Subject: [PATCH 10/37] QmlDesigner: Fix Scrollbar size and colors Task-number: QDS-7741 Change-Id: I013fcfe1c80ef637388af190d27c4954be650d86 Reviewed-by: Thomas Hartmann --- .../qmldesigner/newstateseditor/StateScrollBar.qml | 10 +++++----- share/qtcreator/themes/dark.creatortheme | 4 ++-- share/qtcreator/themes/design.creatortheme | 4 ++-- share/qtcreator/themes/flat-dark.creatortheme | 4 ++-- share/qtcreator/themes/flat.creatortheme | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/share/qtcreator/qmldesigner/newstateseditor/StateScrollBar.qml b/share/qtcreator/qmldesigner/newstateseditor/StateScrollBar.qml index a284131bad7..1591d3ecb78 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/themes/dark.creatortheme b/share/qtcreator/themes/dark.creatortheme index 7b124ca0d67..f6ca9944f3a 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 52132b189df..cc2fd4431fb 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 e67e0e1b9f7..ad1ad7a9a15 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 e1006048791..8a16660243b 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 From 754be28e365e74d5462139eae418b0d7b7ed7af5 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Thu, 22 Sep 2022 17:43:15 +0200 Subject: [PATCH 11/37] QmlDesigner: Fix state shown after reordering Fix an issue which caused the wrong state to be shown in the form editor after reordering the states in the state editor. Task-number: QDS-7753 Change-Id: I220bb5b11beb4f9bfc6a85069a688c9ff2984d8f Reviewed-by: Thomas Hartmann Reviewed-by: Qt CI Bot Reviewed-by: --- .../instances/qmlstatenodeinstance.cpp | 16 ++++++++++++++++ .../qml2puppet/instances/qmlstatenodeinstance.h | 4 ++++ 2 files changed, 20 insertions(+) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp index 9b00f3c43ab..bc28b7076b3 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.cpp @@ -118,5 +118,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 9870223fa75..800acfcad37 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qmlstatenodeinstance.h @@ -49,6 +49,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); From 40b159a1eb1c67ba3a88e875e868936cc4e68e15 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Thu, 22 Sep 2022 17:40:43 +0200 Subject: [PATCH 12/37] QmlDesigner: Add output to DebugView currentStateChanged Change-Id: I6513a98665da1b85ba153edc0d0cfb6d01235406 Reviewed-by: Thomas Hartmann Reviewed-by: Qt CI Bot --- .../qmldesigner/components/debugview/debugview.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/debugview/debugview.cpp b/src/plugins/qmldesigner/components/debugview/debugview.cpp index 2d3b232e51c..7293081b0b7 100644 --- a/src/plugins/qmldesigner/components/debugview/debugview.cpp +++ b/src/plugins/qmldesigner/components/debugview/debugview.cpp @@ -517,9 +517,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(const NodeListProperty &listProperty) From c5020c91ce01fa587be1805245a50eabc2a64a6f Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Thu, 22 Sep 2022 11:17:02 +0200 Subject: [PATCH 13/37] QmlDesigner: Reset default state when removed Reset the default state to base state when a state is removed that is currently the default. Task-number: QDS-7743 Change-Id: Id60549ee0a61b2d3caf05ef2f00e25b74774e7d9 Reviewed-by: Reviewed-by: Thomas Hartmann --- share/qtcreator/qmldesigner/newstateseditor/Main.qml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/share/qtcreator/qmldesigner/newstateseditor/Main.qml b/share/qtcreator/qmldesigner/newstateseditor/Main.qml index 8f50d8f3362..b0e7fa03bc6 100644 --- a/share/qtcreator/qmldesigner/newstateseditor/Main.qml +++ b/share/qtcreator/qmldesigner/newstateseditor/Main.qml @@ -771,7 +771,12 @@ 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, From ff33f7b7cc030cb9dd9c20c49306c684bcf006a8 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Wed, 21 Sep 2022 18:07:23 +0200 Subject: [PATCH 14/37] QmlDesigner: Fix state drop in same position Avoid calling executeDrop() if the state is drop at the same index. Task-number: QDS-7731 Change-Id: I91a2be11ce4f1c34c55ecb6dcc0c75f07114703a Reviewed-by: Reviewed-by: Thomas Hartmann --- share/qtcreator/qmldesigner/newstateseditor/Main.qml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/share/qtcreator/qmldesigner/newstateseditor/Main.qml b/share/qtcreator/qmldesigner/newstateseditor/Main.qml index b0e7fa03bc6..c6069c8cac7 100644 --- a/share/qtcreator/qmldesigner/newstateseditor/Main.qml +++ b/share/qtcreator/qmldesigner/newstateseditor/Main.qml @@ -639,6 +639,9 @@ Rectangle { return } + if (statesRepeater.grabIndex === stateThumbnail.visualIndex) + return + statesRepeater.executeDrop(statesRepeater.grabIndex, stateThumbnail.visualIndex) } From 3d3290424a72c26546e3ccc0fa27d26fbd470e51 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Wed, 21 Sep 2022 16:45:13 +0200 Subject: [PATCH 15/37] QmlDesigner: Make easing curve button non checkable Change-Id: Ia25e710f6cc978645144beaf05a8f53fd0de989f Reviewed-by: Thomas Hartmann Reviewed-by: --- .../propertyEditorQmlSources/QtQuick/AnimationSection.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml index b4dfe0f7a5a..6a181598919 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AnimationSection.qml @@ -157,6 +157,7 @@ Section { BoolButtonRowButton { visible: section.showEasingCurve buttonIcon: StudioTheme.Constants.curveDesigner + checkable: false EasingCurveEditor { id: easingCurveEditor From c3f5a9bf0d78ac914fd07fa5257d3c48241ecc41 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 21 Sep 2022 13:50:14 +0200 Subject: [PATCH 16/37] QmlDesigner: Add timer to library MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QDS-7582 Change-Id: I048b08cae236bbce39d83c6881abad21592fcb8b Reviewed-by: Reviewed-by: Henning Gründl --- .../qtquickplugin/images/timer-16px.png | Bin 0 -> 339 bytes .../qtquickplugin/images/timer-24px.png | Bin 0 -> 712 bytes .../qtquickplugin/images/timer-24px@2x.png | Bin 0 -> 1305 bytes .../qtquickplugin/qtquickplugin.qrc | 3 +++ .../qmldesigner/qtquickplugin/quick.metainfo | 19 ++++++++++++++++++ 5 files changed, 22 insertions(+) create mode 100644 src/plugins/qmldesigner/qtquickplugin/images/timer-16px.png create mode 100644 src/plugins/qmldesigner/qtquickplugin/images/timer-24px.png create mode 100644 src/plugins/qmldesigner/qtquickplugin/images/timer-24px@2x.png 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 0000000000000000000000000000000000000000..c675d5a70721541633f825d38b0c44dbbfc19d59 GIT binary patch literal 339 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4i*LmhONKMUokK+N_o0ChG+z*Uf8egS}1Y+ z<9XiH9n7aS*(9I1%d#)s5qV?Dm5DxP-9OtV%?axAWfSqttNUVRSB8D@w2DNQ(f^l0jwIt~YQ={GJ4cgou=IUJ13ef}~Z*V!o3 z5XF_UWBscA8!MHC=UE;Xj(?Dzd`309 uVouN_8E-EJ&qee2*dz}vG(6K&$KaR!(LQ=k61_n=8KbLh*2~7a$?~Gpn literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..bd9419aaa0c481f9ed10931643f5684bec463f06 GIT binary patch literal 712 zcmeAS@N?(olHy`uVBq!ia0y~yV2}V|4mJh`h6m-gKNuL8`aNA7Lp(aSUiDrP8Y*-A z;A?L=wGVsw-DG}C-hkc}7_yvCQ7lkd+xZ%uG#j9n&-dp7$nAm?XJ|jRv zbZRPdbCcV*MIA;Hmgp!?io2D!;o8>X?|0Mh%Y11+99g|~Z{7W`|JU!W%f4X3E5XBd zYvN4tL~Xxy``1F zVYO1ybD#I-zQ)E1#>Y2uX%`qC+bF;LqnVLXon4kgT3;fw+<}@u4gIhGckXbwIlcKt zkFH?h3f>u}Nmq+MYRMg4zJrZhIY~3Guj8o&Z}NcOTVOyW5`R>5u zh|b#un(z8Ljz@9tV)cKdoLXP^{`7-7ox@T#;fc4kK2-EwsxQ z7As|?Z<_Pp`7UO7p4k3rufD{>;yXNZ%r_bsv;VlRm35qHD zPrhcz-M)Lz3-dEC8P}XW!>fGE?9u0keafm`9m~wb6aD!Y@b6<^e!a|?HQ=#!OyBp9 z-u(gLGRMwY{daKrbC>l--)hnIm9I1y^&bhWJ1#wWZtj80ryQ#U_%p9=R{y5O{zY%j zf*ahs_P*d;bF}n_%gL-o?th|VR;T>c+va}6%dPsN+R@kXhkkY)yqo;%SpD)FUs(JO zzTTRD_Jj9j2EoFBkMs3Ec0HOTDcD^grg!9~#o}p6n~Pfib)*VztdCg#{?N>J_bEla znqhwuMXfl!Mb=9_V7((JXwRGd=eqXim^)ohBYKiQith{f_WWnZk2TrvL=OBH{m-Cv X;kNHBohUU11_lOCS3j3^P6{Qv)d#V8mw zA+XwD#wG>^hSriGzhDLiMkZz!RyIy9ZhiqFQE>@LDQP)*1w|!g6;*W&9X)*mLnBi& zb4x30XID3O4=>-4h{&jz*tn#WwDgR;{KBHripqwjj?SLG36rMJm^pjif`yBgu3Ecp z!=`Q9ckJDF;NYRdM~n;L@5qQwKmQU#Yf zI9};`ld%8)c77ApSfQE^7XFszpDlNm`@QS2k?Zek`mKDahPwqHI6jH#z2wln)hTpNEriuu6yVrt3X&kqBubAG>Kz4xTSZ$Z4#yuWJl zE976CVOlC}koV%qX`jEF8w~lRmzEhY+5fr3(AxONKH&&k)9(vptgRzuirjS2eyDo6(r2`Eb(w39}N9F&!3|=oWLJL!>d0yCpGj*JGx49^C@l z928i?Q>@-=CcffY!Zh=KwNTrV4aywe&IXkw@`pAAt0mu3tiKg-ldq+}prL1nt8dDf`%Nw3%%NYEE9-3a>-WZ4?dRL<78bv211INx zku$c(O9DQrCwzADd%l}}O^eFn(xcP%UCQ!UDEc5S&bW?AMOt;{cDCt!4b4jrMlV}( zOy$E8hu!sD0^A;x{N{1bwbu0HI>IndOh)5u^nr5@Ti;#_;eW#reU?vo^{dMdd%Cv7 zXn&s?pWP|rx4}QO&-h%;58d@^?#s=}Oa2~mJSOZ{%<+}U?A5OBId+u?9E>FfcH9y85}Sb4q9e0P)GAEdT%j literal 0 HcmV?d00001 diff --git a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc b/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc index 7cdc3309cba..1e78c02b779 100644 --- a/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc +++ b/src/plugins/qmldesigner/qtquickplugin/qtquickplugin.qrc @@ -98,5 +98,8 @@ images/timeline-16px.png images/keyframe-16px.png images/timeline-animation-16px.png + images/timer-16px.png + images/timer-24px.png + images/timer-24px@2x.png diff --git a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo index 4b766f715c1..c45db41b8d2 100644 --- a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo +++ b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo @@ -487,6 +487,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" From a8f46ac852d70a6ddbf3a28fd240edda24e846f2 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Wed, 21 Sep 2022 16:26:39 +0200 Subject: [PATCH 17/37] QmlDesigner: Add Timer specifics Task-number: QDS-7582 Change-Id: I8254012970cd54e450853e026b421c73258c1346 Reviewed-by: Reviewed-by: Thomas Hartmann --- .../QtQml/TimerSpecifics.qml | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQml/TimerSpecifics.qml diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQml/TimerSpecifics.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQml/TimerSpecifics.qml new file mode 100644 index 00000000000..9ff90a2b9fa --- /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 {} + } + } + } +} From 66ec244cf9dacb3692c7c29d947afac777cdbf11 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Wed, 21 Sep 2022 17:45:59 +0200 Subject: [PATCH 18/37] QmlDesigner: Fix TextField context menu Fix TextField keeping its selection after context menu is opened. Due to this bug QTBUG-71723 being closed the behavior changed. Also the states when condition TextField needed to be context menu aware to not set a new expression when the context menu is opened, otherwise it will immediately reset the model and the context menu wont show up if the content was edited. Task-number: QDS-7730 Change-Id: Ic0e63cd3d244bd7f83bcb0edd3b31c0ca1f0a5df Reviewed-by: Thomas Hartmann --- .../newstateseditor/StateThumbnail.qml | 7 ++++- .../imports/StudioControls/TextField.qml | 30 +++++++++---------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml b/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml index 642ebd972d1..4b004708c2d 100644 --- a/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml +++ b/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml @@ -650,7 +650,12 @@ 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 diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml index 702d80ab8a1..531a5b0ff35 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml @@ -50,6 +50,8 @@ T.TextField { property string preFocusText: "" + property bool contextMenuAboutToShow: false + horizontalAlignment: Qt.AlignLeft verticalAlignment: Qt.AlignVCenter @@ -62,7 +64,7 @@ T.TextField { readOnly: false selectByMouse: true - persistentSelection: focus // QTBUG-73807 + persistentSelection: contextMenu.visible || root.focus clip: true width: StudioTheme.Values.defaultControlWidth @@ -78,24 +80,22 @@ 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: { @@ -165,7 +165,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 @@ -184,7 +184,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 @@ -199,7 +199,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 @@ -213,7 +213,7 @@ T.TextField { }, State { name: "edit" - when: root.edit + when: root.edit || contextMenu.visible PropertyChanges { target: textFieldBackground color: StudioTheme.Values.themeControlBackgroundInteraction From a7c15838e24514be4024ecc076978f91e1285559 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Thu, 22 Sep 2022 22:23:52 +0200 Subject: [PATCH 19/37] QmlDesigner: Add tooltips in StateEditor Task-number: QDS-7736 Change-Id: I6732043da895e04e6ed70f74d8342ba7ff7354fe Reviewed-by: Reviewed-by: Thomas Hartmann --- .../qmldesigner/newstateseditor/Main.qml | 33 ++++++++++++++++--- .../newstateseditor/StateThumbnail.qml | 7 ++-- 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/share/qtcreator/qmldesigner/newstateseditor/Main.qml b/share/qtcreator/qmldesigner/newstateseditor/Main.qml index c6069c8cac7..ca2cf9e1eb4 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) diff --git a/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml b/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml index 4b004708c2d..199ef9bd777 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 @@ -148,13 +148,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() From e46431f7dffa7599ff1b3ff2ca817400eaaf6670 Mon Sep 17 00:00:00 2001 From: Samuel Ghinet Date: Wed, 14 Sep 2022 15:14:17 +0300 Subject: [PATCH 20/37] QDS New Project Dialog: Remove Warning that UserPresets.json was not read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QDS-7679 Change-Id: I639a8323b3860f3dfb5f4287267a014aaa95dc63 Reviewed-by: Miikka Heikkinen Reviewed-by: Henning Gründl --- src/plugins/studiowelcome/userpresets.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/plugins/studiowelcome/userpresets.cpp b/src/plugins/studiowelcome/userpresets.cpp index e32c010bd63..1a3a7feb6b8 100644 --- a/src/plugins/studiowelcome/userpresets.cpp +++ b/src/plugins/studiowelcome/userpresets.cpp @@ -43,7 +43,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(); @@ -52,7 +59,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(); } From c909e791d656be5f777dd58d7cc97316b8b63051 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 23 Sep 2022 13:51:42 +0300 Subject: [PATCH 21/37] QmlDesigner: Remove unused variable Change-Id: Ifaddb79f01887d73cc2d715ba45f41f2dcd30a0a Reviewed-by: Mahmoud Badri --- .../qml2puppet/instances/qt5informationnodeinstanceserver.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 02d78866bb3..79ec06d9bfe 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -345,7 +345,6 @@ void Qt5InformationNodeInstanceServer::resolveImportSupport() void Qt5InformationNodeInstanceServer::updateMaterialPreviewData(const QVector &valueChanges) { - const PropertyName matPrevPrefix("matPrev"); for (const auto &container : valueChanges) { if (container.instanceId() == 0) { if (container.name() == "matPrevEnv") From 5b0bb021152f7e414d22d344b23bce07df29e859 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Fri, 23 Sep 2022 14:39:09 +0200 Subject: [PATCH 22/37] QmlDesigner: Fix ColorDialog popup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I7f8daa6e9b26ae8244de1f7ab7c7db1dfa9b7e52 Reviewed-by: Henning Gründl --- .../imports/HelperWidgets/ColorEditor.qml | 9 --------- .../imports/HelperWidgets/ColorEditorPopup.qml | 9 +++++++++ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml index 471d2a4e616..b77addd7da3 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditor.qml @@ -288,15 +288,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 34574ec7285..c7b260f1247 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorEditorPopup.qml @@ -200,6 +200,15 @@ T.Popup { } } + StudioControls.Menu { + id: contextMenu + + StudioControls.MenuItem { + text: qsTr("Open Color Dialog") + onTriggered: colorPalette.showColorDialog(colorEditor.color) + } + } + GradientModel { id: gradientModel anchorBackendProperty: anchorBackend From 3d672dbf16ec2ff5bbfe633ab077d5ee90a6e1df Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 23 Sep 2022 14:06:48 +0300 Subject: [PATCH 23/37] QmlDesigner: Fix material 2D view preview for material root components Change-Id: I7930e5087014b47ccc054109cbb607ef9c373515 Reviewed-by: Mahmoud Badri Reviewed-by: Qt CI Bot --- .../instances/quick3dmaterialnodeinstance.cpp | 11 ++++++----- .../instances/quick3dmaterialnodeinstance.h | 3 +-- .../qml2puppet/instances/quick3dnodeinstance.cpp | 8 ++++++-- .../qml2puppet/instances/quick3dnodeinstance.h | 1 + .../instances/quick3drenderablenodeinstance.cpp | 9 ++++++--- .../instances/quick3drenderablenodeinstance.h | 4 +--- 6 files changed, 21 insertions(+), 15 deletions(-) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.cpp index fbfe6c2a2e7..97b0c2bf87e 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.cpp @@ -37,12 +37,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 b55cbb3f309..d035761a8e9 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dmaterialnodeinstance.h @@ -41,11 +41,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 eec52e99927..5dde70d257e 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.cpp @@ -46,6 +46,12 @@ Quick3DNodeInstance::Quick3DNodeInstance(QObject *node) { } +void Quick3DNodeInstance::invokeDummyViewCreate() const +{ + QMetaObject::invokeMethod(m_dummyRootView, "createViewForNode", + Q_ARG(QVariant, QVariant::fromValue(object()))); +} + Quick3DNodeInstance::~Quick3DNodeInstance() { } @@ -79,8 +85,6 @@ void Quick3DNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNo } } - m_dummyRootViewCreateFunction = "createViewForNode"; - Quick3DRenderableNodeInstance::initialize(objectNodeInstance, flags); #else Q_UNUSED(objectNodeInstance) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h index ea44f277fb8..e2b1ebb7e93 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3dnodeinstance.h @@ -47,6 +47,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 cae64ad04c1..94506929eee 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.cpp @@ -50,7 +50,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) @@ -67,8 +67,7 @@ void Quick3DRenderableNodeInstance::initialize(const ObjectNodeInstance::Pointer component.loadUrl(QUrl("qrc:/qtquickplugin/mockfiles/qt6/ModelNode3DImageView.qml")); m_dummyRootView = qobject_cast(component.create()); - QMetaObject::invokeMethod(m_dummyRootView, m_dummyRootViewCreateFunction, - Q_ARG(QVariant, QVariant::fromValue(object()))); + invokeDummyViewCreate(); nodeInstanceServer()->setRootItem(m_dummyRootView); } @@ -215,6 +214,10 @@ Qt5NodeInstanceServer *Quick3DRenderableNodeInstance::qt5NodeInstanceServer() co return qobject_cast(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 208144cb52f..f24b149528a 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quick3drenderablenodeinstance.h @@ -57,10 +57,8 @@ public: protected: explicit Quick3DRenderableNodeInstance(QObject *node); Qt5NodeInstanceServer *qt5NodeInstanceServer() const; + virtual void invokeDummyViewCreate() const; - QByteArray m_dummyRootViewCreateFunction; - -private: QQuickItem *m_dummyRootView = nullptr; }; From 2f55183557dccd1265b39f3059c59037e1967be1 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 22 Sep 2022 14:15:25 +0300 Subject: [PATCH 24/37] QmlDesigner: Fix crash if build target is not defined Change-Id: Ieae55ff1a5f5de132f10ee5b51bab610ece8e39a Reviewed-by: Thomas Hartmann Reviewed-by: Mahmoud Badri Reviewed-by: --- .../imagecache/meshimagecachecollector.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/imagecache/meshimagecachecollector.cpp b/src/plugins/qmldesigner/designercore/imagecache/meshimagecachecollector.cpp index 7602ee7a119..eb064929f53 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/meshimagecachecollector.cpp +++ b/src/plugins/qmldesigner/designercore/imagecache/meshimagecachecollector.cpp @@ -57,10 +57,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() < QtSupport::QtVersionNumber(6, 0, 0)) { - qtQuickVersion = "2.15"; - qtQuick3DVersion = "1.15"; + if (target()) { + QtSupport::QtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(target()->kit()); + if (qtVersion && qtVersion->qtVersion() < QtSupport::QtVersionNumber(6, 0, 0)) { + qtQuickVersion = "2.15"; + qtQuick3DVersion = "1.15"; + } } QString content{ From d9201393027022f1851f9a36362984fb83eb897e Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Fri, 23 Sep 2022 16:24:38 +0200 Subject: [PATCH 25/37] QmlDesigner: Fix binding editor empty expression If the user pressed "Accept" on the binding editor if the text was empty a dialog with a warning popped up. This fix avoids sending empty strings to backend when condition. Task-number: QDS-7729 Change-Id: I77e5e9d34f8566dc4ed215c839b01186d839a2df Reviewed-by: Thomas Hartmann --- .../qmldesigner/newstateseditor/Main.qml | 4 ---- .../newstateseditor/StateThumbnail.qml | 17 +++++++++++++---- .../imports/StudioControls/TextField.qml | 4 +++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/share/qtcreator/qmldesigner/newstateseditor/Main.qml b/share/qtcreator/qmldesigner/newstateseditor/Main.qml index ca2cf9e1eb4..dd9e5772b49 100644 --- a/share/qtcreator/qmldesigner/newstateseditor/Main.qml +++ b/share/qtcreator/qmldesigner/newstateseditor/Main.qml @@ -807,10 +807,6 @@ Rectangle { onStateNameFinished: statesEditorModel.renameState( delegateRoot.internalNodeId, stateThumbnail.stateName) - - onWhenConditionFinished: statesEditorModel.setWhenCondition( - delegateRoot.internalNodeId, - stateThumbnail.whenCondition) } } } diff --git a/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml b/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml index 199ef9bd777..9cde5f27449 100644 --- a/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml +++ b/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml @@ -65,7 +65,6 @@ Item { signal extend signal remove signal stateNameFinished - signal whenConditionFinished signal grabbing signal letGo @@ -608,8 +607,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) @@ -635,6 +642,8 @@ Item { indicatorVisible: true indicator.icon.text: StudioTheme.Constants.edit indicator.onClicked: { + whenCondition.previousCondition = whenCondition.text + bindingEditor.showWidget() bindingEditor.text = whenCondition.text bindingEditor.prepareBindings() @@ -662,7 +671,7 @@ Item { whenCondition.previousCondition = whenCondition.text if (whenCondition.text !== "") - root.whenConditionFinished() + statesEditorModel.setWhenCondition(root.internalNodeId, root.whenCondition) else statesEditorModel.resetWhenCondition(root.internalNodeId) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml index 531a5b0ff35..0a683fa6d12 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/TextField.qml @@ -99,7 +99,9 @@ T.TextField { } 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 } From 5582a8047a913844e7cc75a62653e9b9fc179342 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Fri, 23 Sep 2022 16:14:22 +0200 Subject: [PATCH 26/37] QmlDesigner: Fix model sync on property remove Removing the name property of a state in the TextEditor was not triggering a model rest, which caused the StateEditor being in a wrong state. Change-Id: I1bd43f5f6bfb962e4a838cbd74c37c7ed4e37d9c Reviewed-by: Thomas Hartmann --- .../components/stateseditornew/stateseditorview.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/components/stateseditornew/stateseditorview.cpp b/src/plugins/qmldesigner/components/stateseditornew/stateseditorview.cpp index 9a0af786c38..a4ba6867cbc 100644 --- a/src/plugins/qmldesigner/components/stateseditornew/stateseditorview.cpp +++ b/src/plugins/qmldesigner/components/stateseditornew/stateseditorview.cpp @@ -719,7 +719,7 @@ void StatesEditorView::propertiesRemoved(const QList& 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") @@ -847,7 +847,8 @@ void StatesEditorView::variantPropertiesChanged(const QList &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()) From 507b1fff39bf47b794ad766cef78ed04f4f4ad0e Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Fri, 23 Sep 2022 16:16:33 +0200 Subject: [PATCH 27/37] QmlDesigner: Create importComponentObject in root context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This might be the implicit default, but let's make this explicit. Change-Id: Ic42735b12f22819767ceb642d265f813201c9146 Reviewed-by: Henning Gründl Reviewed-by: Qt CI Bot --- .../qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp index 31a907c37fe..f62972d5716 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp @@ -534,7 +534,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()); From 85b911d30b9eb5e3ad4ce21f0773a27057d57b21 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Fri, 23 Sep 2022 16:17:28 +0200 Subject: [PATCH 28/37] QmlDesigner: Fix anchor targets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In some cases the binding for anchor targets is not properly resolved. Using explicitly the root context we define the ids in does solve the issue. Change-Id: I69e5bd237668719ec9417d30d0bac8635c79506a Reviewed-by: Henning Gründl Reviewed-by: Qt CI Bot --- .../qml2puppet/instances/quickitemnodeinstance.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp index 5b1f3171adb..549db1b789b 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp @@ -872,6 +872,10 @@ void QuickItemNodeInstance::setPropertyVariant(const PropertyName &name, const Q void QuickItemNodeInstance::setPropertyBinding(const PropertyName &name, const QString &expression) { + static QList anchorsTargets = {"anchors.top", + "acnhors.bottom", + "anchors.left", + "achors.right"}; if (ignoredProperties().contains(name)) return; @@ -883,7 +887,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(); From 9542e9bd1c6cac1ddf1e6dad3f1c5a91e10d2341 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 26 Sep 2022 08:42:50 +0200 Subject: [PATCH 29/37] Doc: Fix missing \endlist command Change-Id: I4daee6fad7d016c60b359c881852549c4d751528 Reviewed-by: Mats Honkamaa Reviewed-by: hjk --- .../src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc index 5c2bf4f14bd..be04354ee11 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc @@ -76,7 +76,7 @@ \li Create cameras, lights, and models. \li Open \uicontrol {Material Editor} and edit materials. \li Delete components - \list + \endlist \image 3d-view-context-menu.png From e32f585fdaa5c374fc5cd12e527876287c7ee6aa Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Fri, 23 Sep 2022 23:53:27 +0200 Subject: [PATCH 30/37] QmlDesigner: Fix drop incorrect place * Fix drop incorrect place * Improve overall drag smoothness Task-number: QDS-7733 Change-Id: I70e23df54c0e52b423c21b883924c5daee955d0a Reviewed-by: Reviewed-by: Thomas Hartmann --- .../qmldesigner/newstateseditor/Main.qml | 33 +++++++------------ .../newstateseditor/StateThumbnail.qml | 7 ++++ 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/share/qtcreator/qmldesigner/newstateseditor/Main.qml b/share/qtcreator/qmldesigner/newstateseditor/Main.qml index dd9e5772b49..f38baa7bd4a 100644 --- a/share/qtcreator/qmldesigner/newstateseditor/Main.qml +++ b/share/qtcreator/qmldesigner/newstateseditor/Main.qml @@ -599,11 +599,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) @@ -646,27 +641,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 } - if (statesRepeater.grabIndex === stateThumbnail.visualIndex) + if (statesRepeater.grabIndex === dropSource.visualIndex) return - statesRepeater.executeDrop(statesRepeater.grabIndex, - stateThumbnail.visualIndex) + statesEditorModel.drop(statesRepeater.grabIndex, + dropSource.visualIndex) + statesRepeater.grabIndex = -1 } // Extend Groups Visualization @@ -768,6 +763,8 @@ Rectangle { hasWhenCondition: delegateRoot.hasWhenCondition + dragParent: scrollView + // Fix ScrollView taking over the dragging event onGrabbing: { frame.interactive = false @@ -775,14 +772,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 diff --git a/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml b/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml index 9cde5f27449..ee1ea8132a4 100644 --- a/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml +++ b/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml @@ -55,6 +55,8 @@ Item { property bool hasWhenCondition: false + property Item dragParent + property int visualIndex: 0 property int internalNodeId @@ -765,6 +767,11 @@ Item { name: "drag" when: dragHandler.active + ParentChange { + target: root + parent: root.dragParent + } + AnchorChanges { target: root anchors.horizontalCenter: undefined From 9bde8dc3e8dc853959895e653a41bf6ed3a67f95 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Mon, 26 Sep 2022 11:36:14 +0200 Subject: [PATCH 31/37] QmlDesigner: Fix dragging while scrolling Task-number: QDS-7744 Change-Id: I99de01a09ef939e506c07d411c42bd2b28a53c31 Reviewed-by: Thomas Hartmann Reviewed-by: Brook Cronin --- share/qtcreator/qmldesigner/newstateseditor/Main.qml | 4 ++++ .../qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/share/qtcreator/qmldesigner/newstateseditor/Main.qml b/share/qtcreator/qmldesigner/newstateseditor/Main.qml index f38baa7bd4a..9bc9e6eb4b3 100644 --- a/share/qtcreator/qmldesigner/newstateseditor/Main.qml +++ b/share/qtcreator/qmldesigner/newstateseditor/Main.qml @@ -526,6 +526,7 @@ Rectangle { anchors.leftMargin: root.leftMargin ScrollBar.horizontal: StateScrollBar { + id: horizontalBar parent: scrollView x: scrollView.leftPadding y: scrollView.height - height @@ -534,6 +535,7 @@ Rectangle { } ScrollBar.vertical: StateScrollBar { + id: verticalBar parent: scrollView x: scrollView.mirrored ? 0 : scrollView.width - width y: scrollView.topPadding @@ -763,6 +765,8 @@ Rectangle { hasWhenCondition: delegateRoot.hasWhenCondition + scrollViewActive: horizontalBar.active || verticalBar.active + dragParent: scrollView // Fix ScrollView taking over the dragging event diff --git a/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml b/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml index ee1ea8132a4..ce95aa21983 100644 --- a/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml +++ b/share/qtcreator/qmldesigner/newstateseditor/StateThumbnail.qml @@ -55,6 +55,8 @@ Item { property bool hasWhenCondition: false + property bool scrollViewActive: false + property Item dragParent property int visualIndex: 0 @@ -89,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) From db46d8d76fb7eef445f071bd37914707cfaea887 Mon Sep 17 00:00:00 2001 From: Henning Gruendl Date: Mon, 26 Sep 2022 11:37:28 +0200 Subject: [PATCH 32/37] QmlDesigner: Avoid drag and drop faulty state Avoid the issue described in QTBUG-106943 by reducing the animation duration. Change-Id: Ide2004885d945680fa80cb8d0f10968ae33c8611 Reviewed-by: Thomas Hartmann Reviewed-by: Brook Cronin --- share/qtcreator/qmldesigner/newstateseditor/Main.qml | 1 + 1 file changed, 1 insertion(+) diff --git a/share/qtcreator/qmldesigner/newstateseditor/Main.qml b/share/qtcreator/qmldesigner/newstateseditor/Main.qml index 9bc9e6eb4b3..29feb5741db 100644 --- a/share/qtcreator/qmldesigner/newstateseditor/Main.qml +++ b/share/qtcreator/qmldesigner/newstateseditor/Main.qml @@ -593,6 +593,7 @@ Rectangle { NumberAnimation { properties: "x,y" easing.type: Easing.OutQuad + duration: 100 } } From 945e6fce31e8a4e9530cf61b20c20a74f9443812 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 26 Sep 2022 14:31:50 +0300 Subject: [PATCH 33/37] QmlDesigner: Fix copying material property default values When copying specific set of properties, old values need to be cleared just like in case of copying all properties to ensure also default values get copied. Fixes: QDS-7522 Change-Id: I314ff70b6e611bec3f662b86f964d789618c1df7 Reviewed-by: Mahmoud Badri --- .../components/materialbrowser/materialbrowserview.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 7dd0a913195..b88c0a77d75 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -117,6 +117,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()); } }); }); From 57dc7f8468cb83488dec144f475f157132de9c08 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Mon, 26 Sep 2022 15:21:33 +0300 Subject: [PATCH 34/37] QmlDesigner: Remove an external dependency from the SearchBox Task-number: QDS-7784 Change-Id: Ibd1390398d9984c618da4052560706ac58fb5234 Reviewed-by: Miikka Heikkinen --- share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml | 2 ++ .../qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml | 2 ++ .../qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml | 2 ++ .../imports/HelperWidgets/SearchBox.qml | 4 +++- 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml index b63280b3681..d88b129794b 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml @@ -440,6 +440,8 @@ Item { 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 ae39fdb5e3e..8a926e2273f 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml @@ -225,6 +225,8 @@ Item { 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 d9d207b555f..756a7a98a6f 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml @@ -234,6 +234,8 @@ Item { id: searchBox width: root.width - addMaterialButton.width + + onSearchChanged: (searchText) => rootView.handleSearchfilterChanged(searchText) } IconButton { diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SearchBox.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SearchBox.qml index c50d2e1d68e..3b4f785faaa 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SearchBox.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SearchBox.qml @@ -33,6 +33,8 @@ Item { property alias text: searchFilterText.text + signal searchChanged(string searchText); + function clear() { searchFilterText.text = ""; @@ -80,7 +82,7 @@ Item { selectByMouse: true hoverEnabled: true - onTextChanged: rootView.handleSearchfilterChanged(text) + onTextChanged: root.searchChanged(text) Label { text: StudioTheme.Constants.search From e31debc0e7e5c1cb69d64163b3cecbf99b7fa9f2 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Mon, 26 Sep 2022 15:59:22 +0300 Subject: [PATCH 35/37] QmlDesigner: Move SearchBox to StudioControls Fixes: QDS-7759 Change-Id: Idf33aa47f5e793c4053f825ae8a203b97c078bf1 Reviewed-by: Miikka Heikkinen --- share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml | 2 +- share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml | 2 +- .../qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml | 2 +- .../propertyEditorQmlSources/imports/HelperWidgets/qmldir | 1 - .../imports/{HelperWidgets => StudioControls}/SearchBox.qml | 0 .../propertyEditorQmlSources/imports/StudioControls/qmldir | 1 + 6 files changed, 4 insertions(+), 4 deletions(-) rename share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/{HelperWidgets => StudioControls}/SearchBox.qml (100%) diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml index d88b129794b..eb6408a08f2 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml @@ -436,7 +436,7 @@ Item { width: parent.width - SearchBox { + StudioControls.SearchBox { id: searchBox width: parent.width - addAssetButton.width - 5 diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml index 8a926e2273f..1f7c8ad6623 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml @@ -221,7 +221,7 @@ Item { Row { width: parent.width - SearchBox { + StudioControls.SearchBox { id: searchBox width: parent.width - addModuleButton.width - 5 diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml index 756a7a98a6f..0e3b3a086a8 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml @@ -230,7 +230,7 @@ Item { width: root.width enabled: !materialBrowserModel.hasMaterialRoot && materialBrowserModel.hasQuick3DImport - SearchBox { + StudioControls.SearchBox { id: searchBox width: root.width - addMaterialButton.width diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/qmldir b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/qmldir index 5a18d24846b..f145b098776 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 similarity index 100% rename from share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/SearchBox.qml rename to share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/SearchBox.qml diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/qmldir b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioControls/qmldir index 878b2307c38..fea940d8783 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 From d47e9772e0e9c807e2b76e91df241bd2fdcd7ea8 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Mon, 26 Sep 2022 16:29:03 +0300 Subject: [PATCH 36/37] QmlDesigner: Correct a method's camelCase naming Change-Id: If9d4b750a09873fc0de8f85edcb41d220cbe5a41 Reviewed-by: Miikka Heikkinen --- share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml | 2 +- share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml | 2 +- .../qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml | 2 +- .../components/assetslibrary/assetslibrarywidget.cpp | 2 +- .../qmldesigner/components/assetslibrary/assetslibrarywidget.h | 2 +- .../qmldesigner/components/itemlibrary/itemlibrarywidget.cpp | 2 +- .../qmldesigner/components/itemlibrary/itemlibrarywidget.h | 2 +- .../components/materialbrowser/materialbrowserwidget.cpp | 2 +- .../components/materialbrowser/materialbrowserwidget.h | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml index eb6408a08f2..6578f96b7d1 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml @@ -441,7 +441,7 @@ Item { width: parent.width - addAssetButton.width - 5 - onSearchChanged: (searchText) => rootView.handleSearchfilterChanged(searchText) + onSearchChanged: (searchText) => rootView.handleSearchFilterChanged(searchText) } IconButton { diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml index 1f7c8ad6623..a9abc857d2c 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml @@ -226,7 +226,7 @@ Item { width: parent.width - addModuleButton.width - 5 - onSearchChanged: (searchText) => rootView.handleSearchfilterChanged(searchText) + onSearchChanged: (searchText) => rootView.handleSearchFilterChanged(searchText) } IconButton { diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml index 0e3b3a086a8..20d970e4c59 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml @@ -235,7 +235,7 @@ Item { width: root.width - addMaterialButton.width - onSearchChanged: (searchText) => rootView.handleSearchfilterChanged(searchText) + onSearchChanged: (searchText) => rootView.handleSearchFilterChanged(searchText) } IconButton { diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp index 632574fb0fc..7c111f80c0b 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp @@ -187,7 +187,7 @@ QList 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 18baef0d6cc..29ba7d0349c 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h @@ -78,7 +78,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 &simpleFilePaths, const QList &complexFilePaths, const QString &targetDirPath = {}); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 1e4a9d232f6..51b807d614a 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -227,7 +227,7 @@ QList 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 1b63c2fc660..a323fa8fd74 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h @@ -91,7 +91,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/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp index 99f063dfae4..1bdfbdd58eb 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp @@ -214,7 +214,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 93197225a11..0d50a84cc60 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.h @@ -73,7 +73,7 @@ public: QPointer 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); From 4da66867051b27354b71ff6b4690d4e2d1e53bd6 Mon Sep 17 00:00:00 2001 From: Aleksei German Date: Mon, 19 Sep 2022 18:25:36 +0200 Subject: [PATCH 37/37] QmlDesigner: Add Connections Shortcuts Task-number: QDS-7641 Change-Id: I1cb8f10cb675cee7dd48481cb31e4807fc592dc3 Reviewed-by: Reviewed-by: Thomas Hartmann --- .../components/bindingeditor/actioneditor.cpp | 64 ++++ .../components/bindingeditor/actioneditor.h | 5 + .../componentcore/componentcore_constants.h | 3 + .../componentcore/designeractionmanager.cpp | 302 ++++++++++++++++++ 4 files changed, 374 insertions(+) diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp index 21d7b37e9f2..60f703bdf9d 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp @@ -304,4 +304,68 @@ void ActionEditor::updateWindowName(const QString &targetName) } } +void ActionEditor::invokeEditor(SignalHandlerProperty signalHandler, + std::function 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 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 09597bc8d18..1a9e2c87540 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h +++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,10 @@ public: Q_INVOKABLE void updateWindowName(const QString &targetName = {}); + static void invokeEditor(SignalHandlerProperty signalHandler, + std::function 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 ef2e59397b2..884a4f4413f 100644 --- a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h +++ b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h @@ -34,6 +34,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"; @@ -98,6 +99,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"); @@ -205,6 +207,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 f569546fbeb..71451396be2 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -452,6 +453,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 action; +}; + +QList getSlotsLists(const ModelNode &node) +{ + if (!node.isValid()) + return {}; + + if (!node.view()->rootModelNode().isValid()) + return {}; + + QList 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 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: @@ -999,6 +1296,11 @@ void DesignerActionManager::createDefaultDesignerActions() selectionCategory, prioritySelectionCategory)); + addDesignerAction(new ConnectionsModelNodeActionGroup( + connectionsCategoryDisplayName, + connectionsCategory, + priorityConnectionsCategory)); + addDesignerAction(new ActionGroup( arrangeCategoryDisplayName, arrangeCategory,