From 2ccc4a03ed6e52911321fc139dfd9fb3f8f65594 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Fri, 21 Oct 2022 08:46:46 +0000 Subject: [PATCH 01/97] Revert "QmlDesigner: Add "imported" icon to the icons font" This reverts commit b0fa74756504e83b690ca737c6a67de1de8e32ba. Reason for revert: imported icon not needed anymore. also removed icons are needed. Change-Id: I2d3423a585358abd760f55bba1215d6d2878fdc1 Reviewed-by: Miikka Heikkinen --- .../imports/StudioTheme/InternalConstants.qml | 242 +++++++++--------- .../imports/StudioTheme/icons.ttf | Bin 23968 -> 24432 bytes .../components/componentcore/theme.h | 4 +- 3 files changed, 125 insertions(+), 121 deletions(-) diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml index 484386ec946..368a7e9b76f 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/InternalConstants.qml @@ -71,126 +71,128 @@ QtObject { readonly property string centerHorizontal: "\u0042" readonly property string centerVertical: "\u0043" readonly property string closeCross: "\u0044" - readonly property string colorPopupClose: "\u0045" - readonly property string columnsAndRows: "\u0046" - readonly property string copyStyle: "\u0047" - readonly property string cornerA: "\u0048" - readonly property string cornerB: "\u0049" - readonly property string cornersAll: "\u004A" - readonly property string curveDesigner: "\u004B" - readonly property string curveEditor: "\u004C" - readonly property string customMaterialEditor: "\u004D" - readonly property string decisionNode: "\u004E" - readonly property string deleteColumn: "\u004F" - readonly property string deleteMaterial: "\u0050" - readonly property string deleteRow: "\u0051" - readonly property string deleteTable: "\u0052" - readonly property string detach: "\u0053" - readonly property string distributeBottom: "\u0054" - readonly property string distributeCenterHorizontal: "\u0055" - readonly property string distributeCenterVertical: "\u0056" - readonly property string distributeLeft: "\u0057" - readonly property string distributeOriginBottomRight: "\u0058" - readonly property string distributeOriginCenter: "\u0059" - readonly property string distributeOriginNone: "\u005A" - readonly property string distributeOriginTopLeft: "\u005B" - readonly property string distributeRight: "\u005C" - readonly property string distributeSpacingHorizontal: "\u005D" - readonly property string distributeSpacingVertical: "\u005E" - readonly property string distributeTop: "\u005F" - readonly property string download: "\u0060" - readonly property string downloadUnavailable: "\u0061" - readonly property string downloadUpdate: "\u0062" - readonly property string downloaded: "\u0063" - readonly property string edit: "\u0064" - readonly property string eyeDropper: "\u0065" - readonly property string favorite: "\u0066" - readonly property string flowAction: "\u0067" - readonly property string flowTransition: "\u0068" - readonly property string fontStyleBold: "\u0069" - readonly property string fontStyleItalic: "\u006A" - readonly property string fontStyleStrikethrough: "\u006B" - readonly property string fontStyleUnderline: "\u006C" - readonly property string gradient: "\u006D" - readonly property string gridView: "\u006E" - readonly property string idAliasOff: "\u006F" - readonly property string idAliasOn: "\u0070" - readonly property string imported: "\u0071" - readonly property string infinity: "\u0072" - readonly property string keyframe: "\u0073" - readonly property string linkTriangle: "\u0074" - readonly property string linked: "\u0075" - readonly property string listView: "\u0076" - readonly property string lockOff: "\u0077" - readonly property string lockOn: "\u0078" - readonly property string materialPreviewEnvironment: "\u0079" - readonly property string materialPreviewModel: "\u007A" - readonly property string mergeCells: "\u007B" - readonly property string minus: "\u007C" - readonly property string mirror: "\u007D" - readonly property string newMaterial: "\u007E" - readonly property string openMaterialBrowser: "\u007F" - readonly property string orientation: "\u0080" - readonly property string paddingEdge: "\u0081" - readonly property string paddingFrame: "\u0082" - readonly property string pasteStyle: "\u0083" - readonly property string pause: "\u0084" - readonly property string pin: "\u0085" - readonly property string play: "\u0086" - readonly property string plus: "\u0087" - readonly property string promote: "\u0088" - readonly property string readOnly: "\u0089" - readonly property string redo: "\u008A" - readonly property string rotationFill: "\u008B" - readonly property string rotationOutline: "\u008C" - readonly property string search: "\u008D" - readonly property string sectionToggle: "\u008E" - readonly property string splitColumns: "\u008F" - readonly property string splitRows: "\u0090" - readonly property string startNode: "\u0091" - readonly property string testIcon: "\u0092" - readonly property string textAlignBottom: "\u0093" - readonly property string textAlignCenter: "\u0094" - readonly property string textAlignJustified: "\u0095" - readonly property string textAlignLeft: "\u0096" - readonly property string textAlignMiddle: "\u0097" - readonly property string textAlignRight: "\u0098" - readonly property string textAlignTop: "\u0099" - readonly property string textBulletList: "\u009A" - readonly property string textFullJustification: "\u009B" - readonly property string textNumberedList: "\u009D" - readonly property string tickIcon: "\u009E" - readonly property string translationCreateFiles: "\u009F" - readonly property string translationCreateReport: "\u00A0" - readonly property string translationExport: "\u00A1" - readonly property string translationImport: "\u00A2" - readonly property string translationSelectLanguages: "\u00A3" - readonly property string translationTest: "\u00A4" - readonly property string transparent: "\u00A5" - readonly property string triState: "\u00A6" - readonly property string triangleArcA: "\u00A7" - readonly property string triangleArcB: "\u00A8" - readonly property string triangleCornerA: "\u00A9" - readonly property string triangleCornerB: "\u00AA" - readonly property string unLinked: "\u00AB" - readonly property string undo: "\u00AC" - readonly property string unpin: "\u00AE" - readonly property string upDownIcon: "\u00AF" - readonly property string upDownSquare2: "\u00B0" - readonly property string visibilityOff: "\u00B1" - readonly property string visibilityOn: "\u00B2" - readonly property string wildcard: "\u00B3" - readonly property string wizardsAutomotive: "\u00B4" - readonly property string wizardsDesktop: "\u00B5" - readonly property string wizardsGeneric: "\u00B6" - readonly property string wizardsMcuEmpty: "\u00B7" - readonly property string wizardsMcuGraph: "\u00B8" - readonly property string wizardsMobile: "\u00B9" - readonly property string wizardsUnknown: "\u00BA" - readonly property string zoomAll: "\u00BB" - readonly property string zoomIn: "\u00BC" - readonly property string zoomOut: "\u00BD" - readonly property string zoomSelection: "\u00BE" + readonly property string closeLink: "\u0045" + readonly property string colorPopupClose: "\u0046" + readonly property string columnsAndRows: "\u0047" + readonly property string copyLink: "\u0048" + readonly property string copyStyle: "\u0049" + readonly property string cornerA: "\u004A" + readonly property string cornerB: "\u004B" + readonly property string cornersAll: "\u004C" + readonly property string curveDesigner: "\u004D" + readonly property string curveEditor: "\u004E" + readonly property string customMaterialEditor: "\u004F" + readonly property string decisionNode: "\u0050" + readonly property string deleteColumn: "\u0051" + readonly property string deleteMaterial: "\u0052" + readonly property string deleteRow: "\u0053" + readonly property string deleteTable: "\u0054" + readonly property string detach: "\u0055" + readonly property string distributeBottom: "\u0056" + readonly property string distributeCenterHorizontal: "\u0057" + readonly property string distributeCenterVertical: "\u0058" + readonly property string distributeLeft: "\u0059" + readonly property string distributeOriginBottomRight: "\u005A" + readonly property string distributeOriginCenter: "\u005B" + readonly property string distributeOriginNone: "\u005C" + readonly property string distributeOriginTopLeft: "\u005D" + readonly property string distributeRight: "\u005E" + readonly property string distributeSpacingHorizontal: "\u005F" + readonly property string distributeSpacingVertical: "\u0060" + readonly property string distributeTop: "\u0061" + readonly property string download: "\u0062" + readonly property string downloadUnavailable: "\u0063" + readonly property string downloadUpdate: "\u0064" + readonly property string downloaded: "\u0065" + readonly property string edit: "\u0066" + readonly property string eyeDropper: "\u0067" + readonly property string favorite: "\u0068" + readonly property string flowAction: "\u0069" + readonly property string flowTransition: "\u006A" + readonly property string fontStyleBold: "\u006B" + readonly property string fontStyleItalic: "\u006C" + readonly property string fontStyleStrikethrough: "\u006D" + readonly property string fontStyleUnderline: "\u006E" + readonly property string gradient: "\u006F" + readonly property string gridView: "\u0070" + readonly property string idAliasOff: "\u0071" + readonly property string idAliasOn: "\u0072" + readonly property string infinity: "\u0073" + readonly property string keyframe: "\u0074" + readonly property string linkTriangle: "\u0075" + readonly property string linked: "\u0076" + readonly property string listView: "\u0077" + readonly property string lockOff: "\u0078" + readonly property string lockOn: "\u0079" + readonly property string materialPreviewEnvironment: "\u007A" + readonly property string materialPreviewModel: "\u007B" + readonly property string mergeCells: "\u007C" + readonly property string minus: "\u007D" + readonly property string mirror: "\u007E" + readonly property string newMaterial: "\u007F" + readonly property string openLink: "\u0080" + readonly property string openMaterialBrowser: "\u0081" + readonly property string orientation: "\u0082" + readonly property string paddingEdge: "\u0083" + readonly property string paddingFrame: "\u0084" + readonly property string pasteStyle: "\u0085" + readonly property string pause: "\u0086" + readonly property string pin: "\u0087" + readonly property string play: "\u0088" + readonly property string plus: "\u0089" + readonly property string promote: "\u008A" + readonly property string readOnly: "\u008B" + readonly property string redo: "\u008C" + readonly property string rotationFill: "\u008D" + readonly property string rotationOutline: "\u008E" + readonly property string search: "\u008F" + readonly property string sectionToggle: "\u0090" + readonly property string splitColumns: "\u0091" + readonly property string splitRows: "\u0092" + readonly property string startNode: "\u0093" + readonly property string testIcon: "\u0094" + readonly property string textAlignBottom: "\u0095" + readonly property string textAlignCenter: "\u0096" + readonly property string textAlignJustified: "\u0097" + readonly property string textAlignLeft: "\u0098" + readonly property string textAlignMiddle: "\u0099" + readonly property string textAlignRight: "\u009A" + readonly property string textAlignTop: "\u009B" + readonly property string textBulletList: "\u009D" + readonly property string textFullJustification: "\u009E" + readonly property string textNumberedList: "\u009F" + readonly property string tickIcon: "\u00A0" + readonly property string translationCreateFiles: "\u00A1" + readonly property string translationCreateReport: "\u00A2" + readonly property string translationExport: "\u00A3" + readonly property string translationImport: "\u00A4" + readonly property string translationSelectLanguages: "\u00A5" + readonly property string translationTest: "\u00A6" + readonly property string transparent: "\u00A7" + readonly property string triState: "\u00A8" + readonly property string triangleArcA: "\u00A9" + readonly property string triangleArcB: "\u00AA" + readonly property string triangleCornerA: "\u00AB" + readonly property string triangleCornerB: "\u00AC" + readonly property string unLinked: "\u00AE" + readonly property string undo: "\u00AF" + readonly property string unpin: "\u00B0" + readonly property string upDownIcon: "\u00B1" + readonly property string upDownSquare2: "\u00B2" + readonly property string visibilityOff: "\u00B3" + readonly property string visibilityOn: "\u00B4" + readonly property string wildcard: "\u00B5" + readonly property string wizardsAutomotive: "\u00B6" + readonly property string wizardsDesktop: "\u00B7" + readonly property string wizardsGeneric: "\u00B8" + readonly property string wizardsMcuEmpty: "\u00B9" + readonly property string wizardsMcuGraph: "\u00BA" + readonly property string wizardsMobile: "\u00BB" + readonly property string wizardsUnknown: "\u00BC" + readonly property string zoomAll: "\u00BD" + readonly property string zoomIn: "\u00BE" + readonly property string zoomOut: "\u00BF" + readonly property string zoomSelection: "\u00C0" readonly property font iconFont: Qt.font({ "family": controlIcons.name, diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/icons.ttf index e3b40281c8265d55a97d54aa1443743a3a6928af..acd8df6ce3ff87fe98d8d5df178d672e0d6d070e 100644 GIT binary patch delta 1998 zcmZ3moAJXw#(D-u1_lORh6V;^h5$FW5Z^hk*YYzk#D_32Fv$1^>l;OOq{c8XFh(#i zFeD`BCKlX(w|W)>12YQ)17lEfS&0IJB2y&;0}Du=B|WjY;QxOHW(J0M9|i^nj`W<$ zw2bd*pBNZe7cek*t;tADOi|SoI>^AlaEF0`!7L*qwLX#S<^PEc42&WS3=Aq6xg`~1 zh1?+i4h9BBublkkM6>^1Wef}~AV;|5CRP+Md}TPzz`$t1z`&r8mzbNn@5NhV28IA1 z1_q|51^LA#X^9`47#M<07#MgYz@B4dU^x40&*^x6o39Mq%r6)i7#QyRryqjQGU))^vJ|5-8|%5bgf|JF5#bPt6FDWyB`PMWRWBMPnkTwV^oZyu zF%_{jVo$_H#O=h3#2dudiQf@_CBY#PC$UQ6i=>0(G|5L&7E)8B9!S?nFOYsF<0aD} zb4=DrHb?fB>?b)MIW;*axeB>$a_{7u7ozgeu6y*~t1}a@D zXH?l#!x)$t6d4#8wU}lxY+lT|oRvw4WwQ_W8#X3(w#`;T6B+CE{--hTV*11&&A`CP zC?>+Dq|V96rle+K&dI1|VrC@H$!KOICc@67z&L?ZSd#N!!M_4dNnuXL3I7T}e8vfk z6To~O?Bf3lAo{?u&HUez`8l&Z12+Q$Clfm-qdF(!Yc4tpjT)yztAG{*S~Kd6POBpvW29C+>QSBgA4&1 z$hbLAyU?OwfkmcHrfQD&zkXp!&IT?J(U_r@VpTWC=@-y)M?vyF%)hdvX7+y8Rr znM@ZMm>Jj^7#P(V#f8}!&6)dk{yf&<(q)#_Wts|NGDqtEd92H@`HD<5hyM*`X$E-) zH3kM2B{g+(IYwh6GjlseHFZ5kB{p_-J4PchaXCg2Hg+~aQAJT*Mo}j3gWKG-ZRdrB z&$SJ~wcyJZx7xXHG2x0}})Le>-NP zEn_CmvcIa5f*6)J_VWj017b~biJHFaSzc4IS>$+v9{WVpEg z?GgFLvyGE;3m@YeCdMQkMn&!9R{{cC`1mHP+v(_<=9*+P8k?Ksnwl}DF(!1jC;z*U zlVy@?%4jZDAJz6xB&JR@v+bi;eN+pQSP7db`?-xwEeUKD7@$ig^}asK89L2*o6yvaHF#i>4-dD)Y#LbW-0 zlJg5HLA=e0p_xUCN2;B3yv@| zF!(KDU|_mgkY8L7#*xACfYXPwiE{_%FD?VFIIcZh7r0(+i>S`&*MJA zeS`Z8j{uJfPZiH0UOrww-f6r~_!#)q_$v5T@a^O0;5Xx+#D7A7L%>5IO<;$>1%YRR zI)Xid7lg!wI)v^Bs|ec&hY3#-{wHE5;w2I%(kHU0UgVX?4^cJI2+;>(5@H@=MPkdu zwun6v7Z8^dw-KKteosO}qD119q?lxm*Rw8WWfElF9K!vEjfstYvy;$7#>w^~C7b7qnsLOlFu48CWS+@%k%5hY zn?Z;{l7WFyosXH_kdIMKU09A;+?(RZxnHNY>-x?pE-pcKv)axZJ0o@fJl17n z=i=aGnyORR^Xx$-7ptTavu<7Qv-?%L%(A*{tc+Zen_1+dIaFRU>oCYNs4y_FD5sD7ZzhTHk({$Zy+Ng@^6pGH=b>Rf?N0)*Dx_A=`bp4C%+O9*dik{`INnmMs{{K zqp^8*wi#m@V?t+p^1ll?S=rf)=3@0xZU01K>O?c!K8n>xHEmXQun?%1X0QNfNd^W+ z21$kvD4U6aonaG{&CFoNr~zfOFi0{^hO${1_!-Ya*=!7wOo9x|42&$Cpi+bZR2+fW zj0{E$Ay9E920n&GP&P9|4#O@GTY-g>frY_{F&@NW;bdTCkYij6WwS9DG2Wg0D?n2# zmm!fMi6N08g`tQclYzlGzo4=xGd-h3K_gjH!N|bKNJk+zF)1;nD06a5-~moU1_K6N z215pe$;v?%tcC`jW7U8PQ?70Q`MJ1^zlf$D< hZPtrcWKjVXHUIyEiycrw%y7@=EvRHeDxuEI001)aT#Wz# diff --git a/src/plugins/qmldesigner/components/componentcore/theme.h b/src/plugins/qmldesigner/components/componentcore/theme.h index 3b4846122d8..56bebd51c10 100644 --- a/src/plugins/qmldesigner/components/componentcore/theme.h +++ b/src/plugins/qmldesigner/components/componentcore/theme.h @@ -79,8 +79,10 @@ public: centerHorizontal, centerVertical, closeCross, + closeLink, colorPopupClose, columnsAndRows, + copyLink, copyStyle, cornerA, cornerB, @@ -123,7 +125,6 @@ public: gridView, idAliasOff, idAliasOn, - imported, infinity, keyframe, linkTriangle, @@ -137,6 +138,7 @@ public: minus, mirror, newMaterial, + openLink, openMaterialBrowser, orientation, paddingEdge, From bad166cda85ee9e055f7e9c098a811b58114d984 Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Thu, 20 Oct 2022 22:44:59 +0300 Subject: [PATCH 02/97] QmlDesigner: Maintain bundle categories expand state Prevent categories auto-expanding when adding an bundle material instance. Also some relevant tweaks. Fixes: QDS-8043 Change-Id: Id87886c6d6e065f2c9c1253279348e076bc4d97f Reviewed-by: Miikka Heikkinen --- .../MaterialBrowser.qml | 7 +++-- .../bundlematerialcategory.cpp | 5 ++++ .../materialbrowser/bundlematerialcategory.h | 11 ++++++-- .../materialbrowserbundlemodel.cpp | 28 +++++++++++++------ .../materialbrowserbundlemodel.h | 1 + 5 files changed, 39 insertions(+), 13 deletions(-) diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml index 1e8cdfda5d1..7ee927f250a 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml @@ -263,10 +263,13 @@ Item { delegate: Section { width: root.width - caption: bundleCategory + caption: bundleCategoryName addTopPadding: false sectionBackgroundColor: "transparent" visible: bundleCategoryVisible + expanded: bundleCategoryExpanded + expandOnClick: false + onToggleExpand: bundleCategoryExpanded = !bundleCategoryExpanded Grid { width: scrollView.width @@ -276,7 +279,7 @@ Item { columns: root.width / root.cellWidth Repeater { - model: bundleMaterialsModel + model: bundleCategoryMaterials delegate: BundleMaterialItem { width: root.cellWidth diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.cpp b/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.cpp index 716fb57dbf5..60910abb046 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.cpp @@ -72,6 +72,11 @@ bool BundleMaterialCategory::visible() const return m_visible; } +bool BundleMaterialCategory::expanded() const +{ + return m_expanded; +} + QList BundleMaterialCategory::categoryMaterials() const { return m_categoryMaterials; diff --git a/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.h b/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.h index 2336a03d010..14f7ddf654e 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.h +++ b/src/plugins/qmldesigner/components/materialbrowser/bundlematerialcategory.h @@ -35,8 +35,11 @@ class BundleMaterialCategory : public QObject { Q_OBJECT - Q_PROPERTY(QString categoryName MEMBER m_name CONSTANT) - Q_PROPERTY(bool categoryVisible MEMBER m_visible NOTIFY categoryVisibleChanged) + Q_PROPERTY(QString bundleCategoryName MEMBER m_name CONSTANT) + Q_PROPERTY(bool bundleCategoryVisible MEMBER m_visible NOTIFY categoryVisibleChanged) + Q_PROPERTY(bool bundleCategoryExpanded MEMBER m_expanded NOTIFY categoryExpandChanged) + Q_PROPERTY(QList bundleCategoryMaterials MEMBER m_categoryMaterials + NOTIFY bundleMaterialsModelChanged) public: BundleMaterialCategory(QObject *parent, const QString &name); @@ -47,14 +50,18 @@ public: QString name() const; bool visible() const; + bool expanded() const; QList categoryMaterials() const; signals: void categoryVisibleChanged(); + void categoryExpandChanged(); + void bundleMaterialsModelChanged(); private: QString m_name; bool m_visible = true; + bool m_expanded = true; QList m_categoryMaterials; }; diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp index a43a23a1d1d..441cdc7a693 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp @@ -54,17 +54,26 @@ QVariant MaterialBrowserBundleModel::data(const QModelIndex &index, int role) co QTC_ASSERT(index.isValid() && index.row() < m_bundleCategories.count(), return {}); QTC_ASSERT(roleNames().contains(role), return {}); + return m_bundleCategories.at(index.row())->property(roleNames().value(role)); +} + +bool MaterialBrowserBundleModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid() || !roleNames().contains(role)) + return false; + QByteArray roleName = roleNames().value(role); - if (roleName == "bundleCategory") - return m_bundleCategories.at(index.row())->name(); + BundleMaterialCategory *bundleCategory = m_bundleCategories.at(index.row()); + QVariant currValue = bundleCategory->property(roleName); - if (roleName == "bundleCategoryVisible") - return m_bundleCategories.at(index.row())->visible(); + if (currValue != value) { + bundleCategory->setProperty(roleName, value); - if (roleName == "bundleMaterialsModel") - return QVariant::fromValue(m_bundleCategories.at(index.row())->categoryMaterials()); + emit dataChanged(index, index, {role}); + return true; + } - return {}; + return false; } bool MaterialBrowserBundleModel::isValidIndex(int idx) const @@ -75,9 +84,10 @@ bool MaterialBrowserBundleModel::isValidIndex(int idx) const QHash MaterialBrowserBundleModel::roleNames() const { static const QHash roles { - {Qt::UserRole + 1, "bundleCategory"}, + {Qt::UserRole + 1, "bundleCategoryName"}, {Qt::UserRole + 2, "bundleCategoryVisible"}, - {Qt::UserRole + 3, "bundleMaterialsModel"} + {Qt::UserRole + 3, "bundleCategoryExpanded"}, + {Qt::UserRole + 4, "bundleCategoryMaterials"} }; return roles; } diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.h index 8197ebd78b0..459d7c423af 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.h @@ -57,6 +57,7 @@ public: int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role) override; QHash roleNames() const override; void setSearchText(const QString &searchText); From f496970002e2374d5405be28a79cfcacd0443897 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Fri, 21 Oct 2022 13:36:29 +0300 Subject: [PATCH 03/97] QmlDesigner: Don't copy/remove data property when copying all 'data' property contains node's children, so it should be ignored during the 'copy all properties' operation. Change-Id: Ib056409c9ad0a42ebc40f751173b7a3455d912c6 Reviewed-by: Mahmoud Badri --- .../components/materialbrowser/materialbrowsermodel.cpp | 1 + .../components/materialbrowser/materialbrowserview.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp index cb3a295259b..86f8f7d1948 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp @@ -403,6 +403,7 @@ void MaterialBrowserModel::copyMaterialProperties(int idx, const QString §io } } validProps.remove("objectName"); + validProps.remove("data"); if (m_allPropsCopied || dynamicPropsCopied || m_propertyGroupsObj.empty()) { copiedProps = validProps.values(); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 015b76630c7..979ae3a7ae1 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -123,7 +123,7 @@ WidgetInfo MaterialBrowserView::widgetInfo() } } for (const PropertyName &propName : qAsConst(propNames)) { - if (propName != "objectName") + if (propName != "objectName" && propName != "data") mat.removeProperty(propName); } } From acfd71831cdea3f9177ee86ed1b5f7f9c7e2aa29 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Thu, 20 Oct 2022 22:47:02 +0200 Subject: [PATCH 04/97] Android: Fix crash in AndroidDeployQtStep info.cpuAbi in AndroidDeployQtStep::init can be empty, for example when opening a configured project with a different Qt Creator version, and the "No valid settings file could be found." message appears. Check for !empty(), before accessing the first item. Fixes: QTCREATORBUG-27795 Change-Id: Ife0bf495ed8ea7bfb342300ee2e457398c8ee8f2 Reviewed-by: hjk --- src/plugins/android/androiddeployqtstep.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp index beeb851118f..e676c457c5b 100644 --- a/src/plugins/android/androiddeployqtstep.cpp +++ b/src/plugins/android/androiddeployqtstep.cpp @@ -201,7 +201,8 @@ bool AndroidDeployQtStep::init() } const QtSupport::QtVersion * const qt = QtSupport::QtKitAspect::qtVersion(kit()); - if (qt && qt->supportsMultipleQtAbis() && !selectedAbis.contains(info.cpuAbi.first())) { + if (qt && qt->supportsMultipleQtAbis() && !info.cpuAbi.isEmpty() && + !selectedAbis.contains(info.cpuAbi.first())) { TaskHub::addTask(DeploymentTask(Task::Warning, tr("Android: The main ABI of the deployment device (%1) is not selected. The app " "execution or debugging might not work properly. Add it from Projects > Build > " From c897eacf4975b846c4a520ea5607b86553bdbdb9 Mon Sep 17 00:00:00 2001 From: Aleksei German Date: Tue, 27 Sep 2022 18:18:37 +0200 Subject: [PATCH 05/97] QmlDesigner: Improve connection editor stability Task-number: QDS-8039 Change-Id: Ie200eb080b82558925582a7720e40fc39e93ec63 Reviewed-by: Reviewed-by: Thomas Hartmann --- .../components/bindingeditor/actioneditor.cpp | 33 ++++++++++++------- .../components/bindingeditor/actioneditor.h | 3 +- .../componentcore/designeractionmanager.cpp | 16 ++++++--- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp index 60f703bdf9d..1779db6df53 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp @@ -305,7 +305,8 @@ void ActionEditor::updateWindowName(const QString &targetName) } void ActionEditor::invokeEditor(SignalHandlerProperty signalHandler, - std::function onReject, + std::function removeSignalFunction, + bool removeOnReject, QObject * parent) { if (!signalHandler.isValid()) @@ -336,15 +337,23 @@ void ActionEditor::invokeEditor(SignalHandlerProperty signalHandler, if (!editor) return; if (editor->m_modelNode.isValid()) { - editor->m_modelNode.view()->executeInTransaction("ActionEditor::" - "invokeEditorAccepted", - [=]() { - editor->m_modelNode - .signalHandlerProperty( - signalHandler.name()) - .setSource( - editor->connectionValue()); - }); + editor->m_modelNode.view() + ->executeInTransaction("ActionEditor::" + "invokeEditorAccepted", + [=]() { + if (!editor) + return; + + const QString newSource = editor->connectionValue(); + if ((newSource.isNull() || newSource.trimmed().isEmpty()) + && removeSignalFunction) { + removeSignalFunction(signalHandler); + } else { + editor->m_modelNode + .signalHandlerProperty(signalHandler.name()) + .setSource(newSource); + } + }); } //closing editor widget somewhy triggers rejected() signal. Lets disconect before it affects us: @@ -356,10 +365,10 @@ void ActionEditor::invokeEditor(SignalHandlerProperty signalHandler, if (!editor) return; - if (onReject) { + if (removeOnReject && removeSignalFunction) { editor->m_modelNode.view()->executeInTransaction("ActionEditor::" "invokeEditorOnRejectFunc", - [=]() { onReject(signalHandler); }); + [=]() { removeSignalFunction(signalHandler); }); } //closing editor widget somewhy triggers rejected() signal 2nd time. Lets disconect before it affects us: diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h index 1a9e2c87540..4e481681a1a 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h +++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h @@ -68,7 +68,8 @@ public: Q_INVOKABLE void updateWindowName(const QString &targetName = {}); static void invokeEditor(SignalHandlerProperty signalHandler, - std::function onReject = nullptr, + std::function removeSignalFunction = nullptr, + bool removeOnReject = false, QObject *parent = nullptr); signals: diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index 0edb5487709..02dc868a316 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -568,6 +568,8 @@ ModelNode createNewConnection(ModelNode targetNode) void removeSignal(SignalHandlerProperty signalHandler) { + if (!signalHandler.isValid()) + return; auto connectionNode = signalHandler.parentModelNode(); auto connectionSignals = connectionNode.signalProperties(); if (connectionSignals.size() > 1) { @@ -681,10 +683,14 @@ public: QString( QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Open Connections Editor")), [=](const SelectionContext &) { - signalHandler.parentModelNode().view()->executeInTransaction( - "ConnectionsModelNodeActionGroup::" - "openConnectionsEditor", - [signalHandler]() { ActionEditor::invokeEditor(signalHandler); }); + signalHandler.parentModelNode() + .view() + ->executeInTransaction("ConnectionsModelNodeActionGroup::" + "openConnectionsEditor", + [signalHandler]() { + ActionEditor::invokeEditor(signalHandler, + removeSignal); + }); }); activeSignalHandlerGroup->addAction(openEditorAction); @@ -747,7 +753,7 @@ public: newHandler.setSource( QString("console.log(\"%1.%2\")").arg(currentNode.id(), signalStr)); - ActionEditor::invokeEditor(newHandler, removeSignal); + ActionEditor::invokeEditor(newHandler, removeSignal, true); }); }); newSignal->addAction(openEditorAction); From 59b92b641740fff5ee3b0a292aaf800be43e2fa2 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 21 Oct 2022 14:32:19 +0200 Subject: [PATCH 06/97] Doc: Create separate topics for Qt Design Viewer in QC and QDS manuals The process in the two apps now differs too much for single-sourcing the docs to be helpful. Change-Id: I3aa60c9f2219d19843f5a4c635fc49c83548f13f Reviewed-by: Mats Honkamaa Reviewed-by: hjk --- .../creator-only/qt-design-viewer.qdoc | 39 ++++++++++ .../src/qtquick/qt-design-viewer.qdoc | 72 ------------------- .../src/overviews/qt-design-viewer.qdoc | 39 ++++++++++ 3 files changed, 78 insertions(+), 72 deletions(-) create mode 100644 doc/qtcreator/src/qtquick/creator-only/qt-design-viewer.qdoc delete mode 100644 doc/qtcreator/src/qtquick/qt-design-viewer.qdoc create mode 100644 doc/qtdesignstudio/src/overviews/qt-design-viewer.qdoc diff --git a/doc/qtcreator/src/qtquick/creator-only/qt-design-viewer.qdoc b/doc/qtcreator/src/qtquick/creator-only/qt-design-viewer.qdoc new file mode 100644 index 00000000000..a706997ed4b --- /dev/null +++ b/doc/qtcreator/src/qtquick/creator-only/qt-design-viewer.qdoc @@ -0,0 +1,39 @@ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \page qt-design-viewer.html + \previouspage creator-live-preview-devices.html + \nextpage creator-building-targets.html + + \title Previewing in Browsers + + \image qt-design-viewer.png + + \QDV is a QML viewer that runs in your web browser. This means that you can + run applications in most widely-used web browsers, such as Apple Safari, + Google Chrome, Microsoft Edge, and Mozilla Firefox, on the desktop and on + mobile devices. + + The startup and compilation time depend on your browser and configuration. + However, the actual performance of the application once started is + indistinguishable from the same application running on the desktop. + + You can run \l{Creating Qt Quick UI Projects}{Qt Quick UI projects}, which + have a .qmlproject file that define the main QML file and the import paths. + Compress the project folder into a ZIP file that you upload to \QDV. + + The loaded applications remain locally in your browser. No data is uploaded + into the cloud. + + To preview an application in a web browser: + + \list 1 + \li In the browser, open \l{http://qt-webassembly.io/designviewer/} + {\QDV}. + \li Drag and drop your application package to \QDV, or click the load + icon to browse for your file. + \endlist + + Your application is compiled and run on \QDV. +*/ diff --git a/doc/qtcreator/src/qtquick/qt-design-viewer.qdoc b/doc/qtcreator/src/qtquick/qt-design-viewer.qdoc deleted file mode 100644 index 818ad7ed5eb..00000000000 --- a/doc/qtcreator/src/qtquick/qt-design-viewer.qdoc +++ /dev/null @@ -1,72 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2019 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Design Studio documentation. -** -** 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 Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** -****************************************************************************/ - -/*! - \page qt-design-viewer.html - \if defined(qtdesignstudio) - \previouspage creator-live-preview-android.html - \nextpage studio-exporting-and-importing.html - \else - \previouspage creator-live-preview-devices.html - \nextpage creator-building-targets.html - \endif - - \title Previewing in Browsers - - \image qt-design-viewer.png - - \QDV is a QML viewer that runs in your web browser. This means that you can - run applications in most widely-used web browsers, such as Apple Safari, - Google Chrome, Microsoft Edge, and Mozilla Firefox, on the desktop and on - mobile devices. - - The startup and compilation time depend on your browser and configuration. - However, the actual performance of the application once started is - indistinguishable from the same application running on the desktop. - - \if defined(qtdesignstudio) - To create a resource file out of your project, select \uicontrol Build > - \uicontrol {Generate Resource File} in \QC. Then upload the package into - \QDV. - \else - You can run \l{Creating Qt Quick UI Projects}{Qt Quick UI projects}, which - have a .qmlproject file that define the main QML file and the import paths. - Compress the project folder into a ZIP file that you upload to \QDV. - \endif - - The loaded applications remain locally in your browser. No data is uploaded - into the cloud. - - To preview an application in a web browser: - - \list - \li In the browser, open \l{http://qt-webassembly.io/designviewer/} - {\QDV}. - \li Drag and drop your application package to \QDV, or click the load - icon to browse for your file. - \endlist - - Your application is compiled and run on \QDV. -*/ diff --git a/doc/qtdesignstudio/src/overviews/qt-design-viewer.qdoc b/doc/qtdesignstudio/src/overviews/qt-design-viewer.qdoc new file mode 100644 index 00000000000..5bb4e534f50 --- /dev/null +++ b/doc/qtdesignstudio/src/overviews/qt-design-viewer.qdoc @@ -0,0 +1,39 @@ +// Copyright (C) 2019 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \page qt-design-viewer.html + \previouspage creator-live-preview-android.html + \nextpage studio-exporting-and-importing.html + + \title Previewing in Browsers + + \image qt-design-viewer.png + + \QDV is a QML viewer that runs in your web browser. This means that you can + run applications in most widely-used web browsers, such as Apple Safari, + Google Chrome, Microsoft Edge, and Mozilla Firefox, on the desktop and on + mobile devices. + + The startup and compilation time depend on your browser and configuration. + However, the actual performance of the application once started is + indistinguishable from the same application running on the desktop. + + To create a resource file out of your project, select \uicontrol Build > + \uicontrol {Generate Resource File} in \QC. Then upload the package into + \QDV. + + The loaded applications remain locally in your browser. No data is uploaded + into the cloud. + + To preview an application in a web browser: + + \list 1 + \li In the browser, open \l{http://qt-webassembly.io/designviewer/} + {\QDV}. + \li Drag and drop your application package to \QDV, or click the load + icon to browse for your file. + \endlist + + Your application is compiled and run on \QDV. +*/ From 1ac0acbd7f3c35c2a052f5e306bd243b4e75e2f4 Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Wed, 19 Oct 2022 12:27:46 +0300 Subject: [PATCH 07/97] Doc: Update states view documentation There is a new states view, documentation need to be updated. Task-number: QDS-7892 Change-Id: I17ac7c192d4a8ddf0a10da6c8e399b126dabfebe Reviewed-by: Leena Miettinen --- doc/qtdesignstudio/images/extended-state.webp | Bin 0 -> 10666 bytes .../images/no-extended-state.webp | Bin 0 -> 12630 bytes .../images/qmldesigner-screen-design.png | Bin 51378 -> 25413 bytes .../images/qmldesigner-states.png | Bin 51844 -> 23625 bytes .../images/qmldesigner-transitions.png | Bin 13966 -> 10532 bytes .../images/states-view-menu.png | Bin 0 -> 94 bytes .../studio-design-mode-states-timeline.png | Bin 22609 -> 12629 bytes doc/qtdesignstudio/images/timeline-states.png | Bin 12233 -> 9294 bytes .../src/views/qtquick-states-view.qdoc | 45 +------------- .../src/views/qtquick-states.qdoc | 56 +++++++++++++----- 10 files changed, 42 insertions(+), 59 deletions(-) create mode 100644 doc/qtdesignstudio/images/extended-state.webp create mode 100644 doc/qtdesignstudio/images/no-extended-state.webp create mode 100644 doc/qtdesignstudio/images/states-view-menu.png diff --git a/doc/qtdesignstudio/images/extended-state.webp b/doc/qtdesignstudio/images/extended-state.webp new file mode 100644 index 0000000000000000000000000000000000000000..58eae1febfcc6395d4a4861b88b820ac7f2663be GIT binary patch literal 10666 zcmWIYbaPvz$-ofq>J$(bV4*NglYv1%k8v)eRsqWaM!UH_3w_j7RTe2v(X!Ye+?k&D z`_8Yks((Lpz90RQ}EHQ&*W!pO{>Bbg$fX!Cx=E*s`zv z=k)LLA8j|+*ZzC_yYlbyEBB@5)t^6Z_O1I*`+NC!`*&5z{+s{%d$+yt|9$@+zv2El z{qy;2^VQ}~sEYr!{`3Ave;f8T{A&Np|H014{`vp9ug0JA-^aiEzxNMAz1qLI|8D=j zzH$FY8~M7+|M|apKj8kU{_Xxx`}_aT*693?|KI<||5v`}{<-z5|KI#q{DA*w{Xow~MUad5?( z*W9%V^531xj{Ret^5VKIBi}ST(|uUjoXzhuepYXb+Wbd+bGKKTqObDWx=9B@*9etg z%y;jud?41{qggj|v->mAFLJLM7+tf!aHU@CxTg@T*W>n)X=X{1d56g9#e#brmc>f+ zK4LX`e*f&21BR>Qr$5m>yvgqA?Fph;jmZx@A6$O8tTC?TMttSrzh`d*s6AgVzuhvb z$L_`cJr9IaU!F}278hYNI-IzChRUS~;R>lqPcFYcyZWq1_qX|Rxp5gw;F?~n4^##1yNdIi7kT!*jHu!|zx&q3llL}kyEMbb_kT@AkogxOBeR^gJ-6H)1YRaT zj(-0@(yzDh0vh|#My82%U@O$}`S^JiCmnBK>bm{{#Vaq4h-ztaRfJ?^kD*h$Q4p^ZvGb-am&$Ev#wB zUuI={uC@F8k5$im`GVi;*7Q7|fB(b7eLiL)pBXnSpTXN|b0A0a8FQkqT9BNmlWRg? z;>SbG=eA4QrY?(0-t}AHVTaa}cUz5bUrk<`&(h@ichd974V+U{XMbEB`eWIb>K|;u zi(`uS37)N3E3`Z0gV2)X$8UaZ6yZ7TG4qnu+BfDmKONAX@x#GpzPDS#?bUTXjaM@)vpVW-&H;~PSEav8 ze=l1g_d;-nPQ?S4inyMfNvwUwhZ0&pJh*U=_o0(?&LP%$6DyXsW_(W!UDsfx-1S<> z-=<)P@3;4gjh%&|lYTEaKjDvdNY~3>XI_7dX;H0A6|$UKwSa_pjq0{5e@((gYU5aOIrt(eL1yib>N zx#O{&i>3)D_g0^&xZRoVRJpZs!2##pJ%!z0FX!&7WO#R==&qe)%C1V5BP`FO{eC1% z7Y2A8WcoiR_n`6VV~>9y%AHZ#%q%5iCw{YMf$Jmw?xaayGk0GvGE#ItUkuLD%dgK4 z?V8qd{?)ws!Z+S-erg@<$(Ok5mAC%Y+1*VITkNXzcg<#HHzTOq7EMf@KKn-GdzrwASsh*#b53s6;M#O%=DNiKr7|9G z+PT)Vrfhc-D%ViFWt+dhA*H1BAN%6EZAw=IkzCof9GubStkU}2h2+=c%t}c zkJb5_PhUUePXuK(_phu`-R{>`E;`ob`rCiK*}5-J<4dkRo|t?f?NrSDrQtT`^&Lsf3U(lNJ{y&7?J>HsGQH+ zbnW^Z=jSi=S1vjv-ToW?U7#uaAyjW)>aj0w4 z+~uCNl@AVhByT*rD(k=5dXpgiTeX#&eSeo87kOm%DDuL*oPXI0LAsxQ9X%LoBK&dn z+0`%S%zoIn5gM?8zxB;GY`$kD3@X)|p1r*C^`6Q@t_8k&rYuM2ty7)L&H7-m?0Pk5 zh^_Zd+^6L+b8F?IiFKF$UJlS>+#z@KYej1RIg%S6IZV!r(CW0&Vy@~)2WQNtq7#|soM9Y41H z{sE)8QhS-#wmj7239(-><*JHE_%{C1h()ZX-o7iRt0)9IF>Ox%vek51*m3g{7CQ|) ze?=~wSZA3OTfo5Zb^e#9Tzht>7BKG+P6&7?dd1kPN@~&!@5NaKybUv^K9e&RX}$4y zxoqBs4|jB2c5J)*@+_Z2-X{5e4W6hsS65lT@H}z(_4%D2R93HRvk6#xX;sP^(NfLL zihP0nyAPeZ^|-#Z(&8#_tLjamg)NE#7K-xoL+@8rwXT1X(d|>ZCPUs;PJwOfC;7bj zS{8*@KfK`K&fN3m{@^}BU?Pa$`#3Zws%2PFGzHh$j$Fk%& z-_FX+HZhZKRVy8*SqjntcUHT9G&rK<<+PXU&*Hknjm8G9nZ+%|>lZYMPSPl2U|_ti zenWl#0pHt<>-rCKY0tbh@9B5#uhk4oxMU9|%3TPbxu85wf%&(mm!GzBYm4L@*Z=MJ zPQ3If)hX}H<=<-OEV9;;@4)gbsbhSN0qs!>O%lEcEKf74{PpmtrvU>4W3A+MzO+3b zO%%7)eF#o&nP7I|j_JQF*0z?F=6Casu3tOj%HQ;qsG6|T4M%p!%v^JbF4R=%IG!g6qC3vv+O~(XgD>k$KpU zjMVZ_MxV%T21bszSK9f?EpLc-dmrIEP;IH0>=ZWXkR9jB{T&S~7dB1q;<^8nSLt6( zt-r`T$Goq*>!&j~`pty7}!Rfegkka`z9-6FtB4 zSL|QQ(>K_X=P5}CD|mE2)-IX5b3%Vvx}S%J%9TwH55C=LGx2A;;jz1ond$YkunwnM z*TNH5k1Q#uG>_ZGP+;K9yWWr?{dscR-`uyWO;*|O&NR{9>-kD`ZuOn5S+UH5%{ygl zKk95^@fY^jbn$0j`6-M|y0G0?#+d)CvRQoP28E@a4STO_%8;A%#W3jEGq?Zl3UBVd zKJ@LSE{kT*uV^Fh(pgI~o^7@@>%4NtN$+{SSn8<~FP}d;|AVhuEay*NqT6QoMd44a z*L}H75BOqV=pOuSkTNll$vN{D&#{OjkFRIhJ#@%=C;GalVfI7e^sOHA=O+L2;B56c zs=>ezlqEXjGn+uE_euuOlY2cTHalwUobpCkI5j1eU+%bJOoWHCyg~i4Y4*1ymCk30 zJdLn!OjP4&*8Gqj#Ad#Cuh0VqhO|8g80HkGR4?*aV)to%CWq}pv8%az7SC>~O>{F- z)SY-k=<8#p&uW4Hr>k}_>)1VzFW}!HpurM$EMdpiCp|6G^0d6d4ldYtrDe<3Ypyqp z>sXXd&syjqnRxg6 z!>Z~9+GWB)PF&6V*=2UrT{do1V*kmM`CQR^v7zLvZF)b=1_?x zd8;GS)*PC&YmR%sr%PMkn(tg>bM1b{hIc2d)?BSmxW7H*}a+oc`5dKTokKUsKd zzJ*!ks;XO7JAN(m7Rr-xixN3-L}Iq?)!4fA_2!XLB3AjLaaL3KPCqHUYkFqdCc()| zE?nRW6216r%hEF?FFaqYcy{^WzK`h(Ze*~_r^>xEuZ@>a`eo?#!qR=}F`K7d6FNV> zkQ25z@c#4jj$&z#{JWRm9WVtU!vZjo&1ab2P7Mw6K8 z=W*QQ+U8@E_+2+f#5XAXtZ`=HWW(!TpBgewU;DjEwEC*tvzb!mW_@$!HHG`^V!8di zQo_P|*5e-yt5^)48Q*l9rpx^D+b*{o@n?LTLqa85b}@^3*=(ylv)QP;&3uPp?uVUK zj{I+3Z}e|)&EqZzNL{n8WYzi7Dxobu1AC8seYkMnGM9yAA5|r`FDp8|tLyjNFzIWn zA6&7TDE@8vyqV!Oi~hLoih94`l+U7t;Sm$nt8aRl9LeE4UVZArBGm_VL7RRm-g%?9 zuKoA}zIVrTYo9Zfhj#zaIMP_;GE>&?Vt7%UxR=}AOtsGCXD?^HIQ(^v&$nGpCBK$G zo5AvS{(>Xh8o9R`O-#`jZe%u3&X_g?j~?uO{7b$7g+ zRVSTf(VwvBV8~@?oY2(IMa`Xw)bU|Jf70fUa_Z#V5bEO*pWeX+F!X<+A=?@1*Y9%(HH**80L5%RkMV zl~LovzXEuAB)Gc(T)Ly2LE)k1Vw^O8ZyFES%=BvrjNgEj7HoF zJaTQyfmv~?+kOPhS{3+vSy5@uv@^Sf*jG%BS|+TAxLUlUHyUAAU_fzi!p?`&7qe4n}e&$pFba`?-iiwdiPq!IlYY+ zmTfzEHl4SwcLLih?p>P#)_yRTU23IRf8&Hw&(baIA~lag*-p*hUS^%SZ33sNiV2_W zmwUI~`Zrp?UY}O1BqX{0NLTTiou_pE+$<=Wa_Zb_4SvSEwSI@Xzm)#FF@2r)qxV2jKBnFiim201-zjC+(to?AV?p8w|Ve}Oa7JgTe;>nv=#*gp!Y ze?6xx9+|m}SM_bp-(LdD<6fGHe#*UMs(z=qJwr73;F2q%A)kKk?DNofjrlKf$@7%B z-NC@g?S5xxwn+Bsc57c9cCBy4?_}8|J=XJU( zJ|%M*p4pJEVSb>b`NgBNTi#AOaJKu}DL#fBwijnTdLgH0yqU{R@Xu zHykgjEL>_@yr18=@!`^WOd7Lyhb*Z+YOLYQ@lDLuyKL@-`n`W&FTE%?OY>mUNp?@4f$a5&M_E|D`YAu-vJC{ox7o#k1lW z>u20qyR+x!-~ODrAyHbF+4oNE7mGd=Dx7h*Z~rg(S2d?rCHbb#|GK6mGlq!+r7BC` zz3JS#l~4b%zXNt`i&0V&Xm1XLx zm-Vh3PRq~TzWb-i==-0^ZJW0Wuaw+Ye`;-8dF>R>wX-6B+FjI=d+(RXD;CGIH2pn8 zYsN}W<)?cNtBW3US(z`PQR}VJWch?G_TcRYFOEi@ZIxo`XZtpx;0ynyrsR-327NiZ zmYZ*X^xRY0;>C7wd0|sywBm!~7Zdwy`~sQ&C!g05zx+6B>(2ST{wy1PTt!(|ymHZH zO53{olhkzH5)QYO-=iL$pCf;%*Z5n~{w1$`4Dw%EUTNR-jKe$c#(JBYeNwZy&AjcI zbym;%6I?C*{?c`ynN~M{KD>9p!}7(Y+j^W zz$P>Q!ugYj0{H$%p82_w%{@}@ytN3A-sVeBG)^4Tn$+a|JJ(~6ThER_dBqn@^NaF6 ztog+D)5q)foWc{GIfBmH_Dro+m@9AjAh{=D^>IJvHq$j4Q6ZDKCvkf$ou3u4?Zq1n z;gt8f^LQ_}=fxLHzvX^rhwh4>EbsL9E_a!G`+SX6kkpmeFPhZCisYENI$Uq&Y>Lf@P57^xyW`0?ZbT1v(tkcS6DL? z7Hj-}WaVk~oJYcK^}biT4tlIQdnqS^=MZyHZA0m&W7C3SI)d9&-y9T}vn%P*tEKP$ z6|GRZU3+Cggy(txYx{Q{e6&sR<(scxy*($$2`uX0;9GdtEdA-3#UEa;{?RNg-M^zG z)R=w8iVeqJp0}5=)LXgzYQaG^W+rKM zt?WF0WpRkC*~Ji{vrmhgCVrIoJ0tftzYn9McPignUe&c7yRSdF_Rwd>hm#L%kE|{~ z8o?v;wCDc^`%@-T*=y6?SNfUmsHugAUgLOp?e4pB(&UQM;#{BW! ztCKXf!b>7}WmrC(-uU|N?b-2ZFQOgnL)?TzPJfa);?o$C|7N0YE33ZTF4NU=(TDzR zF->3jao5$`2W7*SoqnFn)Md9c?!|k#!#DMkrj|9kOzU)1QFOdFp>yk0Z`*~}pKec= zo+uHtEGO1N+{`oJ_)clxeQUbARTcKdsNG0O$>Up@|NDJ~Rry=DUx_JC{F9xYA5+qc zy(shlZtdl*XSZ!(`IWF*_C=b*pFLk()K4~eHZGm^t2dxKvhvX}XQ9Mf2e0sMInkh~ z!F;pdY*ua2(C zoKxp+@;fV2zKcCepUd($>((3o3s)@)|1ZI28WwSjNj>^Lcc7wm!W*04%51iBDcd|b z9Qm`aTJya={^iwY&+r_}*$*$*e7<>W|JVKT4R&(wfgXj~M zH&UEpFPDV~^EGOPj2ul%f~K%{SvbLzAZmn zdgQ#?$Nyp9GoGAw`*e@j(jvR;L|aGh{t)kO>&p3EZ;l+jlf9)bv9o)<`&R|~Nx2_| z{+xU%wDrcLzaGlCIbR z=Tw*f{8wb%V*mDUcg^o`sxN;%sWJM?&8~vy$MuvUir1#>P3fzk8Qew&kw>l(cpA1pn#{?}Jv%5DTo1s)-h{^b9VR zxvcxsO+V6n;-Rln=RH=&Zt3!}2<(~W{7kHK!NY`2-pZ@g4m}N5_SUL%T+5Pi;NQLd z8~%%~6>H$$cW0OITNbAh)4LY^X)2{(-K^9v?7L#`+$L~2OGN%i)?J=efug%@TE8z( zTl4Y7|I4fXy;avWzuIxDGuQw1*z1`jgg*6F*KRWqpQkrbUn$sD^m5d~ z{4En*)|ef;>pthDL}%vP=T|eNYjkU($|IbbH*&5AJJip5$ zZoU6u^`g&Jo4?%=HT`355_hY4t3b+nZk^TY$3%<{y*wBeb3$A-?dy%cyRU6i*{{ET zEXvX^GL>I)w~(EwVUqov=p^PcI+e5cK|&@a_2f53F9Y7aS;F&$-ickD9~E{?B%1Uyg=s_x`y=K~-&?y6~Lu zPnhSi36|pFmLG#2rbUT}u-uzdlHK%s-Q(#UQ*~!7*u$n; zWG4A>N%Yost!J6GFO_+GcWGaj5Wc___28nxx99(kZ(M)+%bXY+gLgOoDSeGNdhb*D zjKtODm$y$=y%OTWH{s4X<-p3epb5K@jPGlRIrB}D53sDC%)Yqy+ceedno2Xy5Z%_}9D@FW%l1^*KDXe)oaW-P@1Ua0DA)kofkrH1eLGpvvQ4fj!EC z<=1*91eJ7pT5WhEy0fru@~=}~v-dA(Sf0|Gq-g!{+#TCl2hW@>u)Td-_{$mF{=ezo z8x25S^<}nO%LM#irXSK|xV%p6-y!zhGbT;zsAF)L>LSIkDSb=A z-B-p_VwPPgdHb;V-8O{_zakA6{FyF=( zm;YEkQCLmsmC748i5BV4dM~eCu3h%q_gnlTWw!2H4UKH-`yMcgOzAV_aJUxE|22l| zS~izo|M6d|pFXI&HF=7kaZ~LoOsjZ8xo(-uT7AOs&~}azI9@Yj%Ul4>E_=)R&22`w+z3) z8vOKb+0&ln&#U}g%;pxKK7Z=AsGnA`aB##YX4wL{iSut=n6jqbH`76WlGK97a*tl< zq&?XG;|A}URfJ8HS<>-3~2*Z;B3ElEts`EqyL?(63IHrvHF zobn8foFY)>Zsv2yY=)U_Uy@3Z}-VOerl<9 zV2Zn;+wQ6lXC5t)ndPpNS=ak*r}m|Jg$rVfY-}DBmNf^Ivj0;yy0mHWoie|p3$>$4 zO}fq~im_Y0IA$-n|8(}D;#&FtW#1W?zs==Q^G`3?#{S1y@J`?S-%2&iUeA`@pM3DA z_kMlepD9Ii&N#_y{eQpq)pCB*zMj%WReQsGRRvz2zL4m1|6%vcjRrek&8V@p{SnM> z^7-M*_g75X|E&m|ax-O_uTw(xof|4AA7`gs5*2!yE%2(gC{;dSPZ_J2n%NN}aURD@ z&HF6ApG{c0`MuZ6f|nLQu3Y@}Y~9{{F#?~SrEPp^Zgn&8K@!)@ck)UNZ^hm@{7iUl zTfn5X?%9zS87|6?r5YMJmKmnFKKB;sY>X2Q6xf)1q&;Hs`W2f$@1DRp@#Q4JlCqU~ zU3?n0g)G)fu2_9<{jhm{TMR?)`5UYePiGo$xhMKt=WSu?{O6NbZQm0#r@MIH1NT8<$hmgrzmuZ zzP$CD=lJeP$G;1=9p6*8Crv|{b=Q}l%(Jg4SErkvllDwm{@(v+<-OYw9AYiWzvs!IZAvw5WQ87 zJxA=_lxmX>hS^3ovFj=t(uzfUxC}U^zq%+`$We2=iJ>QsU-7-7$Ij=HN9E5}E80an zWv$#ST*;)`sK;E%&M--2_Pu8>IBmGk-*VqGb?vYEV%u$B{TMeTYjC6=ZFNfKKAB#r z_e*Za1e05WXQuCVP(8hAYIcrN2utm~D-Q4Zr`?~?C|e)Xax&g>SO1f$2f2-t-u!Uc zswrWa6)wwjdTHv3Szd3Sf0^T;+n2JpZsGNLRd*-lzB2vpwJDQ}ooD@&?iAjOZKC1# zJr6ukt)0!eTTL-W|Jjo6C3{c(^mY6m9&)=K`+f|Omfv`B-~CXfPqUY5m06|xN~fi?b)MM&W7g{O z{3NSC*Ox}z`@xrcw=O^0JUV2{&)vBjuK4;bGrO|0xalCbh2`o8zr1UuufKS>%jMyp zzAyK6WJ<49_RW2|jyw0@ee3mnZxx=bwhD~+?eXP3%bFjJQy3(YL;E~0sB14iVIb;W zrz#QfI`n=m_lKGpBxc^UWh4U*p;%4eAvmV|#wRA%gnvgy=sVtVo{ zknO_8yqT}{Iox6t80O2(6%sXl`HF59Bd%hcR6Rb1oqL-a`d@;l#VCtav_IsIh!>qqMiwg~PnWJ-N(^U2)!;-_Y3qF*K_CYJ%vW5B$~t zcdVJq#+TJEqOiNvZOQql*K%9(8-KQ~d!6}fq3u7Z2?q=edS=gi6xitd+mtOVIiu1k zF!I3H@B5N#J}+v>U9i;E;_hxu9+Anuo0b|Fv7g&+$$q+(cN#;;**mxYn>Qs_uc^;l zTC44UTATUv&Ygwpp6G_X$Yv~B!nx$INtSok!b-{8KLZ0#FSOXFE++LoE_}y-mu&}S zzOGv?b9KW?vn>gxI~fdK=ltip`i#x@s^}Sq@7fqMI^#w-b%NtvK zRjn2-aC-itimfX1KzYEILsK@q7(4OtI5Z#P4mQvbQQP1Cs!Y*1UbLSEP%ICoQ^FaL=r%$mqqM-v?(_ zUc4A3A#v&GC1Yia75DeE+&uZ$$z=Nf!{-#PB?adlvR{~AGB4J!efRNsr7Mp;k6P-d zCEq=Hm&qMNeOYGlr?olOQLh|K^tWp{AA23G$W`a8_xHo^U&W=91P(Yk*?27oWj0_s y5LD0Uqruw6eM>3lNo8O=bA_&ur)2*hhJ7!WFvN$jx=nT7=5y^@$gd9!3=9BDM(*PP literal 0 HcmV?d00001 diff --git a/doc/qtdesignstudio/images/no-extended-state.webp b/doc/qtdesignstudio/images/no-extended-state.webp new file mode 100644 index 0000000000000000000000000000000000000000..41fe322f0db4328284d2c4c50dc0b07fc9bc7e90 GIT binary patch literal 12630 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Ð#6QxBeI&fF0&;b7X4sp~jY?9T0p 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�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 JS?83{1OSQi*3_h7 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 diff --git a/doc/qtdesignstudio/images/qmldesigner-states.png b/doc/qtdesignstudio/images/qmldesigner-states.png index 2b6e2794e134727050bd86dcb4ab86372e2cdc3e..552c644e6477ddd0ded92633384a75b2a9f08165 100644 GIT binary patch literal 23625 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 literal 51844 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 literal 13966 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 SDr8__VDNPHb6Mw<&;$SrXA(~U diff --git a/doc/qtdesignstudio/images/states-view-menu.png b/doc/qtdesignstudio/images/states-view-menu.png new file mode 100644 index 0000000000000000000000000000000000000000..6f93774904894f022cfca2c010f6f378540d23c5 GIT binary patch literal 94 zcmeAS@N?(olHy`uVBq!ia0y~yU=U?sU=U(tW?*3GyThK#z`(#3;1l9{@9teSH8oag zrR@w148oo+jv*Y^lN%a;{g;0r!Qmmw&hYr9=zXEDm!B{&Ffe$!`njxgN@xNA$wC>4 literal 0 HcmV?d00001 diff --git a/doc/qtdesignstudio/images/studio-design-mode-states-timeline.png b/doc/qtdesignstudio/images/studio-design-mode-states-timeline.png index 2579687674e8c2b3e8fd6bdce5f7fb0855ffda0f..3b2b8b173ac05fdfbcb19817faecec8a3b2c111c 100644 GIT binary patch literal 12629 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 Y8K-wg-khz+z`(%Z>FVdQ&MBb@0C{6`^#A|> literal 22609 zcmeAS@N?(olHy`uVBq!ia0y~yU|PVyz&L?}je&uoaNVV^3=9zxo-U3d6}R5*EuSJ9 zx^Mgcb>IKrpY{FTPUCa3>ys5q-Yru$G4U*FQ&Uz@TGXM?)X;IEAthi^$_7WL$*Sop z>V|!ZXUpi*2V5FyIPmE{Fi<3GnAc zn>Ijz!U7HrZYW^tf(vgz68CP^xnJ{VJJ7|+|1x@AD%g9|vNrEAt=)BQYu3{4*xh2i zda)%t)BXQ`uKzF2s5`6SpSQeR-12+2R;$C;zniu3X_tDe{L87Q^Iy*nkos|V{+HL6 z^pcIGO#tE1v%O{{7zl`+p^l%ZFDK?$*n)uei-t`}6SfS(X(W(&W$I zJ$yaBZe6*4&V>id7JvQqoi%*P~I=_rd?|{QnJA_icT}@Bi4Vxk9XL?fTjEf-C)szr9{Rf6q#Fx4R4N zX72s+qtDpNE`LSd@0Vw@EK0W7{rII{Wmnx+#VfJk;Nf|fe#h6YTwDAue7fFTlca-s z{*v5ree2~`S8uw%=h<#$|FX-m{dSAW%>VT#Nq@iErak{T=ZnkbeAgE3egE{|&;IKs z8_UyW|6l(8>wfUfUAw z{p`JVw{&;i*Uz`IOutI*{dGspS9leUF!yYeP1kMyDqjCml6F0)cklM@TU%$Z z)~Ie!PjPemAbKh{q;pSG^5dY0ll zZ%@Q@yQ18O_8IRt2}+SRXTOtK6sm5|8&SNr;opbv+fAxpD9ru+ zCAQbkD{Q`DuxYA?^phyxgUZZ^2(@>+8R| z_vN0|=dI%3`S~&<-aGF460TPODKB0rEO>r<+f{b$uot)2@4IwefB%~GaaEq;R^{K0 z3Nz|D1Ofx4CPWH2L4m?`OlKet+P2`~ORM)ZOY0^LBojuD~d}XzKCe>fnDr zm!93V{k+iMkF!rp3EU6dyzTA9f6m9hygDBL;=KHxMQ^!}XI)s~`Rl9r`;4gDg1f%_ zo^D!qLuT*e-5>L(UM=dF_xp7Esdweuug(2?>GwO~v)Sd#x9zLj+WwsX|3Aany8Yg{ zzwa%#J-#h7=6ht_=3mE;i)B^(PyP35ySd-R!;iPUdi3(El>PUf|99J~pJz|G&i>`@ zeYuOyvFWeA^7my1Y}VWv^#AYjD4TVg`~Ea?&jF>=)}>Y)FP7%rEm@W5T)U-kvHjgk zH*e>EpZ#PdqwdOve@}yD@9&DzE-KnmbZf7aO>S@8-al*DQcJ?W?c83Pa#EtSHeq2= zm`~9AGbgLw$IE9VxwUO7n|pP-{QOJJxmH@)Zy9ARioD+c`KG+LP_?+RM~@8SDOrd^BD*}ux| zJaM~ht{RWbg0IW>nTcL$vbM_l@FczD!2!qE%Gb(!|G$cSduHD1f6VW$Kl~nl

*d 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 TT2Ol-4J6^|>gTe~DWM4f(qUV! diff --git a/doc/qtdesignstudio/images/timeline-states.png b/doc/qtdesignstudio/images/timeline-states.png index a1dc73e51eba60394b6aeff7228a0bbcbfb5f642..0ef1f7da959bbe0159e4841e70e6e6ad2f9143da 100644 GIT binary patch literal 9294 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 XOlZB89sZ4hfq}u()z4*}Q$iB}cBuOR literal 12233 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 - \uicontrol {Reset Default}. + To set a state to the default state, select \uicontrol Default. \section1 Applying States - To determine when a state should be applied, select \uicontrol Actions > - \uicontrol {Set when Condition}. In \uicontrol {Binding Editor}, specify - a \l [QtQuick]{State::when}{when} property for the state. Set the value of - the property to a boolean expression that evaluates to \c true when you want - the state to be applied. + To determine when a state is applied, select \inlineimage icons/edit.png + in the \uicontrol {When Condition} field. In \uicontrol {Binding Editor}, + specify a \l [QtQuick]{State::when}{when} property for the state. Set the + value of the property to a boolean expression that evaluates to \c true when + you want the state to be applied. This enables you to evaluate the truthfulness of several components' properties and move the UI to the state in which these conditions apply. @@ -192,10 +188,40 @@ \li Create additional states for each view and set the visibility or opacity of the components in the view. \li To determine which state is applied when the application starts, - select \uicontrol Actions > \uicontrol {Set as Default}. + select \uicontrol Default. \endlist \if defined(qtcreator) \include qtquick-states-scxml.qdocinc scxml state machines \endif + + \section1 State Groups + + With state groups, you can change the state of certain components + independently of other components and their states in the same view. + + Each state group has its own property changes and transitions. + + By default, there is one root state group. + + \section1 Extending States + + When a state extends another state, it inherits all the changes of that + state. The state being extended is treated as the base state in regards to + the changes specified by the extending state. + + Using extended states can make the user interface and your QML code + cleaner. + + Below is an example where the only change between \e State1 and \e State2 + is the brightness of \e directionalLight. + + Here, extended states are not used: + + \image no-extended-state.webp + + Here, \e State2 is extended from \e State1: + + \image extended-state.webp + */ From 920389a660a0ed8210d18d47906c8b67a14a406d Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 24 Oct 2022 07:38:18 +0200 Subject: [PATCH 08/97] McuSupport: Fix qbs build Change-Id: I7efa2aedd022c510ab03718e69eabb11b9e15b16 Reviewed-by: Christian Kandeler --- src/plugins/mcusupport/mcusupport.qbs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/mcusupport/mcusupport.qbs b/src/plugins/mcusupport/mcusupport.qbs index 5f3135214af..6ddccd82f52 100644 --- a/src/plugins/mcusupport/mcusupport.qbs +++ b/src/plugins/mcusupport/mcusupport.qbs @@ -7,6 +7,7 @@ QtcPlugin { Depends { name: "Qt.widgets" } Depends { name: "Qt.testlib"; condition: qtc.testsEnabled } Depends { name: "Utils" } + Depends { name: "app_version_header" } Depends { name: "Core" } Depends { name: "BareMetal" } From ccb03494537f66862188d5ef7c256c0625edabfe Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 24 Oct 2022 14:18:48 +0300 Subject: [PATCH 09/97] QmlDesigner: Don't create module import if later version exists When creating nodes via 3D view context menu, later versions of imported modules are also accepted rather than just the exact required version specified in the ItemLibraryEntry. This fixes the issue of adding duplicate import statements for the same module with different versions. Change-Id: Id8437a1817346839488bea7bf89529cc63f4849f Reviewed-by: Mahmoud Badri --- src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index 05189a53ccc..0710fde19c0 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -249,7 +249,7 @@ void Edit3DWidget::onCreateAction() QString::number(entry.majorVersion()) + QLatin1Char('.') + QString::number(entry.minorVersion())); - if (!m_view->model()->hasImport(import)) + if (!m_view->model()->hasImport(import, true, true)) m_view->model()->changeImports({import}, {}); int activeScene = m_view->rootModelNode().auxiliaryData("active3dScene@Internal").toInt(); From 0e7bb804084e2c32a5d4074ccc2deceb0ad07f80 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 25 Oct 2022 11:04:16 +0200 Subject: [PATCH 10/97] QmlDesigner: Use QML_COMPAT_RESOLVE_URLS_ON_ASSIGNMENT At least for now this is the better default for QDS. See also for example the SafeRenderer items. Task-number: QDS-4812 Change-Id: I03d614ec52c1e5ab11576bbfdaa3bad0d72f0fbf Reviewed-by: Teemu Holappa --- .../studio_templates/projects/common/app.qmlproject.tpl | 1 + .../studio_templates/projects/common/app_environment.h.tpl | 1 + 2 files changed, 2 insertions(+) diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl index 206d8272da6..4031ba86a57 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl @@ -71,6 +71,7 @@ Project { Environment { QT_QUICK_CONTROLS_CONF: "qtquickcontrols2.conf" QT_AUTO_SCREEN_SCALE_FACTOR: "1" + QML_COMPAT_RESOLVE_URLS_ON_ASSIGNMENT: "1" @if %{IsQt6Project} @else QMLSCENE_CORE_PROFILE: "true" // Required for macOS, but can create issues on embedded Linux diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/common/app_environment.h.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/common/app_environment.h.tpl index e25a370c049..e1f7ec2e23d 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/common/app_environment.h.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/common/app_environment.h.tpl @@ -15,4 +15,5 @@ void set_qt_environment() qputenv("QT_ENABLE_HIGHDPI_SCALING", "0"); qputenv("QT_LOGGING_RULES", "qt.qml.connections=false"); qputenv("QT_QUICK_CONTROLS_CONF", ":/qtquickcontrols2.conf"); + qputenv("QML_COMPAT_RESOLVE_URLS_ON_ASSIGNMENT", "1"); } From f2f6f6e6cc005d33e3a0e9367e2e3fac735fbef6 Mon Sep 17 00:00:00 2001 From: Ali Kianian Date: Thu, 20 Oct 2022 17:06:58 +0300 Subject: [PATCH 11/97] Reload material property groups when model changes The property groups would be unloaded when a model is detached, and it would be loaded when the model is attached. The problem was that the unload function was missing for the MaterialBrowserModel. Task-number: QDS-7515 Change-Id: I89064a78552c10228c0b18e42c1e0df4a92fb4a6 Reviewed-by: Miikka Heikkinen Reviewed-by: Mahmoud Badri --- .../materialbrowser/materialbrowsermodel.cpp | 38 ++++++++++++------- .../materialbrowser/materialbrowsermodel.h | 1 + .../materialbrowser/materialbrowserview.cpp | 5 +++ 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp index 86f8f7d1948..10d596abbd7 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp @@ -105,22 +105,19 @@ bool MaterialBrowserModel::loadPropertyGroups(const QString &path) { bool ok = true; - if (m_propertyGroupsObj.isEmpty()) { - QFile matPropsFile(path); + QFile matPropsFile(path); + if (!matPropsFile.open(QIODevice::ReadOnly)) { + qWarning("Couldn't open propertyGroups.json"); + ok = false; + } - if (!matPropsFile.open(QIODevice::ReadOnly)) { - qWarning("Couldn't open propertyGroups.json"); + if (ok) { + QJsonDocument matPropsJsonDoc = QJsonDocument::fromJson(matPropsFile.readAll()); + if (matPropsJsonDoc.isNull()) { + qWarning("Invalid propertyGroups.json file"); ok = false; - } - - if (ok) { - QJsonDocument matPropsJsonDoc = QJsonDocument::fromJson(matPropsFile.readAll()); - if (matPropsJsonDoc.isNull()) { - qWarning("Invalid propertyGroups.json file"); - ok = false; - } else { - m_propertyGroupsObj = matPropsJsonDoc.object(); - } + } else { + m_propertyGroupsObj = matPropsJsonDoc.object(); } } @@ -134,12 +131,25 @@ bool MaterialBrowserModel::loadPropertyGroups(const QString &path) QStringList customMatSections = m_propertyGroupsObj.value("CustomMaterial").toObject().keys(); if (customMatSections.size() > 1) // as of now custom material has only 1 section, so we don't add it m_customMaterialSections.append(customMatSections); + } else { + m_propertyGroupsObj = {}; } emit materialSectionsChanged(); return ok; } +void MaterialBrowserModel::unloadPropertyGroups() +{ + if (!m_propertyGroupsObj.isEmpty()) { + m_propertyGroupsObj = {}; + m_defaultMaterialSections.clear(); + m_principledMaterialSections.clear(); + m_customMaterialSections.clear(); + emit materialSectionsChanged(); + } +} + QHash MaterialBrowserModel::roleNames() const { static const QHash roles { diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h index 3cd8b65a411..039d40921bb 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h @@ -80,6 +80,7 @@ public: int materialIndex(const ModelNode &material) const; ModelNode materialAt(int idx) const; bool loadPropertyGroups(const QString &path); + void unloadPropertyGroups(); void resetModel(); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 979ae3a7ae1..41055988fdf 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -336,6 +336,11 @@ void MaterialBrowserView::modelAboutToBeDetached(Model *model) { m_widget->materialBrowserModel()->setMaterials({}, m_hasQuick3DImport); + if (m_propertyGroupsLoaded) { + m_propertyGroupsLoaded = false; + m_widget->materialBrowserModel()->unloadPropertyGroups(); + } + AbstractView::modelAboutToBeDetached(model); } From da11533a6d97980e36e4e01e418faa4da3254ec1 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 25 Oct 2022 11:25:18 +0200 Subject: [PATCH 12/97] QmlDesigner: Add space to ItemLibraryEntry name for ColorAnimation Task-number: QDS-8079 Change-Id: I09057c58ca17cae22bbea7d5b67eba0ca48e9cf2 Reviewed-by: Miikka Heikkinen --- src/plugins/qmldesigner/qtquickplugin/quick.metainfo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo index c45db41b8d2..6420b398651 100644 --- a/src/plugins/qmldesigner/qtquickplugin/quick.metainfo +++ b/src/plugins/qmldesigner/qtquickplugin/quick.metainfo @@ -459,7 +459,7 @@ MetaInfo { } ItemLibraryEntry { - name: "ColorAnimation" + name: "Color Animation" category: "d.Qt Quick - Animation" libraryIcon: ":/qtquickplugin/images/item-icon.png" version: "2.0" From 09b17bcb4ce8753e985673da1d51298645fd93c6 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 25 Oct 2022 10:04:36 +0200 Subject: [PATCH 13/97] QmlDesigner: Remove [[noreturn]] The throw is conditional now. Change-Id: I058fa8c665714cd9375ee4414a1280e85b6ca270 Reviewed-by: Marcus Tillmanns Reviewed-by: Qt CI Bot Reviewed-by: Thomas Hartmann --- src/plugins/qmldesigner/designercore/model/model_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h index e0d22621bb0..629a97a58f0 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/designercore/model/model_p.h @@ -210,7 +210,7 @@ public: void setAuxiliaryData(const InternalNodePointer &node, const PropertyName &name, const QVariant &data); void removeAuxiliaryData(const InternalNodePointer &node, const PropertyName &name); - [[noreturn]] void resetModelByRewriter(const QString &description); + void resetModelByRewriter(const QString &description); // Imports: const QList &imports() const { return m_imports; } From 552831ead4eb8f9c8025fe1d0bc8352c4319391d Mon Sep 17 00:00:00 2001 From: Mats Honkamaa Date: Sun, 23 Oct 2022 19:58:43 +0300 Subject: [PATCH 14/97] Doc: Update documentation on how to share apps online Provide basic information and instructions about sharing applications online Task-number: QDS-7155 Change-Id: I69632f370a452c1b9cc03ebac260f0382a89449b Reviewed-by: Leena Miettinen --- .../src/qtquick/qtquick-live-preview.qdoc | 9 ++++- .../images/qt-design-viewer.webp | Bin 0 -> 28212 bytes .../images/share-online-manage.webp | Bin 0 -> 11756 bytes doc/qtdesignstudio/images/share-online.webp | Bin 0 -> 6472 bytes .../src/overviews/qt-design-viewer.qdoc | 36 ++++++++++-------- .../src/qtdesignstudio-toc.qdoc | 2 +- 6 files changed, 28 insertions(+), 19 deletions(-) create mode 100644 doc/qtdesignstudio/images/qt-design-viewer.webp create mode 100644 doc/qtdesignstudio/images/share-online-manage.webp create mode 100644 doc/qtdesignstudio/images/share-online.webp diff --git a/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc b/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc index cf4abeb59cd..0003655005e 100644 --- a/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc @@ -79,10 +79,15 @@ You can preview Android applications live using an Android emulator. - \endif + \li \l{Sharing Applications Online} + + You can share applications online and view them in a web browser. + + \else \li \l{Previewing in Browsers} - You can open \l{https://qt-webassembly.io/designviewer/}{\QDV} + You can open \l{https://designviewer.qt.io/}{\QDV} in a browser and load applications to it. + \endif \endlist */ diff --git a/doc/qtdesignstudio/images/qt-design-viewer.webp b/doc/qtdesignstudio/images/qt-design-viewer.webp new file mode 100644 index 0000000000000000000000000000000000000000..47c80e4d6adae35cc8b39ec5d96ecdbb4c84c9b6 GIT binary patch literal 28212 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 XdF8x9rew-9LAF%GT00%}Nem1CQ=kUM literal 0 HcmV?d00001 diff --git a/doc/qtdesignstudio/images/share-online-manage.webp b/doc/qtdesignstudio/images/share-online-manage.webp new file mode 100644 index 0000000000000000000000000000000000000000..3ddb938dfcb8ef5b9db481dee59b5b0ba1b2bf09 GIT binary patch literal 11756 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 literal 0 HcmV?d00001 diff --git a/doc/qtdesignstudio/images/share-online.webp b/doc/qtdesignstudio/images/share-online.webp new file mode 100644 index 0000000000000000000000000000000000000000..c91661f18cbbd2aeae884ccaf05c6bc0e8bf8b42 GIT binary patch literal 6472 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 - \uicontrol {Generate Resource File} in \QC. Then upload the package into - \QDV. - The loaded applications remain locally in your browser. No data is uploaded into the cloud. - To preview an application in a web browser: + \section1 Sharing your Application Online + + To share your \QDS application online: \list 1 - \li In the browser, open \l{http://qt-webassembly.io/designviewer/} - {\QDV}. - \li Drag and drop your application package to \QDV, or click the load - icon to browse for your file. + \li Open the application in \QDS. + \li Select \uicontrol File > \uicontrol {Share Application Online}. + \li In the dialog, select \uicontrol Share. + \image share-online.webp \endlist - Your application is compiled and run on \QDV. + In the dialog, you can now open the application in a web + browser, copy the link to share with others, or manage your shared + applications. + + \image share-online-manage.webp */ diff --git a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc index 11ff34f21a4..edd27446d55 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc @@ -153,7 +153,7 @@ \li \l{Previewing on Desktop} \li \l{Previewing on Devices} \li \l{Previewing Android Applications} - \li \l{Previewing in Browsers} + \li \l{Sharing Applications Online} \endlist \li \l {Asset Creation with Other Tools} \list From f8a272e07686b0d84ffeed3702f95c709c098efe Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 25 Oct 2022 16:40:19 +0200 Subject: [PATCH 15/97] QmlDesigner: Bump QDS version in .qmlproject Change-Id: I39cefcd5c1a16fd56eb05c485eeb11471683aeec Reviewed-by: Tim Jenssen --- .../studio_templates/projects/common/app.qmlproject.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl b/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl index 4031ba86a57..2e933c76136 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl +++ b/share/qtcreator/qmldesigner/studio_templates/projects/common/app.qmlproject.tpl @@ -100,7 +100,7 @@ Project { /* Required for deployment */ targetDirectory: "/opt/%{ProjectName}" - qdsVersion: "3.7" + qdsVersion: "3.8" quickVersion: "%{QtQuickVersion}" From 162635cbe8865fab1e8150ff815f6ce8ab71e905 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 25 Oct 2022 16:40:45 +0200 Subject: [PATCH 16/97] QmlDesigner: Allow QtQuick 6.4 Change-Id: Icb7f3be479f3e2db6b500fec7c209cb429ff4f22 Reviewed-by: Tim Jenssen --- .../qmldesigner/designercore/model/texttomodelmerger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 1a0d3ae9c33..8e9b6844307 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -92,7 +92,7 @@ QStringList supportedVersionsList() { static const QStringList list = {"2.0", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6", "2.7", "2.8", "2.9", "2.10", "2.11", "2.12", "2.13", - "2.14", "2.15", "6.0", "6.1", "6.2", "6.3"}; + "2.14", "2.15", "6.0", "6.1", "6.2", "6.3", "6.4"}; return list; } From 8da35bac0f30ec28ba6c4672beb7f9c48d1d4ac5 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 25 Oct 2022 15:28:43 +0300 Subject: [PATCH 17/97] QmlDesigner: Add support for SpecularGlossyMaterial Task-number: QDS-8087 Change-Id: Ic5cdca5d61d5f4ad11f63f3f5a59907798cde763 Reviewed-by: Mahmoud Badri Reviewed-by: Reviewed-by: Qt CI Bot --- .../MaterialBrowserContextMenu.qml | 4 ++++ .../materialbrowser/materialbrowsermodel.cpp | 3 +++ .../materialbrowser/materialbrowsermodel.h | 2 ++ .../materialeditor/materialeditorview.cpp | 20 ++++++++++++++----- .../choosefrompropertylistdialog.cpp | 4 +++- .../navigator/navigatortreemodel.cpp | 3 ++- 6 files changed, 29 insertions(+), 7 deletions(-) diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserContextMenu.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserContextMenu.qml index d1e9f1ab1f4..796bcab6ebd 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserContextMenu.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowserContextMenu.qml @@ -80,6 +80,10 @@ StudioControls.Menu { root.matSectionsModel = root.matSectionsModel.concat(materialBrowserModel.principledMaterialSections); break; + case "SpecularGlossyMaterial": + root.matSectionsModel = root.matSectionsModel.concat(materialBrowserModel.specularGlossyMaterialSections); + break; + case "CustomMaterial": root.matSectionsModel = root.matSectionsModel.concat(materialBrowserModel.customMaterialSections); break; diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp index 10d596abbd7..be855dc1a53 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.cpp @@ -123,10 +123,12 @@ bool MaterialBrowserModel::loadPropertyGroups(const QString &path) m_defaultMaterialSections.clear(); m_principledMaterialSections.clear(); + m_specularGlossyMaterialSections.clear(); m_customMaterialSections.clear(); if (ok) { m_defaultMaterialSections.append(m_propertyGroupsObj.value("DefaultMaterial").toObject().keys()); m_principledMaterialSections.append(m_propertyGroupsObj.value("PrincipledMaterial").toObject().keys()); + m_specularGlossyMaterialSections.append(m_propertyGroupsObj.value("SpecularGlossyMaterial").toObject().keys()); QStringList customMatSections = m_propertyGroupsObj.value("CustomMaterial").toObject().keys(); if (customMatSections.size() > 1) // as of now custom material has only 1 section, so we don't add it @@ -145,6 +147,7 @@ void MaterialBrowserModel::unloadPropertyGroups() m_propertyGroupsObj = {}; m_defaultMaterialSections.clear(); m_principledMaterialSections.clear(); + m_specularGlossyMaterialSections.clear(); m_customMaterialSections.clear(); emit materialSectionsChanged(); } diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h index 039d40921bb..4a75378de63 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowsermodel.h @@ -47,6 +47,7 @@ class MaterialBrowserModel : public QAbstractListModel Q_PROPERTY(QString copiedMaterialType READ copiedMaterialType WRITE setCopiedMaterialType NOTIFY copiedMaterialTypeChanged) Q_PROPERTY(QStringList defaultMaterialSections MEMBER m_defaultMaterialSections NOTIFY materialSectionsChanged) Q_PROPERTY(QStringList principledMaterialSections MEMBER m_principledMaterialSections NOTIFY materialSectionsChanged) + Q_PROPERTY(QStringList specularGlossyMaterialSections MEMBER m_specularGlossyMaterialSections NOTIFY materialSectionsChanged) Q_PROPERTY(QStringList customMaterialSections MEMBER m_customMaterialSections NOTIFY materialSectionsChanged) public: @@ -128,6 +129,7 @@ private: QString m_searchText; QList m_materialList; QStringList m_defaultMaterialSections; + QStringList m_specularGlossyMaterialSections; QStringList m_principledMaterialSections; QStringList m_customMaterialSections; ModelNode m_copiedMaterial; diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index cc8e4d2190f..9352e200d15 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -718,8 +718,8 @@ void MaterialEditorView::updatePossibleTypes() return; // Ensure basic types are always first - static const QStringList basicTypes {"DefaultMaterial", "PrincipledMaterial", "CustomMaterial"}; - QStringList allTypes = basicTypes; + QStringList nonQuick3dTypes; + QStringList allTypes; const QList itemLibEntries = m_itemLibraryInfo->entries(); for (const ItemLibraryEntry &entry : itemLibEntries) { @@ -734,12 +734,22 @@ void MaterialEditorView::updatePossibleTypes() addImport = model()->hasImport(import, true, true); } if (addImport) { - QString typeName = QString::fromLatin1(entry.typeName().split('.').last()); - if (!allTypes.contains(typeName)) - allTypes.append(typeName); + const QList typeSplit = entry.typeName().split('.'); + const QString typeName = QString::fromLatin1(typeSplit.last()); + if (typeSplit.size() == 2 && typeSplit.first() == "QtQuick3D") { + if (!allTypes.contains(typeName)) + allTypes.append(typeName); + } else if (!nonQuick3dTypes.contains(typeName)) { + nonQuick3dTypes.append(typeName); + } } } } + + allTypes.sort(); + nonQuick3dTypes.sort(); + allTypes.append(nonQuick3dTypes); + m_qmlBackEnd->contextObject()->setPossibleTypes(allTypes); } diff --git a/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp b/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp index 6d8a303f7c3..557810d5431 100644 --- a/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp +++ b/src/plugins/qmldesigner/components/navigator/choosefrompropertylistdialog.cpp @@ -40,6 +40,7 @@ ChooseFromPropertyListFilter::ChooseFromPropertyListFilter(const NodeMetaInfo &i // Texture // -> DefaultMaterial // -> PrincipledMaterial + // -> SpecularGlossyMaterial // -> SpriteParticle3D // -> TextureInput // -> SceneEnvironment @@ -65,7 +66,8 @@ ChooseFromPropertyListFilter::ChooseFromPropertyListFilter(const NodeMetaInfo &i if (insertInfo.isSubclassOf(textureType)) { const TypeName textureTypeCpp = ".QQuick3DTexture"; if (parentInfo.isSubclassOf("QtQuick3D.DefaultMaterial") - || parentInfo.isSubclassOf("QtQuick3D.PrincipledMaterial")) { + || parentInfo.isSubclassOf("QtQuick3D.PrincipledMaterial") + || parentInfo.isSubclassOf("QtQuick3D.SpecularGlossyMaterial")) { // All texture properties are valid targets const PropertyNameList targetNodeNameList = parentInfo.propertyNames(); for (const PropertyName &name : targetNodeNameList) { diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp index d9c9d6699e7..5ca192690a5 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp @@ -1042,7 +1042,8 @@ bool NavigatorTreeModel::dropAsImage3dTexture(const ModelNode &targetNode, }; if (targetNode.isSubclassOf("QtQuick3D.DefaultMaterial") - || targetNode.isSubclassOf("QtQuick3D.PrincipledMaterial")) { + || targetNode.isSubclassOf("QtQuick3D.PrincipledMaterial") + || targetNode.isSubclassOf("QtQuick3D.SpecularGlossyMaterial")) { // if dropping an image on a material, create a texture instead of image // Show texture property selection dialog auto dialog = ChooseFromPropertyListDialog::createIfNeeded(targetNode, "QtQuick3D.Texture", From 869597884df823b6e2eade4d1bead81b7710daa3 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Sat, 22 Oct 2022 23:50:46 +0200 Subject: [PATCH 18/97] CMakePM: Merge cacheVariables, environment for inherited presets cacheVariables, environment (and others) collection fields need to be merged when having inherited presets. Fixes: QTCREATORBUG-28360 Change-Id: I3d2b84355fad9ffa2dc4629ece7d42f7b482a859 Reviewed-by: Reviewed-by: Alexandru Croitor --- .../cmakeprojectmanager/presetsparser.cpp | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/plugins/cmakeprojectmanager/presetsparser.cpp b/src/plugins/cmakeprojectmanager/presetsparser.cpp index bd0d17d8cb8..3566bc1e081 100644 --- a/src/plugins/cmakeprojectmanager/presetsparser.cpp +++ b/src/plugins/cmakeprojectmanager/presetsparser.cpp @@ -441,6 +441,34 @@ bool PresetsParser::parse(const Utils::FilePath &jsonFile, QString &errorMessage return true; } +static QHash merge(const QHash &first, + const QHash &second) +{ + QHash result = first; + for (auto it = second.constKeyValueBegin(); it != second.constKeyValueEnd(); ++it) { + result[it->first] = it->second; + } + + return result; +} + +static CMakeConfig merge(const CMakeConfig &first, const CMakeConfig &second) +{ + return Utils::setUnionMerge( + first, + second, + [](const auto & /*left*/, const auto &right) { return right; }, + &CMakeConfigItem::less); +} + +static QStringList merge(const QStringList &first, const QStringList &second) +{ + return Utils::setUnionMerge( + first, + second, + [](const auto & /*left*/, const auto &right) { return right; }); +} + void PresetsDetails::ConfigurePreset::inheritFrom(const ConfigurePreset &other) { if (!condition && other.condition && !other.condition.value().isNull()) @@ -449,6 +477,9 @@ void PresetsDetails::ConfigurePreset::inheritFrom(const ConfigurePreset &other) if (!vendor && other.vendor) vendor = other.vendor; + if (vendor && other.vendor) + vendor = merge(other.vendor.value(), vendor.value()); + if (!generator && other.generator) generator = other.generator; @@ -472,9 +503,13 @@ void PresetsDetails::ConfigurePreset::inheritFrom(const ConfigurePreset &other) if (!cacheVariables && other.cacheVariables) cacheVariables = other.cacheVariables; + else if (cacheVariables && other.cacheVariables) + cacheVariables = merge(other.cacheVariables.value(), cacheVariables.value()); if (!environment && other.environment) environment = other.environment; + else if (environment && other.environment) + environment = merge(other.environment.value(), environment.value()); if (!warnings && other.warnings) warnings = other.warnings; @@ -494,8 +529,13 @@ void PresetsDetails::BuildPreset::inheritFrom(const BuildPreset &other) if (!vendor && other.vendor) vendor = other.vendor; + if (vendor && other.vendor) + vendor = merge(other.vendor.value(), vendor.value()); + if (!environment && other.environment) environment = other.environment; + else if (environment && other.environment) + environment = merge(other.environment.value(), environment.value()); if (!configurePreset && other.configurePreset) configurePreset = other.configurePreset; @@ -508,6 +548,8 @@ void PresetsDetails::BuildPreset::inheritFrom(const BuildPreset &other) if (!targets && other.targets) targets = other.targets; + else if (targets && other.targets) + targets = merge(other.targets.value(), targets.value()); if (!configuration && other.configuration) configuration = other.configuration; @@ -520,6 +562,8 @@ void PresetsDetails::BuildPreset::inheritFrom(const BuildPreset &other) if (!nativeToolOptions && other.nativeToolOptions) nativeToolOptions = other.nativeToolOptions; + else if (nativeToolOptions && other.nativeToolOptions) + nativeToolOptions = merge(other.nativeToolOptions.value(), nativeToolOptions.value()); } bool PresetsDetails::Condition::evaluate() const From 7dfc7c627b428524b0d3f021e822d5bf20910f98 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Sun, 23 Oct 2022 14:36:47 +0200 Subject: [PATCH 19/97] CMakePM: Allow presets without generator specified This allows presets that do not have a generator specified to proper work. On Windows CMake will detect "Visual Studio" as generator. This change sets the generator and the architecture values accordingly. Change-Id: I943e082430445c4b16cf9eaf4ae5ae2500b2bd2b Reviewed-by: Alexandru Croitor Reviewed-by: --- .../cmakeprojectimporter.cpp | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index a64ad830d63..e82491953d8 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -412,6 +412,27 @@ static QVector extractToolChainsFromCache(const CMakeConfi return result; } +static QString extractVisualStudioPlatformFromConfig(const CMakeConfig &config) +{ + const QString cmakeGenerator = config.stringValueOf(QByteArray("CMAKE_GENERATOR")); + QString platform; + if (cmakeGenerator.contains("Visual Studio")) { + const FilePath linker = config.filePathValueOf("CMAKE_LINKER"); + const QString toolsDir = linker.parentDir().fileName(); + if (toolsDir.compare("x64", Qt::CaseInsensitive) == 0) { + platform = "x64"; + } else if (toolsDir.compare("x86", Qt::CaseInsensitive) == 0) { + platform = "Win32"; + } else if (toolsDir.compare("arm64", Qt::CaseInsensitive) == 0) { + platform = "ARM64"; + } else if (toolsDir.compare("arm", Qt::CaseInsensitive) == 0) { + platform = "ARM"; + } + } + + return platform; +} + QList CMakeProjectImporter::examineDirectory(const FilePath &importPath, QString *warningMessage) const { @@ -476,6 +497,17 @@ QList CMakeProjectImporter::examineDirectory(const FilePath &importPath, QApplication::setOverrideCursor(Qt::WaitCursor); config = configurationFromPresetProbe(importPath, configurePreset); QApplication::restoreOverrideCursor(); + + if (!configurePreset.generator) { + QString cmakeGenerator = config.stringValueOf(QByteArray("CMAKE_GENERATOR")); + configurePreset.generator = cmakeGenerator; + data->generator = cmakeGenerator; + data->platform = extractVisualStudioPlatformFromConfig(config); + if (!data->platform.isEmpty()) { + configurePreset.architecture = PresetsDetails::ValueStrategyPair(); + configurePreset.architecture->value = data->platform; + } + } } else { config = cache; config << CMakeConfigItem("CMAKE_COMMAND", @@ -566,6 +598,8 @@ QList CMakeProjectImporter::examineDirectory(const FilePath &importPath, data->generator = config.stringValueOf("CMAKE_GENERATOR"); data->extraGenerator = config.stringValueOf("CMAKE_EXTRA_GENERATOR"); data->platform = config.stringValueOf("CMAKE_GENERATOR_PLATFORM"); + if (data->platform.isEmpty()) + data->platform = extractVisualStudioPlatformFromConfig(config); data->toolset = config.stringValueOf("CMAKE_GENERATOR_TOOLSET"); data->sysroot = config.filePathValueOf("CMAKE_SYSROOT"); From ec4d96a14b227c0e2d809e20ef28d7d4675b85af Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Sun, 23 Oct 2022 16:11:52 +0200 Subject: [PATCH 20/97] CMakePM: Accept broken kits for CMakePresets For CMakePresets if a preset is broken we should not create a preset kit for every build type. Instead reuse the broken kit created by the first build type. Task-number: QTCREATORBUG-28295 Change-Id: I038fbb23817834f59ac73ccd2f9953f1a412b656 Reviewed-by: Alexandru Croitor Reviewed-by: --- .../cmakeprojectimporter.cpp | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index e82491953d8..c8415a51111 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -652,22 +652,24 @@ bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const if (data->qt.qt && QtSupport::QtKitAspect::qtVersionId(k) != data->qt.qt->uniqueId()) return false; - const QList allLanguages = ToolChainManager::allLanguages(); - for (const ToolChainDescription &tcd : data->toolChains) { - if (!Utils::contains(allLanguages, [&tcd](const Id& language) {return language == tcd.language;})) - continue; - ToolChain *tc = ToolChainKitAspect::toolChain(k, tcd.language); - if (!tc || !tc->matchesCompilerCommand(tcd.compilerPath)) { - return false; - } - } - + bool haveCMakePreset = false; if (!data->cmakePreset.isEmpty()) { auto presetConfigItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(k); if (data->cmakePreset != presetConfigItem.expandedValue(k)) return false; ensureBuildDirectory(*data, k); + haveCMakePreset = true; + } + + const QList allLanguages = ToolChainManager::allLanguages(); + for (const ToolChainDescription &tcd : data->toolChains) { + if (!Utils::contains(allLanguages, [&tcd](const Id& language) {return language == tcd.language;})) + continue; + ToolChain *tc = ToolChainKitAspect::toolChain(k, tcd.language); + if ((!tc || !tc->matchesCompilerCommand(tcd.compilerPath)) && !haveCMakePreset) { + return false; + } } qCDebug(cmInputLog) << k->displayName() From 83e77d71a899d387527f96e49746aec02fe83ae0 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Sun, 23 Oct 2022 18:42:20 +0200 Subject: [PATCH 21/97] CMakePM: Expand cache variables for the preset probe This way the CMAKE_PREFIX_PATH set to $env{HOME}/Qt (Linux) or $env{SystemDrive}/Qt (Windows) would work as expected. Change-Id: I03a9102d6d1da2a8740cab738577c47c44166c6c Reviewed-by: Alexandru Croitor Reviewed-by: --- .../cmakeprojectimporter.cpp | 22 +++++++++++++------ tests/manual/cmakepresets/CMakePresets.json | 6 ++--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index c8415a51111..f8f536e22db 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -197,19 +197,27 @@ static CMakeConfig configurationFromPresetProbe( const CMakeConfig cache = configurePreset.cacheVariables ? configurePreset.cacheVariables.value() : CMakeConfig(); - const FilePath cmakeMakeProgram = cache.filePathValueOf(QByteArray("CMAKE_MAKE_PROGRAM")); - const FilePath toolchainFile = cache.filePathValueOf(QByteArray("CMAKE_TOOLCHAIN_FILE")); - const QString prefixPath = cache.stringValueOf(QByteArray("CMAKE_PREFIX_PATH")); - const QString findRootPath = cache.stringValueOf(QByteArray("CMAKE_FIND_ROOT_PATH")); - const QString qtHostPath = cache.stringValueOf(QByteArray("QT_HOST_PATH")); + + auto expandCacheValue = + [configurePreset, env, importPath, cache](const QString &key) -> QString { + QString result = cache.stringValueOf(key.toUtf8()); + CMakePresets::Macros::expand(configurePreset, env, importPath, result); + return result; + }; + + const QString cmakeMakeProgram = expandCacheValue("CMAKE_MAKE_PROGRAM"); + const QString toolchainFile = expandCacheValue("CMAKE_TOOLCHAIN_FILE"); + const QString prefixPath = expandCacheValue("CMAKE_PREFIX_PATH"); + const QString findRootPath = expandCacheValue("CMAKE_FIND_ROOT_PATH"); + const QString qtHostPath = expandCacheValue("QT_HOST_PATH"); if (!cmakeMakeProgram.isEmpty()) { args.emplace_back( - QStringLiteral("-DCMAKE_MAKE_PROGRAM=%1").arg(cmakeMakeProgram.toString())); + QStringLiteral("-DCMAKE_MAKE_PROGRAM=%1").arg(cmakeMakeProgram)); } if (!toolchainFile.isEmpty()) { args.emplace_back( - QStringLiteral("-DCMAKE_TOOLCHAIN_FILE=%1").arg(toolchainFile.toString())); + QStringLiteral("-DCMAKE_TOOLCHAIN_FILE=%1").arg(toolchainFile)); } if (!prefixPath.isEmpty()) { args.emplace_back(QStringLiteral("-DCMAKE_PREFIX_PATH=%1").arg(prefixPath)); diff --git a/tests/manual/cmakepresets/CMakePresets.json b/tests/manual/cmakepresets/CMakePresets.json index f4eb2283263..50f3968a911 100644 --- a/tests/manual/cmakepresets/CMakePresets.json +++ b/tests/manual/cmakepresets/CMakePresets.json @@ -12,7 +12,7 @@ "generator": "Ninja", "installDir": "../inst-${presetName}", "cacheVariables": { - "CMAKE_PREFIX_PATH": "c:/Qt/6.3.2/mingw_64" + "CMAKE_PREFIX_PATH": "$env{SystemDrive}/Qt/6.3.2/mingw_64" }, "condition": { "type": "equals", @@ -20,7 +20,7 @@ "rhs": "Windows" }, "environment": { - "PATH": "c:/Qt/Tools/mingw1120_64/bin;$penv{PATH}" + "PATH": "$env{SystemDrive}/Qt/Tools/mingw1120_64/bin;$penv{PATH}" }, "debug" : { "find" : true @@ -34,7 +34,7 @@ "inherits" : "mingw", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", - "CMAKE_PREFIX_PATH": "c:/Qt/6.3.2/mingw_64" + "CMAKE_PREFIX_PATH": "$env{SystemDrive}/Qt/6.3.2/mingw_64" } }, { From fb94873765f2db623d83f9fd660d7f6fa479ed5d Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Sun, 23 Oct 2022 20:06:00 +0200 Subject: [PATCH 22/97] CMakePM: Use Utils::Environment for Presets environment Utils::Environment takes care of the case insesitivity of the key of environment variables on Windows. Change-Id: I624340d30c6b170b5d0a86791f26a4841a0b2fb7 Reviewed-by: Reviewed-by: Alexandru Croitor --- .../cmakeprojectmanager/presetsmacros.cpp | 39 ++++++++----------- .../cmakeprojectmanager/presetsparser.cpp | 18 +++++++-- .../cmakeprojectmanager/presetsparser.h | 5 ++- tests/manual/cmakepresets/CMakePresets.json | 4 +- 4 files changed, 36 insertions(+), 30 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/presetsmacros.cpp b/src/plugins/cmakeprojectmanager/presetsmacros.cpp index 0e156ab4a47..3ac96512388 100644 --- a/src/plugins/cmakeprojectmanager/presetsmacros.cpp +++ b/src/plugins/cmakeprojectmanager/presetsmacros.cpp @@ -99,22 +99,17 @@ static QString expandMacroEnv(const QString ¯oPrefix, return result; } -static QHash getEnvCombined( - const std::optional> &optPresetEnv, const Utils::Environment &env) +static Utils::Environment getEnvCombined(const std::optional &optPresetEnv, + const Utils::Environment &env) { - QHash result; - - for (auto it = env.constBegin(); it != env.constEnd(); ++it) { - if (it.value().second) - result.insert(it.key().name, it.value().first); - } + Utils::Environment result = env; if (!optPresetEnv) return result; - QHash presetEnv = optPresetEnv.value(); - for (auto it = presetEnv.constKeyValueBegin(); it != presetEnv.constKeyValueEnd(); ++it) { - result[it->first] = it->second; + Utils::Environment presetEnv = optPresetEnv.value(); + for (auto it = presetEnv.constBegin(); it != presetEnv.constEnd(); ++it) { + result.set(it.key().name, it.value().first); } return result; @@ -125,10 +120,10 @@ void expand(const PresetType &preset, Utils::Environment &env, const Utils::FilePath &sourceDirectory) { - const QHash presetEnv = getEnvCombined(preset.environment, env); - for (auto it = presetEnv.constKeyValueBegin(); it != presetEnv.constKeyValueEnd(); ++it) { - const QString key = it->first; - QString value = it->second; + const Utils::Environment presetEnv = getEnvCombined(preset.environment, env); + for (auto it = presetEnv.constBegin(); it != presetEnv.constEnd(); ++it) { + const QString key = it.key().name; + QString value = it.value().first; expandAllButEnv(preset, sourceDirectory, value); value = expandMacroEnv("env", value, [presetEnv](const QString ¯oName) { @@ -161,15 +156,15 @@ void expand(const PresetType &preset, Utils::EnvironmentItems &envItems, const Utils::FilePath &sourceDirectory) { - const QHash presetEnv = preset.environment ? preset.environment.value() - : QHash(); - for (auto it = presetEnv.constKeyValueBegin(); it != presetEnv.constKeyValueEnd(); ++it) { - const QString key = it->first; - QString value = it->second; + const Utils::Environment presetEnv = preset.environment ? preset.environment.value() + : Utils::Environment(); + for (auto it = presetEnv.constBegin(); it != presetEnv.constEnd(); ++it) { + const QString key = it.key().name; + QString value = it.value().first; expandAllButEnv(preset, sourceDirectory, value); value = expandMacroEnv("env", value, [presetEnv](const QString ¯oName) { - if (presetEnv.contains(macroName)) + if (presetEnv.hasKey(macroName)) return presetEnv.value(macroName); return QString("${%1}").arg(macroName); }); @@ -199,7 +194,7 @@ void expand(const PresetType &preset, { expandAllButEnv(preset, sourceDirectory, value); - const QHash presetEnv = getEnvCombined(preset.environment, env); + const Utils::Environment presetEnv = getEnvCombined(preset.environment, env); value = expandMacroEnv("env", value, [presetEnv](const QString ¯oName) { return presetEnv.value(macroName); }); diff --git a/src/plugins/cmakeprojectmanager/presetsparser.cpp b/src/plugins/cmakeprojectmanager/presetsparser.cpp index 3566bc1e081..6cddec91234 100644 --- a/src/plugins/cmakeprojectmanager/presetsparser.cpp +++ b/src/plugins/cmakeprojectmanager/presetsparser.cpp @@ -208,10 +208,10 @@ bool parseConfigurePresets(const QJsonValue &jsonValue, const QJsonObject environmentObj = object.value("environment").toObject(); for (const QString &envKey : environmentObj.keys()) { if (!preset.environment) - preset.environment = QHash(); + preset.environment = Utils::Environment(); QJsonValue envValue = environmentObj.value(envKey); - preset.environment.value().insert(envKey, envValue.toString()); + preset.environment.value().set(envKey, envValue.toString()); } const QJsonObject warningsObj = object.value("warnings").toObject(); @@ -335,10 +335,10 @@ bool parseBuildPresets(const QJsonValue &jsonValue, const QJsonObject environmentObj = object.value("environment").toObject(); for (const QString &envKey : environmentObj.keys()) { if (!preset.environment) - preset.environment = QHash(); + preset.environment = Utils::Environment(); QJsonValue envValue = environmentObj.value(envKey); - preset.environment.value().insert(envKey, envValue.toString()); + preset.environment.value().set(envKey, envValue.toString()); } if (object.contains("configurePreset")) @@ -452,6 +452,16 @@ static QHash merge(const QHash &first, return result; } +static Utils::Environment merge(const Utils::Environment &first, const Utils::Environment &second) +{ + Utils::Environment result = first; + for (auto it = second.constBegin(); it != second.constEnd(); ++it) { + result.set(it.key().name, it.value().first); + } + + return result; +} + static CMakeConfig merge(const CMakeConfig &first, const CMakeConfig &second) { return Utils::setUnionMerge( diff --git a/src/plugins/cmakeprojectmanager/presetsparser.h b/src/plugins/cmakeprojectmanager/presetsparser.h index 7717f19c666..fdea1808719 100644 --- a/src/plugins/cmakeprojectmanager/presetsparser.h +++ b/src/plugins/cmakeprojectmanager/presetsparser.h @@ -5,6 +5,7 @@ #include "cmakeconfigitem.h" +#include #include #include @@ -103,7 +104,7 @@ public: std::optional installDir; std::optional cmakeExecutable; std::optional cacheVariables; - std::optional> environment; + std::optional environment; std::optional warnings; std::optional errors; std::optional debug; @@ -120,7 +121,7 @@ public: std::optional> vendor; std::optional displayName; std::optional description; - std::optional> environment; + std::optional environment; std::optional configurePreset; std::optional inheritConfigureEnvironment = true; std::optional jobs; diff --git a/tests/manual/cmakepresets/CMakePresets.json b/tests/manual/cmakepresets/CMakePresets.json index 50f3968a911..1b163830640 100644 --- a/tests/manual/cmakepresets/CMakePresets.json +++ b/tests/manual/cmakepresets/CMakePresets.json @@ -12,7 +12,7 @@ "generator": "Ninja", "installDir": "../inst-${presetName}", "cacheVariables": { - "CMAKE_PREFIX_PATH": "$env{SystemDrive}/Qt/6.3.2/mingw_64" + "CMAKE_PREFIX_PATH": "$env{SYSTEMDRIVE}/Qt/6.3.2/mingw_64" }, "condition": { "type": "equals", @@ -20,7 +20,7 @@ "rhs": "Windows" }, "environment": { - "PATH": "$env{SystemDrive}/Qt/Tools/mingw1120_64/bin;$penv{PATH}" + "PATH": "$env{SYSTEMDRIVE}/Qt/Tools/mingw1120_64/bin;$penv{PATH}" }, "debug" : { "find" : true From 4fdbfe164131f16af00a1082cbf45273d074c8a2 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Mon, 24 Oct 2022 12:48:49 +0200 Subject: [PATCH 23/97] CMakePM: Proper handling of relative toolchain files in CMakePresets Previously it was only tested with absolute paths. Change-Id: I3871da60f3f1b17ae4d2d4cfb69d1be60da1435b Reviewed-by: Reviewed-by: Alexandru Croitor --- src/plugins/cmakeprojectmanager/presetsmacros.cpp | 8 +++++--- tests/manual/cmakepresets/CMakePresets.json | 5 +++-- tests/manual/cmakepresets/msvc-toolchain.cmake | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) create mode 100644 tests/manual/cmakepresets/msvc-toolchain.cmake diff --git a/src/plugins/cmakeprojectmanager/presetsmacros.cpp b/src/plugins/cmakeprojectmanager/presetsmacros.cpp index 3ac96512388..74e5279ba3b 100644 --- a/src/plugins/cmakeprojectmanager/presetsmacros.cpp +++ b/src/plugins/cmakeprojectmanager/presetsmacros.cpp @@ -220,7 +220,7 @@ void updateToolchainFile( Utils::FilePath toolchainFile = Utils::FilePath::fromString(toolchainFileName); if (toolchainFile.isRelativePath()) { for (const auto &path : {sourceDirectory, buildDirectory}) { - Utils::FilePath probePath = toolchainFile.resolvePath(path); + Utils::FilePath probePath = path.resolvePath(toolchainFile); if (probePath.exists() && probePath != path) { toolchainFile = probePath; break; @@ -231,6 +231,8 @@ void updateToolchainFile( if (!toolchainFile.exists()) return; + const QString toolchainFileString = toolchainFile.cleanPath().toString(); + // toolchainFile takes precedence to CMAKE_TOOLCHAIN_FILE CMakeConfig cache = configurePreset.cacheVariables ? configurePreset.cacheVariables.value() : CMakeConfig(); @@ -239,11 +241,11 @@ void updateToolchainFile( return item.key == "CMAKE_TOOLCHAIN_FILE"; }); if (it != cache.end()) - it->value = toolchainFile.toString().toUtf8(); + it->value = toolchainFileString.toUtf8(); else cache << CMakeConfigItem("CMAKE_TOOLCHAIN_FILE", CMakeConfigItem::FILEPATH, - toolchainFile.toString().toUtf8()); + toolchainFileString.toUtf8()); configurePreset.cacheVariables = cache; } diff --git a/tests/manual/cmakepresets/CMakePresets.json b/tests/manual/cmakepresets/CMakePresets.json index 1b163830640..90e2df58369 100644 --- a/tests/manual/cmakepresets/CMakePresets.json +++ b/tests/manual/cmakepresets/CMakePresets.json @@ -45,7 +45,7 @@ "architecture" : { "value": "x64" }, - "toolchainFile" : "c:/Qt/6.3.2/msvc2019_64/lib/cmake/Qt6/qt.toolchain.cmake", + "toolchainFile" : "../cmakepresets/msvc-toolchain.cmake", "condition" : { "type": "not", "condition": { @@ -55,7 +55,8 @@ } }, "environment" : { - "HOST_SYSTEM_NAME": "Windows" + "HOST_SYSTEM_NAME": "Windows", + "QT_VERSION": "6.3.2" } }, { diff --git a/tests/manual/cmakepresets/msvc-toolchain.cmake b/tests/manual/cmakepresets/msvc-toolchain.cmake new file mode 100644 index 00000000000..ae5b6fc9283 --- /dev/null +++ b/tests/manual/cmakepresets/msvc-toolchain.cmake @@ -0,0 +1 @@ +include($ENV{SYSTEMDRIVE}/Qt/$ENV{QT_VERSION}/msvc2019_64/lib/cmake/Qt6/qt.toolchain.cmake) From 02024303b10a370d7329b52d48c294aac300795c Mon Sep 17 00:00:00 2001 From: Kwangsub Kim Date: Fri, 21 Oct 2022 12:38:21 +0200 Subject: [PATCH 24/97] McuSupport: Specify MSVC type for toolchain pick up The current criteria allows to select LLVM so that it can cause an unexpected behavior. Explicit toolchain type check will prevent the invalid toolchain setup. Change-Id: Ib0afa4304650dd451c12d7a8d950b26115661862 Reviewed-by: Yasser Grimes Reviewed-by: Reviewed-by: Daniele Bortolotti Reviewed-by: Christian Stenger --- src/plugins/mcusupport/mcupackage.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp index 63a86442290..b0a3699faff 100644 --- a/src/plugins/mcusupport/mcupackage.cpp +++ b/src/plugins/mcusupport/mcupackage.cpp @@ -325,6 +325,7 @@ ToolChain *McuToolChainPackage::msvcToolChain(Id language) return (abi.osFlavor() == Abi::WindowsMsvc2017Flavor || abi.osFlavor() == Abi::WindowsMsvc2019Flavor) && abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64 + && t->typeId() == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID && t->language() == language; }); return toolChain; From afed126ba1bb32d43c0a26d6ed58dcca87f6522a Mon Sep 17 00:00:00 2001 From: Artem Sokolovskii Date: Mon, 24 Oct 2022 16:39:20 +0200 Subject: [PATCH 25/97] ClangFormat: Fix wrong comment indentation Fixes: QTCREATORBUG-25539 Change-Id: Ifecc4bc2c0984319d858720d5bcd1788a9008e90 Reviewed-by: Christian Kandeler Reviewed-by: --- .../clangformat/clangformatbaseindenter.cpp | 4 ++-- .../clangformat/tests/clangformat-test.cpp | 20 +++++++++++++++++++ .../clangformat/tests/clangformat-test.h | 1 + 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/plugins/clangformat/clangformatbaseindenter.cpp b/src/plugins/clangformat/clangformatbaseindenter.cpp index cda7b54d5ef..7c83c8e43b2 100644 --- a/src/plugins/clangformat/clangformatbaseindenter.cpp +++ b/src/plugins/clangformat/clangformatbaseindenter.cpp @@ -250,7 +250,7 @@ QByteArray dummyTextForContext(CharacterContext context, bool closingBraceBlock) case CharacterContext::IfOrElseWithoutScope: return ";"; case CharacterContext::NewStatementOrContinuation: - return "/**/"; + return "/*//*/"; case CharacterContext::Unknown: default: QTC_ASSERT(false, return "";); @@ -302,7 +302,7 @@ int forceIndentWithExtraText(QByteArray &buffer, } // A comment at the end of the line appears to prevent clang-format from removing line breaks. - if (dummyText == "/**/" || dummyText.isEmpty()) { + if (dummyText == "/*//*/" || dummyText.isEmpty()) { if (block.previous().isValid()) { const int prevEndOffset = Utils::Text::utf8NthLineOffset(block.document(), buffer, block.blockNumber()) + block.previous().text().length(); diff --git a/src/plugins/clangformat/tests/clangformat-test.cpp b/src/plugins/clangformat/tests/clangformat-test.cpp index 74107a40e78..161c20406c8 100644 --- a/src/plugins/clangformat/tests/clangformat-test.cpp +++ b/src/plugins/clangformat/tests/clangformat-test.cpp @@ -704,4 +704,24 @@ void ClangFormatTest::testIndentFunctionArgumentOnNewLine() })); } +void ClangFormatTest::testIndentCommentOnNewLine() +{ + insertLines( + {"/*!", + " \\qmlproperty double Type::property", + " ", + " \\brief The property of Type.", + "*/" + }); + m_indenter->indent(*m_cursor, QChar::Null, TextEditor::TabSettings()); + QCOMPARE(documentLines(), + (std::vector{ + "/*!", + " \\qmlproperty double Type::property", + " ", + " \\brief The property of Type.", + "*/" + })); +} + } // namespace ClangFormat::Internal diff --git a/src/plugins/clangformat/tests/clangformat-test.h b/src/plugins/clangformat/tests/clangformat-test.h index 0cb909c0344..a9c146ef8aa 100644 --- a/src/plugins/clangformat/tests/clangformat-test.h +++ b/src/plugins/clangformat/tests/clangformat-test.h @@ -90,6 +90,7 @@ private slots: void testClassIndentStructure(); void testIndentInitializeVector(); void testIndentFunctionArgumentOnNewLine(); + void testIndentCommentOnNewLine(); private: void insertLines(const std::vector &lines); From 5039ebff7052d2f09dd07c3e3cb0217f71d447e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20L=C3=B6hning?= Date: Mon, 24 Oct 2022 22:48:10 +0200 Subject: [PATCH 26/97] Help: SquishTests: Updates for tst_WELP01 Change-Id: I2e25f8c3368c4c00c13827f5eb70d9e3a4fc5a9e Reviewed-by: Reviewed-by: Christian Stenger --- src/plugins/help/generalsettingspage.cpp | 2 ++ tests/system/shared/utils.py | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/plugins/help/generalsettingspage.cpp b/src/plugins/help/generalsettingspage.cpp index 459face1180..9ec864e0b88 100644 --- a/src/plugins/help/generalsettingspage.cpp +++ b/src/plugins/help/generalsettingspage.cpp @@ -114,8 +114,10 @@ GeneralSettingsPageWidget::GeneralSettingsPageWidget() // startup group box auto startupGroupBox = new QGroupBox(Tr::tr("Startup")); + startupGroupBox->setObjectName("startupGroupBox"); contextHelpComboBox = new QComboBox(startupGroupBox); + contextHelpComboBox->setObjectName("contextHelpComboBox"); contextHelpComboBox->addItem(Tr::tr("Show Side-by-Side if Possible")); contextHelpComboBox->addItem(Tr::tr("Always Show Side-by-Side")); contextHelpComboBox->addItem(Tr::tr("Always Show in Help Mode")); diff --git a/tests/system/shared/utils.py b/tests/system/shared/utils.py index aa39725745b..4e26d3913fc 100644 --- a/tests/system/shared/utils.py +++ b/tests/system/shared/utils.py @@ -280,11 +280,12 @@ def addCurrentCreatorDocumentation(): clickButton(waitForObject("{type='QPushButton' name='addButton' visible='1' text='Add...'}")) selectFromFileDialog(docPath) try: - waitForObject("{type='QMessageBox' unnamed='1' visible='1' " - "text~='Unable to register documentation.*'}", 3000) + windowStr = ("{type='QMessageBox' unnamed='1' visible='1' " + "text~='Unable to register documentation.*'}") + waitForObject(windowStr, 3000) test.passes("Qt Creator's documentation found already registered.") clickButton(waitForObject("{type='QPushButton' text='OK' unnamed='1' visible='1' " - "container={name='groupBox' type='QGroupBox' visible='1'}}")) + "window=%s}" % windowStr)) except: test.fail("Added Qt Creator's documentation explicitly.") clickButton(waitForObject(":Options.OK_QPushButton")) From 642ba31f8b4b7020209072ffb19852c1eedf3971 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 24 Oct 2022 11:35:55 +0200 Subject: [PATCH 27/97] Doc: Describe "Show subfolders inside source group folders" ...in Preferences > CMake. Task-number: QTCREATORBUG-27876 Change-Id: I0d71e0281413433e6acfdd7023c138c422a8712f Reviewed-by: Marcus Tillmanns Reviewed-by: Cristian Adam --- doc/qtcreator/src/cmake/creator-projects-cmake.qdoc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/qtcreator/src/cmake/creator-projects-cmake.qdoc b/doc/qtcreator/src/cmake/creator-projects-cmake.qdoc index 441cfe3a179..c6eefa5db24 100644 --- a/doc/qtcreator/src/cmake/creator-projects-cmake.qdoc +++ b/doc/qtcreator/src/cmake/creator-projects-cmake.qdoc @@ -45,6 +45,14 @@ \uicontrol {Clear CMake Configuration}, and then select \uicontrol Build > \uicontrol {Run CMake} to reconfigure the project. + The \uicontrol Projects view shows the names of the subfolders where the + source files are located. To hide the subfolder names and arrange the files + only according to their source group, select \uicontrol Edit > + \uicontrol Preferences > \uicontrol CMake > \uicontrol General, and then + deselect the \uicontrol {Show subfolders inside source group folders} check + box. The change takes effect after you select \uicontrol Build > + \uicontrol {Run CMake}. + \section1 Adding CMake Tools \QC requires CMake's \l{https://cmake.org/cmake/help/latest/manual/cmake-file-api.7.html} From d1a9cecf593bc81799321b0e1a8871d7f5547a44 Mon Sep 17 00:00:00 2001 From: Kwangsub Kim Date: Thu, 20 Oct 2022 17:14:09 +0200 Subject: [PATCH 28/97] McuSupport: Fix crash when there is no proper desktop toolchain Desktop toolchain is picked up from the registered toolchains in Qt Creator, but it can be failed, for instance when there is no toolchain for MinGW, and it causes crash for now. An error handling is added to avoid it and inform to a user. Task-number: QTCREATORBUG-28296 Change-Id: Ie16cd6c75df9be510bb49b765ad61ddf189a41db Reviewed-by: Christian Stenger --- src/plugins/mcusupport/mcukitmanager.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/plugins/mcusupport/mcukitmanager.cpp b/src/plugins/mcusupport/mcukitmanager.cpp index ce846ffc708..e400eefa7b8 100644 --- a/src/plugins/mcusupport/mcukitmanager.cpp +++ b/src/plugins/mcusupport/mcukitmanager.cpp @@ -10,6 +10,7 @@ #include "mcusupportconstants.h" #include "mcusupportplugin.h" #include "mcusupportsdk.h" +#include "mcusupporttr.h" #include "mcutarget.h" #include @@ -247,10 +248,19 @@ public: auto cxxToolchain = toolchainPackage->toolChain( ProjectExplorer::Constants::CXX_LANGUAGE_ID); - configMap.insert("CMAKE_CXX_COMPILER", - cxxToolchain->compilerCommand().toString().toLatin1()); - configMap.insert("CMAKE_C_COMPILER", - cToolchain->compilerCommand().toString().toLatin1()); + if (cToolchain && cxxToolchain) { + configMap.insert("CMAKE_CXX_COMPILER", + cxxToolchain->compilerCommand().toString().toLatin1()); + configMap.insert("CMAKE_C_COMPILER", + cToolchain->compilerCommand().toString().toLatin1()); + } else { + printMessage(Tr::tr("Warning for target %1: invalid toolchain path (%2). " + "Update the toolchain in Edit > Preferences > Kits.") + .arg(generateKitNameFromTarget(mcuTarget), + toolchainPackage->path().toUserOutput()), + true); + } + } else { const FilePath cMakeToolchainFile = mcuTarget->toolChainFilePackage()->path(); From 9257a15a687b7c340e28ea187f2bf7e3848b9b0f Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Wed, 19 Oct 2022 13:30:29 +0200 Subject: [PATCH 29/97] McuSupport: The armgcc version string does not contain 'v' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ic259bed17a97bccb64f427ce2054efc9d05b55f2 Reviewed-by: Dawid Śliwa Reviewed-by: Christian Stenger --- src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h | 2 +- src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h | 2 +- src/plugins/mcusupport/test/armgcc_example_baremetal_json.h | 2 +- .../mcusupport/test/armgcc_mimxrt1050_evk_baremetal_json.h | 2 +- .../mcusupport/test/armgcc_mimxrt1050_evk_freertos_json.h | 2 +- .../mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h | 2 +- .../mcusupport/test/armgcc_mimxrt1064_evk_baremetal_json.h | 2 +- .../mcusupport/test/armgcc_mimxrt1064_evk_freertos_json.h | 2 +- .../mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h | 2 +- .../test/armgcc_stm32f469i_discovery_baremetal_json.h | 2 +- .../test/armgcc_stm32f769i_discovery_baremetal_json.h | 2 +- .../test/armgcc_stm32f769i_discovery_freertos_json.h | 2 +- .../test/armgcc_stm32h750b_discovery_baremetal_json.h | 2 +- src/plugins/mcusupport/test/unittest.cpp | 4 ++-- 14 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h index 84e29625de0..3cc40f01d39 100644 --- a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h @@ -45,7 +45,7 @@ constexpr auto armgcc_ek_ra6m3g_baremetal_json = R"( "versionDetection": { "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", - "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, "detectionPath": { "windows": "bin/arm-none-eabi-g++.exe", diff --git a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h index 738cba2f67f..45f7d554284 100644 --- a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h @@ -45,7 +45,7 @@ constexpr auto armgcc_ek_ra6m3g_freertos_json = R"( "versionDetection": { "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", - "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, "detectionPath": { "windows": "bin/arm-none-eabi-g++.exe", diff --git a/src/plugins/mcusupport/test/armgcc_example_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_example_baremetal_json.h index a72af967c6e..e4f10bd54b3 100644 --- a/src/plugins/mcusupport/test/armgcc_example_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_example_baremetal_json.h @@ -30,7 +30,7 @@ constexpr auto armgcc_example_baremetal_json = R"( "versionDetection": { "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", - "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, "detectionPath": { "windows": "bin/arm-none-eabi-g++.exe", diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_baremetal_json.h index 21e154cbde1..01ac942a0a5 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_baremetal_json.h @@ -49,7 +49,7 @@ constexpr auto armgcc_mimxrt1050_evk_baremetal_json = R"( "versionDetection": { "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", - "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, "detectionPath": { "windows": "bin/arm-none-eabi-g++.exe", diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_freertos_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_freertos_json.h index b366a3f0167..25e696a14d0 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_freertos_json.h @@ -49,7 +49,7 @@ constexpr auto armgcc_mimxrt1050_evk_freertos_json = R"( "versionDetection": { "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", - "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, "detectionPath": { "windows": "bin/arm-none-eabi-g++.exe", diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h index efe74d094e7..79c3eb64356 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h @@ -48,7 +48,7 @@ constexpr auto armgcc_mimxrt1060_evk_baremetal_json = R"( "versionDetection": { "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", - "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, "detectionPath": { "windows": "bin/arm-none-eabi-g++.exe", diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_baremetal_json.h index e8c71e5292d..b2d4b7ec406 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_baremetal_json.h @@ -49,7 +49,7 @@ constexpr auto armgcc_mimxrt1064_evk_baremetal_json = R"( "versionDetection": { "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", - "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, "detectionPath": { "windows": "bin/arm-none-eabi-g++.exe", diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_freertos_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_freertos_json.h index 138a7a56eb7..264ad9c065e 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_freertos_json.h @@ -49,7 +49,7 @@ constexpr auto armgcc_mimxrt1064_evk_freertos_json = R"( "versionDetection": { "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", - "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, "detectionPath": { "windows": "bin/arm-none-eabi-g++.exe", diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h index 5aab5105bcb..a32fd7a1dcc 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h @@ -49,7 +49,7 @@ constexpr auto armgcc_mimxrt1170_evk_freertos_json = R"( "versionDetection": { "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", - "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, "detectionPath": { "windows": "bin/arm-none-eabi-g++.exe", diff --git a/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h index d67026d9fef..452ae4e953c 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h @@ -48,7 +48,7 @@ constexpr auto armgcc_stm32f469i_discovery_baremetal_json = R"( "versionDetection": { "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", - "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, "detectionPath": { "windows": "bin/arm-none-eabi-g++.exe", diff --git a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h index c6464c10a75..9fdb309da14 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h @@ -48,7 +48,7 @@ constexpr auto armgcc_stm32f769i_discovery_baremetal_json = R"( "versionDetection": { "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", - "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, "detectionPath": { "windows": "bin/arm-none-eabi-g++.exe", diff --git a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h index 34da0c65a43..249db9497d5 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h @@ -48,7 +48,7 @@ constexpr auto armgcc_stm32f769i_discovery_freertos_json = R"( "versionDetection": { "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", - "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, "detectionPath": { "windows": "bin/arm-none-eabi-g++.exe", diff --git a/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h index 99aa4cede3f..3b5adc3e989 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h @@ -48,7 +48,7 @@ constexpr auto armgcc_stm32h750b_discovery_baremetal_json = R"( "versionDetection": { "filePattern": "bin/arm-none-eabi-g++", "executableArgs": "--version", - "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, "detectionPath": { "windows": "bin/arm-none-eabi-g++.exe", diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index 30c0808e077..090ed89cd5c 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -75,7 +75,7 @@ using testing::Return; namespace { const char empty[]{""}; const char armGcc[]{"armgcc"}; -const char armGccVersionDetectionRegex[]{R"(\bv(\d+\.\d+\.\d+)\b)"}; +const char armGccVersionDetectionRegex[]{R"(\b(\d+\.\d+\.\d+)\b)"}; const char armGccDir[]{"/opt/armgcc"}; const char armGccDirectorySetting[]{"GNUArmEmbeddedToolchain"}; const char armGccEnvVar[]{"ARMGCC_DIR"}; @@ -1648,7 +1648,7 @@ void McuSupportTest::test_nonemptyVersionDetector() // pkgDesc.validationPath left empty // pkgDesc.versions left empty pkgDesc.versionDetection.filePattern = "bin/arm-none-eabi-g++"; - pkgDesc.versionDetection.regex = "\\bv?(\\d+\\.\\d+\\.\\d+)\\b"; + pkgDesc.versionDetection.regex = "\\b(\\d+\\.\\d+\\.\\d+)\\b"; pkgDesc.versionDetection.executableArgs = "--version"; // pkgDesc.versionDetection.xmlElement left empty // pkgDesc.versionDetection.xmlAttribute left empty From 0482db7a1b23707d46c5dbf84cc4502344aa0bbb Mon Sep 17 00:00:00 2001 From: Knud Dollereder Date: Fri, 30 Sep 2022 13:30:54 +0200 Subject: [PATCH 30/97] QmlDesigner: Fix EasingCurve editor Due to a behavioral change in QTabBar the tabs to choose between the curve editors "factory presets" and "custom presets" got lost. Reordering the function calls made it appear again. Prevent the user from assigning the same name to different easing curves. Fixes: QDS-7720 Fixes: QDS-7721 Change-Id: I247309824868625d2e581f54590dd4c3d99528dd Reviewed-by: Reviewed-by: Ali Kianian Reviewed-by: Thomas Hartmann --- .../timelineeditor/easingcurvedialog.cpp | 7 ++-- .../timelineeditor/preseteditor.cpp | 39 ++++++++----------- .../components/timelineeditor/preseteditor.h | 8 ++-- 3 files changed, 24 insertions(+), 30 deletions(-) diff --git a/src/plugins/qmldesigner/components/timelineeditor/easingcurvedialog.cpp b/src/plugins/qmldesigner/components/timelineeditor/easingcurvedialog.cpp index 79f8141bf0b..c42c580991d 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/easingcurvedialog.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/easingcurvedialog.cpp @@ -91,6 +91,8 @@ EasingCurveDialog::EasingCurveDialog(const QList &frames, QWidget *pa presetBar->setDrawBase(false); presetBar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); + m_presets->initialize(presetBar); + auto *durationLabel = new QLabel("Duration (ms)"); auto *durationEdit = new QSpinBox; durationEdit->setMaximum(std::numeric_limits::max()); @@ -107,6 +109,8 @@ EasingCurveDialog::EasingCurveDialog(const QList &frames, QWidget *pa m_durationLayout->insertSpacing(4, hSpacing); m_durationLayout->addStretch(hSpacing); + m_splineEditor->setDuration(durationEdit->value()); + m_buttons->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred); auto callButtonsClicked = [this](QAbstractButton *button) { buttonsClicked(m_buttons->standardButton(button)); @@ -152,9 +156,6 @@ EasingCurveDialog::EasingCurveDialog(const QList &frames, QWidget *pa connect(animateButton, &QPushButton::clicked, m_splineEditor, &SplineEditor::animate); - m_presets->initialize(presetBar); - - m_splineEditor->setDuration(durationEdit->value()); resize(QSize(1421, 918)); } diff --git a/src/plugins/qmldesigner/components/timelineeditor/preseteditor.cpp b/src/plugins/qmldesigner/components/timelineeditor/preseteditor.cpp index d57caf0e1a4..bf968523abc 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/preseteditor.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/preseteditor.cpp @@ -55,6 +55,19 @@ constexpr int spacingg = 5; const QColor background = Qt::white; + +QString makeNameUnique(const QString& name, const QStringList& currentNames) +{ + QString n = name; + int idx = 0; + while (true) { + if (!currentNames.contains(n)) + return n; + n = name + "_" + QString::number(idx++); + } + return {}; +} + PresetItemDelegate::PresetItemDelegate(const QColor& background) : QStyledItemDelegate() , m_background(background) @@ -388,7 +401,7 @@ void PresetList::createItem() { EasingCurve curve; curve.makeDefault(); - createItem(createUniqueName(), curve); + createItem(makeNameUnique("Default", allNames()), curve); } void PresetList::createItem(const QString &name, const EasingCurve &curve) @@ -424,27 +437,6 @@ void PresetList::setItemData(const QModelIndex &index, const QVariant &curve, co } } -QString PresetList::createUniqueName() const -{ - QStringList names = allNames(); - auto nameIsUnique = [&](const QString &name) { - auto iter = std::find(names.begin(), names.end(), name); - if (iter == names.end()) - return true; - else - return false; - }; - - int counter = 0; - QString tmp("Default"); - QString name = tmp; - - while (!nameIsUnique(name)) - name = tmp + QString(" %1").arg(counter++); - - return name; -} - QStringList PresetList::allNames() const { QStringList names; @@ -551,7 +543,8 @@ bool PresetEditor::writePresets(const EasingCurve &curve) if (ok && !name.isEmpty()) { activate(m_customs->index()); - m_customs->createItem(name, curve); + QString uname = makeNameUnique(name, m_customs->allNames()); + m_customs->createItem(uname, curve); } } diff --git a/src/plugins/qmldesigner/components/timelineeditor/preseteditor.h b/src/plugins/qmldesigner/components/timelineeditor/preseteditor.h index 4e805fcf2b2..e9eed265383 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/preseteditor.h +++ b/src/plugins/qmldesigner/components/timelineeditor/preseteditor.h @@ -38,6 +38,8 @@ namespace QmlDesigner { class EasingCurve; class NamedEasingCurve; +QString makeNameUnique(const QString& name, const QStringList& currentNames); + class PresetItemDelegate : public QStyledItemDelegate { Q_OBJECT @@ -87,6 +89,8 @@ public: QColor curveColor() const; + QStringList allNames() const; + void initialize(int index); void readPresets(); @@ -111,12 +115,8 @@ protected: const QVector &roles = QVector()) override; private: - QStringList allNames() const; - QList storedCurves() const; - QString createUniqueName() const; - void removeSelectedItem(); private: From a2c052089b87a0a92618b95414432f41b04b8f90 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 20 Oct 2022 15:36:28 +0200 Subject: [PATCH 31/97] Autotest: Don't parse tests without files Previously the "Scan for tests" dialog would pop up momentarily during project loading, even though no files were loaded yet. Partial fix for: QTCREATORBUG-27785 Change-Id: I4087ba23d00a628465dd1532a725d9bcc37dec30 Reviewed-by: Christian Stenger --- src/plugins/autotest/testcodeparser.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/autotest/testcodeparser.cpp b/src/plugins/autotest/testcodeparser.cpp index 27175552414..bb46684844c 100644 --- a/src/plugins/autotest/testcodeparser.cpp +++ b/src/plugins/autotest/testcodeparser.cpp @@ -293,7 +293,11 @@ void TestCodeParser::scanForTests(const Utils::FilePaths &fileList, qCDebug(LOG) << "File list empty (FullParse) - trying again in a sec"; emitUpdateTestTree(); return; + } else if (list.size() == 1 && list.first() == project->projectFilePath()) { + qCDebug(LOG) << "File list contains only the project file."; + return; } + qCDebug(LOG) << "setting state to FullParse (scanForTests)"; m_parserState = FullParse; } else { From 91257b3e760f925ef25ae675beac7a6fe8a3f740 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 26 Oct 2022 13:40:55 +0200 Subject: [PATCH 32/97] Bump version to 9.0.0-rc1 Change-Id: If9f046539e70e8aba9af367472b76bac853198b8 Reviewed-by: Christian Stenger --- cmake/QtCreatorIDEBranding.cmake | 6 +++--- qbs/modules/qtc/qtc.qbs | 6 +++--- qtcreator_ide_branding.pri | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/cmake/QtCreatorIDEBranding.cmake b/cmake/QtCreatorIDEBranding.cmake index 2b9a50628a4..f818306d15e 100644 --- a/cmake/QtCreatorIDEBranding.cmake +++ b/cmake/QtCreatorIDEBranding.cmake @@ -1,6 +1,6 @@ -set(IDE_VERSION "8.0.83") # The IDE version. -set(IDE_VERSION_COMPAT "8.0.83") # The IDE Compatibility version. -set(IDE_VERSION_DISPLAY "9.0.0-beta2") # The IDE display version. +set(IDE_VERSION "8.0.84") # The IDE version. +set(IDE_VERSION_COMPAT "8.0.84") # The IDE Compatibility version. +set(IDE_VERSION_DISPLAY "9.0.0-rc1") # The IDE display version. set(IDE_COPYRIGHT_YEAR "2022") # The IDE current copyright year. set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation. diff --git a/qbs/modules/qtc/qtc.qbs b/qbs/modules/qtc/qtc.qbs index dbf9a7c9924..0d65a96b392 100644 --- a/qbs/modules/qtc/qtc.qbs +++ b/qbs/modules/qtc/qtc.qbs @@ -6,16 +6,16 @@ import qbs.Utilities Module { Depends { name: "cpp"; required: false } - property string qtcreator_display_version: '9.0.0-beta2' + property string qtcreator_display_version: '9.0.0-rc1' property string ide_version_major: '8' property string ide_version_minor: '0' - property string ide_version_release: '83' + property string ide_version_release: '84' property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' + ide_version_release property string ide_compat_version_major: '8' property string ide_compat_version_minor: '0' - property string ide_compat_version_release: '83' + property string ide_compat_version_release: '84' property string qtcreator_compat_version: ide_compat_version_major + '.' + ide_compat_version_minor + '.' + ide_compat_version_release diff --git a/qtcreator_ide_branding.pri b/qtcreator_ide_branding.pri index 1d81a2c16f0..ffc9123ae78 100644 --- a/qtcreator_ide_branding.pri +++ b/qtcreator_ide_branding.pri @@ -1,6 +1,6 @@ -QTCREATOR_VERSION = 8.0.83 -QTCREATOR_COMPAT_VERSION = 8.0.83 -QTCREATOR_DISPLAY_VERSION = 9.0.0-beta2 +QTCREATOR_VERSION = 8.0.84 +QTCREATOR_COMPAT_VERSION = 8.0.84 +QTCREATOR_DISPLAY_VERSION = 9.0.0-rc1 QTCREATOR_COPYRIGHT_YEAR = 2022 IDE_DISPLAY_NAME = Qt Creator From 38c8e200710eb1c452705f2451e4f6260b3309fa Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 20 Oct 2022 15:35:38 +0200 Subject: [PATCH 33/97] QMake: Remove unnecessary build dir changed Previously every time a qmake project was built, the "buildDirectoryChanged()" was emitted, leading to a complete reparse of the project file, tests, qml files and qml imports. To keep "QmakeBuildConfiguration::updateProblemLabel" be called, we re-introduce the "buildDirectoryInitialized" signal. Task-number: QTCREATORBUG-27785 Change-Id: I32d881eacb8cf26050c33da643c74c2cab4dc22d Reviewed-by: Christian Kandeler --- src/plugins/projectexplorer/buildconfiguration.h | 1 + src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp | 2 ++ src/plugins/qmakeprojectmanager/qmakestep.cpp | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h index 59649e5defc..815daeda6bf 100644 --- a/src/plugins/projectexplorer/buildconfiguration.h +++ b/src/plugins/projectexplorer/buildconfiguration.h @@ -116,6 +116,7 @@ public: signals: void environmentChanged(); + void buildDirectoryInitialized(); void buildDirectoryChanged(); void enabledChanged(); void buildTypeChanged(); diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp index 899ed4e4a4f..c1cb54d3e12 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp @@ -153,6 +153,8 @@ QmakeBuildConfiguration::QmakeBuildConfiguration(Target *target, Id id) }); buildDirectoryAspect()->allowInSourceBuilds(target->project()->projectDirectory()); + connect(this, &BuildConfiguration::buildDirectoryInitialized, + this, &QmakeBuildConfiguration::updateProblemLabel); connect(this, &BuildConfiguration::buildDirectoryChanged, this, &QmakeBuildConfiguration::updateProblemLabel); connect(this, &QmakeBuildConfiguration::qmakeBuildConfigurationChanged, diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index f29e0abb64b..0a075eb3234 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -306,7 +306,7 @@ bool QMakeStep::processSucceeded(int exitCode, QProcess::ExitStatus status) bool result = AbstractProcessStep::processSucceeded(exitCode, status); if (!result) m_needToRunQMake = true; - emit buildConfiguration()->buildDirectoryChanged(); + emit buildConfiguration()->buildDirectoryInitialized(); return result; } From 37640257db73be17c02e936bfb3993fc3e6216af Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 25 Oct 2022 10:52:52 +0200 Subject: [PATCH 34/97] Editor: Fix painting highlights on scrollbar The document layout rounds up the height of lines in QTextLayout::boundingRect, so we have to do the same for calculating the position of highlights on the scrollbar. Fixes: QTCREATORBUG-28299 Change-Id: I36496ebec7fe7861feff7cb8a2647a11ee078b8f Reviewed-by: Reviewed-by: Christian Stenger --- src/plugins/coreplugin/find/highlightscrollbarcontroller.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/coreplugin/find/highlightscrollbarcontroller.cpp b/src/plugins/coreplugin/find/highlightscrollbarcontroller.cpp index 75736bb6810..222631ad140 100644 --- a/src/plugins/coreplugin/find/highlightscrollbarcontroller.cpp +++ b/src/plugins/coreplugin/find/highlightscrollbarcontroller.cpp @@ -360,7 +360,7 @@ void HighlightScrollBarController::setScrollArea(QAbstractScrollArea *scrollArea double HighlightScrollBarController::lineHeight() const { - return m_lineHeight; + return ceil(m_lineHeight); } void HighlightScrollBarController::setLineHeight(double lineHeight) From ed0727e88fac9b8fb9491fa2dec31683f38c4e37 Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Tue, 25 Oct 2022 16:37:23 +0200 Subject: [PATCH 35/97] QmlDesigner: Add option for Qt 6.4 Change-Id: I7548a680a5773d7d2799fa5998bdc0956fb2e9c2 Reviewed-by: Tim Jenssen Reviewed-by: Reviewed-by: Samuel Ghinet Reviewed-by: Thomas Hartmann --- .../newprojectdialog/imports/NewProjectDialog/Details.qml | 1 + .../studio_templates/projects/application-3d/wizard.json | 8 ++++++++ .../studio_templates/projects/application/wizard.json | 7 +++++++ .../projects/desktop-launcher/wizard.json | 7 +++++++ .../studio_templates/projects/mobile-scroll/wizard.json | 7 +++++++ .../studio_templates/projects/mobile-stack/wizard.json | 7 +++++++ .../studio_templates/projects/mobile-swipe/wizard.json | 7 +++++++ 7 files changed, 44 insertions(+) diff --git a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml index a5ba5afdb3e..26ba4f43cf5 100644 --- a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml +++ b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/Details.qml @@ -423,6 +423,7 @@ Item { ListElement { name: "Qt 5.15" } ListElement { name: "Qt 6.2" } ListElement { name: "Qt 6.3" } + ListElement { name: "Qt 6.4" } } onActivated: (index) => { diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json index 3510d3e190b..6c6949442c6 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-3d/wizard.json @@ -264,6 +264,14 @@ 'TargetQuickVersion': '6.3', 'TargetQuick3DVersion': '6.3' })" + }, + { + "trKey": "Qt 6.4", + "value": + "({ + 'TargetQuickVersion': '6.4', + 'TargetQuick3DVersion': '6.4' + })" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json index 68ffb6cff17..235116a1f4c 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application/wizard.json @@ -261,6 +261,13 @@ "({ 'TargetQuickVersion': '6.3' })" + }, + { + "trKey": "Qt 6.4", + "value": + "({ + 'TargetQuickVersion': '6.4' + })" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json index ab1830752b1..851e3780899 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/desktop-launcher/wizard.json @@ -259,6 +259,13 @@ "({ 'TargetQuickVersion': '6.3' })" + }, + { + "trKey": "Qt 6.4", + "value": + "({ + 'TargetQuickVersion': '6.4' + })" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json index 1a9e07cb63c..87d0c948604 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json @@ -216,6 +216,13 @@ "({ 'TargetQuickVersion': '6.3' })" + }, + { + "trKey": "Qt 6.4", + "value": + "({ + 'TargetQuickVersion': '6.4' + })" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json index 2e07c4725a1..642cd7a8e46 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-stack/wizard.json @@ -216,6 +216,13 @@ "({ 'TargetQuickVersion': '6.3' })" + }, + { + "trKey": "Qt 6.4", + "value": + "({ + 'TargetQuickVersion': '6.4' + })" } ] } diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json index 422db173497..a2ece501ad2 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-swipe/wizard.json @@ -216,6 +216,13 @@ "({ 'TargetQuickVersion': '6.3' })" + }, + { + "trKey": "Qt 6.4", + "value": + "({ + 'TargetQuickVersion': '6.4' + })" } ] } From 5b7729a21a21fbf438ac85b5f66f1cd27f5d1061 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 26 Oct 2022 15:52:18 +0200 Subject: [PATCH 36/97] QbsProjectManager: Fix displayed build variant in build step The initialization was lost in 2ecfda056bf283cc57132481e4fa11642a02491f. Change-Id: I40db0ea26de74aa6420ecc50c473bbcb22891238 Reviewed-by: Christian Stenger Reviewed-by: Qt CI Bot --- .../qbsprojectmanager/qbsbuildstep.cpp | 30 ++++++++----------- src/plugins/qbsprojectmanager/qbsbuildstep.h | 1 - 2 files changed, 13 insertions(+), 18 deletions(-) diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp index 5ac88bb4665..d0b66a15491 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp +++ b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp @@ -209,8 +209,9 @@ QbsBuildStep::QbsBuildStep(BuildStepList *bsl, Utils::Id id) : m_buildVariant = addAspect(); m_buildVariant->setDisplayName(QbsProjectManager::Tr::tr("Build variant:")); m_buildVariant->setDisplayStyle(SelectionAspect::DisplayStyle::ComboBox); - m_buildVariant->addOption(ProjectExplorer::Tr::tr("Debug")); - m_buildVariant->addOption(ProjectExplorer::Tr::tr("Release")); + m_buildVariant->addOption({ProjectExplorer::Tr::tr("Debug"), {}, Constants::QBS_VARIANT_DEBUG}); + m_buildVariant->addOption({ProjectExplorer::Tr::tr("Release"), {}, + Constants::QBS_VARIANT_RELEASE}); m_selectedAbis = addAspect(); m_selectedAbis->setLabelText(QbsProjectManager::Tr::tr("ABIs:")); @@ -263,7 +264,9 @@ QbsBuildStep::QbsBuildStep(BuildStepList *bsl, Utils::Id id) : connect(m_cleanInstallDir, &BaseAspect::changed, this, &QbsBuildStep::updateState); connect(m_forceProbes, &BaseAspect::changed, this, &QbsBuildStep::updateState); - connect(m_buildVariant, &SelectionAspect::changed, this, &QbsBuildStep::changeBuildVariant); + connect(m_buildVariant, &SelectionAspect::changed, this, [this] { + setBuildVariant(m_buildVariant->itemValue().toString()); + }); connect(m_selectedAbis, &SelectionAspect::changed, [this] { setConfiguredArchitectures(m_selectedAbis->selectedArchitectures()); }); } @@ -358,13 +361,16 @@ void QbsBuildStep::setQbsConfiguration(const QVariantMap &config) { QVariantMap tmp = config; tmp.insert(Constants::QBS_CONFIG_PROFILE_KEY, qbsBuildSystem()->profile()); - if (!tmp.contains(Constants::QBS_CONFIG_VARIANT_KEY)) - tmp.insert(Constants::QBS_CONFIG_VARIANT_KEY, - QString::fromLatin1(Constants::QBS_VARIANT_DEBUG)); - + QString buildVariant = tmp.value(Constants::QBS_CONFIG_VARIANT_KEY).toString(); + if (buildVariant.isEmpty()) { + buildVariant = Constants::QBS_VARIANT_DEBUG; + tmp.insert(Constants::QBS_CONFIG_VARIANT_KEY, buildVariant); + } if (tmp == m_qbsConfiguration) return; m_qbsConfiguration = tmp; + if (m_buildVariant) + m_buildVariant->setValue(m_buildVariant->indexForItemValue(buildVariant)); if (ProjectExplorer::BuildConfiguration *bc = buildConfiguration()) emit bc->buildTypeChanged(); emit qbsConfigurationChanged(); @@ -760,16 +766,6 @@ void QbsBuildStepConfigWidget::updatePropertyEdit(const QVariantMap &data) propertyEdit->setText(ProcessArgs::joinArgs(propertyList)); } -void QbsBuildStep::changeBuildVariant() -{ - QString variant; - if (m_buildVariant->value() == 1) - variant = Constants::QBS_VARIANT_RELEASE; - else - variant = Constants::QBS_VARIANT_DEBUG; - setBuildVariant(variant); -} - void QbsBuildStepConfigWidget::changeUseDefaultInstallDir(bool useDefault) { const GuardLocker locker(m_ignoreChanges); diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.h b/src/plugins/qbsprojectmanager/qbsbuildstep.h index faf12c31686..644acabe578 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildstep.h +++ b/src/plugins/qbsprojectmanager/qbsbuildstep.h @@ -89,7 +89,6 @@ private: void finish(); void updateState(); - void changeBuildVariant(); QStringList configuredArchitectures() const; QVariantMap m_qbsConfiguration; From 565bb8052ff869cb103fcbe0fe34ed7a3ee1070f Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Wed, 26 Oct 2022 15:42:47 +0200 Subject: [PATCH 37/97] QmlDesigner: Add option to allow multiple projects Setting QML/Designer/AllowMultipleProjects to true allows multiple projects. Task-number: QDS-7865 Change-Id: Ib44653e48cfbdb439c18dc2d3c57a4ae2ab0ee43 Reviewed-by: Tim Jenssen Reviewed-by: Qt CI Bot --- src/plugins/qmlprojectmanager/qmlproject.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index ba00ad797fd..4a9737d091f 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -88,6 +88,14 @@ static int preferedQtTarget(Target *target) return 5; } +static bool allowOnlySingleProject() +{ + QSettings *settings = Core::ICore::settings(); + const QString qdsAllowMultipleProjects = "QML/Designer/AllowMultipleProjects"; + + return !settings->value(qdsAllowMultipleProjects, false).toBool(); +} + const char openInQDSAppSetting[] = "OpenInQDSApp"; Utils::FilePaths QmlProject::getUiQmlFilesForFolder(const Utils::FilePath &folder) @@ -110,9 +118,10 @@ QmlProject::QmlProject(const Utils::FilePath &fileName) setBuildSystemCreator([](Target *t) { return new QmlBuildSystem(t); }); if (QmlProject::isQtDesignStudio()) { - - EditorManager::closeAllDocuments(); - SessionManager::closeAllProjects(); + if (allowOnlySingleProject()) { + EditorManager::closeAllDocuments(); + SessionManager::closeAllProjects(); + } m_openFileConnection = connect(this, From e003a0272188461aed5bf168cc815caa34d87a06 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Wed, 26 Oct 2022 22:53:40 +0300 Subject: [PATCH 38/97] VCS: Fix resolving active directory for temp editors Amends c666c938822dbdd7f74bc44a6b31bee171ee5c63. Change-Id: Ib7aeb9616d3d527f829ece2a39eb5ddf77f9431e Reviewed-by: Jarek Kobus --- src/plugins/vcsbase/vcsbaseplugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/vcsbase/vcsbaseplugin.cpp b/src/plugins/vcsbase/vcsbaseplugin.cpp index 426ad149bda..64d023cccfd 100644 --- a/src/plugins/vcsbase/vcsbaseplugin.cpp +++ b/src/plugins/vcsbase/vcsbaseplugin.cpp @@ -263,8 +263,8 @@ void StateListener::slotStateChanged() } if (state.currentFile.isDir()) { - state.currentFile.clear(); state.currentFileDirectory = state.currentFile.absoluteFilePath(); + state.currentFile.clear(); } else { state.currentFileDirectory = state.currentFile.absolutePath(); state.currentFileName = state.currentFile.fileName(); From 26bb95331b4cda149c862770f9a92339dfc8dd1b Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 26 Oct 2022 15:02:54 +0200 Subject: [PATCH 39/97] Editor: fix FontSettings::lineSpacing for zoomed fonts Change-Id: Ia7ad3a877c56fb9cd962592b6d3e967beb9002dc Reviewed-by: Reviewed-by: Christian Stenger --- src/plugins/texteditor/fontsettings.cpp | 22 +++++++--------------- src/plugins/texteditor/fontsettings.h | 1 - 2 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/plugins/texteditor/fontsettings.cpp b/src/plugins/texteditor/fontsettings.cpp index f8f2f3db198..887398ad249 100644 --- a/src/plugins/texteditor/fontsettings.cpp +++ b/src/plugins/texteditor/fontsettings.cpp @@ -39,8 +39,7 @@ FontSettings::FontSettings() : m_fontSize(defaultFontSize()), m_fontZoom(100), m_lineSpacing(100), - m_antialias(DEFAULT_ANTIALIAS), - m_lineSpacingCache(0) + m_antialias(DEFAULT_ANTIALIAS) { } @@ -261,7 +260,6 @@ void FontSettings::clearCaches() { m_formatCache.clear(); m_textCharFormatCache.clear(); - m_lineSpacingCache = 0; } QTextCharFormat FontSettings::toTextCharFormat(TextStyles textStyles) const @@ -337,17 +335,12 @@ void FontSettings::setFontZoom(int zoom) qreal FontSettings::lineSpacing() const { - if (m_lineSpacing == 100) { - QFontMetricsF fm(font()); - return fm.lineSpacing(); - } - - if (qFuzzyIsNull(m_lineSpacingCache)) { - auto currentFont = font(); - currentFont.setPointSize(m_fontSize * m_fontZoom / 100); - m_lineSpacingCache = QFontMetricsF(currentFont).lineSpacing() / 100 * m_lineSpacing; - } - return m_lineSpacingCache; + QFont currentFont = font(); + currentFont.setPointSize(m_fontSize * m_fontZoom / 100); + qreal spacing = QFontMetricsF(currentFont).lineSpacing(); + if (m_lineSpacing != 100) + spacing *= 100 / m_lineSpacing; + return spacing; } int FontSettings::relativeLineSpacing() const @@ -358,7 +351,6 @@ int FontSettings::relativeLineSpacing() const void FontSettings::setRelativeLineSpacing(int relativeLineSpacing) { m_lineSpacing = relativeLineSpacing; - m_lineSpacingCache = 0; } QFont FontSettings::font() const diff --git a/src/plugins/texteditor/fontsettings.h b/src/plugins/texteditor/fontsettings.h index e164664baa1..344a3548f2e 100644 --- a/src/plugins/texteditor/fontsettings.h +++ b/src/plugins/texteditor/fontsettings.h @@ -99,7 +99,6 @@ private: ColorScheme m_scheme; mutable QHash m_formatCache; mutable QHash m_textCharFormatCache; - mutable qreal m_lineSpacingCache; }; } // namespace TextEditor From 774b74583ef8c82e16c41b9fad1faec0601c9c28 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 26 Oct 2022 11:44:11 +0200 Subject: [PATCH 40/97] Cppcheck: Do not start non-existing tool Just pollutes the General Messages pane, so skip execution if tool is not existing. Change-Id: Ib78e3a8ccd992ff2d58f183102c778c800156b89 Reviewed-by: Christian Kandeler --- src/plugins/cppcheck/cppcheckrunner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/cppcheck/cppcheckrunner.cpp b/src/plugins/cppcheck/cppcheckrunner.cpp index c31ff515a51..92bdd59c526 100644 --- a/src/plugins/cppcheck/cppcheckrunner.cpp +++ b/src/plugins/cppcheck/cppcheckrunner.cpp @@ -110,7 +110,7 @@ QString CppcheckRunner::currentCommand() const void CppcheckRunner::checkQueued() { - if (m_queue.isEmpty() || m_binary.isEmpty()) + if (m_queue.isEmpty() || !m_binary.isExecutableFile()) return; FilePaths files = m_queue.begin().value(); From 913c6f037c9f44c9b897dfeae0f317c44a58ba09 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Thu, 27 Oct 2022 09:09:06 +0300 Subject: [PATCH 41/97] VCS: Remove export for inline functions vcsenums.h:29:28: warning: inline function 'void VcsBase::operator|=(VcsBase::RunFlags&, VcsBase::RunFlags)' declared as dllimport: attribute ignored [-Wattributes] 29 | inline void VCSBASE_EXPORT operator|=(RunFlags &p, RunFlags r) | ^~~~~~~~ Change-Id: I0490965260302009bb49ed1c4be994496cbe186f Reviewed-by: Jarek Kobus --- src/plugins/vcsbase/vcsenums.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/vcsbase/vcsenums.h b/src/plugins/vcsbase/vcsenums.h index 16037af04ad..279c31dd37e 100644 --- a/src/plugins/vcsbase/vcsenums.h +++ b/src/plugins/vcsbase/vcsenums.h @@ -26,24 +26,24 @@ enum class RunFlags { NoOutput = SuppressStdErr | SuppressFailMessage | SuppressCommandLogging }; -inline void VCSBASE_EXPORT operator|=(RunFlags &p, RunFlags r) +inline void operator|=(RunFlags &p, RunFlags r) { p = RunFlags(int(p) | int(r)); } -inline RunFlags VCSBASE_EXPORT operator|(RunFlags p, RunFlags r) +inline RunFlags operator|(RunFlags p, RunFlags r) { return RunFlags(int(p) | int(r)); } -inline void VCSBASE_EXPORT operator&=(RunFlags &p, RunFlags r) +inline void operator&=(RunFlags &p, RunFlags r) { p = RunFlags(int(p) & int(r)); } // Note, that it returns bool, not RunFlags. // It's only meant for testing whether a specific bit is set. -inline bool VCSBASE_EXPORT operator&(RunFlags p, RunFlags r) +inline bool operator&(RunFlags p, RunFlags r) { return bool(int(p) & int(r)); } From 86a24b707d1c499897a2e2bd31dd3ca49cb2bae6 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 26 Oct 2022 17:21:03 +0200 Subject: [PATCH 42/97] Doc: Add info and examples of using CMake presets Task-number: QTCREATORBUG-27876 Change-Id: Iaaea164d7a8395d6ddc7580db72790187b719eda Reviewed-by: Cristian Adam Reviewed-by: --- .../qtcreator-cmake-presets-configure.webp | Bin 0 -> 8336 bytes .../qtcreator-cmake-presets-environment.webp | Bin 0 -> 12604 bytes .../creator-projects-cmake-building.qdoc | 171 +++++++++++++++++- 3 files changed, 168 insertions(+), 3 deletions(-) create mode 100644 doc/qtcreator/images/qtcreator-cmake-presets-configure.webp create mode 100644 doc/qtcreator/images/qtcreator-cmake-presets-environment.webp diff --git a/doc/qtcreator/images/qtcreator-cmake-presets-configure.webp b/doc/qtcreator/images/qtcreator-cmake-presets-configure.webp new file mode 100644 index 0000000000000000000000000000000000000000..7b86c52530e7edbbe33ddf50cfd077b67ec6414f GIT binary patch literal 8336 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 Jx0|Li0sucTGgbfq literal 0 HcmV?d00001 diff --git a/doc/qtcreator/images/qtcreator-cmake-presets-environment.webp b/doc/qtcreator/images/qtcreator-cmake-presets-environment.webp new file mode 100644 index 0000000000000000000000000000000000000000..03a514fce26abcdd6da9dcc6d02b3964f86e2700 GIT binary patch literal 12604 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 E01tI$W&i*H literal 0 HcmV?d00001 diff --git a/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc b/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc index 1b675abe6ec..b3195cfd210 100644 --- a/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc +++ b/doc/qtcreator/src/cmake/creator-projects-cmake-building.qdoc @@ -14,6 +14,7 @@ \QC creates an initial configuration for you based on the kit settings and displays it in \uicontrol {Initial Configuration} in the \l{Specifying Build Settings}{Build Settings} of the project. + Alternatively, you can use CMake presets to configure CMake. The \uicontrol Configuration field displays the effective CMake call that is constructed by using the values of the \uicontrol {Build directory} and @@ -40,7 +41,7 @@ variables, see \l{CMake Variable Reference}. You can specify additional CMake options, such as \c {--find-debug}, - \c {--preset}, \c {--trace-expand}, or \c {--warn-uninitialized}, in + \c {--trace-expand}, or \c {--warn-uninitialized}, in \uicontrol {Additional CMake options}. For more information about the available options, click the link in the field name or see \l{CMake: cmake(1)}. @@ -60,9 +61,173 @@ Create the presets files in the format described in \l{https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html} - {cmake-presets(7)} and store the in project's root directory. + {cmake-presets(7)} and store them in project's root directory. - To use the preset files, specify the \c {--preset} option for your project. + \QC supports presets up to version 3 (introduced in CMake 3.21), but version + checking is not enforced. All the fields from version 3 are read and used if + present. Test presets are not supported. + + You can import the presets the first time you \l {Opening Projects} + {open a project}, when no \c CMakeLists.txt.user file exists or you have + disabled all kits in the project. To update changes to the + \c CMakePresets.json file, delete the \c CMakeLists.txt.user file. + + \image qtcreator-cmake-presets-configure.webp "Opening a project that contains Cmake presets" + + You can view the presets in the \uicontrol {Initial Configuration} field and + in the environment configuration field below it. + + \image qtcreator-cmake-presets-environment.webp "CMake environment configuration" + + \section2 Configure Presets + + The following configure presets instruct CMake to use the default generator + on the platform and specify the build directory for all build types. + \c NOT_COMMON_VALUE is displayed in \uicontrol {Initial Parameters} + and \c AN_ENVIRONMENT_FLAG in the environment configuration field. + + \badcode + { + "version": 1, + "configurePresets": [ + { + "name": "preset", + "displayName": "preset", + "binaryDir": "${sourceDir}/build/preset", + "cacheVariables": { + "NOT_COMMON_VALUE": "NOT_COMMON_VALUE" + }, + "environment": { + "AN_ENVIRONMENT_FLAG": "1" + } + } + ] + } + \endcode + + \section2 MinGW Example + + The following example configures a Qt project with: + + \list + \li MinGW compiler + \li build directory – \c /build-release + \li build type – \c CMAKE_BUILD_TYPE as \c Release + \li generator – MinGW Makefiles + \li path to a CMake executable + \li path to the Qt installation via \c CMAKE_PREFIX_PATH + \endlist + + \badcode + { + "version": 1, + "configurePresets": [ + { + "name": "mingw", + "displayName": "MinGW 11.2.0", + "generator": "MinGW Makefiles", + "binaryDir": "${sourceDir}/build-release", + "cmakeExecutable": "C:/Qt/Tools/CMake_64/bin/cmake.exe", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_PREFIX_PATH": "C:/Qt/6.4.0/mingw_64" + }, + "environment": { + "PATH": "C:/Qt/Tools/mingw1120_64/bin;$penv{PATH}" + } + } + ] + } + \endcode + + To speed up the process on Windows, specify the \c CMAKE_C_COMPILER and + \c CMAKE_CXX_COMPILER in the \c cacheVariables section. + + \section2 Ninja Generator Example + + The following configure and build presets set Ninja Multi-Config as the + generator, add \c Debug and \c Release build steps, and specify the path + to \c ninja.exe as a value of the \c CMAKE_MAKE_PROGRAM variable: + + \badcode + { + "version": 2, + "configurePresets": [ + { + "name": "ninja-nmc", + "displayName": "Ninja Multi-Config MinGW", + "generator": "Ninja Multi-Config", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug;Release", + "CMAKE_PREFIX_PATH": "C:/Qt/6.4.0/mingw_64" + "CMAKE_MAKE_PROGRAM": "C:/Qt/Tools/Ninja/ninja.exe" + }, + "environment": { + "PATH": "c:/Qt/Tools/mingw1120_64/bin;$penv{PATH}" + } + } + ], + "buildPresets": [ + { + "name": "release", + "displayName": "Ninja Release", + "configurePreset": "ninja-nmc", + "configuration": "Release" + }, + { + "name": "debug", + "displayName": "Ninja Debug", + "configurePreset": "ninja-nmc", + "configuration": "Debug" + } + ] + } + \endcode + + This example assumes that the CMake executable path is set in + \uicontrol Edit > \uicontrol Preferences > \uicontrol CMake > + \uicontrol Tools. + + \section2 Using Conditions + + The following configure presets are used if they match \c condition. That is, + if the \c hostSystemName equals \c Linux, the \c linux presets are used and + if it equals \c Windows, the \c windows presets are used. + + \badcode + { + "version": 3, + "configurePresets": [ + { + "name": "linux", + "displayName": "Linux GCC", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "CMAKE_PREFIX_PATH": "$env{HOME}/Qt/6.4.0/gcc_64" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Linux" + } + }, + { + "name": "windows", + "displayName": "Windows MSVC", + "binaryDir": "${sourceDir}/build", + "cacheVariables": { + "CMAKE_PREFIX_PATH": "$env{SYSTEMDRIVE}/Qt/6.4.0/msvc2019_64" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + } + } + ] + } + \endcode \section1 Multi-Config Support From af0797f0cc481e54438034b4aafe071a9e286fd4 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 27 Oct 2022 08:01:52 +0200 Subject: [PATCH 43/97] Utils: Workaround for slow data upload The deviceshell script is slow to upload large amounts of stdin data. Use QtcProcess directly if the size of the data exceeds 100kb. Change-Id: Ide63bfd973d31f7f076ab7cd4be73cc85c9239ea Reviewed-by: David Schulz --- src/libs/utils/deviceshell.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libs/utils/deviceshell.cpp b/src/libs/utils/deviceshell.cpp index 4cd8642ec0f..1d4aef5273c 100644 --- a/src/libs/utils/deviceshell.cpp +++ b/src/libs/utils/deviceshell.cpp @@ -74,8 +74,14 @@ QStringList DeviceShell::missingFeatures() const { return m_missingFeatures; } RunResult DeviceShell::run(const CommandLine &cmd, const QByteArray &stdInData) { - if (m_shellScriptState == State::NoScript) { - // Fallback ... + // If the script failed to install, use QtcProcess directly instead. + bool useProcess = m_shellScriptState == State::NoScript; + + // Transferring large amounts of stdInData is slow via the shell script. + // Use QtcProcess directly if the size exceeds 100kb. + useProcess |= stdInData.size() > (1024 * 100); + + if (useProcess) { QtcProcess proc; proc.setCommand(createFallbackCommand(cmd)); proc.setWriteData(stdInData); From 87cf82cf06553363b40845278cc25f7a7693f538 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 27 Oct 2022 08:33:48 +0200 Subject: [PATCH 44/97] Utils: Fix inconsistent debug output Change-Id: Iccfae5e70e4f0992cbf16e05688547e54c637a27 Reviewed-by: David Schulz --- src/libs/utils/deviceshell.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libs/utils/deviceshell.cpp b/src/libs/utils/deviceshell.cpp index 1d4aef5273c..ef6814e9c4e 100644 --- a/src/libs/utils/deviceshell.cpp +++ b/src/libs/utils/deviceshell.cpp @@ -83,7 +83,9 @@ RunResult DeviceShell::run(const CommandLine &cmd, const QByteArray &stdInData) if (useProcess) { QtcProcess proc; - proc.setCommand(createFallbackCommand(cmd)); + const CommandLine fallbackCmd = createFallbackCommand(cmd); + qCDebug(deviceShellLog) << "Running fallback:" << fallbackCmd; + proc.setCommand(fallbackCmd); proc.setWriteData(stdInData); proc.start(); @@ -111,7 +113,7 @@ RunResult DeviceShell::run(const CommandLine &cmd, const QByteArray &stdInData) .arg(id) .arg(QString::fromLatin1(stdInData.toBase64())) .arg(cmd.toUserOutput()); - qCDebug(deviceShellLog) << "Running:" << command; + qCDebug(deviceShellLog) << "Running via shell:" << command; m_shellProcess->writeRaw(command.toUtf8()); }); From ba99a7f921143a5b6e1ba24ba274330e425fbf74 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 27 Oct 2022 07:40:27 +0200 Subject: [PATCH 45/97] AutoTest: Fix crash Remove the unneeded stunt when clearing cache which only led to crashes. Fixes: QTCREATORBUG-28269 Change-Id: I908bcbee0f49369a589862cd8fbd3253444246c3 Reviewed-by: David Schulz --- src/plugins/autotest/testresultdelegate.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/plugins/autotest/testresultdelegate.cpp b/src/plugins/autotest/testresultdelegate.cpp index 41ff5f98294..21d8f61b040 100644 --- a/src/plugins/autotest/testresultdelegate.cpp +++ b/src/plugins/autotest/testresultdelegate.cpp @@ -155,16 +155,9 @@ void TestResultDelegate::currentChanged(const QModelIndex ¤t, const QModel void TestResultDelegate::clearCache() { - const QModelIndex current = m_lastProcessedIndex; m_lastProcessedIndex = QModelIndex(); m_lastProcessedFont = QFont(); m_lastWidth = -1; - if (current.isValid()) { - if (auto model = current.model()) { - if (model->index(current.row(), current.column(), current.parent()) == current) - emit sizeHintChanged(current); - } - } } void TestResultDelegate::limitTextOutput(QString &output) const From f7b5e9dcc8e1dd1233270c6685953224e445a699 Mon Sep 17 00:00:00 2001 From: Daniele Bortolotti Date: Wed, 26 Oct 2022 13:10:30 +0200 Subject: [PATCH 46/97] McuSupport: Fix MSVC toolchain in legacy mode Wrong executable argument for version detector was not allowing for Desktop MSVC kit creation in legacy mode. Task-number: UL-6597 Change-Id: If64472002e3aace6240c91cf9c303a2f01febe50 Reviewed-by: Rainer Keller Reviewed-by: Yasser Grimes Reviewed-by: Christian Stenger Reviewed-by: --- src/plugins/mcusupport/mcusupportsdk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index a85ac4c8894..d636f5df166 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -190,7 +190,7 @@ McuToolChainPackagePtr createMsvcToolChainPackage(const SettingsHandler::Ptr &se const FilePath defaultPath = toolChain ? toolChain->compilerCommand().parentDir() : FilePath(); const auto *versionDetector = new McuPackageExecutableVersionDetector(detectionPath, - {"--version"}, + {"/?"}, R"(\b(\d+\.\d+)\.\d+\b)"); return McuToolChainPackagePtr{new McuToolChainPackage(settingsHandler, From bd812b6feb3d3aad40ada62cb1f75a82574c8f4c Mon Sep 17 00:00:00 2001 From: Daniele Bortolotti Date: Mon, 24 Oct 2022 12:15:01 +0200 Subject: [PATCH 47/97] McuSupport: Remove MSVC2017 from supported toolchains According to our documentation we support MSVC2019 (16.0) https://doc-snapshots.qt.io/qtformcus-dev/qtul-msvc-compiler.html Change-Id: I45fd8cda40f1775be3c575e5b4ac55c3a714c4fe Reviewed-by: Rainer Keller Reviewed-by: Christian Stenger --- src/plugins/mcusupport/mcupackage.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp index b0a3699faff..327af9c06b8 100644 --- a/src/plugins/mcusupport/mcupackage.cpp +++ b/src/plugins/mcusupport/mcupackage.cpp @@ -321,9 +321,7 @@ ToolChain *McuToolChainPackage::msvcToolChain(Id language) { ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) { const Abi abi = t->targetAbi(); - // TODO: Should Abi::WindowsMsvc2022Flavor be added too? - return (abi.osFlavor() == Abi::WindowsMsvc2017Flavor - || abi.osFlavor() == Abi::WindowsMsvc2019Flavor) + return abi.osFlavor() == Abi::WindowsMsvc2019Flavor && abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64 && t->typeId() == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID && t->language() == language; From 90e5ca47480f1eec6cd479a975923f52a14cadac Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Tue, 25 Oct 2022 18:06:43 +0300 Subject: [PATCH 48/97] QmlDesigner: Fix duplicating materials with dynamic properties Fixes: QDS-8091 Change-Id: I0f9a710214850326d1cda179c1a2aa6332b98510 Reviewed-by: Reviewed-by: Thomas Hartmann Reviewed-by: Tim Jenssen --- .../materialeditor/materialeditorview.cpp | 50 ++++++++++++++++--- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index 9352e200d15..c8c42b2fa99 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -1022,6 +1022,8 @@ void MaterialEditorView::duplicateMaterial(const ModelNode &material) TypeName matType = material.type(); QmlObjectNode sourceMat(material); + ModelNode duplicateMatNode; + QList dynamicProps; executeInTransaction(__FUNCTION__, [&] { ModelNode matLib = materialLibraryNode(); @@ -1032,25 +1034,57 @@ void MaterialEditorView::duplicateMaterial(const ModelNode &material) NodeMetaInfo metaInfo = model()->metaInfo(matType); QmlObjectNode duplicateMat = createModelNode(matType, metaInfo.majorVersion(), metaInfo.minorVersion()); + duplicateMatNode = duplicateMat.modelNode(); + // set name and id QString newName = sourceMat.modelNode().variantProperty("objectName").value().toString() + " copy"; - duplicateMat.modelNode().variantProperty("objectName").setValue(newName); - duplicateMat.modelNode().setIdWithoutRefactoring(model()->generateIdFromName(newName, "material")); + duplicateMatNode.variantProperty("objectName").setValue(newName); + duplicateMatNode.setIdWithoutRefactoring(model()->generateIdFromName(newName, "material")); - // sync properties + // sync properties. Only the base state is duplicated. const QList props = material.properties(); for (const AbstractProperty &prop : props) { - if (prop.name() == "objectName") + if (prop.name() == "objectName" || prop.name() == "data") continue; - if (prop.isVariantProperty()) - duplicateMat.setVariantProperty(prop.name(), prop.toVariantProperty().value()); - else if (prop.isBindingProperty()) - duplicateMat.setBindingProperty(prop.name(), prop.toBindingProperty().expression()); + if (prop.isVariantProperty()) { + if (prop.isDynamic()) { + dynamicProps.append(prop); + } else { + duplicateMatNode.variantProperty(prop.name()) + .setValue(prop.toVariantProperty().value()); + } + } else if (prop.isBindingProperty()) { + if (prop.isDynamic()) { + dynamicProps.append(prop); + } else { + duplicateMatNode.bindingProperty(prop.name()) + .setExpression(prop.toBindingProperty().expression()); + } + } } matLib.defaultNodeListProperty().reparentHere(duplicateMat); }); + + // For some reason, creating dynamic properties in the same transaction doesn't work, so + // let's do it in separate transaction. + // TODO: Fix the issue and merge transactions (QDS-8094) + if (!dynamicProps.isEmpty()) { + executeInTransaction(__FUNCTION__, [&] { + for (const AbstractProperty &prop : std::as_const(dynamicProps)) { + if (prop.isVariantProperty()) { + duplicateMatNode.variantProperty(prop.name()) + .setDynamicTypeNameAndValue(prop.dynamicTypeName(), + prop.toVariantProperty().value()); + } else if (prop.isBindingProperty()) { + duplicateMatNode.bindingProperty(prop.name()) + .setDynamicTypeNameAndExpression(prop.dynamicTypeName(), + prop.toBindingProperty().expression()); + } + } + }); + } } void MaterialEditorView::customNotification(const AbstractView *view, const QString &identifier, From b65205ed97fcd1a5e2e7b2b7877e839c37f87e68 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 27 Oct 2022 11:42:37 +0200 Subject: [PATCH 49/97] Texteditor: Fix text with underline black background If text was given an underline and the background was unset, it was drawn with a black background. This had been implemented for QTCREATORBUG-18101. Removing that patch does not seem to re-introduce that bug. Fixes: QTCREATORBUG-19191 Change-Id: Iaad05abbc7c673d233601ef72d1641e2edc530c5 Reviewed-by: David Schulz --- src/plugins/texteditor/fontsettings.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/plugins/texteditor/fontsettings.cpp b/src/plugins/texteditor/fontsettings.cpp index 887398ad249..c1d76945fca 100644 --- a/src/plugins/texteditor/fontsettings.cpp +++ b/src/plugins/texteditor/fontsettings.cpp @@ -171,9 +171,6 @@ QTextCharFormat FontSettings::toTextCharFormat(TextStyle category) const } else if (isOverlayCategory(category)) { // overlays without a background schouldn't get painted tf.setBackground(QColor()); - } else if (f.underlineStyle() != QTextCharFormat::NoUnderline) { - // underline does not need to fill without having background color - tf.setBackground(Qt::BrushStyle::NoBrush); } tf.setFontWeight(f.bold() ? QFont::Bold : QFont::Normal); From e61e92d016719dfe1d6289152dad4366df4b40be Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Wed, 26 Oct 2022 22:41:24 +0300 Subject: [PATCH 50/97] Git: Fix focus issue in LogChangeWidget MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Workaround QTBUG-89156. Change-Id: Ia128db1c0c2ee85985b6a725b6cb849d87844668 Reviewed-by: Reviewed-by: André Hartmann --- src/plugins/git/logchangedialog.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/plugins/git/logchangedialog.cpp b/src/plugins/git/logchangedialog.cpp index 41c620ab6fe..ef4b2cb734c 100644 --- a/src/plugins/git/logchangedialog.cpp +++ b/src/plugins/git/logchangedialog.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -75,7 +76,7 @@ LogChangeWidget::LogChangeWidget(QWidget *parent) setSelectionBehavior(QAbstractItemView::SelectRows); setActivationMode(Utils::DoubleClickActivation); connect(this, &LogChangeWidget::activated, this, &LogChangeWidget::emitCommitActivated); - setFocus(); + QTimer::singleShot(0, [this] { setFocus(); }); } bool LogChangeWidget::init(const FilePath &repository, const QString &commit, LogFlags flags) @@ -211,16 +212,15 @@ const QStandardItem *LogChangeWidget::currentItem(int column) const LogChangeDialog::LogChangeDialog(bool isReset, QWidget *parent) : QDialog(parent) , m_widget(new LogChangeWidget) - - , m_dialogButtonBox(new QDialogButtonBox(this)) + , m_dialogButtonBox(new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this)) { auto layout = new QVBoxLayout(this); layout->addWidget(new QLabel(isReset ? Tr::tr("Reset to:") : Tr::tr("Select change:"), this)); layout->addWidget(m_widget); auto popUpLayout = new QHBoxLayout; if (isReset) { - popUpLayout->addWidget(new QLabel(Tr::tr("Reset type:"), this)); - m_resetTypeComboBox = new QComboBox(this); + popUpLayout->addWidget(new QLabel(Tr::tr("Reset type:"))); + m_resetTypeComboBox = new QComboBox; m_resetTypeComboBox->addItem(Tr::tr("Hard"), "--hard"); m_resetTypeComboBox->addItem(Tr::tr("Mixed"), "--mixed"); m_resetTypeComboBox->addItem(Tr::tr("Soft"), "--soft"); @@ -230,8 +230,7 @@ LogChangeDialog::LogChangeDialog(bool isReset, QWidget *parent) : } popUpLayout->addWidget(m_dialogButtonBox); - m_dialogButtonBox->addButton(QDialogButtonBox::Cancel); - QPushButton *okButton = m_dialogButtonBox->addButton(QDialogButtonBox::Ok); + QPushButton *okButton = m_dialogButtonBox->button(QDialogButtonBox::Ok); layout->addLayout(popUpLayout); connect(m_dialogButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); From 596529651bf51640068bcca43fde54d7a9aa84f0 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 25 Oct 2022 16:47:42 +0200 Subject: [PATCH 51/97] Doc: Fix link to Qt 6 based Qt Design Viewer Change-Id: I68a10b4508feb6760f28ef63d29fa54bc1ae37f3 Reviewed-by: Reviewed-by: Tim Jenssen --- doc/qtcreator/src/qtquick/creator-only/qt-design-viewer.qdoc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/qtcreator/src/qtquick/creator-only/qt-design-viewer.qdoc b/doc/qtcreator/src/qtquick/creator-only/qt-design-viewer.qdoc index a706997ed4b..3cb1c61e1b7 100644 --- a/doc/qtcreator/src/qtquick/creator-only/qt-design-viewer.qdoc +++ b/doc/qtcreator/src/qtquick/creator-only/qt-design-viewer.qdoc @@ -29,8 +29,7 @@ To preview an application in a web browser: \list 1 - \li In the browser, open \l{http://qt-webassembly.io/designviewer/} - {\QDV}. + \li In the browser, open \l{ https://designviewer.qt.io/}{\QDV}. \li Drag and drop your application package to \QDV, or click the load icon to browse for your file. \endlist From d72f5674b5e14b2e6015049365bd5ec2ea6b9296 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 27 Oct 2022 13:34:58 +0300 Subject: [PATCH 52/97] QmlDesigner: Fix dynamic properties on material library init Nodes with dynamic properties cannot be reparented under a newly created node in the same transaction without breaking said properties. To work around this issue, ensureMaterialLibraryNode() was split into two transactions. This also meant removing ensureMaterialLibraryNode() call from materialLibraryNode(), so now material library will only be created in response to model attach or qtquick3d import addition. This should still cover all cases where user doesn't manually remove the material library node. Fixes: QDS-8095 Change-Id: Icff449b2bee0da2b43b02bbf5e0d28189aa2b3a9 Reviewed-by: Mahmoud Badri --- .../materialeditor/materialeditorview.cpp | 4 +- .../designercore/model/abstractview.cpp | 55 ++++++++++--------- 2 files changed, 29 insertions(+), 30 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index c8c42b2fa99..f6ed9acff93 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -80,9 +80,7 @@ MaterialEditorView::MaterialEditorView(QWidget *parent) m_ensureMatLibTimer.callOnTimeout([this] { if (model() && model()->rewriterView() && !model()->rewriterView()->hasIncompleteTypeInformation() && model()->rewriterView()->errors().isEmpty()) { - executeInTransaction("MaterialEditorView::MaterialEditorView", [this] { - ensureMaterialLibraryNode(); - }); + ensureMaterialLibraryNode(); m_ensureMatLibTimer.stop(); } }); diff --git a/src/plugins/qmldesigner/designercore/model/abstractview.cpp b/src/plugins/qmldesigner/designercore/model/abstractview.cpp index 5e0e07fde1f..8012bc22365 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractview.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractview.cpp @@ -829,47 +829,48 @@ void AbstractView::changeRootNodeType(const TypeName &type, int majorVersion, in m_model.data()->d->changeRootNodeType(type, majorVersion, minorVersion); } -// Creates material library if it doesn't exist and moves any existing materials into it -// This function should be called only from inside a transaction, as it potentially does many -// changes to model, or undo stack should be cleared after the call. +// Creates material library if it doesn't exist and moves any existing materials into it. void AbstractView::ensureMaterialLibraryNode() { ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID); if (matLib.isValid() || rootModelNode().isSubclassOf("QtQuick3D.Material")) return; - // Create material library node - TypeName nodeType = rootModelNode().isSubclassOf("QtQuick3D.Node") ? "QtQuick3D.Node" - : "QtQuick.Item"; - NodeMetaInfo metaInfo = model()->metaInfo(nodeType); - matLib = createModelNode(nodeType, metaInfo.majorVersion(), metaInfo.minorVersion()); + executeInTransaction(__FUNCTION__, [&] { + // Create material library node + TypeName nodeType = rootModelNode().isSubclassOf("QtQuick3D.Node") ? "QtQuick3D.Node" + : "QtQuick.Item"; + NodeMetaInfo metaInfo = model()->metaInfo(nodeType); - matLib.setIdWithoutRefactoring(Constants::MATERIAL_LIB_ID); - rootModelNode().defaultNodeListProperty().reparentHere(matLib); + matLib = createModelNode(nodeType, metaInfo.majorVersion(), metaInfo.minorVersion()); - const QList materials = rootModelNode().subModelNodesOfType("QtQuick3D.Material"); - if (!materials.isEmpty()) { - // Move all materials to under material library node - for (const ModelNode &node : materials) { - // If material has no name, set name to id - QString matName = node.variantProperty("objectName").value().toString(); - if (matName.isEmpty()) { - VariantProperty objNameProp = node.variantProperty("objectName"); - objNameProp.setValue(node.id()); + matLib.setIdWithoutRefactoring(Constants::MATERIAL_LIB_ID); + rootModelNode().defaultNodeListProperty().reparentHere(matLib); + }); + + // Do the material reparentings in different transaction to work around issue QDS-8094 + executeInTransaction(__FUNCTION__, [&] { + const QList materials = rootModelNode().subModelNodesOfType("QtQuick3D.Material"); + if (!materials.isEmpty()) { + // Move all materials to under material library node + for (const ModelNode &node : materials) { + // If material has no name, set name to id + QString matName = node.variantProperty("objectName").value().toString(); + if (matName.isEmpty()) { + VariantProperty objNameProp = node.variantProperty("objectName"); + objNameProp.setValue(node.id()); + } + + matLib.defaultNodeListProperty().reparentHere(node); } - - matLib.defaultNodeListProperty().reparentHere(node); } - } + }); } -// Returns ModelNode for project's material library. -// Since this calls ensureMaterialLibraryNode(), it should only be called within a transaction. +// Returns ModelNode for project's material library if it exists. ModelNode AbstractView::materialLibraryNode() { - ensureMaterialLibraryNode(); - ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID); - return matLib; + return modelNodeForId(Constants::MATERIAL_LIB_ID); } // Assigns given material to a 3D model. From 24fcdd9c16eecefdad42ec8b69b8db8f21b5aed2 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 27 Oct 2022 13:24:52 +0200 Subject: [PATCH 53/97] Core: Hide Scrollbar highlight This patch hides the scrollbar overlay when the Scrollbar itself gets hidden, for example on mac for documents that fit into the viewport. Fixes: QTCREATORBUG-28336 Change-Id: I2cb61affe38d0066a3d6f3ca012f97674b3d1539 Reviewed-by: David Schulz --- .../coreplugin/find/highlightscrollbarcontroller.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/plugins/coreplugin/find/highlightscrollbarcontroller.cpp b/src/plugins/coreplugin/find/highlightscrollbarcontroller.cpp index 222631ad140..e2d0a7ab893 100644 --- a/src/plugins/coreplugin/find/highlightscrollbarcontroller.cpp +++ b/src/plugins/coreplugin/find/highlightscrollbarcontroller.cpp @@ -232,6 +232,12 @@ bool HighlightScrollBarOverlay::eventFilter(QObject *object, QEvent *event) case QEvent::ZOrderChange: raise(); break; + case QEvent::Show: + show(); + break; + case QEvent::Hide: + hide(); + break; default: break; } From 6936f233286081b2690616735ae8d1b25d31e631 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 27 Oct 2022 14:44:48 +0200 Subject: [PATCH 54/97] CMake: Fix settings display not updated Fixes: QTCREATORBUG-28267 Change-Id: Icf2fb7e5d7a8cd44d7a61ade36be41106aba2138 Reviewed-by: Cristian Adam --- src/plugins/cmakeprojectmanager/cmakesettingspage.cpp | 1 + src/plugins/cmakeprojectmanager/cmaketool.cpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp index 714c90e2b70..5663e952f78 100644 --- a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp +++ b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp @@ -462,6 +462,7 @@ void CMakeToolItemConfigWidget::onBinaryPathEditingFinished() { updateQchFilePath(); store(); + load(m_model->cmakeToolItem(m_id)); } void CMakeToolItemConfigWidget::updateQchFilePath() diff --git a/src/plugins/cmakeprojectmanager/cmaketool.cpp b/src/plugins/cmakeprojectmanager/cmaketool.cpp index 4cef534ff1d..5137f7fe693 100644 --- a/src/plugins/cmakeprojectmanager/cmaketool.cpp +++ b/src/plugins/cmakeprojectmanager/cmaketool.cpp @@ -295,6 +295,9 @@ CMakeTool::Version CMakeTool::version() const QString CMakeTool::versionDisplay() const { + if (m_executable.isEmpty()) + return {}; + if (!isValid()) return Tr::tr("Version not parseable"); From ca3de9c3c7586d86551a013b3adae7d81f08e502 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sivert=20Kr=C3=B8vel?= Date: Mon, 24 Oct 2022 20:37:55 +0200 Subject: [PATCH 55/97] McuSupport: Add missing settings keys The JSON entry "setting" contains the key under which the path to a dependency is persistently stored by QtCreator. Some packages were missing this entry, and as such changes to their settings were not made permanent. This patch updates test jsons to match Qt for MCUs repo. Task-number: QTCREATORBUG-28246 Change-Id: Iaa3eaf28648e97e677a2dd3f1ab5580c18586ca2 Reviewed-by: Rainer Keller Reviewed-by: Yasser Grimes Reviewed-by: Christian Stenger Reviewed-by: --- src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h | 1 + src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h | 2 ++ .../mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h | 4 +++- .../mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h | 1 + src/plugins/mcusupport/test/gcc_desktop_json.h | 1 + src/plugins/mcusupport/test/ghs_tviic2d4m_baremetal_json.h | 2 ++ src/plugins/mcusupport/test/ghs_tviic2d6m_baremetal_json.h | 3 +++ src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h | 1 + src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h | 2 ++ .../mcusupport/test/iar_mimxrt1170_evk_freertos_json.h | 1 + src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h | 2 ++ src/plugins/mcusupport/test/msvc_desktop_json.h | 1 + 12 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h index 3cc40f01d39..fb6a57640a7 100644 --- a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h @@ -64,6 +64,7 @@ constexpr auto armgcc_ek_ra6m3g_baremetal_json = R"( "boardSdk": { "cmakeVar": "QUL_BOARD_SDK_DIR", "envVar": "EK_RA6M3G_FSP_PATH", + "setting": "EK_RA6M3G_FSP_PATH", "id": "EK_RA6M3G_FSP_PATH", "label": "Flexible Software Package for Renesas RA MCU Family", "optional": false, diff --git a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h index 45f7d554284..283b79ab21d 100644 --- a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h @@ -64,6 +64,7 @@ constexpr auto armgcc_ek_ra6m3g_freertos_json = R"( "boardSdk": { "cmakeVar": "QUL_BOARD_SDK_DIR", "envVar": "EK_RA6M3G_FSP_PATH", + "setting": "EK_RA6M3G_FSP_PATH", "id": "EK_RA6M3G_FSP_PATH", "label": "Flexible Software Package for Renesas RA MCU Family", "optional": false, @@ -76,6 +77,7 @@ constexpr auto armgcc_ek_ra6m3g_freertos_json = R"( "envVar": "EK_RA6M3G_FREERTOS_DIR", "id": "EK_RA6M3G_FREERTOS_DIR", "label": "FreeRTOS SDK for EK-RA6M3G", + "setting": "FreeRTOSSourcePackage_EK_RA6M3G", "cmakeVar": "FREERTOS_DIR", "defaultValue": "%{Qul_ROOT}/platform/boards/renesas/ek-ra6m3g-common/3rdparty/freertos", "detectionPath": "tasks.c", diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h index 79c3eb64356..e7a7311b1c9 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h @@ -19,6 +19,7 @@ constexpr auto armgcc_mimxrt1060_evk_baremetal_json = R"( "label": "MCUXpresso IDE", "type": "path", "cmakeVar": "MCUXPRESSO_IDE_PATH", + "setting": "MCUXpressoIDE", "defaultValue": { "windows": "%{Env:ROOT}/nxp/MCUXpressoIDE*", "linux": "/usr/local/mcuxpressoide/" @@ -70,7 +71,8 @@ constexpr auto armgcc_mimxrt1060_evk_baremetal_json = R"( "2.12.0" ], "id": "NXP_SDK_DIR", - "label": "Board SDK MIMXRT1060-EVK", + "label": "Board SDK for MIMXRT1060-EVK", + "setting": "EVK_MIMXRT1060_SDK_PATH", "cmakeVar": "QUL_BOARD_SDK_DIR", "type": "path", "optional": false diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h index a32fd7a1dcc..8c348011231 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h @@ -85,6 +85,7 @@ constexpr auto armgcc_mimxrt1170_evk_freertos_json = R"( "cmakeVar": "FREERTOS_DIR", "envVar": "EVK_MIMXRT1170_FREERTOS_PATH", "label": "FreeRTOS SDK for MIMXRT1170-EVK", + "setting": "FreeRTOSSourcePackage_IMXRT1170", "defaultValue": "%{QUL_BOARD_SDK_DIR}/rtos/freertos/freertos_kernel", "detectionPath": "tasks.c", "type": "path", diff --git a/src/plugins/mcusupport/test/gcc_desktop_json.h b/src/plugins/mcusupport/test/gcc_desktop_json.h index 63c42cc37e8..59e3b499362 100644 --- a/src/plugins/mcusupport/test/gcc_desktop_json.h +++ b/src/plugins/mcusupport/test/gcc_desktop_json.h @@ -23,6 +23,7 @@ constexpr auto gcc_desktop_json = R"( ], "compiler": { "label": "GNU Toolchain", + "setting": "GnuToolchain", "defaultValue": "/usr", "versionDetection": { "executableArgs": "--version", diff --git a/src/plugins/mcusupport/test/ghs_tviic2d4m_baremetal_json.h b/src/plugins/mcusupport/test/ghs_tviic2d4m_baremetal_json.h index c10f1f052fc..339f7fe4280 100644 --- a/src/plugins/mcusupport/test/ghs_tviic2d4m_baremetal_json.h +++ b/src/plugins/mcusupport/test/ghs_tviic2d4m_baremetal_json.h @@ -16,6 +16,7 @@ constexpr auto ghs_tviic2d4m_baremetal_json = R"( "cmakeEntries": [ { "id": "INFINEON_AUTO_FLASH_UTILITY_DIR", + "setting": "CypressAutoFlashUtil", "label": "Cypress Auto Flash Utility", "type": "path", "cmakeVar": "INFINEON_AUTO_FLASH_UTILITY_DIR", @@ -47,6 +48,7 @@ constexpr auto ghs_tviic2d4m_baremetal_json = R"( }, "boardSdk": { "envVar": "TVII_GRAPHICS_DRIVER_DIR", + "setting": "TVII_GRAPHICS_DRIVER_DIR", "versions": [ "V1e.1.0" ], diff --git a/src/plugins/mcusupport/test/ghs_tviic2d6m_baremetal_json.h b/src/plugins/mcusupport/test/ghs_tviic2d6m_baremetal_json.h index 1f8b6bbb6dd..7f908f9a178 100644 --- a/src/plugins/mcusupport/test/ghs_tviic2d6m_baremetal_json.h +++ b/src/plugins/mcusupport/test/ghs_tviic2d6m_baremetal_json.h @@ -16,6 +16,7 @@ constexpr auto ghs_tviic2d6m_baremetal_json = R"( "cmakeEntries": [ { "id": "INFINEON_AUTO_FLASH_UTILITY_DIR", + "setting": "CypressAutoFlashUtil", "label": "Cypress Auto Flash Utility", "type": "path", "cmakeVar": "INFINEON_AUTO_FLASH_UTILITY_DIR", @@ -32,6 +33,7 @@ constexpr auto ghs_tviic2d6m_baremetal_json = R"( "compiler": { "id": "GHS_ARM_DIR", "label": "Green Hills Compiler for ARM", + "setting": "GHSArmToolchain", "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", "optional": false @@ -47,6 +49,7 @@ constexpr auto ghs_tviic2d6m_baremetal_json = R"( }, "boardSdk": { "envVar": "TVII_GRAPHICS_DRIVER_DIR", + "setting": "TVII_GRAPHICS_DRIVER_DIR", "versions": [ "V1e.1.0" ], diff --git a/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h b/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h index 579e04908dd..0c38725d138 100644 --- a/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h @@ -64,6 +64,7 @@ constexpr auto iar_ek_ra6m3g_baremetal_json = R"( "boardSdk": { "cmakeVar": "QUL_BOARD_SDK_DIR", "envVar": "EK_RA6M3G_FSP_PATH", + "setting": "EK_RA6M3G_FSP_PATH", "id": "EK_RA6M3G_FSP_PATH", "label": "Flexible Software Package for Renesas RA MCU Family", "optional": false, diff --git a/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h b/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h index 70e49c8c37d..d5eda9eab7d 100644 --- a/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h +++ b/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h @@ -64,6 +64,7 @@ constexpr auto iar_ek_ra6m3g_freertos_json = R"( "boardSdk": { "cmakeVar": "QUL_BOARD_SDK_DIR", "envVar": "EK_RA6M3G_FSP_PATH", + "setting": "EK_RA6M3G_FSP_PATH", "id": "EK_RA6M3G_FSP_PATH", "label": "Flexible Software Package for Renesas RA MCU Family", "optional": false, @@ -76,6 +77,7 @@ constexpr auto iar_ek_ra6m3g_freertos_json = R"( "envVar": "EK_RA6M3G_FREERTOS_DIR", "id": "EK_RA6M3G_FREERTOS_DIR", "label": "FreeRTOS SDK for EK-RA6M3G", + "setting": "FreeRTOSSourcePackage_EK_RA6M3G", "cmakeVar": "FREERTOS_DIR", "defaultValue": "%{Qul_ROOT}/platform/boards/renesas/ek-ra6m3g-common/3rdparty/freertos", "detectionPath": "tasks.c", diff --git a/src/plugins/mcusupport/test/iar_mimxrt1170_evk_freertos_json.h b/src/plugins/mcusupport/test/iar_mimxrt1170_evk_freertos_json.h index 4143e88cd65..4843a668198 100644 --- a/src/plugins/mcusupport/test/iar_mimxrt1170_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/iar_mimxrt1170_evk_freertos_json.h @@ -85,6 +85,7 @@ constexpr auto iar_mimxrt1170_evk_freertos_json = R"( "cmakeVar": "FREERTOS_DIR", "envVar": "EVK_MIMXRT1170_FREERTOS_PATH", "label": "FreeRTOS SDK for MIMXRT1170-EVK", + "setting": "FreeRTOSSourcePackage_IMXRT1170", "defaultValue": "%{QUL_BOARD_SDK_DIR}/rtos/freertos/freertos_kernel", "detectionPath": "tasks.c", "type": "path", diff --git a/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h b/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h index 0e4d7442dfb..29c391e8db3 100644 --- a/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h @@ -16,6 +16,7 @@ constexpr auto iar_tviic2d6m_baremetal_json = R"( "cmakeEntries": [ { "id": "INFINEON_AUTO_FLASH_UTILITY_DIR", + "setting": "CypressAutoFlashUtil", "label": "Cypress Auto Flash Utility", "type": "path", "cmakeVar": "INFINEON_AUTO_FLASH_UTILITY_DIR", @@ -55,6 +56,7 @@ constexpr auto iar_tviic2d6m_baremetal_json = R"( }, "boardSdk": { "envVar": "TVII_GRAPHICS_DRIVER_DIR", + "setting": "TVII_GRAPHICS_DRIVER_DIR", "versions": [ "V1e.1.0" ], diff --git a/src/plugins/mcusupport/test/msvc_desktop_json.h b/src/plugins/mcusupport/test/msvc_desktop_json.h index 5f5b22e3e85..c2862d72416 100644 --- a/src/plugins/mcusupport/test/msvc_desktop_json.h +++ b/src/plugins/mcusupport/test/msvc_desktop_json.h @@ -31,6 +31,7 @@ constexpr auto msvc_desktop_json = R"( ], "compiler": { "label": "MSVC Toolchain", + "setting": "MsvcToolchain", "defaultValue": "%{Env:MSVC_COMPILER_DIR}", "versionDetection": { "filePattern": "cl.exe", From 8afdb62564b5629f28876b71ac8e8dd68f18fe0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sivert=20Kr=C3=B8vel?= Date: Thu, 27 Oct 2022 01:58:13 +0200 Subject: [PATCH 56/97] McuSupport: Fix error in McuPackage validity check The recently added McuPackage::Status::ValidPackageVersionNotDeteced is supposed to be a valid status for an McuPackage, similar to ValidPackageMismatchedVersion. It produces a warning symbol, but is not supposed to block kit creation. Task-number: QTCREATORBUG-28246 Change-Id: Ifdc8488d28019ec76d29114501876c6d7d5e700c Reviewed-by: Rainer Keller Reviewed-by: Daniele Bortolotti Reviewed-by: Christian Stenger --- src/plugins/mcusupport/mcupackage.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp index 327af9c06b8..ad12f62962e 100644 --- a/src/plugins/mcusupport/mcupackage.cpp +++ b/src/plugins/mcusupport/mcupackage.cpp @@ -156,7 +156,8 @@ McuPackage::Status McuPackage::status() const bool McuPackage::isValidStatus() const { - return m_status == Status::ValidPackage || m_status == Status::ValidPackageMismatchedVersion; + return m_status == Status::ValidPackage || m_status == Status::ValidPackageMismatchedVersion + || m_status == Status::ValidPackageVersionNotDetected; } void McuPackage::updateStatusUi() From db7674307dfecea3516bbf15cea6bab7fffd9947 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sivert=20Kr=C3=B8vel?= Date: Thu, 27 Oct 2022 02:12:10 +0200 Subject: [PATCH 57/97] McuSupport: Only store valid paths to settings The plugin currently requires valid packages before updating kits. Invalid packages are ignored. This change makes writing to settings consistent with this approach. If any of the given paths are invalid, changes are not applied. In order to not accidentally include changes made to packages for other targets than the one visible in the UI, the Apply-button in the Devices page now only stores the current target. This also avoids unpredictable behavior when more than one target in the repo track the same dependencies. The path shown in the UI is the one which is applied, not a hidden path currently stored in another target. Change-Id: Id0a6ec1aebd53357d0ee2fb68f14529f34ae887f Reviewed-by: Daniele Bortolotti Reviewed-by: Christian Stenger --- .../mcusupport/mcusupportoptionspage.cpp | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/plugins/mcusupport/mcusupportoptionspage.cpp b/src/plugins/mcusupport/mcusupportoptionspage.cpp index c493952f4fc..f728851774f 100644 --- a/src/plugins/mcusupport/mcusupportoptionspage.cpp +++ b/src/plugins/mcusupport/mcusupportoptionspage.cpp @@ -7,6 +7,7 @@ #include "mcusupportconstants.h" #include "mcusupportoptions.h" #include "mcusupportsdk.h" +#include "mcusupporttr.h" #include "mcutarget.h" #include "mcutargetfactory.h" #include "settingshandler.h" @@ -28,6 +29,7 @@ #include #include #include +#include #include #include @@ -288,8 +290,27 @@ void McuSupportOptionsWidget::apply() m_settingsHandler->setAutomaticKitCreation(m_options.automaticKitCreationEnabled()); McuTargetFactory::expandVariables(m_options.sdkRepository.packages); + + QMessageBox warningPopup(QMessageBox::Icon::Warning, + Tr::tr("Warning"), + Tr::tr("Unable to apply changes."), + QMessageBox::Ok, + this); + + auto target = currentMcuTarget(); + if (!target) { + warningPopup.setInformativeText(Tr::tr("No target selected.")); + warningPopup.exec(); + return; + } + if (!target->isValid()) { + warningPopup.setInformativeText(Tr::tr("Invalid path(s) present.")); + warningPopup.exec(); + return; + } + pathsChanged |= m_options.qtForMCUsSdkPackage->writeToSettings(); - for (const auto &package : std::as_const(m_options.sdkRepository.packages)) + for (const auto &package : target->packages()) pathsChanged |= package->writeToSettings(); if (pathsChanged) { From afb3c0928934d17a833c839ef020b610c6a2c346 Mon Sep 17 00:00:00 2001 From: Daniele Bortolotti Date: Thu, 27 Oct 2022 13:57:54 +0200 Subject: [PATCH 58/97] McuSupport: Fix version detection for GHS toolchains MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The GHS compiler invoked without a valid input source file returns an error code. Use gversion instead, a utility part of the toolchain, with -help to retrieve the version string. Change-Id: I289f462d322db045368cfb5a02b6644838559639 Reviewed-by: Sivert Krøvel Reviewed-by: Christian Stenger --- src/plugins/mcusupport/mcusupportsdk.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index d636f5df166..c2fe9e0cccc 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -276,8 +276,8 @@ McuToolChainPackagePtr createGhsToolchainPackage(const SettingsHandler::Ptr &set const FilePath defaultPath = FilePath::fromUserInput(qtcEnvironmentVariable(envVar)); const auto *versionDetector - = new McuPackageExecutableVersionDetector(FilePath("as850").withExecutableSuffix(), - {"-V"}, + = new McuPackageExecutableVersionDetector(FilePath("gversion").withExecutableSuffix(), + {"-help"}, R"(\bv(\d+\.\d+\.\d+)\b)"); return McuToolChainPackagePtr{ @@ -301,8 +301,8 @@ McuToolChainPackagePtr createGhsArmToolchainPackage(const SettingsHandler::Ptr & const FilePath defaultPath = FilePath::fromUserInput(qtcEnvironmentVariable(envVar)); const auto *versionDetector - = new McuPackageExecutableVersionDetector(FilePath("asarm").withExecutableSuffix(), - {"-V"}, + = new McuPackageExecutableVersionDetector(FilePath("gversion").withExecutableSuffix(), + {"-help"}, R"(\bv(\d+\.\d+\.\d+)\b)"); return McuToolChainPackagePtr{ From 5759da754e856ae831002fd5c32ffe275891d5eb Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 27 Oct 2022 16:27:05 +0200 Subject: [PATCH 59/97] Doc: Use filename extension of ok.png to fix qdoc warnings Change-Id: Ic33d9c4e8a3af523e087fc1284cb374e7fd37ec0 Reviewed-by: Leena Miettinen --- .../creator-supported-platforms.qdoc | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/doc/qtcreator/src/overview/creator-only/creator-supported-platforms.qdoc b/doc/qtcreator/src/overview/creator-only/creator-supported-platforms.qdoc index 482ecc08a75..6dfdf06c8e3 100644 --- a/doc/qtcreator/src/overview/creator-only/creator-supported-platforms.qdoc +++ b/doc/qtcreator/src/overview/creator-only/creator-supported-platforms.qdoc @@ -25,44 +25,44 @@ \li \l Windows \row \li \l Android - \li \image ok - \li \image ok - \li \image ok + \li \image ok.png + \li \image ok.png + \li \image ok.png \row \li \l{Bare Metal} - \li \image ok - \li \image ok - \li \image ok + \li \image ok.png + \li \image ok.png + \li \image ok.png \row \li \l Boot2Qt - \li \image ok - \li \image ok - \li \image ok + \li \image ok.png + \li \image ok.png + \li \image ok.png \row - \li \l{Generic Remote Linux} - \li \image ok - \li \image ok - \li \image ok + \li \l{Remote Linux} + \li \image ok.png + \li \image ok.png + \li \image ok.png \row \li \l iOS \li - \li \image ok + \li \image ok.png \li \row \li \l{Microcontroller Units (MCU)}{MCUs} \li \li - \li \image ok + \li \image ok.png \row \li \l QNX - \li \image ok - \li \image ok - \li \inlineimage ok + \li \image ok.png + \li \image ok.png + \li \inlineimage ok.png \row \li \l{Building Applications for the Web}{WebAssembly} - \li \image ok - \li \image ok - \li \image ok + \li \image ok.png + \li \image ok.png + \li \image ok.png \endtable \note UWP support was removed from \QC 8.0. From bc370aecfdee8216a512e33b0c33d6f84f5745d8 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 27 Oct 2022 16:40:52 +0300 Subject: [PATCH 60/97] QmlDesigner: Hide material bundle if QtQuick3D version too low Most materials in the material bundle require at least QtQuick3D 6.3, so we hide the bundle materials from material browser when the detected module version is less than 6.3. Fixes: QDS-8100 Change-Id: I9f50b507c3c3c50f821fa6a902995b999da24464 Reviewed-by: Qt CI Bot Reviewed-by: Mahmoud Badri --- .../materialbrowserbundlemodel.cpp | 34 +++++++------- .../materialbrowserbundlemodel.h | 15 +++--- .../materialbrowser/materialbrowserview.cpp | 46 +++++++++++++++++++ .../materialbrowser/materialbrowserview.h | 1 + .../qmldesigner/designercore/include/import.h | 2 + .../qmldesigner/designercore/model/import.cpp | 15 ++++++ 6 files changed, 91 insertions(+), 22 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp index 441cdc7a693..7cb2a39c0d1 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.cpp @@ -94,7 +94,7 @@ QHash MaterialBrowserBundleModel::roleNames() const void MaterialBrowserBundleModel::loadMaterialBundle() { - if (m_matBundleExists || m_probeMatBundleDir) + if (m_matBundleLoaded || m_probeMatBundleDir) return; QDir matBundleDir(qEnvironmentVariable("MATERIAL_BUNDLE_PATH")); @@ -130,7 +130,7 @@ void MaterialBrowserBundleModel::loadMaterialBundle() } } - m_matBundleExists = true; + m_matBundleLoaded = true; QString bundleId = m_matBundleObj.value("id").toString(); @@ -184,20 +184,6 @@ void MaterialBrowserBundleModel::loadMaterialBundle() }); } -bool MaterialBrowserBundleModel::hasQuick3DImport() const -{ - return m_hasQuick3DImport; -} - -void MaterialBrowserBundleModel::setHasQuick3DImport(bool b) -{ - if (b == m_hasQuick3DImport) - return; - - m_hasQuick3DImport = b; - emit hasQuick3DImportChanged(); -} - bool MaterialBrowserBundleModel::hasMaterialRoot() const { return m_hasMaterialRoot; @@ -212,6 +198,11 @@ void MaterialBrowserBundleModel::setHasMaterialRoot(bool b) emit hasMaterialRootChanged(); } +bool MaterialBrowserBundleModel::matBundleExists() const +{ + return m_matBundleLoaded && m_quick3dMajorVersion == 6 && m_quick3dMinorVersion >= 3; +} + Internal::BundleImporter *MaterialBrowserBundleModel::bundleImporter() const { return m_importer; @@ -253,6 +244,17 @@ void MaterialBrowserBundleModel::updateImportedState(const QStringList &imported resetModel(); } +void MaterialBrowserBundleModel::setQuick3DImportVersion(int major, int minor) +{ + bool bundleExisted = matBundleExists(); + + m_quick3dMajorVersion = major; + m_quick3dMinorVersion = minor; + + if (bundleExisted != matBundleExists()) + emit matBundleExistsChanged(); +} + void MaterialBrowserBundleModel::resetModel() { beginResetModel(); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.h index 459d7c423af..beb445422e7 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserbundlemodel.h @@ -46,9 +46,8 @@ class MaterialBrowserBundleModel : public QAbstractListModel { Q_OBJECT - Q_PROPERTY(bool matBundleExists MEMBER m_matBundleExists CONSTANT) + Q_PROPERTY(bool matBundleExists READ matBundleExists NOTIFY matBundleExistsChanged) Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged) - Q_PROPERTY(bool hasQuick3DImport READ hasQuick3DImport WRITE setHasQuick3DImport NOTIFY hasQuick3DImportChanged) Q_PROPERTY(bool hasMaterialRoot READ hasMaterialRoot WRITE setHasMaterialRoot NOTIFY hasMaterialRootChanged) Q_PROPERTY(bool importerRunning MEMBER m_importerRunning NOTIFY importerRunningChanged) @@ -63,12 +62,13 @@ public: void setSearchText(const QString &searchText); void updateImportedState(const QStringList &importedMats); - bool hasQuick3DImport() const; - void setHasQuick3DImport(bool b); + void setQuick3DImportVersion(int major, int minor); bool hasMaterialRoot() const; void setHasMaterialRoot(bool b); + bool matBundleExists() const; + Internal::BundleImporter *bundleImporter() const; void resetModel(); @@ -87,6 +87,7 @@ signals: void bundleMaterialAboutToUnimport(const QmlDesigner::TypeName &type); void bundleMaterialUnimported(const QmlDesigner::NodeMetaInfo &metaInfo); void importerRunningChanged(); + void matBundleExistsChanged(); private: void loadMaterialBundle(); @@ -98,11 +99,13 @@ private: Internal::BundleImporter *m_importer = nullptr; bool m_isEmpty = true; - bool m_hasQuick3DImport = false; bool m_hasMaterialRoot = false; - bool m_matBundleExists = false; + bool m_matBundleLoaded = false; bool m_probeMatBundleDir = false; bool m_importerRunning = false; + + int m_quick3dMajorVersion = -1; + int m_quick3dMinorVersion = -1; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 41055988fdf..fcb52882f1d 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -43,6 +43,14 @@ #include #include +#ifndef QMLDESIGNER_TEST +#include +#include +#include +#include +#include +#endif + #include #include #include @@ -289,6 +297,7 @@ void MaterialBrowserView::modelAttached(Model *model) m_widget->materialBrowserModel()->setHasMaterialRoot(rootModelNode().isSubclassOf("QtQuick3D.Material")); m_hasQuick3DImport = model->hasImport("QtQuick3D"); + updateBundleMaterialsQuick3DVersion(); updateBundleMaterialsImportedState(); // Project load is already very busy and may even trigger puppet reset, so let's wait a moment @@ -482,6 +491,41 @@ void MaterialBrowserView::updateBundleMaterialsImportedState() m_widget->materialBrowserBundleModel()->updateImportedState(importedBundleMats); } +void MaterialBrowserView::updateBundleMaterialsQuick3DVersion() +{ + bool hasImport = false; + int major = -1; + int minor = -1; + const QString url {"QtQuick3D"}; + const auto imports = model()->imports(); + for (const auto &import : imports) { + if (import.url() == url) { + hasImport = true; + const int importMajor = import.majorVersion(); + if (major < importMajor) { + minor = -1; + major = importMajor; + } + if (major == importMajor) + minor = qMax(minor, import.minorVersion()); + } + } +#ifndef QMLDESIGNER_TEST + if (hasImport && major == -1) { + // Import without specifying version, so we take the kit version + auto target = ProjectExplorer::SessionManager::startupTarget(); + if (target) { + QtSupport::QtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(target->kit()); + if (qtVersion) { + major = qtVersion->qtVersion().majorVersion; + minor = qtVersion->qtVersion().minorVersion; + } + } + } +#endif + m_widget->materialBrowserBundleModel()->setQuick3DImportVersion(major, minor); +} + ModelNode MaterialBrowserView::getBundleMaterialDefaultInstance(const TypeName &type) { const QList materials = m_widget->materialBrowserModel()->materials(); @@ -511,6 +555,8 @@ void MaterialBrowserView::importsChanged(const QList &addedImports, cons bool hasQuick3DImport = model()->hasImport("QtQuick3D"); + updateBundleMaterialsQuick3DVersion(); + if (hasQuick3DImport == m_hasQuick3DImport) return; diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h index 8d8e225d349..dc81045384d 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.h @@ -69,6 +69,7 @@ private: bool isMaterial(const ModelNode &node) const; void loadPropertyGroups(); void updateBundleMaterialsImportedState(); + void updateBundleMaterialsQuick3DVersion(); void applyBundleMaterialToDropTarget(const ModelNode &bundleMat, const NodeMetaInfo &metaInfo = {}); ModelNode getBundleMaterialDefaultInstance(const TypeName &type); diff --git a/src/plugins/qmldesigner/designercore/include/import.h b/src/plugins/qmldesigner/designercore/include/import.h index c797a19ae45..7ab87f07c93 100644 --- a/src/plugins/qmldesigner/designercore/include/import.h +++ b/src/plugins/qmldesigner/designercore/include/import.h @@ -63,7 +63,9 @@ public: bool isSameModule(const Import &other) const; int majorVersion() const; + int minorVersion() const; static int majorFromVersion(const QString &version); + static int minorFromVersion(const QString &version); private: Import(const QString &url, const QString &file, const QString &version, const QString &alias, const QStringList &importPaths); diff --git a/src/plugins/qmldesigner/designercore/model/import.cpp b/src/plugins/qmldesigner/designercore/model/import.cpp index 1c217bf47b7..f01e209dfd0 100644 --- a/src/plugins/qmldesigner/designercore/model/import.cpp +++ b/src/plugins/qmldesigner/designercore/model/import.cpp @@ -102,6 +102,11 @@ int Import::majorVersion() const return majorFromVersion(m_version); } +int Import::minorVersion() const +{ + return minorFromVersion(m_version); +} + int Import::majorFromVersion(const QString &version) { if (version.isEmpty()) @@ -109,6 +114,16 @@ int Import::majorFromVersion(const QString &version) return version.split('.').first().toInt(); } +int Import::minorFromVersion(const QString &version) +{ + if (version.isEmpty()) + return -1; + const QStringList parts = version.split('.'); + if (parts.size() < 2) + return -1; + return parts[1].toInt(); +} + Utils::QHashValueType qHash(const Import &import) { return ::qHash(import.url()) ^ ::qHash(import.file()) ^ ::qHash(import.version()) ^ ::qHash(import.alias()); From ad3169bedd3953941d1e6fd82c2db5e1385919ae Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Thu, 27 Oct 2022 15:22:37 +0200 Subject: [PATCH 61/97] qds: fix mobile scroll projects template MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I guess this was removed by accident at d99a6d2efe3b56263835b67cc32d30d3bd0963dc so I just adding it back now. Task-number: QDS-8111 Change-Id: Ib42ce5cc0cf13608f07b0671adce149c15878ef0 Reviewed-by: Henning Gründl --- .../studio_templates/projects/mobile-scroll/wizard.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json index 87d0c948604..37e40ff8baf 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json +++ b/share/qtcreator/qmldesigner/studio_templates/projects/mobile-scroll/wizard.json @@ -18,6 +18,8 @@ { "key": "ProjectPluginClassName", "value": "%{ProjectName}Plugin" }, { "key": "QmlProjectFileName", "value": "%{JS: Util.fileName('%{ProjectName}', 'qmlproject')}" }, { "key": "ImportModuleName", "value": "%{ProjectName}" }, + { "key": "UIClassName", "value": "Screen01" }, + { "key": "UIClassFileName", "value": "%{JS: Util.fileName('%{UIClassName}', 'ui.qml')}" }, { "key": "IsQt6Project", "value": "%{JS: value('QtQuickVersion') !== '2.15' }" }, { "key": "QtQuickVersion", "value": "%{JS: %{TargetQtVersion}.TargetQuickVersion}" }, { "key": "QtQuickFeature", "value": "QtSupport.Wizards.FeatureQtQuick.%{QtQuickVersion}" }, From 564298bba5a4c830d8e14a9e59360c23ee6c5e0d Mon Sep 17 00:00:00 2001 From: Tim Jenssen Date: Thu, 27 Oct 2022 18:11:48 +0200 Subject: [PATCH 62/97] qmldesigner: fix crash while switching modes Task-number: QDS-7984 Change-Id: Ia1803ce062c3956390c12f0da5b86577593fd721 Reviewed-by: Mahmoud Badri Reviewed-by: Reviewed-by: Miikka Heikkinen --- .../components/materialbrowser/materialbrowserview.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index fcb52882f1d..89935205379 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -302,7 +302,7 @@ void MaterialBrowserView::modelAttached(Model *model) // Project load is already very busy and may even trigger puppet reset, so let's wait a moment // before refreshing the model - QTimer::singleShot(1000, this, [this]() { + QTimer::singleShot(1000, model, [this]() { refreshModel(true); loadPropertyGroups(); // Needs the delay because it uses metaInfo }); @@ -310,9 +310,6 @@ void MaterialBrowserView::modelAttached(Model *model) void MaterialBrowserView::refreshModel(bool updateImages) { - if (!model() || !model()->nodeInstanceView()) - return; - ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID); QList materials; @@ -581,7 +578,7 @@ void MaterialBrowserView::customNotification(const AbstractView *view, const QSt if (idx != -1) m_widget->materialBrowserModel()->selectMaterial(idx); } else if (identifier == "refresh_material_browser") { - QTimer::singleShot(0, this, [this]() { + QTimer::singleShot(0, model(), [this]() { refreshModel(true); }); } else if (identifier == "delete_selected_material") { From 2a4de97a84e21641d076d84d550d38d5e3c4a2af Mon Sep 17 00:00:00 2001 From: Mahmoud Badri Date: Thu, 27 Oct 2022 18:15:52 +0300 Subject: [PATCH 63/97] QmlDesigner: Fix toggle section expand after choosing expand all Fixes: QDS-8104 Change-Id: I6191a7b249490e6193acdd8b618c0817a3fc6ab3 Reviewed-by: Reviewed-by: Miikka Heikkinen --- .../MaterialBrowser.qml | 2 ++ .../imports/HelperWidgets/Section.qml | 17 ++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml index 7ee927f250a..55b284ba493 100644 --- a/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml +++ b/share/qtcreator/qmldesigner/materialBrowserQmlSource/MaterialBrowser.qml @@ -270,6 +270,8 @@ Item { expanded: bundleCategoryExpanded expandOnClick: false onToggleExpand: bundleCategoryExpanded = !bundleCategoryExpanded + onExpand: bundleCategoryExpanded = true + onCollapse: bundleCategoryExpanded = false Grid { width: scrollView.width diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml index 69cf7c77953..0c7b83878e6 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/Section.qml @@ -72,10 +72,19 @@ Item { Connections { target: Controller function onCollapseAll() { - if (collapsible) - section.expanded = false + if (collapsible) { + if (section.expandOnClick) + section.expanded = false + else + section.collapse() + } + } + function onExpandAll() { + if (section.expandOnClick) + section.expanded = true + else + section.expand() } - function onExpandAll() { section.expanded = true } } signal drop(var drag) @@ -83,6 +92,8 @@ Item { signal dropExit() signal showContextMenu() signal toggleExpand() + signal expand() + signal collapse() DropArea { id: dropArea From 6f837e258a2fb7f4d5d45431bde007724c0f838c Mon Sep 17 00:00:00 2001 From: Daniele Bortolotti Date: Thu, 27 Oct 2022 10:48:29 +0200 Subject: [PATCH 64/97] McuSupport: Inform only after actual kit creation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, a message about successful kit creation was printed for every kit without verification. So move the print to the actual kit creation function. Issue also reported in QTCREATORBUG-28281 Change-Id: I0e2cb463188210164a3582e7fa465a4ebb79b812 Reviewed-by: Sivert Krøvel Reviewed-by: Christian Stenger --- src/plugins/mcusupport/mcukitmanager.cpp | 10 +++++++++- src/plugins/mcusupport/mcusupportsdk.cpp | 5 ----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/plugins/mcusupport/mcukitmanager.cpp b/src/plugins/mcusupport/mcukitmanager.cpp index e400eefa7b8..84299939e1d 100644 --- a/src/plugins/mcusupport/mcukitmanager.cpp +++ b/src/plugins/mcusupport/mcukitmanager.cpp @@ -345,7 +345,15 @@ Kit *newKit(const McuTarget *mcuTarget, const McuPackagePtr &qtForMCUsSdk) k->fix(); }; - return KitManager::registerKit(init); + Kit *kit = KitManager::registerKit(init); + if (kit) { + printMessage(Tr::tr("Kit for %1 created.").arg(generateKitNameFromTarget(mcuTarget)), false); + } else { + printMessage(Tr::tr("Error registering Kit for %1.") + .arg(generateKitNameFromTarget(mcuTarget)), + true); + } + return kit; } // Kit Information diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index c2fe9e0cccc..a6959917e66 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -815,11 +815,6 @@ McuSdkRepository targetsAndPackages(const McuPackagePtr &qtForMCUsPackage, < McuKitManager::generateKitNameFromTarget(rhs.get()); }); - for (const auto &target : repo.mcuTargets) { - printMessage(McuTarget::tr("Kit for %1 created.") - .arg(McuKitManager::generateKitNameFromTarget(target.get())), - false); - } return repo; } From eabf13b4786548a057cf9c07ea998d335354e9c3 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 28 Oct 2022 10:19:49 +0200 Subject: [PATCH 65/97] Update qbs submodule to HEAD of 1.24 branch Change-Id: I3a991428981c95abd92a7e95f70aac5d3f008b7a Reviewed-by: Reviewed-by: Qt CI Bot Reviewed-by: Ivan Komissarov --- src/shared/qbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/qbs b/src/shared/qbs index f200b701f73..8cfaf76b174 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit f200b701f7307a2935f37d39db8e192d98ff7047 +Subproject commit 8cfaf76b174a47827eb32255cd1fd1d836a3dd65 From a08c49b3217e022252057aa8054c7e467b720719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sivert=20Kr=C3=B8vel?= Date: Thu, 27 Oct 2022 22:46:34 +0200 Subject: [PATCH 66/97] McuSupport: Fix version warnings Packages without version detection should not get a version warning, even if the json contains a version list. With this change, a package without version detection will not get a status with invalid version. Additionally, in the case of failed version detection, it would be helpful for the user to list the acceptable versions. The status text was updated to list these. Change-Id: I814a86c741d573732072206ef1e969790f175e6a Reviewed-by: Yasser Grimes Reviewed-by: Reviewed-by: Christian Stenger --- src/plugins/mcusupport/mcupackage.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp index ad12f62962e..63e0fb2aadc 100644 --- a/src/plugins/mcusupport/mcupackage.cpp +++ b/src/plugins/mcusupport/mcupackage.cpp @@ -140,7 +140,7 @@ void McuPackage::updateStatus() m_status = Status::ValidPathInvalidPackage; } else if (m_versionDetector && m_detectedVersion.isEmpty()) { m_status = Status::ValidPackageVersionNotDetected; - } else if (!validVersion) { + } else if (m_versionDetector && !validVersion) { m_status = Status::ValidPackageMismatchedVersion; } else { m_status = Status::ValidPackage; @@ -223,7 +223,8 @@ QString McuPackage::statusText() const : tr("Path is empty, %1 not found.").arg(displayRequiredPath); break; case Status::ValidPackageVersionNotDetected: - response = tr("Path %1 exists, but version could not be detected.").arg(displayPackagePath); + response = tr("Path %1 exists, but version %2 could not be detected.") + .arg(displayPackagePath, displayVersions); break; } return response; From 7938a8a80fae24af1b678a70ea3e84e391243671 Mon Sep 17 00:00:00 2001 From: Yasser Grimes Date: Mon, 24 Oct 2022 18:50:27 +0300 Subject: [PATCH 67/97] McuSupport: Store macros as part of McuSdkRepository To support extending the macros and calling the McuTargetFactory::expandVariables function statically, the macros are added as part of the SdkRepository. This commit also adds helper functions to extend macros other than the ones created from the packages. Change-Id: Ie7d2a9ad626782eec18738bdd3472ffd202e7a36 Reviewed-by: Rainer Keller Reviewed-by: Reviewed-by: Christian Stenger --- src/plugins/mcusupport/mcuhelpers.h | 14 ++++++ src/plugins/mcusupport/mcusupportoptions.cpp | 43 ++++++++++++++++++- src/plugins/mcusupport/mcusupportoptions.h | 9 ++++ .../mcusupport/mcusupportoptionspage.cpp | 2 +- src/plugins/mcusupport/mcusupportsdk.cpp | 6 ++- src/plugins/mcusupport/mcutargetfactory.cpp | 14 +----- src/plugins/mcusupport/mcutargetfactory.h | 1 - src/plugins/mcusupport/test/unittest.cpp | 25 ++++++++--- 8 files changed, 90 insertions(+), 24 deletions(-) diff --git a/src/plugins/mcusupport/mcuhelpers.h b/src/plugins/mcusupport/mcuhelpers.h index 0c6baf83af0..1054e87eea9 100644 --- a/src/plugins/mcusupport/mcuhelpers.h +++ b/src/plugins/mcusupport/mcuhelpers.h @@ -14,4 +14,18 @@ struct McuTargetDescription; McuTarget::OS deduceOperatingSystem(const McuTargetDescription &); QString removeRtosSuffix(const QString &environmentVariable); +template +class asKeyValueRange +{ +public: + asKeyValueRange(T &data) + : m_data{data} + {} + auto begin() { return m_data.keyValueBegin(); } + auto end() { return m_data.keyValueEnd(); } + +private: + T &m_data; +}; + } // namespace McuSupport::Internal diff --git a/src/plugins/mcusupport/mcusupportoptions.cpp b/src/plugins/mcusupport/mcusupportoptions.cpp index edd7ac13bfc..9dead1d5550 100644 --- a/src/plugins/mcusupport/mcusupportoptions.cpp +++ b/src/plugins/mcusupport/mcusupportoptions.cpp @@ -3,6 +3,7 @@ #include "mcusupportoptions.h" +#include "mcuhelpers.h" #include "mcukitmanager.h" #include "mcupackage.h" #include "mcusupportconstants.h" @@ -16,16 +17,49 @@ #include #include #include +#include #include #include #include #include +#include + using namespace Utils; namespace McuSupport::Internal { +Macros *McuSdkRepository::globalMacros() +{ + static Macros macros; + return ¯os; +} + +void McuSdkRepository::expandVariables() +{ + auto macroExpander = getMacroExpander(); + for (const auto &package : std::as_const(packages)) + package->setPath(macroExpander->expand(package->path())); +} + +MacroExpanderPtr McuSdkRepository::getMacroExpander() +{ + auto macroExpander = std::make_shared(); + + //register the macros + for (const auto &package : std::as_const(packages)) { + macroExpander->registerVariable(package->cmakeVariableName().toLocal8Bit(), + package->label(), + [package] { return package->path().toString(); }); + } + + for (auto [key, macro] : asKeyValueRange(*globalMacros())) + macroExpander->registerVariable(key.toLocal8Bit(), "QtMCUs Macro", macro); + + return macroExpander; +} + McuSupportOptions::McuSupportOptions(const SettingsHandler::Ptr &settingsHandler, QObject *parent) : QObject(parent) , qtForMCUsSdkPackage(createQtForMCUsPackage(settingsHandler)) @@ -93,8 +127,15 @@ bool McuSupportOptions::isLegacyVersion(const QVersionNumber &version) return version < newVersion; } -void McuSupportOptions::setQulDir(const FilePath &) +void McuSupportOptions::setQulDir(const FilePath &path) { + //register the Qt installation directory containing Qul dir + auto qtPath = (path / "../..").cleanPath(); + if (qtPath.exists()) { + McuSdkRepository::globalMacros()->insert("QtDir", [qtPathString = qtPath.path()] { + return qtPathString; + }); + } qtForMCUsSdkPackage->updateStatus(); if (qtForMCUsSdkPackage->isValidStatus()) sdkRepository = targetsAndPackages(qtForMCUsSdkPackage, settingsHandler); diff --git a/src/plugins/mcusupport/mcusupportoptions.h b/src/plugins/mcusupport/mcusupportoptions.h index 945c748dff0..220fc54f125 100644 --- a/src/plugins/mcusupport/mcusupportoptions.h +++ b/src/plugins/mcusupport/mcusupportoptions.h @@ -8,6 +8,7 @@ #include "settingshandler.h" #include +#include #include #include @@ -30,11 +31,19 @@ namespace Internal { class McuAbstractPackage; +using MacroExpanderPtr = std::shared_ptr; +using Macros = QHash; + class McuSdkRepository final { public: Targets mcuTargets; Packages packages; + + void expandVariables(); + MacroExpanderPtr getMacroExpander(); + + static Macros *globalMacros(); }; class McuSupportOptions final : public QObject diff --git a/src/plugins/mcusupport/mcusupportoptionspage.cpp b/src/plugins/mcusupport/mcusupportoptionspage.cpp index f728851774f..556dfd0e216 100644 --- a/src/plugins/mcusupport/mcusupportoptionspage.cpp +++ b/src/plugins/mcusupport/mcusupportoptionspage.cpp @@ -289,7 +289,7 @@ void McuSupportOptionsWidget::apply() bool pathsChanged = false; m_settingsHandler->setAutomaticKitCreation(m_options.automaticKitCreationEnabled()); - McuTargetFactory::expandVariables(m_options.sdkRepository.packages); + m_options.sdkRepository.expandVariables(); QMessageBox warningPopup(QMessageBox::Icon::Warning, Tr::tr("Warning"), diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index a6959917e66..76f24206797 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -591,7 +591,11 @@ McuSdkRepository targetsFromDescriptions(const QList &desc mcuPackages.insert(package); } } - return McuSdkRepository{mcuTargets, mcuPackages}; + + McuSdkRepository repo{mcuTargets, mcuPackages}; + repo.expandVariables(); + + return repo; } FilePath kitsPath(const FilePath &qtMcuSdkPath) diff --git a/src/plugins/mcusupport/mcutargetfactory.cpp b/src/plugins/mcusupport/mcutargetfactory.cpp index ae79aeee359..6f5be2a1026 100644 --- a/src/plugins/mcusupport/mcutargetfactory.cpp +++ b/src/plugins/mcusupport/mcutargetfactory.cpp @@ -4,6 +4,7 @@ #include "mcutargetfactory.h" #include "mcuhelpers.h" #include "mcupackage.h" +#include "mcusupport_global.h" #include "mcusupportplugin.h" #include "mcusupportversiondetection.h" #include "mcutarget.h" @@ -56,18 +57,6 @@ static void removeEmptyPackages(Packages &packages) } } -void McuTargetFactory::expandVariables(Packages &packages) -{ - Utils::MacroExpander macroExpander; - for (const auto &package : packages) { - macroExpander.registerVariable(package->cmakeVariableName().toLocal8Bit(), - package->label(), - [package] { return package->path().toString(); }); - } - for (const auto &package : packages) - package->setPath(macroExpander.expand(package->path())); -} - McuTargetFactory::McuTargetFactory(const SettingsHandler::Ptr &settingsHandler) : settingsHandler{settingsHandler} {} @@ -94,7 +83,6 @@ QPair McuTargetFactory::createTargets(const McuTargetDescript targetPackages.unite({toolchainFile}); removeEmptyPackages(targetPackages); - expandVariables(targetPackages); packages.unite(targetPackages); diff --git a/src/plugins/mcusupport/mcutargetfactory.h b/src/plugins/mcusupport/mcutargetfactory.h index bb18ea40a39..94451b4c07f 100644 --- a/src/plugins/mcusupport/mcutargetfactory.h +++ b/src/plugins/mcusupport/mcutargetfactory.h @@ -22,7 +22,6 @@ public: Packages createPackages(const McuTargetDescription &); McuToolChainPackage *createToolchain(const McuTargetDescription::Toolchain &, const Utils::FilePath &sourceFile = Utils::FilePath()); McuPackagePtr createPackage(const PackageDescription &); - static void expandVariables(Packages &packages); private: SettingsHandler::Ptr settingsHandler; diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index 090ed89cd5c..ca28f925bb6 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -196,6 +196,11 @@ const McuTargetDescription::Platform platformDescription{id, const Id cxxLanguageId{ProjectExplorer::Constants::CXX_LANGUAGE_ID}; } // namespace +//Expand variables in a tested {targets, packages} pair +auto expandTargetsAndPackages = [](Targets &targets, Packages &packages) { + McuSdkRepository{targets, packages}.expandVariables(); +}; + void verifyIarToolchain(const McuToolChainPackagePtr &iarToolchainPackage) { ProjectExplorer::ToolChainFactory toolchainFactory; @@ -676,7 +681,7 @@ void McuSupportTest::test_legacy_createPackagesWithCorrespondingSettings() { QFETCH(QString, json); const McuTargetDescription description = parseDescriptionJson(json.toLocal8Bit()); - const auto [targets, packages]{ + auto [targets, packages]{ targetsFromDescriptions({description}, settingsMockPtr, sdkPackagePtr, runLegacy)}; Q_UNUSED(targets); @@ -701,7 +706,8 @@ void McuSupportTest::test_createTargets() true}; targetDescription.toolchain.id = armGcc; - const auto [targets, packages]{targetFactory.createTargets(targetDescription, sdkPackagePtr)}; + auto [targets, packages]{targetFactory.createTargets(targetDescription, sdkPackagePtr)}; + expandTargetsAndPackages(targets, packages); QCOMPARE(targets.size(), 1); const McuTargetPtr target{targets.at(0)}; @@ -1154,7 +1160,8 @@ void McuSupportTest::test_createFreeRtosPackage() EXPECT_CALL(*settingsMockPtr, getPath(targetDescription.boardSdk.envVar, _, _)) .WillRepeatedly(Return(FilePath::fromString(boardSdkDir))); - auto [targets, packages] = targetFactory.createTargets(targetDescription, sdkPackagePtr); + auto [targets, packages]{targetFactory.createTargets(targetDescription, sdkPackagePtr)}; + expandTargetsAndPackages(targets, packages); auto freeRtos = findOrDefault(packages, [](const McuPackagePtr &pkg) { return (pkg->cmakeVariableName() == freeRtosCMakeVar); @@ -1379,7 +1386,8 @@ void McuSupportTest::test_resolveEnvironmentVariablesInDefaultPath() toochainFileDescription.defaultPath = FilePath::fromUserInput(toolchainFileDefaultPath); targetDescription.toolchain.file = toochainFileDescription; - auto [targets, packages] = targetFactory.createTargets(targetDescription, sdkPackagePtr); + auto [targets, packages]{targetFactory.createTargets(targetDescription, sdkPackagePtr)}; + expandTargetsAndPackages(targets, packages); auto qtForMCUPkg = findOrDefault(packages, [](const McuPackagePtr &pkg) { return pkg->environmentVariableName() == QUL_ENV_VAR; }); @@ -1413,7 +1421,8 @@ void McuSupportTest::test_resolveCmakeVariablesInDefaultPath() toochainFileDescription.defaultPath = FilePath::fromUserInput(toolchainFileDefaultPath); targetDescription.toolchain.file = toochainFileDescription; - auto [targets, packages] = targetFactory.createTargets(targetDescription, sdkPackagePtr); + auto [targets, packages]{targetFactory.createTargets(targetDescription, sdkPackagePtr)}; + expandTargetsAndPackages(targets, packages); auto qtForMCUPkg = findOrDefault(packages, [](const McuPackagePtr &pkg) { return pkg->cmakeVariableName() == QUL_CMAKE_VAR; }); @@ -1541,6 +1550,7 @@ void McuSupportTest::test_createThirdPartyPackage() .WillOnce(Return(FilePath::fromUserInput(path))); auto [targets, packages] = targetFactory.createTargets(targetDescription, sdkPackagePtr); + expandTargetsAndPackages(targets, packages); auto thirdPartyPackage = findOrDefault(packages, [&setting](const McuPackagePtr &pkg) { return (pkg->settingsKey() == setting); @@ -1588,6 +1598,7 @@ void McuSupportTest::test_createJLink3rdPartyPackage() .WillOnce(Return(FilePath::fromUserInput(jlinkPath))); auto [targets, packages] = targetFactory.createTargets(targetDescription, sdkPackagePtr); + expandTargetsAndPackages(targets, packages); auto thirdPartyPackage = findOrDefault(packages, [](const McuPackagePtr &pkg) { return (pkg->settingsKey() == jlinkSetting); @@ -1653,7 +1664,6 @@ void McuSupportTest::test_nonemptyVersionDetector() // pkgDesc.versionDetection.xmlElement left empty // pkgDesc.versionDetection.xmlAttribute left empty pkgDesc.shouldAddToSystemPath = false; - const auto package = targetFactory.createPackage(pkgDesc); QVERIFY(package->getVersionDetector() != nullptr); QCOMPARE(typeid(*package->getVersionDetector()).name(), @@ -1686,7 +1696,8 @@ void McuSupportTest::test_emptyVersionDetector() void McuSupportTest::test_emptyVersionDetectorFromJson() { const auto targetDescription = parseDescriptionJson(armgcc_mimxrt1050_evk_freertos_json); - auto [targets, packages] = targetFactory.createTargets(targetDescription, sdkPackagePtr); + auto [targets, packages]{targetFactory.createTargets(targetDescription, sdkPackagePtr)}; + expandTargetsAndPackages(targets, packages); auto freeRtos = findOrDefault(packages, [](const McuPackagePtr &pkg) { return (pkg->cmakeVariableName() == freeRtosCMakeVar); From 4bf80319441690ed46c7a14b6d6d59dc9b7a33fb Mon Sep 17 00:00:00 2001 From: Daniele Bortolotti Date: Thu, 27 Oct 2022 17:37:40 +0200 Subject: [PATCH 68/97] McuSupport: Update test json files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Match recent changes in QUL repository. Change-Id: Ib00f829a5a866dfc1a76c581c71e1338b29c214d Reviewed-by: Sivert Krøvel Reviewed-by: Reviewed-by: Yasser Grimes Reviewed-by: Christian Stenger --- src/plugins/mcusupport/test/gcc_desktop_json.h | 3 ++- .../mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h | 11 ++++++++++- src/plugins/mcusupport/test/mingw_desktop_json.h | 8 +++++++- src/plugins/mcusupport/test/msvc_desktop_json.h | 3 ++- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/plugins/mcusupport/test/gcc_desktop_json.h b/src/plugins/mcusupport/test/gcc_desktop_json.h index 59e3b499362..d7ba56ffd9b 100644 --- a/src/plugins/mcusupport/test/gcc_desktop_json.h +++ b/src/plugins/mcusupport/test/gcc_desktop_json.h @@ -29,7 +29,8 @@ constexpr auto gcc_desktop_json = R"( "executableArgs": "--version", "filePattern": "bin/g++", "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" - } + }, + "detectionPath": "bin/g++" } } } diff --git a/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h b/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h index 2b10ac19b1d..132cf0319e8 100644 --- a/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h +++ b/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h @@ -45,7 +45,16 @@ constexpr auto ghs_rh850_d1m1a_baremetal_json = R"( "setting": "GHSToolchain", "label": "Green Hills Compiler", "type": "path", - "optional": false + "optional": false, + "versionDetection": { + "filePattern": "gversion", + "executableArgs": "-help", + "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": { + "windows": "cxv850.exe", + "linux": "cxv850" + } }, "file": { "cmakeVar": "CMAKE_TOOLCHAIN_FILE", diff --git a/src/plugins/mcusupport/test/mingw_desktop_json.h b/src/plugins/mcusupport/test/mingw_desktop_json.h index c8c94a4cdc8..b87048ecfa7 100644 --- a/src/plugins/mcusupport/test/mingw_desktop_json.h +++ b/src/plugins/mcusupport/test/mingw_desktop_json.h @@ -22,7 +22,13 @@ constexpr auto mingw_desktop_json = R"( ], "compiler": { "label": "MinGW Toolchain", - "defaultValue": "%{QT_TOOLS_DIR}/mingw1120_64" + "defaultValue": "%{QT_TOOLS_DIR}/mingw1120_64", + "detectionPath": "bin/g++.exe", + "versionDetection": { + "filePattern": "bin//g++.exe", + "executableArgs": "--version", + "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" + } } } } diff --git a/src/plugins/mcusupport/test/msvc_desktop_json.h b/src/plugins/mcusupport/test/msvc_desktop_json.h index c2862d72416..058973d65ed 100644 --- a/src/plugins/mcusupport/test/msvc_desktop_json.h +++ b/src/plugins/mcusupport/test/msvc_desktop_json.h @@ -37,7 +37,8 @@ constexpr auto msvc_desktop_json = R"( "filePattern": "cl.exe", "executableArgs": "--version", "regex": "\\b(\\d+\\.\\d+)\\.\\d+\\b" - } + }, + "detectionPath": "cl.exe" } } } From d063e21c2e9fe1bc39a0cbd2d6a6f667fd982f26 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Fri, 28 Oct 2022 12:22:43 +0200 Subject: [PATCH 69/97] SquishTests: Update and stabilize tst_HELP06 Change-Id: I1d97a550c9b63b8b04f0bd32d23c5bf249b6ccc5 Reviewed-by: Reviewed-by: Christian Stenger --- tests/system/objects.map | 8 ++++---- tests/system/suite_HELP/tst_HELP06/test.py | 7 ++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/system/objects.map b/tests/system/objects.map index 6d7a96a03fa..ab349732385 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -14,12 +14,12 @@ :*Qt Creator_Utils::FilterLineEdit {type='Utils::FancyLineEdit' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :*Qt Creator_Utils::IconButton {occurrence='4' type='Utils::IconButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :About Qt Creator_Core::Internal::VersionDialog {type='Core::Internal::VersionDialog' unnamed='1' visible='1' windowTitle='About Qt Creator'} -:Add Bookmark.ExpandBookmarksList_QToolButton {name='toolButton' text='+' type='QToolButton' visible='1' window=':Add Bookmark_BookmarkDialog'} -:Add Bookmark.New Folder_QPushButton {name='newFolderButton' text='New Folder' type='QPushButton' visible='1' window=':Add Bookmark_BookmarkDialog'} +:Add Bookmark.ExpandBookmarksList_QToolButton {text='+' type='QToolButton' unnamed='1' visible='1' window=':Add Bookmark_BookmarkDialog'} +:Add Bookmark.New Folder_QPushButton {text='New Folder' type='QPushButton' unnamed='1' visible='1' window=':Add Bookmark_BookmarkDialog'} :Add Bookmark.OK_QPushButton {text='OK' type='QPushButton' unnamed='1' visible='1' window=':Add Bookmark_BookmarkDialog'} :Add Bookmark.treeView_QExpandingLineEdit {container=':Add Bookmark.treeView_QTreeView' type='QExpandingLineEdit' unnamed='1' visible='1'} -:Add Bookmark.treeView_QTreeView {name='treeView' type='QTreeView' visible='1' window=':Add Bookmark_BookmarkDialog'} -:Add Bookmark_BookmarkDialog {name='BookmarkDialog' type='BookmarkDialog' visible='1' windowTitle='Add Bookmark'} +:Add Bookmark.treeView_QTreeView {type='QTreeView' unnamed='1' visible='1' window=':Add Bookmark_BookmarkDialog'} +:Add Bookmark_BookmarkDialog {type='BookmarkDialog' unnamed='1' visible='1' windowTitle='Add Bookmark'} :Add to Version Control.No_QPushButton {text='No' type='QPushButton' unnamed='1' visible='1' window=':Add to Version Control_QMessageBox'} :Add to Version Control_QMessageBox {type='QMessageBox' unnamed='1' visible='1' windowTitle='Add to Version Control'} :Analyzer Toolbar.AnalyzerManagerToolBox_QComboBox {container=':DebugModeWidget.Toolbar_QDockWidget' name='PerspectiveChooser' type='QComboBox' visible='1'} diff --git a/tests/system/suite_HELP/tst_HELP06/test.py b/tests/system/suite_HELP/tst_HELP06/test.py index 6b9e1c57246..96c3cc8b46f 100644 --- a/tests/system/suite_HELP/tst_HELP06/test.py +++ b/tests/system/suite_HELP/tst_HELP06/test.py @@ -11,11 +11,10 @@ def renameBookmarkFolder(view, item, newName): return def invokeContextMenuItemOnBookmarkFolder(view, item, menuItem): - aboveWidget = "{name='line' type='QFrame' visible='1' window=':Add Bookmark_BookmarkDialog'}" mouseClick(waitForObjectItem(view, item)) openItemContextMenu(view, item, 5, 5, 0) - activateItem(waitForObject("{aboveWidget=%s type='QMenu' unnamed='1' visible='1' " - "window=':Add Bookmark_BookmarkDialog'}" % aboveWidget), menuItem) + activateItem(waitForObjectItem("{type='QMenu' unnamed='1' visible='1' " + "window=':Add Bookmark_BookmarkDialog'}", menuItem)) def textForQtVersion(text): suffix = "Qt Creator Manual" @@ -51,6 +50,8 @@ def main(): # create root bookmark directory clickButton(waitForObject(":Add Bookmark.New Folder_QPushButton")) # rename root bookmark directory + bookmarkDialog = waitForObject(":Add Bookmark_BookmarkDialog") + waitFor("bookmarkDialog.isActiveWindow") bookmarkView = waitForObject(":Add Bookmark.treeView_QTreeView") renameBookmarkFolder(bookmarkView, "New Folder*", "Sample") # create two more subfolders From 836d964a9dc1c3ce7ebc2ba668dae8cf060638b5 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 27 Oct 2022 09:04:36 -0700 Subject: [PATCH 70/97] Utils: fix build with implicit QPrivateSignal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit fcd294a9ec2a17b3512d03e84ae3560d7fcd3f74 in qtbase made QPrivateSignal constructors explicit. You have to spell it out. locatorfilter.cpp:71:25: error: converting to ‘LanguageClient::DocumentLocatorFilter::QPrivateSignal’ from initializer list would use explicit constructor ‘constexpr LanguageClient::DocumentLocatorFilter::QPrivateSignal::QPrivateSignal()’ Change-Id: I07ec23f3cb174fb197c3fffd1721f899ae46f8cb Reviewed-by: Giuseppe D'Angelo --- src/plugins/languageclient/locatorfilter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/languageclient/locatorfilter.cpp b/src/plugins/languageclient/locatorfilter.cpp index 6dd843900da..b6300b54a3d 100644 --- a/src/plugins/languageclient/locatorfilter.cpp +++ b/src/plugins/languageclient/locatorfilter.cpp @@ -90,7 +90,7 @@ void DocumentLocatorFilter::updateSymbols(const DocumentUri &uri, return; QMutexLocker locker(&m_mutex); m_currentSymbols = symbols; - emit symbolsUpToDate({}); + emit symbolsUpToDate(QPrivateSignal()); } void DocumentLocatorFilter::resetSymbols() From 18553f051cf5fb6a2c16eb8b047158ab9eecf388 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 27 Oct 2022 16:26:26 +0200 Subject: [PATCH 71/97] Doc: Remove \if defined statements from files not used in QDS Change-Id: Ib6c3bf5a89faab97fd28b47e033925c2f4f30f55 Reviewed-by: Leena Miettinen --- doc/qtcreator/src/android/androiddev.qdoc | 4 ---- doc/qtcreator/src/android/deploying-android.qdoc | 2 -- .../src/howto/creator-only/creator-logging-viewer.qdoc | 4 ---- .../creator-only/creator-projects-builds-customizing.qdoc | 5 ----- .../creator-only/creator-projects-settings-dependencies.qdoc | 4 ---- 5 files changed, 19 deletions(-) diff --git a/doc/qtcreator/src/android/androiddev.qdoc b/doc/qtcreator/src/android/androiddev.qdoc index 42807c35728..b0f7123eef3 100644 --- a/doc/qtcreator/src/android/androiddev.qdoc +++ b/doc/qtcreator/src/android/androiddev.qdoc @@ -4,11 +4,7 @@ /*! \page creator-developing-android.html \previouspage creator-connecting-mobile.html - \if defined(qtdesignstudio) - \nextpage creator-developing-generic-linux.html - \else \nextpage creator-developing-baremetal.html - \endif \title Connecting Android Devices diff --git a/doc/qtcreator/src/android/deploying-android.qdoc b/doc/qtcreator/src/android/deploying-android.qdoc index 64bad026294..cb90091da65 100644 --- a/doc/qtcreator/src/android/deploying-android.qdoc +++ b/doc/qtcreator/src/android/deploying-android.qdoc @@ -34,10 +34,8 @@ packages, select \uicontrol Projects > \uicontrol Build > \uicontrol {Build Android APK} > \uicontrol Details. - \if defined(qtcreator) For more information about options that you have for running applications, see \l {Specifying Run Settings for Android Devices}. - \endif \section1 Packaging Applications diff --git a/doc/qtcreator/src/howto/creator-only/creator-logging-viewer.qdoc b/doc/qtcreator/src/howto/creator-only/creator-logging-viewer.qdoc index 8fa7914765f..38e4b92d1ce 100644 --- a/doc/qtcreator/src/howto/creator-only/creator-logging-viewer.qdoc +++ b/doc/qtcreator/src/howto/creator-only/creator-logging-viewer.qdoc @@ -3,11 +3,7 @@ /*! \page creator-logging-viewer.html - \if defined(qtdesignstudio) - \previouspage creator-quick-ui-forms.html - \else \previouspage creator-task-lists.html - \endif \nextpage creator-telemetry.html \title Inspecting Internal Logs diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-builds-customizing.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-builds-customizing.qdoc index 7def0059106..0a7c1df2ac6 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-builds-customizing.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-builds-customizing.qdoc @@ -9,13 +9,8 @@ /*! \page creator-build-process-customizing.html - \if defined(qtdesignstudio) - \previouspage creator-developing-generic-linux.html - \nextpage studio-advanced.html - \else \previouspage creator-setup-webassembly.html \nextpage creator-testing.html - \endif \title Customizing the Build Process diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-settings-dependencies.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-settings-dependencies.qdoc index d40c77300aa..bda2c5b5e71 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-settings-dependencies.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-settings-dependencies.qdoc @@ -10,11 +10,7 @@ /*! \page creator-build-dependencies.html \previouspage creator-code-style-settings.html - \if defined(qtdesignstudio) - \nextpage studio-designing.html - \else \nextpage creator-project-settings-environment.html - \endif \title Specifying Dependencies From da364bd4dfa4449be6e3cf10743f6d50f36027d6 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 19 Oct 2022 09:40:28 +0200 Subject: [PATCH 72/97] Translations: Add targets that update translations without the cruft Without obsolete and vanished translations, and files and line numbers. Which is what we would in the end submit into the repository. run with `cmake --build . --target ts__cleaned` Change-Id: If5b73f19d8fc7b49bcf95fbeb0b0ff7793056cca Reviewed-by: Eike Ziller --- cmake/QtCreatorTranslations.cmake | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cmake/QtCreatorTranslations.cmake b/cmake/QtCreatorTranslations.cmake index 2dab35b3b27..cd50d72f101 100644 --- a/cmake/QtCreatorTranslations.cmake +++ b/cmake/QtCreatorTranslations.cmake @@ -96,6 +96,13 @@ function(_create_ts_custom_target name) COMMENT "Generate .ts files" DEPENDS ${_sources} VERBATIM) + + add_custom_target("${_arg_TS_TARGET_PREFIX}${name}_cleaned" + COMMAND Qt5::lupdate -locations relative -no-ui-lines -no-sort -no-obsolete -locations none "@${ts_file_list}" -ts ${ts_files} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Generate .ts files, remove obsolete and vanished translations, and do not add files and line number" + DEPENDS ${_sources} + VERBATIM) endfunction() function(add_translation_targets file_prefix) From d173f532c75cf3dd36ff74ffe5ce1c0e3eb4d3f9 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 24 Oct 2022 17:45:46 +0200 Subject: [PATCH 73/97] Doc: Describe conditions for automatically finding ccache on macOS Task-number: QTCREATORBUG-27876 Change-Id: I01f671c3f2b36e97c56ce3649ef5ab38d1a067c3 Reviewed-by: Reviewed-by: Eike Ziller --- doc/qtcreator/images/qtcreator-toolchains.png | Bin 22497 -> 31654 bytes .../creator-projects-compilers.qdoc | 14 ++++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/doc/qtcreator/images/qtcreator-toolchains.png b/doc/qtcreator/images/qtcreator-toolchains.png index c82b677b5db0b7a95b9bb7871f8d940576662abd..938762a6e629e80b43856899a8d6702cf6ba8a2e 100644 GIT binary patch literal 31654 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 O&+qB#=d#Wzp$Pz8D$+y% literal 22497 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 diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-compilers.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-compilers.qdoc index 97ca9bd70a4..cac8caf3a80 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-compilers.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-compilers.qdoc @@ -22,10 +22,16 @@ \QC automatically detects the compilers that are registered by your system or by the Qt Installer and lists them in \uicontrol Edit > - \uicontrol Preferences > \uicontrol Kits > \uicontrol Compilers: + \uicontrol Preferences > \uicontrol Kits > \uicontrol Compilers. \image qtcreator-toolchains.png + \note On \macos, the \c ccache C/C++ compiler cache is detected + automatically only if you installed it using Homebrew or MacPorts. + When using MacPorts, you also need to create symlinks, as instructed in + \l{https://trac.macports.org/wiki/howto/ccache}{How to enable ccache} + in the MacPorts wiki. + You can add the following compilers to build applications by using other compilers or by using additional versions of the automatically detected compilers: @@ -68,16 +74,16 @@ \li \l{https://www.iar.com/iar-embedded-workbench/}{IAREW} is a group of C and C++ bare-metal compilers from the various IAR Embedded Workbench development environments. - \note Currently supported architectures are \c 8051, \c AVR, \c ARM, + Currently supported architectures are \c 8051, \c AVR, \c ARM, \c STM8, and \c MSP430. \li \l{https://www.keil.com}{KEIL} is a group of C and C++ bare-metal compilers from the various KEIL development environments. - \note Currently supported architectures are \c 8051 and \c ARM. + Currently supported architectures are \c 8051 and \c ARM. \li \l{http://sdcc.sourceforge.net}{SDCC} is a retargetable, optimizing C bare-metal compiler for various architectures. - \note Currently supported architectures are \c 8051 and \c STM8. + Currently supported architectures are \c 8051 and \c STM8. \endlist From c9f39972cd0b815f36dcf3b6b3b9b6bd315b75c7 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Thu, 27 Oct 2022 11:53:05 +0300 Subject: [PATCH 74/97] More change log Change-Id: I248425c35d1a2aed46dc637aaf3dc18a36c560c1 Reviewed-by: Leena Miettinen Reviewed-by: Eike Ziller --- dist/changelog/changes-9.0.0.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dist/changelog/changes-9.0.0.md b/dist/changelog/changes-9.0.0.md index f871a0926f5..f9abdee16a9 100644 --- a/dist/changelog/changes-9.0.0.md +++ b/dist/changelog/changes-9.0.0.md @@ -34,6 +34,7 @@ Editing * Added option for `Tint whole margin area` * Added option for line spacing (QTCREATORBUG-13727) * Added `Create Cursors at Selected Line Ends` +* Added support for character encoding in binary/memory editor * Improved UI for multiple markers on the same line (QTCREATORBUG-27415) * Fixed performance issue with large selections * Fixed saving files with non-breaking spaces (QTCREATORBUG-17875) @@ -76,10 +77,6 @@ Editing * Fixed that server was not restarted after 5 times, even if a long time passed after the last time -### Binaries - -* Added support for character encoding - ### Image Viewer * Made `Fit to Screen` sticky and added option for the default @@ -88,6 +85,7 @@ Editing ### Diff Viewer * Fixed that calculating differences blocked Qt Creator +* Fixed that description widget height was not persistent (QTCREATORBUG-24286) Projects -------- @@ -105,6 +103,7 @@ Projects toolchain files (QTCREATORBUG-24555) * Added option for changing environment for configure step * Added option for hiding subfolders in source groups (QTCREATORBUG-27432) +* Added support for `Build File` also from header files (QTCREATORBUG-26164) * Fixed that `PATH` environment variable was not completely set up during first CMake run * Fixed issues with importing builds using Visual C++ generator @@ -132,6 +131,9 @@ Version Control Systems ### Git * Added support for user-configured comment character (QTCREATORBUG-28042) +* Improved matching of commit hashes (QTCREATORBUG-24768, QTCREATORBUG-28268) +* Fixed adding or deleting files in nested directories (QTCREATORBUG-27644, QTCREATORBUG-27405) +* Fixed that text encoding in project settings was not respected on diff Test Integration ---------------- From 9d8106e54adcf5a05cfc39a6177b1d6486f3a81c Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 19 Oct 2022 13:50:23 +0200 Subject: [PATCH 75/97] TerminalProcess: Fix stopping the terminal Fixes 30 seconds freeze when stopping the terminal during debugging (when being interrupted on some breakpoint). Fixes also the freeze on closing the preferences dialog after opening the remote shell via "Open Remote Shell" and keeping it open. Fixes: QTCREATORBUG-28365 Change-Id: I15dfd9cba02d03e0ba65878c5285ea8cc96d8aad Reviewed-by: Christian Kandeler Reviewed-by: David Schulz Reviewed-by: Eike Ziller --- src/libs/utils/terminalprocess.cpp | 31 ++++++++++++++++-------------- src/plugins/debugger/terminal.cpp | 5 +---- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/libs/utils/terminalprocess.cpp b/src/libs/utils/terminalprocess.cpp index 575b8562f2e..19d6866f2f7 100644 --- a/src/libs/utils/terminalprocess.cpp +++ b/src/libs/utils/terminalprocess.cpp @@ -9,7 +9,6 @@ #include "qtcassert.h" #include "qtcprocess.h" #include "terminalcommand.h" -#include "winutils.h" #include #include @@ -22,17 +21,19 @@ #ifdef Q_OS_WIN -# include -# include -# include +#include "winutils.h" + +#include +#include +#include #else -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include #endif @@ -423,7 +424,9 @@ void TerminalImpl::sendControlSignal(ControlSignal controlSignal) switch (controlSignal) { case ControlSignal::Terminate: case ControlSignal::Kill: - stopProcess(); + killProcess(); + if (HostOsInfo::isWindowsHost()) + killStub(); break; case ControlSignal::Interrupt: sendCommand('i'); @@ -468,13 +471,13 @@ void TerminalImpl::killStub() TerminateProcess(d->m_pid->hProcess, (unsigned)-1); WaitForSingleObject(d->m_pid->hProcess, INFINITE); cleanupStub(); + emitFinished(-1, QProcess::CrashExit); #else sendCommand('s'); stubServerShutdown(); + d->m_process.stop(); d->m_process.waitForFinished(); #endif - - emitFinished(-1, QProcess::CrashExit); } void TerminalImpl::stopProcess() @@ -519,13 +522,13 @@ QString TerminalImpl::stubServerListen() if (errno != EEXIST) return msgCannotCreateTempDir(stubFifoDir, QString::fromLocal8Bit(strerror(errno))); } - const QString stubServer = stubFifoDir + QLatin1String("/stub-socket"); + const QString stubServer = stubFifoDir + QLatin1String("/stub-socket"); if (!d->m_stubServer.listen(stubServer)) { ::rmdir(d->m_stubServerDir.constData()); return QtcProcess::tr("Cannot create socket \"%1\": %2") .arg(stubServer, d->m_stubServer.errorString()); } - return QString(); + return {}; #endif } diff --git a/src/plugins/debugger/terminal.cpp b/src/plugins/debugger/terminal.cpp index 70e8749c635..330eb763358 100644 --- a/src/plugins/debugger/terminal.cpp +++ b/src/plugins/debugger/terminal.cpp @@ -193,11 +193,8 @@ void TerminalRunner::start() void TerminalRunner::stop() { - if (m_stubProc && m_stubProc->isRunning()) { + if (m_stubProc && m_stubProc->isRunning()) m_stubProc->stop(); - m_stubProc->waitForFinished(); - } - reportStopped(); } void TerminalRunner::stubStarted() From ce89ee59c533c51daf50dc347e39cb890ccdd463 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 21 Oct 2022 17:20:33 +0200 Subject: [PATCH 76/97] Translations: Remove duplicates Amends: 698583dc01a1a7a3315a52acc15b7e7026397ca3 Change-Id: Ia3dfa1743b9959c85cd09b59c3ca08b82c18fa0e Reviewed-by: Eike Ziller --- share/qtcreator/translations/qtcreator_cs.ts | 156 ----------------- share/qtcreator/translations/qtcreator_de.ts | 8 - share/qtcreator/translations/qtcreator_fr.ts | 157 +----------------- share/qtcreator/translations/qtcreator_ja.ts | 4 - share/qtcreator/translations/qtcreator_ru.ts | 8 - .../qtcreator/translations/qtcreator_zh_CN.ts | 156 ----------------- 6 files changed, 2 insertions(+), 487 deletions(-) diff --git a/share/qtcreator/translations/qtcreator_cs.ts b/share/qtcreator/translations/qtcreator_cs.ts index 7d7350c717c..4d7e01c4bd9 100644 --- a/share/qtcreator/translations/qtcreator_cs.ts +++ b/share/qtcreator/translations/qtcreator_cs.ts @@ -14619,46 +14619,6 @@ Další podrobnosti hledejte v /etc/sysctl.d/10-ptrace.conf TextEditor::DisplaySettingsPage - - Display - Zobrazení - - - Display line &numbers - &Zobrazit čísla řádků - - - Display &folding markers - Zobrazit znaky s&kládání kódu - - - Show tabs and spaces. - Ukázat zarážky a prázdné znaky (mezery). - - - &Visualize whitespace - &Zviditelnit prázdné znaky - - - Highlight current &line - Zvýraznit nynější řá&dek - - - Text Wrapping - Zalomení textu - - - Enable text &wrapping - Povolit &zalomení textu - - - Display right &margin at column: - Zobrazit pravý &okraj sloupce: - - - Highlight &blocks - Zvýraznit &bloky - Animate matching parentheses Rozhýbat odpovídající závorky @@ -14675,22 +14635,6 @@ Další podrobnosti hledejte v /etc/sysctl.d/10-ptrace.conf Mark text changes Vyznačit textové změny - - Mark &text changes - Vyznačit &textové změny - - - &Animate matching parentheses - &Rozhýbat odpovídající závorky - - - Auto-fold first &comment - Automaticky složit první po&známku - - - Center &cursor on scroll - Při projíždění držet &ukazovátko vprostřed - TextEditor::FontSettingsPage @@ -30795,14 +30739,6 @@ Určuje, jak se chová zpětná klávesa (backspace) co se týče odsazování. TextEditor::TabSettingsWidget - - Form - Formulář - - - Tabs And Indentation - Zarážky a odsazení - Insert &spaces instead of tabs Vložit místo zarážek prázdné &znaky (mezery) @@ -30815,14 +30751,6 @@ Určuje, jak se chová zpětná klávesa (backspace) co se týče odsazování. Based on the surrounding lines Založeno na okolních řádcích - - Ta&b size: - Šířka &zarážky: - - - &Indent size: - &Velikost odsazení: - Enable automatic &indentation Povolit automatické &odsazení @@ -30835,74 +30763,6 @@ Určuje, jak se chová zpětná klávesa (backspace) co se týče odsazování. &Backspace follows indentation &Zpětná klávesa sleduje hloubku odsazení - - Align continuation lines: - Zarovnání navazujících řádků: - - - <html><head/><body> -Influences the indentation of continuation lines. - -<ul> -<li>Not At All: Do not align at all. Lines will only be indented to the current logical indentation depth. -<pre> -(tab)int i = foo(a, b -(tab)c, d); -</pre> -</li> - -<li>With Spaces: Always use spaces for alignment, regardless of the other indentation settings. -<pre> -(tab)int i = foo(a, b -(tab) c, d); -</pre> -</li> - -<li>With Regular Indent: Use tabs and/or spaces for alignment, as configured above. -<pre> -(tab)int i = foo(a, b -(tab)(tab)(tab) c, d); -</pre> -</li> -</ul></body></html> - <html><head/><body> -Určuje chování odsazení se zřetelem k navazujícím řádkům. - -<ul> -<li>Žádné odsazení: Žádné odsazení dodatečně k logickému odsazení. -<pre> -(tab)int i = foo(a, b -(tab)c, d); -</pre> -</li> - -<li>Prázdné znaky: Dodatečné odsazení pomocí prázdných znaků. -<pre> -(tab)int i = foo(a, b -(tab) c, d); -</pre> -</li> - -<li>Normální odsazení: Používají se zarážky nebo prázdné znaky odpovídající hořejšímu nastavení. -<pre> -(tab)int i = foo(a, b -(tab)(tab)(tab) c, d); -</pre> -</li> -</ul></body></html> - - - Not At All - Žádné odsazení - - - With Spaces - Prázdné znaky - - - With Regular Indent - Normální odsazení - Tab key performs auto-indent: Klávesa pro zarážku provede automatické odsazení: @@ -30919,22 +30779,6 @@ Určuje chování odsazení se zřetelem k navazujícím řádkům. In Leading White Space Pouze v prázdném místu na začátku řádku - - Tab policy: - Chování zarážek: - - - Spaces Only - Pouze mezery - - - Tabs Only - Pouze zarážky - - - Mixed - Smíchaně - Valgrind diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts index 20361352665..d9a9fd2b9a8 100644 --- a/share/qtcreator/translations/qtcreator_de.ts +++ b/share/qtcreator/translations/qtcreator_de.ts @@ -47228,10 +47228,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e TextEditor::DisplaySettingsPage - - Display - Anzeige - Todo @@ -47474,10 +47470,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Are you sure you want to delete this color scheme permanently? Möchten Sie das Farbschema löschen? - - Delete - Löschen - Color Scheme Changed Farbschema geändert diff --git a/share/qtcreator/translations/qtcreator_fr.ts b/share/qtcreator/translations/qtcreator_fr.ts index 83b3484f531..08c56f44681 100644 --- a/share/qtcreator/translations/qtcreator_fr.ts +++ b/share/qtcreator/translations/qtcreator_fr.ts @@ -15872,50 +15872,10 @@ Influence l'indentation des lignes de continuation. TextEditor::DisplaySettingsPage - - Display - Affichage - - - Display line &numbers - Afficher les &numéros de ligne - - - Display &folding markers - Affiche les marqueurs de &pliage - - - Show tabs and spaces. - Afficher les tabulations et espaces. - - - &Visualize whitespace - &Visualiser les espaces - - - Highlight current &line - Surligner la &ligne courante - - - Highlight &blocks - Surligner les &blocs - Animate matching parentheses Animer les parenthèses correspondantes - - Text Wrapping - Retour à la ligne dynamique - - - Enable text &wrapping - Activer le &retour à la ligne automatique - - - Display right &margin at column: - Afficher une &marge à la colonne : - Navigation Navigation @@ -15929,24 +15889,6 @@ Influence l'indentation des lignes de continuation. Put a red mark next to the text that has been modified since the last save Marquer le texte modifié - - Mark &text changes - Marquer les modifications de &texte - - - &Animate matching parentheses - &Animer les parenthèses correspondantes - - - Auto-fold first &comment - reformulation à l'infinitif -francis : en effet, une erreur de ma part --> validé. - Replier automatiquement le premier &commentaire - - - Center &cursor on scroll - Centrer le &curseur sur le barre de défilement - TextEditor::FontSettingsPage @@ -37242,14 +37184,6 @@ Ils requièrent Qt 4.7.4 ou supérieur et l'ensemble de composants install TextEditor::TabSettingsWidget - - Form - Formulaire - - - Tabs And Indentation - Tabulation et indentation - Insert &spaces instead of tabs Insérer des e&spaces au lieu de tabulations @@ -37262,14 +37196,6 @@ Ils requièrent Qt 4.7.4 ou supérieur et l'ensemble de composants install Based on the surrounding lines Basé sur les lignes environnantes - - Ta&b size: - Taille de ta&bulation : - - - &Indent size: - Taille de l'&indentation : - Enable automatic &indentation Activer l'&indentation automatique @@ -37282,71 +37208,6 @@ Ils requièrent Qt 4.7.4 ou supérieur et l'ensemble de composants install &Backspace follows indentation La touche &retour arrière suit l'indentation - - Align continuation lines: - Aligner les lignes de continuation : - - - <html><head/><body> -Influences the indentation of continuation lines. - -<ul> -<li>Not At All: Do not align at all. Lines will only be indented to the current logical indentation depth. -<pre> -(tab)int i = foo(a, b -(tab)c, d); -</pre> -</li> - -<li>With Spaces: Always use spaces for alignment, regardless of the other indentation settings. -<pre> -(tab)int i = foo(a, b -(tab) c, d); -</pre> -</li> - -<li>With Regular Indent: Use tabs and/or spaces for alignment, as configured above. -<pre> -(tab)int i = foo(a, b -(tab)(tab)(tab) c, d); -</pre> -</li> -</ul></body></html> - <html><head/><body> -Influence l'indentation des lignes de continuation. -<ul> -<li>Pas du tout : ne pas aligner. Les lignes ne seront indentées jusqu'à la profondeur d'indentation logique. -<pre> -(tab)int i = foo(a, b -(tab)c, d); -</pre> -</li> -<li>Avec espaces : toujours utiliser des espaces pour l'alignement, sans tenir compte des autres paramètres d'indentation. -<pre> -(tab)int i = foo(a, b -(tab) c, d); -</pre> -</li> -<li>Avec indentation régulière : utiliser des tabulations et/ou des espaces pour l'alignement, en fonction de la configuration. -<pre> -(tab)int i = foo(a, b -(tab)(tab)(tab) c, d); -</pre> -</li> -</ul></body></html> - - - Not At All - Pas du tout - - - With Spaces - Avec espaces - - - With Regular Indent - Avec indentation régulière - Tab key performs auto-indent: La touche tabulation active l'identation automatique : @@ -37363,22 +37224,6 @@ Influence l'indentation des lignes de continuation. In Leading White Space En début de ligne uniquement - - Tab policy: - Politique de tabulation : - - - Spaces Only - Espaces seulement - - - Tabs Only - Tabulation seulement - - - Mixed - Mixte - Valgrind @@ -43644,6 +43489,8 @@ Specifie comment retour arrière se comporte avec l'indentation. Auto-fold first &comment + reformulation à l'infinitif +francis : en effet, une erreur de ma part --> validé. Replier automatiquement le premier &commentaire diff --git a/share/qtcreator/translations/qtcreator_ja.ts b/share/qtcreator/translations/qtcreator_ja.ts index 008cfcade68..419db4765f5 100644 --- a/share/qtcreator/translations/qtcreator_ja.ts +++ b/share/qtcreator/translations/qtcreator_ja.ts @@ -52042,10 +52042,6 @@ Row: %4, Column: %5 TextEditor::DisplaySettingsPage - - Display - 表示 - TextEditor::FontSettingsPageWidget diff --git a/share/qtcreator/translations/qtcreator_ru.ts b/share/qtcreator/translations/qtcreator_ru.ts index be765e3ed3d..4f79054c489 100644 --- a/share/qtcreator/translations/qtcreator_ru.ts +++ b/share/qtcreator/translations/qtcreator_ru.ts @@ -46346,10 +46346,6 @@ In addition, Shift+Enter inserts an escape character at the cursor position and TextEditor::DisplaySettingsPage - - Display - Отображение - Display line &numbers Показывать &номера строк @@ -46499,10 +46495,6 @@ In addition, Shift+Enter inserts an escape character at the cursor position and Color Scheme Цветовая схема - - Delete - Удалить - Copy... Копировать... diff --git a/share/qtcreator/translations/qtcreator_zh_CN.ts b/share/qtcreator/translations/qtcreator_zh_CN.ts index 4393ae95118..d78063b5bce 100644 --- a/share/qtcreator/translations/qtcreator_zh_CN.ts +++ b/share/qtcreator/translations/qtcreator_zh_CN.ts @@ -14944,46 +14944,6 @@ Influences the indentation of continuation lines. TextEditor::DisplaySettingsPage - - Display - 显示 - - - Display line &numbers - 显示行号(&N) - - - Display &folding markers - 显示折叠标记(&F) - - - Show tabs and spaces. - 显示制表符和空白. - - - &Visualize whitespace - 标示空白 - - - Highlight current &line - 高亮显示当前行(&L) - - - Text Wrapping - 文字折行 - - - Enable text &wrapping - 开启文字折行 - - - Display right &margin at column: - 显示右边分界(&M)在列: - - - Highlight &blocks - 高亮显示段落(&B) - Animate matching parentheses 动画显示对应的括号 @@ -15000,22 +14960,6 @@ Influences the indentation of continuation lines. Mark text changes 标记文本改变 - - Mark &text changes - 标记文本改变(&T) - - - &Animate matching parentheses - 动画显示对应的括号(&A) - - - Auto-fold first &comment - 自动折叠开头的注释(&C) - - - Center &cursor on scroll - 滚动时居中光标(&C) - TextEditor::FontSettingsPage @@ -35241,14 +35185,6 @@ Requires Qt 4.7.4 or newer, and the component set installed for your Qt version. TextEditor::TabSettingsWidget - - Form - 界面 - - - Tabs And Indentation - 制表符和缩进 - Insert &spaces instead of tabs 插入空格代替制表符(&S) @@ -35261,14 +35197,6 @@ Requires Qt 4.7.4 or newer, and the component set installed for your Qt version. Based on the surrounding lines 依据周围行的情况 - - Ta&b size: - 制表符尺寸(&B): - - - &Indent size: - 缩进尺寸(&i): - Enable automatic &indentation 开启自动缩进(&i) @@ -35281,74 +35209,6 @@ Requires Qt 4.7.4 or newer, and the component set installed for your Qt version. &Backspace follows indentation 退格键跟随缩进(&B) - - Align continuation lines: - 对齐连续行: - - - <html><head/><body> -Influences the indentation of continuation lines. - -<ul> -<li>Not At All: Do not align at all. Lines will only be indented to the current logical indentation depth. -<pre> -(tab)int i = foo(a, b -(tab)c, d); -</pre> -</li> - -<li>With Spaces: Always use spaces for alignment, regardless of the other indentation settings. -<pre> -(tab)int i = foo(a, b -(tab) c, d); -</pre> -</li> - -<li>With Regular Indent: Use tabs and/or spaces for alignment, as configured above. -<pre> -(tab)int i = foo(a, b -(tab)(tab)(tab) c, d); -</pre> -</li> -</ul></body></html> - <html><head/><body> -改变连续行的缩进 - -<ul> -<li>不对齐: 不进行对齐。代码行只根据当前逻辑缩进深度进行缩进。 -<pre> -(tab)int i = foo(a, b -(tab)c, d); -</pre> -</li> - -<li>伴随空格: 允许使用空格进行对齐,忽略其他缩进设置。 -<pre> -(tab)int i = foo(a, b -(tab) c, d); -</pre> -</li> - -<li>伴随规则缩进: 在原设置上使用 tab 或 空格进行对齐。 -<pre> -(tab)int i = foo(a, b -(tab)(tab)(tab) c, d); -</pre> -</li> -</ul></body></html> - - - Not At All - 不对齐 - - - With Spaces - 伴随空格 - - - With Regular Indent - 伴随规则缩进 - Never 从不 @@ -35361,22 +35221,6 @@ Influences the indentation of continuation lines. In Leading White Space 仅用于行首空白 - - Tab policy: - 缩进策略: - - - Spaces Only - 仅空格 - - - Tabs Only - 仅缩进 - - - Mixed - 混合 - Valgrind From 3533392d95e648810e1670efeaba620b2e8a102c Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Mon, 31 Oct 2022 09:13:54 +0200 Subject: [PATCH 77/97] ProjectExplorer: Remove redundant return in CustomToolChain Amends c15e09e0fe880c58ad39d5d8d0a1baeb84fc7e3b. Change-Id: Ic1aabcada892413f454c3800c925aa7527a09965 Reviewed-by: Christian Kandeler --- src/plugins/projectexplorer/customtoolchain.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/projectexplorer/customtoolchain.cpp b/src/plugins/projectexplorer/customtoolchain.cpp index 4c2904d3cd6..8b072f85eb2 100644 --- a/src/plugins/projectexplorer/customtoolchain.cpp +++ b/src/plugins/projectexplorer/customtoolchain.cpp @@ -157,7 +157,6 @@ QList CustomToolChain::createOutputParsers() const if (m_outputParserId == MsvcParser::id()) return {new MsvcParser}; return {new Internal::CustomParser(customParserSettings())}; - return {}; } QStringList CustomToolChain::headerPathsList() const From eb0649ba05ae47985e3d73b78c048ba6ea8382bb Mon Sep 17 00:00:00 2001 From: Daniele Bortolotti Date: Fri, 28 Oct 2022 13:40:41 +0200 Subject: [PATCH 78/97] McuSupport: Enable os-specific executable version detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently version detection fails in either Linux or Windows based on the content of versionDetection.filePattern in the json kit file. This change enables os-specific filePattern fields: "versionDetection": { "filePattern": { "windows": "bin/arm-none-eabi-g++.exe", "linux": "bin/arm-none-eabi-g++" } "executableArgs": "--version", "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" } Simply appending the binary extension with withExecutableSuffix() is less portable and does not reflect the validationPath field. For McuPackageDirectoryEntriesVersionDetector and McuPackageXmlVersionDetector to work correctly, they rely on filePattern not having os-specific fields. Also make getOsSpecificValue and parseVersionDetection static. Change-Id: Ieacf376126043d732eeb5d5a2f4125963022ae76 Reviewed-by: Sivert Krøvel Reviewed-by: Eike Ziller Reviewed-by: --- src/plugins/mcusupport/mcusupportsdk.cpp | 27 ++++++++++--------- .../test/armgcc_ek_ra6m3g_baremetal_json.h | 5 +++- .../test/armgcc_ek_ra6m3g_freertos_json.h | 5 +++- .../test/armgcc_example_baremetal_json.h | 5 +++- .../armgcc_mimxrt1050_evk_baremetal_json.h | 5 +++- .../armgcc_mimxrt1050_evk_freertos_json.h | 5 +++- .../armgcc_mimxrt1060_evk_baremetal_json.h | 5 +++- .../armgcc_mimxrt1064_evk_baremetal_json.h | 5 +++- .../armgcc_mimxrt1064_evk_freertos_json.h | 5 +++- .../armgcc_mimxrt1170_evk_freertos_json.h | 5 +++- ...mgcc_stm32f469i_discovery_baremetal_json.h | 5 +++- ...mgcc_stm32f769i_discovery_baremetal_json.h | 5 +++- ...rmgcc_stm32f769i_discovery_freertos_json.h | 5 +++- ...mgcc_stm32h750b_discovery_baremetal_json.h | 5 +++- .../test/ghs_rh850_d1m1a_baremetal_json.h | 5 +++- .../test/iar_ek_ra6m3g_baremetal_json.h | 5 +++- .../test/iar_ek_ra6m3g_freertos_json.h | 5 +++- .../test/iar_example_baremetal_json.h | 5 +++- .../test/iar_mimxrt1050_evk_baremetal_json.h | 5 +++- .../test/iar_mimxrt1050_evk_freertos_json.h | 5 +++- .../test/iar_mimxrt1060_evk_baremetal_json.h | 5 +++- .../test/iar_mimxrt1064_evk_baremetal_json.h | 5 +++- .../test/iar_mimxrt1064_evk_freertos_json.h | 5 +++- .../test/iar_mimxrt1170_evk_freertos_json.h | 5 +++- .../iar_stm32f469i_discovery_baremetal_json.h | 5 +++- .../iar_stm32f769i_discovery_baremetal_json.h | 5 +++- .../iar_stm32f769i_discovery_freertos_json.h | 5 +++- .../iar_stm32h750b_discovery_baremetal_json.h | 5 +++- .../test/iar_tviic2d6m_baremetal_json.h | 5 +++- src/plugins/mcusupport/test/unittest.cpp | 4 +-- 30 files changed, 128 insertions(+), 43 deletions(-) diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index 76f24206797..dd06240d507 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -608,19 +608,7 @@ static FilePaths targetDescriptionFiles(const FilePath &dir) return kitsPath(dir).dirEntries(Utils::FileFilter({"*.json"}, QDir::Files)); } -VersionDetection parseVersionDetection(const QJsonObject &packageEntry) -{ - const QJsonObject versioning = packageEntry.value("versionDetection").toObject(); - return { - versioning["regex"].toString(), - versioning["filePattern"].toString(), - versioning["executableArgs"].toString(), - versioning["xmlElement"].toString(), - versioning["xmlAttribute"].toString(), - }; -} - -QString getOsSpecificValue(const QJsonValue &entry) +static QString getOsSpecificValue(const QJsonValue &entry) { if (entry.isObject()) { //The json entry has os-specific values @@ -630,6 +618,19 @@ QString getOsSpecificValue(const QJsonValue &entry) return entry.toString(); } +static VersionDetection parseVersionDetection(const QJsonObject &packageEntry) +{ + const QJsonObject versioning = packageEntry.value("versionDetection").toObject(); + return { + versioning["regex"].toString(), + getOsSpecificValue(versioning["filePattern"]), + versioning["executableArgs"].toString(), + versioning["xmlElement"].toString(), + versioning["xmlAttribute"].toString(), + }; +} + + static PackageDescription parsePackage(const QJsonObject &cmakeEntry) { const QVariantList versionsVariantList = cmakeEntry["versions"].toArray().toVariantList(); diff --git a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h index fb6a57640a7..6d096d21a09 100644 --- a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h @@ -43,7 +43,10 @@ constexpr auto armgcc_ek_ra6m3g_baremetal_json = R"( "type": "path", "optional": false, "versionDetection": { - "filePattern": "bin/arm-none-eabi-g++", + "filePattern": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" + }, "executableArgs": "--version", "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, diff --git a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h index 283b79ab21d..531031cbf94 100644 --- a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h @@ -43,7 +43,10 @@ constexpr auto armgcc_ek_ra6m3g_freertos_json = R"( "type": "path", "optional": false, "versionDetection": { - "filePattern": "bin/arm-none-eabi-g++", + "filePattern": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" + }, "executableArgs": "--version", "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, diff --git a/src/plugins/mcusupport/test/armgcc_example_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_example_baremetal_json.h index e4f10bd54b3..c3e2e7187eb 100644 --- a/src/plugins/mcusupport/test/armgcc_example_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_example_baremetal_json.h @@ -28,7 +28,10 @@ constexpr auto armgcc_example_baremetal_json = R"( "type": "path", "optional": false, "versionDetection": { - "filePattern": "bin/arm-none-eabi-g++", + "filePattern": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" + }, "executableArgs": "--version", "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_baremetal_json.h index 01ac942a0a5..6b55055beba 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_baremetal_json.h @@ -47,7 +47,10 @@ constexpr auto armgcc_mimxrt1050_evk_baremetal_json = R"( "type": "path", "optional": false, "versionDetection": { - "filePattern": "bin/arm-none-eabi-g++", + "filePattern": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" + }, "executableArgs": "--version", "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_freertos_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_freertos_json.h index 25e696a14d0..4a7da4ccf93 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1050_evk_freertos_json.h @@ -47,7 +47,10 @@ constexpr auto armgcc_mimxrt1050_evk_freertos_json = R"( "type": "path", "optional": false, "versionDetection": { - "filePattern": "bin/arm-none-eabi-g++", + "filePattern": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" + }, "executableArgs": "--version", "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h index e7a7311b1c9..8f0b9e54e24 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1060_evk_baremetal_json.h @@ -47,7 +47,10 @@ constexpr auto armgcc_mimxrt1060_evk_baremetal_json = R"( "type": "path", "optional": false, "versionDetection": { - "filePattern": "bin/arm-none-eabi-g++", + "filePattern": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" + }, "executableArgs": "--version", "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_baremetal_json.h index b2d4b7ec406..cdf67a5f6ca 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_baremetal_json.h @@ -47,7 +47,10 @@ constexpr auto armgcc_mimxrt1064_evk_baremetal_json = R"( "type": "path", "optional": false, "versionDetection": { - "filePattern": "bin/arm-none-eabi-g++", + "filePattern": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" + }, "executableArgs": "--version", "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_freertos_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_freertos_json.h index 264ad9c065e..592a84228d1 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1064_evk_freertos_json.h @@ -47,7 +47,10 @@ constexpr auto armgcc_mimxrt1064_evk_freertos_json = R"( "type": "path", "optional": false, "versionDetection": { - "filePattern": "bin/arm-none-eabi-g++", + "filePattern": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" + }, "executableArgs": "--version", "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, diff --git a/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h b/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h index 8c348011231..b7eb801cd60 100644 --- a/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_mimxrt1170_evk_freertos_json.h @@ -47,7 +47,10 @@ constexpr auto armgcc_mimxrt1170_evk_freertos_json = R"( "type": "path", "optional": false, "versionDetection": { - "filePattern": "bin/arm-none-eabi-g++", + "filePattern": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" + }, "executableArgs": "--version", "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, diff --git a/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h index 452ae4e953c..3b1ef8172f7 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h @@ -46,7 +46,10 @@ constexpr auto armgcc_stm32f469i_discovery_baremetal_json = R"( "type": "path", "optional": false, "versionDetection": { - "filePattern": "bin/arm-none-eabi-g++", + "filePattern": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" + }, "executableArgs": "--version", "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, diff --git a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h index 9fdb309da14..62171d73334 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h @@ -46,7 +46,10 @@ constexpr auto armgcc_stm32f769i_discovery_baremetal_json = R"( "type": "path", "optional": false, "versionDetection": { - "filePattern": "bin/arm-none-eabi-g++", + "filePattern": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" + }, "executableArgs": "--version", "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, diff --git a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h index 249db9497d5..d6e28c6c429 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h @@ -46,7 +46,10 @@ constexpr auto armgcc_stm32f769i_discovery_freertos_json = R"( "type": "path", "optional": false, "versionDetection": { - "filePattern": "bin/arm-none-eabi-g++", + "filePattern": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" + }, "executableArgs": "--version", "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, diff --git a/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h index 3b5adc3e989..a2819c8cf8a 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h @@ -46,7 +46,10 @@ constexpr auto armgcc_stm32h750b_discovery_baremetal_json = R"( "type": "path", "optional": false, "versionDetection": { - "filePattern": "bin/arm-none-eabi-g++", + "filePattern": { + "windows": "bin/arm-none-eabi-g++.exe", + "linux": "bin/arm-none-eabi-g++" + }, "executableArgs": "--version", "regex": "\\b(\\d+\\.\\d+\\.\\d+)\\b" }, diff --git a/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h b/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h index 132cf0319e8..e6e32b208e5 100644 --- a/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h +++ b/src/plugins/mcusupport/test/ghs_rh850_d1m1a_baremetal_json.h @@ -47,7 +47,10 @@ constexpr auto ghs_rh850_d1m1a_baremetal_json = R"( "type": "path", "optional": false, "versionDetection": { - "filePattern": "gversion", + "filePattern": { + "windows": "gversion.exe", + "linux": "gversion" + }, "executableArgs": "-help", "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" }, diff --git a/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h b/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h index 0c38725d138..05f26f7cfcf 100644 --- a/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h @@ -42,7 +42,10 @@ constexpr auto iar_ek_ra6m3g_baremetal_json = R"( "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", "versionDetection": { - "filePattern": "bin/iccarm", + "filePattern": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" }, diff --git a/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h b/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h index d5eda9eab7d..12c827436ab 100644 --- a/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h +++ b/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h @@ -42,7 +42,10 @@ constexpr auto iar_ek_ra6m3g_freertos_json = R"( "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", "versionDetection": { - "filePattern": "bin/iccarm", + "filePattern": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" }, diff --git a/src/plugins/mcusupport/test/iar_example_baremetal_json.h b/src/plugins/mcusupport/test/iar_example_baremetal_json.h index 66e6abde63c..d5e0d9ad2f5 100644 --- a/src/plugins/mcusupport/test/iar_example_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_example_baremetal_json.h @@ -27,7 +27,10 @@ constexpr auto iar_example_baremetal_json = R"( "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", "versionDetection": { - "filePattern": "bin/iccarm", + "filePattern": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" }, diff --git a/src/plugins/mcusupport/test/iar_mimxrt1050_evk_baremetal_json.h b/src/plugins/mcusupport/test/iar_mimxrt1050_evk_baremetal_json.h index 5fe5a089842..795eac73054 100644 --- a/src/plugins/mcusupport/test/iar_mimxrt1050_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_mimxrt1050_evk_baremetal_json.h @@ -46,7 +46,10 @@ constexpr auto iar_mimxrt1050_evk_baremetal_json = R"( "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", "versionDetection": { - "filePattern": "bin/iccarm", + "filePattern": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" }, diff --git a/src/plugins/mcusupport/test/iar_mimxrt1050_evk_freertos_json.h b/src/plugins/mcusupport/test/iar_mimxrt1050_evk_freertos_json.h index 93d23e305a2..7ab260d8563 100644 --- a/src/plugins/mcusupport/test/iar_mimxrt1050_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/iar_mimxrt1050_evk_freertos_json.h @@ -46,7 +46,10 @@ constexpr auto iar_mimxrt1050_evk_freertos_json = R"( "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", "versionDetection": { - "filePattern": "bin/iccarm", + "filePattern": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" }, diff --git a/src/plugins/mcusupport/test/iar_mimxrt1060_evk_baremetal_json.h b/src/plugins/mcusupport/test/iar_mimxrt1060_evk_baremetal_json.h index 6600150f5d6..21e5922228b 100644 --- a/src/plugins/mcusupport/test/iar_mimxrt1060_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_mimxrt1060_evk_baremetal_json.h @@ -46,7 +46,10 @@ constexpr auto iar_mimxrt1060_evk_baremetal_json = R"( "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", "versionDetection": { - "filePattern": "bin/iccarm", + "filePattern": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" }, diff --git a/src/plugins/mcusupport/test/iar_mimxrt1064_evk_baremetal_json.h b/src/plugins/mcusupport/test/iar_mimxrt1064_evk_baremetal_json.h index 83d3c23b1a9..628c209f71e 100644 --- a/src/plugins/mcusupport/test/iar_mimxrt1064_evk_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_mimxrt1064_evk_baremetal_json.h @@ -46,7 +46,10 @@ constexpr auto iar_mimxrt1064_evk_baremetal_json = R"( "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", "versionDetection": { - "filePattern": "bin/iccarm", + "filePattern": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" }, diff --git a/src/plugins/mcusupport/test/iar_mimxrt1064_evk_freertos_json.h b/src/plugins/mcusupport/test/iar_mimxrt1064_evk_freertos_json.h index 2f71e359048..e3cdad5b212 100644 --- a/src/plugins/mcusupport/test/iar_mimxrt1064_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/iar_mimxrt1064_evk_freertos_json.h @@ -46,7 +46,10 @@ constexpr auto iar_mimxrt1064_evk_freertos_json = R"( "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", "versionDetection": { - "filePattern": "bin/iccarm", + "filePattern": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" }, diff --git a/src/plugins/mcusupport/test/iar_mimxrt1170_evk_freertos_json.h b/src/plugins/mcusupport/test/iar_mimxrt1170_evk_freertos_json.h index 4843a668198..f783ea67bd5 100644 --- a/src/plugins/mcusupport/test/iar_mimxrt1170_evk_freertos_json.h +++ b/src/plugins/mcusupport/test/iar_mimxrt1170_evk_freertos_json.h @@ -46,7 +46,10 @@ constexpr auto iar_mimxrt1170_evk_freertos_json = R"( "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", "versionDetection": { - "filePattern": "bin/iccarm", + "filePattern": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" }, diff --git a/src/plugins/mcusupport/test/iar_stm32f469i_discovery_baremetal_json.h b/src/plugins/mcusupport/test/iar_stm32f469i_discovery_baremetal_json.h index 793097d5f6a..af961af20d6 100644 --- a/src/plugins/mcusupport/test/iar_stm32f469i_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_stm32f469i_discovery_baremetal_json.h @@ -45,7 +45,10 @@ constexpr auto iar_stm32f469i_discovery_baremetal_json = R"( "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", "versionDetection": { - "filePattern": "bin/iccarm", + "filePattern": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" }, diff --git a/src/plugins/mcusupport/test/iar_stm32f769i_discovery_baremetal_json.h b/src/plugins/mcusupport/test/iar_stm32f769i_discovery_baremetal_json.h index 47df7469ab5..4b7c3fb8223 100644 --- a/src/plugins/mcusupport/test/iar_stm32f769i_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_stm32f769i_discovery_baremetal_json.h @@ -45,7 +45,10 @@ constexpr auto iar_stm32f769i_discovery_baremetal_json = R"( "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", "versionDetection": { - "filePattern": "bin/iccarm", + "filePattern": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" }, diff --git a/src/plugins/mcusupport/test/iar_stm32f769i_discovery_freertos_json.h b/src/plugins/mcusupport/test/iar_stm32f769i_discovery_freertos_json.h index 71181fdca5b..198d008be81 100644 --- a/src/plugins/mcusupport/test/iar_stm32f769i_discovery_freertos_json.h +++ b/src/plugins/mcusupport/test/iar_stm32f769i_discovery_freertos_json.h @@ -45,7 +45,10 @@ constexpr auto iar_stm32f769i_discovery_freertos_json = R"( "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", "versionDetection": { - "filePattern": "bin/iccarm", + "filePattern": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" }, diff --git a/src/plugins/mcusupport/test/iar_stm32h750b_discovery_baremetal_json.h b/src/plugins/mcusupport/test/iar_stm32h750b_discovery_baremetal_json.h index 9c657ab8cc6..cec5412f71e 100644 --- a/src/plugins/mcusupport/test/iar_stm32h750b_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_stm32h750b_discovery_baremetal_json.h @@ -45,7 +45,10 @@ constexpr auto iar_stm32h750b_discovery_baremetal_json = R"( "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", "versionDetection": { - "filePattern": "bin/iccarm", + "filePattern": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" }, diff --git a/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h b/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h index 29c391e8db3..a5770bdef18 100644 --- a/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h @@ -38,7 +38,10 @@ constexpr auto iar_tviic2d6m_baremetal_json = R"( "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", "type": "path", "versionDetection": { - "filePattern": "bin/iccarm", + "filePattern": { + "windows": "bin/iccarm.exe", + "linux": "bin/iccarm" + }, "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" }, diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index ca28f925bb6..887ad6e4cf8 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -80,7 +80,7 @@ const char armGccDir[]{"/opt/armgcc"}; const char armGccDirectorySetting[]{"GNUArmEmbeddedToolchain"}; const char armGccEnvVar[]{"ARMGCC_DIR"}; const char armGccLabel[]{"GNU Arm Embedded Toolchain"}; -const char armGccSuffix[]{"bin/arm-none-eabi-g++"}; +const QString armGccSuffix{HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++")}; const char armGccToolchainFilePath[]{"/opt/qtformcu/2.2/lib/cmake/Qul/toolchain/armgcc.cmake"}; const char armGccToolchainFileUnexpandedPath[]{"%{Qul_ROOT}/lib/cmake/Qul/toolchain/armgcc.cmake"}; const char armGccVersion[]{"10.3.1"}; @@ -1245,7 +1245,7 @@ void McuSupportTest::test_passExecutableVersionDetectorToToolchainPackage_data() << armGccVersionDetectionRegex; QTest::newRow("iar_stm32f469i_discovery_baremetal_json") - << iar_stm32f469i_discovery_baremetal_json << QString{"bin/iccarm"} << version + << iar_stm32f469i_discovery_baremetal_json << HostOsInfo::withExecutableSuffix("bin/iccarm") << version << iarVersionDetectionRegex; } From d9503cdf89479de6e4e2ebd66c3e896e2d268c2e Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 31 Oct 2022 14:50:30 +0100 Subject: [PATCH 79/97] Fix lupdate error GenericTransferImpl doesn't have a translation context and RemoteLinux was changed to Tr::tr anyway. Amends b3233035189cc323049b1f063c34daa0ae9feb22 Change-Id: I048cae28684e223ab1547a5e07d1aaf9bb46c73e Reviewed-by: Reviewed-by: Christian Kandeler --- src/plugins/remotelinux/linuxdevice.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index 402109d6d01..63a3fb5b9a7 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -1458,10 +1458,9 @@ private: const FilePath targetDir = target.parentDir(); if (!m_checkedDirectories.contains(targetDir)) { - emit progress(tr("Creating directory: %1\n") - .arg(targetDir.toUserOutput())); + emit progress(Tr::tr("Creating directory: %1\n").arg(targetDir.toUserOutput())); if (!targetDir.ensureWritableDir()) { - result.m_errorString = tr("Failed."); + result.m_errorString = Tr::tr("Failed."); result.m_exitCode = -1; // Random pick emit done(result); return; @@ -1469,10 +1468,12 @@ private: m_checkedDirectories.insert(targetDir); } - emit progress(tr("Copying %1/%2: %3 -> %4\n") - .arg(m_currentIndex).arg(m_fileCount).arg(source.toUserOutput(), target.toUserOutput())); + emit progress(Tr::tr("Copying %1/%2: %3 -> %4\n") + .arg(m_currentIndex) + .arg(m_fileCount) + .arg(source.toUserOutput(), target.toUserOutput())); if (!source.copyFile(target)) { - result.m_errorString = tr("Failed."); + result.m_errorString = Tr::tr("Failed."); result.m_exitCode = -1; // Random pick emit done(result); return; From 33602af185d87ff473818bdee5fd0aa679980b55 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 31 Oct 2022 17:31:31 +0200 Subject: [PATCH 80/97] QmlDesigner: Fix crashes on mode change Fixes: QDS-8129 Change-Id: Iea76157c58f663244e8fd8de8ea26392d2b49b43 Reviewed-by: Tim Jenssen --- .../components/materialbrowser/materialbrowserview.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp index 89935205379..a2263f39859 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserview.cpp @@ -310,6 +310,9 @@ void MaterialBrowserView::modelAttached(Model *model) void MaterialBrowserView::refreshModel(bool updateImages) { + if (!model()) + return; + ModelNode matLib = modelNodeForId(Constants::MATERIAL_LIB_ID); QList materials; @@ -461,7 +464,7 @@ void MaterialBrowserView::nodeRemoved(const ModelNode &removedNode, void QmlDesigner::MaterialBrowserView::loadPropertyGroups() { - if (!m_hasQuick3DImport || m_propertyGroupsLoaded) + if (!m_hasQuick3DImport || m_propertyGroupsLoaded || !model()) return; QString matPropsPath = model()->metaInfo("QtQuick3D.Material").importDirectoryPath() From 6e8087a1b1ea3beb07317f1331cfb13a16722e9b Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 31 Oct 2022 15:27:26 +0100 Subject: [PATCH 81/97] macOS: Fix missing "Search" item in help menu Define the menu as the help menu directly in the the NSApplication, since the OS built-in heuristics based on the menu name easily fails. Fixes: QTCREATORBUG-24751 Change-Id: I9aa50a46099e295ec0c38ee8a9e88d75d41c74ad Reviewed-by: Timur Pocheptsov Reviewed-by: Qt CI Bot --- src/libs/utils/theme/theme.cpp | 7 +++++++ src/libs/utils/theme/theme.h | 3 +++ src/libs/utils/theme/theme_mac.h | 7 +++++++ src/libs/utils/theme/theme_mac.mm | 7 ++++++- src/plugins/coreplugin/mainwindow.cpp | 1 + 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/libs/utils/theme/theme.cpp b/src/libs/utils/theme/theme.cpp index 0d0908c539a..54676b709cb 100644 --- a/src/libs/utils/theme/theme.cpp +++ b/src/libs/utils/theme/theme.cpp @@ -253,6 +253,13 @@ void Theme::setInitialPalette(Theme *initTheme) initialPalette(); } +void Theme::setHelpMenu(QMenu *menu) +{ +#ifdef Q_OS_MACOS + Internal::setMacOSHelpMenu(menu); +#endif +} + QPalette Theme::initialPalette() { static QPalette palette = copyPalette(QApplication::palette()); diff --git a/src/libs/utils/theme/theme.h b/src/libs/utils/theme/theme.h index effd69aa1f2..e60dc8417fd 100644 --- a/src/libs/utils/theme/theme.h +++ b/src/libs/utils/theme/theme.h @@ -9,6 +9,7 @@ #include QT_BEGIN_NAMESPACE +class QMenu; class QPalette; class QSettings; QT_END_NAMESPACE @@ -473,6 +474,8 @@ public: static void setInitialPalette(Theme *initTheme); + static void setHelpMenu(QMenu *menu); + protected: Theme(Theme *originTheme, QObject *parent = nullptr); ThemePrivate *d; diff --git a/src/libs/utils/theme/theme_mac.h b/src/libs/utils/theme/theme_mac.h index d64e92b164e..27eecd19fba 100644 --- a/src/libs/utils/theme/theme_mac.h +++ b/src/libs/utils/theme/theme_mac.h @@ -3,11 +3,18 @@ #pragma once +#include + +QT_BEGIN_NAMESPACE +class QMenu; +QT_END_NAMESPACE + namespace Utils { namespace Internal { void forceMacAppearance(bool dark); bool currentAppearanceIsDark(); +void setMacOSHelpMenu(QMenu *menu); } // Internal } // Utils diff --git a/src/libs/utils/theme/theme_mac.mm b/src/libs/utils/theme/theme_mac.mm index ea59bfb17e9..d732d7e4a9c 100644 --- a/src/libs/utils/theme/theme_mac.mm +++ b/src/libs/utils/theme/theme_mac.mm @@ -3,7 +3,7 @@ #include "theme_mac.h" -#include +#include #include #include @@ -47,5 +47,10 @@ bool currentAppearanceIsDark() return !currentAppearanceMatches(false /*==light*/); } +void setMacOSHelpMenu(QMenu *menu) +{ + NSApp.helpMenu = menu->toNSMenu(); +} + } // Internal } // Utils diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp index 54c0b38a72c..e71b0b1fc2f 100644 --- a/src/plugins/coreplugin/mainwindow.cpp +++ b/src/plugins/coreplugin/mainwindow.cpp @@ -514,6 +514,7 @@ void MainWindow::registerDefaultContainers() ac = ActionManager::createMenu(Constants::M_HELP); menubar->addMenu(ac, Constants::G_HELP); ac->menu()->setTitle(tr("&Help")); + Theme::setHelpMenu(ac->menu()); ac->appendGroup(Constants::G_HELP_HELP); ac->appendGroup(Constants::G_HELP_SUPPORT); ac->appendGroup(Constants::G_HELP_ABOUT); From b23d066f9da50b3f453d9534e3fa1ae51e84e36f Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Tue, 1 Nov 2022 07:43:03 +0100 Subject: [PATCH 82/97] McuSupport: Remove ASM_MASM from CMake project languages This was never required and was added to the list by accident. Task-number: UL-5875 Change-Id: I7957d49e9c87da91a81a363185f11e8331c650c3 Reviewed-by: Daniele Bortolotti Reviewed-by: Reviewed-by: Eike Ziller --- .../studio_templates/projects/application-mcu/CMakeLists.txt | 2 +- src/plugins/mcusupport/wizards/application/CMakeLists.txt | 2 +- src/plugins/mcusupport/wizards/qmlproject/CMakeLists.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/CMakeLists.txt b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/CMakeLists.txt index fa5be381289..b979c45227b 100644 --- a/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/CMakeLists.txt +++ b/share/qtcreator/qmldesigner/studio_templates/projects/application-mcu/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.15) -project(%{ProjectName} VERSION 0.0.1 LANGUAGES C CXX ASM ASM_MASM) +project(%{ProjectName} VERSION 0.0.1 LANGUAGES C CXX ASM) if (NOT TARGET Qul::Core) find_package(Qul) diff --git a/src/plugins/mcusupport/wizards/application/CMakeLists.txt b/src/plugins/mcusupport/wizards/application/CMakeLists.txt index c260ae1f104..1677e912926 100644 --- a/src/plugins/mcusupport/wizards/application/CMakeLists.txt +++ b/src/plugins/mcusupport/wizards/application/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.15) -project(%{CorrectedProjectName} VERSION 0.0.1 LANGUAGES C CXX ASM ASM_MASM) +project(%{CorrectedProjectName} VERSION 0.0.1 LANGUAGES C CXX ASM) find_package(Qul) diff --git a/src/plugins/mcusupport/wizards/qmlproject/CMakeLists.txt b/src/plugins/mcusupport/wizards/qmlproject/CMakeLists.txt index 532918eb0f2..5374e7d2fe1 100644 --- a/src/plugins/mcusupport/wizards/qmlproject/CMakeLists.txt +++ b/src/plugins/mcusupport/wizards/qmlproject/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.15) -project(%{CorrectedProjectName} VERSION 0.0.1 LANGUAGES C CXX ASM ASM_MASM) +project(%{CorrectedProjectName} VERSION 0.0.1 LANGUAGES C CXX ASM) find_package(Qul) From e558fc4d1f24c8e4e295c7fa381fb321d840cc33 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Tue, 1 Nov 2022 09:06:21 +0100 Subject: [PATCH 83/97] McuSupport: CMake expects programmer path to include the bin folder Change-Id: I193dc5d30abfa50830ca93c61af8eeb985fe9c4f Reviewed-by: Daniele Bortolotti Reviewed-by: Eike Ziller Reviewed-by: --- src/plugins/mcusupport/mcusupportsdk.cpp | 4 ++-- .../test/armgcc_stm32f469i_discovery_baremetal_json.h | 8 ++++---- .../test/armgcc_stm32f769i_discovery_baremetal_json.h | 8 ++++---- .../test/armgcc_stm32f769i_discovery_freertos_json.h | 8 ++++---- .../test/armgcc_stm32h750b_discovery_baremetal_json.h | 8 ++++---- .../test/iar_stm32f469i_discovery_baremetal_json.h | 8 ++++---- .../test/iar_stm32f769i_discovery_baremetal_json.h | 8 ++++---- .../test/iar_stm32f769i_discovery_freertos_json.h | 8 ++++---- .../test/iar_stm32h750b_discovery_baremetal_json.h | 8 ++++---- src/plugins/mcusupport/test/unittest.cpp | 4 ++-- 10 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index dd06240d507..d68a8e9ea88 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -368,8 +368,8 @@ McuPackagePtr createStm32CubeProgrammerPackage(const SettingsHandler::Ptr &setti FilePath defaultPath = {}; const FilePath detectionPath = FilePath::fromUserInput( - QLatin1String(Utils::HostOsInfo::isWindowsHost() ? "bin/STM32_Programmer_CLI.exe" - : "bin/STM32_Programmer.sh")); + QLatin1String(Utils::HostOsInfo::isWindowsHost() ? "STM32_Programmer_CLI.exe" + : "STM32_Programmer.sh")); return McuPackagePtr{ new McuPackage(settingsHandler, diff --git a/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h index 3b1ef8172f7..5a4f2cf0617 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32f469i_discovery_baremetal_json.h @@ -20,12 +20,12 @@ constexpr auto armgcc_stm32f469i_discovery_baremetal_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin" }, "detectionPath": { - "windows": "bin/STM32_Programmer_CLI.exe", - "linux": "bin/STM32_Programmer.sh" + "windows": "STM32_Programmer_CLI.exe", + "linux": "STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true diff --git a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h index 62171d73334..40a075e92a9 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_baremetal_json.h @@ -20,12 +20,12 @@ constexpr auto armgcc_stm32f769i_discovery_baremetal_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin" }, "detectionPath": { - "windows": "bin/STM32_Programmer_CLI.exe", - "linux": "bin/STM32_Programmer.sh" + "windows": "STM32_Programmer_CLI.exe", + "linux": "STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true diff --git a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h index d6e28c6c429..783561df426 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32f769i_discovery_freertos_json.h @@ -20,12 +20,12 @@ constexpr auto armgcc_stm32f769i_discovery_freertos_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin" }, "detectionPath": { - "windows": "bin/STM32_Programmer_CLI.exe", - "linux": "bin/STM32_Programmer.sh" + "windows": "STM32_Programmer_CLI.exe", + "linux": "STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true diff --git a/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h index a2819c8cf8a..b8ae6d3c9ae 100644 --- a/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_stm32h750b_discovery_baremetal_json.h @@ -20,12 +20,12 @@ constexpr auto armgcc_stm32h750b_discovery_baremetal_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin" }, "detectionPath": { - "windows": "bin/STM32_Programmer_CLI.exe", - "linux": "bin/STM32_Programmer.sh" + "windows": "STM32_Programmer_CLI.exe", + "linux": "STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true diff --git a/src/plugins/mcusupport/test/iar_stm32f469i_discovery_baremetal_json.h b/src/plugins/mcusupport/test/iar_stm32f469i_discovery_baremetal_json.h index af961af20d6..0b1741cf63c 100644 --- a/src/plugins/mcusupport/test/iar_stm32f469i_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_stm32f469i_discovery_baremetal_json.h @@ -20,12 +20,12 @@ constexpr auto iar_stm32f469i_discovery_baremetal_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin" }, "detectionPath": { - "windows": "bin/STM32_Programmer_CLI.exe", - "linux": "bin/STM32_Programmer.sh" + "windows": "STM32_Programmer_CLI.exe", + "linux": "STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true diff --git a/src/plugins/mcusupport/test/iar_stm32f769i_discovery_baremetal_json.h b/src/plugins/mcusupport/test/iar_stm32f769i_discovery_baremetal_json.h index 4b7c3fb8223..b4ea6ca8fd9 100644 --- a/src/plugins/mcusupport/test/iar_stm32f769i_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_stm32f769i_discovery_baremetal_json.h @@ -20,12 +20,12 @@ constexpr auto iar_stm32f769i_discovery_baremetal_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin" }, "detectionPath": { - "windows": "bin/STM32_Programmer_CLI.exe", - "linux": "bin/STM32_Programmer.sh" + "windows": "STM32_Programmer_CLI.exe", + "linux": "STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true diff --git a/src/plugins/mcusupport/test/iar_stm32f769i_discovery_freertos_json.h b/src/plugins/mcusupport/test/iar_stm32f769i_discovery_freertos_json.h index 198d008be81..d378be51564 100644 --- a/src/plugins/mcusupport/test/iar_stm32f769i_discovery_freertos_json.h +++ b/src/plugins/mcusupport/test/iar_stm32f769i_discovery_freertos_json.h @@ -20,12 +20,12 @@ constexpr auto iar_stm32f769i_discovery_freertos_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin" }, "detectionPath": { - "windows": "bin/STM32_Programmer_CLI.exe", - "linux": "bin/STM32_Programmer.sh" + "windows": "STM32_Programmer_CLI.exe", + "linux": "STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true diff --git a/src/plugins/mcusupport/test/iar_stm32h750b_discovery_baremetal_json.h b/src/plugins/mcusupport/test/iar_stm32h750b_discovery_baremetal_json.h index cec5412f71e..0e3faaf1884 100644 --- a/src/plugins/mcusupport/test/iar_stm32h750b_discovery_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_stm32h750b_discovery_baremetal_json.h @@ -20,12 +20,12 @@ constexpr auto iar_stm32h750b_discovery_baremetal_json = R"( "type": "path", "setting": "Stm32CubeProgrammer", "defaultValue": { - "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/", - "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/" + "windows": "%{Env:PROGRAMFILES}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin", + "linux": "%{Env:HOME}/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin" }, "detectionPath": { - "windows": "bin/STM32_Programmer_CLI.exe", - "linux": "bin/STM32_Programmer.sh" + "windows": "STM32_Programmer_CLI.exe", + "linux": "STM32_Programmer.sh" }, "optional": false, "addToSystemPath": true diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index 887ad6e4cf8..69ac5e06627 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -139,8 +139,8 @@ const char stmCubeProgrammerSetting[]{"Stm32CubeProgrammer"}; const char stmCubeProgrammerLabel[]{"STM32CubeProgrammer"}; const QString stmCubeProgrammerPath{QString{defaultToolPath} + "/bin"}; const QString stmCubeProgrammerDetectionPath{HostOsInfo::isWindowsHost() - ? QString("bin/STM32_Programmer_CLI.exe") - : QString("bin/STM32_Programmer.sh")}; + ? QString("STM32_Programmer_CLI.exe") + : QString("STM32_Programmer.sh")}; const char renesasProgrammerSetting[]{"RenesasFlashProgrammer"}; const char renesasProgrammerCmakeVar[]{"RENESAS_FLASH_PROGRAMMER_PATH"}; From 2da68d41084e96930bf7d5902f2c2e5b6a981ad0 Mon Sep 17 00:00:00 2001 From: Rainer Keller Date: Mon, 31 Oct 2022 09:27:11 +0100 Subject: [PATCH 84/97] McuSupport: Only expand variables from the same target There are multiple packages in different targets that share the same variable name (eg. QUL_BOARD_SDK_DIR). Registering all packages into the same macro expander will make these packages overwrite the variables from other packages. The macro expander should only use packages included in a specific target to expand values from (plus the global ones). Change-Id: Ia2568696a54e48e4e77f81a9bb1a844f2910bb8d Reviewed-by: Yasser Grimes Reviewed-by: Eike Ziller Reviewed-by: Qt CI Bot --- src/plugins/mcusupport/mcusupportoptions.cpp | 13 ++++++++----- src/plugins/mcusupport/mcusupportoptions.h | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/plugins/mcusupport/mcusupportoptions.cpp b/src/plugins/mcusupport/mcusupportoptions.cpp index 9dead1d5550..25d922bfe8d 100644 --- a/src/plugins/mcusupport/mcusupportoptions.cpp +++ b/src/plugins/mcusupport/mcusupportoptions.cpp @@ -38,17 +38,20 @@ Macros *McuSdkRepository::globalMacros() void McuSdkRepository::expandVariables() { - auto macroExpander = getMacroExpander(); - for (const auto &package : std::as_const(packages)) - package->setPath(macroExpander->expand(package->path())); + for (const auto &target : std::as_const(mcuTargets)) { + auto macroExpander = getMacroExpander(*target); + for (const auto &package : target->packages()) { + package->setPath(macroExpander->expand(package->path())); + } + } } -MacroExpanderPtr McuSdkRepository::getMacroExpander() +MacroExpanderPtr McuSdkRepository::getMacroExpander(const McuTarget &target) { auto macroExpander = std::make_shared(); //register the macros - for (const auto &package : std::as_const(packages)) { + for (const auto &package : target.packages()) { macroExpander->registerVariable(package->cmakeVariableName().toLocal8Bit(), package->label(), [package] { return package->path().toString(); }); diff --git a/src/plugins/mcusupport/mcusupportoptions.h b/src/plugins/mcusupport/mcusupportoptions.h index 220fc54f125..8fddf21ab40 100644 --- a/src/plugins/mcusupport/mcusupportoptions.h +++ b/src/plugins/mcusupport/mcusupportoptions.h @@ -41,7 +41,7 @@ public: Packages packages; void expandVariables(); - MacroExpanderPtr getMacroExpander(); + MacroExpanderPtr getMacroExpander(const McuTarget &target); static Macros *globalMacros(); }; From 75a53bf2b42bcd16cf53eb8f1e31a18b3dff435b Mon Sep 17 00:00:00 2001 From: Daniele Bortolotti Date: Tue, 1 Nov 2022 09:26:31 +0100 Subject: [PATCH 85/97] McuSupport: Improve wizard descriptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I964c58e519beb3f9816e5b95c052acc22d73f4b7 Reviewed-by: Rainer Keller Reviewed-by: Sivert Krøvel Reviewed-by: Eike Ziller --- src/plugins/mcusupport/wizards/application/wizard.json | 6 +++--- src/plugins/mcusupport/wizards/qmlproject/wizard.json | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/mcusupport/wizards/application/wizard.json b/src/plugins/mcusupport/wizards/application/wizard.json index 1c9802f3bd4..7e1f30660d7 100644 --- a/src/plugins/mcusupport/wizards/application/wizard.json +++ b/src/plugins/mcusupport/wizards/application/wizard.json @@ -3,9 +3,9 @@ "supportedProjectTypes": [ "CMakeProjectManager.CMakeProject" ], "id": "M.McuSupportApplication", "category": "D.ApplicationMCU", - "trDescription": "Creates an Mcu Support application with an empty UI.", - "trDisplayName": "Mcu Support Application", - "trDisplayCategory": "Application (Qt for MCU)", + "trDescription": "Creates a Qt for MCUs application with an empty UI.", + "trDisplayName": "Qt for MCUs Application", + "trDisplayCategory": "Application (Qt for MCUs)", "icon": "../icon.png", "iconKind": "Themed", "enabled": true, diff --git a/src/plugins/mcusupport/wizards/qmlproject/wizard.json b/src/plugins/mcusupport/wizards/qmlproject/wizard.json index f0b3bf12ff3..5b433358c98 100644 --- a/src/plugins/mcusupport/wizards/qmlproject/wizard.json +++ b/src/plugins/mcusupport/wizards/qmlproject/wizard.json @@ -3,9 +3,9 @@ "supportedProjectTypes": [ "CMakeProjectManager.CMakeProject" ], "id": "M.McuSupportQmlprojectApplication", "category": "D.ApplicationMCU", - "trDescription": "Creates an Mcu Support application with an empty UI, based on qmlproject (Technical Preview).", + "trDescription": "Creates a Qt for MCUs application with an empty UI, based on qmlproject (Technical Preview).", "trDisplayName": "Qt for MCUs QmlProject Application (Technical Preview)", - "trDisplayCategory": "QmlProject Application (Qt for MCU)", + "trDisplayCategory": "QmlProject Application (Qt for MCUs)", "icon": "../icon.png", "iconKind": "Themed", "enabled": true, From f06958f908b2a2b4e1a4d9a463b51822e0deaded Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sivert=20Kr=C3=B8vel?= Date: Fri, 28 Oct 2022 00:23:49 +0200 Subject: [PATCH 86/97] McuSupport: Add more missing detection paths to test jsons Sync test jsons with board jsons from qul repo. Add detection path to JLink package creation test case. Change-Id: I0a19e53c16fd83ec3cf4bf414c7027bf9eab6eb9 Reviewed-by: Reviewed-by: Daniele Bortolotti Reviewed-by: Eike Ziller --- .../mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h | 4 ++++ src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h | 4 ++++ src/plugins/mcusupport/test/ghs_tviic2d4m_baremetal_json.h | 3 +++ src/plugins/mcusupport/test/ghs_tviic2d6m_baremetal_json.h | 4 +++- src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h | 4 ++++ src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h | 4 ++++ src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h | 3 ++- src/plugins/mcusupport/test/unittest.cpp | 5 ++++- 8 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h index 6d096d21a09..6a9c80282bf 100644 --- a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h +++ b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_baremetal_json.h @@ -24,6 +24,10 @@ constexpr auto armgcc_ek_ra6m3g_baremetal_json = R"( "windows": "%{Env:PROGRAMFILES}/SEGGER/JLink", "linux": "/opt/SEGGER/JLink" }, + "detectionPath": { + "windows": "JLink.exe", + "linux": "JLinkExe" + }, "optional": true, "addToSystemPath": true } diff --git a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h index 531031cbf94..3ff5644efd2 100644 --- a/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h +++ b/src/plugins/mcusupport/test/armgcc_ek_ra6m3g_freertos_json.h @@ -24,6 +24,10 @@ constexpr auto armgcc_ek_ra6m3g_freertos_json = R"( "windows": "%{Env:PROGRAMFILES}/SEGGER/JLink", "linux": "/opt/SEGGER/JLink" }, + "detectionPath": { + "windows": "JLink.exe", + "linux": "JLinkExe" + }, "optional": true, "addToSystemPath": true } diff --git a/src/plugins/mcusupport/test/ghs_tviic2d4m_baremetal_json.h b/src/plugins/mcusupport/test/ghs_tviic2d4m_baremetal_json.h index 339f7fe4280..9500c21c1d6 100644 --- a/src/plugins/mcusupport/test/ghs_tviic2d4m_baremetal_json.h +++ b/src/plugins/mcusupport/test/ghs_tviic2d4m_baremetal_json.h @@ -20,6 +20,7 @@ constexpr auto ghs_tviic2d4m_baremetal_json = R"( "label": "Cypress Auto Flash Utility", "type": "path", "cmakeVar": "INFINEON_AUTO_FLASH_UTILITY_DIR", + "detectionPath": "bin/openocd.exe", "optional": false, "addToSystemPath": true } @@ -34,6 +35,8 @@ constexpr auto ghs_tviic2d4m_baremetal_json = R"( "id": "GHS_ARM_DIR", "label": "Green Hills Compiler for ARM", "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", + "setting": "GHSArmToolchain", + "detectionPath": "cxarm.exe", "type": "path", "optional": false }, diff --git a/src/plugins/mcusupport/test/ghs_tviic2d6m_baremetal_json.h b/src/plugins/mcusupport/test/ghs_tviic2d6m_baremetal_json.h index 7f908f9a178..88b98f0626c 100644 --- a/src/plugins/mcusupport/test/ghs_tviic2d6m_baremetal_json.h +++ b/src/plugins/mcusupport/test/ghs_tviic2d6m_baremetal_json.h @@ -20,6 +20,7 @@ constexpr auto ghs_tviic2d6m_baremetal_json = R"( "label": "Cypress Auto Flash Utility", "type": "path", "cmakeVar": "INFINEON_AUTO_FLASH_UTILITY_DIR", + "detectionPath": "bin/openocd.exe", "optional": false, "addToSystemPath": true } @@ -33,8 +34,9 @@ constexpr auto ghs_tviic2d6m_baremetal_json = R"( "compiler": { "id": "GHS_ARM_DIR", "label": "Green Hills Compiler for ARM", - "setting": "GHSArmToolchain", "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", + "setting": "GHSArmToolchain", + "detectionPath": "cxarm.exe", "type": "path", "optional": false }, diff --git a/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h b/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h index 05f26f7cfcf..5a846b7c268 100644 --- a/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_ek_ra6m3g_baremetal_json.h @@ -24,6 +24,10 @@ constexpr auto iar_ek_ra6m3g_baremetal_json = R"( "windows": "%{Env:PROGRAMFILES}/SEGGER/JLink", "linux": "/opt/SEGGER/JLink" }, + "detectionPath": { + "windows": "JLink.exe", + "linux": "JLinkExe" + }, "optional": true, "addToSystemPath": true } diff --git a/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h b/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h index 12c827436ab..6b647dbeff2 100644 --- a/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h +++ b/src/plugins/mcusupport/test/iar_ek_ra6m3g_freertos_json.h @@ -24,6 +24,10 @@ constexpr auto iar_ek_ra6m3g_freertos_json = R"( "windows": "%{Env:PROGRAMFILES}/SEGGER/JLink", "linux": "/opt/SEGGER/JLink" }, + "detectionPath": { + "windows": "JLink.exe", + "linux": "JLinkExe" + }, "optional": true, "addToSystemPath": true } diff --git a/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h b/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h index a5770bdef18..e55ecc2bdef 100644 --- a/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h @@ -20,6 +20,7 @@ constexpr auto iar_tviic2d6m_baremetal_json = R"( "label": "Cypress Auto Flash Utility", "type": "path", "cmakeVar": "INFINEON_AUTO_FLASH_UTILITY_DIR", + "detectionPath": "bin/openocd.exe", "optional": false, "addToSystemPath": true } @@ -45,7 +46,7 @@ constexpr auto iar_tviic2d6m_baremetal_json = R"( "executableArgs": "--version", "regex": "\\bV(\\d+\\.\\d+\\.\\d+)\\.\\d+\\b" }, - "detectionPath": "bin/iccarm.exe", + "detectionPath": "bin/iccarm.exe", "optional": false }, "file": { diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index 69ac5e06627..9a2e1153c43 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -165,6 +165,9 @@ const char jlinkSetting[]{"JLinkPath"}; const char jlinkCmakeVar[]{"JLINK_PATH"}; const char jlinkEnvVar[]{"JLINK_PATH"}; const char jlinkLabel[]{"Path to SEGGER J-Link"}; +const QString jlinkDetectionPath{HostOsInfo::isWindowsHost() + ? QString("JLink.exe") + : QString("JLinkExe")}; const QString unsupportedToolchainFilePath = QString{qtForMcuSdkPath} + "/lib/cmake/Qul/toolchain/unsupported.cmake"; @@ -1611,7 +1614,7 @@ void McuSupportTest::test_createJLink3rdPartyPackage() jlinkCmakeVar, jlinkEnvVar, jlinkLabel, - {}, + jlinkDetectionPath, {}); } From de88d1c437b8c43428921738244b0ad4d006f4d9 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 24 Aug 2022 14:57:43 +0200 Subject: [PATCH 87/97] QML: Use qtcEnvironmentVariable* instead of qEnvironmentVariable* And instead of qgetenv. Takes Qt Creator's setting at "Environment > System > Environment" into account, which makes it easier on some platforms to set them (e.g. macOS), can be configured differently in different settings paths, and potentially can be changed at runtime (depending on usage). Change-Id: I46378cc1aab44211cdc326afc5fabc78bf4b36a3 Reviewed-by: Tim Jenssen Reviewed-by: Qt CI Bot --- .../components/assetslibrary/assetslibrarywidget.cpp | 9 +++++---- .../components/curveeditor/detail/graphicsview.cpp | 3 ++- .../components/itemlibrary/itemlibrarywidget.cpp | 11 ++++++----- .../materialbrowser/materialbrowserwidget.cpp | 5 +++-- .../materialeditor/materialeditorqmlbackend.cpp | 5 +++-- .../components/materialeditor/materialeditorview.cpp | 7 ++++--- .../propertyeditor/propertyeditorqmlbackend.cpp | 3 ++- .../components/stateseditor/stateseditorwidget.cpp | 5 +++-- .../qmldesigner/designercore/metainfo/metainfo.cpp | 3 ++- .../qmldesigner/designercore/rewritertransaction.cpp | 4 +++- 10 files changed, 33 insertions(+), 22 deletions(-) diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp index e652fcd74f3..29fd84b2073 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp @@ -16,10 +16,11 @@ #include #include -#include +#include #include -#include +#include #include +#include #include #include @@ -47,7 +48,7 @@ namespace QmlDesigner { static QString propertyEditorResourcesPath() { #ifdef SHARE_QML_PATH - if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources"; #endif return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString(); @@ -232,7 +233,7 @@ void AssetsLibraryWidget::setModel(Model *model) QString AssetsLibraryWidget::qmlSourcesPath() { #ifdef SHARE_QML_PATH - if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) return QLatin1String(SHARE_QML_PATH) + "/itemLibraryQmlSources"; #endif return Core::ICore::resourcePath("qmldesigner/itemLibraryQmlSources").toString(); diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp index d7df6c9d633..faa906521f9 100644 --- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp @@ -10,6 +10,7 @@ #include "curveeditorutils.h" #include +#include #include #include @@ -405,7 +406,7 @@ void GraphicsView::contextMenuEvent(QContextMenuEvent *event) QMenu menu; - if (qEnvironmentVariableIsSet("QTC_STYLE_CURVE_EDITOR")) { + if (Utils::qtcEnvironmentVariableIsSet("QTC_STYLE_CURVE_EDITOR")) { QAction *openEditorAction = menu.addAction(tr("Open Style Editor")); connect(openEditorAction, &QAction::triggered, openStyleEditor); } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index dac6a0b8aa1..ae2c88f5b6f 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -23,11 +23,12 @@ #include #include -#include -#include +#include #include -#include +#include +#include #include +#include #include #include @@ -58,7 +59,7 @@ namespace QmlDesigner { static QString propertyEditorResourcesPath() { #ifdef SHARE_QML_PATH - if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources"; #endif return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString(); @@ -295,7 +296,7 @@ void ItemLibraryWidget::setModel(Model *model) QString ItemLibraryWidget::qmlSourcesPath() { #ifdef SHARE_QML_PATH - if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) return QLatin1String(SHARE_QML_PATH) + "/itemLibraryQmlSources"; #endif return Core::ICore::resourcePath("qmldesigner/itemLibraryQmlSources").toString(); diff --git a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp index c0d9648f28b..4a513d380f3 100644 --- a/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp +++ b/src/plugins/qmldesigner/components/materialbrowser/materialbrowserwidget.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -42,7 +43,7 @@ namespace QmlDesigner { static QString propertyEditorResourcesPath() { #ifdef SHARE_QML_PATH - if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources"; #endif return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString(); @@ -231,7 +232,7 @@ void MaterialBrowserWidget::startDragBundleMaterial(QmlDesigner::BundleMaterial QString MaterialBrowserWidget::qmlSourcesPath() { #ifdef SHARE_QML_PATH - if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) return QLatin1String(SHARE_QML_PATH) + "/materialBrowserQmlSource"; #endif return Core::ICore::resourcePath("qmldesigner/materialBrowserQmlSource").toString(); diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.cpp index 3cccbe0b4a7..4ac5d5b300e 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorqmlbackend.cpp @@ -15,9 +15,10 @@ #include #include -#include #include +#include #include +#include #include #include @@ -295,7 +296,7 @@ void MaterialEditorQmlBackend::setup(const QmlObjectNode &selectedMaterialNode, QString MaterialEditorQmlBackend::propertyEditorResourcesPath() { #ifdef SHARE_QML_PATH - if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources"; #endif return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString(); diff --git a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp index 9ddfbe73bec..599e4612391 100644 --- a/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp +++ b/src/plugins/qmldesigner/components/materialeditor/materialeditorview.cpp @@ -29,10 +29,11 @@ #include #include #include -#include +#include +#include #include #include -#include +#include #include #include @@ -363,7 +364,7 @@ void MaterialEditorView::resetView() QString MaterialEditorView::materialEditorResourcesPath() { #ifdef SHARE_QML_PATH - if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) return QLatin1String(SHARE_QML_PATH) + "/materialEditorQmlSources"; #endif return Core::ICore::resourcePath("qmldesigner/materialEditorQmlSources").toString(); diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp index a8625ca784c..894957ed049 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -542,7 +543,7 @@ void PropertyEditorQmlBackend::initialSetup(const TypeName &typeName, const QUrl QString PropertyEditorQmlBackend::propertyEditorResourcesPath() { #ifdef SHARE_QML_PATH - if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources"; #endif return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString(); diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp index fdb61de8daf..2c2272ac8f9 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -39,7 +40,7 @@ namespace QmlDesigner { static QString propertyEditorResourcesPath() { #ifdef SHARE_QML_PATH - if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources"; #endif return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString(); @@ -107,7 +108,7 @@ StatesEditorWidget::~StatesEditorWidget() = default; QString StatesEditorWidget::qmlSourcesPath() { #ifdef SHARE_QML_PATH - if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) return QLatin1String(SHARE_QML_PATH) + "/statesEditorQmlSources"; #endif return Core::ICore::resourcePath("qmldesigner/statesEditorQmlSources").toString(); diff --git a/src/plugins/qmldesigner/designercore/metainfo/metainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/metainfo.cpp index ae8abef5a19..838b5ebd18e 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/metainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/metainfo.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include "pluginmanager/widgetpluginmanager.h" @@ -33,7 +34,7 @@ namespace Internal { static QString globalMetaInfoPath() { #ifdef SHARE_QML_PATH - if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + if (Utils::qtcEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) return QLatin1String(SHARE_QML_PATH) + "/globalMetaInfo"; #endif return Core::ICore::resourcePath("qmldesigner/globalMetaInfo").toString(); diff --git a/src/plugins/qmldesigner/designercore/rewritertransaction.cpp b/src/plugins/qmldesigner/designercore/rewritertransaction.cpp index 5253d412e2a..b7e59b25b17 100644 --- a/src/plugins/qmldesigner/designercore/rewritertransaction.cpp +++ b/src/plugins/qmldesigner/designercore/rewritertransaction.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #ifndef QMLDESIGNER_TEST @@ -18,7 +19,8 @@ namespace QmlDesigner { QList RewriterTransaction::m_identifierList; -bool RewriterTransaction::m_activeIdentifier = qEnvironmentVariableIsSet("QML_DESIGNER_TRACE_REWRITER_TRANSACTION"); +bool RewriterTransaction::m_activeIdentifier = Utils::qtcEnvironmentVariableIsSet( + "QML_DESIGNER_TRACE_REWRITER_TRANSACTION"); RewriterTransaction::RewriterTransaction() : m_valid(false) { From 02f7c9c3eb290bbd362349dab684606ad93b6e60 Mon Sep 17 00:00:00 2001 From: Tomi Korpipaa Date: Mon, 3 Oct 2022 14:06:29 +0300 Subject: [PATCH 88/97] Import QQEM effects via drag or add button MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Be able to add effects using file system drag&drop or using the add resource button Task-number: QTBUG-100626 Change-Id: I33c3ebe29797325a2ed1819bd867e97ae3f8b61c Reviewed-by: Miikka Heikkinen Reviewed-by: Tomi Korpipää Reviewed-by: Reviewed-by: Mahmoud Badri --- .../itemLibraryQmlSources/AssetsView.qml | 13 ++- .../templates/wizards/files/effect/file.qep | 0 .../wizards/files/effect/wizard.json | 40 ++++++++++ .../assetslibrary/assetslibrarymodel.cpp | 12 ++- .../assetslibrary/assetslibrarymodel.h | 1 + .../assetslibrary/assetslibrarywidget.cpp | 63 ++++++++++++++- .../assetslibrary/assetslibrarywidget.h | 8 +- .../componentcore/componentcore_constants.h | 4 +- .../componentcore/modelnodeoperations.cpp | 15 +++- .../componentcore/modelnodeoperations.h | 6 +- .../formeditor/abstractformeditortool.cpp | 3 +- .../components/formeditor/dragtool.cpp | 79 +++++++++++++------ .../designercore/include/qmlitemnode.h | 4 +- .../designercore/model/qmlitemnode.cpp | 27 +++++++ .../designercore/model/texttomodelmerger.cpp | 6 +- .../qmldesigner/qmldesignerconstants.h | 1 + src/plugins/qmldesigner/qmldesignerplugin.cpp | 5 ++ src/plugins/qmldesigner/qmldesignerplugin.h | 4 +- 18 files changed, 250 insertions(+), 41 deletions(-) create mode 100644 share/qtcreator/templates/wizards/files/effect/file.qep create mode 100644 share/qtcreator/templates/wizards/files/effect/wizard.json diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsView.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsView.qml index e1c017814d6..77a784d92d5 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsView.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/AssetsView.qml @@ -162,6 +162,7 @@ ScrollView { // TODO: experiment using ListView instead of ScrollView + Column readonly property string suffix: fileName.substr(-4) readonly property bool isFont: suffix === ".ttf" || suffix === ".otf" + readonly property bool isEffect: suffix === ".qep" property bool currFileSelected: false MouseArea { @@ -180,7 +181,7 @@ ScrollView { // TODO: experiment using ListView instead of ScrollView + Column allowTooltip = true } onPositionChanged: tooltipBackend.reposition() - onPressed: (mouse)=> { + onPressed: (mouse) => { forceActiveFocus() allowTooltip = false tooltipBackend.hideTooltip() @@ -212,7 +213,7 @@ ScrollView { // TODO: experiment using ListView instead of ScrollView + Column } } - onReleased: (mouse)=> { + onReleased: (mouse) => { allowTooltip = true if (mouse.button === Qt.LeftButton) { if (!(mouse.modifiers & Qt.ControlModifier)) @@ -222,6 +223,14 @@ ScrollView { // TODO: experiment using ListView instead of ScrollView + Column } } + onDoubleClicked: (mouse) => { + forceActiveFocus() + allowTooltip = false + tooltipBackend.hideTooltip() + if (mouse.button === Qt.LeftButton && isEffect) + rootView.openEffectMaker(filePath) + } + ToolTip { visible: !isFont && mouseArea.containsMouse && !contextMenu.visible text: filePath diff --git a/share/qtcreator/templates/wizards/files/effect/file.qep b/share/qtcreator/templates/wizards/files/effect/file.qep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/share/qtcreator/templates/wizards/files/effect/wizard.json b/share/qtcreator/templates/wizards/files/effect/wizard.json new file mode 100644 index 00000000000..d966f097eda --- /dev/null +++ b/share/qtcreator/templates/wizards/files/effect/wizard.json @@ -0,0 +1,40 @@ +{ + "version": 1, + "supportedProjectTypes": [ ], + "id": "J.QEP", + "category": "U.QEP", + "trDescription": "Creates an Effect Maker file.", + "trDisplayName": "Effect File (Effect Maker)", + "trDisplayCategory": "Effects", + "iconText": "qep", + "platformIndependent": true, + "enabled": true, + + "options": { "key": "DefaultSuffix", "value": "qep" }, + + "pages" : + [ + { + "trDisplayName": "Location", + "trShortTitle": "Location", + "typeId": "File" + }, + { + "trDisplayName": "Project Management", + "trShortTitle": "Summary", + "typeId": "Summary" + } + ], + "generators" : + [ + { + "typeId": "File", + "data": + { + "source": "file.qep", + "target": "%{JS: Util.fileName(value('TargetPath'), value('DefaultSuffix'))}", + "openInEditor": false + } + } + ] +} diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp index c538b452729..3b013cc2d11 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.cpp @@ -230,7 +230,7 @@ QObject *AssetsLibraryModel::rootDir() const bool AssetsLibraryModel::isEmpty() const { return m_isEmpty; -}; +} void AssetsLibraryModel::setIsEmpty(bool empty) { @@ -238,7 +238,7 @@ void AssetsLibraryModel::setIsEmpty(bool empty) m_isEmpty = empty; emit isEmptyChanged(); } -}; +} QVariant AssetsLibraryModel::data(const QModelIndex &index, int role) const { @@ -398,6 +398,13 @@ const QStringList &AssetsLibraryModel::supportedTexture3DSuffixes() return retList; } +const QStringList &AssetsLibraryModel::supportedEffectMakerSuffixes() +{ + // These are file types only supported by Effect Maker + static QStringList retList {"*.qep"}; + return retList; +} + const QSet &AssetsLibraryModel::supportedSuffixes() { static QSet allSuffixes; @@ -412,6 +419,7 @@ const QSet &AssetsLibraryModel::supportedSuffixes() insertSuffixes(supportedAudioSuffixes()); insertSuffixes(supportedVideoSuffixes()); insertSuffixes(supportedTexture3DSuffixes()); + insertSuffixes(supportedEffectMakerSuffixes()); } return allSuffixes; } diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h index e964766f952..4e846f93af9 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarymodel.h @@ -66,6 +66,7 @@ public: static const QStringList &supportedAudioSuffixes(); static const QStringList &supportedVideoSuffixes(); static const QStringList &supportedTexture3DSuffixes(); + static const QStringList &supportedEffectMakerSuffixes(); static const QSet &supportedSuffixes(); const QSet &previewableSuffixes() const; diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp index 93057e6733a..5d456175229 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.cpp @@ -43,11 +43,18 @@ #include #include #include +#include "utils/environment.h" +#include "utils/filepath.h" +#include "utils/qtcprocess.h" #include #include #include +#include +#include +#include + #include #include #include @@ -64,6 +71,9 @@ #include #include +#include +#include + namespace QmlDesigner { static QString propertyEditorResourcesPath() @@ -141,11 +151,17 @@ AssetsLibraryWidget::AssetsLibraryWidget(AsynchronousImageCache &asynchronousFon // If project directory contents change, or one of the asset files is modified, we must // reconstruct the model to update the icons - connect(m_fileSystemWatcher, &Utils::FileSystemWatcher::directoryChanged, [this](const QString & changedDirPath) { + connect(m_fileSystemWatcher, &Utils::FileSystemWatcher::directoryChanged, + [this](const QString &changedDirPath) { Q_UNUSED(changedDirPath) m_assetCompressionTimer.start(); }); + connect(m_fileSystemWatcher, &Utils::FileSystemWatcher::fileChanged, + [](const QString &changeFilePath) { + QmlDesignerPlugin::instance()->emitAssetChanged(changeFilePath); + }); + auto layout = new QVBoxLayout(this); layout->setContentsMargins({}); layout->setSpacing(0); @@ -245,6 +261,48 @@ QSet AssetsLibraryWidget::supportedAssetSuffixes(bool complex) return suffixes; } +void AssetsLibraryWidget::openEffectMaker(const QString &filePath) +{ + const ProjectExplorer::Target *target = ProjectExplorer::ProjectTree::currentTarget(); + if (!target) { + qWarning() << __FUNCTION__ << "No project open"; + return; + } + + Utils::FilePath projectPath = target->project()->projectDirectory(); + QString effectName = QFileInfo(filePath).baseName(); + QString effectResDir = "asset_imports/Effects/" + effectName; + Utils::FilePath effectResPath = projectPath.resolvePath(effectResDir); + if (!effectResPath.exists()) + QDir(projectPath.toString()).mkpath(effectResDir); + + const QtSupport::QtVersion *baseQtVersion = QtSupport::QtKitAspect::qtVersion(target->kit()); + if (baseQtVersion) { + auto effectMakerPath = baseQtVersion->binPath().pathAppended("QQEffectMaker").withExecutableSuffix(); + if (!effectMakerPath.exists()) { + qWarning() << __FUNCTION__ << "Cannot find EffectMaker app"; + return; + } + + Utils::FilePath effectPath = Utils::FilePath::fromString(filePath); + QString effectContents = QString::fromUtf8(effectPath.fileContents()); + QStringList arguments; + arguments << filePath; + if (effectContents.isEmpty()) + arguments << "--create"; + arguments << "--exportpath" << effectResPath.toString(); + + Utils::Environment env = Utils::Environment::systemEnvironment(); + if (env.osType() == Utils::OsTypeMac) + env.appendOrSet("QSG_RHI_BACKEND", "metal"); + + m_qqemProcess.reset(new Utils::QtcProcess); + m_qqemProcess->setEnvironment(env); + m_qqemProcess->setCommand({ effectMakerPath, arguments }); + m_qqemProcess->start(); + } +} + void AssetsLibraryWidget::setModel(Model *model) { m_model = model; @@ -316,6 +374,9 @@ QPair AssetsLibraryWidget::getAssetTypeAndData(const QStrin } else if (AssetsLibraryModel::supportedTexture3DSuffixes().contains(suffix)) { // Data: Image format (suffix) return {Constants::MIME_TYPE_ASSET_TEXTURE3D, suffix.toUtf8()}; + } else if (AssetsLibraryModel::supportedEffectMakerSuffixes().contains(suffix)) { + // Data: Effect Maker format (suffix) + return {Constants::MIME_TYPE_ASSET_EFFECT, suffix.toUtf8()}; } } return {}; diff --git a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h index 29ba7d0349c..dcec0f9414e 100644 --- a/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h +++ b/src/plugins/qmldesigner/components/assetslibrary/assetslibrarywidget.h @@ -42,7 +42,10 @@ QT_BEGIN_NAMESPACE class QShortcut; QT_END_NAMESPACE -namespace Utils { class FileSystemWatcher; } +namespace Utils { + class FileSystemWatcher; + class QtcProcess; +} namespace QmlDesigner { @@ -83,6 +86,7 @@ public: const QList &complexFilePaths, const QString &targetDirPath = {}); Q_INVOKABLE QSet supportedAssetSuffixes(bool complex); + Q_INVOKABLE void openEffectMaker(const QString &filePath); signals: void itemActivated(const QString &itemName); @@ -114,6 +118,8 @@ private: bool m_updateRetry = false; QString m_filterText; QPoint m_dragStartPoint; + + std::unique_ptr m_qqemProcess; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h index 884a4f4413f..92594f6ab40 100644 --- a/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h +++ b/src/plugins/qmldesigner/components/componentcore/componentcore_constants.h @@ -233,8 +233,8 @@ const char addShadersDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResource const char add3DAssetsDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "3D Assets"); const char addQt3DSPresentationsDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "Qt 3D Studio Presentations"); - -const char addCustomEffectDialogDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "Add Custom Effect"); +const char addCustomEffectDialogDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", + "Effect Maker Files"); } //ComponentCoreConstants diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp index 5724d5d1002..0e442918da3 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.cpp @@ -1614,10 +1614,23 @@ void updateImported3DAsset(const SelectionContext &selectionContext) if (selectionContext.view()) { selectionContext.view()->emitCustomNotification( "UpdateImported3DAsset", {selectionContext.currentSingleSelectedNode()}); - } } +Utils::FilePath getEffectsDirectory() +{ + QString defaultDir = "asset_imports/Effects"; + Utils::FilePath projectPath = QmlDesignerPlugin::instance()->documentManager().currentProjectDirPath(); + Utils::FilePath effectsPath = projectPath.pathAppended(defaultDir); + + if (!effectsPath.exists()) { + QDir dir(projectPath.toString()); + dir.mkpath(defaultDir); + } + + return effectsPath; +} + } // namespace ModelNodeOperations } //QmlDesigner diff --git a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h index 953062573cf..0b1b298a6f2 100644 --- a/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h +++ b/src/plugins/qmldesigner/components/componentcore/modelnodeoperations.h @@ -27,6 +27,8 @@ #include "selectioncontext.h" +#include + namespace QmlDesigner { enum class AddFilesResult { Succeeded, Failed, Cancelled }; @@ -77,7 +79,7 @@ void addItemToStackedContainer(const SelectionContext &selectionContext); void increaseIndexOfStackedContainer(const SelectionContext &selectionContext); void decreaseIndexOfStackedContainer(const SelectionContext &selectionContext); void addTabBarToStackedContainer(const SelectionContext &selectionContext); -AddFilesResult addFilesToProject(const QStringList &fileNames, const QString &defaultDirectory); +QMLDESIGNERCORE_EXPORT AddFilesResult addFilesToProject(const QStringList &fileNames, const QString &defaultDirectory); AddFilesResult addImageToProject(const QStringList &fileNames, const QString &directory); AddFilesResult addFontToProject(const QStringList &fileNames, const QString &directory); AddFilesResult addSoundToProject(const QStringList &fileNames, const QString &directory); @@ -98,6 +100,8 @@ void addMouseAreaFill(const SelectionContext &selectionContext); void openSignalDialog(const SelectionContext &selectionContext); void updateImported3DAsset(const SelectionContext &selectionContext); +QMLDESIGNERCORE_EXPORT Utils::FilePath getEffectsDirectory(); + // ModelNodePreviewImageOperations QVariant previewImageDataForGenericNode(const ModelNode &modelNode); QVariant previewImageDataForImageNode(const ModelNode &modelNode); diff --git a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp index 9f24e7d0e9f..cab4a051319 100644 --- a/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp +++ b/src/plugins/qmldesigner/components/formeditor/abstractformeditortool.cpp @@ -242,7 +242,8 @@ void AbstractFormEditorTool::dragEnterEvent(const QList &itemLis for (const QString &assetPath : assetPaths) { QString assetType = AssetsLibraryWidget::getAssetTypeAndData(assetPath).first; if (assetType == Constants::MIME_TYPE_ASSET_IMAGE - || assetType == Constants::MIME_TYPE_ASSET_FONT) { + || assetType == Constants::MIME_TYPE_ASSET_FONT + || assetType == Constants::MIME_TYPE_ASSET_EFFECT) { hasValidAssets = true; break; } diff --git a/src/plugins/qmldesigner/components/formeditor/dragtool.cpp b/src/plugins/qmldesigner/components/formeditor/dragtool.cpp index 819bf58b34a..290e9f21939 100644 --- a/src/plugins/qmldesigner/components/formeditor/dragtool.cpp +++ b/src/plugins/qmldesigner/components/formeditor/dragtool.cpp @@ -240,38 +240,64 @@ static bool hasItemLibraryInfo(const QMimeData *mimeData) return mimeData->hasFormat(Constants::MIME_TYPE_ITEM_LIBRARY_INFO); } -void DragTool::dropEvent(const QList &/*itemList*/, QGraphicsSceneDragDropEvent *event) +void DragTool::dropEvent(const QList &itemList, QGraphicsSceneDragDropEvent *event) { if (canBeDropped(event->mimeData())) { event->accept(); end(generateUseSnapping(event->modifiers())); + QString effectPath; + const QStringList assetPaths = QString::fromUtf8(event->mimeData() + ->data(Constants::MIME_TYPE_ASSETS)).split(','); + for (auto &path : assetPaths) { + auto assetType = AssetsLibraryWidget::getAssetTypeAndData(path).first; + if (assetType == Constants::MIME_TYPE_ASSET_EFFECT) { + effectPath = path; + break; + } + } + bool resetPuppet = false; - for (auto &node : m_dragNodes) { - if (node.isValid()) { - if ((node.instanceParentItem().isValid() - && node.instanceParent().modelNode().metaInfo().isLayoutable()) - || node.isFlowItem()) { - node.removeProperty("x"); - node.removeProperty("y"); - resetPuppet = true; + + if (!effectPath.isEmpty()) { + FormEditorItem *targetContainerFormEditorItem = targetContainerOrRootItem(itemList); + if (targetContainerFormEditorItem) { + QmlItemNode parentQmlItemNode = targetContainerFormEditorItem->qmlItemNode(); + QString effectName = QFileInfo(effectPath).baseName(); + QmlItemNode effectNode = QmlItemNode::createQmlItemNodeForEffect(view(), parentQmlItemNode, effectName); + + view()->setSelectedModelNodes({effectNode}); + view()->resetPuppet(); + + commitTransaction(); + } + } else { + for (QmlItemNode &node : m_dragNodes) { + if (node.isValid()) { + if ((node.instanceParentItem().isValid() + && node.instanceParent().modelNode().metaInfo().isLayoutable()) + || node.isFlowItem()) { + node.removeProperty("x"); + node.removeProperty("y"); + resetPuppet = true; + } } } - } - if (resetPuppet) - view()->resetPuppet(); // Otherwise the layout might not reposition the items + if (resetPuppet) + view()->resetPuppet(); // Otherwise the layout might not reposition the items - commitTransaction(); + commitTransaction(); - if (!m_dragNodes.isEmpty()) { - QList nodeList; - for (auto &node : std::as_const(m_dragNodes)) { - if (node.isValid()) - nodeList.append(node); + if (!m_dragNodes.isEmpty()) { + QList nodeList; + for (auto &node : std::as_const(m_dragNodes)) { + if (node.isValid()) + nodeList.append(node); + } + view()->setSelectedModelNodes(nodeList); } - view()->setSelectedModelNodes(nodeList); + m_dragNodes.clear(); } - m_dragNodes.clear(); view()->changeToSelectionTool(); } @@ -347,10 +373,17 @@ void DragTool::createDragNodes(const QMimeData *mimeData, const QPointF &scenePo void DragTool::dragMoveEvent(const QList &itemList, QGraphicsSceneDragDropEvent *event) { - if (!m_blockMove && !m_isAborted && canBeDropped(event->mimeData())) { + FormEditorItem *targetContainerItem = targetContainerOrRootItem(itemList); + const QStringList assetPaths = QString::fromUtf8(event->mimeData() + ->data(Constants::MIME_TYPE_ASSETS)).split(','); + QString assetType = AssetsLibraryWidget::getAssetTypeAndData(assetPaths[0]).first; + + if (!m_blockMove + && !m_isAborted + && canBeDropped(event->mimeData()) + && assetType != Constants::MIME_TYPE_ASSET_EFFECT) { event->accept(); if (!m_dragNodes.isEmpty()) { - FormEditorItem *targetContainerItem = targetContainerOrRootItem(itemList); if (targetContainerItem) { move(event->scenePos(), itemList); } else { @@ -364,7 +397,7 @@ void DragTool::dragMoveEvent(const QList &itemList, QGraphicsSc } else { createDragNodes(event->mimeData(), event->scenePos(), itemList); } - } else { + } else if (assetType != Constants::MIME_TYPE_ASSET_EFFECT) { event->ignore(); } } diff --git a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h index 3a3498e6c9a..5406f819180 100644 --- a/src/plugins/qmldesigner/designercore/include/qmlitemnode.h +++ b/src/plugins/qmldesigner/designercore/include/qmlitemnode.h @@ -81,7 +81,9 @@ public: const QPointF &position, NodeAbstractProperty parentproperty, bool executeInTransaction = true); - + static QmlItemNode createQmlItemNodeForEffect(AbstractView *view, + const QmlItemNode &parentNode, + const QString &effectName); QList children() const; QList resources() const; QList allDirectSubNodes() const; diff --git a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp index 6580c4005ba..09a94719f48 100644 --- a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp @@ -181,6 +181,33 @@ QmlItemNode QmlItemNode::createQmlItemNodeFromFont(AbstractView *view, return newQmlItemNode; } +QmlItemNode QmlItemNode::createQmlItemNodeForEffect(AbstractView *view, + const QmlItemNode &parentNode, + const QString &effectName) +{ + QmlItemNode newQmlItemNode; + + QmlDesigner::Import import = Import::createLibraryImport("Effects." + effectName, "1.0"); + try { + if (!view->model()->hasImport(import, true, true)) + view->model()->changeImports({import}, {}); + } catch (const Exception &e) { + QTC_ASSERT(false, return QmlItemNode()); + } + + TypeName type(effectName.toUtf8()); + newQmlItemNode = QmlItemNode(view->createModelNode(type, 1, 0)); + NodeAbstractProperty parentProperty = parentNode.defaultNodeAbstractProperty(); + parentProperty.reparentHere(newQmlItemNode); + + newQmlItemNode.modelNode().bindingProperty("source").setExpression("parent"); + newQmlItemNode.modelNode().bindingProperty("anchors.fill").setExpression("parent"); + + QTC_ASSERT(newQmlItemNode.isValid(), return QmlItemNode()); + + return newQmlItemNode; +} + bool QmlItemNode::isValid() const { return isValidQmlItemNode(modelNode()); diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 8e9b6844307..e4d9c624e92 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -530,10 +530,6 @@ public: qDebug() << astTypeNode->name.toString() << typeName; qDebug() << metaInfo.isValid() << metaInfo.typeName(); qDebug() << metaInfo.directSuperClass().typeName(); - - if (!metaInfo.isFileComponent() && m_model == m_model->metaInfoProxyModel() - && metaInfo.isValid()) - throw RewritingException(__LINE__, __FUNCTION__, __FILE__, "test", "test"); } typeName = QString::fromUtf8(metaInfo.typeName()); @@ -1961,7 +1957,7 @@ void ModelValidator::typeDiffers(bool /*isRootNode*/, Q_UNUSED(minorVersion) Q_UNUSED(majorVersion) - QTC_ASSERT(modelNode.type() == typeName, return ); + QTC_ASSERT(modelNode.type() == typeName, return); if (modelNode.majorVersion() != majorVersion) { qDebug() << Q_FUNC_INFO << modelNode; diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 45dbda6b961..40c751ed980 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -105,6 +105,7 @@ const char MIME_TYPE_ASSET_SOUND[] = "application/vnd.qtdesignstudio.asset const char MIME_TYPE_ASSET_VIDEO[] = "application/vnd.qtdesignstudio.asset.video"; const char MIME_TYPE_ASSET_TEXTURE3D[] = "application/vnd.qtdesignstudio.asset.texture3d"; const char MIME_TYPE_MODELNODE_LIST[] = "application/vnd.qtdesignstudio.modelnode.list"; +const char MIME_TYPE_ASSET_EFFECT[] = "application/vnd.qtdesignstudio.asset.effect"; // Menus const char M_VIEW_WORKSPACES[] = "QmlDesigner.Menu.View.Workspaces"; diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 6226e54e808..d8c71fcd056 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -641,6 +641,11 @@ void QmlDesignerPlugin::emitCurrentTextEditorChanged(Core::IEditor *editor) d->blockEditorChange = false; } +void QmlDesignerPlugin::emitAssetChanged(const QString &assetPath) +{ + emit assetChanged(assetPath); +} + double QmlDesignerPlugin::formEditorDevicePixelRatio() { if (QmlDesignerPlugin::settings().value(DesignerSettingsKey::IGNORE_DEVICE_PIXEL_RATIO).toBool()) diff --git a/src/plugins/qmldesigner/qmldesignerplugin.h b/src/plugins/qmldesigner/qmldesignerplugin.h index 976b9d57c06..aa5fe250018 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.h +++ b/src/plugins/qmldesigner/qmldesignerplugin.h @@ -85,6 +85,8 @@ public: void switchToTextModeDeferred(); void emitCurrentTextEditorChanged(Core::IEditor *editor); + void emitAssetChanged(const QString &assetPath); + static double formEditorDevicePixelRatio(); static void emitUsageStatistics(const QString &identifier); @@ -101,7 +103,7 @@ public: signals: void usageStatisticsNotifier(const QString &identifier); void usageStatisticsUsageTimer(const QString &identifier, int elapsed); - + void assetChanged(const QString &assetPath); private: // functions void integrateIntoQtCreator(QWidget *modeWidget); From 7fa756663c79e43f3a3cefafc4217f685aa7087b Mon Sep 17 00:00:00 2001 From: Daniele Bortolotti Date: Tue, 1 Nov 2022 09:10:42 +0100 Subject: [PATCH 89/97] McuSupport: update default MCU project template (qmlproject) The QmlProject example template is too small for high-resolution displays, so remove hardcoded width, height and increase font size. See: QTCREATORBUG-28159 Change-Id: I67a02c2ffe8d6e54f633f1061062459ecaac0e56 Reviewed-by: Reviewed-by: Rainer Keller Reviewed-by: Eike Ziller --- src/plugins/mcusupport/wizards/qmlproject/component.qml.tpl | 2 +- src/plugins/mcusupport/wizards/qmlproject/main.qml.tpl | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/plugins/mcusupport/wizards/qmlproject/component.qml.tpl b/src/plugins/mcusupport/wizards/qmlproject/component.qml.tpl index 69b8e643bfc..15219a2fa12 100644 --- a/src/plugins/mcusupport/wizards/qmlproject/component.qml.tpl +++ b/src/plugins/mcusupport/wizards/qmlproject/component.qml.tpl @@ -3,5 +3,5 @@ import QtQuick 2.0 Text { color: "salmon" text: "Hello World!" - font.pixelSize: 14 + font.pixelSize: 30 } diff --git a/src/plugins/mcusupport/wizards/qmlproject/main.qml.tpl b/src/plugins/mcusupport/wizards/qmlproject/main.qml.tpl index a60dd10046a..183a9b91745 100644 --- a/src/plugins/mcusupport/wizards/qmlproject/main.qml.tpl +++ b/src/plugins/mcusupport/wizards/qmlproject/main.qml.tpl @@ -2,9 +2,6 @@ import QtQuick 2.0 import CustomModule Rectangle { - width: 480 - height: 272 - CustomComponent { anchors.centerIn: parent } From e16a5c8d0e64312cd63f5ea6370eb37a7da6bc00 Mon Sep 17 00:00:00 2001 From: Daniele Bortolotti Date: Mon, 31 Oct 2022 14:21:16 +0100 Subject: [PATCH 90/97] McuSupport: Update test json headers for TraveoII board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reflect changes in QUL repo that allow for correct SDK and GHS compiler version detection. Change-Id: Ibc54f45ef214227db5681c33b3278dc52f5bdde6 Reviewed-by: Reviewed-by: Sivert Krøvel Reviewed-by: Eike Ziller --- .../mcusupport/test/ghs_tviic2d4m_baremetal_json.h | 14 +++++++++++--- .../mcusupport/test/ghs_tviic2d6m_baremetal_json.h | 14 +++++++++++--- .../mcusupport/test/iar_tviic2d6m_baremetal_json.h | 4 +++- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/plugins/mcusupport/test/ghs_tviic2d4m_baremetal_json.h b/src/plugins/mcusupport/test/ghs_tviic2d4m_baremetal_json.h index 9500c21c1d6..22a6d0809f9 100644 --- a/src/plugins/mcusupport/test/ghs_tviic2d4m_baremetal_json.h +++ b/src/plugins/mcusupport/test/ghs_tviic2d4m_baremetal_json.h @@ -29,7 +29,7 @@ constexpr auto ghs_tviic2d4m_baremetal_json = R"( "toolchain": { "id": "arm-greenhills", "versions": [ - "201954" + "2019.5.4" ], "compiler": { "id": "GHS_ARM_DIR", @@ -38,7 +38,13 @@ constexpr auto ghs_tviic2d4m_baremetal_json = R"( "setting": "GHSArmToolchain", "detectionPath": "cxarm.exe", "type": "path", - "optional": false + "optional": false, + "versionDetection": { + "filePattern": "gversion.exe", + "executableArgs": "-help", + "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": "cxarm.exe" }, "file": { "id": "GHS_ARM_CMAKE_TOOLCHAIN_FILE", @@ -59,7 +65,9 @@ constexpr auto ghs_tviic2d4m_baremetal_json = R"( "label": "Graphics Driver for Traveo II Cluster Series", "cmakeVar": "QUL_BOARD_SDK_DIR", "type": "path", - "optional": false + "optional": false, + "versionDetection": { + "regex": "V\\w+\\.\\d+\\.\\d+" } } )"; diff --git a/src/plugins/mcusupport/test/ghs_tviic2d6m_baremetal_json.h b/src/plugins/mcusupport/test/ghs_tviic2d6m_baremetal_json.h index 88b98f0626c..9f2dfb63921 100644 --- a/src/plugins/mcusupport/test/ghs_tviic2d6m_baremetal_json.h +++ b/src/plugins/mcusupport/test/ghs_tviic2d6m_baremetal_json.h @@ -29,7 +29,7 @@ constexpr auto ghs_tviic2d6m_baremetal_json = R"( "toolchain": { "id": "arm-greenhills", "versions": [ - "201954" + "2019.5.4" ], "compiler": { "id": "GHS_ARM_DIR", @@ -38,7 +38,13 @@ constexpr auto ghs_tviic2d6m_baremetal_json = R"( "setting": "GHSArmToolchain", "detectionPath": "cxarm.exe", "type": "path", - "optional": false + "optional": false, + "versionDetection": { + "filePattern": "gversion.exe", + "executableArgs": "-help", + "regex": "\\bv(\\d+\\.\\d+\\.\\d+)\\b" + }, + "detectionPath": "cxarm.exe" }, "file": { "id": "GHS_ARM_CMAKE_TOOLCHAIN_FILE", @@ -59,7 +65,9 @@ constexpr auto ghs_tviic2d6m_baremetal_json = R"( "label": "Graphics Driver for Traveo II Cluster Series", "cmakeVar": "QUL_BOARD_SDK_DIR", "type": "path", - "optional": false + "optional": false, + "versionDetection": { + "regex": "V\\w+\\.\\d+\\.\\d+" } } )"; diff --git a/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h b/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h index e55ecc2bdef..983aeeaf741 100644 --- a/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h +++ b/src/plugins/mcusupport/test/iar_tviic2d6m_baremetal_json.h @@ -68,7 +68,9 @@ constexpr auto iar_tviic2d6m_baremetal_json = R"( "label": "Graphics Driver for Traveo II Cluster Series", "cmakeVar": "QUL_BOARD_SDK_DIR", "type": "path", - "optional": false + "optional": false, + "versionDetection": { + "regex": "V\\w+\\.\\d+\\.\\d+" } } )"; From 71ae73119ee9ba16efaebabc03d13a1c9af3676f Mon Sep 17 00:00:00 2001 From: Yasser Grimes Date: Mon, 24 Oct 2022 18:50:27 +0300 Subject: [PATCH 91/97] McuSupport: Support globbing in default paths With this change default paths containing globbing characters will be expanded to an available path. example: "sdk-*" will be replaced with "sdk-1.2.3" if the latter is available. To test the wildcards and make sure it works with QtCreator macros a fake_kit was added containing fake packages. Task-number: QTCREATORBUG-26900 Change-Id: I31440d24e42a6170fc5f1905f884bb3be43c57bc Reviewed-by: Eike Ziller --- src/plugins/mcusupport/mcusupportoptions.cpp | 23 +++++- src/plugins/mcusupport/mcusupportoptions.h | 2 +- .../mcusupport/mcusupportoptionspage.cpp | 2 +- src/plugins/mcusupport/mcusupportsdk.cpp | 2 +- src/plugins/mcusupport/mcutargetfactory.cpp | 1 - src/plugins/mcusupport/test/unittest.cpp | 81 ++++++++++++++++++- src/plugins/mcusupport/test/unittest.h | 3 + .../mcusupport/test/wildcards_test_kit_json.h | 74 +++++++++++++++++ 8 files changed, 179 insertions(+), 9 deletions(-) create mode 100644 src/plugins/mcusupport/test/wildcards_test_kit_json.h diff --git a/src/plugins/mcusupport/mcusupportoptions.cpp b/src/plugins/mcusupport/mcusupportoptions.cpp index 25d922bfe8d..cd87896803a 100644 --- a/src/plugins/mcusupport/mcusupportoptions.cpp +++ b/src/plugins/mcusupport/mcusupportoptions.cpp @@ -30,18 +30,37 @@ using namespace Utils; namespace McuSupport::Internal { +static const Utils::FilePath expandWildcards(const Utils::FilePath& path) +{ + if (!path.fileName().contains("*") && !path.fileName().contains("?")) + return path; + + const FilePath p = path.parentDir(); + + auto entries = p.dirEntries( + Utils::FileFilter({path.fileName()}, QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot)); + + if (entries.isEmpty()) + return path; + + // Return the last match (can correspond to the latest version) + sort(entries, [](const FilePath &a, const FilePath &b) { return a.fileName() < b.fileName(); }); + + return entries.last(); +} + Macros *McuSdkRepository::globalMacros() { static Macros macros; return ¯os; } -void McuSdkRepository::expandVariables() +void McuSdkRepository::expandVariablesAndWildcards() { for (const auto &target : std::as_const(mcuTargets)) { auto macroExpander = getMacroExpander(*target); for (const auto &package : target->packages()) { - package->setPath(macroExpander->expand(package->path())); + package->setPath(expandWildcards(macroExpander->expand(package->path()))); } } } diff --git a/src/plugins/mcusupport/mcusupportoptions.h b/src/plugins/mcusupport/mcusupportoptions.h index 8fddf21ab40..f6e39e529ae 100644 --- a/src/plugins/mcusupport/mcusupportoptions.h +++ b/src/plugins/mcusupport/mcusupportoptions.h @@ -40,7 +40,7 @@ public: Targets mcuTargets; Packages packages; - void expandVariables(); + void expandVariablesAndWildcards(); MacroExpanderPtr getMacroExpander(const McuTarget &target); static Macros *globalMacros(); diff --git a/src/plugins/mcusupport/mcusupportoptionspage.cpp b/src/plugins/mcusupport/mcusupportoptionspage.cpp index 556dfd0e216..f317026c07f 100644 --- a/src/plugins/mcusupport/mcusupportoptionspage.cpp +++ b/src/plugins/mcusupport/mcusupportoptionspage.cpp @@ -289,7 +289,7 @@ void McuSupportOptionsWidget::apply() bool pathsChanged = false; m_settingsHandler->setAutomaticKitCreation(m_options.automaticKitCreationEnabled()); - m_options.sdkRepository.expandVariables(); + m_options.sdkRepository.expandVariablesAndWildcards(); QMessageBox warningPopup(QMessageBox::Icon::Warning, Tr::tr("Warning"), diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index d68a8e9ea88..043aad927f3 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -593,7 +593,7 @@ McuSdkRepository targetsFromDescriptions(const QList &desc } McuSdkRepository repo{mcuTargets, mcuPackages}; - repo.expandVariables(); + repo.expandVariablesAndWildcards(); return repo; } diff --git a/src/plugins/mcusupport/mcutargetfactory.cpp b/src/plugins/mcusupport/mcutargetfactory.cpp index 6f5be2a1026..c54a41b4409 100644 --- a/src/plugins/mcusupport/mcutargetfactory.cpp +++ b/src/plugins/mcusupport/mcutargetfactory.cpp @@ -11,7 +11,6 @@ #include "mcutargetdescription.h" #include -#include #include #include diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index 9a2e1153c43..86df7b69d27 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -15,8 +15,9 @@ #include "ghs_tviic2d6m_baremetal_json.h" #include "iar_mimxrt1064_evk_freertos_json.h" #include "iar_stm32f469i_discovery_baremetal_json.h" -#include "msvc_desktop_json.h" #include "mingw_desktop_json.h" +#include "msvc_desktop_json.h" +#include "wildcards_test_kit_json.h" #include "mcuhelpers.h" #include "mcukitmanager.h" @@ -27,6 +28,7 @@ #include "mcusupportsdk.h" #include "mcusupportversiondetection.h" #include "mcutargetdescription.h" +#include "mcutargetfactory.h" #include "mcutargetfactorylegacy.h" #include @@ -44,13 +46,15 @@ #include #include -#include +#include +#include #include #include #include #include +#include #include namespace McuSupport::Internal::Test { @@ -172,6 +176,11 @@ const QString jlinkDetectionPath{HostOsInfo::isWindowsHost() const QString unsupportedToolchainFilePath = QString{qtForMcuSdkPath} + "/lib/cmake/Qul/toolchain/unsupported.cmake"; +// Build/Testing/QtMCUs +const auto testing_output_dir = (FilePath::fromString(QCoreApplication::applicationDirPath()).parentDir() + / "Testing/QtMCUs") + .canonicalPath(); + const QStringList jsonFiles{QString::fromUtf8(armgcc_mimxrt1050_evk_freertos_json), QString::fromUtf8(iar_mimxrt1064_evk_freertos_json)}; @@ -201,7 +210,7 @@ const Id cxxLanguageId{ProjectExplorer::Constants::CXX_LANGUAGE_ID}; //Expand variables in a tested {targets, packages} pair auto expandTargetsAndPackages = [](Targets &targets, Packages &packages) { - McuSdkRepository{targets, packages}.expandVariables(); + McuSdkRepository{targets, packages}.expandVariablesAndWildcards(); }; void verifyIarToolchain(const McuToolChainPackagePtr &iarToolchainPackage) @@ -358,6 +367,30 @@ void verifyPackage(const McuPackagePtr &package, QCOMPARE(package->versions(), versions); } +// create fake files and folders for testing under the "testing_output_dir" folder +bool createFakePath(const FilePath& path, const bool is_file = false) +{ + if (path.exists()) + return true; + + //create an empty file or folder + if (is_file) { + if (!path.parentDir().createDir()) { + qWarning() << "Could not create the parent dir for testing file " << path; + return false; + } + if (!path.writeFileContents("placeholder text")) { + qWarning() << "Could not write to testing file " << path; + return false; + } + } else if (!path.createDir()) { + qWarning() << "Could not create testing dir " << path; + return false; + } + + return true; +}; + McuSupportTest::McuSupportTest() : targetFactory{settingsMockPtr} , compilerDescription{armGccLabel, armGccEnvVar, TOOLCHAIN_DIR_CMAKE_VARIABLE, armGccLabel, armGccDirectorySetting, {}, {}, {}, {}, false} @@ -415,6 +448,15 @@ McuSupportTest::McuSupportTest() testing::FLAGS_gmock_verbose = "error"; } +// load the test file +std::pair McuSupportTest::createTestingKitTargetsAndPackages(QByteArray test_file) +{ + McuTargetFactory factory(settingsMockPtr); + auto [targets, packages] = factory.createTargets(parseDescriptionJson(test_file), sdkPackagePtr); + expandTargetsAndPackages(targets, packages); + return {targets, packages}; +} + void McuSupportTest::initTestCase() { EXPECT_CALL(*freeRtosPackage, environmentVariableName()) @@ -455,6 +497,9 @@ void McuSupportTest::initTestCase() void McuSupportTest::init() { + McuSdkRepository::globalMacros() + ->insert("MCU_TESTING_FOLDER", + [dir = testing_output_dir.absoluteFilePath().toString()] { return dir; }); qDebug() << __func__; } @@ -1650,6 +1695,36 @@ void McuSupportTest::test_addToSystemPathFlag() QCOMPARE(freeRtosPackage.shouldAddToSystemPath, false); } +void McuSupportTest::test_processWildcards_data() +{ + QTest::addColumn("package_label"); + QTest::addColumn("path"); + QTest::addColumn("isFile"); + + QTest::newRow("\"*\" at the end") << "FAKE_WILDCARD_TEST_1" + << "folder-123" << false; + QTest::newRow("\"*\" in the middle") << "FAKE_WILDCARD_TEST_2" + << "file-123.exe" << true; + QTest::newRow("\"*\" at the start") << "FAKE_WILDCARD_TEST_3" + << "123-file.exe" << true; +} + +void McuSupportTest::test_processWildcards() +{ + QFETCH(QString, package_label); + QFETCH(QString, path); + QFETCH(bool, isFile); + + QVERIFY(createFakePath(testing_output_dir / "wildcards" / path, isFile)); + + auto [targets, packages] = createTestingKitTargetsAndPackages(wildcards_test_kit); + auto testWildcardsPackage = findOrDefault(packages, [&](const McuPackagePtr &pkg) { + return (pkg->label() == package_label); + }); + QVERIFY(testWildcardsPackage != nullptr); + QCOMPARE(testWildcardsPackage->path().toString(), FilePath(testing_output_dir / "wildcards" / path).toString()); +} + void McuSupportTest::test_nonemptyVersionDetector() { PackageDescription pkgDesc; diff --git a/src/plugins/mcusupport/test/unittest.h b/src/plugins/mcusupport/test/unittest.h index 50e823d10b2..088bad1475a 100644 --- a/src/plugins/mcusupport/test/unittest.h +++ b/src/plugins/mcusupport/test/unittest.h @@ -22,6 +22,7 @@ class McuSupportTest : public QObject public: McuSupportTest(); + std::pair createTestingKitTargetsAndPackages(QByteArray test_file); private slots: void initTestCase(); @@ -102,6 +103,8 @@ private slots: void test_differentValueForEachOperationSystem(); void test_addToSystemPathFlag(); + void test_processWildcards_data(); + void test_processWildcards(); void test_nonemptyVersionDetector(); void test_emptyVersionDetector(); diff --git a/src/plugins/mcusupport/test/wildcards_test_kit_json.h b/src/plugins/mcusupport/test/wildcards_test_kit_json.h new file mode 100644 index 00000000000..6737c39f56c --- /dev/null +++ b/src/plugins/mcusupport/test/wildcards_test_kit_json.h @@ -0,0 +1,74 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +// This file is intended for testing McuSupport logic by adding fake packages + +#pragma once + +constexpr auto wildcards_test_kit = R"( +{ + "qulVersion": "2.3.0", + "compatVersion": "1", + "platform": { + "id": "fake-platform", + "vendor": "fake-vendor", + "colorDepths": [32], + "cmakeEntries": [ + { + "label": "FAKE_WILDCARD_TEST_1", + "description": "Assert '*' is replaced by possible values", + "defaultValue": "%{MCU_TESTING_FOLDER}/wildcards/folder-*", + "envVar": "", + "type": "path" + }, + { + "label": "FAKE_WILDCARD_TEST_2", + "description": "Assert '*' is replaced by possible values", + "defaultValue": "%{MCU_TESTING_FOLDER}/wildcards/file-*.exe", + "envVar": "", + "type": "path" + }, + { + "label": "FAKE_WILDCARD_TEST_3", + "description": "Assert '*' is replaced by possible values", + "defaultValue": "%{MCU_TESTING_FOLDER}/wildcards/*-file.exe", + "envVar": "", + "type": "path" + } + ] + }, + "toolchain": { + "id": "fake-compiler", + "versions": [ + "0.0.1" + ], + "compiler": { + "cmakeVar": "QUL_TARGET_TOOLCHAIN_DIR", + "setting": "", + "label": "fake compiler", + "type": "path", + "optional": false + }, + "file": { + "cmakeVar": "CMAKE_TOOLCHAIN_FILE", + "type": "file", + "defaultValue": "", + "visible": false, + "optional": false + } + }, + "boardSdk": { + "envVar": "", + "setting": "", + "versions": [ + "0.0.1" + ], + "label": "", + "cmakeVar": "QUL_BOARD_SDK_DIR", + "type": "path", + "defaultValue": "", + "versionDetection": {}, + "optional": false + } +} +)"; From 2c04c644d0b17c5f751f8dc6f0712b452064685c Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 2 Nov 2022 09:33:10 +0100 Subject: [PATCH 92/97] TreeScanner: Pass a copy of filter and factory into async call Otherwise, m_filter and m_factory may be used from 2 threads at the same time, what is not thread safe (setFilter() / setTypeFactory() from caller thread, and copy of m_filter and m_factory inside async call body). Change-Id: Ic322870f9c27de10c5c51082cfbb85c729326993 Reviewed-by: Reviewed-by: Eike Ziller --- src/plugins/projectexplorer/treescanner.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plugins/projectexplorer/treescanner.cpp b/src/plugins/projectexplorer/treescanner.cpp index 6e7e25fe9b0..747a4d1ddcf 100644 --- a/src/plugins/projectexplorer/treescanner.cpp +++ b/src/plugins/projectexplorer/treescanner.cpp @@ -45,8 +45,9 @@ bool TreeScanner::asyncScanForFiles(const Utils::FilePath &directory) if (!m_futureWatcher.isFinished()) return false; - m_scanFuture = Utils::runAsync([this, directory](FutureInterface &fi) { - TreeScanner::scanForFiles(fi, directory, m_filter, m_factory); + m_scanFuture = Utils::runAsync( + [directory, filter = m_filter, factory = m_factory] (FutureInterface &fi) { + TreeScanner::scanForFiles(fi, directory, filter, factory); }); m_futureWatcher.setFuture(m_scanFuture); From 8fa0c2c390cc8dd3afae1bc4e939a653423a6449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sivert=20Kr=C3=B8vel?= Date: Mon, 31 Oct 2022 21:09:19 +0100 Subject: [PATCH 93/97] McuSupport: Implement support for parsing path type from json The json kit files have an entry named "type" which is intended to specify whether a specific path points to a file or a directory (or something else). Until now, this entry has not been handled and all lineEdits expect a path, thus appearing red in the UI if supplied with a file. With this patch, support for the type "file" is added, with the possibility to support further types in parseLineEditType. Currently, only File and ExistingDirectory are supported, with the latter being used by default whenever no "type" entry is specified. Task-number: UL-6610 Change-Id: I252d4eff76d4a11b92ce55a0c0964446072e48c1 Reviewed-by: Daniele Bortolotti Reviewed-by: Reviewed-by: Leena Miettinen Reviewed-by: Eike Ziller --- src/plugins/mcusupport/mcupackage.cpp | 5 ++- src/plugins/mcusupport/mcupackage.h | 27 ++++++++------ src/plugins/mcusupport/mcusupportsdk.cpp | 37 ++++++++++++++++++- src/plugins/mcusupport/mcutargetdescription.h | 3 ++ src/plugins/mcusupport/mcutargetfactory.cpp | 3 +- src/plugins/mcusupport/test/unittest.cpp | 30 +++++++++++---- src/plugins/mcusupport/test/unittest.h | 2 + 7 files changed, 85 insertions(+), 22 deletions(-) diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp index 63e0fb2aadc..f306873f40a 100644 --- a/src/plugins/mcusupport/mcupackage.cpp +++ b/src/plugins/mcusupport/mcupackage.cpp @@ -37,7 +37,8 @@ McuPackage::McuPackage(const SettingsHandler::Ptr &settingsHandler, const QStringList &versions, const QString &downloadUrl, const McuPackageVersionDetector *versionDetector, - const bool addToSystemPath) + const bool addToSystemPath, + const Utils::PathChooser::Kind &valueType) : settingsHandler(settingsHandler) , m_label(label) , m_defaultPath(settingsHandler->getPath(settingsKey, QSettings::SystemScope, defaultPath)) @@ -49,6 +50,7 @@ McuPackage::McuPackage(const SettingsHandler::Ptr &settingsHandler, , m_environmentVariableName(envVarName) , m_downloadUrl(downloadUrl) , m_addToSystemPath(addToSystemPath) + , m_valueType(valueType) { m_path = FilePath::fromUserInput(qtcEnvironmentVariable(m_environmentVariableName)); if (!m_path.exists()) { @@ -245,6 +247,7 @@ QWidget *McuPackage::widget() { auto *widget = new QWidget; m_fileChooser = new PathChooser(widget); + m_fileChooser->setExpectedKind(m_valueType); m_fileChooser->lineEdit()->setButtonIcon(FancyLineEdit::Right, Icons::RESET.icon()); m_fileChooser->lineEdit()->setButtonVisible(FancyLineEdit::Right, true); connect(m_fileChooser->lineEdit(), &FancyLineEdit::rightButtonClicked, this, [&] { diff --git a/src/plugins/mcusupport/mcupackage.h b/src/plugins/mcusupport/mcupackage.h index 7528bba91de..e30364df7a4 100644 --- a/src/plugins/mcusupport/mcupackage.h +++ b/src/plugins/mcusupport/mcupackage.h @@ -8,6 +8,7 @@ #include "settingshandler.h" #include +#include #include @@ -18,7 +19,6 @@ class ToolChain; } namespace Utils { -class PathChooser; class InfoLabel; class Id; } // namespace Utils @@ -30,17 +30,19 @@ class McuPackage : public McuAbstractPackage Q_OBJECT public: - McuPackage(const SettingsHandler::Ptr &settingsHandler, - const QString &label, - const Utils::FilePath &defaultPath, - const Utils::FilePath &detectionPath, - const QString &settingsKey, - const QString &cmakeVarName, - const QString &envVarName, - const QStringList &versions = {}, - const QString &downloadUrl = {}, - const McuPackageVersionDetector *versionDetector = nullptr, - const bool addToPath = false); + McuPackage( + const SettingsHandler::Ptr &settingsHandler, + const QString &label, + const Utils::FilePath &defaultPath, + const Utils::FilePath &detectionPath, + const QString &settingsKey, + const QString &cmakeVarName, + const QString &envVarName, + const QStringList &versions = {}, + const QString &downloadUrl = {}, + const McuPackageVersionDetector *versionDetector = nullptr, + const bool addToPath = false, + const Utils::PathChooser::Kind &valueType = Utils::PathChooser::Kind::ExistingDirectory); ~McuPackage() override = default; @@ -90,6 +92,7 @@ private: const QString m_environmentVariableName; const QString m_downloadUrl; const bool m_addToSystemPath; + const Utils::PathChooser::Kind m_valueType; Status m_status = Status::InvalidPath; }; // class McuPackage diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index 043aad927f3..4ddca854abc 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -9,6 +9,7 @@ #include "mcusupportconstants.h" #include "mcusupportoptions.h" #include "mcusupportplugin.h" +#include "mcusupporttr.h" #include "mcusupportversiondetection.h" #include "mcutarget.h" #include "mcutargetdescription.h" @@ -630,6 +631,39 @@ static VersionDetection parseVersionDetection(const QJsonObject &packageEntry) }; } +static Utils::PathChooser::Kind parseLineEditType(const QJsonValue &type) +{ + //Utility function to handle the different kinds of PathChooser + //Default is ExistingDirectory, see pathchooser.h for more options + const auto defaultValue = Utils::PathChooser::Kind::ExistingDirectory; + if (type.isUndefined()) { + //No "type" entry in the json file, this is not an error + return defaultValue; + } + + const QString typeString = type.toString(); + if (typeString.isNull()) { + printMessage(Tr::tr("Parsing error: the type entry in JSON kit files must be a string, " + "defaulting to \"path\"") + .arg(typeString), + true); + + return defaultValue; + + } else if (typeString.compare("file", Qt::CaseInsensitive) == 0) { + return Utils::PathChooser::File; + } else if (typeString.compare("path", Qt::CaseInsensitive) == 0) { + return Utils::PathChooser::ExistingDirectory; + } else { + printMessage(Tr::tr( + "Parsing error: the type entry \"%2\" in JSON kit files is not supported, " + "defaulting to \"path\"") + .arg(typeString), + true); + + return defaultValue; + } +} static PackageDescription parsePackage(const QJsonObject &cmakeEntry) { @@ -652,7 +686,8 @@ static PackageDescription parsePackage(const QJsonObject &cmakeEntry) FilePath::fromUserInput(detectionPathString), versions, parseVersionDetection(cmakeEntry), - cmakeEntry["addToSystemPath"].toBool()}; + cmakeEntry["addToSystemPath"].toBool(), + parseLineEditType(cmakeEntry["type"])}; } static QList parsePackages(const QJsonArray &cmakeEntries) diff --git a/src/plugins/mcusupport/mcutargetdescription.h b/src/plugins/mcusupport/mcutargetdescription.h index 3c8600b6604..c1cc87d6d92 100644 --- a/src/plugins/mcusupport/mcutargetdescription.h +++ b/src/plugins/mcusupport/mcutargetdescription.h @@ -4,6 +4,8 @@ #pragma once #include +#include + #include #include #include @@ -32,6 +34,7 @@ struct PackageDescription QStringList versions; VersionDetection versionDetection; bool shouldAddToSystemPath; + Utils::PathChooser::Kind type; }; //struct PackageDescription struct McuTargetDescription diff --git a/src/plugins/mcusupport/mcutargetfactory.cpp b/src/plugins/mcusupport/mcutargetfactory.cpp index c54a41b4409..f7105c36f5a 100644 --- a/src/plugins/mcusupport/mcutargetfactory.cpp +++ b/src/plugins/mcusupport/mcutargetfactory.cpp @@ -131,7 +131,8 @@ McuPackagePtr McuTargetFactory::createPackage(const PackageDescription &pkgDesc) pkgDesc.versions, {}, createVersionDetection(pkgDesc.versionDetection), - pkgDesc.shouldAddToSystemPath}}; + pkgDesc.shouldAddToSystemPath, + pkgDesc.type}}; } McuToolChainPackage *McuTargetFactory::createToolchain( diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index 86df7b69d27..b6fe45d2aeb 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -197,7 +197,8 @@ const PackageDescription Legacy::Constants::QT_FOR_MCUS_SDK_PACKAGE_VALIDATION_PATH, {}, VersionDetection{}, - false}; + false, + Utils::PathChooser::Kind::ExistingDirectory}; const McuTargetDescription::Platform platformDescription{id, "", @@ -393,8 +394,8 @@ bool createFakePath(const FilePath& path, const bool is_file = false) McuSupportTest::McuSupportTest() : targetFactory{settingsMockPtr} - , compilerDescription{armGccLabel, armGccEnvVar, TOOLCHAIN_DIR_CMAKE_VARIABLE, armGccLabel, armGccDirectorySetting, {}, {}, {}, {}, false} - , toochainFileDescription{armGccLabel, armGccEnvVar, TOOLCHAIN_FILE_CMAKE_VARIABLE, armGccLabel, armGccDirectorySetting, {}, {}, {}, {}, false} + , compilerDescription{armGccLabel, armGccEnvVar, TOOLCHAIN_DIR_CMAKE_VARIABLE, armGccLabel, armGccDirectorySetting, {}, {}, {}, {}, false, Utils::PathChooser::Kind::ExistingDirectory } + , toochainFileDescription{armGccLabel, armGccEnvVar, TOOLCHAIN_FILE_CMAKE_VARIABLE, armGccLabel, armGccDirectorySetting, {}, {}, {}, {}, false, Utils::PathChooser::Kind::ExistingDirectory } , targetDescription { "autotest-sourceFile", "2.0.1", @@ -751,7 +752,8 @@ void McuSupportTest::test_createTargets() freeRtosDetectionPath, {}, VersionDetection{}, - true}; + true, + Utils::PathChooser::Kind::ExistingDirectory}; targetDescription.toolchain.id = armGcc; auto [targets, packages]{targetFactory.createTargets(targetDescription, sdkPackagePtr)}; @@ -803,7 +805,8 @@ void McuSupportTest::test_createPackages() freeRtosDetectionPath, {}, VersionDetection{}, - true}; + true, + Utils::PathChooser::Kind::ExistingDirectory}; const auto packages{targetFactory.createPackages(targetDescription)}; QVERIFY(!packages.empty()); @@ -848,7 +851,8 @@ void McuSupportTest::test_useFallbackPathForToolchainWhenPathFromSettingsIsNotAv {}, {}, VersionDetection{}, - false}; + false, + Utils::PathChooser::Kind::ExistingDirectory}; McuTargetDescription::Toolchain toolchainDescription{armGcc, {}, compilerDescription, {}}; EXPECT_CALL(*settingsMockPtr, getPath(QString{armGccDirectorySetting}, _, FilePath{fallbackDir})) @@ -871,7 +875,8 @@ void McuSupportTest::test_usePathFromSettingsForToolchainPath() {}, {}, VersionDetection{}, - false}; + false, + Utils::PathChooser::Kind::ExistingDirectory}; McuTargetDescription::Toolchain toolchainDescription{armGcc, {}, compilerDescription, {}}; EXPECT_CALL(*settingsMockPtr, getPath(QString{armGccDirectorySetting}, _, FilePath{empty})) @@ -1788,5 +1793,16 @@ void McuSupportTest::test_emptyVersionDetectorFromJson() QVERIFY(freeRtos->getVersionDetector() == nullptr); } +void McuSupportTest::test_expectedValueType() +{ + const auto targetDescription = parseDescriptionJson(armgcc_mimxrt1050_evk_freertos_json); + + QCOMPARE(targetDescription.toolchain.file.type, Utils::PathChooser::Kind::File); + QCOMPARE(targetDescription.toolchain.compiler.type, Utils::PathChooser::Kind::ExistingDirectory); + QCOMPARE(targetDescription.boardSdk.type, Utils::PathChooser::Kind::ExistingDirectory); + QCOMPARE(targetDescription.freeRTOS.package.type, Utils::PathChooser::Kind::ExistingDirectory); + QCOMPARE(targetDescription.platform.entries[0].type, + Utils::PathChooser::Kind::ExistingDirectory); +} } // namespace McuSupport::Internal::Test diff --git a/src/plugins/mcusupport/test/unittest.h b/src/plugins/mcusupport/test/unittest.h index 088bad1475a..5d424fd02bc 100644 --- a/src/plugins/mcusupport/test/unittest.h +++ b/src/plugins/mcusupport/test/unittest.h @@ -110,6 +110,8 @@ private slots: void test_emptyVersionDetector(); void test_emptyVersionDetectorFromJson(); + void test_expectedValueType(); + private: QVersionNumber currentQulVersion{2, 0}; PackageMock *freeRtosPackage{new PackageMock}; From 3bfebea9813a4d0a6e90ea18ff8d0756ae7a1f27 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 2 Nov 2022 15:06:36 +0100 Subject: [PATCH 94/97] LocatorWidget: Don't leak m_centeredPopupAction Amends d3354d1999923fe1711286b19d94420fb8769b68 Change-Id: I9cd308c83300928e8dafade291ee4559f885ab5f Reviewed-by: Eike Ziller --- src/plugins/coreplugin/locator/locatorwidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/coreplugin/locator/locatorwidget.cpp b/src/plugins/coreplugin/locator/locatorwidget.cpp index 08835179fac..6b0cec28da9 100644 --- a/src/plugins/coreplugin/locator/locatorwidget.cpp +++ b/src/plugins/coreplugin/locator/locatorwidget.cpp @@ -561,7 +561,7 @@ bool CompletionList::eventFilter(QObject *watched, QEvent *event) LocatorWidget::LocatorWidget(Locator *locator) : m_locatorModel(new LocatorModel(this)) , m_filterMenu(new QMenu(this)) - , m_centeredPopupAction(new QAction(tr("Open as Centered Popup"))) + , m_centeredPopupAction(new QAction(tr("Open as Centered Popup"), this)) , m_refreshAction(new QAction(tr("Refresh"), this)) , m_configureAction(new QAction(ICore::msgShowOptionsDialog(), this)) , m_fileLineEdit(new Utils::FancyLineEdit) From e7b1561cc7081dcd7c3311fead494a0ab7b8e176 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 2 Nov 2022 15:31:09 +0100 Subject: [PATCH 95/97] CorePlugin: Don't leak actions for options Amends d86a67e0bc2624e7a4357860439a13bf1b565951 Change-Id: I45703f4fbc018f1f30375e578aa6c55815db902b Reviewed-by: Eike Ziller --- src/plugins/coreplugin/coreplugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp index 7f1b170a957..bd5a65cc97b 100644 --- a/src/plugins/coreplugin/coreplugin.cpp +++ b/src/plugins/coreplugin/coreplugin.cpp @@ -258,12 +258,12 @@ static void registerActionsForOptions() categoryDisplay[page->category()] = page->displayCategory(); } for (IOptionsPage *page : IOptionsPage::allOptionsPages()) { - Id commandId = generateOpenPageCommandId(page); + const Id commandId = generateOpenPageCommandId(page); if (!commandId.isValid()) continue; const QString actionTitle = Tr::tr("%1 > %2 Preferences...") .arg(categoryDisplay.value(page->category()), page->displayName()); - auto action = new QAction(actionTitle); + auto action = new QAction(actionTitle, m_instance); QObject::connect(action, &QAction::triggered, m_instance, [id = page->id()]() { ICore::showOptionsDialog(id); }); From 0d1e1ebab692fba92bdf3a4e678f57cd915763a2 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Fri, 14 Oct 2022 10:56:47 +0200 Subject: [PATCH 96/97] CorePlugin: Do not check recent files for existence Previously recent files would be restored before devices were intialized. Remote paths would therefore be removed since their existence could not be verified. Change-Id: I0412cec9587fd104580a694f20bdd0ec54e35b3e Reviewed-by: Reviewed-by: Eike Ziller --- src/plugins/coreplugin/documentmanager.cpp | 36 +++++++++++++--------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp index 48c2227a3b1..bceee3b1a20 100644 --- a/src/plugins/coreplugin/documentmanager.cpp +++ b/src/plugins/coreplugin/documentmanager.cpp @@ -1376,6 +1376,21 @@ void DocumentManager::saveSettings() s->endGroup(); } +void restoreRecentFiles(const QVariantList &recentFiles, const QStringList &recentEditorIds) +{ + QList result; + + for (int i = 0, n = recentFiles.size(); i < n; ++i) { + QString editorId; + if (i < recentEditorIds.size()) // guard against old or weird settings + editorId = recentEditorIds.at(i); + const Utils::FilePath &filePath = FilePath::fromVariant(recentFiles.at(i)); + result.append({filePath, Id::fromString(editorId)}); + } + + d->m_recentFiles = result; +} + void readSettings() { QSettings *s = ICore::settings(); @@ -1384,23 +1399,14 @@ void readSettings() const QVariantList recentFiles = s->value(QLatin1String(filesKeyC)).toList(); const QStringList recentEditorIds = s->value(QLatin1String(editorsKeyC)).toStringList(); s->endGroup(); - // clean non-existing files - for (int i = 0, n = recentFiles.size(); i < n; ++i) { - QString editorId; - if (i < recentEditorIds.size()) // guard against old or weird settings - editorId = recentEditorIds.at(i); - const Utils::FilePath &filePath = FilePath::fromVariant(recentFiles.at(i)); - if (filePath.exists() && !filePath.isDir()) - d->m_recentFiles.append({filePath, Id::fromString(editorId)}); - } + + restoreRecentFiles(recentFiles, recentEditorIds); s->beginGroup(QLatin1String(directoryGroupC)); - const FilePath settingsProjectDir = FilePath::fromString(s->value(QLatin1String(projectDirectoryKeyC), - QString()).toString()); - if (!settingsProjectDir.isEmpty() && settingsProjectDir.isDir()) - d->m_projectsDirectory = settingsProjectDir; - else - d->m_projectsDirectory = PathChooser::homePath(); + + d->m_projectsDirectory = FilePath::fromVariant( + s->value(QLatin1String(projectDirectoryKeyC), PathChooser::homePath().toVariant())); + d->m_useProjectsDirectory = s->value(QLatin1String(useProjectDirectoryKeyC), kUseProjectsDirectoryDefault).toBool(); From 8de9892c4e877ea7b46940bfc25f203e789de994 Mon Sep 17 00:00:00 2001 From: Daniele Bortolotti Date: Wed, 2 Nov 2022 16:41:59 +0100 Subject: [PATCH 97/97] McuSupport: Improve message box warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The message box might show up when applying changes in other settings pages if the user left the Devices > MCU tab with invalid fields. Improve the warning message with settings page and target name. Change-Id: I335fadd3b5d4c6be10c6bd5100d6aac3c50017f2 Reviewed-by: Leena Miettinen Reviewed-by: Sivert Krøvel Reviewed-by: Eike Ziller --- src/plugins/mcusupport/mcusupportoptionspage.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/plugins/mcusupport/mcusupportoptionspage.cpp b/src/plugins/mcusupport/mcusupportoptionspage.cpp index f317026c07f..7f594d03e0c 100644 --- a/src/plugins/mcusupport/mcusupportoptionspage.cpp +++ b/src/plugins/mcusupport/mcusupportoptionspage.cpp @@ -293,7 +293,7 @@ void McuSupportOptionsWidget::apply() QMessageBox warningPopup(QMessageBox::Icon::Warning, Tr::tr("Warning"), - Tr::tr("Unable to apply changes."), + Tr::tr("Unable to apply changes in Devices > MCU."), QMessageBox::Ok, this); @@ -304,7 +304,9 @@ void McuSupportOptionsWidget::apply() return; } if (!target->isValid()) { - warningPopup.setInformativeText(Tr::tr("Invalid path(s) present.")); + warningPopup.setInformativeText( + Tr::tr("Invalid paths present for target\n%1") + .arg(McuKitManager::generateKitNameFromTarget(target.get()))); warningPopup.exec(); return; }