diff --git a/dist/changes-4.12.0.md b/dist/changes-4.12.0.md index ccdca281858..136428ef568 100644 --- a/dist/changes-4.12.0.md +++ b/dist/changes-4.12.0.md @@ -35,10 +35,15 @@ Editing * Added `Go to Last Edit` * Added option for default line terminator style (QTCREATORBUG-3590) +* Improved behavior when splitting would hide text cursor * Fixed that wizards ignored default file encoding * Fixed that only restricted number of sizes were allowed for font size (QTCREATORBUG-22536) * Fixed completion after undo (QTCREATORBUG-15038) +### C++ + +* Fixed issue with Clang and precompiled headers (QTCREATORBUG-22897) + ### Language Client * Added support for Markdown in tooltips @@ -49,6 +54,7 @@ Editing ### QML +* Updated to Qt 5.15 parser (QTCREATORBUG-23591) * Improved support for multiple imports into same namespace (QTCREATORBUG-15684) * Added scanning of `app.qmltypes` and `lib.qmltypes` for type information @@ -165,7 +171,7 @@ Version Control Systems * Added option to start interactive rebase from log view (QTCREATORBUG-11200) * Added information about upstream status to `Git Branches` view * Added option to `grep` and `pickaxe` git log (QTCREATORBUG-22512) -* Made references in VCS output view clickable (QTCREATORBUG-16477) +* Made references in VCS output view clickable and added context menu (QTCREATORBUG-16477) Test Integration ---------------- @@ -181,6 +187,9 @@ Platforms ### Windows +* Improved behavior with regard to MSVC tool chain matching and compatibility of MSVC 2017 and + MSVC 2019 (QTCREATORBUG-23653) + ### macOS * Fixed parsing of Apple Clang specific linker message (QTCREATORBUG-19766) @@ -191,9 +200,11 @@ Platforms * Added auto-detection of Java JDK (QTCREATORBUG-23407) * Added option to automatically download and install required Android tools (QTCREATORBUG-23285) +* Added option to register multiple NDKs (QTCREATORBUG-23286) * Added automatic selection of correct NDK for Qt version (QTCREATORBUG-23583) * Added support for Android 11 with API level 30 * Improved examples browser to only show items tagged with `android` (QTBUG-80716) +* Improved manifest editor (QTCREATORBUG-23283) * Fixed several issues with AVD manager (QTCREATORBUG-23284, QTCREATORBUG-23448) ### iOS @@ -213,12 +224,14 @@ Platforms Credits for these changes go to: -------------------------------- +Aleksei German Alessandro Portale Alexandru Croitor Andre Hartmann Andrey Sobol André Pönitz Assam Boudjelthia +BogDan Vatra Camila San Christian Kandeler Christian Stenger @@ -227,13 +240,16 @@ David Schulz Denis Shienkov Dmitry Kovalev Eike Ziller +Fawzi Mohamed Federico Guerinoni Filippo Cucchetto Halfdan Ingvarsson Hannes Domani +Henning Gruendl Igor Sidorov Jaroslaw Kobus Jochen Becher +Kai Köhne Knud Dollereder Leander Schulten Leena Miettinen @@ -260,6 +276,7 @@ Tim Jenssen Tobias Hunger Topi Reinio Ulf Hermann +Vikas Pachdha Ville Voutilainen Volodymyr Samokhatko zarelaky diff --git a/doc/qtcreator/config/qtcreator-project.qdocconf b/doc/qtcreator/config/qtcreator-project.qdocconf index 85602350171..a9a0ef579d1 100644 --- a/doc/qtcreator/config/qtcreator-project.qdocconf +++ b/doc/qtcreator/config/qtcreator-project.qdocconf @@ -3,8 +3,11 @@ description = "$IDE_DISPLAY_NAME Manual" url = http://doc.qt.io/$IDE_ID headerdirs = -sourcedirs = ../src +sourcedirs = ../src \ + ../../qtdesignstudio/src/qtquick3d-editor + imagedirs = ../images \ + ../../qtdesignstudio/images \ ../../../src/libs/qmleditorwidgets/images \ ../../../src/libs/utils/images \ ../../../src/plugins/android/images \ @@ -16,6 +19,7 @@ imagedirs = ../images \ ../../../src/plugins/help/images \ ../../../src/plugins/projectexplorer/images \ ../../../src/plugins/qmldesigner/components/componentcore/images \ + ../../../src/plugins/qmldesigner/components/edit3d/images \ ../../../src/plugins/qmldesigner/components/formeditor \ ../../../src/plugins/qmldesigner/components/navigator \ ../../../src/plugins/qmldesigner/components/timelineeditor/images \ @@ -35,12 +39,15 @@ depends += qtwidgets \ qtcmake \ qtcore \ qtqml \ + qtqmlmodels \ qtquick \ qmake \ qtdesigner \ qtdoc \ + qtgraphicaleffects \ qtgui \ qthelp \ + qtquick3d \ qtquickcontrols \ qtquickextras \ qtquicktimeline \ diff --git a/doc/qtcreator/images/icons/detach-group-icon.png b/doc/qtcreator/images/icons/detach-group-icon.png new file mode 100644 index 00000000000..7a3bea690c2 Binary files /dev/null and b/doc/qtcreator/images/icons/detach-group-icon.png differ diff --git a/doc/qtcreator/images/qtcreator-workspace-attaching-views.png b/doc/qtcreator/images/qtcreator-workspace-attaching-views.png new file mode 100644 index 00000000000..e1eeae51a79 Binary files /dev/null and b/doc/qtcreator/images/qtcreator-workspace-attaching-views.png differ diff --git a/doc/qtcreator/images/qtcreator-workspace-manager.png b/doc/qtcreator/images/qtcreator-workspace-manager.png index 3a42f3e536f..603b16f9180 100644 Binary files a/doc/qtcreator/images/qtcreator-workspace-manager.png and b/doc/qtcreator/images/qtcreator-workspace-manager.png differ diff --git a/doc/qtcreator/images/qtquick-annotation-editor.png b/doc/qtcreator/images/qtquick-annotation-editor.png new file mode 100644 index 00000000000..3539872222e Binary files /dev/null and b/doc/qtcreator/images/qtquick-annotation-editor.png differ diff --git a/doc/qtcreator/images/qtquick-annotations.png b/doc/qtcreator/images/qtquick-annotations.png new file mode 100644 index 00000000000..88dde53aaa8 Binary files /dev/null and b/doc/qtcreator/images/qtquick-annotations.png differ diff --git a/doc/qtcreator/src/howto/creator-workspaces.qdoc b/doc/qtcreator/src/howto/creator-workspaces.qdoc index c297c4dc929..49dfa82a37e 100644 --- a/doc/qtcreator/src/howto/creator-workspaces.qdoc +++ b/doc/qtcreator/src/howto/creator-workspaces.qdoc @@ -32,21 +32,42 @@ \title Managing Workspaces In the Design and Debug modes, you can arrange a set of \QC - views as a \e workspace on the screen. For a list of views, - select \uicontrol Window > \uicontrol Views. + views as a \e workspace on the screen. - In \QMLD, you can select the \uicontrol {Restore last workspace on startup} - check box to save the current workspace as a \e default workspace when you - exit \QC and to restore it the next time you start \QC. + To detach views: - To manage workspaces, select \uicontrol Window > \uicontrol Workspaces > - \uicontrol Manage. + \list + \li Double-click the title bar of the view. + \li Start dragging the view to another position. + \li Select the \inlineimage icons/detach-group-icon.png + (\uicontrol {Detach Group}) button. + \endlist + + You can move detached views or groups of views anywhere on the screen. + + To attach views, drag them over the dock area markers until the dock area + where you want to attach the view is highlighted, and then drop them into + the dock area. + + \image qtcreator-workspace-attaching-views.png "Attaching views" + + To close groups of views, select the \uicontrol {Close Group} button. + + To open closed views, select \uicontrol Window > \uicontrol Views. + + \section1 Saving Workspaces + + The changes you make to a workspace are saved when you exit \QC. + In \QMLD, you can select \uicontrol Window > \uicontrol Workspaces > + \uicontrol Manage > \uicontrol {Restore last workspace on startup} + to restore the current workspace the next time you start \QC. \image qtcreator-workspace-manager.png "Workspace Manager" To save a workspace under a new name, select \uicontrol Clone. - To delete the selected workspace, select \uicontrol Delete. + To revert the changes you made to a preset workspace, select + \uicontrol Reset. To switch between workspaces, select \uicontrol {Switch To}. @@ -61,4 +82,5 @@ switch to it. \endlist + To delete the selected workspace, select \uicontrol Delete. */ diff --git a/doc/qtcreator/src/qtcreator-toc.qdoc b/doc/qtcreator/src/qtcreator-toc.qdoc index 1bfa7024fcc..0c63e395821 100644 --- a/doc/qtcreator/src/qtcreator-toc.qdoc +++ b/doc/qtcreator/src/qtcreator-toc.qdoc @@ -25,7 +25,7 @@ /*! - \contentspage {Qt Creator} + \contentspage index.html \page qtcreator-toc.html \title All Topics @@ -91,25 +91,55 @@ \list \li \l {Creating Qt Quick Projects} \li \l {Editing QML Files in Design Mode} - \li \l {Creating Components} + \li \l {Creating UIs} \list - \li \l {Creating Buttons} - \li \l {Creating Scalable Buttons and Borders} + \li \l {Creating Components} + \list + \li \l{Creating Buttons} + \li \l{Creating Scalable Buttons and Borders} + \endlist + \li \l{Managing Item Hierarchy} + \li \l{Specifying Item Properties} + \li \l{Using Custom Fonts} + \li \l{Annotating Designs} + \li \l{Qt Quick UI Forms} + \endlist + \li \l {Adding Dynamics} + \list + \li \l{Creating Animations} + \li \l{Adding Connections} + \list + \li \l{Connecting Objects to Signals} + \li \l{Specifying Dynamic Properties} + \li \l{Adding Bindings Between Properties} + \li \l{Managing C++ Backend Objects} + \endlist + \li \l {Adding States} + \li \l {Editing PathView Properties} \endlist - \li \l {Managing Item Hierarchy} - \li \l {Specifying Item Properties} - \li \l {Creating Animations} - \li \l {Adding Connections} - \list - \li \l{Connecting Objects to Signals} - \li \l{Specifying Dynamic Properties} - \li \l{Adding Bindings Between Properties} - \li \l{Managing C++ Backend Objects} - \endlist - \li \l {Adding States} - \li \l {Editing PathView Properties} + \li \l{Editing 3D Scenes} + \list + \li \l {Exporting 3D Assets} + \list + \li \l{Exporting from Blender}{Blender} + \li \l{Exporting from Maya}{Maya} + \endlist + \li \l{Importing 3D Assets} + \li \l{Editing 3D Assets in Design Mode} + \li \l{Working in the 3D Editor} + \li \l{Adding 3D Views} + \li \l{Using 3D Components} + \list + \li \l{Setting Node Properties} + \li \l{Adding Models} + \li \l{Using Materials and Shaders} + \li \l{Attaching Textures to Materials} + \li \l{Using Lights} + \li \l{Using Scene Camera} + \li \l{Setting Scene Environment} + \endlist + \endlist \li \l {Browsing ISO 7000 Icons} - \li \l {Qt Quick UI Forms} \li \l {Using QML Modules with Plugins} \li \l {Converting UI Projects to Applications} \endlist diff --git a/doc/qtcreator/src/qtquick/creator-only/qtquick-app-development.qdoc b/doc/qtcreator/src/qtquick/creator-only/qtquick-app-development.qdoc index a7938078ab7..16468889570 100644 --- a/doc/qtcreator/src/qtquick/creator-only/qtquick-app-development.qdoc +++ b/doc/qtcreator/src/qtquick/creator-only/qtquick-app-development.qdoc @@ -33,40 +33,13 @@ \contentspage index.html \page creator-visual-editor.html - \if defined(qtdesignstudio) - \previouspage quick-converting-ui-projects.html - \nextpage quick-components.html - \else \previouspage creator-design-mode.html \nextpage quick-projects.html - \endif \title Developing Qt Quick Applications - \if defined(qtdesignstudio) - When you install \QDS, everything you'll need to design UIs - using \l{Qt Quick} and to preview them on the desktop or on Android or - embedded Linux devices is automatically installed and configured correctly - for you. - \endif - - Qt Quick enables you to build UIs around the behavior of - \e components and how they connect with one another. You - create components using Qt Quick and QML types that are available in - the Design mode. You can specify values for the \e properties of a - component to change its appearance and behavior. All QML types have a - set of predefined properties, some of which control things that are - visible to users, while others are used behind the scene. - - While it is useful to learn the basics of Qt Quick, you can also rely on - \QDS to write the code for you when you drag-and-drop the ready-made - components to the working area and change them to your liking by modifying - their properties in the Design mode. You can always check up details in - the extensive Qt Quick documentation by pressing \key F1. - \list - \if defined(qtcreator) \li \l {Creating Qt Quick Projects} You can use wizards to create Qt Quick projects. @@ -76,87 +49,41 @@ You can use the \uicontrol {Form Editor} or the \uicontrol {Text Editor} in the Design mode to develop Qt Quick applications. - \endif - \li \l {Creating Components} + \li \l {Creating UIs} - In addition to your imported artwork, you can use the Design - mode to customize ready-made components or design any custom form - and shape directly as QML types. You can import visual assets in - various formats, such as PNG, JPG, and SVG for use in the - components. + Qt Quick enables you to build UIs around the behavior of + \e components and how they connect with one another. You + create components using Qt Quick and QML types that are + available in the Design mode, manage their relationships, + and specify their properties. - \li \l {Managing Item Hierarchy} + \li \l {Adding Dynamics} - You can manage the items in the current QML file and their - relationships in the \uicontrol Navigator. + You can animate the properties of UI components and create + connections between them to enable them to communicate with + each other. - \li \l {Specifying Item Properties} + \li \l {Editing 3D Scenes} - You can specify values for the properties of a component to change - its appearance and behavior. All QML types have a set of predefined - properties. Some properties, such as position, size, and visibility, - are common to all QML types, whereas others are specific to the QML - type. You can specify properties for your components in the - \uicontrol Properties view. + You can use the 3D editor in the Design mode to edit files you + created using 3D graphics applications and stored in one of the + supported formats. You cannot create 3D models or other assets + in the editor, but you can import the assets you need and work + with them to create scenes and states, as well as the + transitions between them. - \li \l {Creating Animations} - - You can use a timeline and keyframe based editor in the - \uicontrol Timeline view to animate the properties of UI - components. Animating properties enables their values to - move through intermediate values at specified keyframes - instead of immediately changing to the target value. - - \li \l {Adding Connections} - - You can create connections between the UI components and - the application to enable them to communicate with each other. For - example, how does the appearance of a button change on a mouse click - and which action does the application need to perform in response to - it. - - You can also create connections between UI components by - binding their properties together. This way, when the value of a - property changes in a parent component, it can be automatically - changed in all the child components, for example. - - \li \l {Adding States} - - Qt Quick allows you to declare various UI states that describe - how component properties change from a base state. Therefore, - states can be a useful way of organizing your UI - logic. You can associate transitions with items to define - how their properties will animate when they change due to a state - change. \endlist \section1 Related Topics \list - \if defined(qtdesignstudio) - \li \l {Using Custom Fonts} - - You can load custom fonts to \QDS and use them in your designs. - \endif - - \li \l {Editing PathView Properties} - - You can use a graphical spline editor to specify \l{PathView} paths. - A path view lays out data provided by data models on a \l{Path}. \li \l {Browsing ISO 7000 Icons} You can add ISO 7000 icons from a library delivered with \QC to UIs and change their color. - \li \l{Qt Quick UI Forms} - - Some of the wizards create Qt Quick projects that contain UI forms - (.ui.qml files). The forms use a purely declarative subset of the - QML language and you can edit them in the Design mode. - - \if defined(qtcreator) \li \l {Using QML Modules with Plugins} QML modules may use plugins to expose components defined in C++ to @@ -171,7 +98,6 @@ interfaces. To use them for application development, you have to convert them to Qt Quick Application projects that contain .pro, .cpp, and .qrc files. - \endif \endlist diff --git a/doc/qtcreator/src/qtquick/creator-only/qtquick-iso-icon-browser.qdoc b/doc/qtcreator/src/qtquick/creator-only/qtquick-iso-icon-browser.qdoc index 0dbfc06b9fb..4a9c57e9e6c 100644 --- a/doc/qtcreator/src/qtquick/creator-only/qtquick-iso-icon-browser.qdoc +++ b/doc/qtcreator/src/qtquick/creator-only/qtquick-iso-icon-browser.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -26,8 +26,8 @@ /*! \contentspage index.html \page qtquick-iso-icon-browser.html - \previouspage qmldesigner-pathview-editor.html - \nextpage creator-quick-ui-forms.html + \previouspage studio-3d-scene-environment.html + \nextpage creator-qml-modules-with-plugins.html \title Browsing ISO 7000 Icons diff --git a/doc/qtcreator/src/qtquick/qt-design-viewer.qdoc b/doc/qtcreator/src/qtquick/qt-design-viewer.qdoc index 2c63c05baf4..044737bf74f 100644 --- a/doc/qtcreator/src/qtquick/qt-design-viewer.qdoc +++ b/doc/qtcreator/src/qtquick/qt-design-viewer.qdoc @@ -24,7 +24,7 @@ ****************************************************************************/ /*! - \contentspage {Qt Creator} + \contentspage index.html \previouspage creator-live-preview-devices.html \page qt-design-viewer.html \if defined(qtdesignstudio) diff --git a/doc/qtdesignstudio/src/qtdesignstudio-adding-dynamics.qdoc b/doc/qtcreator/src/qtquick/qtquick-adding-dynamics.qdoc similarity index 95% rename from doc/qtdesignstudio/src/qtdesignstudio-adding-dynamics.qdoc rename to doc/qtcreator/src/qtquick/qtquick-adding-dynamics.qdoc index 60891e2aa31..a2e4b5865a6 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-adding-dynamics.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-adding-dynamics.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Design Studio documentation. @@ -24,9 +24,9 @@ ****************************************************************************/ /*! - \contentspage {Qt Design Studio Manual} - \page studio-adding-dynamics.html - \previouspage studio-fonts.html + \contentspage index.html + \page qtquick-adding-dynamics.html + \previouspage qtquick-fonts.html \nextpage studio-timeline.html \title Adding Dynamics diff --git a/doc/qtcreator/src/qtquick/qtquick-annotations.qdoc b/doc/qtcreator/src/qtquick/qtquick-annotations.qdoc new file mode 100644 index 00000000000..cd8ada49258 --- /dev/null +++ b/doc/qtcreator/src/qtquick/qtquick-annotations.qdoc @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Creator documentation. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** +****************************************************************************/ + +/*! + \contentspage {Qt Creator Manual} + \page qtquick-annotations.html + \previouspage qtquick-fonts.html + \nextpage creator-quick-ui-forms.html + + \title Annotating Designs + + You can submit your designs to review or further development as QML files. + You can annotate your designs to provide reviewers or developers with + additional information about them. An annotation consist of an annotation + name and one or several comments. The comments have a title, author, and + comment text. + + \image qtquick-annotations.png "Annotations displayed in the Form Editor tab" + + Annotations are saved in the end of QML files when you save the file. They + do not affect the QML performance in any way. + + To view annotations, select the annotation icon. + + To edit annotations, select \uicontrol {Edit Annotation} in the context + menu of the annotation icon. + + \section1 Adding Annotations + + To add annotations: + + \list 1 + \li Select the component to annotate in the \uicontrol Navigator + or in the \uicontrol {Form Editor}. + \li In the \uicontrol Properties view, select + \uicontrol {Add Annotation}. + \image qtquick-annotation-editor.png "Annotation Editor" + \li The \uicontrol {Selected Item} field displays the ID of the + component. Enter a name for the annotation in the + \uicontrol {Custom ID} field. + \li In the \uicontrol Title field, enter the text to display in + the tab for this comment. + \li In the \uicontrol Author field, enter the author's name. + \li In the \uicontrol Text field, enter the comment text. + \li Select \uicontrol OK. + \endlist + + To add more comments about the component, select the \inlineimage plus.png + (\uicontrol {Add Comment}) button. + + To remove the active comment, select the \inlineimage minus.png + (\uicontrol {Remove Comment}) button. To remove the annotation, right-click + the annotation icon, and then select \uicontrol {Remove Annotation}. +*/ diff --git a/doc/qtcreator/src/qtquick/qtquick-connection-editor-properties.qdoc b/doc/qtcreator/src/qtquick/qtquick-connection-editor-properties.qdoc index 651c224a18d..1473007a547 100644 --- a/doc/qtcreator/src/qtquick/qtquick-connection-editor-properties.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-connection-editor-properties.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -24,8 +24,8 @@ ****************************************************************************/ /*! - \contentspage {Qt Creator Manual} - \previouspage qmldesigner-connections.html + \contentspage index.html + \previouspage quick-signals.html \page quick-dynamic-properties.html \nextpage quick-property-bindings.html diff --git a/doc/qtcreator/src/qtquick/qtquick-connection-editor.qdoc b/doc/qtcreator/src/qtquick/qtquick-connection-editor.qdoc index a79d9c88fd1..d3cefb7699b 100644 --- a/doc/qtcreator/src/qtquick/qtquick-connection-editor.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-connection-editor.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -25,7 +25,7 @@ /*! \contentspage index.html - \previouspage quick-states.html + \previouspage studio-timeline.html \page qmldesigner-connections.html \nextpage quick-signals.html diff --git a/doc/qtcreator/src/qtquick/qtquick-designer.qdoc b/doc/qtcreator/src/qtquick/qtquick-designer.qdoc index 6666f421ddc..50e01b83079 100644 --- a/doc/qtcreator/src/qtquick/qtquick-designer.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-designer.qdoc @@ -37,7 +37,7 @@ \nextpage {Tutorials} \else \previouspage quick-projects.html - \nextpage quick-components.html + \nextpage quick-uis.html \endif \title Editing QML Files in Design Mode diff --git a/doc/qtdesignstudio/src/qtdesignstudio-fonts.qdoc b/doc/qtcreator/src/qtquick/qtquick-fonts.qdoc similarity index 95% rename from doc/qtdesignstudio/src/qtdesignstudio-fonts.qdoc rename to doc/qtcreator/src/qtquick/qtquick-fonts.qdoc index 39073a2d531..081de128623 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-fonts.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-fonts.qdoc @@ -25,10 +25,10 @@ /*! - \contentspage {Qt Design Studio} + \contentspage index.html \previouspage qtquick-properties.html - \page studio-fonts.html - \nextpage studio-adding-dynamics.html + \page qtquick-fonts.html + \nextpage qtquick-annotations.html \title Using Custom Fonts diff --git a/doc/qtcreator/src/qtquick/qtquick-from-qmlproject-to-pro.qdoc b/doc/qtcreator/src/qtquick/qtquick-from-qmlproject-to-pro.qdoc index b02dc93b187..898dd92569f 100644 --- a/doc/qtcreator/src/qtquick/qtquick-from-qmlproject-to-pro.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-from-qmlproject-to-pro.qdoc @@ -28,7 +28,7 @@ \page quick-converting-ui-projects.html \if defined(qtdesignstudio) \previouspage studio-importing-designs.html - \nextpage studio-prototyping.html + \nextpage quick-uis.html \else \previouspage creator-qml-modules-with-plugins.html \nextpage creator-using-qt-designer.html diff --git a/doc/qtcreator/src/qtquick/qtquick-live-preview-desktop.qdoc b/doc/qtcreator/src/qtquick/qtquick-live-preview-desktop.qdoc index 8d9f653b5e8..7b8066e4a31 100644 --- a/doc/qtcreator/src/qtquick/qtquick-live-preview-desktop.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-live-preview-desktop.qdoc @@ -24,7 +24,7 @@ ****************************************************************************/ /*! - \contentspage {Qt Creator} + \contentspage index.html \previouspage creator-live-preview.html \page creator-live-preview-desktop.html \nextpage creator-live-preview-devices.html diff --git a/doc/qtcreator/src/qtquick/qtquick-live-preview-devices.qdoc b/doc/qtcreator/src/qtquick/qtquick-live-preview-devices.qdoc index 4686ef485b0..38edb191dcf 100644 --- a/doc/qtcreator/src/qtquick/qtquick-live-preview-devices.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-live-preview-devices.qdoc @@ -24,7 +24,7 @@ ****************************************************************************/ /*! - \contentspage {Qt Creator} + \contentspage index.html \previouspage creator-live-preview-desktop.html \page creator-live-preview-devices.html \nextpage qt-design-viewer.html diff --git a/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc b/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc index c93eaf4aaf0..48c03e8a55d 100644 --- a/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-live-preview.qdoc @@ -24,7 +24,7 @@ ****************************************************************************/ /*! - \contentspage {Qt Creator} + \contentspage index.html \if defined(qtdesignstudio) \previouspage studio-3d-camera.html \else diff --git a/doc/qtcreator/src/qtquick/qtquick-pathview-editor.qdoc b/doc/qtcreator/src/qtquick/qtquick-pathview-editor.qdoc index 489a84da257..a3e8f875c04 100644 --- a/doc/qtcreator/src/qtquick/qtquick-pathview-editor.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-pathview-editor.qdoc @@ -27,11 +27,7 @@ \contentspage index.html \page qmldesigner-pathview-editor.html \previouspage quick-states.html - \if defined(qtdesignstudio) \nextpage studio-3d.html - \else - \nextpage qtquick-iso-icon-browser.html - \endif \title Editing PathView Properties diff --git a/doc/qtcreator/src/qtquick/qtquick-properties.qdoc b/doc/qtcreator/src/qtquick/qtquick-properties.qdoc index 3f6ef08d6aa..95282b046eb 100644 --- a/doc/qtcreator/src/qtquick/qtquick-properties.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-properties.qdoc @@ -24,14 +24,10 @@ ****************************************************************************/ /*! - \contentspage {Qt Creator Manual} + \contentspage index.html \page qtquick-properties.html \previouspage qtquick-navigator.html - \if defined(qtdesignstudio) - \nextpage studio-fonts.html - \else - \nextpage studio-timeline.html - \endif + \nextpage qtquick-fonts.html \title Specifying Item Properties diff --git a/doc/qtcreator/src/qtquick/qtquick-timeline.qdoc b/doc/qtcreator/src/qtquick/qtquick-timeline.qdoc index a613dc0f3a2..049e0551e27 100644 --- a/doc/qtcreator/src/qtquick/qtquick-timeline.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-timeline.qdoc @@ -25,11 +25,7 @@ /*! \contentspage {Qt Design Studio Manual} - \if defined(qtdesignstudio) - \previouspage studio-adding-dynamics.html - \else - \previouspage qtquick-properties.html - \endif + \previouspage qtquick-adding-dynamics.html \page studio-timeline.html \nextpage qmldesigner-connections.html diff --git a/doc/qtcreator/src/qtquick/qtquick-ui-forms.qdoc b/doc/qtcreator/src/qtquick/qtquick-ui-forms.qdoc index f9dc41cb948..49f682d7ce7 100644 --- a/doc/qtcreator/src/qtquick/qtquick-ui-forms.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-ui-forms.qdoc @@ -33,11 +33,10 @@ \contentspage index.html \page creator-quick-ui-forms.html + \previouspage qtquick-annotations.html \if defined(qtdesignstudio) - \previouspage qmldesigner-pathview-editor.html \nextpage creator-live-preview.html \else - \previouspage qtquick-iso-icon-browser.html \nextpage creator-qml-modules-with-plugins.html \endif diff --git a/doc/qtdesignstudio/src/qtdesignstudio-prototyping.qdoc b/doc/qtcreator/src/qtquick/qtquick-uis.qdoc similarity index 85% rename from doc/qtdesignstudio/src/qtdesignstudio-prototyping.qdoc rename to doc/qtcreator/src/qtquick/qtquick-uis.qdoc index d511c23359f..198949974b3 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-prototyping.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-uis.qdoc @@ -24,17 +24,23 @@ ****************************************************************************/ /*! - \contentspage {Qt Design Studio Manual} + \contentspage index.html + \page quick-uis.html + \if defined(qtdesignstudio) \previouspage quick-converting-ui-projects.html - \page studio-prototyping.html + \else + \previouspage creator-using-qt-quick-designer.html + \endif \nextpage quick-components.html \title Creating UIs + \if defined(qtdesignstudio) When you install \QDS, everything you'll need to design UIs using \l{Qt Quick} and to preview them on the desktop or on Android or embedded Linux devices is automatically installed and configured correctly for you. + \endif Qt Quick enables you to build UIs around the behavior of \e components and how they connect with one another. You @@ -45,7 +51,7 @@ visible to users, while others are used behind the scene. While it is useful to learn the basics of Qt Quick, you can also rely on - \QDS to write the code for you when you drag-and-drop the ready-made + \QMLD to write the code for you when you drag-and-drop the ready-made components to the working area and change them to your liking by modifying their properties in the Design mode. You can always check up details in the extensive Qt Quick documentation by pressing \key F1. @@ -76,13 +82,21 @@ \li \l {Using Custom Fonts} - You can load custom fonts to \QDS and use them in your designs. + You can load custom fonts to \QMLD and use them in your designs. + + \li \l {Annotating Designs} + + You can annotate your designs to provide reviewers or developers + with additional information about them. + + \if defined(qtdesignstudio) \endlist \section1 Related Topics \list - \li \l{Qt Quick UI Forms} + \endif + \li \l{Qt Quick UI Forms} Some of the wizards create Qt Quick projects that contain UI forms (.ui.qml files). The forms use a purely declarative subset of the diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-setup.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-setup.qdoc index 0268fd04af2..1261ee4d85f 100644 --- a/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-setup.qdoc +++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-setup.qdoc @@ -25,7 +25,7 @@ /*! - \contentspage {Qt Design Studio} + \contentspage index.html \previouspage psqtbridge.html \page qtbridge-ps-setup.html \nextpage qtbridge-ps-using.html diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-sketch-setup.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-sketch-setup.qdoc index 4c761b90d09..1f7a49d2e0d 100644 --- a/doc/qtdesignstudio/src/qtbridge/qtbridge-sketch-setup.qdoc +++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-sketch-setup.qdoc @@ -25,7 +25,7 @@ /*! - \contentspage {Qt Design Studio} + \contentspage index.html \previouspage sketchqtbridge.html \page qtbridge-sketch-setup.html \nextpage qtbridge-sketch-using.html diff --git a/doc/qtdesignstudio/src/qtdesignstudio-advanced.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-advanced.qdoc index b10c89527ca..1b4fc732849 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-advanced.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-advanced.qdoc @@ -24,7 +24,7 @@ ****************************************************************************/ /*! - \contentspage {Qt Design Studio} + \contentspage index.html \previouspage qt-design-viewer.html \page studio-advanced.html \nextpage studio-platforms.html diff --git a/doc/qtdesignstudio/src/qtdesignstudio-importing-2d.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-importing-2d.qdoc new file mode 100644 index 00000000000..9b9bd856044 --- /dev/null +++ b/doc/qtdesignstudio/src/qtdesignstudio-importing-2d.qdoc @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Bridge documentation. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** +****************************************************************************/ + +/*! + \contentspage index.html + \previouspage studio-importing-designs.html + \page studio-importing-2d.html + \nextpage studio-importing-3d.html + + \title Importing 2D Assets + + \image studio-imported-assets.png "Artwork imported into Qt Design Studio" + + You can import assets that you exported with \QB to a \QDS project as image + and QML files and edit them in the Design mode. If you make changes to your + design in the design tool, you can merge the changes into existing QML files + without overwriting the changes you have made in \QDS. + + \note Attempting to import assets exported on another system might fail. + + The following instructions use an empty project as an example. For more + information about the options you have, see + \l {Creating Projects}. + + To import designs to \QDS projects: + + \list 1 + \li Select \uicontrol File > \uicontrol {New File or Project} > + \uicontrol General > \uicontrol Choose, and follow the + instructions of the wizard to create an empty project. + \li In \uicontrol Projects, double-click \e Screen01.ui.qml to move to + the Design mode. + \li Select \uicontrol Library > \uicontrol Assets > + \uicontrol {Add New Assets}. + \li Select the folder where you exported the assets. + \li Select \uicontrol {Exported Assets (*.metadata)} in the dropdown + menu to filter \e .metadata files. + \li Select a \e .metadata file to import, and then select + \uicontrol Open. + \li Select \uicontrol Details next to the + \uicontrol {Metadata Import Paths} field to display the path where + the metadata is imported from. + \image studio-import-metadata.png "Asset Import dialog" + \li Select \uicontrol Details next to the + \uicontrol {QML/Asset Export Paths} field to display the paths to + copy the assets to. + \li In the \uicontrol QML field, you can change the folder to copy the + QML files to. + \li In the \uicontrol Assets field, you can change the folder to copy + the image files to. + \li Deselect the \uicontrol {Import assets} check box if you only want + to create QML files. + \li Deselect the \uicontrol {Generate QML} check box if you only + want to import assets. + \li Select the \uicontrol {Merge QML} check box if you have imported the + assets before and want to merge the changes into existing QML files + instead of overwriting the existing files. + \li Select \uicontrol Import to import the QML files and assets. This + might take a little while for complex projects. + \endlist + + The imported assets are displayed in the \uicontrol Assets tab in the + \uicontrol Library as PNG images. The components that you specified in + the design tool are displayed in the \uicontrol {My QML Components} tab, + as well as in the \uicontrol Project tab of the \uicontrol Navigator as + separate QML files. + + \note The layer that was the bottom layer in the design tool becames the top + layer in the \uicontrol Navigator to reflect the QML code model. You + can view the QML code in the \uicontrol {Text Editor} tab. + + If asset importer conflicts, warnings, and errors are displayed in the + \uicontrol {Asset Import} dialog while importing, fix the issues in + design tool and export the assets again. + + \section1 \QB Videos + + For more information about importing assets from Adobe Photoshop, watch a + video tutorial and webinar about using \QB: + + \list + \li \l{https://resources.qt.io/development-topic-ui-design/qtdesignstudio-clustertutorial-partone} + {Building an Instrument Cluster for Your Car HMI, Part 1} + \li \l{https://www.youtube.com/watch?v=ZzbucmQPU44} + {From Photoshop to Prototype with Qt Design Studio} + \endlist +*/ diff --git a/doc/qtdesignstudio/src/qtdesignstudio-importing-designs.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-importing-designs.qdoc index ce53ae2ccd0..8ad05eba811 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-importing-designs.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-importing-designs.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Bridge documentation. @@ -24,7 +24,7 @@ ****************************************************************************/ /*! - \contentspage {Qt Design Studio} + \contentspage index.html \previouspage creator-vcs-git.html \page studio-importing-designs.html \nextpage studio-importing-2d.html @@ -47,131 +47,3 @@ You can then edit them in the Design mode. \endlist */ - -/*! - \contentspage {Qt Design Studio} - \previouspage studio-importing-designs.html - \page studio-importing-2d.html - \nextpage studio-importing-3d.html - - \title Importing 2D Assets - - \image studio-imported-assets.png "Artwork imported into Qt Design Studio" - - You can import assets that you exported with \QB to a \QDS project as image - and QML files and edit them in the Design mode. If you make changes to your - design in the design tool, you can merge the changes into existing QML files - without overwriting the changes you have made in \QDS. - - \note Attempting to import assets exported on another system might fail. - - The following instructions use an empty project as an example. For more - information about the options you have, see - \l {Creating Projects}. - - To import designs to \QDS projects: - - \list 1 - \li Select \uicontrol File > \uicontrol {New File or Project} > - \uicontrol General > \uicontrol Choose, and follow the - instructions of the wizard to create an empty project. - \li In \uicontrol Projects, double-click \e Screen01.ui.qml to move to - the Design mode. - \li Select \uicontrol Library > \uicontrol Assets > - \uicontrol {Add New Assets}. - \li Select the folder where you exported the assets. - \li Select \uicontrol {Exported Assets (*.metadata)} in the dropdown - menu to filter \e .metadata files. - \li Select a \e .metadata file to import, and then select - \uicontrol Open. - \li Select \uicontrol Details next to the - \uicontrol {Metadata Import Paths} field to display the path where - the metadata is imported from. - \image studio-import-metadata.png "Asset Import dialog" - \li Select \uicontrol Details next to the - \uicontrol {QML/Asset Export Paths} field to display the paths to - copy the assets to. - \li In the \uicontrol QML field, you can change the folder to copy the - QML files to. - \li In the \uicontrol Assets field, you can change the folder to copy - the image files to. - \li Deselect the \uicontrol {Import assets} check box if you only want - to create QML files. - \li Deselect the \uicontrol {Generate QML} check box if you only - want to import assets. - \li Select the \uicontrol {Merge QML} check box if you have imported the - assets before and want to merge the changes into existing QML files - instead of overwriting the existing files. - \li Select \uicontrol Import to import the QML files and assets. This - might take a little while for complex projects. - \endlist - - The imported assets are displayed in the \uicontrol Assets tab in the - \uicontrol Library as PNG images. The components that you specified in - the design tool are displayed in the \uicontrol {My QML Components} tab, - as well as in the \uicontrol Project tab of the \uicontrol Navigator as - separate QML files. - - \note The layer that was the bottom layer in the design tool becames the top - layer in the \uicontrol Navigator to reflect the QML code model. You - can view the QML code in the \uicontrol {Text Editor} tab. - - If asset importer conflicts, warnings, and errors are displayed in the - \uicontrol {Asset Import} dialog while importing, fix the issues in - design tool and export the assets again. - - \section1 \QB Videos - - For more information about importing assets from Adobe Photoshop, watch a - video tutorial and webinar about using \QB: - - \list - \li \l{https://resources.qt.io/development-topic-ui-design/qtdesignstudio-clustertutorial-partone} - {Building an Instrument Cluster for Your Car HMI, Part 1} - \li \l{https://www.youtube.com/watch?v=ZzbucmQPU44} - {From Photoshop to Prototype with Qt Design Studio} - \endlist -*/ - -/*! - \contentspage {Qt Design Studio} - \previouspage studio-importing-2d.html - \page studio-importing-3d.html - \nextpage quick-converting-ui-projects.html - - \title Importing 3D Assets - - You can import files you created using 3D graphics applications and stored - in several widely-used formats, such as .blend, .dae, .fbx, .glb, .gltf, - .obj, .uia, or .uip. For a list of formats supported by each \l{Qt Quick 3D} - version, see the module documentation. - - For more information about exporting 3D graphics from Maya, see - \l{Exporting from Maya}. - - During the import, you can optimize the files for \QDS. You can remove - components from meshes to reduce the cache size, find and fix issues in - the files, optimize graphs and meshes, and so on. The available options - depend on whether you are importing files that you created with Qt 3D Studio - or with other 3D graphics tools. See the tooltips in the options dialog - for more information about a particular option. - - \image studio-import-3d.png - - To import 3D assets to \QDS projects: - - \list 1 - \li In the Design mode, select \uicontrol Library > \uicontrol Assets - > \uicontrol {Add New Assets}. - \li Select \uicontrol {3D Assets} in the dropdown menu to filter 3D - graphics files. - \li Select a file to import, and then select \uicontrol Open. - \li In the \uicontrol {3D Scene Options} tab, select options for - importing the file. - \li Select \uicontrol Import to import the 3D graphics file. - \li When the import is done, select \uicontrol Close. - \endlist - - You can open the imported files in the Design mode for editing in the - \l{Editing 3D Scenes}{3D editor}. -*/ diff --git a/doc/qtdesignstudio/src/qtdesignstudio-javascript.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-javascript.qdoc index a0e5926adb4..a182ba79515 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-javascript.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-javascript.qdoc @@ -24,7 +24,7 @@ ****************************************************************************/ /*! - \contentspage {Qt Design Studio} + \contentspage index.html \previouspage creator-editor-options-text.html \page studio-javascript.html \nextpage studio-debugging.html diff --git a/doc/qtdesignstudio/src/qtdesignstudio-platforms.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-platforms.qdoc index 2f48bdf68d2..0e4e52a2783 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-platforms.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-platforms.qdoc @@ -24,7 +24,7 @@ ****************************************************************************/ /*! - \contentspage {Qt Design Studio} + \contentspage index.html \previouspage studio-advanced.html \page studio-platforms.html \nextpage creator-keyboard-shortcuts.html diff --git a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc index 4c7af21e010..a578d73c32a 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc @@ -24,7 +24,7 @@ ****************************************************************************/ /*! - \contentspage {Qt Design Studio} + \contentspage index.html \page qtdesignstudio-toc.html \title All Topics @@ -76,6 +76,7 @@ \li \l{Managing Item Hierarchy} \li \l{Specifying Item Properties} \li \l{Using Custom Fonts} + \li \l{Annotating Designs} \li \l{Qt Quick UI Forms} \endlist \li \l {Adding Dynamics} @@ -90,7 +91,7 @@ \li \l{Adding States} \li \l{Editing PathView Properties} \endlist - \li \b {\l{Editing 3D Scenes}} + \li \l{Editing 3D Scenes} \list \li \l{Editing 3D Assets in Design Mode} \li \l{Working in the 3D Editor} diff --git a/doc/qtdesignstudio/src/qtdesignstudio.qdoc b/doc/qtdesignstudio/src/qtdesignstudio.qdoc index 6195330faeb..1a696084f43 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio.qdoc @@ -62,6 +62,7 @@ \li \l{Managing Item Hierarchy} \li \l{Specifying Item Properties} \li \l{Using Custom Fonts} + \li \l{Annotating Designs} \endlist \li \b {\l{Adding Dynamics}} \list diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/exporting-3d/exporting-3d-assets.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/exporting-3d/exporting-3d-assets.qdoc index e0cc8e09337..ce448c3f20f 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/exporting-3d/exporting-3d-assets.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/exporting-3d/exporting-3d-assets.qdoc @@ -27,9 +27,13 @@ ****************************************************************************/ /*! - \contentspage {Qt Design Studio} + \contentspage index.html \page exporting-3d-assets.html + \if defined(qtdesignstudio) \previouspage qtbridge-sketch-using.html + \else + \previouspage studio-3d.html + \endif \nextpage exporting-from-blender.html \title Exporting 3D Assets diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/exporting-3d/exporting-from-maya.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/exporting-3d/exporting-from-maya.qdoc index 53d3009a782..8903bc238ae 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/exporting-3d/exporting-from-maya.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/exporting-3d/exporting-from-maya.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Design Studio. @@ -26,10 +26,14 @@ ****************************************************************************/ /*! - \contentspage {Qt Design Studio Manual} + \contentspage index.html \page exporting-from-maya.html - \previouspage qtbridge-sketch-using.html + \previouspage exporting-from-blender.html + \if defined (qtdesignstudio) \nextpage creator-quick-tour.html + \else + \nextpage studio-importing-3d.html + \endif \title Exporting from Maya diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-design-mode.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-design-mode.qdoc index da2964d5ba3..947e72cc258 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-design-mode.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-design-mode.qdoc @@ -24,9 +24,13 @@ ****************************************************************************/ /*! - \contentspage {Qt Design Studio} - \previouspage studio-3d.html + \contentspage index.html \page studio-3d-design-mode.html + \if defined (qtdesignstudio) + \previouspage studio-3d.html + \else + \previouspage studio-importing-3d.html + \endif \nextpage studio-3d-editor.html \title Editing 3D Assets in Design Mode diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc index 1e340182b51..71eedd4dfb0 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-editor.qdoc @@ -24,7 +24,7 @@ ****************************************************************************/ /*! - \contentspage {Qt Design Studio} + \contentspage index.html \previouspage studio-3d-design-mode.html \page studio-3d-editor.html \nextpage studio-3d-view.html diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc new file mode 100644 index 00000000000..17f7482233c --- /dev/null +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-importing.qdoc @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Bridge documentation. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** +****************************************************************************/ + +/*! + \contentspage index.html + \page studio-importing-3d.html + \if defined(qtdesignstudio) + \previouspage studio-importing-2d.html + \nextpage quick-converting-ui-projects.html + \else + \previouspage exporting-from-maya.html + \nextpage studio-3d-design-mode.html + \endif + + \title Importing 3D Assets + + You can import files you created using 3D graphics applications and stored + in several widely-used formats, such as .blend, .dae, .fbx, .glb, .gltf, + .obj, .uia, or .uip. For a list of formats supported by each \l{Qt Quick 3D} + version, see the module documentation. + + For more information about exporting 3D graphics from Maya, see + \l{Exporting from Maya}. + + During the import, you can optimize the files for \QDS. You can remove + components from meshes to reduce the cache size, find and fix issues in + the files, optimize graphs and meshes, and so on. The available options + depend on whether you are importing files that you created with Qt 3D Studio + or with other 3D graphics tools. See the tooltips in the options dialog + for more information about a particular option. + + \image studio-import-3d.png + + To import 3D assets to \QDS projects: + + \list 1 + \li In the Design mode, select \uicontrol Library > \uicontrol Assets + > \uicontrol {Add New Assets}. + \li Select \uicontrol {3D Assets} in the dropdown menu to filter 3D + graphics files. + \li Select a file to import, and then select \uicontrol Open. + \li In the \uicontrol {3D Scene Options} tab, select options for + importing the file. + \li Select \uicontrol Import to import the 3D graphics file. + \li When the import is done, select \uicontrol Close. + \endlist + + You can open the imported files in the Design mode for editing in the + \l{Editing 3D Scenes}{3D editor}. +*/ diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-node.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-node.qdoc index 211085fd3c4..b9fb65731ca 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-node.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-node.qdoc @@ -24,7 +24,7 @@ ****************************************************************************/ /*! - \contentspage {Qt Design Studio} + \contentspage index.html \previouspage studio-3d-components.html \page studio-3d-node.html \nextpage studio-3d-model.html diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-scene-environment.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-scene-environment.qdoc index 09511108862..3844439569f 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-scene-environment.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-scene-environment.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of Qt Design Studio. @@ -29,7 +29,11 @@ \contentspage {Qt Design Studio Manual} \page studio-3d-scene-environment.html \previouspage studio-3d-camera.html + \if defined (qtdesignstudio) \nextpage creator-live-preview.html + \else + \nextpage qtquick-iso-icon-browser.html + \endif \title Setting Scene Environment diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-view.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-view.qdoc index 4c61d12a128..ae1e50e0d33 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-view.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-view.qdoc @@ -24,7 +24,7 @@ ****************************************************************************/ /*! - \contentspage {Qt Design Studio} + \contentspage index.html \previouspage studio-3d-editor.html \page studio-3d-view.html \nextpage studio-3d-components.html diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d.qdoc index 03f3085ad60..976ae9aca4e 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 The Qt Company Ltd. +** Copyright (C) 2020 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Design Studio documentation. @@ -24,10 +24,15 @@ ****************************************************************************/ /*! - \contentspage {Qt Design Studio Manual} + \contentspage index.html \page studio-3d.html \previouspage qmldesigner-pathview-editor.html + \if defined(qtdesignstudio) \nextpage studio-3d-design-mode.html + \else + \nextpage exporting-3d-assets.html + \endif + \title Editing 3D Scenes @@ -45,6 +50,20 @@ The following topics contain information about working with Qt Quick 3D: \list + \if defined (qtcreator) + \li \l {Exporting 3D Assets} + + You can import files you created using 3D graphics applications and + stored in several widely-used formats, such as .blend, .dae, .fbx, + .glb, .gltf, .obj, .uia, or .uip. + + \li \l{Importing 3D Assets} + + You can import 3D assets that you created using 3D graphics + applications and stored in one of the supported file formats. + You can then edit them in the Design mode. + \endif + \li \l {Editing 3D Assets in Design Mode} \QDS opens QML files that contain 3D scenes in the Design mode and diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/CameraGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/CameraGizmo.qml index bd55fd4a006..e522a60cf48 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/CameraGizmo.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/CameraGizmo.qml @@ -24,11 +24,12 @@ ****************************************************************************/ import QtQuick 2.0 +import QtQuick3D 1.15 IconGizmo { id: cameraGizmo - property var frustumModel: null + property Model frustumModel: null iconSource: "qrc:///qtquickplugin/mockfiles/images/editor_camera.png" diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml index 8fab6ff0e42..3910b36fd7f 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/EditView3D.qml @@ -134,7 +134,7 @@ Item { function fitToView() { if (editView) { - var targetNode = selectedNodes.length > 0 + var targetNode = selectionBoxes.length > 0 ? selectionBoxes[0].model : null; cameraControl.focusObject(targetNode, editView.camera.eulerRotation, true); } @@ -301,16 +301,20 @@ Item { } // No free gizmos available, create a new one - var component = Qt.createComponent("LightGizmo.qml"); - if (component.status === Component.Ready) { - var gizmo = component.createObject(overlayView, - {"view3D": overlayView, "targetNode": obj, - "selectedNodes": selectedNodes, "scene": scene, - "activeScene": activeScene}); + var gizmoComponent = Qt.createComponent("LightGizmo.qml"); + var modelComponent = Qt.createComponent("LightModel.qml"); + if (gizmoComponent.status === Component.Ready && modelComponent.status === Component.Ready) { + var geometryName = _generalHelper.generateUniqueName("LightGeometry"); + var model = modelComponent.createObject(overlayScene, {"geometryName": geometryName}); + var gizmo = gizmoComponent.createObject(overlayView, + {"view3D": overlayView, "targetNode": obj, + "selectedNodes": selectedNodes, "scene": scene, + "activeScene": activeScene}); lightGizmos[lightGizmos.length] = gizmo; gizmo.clicked.connect(handleObjectClicked); gizmo.selectedNodes = Qt.binding(function() {return selectedNodes;}); gizmo.activeScene = Qt.binding(function() {return activeScene;}); + gizmo.connectModel(model); } } diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml index 9f9f0d23263..9a956c67236 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/LightGizmo.qml @@ -29,14 +29,40 @@ import QtQuick3D 1.15 IconGizmo { id: lightGizmo + property Model lightModel: null + iconSource: targetNode ? targetNode instanceof DirectionalLight ? "qrc:///qtquickplugin/mockfiles/images/directional_light_gradient.png" : targetNode instanceof AreaLight ? "qrc:///qtquickplugin/mockfiles/images/area_light_gradient.png" - : "qrc:///qtquickplugin/mockfiles/images/point_light_gradient.png" + : targetNode instanceof PointLight + ? "qrc:///qtquickplugin/mockfiles/images/point_light_gradient.png" + : "qrc:///qtquickplugin/mockfiles/images/spot_light_gradient.png" : "qrc:///qtquickplugin/mockfiles/images/point_light_gradient.png" // ColorOverlay doesn't work correctly with hidden windows so commenting it out for now //overlayColor: targetNode ? targetNode.color : "transparent" + + function connectModel(model) + { + lightModel = model; + + model.selected = selected; + model.selected = Qt.binding(function() {return selected;}); + + model.scene = scene; + model.scene = Qt.binding(function() {return scene;}); + + model.targetNode = targetNode; + model.targetNode = Qt.binding(function() {return targetNode;}); + + model.visible = visible; + model.visible = Qt.binding(function() {return visible;}); + } + + onActiveSceneChanged: { + if (lightModel && activeScene == scene) + lightModel.updateGeometry(); + } } diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/LightModel.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/LightModel.qml new file mode 100644 index 00000000000..86bebf19d28 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/LightModel.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick3D 1.15 +import LightGeometry 1.0 + +Model { + id: lightModel + + property string geometryName + property alias geometryName: lightGeometry.name // Name must be unique for each geometry + property Node targetNode: null + property Node scene: null + property bool selected: false + + function updateGeometry() + { + lightGeometry.update(); + } + + position: targetNode ? targetNode.scenePosition : Qt.vector3d(0, 0, 0) + rotation: targetNode ? targetNode.sceneRotation : Qt.quaternion(1, 0, 0, 0) + scale: Qt.vector3d(50, 50, 50) + + geometry: lightGeometry + materials: [ + DefaultMaterial { + id: defaultMaterial + emissiveColor: lightModel.selected ? "#FF0000" : "#555555" + lighting: DefaultMaterial.NoLighting + cullMode: Material.NoCulling + } + ] + + LightGeometry { + id: lightGeometry + light: lightModel.scene && lightModel.targetNode ? lightModel.targetNode : null + } +} diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/ToggleButton.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/ToggleButton.qml index a0ebeabbd47..5ecad59a3b0 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/ToggleButton.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/ToggleButton.qml @@ -35,20 +35,13 @@ Rectangle { id: root color: toggleBackground && toggled ? "#aa000000" : mouseArea.containsMouse ? "#44000000" : "#00000000" - width: img.width + txt.width + 5 - height: img.height - - Image { - id: img - anchors.verticalCenter: parent.verticalCenter - source: "qrc:///qtquickplugin/mockfiles/images/" + root.states[toggled ? 1 : 0].iconId + ".png" - } + width: txt.width + 5 + height: 16 Text { id: txt color: "#b5b5b5" anchors.verticalCenter: parent.verticalCenter - anchors.left: img.right text: root.states[toggled ? 1 : 0].text } diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/ToolBarButton.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/ToolBarButton.qml index f3f69cdb0e8..8953559e50e 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/ToolBarButton.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/ToolBarButton.qml @@ -41,8 +41,8 @@ Rectangle { property var _buttonGroupArray: [] id: root - width: img.width + 5 - height: img.height + 5 + width: 16 + height: 16 color: root.selected ? "#aa000000" : (mouseArea.containsMouse ? "#44000000" : "#00000000") radius: 3 @@ -65,13 +65,6 @@ Rectangle { delay: 1000 } - Image { - id: img - anchors.centerIn: parent - source: root.selected ? "qrc:///qtquickplugin/mockfiles/images/" + root.tool + "_selected.png" - : "qrc:///qtquickplugin/mockfiles/images/" + root.tool + "_active.png" - } - Shortcut { sequence: root.currentShortcut onActivated: mouseArea.onClicked(null) diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient.png index f3c013e157d..c743c54630a 100644 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient.png and b/share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient.png differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient@2x.png index 87d60515f50..1ec1148da93 100644 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient@2x.png and b/share/qtcreator/qml/qmlpuppet/mockfiles/images/directional_light_gradient@2x.png differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_off.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_off.png deleted file mode 100644 index 73e6e92374b..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_off.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_off@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_off@2x.png deleted file mode 100644 index 5166264e16d..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_off@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_on.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_on.png deleted file mode 100644 index 7660c285460..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_on.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_on@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_on@2x.png deleted file mode 100644 index 836bd2a0d59..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/edit_light_on@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_active.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_active.png deleted file mode 100644 index 056e9ec3c8b..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_active.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_active@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_active@2x.png deleted file mode 100644 index 4b05f83d460..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_active@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_selected.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_selected.png deleted file mode 100644 index b8f98d9f120..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_selected.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_selected@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_selected@2x.png deleted file mode 100644 index eac43612532..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/fit_selected@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/global.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/global.png deleted file mode 100644 index 1bd09c680ac..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/global.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/global@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/global@2x.png deleted file mode 100644 index a2a857fb10c..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/global@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/group_selection_active.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/group_selection_active.png deleted file mode 100644 index c5801b34654..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/group_selection_active.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/group_selection_active@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/group_selection_active@2x.png deleted file mode 100644 index 85851c7c130..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/group_selection_active@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/group_selection_selected.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/group_selection_selected.png deleted file mode 100644 index bfb848aa384..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/group_selection_selected.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/group_selection_selected@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/group_selection_selected@2x.png deleted file mode 100644 index f18895dc440..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/group_selection_selected@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/item_selection_active.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/item_selection_active.png deleted file mode 100644 index 5fa81302cde..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/item_selection_active.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/item_selection_active@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/item_selection_active@2x.png deleted file mode 100644 index 566da2ef1af..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/item_selection_active@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/item_selection_selected.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/item_selection_selected.png deleted file mode 100644 index 2b685d3d00a..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/item_selection_selected.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/item_selection_selected@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/item_selection_selected@2x.png deleted file mode 100644 index eb0051a606e..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/item_selection_selected@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/light-pick-icon.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/light-pick-icon.png deleted file mode 100644 index b6ac242cbda..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/light-pick-icon.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/light-pick-icon@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/light-pick-icon@2x.png deleted file mode 100644 index d3b041a6043..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/light-pick-icon@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/local.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/local.png deleted file mode 100644 index 0a608f6816e..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/local.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/local@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/local@2x.png deleted file mode 100644 index a5c931e750f..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/local@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/move_active.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/move_active.png deleted file mode 100644 index d21d290349c..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/move_active.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/move_active@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/move_active@2x.png deleted file mode 100644 index bd0827f918c..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/move_active@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/move_selected.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/move_selected.png deleted file mode 100644 index 5c8ce42a758..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/move_selected.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/move_selected@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/move_selected@2x.png deleted file mode 100644 index fad362a3e6a..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/move_selected@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/ortho.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/ortho.png deleted file mode 100644 index 35b36203fa2..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/ortho.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/ortho@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/ortho@2x.png deleted file mode 100644 index 443c73e444b..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/ortho@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/persp.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/persp.png deleted file mode 100644 index 9a48e763996..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/persp.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/persp@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/persp@2x.png deleted file mode 100644 index 88a4eab9c6a..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/persp@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/rotate_active.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/rotate_active.png deleted file mode 100644 index bdabaf30285..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/rotate_active.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/rotate_active@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/rotate_active@2x.png deleted file mode 100644 index 8c81f409d32..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/rotate_active@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/rotate_selected.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/rotate_selected.png deleted file mode 100644 index 42dc2763ce4..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/rotate_selected.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/rotate_selected@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/rotate_selected@2x.png deleted file mode 100644 index b6cc48c0533..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/rotate_selected@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/scale_active.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/scale_active.png deleted file mode 100644 index cd63c1d03bc..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/scale_active.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/scale_active@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/scale_active@2x.png deleted file mode 100644 index 0d95e8e8913..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/scale_active@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/scale_selected.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/scale_selected.png deleted file mode 100644 index 4cca7726170..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/scale_selected.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/scale_selected@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/scale_selected@2x.png deleted file mode 100644 index 690cf5f924f..00000000000 Binary files a/share/qtcreator/qml/qmlpuppet/mockfiles/images/scale_selected@2x.png and /dev/null differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/spot_light_gradient.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/spot_light_gradient.png new file mode 100644 index 00000000000..9bf201f9320 Binary files /dev/null and b/share/qtcreator/qml/qmlpuppet/mockfiles/images/spot_light_gradient.png differ diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/images/spot_light_gradient@2x.png b/share/qtcreator/qml/qmlpuppet/mockfiles/images/spot_light_gradient@2x.png new file mode 100644 index 00000000000..0a4b6b29c75 Binary files /dev/null and b/share/qtcreator/qml/qmlpuppet/mockfiles/images/spot_light_gradient@2x.png differ diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/camerageometry.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/camerageometry.cpp index 15fe79082a5..9c81fdc9703 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/camerageometry.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/camerageometry.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -70,31 +71,31 @@ void CameraGeometry::setCamera(QQuick3DCamera *camera) m_camera = camera; if (auto perspectiveCamera = qobject_cast(m_camera)) { QObject::connect(perspectiveCamera, &QQuick3DPerspectiveCamera::clipNearChanged, - this, &CameraGeometry::update); + this, &CameraGeometry::handleCameraPropertyChange); QObject::connect(perspectiveCamera, &QQuick3DPerspectiveCamera::clipFarChanged, - this, &CameraGeometry::update); + this, &CameraGeometry::handleCameraPropertyChange); QObject::connect(perspectiveCamera, &QQuick3DPerspectiveCamera::fieldOfViewChanged, - this, &CameraGeometry::update); + this, &CameraGeometry::handleCameraPropertyChange); QObject::connect(perspectiveCamera, &QQuick3DPerspectiveCamera::fieldOfViewOrientationChanged, - this, &CameraGeometry::update); + this, &CameraGeometry::handleCameraPropertyChange); if (auto frustumCamera = qobject_cast(m_camera)) { QObject::connect(frustumCamera, &QQuick3DFrustumCamera::topChanged, - this, &CameraGeometry::update); + this, &CameraGeometry::handleCameraPropertyChange); QObject::connect(frustumCamera, &QQuick3DFrustumCamera::bottomChanged, - this, &CameraGeometry::update); + this, &CameraGeometry::handleCameraPropertyChange); QObject::connect(frustumCamera, &QQuick3DFrustumCamera::rightChanged, - this, &CameraGeometry::update); + this, &CameraGeometry::handleCameraPropertyChange); QObject::connect(frustumCamera, &QQuick3DFrustumCamera::leftChanged, - this, &CameraGeometry::update); + this, &CameraGeometry::handleCameraPropertyChange); } } else if (auto orthoCamera = qobject_cast(m_camera)) { QObject::connect(orthoCamera, &QQuick3DOrthographicCamera::clipNearChanged, - this, &CameraGeometry::update); + this, &CameraGeometry::handleCameraPropertyChange); QObject::connect(orthoCamera, &QQuick3DOrthographicCamera::clipFarChanged, - this, &CameraGeometry::update); + this, &CameraGeometry::handleCameraPropertyChange); } else if (auto customCamera = qobject_cast(m_camera)) { QObject::connect(customCamera, &QQuick3DCustomCamera::projectionChanged, - this, &CameraGeometry::update); + this, &CameraGeometry::handleCameraPropertyChange); } emit cameraChanged(); update(); @@ -110,48 +111,28 @@ void CameraGeometry::setViewPortRect(const QRectF &rect) update(); } +void CameraGeometry::handleCameraPropertyChange() +{ + m_cameraUpdatePending = true; + update(); +} + QSSGRenderGraphObject *CameraGeometry::updateSpatialNode(QSSGRenderGraphObject *node) { if (!m_camera) return node; + // If camera properties have been updated, we need to defer updating the frustum geometry + // to the next frame to ensure camera's spatial node has been properly updated. + if (m_cameraUpdatePending) { + QTimer::singleShot(0, this, &CameraGeometry::update); + m_cameraUpdatePending = false; + return node; + } + if (!m_camera->cameraNode()) { -#if QT_VERSION <= QT_VERSION_CHECK(5, 14, 1) - // 5.14.1 doesn't yet have function to force camera node creation, so we must do it - // the hard way - auto camera = new QSSGRenderCamera(); - bool changed = false; - if (auto perspCamera = qobject_cast(m_camera)) { - changed |= qUpdateIfNeeded(camera->clipNear, perspCamera->clipNear()); - changed |= qUpdateIfNeeded(camera->clipFar, perspCamera->clipFar()); - changed |= qUpdateIfNeeded(camera->fov, qDegreesToRadians(perspCamera->fieldOfView())); - changed |= qUpdateIfNeeded(camera->fovHorizontal, perspCamera->fieldOfViewOrientation() - == QQuick3DCamera::FieldOfViewOrientation::Horizontal); - changed |= qUpdateIfNeeded(camera->enableFrustumClipping, perspCamera->frustumCullingEnabled()); - if (auto frustCamera = qobject_cast(m_camera)) { - camera->flags.setFlag(QSSGRenderNode::Flag::CameraFrustumProjection, true); - changed |= qUpdateIfNeeded(camera->top, frustCamera->top()); - changed |= qUpdateIfNeeded(camera->bottom, frustCamera->bottom()); - changed |= qUpdateIfNeeded(camera->right, frustCamera->right()); - changed |= qUpdateIfNeeded(camera->left, frustCamera->left()); - } - } else if (auto orthoCamera = qobject_cast(m_camera)) { - camera->flags.setFlag(QSSGRenderNode::Flag::Orthographic, true); - changed |= qUpdateIfNeeded(camera->clipNear, orthoCamera->clipNear()); - changed |= qUpdateIfNeeded(camera->clipFar, orthoCamera->clipFar()); - changed |= qUpdateIfNeeded(camera->enableFrustumClipping, orthoCamera->frustumCullingEnabled()); - } else if (auto customCamera = qobject_cast(m_camera)) { - camera->flags.setFlag(QSSGRenderNode::Flag::CameraCustomProjection, true); - changed |= qUpdateIfNeeded(camera->projection, customCamera->projection()); - changed |= qUpdateIfNeeded(camera->enableFrustumClipping, customCamera->frustumCullingEnabled()); - } - if (changed) - camera->flags.setFlag(QSSGRenderNode::Flag::CameraDirty); - m_camera->setCameraNode(camera); -#else // Doing explicit viewport mapping forces cameraNode creation m_camera->mapToViewport({}, m_viewPortRect.width(), m_viewPortRect.height()); -#endif } node = QQuick3DGeometry::updateSpatialNode(node); @@ -183,7 +164,7 @@ void CameraGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexDat { const int vertexSize = int(sizeof(float)) * 8 * 3; // 8 vertices, 3 floats/vert vertexData.resize(vertexSize); - const int indexSize = int(sizeof(quint16)) * 12 * 2; // 16 lines, 2 vert/line + const int indexSize = int(sizeof(quint16)) * 12 * 2; // 12 lines, 2 vert/line indexData.resize(indexSize); auto dataPtr = reinterpret_cast(vertexData.data()); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/camerageometry.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/camerageometry.h index 9c0f5e1e3c4..73722cd7a1f 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/camerageometry.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/camerageometry.h @@ -49,6 +49,7 @@ public: public Q_SLOTS: void setCamera(QQuick3DCamera *camera); void setViewPortRect(const QRectF &rect); + void handleCameraPropertyChange(); Q_SIGNALS: void cameraChanged(); @@ -62,6 +63,7 @@ private: QVector3D &minBounds, QVector3D &maxBounds); QQuick3DCamera *m_camera = nullptr; QRectF m_viewPortRect; + bool m_cameraUpdatePending = false; }; } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/editor3d.pri b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/editor3d.pri index c5d7d23b8e0..9a5be562e3c 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/editor3d.pri +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/editor3d.pri @@ -1,6 +1,7 @@ HEADERS += $$PWD/generalhelper.h \ $$PWD/mousearea3d.h \ $$PWD/camerageometry.h \ + $$PWD/lightgeometry.h \ $$PWD/gridgeometry.h \ $$PWD/selectionboxgeometry.h \ $$PWD/linegeometry.h @@ -8,6 +9,7 @@ HEADERS += $$PWD/generalhelper.h \ SOURCES += $$PWD/generalhelper.cpp \ $$PWD/mousearea3d.cpp \ $$PWD/camerageometry.cpp \ + $$PWD/lightgeometry.cpp \ $$PWD/gridgeometry.cpp \ $$PWD/selectionboxgeometry.cpp \ $$PWD/linegeometry.cpp diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/lightgeometry.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/lightgeometry.cpp new file mode 100644 index 00000000000..58d1dc40f28 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/lightgeometry.cpp @@ -0,0 +1,233 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#ifdef QUICK3D_MODULE + +#include "lightgeometry.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace QmlDesigner { +namespace Internal { + +LightGeometry::LightGeometry() + : QQuick3DGeometry() +{ +} + +LightGeometry::~LightGeometry() +{ +} + +QQuick3DAbstractLight *QmlDesigner::Internal::LightGeometry::light() const +{ + return m_light; +} + +void QmlDesigner::Internal::LightGeometry::setLight(QQuick3DAbstractLight *light) +{ + if (m_light == light) + return; + + m_light = light; + + emit lightChanged(); + update(); +} + +QSSGRenderGraphObject *LightGeometry::updateSpatialNode(QSSGRenderGraphObject *node) +{ + if (!m_light) + return node; + + node = QQuick3DGeometry::updateSpatialNode(node); + QSSGRenderGeometry *geometry = static_cast(node); + + geometry->clear(); + + QByteArray vertexData; + QByteArray indexData; + QVector3D minBounds; + QVector3D maxBounds; + fillVertexData(vertexData, indexData, minBounds, maxBounds); + + geometry->addAttribute(QSSGRenderGeometry::Attribute::PositionSemantic, 0, + QSSGRenderGeometry::Attribute::ComponentType::F32Type); + geometry->addAttribute(QSSGRenderGeometry::Attribute::IndexSemantic, 0, + QSSGRenderGeometry::Attribute::ComponentType::U16Type); + geometry->setStride(12); + geometry->setVertexData(vertexData); + geometry->setIndexData(indexData); + geometry->setPrimitiveType(QSSGRenderGeometry::Lines); + geometry->setBounds(minBounds, maxBounds); + + return node; +} + +void LightGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexData, + QVector3D &minBounds, QVector3D &maxBounds) +{ + int vertexSize = 0; + int indexSize = 0; + const int dirSegments = 12; + const int pointLightDensity = 5; + + if (qobject_cast(m_light)) { + // Area light model is a rectangle with perpendicular lines on corners + vertexSize = int(sizeof(float)) * 3 * 8; + indexSize = int(sizeof(quint16)) * 8 * 2; + } else if (qobject_cast(m_light)) { + // Directional light model is a circle with perpendicular lines on circumference vertices + vertexSize = int(sizeof(float)) * 3 * dirSegments * 2; + indexSize = int(sizeof(quint16)) * dirSegments * 2 * 2; + } else if (qobject_cast(m_light)) { + // Point light model is a set of lines radiating from central point. + // We reserve more than we need so we don't have to calculate the actual need here, + // and resize later when we know the exact count. + vertexSize = int(sizeof(float)) * 3 * pointLightDensity * pointLightDensity * 4; + indexSize = int(sizeof(quint16)) * pointLightDensity * pointLightDensity * 4; + } else if (qobject_cast(m_light)) { + // TODO: Spot light model, for now use area light model + vertexSize = int(sizeof(float)) * 3 * dirSegments * 2; + indexSize = int(sizeof(quint16)) * dirSegments * 2 * 2; + } + vertexData.resize(vertexSize); + indexData.resize(indexSize); + + auto dataPtr = reinterpret_cast(vertexData.data()); + auto indexPtr = reinterpret_cast(indexData.data()); + + if (qobject_cast(m_light)) { + *dataPtr++ = -1.f; *dataPtr++ = 1.f; *dataPtr++ = 0.f; + *dataPtr++ = -1.f; *dataPtr++ = -1.f; *dataPtr++ = 0.f; + *dataPtr++ = 1.f; *dataPtr++ = -1.f; *dataPtr++ = 0.f; + *dataPtr++ = 1.f; *dataPtr++ = 1.f; *dataPtr++ = 0.f; + + *dataPtr++ = -1.f; *dataPtr++ = 1.f; *dataPtr++ = -1.f; + *dataPtr++ = -1.f; *dataPtr++ = -1.f; *dataPtr++ = -1.f; + *dataPtr++ = 1.f; *dataPtr++ = -1.f; *dataPtr++ = -1.f; + *dataPtr++ = 1.f; *dataPtr++ = 1.f; *dataPtr++ = -1.f; + + *indexPtr++ = 0; *indexPtr++ = 1; + *indexPtr++ = 1; *indexPtr++ = 2; + *indexPtr++ = 2; *indexPtr++ = 3; + *indexPtr++ = 3; *indexPtr++ = 0; + + *indexPtr++ = 0; *indexPtr++ = 4; + *indexPtr++ = 1; *indexPtr++ = 5; + *indexPtr++ = 2; *indexPtr++ = 6; + *indexPtr++ = 3; *indexPtr++ = 7; + } else if (qobject_cast(m_light)) { + const double segment = M_PI * 2. / double(dirSegments); + for (quint16 i = 0; i < dirSegments; ++i) { + float x = float(qCos(i * segment)); + float y = float(qSin(i * segment)); + *dataPtr++ = x; *dataPtr++ = y; *dataPtr++ = 0.f; + *dataPtr++ = x; *dataPtr++ = y; *dataPtr++ = -1.f; + const quint16 base = i * 2; + *indexPtr++ = base; *indexPtr++ = base + 1; + *indexPtr++ = base; *indexPtr++ = base + 2; + } + // Adjust the final index to complete the circle + *(--indexPtr) = 0; + } else if (qobject_cast(m_light)) { + const double innerRad = .3; + vertexSize = 0; + indexSize = 0; + int vertexIndex = 0; + for (quint16 i = 0; i < pointLightDensity; ++i) { + double latAngle = (((.9 / (pointLightDensity - 1)) * i) + .05) * M_PI; + quint16 longPoints = pointLightDensity * 2 * qSin(latAngle); + latAngle -= M_PI_2; + const double longSegment = M_PI * 2. / double(longPoints); + for (quint16 j = 0; j < longPoints; ++j) { + double longAngle = longSegment * j; + float q = float(qCos(latAngle)); + float x = float(qCos(longAngle) * q); + float y = float(qSin(latAngle)); + float z = float(qSin(longAngle) * q); + + *dataPtr++ = x * innerRad; *dataPtr++ = y * innerRad; *dataPtr++ = z * innerRad; + *dataPtr++ = x; *dataPtr++ = y; *dataPtr++ = z; + *indexPtr++ = vertexIndex; *indexPtr++ = vertexIndex + 1; + + vertexIndex += 2; + vertexSize += 6 * sizeof(float); + indexSize += 2 * sizeof(quint16); + } + } + vertexData.resize(vertexSize); + indexData.resize(indexSize); + } else if (qobject_cast(m_light)) { + // TODO: Spot light model, for now use area light model + *dataPtr++ = -1.f; *dataPtr++ = 1.f; *dataPtr++ = 0.f; + *dataPtr++ = -1.f; *dataPtr++ = -1.f; *dataPtr++ = 0.f; + *dataPtr++ = 1.f; *dataPtr++ = -1.f; *dataPtr++ = 0.f; + *dataPtr++ = 1.f; *dataPtr++ = 1.f; *dataPtr++ = 0.f; + + *dataPtr++ = -1.f; *dataPtr++ = 1.f; *dataPtr++ = -1.f; + *dataPtr++ = -1.f; *dataPtr++ = -1.f; *dataPtr++ = -1.f; + *dataPtr++ = 1.f; *dataPtr++ = -1.f; *dataPtr++ = -1.f; + *dataPtr++ = 1.f; *dataPtr++ = 1.f; *dataPtr++ = -1.f; + + *indexPtr++ = 0; *indexPtr++ = 1; + *indexPtr++ = 1; *indexPtr++ = 2; + *indexPtr++ = 2; *indexPtr++ = 3; + *indexPtr++ = 3; *indexPtr++ = 0; + + *indexPtr++ = 0; *indexPtr++ = 4; + *indexPtr++ = 1; *indexPtr++ = 5; + *indexPtr++ = 2; *indexPtr++ = 6; + *indexPtr++ = 3; *indexPtr++ = 7; + } + + static const float floatMin = std::numeric_limits::lowest(); + static const float floatMax = std::numeric_limits::max(); + auto vertexPtr = reinterpret_cast(vertexData.data()); + minBounds = QVector3D(floatMax, floatMax, floatMax); + maxBounds = QVector3D(floatMin, floatMin, floatMin); + for (int i = 0; i < vertexSize / 12; ++i) { + minBounds[0] = qMin((*vertexPtr)[0], minBounds[0]); + minBounds[1] = qMin((*vertexPtr)[1], minBounds[1]); + minBounds[2] = qMin((*vertexPtr)[2], minBounds[2]); + maxBounds[0] = qMax((*vertexPtr)[0], maxBounds[0]); + maxBounds[1] = qMax((*vertexPtr)[1], maxBounds[1]); + maxBounds[2] = qMax((*vertexPtr)[2], maxBounds[2]); + ++vertexPtr; + } +} + +} +} + +#endif // QUICK3D_MODULE diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/lightgeometry.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/lightgeometry.h new file mode 100644 index 00000000000..5614b3eb406 --- /dev/null +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/lightgeometry.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#ifdef QUICK3D_MODULE + +#include +#include + +namespace QmlDesigner { +namespace Internal { + +class LightGeometry : public QQuick3DGeometry +{ + Q_OBJECT + Q_PROPERTY(QQuick3DAbstractLight *light READ light WRITE setLight NOTIFY lightChanged) + +public: + LightGeometry(); + ~LightGeometry() override; + + QQuick3DAbstractLight *light() const; + +public Q_SLOTS: + void setLight(QQuick3DAbstractLight *light); + +Q_SIGNALS: + void lightChanged(); + +protected: + QSSGRenderGraphObject *updateSpatialNode(QSSGRenderGraphObject *node) override; + +private: + void fillVertexData(QByteArray &vertexData, QByteArray &indexData, + QVector3D &minBounds, QVector3D &maxBounds); + QQuick3DAbstractLight *m_light = nullptr; +}; + +} +} + +QML_DECLARE_TYPE(QmlDesigner::Internal::LightGeometry) + +#endif // QUICK3D_MODULE diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 83fd85202af..91e0ec18d95 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -67,6 +67,7 @@ #include "../editor3d/generalhelper.h" #include "../editor3d/mousearea3d.h" #include "../editor3d/camerageometry.h" +#include "../editor3d/lightgeometry.h" #include "../editor3d/gridgeometry.h" #include "../editor3d/selectionboxgeometry.h" #include "../editor3d/linegeometry.h" @@ -104,6 +105,7 @@ void Qt5InformationNodeInstanceServer::createEditView3D() qmlRegisterRevision("MouseArea3D", 1, 0); qmlRegisterType("MouseArea3D", 1, 0, "MouseArea3D"); qmlRegisterType("CameraGeometry", 1, 0, "CameraGeometry"); + qmlRegisterType("LightGeometry", 1, 0, "LightGeometry"); qmlRegisterType("GridGeometry", 1, 0, "GridGeometry"); qmlRegisterType("SelectionBoxGeometry", 1, 0, "SelectionBoxGeometry"); qmlRegisterType("LineGeometry", 1, 0, "LineGeometry"); diff --git a/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc b/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc index 5d30e496910..0585896fedb 100644 --- a/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc +++ b/share/qtcreator/qml/qmlpuppet/qmlpuppet.qrc @@ -14,6 +14,7 @@ mockfiles/MoveGizmo.qml mockfiles/CameraFrustum.qml mockfiles/CameraGizmo.qml + mockfiles/LightModel.qml mockfiles/LightGizmo.qml mockfiles/IconGizmo.qml mockfiles/Overlay2D.qml @@ -40,49 +41,13 @@ mockfiles/meshes/axishelper.mesh mockfiles/images/editor_camera.png mockfiles/images/editor_camera@2x.png - mockfiles/images/light-pick-icon.png - mockfiles/images/light-pick-icon@2x.png - mockfiles/images/item_selection_active.png - mockfiles/images/item_selection_active@2x.png - mockfiles/images/item_selection_selected.png - mockfiles/images/item_selection_selected@2x.png - mockfiles/images/group_selection_selected.png - mockfiles/images/group_selection_selected@2x.png - mockfiles/images/group_selection_active.png - mockfiles/images/group_selection_active@2x.png - mockfiles/images/move_active.png - mockfiles/images/move_active@2x.png - mockfiles/images/move_selected.png - mockfiles/images/move_selected@2x.png - mockfiles/images/rotate_active.png - mockfiles/images/rotate_active@2x.png - mockfiles/images/rotate_selected.png - mockfiles/images/rotate_selected@2x.png - mockfiles/images/scale_active.png - mockfiles/images/scale_active@2x.png - mockfiles/images/scale_selected.png - mockfiles/images/scale_selected@2x.png mockfiles/images/directional_light_gradient.png mockfiles/images/directional_light_gradient@2x.png mockfiles/images/point_light_gradient.png mockfiles/images/point_light_gradient@2x.png mockfiles/images/area_light_gradient.png mockfiles/images/area_light_gradient@2x.png - mockfiles/images/fit_active.png - mockfiles/images/fit_active@2x.png - mockfiles/images/fit_selected.png - mockfiles/images/fit_selected@2x.png - mockfiles/images/local.png - mockfiles/images/local@2x.png - mockfiles/images/global.png - mockfiles/images/global@2x.png - mockfiles/images/ortho.png - mockfiles/images/ortho@2x.png - mockfiles/images/persp.png - mockfiles/images/persp@2x.png - mockfiles/images/edit_light_off.png - mockfiles/images/edit_light_off@2x.png - mockfiles/images/edit_light_on.png - mockfiles/images/edit_light_on@2x.png + mockfiles/images/spot_light_gradient.png + mockfiles/images/spot_light_gradient@2x.png diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AdvancedSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AdvancedSection.qml index 276284cfc99..4eb7420d740 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AdvancedSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AdvancedSection.qml @@ -99,6 +99,19 @@ Section { } } + Label { + text: "State" + } + SecondColumnLayout { + LineEdit { + backendValue: backendValues.state + showTranslateCheckBox: false + enabled: anchorBackend.hasParent || isBaseState + } + ExpandingSpacer { + } + } + Label { visible: majorQtQuickVersion > 1 text: qsTr("Enabled") diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml index a353d9fec53..2a05bb6622a 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/ItemPane.qml @@ -430,21 +430,21 @@ Rectangle { spacing: -StudioTheme.Values.border AbstractButton { buttonIcon: StudioTheme.Constants.alignLeft - tooltip: qsTr("Align objects to left edge") + tooltip: qsTr("Align left edges.") onClicked: alignDistribute.alignObjects(AlignDistribute.Left, alignToComboBox.currentEnum, keyObjectComboBox.currentText) } AbstractButton { buttonIcon: StudioTheme.Constants.alignCenterHorizontal - tooltip: qsTr("Align objects horizontal center") + tooltip: qsTr("Align horizontal centers.") onClicked: alignDistribute.alignObjects(AlignDistribute.CenterH, alignToComboBox.currentEnum, keyObjectComboBox.currentText) } AbstractButton { buttonIcon: StudioTheme.Constants.alignRight - tooltip: qsTr("Align objects to right edge") + tooltip: qsTr("Align right edges.") onClicked: alignDistribute.alignObjects(AlignDistribute.Right, alignToComboBox.currentEnum, keyObjectComboBox.currentText) @@ -455,21 +455,21 @@ Rectangle { spacing: -StudioTheme.Values.border AbstractButton { buttonIcon: StudioTheme.Constants.alignTop - tooltip: qsTr("Align objects to top edge") + tooltip: qsTr("Align top edges.") onClicked: alignDistribute.alignObjects(AlignDistribute.Top, alignToComboBox.currentEnum, keyObjectComboBox.currentText) } AbstractButton { buttonIcon: StudioTheme.Constants.alignCenterVertical - tooltip: qsTr("Align objects vertical center") + tooltip: qsTr("Align vertical centers.") onClicked: alignDistribute.alignObjects(AlignDistribute.CenterV, alignToComboBox.currentEnum, keyObjectComboBox.currentText) } AbstractButton { buttonIcon: StudioTheme.Constants.alignBottom - tooltip: qsTr("Align objects to bottom edge") + tooltip: qsTr("Align bottom edges.") onClicked: alignDistribute.alignObjects(AlignDistribute.Bottom, alignToComboBox.currentEnum, keyObjectComboBox.currentText) @@ -486,21 +486,21 @@ Rectangle { spacing: -StudioTheme.Values.border AbstractButton { buttonIcon: StudioTheme.Constants.distributeLeft - tooltip: qsTr("Distribute objects left edge") + tooltip: qsTr("Distribute left edges.") onClicked: alignDistribute.distributeObjects(AlignDistribute.Left, alignToComboBox.currentEnum, keyObjectComboBox.currentText) } AbstractButton { buttonIcon: StudioTheme.Constants.distributeCenterHorizontal - tooltip: qsTr("Distribute objects horizontal center") + tooltip: qsTr("Distribute horizontal centers.") onClicked: alignDistribute.distributeObjects(AlignDistribute.CenterH, alignToComboBox.currentEnum, keyObjectComboBox.currentText) } AbstractButton { buttonIcon: StudioTheme.Constants.distributeRight - tooltip: qsTr("Distribute objects right edge") + tooltip: qsTr("Distribute right edges.") onClicked: alignDistribute.distributeObjects(AlignDistribute.Right, alignToComboBox.currentEnum, keyObjectComboBox.currentText) @@ -511,21 +511,21 @@ Rectangle { spacing: -StudioTheme.Values.border AbstractButton { buttonIcon: StudioTheme.Constants.distributeTop - tooltip: qsTr("Distribute objects top edge") + tooltip: qsTr("Distribute top edges.") onClicked: alignDistribute.distributeObjects(AlignDistribute.Top, alignToComboBox.currentEnum, keyObjectComboBox.currentText) } AbstractButton { buttonIcon: StudioTheme.Constants.distributeCenterVertical - tooltip: qsTr("Distribute objects vertical center") + tooltip: qsTr("Distribute vertical centers.") onClicked: alignDistribute.distributeObjects(AlignDistribute.CenterV, alignToComboBox.currentEnum, keyObjectComboBox.currentText) } AbstractButton { buttonIcon: StudioTheme.Constants.distributeBottom - tooltip: qsTr("Distribute objects bottom edge") + tooltip: qsTr("Distribute bottom edges.") onClicked: alignDistribute.distributeObjects(AlignDistribute.Bottom, alignToComboBox.currentEnum, keyObjectComboBox.currentText) @@ -542,7 +542,7 @@ Rectangle { spacing: -StudioTheme.Values.border AbstractButton { buttonIcon: StudioTheme.Constants.distributeSpacingHorizontal - tooltip: qsTr("Distribute spacing horizontal") + tooltip: qsTr("Distribute spacing horizontally.") onClicked: alignDistribute.distributeSpacing(AlignDistribute.X, alignToComboBox.currentEnum, keyObjectComboBox.currentText, @@ -551,7 +551,7 @@ Rectangle { } AbstractButton { buttonIcon: StudioTheme.Constants.distributeSpacingVertical - tooltip: qsTr("Distribute spacing vertical") + tooltip: qsTr("Distribute spacing vertically.") onClicked: alignDistribute.distributeSpacing(AlignDistribute.Y, alignToComboBox.currentEnum, keyObjectComboBox.currentText, diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextInputSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextInputSection.qml index 0a86f113583..cfd972b0854 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextInputSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/TextInputSection.qml @@ -103,7 +103,7 @@ Section { Label { visible: !textInputSection.isTextInput text: qsTr("Text margin") - tooltip: qsTr("Sets the margin, in pixels, around the text in the TextEdit..") + tooltip: qsTr("Sets the margin, in pixels, around the text in the Text Edit.") } SpinBox { visible: !textInputSection.isTextInput diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/AnchorButtons.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/AnchorButtons.qml index 17966d2e9bf..84d5090125f 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/AnchorButtons.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/AnchorButtons.qml @@ -31,7 +31,7 @@ import StudioTheme 1.0 as StudioTheme StudioControls.ButtonRow { id: buttonRow - enabled: anchorBackend.hasParent + enabled: anchorBackend.hasParent && isBaseState opacity: enabled ? 1 : 0.5 actionIndicatorVisible: false diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorCheckButton.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorCheckButton.qml index 9751c7c777a..f45e8661031 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorCheckButton.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ColorCheckButton.qml @@ -81,6 +81,6 @@ Item { hoverEnabled: true anchors.fill: parent anchors.leftMargin: -arrowImage.width - tooltip: qsTr("Toggle color picker view") + tooltip: qsTr("Toggle color picker view.") } } diff --git a/src/libs/advanceddockingsystem/dockcontainerwidget.cpp b/src/libs/advanceddockingsystem/dockcontainerwidget.cpp index 10fdc8cde25..b308879a9f6 100644 --- a/src/libs/advanceddockingsystem/dockcontainerwidget.cpp +++ b/src/libs/advanceddockingsystem/dockcontainerwidget.cpp @@ -595,7 +595,7 @@ namespace ADS { DockWidget *droppedDockWidget = qobject_cast(widget); DockAreaWidget *droppedDockArea = qobject_cast(widget); - DockAreaWidget *newDockArea; + DockAreaWidget *newDockArea = nullptr; if (droppedDockWidget) { newDockArea = new DockAreaWidget(m_dockManager, q); @@ -605,6 +605,18 @@ namespace ADS } newDockArea->addDockWidget(droppedDockWidget); } else { + // We check, if we insert the dropped widget into the same place that + // it already has and do nothing, if it is the same place. It would + // also work without this check, but it looks nicer with the check + // because there will be no layout updates + auto splitter = internal::findParent(droppedDockArea); + auto insertParam = internal::dockAreaInsertParameters(area); + if (splitter == m_rootSplitter && insertParam.orientation() == splitter->orientation()) { + if (insertParam.append() && splitter->lastWidget() == droppedDockArea) + return; + else if (!insertParam.append() && splitter->firstWidget() == droppedDockArea) + return; + } droppedDockArea->dockContainer()->removeDockArea(droppedDockArea); newDockArea = droppedDockArea; } @@ -1217,36 +1229,13 @@ namespace ADS } } - void DockContainerWidget::dropWidget(QWidget *widget, const QPoint &targetPosition) + void DockContainerWidget::dropWidget(QWidget *widget, DockWidgetArea dropArea, DockAreaWidget *targetAreaWidget) { - qCInfo(adsLog) << Q_FUNC_INFO; DockWidget *singleDockWidget = topLevelDockWidget(); - DockAreaWidget *dockArea = dockAreaAt(targetPosition); - auto dropArea = InvalidDockWidgetArea; - auto containerDropArea = d->m_dockManager->containerOverlay()->dropAreaUnderCursor(); - - if (dockArea) { - auto dropOverlay = d->m_dockManager->dockAreaOverlay(); - dropOverlay->setAllowedAreas(dockArea->allowedAreas()); - dropArea = dropOverlay->showOverlay(dockArea); - if (containerDropArea != InvalidDockWidgetArea && containerDropArea != dropArea) { - dropArea = InvalidDockWidgetArea; - } - - if (dropArea != InvalidDockWidgetArea) { - qCInfo(adsLog) << "Dock Area Drop Content: " << dropArea; - d->moveToNewSection(widget, dockArea, dropArea); - } - } - - // mouse is over container - if (InvalidDockWidgetArea == dropArea) { - dropArea = containerDropArea; - qCInfo(adsLog) << "Container Drop Content: " << dropArea; - if (dropArea != InvalidDockWidgetArea) { - d->moveToContainer(widget, dropArea); - } - } + if (targetAreaWidget) + d->moveToNewSection(widget, targetAreaWidget, dropArea); + else + d->moveToContainer(widget, dropArea); // If there was a top level widget before the drop, then it is not top // level widget anymore diff --git a/src/libs/advanceddockingsystem/dockcontainerwidget.h b/src/libs/advanceddockingsystem/dockcontainerwidget.h index 41d1d2f0ba2..0d3b930f5da 100644 --- a/src/libs/advanceddockingsystem/dockcontainerwidget.h +++ b/src/libs/advanceddockingsystem/dockcontainerwidget.h @@ -104,9 +104,13 @@ protected: void dropFloatingWidget(FloatingDockContainer *floatingWidget, const QPoint &targetPos); /** - * Drop a dock area or a dock widget given in widget parameter + * Drop a dock area or a dock widget given in widget parameter. + * If the TargetAreaWidget is a nullptr, then the DropArea indicates + * the drop area for the container. If the given TargetAreaWidget is not + * a nullptr, then the DropArea indicates the drop area in the given + * TargetAreaWidget */ - void dropWidget(QWidget *widget, const QPoint &targetPos); + void dropWidget(QWidget *widget, DockWidgetArea dropArea, DockAreaWidget *targetAreaWidget); /** * Adds the given dock area to this container widget diff --git a/src/libs/advanceddockingsystem/dockmanager.cpp b/src/libs/advanceddockingsystem/dockmanager.cpp index 6adce0111ad..0a621c2c660 100644 --- a/src/libs/advanceddockingsystem/dockmanager.cpp +++ b/src/libs/advanceddockingsystem/dockmanager.cpp @@ -774,15 +774,16 @@ namespace ADS if (!d->m_workspaces.contains(workspace)) return false; - d->m_workspaces.removeOne(workspace); - - emit workspacesRemoved(); - emit workspaceListChanged(); - // Remove corresponding workspace file QFile fi(workspaceNameToFileName(workspace).toString()); - if (fi.exists()) - return fi.remove(); + if (fi.exists()) { + if (fi.remove()) { + d->m_workspaces.removeOne(workspace); + emit workspacesRemoved(); + emit workspaceListChanged(); + return true; + } + } return false; } diff --git a/src/libs/advanceddockingsystem/dockoverlay.cpp b/src/libs/advanceddockingsystem/dockoverlay.cpp index e80fcbba8b0..64558e0d483 100644 --- a/src/libs/advanceddockingsystem/dockoverlay.cpp +++ b/src/libs/advanceddockingsystem/dockoverlay.cpp @@ -399,6 +399,14 @@ namespace ADS { return result; } + DockWidgetArea DockOverlay::visibleDropAreaUnderCursor() const + { + if (isHidden() || !d->m_dropPreviewEnabled) + return InvalidDockWidgetArea; + else + return dropAreaUnderCursor(); + } + DockWidgetArea DockOverlay::showOverlay(QWidget *target) { if (d->m_targetWidget == target) { diff --git a/src/libs/advanceddockingsystem/dockoverlay.h b/src/libs/advanceddockingsystem/dockoverlay.h index 6d1a1925127..e5ee00024e3 100644 --- a/src/libs/advanceddockingsystem/dockoverlay.h +++ b/src/libs/advanceddockingsystem/dockoverlay.h @@ -93,6 +93,13 @@ public: */ DockWidgetArea dropAreaUnderCursor() const; + /** + * This function returns the same like dropAreaUnderCursor() if this + * overlay is not hidden and if drop preview is enabled and returns + * InvalidDockWidgetArea if it is hidden or drop preview is disabled. + */ + DockWidgetArea visibleDropAreaUnderCursor() const; + /** * Show the drop overly for the given target widget */ diff --git a/src/libs/advanceddockingsystem/docksplitter.cpp b/src/libs/advanceddockingsystem/docksplitter.cpp index ec6d8915df5..dfc976298c9 100644 --- a/src/libs/advanceddockingsystem/docksplitter.cpp +++ b/src/libs/advanceddockingsystem/docksplitter.cpp @@ -89,4 +89,14 @@ namespace ADS return false; } + QWidget *DockSplitter::firstWidget() const + { + return (count() > 0) ? widget(0) : nullptr; + } + + QWidget *DockSplitter::lastWidget() const + { + return (count() > 0) ? widget(count() - 1) : nullptr; + } + } // namespace ADS diff --git a/src/libs/advanceddockingsystem/docksplitter.h b/src/libs/advanceddockingsystem/docksplitter.h index 45351a34e22..872f2f04d94 100644 --- a/src/libs/advanceddockingsystem/docksplitter.h +++ b/src/libs/advanceddockingsystem/docksplitter.h @@ -67,6 +67,16 @@ public: * Returns true, if any of the internal widgets is visible */ bool hasVisibleContent() const; + + /** + * Returns first widget or nullptr if splitter is empty + */ + QWidget *firstWidget() const; + + /** + * Returns last widget of nullptr is splitter is empty + */ + QWidget *lastWidget() const; }; // class DockSplitter } // namespace ADS diff --git a/src/libs/advanceddockingsystem/floatingdragpreview.cpp b/src/libs/advanceddockingsystem/floatingdragpreview.cpp index 5732ae408e3..539ef4a11c7 100644 --- a/src/libs/advanceddockingsystem/floatingdragpreview.cpp +++ b/src/libs/advanceddockingsystem/floatingdragpreview.cpp @@ -262,12 +262,14 @@ namespace ADS void FloatingDragPreview::finishDragging() { qCInfo(adsLog) << Q_FUNC_INFO; - auto dockDropArea = d->m_dockManager->dockAreaOverlay()->dropAreaUnderCursor(); - auto containerDropArea = d->m_dockManager->containerOverlay()->dropAreaUnderCursor(); - bool dropPossible = (dockDropArea != InvalidDockWidgetArea) - || (containerDropArea != InvalidDockWidgetArea); - if (d->m_dropContainer && dropPossible) { - d->m_dropContainer->dropWidget(d->m_content, QCursor::pos()); + auto dockDropArea = d->m_dockManager->dockAreaOverlay()->visibleDropAreaUnderCursor(); + auto containerDropArea = d->m_dockManager->containerOverlay()->visibleDropAreaUnderCursor(); + if (d->m_dropContainer && (dockDropArea != InvalidDockWidgetArea)) { + d->m_dropContainer->dropWidget(d->m_content, + dockDropArea, + d->m_dropContainer->dockAreaAt(QCursor::pos())); + } else if (d->m_dropContainer && (containerDropArea != InvalidDockWidgetArea)) { + d->m_dropContainer->dropWidget(d->m_content, containerDropArea, nullptr); } else { DockWidget *dockWidget = qobject_cast(d->m_content); FloatingDockContainer *floatingWidget = nullptr; diff --git a/src/libs/advanceddockingsystem/workspacemodel.cpp b/src/libs/advanceddockingsystem/workspacemodel.cpp index 04ff7b4c757..badf2633687 100644 --- a/src/libs/advanceddockingsystem/workspacemodel.cpp +++ b/src/libs/advanceddockingsystem/workspacemodel.cpp @@ -53,6 +53,7 @@ WorkspaceModel::WorkspaceModel(DockManager *manager, QObject *parent) , m_currentSortColumn(0) { m_sortedWorkspaces = m_manager->workspaces(); + sort(m_currentSortColumn, m_currentSortOrder); connect(m_manager, &DockManager::workspaceLoaded, this, &WorkspaceModel::resetWorkspaces); } diff --git a/src/libs/modelinglib/qmt/stereotype/shapepaintvisitor.cpp b/src/libs/modelinglib/qmt/stereotype/shapepaintvisitor.cpp index 04c5a0a32c4..13ce2b13175 100644 --- a/src/libs/modelinglib/qmt/stereotype/shapepaintvisitor.cpp +++ b/src/libs/modelinglib/qmt/stereotype/shapepaintvisitor.cpp @@ -27,6 +27,8 @@ #include "shapes.h" +#include + namespace qmt { ShapePaintVisitor::ShapePaintVisitor(QPainter *painter, const QPointF &scaledOrigin, const QSizeF &originalSize, diff --git a/src/libs/qmleditorwidgets/easingpane/easingcontextpane.cpp b/src/libs/qmleditorwidgets/easingpane/easingcontextpane.cpp index a794b337a08..d7812885578 100644 --- a/src/libs/qmleditorwidgets/easingpane/easingcontextpane.cpp +++ b/src/libs/qmleditorwidgets/easingpane/easingcontextpane.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include diff --git a/src/libs/qmleditorwidgets/easingpane/easinggraph.cpp b/src/libs/qmleditorwidgets/easingpane/easinggraph.cpp index 4163569c04b..e8360e0db65 100644 --- a/src/libs/qmleditorwidgets/easingpane/easinggraph.cpp +++ b/src/libs/qmleditorwidgets/easingpane/easinggraph.cpp @@ -26,6 +26,7 @@ #include "easinggraph.h" #include +#include #include #include diff --git a/src/libs/qmljs/qmljsstaticanalysismessage.cpp b/src/libs/qmljs/qmljsstaticanalysismessage.cpp index f991b85c3c1..4bbd00bbf5d 100644 --- a/src/libs/qmljs/qmljsstaticanalysismessage.cpp +++ b/src/libs/qmljs/qmljsstaticanalysismessage.cpp @@ -244,7 +244,7 @@ StaticAnalysisMessages::StaticAnalysisMessages() newMsg(WarnDuplicateImport, Warning, tr("Duplicate import (%1)."), 1); newMsg(ErrHitMaximumRecursion, Error, - tr("Hit Maximum recursion limit when visiting AST")); + tr("Hit maximum recursion limit when visiting AST.")); } } // anonymous namespace diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index 3e3710dcc75..e13eafd4cbf 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -222,9 +222,11 @@ bool AndroidBuildApkStep::init() m_inputFile = node->data(Constants::AndroidDeploySettingsFile).toString(); if (m_inputFile.isEmpty()) { + qCDebug(buildapkstepLog) << "no input file" << rc << node << buildKey; m_skipBuilding = true; return true; } + m_skipBuilding = false; if (m_buildTargetSdk.isEmpty()) { emit addOutput(tr("Android build SDK not defined. Check Android settings."), diff --git a/src/plugins/android/androidbuildapkwidget.cpp b/src/plugins/android/androidbuildapkwidget.cpp index 4eb1856bb97..984c3049dbd 100644 --- a/src/plugins/android/androidbuildapkwidget.cpp +++ b/src/plugins/android/androidbuildapkwidget.cpp @@ -35,6 +35,7 @@ #include "createandroidmanifestwizard.h" #include +#include #include #include #include @@ -273,8 +274,11 @@ QWidget *AndroidBuildApkWidget::createAdditionalLibrariesGroup() group->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); auto libsModel = new AndroidExtraLibraryListModel(m_step->target(), this); - connect(libsModel, &AndroidExtraLibraryListModel::enabledChanged, - group, &QWidget::setEnabled); + connect(libsModel, &AndroidExtraLibraryListModel::enabledChanged, this, + [this, group](const bool enabled) { + group->setEnabled(enabled); + m_openSslCheckBox->setChecked(isOpenSslLibsIncluded()); + }); auto libsView = new QListView; libsView->setSelectionMode(QAbstractItemView::ExtendedSelection); @@ -308,9 +312,16 @@ QWidget *AndroidBuildApkWidget::createAdditionalLibrariesGroup() libsButtonLayout->addWidget(removeLibButton); libsButtonLayout->addStretch(1); - auto hbox = new QHBoxLayout(group); - hbox->addWidget(libsView); - hbox->addLayout(libsButtonLayout); + m_openSslCheckBox = new QCheckBox(tr("Include prebuilt OpenSSL libraries")); + m_openSslCheckBox->setToolTip(tr("This is useful for apps that use SSL operations. The path " + "can be defined in Tools > Options > Devices > Android.")); + connect(m_openSslCheckBox, &QAbstractButton::clicked, this, + &AndroidBuildApkWidget::onOpenSslCheckBoxChanged); + + auto grid = new QGridLayout(group); + grid->addWidget(m_openSslCheckBox, 0, 0); + grid->addWidget(libsView, 1, 0); + grid->addLayout(libsButtonLayout, 1, 1); QItemSelectionModel *libSelection = libsView->selectionModel(); connect(libSelection, &QItemSelectionModel::selectionChanged, this, [libSelection, removeLibButton] { @@ -337,6 +348,53 @@ void AndroidBuildApkWidget::signPackageCheckBoxToggled(bool checked) setCertificates(); } +void AndroidBuildApkWidget::onOpenSslCheckBoxChanged() +{ + Utils::FilePath projectPath = m_step->buildConfiguration()->buildSystem()->projectFilePath(); + QFile projectFile(projectPath.toString()); + if (!projectFile.open(QIODevice::ReadWrite | QIODevice::Text)) { + qWarning() << "Cound't open project file to add OpenSSL extra libs: " << projectPath; + return; + } + + const QString searchStr = openSslIncludeFileContent(projectPath); + QTextStream textStream(&projectFile); + + QString fileContent = textStream.readAll(); + if (!m_openSslCheckBox->isChecked()) { + fileContent.remove("\n" + searchStr); + } else if (!fileContent.contains(searchStr, Qt::CaseSensitive)) { + fileContent.append(searchStr + "\n"); + } + + projectFile.resize(0); + textStream << fileContent; + projectFile.close(); +} + +bool AndroidBuildApkWidget::isOpenSslLibsIncluded() +{ + Utils::FilePath projectPath = m_step->buildConfiguration()->buildSystem()->projectFilePath(); + const QString searchStr = openSslIncludeFileContent(projectPath); + QFile projectFile(projectPath.toString()); + projectFile.open(QIODevice::ReadOnly); + QTextStream textStream(&projectFile); + QString fileContent = textStream.readAll(); + projectFile.close(); + return fileContent.contains(searchStr, Qt::CaseSensitive); +} + +QString AndroidBuildApkWidget::openSslIncludeFileContent(const Utils::FilePath &projectPath) +{ + QString openSslPath = AndroidConfigurations::currentConfig().openSslLocation().toString(); + if (projectPath.endsWith(".pro")) + return "android: include(" + openSslPath + "/openssl.pri)"; + if (projectPath.endsWith("CMakeLists.txt")) + return "if (ANDROID)\n include(" + openSslPath + "/CMakeLists.txt)\nendif()"; + + return QString(); +} + void AndroidBuildApkWidget::setCertificates() { QAbstractItemModel *certificates = m_step->keystoreCertificates(); diff --git a/src/plugins/android/androidbuildapkwidget.h b/src/plugins/android/androidbuildapkwidget.h index c3751484a19..5f6875abe25 100644 --- a/src/plugins/android/androidbuildapkwidget.h +++ b/src/plugins/android/androidbuildapkwidget.h @@ -56,6 +56,9 @@ private: void setCertificates(); void updateSigningWarning(); void signPackageCheckBoxToggled(bool checked); + void onOpenSslCheckBoxChanged(); + bool isOpenSslLibsIncluded(); + QString openSslIncludeFileContent(const Utils::FilePath &projectPath); QWidget *createApplicationGroup(); QWidget *createSignPackageGroup(); @@ -69,6 +72,7 @@ private: Utils::InfoLabel *m_signingDebugWarningLabel = nullptr; QComboBox *m_certificatesAliasComboBox = nullptr; QCheckBox *m_addDebuggerCheckBox = nullptr; + QCheckBox *m_openSslCheckBox = nullptr; }; } // namespace Internal diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index 9daf1d0bf21..654daf99057 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -104,6 +104,7 @@ namespace { const QLatin1String SdkFullyConfiguredKey("AllEssentialsInstalled"); const QLatin1String SDKManagerToolArgsKey("SDKManagerToolArgs"); const QLatin1String OpenJDKLocationKey("OpenJDKLocation"); + const QLatin1String OpenSslPriLocationKey("OpenSSLPriLocation"); const QLatin1String KeystoreLocationKey("KeystoreLocation"); const QLatin1String AutomaticKitCreationKey("AutomatiKitCreation"); const QLatin1String PartitionSizeKey("PartitionSize"); @@ -239,6 +240,7 @@ void AndroidConfig::load(const QSettings &settings) m_customNdkList = settings.value(CustomNdkLocationsKey).toStringList(); m_sdkManagerToolArgs = settings.value(SDKManagerToolArgsKey).toStringList(); m_openJDKLocation = FilePath::fromString(settings.value(OpenJDKLocationKey).toString()); + m_openSslLocation = FilePath::fromString(settings.value(OpenSslPriLocationKey).toString()); m_keystoreLocation = FilePath::fromString(settings.value(KeystoreLocationKey).toString()); m_automaticKitCreation = settings.value(AutomaticKitCreationKey, true).toBool(); m_sdkFullyConfigured = settings.value(SdkFullyConfiguredKey, false).toBool(); @@ -251,6 +253,7 @@ void AndroidConfig::load(const QSettings &settings) m_customNdkList = reader.restoreValue(CustomNdkLocationsKey).toStringList(); m_sdkManagerToolArgs = reader.restoreValue(SDKManagerToolArgsKey, m_sdkManagerToolArgs).toStringList(); m_openJDKLocation = FilePath::fromString(reader.restoreValue(OpenJDKLocationKey, m_openJDKLocation.toString()).toString()); + m_openSslLocation = FilePath::fromString(reader.restoreValue(OpenSslPriLocationKey, m_openSslLocation.toString()).toString()); m_automaticKitCreation = reader.restoreValue(AutomaticKitCreationKey, m_automaticKitCreation).toBool(); m_sdkFullyConfigured = reader.restoreValue(SdkFullyConfiguredKey, m_sdkFullyConfigured).toBool(); // persistent settings @@ -271,6 +274,7 @@ void AndroidConfig::save(QSettings &settings) const settings.setValue(SDKManagerToolArgsKey, m_sdkManagerToolArgs); settings.setValue(OpenJDKLocationKey, m_openJDKLocation.toString()); settings.setValue(KeystoreLocationKey, m_keystoreLocation.toString()); + settings.setValue(OpenSslPriLocationKey, m_openSslLocation.toString()); settings.setValue(PartitionSizeKey, m_partitionSize); settings.setValue(AutomaticKitCreationKey, m_automaticKitCreation); settings.setValue(SdkFullyConfiguredKey, m_sdkFullyConfigured); @@ -374,6 +378,16 @@ void AndroidConfig::removeCustomNdk(const QString &customNdk) m_customNdkList.removeAll(customNdk); } +Utils::FilePath AndroidConfig::openSslLocation() const +{ + return m_openSslLocation; +} + +void AndroidConfig::setOpenSslLocation(const Utils::FilePath &openSslLocation) +{ + m_openSslLocation = openSslLocation; +} + QStringList AndroidConfig::apiLevelNamesFor(const SdkPlatformList &platforms) { return Utils::transform(platforms, AndroidConfig::apiLevelNameFor); diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index f793ed78c3f..cf324cdcfb5 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -196,6 +196,10 @@ public: void addCustomNdk(const QString &customNdk); void removeCustomNdk(const QString &customNdk); + Utils::FilePath openSslLocation() const; + void setOpenSslLocation(const Utils::FilePath &openSslLocation); + + private: static QString getDeviceProperty(const Utils::FilePath &adbToolPath, const QString &device, const QString &property); @@ -217,6 +221,7 @@ private: QStringList m_sdkManagerToolArgs; Utils::FilePath m_openJDKLocation; Utils::FilePath m_keystoreLocation; + Utils::FilePath m_openSslLocation; unsigned m_partitionSize = 1024; bool m_automaticKitCreation = true; QUrl m_sdkToolsUrl; diff --git a/src/plugins/android/androidsettingswidget.cpp b/src/plugins/android/androidsettingswidget.cpp index 42511b893c3..30875271c10 100644 --- a/src/plugins/android/androidsettingswidget.cpp +++ b/src/plugins/android/androidsettingswidget.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -112,6 +113,7 @@ private: void openSDKDownloadUrl(); void openNDKDownloadUrl(); void openOpenJDKDownloadUrl(); + void downloadOpenSslRepo(const bool silent = false); void addAVD(); void avdAdded(); void removeAVD(); @@ -134,6 +136,7 @@ private: Utils::FilePath getDefaultSdkPath(); void showEvent(QShowEvent *event) override; void addCustomNdkItem(); + void validateOpenSsl(); Ui_AndroidSettingsWidget *m_ui; AndroidSdkManagerWidget *m_sdkManagerWidget = nullptr; @@ -167,6 +170,12 @@ enum AndroidValidation { NdkinstallDirOkRow }; +enum OpenSslValidation { + OpenSslPathExistsRow, + OpenSslPriPathExists, + OpenSslCmakeListsPathExists +}; + class SummaryWidget : public QWidget { class RowData { @@ -344,6 +353,7 @@ void AndroidSettingsWidget::showEvent(QShowEvent *event) // to let settings dialog open first. QTimer::singleShot(0, std::bind(&AndroidSdkManager::reloadPackages, m_sdkManager.get(), false)); + validateOpenSsl(); m_isInitialReloadDone = true; } } @@ -421,6 +431,18 @@ AndroidSettingsWidget::AndroidSettingsWidget() m_ui->androidDetailsWidget); m_ui->androidDetailsWidget->setWidget(androidSummary); + QMap openSslValidationPoints; + openSslValidationPoints[OpenSslPathExistsRow] = tr("OpenSSL path exists."); + openSslValidationPoints[OpenSslPriPathExists] = tr( + "QMake include project (openssl.pri) exists."); + openSslValidationPoints[OpenSslCmakeListsPathExists] = tr( + "CMake include project (CMakeLists.txt) exists."); + auto openSslSummary = new SummaryWidget(openSslValidationPoints, + tr("OpenSSL Settings are OK."), + tr("OpenSSL settings have errors."), + m_ui->openSslDetailsWidget); + m_ui->openSslDetailsWidget->setWidget(openSslSummary); + connect(m_ui->OpenJDKLocationPathChooser, &Utils::PathChooser::rawPathChanged, this, &AndroidSettingsWidget::validateJdk); Utils::FilePath currentJdkPath = m_androidConfig.openJDKLocation(); @@ -436,6 +458,12 @@ AndroidSettingsWidget::AndroidSettingsWidget() m_ui->SDKLocationPathChooser->setFileName(currentSDKPath); m_ui->SDKLocationPathChooser->setPromptDialogTitle(tr("Select Android SDK folder")); + m_ui->openSslPathChooser->setPromptDialogTitle(tr("Select OpenSSL Include Project File")); + Utils::FilePath currentOpenSslPath = m_androidConfig.openSslLocation(); + if (currentOpenSslPath.isEmpty()) + currentOpenSslPath = currentSDKPath.pathAppended("android_openssl"); + m_ui->openSslPathChooser->setFileName(currentOpenSslPath); + m_ui->DataPartitionSizeSpinBox->setValue(m_androidConfig.partitionSize()); m_ui->CreateKitCheckBox->setChecked(m_androidConfig.automaticKitCreation()); m_ui->AVDTableView->setModel(&m_AVDModel); @@ -448,6 +476,7 @@ AndroidSettingsWidget::AndroidSettingsWidget() m_ui->downloadSDKToolButton->setIcon(downloadIcon); m_ui->downloadNDKToolButton->setIcon(downloadIcon); m_ui->downloadOpenJDKToolButton->setIcon(downloadIcon); + m_ui->downloadOpenSSLPrebuiltLibs->setIcon(downloadIcon); m_ui->sdkToolsAutoDownloadButton->setIcon(Utils::Icons::RELOAD.icon()); connect(m_ui->SDKLocationPathChooser, &Utils::PathChooser::rawPathChanged, @@ -469,6 +498,10 @@ AndroidSettingsWidget::AndroidSettingsWidget() m_ui->ndkListComboBox->removeItem(m_ui->ndkListComboBox->currentIndex()); }); + connect(m_ui->ndkListComboBox, QOverload::of(&QComboBox::currentIndexChanged), + [this](const QString) { validateNdk(); }); + connect(m_ui->openSslPathChooser, &Utils::PathChooser::rawPathChanged, this, + &AndroidSettingsWidget::validateOpenSsl); connect(&m_virtualDevicesWatcher, &QFutureWatcherBase::finished, this, &AndroidSettingsWidget::updateAvds); connect(m_ui->AVDRefreshPushButton, &QAbstractButton::clicked, @@ -494,6 +527,8 @@ AndroidSettingsWidget::AndroidSettingsWidget() this, &AndroidSettingsWidget::openNDKDownloadUrl); connect(m_ui->downloadSDKToolButton, &QAbstractButton::clicked, this, &AndroidSettingsWidget::openSDKDownloadUrl); + connect(m_ui->downloadOpenSSLPrebuiltLibs, &QAbstractButton::clicked, + this, &AndroidSettingsWidget::downloadOpenSslRepo); connect(m_ui->downloadOpenJDKToolButton, &QAbstractButton::clicked, this, &AndroidSettingsWidget::openOpenJDKDownloadUrl); // Validate SDK again after any change in SDK packages. @@ -564,6 +599,22 @@ void AndroidSettingsWidget::validateJdk() updateUI(); } +void AndroidSettingsWidget::validateOpenSsl() +{ + auto openSslPath = Utils::FilePath::fromUserInput(m_ui->openSslPathChooser->rawPath()); + m_androidConfig.setOpenSslLocation(openSslPath); + + auto summaryWidget = static_cast(m_ui->openSslDetailsWidget->widget()); + summaryWidget->setPointValid(OpenSslPathExistsRow, m_androidConfig.openSslLocation().exists()); + + const bool priFileExists = m_androidConfig.openSslLocation().pathAppended("openssl.pri").exists(); + summaryWidget->setPointValid(OpenSslPriPathExists, priFileExists); + const bool cmakeListsExists + = m_androidConfig.openSslLocation().pathAppended("CMakeLists.txt").exists(); + summaryWidget->setPointValid(OpenSslCmakeListsPathExists, cmakeListsExists); + updateUI(); +} + Utils::FilePath AndroidSettingsWidget::findJdkInCommonPaths() { QString jdkFromEnvVar = QString::fromLocal8Bit(getenv("JAVA_HOME")); @@ -700,6 +751,67 @@ void AndroidSettingsWidget::openOpenJDKDownloadUrl() QDesktopServices::openUrl(QUrl::fromUserInput("http://www.oracle.com/technetwork/java/javase/downloads/")); } +void AndroidSettingsWidget::downloadOpenSslRepo(const bool silent) +{ + const Utils::FilePath openSslPath = m_ui->openSslPathChooser->fileName(); + const QString openSslCloneTitle(tr("OpenSSL Cloning")); + + auto openSslSummaryWidget = static_cast(m_ui->openSslDetailsWidget->widget()); + if (openSslSummaryWidget->allRowsOk()) { + if (silent) { + QMessageBox::information(this, openSslCloneTitle, + tr("OpenSSL prebuilt libraries repository is already configured.")); + } + return; + } + + const QString openSslRepo("https://github.com/KDAB/android_openssl.git"); + Utils::QtcProcess *gitCloner = new Utils::QtcProcess(this); + gitCloner->setCommand(Utils::CommandLine("git", {"clone", openSslRepo, openSslPath.fileName()})); + gitCloner->setWorkingDirectory(openSslPath.parentDir().toString()); + + QDir openSslDir(openSslPath.toString()); + if (openSslDir.exists()) { + auto userInput = QMessageBox::information(this, openSslCloneTitle, + tr("The selected download path (%1) for OpenSSL already exists, " + "do you want to remove and overwrite its content?") + .arg(QDir::toNativeSeparators(openSslPath.toString())), + QMessageBox::Yes | QMessageBox::No); + if (userInput == QMessageBox::Yes) + openSslDir.removeRecursively(); + else + return; + } + + QProgressDialog *openSslProgressDialog + = new QProgressDialog(tr("Cloning OpenSSL prebuilt libraries, please be patient..."), + tr("Cancel"), 0, 0); + openSslProgressDialog->setWindowModality(Qt::WindowModal); + openSslProgressDialog->setWindowTitle(openSslCloneTitle); + openSslProgressDialog->setFixedSize(openSslProgressDialog->sizeHint()); + + connect(openSslProgressDialog, &QProgressDialog::canceled, this, [gitCloner]() { + gitCloner->kill(); + }); + + gitCloner->start(); + openSslProgressDialog->show(); + + connect(gitCloner, QOverload::of(&Utils::QtcProcess::finished), + [=](int exitCode, QProcess::ExitStatus exitStatus) { + openSslProgressDialog->close(); + validateOpenSsl(); + + if (!openSslProgressDialog->wasCanceled() || + (exitStatus == Utils::QtcProcess::NormalExit && exitCode != 0)) { + QMessageBox::information(this, openSslCloneTitle, + tr("OpenSSL prebuilt libraries cloning failed. " + "Opening OpenSSL URL for manual download...")); + QDesktopServices::openUrl(QUrl::fromUserInput(openSslRepo)); + } + }); +} + void AndroidSettingsWidget::addAVD() { disableAvdControls(); @@ -767,9 +879,11 @@ void AndroidSettingsWidget::updateUI() { auto javaSummaryWidget = static_cast(m_ui->javaDetailsWidget->widget()); auto androidSummaryWidget = static_cast(m_ui->androidDetailsWidget->widget()); - bool javaSetupOk = javaSummaryWidget->allRowsOk(); - bool sdkToolsOk = androidSummaryWidget->rowsOk({SdkPathExistsRow, SdkPathWritableRow, SdkToolsInstalledRow}); - bool androidSetupOk = androidSummaryWidget->allRowsOk(); + auto openSslSummaryWidget = static_cast(m_ui->openSslDetailsWidget->widget()); + const bool javaSetupOk = javaSummaryWidget->allRowsOk(); + const bool sdkToolsOk = androidSummaryWidget->rowsOk({SdkPathExistsRow, SdkPathWritableRow, SdkToolsInstalledRow}); + const bool androidSetupOk = androidSummaryWidget->allRowsOk(); + const bool openSslOk = openSslSummaryWidget->allRowsOk(); m_ui->avdManagerTab->setEnabled(javaSetupOk && androidSetupOk); m_ui->sdkManagerTab->setEnabled(sdkToolsOk); @@ -785,6 +899,8 @@ void AndroidSettingsWidget::updateUI() Utils::DetailsWidget::Expanded); m_ui->androidDetailsWidget->setState(androidSetupOk ? Utils::DetailsWidget::Collapsed : Utils::DetailsWidget::Expanded); + m_ui->openSslDetailsWidget->setState(openSslOk ? Utils::DetailsWidget::Collapsed : + Utils::DetailsWidget::Expanded); } void AndroidSettingsWidget::manageAVD() @@ -820,6 +936,14 @@ void AndroidSettingsWidget::downloadSdk() m_sdkManager->reloadPackages(true); updateUI(); apply(); + + QMetaObject::Connection *const openSslOneShot = new QMetaObject::Connection; + *openSslOneShot = connect(m_sdkManager.get(), &AndroidSdkManager::packageReloadFinished, + this, [this, openSslOneShot]() { + QObject::disconnect(*openSslOneShot); + downloadOpenSslRepo(true); + delete openSslOneShot; + }); }); auto showErrorDialog = [this](const QString &error) { diff --git a/src/plugins/android/androidsettingswidget.ui b/src/plugins/android/androidsettingswidget.ui index 6d8272b7dfa..2a25b93386c 100644 --- a/src/plugins/android/androidsettingswidget.ui +++ b/src/plugins/android/androidsettingswidget.ui @@ -204,6 +204,48 @@ + + + + Android OpenSSL settings + + + + + + + 0 + 0 + + + + OpenSSL .pri location: + + + + + + + Select the path of the prebuilt OpenSSL binaries. + + + + + + + + + + Automatically download OpenSSL prebuilt libraries. If the automatic download fails, a URL will be opened in the browser for manual download. + + + + + + + + + diff --git a/src/plugins/autotest/testrunconfiguration.h b/src/plugins/autotest/testrunconfiguration.h index df43b9dc86f..a087fa461f4 100644 --- a/src/plugins/autotest/testrunconfiguration.h +++ b/src/plugins/autotest/testrunconfiguration.h @@ -57,10 +57,9 @@ public: if (auto debuggable = dynamic_cast(config)) enableQuick = debuggable->mixedDebugging(); - if (auto debugAspect = aspect()) { - debugAspect->setUseQmlDebugger(enableQuick); - ProjectExplorer::ProjectExplorerPlugin::updateRunActions(); - } + auto debugAspect = addAspect(parent); + debugAspect->setUseQmlDebugger(enableQuick); + ProjectExplorer::ProjectExplorerPlugin::updateRunActions(); m_testConfig = config; } diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index fa529a902b0..ec3c1e2f490 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -555,12 +555,6 @@ void TestRunner::debugTests() QString errorMessage; auto runControl = new RunControl(ProjectExplorer::Constants::DEBUG_RUN_MODE); runControl->setRunConfiguration(config->runConfiguration()); - if (!runControl) { - reportResult(ResultType::MessageFatal, - tr("Failed to create run configuration.\n%1").arg(errorMessage)); - onFinished(); - return; - } QStringList omitted; Runnable inferior = config->runnable(); diff --git a/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp b/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp index c37090c1658..785582f137a 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp @@ -54,16 +54,9 @@ static QString buildToolsetNumber(int number) return QStringLiteral("0x%1").arg(QString::number(number, 16)); } -static QString buildVendor(const QString &vendor) -{ - // Remove the colon symbol. - const int colonIndex = vendor.lastIndexOf(':'); - return vendor.mid(0, colonIndex); -} - static QString buildPackageId(const DeviceSelection::Package &package) { - return QStringLiteral("%1.%2.%3").arg(package.vendor, package.name, package.version); + return QStringLiteral("%1.%2.%3").arg(package.vendorName, package.name, package.version); } static QString buildCpu(const DeviceSelection &device) @@ -139,8 +132,7 @@ Project::Project(const UvscServerProvider *provider, DebuggerRunTool *runTool) const auto targetCommonOption = targetOption->appendPropertyGroup("TargetCommonOption"); const DeviceSelection device = provider->deviceSelection(); targetCommonOption->appendProperty("Device", device.name); - const QString vendor = buildVendor(device.vendor); - targetCommonOption->appendProperty("Vendor", vendor); + targetCommonOption->appendProperty("Vendor", device.vendorName); const QString packageId = buildPackageId(device.package); targetCommonOption->appendProperty("PackID", packageId); targetCommonOption->appendProperty("PackURL", device.package.url); diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp index e39d2789336..e9a33428576 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp @@ -25,6 +25,8 @@ #include "uvtargetdevicemodel.h" +#include + #include #include #include @@ -81,14 +83,19 @@ static QStringList findKeilPackFiles(const QString &path) return files; } +static void fillElementProperty(QXmlStreamReader &in, QString &prop) +{ + prop = in.readElementText().trimmed(); +} + static void fillCpu(QXmlStreamReader &in, DeviceSelection::Cpu &cpu) { const QXmlStreamAttributes attrs = in.attributes(); in.skipCurrentElement(); - cpu.core = attrs.hasAttribute("Dcore") ? attrs.value("Dcore").toString() : cpu.core; - cpu.clock = attrs.hasAttribute("Dclock") ? attrs.value("Dclock").toString() : cpu.clock; - cpu.fpu = attrs.hasAttribute("Dfpu") ? attrs.value("Dfpu").toString() : cpu.fpu; - cpu.mpu = attrs.hasAttribute("Dmpu") ? attrs.value("Dmpu").toString() : cpu.mpu; + cpu.core = attrs.value("Dcore").toString(); + cpu.clock = attrs.value("Dclock").toString(); + cpu.fpu = attrs.value("Dfpu").toString(); + cpu.mpu = attrs.value("Dmpu").toString(); } static void fillMemories(QXmlStreamReader &in, DeviceSelection::Memories &memories) @@ -113,140 +120,67 @@ static void fillAlgorithms(QXmlStreamReader &in, DeviceSelection::Algorithms &al algorithms.push_back(algorithm); } +static void fillVendor(const QString &vendor, QString &vendorName, QString &vendorId) +{ + const auto colonIndex = vendor.lastIndexOf(':'); + vendorName = vendor.mid(0, colonIndex); + if (colonIndex != -1) + vendorId = vendor.mid(colonIndex + 1); +} + +static void fillVendor(QXmlStreamReader &in, QString &vendorName, QString &vendorId) +{ + QString vendor; + fillElementProperty(in, vendor); + fillVendor(vendor, vendorName, vendorId); +} + +static void fillSvd(QXmlStreamReader &in, QString &svd) +{ + const QXmlStreamAttributes attrs = in.attributes(); + in.skipCurrentElement(); + svd = attrs.value("svd").toString(); +} + // DeviceSelectionItem -class DeviceSelectionItem : public TreeItem +class DeviceSelectionItem final : public TreeItem { public: - enum class Type { Unknown, Package, Family, SubFamily, Device, DeviceVariant }; - enum Column { NameColumn, VersionColumn, VendorColumn }; - explicit DeviceSelectionItem(Type type = Type::Unknown) - : m_type(type) - {} - - QVariant data(int column, int role) const override - { - if (role == Qt::DisplayRole && column == NameColumn) - return m_name; - return {}; - } - - Qt::ItemFlags flags(int column) const override - { - Q_UNUSED(column) - return Qt::ItemIsEnabled; - } - - DeviceSelectionItem *parentPackItem() const - { - return static_cast(parent()); - } - - QString m_name; - const Type m_type; -}; - -// PackageItem - -class PackageItem final : public DeviceSelectionItem -{ -public: - explicit PackageItem(const QString &file) - : DeviceSelectionItem(Type::Package), m_file(file), m_version(extractPackVersion(file)) + enum Column { NameColumn, VersionColumn, VendorNameColumn }; + explicit DeviceSelectionItem() {} QVariant data(int column, int role) const final { if (role == Qt::DisplayRole) { if (column == NameColumn) - return m_name; + return name; else if (column == VersionColumn) - return m_version; - else if (column == VendorColumn) - return m_vendor; + return version; + else if (column == VendorNameColumn) + return vendorName; } return {}; } - QString m_file; - QString m_version; - QString m_desc; - QString m_vendor; - QString m_url; -}; - -// FamilyItem - -class FamilyItem final : public DeviceSelectionItem -{ -public: - explicit FamilyItem() - : DeviceSelectionItem(Type::Family) - {} - - QVariant data(int column, int role) const final - { - if (role == Qt::DisplayRole) { - if (column == NameColumn) { - return m_name; - } else if (column == VendorColumn) { - const auto colonIndex = m_vendor.lastIndexOf(':'); - return m_vendor.mid(0, colonIndex); - } - } - return {}; - } - - QString m_desc; - QString m_vendor; -}; - -// SubFamilyItem - -class SubFamilyItem final : public DeviceSelectionItem -{ -public: - explicit SubFamilyItem() - : DeviceSelectionItem(Type::SubFamily) - {} - - QString m_svd; -}; - -// DeviceItem - -class DeviceItem final : public DeviceSelectionItem -{ -public: - explicit DeviceItem() - : DeviceSelectionItem(Type::Device) - {} - Qt::ItemFlags flags(int column) const final { Q_UNUSED(column) return hasChildren() ? Qt::ItemIsEnabled : (Qt::ItemIsEnabled | Qt::ItemIsSelectable); } - DeviceSelection::Cpu m_cpu; - DeviceSelection::Memories m_memories; - DeviceSelection::Algorithms m_algorithms; -}; - -// DeviceVariantItem - -class DeviceVariantItem final : public DeviceSelectionItem -{ -public: - explicit DeviceVariantItem() - : DeviceSelectionItem(Type::DeviceVariant) - {} - - Qt::ItemFlags flags(int column) const final - { - Q_UNUSED(column) - return Qt::ItemIsEnabled | Qt::ItemIsSelectable; - } + QString desc; + QString fullPath; + QString name; + QString svd; + QString url; + QString vendorId; + QString vendorName; + QString version; + DeviceSelection::Algorithms algorithms; + DeviceSelection::Cpu cpu; + DeviceSelection::Memories memories; }; // DeviceSelectionModel @@ -298,20 +232,23 @@ void DeviceSelectionModel::parsePackage(const QString &packageFile) } } -void DeviceSelectionModel::parsePackage(QXmlStreamReader &in, const QString &file) +void DeviceSelectionModel::parsePackage(QXmlStreamReader &in, const QString &packageFile) { - const auto child = new PackageItem(file); + // Create and fill the 'package' item. + const auto child = new DeviceSelectionItem; rootItem()->appendChild(child); + child->fullPath = packageFile; + child->version = extractPackVersion(packageFile); while (in.readNextStartElement()) { const QStringRef elementName = in.name(); if (elementName == "name") { - child->m_name = in.readElementText().trimmed(); + fillElementProperty(in, child->name); } else if (elementName == "description") { - child->m_desc = in.readElementText().trimmed(); + fillElementProperty(in, child->desc); } else if (elementName == "vendor") { - child->m_vendor = in.readElementText().trimmed(); + fillVendor(in, child->vendorName, child->vendorId); } else if (elementName == "url") { - child->m_url = in.readElementText().trimmed(); + fillElementProperty(in, child->url); } else if (elementName == "devices") { while (in.readNextStartElement()) { const QStringRef elementName = in.name(); @@ -328,90 +265,93 @@ void DeviceSelectionModel::parsePackage(QXmlStreamReader &in, const QString &fil void DeviceSelectionModel::parseFamily(QXmlStreamReader &in, DeviceSelectionItem *parent) { - const auto child = new FamilyItem; + // Create and fill the 'family' item. + const auto child = new DeviceSelectionItem; parent->appendChild(child); const QXmlStreamAttributes attrs = in.attributes(); - child->m_name = attrs.value("Dfamily").toString(); - child->m_vendor = attrs.value("Dvendor").toString(); - DeviceSelection::Cpu cpu; - DeviceSelection::Memories memories; + child->name = attrs.value("Dfamily").toString(); + fillVendor(attrs.value("Dvendor").toString(), child->vendorName, child->vendorId); while (in.readNextStartElement()) { const QStringRef elementName = in.name(); if (elementName == "processor") { - fillCpu(in, cpu); + fillCpu(in, child->cpu); } else if (elementName == "memory") { - fillMemories(in, memories); + fillMemories(in, child->memories); } else if (elementName == "description") { - child->m_desc = in.readElementText().trimmed(); + fillElementProperty(in, child->desc); } else if (elementName == "subFamily") { - parseSubFamily(in, child, cpu); + parseSubFamily(in, child); } else if (elementName == "device") { - parseDevice(in, child, cpu, memories); + parseDevice(in, child); } else { in.skipCurrentElement(); } } } -void DeviceSelectionModel::parseSubFamily(QXmlStreamReader &in, DeviceSelectionItem *parent, - DeviceSelection::Cpu &cpu) +void DeviceSelectionModel::parseSubFamily(QXmlStreamReader &in, DeviceSelectionItem *parent) { - const auto child = new SubFamilyItem; + // Create and fill the 'sub-family' item. + const auto child = new DeviceSelectionItem; parent->appendChild(child); const QXmlStreamAttributes attrs = in.attributes(); - child->m_name = attrs.value("DsubFamily").toString(); + child->name = attrs.value("DsubFamily").toString(); while (in.readNextStartElement()) { const QStringRef elementName = in.name(); if (elementName == "processor") { - fillCpu(in, cpu); + fillCpu(in, child->cpu); } else if (elementName == "debug") { - const QXmlStreamAttributes attrs = in.attributes(); - in.skipCurrentElement(); - child->m_svd = attrs.value("svd").toString(); + fillSvd(in, child->svd); } else if (elementName == "device") { - DeviceSelection::Memories memories; - parseDevice(in, child, cpu, memories); + parseDevice(in, child); } else { in.skipCurrentElement(); } } } -void DeviceSelectionModel::parseDevice(QXmlStreamReader &in, DeviceSelectionItem *parent, - DeviceSelection::Cpu &cpu, - DeviceSelection::Memories &memories) +void DeviceSelectionModel::parseDevice(QXmlStreamReader &in, DeviceSelectionItem *parent) { - const auto child = new DeviceItem; + // Create and fill the 'device' item. + const auto child = new DeviceSelectionItem; parent->appendChild(child); const QXmlStreamAttributes attrs = in.attributes(); - child->m_name = attrs.value("Dname").toString(); - DeviceSelection::Algorithms algorithms; + child->name = attrs.value("Dname").toString(); while (in.readNextStartElement()) { const QStringRef elementName = in.name(); if (elementName == "processor") { - fillCpu(in, cpu); + fillCpu(in, child->cpu); } else if (elementName == "memory") { - fillMemories(in, memories); + fillMemories(in, child->memories); } else if (elementName == "algorithm") { - fillAlgorithms(in, algorithms); + fillAlgorithms(in, child->algorithms); } else if (elementName == "variant") { parseDeviceVariant(in, child); } else { in.skipCurrentElement(); } } - child->m_cpu = cpu; - child->m_memories = memories; - child->m_algorithms = algorithms; } void DeviceSelectionModel::parseDeviceVariant(QXmlStreamReader &in, DeviceSelectionItem *parent) { - const auto child = new DeviceVariantItem; + // Create and fill the 'device-variant' item. + const auto child = new DeviceSelectionItem; parent->appendChild(child); const QXmlStreamAttributes attrs = in.attributes(); - in.skipCurrentElement(); - child->m_name = attrs.value("Dvariant").toString(); + child->name = attrs.value("Dvariant").toString(); + while (in.readNextStartElement()) { + const QStringRef elementName = in.name(); + if (elementName == "processor") { + fillCpu(in, child->cpu); + } else if (elementName == "memory") { + fillMemories(in, child->memories); + } else if (elementName == "algorithm") { + fillAlgorithms(in, child->algorithms); + } else { + in.skipCurrentElement(); + } + } } // DeviceSelectionView @@ -433,70 +373,86 @@ void DeviceSelectionView::currentChanged(const QModelIndex ¤t, const QMode if (!selectionModel) return; const DeviceSelectionItem *item = selectionModel->itemForIndex(current); - if (isValidItem(item)) { - const auto selection = buildSelection(item); - if (!selection.name.isEmpty()) - emit deviceSelected(selection); - } -} + if (!item || item->hasChildren()) + return; // We need only in a last 'device' or 'device-variant' item! -bool DeviceSelectionView::isValidItem(const DeviceSelectionItem *item) const -{ - if (!item) - return false; - if (item->m_type == DeviceSelectionItem::Type::DeviceVariant) - return true; - if (item->m_type == DeviceSelectionItem::Type::Device && !item->hasChildren()) - return true; - return false; + const auto selection = buildSelection(item); + if (!selection.name.isEmpty()) + emit deviceSelected(selection); } DeviceSelection DeviceSelectionView::buildSelection(const DeviceSelectionItem *item) const { DeviceSelection selection; - // We need to iterate from the lower 'Device|DeviceVariant' items to - // the upper 'Package' item to fill whole information. + // We need to iterate from the lower 'device' or 'device-variant' item to + // the upper 'package' item to fill a whole information. + DeviceSelection::Algorithms &algs = selection.algorithms; + DeviceSelection::Cpu &cpu = selection.cpu; + DeviceSelection::Memories &mems = selection.memories; + DeviceSelection::Package &pkg = selection.package; + do { - switch (item->m_type) { - case DeviceSelectionItem::Type::DeviceVariant: - selection.name = item->m_name; - break; - case DeviceSelectionItem::Type::Device: { - const auto deviceItem = static_cast(item); - if (!deviceItem->hasChildren()) - selection.name = item->m_name; - selection.cpu = deviceItem->m_cpu; - selection.memories = deviceItem->m_memories; - selection.algorithms = deviceItem->m_algorithms; + if (selection.name.isEmpty()) + selection.name = item->name; + else if (selection.subfamily.isEmpty()) + selection.subfamily = item->name; + else if (selection.family.isEmpty()) + selection.family = item->name; + else if (pkg.name.isEmpty()) + pkg.name = item->name; + + if (selection.desc.isEmpty()) + selection.desc = item->desc; + else if (pkg.desc.isEmpty()) + pkg.desc = item->desc; + + if (selection.vendorId.isEmpty()) + selection.vendorId = item->vendorId; + else if (pkg.vendorId.isEmpty()) + pkg.vendorId = item->vendorId; + + if (selection.vendorName.isEmpty()) + selection.vendorName = item->vendorName; + else if (pkg.vendorName.isEmpty()) + pkg.vendorName = item->vendorName; + + if (selection.svd.isEmpty()) + selection.svd = item->svd; + + if (cpu.clock.isEmpty()) + cpu.clock = item->cpu.clock; + if (cpu.core.isEmpty()) + cpu.core = item->cpu.core; + if (cpu.fpu.isEmpty()) + cpu.fpu = item->cpu.fpu; + if (cpu.mpu.isEmpty()) + cpu.mpu = item->cpu.mpu; + + if (pkg.file.isEmpty()) + pkg.file = item->fullPath; + if (pkg.url.isEmpty()) + pkg.url = item->url; + if (pkg.version.isEmpty()) + pkg.version = item->version; + + // Add only new flash algorithms. + for (const DeviceSelection::Algorithm &newAlg : item->algorithms) { + const bool contains = Utils::contains(algs, [&newAlg](const DeviceSelection::Algorithm &existAlg) { + return newAlg.path == existAlg.path; + }); + if (!contains) + algs.push_back(newAlg); } - break; - case DeviceSelectionItem::Type::SubFamily: { - const auto subFamilyItem = static_cast(item); - selection.subfamily = subFamilyItem->m_name; - selection.svd = subFamilyItem->m_svd; + + // Add only new memory regions. + for (const DeviceSelection::Memory &newMem : item->memories) { + const bool contains = Utils::contains(mems, [&newMem](const DeviceSelection::Memory &existMem) { + return newMem.id == existMem.id; + }); + if (!contains) + mems.push_back(newMem); } - break; - case DeviceSelectionItem::Type::Family: { - const auto familyItem = static_cast(item); - selection.family = familyItem->m_name; - selection.desc = familyItem->m_desc; - selection.vendor = familyItem->m_vendor; - } - break; - case DeviceSelectionItem::Type::Package: { - const auto packageItem = static_cast(item); - selection.package.desc = packageItem->m_desc; - selection.package.file = packageItem->m_file; - selection.package.name = packageItem->m_name; - selection.package.url = packageItem->m_url; - selection.package.vendor = packageItem->m_vendor; - selection.package.version = packageItem->m_version; - } - break; - default: - break; - } - } while ((item = item->parentPackItem())); + } while ((item->level() > 1) && (item = static_cast(item->parent()))); // Fix relative SVD file path to make it as absolute. const QFileInfo fi(selection.svd); diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h index c3a510f36e9..fb877760c35 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h @@ -52,12 +52,10 @@ public: private: void parsePackage(const QString &packageFile); - void parsePackage(QXmlStreamReader &in, const QString &file); + void parsePackage(QXmlStreamReader &in, const QString &packageFile); void parseFamily(QXmlStreamReader &in, DeviceSelectionItem *parent); - void parseSubFamily(QXmlStreamReader &in, DeviceSelectionItem *parent, - DeviceSelection::Cpu &cpu); - void parseDevice(QXmlStreamReader &in, DeviceSelectionItem *parent, - DeviceSelection::Cpu &cpu, DeviceSelection::Memories &memories); + void parseSubFamily(QXmlStreamReader &in, DeviceSelectionItem *parent); + void parseDevice(QXmlStreamReader &in, DeviceSelectionItem *parent); void parseDeviceVariant(QXmlStreamReader &in, DeviceSelectionItem *parent); Utils::FilePath m_toolsIniFile; @@ -77,7 +75,6 @@ signals: private: void currentChanged(const QModelIndex ¤t, const QModelIndex &previous) final; - bool isValidItem(const DeviceSelectionItem *item) const; DeviceSelection buildSelection(const DeviceSelectionItem *item) const; }; diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.cpp index acf44329b0d..4b09a3d5df3 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.cpp @@ -41,14 +41,16 @@ constexpr char packageDescrKeyC[] = "BareMetal.UvscServerProvider.PackageDescrip constexpr char packageFileKeyC[] = "BareMetal.UvscServerProvider.PackageFile"; constexpr char packageNameKeyC[] = "BareMetal.UvscServerProvider.PackageName"; constexpr char packageUrlKeyC[] = "BareMetal.UvscServerProvider.PackageUrl"; -constexpr char packageVendorKeyC[] = "BareMetal.UvscServerProvider.PackageVendor"; +constexpr char packageVendorNameKeyC[] = "BareMetal.UvscServerProvider.PackageVendorName"; +constexpr char packageVendorIdKeyC[] = "BareMetal.UvscServerProvider.PackageVendorId"; constexpr char packageVersionKeyC[] = "BareMetal.UvscServerProvider.PackageVersion"; // Device data keys. constexpr char deviceNameKeyC[] = "BareMetal.UvscServerProvider.DeviceName"; constexpr char deviceDescrKeyC[] = "BareMetal.UvscServerProvider.DeviceDescription"; constexpr char deviceFamilyKeyC[] = "BareMetal.UvscServerProvider.DeviceFamily"; constexpr char deviceSubFamilyKeyC[] = "BareMetal.UvscServerProvider.DeviceSubFamily"; -constexpr char deviceVendorKeyC[] = "BareMetal.UvscServerProvider.DeviceVendor"; +constexpr char deviceVendorNameKeyC[] = "BareMetal.UvscServerProvider.DeviceVendorName"; +constexpr char deviceVendorIdKeyC[] = "BareMetal.UvscServerProvider.DeviceVendorId"; constexpr char deviceSvdKeyC[] = "BareMetal.UvscServerProvider.DeviceSVD"; // Device CPU data keys. constexpr char deviceClockKeyC[] = "BareMetal.UvscServerProvider.DeviceClock"; @@ -77,14 +79,16 @@ QVariantMap DeviceSelection::toMap() const map.insert(packageFileKeyC, package.file); map.insert(packageNameKeyC, package.name); map.insert(packageUrlKeyC, package.url); - map.insert(packageVendorKeyC, package.vendor); + map.insert(packageVendorNameKeyC, package.vendorName); + map.insert(packageVendorIdKeyC, package.vendorId); map.insert(packageVersionKeyC, package.version); // Device. map.insert(deviceNameKeyC, name); map.insert(deviceDescrKeyC, desc); map.insert(deviceFamilyKeyC, family); map.insert(deviceSubFamilyKeyC, subfamily); - map.insert(deviceVendorKeyC, vendor); + map.insert(deviceVendorNameKeyC, vendorName); + map.insert(deviceVendorIdKeyC, vendorId); map.insert(deviceSvdKeyC, svd); // Device CPU. map.insert(deviceClockKeyC, cpu.clock); @@ -122,14 +126,16 @@ void DeviceSelection::fromMap(const QVariantMap &map) package.file = map.value(packageFileKeyC).toString(); package.name = map.value(packageNameKeyC).toString(); package.url = map.value(packageUrlKeyC).toString(); - package.vendor = map.value(packageVendorKeyC).toString(); + package.vendorName = map.value(packageVendorNameKeyC).toString(); + package.vendorId = map.value(packageVendorIdKeyC).toString(); package.version = map.value(packageVersionKeyC).toString(); // Device. name = map.value(deviceNameKeyC).toString(); desc = map.value(deviceDescrKeyC).toString(); family = map.value(deviceFamilyKeyC).toString(); subfamily = map.value(deviceSubFamilyKeyC).toString(); - vendor = map.value(deviceVendorKeyC).toString(); + vendorName = map.value(deviceVendorNameKeyC).toString(); + vendorId = map.value(deviceVendorIdKeyC).toString(); svd = map.value(deviceSvdKeyC).toString(); // Device CPU. cpu.clock = map.value(deviceClockKeyC).toString(); @@ -163,7 +169,8 @@ bool DeviceSelection::Package::operator==(const Package &other) const { return desc == other.desc && file == other.file && name == other.name && url == other.url - && vendor == other.vendor && version == other.version; + && vendorName == other.vendorName && vendorId == other.vendorId + && version == other.version; } bool DeviceSelection::Cpu::operator==(const Cpu &other) const @@ -186,7 +193,8 @@ bool DeviceSelection::operator==(const DeviceSelection &other) const { return package == other.package && name == other.name && desc == other.desc && family == other.family && subfamily == other.subfamily - && vendor == other.vendor && svd == other.svd && cpu == other.cpu + && vendorName == other.vendorName && vendorId == other.vendorId + && svd == other.svd && cpu == other.cpu && memories == other.memories && algorithms == other.algorithms && algorithmIndex == other.algorithmIndex; } diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.h index 36c262d1666..fe9879cde5f 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceselection.h @@ -46,7 +46,8 @@ public: QString file; QString name; QString url; - QString vendor; + QString vendorId; + QString vendorName; QString version; bool operator==(const Package &other) const; @@ -84,7 +85,8 @@ public: QString desc; QString family; QString subfamily; - QString vendor; + QString vendorId; + QString vendorName; QString svd; Cpu cpu; Memories memories; diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp index 6f9866e8b9d..330fd5674a8 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp @@ -117,7 +117,7 @@ static QString trimVendor(const QString &vendor) void DeviceSelectorDetailsPanel::refresh() { - m_vendorEdit->setText(trimVendor(m_selection.vendor)); + m_vendorEdit->setText(trimVendor(m_selection.vendorName)); m_fimilyEdit->setText(m_selection.family); m_descEdit->setPlainText(m_selection.desc); m_memoryView->refresh(); diff --git a/src/plugins/clangtools/filterdialog.ui b/src/plugins/clangtools/filterdialog.ui index d1f4b773888..897b0e72d15 100644 --- a/src/plugins/clangtools/filterdialog.ui +++ b/src/plugins/clangtools/filterdialog.ui @@ -33,7 +33,7 @@ - Select All With Fixits + Select All with Fixits diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp index 75790bee87e..854483c315a 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp +++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp @@ -576,9 +576,9 @@ bool BuildDirManager::checkConfiguration() box->setText(tr("The project has been changed outside of %1.") .arg(Core::Constants::IDE_DISPLAY_NAME)); box->setInformativeText(table); - auto *defaultButton = box->addButton(tr("Discard external changes"), + auto *defaultButton = box->addButton(tr("Discard External Changes"), QMessageBox::RejectRole); - auto *applyButton = box->addButton(tr("Adapt %1 project to changes") + auto *applyButton = box->addButton(tr("Adapt %1 Project to Changes") .arg(Core::Constants::IDE_DISPLAY_NAME), QMessageBox::ApplyRole); box->setDefaultButton(defaultButton); diff --git a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp index 5fe5d41ded7..02536d61233 100644 --- a/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp +++ b/src/plugins/cmakeprojectmanager/cmakesettingspage.cpp @@ -463,7 +463,7 @@ CMakeToolItemConfigWidget::CMakeToolItemConfigWidget(CMakeToolItemModel *model) formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); formLayout->addRow(new QLabel(tr("Name:")), m_displayNameLineEdit); formLayout->addRow(new QLabel(tr("Path:")), m_binaryChooser); - formLayout->addRow(new QLabel(tr("Help File:")), m_qchFileChooser); + formLayout->addRow(new QLabel(tr("Help file:")), m_qchFileChooser); formLayout->addRow(m_autoRunCheckBox); formLayout->addRow(m_autoCreateBuildDirectoryCheckBox); diff --git a/src/plugins/cmakeprojectmanager/fileapiparser.cpp b/src/plugins/cmakeprojectmanager/fileapiparser.cpp index 8d49ad4114a..f1eb1e8aaac 100644 --- a/src/plugins/cmakeprojectmanager/fileapiparser.cpp +++ b/src/plugins/cmakeprojectmanager/fileapiparser.cpp @@ -57,7 +57,7 @@ static void reportFileApiSetupFailure() { Core::MessageManager::write(QCoreApplication::translate( "CMakeProjectManager::Internal", - "Failed to set up CMake file API support. Qt Creator can not extract project information.")); + "Failed to set up CMake file API support. Qt Creator cannot extract project information.")); } static std::pair cmakeVersion(const QJsonObject &obj) diff --git a/src/plugins/coreplugin/fancyactionbar.cpp b/src/plugins/coreplugin/fancyactionbar.cpp index 284b68fdae9..c4a1f822b1b 100644 --- a/src/plugins/coreplugin/fancyactionbar.cpp +++ b/src/plugins/coreplugin/fancyactionbar.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include diff --git a/src/plugins/coreplugin/manhattanstyle.cpp b/src/plugins/coreplugin/manhattanstyle.cpp index b55b885615d..d1617534d51 100644 --- a/src/plugins/coreplugin/manhattanstyle.cpp +++ b/src/plugins/coreplugin/manhattanstyle.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include diff --git a/src/plugins/cppcheck/cppcheckmanualrundialog.cpp b/src/plugins/cppcheck/cppcheckmanualrundialog.cpp index e38c8a081e5..47a3feb195b 100644 --- a/src/plugins/cppcheck/cppcheckmanualrundialog.cpp +++ b/src/plugins/cppcheck/cppcheckmanualrundialog.cpp @@ -47,7 +47,7 @@ ManualRunDialog::ManualRunDialog(const CppcheckOptions &options, { QTC_ASSERT(project, return ); - setWindowTitle(tr("Cppcheck run configuration")); + setWindowTitle(tr("Cppcheck Run Configuration")); auto view = new QTreeView; view->setHeaderHidden(true); diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 377abba60f7..369dc06708f 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -629,7 +629,7 @@ public: QAction *showDateButton = addToggleButton("--date=iso", tr("Show Date"), - tr("Show date instead of sequence")); + tr("Show date instead of sequence.")); mapSetting(showDateButton, settings.boolPointer(GitSettings::refLogShowDateKey)); addReloadButton(); diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp index cfd5def8f5a..24acb258616 100644 --- a/src/plugins/git/giteditor.cpp +++ b/src/plugins/git/giteditor.cpp @@ -92,7 +92,7 @@ public: addSeparator(); addWidget(pickaxeLineEdit); addSeparator(); - caseAction = new QAction(tr("Case sensitive"), this); + caseAction = new QAction(tr("Case Sensitive"), this); caseAction->setCheckable(true); caseAction->setChecked(true); connect(caseAction, &QAction::toggled, editor, &GitEditorWidget::refresh); diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index d3d93267b36..dfaeb44f453 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -1533,7 +1533,7 @@ void GitPluginPrivate::cleanRepository(const QString &directory) QApplication::restoreOverrideCursor(); if (!gotFiles) { - Core::AsynchronousMessageBox::warning(tr("Unable to retrieve file list"), errorMessage); + Core::AsynchronousMessageBox::warning(tr("Unable to Retrieve File List"), errorMessage); return; } if (files.isEmpty() && ignoredFiles.isEmpty()) { diff --git a/src/plugins/help/docsettingspage.cpp b/src/plugins/help/docsettingspage.cpp index cbb161d235d..dca464a462d 100644 --- a/src/plugins/help/docsettingspage.cpp +++ b/src/plugins/help/docsettingspage.cpp @@ -254,7 +254,7 @@ void DocSettingsPageWidget::addDocumentation() } if (!formatedFail.isEmpty()) { - QMessageBox::information(m_ui.addButton->parentWidget(), tr("Registration failed"), + QMessageBox::information(m_ui.addButton->parentWidget(), tr("Registration Failed"), tr("Unable to register documentation.") + formatedFail, QMessageBox::Ok); } } diff --git a/src/plugins/help/qlitehtml/container_qpainter.cpp b/src/plugins/help/qlitehtml/container_qpainter.cpp index 559fc0feded..bf98f3f08f9 100644 --- a/src/plugins/help/qlitehtml/container_qpainter.cpp +++ b/src/plugins/help/qlitehtml/container_qpainter.cpp @@ -998,8 +998,9 @@ QVector DocumentContainer::mouseMoveEvent(const QPoint &documentPos, viewportPos, m_selection.mode); if (element.element) { + redrawRects.append( + m_selection.boundingRect() /*.adjusted(-1, -1, +1, +1)*/); // redraw old selection area m_selection.endElem = element; - redrawRects.append(m_selection.boundingRect()); // redraw old selection area m_selection.update(); redrawRects.append(m_selection.boundingRect()); } diff --git a/src/plugins/help/qlitehtml/qlitehtmlwidget.cpp b/src/plugins/help/qlitehtml/qlitehtmlwidget.cpp index db8c16d5ac2..8f455413bc8 100644 --- a/src/plugins/help/qlitehtml/qlitehtmlwidget.cpp +++ b/src/plugins/help/qlitehtml/qlitehtmlwidget.cpp @@ -664,21 +664,11 @@ QPoint QLiteHtmlWidget::toVirtual(const QPoint &p) const return {int(p.x() / d->zoomFactor), int(p.y() / d->zoomFactor)}; } -QPoint QLiteHtmlWidget::fromVirtual(const QPoint &p) const -{ - return {int(p.x() * d->zoomFactor), int(p.y() * d->zoomFactor)}; -} - QSize QLiteHtmlWidget::toVirtual(const QSize &s) const { return {int(s.width() / d->zoomFactor), int(s.height() / d->zoomFactor)}; } -QSize QLiteHtmlWidget::fromVirtual(const QSize &s) const -{ - return {int(s.width() * d->zoomFactor + 0.5), int(s.height() * d->zoomFactor + 0.5)}; -} - QRect QLiteHtmlWidget::toVirtual(const QRect &r) const { return {toVirtual(r.topLeft()), toVirtual(r.size())}; @@ -686,5 +676,9 @@ QRect QLiteHtmlWidget::toVirtual(const QRect &r) const QRect QLiteHtmlWidget::fromVirtual(const QRect &r) const { - return {fromVirtual(r.topLeft()), fromVirtual(r.size())}; + const QPoint tl{int(r.x() * d->zoomFactor), int(r.y() * d->zoomFactor)}; + // round size up, and add one since the topleft point was rounded down + const QSize s{int(r.width() * d->zoomFactor + 0.5) + 1, + int(r.height() * d->zoomFactor + 0.5) + 1}; + return {tl, s}; } diff --git a/src/plugins/help/qlitehtml/qlitehtmlwidget.h b/src/plugins/help/qlitehtml/qlitehtmlwidget.h index a79e5824b0c..1eed9b1f095 100644 --- a/src/plugins/help/qlitehtml/qlitehtmlwidget.h +++ b/src/plugins/help/qlitehtml/qlitehtmlwidget.h @@ -82,9 +82,7 @@ private: QPoint scrollPosition() const; void htmlPos(const QPoint &pos, QPoint *viewportPos, QPoint *htmlPos) const; QPoint toVirtual(const QPoint &p) const; - QPoint fromVirtual(const QPoint &p) const; QSize toVirtual(const QSize &s) const; - QSize fromVirtual(const QSize &s) const; QRect toVirtual(const QRect &r) const; QRect fromVirtual(const QRect &r) const; diff --git a/src/plugins/nim/project/nimbletaskstep.cpp b/src/plugins/nim/project/nimbletaskstep.cpp index fd45a1686d0..f5f95160d35 100644 --- a/src/plugins/nim/project/nimbletaskstep.cpp +++ b/src/plugins/nim/project/nimbletaskstep.cpp @@ -110,7 +110,7 @@ bool NimbleTaskStep::validate() QTC_ASSERT(nimbleBuildSystem, return false); if (!Utils::contains(nimbleBuildSystem->tasks(), [this](const NimbleTask &task){ return task.name == m_taskName; })) { - emit addTask(BuildSystemTask(Task::Error, tr("Nimble task %1 not found").arg(m_taskName))); + emit addTask(BuildSystemTask(Task::Error, tr("Nimble task %1 not found.").arg(m_taskName))); emitFaultyConfigurationMessage(); return false; } diff --git a/src/plugins/projectexplorer/appoutputpane.cpp b/src/plugins/projectexplorer/appoutputpane.cpp index 4f866490a10..4cc128cc0c2 100644 --- a/src/plugins/projectexplorer/appoutputpane.cpp +++ b/src/plugins/projectexplorer/appoutputpane.cpp @@ -186,14 +186,14 @@ AppOutputPane::AppOutputPane() : // Rerun m_reRunButton->setIcon(Utils::Icons::RUN_SMALL_TOOLBAR.icon()); - m_reRunButton->setToolTip(tr("Re-run this run-configuration")); + m_reRunButton->setToolTip(tr("Re-run this run-configuration.")); m_reRunButton->setEnabled(false); connect(m_reRunButton, &QToolButton::clicked, this, &AppOutputPane::reRunRunControl); // Stop m_stopAction->setIcon(Utils::Icons::STOP_SMALL_TOOLBAR.icon()); - m_stopAction->setToolTip(tr("Stop Running Program")); + m_stopAction->setToolTip(tr("Stop running program.")); m_stopAction->setEnabled(false); Core::Command *cmd = Core::ActionManager::registerAction(m_stopAction, Constants::STOP); @@ -833,7 +833,7 @@ public: : {&m_runOutputModeComboBox, &m_debugOutputModeComboBox}) { modeComboBox->addItem(tr("Always"), int(AppOutputPaneMode::PopupOnOutput)); modeComboBox->addItem(tr("Never"), int(AppOutputPaneMode::FlashOnOutput)); - modeComboBox->addItem(tr("On first output only"), + modeComboBox->addItem(tr("On First Output Only"), int(AppOutputPaneMode::PopupOnFirstOutput)); } m_runOutputModeComboBox.setCurrentIndex(m_runOutputModeComboBox diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 816b2441966..8791ae69ed5 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -1087,7 +1087,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er msessionContextMenu->addAction(cmd, Constants::G_SESSION_BUILD); dd->m_buildSessionForAllConfigsAction - = new QAction(buildIcon, tr("Build All Projects For All Configurations"), this); + = new QAction(buildIcon, tr("Build All Projects for All Configurations"), this); cmd = ActionManager::registerAction(dd->m_buildSessionForAllConfigsAction, Constants::BUILDSESSIONALLCONFIGS); mbuild->addAction(cmd, Constants::G_BUILD_BUILD); @@ -1107,7 +1107,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er msessionContextMenu->addAction(cmd, Constants::G_SESSION_REBUILD); dd->m_rebuildSessionForAllConfigsAction - = new QAction(Icons::REBUILD.icon(), tr("Rebuild All Projects For All Configurations"), + = new QAction(Icons::REBUILD.icon(), tr("Rebuild All Projects for All Configurations"), this); cmd = ActionManager::registerAction(dd->m_rebuildSessionForAllConfigsAction, Constants::REBUILDSESSIONALLCONFIGS); @@ -1122,7 +1122,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er msessionContextMenu->addAction(cmd, Constants::G_SESSION_REBUILD); dd->m_cleanSessionForAllConfigsAction = new QAction(Utils::Icons::CLEAN.icon(), - tr("Clean All Projects For All Configurations"), this); + tr("Clean All Projects for All Configurations"), this); cmd = ActionManager::registerAction(dd->m_cleanSessionForAllConfigsAction, Constants::CLEANSESSIONALLCONFIGS); mbuild->addAction(cmd, Constants::G_BUILD_CLEAN); diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.ui b/src/plugins/projectexplorer/projectexplorersettingspage.ui index d17b7582c4a..2a2fc286d73 100644 --- a/src/plugins/projectexplorer/projectexplorersettingspage.ui +++ b/src/plugins/projectexplorer/projectexplorersettingspage.ui @@ -263,7 +263,7 @@ - Deduced From Project + Deduced from Project diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp index 0b1f61c5f47..4ec47bca4e4 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.cpp +++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp @@ -344,7 +344,7 @@ void ArgumentsAspect::addToLayout(LayoutBuilder &builder) containerLayout->setContentsMargins(0, 0, 0, 0); containerLayout->addWidget(setupChooser()); m_multiLineButton = new ExpandButton; - m_multiLineButton->setToolTip(tr("Toggle multi-line mode")); + m_multiLineButton->setToolTip(tr("Toggle multi-line mode.")); m_multiLineButton->setChecked(m_multiLine); connect(m_multiLineButton, &QCheckBox::clicked, this, [this](bool checked) { if (m_multiLine == checked) diff --git a/src/plugins/qbsprojectmanager/qbssession.cpp b/src/plugins/qbsprojectmanager/qbssession.cpp index 14cdea8095f..af2dd633642 100644 --- a/src/plugins/qbsprojectmanager/qbssession.cpp +++ b/src/plugins/qbsprojectmanager/qbssession.cpp @@ -263,7 +263,7 @@ QString QbsSession::errorString(QbsSession::Error error) { switch (error) { case Error::QbsQuit: - return tr("The qbs process quit unexpectedly"); + return tr("The qbs process quit unexpectedly."); case Error::QbsFailedToStart: return tr("The qbs process failed to start."); case Error::ProtocolError: diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 93a95192688..14fd924665c 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -72,6 +72,7 @@ #include #include #include +#include using namespace QmakeProjectManager::Internal; using namespace ProjectExplorer; @@ -83,6 +84,8 @@ namespace Internal { const int UPDATE_INTERVAL = 3000; +static Q_LOGGING_CATEGORY(qmakeBuildSystemLog, "qtc.qmake.buildsystem", QtWarningMsg); + /// Watches folders for QmakePriFile nodes /// use one file system watcher to watch all folders /// such minimizing system ressouce usage @@ -185,7 +188,7 @@ QmakeBuildSystem::QmakeBuildSystem(QmakeBuildConfiguration *bc) m_qmakeVfs->setTextCodec(codec); m_asyncUpdateTimer.setSingleShot(true); - m_asyncUpdateTimer.setInterval(UPDATE_INTERVAL); + m_asyncUpdateTimer.setInterval(0); connect(&m_asyncUpdateTimer, &QTimer::timeout, this, &QmakeBuildSystem::asyncUpdate); m_rootProFile = std::make_unique(this, projectFilePath()); @@ -454,12 +457,11 @@ void QmakeBuildSystem::scheduleAsyncUpdateFile(QmakeProFile *file, QmakeProFile: void QmakeBuildSystem::scheduleUpdateAllNowOrLater() { - if (m_firstParseNeeded) { - m_firstParseNeeded = false; + qCDebug(qmakeBuildSystemLog) << __FUNCTION__ << m_firstParseNeeded; + if (m_firstParseNeeded) scheduleUpdateAll(QmakeProFile::ParseNow); - } else { + else scheduleUpdateAll(QmakeProFile::ParseLater); - } } void QmakeBuildSystem::scheduleUpdateAll(QmakeProFile::AsyncUpdateDelay delay) @@ -490,13 +492,17 @@ void QmakeBuildSystem::scheduleUpdateAll(QmakeProFile::AsyncUpdateDelay delay) void QmakeBuildSystem::startAsyncTimer(QmakeProFile::AsyncUpdateDelay delay) { - if (!m_buildConfiguration->isActive()) + if (!m_buildConfiguration->isActive()) { + qCDebug(qmakeBuildSystemLog) << __FUNCTION__ << "skipped, not active"; return; + } + + const int interval = qMin(m_asyncUpdateTimer.interval(), + delay == QmakeProFile::ParseLater ? UPDATE_INTERVAL : 0); + qCDebug(qmakeBuildSystemLog) << __FUNCTION__ << interval; m_asyncUpdateTimer.stop(); - m_asyncUpdateTimer.setInterval(qMin(m_asyncUpdateTimer.interval(), - delay == QmakeProFile::ParseLater ? UPDATE_INTERVAL : 0)); - + m_asyncUpdateTimer.setInterval(interval); m_asyncUpdateTimer.start(); } @@ -543,6 +549,9 @@ void QmakeBuildSystem::decrementPendingEvaluateFutures() m_guard.markAsSuccess(); // Qmake always returns (some) data, even when it failed:-) m_guard = {}; // This triggers emitParsingFinished by destroying the previous guard. + qCDebug(qmakeBuildSystemLog) << __FUNCTION__ << "first parse succeeded"; + m_firstParseNeeded = false; + emitBuildSystemUpdated(); } } @@ -556,6 +565,7 @@ bool QmakeBuildSystem::wasEvaluateCanceled() void QmakeBuildSystem::asyncUpdate() { m_asyncUpdateTimer.setInterval(UPDATE_INTERVAL); + qCDebug(qmakeBuildSystemLog) << __FUNCTION__; if (m_invalidateQmakeVfsContents) { m_invalidateQmakeVfsContents = false; @@ -616,7 +626,7 @@ Tasks QmakeProject::projectIssues(const Kit *k) const if (qtThatContainsProject && qtThatContainsProject != qtFromKit) { result.append(CompileTask(Task::Warning, tr("Project is part of Qt sources that do not match " - "the Qt defined in the Kit"))); + "the Qt defined in the kit."))); } return result; diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index eeaa5c48f89..3687ba362d2 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -112,16 +112,17 @@ void DesignerActionManager::polishActions() const [](ActionInterface *action) { return action->type() != ActionInterface::ContextMenu; }); Core::Context qmlDesignerFormEditorContext(Constants::C_QMLFORMEDITOR); + Core::Context qmlDesignerEditor3DContext(Constants::C_QMLEDITOR3D); Core::Context qmlDesignerNavigatorContext(Constants::C_QMLNAVIGATOR); Core::Context qmlDesignerUIContext; qmlDesignerUIContext.add(qmlDesignerFormEditorContext); + qmlDesignerUIContext.add(qmlDesignerEditor3DContext); qmlDesignerUIContext.add(qmlDesignerNavigatorContext); for (auto *action : actions) { if (!action->menuId().isEmpty()) { - const QString id = - QString("QmlDesigner.%1").arg(QString::fromLatin1(action->menuId())); + const QString id = QString("QmlDesigner.%1").arg(QString::fromLatin1(action->menuId())); Core::Command *cmd = Core::ActionManager::registerAction(action->action(), id.toLatin1().constData(), qmlDesignerUIContext); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h index 2243a466dd4..df9ab26be8f 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dcanvas.h @@ -45,6 +45,8 @@ public: void updateRenderImage(const QImage &img); void updateActiveScene(qint32 activeScene); + qint32 activeScene() const { return m_activeScene; } + protected: void mousePressEvent(QMouseEvent *e) override; void mouseReleaseEvent(QMouseEvent *e) override; diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp index d3dc95b4e57..5e203026d3b 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp @@ -37,6 +37,8 @@ #include #include #include +#include +#include #include @@ -55,6 +57,9 @@ void Edit3DView::createEdit3DWidget() { createEdit3DActions(); m_edit3DWidget = new Edit3DWidget(this); + + auto editor3DContext = new Internal::Editor3DContext(m_edit3DWidget.data()); + Core::ICore::addContextObject(editor3DContext); } WidgetInfo Edit3DView::widgetInfo() @@ -88,8 +93,11 @@ void Edit3DView::updateActiveScene3D(const QVariantMap &sceneState) const QString orientationKey = QStringLiteral("globalOrientation"); const QString editLightKey = QStringLiteral("showEditLight"); - if (sceneState.contains(sceneKey)) - edit3DWidget()->canvas()->updateActiveScene(sceneState[sceneKey].value()); + if (sceneState.contains(sceneKey)) { + qint32 newActiveScene = sceneState[sceneKey].value(); + edit3DWidget()->canvas()->updateActiveScene(newActiveScene); + rootModelNode().setAuxiliaryData("3d-active-scene", newActiveScene); + } if (sceneState.contains(selectKey)) m_selectionModeAction->action()->setChecked(sceneState[selectKey].toInt() == 0); @@ -133,12 +141,14 @@ void Edit3DView::modelAboutToBeDetached(Model *model) void Edit3DView::sendInputEvent(QInputEvent *e) const { - nodeInstanceView()->sendInputEvent(e); + if (nodeInstanceView()) + nodeInstanceView()->sendInputEvent(e); } void Edit3DView::edit3DViewResized(const QSize &size) const { - nodeInstanceView()->edit3DViewResized(size); + if (nodeInstanceView()) + nodeInstanceView()->edit3DViewResized(size); } QSize Edit3DView::canvasSize() const @@ -154,7 +164,7 @@ void Edit3DView::createEdit3DActions() m_selectionModeAction = new Edit3DAction( "Edit3DSelectionModeToggle", View3DActionCommand::SelectionModeToggle, - QCoreApplication::translate("SelectionModeToggleAction", "Toggle Group / Single Selection Mode"), + QCoreApplication::translate("SelectionModeToggleAction", "Toggle Group/Single Selection Mode"), QKeySequence(Qt::Key_Q), true, false, Icons::EDIT3D_SELECTION_MODE_OFF.icon(), Icons::EDIT3D_SELECTION_MODE_ON.icon()); @@ -181,27 +191,27 @@ void Edit3DView::createEdit3DActions() m_fitAction = new Edit3DAction( "Edit3DFitToView", View3DActionCommand::FitToView, - QCoreApplication::translate("FitToViewAction", "Fit Selected Object To View"), + QCoreApplication::translate("FitToViewAction", "Fit Selected Object to View"), QKeySequence(Qt::Key_F), false, false, Icons::EDIT3D_FIT_SELECTED_OFF.icon(), {}); m_cameraModeAction = new Edit3DAction( "Edit3DCameraToggle", View3DActionCommand::CameraToggle, - QCoreApplication::translate("CameraToggleAction", "Toggle Perspective / Orthographic Edit Camera"), + QCoreApplication::translate("CameraToggleAction", "Toggle Perspective/Orthographic Edit Camera"), QKeySequence(Qt::Key_T), true, false, Icons::EDIT3D_EDIT_CAMERA_OFF.icon(), Icons::EDIT3D_EDIT_CAMERA_ON.icon()); m_orientationModeAction = new Edit3DAction( "Edit3DOrientationToggle", View3DActionCommand::OrientationToggle, - QCoreApplication::translate("OrientationToggleAction", "Toggle Global / Local Orientation"), + QCoreApplication::translate("OrientationToggleAction", "Toggle Global/Local Orientation"), QKeySequence(Qt::Key_Y), true, false, Icons::EDIT3D_ORIENTATION_OFF.icon(), Icons::EDIT3D_ORIENTATION_ON.icon()); m_editLightAction = new Edit3DAction( "Edit3DEditLightToggle", View3DActionCommand::EditLightToggle, - QCoreApplication::translate("EditLightToggleAction", "Toggle Edit Light On / Off"), + QCoreApplication::translate("EditLightToggleAction", "Toggle Edit Light On/Off"), QKeySequence(Qt::Key_U), true, false, Icons::EDIT3D_LIGHT_OFF.icon(), Icons::EDIT3D_LIGHT_ON.icon()); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp index b21bb3d46ec..461613e476c 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp @@ -33,6 +33,7 @@ #include "qmldesignerconstants.h" #include "viewmanager.h" +#include #include #include #include @@ -42,6 +43,11 @@ namespace QmlDesigner { Edit3DWidget::Edit3DWidget(Edit3DView *view) : m_view(view) { + Core::Context context(Constants::C_QMLEDITOR3D); + m_context = new Core::IContext(this); + m_context->setContext(context); + m_context->setWidget(this); + setMouseTracking(true); setFocusPolicy(Qt::WheelFocus); @@ -93,6 +99,14 @@ Edit3DWidget::Edit3DWidget(Edit3DView *view) : fillLayout->addWidget(m_canvas.data()); } +void Edit3DWidget::contextHelp(const Core::IContext::HelpCallback &callback) const +{ + if (m_view) + m_view->contextHelp(callback); + + callback({}); +} + Edit3DCanvas *Edit3DWidget::canvas() const { return m_canvas.data(); diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h index 967713930e4..c5cea8836cd 100644 --- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h +++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.h @@ -26,6 +26,7 @@ #include #include +#include namespace QmlDesigner { @@ -42,12 +43,14 @@ public: Edit3DCanvas *canvas() const; Edit3DView *view() const; + void contextHelp(const Core::IContext::HelpCallback &callback) const; private: QPointer m_edit3DView; QPointer m_view; QPointer m_canvas; QPointer m_toolBox; + Core::IContext *m_context = nullptr; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp index f13de043258..c9a98580a7a 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp @@ -85,13 +85,13 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) : m_noSnappingAction->setIcon(Icons::NO_SNAPPING.icon()); registerActionAsCommand(m_noSnappingAction, Constants::FORMEDITOR_NO_SNAPPING, QKeySequence(Qt::Key_T)); - m_snappingAndAnchoringAction = layoutActionGroup->addAction(tr("Snap to parent or sibling items and generate anchors")); + m_snappingAndAnchoringAction = layoutActionGroup->addAction(tr("Snap to parent or sibling items and generate anchors.")); m_snappingAndAnchoringAction->setCheckable(true); m_snappingAndAnchoringAction->setChecked(true); m_snappingAndAnchoringAction->setIcon(Icons::NO_SNAPPING_AND_ANCHORING.icon()); registerActionAsCommand(m_snappingAndAnchoringAction, Constants::FORMEDITOR_NO_SNAPPING_AND_ANCHORING, QKeySequence(Qt::Key_W)); - m_snappingAction = layoutActionGroup->addAction(tr("Snap to parent or sibling items but do not generate anchors")); + m_snappingAction = layoutActionGroup->addAction(tr("Snap to parent or sibling items but do not generate anchors.")); m_snappingAction->setCheckable(true); m_snappingAction->setChecked(true); m_snappingAction->setIcon(Icons::SNAPPING.icon()); @@ -106,7 +106,7 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) : upperActions.append(separatorAction); m_showBoundingRectAction = new QAction(Utils::Icons::BOUNDING_RECT.icon(), - tr("Show bounding rectangles and stripes for empty items"), + tr("Show bounding rectangles and stripes for empty items."), this); m_showBoundingRectAction->setCheckable(true); m_showBoundingRectAction->setChecked(false); @@ -152,7 +152,7 @@ FormEditorWidget::FormEditorWidget(FormEditorView *view) : upperActions.append(m_zoomAction.data()); m_toolBox->addRightSideAction(m_zoomAction.data()); - m_resetAction = new QAction(Utils::Icons::RESET_TOOLBAR.icon(), tr("Reset view"), this); + m_resetAction = new QAction(Utils::Icons::RESET_TOOLBAR.icon(), tr("Reset View"), this); registerActionAsCommand(m_resetAction, Constants::FORMEDITOR_REFRESH, QKeySequence(Qt::Key_R)); addAction(m_resetAction.data()); @@ -342,7 +342,6 @@ double FormEditorWidget::containerPadding() const return DesignerSettings::getValue(DesignerSettingsKey::CONTAINERPADDING).toDouble(); } - void FormEditorWidget::contextHelp(const Core::IContext::HelpCallback &callback) const { if (m_formEditorView) diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp index 75b45fedb86..e5d7e8978dc 100644 --- a/src/plugins/qmldesigner/components/integration/designdocument.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp @@ -35,6 +35,8 @@ #include #include #include +#include "qmldesignerconstants.h" +#include "qmlvisualnode.h" #include #include @@ -44,6 +46,7 @@ #include #include #include +#include #include #include @@ -449,7 +452,7 @@ void DesignDocument::paste() if (rootNode.type() == "empty") return; - if (rootNode.id() == "designer__Selection") { + if (rootNode.id() == "designer__Selection") { // pasting multiple objects currentModel()->attachView(&view); ModelNode targetNode; @@ -458,8 +461,22 @@ void DesignDocument::paste() targetNode = view.selectedModelNodes().constFirst(); //In case we copy and paste a selection we paste in the parent item - if ((view.selectedModelNodes().count() == selectedNodes.count()) && targetNode.isValid() && targetNode.hasParentProperty()) + if ((view.selectedModelNodes().count() == selectedNodes.count()) && targetNode.isValid() && targetNode.hasParentProperty()) { targetNode = targetNode.parentProperty().parentModelNode(); + } else { + // if selection is empty and copied nodes are all 3D nodes, paste them under the active scene + bool all3DNodes = std::find_if(selectedNodes.begin(), selectedNodes.end(), + [](const ModelNode &node) { return !node.isSubclassOf("QtQuick3D.Node"); }) + == selectedNodes.end(); + if (all3DNodes) { + int activeSceneId = rootModelNode().auxiliaryData("3d-active-scene").toInt(); + if (activeSceneId != -1) { + NodeListProperty sceneNodeProperty + = QmlVisualNode::findSceneNodeProperty(rootModelNode().view(), activeSceneId); + targetNode = sceneNodeProperty.parentModelNode(); + } + } + } if (!targetNode.isValid()) targetNode = view.rootModelNode(); @@ -487,24 +504,35 @@ void DesignDocument::paste() view.setSelectedModelNodes(pastedNodeList); }); - } else { - rewriterView()->executeInTransaction("DesignDocument::paste1", [this, &view, selectedNodes, rootNode](){ + } else { // pasting single object + rewriterView()->executeInTransaction("DesignDocument::paste1", [this, &view, selectedNodes, rootNode]() { currentModel()->attachView(&view); ModelNode pastedNode(view.insertModel(rootNode)); ModelNode targetNode; - if (!view.selectedModelNodes().isEmpty()) + if (!view.selectedModelNodes().isEmpty()) { targetNode = view.selectedModelNodes().constFirst(); + } else { + // if selection is empty and this is a 3D Node, paste it under the active scene + if (pastedNode.isSubclassOf("QtQuick3D.Node")) { + int activeSceneId = rootModelNode().auxiliaryData("3d-active-scene").toInt(); + if (activeSceneId != -1) { + NodeListProperty sceneNodeProperty + = QmlVisualNode::findSceneNodeProperty(rootModelNode().view(), activeSceneId); + targetNode = sceneNodeProperty.parentModelNode(); + } + } + } if (!targetNode.isValid()) targetNode = view.rootModelNode(); if (targetNode.hasParentProperty() && - (pastedNode.simplifiedTypeName() == targetNode.simplifiedTypeName()) && - (pastedNode.variantProperty("width").value() == targetNode.variantProperty("width").value()) && - (pastedNode.variantProperty("height").value() == targetNode.variantProperty("height").value())) - + pastedNode.simplifiedTypeName() == targetNode.simplifiedTypeName() && + pastedNode.variantProperty("width").value() == targetNode.variantProperty("width").value() && + pastedNode.variantProperty("height").value() == targetNode.variantProperty("height").value()) { targetNode = targetNode.parentProperty().parentModelNode(); + } PropertyName defaultProperty(targetNode.metaInfo().defaultPropertyName()); diff --git a/src/plugins/qmldesigner/components/propertyeditor/aligndistribute.cpp b/src/plugins/qmldesigner/components/propertyeditor/aligndistribute.cpp index 297e815b956..8b7672783e0 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/aligndistribute.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/aligndistribute.cpp @@ -685,7 +685,7 @@ bool AlignDistribute::executePixelPerfectDialog() const { QDialogButtonBox::StandardButton pressed = Utils::CheckableMessageBox::doNotAskAgainQuestion( Core::ICore::dialogParent(), - tr("Cannot distribute perfectly"), + tr("Cannot Distribute Perfectly"), tr("These objects cannot be distributed to equal pixel values. " "Do you want to distribute to the nearest possible values?"), Core::ICore::settings(), diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp index 37693158f17..9674624863b 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorview.cpp @@ -443,6 +443,8 @@ void StatesEditorView::variantPropertiesChanged(const QList &pr for (const VariantProperty &property : propertyList) { if (property.name() == "name" && QmlModelState::isValidQmlModelState(property.parentModelNode())) resetModel(); + else if (property.name() == "state" && property.parentModelNode().isRootNode()) + resetModel(); } m_block = false; diff --git a/src/plugins/qmldesigner/designmodecontext.cpp b/src/plugins/qmldesigner/designmodecontext.cpp index 298fe6d07f4..a0cb0cf4072 100644 --- a/src/plugins/qmldesigner/designmodecontext.cpp +++ b/src/plugins/qmldesigner/designmodecontext.cpp @@ -27,6 +27,7 @@ #include "qmldesignerconstants.h" #include "designmodewidget.h" #include "formeditorwidget.h" +#include "edit3dwidget.h" #include "navigatorwidget.h" #include "texteditorwidget.h" @@ -57,6 +58,18 @@ void FormEditorContext::contextHelp(const HelpCallback &callback) const qobject_cast(m_widget)->contextHelp(callback); } +Editor3DContext::Editor3DContext(QWidget *widget) + : IContext(widget) +{ + setWidget(widget); + setContext(Core::Context(Constants::C_QMLEDITOR3D, Constants::C_QT_QUICK_TOOLS_MENU)); +} + +void Editor3DContext::contextHelp(const HelpCallback &callback) const +{ + qobject_cast(m_widget)->contextHelp(callback); +} + NavigatorContext::NavigatorContext(QWidget *widget) : IContext(widget) { diff --git a/src/plugins/qmldesigner/designmodecontext.h b/src/plugins/qmldesigner/designmodecontext.h index 0417f62921d..b30430b5eeb 100644 --- a/src/plugins/qmldesigner/designmodecontext.h +++ b/src/plugins/qmldesigner/designmodecontext.h @@ -51,6 +51,15 @@ public: void contextHelp(const Core::IContext::HelpCallback &callback) const override; }; +class Editor3DContext : public Core::IContext +{ + Q_OBJECT + +public: + Editor3DContext(QWidget *widget); + void contextHelp(const Core::IContext::HelpCallback &callback) const override; +}; + class NavigatorContext : public Core::IContext { Q_OBJECT diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index 01385895227..ea88dfcc045 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -66,6 +66,7 @@ #include #include #include +#include #include #include @@ -399,6 +400,30 @@ void DesignModeWidget::setup() } }); + auto workspaceComboBox = new QComboBox(); + workspaceComboBox->setMinimumWidth(120); + workspaceComboBox->setToolTip(tr("Switch the active workspace.")); + auto sortedWorkspaces = m_dockManager->workspaces(); + Utils::sort(sortedWorkspaces); + workspaceComboBox->addItems(sortedWorkspaces); + workspaceComboBox->setCurrentText(m_dockManager->activeWorkspace()); + toolBar->addWidget(workspaceComboBox); + + connect(m_dockManager, &ADS::DockManager::workspaceListChanged, + workspaceComboBox, [this, workspaceComboBox]() { + workspaceComboBox->clear(); + auto sortedWorkspaces = m_dockManager->workspaces(); + Utils::sort(sortedWorkspaces); + workspaceComboBox->addItems(sortedWorkspaces); + workspaceComboBox->setCurrentText(m_dockManager->activeWorkspace()); + }); + connect(m_dockManager, &ADS::DockManager::workspaceLoaded, workspaceComboBox, &QComboBox::setCurrentText); + connect(workspaceComboBox, QOverload::of(&QComboBox::activated), + m_dockManager, [this, workspaceComboBox] (int index) { + Q_UNUSED(index) + m_dockManager->openWorkspace(workspaceComboBox->currentText()); + }); + viewManager().enableWidgets(); readSettings(); show(); diff --git a/src/plugins/qmldesigner/generateresource.cpp b/src/plugins/qmldesigner/generateresource.cpp index dd72d8c31ca..87e9772ab4a 100644 --- a/src/plugins/qmldesigner/generateresource.cpp +++ b/src/plugins/qmldesigner/generateresource.cpp @@ -83,7 +83,7 @@ void GenerateResource::generateMenuEntry() currentProject->projectFilePath().parentDir().parentDir().toString())); auto resourceFileName = Core:: DocumentManager::getSaveFileName( - QCoreApplication::translate("QmlDesigner::GenerateResource", "Save Project As Resource"), + QCoreApplication::translate("QmlDesigner::GenerateResource", "Save Project as Resource"), lastUsedPathes.value(currentProject->displayName()) + "/" + currentProject->displayName() + ".qmlrc", QCoreApplication::translate("QmlDesigner::GenerateResource", "QML Resource File (*.qmlrc)")); if (resourceFileName.isEmpty()) diff --git a/src/plugins/qmldesigner/qmldesignerconstants.h b/src/plugins/qmldesigner/qmldesignerconstants.h index 89c5b643967..132f31d2ffd 100644 --- a/src/plugins/qmldesigner/qmldesignerconstants.h +++ b/src/plugins/qmldesigner/qmldesignerconstants.h @@ -28,14 +28,15 @@ namespace QmlDesigner { namespace Constants { -const char C_BACKSPACE[] = "QmlDesigner.Backspace"; -const char C_DELETE[] = "QmlDesigner.Delete"; +const char C_BACKSPACE[] = "QmlDesigner.Backspace"; +const char C_DELETE[] = "QmlDesigner.Delete"; // Context -const char C_QMLDESIGNER[] = "QmlDesigner::QmlDesignerMain"; -const char C_QMLFORMEDITOR[] = "QmlDesigner::FormEditor"; -const char C_QMLNAVIGATOR[] = "QmlDesigner::Navigator"; -const char C_QMLTEXTEDITOR[] = "QmlDesigner::TextEditor"; +const char C_QMLDESIGNER[] = "QmlDesigner::QmlDesignerMain"; +const char C_QMLFORMEDITOR[] = "QmlDesigner::FormEditor"; +const char C_QMLEDITOR3D[] = "QmlDesigner::Editor3D"; +const char C_QMLNAVIGATOR[] = "QmlDesigner::Navigator"; +const char C_QMLTEXTEDITOR[] = "QmlDesigner::TextEditor"; // Special context for preview menu, shared b/w designer and text editor const char C_QT_QUICK_TOOLS_MENU[] = "QmlDesigner::ToolsMenu"; diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 1a2f3c8c273..a65ff3600be 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -287,14 +287,17 @@ void QmlDesignerPlugin::integrateIntoQtCreator(QWidget *modeWidget) Core::ICore::addContextObject(d->context); Core::Context qmlDesignerMainContext(Constants::C_QMLDESIGNER); Core::Context qmlDesignerFormEditorContext(Constants::C_QMLFORMEDITOR); + Core::Context qmlDesignerEditor3dContext(Constants::C_QMLEDITOR3D); Core::Context qmlDesignerNavigatorContext(Constants::C_QMLNAVIGATOR); d->context->context().add(qmlDesignerMainContext); d->context->context().add(qmlDesignerFormEditorContext); + d->context->context().add(qmlDesignerEditor3dContext); d->context->context().add(qmlDesignerNavigatorContext); d->context->context().add(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID); - d->shortCutManager.registerActions(qmlDesignerMainContext, qmlDesignerFormEditorContext, qmlDesignerNavigatorContext); + d->shortCutManager.registerActions(qmlDesignerMainContext, qmlDesignerFormEditorContext, + qmlDesignerEditor3dContext, qmlDesignerNavigatorContext); const QStringList mimeTypes = { QmlJSTools::Constants::QML_MIMETYPE, QmlJSTools::Constants::QMLUI_MIMETYPE }; diff --git a/src/plugins/qmldesigner/shortcutmanager.cpp b/src/plugins/qmldesigner/shortcutmanager.cpp index 8fee83dd8a1..1ae2ef14819 100644 --- a/src/plugins/qmldesigner/shortcutmanager.cpp +++ b/src/plugins/qmldesigner/shortcutmanager.cpp @@ -77,6 +77,7 @@ ShortCutManager::ShortCutManager() void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContext, const Core::Context &qmlDesignerFormEditorContext, + const Core::Context &qmlDesignerEditor3DContext, const Core::Context &qmlDesignerNavigatorContext) { Core::ActionContainer *editMenu = Core::ActionManager::actionContainer(Core::Constants::M_EDIT); @@ -166,18 +167,21 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex designerActionManager.addCreatorCommand(command, ComponentCoreConstants::editCategory, 280); Core::ActionManager::registerAction(&m_cutAction, Core::Constants::CUT, qmlDesignerFormEditorContext); + Core::ActionManager::registerAction(&m_cutAction, Core::Constants::CUT, qmlDesignerEditor3DContext); command = Core::ActionManager::registerAction(&m_cutAction, Core::Constants::CUT, qmlDesignerNavigatorContext); command->setDefaultKeySequence(QKeySequence::Cut); editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE); designerActionManager.addCreatorCommand(command, ComponentCoreConstants::editCategory, 260, Utils::Icons::CUT_TOOLBAR.icon()); Core::ActionManager::registerAction(&m_copyAction, Core::Constants::COPY, qmlDesignerFormEditorContext); + Core::ActionManager::registerAction(&m_copyAction, Core::Constants::COPY, qmlDesignerEditor3DContext); command = Core::ActionManager::registerAction(&m_copyAction, Core::Constants::COPY, qmlDesignerNavigatorContext); command->setDefaultKeySequence(QKeySequence::Copy); editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE); designerActionManager.addCreatorCommand(command, ComponentCoreConstants::editCategory, 250, Utils::Icons::COPY_TOOLBAR.icon()); Core::ActionManager::registerAction(&m_pasteAction, Core::Constants::PASTE, qmlDesignerFormEditorContext); + Core::ActionManager::registerAction(&m_pasteAction, Core::Constants::PASTE, qmlDesignerEditor3DContext); command = Core::ActionManager::registerAction(&m_pasteAction, Core::Constants::PASTE, qmlDesignerNavigatorContext); command->setDefaultKeySequence(QKeySequence::Paste); editMenu->addAction(command, Core::Constants::G_EDIT_COPYPASTE); @@ -209,14 +213,13 @@ void ShortCutManager::registerActions(const Core::Context &qmlDesignerMainContex }); connect(Core::ICore::instance(), &Core::ICore::contextChanged, this, [&designerActionManager, this](const Core::Context &context){ - if (!context.contains(Constants::C_QMLFORMEDITOR) && !context.contains(Constants::C_QMLNAVIGATOR)) { + if (!context.contains(Constants::C_QMLFORMEDITOR) && !context.contains(Constants::C_QMLEDITOR3D) && !context.contains(Constants::C_QMLNAVIGATOR)) { m_deleteAction.setEnabled(false); m_cutAction.setEnabled(false); m_copyAction.setEnabled(false); m_pasteAction.setEnabled(false); } else { designerActionManager.view()->emitSelectionChanged(); - } }); } diff --git a/src/plugins/qmldesigner/shortcutmanager.h b/src/plugins/qmldesigner/shortcutmanager.h index 102448f4307..6e5b5ec23bd 100644 --- a/src/plugins/qmldesigner/shortcutmanager.h +++ b/src/plugins/qmldesigner/shortcutmanager.h @@ -46,6 +46,7 @@ public: void registerActions(const Core::Context &qmlDesignerMainContext, const Core::Context &qmlDesignerFormEditorContext, + const Core::Context &qmlDesignerEditor3DContext, const Core::Context &qmlDesignerNavigatorContext); void connectUndoActions(DesignDocument *designDocument); diff --git a/src/plugins/remotelinux/remotelinuxenvironmentaspectwidget.cpp b/src/plugins/remotelinux/remotelinuxenvironmentaspectwidget.cpp index 0d94cf3ffab..82343b973fb 100644 --- a/src/plugins/remotelinux/remotelinuxenvironmentaspectwidget.cpp +++ b/src/plugins/remotelinux/remotelinuxenvironmentaspectwidget.cpp @@ -72,7 +72,7 @@ RemoteLinuxEnvironmentAspectWidget::RemoteLinuxEnvironmentAspectWidget = [target](const Utils::Environment &env) { IDevice::ConstPtr device = DeviceKitAspect::device(target->kit()); if (!device) { - QMessageBox::critical(Core::ICore::mainWindow(), tr("Cannot open terminal"), + QMessageBox::critical(Core::ICore::mainWindow(), tr("Cannot Open Terminal"), tr("Cannot open remote terminal: Current kit has no device.")); return; } diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 2a6563c2199..a38fab49b03 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -101,6 +101,7 @@ #include #include #include +#include #include #include #include diff --git a/src/plugins/texteditor/texteditoroverlay.cpp b/src/plugins/texteditor/texteditoroverlay.cpp index 735869082f4..b923b257c3d 100644 --- a/src/plugins/texteditor/texteditoroverlay.cpp +++ b/src/plugins/texteditor/texteditoroverlay.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include diff --git a/src/tools/qml2puppet/CMakeLists.txt b/src/tools/qml2puppet/CMakeLists.txt index 50d457f4f38..da25ec53964 100644 --- a/src/tools/qml2puppet/CMakeLists.txt +++ b/src/tools/qml2puppet/CMakeLists.txt @@ -114,6 +114,7 @@ extend_qtc_executable(qml2puppet generalhelper.cpp generalhelper.h mousearea3d.cpp mousearea3d.h camerageometry.cpp camerageometry.h + lightgeometry.cpp lightgeometry.h gridgeometry.cpp gridgeometry.h selectionboxgeometry.cpp selectionboxgeometry.h linegeometry.cpp linegeometry.h diff --git a/src/tools/qml2puppet/qml2puppet.qbs b/src/tools/qml2puppet/qml2puppet.qbs index c5c49670b4a..445ab2e867a 100644 --- a/src/tools/qml2puppet/qml2puppet.qbs +++ b/src/tools/qml2puppet/qml2puppet.qbs @@ -209,6 +209,8 @@ QtcTool { "editor3d/mousearea3d.h", "editor3d/camerageometry.cpp", "editor3d/camerageometry.h", + "editor3d/lightgeometry.cpp", + "editor3d/lightgeometry.h", "editor3d/gridgeometry.cpp", "editor3d/gridgeometry.h", "editor3d/selectionboxgeometry.cpp", diff --git a/tests/system/objects.map b/tests/system/objects.map index b5d903b7bd2..98e35535f9a 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -130,7 +130,7 @@ :Qt Creator.QML debugging and profiling:_QComboBox {leftWidget=':Qt Creator.QML debugging and profiling:_QLabel' type='QComboBox' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator.QML debugging and profiling:_QLabel {text='QML debugging and profiling:' type='QLabel' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator.QtCreator.MenuBar_QMenuBar {name='QtCreator.MenuBar' type='QMenuBar' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} -:Qt Creator.ReRun_QToolButton {toolTip='Re-run this run-configuration' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} +:Qt Creator.ReRun_QToolButton {toolTip='Re-run this run-configuration.' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator.Replace All_QToolButton {name='replaceAllButton' text='Replace All' type='QToolButton' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator.Replace_QToolButton {name='replaceButton' text='Replace' type='QToolButton' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator.Stop_QToolButton {text='Stop' type='QToolButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} diff --git a/tests/system/suite_CSUP/tst_CSUP01/test.py b/tests/system/suite_CSUP/tst_CSUP01/test.py index 63779811f6f..39f959b2128 100644 --- a/tests/system/suite_CSUP/tst_CSUP01/test.py +++ b/tests/system/suite_CSUP/tst_CSUP01/test.py @@ -81,7 +81,9 @@ def main(): try: proposalListView = waitForObject(":popupFrame_Proposal_QListView") waitForObjectItem(proposalListView, "unsigned") - test.compare(proposalListView.model().rowCount(), 1, 'Only one proposal for "unsi"?') + if useClang and platform.system() == 'Linux': # QTCREATORBUG-23159 + test.compare(proposalListView.model().rowCount(), 1, + 'Only one proposal for "unsi"?') type(proposalListView, "") test.compare(str(lineUnderCursor(editorWidget)).strip(), "unsigned", "Step 4: Verifying if: Word 'unsigned' is completed because only one option is available.") diff --git a/tests/system/suite_CSUP/tst_CSUP02/test.py b/tests/system/suite_CSUP/tst_CSUP02/test.py index 0c0e8331563..f5e7894d62d 100644 --- a/tests/system/suite_CSUP/tst_CSUP02/test.py +++ b/tests/system/suite_CSUP/tst_CSUP02/test.py @@ -65,9 +65,10 @@ def main(): usedProposal = "class derived from QObject" expectedProposals = ["class", "class ", "class template", usedProposal, "class derived from QWidget"] - test.compare(len(shownProposals), len(expectedProposals), "Number of proposed templates") - test.compare(set(shownProposals), set(expectedProposals), - "Expected proposals shown, ignoring order?") + test.xcompare(len(shownProposals), len(expectedProposals), # QTCREATORBUG-23159 + "Number of proposed templates") + test.verify(set(expectedProposals).issubset(set(shownProposals)), + "Expected proposals shown, ignoring order?") doubleClickItem(listView, usedProposal, 5, 5, 0, Qt.LeftButton) pattern = ("(?<=class)\s+name\s*:\s*public\s+QObject\s*\{\s*Q_OBJECT\s+" "public:\s+name\(\)\s*\{\}\s+virtual\s+~name\(\)\s*\{\}\s+\};") diff --git a/tests/system/suite_CSUP/tst_CSUP06/test.py b/tests/system/suite_CSUP/tst_CSUP06/test.py index c28c8bb198f..3ac52088425 100644 --- a/tests/system/suite_CSUP/tst_CSUP06/test.py +++ b/tests/system/suite_CSUP/tst_CSUP06/test.py @@ -64,22 +64,15 @@ def performAutoCompletionTest(editor, lineToStartRegEx, linePrefix, testFunc, *f def checkIncludeCompletion(editor, isClangCodeModel): test.log("Check auto-completion of include statements.") # define special handlings - noProposal = ["vec", "detail/hea", "dum"] + noProposal = ["detail/hea"] specialHandling = {"ios":"iostream", "cstd":"cstdio"} - if platform.system() in ('Microsoft', 'Windows'): - missing = ["lin"] - elif platform.system() == "Darwin": - missing = ["lin", "Win"] - noProposal.remove("vec") - else: - missing = ["Win"] # define test function to perform the _real_ auto completion test on the current line def testIncl(currentLine, *args): - missing, noProposal, specialHandling = args + noProposal, specialHandling = args inclSnippet = currentLine.split("//#include")[-1].strip().strip('<"') propShown = waitFor("object.exists(':popupFrame_TextEditor::GenericProposalWidget')", 2500) - test.compare(not propShown, inclSnippet in missing or inclSnippet in noProposal, + test.compare(not propShown, inclSnippet in noProposal, "Proposal widget is (not) shown as expected (%s)" % inclSnippet) if propShown: proposalListView = waitForObject(':popupFrame_Proposal_QListView') @@ -89,14 +82,11 @@ def checkIncludeCompletion(editor, isClangCodeModel): else: type(proposalListView, "") changedLine = str(lineUnderCursor(editor)).strip() - if inclSnippet in missing: - test.compare(changedLine, currentLine.lstrip("/"), "Include has not been modified.") - else: - test.verify(changedLine[-1] in '>"/', - "'%s' has been completed to '%s'" % (currentLine.lstrip("/"), changedLine)) + test.verify(changedLine[-1] in '>"/', + "'%s' has been completed to '%s'" % (currentLine.lstrip("/"), changedLine)) performAutoCompletionTest(editor, ".*Complete includes.*", "//#include", - testIncl, missing, noProposal, specialHandling) + testIncl, noProposal, specialHandling) def checkSymbolCompletion(editor, isClangCodeModel): test.log("Check auto-completion of symbols.") @@ -114,13 +104,16 @@ def checkSymbolCompletion(editor, isClangCodeModel): "internal.o":"internal.one", "freefunc2":"freefunc2(", "using namespace st":"using namespace std", "afun":"afunc()"} if isClangCodeModel: + missing.remove("Dummy::s") # QTCREATORBUG-22729 missing.remove("internal.o") + expectedSuggestion["in"] = ["internal", "int"] # QTCREATORBUG-22728 expectedSuggestion["internal.o"] = ["one", "operator="] if platform.system() in ('Microsoft', 'Windows'): expectedSuggestion["using namespace st"] = ["std", "stdext"] else: expectedSuggestion["using namespace st"] = ["std", "struct ", "struct template"] else: + missing.remove("afun") expectedSuggestion["using namespace st"] = ["std", "st"] # define test function to perform the _real_ auto completion test on the current line def testSymb(currentLine, *args): diff --git a/tests/system/suite_debugger/tst_qml_locals/test.py b/tests/system/suite_debugger/tst_qml_locals/test.py index 63516e89518..5f89fc8942f 100644 --- a/tests/system/suite_debugger/tst_qml_locals/test.py +++ b/tests/system/suite_debugger/tst_qml_locals/test.py @@ -27,8 +27,6 @@ source("../../shared/qtcreator.py") source("Tree.py") def main(): - test.xfail("Skipping test. This must be rewritten for current kits.") - return if os.getenv("SYSTEST_OPENGL_MISSING") == "1": test.xfail("This test needs OpenGL - skipping...") return @@ -73,9 +71,13 @@ def main(): earlyExit("Could not find expected Inspector tree inside Locals and Expressions.") return # reduce items to outer Rectangle object - items = items.getChild("QQmlEngine") + items = items.getChild("QQuickView") if items == None: - earlyExit("Could not find expected QQmlEngine tree inside Locals and Expressions.") + earlyExit("Could not find expected QQuickView tree inside Locals and Expressions.") + return + items = items.getChild("QQuickRootItem") + if items == None: + earlyExit("Could not find expected QQuickRootItem tree inside Locals and Expressions.") return items = items.getChild("Rectangle") if items == None: @@ -97,23 +99,28 @@ def main(): invokeMenuItem("File", "Exit") def __unfoldTree__(): - rootIndex = getQModelIndexStr("text='QQmlEngine'", + # TODO inspect the qmlengine as well? + rootIndex = getQModelIndexStr("text='QQuickView'", ':Locals and Expressions_Debugger::Internal::WatchTreeView') - mainRect = getQModelIndexStr("text='Rectangle'", rootIndex) - unfoldQModelIndexIncludingProperties(mainRect) + unfoldQModelIndex(rootIndex, False) + quickRootItem = getQModelIndexStr("text='QQuickRootItem'", rootIndex) + unfoldQModelIndex(quickRootItem, False) + mainRect = getQModelIndexStr("text='Rectangle'", quickRootItem) + unfoldQModelIndex(mainRect) subItems = ["text='Rectangle'", "text='Rectangle' occurrence='2'", "text='Text'"] for item in subItems: - unfoldQModelIndexIncludingProperties(getQModelIndexStr(item, mainRect)) + unfoldQModelIndex(getQModelIndexStr(item, mainRect)) -def unfoldQModelIndexIncludingProperties(indexStr): +def unfoldQModelIndex(indexStr, includingProperties=True): tv = waitForObject(':Locals and Expressions_Debugger::Internal::WatchTreeView') # HACK to avoid failing clicks tv.scrollToBottom() doubleClick(waitForObject(indexStr)) - propIndex = getQModelIndexStr("text='Properties'", indexStr) - # HACK to avoid failing clicks - tv.scrollToBottom() - doubleClick(waitForObject(propIndex)) + if includingProperties: + propIndex = getQModelIndexStr("text='Properties'", indexStr) + # HACK to avoid failing clicks + tv.scrollToBottom() + doubleClick(waitForObject(propIndex)) def fetchItems(index, valIndex, treeView): tree = Tree()