Merge remote-tracking branch 'origin/6.0'

Change-Id: I560583b200db8f180574256d6d851a867be11c37
This commit is contained in:
Eike Ziller
2021-11-04 13:52:30 +01:00
141 changed files with 2743 additions and 299 deletions

View File

@@ -312,7 +312,10 @@ we thank the authors who made this possible:
With backported/additional patches from https://code.qt.io/clang/llvm-project.git With backported/additional patches from https://code.qt.io/clang/llvm-project.git
### Reference implementation for std::experimental::optional ### Optional
A single-header header-only library for representing optional (nullable)
objects for C++14 (and C++11 to some extent) and passing them by value.
https://github.com/akrzemi1/Optional https://github.com/akrzemi1/Optional
@@ -327,7 +330,9 @@ we thank the authors who made this possible:
The idea and interface is based on Boost.Optional library The idea and interface is based on Boost.Optional library
authored by Fernando Luis Cacciola Carballal authored by Fernando Luis Cacciola Carballal
### Implementation for std::variant ### MPark.Variant
MPark.Variant is an implementation of C++17 std::variant for C++11/14/17.
https://github.com/mpark/variant https://github.com/mpark/variant
@@ -338,7 +343,11 @@ we thank the authors who made this possible:
Distributed under the Boost Software License, Version 1.0. Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
### Implementation for std::span ### std::span implementation for C++11 and later
A single-header implementation of C++20's std::span, conforming to the C++20
committee draft. It is compatible with C++11, but will use newer language
features if they are available.
https://github.com/tcbrindle/span https://github.com/tcbrindle/span
@@ -398,7 +407,10 @@ we thank the authors who made this possible:
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
### SQLite, in-process library that implements a SQL database engine ### SQLite (version 3.8.10.2)
SQLite is a C-language library that implements a small, fast, self-contained,
high-reliability, full-featured, SQL database engine.
SQLite (https://www.sqlite.org) is in the Public Domain. SQLite (https://www.sqlite.org) is in the Public Domain.
@@ -490,7 +502,7 @@ SQLite (https://www.sqlite.org) is in the Public Domain.
from Florian Loitsch which is licensed under the MIT License (see above). from Florian Loitsch which is licensed under the MIT License (see above).
Copyright © 2009 Florian Loitsch Copyright © 2009 Florian Loitsch
### Minitrace ### minitrace
Simple C/C++ library for producing JSON traces. Simple C/C++ library for producing JSON traces.

56
dist/changes-5.0.3.md vendored Normal file
View File

@@ -0,0 +1,56 @@
Qt Creator 5.0.3
================
Qt Creator version 5.0.3 contains bug fixes.
The most important changes are listed in this document. For a complete list of
changes, see the Git log for the Qt Creator sources that you can check out from
the public Git repository. For example:
git clone git://code.qt.io/qt-creator/qt-creator.git
git log --cherry-pick --pretty=oneline origin/v5.0.2..v5.0.3
Editing
-------
### QML
* Fixed possible crash on shutdown
### Image Viewer
* Fixed crash when opening invalid movie (QTCREATORBUG-26377)
Projects
--------
### qmake
* Fixed handling of `QMAKE_EXTRA_COMPILERS` (QTCREATORBUG-26323)
Platforms
---------
### macOS
* Fixed crash when opening qmake projects on ARM Macs (QTBUG-97085)
### Android
* Fixed issue in installation step with qmake projects (QTCREATORBUG-26357)
Credits for these changes go to:
--------------------------------
Assam Boudjelthia
Christian Kandeler
Eike Ziller
Henning Gruendl
Jaroslaw Kobus
Johanna Vanhatapio
Jörg Bornemann
Kai Köhne
Kaj Grönholm
Leena Miettinen
Robert Löhning
Thomas Hartmann
Tim Jenssen

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -36,7 +36,9 @@
You can connect Android devices to the development PC using USB cables You can connect Android devices to the development PC using USB cables
to build, run, debug, and analyze applications from \QC. Devices with to build, run, debug, and analyze applications from \QC. Devices with
Android version 4.1 (API level 16) or later are supported. Android version 4.1 (API level 16) or later are supported when developing
with Qt 5 and devices with Android version 6.0 (API level 23) when
developing with Qt 6.
To develop for Android, you must have a tool chain for building applications To develop for Android, you must have a tool chain for building applications
for Android devices installed on the development PC. \QC can automatically for Android devices installed on the development PC. \QC can automatically
@@ -47,10 +49,6 @@
Starting from Qt 5.14.0, the Qt for Android package contains all the Starting from Qt 5.14.0, the Qt for Android package contains all the
architectures (ABIs) installed as one. architectures (ABIs) installed as one.
\note You can build a 64-bit version of Qt for Android yourself. However,
for such a Qt version, the minimum required Android version on devices
is 5.0 (API level 21). For more information, see \l{Qt for Android}.
To enable helpful code editing features for Java, such as code completion, To enable helpful code editing features for Java, such as code completion,
highlighting, function tooltips, and navigating in code, specify settings highlighting, function tooltips, and navigating in code, specify settings
for a \l{Specifying Java Language Server Settings}{Java language server}. for a \l{Specifying Java Language Server Settings}{Java language server}.
@@ -83,7 +81,9 @@
\list 1 \list 1
\li Select \uicontrol Tools > \uicontrol Options > \uicontrol Devices > \li Select \uicontrol Tools > \uicontrol Options > \uicontrol Devices >
\uicontrol Android. \uicontrol Android on Windows and Linux or \uicontrol {\QC} >
\uicontrol Preferences > \uicontrol Devices > \uicontrol Android on
\macos.
\image qtcreator-options-android-main.png "Android options" \image qtcreator-options-android-main.png "Android options"
\li In the \uicontrol {JDK location} field, set the path to the JDK. \li In the \uicontrol {JDK location} field, set the path to the JDK.
\QC checks the JDK installation and reports errors. \QC checks the JDK installation and reports errors.
@@ -108,7 +108,8 @@
offers to add or remove those packages. Before taking action, it offers to add or remove those packages. Before taking action, it
prompts you to accept the changes it is about to make. In addition, prompts you to accept the changes it is about to make. In addition,
it prompts you to accept Google licenses, as necessary. it prompts you to accept Google licenses, as necessary.
\li The installed NDK versions are listed below the SDK path. \li The installed NDK versions are listed in
\uicontrol {Android NDK list}.
The locked items were installed by the SDK Manager, The locked items were installed by the SDK Manager,
and can only be modified from the \uicontrol {SDK Manager} tab. and can only be modified from the \uicontrol {SDK Manager} tab.
For more information, see \l{Managing Android NDK Packages}. For more information, see \l{Managing Android NDK Packages}.
@@ -118,10 +119,9 @@
For Qt applications that require OpenSSL support, \QC allows to For Qt applications that require OpenSSL support, \QC allows to
quickly add the \l {Android OpenSSL support} to your project. quickly add the \l {Android OpenSSL support} to your project.
For more information, see \l{Adding External Libraries}. For more information, see \l{Adding External Libraries}.
\li Select \inlineimage online.png \li Select \uicontrol {Download OpenSSL} to download the OpenSSL
to download the OpenSSL repository to the selected path. If the repository to the selected path. If the automatic download fails,
automatic download fails, the download web page opens for manual the download web page opens for manual download.
download.
\li Select the \uicontrol {Automatically create kits for Android tool chains} \li Select the \uicontrol {Automatically create kits for Android tool chains}
check box to allow \QC to create the kits for you. \QC displays a check box to allow \QC to create the kits for you. \QC displays a
warning if it cannot find a suitable Qt version. warning if it cannot find a suitable Qt version.
@@ -172,7 +172,9 @@
\section2 Managing Android NDK Packages \section2 Managing Android NDK Packages
To view the installed \l{Android NDK} versions, select \uicontrol Tools > To view the installed \l{Android NDK} versions, select \uicontrol Tools >
\uicontrol Options > \uicontrol Devices > \uicontrol Android. \uicontrol Options > \uicontrol Devices > \uicontrol Android on Windows and
Linux or \uicontrol {\QC} > \uicontrol Preferences > \uicontrol Devices >
\uicontrol Android on \macos.
\image qtcreator-options-android-sdk-tools.png "Android NDK and SDK checks" \image qtcreator-options-android-sdk-tools.png "Android NDK and SDK checks"
@@ -198,7 +200,9 @@
To view the installed Android SDK packages, select \uicontrol Tools > To view the installed Android SDK packages, select \uicontrol Tools >
\uicontrol Options > \uicontrol Devices > \uicontrol Android > \uicontrol Options > \uicontrol Devices > \uicontrol Android >
\uicontrol {SDK Manager}. \uicontrol {SDK Manager} on Windows and Linux or \uicontrol {\QC} >
\uicontrol Preferences > \uicontrol Devices > \uicontrol Android >
\uicontrol {SDK Manager} on \macos.
\image qtcreator-android-sdk-manager.png "Android SDK Manager" \image qtcreator-android-sdk-manager.png "Android SDK Manager"
@@ -216,15 +220,39 @@
\section1 Managing Android Virtual Devices (AVD) \section1 Managing Android Virtual Devices (AVD)
A list of AVDs is shown under \uicontrol Tools > \uicontrol Options > The available AVDs are listed in \uicontrol Tools > \uicontrol Options
\uicontrol Devices > \uicontrol Android > \uicontrol {AVD Manager}. This > \uicontrol Devices on Windows and Linux or \uicontrol {\QC} >
works only if the \uicontrol {Android SDK location} is set correctly in \uicontrol Preferences > \uicontrol Devices > on \macos. You can add more
\uicontrol {Android Settings}. AVDs.
The value in \uicontrol {System/data partition size} is used to set the \image qtcreator-android-avd-manager.png "Android device in Devices"
emulator's system partition size upon execution with \uicontrol {Start}.
\image qtcreator-android-avd-manager.png "Android NDK and SDK checks" You can see the status of the selected device in \uicontrol {Current state}.
To update the status information, select \uicontrol Refresh.
To start an AVD, select \uicontrol {Start AVD}. Usually, you don't need to
start AVDs separately because they are automatically started when you
select them in the \l{Building for Multiple Platforms}{kit selector} to
\l{Deploying Applications to Android Devices}{deploy applications} to them.
To remove an AVD from the list and the kit selector, select
\uicontrol {Erase AVD}.
To specify options for starting an AVD, select \uicontrol {AVD Arguments}.
\image qtcreator-android-avd-arguments.png "Startup options for AVDs"
Specify the options in \uicontrol {Emulator command-line startup options}.
For available options, see \l{Start the emulator from the command line}.
\note The Android Emulator has a bug that prevents it from starting on some
systems. If an AVD does not start, you can try starting it manually by
running the following commands:
\badcode
cd <ANDROID_SDK>/emulator
./emulator -avd <AVD_NAME>
\endcode
\section2 Creating a New AVD \section2 Creating a New AVD
@@ -232,68 +260,18 @@
\list 1 \list 1
\li Select \uicontrol Tools > \uicontrol Options > \uicontrol Devices > \li Select \uicontrol Tools > \uicontrol Options > \uicontrol Devices >
\uicontrol Android. \uicontrol Add > \uicontrol {Android Device} on Windows and Linux
\li In the \uicontrol {SDK Manager} tab, select \uicontrol Install for or \uicontrol {\QC} > \uicontrol Preferences > \uicontrol Devices >
an Android version, and then select \uicontrol Apply to install a \uicontrol Add > \uicontrol {Android Device} on \macos to open the
system image. Alternatively, you can install the system image from \uicontrol {Create New AVD} dialog.
Android Studio. \image qtcreator-android-create-avd.png "Create New AVD dialog"
\li In the \uicontrol {AVD Manager} tab, select \uicontrol {Add} to \li Set the name, definition, architecture, target API level, and
open the \uicontrol {Create New AVD} dialog. SD card size of the device.
\image qtcreator-android-create-avd.png "Android NDK and SDK checks"
\li Set the name, type, skin, architecture, API level, and SD card size
of the device.
\li Select \uicontrol OK to create the AVD. \li Select \uicontrol OK to create the AVD.
\endlist \endlist
For more advanced options for creating a new AVD, use the command-line tool For more advanced options for creating a new AVD, use the command-line tool
\l{avdmanager}, or use Android Studio's native AVD Manager's UI. \l{avdmanager} or the Android Studio's native AVD Manager UI.
\section1 Selecting Android Devices
When you deploy an application to an Android device with Android
version 4.2 (API 16) or later, the \uicontrol {Select Android Device} dialog
opens. It lists the devices that are connected to the development PC, as
well as AVDs, and their status. You can select devices or AVDs from the
\uicontrol {Compatible Devices} list for deployment.
If \QC determines that a device is not ready for deployment, it places the
device in the \uicontrol {Incompatible Devices} list, with information about the
issue. For example, you might need to authorize the connection on the
device. After you authorize the connection on the device, select
\uicontrol {Refresh Device List}. The device is moved to the
\uicontrol {Compatible Devices} list and you can select it for deployment.
Other reasons for showing a device in \uicontrol {Incompatible Devices} are
that the Android version on the device is too old or that the tool chain
used for building does not match the Android architecture on the device
(for example, you cannot deploy an ARM build on an x86 device).
\image qtcreator-android-select-devices.png "Select Android Devices dialog"
To \l{Creating a New AVD}{create a new AVD}, select \uicontrol {Create Android Virtual Device}.
To set a device as the default device for a particular Android architecture
for the current project, select the \uicontrol {Always use this device for architecture}
check box. The \uicontrol {Select Android Devices} dialog will not appear
until you switch to another project or restart \QC.
\section1 Using the Android Emulator
To run your application on the Android Emulator, you must have an Android
virtual device (AVD). For more information about creating a new one, see
\l{Creating a New AVD}. If you run an application without a device connected to the
development PC and without an AVD specified, \QC asks you to add an AVD.
\note The Android Emulator has a bug that prevents it from starting on some
systems. If the Android Emulator does not start, you can try starting it
manually by running the following commands:
\badcode
cd <ANDROID_SDK>/emulator
./emulator -avd <AVD_NAME>
\endcode
For more information, see \l{Start the emulator from the command line}.
\section1 Debugging on Android Devices \section1 Debugging on Android Devices

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2017 The Qt Company Ltd. ** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -34,19 +34,19 @@
A default set of Android Activity manager (am) start options is applied when A default set of Android Activity manager (am) start options is applied when
starting applications. You can specify additional start options in the starting applications. You can specify additional start options in the
\uicontrol {Activity manager start options} field. However, if the default \uicontrol {Activity manager start arguments} field. However, if the default
options conflict with the added options, the application might not start. options conflict with the added options, the application might not start.
The default arguments for the Activity manager for a normal run: The default arguments for the Activity manager for a normal run:
\badcode \badcode
am start -n org.qtproject.example.notification/org.qtproject.qt5.android.bindings.QtActivity am start -n <package_name>/<QtActivity_name>
\endcode \endcode
The default arguments for the Activity manager for the debugger mode: The default arguments for the Activity manager for the debugger mode:
\badcode \badcode
am start -n org.qtproject.example.notification/org.qtproject.qt5.android.bindings.QtActivity -D am start -n <package_name>/<QtActivity_name> -D
\endcode \endcode
For example, to run the application as a particular user, enter the start For example, to run the application as a particular user, enter the start
@@ -54,18 +54,20 @@
\image qtcreator-android-run-settings.png \image qtcreator-android-run-settings.png
You can specify shell commands to run before the application is started and You can specify shell commands to run before the application is started
after it is quit. For example, enter the following commands to unlock the and after it is quit. For example, enter the following commands into
screen and to switch to the user account \c 10 on the device before running \uicontrol{Pre-launch on-device shell commands} to unlock the screen and
the application: to switch to the user account \c 10 on the device before running the
application:
\code \code
input keyevent 82 input keyevent 82
am switch-user 10 am switch-user 10
\endcode \endcode
Enter the following commands to switch back to the default user, \c 0, and Enter the following commands into
to unlock the screen after the application is quit: \uicontrol{Post-quit on-device shell commands} to switch back to the
default user, \c 0, and to unlock the screen after the application is quit:
\code \code
am switch-user 0 am switch-user 0

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -52,7 +52,8 @@
\note Since \QC 4.12, Ministro is not supported. \note Since \QC 4.12, Ministro is not supported.
To specify settings for application packages, select \uicontrol Projects > To \l{Specifying Settings for Packages}{specify settings} for application
packages, select \uicontrol Projects > \uicontrol Build >
\uicontrol {Build Android APK} > \uicontrol Details. \uicontrol {Build Android APK} > \uicontrol Details.
\if defined(qtcreator) \if defined(qtcreator)
@@ -64,7 +65,7 @@
Because bundling applications as APK packages is not Because bundling applications as APK packages is not
trivial, Qt 5 provides a deployment tool called \c androiddeployqt. trivial, Qt 5 provides a deployment tool called \c androiddeployqt.
When you deploy an application using a \uicontrol {Qt for Android Kit}, \QC uses When you deploy an application using a \e {Qt for Android kit}, \QC uses
the \c androiddeployqt tool to create the necessary files and to bundle them the \c androiddeployqt tool to create the necessary files and to bundle them
into an APK: into an APK:
@@ -100,41 +101,58 @@
To view the packages that the \c androiddeployqt tool created, select the To view the packages that the \c androiddeployqt tool created, select the
\uicontrol {Open package location after build} check box. \uicontrol {Open package location after build} check box.
The packages are deployed on the connected Android devices. To switch the \section2 Specifying Deployment Settings
device used as a default device for the selected kit, select
\uicontrol Projects > \uicontrol Run > \uicontrol {Deploy to Android Device}
> \uicontrol {Reset Default Devices}. The setting applies until you restart \QC.
For more information, see \l{Selecting Android Devices}.
For more information about the \c androiddeployqt tool, see The available deployment settings are listed in the \uicontrol Method field.
\l{Deploying an Application on Android}. To add deployment methods for a project, select \uicontrol Add.
\image qtcreator-android-deployment-settings.png "Deployment settings"
To rename the current deployment method, select \uicontrol Rename.
To remove the current deployment method, select \uicontrol Remove.
The packages are deployed on the Android device that you select in the
\l{Building for Multiple Platforms}{kit selector}. To add devices, select
\uicontrol Manage.
For more information about specifying additional start options for
applications, see \l{Specifying Run Settings for Android Devices}.
To remove previously installed files from the device, select
\uicontrol {Uninstall the existing app before deployment}.
To install a pre-built APK, such as a 3rd-party application to a device,
select \uicontrol {Install an APK File}.
\section2 Specifying Settings for Packages \section2 Specifying Settings for Packages
You can specify settings for the \c androiddeployqt tool in \QC and in the To specify settings for the \c androiddeployqt tool, select
project .pro file. To specify settings in \QC, select \uicontrol Projects > \uicontrol Projects > \uicontrol Build > \uicontrol {Build Android APK} >
\uicontrol Build > \uicontrol {Build Android APK} > \uicontrol Details. \uicontrol Details.
\image qtcreator-android-deploy-configurations.png "Deploy configurations" \image qtcreator-android-build-apk-step.png "Build Android APK step"
The anddroiddeployqt tool uses the information in the project .pro file to The \c androiddeployqt tool uses the configuration information to
create APKs. For more information about the qmake variables create APKs. For more information about the available options, see
that you can set in the .pro file to tailor the APK, see \l{androiddeployqt}.
\l{Deploying an Application on Android}.
You can view information about what the anddroiddeployqt tool is doing in You can view information about what the \c androiddeployqt tool is doing in
the \uicontrol {Compile Output} pane. To view additional information, select the the \uicontrol {Compile Output} pane. To view additional information, select the
\uicontrol {Verbose output} check box. \uicontrol {Verbose output} check box.
Select \uicontrol {Add debug server} to include the debug server binary
into a package.
\section3 Selecting API Level \section3 Selecting API Level
In the \uicontrol {Android build SDK} field, you can select the API level to use In the \uicontrol {Android build platform SDK} field, you can select the
for building the application. Usually, you should select the newest API API level to use for building the application. Usually, you should select
level available. the highest API level available.
\note For Qt 5.12.0 to 5.12.5 and Qt 5.13.0 to 5.13.1, Android build SDK 28 should \note For Qt 5.12.0 to 5.12.5 and Qt 5.13.0 to 5.13.1, Android build
be used. For recent versions than the latter, build SDK 29, or the most recent platform SDK 28 should be used. For more recent versions than Qt 5.13.1,
should be used. build platform SDK 29 or the most recent one should be used.
This field does not specify the minimum supported API level nor the target This field does not specify the minimum supported API level nor the target
API level, which you can specify in the Android manifest. See API level, which you can specify in the Android manifest. See
@@ -146,7 +164,7 @@
For testing the application locally, use the APK format, because For testing the application locally, use the APK format, because
the package can be uploaded directly to the device and run. For the package can be uploaded directly to the device and run. For
distribution to the Google Play store, create an AAB by selecting distribution to the Google Play store, create an AAB by selecting
the \uicontrol {Build .aab (Android App Bundle)} check box. the \uicontrol {Build Android App Bundle (*.aab)} check box.
When building with CMake, you can view the selected ABIs in the When building with CMake, you can view the selected ABIs in the
\uicontrol {Initial CMake parameters} field in the \uicontrol CMake section. \uicontrol {Initial CMake parameters} field in the \uicontrol CMake section.
@@ -253,11 +271,11 @@
\section1 Editing Manifest Files \section1 Editing Manifest Files
You can use the qmake variables to specify all You can use the configuration options to specify all the settings you need
the settings you need for the \c androiddeployqt tool and you do not need an for the \c androiddeployqt tool. You only need an Adroid manifest file
Android manifest file unless you need to specify Android specific settings to specify Android-specific settings, such as the application icon.
like the application's icon. Also, the manifest file is needed if you want However, the manifest file is needed when you want to publish the package
to publish the package in the Play Store. in the Play Store.
\section2 Package Names \section2 Package Names
@@ -384,7 +402,7 @@
\li Locks the orientation to its current rotation, whatever that is. \li Locks the orientation to its current rotation, whatever that is.
\endtable \endtable
\section2 Supported Resolutions \section2 Icons and Splash Screens
You can set different images to be shown as application icons and splash You can set different images to be shown as application icons and splash
screens on low, medium, high, and extra high DPI displays. The following screens on low, medium, high, and extra high DPI displays. The following
@@ -399,6 +417,36 @@
\li Extra-extra-extra-high-density (XXXHDPI): ~640dpi \li Extra-extra-extra-high-density (XXXHDPI): ~640dpi
\endlist \endlist
Specify settings for icons in the \uicontrol {Application icon} tab. Select
the image with the highest resolution as the \uicontrol {Master icon}.
\QC resizes the icon and sets versions of it to be shown on low, medium,
high, and extra high DPI displays, as needed. Alternatively, set the icons
for each resolution separately.
\image qtcreator-android-manifest-editor-app-icon.png "Application icons in Android Manifest Editor"
Specify settings for splash screens in the \uicontrol {Splash screen} tab.
Select images to display as splash screens depending on the device
orientation and screen resolution.
\image qtcreator-android-manifest-editor-splash-screen.png "Splash screens in Android Manifest Editor"
By default, the splash screen is hidden automatically
when an activity is drawn. To keep it visible until
\l{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
on the device display or scale it to fill the display.
Set a background color in \uicontrol {Background color}.
Select the images with the highest resolution as the
\uicontrol {Master image}, \uicontrol {Portrait master image},
and \uicontrol {Landscape master image}.
Select \uicontrol {Clear All} to reset all settings or remove all images.
\section2 Android Manifest Editor \section2 Android Manifest Editor
If you use qmake as the build system, you can create an Android manifest If you use qmake as the build system, you can create an Android manifest
@@ -447,22 +495,11 @@
\li In the \uicontrol {Screen orientation} field, select the option for \li In the \uicontrol {Screen orientation} field, select the option for
determining \l{Screen Orientation}{screen orientation}. determining \l{Screen Orientation}{screen orientation}.
\li In \uicontrol {Application icon}, select an image with the highest \li In \uicontrol {Application icon}, specify images to use as application
\l{Supported Resolutions}{resolution} as the \uicontrol {Master icon}. icons depending on screen resolution.
\QC resizes the icon and sets versions of it to be shown on low,
medium, high, and extra high DPI displays, as needed. Alternatively,
set the icons for each resolution separately.
\image qtcreator-android-manifest-editor-app-icon.png "Application icons in Android Manifest Editor"
\li In \uicontrol {Splash screen}, select images to display as splash \li In \uicontrol {Splash screen}, select images to display as splash
screens depending on the device orientation. You can set different images screens depending on the screen orientation and resolution.
to be shown on low, medium, high, and extra high DPI displays. By default,
the splash screen is hidden automatically when an activity is drawn. To keep
it visible until \l{QtAndroid::hideSplashScreen()} is called, select the
\uicontrol {Sticky splash screen} check box.
\image qtcreator-android-manifest-editor-splash-screen.png "Splash screens in Android Manifest Editor"
\li In \uicontrol {Android services}, select \uicontrol Add to add a service. \li In \uicontrol {Android services}, select \uicontrol Add to add a service.
You must enter at least a service class name for a new service. If you select You must enter at least a service class name for a new service. If you select

View File

@@ -43,6 +43,10 @@
code by selecting them in a context menu. For more information, see code by selecting them in a context menu. For more information, see
\l{Applying Refactoring Actions}. \l{Applying Refactoring Actions}.
By default, the refactored files are saved automatically. To disable
this feature, deselect \uicontrol Tools > \uicontrol Options >
\uicontrol System > \uicontrol {Auto-save files after refactoring}.
\if defined(qtcreator) \if defined(qtcreator)
\section1 Finding Symbols \section1 Finding Symbols

View File

@@ -85,12 +85,35 @@
The backgound of the \uicontrol Text element determines the background of the The backgound of the \uicontrol Text element determines the background of the
code editor. code editor.
\li In \uicontrol Font, select \uicontrol Bold or \uicontrol Italic to
format the text of the selected code element by making it bold or
italic.
\li In \uicontrol Underline, select the color and style to use for
underlining code elements.
\endlist \endlist
When you copy code from \QC, it is copied in both plain text and HTML When you copy code from \QC, it is copied in both plain text and HTML
format. The latter makes sure that syntax highlighting is preserved when format. The latter makes sure that syntax highlighting is preserved when
pasting to a rich-text editor. pasting to a rich-text editor.
\section2 Exporting and Importing Color Schemes
To share color schemes with others, export and import them as XML files.
To export a color scheme, select \uicontrol Tools > \uicontrol Options >
\uicontrol {Text Editor} > \uicontrol {Fonts & Color} > \uicontrol Export,
and then select the filename and location for the XML file.
To import a color scheme, select \uicontrol Import, and then select the XML
file to import. In the \uicontrol {Import Color Scheme} dialog, enter a name
for the color scheme in \uicontrol {Color scheme name}:
\image qtcreator-import-color-scheme.png "Import Color Scheme dialog"
When you select \uicontrol OK, the color scheme is added to the list of
color schemes in the \uicontrol {Fonts & Color} tab.
\section2 File Encoding \section2 File Encoding
To define the default file encoding, select \uicontrol Tools > To define the default file encoding, select \uicontrol Tools >

View File

@@ -385,7 +385,11 @@
\li \l{http://code.qt.io/cgit/clang/clang.git} \li \l{http://code.qt.io/cgit/clang/clang.git}
\endlist \endlist
\li \b{Reference implementation for std::experimental::optional} \li \b{Optional}
A single-header header-only library for representing optional
(nullable) objects for C++14 (and C++11 to some extent) and passing
them by value.
Copyright (C) 2011-2012 Andrzej Krzemienski Copyright (C) 2011-2012 Andrzej Krzemienski
@@ -404,7 +408,9 @@
\li \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/src/libs/3rdparty/optional} \li \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/src/libs/3rdparty/optional}
\endlist \endlist
\li \b{Implementation for std::variant} \li \b{MPark.Variant}
MPark.Variant is an implementation of C++17 std::variant for C++11/14/17.
Copyright Michael Park, 2015-2017 Copyright Michael Park, 2015-2017
@@ -419,7 +425,11 @@
\li \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/src/libs/3rdparty/variant} \li \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/src/libs/3rdparty/variant}
\endlist \endlist
\li \b{Implementation for std::span} \li \b{std::span implementation for C++11 and later}
A single-header implementation of C++20's std::span, conforming to
the C++20 committee draft. It is compatible with C++11, but will use
newer language features if they are available.
Copyright Tristan Brindle, 2018 Copyright Tristan Brindle, 2018
@@ -613,7 +623,10 @@
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\endcode \endcode
\li \b{SQLite, an embedded database. Version 3.8.10.2}\br\br \li \b{SQLite (version 3.8.10.2)}
SQLite is a C-language library that implements a small, fast,
self-contained, high-reliability, full-featured, SQL database engine.
The author or authors of this code dedicate any and all copyright The author or authors of this code dedicate any and all copyright
interest in this code to the public domain. We make this dedication interest in this code to the public domain. We make this dedication
@@ -628,11 +641,15 @@
\li \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/src/libs/3rdparty/sqlite} \li \l{https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/src/libs/3rdparty/sqlite}
\endlist \endlist
\li \b{three.js (license MIT)}\br \li \b{three.js}
Copyright (C) 2010-2015 three.js authors\br
Copyright (C) 2010-2015 three.js authors
MIT License.
share/qtcreator/templates/wizards/projects/qmake/qtcanvas3dapplication share/qtcreator/templates/wizards/projects/qmake/qtcanvas3dapplication
\li \b{OpenSSL toolkit} \li \b{OpenSSL}
The OpenSSL toolkit stays under a double license, i.e. both the conditions of The OpenSSL toolkit stays under a double license, i.e. both the conditions of
the OpenSSL License and the original SSLeay license apply to the toolkit. the OpenSSL License and the original SSLeay license apply to the toolkit.
@@ -753,7 +770,7 @@
[including the GNU Public Licence.] [including the GNU Public Licence.]
\endcode \endcode
\li \b{Mesa LLVMPipe, 3D graphics library} \li \b{LLVMPipe - The Mesa 3D Graphics Library}
Mesa is a 3D graphics library with an API which is very similar to that Mesa is a 3D graphics library with an API which is very similar to that
of OpenGL. The llvmpipe software renderer enables the running of OpenGL of OpenGL. The llvmpipe software renderer enables the running of OpenGL
@@ -826,7 +843,7 @@
from Florian Loitsch which is licensed under the MIT License (see above). from Florian Loitsch which is licensed under the MIT License (see above).
Copyright (C) 2009 Florian Loitsch Copyright (C) 2009 Florian Loitsch
\li \b Minitrace \li \b minitrace
Simple C/C++ library for producing JSON traces. Simple C/C++ library for producing JSON traces.

