Merge remote-tracking branch 'origin/6.0'
Change-Id: I560583b200db8f180574256d6d851a867be11c37
22
README.md
@@ -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
@@ -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
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 18 KiB |
BIN
doc/qtcreator/images/qtcreator-android-avd-arguments.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 14 KiB |
BIN
doc/qtcreator/images/qtcreator-android-build-apk-step.png
Normal file
After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 7.8 KiB |
Before Width: | Height: | Size: 15 KiB |
BIN
doc/qtcreator/images/qtcreator-android-deployment-settings.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
BIN
doc/qtcreator/images/qtcreator-import-color-scheme.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 24 KiB |
@@ -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
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
@@ -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 >
|
||||||
|
@@ -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.
|
||||||
|
|
||||||
|
@@ -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}
|
||||||
|
@@ -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"
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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 {}
|
||||||
|
}
|
@@ -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 {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -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 {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -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 {}
|
||||||
|
}
|
@@ -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 {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -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 {}
|
||||||
|
}
|
@@ -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()
|
||||||
|
@@ -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
|
||||||
|
@@ -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";
|
||||||
|
@@ -156,4 +156,8 @@ SemanticTokensDeltaResult::SemanticTokensDeltaResult(const QJsonValue &value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SemanticTokensRefreshRequest::SemanticTokensRefreshRequest()
|
||||||
|
: Request(methodName, nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
} // namespace LanguageServerProtocol
|
} // namespace LanguageServerProtocol
|
||||||
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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;
|
||||||
|
@@ -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
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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;
|
||||||
|
@@ -41,7 +41,6 @@
|
|||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QProcess>
|
|
||||||
#include <QSortFilterProxyModel>
|
#include <QSortFilterProxyModel>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@@ -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>
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
@@ -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()
|
||||||
|
@@ -829,3 +829,8 @@ void lambdaArgTest()
|
|||||||
[](int &) {}(val);
|
[](int &) {}(val);
|
||||||
[](int) {}(val);
|
[](int) {}(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void assignmentTest() {
|
||||||
|
struct S {} s;
|
||||||
|
s = {};
|
||||||
|
}
|
||||||
|
@@ -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>
|
||||||
|
@@ -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();
|
||||||
}
|
}
|
||||||
|
@@ -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."));
|
||||||
}
|
}
|
||||||
|
@@ -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>
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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());
|
||||||
|
@@ -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)
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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);
|
||||||
|
@@ -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; }
|
||||||
|
@@ -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
|
||||||
|
@@ -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>
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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>
|
||||||
|
@@ -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)
|
||||||
|
|
||||||
|
@@ -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 {
|
||||||
|
@@ -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;
|
||||||
|
@@ -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()) {
|
||||||
|
@@ -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
|
||||||
|
@@ -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,
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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;
|
||||||
|
@@ -34,7 +34,6 @@
|
|||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QProcess>
|
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
|
|
||||||
|
@@ -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)
|
||||||
|
@@ -112,7 +112,8 @@ public:
|
|||||||
WindowsMsvc2015Flavor,
|
WindowsMsvc2015Flavor,
|
||||||
WindowsMsvc2017Flavor,
|
WindowsMsvc2017Flavor,
|
||||||
WindowsMsvc2019Flavor,
|
WindowsMsvc2019Flavor,
|
||||||
WindowsLastMsvcFlavor = WindowsMsvc2019Flavor,
|
WindowsMsvc2022Flavor,
|
||||||
|
WindowsLastMsvcFlavor = WindowsMsvc2022Flavor,
|
||||||
WindowsMSysFlavor,
|
WindowsMSysFlavor,
|
||||||
WindowsCEFlavor,
|
WindowsCEFlavor,
|
||||||
|
|
||||||
|
@@ -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>
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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(),
|
||||||
|
@@ -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>
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
1235
src/plugins/qmldesigner/components/componentcore/svgpasteaction.cpp
Normal 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
|
@@ -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")) {
|
||||||
|
@@ -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;
|
||||||
|
@@ -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;
|
||||||
|
|
||||||
|
@@ -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();
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
@@ -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;
|
||||||
|
@@ -27,8 +27,6 @@
|
|||||||
|
|
||||||
#include "connectionmanagerinterface.h"
|
#include "connectionmanagerinterface.h"
|
||||||
|
|
||||||
#include <QProcess>
|
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
@@ -26,7 +26,6 @@
|
|||||||
#include "connectionmanagerinterface.h"
|
#include "connectionmanagerinterface.h"
|
||||||
|
|
||||||
#include <QLocalSocket>
|
#include <QLocalSocket>
|
||||||
#include <QProcess>
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|