diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index 1ae02e38c84..41b7669f56f 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -34,7 +34,13 @@ if (WIN32 AND TARGET clangTooling) llvm::cl::OptionCategory CheckToolCategory("check tool options"); int main(int argc, const char **argv) { - CommonOptionsParser OptionsParser(argc, argv, CheckToolCategory); + class Parser : public CommonOptionsParser { + public: + Parser(int &argc, const char **argv, llvm::cl::OptionCategory &Category) : + CommonOptionsParser(argc, argv, Category) {} + }; + + Parser OptionsParser(argc, argv, CheckToolCategory); ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); return 0; diff --git a/doc/qtdesignstudio/images/studio-3d-area-light.png b/doc/qtdesignstudio/images/studio-3d-area-light.png index d31661e9923..24fbfcbe33e 100644 Binary files a/doc/qtdesignstudio/images/studio-3d-area-light.png and b/doc/qtdesignstudio/images/studio-3d-area-light.png differ diff --git a/doc/qtdesignstudio/images/studio-3d-directional-light.png b/doc/qtdesignstudio/images/studio-3d-directional-light.png index e43f6ec5412..f739e5bba42 100644 Binary files a/doc/qtdesignstudio/images/studio-3d-directional-light.png and b/doc/qtdesignstudio/images/studio-3d-directional-light.png differ diff --git a/doc/qtdesignstudio/images/studio-3d-point-light.png b/doc/qtdesignstudio/images/studio-3d-point-light.png index ac3b7f51f94..a5eb5a888ac 100644 Binary files a/doc/qtdesignstudio/images/studio-3d-point-light.png and b/doc/qtdesignstudio/images/studio-3d-point-light.png differ diff --git a/doc/qtdesignstudio/images/studio-3d-spot-light.png b/doc/qtdesignstudio/images/studio-3d-spot-light.png index cc678a801da..7ebc673e186 100644 Binary files a/doc/qtdesignstudio/images/studio-3d-spot-light.png and b/doc/qtdesignstudio/images/studio-3d-spot-light.png differ diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc index 2e3195ed726..239a168970f 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-lights.qdoc @@ -44,38 +44,75 @@ \uicontrol {Qt Quick 3D} module to your project as instructed in \l {Adding and Removing Modules}. + \note If you select \uicontrol {Qt 5} as the \uicontrol {Target Qt Version} + when \l {Creating Projects}{creating your project}, the available light + components and their properties will be slightly different. The properties + may also be situated differently in the \uicontrol Properties view. + By default, all imported scenes are created with one directional light. You can use the following components to add lights: - \list + \table + \header + \li Icon + \li Name + \li Qt 5 Only + \li More Information + + \row + \li \inlineimage spot.png + \li Directional Light + \li \li \l{DirectionalLight}{Light Directional} + + \row + \li \inlineimage point.png + \li Point Light + \li \li \l{PointLight}{Light Point} + + \row + \li \inlineimage spot.png + \li Spot Light + \li \li \l{SpotLight}{Light Spot} + + \row + \li \inlineimage area.png + \li Area Light + \li \inlineimage ok.png \li \l{AreaLight}{Light Area} - \endlist + \endtable \note Each additional light negatively effects the rendering performance of your scene. Keep scenes as simple as possible and use lights sparingly. Use a \l{SceneEnvironment}{Scene Environment} component to apply image-based lighting that can produce soft and subtle lighting. - You can edit light properties in the \uicontrol Properties view. The - \uicontrol Scope property specifies which node, with it's children, - is illuminated by a light. + To edit light properties, select a light component in \uicontrol Navigator, + or \uicontrol {3D Editor}, and then adjust its properties in the + \uicontrol Properties view or by dragging the yellow light gizmo handles in + \uicontrol {3D Editor}. - Set the \uicontrol {Color} property to specify the color applied to models + To specify an overall multiplier for a light component's effects, adjust the + \uicontrol Brightness property. The \uicontrol Scope property specifies which + component, with its children, is illuminated by the light. Set the + \l{Picking Colors}{Color} property to specify the color applied to models illuminated by a light. Set the \uicontrol {Ambient color} property to specify the ambient color applied to materials before being illuminated by the light. - You can animate light properties in the \uicontrol Timeline view. + You can animate light properties in the \l Timeline view. \section1 Directional Light - A directional light emits light in one direction from a unidentifiable + A directional light emits light in one direction from an unidentifiable source located infinitely far away. This is similar to sunlight. - \image studio-3d-directional-light.png "Models lit by a dirctional light" + Use the \uicontrol Brightness handle of the light gizmo (1) to adjust the + \uicontrol Brightness property of any of the light components. + + \image studio-3d-directional-light.png "Models lit by a directional light." If the \uicontrol {Casts shadow} property is enabled, shadows are positioned parallel to the light direction. A directional light has infinite range and @@ -96,20 +133,17 @@ \section1 Point Light - A point light can be described as a sphere, emitting light with equal + A point light can be described as a sphere that emits light with equal strength in all directions from the center of the light. This is similar to the way a light bulb emits light. - \image studio-3d-point-light.png "Models lit by a point light" + \image studio-3d-point-light.png "Models lit by a point light." Lighting is applied outwards from the center of a point light, becoming increasingly dim away from the center. Moving a point light changes the position from where the light is emitted. Rotating or scaling a point light does not have any effect. - To specify an overall multiplier for a point light's effects, set the - \uicontrol Brightness property. - To control the fade-off and range of a point light, set the \uicontrol {Constant fade}, \uicontrol {Linear fade}, and \uicontrol {Quadratic fade} properties. Constant fade is the constant @@ -125,7 +159,8 @@ dims on surfaces that are far away from the light. The value 1.0 means that the point light fade exactly follows the inverse square law. For example, when the distance to a component doubles, the light intensity decreases to - one fourth. + one fourth. Adjust the \uicontrol {Quadratic fade} in the Properties view, + or by using the light gizmo handle (2). Aside from fade, a point light has the same properties as a directional light. @@ -136,7 +171,13 @@ The light intensity diminishes when approaching the value of the \uicontrol {Cone angle} property. The angle at which the light intensity starts to diminish is defined by the - \uicontrol {Inner cone angle} property. Both angles are defined in degrees. + \uicontrol {Inner cone angle} property. Both angles are defined in degrees + in the \uicontrol Properties view. Use the Properties view or the light gizmo + handles to adjust the \uicontrol {Cone angle} (3), + \uicontrol {Inner cone angle} (4), and \uicontrol {Quadratic fade} (5) + properties. + + \image studio-3d-spot-light.png "A model lit by a spot light." Inside the inner cone angle, the spot light behaves similarly to the point light. There the light intensity diminishes according to inverse-square-law. @@ -144,15 +185,17 @@ \uicontrol {Constant fade}, \uicontrol {Linear fade}, and \uicontrol {Quadratic fade} properties. - \image studio-3d-spot-light.png - \section1 Area Light + \note The \uicontrol {Area Light} component is only available in Qt 5. + An area light is similar to the directional light. However, instead of emitting an equally bright light across the whole scene, the area light - emits directional light from a rectangle shaped component. You can set the - \uicontrol Width and \uicontrol Height properties to determine the size - of the area light. + emits directional light from a rectangle shaped component. Use the light + gizmo or the \uicontrol Properties view to set the \uicontrol Width (6) + and \uicontrol Height (7) properties to determine the size of the area light. + + \image studio-3d-area-light.png "A model lit by two area lights." Aside from the size, an area light has the same properties as a directional light. @@ -160,8 +203,6 @@ The image below shows an example on how to light a component with different colors using two different area lights. - \image studio-3d-area-light.png - You can rotate, scale, and move area lights. \section1 Shadows diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml index 88774a1b434..1a2775e8f1b 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemDelegate.qml @@ -41,7 +41,7 @@ Item { anchors.topMargin: 1 anchors.fill: parent - color: StudioTheme.Values.themePanelBackground + color: mouseRegion.containsMouse ? StudioTheme.Values.themeControlBackgroundHover : StudioTheme.Values.themePanelBackground Image { id: itemIcon // to be set by model diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml index 79ab72f1233..de9d50f0429 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/ItemsView.qml @@ -73,7 +73,7 @@ itemLibraryModel [ ] */ -ScrollView { +Item { id: itemsView property string importToRemove: "" @@ -81,6 +81,11 @@ ScrollView { property var currentItem: null property var currentCategory: null property var currentImport: null + property bool isHorizontalView: false + + // horizontal component lib variables + property var selectedCategory: null + property var selectedCategoryImport: null // called from C++ to close context menu on focus out function closeContextMenu() @@ -91,15 +96,21 @@ ScrollView { function showImportCategories() { - currentImport.importCatVisibleState = true + if (itemLibraryModel.isAllCategoriesHidden()) { + itemsView.currentImport.importCatVisibleState = true + if (!itemLibraryModel.getIsAnyCategoryHidden()) + itemLibraryModel.isAnyCategoryHidden = false + + itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory() + } + + itemsView.currentImport.importCatVisibleState = true if (!itemLibraryModel.getIsAnyCategoryHidden()) itemLibraryModel.isAnyCategoryHidden = false } - onContentHeightChanged: { - var maxPosition = Math.max(contentHeight - height, 0) - if (contentY > maxPosition) - contentY = maxPosition + onWidthChanged: { + itemsView.isHorizontalView = itemsView.width > widthLimit } Item { @@ -112,66 +123,68 @@ ScrollView { property int cellVerticalMargin: 4 // the following depend on the actual shape of the item delegate - property int cellWidth: textWidth + 2 * cellHorizontalMargin - property int cellHeight: itemLibraryIconHeight + textHeight + - 2 * cellVerticalMargin + cellVerticalSpacing + property int cellWidth: styleConstants.textWidth + 2 * styleConstants.cellHorizontalMargin + property int cellHeight: itemLibraryIconHeight + styleConstants.textHeight + + 2 * styleConstants.cellVerticalMargin + styleConstants.cellVerticalSpacing StudioControls.Menu { id: moduleContextMenu StudioControls.MenuItem { text: qsTr("Remove Module") - visible: currentCategory === null + visible: itemsView.currentCategory === null height: visible ? implicitHeight : 0 - enabled: importToRemove !== "" + enabled: itemsView.importToRemove !== "" onTriggered: { showImportCategories() - rootView.removeImport(importToRemove) + rootView.removeImport(itemsView.importToRemove) } } StudioControls.MenuSeparator { - visible: currentCategory === null + visible: itemsView.currentCategory === null height: StudioTheme.Values.border } StudioControls.MenuItem { text: qsTr("Expand All") - visible: currentCategory === null + visible: itemsView.currentCategory === null height: visible ? implicitHeight : 0 onTriggered: itemLibraryModel.expandAll() } StudioControls.MenuItem { text: qsTr("Collapse All") - visible: currentCategory === null + visible: itemsView.currentCategory === null height: visible ? implicitHeight : 0 onTriggered: itemLibraryModel.collapseAll() } StudioControls.MenuSeparator { - visible: currentCategory === null + visible: itemsView.currentCategory === null height: StudioTheme.Values.border } StudioControls.MenuItem { text: qsTr("Hide Category") - visible: currentCategory + visible: itemsView.currentCategory height: visible ? implicitHeight : 0 onTriggered: { itemLibraryModel.isAnyCategoryHidden = true - currentCategory.categoryVisible = false + itemsView.currentCategory.categoryVisible = false + itemsView.currentCategory.categorySelected = false + itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory() } } StudioControls.MenuSeparator { - visible: currentCategory + visible: itemsView.currentCategory height: StudioTheme.Values.border } StudioControls.MenuItem { text: qsTr("Show Module Hidden Categories") - enabled: currentImport && !currentImport.importCatVisibleState + enabled: itemsView.currentImport && !itemsView.currentImport.importCatVisibleState onTriggered: showImportCategories() } @@ -179,6 +192,12 @@ ScrollView { text: qsTr("Show All Hidden Categories") enabled: itemLibraryModel.isAnyCategoryHidden onTriggered: { + if (itemLibraryModel.isAllCategoriesHidden()) { + itemLibraryModel.showHiddenCategories() + itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory() + itemLibraryModel.isAnyCategoryHidden = false + } + itemLibraryModel.isAnyCategoryHidden = false itemLibraryModel.showHiddenCategories() } @@ -192,94 +211,117 @@ ScrollView { StudioControls.MenuItem { id: importMenuItem - text: qsTr("Add Module: ") + importToAdd - enabled: importToAdd !== "" - onTriggered: rootView.addImportForItem(importToAdd) + text: qsTr("Add Module: ") + itemsView.importToAdd + enabled: itemsView.importToAdd !== "" + onTriggered: rootView.addImportForItem(itemsView.importToAdd) } } } - Column { - spacing: 2 - Repeater { - model: itemLibraryModel // to be set in Qml context - delegate: Section { - width: itemsView.width - - (itemsView.verticalScrollBarVisible ? itemsView.verticalThickness : 0) - caption: importName - visible: importVisible - sectionHeight: 30 - sectionFontSize: 15 - showArrow: categoryModel.rowCount() > 0 - labelColor: importUnimported ? StudioTheme.Values.themeUnimportedModuleColor - : StudioTheme.Values.themeTextColor - leftPadding: 0 - rightPadding: 0 - expanded: importExpanded - expandOnClick: false - useDefaulContextMenu: false + Loader { + anchors.fill: parent + sourceComponent: itemsView.isHorizontalView ? horizontalView : verticalView + } - onToggleExpand: { - if (categoryModel.rowCount() > 0) - importExpanded = !importExpanded - } - onShowContextMenu: { - importToRemove = importRemovable ? importUrl : "" - currentImport = model - currentCategory = null - if (!rootView.isSearchActive()) - moduleContextMenu.popup() - } + Component { + id: verticalView - Column { - spacing: 2 - property var currentImportModel: model // allows accessing the import model from inside the category section - Repeater { - model: categoryModel - delegate: Section { - width: itemsView.width - - (itemsView.verticalScrollBarVisible ? itemsView.verticalThickness : 0) - sectionBackgroundColor: "transparent" - showTopSeparator: index > 0 - hideHeader: categoryModel.rowCount() <= 1 - leftPadding: 0 - rightPadding: 0 - addTopPadding: categoryModel.rowCount() > 1 - addBottomPadding: index != categoryModel.rowCount() - 1 - caption: categoryName + " (" + itemModel.rowCount() + ")" - visible: categoryVisible - expanded: categoryExpanded - expandOnClick: false - onToggleExpand: categoryExpanded = !categoryExpanded - onShowContextMenu: { - currentCategory = model - currentImport = parent.currentImportModel - if (!rootView.isSearchActive()) - moduleContextMenu.popup() - } + ScrollView { + id: verticalScrollView + width: itemsView.width + height: itemsView.height + onContentHeightChanged: { + var maxPosition = Math.max(contentHeight - verticalScrollView.height, 0) + if (contentY > maxPosition) + contentY = maxPosition + } - Grid { - id: itemGrid + Column { + spacing: 2 + Repeater { + model: itemLibraryModel // to be set in Qml context + delegate: Section { + width: itemsView.width - + (verticalScrollView.verticalScrollBarVisible + ? verticalScrollView.verticalThickness : 0) + caption: importName + visible: importVisible + sectionHeight: 30 + sectionFontSize: 15 + showArrow: categoryModel.rowCount() > 0 + labelColor: importUnimported ? StudioTheme.Values.themeUnimportedModuleColor + : StudioTheme.Values.themeTextColor + leftPadding: 0 + rightPadding: 0 + expanded: importExpanded + expandOnClick: false + useDefaulContextMenu: false + onToggleExpand: { + if (categoryModel.rowCount() > 0) + importExpanded = !importExpanded + } + onShowContextMenu: { + itemsView.importToRemove = importRemovable ? importUrl : "" + itemsView.currentImport = model + itemsView.currentCategory = null + if (!rootView.isSearchActive()) + moduleContextMenu.popup() + } - property real actualWidth: parent.width - itemGrid.leftPadding -itemGrid.rightPadding - property int flexibleWidth: (itemGrid.actualWidth / columns) - styleConstants.cellWidth + Column { + spacing: 2 + property var currentImportModel: model // allows accessing the import model from inside the category section + Repeater { + model: categoryModel + delegate: Section { + width: itemsView.width - + (verticalScrollView.verticalScrollBarVisible + ? verticalScrollView.verticalThickness : 0) + sectionBackgroundColor: "transparent" + showTopSeparator: index > 0 + hideHeader: categoryModel.rowCount() <= 1 + leftPadding: 0 + rightPadding: 0 + addTopPadding: categoryModel.rowCount() > 1 + addBottomPadding: index !== categoryModel.rowCount() - 1 + caption: categoryName + " (" + itemModel.rowCount() + ")" + visible: categoryVisible + expanded: categoryExpanded + expandOnClick: false + onToggleExpand: categoryExpanded = !categoryExpanded + useDefaulContextMenu: false + onShowContextMenu: { + itemsView.currentCategory = model + itemsView.currentImport = parent.currentImportModel + if (!rootView.isSearchActive()) + moduleContextMenu.popup() + } - leftPadding: 6 - rightPadding: 6 - columns: itemGrid.actualWidth / styleConstants.cellWidth + Grid { + id: itemGrid - Repeater { - model: itemModel - delegate: ItemDelegate { - visible: itemVisible - textColor: importUnimported ? StudioTheme.Values.themeUnimportedModuleColor - : StudioTheme.Values.themeTextColor - width: styleConstants.cellWidth + itemGrid.flexibleWidth - height: styleConstants.cellHeight - onShowContextMenu: { - if (!itemUsable) { - importToAdd = itemRequiredImport - itemContextMenu.popup() + property real actualWidth: parent.width - itemGrid.leftPadding -itemGrid.rightPadding + property int flexibleWidth: (itemGrid.actualWidth / columns) - styleConstants.cellWidth + + leftPadding: 6 + rightPadding: 6 + columns: itemGrid.actualWidth / styleConstants.cellWidth + rowSpacing: 7 + + Repeater { + model: itemModel + delegate: ItemDelegate { + visible: itemVisible + textColor: importUnimported ? StudioTheme.Values.themeUnimportedModuleColor + : StudioTheme.Values.themeTextColor + width: styleConstants.cellWidth + itemGrid.flexibleWidth + height: styleConstants.cellHeight + onShowContextMenu: { + if (!itemUsable) { + itemsView.importToAdd = itemRequiredImport + itemContextMenu.popup() + } + } } } } @@ -291,4 +333,163 @@ ScrollView { } } } + + Component { + id: horizontalView + + Row { + padding: 5 + + ScrollView { + id: horizontalScrollView + width: 270 + height: itemsView.height + onContentHeightChanged: { + var maxPosition = Math.max(contentHeight - horizontalScrollView.height, 0) + if (contentY > maxPosition) + contentY = maxPosition + } + + Column { + width: parent.width + spacing: 2 + Repeater { + model: itemLibraryModel // to be set in Qml context + delegate: Section { + width: 265 - + (horizontalScrollView.verticalScrollBarVisible + ? horizontalScrollView.verticalThickness : 0) + caption: importName + visible: importVisible + sectionHeight: 30 + sectionFontSize: 15 + showArrow: categoryModel.rowCount() > 0 + labelColor: importUnimported ? StudioTheme.Values.themeUnimportedModuleColor + : StudioTheme.Values.themeTextColor + leftPadding: 0 + rightPadding: 0 + expanded: importExpanded + expandOnClick: false + useDefaulContextMenu: false + onToggleExpand: { + if (categoryModel.rowCount() > 0) + importExpanded = !importExpanded + } + onShowContextMenu: { + itemsView.importToRemove = importRemovable ? importUrl : "" + itemsView.currentImport = model + itemsView.currentCategory = null + if (!rootView.isSearchActive()) + moduleContextMenu.popup() + } + + Column { + spacing: 2 + property var currentImportModel: model // allows accessing the import model from inside the category section + Repeater { + model: categoryModel + delegate: Rectangle { + width: 265 - + (horizontalScrollView.verticalScrollBarVisible + ? horizontalScrollView.verticalThickness : 0) + height: 25 + visible: categoryVisible + border.width: StudioTheme.Values.border + border.color: StudioTheme.Values.themeControlOutline + color: categorySelected + ? StudioTheme.Values.themeControlBackgroundHover + : categoryMouseArea.containsMouse ? Qt.darker(StudioTheme.Values.themeControlBackgroundHover, 1.5) + : StudioTheme.Values.themeControlBackground + + Text { + anchors.fill: parent + text: categoryName + color: StudioTheme.Values.themeTextColor + font.pixelSize: 13 + font.capitalization: Font.AllUppercase + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + MouseArea { + id: categoryMouseArea + anchors.fill: parent + hoverEnabled: true + acceptedButtons: Qt.LeftButton | Qt.RightButton + + onClicked: (mouse) => { + itemLibraryModel.selectImportCategory(parent.parent.currentImportModel.importUrl, model.index) + itemsView.selectedCategory = model + itemsView.selectedCategoryImport = parent.parent.currentImportModel + + if (mouse.button === Qt.RightButton && !rootView.isSearchActive() && categoryModel.rowCount() !== 1) { + itemsView.currentCategory = model + itemsView.currentImport = parent.parent.currentImportModel + moduleContextMenu.popup() + } + } + Component.onCompleted: { + if (categorySelected) + categorySelected = !categorySelected + itemsView.selectedCategory = itemLibraryModel.selectImportFirstVisibleCategory() + if (itemsView.selectedCategory === categorySelected) + itemsView.selectedCategoryImport = itemsView.selectedCategory.parent.currentImportModel + } + } + } + } + } + } + } + } + } + + Rectangle { // separator between import/category column and item grid + id: separatingLine + height: itemsView.height - 10 + width: 1 + color: StudioTheme.Values.themeControlOutline + } + + ScrollView { + id: itemScrollView + width: itemsView.width - 275 + height: itemsView.height + onContentHeightChanged: { + var maxPosition = Math.max(contentHeight - itemScrollView.height, 0) + if (contentY > maxPosition) + contentY = maxPosition + } + + Grid { + id: hItemGrid + property real actualWidth: itemsView.width - 294 + property int flexibleWidth: (hItemGrid.actualWidth / hItemGrid.columns) - styleConstants.cellWidth + + leftPadding: 9 + rightPadding: 9 + bottomPadding: 15 + columns: hItemGrid.actualWidth / styleConstants.cellWidth + rowSpacing: 7 + + Repeater { + model: itemsView.selectedCategory ? itemsView.selectedCategory.itemModel : null + delegate: ItemDelegate { + visible: itemVisible + textColor: itemsView.selectedCategoryImport && itemsView.selectedCategoryImport.importUnimported + ? StudioTheme.Values.themeUnimportedModuleColor : StudioTheme.Values.themeTextColor + width: styleConstants.cellWidth + hItemGrid.flexibleWidth + height: styleConstants.cellHeight + onShowContextMenu: { + if (!itemUsable) { + itemsView.importToAdd = itemRequiredImport + itemContextMenu.popup() + } + } + } + } + } + } + } + } } diff --git a/src/libs/languageserverprotocol/clientcapabilities.h b/src/libs/languageserverprotocol/clientcapabilities.h index 147483c5042..c0bdae40319 100644 --- a/src/libs/languageserverprotocol/clientcapabilities.h +++ b/src/libs/languageserverprotocol/clientcapabilities.h @@ -336,6 +336,12 @@ public: Utils::optional> documentationFormat() const; void setDocumentationFormat(const QList &documentationFormat); void clearDocumentationFormat() { remove(documentationFormatKey); } + + Utils::optional activeParameterSupport() const + { return optionalValue(activeParameterSupportKey); } + void setActiveParameterSupport(bool activeParameterSupport) + { insert(activeParameterSupportKey, activeParameterSupport); } + void clearActiveParameterSupport() { remove(activeParameterSupportKey); } }; // The client supports the following `SignatureInformation` specific properties. diff --git a/src/libs/languageserverprotocol/jsonkeys.h b/src/libs/languageserverprotocol/jsonkeys.h index b0109c11349..fa0e5d63e01 100644 --- a/src/libs/languageserverprotocol/jsonkeys.h +++ b/src/libs/languageserverprotocol/jsonkeys.h @@ -29,6 +29,7 @@ namespace LanguageServerProtocol { constexpr char actionsKey[] = "actions"; constexpr char activeParameterKey[] = "activeParameter"; +constexpr char activeParameterSupportKey[] = "activeParameterSupport"; constexpr char activeSignatureKey[] = "activeSignature"; constexpr char addedKey[] = "added"; constexpr char additionalTextEditsKey[] = "additionalTextEdits"; diff --git a/src/libs/languageserverprotocol/languagefeatures.h b/src/libs/languageserverprotocol/languagefeatures.h index fc8df0bc716..ade9507d0b6 100644 --- a/src/libs/languageserverprotocol/languagefeatures.h +++ b/src/libs/languageserverprotocol/languagefeatures.h @@ -145,6 +145,10 @@ public: void setParameters(const QList ¶meters) { insertArray(parametersKey, parameters); } void clearParameters() { remove(parametersKey); } + + Utils::optional activeParameter() const { return optionalValue(activeParameterKey); } + void setActiveParameter(int activeParameter) { insert(activeParameterKey, activeParameter); } + void clearActiveParameter() { remove(activeParameterKey); } }; /** diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp index 2d8e1b641d7..6a6c9d8e91d 100644 --- a/src/libs/utils/aspects.cpp +++ b/src/libs/utils/aspects.cpp @@ -1181,7 +1181,7 @@ void StringAspect::setVolatileValue(const QVariant &val) switch (d->m_displayStyle) { case PathChooserDisplay: if (d->m_pathChooserDisplay) - d->m_pathChooserDisplay->setPath(val.toString()); + d->m_pathChooserDisplay->setFilePath(FilePath::fromVariant(val)); break; case LineEditDisplay: if (d->m_lineEditDisplay) diff --git a/src/libs/utils/commandline.cpp b/src/libs/utils/commandline.cpp index 409c85f04da..ecea6934cfb 100644 --- a/src/libs/utils/commandline.cpp +++ b/src/libs/utils/commandline.cpp @@ -647,8 +647,10 @@ void ProcessArgs::addArgs(QString *args, const QStringList &inArgs) bool ProcessArgs::prepareCommand(const CommandLine &cmdLine, QString *outCmd, ProcessArgs *outArgs, const Environment *env, const FilePath *pwd) { - const FilePath executable = cmdLine.executable(); + FilePath executable = cmdLine.executable(); const QString arguments = cmdLine.arguments(); + if (env && executable.isRelativePath()) + executable = env->searchInPath(executable.toString()); ProcessArgs::SplitError err; *outArgs = ProcessArgs::prepareArgs(arguments, &err, executable.osType(), env, pwd); if (err == ProcessArgs::SplitOk) { diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index 3b099e422e4..3602a6c304f 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -616,7 +616,7 @@ bool FilePath::isWritableFile() const return s_deviceHooks.isWritableFile(*this); } const QFileInfo fi{m_data}; - return fi.exists() && fi.isWritable() && !fi.isDir(); + return fi.isWritable() && !fi.isDir(); } bool FilePath::ensureWritableDir() const @@ -626,7 +626,7 @@ bool FilePath::ensureWritableDir() const return s_deviceHooks.ensureWritableDir(*this); } const QFileInfo fi{m_data}; - if (exists() && fi.isDir() && fi.isWritable()) + if (fi.isDir() && fi.isWritable()) return true; return QDir().mkpath(m_data); } @@ -652,7 +652,7 @@ bool FilePath::isExecutableFile() const return s_deviceHooks.isExecutableFile(*this); } const QFileInfo fi{m_data}; - return fi.exists() && fi.isExecutable() && !fi.isDir(); + return fi.isExecutable() && !fi.isDir(); } bool FilePath::isReadableFile() const @@ -662,7 +662,7 @@ bool FilePath::isReadableFile() const return s_deviceHooks.isReadableFile(*this); } const QFileInfo fi{m_data}; - return fi.exists() && fi.isReadable() && !fi.isDir(); + return fi.isReadable() && !fi.isDir(); } bool FilePath::isReadableDir() const @@ -672,7 +672,7 @@ bool FilePath::isReadableDir() const return s_deviceHooks.isReadableDir(*this); } const QFileInfo fi{m_data}; - return fi.exists() && fi.isReadable() && fi.isDir(); + return fi.isReadable() && fi.isDir(); } bool FilePath::isFile() const @@ -682,7 +682,7 @@ bool FilePath::isFile() const return s_deviceHooks.isFile(*this); } const QFileInfo fi{m_data}; - return fi.exists() && fi.isFile(); + return fi.isFile(); } bool FilePath::isDir() const @@ -692,7 +692,7 @@ bool FilePath::isDir() const return s_deviceHooks.isDir(*this); } const QFileInfo fi{m_data}; - return fi.exists() && fi.isDir(); + return fi.isDir(); } bool FilePath::createDir() const diff --git a/src/libs/utils/projectintropage.cpp b/src/libs/utils/projectintropage.cpp index 1a318df0d4c..6e180496375 100644 --- a/src/libs/utils/projectintropage.cpp +++ b/src/libs/utils/projectintropage.cpp @@ -195,6 +195,11 @@ bool ProjectIntroPage::validate() return false; } +void ProjectIntroPage::fieldsUpdated() +{ + slotChanged(); +} + void ProjectIntroPage::slotChanged() { const bool newComplete = validate(); @@ -286,6 +291,8 @@ void ProjectIntroPage::displayStatusMessage(InfoLabel::InfoType t, const QString { d->m_ui.stateLabel->setType(t); d->m_ui.stateLabel->setText(s); + + emit statusMessageChanged(t, s); } void ProjectIntroPage::hideStatusLabel() diff --git a/src/libs/utils/projectintropage.h b/src/libs/utils/projectintropage.h index 5de165efe11..0bccd91f2b1 100644 --- a/src/libs/utils/projectintropage.h +++ b/src/libs/utils/projectintropage.h @@ -66,8 +66,14 @@ public: bool validateProjectName(const QString &name, QString *errorMessage); + // Calls slotChanged() - i.e. tell the page that some of its fields have been updated. + // This function is useful if you programmatically update the fields of the page (i.e. from + // your client code). + void fieldsUpdated(); + signals: void activated(); + void statusMessageChanged(InfoLabel::InfoType type, const QString &message); public slots: void setFilePath(const FilePath &path); diff --git a/src/libs/utils/textutils.cpp b/src/libs/utils/textutils.cpp index 3b475aef3cd..4e0764fffb7 100644 --- a/src/libs/utils/textutils.cpp +++ b/src/libs/utils/textutils.cpp @@ -88,9 +88,9 @@ QTextCursor selectAt(QTextCursor textCursor, int line, int column, uint length) if (column < 1) column = 1; - const int anchorPosition = positionInText(textCursor.document(), line, column + length); + const int anchorPosition = positionInText(textCursor.document(), line, column); textCursor.setPosition(anchorPosition); - textCursor.setPosition(anchorPosition - length, QTextCursor::KeepAnchor); + textCursor.setPosition(anchorPosition + int(length), QTextCursor::KeepAnchor); return textCursor; } diff --git a/src/plugins/android/androidqmlpreviewworker.cpp b/src/plugins/android/androidqmlpreviewworker.cpp index 645cabbb48a..3c2adca5727 100644 --- a/src/plugins/android/androidqmlpreviewworker.cpp +++ b/src/plugins/android/androidqmlpreviewworker.cpp @@ -23,12 +23,13 @@ ** ****************************************************************************/ +#include "androidqmlpreviewworker.h" + #include "androidavdmanager.h" #include "androiddevice.h" #include "androiddeviceinfo.h" #include "androidglobal.h" #include "androidmanager.h" -#include "androidqmlpreviewworker.h" #include @@ -44,10 +45,11 @@ #include #include +#include + +#include +#include #include -#include -#include -#include namespace Android { namespace Internal { @@ -80,173 +82,143 @@ ApkInfo::ApkInfo() : Q_GLOBAL_STATIC(ApkInfo, apkInfo) -const char packageSuffix[] = ".qmlrc"; +static const char packageSuffix[] = ".qmlrc"; -static inline bool isMainThread() +FilePath AndroidQmlPreviewWorker::designViewerApkPath(const QString &abi) const { - return QCoreApplication::instance()->thread() == QThread::currentThread(); -} - -static FilePath viewerApkPath(const QString &avdAbi) -{ - if (avdAbi.isEmpty()) + if (abi.isEmpty()) return {}; - if (apkInfo()->abis.contains(avdAbi)) - return Core::ICore::resourcePath(QString("android/qtdesignviewer/designviewer_%1.apk"). - arg(avdAbi)); + if (apkInfo()->abis.contains(abi)) { + return Core::ICore::resourcePath(QString("android/qtdesignviewer/designviewer_%1.apk") + .arg(abi)); + } return {}; } -static SdkToolResult runAdbCommandAsyncAndWait(const QString &dev, const QStringList &arguments) +SdkToolResult AndroidQmlPreviewWorker::runAdbCommand(const QStringList &arguments) const { QStringList args; - if (!dev.isEmpty()) - args << AndroidDeviceInfo::adbSelector(dev); - args << arguments; - QFuture asyncResult = QtConcurrent::run([args] { - return AndroidManager::runAdbCommand(args);}); - - while (asyncResult.isRunning()) { - QCoreApplication::instance()->processEvents(QEventLoop::AllEvents, 100); - } - return asyncResult.result(); -} - -static SdkToolResult runAdbCommand(const QString &dev, const QStringList &arguments) -{ - if (isMainThread()) - return runAdbCommandAsyncAndWait(dev, arguments); - QStringList args; - if (!dev.isEmpty()) - args << AndroidDeviceInfo::adbSelector(dev); + if (!m_serialNumber.isEmpty()) + args << AndroidDeviceInfo::adbSelector(m_serialNumber); args << arguments; return AndroidManager::runAdbCommand(args); } -static SdkToolResult runAdbShellCommand(const QString &dev, const QStringList &arguments) +SdkToolResult AndroidQmlPreviewWorker::runAdbShellCommand(const QStringList &arguments) const { - const QStringList shellCmd{"shell"}; - return runAdbCommand(dev, shellCmd + arguments); + return runAdbCommand(QStringList() << "shell" << arguments); } -static QString startAvd(const AndroidAvdManager &avd, const QString &name) -{ - QFuture asyncRes = QtConcurrent::run([avd, name] { - return avd.startAvd(name); - }); - while (asyncRes.isRunning()) - QCoreApplication::instance()->processEvents(QEventLoop::AllEvents, 100); - return asyncRes.result(); -} - -static int pidofPreview(const QString &dev) +int AndroidQmlPreviewWorker::pidofPreview() const { const QStringList command{"pidof", apkInfo()->appId}; - const SdkToolResult res = runAdbShellCommand(dev, command); + const SdkToolResult res = runAdbShellCommand(command); return res.success() ? res.stdOut().toInt() : -1; } -static bool isPreviewRunning(const QString &dev, int lastKnownPid = -1) +bool AndroidQmlPreviewWorker::isPreviewRunning(int lastKnownPid) const { - const int pid = pidofPreview(dev); + const int pid = pidofPreview(); return (lastKnownPid > 1) ? lastKnownPid == pid : pid > 1; } -AndroidQmlPreviewWorker::AndroidQmlPreviewWorker(ProjectExplorer::RunControl *runControl) - : ProjectExplorer::RunWorker(runControl) - , m_rc(runControl) - , m_config(AndroidConfigurations::currentConfig()) +void AndroidQmlPreviewWorker::startPidWatcher() { -} - -QStringList filterAppLog(const QStringList& oldList, const QStringList& newList) -{ - QStringList list = Utils::filtered(newList, - [](const auto & arg){return arg.contains(apkInfo()->name);}); - for (const auto &oldEntry : oldList) { - list.removeAll(oldEntry); - } - return list; -} - -void AndroidQmlPreviewWorker::start() -{ - UploadInfo transfer; - const bool res = ensureAvdIsRunning() - && checkAndInstallPreviewApp() - && prepareUpload(transfer) - && uploadFiles(transfer) - && runPreviewApp(transfer); - - if (!res) { - reportFailure(); - return; - } - reportStarted(); - //Thread to monitor preview life - QtConcurrent::run([this]() { - QElapsedTimer timer; - timer.start(); - while (runControl() && runControl()->isRunning()) { + m_pidFutureWatcher.setFuture(Utils::runAsync([this]() { + // wait for started + const int sleepTimeMs = 2000; + QDeadlineTimer deadline(20000); + while (!m_pidFutureWatcher.isCanceled() && !deadline.hasExpired()) { if (m_viewerPid == -1) { - m_viewerPid = pidofPreview(m_devInfo.serialNumber); - if (m_viewerPid > 0) - QMetaObject::invokeMethod(this, &AndroidQmlPreviewWorker::startLogcat); - } else if (timer.elapsed() > 2000) { - //Get the application output - if (!isPreviewRunning(m_devInfo.serialNumber, m_viewerPid)) - QMetaObject::invokeMethod(this, &AndroidQmlPreviewWorker::stop); - - timer.restart(); + m_viewerPid = pidofPreview(); + if (m_viewerPid > 0) { + emit previewPidChanged(); + break; + } } - QThread::msleep(100); + QThread::msleep(sleepTimeMs); } - }); + + while (!m_pidFutureWatcher.isCanceled()) { + if (!isPreviewRunning(m_viewerPid)) { + stop(); + break; + } + QThread::msleep(sleepTimeMs); + } + })); } void AndroidQmlPreviewWorker::startLogcat() { - QtConcurrent::run([this]() { - QElapsedTimer timer; - timer.start(); - int initialPid = m_viewerPid; // to check if our initial process is still alive - QStringList logLines; - auto appendLogLinesCall = [&logLines, this](){ appendLogLines(logLines); }; - auto runCondition = [this, initialPid](){ return (runControl() && runControl()->isRunning()) - && initialPid == m_viewerPid;}; - QString timeFilter; - while (runCondition()) { - if (timer.elapsed() > 2000) { - //Get the application output - QStringList logcatCmd = {"logcat", QString("--pid=%1").arg(initialPid), "-t"}; - if (!timeFilter.isEmpty()) - logcatCmd.append(QString("%1").arg(timeFilter)); - else - logcatCmd.append(QString("1000")); //show last 1000 lines (but for the 1st time) + QString args = QString("logcat --pid=%1").arg(m_viewerPid); + if (!m_logcatStartTimeStamp.isEmpty()) + args += QString(" -T '%1'").arg(m_logcatStartTimeStamp); + Utils::CommandLine cmd(AndroidConfigurations::currentConfig().adbToolPath()); + cmd.setArguments(args); + m_logcatProcess.setCommand(cmd); + m_logcatProcess.setUseCtrlCStub(true); + m_logcatProcess.start(); +} - const SdkToolResult logcatResult = runAdbCommand(m_devInfo.serialNumber, logcatCmd); - if (runCondition()) { - const QStringList output = logcatResult.stdOut().split('\n'); - const QStringList filtered = filterAppLog(logLines, output); +void AndroidQmlPreviewWorker::filterLogcatAndAppendMessage(const QString &stdOut) +{ + for (const QString &line : stdOut.split('\n')) { + QStringList splittedLine = line.split(QLatin1String("%1: ").arg(apkInfo()->name)); + if (splittedLine.count() == 1) + continue; - if (!filtered.isEmpty()){ - const QString lastLine = filtered.last(); - timeFilter = lastLine.left(lastLine.indexOf(" ", lastLine.indexOf(" ") + 1)); - QMetaObject::invokeMethod(this, appendLogLinesCall); - logLines = filtered; - } - } - timer.restart(); - } - QThread::msleep(100); - } + const QString outLine = splittedLine.last(); + const QString firstPart = splittedLine.first(); + if (firstPart.contains(" I ") || firstPart.contains(" D ")) + appendMessage(outLine, NormalMessageFormat); + else + appendMessage(outLine, ErrorMessageFormat); + } +} + +AndroidQmlPreviewWorker::AndroidQmlPreviewWorker(ProjectExplorer::RunControl *runControl) + : ProjectExplorer::RunWorker(runControl), + m_rc(runControl), + m_androidConfig(AndroidConfigurations::currentConfig()) +{ + connect(this, &RunWorker::started, this, &AndroidQmlPreviewWorker::startPidWatcher); + connect(this, &RunWorker::stopped, &m_pidFutureWatcher, &QFutureWatcher::cancel); + connect(this, &AndroidQmlPreviewWorker::previewPidChanged, + this, &AndroidQmlPreviewWorker::startLogcat); + + connect(this, &RunWorker::stopped, &m_logcatProcess, &Utils::QtcProcess::stopProcess); + m_logcatProcess.setStdOutCallback([this](const QString &stdOut) { + filterLogcatAndAppendMessage(stdOut); }); } +AndroidQmlPreviewWorker::~AndroidQmlPreviewWorker() +{ + m_pidFutureWatcher.cancel(); + m_pidFutureWatcher.waitForFinished(); +} + +void AndroidQmlPreviewWorker::start() +{ + const SdkToolResult dateResult = runAdbCommand({"shell", "date", "+%s"}); + if (dateResult.success()) { + m_logcatStartTimeStamp = QDateTime::fromSecsSinceEpoch(dateResult.stdOut().toInt()) + .toString("MM-dd hh:mm:ss.mmm"); + } + const bool previewStarted = ensureAvdIsRunning() + && checkAndInstallPreviewApp() + && uploadPreviewArtefacts() + && preparePreviewArtefacts() + && startPreviewApp(); + + previewStarted ? reportStarted() : reportStopped(); +} + void AndroidQmlPreviewWorker::stop() { - if (!isPreviewRunning(m_devInfo.serialNumber, m_viewerPid) || stopPreviewApp()) + if (!isPreviewRunning(m_viewerPid) || stopPreviewApp()) appendMessage(tr("%1 has been stopped.").arg(apkInfo()->name), NormalMessageFormat); m_viewerPid = -1; reportStopped(); @@ -254,28 +226,35 @@ void AndroidQmlPreviewWorker::stop() bool AndroidQmlPreviewWorker::ensureAvdIsRunning() { - AndroidAvdManager avdMan(m_config); + AndroidAvdManager avdMananager(m_androidConfig); QString devSN = AndroidManager::deviceSerialNumber(m_rc->target()); if (devSN.isEmpty()) - devSN = m_devInfo.serialNumber; + devSN = m_serialNumber; - if (!avdMan.isAvdBooted(devSN)) { - m_devInfo = {}; + if (!avdMananager.isAvdBooted(devSN)) { using namespace ProjectExplorer; const IDevice *dev = DeviceKitAspect::device(m_rc->target()->kit()).data(); + if (!dev) { + appendMessage(tr("Selected device is invalid."), ErrorMessageFormat); + return false; + } + if (dev->deviceState() == IDevice::DeviceDisconnected) { + appendMessage(tr("Selected device is disconnected."), ErrorMessageFormat); + return false; + } AndroidDeviceInfo devInfoLocal = AndroidDevice::androidDeviceInfoFromIDevice(dev); if (devInfoLocal.isValid()) { - if (devInfoLocal.type == AndroidDeviceInfo::Emulator) { + if (dev->machineType() == IDevice::Emulator) { appendMessage(tr("Launching AVD."), NormalMessageFormat); - devInfoLocal.serialNumber = startAvd(avdMan, devInfoLocal.avdname); + devInfoLocal.serialNumber = avdMananager.startAvd(devInfoLocal.avdname); } if (devInfoLocal.serialNumber.isEmpty()) { - appendMessage(tr("Could not run AVD."), ErrorMessageFormat); + appendMessage(tr("Could not start AVD."), ErrorMessageFormat); } else { - m_devInfo = devInfoLocal; - m_avdAbis = m_config.getAbis(m_config.adbToolPath(), m_devInfo.serialNumber); + m_serialNumber = devInfoLocal.serialNumber; + m_avdAbis = m_androidConfig.getAbis(m_androidConfig.adbToolPath(), m_serialNumber); } return !devInfoLocal.serialNumber.isEmpty(); } else { @@ -283,7 +262,7 @@ bool AndroidQmlPreviewWorker::ensureAvdIsRunning() } return false; } - m_avdAbis = m_config.getAbis(m_config.adbToolPath(), m_devInfo.serialNumber); + m_avdAbis = m_androidConfig.getAbis(m_androidConfig.adbToolPath(), m_serialNumber); return true; } @@ -291,7 +270,7 @@ bool AndroidQmlPreviewWorker::checkAndInstallPreviewApp() { const QStringList command {"pm", "list", "packages", apkInfo()->appId}; appendMessage(tr("Checking if %1 app is installed.").arg(apkInfo()->name), NormalMessageFormat); - const SdkToolResult res = runAdbShellCommand(m_devInfo.serialNumber, command); + const SdkToolResult res = runAdbShellCommand(command); if (!res.success()) { appendMessage(res.stdErr(), ErrorMessageFormat); return false; @@ -303,7 +282,7 @@ bool AndroidQmlPreviewWorker::checkAndInstallPreviewApp() ErrorMessageFormat); return false; } - const FilePath apkPath = viewerApkPath(m_avdAbis.first()); + const FilePath apkPath = designViewerApkPath(m_avdAbis.first()); if (!apkPath.exists()) { appendMessage(tr("Cannot install %1 app for %2 architecture. " "The appropriate APK was not found in resources folders."). @@ -313,32 +292,29 @@ bool AndroidQmlPreviewWorker::checkAndInstallPreviewApp() appendMessage(tr("Installing %1 APK.").arg(apkInfo()->name), NormalMessageFormat); - - const SdkToolResult res = runAdbCommand(m_devInfo.serialNumber, {"install", - apkPath.toString()}); - if (!res.success()) { + const SdkToolResult res = runAdbCommand({"install", apkPath.toString()}); + if (!res.success()) appendMessage(res.stdErr(), StdErrFormat); - - return false; - } } - return true; + + return res.success(); } -bool AndroidQmlPreviewWorker::prepareUpload(UploadInfo &transfer) +bool AndroidQmlPreviewWorker::preparePreviewArtefacts() { if (m_rc->project()->id() == QmlProjectManager::Constants::QML_PROJECT_ID) { const auto bs = m_rc->target()->buildSystem(); if (bs) { - transfer.uploadPackage = FilePath::fromString( + m_uploadInfo.uploadPackage = FilePath::fromString( bs->additionalData(QmlProjectManager::Constants::mainFilePath).toString()); - transfer.projectFolder = bs->projectDirectory(); + m_uploadInfo.projectFolder = bs->projectDirectory(); return true; } } else { const FilePaths allFiles = m_rc->project()->files(m_rc->project()->SourceFiles); const FilePaths filesToExport = Utils::filtered(allFiles,[](const FilePath &path) { - return path.suffix() == "qmlproject";}); + return path.suffix() == "qmlproject"; + }); if (filesToExport.size() > 1) { appendMessage(tr("Too many .qmlproject files in your project. Open directly the " @@ -348,10 +324,9 @@ bool AndroidQmlPreviewWorker::prepareUpload(UploadInfo &transfer) appendMessage(tr("No .qmlproject file found among project files."), ErrorMessageFormat); } else { const FilePath qmlprojectFile = filesToExport.first(); - transfer.uploadPackage = transfer. - projectFolder. - resolvePath(qmlprojectFile.fileName()); - transfer.projectFolder = qmlprojectFile.parentDir(); + m_uploadInfo.uploadPackage = m_uploadInfo.projectFolder.resolvePath( + qmlprojectFile.fileName()); + m_uploadInfo.projectFolder = qmlprojectFile.parentDir(); return true; } } @@ -366,16 +341,15 @@ FilePath AndroidQmlPreviewWorker::createQmlrcFile(const FilePath &workFolder, const FilePath rccBinary = qtVersion->rccFilePath(); QtcProcess rccProcess; FilePath qrcPath = FilePath::fromString(basename) + ".qrc4viewer"; - const FilePath qmlrcPath = FilePath::fromString(QDir::tempPath() + "/" + basename + - packageSuffix); + const FilePath qmlrcPath = FilePath::fromString(QDir::tempPath()) / basename + packageSuffix; rccProcess.setWorkingDirectory(workFolder); const QStringList arguments[2] = {{"--project", "--output", qrcPath.fileName()}, {"--binary", "--output", qmlrcPath.path(), qrcPath.fileName()}}; - for (const auto &arguments : arguments) { - rccProcess.setCommand({rccBinary, arguments}); + for (const QStringList &args : arguments) { + rccProcess.setCommand({rccBinary, args}); rccProcess.start(); if (!rccProcess.waitForStarted()) { appendMessage(tr("Could not create file for %1 \"%2\""). @@ -420,71 +394,54 @@ FilePath AndroidQmlPreviewWorker::createQmlrcFile(const FilePath &workFolder, return qmlrcPath; } -bool AndroidQmlPreviewWorker::uploadFiles(const UploadInfo &transfer) +bool AndroidQmlPreviewWorker::uploadPreviewArtefacts() { appendMessage(tr("Uploading files."), NormalMessageFormat); - - const FilePath qresPath = createQmlrcFile(FilePath::fromString(transfer.projectFolder.path()), - transfer.uploadPackage.baseName()); + const FilePath qresPath = createQmlrcFile(m_uploadInfo.projectFolder, + m_uploadInfo.uploadPackage.baseName()); if (!qresPath.exists()) return false; - runAdbShellCommand(m_devInfo.serialNumber, {"mkdir", "-p", apkInfo()->uploadDir}); - - const SdkToolResult res = runAdbCommand(m_devInfo.serialNumber, - {"push", qresPath.resolvePath(QString()).toString(), - apkInfo()->uploadDir}); + runAdbShellCommand({"mkdir", "-p", apkInfo()->uploadDir}); + const SdkToolResult res = runAdbCommand({"push", qresPath.resolvePath(QString()).toString(), + apkInfo()->uploadDir}); if (!res.success()) { appendMessage(res.stdOut(), ErrorMessageFormat); - if (res.stdOut().contains("Permission denied")) + if (res.stdOut().contains("Permission denied")) { appendMessage("'Permission denied' error detected. Try restarting your device " "and then running the preview.", NormalMessageFormat); + } } qresPath.removeFile(); return res.success(); } -bool AndroidQmlPreviewWorker::runPreviewApp(const UploadInfo &transfer) +bool AndroidQmlPreviewWorker::startPreviewApp() { stopPreviewApp(); appendMessage(tr("Starting %1.").arg(apkInfo()->name), NormalMessageFormat); const QDir destDir(apkInfo()->uploadDir); + const QString qmlrcPath = destDir.filePath(m_uploadInfo.uploadPackage.baseName() + + packageSuffix); const QStringList command{"am", "start", "-n", apkInfo()->activityId, - "-e", "extraappparams", - QString::fromLatin1( - destDir.filePath(transfer.uploadPackage.baseName() + packageSuffix). - toUtf8(). - toBase64())}; - const SdkToolResult res = runAdbShellCommand(m_devInfo.serialNumber, command); - if (!res.success()) { - appendMessage(res.stdErr(), ErrorMessageFormat); - return res.success(); - } - appendMessage(tr("%1 is running.").arg(apkInfo()->name), NormalMessageFormat); - m_viewerPid = pidofPreview(m_devInfo.serialNumber); - return true; + "-e", "extraappparams", QLatin1String(qmlrcPath.toUtf8().toBase64())}; + const SdkToolResult result = runAdbShellCommand(command); + if (result.success()) + appendMessage(tr("%1 is running.").arg(apkInfo()->name), NormalMessageFormat); + else + appendMessage(result.stdErr(), ErrorMessageFormat); + + return result.success(); } bool AndroidQmlPreviewWorker::stopPreviewApp() { const QStringList command{"am", "force-stop", apkInfo()->appId}; - const SdkToolResult res = runAdbShellCommand(m_devInfo.serialNumber, command); - if (!res.success()) { + const SdkToolResult res = runAdbShellCommand(command); + if (!res.success()) appendMessage(res.stdErr(), ErrorMessageFormat); - return res.success(); - } - return true; -} - -void AndroidQmlPreviewWorker::appendLogLines(const QStringList & lines) -{ - for (const QString& line : lines) { - const int charsToSkip = apkInfo()->name.length() + 2; // strlen(": ") == 2 - const QString formatted = line.mid(line.indexOf(apkInfo()->name) + charsToSkip); - // TODO: See AndroidRunnerWorker::logcatProcess() - filtering for logs to decide format. - appendMessage(formatted, StdOutFormat); - } + return res.success(); } } // namespace Internal diff --git a/src/plugins/android/androidqmlpreviewworker.h b/src/plugins/android/androidqmlpreviewworker.h index e014107df54..c837570e01f 100644 --- a/src/plugins/android/androidqmlpreviewworker.h +++ b/src/plugins/android/androidqmlpreviewworker.h @@ -25,9 +25,12 @@ #pragma once #include "androidconfigurations.h" + #include #include +#include + namespace Android { class SdkToolResult; @@ -45,6 +48,10 @@ class AndroidQmlPreviewWorker : public ProjectExplorer::RunWorker Q_OBJECT public: AndroidQmlPreviewWorker(ProjectExplorer::RunControl *runControl); + ~AndroidQmlPreviewWorker(); + +signals: + void previewPidChanged(); private: void start() override; @@ -52,22 +59,33 @@ private: bool ensureAvdIsRunning(); bool checkAndInstallPreviewApp(); - bool prepareUpload(UploadInfo &transfer); - bool uploadFiles(const UploadInfo &transfer); + bool preparePreviewArtefacts(); + bool uploadPreviewArtefacts(); - bool runPreviewApp(const UploadInfo &transfer); + SdkToolResult runAdbCommand(const QStringList &arguments) const; + SdkToolResult runAdbShellCommand(const QStringList &arguments) const; + int pidofPreview() const; + bool isPreviewRunning(int lastKnownPid = -1) const; + + void startPidWatcher(); + void startLogcat(); + void filterLogcatAndAppendMessage(const QString &stdOut); + + bool startPreviewApp(); bool stopPreviewApp(); - void startLogcat(); - void appendLogLines(const QStringList &lines); - + Utils::FilePath designViewerApkPath(const QString &abi) const; Utils::FilePath createQmlrcFile(const Utils::FilePath &workFolder, const QString &basename); ProjectExplorer::RunControl *m_rc = nullptr; - AndroidConfig m_config; - AndroidDeviceInfo m_devInfo; + AndroidConfig m_androidConfig; + QString m_serialNumber; QStringList m_avdAbis; int m_viewerPid = -1; + QFutureWatcher m_pidFutureWatcher; + Utils::QtcProcess m_logcatProcess; + QString m_logcatStartTimeStamp; + UploadInfo m_uploadInfo; }; } // namespace Internal diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp index 7d01bd14401..0a54774d3ee 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp @@ -123,7 +123,7 @@ void DeviceSelectorDetailsPanel::refresh() m_memoryView->refresh(); m_algorithmView->refresh(); m_algorithmView->setAlgorithm(m_selection.algorithmIndex); - m_peripheralDescriptionFileChooser->setPath(m_selection.svd); + m_peripheralDescriptionFileChooser->setFilePath(Utils::FilePath::fromString(m_selection.svd)); } // DeviceSelector diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index 6103fada825..7a6c1045ec3 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -2616,7 +2616,9 @@ static void semanticHighlighter(QFutureInterface &future, } else if (token.type == "type") { styles.mainStyle = C_TYPE; } else if (token.type == "typeParameter") { - styles.mainStyle = C_TYPE; + // clangd reports both type and non-type template parameters as type parameters, + // but the latter can be distinguished by the readonly modifier. + styles.mainStyle = token.modifiers.contains("readonly") ? C_PARAMETER : C_TYPE; } if (token.modifiers.contains("declaration")) styles.mixinStyles.push_back(C_DECLARATION); diff --git a/src/plugins/clangcodemodel/test/clangdtests.cpp b/src/plugins/clangcodemodel/test/clangdtests.cpp index c71bd2d3644..20938701157 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.cpp +++ b/src/plugins/clangcodemodel/test/clangdtests.cpp @@ -506,9 +506,6 @@ void ClangdTestLocalReferences::test() client()->findLocalUsages(doc, cursor, std::move(handler)); timer.start(10000); loop.exec(); - QEXPECT_FAIL("cursor not on identifier", "clangd bug: go to definition does not return", Abort); - QEXPECT_FAIL("template parameter member access", - "clangd bug: go to definition does not return", Abort); QVERIFY(timer.isActive()); timer.stop(); @@ -909,7 +906,7 @@ void ClangdTestHighlighting::test_data() QTest::newRow("template parameter default argument") << 265 << 41 << 265 << 44 << QList{C_TYPE} << 0; QTest::newRow("template non-type parameter") << 265 << 50 << 265 << 74 - << QList{C_LOCAL, C_DECLARATION} << 0; + << QList{C_PARAMETER, C_DECLARATION} << 0; QTest::newRow("template non-type parameter default argument") << 265 << 77 << 265 << 78 << QList{C_NUMBER} << 0; QTest::newRow("template template parameter") << 265 << 103 << 265 << 128 @@ -935,7 +932,7 @@ void ClangdTestHighlighting::test_data() QTest::newRow("local var declaration of template parameter type") << 268 << 27 << 268 << 57 << QList{C_LOCAL, C_DECLARATION} << 0; QTest::newRow("reference to non-type template parameter") << 269 << 46 << 269 << 70 - << QList{C_LOCAL} << 0; + << QList{C_PARAMETER} << 0; QTest::newRow("local var declaration initialized with non-type template parameter") << 269 << 10 << 269 << 43 << QList{C_LOCAL, C_DECLARATION} << 0; @@ -1331,12 +1328,6 @@ void ClangdTestHighlighting::test() QEXPECT_FAIL("non-final virtual function call via pointer", "clangd < 14 does not send virtual modifier", Continue); } - QEXPECT_FAIL("template non-type parameter", - "FIXME: clangd reports non-type template parameters at \"typeParameter\"", - Continue); - QEXPECT_FAIL("reference to non-type template parameter", - "FIXME: clangd reports non-type template parameters at \"typeParameter\"", - Continue); QEXPECT_FAIL("non-const reference via member function call as output argument (function)", "Without punctuation and comment tokens from clangd, it's not possible " "to highlight entire expressions. But do we really want this? What about nested " @@ -1627,7 +1618,7 @@ void ClangdTestCompletion::testFunctionHintsFiltered() QVERIFY(proposal); QCOMPARE(proposal->size(), 2); QVERIFY(hasItem(proposal, "func(const S &s, int j) -> void")); - QEXPECT_FAIL("", "FIXME: LanguageClient handles active parameter only in active signature", Abort); + QEXPECT_FAIL("", "QTCREATORBUG-26346", Abort); QVERIFY(hasItem(proposal, "func(const S &s, int j, int k) -> void")); } @@ -1640,7 +1631,7 @@ void ClangdTestCompletion::testFunctionHintConstructor() QVERIFY(!hasItem(proposal, "globalVariable")); QVERIFY(!hasItem(proposal, " class")); QVERIFY(hasItem(proposal, "Foo(int)")); - QEXPECT_FAIL("", "FIXME: LanguageClient handles active parameter only in active signature", Abort); + QEXPECT_FAIL("", "QTCREATORBUG-26346", Abort); QVERIFY(hasItem(proposal, "Foo(int, double)")); } @@ -1669,8 +1660,7 @@ void ClangdTestCompletion::testCompletePrivateFunctionDefinition() getProposal("privateFuncDefCompletion.cpp", proposal); QVERIFY(proposal); - QEXPECT_FAIL("", "FIXME: clangd needs to differentiate " - "between function call and function definiton", Abort); + QEXPECT_FAIL("", "https://github.com/clangd/clangd/issues/880", Abort); QCOMPARE(proposal->size(), 1); QVERIFY(hasItem(proposal, " theFunc()")); } diff --git a/src/plugins/clearcase/settingspage.cpp b/src/plugins/clearcase/settingspage.cpp index a8b808980dd..11ff5b8d9cf 100644 --- a/src/plugins/clearcase/settingspage.cpp +++ b/src/plugins/clearcase/settingspage.cpp @@ -67,7 +67,7 @@ SettingsPageWidget::SettingsPageWidget() const ClearCaseSettings &s = ClearCasePlugin::settings(); - m_ui.commandPathChooser->setPath(s.ccCommand); + m_ui.commandPathChooser->setFilePath(FilePath::fromString(s.ccCommand)); m_ui.timeOutSpinBox->setValue(s.timeOutS); m_ui.autoCheckOutCheckBox->setChecked(s.autoCheckOut); m_ui.noCommentCheckBox->setChecked(s.noComment); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index d3a95645304..d1c9d9a22b4 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -35,6 +35,7 @@ #include "cmakeprojectnodes.h" #include "cmakeprojectplugin.h" #include "cmakespecificsettings.h" +#include "projecttreehelper.h" #include "utils/algorithm.h" #include @@ -158,8 +159,7 @@ CMakeBuildSystem::CMakeBuildSystem(CMakeBuildConfiguration *bc) m_treeScanner.setFilter([this](const MimeType &mimeType, const FilePath &fn) { // Mime checks requires more resources, so keep it last in check list - auto isIgnored = fn.toString().startsWith(projectFilePath().toString() + ".user") - || TreeScanner::isWellKnownBinary(mimeType, fn); + auto isIgnored = TreeScanner::isWellKnownBinary(mimeType, fn); // Cache mime check result for speed up if (!isIgnored) { @@ -213,7 +213,6 @@ CMakeBuildSystem::~CMakeBuildSystem() delete m_cppCodeModelUpdater; qDeleteAll(m_extraCompilers); - qDeleteAll(m_allFiles.allFiles); } void CMakeBuildSystem::triggerParsing() @@ -244,28 +243,11 @@ void CMakeBuildSystem::triggerParsing() qCDebug(cmakeBuildSystemLog) << "ParseGuard acquired."; - if (m_allFiles.allFiles.isEmpty()) { - qCDebug(cmakeBuildSystemLog) - << "No treescanner information available, forcing treescanner run."; - updateReparseParameters(REPARSE_SCAN); - } - int reparseParameters = takeReparseParameters(); - m_waitingForScan = (reparseParameters & REPARSE_SCAN) != 0; m_waitingForParse = true; m_combinedScanAndParseResult = true; - if (m_waitingForScan) { - qCDebug(cmakeBuildSystemLog) << "Starting TreeScanner"; - QTC_CHECK(m_treeScanner.isFinished()); - if (m_treeScanner.asyncScanForFiles(projectDirectory())) - Core::ProgressManager::addTask(m_treeScanner.future(), - tr("Scan \"%1\" project tree") - .arg(project()->displayName()), - "CMake.Scan.Tree"); - } - QTC_ASSERT(m_parameters.isValid(), return ); TaskHub::clearTasks(ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM); @@ -365,8 +347,6 @@ QString CMakeBuildSystem::reparseParametersString(int reparseFlags) result += " FORCE_CMAKE_RUN"; if (reparseFlags & REPARSE_FORCE_INITIAL_CONFIGURATION) result += " FORCE_CONFIG"; - if (reparseFlags & REPARSE_SCAN) - result += " SCAN"; } return result.trimmed(); } @@ -442,7 +422,7 @@ void CMakeBuildSystem::runCMakeAndScanProjectTree() BuildDirParameters parameters(cmakeBuildConfiguration()); qCDebug(cmakeBuildSystemLog) << "Requesting parse due to \"Rescan Project\" command"; setParametersAndRequestParse(parameters, - REPARSE_FORCE_CMAKE_RUN | REPARSE_SCAN | REPARSE_URGENT); + REPARSE_FORCE_CMAKE_RUN | REPARSE_URGENT); } void CMakeBuildSystem::runCMakeWithExtraArguments() @@ -461,18 +441,6 @@ void CMakeBuildSystem::buildCMakeTarget(const QString &buildTarget) cmakeBuildConfiguration()->buildTarget(buildTarget); } -void CMakeBuildSystem::handleTreeScanningFinished() -{ - QTC_CHECK(m_waitingForScan); - - qDeleteAll(m_allFiles.allFiles); - m_allFiles = m_treeScanner.release(); - - m_waitingForScan = false; - - combineScanAndParse(m_reader.lastCMakeExitCode() != 0); -} - bool CMakeBuildSystem::persistCMakeState() { BuildDirParameters parameters(cmakeBuildConfiguration()); @@ -524,17 +492,10 @@ void CMakeBuildSystem::clearCMakeCache() path.removeRecursively(); } -std::unique_ptr CMakeBuildSystem::generateProjectTree( - const TreeScanner::Result &allFiles, bool failedToParse) -{ - auto root = m_reader.generateProjectTree(allFiles, failedToParse); - return root; -} - void CMakeBuildSystem::combineScanAndParse(bool restoredFromBackup) { if (cmakeBuildConfiguration()->isActive()) { - if (m_waitingForParse || m_waitingForScan) + if (m_waitingForParse) return; if (m_combinedScanAndParseResult) { @@ -548,6 +509,15 @@ void CMakeBuildSystem::combineScanAndParse(bool restoredFromBackup) "

