Merge "Merge remote-tracking branch 'origin/6.0'"
41
dist/changes-6.0.0.md
vendored
@@ -29,16 +29,24 @@ Editing
|
|||||||
* Added option for saving open files automatically after refactoring
|
* Added option for saving open files automatically after refactoring
|
||||||
(QTCREATORBUG-25924)
|
(QTCREATORBUG-25924)
|
||||||
* Added information about source to tooltip on diagnostics
|
* Added information about source to tooltip on diagnostics
|
||||||
* Fixed `Insert Definition` for templates with value parameters
|
* Added highlighting color option for namespaces (QTCREATORBUG-16580)
|
||||||
(QTCREATORBUG-26113)
|
* Made pure virtual functions optional in `Create implementations for all member
|
||||||
|
functions` (QTCREATORBUG-26468)
|
||||||
|
* Fixed `Insert Definition` for template types (QTCREATORBUG-26113,
|
||||||
|
QTCREATORBUG-26397)
|
||||||
|
* Fixed that `Find References` did not work for some template and namespace
|
||||||
|
combinations (QTCREATORBUG-26520)
|
||||||
* Fixed canceling of C++ parsing on configuration change (QTCREATORBUG-24890)
|
* Fixed canceling of C++ parsing on configuration change (QTCREATORBUG-24890)
|
||||||
* Fixed crash when checking for refactoring actions (QTCREATORBUG-26316)
|
* Fixed crash when checking for refactoring actions (QTCREATORBUG-26316)
|
||||||
* Fixed wrong target compiler option (QTCREATORBUG-25615)
|
* Fixed wrong target compiler option (QTCREATORBUG-25615)
|
||||||
* Fixed parentheses matching (QTCREATORBUG-26400)
|
* Fixed parentheses matching (QTCREATORBUG-26400)
|
||||||
|
* Fixed documentation comment generation for template types (QTCREATORBUG-9620)
|
||||||
* Clangd
|
* Clangd
|
||||||
* Added warning for older `clangd` versions
|
* Added warning for older `clangd` versions
|
||||||
* Added support for completion and function hint
|
* Added support for completion and function hint
|
||||||
|
* Added option for `Insert header files on completion`
|
||||||
* Improved location of generated `compile_commands.json` (QTCREATORBUG-26431)
|
* Improved location of generated `compile_commands.json` (QTCREATORBUG-26431)
|
||||||
|
* Fixed missing reparsing after refactorings (QTCREATORBUG-26523)
|
||||||
|
|
||||||
### QML
|
### QML
|
||||||
|
|
||||||
@@ -66,6 +74,7 @@ Projects
|
|||||||
(QTCREATORBUG-26422)
|
(QTCREATORBUG-26422)
|
||||||
* Fixed that re-detecting compilers removed compilers from kits
|
* Fixed that re-detecting compilers removed compilers from kits
|
||||||
(QTCREATORBUG-25697)
|
(QTCREATORBUG-25697)
|
||||||
|
* Fixed GitHub action created by Qt Creator plugin wizard for Qt 6
|
||||||
|
|
||||||
### CMake
|
### CMake
|
||||||
|
|
||||||
@@ -79,6 +88,7 @@ Projects
|
|||||||
QTCREATORBUG-26238, QTCREATORBUG-21452, QTCREATORBUG-25644,
|
QTCREATORBUG-26238, QTCREATORBUG-21452, QTCREATORBUG-25644,
|
||||||
QTCREATORBUG-25782)
|
QTCREATORBUG-25782)
|
||||||
* Fixed that generated files were selected for analyzing (QTCREATORBUG-25125)
|
* Fixed that generated files were selected for analyzing (QTCREATORBUG-25125)
|
||||||
|
* Fixed importing of Qt projects (QTCREATORBUG-25767)
|
||||||
|
|
||||||
### qmake
|
### qmake
|
||||||
|
|
||||||
@@ -88,6 +98,11 @@ Projects
|
|||||||
|
|
||||||
* Fixed that headers were not shown as part of the project (QTCREATORBUG-26356)
|
* Fixed that headers were not shown as part of the project (QTCREATORBUG-26356)
|
||||||
|
|
||||||
|
### Conan
|
||||||
|
|
||||||
|
* Added `QT_CREATOR_CONAN_BUILD_POLICY` used for `BUILD` property of
|
||||||
|
`conan_cmake_run`
|
||||||
|
|
||||||
Debugging
|
Debugging
|
||||||
---------
|
---------
|
||||||
|
|
||||||
@@ -97,6 +112,11 @@ Debugging
|
|||||||
* Fixed variable expansion for `Additional Startup Commands`
|
* Fixed variable expansion for `Additional Startup Commands`
|
||||||
(QTCREATORBUG-26382)
|
(QTCREATORBUG-26382)
|
||||||
|
|
||||||
|
### CDB
|
||||||
|
|
||||||
|
* Added hint for missing Qt debug information
|
||||||
|
* Improved pretty printing for Qt 6 without debug information
|
||||||
|
|
||||||
Version Control Systems
|
Version Control Systems
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
@@ -117,9 +137,16 @@ Test Integration
|
|||||||
Platforms
|
Platforms
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
* Added support for MSVC 2022
|
||||||
|
|
||||||
### macOS
|
### macOS
|
||||||
|
|
||||||
* Changed prebuilt binaries to universal Intel + ARM
|
* Changed prebuilt binaries to universal Intel + ARM
|
||||||
|
* Made dark theme the default in dark system mode
|
||||||
|
* Fixed issues with dark system mode (QTCREATORBUG-21520, QTCREATORBUG-26427,
|
||||||
|
QTCREATORBUG-26428)
|
||||||
|
|
||||||
### Android
|
### Android
|
||||||
|
|
||||||
@@ -127,11 +154,16 @@ Platforms
|
|||||||
selector (QTCREATORBUG-23991)
|
selector (QTCREATORBUG-23991)
|
||||||
* Added details to device settings (QTCREATORBUG-23991)
|
* Added details to device settings (QTCREATORBUG-23991)
|
||||||
* Added filter field for Android SDK manager
|
* Added filter field for Android SDK manager
|
||||||
|
* Fixed that NDK 22 and later could not be added
|
||||||
|
|
||||||
### WebAssembly
|
### WebAssembly
|
||||||
|
|
||||||
* Fixed running applications (QTCREATORBUG-25905, QTCREATORBUG-26189)
|
* Fixed running applications (QTCREATORBUG-25905, QTCREATORBUG-26189)
|
||||||
|
|
||||||
|
### MCU
|
||||||
|
|
||||||
|
* Added preliminary support for SDK 2.0
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
|
|
||||||
* Various improvements
|
* Various improvements
|
||||||
@@ -147,6 +179,7 @@ André Pönitz
|
|||||||
Artem Sokolovskii
|
Artem Sokolovskii
|
||||||
Artur Shepilko
|
Artur Shepilko
|
||||||
Assam Boudjelthia
|
Assam Boudjelthia
|
||||||
|
BogDan Vatra
|
||||||
Christiaan Janssen
|
Christiaan Janssen
|
||||||
Christian Kandeler
|
Christian Kandeler
|
||||||
Christian Stenger
|
Christian Stenger
|
||||||
@@ -160,6 +193,7 @@ Ivan Komissarov
|
|||||||
Jaroslaw Kobus
|
Jaroslaw Kobus
|
||||||
Johanna Vanhatapio
|
Johanna Vanhatapio
|
||||||
Jonas Karlsson
|
Jonas Karlsson
|
||||||
|
Jonas Singe
|
||||||
Kai Köhne
|
Kai Köhne
|
||||||
Kama Wójcik
|
Kama Wójcik
|
||||||
Knud Dollereder
|
Knud Dollereder
|
||||||
@@ -171,9 +205,11 @@ Marco Bubke
|
|||||||
Martin Kampas
|
Martin Kampas
|
||||||
Miikka Heikkinen
|
Miikka Heikkinen
|
||||||
Miina Puuronen
|
Miina Puuronen
|
||||||
|
Oliver Wolff
|
||||||
Orgad Shaneh
|
Orgad Shaneh
|
||||||
Petar Perisin
|
Petar Perisin
|
||||||
Piotr Mikolajczyk
|
Piotr Mikolajczyk
|
||||||
|
Robert Löhning
|
||||||
Samuel Ghinet
|
Samuel Ghinet
|
||||||
Shantanu Tushar
|
Shantanu Tushar
|
||||||
Tapani Mattila
|
Tapani Mattila
|
||||||
@@ -181,6 +217,7 @@ Tasuku Suzuki
|
|||||||
Thiago Macieira
|
Thiago Macieira
|
||||||
Thomas Hartmann
|
Thomas Hartmann
|
||||||
Tim Jenssen
|
Tim Jenssen
|
||||||
|
Tomi Korpipaa
|
||||||
Tony Leinonen
|
Tony Leinonen
|
||||||
Tor Arne Vestbø
|
Tor Arne Vestbø
|
||||||
Tuomo Pelkonen
|
Tuomo Pelkonen
|
||||||
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 28 KiB |
BIN
doc/qtcreator/images/qtcreator-git-amend.png
Normal file
After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 16 KiB |
@@ -135,6 +135,9 @@
|
|||||||
case-sensitivity. Select \uicontrol {Show Non-matching Lines} to
|
case-sensitivity. Select \uicontrol {Show Non-matching Lines} to
|
||||||
hide the lines that match the filter.
|
hide the lines that match the filter.
|
||||||
|
|
||||||
|
Press \key {Ctrl+F} to \l{Finding and Replacing}{search} for a string from
|
||||||
|
the output.
|
||||||
|
|
||||||
To increase or decrease the output text size, select \inlineimage plus.png
|
To increase or decrease the output text size, select \inlineimage plus.png
|
||||||
(\uicontrol {Zoom In}) or \inlineimage minus.png
|
(\uicontrol {Zoom In}) or \inlineimage minus.png
|
||||||
(\uicontrol {Zoom Out}), or press \key Ctrl++ or \key Ctrl+-.
|
(\uicontrol {Zoom Out}), or press \key Ctrl++ or \key Ctrl+-.
|
||||||
@@ -197,5 +200,5 @@
|
|||||||
\image qtcreator-cmake-clean-steps.png
|
\image qtcreator-cmake-clean-steps.png
|
||||||
|
|
||||||
The build errors and warnings are parsed and displayed in the
|
The build errors and warnings are parsed and displayed in the
|
||||||
\uicontrol Issues output pane.
|
\l Issues output pane.
|
||||||
*/
|
*/
|
||||||
|
@@ -57,18 +57,19 @@
|
|||||||
a \c CMakeLists.txt configuration file in a project. Project information is
|
a \c CMakeLists.txt configuration file in a project. Project information is
|
||||||
also automatically refreshed when you build the project.
|
also automatically refreshed when you build the project.
|
||||||
|
|
||||||
The \uicontrol {File System} section in the sidebar \uicontrol Projects view
|
\image qtcreator-projects-view-edit.png "CMake project in Projects view"
|
||||||
displays information from the file system. \QC cannot determine whether the
|
|
||||||
files are part of the project. For example, header files that \QC finds in
|
|
||||||
the project directories but that are not mentioned in the CMakeLists.txt
|
|
||||||
files are listed here.
|
|
||||||
|
|
||||||
\image qtcreator-projects-view-cmake.png "File System section in Projects view"
|
If \QC cannot load the CMake project, the \l Projects view shows a
|
||||||
|
\uicontrol {<File System>} project node to avoid scanning the file
|
||||||
|
system and load the project faster. The node shows the same files
|
||||||
|
as the \l {File System} view. Select \uicontrol Build >
|
||||||
|
\uicontrol {Clear CMake Configuration}, and then select \uicontrol Build
|
||||||
|
> \uicontrol {Run CMake} to reconfigure the project.
|
||||||
|
|
||||||
\section1 Adding CMake Tools
|
\section1 Adding CMake Tools
|
||||||
|
|
||||||
\QC requires CMake's \l{https://cmake.org/cmake/help/latest/manual/cmake-file-api.7.html}
|
\QC requires CMake's \l{https://cmake.org/cmake/help/latest/manual/cmake-file-api.7.html}
|
||||||
{file-based API}. Please make sure to use CMake version 3.14, or later.
|
{file-based API}, and therefore you'll need CMake version 3.14, or later.
|
||||||
|
|
||||||
To view and specify settings for CMake:
|
To view and specify settings for CMake:
|
||||||
|
|
||||||
@@ -144,6 +145,8 @@
|
|||||||
|
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
|
Warnings and errors are displayed in the \l {Issues} output pane.
|
||||||
|
|
||||||
\section1 Adding External Libraries to CMake Projects
|
\section1 Adding External Libraries to CMake Projects
|
||||||
|
|
||||||
Through external libraries, \QC can support code completion and syntax
|
Through external libraries, \QC can support code completion and syntax
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2020 The Qt Company Ltd.
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -57,7 +57,7 @@
|
|||||||
applications for multiple desktop and \l{glossary-device}{device}
|
applications for multiple desktop and \l{glossary-device}{device}
|
||||||
platforms.
|
platforms.
|
||||||
|
|
||||||
\li \l{Using Other Build Systems}
|
\li \l{Build Systems}
|
||||||
|
|
||||||
\QC is integrated with cross-platform systems for build automation:
|
\QC is integrated with cross-platform systems for build automation:
|
||||||
qmake, Qbs, CMake, and Autotools. In addition, you can import
|
qmake, Qbs, CMake, and Autotools. In addition, you can import
|
||||||
|
@@ -515,7 +515,7 @@
|
|||||||
\li \l{Opening Projects}
|
\li \l{Opening Projects}
|
||||||
\li \l{Adding Libraries to Projects}
|
\li \l{Adding Libraries to Projects}
|
||||||
\li \l{Adding New Custom Wizards}
|
\li \l{Adding New Custom Wizards}
|
||||||
\li \l{Using Other Build Systems}
|
\li \l{Build Systems}
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@@ -34,7 +34,7 @@
|
|||||||
\page creator-project-other.html
|
\page creator-project-other.html
|
||||||
\nextpage creator-project-cmake.html
|
\nextpage creator-project-cmake.html
|
||||||
|
|
||||||
\title Using Other Build Systems
|
\title Build Systems
|
||||||
|
|
||||||
Most \QC project wizards enable you to choose the build system to use for
|
Most \QC project wizards enable you to choose the build system to use for
|
||||||
building the project: qmake, CMake, Meson, or Qbs. qmake is installed and
|
building the project: qmake, CMake, Meson, or Qbs. qmake is installed and
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
\section1 Related Topics
|
\section1 Related Topics
|
||||||
|
|
||||||
\list
|
\list
|
||||||
\li \l{Using Other Build Systems}
|
\li \l{Build Systems}
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@@ -212,7 +212,7 @@
|
|||||||
\li \l {Embedded Platforms}
|
\li \l {Embedded Platforms}
|
||||||
\li \l {Mobile Platforms}
|
\li \l {Mobile Platforms}
|
||||||
\endlist
|
\endlist
|
||||||
\li \l{Using Other Build Systems}
|
\li \l{Build Systems}
|
||||||
\list
|
\list
|
||||||
\li \l{Setting Up CMake}
|
\li \l{Setting Up CMake}
|
||||||
\li \l{Setting Up Qbs}
|
\li \l{Setting Up Qbs}
|
||||||
|
@@ -113,7 +113,7 @@
|
|||||||
\li \b {\l{Advanced Use}}
|
\li \b {\l{Advanced Use}}
|
||||||
\list
|
\list
|
||||||
\li \l{Supported Platforms}
|
\li \l{Supported Platforms}
|
||||||
\li \l{Using Other Build Systems}
|
\li \l{Build Systems}
|
||||||
\li \l{Using Command Line Options}
|
\li \l{Using Command Line Options}
|
||||||
\li \l{Keyboard Shortcuts}
|
\li \l{Keyboard Shortcuts}
|
||||||
\li \l{Using External Tools}
|
\li \l{Using External Tools}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2020 The Qt Company Ltd.
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -203,7 +203,20 @@
|
|||||||
commit page containing a text editor where you can enter your commit
|
commit page containing a text editor where you can enter your commit
|
||||||
message and a checkable list of modified files to be included.
|
message and a checkable list of modified files to be included.
|
||||||
|
|
||||||
\image qtcreator-vcs-commit.png
|
\image qtcreator-vcs-commit.png "Committing changes with Git"
|
||||||
|
|
||||||
|
\uicontrol {General Information} displays the names of the
|
||||||
|
repository and branch for the commit.
|
||||||
|
|
||||||
|
In \uicontrol {Commit Information}, you can edit information about the
|
||||||
|
author of the commit. To bypass re-commit and commit message hooks,
|
||||||
|
select \uicontrol {Bypass hooks}. If signoffs are used for your project,
|
||||||
|
select \uicontrol {Sign off} to add a \e signed-off-by trailer by the
|
||||||
|
author at the end of the commit log message.
|
||||||
|
|
||||||
|
In \uicontrol Description, edit the commit message.
|
||||||
|
|
||||||
|
In \uicontrol Files, select the files to include in the commit.
|
||||||
|
|
||||||
When you have finished filling out the commit page information, click on
|
When you have finished filling out the commit page information, click on
|
||||||
\uicontrol Commit to start committing.
|
\uicontrol Commit to start committing.
|
||||||
@@ -223,10 +236,22 @@
|
|||||||
|
|
||||||
\section2 Amending Commits
|
\section2 Amending Commits
|
||||||
|
|
||||||
To apply latest changes to the last commit, select
|
To apply latest changes to the last commit, select \uicontrol Tools >
|
||||||
\uicontrol {Amend Last Commit}. You can also edit the commit message.
|
\uicontrol Git > \uicontrol {Local Repository} >
|
||||||
|
\uicontrol {Amend Last Commit}.
|
||||||
|
|
||||||
|
\image qtcreator-git-amend.png "Amending a Git commit"
|
||||||
|
|
||||||
|
To view the commit in its current form, before amending, select
|
||||||
|
\uicontrol {Show HEAD}.
|
||||||
|
|
||||||
|
To view a diff of the changes in the selected files, select
|
||||||
|
\uicontrol {Diff Selected Files}.
|
||||||
|
|
||||||
|
Select \uicontrol Commit to amend the commit.
|
||||||
|
|
||||||
To amend an earlier comment in a series of related commits, select
|
To amend an earlier comment in a series of related commits, select
|
||||||
|
\uicontrol Tools > \uicontrol Git > \uicontrol {Local Repository} >
|
||||||
\uicontrol {Fixup Previous Commit}. This operation is done using interactive
|
\uicontrol {Fixup Previous Commit}. This operation is done using interactive
|
||||||
rebase. In case of conflicts, a merge tool is suggested.
|
rebase. In case of conflicts, a merge tool is suggested.
|
||||||
|
|
||||||
|
@@ -30,6 +30,28 @@
|
|||||||
|
|
||||||
\title Importing 2D Assets
|
\title Importing 2D Assets
|
||||||
|
|
||||||
|
You can import 2D assets, such as images, fonts, and sound files, to \QDS to
|
||||||
|
use them in your projects.
|
||||||
|
|
||||||
|
To import an asset, drag-and-drop the external file containing the asset from,
|
||||||
|
for example, File Explorer on Windows, to \uicontrol {Form Editor},
|
||||||
|
\uicontrol Navigator, or \uicontrol {Text Editor}. Alternatively, select
|
||||||
|
\l Library > \uicontrol Assets > \inlineimage plus.png
|
||||||
|
and follow the instructions in the \uicontrol {Asset Import} dialog. You can
|
||||||
|
also multiselect several external asset files to drag-and-drop them to
|
||||||
|
\QDS simultaneously.
|
||||||
|
|
||||||
|
The imported images will appear in \uicontrol Library > \uicontrol Assets.
|
||||||
|
If you initiate the import by dragging the assets to \uicontrol {Form Editor},
|
||||||
|
they are also added to your projects as image components, and you can view
|
||||||
|
them in \uicontrol {Form Editor} and \uicontrol Navigator. If you drag an
|
||||||
|
external font file to \uicontrol {Form Editor}, it will be added to your
|
||||||
|
project as a text component. Other imported assets, such as sound files,
|
||||||
|
will only appear in \uicontrol Library > \uicontrol Assets, and you can then
|
||||||
|
drag-and-drop them to a suitable view.
|
||||||
|
|
||||||
|
\section1 Importing Designs From Other Design Tools
|
||||||
|
|
||||||
\image studio-imported-assets.png "UI imported into Qt Design Studio"
|
\image studio-imported-assets.png "UI imported into Qt Design Studio"
|
||||||
|
|
||||||
\QB enables you to export assets and then import them to a \QDS project
|
\QB enables you to export assets and then import them to a \QDS project
|
||||||
@@ -45,7 +67,7 @@
|
|||||||
information about the options you have, see
|
information about the options you have, see
|
||||||
\l {Creating Projects}.
|
\l {Creating Projects}.
|
||||||
|
|
||||||
To import designs to \QDS projects:
|
To import assets exported in \QB to \QDS projects:
|
||||||
|
|
||||||
\list 1
|
\list 1
|
||||||
\li Select \uicontrol File > \uicontrol {New File or Project} >
|
\li Select \uicontrol File > \uicontrol {New File or Project} >
|
||||||
@@ -107,4 +129,5 @@
|
|||||||
design tool and export the assets again.
|
design tool and export the assets again.
|
||||||
|
|
||||||
\include qtbridge-tutorial-links.qdocinc qtsketchbridge tutorials
|
\include qtbridge-tutorial-links.qdocinc qtsketchbridge tutorials
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
@@ -43,17 +43,27 @@
|
|||||||
For more information about exporting 3D graphics, see
|
For more information about exporting 3D graphics, see
|
||||||
\l{Exporting 3D Assets}.
|
\l{Exporting 3D Assets}.
|
||||||
|
|
||||||
During the import, you can optimize the files for \QDS. You can remove
|
|
||||||
components from meshes to reduce the cache size, find and fix issues in
|
|
||||||
the files, optimize graphs and meshes, and so on. The available options
|
|
||||||
depend on whether you are importing files that you created with Qt 3D Studio
|
|
||||||
or with other 3D graphics tools. See the tooltips in the options dialog
|
|
||||||
for more information about a particular option.
|
|
||||||
|
|
||||||
\image studio-import-3d.png
|
\image studio-import-3d.png
|
||||||
|
|
||||||
To import 3D assets to \QDS projects:
|
To import 3D assets to \QDS projects:
|
||||||
|
|
||||||
|
\list 1
|
||||||
|
\li Drag-and-drop an external file containing the 3D asset from,
|
||||||
|
for example, File Explorer (on Windows), to \uicontrol {3D Editor}.
|
||||||
|
\li In the \uicontrol {3D Scene Options} tab, select options for
|
||||||
|
importing the file.
|
||||||
|
\li Select \uicontrol Import to import the 3D graphics file.
|
||||||
|
\li When the import is done, select \uicontrol Close.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
The 3D asset you dragged-and-dropped to \uicontrol {3D Editor} has now
|
||||||
|
been added to your scene, and you can see it in the \uicontrol {3D Editor}
|
||||||
|
view and in \uicontrol Navigator. It is also available in
|
||||||
|
\uicontrol Library > \uicontrol Components > \uicontrol {My 3D Components}.
|
||||||
|
|
||||||
|
Alternatively, you can initiate the import dialog from the
|
||||||
|
\uicontrol Library view:
|
||||||
|
|
||||||
\list 1
|
\list 1
|
||||||
\li In the \l{Design Views}{Design mode}, select \l Library >
|
\li In the \l{Design Views}{Design mode}, select \l Library >
|
||||||
\uicontrol Assets > \inlineimage plus.png
|
\uicontrol Assets > \inlineimage plus.png
|
||||||
@@ -67,6 +77,17 @@
|
|||||||
\li When the import is done, select \uicontrol Close.
|
\li When the import is done, select \uicontrol Close.
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
|
The 3D asset now appears in \uicontrol Library > \uicontrol Components >
|
||||||
|
\uicontrol {My 3D Components}. You can add it to the scene by
|
||||||
|
drag-and-dropping it to \uicontrol {3D Editor}.
|
||||||
|
|
||||||
|
During the import, you can optimize the files for \QDS. You can remove
|
||||||
|
components from meshes to reduce the cache size, find and fix issues in
|
||||||
|
the files, optimize graphs and meshes, and so on. The available options
|
||||||
|
depend on whether you are importing files that you created with Qt 3D Studio
|
||||||
|
or with other 3D graphics tools. See the tooltips in the options dialog
|
||||||
|
for more information about a particular option.
|
||||||
|
|
||||||
The 3D asset you added to the project now appears in \uicontrol Library >
|
The 3D asset you added to the project now appears in \uicontrol Library >
|
||||||
\uicontrol Components > \uicontrol {My 3D Components}. You can add it to
|
\uicontrol Components > \uicontrol {My 3D Components}. You can add it to
|
||||||
your UI by dragging-and-dropping it to \l {3D Editor}.
|
your UI by dragging-and-dropping it to \l {3D Editor}.
|
||||||
|
@@ -119,9 +119,13 @@
|
|||||||
\section1 Assets
|
\section1 Assets
|
||||||
|
|
||||||
\uicontrol Library > \uicontrol {Assets} displays the images and other files
|
\uicontrol Library > \uicontrol {Assets} displays the images and other files
|
||||||
that you add to the project folder by selecting \inlineimage plus.png
|
that you add to the project folder by dragging-and-dropping external asset
|
||||||
. To add assets to your UI, drag-and-drop them to \l Navigator or
|
files to \QDS or by selecting \inlineimage plus.png
|
||||||
\l {Form Editor}.
|
. For more information about importing assets to \QDS, see
|
||||||
|
\l {Importing 2D Assets} and \l {Importing 3D Assets}.
|
||||||
|
|
||||||
|
To add assets to your UI, drag-and-drop them from \uicontrol Library >
|
||||||
|
\uicontrol Assets to \l Navigator, \l {Form Editor}, or \l {3D Editor}.
|
||||||
|
|
||||||
To add multiple assets to your UI simultaneously, multiselect them first by
|
To add multiple assets to your UI simultaneously, multiselect them first by
|
||||||
holding \key Ctrl and clicking the asset files you wish to select.
|
holding \key Ctrl and clicking the asset files you wish to select.
|
||||||
|
@@ -252,8 +252,9 @@ class DumperBase():
|
|||||||
#DumperBase.warn('EXPANDED INAMES: %s' % self.expandedINames)
|
#DumperBase.warn('EXPANDED INAMES: %s' % self.expandedINames)
|
||||||
#DumperBase.warn('WATCHERS: %s' % self.watchers)
|
#DumperBase.warn('WATCHERS: %s' % self.watchers)
|
||||||
|
|
||||||
def setFallbackQtVersion(self, version):
|
def setFallbackQtVersion(self, args):
|
||||||
self.warn("got fallback qt version %x" % version)
|
version = int(args.get('version', self.fallbackQtVersion))
|
||||||
|
DumperBase.warn("got fallback qt version 0x%x" % version)
|
||||||
self.fallbackQtVersion = version
|
self.fallbackQtVersion = version
|
||||||
|
|
||||||
def resetPerStepCaches(self):
|
def resetPerStepCaches(self):
|
||||||
@@ -1135,12 +1136,18 @@ class DumperBase():
|
|||||||
if displayFormat != DisplayFormat.Raw and p:
|
if displayFormat != DisplayFormat.Raw and p:
|
||||||
if innerType.name in (
|
if innerType.name in (
|
||||||
'char',
|
'char',
|
||||||
|
'int8_t',
|
||||||
|
'qint8',
|
||||||
'wchar_t',
|
'wchar_t',
|
||||||
'unsigned char',
|
'unsigned char',
|
||||||
'uint8_t',
|
'uint8_t',
|
||||||
|
'quint8',
|
||||||
'signed char',
|
'signed char',
|
||||||
'CHAR',
|
'CHAR',
|
||||||
'WCHAR'
|
'WCHAR',
|
||||||
|
'char8_t',
|
||||||
|
'char16_t',
|
||||||
|
'char32_t'
|
||||||
):
|
):
|
||||||
self.putCharArrayHelper(p, n, innerType, self.currentItemFormat(),
|
self.putCharArrayHelper(p, n, innerType, self.currentItemFormat(),
|
||||||
makeExpandable=False)
|
makeExpandable=False)
|
||||||
@@ -1406,11 +1413,17 @@ class DumperBase():
|
|||||||
if innerType.name not in (
|
if innerType.name not in (
|
||||||
'char',
|
'char',
|
||||||
'signed char',
|
'signed char',
|
||||||
|
'int8_t',
|
||||||
|
'qint8',
|
||||||
'unsigned char',
|
'unsigned char',
|
||||||
'uint8_t',
|
'uint8_t',
|
||||||
|
'quint8',
|
||||||
'wchar_t',
|
'wchar_t',
|
||||||
'CHAR',
|
'CHAR',
|
||||||
'WCHAR'
|
'WCHAR',
|
||||||
|
'char8_t',
|
||||||
|
'char16_t',
|
||||||
|
'char32_t'
|
||||||
):
|
):
|
||||||
self.putDerefedPointer(value)
|
self.putDerefedPointer(value)
|
||||||
return
|
return
|
||||||
@@ -3628,15 +3641,33 @@ class DumperBase():
|
|||||||
res = {
|
res = {
|
||||||
'bool': 'int:1',
|
'bool': 'int:1',
|
||||||
'char': 'int:1',
|
'char': 'int:1',
|
||||||
|
'int8_t': 'int:1',
|
||||||
|
'qint8': 'int:1',
|
||||||
'signed char': 'int:1',
|
'signed char': 'int:1',
|
||||||
|
'char8_t': 'uint:1',
|
||||||
'unsigned char': 'uint:1',
|
'unsigned char': 'uint:1',
|
||||||
'uint8_t': 'uint:1',
|
'uint8_t': 'uint:1',
|
||||||
|
'quint8': 'uint:1',
|
||||||
'short': 'int:2',
|
'short': 'int:2',
|
||||||
|
'int16_t': 'int:2',
|
||||||
|
'qint16': 'int:2',
|
||||||
'unsigned short': 'uint:2',
|
'unsigned short': 'uint:2',
|
||||||
|
'char16_t': 'uint:2',
|
||||||
|
'uint16_t': 'uint:2',
|
||||||
|
'quint16': 'uint:2',
|
||||||
'int': 'int:4',
|
'int': 'int:4',
|
||||||
|
'int32_t': 'int:4',
|
||||||
|
'qint32': 'int:4',
|
||||||
'unsigned int': 'uint:4',
|
'unsigned int': 'uint:4',
|
||||||
|
'char32_t': 'uint:4',
|
||||||
|
'uint32_t': 'uint:4',
|
||||||
|
'quint32': 'uint:4',
|
||||||
'long long': 'int:8',
|
'long long': 'int:8',
|
||||||
|
'int64_t': 'int:8',
|
||||||
|
'qint64': 'int:8',
|
||||||
'unsigned long long': 'uint:8',
|
'unsigned long long': 'uint:8',
|
||||||
|
'uint64_t': 'uint:8',
|
||||||
|
'quint64': 'uint:8',
|
||||||
'float': 'float:4',
|
'float': 'float:4',
|
||||||
'double': 'float:8',
|
'double': 'float:8',
|
||||||
'QChar': 'uint:2'
|
'QChar': 'uint:2'
|
||||||
|
@@ -1393,14 +1393,19 @@ void NodeInstanceServer::setTranslationLanguage(const QString &language)
|
|||||||
engine()->setUiLanguage(language);
|
engine()->setUiLanguage(language);
|
||||||
#endif
|
#endif
|
||||||
static QPointer<MultiLanguage::Translator> multilanguageTranslator;
|
static QPointer<MultiLanguage::Translator> multilanguageTranslator;
|
||||||
if (!MultiLanguage::databaseFilePath().isEmpty()) {
|
if (!MultiLanguage::databaseFilePath().isEmpty()
|
||||||
if (!multilanguageLink) {
|
&& QFileInfo::exists(QString::fromUtf8(MultiLanguage::databaseFilePath()))) {
|
||||||
multilanguageLink = std::make_unique<MultiLanguage::Link>();
|
try {
|
||||||
multilanguageTranslator = multilanguageLink->translator().release();
|
if (!multilanguageLink) {
|
||||||
QCoreApplication::installTranslator(multilanguageTranslator);
|
multilanguageLink = std::make_unique<MultiLanguage::Link>();
|
||||||
|
multilanguageTranslator = multilanguageLink->translator().release();
|
||||||
|
QCoreApplication::installTranslator(multilanguageTranslator);
|
||||||
|
}
|
||||||
|
if (multilanguageTranslator)
|
||||||
|
multilanguageTranslator->setLanguage(language);
|
||||||
|
} catch (std::exception &e) {
|
||||||
|
qWarning() << "QmlPuppet is unable to initialize MultiLanguage translator:" << e.what();
|
||||||
}
|
}
|
||||||
if (multilanguageTranslator)
|
|
||||||
multilanguageTranslator->setLanguage(language);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -32,6 +32,8 @@ import StudioControls 1.0 as StudioControls
|
|||||||
import StudioTheme 1.0 as StudioTheme
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
id: rootItem
|
||||||
|
|
||||||
property var selectedAssets: ({})
|
property var selectedAssets: ({})
|
||||||
property int allExpandedState: 0
|
property int allExpandedState: 0
|
||||||
property string delFilePath: ""
|
property string delFilePath: ""
|
||||||
@@ -257,4 +259,52 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Placeholder when the assets panel is empty
|
||||||
|
Column {
|
||||||
|
id: colNoAssets
|
||||||
|
visible: assetsModel.isEmpty
|
||||||
|
|
||||||
|
spacing: 20
|
||||||
|
x: 20
|
||||||
|
width: rootItem.width - 2 * x
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Looks like you don't have any assets yet.")
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
font.pixelSize: 18
|
||||||
|
width: colNoAssets.width
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
source: "image://qmldesigner_assets/browse"
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
scale: maBrowse.containsMouse ? 1.2 : 1
|
||||||
|
Behavior on scale {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: 300
|
||||||
|
easing.type: Easing.OutQuad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: maBrowse
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: rootView.handleAddAsset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Drag-and-drop your assets here or click the '+' button to browse assets from the file system.")
|
||||||
|
color: StudioTheme.Values.themeTextColor
|
||||||
|
font.pixelSize: 18
|
||||||
|
width: colNoAssets.width
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -105,8 +105,11 @@ Item {
|
|||||||
verticalAlignment: Text.AlignVCenter
|
verticalAlignment: Text.AlignVCenter
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
color: tabBar.currentIndex === index ? StudioTheme.Values.themeIconColorSelected
|
color: !plusButton.enabled
|
||||||
: StudioTheme.Values.themeIconColor
|
? StudioTheme.Values.themeIconColorDisabled
|
||||||
|
: tabBar.currentIndex === index
|
||||||
|
? StudioTheme.Values.themeIconColorSelected
|
||||||
|
: StudioTheme.Values.themeIconColor
|
||||||
}
|
}
|
||||||
|
|
||||||
HelperWidgets.ToolTipArea {
|
HelperWidgets.ToolTipArea {
|
||||||
|
@@ -0,0 +1,192 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick.Window
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
import StudioControls as SC
|
||||||
|
|
||||||
|
import NewProjectDialog
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: DialogValues.dialogWidth
|
||||||
|
height: DialogValues.dialogHeight
|
||||||
|
|
||||||
|
Rectangle { // the main dialog panel
|
||||||
|
anchors.fill: parent
|
||||||
|
color: DialogValues.darkPaneColor
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Item { // Header Item
|
||||||
|
Layout.fillWidth: true
|
||||||
|
implicitHeight: 218
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Item { width: parent.width; height: 74 } // spacer
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Welcome to Qt Design Studio. Let's Create Something Wonderful!")
|
||||||
|
font.pixelSize: 32
|
||||||
|
width: parent.width
|
||||||
|
height: 47
|
||||||
|
lineHeight: 49
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
color: DialogValues.textColor
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { width: parent.width; height: 11 } // spacer
|
||||||
|
|
||||||
|
Text {
|
||||||
|
width: parent.width
|
||||||
|
text: qsTr("Get started by selecting from Presets or start from empty screen. You may also include your design file.")
|
||||||
|
color: DialogValues.textColor
|
||||||
|
font.pixelSize: DialogValues.paneTitlePixelSize
|
||||||
|
lineHeight: DialogValues.paneTitleLineHeight
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // Header Item
|
||||||
|
|
||||||
|
Item { // Content Item
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
x: 35
|
||||||
|
width: parent.width - 70
|
||||||
|
height: parent.height
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Rectangle { // Left pane
|
||||||
|
color: DialogValues.lightPaneColor
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.minimumWidth: 379 // figured out this number visually
|
||||||
|
Layout.minimumHeight: 326 // figured out this number visually
|
||||||
|
|
||||||
|
Column {
|
||||||
|
x: DialogValues.defaultPadding // left padding
|
||||||
|
width: parent.width - DialogValues.defaultPadding * 2 // right padding
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Presets")
|
||||||
|
width: parent.width
|
||||||
|
font.weight: Font.DemiBold
|
||||||
|
font.pixelSize: DialogValues.paneTitlePixelSize
|
||||||
|
lineHeight: DialogValues.paneTitleLineHeight
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
color: DialogValues.textColor
|
||||||
|
}
|
||||||
|
|
||||||
|
NewProjectView {
|
||||||
|
id: projectViewId
|
||||||
|
x: 10 // left padding
|
||||||
|
width: parent.width - 64 // right padding
|
||||||
|
height: DialogValues.projectViewHeight
|
||||||
|
loader: projectDetailsLoader
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { height: 5; width: parent.width }
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: descriptionText
|
||||||
|
text: dialogBox.projectDescription
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
lineHeight: DialogValues.defaultLineHeight
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
leftPadding: 14
|
||||||
|
width: projectViewId.width
|
||||||
|
color: DialogValues.textColor
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
maximumLineCount: 4
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // Left pane
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: projectDetailsLoader
|
||||||
|
// we need to specify width because the loaded item needs to use parent sizes
|
||||||
|
width: DialogValues.loadedPanesWidth
|
||||||
|
Layout.fillHeight: true
|
||||||
|
source: ""
|
||||||
|
}
|
||||||
|
} // RowLayout
|
||||||
|
} //Content Item
|
||||||
|
|
||||||
|
Item { // Footer
|
||||||
|
implicitHeight: DialogValues.footerHeight
|
||||||
|
implicitWidth: parent.width
|
||||||
|
RowLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: DialogValues.defaultPadding
|
||||||
|
|
||||||
|
Item { Layout.fillWidth: true }
|
||||||
|
|
||||||
|
SC.AbstractButton {
|
||||||
|
implicitWidth: DialogValues.dialogButtonWidth
|
||||||
|
width: DialogValues.dialogButtonWidth
|
||||||
|
visible: true
|
||||||
|
buttonIcon: qsTr("Cancel")
|
||||||
|
iconSize: DialogValues.defaultPixelSize
|
||||||
|
iconFont: StudioTheme.Constants.font
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
dialogBox.reject();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SC.AbstractButton {
|
||||||
|
implicitWidth: DialogValues.dialogButtonWidth
|
||||||
|
width: DialogValues.dialogButtonWidth
|
||||||
|
visible: true
|
||||||
|
buttonIcon: qsTr("Create")
|
||||||
|
iconSize: DialogValues.defaultPixelSize
|
||||||
|
enabled: dialogBox.fieldsValid
|
||||||
|
iconFont: StudioTheme.Constants.font
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
dialogBox.accept();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Item { implicitWidth: 35 - DialogValues.defaultPadding }
|
||||||
|
} // RowLayout
|
||||||
|
} // Footer
|
||||||
|
} // ColumnLayout
|
||||||
|
} // Rectangle
|
||||||
|
}
|
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 8.9 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 9.5 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 9.6 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 9.6 KiB |
@@ -0,0 +1,453 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick.Window
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import StudioControls as SC
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: DialogValues.detailsPaneWidth
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
dialogBox.detailsLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onDestruction: {
|
||||||
|
dialogBox.detailsLoaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color: DialogValues.darkPaneColor
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Item {
|
||||||
|
x: DialogValues.detailsPanePadding // left padding
|
||||||
|
width: parent.width - DialogValues.detailsPanePadding * 2 // right padding
|
||||||
|
|
||||||
|
Column {
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: DialogValues.defaultPadding
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Details")
|
||||||
|
width: parent.width;
|
||||||
|
font.weight: Font.DemiBold
|
||||||
|
font.pixelSize: DialogValues.paneTitlePixelSize
|
||||||
|
lineHeight: DialogValues.paneTitleLineHeight
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
color: DialogValues.textColor
|
||||||
|
}
|
||||||
|
|
||||||
|
SC.TextField {
|
||||||
|
id: projectNameTextField
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
translationIndicatorVisible: false
|
||||||
|
text: dialogBox.projectName
|
||||||
|
width: parent.width
|
||||||
|
color: DialogValues.textColor
|
||||||
|
selectByMouse: true
|
||||||
|
|
||||||
|
font.pixelSize: DialogValues.paneTitlePixelSize
|
||||||
|
}
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: dialogBox
|
||||||
|
property: "projectName"
|
||||||
|
value: projectNameTextField.text
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { width: parent.width; height: DialogValues.narrowSpacing(11) }
|
||||||
|
|
||||||
|
RowLayout { // Project location
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
SC.TextField {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
id: projectLocationTextField
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
translationIndicatorVisible: false
|
||||||
|
text: dialogBox.projectLocation
|
||||||
|
color: DialogValues.textColor
|
||||||
|
selectByMouse: true
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
}
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: dialogBox
|
||||||
|
property: "projectLocation"
|
||||||
|
value: projectLocationTextField.text
|
||||||
|
}
|
||||||
|
|
||||||
|
SC.AbstractButton {
|
||||||
|
implicitWidth: 30
|
||||||
|
iconSize: 20
|
||||||
|
visible: true
|
||||||
|
buttonIcon: "…"
|
||||||
|
iconFont: StudioTheme.Constants.font
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
var newLocation = dialogBox.chooseProjectLocation()
|
||||||
|
if (newLocation)
|
||||||
|
projectLocationTextField.text = newLocation
|
||||||
|
}
|
||||||
|
} // SC.AbstractButton
|
||||||
|
} // Project location RowLayout
|
||||||
|
|
||||||
|
Item { width: parent.width; height: DialogValues.narrowSpacing(7) }
|
||||||
|
|
||||||
|
RowLayout { // StatusMessage
|
||||||
|
width: parent.width
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: statusIcon
|
||||||
|
asynchronous: false
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: statusMessage
|
||||||
|
text: dialogBox.statusMessage
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
lineHeight: DialogValues.defaultLineHeight
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
color: DialogValues.textColor
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
elide: Text.ElideRight
|
||||||
|
maximumLineCount: 3
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
name: "warning"
|
||||||
|
when: dialogBox.statusType === "warning"
|
||||||
|
PropertyChanges {
|
||||||
|
target: statusMessage
|
||||||
|
color: DialogValues.textWarning
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: statusIcon
|
||||||
|
source: "image://newprojectdialog_library/status-warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
State {
|
||||||
|
name: "error"
|
||||||
|
when: dialogBox.statusType === "error"
|
||||||
|
PropertyChanges {
|
||||||
|
target: statusMessage
|
||||||
|
color: DialogValues.textError
|
||||||
|
}
|
||||||
|
PropertyChanges {
|
||||||
|
target: statusIcon
|
||||||
|
source: "image://newprojectdialog_library/status-error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
} // Text
|
||||||
|
} // RowLayout
|
||||||
|
|
||||||
|
SC.CheckBox {
|
||||||
|
id: defaultLocationCheckbox
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
text: qsTr("Use as default project location")
|
||||||
|
checked: false
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
}
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: dialogBox
|
||||||
|
property: "saveAsDefaultLocation"
|
||||||
|
value: defaultLocationCheckbox.checked
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle { width: parent.width; height: 1; color: DialogValues.dividerlineColor }
|
||||||
|
|
||||||
|
SC.ComboBox { // Screen Size ComboBox
|
||||||
|
id: screenSizeComboBox
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
currentIndex: 1
|
||||||
|
model: screenSizeModel
|
||||||
|
textRole: "display"
|
||||||
|
width: parent.width
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
|
||||||
|
onActivated: (index) => {
|
||||||
|
// NOTE: item 0 is activated when the screenSizeModel is reset
|
||||||
|
dialogBox.setScreenSizeIndex(index);
|
||||||
|
|
||||||
|
var r = screenSizeModel.screenSizes(index);
|
||||||
|
widthTextField.text = r.width;
|
||||||
|
heightTextField.text = r.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: screenSizeModel
|
||||||
|
function onModelReset() {
|
||||||
|
screenSizeComboBox.activated(screenSizeComboBox.currentIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // Screen Size ComboBox
|
||||||
|
|
||||||
|
GridLayout { // orientation + width + height
|
||||||
|
width: parent.width
|
||||||
|
height: 85
|
||||||
|
|
||||||
|
columns: 4
|
||||||
|
rows: 2
|
||||||
|
|
||||||
|
columnSpacing: 10
|
||||||
|
rowSpacing: 10
|
||||||
|
|
||||||
|
// header items
|
||||||
|
Text {
|
||||||
|
text: qsTr("Width")
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
lineHeight: DialogValues.defaultLineHeight
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
color: DialogValues.textColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Height")
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
lineHeight: DialogValues.defaultLineHeight
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
color: DialogValues.textColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { Layout.fillWidth: true }
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Orientation")
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
lineHeight: DialogValues.defaultLineHeight
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
color: DialogValues.textColor
|
||||||
|
}
|
||||||
|
|
||||||
|
// content items
|
||||||
|
SC.TextField {
|
||||||
|
id: widthTextField
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
translationIndicatorVisible: false
|
||||||
|
implicitWidth: 50
|
||||||
|
color: DialogValues.textColor
|
||||||
|
selectByMouse: true
|
||||||
|
validator: IntValidator { bottom: 1; top: 100000; }
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
var height = heightTextField.text ? parseInt(heightTextField.text) : 0
|
||||||
|
var width = text ? parseInt(text) : 0
|
||||||
|
|
||||||
|
if (width >= height)
|
||||||
|
orientationButton.setHorizontal()
|
||||||
|
else
|
||||||
|
orientationButton.setVertical()
|
||||||
|
}
|
||||||
|
} // Width Text Field
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: dialogBox
|
||||||
|
property: "customWidth"
|
||||||
|
value: widthTextField.text
|
||||||
|
}
|
||||||
|
|
||||||
|
SC.TextField {
|
||||||
|
id: heightTextField
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
translationIndicatorVisible: false
|
||||||
|
implicitWidth: 50
|
||||||
|
color: DialogValues.textColor
|
||||||
|
selectByMouse: true
|
||||||
|
validator: IntValidator { bottom: 1; top: 100000; }
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
var height = text ? parseInt(text) : 0
|
||||||
|
var width = widthTextField.text ? parseInt(widthTextField.text) : 0
|
||||||
|
|
||||||
|
if (width >= height)
|
||||||
|
orientationButton.setHorizontal()
|
||||||
|
else
|
||||||
|
orientationButton.setVertical()
|
||||||
|
}
|
||||||
|
} // Height Text Field
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: dialogBox
|
||||||
|
property: "customHeight"
|
||||||
|
value: heightTextField.text
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { Layout.fillWidth: true }
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: orientationButton
|
||||||
|
implicitWidth: 100
|
||||||
|
implicitHeight: 50
|
||||||
|
|
||||||
|
checked: false
|
||||||
|
hoverEnabled: false
|
||||||
|
background: Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
color: "transparent"
|
||||||
|
|
||||||
|
Row {
|
||||||
|
Item {
|
||||||
|
width: orientationButton.width / 2
|
||||||
|
height: orientationButton.height
|
||||||
|
Rectangle {
|
||||||
|
id: horizontalBar
|
||||||
|
color: "white"
|
||||||
|
width: parent.width
|
||||||
|
height: orientationButton.height / 2
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: orientationButton.width / 4
|
||||||
|
height: orientationButton.height
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: verticalBar
|
||||||
|
width: orientationButton.width / 4
|
||||||
|
height: orientationButton.height
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (widthTextField.text && heightTextField.text) {
|
||||||
|
[widthTextField.text, heightTextField.text] = [heightTextField.text, widthTextField.text];
|
||||||
|
|
||||||
|
checked = !checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setHorizontal() {
|
||||||
|
checked = false
|
||||||
|
horizontalBar.color = DialogValues.textColorInteraction
|
||||||
|
verticalBar.color = "white"
|
||||||
|
}
|
||||||
|
|
||||||
|
function setVertical() {
|
||||||
|
checked = true
|
||||||
|
horizontalBar.color = "white"
|
||||||
|
verticalBar.color = DialogValues.textColorInteraction
|
||||||
|
}
|
||||||
|
} // Orientation button
|
||||||
|
|
||||||
|
} // GridLayout: orientation + width + height
|
||||||
|
|
||||||
|
Rectangle { width: parent.width; height: 1; color: DialogValues.dividerlineColor }
|
||||||
|
|
||||||
|
SC.Section {
|
||||||
|
width: parent.width
|
||||||
|
caption: qsTr("Advanced")
|
||||||
|
captionPixelSize: DialogValues.defaultPixelSize
|
||||||
|
captionColor: DialogValues.darkPaneColor
|
||||||
|
captionTextColor: DialogValues.textColor
|
||||||
|
leftPadding: 0
|
||||||
|
expanded: true
|
||||||
|
visible: dialogBox.haveVirtualKeyboard || dialogBox.haveTargetQtVersion
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: DialogValues.defaultPadding
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
/* We need a spacer of -10 in order to have actual 18px spacing between
|
||||||
|
* section bottom and the checkbox. Otherwise, with Column spacing set to
|
||||||
|
* 18, without a spacer, the default space to the first item would be 10,
|
||||||
|
* for some reason. */
|
||||||
|
Item { width: parent.width; height: -10 }
|
||||||
|
|
||||||
|
SC.CheckBox {
|
||||||
|
id: useQtVirtualKeyboard
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
text: qsTr("Use Qt Virtual Keyboard")
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
checked: dialogBox.useVirtualKeyboard
|
||||||
|
visible: dialogBox.haveVirtualKeyboard
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout { // Target Qt Version
|
||||||
|
width: parent.width
|
||||||
|
visible: dialogBox.haveTargetQtVersion
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: "Target Qt Version:"
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
lineHeight: DialogValues.defaultLineHeight
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
color: DialogValues.textColor
|
||||||
|
}
|
||||||
|
|
||||||
|
SC.ComboBox { // Target Qt Version ComboBox
|
||||||
|
id: qtVersionComboBox
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
implicitWidth: 70
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
currentIndex: 1
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
|
||||||
|
model: ListModel {
|
||||||
|
ListElement {
|
||||||
|
name: "Qt 5"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Qt 6"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
onActivated: (index) => {
|
||||||
|
dialogBox.setTargetQtVersion(index)
|
||||||
|
}
|
||||||
|
} // Target Qt Version ComboBox
|
||||||
|
|
||||||
|
} // RowLayout
|
||||||
|
} // Column
|
||||||
|
} // SC.Section
|
||||||
|
|
||||||
|
Binding {
|
||||||
|
target: dialogBox
|
||||||
|
property: "useVirtualKeyboard"
|
||||||
|
value: useQtVirtualKeyboard.checked
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Column
|
||||||
|
} // Item
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,83 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
pragma Singleton
|
||||||
|
import QtQml
|
||||||
|
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
readonly property int dialogWidth: 1522
|
||||||
|
readonly property int dialogHeight: 994
|
||||||
|
readonly property int projectViewMinimumWidth: 600
|
||||||
|
readonly property int projectViewMinimumHeight: projectViewHeight
|
||||||
|
readonly property int dialogContentHeight: projectViewHeight + 300 // i.e. dialog without header and footer
|
||||||
|
readonly property int loadedPanesWidth: detailsPaneWidth + stylesPaneWidth
|
||||||
|
readonly property int detailsPaneWidth: 330 + detailsPanePadding * 2
|
||||||
|
readonly property int stylesPaneWidth: styleImageWidth + stylesPanePadding * 2 + styleImageBorderWidth * 2 // i.e. 240px
|
||||||
|
readonly property int detailsPanePadding: 18
|
||||||
|
readonly property int stylesPanePadding: 18
|
||||||
|
readonly property int defaultPadding: 18
|
||||||
|
|
||||||
|
readonly property int styleImageWidth: 200
|
||||||
|
readonly property int styleImageBorderWidth: 2
|
||||||
|
readonly property int footerHeight: 73
|
||||||
|
readonly property int projectItemWidth: 144
|
||||||
|
readonly property int projectItemHeight: 144
|
||||||
|
readonly property int projectViewHeight: projectItemHeight * 2 + projectViewHeaderHeight
|
||||||
|
readonly property int projectViewHeaderHeight: 38
|
||||||
|
|
||||||
|
readonly property int dialogButtonWidth: 100
|
||||||
|
|
||||||
|
readonly property int loadedPanesHeight: dialogContentHeight
|
||||||
|
readonly property int detailsPaneHeight: dialogContentHeight
|
||||||
|
|
||||||
|
readonly property string darkPaneColor: StudioTheme.Values.themeBackgroundColorNormal
|
||||||
|
readonly property string lightPaneColor: StudioTheme.Values.themeBackgroundColorAlternate
|
||||||
|
|
||||||
|
readonly property string textColor: StudioTheme.Values.themeTabInactiveText
|
||||||
|
readonly property string textColorInteraction: StudioTheme.Values.themeInteraction
|
||||||
|
readonly property string dividerlineColor: StudioTheme.Values.themeTextColorDisabled
|
||||||
|
readonly property string textError: StudioTheme.Values.themeError
|
||||||
|
readonly property string textWarning: StudioTheme.Values.themeWarning
|
||||||
|
|
||||||
|
readonly property real defaultPixelSize: 14
|
||||||
|
readonly property real defaultLineHeight: 21
|
||||||
|
readonly property real viewHeaderPixelSize: 16
|
||||||
|
readonly property real viewHeaderLineHeight: 24
|
||||||
|
readonly property real paneTitlePixelSize: 18
|
||||||
|
readonly property real paneTitleLineHeight: 27
|
||||||
|
|
||||||
|
// for a spacer item
|
||||||
|
function narrowSpacing(value, layoutSpacing = DialogValues.defaultPadding) {
|
||||||
|
/* e.g. if we want narrow spacing value = 11, then for the spacer item residing inside a
|
||||||
|
layout with spacing set to 18, we need to realize the fact that by adding the spacer
|
||||||
|
item, we already have 18 * 2 spacing added implicitly (i.e. spacing before the spacer
|
||||||
|
item and spacing after it). So we have to subtract 2 x layout spacing before setting
|
||||||
|
our own, narrower, spacing.
|
||||||
|
*/
|
||||||
|
return -layoutSpacing -layoutSpacing + value
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,198 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick.Window
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
|
GridView {
|
||||||
|
id: projectView
|
||||||
|
|
||||||
|
required property Item loader
|
||||||
|
|
||||||
|
header: TabBar {
|
||||||
|
id: tabBar
|
||||||
|
width: parent.width
|
||||||
|
height: DialogValues.projectViewHeaderHeight
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: DialogValues.lightPaneColor
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: categoryModel
|
||||||
|
|
||||||
|
TabButton {
|
||||||
|
padding: 0
|
||||||
|
|
||||||
|
width: headerText.contentWidth + 36
|
||||||
|
|
||||||
|
background: Item { // TabButton background
|
||||||
|
Rectangle { // bottom strip
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
width: headerText.contentWidth
|
||||||
|
height: 6
|
||||||
|
radius: 10
|
||||||
|
color: tabBar.currentIndex === index ? DialogValues.textColorInteraction
|
||||||
|
: "transparent"
|
||||||
|
}
|
||||||
|
} // TabButton background
|
||||||
|
|
||||||
|
implicitHeight: headerText.height + DialogValues.defaultPadding - 7
|
||||||
|
|
||||||
|
contentItem: Item {
|
||||||
|
Column {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: headerText
|
||||||
|
color: tabBar.currentIndex == index ? DialogValues.textColorInteraction
|
||||||
|
: DialogValues.textColor
|
||||||
|
text: name
|
||||||
|
width: parent.width
|
||||||
|
font.weight: Font.DemiBold
|
||||||
|
font.pixelSize: DialogValues.viewHeaderPixelSize
|
||||||
|
lineHeight: DialogValues.viewHeaderLineHeight
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
Item { width: parent.width; height: 11; }
|
||||||
|
} // Column
|
||||||
|
} // Item
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
projectModel.setPage(index)
|
||||||
|
projectView.currentIndex = 0
|
||||||
|
projectView.currentIndexChanged()
|
||||||
|
}
|
||||||
|
} // TabButton
|
||||||
|
} // Repeater
|
||||||
|
} // Header - TabBar
|
||||||
|
|
||||||
|
cellWidth: DialogValues.projectItemWidth
|
||||||
|
cellHeight: DialogValues.projectItemHeight
|
||||||
|
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
|
||||||
|
children: [
|
||||||
|
Rectangle {
|
||||||
|
color: DialogValues.darkPaneColor
|
||||||
|
anchors.fill: parent
|
||||||
|
z: -1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
model: projectModel
|
||||||
|
|
||||||
|
// called by onModelReset and when user clicks on an item, or when the header item is changed.
|
||||||
|
onCurrentIndexChanged: {
|
||||||
|
dialogBox.selectedProject = projectView.currentIndex
|
||||||
|
var source = dialogBox.currentProjectQmlPath()
|
||||||
|
loader.source = source
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: projectModel
|
||||||
|
|
||||||
|
// called when data is set (setWizardFactories)
|
||||||
|
function onModelReset() {
|
||||||
|
currentIndex = 0
|
||||||
|
currentIndexChanged()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
id: delegate
|
||||||
|
|
||||||
|
width: DialogValues.projectItemWidth
|
||||||
|
height: DialogValues.projectItemHeight
|
||||||
|
|
||||||
|
function fontIconCode(index) {
|
||||||
|
var code = projectModel.fontIconCode(index)
|
||||||
|
return code ? code : StudioTheme.Constants.wizardsUnknown
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: projectTypeIcon
|
||||||
|
text: fontIconCode(index)
|
||||||
|
color: DialogValues.textColor
|
||||||
|
width: parent.width
|
||||||
|
height: DialogValues.projectItemHeight / 2
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignBottom
|
||||||
|
renderType: Text.NativeRendering
|
||||||
|
font.pixelSize: 65
|
||||||
|
font.family: StudioTheme.Constants.iconFont.family
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: projectTypeLabel
|
||||||
|
color: DialogValues.textColor
|
||||||
|
|
||||||
|
text: name
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
lineHeight: DialogValues.defaultLineHeight
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
width: parent.width
|
||||||
|
height: DialogValues.projectItemHeight / 2
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignTop
|
||||||
|
}
|
||||||
|
} // Column
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
delegate.GridView.view.currentIndex = index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
states: [
|
||||||
|
State {
|
||||||
|
when: delegate.GridView.isCurrentItem
|
||||||
|
PropertyChanges {
|
||||||
|
target: projectTypeLabel
|
||||||
|
color: DialogValues.textColorInteraction
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyChanges {
|
||||||
|
target: projectTypeIcon
|
||||||
|
color: DialogValues.textColorInteraction
|
||||||
|
}
|
||||||
|
} // State
|
||||||
|
]
|
||||||
|
} // ItemDelegate
|
||||||
|
} // GridView
|
@@ -0,0 +1,183 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick.Window
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import StudioControls as SC
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: DialogValues.stylesPaneWidth
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
dialogBox.stylesLoaded = true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: roleNames is called before the backend model (in the proxy class StyleModel) is
|
||||||
|
* loaded, which may be buggy. But I found no way to force refresh the model, so as to
|
||||||
|
* reload the role names afterwards. setting styleModel.dynamicRoles doesn't appear to do
|
||||||
|
* anything.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onDestruction: {
|
||||||
|
dialogBox.stylesLoaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color: DialogValues.lightPaneColor
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Item {
|
||||||
|
x: DialogValues.stylesPanePadding // left padding
|
||||||
|
width: parent.width - DialogValues.stylesPanePadding * 2 // right padding
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 5
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: styleTitleText
|
||||||
|
text: qsTr("Style")
|
||||||
|
width: parent.width;
|
||||||
|
font.weight: Font.DemiBold
|
||||||
|
font.pixelSize: DialogValues.paneTitlePixelSize
|
||||||
|
lineHeight: DialogValues.paneTitleLineHeight
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
color: DialogValues.textColor
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
text = qsTr("Style") + " (" + styleModel.rowCount() + ")"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SC.ComboBox { // Style Filter ComboBox
|
||||||
|
actionIndicatorVisible: false
|
||||||
|
currentIndex: 0
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "value"
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
|
||||||
|
model: ListModel {
|
||||||
|
ListElement { text: qsTr("All"); value: "all" }
|
||||||
|
ListElement { text: qsTr("Light"); value: "light" }
|
||||||
|
ListElement { text: qsTr("Dark"); value: "dark" }
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitWidth: parent.width
|
||||||
|
|
||||||
|
onActivated: (index) => {
|
||||||
|
styleModel.filter(currentValue.toLowerCase());
|
||||||
|
styleTitleText.refresh();
|
||||||
|
}
|
||||||
|
} // Style Filter ComboBox
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: stylesList
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
clip: true
|
||||||
|
model: styleModel
|
||||||
|
|
||||||
|
focus: true
|
||||||
|
boundsBehavior: Flickable.StopAtBounds
|
||||||
|
|
||||||
|
highlightFollowsCurrentItem: false
|
||||||
|
|
||||||
|
onCurrentIndexChanged: {
|
||||||
|
if (styleModel.rowCount() > 0)
|
||||||
|
dialogBox.styleIndex = stylesList.currentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
id: delegateId
|
||||||
|
height: styleImage.height + DialogValues.styleImageBorderWidth + styleText.height + 1
|
||||||
|
width: stylesList.width
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: DialogValues.lightPaneColor
|
||||||
|
|
||||||
|
Column {
|
||||||
|
spacing: 0
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
border.color: index == stylesList.currentIndex ? DialogValues.textColorInteraction : "transparent"
|
||||||
|
border.width: index == stylesList.currentIndex ? DialogValues.styleImageBorderWidth : 0
|
||||||
|
color: "transparent"
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height - styleText.height
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: styleImage
|
||||||
|
asynchronous: false
|
||||||
|
source: "image://newprojectdialog_library/" + styleModel.iconId(model.index)
|
||||||
|
width: 200
|
||||||
|
height: 262
|
||||||
|
x: DialogValues.styleImageBorderWidth
|
||||||
|
y: DialogValues.styleImageBorderWidth
|
||||||
|
}
|
||||||
|
} // Rectangle
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: styleText
|
||||||
|
text: model.display
|
||||||
|
font.pixelSize: DialogValues.defaultPixelSize
|
||||||
|
lineHeight: DialogValues.defaultLineHeight
|
||||||
|
height: 18
|
||||||
|
lineHeightMode: Text.FixedHeight
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
width: parent.width
|
||||||
|
color: DialogValues.textColor
|
||||||
|
}
|
||||||
|
} // Column
|
||||||
|
} // Rectangle
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
stylesList.currentIndex = index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: styleModel
|
||||||
|
function onModelReset() {
|
||||||
|
stylesList.currentIndex = dialogBox.styleIndex;
|
||||||
|
stylesList.currentIndexChanged();
|
||||||
|
styleTitleText.refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // ListView
|
||||||
|
} // ColumnLayout
|
||||||
|
} // Parent Item
|
||||||
|
} // Rectangle
|
||||||
|
}
|
@@ -0,0 +1,4 @@
|
|||||||
|
singleton DialogValues 1.0 DialogValues.qml
|
||||||
|
Details 1.0 Details.qml
|
||||||
|
Styles 1.0 Styles.qml
|
||||||
|
NewProjectView 1.0 NewProjectView.qml
|
@@ -0,0 +1,48 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2021 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
import QtQuick.Window
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import newprojectdialog
|
||||||
|
|
||||||
|
Item {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Details {
|
||||||
|
height: parent.height
|
||||||
|
}
|
||||||
|
|
||||||
|
Styles {
|
||||||
|
height: parent.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1 @@
|
|||||||
|
DefaultProject 1.0 DefaultProject.qml
|
@@ -30,6 +30,9 @@ import StudioTheme 1.0 as StudioTheme
|
|||||||
Item {
|
Item {
|
||||||
id: section
|
id: section
|
||||||
property alias caption: label.text
|
property alias caption: label.text
|
||||||
|
property alias captionPixelSize: label.font.pixelSize
|
||||||
|
property alias captionColor: header.color
|
||||||
|
property alias captionTextColor: label.color
|
||||||
property int leftPadding: 8
|
property int leftPadding: 8
|
||||||
property int topPadding: 4
|
property int topPadding: 4
|
||||||
property int rightPadding: 0
|
property int rightPadding: 0
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
import QtQuick 2.10
|
import QtQuick 2.15
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
readonly property int width: 1920
|
readonly property int width: 1920
|
||||||
@@ -95,84 +95,92 @@ QtObject {
|
|||||||
readonly property string distributeSpacingHorizontal: "\u005A"
|
readonly property string distributeSpacingHorizontal: "\u005A"
|
||||||
readonly property string distributeSpacingVertical: "\u005B"
|
readonly property string distributeSpacingVertical: "\u005B"
|
||||||
readonly property string distributeTop: "\u005C"
|
readonly property string distributeTop: "\u005C"
|
||||||
readonly property string edit: "\u005D"
|
readonly property string download: "\u005D"
|
||||||
readonly property string eyeDropper: "\u005E"
|
readonly property string edit: "\u005E"
|
||||||
readonly property string flowAction: "\u005F"
|
readonly property string eyeDropper: "\u005F"
|
||||||
readonly property string flowTransition: "\u0060"
|
readonly property string favorite: "\u0060"
|
||||||
readonly property string fontStyleBold: "\u0061"
|
readonly property string flowAction: "\u0061"
|
||||||
readonly property string fontStyleItalic: "\u0062"
|
readonly property string flowTransition: "\u0062"
|
||||||
readonly property string fontStyleStrikethrough: "\u0063"
|
readonly property string fontStyleBold: "\u0063"
|
||||||
readonly property string fontStyleUnderline: "\u0064"
|
readonly property string fontStyleItalic: "\u0064"
|
||||||
readonly property string gradient: "\u0065"
|
readonly property string fontStyleStrikethrough: "\u0065"
|
||||||
readonly property string gridView: "\u0066"
|
readonly property string fontStyleUnderline: "\u0066"
|
||||||
readonly property string idAliasOff: "\u0067"
|
readonly property string gradient: "\u0067"
|
||||||
readonly property string idAliasOn: "\u0068"
|
readonly property string gridView: "\u0068"
|
||||||
readonly property string infinity: "\u0069"
|
readonly property string idAliasOff: "\u0069"
|
||||||
readonly property string keyframe: "\u006A"
|
readonly property string idAliasOn: "\u006A"
|
||||||
readonly property string linkTriangle: "\u006B"
|
readonly property string infinity: "\u006B"
|
||||||
readonly property string linked: "\u006C"
|
readonly property string keyframe: "\u006C"
|
||||||
readonly property string listView: "\u006D"
|
readonly property string linkTriangle: "\u006D"
|
||||||
readonly property string lockOff: "\u006E"
|
readonly property string linked: "\u006E"
|
||||||
readonly property string lockOn: "\u006F"
|
readonly property string listView: "\u006F"
|
||||||
readonly property string mergeCells: "\u0070"
|
readonly property string lockOff: "\u0070"
|
||||||
readonly property string minus: "\u0071"
|
readonly property string lockOn: "\u0071"
|
||||||
readonly property string mirror: "\u0072"
|
readonly property string mergeCells: "\u0072"
|
||||||
readonly property string orientation: "\u0073"
|
readonly property string minus: "\u0073"
|
||||||
readonly property string paddingEdge: "\u0074"
|
readonly property string mirror: "\u0074"
|
||||||
readonly property string paddingFrame: "\u0075"
|
readonly property string orientation: "\u0075"
|
||||||
readonly property string pasteStyle: "\u0076"
|
readonly property string paddingEdge: "\u0076"
|
||||||
readonly property string pause: "\u0077"
|
readonly property string paddingFrame: "\u0077"
|
||||||
readonly property string pin: "\u0078"
|
readonly property string pasteStyle: "\u0078"
|
||||||
readonly property string play: "\u0079"
|
readonly property string pause: "\u0079"
|
||||||
readonly property string plus: "\u007A"
|
readonly property string pin: "\u007A"
|
||||||
readonly property string promote: "\u007B"
|
readonly property string play: "\u007B"
|
||||||
readonly property string readOnly: "\u007C"
|
readonly property string plus: "\u007C"
|
||||||
readonly property string redo: "\u007D"
|
readonly property string promote: "\u007D"
|
||||||
readonly property string rotationFill: "\u007E"
|
readonly property string readOnly: "\u007E"
|
||||||
readonly property string rotationOutline: "\u007F"
|
readonly property string redo: "\u007F"
|
||||||
readonly property string search: "\u0080"
|
readonly property string rotationFill: "\u0080"
|
||||||
readonly property string sectionToggle: "\u0081"
|
readonly property string rotationOutline: "\u0081"
|
||||||
readonly property string splitColumns: "\u0082"
|
readonly property string search: "\u0082"
|
||||||
readonly property string splitRows: "\u0083"
|
readonly property string sectionToggle: "\u0083"
|
||||||
readonly property string startNode: "\u0084"
|
readonly property string splitColumns: "\u0084"
|
||||||
readonly property string testIcon: "\u0085"
|
readonly property string splitRows: "\u0085"
|
||||||
readonly property string textAlignBottom: "\u0086"
|
readonly property string startNode: "\u0086"
|
||||||
readonly property string textAlignCenter: "\u0087"
|
readonly property string testIcon: "\u0087"
|
||||||
readonly property string textAlignJustified: "\u0088"
|
readonly property string textAlignBottom: "\u0088"
|
||||||
readonly property string textAlignLeft: "\u0089"
|
readonly property string textAlignCenter: "\u0089"
|
||||||
readonly property string textAlignMiddle: "\u008A"
|
readonly property string textAlignJustified: "\u008A"
|
||||||
readonly property string textAlignRight: "\u008B"
|
readonly property string textAlignLeft: "\u008B"
|
||||||
readonly property string textAlignTop: "\u008C"
|
readonly property string textAlignMiddle: "\u008C"
|
||||||
readonly property string textBulletList: "\u008D"
|
readonly property string textAlignRight: "\u008D"
|
||||||
readonly property string textFullJustification: "\u008E"
|
readonly property string textAlignTop: "\u008E"
|
||||||
readonly property string textNumberedList: "\u008F"
|
readonly property string textBulletList: "\u008F"
|
||||||
readonly property string tickIcon: "\u0090"
|
readonly property string textFullJustification: "\u0090"
|
||||||
readonly property string transparent: "\u0091"
|
readonly property string textNumberedList: "\u0091"
|
||||||
readonly property string triState: "\u0092"
|
readonly property string tickIcon: "\u0092"
|
||||||
readonly property string triangleArcA: "\u0093"
|
readonly property string translationCreateFiles: "\u0093"
|
||||||
readonly property string triangleArcB: "\u0094"
|
readonly property string translationCreateReport: "\u0094"
|
||||||
readonly property string triangleCornerA: "\u0095"
|
readonly property string translationExport: "\u0095"
|
||||||
readonly property string triangleCornerB: "\u0096"
|
readonly property string translationImport: "\u0096"
|
||||||
readonly property string unLinked: "\u0097"
|
readonly property string translationSelectLanguages: "\u0097"
|
||||||
readonly property string undo: "\u0098"
|
readonly property string translationTest: "\u0098"
|
||||||
readonly property string unpin: "\u0099"
|
readonly property string transparent: "\u0099"
|
||||||
readonly property string upDownIcon: "\u009A"
|
readonly property string triState: "\u009A"
|
||||||
readonly property string upDownSquare2: "\u009B"
|
readonly property string triangleArcA: "\u009B"
|
||||||
readonly property string visibilityOffBroken: "\u009C" // visibilityOff
|
readonly property string triangleArcB: "\u009C"
|
||||||
readonly property string visibilityOff: "\u009D" // visibilityOff2
|
readonly property string triangleCornerA: "\u009D"
|
||||||
readonly property string visibilityOn: "\u009E"
|
readonly property string triangleCornerB: "\u009E"
|
||||||
readonly property string wildcard: "\u009F"
|
readonly property string unLinked: "\u009F"
|
||||||
readonly property string wizardsAutomotive: "\u00A0"
|
readonly property string undo: "\u00A0"
|
||||||
readonly property string wizardsDesktop: "\u00A1"
|
readonly property string unpin: "\u00A1"
|
||||||
readonly property string wizardsGeneric: "\u00A2"
|
readonly property string upDownIcon: "\u00A2"
|
||||||
readonly property string wizardsMcuEmpty: "\u00A3"
|
readonly property string upDownSquare2: "\u00A3"
|
||||||
readonly property string wizardsMcuGraph: "\u00A4"
|
readonly property string visibilityOffBroken: "\u00A4" // visibilityOff
|
||||||
readonly property string wizardsMobile: "\u00A5"
|
readonly property string visibilityOff: "\u00A5" // visibilityOff2
|
||||||
readonly property string wizardsUnknown: "\u00A6"
|
readonly property string visibilityOn: "\u00A6"
|
||||||
readonly property string zoomAll: "\u00A7"
|
readonly property string wildcard: "\u00A7"
|
||||||
readonly property string zoomIn: "\u00A8"
|
readonly property string wizardsAutomotive: "\u00A8"
|
||||||
readonly property string zoomOut: "\u00A9"
|
readonly property string wizardsDesktop: "\u00A9"
|
||||||
readonly property string zoomSelection: "\u00AA"
|
readonly property string wizardsGeneric: "\u00AA"
|
||||||
|
readonly property string wizardsMcuEmpty: "\u00AB"
|
||||||
|
readonly property string wizardsMcuGraph: "\u00AC"
|
||||||
|
readonly property string wizardsMobile: "\u00AD"
|
||||||
|
readonly property string wizardsUnknown: "\u00AE"
|
||||||
|
readonly property string zoomAll: "\u00AF"
|
||||||
|
readonly property string zoomIn: "\u00B0"
|
||||||
|
readonly property string zoomOut: "\u00B1"
|
||||||
|
readonly property string zoomSelection: "\u00B2"
|
||||||
|
|
||||||
readonly property font iconFont: Qt.font({
|
readonly property font iconFont: Qt.font({
|
||||||
"family": controlIcons.name,
|
"family": controlIcons.name,
|
||||||
|
2
src/libs/3rdparty/cplusplus/Lexer.cpp
vendored
@@ -1034,7 +1034,7 @@ void Lexer::scanPreprocessorNumber(Token *tok, bool dotAlreadySkipped)
|
|||||||
yyinp();
|
yyinp();
|
||||||
if (_yychar == '+' || _yychar == '-')
|
if (_yychar == '+' || _yychar == '-')
|
||||||
yyinp();
|
yyinp();
|
||||||
} else if (std::isalnum(_yychar) || _yychar == '_' || _yychar == '.') {
|
} else if (std::isalnum(_yychar) || (_yychar == '\'') || _yychar == '_' || _yychar == '.') {
|
||||||
yyinp();
|
yyinp();
|
||||||
} else {
|
} else {
|
||||||
scanOptionalUserDefinedLiteral(tok);
|
scanOptionalUserDefinedLiteral(tok);
|
||||||
|
@@ -910,7 +910,7 @@ bool ResolveExpression::visit(CallAST *ast)
|
|||||||
if (Symbol *declaration = templateTy->declaration()) {
|
if (Symbol *declaration = templateTy->declaration()) {
|
||||||
if (Function *funTy = declaration->asFunction()) {
|
if (Function *funTy = declaration->asFunction()) {
|
||||||
if (maybeValidPrototype(funTy, actualArgumentCount))
|
if (maybeValidPrototype(funTy, actualArgumentCount))
|
||||||
addResult(funTy->returnType().simplified(), _scope);
|
addResult(funTy->returnType().simplified(), scope);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -136,6 +136,7 @@ static Utils::optional<Tool> unzipTool(const FilePath &src, const FilePath &dest
|
|||||||
const QString destStr = dest.toString();
|
const QString destStr = dest.toString();
|
||||||
const QString args = result.command.arguments().replace("%{src}", srcStr).replace("%{dest}", destStr);
|
const QString args = result.command.arguments().replace("%{src}", srcStr).replace("%{dest}", destStr);
|
||||||
result.command.setArguments(args);
|
result.command.setArguments(args);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
|
@@ -41,7 +41,7 @@ namespace Internal {
|
|||||||
|
|
||||||
bool currentAppearanceMatches(bool dark)
|
bool currentAppearanceMatches(bool dark)
|
||||||
{
|
{
|
||||||
#if __has_builtin(__builtin_available)
|
#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14)
|
||||||
if (__builtin_available(macOS 10.14, *)) {
|
if (__builtin_available(macOS 10.14, *)) {
|
||||||
auto appearance = [NSApp.effectiveAppearance
|
auto appearance = [NSApp.effectiveAppearance
|
||||||
bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]];
|
bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]];
|
||||||
|
@@ -57,7 +57,6 @@ add_subdirectory(scxmleditor)
|
|||||||
add_subdirectory(subversion)
|
add_subdirectory(subversion)
|
||||||
add_subdirectory(compilationdatabaseprojectmanager)
|
add_subdirectory(compilationdatabaseprojectmanager)
|
||||||
add_subdirectory(languageclient)
|
add_subdirectory(languageclient)
|
||||||
add_subdirectory(studiowelcome)
|
|
||||||
|
|
||||||
# Level 6:
|
# Level 6:
|
||||||
add_subdirectory(cmakeprojectmanager)
|
add_subdirectory(cmakeprojectmanager)
|
||||||
@@ -93,6 +92,7 @@ if (WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|||||||
set(qmldesigner_builddir ${PROJECT_BINARY_DIR}/qmldsgnr)
|
set(qmldesigner_builddir ${PROJECT_BINARY_DIR}/qmldsgnr)
|
||||||
endif()
|
endif()
|
||||||
add_subdirectory(qmldesigner ${qmldesigner_builddir})
|
add_subdirectory(qmldesigner ${qmldesigner_builddir})
|
||||||
|
add_subdirectory(studiowelcome)
|
||||||
add_subdirectory(qnx)
|
add_subdirectory(qnx)
|
||||||
add_subdirectory(webassembly)
|
add_subdirectory(webassembly)
|
||||||
add_subdirectory(mcusupport)
|
add_subdirectory(mcusupport)
|
||||||
|
@@ -562,6 +562,16 @@ FilePath AndroidConfig::gdbPathFromNdk(const Abi &abi, const FilePath &ndkLocati
|
|||||||
QString(QTC_HOST_EXE_SUFFIX)));
|
QString(QTC_HOST_EXE_SUFFIX)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilePath AndroidConfig::lldbPathFromNdk(const FilePath &ndkLocation) const
|
||||||
|
{
|
||||||
|
const FilePath path = ndkLocation.pathAppended(
|
||||||
|
QString("toolchains/llvm/prebuilt/%1/bin/lldb%2").arg(toolchainHostFromNdk(ndkLocation),
|
||||||
|
QString(QTC_HOST_EXE_SUFFIX)));
|
||||||
|
if (path.exists())
|
||||||
|
return path;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
FilePath AndroidConfig::makePathFromNdk(const FilePath &ndkLocation) const
|
FilePath AndroidConfig::makePathFromNdk(const FilePath &ndkLocation) const
|
||||||
{
|
{
|
||||||
return ndkLocation.pathAppended(
|
return ndkLocation.pathAppended(
|
||||||
@@ -1240,39 +1250,79 @@ static QString getMultiOrSingleAbiString(const QStringList &abis)
|
|||||||
return containsAllAbis(abis) ? "Multi-Abi" : abis.join(",");
|
return containsAllAbis(abis) ? "Multi-Abi" : abis.join(",");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const Debugger::DebuggerItem *existingDebugger(const FilePath &command,
|
||||||
|
Debugger::DebuggerEngineType type)
|
||||||
|
{
|
||||||
|
// check if the debugger is already registered, but ignoring the display name
|
||||||
|
const Debugger::DebuggerItem *existing = Debugger::DebuggerItemManager::findByCommand(command);
|
||||||
|
|
||||||
|
// Return existing debugger with same command
|
||||||
|
if (existing && existing->engineType() == type && existing->isAutoDetected())
|
||||||
|
return existing;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
static QVariant findOrRegisterDebugger(ToolChain *tc,
|
static QVariant findOrRegisterDebugger(ToolChain *tc,
|
||||||
const QStringList &abisList,
|
const QStringList &abisList,
|
||||||
bool customDebugger = false)
|
bool customDebugger = false)
|
||||||
{
|
{
|
||||||
const auto ¤tConfig = AndroidConfigurations::currentConfig();
|
const auto ¤tConfig = AndroidConfigurations::currentConfig();
|
||||||
const FilePath ndk = static_cast<AndroidToolChain *>(tc)->ndkLocation();
|
const FilePath ndk = static_cast<AndroidToolChain *>(tc)->ndkLocation();
|
||||||
const FilePath command = currentConfig.gdbPathFromNdk(tc->targetAbi(), ndk);
|
const FilePath lldbCommand = currentConfig.lldbPathFromNdk(ndk);
|
||||||
|
const Debugger::DebuggerItem *existingLldb = existingDebugger(lldbCommand,
|
||||||
|
Debugger::LldbEngineType);
|
||||||
|
// Return existing debugger with same command - prefer lldb (limit to sdk/ndk min version?)
|
||||||
|
if (existingLldb)
|
||||||
|
return existingLldb->id();
|
||||||
|
|
||||||
|
const FilePath gdbCommand = currentConfig.gdbPathFromNdk(tc->targetAbi(), ndk);
|
||||||
|
|
||||||
// check if the debugger is already registered, but ignoring the display name
|
// check if the debugger is already registered, but ignoring the display name
|
||||||
const Debugger::DebuggerItem *existing = Debugger::DebuggerItemManager::findByCommand(command);
|
const Debugger::DebuggerItem *existingGdb = existingDebugger(gdbCommand,
|
||||||
|
Debugger::GdbEngineType);
|
||||||
// Return existing debugger with same command
|
// Return existing debugger with same command
|
||||||
if (existing && existing->engineType() == Debugger::GdbEngineType
|
if (existingGdb)
|
||||||
&& existing->isAutoDetected()) {
|
return existingGdb->id();
|
||||||
return existing->id();
|
|
||||||
|
const QString mainName = AndroidConfigurations::tr("Android Debugger (%1, NDK %2)");
|
||||||
|
const QString custom = customDebugger ? QString{"Custom "} : QString{};
|
||||||
|
// debugger not found, register a new one
|
||||||
|
// check lldb
|
||||||
|
QVariant registeredLldb;
|
||||||
|
if (!lldbCommand.isEmpty()) {
|
||||||
|
Debugger::DebuggerItem debugger;
|
||||||
|
debugger.setCommand(lldbCommand);
|
||||||
|
debugger.setEngineType(Debugger::LldbEngineType);
|
||||||
|
debugger.setUnexpandedDisplayName(custom + mainName
|
||||||
|
.arg(getMultiOrSingleAbiString(allSupportedAbis()))
|
||||||
|
.arg(AndroidConfigurations::currentConfig().ndkVersion(ndk).toString())
|
||||||
|
+ ' ' + debugger.engineTypeName());
|
||||||
|
debugger.setAutoDetected(true);
|
||||||
|
debugger.reinitializeFromFile();
|
||||||
|
registeredLldb = Debugger::DebuggerItemManager::registerDebugger(debugger);
|
||||||
|
}
|
||||||
|
|
||||||
|
// we always have a value for gdb (but we shouldn't - we currently use a fallback)
|
||||||
|
if (!gdbCommand.exists()) {
|
||||||
|
if (!registeredLldb.isNull())
|
||||||
|
return registeredLldb;
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// debugger not found, register a new one
|
|
||||||
Debugger::DebuggerItem debugger;
|
Debugger::DebuggerItem debugger;
|
||||||
debugger.setCommand(command);
|
debugger.setCommand(gdbCommand);
|
||||||
debugger.setEngineType(Debugger::GdbEngineType);
|
debugger.setEngineType(Debugger::GdbEngineType);
|
||||||
|
|
||||||
// NDK 10 and older have multiple gdb versions per ABI, so check for that.
|
// NDK 10 and older have multiple gdb versions per ABI, so check for that.
|
||||||
const bool oldNdkVersion = currentConfig.ndkVersion(ndk) <= QVersionNumber{11};
|
const bool oldNdkVersion = currentConfig.ndkVersion(ndk) <= QVersionNumber{11};
|
||||||
QString mainName = AndroidConfigurations::tr("Android Debugger (%1, NDK %2)");
|
debugger.setUnexpandedDisplayName(custom + mainName
|
||||||
if (customDebugger)
|
|
||||||
mainName.prepend("Custom ");
|
|
||||||
debugger.setUnexpandedDisplayName(mainName
|
|
||||||
.arg(getMultiOrSingleAbiString(oldNdkVersion ? abisList : allSupportedAbis()))
|
.arg(getMultiOrSingleAbiString(oldNdkVersion ? abisList : allSupportedAbis()))
|
||||||
.arg(AndroidConfigurations::currentConfig().ndkVersion(ndk).toString()));
|
.arg(AndroidConfigurations::currentConfig().ndkVersion(ndk).toString())
|
||||||
|
+ ' ' + debugger.engineTypeName());
|
||||||
debugger.setAutoDetected(true);
|
debugger.setAutoDetected(true);
|
||||||
debugger.reinitializeFromFile();
|
debugger.reinitializeFromFile();
|
||||||
return Debugger::DebuggerItemManager::registerDebugger(debugger);
|
QVariant registeredGdb = Debugger::DebuggerItemManager::registerDebugger(debugger);
|
||||||
|
return registeredLldb.isNull() ? registeredGdb : registeredLldb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidConfigurations::registerCustomToolChainsAndDebuggers()
|
void AndroidConfigurations::registerCustomToolChainsAndDebuggers()
|
||||||
|
@@ -140,6 +140,7 @@ public:
|
|||||||
|
|
||||||
Utils::FilePath gdbPath(const ProjectExplorer::Abi &abi, const QtSupport::BaseQtVersion *qtVersion) const;
|
Utils::FilePath gdbPath(const ProjectExplorer::Abi &abi, const QtSupport::BaseQtVersion *qtVersion) const;
|
||||||
Utils::FilePath gdbPathFromNdk(const ProjectExplorer::Abi &abi, const Utils::FilePath &ndkLocation) const;
|
Utils::FilePath gdbPathFromNdk(const ProjectExplorer::Abi &abi, const Utils::FilePath &ndkLocation) const;
|
||||||
|
Utils::FilePath lldbPathFromNdk(const Utils::FilePath &ndkLocation) const;
|
||||||
Utils::FilePath makePathFromNdk(const Utils::FilePath &ndkLocation) const;
|
Utils::FilePath makePathFromNdk(const Utils::FilePath &ndkLocation) const;
|
||||||
|
|
||||||
Utils::FilePath keytoolPath() const;
|
Utils::FilePath keytoolPath() const;
|
||||||
|
@@ -428,7 +428,7 @@ void AndroidDeviceManager::updateDevicesList()
|
|||||||
void AndroidDeviceManager::updateDevicesListOnce()
|
void AndroidDeviceManager::updateDevicesListOnce()
|
||||||
{
|
{
|
||||||
if (!m_avdsFutureWatcher.isRunning() && m_androidConfig.adbToolPath().exists()) {
|
if (!m_avdsFutureWatcher.isRunning() && m_androidConfig.adbToolPath().exists()) {
|
||||||
m_avdsFutureWatcher.setFuture((new AndroidAvdManager)->avdList());
|
m_avdsFutureWatcher.setFuture(m_avdManager.avdList());
|
||||||
m_devicesFutureWatcher.setFuture(Utils::runAsync([this]() {
|
m_devicesFutureWatcher.setFuture(Utils::runAsync([this]() {
|
||||||
return m_androidConfig.connectedDevices();
|
return m_androidConfig.connectedDevices();
|
||||||
}));
|
}));
|
||||||
|
@@ -246,11 +246,6 @@ bool AndroidManager::isQtCreatorGenerated(const FilePath &deploymentFile)
|
|||||||
return QJsonDocument::fromJson(f.readAll()).object()["_description"].toString() == qtcSignature;
|
return QJsonDocument::fromJson(f.readAll()).object()["_description"].toString() == qtcSignature;
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePath AndroidManager::dirPath(const Target *target)
|
|
||||||
{
|
|
||||||
return androidBuildDirectory(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
FilePath AndroidManager::androidBuildDirectory(const Target *target)
|
FilePath AndroidManager::androidBuildDirectory(const Target *target)
|
||||||
{
|
{
|
||||||
return buildDirectory(target) / Constants::ANDROID_BUILD_DIRECTORY;
|
return buildDirectory(target) / Constants::ANDROID_BUILD_DIRECTORY;
|
||||||
|
@@ -95,8 +95,6 @@ public:
|
|||||||
|
|
||||||
static bool isQt5CmakeProject(const ProjectExplorer::Target *target);
|
static bool isQt5CmakeProject(const ProjectExplorer::Target *target);
|
||||||
|
|
||||||
// TODO: remove this on 6.0 branch, kept here for binary compatibility for 5.0 release.
|
|
||||||
static Utils::FilePath dirPath(const ProjectExplorer::Target *target);
|
|
||||||
static Utils::FilePath androidBuildDirectory(const ProjectExplorer::Target *target);
|
static Utils::FilePath androidBuildDirectory(const ProjectExplorer::Target *target);
|
||||||
static Utils::FilePath buildDirectory(const ProjectExplorer::Target *target);
|
static Utils::FilePath buildDirectory(const ProjectExplorer::Target *target);
|
||||||
static Utils::FilePath manifestPath(const ProjectExplorer::Target *target);
|
static Utils::FilePath manifestPath(const ProjectExplorer::Target *target);
|
||||||
|
@@ -166,7 +166,7 @@ void AndroidManifestEditorIconWidget::selectIcon()
|
|||||||
{
|
{
|
||||||
FilePath file = FileUtils::getOpenFilePath(this, m_iconSelectionText,
|
FilePath file = FileUtils::getOpenFilePath(this, m_iconSelectionText,
|
||||||
FileUtils::homePath(),
|
FileUtils::homePath(),
|
||||||
tr("Images (*.png *.jpg *.webp *.svg)"));
|
tr("Images (*.png *.jpg *.jpeg *.webp *.svg)"));
|
||||||
if (file.isEmpty())
|
if (file.isEmpty())
|
||||||
return;
|
return;
|
||||||
setIconFromPath(file);
|
setIconFromPath(file);
|
||||||
|
@@ -62,7 +62,7 @@ const char splashscreenFileName[] = "logo";
|
|||||||
const char splashscreenPortraitFileName[] = "logo_port";
|
const char splashscreenPortraitFileName[] = "logo_port";
|
||||||
const char splashscreenLandscapeFileName[] = "logo_land";
|
const char splashscreenLandscapeFileName[] = "logo_land";
|
||||||
const char imageSuffix[] = ".png";
|
const char imageSuffix[] = ".png";
|
||||||
const QString fileDialogImageFiles = QString(QWidget::tr("Images (*.png *.jpg)"));
|
const QString fileDialogImageFiles = QString(QWidget::tr("Images (*.png *.jpg *.jpeg)"));
|
||||||
const QSize lowDpiImageSize{200, 320};
|
const QSize lowDpiImageSize{200, 320};
|
||||||
const QSize mediumDpiImageSize{320, 480};
|
const QSize mediumDpiImageSize{320, 480};
|
||||||
const QSize highDpiImageSize{480, 800};
|
const QSize highDpiImageSize{480, 800};
|
||||||
@@ -608,8 +608,8 @@ void SplashScreenContainerWidget::checkSplashscreenImage(const QString &name)
|
|||||||
|
|
||||||
for (const QString &path : paths) {
|
for (const QString &path : paths) {
|
||||||
const FilePath filePath = baseDir.pathAppended(path + name);
|
const FilePath filePath = baseDir.pathAppended(path + name);
|
||||||
if (filePath.stringAppended(".png").exists()
|
if (filePath.stringAppended(".png").exists() || filePath.stringAppended(".jpg").exists()
|
||||||
|| filePath.stringAppended(".jpg").exists()) {
|
|| filePath.stringAppended(".jpeg").exists()) {
|
||||||
setCurrentIndex(1);
|
setCurrentIndex(1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -189,7 +189,8 @@ void SplashScreenWidget::selectImage()
|
|||||||
{
|
{
|
||||||
const FilePath file = FileUtils::getOpenFilePath(this, m_imageSelectionText,
|
const FilePath file = FileUtils::getOpenFilePath(this, m_imageSelectionText,
|
||||||
FileUtils::homePath(),
|
FileUtils::homePath(),
|
||||||
QStringLiteral("%1 (*.png *.jpg)").arg(tr("Images")));
|
QStringLiteral("%1 (*.png *.jpg *.jpeg)")
|
||||||
|
.arg(tr("Images")));
|
||||||
if (file.isEmpty())
|
if (file.isEmpty())
|
||||||
return;
|
return;
|
||||||
setImageFromPath(file, false);
|
setImageFromPath(file, false);
|
||||||
|
@@ -55,6 +55,7 @@ QStringList filterInterfering(const QStringList &provided, QStringList *omitted)
|
|||||||
"--gtest_stream_result_to=",
|
"--gtest_stream_result_to=",
|
||||||
"--gtest_break_on_failure",
|
"--gtest_break_on_failure",
|
||||||
"--gtest_throw_on_failure",
|
"--gtest_throw_on_failure",
|
||||||
|
"--gtest_catch_exceptions=",
|
||||||
"--gtest_print_time="
|
"--gtest_print_time="
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -100,6 +101,7 @@ QStringList GTestConfiguration::argumentsForTestRunner(QStringList *omitted) con
|
|||||||
if (isDebugRunMode()) {
|
if (isDebugRunMode()) {
|
||||||
if (gSettings->breakOnFailure.value())
|
if (gSettings->breakOnFailure.value())
|
||||||
arguments << "--gtest_break_on_failure";
|
arguments << "--gtest_break_on_failure";
|
||||||
|
arguments << "--gtest_catch_exceptions=0";
|
||||||
}
|
}
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
@@ -61,3 +61,14 @@ extend_qtc_plugin(ClangCodeModel
|
|||||||
test/clangdtests.cpp test/clangdtests.h
|
test/clangdtests.cpp test/clangdtests.h
|
||||||
test/data/clangtestdata.qrc
|
test/data/clangtestdata.qrc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(MINGW)
|
||||||
|
set(big_obj_compile_option "-Wa,-mbig-obj")
|
||||||
|
elseif(MSVC)
|
||||||
|
set(big_obj_compile_option "/bigobj")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
extend_qtc_plugin(ClangCodeModel
|
||||||
|
CONDITION DEFINED big_obj_compile_option
|
||||||
|
PROPERTIES COMPILE_OPTIONS ${big_obj_compile_option}
|
||||||
|
)
|
||||||
|
@@ -252,6 +252,16 @@ public:
|
|||||||
QString theType = type();
|
QString theType = type();
|
||||||
if (theType.endsWith("const"))
|
if (theType.endsWith("const"))
|
||||||
theType.chop(5);
|
theType.chop(5);
|
||||||
|
|
||||||
|
// We don't care about the "inner" type of templates.
|
||||||
|
const int openAngleBracketPos = theType.indexOf('<');
|
||||||
|
if (openAngleBracketPos != -1) {
|
||||||
|
const int closingAngleBracketPos = theType.lastIndexOf('>');
|
||||||
|
if (closingAngleBracketPos > openAngleBracketPos) {
|
||||||
|
theType = theType.left(openAngleBracketPos)
|
||||||
|
+ theType.mid(closingAngleBracketPos + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
const int xrefCount = theType.count("&&");
|
const int xrefCount = theType.count("&&");
|
||||||
const int refCount = theType.count('&') - 2 * xrefCount;
|
const int refCount = theType.count('&') - 2 * xrefCount;
|
||||||
const int ptrRefCount = theType.count('*') + refCount;
|
const int ptrRefCount = theType.count('*') + refCount;
|
||||||
@@ -2443,6 +2453,8 @@ static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (it->kind() == "Lambda")
|
||||||
|
return false;
|
||||||
if (it->kind().endsWith("Cast") && it->hasConstType())
|
if (it->kind().endsWith("Cast") && it->hasConstType())
|
||||||
return false;
|
return false;
|
||||||
if (it->kind() == "Member" && it->arcanaContains("(")
|
if (it->kind() == "Member" && it->arcanaContains("(")
|
||||||
@@ -3140,6 +3152,18 @@ void ExtraHighlightingResultsCollector::insertResult(const HighlightingResult &r
|
|||||||
return;
|
return;
|
||||||
const auto it = std::lower_bound(m_results.begin(), m_results.end(), result, lessThan);
|
const auto it = std::lower_bound(m_results.begin(), m_results.end(), result, lessThan);
|
||||||
if (it == m_results.end() || *it != result) {
|
if (it == m_results.end() || *it != result) {
|
||||||
|
|
||||||
|
// Prevent inserting expansions for function-like macros. For instance:
|
||||||
|
// #define TEST() "blubb"
|
||||||
|
// const char *s = TEST();
|
||||||
|
// The macro name is always shorter than the expansion and starts at the same
|
||||||
|
// location, so it should occur right before the insertion position.
|
||||||
|
if (it > m_results.begin() && (it - 1)->line == result.line
|
||||||
|
&& (it - 1)->column == result.column
|
||||||
|
&& (it - 1)->textStyles.mainStyle == C_PREPROCESSOR) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
qCDebug(clangdLogHighlight) << "adding additional highlighting result"
|
qCDebug(clangdLogHighlight) << "adding additional highlighting result"
|
||||||
<< result.line << result.column << result.length;
|
<< result.line << result.column << result.length;
|
||||||
m_results.insert(it, result);
|
m_results.insert(it, result);
|
||||||
|
@@ -112,6 +112,7 @@ ClangModelManagerSupport::ClangModelManagerSupport()
|
|||||||
m_instance = this;
|
m_instance = this;
|
||||||
|
|
||||||
watchForExternalChanges();
|
watchForExternalChanges();
|
||||||
|
watchForInternalChanges();
|
||||||
cppModelManager()->setCurrentDocumentFilter(std::make_unique<ClangdCurrentDocumentFilter>());
|
cppModelManager()->setCurrentDocumentFilter(std::make_unique<ClangdCurrentDocumentFilter>());
|
||||||
cppModelManager()->setLocatorFilter(std::make_unique<ClangGlobalSymbolFilter>());
|
cppModelManager()->setLocatorFilter(std::make_unique<ClangGlobalSymbolFilter>());
|
||||||
cppModelManager()->setClassesFilter(std::make_unique<ClangClassesFilter>());
|
cppModelManager()->setClassesFilter(std::make_unique<ClangClassesFilter>());
|
||||||
@@ -488,6 +489,29 @@ void ClangModelManagerSupport::watchForExternalChanges()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClangModelManagerSupport::watchForInternalChanges()
|
||||||
|
{
|
||||||
|
connect(Core::DocumentManager::instance(), &Core::DocumentManager::filesChangedInternally,
|
||||||
|
this, [this](const Utils::FilePaths &filePaths) {
|
||||||
|
for (const Utils::FilePath &fp : filePaths) {
|
||||||
|
ClangdClient * const client = clientForFile(fp);
|
||||||
|
if (!client || client->documentForFilePath(fp))
|
||||||
|
continue;
|
||||||
|
client->openExtraFile(fp);
|
||||||
|
|
||||||
|
// We need to give clangd some time to start re-parsing the file.
|
||||||
|
// Closing right away does not work, and neither does doing it queued.
|
||||||
|
// If it turns out that this delay is not always enough, we'll need to come up
|
||||||
|
// with something more clever.
|
||||||
|
// Ideally, clangd would implement workspace/didChangeWatchedFiles; let's keep
|
||||||
|
// any eye on that.
|
||||||
|
QTimer::singleShot(5000, client, [client, fp] {
|
||||||
|
if (!client->documentForFilePath(fp))
|
||||||
|
client->closeExtraFile(fp); });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void ClangModelManagerSupport::onEditorOpened(Core::IEditor *editor)
|
void ClangModelManagerSupport::onEditorOpened(Core::IEditor *editor)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(editor, return);
|
QTC_ASSERT(editor, return);
|
||||||
|
@@ -135,8 +135,8 @@ private:
|
|||||||
ClangdClient *createClient(ProjectExplorer::Project *project, const Utils::FilePath &jsonDbDir);
|
ClangdClient *createClient(ProjectExplorer::Project *project, const Utils::FilePath &jsonDbDir);
|
||||||
void claimNonProjectSources(ClangdClient *fallbackClient);
|
void claimNonProjectSources(ClangdClient *fallbackClient);
|
||||||
void watchForExternalChanges();
|
void watchForExternalChanges();
|
||||||
|
void watchForInternalChanges();
|
||||||
|
|
||||||
private:
|
|
||||||
UiHeaderOnDiskManager m_uiHeaderOnDiskManager;
|
UiHeaderOnDiskManager m_uiHeaderOnDiskManager;
|
||||||
BackendCommunicator m_communicator;
|
BackendCommunicator m_communicator;
|
||||||
ClangCompletionAssistProvider m_completionAssistProvider;
|
ClangCompletionAssistProvider m_completionAssistProvider;
|
||||||
|
@@ -1249,6 +1249,9 @@ void ClangdTestHighlighting::test_data()
|
|||||||
QTest::newRow("const argument to unnamed lambda") << 830 << 16 << 830 << 19
|
QTest::newRow("const argument to unnamed lambda") << 830 << 16 << 830 << 19
|
||||||
<< QList<int>{C_LOCAL} << 0;
|
<< QList<int>{C_LOCAL} << 0;
|
||||||
QTest::newRow("simple assignment") << 835 << 5 << 835 << 6 << QList<int>{C_LOCAL} << 0;
|
QTest::newRow("simple assignment") << 835 << 5 << 835 << 6 << QList<int>{C_LOCAL} << 0;
|
||||||
|
QTest::newRow("simple return") << 841 << 12 << 841 << 15 << QList<int>{C_LOCAL} << 0;
|
||||||
|
QTest::newRow("lambda parameter") << 847 << 49 << 847 << 52
|
||||||
|
<< QList<int>{C_PARAMETER, C_DECLARATION} << 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangdTestHighlighting::test()
|
void ClangdTestHighlighting::test()
|
||||||
|
@@ -834,3 +834,15 @@ void assignmentTest() {
|
|||||||
struct S {} s;
|
struct S {} s;
|
||||||
s = {};
|
s = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using FooPtrVector = std::vector<Foo *>;
|
||||||
|
FooPtrVector returnTest() {
|
||||||
|
FooPtrVector foo;
|
||||||
|
return foo;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Container, typename Func> inline void useContainer(const Container &, Func) {}
|
||||||
|
void testConstRefAutoLambdaArgs()
|
||||||
|
{
|
||||||
|
useContainer(FooPtrVector(), [](const auto &arg) {});
|
||||||
|
}
|
||||||
|
@@ -421,10 +421,13 @@ QTextCursor BaseTextFind::findOne(const QRegularExpression &expr,
|
|||||||
QTextCursor found = document()->find(expr, from, options);
|
QTextCursor found = document()->find(expr, from, options);
|
||||||
while (!found.isNull() && !inScope(found)) {
|
while (!found.isNull() && !inScope(found)) {
|
||||||
if (!found.hasSelection()) {
|
if (!found.hasSelection()) {
|
||||||
from = found;
|
if (found.movePosition(options & QTextDocument::FindBackward
|
||||||
found.movePosition(options & QTextDocument::FindBackward
|
? QTextCursor::PreviousCharacter
|
||||||
? QTextCursor::PreviousCharacter
|
: QTextCursor::NextCharacter)) {
|
||||||
: QTextCursor::NextCharacter);
|
from = found;
|
||||||
|
} else {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
from.setPosition(options & QTextDocument::FindBackward ? found.selectionStart()
|
from.setPosition(options & QTextDocument::FindBackward ? found.selectionStart()
|
||||||
: found.selectionEnd());
|
: found.selectionEnd());
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
#include <extensionsystem/pluginmanager.h>
|
#include <extensionsystem/pluginmanager.h>
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@@ -165,9 +166,13 @@ namespace Core {
|
|||||||
// The Core Singleton
|
// The Core Singleton
|
||||||
static ICore *m_instance = nullptr;
|
static ICore *m_instance = nullptr;
|
||||||
static MainWindow *m_mainwindow = nullptr;
|
static MainWindow *m_mainwindow = nullptr;
|
||||||
std::function<NewDialog *(QWidget *)> ICore::m_newDialogFactory = [](QWidget *parent) {
|
|
||||||
|
static NewDialog *defaultDialogFactory(QWidget *parent)
|
||||||
|
{
|
||||||
return new NewDialogWidget(parent);
|
return new NewDialogWidget(parent);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
static std::function<NewDialog *(QWidget *)> m_newDialogFactory = defaultDialogFactory;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Returns the pointer to the instance. Only use for connecting to signals.
|
Returns the pointer to the instance. Only use for connecting to signals.
|
||||||
@@ -253,7 +258,23 @@ void ICore::showNewItemDialog(const QString &title,
|
|||||||
const QVariantMap &extraVariables)
|
const QVariantMap &extraVariables)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!isNewItemDialogRunning(), return);
|
QTC_ASSERT(!isNewItemDialogRunning(), return);
|
||||||
NewDialog *newDialog = ICore::m_newDialogFactory(dialogParent());
|
|
||||||
|
/* This is a workaround for QDS: In QDS, we currently have a "New Project" dialog box but we do
|
||||||
|
* not also have a "New file" dialog box (yet). Therefore, when requested to add a new file, we
|
||||||
|
* need to use QtCreator's dialog box. In QDS, if `factories` contains project wizard factories
|
||||||
|
* (even though it may contain file wizard factories as well), then we consider it to be a
|
||||||
|
* request for "New Project". Otherwise, if we only have file wizard factories, we defer to
|
||||||
|
* QtCreator's dialog and request "New File"
|
||||||
|
*/
|
||||||
|
auto dialogFactory = m_newDialogFactory;
|
||||||
|
bool haveProjectWizards = Utils::anyOf(factories, [](IWizardFactory *f) {
|
||||||
|
return f->kind() == IWizardFactory::ProjectWizard;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!haveProjectWizards)
|
||||||
|
dialogFactory = defaultDialogFactory;
|
||||||
|
|
||||||
|
NewDialog *newDialog = dialogFactory(dialogParent());
|
||||||
connect(newDialog->widget(), &QObject::destroyed, m_instance, &ICore::updateNewItemDialogState);
|
connect(newDialog->widget(), &QObject::destroyed, m_instance, &ICore::updateNewItemDialogState);
|
||||||
newDialog->setWizardFactories(factories, defaultLocation, extraVariables);
|
newDialog->setWizardFactories(factories, defaultLocation, extraVariables);
|
||||||
newDialog->setWindowTitle(title);
|
newDialog->setWindowTitle(title);
|
||||||
|
@@ -180,8 +180,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
static void updateNewItemDialogState();
|
static void updateNewItemDialogState();
|
||||||
|
|
||||||
static std::function<NewDialog *(QWidget *)> m_newDialogFactory;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Core
|
} // namespace Core
|
||||||
|
@@ -291,9 +291,10 @@ Wizard *IWizardFactory::runWizard(const FilePath &path, QWidget *parent, Id plat
|
|||||||
s_reopenData.reopen();
|
s_reopenData.reopen();
|
||||||
});
|
});
|
||||||
s_inspectWizardAction->setEnabled(true);
|
s_inspectWizardAction->setEnabled(true);
|
||||||
if (showWizard)
|
if (showWizard) {
|
||||||
wizard->show();
|
wizard->show();
|
||||||
Core::ICore::registerWindow(wizard, Core::Context("Core.NewWizard"));
|
Core::ICore::registerWindow(wizard, Core::Context("Core.NewWizard"));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
s_isWizardRunning = false;
|
s_isWizardRunning = false;
|
||||||
ICore::updateNewItemDialogState();
|
ICore::updateNewItemDialogState();
|
||||||
|
@@ -92,6 +92,7 @@
|
|||||||
#include <QStyleFactory>
|
#include <QStyleFactory>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
|
#include <QWindow>
|
||||||
|
|
||||||
using namespace ExtensionSystem;
|
using namespace ExtensionSystem;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
@@ -101,6 +102,14 @@ namespace Internal {
|
|||||||
|
|
||||||
enum { debugMainWindow = 0 };
|
enum { debugMainWindow = 0 };
|
||||||
|
|
||||||
|
static bool isQtDesignStudio()
|
||||||
|
{
|
||||||
|
QSettings *settings = Core::ICore::settings();
|
||||||
|
const QString qdsStandaloneEntry = "QML/Designer/StandAloneMode"; //entry from qml settings
|
||||||
|
|
||||||
|
return settings->value(qdsStandaloneEntry, false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
MainWindow::MainWindow()
|
MainWindow::MainWindow()
|
||||||
: AppMainWindow()
|
: AppMainWindow()
|
||||||
, m_coreImpl(new ICore(this))
|
, m_coreImpl(new ICore(this))
|
||||||
@@ -518,7 +527,8 @@ void MainWindow::registerDefaultActions()
|
|||||||
|
|
||||||
// New File Action
|
// New File Action
|
||||||
QIcon icon = QIcon::fromTheme(QLatin1String("document-new"), Utils::Icons::NEWFILE.icon());
|
QIcon icon = QIcon::fromTheme(QLatin1String("document-new"), Utils::Icons::NEWFILE.icon());
|
||||||
m_newAction = new QAction(icon, tr("&New File or Project..."), this);
|
QString newActionText = isQtDesignStudio() ? tr("&New Project...") : tr("&New File or Project...");
|
||||||
|
m_newAction = new QAction(icon, newActionText, this);
|
||||||
cmd = ActionManager::registerAction(m_newAction, Constants::NEW);
|
cmd = ActionManager::registerAction(m_newAction, Constants::NEW);
|
||||||
cmd->setDefaultKeySequence(QKeySequence::New);
|
cmd->setDefaultKeySequence(QKeySequence::New);
|
||||||
mfile->addAction(cmd, Constants::G_FILE_NEW);
|
mfile->addAction(cmd, Constants::G_FILE_NEW);
|
||||||
@@ -939,6 +949,20 @@ void MainWindow::setFocusToEditor()
|
|||||||
EditorManagerPrivate::doEscapeKeyFocusMoveMagic();
|
EditorManagerPrivate::doEscapeKeyFocusMoveMagic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void acceptModalDialogs()
|
||||||
|
{
|
||||||
|
const QWidgetList topLevels = QApplication::topLevelWidgets();
|
||||||
|
QList<QDialog *> dialogsToClose;
|
||||||
|
for (QWidget *topLevel : topLevels) {
|
||||||
|
if (auto dialog = qobject_cast<QDialog *>(topLevel)) {
|
||||||
|
if (dialog->isModal())
|
||||||
|
dialogsToClose.append(dialog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (QDialog *dialog : dialogsToClose)
|
||||||
|
dialog->accept();
|
||||||
|
}
|
||||||
|
|
||||||
void MainWindow::exit()
|
void MainWindow::exit()
|
||||||
{
|
{
|
||||||
// this function is most likely called from a user action
|
// this function is most likely called from a user action
|
||||||
@@ -946,7 +970,15 @@ void MainWindow::exit()
|
|||||||
// since on close we are going to delete everything
|
// since on close we are going to delete everything
|
||||||
// so to prevent the deleting of that object we
|
// so to prevent the deleting of that object we
|
||||||
// just append it
|
// just append it
|
||||||
QMetaObject::invokeMethod(this, &QWidget::close, Qt::QueuedConnection);
|
QMetaObject::invokeMethod(
|
||||||
|
this,
|
||||||
|
[this] {
|
||||||
|
// Modal dialogs block the close event. So close them, in case this was triggered from
|
||||||
|
// a RestartDialog in the settings dialog.
|
||||||
|
acceptModalDialogs();
|
||||||
|
close();
|
||||||
|
},
|
||||||
|
Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::openFileWith()
|
void MainWindow::openFileWith()
|
||||||
|
@@ -36,6 +36,9 @@
|
|||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QHash>
|
||||||
|
#include <QPair>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
@@ -356,11 +359,12 @@ static QVersionNumber getClangdVersion(const FilePath &clangdFilePath)
|
|||||||
|
|
||||||
QVersionNumber ClangdSettings::clangdVersion(const FilePath &clangdFilePath)
|
QVersionNumber ClangdSettings::clangdVersion(const FilePath &clangdFilePath)
|
||||||
{
|
{
|
||||||
|
static QHash<Utils::FilePath, QPair<QDateTime, QVersionNumber>> versionCache;
|
||||||
const QDateTime timeStamp = clangdFilePath.lastModified();
|
const QDateTime timeStamp = clangdFilePath.lastModified();
|
||||||
const auto it = m_versionCache.find(clangdFilePath);
|
const auto it = versionCache.find(clangdFilePath);
|
||||||
if (it == m_versionCache.end()) {
|
if (it == versionCache.end()) {
|
||||||
const QVersionNumber version = getClangdVersion(clangdFilePath);
|
const QVersionNumber version = getClangdVersion(clangdFilePath);
|
||||||
m_versionCache.insert(clangdFilePath, qMakePair(timeStamp, version));
|
versionCache.insert(clangdFilePath, qMakePair(timeStamp, version));
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
if (it->first != timeStamp) {
|
if (it->first != timeStamp) {
|
||||||
|
@@ -29,10 +29,7 @@
|
|||||||
|
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
|
|
||||||
#include <QDateTime>
|
|
||||||
#include <QHash>
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QPair>
|
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QVersionNumber>
|
#include <QVersionNumber>
|
||||||
|
|
||||||
@@ -150,7 +147,6 @@ private:
|
|||||||
void saveSettings();
|
void saveSettings();
|
||||||
|
|
||||||
Data m_data;
|
Data m_data;
|
||||||
static inline QHash<Utils::FilePath, QPair<QDateTime, QVersionNumber>> m_versionCache;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator==(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2)
|
inline bool operator==(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2)
|
||||||
|
@@ -213,6 +213,7 @@ QuickFixOperationTest::QuickFixOperationTest(const QList<TestDocumentPtr> &testD
|
|||||||
QuickFixOperations operations;
|
QuickFixOperations operations;
|
||||||
factory->match(quickFixInterface, operations);
|
factory->match(quickFixInterface, operations);
|
||||||
if (operations.isEmpty()) {
|
if (operations.isEmpty()) {
|
||||||
|
QEXPECT_FAIL("CompleteSwitchCaseStatement_QTCREATORBUG-25998", "FIXME", Abort);
|
||||||
QVERIFY(testDocuments.first()->m_expectedSource.isEmpty());
|
QVERIFY(testDocuments.first()->m_expectedSource.isEmpty());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -148,6 +148,7 @@ void SemanticHighlighter::run()
|
|||||||
connectWatcher();
|
connectWatcher();
|
||||||
|
|
||||||
m_revision = documentRevision();
|
m_revision = documentRevision();
|
||||||
|
qCDebug(log) << "starting runner for document revision" << m_revision;
|
||||||
m_watcher->setFuture(m_highlightingRunner());
|
m_watcher->setFuture(m_highlightingRunner());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,12 +161,17 @@ static Parentheses getClearedParentheses(const QTextBlock &block)
|
|||||||
|
|
||||||
void SemanticHighlighter::onHighlighterResultAvailable(int from, int to)
|
void SemanticHighlighter::onHighlighterResultAvailable(int from, int to)
|
||||||
{
|
{
|
||||||
if (documentRevision() != m_revision)
|
|
||||||
return; // outdated
|
|
||||||
if (!m_watcher || m_watcher->isCanceled())
|
|
||||||
return; // aborted
|
|
||||||
|
|
||||||
qCDebug(log) << "onHighlighterResultAvailable()" << from << to;
|
qCDebug(log) << "onHighlighterResultAvailable()" << from << to;
|
||||||
|
if (documentRevision() != m_revision) {
|
||||||
|
qCDebug(log) << "ignoring results: revision changed from" << m_revision << "to"
|
||||||
|
<< documentRevision();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!m_watcher || m_watcher->isCanceled()) {
|
||||||
|
qCDebug(log) << "ignoring results: future was canceled";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QElapsedTimer t;
|
QElapsedTimer t;
|
||||||
t.start();
|
t.start();
|
||||||
|
|
||||||
|
@@ -2832,8 +2832,10 @@ void CdbEngine::setupScripting(const DebuggerResponse &response)
|
|||||||
runCommand({command, ScriptCommand});
|
runCommand({command, ScriptCommand});
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString qtVersion = QString::number(runParameters().fallbackQtVersion, 16);
|
DebuggerCommand cmd0("theDumper.setFallbackQtVersion", ScriptCommand);
|
||||||
runCommand({"theDumper.setFallbackQtVersion(0x" + qtVersion + ")", ScriptCommand});
|
cmd0.arg("version", runParameters().fallbackQtVersion);
|
||||||
|
runCommand(cmd0);
|
||||||
|
|
||||||
runCommand({"theDumper.loadDumpers(None)", ScriptCommand,
|
runCommand({"theDumper.loadDumpers(None)", ScriptCommand,
|
||||||
[this](const DebuggerResponse &response) {
|
[this](const DebuggerResponse &response) {
|
||||||
watchHandler()->addDumpers(response.data["result"]["dumpers"]);
|
watchHandler()->addDumpers(response.data["result"]["dumpers"]);
|
||||||
|
@@ -931,22 +931,27 @@ void DebuggerEngine::showStatusMessage(const QString &msg, int timeout) const
|
|||||||
|
|
||||||
void DebuggerEngine::updateLocalsWindow(bool showReturn)
|
void DebuggerEngine::updateLocalsWindow(bool showReturn)
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(d->m_returnWindow, return);
|
||||||
|
QTC_ASSERT(d->m_localsView, return);
|
||||||
d->m_returnWindow->setVisible(showReturn);
|
d->m_returnWindow->setVisible(showReturn);
|
||||||
d->m_localsView->resizeColumns();
|
d->m_localsView->resizeColumns();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DebuggerEngine::isRegistersWindowVisible() const
|
bool DebuggerEngine::isRegistersWindowVisible() const
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(d->m_registerWindow, return false);
|
||||||
return d->m_registerWindow->isVisible();
|
return d->m_registerWindow->isVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DebuggerEngine::isPeripheralRegistersWindowVisible() const
|
bool DebuggerEngine::isPeripheralRegistersWindowVisible() const
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(d->m_peripheralRegisterWindow, return false);
|
||||||
return d->m_peripheralRegisterWindow->isVisible();
|
return d->m_peripheralRegisterWindow->isVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DebuggerEngine::isModulesWindowVisible() const
|
bool DebuggerEngine::isModulesWindowVisible() const
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(d->m_modulesWindow, return false);
|
||||||
return d->m_modulesWindow->isVisible();
|
return d->m_modulesWindow->isVisible();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -165,9 +165,12 @@ void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *erro
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Environment env = sysEnv.size() == 0 ? Environment::systemEnvironment() : sysEnv;
|
||||||
// Prevent calling lldb on Windows because the lldb from the llvm package is linked against
|
// Prevent calling lldb on Windows because the lldb from the llvm package is linked against
|
||||||
// python but does not contain a python dll.
|
// python but does not contain a python dll.
|
||||||
if (HostOsInfo::isWindowsHost() && m_command.fileName().startsWith("lldb")) {
|
const bool isAndroidNdkLldb = DebuggerItem::addAndroidLldbPythonEnv(m_command, env);
|
||||||
|
if (HostOsInfo::isWindowsHost() && m_command.fileName().startsWith("lldb")
|
||||||
|
&& !isAndroidNdkLldb) {
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
m_version = winGetDLLVersion(WinDLLFileVersion,
|
m_version = winGetDLLVersion(WinDLLFileVersion,
|
||||||
m_command.absoluteFilePath().path(),
|
m_command.absoluteFilePath().path(),
|
||||||
@@ -178,7 +181,7 @@ void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
QtcProcess proc;
|
QtcProcess proc;
|
||||||
proc.setEnvironment(sysEnv);
|
proc.setEnvironment(env);
|
||||||
proc.setCommand({m_command, {version}});
|
proc.setCommand({m_command, {version}});
|
||||||
proc.runBlocking();
|
proc.runBlocking();
|
||||||
const QString output = proc.allOutput().trimmed();
|
const QString output = proc.allOutput().trimmed();
|
||||||
@@ -262,6 +265,22 @@ void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *erro
|
|||||||
m_engineType = NoEngineType;
|
m_engineType = NoEngineType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DebuggerItem::addAndroidLldbPythonEnv(const Utils::FilePath &lldbCmd, Utils::Environment &env)
|
||||||
|
{
|
||||||
|
if (lldbCmd.baseName().contains("lldb") &&
|
||||||
|
(lldbCmd.path().contains("/ndk/") || lldbCmd.path().contains("/ndk-bundle/"))) {
|
||||||
|
const FilePath pythonDir = lldbCmd.parentDir().parentDir().pathAppended("python3");
|
||||||
|
const FilePath pythonBinDir =
|
||||||
|
HostOsInfo::isAnyUnixHost() ? pythonDir.pathAppended("bin") : pythonDir;
|
||||||
|
if (pythonBinDir.exists()) {
|
||||||
|
env.set("PYTHONHOME", pythonDir.toUserOutput());
|
||||||
|
env.prependOrSetPath(pythonBinDir);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
QString DebuggerItem::engineTypeName() const
|
QString DebuggerItem::engineTypeName() const
|
||||||
{
|
{
|
||||||
switch (m_engineType) {
|
switch (m_engineType) {
|
||||||
|
@@ -107,6 +107,8 @@ public:
|
|||||||
QString detectionSource() const { return m_detectionSource; }
|
QString detectionSource() const { return m_detectionSource; }
|
||||||
void setDetectionSource(const QString &source) { m_detectionSource = source; }
|
void setDetectionSource(const QString &source) { m_detectionSource = source; }
|
||||||
|
|
||||||
|
static bool addAndroidLldbPythonEnv(const Utils::FilePath &lldbCmd, Utils::Environment &env);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DebuggerItem(const QVariant &id);
|
DebuggerItem(const QVariant &id);
|
||||||
void initMacroExpander();
|
void initMacroExpander();
|
||||||
|
@@ -4011,7 +4011,10 @@ void GdbEngine::setupEngine()
|
|||||||
if (!commands.isEmpty())
|
if (!commands.isEmpty())
|
||||||
runCommand({commands});
|
runCommand({commands});
|
||||||
|
|
||||||
runCommand({"setFallbackQtVersion(0x" + QString::number(rp.fallbackQtVersion, 16) + ")"});
|
DebuggerCommand cmd1("setFallbackQtVersion");
|
||||||
|
cmd1.arg("version", rp.fallbackQtVersion);
|
||||||
|
runCommand(cmd1);
|
||||||
|
|
||||||
runCommand({"loadDumpers", CB(handlePythonSetup)});
|
runCommand({"loadDumpers", CB(handlePythonSetup)});
|
||||||
|
|
||||||
// Reload peripheral register description.
|
// Reload peripheral register description.
|
||||||
|
@@ -213,12 +213,7 @@ void LldbEngine::setupEngine()
|
|||||||
showMessage("STARTING LLDB: " + lldbCmd.toUserOutput());
|
showMessage("STARTING LLDB: " + lldbCmd.toUserOutput());
|
||||||
Environment environment = runParameters().debugger.environment;
|
Environment environment = runParameters().debugger.environment;
|
||||||
environment.appendOrSet("PYTHONUNBUFFERED", "1"); // avoid flushing problem on macOS
|
environment.appendOrSet("PYTHONUNBUFFERED", "1"); // avoid flushing problem on macOS
|
||||||
if (lldbCmd.path().contains("/ndk-bundle/")) {
|
DebuggerItem::addAndroidLldbPythonEnv(lldbCmd, environment);
|
||||||
FilePath androidPythonDir = lldbCmd.parentDir().parentDir().pathAppended("python3");
|
|
||||||
if (HostOsInfo::isAnyUnixHost())
|
|
||||||
androidPythonDir = androidPythonDir.pathAppended("bin");
|
|
||||||
environment.prependOrSetPath(androidPythonDir);
|
|
||||||
}
|
|
||||||
m_lldbProc.setEnvironment(environment);
|
m_lldbProc.setEnvironment(environment);
|
||||||
|
|
||||||
if (runParameters().debugger.workingDirectory.isDir())
|
if (runParameters().debugger.workingDirectory.isDir())
|
||||||
@@ -269,10 +264,6 @@ void LldbEngine::setupEngine()
|
|||||||
runCommand(cmd);
|
runCommand(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggerCommand cmd0("setFallbackQtVersion");
|
|
||||||
cmd0.arg("version", "0x" + QString::number(rp.fallbackQtVersion, 16));
|
|
||||||
runCommand(cmd0);
|
|
||||||
|
|
||||||
DebuggerCommand cmd1("loadDumpers");
|
DebuggerCommand cmd1("loadDumpers");
|
||||||
cmd1.callback = [this](const DebuggerResponse &response) {
|
cmd1.callback = [this](const DebuggerResponse &response) {
|
||||||
watchHandler()->addDumpers(response.data["dumpers"]);
|
watchHandler()->addDumpers(response.data["dumpers"]);
|
||||||
@@ -348,6 +339,10 @@ void LldbEngine::setupEngine()
|
|||||||
|
|
||||||
cmd2.flags = Silent;
|
cmd2.flags = Silent;
|
||||||
runCommand(cmd2);
|
runCommand(cmd2);
|
||||||
|
|
||||||
|
DebuggerCommand cmd0("setFallbackQtVersion");
|
||||||
|
cmd0.arg("version", rp.fallbackQtVersion);
|
||||||
|
runCommand(cmd0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LldbEngine::runEngine()
|
void LldbEngine::runEngine()
|
||||||
|
@@ -48,7 +48,11 @@ bool isIntType(const QString &type)
|
|||||||
case 'b':
|
case 'b':
|
||||||
return type == "bool";
|
return type == "bool";
|
||||||
case 'c':
|
case 'c':
|
||||||
return type == "char";
|
return type.startsWith("char") &&
|
||||||
|
( type == "char"
|
||||||
|
|| type == "char8_t"
|
||||||
|
|| type == "char16_t"
|
||||||
|
|| type == "char32_t" );
|
||||||
case 'i':
|
case 'i':
|
||||||
return type.startsWith("int") &&
|
return type.startsWith("int") &&
|
||||||
( type == "int"
|
( type == "int"
|
||||||
@@ -63,7 +67,8 @@ bool isIntType(const QString &type)
|
|||||||
case 'p':
|
case 'p':
|
||||||
return type == "ptrdiff_t";
|
return type == "ptrdiff_t";
|
||||||
case 'q':
|
case 'q':
|
||||||
return type == "qint16" || type == "quint16"
|
return type == "qint8" || type == "quint8"
|
||||||
|
|| type == "qint16" || type == "quint16"
|
||||||
|| type == "qint32" || type == "quint32"
|
|| type == "qint32" || type == "quint32"
|
||||||
|| type == "qint64" || type == "quint64"
|
|| type == "qint64" || type == "quint64"
|
||||||
|| type == "qlonglong" || type == "qulonglong";
|
|| type == "qlonglong" || type == "qulonglong";
|
||||||
|
@@ -717,22 +717,34 @@ static QString formattedValue(const WatchItem *item)
|
|||||||
|
|
||||||
// Append quoted, printable character also for decimal.
|
// Append quoted, printable character also for decimal.
|
||||||
// FIXME: This is unreliable.
|
// FIXME: This is unreliable.
|
||||||
if (item->type.endsWith("char") || item->type.endsWith("int8_t")) {
|
const QString type = item->type;
|
||||||
|
if (type == "char8_t" || type.endsWith("char") || type.endsWith("int8_t")) {
|
||||||
bool ok;
|
bool ok;
|
||||||
const int code = item->value.toInt(&ok);
|
const int code = item->value.toInt(&ok);
|
||||||
bool isUnsigned = item->type == "unsigned char" || item->type == "uchar" || item->type == "uint8_t";
|
bool isUnsigned = type == "char8_t"
|
||||||
|
|| type == "unsigned char"
|
||||||
|
|| type == "uchar"
|
||||||
|
|| type == "uint8_t";
|
||||||
if (ok)
|
if (ok)
|
||||||
return reformatCharacter(code, 1, !isUnsigned);
|
return reformatCharacter(code, 1, !isUnsigned);
|
||||||
} else if (item->type.endsWith("wchar_t")) {
|
} else if (type == "qint8" || type == "quint8") {
|
||||||
|
bool ok = false;
|
||||||
|
const int code = item->value.toInt(&ok);
|
||||||
|
bool isUnsigned = type == "quint8";
|
||||||
|
if (ok)
|
||||||
|
return reformatCharacter(code, 1, !isUnsigned);
|
||||||
|
} else if (type == "char32_t" || type.endsWith("wchar_t")) {
|
||||||
bool ok;
|
bool ok;
|
||||||
const int code = item->value.toInt(&ok);
|
const int code = item->value.toInt(&ok);
|
||||||
|
bool isUnsigned = type == "char32_t";
|
||||||
if (ok)
|
if (ok)
|
||||||
return reformatCharacter(code, 4, false);
|
return reformatCharacter(code, 4, !isUnsigned);
|
||||||
} else if (item->type.endsWith("QChar")) {
|
} else if (type == "char16_t" || type.endsWith("QChar")) {
|
||||||
bool ok;
|
bool ok;
|
||||||
const int code = item->value.toInt(&ok);
|
const int code = item->value.toInt(&ok);
|
||||||
|
bool isUnsigned = type == "char16_t";
|
||||||
if (ok)
|
if (ok)
|
||||||
return reformatCharacter(code, 2, false);
|
return reformatCharacter(code, 2, !isUnsigned);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format == HexadecimalIntegerFormat
|
if (format == HexadecimalIntegerFormat
|
||||||
|
@@ -937,7 +937,6 @@ void Client::handleCodeActionResponse(const CodeActionRequest::Response &respons
|
|||||||
|
|
||||||
void Client::executeCommand(const Command &command)
|
void Client::executeCommand(const Command &command)
|
||||||
{
|
{
|
||||||
const QString method(ExecuteCommandRequest::methodName);
|
|
||||||
bool serverSupportsExecuteCommand = m_serverCapabilities.executeCommandProvider().has_value();
|
bool serverSupportsExecuteCommand = m_serverCapabilities.executeCommandProvider().has_value();
|
||||||
serverSupportsExecuteCommand = m_dynamicCapabilities
|
serverSupportsExecuteCommand = m_dynamicCapabilities
|
||||||
.isRegistered(ExecuteCommandRequest::methodName)
|
.isRegistered(ExecuteCommandRequest::methodName)
|
||||||
@@ -953,7 +952,18 @@ ProjectExplorer::Project *Client::project() const
|
|||||||
|
|
||||||
void Client::setCurrentProject(ProjectExplorer::Project *project)
|
void Client::setCurrentProject(ProjectExplorer::Project *project)
|
||||||
{
|
{
|
||||||
|
if (m_project == project)
|
||||||
|
return;
|
||||||
|
if (m_project)
|
||||||
|
m_project->disconnect(this);
|
||||||
m_project = project;
|
m_project = project;
|
||||||
|
if (m_project) {
|
||||||
|
connect(m_project, &ProjectExplorer::Project::destroyed, this, [this]() {
|
||||||
|
// the project of the client should already be null since we expect the session and
|
||||||
|
// the language client manager to reset it before it gets deleted.
|
||||||
|
QTC_ASSERT(m_project == nullptr, projectClosed(m_project));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::projectOpened(ProjectExplorer::Project *project)
|
void Client::projectOpened(ProjectExplorer::Project *project)
|
||||||
|
@@ -53,6 +53,8 @@ using namespace LanguageServerProtocol;
|
|||||||
|
|
||||||
namespace LanguageClient {
|
namespace LanguageClient {
|
||||||
|
|
||||||
|
static Q_LOGGING_CATEGORY(Log, "qtc.languageclient.manager", QtWarningMsg)
|
||||||
|
|
||||||
static LanguageClientManager *managerInstance = nullptr;
|
static LanguageClientManager *managerInstance = nullptr;
|
||||||
|
|
||||||
LanguageClientManager::LanguageClientManager(QObject *parent)
|
LanguageClientManager::LanguageClientManager(QObject *parent)
|
||||||
@@ -111,6 +113,7 @@ void LanguageClient::LanguageClientManager::addClient(Client *client)
|
|||||||
if (managerInstance->m_clients.contains(client))
|
if (managerInstance->m_clients.contains(client))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
qCDebug(Log) << "add client: " << client->name() << client;
|
||||||
managerInstance->m_clients << client;
|
managerInstance->m_clients << client;
|
||||||
connect(client, &Client::finished, managerInstance, [client]() { clientFinished(client); });
|
connect(client, &Client::finished, managerInstance, [client]() { clientFinished(client); });
|
||||||
connect(client,
|
connect(client,
|
||||||
@@ -130,6 +133,7 @@ void LanguageClient::LanguageClientManager::addClient(Client *client)
|
|||||||
|
|
||||||
void LanguageClientManager::clientStarted(Client *client)
|
void LanguageClientManager::clientStarted(Client *client)
|
||||||
{
|
{
|
||||||
|
qCDebug(Log) << "client started: " << client->name() << client;
|
||||||
QTC_ASSERT(managerInstance, return);
|
QTC_ASSERT(managerInstance, return);
|
||||||
QTC_ASSERT(client, return);
|
QTC_ASSERT(client, return);
|
||||||
if (managerInstance->m_shuttingDown)
|
if (managerInstance->m_shuttingDown)
|
||||||
@@ -150,6 +154,7 @@ void LanguageClientManager::clientFinished(Client *client)
|
|||||||
const QList<TextEditor::TextDocument *> &clientDocs
|
const QList<TextEditor::TextDocument *> &clientDocs
|
||||||
= managerInstance->m_clientForDocument.keys(client);
|
= managerInstance->m_clientForDocument.keys(client);
|
||||||
if (client->reset()) {
|
if (client->reset()) {
|
||||||
|
qCDebug(Log) << "restart unexpectedly finished client: " << client->name() << client;
|
||||||
client->disconnect(managerInstance);
|
client->disconnect(managerInstance);
|
||||||
client->log(
|
client->log(
|
||||||
tr("Unexpectedly finished. Restarting in %1 seconds.").arg(restartTimeoutS));
|
tr("Unexpectedly finished. Restarting in %1 seconds.").arg(restartTimeoutS));
|
||||||
@@ -158,6 +163,7 @@ void LanguageClientManager::clientFinished(Client *client)
|
|||||||
client->deactivateDocument(document);
|
client->deactivateDocument(document);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
qCDebug(Log) << "client finished unexpectedly: " << client->name() << client;
|
||||||
client->log(tr("Unexpectedly finished."));
|
client->log(tr("Unexpectedly finished."));
|
||||||
for (TextEditor::TextDocument *document : clientDocs)
|
for (TextEditor::TextDocument *document : clientDocs)
|
||||||
managerInstance->m_clientForDocument.remove(document);
|
managerInstance->m_clientForDocument.remove(document);
|
||||||
@@ -174,6 +180,7 @@ Client *LanguageClientManager::startClient(BaseSettings *setting, ProjectExplore
|
|||||||
QTC_ASSERT(setting, return nullptr);
|
QTC_ASSERT(setting, return nullptr);
|
||||||
QTC_ASSERT(setting->isValid(), return nullptr);
|
QTC_ASSERT(setting->isValid(), return nullptr);
|
||||||
Client *client = setting->createClient(project);
|
Client *client = setting->createClient(project);
|
||||||
|
qCDebug(Log) << "start client: " << client->name() << client;
|
||||||
QTC_ASSERT(client, return nullptr);
|
QTC_ASSERT(client, return nullptr);
|
||||||
client->start();
|
client->start();
|
||||||
managerInstance->m_clientsForSetting[setting->m_id].append(client);
|
managerInstance->m_clientsForSetting[setting->m_id].append(client);
|
||||||
@@ -206,6 +213,7 @@ void LanguageClientManager::shutdownClient(Client *client)
|
|||||||
{
|
{
|
||||||
if (!client)
|
if (!client)
|
||||||
return;
|
return;
|
||||||
|
qCDebug(Log) << "request client shutdown: " << client->name() << client;
|
||||||
// reset the documents for that client already when requesting the shutdown so they can get
|
// reset the documents for that client already when requesting the shutdown so they can get
|
||||||
// reassigned to another server right after this request to another server
|
// reassigned to another server right after this request to another server
|
||||||
for (TextEditor::TextDocument *document : managerInstance->m_clientForDocument.keys(client))
|
for (TextEditor::TextDocument *document : managerInstance->m_clientForDocument.keys(client))
|
||||||
@@ -220,6 +228,7 @@ void LanguageClientManager::deleteClient(Client *client)
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(managerInstance, return);
|
QTC_ASSERT(managerInstance, return);
|
||||||
QTC_ASSERT(client, return);
|
QTC_ASSERT(client, return);
|
||||||
|
qCDebug(Log) << "delete client: " << client->name() << client;
|
||||||
client->disconnect();
|
client->disconnect();
|
||||||
managerInstance->m_clients.removeAll(client);
|
managerInstance->m_clients.removeAll(client);
|
||||||
for (QVector<Client *> &clients : managerInstance->m_clientsForSetting)
|
for (QVector<Client *> &clients : managerInstance->m_clientsForSetting)
|
||||||
@@ -237,6 +246,7 @@ void LanguageClientManager::shutdown()
|
|||||||
QTC_ASSERT(managerInstance, return);
|
QTC_ASSERT(managerInstance, return);
|
||||||
if (managerInstance->m_shuttingDown)
|
if (managerInstance->m_shuttingDown)
|
||||||
return;
|
return;
|
||||||
|
qCDebug(Log) << "shutdown manager";
|
||||||
managerInstance->m_shuttingDown = true;
|
managerInstance->m_shuttingDown = true;
|
||||||
for (Client *client : qAsConst(managerInstance->m_clients))
|
for (Client *client : qAsConst(managerInstance->m_clients))
|
||||||
shutdownClient(client);
|
shutdownClient(client);
|
||||||
@@ -412,6 +422,7 @@ void LanguageClientManager::openDocumentWithClient(TextEditor::TextDocument *doc
|
|||||||
currentClient->deactivateDocument(document);
|
currentClient->deactivateDocument(document);
|
||||||
managerInstance->m_clientForDocument[document] = client;
|
managerInstance->m_clientForDocument[document] = client;
|
||||||
if (client) {
|
if (client) {
|
||||||
|
qCDebug(Log) << "open" << document->filePath() << "with" << client->name() << client;
|
||||||
if (!client->documentOpen(document))
|
if (!client->documentOpen(document))
|
||||||
client->openDocument(document);
|
client->openDocument(document);
|
||||||
else
|
else
|
||||||
|
@@ -25,12 +25,13 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../projectexplorer_export.h"
|
||||||
#include <utils/projectintropage.h>
|
#include <utils/projectintropage.h>
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
|
|
||||||
// Documentation inside.
|
// Documentation inside.
|
||||||
class JsonProjectPage : public Utils::ProjectIntroPage
|
class PROJECTEXPLORER_EXPORT JsonProjectPage : public Utils::ProjectIntroPage
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@@ -603,7 +603,7 @@ double round(double value, int decimal_places) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const std::initializer_list<QStringView> tagAllowList{
|
static const std::initializer_list<QStringView> tagAllowList{
|
||||||
u"path", u"rect", u"polygon", u"circle", u"ellipse"
|
u"path", u"rect", u"line", u"polygon", u"polyline", u"circle", u"ellipse"
|
||||||
};
|
};
|
||||||
|
|
||||||
// fillOpacity and strokeOpacity aren't actual QML properties, but get mapped anyways
|
// fillOpacity and strokeOpacity aren't actual QML properties, but get mapped anyways
|
||||||
@@ -840,6 +840,8 @@ QVariant convertValue(const QByteArray &key, const QString &value)
|
|||||||
return value.toInt();
|
return value.toInt();
|
||||||
} else if (key == "opacity") {
|
} else if (key == "opacity") {
|
||||||
return value.toFloat();
|
return value.toFloat();
|
||||||
|
} else if ((key == "fillColor" || key == "strokeColor") && value == "none") {
|
||||||
|
return "transparent";
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
@@ -1015,6 +1017,28 @@ PropertyMap generateRectProperties(const QDomElement &e, const CSSRules &cssRule
|
|||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PropertyMap generateLineProperties(const QDomElement &e, const CSSRules &cssRules)
|
||||||
|
{
|
||||||
|
QLineF line(e.attribute("x1").toFloat(),
|
||||||
|
e.attribute("y1").toFloat(),
|
||||||
|
e.attribute("x2").toFloat(),
|
||||||
|
e.attribute("y2").toFloat());
|
||||||
|
|
||||||
|
QPainterPath path(line.p1());
|
||||||
|
path.lineTo(line.p2());
|
||||||
|
|
||||||
|
PropertyMap properties;
|
||||||
|
QTransform transform;
|
||||||
|
flattenTransformsAndStyles(e, cssRules, transform, properties);
|
||||||
|
|
||||||
|
path = transform.map(path);
|
||||||
|
|
||||||
|
if (!applyMinimumBoundingBox(path, properties))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
PropertyMap generateEllipseProperties(const QDomElement &e, const CSSRules &cssRules)
|
PropertyMap generateEllipseProperties(const QDomElement &e, const CSSRules &cssRules)
|
||||||
{
|
{
|
||||||
const QPointF center(e.attribute("cx").toFloat(), e.attribute("cy").toFloat());
|
const QPointF center(e.attribute("cx").toFloat(), e.attribute("cy").toFloat());
|
||||||
@@ -1085,7 +1109,7 @@ PropertyMap generatePolygonProperties(const QDomElement &e, const CSSRules &cssR
|
|||||||
for (int i = 0; i < pointList.length(); i += 2)
|
for (int i = 0; i < pointList.length(); i += 2)
|
||||||
polygon.push_back({pointList[i].toFloat(), pointList[i + 1].toFloat()});
|
polygon.push_back({pointList[i].toFloat(), pointList[i + 1].toFloat()});
|
||||||
|
|
||||||
if (!polygon.isClosed() && polygon.size())
|
if (e.tagName() != "polyline" && !polygon.isClosed() && polygon.size())
|
||||||
polygon.push_back(polygon.front());
|
polygon.push_back(polygon.front());
|
||||||
|
|
||||||
QPainterPath path;
|
QPainterPath path;
|
||||||
@@ -1178,6 +1202,11 @@ QmlObjectNode SVGPasteAction::createQmlObjectNode(QmlDesigner::ModelNode &target
|
|||||||
round(tmp[2].toFloat(), 2),
|
round(tmp[2].toFloat(), 2),
|
||||||
round(tmp[3].toFloat(), 2));
|
round(tmp[3].toFloat(), 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
viewBoxProperties.insert("clip", true);
|
||||||
|
} else {
|
||||||
|
viewBox.setWidth(round(rootElement.attribute("width").toFloat(), 2));
|
||||||
|
viewBox.setHeight(round(rootElement.attribute("height").toFloat(), 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
viewBoxProperties.insert("x", viewBox.x());
|
viewBoxProperties.insert("x", viewBox.x());
|
||||||
@@ -1202,8 +1231,6 @@ QmlObjectNode SVGPasteAction::createQmlObjectNode(QmlDesigner::ModelNode &target
|
|||||||
|
|
||||||
depthFirstTraversal(node, processStyleAndCollectShapes);
|
depthFirstTraversal(node, processStyleAndCollectShapes);
|
||||||
|
|
||||||
viewBoxProperties.insert("clip", true);
|
|
||||||
|
|
||||||
ModelNode groupNode = createGroupNode(targetNode, viewBoxProperties);
|
ModelNode groupNode = createGroupNode(targetNode, viewBoxProperties);
|
||||||
|
|
||||||
for (const QDomElement &e : shapeElements) {
|
for (const QDomElement &e : shapeElements) {
|
||||||
@@ -1213,7 +1240,9 @@ QmlObjectNode SVGPasteAction::createQmlObjectNode(QmlDesigner::ModelNode &target
|
|||||||
pathProperties = generatePathProperties(e, cssRules);
|
pathProperties = generatePathProperties(e, cssRules);
|
||||||
else if (e.tagName() == "rect")
|
else if (e.tagName() == "rect")
|
||||||
pathProperties = generateRectProperties(e, cssRules);
|
pathProperties = generateRectProperties(e, cssRules);
|
||||||
else if (e.tagName() == "polygon")
|
else if (e.tagName() == "line")
|
||||||
|
pathProperties = generateLineProperties(e, cssRules);
|
||||||
|
else if (e.tagName() == "polygon" || e.tagName() == "polyline")
|
||||||
pathProperties = generatePolygonProperties(e, cssRules);
|
pathProperties = generatePolygonProperties(e, cssRules);
|
||||||
else if (e.tagName() == "circle" || e.tagName() == "ellipse")
|
else if (e.tagName() == "circle" || e.tagName() == "ellipse")
|
||||||
pathProperties = generateEllipseProperties(e, cssRules);
|
pathProperties = generateEllipseProperties(e, cssRules);
|
||||||
|
@@ -103,8 +103,10 @@ public:
|
|||||||
distributeSpacingHorizontal,
|
distributeSpacingHorizontal,
|
||||||
distributeSpacingVertical,
|
distributeSpacingVertical,
|
||||||
distributeTop,
|
distributeTop,
|
||||||
|
download,
|
||||||
edit,
|
edit,
|
||||||
eyeDropper,
|
eyeDropper,
|
||||||
|
favorite,
|
||||||
flowAction,
|
flowAction,
|
||||||
flowTransition,
|
flowTransition,
|
||||||
fontStyleBold,
|
fontStyleBold,
|
||||||
@@ -155,6 +157,12 @@ public:
|
|||||||
textFullJustification,
|
textFullJustification,
|
||||||
textNumberedList,
|
textNumberedList,
|
||||||
tickIcon,
|
tickIcon,
|
||||||
|
translationCreateFiles,
|
||||||
|
translationCreateReport,
|
||||||
|
translationExport,
|
||||||
|
translationImport,
|
||||||
|
translationSelectLanguages,
|
||||||
|
translationTest,
|
||||||
transparent,
|
transparent,
|
||||||
triState,
|
triState,
|
||||||
triangleArcA,
|
triangleArcA,
|
||||||
|
@@ -63,7 +63,7 @@ static bool itemIsResizable(const QmlItemNode &qmlItemNode)
|
|||||||
&& qmlItemNode.instanceIsResizable()
|
&& qmlItemNode.instanceIsResizable()
|
||||||
&& qmlItemNode.modelIsMovable()
|
&& qmlItemNode.modelIsMovable()
|
||||||
&& qmlItemNode.modelIsResizable()
|
&& qmlItemNode.modelIsResizable()
|
||||||
&& !qmlItemNode.instanceHasRotationTransform()
|
&& !qmlItemNode.instanceHasScaleOrRotationTransform()
|
||||||
&& !qmlItemNode.instanceIsInLayoutable();
|
&& !qmlItemNode.instanceIsInLayoutable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -311,6 +311,7 @@ void DesignDocument::changeToDocumentModel()
|
|||||||
viewManager().detachViewsExceptRewriterAndComponetView();
|
viewManager().detachViewsExceptRewriterAndComponetView();
|
||||||
|
|
||||||
m_inFileComponentModel.reset();
|
m_inFileComponentModel.reset();
|
||||||
|
m_inFileComponentTextModifier.reset();
|
||||||
|
|
||||||
viewManager().attachRewriterView();
|
viewManager().attachRewriterView();
|
||||||
viewManager().attachViewsExceptRewriterAndComponetView();
|
viewManager().attachViewsExceptRewriterAndComponetView();
|
||||||
|
BIN
src/plugins/qmldesigner/components/itemlibrary/images/browse.png
Normal file
After Width: | Height: | Size: 494 B |
After Width: | Height: | Size: 871 B |
@@ -31,5 +31,7 @@
|
|||||||
<file>images/asset_sound_384.png</file>
|
<file>images/asset_sound_384.png</file>
|
||||||
<file>images/x.png</file>
|
<file>images/x.png</file>
|
||||||
<file>images/x@2x.png</file>
|
<file>images/x@2x.png</file>
|
||||||
|
<file>images/browse.png</file>
|
||||||
|
<file>images/browse@2x.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
@@ -42,16 +42,18 @@ QPixmap ItemLibraryAssetsIconProvider::requestPixmap(const QString &id, QSize *s
|
|||||||
{
|
{
|
||||||
QPixmap pixmap;
|
QPixmap pixmap;
|
||||||
const QString suffix = "*." + id.split('.').last().toLower();
|
const QString suffix = "*." + id.split('.').last().toLower();
|
||||||
if (ItemLibraryAssetsModel::supportedFontSuffixes().contains(suffix))
|
if (id == "browse")
|
||||||
|
pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/ItemLibrary/images/browse.png");
|
||||||
|
else if (ItemLibraryAssetsModel::supportedFontSuffixes().contains(suffix))
|
||||||
pixmap = generateFontIcons(id);
|
pixmap = generateFontIcons(id);
|
||||||
else if (ItemLibraryAssetsModel::supportedImageSuffixes().contains(suffix))
|
else if (ItemLibraryAssetsModel::supportedImageSuffixes().contains(suffix))
|
||||||
pixmap = Utils::StyleHelper::dpiSpecificImageFile(id);
|
pixmap = Utils::StyleHelper::dpiSpecificImageFile(id);
|
||||||
else if (ItemLibraryAssetsModel::supportedTexture3DSuffixes().contains(suffix))
|
else if (ItemLibraryAssetsModel::supportedTexture3DSuffixes().contains(suffix))
|
||||||
pixmap = HdrImage{id}.toPixmap();
|
pixmap = HdrImage{id}.toPixmap();
|
||||||
else if (ItemLibraryAssetsModel::supportedShaderSuffixes().contains(suffix))
|
else if (ItemLibraryAssetsModel::supportedShaderSuffixes().contains(suffix))
|
||||||
pixmap = QPixmap(Utils::StyleHelper::dpiSpecificImageFile(":/ItemLibrary/images/asset_shader_48.png"));
|
pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/ItemLibrary/images/asset_shader_48.png");
|
||||||
else if (ItemLibraryAssetsModel::supportedAudioSuffixes().contains(suffix))
|
else if (ItemLibraryAssetsModel::supportedAudioSuffixes().contains(suffix))
|
||||||
pixmap = QPixmap(Utils::StyleHelper::dpiSpecificImageFile(":/ItemLibrary/images/asset_sound_48.png"));
|
pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/ItemLibrary/images/asset_sound_48.png");
|
||||||
|
|
||||||
if (size) {
|
if (size) {
|
||||||
size->setWidth(pixmap.width());
|
size->setWidth(pixmap.width());
|
||||||
|
@@ -275,7 +275,8 @@ void ItemLibraryAssetsModel::setRootPath(const QString &path)
|
|||||||
|
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
m_assetsDir = new ItemLibraryAssetsDir(path, 0, true, this);
|
m_assetsDir = new ItemLibraryAssetsDir(path, 0, true, this);
|
||||||
parseDirRecursive(m_assetsDir, 1);
|
bool noAssets = parseDirRecursive(m_assetsDir, 1);
|
||||||
|
setIsEmpty(noAssets);
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,6 +305,19 @@ const QSet<QString> &ItemLibraryAssetsModel::supportedSuffixes() const
|
|||||||
return allSuffixes;
|
return allSuffixes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ItemLibraryAssetsModel::isEmpty() const
|
||||||
|
{
|
||||||
|
return m_isEmpty;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ItemLibraryAssetsModel::setIsEmpty(bool empty)
|
||||||
|
{
|
||||||
|
if (m_isEmpty != empty) {
|
||||||
|
m_isEmpty = empty;
|
||||||
|
emit isEmptyChanged();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const QSet<QString> &ItemLibraryAssetsModel::previewableSuffixes() const
|
const QSet<QString> &ItemLibraryAssetsModel::previewableSuffixes() const
|
||||||
{
|
{
|
||||||
static QSet<QString> previewableSuffixes;
|
static QSet<QString> previewableSuffixes;
|
||||||
|
@@ -46,13 +46,15 @@ class ItemLibraryAssetsModel : public QAbstractListModel
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(bool isEmpty READ isEmpty WRITE setIsEmpty NOTIFY isEmptyChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ItemLibraryAssetsModel(QmlDesigner::SynchronousImageCache &fontImageCache,
|
ItemLibraryAssetsModel(QmlDesigner::SynchronousImageCache &fontImageCache,
|
||||||
Utils::FileSystemWatcher *fileSystemWatcher,
|
Utils::FileSystemWatcher *fileSystemWatcher,
|
||||||
QObject *parent = nullptr);
|
QObject *parent = nullptr);
|
||||||
|
|
||||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
int rowCount(const QModelIndex & parent = QModelIndex()) const override;
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
void refresh();
|
void refresh();
|
||||||
@@ -82,15 +84,22 @@ public:
|
|||||||
Q_INVOKABLE DirExpandState getAllExpandedState() const;
|
Q_INVOKABLE DirExpandState getAllExpandedState() const;
|
||||||
Q_INVOKABLE void removeFile(const QString &filePath);
|
Q_INVOKABLE void removeFile(const QString &filePath);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void isEmptyChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QSet<QString> &supportedSuffixes() const;
|
const QSet<QString> &supportedSuffixes() const;
|
||||||
|
|
||||||
|
bool isEmpty() const;
|
||||||
|
void setIsEmpty(bool empty);
|
||||||
|
|
||||||
SynchronousImageCache &m_fontImageCache;
|
SynchronousImageCache &m_fontImageCache;
|
||||||
QHash<QString, QPair<QDateTime, QIcon>> m_iconCache;
|
QHash<QString, QPair<QDateTime, QIcon>> m_iconCache;
|
||||||
|
|
||||||
QString m_searchText;
|
QString m_searchText;
|
||||||
Utils::FileSystemWatcher *m_fileSystemWatcher = nullptr;
|
Utils::FileSystemWatcher *m_fileSystemWatcher = nullptr;
|
||||||
ItemLibraryAssetsDir *m_assetsDir = nullptr;
|
ItemLibraryAssetsDir *m_assetsDir = nullptr;
|
||||||
|
bool m_isEmpty = true;
|
||||||
|
|
||||||
QHash<int, QByteArray> m_roleNames;
|
QHash<int, QByteArray> m_roleNames;
|
||||||
inline static QHash<QString, bool> m_expandedStateHash; // <assetPath, isExpanded>
|
inline static QHash<QString, bool> m_expandedStateHash; // <assetPath, isExpanded>
|
||||||
|
@@ -118,6 +118,8 @@ void ItemLibraryView::modelAttached(Model *model)
|
|||||||
m_widget->clearSearchFilter();
|
m_widget->clearSearchFilter();
|
||||||
m_widget->setModel(model);
|
m_widget->setModel(model);
|
||||||
updateImports();
|
updateImports();
|
||||||
|
if (model)
|
||||||
|
m_widget->updatePossibleImports(model->possibleImports());
|
||||||
m_hasErrors = !rewriterView()->errors().isEmpty();
|
m_hasErrors = !rewriterView()->errors().isEmpty();
|
||||||
m_widget->setFlowMode(QmlItemNode(rootModelNode()).isFlowView());
|
m_widget->setFlowMode(QmlItemNode(rootModelNode()).isFlowView());
|
||||||
setResourcePath(DocumentManager::currentResourcePath().toFileInfo().absoluteFilePath());
|
setResourcePath(DocumentManager::currentResourcePath().toFileInfo().absoluteFilePath());
|
||||||
|
@@ -29,12 +29,12 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
// This dialog displays all given type properties of an object and allows the user to choose one
|
// This dialog displays specified properties and allows the user to choose one
|
||||||
ChooseFromPropertyListDialog::ChooseFromPropertyListDialog(const ModelNode &node, TypeName type, QWidget *parent)
|
ChooseFromPropertyListDialog::ChooseFromPropertyListDialog(const QStringList &propNames,
|
||||||
|
QWidget *parent)
|
||||||
: QDialog(parent)
|
: QDialog(parent)
|
||||||
, m_ui(new Ui::ChooseFromPropertyListDialog)
|
, m_ui(new Ui::ChooseFromPropertyListDialog)
|
||||||
{
|
{
|
||||||
m_propertyTypeName = type;
|
|
||||||
m_ui->setupUi(this);
|
m_ui->setupUi(this);
|
||||||
setWindowTitle(tr("Select property"));
|
setWindowTitle(tr("Select property"));
|
||||||
m_ui->label->setText(tr("Bind to property:"));
|
m_ui->label->setText(tr("Bind to property:"));
|
||||||
@@ -50,7 +50,7 @@ ChooseFromPropertyListDialog::ChooseFromPropertyListDialog(const ModelNode &node
|
|||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
});
|
});
|
||||||
|
|
||||||
fillList(node);
|
fillList(propNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
ChooseFromPropertyListDialog::~ChooseFromPropertyListDialog()
|
ChooseFromPropertyListDialog::~ChooseFromPropertyListDialog()
|
||||||
@@ -63,31 +63,80 @@ TypeName ChooseFromPropertyListDialog::selectedProperty() const
|
|||||||
return m_selectedProperty;
|
return m_selectedProperty;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChooseFromPropertyListDialog::fillList(const ModelNode &node)
|
// Create dialog for selecting any property matching newNode type
|
||||||
|
// Subclass type matches are also valid
|
||||||
|
ChooseFromPropertyListDialog *ChooseFromPropertyListDialog::createIfNeeded(
|
||||||
|
const ModelNode &targetNode, const ModelNode &newNode, QWidget *parent)
|
||||||
{
|
{
|
||||||
// Fill the list with all properties of given type
|
TypeName typeName = newNode.type();
|
||||||
const auto metaInfo = node.metaInfo();
|
|
||||||
const auto propNames = metaInfo.propertyNames();
|
// Component matches cases where you don't want to insert a plain component,
|
||||||
const TypeName property(m_propertyTypeName);
|
// such as layer.effect. Also, default property is often a Component (typically 'delegate'),
|
||||||
QStringList nameList;
|
// and inserting into such property will silently overwrite implicit component, if any.
|
||||||
|
if (typeName == "QtQml.Component")
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
const NodeMetaInfo metaInfo = targetNode.metaInfo();
|
||||||
|
const PropertyNameList propNames = metaInfo.propertyNames();
|
||||||
|
QStringList matchingNames;
|
||||||
|
|
||||||
|
// Common base types cause too many rarely valid matches, so they are ignored
|
||||||
|
const QSet<TypeName> ignoredTypes {"<cpp>.QObject",
|
||||||
|
"<cpp>.QQuickItem",
|
||||||
|
"QtQuick.Item",
|
||||||
|
"QtQuick3D.Object3D",
|
||||||
|
"QtQuick3D.Node"};
|
||||||
|
|
||||||
for (const auto &propName : propNames) {
|
for (const auto &propName : propNames) {
|
||||||
if (metaInfo.propertyTypeName(propName) == property)
|
const TypeName testType = metaInfo.propertyTypeName(propName);
|
||||||
nameList.append(QString::fromLatin1(propName));
|
if (!ignoredTypes.contains(testType)
|
||||||
}
|
&& metaInfo.propertyIsWritable(propName)
|
||||||
|
&& (testType == typeName || newNode.isSubclassOf(testType))) {
|
||||||
if (!nameList.isEmpty()) {
|
matchingNames.append(QString::fromLatin1(propName));
|
||||||
QString defaultProp = nameList.first();
|
|
||||||
|
|
||||||
nameList.sort();
|
|
||||||
for (const auto &propName : qAsConst(nameList)) {
|
|
||||||
QListWidgetItem *newItem = new QListWidgetItem(propName);
|
|
||||||
m_ui->listProps->addItem(newItem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Select the default prop
|
|
||||||
m_ui->listProps->setCurrentRow(nameList.indexOf(defaultProp));
|
|
||||||
m_selectedProperty = defaultProp.toLatin1();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!matchingNames.isEmpty())
|
||||||
|
return new ChooseFromPropertyListDialog(matchingNames, parent);
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create dialog for selecting writable properties of exact property type
|
||||||
|
ChooseFromPropertyListDialog *ChooseFromPropertyListDialog::createIfNeeded(
|
||||||
|
const ModelNode &targetNode, TypeName type, QWidget *parent)
|
||||||
|
{
|
||||||
|
const NodeMetaInfo metaInfo = targetNode.metaInfo();
|
||||||
|
const PropertyNameList propNames = metaInfo.propertyNames();
|
||||||
|
const TypeName property(type);
|
||||||
|
QStringList matchingNames;
|
||||||
|
for (const auto &propName : propNames) {
|
||||||
|
if (metaInfo.propertyTypeName(propName) == property && metaInfo.propertyIsWritable(propName))
|
||||||
|
matchingNames.append(QString::fromLatin1(propName));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!matchingNames.isEmpty())
|
||||||
|
return new ChooseFromPropertyListDialog(matchingNames, parent);
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChooseFromPropertyListDialog::fillList(const QStringList &propNames)
|
||||||
|
{
|
||||||
|
if (propNames.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QString defaultProp = propNames.first();
|
||||||
|
QStringList sortedNames = propNames;
|
||||||
|
sortedNames.sort();
|
||||||
|
for (const auto &propName : qAsConst(sortedNames)) {
|
||||||
|
QListWidgetItem *newItem = new QListWidgetItem(propName);
|
||||||
|
m_ui->listProps->addItem(newItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Select the default prop
|
||||||
|
m_ui->listProps->setCurrentRow(sortedNames.indexOf(defaultProp));
|
||||||
|
m_selectedProperty = defaultProp.toLatin1();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -40,16 +40,22 @@ class ChooseFromPropertyListDialog : public QDialog
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ChooseFromPropertyListDialog(const ModelNode &node, TypeName type, QWidget *parent = 0);
|
|
||||||
~ChooseFromPropertyListDialog();
|
~ChooseFromPropertyListDialog();
|
||||||
|
|
||||||
TypeName selectedProperty() const;
|
TypeName selectedProperty() const;
|
||||||
|
|
||||||
|
static ChooseFromPropertyListDialog *createIfNeeded(const ModelNode &targetNode,
|
||||||
|
const ModelNode &newNode,
|
||||||
|
QWidget *parent = 0);
|
||||||
|
static ChooseFromPropertyListDialog *createIfNeeded(const ModelNode &targetNode,
|
||||||
|
TypeName type,
|
||||||
|
QWidget *parent = 0);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void fillList(const ModelNode &node);
|
explicit ChooseFromPropertyListDialog(const QStringList &propNames, QWidget *parent = 0);
|
||||||
|
void fillList(const QStringList &propNames);
|
||||||
|
|
||||||
Ui::ChooseFromPropertyListDialog *m_ui;
|
Ui::ChooseFromPropertyListDialog *m_ui;
|
||||||
TypeName m_selectedProperty;
|
TypeName m_selectedProperty;
|
||||||
TypeName m_propertyTypeName;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -739,25 +739,13 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ModelNode targetNode = targetProperty.parentModelNode();
|
ModelNode targetNode = targetProperty.parentModelNode();
|
||||||
NodeMetaInfo metaInfo = targetNode.metaInfo();
|
ChooseFromPropertyListDialog *dialog = ChooseFromPropertyListDialog::createIfNeeded(
|
||||||
TypeName typeName = newModelNode.type();
|
targetNode, newModelNode, Core::ICore::dialogParent());
|
||||||
|
if (dialog) {
|
||||||
// Empty components are not supported and having one as property value is generally
|
dialog->exec();
|
||||||
// unstable, so let's not offer user to put a fresh Component into a property
|
if (dialog->result() == QDialog::Accepted)
|
||||||
if (typeName != "QtQml.Component") {
|
targetNode.bindingProperty(dialog->selectedProperty()).setExpression(newModelNode.validId());
|
||||||
const PropertyNameList nameList = targetNode.metaInfo().directPropertyNames();
|
delete dialog;
|
||||||
for (const auto &propertyName : nameList) {
|
|
||||||
auto testType = metaInfo.propertyTypeName(propertyName);
|
|
||||||
if (testType == typeName || newModelNode.isSubclassOf(testType)) {
|
|
||||||
ChooseFromPropertyListDialog *dialog = nullptr;
|
|
||||||
dialog = new ChooseFromPropertyListDialog(targetNode, testType, Core::ICore::dialogParent());
|
|
||||||
dialog->exec();
|
|
||||||
if (dialog->result() == QDialog::Accepted)
|
|
||||||
targetNode.bindingProperty(dialog->selectedProperty()).setExpression(newModelNode.validId());
|
|
||||||
delete dialog;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1015,10 +1003,13 @@ bool NavigatorTreeModel::dropAsImage3dTexture(const ModelNode &targetNode,
|
|||||||
if (targetNode.isSubclassOf("QtQuick3D.Material")) {
|
if (targetNode.isSubclassOf("QtQuick3D.Material")) {
|
||||||
// if dropping an image on a default material, create a texture instead of image
|
// if dropping an image on a default material, create a texture instead of image
|
||||||
ChooseFromPropertyListDialog *dialog = nullptr;
|
ChooseFromPropertyListDialog *dialog = nullptr;
|
||||||
if (targetNode.isSubclassOf("QtQuick3D.DefaultMaterial") || targetNode.isSubclassOf("QtQuick3D.PrincipledMaterial")) {
|
if (targetNode.isSubclassOf("QtQuick3D.DefaultMaterial")
|
||||||
|
|| targetNode.isSubclassOf("QtQuick3D.PrincipledMaterial")) {
|
||||||
// Show texture property selection dialog
|
// Show texture property selection dialog
|
||||||
dialog = new ChooseFromPropertyListDialog(targetNode, "QtQuick3D.Texture", Core::ICore::dialogParent());
|
dialog = ChooseFromPropertyListDialog::createIfNeeded(targetNode, "QtQuick3D.Texture",
|
||||||
dialog->exec();
|
Core::ICore::dialogParent());
|
||||||
|
if (dialog)
|
||||||
|
dialog->exec();
|
||||||
}
|
}
|
||||||
if (!dialog || dialog->result() == QDialog::Accepted) {
|
if (!dialog || dialog->result() == QDialog::Accepted) {
|
||||||
m_view->executeInTransaction("NavigatorTreeModel::dropAsImage3dTexture", [&] {
|
m_view->executeInTransaction("NavigatorTreeModel::dropAsImage3dTexture", [&] {
|
||||||
|
@@ -99,7 +99,7 @@ public:
|
|||||||
bool instanceIsMovable() const;
|
bool instanceIsMovable() const;
|
||||||
bool instanceIsResizable() const;
|
bool instanceIsResizable() const;
|
||||||
bool instanceIsInLayoutable() const;
|
bool instanceIsInLayoutable() const;
|
||||||
bool instanceHasRotationTransform() const;
|
bool instanceHasScaleOrRotationTransform() const;
|
||||||
|
|
||||||
bool modelIsMovable() const;
|
bool modelIsMovable() const;
|
||||||
bool modelIsResizable() const;
|
bool modelIsResizable() const;
|
||||||
|