diff --git a/doc/qtcreator/images/qml-profiler-flamegraph.png b/doc/qtcreator/images/qml-profiler-flamegraph.png index 4e6c694385b..52efcb7e2f8 100644 Binary files a/doc/qtcreator/images/qml-profiler-flamegraph.png and b/doc/qtcreator/images/qml-profiler-flamegraph.png differ diff --git a/doc/qtcreator/images/qml-profiler-settings.png b/doc/qtcreator/images/qml-profiler-settings.png index 5d2b78d56d3..e8d61203467 100644 Binary files a/doc/qtcreator/images/qml-profiler-settings.png and b/doc/qtcreator/images/qml-profiler-settings.png differ diff --git a/doc/qtcreator/images/qml-profiler-start-dialog.png b/doc/qtcreator/images/qml-profiler-start-dialog.png new file mode 100644 index 00000000000..a2cf7bd07c2 Binary files /dev/null and b/doc/qtcreator/images/qml-profiler-start-dialog.png differ diff --git a/doc/qtcreator/images/qml-profiler-statistics.png b/doc/qtcreator/images/qml-profiler-statistics.png index d45b950c2c8..93bdf001456 100644 Binary files a/doc/qtcreator/images/qml-profiler-statistics.png and b/doc/qtcreator/images/qml-profiler-statistics.png differ diff --git a/doc/qtcreator/images/qtcreator-embedded-linux-deployment-details.png b/doc/qtcreator/images/qtcreator-embedded-linux-deployment-details.png index f63b4c38b5c..6f7886894d9 100644 Binary files a/doc/qtcreator/images/qtcreator-embedded-linux-deployment-details.png and b/doc/qtcreator/images/qtcreator-embedded-linux-deployment-details.png differ diff --git a/doc/qtcreator/images/qtcreator-fakevim-options-ex-command-mapping.png b/doc/qtcreator/images/qtcreator-fakevim-options-ex-command-mapping.png new file mode 100644 index 00000000000..acf59567ffc Binary files /dev/null and b/doc/qtcreator/images/qtcreator-fakevim-options-ex-command-mapping.png differ diff --git a/doc/qtcreator/images/qtcreator-fakevim-options-general-plugin-emulation.png b/doc/qtcreator/images/qtcreator-fakevim-options-general-plugin-emulation.png new file mode 100644 index 00000000000..7fcb4dad333 Binary files /dev/null and b/doc/qtcreator/images/qtcreator-fakevim-options-general-plugin-emulation.png differ diff --git a/doc/qtcreator/images/qtcreator-fakevim-options-user-command-mapping.png b/doc/qtcreator/images/qtcreator-fakevim-options-user-command-mapping.png new file mode 100644 index 00000000000..e04cae50b48 Binary files /dev/null and b/doc/qtcreator/images/qtcreator-fakevim-options-user-command-mapping.png differ diff --git a/doc/qtcreator/images/qtcreator-fakevim-options.png b/doc/qtcreator/images/qtcreator-fakevim-options.png index b5aba9b8486..1dfeaa3432b 100644 Binary files a/doc/qtcreator/images/qtcreator-fakevim-options.png and b/doc/qtcreator/images/qtcreator-fakevim-options.png differ diff --git a/doc/qtcreator/images/qtcreator-generic-linux-device-key-deployment.png b/doc/qtcreator/images/qtcreator-generic-linux-device-key-deployment.png new file mode 100644 index 00000000000..cea3c218d45 Binary files /dev/null and b/doc/qtcreator/images/qtcreator-generic-linux-device-key-deployment.png differ diff --git a/doc/qtcreator/images/qtcreator-kit-selector-run-targets.png b/doc/qtcreator/images/qtcreator-kit-selector-run-targets.png new file mode 100644 index 00000000000..4ba57d0fe9f Binary files /dev/null and b/doc/qtcreator/images/qtcreator-kit-selector-run-targets.png differ diff --git a/doc/qtcreator/images/qtcreator-linux-device-configurations.png b/doc/qtcreator/images/qtcreator-linux-device-configurations.png index 0f73327aef4..58d4362da1e 100644 Binary files a/doc/qtcreator/images/qtcreator-linux-device-configurations.png and b/doc/qtcreator/images/qtcreator-linux-device-configurations.png differ diff --git a/doc/qtcreator/images/qtcreator-mime-types-magic-header.png b/doc/qtcreator/images/qtcreator-mime-types-magic-header.png index 25d89d327d3..395a975628e 100644 Binary files a/doc/qtcreator/images/qtcreator-mime-types-magic-header.png and b/doc/qtcreator/images/qtcreator-mime-types-magic-header.png differ diff --git a/doc/qtcreator/images/qtcreator-mime-types.png b/doc/qtcreator/images/qtcreator-mime-types.png index fc453ff1367..e91bbb8c644 100644 Binary files a/doc/qtcreator/images/qtcreator-mime-types.png and b/doc/qtcreator/images/qtcreator-mime-types.png differ diff --git a/doc/qtcreator/images/qtcreator-qml-performance-monitor.png b/doc/qtcreator/images/qtcreator-qml-performance-monitor.png index 6de351818e2..2f256ce3d6d 100644 Binary files a/doc/qtcreator/images/qtcreator-qml-performance-monitor.png and b/doc/qtcreator/images/qtcreator-qml-performance-monitor.png differ diff --git a/doc/qtcreator/images/qtcreator-qnx-deployment.png b/doc/qtcreator/images/qtcreator-qnx-deployment.png index 459540ef66e..6608e121b67 100644 Binary files a/doc/qtcreator/images/qtcreator-qnx-deployment.png and b/doc/qtcreator/images/qtcreator-qnx-deployment.png differ diff --git a/doc/qtcreator/images/qtcreator-screenshot-devconf-linux.png b/doc/qtcreator/images/qtcreator-screenshot-devconf-linux.png index 2696c7f99c4..fa76062961c 100644 Binary files a/doc/qtcreator/images/qtcreator-screenshot-devconf-linux.png and b/doc/qtcreator/images/qtcreator-screenshot-devconf-linux.png differ diff --git a/doc/qtcreator/images/qtcreator-ssh-key-configuration.png b/doc/qtcreator/images/qtcreator-ssh-key-configuration.png index aac22732bda..3f68d72d084 100644 Binary files a/doc/qtcreator/images/qtcreator-ssh-key-configuration.png and b/doc/qtcreator/images/qtcreator-ssh-key-configuration.png differ diff --git a/doc/qtcreator/images/qtcreator-ssh-options.png b/doc/qtcreator/images/qtcreator-ssh-options.png index 43009605325..4b1287c5b50 100644 Binary files a/doc/qtcreator/images/qtcreator-ssh-options.png and b/doc/qtcreator/images/qtcreator-ssh-options.png differ diff --git a/doc/qtcreator/src/android/deploying-android.qdoc b/doc/qtcreator/src/android/deploying-android.qdoc index 7a97cf2b397..362abd7cf3e 100644 --- a/doc/qtcreator/src/android/deploying-android.qdoc +++ b/doc/qtcreator/src/android/deploying-android.qdoc @@ -433,7 +433,8 @@ By default, the splash screen is hidden automatically when an activity is drawn. To keep it visible until - \l{QNativeInterface::QAndroidApplication::hideSplashScreen()} is + \l{https://doc.qt.io/qt-6/qnativeinterface-qandroidapplication.html#hideSplashScreen} + {QNativeInterface::QAndroidApplication::hideSplashScreen()} is called, select the \uicontrol {Sticky splash screen} check box. In \uicontrol {Image show mode}, select whether to center the splash screen diff --git a/doc/qtcreator/src/editors/creator-only/creator-fakevim.qdoc b/doc/qtcreator/src/editors/creator-only/creator-fakevim.qdoc index 120411684da..6d5217e657f 100644 --- a/doc/qtcreator/src/editors/creator-only/creator-fakevim.qdoc +++ b/doc/qtcreator/src/editors/creator-only/creator-fakevim.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2019 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. @@ -118,6 +118,8 @@ for particular plugins, select \uicontrol Tools > \uicontrol Options > \uicontrol FakeVim > \uicontrol General > \uicontrol {Plugin Emulation}. + \image qtcreator-fakevim-options-general-plugin-emulation.png "FakeVim Plugin Emulation options" + Currently emulated plugins: \list \li \l{https://github.com/tpope/vim-commentary}{vim-commentary}: \c gc @@ -129,9 +131,10 @@ register \c x. \li ["x]grr to replace the current line. \endlist - \li \l{https://github.com/tommcdo/vim-exchange}{vim-exchange} \li \l{https://github.com/vim-scripts/argtextobj.vim}{argtextobj.vim}: Defines the \c ia and \c aa text objects for function parameters. + \li \l{https://github.com/tommcdo/vim-exchange}{vim-exchange}: + A text exchange operator for vim. \li \l{https://github.com/tpope/vim-surround}{vim-surround}: Adds mappings for deleting, adding and changing surroundings. \endlist @@ -287,15 +290,29 @@ \section1 Mapping FakeVim Commands - To map commands entered on the \uicontrol FakeVim command line to actions - of the \QC core, select \uicontrol Tools > \uicontrol Options > + To map commands entered on the \uicontrol FakeVim command line to + \QC functions, select \uicontrol Tools > \uicontrol Options > \uicontrol FakeVim > \uicontrol {Ex Command Mapping}. + Enter a string in the \uicontrol Filter field to search for a specific + \QC function. + + \image qtcreator-fakevim-options-ex-command-mapping.png "FakeVim Ex Command Mapping options" + + Select a function in the list, and enter a string that will trigger the + function in the \uicontrol {Regular expression} field. You can view the + trigger expression in the \uicontrol {Ex Trigger Expression} field. To + remove the trigger expression, select \uicontrol Reset. + + To reset the trigger expressions for all functions, select + \uicontrol {Reset All}. To map \e {user commands} to keyboard shortcuts, select \uicontrol Tools > \uicontrol Options > \uicontrol FakeVim > \uicontrol {User Command Mapping}. The user command mapped to the shortcut is executed by FakeVim as if you were typing it (as when replaying a macro). + \image qtcreator-fakevim-options-user-command-mapping.png "FakeVim User Command Mapping options" + \section1 Specifying FakeVim Options To make changes to the Vim-style settings, select \uicontrol Tools > @@ -319,5 +336,6 @@ \uicontrol FakeVim > \uicontrol {Use FakeVim} or press \key {Alt+V,Alt+V}. You can temporarily escape FakeVim mode to access the normal \QC keyboard - shortcuts like \key {Ctrl-R} for \uicontrol Run by pressing \key {,} first. + shortcuts like \key {Ctrl-R} for \uicontrol Run by first pressing the comma + key (\key {,}). */ diff --git a/doc/qtcreator/src/editors/creator-only/creator-mime-types.qdoc b/doc/qtcreator/src/editors/creator-only/creator-mime-types.qdoc index ee04620d422..6c4bf3803e5 100644 --- a/doc/qtcreator/src/editors/creator-only/creator-mime-types.qdoc +++ b/doc/qtcreator/src/editors/creator-only/creator-mime-types.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 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. @@ -75,6 +75,11 @@ \li In \uicontrol {MIME Type}, select a MIME type. + \li In \uicontrol Handler, double-click the editor name to display a + context-menu where you can select another editor to open the file + in by default. The menu is available only if alternative suitable + editors are available. + \li In \uicontrol Patterns, add the filename extension for the type of files that you want to identify as having this MIME type. @@ -96,12 +101,7 @@ \note You are recommended not to change the range and priority, because it might cause problems when opening files in \QC. - \li In \uicontrol Handler, double-click the editor name to display a - context-menu where you can select another editor to open the file - in by default. The menu is available only if alternative suitable - editors are available. - - \li Click \uicontrol OK. + \li Click \uicontrol OK to return to the \uicontrol {MIME Types} tab. \endlist @@ -119,8 +119,8 @@ select \uicontrol {Reset MIME Types}. To revert the changes you have made to the default editors, select \uicontrol {Reset Handlers}. - \note If you now select \uicontrol OK or \uicontrol Apply, you permanently lose all - your own patterns and magic headers. The changes are reverted the next - time you start \QC. + \note If you select \uicontrol OK or \uicontrol Apply after reverting + changes, you permanently lose all your own patterns and magic headers. + They are removed the next time you start \QC. */ diff --git a/doc/qtcreator/src/external-resources/external-resources.qdoc b/doc/qtcreator/src/external-resources/external-resources.qdoc index a6ddbe1414f..f3d2f69d92e 100644 --- a/doc/qtcreator/src/external-resources/external-resources.qdoc +++ b/doc/qtcreator/src/external-resources/external-resources.qdoc @@ -109,3 +109,7 @@ \externalpage https://doc.qt.io/qt/qtqml-syntax-imports.html#qml-import-path \title QML Import Path */ +/*! + \externalpage https://doc.qt.io/QtApplicationManager/ + \title Qt Application Manager +*/ diff --git a/doc/qtcreator/src/linux-mobile/creator-embedded-platforms.qdoc b/doc/qtcreator/src/linux-mobile/creator-embedded-platforms.qdoc index c67c1157467..220c19beae0 100644 --- a/doc/qtcreator/src/linux-mobile/creator-embedded-platforms.qdoc +++ b/doc/qtcreator/src/linux-mobile/creator-embedded-platforms.qdoc @@ -123,6 +123,10 @@ The QNX Neutrino RTOS should provide a few additional command line tools and services, as described in \l {Qt Creator Target Requirements}. + \note In Qt 6, Qt for QNX is a part of + \l{https://doc.qt.io/QtForDeviceCreation/index.html}{Qt for Device Creation}, + and the \QC support is considered experimental. + The following topics contain more information about developing applications for QNX devices: diff --git a/doc/qtcreator/src/linux-mobile/linuxdev.qdoc b/doc/qtcreator/src/linux-mobile/linuxdev.qdoc index 392f04dc6df..818b5fcad56 100644 --- a/doc/qtcreator/src/linux-mobile/linuxdev.qdoc +++ b/doc/qtcreator/src/linux-mobile/linuxdev.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. @@ -87,7 +87,7 @@ \li To deploy applications and run them remotely on devices, specify parameters for accessing the devices: - \list 1 + \list a \li Select \uicontrol Tools > \uicontrol Options > \uicontrol Devices > \uicontrol Devices > \uicontrol Add > @@ -108,14 +108,23 @@ application as. This value will be available in the variable \c %{Device:UserName}. - \li In the \uicontrol {The authentication type} field, select - \uicontrol Default to use the currently displayed private - key file for authentication. Select \uicontrol {Specific Key} - to use some other key, and enter the path to the file that - contains the private key in the field below. This value will - be available in the variable \c %{Device:PrivateKeyFile}. + \li Select \uicontrol {Next} to open the + \uicontrol {Key Deployment} dialog. - \li Click \uicontrol {Next} to create the connection. + \image qtcreator-generic-linux-device-key-deployment.png "Key Deployment dialog" + + \li In \uicontrol {Private key file}, select a private key file + to use for authentication. This value will be available in + the variable \c %{Device:PrivateKeyFile}. + + \li If you do not have a public-private key pair, select + \uicontrol {Create New Key Pair}. For more information, + see \l{Generating SSH Keys}. + + \li Select \uicontrol {Deploy Public Key} to copy the public + key to the device. + + \li Select \uicontrol {Next} to create the connection. \endlist diff --git a/doc/qtcreator/src/projects/creator-projects-running.qdoc b/doc/qtcreator/src/projects/creator-projects-running.qdoc index a7d6a27f9aa..4d4bbbe4f34 100644 --- a/doc/qtcreator/src/projects/creator-projects-running.qdoc +++ b/doc/qtcreator/src/projects/creator-projects-running.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. @@ -65,6 +65,18 @@ \endlist + If your project has several run targets defined, such as + \l{Running Autotests}{tests}, you can select them in the kit selector. + + \image qtcreator-kit-selector-run-targets.png "Run targets in the kit selector" + + If you have connected \l{Mobile Platforms}{mobile devices} or + \l{Embedded Platforms}{embedded devices} to the development PC + or added virtual devices, such as \l{Managing Android Virtual Devices (AVD)} + {Android Virtual Devices (AVD)}, you can select them in the kit selector. + Select \uicontrol Manage to manage device settings. For example, you can add + AVDs or manually start disconnected AVDs. + The \uicontrol {Application Output} pane displays the status of the application while it is running. You can select the \uicontrol Run button in the pane to re-run applications without building them first. This is diff --git a/doc/qtcreator/src/qnx/creator-developing-qnx.qdoc b/doc/qtcreator/src/qnx/creator-developing-qnx.qdoc index 6af72ab2536..bb5d1c50554 100644 --- a/doc/qtcreator/src/qnx/creator-developing-qnx.qdoc +++ b/doc/qtcreator/src/qnx/creator-developing-qnx.qdoc @@ -1,13 +1,13 @@ /**************************************************************************** ** -** This file is part of Qt Creator -** ** Copyright (C) 2018 Blackberry -** ** Contact: Blackberry (qt@blackberry.com) ** Contact: KDAB (info@kdab.com) ** -** This file is part of Qt Creator. +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Creator documentation. ** ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in @@ -40,6 +40,10 @@ a few additional command line tools and services, as described in \l {Qt Creator Target Requirements}. + \note In Qt 6, Qt for QNX is a part of + \l{https://doc.qt.io/QtForDeviceCreation/index.html}{Qt for Device Creation}, + and the \QC support is considered experimental. + \section1 Adding a QNX Neutrino Device in \QC Adding a QNX Neutrino device is very similar to diff --git a/doc/qtcreator/src/qtquick/qtquick-live-preview-devices.qdoc b/doc/qtcreator/src/qtquick/qtquick-live-preview-devices.qdoc index 0b3cde02ea8..1e3e2408e53 100644 --- a/doc/qtcreator/src/qtquick/qtquick-live-preview-devices.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-live-preview-devices.qdoc @@ -92,7 +92,7 @@ \note At the time of this writing, \macos is not supported as a development host for Qt for Device Creation. This means that you cannot preview UIs on - devices if you are using \QDS on \macos. For more information about + devices if you are using \QC on \macos. For more information about supported development hosts, see \l {https://doc.qt.io/QtForDeviceCreation/qtdc-supported-platforms.html#supported-development-hosts} {Supported Development Hosts}. diff --git a/doc/qtcreator/src/qtquick/qtquick-profiler.qdoc b/doc/qtcreator/src/qtquick/qtquick-profiler.qdoc index b8744fbb74b..693a0c2a4cc 100644 --- a/doc/qtcreator/src/qtquick/qtquick-profiler.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-profiler.qdoc @@ -96,7 +96,7 @@ \endif \note To profile applications on \l{glossary-device}{devices}, you - must install Qt 4.7.4 or later libraries on them. + must install Qt libraries on them. \li Select \uicontrol Analyze > \uicontrol {QML Profiler} to profile the current application. @@ -131,8 +131,8 @@ application is launched. Data collection starts when you select the button again. - To save all the collected data, right-click any QML Profiler view to open - the context menu, and then select \uicontrol {Save QML Trace}. To view the saved + To save all the collected data, select \uicontrol Analyze > + \uicontrol {QML Profiler Options} > \uicontrol {Save QML Trace}. To view the saved data, select \uicontrol {Load QML Trace}. You can also deliver the saved data to others for examination or load data saved by them. @@ -167,13 +167,21 @@ \section1 Attaching to Running Qt Quick Applications - To profile Qt Quick applications that are not launched by \QC, select - \uicontrol Analyze > \uicontrol {QML Profiler (External)}. You must enable - QML debugging and profiling for the application in the project build - settings. For more information, see \l{Setting Up QML Debugging}. + You can profile Qt Quick applications that are not launched by \QC. + However, you must enable QML debugging and profiling for the application + in the project build settings. For more information, see + \l{Setting Up QML Debugging}. - In the \uicontrol {QML Profiler} dialog, \uicontrol Port field, specify the port to - listen to. + To attach to waiting applications: + + \list 1 + \li Select \uicontrol Analyze > + \uicontrol {QML Profiler (Attach to Waiting Application)}. + \image qml-profiler-start-dialog.png "Start QML Profiler dialog" + \li In \uicontrol Kit, select the kit used to build the application. + \li In \uicontrol Port, specify the port to listen to. + \li Select \uicontrol OK. + \endlist \section1 Analyzing Collected Data @@ -578,21 +586,19 @@ \section2 Visualizing Statistics as Flame Graphs The \uicontrol {Flame Graph} view shows a more concise statistical overview - of QML and JavaScript execution. In the \uicontrol {Visualize Total Time} - view, the horizontal bars show the amount of + of QML and JavaScript execution. In the \uicontrol {Total Time} view, the + horizontal bars show the amount of time all invocations of a certain function took together, relative to the total runtime of all JavaScript and QML events. The nesting shows which functions were called by which other ones. \image qml-profiler-flamegraph.png "Flame Graph View" - To view the total amount of memory allocated by the functions in the - \uicontrol {Visualize Memory} view, select \uicontrol Memory in the - drop-down menu (1). + To view the total amount of memory allocated by the functions, select + \uicontrol Memory in the drop-down menu. - To view the the number of memory allocations performed by the functions in - the \uicontrol {Visualize Allocations} view, select \uicontrol Allocations - in the drop-down menu. + To view the the number of memory allocations performed by the functions, + select \uicontrol Allocations. Double-click an item in a view to zoom into it. Double-click an empty area in the view to zoom out again. diff --git a/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-setup.qdoc b/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-setup.qdoc index bdd1d8cd070..2a524d26891 100644 --- a/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-setup.qdoc +++ b/doc/qtdesignstudio/src/qtbridge/qtbridge-ps-setup.qdoc @@ -43,31 +43,12 @@ \QBPS is delivered as an Adobe extension (ZXP) package and requires Adobe Photoshop version 20.0.0, or later to be installed. The \QBPS installation process differs depending - on whether you use ZXPInstaller and whether you are installing on + on whether you are installing on Windows or \macos. - \section1 Installing with ZXPInstaller + \section1 Installing on Windows - To use ZXPInstaller to install \QBPS: - - \list 1 - \li Download and install \l{http://zxpinstaller.com/}{ZXPInstaller}. - \li Start ZXPInstaller. - \li Drag and drop the \QBPS ZXP package from - \c {Qt\Tools\QtDesignStudio\photoshop_bridge} on Windows - or \c {Qt/QtDesignStudio/photoshop_bridge} on \macos - to ZXPInstaller. - \li Follow the instructions of the installation program. - \endlist - - \section1 Installing Without ZXPInstaller - - The \QBPS installation process differs depending on the platform you - are installing on. - - \section2 Installing on Windows - - To install \QBPS on Windows without using ZXPInstaller: + To install \QBPS on Windows: \list 1 \li Copy the \QBPS ZXP package from @@ -83,9 +64,9 @@ \endcode \endlist - \section2 Installing on \macos + \section1 Installing on \macos - To install \QBPS on \macos without using ZXPInstaller: + To install \QBPS on \macos: \list 1 \li Copy the \QBPS ZXP package from diff --git a/doc/qtdesignstudio/src/qtdesignstudio.qdoc b/doc/qtdesignstudio/src/qtdesignstudio.qdoc index 22057fb4105..e97a0cbf6a3 100644 --- a/doc/qtdesignstudio/src/qtdesignstudio.qdoc +++ b/doc/qtdesignstudio/src/qtdesignstudio.qdoc @@ -36,9 +36,9 @@ and dynamic behavior. You can test, preview, and fine-tune your designs to pixel-perfection live on the desktop or target device. + View \l{All Topics}{all topics} or select a topic from below. + \table - \row - \li {4,1} \b {\l{All Topics}} \row \li \inlineimage front-gs.png \li \inlineimage front-ui.png diff --git a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ModelNode3DImageView.qml b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ModelNode3DImageView.qml index f0722c660fb..36d4cea8553 100644 --- a/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ModelNode3DImageView.qml +++ b/share/qtcreator/qml/qmlpuppet/mockfiles/qt6/ModelNode3DImageView.qml @@ -102,11 +102,6 @@ Item { } } - View3D { - // Dummy view to hold the context - // TODO remove when QTBUG-87678 is fixed - } - Item { id: contentItem anchors.fill: parent diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp index 6eb7a7146e0..afc4adcae04 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.cpp @@ -998,18 +998,17 @@ void Qt5InformationNodeInstanceServer::doRenderModelNodeImageView() void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView() { #ifdef QUICK3D_MODULE + m_modelNode3DImageViewAsyncData.cleanup(); if (m_modelNode3DImageViewData.rootItem) { + QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "destroyView"); if (!m_modelNode3DImageViewData.contentItem) m_modelNode3DImageViewData.contentItem = getContentItemForRendering(m_modelNode3DImageViewData.rootItem); - // Key number is selected so that it is unlikely to conflict other ImageContainer use. - auto imgContainer = ImageContainer(m_modelNodePreviewImageCommand.instanceId(), {}, 2100000001); - QImage renderImage; if (m_modelNodePreviewImageCache.contains(m_modelNodePreviewImageCommand.componentPath())) { - renderImage = m_modelNodePreviewImageCache[m_modelNodePreviewImageCommand.componentPath()]; + m_modelNode3DImageViewAsyncData.renderImage + = m_modelNodePreviewImageCache[m_modelNodePreviewImageCommand.componentPath()]; + modelNode3DImageViewSendImageToCreator(); } else { - QObject *instanceObj = nullptr; - bool createdFromComponent = false; ServerNodeInstance instance = instanceForId(m_modelNodePreviewImageCommand.instanceId()); if (!m_modelNodePreviewImageCommand.componentPath().isEmpty() && instance.isSubclassOf("QQuick3DNode")) { @@ -1018,14 +1017,15 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView() // wouldn't want the children of the Node to appear in the preview. QQmlComponent component(engine()); component.loadUrl(QUrl::fromLocalFile(m_modelNodePreviewImageCommand.componentPath())); - instanceObj = qobject_cast(component.create()); - if (!instanceObj) { + m_modelNode3DImageViewAsyncData.instanceObj = qobject_cast(component.create()); + if (!m_modelNode3DImageViewAsyncData.instanceObj) { qWarning() << "Could not create preview component: " << component.errors(); + m_modelNode3DImageViewAsyncData.cleanup(); return; } - createdFromComponent = true; + m_modelNode3DImageViewAsyncData.createdFromComponent = true; } else { - instanceObj = instance.internalObject(); + m_modelNode3DImageViewAsyncData.instanceObj = instance.internalObject(); } QSize renderSize = m_modelNodePreviewImageCommand.size(); if (Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) { @@ -1044,53 +1044,73 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView() m_modelNode3DImageViewData.window->resize(renderSize); m_modelNode3DImageViewData.rootItem->setSize(renderSize); - QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "createViewForObject", - Q_ARG(QVariant, objectToVariant(instanceObj))); + QMetaObject::invokeMethod( + m_modelNode3DImageViewData.rootItem, "createViewForObject", + Q_ARG(QVariant, objectToVariant(m_modelNode3DImageViewAsyncData.instanceObj))); - bool ready = false; - int count = 0; // Ensure we don't ever get stuck in an infinite loop - while (!ready && ++count < 10) { - updateNodesRecursive(m_modelNode3DImageViewData.contentItem); -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) - if (Internal::QuickItemNodeInstance::unifiedRenderPath()) { - renderImage = m_modelNode3DImageViewData.window->grabWindow(); - } else { - // Fake render loop signaling to update things like QML items as 3D textures - m_modelNode3DImageViewData.window->beforeSynchronizing(); - m_modelNode3DImageViewData.window->beforeRendering(); - - QSizeF size = qobject_cast(m_modelNode3DImageViewData.contentItem)->size(); - QRectF renderRect(QPointF(0., 0.), size); - renderImage = designerSupport()->renderImageForItem(m_modelNode3DImageViewData.contentItem, - renderRect, size.toSize()); - - m_modelNode3DImageViewData.window->afterRendering(); - } -#else - renderImage = grabRenderControl(m_modelNode3DImageViewData); -#endif - QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "afterRender"); - ready = QQmlProperty::read(m_modelNode3DImageViewData.rootItem, "ready").value(); - } - QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "destroyView"); - if (createdFromComponent) { - // If component changes, puppet will need a reset anyway, so we can cache the image - m_modelNodePreviewImageCache.insert(m_modelNodePreviewImageCommand.componentPath(), renderImage); - delete instanceObj; - } - } - - if (!renderImage.isNull()) { - imgContainer.setImage(renderImage); - - // send the rendered image to creator process - nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::RenderModelNodePreviewImage, - QVariant::fromValue(imgContainer)}); + // Selection box geometry updates have an asynchronous step, so we need to do rendering + // in asynchronous steps as well, since we are adjusting the selection box geometry + // while finding correct zoom level. + m_modelNode3DImageViewAsyncData.timer.start(); } } #endif } +void Qt5InformationNodeInstanceServer::modelNode3DImageViewSendImageToCreator() +{ + if (!m_modelNode3DImageViewAsyncData.renderImage.isNull()) { + // Key number is selected so that it is unlikely to conflict other ImageContainer use. + ImageContainer imgContainer(m_modelNodePreviewImageCommand.instanceId(), {}, 2100000001); + imgContainer.setImage(m_modelNode3DImageViewAsyncData.renderImage); + + // send the rendered image to creator process + nodeInstanceClient()->handlePuppetToCreatorCommand( + {PuppetToCreatorCommand::RenderModelNodePreviewImage, + QVariant::fromValue(imgContainer)}); + + m_modelNode3DImageViewAsyncData.cleanup(); + } +} + +void Qt5InformationNodeInstanceServer::modelNode3DImageViewRenderStep() +{ + ++m_modelNode3DImageViewAsyncData.count; + + updateNodesRecursive(m_modelNode3DImageViewData.contentItem); +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + if (Internal::QuickItemNodeInstance::unifiedRenderPath()) { + m_modelNode3DImageViewAsyncData.renderImage = m_modelNode3DImageViewData.window->grabWindow(); + } else { + // Fake render loop signaling to update things like QML items as 3D textures + m_modelNode3DImageViewData.window->beforeSynchronizing(); + m_modelNode3DImageViewData.window->beforeRendering(); + + QSizeF size = qobject_cast(m_modelNode3DImageViewData.contentItem)->size(); + QRectF renderRect(QPointF(0., 0.), size); + m_modelNode3DImageViewAsyncData.renderImage + = designerSupport()->renderImageForItem(m_modelNode3DImageViewData.contentItem, + renderRect, size.toSize()); + m_modelNode3DImageViewData.window->afterRendering(); + } +#else + m_modelNode3DImageViewAsyncData.renderImage = grabRenderControl(m_modelNode3DImageViewData); +#endif + QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "afterRender"); + const bool ready = QQmlProperty::read(m_modelNode3DImageViewData.rootItem, "ready").value(); + if (ready || m_modelNode3DImageViewAsyncData.count >= 10) { + QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "destroyView"); + if (m_modelNode3DImageViewAsyncData.createdFromComponent) { + // If component changes, puppet will need a reset anyway, so we can cache the image + m_modelNodePreviewImageCache.insert(m_modelNodePreviewImageCommand.componentPath(), + m_modelNode3DImageViewAsyncData.renderImage); + } + modelNode3DImageViewSendImageToCreator(); + } else { + m_modelNode3DImageViewAsyncData.timer.start(); + } +} + static QRectF itemBoundingRect(QQuickItem *item) { QRectF itemRect; @@ -1205,6 +1225,7 @@ Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceC m_render3DEditViewTimer.setSingleShot(true); m_inputEventTimer.setSingleShot(true); m_renderModelNodeImageViewTimer.setSingleShot(true); + m_modelNode3DImageViewAsyncData.timer.setSingleShot(true); #ifdef FPS_COUNTER if (!_fpsTimer) { @@ -1224,11 +1245,12 @@ Qt5InformationNodeInstanceServer::~Qt5InformationNodeInstanceServer() { m_editView3DSetupDone = false; - m_propertyChangeTimer.stop(); m_propertyChangeTimer.stop(); m_selectionChangeTimer.stop(); m_render3DEditViewTimer.stop(); m_inputEventTimer.stop(); + m_renderModelNodeImageViewTimer.stop(); + m_modelNode3DImageViewAsyncData.timer.stop(); if (m_editView3DData.rootItem) m_editView3DData.rootItem->disconnect(this); @@ -1621,6 +1643,8 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList(m_3dHelper); @@ -2089,6 +2113,7 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c void Qt5InformationNodeInstanceServer::requestModelNodePreviewImage(const RequestModelNodePreviewImageCommand &command) { + m_modelNode3DImageViewAsyncData.timer.stop(); m_modelNodePreviewImageCommand = command; renderModelNodeImageView(); } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h index ef6f576dac9..3d96b3bb70d 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5informationnodeinstanceserver.h @@ -138,6 +138,8 @@ private: void renderModelNodeImageView(); void doRenderModelNodeImageView(); void doRenderModelNode3DImageView(); + void modelNode3DImageViewSendImageToCreator(); + void modelNode3DImageViewRenderStep(); void doRenderModelNode2DImageView(); void updateLockedAndHiddenStates(const QSet &instances); void handleInputEvents(); @@ -184,6 +186,26 @@ private: QList m_pendingInputEventCommands; QObject *m_3dHelper = nullptr; int m_need3DEditViewRender = 0; + + struct ModelNode3DImageViewAsyncData { + QTimer timer; + QImage renderImage; + int count = 0; + bool createdFromComponent = false; + QObject *instanceObj = nullptr; + + void cleanup() + { + timer.stop(); + count = 0; + renderImage = {}; + if (createdFromComponent) + delete instanceObj; + instanceObj = nullptr; + createdFromComponent = false; + } + }; + ModelNode3DImageViewAsyncData m_modelNode3DImageViewAsyncData; }; } // namespace QmlDesigner diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp index dbffe2f4fbe..abcf74f39cb 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/qt5nodeinstanceserver.cpp @@ -417,7 +417,7 @@ QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item) if (instance.isValid()) renderBoundingRect = instance.boundingRect(); else - renderBoundingRect = item->boundingRect(); + renderBoundingRect = ServerNodeInstance::effectAdjustedBoundingRect(item); // 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. diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp index 403ba9fbe9a..4399f669c78 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/quickitemnodeinstance.cpp @@ -329,11 +329,23 @@ QRectF QuickItemNodeInstance::contentItemBoundingBox() const return QRectF(); } +static bool layerEnabledAndEffect(QQuickItem *item) +{ + QQuickItemPrivate *pItem = QQuickItemPrivate::get(item); + + if (pItem && pItem->layer() && pItem->layer()->enabled() && pItem->layer()->effect()) + return true; + + return false; +} + QRectF QuickItemNodeInstance::boundingRect() const { if (quickItem()) { if (quickItem()->clip()) { return quickItem()->boundingRect(); + } else if (layerEnabledAndEffect(quickItem())) { + return ServerNodeInstance::effectAdjustedBoundingRect(quickItem()); } else { return boundingRectWithStepChilds(quickItem()); } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp index 97b5031260c..6b2ba783402 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.cpp @@ -135,6 +135,13 @@ bool ServerNodeInstance::isSubclassOf(QObject *object, const QByteArray &superTy return Internal::QmlPrivateGate::isSubclassOf(object, superTypeName); } +QRectF ServerNodeInstance::effectAdjustedBoundingRect(QQuickItem *item) +{ + if (item) + return item->boundingRect().adjusted(-40, -40, 40, 40); + return {}; +} + void ServerNodeInstance::setModifiedFlag(bool b) { m_nodeInstance->setModifiedFlag(b); diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h index 7fd6453daa5..0e5ca3547db 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/instances/servernodeinstance.h @@ -180,6 +180,7 @@ public: QStringList allStates() const; static bool isSubclassOf(QObject *object, const QByteArray &superTypeName); + static QRectF effectAdjustedBoundingRect(QQuickItem *item); void setModifiedFlag(bool b); void updateDirtyNodeRecursive(); diff --git a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/DialogValues.qml b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/DialogValues.qml index 5bcfadaa785..4fedf879215 100644 --- a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/DialogValues.qml +++ b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/DialogValues.qml @@ -57,7 +57,7 @@ QtObject { readonly property string darkPaneColor: StudioTheme.Values.themeBackgroundColorNormal readonly property string lightPaneColor: StudioTheme.Values.themeBackgroundColorAlternate - readonly property string textColor: StudioTheme.Values.themeTabInactiveText + readonly property string textColor: StudioTheme.Values.themeTextColor readonly property string textColorInteraction: StudioTheme.Values.themeInteraction readonly property string dividerlineColor: StudioTheme.Values.themeTextColorDisabled readonly property string textError: StudioTheme.Values.themeError diff --git a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/NewProjectView.qml b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/NewProjectView.qml index 3b72dc1b83f..32a22cb1fcd 100644 --- a/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/NewProjectView.qml +++ b/share/qtcreator/qmldesigner/newprojectdialog/imports/NewProjectDialog/NewProjectView.qml @@ -35,67 +35,58 @@ GridView { required property Item loader - header: TabBar { - id: tabBar + readonly property int animDur: 500 + + header: Rectangle { width: parent.width height: DialogValues.projectViewHeaderHeight + color: DialogValues.lightPaneColor - background: Rectangle { - color: DialogValues.lightPaneColor - } + Row { + id: row + spacing: 20 + property int currIndex: 0 - Repeater { - model: categoryModel + Repeater { + model: categoryModel + Text { + text: name + font.weight: Font.DemiBold + font.pixelSize: DialogValues.viewHeaderPixelSize + verticalAlignment: Text.AlignVCenter + color: row.currIndex === index ? DialogValues.textColorInteraction + : DialogValues.textColor + Behavior on color { ColorAnimation { duration: animDur } } - TabButton { - padding: 0 - - width: headerText.contentWidth + 36 - - background: Item { // TabButton background - Rectangle { // bottom strip - anchors.bottom: parent.bottom - anchors.horizontalCenter: parent.horizontalCenter - width: headerText.contentWidth - height: 6 - radius: 10 - color: tabBar.currentIndex === index ? DialogValues.textColorInteraction - : "transparent" - } - } // TabButton background - - implicitHeight: headerText.height + DialogValues.defaultPadding - 7 - - contentItem: Item { - Column { + MouseArea { anchors.fill: parent + onClicked: { + row.currIndex = index + projectModel.setPage(index) + projectView.currentIndex = 0 + projectView.currentIndexChanged() - Text { - id: headerText - color: tabBar.currentIndex == index ? DialogValues.textColorInteraction - : DialogValues.textColor - text: name - width: parent.width - font.weight: Font.DemiBold - font.pixelSize: DialogValues.viewHeaderPixelSize - lineHeight: DialogValues.viewHeaderLineHeight - lineHeightMode: Text.FixedHeight - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter + strip.x = parent.x + strip.width = parent.width } + } - Item { width: parent.width; height: 11; } - } // Column - } // Item + } // Text + } // Repeater + } // Row - onClicked: { - projectModel.setPage(index) - projectView.currentIndex = 0 - projectView.currentIndexChanged() - } - } // TabButton - } // Repeater - } // Header - TabBar + Rectangle { + id: strip + width: row.children[0].width + height: 5 + radius: 2 + color: DialogValues.textColorInteraction + anchors.bottom: parent.bottom + + Behavior on x { SmoothedAnimation { duration: animDur } } + Behavior on width { SmoothedAnimation { duration: strip.width === 0 ? 0 : animDur } } // do not animate initial width + } + } // Rectangle cellWidth: DialogValues.projectItemWidth cellHeight: DialogValues.projectItemHeight diff --git a/src/libs/utils/infobar.cpp b/src/libs/utils/infobar.cpp index 230473b31bb..f481113b4eb 100644 --- a/src/libs/utils/infobar.cpp +++ b/src/libs/utils/infobar.cpp @@ -344,7 +344,7 @@ void InfoBarDisplay::update() if (info.m_cancelButtonCallBack) connect(infoWidgetCloseButton, &QAbstractButton::clicked, info.m_cancelButtonCallBack); connect(infoWidgetCloseButton, &QAbstractButton::clicked, this, [this, id] { - m_infoBar->suppressInfo(id); + m_infoBar->removeInfo(id); }); } diff --git a/src/plugins/android/androidqmlpreviewworker.cpp b/src/plugins/android/androidqmlpreviewworker.cpp index 007562823a7..60372f33dce 100644 --- a/src/plugins/android/androidqmlpreviewworker.cpp +++ b/src/plugins/android/androidqmlpreviewworker.cpp @@ -57,7 +57,7 @@ namespace Internal { using namespace Utils; -#define APP_ID "io.qt.designviewer" +#define APP_ID "io.qt.qtdesignviewer" class ApkInfo { public: @@ -92,7 +92,7 @@ FilePath AndroidQmlPreviewWorker::designViewerApkPath(const QString &abi) const return {}; if (apkInfo()->abis.contains(abi)) { - return Core::ICore::resourcePath(QString("android/qtdesignviewer/designviewer_%1.apk") + return Core::ICore::resourcePath(QString("android/qtdesignviewer/qtdesignviewer_%1.apk") .arg(abi)); } return {}; diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index 7ca82cf1a8d..da999910c18 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -2938,10 +2938,12 @@ void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator, if (!edit) return; + const int labelOpenParenOffset = item.label().indexOf('('); + const int labelClosingParenOffset = item.label().indexOf(')'); const auto kind = static_cast( item.kind().value_or(CompletionItemKind::Text)); - const bool isMacroCall = kind == CompletionItemKind::Text && item.label().contains('(') - && item.label().contains(')'); // Heuristic + const bool isMacroCall = kind == CompletionItemKind::Text && labelOpenParenOffset != -1 + && labelClosingParenOffset > labelOpenParenOffset; // Heuristic const bool isFunctionLike = kind == CompletionItemKind::Function || kind == CompletionItemKind::Method || kind == CompletionItemKind::Constructor || isMacroCall; @@ -2951,10 +2953,12 @@ void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator, // Some preparation for our magic involving (non-)insertion of parentheses and // cursor placement. if (isFunctionLike && !rawInsertText.contains('(')) { - if (item.label().contains("()")) // function takes no arguments - rawInsertText += "()"; - else if (item.label().contains('(')) // function takes arguments - rawInsertText += "( )"; + if (labelOpenParenOffset != -1) { + if (labelClosingParenOffset == labelOpenParenOffset + 1) // function takes no arguments + rawInsertText += "()"; + else // function takes arguments + rawInsertText += "( )"; + } } const int firstParenOffset = rawInsertText.indexOf('('); @@ -3670,7 +3674,13 @@ void ExtraHighlightingResultsCollector::visitNode(const AstNode &node) bool ClangdClient::FollowSymbolData::defLinkIsAmbiguous() const { - // If we have up-to-date highlighting info, we can give a definite answer. + // Even if the call is to a virtual function, it might not be ambiguous: + // class A { virtual void f(); }; class B : public A { void f() override { A::f(); } }; + if (!cursorNode->mightBeAmbiguousVirtualCall() && !cursorNode->isPureVirtualDeclaration()) + return false; + + // If we have up-to-date highlighting info, we know whether we are dealing with + // a virtual call. if (editorWidget) { const auto virtualRanges = q->d->virtualRanges.constFind(editorWidget->textDocument()); if (virtualRanges != q->d->virtualRanges.constEnd() @@ -3682,8 +3692,9 @@ bool ClangdClient::FollowSymbolData::defLinkIsAmbiguous() const } } - // Otherwise, we have to rely on AST-based heuristics. - return cursorNode->mightBeAmbiguousVirtualCall() || cursorNode->isPureVirtualDeclaration(); + // Otherwise, we accept potentially doing more work than needed rather than not catching + // possible overrides. + return true; } } // namespace Internal diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp index 10cb64d3e91..71fdb6606ed 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp @@ -149,6 +149,7 @@ void CMakeManager::updateCmakeActions(Node *node) auto project = qobject_cast(SessionManager::startupProject()); const bool visible = project && !BuildManager::isBuilding(project); m_runCMakeAction->setVisible(visible); + m_runCMakeActionContextMenu->setEnabled(visible); m_clearCMakeCacheAction->setVisible(visible); m_rescanProjectAction->setVisible(visible); enableBuildFileMenus(node); diff --git a/src/plugins/coreplugin/documentmanager.cpp b/src/plugins/coreplugin/documentmanager.cpp index 4fd4213dbbb..15fb2edfdc1 100644 --- a/src/plugins/coreplugin/documentmanager.cpp +++ b/src/plugins/coreplugin/documentmanager.cpp @@ -607,7 +607,7 @@ QList DocumentManager::modifiedDocuments() } /*! - Treats any subsequent change to \a fileName as an expected file change. + Treats any subsequent change to \a filePath as an expected file change. \sa unexpectFileChange() */ @@ -631,7 +631,7 @@ static void updateExpectedState(const FilePath &filePathKey) } /*! - Considers all changes to \a fileName unexpected again. + Considers all changes to \a filePath unexpected again. \sa expectFileChange() */ diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index df1cc400931..a12c61eb4af 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -256,29 +256,13 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *) */ /*! - \class EditorManager::FilePathInfo - \inheaderfile coreplugin/editormanager/editormanager.h - \inmodule QtCreator - - \brief The FilePathInfo class contains information about a file path's - special segments. - - File names can have an additional postfix, optionally specifying a line and - column number, when opening a file in \QC from the command line or locator. - The FilePathInfo class contains the file name, the complete postfix string, - and the parsed line and column numbers. - - \sa EditorManager::splitLineAndColumnNumber() -*/ - -/*! - \fn void EditorManager::currentEditorChanged(IEditor *editor) + \fn void Core::EditorManager::currentEditorChanged(Core::IEditor *editor) This signal is emitted after the current editor changed to \a editor. */ /*! - \fn void EditorManager::currentDocumentStateChanged() + \fn void Core::EditorManager::currentDocumentStateChanged() This signal is emitted when the meta data of the current document, for example file name or modified state, changed. @@ -287,7 +271,7 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *) */ /*! - \fn void EditorManager::documentStateChanged(IDocument *document) + \fn void Core::EditorManager::documentStateChanged(Core::IDocument *document) This signal is emitted when the meta data of the \a document, for example file name or modified state, changed. @@ -296,13 +280,13 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *) */ /*! - \fn void EditorManager::editorCreated(IEditor *editor, const QString &fileName) + \fn void Core::EditorManager::editorCreated(Core::IEditor *editor, const QString &fileName) This signal is emitted after an \a editor was created for \a fileName, but before it was opened in an editor view. */ /*! - \fn void EditorManager::editorOpened(IEditor *editor) + \fn void Core::EditorManager::editorOpened(Core::IEditor *editor) This signal is emitted after a new \a editor was opened in an editor view. @@ -310,14 +294,14 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *) */ /*! - \fn void EditorManager::documentOpened(IDocument *document) + \fn void Core::EditorManager::documentOpened(Core::IDocument *document) This signal is emitted after the first editor for \a document opened in an editor view. */ /*! - \fn void EditorManager::editorAboutToClose(IEditor *editor) + \fn void Core::EditorManager::editorAboutToClose(Core::IEditor *editor) This signal is emitted before \a editor is closed. This can be used to free resources that were allocated for the editor separately from the editor @@ -330,7 +314,7 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *) */ /*! - \fn void EditorManager::editorsClosed(QList editors) + \fn void Core::EditorManager::editorsClosed(QList editors) This signal is emitted after the \a editors closed, but before they are deleted. @@ -339,7 +323,7 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *) */ /*! - \fn void EditorManager::documentClosed(IDocument *document) + \fn void Core::EditorManager::documentClosed(Core::IDocument *document) This signal is emitted after the \a document closed, but before it is deleted. */ @@ -349,22 +333,22 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *) \internal */ /*! - \fn void EditorManager::aboutToSave(IDocument *document) + \fn void Core::EditorManager::aboutToSave(Core::IDocument *document) This signal is emitted before the \a document is saved. */ /*! - \fn void EditorManager::saved(IDocument *document) + \fn void Core::EditorManager::saved(Core::IDocument *document) This signal is emitted after the \a document was saved. */ /*! - \fn void EditorManager::autoSaved() + \fn void Core::EditorManager::autoSaved() This signal is emitted after auto-save was triggered. */ /*! - \fn void EditorManager::currentEditorAboutToChange(IEditor *editor) + \fn void Core::EditorManager::currentEditorAboutToChange(Core::IEditor *editor) This signal is emitted before the current editor changes to \a editor. */ @@ -3076,10 +3060,10 @@ IEditor *EditorManager::openEditor(const QString &fileName, Id editorId, } /*! - Opens the document specified by \a filePath using the editor type \a + Opens the document specified by \a link using the editor type \a editorId and the specified \a flags. - Moves the text cursor to the \a line and \a column. + Moves the text cursor to the \e line and \e column specified in \a link. If \a editorId is \c Id(), the editor type is derived from the file's MIME type. @@ -3147,7 +3131,7 @@ void EditorManager::openEditorAtSearchResult(const SearchResultItem &item, } /*! - Returns whether \a fileName is an auto-save file created by \QC. + Returns whether \a filePath is an auto-save file created by \QC. */ bool EditorManager::isAutoSaveFile(const QString &filePath) { @@ -3199,7 +3183,7 @@ void EditorManager::addCloseEditorListener(const std::function /*! Asks the user for a list of files to open and returns the choice. - \sa DocumentManager::getOpenFilePaths() + \sa DocumentManager::getOpenFileNames() */ FilePaths EditorManager::getOpenFilePaths() { diff --git a/src/plugins/coreplugin/editormanager/ieditorfactory.cpp b/src/plugins/coreplugin/editormanager/ieditorfactory.cpp index 702527441fe..59d0b988c08 100644 --- a/src/plugins/coreplugin/editormanager/ieditorfactory.cpp +++ b/src/plugins/coreplugin/editormanager/ieditorfactory.cpp @@ -162,7 +162,7 @@ const EditorFactoryList IEditorFactory::defaultEditorFactories(const Utils::Mime } /*! - Returns the available editor factories for \a fileName in order of + Returns the available editor factories for \a filePath in order of preference. That is the default order for the document's MIME type but with a user overridden default editor first, and the binary editor as the very first item if a text document is too large to be opened as a text file. diff --git a/src/plugins/coreplugin/editormanager/iexternaleditor.cpp b/src/plugins/coreplugin/editormanager/iexternaleditor.cpp index 99dcbe2703a..0680da44a42 100644 --- a/src/plugins/coreplugin/editormanager/iexternaleditor.cpp +++ b/src/plugins/coreplugin/editormanager/iexternaleditor.cpp @@ -55,8 +55,7 @@ namespace Core { */ /*! - - \fn bool Core::IExternalEditor::startEditor(const QString &fileName, QString *errorMessage) = 0; + \fn bool Core::IExternalEditor::startEditor(const Utils::FilePath &fileName, QString *errorMessage) Opens the editor with \a fileName. Returns \c true on success or \c false on failure along with the error in \a errorMessage. diff --git a/src/plugins/coreplugin/fileiconprovider.cpp b/src/plugins/coreplugin/fileiconprovider.cpp index 78232af52b0..e2149ce35a4 100644 --- a/src/plugins/coreplugin/fileiconprovider.cpp +++ b/src/plugins/coreplugin/fileiconprovider.cpp @@ -186,7 +186,7 @@ QIcon FileIconProviderImplementation::icon(const FilePath &filePath) const } /*! - Returns the icon associated with the file suffix in \a info. If there is none, + Returns the icon associated with the file suffix in \a filePath. If there is none, the default icon of the operating system is returned. */ diff --git a/src/plugins/coreplugin/find/searchresultwindow.cpp b/src/plugins/coreplugin/find/searchresultwindow.cpp index 1e0f46da0e4..daeeaee7332 100644 --- a/src/plugins/coreplugin/find/searchresultwindow.cpp +++ b/src/plugins/coreplugin/find/searchresultwindow.cpp @@ -857,7 +857,7 @@ void SearchResult::setTextToReplace(const QString &textToReplace) } /*! - Sets whether replace is enabled and can be triggered by the user + Sets whether replace is \a enabled and can be triggered by the user. */ void SearchResult::setReplaceEnabled(bool enabled) { diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index 82a715f59e2..32de08b64ec 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -426,7 +426,7 @@ static QString pathHelper(const QString &rel) return '/' + rel; } /*! - Returns the absolute path that is used for resources like + Returns the absolute path for the relative path \a rel that is used for resources like project templates and the debugger macros. This abstraction is needed to avoid platform-specific code all over @@ -443,7 +443,7 @@ FilePath ICore::resourcePath(const QString &rel) } /*! - Returns the absolute path in the users directory that is used for + Returns the absolute path for the relative path \a rel in the users directory that is used for resources like project templates. Use this function for finding the place for resources that the user may @@ -468,7 +468,7 @@ FilePath ICore::userResourcePath(const QString &rel) } /*! - Returns a writable path that can be used for persistent cache files. + Returns a writable path for the relative path \a rel that can be used for persistent cache files. */ FilePath ICore::cacheResourcePath(const QString &rel) { @@ -477,8 +477,8 @@ FilePath ICore::cacheResourcePath(const QString &rel) } /*! - Returns the path to resources written by the installer, for example - pre-defined kits and toolchains. + Returns the path, based on the relative path \a rel, to resources written by the installer, + for example pre-defined kits and toolchains. */ FilePath ICore::installerResourcePath(const QString &rel) { @@ -516,8 +516,8 @@ QString ICore::userPluginPath() } /*! - Returns the path to the command line tools that are included in the \QC - installation. + Returns the path, based on the relative path \a rel, to the command line tools that are + included in the \QC installation. */ FilePath ICore::libexecPath(const QString &rel) { diff --git a/src/plugins/coreplugin/iversioncontrol.cpp b/src/plugins/coreplugin/iversioncontrol.cpp index b7d7e63405f..6da74e6a502 100644 --- a/src/plugins/coreplugin/iversioncontrol.cpp +++ b/src/plugins/coreplugin/iversioncontrol.cpp @@ -61,11 +61,11 @@ */ /*! - \fn Core::IVersionControl::TopicCache::trackFile(const QString &repository) + \fn Utils::FilePath Core::IVersionControl::TopicCache::trackFile(const Utils::FilePath &repository) Returns the path to the file that invalidates the cache for \a repository when the file is modified. - \fn Core::IVersionControl::TopicCache::refreshTopic(const QString &repository) + \fn QString Core::IVersionControl::TopicCache::refreshTopic(const Utils::FilePath &repository) Returns the current topic for \a repository. */ diff --git a/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp b/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp index 4f7e49d2f2c..4c43a9832f8 100644 --- a/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp @@ -180,7 +180,7 @@ static QString defaultCommand() return "locate"; } -/*! +/* For the tools es [1] and locate [2], interpret space as AND operator. Currently doesn't support fine picking a file with a space in the path by escaped space. diff --git a/src/plugins/languageclient/languageclientoutline.cpp b/src/plugins/languageclient/languageclientoutline.cpp index 32feba487cd..8cffbe9b4df 100644 --- a/src/plugins/languageclient/languageclientoutline.cpp +++ b/src/plugins/languageclient/languageclientoutline.cpp @@ -81,6 +81,7 @@ public: } } + Range range() const { return m_range; } Position pos() const { return m_range.start(); } bool contains(const Position &pos) const { return m_range.contains(pos); } @@ -345,8 +346,14 @@ void OutlineComboBox::updateModel(const DocumentUri &resultUri, const DocumentSy void OutlineComboBox::updateEntry() { const Position pos(m_editorWidget->textCursor()); - LanguageClientOutlineItem *itemForCursor = m_model.findNonRootItem( - [&](const LanguageClientOutlineItem *item) { return item->contains(pos); }); + LanguageClientOutlineItem *itemForCursor = nullptr; + m_model.forAllItems([&](LanguageClientOutlineItem *candidate){ + if (!candidate->contains(pos)) + return; + if (itemForCursor && candidate->range().contains(itemForCursor->range())) + return; // skip item if the range is equal or bigger than the previous found range + itemForCursor = candidate; + }); if (itemForCursor) setCurrentIndex(m_model.indexForItem(itemForCursor)); } diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index 1823d634513..90fc1bb1467 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -104,8 +104,6 @@ static McuToolChainPackage *createArmGccPackage() defaultPath = subDirs.first(); } } - if (defaultPath.isEmpty()) - defaultPath = FileUtils::homePath(); const QString detectionPath = Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++"); const auto versionDetector = new McuPackageExecutableVersionDetector( @@ -129,8 +127,7 @@ static McuToolChainPackage *createGhsToolchainPackage() { const char envVar[] = "GHS_COMPILER_DIR"; - const FilePath defaultPath = qEnvironmentVariableIsSet(envVar) - ? FilePath::fromUserInput(qEnvironmentVariable(envVar)) : FileUtils::homePath(); + const FilePath defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar)); const auto versionDetector = new McuPackageExecutableVersionDetector( Utils::HostOsInfo::withExecutableSuffix("as850"), @@ -153,8 +150,7 @@ static McuToolChainPackage *createGhsArmToolchainPackage() { const char envVar[] = "GHS_ARM_COMPILER_DIR"; - const FilePath defaultPath = qEnvironmentVariableIsSet(envVar) - ? FilePath::fromUserInput(qEnvironmentVariable(envVar)) : FileUtils::homePath(); + const FilePath defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar)); const auto versionDetector = new McuPackageExecutableVersionDetector( Utils::HostOsInfo::withExecutableSuffix("asarm"), @@ -189,8 +185,6 @@ static McuToolChainPackage *createIarToolChainPackage() const FilePath compilerExecPath = tc->compilerCommand(); defaultPath = compilerExecPath.parentDir().parentDir(); } - else - defaultPath = FileUtils::homePath(); } const QString detectionPath = Utils::HostOsInfo::withExecutableSuffix("bin/iccarm"); @@ -219,8 +213,9 @@ static McuPackage *createRGLPackage() if (qEnvironmentVariableIsSet(envVar)) { defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar)); } else if (Utils::HostOsInfo::isWindowsHost()) { - defaultPath = FilePath::fromUserInput(QDir::rootPath() + "Renesas_Electronics/D1x_RGL"); - if (defaultPath.exists()) { + const FilePath rglPath = FilePath::fromString(QDir::rootPath()) / "Renesas_Electronics/D1x_RGL"; + if (rglPath.exists()) { + defaultPath = rglPath; const FilePaths subDirs = defaultPath.dirEntries({QLatin1String("rgl_ghs_D1Mx_*")}, QDir::Dirs | QDir::NoDotAndDotDot); @@ -240,7 +235,7 @@ static McuPackage *createRGLPackage() static McuPackage *createStm32CubeProgrammerPackage() { - FilePath defaultPath = FileUtils::homePath(); + FilePath defaultPath; const QString cubePath = "STMicroelectronics/STM32Cube/STM32CubeProgrammer"; if (HostOsInfo::isWindowsHost()) { const FilePath programPath = findInProgramFiles(cubePath); @@ -272,8 +267,9 @@ static McuPackage *createMcuXpressoIdePackage() if (qEnvironmentVariableIsSet(envVar)) { defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar)); } else if (HostOsInfo::isWindowsHost()) { - defaultPath = FilePath::fromString(QDir::rootPath() + "nxp"); - if (defaultPath.exists()) { + const FilePath programPath = FilePath::fromString(QDir::rootPath()) / "nxp"; + if (programPath.exists()) { + defaultPath = programPath; // If default dir has exactly one sub dir that could be the IDE path, pre-select that. const FilePaths subDirs = defaultPath.dirEntries({QLatin1String("MCUXpressoIDE*")}, @@ -282,7 +278,9 @@ static McuPackage *createMcuXpressoIdePackage() defaultPath = subDirs.first(); } } else { - defaultPath = "/usr/local/mcuxpressoide/"; + const FilePath programPath = FilePath::fromString("/usr/local/mcuxpressoide/"); + if (programPath.exists()) + defaultPath = programPath; } auto result = new McuPackage( @@ -303,17 +301,11 @@ static McuPackage *createCypressProgrammerPackage() if (qEnvironmentVariableIsSet(envVar)) { defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar)); } else if (HostOsInfo::isWindowsHost()) { - FilePath candidate = findInProgramFiles("Cypress/Cypress Auto Flash Utility 1.0"); - if (candidate.exists()) { + const FilePath candidate = findInProgramFiles("Cypress/Cypress Auto Flash Utility 1.0"); + if (candidate.exists()) defaultPath = candidate; - } - } else { - defaultPath = "/usr"; } - if (defaultPath.isEmpty()) - defaultPath = FileUtils::homePath(); - auto result = new McuPackage( "Cypress Auto Flash Utility", defaultPath, @@ -393,7 +385,7 @@ static McuPackage *createBoardSdkPackage(const McuTargetDescription& desc) if (defaultPath.exists()) return defaultPath; } - return FileUtils::homePath(); + return FilePath(); }(); const auto versionDetector = generatePackageVersionDetector(desc.boardSdk.envVar); @@ -418,8 +410,6 @@ static McuPackage *createFreeRTOSSourcesPackage(const QString &envVar, const Fil defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar.toLatin1())); else if (!boardSdkDir.isEmpty() && !freeRTOSBoardSdkSubDir.isEmpty()) defaultPath = boardSdkDir / freeRTOSBoardSdkSubDir; - else - defaultPath = FileUtils::homePath(); auto result = new McuPackage( QString::fromLatin1("FreeRTOS Sources (%1)").arg(envVarPrefix), @@ -634,7 +624,7 @@ static QVector targetsFromDescriptions(const QListsource() == Qt::MouseEventSynthesizedBySystem) { - emit panChanged(QPointF(event->pixelDelta())); - event->accept(); - return true; + if (event->modifiers().testFlag(Qt::ControlModifier)) { + if (QPointF delta = event->pixelDelta(); !delta.isNull()) { + double dist = std::abs(delta.x()) > std::abs(delta.y()) ? -delta.x() : delta.y(); + emit zoomChanged(dist/200.0, event->position()); + event->accept(); + return true; + } + } else { + emit panChanged(QPointF(event->pixelDelta())); + event->accept(); + return true; + } } else if (event->source() == Qt::MouseEventNotSynthesized) { auto zoomInSignal = QMetaMethod::fromSignal(&Navigation2dFilter::zoomIn); diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp index 8b8b3b91253..f32a66b832f 100644 --- a/src/plugins/qmldesigner/components/integration/designdocument.cpp +++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp @@ -279,7 +279,10 @@ bool DesignDocument::isDocumentLoaded() const void DesignDocument::resetToDocumentModel() { - plainTextEdit()->document()->clearUndoRedoStacks(); + const QPlainTextEdit *edit = plainTextEdit(); + if (edit) + edit->document()->clearUndoRedoStacks(); + m_inFileComponentModel.reset(); } @@ -311,7 +314,9 @@ void DesignDocument::changeToDocumentModel() viewManager().detachRewriterView(); viewManager().detachViewsExceptRewriterAndComponetView(); - plainTextEdit()->document()->clearUndoRedoStacks(); + const QPlainTextEdit *edit = plainTextEdit(); + if (edit) + edit->document()->clearUndoRedoStacks(); m_inFileComponentModel.reset(); m_inFileComponentTextModifier.reset(); @@ -348,7 +353,9 @@ void DesignDocument::changeToInFileComponentModel(ComponentTextModifier *textMod viewManager().detachRewriterView(); viewManager().detachViewsExceptRewriterAndComponetView(); - plainTextEdit()->document()->clearUndoRedoStacks(); + const QPlainTextEdit *edit = plainTextEdit(); + if (edit) + edit->document()->clearUndoRedoStacks(); m_inFileComponentModel.reset(createInFileComponentModel()); m_inFileComponentModel->setTextModifier(m_inFileComponentTextModifier.data()); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 03547fcee77..4c02b25433b 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -102,11 +102,15 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event) // For drag to be handled correctly, we must have the component properly imported // beforehand, so we import the module immediately when the drag starts if (!entry.requiredImport().isEmpty()) { - Import import = Import::createLibraryImport(entry.requiredImport()); - if (!m_model->hasImport(import, true, true)) { + // We don't know if required import is library of file import, so try both. + Import libImport = Import::createLibraryImport(entry.requiredImport()); + Import fileImport = Import::createFileImport(entry.requiredImport()); + if (!m_model->hasImport(libImport, true, true) + && !m_model->hasImport(fileImport, true, true)) { const QList possImports = m_model->possibleImports(); for (const auto &possImport : possImports) { - if (possImport.url() == import.url()) { + if ((!possImport.url().isEmpty() && possImport.url() == libImport.url()) + || (!possImport.file().isEmpty() && possImport.file() == fileImport.file())) { m_model->changeImports({possImport}, {}); break; } diff --git a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp index 2606ea83a49..514bf2c75b1 100644 --- a/src/plugins/qmldesigner/components/navigator/navigatorview.cpp +++ b/src/plugins/qmldesigner/components/navigator/navigatorview.cpp @@ -28,6 +28,7 @@ #include "navigatorwidget.h" #include "qmldesignerconstants.h" #include "qmldesignericons.h" +#include "qmldesignerplugin.h" #include "nameitemdelegate.h" #include "iconcheckboxitemdelegate.h" @@ -166,9 +167,14 @@ void NavigatorView::modelAttached(Model *model) const QHash localExpandMap = m_expandMap[AbstractView::model()->fileUrl()]; auto it = localExpandMap.constBegin(); while (it != localExpandMap.constEnd()) { - const QModelIndex index = indexForModelNode(modelNodeForId(it.key())); - if (index.isValid()) - treeWidget()->setExpanded(index, it.value()); + const ModelNode node = modelNodeForId(it.key()); + // When editing subcomponent, the current root node may be marked collapsed in the + // full file view, but we never want to actually collapse it, so skip it. + if (!node.isRootNode()) { + const QModelIndex index = indexForModelNode(node); + if (index.isValid()) + treeWidget()->setExpanded(index, it.value()); + } ++it; } } @@ -200,11 +206,18 @@ void NavigatorView::addNodeAndSubModelNodesToList(const ModelNode &node, QListfileUrl()); + QHash &localExpandMap = m_expandMap[model->fileUrl()]; + + // If detaching full document model, recreate expand map from scratch to remove stale entries. + // Otherwise just update it (subcomponent edit case). + bool fullUpdate = true; + if (DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument()) + fullUpdate = !document->inFileComponentModelActive(); + if (fullUpdate) + localExpandMap.clear(); if (currentModel()) { // Store expand state of the navigator tree - QHash localExpandMap; const ModelNode rootNode = rootModelNode(); const QModelIndex rootIndex = indexForModelNode(rootNode); @@ -215,15 +228,18 @@ void NavigatorView::modelAboutToBeDetached(Model *model) for (int i = 0; i < rowCount; ++i) { const QModelIndex childIndex = currentModel()->index(i, 0, index); const ModelNode node = modelNodeForIndex(childIndex); - // Just store collapsed states as everything is expanded by default - if (node.isValid() && !treeWidget()->isExpanded(childIndex)) - localExpandMap.insert(node.id(), false); + if (node.isValid()) { + // Just store collapsed states as everything is expanded by default + if (!treeWidget()->isExpanded(childIndex)) + localExpandMap.insert(node.id(), false); + else if (!fullUpdate) + localExpandMap.remove(node.id()); + } gatherExpandedState(childIndex); } } }; gatherExpandedState(rootIndex); - m_expandMap[model->fileUrl()] = localExpandMap; } AbstractView::modelAboutToBeDetached(model); diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index 0dc6f5c5a18..c17f7f158bc 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -112,7 +112,7 @@ QmlProject::QmlProject(const Utils::FilePath &fileName) Utils::InfoBarEntry info(openInQDSAppSetting, tr("Would you like to open the project in Qt Design Studio?"), - Utils::InfoBarEntry::GlobalSuppression::Enabled); + Utils::InfoBarEntry::GlobalSuppression::Disabled); info.setCustomButtonInfo(tr("Open in Qt Design Studio"), [&, fileName] { Core::ICore::infoBar()->removeInfo(openInQDSAppSetting); QmlProjectPlugin::openQDS(fileName); diff --git a/src/plugins/studiowelcome/qdsnewdialog.cpp b/src/plugins/studiowelcome/qdsnewdialog.cpp index 62def1d397e..7ab0d9f8c13 100644 --- a/src/plugins/studiowelcome/qdsnewdialog.cpp +++ b/src/plugins/studiowelcome/qdsnewdialog.cpp @@ -303,6 +303,7 @@ void QdsNewDialog::accept() { CreateProject create{m_wizard}; + m_dialog->hide(); create.withName(m_qmlProjectName) .atLocation(m_qmlProjectLocation) .withScreenSizes(m_qmlScreenSizeIndex, m_qmlCustomWidth, m_qmlCustomHeight) @@ -313,6 +314,8 @@ void QdsNewDialog::accept() .execute(); m_dialog->close(); + m_dialog->deleteLater(); + m_dialog = nullptr; } void QdsNewDialog::reject() diff --git a/src/plugins/studiowelcome/wizardhandler.cpp b/src/plugins/studiowelcome/wizardhandler.cpp index c8c6c85d12e..bf9f0f31f76 100644 --- a/src/plugins/studiowelcome/wizardhandler.cpp +++ b/src/plugins/studiowelcome/wizardhandler.cpp @@ -63,6 +63,7 @@ void WizardHandler::destroyWizard() m_selectedProject = -1; m_wizard->deleteLater(); m_wizard = nullptr; + m_detailsPage = nullptr; } void WizardHandler::setupWizard()