View File

@@ -56,11 +56,11 @@
Qt applications for Android are compiled as \c {shared objects} that Qt applications for Android are compiled as \c {shared objects} that
are loaded by a Java launcher that is part of Qt. are loaded by a Java launcher that is part of Qt.
This is totally transparent to users. As Qt is composed of libraries This is totally transparent to users. As Qt is composed of libraries
referencing each other, Qt 4 applications are only supported on referencing each other, Qt 5 applications are only supported on
Android version 1.6, or later, and Qt 5 applications on version Android version 4.1 (API level 16), or later, and Qt 6 applications
4.1 (API level 16), or later. You must install a Qt version on Android version 6.0 (API level 23), or later. You must install a
targeting Android and the Android SDK and NDK to develop for Qt version targeting Android and the Android SDK and NDK to develop
Android devices. for Android devices.
\if defined(qtcreator) \if defined(qtcreator)
\li \l{Connecting Bare Metal Devices} \li \l{Connecting Bare Metal Devices}

View File

@@ -55,7 +55,8 @@
\li Click the \uicontrol {Build and Run Kit Selector} icon (1) or select \li Click the \uicontrol {Build and Run Kit Selector} icon (1) or select
\uicontrol Build > \uicontrol {Open Build and Run Kit Selector} to select the \uicontrol Build > \uicontrol {Open Build and Run Kit Selector} to select the
build and run \l{glossary-buildandrun-kit}{kit}. build and run \l{glossary-buildandrun-kit}{kit} or an
\l{Managing Android Virtual Devices (AVD)}{Android device}.
\image qtcreator-kit-selector.png "Kit selector" \image qtcreator-kit-selector.png "Kit selector"

