Merge remote-tracking branch 'origin/6.0'

Conflicts:
	src/libs/utils/theme/theme_mac.mm
	src/plugins/android/androiddeployqtstep.cpp
	src/plugins/debugger/lldb/lldbengine.cpp

Change-Id: I5f2c62e0bce6c91a53a554b3278dbe23ff7dde36
This commit is contained in:
Eike Ziller
2021-11-11 11:54:41 +01:00
129 changed files with 4084 additions and 328 deletions

41
dist/changes-6.0.0.md vendored
View File

@@ -29,16 +29,24 @@ Editing
* Added option for saving open files automatically after refactoring
(QTCREATORBUG-25924)
* Added information about source to tooltip on diagnostics
* Fixed `Insert Definition` for templates with value parameters
(QTCREATORBUG-26113)
* Added highlighting color option for namespaces (QTCREATORBUG-16580)
* 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 crash when checking for refactoring actions (QTCREATORBUG-26316)
* Fixed wrong target compiler option (QTCREATORBUG-25615)
* Fixed parentheses matching (QTCREATORBUG-26400)
* Fixed documentation comment generation for template types (QTCREATORBUG-9620)
* Clangd
* Added warning for older `clangd` versions
* Added support for completion and function hint
* Added option for `Insert header files on completion`
* Improved location of generated `compile_commands.json` (QTCREATORBUG-26431)
* Fixed missing reparsing after refactorings (QTCREATORBUG-26523)
### QML
@@ -66,6 +74,7 @@ Projects
(QTCREATORBUG-26422)
* Fixed that re-detecting compilers removed compilers from kits
(QTCREATORBUG-25697)
* Fixed GitHub action created by Qt Creator plugin wizard for Qt 6
### CMake
@@ -79,6 +88,7 @@ Projects
QTCREATORBUG-26238, QTCREATORBUG-21452, QTCREATORBUG-25644,
QTCREATORBUG-25782)
* Fixed that generated files were selected for analyzing (QTCREATORBUG-25125)
* Fixed importing of Qt projects (QTCREATORBUG-25767)
### qmake
@@ -88,6 +98,11 @@ Projects
* 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
---------
@@ -97,6 +112,11 @@ Debugging
* Fixed variable expansion for `Additional Startup Commands`
(QTCREATORBUG-26382)
### CDB
* Added hint for missing Qt debug information
* Improved pretty printing for Qt 6 without debug information
Version Control Systems
-----------------------
@@ -117,9 +137,16 @@ Test Integration
Platforms
---------
### Windows
* Added support for MSVC 2022
### macOS
* 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
@@ -127,11 +154,16 @@ Platforms
selector (QTCREATORBUG-23991)
* Added details to device settings (QTCREATORBUG-23991)
* Added filter field for Android SDK manager
* Fixed that NDK 22 and later could not be added
### WebAssembly
* Fixed running applications (QTCREATORBUG-25905, QTCREATORBUG-26189)
### MCU
* Added preliminary support for SDK 2.0
### Docker
* Various improvements
@@ -147,6 +179,7 @@ André Pönitz
Artem Sokolovskii
Artur Shepilko
Assam Boudjelthia
BogDan Vatra
Christiaan Janssen
Christian Kandeler
Christian Stenger
@@ -160,6 +193,7 @@ Ivan Komissarov
Jaroslaw Kobus
Johanna Vanhatapio
Jonas Karlsson
Jonas Singe
Kai Köhne
Kama Wójcik
Knud Dollereder
@@ -171,9 +205,11 @@ Marco Bubke
Martin Kampas
Miikka Heikkinen
Miina Puuronen
Oliver Wolff
Orgad Shaneh
Petar Perisin
Piotr Mikolajczyk
Robert Löhning
Samuel Ghinet
Shantanu Tushar
Tapani Mattila
@@ -181,6 +217,7 @@ Tasuku Suzuki
Thiago Macieira
Thomas Hartmann
Tim Jenssen
Tomi Korpipaa
Tony Leinonen
Tor Arne Vestbø
Tuomo Pelkonen

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -135,6 +135,9 @@
case-sensitivity. Select \uicontrol {Show Non-matching Lines} to
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
(\uicontrol {Zoom In}) or \inlineimage minus.png
(\uicontrol {Zoom Out}), or press \key Ctrl++ or \key Ctrl+-.
@@ -197,5 +200,5 @@
\image qtcreator-cmake-clean-steps.png
The build errors and warnings are parsed and displayed in the
\uicontrol Issues output pane.
\l Issues output pane.
*/

View File

@@ -57,18 +57,19 @@
a \c CMakeLists.txt configuration file in a project. Project information is
also automatically refreshed when you build the project.
The \uicontrol {File System} section in the sidebar \uicontrol 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-edit.png "CMake project in Projects view"
\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
\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:
@@ -144,6 +145,8 @@
\endlist
Warnings and errors are displayed in the \l {Issues} output pane.
\section1 Adding External Libraries to CMake Projects
Through external libraries, \QC can support code completion and syntax

View File

@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -57,7 +57,7 @@
applications for multiple desktop and \l{glossary-device}{device}
platforms.
\li \l{Using Other Build Systems}
\li \l{Build Systems}
\QC is integrated with cross-platform systems for build automation:
qmake, Qbs, CMake, and Autotools. In addition, you can import

View File

@@ -515,7 +515,7 @@
\li \l{Opening Projects}
\li \l{Adding Libraries to Projects}
\li \l{Adding New Custom Wizards}
\li \l{Using Other Build Systems}
\li \l{Build Systems}
\endlist
*/

View File

@@ -34,7 +34,7 @@
\page creator-project-other.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
building the project: qmake, CMake, Meson, or Qbs. qmake is installed and

View File

@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Creator documentation.
@@ -75,7 +75,7 @@
\section1 Related Topics
\list
\li \l{Using Other Build Systems}
\li \l{Build Systems}
\endlist
*/

View File

@@ -212,7 +212,7 @@
\li \l {Embedded Platforms}
\li \l {Mobile Platforms}
\endlist
\li \l{Using Other Build Systems}
\li \l{Build Systems}
\list
\li \l{Setting Up CMake}
\li \l{Setting Up Qbs}

View File

@@ -113,7 +113,7 @@
\li \b {\l{Advanced Use}}
\list
\li \l{Supported Platforms}
\li \l{Using Other Build Systems}
\li \l{Build Systems}
\li \l{Using Command Line Options}
\li \l{Keyboard Shortcuts}
\li \l{Using External Tools}

View File

@@ -1,6 +1,6 @@
/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** 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
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
\uicontrol Commit to start committing.
@@ -223,10 +236,22 @@
\section2 Amending Commits
To apply latest changes to the last commit, select
\uicontrol {Amend Last Commit}. You can also edit the commit message.
To apply latest changes to the last commit, select \uicontrol Tools >
\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
\uicontrol Tools > \uicontrol Git > \uicontrol {Local Repository} >
\uicontrol {Fixup Previous Commit}. This operation is done using interactive
rebase. In case of conflicts, a merge tool is suggested.

View File

