Merge remote-tracking branch 'origin/6.0' into qds-2.3
Change-Id: I66a1479cb9cf801700d82fdde339b7aab83f1f96
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 4.2 KiB |
BIN
doc/qtcreator/images/qml-profiler-start-dialog.png
Normal file
After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 13 KiB |
BIN
doc/qtcreator/images/qtcreator-kit-selector-run-targets.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 11 KiB |
@@ -433,7 +433,8 @@
|
||||
|
||||
By default, the splash screen is hidden automatically
|
||||
when an activity is drawn. To keep it visible until
|
||||
\l{QNativeInterface::QAndroidApplication::hideSplashScreen()} is
|
||||
\l{https://doc.qt.io/qt-6/qnativeinterface-qandroidapplication.html#hideSplashScreen}
|
||||
{QNativeInterface::QAndroidApplication::hideSplashScreen()} is
|
||||
called, select the \uicontrol {Sticky splash screen} check box.
|
||||
|
||||
In \uicontrol {Image show mode}, select whether to center the splash screen
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 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.
|
||||
@@ -118,6 +118,8 @@
|
||||
for particular plugins, select \uicontrol Tools > \uicontrol Options >
|
||||
\uicontrol FakeVim > \uicontrol General > \uicontrol {Plugin Emulation}.
|
||||
|
||||
\image qtcreator-fakevim-options-general-plugin-emulation.png "FakeVim Plugin Emulation options"
|
||||
|
||||
Currently emulated plugins:
|
||||
\list
|
||||
\li \l{https://github.com/tpope/vim-commentary}{vim-commentary}: \c gc
|
||||
@@ -129,9 +131,10 @@
|
||||
register \c x.
|
||||
\li ["x]grr to replace the current line.
|
||||
\endlist
|
||||
\li \l{https://github.com/tommcdo/vim-exchange}{vim-exchange}
|
||||
\li \l{https://github.com/vim-scripts/argtextobj.vim}{argtextobj.vim}:
|
||||
Defines the \c ia and \c aa text objects for function parameters.
|
||||
\li \l{https://github.com/tommcdo/vim-exchange}{vim-exchange}:
|
||||
A text exchange operator for vim.
|
||||
\li \l{https://github.com/tpope/vim-surround}{vim-surround}:
|
||||
Adds mappings for deleting, adding and changing surroundings.
|
||||
\endlist
|
||||
@@ -287,15 +290,29 @@
|
||||
|
||||
\section1 Mapping FakeVim Commands
|
||||
|
||||
To map commands entered on the \uicontrol FakeVim command line to actions
|
||||
of the \QC core, select \uicontrol Tools > \uicontrol Options >
|
||||
To map commands entered on the \uicontrol FakeVim command line to
|
||||
\QC functions, select \uicontrol Tools > \uicontrol Options >
|
||||
\uicontrol FakeVim > \uicontrol {Ex Command Mapping}.
|
||||
Enter a string in the \uicontrol Filter field to search for a specific
|
||||
\QC function.
|
||||
|
||||
\image qtcreator-fakevim-options-ex-command-mapping.png "FakeVim Ex Command Mapping options"
|
||||
|
||||
Select a function in the list, and enter a string that will trigger the
|
||||
function in the \uicontrol {Regular expression} field. You can view the
|
||||
trigger expression in the \uicontrol {Ex Trigger Expression} field. To
|
||||
remove the trigger expression, select \uicontrol Reset.
|
||||
|
||||
To reset the trigger expressions for all functions, select
|
||||
\uicontrol {Reset All}.
|
||||
|
||||
To map \e {user commands} to keyboard shortcuts, select \uicontrol Tools >
|
||||
\uicontrol Options > \uicontrol FakeVim >
|
||||
\uicontrol {User Command Mapping}. The user command mapped to the shortcut
|
||||
is executed by FakeVim as if you were typing it (as when replaying a macro).
|
||||
|
||||
\image qtcreator-fakevim-options-user-command-mapping.png "FakeVim User Command Mapping options"
|
||||
|
||||
\section1 Specifying FakeVim Options
|
||||
|
||||
To make changes to the Vim-style settings, select \uicontrol Tools >
|
||||
@@ -319,5 +336,6 @@
|
||||
\uicontrol FakeVim > \uicontrol {Use FakeVim} or press \key {Alt+V,Alt+V}.
|
||||
|
||||
You can temporarily escape FakeVim mode to access the normal \QC keyboard
|
||||
shortcuts like \key {Ctrl-R} for \uicontrol Run by pressing \key {,} first.
|
||||
shortcuts like \key {Ctrl-R} for \uicontrol Run by first pressing the comma
|
||||
key (\key {,}).
|
||||
*/
|
||||
|
@@ -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,6 +75,11 @@
|
||||
|
||||
\li In \uicontrol {MIME Type}, select a MIME type.
|
||||
|
||||
\li In \uicontrol Handler, double-click the editor name to display a
|
||||
context-menu where you can select another editor to open the file
|
||||
in by default. The menu is available only if alternative suitable
|
||||
editors are available.
|
||||
|
||||
\li In \uicontrol Patterns, add the filename extension for the type of files
|
||||
that you want to identify as having this MIME type.
|
||||
|
||||
@@ -96,12 +101,7 @@
|
||||
\note You are recommended not to change the range and priority,
|
||||
because it might cause problems when opening files in \QC.
|
||||
|
||||
\li In \uicontrol Handler, double-click the editor name to display a
|
||||
context-menu where you can select another editor to open the file
|
||||
in by default. The menu is available only if alternative suitable
|
||||
editors are available.
|
||||
|
||||
\li Click \uicontrol OK.
|
||||
\li Click \uicontrol OK to return to the \uicontrol {MIME Types} tab.
|
||||
|
||||
\endlist
|
||||
|
||||
@@ -119,8 +119,8 @@
|
||||
select \uicontrol {Reset MIME Types}. To revert the changes you have
|
||||
made to the default editors, select \uicontrol {Reset Handlers}.
|
||||
|
||||
\note If you now select \uicontrol OK or \uicontrol Apply, you permanently lose all
|
||||
your own patterns and magic headers. The changes are reverted the next
|
||||
time you start \QC.
|
||||
\note If you select \uicontrol OK or \uicontrol Apply after reverting
|
||||
changes, you permanently lose all your own patterns and magic headers.
|
||||
They are removed the next time you start \QC.
|
||||
|
||||
*/
|
||||
|
@@ -109,3 +109,7 @@
|
||||
\externalpage https://doc.qt.io/qt/qtqml-syntax-imports.html#qml-import-path
|
||||
\title QML Import Path
|
||||
*/
|
||||
/*!
|
||||
\externalpage https://doc.qt.io/QtApplicationManager/
|
||||
\title Qt Application Manager
|
||||
*/
|
||||
|
@@ -123,6 +123,10 @@
|
||||
The QNX Neutrino RTOS should provide a few additional command line tools
|
||||
and services, as described in \l {Qt Creator Target Requirements}.
|
||||
|
||||
\note In Qt 6, Qt for QNX is a part of
|
||||
\l{https://doc.qt.io/QtForDeviceCreation/index.html}{Qt for Device Creation},
|
||||
and the \QC support is considered experimental.
|
||||
|
||||
The following topics contain more information about developing applications
|
||||
for QNX devices:
|
||||
|
||||
|
@@ -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.
|
||||
@@ -87,7 +87,7 @@
|
||||
\li To deploy applications and run them remotely on devices, specify
|
||||
parameters for accessing the devices:
|
||||
|
||||
\list 1
|
||||
\list a
|
||||
|
||||
\li Select \uicontrol Tools > \uicontrol Options >
|
||||
\uicontrol Devices > \uicontrol Devices > \uicontrol Add >
|
||||
@@ -108,14 +108,23 @@
|
||||
application as.
|
||||
This value will be available in the variable \c %{Device:UserName}.
|
||||
|
||||
\li In the \uicontrol {The authentication type} field, select
|
||||
\uicontrol Default to use the currently displayed private
|
||||
key file for authentication. Select \uicontrol {Specific Key}
|
||||
to use some other key, and enter the path to the file that
|
||||
contains the private key in the field below. This value will
|
||||
be available in the variable \c %{Device:PrivateKeyFile}.
|
||||
\li Select \uicontrol {Next} to open the
|
||||
\uicontrol {Key Deployment} dialog.
|
||||
|
||||
\li Click \uicontrol {Next} to create the connection.
|
||||
\image qtcreator-generic-linux-device-key-deployment.png "Key Deployment dialog"
|
||||
|
||||
\li In \uicontrol {Private key file}, select a private key file
|
||||
to use for authentication. This value will be available in
|
||||
the variable \c %{Device:PrivateKeyFile}.
|
||||
|
||||
\li If you do not have a public-private key pair, select
|
||||
\uicontrol {Create New Key Pair}. For more information,
|
||||
see \l{Generating SSH Keys}.
|
||||
|
||||
\li Select \uicontrol {Deploy Public Key} to copy the public
|
||||
key to the device.
|
||||
|
||||
\li Select \uicontrol {Next} to create the connection.
|
||||
|
||||
\endlist
|
||||
|
||||
|
@@ -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.
|
||||
@@ -65,6 +65,18 @@
|
||||
|
||||
\endlist
|
||||
|
||||
If your project has several run targets defined, such as
|
||||
\l{Running Autotests}{tests}, you can select them in the kit selector.
|
||||
|
||||
\image qtcreator-kit-selector-run-targets.png "Run targets in the kit selector"
|
||||
|
||||
If you have connected \l{Mobile Platforms}{mobile devices} or
|
||||
\l{Embedded Platforms}{embedded devices} to the development PC
|
||||
or added virtual devices, such as \l{Managing Android Virtual Devices (AVD)}
|
||||
{Android Virtual Devices (AVD)}, you can select them in the kit selector.
|
||||
Select \uicontrol Manage to manage device settings. For example, you can add
|
||||
AVDs or manually start disconnected AVDs.
|
||||
|
||||
The \uicontrol {Application Output} pane displays the status of the
|
||||
application while it is running. You can select the \uicontrol Run button
|
||||
in the pane to re-run applications without building them first. This is
|
||||
|
@@ -1,13 +1,13 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (C) 2018 Blackberry
|
||||
**
|
||||
** Contact: Blackberry (qt@blackberry.com)
|
||||
** Contact: KDAB (info@kdab.com)
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
** Copyright (C) 2021 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the Qt Creator documentation.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
@@ -40,6 +40,10 @@
|
||||
a few additional command line tools and services, as described in
|
||||
\l {Qt Creator Target Requirements}.
|
||||
|
||||
\note In Qt 6, Qt for QNX is a part of
|
||||
\l{https://doc.qt.io/QtForDeviceCreation/index.html}{Qt for Device Creation},
|
||||
and the \QC support is considered experimental.
|
||||
|
||||
\section1 Adding a QNX Neutrino Device in \QC
|
||||
|
||||
Adding a QNX Neutrino device is very similar to
|
||||
|
@@ -92,7 +92,7 @@
|
||||
|
||||
\note At the time of this writing, \macos is not supported as a development
|
||||
host for Qt for Device Creation. This means that you cannot preview UIs on
|
||||
devices if you are using \QDS on \macos. For more information about
|
||||
devices if you are using \QC on \macos. For more information about
|
||||
supported development hosts, see
|
||||
\l {https://doc.qt.io/QtForDeviceCreation/qtdc-supported-platforms.html#supported-development-hosts}
|
||||
{Supported Development Hosts}.
|
||||
|
@@ -96,7 +96,7 @@
|
||||
\endif
|
||||
|
||||
\note To profile applications on \l{glossary-device}{devices}, you
|
||||
must install Qt 4.7.4 or later libraries on them.
|
||||
must install Qt libraries on them.
|
||||
|
||||
\li Select \uicontrol Analyze > \uicontrol {QML Profiler} to profile the
|
||||
current application.
|
||||
@@ -131,8 +131,8 @@
|
||||
application is launched. Data collection starts when you select the button
|
||||
again.
|
||||
|
||||
To save all the collected data, right-click any QML Profiler view to open
|
||||
the context menu, and then select \uicontrol {Save QML Trace}. To view the saved
|
||||
To save all the collected data, select \uicontrol Analyze >
|
||||
\uicontrol {QML Profiler Options} > \uicontrol {Save QML Trace}. To view the saved
|
||||
data, select \uicontrol {Load QML Trace}. You can also deliver the saved data to
|
||||
others for examination or load data saved by them.
|
||||
|
||||
@@ -167,13 +167,21 @@
|
||||
|
||||
\section1 Attaching to Running Qt Quick Applications
|
||||
|
||||
To profile Qt Quick applications that are not launched by \QC, select
|
||||
\uicontrol Analyze > \uicontrol {QML Profiler (External)}. You must enable
|
||||
QML debugging and profiling for the application in the project build
|
||||
settings. For more information, see \l{Setting Up QML Debugging}.
|
||||
You can profile Qt Quick applications that are not launched by \QC.
|
||||
However, you must enable QML debugging and profiling for the application
|
||||
in the project build settings. For more information, see
|
||||
\l{Setting Up QML Debugging}.
|
||||
|
||||
In the \uicontrol {QML Profiler} dialog, \uicontrol Port field, specify the port to
|
||||
listen to.
|
||||
To attach to waiting applications:
|
||||
|
||||
\list 1
|
||||
\li Select \uicontrol Analyze >
|
||||
\uicontrol {QML Profiler (Attach to Waiting Application)}.
|
||||
\image qml-profiler-start-dialog.png "Start QML Profiler dialog"
|
||||
\li In \uicontrol Kit, select the kit used to build the application.
|
||||
\li In \uicontrol Port, specify the port to listen to.
|
||||
\li Select \uicontrol OK.
|
||||
\endlist
|
||||
|
||||
\section1 Analyzing Collected Data
|
||||
|
||||
@@ -578,21 +586,19 @@
|
||||
\section2 Visualizing Statistics as Flame Graphs
|
||||
|
||||
The \uicontrol {Flame Graph} view shows a more concise statistical overview
|
||||
of QML and JavaScript execution. In the \uicontrol {Visualize Total Time}
|
||||
view, the horizontal bars show the amount of
|
||||
of QML and JavaScript execution. In the \uicontrol {Total Time} view, the
|
||||
horizontal bars show the amount of
|
||||
time all invocations of a certain function took together, relative to the
|
||||
total runtime of all JavaScript and QML events. The nesting shows which
|
||||
functions were called by which other ones.
|
||||
|
||||
\image qml-profiler-flamegraph.png "Flame Graph View"
|
||||
|
||||
To view the total amount of memory allocated by the functions in the
|
||||
\uicontrol {Visualize Memory} view, select \uicontrol Memory in the
|
||||
drop-down menu (1).
|
||||
To view the total amount of memory allocated by the functions, select
|
||||
\uicontrol Memory in the drop-down menu.
|
||||
|
||||
To view the the number of memory allocations performed by the functions in
|
||||
the \uicontrol {Visualize Allocations} view, select \uicontrol Allocations
|
||||
in the drop-down menu.
|
||||
To view the the number of memory allocations performed by the functions,
|
||||
select \uicontrol Allocations.
|
||||
|
||||
Double-click an item in a view to zoom into it. Double-click an empty
|
||||
area in the view to zoom out again.
|
||||
|
@@ -43,31 +43,12 @@
|
||||
\QBPS is delivered as an Adobe extension (ZXP)
|
||||
package and requires Adobe Photoshop version 20.0.0, or later
|
||||
to be installed. The \QBPS installation process differs depending
|
||||
on whether you use ZXPInstaller and whether you are installing on
|
||||
on whether you are installing on
|
||||
Windows or \macos.
|
||||
|
||||
\section1 Installing with ZXPInstaller
|
||||
\section1 Installing on Windows
|
||||
|
||||
To use ZXPInstaller to install \QBPS:
|
||||
|
||||
\list 1
|
||||
\li Download and install \l{http://zxpinstaller.com/}{ZXPInstaller}.
|
||||
\li Start ZXPInstaller.
|
||||
\li Drag and drop the \QBPS ZXP package from
|
||||
\c {Qt\Tools\QtDesignStudio\photoshop_bridge} on Windows
|
||||
or \c {Qt/QtDesignStudio/photoshop_bridge} on \macos
|
||||
to ZXPInstaller.
|
||||
\li Follow the instructions of the installation program.
|
||||
\endlist
|
||||
|
||||
\section1 Installing Without ZXPInstaller
|
||||
|
||||
The \QBPS installation process differs depending on the platform you
|
||||
are installing on.
|
||||
|
||||
\section2 Installing on Windows
|
||||
|
||||
To install \QBPS on Windows without using ZXPInstaller:
|
||||
To install \QBPS on Windows:
|
||||
|
||||
\list 1
|
||||
\li Copy the \QBPS ZXP package from
|
||||
@@ -83,9 +64,9 @@
|
||||
\endcode
|
||||
\endlist
|
||||
|
||||
\section2 Installing on \macos
|
||||
\section1 Installing on \macos
|
||||
|
||||
To install \QBPS on \macos without using ZXPInstaller:
|
||||
To install \QBPS on \macos:
|
||||
|
||||
\list 1
|
||||
\li Copy the \QBPS ZXP package from
|
||||
|
@@ -36,9 +36,9 @@
|
||||
and dynamic behavior. You can test, preview, and fine-tune your designs to
|
||||
pixel-perfection live on the desktop or target device.
|
||||
|
||||
View \l{All Topics}{all topics} or select a topic from below.
|
||||
|
||||
\table
|
||||
\row
|
||||
\li {4,1} \b {\l{All Topics}}
|
||||
\row
|
||||
\li \inlineimage front-gs.png
|
||||
\li \inlineimage front-ui.png
|
||||
|
@@ -102,11 +102,6 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
View3D {
|
||||
// Dummy view to hold the context
|
||||
// TODO remove when QTBUG-87678 is fixed
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentItem
|
||||
anchors.fill: parent
|
||||
|
@@ -998,18 +998,17 @@ void Qt5InformationNodeInstanceServer::doRenderModelNodeImageView()
|
||||
void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
|
||||
{
|
||||
#ifdef QUICK3D_MODULE
|
||||
m_modelNode3DImageViewAsyncData.cleanup();
|
||||
if (m_modelNode3DImageViewData.rootItem) {
|
||||
QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "destroyView");
|
||||
if (!m_modelNode3DImageViewData.contentItem)
|
||||
m_modelNode3DImageViewData.contentItem = getContentItemForRendering(m_modelNode3DImageViewData.rootItem);
|
||||
|
||||
// Key number is selected so that it is unlikely to conflict other ImageContainer use.
|
||||
auto imgContainer = ImageContainer(m_modelNodePreviewImageCommand.instanceId(), {}, 2100000001);
|
||||
QImage renderImage;
|
||||
if (m_modelNodePreviewImageCache.contains(m_modelNodePreviewImageCommand.componentPath())) {
|
||||
renderImage = m_modelNodePreviewImageCache[m_modelNodePreviewImageCommand.componentPath()];
|
||||
m_modelNode3DImageViewAsyncData.renderImage
|
||||
= m_modelNodePreviewImageCache[m_modelNodePreviewImageCommand.componentPath()];
|
||||
modelNode3DImageViewSendImageToCreator();
|
||||
} else {
|
||||
QObject *instanceObj = nullptr;
|
||||
bool createdFromComponent = false;
|
||||
ServerNodeInstance instance = instanceForId(m_modelNodePreviewImageCommand.instanceId());
|
||||
if (!m_modelNodePreviewImageCommand.componentPath().isEmpty()
|
||||
&& instance.isSubclassOf("QQuick3DNode")) {
|
||||
@@ -1018,14 +1017,15 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
|
||||
// wouldn't want the children of the Node to appear in the preview.
|
||||
QQmlComponent component(engine());
|
||||
component.loadUrl(QUrl::fromLocalFile(m_modelNodePreviewImageCommand.componentPath()));
|
||||
instanceObj = qobject_cast<QQuick3DObject *>(component.create());
|
||||
if (!instanceObj) {
|
||||
m_modelNode3DImageViewAsyncData.instanceObj = qobject_cast<QQuick3DObject *>(component.create());
|
||||
if (!m_modelNode3DImageViewAsyncData.instanceObj) {
|
||||
qWarning() << "Could not create preview component: " << component.errors();
|
||||
m_modelNode3DImageViewAsyncData.cleanup();
|
||||
return;
|
||||
}
|
||||
createdFromComponent = true;
|
||||
m_modelNode3DImageViewAsyncData.createdFromComponent = true;
|
||||
} else {
|
||||
instanceObj = instance.internalObject();
|
||||
m_modelNode3DImageViewAsyncData.instanceObj = instance.internalObject();
|
||||
}
|
||||
QSize renderSize = m_modelNodePreviewImageCommand.size();
|
||||
if (Internal::QuickItemNodeInstance::unifiedRenderPathOrQt6()) {
|
||||
@@ -1044,53 +1044,73 @@ void Qt5InformationNodeInstanceServer::doRenderModelNode3DImageView()
|
||||
m_modelNode3DImageViewData.window->resize(renderSize);
|
||||
m_modelNode3DImageViewData.rootItem->setSize(renderSize);
|
||||
|
||||
QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "createViewForObject",
|
||||
Q_ARG(QVariant, objectToVariant(instanceObj)));
|
||||
QMetaObject::invokeMethod(
|
||||
m_modelNode3DImageViewData.rootItem, "createViewForObject",
|
||||
Q_ARG(QVariant, objectToVariant(m_modelNode3DImageViewAsyncData.instanceObj)));
|
||||
|
||||
bool ready = false;
|
||||
int count = 0; // Ensure we don't ever get stuck in an infinite loop
|
||||
while (!ready && ++count < 10) {
|
||||
updateNodesRecursive(m_modelNode3DImageViewData.contentItem);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
||||
renderImage = m_modelNode3DImageViewData.window->grabWindow();
|
||||
} else {
|
||||
// Fake render loop signaling to update things like QML items as 3D textures
|
||||
m_modelNode3DImageViewData.window->beforeSynchronizing();
|
||||
m_modelNode3DImageViewData.window->beforeRendering();
|
||||
|
||||
QSizeF size = qobject_cast<QQuickItem *>(m_modelNode3DImageViewData.contentItem)->size();
|
||||
QRectF renderRect(QPointF(0., 0.), size);
|
||||
renderImage = designerSupport()->renderImageForItem(m_modelNode3DImageViewData.contentItem,
|
||||
renderRect, size.toSize());
|
||||
|
||||
m_modelNode3DImageViewData.window->afterRendering();
|
||||
}
|
||||
#else
|
||||
renderImage = grabRenderControl(m_modelNode3DImageViewData);
|
||||
#endif
|
||||
QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "afterRender");
|
||||
ready = QQmlProperty::read(m_modelNode3DImageViewData.rootItem, "ready").value<bool>();
|
||||
}
|
||||
QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "destroyView");
|
||||
if (createdFromComponent) {
|
||||
// If component changes, puppet will need a reset anyway, so we can cache the image
|
||||
m_modelNodePreviewImageCache.insert(m_modelNodePreviewImageCommand.componentPath(), renderImage);
|
||||
delete instanceObj;
|
||||
}
|
||||
}
|
||||
|
||||
if (!renderImage.isNull()) {
|
||||
imgContainer.setImage(renderImage);
|
||||
|
||||
// send the rendered image to creator process
|
||||
nodeInstanceClient()->handlePuppetToCreatorCommand({PuppetToCreatorCommand::RenderModelNodePreviewImage,
|
||||
QVariant::fromValue(imgContainer)});
|
||||
// Selection box geometry updates have an asynchronous step, so we need to do rendering
|
||||
// in asynchronous steps as well, since we are adjusting the selection box geometry
|
||||
// while finding correct zoom level.
|
||||
m_modelNode3DImageViewAsyncData.timer.start();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::modelNode3DImageViewSendImageToCreator()
|
||||
{
|
||||
if (!m_modelNode3DImageViewAsyncData.renderImage.isNull()) {
|
||||
// Key number is selected so that it is unlikely to conflict other ImageContainer use.
|
||||
ImageContainer imgContainer(m_modelNodePreviewImageCommand.instanceId(), {}, 2100000001);
|
||||
imgContainer.setImage(m_modelNode3DImageViewAsyncData.renderImage);
|
||||
|
||||
// send the rendered image to creator process
|
||||
nodeInstanceClient()->handlePuppetToCreatorCommand(
|
||||
{PuppetToCreatorCommand::RenderModelNodePreviewImage,
|
||||
QVariant::fromValue(imgContainer)});
|
||||
|
||||
m_modelNode3DImageViewAsyncData.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
void Qt5InformationNodeInstanceServer::modelNode3DImageViewRenderStep()
|
||||
{
|
||||
++m_modelNode3DImageViewAsyncData.count;
|
||||
|
||||
updateNodesRecursive(m_modelNode3DImageViewData.contentItem);
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
if (Internal::QuickItemNodeInstance::unifiedRenderPath()) {
|
||||
m_modelNode3DImageViewAsyncData.renderImage = m_modelNode3DImageViewData.window->grabWindow();
|
||||
} else {
|
||||
// Fake render loop signaling to update things like QML items as 3D textures
|
||||
m_modelNode3DImageViewData.window->beforeSynchronizing();
|
||||
m_modelNode3DImageViewData.window->beforeRendering();
|
||||
|
||||
QSizeF size = qobject_cast<QQuickItem *>(m_modelNode3DImageViewData.contentItem)->size();
|
||||
QRectF renderRect(QPointF(0., 0.), size);
|
||||
m_modelNode3DImageViewAsyncData.renderImage
|
||||
= designerSupport()->renderImageForItem(m_modelNode3DImageViewData.contentItem,
|
||||
renderRect, size.toSize());
|
||||
m_modelNode3DImageViewData.window->afterRendering();
|
||||
}
|
||||
#else
|
||||
m_modelNode3DImageViewAsyncData.renderImage = grabRenderControl(m_modelNode3DImageViewData);
|
||||
#endif
|
||||
QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "afterRender");
|
||||
const bool ready = QQmlProperty::read(m_modelNode3DImageViewData.rootItem, "ready").value<bool>();
|
||||
if (ready || m_modelNode3DImageViewAsyncData.count >= 10) {
|
||||
QMetaObject::invokeMethod(m_modelNode3DImageViewData.rootItem, "destroyView");
|
||||
if (m_modelNode3DImageViewAsyncData.createdFromComponent) {
|
||||
// If component changes, puppet will need a reset anyway, so we can cache the image
|
||||
m_modelNodePreviewImageCache.insert(m_modelNodePreviewImageCommand.componentPath(),
|
||||
m_modelNode3DImageViewAsyncData.renderImage);
|
||||
}
|
||||
modelNode3DImageViewSendImageToCreator();
|
||||
} else {
|
||||
m_modelNode3DImageViewAsyncData.timer.start();
|
||||
}
|
||||
}
|
||||
|
||||
static QRectF itemBoundingRect(QQuickItem *item)
|
||||
{
|
||||
QRectF itemRect;
|
||||
@@ -1205,6 +1225,7 @@ Qt5InformationNodeInstanceServer::Qt5InformationNodeInstanceServer(NodeInstanceC
|
||||
m_render3DEditViewTimer.setSingleShot(true);
|
||||
m_inputEventTimer.setSingleShot(true);
|
||||
m_renderModelNodeImageViewTimer.setSingleShot(true);
|
||||
m_modelNode3DImageViewAsyncData.timer.setSingleShot(true);
|
||||
|
||||
#ifdef FPS_COUNTER
|
||||
if (!_fpsTimer) {
|
||||
@@ -1224,11 +1245,12 @@ Qt5InformationNodeInstanceServer::~Qt5InformationNodeInstanceServer()
|
||||
{
|
||||
m_editView3DSetupDone = false;
|
||||
|
||||
m_propertyChangeTimer.stop();
|
||||
m_propertyChangeTimer.stop();
|
||||
m_selectionChangeTimer.stop();
|
||||
m_render3DEditViewTimer.stop();
|
||||
m_inputEventTimer.stop();
|
||||
m_renderModelNodeImageViewTimer.stop();
|
||||
m_modelNode3DImageViewAsyncData.timer.stop();
|
||||
|
||||
if (m_editView3DData.rootItem)
|
||||
m_editView3DData.rootItem->disconnect(this);
|
||||
@@ -1621,6 +1643,8 @@ void Qt5InformationNodeInstanceServer::setup3DEditView(const QList<ServerNodeIns
|
||||
this, &Qt5InformationNodeInstanceServer::doRender3DEditView);
|
||||
QObject::connect(&m_inputEventTimer, &QTimer::timeout,
|
||||
this, &Qt5InformationNodeInstanceServer::handleInputEvents);
|
||||
QObject::connect(&m_modelNode3DImageViewAsyncData.timer, &QTimer::timeout,
|
||||
this, &Qt5InformationNodeInstanceServer::modelNode3DImageViewRenderStep);
|
||||
|
||||
QString lastSceneId;
|
||||
auto helper = qobject_cast<QmlDesigner::Internal::GeneralHelper *>(m_3dHelper);
|
||||
@@ -2089,6 +2113,7 @@ void Qt5InformationNodeInstanceServer::view3DAction(const View3DActionCommand &c
|
||||
|
||||
void Qt5InformationNodeInstanceServer::requestModelNodePreviewImage(const RequestModelNodePreviewImageCommand &command)
|
||||
{
|
||||
m_modelNode3DImageViewAsyncData.timer.stop();
|
||||
m_modelNodePreviewImageCommand = command;
|
||||
renderModelNodeImageView();
|
||||
}
|
||||
|
@@ -138,6 +138,8 @@ private:
|
||||
void renderModelNodeImageView();
|
||||
void doRenderModelNodeImageView();
|
||||
void doRenderModelNode3DImageView();
|
||||
void modelNode3DImageViewSendImageToCreator();
|
||||
void modelNode3DImageViewRenderStep();
|
||||
void doRenderModelNode2DImageView();
|
||||
void updateLockedAndHiddenStates(const QSet<ServerNodeInstance> &instances);
|
||||
void handleInputEvents();
|
||||
@@ -184,6 +186,26 @@ private:
|
||||
QList<InputEventCommand> m_pendingInputEventCommands;
|
||||
QObject *m_3dHelper = nullptr;
|
||||
int m_need3DEditViewRender = 0;
|
||||
|
||||
struct ModelNode3DImageViewAsyncData {
|
||||
QTimer timer;
|
||||
QImage renderImage;
|
||||
int count = 0;
|
||||
bool createdFromComponent = false;
|
||||
QObject *instanceObj = nullptr;
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
timer.stop();
|
||||
count = 0;
|
||||
renderImage = {};
|
||||
if (createdFromComponent)
|
||||
delete instanceObj;
|
||||
instanceObj = nullptr;
|
||||
createdFromComponent = false;
|
||||
}
|
||||
};
|
||||
ModelNode3DImageViewAsyncData m_modelNode3DImageViewAsyncData;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -417,7 +417,7 @@ QImage Qt5NodeInstanceServer::grabItem(QQuickItem *item)
|
||||
if (instance.isValid())
|
||||
renderBoundingRect = instance.boundingRect();
|
||||
else
|
||||
renderBoundingRect = item->boundingRect();
|
||||
renderBoundingRect = ServerNodeInstance::effectAdjustedBoundingRect(item);
|
||||
|
||||
// Hide immediate children that have instances and are QQuickItems so we get only
|
||||
// the parent item's content, as compositing is handled on creator side.
|
||||
|
@@ -329,11 +329,23 @@ QRectF QuickItemNodeInstance::contentItemBoundingBox() const
|
||||
return QRectF();
|
||||
}
|
||||
|
||||
static bool layerEnabledAndEffect(QQuickItem *item)
|
||||
{
|
||||
QQuickItemPrivate *pItem = QQuickItemPrivate::get(item);
|
||||
|
||||
if (pItem && pItem->layer() && pItem->layer()->enabled() && pItem->layer()->effect())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QRectF QuickItemNodeInstance::boundingRect() const
|
||||
{
|
||||
if (quickItem()) {
|
||||
if (quickItem()->clip()) {
|
||||
return quickItem()->boundingRect();
|
||||
} else if (layerEnabledAndEffect(quickItem())) {
|
||||
return ServerNodeInstance::effectAdjustedBoundingRect(quickItem());
|
||||
} else {
|
||||
return boundingRectWithStepChilds(quickItem());
|
||||
}
|
||||
|
@@ -135,6 +135,13 @@ bool ServerNodeInstance::isSubclassOf(QObject *object, const QByteArray &superTy
|
||||
return Internal::QmlPrivateGate::isSubclassOf(object, superTypeName);
|
||||
}
|
||||
|
||||
QRectF ServerNodeInstance::effectAdjustedBoundingRect(QQuickItem *item)
|
||||
{
|
||||
if (item)
|
||||
return item->boundingRect().adjusted(-40, -40, 40, 40);
|
||||
return {};
|
||||
}
|
||||
|
||||
void ServerNodeInstance::setModifiedFlag(bool b)
|
||||
{
|
||||
m_nodeInstance->setModifiedFlag(b);
|
||||
|
@@ -180,6 +180,7 @@ public:
|
||||
QStringList allStates() const;
|
||||
|
||||
static bool isSubclassOf(QObject *object, const QByteArray &superTypeName);
|
||||
static QRectF effectAdjustedBoundingRect(QQuickItem *item);
|
||||
|
||||
void setModifiedFlag(bool b);
|
||||
void updateDirtyNodeRecursive();
|
||||
|
@@ -57,7 +57,7 @@ QtObject {
|
||||
readonly property string darkPaneColor: StudioTheme.Values.themeBackgroundColorNormal
|
||||
readonly property string lightPaneColor: StudioTheme.Values.themeBackgroundColorAlternate
|
||||
|
||||
readonly property string textColor: StudioTheme.Values.themeTabInactiveText
|
||||
readonly property string textColor: StudioTheme.Values.themeTextColor
|
||||
readonly property string textColorInteraction: StudioTheme.Values.themeInteraction
|
||||
readonly property string dividerlineColor: StudioTheme.Values.themeTextColorDisabled
|
||||
readonly property string textError: StudioTheme.Values.themeError
|
||||
|
@@ -35,67 +35,58 @@ GridView {
|
||||
|
||||
required property Item loader
|
||||
|
||||
header: TabBar {
|
||||
id: tabBar
|
||||
readonly property int animDur: 500
|
||||
|
||||
header: Rectangle {
|
||||
width: parent.width
|
||||
height: DialogValues.projectViewHeaderHeight
|
||||
color: DialogValues.lightPaneColor
|
||||
|
||||
background: Rectangle {
|
||||
color: DialogValues.lightPaneColor
|
||||
}
|
||||
Row {
|
||||
id: row
|
||||
spacing: 20
|
||||
property int currIndex: 0
|
||||
|
||||
Repeater {
|
||||
model: categoryModel
|
||||
Repeater {
|
||||
model: categoryModel
|
||||
Text {
|
||||
text: name
|
||||
font.weight: Font.DemiBold
|
||||
font.pixelSize: DialogValues.viewHeaderPixelSize
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: row.currIndex === index ? DialogValues.textColorInteraction
|
||||
: DialogValues.textColor
|
||||
Behavior on color { ColorAnimation { duration: animDur } }
|
||||
|
||||
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 {
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
row.currIndex = index
|
||||
projectModel.setPage(index)
|
||||
projectView.currentIndex = 0
|
||||
projectView.currentIndexChanged()
|
||||
|
||||
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
|
||||
strip.x = parent.x
|
||||
strip.width = parent.width
|
||||
}
|
||||
}
|
||||
|
||||
Item { width: parent.width; height: 11; }
|
||||
} // Column
|
||||
} // Item
|
||||
} // Text
|
||||
} // Repeater
|
||||
} // Row
|
||||
|
||||
onClicked: {
|
||||
projectModel.setPage(index)
|
||||
projectView.currentIndex = 0
|
||||
projectView.currentIndexChanged()
|
||||
}
|
||||
} // TabButton
|
||||
} // Repeater
|
||||
} // Header - TabBar
|
||||
Rectangle {
|
||||
id: strip
|
||||
width: row.children[0].width
|
||||
height: 5
|
||||
radius: 2
|
||||
color: DialogValues.textColorInteraction
|
||||
anchors.bottom: parent.bottom
|
||||
|
||||
Behavior on x { SmoothedAnimation { duration: animDur } }
|
||||
Behavior on width { SmoothedAnimation { duration: strip.width === 0 ? 0 : animDur } } // do not animate initial width
|
||||
}
|
||||
} // Rectangle
|
||||
|
||||
cellWidth: DialogValues.projectItemWidth
|
||||
cellHeight: DialogValues.projectItemHeight
|
||||
|
@@ -344,7 +344,7 @@ void InfoBarDisplay::update()
|
||||
if (info.m_cancelButtonCallBack)
|
||||
connect(infoWidgetCloseButton, &QAbstractButton::clicked, info.m_cancelButtonCallBack);
|
||||
connect(infoWidgetCloseButton, &QAbstractButton::clicked, this, [this, id] {
|
||||
m_infoBar->suppressInfo(id);
|
||||
m_infoBar->removeInfo(id);
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -57,7 +57,7 @@ namespace Internal {
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
#define APP_ID "io.qt.designviewer"
|
||||
#define APP_ID "io.qt.qtdesignviewer"
|
||||
|
||||
class ApkInfo {
|
||||
public:
|
||||
@@ -92,7 +92,7 @@ FilePath AndroidQmlPreviewWorker::designViewerApkPath(const QString &abi) const
|
||||
return {};
|
||||
|
||||
if (apkInfo()->abis.contains(abi)) {
|
||||
return Core::ICore::resourcePath(QString("android/qtdesignviewer/designviewer_%1.apk")
|
||||
return Core::ICore::resourcePath(QString("android/qtdesignviewer/qtdesignviewer_%1.apk")
|
||||
.arg(abi));
|
||||
}
|
||||
return {};
|
||||
|
@@ -2938,10 +2938,12 @@ void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator,
|
||||
if (!edit)
|
||||
return;
|
||||
|
||||
const int labelOpenParenOffset = item.label().indexOf('(');
|
||||
const int labelClosingParenOffset = item.label().indexOf(')');
|
||||
const auto kind = static_cast<CompletionItemKind::Kind>(
|
||||
item.kind().value_or(CompletionItemKind::Text));
|
||||
const bool isMacroCall = kind == CompletionItemKind::Text && item.label().contains('(')
|
||||
&& item.label().contains(')'); // Heuristic
|
||||
const bool isMacroCall = kind == CompletionItemKind::Text && labelOpenParenOffset != -1
|
||||
&& labelClosingParenOffset > labelOpenParenOffset; // Heuristic
|
||||
const bool isFunctionLike = kind == CompletionItemKind::Function
|
||||
|| kind == CompletionItemKind::Method || kind == CompletionItemKind::Constructor
|
||||
|| isMacroCall;
|
||||
@@ -2951,10 +2953,12 @@ void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator,
|
||||
// Some preparation for our magic involving (non-)insertion of parentheses and
|
||||
// cursor placement.
|
||||
if (isFunctionLike && !rawInsertText.contains('(')) {
|
||||
if (item.label().contains("()")) // function takes no arguments
|
||||
rawInsertText += "()";
|
||||
else if (item.label().contains('(')) // function takes arguments
|
||||
rawInsertText += "( )";
|
||||
if (labelOpenParenOffset != -1) {
|
||||
if (labelClosingParenOffset == labelOpenParenOffset + 1) // function takes no arguments
|
||||
rawInsertText += "()";
|
||||
else // function takes arguments
|
||||
rawInsertText += "( )";
|
||||
}
|
||||
}
|
||||
|
||||
const int firstParenOffset = rawInsertText.indexOf('(');
|
||||
@@ -3670,7 +3674,13 @@ void ExtraHighlightingResultsCollector::visitNode(const AstNode &node)
|
||||
|
||||
bool ClangdClient::FollowSymbolData::defLinkIsAmbiguous() const
|
||||
{
|
||||
// If we have up-to-date highlighting info, we can give a definite answer.
|
||||
// Even if the call is to a virtual function, it might not be ambiguous:
|
||||
// class A { virtual void f(); }; class B : public A { void f() override { A::f(); } };
|
||||
if (!cursorNode->mightBeAmbiguousVirtualCall() && !cursorNode->isPureVirtualDeclaration())
|
||||
return false;
|
||||
|
||||
// If we have up-to-date highlighting info, we know whether we are dealing with
|
||||
// a virtual call.
|
||||
if (editorWidget) {
|
||||
const auto virtualRanges = q->d->virtualRanges.constFind(editorWidget->textDocument());
|
||||
if (virtualRanges != q->d->virtualRanges.constEnd()
|
||||
@@ -3682,8 +3692,9 @@ bool ClangdClient::FollowSymbolData::defLinkIsAmbiguous() const
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, we have to rely on AST-based heuristics.
|
||||
return cursorNode->mightBeAmbiguousVirtualCall() || cursorNode->isPureVirtualDeclaration();
|
||||
// Otherwise, we accept potentially doing more work than needed rather than not catching
|
||||
// possible overrides.
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -149,6 +149,7 @@ void CMakeManager::updateCmakeActions(Node *node)
|
||||
auto project = qobject_cast<CMakeProject *>(SessionManager::startupProject());
|
||||
const bool visible = project && !BuildManager::isBuilding(project);
|
||||
m_runCMakeAction->setVisible(visible);
|
||||
m_runCMakeActionContextMenu->setEnabled(visible);
|
||||
m_clearCMakeCacheAction->setVisible(visible);
|
||||
m_rescanProjectAction->setVisible(visible);
|
||||
enableBuildFileMenus(node);
|
||||
|
@@ -607,7 +607,7 @@ QList<IDocument *> DocumentManager::modifiedDocuments()
|
||||
}
|
||||
|
||||
/*!
|
||||
Treats any subsequent change to \a fileName as an expected file change.
|
||||
Treats any subsequent change to \a filePath as an expected file change.
|
||||
|
||||
\sa unexpectFileChange()
|
||||
*/
|
||||
@@ -631,7 +631,7 @@ static void updateExpectedState(const FilePath &filePathKey)
|
||||
}
|
||||
|
||||
/*!
|
||||
Considers all changes to \a fileName unexpected again.
|
||||
Considers all changes to \a filePath unexpected again.
|
||||
|
||||
\sa expectFileChange()
|
||||
*/
|
||||
|
@@ -256,29 +256,13 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *)
|
||||
*/
|
||||
|
||||
/*!
|
||||
\class EditorManager::FilePathInfo
|
||||
\inheaderfile coreplugin/editormanager/editormanager.h
|
||||
\inmodule QtCreator
|
||||
|
||||
\brief The FilePathInfo class contains information about a file path's
|
||||
special segments.
|
||||
|
||||
File names can have an additional postfix, optionally specifying a line and
|
||||
column number, when opening a file in \QC from the command line or locator.
|
||||
The FilePathInfo class contains the file name, the complete postfix string,
|
||||
and the parsed line and column numbers.
|
||||
|
||||
\sa EditorManager::splitLineAndColumnNumber()
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void EditorManager::currentEditorChanged(IEditor *editor)
|
||||
\fn void Core::EditorManager::currentEditorChanged(Core::IEditor *editor)
|
||||
|
||||
This signal is emitted after the current editor changed to \a editor.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void EditorManager::currentDocumentStateChanged()
|
||||
\fn void Core::EditorManager::currentDocumentStateChanged()
|
||||
|
||||
This signal is emitted when the meta data of the current document, for
|
||||
example file name or modified state, changed.
|
||||
@@ -287,7 +271,7 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *)
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void EditorManager::documentStateChanged(IDocument *document)
|
||||
\fn void Core::EditorManager::documentStateChanged(Core::IDocument *document)
|
||||
|
||||
This signal is emitted when the meta data of the \a document, for
|
||||
example file name or modified state, changed.
|
||||
@@ -296,13 +280,13 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *)
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void EditorManager::editorCreated(IEditor *editor, const QString &fileName)
|
||||
\fn void Core::EditorManager::editorCreated(Core::IEditor *editor, const QString &fileName)
|
||||
|
||||
This signal is emitted after an \a editor was created for \a fileName, but
|
||||
before it was opened in an editor view.
|
||||
*/
|
||||
/*!
|
||||
\fn void EditorManager::editorOpened(IEditor *editor)
|
||||
\fn void Core::EditorManager::editorOpened(Core::IEditor *editor)
|
||||
|
||||
This signal is emitted after a new \a editor was opened in an editor view.
|
||||
|
||||
@@ -310,14 +294,14 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *)
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void EditorManager::documentOpened(IDocument *document)
|
||||
\fn void Core::EditorManager::documentOpened(Core::IDocument *document)
|
||||
|
||||
This signal is emitted after the first editor for \a document opened in an
|
||||
editor view.
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void EditorManager::editorAboutToClose(IEditor *editor)
|
||||
\fn void Core::EditorManager::editorAboutToClose(Core::IEditor *editor)
|
||||
|
||||
This signal is emitted before \a editor is closed. This can be used to free
|
||||
resources that were allocated for the editor separately from the editor
|
||||
@@ -330,7 +314,7 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *)
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void EditorManager::editorsClosed(QList<IEditor *> editors)
|
||||
\fn void Core::EditorManager::editorsClosed(QList<Core::IEditor *> editors)
|
||||
|
||||
This signal is emitted after the \a editors closed, but before they are
|
||||
deleted.
|
||||
@@ -339,7 +323,7 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *)
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn void EditorManager::documentClosed(IDocument *document)
|
||||
\fn void Core::EditorManager::documentClosed(Core::IDocument *document)
|
||||
|
||||
This signal is emitted after the \a document closed, but before it is deleted.
|
||||
*/
|
||||
@@ -349,22 +333,22 @@ void EditorManagerPlaceHolder::showEvent(QShowEvent *)
|
||||
\internal
|
||||
*/
|
||||
/*!
|
||||
\fn void EditorManager::aboutToSave(IDocument *document)
|
||||
\fn void Core::EditorManager::aboutToSave(Core::IDocument *document)
|
||||
|
||||
This signal is emitted before the \a document is saved.
|
||||
*/
|
||||
/*!
|
||||
\fn void EditorManager::saved(IDocument *document)
|
||||
\fn void Core::EditorManager::saved(Core::IDocument *document)
|
||||
|
||||
This signal is emitted after the \a document was saved.
|
||||
*/
|
||||
/*!
|
||||
\fn void EditorManager::autoSaved()
|
||||
\fn void Core::EditorManager::autoSaved()
|
||||
|
||||
This signal is emitted after auto-save was triggered.
|
||||
*/
|
||||
/*!
|
||||
\fn void EditorManager::currentEditorAboutToChange(IEditor *editor)
|
||||
\fn void Core::EditorManager::currentEditorAboutToChange(Core::IEditor *editor)
|
||||
|
||||
This signal is emitted before the current editor changes to \a editor.
|
||||
*/
|
||||
@@ -3076,10 +3060,10 @@ IEditor *EditorManager::openEditor(const QString &fileName, Id editorId,
|
||||
}
|
||||
|
||||
/*!
|
||||
Opens the document specified by \a filePath using the editor type \a
|
||||
Opens the document specified by \a link using the editor type \a
|
||||
editorId and the specified \a flags.
|
||||
|
||||
Moves the text cursor to the \a line and \a column.
|
||||
Moves the text cursor to the \e line and \e column specified in \a link.
|
||||
|
||||
If \a editorId is \c Id(), the editor type is derived from the file's MIME
|
||||
type.
|
||||
@@ -3147,7 +3131,7 @@ void EditorManager::openEditorAtSearchResult(const SearchResultItem &item,
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns whether \a fileName is an auto-save file created by \QC.
|
||||
Returns whether \a filePath is an auto-save file created by \QC.
|
||||
*/
|
||||
bool EditorManager::isAutoSaveFile(const QString &filePath)
|
||||
{
|
||||
@@ -3199,7 +3183,7 @@ void EditorManager::addCloseEditorListener(const std::function<bool (IEditor *)>
|
||||
/*!
|
||||
Asks the user for a list of files to open and returns the choice.
|
||||
|
||||
\sa DocumentManager::getOpenFilePaths()
|
||||
\sa DocumentManager::getOpenFileNames()
|
||||
*/
|
||||
FilePaths EditorManager::getOpenFilePaths()
|
||||
{
|
||||
|
@@ -162,7 +162,7 @@ const EditorFactoryList IEditorFactory::defaultEditorFactories(const Utils::Mime
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the available editor factories for \a fileName in order of
|
||||
Returns the available editor factories for \a filePath in order of
|
||||
preference. That is the default order for the document's MIME type but with
|
||||
a user overridden default editor first, and the binary editor as the very
|
||||
first item if a text document is too large to be opened as a text file.
|
||||
|
@@ -55,8 +55,7 @@ namespace Core {
|
||||
*/
|
||||
|
||||
/*!
|
||||
|
||||
\fn bool Core::IExternalEditor::startEditor(const QString &fileName, QString *errorMessage) = 0;
|
||||
\fn bool Core::IExternalEditor::startEditor(const Utils::FilePath &fileName, QString *errorMessage)
|
||||
|
||||
Opens the editor with \a fileName. Returns \c true on success or \c false
|
||||
on failure along with the error in \a errorMessage.
|
||||
|
@@ -186,7 +186,7 @@ QIcon FileIconProviderImplementation::icon(const FilePath &filePath) const
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the icon associated with the file suffix in \a info. If there is none,
|
||||
Returns the icon associated with the file suffix in \a filePath. If there is none,
|
||||
the default icon of the operating system is returned.
|
||||
*/
|
||||
|
||||
|
@@ -857,7 +857,7 @@ void SearchResult::setTextToReplace(const QString &textToReplace)
|
||||
}
|
||||
|
||||
/*!
|
||||
Sets whether replace is enabled and can be triggered by the user
|
||||
Sets whether replace is \a enabled and can be triggered by the user.
|
||||
*/
|
||||
void SearchResult::setReplaceEnabled(bool enabled)
|
||||
{
|
||||
|
@@ -426,7 +426,7 @@ static QString pathHelper(const QString &rel)
|
||||
return '/' + rel;
|
||||
}
|
||||
/*!
|
||||
Returns the absolute path that is used for resources like
|
||||
Returns the absolute path for the relative path \a rel that is used for resources like
|
||||
project templates and the debugger macros.
|
||||
|
||||
This abstraction is needed to avoid platform-specific code all over
|
||||
@@ -443,7 +443,7 @@ FilePath ICore::resourcePath(const QString &rel)
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the absolute path in the users directory that is used for
|
||||
Returns the absolute path for the relative path \a rel in the users directory that is used for
|
||||
resources like project templates.
|
||||
|
||||
Use this function for finding the place for resources that the user may
|
||||
@@ -468,7 +468,7 @@ FilePath ICore::userResourcePath(const QString &rel)
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns a writable path that can be used for persistent cache files.
|
||||
Returns a writable path for the relative path \a rel that can be used for persistent cache files.
|
||||
*/
|
||||
FilePath ICore::cacheResourcePath(const QString &rel)
|
||||
{
|
||||
@@ -477,8 +477,8 @@ FilePath ICore::cacheResourcePath(const QString &rel)
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the path to resources written by the installer, for example
|
||||
pre-defined kits and toolchains.
|
||||
Returns the path, based on the relative path \a rel, to resources written by the installer,
|
||||
for example pre-defined kits and toolchains.
|
||||
*/
|
||||
FilePath ICore::installerResourcePath(const QString &rel)
|
||||
{
|
||||
@@ -516,8 +516,8 @@ QString ICore::userPluginPath()
|
||||
}
|
||||
|
||||
/*!
|
||||
Returns the path to the command line tools that are included in the \QC
|
||||
installation.
|
||||
Returns the path, based on the relative path \a rel, to the command line tools that are
|
||||
included in the \QC installation.
|
||||
*/
|
||||
FilePath ICore::libexecPath(const QString &rel)
|
||||
{
|
||||
|
@@ -61,11 +61,11 @@
|
||||
*/
|
||||
|
||||
/*!
|
||||
\fn Core::IVersionControl::TopicCache::trackFile(const QString &repository)
|
||||
\fn Utils::FilePath Core::IVersionControl::TopicCache::trackFile(const Utils::FilePath &repository)
|
||||
Returns the path to the file that invalidates the cache for \a repository when
|
||||
the file is modified.
|
||||
|
||||
\fn Core::IVersionControl::TopicCache::refreshTopic(const QString &repository)
|
||||
\fn QString Core::IVersionControl::TopicCache::refreshTopic(const Utils::FilePath &repository)
|
||||
Returns the current topic for \a repository.
|
||||
*/
|
||||
|
||||
|
@@ -180,7 +180,7 @@ static QString defaultCommand()
|
||||
return "locate";
|
||||
}
|
||||
|
||||
/*!
|
||||
/*
|
||||
For the tools es [1] and locate [2], interpret space as AND operator.
|
||||
|
||||
Currently doesn't support fine picking a file with a space in the path by escaped space.
|
||||
|
@@ -81,6 +81,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
Range range() const { return m_range; }
|
||||
Position pos() const { return m_range.start(); }
|
||||
bool contains(const Position &pos) const { return m_range.contains(pos); }
|
||||
|
||||
@@ -345,8 +346,14 @@ void OutlineComboBox::updateModel(const DocumentUri &resultUri, const DocumentSy
|
||||
void OutlineComboBox::updateEntry()
|
||||
{
|
||||
const Position pos(m_editorWidget->textCursor());
|
||||
LanguageClientOutlineItem *itemForCursor = m_model.findNonRootItem(
|
||||
[&](const LanguageClientOutlineItem *item) { return item->contains(pos); });
|
||||
LanguageClientOutlineItem *itemForCursor = nullptr;
|
||||
m_model.forAllItems([&](LanguageClientOutlineItem *candidate){
|
||||
if (!candidate->contains(pos))
|
||||
return;
|
||||
if (itemForCursor && candidate->range().contains(itemForCursor->range()))
|
||||
return; // skip item if the range is equal or bigger than the previous found range
|
||||
itemForCursor = candidate;
|
||||
});
|
||||
if (itemForCursor)
|
||||
setCurrentIndex(m_model.indexForItem(itemForCursor));
|
||||
}
|
||||
|
@@ -104,8 +104,6 @@ static McuToolChainPackage *createArmGccPackage()
|
||||
defaultPath = subDirs.first();
|
||||
}
|
||||
}
|
||||
if (defaultPath.isEmpty())
|
||||
defaultPath = FileUtils::homePath();
|
||||
|
||||
const QString detectionPath = Utils::HostOsInfo::withExecutableSuffix("bin/arm-none-eabi-g++");
|
||||
const auto versionDetector = new McuPackageExecutableVersionDetector(
|
||||
@@ -129,8 +127,7 @@ static McuToolChainPackage *createGhsToolchainPackage()
|
||||
{
|
||||
const char envVar[] = "GHS_COMPILER_DIR";
|
||||
|
||||
const FilePath defaultPath = qEnvironmentVariableIsSet(envVar)
|
||||
? FilePath::fromUserInput(qEnvironmentVariable(envVar)) : FileUtils::homePath();
|
||||
const FilePath defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar));
|
||||
|
||||
const auto versionDetector = new McuPackageExecutableVersionDetector(
|
||||
Utils::HostOsInfo::withExecutableSuffix("as850"),
|
||||
@@ -153,8 +150,7 @@ static McuToolChainPackage *createGhsArmToolchainPackage()
|
||||
{
|
||||
const char envVar[] = "GHS_ARM_COMPILER_DIR";
|
||||
|
||||
const FilePath defaultPath = qEnvironmentVariableIsSet(envVar)
|
||||
? FilePath::fromUserInput(qEnvironmentVariable(envVar)) : FileUtils::homePath();
|
||||
const FilePath defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar));
|
||||
|
||||
const auto versionDetector = new McuPackageExecutableVersionDetector(
|
||||
Utils::HostOsInfo::withExecutableSuffix("asarm"),
|
||||
@@ -189,8 +185,6 @@ static McuToolChainPackage *createIarToolChainPackage()
|
||||
const FilePath compilerExecPath = tc->compilerCommand();
|
||||
defaultPath = compilerExecPath.parentDir().parentDir();
|
||||
}
|
||||
else
|
||||
defaultPath = FileUtils::homePath();
|
||||
}
|
||||
|
||||
const QString detectionPath = Utils::HostOsInfo::withExecutableSuffix("bin/iccarm");
|
||||
@@ -219,8 +213,9 @@ static McuPackage *createRGLPackage()
|
||||
if (qEnvironmentVariableIsSet(envVar)) {
|
||||
defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar));
|
||||
} else if (Utils::HostOsInfo::isWindowsHost()) {
|
||||
defaultPath = FilePath::fromUserInput(QDir::rootPath() + "Renesas_Electronics/D1x_RGL");
|
||||
if (defaultPath.exists()) {
|
||||
const FilePath rglPath = FilePath::fromString(QDir::rootPath()) / "Renesas_Electronics/D1x_RGL";
|
||||
if (rglPath.exists()) {
|
||||
defaultPath = rglPath;
|
||||
const FilePaths subDirs =
|
||||
defaultPath.dirEntries({QLatin1String("rgl_ghs_D1Mx_*")},
|
||||
QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
@@ -240,7 +235,7 @@ static McuPackage *createRGLPackage()
|
||||
|
||||
static McuPackage *createStm32CubeProgrammerPackage()
|
||||
{
|
||||
FilePath defaultPath = FileUtils::homePath();
|
||||
FilePath defaultPath;
|
||||
const QString cubePath = "STMicroelectronics/STM32Cube/STM32CubeProgrammer";
|
||||
if (HostOsInfo::isWindowsHost()) {
|
||||
const FilePath programPath = findInProgramFiles(cubePath);
|
||||
@@ -272,8 +267,9 @@ static McuPackage *createMcuXpressoIdePackage()
|
||||
if (qEnvironmentVariableIsSet(envVar)) {
|
||||
defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar));
|
||||
} else if (HostOsInfo::isWindowsHost()) {
|
||||
defaultPath = FilePath::fromString(QDir::rootPath() + "nxp");
|
||||
if (defaultPath.exists()) {
|
||||
const FilePath programPath = FilePath::fromString(QDir::rootPath()) / "nxp";
|
||||
if (programPath.exists()) {
|
||||
defaultPath = programPath;
|
||||
// If default dir has exactly one sub dir that could be the IDE path, pre-select that.
|
||||
const FilePaths subDirs =
|
||||
defaultPath.dirEntries({QLatin1String("MCUXpressoIDE*")},
|
||||
@@ -282,7 +278,9 @@ static McuPackage *createMcuXpressoIdePackage()
|
||||
defaultPath = subDirs.first();
|
||||
}
|
||||
} else {
|
||||
defaultPath = "/usr/local/mcuxpressoide/";
|
||||
const FilePath programPath = FilePath::fromString("/usr/local/mcuxpressoide/");
|
||||
if (programPath.exists())
|
||||
defaultPath = programPath;
|
||||
}
|
||||
|
||||
auto result = new McuPackage(
|
||||
@@ -303,17 +301,11 @@ static McuPackage *createCypressProgrammerPackage()
|
||||
if (qEnvironmentVariableIsSet(envVar)) {
|
||||
defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar));
|
||||
} else if (HostOsInfo::isWindowsHost()) {
|
||||
FilePath candidate = findInProgramFiles("Cypress/Cypress Auto Flash Utility 1.0");
|
||||
if (candidate.exists()) {
|
||||
const FilePath candidate = findInProgramFiles("Cypress/Cypress Auto Flash Utility 1.0");
|
||||
if (candidate.exists())
|
||||
defaultPath = candidate;
|
||||
}
|
||||
} else {
|
||||
defaultPath = "/usr";
|
||||
}
|
||||
|
||||
if (defaultPath.isEmpty())
|
||||
defaultPath = FileUtils::homePath();
|
||||
|
||||
auto result = new McuPackage(
|
||||
"Cypress Auto Flash Utility",
|
||||
defaultPath,
|
||||
@@ -393,7 +385,7 @@ static McuPackage *createBoardSdkPackage(const McuTargetDescription& desc)
|
||||
if (defaultPath.exists())
|
||||
return defaultPath;
|
||||
}
|
||||
return FileUtils::homePath();
|
||||
return FilePath();
|
||||
}();
|
||||
|
||||
const auto versionDetector = generatePackageVersionDetector(desc.boardSdk.envVar);
|
||||
@@ -418,8 +410,6 @@ static McuPackage *createFreeRTOSSourcesPackage(const QString &envVar, const Fil
|
||||
defaultPath = FilePath::fromUserInput(qEnvironmentVariable(envVar.toLatin1()));
|
||||
else if (!boardSdkDir.isEmpty() && !freeRTOSBoardSdkSubDir.isEmpty())
|
||||
defaultPath = boardSdkDir / freeRTOSBoardSdkSubDir;
|
||||
else
|
||||
defaultPath = FileUtils::homePath();
|
||||
|
||||
auto result = new McuPackage(
|
||||
QString::fromLatin1("FreeRTOS Sources (%1)").arg(envVarPrefix),
|
||||
@@ -634,7 +624,7 @@ static QVector<McuTarget *> targetsFromDescriptions(const QList<McuTargetDescrip
|
||||
|
||||
Utils::FilePath kitsPath(const Utils::FilePath &dir)
|
||||
{
|
||||
return dir + "/kits/";
|
||||
return dir / "kits/";
|
||||
}
|
||||
|
||||
static QFileInfoList targetDescriptionFiles(const Utils::FilePath &dir)
|
||||
|
@@ -83,9 +83,18 @@ bool Navigation2dFilter::gestureEvent(QGestureEvent *event)
|
||||
bool Navigation2dFilter::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
if (event->source() == Qt::MouseEventSynthesizedBySystem) {
|
||||
emit panChanged(QPointF(event->pixelDelta()));
|
||||
event->accept();
|
||||
return true;
|
||||
if (event->modifiers().testFlag(Qt::ControlModifier)) {
|
||||
if (QPointF delta = event->pixelDelta(); !delta.isNull()) {
|
||||
double dist = std::abs(delta.x()) > std::abs(delta.y()) ? -delta.x() : delta.y();
|
||||
emit zoomChanged(dist/200.0, event->position());
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
emit panChanged(QPointF(event->pixelDelta()));
|
||||
event->accept();
|
||||
return true;
|
||||
}
|
||||
} else if (event->source() == Qt::MouseEventNotSynthesized) {
|
||||
|
||||
auto zoomInSignal = QMetaMethod::fromSignal(&Navigation2dFilter::zoomIn);
|
||||
|
@@ -279,7 +279,10 @@ bool DesignDocument::isDocumentLoaded() const
|
||||
|
||||
void DesignDocument::resetToDocumentModel()
|
||||
{
|
||||
plainTextEdit()->document()->clearUndoRedoStacks();
|
||||
const QPlainTextEdit *edit = plainTextEdit();
|
||||
if (edit)
|
||||
edit->document()->clearUndoRedoStacks();
|
||||
|
||||
m_inFileComponentModel.reset();
|
||||
}
|
||||
|
||||
@@ -311,7 +314,9 @@ void DesignDocument::changeToDocumentModel()
|
||||
viewManager().detachRewriterView();
|
||||
viewManager().detachViewsExceptRewriterAndComponetView();
|
||||
|
||||
plainTextEdit()->document()->clearUndoRedoStacks();
|
||||
const QPlainTextEdit *edit = plainTextEdit();
|
||||
if (edit)
|
||||
edit->document()->clearUndoRedoStacks();
|
||||
|
||||
m_inFileComponentModel.reset();
|
||||
m_inFileComponentTextModifier.reset();
|
||||
@@ -348,7 +353,9 @@ void DesignDocument::changeToInFileComponentModel(ComponentTextModifier *textMod
|
||||
viewManager().detachRewriterView();
|
||||
viewManager().detachViewsExceptRewriterAndComponetView();
|
||||
|
||||
plainTextEdit()->document()->clearUndoRedoStacks();
|
||||
const QPlainTextEdit *edit = plainTextEdit();
|
||||
if (edit)
|
||||
edit->document()->clearUndoRedoStacks();
|
||||
|
||||
m_inFileComponentModel.reset(createInFileComponentModel());
|
||||
m_inFileComponentModel->setTextModifier(m_inFileComponentTextModifier.data());
|
||||
|
@@ -102,11 +102,15 @@ bool ItemLibraryWidget::eventFilter(QObject *obj, QEvent *event)
|
||||
// For drag to be handled correctly, we must have the component properly imported
|
||||
// beforehand, so we import the module immediately when the drag starts
|
||||
if (!entry.requiredImport().isEmpty()) {
|
||||
Import import = Import::createLibraryImport(entry.requiredImport());
|
||||
if (!m_model->hasImport(import, true, true)) {
|
||||
// We don't know if required import is library of file import, so try both.
|
||||
Import libImport = Import::createLibraryImport(entry.requiredImport());
|
||||
Import fileImport = Import::createFileImport(entry.requiredImport());
|
||||
if (!m_model->hasImport(libImport, true, true)
|
||||
&& !m_model->hasImport(fileImport, true, true)) {
|
||||
const QList<Import> possImports = m_model->possibleImports();
|
||||
for (const auto &possImport : possImports) {
|
||||
if (possImport.url() == import.url()) {
|
||||
if ((!possImport.url().isEmpty() && possImport.url() == libImport.url())
|
||||
|| (!possImport.file().isEmpty() && possImport.file() == fileImport.file())) {
|
||||
m_model->changeImports({possImport}, {});
|
||||
break;
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "navigatorwidget.h"
|
||||
#include "qmldesignerconstants.h"
|
||||
#include "qmldesignericons.h"
|
||||
#include "qmldesignerplugin.h"
|
||||
|
||||
#include "nameitemdelegate.h"
|
||||
#include "iconcheckboxitemdelegate.h"
|
||||
@@ -166,9 +167,14 @@ void NavigatorView::modelAttached(Model *model)
|
||||
const QHash<QString, bool> localExpandMap = m_expandMap[AbstractView::model()->fileUrl()];
|
||||
auto it = localExpandMap.constBegin();
|
||||
while (it != localExpandMap.constEnd()) {
|
||||
const QModelIndex index = indexForModelNode(modelNodeForId(it.key()));
|
||||
if (index.isValid())
|
||||
treeWidget()->setExpanded(index, it.value());
|
||||
const ModelNode node = modelNodeForId(it.key());
|
||||
// When editing subcomponent, the current root node may be marked collapsed in the
|
||||
// full file view, but we never want to actually collapse it, so skip it.
|
||||
if (!node.isRootNode()) {
|
||||
const QModelIndex index = indexForModelNode(node);
|
||||
if (index.isValid())
|
||||
treeWidget()->setExpanded(index, it.value());
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
@@ -200,11 +206,18 @@ void NavigatorView::addNodeAndSubModelNodesToList(const ModelNode &node, QList<M
|
||||
|
||||
void NavigatorView::modelAboutToBeDetached(Model *model)
|
||||
{
|
||||
m_expandMap.remove(model->fileUrl());
|
||||
QHash<QString, bool> &localExpandMap = m_expandMap[model->fileUrl()];
|
||||
|
||||
// If detaching full document model, recreate expand map from scratch to remove stale entries.
|
||||
// Otherwise just update it (subcomponent edit case).
|
||||
bool fullUpdate = true;
|
||||
if (DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument())
|
||||
fullUpdate = !document->inFileComponentModelActive();
|
||||
if (fullUpdate)
|
||||
localExpandMap.clear();
|
||||
|
||||
if (currentModel()) {
|
||||
// Store expand state of the navigator tree
|
||||
QHash<QString, bool> localExpandMap;
|
||||
const ModelNode rootNode = rootModelNode();
|
||||
const QModelIndex rootIndex = indexForModelNode(rootNode);
|
||||
|
||||
@@ -215,15 +228,18 @@ void NavigatorView::modelAboutToBeDetached(Model *model)
|
||||
for (int i = 0; i < rowCount; ++i) {
|
||||
const QModelIndex childIndex = currentModel()->index(i, 0, index);
|
||||
const ModelNode node = modelNodeForIndex(childIndex);
|
||||
// Just store collapsed states as everything is expanded by default
|
||||
if (node.isValid() && !treeWidget()->isExpanded(childIndex))
|
||||
localExpandMap.insert(node.id(), false);
|
||||
if (node.isValid()) {
|
||||
// Just store collapsed states as everything is expanded by default
|
||||
if (!treeWidget()->isExpanded(childIndex))
|
||||
localExpandMap.insert(node.id(), false);
|
||||
else if (!fullUpdate)
|
||||
localExpandMap.remove(node.id());
|
||||
}
|
||||
gatherExpandedState(childIndex);
|
||||
}
|
||||
}
|
||||
};
|
||||
gatherExpandedState(rootIndex);
|
||||
m_expandMap[model->fileUrl()] = localExpandMap;
|
||||
}
|
||||
|
||||
AbstractView::modelAboutToBeDetached(model);
|
||||
|
@@ -112,7 +112,7 @@ QmlProject::QmlProject(const Utils::FilePath &fileName)
|
||||
Utils::InfoBarEntry
|
||||
info(openInQDSAppSetting,
|
||||
tr("Would you like to open the project in Qt Design Studio?"),
|
||||
Utils::InfoBarEntry::GlobalSuppression::Enabled);
|
||||
Utils::InfoBarEntry::GlobalSuppression::Disabled);
|
||||
info.setCustomButtonInfo(tr("Open in Qt Design Studio"), [&, fileName] {
|
||||
Core::ICore::infoBar()->removeInfo(openInQDSAppSetting);
|
||||
QmlProjectPlugin::openQDS(fileName);
|
||||
|
@@ -303,6 +303,7 @@ void QdsNewDialog::accept()
|
||||
{
|
||||
CreateProject create{m_wizard};
|
||||
|
||||
m_dialog->hide();
|
||||
create.withName(m_qmlProjectName)
|
||||
.atLocation(m_qmlProjectLocation)
|
||||
.withScreenSizes(m_qmlScreenSizeIndex, m_qmlCustomWidth, m_qmlCustomHeight)
|
||||
@@ -313,6 +314,8 @@ void QdsNewDialog::accept()
|
||||
.execute();
|
||||
|
||||
m_dialog->close();
|
||||
m_dialog->deleteLater();
|
||||
m_dialog = nullptr;
|
||||
}
|
||||
|
||||
void QdsNewDialog::reject()
|
||||
|
@@ -63,6 +63,7 @@ void WizardHandler::destroyWizard()
|
||||
m_selectedProject = -1;
|
||||
m_wizard->deleteLater();
|
||||
m_wizard = nullptr;
|
||||
m_detailsPage = nullptr;
|
||||
}
|
||||
|
||||
void WizardHandler::setupWizard()
|
||||
|