View File

@@ -1,6 +1,6 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2020 The Qt Company Ltd. ** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the Qt Creator documentation. ** This file is part of the Qt Creator documentation.
@@ -48,8 +48,8 @@
\list 1 \list 1
\li Select \uicontrol File > \uicontrol {New File or Project} > \li Select \uicontrol File > \uicontrol {New File or Project} >
\uicontrol Application (Qt) > \uicontrol {Qt Widgets Application} > \uicontrol {Application (Qt)} > \uicontrol {Qt Widgets Application}
\uicontrol Choose. > \uicontrol Choose.
\image qtcreator-new-qt-gui-application.png "New File or Project dialog" \image qtcreator-new-qt-gui-application.png "New File or Project dialog"
@@ -60,10 +60,11 @@
\li In the \uicontrol{Name} field, type \b {TextFinder}. \li In the \uicontrol{Name} field, type \b {TextFinder}.
\li In the \uicontrol {Create in} field, enter the path for the project files. \li In the \uicontrol {Create in} field, enter the path for the project files.
For example, \c {C:\Qt\examples}, and then select \uicontrol{Next} (on For example, \c {C:\Qt\examples}.
Windows and Linux) or \uicontrol Continue (on \macos).
The \uicontrol {Define Build System} dialog opens. \li Select \uicontrol{Next} (on Windows and Linux) or
\uicontrol Continue (on \macos) to open the
\uicontrol {Define Build System} dialog.
\image qtcreator-new-project-build-system-qt-gui.png "Define Build System dialog" \image qtcreator-new-project-build-system-qt-gui.png "Define Build System dialog"
@@ -71,7 +72,8 @@
use for building and running the project: \l qmake, use for building and running the project: \l qmake,
\l {Setting Up CMake}{CMake}, or \l {Setting Up Qbs}{Qbs}. \l {Setting Up CMake}{CMake}, or \l {Setting Up Qbs}{Qbs}.
The \uicontrol{Class Information} dialog opens. \li Select \uicontrol Next or \uicontrol Continue to open the
\uicontrol{Class Information} dialog.
\image qtcreator-class-info-qt-gui.png "Class Information dialog" \image qtcreator-class-info-qt-gui.png "Class Information dialog"
@@ -84,16 +86,26 @@
\note The \uicontrol{Header file}, \uicontrol{Source file} and \uicontrol{Form file} \note The \uicontrol{Header file}, \uicontrol{Source file} and \uicontrol{Form file}
fields are automatically updated to match the name of the class. fields are automatically updated to match the name of the class.
The \uicontrol {Kit Selection} dialog opens. \li Select \uicontrol Next or \uicontrol Continue to open the
\uicontrol {Translation File} dialog.
\image qtcreator-new-qt-gui-application-translationfile.png "Translation File dialog"
\li In the \uicontrol Language field, you can select a language that you
plan to \l {Using Qt Linguist}{translate} the application to. This
sets up localization support for the application. You can add other
languages later by editing the project file.
\li Select \uicontrol Next or \uicontrol Continue to open the
\uicontrol {Kit Selection} dialog.
\image qtcreator-new-project-qt-versions-qt-gui.png "Kit Selection dialog" \image qtcreator-new-project-qt-versions-qt-gui.png "Kit Selection dialog"
\li Select build and run \l{glossary-buildandrun-kit}{kits} for your project, \li Select build and run \l{glossary-buildandrun-kit}{kits} for your
and select \uicontrol Next or \uicontrol Continue. project.
\li Select \uicontrol Next or \uicontrol Continue. \li Select \uicontrol Next or \uicontrol Continue to open the
\uicontrol {Project Management} dialog.
The \uicontrol{Project Management} dialog opens.
\image qtcreator-new-project-summary-qt-gui.png "Project Management dialog" \image qtcreator-new-project-summary-qt-gui.png "Project Management dialog"
@@ -105,7 +117,8 @@
\note The project opens in the \uicontrol Edit mode, and these instructions are \note The project opens in the \uicontrol Edit mode, and these instructions are
hidden. To return to these instructions, open the \uicontrol Help mode. hidden. To return to these instructions, open the \uicontrol Help mode.
The TextFinder project now contains the following files: If you selected qmake as the build system, the TextFinder project now
contains the following files:
\list \list
@@ -122,6 +135,9 @@
The .h and .cpp files come with the necessary boiler plate code. The .h and .cpp files come with the necessary boiler plate code.
The .pro file is complete. The .pro file is complete.
If you selected CMake as the build system, \QC created a CMakeLists.txt
project file for you.
\section1 Filling in the Missing Pieces \section1 Filling in the Missing Pieces
Begin by designing the user interface and then move on to filling Begin by designing the user interface and then move on to filling

View File

@@ -51,7 +51,7 @@ Item {
if (url.startsWith("file:///")) // remove file scheme (happens on Windows) if (url.startsWith("file:///")) // remove file scheme (happens on Windows)
url = url.substr(8) url = url.substr(8)
var ext = url.slice(url.lastIndexOf('.') + 1).toLowerCase() var ext = url.slice(url.lastIndexOf('.') + 1).toLowerCase()
if (rootView.supportedSuffixes().includes('*.' + ext)) if (rootView.supportedDropSuffixes().includes('*.' + ext))
files.push(url) files.push(url)
} }

View File

@@ -82,7 +82,7 @@ Item {
property var currentImport: null property var currentImport: null
property bool isHorizontalView: false property bool isHorizontalView: false
// called from C++ to close context menu on focus out // Called also from C++ to close context menu on focus out
function closeContextMenu() function closeContextMenu()
{ {
moduleContextMenu.close() moduleContextMenu.close()
@@ -93,6 +93,8 @@ Item {
itemsView.isHorizontalView = itemsView.width > widthLimit itemsView.isHorizontalView = itemsView.width > widthLimit
} }
onIsHorizontalViewChanged: closeContextMenu()
Item { Item {
id: styleConstants id: styleConstants
property int textWidth: 58 property int textWidth: 58

View File

@@ -0,0 +1,37 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import HelperWidgets 2.0
import StudioControls 1.0 as StudioControls
import StudioTheme 1.0 as StudioTheme
Column {
anchors.left: parent.left
anchors.right: parent.right
AudioSection {}
}

View File

@@ -0,0 +1,67 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import HelperWidgets 2.0
import StudioControls 1.0 as StudioControls
import StudioTheme 1.0 as StudioTheme
Section {
caption: qsTr("Audio")
anchors.left: parent.left
anchors.right: parent.right
SectionLayout {
PropertyLabel { text: qsTr("Volume") }
SecondColumnLayout {
SpinBox {
implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth
backendValue: backendValues.volume
decimals: 1
minimumValue: 0.0
maximumValue: 1.0
}
ExpandingSpacer {}
}
PropertyLabel { text: qsTr("Muted") }
SecondColumnLayout {
CheckBox {
implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth
backendValue: backendValues.muted
text: backendValues.muted.valueToString
}
ExpandingSpacer {}
}
}
}

View File

@@ -0,0 +1,56 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import HelperWidgets 2.0
import StudioControls 1.0 as StudioControls
import StudioTheme 1.0 as StudioTheme
Section {
caption: qsTr("Media Player")
anchors.left: parent.left
anchors.right: parent.right
// TODO position property, what should be the range?!
SectionLayout {
PropertyLabel { text: qsTr("Playback rate") }
SecondColumnLayout {
SpinBox {
implicitWidth: StudioTheme.Values.twoControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth
backendValue: backendValues.playbackRate
decimals: 1
minimumValue: -1000 // TODO correct range
maximumValue: 1000
}
ExpandingSpacer {}
}
}
}

View File

@@ -0,0 +1,37 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import HelperWidgets 2.0
import StudioControls 1.0 as StudioControls
import StudioTheme 1.0 as StudioTheme
Column {
anchors.left: parent.left
anchors.right: parent.right
MediaPlayerSection {}
}

View File

@@ -0,0 +1,105 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import HelperWidgets 2.0
import StudioControls 1.0 as StudioControls
import StudioTheme 1.0 as StudioTheme
Section {
caption: qsTr("Video")
anchors.left: parent.left
anchors.right: parent.right
SectionLayout {
PropertyLabel { text: qsTr("Source") }
SecondColumnLayout {
UrlChooser {
backendValue: backendValues.source
filter: "*.mp4"
}
ExpandingSpacer {}
}
PropertyLabel { text: qsTr("Fill mode") }
SecondColumnLayout {
ComboBox {
implicitWidth: StudioTheme.Values.singleControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth
width: implicitWidth
scope: "VideoOutput"
model: ["Stretch", "PreserveAspectFit", "PreserveAspectCrop"]
backendValue: backendValues.fillMode
}
ExpandingSpacer {}
}
PropertyLabel { text: qsTr("Orientation") }
SecondColumnLayout {
ComboBox {
id: orientationComboBox
implicitWidth: StudioTheme.Values.singleControlColumnWidth
+ StudioTheme.Values.actionIndicatorWidth
width: implicitWidth
model: [0, 90, 180, 270, 360]
backendValue: backendValues.orientation
manualMapping: true
onValueFromBackendChanged: {
if (!orientationComboBox.__isCompleted)
return
orientationComboBox.syncIndexToBackendValue()
}
onCompressedActivated: {
if (!orientationComboBox.__isCompleted)
return
if (orientationComboBox.block)
return
backendValues.orientation.value = orientationComboBox.model[orientationComboBox.currentIndex]
}
Component.onCompleted: orientationComboBox.syncIndexToBackendValue()
function syncIndexToBackendValue() {
orientationComboBox.block = true
orientationComboBox.currentIndex = orientationComboBox.model.indexOf(backendValues.orientation.value)
orientationComboBox.block = false
}
}
ExpandingSpacer {}
}
}
}

View File

@@ -0,0 +1,41 @@
/****************************************************************************
**
** 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.
**
****************************************************************************/
import QtQuick 2.15
import QtQuick.Layouts 1.15
import HelperWidgets 2.0
import StudioControls 1.0 as StudioControls
import StudioTheme 1.0 as StudioTheme
Column {
anchors.left: parent.left
anchors.right: parent.right
MediaPlayerSection {}
VideoSection {}
AudioSection {}
}

View File

@@ -102,6 +102,7 @@ jobs:
run: | run: |
set(qt_version "$ENV{QT_VERSION}") set(qt_version "$ENV{QT_VERSION}")
string(REGEX MATCH "^[0-9]+" qt_version_major "${qt_version}")
string(REPLACE "." "" qt_version_dotless "${qt_version}") string(REPLACE "." "" qt_version_dotless "${qt_version}")
if ("${{ runner.os }}" STREQUAL "Windows") if ("${{ runner.os }}" STREQUAL "Windows")
set(url_os "windows_x86") set(url_os "windows_x86")
@@ -112,45 +113,63 @@ jobs:
set(url_os "linux_x64") set(url_os "linux_x64")
set(qt_package_arch_suffix "gcc_64") set(qt_package_arch_suffix "gcc_64")
set(qt_dir_prefix "${qt_version}/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") if("${qt_version_major}" STREQUAL "5")
set(qt_package_suffix "-Linux-RHEL_7_6-GCC-Linux-RHEL_7_6-X86_64")
else()
set(qt_package_suffix "-Linux-RHEL_8_2-GCC-Linux-RHEL_8_2-X86_64")
endif()
elseif ("${{ runner.os }}" STREQUAL "macOS") elseif ("${{ runner.os }}" STREQUAL "macOS")
set(url_os "mac_x64") set(url_os "mac_x64")
set(qt_package_arch_suffix "clang_64") set(qt_package_arch_suffix "clang_64")
set(qt_dir_prefix "${qt_version}/clang_64") if("${qt_version_major}" STREQUAL "5")
set(qt_package_suffix "-MacOS-MacOS_10_13-Clang-MacOS-MacOS_10_13-X86_64") set(qt_dir_prefix "${qt_version}/clang_64")
set(qt_package_suffix "-MacOS-MacOS_10_13-Clang-MacOS-MacOS_10_13-X86_64")
else()
set(qt_dir_prefix "${qt_version}/macos")
set(qt_package_suffix "-MacOS-MacOS_11_00-Clang-MacOS-MacOS_11_00-X86_64-ARM64")
endif()
endif() endif()
set(qt_base_url "https://download.qt.io/online/qtsdkrepository/${url_os}/desktop/qt5_${qt_version_dotless}") set(qt_base_url "https://download.qt.io/online/qtsdkrepository/${url_os}/desktop/qt${qt_version_major}_${qt_version_dotless}")
file(DOWNLOAD "${qt_base_url}/Updates.xml" ./Updates.xml SHOW_PROGRESS) file(DOWNLOAD "${qt_base_url}/Updates.xml" ./Updates.xml SHOW_PROGRESS)
file(READ ./Updates.xml updates_xml) file(READ ./Updates.xml updates_xml)
string(REGEX MATCH "<Name>qt.qt5.*<Version>([0-9+-.]+)</Version>" updates_xml_output "${updates_xml}") string(REGEX MATCH "<Name>qt.qt${qt_version_major}.*<Version>([0-9+-.]+)</Version>" updates_xml_output "${updates_xml}")
set(qt_package_version ${CMAKE_MATCH_1}) set(qt_package_version ${CMAKE_MATCH_1})
file(MAKE_DIRECTORY qt5) file(MAKE_DIRECTORY qt)
# Save the path for other steps # Save the path for other steps
file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qt5/${qt_dir_prefix}" qt_dir) file(TO_CMAKE_PATH "$ENV{GITHUB_WORKSPACE}/qt/${qt_dir_prefix}" qt_dir)
message("::set-output name=qt_dir::${qt_dir}") message("::set-output name=qt_dir::${qt_dir}")
message("Downloading Qt to ${qt_dir}") message("Downloading Qt to ${qt_dir}")
function(downloadAndExtract url archive) function(downloadAndExtract url archive)
message("Downloading ${url}") message("Downloading ${url}")
file(DOWNLOAD "${url}" ./${archive} SHOW_PROGRESS) file(DOWNLOAD "${url}" ./${archive} SHOW_PROGRESS)
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ../${archive} WORKING_DIRECTORY qt5) execute_process(COMMAND ${CMAKE_COMMAND} -E tar xvf ../${archive} WORKING_DIRECTORY qt)
endfunction() endfunction()
foreach(package qtbase qtdeclarative) foreach(package qtbase qtdeclarative)
downloadAndExtract( downloadAndExtract(
"${qt_base_url}/qt.qt5.${qt_version_dotless}.${qt_package_arch_suffix}/${qt_package_version}${package}${qt_package_suffix}.7z" "${qt_base_url}/qt.qt${qt_version_major}.${qt_version_dotless}.${qt_package_arch_suffix}/${qt_package_version}${package}${qt_package_suffix}.7z"
${package}.7z ${package}.7z
) )
endforeach() endforeach()
if("${qt_version_major}" STREQUAL "6")
foreach(package qt5compat qtshadertools)
downloadAndExtract(
"${qt_base_url}/qt.qt6.${qt_version_dotless}.${package}.${qt_package_arch_suffix}/${qt_package_version}${package}${qt_package_suffix}.7z"
${package}.7z
)
endforeach()
endif()
# uic depends on libicu56.so # uic depends on libicu56.so
if ("${{ runner.os }}" STREQUAL "Linux") if ("${{ runner.os }}" STREQUAL "Linux")
downloadAndExtract( downloadAndExtract(
"${qt_base_url}/qt.qt5.${qt_version_dotless}.${qt_package_arch_suffix}/${qt_package_version}icu-linux-Rhel7.2-x64.7z" "${qt_base_url}/qt.qt${qt_version_major}.${qt_version_dotless}.${qt_package_arch_suffix}/${qt_package_version}icu-linux-Rhel7.2-x64.7z"
icu.7z icu.7z
) )
endif() endif()

View File

@@ -529,6 +529,24 @@ public:
void clearSemanticTokens() { remove(semanticTokensKey); } void clearSemanticTokens() { remove(semanticTokensKey); }
}; };
class LANGUAGESERVERPROTOCOL_EXPORT SemanticTokensWorkspaceClientCapabilities : public JsonObject
{
public:
using JsonObject::JsonObject;
/**
* Whether the client implementation supports a refresh request sent from
* the server to the client.
*
* Note that this event is global and will force the client to refresh all
* semantic tokens currently shown. It should be used with absolute care
* and is useful for situation where a server for example detect a project
* wide change that requires such a calculation.
*/
Utils::optional<bool> refreshSupport() const { return optionalValue<bool>(refreshSupportKey); }
void setRefreshSupport(bool refreshSupport) { insert(refreshSupportKey, refreshSupport); }
void clearRefreshSupport() { remove(refreshSupportKey); }
};
class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceClientCapabilities : public JsonObject class LANGUAGESERVERPROTOCOL_EXPORT WorkspaceClientCapabilities : public JsonObject
{ {
public: public:
@@ -601,6 +619,12 @@ public:
Utils::optional<bool> configuration() const { return optionalValue<bool>(configurationKey); } Utils::optional<bool> configuration() const { return optionalValue<bool>(configurationKey); }
void setConfiguration(bool configuration) { insert(configurationKey, configuration); } void setConfiguration(bool configuration) { insert(configurationKey, configuration); }
void clearConfiguration() { remove(configurationKey); } void clearConfiguration() { remove(configurationKey); }
Utils::optional<SemanticTokensWorkspaceClientCapabilities> semanticTokens() const
{ return optionalValue<SemanticTokensWorkspaceClientCapabilities>(semanticTokensKey); }
void setSemanticTokens(const SemanticTokensWorkspaceClientCapabilities &semanticTokens)
{ insert(semanticTokensKey, semanticTokens); }
void clearSemanticTokens() { remove(semanticTokensKey); }
}; };
class WindowClientClientCapabilities : public JsonObject class WindowClientClientCapabilities : public JsonObject

View File

@@ -171,6 +171,7 @@ constexpr char reasonKey[] = "reason";
constexpr char redKey[] = "red"; constexpr char redKey[] = "red";
constexpr char referencesKey[] = "references"; constexpr char referencesKey[] = "references";
constexpr char referencesProviderKey[] = "referencesProvider"; constexpr char referencesProviderKey[] = "referencesProvider";
constexpr char refreshSupportKey[] = "refreshSupport";
constexpr char registerOptionsKey[] = "registerOptions"; constexpr char registerOptionsKey[] = "registerOptions";
constexpr char registrationsKey[] = "registrations"; constexpr char registrationsKey[] = "registrations";
constexpr char removedKey[] = "removed"; constexpr char removedKey[] = "removed";

View File

@@ -156,4 +156,8 @@ SemanticTokensDeltaResult::SemanticTokensDeltaResult(const QJsonValue &value)
} }
} }
SemanticTokensRefreshRequest::SemanticTokensRefreshRequest()
: Request(methodName, nullptr)
{}
} // namespace LanguageServerProtocol } // namespace LanguageServerProtocol

