diff options
author | Eike Ziller <[email protected]> | 2021-08-26 11:09:08 +0200 |
---|---|---|
committer | Eike Ziller <[email protected]> | 2021-08-26 11:09:08 +0200 |
commit | 0777b65db3589324ab45ea5d08ad68860623e69b (patch) | |
tree | fe5e03fc4a36397649f6ec6791b3488efec8c1b4 | |
parent | 245b6c0dc73087678de941652f8c752bb49995cf (diff) | |
parent | cd8da8fe5f608d4968b90f19f30b515058605b8c (diff) |
Merge remote-tracking branch 'origin/5.0'
Conflicts:
qbs/modules/qtc/qtc.qbs
src/plugins/android/androidconfigurations.cpp
Change-Id: If8dc2cdf131811e08ca147c6f58dbb3ed3bf7227
114 files changed, 1840 insertions, 641 deletions
diff --git a/README.md b/README.md index 11630694650..d3f566f5c8d 100644 --- a/README.md +++ b/README.md @@ -213,9 +213,14 @@ While the plugin builds without it, it might not be fully functional. Note that the plugin is disabled by default. -## Third-party Components +# Licenses and Attributions -Qt Creator includes the following third-party components, +Qt Creator is available under commercial licenses from The Qt Company, +and under the GNU General Public License version 3, +annotated with The Qt Company GPL Exception 1.0. +See [LICENSE.GPL-EXCEPT](LICENSE.GPL-EXCEPT) for the details. + +Qt Creator furthermore includes the following third-party components, we thank the authors who made this possible: ### YAML Parser yaml-cpp (MIT License) diff --git a/dist/changes-5.0.0.md b/dist/changes-5.0.0.md index 565313bea38..abe1861b5db 100644 --- a/dist/changes-5.0.0.md +++ b/dist/changes-5.0.0.md @@ -22,6 +22,7 @@ Editing * Added menu item and shortcut for editing bookmark comments (QTCREATORBUG-25696) * Fixed folding for Markdown (QTCREATORBUG-25882) +* Fixed completion tooltip on secondary display (QTCREATORBUG-26053) ### C++ @@ -49,6 +50,7 @@ Editing * Fixed reformatting of functions with default values (QTCREATORBUG-23009) * Fixed wrong warning for types with same name but different namespace (QTCREATORBUG-24615) +* Fixed `Tools > External > Qt Quick > QML Utility` (QTCREATORBUG-26137) ### Language Client @@ -56,12 +58,18 @@ Editing * Added support for snippets (QTCREATORBUG-22406) * Fixed completion results for language servers that do not filter results themselves +* Fixed that empty responses could be sent (QTCREATORBUG-26116) ### Beautifier * Fixed issue with `clang-format` and multi-byte characters (QTCREATORBUG-21812, QTCREATORBUG-23131) +### Designer + +* Fixed `Go to Slot` if UI class is referred to as `UI_<class>` + (QTCREATORBUG-26013) + Projects -------- @@ -76,6 +84,8 @@ Projects * Fixed missing update of run configuration environment (QTCREATORBUG-25947) * Fixed that user files were unnecessarily saved with new time stamp (QTCREATORBUG-25921) +* Fixed that toolchain setting was fixed for auto-detected kits + (QTCREATORBUG-25839) * Reduced UI freeze after loading projects (QTCREATORBUG-25783) ### CMake @@ -83,10 +93,15 @@ Projects * Removed option `Auto-create build directories`, making this the default behavior (QTCREATORBUG-25532) * Added CMake output to right side of `Projects` mode (QTCREATORBUG-25522) +* Added CMake option `QT_CREATOR_SKIP_PACKAGE_MANAGER_SETUP` for skipping Qt + Creator's package manager auto-setup * Fixed `Jump to File` for file names with special characters (QTCREATORBUG-25572) * Fixed updating of available targets (QTCREATORBUG-24914, QTCREATORBUG-25906) * Fixed persistence of CMake tool options (QTCREATORBUG-25911) +* Fixed build library search path for CMake 3.20 and later (QTCREATORBUG-26110) +* Fixed code model issues with MSVC and CMake 3.20 and later + (QTCREATORBUG-26146) ### Qbs @@ -144,6 +159,11 @@ Platforms * Fixed detection of `_prepare_apk_dir` target for CMake projects (QTCREATORBUG-25216) +### Remote Linux + +* Fixed update of temporary local installation when build path is changed + (QTCREATORBUG-26103) + ### QNX * Fixed device configuration diff --git a/doc/qtcreator/images/qmldesigner-export-item.png b/doc/qtcreator/images/qmldesigner-export-item.png Binary files differindex 6fb8da4f538..567a9c5fa4d 100644 --- a/doc/qtcreator/images/qmldesigner-export-item.png +++ b/doc/qtcreator/images/qmldesigner-export-item.png diff --git a/doc/qtcreator/images/qmldesigner-mcu-support.png b/doc/qtcreator/images/qmldesigner-mcu-support.png Binary files differindex 23d3c0ce3d4..78cf610f1b1 100644 --- a/doc/qtcreator/images/qmldesigner-mcu-support.png +++ b/doc/qtcreator/images/qmldesigner-mcu-support.png diff --git a/doc/qtcreator/images/qmldesigner-preview-size.png b/doc/qtcreator/images/qmldesigner-preview-size.png Binary files differindex ec1d4d42543..d6a481ef735 100644 --- a/doc/qtcreator/images/qmldesigner-preview-size.png +++ b/doc/qtcreator/images/qmldesigner-preview-size.png diff --git a/doc/qtcreator/images/qmldesigner-properties-view.png b/doc/qtcreator/images/qmldesigner-properties-view.png Binary files differindex eb9cf6356f3..282b90d99d2 100644 --- a/doc/qtcreator/images/qmldesigner-properties-view.png +++ b/doc/qtcreator/images/qmldesigner-properties-view.png diff --git a/doc/qtcreator/images/qtcreator-new-subproject.png b/doc/qtcreator/images/qtcreator-new-subproject.png Binary files differindex a55daead087..e65a09bee68 100644 --- a/doc/qtcreator/images/qtcreator-new-subproject.png +++ b/doc/qtcreator/images/qtcreator-new-subproject.png diff --git a/doc/qtcreator/images/qtcreator-workspace-attaching-views.png b/doc/qtcreator/images/qtcreator-workspace-attaching-views.png Binary files differindex bbe222af3f2..c0bd0f897ee 100644 --- a/doc/qtcreator/images/qtcreator-workspace-attaching-views.png +++ b/doc/qtcreator/images/qtcreator-workspace-attaching-views.png diff --git a/doc/qtcreator/src/mcu/qtquick-mcu-support.qdocinc b/doc/qtcreator/src/mcu/qtquick-mcu-support.qdocinc index 66359905553..4501225ae4d 100644 --- a/doc/qtcreator/src/mcu/qtquick-mcu-support.qdocinc +++ b/doc/qtcreator/src/mcu/qtquick-mcu-support.qdocinc @@ -38,9 +38,9 @@ the components available on MCUs are displayed in \l Library > \uicontrol Components. Only a subset of properties is supported for the supported components. The properties that are not available on MCUs are - marked in the \l Properties view by enclosing them in square brackets. + marked in the \l Properties view with strikethrough text. - \image qmldesigner-mcu-support.png "Components and Image properties supported for MCUs" + \image qmldesigner-mcu-support.png "Components and Text properties supported for MCUs" For more information about the supported components and their properties, see \l{Qt for MCUs - All QML Types}. diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc index 942f0902cf5..d997de4a3dd 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-creating.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -93,174 +93,151 @@ \section1 Selecting Project Type - You can use wizards to create following types of projects: - - \list - - \li Application (Qt Quick) - - \list - \li Qt Quick Application - Empty - - Create an empty \l{Qt Quick} application that uses Qt Quick 2 - types. - - You can build the application and deploy it to desktop, - embedded, and mobile target platforms. - - \li Qt Quick Application - Scroll, Stack, or Swipe - - Create a Qt Quick application that uses \l{Qt Quick Controls} to - implement a scrollable list (requires Qt 5.9 or later) or a set - of pages with a stack-based or swipe-based navigation model - (requires Qt 5.7 or later). - \endlist - - \li Application (Qt) - - \list - + The following table lists the wizard templates for creating projects. + + \table + \header + \li Category + \li Wizard Template + \li Purpose + \row + \li Application (Qt for MCU) + \li MCU Support Application + \li Creates an application that uses a subset of Qt QML and + Qt Quick Controls types (as supported by Qt for MCUs) that + you can deploy, run, and debug on MCU boards. For more + information, see \l {Connecting MCUs}. + \row + \li {1,2} Application (Qt) \li Qt Widgets Application - - Use \QD forms to design a Qt widget based user interface for the - desktop and C++ to implement the application logic - + \li Uses \QD forms to design a Qt widget based user interface for + the desktop and C++ to implement the application logic. + \row \li Qt Console Application - - Use a single main.cpp file - \endlist - - \li Application (Qt for Python) - - \list - - \li Qt for Python Application - Empty, Window, Window (UI file), or - Qt Quick Application (Empty) - - Create a \l{https://doc.qt.io/qtforpython/index.html} + \li Uses a single main.cpp file. + \row + \li {1,4} Application (Qt Quick) + \li Qt Quick Application - Empty + \li Creates a Qt Quick 2 application project that can contain both + QML and C++ code. You can build the application and deploy it + to desktop, embedded, and mobile target platforms. + \row + \li Qt Quick Application - Scroll + \li Uses the \l{ScrollView} component to implement a scrollable + list view (requires Qt 5.9 or later). + \row + \li Qt Quick Application - Stack + \li Uses the \l{StackView} component to implement a set of pages + with a stack-based navigation model (requires Qt 5.7 or later). + \row + \li Qt Quick Application - Swipe + \li Uses the \l{SwipeView} component to implement a set of pages + with a swipe-based navigation model (requires Qt 5.7 or later). + \row + \li {1,4} Application (Qt for Python) + \li Qt for Python - Empty + \li Creates a \l{https://doc.qt.io/qtforpython/index.html} {Qt for Python} application that contains only the main - code for a QApplication or an empty window with or without - a widget-based UI. Alternatively, you can create an empty - Qt Quick Application. - - \endlist - - \li Application (Qt for MCU) - - \list - \li MCU Support Application - - Creates an application that uses a subset of Qt QML and - Qt Quick Controls types (as supported by Qt for MCUs) that - you can deploy, run, and debug on MCU boards. For more - information, see \l {Connecting MCUs}. - \endlist - - \li Libraries - - \list - + code for a QApplication. + \row + \li Qt for Python - Window + \li Creates a Qt for Python application that contains an empty + window. + \row + \li Qt for Python - Window (UI file) + \li Creates a Qt for Python application that contains an empty + window with a widget-based UI. + \row + \li Qt for Python - Qt Quick Application + \li Creates a Python project that contains an empty Qt Quick + Application. + \row + \li {1,3} Library \li C++ Library - - Shared or static C++ library based on qmake - + \li A shared or static C++ library based on qmake. + \row \li Qt Quick 2 Extension Plugin - - C++ plugin that makes it possible to offer extensions that can - be loaded dynamically into Qt Quick 2 applications by using the - QQmlEngine class - + \li Creates a C++ plugin that makes it possible to offer extensions + that can be loaded dynamically into Qt Quick 2 applications + by using the QQmlEngine class. + \row \li \QC Plugin - - - \endlist - - \li Other Projects - - \list - - \li Auto Test Project - - Projects with boilerplate code for a Qt or Google test. For more - information, see \l {Creating Tests}. - + \li Creates a \QC plugin. + \row + \li {1,6} Other Project + \li Qt Custom Designer Widget + \li Creates a custom \QD widget or widget collection. + \row \li Qt Quick UI Prototype - - Use a single QML file that contains the main view. You can - review \l{Creating Qt Quick UI Projects}{Qt Quick UI prototypes} - in a \l{Previewing QML Files}{preview tool} and you need not - build them. Qt Quick UI prototypes cannot be deployed to embedded - or mobile target platforms. For those platforms, create a - Qt Quick application instead. - - \li Qt Custom Designer Widgets - - Custom \QD widget or widget collection - - \li Empty qmake Project - - Empty qmake project that is based on qmake but does not use any - default classes - + \li Creates a \l{Creating Qt Quick UI Projects}{Qt Quick UI project} + with a single QML file that contains the main view. You can + preview Qt Quick 2 UI projects in the + \l{Validating with Target Hardware}{QML Scene preview tool}. + You do not need to build them, because they do not contain any + C++ code. + + Use this template only if you are prototyping. You cannot create + a full application by using this template. + + Qt Quick UI projects cannot be deployed to embedded or mobile + target platforms. For those platforms, create a Qt Quick + application instead. + \row + \li Auto Test Project + \li Creates a project with boilerplate code for a Qt or Google + test. For more information, see \l {Creating Tests}. + \row \li Subdirs Project - - Subprojects that enable you to structure your qmake projects as - a tree hierarchy - + \li Creates a subproject that enables you to structure your qmake + projects as a tree hierarchy. + \row + \li Empty qmake Project + \li Creates an empty qmake project that is based on qmake but does + not use any default classes. + \row \li Code Snippet - - Creates a qmake project from a code snippet. When fixing bug + \li Creates a qmake project from a code snippet. When fixing bug reports that contain a code snippet, you can place the code snippet into a project to compile and check it. - - \endlist - - \li Non-Qt Projects - - \list - - \li Plain C or C++ Application - - Plain C or C++ application that uses qmake, Qbs, or CMake but does - not use the Qt library - - \li Nim or Nimble Applications (experimental) - - Nim or Nimble application that uses Nimble, but does not use - the Qt library - - For more information, see \l {Setting Up Nimble}. - - \endlist - - \li Import Project - - \list - - \li Project from version control - - Import a project from a supported version control system. For more - information on how version control systems are integrated in - \QC, see \l{Using Version Control Systems} - - \li Import as qmake Project - - Import an existing project that does not use any of the supported - build systems: qmake, Qbs, CMake, or Autotools. The wizard creates - a qmake .pro file, which enables you to use \QC as a code editor and - as a launcher for debugging and analysis tools. However, if you want - to build the project, you might need to edit the generated .pro - file. - - \li Import Existing Project - - Import an existing project that does not use any of the supported - build systems: qmake, Qbs, CMake, or Autotools. This enables you to - use \QC as a code editor - - \endlist - - \endlist + \row + \li {1,4} Non-Qt Project + \li Plain C Application + \li Creates a plain C application that uses qmake, Qbs, or CMake + but does not use the Qt library. + \row + \li Plain C++ Application + \li Creates a plain C++ application that uses qmake, Qbs, or CMake + but does not use the Qt library. + \row + \li Nim Application (experimental) + \li Creates a Nim application that uses Nimble, but does not use the + Qt library. For more information, see \l {Setting Up Nimble}. + \row + \li Nimble Application (experimental) + \li Creates a Nimble application that uses Nimble, but does not use + the Qt library. For more information, see + \l {Setting Up Nimble}. + \row + \li {1,3} Import Project + \li Project from version control + \li Imports a project from a supported version control system, such + as Bazaar, CVS, Git, Mercurial, or Subversion. For + more information on how version control systems are integrated + in \QC, see \l{Using Version Control Systems}. + \row + \li Import as qmake or CMake Project (Limited Functionality) + \li Imports an existing project that does not use any of the + supported build systems: qmake, Qbs, CMake, or Autotools. The + template creates a project file, which enables you to use + \QC as a code editor and as a launcher for debugging and + analysis tools. However, if you want to build the project, + you might need to edit the generated project file. + \row + \li Import Existing Project + \li Imports an existing project that does not use any of the + supported build systems: qmake, Qbs, CMake, or Autotools. + This enables you to use \QC as a code editor. + \endtable To create a new project, select \uicontrol File > \uicontrol{New File or Project} and select the type of your project. The contents of the wizard dialogs depend @@ -278,93 +255,118 @@ \section1 Adding Files to Projects You can use wizards also to add individual files to your projects. - You can create the following types of files: - - \list - - \li C/C++ - - C or C++ source and header files - - \li Qt - - \list - - \li Qt item model source and header files that you can use to create - classes derived from QAbstractItemModel, QAbstractTableModel, or - QAbstractListModel. - - \li \QD forms and \QD form classes, which specify parts of user - interfaces in Qt widget based projects - - \li Qt resource files, which allow you to store binary files in the - application executable - - \li QML files, which specify items in Qt Quick projects. - \uicontrol {QML File (Qt Quick 2)} creates a QML file that imports - Qt Quick 2.0, and \uicontrol {Qt Quick UI File} creates a - \l{UI Files}{UI file} (\e .ui.qml) and the corresponding - implementation file (\e .qml). - - \li JavaScript files that you can use to write the application logic in - Qt Quick projects - - \endlist - - \li Models and state charts - - \list - - \li Universal Modeling Language (UML) style models with structured - diagrams. However, the model editor uses a variant of UML and + The following table lists the wizard templates for creating files. + + \table + \header + \li Category + \li Wizard Template + \li Purpose + \row + \li {1,3} C/C++ + \li C++ Class + \li C++ header and source file for a new class that you can add to + a C++ project. + \row + \li C/C++ Source File + \li C++ source file that you can add to a C++ project. + \row + \li C/C++ Header File + \li C++ header file that you can add to a C++ project. + \row + \li {1,3} Modeling + \li State Chart + \li State Chart XML (SCXML) file that contains boilerplate + code for state machines. You can use the classes in the + \l {Qt SCXML} module to embed state machines created from + the files in Qt applications. + \row + \li Model + \li Universal Modeling Language (UML) style model with a structured + diagram. However, the model editor uses a variant of UML and provides only a subset of properties for specifying the appearance of model elements. For more information, see \l {Modeling}. - - \li State Chart XML (SCXML) files that contain boilerplate code for - state machines. You can use the classes in the \l {Qt SCXML} - module to embed state machines created from the files in Qt - applications. - - \endlist - - \li GLSL - - GLSL files that define fragment and vertex shaders in both Qt Quick - projects and Qt widget based projects - - \li General - - \list - - \li Empty files - - \li Scratch buffers that use temporary files. You can create this - type of files for temporarily storing information that you do - not intend to save - - \endlist - - \li Java - - Java class files that you can use to create Java classes. - - \li Python - - Python class and source files that you can use to create Python - classes and scripts with UTF-8 encoding. - - \li Nim (experimental) - - \list - - \li Nim script files. - - \li Nim source files with UTF-8 encoding. - - \endlist - - \endlist + \row + \li Scratch Model + \li Scratch model using a temporary file. + \row + \li {1,7} Qt + \li Qt Item Model + \li Source and header files that you can use to create classes + derived from QAbstractItemModel, QAbstractTableModel, or + QAbstractListModel. + \row + \li \QD Form Class + \li \QD form and a matching class for implementing a UI based + on Qt widgets. + \row + \li \QD Form + \li \QD form for Qt widget based projects. This is useful + if you already have an existing class for the UI logic. + \row + \li Qt Resource File + \li Resource file for storing binary files in the application + executable. + \row + \li QML File (Qt Quick 2) + \li QML file that imports Qt Quick 2.0 for use in Qt Quick projects. + \row + \li Qt Quick UI File + \li \l{UI Files}{UI file} (\e .ui.qml) and the corresponding + implementation file (\e .qml) for use in Qt Quick projects. + \row + \li JS File + \li JavaScript file that you can use to write the application logic + in Qt Quick projects. + \row + \li {1,4} GLSL + \li Fragment Shader (OpenGL/ES 2.0) + \li Fragment shader that generates the final pixel colors for + triangles, points, and lines rendered with OpenGL. You can use + it in both Qt Quick projects and Qt widget based projects. + \row + \li Vertex Shader (OpenGL/ES 2.0) + \li Vertex shader that transforms the positions, normals, and + texture coordinates of triangles, points, and lines rendered + with OpenGL. You can use it in both Qt Quick projects and Qt + widget based projects. + \row + \li Fragment Shader (Desktop OpenGL) + \li Fragment shader for use in both Qt Quick projects and Qt + widget based projects. + \row + \li Vertex Shader (Desktop OpenGL) + \li Vertex shader for use in both Qt Quick projects and Qt + widget based projects. + \row + \li {1,2} General + \li Empty File + \li Empty file that you can save with any filename extensio. + \row + \li Scratch Buffer + \li Scratch buffer that uses temporary files. You can + create this type of files for temporarily storing information + that you do not intend to save + \row + \li Java + \li Java File + \li Java class files that you can use to create Java classes. + \row + \li {1,2} Python + \li Python Class + \li Python class file. + \row + \li Python File + \li Python script file using UTF-8 encoding. + \row + \li {1,2} Nim (experimental) + \li Nim Script File + \li Empty Nim script file using UTF-8 encoding. + \row + \li Nim File + \li Empty Nim source file using UTF-8 encoding. + \endtable \section2 Creating C++ Classes diff --git a/doc/qtcreator/src/qtcreator-toc.qdoc b/doc/qtcreator/src/qtcreator-toc.qdoc index dfb84f20f71..43396743138 100644 --- a/doc/qtcreator/src/qtcreator-toc.qdoc +++ b/doc/qtcreator/src/qtcreator-toc.qdoc @@ -132,6 +132,7 @@ \li \l{Animations} \li \l{3D Views} \li \l{Group} + \li \l{Skeletal Animation} \li \l{3D Models} \li \l{Materials and Shaders} \li \l{Textures} diff --git a/doc/qtcreator/src/qtquick/creator-only/qtquick-creating.qdoc b/doc/qtcreator/src/qtquick/creator-only/qtquick-creating.qdoc index 46f2b55b2e3..56c481dd7c5 100644 --- a/doc/qtcreator/src/qtquick/creator-only/qtquick-creating.qdoc +++ b/doc/qtcreator/src/qtquick/creator-only/qtquick-creating.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -38,55 +38,59 @@ \image qmldesigner-new-project.png "New File or Project dialog" - When you create a new Qt Quick project from scratch, you have the following - options: - - \list - \li \uicontrol {Application (Qt Quick)}: - - \list - - \li \uicontrol {Qt Quick Application - Empty} creates a Qt Quick 2 - application project that can contain both QML and C++ code. You can - build the application and deploy it to desktop, embedded, and mobile - target platforms. - - \li \uicontrol {Qt Quick Application - Scroll} uses the - \l{ScrollView} component to implement a scrollable list view - (requires Qt 5.9 or later). - - \li \uicontrol {Qt Quick Application - Stack} uses the - \l{StackView} component to implement a set of pages with a stack-based - navigation model (requires Qt 5.7 or later). - - \li \uicontrol {Qt Quick Application - Swipe} uses the - \l{SwipeView} component to implement a set of pages with a swipe-based - navigation model (requires Qt 5.7 or later). - - \endlist - - \li \uicontrol {Application (Qt for Python)} > - \uicontrol {Qt for Python - Qt Quick Application - Empty} creates a - Python project that contains an empty Qt Quick Application. - - \li \uicontrol {Other Project} > \uicontrol {Qt Quick UI Prototype} - creates a \l{Creating Qt Quick UI Projects}{Qt Quick UI project} - with a single QML file that - contains the main view. You can review Qt Quick 2 UI projects in the - \l{Previewing QML Files}{QML Scene preview tool}. You do not need to - build them, because they do not contain any C++ code. - Use this only if you are prototyping. You cannot create a full application - with this. - - Qt Quick UI projects cannot be deployed to embedded or mobile - target platforms. For those platforms, create a Qt Quick application - instead. - - \li \uicontrol Library > \uicontrol {Qt Quick 2 Extension Plugin} - creates C++ plugins that make it possible to offer extensions that - can be loaded dynamically into Qt Quick 2 applications. - - \endlist + The following table lists the wizard templates for creating a new + Qt Quick project from scratch. + + \table + \header + \li Category + \li Wizard Template + \li Purpose + \row + \li {1,4} Application (Qt Quick) + \li Qt Quick Application - Empty + \li Creates a Qt Quick 2 application project that can contain both + QML and C++ code. You can build the application and deploy it + to desktop, embedded, and mobile target platforms. + \row + \li Qt Quick Application - Scroll + \li Uses the \l{ScrollView} component to implement a scrollable + list view (requires Qt 5.9 or later). + \row + \li Qt Quick Application - Stack + \li Uses the \l{StackView} component to implement a set of pages + with a stack-based navigation model (requires Qt 5.7 or later). + \row + \li Qt Quick Application - Swipe + \li Uses the \l{SwipeView} component to implement a set of pages + with a swipe-based navigation model (requires Qt 5.7 or later). + \row + \li Application (Qt for Python) + \li Qt for Python - Qt Quick Application + \li Creates a Python project that contains an empty Qt Quick + Application. + \row + \li Other Project + \li Qt Quick UI Prototype + \li Creates a \l{Creating Qt Quick UI Projects}{Qt Quick UI project} + with a single QML file that contains the main view. You can + preview Qt Quick 2 UI projects in the + \l{Validating with Target Hardware}{QML Scene preview tool}. + You do not need to build them, because they do not contain any + C++ code. + + Use this template only if you are prototyping. You cannot create + a full application by using this template. + + Qt Quick UI projects cannot be deployed to embedded or mobile + target platforms. For those platforms, create a Qt Quick + application instead. + \row + \li Library + \li Qt Quick 2 Extension Plugin + \li Creates C++ plugins that make it possible to offer extensions + that can be loaded dynamically into Qt Quick 2 applications. + \endtable \note The SDK for a particular target platform might install additional templates for that platform. For example, the QNX templates are installed diff --git a/doc/qtcreator/src/qtquick/library/qtquick-preset-components.qdoc b/doc/qtcreator/src/qtquick/library/qtquick-preset-components.qdoc index d9ac4b9387f..68c1875c068 100644 --- a/doc/qtcreator/src/qtquick/library/qtquick-preset-components.qdoc +++ b/doc/qtcreator/src/qtquick/library/qtquick-preset-components.qdoc @@ -70,6 +70,7 @@ \list \li \l {3D Views} \li \l {Group} + \li \l {Skeletal Animation} \li \l {3D Models} \li \l {Materials and Shaders} \li \l {Textures} diff --git a/doc/qtcreator/src/qtquick/qtquick-library.qdoc b/doc/qtcreator/src/qtquick/qtquick-library.qdoc index 8dc9c3c44a7..ae206f3e4fd 100644 --- a/doc/qtcreator/src/qtquick/qtquick-library.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-library.qdoc @@ -71,6 +71,7 @@ \li \l Animations \li \l{3D Views} \li \l{Group} + \li \l{Skeletal Animation} \li \l{3D Models} \li \l{Materials and Shaders} \li \l{Textures} diff --git a/doc/qtcreator/src/qtquick/qtquick-positioning.qdoc b/doc/qtcreator/src/qtquick/qtquick-positioning.qdoc index 3dc0d3cbe6a..1076e7a3746 100644 --- a/doc/qtcreator/src/qtquick/qtquick-positioning.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-positioning.qdoc @@ -195,15 +195,32 @@ \uicontrol {Distribute spacing} field to determine whether it is distributed evenly within a target area or at specified distances, calculated from a starting point. - You can select the orientation in which the components are distributed evenly within the target area: horizontally along the x axis or vertically along the y axis. Alternatively, you can distribute spacing in pixels by selecting one of the - starting point buttons: top-left or bottom-right edge of the target area, - or its center. Note that some components might end up outside the target - area. + starting point buttons: top/left or bottom/right edge of the target area or + item, or its center. The edge to use depends on whether the items are + distributed horizontally or vertically: + + \list + \li Select \inlineimage icons/distribute-origin-top-left.png + and \inlineimage icons/distribute-spacing-horizontal.png + to use the left edge of the target area or item as the starting + point. + \li Select \inlineimage icons/distribute-origin-top-left.png + and \inlineimage icons/distribute-spacing-vertical.png + to use the top edge. + \li Select \inlineimage icons/distribute-origin-bottom-right.png + and \inlineimage icons/distribute-spacing-horizontal.png + to use the right edge. + \li Select \inlineimage icons/distribute-origin-bottom-right.png + and \inlineimage icons/distribute-spacing-vertical.png + to use the bottom edge. + \endlist + + \note Some components might end up outside the target area. In the \uicontrol {Pixel spacing} field, you can set the space between components in pixels. You can disable the distribution of spacing in @@ -273,16 +290,18 @@ \li Disables the distribution of spacing in pixels. \row \li \inlineimage icons/distribute-origin-top-left.png - \li Sets the top-left corner of the target area as the starting point - for distributing spacing in pixels. + \li Sets the top or left edge of the target area or item as the + starting point for distributing spacing in pixels depending on + the distribution orientation. \row \li \inlineimage icons/distribute-origin-center.png \li Sets the center of the target area as the starting point for distributing spacing in pixels. \row \li \inlineimage icons/distribute-origin-bottom-right.png - \li Sets the bottom-right corner of the target area as the starting - point for distributing spacing in pixels. + \li Sets the bottom or right edge of the target area or item as the + starting point for distributing spacing in pixels, depending on + the distribution orientation. \endtable \section2 Using Positioners diff --git a/doc/qtcreatordev/examples/exampleplugin/.github/workflows/README.md b/doc/qtcreatordev/examples/exampleplugin/.github/workflows/README.md new file mode 100644 index 00000000000..107410c6ec3 --- /dev/null +++ b/doc/qtcreatordev/examples/exampleplugin/.github/workflows/README.md @@ -0,0 +1,41 @@ +# GitHub Actions & Workflows + +The `build_cmake.yml` in this directory adds a [GitHub action][1] and workflow that builds +your plugin anytime you push commits to GitHub on Windows, Linux and macOS. + +The build artifacts can be downloaded from GitHub and be installed into an existing Qt Creator +installation. + +When you push a tag, the workflow also creates a new release on GitHub. + +## Keeping it up to date + +Near the top of the file you find a section starting with `env:`. + +The value for `QT_VERSION` specifies the Qt version to use for building the plugin. + +The value for `QT_CREATOR_VERSION` specifies the Qt Creator version to use for building the plugin. + +The value for `QT_CREATOR_SNAPSHOT` can either be `NO` or `latest` or the build ID of a specific +snapshot build for the Qt Creator version that you specified. + +You need to keep these values updated for different versions of your plugin, and take care +that the Qt version and Qt Creator version you specify are compatible. + +## What it does + +The build job consists of several steps: + +* Install required packages on the build host +* Download, unpack and install the binary for the Qt version +* Download and unpack the binary for the Qt Creator version +* Build the plugin and upload the plugin libraries to GitHub +* If a tag is pushed, create a release on GitHub for the tag, including zipped plugin libraries + for download + +## Limitations + +If your plugin requires additional resources besides the plugin library, you need to adapt the +script accordingly. + +[1]: https://help.github.com/en/actions/automating-your-workflow-with-github-actions/about-github-actions diff --git a/doc/qtcreatordev/examples/exampleplugin/.github/workflows/build_cmake.yml b/doc/qtcreatordev/examples/exampleplugin/.github/workflows/build_cmake.yml new file mode 100644 index 00000000000..97471b308a9 --- /dev/null +++ b/doc/qtcreatordev/examples/exampleplugin/.github/workflows/build_cmake.yml @@ -0,0 +1,322 @@ +name: Build plugin + +on: [push] + +env: + PLUGIN_NAME: Example + QT_VERSION: 6.2.0 + QT_CREATOR_VERSION: 5.0.0 + QT_CREATOR_SNAPSHOT: NO + CMAKE_VERSION: 3.18.3 + NINJA_VERSION: 1.10.1 + +jobs: + build: + name: ${{ matrix.config.name }} + runs-on: ${{ matrix.config.os }} + strategy: + matrix: + config: + - { + name: "Windows Latest MSVC", artifact: "Windows-x64", + os: windows-latest, + cc: "cl", cxx: "cl", + environment_script: "C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat", + } + - { + name: "Ubuntu Latest GCC", artifact: "Linux-x64", + os: ubuntu-latest, + cc: "gcc", cxx: "g++" + } + - { + name: "macOS Latest Clang", artifact: "macOS-x64", + os: macos-latest, + cc: "clang", cxx: "clang++" + } + + steps: + - uses: actions/checkout@v1 + + - name: Download Ninja and CMake + shell: cmake -P {0} + run: | + set(cmake_version "$ENV{CMAKE_VERSION}") + set(ninja_version "$ENV{NINJA_VERSION}") + + if ("${{ runner.os }}" STREQUAL "Windows") + set(ninja_suffix "win.zip") + set(cmake_suffix "win64-x64.zip") + set(cmake_dir "cmake-${cmake_version}-win64-x64/bin") + elseif ("${{ runner.os }}" STREQUAL "Linux") + set(ninja_suffix "linux.zip") + set(cmake_suffix "Linux-x86_64.tar.gz") + set(cmake_dir "cmake-${cmake_version}-Linux-x86_64/bin") + elseif ("${{ runner.os }}" STREQUAL "macOS") + set(ninja_suffix "mac.zip") + set(cmake_suffix "Darwin-x86_64.tar.gz") + set(cmake_dir "cmake-${cmake_version}-Darwin-x86_64/CMake.app/Contents/bin") + endif() + + set(ninja_url "https://github.com/ninja-build/ninja/releases/download/v${ninja_version}/ninja-${ninja_suffix}") + file(DOWNLOAD "${ninja_url}" ./ninja.zip SHOW_PROGRESS) + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./ninja.zip) + + set(cmake_url "https://github.com/Kitware/CMake/releases/download/v${cmake_version}/cmake-${cmake_version}-${cmake_suffix}") + file(DOWNLOAD "${cmake_url}" ./cmake.zip SHOW_PROGRESS) + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ./cmake.zip) + + # Add to PATH environment variable + file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/${cmake_dir}" cmake_dir) + set(path_separator ":") + if ("${{ runner.os }}" STREQUAL "Windows") + set(path_separator ";") + endif() + file(APPEND "$ENV{GITHUB_PATH}" "$ENV{GITHUB_WORKSPACE}${path_separator}${cmake_dir}") + + if (NOT "${{ runner.os }}" STREQUAL "Windows") + execute_process( + COMMAND chmod +x ninja + COMMAND chmod +x ${cmake_dir}/cmake + ) + endif() + + - name: Install system libs + shell: cmake -P {0} + run: | + if ("${{ runner.os }}" STREQUAL "Linux") + execute_process( + COMMAND sudo apt update + ) + execute_process( + COMMAND sudo apt install libgl1-mesa-dev + RESULT_VARIABLE result + ) + if (NOT result EQUAL 0) + message(FATAL_ERROR "Failed to install dependencies") + endif() + endif() + + - name: Download Qt + id: qt + shell: cmake -P {0} + run: | + set(qt_version "$ENV{QT_VERSION}") + + string(REPLACE "." "" qt_version_dotless "${qt_version}") + if ("${{ runner.os }}" STREQUAL "Windows") + set(url_os "windows_x86") + set(qt_package_arch_suffix "win64_msvc2019_64") + set(qt_dir_prefix "${qt_version}/msvc2019_64") + set(qt_package_suffix "-Windows-Windows_10-MSVC2019-Windows-Windows_10-X86_64") + elseif ("${{ runner.os }}" STREQUAL "Linux") + set(url_os "linux_x64") + set(qt_package_arch_suffix "gcc_64") + set(qt_dir_prefix "${qt_version}/gcc_64") + set(qt_package_suffix "-Linux-RHEL_7_6-GCC-Linux-RHEL_7_6-X86_64") + elseif ("${{ runner.os }}" STREQUAL "macOS") + set(url_os "mac_x64") + set(qt_package_arch_suffix "clang_64") + set(qt_dir_prefix "${qt_version}/clang_64") + set(qt_package_suffix "-MacOS-MacOS_10_13-Clang-MacOS-MacOS_10_13-X86_64") + endif() + + set(qt_base_url "https://download.qt.io/online/qtsdkrepository/${url_os}/desktop/qt5_${qt_version_dotless}") + file(DOWNLOAD "${qt_base_url}/Updates.xml" ./Updates.xml SHOW_PROGRESS) + + file(READ ./Updates.xml updates_xml) + string(REGEX MATCH "<Name>qt.qt5.*<Version>([0-9+-.]+)</Version>" updates_xml_output "${updates_xml}") + set(qt_package_version ${CMAKE_MATCH_1}) + + file(MAKE_DIRECTORY qt5) + + # Save the path for other steps + file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qt5/${qt_dir_prefix}" qt_dir) + message("::set-output name=qt_dir::${qt_dir}") + + message("Downloading Qt to ${qt_dir}") + function(downloadAndExtract url archive) + message("Downloading ${url}") + file(DOWNLOAD "${url}" ./${archive} SHOW_PROGRESS) + execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ../${archive} WORKING_DIRECTORY qt5) + endfunction() + + foreach(package qtbase qtdeclarative) + downloadAndExtract( + "${qt_base_url}/qt.qt5.${qt_version_dotless}.${qt_package_arch_suffix}/${qt_package_version}${package}${qt_package_suffix}.7z" + ${package}.7z + ) + endforeach() + + # uic depends on libicu56.so + if ("${{ runner.os }}" STREQUAL "Linux") + downloadAndExtract( + "${qt_base_url}/qt.qt5.${qt_version_dotless}.${qt_package_arch_suffix}/${qt_package_version}icu-linux-Rhel7.2-x64.7z" + icu.7z + ) + endif() + + - name: Download Qt Creator + id: qt_creator + shell: cmake -P {0} + run: | + string(REGEX MATCH "([0-9]+.[0-9]+).[0-9]+" outvar "$ENV{QT_CREATOR_VERSION}") + + set(qtc_base_url "https://download.qt.io/official_releases/qtcreator/${CMAKE_MATCH_1}/$ENV{QT_CREATOR_VERSION}/installer_source") + set(qtc_snapshot "$ENV{QT_CREATOR_SNAPSHOT}") + if (qtc_snapshot) + set(qtc_base_url "https://download.qt.io/snapshots/qtcreator/${CMAKE_MATCH_1}/$ENV{QT_CREATOR_VERSION}/installer_source/${qtc_snapshot}") + endif() + + if ("${{ runner.os }}" STREQUAL "Windows") + set(qtc_platform "windows_x64") + elseif ("${{ runner.os }}" STREQUAL "Linux") + set(qtc_platform "linux_x64") + elseif ("${{ runner.os }}" STREQUAL "macOS") + set(qtc_platform "mac_x64") + endif() + + file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qtcreator" qtc_dir) + # Save the path for other steps + message("::set-output name=qtc_dir::${qtc_dir}") + + file(MAKE_DIRECTORY qtcreator) + + message("Downloading Qt Creator from ${qtc_base_url}/${qtc_platform}") + + foreach(package qtcreator qtcreator_dev) + file(DOWNLOAD + "${qtc_base_url}/${qtc_platform}/${package}.7z" ./${package}.7z SHOW_PROGRESS) + execute_process(COMMAND + ${CMAKE_COMMAND} -E tar xvf ../${package}.7z WORKING_DIRECTORY qtcreator) + endforeach() + + - name: Build + shell: cmake -P {0} + run: | + set(ENV{CC} ${{ matrix.config.cc }}) + set(ENV{CXX} ${{ matrix.config.cxx }}) + set(ENV{MACOSX_DEPLOYMENT_TARGET} "10.13") + + if ("${{ runner.os }}" STREQUAL "Windows" AND NOT "x${{ matrix.config.environment_script }}" STREQUAL "x") + execute_process( + COMMAND "${{ matrix.config.environment_script }}" && set + OUTPUT_FILE environment_script_output.txt + ) + file(STRINGS environment_script_output.txt output_lines) + foreach(line IN LISTS output_lines) + if (line MATCHES "^([a-zA-Z0-9_-]+)=(.*)$") + set(ENV{${CMAKE_MATCH_1}} "${CMAKE_MATCH_2}") + endif() + endforeach() + endif() + + set(ENV{NINJA_STATUS} "[%f/%t %o/sec] ") + + set(build_plugin_py "scripts/build_plugin.py") + foreach(dir "share/qtcreator/scripts" "Qt Creator.app/Contents/Resources/scripts" "Contents/Resources/scripts") + if(EXISTS "${{ steps.qt_creator.outputs.qtc_dir }}/${dir}/build_plugin.py") + set(build_plugin_py "${dir}/build_plugin.py") + break() + endif() + endforeach() + + execute_process( + COMMAND python + -u + "${{ steps.qt_creator.outputs.qtc_dir }}/${build_plugin_py}" + --name "$ENV{PLUGIN_NAME}-$ENV{QT_CREATOR_VERSION}-${{ matrix.config.artifact }}" + --src . + --build build + --qt-path "${{ steps.qt.outputs.qt_dir }}" + --qtc-path "${{ steps.qt_creator.outputs.qtc_dir }}" + --output-path "$ENV{GITHUB_WORKSPACE}" + RESULT_VARIABLE result + ) + if (NOT result EQUAL 0) + string(REGEX MATCH "FAILED:.*$" error_message "${output}") + string(REPLACE "\n" "%0A" error_message "${error_message}") + message("::error::${error_message}") + message(FATAL_ERROR "Build failed") + endif() + + - uses: actions/upload-artifact@v2 + id: upload_artifact + with: + path: ./${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}.7z + name: ${{ env.PLUGIN_NAME}}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }}.7z + + release: + if: contains(github.ref, 'tags/v') + runs-on: ubuntu-latest + needs: build + + steps: + - name: Create Release + id: create_release + uses: actions/[email protected] + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + draft: false + prerelease: false + + - name: Store Release url + run: | + echo "${{ steps.create_release.outputs.upload_url }}" > ./upload_url + + - uses: actions/upload-artifact@v1 + with: + path: ./upload_url + name: upload_url + + publish: + if: contains(github.ref, 'tags/v') + + name: ${{ matrix.config.name }} + runs-on: ${{ matrix.config.os }} + strategy: + matrix: + config: + - { + name: "Windows Latest x64", artifact: "Windows-x64.7z", + os: ubuntu-latest + } + - { + name: "Linux Latest x64", artifact: "Linux-x64.7z", + os: ubuntu-latest + } + - { + name: "macOS Latest x64", artifact: "macOS-x64.7z", + os: macos-latest + } + needs: release + + steps: + - name: Download artifact + uses: actions/download-artifact@v1 + with: + name: ${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }} + path: ./ + + - name: Download URL + uses: actions/download-artifact@v1 + with: + name: upload_url + path: ./ + - id: set_upload_url + run: | + upload_url=`cat ./upload_url` + echo ::set-output name=upload_url::$upload_url + + - name: Upload to Release + id: upload_to_release + uses: actions/[email protected] + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.set_upload_url.outputs.upload_url }} + asset_path: ./${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }} + asset_name: ${{ env.PLUGIN_NAME }}-${{ env.QT_CREATOR_VERSION }}-${{ matrix.config.artifact }} + asset_content_type: application/x-7z-compressed diff --git a/doc/qtcreatordev/examples/exampleplugin/.gitignore b/doc/qtcreatordev/examples/exampleplugin/.gitignore new file mode 100644 index 00000000000..fab7372d796 --- /dev/null +++ b/doc/qtcreatordev/examples/exampleplugin/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/doc/qtcreatordev/examples/exampleplugin/CMakeLists.txt b/doc/qtcreatordev/examples/exampleplugin/CMakeLists.txt new file mode 100644 index 00000000000..69df3ec4da7 --- /dev/null +++ b/doc/qtcreatordev/examples/exampleplugin/CMakeLists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.10) + +#! [1] +# Remove when sharing with others. +list(APPEND CMAKE_PREFIX_PATH "/Users/example/qt-creator/build") +#! [1] + +#! [2] +project(Example) + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) +set(CMAKE_AUTOUIC ON) +set(CMAKE_CXX_STANDARD 17) +#! [2] + +#! [3] +find_package(QtCreator COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED) +set(QtX Qt${QT_VERSION_MAJOR}) +#! [3] + +#! [4] +add_qtc_plugin(Example + PLUGIN_DEPENDS + QtCreator::Core + DEPENDS + ${QtX}::Widgets + QtCreator::ExtensionSystem + QtCreator::Utils + SOURCES + .github/workflows/build_cmake.yml + .github/workflows/README.md + README.md + example.cpp + example.h + example_global.h + exampleconstants.h +) +#! [4] diff --git a/doc/qtcreatordev/examples/exampleplugin/Example.json.in b/doc/qtcreatordev/examples/exampleplugin/Example.json.in index 12b8bc37a0e..3a52e318c55 100644 --- a/doc/qtcreatordev/examples/exampleplugin/Example.json.in +++ b/doc/qtcreatordev/examples/exampleplugin/Example.json.in @@ -5,12 +5,11 @@ \"CompatVersion\" : \"0.0.1\", //! [1] //! [2] - \"Vendor\" : \"My Company\", - \"Copyright\" : \"(C) My Company\", - \"License\" : \"BSD\", - \"Category\" : \"Examples\", - \"Description\" : \"Minimal plugin example.\", - \"Url\" : \"http://www.mycompany.com\", + \"Vendor\" : \"MyCompany\", + \"Copyright\" : \"(C) MyCompany\", + \"License\" : \"Put short license information here\", + \"Description\" : \"Put a short description of your plugin here\", + \"Url\" : \"https://www.mycompany.com\", //! [2] //! [3] $$dependencyList diff --git a/doc/qtcreatordev/examples/exampleplugin/README.md b/doc/qtcreatordev/examples/exampleplugin/README.md new file mode 100644 index 00000000000..bcb70958c7f --- /dev/null +++ b/doc/qtcreatordev/examples/exampleplugin/README.md @@ -0,0 +1,36 @@ +# Example + +## How to Build + +Create a build directory and run + + cmake -DCMAKE_PREFIX_PATH=<path_to_qtcreator> -DCMAKE_BUILD_TYPE=RelWithDebInfo <path_to_plugin_source> + cmake --build . + +where `<path_to_qtcreator>` is the relative or absolute path to a Qt Creator build directory, or to a +combined binary and development package (Windows / Linux), or to the `Qt Creator.app/Contents/Resources/` +directory of a combined binary and development package (macOS), and `<path_to_plugin_source>` is the +relative or absolute path to this plugin directory. + +## How to Run + +Run a compatible Qt Creator with the additional command line argument + + -pluginpath <path_to_plugin> + +where `<path_to_plugin>` is the path to the resulting plugin library in the build directory +(`<plugin_build>/lib/qtcreator/plugins` on Windows and Linux, +`<plugin_build>/Qt Creator.app/Contents/PlugIns` on macOS). + +You might want to add `-temporarycleansettings` (or `-tcs`) to ensure that the opened Qt Creator +instance cannot mess with your user-global Qt Creator settings. + +When building and running the plugin from Qt Creator, you can use + + -pluginpath "%{buildDir}/lib/qtcreator/plugins" -tcs + +on Windows and Linux, or + + -pluginpath "%{buildDir}/Qt Creator.app/Contents/PlugIns" -tcs + +for the `Command line arguments` field in the run settings. diff --git a/doc/qtcreatordev/examples/exampleplugin/exampleplugin.cpp b/doc/qtcreatordev/examples/exampleplugin/example.cpp index 5adc093c46d..f001fad5119 100644 --- a/doc/qtcreatordev/examples/exampleplugin/exampleplugin.cpp +++ b/doc/qtcreatordev/examples/exampleplugin/example.cpp @@ -1,4 +1,4 @@ -#include "exampleplugin.h" +#include "example.h" #include "exampleconstants.h" #include <coreplugin/icore.h> @@ -13,8 +13,6 @@ #include <QMainWindow> #include <QMenu> -#include <QtPlugin> - namespace Example { namespace Internal { @@ -42,9 +40,9 @@ bool ExamplePlugin::initialize(const QStringList &arguments, QString *errorStrin Q_UNUSED(errorString) //! [add action] - QAction *action = new QAction(tr("Example Action"), this); + auto action = new QAction(tr("Example Action"), this); Core::Command *cmd = Core::ActionManager::registerAction(action, Constants::ACTION_ID, - Core::Context(Core::Constants::C_GLOBAL)); + Core::Context(Core::Constants::C_GLOBAL)); cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Meta+A"))); connect(action, &QAction::triggered, this, &ExamplePlugin::triggerAction); //! [add action] diff --git a/doc/qtcreatordev/examples/exampleplugin/exampleplugin.h b/doc/qtcreatordev/examples/exampleplugin/example.h index e858e92180d..e858e92180d 100644 --- a/doc/qtcreatordev/examples/exampleplugin/exampleplugin.h +++ b/doc/qtcreatordev/examples/exampleplugin/example.h diff --git a/doc/qtcreatordev/examples/exampleplugin/example.pro b/doc/qtcreatordev/examples/exampleplugin/example.pro deleted file mode 100644 index c100894b7ba..00000000000 --- a/doc/qtcreatordev/examples/exampleplugin/example.pro +++ /dev/null @@ -1,59 +0,0 @@ -#! [1] -DEFINES += EXAMPLE_LIBRARY -#! [1] - -# Example files - -#! [2] -SOURCES += exampleplugin.cpp - -HEADERS += exampleplugin.h \ - example_global.h \ - exampleconstants.h -#! [2] - -# Qt Creator linking - -#! [3] -## set the QTC_SOURCE environment variable to override the setting here -QTCREATOR_SOURCES = $$(QTC_SOURCE) -isEmpty(QTCREATOR_SOURCES):QTCREATOR_SOURCES=/Users/example/qtcreator-src - -## set the QTC_BUILD environment variable to override the setting here -IDE_BUILD_TREE = $$(QTC_BUILD) -isEmpty(IDE_BUILD_TREE):IDE_BUILD_TREE=/Users/example/qtcreator-build -#! [3] - -#! [4] -## uncomment to build plugin into user config directory -## <localappdata>/plugins/<ideversion> -## where <localappdata> is e.g. -## "%LOCALAPPDATA%\QtProject\qtcreator" on Windows Vista and later -## "$XDG_DATA_HOME/data/QtProject/qtcreator" or "~/.local/share/data/QtProject/qtcreator" on Linux -## "~/Library/Application Support/QtProject/Qt Creator" on Mac -# USE_USER_DESTDIR = yes -#! [4] - -#! [5] -###### If the plugin can be depended upon by other plugins, this code needs to be outsourced to -###### <dirname>_dependencies.pri, where <dirname> is the name of the directory containing the -###### plugin's sources. - -QTC_PLUGIN_NAME = Example -QTC_LIB_DEPENDS += \ - # nothing here at this time - -QTC_PLUGIN_DEPENDS += \ - coreplugin - -QTC_PLUGIN_RECOMMENDS += \ - # optional plugin dependencies. nothing here at this time - -###### End _dependencies.pri contents ###### -#! [5] - -#![6] -include($$QTCREATOR_SOURCES/src/qtcreatorplugin.pri) - -#![6] - diff --git a/doc/qtcreatordev/examples/exampleplugin/example_global.h b/doc/qtcreatordev/examples/exampleplugin/example_global.h index 00c77e6b162..a1bab3f9091 100644 --- a/doc/qtcreatordev/examples/exampleplugin/example_global.h +++ b/doc/qtcreatordev/examples/exampleplugin/example_global.h @@ -1,9 +1,32 @@ -#pragma once +/**************************************************************************** +** +** Copyright (C) 2021 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. +** +****************************************************************************/ -#include <QtGlobal> +#pragma once #if defined(EXAMPLE_LIBRARY) -# define EXAMPLESHARED_EXPORT Q_DECL_EXPORT +# define EXAMPLE_EXPORT Q_DECL_EXPORT #else -# define EXAMPLESHARED_EXPORT Q_DECL_IMPORT +# define EXAMPLE_EXPORT Q_DECL_IMPORT #endif diff --git a/doc/qtcreatordev/examples/exampleplugin/exampleconstants.h b/doc/qtcreatordev/examples/exampleplugin/exampleconstants.h index fced2e04295..c5068d94bb6 100644 --- a/doc/qtcreatordev/examples/exampleplugin/exampleconstants.h +++ b/doc/qtcreatordev/examples/exampleplugin/exampleconstants.h @@ -1,3 +1,28 @@ +/**************************************************************************** +** +** Copyright (C) 2021 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 namespace Example { @@ -6,5 +31,6 @@ namespace Constants { const char ACTION_ID[] = "Example.Action"; const char MENU_ID[] = "Example.Menu"; -} // namespace Example } // namespace Constants +} // namespace Example + diff --git a/doc/qtcreatordev/images/firstplugin-kitselection.png b/doc/qtcreatordev/images/firstplugin-kitselection.png Binary files differindex 492142c0d7f..1e18114b580 100644 --- a/doc/qtcreatordev/images/firstplugin-kitselection.png +++ b/doc/qtcreatordev/images/firstplugin-kitselection.png diff --git a/doc/qtcreatordev/images/firstplugin-nameandpath.png b/doc/qtcreatordev/images/firstplugin-nameandpath.png Binary files differindex 77942826716..9faad8c08ff 100644 --- a/doc/qtcreatordev/images/firstplugin-nameandpath.png +++ b/doc/qtcreatordev/images/firstplugin-nameandpath.png diff --git a/doc/qtcreatordev/images/firstplugin-pluginsetup.png b/doc/qtcreatordev/images/firstplugin-pluginsetup.png Binary files differindex 273ef3b8b84..019bfa58ecc 100644 --- a/doc/qtcreatordev/images/firstplugin-pluginsetup.png +++ b/doc/qtcreatordev/images/firstplugin-pluginsetup.png diff --git a/doc/qtcreatordev/images/firstplugin-runsettings.png b/doc/qtcreatordev/images/firstplugin-runsettings.png Binary files differindex e2b5870282d..e2d13ad28c6 100644 --- a/doc/qtcreatordev/images/firstplugin-runsettings.png +++ b/doc/qtcreatordev/images/firstplugin-runsettings.png diff --git a/doc/qtcreatordev/images/firstplugin-summary.png b/doc/qtcreatordev/images/firstplugin-summary.png Binary files differindex c4670a07acc..88ad782030c 100644 --- a/doc/qtcreatordev/images/firstplugin-summary.png +++ b/doc/qtcreatordev/images/firstplugin-summary.png diff --git a/doc/qtcreatordev/images/firstplugin-translation-file.png b/doc/qtcreatordev/images/firstplugin-translation-file.png Binary files differindex 296367f6d94..bb8a1a3c9b8 100644 --- a/doc/qtcreatordev/images/firstplugin-translation-file.png +++ b/doc/qtcreatordev/images/firstplugin-translation-file.png diff --git a/doc/qtcreatordev/images/firstplugin-wizard.png b/doc/qtcreatordev/images/firstplugin-wizard.png Binary files differindex 5a888583142..f214f92b466 100644 --- a/doc/qtcreatordev/images/firstplugin-wizard.png +++ b/doc/qtcreatordev/images/firstplugin-wizard.png diff --git a/doc/qtcreatordev/src/coding-style.qdoc b/doc/qtcreatordev/src/coding-style.qdoc index 6b87163baf5..19adf253d90 100644 --- a/doc/qtcreatordev/src/coding-style.qdoc +++ b/doc/qtcreatordev/src/coding-style.qdoc @@ -983,7 +983,7 @@ \li \c{#include <stdthing>} \li \c{#include <system.h>} \endlist - \li Enclose headers from other plugins in square brackets (<>) rather than + \li Enclose headers from other plugins in angle brackets (<>) rather than quotation marks ("") to make it easier to spot external dependencies in the sources. \li Add empty lines between long blocks of \e peer headers and try to diff --git a/doc/qtcreatordev/src/first-plugin.qdoc b/doc/qtcreatordev/src/first-plugin.qdoc index 642fecb0c83..9b347facc35 100644 --- a/doc/qtcreatordev/src/first-plugin.qdoc +++ b/doc/qtcreatordev/src/first-plugin.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2020 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -61,9 +61,8 @@ \li Give your project a name and specify in which path this project will be created. The actual plugin's name can be different from the project name. You will choose that name later in the wizard. - Continue to the next page. - The \uicontrol {Plugin Information} dialog opens. + \li Continue to the \uicontrol {Plugin Information} dialog. \image firstplugin-pluginsetup.png "Specify Your Plugin Details" @@ -74,7 +73,7 @@ \li The values of the following fields are mainly informational, and are shown in the detailed view in \QC's plugin overview (\uicontrol Help > \uicontrol {About Plugins}, or - \uicontrol {Qt Creator} > \uicontrol {About Plugins} on Mac). + \uicontrol {\QC} > \uicontrol {About Plugins} on \macos). \list \li \uicontrol {Vendor name} is a short one-word name of the @@ -94,33 +93,19 @@ it. \endlist - \li Set the \uicontrol {Qt Creator sources} and - \uicontrol{Qt Creator build} fields to the source and build - directory of the \QC instance you want to use to test your plugin - with, respectively. If you don't do that correctly you will get - compile errors for your plugin, and your plugin might not show up in - \QC at all. - - \li In the \uicontrol {Deploy into} list, select - \uicontrol {Qt Creator build}. This sets your \c {.pro} file up to - deploy your plugin directly into your \QC build's plugin directory - (requires you to have write permissions there). The other option, - \uicontrol {Local user settings}, sets your \c {.pro} file up to - deploy your plugin into \QC's user plugin path (for example - \c {~/.config/QtProject/qtcreator/plugins} on Unix systems). We - choose \uicontrol {Qt Creator build} because we use a self-compiled - \QC, and want the plugin to be only loaded by that \QC - instance. Continue to the next page. - - The \uicontrol {Translation File} dialog opens. + \li Set the \uicontrol{\QC build} field to the build directory + of the \QC instance you want to use to test your plugin with. If + you don't do that correctly, you will get compile errors for your + plugin, and your plugin might not show up in \QC at all. + + \li Continue to the \uicontrol {Translation File} dialog. \image firstplugin-translation-file.png "Choose a language to localize your plugin to" \li Select a language to localize your plugin to. This sets up - translation support for the selected language. Continue to the - next page. + translation support for the selected language. - The \uicontrol {Kit Selection} dialog opens. + \li Continue to the \uicontrol {Kit Selection} dialog. \image firstplugin-kitselection.png "Choose the kit to build and run your project with" @@ -129,9 +114,9 @@ version that is compatible with the Qt version that your \QC was built with (in the best case the exact same build). If you use an incompatible Qt version to build your plugin, you will get errors - while \QC tries to load your plugin. Continue to the next page. + while \QC tries to load your plugin. - The \uicontrol {Project Management} dialog opens. + \li Continue to the \uicontrol {Project Management} dialog. \image firstplugin-summary.png "Summary of Created Files" @@ -142,7 +127,7 @@ \section1 Building and Running the Plugin - If you passed the correct \QC source and build paths in the project wizard, + If you passed the correct \QC build path in the project wizard, your plugin should just build fine when pressing the build button. Before running the project, select \uicontrol {Build & Run} > \uicontrol Run to specify run settings: @@ -150,9 +135,12 @@ \image firstplugin-runsettings.png "Specify the Executable to Run" Select the path to the \QC executable from the build that you specified in - the \uicontrol {Qt Creator build} setting in the project wizard and click - \uicontrol OK. \QC starts up, and you can verify that your plugin - successfully loaded by looking for a menu entry \uicontrol Tools > + the \uicontrol {\QC build} field in the project wizard and set the value + of the \uicontrol {Command line arguments} field to + \c {-pluginpath %{buildDir}}. + + When you click \uicontrol OK, \QC starts up, and you can verify that your + plugin is successfully loaded by looking for a menu entry \uicontrol Tools > \uicontrol Example and by looking for the plugin in the \uicontrol Help > \uicontrol {About Plugins} dialog. @@ -168,16 +156,19 @@ \li Role \row + \li \c {README.md} + + \li Describes how to build and run the plugin. + \row \li \c {Example.json.in} - \li Plugin meta data template. QMake creates an \c {Example.json} + \li Plugin meta data template. CMake creates an \c {Example.json} from this file, which is compiled into the plugin as meta data. The meta data is read by \QC to find out about the plugin. \row - \li \c {example.pro} + \li \c {CMakeLists.txt} - \li Project file, used by QMake to generate a Makefile that then is used to - build the plugin. + \li Project file, used by CMake to generate build files and build the plugin. \row \li \c {example_global.h} @@ -193,7 +184,7 @@ \li C++ header and source files that define the plugin class that will be instantiated and run by \QC's plugin manager. \row - \li \c{build_qmake.yml} + \li \c{build_cmake.yml} \li Adds a \l {https://help.github.com/en/actions/automating-your-workflow-with-github-actions/about-github-actions} @@ -202,71 +193,61 @@ information, see \c {.github\workflow\README.md}. \endtable - \section1 qmake Project + \section1 CMake Project - The qmake project file \c {example.pro} defines how your plugin should be + The CMake project file \c {CMakeLists.txt} defines how your plugin should be compiled. \QC plugins need to have a specific setup there, in addition to - telling qmake which files need to be compiled (or handled by \c moc or + telling CMake which files need to be compiled (or handled by \c moc or \c uic). Let us have a look at what the project wizard generated for you in detail. - \snippet exampleplugin/example.pro 1 - - The first section of the .pro file lets the compiler pass an - \c EXAMPLE_LIBRARY define to the compiled code, which is used in the - \c {example_global.h} header, but is not really of interest for now. You - should not need to change that section of the \c {.pro} file. - - \snippet exampleplugin/example.pro 2 + \snippet exampleplugin/CMakeLists.txt 1 - This section tells qmake about the files of your project that it should let - compile or otherwise handle. You need to expand that section with any files - you add to the project. + The \c{list(APPEND ...)} call tells CMake to include the \QC build path that + you specified in the wizard in its search path for dependencies. Since this + contains an absolute path on your local machine, you should remove this line + when sharing the project with others. - \snippet exampleplugin/example.pro 3 + Without this line, you need to explicitly add the path to the \QC + build to \c {CMAKE_PREFIX_PATH} when configuring your plugin with CMake. - To compile and deploy your plugin, the project needs access to the \QC - sources and build. This section contains the logic that looks for the - information about the location of the sources and build in the - \c {QTC_SOURCE} and \c {QTC_BUILD} environment variables. If these are not - defined, it uses the defaults you set in the project wizard. + \snippet exampleplugin/CMakeLists.txt 2 - So, if someone else opens your plugin project on their machine, they do not - need to edit the .pro file, but instead they should set the \c {QTC_SOURCE} - and \c {QTC_BUILD} environment variables correctly for the plugin's build - environment. + This section does some standard setup for Qt/CMake projects. Besides + setting a project name and a C++ standard to use, it turns on automatic + detection of files that need to be run through \c {moc}, \c {rcc} or \c + {uic}. - You should not need to change this section, except perhaps to adapt the - defaults. + \snippet exampleplugin/CMakeLists.txt 3 - \snippet exampleplugin/example.pro 4 + This section tells CMake to locate \QC and Qt. If your plugin requires + additional Qt modules, you need to add them to the corresponding + \c {find_package} call in this section. - \QC plugins can either be installed into the \QC installation's plugin - directory (requires write access there), or to a user specific plugin - directory. The \c USE_USER_DESTDIR switch in the .pro file defines which - method is used for building the plugin (which is independent from what you - can later use for distributing your plugin to other users). + To find \QC and Qt, the paths to the \QC and Qt installation must be + present in the \c {CMAKE_PREFIX_PATH} when you configure your plugin + with CMake. - \snippet exampleplugin/example.pro 5 + \snippet exampleplugin/CMakeLists.txt 4 - This section defines the name and dependencies of your plugin. The - \c {QTC_PLUGIN_NAME} variable defines the name of your plugin, and the name - of the dynamic library that is created for it. The \c {QTC_LIB_DEPENDS} - variable is a list of library names of the \QC utility libraries that your - plugin depends on. Typical values would be \c aggregation, - \c extensionsystem and \c utils. The \c {QTC_PLUGIN_DEPENDS} variable - defines the \QC plugins that your plugin depends on. Almost all \QC plugins - will depend on the \c coreplugin. The \c {QTC_PLUGIN_RECOMMENDS} variable - defines the \QC plugins that your plugin optionally depends on. For more - information, see \l{Optional Dependencies}. + The \c {add_qtc_plugin} call creates a target for your plugin with the + specified name. - \snippet exampleplugin/example.pro 6 + In the \c {PLUGIN_DEPENDS} sub-section, you need to specify \QC plugins that + your plugin depends on. Valid values are a plugin's name prefixed with + \c {QtCreator::}. - The included file \c{qtcreatorplugin.pri} makes sure that you build a plugin - that is suitable for use in \QC, by using the information you gave above. + In the \c {DEPENDS} sub-section, you need to specify libraries that your + plugin depends on. Use a Qt module name prefixed with \c {$\{QtX\}::} + to link to additional Qt modules. To link against additional \QC libraries, + prefix their name with \c {QtCreator::}. In this subsection you also + specify other libraries that your plugin depends on. - For more information about qmake, and writing \c {.pro} files in general, - see the \l{qmake Manual}. + In the \c {SOURCES} sub-section, you specify all files that belong to your + plugin project. CMake sorts these into source files and header files + automatically. Other files in this section are ignored by CMake but appear + for example in the project tree that is shown in IDEs like \QC for easier + access. \section1 Plugin Meta Data Template @@ -301,22 +282,22 @@ \section1 Plugin Class - The files \c {exampleplugin.h} and \c {exampleplugin.cpp} define the plugin + The files \c {example.h} and \c {example.cpp} define the plugin implementation of your little plugin. We'll concentrate on some highlights here, and give pointers to more detailed information for the various parts. \section2 Header File - The header file \c {exampleplugin.h} defines the interface of the plugin + The header file \c {example.h} defines the interface of the plugin class. - \snippet exampleplugin/exampleplugin.h namespaces + \snippet exampleplugin/example.h namespaces The plugin is defined in a \c {Example::Internal} namespace, which conforms to the coding rules for \l{coding-rules-namespacing}{namespacing} in \QC sources. - \snippet exampleplugin/exampleplugin.h base class + \snippet exampleplugin/example.h base class All \QC plugins must be derived from \l{ExtensionSystem::IPlugin} and are QObjects. The \c {Q_PLUGIN_METADATA} macro is necessary to create a @@ -325,13 +306,13 @@ \c FILE must point to the plugin's meta data file as described in \l{Plugin Meta Data}. - \snippet exampleplugin/exampleplugin.h plugin functions + \snippet exampleplugin/example.h plugin functions The base class defines basic functions that are called during the life cycle of a plugin, which are here implemented for your new plugin. These functions and their roles are described in detail in \l{Plugin Life Cycle}. - \snippet exampleplugin/exampleplugin.h slot + \snippet exampleplugin/example.h slot The plugin has an additional custom slot, that is used to pop up a dialog when the user chooses the menu item that this plugin adds. @@ -353,7 +334,7 @@ For more information about implementing the plugin interface, see the \l{ExtensionSystem::IPlugin} API documentation and \l{Plugin Life Cycle}. - \snippet exampleplugin/exampleplugin.cpp add action + \snippet exampleplugin/example.cpp add action This part of the code creates a new \c QAction, registers it as a new \c Command in the action manager, and connects it to the plugin's slot. The @@ -362,12 +343,12 @@ be directed to different plugins under different circumstances, as well as a few other things. - \snippet exampleplugin/exampleplugin.cpp add menu + \snippet exampleplugin/example.cpp add menu Here a new menu item is created, the created command added to it, and the menu added to the \uicontrol Tools menu in the menu bar. - \snippet exampleplugin/exampleplugin.cpp slot implementation + \snippet exampleplugin/example.cpp slot implementation This part defines the code that is called when the menu item is triggered. It uses the Qt API to open a message box that displays informative text and diff --git a/doc/qtdesignstudio/images/studio-3d-joint-properties.png b/doc/qtdesignstudio/images/studio-3d-joint-properties.png Binary files differnew file mode 100644 index 00000000000..71beb6fd3e4 --- /dev/null +++ b/doc/qtdesignstudio/images/studio-3d-joint-properties.png diff --git a/doc/qtdesignstudio/images/studio-3d-models.png b/doc/qtdesignstudio/images/studio-3d-models.png Binary files differindex 6f2dfc68122..d7c07086725 100644 --- a/doc/qtdesignstudio/images/studio-3d-models.png +++ b/doc/qtdesignstudio/images/studio-3d-models.png diff --git a/doc/qtdesignstudio/images/studio-design-mode.png b/doc/qtdesignstudio/images/studio-design-mode.png Binary files differindex eb610dcf8ea..e4a03c583aa 100644 --- a/doc/qtdesignstudio/images/studio-design-mode.png +++ b/doc/qtdesignstudio/images/studio-design-mode.png diff --git a/doc/qtdesignstudio/images/studio-qtquick-3d-components.png b/doc/qtdesignstudio/images/studio-qtquick-3d-components.png Binary files differindex ccf4ea0b377..25974ab3260 100644 --- a/doc/qtdesignstudio/images/studio-qtquick-3d-components.png +++ b/doc/qtdesignstudio/images/studio-qtquick-3d-components.png diff --git a/doc/qtdesignstudio/images/studio-qtquick-3d-model.png b/doc/qtdesignstudio/images/studio-qtquick-3d-model.png Binary files differindex 94dd662ea4e..3916774b3a8 100644 --- a/doc/qtdesignstudio/images/studio-qtquick-3d-model.png +++ b/doc/qtdesignstudio/images/studio-qtquick-3d-model.png diff --git a/doc/qtdesignstudio/images/studio-qtquick-3d-properties-tessellation.png b/doc/qtdesignstudio/images/studio-qtquick-3d-properties-tessellation.png Binary files differnew file mode 100644 index 00000000000..6c56ef9fec0 --- /dev/null +++ b/doc/qtdesignstudio/images/studio-qtquick-3d-properties-tessellation.png diff --git a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc index 9442cbfd6db..ceb5d458611 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio-toc.qdoc @@ -89,6 +89,7 @@ \li \l Animations \li \l{3D Views} \li \l{Group} + \li \l{Skeletal Animation} \li \l{3D Models} \li \l{Materials and Shaders} \li \l{Textures} diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-materials.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-materials.qdoc index 288b664c45b..4f98406dd9d 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-materials.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-materials.qdoc @@ -32,8 +32,19 @@ \title 3D Materials - \QDS provides a set of pregenerated Qt Quick 3D materials that can be used - to create good-looking \l {3D Models}{models} quickly and easily. + \QDS provides a set of pregenerated \uicontrol {Qt Quick 3D} + materials. If the 3D materials are not displayed in \uicontrol Library, + you can add the \uicontrol QtQuick3D.Materials module to your project, + as described in \l {Adding and Removing Modules}. However, since using the + pregenerated 3D materials may cause performance issues, we advice you to + use \uicontrol {Principled Material}, \uicontrol {Default Material}, or + \uicontrol {Custom Material} instead. For more information, + see \l {Materials and Shaders} and \l {Creating Custom Materials}. + + \note The \uicontrol QtQuick3D.Materials module is not available in + \uicontrol {Qt 6}. To use the pregenerated \uicontrol {Qt Quick 3D} + materials, you need to select \uicontrol {Qt 5} as the + \uicontrol {Target Qt Version} when \l {Creating Projects}{creating your project}. To apply a 3D material to a component, you should first delete the default material and then drag-and-drop a new material from \l Library > @@ -46,10 +57,6 @@ \uicontrol Materials property, select the \inlineimage plus.png icon, and choose the new material in the dropdown menu. - If the 3D materials are not displayed in \uicontrol Library, you should add - the \uicontrol QtQuick3D.Materials module to your project, as described in - \l {Adding and Removing Modules}. - Each material has its own set of properties that can be used to further define the appearance of the material. For each material the \uicontrol {Environment Map} property specifies whether or not diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-model.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-model.qdoc index 5826a2bb17c..26d0685296d 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-model.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-model.qdoc @@ -27,18 +27,19 @@ /*! \page studio-3d-model.html - \previouspage studio-3d-node.html + \previouspage studio-skeletal-components.html \nextpage studio-3d-materials.html \title 3D Models - \QDS \l Library features some built-in primitive 3D models. This allows you - to add cubes, cones, cylinders, and planes (rectangles) to your scene. + The \l Library view features some built-in primitive 3D models. This allows + you to add cubes, cones, cylinders, and planes (rectangles) to your scene. - \image studio-3d-models.png + \image studio-3d-models.png "Various 3D models in 3D Editor" A Model component loads mesh data from a file. You can modify how the - component is shaded by adding \l{3D Materials}{materials} to the model. + component is shaded by using materials. For more information, see + \l {Materials and Shaders} and \l {Creating Custom Materials}. You can drag-and-drop a model from \uicontrol Library > \uicontrol Components > \uicontrol {Qt Quick 3D} > \uicontrol {Qt Quick 3D} to \l {3D Editor} or @@ -49,28 +50,66 @@ \image studio-qtquick-3d-components.png "The Qt Quick 3D section in Library" - You can change the model type in the \uicontrol Source field in the - \uicontrol Properties view. Select the \inlineimage plus.png + \section1 Model Properties + + You can change the model type in \uicontrol Properties > \uicontrol Model + > \uicontrol Source field. Select the \inlineimage plus.png button to add custom model types to the list. \image studio-qtquick-3d-model.png "Model properties" + To use the geometry of this model when rendering to shadow maps, select the + \uicontrol {Casts shadows} check box. To allow casting shadows on the model, + select the \uicontrol {Receives shadows} check box. + To enable picking the model against the scene, select the \uicontrol Pickable check box. Picking transforms the screen space x and y coordinates to a ray cast towards the specified position in scene space. - To use the geometry of this model when rendering to shadow maps, select the - \uicontrol {Casts shadows} check box. To allow casting shadows on the model, - select the \uicontrol {Receives shadows} check box. + A model can consist of several sub-meshes, each of which can have its own + material. Select the material from the list in the \uicontrol {Materials} + field. Select the \inlineimage plus.png + button to add materials to the list. For more information about materials, + see \l {Materials and Shaders}. + + Specify a custom geometry for the model in the \uicontrol Geometry field. + The \uicontrol Source field must be empty when custom geometry is used. - \section1 Tessellation + Set the \uicontrol Instancing property to render a number of instances of + the model as defined by the instance table. - To dynamically generate additional geometry for the model, select the - tiling mode in the \uicontrol {Tessellation mode} filed. Tessellation - is useful when using a displacement map with geometry, or to generate a - smoother silhouette when zooming in. You can select either a Phong or - an NPatch tessellation generator. + Set the \uicontrol {Instance root} property to define the origin of the + instance's coordinate system. + + Specify the \uicontrol Skeleton property to define the \uicontrol Skeleton + component used for this model. \uicontrol Skeletons are used for skeletal + animation. + + Specify \uicontrol {Morph targets} to use for rendering the provided + geometry. Meshes should have at least one attribute among positions, normals, + tangent, and bitangent for the morph targets. \uicontrol {Quick 3D} supports + the maximum of eight \uicontrol {Morph targets}. Any additional targets + after the first eight will be ignored. This property is not used when the + model is shaded by a \uicontrol {Custom Material}. + + Define the \uicontrol {Depth bias} property to ensure the shadows of your + model are displayed correctly. + + \section1 Tessellation Properties Available in Qt 5 + + The properties discussed in this section are only available if you selected + \uicontrol {Qt 5} as the \uicontrol {Target Qt Version} when creating the + project. + + \image studio-qtquick-3d-properties-tessellation.png "Tessellation properties" + + Tessellation refers to additional geometry that resembles tiling, which you + can add to your model. To dynamically generate tessellation for the model, + select \uicontrol Linear, \uicontrol Phong, or \uicontrol NPatch as the + \uicontrol {Tessellation mode}. Tessellation is useful when using a + displacement map with geometry, or to generate a smoother silhouette + when zooming in. Specify an edge multiplier to the tessellation generator in the \uicontrol {Edge tessellation} field and an inner multiplier in @@ -80,11 +119,4 @@ the tessellation generator, select the \uicontrol {Enable wireframe mode} check box. - \section1 Adding Materials to Sub-Meshes - - A model can consist of several sub-meshes, each of which can have its own - material. Select the material from the list in the \uicontrol {Materials} - field. Select the \inlineimage plus.png - button to add materials to the list. For more information about materials, - see \l {Materials and Shaders}. */ diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-node.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-node.qdoc index 701683979cb..9c50ec4232d 100644 --- a/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-node.qdoc +++ b/doc/qtdesignstudio/src/qtquick3d-editor/qtdesignstudio-3d-node.qdoc @@ -26,7 +26,7 @@ /*! \page studio-3d-node.html \previouspage quick-animations.html - \nextpage studio-3d-model.html + \nextpage studio-skeletal-components.html \title Group diff --git a/doc/qtdesignstudio/src/qtquick3d-editor/studio-skeletal-components.qdoc b/doc/qtdesignstudio/src/qtquick3d-editor/studio-skeletal-components.qdoc new file mode 100644 index 00000000000..c6edcc7197c --- /dev/null +++ b/doc/qtdesignstudio/src/qtquick3d-editor/studio-skeletal-components.qdoc @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Design Studio documentation. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** +****************************************************************************/ + +/*! + \page studio-skeletal-components.html + \previouspage studio-3d-node.html + \nextpage studio-3d-model.html + + \title Skeletal Animation + + Skeletal animation is a technique used in computer animation. In skeletal + animation, a character is represented in the form of a surface representation + (skin or mesh), and a skeleton. This portrays how the character can move, + inspired by how a physical skeleton works for vertebrates. The "bones" of the + skeleton are represented by a hierarchy of joint nodes. + + The normal workflow is to use an external content creation tool to define + the skeleton and the skin (this is sometimes also referred to as rigging), + and import them to \QDS. You can then create skeletal animations using + \uicontrol Skeleton and \uicontrol Joint components available in + \uicontrol Library > \uicontrol Components > \uicontrol {Qt Quick 3D} > + \uicontrol {Qt Quick 3D}. + + \section1 Skeleton + + A \uicontrol Skeleton component determines a skeletal animation hierarchy + and defines how a model can be animated using skeletal animation. + It contains a hierarchy of \uicontrol Joint nodes. Each joint can be + transformed for a skinning animation. + + \section1 Joint + + A \uicontrol Joint defines a node in a skeletal animation hierarchy + and functions similarly to joints between bones in a human skeleton. + It is a transformable node that must be contained inside a + \uicontrol Skeleton component. + + Define properties for \uicontrol Joint components in \uicontrol Properties + > \uicontrol Joint. + + \image studio-3d-joint-properties.png "Joint properties in the Properties view" + + Use the \uicontrol Index property to define the index of this joint. + This index value is used in the \uicontrol {Joint semantic} custom geometry + attribute. + + \note The \uicontrol Index values must be unique within the same + \uicontrol Skeleton. + + Use the \uicontrol {Skeleton root} property to define the \uicontrol Skeleton + that contains the \uicontrol Joint. Do note that all the \uicontrol Joints + in the \uicontrol Skeleton must have the same \uicontrol {Skeleton root} + for the animation to work properly. +*/ diff --git a/scripts/deployqtHelper_mac.sh b/scripts/deployqtHelper_mac.sh index 815054b4e83..c28ada426f1 100755 --- a/scripts/deployqtHelper_mac.sh +++ b/scripts/deployqtHelper_mac.sh @@ -90,6 +90,18 @@ if [ -d "$sqldriversSrcDir" ]; then fi fi +# workaround for Qt 6.2: +# - QTBUG-94796 macdeployqt does not deploy /Contents/PlugIns/imageformats/libqsvg.dylib anymore +imageformatsDestDir="$app_path/Contents/PlugIns/imageformats" +imageformatsSrcDir="$plugin_src/imageformats" +if [ -d "$imageformatsSrcDir" ]; then + if [ ! -d "$imageformatsDestDir" ]; then + echo "- Copying sqlitedriver plugin" + mkdir -p "$imageformatsDestDir" + cp "$imageformatsSrcDir/libqsvg.dylib" "$imageformatsDestDir/libqsvg.dylib" + fi +fi + # copy Qt Quick 2 imports imports2Dir="$app_path/Contents/Imports/qtquick2" if [ -d "$quick2_src" ]; then diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/camerageometry.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/camerageometry.cpp index c80343bb466..365b03a8f7b 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/camerageometry.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/camerageometry.cpp @@ -139,7 +139,7 @@ void CameraGeometry::doUpdateGeometry() return; } - if (!m_camera->cameraNode()) { + if (!QQuick3DObjectPrivate::get(m_camera)->spatialNode) { // Doing explicit viewport mapping forces cameraNode creation m_camera->mapToViewport({}, m_viewPortRect.width(), m_viewPortRect.height()); } @@ -171,7 +171,7 @@ void CameraGeometry::fillVertexData(QByteArray &vertexData, QByteArray &indexDat auto indexPtr = reinterpret_cast<quint16 *>(indexData.data()); QMatrix4x4 m; - QSSGRenderCamera *camera = m_camera->cameraNode(); + QSSGRenderCamera *camera = static_cast<QSSGRenderCamera *>(QQuick3DObjectPrivate::get(m_camera)->spatialNode); if (camera) { QRectF rect = m_viewPortRect; if (rect.isNull()) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp index 1853363287f..ef0dd33fba2 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/editor3d/mousearea3d.cpp @@ -818,7 +818,8 @@ QVector3D MouseArea3D::getMousePosInPlane(const MouseArea3D *helper, const DoubleVec3D rayPos0 = m_view3D->mapTo3DScene(mousePos1.toVec3()); DoubleVec3D rayPos1; if (qobject_cast<QQuick3DOrthographicCamera *>(m_view3D->camera())) { - rayPos1 = rayPos0 - rayPos0.length() * DoubleVec3D(m_view3D->camera()->cameraNode()->getDirection()); + if (auto cameraNode = static_cast<QSSGRenderCamera *>(QQuick3DObjectPrivate::get(m_view3D->camera())->spatialNode)) + rayPos1 = rayPos0 - rayPos0.length() * DoubleVec3D(cameraNode->getDirection()); } else { DoubleVec3D dir; DoubleVec3D camPos = m_view3D->camera()->scenePosition(); @@ -1021,12 +1022,17 @@ QVector3D MouseArea3D::getNormal() const QVector3D MouseArea3D::getCameraToNodeDir(QQuick3DNode *node) const { QVector3D dir; - if (qobject_cast<QQuick3DOrthographicCamera *>(m_view3D->camera())) { - dir = -m_view3D->camera()->cameraNode()->getDirection(); - } else { - QVector3D camPos = m_view3D->camera()->scenePosition(); - QVector3D nodePos = pivotScenePosition(node); - dir = (nodePos - camPos).normalized(); + if (m_view3D->camera()) { + // We need to do a cast here to be compatible with Qt 5.x. + // From Qt 6.2 the type can be read from the node directly. + if (qobject_cast<QQuick3DOrthographicCamera *>(m_view3D->camera())) { + if (auto renderCamera = QQuick3DObjectPrivate::get(m_view3D->camera())->spatialNode) + dir -= static_cast<QSSGRenderCamera *>(renderCamera)->getDirection(); + } else { + QVector3D camPos = m_view3D->camera()->scenePosition(); + QVector3D nodePos = pivotScenePosition(node); + dir = (nodePos - camPos).normalized(); + } } return dir; } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp index e191d6468e1..e31c4932cf7 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.cpp @@ -935,6 +935,9 @@ void NodeInstanceServer::setInstancePropertyBinding(const PropertyBindingContain Internal::QmlPrivateGate::createNewDynamicProperty(instance.internalInstance()->object(), engine(), QString::fromUtf8(name)); instance.setPropertyBinding(name, expression); + + if (instance.instanceId() == 0 && (name == "width" || name == "height")) + resizeCanvasToRootItem(); } } } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h index fffecc3609c..92fc069690a 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/nodeinstanceserver.h @@ -218,6 +218,7 @@ public: virtual void handleInstanceHidden(const ServerNodeInstance &instance, bool enable, bool checkAncestors); virtual QImage grabWindow() = 0; + virtual QImage grabItem(QQuickItem *item) = 0; public slots: void refreshLocalFileProperty(const QString &path); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 384f6405e5b..ad9de63f57e 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -761,7 +761,8 @@ void Qt5InformationNodeInstanceServer::updateNodesRecursive(QQuickItem *item) const auto childItems = item->childItems(); for (QQuickItem *childItem : childItems) updateNodesRecursive(childItem); - if (Internal::QuickItemNodeInstance::unifiedRenderPath()) { + + if (Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) { if (item->flags() & QQuickItem::ItemHasContents) item->update(); } else { @@ -773,7 +774,7 @@ QQuickItem *Qt5InformationNodeInstanceServer::getContentItemForRendering(QQuickI { QQuickItem *contentItem = QQmlProperty::read(rootItem, "contentItem").value<QQuickItem *>(); if (contentItem) { - if (!Internal::QuickItemNodeInstance::unifiedRenderPath()) + if (!Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) designerSupport()->refFromEffectItem(contentItem, false); QmlDesigner::Internal::QmlPrivateGate::disableNativeTextRendering(contentItem); } @@ -899,7 +900,7 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView() instanceObj = instance.internalObject(); } QSize renderSize = m_modelNodePreviewImageCommand.size(); - if (Internal::QuickItemNodeInstance::unifiedRenderPath()) { + if (Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) { // Requested size is already adjusted for target pixel ratio, so we have to adjust // back if ratio is not default for our window. double ratio = m_modelNode3DImageViewData.window->devicePixelRatio(); @@ -1106,7 +1107,7 @@ Qt5InformationNodeInstanceServer::~Qt5InformationNodeInstanceServer() if (m_editView3DData.rootItem) QMetaObject::invokeMethod(m_editView3DData.rootItem, "aboutToShutDown", Qt::DirectConnection); - if (!Internal::QuickItemNodeInstance::unifiedRenderPath()) { + if (!Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) { if (m_editView3DData.contentItem) designerSupport()->derefFromEffectItem(m_editView3DData.contentItem); if (m_modelNode3DImageViewData.contentItem) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp index 93e6e786cd5..6c914bf3ea8 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceclientproxy.cpp @@ -64,11 +64,11 @@ Qt5NodeInstanceClientProxy::Qt5NodeInstanceClientProxy(QObject *parent) : const bool qt6 = true; #endif - const bool unifiedRenderPath = qt6 || qEnvironmentVariableIsSet("QMLPUPPET_UNIFIED_RENDER_PATH"); + const bool unifiedRenderPath = qEnvironmentVariableIsSet("QMLPUPPET_UNIFIED_RENDER_PATH"); if (unifiedRenderPath) Internal::QuickItemNodeInstance::enableUnifiedRenderPath(true); - else + else if (!qt6) DesignerSupport::activateDesignerWindowManager(); if (QCoreApplication::arguments().at(1) == QLatin1String("--readcapturedstream")) { diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp index da9f7ed8233..13cdb4b9b93 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp @@ -44,10 +44,13 @@ #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #include <QtGui/private/qrhi_p.h> -#include <QtQuick/private/qquickwindow_p.h> -#include <QtQuick/private/qsgrenderer_p.h> +#include <QtQuick/private/qquickitem_p.h> #include <QtQuick/private/qquickrendercontrol_p.h> #include <QtQuick/private/qquickrendertarget_p.h> +#include <QtQuick/private/qquickwindow_p.h> +#include <QtQuick/private/qsgcontext_p.h> +#include <QtQuick/private/qsgrenderer_p.h> +#include <QtQuick/private/qsgrhilayer_p.h> #endif namespace QmlDesigner { @@ -332,6 +335,80 @@ QImage Qt5NodeInstanceServer::grabWindow() return {}; } +QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item) +{ + QImage renderImage; +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + if (!m_viewData.rootItem || (m_viewData.bufferDirty && !initRhi(m_viewData))) + return {}; + + QQuickItemPrivate *pItem = QQuickItemPrivate::get(item); + pItem->refFromEffectItem(false); + + ServerNodeInstance instance = instanceForObject(item); + const auto childInstances = instance.childItems(); + + // Hide immediate children that have instances and are QQuickItems so we get only + // the parent item's content, as compositing is handled on creator side. + for (const auto &childInstance : childInstances) { + QQuickItem *childItem = qobject_cast<QQuickItem *>(childInstance.internalObject()); + if (childItem) { + QQuickItemPrivate *pChild = QQuickItemPrivate::get(childItem); + pChild->refFromEffectItem(true); + } + } + + m_viewData.renderControl->polishItems(); + m_viewData.renderControl->beginFrame(); + m_viewData.renderControl->sync(); + + // Connection to afterRendering is necessary, as this needs to be done before + // call to endNextRhiFrame which happens inside QQuickRenderControl::render() + QMetaObject::Connection connection = QObject::connect(m_viewData.window.data(), + &QQuickWindow::afterRendering, + this, [&]() { + // To get only the single item, we need to make a layer out of it, which enables + // us to render it to a texture that we can grab to an image. + QSGRenderContext *rc = QQuickWindowPrivate::get(m_viewData.window.data())->context; + QSGLayer *layer = rc->sceneGraphContext()->createLayer(rc); + layer->setItem(pItem->itemNode()); + QSizeF itemSize = QSizeF(item->width(), item->height()); + layer->setRect(QRectF(0, itemSize.height(), itemSize.width(), -itemSize.height())); + const QSize minSize = rc->sceneGraphContext()->minimumFBOSize(); + layer->setSize(QSize(qMax(minSize.width(), int(itemSize.width())), + qMax(minSize.height(), int(itemSize.height())))); + layer->scheduleUpdate(); + + if (layer->updateTexture()) + renderImage = layer->toImage(); + else + qWarning() << __FUNCTION__ << "Failed to update layer texture"; + + delete layer; + layer = nullptr; + }); + + m_viewData.renderControl->render(); + + QObject::disconnect(connection); + + m_viewData.renderControl->endFrame(); + + // Restore visibility of immediate children that have instances and are QQuickItems + for (const auto &childInstance : childInstances) { + QQuickItem *childItem = qobject_cast<QQuickItem *>(childInstance.internalObject()); + if (childItem) { + QQuickItemPrivate *pChild = QQuickItemPrivate::get(childItem); + pChild->derefFromEffectItem(true); + } + } + pItem->derefFromEffectItem(false); +#else + Q_UNUSED(item) +#endif + return renderImage; +} + void Qt5NodeInstanceServer::refreshBindings() { DesignerSupport::refreshExpressions(context()); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h index 9a7d43635df..190a0012754 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.h @@ -69,6 +69,7 @@ public: void reparentInstances(const ReparentInstancesCommand &command) override; QImage grabWindow() override; + QImage grabItem(QQuickItem *item) override; protected: void initializeView() override; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp index 63dba600d50..97e015b2e74 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5rendernodeinstanceserver.cpp @@ -102,9 +102,6 @@ void Qt5RenderNodeInstanceServer::collectItemChangesAndSendChangeCommands() clearChangedPropertyList(); if (Internal::QuickItemNodeInstance::unifiedRenderPath()) { - /* QQuickItem::grabToImage render path */ - /* TODO implement QQuickItem::grabToImage based rendering */ - /* sheduleRootItemRender(); */ if (windowDirty) nodeInstanceClient()->pixmapChanged(createPixmapChangedCommand({rootNodeInstance()})); } else { diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp index ee74ab856c9..51b1dcd1c06 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp @@ -171,10 +171,15 @@ void QuickItemNodeInstance::enableUnifiedRenderPath(bool unifiedRenderPath) bool QuickItemNodeInstance::checkIfRefFromEffect(qint32 id) { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) if (s_unifiedRenderPath) return false; return (s_createEffectItem || id == 0); +#else + Q_UNUSED(id) + return false; +#endif } void QuickItemNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance, @@ -267,9 +272,13 @@ QStringList QuickItemNodeInstance::allStates() const void QuickItemNodeInstance::updateDirtyNode(QQuickItem *item) { +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) if (s_unifiedRenderPath) return; DesignerSupport::updateDirtyNode(item); +#else + Q_UNUSED(item) +#endif } bool QuickItemNodeInstance::unifiedRenderPath() @@ -277,6 +286,15 @@ bool QuickItemNodeInstance::unifiedRenderPath() return s_unifiedRenderPath; } +bool QuickItemNodeInstance::unifiedRenderPathOrQt6() +{ +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + return true; +#else + return s_unifiedRenderPath; +#endif +} + QRectF QuickItemNodeInstance::contentItemBoundingBox() const { if (contentItem()) { @@ -415,16 +433,15 @@ QImage QuickItemNodeInstance::renderImage() const updateDirtyNodesRecursive(quickItem()); QRectF renderBoundingRect = boundingRect(); + QImage renderImage; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QSize size = renderBoundingRect.size().toSize(); static double devicePixelRatio = qgetenv("FORMEDITOR_DEVICE_PIXEL_RATIO").toDouble(); if (size.width() * size.height() > 4000 * 4000) size = QSize(0,0); size *= devicePixelRatio; - QImage renderImage; - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) if (s_unifiedRenderPath) { renderImage = nodeInstanceServer()->quickWindow()->grabWindow(); } else { @@ -438,8 +455,12 @@ QImage QuickItemNodeInstance::renderImage() const } renderImage.setDevicePixelRatio(devicePixelRatio); #else - renderImage = nodeInstanceServer()->grabWindow(); + if (s_unifiedRenderPath) + renderImage = nodeInstanceServer()->grabWindow(); + else + renderImage = nodeInstanceServer()->grabItem(quickItem()); renderImage = renderImage.copy(renderBoundingRect.toRect()); + /* When grabbing an offscren window the device pixel ratio is 1 */ renderImage.setDevicePixelRatio(1); #endif diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h index b71b9909864..7e9bd53341f 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.h @@ -104,6 +104,7 @@ public: static void updateDirtyNode(QQuickItem *item); static bool unifiedRenderPath(); + static bool unifiedRenderPathOrQt6(); protected: explicit QuickItemNodeInstance(QQuickItem*); diff --git a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml index 4ed0159dd58..498c474411a 100644 --- a/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml +++ b/share/qtcreator/qmldesigner/itemLibraryQmlSources/Assets.qml @@ -165,7 +165,8 @@ Item { (assetsView.verticalScrollBarVisible ? assetsView.verticalThickness : 0) height: img.height color: selectedAssets[filePath] ? StudioTheme.Values.themeInteraction - : (mouseArea.containsMouse ? "#444444" : "transparent") + : (mouseArea.containsMouse ? StudioTheme.Values.themeSectionHeadBackground + : "transparent") Row { spacing: 5 diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AlignDistributeSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AlignDistributeSection.qml index e2228795935..b1fcddba371 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AlignDistributeSection.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/QtQuick/AlignDistributeSection.qml @@ -210,7 +210,7 @@ Section { onClicked: alignDistribute.distributeSpacing(AlignDistribute.X, alignToComboBox.currentEnum, keyObjectComboBox.currentText, - distanceSpinBox.realValue, + distanceSpinBox.value, buttonRow.getDistributeDirection()) } @@ -220,11 +220,13 @@ Section { onClicked: alignDistribute.distributeSpacing(AlignDistribute.Y, alignToComboBox.currentEnum, keyObjectComboBox.currentText, - distanceSpinBox.realValue, + distanceSpinBox.value, buttonRow.getDistributeDirection()) } } + Spacer { implicitWidth: 8 } + StudioControls.ButtonRow { id: buttonRow actionIndicatorVisible: false @@ -250,6 +252,7 @@ Section { buttonIcon: StudioTheme.Constants.distributeOriginNone checkable: true StudioControls.ButtonGroup.group: group + tooltip: qsTr("Disables the distribution of spacing in pixels.") } AbstractButton { @@ -257,6 +260,8 @@ Section { buttonIcon: StudioTheme.Constants.distributeOriginTopLeft checkable: true StudioControls.ButtonGroup.group: group + tooltip: qsTr("Sets the left or top border of the target area or item as the " + + "starting point, depending on the distribution orientation.") } AbstractButton { @@ -264,6 +269,9 @@ Section { buttonIcon: StudioTheme.Constants.distributeOriginCenter checkable: true StudioControls.ButtonGroup.group: group + tooltip: qsTr("Sets the horizontal or vertical center of the target area or " + + "item as the starting point, depending on the distribution " + + "orientation.") } AbstractButton { @@ -271,6 +279,8 @@ Section { buttonIcon: StudioTheme.Constants.distributeOriginBottomRight checkable: true StudioControls.ButtonGroup.group: group + tooltip: qsTr("Sets the bottom or right border of the target area or item as " + + "the starting point, depending on the distribution orientation.") } } } @@ -280,12 +290,13 @@ Section { SecondColumnLayout { Spacer { implicitWidth: StudioTheme.Values.actionIndicatorWidth } - StudioControls.RealSpinBox { + DoubleSpinBox { id: distanceSpinBox implicitWidth: StudioTheme.Values.twoControlColumnWidth - actionIndicatorVisible: false - realFrom: -1000 - realTo: 1000 + stepSize: 1 + minimumValue: -1000 + maximumValue: 1000 + decimals: 0 enabled: !buttonNone.checked } } diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml index 38034918fb5..09764f7baf9 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/StudioTheme/Values.qml @@ -278,7 +278,7 @@ QtObject { property string themeStateBackground: Theme.color(Theme.DSstateBackgroundColor) property string themeStatePreviewOutline: Theme.color(Theme.DSstatePreviewOutline) - property string themeUnimportedModuleColor: "#e33c2e" + property string themeUnimportedModuleColor: Theme.color(Theme.DSUnimportedModuleColor) // Taken out of Constants.js property string themeChangedStateText: Theme.color(Theme.DSchangedStateText) diff --git a/share/qtcreator/themes/dark.creatortheme b/share/qtcreator/themes/dark.creatortheme index 736d517c6ef..7593a2b3875 100644 --- a/share/qtcreator/themes/dark.creatortheme +++ b/share/qtcreator/themes/dark.creatortheme @@ -152,6 +152,8 @@ DStoolTipBackground=ff111111 DStoolTipOutline=ffdadada DStoolTipText=ffdadada +DSUnimportedModuleColor=ffe33c2e + ;DS controls theme END BackgroundColorAlternate=alternateBackground diff --git a/share/qtcreator/themes/default.creatortheme b/share/qtcreator/themes/default.creatortheme index 0eb98021ba8..aeabe826906 100644 --- a/share/qtcreator/themes/default.creatortheme +++ b/share/qtcreator/themes/default.creatortheme @@ -143,6 +143,8 @@ DStoolTipBackground=ff111111 DStoolTipOutline=ffdadada DStoolTipText=ffdadada +DSUnimportedModuleColor=ffe33c2e + ;DS controls theme END BackgroundColorAlternate=ff3d3d3d diff --git a/share/qtcreator/themes/design-light.creatortheme b/share/qtcreator/themes/design-light.creatortheme index ef1b7bcbb1b..70ee4462cb6 100644 --- a/share/qtcreator/themes/design-light.creatortheme +++ b/share/qtcreator/themes/design-light.creatortheme @@ -157,6 +157,8 @@ DStoolTipBackground=ff111111 DStoolTipOutline=ffdadada DStoolTipText=ffdadada +DSUnimportedModuleColor=ffe33c2e + ;DS controls theme END BackgroundColorAlternate=alternateBackground diff --git a/share/qtcreator/themes/design.creatortheme b/share/qtcreator/themes/design.creatortheme index f93c74914b9..b48b3720988 100644 --- a/share/qtcreator/themes/design.creatortheme +++ b/share/qtcreator/themes/design.creatortheme @@ -154,6 +154,8 @@ DStoolTipBackground=ff111111 DStoolTipOutline=ffdadada DStoolTipText=ffdadada +DSUnimportedModuleColor=ffe33c2e + ;DS controls theme END BackgroundColorAlternate=alternateBackground diff --git a/share/qtcreator/themes/flat-dark.creatortheme b/share/qtcreator/themes/flat-dark.creatortheme index aa9c150b1a5..aa0e8d2fdfb 100644 --- a/share/qtcreator/themes/flat-dark.creatortheme +++ b/share/qtcreator/themes/flat-dark.creatortheme @@ -156,6 +156,8 @@ DStoolTipBackground=ff111111 DStoolTipOutline=ffdadada DStoolTipText=ffdadada +DSUnimportedModuleColor=ffe33c2e + ;DS controls theme END BackgroundColorAlternate=alternateBackground diff --git a/share/qtcreator/themes/flat-light.creatortheme b/share/qtcreator/themes/flat-light.creatortheme index 1fa9747d3a3..b98478d134d 100644 --- a/share/qtcreator/themes/flat-light.creatortheme +++ b/share/qtcreator/themes/flat-light.creatortheme @@ -152,6 +152,8 @@ DStoolTipBackground=ff111111 DStoolTipOutline=ffdadada DStoolTipText=ffdadada +DSUnimportedModuleColor=ffe33c2e + ;DS controls theme END BackgroundColorAlternate=alternateBackground diff --git a/share/qtcreator/themes/flat.creatortheme b/share/qtcreator/themes/flat.creatortheme index 25a582d17ec..b6c8f09d9e4 100644 --- a/share/qtcreator/themes/flat.creatortheme +++ b/share/qtcreator/themes/flat.creatortheme @@ -150,6 +150,8 @@ DStoolTipBackground=ff111111 DStoolTipOutline=ffdadada DStoolTipText=ffdadada +DSUnimportedModuleColor=ffe33c2e + ;DS controls theme END BackgroundColorAlternate=alternateBackground diff --git a/src/libs/utils/cpplanguage_details.h b/src/libs/utils/cpplanguage_details.h index c5697b1fcb7..59ec1e3920a 100644 --- a/src/libs/utils/cpplanguage_details.h +++ b/src/libs/utils/cpplanguage_details.h @@ -43,8 +43,9 @@ enum class LanguageVersion : unsigned char { CXX11, CXX14, CXX17, - CXX2a, - LatestCxx = CXX2a, + CXX20, + CXX2b, + LatestCxx = CXX2b, }; enum class LanguageExtension : unsigned char { diff --git a/src/libs/utils/shellcommand.cpp b/src/libs/utils/shellcommand.cpp index b803db8f0a9..08523c13e3e 100644 --- a/src/libs/utils/shellcommand.cpp +++ b/src/libs/utils/shellcommand.cpp @@ -391,7 +391,7 @@ void ShellCommand::runSynchronous(QtcProcess &process, const FilePath &workingDi if (d->m_progressParser) d->m_progressParser->parseProgress(text); if (!(d->m_flags & SuppressStdErr)) - appendError(text); + emit appendError(text); if (d->m_progressiveOutput) emit stdErrText(text); }); @@ -403,7 +403,7 @@ void ShellCommand::runSynchronous(QtcProcess &process, const FilePath &workingDi if (d->m_progressParser) d->m_progressParser->parseProgress(text); if (d->m_flags & ShowStdOut) - append(text); + emit append(text); if (d->m_progressiveOutput) { emit stdOutText(text); d->m_hadOutput = true; diff --git a/src/libs/utils/theme/theme.h b/src/libs/utils/theme/theme.h index dd8735c4029..66d2d291aba 100644 --- a/src/libs/utils/theme/theme.h +++ b/src/libs/utils/theme/theme.h @@ -417,7 +417,9 @@ public: DStoolTipBackground, DStoolTipOutline, - DStoolTipText + DStoolTipText, + + DSUnimportedModuleColor }; enum Gradient { diff --git a/src/libs/utils/url.cpp b/src/libs/utils/url.cpp index 026af262fc5..e325615bb2d 100644 --- a/src/libs/utils/url.cpp +++ b/src/libs/utils/url.cpp @@ -47,7 +47,13 @@ QUrl urlFromLocalSocket() { QUrl serverUrl; serverUrl.setScheme(urlSocketScheme()); - TemporaryFile file("qtcreator-freesocket"); + TemporaryFile file("qtc-socket"); + // see "man unix" for unix socket file name size limitations + if (file.fileName().size() > 104) { + qWarning().nospace() + << "Socket file name \"" << file.fileName() + << "\" is larger than 104 characters, which will not work on Darwin/macOS/Linux!"; + } if (file.open()) serverUrl.setPath(file.fileName()); return serverUrl; diff --git a/src/plugins/android/androidavdmanager.cpp b/src/plugins/android/androidavdmanager.cpp index c385b964eef..58204b1cc71 100644 --- a/src/plugins/android/androidavdmanager.cpp +++ b/src/plugins/android/androidavdmanager.cpp @@ -333,7 +333,7 @@ QString AndroidAvdManager::waitForAvd(const QString &avdName, // 60 rounds of 2s sleeping, two minutes for the avd to start QString serialNumber; for (int i = 0; i < 60; ++i) { - if (cancelChecker()) + if (cancelChecker && cancelChecker()) return QString(); serialNumber = findAvd(avdName); if (!serialNumber.isEmpty()) @@ -365,7 +365,7 @@ bool AndroidAvdManager::waitForBooted(const QString &serialNumber, { // found a serial number, now wait until it's done booting... for (int i = 0; i < 60; ++i) { - if (cancelChecker()) + if (cancelChecker && cancelChecker()) return false; if (isAvdBooted(serialNumber)) { return true; diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index e1cebec3d39..558f4300a37 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -176,7 +176,8 @@ AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step) QWidget *AndroidBuildApkWidget::createApplicationGroup() { - const int minApiSupported = AndroidManager::apiLevelRange().first; + QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(m_step->target()->kit()); + const int minApiSupported = AndroidManager::defaultMinimumSDK(qt); QStringList targets = AndroidConfig::apiLevelNamesFor(AndroidConfigurations::sdkManager()-> filteredSdkPlatforms(minApiSupported)); targets.removeDuplicates(); diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index cdade682f09..8c57e3e7971 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -778,12 +778,12 @@ bool AndroidConfig::isValidNdk(const QString &ndkLocation) const QString AndroidConfig::bestNdkPlatformMatch(int target, const BaseQtVersion *qtVersion) const { - target = std::max(AndroidManager::apiLevelRange().first, target); + target = std::max(AndroidManager::defaultMinimumSDK(qtVersion), target); foreach (int apiLevel, availableNdkPlatforms(qtVersion)) { if (apiLevel <= target) return QString::fromLatin1("android-%1").arg(apiLevel); } - return QString("android-%1").arg(AndroidManager::apiLevelRange().first); + return QString("android-%1").arg(AndroidManager::defaultMinimumSDK(qtVersion)); } FilePath AndroidConfig::sdkLocation() const @@ -1291,10 +1291,7 @@ void AndroidConfigurations::updateAutomaticKitList() Id deviceTypeId = DeviceTypeKitAspect::deviceTypeId(k); if (k->isAutoDetected() && !k->isSdkProvided() && deviceTypeId == Constants::ANDROID_DEVICE_TYPE) { - if (!QtKitAspect::qtVersion(k)) - KitManager::deregisterKit(k); // Remove autoDetected kits without Qt. - else - return true; + return true; } return false; }); @@ -1327,6 +1324,7 @@ void AndroidConfigurations::updateAutomaticKitList() && tc->isValid() && tc->typeId() == Constants::ANDROID_TOOLCHAIN_TYPEID; }); + QList<Kit *> unhandledKits = existingKits; for (ToolChain *tc : toolchains) { if (tc->language() != ProjectExplorer::Constants::CXX_LANGUAGE_ID) continue; @@ -1381,12 +1379,18 @@ void AndroidConfigurations::updateAutomaticKitList() k->setValueSilently(Constants::ANDROID_KIT_SDK, currentConfig().sdkLocation().toString()); }; - if (existingKit) + if (existingKit) { initializeKit(existingKit); // Update the existing kit with new data. - else + unhandledKits.removeOne(existingKit); + } else { KitManager::registerKit(initializeKit); + } } } + // cleanup any mess that might have existed before, by removing all Android kits that + // existed before, but weren't re-used + for (Kit *k : unhandledKits) + KitManager::deregisterKit(k); } bool AndroidConfigurations::force32bitEmulator() diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index 45fc9d64ce2..de02afee335 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -399,9 +399,14 @@ void AndroidManager::setDeviceApiLevel(Target *target, int level) target->setNamedSettings(ApiLevelKey, level); } -QPair<int, int> AndroidManager::apiLevelRange() +int AndroidManager::defaultMinimumSDK(const QtSupport::BaseQtVersion *qtVersion) { - return qMakePair(16, 29); + if (qtVersion && qtVersion->qtVersion() >= QtSupport::QtVersionNumber{6, 0}) + return 23; + else if (qtVersion && qtVersion->qtVersion() >= QtSupport::QtVersionNumber{5, 13}) + return 21; + else + return 16; } QString AndroidManager::androidNameForApiLevel(int x) diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h index fba589a3dba..b97fab1f205 100644 --- a/src/plugins/android/androidmanager.h +++ b/src/plugins/android/androidmanager.h @@ -31,6 +31,7 @@ #include <QObject> #include <QVersionNumber> +#include <qtsupport/baseqtversion.h> #include <projectexplorer/abi.h> QT_BEGIN_NAMESPACE @@ -87,6 +88,7 @@ public: static int minimumSDK(const ProjectExplorer::Target *target); static int minimumSDK(const ProjectExplorer::Kit *kit); + static int defaultMinimumSDK(const QtSupport::BaseQtVersion *qtVersion); static QStringList applicationAbis(const ProjectExplorer::Target *target); static QString archTriplet(const QString &abi); @@ -100,7 +102,6 @@ public: static QString devicePreferredAbi(const QStringList &deviceAbis, const QStringList &appAbis); static ProjectExplorer::Abi androidAbi2Abi(const QString &androidAbi); - static QPair<int, int> apiLevelRange(); static QString androidNameForApiLevel(int x); static void installQASIPackage(ProjectExplorer::Target *target, const Utils::FilePath &packagePath); diff --git a/src/plugins/android/androidmanifesteditorwidget.cpp b/src/plugins/android/androidmanifesteditorwidget.cpp index db74a953970..e9c065ddd15 100644 --- a/src/plugins/android/androidmanifesteditorwidget.cpp +++ b/src/plugins/android/androidmanifesteditorwidget.cpp @@ -720,18 +720,21 @@ void AndroidManifestEditorWidget::updateInfoBar() void AndroidManifestEditorWidget::updateSdkVersions() { - QPair<int, int> apiLevels = AndroidManager::apiLevelRange(); - for (int i = apiLevels.first; i < apiLevels.second + 1; ++i) - m_androidMinSdkVersion->addItem(tr("API %1: %2") - .arg(i) - .arg(AndroidManager::androidNameForApiLevel(i)), - i); - - for (int i = apiLevels.first; i < apiLevels.second + 1; ++i) - m_androidTargetSdkVersion->addItem(tr("API %1: %2") - .arg(i) - .arg(AndroidManager::androidNameForApiLevel(i)), - i); + static const QPair<int, int> sdkPair = qMakePair(16, 31); + int minSdk = sdkPair.first; + const int targetSdk = sdkPair.second; + const Target *target = androidTarget(m_textEditorWidget->textDocument()->filePath()); + if (target) { + const QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(target->kit()); + minSdk = AndroidManager::defaultMinimumSDK(qt); + } + + for (int i = minSdk; i <= targetSdk; ++i) { + const QString apiStr = tr("API %1: %2").arg(i) + .arg(AndroidManager::androidNameForApiLevel(i)); + m_androidMinSdkVersion->addItem(apiStr, i); + m_androidTargetSdkVersion->addItem(apiStr, i); + } } void AndroidManifestEditorWidget::updateInfoBar(const QString &errorMessage, int line, int column) diff --git a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp index 7b38aa0f41f..951847397c4 100644 --- a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp +++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp @@ -191,12 +191,14 @@ static bool isChildOf(const FilePath &path, const QStringList &prefixes) QList<CMakeBuildTarget> generateBuildTargets(const PreprocessedData &input, const FilePath &sourceDirectory, - const FilePath &buildDirectory) + const FilePath &buildDirectory, + bool haveLibrariesRelativeToBuildDirectory) { QDir sourceDir(sourceDirectory.toString()); const QList<CMakeBuildTarget> result = transform<QList>(input.targetDetails, - [&sourceDir, &sourceDirectory, &buildDirectory](const TargetDetails &t) { + [&sourceDir, &sourceDirectory, &buildDirectory, + &haveLibrariesRelativeToBuildDirectory](const TargetDetails &t) { const FilePath currentBuildDir = buildDirectory.absoluteFilePath(t.buildDir); CMakeBuildTarget ct; @@ -271,7 +273,8 @@ QList<CMakeBuildTarget> generateBuildTargets(const PreprocessedData &input, if (part.startsWith("-")) continue; - FilePath tmp = currentBuildDir.absoluteFilePath(FilePath::fromUserInput(part)); + const FilePath buildDir = haveLibrariesRelativeToBuildDirectory ? buildDirectory : currentBuildDir; + FilePath tmp = buildDir.absoluteFilePath(FilePath::fromUserInput(part)); if (f.role == "libraries") tmp = tmp.parentDir(); @@ -707,7 +710,12 @@ FileApiQtcData extractData(FileApiData &input, return {}; } - result.buildTargets = generateBuildTargets(data, sourceDirectory, buildDirectory); + // Ninja generator from CMake version 3.20.5 has libraries relative to build directory + const bool haveLibrariesRelativeToBuildDirectory = + input.replyFile.generator.startsWith("Ninja") + && input.replyFile.cmakeVersion >= QVersionNumber(3, 20, 5); + + result.buildTargets = generateBuildTargets(data, sourceDirectory, buildDirectory, haveLibrariesRelativeToBuildDirectory); result.cmakeFiles = std::move(data.cmakeFiles); result.projectParts = generateRawProjectParts(data, sourceDirectory); diff --git a/src/plugins/cmakeprojectmanager/fileapiparser.cpp b/src/plugins/cmakeprojectmanager/fileapiparser.cpp index cf6bff8233e..c2942b02ddf 100644 --- a/src/plugins/cmakeprojectmanager/fileapiparser.cpp +++ b/src/plugins/cmakeprojectmanager/fileapiparser.cpp @@ -147,6 +147,13 @@ static ReplyFileContents readReplyFile(const FilePath &filePath, QString &errorM result.generator = generator.value("name").toString(); result.isMultiConfig = generator.value("multiConfig").toBool(); } + const QJsonObject version = cmakeObject.value("version").toObject(); + { + int major = version.value("major").toInt(); + int minor = version.value("minor").toInt(); + int patch = version.value("patch").toInt(); + result.cmakeVersion = QVersionNumber(major, minor, patch); + } } } diff --git a/src/plugins/cmakeprojectmanager/fileapiparser.h b/src/plugins/cmakeprojectmanager/fileapiparser.h index e4400a7abc8..dc018a7c62c 100644 --- a/src/plugins/cmakeprojectmanager/fileapiparser.h +++ b/src/plugins/cmakeprojectmanager/fileapiparser.h @@ -39,6 +39,7 @@ #include <QFutureInterface> #include <QString> #include <QVector> +#include <QVersionNumber> #include <vector> @@ -65,6 +66,7 @@ public: QString cmakeRoot; QVector<ReplyObject> replies; + QVersionNumber cmakeVersion; Utils::FilePath jsonFile(const QString &kind, const Utils::FilePath &replyDir) const; }; diff --git a/src/plugins/cppcheck/cppchecktool.cpp b/src/plugins/cppcheck/cppchecktool.cpp index 312a0f420ef..a0cd174c2e6 100644 --- a/src/plugins/cppcheck/cppchecktool.cpp +++ b/src/plugins/cppcheck/cppchecktool.cpp @@ -164,7 +164,8 @@ QStringList CppcheckTool::additionalArguments(const CppTools::ProjectPart &part) break; case Version::CXX98: case Version::CXX17: - case Version::CXX2a: + case Version::CXX20: + case Version::CXX2b: result.push_back("--language=c++"); break; case Version::None: diff --git a/src/plugins/cppeditor/cppincludehierarchy_test.cpp b/src/plugins/cppeditor/cppincludehierarchy_test.cpp index b04a02f8a15..02dd165bc70 100644 --- a/src/plugins/cppeditor/cppincludehierarchy_test.cpp +++ b/src/plugins/cppeditor/cppincludehierarchy_test.cpp @@ -92,15 +92,15 @@ public: filePaths << absoluteFilePath; } - // Update Code Model - QVERIFY(parseFiles(filePaths)); - // Open Editor const QString fileName = temporaryDir.path() + QLatin1String("/file1.h"); CppEditor *editor; QVERIFY(openCppEditor(fileName, &editor)); closeEditorAtEndOfTestCase(editor); + // Update Code Model + QVERIFY(parseFiles(filePaths)); + // Test model CppIncludeHierarchyModel model; model.buildHierarchy(editor->document()->filePath().toString()); diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp index f5eb770c369..0c8c5d93056 100644 --- a/src/plugins/cpptools/compileroptionsbuilder.cpp +++ b/src/plugins/cpptools/compileroptionsbuilder.cpp @@ -472,7 +472,10 @@ void CompilerOptionsBuilder::addLanguageVersionAndExtensions() case LanguageVersion::CXX17: option = "/std:c++17"; break; - case LanguageVersion::CXX2a: + case LanguageVersion::CXX20: + option = "/std:c++20"; + break; + case LanguageVersion::CXX2b: option = "/std:c++latest"; break; } @@ -517,8 +520,11 @@ void CompilerOptionsBuilder::addLanguageVersionAndExtensions() case LanguageVersion::CXX17: option = (gnuExtensions ? QLatin1String("-std=gnu++17") : QLatin1String("-std=c++17")); break; - case LanguageVersion::CXX2a: - option = (gnuExtensions ? QLatin1String("-std=gnu++2a") : QLatin1String("-std=c++2a")); + case LanguageVersion::CXX20: + option = (gnuExtensions ? QLatin1String("-std=gnu++20") : QLatin1String("-std=c++20")); + break; + case LanguageVersion::CXX2b: + option = (gnuExtensions ? QLatin1String("-std=gnu++2b") : QLatin1String("-std=c++2b")); break; case LanguageVersion::None: break; @@ -868,6 +874,14 @@ void CompilerOptionsBuilder::evaluateCompilerFlags() theOption[0] = '-'; } + // Clang-cl (as of Clang 12) frontend doesn't know about -std:c++20 + // but the clang front end knows about -std=c++20 + // https://github.com/llvm/llvm-project/blob/release/12.x/clang/lib/Driver/ToolChains/Clang.cpp#L5855 + if (toolChain == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID || + toolChain == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID) { + theOption.replace("-std:c++20", "-clang:-std=c++20"); + } + m_compilerFlags.flags.append(theOption); } diff --git a/src/plugins/cpptools/cppcodemodelinspectordumper.cpp b/src/plugins/cpptools/cppcodemodelinspectordumper.cpp index efaf909c55f..44c968e10b2 100644 --- a/src/plugins/cpptools/cppcodemodelinspectordumper.cpp +++ b/src/plugins/cpptools/cppcodemodelinspectordumper.cpp @@ -123,7 +123,8 @@ QString Utils::toString(::Utils::LanguageVersion languageVersion) CASE_LANGUAGEVERSION(CXX11); CASE_LANGUAGEVERSION(CXX14); CASE_LANGUAGEVERSION(CXX17); - CASE_LANGUAGEVERSION(CXX2a); + CASE_LANGUAGEVERSION(CXX20); + CASE_LANGUAGEVERSION(CXX2b); // no default to get a compiler warning if anything is added } #undef CASE_LANGUAGEVERSION diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp index b34fd3e4617..d5655e3584d 100644 --- a/src/plugins/projectexplorer/projectmodels.cpp +++ b/src/plugins/projectexplorer/projectmodels.cpp @@ -235,7 +235,7 @@ QVariant FlatModel::data(const QModelIndex &index, int role) const } case Qt::DecorationRole: { if (!folderNode) - return Core::FileIconProvider::icon(node->filePath()); + return node->asFileNode()->icon(); if (!project) return folderNode->icon(); static QIcon warnIcon = Utils::Icons::WARNING.icon(); diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index 161eccdd2e2..69fcd50c1a8 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -44,6 +44,7 @@ #include <utils/pointeralgorithm.h> #include <utils/qtcassert.h> #include <utils/stringutils.h> +#include <utils/utilsicons.h> #include <QDir> #include <QFileInfo> @@ -252,6 +253,35 @@ bool Node::isEnabled() const return parent ? parent->isEnabled() : true; } +QIcon FileNode::icon() const +{ + if (hasError()) + return Utils::Icons::WARNING.icon(); + if (m_icon.isNull()) + m_icon = Core::FileIconProvider::icon(filePath()); + return m_icon; +} + +void FileNode::setIcon(const QIcon icon) +{ + m_icon = icon; +} + +bool FileNode::hasError() const +{ + return m_hasError; +} + +void FileNode::setHasError(bool error) +{ + m_hasError = error; +} + +void FileNode::setHasError(bool error) const +{ + m_hasError = error; +} + /*! Returns \c true if the file is automatically generated by a compile step. */ diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h index c416d6d6529..c5cd68a4c53 100644 --- a/src/plugins/projectexplorer/projectnodes.h +++ b/src/plugins/projectexplorer/projectnodes.h @@ -218,8 +218,17 @@ public: bool supportsAction(ProjectAction action, const Node *node) const override; QString displayName() const override; + bool hasError() const; + void setHasError(const bool error); + void setHasError(const bool error) const; + + QIcon icon() const; + void setIcon(const QIcon icon); + private: FileType m_fileType; + mutable QIcon m_icon; + mutable bool m_hasError = false; }; // Documentation inside. diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index e578445ac49..182c1c1a7f5 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -10,6 +10,7 @@ add_qtc_plugin(QmlDesigner DEFINES DESIGNER_CORE_LIBRARY IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\" + SHARE_QML_PATH="${CMAKE_CURRENT_SOURCE_DIR}/../../../share/qtcreator/qmldesigner" PUBLIC_INCLUDES "${CMAKE_CURRENT_LIST_DIR}" "${CMAKE_CURRENT_LIST_DIR}/designercore/include" diff --git a/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp b/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp index f98a32b9698..5a405098039 100644 --- a/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp +++ b/src/plugins/qmldesigner/components/componentcore/changestyleaction.cpp @@ -48,6 +48,24 @@ static QString styleConfigFileName(const QString &qmlFileName) ChangeStyleWidgetAction::ChangeStyleWidgetAction(QObject *parent) : QWidgetAction(parent) { + // The Default style was renamed to Basic in Qt 6. In Qt 6, "Default" + // will result in a platform-specific style being chosen. + items = { + {"Basic", "Basic", {}}, + {"Default", "Default", {}}, + {"Fusion", "Fusion", {}}, + {"Imagine", "Imagine", {}}, + {"Material Light", "Material", "Light"}, + {"Material Dark", "Material", "Dark"}, + {"Universal Light", "Universal", "Light"}, + {"Universal Dark", "Universal", "Dark"}, + {"Universal System", "Universal", "System"} + }; + + if (Utils::HostOsInfo::isMacHost()) + items.append({"macOS", "macOS", {}}); + if (Utils::HostOsInfo::isWindowsHost()) + items.append({"Windows", "Windows", {}}); } void ChangeStyleWidgetAction::handleModelUpdate(const QString &style) @@ -55,6 +73,48 @@ void ChangeStyleWidgetAction::handleModelUpdate(const QString &style) emit modelUpdated(style); } +const QList<StyleWidgetEntry> ChangeStyleWidgetAction::styleItems() const +{ + return items; +} + +void ChangeStyleWidgetAction::changeStyle(const QString &style) +{ + if (style.isEmpty()) + return; + + const Utils::FilePath configFileName = Utils::FilePath::fromString(styleConfigFileName(qmlFileName)); + + if (configFileName.exists()) { + QSettings infiFile(configFileName.toString(), QSettings::IniFormat); + + int contains = -1; + + for (const auto &item : qAsConst(items)) { + if (item.displayName == style) { + contains = items.indexOf(item); + break; + } + } + + if (contains >= 0) { + const QString styleName = items.at(contains).styleName; + const QString styleTheme = items.at(contains).styleTheme; + + infiFile.setValue("Controls/Style", styleName); + + if (!styleTheme.isEmpty()) + infiFile.setValue((styleName + "/Theme"), styleTheme); + } + else { + infiFile.setValue("Controls/Style", style); + } + + if (view) + view->resetPuppet(); + } +} + const char enabledTooltip[] = QT_TRANSLATE_NOOP("ChangeStyleWidgetAction", "Change style for Qt Quick Controls 2."); const char disbledTooltip[] = QT_TRANSLATE_NOOP("ChangeStyleWidgetAction", @@ -64,18 +124,10 @@ QWidget *ChangeStyleWidgetAction::createWidget(QWidget *parent) { auto comboBox = new QComboBox(parent); comboBox->setToolTip(tr(enabledTooltip)); - // The Default style was renamed to Basic in Qt 6. In Qt 6, "Default" - // will result in a platform-specific style being chosen. - comboBox->addItem("Basic"); - comboBox->addItem("Default"); - comboBox->addItem("Fusion"); - comboBox->addItem("Imagine"); - if (Utils::HostOsInfo::isMacHost()) - comboBox->addItem("macOS"); - comboBox->addItem("Material"); - comboBox->addItem("Universal"); - if (Utils::HostOsInfo::isWindowsHost()) - comboBox->addItem("Windows"); + + for (const auto &item : qAsConst(items)) + comboBox->addItem(item.displayName); + comboBox->setEditable(true); comboBox->setCurrentIndex(0); @@ -97,23 +149,8 @@ QWidget *ChangeStyleWidgetAction::createWidget(QWidget *parent) } }); - connect(comboBox, - &QComboBox::textActivated, - this, - [this](const QString &style) { - - if (style.isEmpty()) - return; - - const Utils::FilePath configFileName = Utils::FilePath::fromString(styleConfigFileName(qmlFileName)); - - if (configFileName.exists()) { - QSettings infiFile(configFileName.toString(), QSettings::IniFormat); - infiFile.setValue("Controls/Style", style); - if (view) - view->resetPuppet(); - } - }); + connect(comboBox, &QComboBox::textActivated, + this, &ChangeStyleWidgetAction::changeStyle); return comboBox; } @@ -135,11 +172,27 @@ void ChangeStyleAction::currentContextChanged(const SelectionContext &selectionC if (Utils::FilePath::fromString(confFileName).exists()) { QSettings infiFile(confFileName, QSettings::IniFormat); - m_action->handleModelUpdate(infiFile.value("Controls/Style", "Basic").toString()); + const QString styleName = infiFile.value("Controls/Style", "Basic").toString(); + const QString styleTheme = infiFile.value(styleName + "/Theme", "").toString(); + const auto items = m_action->styleItems(); + + QString comboBoxEntry = styleName; + + for (const auto &item : items) { + if (item.styleName == styleName) { + if (!styleTheme.isEmpty() && (item.styleTheme == styleTheme)) { + comboBoxEntry.append(" "); + comboBoxEntry.append(styleTheme); + + break; + } + } + } + + m_action->handleModelUpdate(comboBoxEntry); } else { m_action->handleModelUpdate(""); } - } } diff --git a/src/plugins/qmldesigner/components/componentcore/changestyleaction.h b/src/plugins/qmldesigner/components/componentcore/changestyleaction.h index fe6d275e12c..fab1b9de50c 100644 --- a/src/plugins/qmldesigner/components/componentcore/changestyleaction.h +++ b/src/plugins/qmldesigner/components/componentcore/changestyleaction.h @@ -38,6 +38,24 @@ namespace QmlDesigner { class AbstractView; +struct StyleWidgetEntry { + QString displayName; + + QString styleName; + QString styleTheme; + + bool operator==(const StyleWidgetEntry &entry) const { + if (displayName != entry.displayName) + return false; + if (styleName != entry.styleName) + return false; + if (styleTheme != entry.styleTheme) + return false; + + return true; + }; +}; + class ChangeStyleWidgetAction : public QWidgetAction { Q_OBJECT @@ -46,6 +64,11 @@ public: explicit ChangeStyleWidgetAction(QObject *parent = nullptr); void handleModelUpdate(const QString &style); + const QList<StyleWidgetEntry> styleItems() const; + +public slots: + void changeStyle(const QString &style); + protected: QWidget *createWidget(QWidget *parent) override; @@ -55,6 +78,8 @@ signals: public: QString qmlFileName; QPointer<AbstractView> view; + + QList<StyleWidgetEntry> items; }; class ChangeStyleAction : public ActionInterface diff --git a/src/plugins/qmldesigner/components/componentcore/theme.cpp b/src/plugins/qmldesigner/components/componentcore/theme.cpp index a2fea95603d..6fe7afe7603 100644 --- a/src/plugins/qmldesigner/components/componentcore/theme.cpp +++ b/src/plugins/qmldesigner/components/componentcore/theme.cpp @@ -128,7 +128,7 @@ QString Theme::replaceCssColors(const QString &input) void Theme::setupTheme(QQmlEngine *engine) { static const int typeIndex = qmlRegisterSingletonType<Theme>( - "QtQuickDesignerTheme", 1, 0, "Theme", [](QQmlEngine *engine, QJSEngine *) { + "QtQuickDesignerTheme", 1, 0, "Theme", [](QQmlEngine *, QJSEngine *) { return new Theme(Utils::creatorTheme(), nullptr); }); Q_UNUSED(typeIndex) diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index d70d0c19bf8..1a38eb509ef 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -79,6 +79,10 @@ namespace QmlDesigner { static QString propertyEditorResourcesPath() { +#ifdef SHARE_QML_PATH + if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources"; +#endif return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString(); } @@ -376,6 +380,10 @@ void ItemLibraryWidget::handleTabChanged(int index) QString ItemLibraryWidget::qmlSourcesPath() { +#ifdef SHARE_QML_PATH + if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + return QLatin1String(SHARE_QML_PATH) + "/itemLibraryQmlSources"; +#endif return Core::ICore::resourcePath("qmldesigner/itemLibraryQmlSources").toString(); } diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index 95586fa2eeb..2606ea83a49 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -46,6 +46,10 @@ #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/icore.h> +#include <projectexplorer/project.h> +#include <projectexplorer/session.h> +#include <projectexplorer/projectnodes.h> + #include <utils/algorithm.h> #include <utils/icon.h> #include <utils/utilsicons.h> @@ -169,6 +173,29 @@ void NavigatorView::modelAttached(Model *model) } } }); + + clearExplorerWarnings(); +} + +void NavigatorView::clearExplorerWarnings() +{ + QList<ModelNode> allNodes; + addNodeAndSubModelNodesToList(rootModelNode(), allNodes); + for (ModelNode node : allNodes) { + if (node.metaInfo().isFileComponent()) { + const ProjectExplorer::FileNode *fnode = fileNodeForModelNode(node); + if (fnode) + fnode->setHasError(false); + } + } +} + +void NavigatorView::addNodeAndSubModelNodesToList(const ModelNode &node, QList<ModelNode> &nodes) +{ + nodes.append(node); + for (ModelNode subNode : node.allSubModelNodes()) { + addNodeAndSubModelNodesToList(subNode, nodes); + } } void NavigatorView::modelAboutToBeDetached(Model *model) @@ -342,8 +369,10 @@ void NavigatorView::auxiliaryDataChanged(const ModelNode &modelNode, void NavigatorView::instanceErrorChanged(const QVector<ModelNode> &errorNodeList) { - for (const ModelNode &modelNode : errorNodeList) + for (const ModelNode &modelNode : errorNodeList) { m_currentModelInterface->notifyDataChanged(modelNode); + propagateInstanceErrorToExplorer(modelNode); + } } void NavigatorView::nodeOrderChanged(const NodeListProperty &listProperty) @@ -374,6 +403,52 @@ QAbstractItemModel *NavigatorView::currentModel() const return treeWidget()->model(); } +const ProjectExplorer::FileNode *NavigatorView::fileNodeForModelNode(const ModelNode &node) const +{ + QString filename = node.metaInfo().componentFileName(); + Utils::FilePath filePath = Utils::FilePath::fromString(filename); + ProjectExplorer::Project *currentProject = ProjectExplorer::SessionManager::projectForFile( + filePath); + + if (!currentProject) { + filePath = Utils::FilePath::fromString(node.model()->fileUrl().toLocalFile()); + + /* If the component does not belong to the project then we can fallback to the current file */ + currentProject = ProjectExplorer::SessionManager::projectForFile(filePath); + } + if (!currentProject) + return nullptr; + + return currentProject->nodeForFilePath(filePath)->asFileNode(); +} + +const ProjectExplorer::FileNode *NavigatorView::fileNodeForIndex(const QModelIndex &index) const +{ + if (index.isValid() && currentModel()->data(index, Qt::UserRole).isValid()) { + ModelNode node = modelNodeForIndex(index); + if (node.metaInfo().isFileComponent()) { + return fileNodeForModelNode(node); + } + } + + return nullptr; +} + +void NavigatorView::propagateInstanceErrorToExplorer(const ModelNode &modelNode) { + QModelIndex index = indexForModelNode(modelNode);; + + do { + const ProjectExplorer::FileNode *fnode = fileNodeForIndex(index); + if (fnode) { + fnode->setHasError(true); + return; + } + else { + index = index.parent(); + } + } while (index.isValid()); +} + void NavigatorView::leftButtonClicked() { if (selectedModelNodes().count() > 1) diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.h b/src/plugins/qmldesigner/components/navigator/navigatorview.h index 7e811ca39f3..c779522baa7 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.h +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.h @@ -28,6 +28,7 @@ #include "navigatormodelinterface.h" #include <abstractview.h> +#include <projectexplorer/projectnodes.h> #include <QPointer> #include <QHash> @@ -108,6 +109,7 @@ private: void changeToComponent(const QModelIndex &index); QModelIndex indexForModelNode(const ModelNode &modelNode) const; QAbstractItemModel *currentModel() const; + void propagateInstanceErrorToExplorer(const ModelNode &modelNode); void leftButtonClicked(); void rightButtonClicked(); @@ -123,6 +125,10 @@ protected: //functions void expandAncestors(const QModelIndex &index); void reparentAndCatch(NodeAbstractProperty property, const ModelNode &modelNode); void setupWidget(); + void addNodeAndSubModelNodesToList(const ModelNode &node, QList<ModelNode> &nodes); + void clearExplorerWarnings(); + const ProjectExplorer::FileNode *fileNodeForModelNode(const ModelNode &node) const; + const ProjectExplorer::FileNode *fileNodeForIndex(const QModelIndex &index) const; private: bool m_blockSelectionChangedSignal; diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp index 4dbe773adb5..5adce7e9328 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp @@ -47,8 +47,9 @@ #include <QApplication> #include <QDir> #include <QFileInfo> -#include <QVector3D> #include <QVector2D> +#include <QVector3D> +#include <QVector4D> #include <QLoggingCategory> @@ -343,6 +344,18 @@ void PropertyEditorQmlBackend::setValue(const QmlObjectNode & , const PropertyNa if (propertyValue) propertyValue->setValue(QVariant(vecValue[i])); } + } else if (value.type() == QVariant::Vector4D) { + const char *suffix[4] = {"_x", "_y", "_z", "_w"}; + auto vecValue = value.value<QVector4D>(); + for (int i = 0; i < 4; ++i) { + PropertyName subPropName(name.size() + 2, '\0'); + subPropName.replace(0, name.size(), name); + subPropName.replace(name.size(), 2, suffix[i]); + auto propertyValue = qobject_cast<PropertyEditorValue *>( + variantToQObject(m_backendValuesPropertyMap.value(QString::fromUtf8(subPropName)))); + if (propertyValue) + propertyValue->setValue(QVariant(vecValue[i])); + } } else { PropertyName propertyName = name; propertyName.replace('.', '_'); @@ -532,6 +545,10 @@ void PropertyEditorQmlBackend::initialSetup(const TypeName &typeName, const QUrl QString PropertyEditorQmlBackend::propertyEditorResourcesPath() { +#ifdef SHARE_QML_PATH + if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources"; +#endif return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString(); } diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp index abdfc2ebd4b..6fa649e699e 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorview.cpp @@ -227,14 +227,21 @@ void PropertyEditorView::changeValue(const QString &name) removePropertyFromModel(propertyName); } else { // QVector*D(0, 0, 0) detects as null variant though it is valid value - if (castedValue.isValid() && (!castedValue.isNull() - || castedValue.type() == QVariant::Vector2D - || castedValue.type() == QVariant::Vector3D)) { + if (castedValue.isValid() + && (!castedValue.isNull() || castedValue.type() == QVariant::Vector2D + || castedValue.type() == QVariant::Vector3D + || castedValue.type() == QVariant::Vector4D)) { commitVariantValueToModel(propertyName, castedValue); } } } +static bool isTrueFalseLiteral(const QString &expression) +{ + return (expression.compare("false", Qt::CaseInsensitive) == 0) + || (expression.compare("true", Qt::CaseInsensitive) == 0); +} + void PropertyEditorView::changeExpression(const QString &propertyName) { PropertyName name = propertyName.toUtf8(); @@ -267,9 +274,8 @@ void PropertyEditorView::changeExpression(const QString &propertyName) return; } } else if (qmlObjectNode->modelNode().metaInfo().propertyTypeName(name) == "bool") { - if (value->expression().compare(QLatin1String("false"), Qt::CaseInsensitive) == 0 - || value->expression().compare(QLatin1String("true"), Qt::CaseInsensitive) == 0) { - if (value->expression().compare(QLatin1String("true"), Qt::CaseInsensitive) == 0) + if (isTrueFalseLiteral(value->expression())) { + if (value->expression().compare("true", Qt::CaseInsensitive) == 0) qmlObjectNode->setVariantProperty(name, true); else qmlObjectNode->setVariantProperty(name, false); @@ -289,6 +295,19 @@ void PropertyEditorView::changeExpression(const QString &propertyName) qmlObjectNode->setVariantProperty(name, realValue); return; } + } else if (qmlObjectNode->modelNode().metaInfo().propertyTypeName(name) == "QVariant") { + bool ok; + qreal realValue = value->expression().toDouble(&ok); + if (ok) { + qmlObjectNode->setVariantProperty(name, realValue); + return; + } else if (isTrueFalseLiteral(value->expression())) { + if (value->expression().compare("true", Qt::CaseInsensitive) == 0) + qmlObjectNode->setVariantProperty(name, true); + else + qmlObjectNode->setVariantProperty(name, false); + return; + } } } diff --git a/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp b/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp index dc3ed7c30ee..aecab7c42ce 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/qmlanchorbindingproxy.cpp @@ -894,7 +894,8 @@ QmlItemNode QmlAnchorBindingProxy::targetIdToNode(const QString &id) const QString QmlAnchorBindingProxy::idForNode(const QmlItemNode &qmlItemNode) const { - QTC_ASSERT(qmlItemNode.modelNode().isValid(), return {}); + if (!qmlItemNode.modelNode().isValid()) + return {}; if (!qmlItemNode.isValid()) return qmlItemNode.id(); diff --git a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp index 2bc45e3b12e..d94f21bd352 100644 --- a/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp +++ b/src/plugins/qmldesigner/components/stateseditor/stateseditorwidget.cpp @@ -58,6 +58,10 @@ namespace QmlDesigner { static QString propertyEditorResourcesPath() { +#ifdef SHARE_QML_PATH + if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + return QLatin1String(SHARE_QML_PATH) + "/propertyEditorQmlSources"; +#endif return Core::ICore::resourcePath("qmldesigner/propertyEditorQmlSources").toString(); } @@ -122,6 +126,10 @@ StatesEditorWidget::~StatesEditorWidget() = default; QString StatesEditorWidget::qmlSourcesPath() { +#ifdef SHARE_QML_PATH + if (qEnvironmentVariableIsSet("LOAD_QML_FROM_SOURCE")) + return QLatin1String(SHARE_QML_PATH) + "/statesEditorQmlSources"; +#endif return Core::ICore::resourcePath("qmldesigner/statesEditorQmlSources").toString(); } diff --git a/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp b/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp index 91bb2c30711..453df15d325 100644 --- a/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp +++ b/src/plugins/qmldesigner/designercore/instances/nodeinstance.cpp @@ -32,8 +32,9 @@ #include <QDebug> #include <QPainter> -#include <QVector3D> #include <QVector2D> +#include <QVector3D> +#include <QVector4D> QT_BEGIN_NAMESPACE void qt_blurImage(QPainter *painter, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0); @@ -352,6 +353,28 @@ QVariant NodeInstance::property(const PropertyName &name) const break; } return QVariant(subValue); + } else if (varValue.type() == QVariant::Vector4D) { + auto value = varValue.value<QVector4D>(); + char subProp = name.right(1)[0]; + float subValue = 0.f; + switch (subProp) { + case 'x': + subValue = value.x(); + break; + case 'y': + subValue = value.y(); + break; + case 'z': + subValue = value.z(); + break; + case 'w': + subValue = value.w(); + break; + default: + subValue = 0.f; + break; + } + return QVariant(subValue); } } } @@ -443,6 +466,24 @@ void NodeInstance::setProperty(const PropertyName &name, const QVariant &value) update = true; } newValueVar = newValue; + } else if (oldValue.type() == QVariant::Vector4D) { + QVector4D newValue; + if (oldValue.type() == QVariant::Vector4D) + newValue = oldValue.value<QVector4D>(); + if (name.endsWith(".x")) { + newValue.setX(value.toFloat()); + update = true; + } else if (name.endsWith(".y")) { + newValue.setY(value.toFloat()); + update = true; + } else if (name.endsWith(".z")) { + newValue.setZ(value.toFloat()); + update = true; + } else if (name.endsWith(".w")) { + newValue.setW(value.toFloat()); + update = true; + } + newValueVar = newValue; } if (update) { d->propertyValues.insert(parentPropName, newValueVar); diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index 7eacf171971..33693210a99 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -349,15 +349,35 @@ private: static inline bool isValueType(const TypeName &type) { - static const PropertyTypeList objectValuesList({"QFont", "QPoint", "QPointF", - "QSize", "QSizeF", "QVector3D", "QVector2D", "vector2d", "vector3d", "font"}); + static const PropertyTypeList objectValuesList({"QFont", + "QPoint", + "QPointF", + "QSize", + "QSizeF", + "QVector2D", + "QVector3D", + "QVector4D", + "vector2d", + "vector3d", + "vector4d", + "font"}); return objectValuesList.contains(type); } static inline bool isValueType(const QString &type) { - static const QStringList objectValuesList({"QFont", "QPoint", "QPointF", - "QSize", "QSizeF", "QVector3D", "QVector2D", "vector2d", "vector3d", "font"}); + static const QStringList objectValuesList({"QFont", + "QPoint", + "QPointF", + "QSize", + "QSizeF", + "QVector2D", + "QVector3D", + "QVector4D", + "vector2d", + "vector3d", + "vector4d", + "font"}); return objectValuesList.contains(type); } @@ -1091,6 +1111,9 @@ QVariant::Type NodeMetaInfoPrivate::variantTypeId(const PropertyName &propertyNa if (typeName == "vector3d") return QVariant::Vector3D; + if (typeName == "vector4d") + return QVariant::Vector4D; + return QVariant::nameToType(typeName.data()); } diff --git a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp b/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp index 0a22c352b27..51cb503d81e 100644 --- a/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp +++ b/src/plugins/qmldesigner/designercore/model/qmltextgenerator.cpp @@ -27,6 +27,7 @@ #include <QVariant> #include <QColor> +#include <QVector4D> #include <QVector3D> #include <QVector2D> @@ -169,6 +170,14 @@ QString QmlTextGenerator::toQml(const AbstractProperty &property, int indentDept auto vec = value.value<QVector3D>(); return QStringLiteral("Qt.vector3d(%1, %2, %3)").arg(vec.x()).arg(vec.y()).arg(vec.z()); } + case QMetaType::QVector4D: { + auto vec = value.value<QVector4D>(); + return QStringLiteral("Qt.vector4d(%1, %2, %3, %4)") + .arg(vec.x()) + .arg(vec.y()) + .arg(vec.z()) + .arg(vec.w()); + } default: return QStringLiteral("\"%1\"").arg(escape(stringValue)); } diff --git a/src/plugins/qmldesigner/designercore/model/rewriteaction.cpp b/src/plugins/qmldesigner/designercore/model/rewriteaction.cpp index 2b12f03b2b5..38e9427892e 100644 --- a/src/plugins/qmldesigner/designercore/model/rewriteaction.cpp +++ b/src/plugins/qmldesigner/designercore/model/rewriteaction.cpp @@ -83,7 +83,7 @@ bool AddPropertyRewriteAction::execute(QmlRefactoring &refactoring, ModelNodePos const int nodeLocation = positionStore.nodeOffset(m_property.parentModelNode()); bool result = false; - if (m_property.isDefaultProperty()) { + if (m_propertyType != QmlRefactoring::ScriptBinding && m_property.isDefaultProperty()) { result = refactoring.addToObjectMemberList(nodeLocation, m_valueText); if (!result) { @@ -187,7 +187,7 @@ bool ChangePropertyRewriteAction::execute(QmlRefactoring &refactoring, ModelNode } bool result = false; - if (m_property.isDefaultProperty()) { + if (m_propertyType != QmlRefactoring::ScriptBinding && m_property.isDefaultProperty()) { result = refactoring.addToObjectMemberList(nodeLocation, m_valueText); if (!result) { diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 5d431331125..3c6a64d02c2 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -824,10 +824,9 @@ void TextToModelMerger::setupImports(const Document::Ptr &doc, differenceHandler.modelMissesImport(newImport); } else { QString importUri = toString(import->importUri); - if (version.isEmpty()) { - version = getHighestPossibleImport(importUri); + if (version.isEmpty()) m_hasVersionlessImport = true; - } + const Import newImport = Import::createLibraryImport(importUri, version, as, diff --git a/src/plugins/qmldesigner/qmldesignerplugin.pro b/src/plugins/qmldesigner/qmldesignerplugin.pro index 6ed8535da36..41e7568ff7e 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.pro +++ b/src/plugins/qmldesigner/qmldesignerplugin.pro @@ -42,3 +42,7 @@ BUILD_PUPPET_IN_CREATOR_BINPATH = $$(BUILD_PUPPET_IN_CREATOR_BINPATH) DEFINES += SEARCH_PUPPET_IN_CREATOR_BINPATH message("Search puppet in qtcreator bin path!") } + +SHARE_QML_PATH = "$${PWD}/../../../share/qtcreator/qmldesigner" + +DEFINES += SHARE_QML_PATH=\\\"$${SHARE_QML_PATH}\\\" diff --git a/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml b/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml index 860e7b0f564..e7ef726611e 100644 --- a/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml +++ b/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml @@ -235,6 +235,13 @@ Rectangle { id: doNotShowCheckBox text: qsTr("Do not show this again") padding: 0 + spacing: 12 + + contentItem: Text { + text: doNotShowCheckBox.text + color: "#ffffff" + leftPadding: doNotShowCheckBox.indicator.width + doNotShowCheckBox.spacing + } } CheckBox { @@ -242,8 +249,15 @@ Rectangle { text: qsTr("Enable Usage Statistics") checked: usageStatisticModel.usageStatisticEnabled padding: 0 + spacing: 12 onCheckedChanged: usageStatisticModel.setTelemetryEnabled(usageStatisticCheckBox.checked) + + contentItem: Text { + text: usageStatisticCheckBox.text + color: "#ffffff" + leftPadding: usageStatisticCheckBox.indicator.width + usageStatisticCheckBox.spacing + } } } diff --git a/src/share/3rdparty/package-manager/auto-setup.cmake b/src/share/3rdparty/package-manager/auto-setup.cmake index ba25ae56671..50519f30af8 100644 --- a/src/share/3rdparty/package-manager/auto-setup.cmake +++ b/src/share/3rdparty/package-manager/auto-setup.cmake @@ -14,6 +14,7 @@ endif() if (QT_CREATOR_SKIP_PACKAGE_MANAGER_SETUP) return() endif() +option(QT_CREATOR_SKIP_PACKAGE_MANAGER_SETUP "Skip Qt Creator's package manager auto-setup" OFF) # # conan @@ -27,6 +28,7 @@ foreach(file conanfile.txt conanfile.py) endforeach() if (conanfile_txt AND NOT QT_CREATOR_SKIP_CONAN_SETUP) + option(QT_CREATOR_SKIP_CONAN_SETUP "Skip Qt Creator's conan package manager auto-setup" OFF) # Get conan from Qt SDK set(qt_creator_ini "${CMAKE_CURRENT_LIST_DIR}/../QtProject/QtCreator.ini") @@ -108,6 +110,8 @@ unset(conanfile_txt) # if (EXISTS "${CMAKE_SOURCE_DIR}/vcpkg.json" AND NOT QT_CREATOR_SKIP_VCPKG_SETUP) + option(QT_CREATOR_SKIP_VCPKG_SETUP "Skip Qt Creator's vcpkg package manager auto-setup" OFF) + find_program(vcpkg_program vcpkg) if (NOT vcpkg_program) return() diff --git a/src/shared/qbs b/src/shared/qbs -Subproject 1d0a0a9c2af318c8e3e7bd4be444854ab8f4ae3 +Subproject 893e985449b1db91195966884f4b743bf08b3f9 diff --git a/tests/auto/tracing/flamegraphview/CMakeLists.txt b/tests/auto/tracing/flamegraphview/CMakeLists.txt index a1e900b7288..a35961bc524 100644 --- a/tests/auto/tracing/flamegraphview/CMakeLists.txt +++ b/tests/auto/tracing/flamegraphview/CMakeLists.txt @@ -18,7 +18,7 @@ else() # < Qt 6.2 qt_add_qml_module(tst_tracing_flamegraphview URI "QtCreator.TstTracingFlameGraphView" VERSION "1.0" - NO_CREATE_PLUGIN_TARGET + NO_PLUGIN QML_FILES TestFlameGraphView.qml SOURCES diff --git a/tests/auto/utils/indexedcontainerproxyconstiterator/tst_indexedcontainerproxyconstiterator.cpp b/tests/auto/utils/indexedcontainerproxyconstiterator/tst_indexedcontainerproxyconstiterator.cpp index f0dceb0eb24..b60b5cf114d 100644 --- a/tests/auto/utils/indexedcontainerproxyconstiterator/tst_indexedcontainerproxyconstiterator.cpp +++ b/tests/auto/utils/indexedcontainerproxyconstiterator/tst_indexedcontainerproxyconstiterator.cpp @@ -83,7 +83,7 @@ void tst_IndexedContainerProxyConstIterator::testDereference() { StringIterator strIt(strings, 0); QCOMPARE(*strIt, "abc"); - QCOMPARE(strIt->length(), 3); + QCOMPARE(int(strIt->length()), 3); BoolIterator boolIt(bools, 0); QCOMPARE(*boolIt, false); diff --git a/tests/system/shared/utils.py b/tests/system/shared/utils.py index c34e39af7b8..dedd43179c2 100644 --- a/tests/system/shared/utils.py +++ b/tests/system/shared/utils.py @@ -317,7 +317,7 @@ def addCurrentCreatorDocumentation(): selectFromFileDialog(docPath) try: waitForObject("{type='QMessageBox' unnamed='1' visible='1' " - "text?='Unable to register documentation.*'}", 3000) + "text~='Unable to register documentation.*'}", 3000) test.passes("Qt Creator's documentation found already registered.") clickButton(waitForObject("{type='QPushButton' text='OK' unnamed='1' visible='1' " "container={name='groupBox' type='QGroupBox' visible='1'}}")) @@ -619,8 +619,8 @@ def clickOnTab(tabBarStr, tabText, timeout=5000): if not waitFor("object.exists(tabBarStr)", timeout): raise LookupError("Could not find QTabBar: %s" % objectMap.realName(tabBarStr)) tabBar = findObject(tabBarStr) - if platform.system() == 'Darwin' and not tabBar.visible: - test.log("Using workaround for Mac.") + if not (platform.system() == 'Linux' or tabBar.visible): + test.log("Using workaround for Mac and Windows.") setWindowState(tabBar, WindowState.Normal) tabBar = waitForObject(tabBarStr, 2000) clickTab(tabBar, tabText) diff --git a/tests/system/suite_editors/tst_memberoperator/test.py b/tests/system/suite_editors/tst_memberoperator/test.py index 3c3625b61b5..a971adb1552 100644 --- a/tests/system/suite_editors/tst_memberoperator/test.py +++ b/tests/system/suite_editors/tst_memberoperator/test.py @@ -51,10 +51,10 @@ def main(): selectBuildConfig(Targets.DESKTOP_5_10_1_DEFAULT, "Debug") checkCodeModelSettings(useClang) selectFromLocator("main.cpp") - cppwindow = waitForObject(":Qt Creator_CppEditor::Internal::CPPEditorWidget") for record in testData.dataset("usages.tsv"): include = testData.field(record, "include") + cppwindow = waitForObject(":Qt Creator_CppEditor::Internal::CPPEditorWidget") if include: placeCursorToLine(cppwindow, "#include <QCoreApplication>") typeLines(cppwindow, ("", "#include " + include)) diff --git a/tests/system/suite_editors/tst_memberoperator/testdata/usages.tsv b/tests/system/suite_editors/tst_memberoperator/testdata/usages.tsv index daecc37c7ac..89831a431bb 100644 --- a/tests/system/suite_editors/tst_memberoperator/testdata/usages.tsv +++ b/tests/system/suite_editors/tst_memberoperator/testdata/usages.tsv @@ -4,7 +4,7 @@ "" "" "argv[0]" "." "argv[0]." "False" "" "" "" "2" "." "2." "False" "" "" "" "float fl = 2" "." "float fl = 2." "False" "" -"" "QCoreApplication qa;" "qa" "." "qa." "False" "" +"" "QCoreApplication qa;" "qa" "." "qa." "True" "none" "" "QCoreApplication *p;" "p" "." "p->" "True" "all" "" "QCoreApplication &ref = a;" "ref" "." "ref." "True" "none" "<QPointer>" "QPointer<QCoreApplication> p;" "p" "." "p." "True" "mixed" diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp index 53909d086ed..f158d4536b7 100644 --- a/tests/unit/unittest/gtest-creator-printing.cpp +++ b/tests/unit/unittest/gtest-creator-printing.cpp @@ -105,8 +105,10 @@ const char * toText(Utils::LanguageVersion languageVersion) return "CXX14"; case LanguageVersion::CXX17: return "CXX17"; - case LanguageVersion::CXX2a: - return "CXX2a"; + case LanguageVersion::CXX20: + return "CXX20"; + case LanguageVersion::CXX2b: + return "CXX2b"; case LanguageVersion::CXX98: return "CXX98"; case LanguageVersion::None: |