Merge remote-tracking branch 'origin/4.9'
Change-Id: I7d1912cd5c4d824fd40d3454c5f1bb796f2c21d8
@@ -8,7 +8,7 @@ The standalone binary packages support the following platforms:
|
|||||||
|
|
||||||
* Windows 7 or later
|
* Windows 7 or later
|
||||||
* (K)Ubuntu Linux 16.04 (64-bit) or later
|
* (K)Ubuntu Linux 16.04 (64-bit) or later
|
||||||
* macOS 10.11 or later
|
* macOS 10.12 or later
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|||||||
@@ -221,6 +221,11 @@ Remote Linux
|
|||||||
(QTCREATORBUG-21225)
|
(QTCREATORBUG-21225)
|
||||||
* Fixed issue with killing remote process (QTCREATORBUG-19941)
|
* Fixed issue with killing remote process (QTCREATORBUG-19941)
|
||||||
|
|
||||||
|
Boot to Qt
|
||||||
|
|
||||||
|
* Removed ADB-based Boot to Qt plugin that provided support for
|
||||||
|
Boot to Qt versions 5.8, and earlier.
|
||||||
|
|
||||||
Credits for these changes go to:
|
Credits for these changes go to:
|
||||||
Aaron Barany
|
Aaron Barany
|
||||||
Alessandro Portale
|
Alessandro Portale
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
** Copyright (C) 2019 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of Qt Creator.
|
** This file is part of Qt Creator.
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ imagedirs = ../images \
|
|||||||
../../src/plugins/qmldesigner/components/formeditor \
|
../../src/plugins/qmldesigner/components/formeditor \
|
||||||
../../src/plugins/qmldesigner/components/navigator \
|
../../src/plugins/qmldesigner/components/navigator \
|
||||||
../../src/plugins/scxmleditor/common/images \
|
../../src/plugins/scxmleditor/common/images \
|
||||||
../../src/plugins/texteditor/images
|
../../src/plugins/texteditor/images \
|
||||||
|
../../src/plugins/valgrind/images
|
||||||
|
|
||||||
exampledirs = ../examples
|
exampledirs = ../examples
|
||||||
examples.fileextensions += *.qml *.svg
|
examples.fileextensions += *.qml *.svg
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 3.7 KiB |
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
** Copyright (C) 2019 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -149,13 +149,17 @@
|
|||||||
|
|
||||||
You can use the Callgrind tool included in the
|
You can use the Callgrind tool included in the
|
||||||
\l{http://valgrind.org/info/tools.html}{Valgrind tool suite} to detect
|
\l{http://valgrind.org/info/tools.html}{Valgrind tool suite} to detect
|
||||||
problems that are related to executing functions.
|
problems that are related to executing functions. In addition, you
|
||||||
|
can load the data files generated by Callgrind into the
|
||||||
|
\l{https://kcachegrind.github.io/html/Home.html}{KCachegrind}
|
||||||
|
profile data visualization tool for browsing the performance results.
|
||||||
|
|
||||||
After you download and install Valgrind tools, you can use Callgrind from
|
After you download and install Valgrind tools and KCachegrind, you can use
|
||||||
\QC.
|
Callgrind and KCachegrind from \QC.
|
||||||
|
|
||||||
\note You can install and run Callgrind locally on Linux. You can run
|
\note You can install and run Callgrind and KCachegrind locally on Linux.
|
||||||
it on a remote Linux machine or device from any development machine.
|
You can run Callgrind on a remote Linux machine or device from any
|
||||||
|
development machine.
|
||||||
|
|
||||||
To analyze applications:
|
To analyze applications:
|
||||||
|
|
||||||
@@ -207,6 +211,10 @@
|
|||||||
|
|
||||||
\image qtcreator-valgrind-callgrind.png "Profile view"
|
\image qtcreator-valgrind-callgrind.png "Profile view"
|
||||||
|
|
||||||
|
To view the data in KCachegrind, select the \inlineimage kcachegrind.png
|
||||||
|
(\uicontrol {Open Results in KCachegrind}) button on the toolbar. \QC
|
||||||
|
launches KCachegrind and loads the data into it for visualization.
|
||||||
|
|
||||||
\section1 Selecting Profiling Options
|
\section1 Selecting Profiling Options
|
||||||
|
|
||||||
You can specify analyzer settings either globally for all projects or
|
You can specify analyzer settings either globally for all projects or
|
||||||
@@ -218,6 +226,9 @@
|
|||||||
|
|
||||||
\image qtcreator-valgrind-callgrind-options.png "Valgrind options"
|
\image qtcreator-valgrind-callgrind-options.png "Valgrind options"
|
||||||
|
|
||||||
|
In the \uicontrol {KCachegrind executable} field, enter the path to the
|
||||||
|
KCachegrind executable to launch.
|
||||||
|
|
||||||
In the \uicontrol {Result view: Minimum event cost}
|
In the \uicontrol {Result view: Minimum event cost}
|
||||||
field, limit the amount of results the profiler gives you to increase
|
field, limit the amount of results the profiler gives you to increase
|
||||||
profiler performance.
|
profiler performance.
|
||||||
|
|||||||
@@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
\section2 Automatic Formatting and Indentation
|
\section2 Automatic Formatting and Indentation
|
||||||
|
|
||||||
The experimental Clang Format plugin uses the
|
The Clang Format plugin uses the
|
||||||
\l{https://clang.llvm.org/docs/LibFormat.html}{LibFormat}
|
\l{https://clang.llvm.org/docs/LibFormat.html}{LibFormat}
|
||||||
library for automatic formatting and indentation.
|
library for automatic formatting and indentation.
|
||||||
|
|
||||||
|
|||||||
@@ -112,7 +112,7 @@
|
|||||||
|
|
||||||
\list
|
\list
|
||||||
\li Clang code model (globally or at project level)
|
\li Clang code model (globally or at project level)
|
||||||
\li Clang tools (globally or at project level)
|
\li \l{Using Clang Tools}{Clang tools} (globally or at project level)
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
\section1 Configuring Clang Code Model
|
\section1 Configuring Clang Code Model
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
** Copyright (C) 2019 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -97,6 +97,6 @@
|
|||||||
retrieve the code snippet by selecting \uicontrol Tools >
|
retrieve the code snippet by selecting \uicontrol Tools >
|
||||||
\uicontrol {Code Pasting} > \uicontrol {Fetch Snippet}. If they have the
|
\uicontrol {Code Pasting} > \uicontrol {Fetch Snippet}. If they have the
|
||||||
project currently opened in \QC, they can apply and test the change by
|
project currently opened in \QC, they can apply and test the change by
|
||||||
choosing \uicontrol Tools > \uicontrol Git > \uicontrol {Patch} >
|
choosing \uicontrol Tools > \uicontrol Git > \uicontrol {Local Repository}
|
||||||
\uicontrol {Apply from Editor}.
|
> \uicontrol Patch > \uicontrol {Apply from Editor}.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -145,6 +145,9 @@
|
|||||||
\li To hide source files which are automatically generated by the build
|
\li To hide source files which are automatically generated by the build
|
||||||
system, select \uicontrol {Filter Tree > Hide Generated Files}.
|
system, select \uicontrol {Filter Tree > Hide Generated Files}.
|
||||||
|
|
||||||
|
\li To hide directories that do not contain any files, select
|
||||||
|
\uicontrol {Filter Tree} > \uicontrol {Hide Empty Directories}.
|
||||||
|
|
||||||
\li To stop synchronizing the position in the project tree with the file
|
\li To stop synchronizing the position in the project tree with the file
|
||||||
currently opened in the editor, deselect \inlineimage linkicon.png
|
currently opened in the editor, deselect \inlineimage linkicon.png
|
||||||
(\uicontrol {Synchronize with Editor}). You can specify a keyboard
|
(\uicontrol {Synchronize with Editor}). You can specify a keyboard
|
||||||
@@ -190,7 +193,8 @@
|
|||||||
|
|
||||||
For managing files and directories, the same functions are available as in
|
For managing files and directories, the same functions are available as in
|
||||||
the \uicontrol {File System} view. In addition, you can remove and rename
|
the \uicontrol {File System} view. In addition, you can remove and rename
|
||||||
files.
|
files, as well as compare the selected file with the currently open file
|
||||||
|
in the diff editor. For more information, see \l{Comparing Files}.
|
||||||
|
|
||||||
//! [projects view]
|
//! [projects view]
|
||||||
|
|
||||||
|
|||||||
@@ -124,10 +124,11 @@
|
|||||||
|
|
||||||
For more information, see \l{Defining Color Schemes}.
|
For more information, see \l{Defining Color Schemes}.
|
||||||
|
|
||||||
Generic highlighting is based on highlight definition files that are
|
Generic highlighting is provided by
|
||||||
provided by the
|
\l{https://api.kde.org/frameworks/syntax-highlighting/html/index.html}
|
||||||
\l{http://kate-editor.org/2005/03/24/writing-a-syntax-highlighting-file/}
|
{KSyntaxHighlighting}, which is the syntax highlighting engine for Kate
|
||||||
{Kate Editor}. You can download highlight definition files for use with \QC.
|
syntax definitions. \QC comes with most of the commonly used syntax files,
|
||||||
|
and you can download additional files.
|
||||||
|
|
||||||
To download and use highlight definition files, select \uicontrol Tools >
|
To download and use highlight definition files, select \uicontrol Tools >
|
||||||
\uicontrol Options > \uicontrol {Text Editor} > \uicontrol {Generic Highlighter}.
|
\uicontrol Options > \uicontrol {Text Editor} > \uicontrol {Generic Highlighter}.
|
||||||
|
|||||||
@@ -79,6 +79,10 @@
|
|||||||
languages as code, not just as plain text. This enables it to
|
languages as code, not just as plain text. This enables it to
|
||||||
provide you with useful features, such as semantic highlighting,
|
provide you with useful features, such as semantic highlighting,
|
||||||
checking code syntax, code completion, and refactoring actions.
|
checking code syntax, code completion, and refactoring actions.
|
||||||
|
In addition, the experimental language server plugin provides
|
||||||
|
some of these services for other programming languages, such as
|
||||||
|
Python, for which a \e {language server} is available that
|
||||||
|
provides information about the code to IDEs.
|
||||||
For more information, see \l{Coding}.
|
For more information, see \l{Coding}.
|
||||||
\row
|
\row
|
||||||
\li \inlineimage creator_buildingrunning.png
|
\li \inlineimage creator_buildingrunning.png
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
** Copyright (C) 2019 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -101,7 +101,7 @@
|
|||||||
|
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
\li \macos 10.11 or later with the following:
|
\li \macos 10.12 or later with the following:
|
||||||
|
|
||||||
\list
|
\list
|
||||||
|
|
||||||
@@ -117,9 +117,9 @@
|
|||||||
Either Windows 7 or later or Ubuntu Linux 64-bit 12.04 LTS or later is
|
Either Windows 7 or later or Ubuntu Linux 64-bit 12.04 LTS or later is
|
||||||
required to install and use Qt for Device Creation. For more information
|
required to install and use Qt for Device Creation. For more information
|
||||||
about the requirements for the development host, see the
|
about the requirements for the development host, see the
|
||||||
\l{http://doc.qt.io/QtForDeviceCreation/qtee-installation-guide.html}
|
\l{https://doc.qt.io/QtForDeviceCreation/b2qt-installation-guides.html}
|
||||||
{Installation Guide} in the
|
{Installation Guides} in the
|
||||||
\l{http://doc.qt.io/QtForDeviceCreation/index.html}{Qt for Device Creation}
|
\l{https://doc.qt.io/QtForDeviceCreation/index.html}{Qt for Device Creation}
|
||||||
documentation.
|
documentation.
|
||||||
|
|
||||||
\section1 Compiling from Source
|
\section1 Compiling from Source
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2017 The Qt Company Ltd.
|
** Copyright (C) 2019 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -56,9 +56,13 @@
|
|||||||
hardware.
|
hardware.
|
||||||
|
|
||||||
For more information about the supported device groups and reference devices,
|
For more information about the supported device groups and reference devices,
|
||||||
see \l{http://doc.qt.io/QtForDeviceCreation/qtee-supported-platforms.html}
|
see \l{https://doc.qt.io/QtForDeviceCreation/qtee-supported-platforms.html}
|
||||||
{Supported Platforms} in the \l{http://doc.qt.io/QtForDeviceCreation/index.html}
|
{Reference Target Devices and Development Hosts} in the
|
||||||
{Qt for Device Creation} documentation.
|
\l{https://doc.qt.io/QtForDeviceCreation/index.html}{Qt for Device Creation}
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
\note Since \QC 4.9, only Boot to Qt version 5.9 and later are supported.
|
||||||
|
To develop for earlier Boot to Qt versions, use \QC 4.8.
|
||||||
|
|
||||||
\section2 Mobile Devices
|
\section2 Mobile Devices
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,10 @@
|
|||||||
\li Clang is a C, C++, Objective C, and Objective C++ front-end for the
|
\li Clang is a C, C++, Objective C, and Objective C++ front-end for the
|
||||||
LLVM compiler for Windows, Linux, and \macos.
|
LLVM compiler for Windows, Linux, and \macos.
|
||||||
|
|
||||||
|
\li \l{https://clang.llvm.org/docs/UsersManual.html#clang-cl}{clang-cl}
|
||||||
|
is an alternative command-line interface to Clang that is compatible
|
||||||
|
with the Visual C++ compiler, \c cl.exe.
|
||||||
|
|
||||||
\li Nim is the Nim Compiler for Windows, Linux, and \macos.
|
\li Nim is the Nim Compiler for Windows, Linux, and \macos.
|
||||||
|
|
||||||
\li QCC is the interface for compiling C++ applications for QNX.
|
\li QCC is the interface for compiling C++ applications for QNX.
|
||||||
@@ -76,6 +80,12 @@
|
|||||||
versions. You can also create a custom ABI definition.
|
versions. You can also create a custom ABI definition.
|
||||||
For QCC, also specify the path to the QNX Software Development Platform (SDP).
|
For QCC, also specify the path to the QNX Software Development Platform (SDP).
|
||||||
|
|
||||||
|
To enable Microsoft Visual C++ Compilers (MSVC) and clang-cl to find system
|
||||||
|
headers, libraries, and the linker, \QC executes them inside a command
|
||||||
|
prompt where the environment has been set up using \c {vcvarsall.bat}. For
|
||||||
|
these compilers, you also specify the path to the script that sets up the
|
||||||
|
command prompt.
|
||||||
|
|
||||||
You specify the compiler to use for each kit in \uicontrol Tools >
|
You specify the compiler to use for each kit in \uicontrol Tools >
|
||||||
\uicontrol Options > \uicontrol Kits.
|
\uicontrol Options > \uicontrol Kits.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
** Copyright (C) 2019 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -86,4 +86,8 @@
|
|||||||
the shell or the device. Usually, you can leave this field empty.
|
the shell or the device. Usually, you can leave this field empty.
|
||||||
|
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
|
To remove the selected manually added debugger, select \uicontrol Remove.
|
||||||
|
The debugger is removed from the list when you select \uicontrol Apply.
|
||||||
|
Until then, you can cancel the deletion by clicking \uicontrol Restore.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
** Copyright (C) 2019 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -58,6 +58,10 @@
|
|||||||
select the \uicontrol Options link, or select \uicontrol Tools >
|
select the \uicontrol Options link, or select \uicontrol Tools >
|
||||||
\uicontrol Options > \uicontrol Kits.
|
\uicontrol Options > \uicontrol Kits.
|
||||||
|
|
||||||
|
Qt for Python projects rely on the \l{Using Language Servers}
|
||||||
|
{experimental language server client} for code completion,
|
||||||
|
highlighting, and other useful features.
|
||||||
|
|
||||||
If \QC cannot find an existing build for a particular \l{glossary-buildandrun-kit}{kit},
|
If \QC cannot find an existing build for a particular \l{glossary-buildandrun-kit}{kit},
|
||||||
it starts out
|
it starts out
|
||||||
from a clean slate, and creates new debug and release build configurations
|
from a clean slate, and creates new debug and release build configurations
|
||||||
@@ -79,8 +83,8 @@
|
|||||||
\li Select \uicontrol File > \uicontrol {Open File or Project}
|
\li Select \uicontrol File > \uicontrol {Open File or Project}
|
||||||
(\key Ctrl+O or \key Cmd+O on \macos) and select the project file
|
(\key Ctrl+O or \key Cmd+O on \macos) and select the project file
|
||||||
for the project to open: \e {.pro} (qmake), \e {CMakeLists.txt}
|
for the project to open: \e {.pro} (qmake), \e {CMakeLists.txt}
|
||||||
(CMake), \e {.qbs} (Qbs), or \e {Makefile.am} (Autotools,
|
(CMake), \e {.qbs} (Qbs), \e {pyproject} (Python), or
|
||||||
experimental).
|
\e {Makefile.am} (Autotools, experimental).
|
||||||
|
|
||||||
\li In the \uicontrol {Configure Project} tab, select kits for building and running your
|
\li In the \uicontrol {Configure Project} tab, select kits for building and running your
|
||||||
project, and click \uicontrol {Configure Project}.
|
project, and click \uicontrol {Configure Project}.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
** Copyright (C) 2019 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -48,6 +48,16 @@
|
|||||||
switch between them. In addition, you can import and export code style
|
switch between them. In addition, you can import and export code style
|
||||||
settings.
|
settings.
|
||||||
|
|
||||||
|
\image qtcreator-projects-code-style.png "Code Style settings in Projects mode"
|
||||||
|
|
||||||
|
Alternatively, you can enable the Clang Format plugin to enforce
|
||||||
|
the code style specified in a \c {.clang-format} file. It uses the
|
||||||
|
\l{https://clang.llvm.org/docs/LibFormat.html}{LibFormat} library for
|
||||||
|
automatic code formatting and indentation. For more information, see
|
||||||
|
\l {Automatic Formatting and Indentation}.
|
||||||
|
|
||||||
|
\image qtcreator-code-style-clang-format.png "Clang Format Code Style settings in Projects mode"
|
||||||
|
|
||||||
To specify global code style settings sets for C++ files, select
|
To specify global code style settings sets for C++ files, select
|
||||||
\uicontrol {Tools > Options > C++}.
|
\uicontrol {Tools > Options > C++}.
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
** Copyright (C) 2019 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -117,4 +117,6 @@
|
|||||||
\image qmldesigner-run-custom-exe.png "Run settings for custom executables"
|
\image qmldesigner-run-custom-exe.png "Run settings for custom executables"
|
||||||
|
|
||||||
\include qtquick/creator-projects-settings-run-qtquick.qdocinc run settings qt quick ui
|
\include qtquick/creator-projects-settings-run-qtquick.qdocinc run settings qt quick ui
|
||||||
|
\include python/creator-python-run.qdocinc run settings python
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
** Copyright (C) 2019 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -53,6 +53,10 @@
|
|||||||
|
|
||||||
\li Bare Metal Device
|
\li Bare Metal Device
|
||||||
|
|
||||||
|
\li Boot2Qt Device (commercial only)
|
||||||
|
|
||||||
|
\li \l {Emulator}{Boot2Qt Emulator Device} (commercial only)
|
||||||
|
|
||||||
\li Generic Linux Device
|
\li Generic Linux Device
|
||||||
|
|
||||||
\li iOS Device
|
\li iOS Device
|
||||||
@@ -61,6 +65,12 @@
|
|||||||
|
|
||||||
\li QNX Device
|
\li QNX Device
|
||||||
|
|
||||||
|
\li Windows Phone
|
||||||
|
|
||||||
|
\li Windows Phone Emulator
|
||||||
|
|
||||||
|
\li Windows Runtime (local)
|
||||||
|
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
To add kits:
|
To add kits:
|
||||||
@@ -95,6 +105,9 @@
|
|||||||
|
|
||||||
\li In the \uicontrol Device field, select a device.
|
\li In the \uicontrol Device field, select a device.
|
||||||
|
|
||||||
|
\li In the \uicontrol {Emulator skin} field, select the skin to use for
|
||||||
|
the \l {Emulator}{Boot2Qt Emulator Device}.
|
||||||
|
|
||||||
\li In the \uicontrol Sysroot field, specify the directory where the device
|
\li In the \uicontrol Sysroot field, specify the directory where the device
|
||||||
image is located. If you are not cross-compiling, leave this field
|
image is located. If you are not cross-compiling, leave this field
|
||||||
empty.
|
empty.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
** Copyright (C) 2019 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -85,5 +85,6 @@
|
|||||||
|
|
||||||
\if defined(qtcreator)
|
\if defined(qtcreator)
|
||||||
\include qnx/creator-projects-running-qnx.qdocinc running on qnx
|
\include qnx/creator-projects-running-qnx.qdocinc running on qnx
|
||||||
|
\include python/creator-python-run.qdocinc running python
|
||||||
\endif
|
\endif
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2019 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
|
||||||
|
** 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 Free Documentation License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU Free
|
||||||
|
** Documentation License version 1.3 as published by the Free Software
|
||||||
|
** Foundation and appearing in the file included in the packaging of
|
||||||
|
** this file. Please review the following information to ensure
|
||||||
|
** the GNU Free Documentation License version 1.3 requirements
|
||||||
|
** will be met: https://www.gnu.org/licenses/fdl-1.3.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
//! [running python]
|
||||||
|
\section1 Running Python Projects
|
||||||
|
|
||||||
|
You can execute Qt for Python applications directly from \QC. If you
|
||||||
|
used the \l{Creating Qt for Python Applications}{new project wizard}
|
||||||
|
to create the application project, the \c main.py file is automatically
|
||||||
|
executed when you select the \uicontrol Run button.
|
||||||
|
|
||||||
|
You can specify another file to execute in the
|
||||||
|
\l{Specifying Run Settings for Python Projects}{run settings}
|
||||||
|
of the project.
|
||||||
|
|
||||||
|
//! [running python]
|
||||||
|
|
||||||
|
|
||||||
|
//! [run settings python]
|
||||||
|
|
||||||
|
\section1 Specifying Run Settings for Python Projects
|
||||||
|
|
||||||
|
You can specify settings for running Qt for Python applications:
|
||||||
|
|
||||||
|
\image qtcreator-python-run-settings.png
|
||||||
|
|
||||||
|
\list
|
||||||
|
\li In the \uicontrol Interpreter field, specify the path to the
|
||||||
|
Python executable.
|
||||||
|
\li In the \uicontrol Script field, you can see the path to the
|
||||||
|
main file of the project that will be run.
|
||||||
|
\li In the \uicontrol {Command line arguments} field, specify
|
||||||
|
command line arguments to be passed to the executable.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
If you want to run some other Python file than \c main.py, create a custom
|
||||||
|
executable run configuration:
|
||||||
|
|
||||||
|
\image qtcreator-python-run-settings-custom-executable.png
|
||||||
|
|
||||||
|
\list 1
|
||||||
|
\li Select \uicontrol Add > \uicontrol {Custom Executable}.
|
||||||
|
\li In the \uicontrol Executable field, specify the path to the
|
||||||
|
Python executable.
|
||||||
|
\li In the \uicontrol {Command line arguments} field, select
|
||||||
|
the Python file to run.
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
//! [run settings python]
|
||||||
|
*/
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
** Copyright (C) 2019 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -212,6 +212,11 @@
|
|||||||
|
|
||||||
To zoom into an event range, double-click it.
|
To zoom into an event range, double-click it.
|
||||||
|
|
||||||
|
To narrow down the current range in the \uicontrol Timeline,
|
||||||
|
\uicontrol Statistics, and \uicontrol {Flame Graph} views, right-click
|
||||||
|
the range and select \uicontrol {Analyze Current Range}. To return to
|
||||||
|
the full range, select \uicontrol {Analyze Full Range} in the context menu.
|
||||||
|
|
||||||
To remove an event range, close the \uicontrol Selection dialog.
|
To remove an event range, close the \uicontrol Selection dialog.
|
||||||
|
|
||||||
\section2 Understanding the Data
|
\section2 Understanding the Data
|
||||||
@@ -556,10 +561,9 @@
|
|||||||
|
|
||||||
Click on an event to move to it in the source code in the code editor.
|
Click on an event to move to it in the source code in the code editor.
|
||||||
|
|
||||||
When you select an event in the \uicontrol Timeline view, information about it is
|
When you select an event in the \uicontrol Timeline view, information about
|
||||||
displayed in the \uicontrol Statistics view. To view an event range in the
|
it is displayed in the \uicontrol Statistics and \uicontrol {Flame Graph}
|
||||||
\uicontrol Statistics view, select \uicontrol {Analyze Current Range}
|
views.
|
||||||
in the context menu in the \uicontrol Timeline view.
|
|
||||||
|
|
||||||
To copy the contents of one view or row to the clipboard, select
|
To copy the contents of one view or row to the clipboard, select
|
||||||
\uicontrol {Copy Table} or \uicontrol {Copy Row} in the context menu.
|
\uicontrol {Copy Table} or \uicontrol {Copy Row} in the context menu.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
**
|
**
|
||||||
** Copyright (C) 2018 The Qt Company Ltd.
|
** Copyright (C) 2019 The Qt Company Ltd.
|
||||||
** Contact: https://www.qt.io/licensing/
|
** Contact: https://www.qt.io/licensing/
|
||||||
**
|
**
|
||||||
** This file is part of the Qt Creator documentation.
|
** This file is part of the Qt Creator documentation.
|
||||||
@@ -41,9 +41,16 @@
|
|||||||
|
|
||||||
In addition to the standard version control system functions described in
|
In addition to the standard version control system functions described in
|
||||||
\l {Using Common Functions}, you can select \uicontrol Tools >
|
\l {Using Common Functions}, you can select \uicontrol Tools >
|
||||||
\uicontrol CVS > \uicontrol Edit to open a file for editing.
|
\uicontrol CVS > \uicontrol Edit to set a file as writable, notify
|
||||||
|
watchers that the file is being edited, and watch for actions performed
|
||||||
|
on the file by other users.
|
||||||
|
|
||||||
To discard the changes that you made in a file, select \uicontrol Unedit.
|
To discard the changes that you made in a file, notify watchers that
|
||||||
|
the file is no longer being edited, and set the file as read-only,
|
||||||
|
select \uicontrol Unedit.
|
||||||
|
|
||||||
|
To unedit files in the local directory, as well as recursively in all
|
||||||
|
subdirectories, select \uicontrol {Unedit Repository}.
|
||||||
|
|
||||||
To specify the CVS root directory, select \uicontrol Tools >
|
To specify the CVS root directory, select \uicontrol Tools >
|
||||||
\uicontrol Options > \uicontrol {Version Control} > \uicontrol CVS, and then
|
\uicontrol Options > \uicontrol {Version Control} > \uicontrol CVS, and then
|
||||||
|
|||||||
@@ -72,6 +72,11 @@
|
|||||||
\li \l{Using Perforce}{Perforce}
|
\li \l{Using Perforce}{Perforce}
|
||||||
\li \l{http://www.perforce.com}
|
\li \l{http://www.perforce.com}
|
||||||
\li Server version 2006.1 and later
|
\li Server version 2006.1 and later
|
||||||
|
|
||||||
|
Disabled by default. To enable the plugin, select
|
||||||
|
\uicontrol Help > \uicontrol {About Plugins} >
|
||||||
|
\uicontrol {Version Control} > \uicontrol Perforce,
|
||||||
|
and then restart \QC.
|
||||||
\row
|
\row
|
||||||
\li \l{Using Subversion}{Subversion}
|
\li \l{Using Subversion}{Subversion}
|
||||||
\li \l{http://subversion.apache.org/}
|
\li \l{http://subversion.apache.org/}
|
||||||
|
|||||||
@@ -50,7 +50,7 @@
|
|||||||
"QtCharts 2.3",
|
"QtCharts 2.3",
|
||||||
"QtDataVisualization 1.0",
|
"QtDataVisualization 1.0",
|
||||||
"QtDataVisualization 1.3",
|
"QtDataVisualization 1.3",
|
||||||
"QtGamePad 1.12",
|
"QtGamepad 1.12",
|
||||||
"QtGraphicalEffects 1.0",
|
"QtGraphicalEffects 1.0",
|
||||||
"QtMultimedia 5.0",
|
"QtMultimedia 5.0",
|
||||||
"QtMultimedia 5.2",
|
"QtMultimedia 5.2",
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 271 B After Width: | Height: | Size: 165 B |
|
Before Width: | Height: | Size: 490 B After Width: | Height: | Size: 311 B |
@@ -80,7 +80,6 @@
|
|||||||
"name": "QtVersion",
|
"name": "QtVersion",
|
||||||
"trDisplayName": "Minimal required Qt version:",
|
"trDisplayName": "Minimal required Qt version:",
|
||||||
"type": "ComboBox",
|
"type": "ComboBox",
|
||||||
"visible": false,
|
|
||||||
"data":
|
"data":
|
||||||
{
|
{
|
||||||
"index": 1,
|
"index": 1,
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ DoubleTabWidget2ndTabInactiveTextColor=ff000000
|
|||||||
EditorPlaceholderColor=ffe0dcd8
|
EditorPlaceholderColor=ffe0dcd8
|
||||||
FancyToolBarSeparatorColor=60ffffff
|
FancyToolBarSeparatorColor=60ffffff
|
||||||
FancyTabBarBackgroundColor=ffff0000
|
FancyTabBarBackgroundColor=ffff0000
|
||||||
|
FancyTabBarSelectedBackgroundColor=ffff0000
|
||||||
FancyTabWidgetDisabledSelectedTextColor=textDisabled
|
FancyTabWidgetDisabledSelectedTextColor=textDisabled
|
||||||
FancyTabWidgetDisabledUnselectedTextColor=textDisabled
|
FancyTabWidgetDisabledUnselectedTextColor=textDisabled
|
||||||
FancyTabWidgetEnabledSelectedTextColor=ff3c3c3c
|
FancyTabWidgetEnabledSelectedTextColor=ff3c3c3c
|
||||||
|
|||||||
@@ -18536,11 +18536,11 @@ Gibt an, wie sich die Rücktaste bezüglich Einrückung verhält.
|
|||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Show help tooltips using keyboard shortcut (Alt)</source>
|
<source>Show help tooltips using keyboard shortcut (Alt)</source>
|
||||||
<translation>Zeige Tooltips mit Hilfe unter Verwendung des Tastaturkürzels (Alt-Taste)</translation>
|
<translation>Hilfe-Tooltips mit der Tastatur aufrufen (Alt-Taste)</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Show help tooltips using the mouse:</source>
|
<source>Show help tooltips using the mouse:</source>
|
||||||
<translation>Zeige Tooltips mit Hilfe unter Verwendung der Maus:</translation>
|
<translation>Hilfe-Tooltips mit der Maus aufrufen:</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Cleans whitespace in entire document instead of only for changed parts.</source>
|
<source>Cleans whitespace in entire document instead of only for changed parts.</source>
|
||||||
|
|||||||
@@ -921,12 +921,11 @@ protected:
|
|||||||
|
|
||||||
bool visit(PatternElement *ast) override
|
bool visit(PatternElement *ast) override
|
||||||
{
|
{
|
||||||
if (!ast->isVariableDeclaration())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
out(ast->identifierToken);
|
out(ast->identifierToken);
|
||||||
if (ast->initializer) {
|
if (ast->initializer) {
|
||||||
out(" = ");
|
if (ast->isVariableDeclaration())
|
||||||
|
out(" = ");
|
||||||
accept(ast->initializer);
|
accept(ast->initializer);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ void TypeDescriptionReader::readComponent(UiObjectDefinition *ast)
|
|||||||
} else if (name == QLatin1String("exports")) {
|
} else if (name == QLatin1String("exports")) {
|
||||||
readExports(script, fmo);
|
readExports(script, fmo);
|
||||||
} else if (name == QLatin1String("exportMetaObjectRevisions")) {
|
} else if (name == QLatin1String("exportMetaObjectRevisions")) {
|
||||||
//readMetaObjectRevisions(script, fmo);
|
readMetaObjectRevisions(script, fmo);
|
||||||
} else if (name == QLatin1String("attachedType")) {
|
} else if (name == QLatin1String("attachedType")) {
|
||||||
fmo->setAttachedTypeName(readStringBinding(script));
|
fmo->setAttachedTypeName(readStringBinding(script));
|
||||||
} else if (name == QLatin1String("isSingleton")) {
|
} else if (name == QLatin1String("isSingleton")) {
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "progressindicator.h"
|
#include "progressindicator.h"
|
||||||
#include "treemodel.h"
|
#include "treemodel.h"
|
||||||
|
|
||||||
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@@ -39,6 +40,7 @@
|
|||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <QSortFilterProxyModel>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
@@ -596,11 +598,23 @@ ItemViewEvent::ItemViewEvent(QEvent *ev, QAbstractItemView *view)
|
|||||||
m_selectedRows.append(current);
|
m_selectedRows.append(current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto fixIndex = [view](QModelIndex idx) {
|
||||||
|
QAbstractItemModel *model = view->model();
|
||||||
|
while (auto proxy = qobject_cast<QSortFilterProxyModel *>(model)) {
|
||||||
|
idx = proxy->mapToSource(idx);
|
||||||
|
model = proxy->sourceModel();
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
};
|
||||||
|
|
||||||
|
m_sourceModelIndex = fixIndex(m_index);
|
||||||
|
m_selectedRows = Utils::transform(m_selectedRows, fixIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndexList ItemViewEvent::currentOrSelectedRows() const
|
QModelIndexList ItemViewEvent::currentOrSelectedRows() const
|
||||||
{
|
{
|
||||||
return m_selectedRows.isEmpty() ? QModelIndexList() << m_index : m_selectedRows;
|
return m_selectedRows.isEmpty() ? QModelIndexList() << m_sourceModelIndex : m_selectedRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ public:
|
|||||||
QPoint pos() const { return m_pos; }
|
QPoint pos() const { return m_pos; }
|
||||||
QPoint globalPos() const { return m_view->mapToGlobal(m_pos); }
|
QPoint globalPos() const { return m_view->mapToGlobal(m_pos); }
|
||||||
QModelIndex index() const { return m_index; }
|
QModelIndex index() const { return m_index; }
|
||||||
|
QModelIndex sourceModelIndex() const { return m_sourceModelIndex; }
|
||||||
QModelIndexList selectedRows() const { return m_selectedRows; }
|
QModelIndexList selectedRows() const { return m_selectedRows; }
|
||||||
QModelIndexList currentOrSelectedRows() const;
|
QModelIndexList currentOrSelectedRows() const;
|
||||||
|
|
||||||
@@ -143,6 +144,7 @@ private:
|
|||||||
QWidget *m_view = nullptr;
|
QWidget *m_view = nullptr;
|
||||||
QPoint m_pos;
|
QPoint m_pos;
|
||||||
QModelIndex m_index;
|
QModelIndex m_index;
|
||||||
|
QModelIndex m_sourceModelIndex;
|
||||||
QModelIndexList m_selectedRows;
|
QModelIndexList m_selectedRows;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -523,6 +523,21 @@ bool FancyMainWindow::autoHideTitleBars() const
|
|||||||
return d->m_autoHideTitleBars.isChecked();
|
return d->m_autoHideTitleBars.isChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FancyMainWindow::setAutoHideTitleBars(bool on)
|
||||||
|
{
|
||||||
|
d->m_autoHideTitleBars.setChecked(on);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FancyMainWindow::isCentralWidgetShown() const
|
||||||
|
{
|
||||||
|
return d->m_showCentralWidget.isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FancyMainWindow::showCentralWidget(bool on)
|
||||||
|
{
|
||||||
|
d->m_showCentralWidget.setChecked(on);
|
||||||
|
}
|
||||||
|
|
||||||
void FancyMainWindow::addDockActionsToMenu(QMenu *menu)
|
void FancyMainWindow::addDockActionsToMenu(QMenu *menu)
|
||||||
{
|
{
|
||||||
QList<QAction *> actions;
|
QList<QAction *> actions;
|
||||||
|
|||||||
@@ -66,6 +66,10 @@ public:
|
|||||||
void addDockActionsToMenu(QMenu *menu);
|
void addDockActionsToMenu(QMenu *menu);
|
||||||
|
|
||||||
bool autoHideTitleBars() const;
|
bool autoHideTitleBars() const;
|
||||||
|
void setAutoHideTitleBars(bool on);
|
||||||
|
|
||||||
|
bool isCentralWidgetShown() const;
|
||||||
|
void showCentralWidget(bool on);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// Emitted by resetLayoutAction(). Connect to a slot
|
// Emitted by resetLayoutAction(). Connect to a slot
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ void GTestOutputReader::processOutputLine(const QByteArray &outputLineWithNewLin
|
|||||||
m_description = line;
|
m_description = line;
|
||||||
if (m_iteration > 1)
|
if (m_iteration > 1)
|
||||||
m_description.append(' ' + tr("(iteration %1)").arg(m_iteration));
|
m_description.append(' ' + tr("(iteration %1)").arg(m_iteration));
|
||||||
TestResultPtr testResult = TestResultPtr(new GTestResult(m_projectFile));
|
TestResultPtr testResult = TestResultPtr(new GTestResult(id(), m_projectFile, QString()));
|
||||||
testResult->setResult(Result::MessageInternal);
|
testResult->setResult(Result::MessageInternal);
|
||||||
testResult->setDescription(m_description);
|
testResult->setDescription(m_description);
|
||||||
reportResult(testResult);
|
reportResult(testResult);
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ bool GTestResult::isDirectParentOf(const TestResult *other, bool *needsIntermedi
|
|||||||
if (m_testSetName == gtOther->m_testSetName) {
|
if (m_testSetName == gtOther->m_testSetName) {
|
||||||
const Result::Type otherResult = other->result();
|
const Result::Type otherResult = other->result();
|
||||||
if (otherResult == Result::MessageInternal || otherResult == Result::MessageLocation)
|
if (otherResult == Result::MessageInternal || otherResult == Result::MessageLocation)
|
||||||
return result() != Result::MessageLocation;
|
return result() != Result::MessageInternal && result() != Result::MessageLocation;
|
||||||
}
|
}
|
||||||
if (m_iteration != gtOther->m_iteration)
|
if (m_iteration != gtOther->m_iteration)
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ void adjustFormatStyleForLineBreak(clang::format::FormatStyle &style,
|
|||||||
|
|
||||||
// This is a separate pass, don't do it unless it's the full formatting.
|
// This is a separate pass, don't do it unless it's the full formatting.
|
||||||
style.FixNamespaceComments = false;
|
style.FixNamespaceComments = false;
|
||||||
|
style.AlignTrailingComments = false;
|
||||||
|
|
||||||
if (replacementsToKeep == ReplacementsToKeep::IndentAndBefore)
|
if (replacementsToKeep == ReplacementsToKeep::IndentAndBefore)
|
||||||
return;
|
return;
|
||||||
@@ -118,13 +119,11 @@ void trimRHSWhitespace(const QTextBlock &block)
|
|||||||
const int extraSpaceCount = static_cast<int>(std::distance(initialText.rbegin(), lastNonSpace));
|
const int extraSpaceCount = static_cast<int>(std::distance(initialText.rbegin(), lastNonSpace));
|
||||||
|
|
||||||
QTextCursor cursor(block);
|
QTextCursor cursor(block);
|
||||||
cursor.beginEditBlock();
|
|
||||||
cursor.movePosition(QTextCursor::Right,
|
cursor.movePosition(QTextCursor::Right,
|
||||||
QTextCursor::MoveAnchor,
|
QTextCursor::MoveAnchor,
|
||||||
initialText.size() - extraSpaceCount);
|
initialText.size() - extraSpaceCount);
|
||||||
cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, extraSpaceCount);
|
cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, extraSpaceCount);
|
||||||
cursor.removeSelectedText();
|
cursor.removeSelectedText();
|
||||||
cursor.endEditBlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextBlock reverseFindLastEmptyBlock(QTextBlock start)
|
QTextBlock reverseFindLastEmptyBlock(QTextBlock start)
|
||||||
@@ -139,7 +138,13 @@ QTextBlock reverseFindLastEmptyBlock(QTextBlock start)
|
|||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class CharacterContext { AfterComma, LastAfterComma, NewStatement, Continuation, Unknown };
|
enum class CharacterContext {
|
||||||
|
AfterComma,
|
||||||
|
LastAfterComma,
|
||||||
|
NewStatementOrContinuation,
|
||||||
|
IfOrElseWithoutScope,
|
||||||
|
Unknown
|
||||||
|
};
|
||||||
|
|
||||||
QChar findFirstNonWhitespaceCharacter(const QTextBlock ¤tBlock)
|
QChar findFirstNonWhitespaceCharacter(const QTextBlock ¤tBlock)
|
||||||
{
|
{
|
||||||
@@ -150,10 +155,42 @@ QChar findFirstNonWhitespaceCharacter(const QTextBlock ¤tBlock)
|
|||||||
return currentPos < doc->characterCount() ? doc->characterAt(currentPos) : QChar::Null;
|
return currentPos < doc->characterCount() ? doc->characterAt(currentPos) : QChar::Null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int findMatchingOpeningParen(const QTextBlock &blockEndingWithClosingParen)
|
||||||
|
{
|
||||||
|
const QTextDocument *doc = blockEndingWithClosingParen.document();
|
||||||
|
int currentPos = blockEndingWithClosingParen.position()
|
||||||
|
+ blockEndingWithClosingParen.text().lastIndexOf(')');
|
||||||
|
int parenBalance = 1;
|
||||||
|
|
||||||
|
while (currentPos > 0 && parenBalance > 0) {
|
||||||
|
--currentPos;
|
||||||
|
if (doc->characterAt(currentPos) == ')')
|
||||||
|
++parenBalance;
|
||||||
|
if (doc->characterAt(currentPos) == '(')
|
||||||
|
--parenBalance;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parenBalance == 0)
|
||||||
|
return currentPos;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool comesDirectlyAfterIf(const QTextDocument *doc, int pos)
|
||||||
|
{
|
||||||
|
--pos;
|
||||||
|
while (pos > 0 && doc->characterAt(pos).isSpace())
|
||||||
|
--pos;
|
||||||
|
return pos > 0 && doc->characterAt(pos) == 'f' && doc->characterAt(pos - 1) == 'i';
|
||||||
|
}
|
||||||
|
|
||||||
CharacterContext characterContext(const QTextBlock ¤tBlock,
|
CharacterContext characterContext(const QTextBlock ¤tBlock,
|
||||||
const QTextBlock &previousNonEmptyBlock)
|
const QTextBlock &previousNonEmptyBlock)
|
||||||
{
|
{
|
||||||
const QString prevLineText = previousNonEmptyBlock.text().trimmed();
|
const QString prevLineText = previousNonEmptyBlock.text().trimmed();
|
||||||
|
if (prevLineText.isEmpty())
|
||||||
|
return CharacterContext::NewStatementOrContinuation;
|
||||||
|
|
||||||
const QChar firstNonWhitespaceChar = findFirstNonWhitespaceCharacter(currentBlock);
|
const QChar firstNonWhitespaceChar = findFirstNonWhitespaceCharacter(currentBlock);
|
||||||
if (prevLineText.endsWith(',')) {
|
if (prevLineText.endsWith(',')) {
|
||||||
// We don't need to add comma in case it's the last argument.
|
// We don't need to add comma in case it's the last argument.
|
||||||
@@ -162,12 +199,15 @@ CharacterContext characterContext(const QTextBlock ¤tBlock,
|
|||||||
return CharacterContext::AfterComma;
|
return CharacterContext::AfterComma;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevLineText.endsWith(';') || prevLineText.endsWith('{') || prevLineText.endsWith('}')
|
if (prevLineText.endsWith("else"))
|
||||||
|| firstNonWhitespaceChar == QChar::Null) {
|
return CharacterContext::IfOrElseWithoutScope;
|
||||||
return CharacterContext::NewStatement;
|
if (prevLineText.endsWith(')')) {
|
||||||
|
const int pos = findMatchingOpeningParen(previousNonEmptyBlock);
|
||||||
|
if (pos >= 0 && comesDirectlyAfterIf(previousNonEmptyBlock.document(), pos))
|
||||||
|
return CharacterContext::IfOrElseWithoutScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CharacterContext::Continuation;
|
return CharacterContext::NewStatementOrContinuation;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nextBlockExistsAndEmpty(const QTextBlock ¤tBlock)
|
bool nextBlockExistsAndEmpty(const QTextBlock ¤tBlock)
|
||||||
@@ -181,20 +221,18 @@ bool nextBlockExistsAndEmpty(const QTextBlock ¤tBlock)
|
|||||||
|
|
||||||
QByteArray dummyTextForContext(CharacterContext context, bool closingBraceBlock)
|
QByteArray dummyTextForContext(CharacterContext context, bool closingBraceBlock)
|
||||||
{
|
{
|
||||||
if (closingBraceBlock
|
if (closingBraceBlock && context == CharacterContext::NewStatementOrContinuation)
|
||||||
&& (context == CharacterContext::NewStatement
|
|
||||||
|| context == CharacterContext::Continuation)) {
|
|
||||||
return QByteArray();
|
return QByteArray();
|
||||||
}
|
|
||||||
|
|
||||||
switch (context) {
|
switch (context) {
|
||||||
case CharacterContext::AfterComma:
|
case CharacterContext::AfterComma:
|
||||||
return "a,";
|
return "a,";
|
||||||
case CharacterContext::NewStatement:
|
|
||||||
return "a;";
|
|
||||||
case CharacterContext::Continuation:
|
|
||||||
case CharacterContext::LastAfterComma:
|
case CharacterContext::LastAfterComma:
|
||||||
return "& a &";
|
return "a";
|
||||||
|
case CharacterContext::IfOrElseWithoutScope:
|
||||||
|
return ";";
|
||||||
|
case CharacterContext::NewStatementOrContinuation:
|
||||||
|
return "/**/";
|
||||||
case CharacterContext::Unknown:
|
case CharacterContext::Unknown:
|
||||||
default:
|
default:
|
||||||
QTC_ASSERT(false, return "";);
|
QTC_ASSERT(false, return "";);
|
||||||
@@ -202,7 +240,7 @@ QByteArray dummyTextForContext(CharacterContext context, bool closingBraceBlock)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add extra text in case of the empty line or the line starting with ')'.
|
// Add extra text in case of the empty line or the line starting with ')'.
|
||||||
// Track such extra pieces of text in isInsideModifiedLine().
|
// Track such extra pieces of text in isInsideDummyTextInLine().
|
||||||
int forceIndentWithExtraText(QByteArray &buffer,
|
int forceIndentWithExtraText(QByteArray &buffer,
|
||||||
CharacterContext &charContext,
|
CharacterContext &charContext,
|
||||||
const QTextBlock &block,
|
const QTextBlock &block,
|
||||||
@@ -265,7 +303,7 @@ int forceIndentWithExtraText(QByteArray &buffer,
|
|||||||
return extraLength;
|
return extraLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isInsideModifiedLine(const QString &originalLine, const QString &modifiedLine, int column)
|
bool isInsideDummyTextInLine(const QString &originalLine, const QString &modifiedLine, int column)
|
||||||
{
|
{
|
||||||
// Detect the cases when we have inserted extra text into the line to get the indentation.
|
// Detect the cases when we have inserted extra text into the line to get the indentation.
|
||||||
return originalLine.length() < modifiedLine.length() && column != modifiedLine.length() + 1
|
return originalLine.length() < modifiedLine.length() && column != modifiedLine.length() + 1
|
||||||
@@ -291,7 +329,7 @@ TextEditor::Replacements utf16Replacements(const QTextDocument *doc,
|
|||||||
const QString bufferLineText
|
const QString bufferLineText
|
||||||
= Utils::Text::utf16LineTextInUtf8Buffer(utf8Buffer,
|
= Utils::Text::utf16LineTextInUtf8Buffer(utf8Buffer,
|
||||||
static_cast<int>(replacement.getOffset()));
|
static_cast<int>(replacement.getOffset()));
|
||||||
if (isInsideModifiedLine(lineText, bufferLineText, lineColUtf16.column))
|
if (isInsideDummyTextInLine(lineText, bufferLineText, lineColUtf16.column))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
lineColUtf16.column = std::min(lineColUtf16.column, lineText.length() + 1);
|
lineColUtf16.column = std::min(lineColUtf16.column, lineText.length() + 1);
|
||||||
@@ -319,14 +357,12 @@ void applyReplacements(QTextDocument *doc, const TextEditor::Replacements &repla
|
|||||||
int fullOffsetShift = 0;
|
int fullOffsetShift = 0;
|
||||||
QTextCursor editCursor(doc);
|
QTextCursor editCursor(doc);
|
||||||
for (const TextEditor::Replacement &replacement : replacements) {
|
for (const TextEditor::Replacement &replacement : replacements) {
|
||||||
editCursor.beginEditBlock();
|
|
||||||
editCursor.setPosition(replacement.offset + fullOffsetShift);
|
editCursor.setPosition(replacement.offset + fullOffsetShift);
|
||||||
editCursor.movePosition(QTextCursor::NextCharacter,
|
editCursor.movePosition(QTextCursor::NextCharacter,
|
||||||
QTextCursor::KeepAnchor,
|
QTextCursor::KeepAnchor,
|
||||||
replacement.length);
|
replacement.length);
|
||||||
editCursor.removeSelectedText();
|
editCursor.removeSelectedText();
|
||||||
editCursor.insertText(replacement.text);
|
editCursor.insertText(replacement.text);
|
||||||
editCursor.endEditBlock();
|
|
||||||
fullOffsetShift += replacement.text.length() - replacement.length;
|
fullOffsetShift += replacement.text.length() - replacement.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -510,8 +546,11 @@ TextEditor::Replacements ClangFormatBaseIndenter::format(
|
|||||||
ranges = clang::tooling::calculateRangesAfterReplacements(clangReplacements, ranges);
|
ranges = clang::tooling::calculateRangesAfterReplacements(clangReplacements, ranges);
|
||||||
|
|
||||||
clang::format::FormattingAttemptStatus status;
|
clang::format::FormattingAttemptStatus status;
|
||||||
const clang::tooling::Replacements formatReplacements
|
const clang::tooling::Replacements formatReplacements = reformat(style,
|
||||||
= reformat(style, *changedCode, ranges, m_fileName.toString().toStdString(), &status);
|
*changedCode,
|
||||||
|
ranges,
|
||||||
|
assumedFileName,
|
||||||
|
&status);
|
||||||
clangReplacements = clangReplacements.merge(formatReplacements);
|
clangReplacements = clangReplacements.merge(formatReplacements);
|
||||||
|
|
||||||
const TextEditor::Replacements toReplace = utf16Replacements(m_doc, buffer, clangReplacements);
|
const TextEditor::Replacements toReplace = utf16Replacements(m_doc, buffer, clangReplacements);
|
||||||
@@ -533,7 +572,7 @@ TextEditor::Replacements ClangFormatBaseIndenter::indentsFor(QTextBlock startBlo
|
|||||||
|
|
||||||
startBlock = reverseFindLastEmptyBlock(startBlock);
|
startBlock = reverseFindLastEmptyBlock(startBlock);
|
||||||
const int startBlockPosition = startBlock.position();
|
const int startBlockPosition = startBlock.position();
|
||||||
if (startBlock.position() > 0) {
|
if (startBlockPosition > 0) {
|
||||||
trimRHSWhitespace(startBlock.previous());
|
trimRHSWhitespace(startBlock.previous());
|
||||||
if (cursorPositionInEditor >= 0)
|
if (cursorPositionInEditor >= 0)
|
||||||
cursorPositionInEditor += startBlock.position() - startBlockPosition;
|
cursorPositionInEditor += startBlock.position() - startBlockPosition;
|
||||||
@@ -548,9 +587,9 @@ TextEditor::Replacements ClangFormatBaseIndenter::indentsFor(QTextBlock startBlo
|
|||||||
// Format before current position only in case the cursor is inside the indented block.
|
// Format before current position only in case the cursor is inside the indented block.
|
||||||
// So if cursor position is less then the block position then the current line is before
|
// So if cursor position is less then the block position then the current line is before
|
||||||
// the indented block - don't trigger extra formatting in this case.
|
// the indented block - don't trigger extra formatting in this case.
|
||||||
// cursorPositionInEditor == -1 means the consition matches automatically.
|
// cursorPositionInEditor == -1 means the condition matches automatically.
|
||||||
|
|
||||||
// Format only before newline or complete statement not to break code.
|
// Format only before complete statement not to break code.
|
||||||
replacementsToKeep = ReplacementsToKeep::IndentAndBefore;
|
replacementsToKeep = ReplacementsToKeep::IndentAndBefore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,11 +125,17 @@ void ClangFormatConfigWidget::initialize()
|
|||||||
if (lastItem->spacerItem())
|
if (lastItem->spacerItem())
|
||||||
m_ui->verticalLayout->removeItem(lastItem);
|
m_ui->verticalLayout->removeItem(lastItem);
|
||||||
|
|
||||||
|
m_ui->clangFormatOptionsTable->setEnabled(true);
|
||||||
if (!m_ui->overrideDefault->isChecked()) {
|
if (!m_ui->overrideDefault->isChecked()) {
|
||||||
m_ui->clangFormatOptionsTable->hide();
|
if (m_project) {
|
||||||
m_preview->hide();
|
m_ui->clangFormatOptionsTable->hide();
|
||||||
m_ui->verticalLayout->addStretch(1);
|
m_preview->hide();
|
||||||
return;
|
m_ui->verticalLayout->addStretch(1);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// Show the fallback configuration only globally.
|
||||||
|
m_ui->clangFormatOptionsTable->setEnabled(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_ui->clangFormatOptionsTable->show();
|
m_ui->clangFormatOptionsTable->show();
|
||||||
@@ -145,6 +151,7 @@ void ClangFormatConfigWidget::initialize()
|
|||||||
if (!currentProject || !projectConfigExists()) {
|
if (!currentProject || !projectConfigExists()) {
|
||||||
m_ui->projectHasClangFormat->hide();
|
m_ui->projectHasClangFormat->hide();
|
||||||
} else {
|
} else {
|
||||||
|
m_ui->projectHasClangFormat->show();
|
||||||
m_ui->projectHasClangFormat->setText(
|
m_ui->projectHasClangFormat->setText(
|
||||||
tr("Current project has its own overridden .clang-format file "
|
tr("Current project has its own overridden .clang-format file "
|
||||||
"and can be configured in Projects > Code Style > C++."));
|
"and can be configured in Projects > Code Style > C++."));
|
||||||
@@ -189,7 +196,7 @@ void ClangFormatConfigWidget::apply()
|
|||||||
}
|
}
|
||||||
settings.write();
|
settings.write();
|
||||||
|
|
||||||
if (!m_ui->overrideDefault->isChecked())
|
if (!m_ui->clangFormatOptionsTable->isVisible())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const QString text = m_ui->clangFormatOptionsTable->toPlainText();
|
const QString text = m_ui->clangFormatOptionsTable->toPlainText();
|
||||||
|
|||||||
@@ -293,8 +293,11 @@ static QByteArray configBaseStyleName(const QString &configFile)
|
|||||||
static clang::format::FormatStyle styleForFile(Utils::FileName fileName, bool checkForSettings)
|
static clang::format::FormatStyle styleForFile(Utils::FileName fileName, bool checkForSettings)
|
||||||
{
|
{
|
||||||
QString configFile = configForFile(fileName, checkForSettings);
|
QString configFile = configForFile(fileName, checkForSettings);
|
||||||
if (configFile.isEmpty())
|
if (configFile.isEmpty()) {
|
||||||
return constructStyle();
|
// If no configuration is found create a global one (if it does not yet exist) and use it.
|
||||||
|
createStyleFileIfNeeded(true);
|
||||||
|
configFile = globalPath().appendPath(Constants::SETTINGS_FILE_NAME).toString();
|
||||||
|
}
|
||||||
|
|
||||||
fileName = assumedPathForConfig(configFile);
|
fileName = assumedPathForConfig(configFile);
|
||||||
Expected<FormatStyle> style = format::getStyle("file",
|
Expected<FormatStyle> style = format::getStyle("file",
|
||||||
|
|||||||
@@ -215,10 +215,13 @@ void FancyTabBar::mousePressEvent(QMouseEvent *event)
|
|||||||
// menu arrow clicked
|
// menu arrow clicked
|
||||||
emit menuTriggered(index, event);
|
emit menuTriggered(index, event);
|
||||||
} else {
|
} else {
|
||||||
m_currentIndex = index;
|
if (index != m_currentIndex) {
|
||||||
update();
|
emit currentAboutToChange(index);
|
||||||
// update tab bar before showing widget
|
m_currentIndex = index;
|
||||||
QTimer::singleShot(0, this, [this]() { emit currentChanged(m_currentIndex); });
|
update();
|
||||||
|
// update tab bar before showing widget
|
||||||
|
QTimer::singleShot(0, this, [this]() { emit currentChanged(m_currentIndex); });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -396,6 +399,7 @@ void FancyTabBar::paintTab(QPainter *painter, int tabIndex) const
|
|||||||
void FancyTabBar::setCurrentIndex(int index)
|
void FancyTabBar::setCurrentIndex(int index)
|
||||||
{
|
{
|
||||||
if (isTabEnabled(index) && index != m_currentIndex) {
|
if (isTabEnabled(index) && index != m_currentIndex) {
|
||||||
|
emit currentAboutToChange(index);
|
||||||
m_currentIndex = index;
|
m_currentIndex = index;
|
||||||
update();
|
update();
|
||||||
emit currentChanged(m_currentIndex);
|
emit currentChanged(m_currentIndex);
|
||||||
@@ -520,6 +524,7 @@ FancyTabWidget::FancyTabWidget(QWidget *parent)
|
|||||||
mainLayout->addLayout(vlayout);
|
mainLayout->addLayout(vlayout);
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
|
connect(m_tabBar, &FancyTabBar::currentAboutToChange, this, &FancyTabWidget::currentAboutToShow);
|
||||||
connect(m_tabBar, &FancyTabBar::currentChanged, this, &FancyTabWidget::showWidget);
|
connect(m_tabBar, &FancyTabBar::currentChanged, this, &FancyTabWidget::showWidget);
|
||||||
connect(m_tabBar, &FancyTabBar::menuTriggered, this, &FancyTabWidget::menuTriggered);
|
connect(m_tabBar, &FancyTabBar::menuTriggered, this, &FancyTabWidget::menuTriggered);
|
||||||
}
|
}
|
||||||
@@ -598,7 +603,7 @@ void FancyTabWidget::addCornerWidget(QWidget *widget)
|
|||||||
|
|
||||||
int FancyTabWidget::currentIndex() const
|
int FancyTabWidget::currentIndex() const
|
||||||
{
|
{
|
||||||
return m_modesStack->currentIndex();
|
return m_tabBar->currentIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
QStatusBar *FancyTabWidget::statusBar() const
|
QStatusBar *FancyTabWidget::statusBar() const
|
||||||
@@ -613,7 +618,6 @@ void FancyTabWidget::setCurrentIndex(int index)
|
|||||||
|
|
||||||
void FancyTabWidget::showWidget(int index)
|
void FancyTabWidget::showWidget(int index)
|
||||||
{
|
{
|
||||||
emit currentAboutToShow(index);
|
|
||||||
m_modesStack->setCurrentIndex(index);
|
m_modesStack->setCurrentIndex(index);
|
||||||
QWidget *w = m_modesStack->currentWidget();
|
QWidget *w = m_modesStack->currentWidget();
|
||||||
if (QTC_GUARD(w)) {
|
if (QTC_GUARD(w)) {
|
||||||
|
|||||||
@@ -125,6 +125,7 @@ public:
|
|||||||
QRect tabRect(int index) const;
|
QRect tabRect(int index) const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void currentAboutToChange(int index);
|
||||||
void currentChanged(int index);
|
void currentChanged(int index);
|
||||||
void menuTriggered(int index, QMouseEvent *event);
|
void menuTriggered(int index, QMouseEvent *event);
|
||||||
|
|
||||||
|
|||||||
@@ -44,10 +44,12 @@
|
|||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/session.h>
|
||||||
|
|
||||||
#include <texteditor/icodestylepreferencesfactory.h>
|
#include <texteditor/icodestylepreferencesfactory.h>
|
||||||
|
#include <texteditor/storagesettings.h>
|
||||||
#include <texteditor/textdocumentlayout.h>
|
#include <texteditor/textdocumentlayout.h>
|
||||||
#include <texteditor/texteditorsettings.h>
|
#include <texteditor/texteditorsettings.h>
|
||||||
|
|
||||||
#include <coreplugin/editormanager/editormanager.h>
|
#include <coreplugin/editormanager/editormanager.h>
|
||||||
|
#include <utils/executeondestruction.h>
|
||||||
#include <utils/mimetypes/mimedatabase.h>
|
#include <utils/mimetypes/mimedatabase.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/runextensions.h>
|
#include <utils/runextensions.h>
|
||||||
@@ -448,6 +450,8 @@ TextEditor::TabSettings CppEditorDocument::tabSettings() const
|
|||||||
|
|
||||||
bool CppEditorDocument::save(QString *errorString, const QString &fileName, bool autoSave)
|
bool CppEditorDocument::save(QString *errorString, const QString &fileName, bool autoSave)
|
||||||
{
|
{
|
||||||
|
Utils::ExecuteOnDestruction resetSettingsOnScopeExit;
|
||||||
|
|
||||||
if (indenter()->formatOnSave() && !autoSave) {
|
if (indenter()->formatOnSave() && !autoSave) {
|
||||||
auto *layout = qobject_cast<TextEditor::TextDocumentLayout *>(document()->documentLayout());
|
auto *layout = qobject_cast<TextEditor::TextDocumentLayout *>(document()->documentLayout());
|
||||||
const int documentRevision = layout->lastSaveRevision;
|
const int documentRevision = layout->lastSaveRevision;
|
||||||
@@ -479,6 +483,12 @@ bool CppEditorDocument::save(QString *errorString, const QString &fileName, bool
|
|||||||
indenter()->format(editedRanges);
|
indenter()->format(editedRanges);
|
||||||
cursor.endEditBlock();
|
cursor.endEditBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextEditor::StorageSettings settings = storageSettings();
|
||||||
|
resetSettingsOnScopeExit.reset(
|
||||||
|
[this, defaultSettings = settings]() { setStorageSettings(defaultSettings); });
|
||||||
|
settings.m_cleanWhitespace = false;
|
||||||
|
setStorageSettings(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TextEditor::TextDocument::save(errorString, fileName, autoSave);
|
return TextEditor::TextDocument::save(errorString, fileName, autoSave);
|
||||||
|
|||||||
@@ -1661,8 +1661,8 @@ bool BreakHandler::contextMenuEvent(const ItemViewEvent &ev)
|
|||||||
// Delete by file: Find indices of breakpoints of the same file.
|
// Delete by file: Find indices of breakpoints of the same file.
|
||||||
QList<Breakpoint> breakpointsInFile;
|
QList<Breakpoint> breakpointsInFile;
|
||||||
QString file;
|
QString file;
|
||||||
if (Breakpoint bp = itemForIndexAtLevel<1>(ev.index())) {
|
if (Breakpoint bp = itemForIndexAtLevel<1>(ev.sourceModelIndex())) {
|
||||||
const QModelIndex index = ev.index().sibling(ev.index().row(), BreakpointFileColumn);
|
const QModelIndex index = ev.sourceModelIndex().sibling(ev.sourceModelIndex().row(), BreakpointFileColumn);
|
||||||
if (!file.isEmpty()) {
|
if (!file.isEmpty()) {
|
||||||
for (int i = 0; i != rowCount(); ++i)
|
for (int i = 0; i != rowCount(); ++i)
|
||||||
if (index.data().toString() == file)
|
if (index.data().toString() == file)
|
||||||
@@ -2626,7 +2626,7 @@ bool BreakpointManager::contextMenuEvent(const ItemViewEvent &ev)
|
|||||||
// Delete by file: Find indices of breakpoints of the same file.
|
// Delete by file: Find indices of breakpoints of the same file.
|
||||||
GlobalBreakpoints breakpointsInFile;
|
GlobalBreakpoints breakpointsInFile;
|
||||||
QString file;
|
QString file;
|
||||||
if (GlobalBreakpoint gbp = itemForIndexAtLevel<1>(ev.index())) {
|
if (GlobalBreakpoint gbp = itemForIndexAtLevel<1>(ev.sourceModelIndex())) {
|
||||||
if (!file.isEmpty()) {
|
if (!file.isEmpty()) {
|
||||||
for (int i = 0; i != rowCount(); ++i)
|
for (int i = 0; i != rowCount(); ++i)
|
||||||
if (gbp->markerFileName() == file)
|
if (gbp->markerFileName() == file)
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/idocument.h>
|
#include <coreplugin/idocument.h>
|
||||||
#include <coreplugin/messagebox.h>
|
#include <coreplugin/messagebox.h>
|
||||||
|
#include <coreplugin/modemanager.h>
|
||||||
#include <coreplugin/progressmanager/progressmanager.h>
|
#include <coreplugin/progressmanager/progressmanager.h>
|
||||||
#include <coreplugin/progressmanager/futureprogress.h>
|
#include <coreplugin/progressmanager/futureprogress.h>
|
||||||
|
|
||||||
@@ -280,12 +281,16 @@ public:
|
|||||||
m_disassemblerAgent(engine),
|
m_disassemblerAgent(engine),
|
||||||
m_toolTipManager(engine)
|
m_toolTipManager(engine)
|
||||||
{
|
{
|
||||||
m_logWindow = new LogWindow(m_engine); // Needed before start()
|
|
||||||
m_logWindow->setObjectName(DOCKWIDGET_OUTPUT);
|
|
||||||
m_debuggerName = DebuggerEngine::tr("Debugger");
|
m_debuggerName = DebuggerEngine::tr("Debugger");
|
||||||
|
|
||||||
connect(action(EnableReverseDebugging), &SavedAction::valueChanged,
|
m_logWindow = new LogWindow(m_engine); // Needed before start()
|
||||||
this, [this] { updateState(true); });
|
m_logWindow->setObjectName("Debugger.Dock.Output");
|
||||||
|
|
||||||
|
connect(action(EnableReverseDebugging), &SavedAction::valueChanged, this, [this] {
|
||||||
|
updateState();
|
||||||
|
if (m_companionEngine)
|
||||||
|
m_companionEngine->d->updateState();
|
||||||
|
});
|
||||||
static int contextCount = 0;
|
static int contextCount = 0;
|
||||||
m_context = Context(Id("Debugger.Engine.").withSuffix(++contextCount));
|
m_context = Context(Id("Debugger.Engine.").withSuffix(++contextCount));
|
||||||
|
|
||||||
@@ -370,17 +375,15 @@ public:
|
|||||||
if (!m_perspective)
|
if (!m_perspective)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
delete m_perspective;
|
Perspective *perspective = m_perspective;
|
||||||
m_perspective = nullptr;
|
m_perspective = nullptr;
|
||||||
|
|
||||||
EngineManager::unregisterEngine(m_engine);
|
EngineManager::unregisterEngine(m_engine);
|
||||||
|
|
||||||
// Give up ownership on claimed breakpoints.
|
// This triggers activity in the EngineManager which
|
||||||
m_breakHandler.releaseAllBreakpoints();
|
// recognizes the rampdown by the m_perpective == nullptr above.
|
||||||
m_toolTipManager.deregisterEngine();
|
perspective->destroy();
|
||||||
m_memoryAgents.handleDebuggerFinished();
|
delete perspective;
|
||||||
|
|
||||||
setBusyCursor(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateReturnViewHeader(int section, int, int newSize)
|
void updateReturnViewHeader(int section, int, int newSize)
|
||||||
@@ -446,13 +449,13 @@ public:
|
|||||||
void setInitialActionStates();
|
void setInitialActionStates();
|
||||||
void setBusyCursor(bool on);
|
void setBusyCursor(bool on);
|
||||||
void cleanupViews();
|
void cleanupViews();
|
||||||
void updateState(bool alsoUpdateCompanion);
|
void updateState();
|
||||||
void updateReverseActions();
|
void updateReverseActions();
|
||||||
|
|
||||||
DebuggerEngine *m_engine = nullptr; // Not owned.
|
DebuggerEngine *m_engine = nullptr; // Not owned.
|
||||||
QString m_runId;
|
QString m_runId;
|
||||||
QString m_debuggerName;
|
QString m_debuggerName;
|
||||||
Perspective *m_perspective = nullptr;
|
QPointer<Perspective> m_perspective;
|
||||||
DebuggerRunParameters m_runParameters;
|
DebuggerRunParameters m_runParameters;
|
||||||
IDevice::ConstPtr m_device;
|
IDevice::ConstPtr m_device;
|
||||||
|
|
||||||
@@ -550,16 +553,17 @@ public:
|
|||||||
void DebuggerEnginePrivate::setupViews()
|
void DebuggerEnginePrivate::setupViews()
|
||||||
{
|
{
|
||||||
const DebuggerRunParameters &rp = m_runParameters;
|
const DebuggerRunParameters &rp = m_runParameters;
|
||||||
|
const QString engineId = EngineManager::registerEngine(m_engine);
|
||||||
|
|
||||||
QTC_CHECK(!m_perspective);
|
QTC_CHECK(!m_perspective);
|
||||||
|
|
||||||
m_perspective = new Perspective("Debugger.Perspective." + m_runId + '.' + m_debuggerName,
|
const QString perspectiveId = "Debugger.Perspective." + m_runId + '.' + m_debuggerName;
|
||||||
|
const QString settingsId = "Debugger.Perspective." + m_debuggerName;
|
||||||
|
|
||||||
|
m_perspective = new Perspective(perspectiveId,
|
||||||
m_engine->displayName(),
|
m_engine->displayName(),
|
||||||
Debugger::Constants::PRESET_PERSPECTIVE_ID,
|
Debugger::Constants::PRESET_PERSPECTIVE_ID,
|
||||||
m_debuggerName);
|
settingsId);
|
||||||
m_perspective->setShouldPersistChecker([this] {
|
|
||||||
return EngineManager::isLastOf(m_debuggerName);
|
|
||||||
});
|
|
||||||
|
|
||||||
m_progress.setProgressRange(0, 1000);
|
m_progress.setProgressRange(0, 1000);
|
||||||
FutureProgress *fp = ProgressManager::addTask(m_progress.future(),
|
FutureProgress *fp = ProgressManager::addTask(m_progress.future(),
|
||||||
@@ -627,7 +631,7 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
m_engine, &DebuggerEngine::reloadModules,
|
m_engine, &DebuggerEngine::reloadModules,
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
m_modulesWindow = addSearch(m_modulesView);
|
m_modulesWindow = addSearch(m_modulesView);
|
||||||
m_modulesWindow->setObjectName(DOCKWIDGET_MODULES);
|
m_modulesWindow->setObjectName("Debugger.Dock.Modules." + engineId);
|
||||||
m_modulesWindow->setWindowTitle(tr("&Modules"));
|
m_modulesWindow->setWindowTitle(tr("&Modules"));
|
||||||
|
|
||||||
m_registerView = new BaseTreeView;
|
m_registerView = new BaseTreeView;
|
||||||
@@ -638,7 +642,7 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
m_engine, &DebuggerEngine::reloadRegisters,
|
m_engine, &DebuggerEngine::reloadRegisters,
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
m_registerWindow = addSearch(m_registerView);
|
m_registerWindow = addSearch(m_registerView);
|
||||||
m_registerWindow->setObjectName(DOCKWIDGET_REGISTER);
|
m_registerWindow->setObjectName("Debugger.Dock.Register." + engineId);
|
||||||
m_registerWindow->setWindowTitle(tr("Reg&isters"));
|
m_registerWindow->setWindowTitle(tr("Reg&isters"));
|
||||||
|
|
||||||
m_stackView = new StackTreeView;
|
m_stackView = new StackTreeView;
|
||||||
@@ -646,7 +650,7 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
m_stackView->setSettings(settings, "Debugger.StackView");
|
m_stackView->setSettings(settings, "Debugger.StackView");
|
||||||
m_stackView->setIconSize(QSize(10, 10));
|
m_stackView->setIconSize(QSize(10, 10));
|
||||||
m_stackWindow = addSearch(m_stackView);
|
m_stackWindow = addSearch(m_stackView);
|
||||||
m_stackWindow->setObjectName(DOCKWIDGET_STACK);
|
m_stackWindow->setObjectName("Debugger.Dock.Stack." + engineId);
|
||||||
m_stackWindow->setWindowTitle(tr("&Stack"));
|
m_stackWindow->setWindowTitle(tr("&Stack"));
|
||||||
|
|
||||||
m_sourceFilesView = new BaseTreeView;
|
m_sourceFilesView = new BaseTreeView;
|
||||||
@@ -657,7 +661,7 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
m_engine, &DebuggerEngine::reloadSourceFiles,
|
m_engine, &DebuggerEngine::reloadSourceFiles,
|
||||||
Qt::QueuedConnection);
|
Qt::QueuedConnection);
|
||||||
m_sourceFilesWindow = addSearch(m_sourceFilesView);
|
m_sourceFilesWindow = addSearch(m_sourceFilesView);
|
||||||
m_sourceFilesWindow->setObjectName(DOCKWIDGET_SOURCE_FILES);
|
m_sourceFilesWindow->setObjectName("Debugger.Dock.SourceFiles." + engineId);
|
||||||
m_sourceFilesWindow->setWindowTitle(tr("Source Files"));
|
m_sourceFilesWindow->setWindowTitle(tr("Source Files"));
|
||||||
|
|
||||||
m_threadsView = new BaseTreeView;
|
m_threadsView = new BaseTreeView;
|
||||||
@@ -667,7 +671,7 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
m_threadsView->setIconSize(QSize(10, 10));
|
m_threadsView->setIconSize(QSize(10, 10));
|
||||||
m_threadsView->setSpanColumn(ThreadData::FunctionColumn);
|
m_threadsView->setSpanColumn(ThreadData::FunctionColumn);
|
||||||
m_threadsWindow = addSearch(m_threadsView);
|
m_threadsWindow = addSearch(m_threadsView);
|
||||||
m_threadsWindow->setObjectName(DOCKWIDGET_THREADS);
|
m_threadsWindow->setObjectName("Debugger.Dock.Threads." + engineId);
|
||||||
m_threadsWindow->setWindowTitle(tr("&Threads"));
|
m_threadsWindow->setWindowTitle(tr("&Threads"));
|
||||||
|
|
||||||
m_returnView = new WatchTreeView{ReturnType};
|
m_returnView = new WatchTreeView{ReturnType};
|
||||||
@@ -681,26 +685,26 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
m_localsView->setModel(m_watchHandler.model());
|
m_localsView->setModel(m_watchHandler.model());
|
||||||
m_localsView->setSettings(settings, "Debugger.LocalsView");
|
m_localsView->setSettings(settings, "Debugger.LocalsView");
|
||||||
m_localsWindow = addSearch(m_localsView);
|
m_localsWindow = addSearch(m_localsView);
|
||||||
m_localsWindow->setObjectName("CppDebugLocals");
|
m_localsWindow->setObjectName("Debugger.Dock.Locals." + engineId);
|
||||||
m_localsWindow->setWindowTitle(tr("Locals"));
|
m_localsWindow->setWindowTitle(tr("Locals"));
|
||||||
|
|
||||||
m_inspectorView = new WatchTreeView{InspectType};
|
m_inspectorView = new WatchTreeView{InspectType};
|
||||||
m_inspectorView->setModel(m_watchHandler.model());
|
m_inspectorView->setModel(m_watchHandler.model());
|
||||||
m_inspectorView->setSettings(settings, "Debugger.LocalsView"); // sic! same as locals view.
|
m_inspectorView->setSettings(settings, "Debugger.LocalsView"); // sic! same as locals view.
|
||||||
m_inspectorWindow = addSearch(m_inspectorView);
|
m_inspectorWindow = addSearch(m_inspectorView);
|
||||||
m_inspectorWindow->setObjectName("Inspector");
|
m_inspectorWindow->setObjectName("Debugger.Dock.Inspector." + engineId);
|
||||||
m_inspectorWindow->setWindowTitle(tr("Locals"));
|
m_inspectorWindow->setWindowTitle(tr("Locals"));
|
||||||
|
|
||||||
m_watchersView = new WatchTreeView{WatchersType};
|
m_watchersView = new WatchTreeView{WatchersType};
|
||||||
m_watchersView->setModel(m_watchHandler.model());
|
m_watchersView->setModel(m_watchHandler.model());
|
||||||
m_watchersView->setSettings(settings, "Debugger.WatchersView");
|
m_watchersView->setSettings(settings, "Debugger.WatchersView");
|
||||||
m_watchersWindow = addSearch(m_watchersView);
|
m_watchersWindow = addSearch(m_watchersView);
|
||||||
m_watchersWindow->setObjectName("CppDebugWatchers");
|
m_watchersWindow->setObjectName("Debugger.Dock.Watchers." + engineId);
|
||||||
m_watchersWindow->setWindowTitle(tr("&Expressions"));
|
m_watchersWindow->setWindowTitle(tr("&Expressions"));
|
||||||
|
|
||||||
m_localsAndInspectorWindow = new LocalsAndInspectorWindow(
|
m_localsAndInspectorWindow = new LocalsAndInspectorWindow(
|
||||||
m_localsWindow, m_inspectorWindow, m_returnWindow);
|
m_localsWindow, m_inspectorWindow, m_returnWindow);
|
||||||
m_localsAndInspectorWindow->setObjectName(DOCKWIDGET_LOCALS_AND_INSPECTOR);
|
m_localsAndInspectorWindow->setObjectName("Debugger.Dock.LocalsAndInspector." + engineId);
|
||||||
m_localsAndInspectorWindow->setWindowTitle(m_localsWindow->windowTitle());
|
m_localsAndInspectorWindow->setWindowTitle(m_localsWindow->windowTitle());
|
||||||
|
|
||||||
// Locals
|
// Locals
|
||||||
@@ -718,7 +722,7 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
m_breakView->setModel(m_breakHandler.model());
|
m_breakView->setModel(m_breakHandler.model());
|
||||||
m_breakView->setRootIsDecorated(true);
|
m_breakView->setRootIsDecorated(true);
|
||||||
m_breakWindow = addSearch(m_breakView);
|
m_breakWindow = addSearch(m_breakView);
|
||||||
m_breakWindow->setObjectName(DOCKWIDGET_BREAK);
|
m_breakWindow->setObjectName("Debugger.Dock.Break." + engineId);
|
||||||
m_breakWindow->setWindowTitle(tr("&Breakpoints"));
|
m_breakWindow->setWindowTitle(tr("&Breakpoints"));
|
||||||
|
|
||||||
m_perspective->useSubPerspectiveSwitcher(EngineManager::engineChooser());
|
m_perspective->useSubPerspectiveSwitcher(EngineManager::engineChooser());
|
||||||
@@ -845,7 +849,6 @@ void DebuggerEnginePrivate::setupViews()
|
|||||||
DebuggerEngine::DebuggerEngine()
|
DebuggerEngine::DebuggerEngine()
|
||||||
: d(new DebuggerEnginePrivate(this))
|
: d(new DebuggerEnginePrivate(this))
|
||||||
{
|
{
|
||||||
updateState(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggerEngine::~DebuggerEngine()
|
DebuggerEngine::~DebuggerEngine()
|
||||||
@@ -1018,7 +1021,6 @@ void DebuggerEngine::setRunTool(DebuggerRunTool *runTool)
|
|||||||
|
|
||||||
void DebuggerEngine::start()
|
void DebuggerEngine::start()
|
||||||
{
|
{
|
||||||
EngineManager::registerEngine(this);
|
|
||||||
d->m_watchHandler.resetWatchers();
|
d->m_watchHandler.resetWatchers();
|
||||||
d->setInitialActionStates();
|
d->setInitialActionStates();
|
||||||
setState(EngineSetupRequested);
|
setState(EngineSetupRequested);
|
||||||
@@ -1114,7 +1116,7 @@ void DebuggerEngine::abortDebugger()
|
|||||||
|
|
||||||
void DebuggerEngine::updateUi(bool isCurrentEngine)
|
void DebuggerEngine::updateUi(bool isCurrentEngine)
|
||||||
{
|
{
|
||||||
updateState(false);
|
updateState();
|
||||||
if (isCurrentEngine) {
|
if (isCurrentEngine) {
|
||||||
gotoCurrentLocation();
|
gotoCurrentLocation();
|
||||||
} else {
|
} else {
|
||||||
@@ -1317,7 +1319,7 @@ void DebuggerEngine::notifyInferiorSpontaneousStop()
|
|||||||
{
|
{
|
||||||
showMessage("NOTE: INFERIOR SPONTANEOUS STOP");
|
showMessage("NOTE: INFERIOR SPONTANEOUS STOP");
|
||||||
QTC_ASSERT(state() == InferiorRunOk, qDebug() << this << state());
|
QTC_ASSERT(state() == InferiorRunOk, qDebug() << this << state());
|
||||||
EngineManager::activateEngine(this);
|
d->m_perspective->select();
|
||||||
showMessage(tr("Stopped."), StatusBar);
|
showMessage(tr("Stopped."), StatusBar);
|
||||||
setState(InferiorStopOk);
|
setState(InferiorStopOk);
|
||||||
if (boolSetting(RaiseOnInterrupt))
|
if (boolSetting(RaiseOnInterrupt))
|
||||||
@@ -1384,10 +1386,12 @@ void DebuggerEnginePrivate::setInitialActionStates()
|
|||||||
m_threadLabel->setEnabled(false);
|
m_threadLabel->setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerEnginePrivate::updateState(bool alsoUpdateCompanion)
|
void DebuggerEnginePrivate::updateState()
|
||||||
{
|
{
|
||||||
if (!m_perspective)
|
// Can happen in mixed debugging.
|
||||||
|
if (!m_threadLabel)
|
||||||
return;
|
return;
|
||||||
|
QTC_ASSERT(m_threadLabel, return);
|
||||||
|
|
||||||
const DebuggerState state = m_state;
|
const DebuggerState state = m_state;
|
||||||
const bool companionPreventsAction = m_engine->companionPreventsActions();
|
const bool companionPreventsAction = m_engine->companionPreventsActions();
|
||||||
@@ -1397,7 +1401,7 @@ void DebuggerEnginePrivate::updateState(bool alsoUpdateCompanion)
|
|||||||
// visible, possibly disabled.
|
// visible, possibly disabled.
|
||||||
if (state == DebuggerNotReady) {
|
if (state == DebuggerNotReady) {
|
||||||
// Happens when companion starts, otherwise this should not happen.
|
// Happens when companion starts, otherwise this should not happen.
|
||||||
QTC_CHECK(m_companionEngine);
|
//QTC_CHECK(m_companionEngine);
|
||||||
m_interruptAction.setVisible(true);
|
m_interruptAction.setVisible(true);
|
||||||
m_interruptAction.setEnabled(false);
|
m_interruptAction.setEnabled(false);
|
||||||
m_continueAction.setVisible(false);
|
m_continueAction.setVisible(false);
|
||||||
@@ -1527,9 +1531,6 @@ void DebuggerEnginePrivate::updateState(bool alsoUpdateCompanion)
|
|||||||
|| state == DebuggerFinished
|
|| state == DebuggerFinished
|
||||||
|| state == InferiorUnrunnable;
|
|| state == InferiorUnrunnable;
|
||||||
setBusyCursor(!notbusy);
|
setBusyCursor(!notbusy);
|
||||||
|
|
||||||
if (alsoUpdateCompanion && m_companionEngine)
|
|
||||||
m_companionEngine->updateState(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerEnginePrivate::updateReverseActions()
|
void DebuggerEnginePrivate::updateReverseActions()
|
||||||
@@ -1688,9 +1689,9 @@ void DebuggerEngine::notifyInferiorExited()
|
|||||||
d->doShutdownEngine();
|
d->doShutdownEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerEngine::updateState(bool alsoUpdateCompanion)
|
void DebuggerEngine::updateState()
|
||||||
{
|
{
|
||||||
d->updateState(alsoUpdateCompanion);
|
d->updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
WatchTreeView *DebuggerEngine::inspectorView()
|
WatchTreeView *DebuggerEngine::inspectorView()
|
||||||
@@ -1791,17 +1792,28 @@ void DebuggerEngine::setState(DebuggerState state, bool forced)
|
|||||||
if (!forced && !isAllowedTransition(oldState, state))
|
if (!forced && !isAllowedTransition(oldState, state))
|
||||||
qDebug() << "*** UNEXPECTED STATE TRANSITION: " << this << msg;
|
qDebug() << "*** UNEXPECTED STATE TRANSITION: " << this << msg;
|
||||||
|
|
||||||
if (state == EngineRunRequested)
|
if (state == EngineRunRequested) {
|
||||||
emit engineStarted();
|
emit engineStarted();
|
||||||
|
d->m_perspective->select();
|
||||||
|
}
|
||||||
|
|
||||||
showMessage(msg, LogDebug);
|
showMessage(msg, LogDebug);
|
||||||
|
|
||||||
d->updateState(true);
|
d->updateState();
|
||||||
|
if (d->m_companionEngine)
|
||||||
|
d->m_companionEngine->d->updateState();
|
||||||
|
|
||||||
if (oldState != d->m_state)
|
if (oldState != d->m_state)
|
||||||
emit EngineManager::instance()->engineStateChanged(this);
|
emit EngineManager::instance()->engineStateChanged(this);
|
||||||
|
|
||||||
if (state == DebuggerFinished) {
|
if (state == DebuggerFinished) {
|
||||||
|
d->setBusyCursor(false);
|
||||||
|
|
||||||
|
// Give up ownership on claimed breakpoints.
|
||||||
|
d->m_breakHandler.releaseAllBreakpoints();
|
||||||
|
d->m_toolTipManager.deregisterEngine();
|
||||||
|
d->m_memoryAgents.handleDebuggerFinished();
|
||||||
|
|
||||||
d->destroyPerspective();
|
d->destroyPerspective();
|
||||||
emit engineFinished();
|
emit engineFinished();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -445,7 +445,7 @@ protected:
|
|||||||
void notifyInferiorStopFailed();
|
void notifyInferiorStopFailed();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void updateState(bool alsoUpdateCompanion);
|
void updateState();
|
||||||
QString formatStartParameters() const;
|
QString formatStartParameters() const;
|
||||||
WatchTreeView *inspectorView();
|
WatchTreeView *inspectorView();
|
||||||
void updateLocalsWindow(bool showReturn);
|
void updateLocalsWindow(bool showReturn);
|
||||||
|
|||||||
@@ -28,24 +28,6 @@
|
|||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
// DebuggerMainWindow dock widget names
|
|
||||||
const char DOCKWIDGET_BREAKPOINTMANAGER[] = "Debugger.Docks.BreakpointManager";
|
|
||||||
const char DOCKWIDGET_ENGINEMANAGER[] = "Debugger.Docks.Snapshots";
|
|
||||||
const char DOCKWIDGET_GLOBALLOG[] = "Debugger.Docks.GlobalLog";
|
|
||||||
|
|
||||||
const char DOCKWIDGET_BREAK[] = "Debugger.Docks.Break";
|
|
||||||
const char DOCKWIDGET_MODULES[] = "Debugger.Docks.Modules";
|
|
||||||
const char DOCKWIDGET_REGISTER[] = "Debugger.Docks.Register";
|
|
||||||
const char DOCKWIDGET_OUTPUT[] = "Debugger.Docks.Output";
|
|
||||||
const char DOCKWIDGET_STACK[] = "Debugger.Docks.Stack";
|
|
||||||
const char DOCKWIDGET_SOURCE_FILES[] = "Debugger.Docks.SourceFiles";
|
|
||||||
const char DOCKWIDGET_THREADS[] = "Debugger.Docks.Threads";
|
|
||||||
const char DOCKWIDGET_LOCALS_AND_INSPECTOR[] = "Debugger.Docks.LocalsAndInspector";
|
|
||||||
|
|
||||||
} // namespace Internal
|
|
||||||
|
|
||||||
|
|
||||||
namespace Constants {
|
namespace Constants {
|
||||||
|
|
||||||
|
|||||||
@@ -49,9 +49,10 @@
|
|||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
#include <QDebug>
|
#include <QContextMenuEvent>
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
#include <QLoggingCategory>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
#include <QStackedWidget>
|
#include <QStackedWidget>
|
||||||
@@ -62,37 +63,57 @@
|
|||||||
using namespace Debugger;
|
using namespace Debugger;
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(perspectivesLog, "qtc.utils.perspectives", QtWarningMsg)
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
|
const int SettingsVersion = 3;
|
||||||
|
|
||||||
const char LAST_PERSPECTIVE_KEY[] = "LastPerspective";
|
const char LAST_PERSPECTIVE_KEY[] = "LastPerspective";
|
||||||
const char OWNED_BY_PERSPECTIVE[] = "OwnedByPerspective";
|
const char MAINWINDOW_KEY[] = "Debugger.MainWindow";
|
||||||
|
const char AUTOHIDE_TITLEBARS_KEY[] = "AutoHideTitleBars";
|
||||||
|
const char SHOW_CENTRALWIDGET_KEY[] = "ShowCentralWidget";
|
||||||
|
const char STATE_KEY[] = "State";
|
||||||
|
const char CHANGED_DOCK_KEY[] = "ChangedDocks";
|
||||||
|
|
||||||
static DebuggerMainWindow *theMainWindow = nullptr;
|
static DebuggerMainWindow *theMainWindow = nullptr;
|
||||||
|
|
||||||
class DockOperation
|
class DockOperation
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
void setupLayout();
|
||||||
|
QString name() const { QTC_ASSERT(widget, return QString()); return widget->objectName(); }
|
||||||
|
|
||||||
|
Core::Id commandId;
|
||||||
QPointer<QWidget> widget;
|
QPointer<QWidget> widget;
|
||||||
QString anchorDockId;
|
QPointer<QDockWidget> dock;
|
||||||
|
QPointer<QWidget> anchorWidget;
|
||||||
Perspective::OperationType operationType = Perspective::Raise;
|
Perspective::OperationType operationType = Perspective::Raise;
|
||||||
bool visibleByDefault = true;
|
bool visibleByDefault = true;
|
||||||
|
bool visibleByUser = true;
|
||||||
Qt::DockWidgetArea area = Qt::BottomDockWidgetArea;
|
Qt::DockWidgetArea area = Qt::BottomDockWidgetArea;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PerspectivePrivate
|
class PerspectivePrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void showToolBar();
|
void showInnerToolBar();
|
||||||
void hideToolBar();
|
void hideInnerToolBar();
|
||||||
void restoreLayout();
|
void restoreLayout();
|
||||||
void saveLayout();
|
void saveLayout();
|
||||||
|
void resetPerspective();
|
||||||
|
void populatePerspective();
|
||||||
|
void depopulatePerspective();
|
||||||
|
void saveAsLastUsedPerspective();
|
||||||
|
Context context() const;
|
||||||
|
|
||||||
QString settingsId() const;
|
QString settingsId() const;
|
||||||
QToolButton *setupToolButton(QAction *action);
|
QToolButton *setupToolButton(QAction *action);
|
||||||
|
|
||||||
QString m_id;
|
QString m_id;
|
||||||
QString m_name;
|
QString m_name;
|
||||||
QString m_parentPerspectiveId;
|
QString m_parentPerspectiveId;
|
||||||
QString m_subPerspectiveType;
|
QString m_settingsId;
|
||||||
QVector<DockOperation> m_dockOperations;
|
QVector<DockOperation> m_dockOperations;
|
||||||
QPointer<QWidget> m_centralWidget;
|
QPointer<QWidget> m_centralWidget;
|
||||||
Perspective::Callback m_aboutToActivateCallback;
|
Perspective::Callback m_aboutToActivateCallback;
|
||||||
@@ -100,8 +121,6 @@ public:
|
|||||||
QHBoxLayout *m_innerToolBarLayout = nullptr;
|
QHBoxLayout *m_innerToolBarLayout = nullptr;
|
||||||
QPointer<QWidget> m_switcher;
|
QPointer<QWidget> m_switcher;
|
||||||
QString m_lastActiveSubPerspectiveId;
|
QString m_lastActiveSubPerspectiveId;
|
||||||
QHash<QString, QVariant> m_nonPersistenSettings;
|
|
||||||
Perspective::ShouldPersistChecker m_shouldPersistChecker;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DebuggerMainWindowPrivate : public QObject
|
class DebuggerMainWindowPrivate : public QObject
|
||||||
@@ -118,20 +137,30 @@ public:
|
|||||||
void registerPerspective(Perspective *perspective);
|
void registerPerspective(Perspective *perspective);
|
||||||
void resetCurrentPerspective();
|
void resetCurrentPerspective();
|
||||||
int indexInChooser(Perspective *perspective) const;
|
int indexInChooser(Perspective *perspective) const;
|
||||||
void fixupLayoutIfNeeded();
|
|
||||||
void updatePerspectiveChooserWidth();
|
void updatePerspectiveChooserWidth();
|
||||||
|
|
||||||
|
void cleanDocks();
|
||||||
|
void setCentralWidget(QWidget *widget);
|
||||||
|
|
||||||
|
QDockWidget *dockForWidget(QWidget *widget) const;
|
||||||
|
|
||||||
|
void setCurrentPerspective(Perspective *perspective)
|
||||||
|
{
|
||||||
|
m_currentPerspective = perspective;
|
||||||
|
}
|
||||||
|
|
||||||
DebuggerMainWindow *q = nullptr;
|
DebuggerMainWindow *q = nullptr;
|
||||||
Perspective *m_currentPerspective = nullptr;
|
QPointer<Perspective> m_currentPerspective = nullptr;
|
||||||
QComboBox *m_perspectiveChooser = nullptr;
|
QComboBox *m_perspectiveChooser = nullptr;
|
||||||
QStackedWidget *m_centralWidgetStack = nullptr;
|
QStackedWidget *m_centralWidgetStack = nullptr;
|
||||||
QHBoxLayout *m_subPerspectiveSwitcherLayout = nullptr;
|
QHBoxLayout *m_subPerspectiveSwitcherLayout = nullptr;
|
||||||
QHBoxLayout *m_innerToolsLayout = nullptr;
|
QHBoxLayout *m_innerToolsLayout = nullptr;
|
||||||
QWidget *m_editorPlaceHolder = nullptr;
|
QPointer<QWidget> m_editorPlaceHolder;
|
||||||
Utils::StatusLabel *m_statusLabel = nullptr;
|
Utils::StatusLabel *m_statusLabel = nullptr;
|
||||||
QDockWidget *m_toolBarDock = nullptr;
|
QDockWidget *m_toolBarDock = nullptr;
|
||||||
|
|
||||||
QList<Perspective *> m_perspectives;
|
QList<QPointer<Perspective>> m_perspectives;
|
||||||
|
QSet<QString> m_persistentChangedDocks;
|
||||||
};
|
};
|
||||||
|
|
||||||
DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent)
|
DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent)
|
||||||
@@ -211,10 +240,9 @@ DebuggerMainWindowPrivate::DebuggerMainWindowPrivate(DebuggerMainWindow *parent)
|
|||||||
m_toolBarDock = dock;
|
m_toolBarDock = dock;
|
||||||
q->addDockWidget(Qt::BottomDockWidgetArea, m_toolBarDock);
|
q->addDockWidget(Qt::BottomDockWidgetArea, m_toolBarDock);
|
||||||
|
|
||||||
connect(viewButton, &QAbstractButton::clicked, [this, viewButton] {
|
connect(viewButton, &QAbstractButton::clicked, this, [this, viewButton] {
|
||||||
QMenu menu;
|
ActionContainer *viewsMenu = ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS);
|
||||||
q->addDockActionsToMenu(&menu);
|
viewsMenu->menu()->exec(viewButton->mapToGlobal(QPoint()));
|
||||||
menu.exec(viewButton->mapToGlobal(QPoint()));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(closeButton, &QAbstractButton::clicked, [] {
|
connect(closeButton, &QAbstractButton::clicked, [] {
|
||||||
@@ -256,6 +284,19 @@ DebuggerMainWindow::DebuggerMainWindow()
|
|||||||
"Debugger.Views.ResetSimple", debugcontext);
|
"Debugger.Views.ResetSimple", debugcontext);
|
||||||
cmd->setAttribute(Command::CA_Hide);
|
cmd->setAttribute(Command::CA_Hide);
|
||||||
viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
|
viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE);
|
||||||
|
|
||||||
|
connect(ICore::instance(), &ICore::saveSettingsRequested, this, [this] {
|
||||||
|
// There's one saveSettings triggered after plugin loading intentionally.
|
||||||
|
// We do not want to save anything at that time.
|
||||||
|
static bool firstOne = true;
|
||||||
|
if (firstOne) {
|
||||||
|
qCDebug(perspectivesLog) << "FIRST SAVE SETTINGS REQUEST IGNORED";
|
||||||
|
firstOne = false;
|
||||||
|
} else {
|
||||||
|
qCDebug(perspectivesLog) << "SAVING SETTINGS";
|
||||||
|
savePersistentSettings();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggerMainWindow::~DebuggerMainWindow()
|
DebuggerMainWindow::~DebuggerMainWindow()
|
||||||
@@ -263,6 +304,12 @@ DebuggerMainWindow::~DebuggerMainWindow()
|
|||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebuggerMainWindow::contextMenuEvent(QContextMenuEvent *ev)
|
||||||
|
{
|
||||||
|
ActionContainer *viewsMenu = ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS);
|
||||||
|
viewsMenu->menu()->exec(ev->globalPos());
|
||||||
|
}
|
||||||
|
|
||||||
void DebuggerMainWindow::ensureMainWindowExists()
|
void DebuggerMainWindow::ensureMainWindowExists()
|
||||||
{
|
{
|
||||||
if (!theMainWindow)
|
if (!theMainWindow)
|
||||||
@@ -271,6 +318,8 @@ void DebuggerMainWindow::ensureMainWindowExists()
|
|||||||
|
|
||||||
void DebuggerMainWindow::doShutdown()
|
void DebuggerMainWindow::doShutdown()
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(theMainWindow, return);
|
||||||
|
|
||||||
delete theMainWindow;
|
delete theMainWindow;
|
||||||
theMainWindow = nullptr;
|
theMainWindow = nullptr;
|
||||||
}
|
}
|
||||||
@@ -286,9 +335,12 @@ void DebuggerMainWindowPrivate::registerPerspective(Perspective *perspective)
|
|||||||
|
|
||||||
void DebuggerMainWindowPrivate::destroyPerspective(Perspective *perspective)
|
void DebuggerMainWindowPrivate::destroyPerspective(Perspective *perspective)
|
||||||
{
|
{
|
||||||
if (perspective == m_currentPerspective) {
|
qCDebug(perspectivesLog) << "ABOUT TO DESTROY PERSPECTIVE" << perspective->id();
|
||||||
depopulateCurrentPerspective();
|
|
||||||
m_currentPerspective = nullptr;
|
const bool wasCurrent = perspective == m_currentPerspective;
|
||||||
|
if (wasCurrent) {
|
||||||
|
qCDebug(perspectivesLog) << "RAMPING IT DOWN FIRST AS IT WAS CURRENT" << perspective->id();
|
||||||
|
perspective->rampDownAsCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_perspectives.removeAll(perspective);
|
m_perspectives.removeAll(perspective);
|
||||||
@@ -298,6 +350,31 @@ void DebuggerMainWindowPrivate::destroyPerspective(Perspective *perspective)
|
|||||||
const int idx = indexInChooser(perspective);
|
const int idx = indexInChooser(perspective);
|
||||||
if (idx != -1)
|
if (idx != -1)
|
||||||
m_perspectiveChooser->removeItem(idx);
|
m_perspectiveChooser->removeItem(idx);
|
||||||
|
|
||||||
|
for (DockOperation &op : perspective->d->m_dockOperations) {
|
||||||
|
if (op.commandId.isValid())
|
||||||
|
ActionManager::unregisterAction(op.dock->toggleViewAction(), op.commandId);
|
||||||
|
if (op.dock) {
|
||||||
|
theMainWindow->removeDockWidget(op.dock);
|
||||||
|
op.widget->setParent(nullptr); // Prevent deletion
|
||||||
|
op.dock->setParent(nullptr);
|
||||||
|
delete op.dock;
|
||||||
|
op.dock = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wasCurrent) {
|
||||||
|
if (Perspective *parent = Perspective::findPerspective(perspective->d->m_parentPerspectiveId)) {
|
||||||
|
qCDebug(perspectivesLog) << "RAMPING UP PARENT PERSPECTIVE" << parent->id();
|
||||||
|
parent->rampUpAsCurrent();
|
||||||
|
} else {
|
||||||
|
qCDebug(perspectivesLog) << "RAMPED DOWN WAS ACTION, BUT NO PARENT AVAILABLE. TAKE FIRST BEST";
|
||||||
|
if (QTC_GUARD(!m_perspectives.isEmpty()))
|
||||||
|
m_perspectives.first()->rampUpAsCurrent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qCDebug(perspectivesLog) << "DESTROYED PERSPECTIVE" << perspective->id();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerMainWindow::showStatusMessage(const QString &message, int timeoutMS)
|
void DebuggerMainWindow::showStatusMessage(const QString &message, int timeoutMS)
|
||||||
@@ -309,36 +386,122 @@ void DebuggerMainWindow::showStatusMessage(const QString &message, int timeoutMS
|
|||||||
void DebuggerMainWindow::enterDebugMode()
|
void DebuggerMainWindow::enterDebugMode()
|
||||||
{
|
{
|
||||||
theMainWindow->setDockActionsVisible(true);
|
theMainWindow->setDockActionsVisible(true);
|
||||||
Perspective *perspective = theMainWindow->d->m_currentPerspective;
|
theMainWindow->restorePersistentSettings();
|
||||||
if (!perspective) {
|
QTC_CHECK(theMainWindow->d->m_currentPerspective == nullptr);
|
||||||
const QSettings *settings = ICore::settings();
|
|
||||||
const QString lastPerspectiveId = settings->value(LAST_PERSPECTIVE_KEY).toString();
|
QSettings *settings = ICore::settings();
|
||||||
perspective = Perspective::findPerspective(lastPerspectiveId);
|
const QString lastPerspectiveId = settings->value(LAST_PERSPECTIVE_KEY).toString();
|
||||||
// If we don't find a perspective with the stored name, pick any.
|
Perspective *perspective = Perspective::findPerspective(lastPerspectiveId);
|
||||||
// This can happen e.g. when a plugin was disabled that provided
|
// If we don't find a perspective with the stored name, pick any.
|
||||||
// the stored perspective, or when the save file was modified externally.
|
// This can happen e.g. when a plugin was disabled that provided
|
||||||
if (!perspective && !theMainWindow->d->m_perspectives.isEmpty())
|
// the stored perspective, or when the save file was modified externally.
|
||||||
perspective = theMainWindow->d->m_perspectives.first();
|
if (!perspective && !theMainWindow->d->m_perspectives.isEmpty())
|
||||||
}
|
perspective = theMainWindow->d->m_perspectives.first();
|
||||||
|
|
||||||
// There's at least the debugger preset perspective that should be found above.
|
// There's at least the debugger preset perspective that should be found above.
|
||||||
QTC_ASSERT(perspective, return);
|
QTC_ASSERT(perspective, return);
|
||||||
perspective->select();
|
|
||||||
|
if (auto sub = Perspective::findPerspective(perspective->d->m_lastActiveSubPerspectiveId)) {
|
||||||
|
qCDebug(perspectivesLog) << "SWITCHING TO SUBPERSPECTIVE" << sub->d->m_id;
|
||||||
|
perspective = sub;
|
||||||
|
}
|
||||||
|
|
||||||
|
perspective->rampUpAsCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerMainWindow::leaveDebugMode()
|
void DebuggerMainWindow::leaveDebugMode()
|
||||||
{
|
{
|
||||||
if (Perspective *perspective = theMainWindow->d->m_currentPerspective)
|
theMainWindow->savePersistentSettings();
|
||||||
perspective->d->saveLayout();
|
|
||||||
|
if (theMainWindow->d->m_currentPerspective)
|
||||||
|
theMainWindow->d->m_currentPerspective->rampDownAsCurrent();
|
||||||
|
QTC_CHECK(theMainWindow->d->m_currentPerspective == nullptr);
|
||||||
|
|
||||||
theMainWindow->setDockActionsVisible(false);
|
theMainWindow->setDockActionsVisible(false);
|
||||||
|
|
||||||
// Hide dock widgets manually in case they are floating.
|
// Hide dock widgets manually in case they are floating.
|
||||||
for (QDockWidget *dockWidget : theMainWindow->dockWidgets()) {
|
for (QDockWidget *dockWidget : theMainWindow->dockWidgets()) {
|
||||||
if (dockWidget->isFloating())
|
if (dockWidget->isFloating())
|
||||||
dockWidget->hide();
|
dockWidget->setVisible(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DebuggerMainWindow::restorePersistentSettings()
|
||||||
|
{
|
||||||
|
qCDebug(perspectivesLog) << "RESTORE PERSISTENT";
|
||||||
|
QSettings *settings = ICore::settings();
|
||||||
|
settings->beginGroup(MAINWINDOW_KEY);
|
||||||
|
const bool res = theMainWindow->restoreState(settings->value(STATE_KEY).toByteArray(),
|
||||||
|
SettingsVersion);
|
||||||
|
if (!res)
|
||||||
|
qCDebug(perspectivesLog) << "NO READABLE PERSISTENT SETTINGS FOUND, ASSUMING NEW CLEAN SETTINGS";
|
||||||
|
|
||||||
|
theMainWindow->setAutoHideTitleBars(settings->value(AUTOHIDE_TITLEBARS_KEY, true).toBool());
|
||||||
|
theMainWindow->showCentralWidget(settings->value(SHOW_CENTRALWIDGET_KEY, true).toBool());
|
||||||
|
theMainWindow->d->m_persistentChangedDocks
|
||||||
|
= QSet<QString>::fromList(settings->value(CHANGED_DOCK_KEY).toStringList());
|
||||||
|
settings->endGroup();
|
||||||
|
|
||||||
|
qCDebug(perspectivesLog) << "LOADED DOCKS:" << theMainWindow->d->m_persistentChangedDocks;
|
||||||
|
|
||||||
|
for (Perspective *perspective : theMainWindow->d->m_perspectives) {
|
||||||
|
qCDebug(perspectivesLog) << "RESTORING PERSPECTIVE" << perspective->d->m_id;
|
||||||
|
for (DockOperation &op : perspective->d->m_dockOperations) {
|
||||||
|
if (op.operationType != Perspective::Raise) {
|
||||||
|
QTC_ASSERT(op.dock, continue);
|
||||||
|
QTC_ASSERT(op.widget, continue);
|
||||||
|
if (theMainWindow->d->m_persistentChangedDocks.contains(op.name())) {
|
||||||
|
qCDebug(perspectivesLog) << "DOCK " << op.name() << "*** UNUSUAL";
|
||||||
|
op.visibleByUser = !op.visibleByDefault;
|
||||||
|
} else {
|
||||||
|
qCDebug(perspectivesLog) << "DOCK " << op.name() << "NORMAL";
|
||||||
|
QTC_CHECK(op.visibleByUser == op.visibleByDefault);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Perspective *DebuggerMainWindow::currentPerspective()
|
||||||
|
{
|
||||||
|
return theMainWindow->d->m_currentPerspective;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebuggerMainWindow::savePersistentSettings()
|
||||||
|
{
|
||||||
|
// The current one might have active, non saved changes.
|
||||||
|
if (Perspective *perspective = theMainWindow->d->m_currentPerspective)
|
||||||
|
perspective->d->saveLayout();
|
||||||
|
|
||||||
|
qCDebug(perspectivesLog) << "SAVE PERSISTENT";
|
||||||
|
|
||||||
|
QSet<QString> changedDocks = theMainWindow->d->m_persistentChangedDocks;
|
||||||
|
for (Perspective *perspective : theMainWindow->d->m_perspectives) {
|
||||||
|
qCDebug(perspectivesLog) << "SAVE PERSPECTIVE" << perspective->d->m_id;
|
||||||
|
for (const DockOperation &op : perspective->d->m_dockOperations) {
|
||||||
|
if (op.operationType != Perspective::Raise) {
|
||||||
|
QTC_ASSERT(op.dock, continue);
|
||||||
|
QTC_ASSERT(op.widget, continue);
|
||||||
|
qCDebug(perspectivesLog) << "DOCK " << op.name() << "ACTIVE: " << op.visibleByUser;
|
||||||
|
if (op.visibleByUser != op.visibleByDefault)
|
||||||
|
changedDocks.insert(op.name());
|
||||||
|
else
|
||||||
|
changedDocks.remove(op.name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
theMainWindow->d->m_persistentChangedDocks = changedDocks;
|
||||||
|
qCDebug(perspectivesLog) << "CHANGED DOCKS:" << changedDocks;
|
||||||
|
|
||||||
|
QSettings *settings = ICore::settings();
|
||||||
|
settings->beginGroup(MAINWINDOW_KEY);
|
||||||
|
settings->setValue(CHANGED_DOCK_KEY, QStringList(changedDocks.toList()));
|
||||||
|
settings->setValue(STATE_KEY, theMainWindow->saveState(SettingsVersion));
|
||||||
|
settings->setValue(AUTOHIDE_TITLEBARS_KEY, theMainWindow->autoHideTitleBars());
|
||||||
|
settings->setValue(SHOW_CENTRALWIDGET_KEY, theMainWindow->isCentralWidgetShown());
|
||||||
|
settings->endGroup();
|
||||||
|
}
|
||||||
|
|
||||||
QWidget *DebuggerMainWindow::centralWidgetStack()
|
QWidget *DebuggerMainWindow::centralWidgetStack()
|
||||||
{
|
{
|
||||||
return theMainWindow ? theMainWindow->d->m_centralWidgetStack : nullptr;
|
return theMainWindow ? theMainWindow->d->m_centralWidgetStack : nullptr;
|
||||||
@@ -358,21 +521,95 @@ DebuggerMainWindow *DebuggerMainWindow::instance()
|
|||||||
|
|
||||||
Perspective *Perspective::findPerspective(const QString &perspectiveId)
|
Perspective *Perspective::findPerspective(const QString &perspectiveId)
|
||||||
{
|
{
|
||||||
return Utils::findOr(theMainWindow->d->m_perspectives, nullptr, [&](Perspective *perspective) {
|
QTC_ASSERT(theMainWindow, return nullptr);
|
||||||
return perspective->d->m_id == perspectiveId;
|
return Utils::findOr(theMainWindow->d->m_perspectives, nullptr,
|
||||||
|
[perspectiveId](Perspective *perspective) {
|
||||||
|
return perspective && perspective->d->m_id == perspectiveId;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Perspective::isCurrent() const
|
||||||
|
{
|
||||||
|
return theMainWindow->d->m_currentPerspective == this;
|
||||||
|
}
|
||||||
|
|
||||||
|
QDockWidget *DebuggerMainWindowPrivate::dockForWidget(QWidget *widget) const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(widget, return nullptr);
|
||||||
|
|
||||||
|
for (QDockWidget *dock : q->dockWidgets()) {
|
||||||
|
if (dock->widget() == widget)
|
||||||
|
return dock;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
void DebuggerMainWindowPrivate::resetCurrentPerspective()
|
void DebuggerMainWindowPrivate::resetCurrentPerspective()
|
||||||
{
|
{
|
||||||
if (m_currentPerspective) {
|
QTC_ASSERT(m_currentPerspective, return);
|
||||||
m_currentPerspective->d->m_nonPersistenSettings.clear();
|
cleanDocks();
|
||||||
m_currentPerspective->d->hideToolBar();
|
m_currentPerspective->d->resetPerspective();
|
||||||
|
setCentralWidget(m_currentPerspective->d->m_centralWidget);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebuggerMainWindowPrivate::setCentralWidget(QWidget *widget)
|
||||||
|
{
|
||||||
|
if (widget) {
|
||||||
|
m_centralWidgetStack->addWidget(widget);
|
||||||
|
q->showCentralWidgetAction()->setText(widget->windowTitle());
|
||||||
|
} else {
|
||||||
|
m_centralWidgetStack->addWidget(m_editorPlaceHolder);
|
||||||
|
q->showCentralWidgetAction()->setText(DebuggerMainWindow::tr("Editor"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerspectivePrivate::resetPerspective()
|
||||||
|
{
|
||||||
|
showInnerToolBar();
|
||||||
|
|
||||||
|
for (DockOperation &op : m_dockOperations) {
|
||||||
|
if (op.operationType == Perspective::Raise) {
|
||||||
|
QTC_ASSERT(op.dock, qCDebug(perspectivesLog) << op.name(); continue);
|
||||||
|
op.dock->raise();
|
||||||
|
} else {
|
||||||
|
op.setupLayout();
|
||||||
|
op.dock->setVisible(op.visibleByDefault);
|
||||||
|
qCDebug(perspectivesLog) << "SETTING " << op.name()
|
||||||
|
<< " TO ACTIVE: " << op.visibleByDefault;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DockOperation::setupLayout()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(widget, return);
|
||||||
|
QTC_ASSERT(operationType != Perspective::Raise, return);
|
||||||
|
QTC_ASSERT(dock, return);
|
||||||
|
|
||||||
|
QDockWidget *anchor = nullptr;
|
||||||
|
if (anchorWidget)
|
||||||
|
anchor = theMainWindow->d->dockForWidget(anchorWidget);
|
||||||
|
else if (area == Qt::BottomDockWidgetArea)
|
||||||
|
anchor = theMainWindow->d->m_toolBarDock;
|
||||||
|
|
||||||
|
if (anchor) {
|
||||||
|
switch (operationType) {
|
||||||
|
case Perspective::AddToTab:
|
||||||
|
theMainWindow->tabifyDockWidget(anchor, dock);
|
||||||
|
break;
|
||||||
|
case Perspective::SplitHorizontal:
|
||||||
|
theMainWindow->splitDockWidget(anchor, dock, Qt::Horizontal);
|
||||||
|
break;
|
||||||
|
case Perspective::SplitVertical:
|
||||||
|
theMainWindow->splitDockWidget(anchor, dock, Qt::Vertical);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
theMainWindow->addDockWidget(area, dock);
|
||||||
}
|
}
|
||||||
depopulateCurrentPerspective();
|
|
||||||
populateCurrentPerspective();
|
|
||||||
if (m_currentPerspective)
|
|
||||||
m_currentPerspective->d->saveLayout();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int DebuggerMainWindowPrivate::indexInChooser(Perspective *perspective) const
|
int DebuggerMainWindowPrivate::indexInChooser(Perspective *perspective) const
|
||||||
@@ -380,47 +617,6 @@ int DebuggerMainWindowPrivate::indexInChooser(Perspective *perspective) const
|
|||||||
return perspective ? m_perspectiveChooser->findData(perspective->d->m_id) : -1;
|
return perspective ? m_perspectiveChooser->findData(perspective->d->m_id) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerMainWindowPrivate::fixupLayoutIfNeeded()
|
|
||||||
{
|
|
||||||
// Evil workaround for QTCREATORBUG-21455: In some so far unknown situation
|
|
||||||
// the saveLayout/restoreLayout process leads to a situation where some docks
|
|
||||||
// do not end up below the perspective toolbar even though they were there
|
|
||||||
// initially, leading to an awkward dock layout.
|
|
||||||
// This here tries to detect the situation (sonmething else in the bottom
|
|
||||||
// area is at the right of the toolbar) "corrects" that by restoring the
|
|
||||||
// default layout.
|
|
||||||
|
|
||||||
if (m_toolBarDock->width() != q->width()) {
|
|
||||||
qDebug() << "Scrambled dock layout found. Resetting it.";
|
|
||||||
resetCurrentPerspective();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerMainWindowPrivate::selectPerspective(Perspective *perspective)
|
|
||||||
{
|
|
||||||
QTC_ASSERT(perspective, return);
|
|
||||||
|
|
||||||
if (m_currentPerspective) {
|
|
||||||
m_currentPerspective->d->saveLayout();
|
|
||||||
m_currentPerspective->d->hideToolBar();
|
|
||||||
}
|
|
||||||
|
|
||||||
depopulateCurrentPerspective();
|
|
||||||
|
|
||||||
m_currentPerspective = perspective;
|
|
||||||
|
|
||||||
perspective->aboutToActivate();
|
|
||||||
|
|
||||||
populateCurrentPerspective();
|
|
||||||
|
|
||||||
if (m_currentPerspective) {
|
|
||||||
m_currentPerspective->d->restoreLayout();
|
|
||||||
fixupLayoutIfNeeded();
|
|
||||||
}
|
|
||||||
|
|
||||||
updatePerspectiveChooserWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DebuggerMainWindowPrivate::updatePerspectiveChooserWidth()
|
void DebuggerMainWindowPrivate::updatePerspectiveChooserWidth()
|
||||||
{
|
{
|
||||||
Perspective *perspective = m_currentPerspective;
|
Perspective *perspective = m_currentPerspective;
|
||||||
@@ -445,111 +641,72 @@ void DebuggerMainWindowPrivate::updatePerspectiveChooserWidth()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerMainWindowPrivate::depopulateCurrentPerspective()
|
void DebuggerMainWindowPrivate::cleanDocks()
|
||||||
{
|
{
|
||||||
// Clean up old perspective.
|
m_statusLabel->clear();
|
||||||
for (QDockWidget *dock : q->dockWidgets()) {
|
|
||||||
if (dock->property(OWNED_BY_PERSPECTIVE).toBool()) {
|
|
||||||
// Prevent deletion of plugin-owned widgets.
|
|
||||||
if (dock->widget())
|
|
||||||
dock->widget()->setParent(nullptr);
|
|
||||||
ActionManager::unregisterAction(dock->toggleViewAction(),
|
|
||||||
Id("Dock.").withSuffix(dock->objectName()));
|
|
||||||
delete dock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_currentPerspective) {
|
for (QDockWidget *dock : q->dockWidgets()) {
|
||||||
ICore::removeAdditionalContext(m_currentPerspective->context());
|
if (dock != m_toolBarDock)
|
||||||
QWidget *central = m_currentPerspective->centralWidget();
|
dock->setVisible(false);
|
||||||
m_centralWidgetStack->removeWidget(central ? central : m_editorPlaceHolder);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerMainWindowPrivate::populateCurrentPerspective()
|
void PerspectivePrivate::depopulatePerspective()
|
||||||
{
|
{
|
||||||
// Create dock widgets wrapping ther perspective's widgets.
|
ICore::removeAdditionalContext(context());
|
||||||
QHash<QString, QDockWidget *> dockForDockId;
|
theMainWindow->d->m_centralWidgetStack
|
||||||
for (const DockOperation &op : m_currentPerspective->d->m_dockOperations) {
|
->removeWidget(m_centralWidget ? m_centralWidget : theMainWindow->d->m_editorPlaceHolder);
|
||||||
if (op.operationType == Perspective::Raise)
|
|
||||||
continue;
|
|
||||||
QTC_ASSERT(op.widget, continue);
|
|
||||||
const QString dockId = op.widget->objectName();
|
|
||||||
QTC_CHECK(!dockId.isEmpty());
|
|
||||||
QTC_ASSERT(!dockForDockId.contains(dockId), continue);
|
|
||||||
QDockWidget *dock = q->addDockForWidget(op.widget);
|
|
||||||
dock->setProperty(OWNED_BY_PERSPECTIVE, true);
|
|
||||||
dockForDockId[dockId] = dock;
|
|
||||||
q->addDockWidget(op.area, dock);
|
|
||||||
|
|
||||||
QAction *toggleViewAction = dock->toggleViewAction();
|
theMainWindow->d->m_statusLabel->clear();
|
||||||
toggleViewAction->setText(dock->windowTitle());
|
|
||||||
|
|
||||||
Command *cmd = ActionManager::registerAction(toggleViewAction,
|
for (QDockWidget *dock : theMainWindow->dockWidgets()) {
|
||||||
Id("Dock.").withSuffix(dock->objectName()),
|
if (dock != theMainWindow->d->m_toolBarDock)
|
||||||
m_currentPerspective->context());
|
dock->setVisible(false);
|
||||||
cmd->setAttribute(Command::CA_Hide);
|
|
||||||
ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS)->addAction(cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_currentPerspective->d->showToolBar();
|
hideInnerToolBar();
|
||||||
|
}
|
||||||
|
|
||||||
// Pre-arrange dock widgets.
|
void PerspectivePrivate::saveAsLastUsedPerspective()
|
||||||
for (const DockOperation &op : m_currentPerspective->d->m_dockOperations) {
|
{
|
||||||
QTC_ASSERT(op.widget, continue);
|
if (Perspective *parent = Perspective::findPerspective(m_parentPerspectiveId))
|
||||||
const QString dockId = op.widget->objectName();
|
parent->d->m_lastActiveSubPerspectiveId = m_id;
|
||||||
QDockWidget *dock = dockForDockId.value(dockId);
|
else
|
||||||
QTC_ASSERT(dock, continue);
|
m_lastActiveSubPerspectiveId.clear();
|
||||||
if (op.operationType == Perspective::Raise) {
|
|
||||||
dock->raise();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
QDockWidget *anchor = dockForDockId.value(op.anchorDockId);
|
|
||||||
if (!anchor && op.area == Qt::BottomDockWidgetArea) {
|
|
||||||
anchor = m_toolBarDock;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (anchor) {
|
const QString &lastKey = m_parentPerspectiveId.isEmpty() ? m_id : m_parentPerspectiveId;
|
||||||
switch (op.operationType) {
|
qCDebug(perspectivesLog) << "SAVE LAST USED PERSPECTIVE" << lastKey;
|
||||||
case Perspective::AddToTab:
|
ICore::settings()->setValue(LAST_PERSPECTIVE_KEY, lastKey);
|
||||||
q->tabifyDockWidget(anchor, dock);
|
}
|
||||||
break;
|
|
||||||
case Perspective::SplitHorizontal:
|
void PerspectivePrivate::populatePerspective()
|
||||||
q->splitDockWidget(anchor, dock, Qt::Horizontal);
|
{
|
||||||
break;
|
showInnerToolBar();
|
||||||
case Perspective::SplitVertical:
|
|
||||||
q->splitDockWidget(anchor, dock, Qt::Vertical);
|
if (m_centralWidget) {
|
||||||
break;
|
theMainWindow->d->m_centralWidgetStack->addWidget(m_centralWidget);
|
||||||
default:
|
theMainWindow->showCentralWidgetAction()->setText(m_centralWidget->windowTitle());
|
||||||
break;
|
} else {
|
||||||
}
|
theMainWindow->d->m_centralWidgetStack->addWidget(theMainWindow->d->m_editorPlaceHolder);
|
||||||
}
|
theMainWindow->showCentralWidgetAction()->setText(DebuggerMainWindow::tr("Editor"));
|
||||||
dock->setVisible(op.visibleByDefault);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *central = m_currentPerspective->centralWidget();
|
ICore::addAdditionalContext(context());
|
||||||
m_centralWidgetStack->addWidget(central ? central : m_editorPlaceHolder);
|
|
||||||
q->showCentralWidgetAction()->setText(central ? central->windowTitle()
|
|
||||||
: DebuggerMainWindow::tr("Editor"));
|
|
||||||
|
|
||||||
m_statusLabel->clear();
|
restoreLayout();
|
||||||
|
|
||||||
ICore::addAdditionalContext(m_currentPerspective->context());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perspective
|
// Perspective
|
||||||
|
|
||||||
Perspective::Perspective(const QString &id, const QString &name,
|
Perspective::Perspective(const QString &id, const QString &name,
|
||||||
const QString &parentPerspectiveId,
|
const QString &parentPerspectiveId,
|
||||||
const QString &subPerspectiveType)
|
const QString &settingsId)
|
||||||
: d(new PerspectivePrivate)
|
: d(new PerspectivePrivate)
|
||||||
{
|
{
|
||||||
const bool shouldPersist = parentPerspectiveId.isEmpty();
|
|
||||||
d->m_id = id;
|
d->m_id = id;
|
||||||
d->m_name = name;
|
d->m_name = name;
|
||||||
d->m_parentPerspectiveId = parentPerspectiveId;
|
d->m_parentPerspectiveId = parentPerspectiveId;
|
||||||
d->m_subPerspectiveType = subPerspectiveType;
|
d->m_settingsId = settingsId;
|
||||||
d->m_shouldPersistChecker = [shouldPersist] { return shouldPersist; };
|
|
||||||
|
|
||||||
DebuggerMainWindow::ensureMainWindowExists();
|
DebuggerMainWindow::ensureMainWindowExists();
|
||||||
theMainWindow->d->registerPerspective(this);
|
theMainWindow->d->registerPerspective(this);
|
||||||
@@ -566,12 +723,8 @@ Perspective::Perspective(const QString &id, const QString &name,
|
|||||||
Perspective::~Perspective()
|
Perspective::~Perspective()
|
||||||
{
|
{
|
||||||
if (theMainWindow) {
|
if (theMainWindow) {
|
||||||
d->saveLayout();
|
|
||||||
|
|
||||||
delete d->m_innerToolBar;
|
delete d->m_innerToolBar;
|
||||||
d->m_innerToolBar = nullptr;
|
d->m_innerToolBar = nullptr;
|
||||||
|
|
||||||
theMainWindow->d->destroyPerspective(this);
|
|
||||||
}
|
}
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
@@ -597,12 +750,6 @@ void Perspective::setAboutToActivateCallback(const Perspective::Callback &cb)
|
|||||||
d->m_aboutToActivateCallback = cb;
|
d->m_aboutToActivateCallback = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perspective::aboutToActivate() const
|
|
||||||
{
|
|
||||||
if (d->m_aboutToActivateCallback)
|
|
||||||
d->m_aboutToActivateCallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Perspective::setEnabled(bool enabled)
|
void Perspective::setEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(theMainWindow, return);
|
QTC_ASSERT(theMainWindow, return);
|
||||||
@@ -655,34 +802,24 @@ void Perspective::addToolbarSeparator()
|
|||||||
d->m_innerToolBarLayout->addWidget(new StyledSeparator(d->m_innerToolBar));
|
d->m_innerToolBarLayout->addWidget(new StyledSeparator(d->m_innerToolBar));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perspective::setShouldPersistChecker(const ShouldPersistChecker &checker)
|
|
||||||
{
|
|
||||||
d->m_shouldPersistChecker = checker;
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget *Perspective::centralWidget() const
|
QWidget *Perspective::centralWidget() const
|
||||||
{
|
{
|
||||||
return d->m_centralWidget;
|
return d->m_centralWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
Perspective *Perspective::currentPerspective()
|
Context PerspectivePrivate::context() const
|
||||||
{
|
{
|
||||||
return theMainWindow ? theMainWindow->d->m_currentPerspective : nullptr;
|
return Context(Id::fromName(m_id.toUtf8()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Context Perspective::context() const
|
void PerspectivePrivate::showInnerToolBar()
|
||||||
{
|
|
||||||
return Context(Id::fromName(d->m_id.toUtf8()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PerspectivePrivate::showToolBar()
|
|
||||||
{
|
{
|
||||||
m_innerToolBar->setVisible(true);
|
m_innerToolBar->setVisible(true);
|
||||||
if (m_switcher)
|
if (m_switcher)
|
||||||
m_switcher->setVisible(true);
|
m_switcher->setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerspectivePrivate::hideToolBar()
|
void PerspectivePrivate::hideInnerToolBar()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(m_innerToolBar, return);
|
QTC_ASSERT(m_innerToolBar, return);
|
||||||
m_innerToolBar->setVisible(false);
|
m_innerToolBar->setVisible(false);
|
||||||
@@ -699,63 +836,131 @@ void Perspective::addWindow(QWidget *widget,
|
|||||||
QTC_ASSERT(widget, return);
|
QTC_ASSERT(widget, return);
|
||||||
DockOperation op;
|
DockOperation op;
|
||||||
op.widget = widget;
|
op.widget = widget;
|
||||||
if (anchorWidget)
|
|
||||||
op.anchorDockId = anchorWidget->objectName();
|
|
||||||
op.operationType = type;
|
op.operationType = type;
|
||||||
|
op.anchorWidget = anchorWidget;
|
||||||
op.visibleByDefault = visibleByDefault;
|
op.visibleByDefault = visibleByDefault;
|
||||||
op.area = area;
|
op.area = area;
|
||||||
|
|
||||||
|
if (op.operationType != Perspective::Raise) {
|
||||||
|
qCDebug(perspectivesLog) << "CREATING DOCK " << op.name()
|
||||||
|
<< "DEFAULT: " << op.visibleByDefault;
|
||||||
|
op.dock = theMainWindow->addDockForWidget(op.widget);
|
||||||
|
op.commandId = Id("Dock.").withSuffix(op.name());
|
||||||
|
if (theMainWindow->restoreDockWidget(op.dock)) {
|
||||||
|
qCDebug(perspectivesLog) << "RESTORED SUCCESSFULLY";
|
||||||
|
} else {
|
||||||
|
qCDebug(perspectivesLog) << "COULD NOT RESTORE";
|
||||||
|
op.setupLayout();
|
||||||
|
}
|
||||||
|
op.dock->setVisible(false);
|
||||||
|
op.dock->toggleViewAction()->setText(op.dock->windowTitle());
|
||||||
|
|
||||||
|
QObject::connect(op.dock->toggleViewAction(), &QAction::changed, op.dock, [this, op] {
|
||||||
|
qCDebug(perspectivesLog) << "CHANGED: " << op.name()
|
||||||
|
<< "ACTION CHECKED: " << op.dock->toggleViewAction()->isChecked();
|
||||||
|
});
|
||||||
|
|
||||||
|
Command *cmd = ActionManager::registerAction(op.dock->toggleViewAction(),
|
||||||
|
op.commandId, d->context());
|
||||||
|
cmd->setAttribute(Command::CA_Hide);
|
||||||
|
ActionManager::actionContainer(Core::Constants::M_WINDOW_VIEWS)->addAction(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
op.visibleByUser = op.visibleByDefault;
|
||||||
|
if (theMainWindow->d->m_persistentChangedDocks.contains(op.name())) {
|
||||||
|
op.visibleByUser = !op.visibleByUser;
|
||||||
|
qCDebug(perspectivesLog) << "*** NON-DEFAULT USER: " << op.visibleByUser;
|
||||||
|
} else {
|
||||||
|
qCDebug(perspectivesLog) << "DEFAULT USER";
|
||||||
|
}
|
||||||
|
|
||||||
d->m_dockOperations.append(op);
|
d->m_dockOperations.append(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Perspective::destroy()
|
||||||
|
{
|
||||||
|
theMainWindow->d->destroyPerspective(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Perspective::rampDownAsCurrent()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(this == theMainWindow->d->m_currentPerspective, return);
|
||||||
|
d->saveLayout();
|
||||||
|
d->depopulatePerspective();
|
||||||
|
theMainWindow->d->setCurrentPerspective(nullptr);
|
||||||
|
|
||||||
|
Debugger::Internal::EngineManager::updatePerspectives();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Perspective::rampUpAsCurrent()
|
||||||
|
{
|
||||||
|
if (d->m_aboutToActivateCallback)
|
||||||
|
d->m_aboutToActivateCallback();
|
||||||
|
|
||||||
|
QTC_ASSERT(theMainWindow->d->m_currentPerspective == nullptr, return);
|
||||||
|
theMainWindow->d->setCurrentPerspective(this);
|
||||||
|
QTC_ASSERT(theMainWindow->d->m_currentPerspective == this, return);
|
||||||
|
|
||||||
|
d->populatePerspective();
|
||||||
|
|
||||||
|
theMainWindow->d->updatePerspectiveChooserWidth();
|
||||||
|
|
||||||
|
d->saveAsLastUsedPerspective();
|
||||||
|
|
||||||
|
Debugger::Internal::EngineManager::updatePerspectives();
|
||||||
|
}
|
||||||
|
|
||||||
void Perspective::select()
|
void Perspective::select()
|
||||||
{
|
{
|
||||||
Debugger::Internal::EngineManager::activateDebugMode();
|
Debugger::Internal::EngineManager::activateDebugMode();
|
||||||
if (Perspective::currentPerspective() == this)
|
|
||||||
return;
|
|
||||||
theMainWindow->d->selectPerspective(this);
|
|
||||||
if (Perspective *parent = Perspective::findPerspective(d->m_parentPerspectiveId))
|
|
||||||
parent->d->m_lastActiveSubPerspectiveId = d->m_id;
|
|
||||||
else
|
|
||||||
d->m_lastActiveSubPerspectiveId.clear();
|
|
||||||
|
|
||||||
const QString &lastKey = d->m_parentPerspectiveId.isEmpty() ? d->m_id : d->m_parentPerspectiveId;
|
if (theMainWindow->d->m_currentPerspective == this)
|
||||||
ICore::settings()->setValue(LAST_PERSPECTIVE_KEY, lastKey);
|
return;
|
||||||
|
|
||||||
|
if (theMainWindow->d->m_currentPerspective)
|
||||||
|
theMainWindow->d->m_currentPerspective->rampDownAsCurrent();
|
||||||
|
QTC_CHECK(theMainWindow->d->m_currentPerspective == nullptr);
|
||||||
|
|
||||||
|
rampUpAsCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerspectivePrivate::restoreLayout()
|
void PerspectivePrivate::restoreLayout()
|
||||||
{
|
{
|
||||||
if (m_nonPersistenSettings.isEmpty()) {
|
qCDebug(perspectivesLog) << "PERSPECTIVE" << m_id << "RESTORING LAYOUT FROM " << settingsId();
|
||||||
//qDebug() << "PERSPECTIVE" << m_id << "RESTORE PERSISTENT FROM " << settingsId();
|
for (DockOperation &op : m_dockOperations) {
|
||||||
QSettings *settings = ICore::settings();
|
if (op.operationType != Perspective::Raise) {
|
||||||
settings->beginGroup(settingsId());
|
QTC_ASSERT(op.dock, continue);
|
||||||
theMainWindow->restoreSettings(settings);
|
const bool active = op.visibleByUser;
|
||||||
settings->endGroup();
|
op.dock->toggleViewAction()->setChecked(active);
|
||||||
m_nonPersistenSettings = theMainWindow->saveSettings();
|
op.dock->setVisible(active);
|
||||||
} else {
|
qCDebug(perspectivesLog) << "RESTORE DOCK " << op.name() << "ACTIVE: " << active
|
||||||
//qDebug() << "PERSPECTIVE" << m_id << "RESTORE FROM LOCAL TEMP";
|
<< (active == op.visibleByDefault ? "DEFAULT USER" : "*** NON-DEFAULT USER");
|
||||||
theMainWindow->restoreSettings(m_nonPersistenSettings);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerspectivePrivate::saveLayout()
|
void PerspectivePrivate::saveLayout()
|
||||||
{
|
{
|
||||||
//qDebug() << "PERSPECTIVE" << m_id << "SAVE LOCAL TEMP";
|
qCDebug(perspectivesLog) << "PERSPECTIVE" << m_id << "SAVE LAYOUT TO " << settingsId();
|
||||||
m_nonPersistenSettings = theMainWindow->saveSettings();
|
for (DockOperation &op : m_dockOperations) {
|
||||||
|
if (op.operationType != Perspective::Raise) {
|
||||||
if (m_shouldPersistChecker()) {
|
QTC_ASSERT(op.dock, continue);
|
||||||
//qDebug() << "PERSPECTIVE" << m_id << "SAVE PERSISTENT TO " << settingsId();
|
QTC_ASSERT(op.widget, continue);
|
||||||
QSettings *settings = ICore::settings();
|
const bool active = op.dock->toggleViewAction()->isChecked();
|
||||||
settings->beginGroup(settingsId());
|
op.visibleByUser = active;
|
||||||
theMainWindow->saveSettings(settings);
|
if (active == op.visibleByDefault)
|
||||||
settings->endGroup();
|
theMainWindow->d->m_persistentChangedDocks.remove(op.name());
|
||||||
} else {
|
else
|
||||||
//qDebug() << "PERSPECTIVE" << m_id << "NOT PERSISTENT";
|
theMainWindow->d->m_persistentChangedDocks.insert(op.name());
|
||||||
|
qCDebug(perspectivesLog) << "SAVE DOCK " << op.name() << "ACTIVE: " << active
|
||||||
|
<< (active == op.visibleByDefault ? "DEFAULT USER" : "*** NON-DEFAULT USER");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PerspectivePrivate::settingsId() const
|
QString PerspectivePrivate::settingsId() const
|
||||||
{
|
{
|
||||||
return m_parentPerspectiveId.isEmpty() ? m_id : (m_parentPerspectiveId + '.' + m_subPerspectiveType);
|
return m_settingsId.isEmpty() ? m_id : m_settingsId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToolbarAction
|
// ToolbarAction
|
||||||
|
|||||||
@@ -59,12 +59,12 @@ public:
|
|||||||
QPointer<QToolButton> m_toolButton;
|
QPointer<QToolButton> m_toolButton;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DEBUGGER_EXPORT Perspective
|
class DEBUGGER_EXPORT Perspective : public QObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Perspective(const QString &id, const QString &name,
|
Perspective(const QString &id, const QString &name,
|
||||||
const QString &parentPerspectiveId = QString(),
|
const QString &parentPerspectiveId = QString(),
|
||||||
const QString &subPerspectiveType = QString());
|
const QString &settingId = QString());
|
||||||
~Perspective();
|
~Perspective();
|
||||||
|
|
||||||
enum OperationType { SplitVertical, SplitHorizontal, AddToTab, Raise };
|
enum OperationType { SplitVertical, SplitHorizontal, AddToTab, Raise };
|
||||||
@@ -92,26 +92,26 @@ public:
|
|||||||
|
|
||||||
using Callback = std::function<void()>;
|
using Callback = std::function<void()>;
|
||||||
void setAboutToActivateCallback(const Callback &cb);
|
void setAboutToActivateCallback(const Callback &cb);
|
||||||
void aboutToActivate() const;
|
|
||||||
|
|
||||||
void setEnabled(bool enabled);
|
void setEnabled(bool enabled);
|
||||||
|
|
||||||
void select();
|
void select();
|
||||||
|
void destroy();
|
||||||
|
|
||||||
static Perspective *currentPerspective();
|
|
||||||
static Perspective *findPerspective(const QString &perspectiveId);
|
static Perspective *findPerspective(const QString &perspectiveId);
|
||||||
|
|
||||||
Core::Context context() const;
|
bool isCurrent() const;
|
||||||
|
|
||||||
void showToolBar();
|
|
||||||
void hideToolBar();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void rampDownAsCurrent();
|
||||||
|
void rampUpAsCurrent();
|
||||||
|
|
||||||
Perspective(const Perspective &) = delete;
|
Perspective(const Perspective &) = delete;
|
||||||
void operator=(const Perspective &) = delete;
|
void operator=(const Perspective &) = delete;
|
||||||
|
|
||||||
friend class DebuggerMainWindow;
|
friend class DebuggerMainWindow;
|
||||||
friend class DebuggerMainWindowPrivate;
|
friend class DebuggerMainWindowPrivate;
|
||||||
|
friend class PerspectivePrivate;
|
||||||
class PerspectivePrivate *d = nullptr;
|
class PerspectivePrivate *d = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -132,12 +132,20 @@ public:
|
|||||||
static QWidget *centralWidgetStack();
|
static QWidget *centralWidgetStack();
|
||||||
void addSubPerspectiveSwitcher(QWidget *widget);
|
void addSubPerspectiveSwitcher(QWidget *widget);
|
||||||
|
|
||||||
|
static void savePersistentSettings();
|
||||||
|
static void restorePersistentSettings();
|
||||||
|
|
||||||
|
static Perspective *currentPerspective();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DebuggerMainWindow();
|
DebuggerMainWindow();
|
||||||
~DebuggerMainWindow() override;
|
~DebuggerMainWindow() override;
|
||||||
|
|
||||||
|
void contextMenuEvent(QContextMenuEvent *ev) override;
|
||||||
|
|
||||||
friend class Perspective;
|
friend class Perspective;
|
||||||
friend class PerspectivePrivate;
|
friend class PerspectivePrivate;
|
||||||
|
friend class DockOperation;
|
||||||
class DebuggerMainWindowPrivate *d = nullptr;
|
class DebuggerMainWindowPrivate *d = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1052,7 +1052,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
|
|||||||
m_breakpointManagerView->setSpanColumn(BreakpointFunctionColumn);
|
m_breakpointManagerView->setSpanColumn(BreakpointFunctionColumn);
|
||||||
m_breakpointManagerWindow = addSearch(m_breakpointManagerView);
|
m_breakpointManagerWindow = addSearch(m_breakpointManagerView);
|
||||||
m_breakpointManagerWindow->setWindowTitle(tr("Breakpoint Preset"));
|
m_breakpointManagerWindow->setWindowTitle(tr("Breakpoint Preset"));
|
||||||
m_breakpointManagerWindow->setObjectName(DOCKWIDGET_BREAKPOINTMANAGER);
|
m_breakpointManagerWindow->setObjectName("Debugger.Docks.BreakpointManager");
|
||||||
addLabel(m_breakpointManagerWindow, m_breakpointManagerWindow->windowTitle());
|
addLabel(m_breakpointManagerWindow, m_breakpointManagerWindow->windowTitle());
|
||||||
|
|
||||||
|
|
||||||
@@ -1064,7 +1064,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
|
|||||||
m_engineManagerView->setModel(m_engineManager.model());
|
m_engineManagerView->setModel(m_engineManager.model());
|
||||||
m_engineManagerWindow = addSearch(m_engineManagerView);
|
m_engineManagerWindow = addSearch(m_engineManagerView);
|
||||||
m_engineManagerWindow->setWindowTitle(tr("Debugger Perspectives"));
|
m_engineManagerWindow->setWindowTitle(tr("Debugger Perspectives"));
|
||||||
m_engineManagerWindow->setObjectName(DOCKWIDGET_ENGINEMANAGER);
|
m_engineManagerWindow->setObjectName("Debugger.Docks.Snapshots");
|
||||||
addLabel(m_engineManagerWindow, m_engineManagerWindow->windowTitle());
|
addLabel(m_engineManagerWindow, m_engineManagerWindow->windowTitle());
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
@@ -1366,7 +1366,8 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
|
|||||||
DebuggerMainWindow::leaveDebugMode();
|
DebuggerMainWindow::leaveDebugMode();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(ModeManager::instance(), &ModeManager::currentModeChanged, this, [](Id mode) {
|
connect(ModeManager::instance(), &ModeManager::currentModeChanged, [](Id mode, Id oldMode) {
|
||||||
|
QTC_ASSERT(mode != oldMode, return);
|
||||||
if (mode == MODE_DEBUG) {
|
if (mode == MODE_DEBUG) {
|
||||||
DebuggerMainWindow::enterDebugMode();
|
DebuggerMainWindow::enterDebugMode();
|
||||||
if (IEditor *editor = EditorManager::currentEditor())
|
if (IEditor *editor = EditorManager::currentEditor())
|
||||||
@@ -1531,7 +1532,7 @@ void DebuggerPluginPrivate::updatePresetState()
|
|||||||
} else {
|
} else {
|
||||||
// The startup phase should be over once we are here.
|
// The startup phase should be over once we are here.
|
||||||
// But treat it as 'undisturbable if we are here by accident.
|
// But treat it as 'undisturbable if we are here by accident.
|
||||||
QTC_CHECK(state != DebuggerNotReady);
|
//QTC_CHECK(state != DebuggerNotReady);
|
||||||
// Everything else is "undisturbable".
|
// Everything else is "undisturbable".
|
||||||
m_startAction.setEnabled(false);
|
m_startAction.setEnabled(false);
|
||||||
m_debugWithoutDeployAction.setEnabled(false);
|
m_debugWithoutDeployAction.setEnabled(false);
|
||||||
@@ -1569,7 +1570,7 @@ void DebuggerPluginPrivate::onStartupProjectChanged(Project *project)
|
|||||||
}
|
}
|
||||||
for (DebuggerEngine *engine : EngineManager::engines()) {
|
for (DebuggerEngine *engine : EngineManager::engines()) {
|
||||||
// Run controls might be deleted during exit.
|
// Run controls might be deleted during exit.
|
||||||
engine->updateState(false);
|
engine->updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePresetState();
|
updatePresetState();
|
||||||
@@ -2022,11 +2023,9 @@ void DebuggerPluginPrivate::aboutToShutdown()
|
|||||||
m_shutdownTimer.setInterval(0);
|
m_shutdownTimer.setInterval(0);
|
||||||
m_shutdownTimer.setSingleShot(true);
|
m_shutdownTimer.setSingleShot(true);
|
||||||
connect(&m_shutdownTimer, &QTimer::timeout, this, &DebuggerPluginPrivate::doShutdown);
|
connect(&m_shutdownTimer, &QTimer::timeout, this, &DebuggerPluginPrivate::doShutdown);
|
||||||
for (DebuggerEngine *engine : m_engineManager.engines()) {
|
if (EngineManager::shutDown()) {
|
||||||
if (engine && engine->state() != Debugger::DebuggerNotReady) {
|
// If any engine is aborting we give them extra three seconds.
|
||||||
engine->abortDebugger();
|
m_shutdownTimer.setInterval(3000);
|
||||||
m_shutdownTimer.setInterval(3000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
m_shutdownTimer.start();
|
m_shutdownTimer.start();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -730,8 +730,6 @@ void DebuggerRunTool::stop()
|
|||||||
|
|
||||||
void DebuggerRunTool::handleEngineStarted(DebuggerEngine *engine)
|
void DebuggerRunTool::handleEngineStarted(DebuggerEngine *engine)
|
||||||
{
|
{
|
||||||
EngineManager::activateEngine(engine);
|
|
||||||
|
|
||||||
// Correct:
|
// Correct:
|
||||||
// if (--d->engineStartsNeeded == 0) {
|
// if (--d->engineStartsNeeded == 0) {
|
||||||
// EngineManager::activateDebugMode();
|
// EngineManager::activateDebugMode();
|
||||||
|
|||||||
@@ -155,16 +155,18 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
EngineItem *findEngineItem(DebuggerEngine *engine);
|
EngineItem *findEngineItem(DebuggerEngine *engine);
|
||||||
void activateEngine(DebuggerEngine *engine);
|
|
||||||
void activateEngineItem(EngineItem *engineItem);
|
void activateEngineItem(EngineItem *engineItem);
|
||||||
void activateEngineByIndex(int index);
|
void activateEngineByIndex(int index);
|
||||||
void selectUiForCurrentEngine();
|
void selectUiForCurrentEngine();
|
||||||
void updateEngineChooserVisibility();
|
void updateEngineChooserVisibility();
|
||||||
|
void updatePerspectives();
|
||||||
|
|
||||||
TreeModel<TypedTreeItem<EngineItem>, EngineItem> m_engineModel;
|
TreeModel<TypedTreeItem<EngineItem>, EngineItem> m_engineModel;
|
||||||
QPointer<EngineItem> m_currentItem;
|
QPointer<EngineItem> m_currentItem; // The primary information is DebuggerMainWindow::d->m_currentPerspective
|
||||||
Core::Id m_previousMode;
|
Core::Id m_previousMode;
|
||||||
QPointer<QComboBox> m_engineChooser;
|
QPointer<QComboBox> m_engineChooser;
|
||||||
|
bool m_shuttingDown = false;
|
||||||
|
Context m_currentAdditionalContext;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
@@ -192,6 +194,11 @@ QWidget *EngineManager::engineChooser()
|
|||||||
return d->m_engineChooser;
|
return d->m_engineChooser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EngineManager::updatePerspectives()
|
||||||
|
{
|
||||||
|
d->updatePerspectives();
|
||||||
|
}
|
||||||
|
|
||||||
EngineManager::~EngineManager()
|
EngineManager::~EngineManager()
|
||||||
{
|
{
|
||||||
theEngineManager = nullptr;
|
theEngineManager = nullptr;
|
||||||
@@ -208,11 +215,6 @@ QAbstractItemModel *EngineManager::model()
|
|||||||
return &d->m_engineModel;
|
return &d->m_engineModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EngineManager::activateEngine(DebuggerEngine *engine)
|
|
||||||
{
|
|
||||||
d->activateEngine(engine);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant EngineItem::data(int column, int role) const
|
QVariant EngineItem::data(int column, int role) const
|
||||||
{
|
{
|
||||||
if (m_engine) {
|
if (m_engine) {
|
||||||
@@ -273,7 +275,7 @@ bool EngineItem::setData(int row, const QVariant &value, int role)
|
|||||||
|
|
||||||
if (role == BaseTreeView::ItemActivatedRole) {
|
if (role == BaseTreeView::ItemActivatedRole) {
|
||||||
EngineItem *engineItem = d->findEngineItem(m_engine);
|
EngineItem *engineItem = d->findEngineItem(m_engine);
|
||||||
d->activateEngineItem(engineItem);
|
d->activateEngineByIndex(engineItem->indexInParent());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,21 +318,27 @@ bool EngineItem::setData(int row, const QVariant &value, int role)
|
|||||||
|
|
||||||
void EngineManagerPrivate::activateEngineByIndex(int index)
|
void EngineManagerPrivate::activateEngineByIndex(int index)
|
||||||
{
|
{
|
||||||
activateEngineItem(m_engineModel.rootItem()->childAt(index));
|
// The actual activation is triggered indirectly via the perspective change.
|
||||||
|
Perspective *perspective = nullptr;
|
||||||
|
if (index == 0) {
|
||||||
|
perspective = Perspective::findPerspective(Debugger::Constants::PRESET_PERSPECTIVE_ID);
|
||||||
|
} else {
|
||||||
|
EngineItem *engineItem = m_engineModel.rootItem()->childAt(index);
|
||||||
|
QTC_ASSERT(engineItem, return);
|
||||||
|
QTC_ASSERT(engineItem->m_engine, return);
|
||||||
|
perspective = engineItem->m_engine->perspective();
|
||||||
|
}
|
||||||
|
|
||||||
|
QTC_ASSERT(perspective, return);
|
||||||
|
perspective->select();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EngineManagerPrivate::activateEngineItem(EngineItem *engineItem)
|
void EngineManagerPrivate::activateEngineItem(EngineItem *engineItem)
|
||||||
{
|
{
|
||||||
Context previousContext;
|
if (m_currentItem == engineItem)
|
||||||
if (m_currentItem) {
|
return;
|
||||||
if (DebuggerEngine *engine = m_currentItem->m_engine) {
|
|
||||||
previousContext.add(engine->languageContext());
|
|
||||||
previousContext.add(engine->debuggerContext());
|
|
||||||
} else {
|
|
||||||
previousContext.add(Context(Constants::C_DEBUGGER_NOTRUNNING));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
QTC_ASSERT(engineItem, return);
|
||||||
m_currentItem = engineItem;
|
m_currentItem = engineItem;
|
||||||
|
|
||||||
Context newContext;
|
Context newContext;
|
||||||
@@ -343,7 +351,13 @@ void EngineManagerPrivate::activateEngineItem(EngineItem *engineItem)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ICore::updateAdditionalContexts(previousContext, newContext);
|
ICore::updateAdditionalContexts(m_currentAdditionalContext, newContext);
|
||||||
|
m_currentAdditionalContext = newContext;
|
||||||
|
|
||||||
|
// In case this was triggered externally by some Perspective::select() call.
|
||||||
|
const int idx = engineItem->indexInParent();
|
||||||
|
m_engineChooser->setCurrentIndex(idx);
|
||||||
|
|
||||||
selectUiForCurrentEngine();
|
selectUiForCurrentEngine();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,12 +366,7 @@ void EngineManagerPrivate::selectUiForCurrentEngine()
|
|||||||
if (ModeManager::currentModeId() != Constants::MODE_DEBUG)
|
if (ModeManager::currentModeId() != Constants::MODE_DEBUG)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Perspective *perspective = nullptr;
|
|
||||||
int row = 0;
|
int row = 0;
|
||||||
|
|
||||||
if (m_currentItem && m_currentItem->m_engine)
|
|
||||||
perspective = m_currentItem->m_engine->perspective();
|
|
||||||
|
|
||||||
if (m_currentItem)
|
if (m_currentItem)
|
||||||
row = m_engineModel.rootItem()->indexOf(m_currentItem);
|
row = m_engineModel.rootItem()->indexOf(m_currentItem);
|
||||||
|
|
||||||
@@ -371,12 +380,6 @@ void EngineManagerPrivate::selectUiForCurrentEngine()
|
|||||||
QStyle::CT_ComboBox, &option, sz).width();
|
QStyle::CT_ComboBox, &option, sz).width();
|
||||||
m_engineChooser->setFixedWidth(width);
|
m_engineChooser->setFixedWidth(width);
|
||||||
|
|
||||||
if (!perspective)
|
|
||||||
perspective = Perspective::findPerspective(Debugger::Constants::PRESET_PERSPECTIVE_ID);
|
|
||||||
|
|
||||||
QTC_ASSERT(perspective, return);
|
|
||||||
perspective->select();
|
|
||||||
|
|
||||||
m_engineModel.rootItem()->forFirstLevelChildren([this](EngineItem *engineItem) {
|
m_engineModel.rootItem()->forFirstLevelChildren([this](EngineItem *engineItem) {
|
||||||
if (engineItem && engineItem->m_engine)
|
if (engineItem && engineItem->m_engine)
|
||||||
engineItem->m_engine->updateUi(engineItem == m_currentItem);
|
engineItem->m_engine->updateUi(engineItem == m_currentItem);
|
||||||
@@ -392,12 +395,6 @@ EngineItem *EngineManagerPrivate::findEngineItem(DebuggerEngine *engine)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void EngineManagerPrivate::activateEngine(DebuggerEngine *engine)
|
|
||||||
{
|
|
||||||
EngineItem *engineItem = findEngineItem(engine);
|
|
||||||
activateEngineItem(engineItem);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EngineManagerPrivate::updateEngineChooserVisibility()
|
void EngineManagerPrivate::updateEngineChooserVisibility()
|
||||||
{
|
{
|
||||||
// Show it if there's more than one option (i.e. not the preset engine only)
|
// Show it if there's more than one option (i.e. not the preset engine only)
|
||||||
@@ -407,12 +404,48 @@ void EngineManagerPrivate::updateEngineChooserVisibility()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EngineManager::registerEngine(DebuggerEngine *engine)
|
void EngineManagerPrivate::updatePerspectives()
|
||||||
|
{
|
||||||
|
d->updateEngineChooserVisibility();
|
||||||
|
|
||||||
|
Perspective *current = DebuggerMainWindow::currentPerspective();
|
||||||
|
if (!current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_engineModel.rootItem()->forFirstLevelChildren([this, current](EngineItem *engineItem) {
|
||||||
|
if (engineItem == m_currentItem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool shouldBeActive = false;
|
||||||
|
if (engineItem->m_engine) {
|
||||||
|
// Normal engine.
|
||||||
|
shouldBeActive = engineItem->m_engine->perspective()->isCurrent();
|
||||||
|
} else {
|
||||||
|
// Preset.
|
||||||
|
shouldBeActive = current->id() == Debugger::Constants::PRESET_PERSPECTIVE_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldBeActive && engineItem != m_currentItem)
|
||||||
|
activateEngineItem(engineItem);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
QString EngineManager::registerEngine(DebuggerEngine *engine)
|
||||||
{
|
{
|
||||||
auto engineItem = new EngineItem;
|
auto engineItem = new EngineItem;
|
||||||
engineItem->m_engine = engine;
|
engineItem->m_engine = engine;
|
||||||
d->m_engineModel.rootItem()->appendChild(engineItem);
|
d->m_engineModel.rootItem()->appendChild(engineItem);
|
||||||
d->updateEngineChooserVisibility();
|
d->updateEngineChooserVisibility();
|
||||||
|
return QString::number(d->m_engineModel.rootItem()->childCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
void EngineManager::unregisterEngine(DebuggerEngine *engine)
|
||||||
|
{
|
||||||
|
EngineItem *engineItem = d->findEngineItem(engine);
|
||||||
|
QTC_ASSERT(engineItem, return);
|
||||||
|
d->m_engineModel.destroyItem(engineItem);
|
||||||
|
d->updateEngineChooserVisibility();
|
||||||
}
|
}
|
||||||
|
|
||||||
void EngineManager::activateDebugMode()
|
void EngineManager::activateDebugMode()
|
||||||
@@ -435,33 +468,6 @@ void EngineManager::deactivateDebugMode()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EngineManager::isLastOf(const QString &type)
|
|
||||||
{
|
|
||||||
int count = 0;
|
|
||||||
d->m_engineModel.rootItem()->forFirstLevelChildren([&](EngineItem *engineItem) {
|
|
||||||
if (engineItem && engineItem->m_engine)
|
|
||||||
count += (engineItem->m_engine->debuggerName() == type);
|
|
||||||
});
|
|
||||||
return count == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EngineManager::unregisterEngine(DebuggerEngine *engine)
|
|
||||||
{
|
|
||||||
if (ModeManager::currentModeId() == Constants::MODE_DEBUG) {
|
|
||||||
if (Perspective *parent = Perspective::findPerspective(Constants::PRESET_PERSPECTIVE_ID))
|
|
||||||
parent->select();
|
|
||||||
}
|
|
||||||
|
|
||||||
d->activateEngineItem(d->m_engineModel.rootItem()->childAt(0)); // Preset.
|
|
||||||
|
|
||||||
// Could be that the run controls died before it was appended.
|
|
||||||
if (auto engineItem = d->findEngineItem(engine))
|
|
||||||
d->m_engineModel.destroyItem(engineItem);
|
|
||||||
|
|
||||||
d->updateEngineChooserVisibility();
|
|
||||||
emit theEngineManager->currentEngineChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<QPointer<DebuggerEngine>> EngineManager::engines()
|
QList<QPointer<DebuggerEngine>> EngineManager::engines()
|
||||||
{
|
{
|
||||||
QList<QPointer<DebuggerEngine>> result;
|
QList<QPointer<DebuggerEngine>> result;
|
||||||
@@ -477,5 +483,18 @@ QPointer<DebuggerEngine> EngineManager::currentEngine()
|
|||||||
return d->m_currentItem ? d->m_currentItem->m_engine : nullptr;
|
return d->m_currentItem ? d->m_currentItem->m_engine : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EngineManager::shutDown()
|
||||||
|
{
|
||||||
|
d->m_shuttingDown = true;
|
||||||
|
bool anyEngineAborting = false;
|
||||||
|
for (DebuggerEngine *engine : EngineManager::engines()) {
|
||||||
|
if (engine && engine->state() != Debugger::DebuggerNotReady) {
|
||||||
|
engine->abortDebugger();
|
||||||
|
anyEngineAborting = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return anyEngineAborting;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|||||||
@@ -45,17 +45,19 @@ public:
|
|||||||
static EngineManager *instance();
|
static EngineManager *instance();
|
||||||
static QAbstractItemModel *model();
|
static QAbstractItemModel *model();
|
||||||
|
|
||||||
static void registerEngine(DebuggerEngine *engine);
|
static QString registerEngine(DebuggerEngine *engine);
|
||||||
static void unregisterEngine(DebuggerEngine *engine);
|
static void unregisterEngine(DebuggerEngine *engine);
|
||||||
static void activateEngine(DebuggerEngine *engine);
|
|
||||||
static void activateDebugMode();
|
static void activateDebugMode();
|
||||||
static void deactivateDebugMode();
|
static void deactivateDebugMode();
|
||||||
static bool isLastOf(const QString &type);
|
|
||||||
|
|
||||||
static QList<QPointer<DebuggerEngine> > engines();
|
static QList<QPointer<DebuggerEngine> > engines();
|
||||||
static QPointer<DebuggerEngine> currentEngine();
|
static QPointer<DebuggerEngine> currentEngine();
|
||||||
|
|
||||||
static QWidget *engineChooser();
|
static QWidget *engineChooser();
|
||||||
|
static void updatePerspectives();
|
||||||
|
|
||||||
|
static bool shutDown(); // Return true if some engine is being forced to shut down.
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void engineStateChanged(DebuggerEngine *engine);
|
void engineStateChanged(DebuggerEngine *engine);
|
||||||
|
|||||||
@@ -2952,7 +2952,7 @@ void GdbEngine::handleThreadInfo(const DebuggerResponse &response)
|
|||||||
if (response.resultClass == ResultDone) {
|
if (response.resultClass == ResultDone) {
|
||||||
ThreadsHandler *handler = threadsHandler();
|
ThreadsHandler *handler = threadsHandler();
|
||||||
handler->setThreads(response.data);
|
handler->setThreads(response.data);
|
||||||
updateState(false); // Adjust Threads combobox.
|
updateState(); // Adjust Threads combobox.
|
||||||
if (boolSetting(ShowThreadNames)) {
|
if (boolSetting(ShowThreadNames)) {
|
||||||
runCommand({"threadnames " + action(MaximalStackDepth)->value().toString(),
|
runCommand({"threadnames " + action(MaximalStackDepth)->value().toString(),
|
||||||
Discardable, CB(handleThreadNames)});
|
Discardable, CB(handleThreadNames)});
|
||||||
@@ -2992,7 +2992,7 @@ void GdbEngine::handleThreadNames(const DebuggerResponse &response)
|
|||||||
thread.name = decodeData(name["value"].data(), name["valueencoded"].data());
|
thread.name = decodeData(name["value"].data(), name["valueencoded"].data());
|
||||||
handler->updateThread(thread);
|
handler->updateThread(thread);
|
||||||
}
|
}
|
||||||
updateState(false);
|
updateState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ public:
|
|||||||
|
|
||||||
bool ModulesModel::contextMenuEvent(const ItemViewEvent &ev)
|
bool ModulesModel::contextMenuEvent(const ItemViewEvent &ev)
|
||||||
{
|
{
|
||||||
ModuleItem *item = itemForIndexAtLevel<1>(ev.index());
|
ModuleItem *item = itemForIndexAtLevel<1>(ev.sourceModelIndex());
|
||||||
|
|
||||||
const bool enabled = engine->debuggerActionsEnabled();
|
const bool enabled = engine->debuggerActionsEnabled();
|
||||||
const bool canReload = engine->hasCapability(ReloadModuleCapability);
|
const bool canReload = engine->hasCapability(ReloadModuleCapability);
|
||||||
|
|||||||
@@ -679,8 +679,8 @@ bool RegisterHandler::contextMenuEvent(const ItemViewEvent &ev)
|
|||||||
const DebuggerState state = m_engine->state();
|
const DebuggerState state = m_engine->state();
|
||||||
const bool actionsEnabled = m_engine->debuggerActionsEnabled();
|
const bool actionsEnabled = m_engine->debuggerActionsEnabled();
|
||||||
|
|
||||||
RegisterItem *registerItem = itemForIndexAtLevel<1>(ev.index());
|
RegisterItem *registerItem = itemForIndexAtLevel<1>(ev.sourceModelIndex());
|
||||||
RegisterSubItem *registerSubItem = itemForIndexAtLevel<2>(ev.index());
|
RegisterSubItem *registerSubItem = itemForIndexAtLevel<2>(ev.sourceModelIndex());
|
||||||
|
|
||||||
const quint64 address = registerItem ? registerItem->addressValue() : 0;
|
const quint64 address = registerItem ? registerItem->addressValue() : 0;
|
||||||
const QString registerName = registerItem ? registerItem->m_reg.name : QString();
|
const QString registerName = registerItem ? registerItem->m_reg.name : QString();
|
||||||
|
|||||||
@@ -367,7 +367,7 @@ bool StackHandler::contextMenuEvent(const ItemViewEvent &ev)
|
|||||||
{
|
{
|
||||||
auto menu = new QMenu;
|
auto menu = new QMenu;
|
||||||
|
|
||||||
const int row = ev.index().row();
|
const int row = ev.sourceModelIndex().row();
|
||||||
StackFrame frame;
|
StackFrame frame;
|
||||||
if (row >= 0 && row < stackSize())
|
if (row >= 0 && row < stackSize())
|
||||||
frame = frameAt(row);
|
frame = frameAt(row);
|
||||||
|
|||||||
@@ -1638,7 +1638,7 @@ void WatchModel::inputNewExpression()
|
|||||||
|
|
||||||
bool WatchModel::contextMenuEvent(const ItemViewEvent &ev)
|
bool WatchModel::contextMenuEvent(const ItemViewEvent &ev)
|
||||||
{
|
{
|
||||||
WatchItem *item = itemForIndex(ev.index());
|
WatchItem *item = itemForIndex(ev.sourceModelIndex());
|
||||||
|
|
||||||
const QString exp = item ? item->expression() : QString();
|
const QString exp = item ? item->expression() : QString();
|
||||||
const QString name = item ? item->name : QString();
|
const QString name = item ? item->name : QString();
|
||||||
|
|||||||
@@ -756,10 +756,16 @@ void QbsProject::updateDocuments(const QSet<QString> &files)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
QSet<IDocument *> toAdd;
|
QSet<IDocument *> toAdd;
|
||||||
foreach (const QString &f, filesToAdd)
|
const FileName buildDir = FileName::fromString(m_projectData.buildDirectory());
|
||||||
toAdd.insert(new ProjectDocument(Constants::MIME_TYPE, FileName::fromString(f),
|
for (const QString &f : qAsConst(filesToAdd)) {
|
||||||
[this]() { delayParsing(); }));
|
// A changed qbs file (project, module etc) should trigger a re-parse, but not if
|
||||||
|
// the file was generated by qbs itself, in which case that might cause an infinite loop.
|
||||||
|
const FileName fp = FileName::fromString(f);
|
||||||
|
static const ProjectDocument::ProjectCallback noOpCallback = []{};
|
||||||
|
const ProjectDocument::ProjectCallback reparseCallback = [this]() { delayParsing(); };
|
||||||
|
toAdd.insert(new ProjectDocument(Constants::MIME_TYPE, fp, fp.isChildOf(buildDir)
|
||||||
|
? noOpCallback : reparseCallback));
|
||||||
|
}
|
||||||
m_qbsDocuments.unite(toAdd);
|
m_qbsDocuments.unite(toAdd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -166,6 +166,7 @@ QMakeStepConfig QMakeStep::deducedArguments() const
|
|||||||
|
|
||||||
bool QMakeStep::init()
|
bool QMakeStep::init()
|
||||||
{
|
{
|
||||||
|
m_wasSuccess = true;
|
||||||
QmakeBuildConfiguration *qmakeBc = qmakeBuildConfiguration();
|
QmakeBuildConfiguration *qmakeBc = qmakeBuildConfiguration();
|
||||||
const BaseQtVersion *qtVersion = QtKitAspect::qtVersion(target()->kit());
|
const BaseQtVersion *qtVersion = QtKitAspect::qtVersion(target()->kit());
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,8 @@ QPixmap QmlDesignerIconProvider::getPixmap(const QString &id)
|
|||||||
else if (id == "plus")
|
else if (id == "plus")
|
||||||
result = Utils::Icons::PLUS_TOOLBAR.pixmap();
|
result = Utils::Icons::PLUS_TOOLBAR.pixmap();
|
||||||
else if (id == "expression")
|
else if (id == "expression")
|
||||||
result = Icon(iconPath() + "expression.png").pixmap();
|
result = Icon({
|
||||||
|
{ iconPath() + QLatin1String("expression.png"), Theme::QmlDesigner_HighlightColor}}).pixmap();
|
||||||
else if (id == "placeholder")
|
else if (id == "placeholder")
|
||||||
result = Icon(iconPath() + "placeholder.png").pixmap();
|
result = Icon(iconPath() + "placeholder.png").pixmap();
|
||||||
else if (id == "submenu")
|
else if (id == "submenu")
|
||||||
|
|||||||
@@ -28,6 +28,8 @@
|
|||||||
#include <qmlanchors.h>
|
#include <qmlanchors.h>
|
||||||
#include <nodeabstractproperty.h>
|
#include <nodeabstractproperty.h>
|
||||||
#include <variantproperty.h>
|
#include <variantproperty.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
|
||||||
#include <QtQml>
|
#include <QtQml>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
@@ -108,13 +110,18 @@ void QmlAnchorBindingProxy::invalidate(const QmlItemNode &fxItemNode)
|
|||||||
|
|
||||||
m_ignoreQml = true;
|
m_ignoreQml = true;
|
||||||
|
|
||||||
|
auto parentModelNode = [](const QmlItemNode &node) {
|
||||||
|
QTC_ASSERT(node.modelNode().hasParentProperty(), return ModelNode());
|
||||||
|
return node.modelNode().parentProperty().parentModelNode();
|
||||||
|
};
|
||||||
|
|
||||||
m_verticalTarget =
|
m_verticalTarget =
|
||||||
m_horizontalTarget =
|
m_horizontalTarget =
|
||||||
m_topTarget =
|
m_topTarget =
|
||||||
m_bottomTarget =
|
m_bottomTarget =
|
||||||
m_leftTarget =
|
m_leftTarget =
|
||||||
m_rightTarget =
|
m_rightTarget =
|
||||||
m_qmlItemNode.modelNode().parentProperty().parentModelNode();
|
parentModelNode(m_qmlItemNode);
|
||||||
|
|
||||||
setupAnchorTargets();
|
setupAnchorTargets();
|
||||||
|
|
||||||
|
|||||||
@@ -172,7 +172,8 @@ void TextEditorView::nodeIdChanged(const ModelNode& /*node*/, const QString &/*n
|
|||||||
void TextEditorView::selectedNodesChanged(const QList<ModelNode> &/*selectedNodeList*/,
|
void TextEditorView::selectedNodesChanged(const QList<ModelNode> &/*selectedNodeList*/,
|
||||||
const QList<ModelNode> &/*lastSelectedNodeList*/)
|
const QList<ModelNode> &/*lastSelectedNodeList*/)
|
||||||
{
|
{
|
||||||
m_widget->jumpTextCursorToSelectedModelNode();
|
if (!m_errorState)
|
||||||
|
m_widget->jumpTextCursorToSelectedModelNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEditorView::customNotification(const AbstractView * /*view*/, const QString &identifier, const QList<ModelNode> &/*nodeList*/, const QList<QVariant> &/*data*/)
|
void TextEditorView::customNotification(const AbstractView * /*view*/, const QString &identifier, const QList<ModelNode> &/*nodeList*/, const QList<QVariant> &/*data*/)
|
||||||
@@ -187,9 +188,11 @@ void TextEditorView::documentMessagesChanged(const QList<DocumentMessage> &error
|
|||||||
{
|
{
|
||||||
if (errors.isEmpty()) {
|
if (errors.isEmpty()) {
|
||||||
m_widget->clearStatusBar();
|
m_widget->clearStatusBar();
|
||||||
|
m_errorState = false;
|
||||||
} else {
|
} else {
|
||||||
const DocumentMessage &error = errors.constFirst();
|
const DocumentMessage &error = errors.constFirst();
|
||||||
m_widget->setStatusText(QString("%1 (Line: %2)").arg(error.description()).arg(error.line()));
|
m_widget->setStatusText(QString("%1 (Line: %2)").arg(error.description()).arg(error.line()));
|
||||||
|
m_errorState = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
QPointer<TextEditorWidget> m_widget;
|
QPointer<TextEditorWidget> m_widget;
|
||||||
Internal::TextEditorContext *m_textEditorContext;
|
Internal::TextEditorContext *m_textEditorContext;
|
||||||
|
bool m_errorState = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
|||||||
@@ -108,15 +108,20 @@ void TextEditorWidget::updateSelectionByCursorPosition()
|
|||||||
const int cursorPosition = m_textEditor->editorWidget()->textCursor().position();
|
const int cursorPosition = m_textEditor->editorWidget()->textCursor().position();
|
||||||
RewriterView *rewriterView = m_textEditorView->model()->rewriterView();
|
RewriterView *rewriterView = m_textEditorView->model()->rewriterView();
|
||||||
|
|
||||||
|
m_blockRoundTrip = true;
|
||||||
if (rewriterView) {
|
if (rewriterView) {
|
||||||
ModelNode modelNode = rewriterView->nodeAtTextCursorPosition(cursorPosition);
|
ModelNode modelNode = rewriterView->nodeAtTextCursorPosition(cursorPosition);
|
||||||
if (modelNode.isValid() && !m_textEditorView->isSelectedModelNode(modelNode))
|
if (modelNode.isValid() && !m_textEditorView->isSelectedModelNode(modelNode))
|
||||||
m_textEditorView->setSelectedModelNode(modelNode);
|
m_textEditorView->setSelectedModelNode(modelNode);
|
||||||
}
|
}
|
||||||
|
m_blockRoundTrip = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEditorWidget::jumpTextCursorToSelectedModelNode()
|
void TextEditorWidget::jumpTextCursorToSelectedModelNode()
|
||||||
{
|
{
|
||||||
|
if (m_blockRoundTrip)
|
||||||
|
return;
|
||||||
|
|
||||||
ModelNode selectedNode;
|
ModelNode selectedNode;
|
||||||
|
|
||||||
if (hasFocus())
|
if (hasFocus())
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ private:
|
|||||||
QTimer m_updateSelectionTimer;
|
QTimer m_updateSelectionTimer;
|
||||||
TextEditorStatusBar *m_statusBar;
|
TextEditorStatusBar *m_statusBar;
|
||||||
bool m_blockCursorSelectionSynchronisation = false;
|
bool m_blockCursorSelectionSynchronisation = false;
|
||||||
|
bool m_blockRoundTrip = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 110 B After Width: | Height: | Size: 110 B |
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 118 B |
|
Before Width: | Height: | Size: 110 B After Width: | Height: | Size: 110 B |
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 118 B |
|
Before Width: | Height: | Size: 118 B After Width: | Height: | Size: 108 B |
@@ -191,7 +191,7 @@ void GenericDirectUploadService::stopDeployment()
|
|||||||
QList<DeployableFile> GenericDirectUploadService::collectFilesToUpload(
|
QList<DeployableFile> GenericDirectUploadService::collectFilesToUpload(
|
||||||
const DeployableFile &deployable) const
|
const DeployableFile &deployable) const
|
||||||
{
|
{
|
||||||
QList<DeployableFile> collected({deployable});
|
QList<DeployableFile> collected;
|
||||||
QFileInfo fileInfo = deployable.localFilePath().toFileInfo();
|
QFileInfo fileInfo = deployable.localFilePath().toFileInfo();
|
||||||
if (fileInfo.isDir()) {
|
if (fileInfo.isDir()) {
|
||||||
const QStringList files = QDir(deployable.localFilePath().toString())
|
const QStringList files = QDir(deployable.localFilePath().toString())
|
||||||
@@ -203,6 +203,8 @@ QList<DeployableFile> GenericDirectUploadService::collectFilesToUpload(
|
|||||||
+ fileInfo.fileName();
|
+ fileInfo.fileName();
|
||||||
collected.append(collectFilesToUpload(DeployableFile(localFilePath, remoteDir)));
|
collected.append(collectFilesToUpload(DeployableFile(localFilePath, remoteDir)));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
collected << deployable;
|
||||||
}
|
}
|
||||||
return collected;
|
return collected;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
import Qt 4.7
|
import QtQuick 2.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: id;
|
id: id;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
import Qt 4.7
|
import QtQuick 2.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
import Qt 4.7
|
import QtQuick 2.0
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: 200
|
width: 200
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
import Qt 4.7
|
import QtQuick 2.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
property bool pushed
|
property bool pushed
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
import Qt 4.7
|
import QtQuick 2.0
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: rect
|
id: rect
|
||||||
|
|||||||
@@ -125,9 +125,7 @@ def handleBuildSystemVerifyKits(category, template, kits, displayedPlatforms,
|
|||||||
test.log("Using build system '%s'" % buildSystem)
|
test.log("Using build system '%s'" % buildSystem)
|
||||||
selectFromCombo(combo, buildSystem)
|
selectFromCombo(combo, buildSystem)
|
||||||
clickButton(waitForObject(":Next_QPushButton"))
|
clickButton(waitForObject(":Next_QPushButton"))
|
||||||
if template == "Qt Quick Application - Scroll":
|
if specialHandlingFunc:
|
||||||
clickButton(waitForObject(":Next_QPushButton"))
|
|
||||||
elif specialHandlingFunc:
|
|
||||||
specialHandlingFunc(displayedPlatforms, *args)
|
specialHandlingFunc(displayedPlatforms, *args)
|
||||||
verifyKitCheckboxes(kits, displayedPlatforms)
|
verifyKitCheckboxes(kits, displayedPlatforms)
|
||||||
safeClickButton("Cancel")
|
safeClickButton("Cancel")
|
||||||
|
|||||||
@@ -12646,8 +12646,6 @@
|
|||||||
"bundledqt.qbs:4" "3"
|
"bundledqt.qbs:4" "3"
|
||||||
"QPA plugin" "3"
|
"QPA plugin" "3"
|
||||||
"bundledqt.qbs:65" "4"
|
"bundledqt.qbs:65" "4"
|
||||||
"Qt libraries" "3"
|
|
||||||
"bundledqt.qbs:30" "4"
|
|
||||||
"qt.conf" "3"
|
"qt.conf" "3"
|
||||||
"bundledqt.qbs:22" "4"
|
"bundledqt.qbs:22" "4"
|
||||||
"qt.conf" "4"
|
"qt.conf" "4"
|
||||||
|
|||||||
|
@@ -404,6 +404,39 @@ TEST_F(ClangFormat, IndentEmptyLineInsideParantheses)
|
|||||||
" && b)"));
|
" && b)"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ClangFormat, IndentInsideIf)
|
||||||
|
{
|
||||||
|
insertLines({"if (a && b",
|
||||||
|
")"});
|
||||||
|
|
||||||
|
indenter.indentBlock(doc.findBlockByNumber(1), QChar::Null, TextEditor::TabSettings());
|
||||||
|
|
||||||
|
ASSERT_THAT(documentLines(), ElementsAre("if (a && b",
|
||||||
|
" )"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ClangFormat, IndentInsideIf2)
|
||||||
|
{
|
||||||
|
insertLines({"if (a && b &&",
|
||||||
|
")"});
|
||||||
|
|
||||||
|
indenter.indentBlock(doc.findBlockByNumber(1), QChar::Null, TextEditor::TabSettings());
|
||||||
|
|
||||||
|
ASSERT_THAT(documentLines(), ElementsAre("if (a && b &&",
|
||||||
|
" )"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ClangFormat, IndentInsideIf3)
|
||||||
|
{
|
||||||
|
insertLines({"if (a || b",
|
||||||
|
")"});
|
||||||
|
|
||||||
|
indenter.indentBlock(doc.findBlockByNumber(1), QChar::Null, TextEditor::TabSettings());
|
||||||
|
|
||||||
|
ASSERT_THAT(documentLines(), ElementsAre("if (a || b",
|
||||||
|
" )"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ClangFormat, EmptyLineInInitializerList)
|
TEST_F(ClangFormat, EmptyLineInInitializerList)
|
||||||
{
|
{
|
||||||
insertLines({"Bar foo{a,",
|
insertLines({"Bar foo{a,",
|
||||||
@@ -441,6 +474,31 @@ TEST_F(ClangFormat, DoNotIndentClosingBraceAfterSemicolon)
|
|||||||
"}"));
|
"}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ClangFormat, IndentAfterIf)
|
||||||
|
{
|
||||||
|
insertLines({"if (a)",
|
||||||
|
""});
|
||||||
|
|
||||||
|
indenter.indentBlock(doc.findBlockByNumber(1), QChar::Null, TextEditor::TabSettings());
|
||||||
|
|
||||||
|
ASSERT_THAT(documentLines(), ElementsAre("if (a)",
|
||||||
|
" "));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ClangFormat, IndentAfterElse)
|
||||||
|
{
|
||||||
|
insertLines({"if (a)",
|
||||||
|
" foo();",
|
||||||
|
"else",
|
||||||
|
""});
|
||||||
|
indenter.indentBlock(doc.findBlockByNumber(3), QChar::Null, TextEditor::TabSettings());
|
||||||
|
|
||||||
|
ASSERT_THAT(documentLines(), ElementsAre("if (a)",
|
||||||
|
" foo();",
|
||||||
|
"else",
|
||||||
|
" "));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ClangFormat, SameIndentAfterSecondNewLineAfterIf)
|
TEST_F(ClangFormat, SameIndentAfterSecondNewLineAfterIf)
|
||||||
{
|
{
|
||||||
insertLines({"if (a)",
|
insertLines({"if (a)",
|
||||||
@@ -504,6 +562,102 @@ TEST_F(ClangFormat, SameIndentsOnNewLinesAfterComments)
|
|||||||
""));
|
""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(ClangFormat, IndentAfterEmptyLineAfterAngledIncludeDirective)
|
||||||
|
{
|
||||||
|
insertLines({"#include <string>",
|
||||||
|
"",
|
||||||
|
"using namespace std;"});
|
||||||
|
|
||||||
|
indenter.indentBlock(doc.findBlockByNumber(2), QChar::Null, TextEditor::TabSettings());
|
||||||
|
|
||||||
|
ASSERT_THAT(documentLines(), ElementsAre("#include <string>",
|
||||||
|
"",
|
||||||
|
"using namespace std;"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ClangFormat, IndentAfterEmptyLineAfterQuotedIncludeDirective)
|
||||||
|
{
|
||||||
|
insertLines({"#include \"foo.h\"",
|
||||||
|
"",
|
||||||
|
"using namespace std;"});
|
||||||
|
|
||||||
|
indenter.indentBlock(doc.findBlockByNumber(2), QChar::Null, TextEditor::TabSettings());
|
||||||
|
|
||||||
|
ASSERT_THAT(documentLines(), ElementsAre("#include \"foo.h\"",
|
||||||
|
"",
|
||||||
|
"using namespace std;"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ClangFormat, IndentAfterLineComment)
|
||||||
|
{
|
||||||
|
insertLines({"int foo()",
|
||||||
|
"{",
|
||||||
|
" // Comment",
|
||||||
|
" ",
|
||||||
|
" if (",
|
||||||
|
"}"});
|
||||||
|
|
||||||
|
indenter.indentBlock(doc.findBlockByNumber(4), '(', TextEditor::TabSettings());
|
||||||
|
|
||||||
|
ASSERT_THAT(documentLines(), ElementsAre("int foo()",
|
||||||
|
"{",
|
||||||
|
" // Comment",
|
||||||
|
" ",
|
||||||
|
" if (",
|
||||||
|
"}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ClangFormat, IndentAfterBlockComment)
|
||||||
|
{
|
||||||
|
insertLines({"int foo()",
|
||||||
|
"{",
|
||||||
|
" bar(); /* Comment */",
|
||||||
|
" ",
|
||||||
|
" if (",
|
||||||
|
"}"});
|
||||||
|
|
||||||
|
indenter.indentBlock(doc.findBlockByNumber(4), '(', TextEditor::TabSettings());
|
||||||
|
|
||||||
|
ASSERT_THAT(documentLines(), ElementsAre("int foo()",
|
||||||
|
"{",
|
||||||
|
" bar(); /* Comment */",
|
||||||
|
" ",
|
||||||
|
" if (",
|
||||||
|
"}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ClangFormat, IndentAfterIfdef)
|
||||||
|
{
|
||||||
|
insertLines({"int foo()",
|
||||||
|
"{",
|
||||||
|
"#ifdef FOO",
|
||||||
|
"#endif",
|
||||||
|
" ",
|
||||||
|
" if (",
|
||||||
|
"}"});
|
||||||
|
|
||||||
|
indenter.indentBlock(doc.findBlockByNumber(5), '(', TextEditor::TabSettings());
|
||||||
|
|
||||||
|
ASSERT_THAT(documentLines(), ElementsAre("int foo()",
|
||||||
|
"{",
|
||||||
|
"#ifdef FOO",
|
||||||
|
"#endif",
|
||||||
|
" ",
|
||||||
|
" if (",
|
||||||
|
"}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ClangFormat, IndentAfterEmptyLineInTheFileBeginning)
|
||||||
|
{
|
||||||
|
insertLines({"",
|
||||||
|
"void foo()"});
|
||||||
|
|
||||||
|
indenter.indentBlock(doc.findBlockByNumber(1), ')', TextEditor::TabSettings());
|
||||||
|
|
||||||
|
ASSERT_THAT(documentLines(), ElementsAre("",
|
||||||
|
"void foo()"));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(ClangFormat, IndentFunctionBodyButNotFormatBeforeIt)
|
TEST_F(ClangFormat, IndentFunctionBodyButNotFormatBeforeIt)
|
||||||
{
|
{
|
||||||
insertLines({"int foo(int a, int b,",
|
insertLines({"int foo(int a, int b,",
|
||||||
|
|||||||