View File

@@ -240,4 +240,13 @@ public:
constexpr static const char methodName[] = "textDocument/semanticTokens/range"; constexpr static const char methodName[] = "textDocument/semanticTokens/range";
}; };
class LANGUAGESERVERPROTOCOL_EXPORT SemanticTokensRefreshRequest
: public Request<std::nullptr_t, std::nullptr_t, std::nullptr_t>
{
public:
explicit SemanticTokensRefreshRequest();
using Request::Request;
constexpr static const char methodName[] = "workspace/semanticTokens/refresh";
};
} // namespace LanguageServerProtocol } // namespace LanguageServerProtocol

View File

@@ -1081,8 +1081,9 @@ void StringAspect::addToLayout(LayoutBuilder &builder)
d->m_blockAutoApply = false; d->m_blockAutoApply = false;
}); });
} else { } else {
connect(d->m_pathChooserDisplay, &PathChooser::pathChanged, this, [this] { connect(d->m_pathChooserDisplay, &PathChooser::pathChanged,
setValue(d->m_pathChooserDisplay->filePath().toString()); this, [this](const QString &path) {
setValue(path);
}); });
} }
} }

View File

@@ -32,12 +32,15 @@
#include "stringutils.h" #include "stringutils.h"
#include <QCoreApplication> #include <QCoreApplication>
#include <QLoggingCategory>
#include <QMutex> #include <QMutex>
#include <QRegularExpression> #include <QRegularExpression>
#include <QTextCodec> #include <QTextCodec>
#include <cctype> #include <cctype>
Q_LOGGING_CATEGORY(log, "qtc.utils.filesearch", QtWarningMsg)
using namespace Utils; using namespace Utils;
static inline QString msgCanceled(const QString &searchTerm, int numMatches, int numFilesSearched) static inline QString msgCanceled(const QString &searchTerm, int numMatches, int numFilesSearched)
@@ -140,11 +143,13 @@ void FileSearch::operator()(QFutureInterface<FileSearchResultList> &futureInterf
{ {
if (futureInterface.isCanceled()) if (futureInterface.isCanceled())
return; return;
qCDebug(log) << "Searching in" << item.filePath;
futureInterface.setProgressRange(0, 1); futureInterface.setProgressRange(0, 1);
futureInterface.setProgressValue(0); futureInterface.setProgressValue(0);
FileSearchResultList results; FileSearchResultList results;
QString tempString; QString tempString;
if (!getFileContent(item.filePath, item.encoding, &tempString, fileToContentsMap)) { if (!getFileContent(item.filePath, item.encoding, &tempString, fileToContentsMap)) {
qCDebug(log) << "- failed to get content for" << item.filePath;
futureInterface.cancel(); // failure futureInterface.cancel(); // failure
return; return;
} }
@@ -222,6 +227,7 @@ void FileSearch::operator()(QFutureInterface<FileSearchResultList> &futureInterf
futureInterface.reportResult(results); futureInterface.reportResult(results);
futureInterface.setProgressValue(1); futureInterface.setProgressValue(1);
} }
qCDebug(log) << "- finished searching in" << item.filePath;
} }
FileSearchRegExp::FileSearchRegExp(const QString &searchTerm, QTextDocument::FindFlags flags, FileSearchRegExp::FileSearchRegExp(const QString &searchTerm, QTextDocument::FindFlags flags,
@@ -257,11 +263,13 @@ void FileSearchRegExp::operator()(QFutureInterface<FileSearchResultList> &future
} }
if (futureInterface.isCanceled()) if (futureInterface.isCanceled())
return; return;
qCDebug(log) << "Searching in" << item.filePath;
futureInterface.setProgressRange(0, 1); futureInterface.setProgressRange(0, 1);
futureInterface.setProgressValue(0); futureInterface.setProgressValue(0);
FileSearchResultList results; FileSearchResultList results;
QString tempString; QString tempString;
if (!getFileContent(item.filePath, item.encoding, &tempString, fileToContentsMap)) { if (!getFileContent(item.filePath, item.encoding, &tempString, fileToContentsMap)) {
qCDebug(log) << "- failed to get content for" << item.filePath;
futureInterface.cancel(); // failure futureInterface.cancel(); // failure
return; return;
} }
@@ -296,6 +304,7 @@ void FileSearchRegExp::operator()(QFutureInterface<FileSearchResultList> &future
futureInterface.reportResult(results); futureInterface.reportResult(results);
futureInterface.setProgressValue(1); futureInterface.setProgressValue(1);
} }
qCDebug(log) << "- finished searching in" << item.filePath;
} }
struct SearchState struct SearchState

View File

