Merge remote-tracking branch 'origin/15.0'
Conflicts: src/plugins/android/androiddeployqtstep.cpp src/plugins/debugger/debuggerdialogs.cpp src/plugins/projectexplorer/kitaspect.cpp Change-Id: Iebc1d7a38db4c228282c04c63d7f11ee76072a06
@@ -2,27 +2,45 @@ type: Group
|
|||||||
instructions:
|
instructions:
|
||||||
- type: Group
|
- type: Group
|
||||||
instructions:
|
instructions:
|
||||||
|
# Currently used Qt version for packaging ...
|
||||||
- type: Group
|
- type: Group
|
||||||
instructions:
|
instructions:
|
||||||
- type: SetBuildDirectory
|
- type: EnvironmentVariable
|
||||||
directory: "{{.AgentWorkingDir}}/build"
|
variableName: QTC_QT_BASE_URL
|
||||||
- type: MakeDirectory
|
variableValue: "https://ci-files02-hki.ci.qt.io/packages/jenkins/qt/6.8.0/release_content/"
|
||||||
directory: "{{.BuildDir}}"
|
- type: EnvironmentVariable
|
||||||
|
variableName: MACOSX_DEPLOYMENT_TARGET
|
||||||
|
variableValue: 12.0
|
||||||
|
enable_if:
|
||||||
|
condition: property
|
||||||
|
property: features
|
||||||
|
not_contains_value: "OldestQt"
|
||||||
|
# ... or oldest supported Qt version
|
||||||
|
- type: Group
|
||||||
|
instructions:
|
||||||
|
- type: EnvironmentVariable
|
||||||
|
variableName: QTC_QT_BASE_URL
|
||||||
|
variableValue: "https://ci-files02-hki.ci.qt.io/packages/jenkins/qt/6.4.3/release_content/"
|
||||||
|
- type: EnvironmentVariable
|
||||||
|
variableName: MACOSX_DEPLOYMENT_TARGET
|
||||||
|
variableValue: 11.0
|
||||||
|
enable_if:
|
||||||
|
condition: property
|
||||||
|
property: features
|
||||||
|
contains_value: "OldestQt"
|
||||||
|
- type: SetBuildDirectory
|
||||||
|
directory: "{{.AgentWorkingDir}}/build"
|
||||||
|
- type: MakeDirectory
|
||||||
|
directory: "{{.BuildDir}}"
|
||||||
- type: EnvironmentVariable
|
- type: EnvironmentVariable
|
||||||
variableName: QTC_BUILD_TYPE
|
variableName: QTC_BUILD_TYPE
|
||||||
variableValue: "RelWithDebInfo"
|
variableValue: "RelWithDebInfo"
|
||||||
- type: EnvironmentVariable
|
- type: EnvironmentVariable
|
||||||
variableName: LLVM_BASE_URL
|
variableName: LLVM_BASE_URL
|
||||||
variableValue: https://ci-files02-hki.ci.qt.io/packages/jenkins/qtcreator_libclang/libclang-release_19.1.0-based
|
variableValue: https://ci-files02-hki.ci.qt.io/packages/jenkins/qtcreator_libclang/libclang-release_19.1.0-based
|
||||||
- type: EnvironmentVariable
|
|
||||||
variableName: QTC_QT_BASE_URL
|
|
||||||
variableValue: "https://ci-files02-hki.ci.qt.io/packages/jenkins/qt/6.8.0/release_content/"
|
|
||||||
- type: EnvironmentVariable
|
- type: EnvironmentVariable
|
||||||
variableName: QTC_QT_MODULES
|
variableName: QTC_QT_MODULES
|
||||||
variableValue: "qt5compat qtbase qtdeclarative qtimageformats qtquick3d qtquicktimeline qtserialport qtshadertools qtsvg qttools qttranslations qtwebengine"
|
variableValue: "qt5compat qtbase qtdeclarative qtimageformats qtquick3d qtquicktimeline qtserialport qtshadertools qtsvg qttools qttranslations qtwebengine"
|
||||||
- type: EnvironmentVariable
|
|
||||||
variableName: MACOSX_DEPLOYMENT_TARGET
|
|
||||||
variableValue: 11.0
|
|
||||||
- type: EnvironmentVariable
|
- type: EnvironmentVariable
|
||||||
variableName: SDKTOOL_MACOSX_DEPLOYMENT_TARGET
|
variableName: SDKTOOL_MACOSX_DEPLOYMENT_TARGET
|
||||||
variableValue: 11.0
|
variableValue: 11.0
|
||||||
@@ -37,6 +55,17 @@ instructions:
|
|||||||
- type: EnvironmentVariable
|
- type: EnvironmentVariable
|
||||||
variableName: QTC_QT_POSTFIX
|
variableName: QTC_QT_POSTFIX
|
||||||
variableValue: "-Windows-Windows_11_23H2-MSVC2022-Windows-Windows_11_23H2-X86_64.7z"
|
variableValue: "-Windows-Windows_11_23H2-MSVC2022-Windows-Windows_11_23H2-X86_64.7z"
|
||||||
|
enable_if:
|
||||||
|
condition: property
|
||||||
|
property: features
|
||||||
|
not_contains_value: "OldestQt"
|
||||||
|
- type: EnvironmentVariable
|
||||||
|
variableName: QTC_QT_POSTFIX
|
||||||
|
variableValue: "-Windows-Windows_11_22H2-MSVC2019-Windows-Windows_11_22H2-X86_64.7z"
|
||||||
|
enable_if:
|
||||||
|
condition: property
|
||||||
|
property: features
|
||||||
|
contains_value: "OldestQt"
|
||||||
- type: EnvironmentVariable
|
- type: EnvironmentVariable
|
||||||
variableName: QTC_SDKTOOL_QT_EXT
|
variableName: QTC_SDKTOOL_QT_EXT
|
||||||
variableValue: ".zip"
|
variableValue: ".zip"
|
||||||
@@ -55,9 +84,30 @@ instructions:
|
|||||||
equals_value: Windows
|
equals_value: Windows
|
||||||
- type: Group
|
- type: Group
|
||||||
instructions:
|
instructions:
|
||||||
- type: EnvironmentVariable
|
- type: Group
|
||||||
variableName: QTC_QT_POSTFIX
|
instructions:
|
||||||
variableValue: "-Linux-RHEL_8_8-GCC-Linux-RHEL_8_8-X86_64.7z"
|
- type: EnvironmentVariable
|
||||||
|
variableName: QTC_QT_POSTFIX
|
||||||
|
variableValue: "-Linux-RHEL_8_8-GCC-Linux-RHEL_8_8-X86_64.7z"
|
||||||
|
- type: EnvironmentVariable
|
||||||
|
variableName: QTC_ICU_URL
|
||||||
|
variableValue: "https://ci-files02-hki.ci.qt.io/packages/jenkins/development_releases/prebuilt/icu/prebuilt/73.2/icu-linux-g++-Rhel8.6-x64.7z"
|
||||||
|
enable_if:
|
||||||
|
condition: property
|
||||||
|
property: features
|
||||||
|
not_contains_value: "OldestQt"
|
||||||
|
- type: Group
|
||||||
|
instructions:
|
||||||
|
- type: EnvironmentVariable
|
||||||
|
variableName: QTC_QT_POSTFIX
|
||||||
|
variableValue: "-Linux-RHEL_8_4-GCC-Linux-RHEL_8_4-X86_64.7z"
|
||||||
|
- type: EnvironmentVariable
|
||||||
|
variableName: QTC_ICU_URL
|
||||||
|
variableValue: "https://ci-files02-hki.ci.qt.io/packages/jenkins/development_releases/prebuilt/icu/prebuilt/56.1/icu-linux-g++-Rhel7.2-x64.7z"
|
||||||
|
enable_if:
|
||||||
|
condition: property
|
||||||
|
property: features
|
||||||
|
contains_value: "OldestQt"
|
||||||
- type: EnvironmentVariable
|
- type: EnvironmentVariable
|
||||||
variableName: QTC_SDKTOOL_QT_EXT
|
variableName: QTC_SDKTOOL_QT_EXT
|
||||||
variableValue: ".tar.xz"
|
variableValue: ".tar.xz"
|
||||||
@@ -67,9 +117,6 @@ instructions:
|
|||||||
- type: EnvironmentVariable
|
- type: EnvironmentVariable
|
||||||
variableName: QTC_LLVM_POSTFIX
|
variableName: QTC_LLVM_POSTFIX
|
||||||
variableValue: "-linux-Rhel8.8-gcc10.3-x86_64.7z"
|
variableValue: "-linux-Rhel8.8-gcc10.3-x86_64.7z"
|
||||||
- type: EnvironmentVariable
|
|
||||||
variableName: QTC_ICU_URL
|
|
||||||
variableValue: "https://ci-files02-hki.ci.qt.io/packages/jenkins/development_releases/prebuilt/icu/prebuilt/56.1/icu-linux-g++-Rhel7.2-x64.7z"
|
|
||||||
- type: EnvironmentVariable
|
- type: EnvironmentVariable
|
||||||
variableName: PYTHON_EXECUTABLE
|
variableName: PYTHON_EXECUTABLE
|
||||||
variableValue: "python3"
|
variableValue: "python3"
|
||||||
@@ -124,6 +171,17 @@ instructions:
|
|||||||
- type: EnvironmentVariable
|
- type: EnvironmentVariable
|
||||||
variableName: QTC_QT_POSTFIX
|
variableName: QTC_QT_POSTFIX
|
||||||
variableValue: "-MacOS-MacOS_14-Clang-MacOS-MacOS_14-X86_64-ARM64.7z"
|
variableValue: "-MacOS-MacOS_14-Clang-MacOS-MacOS_14-X86_64-ARM64.7z"
|
||||||
|
enable_if:
|
||||||
|
condition: property
|
||||||
|
property: features
|
||||||
|
not_contains_value: "OldestQt"
|
||||||
|
- type: EnvironmentVariable
|
||||||
|
variableName: QTC_QT_POSTFIX
|
||||||
|
variableValue: "-MacOS-MacOS_12-Clang-MacOS-MacOS_12-X86_64-ARM64.7z"
|
||||||
|
enable_if:
|
||||||
|
condition: property
|
||||||
|
property: features
|
||||||
|
contains_value: "OldestQt"
|
||||||
- type: EnvironmentVariable
|
- type: EnvironmentVariable
|
||||||
variableName: QTC_SDKTOOL_QT_EXT
|
variableName: QTC_SDKTOOL_QT_EXT
|
||||||
variableValue: ".tar.xz"
|
variableValue: ".tar.xz"
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
../../qt/qt5.git:
|
../../qt/qt5.git:
|
||||||
ref: "6.8"
|
ref: "6.8"
|
||||||
|
|
||||||
|
18
dist/changelog/changes-15.0.0.md
vendored
@@ -47,6 +47,8 @@ Editing
|
|||||||
* Added `Fold Recursively` and `Unfold Recursively`
|
* Added `Fold Recursively` and `Unfold Recursively`
|
||||||
* Fixed the display of multi-line annotations
|
* Fixed the display of multi-line annotations
|
||||||
([QTCREATORBUG-29951](https://bugreports.qt.io/browse/QTCREATORBUG-29951))
|
([QTCREATORBUG-29951](https://bugreports.qt.io/browse/QTCREATORBUG-29951))
|
||||||
|
* Fixed the tab order in `Advanced Search`
|
||||||
|
([QTCREATORBUG-31771](https://bugreports.qt.io/browse/QTCREATORBUG-31771))
|
||||||
|
|
||||||
### C++
|
### C++
|
||||||
|
|
||||||
@@ -67,6 +69,8 @@ Editing
|
|||||||
([QTCREATORBUG-31256](https://bugreports.qt.io/browse/QTCREATORBUG-31256))
|
([QTCREATORBUG-31256](https://bugreports.qt.io/browse/QTCREATORBUG-31256))
|
||||||
* Fixed the display of annotations with array operators
|
* Fixed the display of annotations with array operators
|
||||||
([QTCREATORBUG-31670](https://bugreports.qt.io/browse/QTCREATORBUG-31670))
|
([QTCREATORBUG-31670](https://bugreports.qt.io/browse/QTCREATORBUG-31670))
|
||||||
|
* Fixed code formatting after `Apply Changes to Declaration / Definition`
|
||||||
|
([QTCREATORBUG-31293](https://bugreports.qt.io/browse/QTCREATORBUG-31293))
|
||||||
* ClangFormat
|
* ClangFormat
|
||||||
* Implemented `Export` and `Import` for the settings
|
* Implemented `Export` and `Import` for the settings
|
||||||
|
|
||||||
@@ -182,6 +186,8 @@ Projects
|
|||||||
* Fixed the option `Build Only the Application to Be Run` for the
|
* Fixed the option `Build Only the Application to Be Run` for the
|
||||||
`Build before deploying` preferences
|
`Build before deploying` preferences
|
||||||
([QTCREATORBUG-31416](https://bugreports.qt.io/browse/QTCREATORBUG-31416))
|
([QTCREATORBUG-31416](https://bugreports.qt.io/browse/QTCREATORBUG-31416))
|
||||||
|
* Fixed the `vcpkg` support for Android
|
||||||
|
([QTCREATORBUG-31883](https://bugreports.qt.io/browse/QTCREATORBUG-31883))
|
||||||
|
|
||||||
### Workspace
|
### Workspace
|
||||||
|
|
||||||
@@ -274,6 +280,11 @@ Extension Manager
|
|||||||
Platforms
|
Platforms
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
* Fixed that it wasn't possible to select a remote `qmake` executable
|
||||||
|
([QTCREATORBUG-31939](https://bugreports.qt.io/browse/QTCREATORBUG-31939))
|
||||||
|
|
||||||
### macOS
|
### macOS
|
||||||
|
|
||||||
* Added support for back and forward gestures
|
* Added support for back and forward gestures
|
||||||
@@ -284,6 +295,8 @@ Platforms
|
|||||||
* Improved the responsiveness of Qt Creator during Android related operations
|
* Improved the responsiveness of Qt Creator during Android related operations
|
||||||
* Fixed that the setup wizard could use the wrong NDK and build tools version
|
* Fixed that the setup wizard could use the wrong NDK and build tools version
|
||||||
([QTCREATORBUG-31311](https://bugreports.qt.io/browse/QTCREATORBUG-31311))
|
([QTCREATORBUG-31311](https://bugreports.qt.io/browse/QTCREATORBUG-31311))
|
||||||
|
* Fixed a freeze in the preferences while an emulator is running
|
||||||
|
([QTCREATORBUG-31912](https://bugreports.qt.io/browse/QTCREATORBUG-31912))
|
||||||
|
|
||||||
### iOS
|
### iOS
|
||||||
|
|
||||||
@@ -314,11 +327,13 @@ Alexandru Croitor
|
|||||||
Ali Kianian
|
Ali Kianian
|
||||||
Andre Hartmann
|
Andre Hartmann
|
||||||
André Pönitz
|
André Pönitz
|
||||||
|
Andrii Batyiev
|
||||||
Andrii Semkiv
|
Andrii Semkiv
|
||||||
Artem Sokolovskii
|
Artem Sokolovskii
|
||||||
Artur Twardy
|
Artur Twardy
|
||||||
Assam Boudjelthia
|
Assam Boudjelthia
|
||||||
Audun Sutterud
|
Audun Sutterud
|
||||||
|
BogDan Vatra
|
||||||
Burak Hancerli
|
Burak Hancerli
|
||||||
Christian Kandeler
|
Christian Kandeler
|
||||||
Christian Stenger
|
Christian Stenger
|
||||||
@@ -332,6 +347,7 @@ Henning Gruendl
|
|||||||
Jaroslaw Kobus
|
Jaroslaw Kobus
|
||||||
Jussi Witick
|
Jussi Witick
|
||||||
Justyna Hudziak
|
Justyna Hudziak
|
||||||
|
Kai Köhne
|
||||||
Karim Pinter
|
Karim Pinter
|
||||||
Knud Dollereder
|
Knud Dollereder
|
||||||
Kwangsub Kim
|
Kwangsub Kim
|
||||||
@@ -346,6 +362,7 @@ Mariusz Szczepanik
|
|||||||
Mathias Hasselmann
|
Mathias Hasselmann
|
||||||
Mats Honkamaa
|
Mats Honkamaa
|
||||||
Mehdi Salem
|
Mehdi Salem
|
||||||
|
Michael Weghorn
|
||||||
Miikka Heikkinen
|
Miikka Heikkinen
|
||||||
Orgad Shaneh
|
Orgad Shaneh
|
||||||
Pino Toscano
|
Pino Toscano
|
||||||
@@ -366,5 +383,6 @@ Tim Jenßen
|
|||||||
Toni Saario
|
Toni Saario
|
||||||
Ulf Hermann
|
Ulf Hermann
|
||||||
Vikas Pachdha
|
Vikas Pachdha
|
||||||
|
Ville Lavonius
|
||||||
Xavier Besson
|
Xavier Besson
|
||||||
Zoltan Gera
|
Zoltan Gera
|
||||||
|
Before Width: | Height: | Size: 21 KiB |
BIN
doc/qtcreator/images/qtcreator-preferences-debugger-general.webp
Normal file
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 16 KiB |
@@ -15,7 +15,7 @@
|
|||||||
\uicontrol Debugger. In the \uicontrol General tab, you can specify settings
|
\uicontrol Debugger. In the \uicontrol General tab, you can specify settings
|
||||||
that are common to all debuggers.
|
that are common to all debuggers.
|
||||||
|
|
||||||
\image qtcreator-debugger-general-options.png "Debugger General preferences"
|
\image qtcreator-preferences-debugger-general.webp {Debugger General preferences}
|
||||||
|
|
||||||
You can customize the appearance and behavior of the debug views and
|
You can customize the appearance and behavior of the debug views and
|
||||||
setting breakpoints, as well as map source paths to target paths.
|
setting breakpoints, as well as map source paths to target paths.
|
||||||
|
@@ -838,7 +838,7 @@
|
|||||||
To change the appearance and behavior of the debug views, set preferences
|
To change the appearance and behavior of the debug views, set preferences
|
||||||
in \preferences > \uicontrol Debugger > \uicontrol General.
|
in \preferences > \uicontrol Debugger > \uicontrol General.
|
||||||
|
|
||||||
\image qtcreator-debugger-general-options.png {General tab in Debugger preferences}
|
\image qtcreator-preferences-debugger-general.webp {General tab in Debugger preferences}
|
||||||
|
|
||||||
For example, you can:
|
For example, you can:
|
||||||
|
|
||||||
@@ -1270,7 +1270,7 @@
|
|||||||
at which the libraries were built, you can map source paths to target
|
at which the libraries were built, you can map source paths to target
|
||||||
paths in \preferences > \uicontrol Debugger > \uicontrol General.
|
paths in \preferences > \uicontrol Debugger > \uicontrol General.
|
||||||
|
|
||||||
\image qtcreator-debugger-general-options.png {General tab in Debugger preferences}
|
\image qtcreator-preferences-debugger-general.webp {General tab in Debugger preferences}
|
||||||
|
|
||||||
For more information, see \l{Source Paths Mapping}.
|
For more information, see \l{Source Paths Mapping}.
|
||||||
|
|
||||||
|
@@ -74,8 +74,8 @@
|
|||||||
To use a context-specific margin when available, select the
|
To use a context-specific margin when available, select the
|
||||||
\uicontrol {Use context-specific margin} check box.
|
\uicontrol {Use context-specific margin} check box.
|
||||||
\if defined(qtcreator)
|
\if defined(qtcreator)
|
||||||
Then, use the ClangFormat \c ColumnLimit option to set the margin, for
|
Then, use the \l{ClangFormat Style Options}{ClangFormat} \c ColumnLimit
|
||||||
example.
|
option to set the margin, for example.
|
||||||
|
|
||||||
\sa {C++ Code Style}
|
\sa {C++ Code Style}
|
||||||
\endif
|
\endif
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
\li \l{http://astyle.sourceforge.net}{Artistic Style}
|
\li \l{http://astyle.sourceforge.net}{Artistic Style}
|
||||||
|
|
||||||
\li \l{http://clang.llvm.org/docs/ClangFormat.html}{ClangFormat}
|
\li \l{ClangFormat: Documentation}{ClangFormat}
|
||||||
|
|
||||||
\li \l{http://uncrustify.sourceforge.net}{Uncrustify}
|
\li \l{http://uncrustify.sourceforge.net}{Uncrustify}
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
\list
|
\list
|
||||||
\li \l{http://sourceforge.net/projects/astyle/files/astyle}
|
\li \l{http://sourceforge.net/projects/astyle/files/astyle}
|
||||||
{Artistic Style}
|
{Artistic Style}
|
||||||
\li \l{http://llvm.org/releases/download.html}{ClangFormat}
|
\li \l{ClangFormat: Download}{ClangFormat}
|
||||||
\li \l{http://sourceforge.net/projects/uncrustify/files/uncrustify}
|
\li \l{http://sourceforge.net/projects/uncrustify/files/uncrustify}
|
||||||
{Uncrustify}
|
{Uncrustify}
|
||||||
\endlist
|
\endlist
|
||||||
|
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
\brief Set global code style for C++ files.
|
\brief Set global code style for C++ files.
|
||||||
|
|
||||||
\QC uses the Clang \l{https://clang.llvm.org/docs/LibFormat.html}{LibFormat}
|
\QC uses the Clang \l{LibFormat: Documentation}{LibFormat}
|
||||||
library to automatically format and indent C++ code. It enforces a coding
|
library to automatically format and indent C++ code. It enforces a coding
|
||||||
style for a project or the whole organization.
|
style for a project or the whole organization.
|
||||||
|
|
||||||
@@ -25,7 +25,8 @@
|
|||||||
\li \uicontrol {Indenting Only} to only indent code.
|
\li \uicontrol {Indenting Only} to only indent code.
|
||||||
\li \uicontrol {Full Formatting} to use the \key {Ctrl+I}
|
\li \uicontrol {Full Formatting} to use the \key {Ctrl+I}
|
||||||
keyboard shortcut to format code instead of indenting.
|
keyboard shortcut to format code instead of indenting.
|
||||||
\li \uicontrol {Use Built-In Indenter} to turn off ClangFormat.
|
\li \uicontrol {Use Built-In Indenter} to turn off
|
||||||
|
\l{ClangFormat: Documentation}{ClangFormat}.
|
||||||
\endlist
|
\endlist
|
||||||
\li Select \uicontrol {Ignore files greater than} to make parsing faster
|
\li Select \uicontrol {Ignore files greater than} to make parsing faster
|
||||||
by ignoring big files. Specify the maximum size of files to parse.
|
by ignoring big files. Specify the maximum size of files to parse.
|
||||||
@@ -38,10 +39,8 @@
|
|||||||
\li In \uicontrol {Custom settings}, select the settings to change, and
|
\li In \uicontrol {Custom settings}, select the settings to change, and
|
||||||
then select \uicontrol Copy.
|
then select \uicontrol Copy.
|
||||||
\li Give a name to the settings, and select \uicontrol OK.
|
\li Give a name to the settings, and select \uicontrol OK.
|
||||||
\li In \uicontrol ClangFormat, edit the
|
\li In \uicontrol ClangFormat, edit the \l {ClangFormat Style Options}.
|
||||||
\l{https://clang.llvm.org/docs/ClangFormatStyleOptions.html}
|
The live preview shows how the preferences change the indentation.
|
||||||
{ClangFormat Style Options}. The live preview shows how the
|
|
||||||
preferences change the indentation.
|
|
||||||
If you enter invalid values, you see warning messages.
|
If you enter invalid values, you see warning messages.
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
|
@@ -253,3 +253,19 @@
|
|||||||
\externalpage https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/share/qtcreator/jsonschemas/project.json
|
\externalpage https://code.qt.io/cgit/qt-creator/qt-creator.git/tree/share/qtcreator/jsonschemas/project.json
|
||||||
\title project.json
|
\title project.json
|
||||||
*/
|
*/
|
||||||
|
/*!
|
||||||
|
\externalpage https://clang.llvm.org/docs/ClangFormat.html
|
||||||
|
\title ClangFormat: Documentation
|
||||||
|
*/
|
||||||
|
/*!
|
||||||
|
\externalpage https://llvm.org/releases/download.html
|
||||||
|
\title ClangFormat: Download
|
||||||
|
*/
|
||||||
|
/*!
|
||||||
|
\externalpage https://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||||
|
\title ClangFormat Style Options
|
||||||
|
*/
|
||||||
|
/*!
|
||||||
|
\externalpage https://clang.llvm.org/docs/LibFormat.html
|
||||||
|
\title LibFormat: Documentation
|
||||||
|
*/
|
||||||
|
38
doc/qtcreator/src/howto/creator-only/creator-telemetry.qdoc
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\page creator-how-to-collect-usage-statistics.html
|
||||||
|
\previouspage creator-how-tos.html
|
||||||
|
|
||||||
|
\ingroup creator-how-to-use
|
||||||
|
|
||||||
|
\title Collect usage statistics
|
||||||
|
|
||||||
|
When you install \QC with \QOI, you can allow it to collect pseudonymous
|
||||||
|
information about your system and \QC use. If you decline, the telemetry
|
||||||
|
plugin is not installed and no usage statistics are collected.
|
||||||
|
|
||||||
|
\section1 Principles of data collection
|
||||||
|
|
||||||
|
No personal data, such as names, IP addresses, MAC addresses, or project
|
||||||
|
and path names are collected. However, QUuid objects are used to identify
|
||||||
|
data records that belong to one user. The objects cannot be converted
|
||||||
|
back to the actual values from which they were generated.
|
||||||
|
|
||||||
|
For more information about Qt privacy policy, see
|
||||||
|
\l{https://www.qt.io/terms-conditions/privacy-and-security}
|
||||||
|
{Qt Appendix for Privacy and Security}.
|
||||||
|
|
||||||
|
\QC respects the same privacy rules.
|
||||||
|
|
||||||
|
\section1 Turn on data collection
|
||||||
|
|
||||||
|
To allow the telemetry plugin to collect data, go to \preferences >
|
||||||
|
\uicontrol Telemetry > \uicontrol {Usage Statistics}, and then select
|
||||||
|
\uicontrol {Send pseudonymous usage statistics}.
|
||||||
|
|
||||||
|
\image qtcreator-preferences-telemetry-usage-statistics.webp {Usage Statistics}
|
||||||
|
|
||||||
|
\sa {Installation}
|
||||||
|
*/
|
@@ -1,106 +0,0 @@
|
|||||||
// Copyright (C) 2023 The Qt Company Ltd.
|
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\page creator-telemetry.html
|
|
||||||
\if defined(qtdesignstudio)
|
|
||||||
\previouspage creator-quick-ui-forms.html
|
|
||||||
\nextpage collecting-usage-statistics.html
|
|
||||||
\else
|
|
||||||
\previouspage creator-how-tos.html
|
|
||||||
\endif
|
|
||||||
|
|
||||||
\ingroup creator-how-to-use
|
|
||||||
|
|
||||||
\title Manage data collection
|
|
||||||
|
|
||||||
\if defined (qtcreator)
|
|
||||||
When you install \QC as a part of Qt installation, you are asked whether
|
|
||||||
you allow it to collect pseudonymous information about your system and \QC
|
|
||||||
use. If you decline, the plugin is not installed and no analytics data is
|
|
||||||
collected.
|
|
||||||
|
|
||||||
If you accept, all collected and transmitted data is fully transparent to
|
|
||||||
you. You can change the settings for collecting and transmitting data any
|
|
||||||
time. By default, no data is collected and you have to select a telemetry
|
|
||||||
mode for data collection to begin.
|
|
||||||
|
|
||||||
|
|
||||||
See \l {Collect usage statistics} for more information about the data
|
|
||||||
transmitted by the telemetry plugin and \l {Specify telemetry settings}
|
|
||||||
{specifying telemetry settings}.
|
|
||||||
\else
|
|
||||||
To enable the use of the telemetry plugin, you need to select \uicontrol
|
|
||||||
{Enable Usage Statistics} in the splash screen that appears when you first
|
|
||||||
launch \QDS. If the splash screen does not appear, you can enable the
|
|
||||||
telemetry plugin by selecting \uicontrol Help > \uicontrol {About Plugins} >
|
|
||||||
\uicontrol Utilities > \uicontrol UsageStatistic on Linux and Windows (or
|
|
||||||
\uicontrol {\QDS} > \uicontrol {About Plugins} > \uicontrol Utilities >
|
|
||||||
\uicontrol UsageStatistic on \macos).
|
|
||||||
\image studio-usage-statistics.png "Enabling Usage Statistics"
|
|
||||||
\endif
|
|
||||||
|
|
||||||
\if defined(qtdesignstudio)
|
|
||||||
See below for more information about the collected data:
|
|
||||||
|
|
||||||
\list
|
|
||||||
\li \l {Collect usage statistics}
|
|
||||||
\li \l {Collecting User Feedback}
|
|
||||||
\li \l {Reporting Crashes}
|
|
||||||
\endlist
|
|
||||||
\endif
|
|
||||||
|
|
||||||
\section1 Principles of data collection
|
|
||||||
|
|
||||||
No personal data, such as names, IP addresses, MAC addresses, or project
|
|
||||||
and path names are collected. However, QUuid objects are used to identify
|
|
||||||
data records that belong to one user. The objects cannot be converted
|
|
||||||
back to the actual values from which they were generated.
|
|
||||||
|
|
||||||
For more information about Qt privacy policy, select
|
|
||||||
\l{https://www.qt.io/terms-conditions/#privacy}
|
|
||||||
{Legal Notice and Privacy Policy}.
|
|
||||||
|
|
||||||
\sa {Collect usage statistics}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\page collecting-usage-statistics.html
|
|
||||||
\if defined(qtdesignstudio)
|
|
||||||
\previouspage creator-telemetry.html
|
|
||||||
\nextpage studio-user-feedback.html
|
|
||||||
\else
|
|
||||||
\previouspage creator-how-tos.html
|
|
||||||
\endif
|
|
||||||
|
|
||||||
\ingroup creator-how-to-use
|
|
||||||
|
|
||||||
\title Collect usage statistics
|
|
||||||
|
|
||||||
The telemetry plugin uses the
|
|
||||||
\l{https://api.kde.org/frameworks/kuserfeedback/html/index.html}
|
|
||||||
{KUserFeedback} framework to collect the usage data. The library
|
|
||||||
has been designed from the user data privacy point of view and
|
|
||||||
\QC respects the same privacy rules.
|
|
||||||
|
|
||||||
The data is transmitted to the backend storage using an encrypted
|
|
||||||
connection. The storage is located in the same Heroku backend as the
|
|
||||||
\QOI backend. Physically, data is stored in the Amazon cloud.
|
|
||||||
|
|
||||||
\section1 Specify telemetry settings
|
|
||||||
|
|
||||||
To determine what data is transmitted to the backend storage:
|
|
||||||
|
|
||||||
\list 1
|
|
||||||
\li Select \preferences > \uicontrol Telemetry
|
|
||||||
> \uicontrol {Usage Statistics}.
|
|
||||||
\image qtcreator-telemetry-settings.png "Telemetry settings"
|
|
||||||
\li In the \uicontrol {Telemetry mode} list, select the mode that
|
|
||||||
determines what kind of data is collected.
|
|
||||||
\li In the \uicontrol {Data sources} list, select entries to view
|
|
||||||
exactly what data is collected. Deselect check boxes for data
|
|
||||||
that you do not want to transmit to the backend storage.
|
|
||||||
\endlist
|
|
||||||
|
|
||||||
\sa {Manage data collection}
|
|
||||||
*/
|
|
@@ -258,17 +258,29 @@
|
|||||||
system libraries or your own libraries. Further, your own libraries might
|
system libraries or your own libraries. Further, your own libraries might
|
||||||
link to other libraries. To compile your project and benefit from services
|
link to other libraries. To compile your project and benefit from services
|
||||||
such as code completion and syntax highlighting, add the libraries to your
|
such as code completion and syntax highlighting, add the libraries to your
|
||||||
project. The process of adding a library to a project depends on the build
|
project.
|
||||||
system that you use.
|
|
||||||
|
|
||||||
\section1 CMake projects
|
\section1 Create subprojects
|
||||||
|
|
||||||
To add CMakeLists.txt files to any project, use the
|
To create subprojects and add them to a project:
|
||||||
\l{https://cmake.org/cmake/help/latest/command/add_subdirectory.html}
|
|
||||||
{add_subdirectory} command. The files can define complete projects that
|
|
||||||
you include into the top-level project or any other CMake commands.
|
|
||||||
|
|
||||||
\section1 qmake projects
|
\list 1
|
||||||
|
\li Right-click the project name in the \l Projects view to open the
|
||||||
|
context menu, and select \uicontrol {New Subproject}.
|
||||||
|
\li Follow the instructions of the wizard to create a subproject.
|
||||||
|
\image qtcreator-project-qt-quick.webp {New Project dialog}
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
\section1 Add existing projects as subprojects
|
||||||
|
|
||||||
|
To add an existing project as a subproject:
|
||||||
|
|
||||||
|
\list 1
|
||||||
|
\li Select \uicontrol {Add Existing Projects} in the context menu.
|
||||||
|
\li In the file browser dialog, locate your subproject.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
\section1 Create SUBDIRS projects for qmake
|
||||||
|
|
||||||
When you create a new project and select qmake as the build system,
|
When you create a new project and select qmake as the build system,
|
||||||
you can add it to another project as a subproject in the
|
you can add it to another project as a subproject in the
|
||||||
@@ -292,28 +304,15 @@
|
|||||||
and the subproject that you add as a value of the \l{Variables#subdirs}
|
and the subproject that you add as a value of the \l{Variables#subdirs}
|
||||||
{SUBDIRS variable}. It also adds all the necessary files for the subproject.
|
{SUBDIRS variable}. It also adds all the necessary files for the subproject.
|
||||||
|
|
||||||
\section2 Add subprojects to the root project
|
\section2 Specify dependencies
|
||||||
|
|
||||||
To create more subprojects, right-click the project name in the
|
To specify dependencies, use the \uicontrol{Add Library} wizard.
|
||||||
\l Projects view to open the context menu, and select
|
|
||||||
\uicontrol {New Subproject}. Follow the steps in the
|
|
||||||
\uicontrol {New Subproject} wizard to create a subproject.
|
|
||||||
|
|
||||||
\image qtcreator-project-qt-quick.webp {New Project dialog}
|
|
||||||
|
|
||||||
To add an existing project as a subproject, select
|
|
||||||
\uicontrol {Add Existing Projects} in the context menu.
|
|
||||||
In the file browser dialog, locate your subproject.
|
|
||||||
|
|
||||||
\section2 Remove subprojects
|
\section2 Remove subprojects
|
||||||
|
|
||||||
To remove subprojects, right-click the project name in the \uicontrol Projects
|
To remove subprojects, right-click the project name in the \uicontrol Projects
|
||||||
view, and select \uicontrol {Remove Subproject} in the context menu.
|
view, and select \uicontrol {Remove Subproject} in the context menu.
|
||||||
|
|
||||||
\section2 Specify dependencies
|
|
||||||
|
|
||||||
To specify dependencies, use the \uicontrol{Add Library} wizard.
|
|
||||||
|
|
||||||
\sa {Creating Projects}, {Use project wizards},
|
\sa {Creating Projects}, {Use project wizards},
|
||||||
{Add libraries to qmake projects}, {Add libraries to CMake projects}
|
{Add libraries to qmake projects}, {Add libraries to CMake projects}
|
||||||
*/
|
*/
|
||||||
|
@@ -53,9 +53,9 @@
|
|||||||
project.
|
project.
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
In rare cases, ClangFormat can trip over a code construct and
|
In rare cases, \l{ClangFormat: Documentation}{ClangFormat} can trip over a
|
||||||
trigger a \QC crash. If that happens for your project, select
|
code construct and trigger a \QC crash. If that happens for your project,
|
||||||
\uicontrol {Use Built-In Indenter} in \uicontrol {Formatting mode} to
|
select \uicontrol {Use Built-In Indenter} in \uicontrol {Formatting mode} to
|
||||||
turn off ClangFormat for the project. If you can reproduce the crash,
|
turn off ClangFormat for the project. If you can reproduce the crash,
|
||||||
go to \uicontrol Help > \uicontrol {Report Bug} to report
|
go to \uicontrol Help > \uicontrol {Report Bug} to report
|
||||||
the bug and attach the code that triggers the crash to the bug report.
|
the bug and attach the code that triggers the crash to the bug report.
|
||||||
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1,59 @@
|
|||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\page studio-telemetry.html
|
||||||
|
\previouspage creator-quick-ui-forms.html
|
||||||
|
\nextpage studio-collecting-usage-statistics.html
|
||||||
|
|
||||||
|
\title Managing Data Collection
|
||||||
|
|
||||||
|
See below for more information about the collected data:
|
||||||
|
|
||||||
|
\list
|
||||||
|
\li \l {Collecting Usage Statistics}
|
||||||
|
\li \l {Collecting User Feedback}
|
||||||
|
\li \l {Reporting Crashes}
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
\section1 Principles of Data Collection
|
||||||
|
|
||||||
|
No personal data, such as names, IP addresses, MAC addresses, or project
|
||||||
|
and path names are collected. However, QUuid objects are used to identify
|
||||||
|
data records that belong to one user. The objects cannot be converted
|
||||||
|
back to the actual values from which they were generated.
|
||||||
|
|
||||||
|
For more information about Qt privacy policy, see
|
||||||
|
\l{https://www.qt.io/terms-conditions/privacy-and-security}
|
||||||
|
{Qt Appendix for Privacy and Security}.
|
||||||
|
|
||||||
|
\sa {Collecting Usage Statistics}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\page studio-collecting-usage-statistics.html
|
||||||
|
\previouspage studio-telemetry.html
|
||||||
|
\nextpage studio-user-feedback.html
|
||||||
|
|
||||||
|
\title Collecting Usage Statistics
|
||||||
|
|
||||||
|
The telemetry plugin uses the
|
||||||
|
\l{https://api.kde.org/frameworks/kuserfeedback/html/index.html}
|
||||||
|
{KUserFeedback} framework to collect the usage data. The library
|
||||||
|
has been designed from the user data privacy point of view and
|
||||||
|
\QC respects the same privacy rules.
|
||||||
|
|
||||||
|
The data is transmitted to the backend storage using an encrypted
|
||||||
|
connection. The storage is located in the same Heroku backend as the
|
||||||
|
\QOI backend. Physically, data is stored in the Amazon cloud.
|
||||||
|
|
||||||
|
\section1 Turning on Telemetry
|
||||||
|
|
||||||
|
To determine what data is transmitted to the backend storage, go to
|
||||||
|
\preferences > \uicontrol Telemetry > \uicontrol {Usage Statistics},
|
||||||
|
and then select \uicontrol {Enable telemetry}.
|
||||||
|
|
||||||
|
\image studio-preferences-telemetry-usage-statistics.webp {Usage Statistics}
|
||||||
|
|
||||||
|
\sa {Managing Data Collection}
|
||||||
|
*/
|
@@ -23,7 +23,7 @@
|
|||||||
Some of the wizard templates create projects that contain UI files.
|
Some of the wizard templates create projects that contain UI files.
|
||||||
You should always edit UI files in the \l {2D}
|
You should always edit UI files in the \l {2D}
|
||||||
and \l Properties view, to avoid breaking the code.
|
and \l Properties view, to avoid breaking the code.
|
||||||
\li \l{Manage Data Collection}
|
\li \l{Managing Data Collection}
|
||||||
|
|
||||||
You can enable \QDS to report crashes automatically. If you enable
|
You can enable \QDS to report crashes automatically. If you enable
|
||||||
the telemetry plugin, you can turn on the pseudonymous user
|
the telemetry plugin, you can turn on the pseudonymous user
|
||||||
|
@@ -217,9 +217,9 @@
|
|||||||
\li Extending Component Functionality
|
\li Extending Component Functionality
|
||||||
\endomit
|
\endomit
|
||||||
\li \l{UI Files}
|
\li \l{UI Files}
|
||||||
\li \l{Manage Data Collection}
|
\li \l{Managing Data Collection}
|
||||||
\list
|
\list
|
||||||
\li \l {Collect Usage Statistics}
|
\li \l {Collecting Usage Statistics}
|
||||||
\li \l {Collecting User Feedback}
|
\li \l {Collecting User Feedback}
|
||||||
\li \l {Reporting Crashes}
|
\li \l {Reporting Crashes}
|
||||||
\endlist
|
\endlist
|
||||||
|
@@ -272,12 +272,7 @@ def package_qtcreator(args, paths):
|
|||||||
if not args.no_cdb:
|
if not args.no_cdb:
|
||||||
common.check_print_call(command + [paths.qtcreatorcdbext_install])
|
common.check_print_call(command + [paths.qtcreatorcdbext_install])
|
||||||
|
|
||||||
# use -mf=off to avoid usage of the ARM executable compression filter,
|
zip = common.sevenzip_command(args.zip_threads)
|
||||||
# which cannot be extracted by p7zip
|
|
||||||
# use -snl to preserve symlinks even if their target doesn't exist
|
|
||||||
# which is important for the _dev package on Linux
|
|
||||||
# (only works with official/upstream 7zip)
|
|
||||||
zip = ['7z', 'a', '-mmt' + args.zip_threads, '-mf=off', '-snl']
|
|
||||||
if not args.no_zip:
|
if not args.no_zip:
|
||||||
if not args.no_qtcreator:
|
if not args.no_qtcreator:
|
||||||
common.check_print_call(zip
|
common.check_print_call(zip
|
||||||
|
@@ -147,12 +147,7 @@ def package(args, paths):
|
|||||||
if common.is_windows_platform() and args.sign_command:
|
if common.is_windows_platform() and args.sign_command:
|
||||||
command = shlex.split(args.sign_command)
|
command = shlex.split(args.sign_command)
|
||||||
common.check_print_call(command + [paths.install])
|
common.check_print_call(command + [paths.install])
|
||||||
# use -mf=off to avoid usage of the ARM executable compression filter,
|
zip = common.sevenzip_command(args.zip_threads)
|
||||||
# which cannot be extracted by p7zip
|
|
||||||
# use -snl to preserve symlinks even if their target doesn't exist
|
|
||||||
# which is important for the _dev package on Linux
|
|
||||||
# (only works with official/upstream 7zip)
|
|
||||||
zip = ['7z', 'a', '-mmt' + args.zip_threads, '-mf=off', '-snl']
|
|
||||||
common.check_print_call(zip + [os.path.join(paths.result, args.name + '.7z'), '*'],
|
common.check_print_call(zip + [os.path.join(paths.result, args.name + '.7z'), '*'],
|
||||||
paths.install)
|
paths.install)
|
||||||
if os.path.exists(paths.dev_install): # some plugins might not provide anything in Devel
|
if os.path.exists(paths.dev_install): # some plugins might not provide anything in Devel
|
||||||
|
@@ -4,13 +4,13 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse
|
import argparse
|
||||||
from itertools import islice
|
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import NamedTuple
|
from typing import NamedTuple
|
||||||
|
|
||||||
from common import (is_linux_platform, is_mac_platform, is_windows_platform,
|
from common import (is_linux_platform, is_mac_platform, is_windows_platform,
|
||||||
download_and_extract, check_print_call)
|
download_and_extract, check_print_call, sevenzip_command,
|
||||||
|
get_single_subdir)
|
||||||
|
|
||||||
|
|
||||||
class BuildParams(NamedTuple):
|
class BuildParams(NamedTuple):
|
||||||
@@ -105,13 +105,6 @@ def sign_sdktool(params: BuildParams,
|
|||||||
env=environment)
|
env=environment)
|
||||||
|
|
||||||
|
|
||||||
def get_single_subdir(path: Path):
|
|
||||||
entries = list(islice(path.iterdir(), 2))
|
|
||||||
if len(entries) == 1:
|
|
||||||
return path / entries[0]
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
def build_sdktool(
|
def build_sdktool(
|
||||||
qt_src_url: str,
|
qt_src_url: str,
|
||||||
qt_build_base: Path,
|
qt_build_base: Path,
|
||||||
@@ -150,7 +143,7 @@ def zip_sdktool(
|
|||||||
) -> None:
|
) -> None:
|
||||||
glob = "*.exe" if is_windows_platform() else "*"
|
glob = "*.exe" if is_windows_platform() else "*"
|
||||||
check_print_call(
|
check_print_call(
|
||||||
cmd=["7z", "a", str(out_7zip), glob],
|
cmd=sevenzip_command() + [str(out_7zip), glob],
|
||||||
cwd=sdktool_target_path
|
cwd=sdktool_target_path
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse
|
import argparse
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from itertools import islice
|
||||||
import os
|
import os
|
||||||
import locale
|
import locale
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@@ -61,6 +62,26 @@ def get_commit_SHA(path):
|
|||||||
git_sha = f.read().strip()
|
git_sha = f.read().strip()
|
||||||
return git_sha
|
return git_sha
|
||||||
|
|
||||||
|
|
||||||
|
def get_single_subdir(path: Path):
|
||||||
|
entries = list(islice(path.iterdir(), 2))
|
||||||
|
if len(entries) == 1:
|
||||||
|
return path / entries[0]
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
def sevenzip_command(threads=None):
|
||||||
|
# use -mf=off to avoid usage of the ARM executable compression filter,
|
||||||
|
# which cannot be extracted by p7zip
|
||||||
|
# use -snl to preserve symlinks even if their target doesn't exist
|
||||||
|
# which is important for the _dev package on Linux
|
||||||
|
# (only works with official/upstream 7zip)
|
||||||
|
command = ['7z', 'a', '-mf=off', '-snl']
|
||||||
|
if threads:
|
||||||
|
command.extend(['-mmt' + threads])
|
||||||
|
return command
|
||||||
|
|
||||||
|
|
||||||
# copy of shutil.copytree that does not bail out if the target directory already exists
|
# copy of shutil.copytree that does not bail out if the target directory already exists
|
||||||
# and that does not create empty directories
|
# and that does not create empty directories
|
||||||
def copytree(src, dst, symlinks=False, ignore=None):
|
def copytree(src, dst, symlinks=False, ignore=None):
|
||||||
@@ -142,22 +163,26 @@ async def download(url: str, target: Path) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def download_and_extract(urls: list[str], target: Path, temp: Path) -> None:
|
def download_and_extract(urls: list[str], target: Path, temp: Path) -> None:
|
||||||
|
download_and_extract_tuples([(url, target) for url in urls], temp)
|
||||||
|
|
||||||
|
|
||||||
|
def download_and_extract_tuples(urls_and_targets: list[tuple[str, Path]], temp: Path) -> None:
|
||||||
temp.mkdir(parents=True, exist_ok=True)
|
temp.mkdir(parents=True, exist_ok=True)
|
||||||
target_files = []
|
target_tuples : list[tuple[Path, Path]] = []
|
||||||
# TODO make this work with file URLs, which then aren't downloaded
|
# TODO make this work with file URLs, which then aren't downloaded
|
||||||
# but just extracted
|
# but just extracted
|
||||||
async def impl():
|
async def impl():
|
||||||
tasks : list[asyncio.Task] = []
|
tasks : list[asyncio.Task] = []
|
||||||
for url in urls:
|
for (url, target_path) in urls_and_targets:
|
||||||
u = urlparse(url)
|
u = urlparse(url)
|
||||||
filename = Path(u.path).name
|
filename = Path(u.path).name
|
||||||
target_file = temp / filename
|
target_file = temp / filename
|
||||||
target_files.append(target_file)
|
target_tuples.append((target_file, target_path))
|
||||||
tasks.append(asyncio.create_task(download(url, target_file)))
|
tasks.append(asyncio.create_task(download(url, target_file)))
|
||||||
for task in tasks:
|
for task in tasks:
|
||||||
await task
|
await task
|
||||||
asyncio.run(impl())
|
asyncio.run(impl())
|
||||||
for file in target_files:
|
for (file, target) in target_tuples:
|
||||||
extract_file(file, target)
|
extract_file(file, target)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import argparse
|
import argparse
|
||||||
from common import download_and_extract
|
from common import download_and_extract_tuples
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
@@ -73,10 +73,10 @@ def install_qt(
|
|||||||
|
|
||||||
with TemporaryDirectory() as temporary_dir:
|
with TemporaryDirectory() as temporary_dir:
|
||||||
if need_to_install_qt:
|
if need_to_install_qt:
|
||||||
urls = qt_modules
|
url_target_tuples = [(url, qt_path) for url in qt_modules]
|
||||||
if icu_url:
|
if icu_url:
|
||||||
qt_modules.append(icu_url)
|
url_target_tuples.append((icu_url, qt_path / 'lib'))
|
||||||
download_and_extract(urls, qt_path, Path(temporary_dir))
|
download_and_extract_tuples(url_target_tuples, Path(temporary_dir))
|
||||||
patch_qt(qt_path)
|
patch_qt(qt_path)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -202,6 +202,46 @@ def qdump__CPlusPlus__Internal__Value(d, value):
|
|||||||
d.putPlainChildren(value)
|
d.putPlainChildren(value)
|
||||||
|
|
||||||
|
|
||||||
|
def is_windows_drive_letter(ch):
|
||||||
|
return (ch >= ord('A') and ch <= ord('Z')) or (ch >= ord('a') and ch <= ord('z'))
|
||||||
|
|
||||||
|
def is_relative_filepath_enc(path_enc):
|
||||||
|
# Note: path is hex-encoded UTF-16 here, i.e. 4 byte per original QChar
|
||||||
|
"""
|
||||||
|
This needs to stay in sync with the implementation on the C++ side
|
||||||
|
in filepath.cpp.
|
||||||
|
|
||||||
|
bool isWindowsDriveLetter(QChar ch)
|
||||||
|
{
|
||||||
|
return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
|
||||||
|
}
|
||||||
|
bool startsWithWindowsDriveLetterAndSlash(QStringView path)
|
||||||
|
{
|
||||||
|
return path.size() > 2 && path[1] == ':' && path[2] == '/
|
||||||
|
&& isWindowsDriveLetter(path[0]);
|
||||||
|
}
|
||||||
|
bool FilePath::isRelativePath() const
|
||||||
|
{
|
||||||
|
const QStringView p = pathView();
|
||||||
|
if (p.startsWith('/'))
|
||||||
|
return false;
|
||||||
|
if (startsWithWindowsDriveLetterAndSlash(p))
|
||||||
|
return false;
|
||||||
|
if (p.startsWith(u":/")) // QRC
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
colon = "3A00"
|
||||||
|
slash = "2F00"
|
||||||
|
if path_enc.startswith(slash):
|
||||||
|
return False
|
||||||
|
if path_enc[4:12] == colon + slash and is_windows_drive_letter(int(path_enc[0:2], 16)):
|
||||||
|
return False
|
||||||
|
if path_enc.startswith(colon + slash):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def qdump__Utils__FilePath(d, value):
|
def qdump__Utils__FilePath(d, value):
|
||||||
data, path_len, scheme_len, host_len = d.split("{@QString}IHH", value)
|
data, path_len, scheme_len, host_len = d.split("{@QString}IHH", value)
|
||||||
length, enc = d.encodeStringHelper(data, d.displayStringLimit)
|
length, enc = d.encodeStringHelper(data, d.displayStringLimit)
|
||||||
@@ -216,8 +256,10 @@ def qdump__Utils__FilePath(d, value):
|
|||||||
dot = "2E00"
|
dot = "2E00"
|
||||||
colon = "3A00"
|
colon = "3A00"
|
||||||
val = scheme_enc + colon + slash + slash + host_enc
|
val = scheme_enc + colon + slash + slash + host_enc
|
||||||
if not path_enc.startswith(slash):
|
if is_relative_filepath_enc(path_enc):
|
||||||
val += slash + dot + slash
|
val += slash + dot + slash
|
||||||
|
elif is_windows_drive_letter(int(path_enc[0:2], 16)):
|
||||||
|
val += slash
|
||||||
val += path_enc
|
val += path_enc
|
||||||
else:
|
else:
|
||||||
val = enc
|
val = enc
|
||||||
|
@@ -988,7 +988,7 @@ class Dumper(DumperBase):
|
|||||||
connect_options = lldb.SBPlatformConnectOptions(self.remoteChannel_)
|
connect_options = lldb.SBPlatformConnectOptions(self.remoteChannel_)
|
||||||
res = self.target.GetPlatform().ConnectRemote(connect_options)
|
res = self.target.GetPlatform().ConnectRemote(connect_options)
|
||||||
|
|
||||||
DumperBase.warn("CONNECT: %s %s platform: %s %s" % (res,
|
DumperBase.warn("CONNECT: %s %s platform: %s connected: %s" % (res,
|
||||||
self.remoteChannel_,
|
self.remoteChannel_,
|
||||||
self.target.GetPlatform().GetName(),
|
self.target.GetPlatform().GetName(),
|
||||||
self.target.GetPlatform().IsConnected()))
|
self.target.GetPlatform().IsConnected()))
|
||||||
|
@@ -46,6 +46,9 @@ local function tst_embedWidget()
|
|||||||
}
|
}
|
||||||
|
|
||||||
embed = editor:addEmbeddedWidget(layout, cursor:mainCursor():position())
|
embed = editor:addEmbeddedWidget(layout, cursor:mainCursor():position())
|
||||||
|
embed:onShouldClose(function()
|
||||||
|
embed:close()
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function setup()
|
local function setup()
|
||||||
|
@@ -1451,10 +1451,10 @@ void PluginManagerPrivate::loadPlugins()
|
|||||||
|
|
||||||
void PluginManagerPrivate::loadPluginsAtRuntime(const QSet<PluginSpec *> &plugins)
|
void PluginManagerPrivate::loadPluginsAtRuntime(const QSet<PluginSpec *> &plugins)
|
||||||
{
|
{
|
||||||
const bool allSoftloadable = allOf(plugins, &PluginSpec::isSoftLoadable);
|
const bool allSoftloadable = allOf(plugins, &PluginSpec::isEffectivelySoftloadable);
|
||||||
if (!allSoftloadable) {
|
if (!allSoftloadable) {
|
||||||
const QStringList notSoftLoadablePlugins = Utils::transform<QStringList>(
|
const QStringList notSoftLoadablePlugins = Utils::transform<QStringList>(
|
||||||
Utils::filtered(plugins, std::not_fn(&PluginSpec::isSoftLoadable)),
|
Utils::filtered(plugins, std::not_fn(&PluginSpec::isEffectivelySoftloadable)),
|
||||||
&PluginSpec::displayName);
|
&PluginSpec::displayName);
|
||||||
qWarning().noquote()
|
qWarning().noquote()
|
||||||
<< "PluginManagerPrivate::loadPluginsAtRuntime(): trying to load non-softloadable"
|
<< "PluginManagerPrivate::loadPluginsAtRuntime(): trying to load non-softloadable"
|
||||||
@@ -1464,7 +1464,7 @@ void PluginManagerPrivate::loadPluginsAtRuntime(const QSet<PluginSpec *> &plugin
|
|||||||
// load the plugins and their dependencies (if possible) ordered by dependency
|
// load the plugins and their dependencies (if possible) ordered by dependency
|
||||||
const QList<PluginSpec *> queue = filtered(loadQueue(), [&plugins](PluginSpec *spec) {
|
const QList<PluginSpec *> queue = filtered(loadQueue(), [&plugins](PluginSpec *spec) {
|
||||||
// Is the current plugin already running, or not soft loadable?
|
// Is the current plugin already running, or not soft loadable?
|
||||||
if (spec->state() == PluginSpec::State::Running || !spec->isSoftLoadable())
|
if (spec->state() == PluginSpec::State::Running || !spec->isEffectivelySoftloadable())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Is the current plugin in the list of plugins to load?
|
// Is the current plugin in the list of plugins to load?
|
||||||
|
@@ -497,6 +497,22 @@ bool PluginSpec::isForceDisabled() const
|
|||||||
return d->forceDisabled;
|
return d->forceDisabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PluginSpec::isEffectivelySoftloadable() const
|
||||||
|
{
|
||||||
|
if (state() == Running)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!d->softLoadable)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (state() < PluginSpec::Resolved)
|
||||||
|
return false; // We won't know yet.
|
||||||
|
|
||||||
|
return !Utils::anyOf(dependencySpecs(), [](PluginSpec *dependency) {
|
||||||
|
return !dependency->isEffectivelySoftloadable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns whether the plugin is allowed to be loaded during runtime
|
Returns whether the plugin is allowed to be loaded during runtime
|
||||||
without a restart.
|
without a restart.
|
||||||
|
@@ -131,6 +131,7 @@ public:
|
|||||||
virtual bool isForceEnabled() const;
|
virtual bool isForceEnabled() const;
|
||||||
virtual bool isForceDisabled() const;
|
virtual bool isForceDisabled() const;
|
||||||
virtual bool isSoftLoadable() const;
|
virtual bool isSoftLoadable() const;
|
||||||
|
virtual bool isEffectivelySoftloadable() const;
|
||||||
|
|
||||||
virtual QVector<PluginDependency> dependencies() const;
|
virtual QVector<PluginDependency> dependencies() const;
|
||||||
virtual QJsonObject metaData() const;
|
virtual QJsonObject metaData() const;
|
||||||
|
@@ -239,8 +239,10 @@ Result DeviceFileAccess::copyRecursively(const FilePath &src, const FilePath &ta
|
|||||||
targetProcess.writeRaw(srcProcess.readAllRawStandardOutput());
|
targetProcess.writeRaw(srcProcess.readAllRawStandardOutput());
|
||||||
});
|
});
|
||||||
|
|
||||||
srcProcess.setCommand({sourceTar, {"-C", src.path(), "-cf", "-", "."}});
|
srcProcess.setCommand({sourceTar, {"-cf", "-", "."}});
|
||||||
targetProcess.setCommand({targetTar, {"xf", "-", "-C", target.path()}});
|
srcProcess.setWorkingDirectory(src);
|
||||||
|
targetProcess.setCommand({targetTar, {"xf", "-"}});
|
||||||
|
targetProcess.setWorkingDirectory(target);
|
||||||
|
|
||||||
targetProcess.start();
|
targetProcess.start();
|
||||||
targetProcess.waitForStarted();
|
targetProcess.waitForStarted();
|
||||||
|
@@ -869,6 +869,13 @@ static bool startsWithWindowsDriveLetterAndSlash(QStringView path)
|
|||||||
return path.size() > 2 && path[1] == ':' && path[2] == '/' && isWindowsDriveLetter(path[0]);
|
return path.size() > 2 && path[1] == ':' && path[2] == '/' && isWindowsDriveLetter(path[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool startsWithWindowsDriveLetter(QStringView path)
|
||||||
|
{
|
||||||
|
if (path.size() > 2 && startsWithWindowsDriveLetterAndSlash(path))
|
||||||
|
return true;
|
||||||
|
return path.size() == 2 && path[1] == ':' && isWindowsDriveLetter(path[0]);
|
||||||
|
}
|
||||||
|
|
||||||
int FilePath::rootLength(const QStringView path)
|
int FilePath::rootLength(const QStringView path)
|
||||||
{
|
{
|
||||||
if (path.size() == 0)
|
if (path.size() == 0)
|
||||||
@@ -888,6 +895,8 @@ int FilePath::rootLength(const QStringView path)
|
|||||||
|
|
||||||
if (startsWithWindowsDriveLetterAndSlash(path))
|
if (startsWithWindowsDriveLetterAndSlash(path))
|
||||||
return 3; // FIXME-ish: same assumption as elsewhere: we assume "x:/" only ever appears as root
|
return 3; // FIXME-ish: same assumption as elsewhere: we assume "x:/" only ever appears as root
|
||||||
|
if (path.size() == 2 && startsWithWindowsDriveLetter(path))
|
||||||
|
return 2;
|
||||||
|
|
||||||
if (path[0] == '/')
|
if (path[0] == '/')
|
||||||
return 1;
|
return 1;
|
||||||
@@ -1252,9 +1261,14 @@ void FilePath::setFromString(QStringView fileNameView)
|
|||||||
if (schemeEnd != -1 && schemeEnd < firstSlash) {
|
if (schemeEnd != -1 && schemeEnd < firstSlash) {
|
||||||
// This is a pseudo Url, we can't use QUrl here sadly.
|
// This is a pseudo Url, we can't use QUrl here sadly.
|
||||||
const QStringView scheme = fileNameView.left(schemeEnd);
|
const QStringView scheme = fileNameView.left(schemeEnd);
|
||||||
const int hostEnd = fileNameView.indexOf(slash, schemeEnd + 3);
|
int hostEnd = fileNameView.indexOf(slash, schemeEnd + 3);
|
||||||
const QString host = decodeHost(
|
const QString host = decodeHost(
|
||||||
fileNameView.mid(schemeEnd + 3, hostEnd - schemeEnd - 3).toString());
|
fileNameView.mid(schemeEnd + 3, hostEnd - schemeEnd - 3).toString());
|
||||||
|
|
||||||
|
QStringView path = fileNameView.mid(hostEnd);
|
||||||
|
if (!path.isEmpty() && path[0] == '/' && startsWithWindowsDriveLetter(path.mid(1)))
|
||||||
|
hostEnd++;
|
||||||
|
|
||||||
setParts(scheme, host, hostEnd != -1 ? fileNameView.mid(hostEnd) : QStringView());
|
setParts(scheme, host, hostEnd != -1 ? fileNameView.mid(hostEnd) : QStringView());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1553,9 +1567,6 @@ bool FilePath::contains(const QString &s) const
|
|||||||
bool FilePath::startsWithDriveLetter() const
|
bool FilePath::startsWithDriveLetter() const
|
||||||
{
|
{
|
||||||
QStringView p = pathView();
|
QStringView p = pathView();
|
||||||
if (needsDevice() && !p.isEmpty())
|
|
||||||
p = p.mid(1);
|
|
||||||
|
|
||||||
return p.size() >= 2 && isWindowsDriveLetter(p[0]) && p.at(1) == ':';
|
return p.size() >= 2 && isWindowsDriveLetter(p[0]) && p.at(1) == ':';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
|
#include <QKeyEvent>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
@@ -785,6 +786,11 @@ void Widget::setContentsMargins(int left, int top, int right, int bottom)
|
|||||||
access(this)->setContentsMargins(left, top, right, bottom);
|
access(this)->setContentsMargins(left, top, right, bottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Widget::setCursor(Qt::CursorShape shape)
|
||||||
|
{
|
||||||
|
access(this)->setCursor(shape);
|
||||||
|
}
|
||||||
|
|
||||||
void Widget::activateWindow()
|
void Widget::activateWindow()
|
||||||
{
|
{
|
||||||
access(this)->activateWindow();
|
access(this)->activateWindow();
|
||||||
@@ -1149,9 +1155,24 @@ void tight(Layout *layout)
|
|||||||
layout->setSpacing(0);
|
layout->setSpacing(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LineEditImpl : public Utils::FancyLineEdit
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using FancyLineEdit::FancyLineEdit;
|
||||||
|
|
||||||
|
void keyPressEvent(QKeyEvent *event) override
|
||||||
|
{
|
||||||
|
FancyLineEdit::keyPressEvent(event);
|
||||||
|
if (acceptReturnKeys && (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return))
|
||||||
|
event->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool acceptReturnKeys = false;
|
||||||
|
};
|
||||||
|
|
||||||
LineEdit::LineEdit(std::initializer_list<I> ps)
|
LineEdit::LineEdit(std::initializer_list<I> ps)
|
||||||
{
|
{
|
||||||
ptr = new Implementation;
|
ptr = new LineEditImpl;
|
||||||
apply(this, ps);
|
apply(this, ps);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1192,6 +1213,7 @@ void LineEdit::setMinimumHeight(int height)
|
|||||||
|
|
||||||
void LineEdit::onReturnPressed(const std::function<void()> &func, QObject *guard)
|
void LineEdit::onReturnPressed(const std::function<void()> &func, QObject *guard)
|
||||||
{
|
{
|
||||||
|
static_cast<LineEditImpl *>(access(this))->acceptReturnKeys = true;
|
||||||
QObject::connect(access(this), &Utils::FancyLineEdit::returnPressed, guard, func);
|
QObject::connect(access(this), &Utils::FancyLineEdit::returnPressed, guard, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -258,6 +258,8 @@ public:
|
|||||||
void setNoMargins(int = 0);
|
void setNoMargins(int = 0);
|
||||||
void setNormalMargins(int = 0);
|
void setNormalMargins(int = 0);
|
||||||
void setContentsMargins(int left, int top, int right, int bottom);
|
void setContentsMargins(int left, int top, int right, int bottom);
|
||||||
|
void setCursor(Qt::CursorShape shape);
|
||||||
|
|
||||||
void activateWindow();
|
void activateWindow();
|
||||||
void close();
|
void close();
|
||||||
};
|
};
|
||||||
|
@@ -382,7 +382,13 @@ QString MacroExpander::expand(const QString &stringWithVariables) const
|
|||||||
|
|
||||||
FilePath MacroExpander::expand(const FilePath &fileNameWithVariables) const
|
FilePath MacroExpander::expand(const FilePath &fileNameWithVariables) const
|
||||||
{
|
{
|
||||||
// We want single variables to expand to fully qualified strings.
|
// This is intentionally unsymmetric: We have already sanitized content
|
||||||
|
// in fileNameWithVariables, so using .toString() is fine.
|
||||||
|
// The macro expansion may introduce arbitrary new contents, so
|
||||||
|
// sanitization using fromUserInput() needs to repeated.
|
||||||
|
// We also cannot just operate on the scheme, host and path component
|
||||||
|
// individually as we want to allow single variables to expand to fully
|
||||||
|
// remote-qualified paths.
|
||||||
return FilePath::fromUserInput(expand(fileNameWithVariables.toString()));
|
return FilePath::fromUserInput(expand(fileNameWithVariables.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -394,6 +394,11 @@ QSize MarkdownBrowser::minimumSizeHint() const
|
|||||||
return boundingRect.size().toSize() + QTextBrowser::minimumSizeHint();
|
return boundingRect.size().toSize() + QTextBrowser::minimumSizeHint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MarkdownBrowser::setMargins(const QMargins &margins)
|
||||||
|
{
|
||||||
|
setViewportMargins(margins);
|
||||||
|
}
|
||||||
|
|
||||||
void MarkdownBrowser::setAllowRemoteImages(bool allow)
|
void MarkdownBrowser::setAllowRemoteImages(bool allow)
|
||||||
{
|
{
|
||||||
static_cast<AnimatedDocument *>(document())->setAllowRemoteImages(allow);
|
static_cast<AnimatedDocument *>(document())->setAllowRemoteImages(allow);
|
||||||
|
@@ -25,6 +25,8 @@ public:
|
|||||||
QSize sizeHint() const override;
|
QSize sizeHint() const override;
|
||||||
QSize minimumSizeHint() const override;
|
QSize minimumSizeHint() const override;
|
||||||
|
|
||||||
|
void setMargins(const QMargins &margins);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void changeEvent(QEvent *event) override;
|
void changeEvent(QEvent *event) override;
|
||||||
|
|
||||||
|
@@ -58,6 +58,22 @@
|
|||||||
# include <QTest>
|
# include <QTest>
|
||||||
#endif // WITH_TESTS
|
#endif // WITH_TESTS
|
||||||
|
|
||||||
|
/*
|
||||||
|
Suggested NDK and Debugger version per Qt version:
|
||||||
|
|
||||||
|
| Qt5 | Qt6 | NDK | GDB | LLDB |
|
||||||
|
| ---------------- | --------- | ------------- | ------ | ------ |
|
||||||
|
| 5.12.0 - 5.13.1 | | 19.2.5345600 | 7.11.0 | |
|
||||||
|
| 5.13.2 - 5.15.8 | 6.0 - 6.1 | 21.3.6528147 | 8.3.0 | |
|
||||||
|
| 5.15.9 - 5.15.16 | 6.2 - 6.3 | 22.1.7171670 | 8.3.0 | 11.0.5 |
|
||||||
|
| | 6.4 | 23.1.7779620 | 8.3.0 | 12.0.8 |
|
||||||
|
| | 6.5 - 6.6 | 25.1.8937393 | | 14.0.6 |
|
||||||
|
| | 6.7 - 6.8 | 26.1.10909125 | | 17.0.2 |
|
||||||
|
|
||||||
|
< Qt 6.5: Mapping read from sdk_definitions.json
|
||||||
|
>= Qt 6.5: Mapping read from <QtDir>/modules/Core.json
|
||||||
|
*/
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
using namespace QtSupport;
|
using namespace QtSupport;
|
||||||
using namespace Tasking;
|
using namespace Tasking;
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include <projectexplorer/projectmanager.h>
|
#include <projectexplorer/projectmanager.h>
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
@@ -303,23 +304,30 @@ ITestConfiguration *QtTestTreeItem::debugConfiguration() const
|
|||||||
QList<ITestConfiguration *> QtTestTreeItem::getAllTestConfigurations() const
|
QList<ITestConfiguration *> QtTestTreeItem::getAllTestConfigurations() const
|
||||||
{
|
{
|
||||||
QList<ITestConfiguration *> result;
|
QList<ITestConfiguration *> result;
|
||||||
|
QList<QSet<QString>> allTargets;
|
||||||
|
|
||||||
ProjectExplorer::Project *project = ProjectExplorer::ProjectManager::startupProject();
|
ProjectExplorer::Project *project = ProjectExplorer::ProjectManager::startupProject();
|
||||||
if (!project || type() != Root)
|
if (!project || type() != Root)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
forFirstLevelChildren([&result](ITestTreeItem *child) {
|
// avoid executing tests with multiple test classes multiple times
|
||||||
if (child->type() == TestCase) {
|
auto appendConfiguration = [&result, &allTargets](ITestTreeItem *item) {
|
||||||
ITestConfiguration *tc = child->testConfiguration();
|
ITestConfiguration *config = item->testConfiguration();
|
||||||
QTC_ASSERT(tc, return);
|
QTC_ASSERT(config, return);
|
||||||
result << tc;
|
const QSet<QString> targets = static_cast<TestConfiguration *>(config)->internalTargets();
|
||||||
} else if (child->type() == GroupNode) {
|
if (allTargets.contains(targets)) {
|
||||||
child->forFirstLevelChildren([&result](ITestTreeItem *groupChild) {
|
delete config;
|
||||||
ITestConfiguration *tc = groupChild->testConfiguration();
|
} else {
|
||||||
QTC_ASSERT(tc, return);
|
result << config;
|
||||||
result << tc;
|
allTargets << targets;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
forFirstLevelChildren([appendConfiguration](ITestTreeItem *child) {
|
||||||
|
if (child->type() == TestCase)
|
||||||
|
appendConfiguration(child);
|
||||||
|
else if (child->type() == GroupNode)
|
||||||
|
child->forFirstLevelChildren(appendConfiguration);
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@@ -116,8 +116,8 @@ bool ITestTreeItem::lessThan(const ITestTreeItem *other, ITestTreeItem::SortMode
|
|||||||
return filePath().path().compare(other->filePath().path(), Qt::CaseInsensitive) > 0;
|
return filePath().path().compare(other->filePath().path(), Qt::CaseInsensitive) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Link &leftLink = data(0, LinkRole).value<Link>();
|
const Link leftLink{m_filePath, m_line};
|
||||||
const Link &rightLink = other->data(0, LinkRole).value<Link>();
|
const Link rightLink{other->m_filePath, other->m_line};
|
||||||
const int comparison = leftLink.targetFilePath.path()
|
const int comparison = leftLink.targetFilePath.path()
|
||||||
.compare(rightLink.targetFilePath.path(), Qt::CaseInsensitive);
|
.compare(rightLink.targetFilePath.path(), Qt::CaseInsensitive);
|
||||||
if (comparison == 0) {
|
if (comparison == 0) {
|
||||||
|
@@ -92,10 +92,6 @@ static std::optional<PathMapping> findPathMappingMatch(const QString &projectNam
|
|||||||
for (const PathMapping &mapping : settings().validPathMappings()) {
|
for (const PathMapping &mapping : settings().validPathMappings()) {
|
||||||
if (mapping.projectName != projectName)
|
if (mapping.projectName != projectName)
|
||||||
continue;
|
continue;
|
||||||
if (mapping.localPath.isRelativePath()) // TODO mark inside settings
|
|
||||||
continue;
|
|
||||||
if (mapping.analysisPath.isAbsolutePath()) // TODO mark inside settings
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (mapping.analysisPath.isEmpty())
|
if (mapping.analysisPath.isEmpty())
|
||||||
return mapping;
|
return mapping;
|
||||||
|
@@ -86,6 +86,31 @@ bool PathMapping::operator!=(const PathMapping &other) const
|
|||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool analysisPathValid(const FilePath &analysisPath, QString *error)
|
||||||
|
{
|
||||||
|
if (analysisPath.isEmpty())
|
||||||
|
return true;
|
||||||
|
if (analysisPath.needsDevice() || analysisPath.isAbsolutePath()) {
|
||||||
|
if (error)
|
||||||
|
*error = QString("Path must be relative.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
static const QRegularExpression invalid("^(.*/)?\\.\\.?(/.*)?$");
|
||||||
|
if (invalid.match(analysisPath.path()).hasMatch()) {
|
||||||
|
if (error)
|
||||||
|
*error = QString("Invalid path elements (. or ..)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PathMapping::isValid() const
|
||||||
|
{
|
||||||
|
return !projectName.isEmpty() && !localPath.isEmpty()
|
||||||
|
&& !localPath.needsDevice() && localPath.isAbsolutePath()
|
||||||
|
&& analysisPathValid(analysisPath, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
static FilePath axivionJsonFilePath()
|
static FilePath axivionJsonFilePath()
|
||||||
{
|
{
|
||||||
return FilePath::fromString(ICore::settings()->fileName()).parentDir()
|
return FilePath::fromString(ICore::settings()->fileName()).parentDir()
|
||||||
@@ -549,8 +574,22 @@ public:
|
|||||||
{
|
{
|
||||||
m_projectName.setLabelText(Tr::tr("Project name:"));
|
m_projectName.setLabelText(Tr::tr("Project name:"));
|
||||||
m_projectName.setDisplayStyle(StringAspect::LineEditDisplay);
|
m_projectName.setDisplayStyle(StringAspect::LineEditDisplay);
|
||||||
|
m_projectName.setValidationFunction([](FancyLineEdit *edit, QString *error) {
|
||||||
|
QTC_ASSERT(edit, return false);
|
||||||
|
if (!edit->text().isEmpty())
|
||||||
|
return true;
|
||||||
|
if (error)
|
||||||
|
*error = QString("Project name must be non-empty.");
|
||||||
|
return false;
|
||||||
|
});
|
||||||
m_analysisPath.setLabelText(Tr::tr("Analysis path:"));
|
m_analysisPath.setLabelText(Tr::tr("Analysis path:"));
|
||||||
m_analysisPath.setDisplayStyle(StringAspect::LineEditDisplay);
|
m_analysisPath.setDisplayStyle(StringAspect::LineEditDisplay);
|
||||||
|
m_analysisPath.setValidationFunction([](FancyLineEdit *edit, QString *error) {
|
||||||
|
QTC_ASSERT(edit, return false);
|
||||||
|
// do NOT use fromUserInput() as this also cleans the path
|
||||||
|
const FilePath fp = FilePath::fromString(edit->text().replace('\\', '/'));
|
||||||
|
return analysisPathValid(fp, error);
|
||||||
|
});
|
||||||
m_localPath.setLabelText(Tr::tr("Local path:"));
|
m_localPath.setLabelText(Tr::tr("Local path:"));
|
||||||
m_localPath.setExpectedKind(PathChooser::ExistingDirectory);
|
m_localPath.setExpectedKind(PathChooser::ExistingDirectory);
|
||||||
m_localPath.setAllowPathFromDevice(false);
|
m_localPath.setAllowPathFromDevice(false);
|
||||||
|
@@ -43,7 +43,7 @@ public:
|
|||||||
bool operator==(const PathMapping &other) const;
|
bool operator==(const PathMapping &other) const;
|
||||||
bool operator!=(const PathMapping &other) const;
|
bool operator!=(const PathMapping &other) const;
|
||||||
|
|
||||||
bool isValid() const {return !projectName.isEmpty() && !localPath.isEmpty(); }
|
bool isValid() const;
|
||||||
QString projectName;
|
QString projectName;
|
||||||
Utils::FilePath analysisPath;
|
Utils::FilePath analysisPath;
|
||||||
Utils::FilePath localPath;
|
Utils::FilePath localPath;
|
||||||
|
@@ -10,10 +10,12 @@
|
|||||||
#include <utils/layoutbuilder.h>
|
#include <utils/layoutbuilder.h>
|
||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
|
|
||||||
|
#include <QGuiApplication>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QScreen>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
|
|
||||||
namespace Axivion::Internal {
|
namespace Axivion::Internal {
|
||||||
@@ -37,6 +39,22 @@ static QString infoText()
|
|||||||
"\"\" matches issues having an empty value in this column\n"
|
"\"\" matches issues having an empty value in this column\n"
|
||||||
"!\"\" matches issues having any non-empty value in this column");
|
"!\"\" matches issues having any non-empty value in this column");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fixGlobalPosOnScreen(QPoint *globalPos, const QSize &size)
|
||||||
|
{
|
||||||
|
QScreen *qscreen = QGuiApplication::screenAt(*globalPos);
|
||||||
|
if (!qscreen)
|
||||||
|
qscreen = QGuiApplication::primaryScreen();
|
||||||
|
const QRect screen = qscreen->availableGeometry();
|
||||||
|
|
||||||
|
if (globalPos->x() + size.width() > screen.width())
|
||||||
|
globalPos->setX(screen.width() - size.width());
|
||||||
|
if (globalPos->y() + size.height() > screen.height())
|
||||||
|
globalPos->setY(screen.height() - size.height());
|
||||||
|
if (globalPos->y() < 0)
|
||||||
|
globalPos->setY(0);
|
||||||
|
}
|
||||||
|
|
||||||
class FilterPopupWidget : public QFrame
|
class FilterPopupWidget : public QFrame
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -262,8 +280,10 @@ void IssueHeaderView::mouseReleaseEvent(QMouseEvent *event)
|
|||||||
popup->setOnApply(onApply);
|
popup->setOnApply(onApply);
|
||||||
const int right = sectionViewportPosition(logical) + sectionSize(logical);
|
const int right = sectionViewportPosition(logical) + sectionSize(logical);
|
||||||
const QSize size = popup->sizeHint();
|
const QSize size = popup->sizeHint();
|
||||||
popup->move(mapToGlobal(QPoint{x() + right - size.width(),
|
QPoint globalPos = mapToGlobal(QPoint{std::max(0, x() + right - size.width()),
|
||||||
this->y() - size.height()}));
|
this->y() - size.height()});
|
||||||
|
fixGlobalPosOnScreen(&globalPos, size);
|
||||||
|
popup->move(globalPos);
|
||||||
popup->show();
|
popup->show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -41,7 +41,10 @@ clang::format::FormatStyle calculateQtcStyle()
|
|||||||
style.Language = FormatStyle::LK_Cpp;
|
style.Language = FormatStyle::LK_Cpp;
|
||||||
style.AccessModifierOffset = -4;
|
style.AccessModifierOffset = -4;
|
||||||
style.AlignAfterOpenBracket = FormatStyle::BAS_Align;
|
style.AlignAfterOpenBracket = FormatStyle::BAS_Align;
|
||||||
#if LLVM_VERSION_MAJOR >= 15
|
#if LLVM_VERSION_MAJOR >= 18
|
||||||
|
style.AlignConsecutiveAssignments = {false, false, false, false, false, false};
|
||||||
|
style.AlignConsecutiveDeclarations = {false, false, false, false, false, false};
|
||||||
|
#elif LLVM_VERSION_MAJOR >= 15
|
||||||
style.AlignConsecutiveAssignments = {false, false, false, false, false};
|
style.AlignConsecutiveAssignments = {false, false, false, false, false};
|
||||||
style.AlignConsecutiveDeclarations = {false, false, false, false, false};
|
style.AlignConsecutiveDeclarations = {false, false, false, false, false};
|
||||||
#else
|
#else
|
||||||
|
@@ -720,7 +720,9 @@ static void addCompileGroups(ProjectNode *targetRoot,
|
|||||||
targetRoot);
|
targetRoot);
|
||||||
if (showSourceFolders) {
|
if (showSourceFolders) {
|
||||||
FilePath baseDir = sourceDirectory.pathAppended(td.sourceGroups[i]);
|
FilePath baseDir = sourceDirectory.pathAppended(td.sourceGroups[i]);
|
||||||
if (!baseDir.exists())
|
const bool caseSensitiveMatch = baseDir.nativePath()
|
||||||
|
== baseDir.canonicalPath().nativePath();
|
||||||
|
if (!baseDir.exists() || !caseSensitiveMatch)
|
||||||
baseDir = sourceDirectory;
|
baseDir = sourceDirectory;
|
||||||
insertNode->addNestedNodes(std::move(current), baseDir);
|
insertNode->addNestedNodes(std::move(current), baseDir);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -484,9 +484,11 @@ static void drawPrimitiveTweakedForDarkTheme(QStyle::PrimitiveElement element,
|
|||||||
case QStyle::PE_FrameGroupBox: {
|
case QStyle::PE_FrameGroupBox: {
|
||||||
QRect groupBoxFrame = option->rect;
|
QRect groupBoxFrame = option->rect;
|
||||||
int topMargin = 0;
|
int topMargin = 0;
|
||||||
if (widget) {
|
if (auto control = dynamic_cast<const QGroupBox *>(widget)) {
|
||||||
|
const bool emptyTitle = !control->isCheckable() && control->title().isEmpty();
|
||||||
// Before Qt 6.6.3, QStyle::subControlRect() returned wrong QRect for SC_GroupBoxFrame
|
// Before Qt 6.6.3, QStyle::subControlRect() returned wrong QRect for SC_GroupBoxFrame
|
||||||
static const bool validSCRect = QLibraryInfo::version() >= QVersionNumber(6, 6, 3);
|
const bool validSCRect = QLibraryInfo::version() >= QVersionNumber(6, 6, 3)
|
||||||
|
&& !emptyTitle; // QTCREATORBUG-31960
|
||||||
if (validSCRect) {
|
if (validSCRect) {
|
||||||
QStyleOptionGroupBox opt;
|
QStyleOptionGroupBox opt;
|
||||||
opt.initFrom(widget);
|
opt.initFrom(widget);
|
||||||
@@ -497,8 +499,7 @@ static void drawPrimitiveTweakedForDarkTheme(QStyle::PrimitiveElement element,
|
|||||||
} else {
|
} else {
|
||||||
// Snippet from pre-6.6.3 FusionStyle::drawPrimitive - BEGIN
|
// Snippet from pre-6.6.3 FusionStyle::drawPrimitive - BEGIN
|
||||||
static const int groupBoxTopMargin = 3;
|
static const int groupBoxTopMargin = 3;
|
||||||
auto control = dynamic_cast<const QGroupBox *>(widget);
|
if (emptyTitle) {
|
||||||
if (!control->isCheckable() && control->title().isEmpty()) {
|
|
||||||
// Shrinking the topMargin if Not checkable AND title is empty
|
// Shrinking the topMargin if Not checkable AND title is empty
|
||||||
topMargin = groupBoxTopMargin;
|
topMargin = groupBoxTopMargin;
|
||||||
} else {
|
} else {
|
||||||
@@ -630,8 +631,10 @@ void ManhattanStyle::drawPrimitiveForPanelWidget(PrimitiveElement element,
|
|||||||
if (!enabled)
|
if (!enabled)
|
||||||
painter->setOpacity(0.75);
|
painter->setOpacity(0.75);
|
||||||
QBrush baseBrush = option->palette.base();
|
QBrush baseBrush = option->palette.base();
|
||||||
if (widget && qobject_cast<const QSpinBox *>(widget->parentWidget()))
|
if (widget && qobject_cast<const QSpinBox *>(widget->parentWidget())
|
||||||
|
&& StyleHelper::isQDSTheme()) {
|
||||||
baseBrush = creatorColor(Theme::DScontrolBackgroundDisabled);
|
baseBrush = creatorColor(Theme::DScontrolBackgroundDisabled);
|
||||||
|
}
|
||||||
painter->fillRect(backgroundRect, baseBrush);
|
painter->fillRect(backgroundRect, baseBrush);
|
||||||
painter->restore();
|
painter->restore();
|
||||||
} else {
|
} else {
|
||||||
|
@@ -84,7 +84,7 @@ PluginDialog::PluginDialog()
|
|||||||
connect(m_view, &ExtensionSystem::PluginView::pluginsChanged,
|
connect(m_view, &ExtensionSystem::PluginView::pluginsChanged,
|
||||||
this, [this](const QSet<PluginSpec *> &plugins, bool enable) {
|
this, [this](const QSet<PluginSpec *> &plugins, bool enable) {
|
||||||
for (PluginSpec *plugin : plugins) {
|
for (PluginSpec *plugin : plugins) {
|
||||||
if (enable && plugin->isSoftLoadable()) {
|
if (enable && plugin->isEffectivelySoftloadable()) {
|
||||||
m_softLoad.insert(plugin);
|
m_softLoad.insert(plugin);
|
||||||
} else {
|
} else {
|
||||||
m_softLoad.remove(plugin); // In case it was added, harmless otherwise.
|
m_softLoad.remove(plugin); // In case it was added, harmless otherwise.
|
||||||
|
@@ -207,7 +207,7 @@ void SecretAspect::addToLayoutImpl(Layouting::Layout &parent)
|
|||||||
d->wasEdited = true;
|
d->wasEdited = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
addLabeledItem(parent, Layouting::Row{edit, warningLabel, showPasswordButton}.emerge());
|
addLabeledItem(parent, Layouting::Row{Layouting::noMargin, edit, warningLabel, showPasswordButton}.emerge());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SecretAspect::requestValue(
|
void SecretAspect::requestValue(
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include <QGroupBox>
|
#include <QGroupBox>
|
||||||
#include <QGuiApplication>
|
#include <QGuiApplication>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QMessageBox>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QRadioButton>
|
#include <QRadioButton>
|
||||||
@@ -402,6 +403,11 @@ void StartApplicationDialog::run(bool attachRemote)
|
|||||||
}
|
}
|
||||||
|
|
||||||
IDevice::ConstPtr dev = RunDeviceKitAspect::device(k);
|
IDevice::ConstPtr dev = RunDeviceKitAspect::device(k);
|
||||||
|
if (!dev) {
|
||||||
|
QMessageBox::critical(
|
||||||
|
&dialog, Tr::tr("Cannot debug"), Tr::tr("Cannot debug application: Kit has no device"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
ProcessRunData inferior = newParameters.runnable;
|
ProcessRunData inferior = newParameters.runnable;
|
||||||
const QString inputAddress = dialog.d->channelOverrideEdit->text();
|
const QString inputAddress = dialog.d->channelOverrideEdit->text();
|
||||||
if (!inputAddress.isEmpty())
|
if (!inputAddress.isEmpty())
|
||||||
@@ -419,7 +425,7 @@ void StartApplicationDialog::run(bool attachRemote)
|
|||||||
if (!newParameters.sysRoot.isEmpty())
|
if (!newParameters.sysRoot.isEmpty())
|
||||||
debugger->setSysRoot(newParameters.sysRoot);
|
debugger->setSysRoot(newParameters.sysRoot);
|
||||||
|
|
||||||
bool isLocal = !dev || (dev->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE);
|
bool isLocal = dev->type() == ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE;
|
||||||
if (isLocal) // FIXME: Restriction needed?
|
if (isLocal) // FIXME: Restriction needed?
|
||||||
debugger->setInferiorEnvironment(k->runEnvironment());
|
debugger->setInferiorEnvironment(k->runEnvironment());
|
||||||
|
|
||||||
|
@@ -279,6 +279,8 @@ public:
|
|||||||
|
|
||||||
QString m_container;
|
QString m_container;
|
||||||
|
|
||||||
|
std::unique_ptr<Process> m_startProcess;
|
||||||
|
|
||||||
std::optional<Environment> m_cachedEnviroment;
|
std::optional<Environment> m_cachedEnviroment;
|
||||||
bool m_isShutdown = false;
|
bool m_isShutdown = false;
|
||||||
SynchronizedValue<std::unique_ptr<DeviceFileAccess>> m_fileAccess;
|
SynchronizedValue<std::unique_ptr<DeviceFileAccess>> m_fileAccess;
|
||||||
@@ -771,13 +773,11 @@ void DockerDevicePrivate::stopCurrentContainer()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process proc;
|
if (m_startProcess && m_startProcess->isRunning())
|
||||||
proc.setCommand({settings().dockerBinaryPath(), {"container", "kill", m_container}});
|
m_startProcess->kill(); // Kill instead of stop so we don't wait for the process to finish.
|
||||||
|
|
||||||
m_container.clear();
|
m_container.clear();
|
||||||
|
|
||||||
proc.runBlocking();
|
|
||||||
|
|
||||||
m_cachedEnviroment.reset();
|
m_cachedEnviroment.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -972,18 +972,45 @@ expected_str<QString> DockerDevicePrivate::createContainer()
|
|||||||
|
|
||||||
expected_str<void> DockerDevicePrivate::startContainer()
|
expected_str<void> DockerDevicePrivate::startContainer()
|
||||||
{
|
{
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
auto createResult = createContainer();
|
auto createResult = createContainer();
|
||||||
if (!createResult)
|
if (!createResult)
|
||||||
return make_unexpected(createResult.error());
|
return make_unexpected(createResult.error());
|
||||||
|
|
||||||
Process startProcess;
|
if (m_startProcess)
|
||||||
startProcess.setCommand({settings().dockerBinaryPath(), {"container", "start", m_container}});
|
m_startProcess->stop();
|
||||||
startProcess.runBlocking();
|
|
||||||
if (startProcess.result() != ProcessResult::FinishedWithSuccess) {
|
m_startProcess = std::make_unique<Process>();
|
||||||
return make_unexpected(Tr::tr("Failed starting Docker container. Exit code: %1, output: %2")
|
|
||||||
.arg(startProcess.exitCode())
|
m_startProcess->setCommand(
|
||||||
.arg(startProcess.allOutput()));
|
{settings().dockerBinaryPath(), {"container", "start", "-a", "-i", m_container}});
|
||||||
|
m_startProcess->setProcessMode(ProcessMode::Writer);
|
||||||
|
m_startProcess->start();
|
||||||
|
if (!m_startProcess->waitForStarted(5s)) {
|
||||||
|
if (m_startProcess->state() == QProcess::NotRunning) {
|
||||||
|
return make_unexpected(
|
||||||
|
Tr::tr("Failed starting Docker container. Exit code: %1, output: %2")
|
||||||
|
.arg(m_startProcess->exitCode())
|
||||||
|
.arg(m_startProcess->allOutput()));
|
||||||
|
}
|
||||||
|
// Lets assume it will start soon
|
||||||
|
qCWarning(dockerDeviceLog)
|
||||||
|
<< "Docker container start process took more than 5 seconds to start.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QDeadlineTimer deadline(5s);
|
||||||
|
while (!DockerApi::instance()->isContainerRunning(m_container) && !deadline.hasExpired()) {
|
||||||
|
QThread::msleep(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deadline.hasExpired() && !DockerApi::instance()->isContainerRunning(m_container)) {
|
||||||
|
m_startProcess->stop();
|
||||||
|
return make_unexpected(Tr::tr("Failed to start container: %1").arg(m_container));
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(dockerDeviceLog) << "Started container: " << m_startProcess->commandLine();
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -389,7 +389,6 @@ private:
|
|||||||
QStackedWidget *m_detailsStack;
|
QStackedWidget *m_detailsStack;
|
||||||
CollapsingWidget *m_secondaryDescriptionWidget;
|
CollapsingWidget *m_secondaryDescriptionWidget;
|
||||||
HeadingWidget *m_headingWidget;
|
HeadingWidget *m_headingWidget;
|
||||||
QWidget *m_primaryContent;
|
|
||||||
QWidget *m_secondaryContent;
|
QWidget *m_secondaryContent;
|
||||||
MarkdownBrowser *m_description;
|
MarkdownBrowser *m_description;
|
||||||
QLabel *m_dateUpdatedTitle;
|
QLabel *m_dateUpdatedTitle;
|
||||||
@@ -457,17 +456,8 @@ ExtensionManagerWidget::ExtensionManagerWidget()
|
|||||||
QPalette browserPal = m_description->palette();
|
QPalette browserPal = m_description->palette();
|
||||||
browserPal.setColor(QPalette::Base, creatorColor(Theme::Token_Background_Default));
|
browserPal.setColor(QPalette::Base, creatorColor(Theme::Token_Background_Default));
|
||||||
m_description->setPalette(browserPal);
|
m_description->setPalette(browserPal);
|
||||||
|
const int verticalPadding = SpacingTokens::ExVPaddingGapXl - SpacingTokens::VPaddingM;
|
||||||
using namespace Layouting;
|
m_description->setMargins({verticalPadding, 0, verticalPadding, 0});
|
||||||
auto primary = new QWidget;
|
|
||||||
const auto spL = spacing(SpacingTokens::VPaddingL);
|
|
||||||
// clang-format off
|
|
||||||
Column {
|
|
||||||
m_description,
|
|
||||||
noMargin, spacing(SpacingTokens::ExVPaddingGapXl),
|
|
||||||
}.attachTo(primary);
|
|
||||||
// clang-format on
|
|
||||||
m_primaryContent = toScrollableColumn(primary);
|
|
||||||
|
|
||||||
m_dateUpdatedTitle = sectionTitle(h6TF, Tr::tr("Last Update"));
|
m_dateUpdatedTitle = sectionTitle(h6TF, Tr::tr("Last Update"));
|
||||||
m_dateUpdated = tfLabel(contentTF, false);
|
m_dateUpdated = tfLabel(contentTF, false);
|
||||||
@@ -482,7 +472,11 @@ ExtensionManagerWidget::ExtensionManagerWidget()
|
|||||||
m_pluginStatus = new PluginStatusWidget;
|
m_pluginStatus = new PluginStatusWidget;
|
||||||
|
|
||||||
auto secondary = new QWidget;
|
auto secondary = new QWidget;
|
||||||
|
|
||||||
|
using namespace Layouting;
|
||||||
|
const auto spL = spacing(SpacingTokens::VPaddingL);
|
||||||
const auto spXxs = spacing(SpacingTokens::VPaddingXxs);
|
const auto spXxs = spacing(SpacingTokens::VPaddingXxs);
|
||||||
|
// clang-format off
|
||||||
Column {
|
Column {
|
||||||
sectionTitle(h6CapitalTF, Tr::tr("Extension details")),
|
sectionTitle(h6CapitalTF, Tr::tr("Extension details")),
|
||||||
Column {
|
Column {
|
||||||
@@ -515,7 +509,7 @@ ExtensionManagerWidget::ExtensionManagerWidget()
|
|||||||
customMargins(SpacingTokens::ExVPaddingGapXl, SpacingTokens::ExVPaddingGapXl,
|
customMargins(SpacingTokens::ExVPaddingGapXl, SpacingTokens::ExVPaddingGapXl,
|
||||||
SpacingTokens::ExVPaddingGapXl, SpacingTokens::ExVPaddingGapXl),
|
SpacingTokens::ExVPaddingGapXl, SpacingTokens::ExVPaddingGapXl),
|
||||||
},
|
},
|
||||||
m_primaryContent,
|
m_description,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
m_secondaryDescriptionWidget,
|
m_secondaryDescriptionWidget,
|
||||||
@@ -536,6 +530,7 @@ ExtensionManagerWidget::ExtensionManagerWidget()
|
|||||||
},
|
},
|
||||||
noMargin, spacing(0),
|
noMargin, spacing(0),
|
||||||
}.attachTo(this);
|
}.attachTo(this);
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
WelcomePageHelpers::setBackgroundColor(this, Theme::Token_Background_Default);
|
WelcomePageHelpers::setBackgroundColor(this, Theme::Token_Background_Default);
|
||||||
|
|
||||||
@@ -580,6 +575,7 @@ void ExtensionManagerWidget::updateView(const QModelIndex ¤t)
|
|||||||
{
|
{
|
||||||
const QString description = current.data(RoleDescriptionLong).toString();
|
const QString description = current.data(RoleDescriptionLong).toString();
|
||||||
m_description->setMarkdown(description);
|
m_description->setMarkdown(description);
|
||||||
|
m_description->document()->setDocumentMargin(SpacingTokens::VPaddingM);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@@ -986,17 +986,21 @@ void GitPluginPrivate::logFile()
|
|||||||
*/
|
*/
|
||||||
QStringList GitPluginPrivate::lineRange(int &firstLine, bool allowSingleLine) const
|
QStringList GitPluginPrivate::lineRange(int &firstLine, bool allowSingleLine) const
|
||||||
{
|
{
|
||||||
|
auto buildLineRange = [](int firstLine, int lastLine = -1) {
|
||||||
|
int stop = (lastLine == -1) ? firstLine : lastLine;
|
||||||
|
return QStringList{"-L " + QString::number(firstLine) + ',' + QString::number(stop)};
|
||||||
|
};
|
||||||
|
|
||||||
if (BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor()) {
|
if (BaseTextEditor *textEditor = BaseTextEditor::currentTextEditor()) {
|
||||||
QTextCursor cursor = textEditor->textCursor();
|
QTextCursor cursor = textEditor->textCursor();
|
||||||
if (cursor.hasSelection()) {
|
if (cursor.hasSelection()) {
|
||||||
QString argument = "-L ";
|
|
||||||
int selectionStart = cursor.selectionStart();
|
int selectionStart = cursor.selectionStart();
|
||||||
int selectionEnd = cursor.selectionEnd();
|
int selectionEnd = cursor.selectionEnd();
|
||||||
cursor.setPosition(selectionStart);
|
cursor.setPosition(selectionStart);
|
||||||
const int startBlock = cursor.blockNumber();
|
const int startBlock = cursor.blockNumber();
|
||||||
cursor.setPosition(selectionEnd);
|
cursor.setPosition(selectionEnd);
|
||||||
int endBlock = cursor.blockNumber();
|
int endBlock = cursor.blockNumber();
|
||||||
if (startBlock != endBlock) {
|
if (startBlock != endBlock || allowSingleLine) {
|
||||||
firstLine = startBlock + 1;
|
firstLine = startBlock + 1;
|
||||||
if (cursor.atBlockStart())
|
if (cursor.atBlockStart())
|
||||||
--endBlock;
|
--endBlock;
|
||||||
@@ -1005,13 +1009,18 @@ QStringList GitPluginPrivate::lineRange(int &firstLine, bool allowSingleLine) co
|
|||||||
if (previousFirstLine > 0)
|
if (previousFirstLine > 0)
|
||||||
firstLine = previousFirstLine;
|
firstLine = previousFirstLine;
|
||||||
}
|
}
|
||||||
argument += QString::number(firstLine) + ',';
|
return buildLineRange(firstLine, firstLine + endBlock - startBlock);
|
||||||
argument += QString::number(endBlock + firstLine - startBlock);
|
} else if (startBlock == endBlock) {
|
||||||
return {argument};
|
QTextCursor lineCursor = textEditor->textCursor();
|
||||||
|
lineCursor.movePosition(QTextCursor::StartOfLine);
|
||||||
|
const bool startsAtLineStart = (lineCursor.position() == selectionStart);
|
||||||
|
lineCursor.movePosition(QTextCursor::EndOfLine);
|
||||||
|
const bool endsAtLineEnd = (lineCursor.position() == selectionEnd);
|
||||||
|
if (startsAtLineStart && endsAtLineEnd)
|
||||||
|
return buildLineRange(lineCursor.blockNumber() + 1);
|
||||||
}
|
}
|
||||||
} else if (allowSingleLine) {
|
} else if (allowSingleLine) {
|
||||||
firstLine = cursor.blockNumber() + 1;
|
return buildLineRange(cursor.blockNumber() + 1);
|
||||||
return {"-L " + QString::number(firstLine) + ',' + QString::number(firstLine)};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
@@ -1829,6 +1829,7 @@ LanguageClientValue<MessageActionItem> ClientPrivate::showMessageBox(
|
|||||||
const ShowMessageRequestParams &message)
|
const ShowMessageRequestParams &message)
|
||||||
{
|
{
|
||||||
QMessageBox box;
|
QMessageBox box;
|
||||||
|
box.setWindowTitle(q->name());
|
||||||
box.setText(message.toString());
|
box.setText(message.toString());
|
||||||
switch (message.type()) {
|
switch (message.type()) {
|
||||||
case Error:
|
case Error:
|
||||||
|
@@ -43,7 +43,11 @@ QString LanguageClientCompletionItem::text() const
|
|||||||
{ return m_item.label(); }
|
{ return m_item.label(); }
|
||||||
|
|
||||||
bool LanguageClientCompletionItem::implicitlyApplies() const
|
bool LanguageClientCompletionItem::implicitlyApplies() const
|
||||||
{ return false; }
|
{
|
||||||
|
// only implicitly apply this item if there is no textEdit otherwise the user has to confirm
|
||||||
|
// the completion
|
||||||
|
return !m_item.textEdit();
|
||||||
|
}
|
||||||
|
|
||||||
bool LanguageClientCompletionItem::prematurelyApplies(const QChar &typedCharacter) const
|
bool LanguageClientCompletionItem::prematurelyApplies(const QChar &typedCharacter) const
|
||||||
{
|
{
|
||||||
|
@@ -166,6 +166,7 @@ void LspCapabilitiesWidget::setCapabilities(const Capabilities &serverCapabiliti
|
|||||||
{
|
{
|
||||||
m_capabilitiesView->setModel(
|
m_capabilitiesView->setModel(
|
||||||
createJsonModel(Tr::tr("Server Capabilities"), QJsonObject(serverCapabilities.capabilities)));
|
createJsonModel(Tr::tr("Server Capabilities"), QJsonObject(serverCapabilities.capabilities)));
|
||||||
|
|
||||||
m_dynamicCapabilities = serverCapabilities.dynamicCapabilities;
|
m_dynamicCapabilities = serverCapabilities.dynamicCapabilities;
|
||||||
const QStringList &methods = m_dynamicCapabilities.registeredMethods();
|
const QStringList &methods = m_dynamicCapabilities.registeredMethods();
|
||||||
if (methods.isEmpty()) {
|
if (methods.isEmpty()) {
|
||||||
@@ -502,7 +503,7 @@ LspInspectorWidget::LspInspectorWidget(LspInspector *inspector)
|
|||||||
TabWidget {
|
TabWidget {
|
||||||
bindTo(&m_tabWidget),
|
bindTo(&m_tabWidget),
|
||||||
Tab(Tr::tr("Log"), Column { m_logWidget }),
|
Tab(Tr::tr("Log"), Column { m_logWidget }),
|
||||||
Tab(Tr::tr("Capabilities"), Column {new LspCapabilitiesWidget}),
|
Tab(Tr::tr("Capabilities"), Column { m_capWidget }),
|
||||||
},
|
},
|
||||||
buttonBox,
|
buttonBox,
|
||||||
}.attachTo(this);
|
}.attachTo(this);
|
||||||
|
@@ -490,6 +490,7 @@ public:
|
|||||||
m_initializationOptions = options.as<QString>();
|
m_initializationOptions = options.as<QString>();
|
||||||
|
|
||||||
emit optionsChanged();
|
emit optionsChanged();
|
||||||
|
LanguageClientManager::applySettings();
|
||||||
m_isUpdatingAsyncOptions = false;
|
m_isUpdatingAsyncOptions = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -703,7 +704,7 @@ static void registerLuaApi()
|
|||||||
"sendMessageWithIdForDocument_cb",
|
"sendMessageWithIdForDocument_cb",
|
||||||
&LuaClientWrapper::sendMessageWithIdForDocument_cb,
|
&LuaClientWrapper::sendMessageWithIdForDocument_cb,
|
||||||
"create",
|
"create",
|
||||||
[](const sol::table &options) -> std::shared_ptr<LuaClientWrapper> {
|
[](const sol::main_table &options) -> std::shared_ptr<LuaClientWrapper> {
|
||||||
auto luaClientWrapper = std::make_shared<LuaClientWrapper>(options);
|
auto luaClientWrapper = std::make_shared<LuaClientWrapper>(options);
|
||||||
auto clientSettings = new LuaClientSettings(luaClientWrapper);
|
auto clientSettings = new LuaClientSettings(luaClientWrapper);
|
||||||
|
|
||||||
|
@@ -111,10 +111,24 @@ CREATE_HAS_FUNC(setTextInteractionFlags, Qt::TextInteractionFlags())
|
|||||||
CREATE_HAS_FUNC(setFixedSize, QSize())
|
CREATE_HAS_FUNC(setFixedSize, QSize())
|
||||||
CREATE_HAS_FUNC(setVisible, bool())
|
CREATE_HAS_FUNC(setVisible, bool())
|
||||||
CREATE_HAS_FUNC(setIcon, Utils::Icon());
|
CREATE_HAS_FUNC(setIcon, Utils::Icon());
|
||||||
|
CREATE_HAS_FUNC(setContentsMargins, int(), int(), int(), int());
|
||||||
|
CREATE_HAS_FUNC(setCursor, Qt::CursorShape())
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void setProperties(std::unique_ptr<T> &item, const sol::table &children, QObject *guard)
|
void setProperties(std::unique_ptr<T> &item, const sol::table &children, QObject *guard)
|
||||||
{
|
{
|
||||||
|
if constexpr (has_setContentsMargins<T>) {
|
||||||
|
sol::optional<QMargins> margins = children.get<sol::optional<QMargins>>("contentMargins");
|
||||||
|
if (margins)
|
||||||
|
item->setContentsMargins(margins->left(), margins->top(), margins->right(), margins->bottom());
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (has_setCursor<T>) {
|
||||||
|
const auto cursor = children.get<sol::optional<Qt::CursorShape>>("cursor");
|
||||||
|
if (cursor)
|
||||||
|
item->setCursor(*cursor);
|
||||||
|
}
|
||||||
|
|
||||||
if constexpr (has_setVisible<T>) {
|
if constexpr (has_setVisible<T>) {
|
||||||
const auto visible = children.get<sol::optional<bool>>("visible");
|
const auto visible = children.get<sol::optional<bool>>("visible");
|
||||||
if (visible)
|
if (visible)
|
||||||
@@ -243,8 +257,8 @@ void setProperties(std::unique_ptr<T> &item, const sol::table &children, QObject
|
|||||||
}
|
}
|
||||||
|
|
||||||
if constexpr (has_onTextChanged<T>) {
|
if constexpr (has_onTextChanged<T>) {
|
||||||
sol::optional<sol::protected_function> onTextChanged
|
sol::optional<sol::main_function> onTextChanged
|
||||||
= children.get<sol::optional<sol::protected_function>>("onTextChanged");
|
= children.get<sol::optional<sol::main_function>>("onTextChanged");
|
||||||
if (onTextChanged) {
|
if (onTextChanged) {
|
||||||
item->onTextChanged(
|
item->onTextChanged(
|
||||||
[f = *onTextChanged](const QString &text) {
|
[f = *onTextChanged](const QString &text) {
|
||||||
@@ -255,8 +269,8 @@ void setProperties(std::unique_ptr<T> &item, const sol::table &children, QObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if constexpr (has_onClicked<T>) {
|
if constexpr (has_onClicked<T>) {
|
||||||
sol::optional<sol::protected_function> onClicked
|
sol::optional<sol::main_function> onClicked
|
||||||
= children.get<sol::optional<sol::protected_function>>("onClicked");
|
= children.get<sol::optional<sol::main_function>>("onClicked");
|
||||||
if (onClicked) {
|
if (onClicked) {
|
||||||
item->onClicked(
|
item->onClicked(
|
||||||
[f = *onClicked]() {
|
[f = *onClicked]() {
|
||||||
@@ -525,6 +539,10 @@ void setupGuiModule()
|
|||||||
sol::property(&Widget::isVisible, &Widget::setVisible),
|
sol::property(&Widget::isVisible, &Widget::setVisible),
|
||||||
"enabled",
|
"enabled",
|
||||||
sol::property(&Widget::isEnabled, &Widget::setEnabled),
|
sol::property(&Widget::isEnabled, &Widget::setEnabled),
|
||||||
|
"focus",
|
||||||
|
sol::property([](Widget *self) { return self->emerge()->hasFocus(); }),
|
||||||
|
"setFocus",
|
||||||
|
[](Widget *self) { self->emerge()->setFocus(); },
|
||||||
sol::base_classes,
|
sol::base_classes,
|
||||||
sol::bases<Object, Thing>());
|
sol::bases<Object, Thing>());
|
||||||
|
|
||||||
@@ -532,6 +550,7 @@ void setupGuiModule()
|
|||||||
mirrorEnum(gui, QMetaEnum::fromType<Qt::WindowType>());
|
mirrorEnum(gui, QMetaEnum::fromType<Qt::WindowType>());
|
||||||
mirrorEnum(gui, QMetaEnum::fromType<Qt::TextFormat>());
|
mirrorEnum(gui, QMetaEnum::fromType<Qt::TextFormat>());
|
||||||
mirrorEnum(gui, QMetaEnum::fromType<Qt::TextInteractionFlag>());
|
mirrorEnum(gui, QMetaEnum::fromType<Qt::TextInteractionFlag>());
|
||||||
|
mirrorEnum(gui, QMetaEnum::fromType<Qt::CursorShape>());
|
||||||
|
|
||||||
gui.new_usertype<Stack>(
|
gui.new_usertype<Stack>(
|
||||||
"Stack",
|
"Stack",
|
||||||
|
@@ -36,7 +36,7 @@ void setupQtModule()
|
|||||||
&QCompleter::completionMode,
|
&QCompleter::completionMode,
|
||||||
[](QCompleter *c, QCompleter::CompletionMode mode) { c->setCompletionMode(mode); }),
|
[](QCompleter *c, QCompleter::CompletionMode mode) { c->setCompletionMode(mode); }),
|
||||||
"onActivated",
|
"onActivated",
|
||||||
sol::property([guard = pluginSpec](QCompleter &obj, sol::function callback) {
|
sol::property([guard = pluginSpec](QCompleter &obj, sol::main_function callback) {
|
||||||
QObject::connect(
|
QObject::connect(
|
||||||
&obj,
|
&obj,
|
||||||
QOverload<const QString &>::of(&QCompleter::activated),
|
QOverload<const QString &>::of(&QCompleter::activated),
|
||||||
|
@@ -294,7 +294,7 @@ sol::usertype<T> addTypedAspect(sol::table &lua, const QString &name)
|
|||||||
return lua.new_usertype<T>(
|
return lua.new_usertype<T>(
|
||||||
name,
|
name,
|
||||||
"create",
|
"create",
|
||||||
[](const sol::table &options) {
|
[](const sol::main_table &options) {
|
||||||
return createAspectFromTable<T>(options, &typedAspectCreate<T>);
|
return createAspectFromTable<T>(options, &typedAspectCreate<T>);
|
||||||
},
|
},
|
||||||
sol::base_classes,
|
sol::base_classes,
|
||||||
@@ -355,7 +355,7 @@ void setupSettingsModule()
|
|||||||
settings.new_usertype<SecretAspect>(
|
settings.new_usertype<SecretAspect>(
|
||||||
"SecretAspect",
|
"SecretAspect",
|
||||||
"create",
|
"create",
|
||||||
[](const sol::table &options) {
|
[](const sol::main_table &options) {
|
||||||
return createAspectFromTable<SecretAspect>(
|
return createAspectFromTable<SecretAspect>(
|
||||||
options,
|
options,
|
||||||
[](SecretAspect *aspect, const std::string &key, const sol::object &value) {
|
[](SecretAspect *aspect, const std::string &key, const sol::object &value) {
|
||||||
@@ -392,7 +392,7 @@ void setupSettingsModule()
|
|||||||
settings.new_usertype<SelectionAspect>(
|
settings.new_usertype<SelectionAspect>(
|
||||||
"SelectionAspect",
|
"SelectionAspect",
|
||||||
"create",
|
"create",
|
||||||
[](const sol::table &options) {
|
[](const sol::main_table &options) {
|
||||||
return createAspectFromTable<SelectionAspect>(
|
return createAspectFromTable<SelectionAspect>(
|
||||||
options,
|
options,
|
||||||
[](SelectionAspect *aspect, const std::string &key, const sol::object &value) {
|
[](SelectionAspect *aspect, const std::string &key, const sol::object &value) {
|
||||||
@@ -473,7 +473,7 @@ void setupSettingsModule()
|
|||||||
settings.new_usertype<ToggleAspect>(
|
settings.new_usertype<ToggleAspect>(
|
||||||
"ToggleAspect",
|
"ToggleAspect",
|
||||||
"create",
|
"create",
|
||||||
[](const sol::table &options) {
|
[](const sol::main_table &options) {
|
||||||
return createAspectFromTable<ToggleAspect>(
|
return createAspectFromTable<ToggleAspect>(
|
||||||
options,
|
options,
|
||||||
[](ToggleAspect *aspect, const std::string &key, const sol::object &value) {
|
[](ToggleAspect *aspect, const std::string &key, const sol::object &value) {
|
||||||
@@ -521,7 +521,7 @@ void setupSettingsModule()
|
|||||||
settings.new_usertype<TriStateAspect>(
|
settings.new_usertype<TriStateAspect>(
|
||||||
"TriStateAspect",
|
"TriStateAspect",
|
||||||
"create",
|
"create",
|
||||||
[](const sol::table &options) {
|
[](const sol::main_table &options) {
|
||||||
return createAspectFromTable<TriStateAspect>(
|
return createAspectFromTable<TriStateAspect>(
|
||||||
options,
|
options,
|
||||||
[](TriStateAspect *aspect, const std::string &key, const sol::object &value) {
|
[](TriStateAspect *aspect, const std::string &key, const sol::object &value) {
|
||||||
@@ -553,7 +553,7 @@ void setupSettingsModule()
|
|||||||
settings.new_usertype<TextDisplay>(
|
settings.new_usertype<TextDisplay>(
|
||||||
"TextDisplay",
|
"TextDisplay",
|
||||||
"create",
|
"create",
|
||||||
[](const sol::table &options) {
|
[](const sol::main_table &options) {
|
||||||
return createAspectFromTable<TextDisplay>(
|
return createAspectFromTable<TextDisplay>(
|
||||||
options,
|
options,
|
||||||
[](TextDisplay *aspect, const std::string &key, const sol::object &value) {
|
[](TextDisplay *aspect, const std::string &key, const sol::object &value) {
|
||||||
@@ -587,7 +587,7 @@ void setupSettingsModule()
|
|||||||
settings.new_usertype<AspectList>(
|
settings.new_usertype<AspectList>(
|
||||||
"AspectList",
|
"AspectList",
|
||||||
"create",
|
"create",
|
||||||
[](const sol::table &options) {
|
[](const sol::main_table &options) {
|
||||||
return createAspectFromTable<AspectList>(
|
return createAspectFromTable<AspectList>(
|
||||||
options,
|
options,
|
||||||
[](AspectList *aspect, const std::string &key, const sol::object &value) {
|
[](AspectList *aspect, const std::string &key, const sol::object &value) {
|
||||||
@@ -682,7 +682,7 @@ void setupSettingsModule()
|
|||||||
settings.new_usertype<OptionsPage>(
|
settings.new_usertype<OptionsPage>(
|
||||||
"OptionsPage",
|
"OptionsPage",
|
||||||
"create",
|
"create",
|
||||||
[&pool, pluginSpec](const sol::table &options) {
|
[&pool, pluginSpec](const sol::main_table &options) {
|
||||||
return pool.makePage<OptionsPage>(pluginSpec, options);
|
return pool.makePage<OptionsPage>(pluginSpec, options);
|
||||||
},
|
},
|
||||||
"show",
|
"show",
|
||||||
|
@@ -4,8 +4,11 @@
|
|||||||
#include "../luaengine.h"
|
#include "../luaengine.h"
|
||||||
#include "../luatr.h"
|
#include "../luatr.h"
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
#include <texteditor/basehoverhandler.h>
|
#include <texteditor/basehoverhandler.h>
|
||||||
#include <texteditor/fontsettings.h>
|
#include <texteditor/fontsettings.h>
|
||||||
|
#include <texteditor/refactoroverlay.h>
|
||||||
#include <texteditor/textdocument.h>
|
#include <texteditor/textdocument.h>
|
||||||
#include <texteditor/textdocumentlayout.h>
|
#include <texteditor/textdocumentlayout.h>
|
||||||
#include <texteditor/texteditor.h>
|
#include <texteditor/texteditor.h>
|
||||||
@@ -47,14 +50,61 @@ TextEditor::TextEditorWidget *getSuggestionReadyEditorWidget(TextEditor::TextDoc
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<EmbeddedWidgetInterface> addEmbeddedWidget(
|
std::unique_ptr<EmbeddedWidgetInterface> addEmbeddedWidget(
|
||||||
BaseTextEditor *editor, QWidget *widget, int cursorPosition)
|
BaseTextEditor *editor, QWidget *widget, std::variant<int, Position> cursorPosition)
|
||||||
{
|
{
|
||||||
|
if (!editor->textDocument() || !editor->textDocument()->document())
|
||||||
|
throw sol::error("No text document set");
|
||||||
|
|
||||||
widget->setParent(editor->editorWidget()->viewport());
|
widget->setParent(editor->editorWidget()->viewport());
|
||||||
TextEditorWidget *editorWidget = editor->editorWidget();
|
TextEditorWidget *editorWidget = editor->editorWidget();
|
||||||
std::unique_ptr<EmbeddedWidgetInterface> embed
|
|
||||||
= editorWidget->insertWidget(widget, cursorPosition);
|
int pos = cursorPosition.index() == 0
|
||||||
|
? std::get<int>(cursorPosition)
|
||||||
|
: std::get<Position>(cursorPosition)
|
||||||
|
.positionInDocument(editor->textDocument()->document());
|
||||||
|
|
||||||
|
std::unique_ptr<EmbeddedWidgetInterface> embed = editorWidget->insertWidget(widget, pos);
|
||||||
return embed;
|
return embed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clearRefactorMarkers(BaseTextEditor *editor, const Utils::Id &id)
|
||||||
|
{
|
||||||
|
TextEditorWidget *editorWidget = editor->editorWidget();
|
||||||
|
QTC_ASSERT(editorWidget, throw sol::error("TextEditorWidget is not valid"));
|
||||||
|
|
||||||
|
editorWidget->clearRefactorMarkers(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setRefactorMarker(
|
||||||
|
BaseTextEditor *editor,
|
||||||
|
const Utils::Icon &icon,
|
||||||
|
int position,
|
||||||
|
const Utils::Id &id,
|
||||||
|
bool anchorLeft,
|
||||||
|
sol::main_function callback)
|
||||||
|
{
|
||||||
|
TextEditorWidget *editorWidget = editor->editorWidget();
|
||||||
|
QTC_ASSERT(editorWidget, throw sol::error("TextEditorWidget is not valid"));
|
||||||
|
|
||||||
|
TextDocument *textDocument = editor->textDocument();
|
||||||
|
QTextCursor cursor = QTextCursor(textDocument->document());
|
||||||
|
cursor.setPosition(position);
|
||||||
|
|
||||||
|
// Move cursor to start of line
|
||||||
|
if (anchorLeft)
|
||||||
|
cursor.movePosition(QTextCursor::MoveOperation::StartOfBlock);
|
||||||
|
|
||||||
|
TextEditor::RefactorMarker marker;
|
||||||
|
marker.cursor = cursor;
|
||||||
|
marker.icon = icon.icon();
|
||||||
|
marker.callback = [callback](TextEditorWidget *) {
|
||||||
|
expected_str<void> res = Lua::void_safe_call(callback);
|
||||||
|
QTC_CHECK_EXPECTED(res);
|
||||||
|
};
|
||||||
|
marker.type = id;
|
||||||
|
|
||||||
|
editorWidget->setRefactorMarkers({std::move(marker)}, id);
|
||||||
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace Lua::Internal {
|
namespace Lua::Internal {
|
||||||
@@ -148,6 +198,9 @@ void setupTextEditorModule()
|
|||||||
TextEditorRegistry::instance();
|
TextEditorRegistry::instance();
|
||||||
|
|
||||||
registerProvider("TextEditor", [](sol::state_view lua) -> sol::object {
|
registerProvider("TextEditor", [](sol::state_view lua) -> sol::object {
|
||||||
|
const ScriptPluginSpec *pluginSpec = lua.get<ScriptPluginSpec *>("PluginSpec");
|
||||||
|
QObject *guard = pluginSpec->connectionGuard.get();
|
||||||
|
|
||||||
sol::table result = lua.create_table();
|
sol::table result = lua.create_table();
|
||||||
|
|
||||||
result["currentEditor"] = []() -> TextEditorPtr {
|
result["currentEditor"] = []() -> TextEditorPtr {
|
||||||
@@ -168,18 +221,18 @@ void setupTextEditorModule()
|
|||||||
"Position",
|
"Position",
|
||||||
sol::no_constructor,
|
sol::no_constructor,
|
||||||
"line",
|
"line",
|
||||||
sol::property([](Position &pos) { return pos.line; }),
|
sol::property(&Position::line, &Position::line),
|
||||||
"column",
|
"column",
|
||||||
sol::property([](Position &pos) { return pos.column; }));
|
sol::property(&Position::column, &Position::column));
|
||||||
|
|
||||||
// In range can't use begin/end as "end" is a reserved word for LUA scripts
|
// In range can't use begin/end as "end" is a reserved word for LUA scripts
|
||||||
result.new_usertype<Range>(
|
result.new_usertype<Range>(
|
||||||
"Range",
|
"Range",
|
||||||
sol::no_constructor,
|
sol::no_constructor,
|
||||||
"from",
|
"from",
|
||||||
sol::property([](Range &range) { return range.begin; }),
|
sol::property(&Range::begin, &Range::begin),
|
||||||
"to",
|
"to",
|
||||||
sol::property([](Range &range) { return range.end; }));
|
sol::property(&Range::end, &Range::end));
|
||||||
|
|
||||||
result.new_usertype<QTextCursor>(
|
result.new_usertype<QTextCursor>(
|
||||||
"TextCursor",
|
"TextCursor",
|
||||||
@@ -246,7 +299,26 @@ void setupTextEditorModule()
|
|||||||
"resize",
|
"resize",
|
||||||
&EmbeddedWidgetInterface::resize,
|
&EmbeddedWidgetInterface::resize,
|
||||||
"close",
|
"close",
|
||||||
&EmbeddedWidgetInterface::close);
|
&EmbeddedWidgetInterface::close,
|
||||||
|
"onShouldClose",
|
||||||
|
[guard](EmbeddedWidgetInterface *widget, sol::main_function func) {
|
||||||
|
QObject::connect(widget, &EmbeddedWidgetInterface::shouldClose, guard, [func]() {
|
||||||
|
expected_str<void> res = void_safe_call(func);
|
||||||
|
QTC_CHECK_EXPECTED(res);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
std::shared_ptr<QMap<TextEditorPtr, QSet<Utils::Id>>> activeMarkers
|
||||||
|
= std::make_shared<QMap<TextEditorPtr, QSet<Utils::Id>>>();
|
||||||
|
|
||||||
|
QObject::connect(guard, &QObject::destroyed, [activeMarkers] {
|
||||||
|
for (const auto &[k, v] : activeMarkers->asKeyValueRange()) {
|
||||||
|
if (k) {
|
||||||
|
for (const auto &id : v)
|
||||||
|
k->editorWidget()->clearRefactorMarkers(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
result.new_usertype<BaseTextEditor>(
|
result.new_usertype<BaseTextEditor>(
|
||||||
"TextEditor",
|
"TextEditor",
|
||||||
@@ -257,10 +329,39 @@ void setupTextEditorModule()
|
|||||||
return textEditor->textDocument();
|
return textEditor->textDocument();
|
||||||
},
|
},
|
||||||
"addEmbeddedWidget",
|
"addEmbeddedWidget",
|
||||||
[](const TextEditorPtr &textEditor, LayoutOrWidget widget, int position) {
|
[](const TextEditorPtr &textEditor,
|
||||||
|
LayoutOrWidget widget,
|
||||||
|
std::variant<int, Position> position) {
|
||||||
QTC_ASSERT(textEditor, throw sol::error("TextEditor is not valid"));
|
QTC_ASSERT(textEditor, throw sol::error("TextEditor is not valid"));
|
||||||
return addEmbeddedWidget(textEditor, toWidget(widget), position);
|
return addEmbeddedWidget(textEditor, toWidget(widget), position);
|
||||||
},
|
},
|
||||||
|
"setRefactorMarker",
|
||||||
|
[pluginSpec, activeMarkers](
|
||||||
|
const TextEditorPtr &textEditor,
|
||||||
|
const IconFilePathOrString &icon,
|
||||||
|
int position,
|
||||||
|
const QString &id,
|
||||||
|
bool anchorLeft,
|
||||||
|
sol::main_function callback) {
|
||||||
|
QTC_ASSERT(textEditor, throw sol::error("TextEditor is not valid"));
|
||||||
|
QTC_ASSERT(!id.isEmpty(), throw sol::error("Id is empty"));
|
||||||
|
QTC_ASSERT(!icon.valueless_by_exception(), throw sol::error("Icon is invalid"));
|
||||||
|
|
||||||
|
Id finalId = Utils::Id::fromString(QString(pluginSpec->id + "." + id));
|
||||||
|
(*activeMarkers)[textEditor].insert(finalId);
|
||||||
|
|
||||||
|
setRefactorMarker(textEditor, *toIcon(icon), position, finalId, anchorLeft, callback);
|
||||||
|
},
|
||||||
|
"clearRefactorMarkers",
|
||||||
|
[pluginSpec, activeMarkers](const TextEditorPtr &textEditor, const QString &id) {
|
||||||
|
QTC_ASSERT(textEditor, throw sol::error("TextEditor is not valid"));
|
||||||
|
QTC_ASSERT(!id.isEmpty(), throw sol::error("Id is empty"));
|
||||||
|
|
||||||
|
Id finalId = Utils::Id::fromString(QString(pluginSpec->id + "." + id));
|
||||||
|
(*activeMarkers)[textEditor].remove(finalId);
|
||||||
|
|
||||||
|
clearRefactorMarkers(textEditor, finalId);
|
||||||
|
},
|
||||||
"cursor",
|
"cursor",
|
||||||
[](const TextEditorPtr &textEditor) {
|
[](const TextEditorPtr &textEditor) {
|
||||||
QTC_ASSERT(textEditor, throw sol::error("TextEditor is not valid"));
|
QTC_ASSERT(textEditor, throw sol::error("TextEditor is not valid"));
|
||||||
|
@@ -251,7 +251,7 @@ void setupUtilsModule()
|
|||||||
utils.new_usertype<QTimer>(
|
utils.new_usertype<QTimer>(
|
||||||
"Timer",
|
"Timer",
|
||||||
"create",
|
"create",
|
||||||
[guard = pluginSpec](int timeout, bool singleShort, sol::function callback)
|
[guard = pluginSpec](int timeout, bool singleShort, sol::main_function callback)
|
||||||
-> std::unique_ptr<QTimer> {
|
-> std::unique_ptr<QTimer> {
|
||||||
auto timer = std::make_unique<QTimer>();
|
auto timer = std::make_unique<QTimer>();
|
||||||
timer->setInterval(timeout);
|
timer->setInterval(timeout);
|
||||||
|
@@ -1,7 +1,9 @@
|
|||||||
---@meta Action
|
---@meta Action
|
||||||
|
|
||||||
local action = {}
|
local action = {}
|
||||||
|
|
||||||
|
---@module 'Utils'
|
||||||
|
local Utils
|
||||||
|
|
||||||
---@enum CommandAttributes
|
---@enum CommandAttributes
|
||||||
action.CommandAttribute = {
|
action.CommandAttribute = {
|
||||||
---Hide the command from the menu.
|
---Hide the command from the menu.
|
||||||
@@ -17,7 +19,7 @@ action.CommandAttribute = {
|
|||||||
---@class ActionOptions
|
---@class ActionOptions
|
||||||
---@field context? string The context in which the action is available.
|
---@field context? string The context in which the action is available.
|
||||||
---@field text? string The text to display for the action.
|
---@field text? string The text to display for the action.
|
||||||
---@field icon? FilePath|string The icon to display for the action.
|
---@field icon? Utils.Icon|FilePath|string The icon to display for the action.
|
||||||
---@field iconText? string The icon text to display for the action.
|
---@field iconText? string The icon text to display for the action.
|
||||||
---@field toolTip? string The toolTip to display for the action.
|
---@field toolTip? string The toolTip to display for the action.
|
||||||
---@field onTrigger? function The callback to call when the action is triggered.
|
---@field onTrigger? function The callback to call when the action is triggered.
|
||||||
|
@@ -38,6 +38,8 @@ gui.baseWidgetOptions = {}
|
|||||||
---@field flat? boolean A boolean, representing whether the widget should be flat, if applicable.
|
---@field flat? boolean A boolean, representing whether the widget should be flat, if applicable.
|
||||||
---@field [1]? Layout The layout of the widget, if applicable.
|
---@field [1]? Layout The layout of the widget, if applicable.
|
||||||
---@field fixedSize? integer[] Two integers representing the width and height
|
---@field fixedSize? integer[] Two integers representing the width and height
|
||||||
|
---@field contentMargins? integer[] Four integers represending left, top, right and bottom margins.
|
||||||
|
---@field cursor? CursorShape The cursor shape for the widget.
|
||||||
gui.widgetOptions = {}
|
gui.widgetOptions = {}
|
||||||
|
|
||||||
---@param options WidgetOptions
|
---@param options WidgetOptions
|
||||||
@@ -430,6 +432,37 @@ gui.WidgetAttribute = {
|
|||||||
WA_ContentsMarginsRespectsSafeArea = 0,
|
WA_ContentsMarginsRespectsSafeArea = 0,
|
||||||
WA_StyleSheetTarget = 0
|
WA_StyleSheetTarget = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
--- Enum representing cursor shape for the widget
|
||||||
|
---@enum CursorShape
|
||||||
|
gui.CursorShape = {
|
||||||
|
ArrowCursor = 0 = 0,
|
||||||
|
UpArrowCursor = 0,
|
||||||
|
CrossCursor = 0,
|
||||||
|
WaitCursor = 0,
|
||||||
|
IBeamCursor = 0,
|
||||||
|
SizeVerCursor = 0,
|
||||||
|
SizeHorCursor = 0,
|
||||||
|
SizeBDiagCursor = 0,
|
||||||
|
SizeFDiagCursor = 0,
|
||||||
|
SizeAllCursor = 0,
|
||||||
|
BlankCursor = 0,
|
||||||
|
SplitVCursor = 0,
|
||||||
|
SplitHCursor = 0,
|
||||||
|
PointingHandCursor = 0,
|
||||||
|
ForbiddenCursor = 0,
|
||||||
|
WhatsThisCursor = 0,
|
||||||
|
BusyCursor = 0,
|
||||||
|
OpenHandCursor = 0,
|
||||||
|
ClosedHandCursor = 0,
|
||||||
|
DragCopyCursor = 0,
|
||||||
|
DragMoveCursor = 0,
|
||||||
|
DragLinkCursor = 0,
|
||||||
|
LastCursor = DragLinkCursor,
|
||||||
|
BitmapCursor = 0,
|
||||||
|
CustomCursor = 0
|
||||||
|
}
|
||||||
|
|
||||||
---@class Space : Layout
|
---@class Space : Layout
|
||||||
gui.space = {}
|
gui.space = {}
|
||||||
|
|
||||||
|
@@ -1,6 +1,10 @@
|
|||||||
---@meta TextEditor
|
---@meta TextEditor
|
||||||
local textEditor = {}
|
local textEditor = {}
|
||||||
|
|
||||||
|
---@module 'Utils'
|
||||||
|
local Utils
|
||||||
|
|
||||||
|
|
||||||
---@class Position
|
---@class Position
|
||||||
---@field line integer The line number.
|
---@field line integer The line number.
|
||||||
---@field column integer The column number.
|
---@field column integer The column number.
|
||||||
@@ -116,12 +120,28 @@ function EmbeddedWidget:close() end
|
|||||||
---Resizes the floating widget according to its layout.
|
---Resizes the floating widget according to its layout.
|
||||||
function EmbeddedWidget:resize() end
|
function EmbeddedWidget:resize() end
|
||||||
|
|
||||||
|
---Set the callback to be called when the widget should close. (E.g. if the user presses the escape key)
|
||||||
|
---@param fn function The function to be called when the embed should close.
|
||||||
|
function EmbeddedWidget:onShouldClose(fn) end
|
||||||
|
|
||||||
---Embeds a widget at the specified cursor position in the text editor.
|
---Embeds a widget at the specified cursor position in the text editor.
|
||||||
---@param widget Widget|Layout The widget to be added as a floating widget.
|
---@param widget Widget|Layout The widget to be added as a floating widget.
|
||||||
---@param position integer The position in the document where the widget should appear.
|
---@param position integer|Position The position in the document where the widget should appear.
|
||||||
---@return EmbeddedWidget interface An interface to control the floating widget.
|
---@return EmbeddedWidget interface An interface to control the floating widget.
|
||||||
function TextEditor:addEmbeddedWidget(widget, position) end
|
function TextEditor:addEmbeddedWidget(widget, position) end
|
||||||
|
|
||||||
|
---Adds an refactor marker in the text editor at given cursor position.
|
||||||
|
---@param icon Utils.Icon|FilePath|string Icon to be used. If specified icon is invalid the default QtCreator for markers is used.
|
||||||
|
---@param position integer The position in the document where the marker should appear.
|
||||||
|
---@param id string The identifier of the marker.
|
||||||
|
---@param anchorLeft boolean Specifies if the marker should appear at the beginning of the TextCursor block.
|
||||||
|
---@param callback function A function to be called once the marker is pressed.
|
||||||
|
function TextEditor:setRefactorMarker(icon, position, id, anchorLeft, callback) end
|
||||||
|
|
||||||
|
---Removes the refactor markers with given id.
|
||||||
|
---param id string The identifier of the marker.
|
||||||
|
function TextEditor:clearRefactorMarkers(icon, position, id, anchorLeft, callback) end
|
||||||
|
|
||||||
---Checks if the current suggestion is locked. The suggestion is locked when the user can use it.
|
---Checks if the current suggestion is locked. The suggestion is locked when the user can use it.
|
||||||
---@return boolean True if the suggestion is locked, false otherwise.
|
---@return boolean True if the suggestion is locked, false otherwise.
|
||||||
function TextEditor:hasLockedSuggestion() end
|
function TextEditor:hasLockedSuggestion() end
|
||||||
|
@@ -26,5 +26,18 @@
|
|||||||
],
|
],
|
||||||
"Url" : "https://www.mesonbuild.com",
|
"Url" : "https://www.mesonbuild.com",
|
||||||
"DocumentationUrl" : "https://doc.qt.io/qtcreator/creator-project-meson.html",
|
"DocumentationUrl" : "https://doc.qt.io/qtcreator/creator-project-meson.html",
|
||||||
${IDE_PLUGIN_DEPENDENCIES}
|
${IDE_PLUGIN_DEPENDENCIES},
|
||||||
|
|
||||||
|
"Mimetypes" : [
|
||||||
|
"<?xml version='1.0' encoding='UTF-8'?>",
|
||||||
|
"<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>",
|
||||||
|
" <mime-type type='text/x-meson'>",
|
||||||
|
" <sub-class-of type='text/plain'/>",
|
||||||
|
" <comment>Meson build description</comment>",
|
||||||
|
" <glob pattern='meson.build'/>",
|
||||||
|
" <glob pattern='meson.options'/>",
|
||||||
|
" <glob pattern='meson_options.txt'/>",
|
||||||
|
" </mime-type>",
|
||||||
|
"</mime-info>"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
@@ -198,8 +198,6 @@ void KitAspect::addToInnerLayout(Layouting::Layout &parentItem)
|
|||||||
void KitAspect::addListAspectSpec(const ListAspectSpec &listAspectSpec)
|
void KitAspect::addListAspectSpec(const ListAspectSpec &listAspectSpec)
|
||||||
{
|
{
|
||||||
const auto comboBox = createSubWidget<QComboBox>();
|
const auto comboBox = createSubWidget<QComboBox>();
|
||||||
comboBox->setSizePolicy(QSizePolicy::Preferred, comboBox->sizePolicy().verticalPolicy());
|
|
||||||
comboBox->setEnabled(true);
|
|
||||||
const auto sortModel = new KitAspectSortModel(this);
|
const auto sortModel = new KitAspectSortModel(this);
|
||||||
sortModel->setSourceModel(listAspectSpec.model);
|
sortModel->setSourceModel(listAspectSpec.model);
|
||||||
comboBox->setModel(sortModel);
|
comboBox->setModel(sortModel);
|
||||||
|
@@ -865,7 +865,10 @@ void MiniProjectTargetSelector::doLayout()
|
|||||||
|
|
||||||
m_kitAreaWidget->move(0, 0);
|
m_kitAreaWidget->move(0, 0);
|
||||||
|
|
||||||
int kitAreaHeight = m_kitAreaWidget->isVisibleTo(this) ? m_kitAreaWidget->sizeHint().height() : 0;
|
const int kitAreaHeight = m_kitAreaWidget->isVisibleTo(this)
|
||||||
|
? m_kitAreaWidget->sizeHint().height() : 0;
|
||||||
|
const int kitAreaWidth = m_kitAreaWidget->isVisibleTo(this)
|
||||||
|
? m_kitAreaWidget->sizeHint().width() : 0;
|
||||||
|
|
||||||
// 1. Calculate the summary label height
|
// 1. Calculate the summary label height
|
||||||
int summaryLabelY = 1 + kitAreaHeight;
|
int summaryLabelY = 1 + kitAreaHeight;
|
||||||
@@ -900,6 +903,7 @@ void MiniProjectTargetSelector::doLayout()
|
|||||||
|
|
||||||
QRect newGeometry;
|
QRect newGeometry;
|
||||||
|
|
||||||
|
const int minWidth = std::max({m_summaryLabel->sizeHint().width(), kitAreaWidth, 250});
|
||||||
if (!onlySummary) {
|
if (!onlySummary) {
|
||||||
// list widget height
|
// list widget height
|
||||||
int maxItemCount = m_projectListWidget->maxCount();
|
int maxItemCount = m_projectListWidget->maxCount();
|
||||||
@@ -920,8 +924,6 @@ void MiniProjectTargetSelector::doLayout()
|
|||||||
int listHeight = heightWithoutKitArea + kitAreaHeight - bottomMargin - listY + 1;
|
int listHeight = heightWithoutKitArea + kitAreaHeight - bottomMargin - listY + 1;
|
||||||
|
|
||||||
// list widget widths
|
// list widget widths
|
||||||
int minWidth = qMax(m_summaryLabel->sizeHint().width(), 250);
|
|
||||||
minWidth = qMax(minWidth, m_kitAreaWidget->sizeHint().width());
|
|
||||||
QVector<int> widths = listWidgetWidths(minWidth, Core::ICore::mainWindow()->width() * 0.9);
|
QVector<int> widths = listWidgetWidths(minWidth, Core::ICore::mainWindow()->width() * 0.9);
|
||||||
|
|
||||||
const int runColumnWidth = widths[RUN] == -1 ? 0 : RunColumnWidth;
|
const int runColumnWidth = widths[RUN] == -1 ? 0 : RunColumnWidth;
|
||||||
@@ -952,7 +954,7 @@ void MiniProjectTargetSelector::doLayout()
|
|||||||
heightWithoutKitArea = qMax(summaryLabelHeight + bottomMargin, alignedWithActionHeight);
|
heightWithoutKitArea = qMax(summaryLabelHeight + bottomMargin, alignedWithActionHeight);
|
||||||
m_summaryLabel->resize(m_summaryLabel->sizeHint().width(), heightWithoutKitArea - bottomMargin);
|
m_summaryLabel->resize(m_summaryLabel->sizeHint().width(), heightWithoutKitArea - bottomMargin);
|
||||||
m_kitAreaWidget->resize(m_kitAreaWidget->sizeHint());
|
m_kitAreaWidget->resize(m_kitAreaWidget->sizeHint());
|
||||||
newGeometry.setSize({m_summaryLabel->width() + 1, heightWithoutKitArea + kitAreaHeight});
|
newGeometry.setSize({minWidth + 1, heightWithoutKitArea + kitAreaHeight});
|
||||||
}
|
}
|
||||||
|
|
||||||
newGeometry.translate(statusBar->mapToGlobal(QPoint{0, 0}));
|
newGeometry.translate(statusBar->mapToGlobal(QPoint{0, 0}));
|
||||||
|
@@ -578,6 +578,7 @@ void ToolChainOptionsWidget::apply()
|
|||||||
removedTcs << Utils::transform(notRegistered, &Toolchain::displayName);
|
removedTcs << Utils::transform(notRegistered, &Toolchain::displayName);
|
||||||
}
|
}
|
||||||
for (ExtendedToolchainTreeItem * const item : std::as_const(m_toAddList)) {
|
for (ExtendedToolchainTreeItem * const item : std::as_const(m_toAddList)) {
|
||||||
|
m_model.takeItem(item);
|
||||||
item->bundle->deleteToolchains();
|
item->bundle->deleteToolchains();
|
||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
|
@@ -1373,17 +1373,23 @@ FilePath QtVersion::examplesPath() const // QT_INSTALL_EXAMPLES
|
|||||||
return d->data().examplesPath;
|
return d->data().examplesPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\internal
|
||||||
|
Returns a list of directories containing Qt related shared objects
|
||||||
|
*/
|
||||||
FilePaths QtVersion::qtSoPaths() const
|
FilePaths QtVersion::qtSoPaths() const
|
||||||
{
|
{
|
||||||
FilePaths paths;
|
FilePaths paths;
|
||||||
const FilePaths qtPaths = {libraryPath(), pluginPath(), qmlPath(), importsPath()};
|
const FilePath qtPaths[] = {libraryPath(), pluginPath(), qmlPath(), importsPath()};
|
||||||
for (const FilePath &qtPath : qtPaths) {
|
for (const FilePath &qtPath : qtPaths) {
|
||||||
if (qtPath.isEmpty())
|
if (qtPath.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// FIXME: Could be sped up, we need just the info whether there is one such entry
|
||||||
const FilePaths soPaths =
|
const FilePaths soPaths =
|
||||||
qtPath.dirEntries({{"*.so"}, QDir::Files, QDirIterator::Subdirectories});
|
qtPath.dirEntries({{"*.so"}, QDir::Files, QDirIterator::Subdirectories});
|
||||||
paths.append(soPaths);
|
for (const FilePath &soPath : soPaths)
|
||||||
|
paths.append(soPath.parentDir());
|
||||||
}
|
}
|
||||||
FilePath::removeDuplicates(paths);
|
FilePath::removeDuplicates(paths);
|
||||||
return paths;
|
return paths;
|
||||||
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 4.3 KiB |
@@ -750,6 +750,7 @@ public:
|
|||||||
qreal charWidth() const;
|
qreal charWidth() const;
|
||||||
|
|
||||||
std::unique_ptr<EmbeddedWidgetInterface> insertWidget(QWidget *widget, int line);
|
std::unique_ptr<EmbeddedWidgetInterface> insertWidget(QWidget *widget, int line);
|
||||||
|
void forceUpdateScrollbarSize();
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
void registerActions();
|
void registerActions();
|
||||||
@@ -947,6 +948,7 @@ public:
|
|||||||
void updateSuggestion();
|
void updateSuggestion();
|
||||||
void clearCurrentSuggestion();
|
void clearCurrentSuggestion();
|
||||||
QTextBlock m_suggestionBlock;
|
QTextBlock m_suggestionBlock;
|
||||||
|
int m_numEmbeddedWidgets = 0;
|
||||||
|
|
||||||
Context m_editorContext;
|
Context m_editorContext;
|
||||||
QAction *m_undoAction = nullptr;
|
QAction *m_undoAction = nullptr;
|
||||||
@@ -1839,6 +1841,7 @@ void TextEditorWidgetPrivate::insertSuggestion(std::unique_ptr<TextSuggestion> &
|
|||||||
auto options = suggestion->replacementDocument()->defaultTextOption();
|
auto options = suggestion->replacementDocument()->defaultTextOption();
|
||||||
m_suggestionBlock = cursor.block();
|
m_suggestionBlock = cursor.block();
|
||||||
m_document->insertSuggestion(std::move(suggestion));
|
m_document->insertSuggestion(std::move(suggestion));
|
||||||
|
forceUpdateScrollbarSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEditorWidgetPrivate::updateSuggestion()
|
void TextEditorWidgetPrivate::updateSuggestion()
|
||||||
@@ -3500,7 +3503,10 @@ bool TextEditorWidget::event(QEvent *e)
|
|||||||
if (ke->key() == Qt::Key_Escape
|
if (ke->key() == Qt::Key_Escape
|
||||||
&& (d->m_snippetOverlay->isVisible()
|
&& (d->m_snippetOverlay->isVisible()
|
||||||
|| multiTextCursor().hasMultipleCursors()
|
|| multiTextCursor().hasMultipleCursors()
|
||||||
|| d->m_suggestionBlock.isValid())) {
|
|| d->m_suggestionBlock.isValid()
|
||||||
|
|| d->m_numEmbeddedWidgets > 0)) {
|
||||||
|
if (d->m_numEmbeddedWidgets > 0)
|
||||||
|
emit embeddedWidgetsShouldClose();
|
||||||
e->accept();
|
e->accept();
|
||||||
} else {
|
} else {
|
||||||
// hack copied from QInputControl::isCommonTextEditShortcut
|
// hack copied from QInputControl::isCommonTextEditShortcut
|
||||||
@@ -3920,10 +3926,8 @@ qreal TextEditorWidgetPrivate::charWidth() const
|
|||||||
{
|
{
|
||||||
return QFontMetricsF(q->font()).horizontalAdvance(QLatin1Char('x'));
|
return QFontMetricsF(q->font()).horizontalAdvance(QLatin1Char('x'));
|
||||||
}
|
}
|
||||||
|
|
||||||
class CarrierWidget : public QWidget
|
class CarrierWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
|
||||||
public:
|
public:
|
||||||
CarrierWidget(TextEditorWidget *textEditorWidget, QWidget *embed)
|
CarrierWidget(TextEditorWidget *textEditorWidget, QWidget *embed)
|
||||||
: QWidget(textEditorWidget->viewport())
|
: QWidget(textEditorWidget->viewport())
|
||||||
@@ -3942,7 +3946,7 @@ public:
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
int embedHeight() { return m_embed->minimumSizeHint().height(); }
|
int embedHeight() { return m_embed->sizeHint().height(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QWidget *m_embed;
|
QWidget *m_embed;
|
||||||
@@ -3964,12 +3968,27 @@ void EmbeddedWidgetInterface::close()
|
|||||||
emit closed();
|
emit closed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TextEditorWidgetPrivate::forceUpdateScrollbarSize()
|
||||||
|
{
|
||||||
|
// We use resizeEvent here as a workaround as we can't get access to the
|
||||||
|
// scrollarea which is a private part of the QPlainTextEdit.
|
||||||
|
// During the resizeEvent the plain text edit will resize its scrollbars.
|
||||||
|
// The TextEditorWidget will also update its scrollbar overlays.
|
||||||
|
q->resizeEvent(new QResizeEvent(q->size(), q->size()));
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_ptr<EmbeddedWidgetInterface> TextEditorWidgetPrivate::insertWidget(
|
std::unique_ptr<EmbeddedWidgetInterface> TextEditorWidgetPrivate::insertWidget(
|
||||||
QWidget *widget, int line)
|
QWidget *widget, int line)
|
||||||
{
|
{
|
||||||
QPointer<CarrierWidget> carrier = new CarrierWidget(q, widget);
|
QPointer<CarrierWidget> carrier = new CarrierWidget(q, widget);
|
||||||
std::unique_ptr<EmbeddedWidgetInterface> result(new EmbeddedWidgetInterface());
|
std::unique_ptr<EmbeddedWidgetInterface> result(new EmbeddedWidgetInterface());
|
||||||
|
|
||||||
|
connect(
|
||||||
|
q,
|
||||||
|
&TextEditorWidget::embeddedWidgetsShouldClose,
|
||||||
|
result.get(),
|
||||||
|
&EmbeddedWidgetInterface::shouldClose);
|
||||||
|
|
||||||
struct State
|
struct State
|
||||||
{
|
{
|
||||||
int height = 0;
|
int height = 0;
|
||||||
@@ -4032,9 +4051,14 @@ std::unique_ptr<EmbeddedWidgetInterface> TextEditorWidgetPrivate::insertWidget(
|
|||||||
QTextBlock block = pState->cursor.block();
|
QTextBlock block = pState->cursor.block();
|
||||||
auto userData = TextDocumentLayout::userData(block);
|
auto userData = TextDocumentLayout::userData(block);
|
||||||
userData->removeEmbeddedWidget(carrier);
|
userData->removeEmbeddedWidget(carrier);
|
||||||
|
m_numEmbeddedWidgets--;
|
||||||
|
forceUpdateScrollbarSize();
|
||||||
});
|
});
|
||||||
connect(q->document()->documentLayout(), &QAbstractTextDocumentLayout::update, carrier, position);
|
connect(q->document()->documentLayout(), &QAbstractTextDocumentLayout::update, carrier, position);
|
||||||
connect(result.get(), &EmbeddedWidgetInterface::resized, carrier, position);
|
connect(result.get(), &EmbeddedWidgetInterface::resized, carrier, [position, this]() {
|
||||||
|
position();
|
||||||
|
forceUpdateScrollbarSize();
|
||||||
|
});
|
||||||
connect(result.get(), &EmbeddedWidgetInterface::closed, this, [this, carrier] {
|
connect(result.get(), &EmbeddedWidgetInterface::closed, this, [this, carrier] {
|
||||||
if (carrier)
|
if (carrier)
|
||||||
carrier->deleteLater();
|
carrier->deleteLater();
|
||||||
@@ -4042,7 +4066,11 @@ std::unique_ptr<EmbeddedWidgetInterface> TextEditorWidgetPrivate::insertWidget(
|
|||||||
QTimer::singleShot(0, layout, [layout] { layout->update(); });
|
QTimer::singleShot(0, layout, [layout] { layout->update(); });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_numEmbeddedWidgets++;
|
||||||
|
|
||||||
carrier->show();
|
carrier->show();
|
||||||
|
|
||||||
|
forceUpdateScrollbarSize();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7078,6 +7106,15 @@ void TextEditorWidget::mouseReleaseEvent(QMouseEvent *e)
|
|||||||
if (!HostOsInfo::isLinuxHost() && handleForwardBackwardMouseButtons(e))
|
if (!HostOsInfo::isLinuxHost() && handleForwardBackwardMouseButtons(e))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// If the refactor marker was pressed then don't propagate release event to editor
|
||||||
|
RefactorMarker refactorMarker = d->m_refactorOverlay->markerAt(e->pos());
|
||||||
|
if (refactorMarker.isValid()) {
|
||||||
|
if (refactorMarker.callback) {
|
||||||
|
e->accept();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QPlainTextEdit::mouseReleaseEvent(e);
|
QPlainTextEdit::mouseReleaseEvent(e);
|
||||||
|
|
||||||
d->setClipboardSelection();
|
d->setClipboardSelection();
|
||||||
|
@@ -113,6 +113,7 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void resized();
|
void resized();
|
||||||
void closed();
|
void closed();
|
||||||
|
void shouldClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
class TEXTEDITOR_EXPORT BaseTextEditor : public Core::IEditor
|
class TEXTEDITOR_EXPORT BaseTextEditor : public Core::IEditor
|
||||||
@@ -561,6 +562,7 @@ signals:
|
|||||||
void addCurrentStateToNavigationHistory();
|
void addCurrentStateToNavigationHistory();
|
||||||
|
|
||||||
void resized();
|
void resized();
|
||||||
|
void embeddedWidgetsShouldClose();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QTextBlock blockForVisibleRow(int row) const;
|
QTextBlock blockForVisibleRow(int row) const;
|
||||||
|
@@ -207,7 +207,7 @@ macro(qtc_auto_setup_vcpkg)
|
|||||||
option(QT_CREATOR_SKIP_VCPKG_SETUP "Skip Qt Creator's vcpkg package manager auto-setup" OFF)
|
option(QT_CREATOR_SKIP_VCPKG_SETUP "Skip Qt Creator's vcpkg package manager auto-setup" OFF)
|
||||||
|
|
||||||
find_program(vcpkg_program vcpkg
|
find_program(vcpkg_program vcpkg
|
||||||
PATHS $ENV{VCPKG_ROOT} ${CMAKE_SOURCE_DIR}/vcpkg
|
PATHS $ENV{VCPKG_ROOT} ${CMAKE_SOURCE_DIR}/vcpkg ${CMAKE_SOURCE_DIR}/3rdparty/vcpkg
|
||||||
NO_DEFAULT_PATH
|
NO_DEFAULT_PATH
|
||||||
)
|
)
|
||||||
if (NOT vcpkg_program)
|
if (NOT vcpkg_program)
|
||||||
@@ -247,7 +247,23 @@ macro(qtc_auto_setup_vcpkg)
|
|||||||
if (VCPKG_TARGET_TRIPLET)
|
if (VCPKG_TARGET_TRIPLET)
|
||||||
set(vcpkg_triplet ${VCPKG_TARGET_TRIPLET})
|
set(vcpkg_triplet ${VCPKG_TARGET_TRIPLET})
|
||||||
else()
|
else()
|
||||||
if (WIN32)
|
if (ANDROID_ABI)
|
||||||
|
if (ANDROID_ABI STREQUAL "armeabi-v7a")
|
||||||
|
set(vcpkg_triplet arm-neon-android)
|
||||||
|
elseif (ANDROID_ABI STREQUAL "arm64-v8a")
|
||||||
|
set(vcpkg_triplet arm64-android)
|
||||||
|
elseif (ANDROID_ABI STREQUAL "x86")
|
||||||
|
set(vcpkg_triplet x86-android)
|
||||||
|
elseif (ANDROID_ABI STREQUAL "x86_64")
|
||||||
|
set(vcpkg_triplet x64-android)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "Unsupported Android ABI: ${ANDROID_ABI}")
|
||||||
|
endif()
|
||||||
|
# Needed by vcpkg/scripts/toolchains/android.cmake
|
||||||
|
file(APPEND "${CMAKE_BINARY_DIR}/vcpkg-dependencies/toolchain.cmake" "
|
||||||
|
set(ENV{ANDROID_NDK_HOME} \"${ANDROID_NDK}\")
|
||||||
|
")
|
||||||
|
elseif (WIN32)
|
||||||
set(vcpkg_triplet x64-mingw-static)
|
set(vcpkg_triplet x64-mingw-static)
|
||||||
if (CMAKE_CXX_COMPILER MATCHES ".*/(.*)/cl.exe")
|
if (CMAKE_CXX_COMPILER MATCHES ".*/(.*)/cl.exe")
|
||||||
set(vcpkg_triplet ${CMAKE_MATCH_1}-windows)
|
set(vcpkg_triplet ${CMAKE_MATCH_1}-windows)
|
||||||
|
@@ -55,7 +55,7 @@ function(_get_msvc_ide_version result)
|
|||||||
set(${result} 15 PARENT_SCOPE)
|
set(${result} 15 PARENT_SCOPE)
|
||||||
elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930)
|
elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930)
|
||||||
set(${result} 16 PARENT_SCOPE)
|
set(${result} 16 PARENT_SCOPE)
|
||||||
elseif(NOT MSVC_VERSION VERSION_LESS 1930 AND MSVC_VERSION VERSION_LESS 1940)
|
elseif(NOT MSVC_VERSION VERSION_LESS 1930 AND MSVC_VERSION VERSION_LESS 1950)
|
||||||
set(${result} 17 PARENT_SCOPE)
|
set(${result} 17 PARENT_SCOPE)
|
||||||
else()
|
else()
|
||||||
message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]")
|
message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]")
|
||||||
|
@@ -9,6 +9,7 @@ qtc_add_public_header(qtcreator_pch.h)
|
|||||||
qtc_add_public_header(qtcreator_gui_pch.h)
|
qtc_add_public_header(qtcreator_gui_pch.h)
|
||||||
|
|
||||||
option(BUILD_QBS "Build Qbs together with Qt Creator" OFF)
|
option(BUILD_QBS "Build Qbs together with Qt Creator" OFF)
|
||||||
|
option(WITH_QBS_DOCS "Build Qbs documentation" ${WITH_DOCS})
|
||||||
|
|
||||||
add_feature_info("Build Qbs" BUILD_QBS "")
|
add_feature_info("Build Qbs" BUILD_QBS "")
|
||||||
if (BUILD_QBS)
|
if (BUILD_QBS)
|
||||||
@@ -30,6 +31,6 @@ if (BUILD_QBS)
|
|||||||
set(INSTALL_PUBLIC_HEADERS OFF CACHE BOOL "")
|
set(INSTALL_PUBLIC_HEADERS OFF CACHE BOOL "")
|
||||||
set(WITH_TESTS OFF)
|
set(WITH_TESTS OFF)
|
||||||
set(WITH_PROJECT_FILE_UPDATES ON CACHE BOOL "")
|
set(WITH_PROJECT_FILE_UPDATES ON CACHE BOOL "")
|
||||||
set(QBS_INSTALL_QCH_DOCS ${WITH_DOCS} CACHE BOOL "")
|
set(QBS_INSTALL_QCH_DOCS ${WITH_QBS_DOCS} CACHE BOOL "")
|
||||||
add_subdirectory(qbs)
|
add_subdirectory(qbs)
|
||||||
endif()
|
endif()
|
||||||
|
@@ -198,9 +198,10 @@ public:
|
|||||||
const auto end = system_clock::now();
|
const auto end = system_clock::now();
|
||||||
const auto freeze = duration_cast<milliseconds>(end - start);
|
const auto freeze = duration_cast<milliseconds>(end - start);
|
||||||
if (freeze > m_threshold) {
|
if (freeze > m_threshold) {
|
||||||
|
m_total += freeze;
|
||||||
const QString time = QTime::currentTime().toString(Qt::ISODateWithMs);
|
const QString time = QTime::currentTime().toString(Qt::ISODateWithMs);
|
||||||
qDebug().noquote() << QString("FREEZE [%1]").arg(time)
|
qDebug().noquote() << QString("FREEZE [%1]").arg(time) << "of" << freeze.count()
|
||||||
<< "of" << freeze.count() << "ms, on:" << event;
|
<< "ms, total" << m_total.count() << "ms, on:" << event;
|
||||||
const QString receiverMessage = name.isEmpty()
|
const QString receiverMessage = name.isEmpty()
|
||||||
? QString("receiver class: %1").arg(className)
|
? QString("receiver class: %1").arg(className)
|
||||||
: QString("receiver class: %1, object name: %2").arg(className, name);
|
: QString("receiver class: %1, object name: %2").arg(className, name);
|
||||||
@@ -215,6 +216,7 @@ private:
|
|||||||
bool m_inNotify = false;
|
bool m_inNotify = false;
|
||||||
const QString m_align;
|
const QString m_align;
|
||||||
milliseconds m_threshold{100};
|
milliseconds m_threshold{100};
|
||||||
|
milliseconds m_total{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
QtSingleApplication *createApplication(const QString &id, int &argc, char **argv)
|
QtSingleApplication *createApplication(const QString &id, int &argc, char **argv)
|
||||||
|
@@ -460,27 +460,6 @@
|
|||||||
effect="fill_between_many"
|
effect="fill_between_many"
|
||||||
linkedpaths="#path2259-2-0-6,0"
|
linkedpaths="#path2259-2-0-6,0"
|
||||||
id="path-effect2469-8" />
|
id="path-effect2469-8" />
|
||||||
<linearGradient
|
|
||||||
gradientUnits="userSpaceOnUse"
|
|
||||||
gradientTransform="matrix(75,0,0,-70,-74,7774.97)"
|
|
||||||
y2="111"
|
|
||||||
x2="1.45"
|
|
||||||
y1="109.58"
|
|
||||||
x1="2.76"
|
|
||||||
id="linear-gradient-7">
|
|
||||||
<stop
|
|
||||||
id="stop2568"
|
|
||||||
stop-color="#6ffe80"
|
|
||||||
offset="0" />
|
|
||||||
<stop
|
|
||||||
id="stop2570"
|
|
||||||
stop-color="#43ce58"
|
|
||||||
offset="0.37" />
|
|
||||||
<stop
|
|
||||||
id="stop2572"
|
|
||||||
stop-color="#425fcf"
|
|
||||||
offset="1" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
<linearGradient
|
||||||
inkscape:collect="always"
|
inkscape:collect="always"
|
||||||
xlink:href="#linearGradient2550"
|
xlink:href="#linearGradient2550"
|
||||||
@@ -738,17 +717,52 @@
|
|||||||
x="0"
|
x="0"
|
||||||
y="0"
|
y="0"
|
||||||
style="fill:#ffffff" />
|
style="fill:#ffffff" />
|
||||||
<path
|
<g
|
||||||
style="fill:url(#linear-gradient-7)"
|
id="g11668"
|
||||||
d="m 145.67,81.5 a 1.34,1.34 0 0 0 -1.34,1.33 v 0.44 l -16,6.59 V 87.5 l 17.85,-7.38 a 1.36,1.36 0 0 0 0.82,-1.24 1.34,1.34 0 0 0 -0.82,-1.23 l -38.67,-16 a 1.38,1.38 0 0 0 -1,0 l -38.67,16 a 1.34,1.34 0 0 0 -0.84,1.18 1.36,1.36 0 0 0 0.82,1.24 l 38.67,16 a 1.24,1.24 0 0 0 1,0 l 14,-5.78 a 1.33,1.33 0 0 0 -1,-2.46 L 107,93.39 71.82,78.83 107,64.28 l 35.18,14.55 -15.31,6.34 -14.66,-5.48 a 3,3 0 0 0 0.12,-0.86 c 0,-2.24 -2.34,-4 -5.33,-4 -2.99,0 -5.33,1.76 -5.33,4 0,2.24 2.34,4 5.33,4 a 6.41,6.41 0 0 0 3.45,-0.95 l 15.22,5.68 v 4.28 0 28.57 a 4,4 0 1 0 2.66,0 v -7.57 a 16.19,16.19 0 0 0 5.26,-6.9 1.32,1.32 0 0 0 0.08,-0.44 v -9.33 a 1.34,1.34 0 1 0 -2.67,0 v 9.08 a 13.49,13.49 0 0 1 -2.67,4 V 92.74 L 146.17,85.4 A 1.34,1.34 0 0 0 147,84.17 v -1.34 a 1.34,1.34 0 0 0 -1.33,-1.33 z m -41.34,-2.67 c 0,-0.54 1,-1.33 2.67,-1.33 1.67,0 2.67,0.79 2.67,1.33 0,0.54 -1,1.34 -2.67,1.34 -1.67,0 -2.67,-0.79 -2.67,-1.34 z M 127,125.5 a 1.34,1.34 0 1 1 1.33,-1.33 1.33,1.33 0 0 1 -1.33,1.33 z M 106.49,101.4 67.82,85.4 A 1.34,1.34 0 0 1 67,84.17 v -1.34 a 1.34,1.34 0 0 1 2.67,0 v 0.45 L 107,98.72 121.15,92.86 a 1.36,1.36 0 0 1 1.75,0.73 1.33,1.33 0 0 1 -0.72,1.74 l -14.67,6.07 a 1.35,1.35 0 0 1 -1,0 z m 15.77,15.54 A 34.28,34.28 0 0 1 107,120.17 c -20.67,0 -26.34,-13.6 -26.57,-14.17 a 1.44,1.44 0 0 1 -0.1,-0.5 v -9.33 a 1.34,1.34 0 1 1 2.67,0 v 9 c 0.77,1.67 6.11,11.7 22.67,12.23 v -11.9 a 1.33,1.33 0 0 1 2.66,0 v 12 a 31,31 0 0 0 12.75,-2.91 1.3327134,1.3327134 0 0 1 1.18,2.39 z m 6.07,13.89 v 4 a 1.33,1.33 0 1 1 -2.66,0 v -4 a 1.33,1.33 0 1 1 2.66,0 z m -4,-1 -1.33,5.33 a 1.33,1.33 0 0 1 -1.29,1 1.86,1.86 0 0 1 -0.33,0 1.34,1.34 0 0 1 -1,-1.62 l 1.34,-5.33 a 1.33,1.33 0 0 1 2.58,0.64 z m 9.34,4.69 a 1.34,1.34 0 0 1 -1,1.62 1.86,1.86 0 0 1 -0.33,0 1.33,1.33 0 0 1 -1.29,-1 l -1.33,-5.34 a 1.33,1.33 0 1 1 2.58,-0.64 l 1.34,5.33 z"
|
transform="translate(17,-13)">
|
||||||
class="cls-2"
|
<rect
|
||||||
id="graduation-hat"
|
style="fill:#2cde85;fill-opacity:0.6"
|
||||||
inkscape:connector-curvature="0" />
|
id="rect2143"
|
||||||
<path
|
width="47"
|
||||||
id="path2598"
|
height="53"
|
||||||
style="fill:#222840"
|
x="56"
|
||||||
d="M 133.5,41.74 V 29 h 2 v 12.74 z m -2.57,-6.22 v 4.1 a 0.86,0.86 0 0 0 0.2,0.58 1,1 0 0 0 0.59,0.25 v 1.49 a 3.81,3.81 0 0 1 -2.4,-0.66 6.91,6.91 0 0 1 -2.9,0.66 c -1.79,0 -2.68,-1 -2.68,-2.86 a 2.44,2.44 0 0 1 0.73,-2 4,4 0 0 1 2.24,-0.74 l 2.32,-0.2 V 35.5 a 1.33,1.33 0 0 0 -0.31,-1 1.35,1.35 0 0 0 -0.93,-0.29 c -0.77,0 -1.73,0 -2.88,0.14 h -0.57 L 124.21,33 a 15.72,15.72 0 0 1 3.61,-0.46 3.31,3.31 0 0 1 2.38,0.71 3.05,3.05 0 0 1 0.73,2.27 z m -4,2.23 a 1.21,1.21 0 0 0 -1.25,1.35 c 0,0.83 0.37,1.24 1.1,1.24 a 7,7 0 0 0 1.91,-0.29 l 0.32,-0.11 v -2.39 z m -7,-6.54 v -2.07 h 2 v 2.07 z m 0,10.53 v -9 h 2 v 9 z m -6.5,0 v -9 h 1.95 v 1.08 a 8.42,8.42 0 0 1 3.06,-1.27 v 2 a 12.5,12.5 0 0 0 -2.65,0.79 l -0.4,0.16 v 6.28 z m -9.04,-8.02 a 4.65,4.65 0 0 1 6.17,0 5.57,5.57 0 0 1 0.94,3.51 5.76,5.76 0 0 1 -0.9,3.52 4.67,4.67 0 0 1 -6.23,0 5.76,5.76 0 0 1 -0.9,-3.52 5.57,5.57 0 0 1 0.92,-3.51 z m 1.46,5.85 a 1.71,1.71 0 0 0 1.62,0.72 1.69,1.69 0 0 0 1.62,-0.72 4.93,4.93 0 0 0 0.41,-2.36 4.53,4.53 0 0 0 -0.44,-2.32 1.76,1.76 0 0 0 -1.56,-0.69 1.74,1.74 0 0 0 -1.59,0.69 4.53,4.53 0 0 0 -0.44,2.32 5.08,5.08 0 0 0 0.38,2.36 z m -3.56,-5.15 h -2.48 v 4 a 4.19,4.19 0 0 0 0.16,1.46 c 0.11,0.24 0.38,0.36 0.83,0.36 l 1.47,-0.06 0.09,1.57 a 10.91,10.91 0 0 1 -1.83,0.23 2.59,2.59 0 0 1 -2.1,-0.7 4.41,4.41 0 0 1 -0.57,-2.65 v -4.21 h -1.15 v -1.68 h 1.15 v -2.61 h 2 v 2.61 h 2.48 z m -9.16,-1.68 h 1.94 v 9 h -1.94 v -0.55 a 5,5 0 0 1 -2.43,0.75 2.72,2.72 0 0 1 -2.49,-1 7,7 0 0 1 -0.63,-3.5 v -4.7 h 2 v 4.72 a 5.78,5.78 0 0 0 0.27,2.18 c 0.18,0.37 0.6,0.56 1.26,0.56 a 4.36,4.36 0 0 0 1.78,-0.36 l 0.27,-0.11 z M 78.5,31.2 v -1.79 h 9 V 31.2 H 84 V 41.74 H 82 V 31.2 Z"
|
y="80"
|
||||||
inkscape:connector-curvature="0" />
|
ry="4" />
|
||||||
|
<rect
|
||||||
|
style="fill:#00414a"
|
||||||
|
id="rect3291"
|
||||||
|
width="47"
|
||||||
|
height="53"
|
||||||
|
x="66"
|
||||||
|
y="67"
|
||||||
|
ry="4" />
|
||||||
|
<g
|
||||||
|
id="g5219"
|
||||||
|
transform="translate(-22,-57)">
|
||||||
|
<use
|
||||||
|
x="0"
|
||||||
|
y="0"
|
||||||
|
xlink:href="#rect2143"
|
||||||
|
id="use5085"
|
||||||
|
transform="translate(42,31)" />
|
||||||
|
<path
|
||||||
|
id="path5274"
|
||||||
|
style="fill:none;stroke:#ffffff"
|
||||||
|
d="m 109,139.5 h 13 m -13,-6 h 28 m -28,-6 h 28 m -28,-6 h 28"
|
||||||
|
sodipodi:nodetypes="cccccccc" />
|
||||||
|
</g>
|
||||||
|
<path
|
||||||
|
id="Rectangle"
|
||||||
|
d="m -7.0710678,-175.43154 v -11.34132 c 0,-2.29705 -1.8489181,-4.14597 -4.1459662,-4.14597 h -1.607563 c -2.297048,0 -4.145966,1.84892 -4.145966,4.14597 v 11.34132 c 3.181981,-0.9916 7.7781748,-0.63805 9.8994952,0 z"
|
||||||
|
transform="rotate(135)"
|
||||||
|
sodipodi:nodetypes="csssscc" />
|
||||||
|
<circle
|
||||||
|
style="opacity:1;fill:none;stroke:#2cde85;stroke-width:10;stroke-opacity:0.9"
|
||||||
|
id="path27226"
|
||||||
|
cx="118.5"
|
||||||
|
cy="101.5"
|
||||||
|
r="15.5" />
|
||||||
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
<g
|
<g
|
||||||
|
Before Width: | Height: | Size: 378 KiB After Width: | Height: | Size: 376 KiB |
@@ -17,6 +17,8 @@ using namespace std::chrono_literals;
|
|||||||
using TaskObject = milliseconds;
|
using TaskObject = milliseconds;
|
||||||
using TestTask = TimeoutTask;
|
using TestTask = TimeoutTask;
|
||||||
|
|
||||||
|
constexpr milliseconds s_endlessTime = 1000000s;
|
||||||
|
|
||||||
namespace PrintableEnums {
|
namespace PrintableEnums {
|
||||||
|
|
||||||
Q_NAMESPACE
|
Q_NAMESPACE
|
||||||
@@ -347,17 +349,6 @@ void tst_Tasking::runtimeCheck()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Tick : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
Tick(const milliseconds &interval) { QTimer::singleShot(interval, this, &Tick::tick); }
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void tick();
|
|
||||||
};
|
|
||||||
|
|
||||||
class TickAndDone : public QObject
|
class TickAndDone : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -3171,7 +3162,7 @@ void tst_Tasking::testTree_data()
|
|||||||
// This test ensures the task done handlers are invoked in a different order
|
// This test ensures the task done handlers are invoked in a different order
|
||||||
// than the corresponding setup handlers.
|
// than the corresponding setup handlers.
|
||||||
|
|
||||||
const QList<milliseconds> tasks { 1000000ms, 0ms };
|
const QList<milliseconds> tasks { s_endlessTime, 0ms };
|
||||||
const LoopList iterator(tasks);
|
const LoopList iterator(tasks);
|
||||||
|
|
||||||
const auto onSetup = [storage, iterator](TaskObject &taskObject) {
|
const auto onSetup = [storage, iterator](TaskObject &taskObject) {
|
||||||
@@ -3790,25 +3781,28 @@ void tst_Tasking::testTree_data()
|
|||||||
{
|
{
|
||||||
// withCancel / withAccept
|
// withCancel / withAccept
|
||||||
|
|
||||||
const Storage<std::unique_ptr<Tick>> tickStorage;
|
const Storage<std::unique_ptr<QTimer>> tickStorage;
|
||||||
|
|
||||||
const auto onSetup = [tickStorage](milliseconds timeout) {
|
const auto onSetup = [tickStorage](milliseconds timeout) {
|
||||||
return [tickStorage, timeout] { tickStorage->reset(new Tick(timeout)); };
|
return [tickStorage, timeout] {
|
||||||
|
tickStorage->reset(new QTimer);
|
||||||
|
tickStorage->get()->start(timeout);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto onTickSetup = [tickStorage] {
|
const auto onTickSetup = [tickStorage] {
|
||||||
return std::make_pair(tickStorage->get(), &Tick::tick);
|
return std::make_pair(tickStorage->get(), &QTimer::timeout);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Group cancelRecipe {
|
const Group cancelRecipe {
|
||||||
storage,
|
storage,
|
||||||
tickStorage,
|
tickStorage,
|
||||||
onGroupSetup(onSetup(0ms)),
|
onGroupSetup(onSetup(0ms)), // 1st queued call
|
||||||
Group {
|
Group {
|
||||||
groupSetup(1),
|
groupSetup(1),
|
||||||
createSuccessTask(2, 1ms),
|
createSuccessTask(2, s_endlessTime),
|
||||||
groupDone(1)
|
groupDone(1)
|
||||||
}.withCancel(onTickSetup)
|
}.withCancel(onTickSetup) // 2nd queued call
|
||||||
};
|
};
|
||||||
|
|
||||||
const Log cancelLog {
|
const Log cancelLog {
|
||||||
|
@@ -126,6 +126,9 @@ private slots:
|
|||||||
|
|
||||||
void dontBreakPathOnWierdWindowsPaths();
|
void dontBreakPathOnWierdWindowsPaths();
|
||||||
|
|
||||||
|
void isRelativePath();
|
||||||
|
void isRelativePath_data();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTemporaryDir tempDir;
|
QTemporaryDir tempDir;
|
||||||
QString rootPath;
|
QString rootPath;
|
||||||
@@ -506,6 +509,10 @@ void tst_filepath::rootLength_data()
|
|||||||
QTest::newRow("unc-localhost-drive") << "//localhost/c$" << 12;
|
QTest::newRow("unc-localhost-drive") << "//localhost/c$" << 12;
|
||||||
QTest::newRow("unc-localhost-drive-slash") << "//localhost//c$/" << 12;
|
QTest::newRow("unc-localhost-drive-slash") << "//localhost//c$/" << 12;
|
||||||
QTest::newRow("unc-localhost-drive-slash-rest") << "//localhost//c$/x" << 12;
|
QTest::newRow("unc-localhost-drive-slash-rest") << "//localhost//c$/x" << 12;
|
||||||
|
|
||||||
|
QTest::newRow("windows-1") << "C:" << 2;
|
||||||
|
QTest::newRow("windows-2") << "C:/" << 3;
|
||||||
|
QTest::newRow("windows-3") << "C:/foor" << 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_filepath::rootLength()
|
void tst_filepath::rootLength()
|
||||||
@@ -1323,7 +1330,7 @@ void tst_filepath::startsWithDriveLetter_data()
|
|||||||
QTest::newRow("remote-slash") << FilePath::fromString("docker://1234/") << false;
|
QTest::newRow("remote-slash") << FilePath::fromString("docker://1234/") << false;
|
||||||
QTest::newRow("remote-single-letter") << FilePath::fromString("docker://1234/c") << false;
|
QTest::newRow("remote-single-letter") << FilePath::fromString("docker://1234/c") << false;
|
||||||
QTest::newRow("remote-drive") << FilePath::fromString("docker://1234/c:") << true;
|
QTest::newRow("remote-drive") << FilePath::fromString("docker://1234/c:") << true;
|
||||||
QTest::newRow("remote-invalid-drive") << FilePath::fromString("docker://1234/c:a") << true;
|
QTest::newRow("remote-invalid-drive") << FilePath::fromString("docker://1234/c:a") << false;
|
||||||
QTest::newRow("remote-with-path") << FilePath::fromString("docker://1234/c:/a") << true;
|
QTest::newRow("remote-with-path") << FilePath::fromString("docker://1234/c:/a") << true;
|
||||||
QTest::newRow("remote-z") << FilePath::fromString("docker://1234/z:") << true;
|
QTest::newRow("remote-z") << FilePath::fromString("docker://1234/z:") << true;
|
||||||
QTest::newRow("remote-1") << FilePath::fromString("docker://1234/1:") << false;
|
QTest::newRow("remote-1") << FilePath::fromString("docker://1234/1:") << false;
|
||||||
@@ -1810,15 +1817,66 @@ void tst_filepath::makeTemporaryFile()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_filepath::isRelativePath_data()
|
||||||
|
{
|
||||||
|
QTest::addColumn<QString>("path");
|
||||||
|
QTest::addColumn<bool>("expected");
|
||||||
|
|
||||||
|
QTest::newRow("empty") << "" << true;
|
||||||
|
QTest::newRow("root") << "/" << false;
|
||||||
|
QTest::newRow("relative") << "foo" << true;
|
||||||
|
QTest::newRow("relative-path") << "foo/bar" << true;
|
||||||
|
QTest::newRow("absolute") << "/foo" << false;
|
||||||
|
QTest::newRow("absolute-path") << "/foo/bar" << false;
|
||||||
|
QTest::newRow("remote") << "device://host/foo" << false;
|
||||||
|
QTest::newRow("remote-path") << "device://host/foo/bar" << false;
|
||||||
|
|
||||||
|
QTest::newRow("windows-current-dir") << "c:" << true;
|
||||||
|
QTest::newRow("windows-path") << "c:/" << false;
|
||||||
|
QTest::newRow("windows-path-with-dir") << "c:/foo" << false;
|
||||||
|
|
||||||
|
QTest::newRow("windows-remote-current-dir") << "device://host/C:" << true;
|
||||||
|
QTest::newRow("windows-remote-path") << "device://host/C:/" << false;
|
||||||
|
QTest::newRow("windows-remote-path-with-dir") << "device://host/C:/foo" << false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_filepath::isRelativePath()
|
||||||
|
{
|
||||||
|
QFETCH(QString, path);
|
||||||
|
QFETCH(bool, expected);
|
||||||
|
|
||||||
|
QCOMPARE(FilePath::fromUserInput(path).isRelativePath(), expected);
|
||||||
|
}
|
||||||
|
|
||||||
void tst_filepath::dontBreakPathOnWierdWindowsPaths()
|
void tst_filepath::dontBreakPathOnWierdWindowsPaths()
|
||||||
{
|
{
|
||||||
FilePath path = FilePath::fromString(
|
FilePath path = FilePath::fromString(
|
||||||
"device://host/./C:/Users/ckandeler/Documents/"
|
"device://host/./C:/Users/johndoe/Documents/"
|
||||||
"build-iartest-IAR-Debugx/Debug_IAR_55df6f02d5b3d06d/iartest.a152245e/iartest.out");
|
"build-iartest-IAR-Debugx/Debug_IAR_55df6f02d5b3d06d/iartest.a152245e/iartest.out");
|
||||||
QCOMPARE(
|
QCOMPARE(
|
||||||
path.toString(),
|
path.toString(),
|
||||||
"device://host/C:/Users/ckandeler/Documents/"
|
"device://host/C:/Users/johndoe/Documents/"
|
||||||
"build-iartest-IAR-Debugx/Debug_IAR_55df6f02d5b3d06d/iartest.a152245e/iartest.out");
|
"build-iartest-IAR-Debugx/Debug_IAR_55df6f02d5b3d06d/iartest.a152245e/iartest.out");
|
||||||
|
|
||||||
|
FilePath pathWithBackslash = FilePath::fromUserInput(
|
||||||
|
"device://host/C:\\Users\\johndoe\\Documents\\test.elf");
|
||||||
|
QCOMPARE(pathWithBackslash.toString(), "device://host/C:/Users/johndoe/Documents/test.elf");
|
||||||
|
QCOMPARE(pathWithBackslash.path(), "C:/Users/johndoe/Documents/test.elf");
|
||||||
|
|
||||||
|
const FilePath bin = FilePath::fromString(pathWithBackslash.path());
|
||||||
|
QCOMPARE(bin.toString(), "C:/Users/johndoe/Documents/test.elf");
|
||||||
|
|
||||||
|
// Make sure the optimization still works
|
||||||
|
FilePath path2 = FilePath::fromString("/./");
|
||||||
|
QCOMPARE(path2.toString(), "");
|
||||||
|
|
||||||
|
// Make sure unix paths are not affected
|
||||||
|
FilePath path3 = FilePath::fromString("/./foo/bar");
|
||||||
|
QCOMPARE(path3.toString(), "foo/bar");
|
||||||
|
|
||||||
|
// Make sure unix paths with device also work
|
||||||
|
FilePath path4 = FilePath::fromString("device://host/./foo/bar");
|
||||||
|
QCOMPARE(path4.toString(), "device://host/./foo/bar");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Utils
|
} // Utils
|
||||||
|
31
tests/manual/docker/linux/DockerFile-with-creator
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
ENV DEBIAN_FRONTEND=noninteractive
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y \
|
||||||
|
libgl1-mesa-dev \
|
||||||
|
qt6-base-dev \
|
||||||
|
qt6-base-private-dev \
|
||||||
|
qt6-declarative-dev \
|
||||||
|
qt6-declarative-private-dev \
|
||||||
|
libqt6core5compat6-dev \
|
||||||
|
build-essential \
|
||||||
|
clang-format clang-tidy clang-tools clang clangd libc++-dev libc++1 libc++abi-dev libc++abi1 libclang-dev libclang1 liblldb-dev libllvm-ocaml-dev libomp-dev libomp5 lld lldb llvm-dev llvm-runtime llvm python3-clang python3-lldb \
|
||||||
|
cmake \
|
||||||
|
nano \
|
||||||
|
ninja-build \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
gnupg \
|
||||||
|
lsb-release \
|
||||||
|
qtcreator \
|
||||||
|
gdb \
|
||||||
|
&& curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \
|
||||||
|
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y docker-ce-cli \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* # buildkit
|
||||||
|
|
||||||
|
# Fix lldb python installation
|
||||||
|
RUN ln -s /usr/lib/llvm-14/lib/python3.10/dist-packages/lldb/* /usr/lib/python3/dist-packages/lldb/
|
22
tests/manual/docker/linux/Dockerfile
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y \
|
||||||
|
libgl1-mesa-dev \
|
||||||
|
qt6-base-dev \
|
||||||
|
qt6-base-private-dev \
|
||||||
|
qt6-declarative-dev \
|
||||||
|
qt6-declarative-private-dev \
|
||||||
|
libqt6core5compat6-dev \
|
||||||
|
build-essential \
|
||||||
|
cmake \
|
||||||
|
nano \
|
||||||
|
ninja-build \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
gnupg \
|
||||||
|
lsb-release \
|
||||||
|
gdb \
|
||||||
|
xterm \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
20
tests/manual/docker/linux/Dockerfile-base
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y \
|
||||||
|
build-essential curl cmake libssl-dev python3 nano ninja-build \
|
||||||
|
libglu1-mesa-dev libgl1-mesa-dev libopengl-dev libgl-dev libfontconfig1-dev libfreetype6-dev libx11-dev libx11-xcb-dev libxext-dev libxfixes-dev libxi-dev libxrender-dev libxcb1-dev libxcb-glx0-dev libxcb-keysyms1-dev libxcb-image0-dev libxcb-shm0-dev libxcb-icccm4-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-shape0-dev libxcb-randr0-dev libxcb-render-util0-dev libxcb-util-dev libxcb-xinerama0-dev libxcb-xkb-dev libxkbcommon-dev libxkbcommon-x11-dev && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
RUN curl -L https://download.qt.io/official_releases/qt/6.4/6.4.2/single/qt-everywhere-src-6.4.2.tar.xz -o /tmp/qt.tar.xz && \
|
||||||
|
cd /tmp && tar -xf qt.tar.xz && \
|
||||||
|
cd /tmp/qt-everywhere-src-6.4.2 && \
|
||||||
|
./configure -nomake tests -debug -skip qtlocation -skip qtpositioning -no-warnings-are-errors && \
|
||||||
|
cmake --build . --parallel 4 && \
|
||||||
|
cmake --install . && \
|
||||||
|
rm -rf /tmp/*
|
||||||
|
|
||||||
|
ENV PATH="/usr/local/Qt-6.4.2/bin:$PATH"
|
||||||
|
|
||||||
|
|
||||||
|
|
29
tests/manual/docker/linux/Dockerfile-llvm
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y \
|
||||||
|
libgl1-mesa-dev \
|
||||||
|
qt6-base-dev \
|
||||||
|
qt6-base-private-dev \
|
||||||
|
qt6-declarative-dev \
|
||||||
|
qt6-declarative-private-dev \
|
||||||
|
libqt6core5compat6-dev \
|
||||||
|
build-essential \
|
||||||
|
clang-format clang-tidy clang-tools clang clangd libc++-dev libc++1 libc++abi-dev libc++abi1 libclang-dev libclang1 liblldb-dev libllvm-ocaml-dev libomp-dev libomp5 lld lldb llvm-dev llvm-runtime llvm python3-clang python3-lldb \
|
||||||
|
cmake \
|
||||||
|
nano \
|
||||||
|
ninja-build \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
gnupg \
|
||||||
|
lsb-release \
|
||||||
|
gdb \
|
||||||
|
xterm \
|
||||||
|
&& curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \
|
||||||
|
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y docker-ce-cli \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* # buildkit
|
||||||
|
|
||||||
|
# Fix lldb python installation
|
||||||
|
RUN ln -s /usr/lib/llvm-14/lib/python3.10/dist-packages/lldb/* /usr/lib/python3/dist-packages/lldb/
|
32
tests/manual/docker/linux/Dockerfile-llvm-conan
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y \
|
||||||
|
libgl1-mesa-dev \
|
||||||
|
qt6-base-dev \
|
||||||
|
qt6-base-private-dev \
|
||||||
|
qt6-declarative-dev \
|
||||||
|
qt6-declarative-private-dev \
|
||||||
|
libqt6core5compat6-dev \
|
||||||
|
build-essential \
|
||||||
|
clang-format clang-tidy clang-tools clang clangd libc++-dev libc++1 libc++abi-dev libc++abi1 libclang-dev libclang1 liblldb-dev libllvm-ocaml-dev libomp-dev libomp5 lld lldb llvm-dev llvm-runtime llvm python3-clang python3-lldb \
|
||||||
|
cmake \
|
||||||
|
nano \
|
||||||
|
ninja-build \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
gnupg \
|
||||||
|
lsb-release \
|
||||||
|
gdb \
|
||||||
|
&& curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \
|
||||||
|
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y docker-ce-cli \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* # buildkit
|
||||||
|
|
||||||
|
# Fix lldb python installation
|
||||||
|
RUN ln -s /usr/lib/llvm-14/lib/python3.10/dist-packages/lldb/* /usr/lib/python3/dist-packages/lldb/
|
||||||
|
|
||||||
|
RUN curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py && python3 get-pip.py && rm get-pip.py
|
||||||
|
RUN pip install conan && conan --version && mkdir /.conan && chmod 777 /.conan
|
||||||
|
|
36
tests/manual/docker/linux/Dockerfile-llvm-vcpkg
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y \
|
||||||
|
libgl1-mesa-dev \
|
||||||
|
qt6-base-dev \
|
||||||
|
qt6-base-private-dev \
|
||||||
|
qt6-declarative-dev \
|
||||||
|
qt6-declarative-private-dev \
|
||||||
|
libqt6core5compat6-dev \
|
||||||
|
build-essential \
|
||||||
|
clang-format clang-tidy clang-tools clang clangd libc++-dev libc++1 libc++abi-dev libc++abi1 libclang-dev libclang1 liblldb-dev libllvm-ocaml-dev libomp-dev libomp5 lld lldb llvm-dev llvm-runtime llvm python3-clang python3-lldb \
|
||||||
|
cmake \
|
||||||
|
nano \
|
||||||
|
ninja-build \
|
||||||
|
ca-certificates \
|
||||||
|
curl \
|
||||||
|
gnupg \
|
||||||
|
lsb-release \
|
||||||
|
git \
|
||||||
|
zip unzip tar \
|
||||||
|
gdb \
|
||||||
|
&& curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \
|
||||||
|
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
|
||||||
|
&& apt-get update \
|
||||||
|
&& apt-get install -y docker-ce-cli \
|
||||||
|
&& rm -rf /var/lib/apt/lists/* # buildkit
|
||||||
|
|
||||||
|
# Fix lldb python installation
|
||||||
|
RUN ln -s /usr/lib/llvm-14/lib/python3.10/dist-packages/lldb/* /usr/lib/python3/dist-packages/lldb/
|
||||||
|
|
||||||
|
RUN cd / && git clone --depth 1 https://github.com/Microsoft/vcpkg.git && cd vcpkg && ./bootstrap-vcpkg.sh
|
||||||
|
|
||||||
|
RUN chmod -R 777 /vcpkg
|
||||||
|
|
||||||
|
RUN ln -s /vcpkg/vcpkg /usr/local/bin/vcpkg
|
43
tests/manual/docker/linux/Makefile
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
all: help
|
||||||
|
|
||||||
|
help:
|
||||||
|
@grep -E '^[0-9a-zA-Z._-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||||
|
|
||||||
|
default_run_args = --env="DISPLAY=host.docker.internal:0" --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -v $(HOME):$(HOME) --workdir=$(HOME)
|
||||||
|
|
||||||
|
base: Dockerfile-base ## Build Ubuntu 22.04, docker-cli image, build Qt manually
|
||||||
|
docker build . -f Dockerfile-base -t qt-linux-base -t qt-linux-base:6
|
||||||
|
|
||||||
|
base-run: ## Build & run the base image
|
||||||
|
docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock $(default_run_args) qt-linux-base /bin/bash
|
||||||
|
|
||||||
|
qt-linux: Dockerfile ## Build Ubuntu 22.04, Qt 6, docker-cli image
|
||||||
|
docker build . -t qt-linux -t qt-linux:6
|
||||||
|
|
||||||
|
qt-linux-run: qt-linux ## Build & run the image
|
||||||
|
docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock $(default_run_args) qt-linux:6 /bin/bash
|
||||||
|
|
||||||
|
qt-linux-with-qtc: DockerFile-with-creator ## Build Ubuntu 22.04, Qt 6, docker-cli image, Includes Qt Creator
|
||||||
|
docker build . -f DockerFile-with-creator -t qt-linux-qtc -t qt-linux-qtc:6
|
||||||
|
|
||||||
|
qt-linux-with-qtc-run: qt-linux-with-qtc ## Build & run the image, Includes Qt Creator
|
||||||
|
docker run -it --rm $(default_run_args) qt-linux-qtc:6 /bin/bash
|
||||||
|
|
||||||
|
qt-linux-with-llvm: Dockerfile-llvm ## Build Ubuntu 22.04, Qt 6, docker-cli image, With Clang
|
||||||
|
docker build . -f Dockerfile-llvm -t qt-linux-llvm -t qt-linux-llvm:6
|
||||||
|
|
||||||
|
qt-linux-with-llvm-run: qt-linux-with-llvm ## Build & run the image, With Clang
|
||||||
|
docker run -it --rm $(default_run_args) qt-linux-llvm:6 /bin/bash
|
||||||
|
|
||||||
|
qt-linux-with-llvm-conan: Dockerfile-llvm-conan ## Build Ubuntu 22.04, Qt 6, docker-cli image, With Clang, Conan
|
||||||
|
docker build . -f Dockerfile-llvm-conan -t qt-linux-llvm-conan -t qt-linux-llvm-conan:6
|
||||||
|
|
||||||
|
qt-linux-with-llvm-conan-run: qt-linux-with-llvm-conan ## Build & run the image, With Clang, Conan
|
||||||
|
docker run -it --rm $(default_run_args) qt-linux-llvm-conan:6 /bin/bash
|
||||||
|
|
||||||
|
qt-linux-with-llvm-vcpkg: Dockerfile-llvm-vcpkg ## Build Ubuntu 22.04, Qt 6, docker-cli image, With Clang, Vcpkg
|
||||||
|
docker build . -f Dockerfile-llvm-vcpkg -t qt-linux-llvm-vcpkg -t qt-linux-llvm-vcpkg:6
|
||||||
|
|
||||||
|
qt-linux-with-llvm-vcpkg-run: qt-linux-with-llvm-vcpkg ## Build & run the image, With Clang, Vcpkg
|
||||||
|
docker run -it --rm $(default_run_args) qt-linux-llvm-vcpkg:6 /bin/bash
|
||||||
|
|