The backup of the previous configuration has been restored.

" "

Have a look at the Issues pane or in the \"Projects > Build\" settings " "for more information about the failure.(m_parameters.sourceDirectory); + newRoot->setDisplayName(m_parameters.sourceDirectory.fileName()); + + if (!m_reader.topCmakeFile().isEmpty()) { + auto node = std::make_unique(m_reader.topCmakeFile(), FileType::Project); + node->setIsGenerated(false); + + std::vector> fileNodes; + fileNodes.emplace_back(std::move(node)); + + addCMakeLists(newRoot.get(), std::move(fileNodes)); + } + + addFileSystemNodes(newRoot.get(), m_allFiles); + setRootProjectNode(std::move(newRoot)); + + m_reader.resetData(); + + m_currentGuard = {}; + emitBuildSystemUpdated(); + + qCDebug(cmakeBuildSystemLog) << "All fallback CMake project data up to date."; +} + void CMakeBuildSystem::updateFallbackProjectData() { qCDebug(cmakeBuildSystemLog) << "Updating fallback CMake project data"; - - QTC_ASSERT(m_treeScanner.isFinished() && !m_reader.isParsing(), return ); - - auto newRoot = generateProjectTree(m_allFiles, true); - setRootProjectNode(std::move(newRoot)); - - qCDebug(cmakeBuildSystemLog) << "All fallback CMake project data up to date."; + qCDebug(cmakeBuildSystemLog) << "Starting TreeScanner"; + QTC_CHECK(m_treeScanner.isFinished()); + if (m_treeScanner.asyncScanForFiles(projectDirectory())) + Core::ProgressManager::addTask(m_treeScanner.future(), + tr("Scan \"%1\" project tree") + .arg(project()->displayName()), + "CMake.Scan.Tree"); } void CMakeBuildSystem::updateCMakeConfiguration(QString &errorMessage) @@ -899,7 +895,7 @@ void CMakeBuildSystem::becameDirty() if (isParsing()) return; - setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()), REPARSE_SCAN); + setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()), REPARSE_DEFAULT); } void CMakeBuildSystem::updateReparseParameters(const int parameters) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h index 4ed4342b01d..542568b5a77 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h @@ -37,7 +37,10 @@ #include namespace CppEditor { class CppProjectUpdater; } -namespace ProjectExplorer { class ExtraCompiler; } +namespace ProjectExplorer { + class ExtraCompiler; + class FolderNode; +} namespace CMakeProjectManager { @@ -113,8 +116,7 @@ private: REPARSE_FORCE_INITIAL_CONFIGURATION = (1 << 1), // Force initial configuration arguments to cmake REPARSE_FORCE_EXTRA_CONFIGURATION = (1 << 2), // Force extra configuration arguments to cmake - REPARSE_SCAN = (1 << 3), // Run filesystem scan - REPARSE_URGENT = (1 << 4), // Do not delay the parser run by 1s + REPARSE_URGENT = (1 << 3), // Do not delay the parser run by 1s }; QString reparseParametersString(int reparseFlags); void setParametersAndRequestParse(const BuildDirParameters ¶meters, @@ -132,9 +134,6 @@ private: // Combining Treescanner and Parser states: void combineScanAndParse(bool restoredFromBackup); - - std::unique_ptr generateProjectTree( - const ProjectExplorer::TreeScanner::Result &allFiles, bool failedToParse); void checkAndReportError(QString &errorMessage); void updateCMakeConfiguration(QString &errorMessage); @@ -146,6 +145,8 @@ private: const QList &moduleMappings); void updateInitialCMakeExpandableVars(); + void updateFileSystemNodes(); + void handleParsingSucceeded(bool restoredFromBackup); void handleParsingFailed(const QString &msg); @@ -161,10 +162,9 @@ private: void runCTest(); ProjectExplorer::TreeScanner m_treeScanner; - ProjectExplorer::TreeScanner::Result m_allFiles; + std::shared_ptr m_allFiles; QHash m_mimeBinaryCache; - bool m_waitingForScan = false; bool m_waitingForParse = false; bool m_combinedScanAndParseResult = false; diff --git a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp index 5c50ce0c977..d893370028e 100644 --- a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp +++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp @@ -721,31 +721,5 @@ FileApiQtcData extractData(FileApiData &input, return result; } -FileApiQtcData generateFallbackData(const FilePath &topCmakeFile, - const FilePath &sourceDirectory, - const FilePath &buildDirectory, - QString errorMessage) -{ - Q_UNUSED(buildDirectory) - - FileApiQtcData result; - - result.rootProjectNode.reset(new CMakeProjectNode{sourceDirectory}); - result.rootProjectNode->setDisplayName(sourceDirectory.fileName()); - result.errorMessage = errorMessage; - - if (!topCmakeFile.isEmpty()) { - auto node = std::make_unique(topCmakeFile, FileType::Project); - node->setIsGenerated(false); - - std::vector> fileNodes; - fileNodes.emplace_back(std::move(node)); - - addCMakeLists(result.rootProjectNode.get(), std::move(fileNodes)); - } - - return result; -} - } // namespace Internal } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/fileapidataextractor.h b/src/plugins/cmakeprojectmanager/fileapidataextractor.h index f0ba89d0428..2b65c76e079 100644 --- a/src/plugins/cmakeprojectmanager/fileapidataextractor.h +++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.h @@ -75,10 +75,6 @@ public: FileApiQtcData extractData(FileApiData &data, const Utils::FilePath &sourceDirectory, const Utils::FilePath &buildDirectory); -FileApiQtcData generateFallbackData(const Utils::FilePath &topCmakeFile, - const Utils::FilePath &sourceDirectory, - const Utils::FilePath &buildDirectory, - QString errorMessage); } // namespace Internal } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/fileapireader.cpp b/src/plugins/cmakeprojectmanager/fileapireader.cpp index 24c3c29fe47..faa1717e71c 100644 --- a/src/plugins/cmakeprojectmanager/fileapireader.cpp +++ b/src/plugins/cmakeprojectmanager/fileapireader.cpp @@ -27,7 +27,6 @@ #include "fileapidataextractor.h" #include "fileapiparser.h" -#include "projecttreehelper.h" #include @@ -214,15 +213,6 @@ bool FileApiReader::usesAllCapsTargets() const return m_usesAllCapsTargets; } -std::unique_ptr FileApiReader::generateProjectTree( - const ProjectExplorer::TreeScanner::Result &allFiles, bool failedToParse) -{ - if (failedToParse) - addFileSystemNodes(m_rootProjectNode.get(), allFiles.folderNode); - - return std::exchange(m_rootProjectNode, {}); -} - RawProjectParts FileApiReader::createRawProjectParts(QString &errorMessage) { Q_UNUSED(errorMessage) @@ -250,37 +240,29 @@ void FileApiReader::endState(const FilePath &replyFilePath, bool restoredFromBac const FilePath sourceDirectory = m_parameters.sourceDirectory; const FilePath buildDirectory = m_parameters.buildDirectory; - const FilePath topCmakeFile = m_cmakeFiles.size() == 1 ? (*m_cmakeFiles.begin()).path : FilePath{}; const QString cmakeBuildType = m_parameters.cmakeBuildType == "Build" ? "" : m_parameters.cmakeBuildType; QTC_CHECK(!replyFilePath.needsDevice()); m_lastReplyTimestamp = replyFilePath.lastModified(); m_future = runAsync(ProjectExplorerPlugin::sharedThreadPool(), - [replyFilePath, sourceDirectory, buildDirectory, topCmakeFile, cmakeBuildType]( + [replyFilePath, sourceDirectory, buildDirectory, cmakeBuildType]( QFutureInterface> &fi) { auto result = std::make_shared(); FileApiData data = FileApiParser::parseData(fi, replyFilePath, cmakeBuildType, result->errorMessage); - if (!result->errorMessage.isEmpty()) { - *result = generateFallbackData(topCmakeFile, - sourceDirectory, - buildDirectory, - result->errorMessage); - } else { + if (result->errorMessage.isEmpty()) *result = extractData(data, sourceDirectory, buildDirectory); - } - if (!result->errorMessage.isEmpty()) { + else qWarning() << result->errorMessage; - } fi.reportResult(result); }); onResultReady(m_future.value(), this, - [this, topCmakeFile, sourceDirectory, buildDirectory, restoredFromBackup]( + [this, sourceDirectory, buildDirectory, restoredFromBackup]( const std::shared_ptr &value) { m_isParsing = false; m_cache = std::move(value->cache); @@ -348,6 +330,16 @@ void FileApiReader::writeConfigurationIntoBuildDirectory(const QStringList &conf QTC_CHECK(settingsFile.writeFileContents(contents)); } +std::unique_ptr FileApiReader::rootProjectNode() +{ + return std::exchange(m_rootProjectNode, {}); +} + +FilePath FileApiReader::topCmakeFile() const +{ + return m_cmakeFiles.size() == 1 ? (*m_cmakeFiles.begin()).path : FilePath{}; +} + int FileApiReader::lastCMakeExitCode() const { return m_lastCMakeExitCode; diff --git a/src/plugins/cmakeprojectmanager/fileapireader.h b/src/plugins/cmakeprojectmanager/fileapireader.h index a0fd38c491d..8e0c77278d2 100644 --- a/src/plugins/cmakeprojectmanager/fileapireader.h +++ b/src/plugins/cmakeprojectmanager/fileapireader.h @@ -71,8 +71,6 @@ public: QList takeBuildTargets(QString &errorMessage); CMakeConfig takeParsedConfiguration(QString &errorMessage); QString ctestPath() const; - std::unique_ptr generateProjectTree( - const ProjectExplorer::TreeScanner::Result &allFiles, bool failedToParse); ProjectExplorer::RawProjectParts createRawProjectParts(QString &errorMessage); bool isMultiConfig() const; @@ -80,6 +78,10 @@ public: int lastCMakeExitCode() const; + std::unique_ptr rootProjectNode(); + + Utils::FilePath topCmakeFile() const; + signals: void configurationStarted() const; void dataAvailable(bool restoredFromBackup) const; diff --git a/src/plugins/cppeditor/cpplocalrenaming.cpp b/src/plugins/cppeditor/cpplocalrenaming.cpp index 5713a02fdda..cce808e4af1 100644 --- a/src/plugins/cppeditor/cpplocalrenaming.cpp +++ b/src/plugins/cppeditor/cpplocalrenaming.cpp @@ -243,9 +243,15 @@ void CppLocalRenaming::forgetRenamingSelection() m_renameSelectionIndex = -1; } +bool CppLocalRenaming::isWithinSelection(const QTextEdit::ExtraSelection &selection, int position) +{ + return selection.cursor.selectionStart() <= position + && position <= selection.cursor.selectionEnd(); +} + bool CppLocalRenaming::isWithinRenameSelection(int position) { - return renameSelectionBegin() <= position && position <= renameSelectionEnd(); + return isWithinSelection(renameSelection(), position); } bool CppLocalRenaming::isSameSelection(int cursorPosition) const @@ -254,14 +260,14 @@ bool CppLocalRenaming::isSameSelection(int cursorPosition) const return false; const QTextEdit::ExtraSelection &sel = m_selections[m_renameSelectionIndex]; - return (sel.cursor.position() <= cursorPosition && cursorPosition <= sel.cursor.anchor()); + return isWithinSelection(sel, cursorPosition); } bool CppLocalRenaming::findRenameSelection(int cursorPosition) { for (int i = 0, total = m_selections.size(); i < total; ++i) { const QTextEdit::ExtraSelection &sel = m_selections.at(i); - if (sel.cursor.position() <= cursorPosition && cursorPosition <= sel.cursor.anchor()) { + if (isWithinSelection(sel, cursorPosition)) { m_renameSelectionIndex = i; return true; } diff --git a/src/plugins/cppeditor/cpplocalrenaming.h b/src/plugins/cppeditor/cpplocalrenaming.h index 61c1d1ca11c..5571977c503 100644 --- a/src/plugins/cppeditor/cpplocalrenaming.h +++ b/src/plugins/cppeditor/cpplocalrenaming.h @@ -72,11 +72,12 @@ private: // The "rename selection" is the local use selection on which the user started the renaming bool findRenameSelection(int cursorPosition); void forgetRenamingSelection(); + static bool isWithinSelection(const QTextEdit::ExtraSelection &selection, int position); bool isWithinRenameSelection(int position); QTextEdit::ExtraSelection &renameSelection(); - int renameSelectionBegin() { return renameSelection().cursor.position(); } - int renameSelectionEnd() { return renameSelection().cursor.anchor(); } + int renameSelectionBegin() { return renameSelection().cursor.selectionStart(); } + int renameSelectionEnd() { return renameSelection().cursor.selectionEnd(); } void updateRenamingSelectionCursor(const QTextCursor &cursor); void updateRenamingSelectionFormat(const QTextCharFormat &format); diff --git a/src/plugins/debugger/debuggerkitinformation.cpp b/src/plugins/debugger/debuggerkitinformation.cpp index edc355469de..e7f1c5f2d7f 100644 --- a/src/plugins/debugger/debuggerkitinformation.cpp +++ b/src/plugins/debugger/debuggerkitinformation.cpp @@ -308,7 +308,8 @@ DebuggerKitAspect::ConfigurationErrors DebuggerKitAspect::configurationErrors(co ConfigurationErrors result = NoConfigurationError; const FilePath debugger = item->command(); - if (!debugger.exists() || debugger.isDir()) + const bool found = debugger.exists() && !debugger.isDir(); + if (!found) result |= DebuggerNotFound; else if (!debugger.isExecutableFile()) result |= DebuggerNotExecutable; @@ -321,7 +322,7 @@ DebuggerKitAspect::ConfigurationErrors DebuggerKitAspect::configurationErrors(co result |= DebuggerDoesNotMatch; } - if (!debugger.exists() || debugger.isDir()) { + if (!found) { if (item->engineType() == NoEngineType) return NoDebugger; diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index cbf27544079..624f3eab49b 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -897,7 +897,10 @@ void DockerDevicePrivate::startContainer() void DockerDevicePrivate::tryCreateLocalFileAccess() { - if (!m_container.isEmpty() || DockerPlugin::isDaemonRunning().value_or(true) == false) + if (!m_container.isEmpty()) + return; + + if (DockerPlugin::isDaemonRunning().value_or(true) == false) return; if (!m_shell) diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index de1427e8398..b1b4362956b 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -87,6 +87,7 @@ #include #include #include +#include #include #ifdef WITH_TESTS @@ -477,8 +478,11 @@ void GitPluginPrivate::onApplySettings() bool gitFoundOk; QString errorMessage; m_settings.gitExecutable(&gitFoundOk, &errorMessage); - if (!gitFoundOk) - Core::AsynchronousMessageBox::warning(tr("Git Settings"), errorMessage); + if (!gitFoundOk) { + QTimer::singleShot(0, this, [this, errorMessage] { + Core::AsynchronousMessageBox::warning(tr("Git Settings"), errorMessage); + }); + } } void GitPluginPrivate::cleanCommitMessageFile() diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index 220ddb42c55..5f2b44d5e91 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -248,6 +248,7 @@ static ClientCapabilities generateClientCapabilities() signatureHelp.setDynamicRegistration(true); TextDocumentClientCapabilities::SignatureHelpCapabilities::SignatureInformationCapabilities info; info.setDocumentationFormat({MarkupKind::markdown, MarkupKind::plaintext}); + info.setActiveParameterSupport(true); signatureHelp.setSignatureInformation(info); documentCapabilities.setSignatureHelp(signatureHelp); diff --git a/src/plugins/languageclient/languageclientfunctionhint.cpp b/src/plugins/languageclient/languageclientfunctionhint.cpp index 76a851d0cd4..f554d4a3b0e 100644 --- a/src/plugins/languageclient/languageclientfunctionhint.cpp +++ b/src/plugins/languageclient/languageclientfunctionhint.cpp @@ -61,11 +61,12 @@ QString FunctionHintProposalModel::text(int index) const if (index < 0 || m_sigis.signatures().size() <= index) return {}; const SignatureInformation signature = m_sigis.signatures().at(index); + int parametersIndex = signature.activeParameter().value_or(-1); + if (parametersIndex < 0) { + if (index == m_sigis.activeSignature().value_or(-1)) + parametersIndex = m_sigis.activeParameter().value_or(-1); + } QString label = signature.label(); - if (index != m_sigis.activeSignature().value_or(-1)) - return label; - - const int parametersIndex = m_sigis.activeParameter().value_or(-1); if (parametersIndex < 0) return label; diff --git a/src/plugins/languageclient/languageclientsymbolsupport.cpp b/src/plugins/languageclient/languageclientsymbolsupport.cpp index fabb628bebc..8199084c416 100644 --- a/src/plugins/languageclient/languageclientsymbolsupport.cpp +++ b/src/plugins/languageclient/languageclientsymbolsupport.cpp @@ -78,14 +78,18 @@ static void handleGotoDefinitionResponse(const GotoDefinitionRequest::Response & { if (Utils::optional _result = response.result()) { const GotoResult result = _result.value(); - if (Utils::holds_alternative(result)) - return; - if (auto ploc = Utils::get_if(&result)) { + if (Utils::holds_alternative(result)) { + callback({}); + } else if (auto ploc = Utils::get_if(&result)) { callback(linkUnderCursor.value_or(ploc->toLink())); } else if (auto plloc = Utils::get_if>(&result)) { if (!plloc->isEmpty()) callback(linkUnderCursor.value_or(plloc->value(0).toLink())); + else + callback({}); } + } else { + callback({}); } } diff --git a/src/plugins/languageclient/locatorfilter.cpp b/src/plugins/languageclient/locatorfilter.cpp index a817b4339d8..5d2a583a27f 100644 --- a/src/plugins/languageclient/locatorfilter.cpp +++ b/src/plugins/languageclient/locatorfilter.cpp @@ -62,7 +62,9 @@ void DocumentLocatorFilter::updateCurrentClient() disconnect(m_resetSymbolsConnection); TextEditor::TextDocument *document = TextEditor::TextDocument::currentTextDocument(); - if (Client *client = LanguageClientManager::clientForDocument(document)) { + if (Client *client = LanguageClientManager::clientForDocument(document); + client && client->locatorsEnabled()) { + setEnabled(true); if (m_symbolCache != client->documentSymbolCache()) { disconnect(m_updateSymbolsConnection); m_symbolCache = client->documentSymbolCache(); @@ -76,6 +78,7 @@ void DocumentLocatorFilter::updateCurrentClient() disconnect(m_updateSymbolsConnection); m_symbolCache.clear(); m_currentUri.clear(); + setEnabled(false); } } diff --git a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp index d7584ede0bb..d6080f4e90f 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage.cpp @@ -956,6 +956,15 @@ void CheckBoxField::setup(JsonFieldPage *page, const QString &name) }); } +void CheckBoxField::setChecked(bool value) +{ + auto w = qobject_cast(widget()); + QTC_ASSERT(w, return); + + w->setChecked(value); + w->clicked(value); +} + bool CheckBoxField::validate(MacroExpander *expander, QString *message) { if (!JsonFieldPage::Field::validate(expander, message)) diff --git a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h index 251315a510b..ed89746d0b2 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonfieldpage_p.h @@ -230,11 +230,13 @@ private: Utils::PathChooser::Kind m_kind = Utils::PathChooser::ExistingDirectory; }; -class CheckBoxField : public JsonFieldPage::Field +class PROJECTEXPLORER_EXPORT CheckBoxField : public JsonFieldPage::Field { public: bool suppressName() const override { return true; } + void setChecked(bool); + private: bool parseData(const QVariant &data, QString *errorMessage) override; diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp index 579722a63d6..9aa16ff0513 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp @@ -257,12 +257,14 @@ QList JsonWizardFactory::createWizardFactories() .arg(currentFile.fileName()) .arg(line).arg(column) .arg(error.errorString())); + qWarning() << "Failed to parse wizard: " << currentFile.fileName(); continue; } if (!json.isObject()) { verboseLog.append(tr("* Did not find a JSON object in \"%1\".\n") .arg(currentFile.fileName())); + qWarning() << "Failed to parse wizard: " << currentFile.fileName(); continue; } @@ -280,6 +282,7 @@ QList JsonWizardFactory::createWizardFactories() JsonWizardFactory *factory = createWizardFactory(data, currentDir, &errorMessage); if (!factory) { verboseLog.append(tr("* Failed to create: %1\n").arg(errorMessage)); + qWarning() << "Failed to create wizard: " << currentFile.fileName(); continue; } diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp index cabe83f1941..dbd060cfe8d 100644 --- a/src/plugins/projectexplorer/kitinformation.cpp +++ b/src/plugins/projectexplorer/kitinformation.cpp @@ -51,8 +51,6 @@ #include #include -#include -#include #include #include #include @@ -133,18 +131,16 @@ Tasks SysRootKitAspect::validate(const Kit *k) const if (dir.isEmpty()) return result; - if (dir.toString().startsWith("target:") || dir.toString().startsWith("remote:")) + if (dir.startsWith("target:") || dir.startsWith("remote:")) return result; - const QFileInfo fi = dir.toFileInfo(); - - if (!fi.exists()) { + if (!dir.exists()) { result << BuildSystemTask(Task::Warning, tr("Sys Root \"%1\" does not exist in the file system.").arg(dir.toUserOutput())); - } else if (!fi.isDir()) { + } else if (!dir.isDir()) { result << BuildSystemTask(Task::Warning, tr("Sys Root \"%1\" is not a directory.").arg(dir.toUserOutput())); - } else if (QDir(dir.toString()).entryList(QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty()) { + } else if (dir.dirEntries(QDir::AllEntries | QDir::NoDotAndDotDot).isEmpty()) { result << BuildSystemTask(Task::Warning, tr("Sys Root \"%1\" is empty.").arg(dir.toUserOutput())); } @@ -626,11 +622,10 @@ QList ToolChainKitAspect::toolChains(const Kit *k) const QVariantMap value = k->value(ToolChainKitAspect::id()).toMap(); const QList tcList - = Utils::transform(ToolChainManager::allLanguages(), - [&value](Utils::Id l) -> ToolChain * { - return ToolChainManager::findToolChain(value.value(l.toString()).toByteArray()); - }); - return Utils::filtered(tcList, [](ToolChain *tc) { return tc; }); + = transform(ToolChainManager::allLanguages(), [&value](Id l) { + return ToolChainManager::findToolChain(value.value(l.toString()).toByteArray()); + }); + return filtered(tcList, [](ToolChain *tc) { return tc; }); } void ToolChainKitAspect::setToolChain(Kit *k, ToolChain *tc) @@ -664,7 +659,7 @@ void ToolChainKitAspect::setAllToolChainsToMatch(Kit *k, ToolChain *tc) QVariantMap result = k->value(ToolChainKitAspect::id()).toMap(); result.insert(tc->language().toString(), tc->id()); - for (Utils::Id l : ToolChainManager::allLanguages()) { + for (const Id l : ToolChainManager::allLanguages()) { if (l == tc->language()) continue; @@ -692,7 +687,7 @@ void ToolChainKitAspect::setAllToolChainsToMatch(Kit *k, ToolChain *tc) k->setValue(id(), result); } -void ToolChainKitAspect::clearToolChain(Kit *k, Utils::Id language) +void ToolChainKitAspect::clearToolChain(Kit *k, Id language) { QTC_ASSERT(language.isValid(), return); QTC_ASSERT(k, return); @@ -710,7 +705,7 @@ Abi ToolChainKitAspect::targetAbi(const Kit *k) QHash abiCount; foreach (ToolChain *tc, tcList) { Abi ta = tc->targetAbi(); - if (tc->language() == Utils::Id(Constants::CXX_LANGUAGE_ID)) + if (tc->language() == Id(Constants::CXX_LANGUAGE_ID)) cxxAbi = tc->targetAbi(); abiCount[ta] = (abiCount.contains(ta) ? abiCount[ta] + 1 : 1); } @@ -799,7 +794,7 @@ private: void refresh() override { - Utils::Id devType = DeviceTypeKitAspect::deviceTypeId(m_kit); + Id devType = DeviceTypeKitAspect::deviceTypeId(m_kit); if (!devType.isValid()) m_comboBox->setCurrentIndex(-1); for (int i = 0; i < m_comboBox->count(); ++i) { @@ -812,7 +807,7 @@ private: void currentTypeChanged(int idx) { - Utils::Id type = idx < 0 ? Utils::Id() : Utils::Id::fromSetting(m_comboBox->itemData(idx)); + Id type = idx < 0 ? Id() : Id::fromSetting(m_comboBox->itemData(idx)); DeviceTypeKitAspect::setDeviceTypeId(m_kit, type); } @@ -851,7 +846,7 @@ KitAspectWidget *DeviceTypeKitAspect::createConfigWidget(Kit *k) const KitAspect::ItemList DeviceTypeKitAspect::toUserOutput(const Kit *k) const { QTC_ASSERT(k, return {}); - Utils::Id type = deviceTypeId(k); + Id type = deviceTypeId(k); QString typeDisplayName = tr("Unknown device type"); if (type.isValid()) { if (IDeviceFactory *factory = IDeviceFactory::find(type)) @@ -860,33 +855,33 @@ KitAspect::ItemList DeviceTypeKitAspect::toUserOutput(const Kit *k) const return {{tr("Device type"), typeDisplayName}}; } -const Utils::Id DeviceTypeKitAspect::id() +const Id DeviceTypeKitAspect::id() { return "PE.Profile.DeviceType"; } -const Utils::Id DeviceTypeKitAspect::deviceTypeId(const Kit *k) +const Id DeviceTypeKitAspect::deviceTypeId(const Kit *k) { - return k ? Utils::Id::fromSetting(k->value(DeviceTypeKitAspect::id())) : Utils::Id(); + return k ? Id::fromSetting(k->value(DeviceTypeKitAspect::id())) : Id(); } -void DeviceTypeKitAspect::setDeviceTypeId(Kit *k, Utils::Id type) +void DeviceTypeKitAspect::setDeviceTypeId(Kit *k, Id type) { QTC_ASSERT(k, return); k->setValue(DeviceTypeKitAspect::id(), type.toSetting()); } -QSet DeviceTypeKitAspect::supportedPlatforms(const Kit *k) const +QSet DeviceTypeKitAspect::supportedPlatforms(const Kit *k) const { return {deviceTypeId(k)}; } -QSet DeviceTypeKitAspect::availableFeatures(const Kit *k) const +QSet DeviceTypeKitAspect::availableFeatures(const Kit *k) const { - Utils::Id id = DeviceTypeKitAspect::deviceTypeId(k); + Id id = DeviceTypeKitAspect::deviceTypeId(k); if (id.isValid()) return {id.withPrefix("DeviceType.")}; - return QSet(); + return {}; } // -------------------------------------------------------------------------- @@ -1225,7 +1220,7 @@ private: QComboBox *m_comboBox; QWidget *m_manageButton; DeviceManagerModel *m_model; - Utils::Id m_selectedId; + Id m_selectedId; }; } // namespace Internal diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.cpp b/src/plugins/projectexplorer/projectexplorersettingspage.cpp index 1cf66764a68..22163a9f451 100644 --- a/src/plugins/projectexplorer/projectexplorersettingspage.cpp +++ b/src/plugins/projectexplorer/projectexplorersettingspage.cpp @@ -34,10 +34,13 @@ #include +using namespace Core; +using namespace Utils; + namespace ProjectExplorer { namespace Internal { - enum { UseCurrentDirectory, UseProjectDirectory }; +enum { UseCurrentDirectory, UseProjectDirectory }; class ProjectExplorerSettingsWidget : public QWidget { @@ -49,8 +52,8 @@ public: ProjectExplorerSettings settings() const; void setSettings(const ProjectExplorerSettings &s); - QString projectsDirectory() const; - void setProjectsDirectory(const QString &pd); + FilePath projectsDirectory() const; + void setProjectsDirectory(const FilePath &pd); bool useProjectsDirectory(); void setUseProjectsDirectory(bool v); @@ -68,7 +71,7 @@ ProjectExplorerSettingsWidget::ProjectExplorerSettingsWidget(QWidget *parent) : QWidget(parent) { m_ui.setupUi(this); - setJomVisible(Utils::HostOsInfo::isWindowsHost()); + setJomVisible(HostOsInfo::isWindowsHost()); m_ui.stopBeforeBuildComboBox->addItem(tr("None"), int(StopBeforeBuild::None)); m_ui.stopBeforeBuildComboBox->addItem(tr("All"), int(StopBeforeBuild::All)); m_ui.stopBeforeBuildComboBox->addItem(tr("Same Project"), int(StopBeforeBuild::SameProject)); @@ -135,14 +138,14 @@ void ProjectExplorerSettingsWidget::setSettings(const ProjectExplorerSettings & m_ui.lowBuildPriorityCheckBox->setChecked(m_settings.lowBuildPriority); } -QString ProjectExplorerSettingsWidget::projectsDirectory() const +FilePath ProjectExplorerSettingsWidget::projectsDirectory() const { - return m_ui.projectsDirectoryPathChooser->filePath().toString(); + return m_ui.projectsDirectoryPathChooser->filePath(); } -void ProjectExplorerSettingsWidget::setProjectsDirectory(const QString &pd) +void ProjectExplorerSettingsWidget::setProjectsDirectory(const FilePath &pd) { - m_ui.projectsDirectoryPathChooser->setPath(pd); + m_ui.projectsDirectoryPathChooser->setFilePath(pd); } bool ProjectExplorerSettingsWidget::useProjectsDirectory() @@ -179,8 +182,8 @@ QWidget *ProjectExplorerSettingsPage::widget() if (!m_widget) { m_widget = new ProjectExplorerSettingsWidget; m_widget->setSettings(ProjectExplorerPlugin::projectExplorerSettings()); - m_widget->setProjectsDirectory(Core::DocumentManager::projectsDirectory().toString()); - m_widget->setUseProjectsDirectory(Core::DocumentManager::useProjectsDirectory()); + m_widget->setProjectsDirectory(DocumentManager::projectsDirectory()); + m_widget->setUseProjectsDirectory(DocumentManager::useProjectsDirectory()); } return m_widget; } @@ -189,9 +192,8 @@ void ProjectExplorerSettingsPage::apply() { if (m_widget) { ProjectExplorerPlugin::setProjectExplorerSettings(m_widget->settings()); - Core::DocumentManager::setProjectsDirectory( - Utils::FilePath::fromString(m_widget->projectsDirectory())); - Core::DocumentManager::setUseProjectsDirectory(m_widget->useProjectsDirectory()); + DocumentManager::setProjectsDirectory(m_widget->projectsDirectory()); + DocumentManager::setUseProjectsDirectory(m_widget->useProjectsDirectory()); } } diff --git a/src/plugins/projectexplorer/projectwelcomepage.cpp b/src/plugins/projectexplorer/projectwelcomepage.cpp index 8cf3fc70f9a..e0b8795f403 100644 --- a/src/plugins/projectexplorer/projectwelcomepage.cpp +++ b/src/plugins/projectexplorer/projectwelcomepage.cpp @@ -320,14 +320,14 @@ public: QFontMetrics fm(option.widget->font()); for (const QString &project : projects) { // Project name. - QFileInfo fi(project); - QString completeBase = fi.completeBaseName(); + FilePath projectPath = FilePath::fromString(project); + QString completeBase = projectPath.completeBaseName(); painter->setPen(textColor); painter->drawText(x1, yy, completeBase); yy += 18; // Project path. - QString pathWithTilde = Utils::withTildeHomePath(QDir::toNativeSeparators(project)); + QString pathWithTilde = Utils::withTildeHomePath(projectPath.toUserOutput()); painter->setPen(foregroundColor1); painter->drawText(x1, yy, fm.elidedText(pathWithTilde, Qt::ElideMiddle, rc.width() - 40)); yy += 22; @@ -454,7 +454,7 @@ public: painter->drawPixmap(x + 11, y + 6, projectIcon); QString projectName = idx.data(Qt::DisplayRole).toString(); - QString projectPath = idx.data(ProjectModel::FilePathRole).toString(); + FilePath projectPath = FilePath::fromVariant(idx.data(ProjectModel::FilePathRole)); painter->setPen(themeColor(Theme::Welcome_ForegroundSecondaryColor)); painter->setFont(sizedFont(10, option.widget)); @@ -468,7 +468,7 @@ public: painter->setPen(themeColor(Theme::Welcome_ForegroundPrimaryColor)); painter->setFont(sizedFont(13, option.widget)); - QString pathWithTilde = Utils::withTildeHomePath(QDir::toNativeSeparators(projectPath)); + QString pathWithTilde = Utils::withTildeHomePath(projectPath.toUserOutput()); painter->drawText(x + 36, secondBase, pathWithTilde); } diff --git a/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp b/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp index e2fc82358af..8839a89e8ab 100644 --- a/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp +++ b/src/plugins/qmakeprojectmanager/addlibrarywizard.cpp @@ -38,8 +38,8 @@ #include #include -using namespace QmakeProjectManager; -using namespace QmakeProjectManager::Internal; +namespace QmakeProjectManager { +namespace Internal { const char qt_file_dialog_filter_reg_exp[] = "^(.*)\\(([a-zA-Z0-9_.*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$"; @@ -79,8 +79,8 @@ static bool validateLibraryPath(const Utils::FilePath &filePath, return false; } -AddLibraryWizard::AddLibraryWizard(const QString &fileName, QWidget *parent) : - Utils::Wizard(parent), m_proFile(fileName) +AddLibraryWizard::AddLibraryWizard(const Utils::FilePath &proFile, QWidget *parent) : + Utils::Wizard(parent), m_proFile(proFile) { setWindowTitle(tr("Add Library")); m_libraryTypePage = new LibraryTypePage(this); @@ -93,7 +93,7 @@ AddLibraryWizard::AddLibraryWizard(const QString &fileName, QWidget *parent) : AddLibraryWizard::~AddLibraryWizard() = default; -QString AddLibraryWizard::proFile() const +Utils::FilePath AddLibraryWizard::proFile() const { return m_proFile; } @@ -294,10 +294,9 @@ SummaryPage::SummaryPage(AddLibraryWizard *parent) void SummaryPage::initializePage() { m_snippet = m_libraryWizard->snippet(); - QFileInfo fi(m_libraryWizard->proFile()); m_summaryLabel->setText( tr("The following snippet will be added to the
%1 file:") - .arg(fi.fileName())); + .arg(m_libraryWizard->proFile().fileName())); QString richSnippet; { QTextStream str(&richSnippet); @@ -316,3 +315,6 @@ QString SummaryPage::snippet() const { return m_snippet; } + +} // Internal +} // QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/addlibrarywizard.h b/src/plugins/qmakeprojectmanager/addlibrarywizard.h index ad2372f0072..5825fae4d99 100644 --- a/src/plugins/qmakeprojectmanager/addlibrarywizard.h +++ b/src/plugins/qmakeprojectmanager/addlibrarywizard.h @@ -76,20 +76,18 @@ public: Q_DECLARE_FLAGS(Platforms, Platform) - explicit AddLibraryWizard(const QString &fileName, QWidget *parent = nullptr); + explicit AddLibraryWizard(const Utils::FilePath &proFile, QWidget *parent = nullptr); ~AddLibraryWizard() override; LibraryKind libraryKind() const; - QString proFile() const; + Utils::FilePath proFile() const; QString snippet() const; -signals: - private: LibraryTypePage *m_libraryTypePage = nullptr; DetailsPage *m_detailsPage = nullptr; SummaryPage *m_summaryPage = nullptr; - QString m_proFile; + Utils::FilePath m_proFile; }; class LibraryTypePage : public QWizardPage diff --git a/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp b/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp index 04f6e131bce..6a1e405b369 100644 --- a/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp +++ b/src/plugins/qmakeprojectmanager/librarydetailscontroller.cpp @@ -40,22 +40,24 @@ #include using namespace ProjectExplorer; -using namespace QmakeProjectManager; -using namespace QmakeProjectManager::Internal; +using namespace Utils; + +namespace QmakeProjectManager { +namespace Internal { static void fillLibraryPlatformTypes(QComboBox *comboBox) { comboBox->clear(); - comboBox->addItem("Windows (*.lib lib*.a)", int(Utils::OsTypeWindows)); - comboBox->addItem("Linux (lib*.so lib*.a)", int(Utils::OsTypeLinux)); - comboBox->addItem("macOS (*.dylib *.a *.framework)", int(Utils::OsTypeMac)); - const int currentIndex = comboBox->findData(int(Utils::HostOsInfo::hostOs())); + comboBox->addItem("Windows (*.lib lib*.a)", int(OsTypeWindows)); + comboBox->addItem("Linux (lib*.so lib*.a)", int(OsTypeLinux)); + comboBox->addItem("macOS (*.dylib *.a *.framework)", int(OsTypeMac)); + const int currentIndex = comboBox->findData(int(HostOsInfo::hostOs())); comboBox->setCurrentIndex(std::max(0, currentIndex)); } LibraryDetailsController::LibraryDetailsController( Ui::LibraryDetailsWidget *libraryDetails, - const QString &proFile, QObject *parent) : + const FilePath &proFile, QObject *parent) : QObject(parent), m_proFile(proFile), m_libraryDetailsWidget(libraryDetails) @@ -65,12 +67,12 @@ LibraryDetailsController::LibraryDetailsController( setLinkageGroupVisible(true); setMacLibraryGroupVisible(true); setPackageLineEditVisible(false); - const bool isMacOs = libraryPlatformType() == Utils::OsTypeMac; - const bool isWindows = libraryPlatformType() == Utils::OsTypeWindows; + const bool isMacOs = libraryPlatformType() == OsTypeMac; + const bool isWindows = libraryPlatformType() == OsTypeWindows; setMacLibraryRadiosVisible(!isMacOs); setLinkageRadiosVisible(isWindows); - connect(m_libraryDetailsWidget->includePathChooser, &Utils::PathChooser::rawPathChanged, + connect(m_libraryDetailsWidget->includePathChooser, &PathChooser::rawPathChanged, this, &LibraryDetailsController::slotIncludePathChanged); connect(m_libraryDetailsWidget->frameworkRadio, &QAbstractButton::clicked, this, &LibraryDetailsController::slotMacLibraryTypeChanged); @@ -108,9 +110,9 @@ AddLibraryWizard::MacLibraryType LibraryDetailsController::macLibraryType() cons return m_macLibraryType; } -Utils::OsType LibraryDetailsController::libraryPlatformType() const +OsType LibraryDetailsController::libraryPlatformType() const { - return Utils::OsType(m_libraryDetailsWidget->libraryTypeComboBox->currentData().value()); + return OsType(m_libraryDetailsWidget->libraryTypeComboBox->currentData().value()); } QString LibraryDetailsController::libraryPlatformFilter() const @@ -198,7 +200,7 @@ void LibraryDetailsController::updateGui() // UGLY HACK END } -QString LibraryDetailsController::proFile() const +FilePath LibraryDetailsController::proFile() const { return m_proFile; } @@ -397,7 +399,7 @@ static QString smartQuote(const QString &aString) { // The OS type is not important in that case, but use always the same // in order not to generate different quoting depending on host platform - return Utils::ProcessArgs::quoteArg(aString, Utils::OsTypeLinux); + return ProcessArgs::quoteArg(aString, OsTypeLinux); } static QString appendSeparator(const QString &aString) @@ -622,15 +624,15 @@ static QString generatePreTargetDepsSnippet(AddLibraryWizard::Platforms platform NonInternalLibraryDetailsController::NonInternalLibraryDetailsController( Ui::LibraryDetailsWidget *libraryDetails, - const QString &proFile, QObject *parent) : + const FilePath &proFile, QObject *parent) : LibraryDetailsController(libraryDetails, proFile, parent) { setLibraryComboBoxVisible(false); setLibraryPathChooserVisible(true); - connect(libraryDetailsWidget()->libraryPathChooser, &Utils::PathChooser::validChanged, + connect(libraryDetailsWidget()->libraryPathChooser, &PathChooser::validChanged, this, &LibraryDetailsController::completeChanged); - connect(libraryDetailsWidget()->libraryPathChooser, &Utils::PathChooser::rawPathChanged, + connect(libraryDetailsWidget()->libraryPathChooser, &PathChooser::rawPathChanged, this, &NonInternalLibraryDetailsController::slotLibraryPathChanged); connect(libraryDetailsWidget()->removeSuffixCheckBox, &QAbstractButton::toggled, this, &NonInternalLibraryDetailsController::slotRemoveSuffixChanged); @@ -646,7 +648,7 @@ NonInternalLibraryDetailsController::NonInternalLibraryDetailsController( AddLibraryWizard::LinkageType NonInternalLibraryDetailsController::suggestedLinkageType() const { AddLibraryWizard::LinkageType type = AddLibraryWizard::NoLinkage; - if (libraryPlatformType() != Utils::OsTypeWindows) { + if (libraryPlatformType() != OsTypeWindows) { if (libraryDetailsWidget()->libraryPathChooser->isValid()) { QFileInfo fi(libraryDetailsWidget()->libraryPathChooser->filePath().toString()); if (fi.suffix() == QLatin1String("a")) @@ -661,7 +663,7 @@ AddLibraryWizard::LinkageType NonInternalLibraryDetailsController::suggestedLink AddLibraryWizard::MacLibraryType NonInternalLibraryDetailsController::suggestedMacLibraryType() const { AddLibraryWizard::MacLibraryType type = AddLibraryWizard::NoLibraryType; - if (libraryPlatformType() == Utils::OsTypeMac) { + if (libraryPlatformType() == OsTypeMac) { if (libraryDetailsWidget()->libraryPathChooser->isValid()) { QFileInfo fi(libraryDetailsWidget()->libraryPathChooser->filePath().toString()); if (fi.suffix() == QLatin1String("framework")) @@ -695,7 +697,7 @@ QString NonInternalLibraryDetailsController::suggestedIncludePath() const void NonInternalLibraryDetailsController::updateWindowsOptionsEnablement() { bool ena = platforms() & (AddLibraryWizard::WindowsMinGWPlatform | AddLibraryWizard::WindowsMSVCPlatform); - if (libraryPlatformType() == Utils::OsTypeWindows) { + if (libraryPlatformType() == OsTypeWindows) { libraryDetailsWidget()->addSuffixCheckBox->setEnabled(ena); ena = true; } @@ -732,10 +734,10 @@ void NonInternalLibraryDetailsController::slotRemoveSuffixChanged(bool ena) void NonInternalLibraryDetailsController::handleLibraryTypeChange() { libraryDetailsWidget()->libraryPathChooser->setPromptDialogFilter(libraryPlatformFilter()); - const bool isMacOs = libraryPlatformType() == Utils::OsTypeMac; - const bool isWindows = libraryPlatformType() == Utils::OsTypeWindows; - libraryDetailsWidget()->libraryPathChooser->setExpectedKind(isMacOs ? Utils::PathChooser::Any - : Utils::PathChooser::File); + const bool isMacOs = libraryPlatformType() == OsTypeMac; + const bool isWindows = libraryPlatformType() == OsTypeWindows; + libraryDetailsWidget()->libraryPathChooser->setExpectedKind(isMacOs ? PathChooser::Any + : PathChooser::File); setMacLibraryRadiosVisible(!isMacOs); setLinkageRadiosVisible(isWindows); setRemoveSuffixVisible(isWindows); @@ -752,7 +754,7 @@ void NonInternalLibraryDetailsController::slotLibraryTypeChanged() void NonInternalLibraryDetailsController::handleLibraryPathChange() { - if (libraryPlatformType() == Utils::OsTypeWindows) { + if (libraryPlatformType() == OsTypeWindows) { bool subfoldersEnabled = true; bool removeSuffixEnabled = true; if (libraryDetailsWidget()->libraryPathChooser->isValid()) { @@ -797,13 +799,13 @@ QString NonInternalLibraryDetailsController::snippet() const QString libName; const bool removeSuffix = isWindowsGroupVisible() && libraryDetailsWidget()->removeSuffixCheckBox->isChecked(); - if (libraryPlatformType() == Utils::OsTypeWindows) { + if (libraryPlatformType() == OsTypeWindows) { libName = fi.completeBaseName(); if (removeSuffix && !libName.isEmpty()) // remove last letter which needs to be "d" libName = libName.left(libName.size() - 1); if (fi.completeSuffix() == QLatin1String("a")) // the mingw lib case libName = libName.mid(3); // cut the "lib" prefix - } else if (libraryPlatformType() == Utils::OsTypeMac) { + } else if (libraryPlatformType() == OsTypeMac) { if (macLibraryType() == AddLibraryWizard::FrameworkType) libName = fi.completeBaseName(); else @@ -817,7 +819,7 @@ QString NonInternalLibraryDetailsController::snippet() const if (isWindowsGroupVisible()) { // when we are on Win but we don't generate the code for Win // we still need to remove "debug" or "release" subfolder - const bool useSubfoldersCondition = (libraryPlatformType() == Utils::OsTypeWindows) + const bool useSubfoldersCondition = (libraryPlatformType() == OsTypeWindows) ? true : platforms() & (AddLibraryWizard::WindowsMinGWPlatform | AddLibraryWizard::WindowsMSVCPlatform); if (useSubfoldersCondition) @@ -829,10 +831,10 @@ QString NonInternalLibraryDetailsController::snippet() const QString targetRelativePath; QString includeRelativePath; if (isIncludePathVisible()) { // generate also the path to lib - QFileInfo pfi(proFile()); + QFileInfo pfi = proFile().toFileInfo(); QDir pdir = pfi.absoluteDir(); QString absoluteLibraryPath = fi.absolutePath(); - if (libraryPlatformType() == Utils::OsTypeWindows && useSubfolders) { // drop last subfolder which needs to be "debug" or "release" + if (libraryPlatformType() == OsTypeWindows && useSubfolders) { // drop last subfolder which needs to be "debug" or "release" QFileInfo libfi(absoluteLibraryPath); absoluteLibraryPath = libfi.absolutePath(); } @@ -862,7 +864,7 @@ QString NonInternalLibraryDetailsController::snippet() const PackageLibraryDetailsController::PackageLibraryDetailsController( Ui::LibraryDetailsWidget *libraryDetails, - const QString &proFile, QObject *parent) + const FilePath &proFile, QObject *parent) : NonInternalLibraryDetailsController(libraryDetails, proFile, parent) { setPlatformsVisible(false); @@ -897,11 +899,11 @@ QString PackageLibraryDetailsController::snippet() const bool PackageLibraryDetailsController::isLinkPackageGenerated() const { - const Project *project = SessionManager::projectForFile(Utils::FilePath::fromString(proFile())); + const Project *project = SessionManager::projectForFile(proFile()); if (!project) return false; - const ProjectNode *projectNode = project->findNodeForBuildKey(proFile()); + const ProjectNode *projectNode = project->findNodeForBuildKey(proFile().toString()); if (!projectNode) return false; @@ -921,7 +923,7 @@ bool PackageLibraryDetailsController::isLinkPackageGenerated() const SystemLibraryDetailsController::SystemLibraryDetailsController( Ui::LibraryDetailsWidget *libraryDetails, - const QString &proFile, QObject *parent) + const FilePath &proFile, QObject *parent) : NonInternalLibraryDetailsController(libraryDetails, proFile, parent) { setIncludePathVisible(false); @@ -934,7 +936,7 @@ SystemLibraryDetailsController::SystemLibraryDetailsController( ExternalLibraryDetailsController::ExternalLibraryDetailsController( Ui::LibraryDetailsWidget *libraryDetails, - const QString &proFile, QObject *parent) + const FilePath &proFile, QObject *parent) : NonInternalLibraryDetailsController(libraryDetails, proFile, parent) { setIncludePathVisible(true); @@ -949,7 +951,7 @@ void ExternalLibraryDetailsController::updateWindowsOptionsEnablement() bool subfoldersEnabled = true; bool removeSuffixEnabled = true; - if (libraryPlatformType() == Utils::OsTypeWindows + if (libraryPlatformType() == OsTypeWindows && libraryDetailsWidget()->libraryPathChooser->isValid()) { QFileInfo fi(libraryDetailsWidget()->libraryPathChooser->filePath().toString()); QFileInfo dfi(fi.absolutePath()); @@ -968,9 +970,8 @@ void ExternalLibraryDetailsController::updateWindowsOptionsEnablement() ///////////// -InternalLibraryDetailsController::InternalLibraryDetailsController( - Ui::LibraryDetailsWidget *libraryDetails, - const QString &proFile, QObject *parent) +InternalLibraryDetailsController::InternalLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails, + const FilePath &proFile, QObject *parent) : LibraryDetailsController(libraryDetails, proFile, parent) { setLinkageRadiosVisible(false); @@ -980,7 +981,7 @@ InternalLibraryDetailsController::InternalLibraryDetailsController( setWindowsGroupVisible(true); setRemoveSuffixVisible(false); - if (Utils::HostOsInfo::isWindowsHost()) + if (HostOsInfo::isWindowsHost()) libraryDetailsWidget()->useSubfoldersCheckBox->setEnabled(true); connect(libraryDetailsWidget()->libraryComboBox, @@ -1034,7 +1035,7 @@ QString InternalLibraryDetailsController::suggestedIncludePath() const void InternalLibraryDetailsController::updateWindowsOptionsEnablement() { - if (Utils::HostOsInfo::isWindowsHost()) + if (HostOsInfo::isWindowsHost()) libraryDetailsWidget()->addSuffixCheckBox->setEnabled(true); libraryDetailsWidget()->winGroupBox->setEnabled(platforms() & (AddLibraryWizard::WindowsMinGWPlatform | AddLibraryWizard::WindowsMSVCPlatform)); @@ -1047,7 +1048,7 @@ void InternalLibraryDetailsController::updateProFile() libraryDetailsWidget()->libraryComboBox->clear(); const QmakeProject *project - = dynamic_cast(SessionManager::projectForFile(Utils::FilePath::fromString(proFile()))); + = dynamic_cast(SessionManager::projectForFile(proFile())); if (!project) return; @@ -1091,7 +1092,7 @@ void InternalLibraryDetailsController::slotCurrentLibraryChanged() currentIndex, Qt::ToolTipRole).toString()); QmakeProFile *proFile = m_proFiles.at(currentIndex); const QStringList configVar = proFile->variableValue(Variable::Config); - if (Utils::HostOsInfo::isWindowsHost()) { + if (HostOsInfo::isWindowsHost()) { bool useSubfolders = false; if (configVar.contains(QLatin1String("debug_and_release")) && configVar.contains(QLatin1String("debug_and_release_target"))) @@ -1130,10 +1131,10 @@ QString InternalLibraryDetailsController::snippet() const // relative path for the project for which we insert the snippet, // it's relative to the root project - const QString proRelavitePath = rootDir.relativeFilePath(proFile()); + const QString proRelavitePath = rootDir.relativeFilePath(proFile().toString()); // project for which we insert the snippet - const Project *project = SessionManager::projectForFile(Utils::FilePath::fromString(proFile())); + const Project *project = SessionManager::projectForFile(proFile()); // the build directory of the active build configuration QDir rootBuildDir = rootDir; // If the project is unconfigured use the project dir @@ -1147,7 +1148,7 @@ QString InternalLibraryDetailsController::snippet() const QDir projectBuildDir(pfi.absolutePath()); // current project node from combobox - QFileInfo fi(proFile()); + QFileInfo fi = proFile().toFileInfo(); QDir projectSrcDir(fi.absolutePath()); // project node which we want to link against @@ -1175,3 +1176,6 @@ QString InternalLibraryDetailsController::snippet() const useSubfolders, addSuffix); return snippetMessage; } + +} // Internal +} // QmakeProjectManager diff --git a/src/plugins/qmakeprojectmanager/librarydetailscontroller.h b/src/plugins/qmakeprojectmanager/librarydetailscontroller.h index 70d64757ed7..4e7571adbf8 100644 --- a/src/plugins/qmakeprojectmanager/librarydetailscontroller.h +++ b/src/plugins/qmakeprojectmanager/librarydetailscontroller.h @@ -38,7 +38,7 @@ class LibraryDetailsController : public QObject Q_OBJECT public: explicit LibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails, - const QString &proFile, + const Utils::FilePath &proFile, QObject *parent = nullptr); virtual bool isComplete() const = 0; virtual QString snippet() const = 0; @@ -54,7 +54,7 @@ protected: AddLibraryWizard::MacLibraryType macLibraryType() const; Utils::OsType libraryPlatformType() const; QString libraryPlatformFilter() const; - QString proFile() const; + Utils::FilePath proFile() const; bool isIncludePathChanged() const; bool guiSignalsIgnored() const; @@ -99,7 +99,7 @@ private: AddLibraryWizard::LinkageType m_linkageType = AddLibraryWizard::NoLinkage; AddLibraryWizard::MacLibraryType m_macLibraryType = AddLibraryWizard::NoLibraryType; - QString m_proFile; + Utils::FilePath m_proFile; bool m_ignoreGuiSignals = false; bool m_includePathChanged = false; @@ -118,7 +118,7 @@ class NonInternalLibraryDetailsController : public LibraryDetailsController Q_OBJECT public: explicit NonInternalLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails, - const QString &proFile, + const Utils::FilePath &proFile, QObject *parent = nullptr); bool isComplete() const override; QString snippet() const override; @@ -143,7 +143,7 @@ class PackageLibraryDetailsController : public NonInternalLibraryDetailsControll Q_OBJECT public: explicit PackageLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails, - const QString &proFile, + const Utils::FilePath &proFile, QObject *parent = nullptr); bool isComplete() const override; QString snippet() const override; @@ -160,7 +160,7 @@ class SystemLibraryDetailsController : public NonInternalLibraryDetailsControlle Q_OBJECT public: explicit SystemLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails, - const QString &proFile, + const Utils::FilePath &proFile, QObject *parent = nullptr); protected: void updateWindowsOptionsEnablement() override final { @@ -173,7 +173,7 @@ class ExternalLibraryDetailsController : public NonInternalLibraryDetailsControl Q_OBJECT public: explicit ExternalLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails, - const QString &proFile, + const Utils::FilePath &proFile, QObject *parent = nullptr); protected: void updateWindowsOptionsEnablement() override final; @@ -184,7 +184,7 @@ class InternalLibraryDetailsController : public LibraryDetailsController Q_OBJECT public: explicit InternalLibraryDetailsController(Ui::LibraryDetailsWidget *libraryDetails, - const QString &proFile, + const Utils::FilePath &proFile, QObject *parent = nullptr); bool isComplete() const override; QString snippet() const override; diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp index 603f683f304..3268d16a529 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp @@ -73,6 +73,7 @@ using namespace Core; using namespace ProjectExplorer; using namespace TextEditor; +using namespace Utils; namespace QmakeProjectManager { namespace Internal { @@ -90,7 +91,7 @@ public: void buildStateChanged(Project *pro); void updateBuildFileAction(); void disableBuildFileMenus(); - void enableBuildFileMenus(const Utils::FilePath &file); + void enableBuildFileMenus(const FilePath &file); Core::Context projectContext; @@ -114,15 +115,15 @@ public: QAction *m_runQMakeAction = nullptr; QAction *m_runQMakeActionContextMenu = nullptr; - Utils::ParameterAction *m_buildSubProjectContextMenu = nullptr; + ParameterAction *m_buildSubProjectContextMenu = nullptr; QAction *m_subProjectRebuildSeparator = nullptr; QAction *m_rebuildSubProjectContextMenu = nullptr; QAction *m_cleanSubProjectContextMenu = nullptr; QAction *m_buildFileContextMenu = nullptr; - Utils::ParameterAction *m_buildSubProjectAction = nullptr; + ParameterAction *m_buildSubProjectAction = nullptr; QAction *m_rebuildSubProjectAction = nullptr; QAction *m_cleanSubProjectAction = nullptr; - Utils::ParameterAction *m_buildFileAction = nullptr; + ParameterAction *m_buildFileAction = nullptr; QAction *m_addLibraryAction = nullptr; QAction *m_addLibraryActionContextMenu = nullptr; @@ -140,7 +141,7 @@ public: void buildFile(); void handleSubDirContextMenu(QmakeBuildSystem::Action action, bool isFileBuild); - void addLibraryImpl(const QString &fileName, TextEditor::BaseTextEditor *editor); + void addLibraryImpl(const FilePath &filePath, TextEditor::BaseTextEditor *editor); void runQMakeImpl(Project *p, ProjectExplorer::Node *node); }; @@ -181,8 +182,8 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString //register actions Command *command = nullptr; - d->m_buildSubProjectContextMenu = new Utils::ParameterAction(tr("Build"), tr("Build \"%1\""), - Utils::ParameterAction::AlwaysEnabled/*handled manually*/, + d->m_buildSubProjectContextMenu = new ParameterAction(tr("Build"), tr("Build \"%1\""), + ParameterAction::AlwaysEnabled/*handled manually*/, this); command = ActionManager::registerAction(d->m_buildSubProjectContextMenu, Constants::BUILDSUBDIRCONTEXTMENU, projectContext); command->setAttribute(Command::CA_Hide); @@ -227,8 +228,8 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString connect(d->m_buildFileContextMenu, &QAction::triggered, d, &QmakeProjectManagerPluginPrivate::buildFileContextMenu); - d->m_buildSubProjectAction = new Utils::ParameterAction(tr("Build &Subproject"), tr("Build &Subproject \"%1\""), - Utils::ParameterAction::AlwaysEnabled, this); + d->m_buildSubProjectAction = new ParameterAction(tr("Build &Subproject"), tr("Build &Subproject \"%1\""), + ParameterAction::AlwaysEnabled, this); command = ActionManager::registerAction(d->m_buildSubProjectAction, Constants::BUILDSUBDIR, projectContext); command->setAttribute(Command::CA_Hide); command->setAttribute(Command::CA_UpdateText); @@ -244,8 +245,7 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString connect(d->m_runQMakeAction, &QAction::triggered, d, &QmakeProjectManagerPluginPrivate::runQMake); - d->m_rebuildSubProjectAction = new QAction(Icons::REBUILD.icon(), tr("Rebuild"), - this); + d->m_rebuildSubProjectAction = new QAction(ProjectExplorer::Icons::REBUILD.icon(), tr("Rebuild"), this); d->m_rebuildSubProjectAction->setWhatsThis(tr("Rebuild Subproject")); command = ActionManager::registerAction(d->m_rebuildSubProjectAction, Constants::REBUILDSUBDIR, projectContext); command->setAttribute(Command::CA_Hide); @@ -265,8 +265,8 @@ bool QmakeProjectManagerPlugin::initialize(const QStringList &arguments, QString connect(d->m_cleanSubProjectAction, &QAction::triggered, d, &QmakeProjectManagerPluginPrivate::cleanSubDirContextMenu); - d->m_buildFileAction = new Utils::ParameterAction(tr("Build File"), tr("Build File \"%1\""), - Utils::ParameterAction::AlwaysEnabled, this); + d->m_buildFileAction = new ParameterAction(tr("Build File"), tr("Build File \"%1\""), + ParameterAction::AlwaysEnabled, this); command = ActionManager::registerAction(d->m_buildFileAction, Constants::BUILDFILE, projectContext); command->setAttribute(Command::CA_Hide); command->setAttribute(Command::CA_UpdateText); @@ -361,33 +361,33 @@ static QmakeProFileNode *buildableFileProFile(Node *node) void QmakeProjectManagerPluginPrivate::addLibrary() { if (auto editor = qobject_cast(Core::EditorManager::currentEditor())) - addLibraryImpl(editor->document()->filePath().toString(), editor); + addLibraryImpl(editor->document()->filePath(), editor); } void QmakeProjectManagerPluginPrivate::addLibraryContextMenu() { - QString projectPath; + FilePath projectPath; Node *node = ProjectTree::currentNode(); if (ContainerNode *cn = node->asContainerNode()) - projectPath = cn->project()->projectFilePath().toString(); + projectPath = cn->project()->projectFilePath(); else if (dynamic_cast(node)) - projectPath = node->filePath().toString(); + projectPath = node->filePath(); addLibraryImpl(projectPath, nullptr); } -void QmakeProjectManagerPluginPrivate::addLibraryImpl(const QString &fileName, BaseTextEditor *editor) +void QmakeProjectManagerPluginPrivate::addLibraryImpl(const FilePath &filePath, BaseTextEditor *editor) { - if (fileName.isEmpty()) + if (filePath.isEmpty()) return; - Internal::AddLibraryWizard wizard(fileName, Core::ICore::dialogParent()); + Internal::AddLibraryWizard wizard(filePath, Core::ICore::dialogParent()); if (wizard.exec() != QDialog::Accepted) return; if (!editor) - editor = qobject_cast(Core::EditorManager::openEditor(fileName, + editor = qobject_cast(Core::EditorManager::openEditor(filePath, Constants::PROFILE_EDITOR_ID, Core::EditorManager::DoNotMakeVisible)); if (!editor) return; @@ -448,7 +448,7 @@ void QmakeProjectManagerPluginPrivate::buildFile() if (!currentDocument) return; - const Utils::FilePath file = currentDocument->filePath(); + const FilePath file = currentDocument->filePath(); Node *n = ProjectTree::nodeForFile(file); FileNode *node = n ? n->asFileNode() : nullptr; if (!node) @@ -599,7 +599,7 @@ void QmakeProjectManagerPluginPrivate::disableBuildFileMenus() m_buildFileContextMenu->setEnabled(false); } -void QmakeProjectManagerPluginPrivate::enableBuildFileMenus(const Utils::FilePath &file) +void QmakeProjectManagerPluginPrivate::enableBuildFileMenus(const FilePath &file) { bool visible = false; bool enabled = false; diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index 5292c2f1999..d4528893637 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -58,6 +58,7 @@ #include #include #include +#include #include @@ -241,6 +242,56 @@ ModelNodePreviewImageOperation DesignerActionManager::modelNodePreviewOperation( return op; } +bool DesignerActionManager::externalDragHasSupportedAssets(const QMimeData *mimeData) const +{ + if (!mimeData->hasUrls()) + return false; + + QSet filtersSet; + const QList handlers = addResourceHandler(); + for (const AddResourceHandler &handler : handlers) + filtersSet.insert(handler.filter); + + const QList urls = mimeData->urls(); + for (const QUrl &url : urls) { + QString suffix = "*." + url.fileName().split('.').last().toLower(); + if (filtersSet.contains(suffix)) // accept drop if it contains a valid file + return true; + } + + return false; +} + +void DesignerActionManager::handleExternalAssetsDrop(const QMimeData *mimeData) const +{ + const QList handlers = addResourceHandler(); + // create suffix to categry and category to operation hashes + QHash suffixCategory; + QHash categoryOperation; + for (const AddResourceHandler &handler : handlers) { + suffixCategory.insert(handler.filter, handler.category); + categoryOperation.insert(handler.category, handler.operation); + } + + // add files grouped by categories (so that files under same category run under 1 operation) + QHash categoryFiles; + const QList urls = mimeData->urls(); + for (const QUrl &url : urls) { + QString suffix = "*." + url.fileName().split('.').last().toLower(); + QString category = suffixCategory.value(suffix); + if (!category.isEmpty()) + categoryFiles[category].append(url.toLocalFile()); + } + + // run operations + const QStringList categories = categoryFiles.keys(); + for (const QString &category : categories) { + AddResourceOperation operation = categoryOperation.value(category); + QStringList files = categoryFiles.value(category); + operation(files, {}); + } +} + class VisiblityModelNodeAction : public ModelNodeContextMenuAction { public: diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h index 36253fc4453..e0fe93f601d 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.h @@ -38,6 +38,7 @@ QT_BEGIN_NAMESPACE class QGraphicsItem; class QGraphicsWidget; +class QMimeData; QT_END_NAMESPACE namespace QmlDesigner { @@ -135,6 +136,8 @@ public: void registerModelNodePreviewHandler(const ModelNodePreviewImageHandler &handler); bool hasModelNodePreviewHandler(const ModelNode &node) const; ModelNodePreviewImageOperation modelNodePreviewOperation(const ModelNode &node) const; + bool externalDragHasSupportedAssets(const QMimeData *data) const; + void handleExternalAssetsDrop(const QMimeData *data) const; private: void addTransitionEffectAction(const TypeName &typeName); diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp index 23623ae3095..acc77acf0a5 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp @@ -81,6 +81,18 @@ void CurveEditor::clearCanvas() m_view->reset({}); } +void CurveEditor::showEvent(QShowEvent *event) +{ + emit viewEnabledChanged(true); + QWidget::showEvent(event); +} + +void CurveEditor::hideEvent(QHideEvent *event) +{ + emit viewEnabledChanged(false); + QWidget::hideEvent(event); +} + QToolBar *CurveEditor::createToolBar(CurveEditorModel *model) { auto *bar = new QToolBar; diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditor.h b/src/plugins/qmldesigner/components/curveeditor/curveeditor.h index f248a0ed080..e297e31a9bc 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditor.h +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditor.h @@ -49,6 +49,13 @@ public: void clearCanvas(); +signals: + void viewEnabledChanged(const bool); + +protected: + void showEvent(QShowEvent *event) override; + void hideEvent(QHideEvent *event) override; + private: QToolBar *createToolBar(CurveEditorModel *model); diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp index 5172d10d8db..bddb6536c7c 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.cpp @@ -51,6 +51,13 @@ CurveEditorView::CurveEditorView(QObject *parent) connect(m_model, &CurveEditorModel::commitStartFrame, this, &CurveEditorView::commitStartFrame); connect(m_model, &CurveEditorModel::commitEndFrame, this, &CurveEditorView::commitEndFrame); connect(m_model, &CurveEditorModel::curveChanged, this, &CurveEditorView::commitKeyframes); + + connect(m_editor, &CurveEditor::viewEnabledChanged, this, [this](bool enabled){ + setEnabled(enabled); + if (enabled) + init(); + }); + setEnabled(false); } CurveEditorView::~CurveEditorView() {} @@ -70,10 +77,8 @@ void CurveEditorView::modelAttached(Model *model) { AbstractView::modelAttached(model); - QmlTimeline timeline = activeTimeline(); - if (timeline.isValid()) { - m_model->setTimeline(timeline); - } + if (isEnabled()) + init(); } void CurveEditorView::modelAboutToBeDetached(Model *model) @@ -389,4 +394,13 @@ void CurveEditorView::commitEndFrame(int frame) timeline.modelNode().variantProperty("endFrame").setValue(frame); } +void CurveEditorView::init() +{ + QmlTimeline timeline = activeTimeline(); + if (timeline.isValid()) { + m_model->setTimeline(timeline); + } + +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.h b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.h index e774d2bc434..cdfc762191a 100644 --- a/src/plugins/qmldesigner/components/curveeditor/curveeditorview.h +++ b/src/plugins/qmldesigner/components/curveeditor/curveeditorview.h @@ -85,6 +85,7 @@ private: void commitCurrentFrame(int frame); void commitStartFrame(int frame); void commitEndFrame(int frame); + void init(); private: bool m_block; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index ec8a1a69d9b..025b6227893 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -40,6 +40,7 @@ #include #include +#include #include namespace QmlDesigner { @@ -47,6 +48,8 @@ namespace QmlDesigner { Edit3DWidget::Edit3DWidget(Edit3DView *view) : m_view(view) { + setAcceptDrops(true); + Core::Context context(Constants::C_QMLEDITOR3D); m_context = new Core::IContext(this); m_context->setContext(context); @@ -159,4 +162,19 @@ Edit3DView *Edit3DWidget::view() const return m_view.data(); } +void Edit3DWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent) +{ + const DesignerActionManager &actionManager = QmlDesignerPlugin::instance() + ->viewManager().designerActionManager(); + if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData())) + dragEnterEvent->acceptProposedAction(); } + +void Edit3DWidget::dropEvent(QDropEvent *dropEvent) +{ + const DesignerActionManager &actionManager = QmlDesignerPlugin::instance() + ->viewManager().designerActionManager(); + actionManager.handleExternalAssetsDrop(dropEvent->mimeData()); +} + +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h index ca44a955f5e..e7223ceb8c9 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h @@ -48,6 +48,10 @@ public: void showCanvas(bool show); +protected: + void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override; + void dropEvent(QDropEvent *dropEvent) override; + private: void linkActivated(const QString &link); diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp index b6716939f96..1f9fc4487b6 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp @@ -53,6 +53,7 @@ #include #include +#include #include #include #include @@ -63,6 +64,8 @@ namespace QmlDesigner { FormEditorWidget::FormEditorWidget(FormEditorView *view) : m_formEditorView(view) { + setAcceptDrops(true); + Core::Context context(Constants::C_QMLFORMEDITOR); m_context = new Core::IContext(this); m_context->setContext(context); @@ -582,4 +585,19 @@ void FormEditorWidget::showEvent(QShowEvent *event) } } +void FormEditorWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent) +{ + const DesignerActionManager &actionManager = QmlDesignerPlugin::instance() + ->viewManager().designerActionManager(); + if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData())) + dragEnterEvent->acceptProposedAction(); +} + +void FormEditorWidget::dropEvent(QDropEvent *dropEvent) +{ + const DesignerActionManager &actionManager = QmlDesignerPlugin::instance() + ->viewManager().designerActionManager(); + actionManager.handleExternalAssetsDrop(dropEvent->mimeData()); +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h index d0c1fa7c5ee..64b1e1a4eeb 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.h @@ -49,6 +49,7 @@ class QmlItemNode; class FormEditorWidget : public QWidget { Q_OBJECT + public: FormEditorWidget(FormEditorView *view); @@ -93,6 +94,8 @@ protected: DocumentWarningWidget *errorWidget(); void hideEvent(QHideEvent *event) override; void showEvent(QShowEvent *event) override; + void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override; + void dropEvent(QDropEvent *dropEvent) override; private: void changeTransformTool(bool checked); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.cpp index 2677eb94ae9..d351232e36b 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.cpp @@ -144,6 +144,17 @@ void ItemLibraryCategoriesModel::resetModel() endResetModel(); } +bool ItemLibraryCategoriesModel::isAllCategoriesHidden() const +{ + for (const auto &category : std::as_const(m_categoryList)) { + // ignore "All Other Components" as its categoryVisible is always true + if (category->isCategoryVisible() && category->categoryName() != "All Other Components") + return false; + } + + return true; +} + void ItemLibraryCategoriesModel::showAllCategories(bool show) { for (const auto &category : std::as_const(m_categoryList)) { @@ -153,9 +164,43 @@ void ItemLibraryCategoriesModel::showAllCategories(bool show) category->ownerImport()->importName()); } } + emit dataChanged(index(0), index(m_categoryList.size() - 1), {m_roleNames.key("categoryVisible")}); } +QObject *ItemLibraryCategoriesModel::selectFirstVisibleCategory() +{ + for (int i = 0; i < m_categoryList.length(); ++i) { + const auto category = m_categoryList.at(i); + + if (category->isCategoryVisible()) { + category->setCategorySelected(true); + emit dataChanged(index(i),index(i), {m_roleNames.key("categorySelected")}); + return category; + } + } + + return nullptr; +} + +void ItemLibraryCategoriesModel::clearSelectedCategories() +{ + for (const auto &category : std::as_const(m_categoryList)) + category->setCategorySelected(false); + + emit dataChanged(index(0), index(m_categoryList.size() - 1), {m_roleNames.key("categorySelected")}); +} + +void ItemLibraryCategoriesModel::selectCategory(int categoryIndex) +{ + const auto category = m_categoryList.at(categoryIndex); + if (!category->categorySelected()) { + clearSelectedCategories(); + category->setCategorySelected(true); + emit dataChanged(index(categoryIndex),index(categoryIndex), {m_roleNames.key("categorySelected")}); + } +} + void ItemLibraryCategoriesModel::addRoleNames() { int role = 0; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.h index 276d47ac480..9433af804f9 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategoriesmodel.h @@ -52,9 +52,13 @@ public: const QList> &categorySections() const; + bool isAllCategoriesHidden() const; void sortCategorySections(); void resetModel(); void showAllCategories(bool show = true); + void clearSelectedCategories(); + QObject *selectFirstVisibleCategory(); + void selectCategory(int categoryIndex); private: void addRoleNames(); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.cpp index 464f56ca103..0744b7b2b3f 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.cpp @@ -26,6 +26,7 @@ #include "itemlibrarycategory.h" #include "itemlibraryitem.h" +#include "itemlibrarywidget.h" namespace QmlDesigner { @@ -46,6 +47,11 @@ bool ItemLibraryCategory::categoryExpanded() const return m_categoryExpanded; } +bool ItemLibraryCategory::categorySelected() const +{ + return m_categorySelected; +} + QString ItemLibraryCategory::sortingName() const { if (ItemLibraryModel::categorySortingHash.contains(categoryName())) @@ -84,6 +90,10 @@ bool ItemLibraryCategory::updateItemVisibility(const QString &searchText, bool * hasVisibleItems = true; } + // update item model in horizontal view so search text matches item grid + if (ItemLibraryWidget::isHorizontalLayout) + m_itemModel.resetModel(); + // expand category if it has an item matching search criteria if (!searchText.isEmpty() && hasVisibleItems && !categoryExpanded()) setExpanded(true); @@ -124,4 +134,9 @@ void ItemLibraryCategory::setExpanded(bool expanded) m_categoryExpanded = expanded; } +void ItemLibraryCategory::setCategorySelected(bool selected) +{ + m_categorySelected = selected; +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.h index 6e5da446108..e1af69e5fa6 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarycategory.h @@ -39,6 +39,7 @@ class ItemLibraryCategory : public QObject Q_PROPERTY(QString categoryName READ categoryName FINAL) Q_PROPERTY(bool categoryVisible READ isCategoryVisible WRITE setCategoryVisible NOTIFY categoryVisibilityChanged FINAL) Q_PROPERTY(bool categoryExpanded READ categoryExpanded WRITE setExpanded NOTIFY expandedChanged FINAL) + Q_PROPERTY(bool categorySelected READ categorySelected WRITE setCategorySelected NOTIFY categorySelectedChanged FINAL) Q_PROPERTY(QObject *itemModel READ itemModel NOTIFY itemModelChanged FINAL) public: @@ -46,6 +47,7 @@ public: QString categoryName() const; bool categoryExpanded() const; + bool categorySelected() const; QString sortingName() const; void addItem(ItemLibraryItem *item); @@ -60,6 +62,7 @@ public: void sortItems(); void setExpanded(bool expanded); + void setCategorySelected(bool selected); ItemLibraryImport *ownerImport() const { return m_ownerImport; } @@ -68,6 +71,7 @@ signals: void visibilityChanged(); void expandedChanged(); void categoryVisibilityChanged(); + void categorySelectedChanged(); private: ItemLibraryItemsModel m_itemModel; @@ -75,6 +79,7 @@ private: QString m_name; bool m_categoryExpanded = true; bool m_isVisible = true; + bool m_categorySelected = false; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp index 76138ed0745..7e696e43ef4 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.cpp @@ -138,6 +138,26 @@ void ItemLibraryImport::showAllCategories(bool show) m_categoryModel.showAllCategories(show); } +void ItemLibraryImport::selectCategory(int categoryIndex) +{ + m_categoryModel.selectCategory(categoryIndex); +} + +QObject *ItemLibraryImport::selectFirstVisibleCategory() +{ + return m_categoryModel.selectFirstVisibleCategory(); +} + +void ItemLibraryImport::clearSelectedCategories() +{ + m_categoryModel.clearSelectedCategories(); +} + +bool ItemLibraryImport::isAllCategoriesHidden() const +{ + return m_categoryModel.isAllCategoriesHidden(); +} + Import ItemLibraryImport::importEntry() const { return m_import; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.h index 81717439f9a..f5a1cd02791 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryimport.h @@ -68,6 +68,7 @@ public: bool importCatVisibleState() const; bool hasCategories() const; bool hasSingleCategory() const; + bool isAllCategoriesHidden() const; ItemLibraryCategory *getCategorySection(const QString &categoryName) const; void addCategory(ItemLibraryCategory *category); @@ -80,6 +81,9 @@ public: void setImportCatVisibleState(bool show); void expandCategories(bool expand = true); void showAllCategories(bool show = true); + void selectCategory(int categoryIndex); + QObject *selectFirstVisibleCategory(); + void clearSelectedCategories(); static QString userComponentsTitle(); static QString quick3DAssetsTitle(); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp index 85d367fb77c..ebef71f63f5 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.cpp @@ -90,6 +90,40 @@ bool ItemLibraryModel::getIsAnyCategoryHidden() const return false; } +void ItemLibraryModel::selectImportCategory(const QString importUrl, int categoryIndex) +{ + ItemLibraryImport *selectedCategoryImport = importByUrl(importUrl); + + for (int i = 0; i < m_importList.length(); ++i) { + const auto importToSelect = m_importList.at(i); + + if (selectedCategoryImport == importToSelect) + importToSelect->selectCategory(categoryIndex); + else + importToSelect->clearSelectedCategories(); + } +} + +bool ItemLibraryModel::isAllCategoriesHidden() const +{ + for (int i = 0; i < m_importList.length(); ++i) { + if (!m_importList.at(i)->isAllCategoriesHidden()) + return false; + } + + return true; +} + +QObject *ItemLibraryModel::selectImportFirstVisibleCategory() +{ + for (const QPointer &import : std::as_const(m_importList)) { + if (!import->isAllCategoriesHidden()) + return import->selectFirstVisibleCategory(); + } + + return nullptr; +} + bool ItemLibraryModel::isAnyCategoryHidden() const { return m_isAnyCategoryHidden; diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h index f2e5786f302..ad9803821ff 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarymodel.h @@ -77,6 +77,9 @@ public: Q_INVOKABLE void collapseAll(); Q_INVOKABLE void showHiddenCategories(); Q_INVOKABLE bool getIsAnyCategoryHidden() const; + Q_INVOKABLE void selectImportCategory(const QString importUrl, int categoryIndex); + Q_INVOKABLE QObject *selectImportFirstVisibleCategory(); + Q_INVOKABLE bool isAllCategoriesHidden() const; Import entryToImport(const ItemLibraryEntry &entry); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 3c8a76597bd..de15fde7cf3 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -143,6 +143,11 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event) return QObject::eventFilter(obj, event); } +void ItemLibraryWidget::resizeEvent(QResizeEvent *event) +{ + isHorizontalLayout = event->size().width() >= HORIZONTAL_LAYOUT_WIDTH_LIMIT; +} + ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache, AsynchronousImageCache &asynchronousFontImageCache, SynchronousImageCache &synchronousFontImageCache) @@ -196,6 +201,7 @@ ItemLibraryWidget::ItemLibraryWidget(AsynchronousImageCache &imageCache, {{"itemLibraryIconWidth"}, m_itemIconSize.width()}, {{"itemLibraryIconHeight"}, m_itemIconSize.height()}, {{"rootView"}, QVariant::fromValue(this)}, + {{"widthLimit"}, HORIZONTAL_LAYOUT_WIDTH_LIMIT}, {{"highlightColor"}, Utils::StyleHelper::notTooBrightHighlightColor()}, }); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h index 4910fedc182..6695c01da5a 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h @@ -92,6 +92,8 @@ public: void setFlowMode(bool b); static QPair getAssetTypeAndData(const QString &assetPath); + inline static bool isHorizontalLayout = false; + Q_INVOKABLE void startDragAndDrop(const QVariant &itemLibEntry, const QPointF &mousePos); Q_INVOKABLE void startDragAsset(const QStringList &assetPaths, const QPointF &mousePos); Q_INVOKABLE void removeImport(const QString &importUrl); @@ -110,6 +112,7 @@ signals: protected: bool eventFilter(QObject *obj, QEvent *event) override; + void resizeEvent(QResizeEvent *event) override; private: void reloadQmlSource(); @@ -149,6 +152,8 @@ private: bool m_updateRetry = false; QString m_filterText; QPoint m_dragStartPoint; + + inline static int HORIZONTAL_LAYOUT_WIDTH_LIMIT = 600; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp b/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp index 453865966be..4e77b7d4b1d 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorwidget.cpp @@ -49,6 +49,8 @@ NavigatorWidget::NavigatorWidget(NavigatorView *view) : m_treeView(new NavigatorTreeView) , m_navigatorView(view) { + setAcceptDrops(true); + m_treeView->setDragEnabled(true); m_treeView->setAcceptDrops(true); m_treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); @@ -184,4 +186,19 @@ NavigatorView *NavigatorWidget::navigatorView() const return m_navigatorView.data(); } +void NavigatorWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent) +{ + const DesignerActionManager &actionManager = QmlDesignerPlugin::instance() + ->viewManager().designerActionManager(); + if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData())) + dragEnterEvent->acceptProposedAction(); +} + +void NavigatorWidget::dropEvent(QDropEvent *dropEvent) +{ + const DesignerActionManager &actionManager = QmlDesignerPlugin::instance() + ->viewManager().designerActionManager(); + actionManager.handleExternalAssetsDrop(dropEvent->mimeData()); +} + } diff --git a/src/plugins/qmldesigner/components/navigator/navigatorwidget.h b/src/plugins/qmldesigner/components/navigator/navigatorwidget.h index 9c1c962c435..d8dc0938566 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorwidget.h +++ b/src/plugins/qmldesigner/components/navigator/navigatorwidget.h @@ -43,6 +43,7 @@ class NavigatorView; class NavigatorWidget: public QFrame { Q_OBJECT + public: NavigatorWidget(NavigatorView *view); @@ -63,10 +64,13 @@ signals: void filterToggled(bool); void reverseOrderToggled(bool); -private: // functions +protected: + void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override; + void dropEvent(QDropEvent *dropEvent) override; + +private: NavigatorView *navigatorView() const; -private: // variables NavigatorTreeView *m_treeView; QPointer m_navigatorView; }; diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp b/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp index b8747f7102d..6f45bbb5636 100644 --- a/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp +++ b/src/plugins/qmldesigner/components/texteditor/texteditorwidget.cpp @@ -53,6 +53,8 @@ TextEditorWidget::TextEditorWidget(TextEditorView *textEditorView) , m_textEditorView(textEditorView) , m_statusBar(new TextEditorStatusBar(this)) { + setAcceptDrops(true); + QBoxLayout *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); @@ -179,7 +181,7 @@ void TextEditorWidget::setBlockCursorSelectionSynchronisation(bool b) m_blockCursorSelectionSynchronisation = b; } -bool TextEditorWidget::eventFilter( QObject *, QEvent *event) +bool TextEditorWidget::eventFilter(QObject *, QEvent *event) { static std::vector overrideKeys = { Qt::Key_Delete, Qt::Key_Backspace, Qt::Key_Insert, Qt::Key_Escape }; @@ -216,5 +218,19 @@ bool TextEditorWidget::eventFilter( QObject *, QEvent *event) return false; } +void TextEditorWidget::dragEnterEvent(QDragEnterEvent *dragEnterEvent) +{ + const DesignerActionManager &actionManager = QmlDesignerPlugin::instance() + ->viewManager().designerActionManager(); + if (actionManager.externalDragHasSupportedAssets(dragEnterEvent->mimeData())) + dragEnterEvent->acceptProposedAction(); +} + +void TextEditorWidget::dropEvent(QDropEvent *dropEvent) +{ + const DesignerActionManager &actionManager = QmlDesignerPlugin::instance() + ->viewManager().designerActionManager(); + actionManager.handleExternalAssetsDrop(dropEvent->mimeData()); +} } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/texteditor/texteditorwidget.h b/src/plugins/qmldesigner/components/texteditor/texteditorwidget.h index 8f0ba40e47f..96a8361069f 100644 --- a/src/plugins/qmldesigner/components/texteditor/texteditorwidget.h +++ b/src/plugins/qmldesigner/components/texteditor/texteditorwidget.h @@ -63,6 +63,8 @@ public: protected: bool eventFilter(QObject *object, QEvent *event) override; + void dragEnterEvent(QDragEnterEvent *dragEnterEvent) override; + void dropEvent(QDropEvent *dropEvent) override; private: void updateSelectionByCursorPosition(); diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp index cb9ed8f0cd4..1f1bef923d5 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelineview.cpp @@ -71,6 +71,7 @@ TimelineView::TimelineView(QObject *parent) , m_timelineWidget(nullptr) { EasingCurve::registerStreamOperators(); + setEnabled(false); } TimelineView::~TimelineView() = default; diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp index 149d1fd7e97..b583863015f 100644 --- a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp +++ b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp @@ -606,13 +606,7 @@ void TimelineWidget::showEvent(QShowEvent *event) { Q_UNUSED(event) - /* m_timelineView->setEnabled(true); - TODO See QDS-4191 - */ - - if (m_timelineView->model()) - init(); graphicsScene()->setWidth(m_graphicsView->viewport()->width()); graphicsScene()->invalidateLayout(); @@ -620,6 +614,10 @@ void TimelineWidget::showEvent(QShowEvent *event) graphicsScene()->onShow(); QWidget::showEvent(event); + + //All the events have to be fully processed before we call init() + if (m_timelineView->model()) + QTimer::singleShot(0, [this]() { init(); }); } void TimelineWidget::resizeEvent(QResizeEvent *event) @@ -630,7 +628,7 @@ void TimelineWidget::resizeEvent(QResizeEvent *event) void TimelineWidget::hideEvent(QHideEvent *event) { - /* m_timelineView->setEnabled(false); TODO See QDS-4191 */ + m_timelineView->setEnabled(false); QWidget::hideEvent(event); } diff --git a/src/plugins/qnx/qnxbaseqtconfigwidget.cpp b/src/plugins/qnx/qnxbaseqtconfigwidget.cpp index 056dfa9cedf..7ac289c9bf5 100644 --- a/src/plugins/qnx/qnxbaseqtconfigwidget.cpp +++ b/src/plugins/qnx/qnxbaseqtconfigwidget.cpp @@ -33,30 +33,28 @@ #include #include +using namespace Utils; + namespace Qnx { namespace Internal { QnxBaseQtConfigWidget::QnxBaseQtConfigWidget(QnxQtVersion *version) : m_version(version), - m_sdpPathChooser(new Utils::PathChooser) + m_sdpPathChooser(new PathChooser) { QTC_ASSERT(version, return); auto layout = new QHBoxLayout(this); layout->addWidget(m_sdpPathChooser); - m_sdpPathChooser->setExpectedKind(Utils::PathChooser::ExistingDirectory); - m_sdpPathChooser->setHistoryCompleter(QLatin1String("Qnx.Sdp.History")); - m_sdpPathChooser->setPath(version->sdpPath()); + m_sdpPathChooser->setExpectedKind(PathChooser::ExistingDirectory); + m_sdpPathChooser->setHistoryCompleter("Qnx.Sdp.History"); + m_sdpPathChooser->setFilePath(version->sdpPath()); - connect(m_sdpPathChooser, &Utils::PathChooser::rawPathChanged, - this, &QnxBaseQtConfigWidget::updateSdpPath); -} - -void QnxBaseQtConfigWidget::updateSdpPath(const QString &path) -{ - m_version->setSdpPath(path); - emit changed(); + connect(m_sdpPathChooser, &PathChooser::rawPathChanged, [this] { + m_version->setSdpPath(m_sdpPathChooser->filePath()); + emit changed(); + }); } } // namespace Internal diff --git a/src/plugins/qnx/qnxbaseqtconfigwidget.h b/src/plugins/qnx/qnxbaseqtconfigwidget.h index 28428144a71..1ab1a9d16e5 100644 --- a/src/plugins/qnx/qnxbaseqtconfigwidget.h +++ b/src/plugins/qnx/qnxbaseqtconfigwidget.h @@ -27,7 +27,10 @@ #include -namespace Utils { class PathChooser; } +namespace Utils { +class PathChooser; +class FilePath; +} // Utils namespace Qnx { namespace Internal { @@ -41,9 +44,6 @@ class QnxBaseQtConfigWidget : public QtSupport::QtConfigWidget public: explicit QnxBaseQtConfigWidget(QnxQtVersion *version); -private slots: - void updateSdpPath(const QString &path); - private: QnxQtVersion *m_version; Utils::PathChooser *m_sdpPathChooser; diff --git a/src/plugins/qnx/qnxconfiguration.cpp b/src/plugins/qnx/qnxconfiguration.cpp index 33af0f3ecb8..706551360b4 100644 --- a/src/plugins/qnx/qnxconfiguration.cpp +++ b/src/plugins/qnx/qnxconfiguration.cpp @@ -225,7 +225,7 @@ QnxQtVersion *QnxConfiguration::qnxQtVersion(const Target &target) const QtVersionManager::instance()->versions(Utils::equal(&BaseQtVersion::type, QString::fromLatin1(Constants::QNX_QNX_QT)))) { auto qnxQt = dynamic_cast(version); - if (qnxQt && FilePath::fromString(qnxQt->sdpPath()) == sdpPath()) { + if (qnxQt && qnxQt->sdpPath() == sdpPath()) { foreach (const Abi &qtAbi, version->qtAbis()) { if ((qtAbi == target.m_abi) && (qnxQt->cpuDir() == target.cpuDir())) return qnxQt; @@ -240,7 +240,7 @@ QList QnxConfiguration::autoDetect(const QList &alread { QList result; - foreach (const Target &target, m_targets) + for (const Target &target : qAsConst(m_targets)) result += findToolChain(alreadyKnown, target.m_abi); return result; @@ -286,7 +286,7 @@ QnxConfiguration::QnxToolChainMap QnxConfiguration::createToolChain(const Target "QCC for %1 (%2)") .arg(displayName()) .arg(target.shortDescription())); - toolChain->setSdpPath(sdpPath().toString()); + toolChain->setSdpPath(sdpPath()); toolChain->setCpuDir(target.cpuDir()); toolChain->resetToolChain(qccCompilerPath()); ToolChainManager::registerToolChain(toolChain); @@ -372,11 +372,11 @@ void QnxConfiguration::setVersion(const QnxVersionNumber &version) void QnxConfiguration::readInformation() { const QString qConfigPath = m_qnxConfiguration.pathAppended("qconfig").toString(); - QList installInfoList = QnxUtils::installedConfigs(qConfigPath); + const QList installInfoList = QnxUtils::installedConfigs(qConfigPath); if (installInfoList.isEmpty()) return; - foreach (const ConfigInstallInformation &info, installInfoList) { + for (const ConfigInstallInformation &info : installInfoList) { if (m_qnxHost == FilePath::fromString(info.host).canonicalPath() && m_qnxTarget == FilePath::fromString(info.target).canonicalPath()) { m_configName = info.name; @@ -386,11 +386,11 @@ void QnxConfiguration::readInformation() } } -void QnxConfiguration::setDefaultConfiguration(const Utils::FilePath &envScript) +void QnxConfiguration::setDefaultConfiguration(const FilePath &envScript) { QTC_ASSERT(!envScript.isEmpty(), return); m_envFile = envScript; - m_qnxEnv = QnxUtils::qnxEnvironmentFromEnvFile(m_envFile.toString()); + m_qnxEnv = QnxUtils::qnxEnvironmentFromEnvFile(m_envFile); foreach (const EnvironmentItem &item, m_qnxEnv) { if (item.name == QNXConfiguration) m_qnxConfiguration = FilePath::fromString(item.value).canonicalPath(); diff --git a/src/plugins/qnx/qnxqtversion.cpp b/src/plugins/qnx/qnxqtversion.cpp index 02dceac4a48..b0fcf300b35 100644 --- a/src/plugins/qnx/qnxqtversion.cpp +++ b/src/plugins/qnx/qnxqtversion.cpp @@ -109,14 +109,14 @@ QString QnxQtVersion::cpuDir() const QVariantMap QnxQtVersion::toMap() const { QVariantMap result = BaseQtVersion::toMap(); - result.insert(QLatin1String(SDP_PATH_KEY), sdpPath()); + result.insert(SDP_PATH_KEY, sdpPath().toVariant()); return result; } void QnxQtVersion::fromMap(const QVariantMap &map) { BaseQtVersion::fromMap(map); - setSdpPath(QDir::fromNativeSeparators(map.value(QLatin1String(SDP_PATH_KEY)).toString())); + setSdpPath(FilePath::fromVariant(map.value(SDP_PATH_KEY))); } Abis QnxQtVersion::detectQtAbis() const @@ -134,7 +134,7 @@ void QnxQtVersion::addToEnvironment(const Kit *k, Environment &env) const env.prependOrSetLibrarySearchPath(libraryPath().toString()); } -void QnxQtVersion::setupQmakeRunEnvironment(Utils::Environment &env) const +void QnxQtVersion::setupQmakeRunEnvironment(Environment &env) const { if (!sdpPath().isEmpty()) updateEnvironment(); @@ -160,12 +160,12 @@ QString QnxQtVersion::invalidReason() const return QtSupport::BaseQtVersion::invalidReason(); } -QString QnxQtVersion::sdpPath() const +FilePath QnxQtVersion::sdpPath() const { return m_sdpPath; } -void QnxQtVersion::setSdpPath(const QString &sdpPath) +void QnxQtVersion::setSdpPath(const FilePath &sdpPath) { if (m_sdpPath == sdpPath) return; diff --git a/src/plugins/qnx/qnxqtversion.h b/src/plugins/qnx/qnxqtversion.h index bd8876def20..637e9475f9f 100644 --- a/src/plugins/qnx/qnxqtversion.h +++ b/src/plugins/qnx/qnxqtversion.h @@ -63,15 +63,15 @@ public: bool isValid() const override; QString invalidReason() const override; - QString sdpPath() const; - void setSdpPath(const QString &sdpPath); + Utils::FilePath sdpPath() const; + void setSdpPath(const Utils::FilePath &sdpPath); private: void updateEnvironment() const; Utils::EnvironmentItems environment() const; - QString m_sdpPath; + Utils::FilePath m_sdpPath; mutable QString m_cpuDir; mutable bool m_environmentUpToDate = false; diff --git a/src/plugins/qnx/qnxtoolchain.cpp b/src/plugins/qnx/qnxtoolchain.cpp index 0fc060f51e1..984d593b4e0 100644 --- a/src/plugins/qnx/qnxtoolchain.cpp +++ b/src/plugins/qnx/qnxtoolchain.cpp @@ -41,8 +41,8 @@ using namespace Utils; namespace Qnx { namespace Internal { -static const char CompilerSdpPath[] = "Qnx.QnxToolChain.NDKPath"; -static const char CpuDirKey[] = "Qnx.QnxToolChain.CpuDir"; +const char CompilerSdpPath[] = "Qnx.QnxToolChain.NDKPath"; +const char CpuDirKey[] = "Qnx.QnxToolChain.CpuDir"; static Abis detectTargetAbis(const FilePath &sdpPath) { @@ -50,8 +50,8 @@ static Abis detectTargetAbis(const FilePath &sdpPath) FilePath qnxTarget; if (!sdpPath.fileName().isEmpty()) { - Utils::EnvironmentItems environment = QnxUtils::qnxEnvironment(sdpPath.toString()); - foreach (const Utils::EnvironmentItem &item, environment) { + const EnvironmentItems environment = QnxUtils::qnxEnvironment(sdpPath); + for (const EnvironmentItem &item : environment) { if (item.name == QLatin1String("QNX_TARGET")) qnxTarget = FilePath::fromString(item.value); } @@ -137,7 +137,7 @@ QStringList QnxToolChain::suggestedMkspecList() const QVariantMap QnxToolChain::toMap() const { QVariantMap data = GccToolChain::toMap(); - data.insert(QLatin1String(CompilerSdpPath), m_sdpPath); + data.insert(QLatin1String(CompilerSdpPath), m_sdpPath.toVariant()); data.insert(QLatin1String(CpuDirKey), m_cpuDir); return data; } @@ -147,7 +147,7 @@ bool QnxToolChain::fromMap(const QVariantMap &data) if (!GccToolChain::fromMap(data)) return false; - m_sdpPath = data.value(QLatin1String(CompilerSdpPath)).toString(); + m_sdpPath = FilePath::fromVariant(data.value(CompilerSdpPath)); m_cpuDir = data.value(QLatin1String(CpuDirKey)).toString(); // Make the ABIs QNX specific (if they aren't already). @@ -157,12 +157,12 @@ bool QnxToolChain::fromMap(const QVariantMap &data) return true; } -QString QnxToolChain::sdpPath() const +FilePath QnxToolChain::sdpPath() const { return m_sdpPath; } -void QnxToolChain::setSdpPath(const QString &sdpPath) +void QnxToolChain::setSdpPath(const FilePath &sdpPath) { if (m_sdpPath == sdpPath) return; @@ -185,7 +185,7 @@ void QnxToolChain::setCpuDir(const QString &cpuDir) GccToolChain::DetectedAbisResult QnxToolChain::detectSupportedAbis() const { - return detectTargetAbis(FilePath::fromString(m_sdpPath)); + return detectTargetAbis(m_sdpPath); } bool QnxToolChain::operator ==(const ToolChain &other) const @@ -243,7 +243,7 @@ QnxToolChainConfigWidget::QnxToolChainConfigWidget(QnxToolChain *tc) m_sdpPath->setExpectedKind(PathChooser::ExistingDirectory); m_sdpPath->setHistoryCompleter(QLatin1String("Qnx.Sdp.History")); - m_sdpPath->setPath(tc->sdpPath()); + m_sdpPath->setFilePath(tc->sdpPath()); m_sdpPath->setEnabled(!tc->isAutoDetected()); const Abis abiList = detectTargetAbis(m_sdpPath->filePath()); @@ -270,7 +270,7 @@ void QnxToolChainConfigWidget::applyImpl() Q_ASSERT(tc); QString displayName = tc->displayName(); tc->setDisplayName(displayName); // reset display name - tc->setSdpPath(m_sdpPath->filePath().toString()); + tc->setSdpPath(m_sdpPath->filePath()); tc->setTargetAbi(m_abiWidget->currentAbi()); tc->resetToolChain(m_compilerCommand->filePath()); } @@ -281,7 +281,7 @@ void QnxToolChainConfigWidget::discardImpl() QSignalBlocker blocker(this); auto tc = static_cast(toolChain()); m_compilerCommand->setFilePath(tc->compilerCommand()); - m_sdpPath->setPath(tc->sdpPath()); + m_sdpPath->setFilePath(tc->sdpPath()); m_abiWidget->setAbis(tc->supportedAbis(), tc->targetAbi()); if (!m_compilerCommand->filePath().toString().isEmpty()) m_abiWidget->setEnabled(true); @@ -292,7 +292,7 @@ bool QnxToolChainConfigWidget::isDirtyImpl() const auto tc = static_cast(toolChain()); Q_ASSERT(tc); return m_compilerCommand->filePath() != tc->compilerCommand() - || m_sdpPath->filePath().toString() != tc->sdpPath() + || m_sdpPath->filePath() != tc->sdpPath() || m_abiWidget->currentAbi() != tc->targetAbi(); } diff --git a/src/plugins/qnx/qnxtoolchain.h b/src/plugins/qnx/qnxtoolchain.h index 428cc5202d1..a2d8440ddee 100644 --- a/src/plugins/qnx/qnxtoolchain.h +++ b/src/plugins/qnx/qnxtoolchain.h @@ -46,8 +46,8 @@ public: QVariantMap toMap() const override; bool fromMap(const QVariantMap &data) override; - QString sdpPath() const; - void setSdpPath(const QString &sdpPath); + Utils::FilePath sdpPath() const; + void setSdpPath(const Utils::FilePath &sdpPath); QString cpuDir() const; void setCpuDir(const QString &cpuDir); @@ -57,7 +57,7 @@ protected: DetectedAbisResult detectSupportedAbis() const override; private: - QString m_sdpPath; + Utils::FilePath m_sdpPath; QString m_cpuDir; }; diff --git a/src/plugins/qnx/qnxutils.cpp b/src/plugins/qnx/qnxutils.cpp index d90acdda803..e8fabfb959b 100644 --- a/src/plugins/qnx/qnxutils.cpp +++ b/src/plugins/qnx/qnxutils.cpp @@ -78,11 +78,11 @@ QString QnxUtils::cpuDirShortDescription(const QString &cpuDir) return cpuDir; } -EnvironmentItems QnxUtils::qnxEnvironmentFromEnvFile(const QString &fileName) +EnvironmentItems QnxUtils::qnxEnvironmentFromEnvFile(const FilePath &filePath) { EnvironmentItems items; - if (!QFileInfo::exists(fileName)) + if (!filePath.exists()) return items; const bool isWindows = HostOsInfo::isWindowsHost(); @@ -97,10 +97,10 @@ EnvironmentItems QnxUtils::qnxEnvironmentFromEnvFile(const QString &fileName) QTextStream fileContent(&tmpFile); if (isWindows) fileContent << "@echo off\n" - << "call " << fileName << '\n'; + << "call " << filePath.path() << '\n'; else fileContent << "#!/bin/bash\n" - << ". " << fileName << '\n'; + << ". " << filePath.path() << '\n'; QString linePattern = QString::fromLatin1(isWindows ? "echo %1=%%1%" : "echo %1=$%1"); for (int i = 0, len = sizeof(EVAL_ENV_VARS) / sizeof(const char *); i < len; ++i) fileContent << linePattern.arg(QLatin1String(EVAL_ENV_VARS[i])) << QLatin1Char('\n'); @@ -140,19 +140,18 @@ EnvironmentItems QnxUtils::qnxEnvironmentFromEnvFile(const QString &fileName) return items; } -QString QnxUtils::envFilePath(const QString &sdpPath) +FilePath QnxUtils::envFilePath(const FilePath &sdpPath) { - QDir sdp(sdpPath); - QStringList entries; - if (HostOsInfo::isWindowsHost()) - entries = sdp.entryList(QStringList(QLatin1String("*-env.bat"))); + FilePaths entries; + if (sdpPath.osType() == OsTypeWindows) + entries = sdpPath.dirEntries({"*-env.bat"}); else - entries = sdp.entryList(QStringList(QLatin1String("*-env.sh"))); + entries = sdpPath.dirEntries({"*-env.sh"}); if (!entries.isEmpty()) - return sdp.absoluteFilePath(entries.first()); + return entries.first(); - return QString(); + return {}; } QString QnxUtils::defaultTargetVersion(const QString &sdpPath) @@ -208,7 +207,7 @@ QList QnxUtils::installedConfigs(const QString &config return sdpList; } -EnvironmentItems QnxUtils::qnxEnvironment(const QString &sdpPath) +EnvironmentItems QnxUtils::qnxEnvironment(const FilePath &sdpPath) { return qnxEnvironmentFromEnvFile(envFilePath(sdpPath)); } diff --git a/src/plugins/qnx/qnxutils.h b/src/plugins/qnx/qnxutils.h index c918ba09ab6..a90f5ded4a4 100644 --- a/src/plugins/qnx/qnxutils.h +++ b/src/plugins/qnx/qnxutils.h @@ -68,11 +68,11 @@ class QnxUtils public: static QString cpuDirFromAbi(const ProjectExplorer::Abi &abi); static QString cpuDirShortDescription(const QString &cpuDir); - static Utils::EnvironmentItems qnxEnvironmentFromEnvFile(const QString &fileName); - static QString envFilePath(const QString &sdpPath); + static Utils::EnvironmentItems qnxEnvironmentFromEnvFile(const Utils::FilePath &filePath); + static Utils::FilePath envFilePath(const Utils::FilePath &sdpPath); static QString defaultTargetVersion(const QString &sdpPath); static QList installedConfigs(const QString &configPath = QString()); - static Utils::EnvironmentItems qnxEnvironment(const QString &sdpPath); + static Utils::EnvironmentItems qnxEnvironment(const Utils::FilePath &sdpPath); static QList findTargets(const Utils::FilePath &basePath); static ProjectExplorer::Abi convertAbi(const ProjectExplorer::Abi &abi); static ProjectExplorer::Abis convertAbis(const ProjectExplorer::Abis &abis); diff --git a/src/tools/icons/qtcreatoricons.svg b/src/tools/icons/qtcreatoricons.svg index af3ce0d8a03..c33350195bb 100644 --- a/src/tools/icons/qtcreatoricons.svg +++ b/src/tools/icons/qtcreatoricons.svg @@ -6,7 +6,7 @@ height="600" id="svg2" version="1.1" - inkscape:version="1.1 (c68e22c387, 2021-05-23)" + inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)" sodipodi:docname="qtcreatoricons.svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" @@ -594,7 +594,6 @@ image/svg+xml - @@ -755,7 +754,7 @@ style="display:inline"> + transform="rotate(180,614,592)"> @@ -781,27 +780,27 @@ style="display:inline"> + transform="translate(102)"> + transform="translate(96)"> + style="fill:none;stroke:#232323;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.686275" /> @@ -896,7 +895,7 @@ style="opacity:0.83" height="600" width="800" - transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,503.25335,-30.961074)" + transform="rotate(45,289,591.99999)" id="use4511" xlink:href="#g4504" y="0" @@ -905,7 +904,7 @@ style="opacity:0.66" height="600" width="800" - transform="matrix(0,1,-1,0,881,303)" + transform="rotate(90,289,592)" id="use4525" xlink:href="#g4504" y="0" @@ -914,7 +913,7 @@ style="opacity:0.49" height="600" width="800" - transform="matrix(-0.70710678,0.70710678,-0.70710678,-0.70710678,911.96107,806.25335)" + transform="rotate(135,289,592)" id="use4528" xlink:href="#g4504" y="0" @@ -923,7 +922,7 @@ style="opacity:0.32" height="600" width="800" - transform="matrix(-1,0,0,-1,578,1184)" + transform="rotate(180,289,592)" id="use4530" xlink:href="#g4504" y="0" @@ -932,7 +931,7 @@ style="opacity:0.32" height="600" width="800" - transform="matrix(-0.70710678,-0.70710678,0.70710678,-0.70710678,74.746645,1214.9611)" + transform="rotate(-135,289.00001,592.00001)" id="use4532" xlink:href="#g4504" y="0" @@ -941,7 +940,7 @@ style="opacity:0.32" height="600" width="800" - transform="matrix(0,-1,1,0,-303,881)" + transform="rotate(-90,289,592)" id="use4534" xlink:href="#g4504" y="0" @@ -950,7 +949,7 @@ style="opacity:0.32" height="600" width="800" - transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,-333.96107,377.74665)" + transform="rotate(-45,289.00001,592)" id="use4536" xlink:href="#g4504" y="0" @@ -971,7 +970,7 @@ + style="opacity:0.887" /> + style="opacity:0.773" /> + style="opacity:0.66" /> @@ -1026,64 +1025,64 @@ y="0" xlink:href="#g3383" id="use3397" - transform="matrix(-0.8660254,0.5,-0.5,-0.8660254,957.63514,879.40243)" + transform="rotate(150,360.99998,568)" width="800" height="600" - style="opacity:0.43299997" /> + style="opacity:0.433" /> + style="opacity:0.32" /> + style="opacity:0.32" /> + style="opacity:0.32" /> + style="opacity:0.32" /> + style="opacity:0.32" /> + style="opacity:0.32" /> + style="opacity:0.417;fill:none;stroke:none" /> + style="opacity:1;fill:none;fill-opacity:0.8;stroke:#ffffff;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + sodipodi:arc-type="arc" /> + transform="translate(2)"> + transform="translate(8)"> @@ -1318,8 +1318,8 @@ sodipodi:nodetypes="cccc" inkscape:connector-curvature="0" id="path6627" - d="m 485,585 8,0 -4,4 -4,-4" - style="fill:#000000;fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + d="m 485,585 h 8 l -4,4 -4,-4" + style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + transform="translate(-26)"> + transform="translate(-25)"> @@ -1400,7 +1400,7 @@ + transform="rotate(90,606,600)"> + transform="rotate(-90,622.5,567.5)"> + transform="rotate(-90,630.5,559.5)"> @@ -1482,7 +1482,7 @@ + transform="rotate(90,646,640)"> + transform="rotate(-90,598,592)" /> + transform="translate(-39)"> + transform="rotate(90)" /> + d="m 741,599 h 16 v 1 h -16 z m 2,-3 h 12 v 1 h -12 z m 1,-3 h 10 v 1 h -10 z m -3,-3 h 16 v 1 h -16 z m 1,-3 h 14 v 1 h -14 z m 1,-3 h 12 v 1 h -12 z" /> + transform="translate(9)"> + transform="rotate(90)" /> + transform="translate(25)"> + transform="rotate(90)" /> + transform="translate(41)"> + transform="rotate(90)" /> @@ -2355,14 +2355,14 @@ y="0" xlink:href="#share/qtcreator/templates/wizards/global/guiapplication" id="src/plugins/qmakeprojectmanager/wizards/images/gui" - transform="translate(60,0)" + transform="translate(60)" width="100%" height="100%" /> + sodipodi:open="true" + sodipodi:arc-type="arc" /> + style="display:inline;stroke-width:0.547721" /> + id="g3920"> + style="fill:none;stroke:#000000;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:1.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.9;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:0.9;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + points="113,255 109,258 109,264 107,262 107,258 103,255 103,253 113,253 " + style="display:inline;fill:#000000;fill-opacity:1;stroke:none" /> + transform="translate(1)"> + transform="translate(17)"> + transform="translate(1)"> + id="g3973"> + sodipodi:open="true" + sodipodi:arc-type="arc" /> @@ -4096,12 +4093,11 @@ + x="0" /> + clip-path="url(#clipPath3218)"> + clip-path="url(#clipPath4031)"> @@ -4224,7 +4217,7 @@ id="rect3817" style="fill:#ffffff" /> + transform="matrix(1,0,0,-1,233,1169)" /> + transform="translate(112)"> + transform="translate(112)"> + transform="translate(16)"> + transform="translate(16)"> @@ -4480,7 +4471,7 @@ style="fill-opacity:1" sodipodi:nodetypes="cccccsscc" /> @@ -4518,7 +4509,7 @@ @@ -4535,29 +4526,29 @@ style="fill:#ffffff;fill-opacity:1;stroke:none" /> + transform="translate(399)"> @@ -4588,7 +4579,7 @@ style="fill:#000000;fill-opacity:1;stroke:none"> @@ -4733,7 +4724,7 @@ id="polygon6686-2" transform="translate(-69.369828,-0.1767767)" style="fill:#000000;fill-opacity:1" - d="m 156,315 0,-5 -2.5,2.5 z m 3,-8 5,0 -2.5,-2.5 z m -7.99979,-5.00001 1,0 0,13 -1,0 z m 0,0 13,0 0,1 -13,0 z" + d="m 156,315 v -5 l -2.5,2.5 z m 3,-8 h 5 l -2.5,-2.5 z m -7.99979,-5.00001 h 1 v 13 h -1 z m 0,0 h 13 v 1 h -13 z" inkscape:connector-curvature="0" /> @@ -4792,7 +4783,7 @@ + transform="translate(32)"> @@ -4822,7 +4813,7 @@ + transform="translate(48)"> + transform="translate(-32)"> + transform="translate(64)"> + transform="translate(80)"> + sodipodi:open="true" + sodipodi:arc-type="arc" /> + style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + sodipodi:arc-type="arc" /> + transform="translate(16)"> + transform="translate(16)"> + transform="translate(32)"> @@ -5016,7 +5009,7 @@ sodipodi:nodetypes="cccc" /> @@ -5024,7 +5017,7 @@ + transform="translate(48)"> + transform="translate(16)"> + transform="translate(16)"> + transform="translate(32)"> @@ -5211,11 +5204,11 @@ + transform="translate(16)"> + style="fill:#cccccc;fill-opacity:1;stroke:#000000;stroke-opacity:1" /> @@ -5289,7 +5282,7 @@ + style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -5342,7 +5335,7 @@ + transform="translate(16)"> @@ -5370,7 +5363,7 @@ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> @@ -5411,13 +5404,13 @@ x="0" /> + style="fill:#000000;fill-opacity:0.156863;stroke:#000000" /> + transform="translate(31)"> + transform="translate(80)" /> + transform="translate(16)"> @@ -5545,7 +5538,7 @@ + transform="translate(16)"> @@ -5572,14 +5565,14 @@ id="rect6782-96-0-0-7-8-1-0-4-4" /> @@ -5620,7 +5613,7 @@ sodipodi:nodetypes="cccc" inkscape:connector-curvature="0" id="path5163" - d="m 1233,580.5 4,0 c 6,0 6,-8 0,-8 l -5,0" + d="m 1233,580.5 h 4 c 6,0 6,-8 0,-8 h -5" style="fill:none;stroke:#000000" /> + transform="translate(48)"> @@ -5858,18 +5851,18 @@ r="2.5" /> @@ -5894,7 +5887,7 @@ y="570" /> @@ -5906,25 +5899,25 @@ sodipodi:nodetypes="cc" /> + d="m 1237.5,572 v 5 m 2.5,-2.5 h -5" /> @@ -6017,7 +6010,7 @@ width="100%" height="100%" /> + transform="rotate(90,1232.5,581)" /> @@ -6128,11 +6121,11 @@ y="0" xlink:href="#src/plugins/scxmleditor/common/images/align_bottom" id="src/plugins/scxmleditor/common/images/align_left" - transform="matrix(0,1,-1,0,2084,-884)" + transform="rotate(90,1484,600)" width="100%" height="100%" /> @@ -6179,7 +6172,7 @@ width="100%" height="100%" /> + style="stroke:#000000;stroke-width:0.6" /> + style="fill:#ffffff;fill-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:1.42;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#000000;stroke-width:1.42;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -6556,7 +6549,7 @@ y="552" /> @@ -6564,7 +6557,7 @@ inkscape:connector-curvature="0" id="path4228" d="m 52,564 c 8,-8 8,-8 8,-8" - style="fill:none;stroke:#000000;stroke-width:1.42;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1.0;stroke-dasharray:none" /> + style="fill:none;stroke:#000000;stroke-width:1.42;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -6667,7 +6660,7 @@ sodipodi:nodetypes="csscsccscccsc" style="fill:#000000;fill-opacity:1" inkscape:connector-curvature="0" - d="m 60.447,269.795 c -0.207,-0.04 -0.431,-0.726 0,-1.363 0.521,-0.77 1.225,-2.879 1.225,-4.146 0,-2.366 -1.645,-4.284 -3.672,-4.285 -2.027,0.001 -3.672,1.919 -3.672,4.285 0,1.268 0.701,3.377 1.225,4.146 0.43,0.638 0.206,1.323 0,1.363 -3.284,0.648 -5.053,1.389 -5.053,3.408 l 0,1.798 7.5,0 7.5,0 0,-1.798 c 0,-2.019 -1.77,-2.76 -5.053,-3.408 z" + d="m 60.447,269.795 c -0.207,-0.04 -0.431,-0.726 0,-1.363 0.521,-0.77 1.225,-2.879 1.225,-4.146 0,-2.366 -1.645,-4.284 -3.672,-4.285 -2.027,0.001 -3.672,1.919 -3.672,4.285 0,1.268 0.701,3.377 1.225,4.146 0.43,0.638 0.206,1.323 0,1.363 -3.284,0.648 -5.053,1.389 -5.053,3.408 v 1.798 h 7.5 7.5 v -1.798 c 0,-2.019 -1.77,-2.76 -5.053,-3.408 z" id="path4884-6" /> @@ -6711,14 +6704,14 @@ style="fill:#ffffff;fill-opacity:1" /> + transform="translate(16)"> @@ -6747,7 +6740,7 @@ transform="translate(144,148)" /> @@ -6780,7 +6773,7 @@ + transform="translate(-28)"> + transform="rotate(45)" /> + sodipodi:open="true" + sodipodi:arc-type="arc" /> + sodipodi:open="true" + sodipodi:arc-type="arc" /> + sodipodi:open="true" + sodipodi:arc-type="arc" /> + id="use4943" + width="100%" + height="100%" /> + transform="translate(36)"> + transform="translate(52)"> + transform="translate(36)"> + sodipodi:open="true" + sodipodi:arc-type="arc" /> + transform="translate(52)"> + style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + sodipodi:open="true" + sodipodi:arc-type="arc" /> + transform="translate(68)"> + transform="translate(84)"> + transform="translate(84)"> + transform="translate(100)"> + transform="translate(116)"> + transform="translate(148)"> + transform="translate(164)"> @@ -7188,7 +7188,7 @@ cy="560.5" cx="353.5" id="path4897" - style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.7;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> @@ -7205,12 +7205,12 @@ height="4" width="3" id="namespacedot" - style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.7;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" ry="1.5" /> + style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + style="fill:none;stroke:#ffffff;stroke-width:1;stroke-linecap:square;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"> + style="fill:none;stroke:#ffffff;stroke-linecap:square" /> + style="stroke:#ffffff;stroke-linecap:square" /> + style="stroke:#ffffff;stroke-linecap:square" /> + style="stroke:#ffffff;stroke-linecap:square" /> + style="stroke:#ffffff;stroke-linecap:butt" + sodipodi:arc-type="arc" /> + transform="translate(16)"> + transform="translate(32)"> @@ -7515,7 +7516,7 @@ y="584" /> @@ -7540,7 +7541,7 @@ height="100%" /> @@ -7558,7 +7559,7 @@ x="0" /> @@ -7574,13 +7575,13 @@ style="fill:#ffffff;stroke:none" /> + transform="translate(16)"> @@ -7636,7 +7637,7 @@ x="0" /> @@ -7671,13 +7672,13 @@ style="fill:#ffffff;stroke:none" /> @@ -7728,11 +7729,11 @@ sodipodi:nodetypes="cccccccc" inkscape:connector-curvature="0" id="path4833" - d="m 145.5,542.5 6,0 0,-3 7,4.5 -7,4.5 0,-3 -6,0 z" + d="m 145.5,542.5 h 6 v -3 l 7,4.5 -7,4.5 v -3 h -6 z" style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + d="m 145.5,542.5 h 6 v -3 l 7,4.5 -7,4.5 v -3 h -6 z" + style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" /> + transform="translate(-24)"> + transform="translate(-34)"> + transform="translate(-44)"> + transform="translate(-139,-80)"> + id="g4438"> + style="opacity:0.601;fill:#ffffff;fill-opacity:0" /> @@ -7988,16 +7987,16 @@ height="17" width="21" id="rect4116" - style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-opacity:0.4;stroke-dasharray:none" /> + style="fill:none;stroke:#ffffff;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.4" /> @@ -8006,12 +8005,12 @@ + style="opacity:0.83" + transform="translate(-4)"> + style="fill:#ffffff;fill-opacity:0.12549;stroke:none" /> + style="opacity:0.83" + transform="translate(-8)"> + style="opacity:0.83" + transform="translate(-12)"> + style="opacity:0.83" + transform="translate(-16)"> + style="opacity:0.83"> + style="stroke-width:0.82734" /> + style="display:inline;stroke-width:0.82734" /> + style="display:inline;stroke-width:0.82734" /> + style="display:inline;stroke-width:0.82734" /> + style="stroke-width:0.82734" /> + style="display:inline;stroke-width:0.82734" /> + style="display:inline;stroke-width:0.82734" /> + style="display:inline;stroke-width:0.82734" /> @@ -8606,7 +8605,7 @@ transform="translate(-1,-3)"> @@ -10228,7 +10227,7 @@ + transform="rotate(180,1122.5,574)"> + style="opacity:0.93" />