@@ -141,10 +141,8 @@ QList<CallerHandle::SignalType> CallerHandle::flushFor(CallerHandle::SignalType
{ {
// 1. If signalType is no signal - flush all // 1. If signalType is no signal - flush all
// 2. Flush all if we have any error // 2. Flush all if we have any error
// 3. If we are flushing for Finished, flush Started / ReadyRead, too // 3. If we are flushing for Finished or ReadyRead, flush all, too
// 4. If we are flushing for ReadyRead, flush Started, too // 4. If we are flushing for Started, flush Started only
// 5. (?) If we have collected Finished, flush it only when flushing
// for ReadyRead / Finished (not for Started)
QMutexLocker locker(&m_mutex); QMutexLocker locker(&m_mutex);
@@ -154,6 +152,7 @@ QList<CallerHandle::SignalType> CallerHandle::flushFor(CallerHandle::SignalType
}); });
const bool flushAll = (signalType == CallerHandle::SignalType::NoSignal) const bool flushAll = (signalType == CallerHandle::SignalType::NoSignal)
|| (signalType == CallerHandle::SignalType::ReadyRead)
|| (signalType == CallerHandle::SignalType::Finished) || (signalType == CallerHandle::SignalType::Finished)
|| storedSignals.contains(CallerHandle::SignalType::Error); || storedSignals.contains(CallerHandle::SignalType::Error);
if (flushAll) { if (flushAll) {

View File

@@ -27,6 +27,7 @@
#include "algorithm.h" #include "algorithm.h"
#include "camelcasecursor.h" #include "camelcasecursor.h"
#include "hostosinfo.h"
#include "qtcassert.h" #include "qtcassert.h"
#include <QKeyEvent> #include <QKeyEvent>
@@ -296,7 +297,10 @@ static QTextLine currentTextLine(const QTextCursor &cursor)
bool multiCursorAddEvent(QKeyEvent *e, QKeySequence::StandardKey matchKey) bool multiCursorAddEvent(QKeyEvent *e, QKeySequence::StandardKey matchKey)
{ {
uint searchkey = (e->modifiers() | e->key()) uint searchkey = (e->modifiers() | e->key())
& ~(Qt::KeypadModifier | Qt::GroupSwitchModifier | Qt::AltModifier); & ~(Qt::KeypadModifier
| Qt::GroupSwitchModifier
| Qt::AltModifier
| Qt::ShiftModifier);
const QList<QKeySequence> bindings = QKeySequence::keyBindings(matchKey); const QList<QKeySequence> bindings = QKeySequence::keyBindings(matchKey);
return bindings.contains(QKeySequence(searchkey)); return bindings.contains(QKeySequence(searchkey));
@@ -306,7 +310,7 @@ bool MultiTextCursor::handleMoveKeyEvent(QKeyEvent *e,
QPlainTextEdit *edit, QPlainTextEdit *edit,
bool camelCaseNavigationEnabled) bool camelCaseNavigationEnabled)
{ {
if (e->modifiers() & Qt::AltModifier) { if (e->modifiers() & Qt::AltModifier && !Utils::HostOsInfo::isMacHost()) {
QTextCursor::MoveOperation op = QTextCursor::NoMove; QTextCursor::MoveOperation op = QTextCursor::NoMove;
if (multiCursorAddEvent(e, QKeySequence::MoveToNextWord)) { if (multiCursorAddEvent(e, QKeySequence::MoveToNextWord)) {
op = QTextCursor::WordRight; op = QTextCursor::WordRight;

View File

@@ -840,11 +840,23 @@ QStringList AndroidConfig::getAbis(const QString &device)
bool AndroidConfig::isValidNdk(const QString &ndkLocation) const bool AndroidConfig::isValidNdk(const QString &ndkLocation) const
{ {
auto ndkPath = Utils::FilePath::fromUserInput(ndkLocation); auto ndkPath = Utils::FilePath::fromUserInput(ndkLocation);
const FilePath ndkPlatformsDir = ndkPath.pathAppended("platforms");
return ndkPath.exists() && ndkPath.pathAppended("toolchains").exists() if (!ndkPath.exists())
&& ndkPlatformsDir.exists() && !ndkPlatformsDir.toString().contains(' ') return false;
&& !ndkVersion(ndkPath).isNull();
if (!ndkPath.pathAppended("toolchains").exists())
return false;
const QVersionNumber version = ndkVersion(ndkPath);
if (ndkVersion(ndkPath).isNull())
return false;
const FilePath ndkPlatformsDir = ndkPath.pathAppended("platforms");
if (version.majorVersion() <= 22
&& (!ndkPlatformsDir.exists() || ndkPlatformsDir.toString().contains(' ')))
return false; // TODO: Adapt code that assumes the presence of a "platforms" folder
return true;
} }
QString AndroidConfig::bestNdkPlatformMatch(int target, const BaseQtVersion *qtVersion) const QString AndroidConfig::bestNdkPlatformMatch(int target, const BaseQtVersion *qtVersion) const

View File

@@ -32,10 +32,9 @@
#include <qmldebug/qmloutputparser.h> #include <qmldebug/qmloutputparser.h>
#include <QObject> #include <QObject>
#include <QTimer>
#include <QTcpSocket> #include <QTcpSocket>
#include <QThread> #include <QThread>
#include <QProcess> #include <QTimer>
namespace Android { namespace Android {
namespace Internal { namespace Internal {

View File

@@ -28,11 +28,10 @@
#include "utils/qtcprocess.h" #include "utils/qtcprocess.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <QCryptographicHash>
#include <QDir> #include <QDir>
#include <QDirIterator> #include <QDirIterator>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QProcess>
#include <QCryptographicHash>
#include <QStandardPaths> #include <QStandardPaths>
using namespace Utils; using namespace Utils;

View File

@@ -41,7 +41,6 @@
#include <QLineEdit> #include <QLineEdit>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QMessageBox> #include <QMessageBox>
#include <QProcess>
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
namespace { namespace {

View File

@@ -62,7 +62,6 @@
#include <QFileInfo> #include <QFileInfo>
#include <QMenu> #include <QMenu>
#include <QPlainTextEdit> #include <QPlainTextEdit>
#include <QProcess>
#include <QScrollBar> #include <QScrollBar>
#include <QTextBlock> #include <QTextBlock>

View File

@@ -27,6 +27,7 @@
#include "clangcompletioncontextanalyzer.h" #include "clangcompletioncontextanalyzer.h"
#include "clangdiagnosticmanager.h" #include "clangdiagnosticmanager.h"
#include "clangmodelmanagersupport.h"
#include "clangpreprocessorassistproposalitem.h" #include "clangpreprocessorassistproposalitem.h"
#include "clangtextmark.h" #include "clangtextmark.h"
#include "clangutils.h" #include "clangutils.h"
@@ -51,6 +52,7 @@
#include <cppeditor/cppvirtualfunctionproposalitem.h> #include <cppeditor/cppvirtualfunctionproposalitem.h>
#include <cppeditor/semantichighlighter.h> #include <cppeditor/semantichighlighter.h>
#include <languageclient/languageclientinterface.h> #include <languageclient/languageclientinterface.h>
#include <languageclient/languageclientmanager.h>
#include <languageclient/languageclientutils.h> #include <languageclient/languageclientutils.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/projecttree.h> #include <projectexplorer/projecttree.h>
@@ -559,12 +561,12 @@ static BaseClientInterface *clientInterface(Project *project, const Utils::FileP
{ {
QString indexingOption = "--background-index"; QString indexingOption = "--background-index";
const CppEditor::ClangdSettings settings(CppEditor::ClangdProjectSettings(project).settings()); const CppEditor::ClangdSettings settings(CppEditor::ClangdProjectSettings(project).settings());
if (!settings.indexingEnabled()) if (!settings.indexingEnabled() || jsonDbDir.isEmpty())
indexingOption += "=0"; indexingOption += "=0";
const QString headerInsertionOption = QString("--header-insertion=") const QString headerInsertionOption = QString("--header-insertion=")
+ (settings.autoIncludeHeaders() ? "iwyu" : "never"); + (settings.autoIncludeHeaders() ? "iwyu" : "never");
Utils::CommandLine cmd{settings.clangdFilePath(), {indexingOption, headerInsertionOption, Utils::CommandLine cmd{settings.clangdFilePath(), {indexingOption, headerInsertionOption,
"--limit-results=0", "--clang-tidy=0"}}; "--limit-results=0", "--limit-references=0", "--clang-tidy=0"}};
if (settings.workerThreadLimit() != 0) if (settings.workerThreadLimit() != 0)
cmd.addArg("-j=" + QString::number(settings.workerThreadLimit())); cmd.addArg("-j=" + QString::number(settings.workerThreadLimit()));
if (!jsonDbDir.isEmpty()) if (!jsonDbDir.isEmpty())
@@ -654,6 +656,7 @@ public:
bool openInSplit) bool openInSplit)
: q(q), id(id), cursor(cursor), editorWidget(editorWidget), uri(uri), : q(q), id(id), cursor(cursor), editorWidget(editorWidget), uri(uri),
callback(std::move(callback)), virtualFuncAssistProvider(q->d), callback(std::move(callback)), virtualFuncAssistProvider(q->d),
docRevision(editorWidget ? editorWidget->textDocument()->document()->revision() : -1),
openInSplit(openInSplit) {} openInSplit(openInSplit) {}
~FollowSymbolData() ~FollowSymbolData()
@@ -678,6 +681,8 @@ public:
openedFiles.clear(); openedFiles.clear();
} }
bool defLinkIsAmbiguous() const;
ClangdClient * const q; ClangdClient * const q;
const quint64 id; const quint64 id;
const QTextCursor cursor; const QTextCursor cursor;
@@ -688,6 +693,7 @@ public:
QList<MessageId> pendingSymbolInfoRequests; QList<MessageId> pendingSymbolInfoRequests;
QList<MessageId> pendingGotoImplRequests; QList<MessageId> pendingGotoImplRequests;
QList<MessageId> pendingGotoDefRequests; QList<MessageId> pendingGotoDefRequests;
const int docRevision;
const bool openInSplit; const bool openInSplit;
Utils::Link defLink; Utils::Link defLink;
@@ -1059,6 +1065,12 @@ public:
// The highlighters are owned by their respective documents. // The highlighters are owned by their respective documents.
std::unordered_map<TextDocument *, CppEditor::SemanticHighlighter *> highlighters; std::unordered_map<TextDocument *, CppEditor::SemanticHighlighter *> highlighters;
QHash<TextDocument *, QPair<QList<ExpandedSemanticToken>, int>> previousTokens;
// The ranges of symbols referring to virtual functions, with document version,
// as extracted by the highlighting procedure.
QHash<TextDocument *, QPair<QList<Range>, int>> virtualRanges;
VersionedDataCache<const TextDocument *, AstNode> astCache; VersionedDataCache<const TextDocument *, AstNode> astCache;
VersionedDataCache<Utils::FilePath, AstNode> externalAstCache; VersionedDataCache<Utils::FilePath, AstNode> externalAstCache;
TaskTimer highlightingTimer{"highlighting"}; TaskTimer highlightingTimer{"highlighting"};
@@ -1074,6 +1086,10 @@ public:
: TextDocumentClientCapabilities::CompletionCapabilities(object) : TextDocumentClientCapabilities::CompletionCapabilities(object)
{ {
insert("editsNearCursor", true); // For dot-to-arrow correction. insert("editsNearCursor", true); // For dot-to-arrow correction.
if (Utils::optional<CompletionItemCapbilities> completionItemCaps = completionItem()) {
completionItemCaps->setSnippetSupport(false);
setCompletionItem(*completionItemCaps);
}
} }
}; };
@@ -1188,6 +1204,15 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir)
initOptions.insert("fallbackFlags", QJsonArray::fromStringList(clangOptions)); initOptions.insert("fallbackFlags", QJsonArray::fromStringList(clangOptions));
setInitializationOptions(initOptions); setInitializationOptions(initOptions);
} }
auto isRunningClangdClient = [](const LanguageClient::Client *c) {
return qobject_cast<const ClangdClient *>(c) && c->state() != Client::ShutdownRequested
&& c->state() != Client::Shutdown;
};
const QList<Client *> clients =
Utils::filtered(LanguageClientManager::clientsForProject(project), isRunningClangdClient);
QTC_CHECK(clients.isEmpty());
for (const Client *client : clients)
qCWarning(clangdLog) << client->name() << client->stateString();
ClientCapabilities caps = Client::defaultClientCapabilities(); ClientCapabilities caps = Client::defaultClientCapabilities();
Utils::optional<TextDocumentClientCapabilities> textCaps = caps.textDocument(); Utils::optional<TextDocumentClientCapabilities> textCaps = caps.textDocument();
if (textCaps) { if (textCaps) {
@@ -1366,6 +1391,8 @@ void ClangdClient::handleDocumentClosed(TextDocument *doc)
{ {
d->highlighters.erase(doc); d->highlighters.erase(doc);
d->astCache.remove(doc); d->astCache.remove(doc);
d->previousTokens.remove(doc);
d->virtualRanges.remove(doc);
} }
QVersionNumber ClangdClient::versionNumber() const QVersionNumber ClangdClient::versionNumber() const
@@ -1996,6 +2023,14 @@ void ClangdClient::gatherHelpItemForTooltip(const HoverRequest::Response &hoverR
d->getAndHandleAst(doc, astHandler, Private::AstCallbackMode::SyncIfPossible); d->getAndHandleAst(doc, astHandler, Private::AstCallbackMode::SyncIfPossible);
} }
void ClangdClient::setVirtualRanges(const Utils::FilePath &filePath, const QList<Range> &ranges,
int revision)
{
TextDocument * const doc = documentForFilePath(filePath);
if (doc && doc->document()->revision() == revision)
d->virtualRanges.insert(doc, {ranges, revision});
}
void ClangdClient::Private::handleGotoDefinitionResult() void ClangdClient::Private::handleGotoDefinitionResult()
{ {
QTC_ASSERT(followSymbolData->defLink.hasValidTarget(), return); QTC_ASSERT(followSymbolData->defLink.hasValidTarget(), return);
@@ -2003,8 +2038,7 @@ void ClangdClient::Private::handleGotoDefinitionResult()
qCDebug(clangdLog) << "handling go to definition result"; qCDebug(clangdLog) << "handling go to definition result";
// No dis-ambiguation necessary. Call back with the link and finish. // No dis-ambiguation necessary. Call back with the link and finish.
if (!followSymbolData->cursorNode->mightBeAmbiguousVirtualCall() if (!followSymbolData->defLinkIsAmbiguous()) {
&& !followSymbolData->cursorNode->isPureVirtualDeclaration()) {
followSymbolData->callback(followSymbolData->defLink); followSymbolData->callback(followSymbolData->defLink);
followSymbolData.reset(); followSymbolData.reset();
return; return;
@@ -2377,16 +2411,37 @@ static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
return true; return true;
if (token.type != "variable" && token.type != "property" && token.type != "parameter") if (token.type != "variable" && token.type != "property" && token.type != "parameter")
return false; return false;
const QList<AstNode> path = getAstPath(ast, tokenRange(token)); const Range range = tokenRange(token);
const QList<AstNode> path = getAstPath(ast, range);
if (path.size() < 2) if (path.size() < 2)
return false; return false;
if (path.last().hasConstType()) if (path.last().hasConstType())
return false; return false;
for (auto it = path.rbegin() + 1; it != path.rend(); ++it) { for (auto it = path.rbegin() + 1; it != path.rend(); ++it) {
if (it->kind() == "Call" || it->kind() == "CXXConstruct" if (it->kind() == "Call" || it->kind() == "CXXConstruct"
|| it->kind() == "MemberInitializer" || it->kind() == "CXXOperatorCall") { || it->kind() == "MemberInitializer") {
return true; return true;
} }
// The token should get marked for e.g. lambdas, but not for assignment operators,
// where the user sees that it's being written.
if (it->kind() == "CXXOperatorCall") {
const QList<AstNode> children = it->children().value_or(QList<AstNode>());
if (children.size() < 2)
return false;
if (!children.last().range().contains(range))
return false;
QList<AstNode> firstChildTree{children.first()};
while (!firstChildTree.isEmpty()) {
const AstNode n = firstChildTree.takeFirst();
const QString detail = n.detail().value_or(QString());
if (detail.startsWith("operator"))
return !detail.contains('=');
firstChildTree << n.children().value_or(QList<AstNode>());
}
return true;
}
if (it->kind().endsWith("Cast") && it->hasConstType()) if (it->kind().endsWith("Cast") && it->hasConstType())
return false; return false;
if (it->kind() == "Member" && it->arcanaContains("(") if (it->kind() == "Member" && it->arcanaContains("(")
@@ -2491,6 +2546,20 @@ static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
ExtraHighlightingResultsCollector(future, results, filePath, ast, &doc, docContents).collect(); ExtraHighlightingResultsCollector(future, results, filePath, ast, &doc, docContents).collect();
if (!future.isCanceled()) { if (!future.isCanceled()) {
qCDebug(clangdLog) << "reporting" << results.size() << "highlighting results"; qCDebug(clangdLog) << "reporting" << results.size() << "highlighting results";
QList<Range> virtualRanges;
for (const HighlightingResult &r : results) {
if (r.textStyles.mainStyle != C_VIRTUAL_METHOD)
continue;
const Position startPos(r.line - 1, r.column - 1);
virtualRanges << Range(startPos, startPos.withOffset(r.length, &doc));
}
QMetaObject::invokeMethod(ClangModelManagerSupport::instance(),
[filePath, virtualRanges, docRevision] {
if (ClangdClient * const client
= ClangModelManagerSupport::instance()->clientForFile(filePath)) {
client->setVirtualRanges(filePath, virtualRanges, docRevision);
}
}, Qt::QueuedConnection);
future.reportResults(QVector<HighlightingResult>(results.cbegin(), future.reportResults(QVector<HighlightingResult>(results.cbegin(),
results.cend())); results.cend()));
} }
@@ -2520,6 +2589,17 @@ void ClangdClient::Private::handleSemanticTokens(TextDocument *doc,
<< version << q->documentVersion(doc->filePath()); << version << q->documentVersion(doc->filePath());
return; return;
} }
const auto previous = previousTokens.find(doc);
if (previous != previousTokens.end()) {
if (previous->first == tokens && previous->second == version) {
qCDebug(clangdLogHighlight) << "tokens and version same as last time; nothing to do";
return;
}
previous->first = tokens;
previous->second = version;
} else {
previousTokens.insert(doc, qMakePair(tokens, version));
}
for (const ExpandedSemanticToken &t : tokens) for (const ExpandedSemanticToken &t : tokens)
qCDebug(clangdLogHighlight()) << '\t' << t.line << t.column << t.length << t.type qCDebug(clangdLogHighlight()) << '\t' << t.line << t.column << t.length << t.type
<< t.modifiers; << t.modifiers;
@@ -2788,7 +2868,21 @@ void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator,
if (!edit) if (!edit)
return; return;
const QString rawInsertText = edit->newText(); const auto kind = static_cast<CompletionItemKind::Kind>(
item.kind().value_or(CompletionItemKind::Text));
const bool isFunctionLike = kind == CompletionItemKind::Function
|| kind == CompletionItemKind::Method || kind == CompletionItemKind::Constructor;
QString rawInsertText = edit->newText();
// 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 += "( )";
}
const int firstParenOffset = rawInsertText.indexOf('('); const int firstParenOffset = rawInsertText.indexOf('(');
const int lastParenOffset = rawInsertText.lastIndexOf(')'); const int lastParenOffset = rawInsertText.lastIndexOf(')');
const QString detail = item.detail().value_or(QString()); const QString detail = item.detail().value_or(QString());
@@ -2802,12 +2896,6 @@ void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator,
const QTextDocument * const doc = manipulator.textCursorAt(currentPos).document(); const QTextDocument * const doc = manipulator.textCursorAt(currentPos).document();
const Range range = edit->range(); const Range range = edit->range();
const int rangeStart = range.start().toPositionInDocument(doc); const int rangeStart = range.start().toPositionInDocument(doc);
const auto kind = static_cast<CompletionItemKind::Kind>(
item.kind().value_or(CompletionItemKind::Text));
const bool isFunctionLike = kind == CompletionItemKind::Function
|| kind == CompletionItemKind::Method || kind == CompletionItemKind::Constructor
|| (firstParenOffset != -1 && lastParenOffset != -1);
if (isFunctionLike && completionSettings.m_autoInsertBrackets) { if (isFunctionLike && completionSettings.m_autoInsertBrackets) {
// If the user typed the opening parenthesis, they'll likely also type the closing one, // If the user typed the opening parenthesis, they'll likely also type the closing one,
// in which case it would be annoying if we put the cursor after the already automatically // in which case it would be annoying if we put the cursor after the already automatically
@@ -3463,6 +3551,24 @@ 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.
if (editorWidget) {
const auto virtualRanges = q->d->virtualRanges.constFind(editorWidget->textDocument());
if (virtualRanges != q->d->virtualRanges.constEnd()
&& virtualRanges->second == docRevision) {
const auto matcher = [cursorRange = cursorNode->range()](const Range &r) {
return cursorRange.overlaps(r);
};
return Utils::contains(virtualRanges->first, matcher);
}
}
// Otherwise, we have to rely on AST-based heuristics.
return cursorNode->mightBeAmbiguousVirtualCall() || cursorNode->isPureVirtualDeclaration();
}
} // namespace Internal } // namespace Internal
} // namespace ClangCodeModel } // namespace ClangCodeModel

View File

@@ -35,6 +35,7 @@
namespace Core { class SearchResultItem; } namespace Core { class SearchResultItem; }
namespace CppEditor { class CppEditorWidget; } namespace CppEditor { class CppEditorWidget; }
namespace LanguageServerProtocol { class Range; }
namespace ProjectExplorer { class Project; } namespace ProjectExplorer { class Project; }
namespace TextEditor { class BaseTextEditor; } namespace TextEditor { class BaseTextEditor; }
@@ -76,6 +77,9 @@ public:
const LanguageServerProtocol::HoverRequest::Response &hoverResponse, const LanguageServerProtocol::HoverRequest::Response &hoverResponse,
const LanguageServerProtocol::DocumentUri &uri); const LanguageServerProtocol::DocumentUri &uri);
void setVirtualRanges(const Utils::FilePath &filePath,
const QList<LanguageServerProtocol::Range> &ranges, int revision);
void enableTesting(); void enableTesting();
bool testingEnabled() const; bool testingEnabled() const;

View File

@@ -388,6 +388,18 @@ ClangdClient *ClangModelManagerSupport::clientForProject(
&& c->state() != Client::Shutdown; && c->state() != Client::Shutdown;
}); });
QTC_ASSERT(clients.size() <= 1, qDebug() << project << clients.size()); QTC_ASSERT(clients.size() <= 1, qDebug() << project << clients.size());
if (clients.size() > 1) {
Client *activeClient = nullptr;
for (Client * const c : clients) {
if (!activeClient && (c->state() == Client::Initialized
|| c->state() == Client::InitializeRequested)) {
activeClient = c;
} else {
LanguageClientManager::shutdownClient(c);
}
}
return qobject_cast<ClangdClient *>(activeClient);
}
return clients.empty() ? nullptr : qobject_cast<ClangdClient *>(clients.first()); return clients.empty() ? nullptr : qobject_cast<ClangdClient *>(clients.first());
} }
@@ -463,7 +475,7 @@ void ClangModelManagerSupport::watchForExternalChanges()
return; return;
ClangdClient * const client = clientForProject(project); ClangdClient * const client = clientForProject(project);
if (client) { if (client && !m_clientsToRestart.contains(client)) {
m_clientsToRestart.append(client); m_clientsToRestart.append(client);
timer->start(); timer->start();
} }

View File

@@ -674,7 +674,7 @@ void ClangdTestHighlighting::initTestCase()
m_results = results; m_results = results;
loop.quit(); loop.quit();
}; };
connect(client(), &ClangdClient::highlightingResultsReady, handler); connect(client(), &ClangdClient::highlightingResultsReady, &loop, handler);
timer.start(10000); timer.start(10000);
loop.exec(); loop.exec();
QVERIFY(timer.isActive()); QVERIFY(timer.isActive());
@@ -1040,7 +1040,9 @@ void ClangdTestHighlighting::test_data()
<< QList<int>{C_PARAMETER, C_OUTPUT_ARGUMENT} << 0; << QList<int>{C_PARAMETER, C_OUTPUT_ARGUMENT} << 0;
QTest::newRow("typedef as underlying type in enum declaration") << 424 << 21 << 424 << 39 QTest::newRow("typedef as underlying type in enum declaration") << 424 << 21 << 424 << 39
<< QList<int>{C_TYPE} << 0; << QList<int>{C_TYPE} << 0;
QTest::newRow("argument to user-defined subscript operator") << 434 << 12 << 434 << 17 QTest::newRow("argument 1 to user-defined subscript operator") << 434 << 5 << 434 << 11
<< QList<int>{C_PARAMETER} << 0;
QTest::newRow("argument 2 to user-defined subscript operator") << 434 << 12 << 434 << 17
<< QList<int>{C_PARAMETER, C_OUTPUT_ARGUMENT} << 0; << QList<int>{C_PARAMETER, C_OUTPUT_ARGUMENT} << 0;
QTest::newRow("partial class template specialization") << 553 << 25 << 553 << 28 QTest::newRow("partial class template specialization") << 553 << 25 << 553 << 28
<< QList<int>{C_TYPE, C_DECLARATION} << 0; << QList<int>{C_TYPE, C_DECLARATION} << 0;
@@ -1246,6 +1248,7 @@ void ClangdTestHighlighting::test_data()
<< QList<int>{C_LOCAL, C_OUTPUT_ARGUMENT} << 0; << QList<int>{C_LOCAL, C_OUTPUT_ARGUMENT} << 0;
QTest::newRow("const argument to unnamed lambda") << 830 << 16 << 830 << 19 QTest::newRow("const argument to unnamed lambda") << 830 << 16 << 830 << 19
<< QList<int>{C_LOCAL} << 0; << QList<int>{C_LOCAL} << 0;
QTest::newRow("simple assignment") << 835 << 5 << 835 << 6 << QList<int>{C_LOCAL} << 0;
} }
void ClangdTestHighlighting::test() void ClangdTestHighlighting::test()

View File

@@ -829,3 +829,8 @@ void lambdaArgTest()
[](int &) {}(val); [](int &) {}(val);
[](int) {}(val); [](int) {}(val);
} }
void assignmentTest() {
struct S {} s;
s = {};
}

View File

@@ -88,7 +88,6 @@
#include <QMessageBox> #include <QMessageBox>
#include <QMetaObject> #include <QMetaObject>
#include <QMutex> #include <QMutex>
#include <QProcess>
#include <QRegularExpression> #include <QRegularExpression>
#include <QSharedPointer> #include <QSharedPointer>
#include <QTextCodec> #include <QTextCodec>

View File

@@ -483,6 +483,8 @@ void ShortcutSettingsWidget::resetToDefault()
ShortcutItem *scitem = shortcutItem(current); ShortcutItem *scitem = shortcutItem(current);
if (scitem) { if (scitem) {
scitem->m_keys = scitem->m_cmd->defaultKeySequences(); scitem->m_keys = scitem->m_cmd->defaultKeySequences();
current->setText(2, keySequencesToNativeString(scitem->m_keys));
CommandMappings::setModified(current, false);
setupShortcutBox(scitem); setupShortcutBox(scitem);
markAllCollisions(); markAllCollisions();
} }

View File

@@ -2288,7 +2288,6 @@ void EditorManagerPrivate::vcsOpenCurrentEditor()
return; return;
if (!versionControl->vcsOpen(document->filePath())) { if (!versionControl->vcsOpen(document->filePath())) {
// TODO: wrong dialog parent
QMessageBox::warning(ICore::dialogParent(), tr("Cannot Open File"), QMessageBox::warning(ICore::dialogParent(), tr("Cannot Open File"),
tr("Cannot open the file for editing with VCS.")); tr("Cannot open the file for editing with VCS."));
} }

View File

@@ -45,7 +45,6 @@
#include <QJsonObject> #include <QJsonObject>
#include <QMutex> #include <QMutex>
#include <QMutexLocker> #include <QMutexLocker>
#include <QProcess>
#include <QRegularExpression> #include <QRegularExpression>
#include <QWaitCondition> #include <QWaitCondition>

View File

@@ -791,6 +791,7 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
bool containsDriverMode = false; bool containsDriverMode = false;
bool skipNext = false; bool skipNext = false;
bool nextIsTarget = false; bool nextIsTarget = false;
bool nextIsGccToolchain = false;
const QStringList allFlags = m_projectPart.extraCodeModelFlags + m_projectPart.compilerFlags; const QStringList allFlags = m_projectPart.extraCodeModelFlags + m_projectPart.compilerFlags;
for (const QString &option : allFlags) { for (const QString &option : allFlags) {
if (skipNext) { if (skipNext) {
@@ -802,6 +803,11 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
m_explicitTarget = option; m_explicitTarget = option;
continue; continue;
} }
if (nextIsGccToolchain) {
nextIsGccToolchain = false;
m_compilerFlags.flags.append("--gcc-toolchain=" + option);
continue;
}
if (userBlackList.contains(option)) if (userBlackList.contains(option))
continue; continue;
@@ -833,6 +839,11 @@ void CompilerOptionsBuilder::evaluateCompilerFlags()
continue; continue;
} }
if (option == "-gcc-toolchain") {
nextIsGccToolchain = true;
continue;
}
if (option == includeUserPathOption || option == includeSystemPathOption if (option == includeUserPathOption || option == includeSystemPathOption
|| option == includeUserPathOptionWindows) { || option == includeUserPathOptionWindows) {
skipNext = true; skipNext = true;

View File

@@ -34,6 +34,7 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <QSettings> #include <QSettings>
@@ -312,6 +313,11 @@ ClangdSettings &ClangdSettings::instance()
return settings; return settings;
} }
bool ClangdSettings::useClangd() const
{
return m_data.useClangd && clangdVersion(clangdFilePath()) >= QVersionNumber(13);
}
void ClangdSettings::setDefaultClangdPath(const FilePath &filePath) void ClangdSettings::setDefaultClangdPath(const FilePath &filePath)
{ {
g_defaultClangdFilePath = filePath; g_defaultClangdFilePath = filePath;
@@ -333,6 +339,37 @@ void ClangdSettings::setData(const Data &data)
} }
} }
static QVersionNumber getClangdVersion(const FilePath &clangdFilePath)
{
Utils::QtcProcess clangdProc;
clangdProc.setCommand({clangdFilePath, {"--version"}});
clangdProc.start();
if (!clangdProc.waitForStarted() || !clangdProc.waitForFinished())
return{};
const QString output = clangdProc.allOutput();
static const QString versionPrefix = "clangd version ";
const int prefixOffset = output.indexOf(versionPrefix);
if (prefixOffset == -1)
return {};
return QVersionNumber::fromString(output.mid(prefixOffset + versionPrefix.length()));
}
QVersionNumber ClangdSettings::clangdVersion(const FilePath &clangdFilePath)
{
const QDateTime timeStamp = clangdFilePath.lastModified();
const auto it = m_versionCache.find(clangdFilePath);
if (it == m_versionCache.end()) {
const QVersionNumber version = getClangdVersion(clangdFilePath);
m_versionCache.insert(clangdFilePath, qMakePair(timeStamp, version));
return version;
}
if (it->first != timeStamp) {
it->first = timeStamp;
it->second = getClangdVersion(clangdFilePath);
}
return it->second;
}
void ClangdSettings::loadSettings() void ClangdSettings::loadSettings()
{ {
m_data.fromMap(Core::ICore::settings()->value(clangdSettingsKey()).toMap()); m_data.fromMap(Core::ICore::settings()->value(clangdSettingsKey()).toMap());

View File

@@ -29,8 +29,12 @@
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <QDateTime>
#include <QHash>
#include <QObject> #include <QObject>
#include <QPair>
#include <QStringList> #include <QStringList>
#include <QVersionNumber>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QSettings; class QSettings;
@@ -117,7 +121,7 @@ public:
ClangdSettings(const Data &data) : m_data(data) {} ClangdSettings(const Data &data) : m_data(data) {}
static ClangdSettings &instance(); static ClangdSettings &instance();
bool useClangd() const { return m_data.useClangd; } bool useClangd() const;
static void setDefaultClangdPath(const Utils::FilePath &filePath); static void setDefaultClangdPath(const Utils::FilePath &filePath);
Utils::FilePath clangdFilePath() const; Utils::FilePath clangdFilePath() const;
@@ -129,6 +133,8 @@ public:
void setData(const Data &data); void setData(const Data &data);
Data data() const { return m_data; } Data data() const { return m_data; }
static QVersionNumber clangdVersion(const Utils::FilePath &clangdFilePath);
#ifdef WITH_TESTS #ifdef WITH_TESTS
static void setUseClangd(bool use); static void setUseClangd(bool use);
static void setClangdFilePath(const Utils::FilePath &filePath); static void setClangdFilePath(const Utils::FilePath &filePath);
@@ -144,6 +150,7 @@ private:
void saveSettings(); void saveSettings();
Data m_data; Data m_data;
static inline QHash<Utils::FilePath, QPair<QDateTime, QVersionNumber>> m_versionCache;
}; };
inline bool operator==(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2) inline bool operator==(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2)

