Merge remote-tracking branch 'origin/4.9'

Change-Id: I7d1912cd5c4d824fd40d3454c5f1bb796f2c21d8
This commit is contained in:
Orgad Shaneh
2019-04-07 20:40:29 +03:00
92 changed files with 1153 additions and 490 deletions
+1 -1
View File
@@ -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
+5
View File
@@ -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 -1
View File
@@ -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.
+2 -1
View File
@@ -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
Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

+17 -6
View File
@@ -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.
+1 -1
View File
@@ -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}.
*/ */
+5 -1
View File
@@ -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
*/ */
+73
View File
@@ -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]
*/
+9 -5
View File
@@ -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.
+10 -3
View File
@@ -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",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

After

Width:  |  Height:  |  Size: 165 B

Binary file not shown.

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
+2 -2
View File
@@ -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>
+2 -3
View File
@@ -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")) {
+15 -1
View File
@@ -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
+2
View File
@@ -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;
}; };
+15
View File
@@ -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;
+4
View File
@@ -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);
+1 -1
View File
@@ -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 &currentBlock) QChar findFirstNonWhitespaceCharacter(const QTextBlock &currentBlock)
{ {
@@ -150,10 +155,42 @@ QChar findFirstNonWhitespaceCharacter(const QTextBlock &currentBlock)
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 &currentBlock, CharacterContext characterContext(const QTextBlock &currentBlock,
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 &currentBlock,
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 &currentBlock) bool nextBlockExistsAndEmpty(const QTextBlock &currentBlock)
@@ -181,20 +221,18 @@ bool nextBlockExistsAndEmpty(const QTextBlock &currentBlock)
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();
+5 -2
View File
@@ -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",
+10 -6
View 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)) {
+1
View File
@@ -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);
+3 -3
View File
@@ -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)
+54 -42
View 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();
} }
+1 -1
View File
@@ -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 {
+425 -220
View File
@@ -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
+16 -8
View File
@@ -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;
}; };
+9 -10
View File
@@ -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();
+83 -64
View File
@@ -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
+5 -3
View File
@@ -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);
+2 -2
View File
@@ -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();
} }
} }
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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();
+1 -1
View File
@@ -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);
+1 -1
View File
@@ -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();
+10 -4
View File
@@ -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
Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 B

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 B

After

Width:  |  Height:  |  Size: 110 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 118 B

After

Width:  |  Height:  |  Size: 118 B

Binary file not shown.

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;
+1 -1
View File
@@ -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"
1 text nestinglevel
12646 bundledqt.qbs:4 3
12647 QPA plugin 3
12648 bundledqt.qbs:65 4
Qt libraries 3
bundledqt.qbs:30 4
12649 qt.conf 3
12650 bundledqt.qbs:22 4
12651 qt.conf 4
+154
View File
@@ -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,",