@@ -30,6 +30,28 @@
\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"
\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
\l {Creating Projects}.
To import designs to \QDS projects:
To import assets exported in \QB to \QDS projects:
\list 1
\li Select \uicontrol File > \uicontrol {New File or Project} >
@@ -107,4 +129,5 @@
design tool and export the assets again.
\include qtbridge-tutorial-links.qdocinc qtsketchbridge tutorials
*/

View File

@@ -43,17 +43,27 @@
For more information about exporting 3D graphics, see
\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
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
\li In the \l{Design Views}{Design mode}, select \l Library >
\uicontrol Assets > \inlineimage plus.png
@@ -67,6 +77,17 @@
\li When the import is done, select \uicontrol Close.
\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 >
\uicontrol Components > \uicontrol {My 3D Components}. You can add it to
your UI by dragging-and-dropping it to \l {3D Editor}.

View File

@@ -119,9 +119,13 @@
\section1 Assets
\uicontrol Library > \uicontrol {Assets} displays the images and other files
that you add to the project folder by selecting \inlineimage plus.png
. To add assets to your UI, drag-and-drop them to \l Navigator or
\l {Form Editor}.
that you add to the project folder by dragging-and-dropping external asset
files to \QDS or by selecting \inlineimage plus.png
. 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
holding \key Ctrl and clicking the asset files you wish to select.

View File

@@ -252,8 +252,9 @@ class DumperBase():
#DumperBase.warn('EXPANDED INAMES: %s' % self.expandedINames)
#DumperBase.warn('WATCHERS: %s' % self.watchers)
def setFallbackQtVersion(self, version):
self.warn("got fallback qt version %x" % version)
def setFallbackQtVersion(self, args):
version = int(args.get('version', self.fallbackQtVersion))
DumperBase.warn("got fallback qt version 0x%x" % version)
self.fallbackQtVersion = version
def resetPerStepCaches(self):
@@ -1135,12 +1136,18 @@ class DumperBase():
if displayFormat != DisplayFormat.Raw and p:
if innerType.name in (
'char',
'int8_t',
'qint8',
'wchar_t',
'unsigned char',
'uint8_t',
'quint8',
'signed char',
'CHAR',
'WCHAR'
'WCHAR',
'char8_t',
'char16_t',
'char32_t'
):
self.putCharArrayHelper(p, n, innerType, self.currentItemFormat(),
makeExpandable=False)
@@ -1406,11 +1413,17 @@ class DumperBase():
if innerType.name not in (
'char',
'signed char',
'int8_t',
'qint8',
'unsigned char',
'uint8_t',
'quint8',
'wchar_t',
'CHAR',
'WCHAR'
'WCHAR',
'char8_t',
'char16_t',
'char32_t'
):
self.putDerefedPointer(value)
return
@@ -3628,15 +3641,33 @@ class DumperBase():
res = {
'bool': 'int:1',
'char': 'int:1',
'int8_t': 'int:1',
'qint8': 'int:1',
'signed char': 'int:1',
'char8_t': 'uint:1',
'unsigned char': 'uint:1',
'uint8_t': 'uint:1',
'quint8': 'uint:1',
'short': 'int:2',
'int16_t': 'int:2',
'qint16': 'int:2',
'unsigned short': 'uint:2',
'char16_t': 'uint:2',
'uint16_t': 'uint:2',
'quint16': 'uint:2',
'int': 'int:4',
'int32_t': 'int:4',
'qint32': 'int:4',
'unsigned int': 'uint:4',
'char32_t': 'uint:4',
'uint32_t': 'uint:4',
'quint32': 'uint:4',
'long long': 'int:8',
'int64_t': 'int:8',
'qint64': 'int:8',
'unsigned long long': 'uint:8',
'uint64_t': 'uint:8',
'quint64': 'uint:8',
'float': 'float:4',
'double': 'float:8',
'QChar': 'uint:2'

View File

@@ -1393,14 +1393,19 @@ void NodeInstanceServer::setTranslationLanguage(const QString &language)
engine()->setUiLanguage(language);
#endif
static QPointer<MultiLanguage::Translator> multilanguageTranslator;
if (!MultiLanguage::databaseFilePath().isEmpty()) {
if (!multilanguageLink) {
multilanguageLink = std::make_unique<MultiLanguage::Link>();
multilanguageTranslator = multilanguageLink->translator().release();
QCoreApplication::installTranslator(multilanguageTranslator);
if (!MultiLanguage::databaseFilePath().isEmpty()
&& QFileInfo::exists(QString::fromUtf8(MultiLanguage::databaseFilePath()))) {
try {
if (!multilanguageLink) {
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);
}
}

View File

@@ -32,6 +32,8 @@ import StudioControls 1.0 as StudioControls
import StudioTheme 1.0 as StudioTheme
Item {
id: rootItem
property var selectedAssets: ({})
property int allExpandedState: 0
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
}
}
}

View File

@@ -105,8 +105,11 @@ Item {
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
anchors.centerIn: parent
color: tabBar.currentIndex === index ? StudioTheme.Values.themeIconColorSelected
: StudioTheme.Values.themeIconColor
color: !plusButton.enabled
? StudioTheme.Values.themeIconColorDisabled
: tabBar.currentIndex === index
? StudioTheme.Values.themeIconColorSelected
: StudioTheme.Values.themeIconColor
}
HelperWidgets.ToolTipArea {

View File

@@ -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
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
}
}
}

View File

@@ -0,0 +1 @@
DefaultProject 1.0 DefaultProject.qml

View File