View File

@@ -35,7 +35,6 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/infolabel.h> #include <utils/infolabel.h>
#include <utils/pathchooser.h> #include <utils/pathchooser.h>
#include <utils/qtcprocess.h>
#include <QFormLayout> #include <QFormLayout>
#include <QSpinBox> #include <QSpinBox>
@@ -285,30 +284,14 @@ ClangdSettingsWidget::ClangdSettingsWidget(const ClangdSettings::Data &settingsD
if (!d->clangdChooser.isValid()) if (!d->clangdChooser.isValid())
return; return;
const Utils::FilePath clangdPath = d->clangdChooser.filePath(); const Utils::FilePath clangdPath = d->clangdChooser.filePath();
Utils::QtcProcess clangdProc; const QVersionNumber clangdVersion = ClangdSettings::clangdVersion(clangdPath);
clangdProc.setCommand({clangdPath, {"--version"}});
clangdProc.start();
if (!clangdProc.waitForStarted() || !clangdProc.waitForFinished()) {
labelSetter.setWarning(tr("Failed to retrieve clangd version: %1")
.arg(clangdProc.exitMessage()));
return;
}
const QString output = clangdProc.allOutput();
static const QString versionPrefix = "clangd version ";
const int prefixOffset = output.indexOf(versionPrefix);
QVersionNumber clangdVersion;
if (prefixOffset != -1) {
clangdVersion = QVersionNumber::fromString(output.mid(prefixOffset
+ versionPrefix.length()));
}
if (clangdVersion.isNull()) { if (clangdVersion.isNull()) {
labelSetter.setWarning(tr("Failed to retrieve clangd version: " labelSetter.setWarning(tr("Failed to retrieve clangd version: "
"Unexpected clangd output.")); "Unexpected clangd output."));
return; return;
} }
if (clangdVersion < QVersionNumber(13)) { if (clangdVersion < QVersionNumber(13)) {
labelSetter.setWarning(tr("The clangd version is %1, but %2 or greater is " labelSetter.setWarning(tr("The clangd version is %1, but %2 or greater is required.")
"recommended for full functionality.")
.arg(clangdVersion.toString()).arg(13)); .arg(clangdVersion.toString()).arg(13));
return; return;
} }

View File

@@ -90,11 +90,16 @@ void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo,
// extra compilers // extra compilers
for (QPointer<ExtraCompiler> compiler : qAsConst(m_extraCompilers)) { for (QPointer<ExtraCompiler> compiler : qAsConst(m_extraCompilers)) {
if (compiler->isDirty()) { if (compiler->isDirty()) {
auto watcher = new QFutureWatcher<void>; QPointer<QFutureWatcher<void>> watcher = new QFutureWatcher<void>;
// queued connection to delay after the extra compiler updated its result contents, // queued connection to delay after the extra compiler updated its result contents,
// which is also done in the main thread when compiler->run() finished // which is also done in the main thread when compiler->run() finished
connect(watcher, &QFutureWatcherBase::finished, connect(watcher, &QFutureWatcherBase::finished,
this, [this, watcher] { this, [this, watcher] {
// In very unlikely case the CppProjectUpdater::cancel() could have been
// invoked after posting the finished() signal and before this handler
// gets called. In this case the watcher is already deleted.
if (!watcher)
return;
m_projectUpdateFutureInterface->setProgressValue( m_projectUpdateFutureInterface->setProgressValue(
m_projectUpdateFutureInterface->progressValue() + 1); m_projectUpdateFutureInterface->progressValue() + 1);
m_extraCompilersFutureWatchers.remove(watcher); m_extraCompilersFutureWatchers.remove(watcher);

View File

@@ -33,7 +33,6 @@
#include <QDateTime> #include <QDateTime>
#include <QHash> #include <QHash>
#include <QProcess>
#include <QSet> #include <QSet>
namespace Core { class IEditor; } namespace Core { class IEditor; }

View File

@@ -41,7 +41,6 @@
#include <utils/winutils.h> #include <utils/winutils.h>
#include <QFileInfo> #include <QFileInfo>
#include <QProcess>
#include <QUuid> #include <QUuid>
#ifdef WITH_TESTS #ifdef WITH_TESTS

View File

@@ -71,14 +71,13 @@
#include <QMenu> #include <QMenu>
#include <QMimeData> #include <QMimeData>
#include <QPainter> #include <QPainter>
#include <QProcess>
#include <QSet> #include <QSet>
#include <QTableWidget>
#include <QTabWidget> #include <QTabWidget>
#include <QTextEdit> #include <QTextEdit>
#include <QTableWidget>
#include <QTimer> #include <QTimer>
#include <QVBoxLayout>
#include <QToolTip> #include <QToolTip>
#include <QVBoxLayout>
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>

View File

@@ -2598,7 +2598,7 @@ bool GitClient::tryLauchingGitK(const Environment &env,
process->start(); process->start();
success = process->waitForStarted(); success = process->waitForStarted();
if (success) if (success)
connect(process, &QtcProcess::finished, process, &QProcess::deleteLater); connect(process, &QtcProcess::finished, process, &QObject::deleteLater);
else else
delete process; delete process;
} else { } else {

View File

@@ -60,10 +60,9 @@
#include <QHash> #include <QHash>
#include <QList> #include <QList>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QProcess>
#include <QSettings> #include <QSettings>
#include <QStringList>
#include <QStandardPaths> #include <QStandardPaths>
#include <QStringList>
#include <QTimer> #include <QTimer>
#include <memory> #include <memory>

View File

@@ -32,7 +32,6 @@
#include <QFileInfo> #include <QFileInfo>
#include <QFileInfoList> #include <QFileInfoList>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QProcess>
static Q_LOGGING_CATEGORY(probeLog, "qtc.ios.probe", QtWarningMsg) static Q_LOGGING_CATEGORY(probeLog, "qtc.ios.probe", QtWarningMsg)

View File

@@ -31,7 +31,6 @@
#include <QMap> #include <QMap>
#include <QString> #include <QString>
#include <QStringList> #include <QStringList>
#include <QProcess>
namespace Ios { namespace Ios {
namespace Internal { namespace Internal {

View File

@@ -42,7 +42,6 @@
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QProcess>
using namespace Utils; using namespace Utils;
using namespace std; using namespace std;

View File

@@ -170,6 +170,9 @@ static ClientCapabilities generateClientCapabilities()
workspaceCapabilities.setDidChangeConfiguration(allowDynamicRegistration); workspaceCapabilities.setDidChangeConfiguration(allowDynamicRegistration);
workspaceCapabilities.setExecuteCommand(allowDynamicRegistration); workspaceCapabilities.setExecuteCommand(allowDynamicRegistration);
workspaceCapabilities.setConfiguration(true); workspaceCapabilities.setConfiguration(true);
SemanticTokensWorkspaceClientCapabilities semanticTokensWorkspaceClientCapabilities;
semanticTokensWorkspaceClientCapabilities.setRefreshSupport(true);
workspaceCapabilities.setSemanticTokens(semanticTokensWorkspaceClientCapabilities);
capabilities.setWorkspace(workspaceCapabilities); capabilities.setWorkspace(workspaceCapabilities);
TextDocumentClientCapabilities documentCapabilities; TextDocumentClientCapabilities documentCapabilities;
@@ -340,6 +343,19 @@ Client::State Client::state() const
return m_state; return m_state;
} }
QString Client::stateString() const
{
switch (m_state){
case Uninitialized: return tr("uninitialized");
case InitializeRequested: return tr("initialize requested");
case Initialized: return tr("initialized");
case ShutdownRequested: return tr("shutdown requested");
case Shutdown: return tr("shutdown");
case Error: return tr("error");
}
return {};
}
ClientCapabilities Client::defaultClientCapabilities() ClientCapabilities Client::defaultClientCapabilities()
{ {
return generateClientCapabilities(); return generateClientCapabilities();
@@ -1350,6 +1366,11 @@ void Client::handleMethod(const QString &method, const MessageId &id, const ICon
dynamic_cast<const WorkDoneProgressCreateRequest *>(content)->id()); dynamic_cast<const WorkDoneProgressCreateRequest *>(content)->id());
response.setResult(nullptr); response.setResult(nullptr);
sendContent(response); sendContent(response);
} else if (method == SemanticTokensRefreshRequest::methodName) {
m_tokenSupport.refresh();
Response<std::nullptr_t, JsonObject> response(id);
response.setResult(nullptr);
sendContent(response);
} else if (method == ProgressNotification::methodName) { } else if (method == ProgressNotification::methodName) {
if (Utils::optional<ProgressParams> params if (Utils::optional<ProgressParams> params
= dynamic_cast<const ProgressNotification *>(content)->params()) { = dynamic_cast<const ProgressNotification *>(content)->params()) {

View File

@@ -58,7 +58,6 @@
#include <QBuffer> #include <QBuffer>
#include <QHash> #include <QHash>
#include <QProcess>
#include <QJsonDocument> #include <QJsonDocument>
#include <QTextCursor> #include <QTextCursor>
@@ -116,6 +115,7 @@ public:
Error Error
}; };
State state() const; State state() const;
QString stateString() const;
bool reachable() const { return m_state == Initialized; } bool reachable() const { return m_state == Initialized; }
// capabilities // capabilities

View File

@@ -71,6 +71,7 @@ LanguageClientManager::LanguageClientManager(QObject *parent)
JsonRpcMessageHandler::registerMessageProvider<UnregisterCapabilityRequest>(); JsonRpcMessageHandler::registerMessageProvider<UnregisterCapabilityRequest>();
JsonRpcMessageHandler::registerMessageProvider<WorkDoneProgressCreateRequest>(); JsonRpcMessageHandler::registerMessageProvider<WorkDoneProgressCreateRequest>();
JsonRpcMessageHandler::registerMessageProvider<ProgressNotification>(); JsonRpcMessageHandler::registerMessageProvider<ProgressNotification>();
JsonRpcMessageHandler::registerMessageProvider<SemanticTokensRefreshRequest>();
connect(EditorManager::instance(), &EditorManager::editorOpened, connect(EditorManager::instance(), &EditorManager::editorOpened,
this, &LanguageClientManager::editorOpened); this, &LanguageClientManager::editorOpened);
connect(EditorManager::instance(), &EditorManager::documentOpened, connect(EditorManager::instance(), &EditorManager::documentOpened,

View File

@@ -183,6 +183,17 @@ SemanticTokenSupport::SemanticTokenSupport(Client *client)
&TextEditorSettings::fontSettingsChanged, &TextEditorSettings::fontSettingsChanged,
client, client,
[this]() { updateFormatHash(); }); [this]() { updateFormatHash(); });
QObject::connect(Core::EditorManager::instance(),
&Core::EditorManager::currentEditorChanged,
this,
&SemanticTokenSupport::onCurrentEditorChanged);
}
void SemanticTokenSupport::refresh()
{
m_tokens.clear();
for (Core::IEditor *editor : Core::EditorManager::visibleEditors())
onCurrentEditorChanged(editor);
} }
void SemanticTokenSupport::reloadSemanticTokens(TextDocument *textDocument) void SemanticTokenSupport::reloadSemanticTokens(TextDocument *textDocument)
@@ -224,8 +235,11 @@ void SemanticTokenSupport::updateSemanticTokens(TextDocument *textDocument)
const SemanticRequestTypes supportedRequests = supportedSemanticRequests(textDocument); const SemanticRequestTypes supportedRequests = supportedSemanticRequests(textDocument);
if (supportedRequests.testFlag(SemanticRequestType::FullDelta)) { if (supportedRequests.testFlag(SemanticRequestType::FullDelta)) {
const Utils::FilePath filePath = textDocument->filePath(); const Utils::FilePath filePath = textDocument->filePath();
const QString &previousResultId = m_tokens.value(filePath).tokens.resultId().value_or(QString()); const VersionedTokens versionedToken = m_tokens.value(filePath);
const QString &previousResultId = versionedToken.tokens.resultId().value_or(QString());
if (!previousResultId.isEmpty()) { if (!previousResultId.isEmpty()) {
if (m_client->documentVersion(filePath) == versionedToken.version)
return;
SemanticTokensDeltaParams params; SemanticTokensDeltaParams params;
params.setTextDocument(TextDocumentIdentifier(DocumentUri::fromFilePath(filePath))); params.setTextDocument(TextDocumentIdentifier(DocumentUri::fromFilePath(filePath)));
params.setPreviousResultId(previousResultId); params.setPreviousResultId(previousResultId);
@@ -325,6 +339,12 @@ void SemanticTokenSupport::updateFormatHash()
rehighlight(); rehighlight();
} }
void SemanticTokenSupport::onCurrentEditorChanged(Core::IEditor *editor)
{
if (auto textEditor = qobject_cast<BaseTextEditor *>(editor))
updateSemanticTokens(textEditor->textDocument());
}
void SemanticTokenSupport::setTokenTypesMap(const QMap<QString, int> &tokenTypesMap) void SemanticTokenSupport::setTokenTypesMap(const QMap<QString, int> &tokenTypesMap)
{ {
m_tokenTypesMap = tokenTypesMap; m_tokenTypesMap = tokenTypesMap;

View File

@@ -36,6 +36,8 @@
#include <functional> #include <functional>
namespace Core { class IEditor; }
namespace LanguageClient { namespace LanguageClient {
class Client; class Client;
@@ -48,6 +50,11 @@ public:
QString type; QString type;
QStringList modifiers; QStringList modifiers;
}; };
inline bool operator==(const ExpandedSemanticToken &t1, const ExpandedSemanticToken &t2)
{
return t1.line == t2.line && t1.column == t2.column && t1.length == t2.length
&& t1.type == t2.type && t1.modifiers == t2.modifiers;
}
using SemanticTokensHandler = std::function<void(TextEditor::TextDocument *, using SemanticTokensHandler = std::function<void(TextEditor::TextDocument *,
const QList<ExpandedSemanticToken> &, int)>; const QList<ExpandedSemanticToken> &, int)>;
@@ -62,11 +69,12 @@ void applyHighlight(TextEditor::TextDocument *doc,
} // namespace SemanticHighligtingSupport } // namespace SemanticHighligtingSupport
class SemanticTokenSupport class SemanticTokenSupport : public QObject
{ {
public: public:
explicit SemanticTokenSupport(Client *client); explicit SemanticTokenSupport(Client *client);
void refresh();
void reloadSemanticTokens(TextEditor::TextDocument *doc); void reloadSemanticTokens(TextEditor::TextDocument *doc);
void updateSemanticTokens(TextEditor::TextDocument *doc); void updateSemanticTokens(TextEditor::TextDocument *doc);
void rehighlight(); void rehighlight();
@@ -94,6 +102,7 @@ private:
void highlight(const Utils::FilePath &filePath); void highlight(const Utils::FilePath &filePath);
void updateFormatHash(); void updateFormatHash();
void currentEditorChanged(); void currentEditorChanged();
void onCurrentEditorChanged(Core::IEditor *editor);
Client *m_client = nullptr; Client *m_client = nullptr;

View File

@@ -381,6 +381,7 @@ static ToolChain *msvcToolChain(Id language)
{ {
ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) { ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) {
const Abi abi = t->targetAbi(); const Abi abi = t->targetAbi();
// TODO: Should Abi::WindowsMsvc2022Flavor be added too?
return (abi.osFlavor() == Abi::WindowsMsvc2017Flavor || abi.osFlavor() == Abi::WindowsMsvc2019Flavor) return (abi.osFlavor() == Abi::WindowsMsvc2017Flavor || abi.osFlavor() == Abi::WindowsMsvc2019Flavor)
&& abi.architecture() == Abi::X86Architecture && abi.architecture() == Abi::X86Architecture
&& abi.wordWidth() == 64 && abi.wordWidth() == 64

View File

@@ -36,7 +36,6 @@
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <QFormLayout> #include <QFormLayout>
#include <QProcess>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;

View File

@@ -34,7 +34,6 @@
#include <QDebug> #include <QDebug>
#include <QFileInfo> #include <QFileInfo>
#include <QProcess>
#include <QSet> #include <QSet>
#include <QTextStream> #include <QTextStream>

View File

@@ -111,6 +111,7 @@ static void setupPreregisteredOsFlavors() {
registerOsFlavor(Abi::WindowsMsvc2015Flavor, "msvc2015", {Abi::OS::WindowsOS}); registerOsFlavor(Abi::WindowsMsvc2015Flavor, "msvc2015", {Abi::OS::WindowsOS});
registerOsFlavor(Abi::WindowsMsvc2017Flavor, "msvc2017", {Abi::OS::WindowsOS}); registerOsFlavor(Abi::WindowsMsvc2017Flavor, "msvc2017", {Abi::OS::WindowsOS});
registerOsFlavor(Abi::WindowsMsvc2019Flavor, "msvc2019", {Abi::OS::WindowsOS}); registerOsFlavor(Abi::WindowsMsvc2019Flavor, "msvc2019", {Abi::OS::WindowsOS});
registerOsFlavor(Abi::WindowsMsvc2022Flavor, "msvc2022", {Abi::OS::WindowsOS});
registerOsFlavor(Abi::WindowsMSysFlavor, "msys", {Abi::OS::WindowsOS}); registerOsFlavor(Abi::WindowsMSysFlavor, "msys", {Abi::OS::WindowsOS});
registerOsFlavor(Abi::WindowsCEFlavor, "ce", {Abi::OS::WindowsOS}); registerOsFlavor(Abi::WindowsCEFlavor, "ce", {Abi::OS::WindowsOS});
registerOsFlavor(Abi::VxWorksFlavor, "vxworks", {Abi::OS::VxWorks}); registerOsFlavor(Abi::VxWorksFlavor, "vxworks", {Abi::OS::VxWorks});
@@ -285,7 +286,9 @@ static Abis parseCoffHeader(const QByteArray &data)
flavor = Abi::WindowsMsvc2013Flavor; flavor = Abi::WindowsMsvc2013Flavor;
break; break;
case 14: case 14:
if (minorLinker >= quint8(20)) if (minorLinker >= quint8(30))
flavor = Abi::WindowsMsvc2022Flavor;
else if (minorLinker >= quint8(20))
flavor = Abi::WindowsMsvc2019Flavor; flavor = Abi::WindowsMsvc2019Flavor;
else if (minorLinker >= quint8(10)) else if (minorLinker >= quint8(10))
flavor = Abi::WindowsMsvc2017Flavor; flavor = Abi::WindowsMsvc2017Flavor;
@@ -295,6 +298,9 @@ static Abis parseCoffHeader(const QByteArray &data)
case 15: case 15:
flavor = Abi::WindowsMsvc2019Flavor; flavor = Abi::WindowsMsvc2019Flavor;
break; break;
case 16:
flavor = Abi::WindowsMsvc2022Flavor;
break;
default: // Keep unknown flavor default: // Keep unknown flavor
if (minorLinker != 0) if (minorLinker != 0)
flavor = Abi::WindowsMSysFlavor; // MSVC seems to avoid using minor numbers flavor = Abi::WindowsMSysFlavor; // MSVC seems to avoid using minor numbers
@@ -692,9 +698,9 @@ bool Abi::operator == (const Abi &other) const
static bool compatibleMSVCFlavors(const Abi::OSFlavor &left, const Abi ::OSFlavor &right) static bool compatibleMSVCFlavors(const Abi::OSFlavor &left, const Abi ::OSFlavor &right)
{ {
// MSVC 2019, 2017 and 2015 are compatible // MSVC 2022, 2019, 2017 and 2015 are compatible
return left >= Abi::WindowsMsvc2015Flavor && left <= Abi::WindowsMsvc2019Flavor return left >= Abi::WindowsMsvc2015Flavor && left <= Abi::WindowsMsvc2022Flavor
&& right >= Abi::WindowsMsvc2015Flavor && right <= Abi::WindowsMsvc2019Flavor; && right >= Abi::WindowsMsvc2015Flavor && right <= Abi::WindowsMsvc2022Flavor;
} }
bool Abi::isCompatibleWith(const Abi &other) const bool Abi::isCompatibleWith(const Abi &other) const
@@ -1091,6 +1097,8 @@ bool Abi::osSupportsFlavor(const Abi::OS &os, const Abi::OSFlavor &flavor)
Abi::OSFlavor Abi::flavorForMsvcVersion(int version) Abi::OSFlavor Abi::flavorForMsvcVersion(int version)
{ {
if (version >= 1930)
return WindowsMsvc2022Flavor;
if (version >= 1920) if (version >= 1920)
return WindowsMsvc2019Flavor; return WindowsMsvc2019Flavor;
if (version >= 1910) if (version >= 1910)

View File

@@ -112,7 +112,8 @@ public:
WindowsMsvc2015Flavor, WindowsMsvc2015Flavor,
WindowsMsvc2017Flavor, WindowsMsvc2017Flavor,
WindowsMsvc2019Flavor, WindowsMsvc2019Flavor,
WindowsLastMsvcFlavor = WindowsMsvc2019Flavor, WindowsMsvc2022Flavor,
WindowsLastMsvcFlavor = WindowsMsvc2022Flavor,
WindowsMSysFlavor, WindowsMSysFlavor,
WindowsCEFlavor, WindowsCEFlavor,

View File

@@ -31,7 +31,6 @@
#include <QTimer> #include <QTimer>
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
#include <QProcess>
#include <QDir> #include <QDir>
#include <signal.h> #include <signal.h>
#include <errno.h> #include <errno.h>

View File

@@ -45,10 +45,9 @@
#include <QDateTime> #include <QDateTime>
#include <QFutureInterface> #include <QFutureInterface>
#include <QFutureWatcher> #include <QFutureWatcher>
#include <QProcess> #include <QTextBlock>
#include <QThreadPool> #include <QThreadPool>
#include <QTimer> #include <QTimer>
#include <QTextBlock>
using namespace Utils; using namespace Utils;

View File

@@ -51,7 +51,6 @@
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
#include <QLoggingCategory> #include <QLoggingCategory>
#include <QProcess>
#include <QRegularExpression> #include <QRegularExpression>
#include <QSettings> #include <QSettings>
#include <QVector> #include <QVector>
@@ -430,7 +429,9 @@ static Abi findAbiOfMsvc(MsvcToolChain::Type type,
else if (version == QLatin1String("v7.0A") || version == QLatin1String("v7.1")) else if (version == QLatin1String("v7.0A") || version == QLatin1String("v7.1"))
msvcVersionString = QLatin1String("10.0"); msvcVersionString = QLatin1String("10.0");
} }
if (msvcVersionString.startsWith(QLatin1String("16."))) if (msvcVersionString.startsWith(QLatin1String("17.")))
flavor = Abi::WindowsMsvc2022Flavor;
else if (msvcVersionString.startsWith(QLatin1String("16.")))
flavor = Abi::WindowsMsvc2019Flavor; flavor = Abi::WindowsMsvc2019Flavor;
else if (msvcVersionString.startsWith(QLatin1String("15."))) else if (msvcVersionString.startsWith(QLatin1String("15.")))
flavor = Abi::WindowsMsvc2017Flavor; flavor = Abi::WindowsMsvc2017Flavor;
@@ -927,6 +928,10 @@ QStringList MsvcToolChain::suggestedMkspecList() const
"winrt-arm-msvc2019", "winrt-arm-msvc2019",
"winrt-x86-msvc2019", "winrt-x86-msvc2019",
"winrt-x64-msvc2019"}; "winrt-x64-msvc2019"};
case Abi::WindowsMsvc2022Flavor:
return {"win32-msvc",
"win32-msvc2022",
"win32-arm64-msvc"};
default: default:
break; break;
} }
@@ -938,6 +943,14 @@ Abis MsvcToolChain::supportedAbis() const
Abi abi = targetAbi(); Abi abi = targetAbi();
Abis abis = {abi}; Abis abis = {abi};
switch (abi.osFlavor()) { switch (abi.osFlavor()) {
case Abi::WindowsMsvc2022Flavor:
abis << Abi(abi.architecture(),
abi.os(),
Abi::WindowsMsvc2019Flavor,
abi.binaryFormat(),
abi.wordWidth(),
abi.param());
Q_FALLTHROUGH();
case Abi::WindowsMsvc2019Flavor: case Abi::WindowsMsvc2019Flavor:
abis << Abi(abi.architecture(), abis << Abi(abi.architecture(),
abi.os(), abi.os(),

View File

@@ -31,7 +31,7 @@
#include <QHash> #include <QHash>
#include <QJsonObject> #include <QJsonObject>
#include <QObject> #include <QObject>
#include <QProcess> #include <QProcessEnvironment>
#include <QString> #include <QString>
#include <QVariant> #include <QVariant>

View File

@@ -36,11 +36,9 @@
#include <qtsupport/qtkitinformation.h> #include <qtsupport/qtkitinformation.h>
#include <designer/designerconstants.h> #include <designer/designerconstants.h>
#include <QProcess>
#include <QDebug> #include <QDebug>
#include <QTcpSocket>
#include <QTcpServer> #include <QTcpServer>
#include <QTcpSocket>
using namespace ProjectExplorer; using namespace ProjectExplorer;
using namespace Utils; using namespace Utils;

View File

@@ -7,7 +7,7 @@ add_qtc_plugin(QmlDesigner
CONDITION TARGET Qt5::QuickWidgets CONDITION TARGET Qt5::QuickWidgets
DEPENDS DEPENDS
QmlJS LanguageUtils QmlEditorWidgets AdvancedDockingSystem QmlJS LanguageUtils QmlEditorWidgets AdvancedDockingSystem
Qt5::QuickWidgets Qt5::CorePrivate Sqlite Qt5::QuickWidgets Qt5::CorePrivate Sqlite Qt5::Xml Qt5::Svg
DEFINES DEFINES
DESIGNER_CORE_LIBRARY DESIGNER_CORE_LIBRARY
IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\" IDE_LIBRARY_BASENAME=\"${IDE_LIBRARY_BASE_PATH}\"
@@ -139,6 +139,7 @@ extend_qtc_plugin(QmlDesigner
theme.cpp theme.h theme.cpp theme.h
zoomaction.cpp zoomaction.h zoomaction.cpp zoomaction.h
hdrimage.cpp hdrimage.h hdrimage.cpp hdrimage.h
svgpasteaction.cpp svgpasteaction.h
) )
extend_qtc_plugin(QmlDesigner extend_qtc_plugin(QmlDesigner

View File

@@ -20,6 +20,7 @@ SOURCES += crumblebar.cpp
SOURCES += qmldesignericonprovider.cpp SOURCES += qmldesignericonprovider.cpp
SOURCES += zoomaction.cpp SOURCES += zoomaction.cpp
SOURCES += hdrimage.cpp SOURCES += hdrimage.cpp
SOURCES += svgpasteaction.cpp
HEADERS += modelnodecontextmenu.h HEADERS += modelnodecontextmenu.h
HEADERS += addimagesdialog.h HEADERS += addimagesdialog.h
@@ -43,6 +44,7 @@ HEADERS += crumblebar.h
HEADERS += qmldesignericonprovider.h HEADERS += qmldesignericonprovider.h
HEADERS += zoomaction.h HEADERS += zoomaction.h
HEADERS += hdrimage.h HEADERS += hdrimage.h
HEADERS += svgpasteaction.h
FORMS += \ FORMS += \
$$PWD/addsignalhandlerdialog.ui $$PWD/addsignalhandlerdialog.ui

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,56 @@
/****************************************************************************
**
** 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
#include <qmlitemnode.h>
#include <QDomDocument>
namespace QmlDesigner {
struct CSSProperty
{
QString directive;
QString value;
};
using CSSRule = std::vector<CSSProperty>;
using CSSRules = QHash<QString, CSSRule>;
using PropertyMap = QHash<QByteArray, QVariant>;
class SVGPasteAction
{
public:
SVGPasteAction();
bool containsSVG(const QString &str);
QmlObjectNode createQmlObjectNode(QmlDesigner::ModelNode &targetNode);
private:
QDomDocument m_domDocument;
};
} // namespace QmlDesigner

View File

@@ -51,9 +51,12 @@
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <timelineactions.h> #include <timelineactions.h>
#include <svgpasteaction.h>
#include <qmljs/qmljsmodelmanagerinterface.h> #include <qmljs/qmljsmodelmanagerinterface.h>
#include <utils/qtcassert.h>
#include <QFileInfo> #include <QFileInfo>
#include <QUrl> #include <QUrl>
#include <QDebug> #include <QDebug>
@@ -62,6 +65,7 @@
#include <QMessageBox> #include <QMessageBox>
#include <QPlainTextEdit> #include <QPlainTextEdit>
#include <QRandomGenerator> #include <QRandomGenerator>
#include <QClipboard>
using namespace ProjectExplorer; using namespace ProjectExplorer;
@@ -166,10 +170,46 @@ Model* DesignDocument::createInFileComponentModel()
{ {
Model *model = Model::create("QtQuick.Item", 1, 0); Model *model = Model::create("QtQuick.Item", 1, 0);
model->setFileUrl(m_documentModel->fileUrl()); model->setFileUrl(m_documentModel->fileUrl());
model->setMetaInfo(m_documentModel->metaInfo());
return model; return model;
} }
bool DesignDocument::pasteSVG()
{
SVGPasteAction svgPasteAction;
if (!svgPasteAction.containsSVG(QApplication::clipboard()->text()))
return false;
rewriterView()->executeInTransaction("DesignDocument::paste1", [&]() {
ModelNode targetNode;
// If nodes are currently selected make the first node in selection the target
if (!view()->selectedModelNodes().isEmpty())
targetNode = view()->firstSelectedModelNode();
// If target is still invalid make the root node the target
if (!targetNode.isValid())
targetNode = view()->rootModelNode();
// Check if document has studio components import, if not create it
QmlDesigner::Import import = QmlDesigner::Import::createLibraryImport("QtQuick.Studio.Components", "1.0");
if (!currentModel()->hasImport(import, true, true)) {
QmlDesigner::Import studioComponentsImport = QmlDesigner::Import::createLibraryImport("QtQuick.Studio.Components", "1.0");
try {
currentModel()->changeImports({studioComponentsImport}, {});
} catch (const QmlDesigner::Exception &) {
QTC_ASSERT(false, return);
}
}
svgPasteAction.createQmlObjectNode(targetNode);
});
return true;
}
QList<DocumentMessage> DesignDocument::qmlParseWarnings() const QList<DocumentMessage> DesignDocument::qmlParseWarnings() const
{ {
return m_rewriterView->warnings(); return m_rewriterView->warnings();
@@ -494,6 +534,9 @@ static void scatterItem(const ModelNode &pastedNode, const ModelNode &targetNode
void DesignDocument::paste() void DesignDocument::paste()
{ {
if (pasteSVG())
return;
if (TimelineActions::clipboardContainsKeyframes()) // pasting keyframes is handled in TimelineView if (TimelineActions::clipboardContainsKeyframes()) // pasting keyframes is handled in TimelineView
return; return;
@@ -517,7 +560,7 @@ void DesignDocument::paste()
ModelNode targetNode; ModelNode targetNode;
if (!view.selectedModelNodes().isEmpty()) if (!view.selectedModelNodes().isEmpty())
targetNode = view.selectedModelNodes().constFirst(); targetNode = view.firstSelectedModelNode();
// in case we copy and paste a selection we paste in the parent item // in case we copy and paste a selection we paste in the parent item
if ((view.selectedModelNodes().count() == selectedNodes.count()) && targetNode.isValid() && targetNode.hasParentProperty()) { if ((view.selectedModelNodes().count() == selectedNodes.count()) && targetNode.isValid() && targetNode.hasParentProperty()) {
@@ -571,7 +614,7 @@ void DesignDocument::paste()
ModelNode targetNode; ModelNode targetNode;
if (!view.selectedModelNodes().isEmpty()) { if (!view.selectedModelNodes().isEmpty()) {
targetNode = view.selectedModelNodes().constFirst(); targetNode = view.firstSelectedModelNode();
} else { } else {
// if selection is empty and this is a 3D Node, paste it under the active scene // if selection is empty and this is a 3D Node, paste it under the active scene
if (pastedNode.isSubclassOf("QtQuick3D.Node")) { if (pastedNode.isSubclassOf("QtQuick3D.Node")) {

View File

@@ -145,6 +145,8 @@ private: // functions
Model *createInFileComponentModel(); Model *createInFileComponentModel();
bool pasteSVG();
private: // variables private: // variables
QScopedPointer<Model> m_documentModel; QScopedPointer<Model> m_documentModel;
QScopedPointer<Model> m_inFileComponentModel; QScopedPointer<Model> m_inFileComponentModel;

View File

@@ -66,7 +66,6 @@ public:
static const QStringList &supportedAudioSuffixes(); static const QStringList &supportedAudioSuffixes();
static const QStringList &supportedTexture3DSuffixes(); static const QStringList &supportedTexture3DSuffixes();
const QSet<QString> &supportedSuffixes() const;
const QSet<QString> &previewableSuffixes() const; const QSet<QString> &previewableSuffixes() const;
static void saveExpandedState(bool expanded, const QString &assetPath); static void saveExpandedState(bool expanded, const QString &assetPath);
@@ -84,6 +83,8 @@ public:
Q_INVOKABLE void removeFile(const QString &filePath); Q_INVOKABLE void removeFile(const QString &filePath);
private: private:
const QSet<QString> &supportedSuffixes() const;
SynchronousImageCache &m_fontImageCache; SynchronousImageCache &m_fontImageCache;
QHash<QString, QPair<QDateTime, QIcon>> m_iconCache; QHash<QString, QPair<QDateTime, QIcon>> m_iconCache;

View File

@@ -372,6 +372,18 @@ void ItemLibraryWidget::handleFilesDrop(const QStringList &filesPaths)
addResources(filesPaths); addResources(filesPaths);
} }
QSet<QString> ItemLibraryWidget::supportedDropSuffixes()
{
const QList<AddResourceHandler> handlers = QmlDesignerPlugin::instance()->viewManager()
.designerActionManager().addResourceHandler();
QSet<QString> suffixes;
for (const AddResourceHandler &handler : handlers)
suffixes.insert(handler.filter);
return suffixes;
}
void ItemLibraryWidget::delayedUpdateModel() void ItemLibraryWidget::delayedUpdateModel()
{ {
static bool disableTimer = DesignerSettings::getValue(DesignerSettingsKey::DISABLE_ITEM_LIBRARY_UPDATE_TIMER).toBool(); static bool disableTimer = DesignerSettings::getValue(DesignerSettingsKey::DISABLE_ITEM_LIBRARY_UPDATE_TIMER).toBool();

View File

@@ -105,7 +105,7 @@ public:
Q_INVOKABLE void handleAddImport(int index); Q_INVOKABLE void handleAddImport(int index);
Q_INVOKABLE bool isSearchActive() const; Q_INVOKABLE bool isSearchActive() const;
Q_INVOKABLE void handleFilesDrop(const QStringList &filesPaths); Q_INVOKABLE void handleFilesDrop(const QStringList &filesPaths);
Q_INVOKABLE QSet<QString> supportedSuffixes() const { return m_assetsModel->supportedSuffixes(); }; Q_INVOKABLE QSet<QString> supportedDropSuffixes();
signals: signals:
void itemActivated(const QString& itemName); void itemActivated(const QString& itemName);

View File

@@ -88,6 +88,7 @@ public:
MetaInfo metaInfo(); MetaInfo metaInfo();
NodeMetaInfo metaInfo(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1); NodeMetaInfo metaInfo(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1);
bool hasNodeMetaInfo(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1); bool hasNodeMetaInfo(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1);
void setMetaInfo(const MetaInfo &metaInfo);
void attachView(AbstractView *view); void attachView(AbstractView *view);
void detachView(AbstractView *view, ViewNotification emitDetachNotify = NotifyView); void detachView(AbstractView *view, ViewNotification emitDetachNotify = NotifyView);

View File

@@ -179,6 +179,8 @@ public:
void sanitizeModel(); void sanitizeModel();
void setAllowComponentRoot(bool allow);
bool allowComponentRoot() const;
signals: signals:
void modelInterfaceProjectUpdated(); void modelInterfaceProjectUpdated();
@@ -221,6 +223,7 @@ private: //variables
bool m_hasIncompleteTypeInformation = false; bool m_hasIncompleteTypeInformation = false;
bool m_restoringAuxData = false; bool m_restoringAuxData = false;
bool m_modelAttachPending = false; bool m_modelAttachPending = false;
bool m_allowComponentRoot = false;
mutable QHash<int, ModelNode> m_canonicalIntModelNode; mutable QHash<int, ModelNode> m_canonicalIntModelNode;
mutable QHash<ModelNode, int> m_canonicalModelNodeInt; mutable QHash<ModelNode, int> m_canonicalModelNodeInt;

View File

@@ -27,8 +27,6 @@
#include "connectionmanagerinterface.h" #include "connectionmanagerinterface.h"
#include <QProcess>
#include <mutex> #include <mutex>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE

View File

@@ -26,7 +26,6 @@
#include "connectionmanagerinterface.h" #include "connectionmanagerinterface.h"
#include <QLocalSocket> #include <QLocalSocket>
#include <QProcess>
#include <QTimer> #include <QTimer>
namespace QmlDesigner { namespace QmlDesigner {

Some files were not shown because too many files have changed in this diff Show More