@@ -30,6 +30,9 @@ import StudioTheme 1.0 as StudioTheme
Item {
id: section
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 topPadding: 4
property int rightPadding: 0

View File

@@ -23,7 +23,7 @@
**
****************************************************************************/
import QtQuick 2.10
import QtQuick 2.15
QtObject {
readonly property int width: 1920
@@ -95,84 +95,92 @@ QtObject {
readonly property string distributeSpacingHorizontal: "\u005A"
readonly property string distributeSpacingVertical: "\u005B"
readonly property string distributeTop: "\u005C"
readonly property string edit: "\u005D"
readonly property string eyeDropper: "\u005E"
readonly property string flowAction: "\u005F"
readonly property string flowTransition: "\u0060"
readonly property string fontStyleBold: "\u0061"
readonly property string fontStyleItalic: "\u0062"
readonly property string fontStyleStrikethrough: "\u0063"
readonly property string fontStyleUnderline: "\u0064"
readonly property string gradient: "\u0065"
readonly property string gridView: "\u0066"
readonly property string idAliasOff: "\u0067"
readonly property string idAliasOn: "\u0068"
readonly property string infinity: "\u0069"
readonly property string keyframe: "\u006A"
readonly property string linkTriangle: "\u006B"
readonly property string linked: "\u006C"
readonly property string listView: "\u006D"
readonly property string lockOff: "\u006E"
readonly property string lockOn: "\u006F"
readonly property string mergeCells: "\u0070"
readonly property string minus: "\u0071"
readonly property string mirror: "\u0072"
readonly property string orientation: "\u0073"
readonly property string paddingEdge: "\u0074"
readonly property string paddingFrame: "\u0075"
readonly property string pasteStyle: "\u0076"
readonly property string pause: "\u0077"
readonly property string pin: "\u0078"
readonly property string play: "\u0079"
readonly property string plus: "\u007A"
readonly property string promote: "\u007B"
readonly property string readOnly: "\u007C"
readonly property string redo: "\u007D"
readonly property string rotationFill: "\u007E"
readonly property string rotationOutline: "\u007F"
readonly property string search: "\u0080"
readonly property string sectionToggle: "\u0081"
readonly property string splitColumns: "\u0082"
readonly property string splitRows: "\u0083"
readonly property string startNode: "\u0084"
readonly property string testIcon: "\u0085"
readonly property string textAlignBottom: "\u0086"
readonly property string textAlignCenter: "\u0087"
readonly property string textAlignJustified: "\u0088"
readonly property string textAlignLeft: "\u0089"
readonly property string textAlignMiddle: "\u008A"
readonly property string textAlignRight: "\u008B"
readonly property string textAlignTop: "\u008C"
readonly property string textBulletList: "\u008D"
readonly property string textFullJustification: "\u008E"
readonly property string textNumberedList: "\u008F"
readonly property string tickIcon: "\u0090"
readonly property string transparent: "\u0091"
readonly property string triState: "\u0092"
readonly property string triangleArcA: "\u0093"
readonly property string triangleArcB: "\u0094"
readonly property string triangleCornerA: "\u0095"
readonly property string triangleCornerB: "\u0096"
readonly property string unLinked: "\u0097"
readonly property string undo: "\u0098"
readonly property string unpin: "\u0099"
readonly property string upDownIcon: "\u009A"
readonly property string upDownSquare2: "\u009B"
readonly property string visibilityOffBroken: "\u009C" // visibilityOff
readonly property string visibilityOff: "\u009D" // visibilityOff2
readonly property string visibilityOn: "\u009E"
readonly property string wildcard: "\u009F"
readonly property string wizardsAutomotive: "\u00A0"
readonly property string wizardsDesktop: "\u00A1"
readonly property string wizardsGeneric: "\u00A2"
readonly property string wizardsMcuEmpty: "\u00A3"
readonly property string wizardsMcuGraph: "\u00A4"
readonly property string wizardsMobile: "\u00A5"
readonly property string wizardsUnknown: "\u00A6"
readonly property string zoomAll: "\u00A7"
readonly property string zoomIn: "\u00A8"
readonly property string zoomOut: "\u00A9"
readonly property string zoomSelection: "\u00AA"
readonly property string download: "\u005D"
readonly property string edit: "\u005E"
readonly property string eyeDropper: "\u005F"
readonly property string favorite: "\u0060"
readonly property string flowAction: "\u0061"
readonly property string flowTransition: "\u0062"
readonly property string fontStyleBold: "\u0063"
readonly property string fontStyleItalic: "\u0064"
readonly property string fontStyleStrikethrough: "\u0065"
readonly property string fontStyleUnderline: "\u0066"
readonly property string gradient: "\u0067"
readonly property string gridView: "\u0068"
readonly property string idAliasOff: "\u0069"
readonly property string idAliasOn: "\u006A"
readonly property string infinity: "\u006B"
readonly property string keyframe: "\u006C"
readonly property string linkTriangle: "\u006D"
readonly property string linked: "\u006E"
readonly property string listView: "\u006F"
readonly property string lockOff: "\u0070"
readonly property string lockOn: "\u0071"
readonly property string mergeCells: "\u0072"
readonly property string minus: "\u0073"
readonly property string mirror: "\u0074"
readonly property string orientation: "\u0075"
readonly property string paddingEdge: "\u0076"
readonly property string paddingFrame: "\u0077"
readonly property string pasteStyle: "\u0078"
readonly property string pause: "\u0079"
readonly property string pin: "\u007A"
readonly property string play: "\u007B"
readonly property string plus: "\u007C"
readonly property string promote: "\u007D"
readonly property string readOnly: "\u007E"
readonly property string redo: "\u007F"
readonly property string rotationFill: "\u0080"
readonly property string rotationOutline: "\u0081"
readonly property string search: "\u0082"
readonly property string sectionToggle: "\u0083"
readonly property string splitColumns: "\u0084"
readonly property string splitRows: "\u0085"
readonly property string startNode: "\u0086"
readonly property string testIcon: "\u0087"
readonly property string textAlignBottom: "\u0088"
readonly property string textAlignCenter: "\u0089"
readonly property string textAlignJustified: "\u008A"
readonly property string textAlignLeft: "\u008B"
readonly property string textAlignMiddle: "\u008C"
readonly property string textAlignRight: "\u008D"
readonly property string textAlignTop: "\u008E"
readonly property string textBulletList: "\u008F"
readonly property string textFullJustification: "\u0090"
readonly property string textNumberedList: "\u0091"
readonly property string tickIcon: "\u0092"
readonly property string translationCreateFiles: "\u0093"
readonly property string translationCreateReport: "\u0094"
readonly property string translationExport: "\u0095"
readonly property string translationImport: "\u0096"
readonly property string translationSelectLanguages: "\u0097"
readonly property string translationTest: "\u0098"
readonly property string transparent: "\u0099"
readonly property string triState: "\u009A"
readonly property string triangleArcA: "\u009B"
readonly property string triangleArcB: "\u009C"
readonly property string triangleCornerA: "\u009D"
readonly property string triangleCornerB: "\u009E"
readonly property string unLinked: "\u009F"
readonly property string undo: "\u00A0"
readonly property string unpin: "\u00A1"
readonly property string upDownIcon: "\u00A2"
readonly property string upDownSquare2: "\u00A3"
readonly property string visibilityOffBroken: "\u00A4" // visibilityOff
readonly property string visibilityOff: "\u00A5" // visibilityOff2
readonly property string visibilityOn: "\u00A6"
readonly property string wildcard: "\u00A7"
readonly property string wizardsAutomotive: "\u00A8"
readonly property string wizardsDesktop: "\u00A9"
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({
"family": controlIcons.name,

View File

@@ -1034,7 +1034,7 @@ void Lexer::scanPreprocessorNumber(Token *tok, bool dotAlreadySkipped)
yyinp();
if (_yychar == '+' || _yychar == '-')
yyinp();
} else if (std::isalnum(_yychar) || _yychar == '_' || _yychar == '.') {
} else if (std::isalnum(_yychar) || (_yychar == '\'') || _yychar == '_' || _yychar == '.') {
yyinp();
} else {
scanOptionalUserDefinedLiteral(tok);

View File

@@ -910,7 +910,7 @@ bool ResolveExpression::visit(CallAST *ast)
if (Symbol *declaration = templateTy->declaration()) {
if (Function *funTy = declaration->asFunction()) {
if (maybeValidPrototype(funTy, actualArgumentCount))
addResult(funTy->returnType().simplified(), _scope);
addResult(funTy->returnType().simplified(), scope);
}
}
}

View File

@@ -136,6 +136,7 @@ static Utils::optional<Tool> unzipTool(const FilePath &src, const FilePath &dest
const QString destStr = dest.toString();
const QString args = result.command.arguments().replace("%{src}", srcStr).replace("%{dest}", destStr);
result.command.setArguments(args);
return result;
}
}
return {};

View File

@@ -41,7 +41,7 @@ namespace Internal {
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, *)) {
auto appearance = [NSApp.effectiveAppearance
bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]];

View File

@@ -57,7 +57,6 @@ add_subdirectory(scxmleditor)
add_subdirectory(subversion)
add_subdirectory(compilationdatabaseprojectmanager)
add_subdirectory(languageclient)
add_subdirectory(studiowelcome)
# Level 6:
add_subdirectory(cmakeprojectmanager)
@@ -93,6 +92,7 @@ if (WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(qmldesigner_builddir ${PROJECT_BINARY_DIR}/qmldsgnr)
endif()
add_subdirectory(qmldesigner ${qmldesigner_builddir})
add_subdirectory(studiowelcome)
add_subdirectory(qnx)
add_subdirectory(webassembly)
add_subdirectory(mcusupport)

View File

@@ -562,6 +562,16 @@ FilePath AndroidConfig::gdbPathFromNdk(const Abi &abi, const FilePath &ndkLocati
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
{
return ndkLocation.pathAppended(
@@ -1240,39 +1250,79 @@ static QString getMultiOrSingleAbiString(const QStringList &abis)
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,
const QStringList &abisList,
bool customDebugger = false)
{
const auto &currentConfig = AndroidConfigurations::currentConfig();
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
const Debugger::DebuggerItem *existing = Debugger::DebuggerItemManager::findByCommand(command);
const Debugger::DebuggerItem *existingGdb = existingDebugger(gdbCommand,
Debugger::GdbEngineType);
// Return existing debugger with same command
if (existing && existing->engineType() == Debugger::GdbEngineType
&& existing->isAutoDetected()) {
return existing->id();
if (existingGdb)
return existingGdb->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.setCommand(command);
debugger.setCommand(gdbCommand);
debugger.setEngineType(Debugger::GdbEngineType);
// NDK 10 and older have multiple gdb versions per ABI, so check for that.
const bool oldNdkVersion = currentConfig.ndkVersion(ndk) <= QVersionNumber{11};
QString mainName = AndroidConfigurations::tr("Android Debugger (%1, NDK %2)");
if (customDebugger)
mainName.prepend("Custom ");
debugger.setUnexpandedDisplayName(mainName
debugger.setUnexpandedDisplayName(custom + mainName
.arg(getMultiOrSingleAbiString(oldNdkVersion ? abisList : allSupportedAbis()))
.arg(AndroidConfigurations::currentConfig().ndkVersion(ndk).toString()));
.arg(AndroidConfigurations::currentConfig().ndkVersion(ndk).toString())
+ ' ' + debugger.engineTypeName());
debugger.setAutoDetected(true);
debugger.reinitializeFromFile();
return Debugger::DebuggerItemManager::registerDebugger(debugger);
QVariant registeredGdb = Debugger::DebuggerItemManager::registerDebugger(debugger);
return registeredLldb.isNull() ? registeredGdb : registeredLldb;
}
void AndroidConfigurations::registerCustomToolChainsAndDebuggers()

View File

@@ -140,6 +140,7 @@ public:
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 lldbPathFromNdk(const Utils::FilePath &ndkLocation) const;
Utils::FilePath makePathFromNdk(const Utils::FilePath &ndkLocation) const;
Utils::FilePath keytoolPath() const;

View File

@@ -428,7 +428,7 @@ void AndroidDeviceManager::updateDevicesList()
void AndroidDeviceManager::updateDevicesListOnce()
{
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]() {
return m_androidConfig.connectedDevices();
}));

View File

@@ -246,11 +246,6 @@ bool AndroidManager::isQtCreatorGenerated(const FilePath &deploymentFile)
return QJsonDocument::fromJson(f.readAll()).object()["_description"].toString() == qtcSignature;
}
FilePath AndroidManager::dirPath(const Target *target)
{
return androidBuildDirectory(target);
}
FilePath AndroidManager::androidBuildDirectory(const Target *target)
{
return buildDirectory(target) / Constants::ANDROID_BUILD_DIRECTORY;

View File

@@ -95,8 +95,6 @@ public:
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 buildDirectory(const ProjectExplorer::Target *target);
static Utils::FilePath manifestPath(const ProjectExplorer::Target *target);

View File

@@ -166,7 +166,7 @@ void AndroidManifestEditorIconWidget::selectIcon()
{
FilePath file = FileUtils::getOpenFilePath(this, m_iconSelectionText,
FileUtils::homePath(),
tr("Images (*.png *.jpg *.webp *.svg)"));
tr("Images (*.png *.jpg *.jpeg *.webp *.svg)"));
if (file.isEmpty())
return;
setIconFromPath(file);

View File

@@ -62,7 +62,7 @@ const char splashscreenFileName[] = "logo";
const char splashscreenPortraitFileName[] = "logo_port";
const char splashscreenLandscapeFileName[] = "logo_land";
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 mediumDpiImageSize{320, 480};
const QSize highDpiImageSize{480, 800};
@@ -608,8 +608,8 @@ void SplashScreenContainerWidget::checkSplashscreenImage(const QString &name)
for (const QString &path : paths) {
const FilePath filePath = baseDir.pathAppended(path + name);
if (filePath.stringAppended(".png").exists()
|| filePath.stringAppended(".jpg").exists()) {
if (filePath.stringAppended(".png").exists() || filePath.stringAppended(".jpg").exists()
|| filePath.stringAppended(".jpeg").exists()) {
setCurrentIndex(1);
break;
}

View File

@@ -189,7 +189,8 @@ void SplashScreenWidget::selectImage()
{
const FilePath file = FileUtils::getOpenFilePath(this, m_imageSelectionText,
FileUtils::homePath(),
QStringLiteral("%1 (*.png *.jpg)").arg(tr("Images")));
QStringLiteral("%1 (*.png *.jpg *.jpeg)")
.arg(tr("Images")));
if (file.isEmpty())
return;
setImageFromPath(file, false);

View File

@@ -55,6 +55,7 @@ QStringList filterInterfering(const QStringList &provided, QStringList *omitted)
"--gtest_stream_result_to=",
"--gtest_break_on_failure",
"--gtest_throw_on_failure",
"--gtest_catch_exceptions=",
"--gtest_print_time="
};
@@ -100,6 +101,7 @@ QStringList GTestConfiguration::argumentsForTestRunner(QStringList *omitted) con
if (isDebugRunMode()) {
if (gSettings->breakOnFailure.value())
arguments << "--gtest_break_on_failure";
arguments << "--gtest_catch_exceptions=0";
}
return arguments;
}

View File

@@ -61,3 +61,14 @@ extend_qtc_plugin(ClangCodeModel
test/clangdtests.cpp test/clangdtests.h
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}
)

View File

@@ -252,6 +252,16 @@ public:
QString theType = type();
if (theType.endsWith("const"))
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 refCount = theType.count('&') - 2 * xrefCount;
const int ptrRefCount = theType.count('*') + refCount;
@@ -2443,6 +2453,8 @@ static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
return true;
}
if (it->kind() == "Lambda")
return false;
if (it->kind().endsWith("Cast") && it->hasConstType())
return false;
if (it->kind() == "Member" && it->arcanaContains("(")
@@ -3140,6 +3152,18 @@ void ExtraHighlightingResultsCollector::insertResult(const HighlightingResult &r
return;
const auto it = std::lower_bound(m_results.begin(), m_results.end(), result, lessThan);
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"
<< result.line << result.column << result.length;
m_results.insert(it, result);

View File

@@ -112,6 +112,7 @@ ClangModelManagerSupport::ClangModelManagerSupport()
m_instance = this;
watchForExternalChanges();
watchForInternalChanges();
cppModelManager()->setCurrentDocumentFilter(std::make_unique<ClangdCurrentDocumentFilter>());
cppModelManager()->setLocatorFilter(std::make_unique<ClangGlobalSymbolFilter>());
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)
{
QTC_ASSERT(editor, return);

View File

@@ -135,8 +135,8 @@ private:
ClangdClient *createClient(ProjectExplorer::Project *project, const Utils::FilePath &jsonDbDir);
void claimNonProjectSources(ClangdClient *fallbackClient);
void watchForExternalChanges();
void watchForInternalChanges();
private:
UiHeaderOnDiskManager m_uiHeaderOnDiskManager;
BackendCommunicator m_communicator;
ClangCompletionAssistProvider m_completionAssistProvider;

View File

@@ -1249,6 +1249,9 @@ void ClangdTestHighlighting::test_data()
QTest::newRow("const argument to unnamed lambda") << 830 << 16 << 830 << 19
<< 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()

View File

@@ -834,3 +834,15 @@ void assignmentTest() {
struct 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) {});
}

View File

@@ -421,10 +421,13 @@ QTextCursor BaseTextFind::findOne(const QRegularExpression &expr,
QTextCursor found = document()->find(expr, from, options);
while (!found.isNull() && !inScope(found)) {
if (!found.hasSelection()) {
from = found;
found.movePosition(options & QTextDocument::FindBackward
? QTextCursor::PreviousCharacter
: QTextCursor::NextCharacter);
if (found.movePosition(options & QTextDocument::FindBackward
? QTextCursor::PreviousCharacter
: QTextCursor::NextCharacter)) {
from = found;
} else {
return {};
}
} else {
from.setPosition(options & QTextDocument::FindBackward ? found.selectionStart()
: found.selectionEnd());

View File

@@ -32,6 +32,7 @@
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>
#include <utils/algorithm.h>
#include <QApplication>
#include <QDebug>
@@ -165,9 +166,13 @@ namespace Core {
// The Core Singleton
static ICore *m_instance = nullptr;
static MainWindow *m_mainwindow = nullptr;
std::function<NewDialog *(QWidget *)> ICore::m_newDialogFactory = [](QWidget *parent) {
static NewDialog *defaultDialogFactory(QWidget *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.
@@ -253,7 +258,23 @@ void ICore::showNewItemDialog(const QString &title,
const QVariantMap &extraVariables)
{
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);
newDialog->setWizardFactories(factories, defaultLocation, extraVariables);
newDialog->setWindowTitle(title);

View File

@@ -180,8 +180,6 @@ public:
private:
static void updateNewItemDialogState();
static std::function<NewDialog *(QWidget *)> m_newDialogFactory;
};
} // namespace Core

View File

@@ -291,9 +291,10 @@ Wizard *IWizardFactory::runWizard(const FilePath &path, QWidget *parent, Id plat
s_reopenData.reopen();
});
s_inspectWizardAction->setEnabled(true);
if (showWizard)
if (showWizard) {
wizard->show();
Core::ICore::registerWindow(wizard, Core::Context("Core.NewWizard"));
Core::ICore::registerWindow(wizard, Core::Context("Core.NewWizard"));
}
} else {
s_isWizardRunning = false;
ICore::updateNewItemDialogState();

View File

@@ -92,6 +92,7 @@
#include <QStyleFactory>
#include <QToolButton>
#include <QUrl>
#include <QWindow>
using namespace ExtensionSystem;
using namespace Utils;
@@ -101,6 +102,14 @@ namespace Internal {
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()
: AppMainWindow()
, m_coreImpl(new ICore(this))
@@ -518,7 +527,8 @@ void MainWindow::registerDefaultActions()
// New File Action
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->setDefaultKeySequence(QKeySequence::New);
mfile->addAction(cmd, Constants::G_FILE_NEW);
@@ -939,6 +949,20 @@ void MainWindow::setFocusToEditor()
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()
{
// 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
// so to prevent the deleting of that object we
// 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()

View File

@@ -36,6 +36,9 @@
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
#include <QDateTime>
#include <QHash>
#include <QPair>
#include <QSettings>
using namespace Utils;
@@ -356,11 +359,12 @@ static QVersionNumber getClangdVersion(const FilePath &clangdFilePath)
QVersionNumber ClangdSettings::clangdVersion(const FilePath &clangdFilePath)
{
static QHash<Utils::FilePath, QPair<QDateTime, QVersionNumber>> versionCache;
const QDateTime timeStamp = clangdFilePath.lastModified();
const auto it = m_versionCache.find(clangdFilePath);
if (it == m_versionCache.end()) {
const auto it = versionCache.find(clangdFilePath);
if (it == versionCache.end()) {
const QVersionNumber version = getClangdVersion(clangdFilePath);
m_versionCache.insert(clangdFilePath, qMakePair(timeStamp, version));
versionCache.insert(clangdFilePath, qMakePair(timeStamp, version));
return version;
}
if (it->first != timeStamp) {

View File

@@ -29,10 +29,7 @@
#include <utils/fileutils.h>
#include <QDateTime>
#include <QHash>
#include <QObject>
#include <QPair>
#include <QStringList>
#include <QVersionNumber>
@@ -150,7 +147,6 @@ private:
void saveSettings();
Data m_data;
static inline QHash<Utils::FilePath, QPair<QDateTime, QVersionNumber>> m_versionCache;
};
inline bool operator==(const ClangdSettings::Data &s1, const ClangdSettings::Data &s2)

View File

@@ -213,6 +213,7 @@ QuickFixOperationTest::QuickFixOperationTest(const QList<TestDocumentPtr> &testD
QuickFixOperations operations;
factory->match(quickFixInterface, operations);
if (operations.isEmpty()) {
QEXPECT_FAIL("CompleteSwitchCaseStatement_QTCREATORBUG-25998", "FIXME", Abort);
QVERIFY(testDocuments.first()->m_expectedSource.isEmpty());
return;
}

View File

@@ -148,6 +148,7 @@ void SemanticHighlighter::run()
connectWatcher();
m_revision = documentRevision();
qCDebug(log) << "starting runner for document revision" << m_revision;
m_watcher->setFuture(m_highlightingRunner());
}
@@ -160,12 +161,17 @@ static Parentheses getClearedParentheses(const QTextBlock &block)
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;
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;
t.start();

View File

@@ -2832,8 +2832,10 @@ void CdbEngine::setupScripting(const DebuggerResponse &response)
runCommand({command, ScriptCommand});
}
const QString qtVersion = QString::number(runParameters().fallbackQtVersion, 16);
runCommand({"theDumper.setFallbackQtVersion(0x" + qtVersion + ")", ScriptCommand});
DebuggerCommand cmd0("theDumper.setFallbackQtVersion", ScriptCommand);
cmd0.arg("version", runParameters().fallbackQtVersion);
runCommand(cmd0);
runCommand({"theDumper.loadDumpers(None)", ScriptCommand,
[this](const DebuggerResponse &response) {
watchHandler()->addDumpers(response.data["result"]["dumpers"]);

View File

@@ -931,22 +931,27 @@ void DebuggerEngine::showStatusMessage(const QString &msg, int timeout) const
void DebuggerEngine::updateLocalsWindow(bool showReturn)
{
QTC_ASSERT(d->m_returnWindow, return);
QTC_ASSERT(d->m_localsView, return);
d->m_returnWindow->setVisible(showReturn);
d->m_localsView->resizeColumns();
}
bool DebuggerEngine::isRegistersWindowVisible() const
{
QTC_ASSERT(d->m_registerWindow, return false);
return d->m_registerWindow->isVisible();
}
bool DebuggerEngine::isPeripheralRegistersWindowVisible() const
{
QTC_ASSERT(d->m_peripheralRegisterWindow, return false);
return d->m_peripheralRegisterWindow->isVisible();
}
bool DebuggerEngine::isModulesWindowVisible() const
{
QTC_ASSERT(d->m_modulesWindow, return false);
return d->m_modulesWindow->isVisible();
}

View File

@@ -165,9 +165,12 @@ void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *erro
return;
}
Environment env = sysEnv.size() == 0 ? Environment::systemEnvironment() : sysEnv;
// Prevent calling lldb on Windows because the lldb from the llvm package is linked against
// 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;
m_version = winGetDLLVersion(WinDLLFileVersion,
m_command.absoluteFilePath().path(),
@@ -178,7 +181,7 @@ void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *erro
}
QtcProcess proc;
proc.setEnvironment(sysEnv);
proc.setEnvironment(env);
proc.setCommand({m_command, {version}});
proc.runBlocking();
const QString output = proc.allOutput().trimmed();
@@ -262,6 +265,22 @@ void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *erro
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
{
switch (m_engineType) {

View File

@@ -107,6 +107,8 @@ public:
QString detectionSource() const { return m_detectionSource; }
void setDetectionSource(const QString &source) { m_detectionSource = source; }
static bool addAndroidLldbPythonEnv(const Utils::FilePath &lldbCmd, Utils::Environment &env);
private:
DebuggerItem(const QVariant &id);
void initMacroExpander();

View File

@@ -4011,7 +4011,10 @@ void GdbEngine::setupEngine()
if (!commands.isEmpty())
runCommand({commands});
runCommand({"setFallbackQtVersion(0x" + QString::number(rp.fallbackQtVersion, 16) + ")"});
DebuggerCommand cmd1("setFallbackQtVersion");
cmd1.arg("version", rp.fallbackQtVersion);
runCommand(cmd1);
runCommand({"loadDumpers", CB(handlePythonSetup)});
// Reload peripheral register description.

View File

@@ -213,12 +213,7 @@ void LldbEngine::setupEngine()
showMessage("STARTING LLDB: " + lldbCmd.toUserOutput());
Environment environment = runParameters().debugger.environment;
environment.appendOrSet("PYTHONUNBUFFERED", "1"); // avoid flushing problem on macOS
if (lldbCmd.path().contains("/ndk-bundle/")) {
FilePath androidPythonDir = lldbCmd.parentDir().parentDir().pathAppended("python3");
if (HostOsInfo::isAnyUnixHost())
androidPythonDir = androidPythonDir.pathAppended("bin");
environment.prependOrSetPath(androidPythonDir);
}
DebuggerItem::addAndroidLldbPythonEnv(lldbCmd, environment);
m_lldbProc.setEnvironment(environment);
if (runParameters().debugger.workingDirectory.isDir())
@@ -269,10 +264,6 @@ void LldbEngine::setupEngine()
runCommand(cmd);
}
DebuggerCommand cmd0("setFallbackQtVersion");
cmd0.arg("version", "0x" + QString::number(rp.fallbackQtVersion, 16));
runCommand(cmd0);
DebuggerCommand cmd1("loadDumpers");
cmd1.callback = [this](const DebuggerResponse &response) {
watchHandler()->addDumpers(response.data["dumpers"]);
@@ -348,6 +339,10 @@ void LldbEngine::setupEngine()
cmd2.flags = Silent;
runCommand(cmd2);
DebuggerCommand cmd0("setFallbackQtVersion");
cmd0.arg("version", rp.fallbackQtVersion);
runCommand(cmd0);
}
void LldbEngine::runEngine()

View File

@@ -48,7 +48,11 @@ bool isIntType(const QString &type)
case 'b':
return type == "bool";
case 'c':
return type == "char";
return type.startsWith("char") &&
( type == "char"
|| type == "char8_t"
|| type == "char16_t"
|| type == "char32_t" );
case 'i':
return type.startsWith("int") &&
( type == "int"
@@ -63,7 +67,8 @@ bool isIntType(const QString &type)
case 'p':
return type == "ptrdiff_t";
case 'q':
return type == "qint16" || type == "quint16"
return type == "qint8" || type == "quint8"
|| type == "qint16" || type == "quint16"
|| type == "qint32" || type == "quint32"
|| type == "qint64" || type == "quint64"
|| type == "qlonglong" || type == "qulonglong";

View File

@@ -717,22 +717,34 @@ static QString formattedValue(const WatchItem *item)
// Append quoted, printable character also for decimal.
// 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;
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)
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;
const int code = item->value.toInt(&ok);
bool isUnsigned = type == "char32_t";
if (ok)
return reformatCharacter(code, 4, false);
} else if (item->type.endsWith("QChar")) {
return reformatCharacter(code, 4, !isUnsigned);
} else if (type == "char16_t" || type.endsWith("QChar")) {
bool ok;
const int code = item->value.toInt(&ok);
bool isUnsigned = type == "char16_t";
if (ok)
return reformatCharacter(code, 2, false);
return reformatCharacter(code, 2, !isUnsigned);
}
if (format == HexadecimalIntegerFormat

View File

@@ -937,7 +937,6 @@ void Client::handleCodeActionResponse(const CodeActionRequest::Response &respons
void Client::executeCommand(const Command &command)
{
const QString method(ExecuteCommandRequest::methodName);
bool serverSupportsExecuteCommand = m_serverCapabilities.executeCommandProvider().has_value();
serverSupportsExecuteCommand = m_dynamicCapabilities
.isRegistered(ExecuteCommandRequest::methodName)
@@ -953,7 +952,18 @@ ProjectExplorer::Project *Client::project() const
void Client::setCurrentProject(ProjectExplorer::Project *project)
{
if (m_project == project)
return;
if (m_project)
m_project->disconnect(this);
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)

View File

@@ -53,6 +53,8 @@ using namespace LanguageServerProtocol;
namespace LanguageClient {
static Q_LOGGING_CATEGORY(Log, "qtc.languageclient.manager", QtWarningMsg)
static LanguageClientManager *managerInstance = nullptr;
LanguageClientManager::LanguageClientManager(QObject *parent)
@@ -111,6 +113,7 @@ void LanguageClient::LanguageClientManager::addClient(Client *client)
if (managerInstance->m_clients.contains(client))
return;
qCDebug(Log) << "add client: " << client->name() << client;
managerInstance->m_clients << client;
connect(client, &Client::finished, managerInstance, [client]() { clientFinished(client); });
connect(client,
@@ -130,6 +133,7 @@ void LanguageClient::LanguageClientManager::addClient(Client *client)
void LanguageClientManager::clientStarted(Client *client)
{
qCDebug(Log) << "client started: " << client->name() << client;
QTC_ASSERT(managerInstance, return);
QTC_ASSERT(client, return);
if (managerInstance->m_shuttingDown)
@@ -150,6 +154,7 @@ void LanguageClientManager::clientFinished(Client *client)
const QList<TextEditor::TextDocument *> &clientDocs
= managerInstance->m_clientForDocument.keys(client);
if (client->reset()) {
qCDebug(Log) << "restart unexpectedly finished client: " << client->name() << client;
client->disconnect(managerInstance);
client->log(
tr("Unexpectedly finished. Restarting in %1 seconds.").arg(restartTimeoutS));
@@ -158,6 +163,7 @@ void LanguageClientManager::clientFinished(Client *client)
client->deactivateDocument(document);
return;
}
qCDebug(Log) << "client finished unexpectedly: " << client->name() << client;
client->log(tr("Unexpectedly finished."));
for (TextEditor::TextDocument *document : clientDocs)
managerInstance->m_clientForDocument.remove(document);
@@ -174,6 +180,7 @@ Client *LanguageClientManager::startClient(BaseSettings *setting, ProjectExplore
QTC_ASSERT(setting, return nullptr);
QTC_ASSERT(setting->isValid(), return nullptr);
Client *client = setting->createClient(project);
qCDebug(Log) << "start client: " << client->name() << client;
QTC_ASSERT(client, return nullptr);
client->start();
managerInstance->m_clientsForSetting[setting->m_id].append(client);
@@ -206,6 +213,7 @@ void LanguageClientManager::shutdownClient(Client *client)
{
if (!client)
return;
qCDebug(Log) << "request client shutdown: " << client->name() << client;
// 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
for (TextEditor::TextDocument *document : managerInstance->m_clientForDocument.keys(client))
@@ -220,6 +228,7 @@ void LanguageClientManager::deleteClient(Client *client)
{
QTC_ASSERT(managerInstance, return);
QTC_ASSERT(client, return);
qCDebug(Log) << "delete client: " << client->name() << client;
client->disconnect();
managerInstance->m_clients.removeAll(client);
for (QVector<Client *> &clients : managerInstance->m_clientsForSetting)
@@ -237,6 +246,7 @@ void LanguageClientManager::shutdown()
QTC_ASSERT(managerInstance, return);
if (managerInstance->m_shuttingDown)
return;
qCDebug(Log) << "shutdown manager";
managerInstance->m_shuttingDown = true;
for (Client *client : qAsConst(managerInstance->m_clients))
shutdownClient(client);
@@ -412,6 +422,7 @@ void LanguageClientManager::openDocumentWithClient(TextEditor::TextDocument *doc
currentClient->deactivateDocument(document);
managerInstance->m_clientForDocument[document] = client;
if (client) {
qCDebug(Log) << "open" << document->filePath() << "with" << client->name() << client;
if (!client->documentOpen(document))
client->openDocument(document);
else

View File

@@ -25,12 +25,13 @@
#pragma once
#include "../projectexplorer_export.h"
#include <utils/projectintropage.h>
namespace ProjectExplorer {
// Documentation inside.
class JsonProjectPage : public Utils::ProjectIntroPage
class PROJECTEXPLORER_EXPORT JsonProjectPage : public Utils::ProjectIntroPage
{
Q_OBJECT

View File

@@ -603,7 +603,7 @@ double round(double value, int decimal_places) {
}
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
@@ -840,6 +840,8 @@ QVariant convertValue(const QByteArray &key, const QString &value)
return value.toInt();
} else if (key == "opacity") {
return value.toFloat();
} else if ((key == "fillColor" || key == "strokeColor") && value == "none") {
return "transparent";
}
return value;
@@ -1015,6 +1017,28 @@ PropertyMap generateRectProperties(const QDomElement &e, const CSSRules &cssRule
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)
{
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)
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());
QPainterPath path;
@@ -1178,6 +1202,11 @@ QmlObjectNode SVGPasteAction::createQmlObjectNode(QmlDesigner::ModelNode &target
round(tmp[2].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());
@@ -1202,8 +1231,6 @@ QmlObjectNode SVGPasteAction::createQmlObjectNode(QmlDesigner::ModelNode &target
depthFirstTraversal(node, processStyleAndCollectShapes);
viewBoxProperties.insert("clip", true);
ModelNode groupNode = createGroupNode(targetNode, viewBoxProperties);
for (const QDomElement &e : shapeElements) {
@@ -1213,7 +1240,9 @@ QmlObjectNode SVGPasteAction::createQmlObjectNode(QmlDesigner::ModelNode &target
pathProperties = generatePathProperties(e, cssRules);
else if (e.tagName() == "rect")
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);
else if (e.tagName() == "circle" || e.tagName() == "ellipse")
pathProperties = generateEllipseProperties(e, cssRules);

View File

@@ -103,8 +103,10 @@ public:
distributeSpacingHorizontal,
distributeSpacingVertical,
distributeTop,
download,
edit,
eyeDropper,
favorite,
flowAction,
flowTransition,
fontStyleBold,
@@ -155,6 +157,12 @@ public:
textFullJustification,
textNumberedList,
tickIcon,
translationCreateFiles,
translationCreateReport,
translationExport,
translationImport,
translationSelectLanguages,
translationTest,
transparent,
triState,
triangleArcA,

View File

@@ -63,7 +63,7 @@ static bool itemIsResizable(const QmlItemNode &qmlItemNode)
&& qmlItemNode.instanceIsResizable()
&& qmlItemNode.modelIsMovable()
&& qmlItemNode.modelIsResizable()
&& !qmlItemNode.instanceHasRotationTransform()
&& !qmlItemNode.instanceHasScaleOrRotationTransform()
&& !qmlItemNode.instanceIsInLayoutable();
}

View File

@@ -311,6 +311,7 @@ void DesignDocument::changeToDocumentModel()
viewManager().detachViewsExceptRewriterAndComponetView();
m_inFileComponentModel.reset();
m_inFileComponentTextModifier.reset();
viewManager().attachRewriterView();
viewManager().attachViewsExceptRewriterAndComponetView();

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 B

View File

@@ -31,5 +31,7 @@
<file>images/asset_sound_384.png</file>
<file>images/x.png</file>
<file>images/x@2x.png</file>
<file>images/browse.png</file>
<file>images/browse@2x.png</file>
</qresource>
</RCC>

View File

@@ -42,16 +42,18 @@ QPixmap ItemLibraryAssetsIconProvider::requestPixmap(const QString &id, QSize *s
{
QPixmap pixmap;
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);
else if (ItemLibraryAssetsModel::supportedImageSuffixes().contains(suffix))
pixmap = Utils::StyleHelper::dpiSpecificImageFile(id);
else if (ItemLibraryAssetsModel::supportedTexture3DSuffixes().contains(suffix))
pixmap = HdrImage{id}.toPixmap();
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))
pixmap = QPixmap(Utils::StyleHelper::dpiSpecificImageFile(":/ItemLibrary/images/asset_sound_48.png"));
pixmap = Utils::StyleHelper::dpiSpecificImageFile(":/ItemLibrary/images/asset_sound_48.png");
if (size) {
size->setWidth(pixmap.width());

View File

@@ -275,7 +275,8 @@ void ItemLibraryAssetsModel::setRootPath(const QString &path)
beginResetModel();
m_assetsDir = new ItemLibraryAssetsDir(path, 0, true, this);
parseDirRecursive(m_assetsDir, 1);
bool noAssets = parseDirRecursive(m_assetsDir, 1);
setIsEmpty(noAssets);
endResetModel();
}
@@ -304,6 +305,19 @@ const QSet<QString> &ItemLibraryAssetsModel::supportedSuffixes() const
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
{
static QSet<QString> previewableSuffixes;

View File

@@ -46,13 +46,15 @@ class ItemLibraryAssetsModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(bool isEmpty READ isEmpty WRITE setIsEmpty NOTIFY isEmptyChanged)
public:
ItemLibraryAssetsModel(QmlDesigner::SynchronousImageCache &fontImageCache,
Utils::FileSystemWatcher *fileSystemWatcher,
QObject *parent = nullptr);
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex & parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QHash<int, QByteArray> roleNames() const override;
void refresh();
@@ -82,15 +84,22 @@ public:
Q_INVOKABLE DirExpandState getAllExpandedState() const;
Q_INVOKABLE void removeFile(const QString &filePath);
signals:
void isEmptyChanged();
private:
const QSet<QString> &supportedSuffixes() const;
bool isEmpty() const;
void setIsEmpty(bool empty);
SynchronousImageCache &m_fontImageCache;
QHash<QString, QPair<QDateTime, QIcon>> m_iconCache;
QString m_searchText;
Utils::FileSystemWatcher *m_fileSystemWatcher = nullptr;
ItemLibraryAssetsDir *m_assetsDir = nullptr;
bool m_isEmpty = true;
QHash<int, QByteArray> m_roleNames;
inline static QHash<QString, bool> m_expandedStateHash; // <assetPath, isExpanded>

View File

@@ -118,6 +118,8 @@ void ItemLibraryView::modelAttached(Model *model)
m_widget->clearSearchFilter();
m_widget->setModel(model);
updateImports();
if (model)
m_widget->updatePossibleImports(model->possibleImports());
m_hasErrors = !rewriterView()->errors().isEmpty();
m_widget->setFlowMode(QmlItemNode(rootModelNode()).isFlowView());
setResourcePath(DocumentManager::currentResourcePath().toFileInfo().absoluteFilePath());

View File

@@ -29,12 +29,12 @@
namespace QmlDesigner {
// This dialog displays all given type properties of an object and allows the user to choose one
ChooseFromPropertyListDialog::ChooseFromPropertyListDialog(const ModelNode &node, TypeName type, QWidget *parent)
// This dialog displays specified properties and allows the user to choose one
ChooseFromPropertyListDialog::ChooseFromPropertyListDialog(const QStringList &propNames,
QWidget *parent)
: QDialog(parent)
, m_ui(new Ui::ChooseFromPropertyListDialog)
{
m_propertyTypeName = type;
m_ui->setupUi(this);
setWindowTitle(tr("Select property"));
m_ui->label->setText(tr("Bind to property:"));
@@ -50,7 +50,7 @@ ChooseFromPropertyListDialog::ChooseFromPropertyListDialog(const ModelNode &node
QDialog::accept();
});
fillList(node);
fillList(propNames);
}
ChooseFromPropertyListDialog::~ChooseFromPropertyListDialog()
@@ -63,31 +63,80 @@ TypeName ChooseFromPropertyListDialog::selectedProperty() const
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
const auto metaInfo = node.metaInfo();
const auto propNames = metaInfo.propertyNames();
const TypeName property(m_propertyTypeName);
QStringList nameList;
TypeName typeName = newNode.type();
// Component matches cases where you don't want to insert a plain component,
// such as layer.effect. Also, default property is often a Component (typically 'delegate'),
// 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) {
if (metaInfo.propertyTypeName(propName) == property)
nameList.append(QString::fromLatin1(propName));
}
if (!nameList.isEmpty()) {
QString defaultProp = nameList.first();
nameList.sort();
for (const auto &propName : qAsConst(nameList)) {
QListWidgetItem *newItem = new QListWidgetItem(propName);
m_ui->listProps->addItem(newItem);
const TypeName testType = metaInfo.propertyTypeName(propName);
if (!ignoredTypes.contains(testType)
&& metaInfo.propertyIsWritable(propName)
&& (testType == typeName || newNode.isSubclassOf(testType))) {
matchingNames.append(QString::fromLatin1(propName));
}
// 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();
}
}

View File

@@ -40,16 +40,22 @@ class ChooseFromPropertyListDialog : public QDialog
Q_OBJECT
public:
explicit ChooseFromPropertyListDialog(const ModelNode &node, TypeName type, QWidget *parent = 0);
~ChooseFromPropertyListDialog();
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:
void fillList(const ModelNode &node);
explicit ChooseFromPropertyListDialog(const QStringList &propNames, QWidget *parent = 0);
void fillList(const QStringList &propNames);
Ui::ChooseFromPropertyListDialog *m_ui;
TypeName m_selectedProperty;
TypeName m_propertyTypeName;
};
}

View File

@@ -739,25 +739,13 @@ void NavigatorTreeModel::handleItemLibraryItemDrop(const QMimeData *mimeData, in
}
} else {
ModelNode targetNode = targetProperty.parentModelNode();
NodeMetaInfo metaInfo = targetNode.metaInfo();
TypeName typeName = newModelNode.type();
// Empty components are not supported and having one as property value is generally
// unstable, so let's not offer user to put a fresh Component into a property
if (typeName != "QtQml.Component") {
const PropertyNameList nameList = targetNode.metaInfo().directPropertyNames();
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;
}
}
ChooseFromPropertyListDialog *dialog = ChooseFromPropertyListDialog::createIfNeeded(
targetNode, newModelNode, Core::ICore::dialogParent());
if (dialog) {
dialog->exec();
if (dialog->result() == QDialog::Accepted)
targetNode.bindingProperty(dialog->selectedProperty()).setExpression(newModelNode.validId());
delete dialog;
}
}
@@ -1015,10 +1003,13 @@ bool NavigatorTreeModel::dropAsImage3dTexture(const ModelNode &targetNode,
if (targetNode.isSubclassOf("QtQuick3D.Material")) {
// if dropping an image on a default material, create a texture instead of image
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
dialog = new ChooseFromPropertyListDialog(targetNode, "QtQuick3D.Texture", Core::ICore::dialogParent());
dialog->exec();
dialog = ChooseFromPropertyListDialog::createIfNeeded(targetNode, "QtQuick3D.Texture",
Core::ICore::dialogParent());
if (dialog)
dialog->exec();
}
if (!dialog || dialog->result() == QDialog::Accepted) {
m_view->executeInTransaction("NavigatorTreeModel::dropAsImage3dTexture", [&] {

View File

@@ -99,7 +99,7 @@ public:
bool instanceIsMovable() const;
bool instanceIsResizable() const;
bool instanceIsInLayoutable() const;
bool instanceHasRotationTransform() const;
bool instanceHasScaleOrRotationTransform() const;
bool modelIsMovable() const;
bool modelIsResizable() const;

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