Merge remote-tracking branch 'origin/4.4'
Change-Id: I778acc044ac105a11054b314aecac5b1c2cfee6a
190
dist/changes-4.4.0.md
vendored
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
Qt Creator version 4.4 contains bug fixes and new features.
|
||||||
|
|
||||||
|
The most important changes are listed in this document. For a complete
|
||||||
|
list of changes, see the Git log for the Qt Creator sources that
|
||||||
|
you can check out from the public Git repository. For example:
|
||||||
|
|
||||||
|
git clone git://code.qt.io/qt-creator/qt-creator.git
|
||||||
|
git log --cherry-pick --pretty=oneline origin/4.3..v4.4.0
|
||||||
|
|
||||||
|
General
|
||||||
|
|
||||||
|
* Added highlighting of search term in Locator results
|
||||||
|
* Added larger icons to `New` dialog
|
||||||
|
* Added locator input to extra editor and help windows (QTCREATORBUG-9696)
|
||||||
|
* Fixed theming of Debugger Console and TODO pane (QTCREATORBUG-17532)
|
||||||
|
|
||||||
|
Editing
|
||||||
|
|
||||||
|
* Added inline annotations for errors, warnings and bookmarks
|
||||||
|
* Added optional smooth scrolling when navigating within the same file
|
||||||
|
(for example with Locator or `Follow Symbol Under Cursor`)
|
||||||
|
* Added overridable `DeleteStartOfLine` and `DeleteEndOfLine` actions
|
||||||
|
(QTCREATORBUG-18095)
|
||||||
|
* Added support for relative path to active project to `Advanced Find` >
|
||||||
|
`Files in File System` (QTCREATORBUG-18139)
|
||||||
|
* Added colors to default text editor scheme (the previous default is
|
||||||
|
available as `Default Classic`)
|
||||||
|
* FakeVim
|
||||||
|
* Fixed `gt`/`gT`/`:tabnext`/`:tabprevious`
|
||||||
|
|
||||||
|
All Projects
|
||||||
|
|
||||||
|
* Improved detection of cross-compilers
|
||||||
|
|
||||||
|
CMake Projects
|
||||||
|
|
||||||
|
* Added option to filter for CMake variables in build configuration
|
||||||
|
(QTCREATORBUG-17973)
|
||||||
|
* Added warning when detecting `CMakeCache.txt` in source directory even though
|
||||||
|
build is configured for out-of-source build (QTCREATORBUG-18381)
|
||||||
|
* CMake >= 3.7
|
||||||
|
* Fixed that headers from top level directory were not shown in project tree
|
||||||
|
(QTCREATORBUG-17760)
|
||||||
|
* Improved handling of `CMAKE_RUNTIME_OUTPUT_DIRECTORY` (QTCREATORBUG-18158)
|
||||||
|
|
||||||
|
Qbs Projects
|
||||||
|
|
||||||
|
* Re-added `Qbs install` deploy step (QTCREATORBUG-17958)
|
||||||
|
* Added `rebuild` and `clean` actions to products and subprojects
|
||||||
|
(QTCREATORBUG-15919)
|
||||||
|
|
||||||
|
C++ Support
|
||||||
|
|
||||||
|
* Added option to rename files when renaming symbol using same name
|
||||||
|
(QTCREATORBUG-14696)
|
||||||
|
* Added auto-insertion of matching curly brace (QTCREATORBUG-15073)
|
||||||
|
* Fixed that C++ and Qt keywords were considered keywords in C files
|
||||||
|
(QTCREATORBUG-2818, QTCREATORBUG-18004)
|
||||||
|
* Fixed highlighting of raw string literals (QTCREATORBUG-17720)
|
||||||
|
* Fixed `Add #include` refactoring action for static functions
|
||||||
|
* Clang Code Model
|
||||||
|
* Added highlighting of identifier under cursor, which was still
|
||||||
|
delegated to built-in code model
|
||||||
|
* Improved order of items in completion list
|
||||||
|
(QTCREATORBUG-18319, QTCREATORBUG-15445)
|
||||||
|
* Fixed function signature hint when completing constructors and functors
|
||||||
|
(QTCREATORBUG-14882)
|
||||||
|
* Fixed that completing function pointer was adding parentheses
|
||||||
|
(QTCREATORBUG-17578)
|
||||||
|
* Fixed completion inside function template (QTCREATORBUG-17222)
|
||||||
|
* Fixed wrong column number with non-ASCII characters (QTCREATORBUG-16775)
|
||||||
|
* Fixed highlighting of primitive types and operators (QTCREATORBUG-17867)
|
||||||
|
* Fixed highlighting of partial template specializations
|
||||||
|
* Fixed highlighting of functions in `using` declarations
|
||||||
|
* Fixed that keywords were highlighted in preprocessor directives
|
||||||
|
(QTCREATORBUG-15516)
|
||||||
|
* Built-in Code Model
|
||||||
|
* Fixed completion of STL containers (QTCREATORBUG-1892)
|
||||||
|
|
||||||
|
QML Support
|
||||||
|
|
||||||
|
* Updated QML parser to newer QML version (QTCREATORBUG-17842)
|
||||||
|
|
||||||
|
Debugging
|
||||||
|
|
||||||
|
* Added `Alt+V` + letter shortcuts to open views
|
||||||
|
* Added dumper for `qfloat16`
|
||||||
|
* Added dumpers for `std::{optional,byte}`, `gsl::{span,byte}`, `boost::variant`
|
||||||
|
* Improved display of enum bitfields
|
||||||
|
* Fixed support for `long double` (QTCREATORBUG-18023)
|
||||||
|
* CDB
|
||||||
|
* Added support for extra debugging helpers and debugging helper
|
||||||
|
customization
|
||||||
|
* Added warning if run configuration uses unsupported shell command
|
||||||
|
|
||||||
|
Version Control Systems
|
||||||
|
|
||||||
|
* Fixed format of visual whitespace in blame, log and git rebase editors
|
||||||
|
(QTCREATORBUG-17735)
|
||||||
|
* Git
|
||||||
|
* Improved branch listing in `Show` (QTCREATORBUG-16949)
|
||||||
|
* Gerrit
|
||||||
|
* Added validation of server certificate when using REST API
|
||||||
|
* Fixed that non-Gerrit remotes were shown in `Push to Gerrit` dialog
|
||||||
|
(QTCREATORBUG-16367)
|
||||||
|
* ClearCase
|
||||||
|
* Disabled by default
|
||||||
|
|
||||||
|
Diff Viewer
|
||||||
|
|
||||||
|
* Fixed state of actions in `Edit` menu
|
||||||
|
* Fixed that context information for chunks was not shown in side-by-side view
|
||||||
|
(QTCREATORBUG-18289)
|
||||||
|
* Fixed that UI blocked when showing very large diffs
|
||||||
|
|
||||||
|
Test Integration
|
||||||
|
|
||||||
|
* Added view with complete, unprocessed test output
|
||||||
|
* Made it possible to enable and disable all tests using a specific test
|
||||||
|
framework
|
||||||
|
* QTest
|
||||||
|
* Added option to run verbose and with logging of signals and slots
|
||||||
|
(`-vb` and `-vs`)
|
||||||
|
|
||||||
|
Beautifier
|
||||||
|
|
||||||
|
* Added option for using a different AStyle configuration file
|
||||||
|
* Added option for fallback style for `clang-format`
|
||||||
|
|
||||||
|
Platform Specific
|
||||||
|
|
||||||
|
Windows
|
||||||
|
|
||||||
|
* Removed support for Windows CE
|
||||||
|
|
||||||
|
Android
|
||||||
|
|
||||||
|
* Added option to run commands before app starts and after app stopped
|
||||||
|
* Fixed state of actions in `Edit` menu in text based manifest editor
|
||||||
|
|
||||||
|
iOS
|
||||||
|
|
||||||
|
* Added UI for managing simulator devices (QTCREATORBUG-17602)
|
||||||
|
|
||||||
|
Remote Linux
|
||||||
|
|
||||||
|
* Added support for `ssh-agent` (QTCREATORBUG-16245)
|
||||||
|
|
||||||
|
Credits for these changes go to:
|
||||||
|
Alessandro Portale
|
||||||
|
Alexander Drozdov
|
||||||
|
Andre Hartmann
|
||||||
|
André Pönitz
|
||||||
|
Christian Kandeler
|
||||||
|
Christian Stenger
|
||||||
|
Daniel Teske
|
||||||
|
David Schulz
|
||||||
|
Eike Ziller
|
||||||
|
Felix Kälberer
|
||||||
|
Florian Apolloner
|
||||||
|
Friedemann Kleint
|
||||||
|
Ivan Donchevskii
|
||||||
|
Jake Petroules
|
||||||
|
Jaroslaw Kobus
|
||||||
|
Jesus Fernandez
|
||||||
|
Jochen Becher
|
||||||
|
Jörg Bornemann
|
||||||
|
Kai Köhne
|
||||||
|
Leandro T. C. Melo
|
||||||
|
Leena Miettinen
|
||||||
|
Lorenz Haas
|
||||||
|
Marco Benelli
|
||||||
|
Marco Bubke
|
||||||
|
Mitch Curtis
|
||||||
|
Montel Laurent
|
||||||
|
Nikita Baryshnikov
|
||||||
|
Nikolai Kosjar
|
||||||
|
Orgad Shaneh
|
||||||
|
Przemyslaw Gorszkowski
|
||||||
|
Robert Löhning
|
||||||
|
Serhii Moroz
|
||||||
|
Tasuku Suzuki
|
||||||
|
Thiago Macieira
|
||||||
|
Thomas Hartmann
|
||||||
|
Tim Jenssen
|
||||||
|
Tobias Hunger
|
||||||
|
Tomasz Olszak
|
||||||
|
Tor Arne Vestbø
|
||||||
|
Ulf Hermann
|
||||||
|
Vikas Pachdha
|
||||||
BIN
doc/images/qtcreator-clang-code-model-build-settings.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 58 KiB |
@@ -129,14 +129,29 @@
|
|||||||
|
|
||||||
\image qtcreator-clang-code-model-options.png
|
\image qtcreator-clang-code-model-options.png
|
||||||
|
|
||||||
\li In the \uicontrol {Configuration to use} list, configure the
|
\li To instruct the code model to interpret ambiguous header files as C
|
||||||
|
language files if you develop mainly using C, select the
|
||||||
|
\uicontrol {Interpret ambiguous headers as C headers} check box.
|
||||||
|
|
||||||
|
\li To process pre-compiled headers, deselect the
|
||||||
|
\uicontrol {Ignore pre-compiled headers} check box.
|
||||||
|
|
||||||
|
\li To avoid out-of-memory crashes caused by indexing huge source files
|
||||||
|
that are typically auto-generated by scripts or code, the size of
|
||||||
|
files to index is limited to 5MB by default. To adjust the limit,
|
||||||
|
edit the value for the \uicontrol {Do not index files greater than}
|
||||||
|
check box. To index all files, deselect the check box.
|
||||||
|
|
||||||
|
\li In the \uicontrol {Clang Code Model Warnings} group, configure the
|
||||||
diagnostics that Clang should issue.
|
diagnostics that Clang should issue.
|
||||||
|
|
||||||
You can either select one of the predefined configurations, or
|
|
||||||
create a copy of a configuration and edit it to fit your needs:
|
|
||||||
|
|
||||||
\list
|
\list
|
||||||
|
|
||||||
|
\li In the \uicontrol {Configuration to use} list, select one of
|
||||||
|
the predefined configurations, or select \uicontrol Copy to
|
||||||
|
create a copy of a configuration and edit it to fit your
|
||||||
|
needs.
|
||||||
|
|
||||||
\li \uicontrol {Pedantic Warnings} uses the \c -Wpendantic
|
\li \uicontrol {Pedantic Warnings} uses the \c -Wpendantic
|
||||||
option that requests all the warnings demanded by strict
|
option that requests all the warnings demanded by strict
|
||||||
ISO C and ISO C++.
|
ISO C and ISO C++.
|
||||||
@@ -160,15 +175,17 @@
|
|||||||
{Options to Request or Suppress Warnings} or the GCC or Clang
|
{Options to Request or Suppress Warnings} or the GCC or Clang
|
||||||
manual pages.
|
manual pages.
|
||||||
|
|
||||||
\li To process pre-compiled headers, deselect the
|
|
||||||
\uicontrol {Ignore pre-compiled headers} check box.
|
|
||||||
|
|
||||||
\li To avoid out-of-memory crashes caused by indexing huge source files
|
|
||||||
that are typically auto-generated by scripts or code, the size of
|
|
||||||
files to index is limited to 5MB by default. To adjust the limit,
|
|
||||||
edit the value for the \uicontrol {Do not index files greater than}
|
|
||||||
check box. To index all files, deselect the check box.
|
|
||||||
|
|
||||||
\endlist
|
\endlist
|
||||||
|
|
||||||
|
You can specify Clang settings at project level in the build settings of
|
||||||
|
the project by selecting \uicontrol Projects >
|
||||||
|
\uicontrol {Clang Code Model}. In addition to configuring the diagnostics,
|
||||||
|
you can select the \uicontrol {Enable MSVC-compliant template parsing} check
|
||||||
|
box to parse templates in a MSVC-compliant way. This enables Clang to parse
|
||||||
|
headers for example from Active Template Library (ATL) or Windows Runtime
|
||||||
|
Library (WRL). However, using the relaxed and extended rules means that no
|
||||||
|
highlighting or completion can be provided within template functions.
|
||||||
|
|
||||||
|
\image qtcreator-clang-code-model-build-settings.png
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -304,9 +304,9 @@ int MetaObject::metaCall(QMetaObject::Call call, int id, void **a)
|
|||||||
&& property(id).name() == QLatin1String("parent"))) {
|
&& property(id).name() == QLatin1String("parent"))) {
|
||||||
|
|
||||||
QObject *contextDummyObject = objectNodeInstance->nodeInstanceServer()->dummyContextObject();
|
QObject *contextDummyObject = objectNodeInstance->nodeInstanceServer()->dummyContextObject();
|
||||||
int properyIndex = contextDummyObject->metaObject()->indexOfProperty(propertyById.name());
|
int propertyIndex = contextDummyObject->metaObject()->indexOfProperty(propertyById.name());
|
||||||
if (properyIndex >= 0)
|
if (propertyIndex >= 0)
|
||||||
metaCallReturnValue = contextDummyObject->qt_metacall(call, properyIndex, a);
|
metaCallReturnValue = contextDummyObject->qt_metacall(call, propertyIndex, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -6,7 +6,7 @@
|
|||||||
"trDescription": "Creates an empty Nim file using UTF-8 charset.",
|
"trDescription": "Creates an empty Nim file using UTF-8 charset.",
|
||||||
"trDisplayName": "Nim File",
|
"trDisplayName": "Nim File",
|
||||||
"trDisplayCategory": "Nim",
|
"trDisplayCategory": "Nim",
|
||||||
"icon": "icon.png",
|
"icon": "../../projects/nim/icon.png",
|
||||||
"enabled": "%{JS: [ %{Plugins} ].indexOf('Nim') >= 0}",
|
"enabled": "%{JS: [ %{Plugins} ].indexOf('Nim') >= 0}",
|
||||||
|
|
||||||
"pages" :
|
"pages" :
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -6,7 +6,7 @@
|
|||||||
"trDescription": "Creates an empty Nim script file using UTF-8 charset.",
|
"trDescription": "Creates an empty Nim script file using UTF-8 charset.",
|
||||||
"trDisplayName": "Nim Script File",
|
"trDisplayName": "Nim Script File",
|
||||||
"trDisplayCategory": "Nim",
|
"trDisplayCategory": "Nim",
|
||||||
"icon": "icon.png",
|
"icon": "../../projects/nim/icon.png",
|
||||||
"enabled": "%{JS: [ %{Plugins} ].indexOf('Nim') >= 0}",
|
"enabled": "%{JS: [ %{Plugins} ].indexOf('Nim') >= 0}",
|
||||||
|
|
||||||
"pages" :
|
"pages" :
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.8 KiB |
BIN
share/qtcreator/templates/wizards/projects/nim/icon@2x.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 586 B |
@@ -6,7 +6,7 @@
|
|||||||
"trDescription": "Creates a deployable Qt Quick 2 application.",
|
"trDescription": "Creates a deployable Qt Quick 2 application.",
|
||||||
"trDisplayName": "Qt Quick Application",
|
"trDisplayName": "Qt Quick Application",
|
||||||
"trDisplayCategory": "Application",
|
"trDisplayCategory": "Application",
|
||||||
"icon": "qml_wizard.png",
|
"icon": "icon-empty.png",
|
||||||
"featuresRequired": [ "QtSupport.Wizards.FeatureQt.5.3" ],
|
"featuresRequired": [ "QtSupport.Wizards.FeatureQt.5.3" ],
|
||||||
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0 || [ %{Plugins} ].indexOf('QbsProjectManager') >= 0 || [ %{Plugins} ].indexOf('CMakeProjectManager') >= 0}",
|
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0 || [ %{Plugins} ].indexOf('QbsProjectManager') >= 0 || [ %{Plugins} ].indexOf('CMakeProjectManager') >= 0}",
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
"trDescription": "Creates a deployable Qt Quick 2 application using Qt Quick Controls 2.<br/><br/><b>Note:</b> Qt Quick Controls 2 are available with Qt 5.7 and later.",
|
"trDescription": "Creates a deployable Qt Quick 2 application using Qt Quick Controls 2.<br/><br/><b>Note:</b> Qt Quick Controls 2 are available with Qt 5.7 and later.",
|
||||||
"trDisplayName": "Qt Quick Controls 2 Application",
|
"trDisplayName": "Qt Quick Controls 2 Application",
|
||||||
"trDisplayCategory": "Application",
|
"trDisplayCategory": "Application",
|
||||||
"icon": "../qtquickapplication/qml_wizard.png",
|
"icon": "../qtquickapplication/icon-swipe.png",
|
||||||
"featuresRequired": [ "QtSupport.Wizards.FeatureQtQuick.Controls.2" ],
|
"featuresRequired": [ "QtSupport.Wizards.FeatureQtQuick.Controls.2" ],
|
||||||
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0 || [ %{Plugins} ].indexOf('QbsProjectManager') >= 0 || [ %{Plugins} ].indexOf('CMakeProjectManager') >= 0}",
|
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0 || [ %{Plugins} ].indexOf('QbsProjectManager') >= 0 || [ %{Plugins} ].indexOf('CMakeProjectManager') >= 0}",
|
||||||
|
|
||||||
|
|||||||
4
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -27,6 +27,8 @@
|
|||||||
#include "ObjectiveCTypeQualifiers.h"
|
#include "ObjectiveCTypeQualifiers.h"
|
||||||
#include "QtContextKeywords.h"
|
#include "QtContextKeywords.h"
|
||||||
|
|
||||||
|
#include <utils/qtcfallthrough.h>
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -442,7 +444,7 @@ bool Parser::skipUntilStatement()
|
|||||||
case T_AT_THROW:
|
case T_AT_THROW:
|
||||||
if (_languageFeatures.objCEnabled)
|
if (_languageFeatures.objCEnabled)
|
||||||
return true;
|
return true;
|
||||||
|
Q_FALLTHROUGH();
|
||||||
default:
|
default:
|
||||||
consumeToken();
|
consumeToken();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -143,9 +143,13 @@ bool MatchingText::contextAllowsAutoParentheses(const QTextCursor &cursor,
|
|||||||
if (!textToInsert.isEmpty())
|
if (!textToInsert.isEmpty())
|
||||||
ch = textToInsert.at(0);
|
ch = textToInsert.at(0);
|
||||||
|
|
||||||
|
if (ch == QLatin1Char('{') && cursor.block().text().trimmed().isEmpty())
|
||||||
|
return false; // User just might want to wrap up some lines.
|
||||||
|
|
||||||
if (!shouldInsertMatchingText(cursor) && ch != QLatin1Char('\'') && ch != QLatin1Char('"'))
|
if (!shouldInsertMatchingText(cursor) && ch != QLatin1Char('\'') && ch != QLatin1Char('"'))
|
||||||
return false;
|
return false;
|
||||||
else if (isInCommentHelper(cursor))
|
|
||||||
|
if (isInCommentHelper(cursor))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
54
src/libs/utils/qtcfallthrough.h
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2017 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** Commercial License Usage
|
||||||
|
** Licensees holding valid commercial Qt licenses may use this file in
|
||||||
|
** accordance with the commercial license agreement provided with the
|
||||||
|
** Software or, alternatively, in accordance with the terms contained in
|
||||||
|
** a written agreement between you and The Qt Company. For licensing terms
|
||||||
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||||
|
** information use the contact form at https://www.qt.io/contact-us.
|
||||||
|
**
|
||||||
|
** GNU General Public License Usage
|
||||||
|
** Alternatively, this file may be used under the terms of the GNU
|
||||||
|
** General Public License version 3 as published by the Free Software
|
||||||
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||||
|
** included in the packaging of this file. Please review the following
|
||||||
|
** information to ensure the GNU General Public License requirements will
|
||||||
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||||
|
**
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
#ifndef Q_FALLTHROUGH
|
||||||
|
#ifndef QT_HAS_CPP_ATTRIBUTE
|
||||||
|
#ifdef __has_cpp_attribute
|
||||||
|
# define QT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
|
||||||
|
#else
|
||||||
|
# define QT_HAS_CPP_ATTRIBUTE(x) 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
#if QT_HAS_CPP_ATTRIBUTE(fallthrough)
|
||||||
|
# define Q_FALLTHROUGH() [[fallthrough]]
|
||||||
|
#elif QT_HAS_CPP_ATTRIBUTE(clang::fallthrough)
|
||||||
|
# define Q_FALLTHROUGH() [[clang::fallthrough]]
|
||||||
|
#elif QT_HAS_CPP_ATTRIBUTE(gnu::fallthrough)
|
||||||
|
# define Q_FALLTHROUGH() [[gnu::fallthrough]]
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef Q_FALLTHROUGH
|
||||||
|
# if (defined(Q_CC_GNU) && Q_CC_GNU >= 700) && !defined(Q_CC_INTEL)
|
||||||
|
# define Q_FALLTHROUGH() __attribute__((fallthrough))
|
||||||
|
# else
|
||||||
|
# define Q_FALLTHROUGH() (void)0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@@ -239,6 +239,7 @@ HEADERS += \
|
|||||||
$$PWD/asconst.h \
|
$$PWD/asconst.h \
|
||||||
$$PWD/smallstringfwd.h \
|
$$PWD/smallstringfwd.h \
|
||||||
$$PWD/optional.h \
|
$$PWD/optional.h \
|
||||||
|
$$PWD/qtcfallthrough.h \
|
||||||
$$PWD/../3rdparty/optional/optional.hpp
|
$$PWD/../3rdparty/optional/optional.hpp
|
||||||
|
|
||||||
FORMS += $$PWD/filewizardpage.ui \
|
FORMS += $$PWD/filewizardpage.ui \
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ Project {
|
|||||||
"proxycredentialsdialog.cpp",
|
"proxycredentialsdialog.cpp",
|
||||||
"proxycredentialsdialog.h",
|
"proxycredentialsdialog.h",
|
||||||
"proxycredentialsdialog.ui",
|
"proxycredentialsdialog.ui",
|
||||||
|
"qtcfallthrough.h",
|
||||||
"qtcassert.cpp",
|
"qtcassert.cpp",
|
||||||
"qtcassert.h",
|
"qtcassert.h",
|
||||||
"qtcolorbutton.cpp",
|
"qtcolorbutton.cpp",
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ IpcReceiver::IpcReceiver()
|
|||||||
|
|
||||||
IpcReceiver::~IpcReceiver()
|
IpcReceiver::~IpcReceiver()
|
||||||
{
|
{
|
||||||
deleteAndClearWaitingAssistProcessors();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IpcReceiver::setAliveHandler(const IpcReceiver::AliveHandler &handler)
|
void IpcReceiver::setAliveHandler(const IpcReceiver::AliveHandler &handler)
|
||||||
@@ -116,12 +116,6 @@ void IpcReceiver::addExpectedCodeCompletedMessage(
|
|||||||
m_assistProcessorsTable.insert(ticket, processor);
|
m_assistProcessorsTable.insert(ticket, processor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IpcReceiver::deleteAndClearWaitingAssistProcessors()
|
|
||||||
{
|
|
||||||
qDeleteAll(m_assistProcessorsTable.begin(), m_assistProcessorsTable.end());
|
|
||||||
m_assistProcessorsTable.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void IpcReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget)
|
void IpcReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget)
|
||||||
{
|
{
|
||||||
QMutableHashIterator<quint64, ClangCompletionAssistProcessor *> it(m_assistProcessorsTable);
|
QMutableHashIterator<quint64, ClangCompletionAssistProcessor *> it(m_assistProcessorsTable);
|
||||||
@@ -155,6 +149,18 @@ bool IpcReceiver::isExpectingCodeCompletedMessage() const
|
|||||||
return !m_assistProcessorsTable.isEmpty();
|
return !m_assistProcessorsTable.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IpcReceiver::reset()
|
||||||
|
{
|
||||||
|
// Clean up waiting assist processors
|
||||||
|
qDeleteAll(m_assistProcessorsTable.begin(), m_assistProcessorsTable.end());
|
||||||
|
m_assistProcessorsTable.clear();
|
||||||
|
|
||||||
|
// Clean up futures for references
|
||||||
|
for (ReferencesEntry &entry : m_referencesTable)
|
||||||
|
entry.futureInterface.cancel();
|
||||||
|
m_referencesTable.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void IpcReceiver::alive()
|
void IpcReceiver::alive()
|
||||||
{
|
{
|
||||||
if (printAliveMessage())
|
if (printAliveMessage())
|
||||||
@@ -719,7 +725,7 @@ void IpcCommunicator::onConnectedToBackend()
|
|||||||
if (m_connectedCount > 1)
|
if (m_connectedCount > 1)
|
||||||
logRestartedDueToUnexpectedFinish();
|
logRestartedDueToUnexpectedFinish();
|
||||||
|
|
||||||
m_ipcReceiver.deleteAndClearWaitingAssistProcessors();
|
m_ipcReceiver.reset();
|
||||||
m_ipcSender.reset(new IpcSender(m_connection));
|
m_ipcSender.reset(new IpcSender(m_connection));
|
||||||
|
|
||||||
initializeBackendWithCurrentData();
|
initializeBackendWithCurrentData();
|
||||||
|
|||||||
@@ -73,14 +73,14 @@ public:
|
|||||||
void setAliveHandler(const AliveHandler &handler);
|
void setAliveHandler(const AliveHandler &handler);
|
||||||
|
|
||||||
void addExpectedCodeCompletedMessage(quint64 ticket, ClangCompletionAssistProcessor *processor);
|
void addExpectedCodeCompletedMessage(quint64 ticket, ClangCompletionAssistProcessor *processor);
|
||||||
void deleteAndClearWaitingAssistProcessors();
|
|
||||||
void deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget);
|
void deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget);
|
||||||
|
|
||||||
QFuture<CppTools::CursorInfo> addExpectedReferencesMessage(quint64 ticket,
|
QFuture<CppTools::CursorInfo> addExpectedReferencesMessage(quint64 ticket,
|
||||||
QTextDocument *textDocument);
|
QTextDocument *textDocument);
|
||||||
|
|
||||||
bool isExpectingCodeCompletedMessage() const;
|
bool isExpectingCodeCompletedMessage() const;
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void alive() override;
|
void alive() override;
|
||||||
void echo(const ClangBackEnd::EchoMessage &message) override;
|
void echo(const ClangBackEnd::EchoMessage &message) override;
|
||||||
|
|||||||
@@ -278,6 +278,8 @@ namespace Internal {
|
|||||||
ClangDiagnosticManager::ClangDiagnosticManager(TextEditor::TextDocument *textDocument)
|
ClangDiagnosticManager::ClangDiagnosticManager(TextEditor::TextDocument *textDocument)
|
||||||
: m_textDocument(textDocument)
|
: m_textDocument(textDocument)
|
||||||
{
|
{
|
||||||
|
m_textMarkDelay.setInterval(1500);
|
||||||
|
m_textMarkDelay.setSingleShot(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClangDiagnosticManager::~ClangDiagnosticManager()
|
ClangDiagnosticManager::~ClangDiagnosticManager()
|
||||||
@@ -295,6 +297,7 @@ void ClangDiagnosticManager::cleanMarks()
|
|||||||
}
|
}
|
||||||
void ClangDiagnosticManager::generateTextMarks()
|
void ClangDiagnosticManager::generateTextMarks()
|
||||||
{
|
{
|
||||||
|
QObject::disconnect(&m_textMarkDelay, &QTimer::timeout, 0, 0);
|
||||||
cleanMarks();
|
cleanMarks();
|
||||||
m_clangTextMarks.reserve(m_warningDiagnostics.size() + m_errorDiagnostics.size());
|
m_clangTextMarks.reserve(m_warningDiagnostics.size() + m_errorDiagnostics.size());
|
||||||
addClangTextMarks(m_warningDiagnostics);
|
addClangTextMarks(m_warningDiagnostics);
|
||||||
@@ -350,6 +353,7 @@ ClangDiagnosticManager::diagnosticsAt(uint line, uint column) const
|
|||||||
|
|
||||||
void ClangDiagnosticManager::invalidateDiagnostics()
|
void ClangDiagnosticManager::invalidateDiagnostics()
|
||||||
{
|
{
|
||||||
|
m_textMarkDelay.start();
|
||||||
if (m_diagnosticsInvalidated)
|
if (m_diagnosticsInvalidated)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -383,9 +387,18 @@ void ClangDiagnosticManager::processNewDiagnostics(
|
|||||||
m_showTextMarkAnnotations = showTextMarkAnnotations;
|
m_showTextMarkAnnotations = showTextMarkAnnotations;
|
||||||
filterDiagnostics(allDiagnostics);
|
filterDiagnostics(allDiagnostics);
|
||||||
|
|
||||||
generateTextMarks();
|
|
||||||
generateEditorSelections();
|
generateEditorSelections();
|
||||||
generateFixItAvailableMarkers();
|
generateFixItAvailableMarkers();
|
||||||
|
if (m_firstDiagnostics) {
|
||||||
|
m_firstDiagnostics = false;
|
||||||
|
generateTextMarks();
|
||||||
|
} else if (!m_textMarkDelay.isActive()) {
|
||||||
|
generateTextMarks();
|
||||||
|
} else {
|
||||||
|
QObject::connect(&m_textMarkDelay, &QTimer::timeout, [this]() {
|
||||||
|
generateTextMarks();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QVector<ClangBackEnd::DiagnosticContainer> &
|
const QVector<ClangBackEnd::DiagnosticContainer> &
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
|
#include <QTimer>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -82,8 +83,10 @@ private:
|
|||||||
QList<QTextEdit::ExtraSelection> m_extraSelections;
|
QList<QTextEdit::ExtraSelection> m_extraSelections;
|
||||||
TextEditor::RefactorMarkers m_fixItAvailableMarkers;
|
TextEditor::RefactorMarkers m_fixItAvailableMarkers;
|
||||||
std::vector<ClangTextMark *> m_clangTextMarks;
|
std::vector<ClangTextMark *> m_clangTextMarks;
|
||||||
|
bool m_firstDiagnostics = true;
|
||||||
bool m_diagnosticsInvalidated = false;
|
bool m_diagnosticsInvalidated = false;
|
||||||
bool m_showTextMarkAnnotations = false;
|
bool m_showTextMarkAnnotations = false;
|
||||||
|
QTimer m_textMarkDelay;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ bool ClangStaticAnalyzerPlugin::initialize(const QStringList &arguments, QString
|
|||||||
};
|
};
|
||||||
|
|
||||||
RunControl::registerWorker<ClangStaticAnalyzerToolRunner>
|
RunControl::registerWorker<ClangStaticAnalyzerToolRunner>
|
||||||
(Constants::CLANGSTATICANALYZER_RUN_MODE, constraint);
|
(Constants::CLANGSTATICANALYZER_RUN_MODE, constraint, /*priority*/ -1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,7 +79,9 @@ ClangStaticAnalyzerToolRunner::ClangStaticAnalyzerToolRunner(RunControl *runCont
|
|||||||
|
|
||||||
RunConfiguration *runConfiguration = runControl->runConfiguration();
|
RunConfiguration *runConfiguration = runControl->runConfiguration();
|
||||||
auto tool = ClangStaticAnalyzerTool::instance();
|
auto tool = ClangStaticAnalyzerTool::instance();
|
||||||
|
tool->stopAction()->disconnect();
|
||||||
connect(tool->stopAction(), &QAction::triggered, runControl, &RunControl::initiateStop);
|
connect(tool->stopAction(), &QAction::triggered, runControl, &RunControl::initiateStop);
|
||||||
|
tool->handleWorkerStart(this);
|
||||||
|
|
||||||
ProjectInfo projectInfoBeforeBuild = tool->projectInfoBeforeBuild();
|
ProjectInfo projectInfoBeforeBuild = tool->projectInfoBeforeBuild();
|
||||||
QTC_ASSERT(projectInfoBeforeBuild.isValid(), return);
|
QTC_ASSERT(projectInfoBeforeBuild.isValid(), return);
|
||||||
@@ -495,10 +497,14 @@ void ClangStaticAnalyzerToolRunner::start()
|
|||||||
m_success = false;
|
m_success = false;
|
||||||
ClangStaticAnalyzerTool::instance()->onEngineIsStarting();
|
ClangStaticAnalyzerTool::instance()->onEngineIsStarting();
|
||||||
|
|
||||||
|
connect(runControl(), &RunControl::stopped, this, [this] {
|
||||||
|
ClangStaticAnalyzerTool::instance()->onEngineFinished(m_success);
|
||||||
|
});
|
||||||
|
|
||||||
QTC_ASSERT(m_projectInfo.isValid(), reportFailure(); return);
|
QTC_ASSERT(m_projectInfo.isValid(), reportFailure(); return);
|
||||||
const Utils::FileName projectFile = m_projectInfo.project()->projectFilePath();
|
const Utils::FileName projectFile = m_projectInfo.project()->projectFilePath();
|
||||||
appendMessage(tr("Running Clang Static Analyzer on %1").arg(projectFile.toUserOutput())
|
appendMessage(tr("Running Clang Static Analyzer on %1").arg(projectFile.toUserOutput()),
|
||||||
+ QLatin1Char('\n'), Utils::NormalMessageFormat);
|
Utils::NormalMessageFormat);
|
||||||
|
|
||||||
// Check clang executable
|
// Check clang executable
|
||||||
bool isValidClangExecutable;
|
bool isValidClangExecutable;
|
||||||
@@ -507,7 +513,7 @@ void ClangStaticAnalyzerToolRunner::start()
|
|||||||
if (!isValidClangExecutable) {
|
if (!isValidClangExecutable) {
|
||||||
const QString errorMessage = tr("Clang Static Analyzer: Invalid executable \"%1\", stop.")
|
const QString errorMessage = tr("Clang Static Analyzer: Invalid executable \"%1\", stop.")
|
||||||
.arg(executable);
|
.arg(executable);
|
||||||
appendMessage(errorMessage + QLatin1Char('\n'), Utils::ErrorMessageFormat);
|
appendMessage(errorMessage, Utils::ErrorMessageFormat);
|
||||||
TaskHub::addTask(Task::Error, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
|
TaskHub::addTask(Task::Error, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
|
||||||
TaskHub::requestPopup();
|
TaskHub::requestPopup();
|
||||||
reportFailure();
|
reportFailure();
|
||||||
@@ -522,7 +528,7 @@ void ClangStaticAnalyzerToolRunner::start()
|
|||||||
= tr("Clang Static Analyzer: Running with possibly unsupported version, "
|
= tr("Clang Static Analyzer: Running with possibly unsupported version, "
|
||||||
"could not determine version from executable \"%1\".")
|
"could not determine version from executable \"%1\".")
|
||||||
.arg(versionCheckExecutable);
|
.arg(versionCheckExecutable);
|
||||||
appendMessage(warningMessage + QLatin1Char('\n'), Utils::StdErrFormat);
|
appendMessage(warningMessage, Utils::StdErrFormat);
|
||||||
TaskHub::addTask(Task::Warning, warningMessage, Debugger::Constants::ANALYZERTASK_ID);
|
TaskHub::addTask(Task::Warning, warningMessage, Debugger::Constants::ANALYZERTASK_ID);
|
||||||
TaskHub::requestPopup();
|
TaskHub::requestPopup();
|
||||||
} else if (!version.isSupportedVersion()) {
|
} else if (!version.isSupportedVersion()) {
|
||||||
@@ -531,7 +537,7 @@ void ClangStaticAnalyzerToolRunner::start()
|
|||||||
"supported version is %2.")
|
"supported version is %2.")
|
||||||
.arg(version.toString())
|
.arg(version.toString())
|
||||||
.arg(ClangExecutableVersion::supportedVersionAsString());
|
.arg(ClangExecutableVersion::supportedVersionAsString());
|
||||||
appendMessage(warningMessage + QLatin1Char('\n'), Utils::StdErrFormat);
|
appendMessage(warningMessage, Utils::StdErrFormat);
|
||||||
TaskHub::addTask(Task::Warning, warningMessage, Debugger::Constants::ANALYZERTASK_ID);
|
TaskHub::addTask(Task::Warning, warningMessage, Debugger::Constants::ANALYZERTASK_ID);
|
||||||
TaskHub::requestPopup();
|
TaskHub::requestPopup();
|
||||||
}
|
}
|
||||||
@@ -544,7 +550,7 @@ void ClangStaticAnalyzerToolRunner::start()
|
|||||||
if (!temporaryDir.isValid()) {
|
if (!temporaryDir.isValid()) {
|
||||||
const QString errorMessage
|
const QString errorMessage
|
||||||
= tr("Clang Static Analyzer: Failed to create temporary dir, stop.");
|
= tr("Clang Static Analyzer: Failed to create temporary dir, stop.");
|
||||||
appendMessage(errorMessage + QLatin1Char('\n'), Utils::ErrorMessageFormat);
|
appendMessage(errorMessage, Utils::ErrorMessageFormat);
|
||||||
TaskHub::addTask(Task::Error, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
|
TaskHub::addTask(Task::Error, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
|
||||||
TaskHub::requestPopup();
|
TaskHub::requestPopup();
|
||||||
reportFailure(errorMessage);
|
reportFailure(errorMessage);
|
||||||
@@ -599,15 +605,11 @@ void ClangStaticAnalyzerToolRunner::stop()
|
|||||||
}
|
}
|
||||||
m_runners.clear();
|
m_runners.clear();
|
||||||
m_unitsToProcess.clear();
|
m_unitsToProcess.clear();
|
||||||
appendMessage(tr("Clang Static Analyzer stopped by user.") + QLatin1Char('\n'),
|
appendMessage(tr("Clang Static Analyzer stopped by user."),
|
||||||
Utils::NormalMessageFormat);
|
Utils::NormalMessageFormat);
|
||||||
m_progress.reportFinished();
|
m_progress.reportFinished();
|
||||||
reportStopped();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClangStaticAnalyzerToolRunner::onFinished()
|
|
||||||
{
|
|
||||||
ClangStaticAnalyzerTool::instance()->onEngineFinished(m_success);
|
ClangStaticAnalyzerTool::instance()->onEngineFinished(m_success);
|
||||||
|
reportStopped();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangStaticAnalyzerToolRunner::analyzeNextFile()
|
void ClangStaticAnalyzerToolRunner::analyzeNextFile()
|
||||||
@@ -629,7 +631,7 @@ void ClangStaticAnalyzerToolRunner::analyzeNextFile()
|
|||||||
QTC_ASSERT(runner->run(unit.file, unit.arguments), return);
|
QTC_ASSERT(runner->run(unit.file, unit.arguments), return);
|
||||||
|
|
||||||
appendMessage(tr("Analyzing \"%1\".").arg(
|
appendMessage(tr("Analyzing \"%1\".").arg(
|
||||||
Utils::FileName::fromString(unit.file).toUserOutput()) + QLatin1Char('\n'),
|
Utils::FileName::fromString(unit.file).toUserOutput()),
|
||||||
Utils::StdOutFormat);
|
Utils::StdOutFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -658,9 +660,8 @@ void ClangStaticAnalyzerToolRunner::onRunnerFinishedWithSuccess(const QString &l
|
|||||||
if (!errorMessage.isEmpty()) {
|
if (!errorMessage.isEmpty()) {
|
||||||
qCDebug(LOG) << "onRunnerFinishedWithSuccess: Error reading log file:" << errorMessage;
|
qCDebug(LOG) << "onRunnerFinishedWithSuccess: Error reading log file:" << errorMessage;
|
||||||
const QString filePath = qobject_cast<ClangStaticAnalyzerRunner *>(sender())->filePath();
|
const QString filePath = qobject_cast<ClangStaticAnalyzerRunner *>(sender())->filePath();
|
||||||
appendMessage(tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage)
|
appendMessage(tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage),
|
||||||
+ QLatin1Char('\n')
|
Utils::StdErrFormat);
|
||||||
, Utils::StdErrFormat);
|
|
||||||
} else {
|
} else {
|
||||||
++m_filesAnalyzed;
|
++m_filesAnalyzed;
|
||||||
if (!diagnostics.isEmpty())
|
if (!diagnostics.isEmpty())
|
||||||
@@ -679,9 +680,8 @@ void ClangStaticAnalyzerToolRunner::onRunnerFinishedWithFailure(const QString &e
|
|||||||
++m_filesNotAnalyzed;
|
++m_filesNotAnalyzed;
|
||||||
m_success = false;
|
m_success = false;
|
||||||
const QString filePath = qobject_cast<ClangStaticAnalyzerRunner *>(sender())->filePath();
|
const QString filePath = qobject_cast<ClangStaticAnalyzerRunner *>(sender())->filePath();
|
||||||
appendMessage(tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage)
|
appendMessage(tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage),
|
||||||
+ QLatin1Char('\n')
|
Utils::StdErrFormat);
|
||||||
, Utils::StdErrFormat);
|
|
||||||
appendMessage(errorDetails, Utils::StdErrFormat);
|
appendMessage(errorDetails, Utils::StdErrFormat);
|
||||||
TaskHub::addTask(Task::Warning, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
|
TaskHub::addTask(Task::Warning, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
|
||||||
TaskHub::addTask(Task::Warning, errorDetails, Debugger::Constants::ANALYZERTASK_ID);
|
TaskHub::addTask(Task::Warning, errorDetails, Debugger::Constants::ANALYZERTASK_ID);
|
||||||
@@ -699,7 +699,7 @@ void ClangStaticAnalyzerToolRunner::handleFinished()
|
|||||||
void ClangStaticAnalyzerToolRunner::onProgressCanceled()
|
void ClangStaticAnalyzerToolRunner::onProgressCanceled()
|
||||||
{
|
{
|
||||||
m_progress.reportCanceled();
|
m_progress.reportCanceled();
|
||||||
stop();
|
runControl()->initiateStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangStaticAnalyzerToolRunner::updateProgressValue()
|
void ClangStaticAnalyzerToolRunner::updateProgressValue()
|
||||||
@@ -711,9 +711,7 @@ void ClangStaticAnalyzerToolRunner::finalize()
|
|||||||
{
|
{
|
||||||
appendMessage(tr("Clang Static Analyzer finished: "
|
appendMessage(tr("Clang Static Analyzer finished: "
|
||||||
"Processed %1 files successfully, %2 failed.")
|
"Processed %1 files successfully, %2 failed.")
|
||||||
.arg(m_filesAnalyzed)
|
.arg(m_filesAnalyzed).arg(m_filesNotAnalyzed),
|
||||||
.arg(m_filesNotAnalyzed)
|
|
||||||
+ QLatin1Char('\n'),
|
|
||||||
Utils::NormalMessageFormat);
|
Utils::NormalMessageFormat);
|
||||||
|
|
||||||
if (m_filesNotAnalyzed != 0) {
|
if (m_filesNotAnalyzed != 0) {
|
||||||
@@ -723,7 +721,7 @@ void ClangStaticAnalyzerToolRunner::finalize()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_progress.reportFinished();
|
m_progress.reportFinished();
|
||||||
reportStopped();
|
runControl()->initiateStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -56,7 +56,6 @@ public:
|
|||||||
|
|
||||||
void start() override;
|
void start() override;
|
||||||
void stop() override;
|
void stop() override;
|
||||||
void onFinished() override;
|
|
||||||
|
|
||||||
bool success() const { return m_success; } // For testing.
|
bool success() const { return m_success; } // For testing.
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,6 @@ ClangStaticAnalyzerTool::ClangStaticAnalyzerTool()
|
|||||||
{{ClangStaticAnalyzerDockId, m_diagnosticView, {}, Perspective::SplitVertical}}
|
{{ClangStaticAnalyzerDockId, m_diagnosticView, {}, Perspective::SplitVertical}}
|
||||||
));
|
));
|
||||||
|
|
||||||
//Debugger::registerAction(Constants::CLANGSTATICANALYZER_RUN_MODE, {});
|
|
||||||
action = new QAction(tr("Clang Static Analyzer"), this);
|
action = new QAction(tr("Clang Static Analyzer"), this);
|
||||||
action->setToolTip(toolTip);
|
action->setToolTip(toolTip);
|
||||||
menu->addAction(ActionManager::registerAction(action, "ClangStaticAnalyzer.Action"),
|
menu->addAction(ActionManager::registerAction(action, "ClangStaticAnalyzer.Action"),
|
||||||
@@ -211,14 +210,12 @@ static bool dontStartAfterHintForDebugMode(Project *project)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangStaticAnalyzerTool::startTool()
|
void ClangStaticAnalyzerTool::handleWorkerStart(RunWorker *runWorker)
|
||||||
{
|
{
|
||||||
Project *project = SessionManager::startupProject();
|
RunControl *runControl = runWorker->runControl();
|
||||||
|
Project *project = runControl->project();
|
||||||
QTC_ASSERT(project, emit finished(false); return);
|
QTC_ASSERT(project, emit finished(false); return);
|
||||||
|
|
||||||
if (dontStartAfterHintForDebugMode(project))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Debugger::selectPerspective(ClangStaticAnalyzerPerspectiveId);
|
Debugger::selectPerspective(ClangStaticAnalyzerPerspectiveId);
|
||||||
m_diagnosticModel->clear();
|
m_diagnosticModel->clear();
|
||||||
setBusyCursor(true);
|
setBusyCursor(true);
|
||||||
@@ -230,8 +227,13 @@ void ClangStaticAnalyzerTool::startTool()
|
|||||||
|
|
||||||
m_toolBusy = true;
|
m_toolBusy = true;
|
||||||
updateRunActions();
|
updateRunActions();
|
||||||
|
}
|
||||||
|
|
||||||
Target * const target = project->activeTarget();
|
void ClangStaticAnalyzerTool::startTool()
|
||||||
|
{
|
||||||
|
Project *project = SessionManager::startupProject();
|
||||||
|
QTC_ASSERT(project, return);
|
||||||
|
Target *target = project->activeTarget();
|
||||||
QTC_ASSERT(target, return);
|
QTC_ASSERT(target, return);
|
||||||
DummyRunConfiguration *& rc = m_runConfigs[target];
|
DummyRunConfiguration *& rc = m_runConfigs[target];
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
@@ -245,6 +247,9 @@ void ClangStaticAnalyzerTool::startTool()
|
|||||||
connect(SessionManager::instance(), &SessionManager::aboutToRemoveProject, this,
|
connect(SessionManager::instance(), &SessionManager::aboutToRemoveProject, this,
|
||||||
onProjectRemoved, Qt::UniqueConnection);
|
onProjectRemoved, Qt::UniqueConnection);
|
||||||
}
|
}
|
||||||
|
if (dontStartAfterHintForDebugMode(project))
|
||||||
|
return;
|
||||||
|
|
||||||
ProjectExplorerPlugin::runRunConfiguration(rc, Constants::CLANGSTATICANALYZER_RUN_MODE);
|
ProjectExplorerPlugin::runRunConfiguration(rc, Constants::CLANGSTATICANALYZER_RUN_MODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,9 +58,10 @@ public:
|
|||||||
|
|
||||||
// For testing.
|
// For testing.
|
||||||
QList<Diagnostic> diagnostics() const;
|
QList<Diagnostic> diagnostics() const;
|
||||||
|
|
||||||
void startTool();
|
void startTool();
|
||||||
|
|
||||||
|
void handleWorkerStart(ProjectExplorer::RunWorker *runWorker);
|
||||||
|
|
||||||
void onEngineIsStarting();
|
void onEngineIsStarting();
|
||||||
void onNewDiagnosticsAvailable(const QList<Diagnostic> &diagnostics);
|
void onNewDiagnosticsAvailable(const QList<Diagnostic> &diagnostics);
|
||||||
void onEngineFinished(bool success);
|
void onEngineFinished(bool success);
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public:
|
|||||||
invalidateFilter();
|
invalidateFilter();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
|
||||||
{
|
{
|
||||||
if (!sourceParent.isValid())
|
if (!sourceParent.isValid())
|
||||||
return true;
|
return true;
|
||||||
@@ -91,6 +91,21 @@ public:
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
|
||||||
|
{
|
||||||
|
if (role == Qt::DecorationRole) {
|
||||||
|
// scale too small icons to have one size for all
|
||||||
|
QIcon icon = qvariant_cast<QIcon>(QSortFilterProxyModel::data(index, role));
|
||||||
|
if (!icon.isNull()) {
|
||||||
|
QPixmap pixmap(icon.pixmap(ICON_SIZE, ICON_SIZE));
|
||||||
|
if (pixmap.size() != QSize(ICON_SIZE, ICON_SIZE))
|
||||||
|
return pixmap.scaled(ICON_SIZE, ICON_SIZE, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QSortFilterProxyModel::data(index, role);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Core::Id m_platform;
|
Core::Id m_platform;
|
||||||
};
|
};
|
||||||
@@ -101,18 +116,18 @@ class TwoLevelProxyModel : public QAbstractProxyModel
|
|||||||
public:
|
public:
|
||||||
TwoLevelProxyModel(QObject *parent = 0): QAbstractProxyModel(parent) {}
|
TwoLevelProxyModel(QObject *parent = 0): QAbstractProxyModel(parent) {}
|
||||||
|
|
||||||
QModelIndex index(int row, int column, const QModelIndex &parent) const
|
QModelIndex index(int row, int column, const QModelIndex &parent) const override
|
||||||
{
|
{
|
||||||
QModelIndex ourModelIndex = sourceModel()->index(row, column, mapToSource(parent));
|
QModelIndex ourModelIndex = sourceModel()->index(row, column, mapToSource(parent));
|
||||||
return createIndex(row, column, ourModelIndex.internalPointer());
|
return createIndex(row, column, ourModelIndex.internalPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex parent(const QModelIndex &index) const
|
QModelIndex parent(const QModelIndex &index) const override
|
||||||
{
|
{
|
||||||
return mapFromSource(mapToSource(index).parent());
|
return mapFromSource(mapToSource(index).parent());
|
||||||
}
|
}
|
||||||
|
|
||||||
int rowCount(const QModelIndex &index) const
|
int rowCount(const QModelIndex &index) const override
|
||||||
{
|
{
|
||||||
if (index.isValid() && index.parent().isValid() && !index.parent().parent().isValid())
|
if (index.isValid() && index.parent().isValid() && !index.parent().parent().isValid())
|
||||||
return 0;
|
return 0;
|
||||||
@@ -120,19 +135,19 @@ public:
|
|||||||
return sourceModel()->rowCount(mapToSource(index));
|
return sourceModel()->rowCount(mapToSource(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
int columnCount(const QModelIndex &index) const
|
int columnCount(const QModelIndex &index) const override
|
||||||
{
|
{
|
||||||
return sourceModel()->columnCount(mapToSource(index));
|
return sourceModel()->columnCount(mapToSource(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex mapFromSource (const QModelIndex &index) const
|
QModelIndex mapFromSource (const QModelIndex &index) const override
|
||||||
{
|
{
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
return createIndex(index.row(), index.column(), index.internalPointer());
|
return createIndex(index.row(), index.column(), index.internalPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex mapToSource (const QModelIndex &index) const
|
QModelIndex mapToSource (const QModelIndex &index) const override
|
||||||
{
|
{
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return QModelIndex();
|
return QModelIndex();
|
||||||
@@ -148,7 +163,7 @@ public:
|
|||||||
FancyTopLevelDelegate(QObject *parent = 0)
|
FancyTopLevelDelegate(QObject *parent = 0)
|
||||||
: QItemDelegate(parent) {}
|
: QItemDelegate(parent) {}
|
||||||
|
|
||||||
void drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const
|
void drawDisplay(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect, const QString &text) const override
|
||||||
{
|
{
|
||||||
QStyleOptionViewItem newoption = option;
|
QStyleOptionViewItem newoption = option;
|
||||||
if (!(option.state & QStyle::State_Enabled)) {
|
if (!(option.state & QStyle::State_Enabled)) {
|
||||||
@@ -168,11 +183,10 @@ public:
|
|||||||
QItemDelegate::drawDisplay(painter, newoption, rect, text);
|
QItemDelegate::drawDisplay(painter, newoption, rect, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
|
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
|
||||||
{
|
{
|
||||||
QSize size = QItemDelegate::sizeHint(option, index);
|
QSize size = QItemDelegate::sizeHint(option, index);
|
||||||
|
|
||||||
|
|
||||||
size = size.expandedTo(QSize(0, ROW_HEIGHT));
|
size = size.expandedTo(QSize(0, ROW_HEIGHT));
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
|
|||||||
@@ -483,6 +483,16 @@ void CompletionList::keyPressEvent(QKeyEvent *event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case Qt::Key_Return:
|
||||||
|
case Qt::Key_Enter:
|
||||||
|
// emit activated even if current index is not valid
|
||||||
|
// if there are no results yet, this allows activating the first entry when it is available
|
||||||
|
// (see LocatorWidget::addSearchResults)
|
||||||
|
if (event->modifiers() == 0) {
|
||||||
|
emit activated(currentIndex());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
Utils::TreeView::keyPressEvent(event);
|
Utils::TreeView::keyPressEvent(event);
|
||||||
}
|
}
|
||||||
@@ -795,9 +805,9 @@ void LocatorWidget::handleSearchFinished()
|
|||||||
m_showProgressTimer.stop();
|
m_showProgressTimer.stop();
|
||||||
setProgressIndicatorVisible(false);
|
setProgressIndicatorVisible(false);
|
||||||
m_updateRequested = false;
|
m_updateRequested = false;
|
||||||
if (m_rowRequestedForAccept >= 0) {
|
if (m_rowRequestedForAccept) {
|
||||||
acceptEntry(m_rowRequestedForAccept);
|
acceptEntry(m_rowRequestedForAccept.value());
|
||||||
m_rowRequestedForAccept = -1;
|
m_rowRequestedForAccept.reset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_entriesWatcher->future().isCanceled()) {
|
if (m_entriesWatcher->future().isCanceled()) {
|
||||||
@@ -892,7 +902,7 @@ void LocatorWidget::addSearchResults(int firstIndex, int endIndex)
|
|||||||
m_locatorModel->addEntries(entries);
|
m_locatorModel->addEntries(entries);
|
||||||
if (selectFirst) {
|
if (selectFirst) {
|
||||||
emit selectRow(0);
|
emit selectRow(0);
|
||||||
if (m_rowRequestedForAccept >= 0)
|
if (m_rowRequestedForAccept)
|
||||||
m_rowRequestedForAccept = 0;
|
m_rowRequestedForAccept = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include "locator.h"
|
#include "locator.h"
|
||||||
|
|
||||||
|
#include <utils/optional.h>
|
||||||
|
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
@@ -99,9 +101,9 @@ private:
|
|||||||
bool m_needsClearResult = true;
|
bool m_needsClearResult = true;
|
||||||
bool m_updateRequested = false;
|
bool m_updateRequested = false;
|
||||||
bool m_possibleToolTipRequest = false;
|
bool m_possibleToolTipRequest = false;
|
||||||
int m_rowRequestedForAccept = -1;
|
|
||||||
QWidget *m_progressIndicator;
|
QWidget *m_progressIndicator;
|
||||||
QTimer m_showProgressTimer;
|
QTimer m_showProgressTimer;
|
||||||
|
Utils::optional<int> m_rowRequestedForAccept;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LocatorPopup : public QWidget
|
class LocatorPopup : public QWidget
|
||||||
|
|||||||
@@ -245,13 +245,19 @@ void CppEditorWidget::finalizeInitialization()
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Toolbar: '#' Button
|
// Toolbar: '#' Button
|
||||||
d->m_preprocessorButton = new QToolButton(this);
|
// TODO: Make "Additional Preprocessor Directives" also useful with Clang Code Model.
|
||||||
d->m_preprocessorButton->setText(QLatin1String("#"));
|
if (!d->m_modelManager->isClangCodeModelActive()) {
|
||||||
Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
|
d->m_preprocessorButton = new QToolButton(this);
|
||||||
connect(cmd, &Command::keySequenceChanged, this, &CppEditorWidget::updatePreprocessorButtonTooltip);
|
d->m_preprocessorButton->setText(QLatin1String("#"));
|
||||||
updatePreprocessorButtonTooltip();
|
Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
|
||||||
connect(d->m_preprocessorButton, &QAbstractButton::clicked, this, &CppEditorWidget::showPreProcessorWidget);
|
connect(cmd, &Command::keySequenceChanged,
|
||||||
insertExtraToolBarWidget(TextEditorWidget::Left, d->m_preprocessorButton);
|
this, &CppEditorWidget::updatePreprocessorButtonTooltip);
|
||||||
|
updatePreprocessorButtonTooltip();
|
||||||
|
connect(d->m_preprocessorButton, &QAbstractButton::clicked,
|
||||||
|
this, &CppEditorWidget::showPreProcessorWidget);
|
||||||
|
|
||||||
|
insertExtraToolBarWidget(TextEditorWidget::Left, d->m_preprocessorButton);
|
||||||
|
}
|
||||||
|
|
||||||
// Toolbar: Actions to show minimized info bars
|
// Toolbar: Actions to show minimized info bars
|
||||||
d->m_showInfoBarActions = MinimizableInfoBars::createShowInfoBarActions([this](QWidget *w) {
|
d->m_showInfoBarActions = MinimizableInfoBars::createShowInfoBarActions([this](QWidget *w) {
|
||||||
@@ -429,13 +435,16 @@ bool CppEditorWidget::selectBlockDown()
|
|||||||
|
|
||||||
void CppEditorWidget::updateWidgetHighlighting(QWidget *widget, bool highlight)
|
void CppEditorWidget::updateWidgetHighlighting(QWidget *widget, bool highlight)
|
||||||
{
|
{
|
||||||
|
if (!widget)
|
||||||
|
return;
|
||||||
|
|
||||||
widget->setProperty("highlightWidget", highlight);
|
widget->setProperty("highlightWidget", highlight);
|
||||||
widget->update();
|
widget->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CppEditorWidget::isWidgetHighlighted(QWidget *widget)
|
bool CppEditorWidget::isWidgetHighlighted(QWidget *widget)
|
||||||
{
|
{
|
||||||
return widget->property("highlightWidget").toBool();
|
return widget ? widget->property("highlightWidget").toBool() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEditorWidget::renameSymbolUnderCursor()
|
void CppEditorWidget::renameSymbolUnderCursor()
|
||||||
@@ -586,7 +595,9 @@ void CppEditorWidget::renameSymbolUnderCursorClang()
|
|||||||
|
|
||||||
void CppEditorWidget::updatePreprocessorButtonTooltip()
|
void CppEditorWidget::updatePreprocessorButtonTooltip()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(d->m_preprocessorButton, return);
|
if (!d->m_preprocessorButton)
|
||||||
|
return;
|
||||||
|
|
||||||
Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
|
Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
|
||||||
QTC_ASSERT(cmd, return);
|
QTC_ASSERT(cmd, return);
|
||||||
d->m_preprocessorButton->setToolTip(cmd->action()->toolTip());
|
d->m_preprocessorButton->setToolTip(cmd->action()->toolTip());
|
||||||
|
|||||||
@@ -201,12 +201,17 @@ void CppEditorDocument::onAboutToReload()
|
|||||||
{
|
{
|
||||||
QTC_CHECK(!m_fileIsBeingReloaded);
|
QTC_CHECK(!m_fileIsBeingReloaded);
|
||||||
m_fileIsBeingReloaded = true;
|
m_fileIsBeingReloaded = true;
|
||||||
|
|
||||||
|
processor()->invalidateDiagnostics();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEditorDocument::onReloadFinished()
|
void CppEditorDocument::onReloadFinished()
|
||||||
{
|
{
|
||||||
QTC_CHECK(m_fileIsBeingReloaded);
|
QTC_CHECK(m_fileIsBeingReloaded);
|
||||||
m_fileIsBeingReloaded = false;
|
m_fileIsBeingReloaded = false;
|
||||||
|
|
||||||
|
m_processorRevision = document()->revision();
|
||||||
|
processDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppEditorDocument::reparseWithPreferredParseContext(const QString &parseContextId)
|
void CppEditorDocument::reparseWithPreferredParseContext(const QString &parseContextId)
|
||||||
@@ -250,6 +255,9 @@ void CppEditorDocument::onFilePathChanged(const Utils::FileName &oldPath,
|
|||||||
|
|
||||||
void CppEditorDocument::scheduleProcessDocument()
|
void CppEditorDocument::scheduleProcessDocument()
|
||||||
{
|
{
|
||||||
|
if (m_fileIsBeingReloaded)
|
||||||
|
return;
|
||||||
|
|
||||||
m_processorRevision = document()->revision();
|
m_processorRevision = document()->revision();
|
||||||
m_processorTimer.start();
|
m_processorTimer.start();
|
||||||
processor()->editorDocumentTimerRestarted();
|
processor()->editorDocumentTimerRestarted();
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
|
|
||||||
#include <utils/fancylineedit.h>
|
#include <utils/fancylineedit.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/qtcfallthrough.h>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
@@ -4119,7 +4120,7 @@ public:
|
|||||||
break;
|
break;
|
||||||
case FromReference:
|
case FromReference:
|
||||||
removeReferenceOperator(changes);
|
removeReferenceOperator(changes);
|
||||||
// fallthrough intended
|
Q_FALLTHROUGH();
|
||||||
case FromVariable:
|
case FromVariable:
|
||||||
convertToPointer(changes);
|
convertToPointer(changes);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -98,8 +98,12 @@ void CppUseSelectionsUpdater::update(CallType callType)
|
|||||||
|
|
||||||
// QFuture::waitForFinished seems to block completely, not even
|
// QFuture::waitForFinished seems to block completely, not even
|
||||||
// allowing to process events from QLocalSocket.
|
// allowing to process events from QLocalSocket.
|
||||||
while (!future.isFinished())
|
while (!future.isFinished()) {
|
||||||
|
if (future.isCanceled())
|
||||||
|
return;
|
||||||
|
|
||||||
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||||
|
}
|
||||||
|
|
||||||
processResults(future.result());
|
processResults(future.result());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#include "compileroptionsbuilder.h"
|
#include "compileroptionsbuilder.h"
|
||||||
|
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
#include <utils/qtcfallthrough.h>
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
@@ -201,7 +202,8 @@ static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objc
|
|||||||
if (!objcExt) {
|
if (!objcExt) {
|
||||||
opts += QLatin1String("c++-header");
|
opts += QLatin1String("c++-header");
|
||||||
break;
|
break;
|
||||||
} // else: fall-through!
|
}
|
||||||
|
Q_FALLTHROUGH();
|
||||||
case ProjectFile::ObjCHeader:
|
case ProjectFile::ObjCHeader:
|
||||||
case ProjectFile::ObjCXXHeader:
|
case ProjectFile::ObjCXXHeader:
|
||||||
opts += QLatin1String("objective-c++-header");
|
opts += QLatin1String("objective-c++-header");
|
||||||
@@ -211,7 +213,8 @@ static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objc
|
|||||||
if (!objcExt) {
|
if (!objcExt) {
|
||||||
opts += QLatin1String("c");
|
opts += QLatin1String("c");
|
||||||
break;
|
break;
|
||||||
} // else: fall-through!
|
}
|
||||||
|
Q_FALLTHROUGH();
|
||||||
case ProjectFile::ObjCSource:
|
case ProjectFile::ObjCSource:
|
||||||
opts += QLatin1String("objective-c");
|
opts += QLatin1String("objective-c");
|
||||||
break;
|
break;
|
||||||
@@ -220,7 +223,8 @@ static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objc
|
|||||||
if (!objcExt) {
|
if (!objcExt) {
|
||||||
opts += QLatin1String("c++");
|
opts += QLatin1String("c++");
|
||||||
break;
|
break;
|
||||||
} // else: fall-through!
|
}
|
||||||
|
Q_FALLTHROUGH();
|
||||||
case ProjectFile::ObjCXXSource:
|
case ProjectFile::ObjCXXSource:
|
||||||
opts += QLatin1String("objective-c++");
|
opts += QLatin1String("objective-c++");
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ class StartApplicationDialogPrivate
|
|||||||
public:
|
public:
|
||||||
KitChooser *kitChooser;
|
KitChooser *kitChooser;
|
||||||
QLabel *serverPortLabel;
|
QLabel *serverPortLabel;
|
||||||
QLabel *serverAddressLabel;
|
QLabel *channelOverrideLabel;
|
||||||
QLineEdit *serverAddressEdit;
|
QLineEdit *channelOverrideEdit;
|
||||||
QSpinBox *serverPortSpinBox;
|
QSpinBox *serverPortSpinBox;
|
||||||
PathChooser *localExecutablePathChooser;
|
PathChooser *localExecutablePathChooser;
|
||||||
FancyLineEdit *arguments;
|
FancyLineEdit *arguments;
|
||||||
@@ -235,8 +235,11 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent)
|
|||||||
d->serverPortSpinBox = new QSpinBox(this);
|
d->serverPortSpinBox = new QSpinBox(this);
|
||||||
d->serverPortSpinBox->setRange(1, 65535);
|
d->serverPortSpinBox->setRange(1, 65535);
|
||||||
|
|
||||||
d->serverAddressLabel = new QLabel(tr("Override server address"), this);
|
d->channelOverrideLabel = new QLabel(tr("Override server channel:"), this);
|
||||||
d->serverAddressEdit = new QLineEdit(this);
|
d->channelOverrideEdit = new QLineEdit(this);
|
||||||
|
//: "For example, /dev/ttyS0, COM1, 127.0.0.1:1234"
|
||||||
|
d->channelOverrideEdit->setPlaceholderText(
|
||||||
|
tr("For example, %1").arg("/dev/ttyS0, COM1, 127.0.0.1:1234"));
|
||||||
|
|
||||||
d->localExecutablePathChooser = new PathChooser(this);
|
d->localExecutablePathChooser = new PathChooser(this);
|
||||||
d->localExecutablePathChooser->setExpectedKind(PathChooser::File);
|
d->localExecutablePathChooser->setExpectedKind(PathChooser::File);
|
||||||
@@ -292,7 +295,6 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent)
|
|||||||
formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
|
formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
|
||||||
formLayout->addRow(tr("&Kit:"), d->kitChooser);
|
formLayout->addRow(tr("&Kit:"), d->kitChooser);
|
||||||
formLayout->addRow(d->serverPortLabel, d->serverPortSpinBox);
|
formLayout->addRow(d->serverPortLabel, d->serverPortSpinBox);
|
||||||
formLayout->addRow(d->serverAddressLabel, d->serverAddressEdit);
|
|
||||||
formLayout->addRow(tr("Local &executable:"), d->localExecutablePathChooser);
|
formLayout->addRow(tr("Local &executable:"), d->localExecutablePathChooser);
|
||||||
formLayout->addRow(tr("Command line &arguments:"), d->arguments);
|
formLayout->addRow(tr("Command line &arguments:"), d->arguments);
|
||||||
formLayout->addRow(tr("&Working directory:"), d->workingDirectory);
|
formLayout->addRow(tr("&Working directory:"), d->workingDirectory);
|
||||||
@@ -300,6 +302,11 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent)
|
|||||||
formLayout->addRow(tr("Break at \"&main\":"), d->breakAtMainCheckBox);
|
formLayout->addRow(tr("Break at \"&main\":"), d->breakAtMainCheckBox);
|
||||||
formLayout->addRow(d->serverStartScriptLabel, d->serverStartScriptPathChooser);
|
formLayout->addRow(d->serverStartScriptLabel, d->serverStartScriptPathChooser);
|
||||||
formLayout->addRow(tr("Debug &information:"), d->debuginfoPathChooser);
|
formLayout->addRow(tr("Debug &information:"), d->debuginfoPathChooser);
|
||||||
|
formLayout->addRow(new QLabel(tr("Normally, the running server is identified by the IP of the "
|
||||||
|
"device in the kit and the server port selected above.\n"
|
||||||
|
"You can choose another communication channel here, such as "
|
||||||
|
"a serial line or custom ip:port.")));
|
||||||
|
formLayout->addRow(d->channelOverrideLabel, d->channelOverrideEdit);
|
||||||
formLayout->addRow(line2);
|
formLayout->addRow(line2);
|
||||||
formLayout->addRow(tr("&Recent:"), d->historyComboBox);
|
formLayout->addRow(tr("&Recent:"), d->historyComboBox);
|
||||||
|
|
||||||
@@ -316,6 +323,9 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent)
|
|||||||
connect(d->historyComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
connect(d->historyComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
|
||||||
this, &StartApplicationDialog::historyIndexChanged);
|
this, &StartApplicationDialog::historyIndexChanged);
|
||||||
|
|
||||||
|
connect(d->channelOverrideEdit, &QLineEdit::textChanged,
|
||||||
|
this, &StartApplicationDialog::onChannelOverrideChanged);
|
||||||
|
|
||||||
updateState();
|
updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,6 +344,12 @@ void StartApplicationDialog::setHistory(const QList<StartApplicationParameters>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StartApplicationDialog::onChannelOverrideChanged(const QString &channel)
|
||||||
|
{
|
||||||
|
d->serverPortSpinBox->setEnabled(channel.isEmpty());
|
||||||
|
d->serverPortLabel->setEnabled(channel.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
void StartApplicationDialog::historyIndexChanged(int index)
|
void StartApplicationDialog::historyIndexChanged(int index)
|
||||||
{
|
{
|
||||||
if (index < 0)
|
if (index < 0)
|
||||||
@@ -379,8 +395,8 @@ bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp, Kit
|
|||||||
dialog.d->serverStartScriptLabel->setVisible(false);
|
dialog.d->serverStartScriptLabel->setVisible(false);
|
||||||
dialog.d->serverPortSpinBox->setVisible(false);
|
dialog.d->serverPortSpinBox->setVisible(false);
|
||||||
dialog.d->serverPortLabel->setVisible(false);
|
dialog.d->serverPortLabel->setVisible(false);
|
||||||
dialog.d->serverAddressLabel->setVisible(false);
|
dialog.d->channelOverrideLabel->setVisible(false);
|
||||||
dialog.d->serverAddressEdit->setVisible(false);
|
dialog.d->channelOverrideEdit->setVisible(false);
|
||||||
}
|
}
|
||||||
if (dialog.exec() != QDialog::Accepted)
|
if (dialog.exec() != QDialog::Accepted)
|
||||||
return false;
|
return false;
|
||||||
@@ -404,7 +420,7 @@ bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp, Kit
|
|||||||
}
|
}
|
||||||
|
|
||||||
rp->inferior.executable = newParameters.runnable.executable;
|
rp->inferior.executable = newParameters.runnable.executable;
|
||||||
const QString inputAddress = dialog.d->serverAddressEdit->text();
|
const QString inputAddress = dialog.d->channelOverrideEdit->text();
|
||||||
if (!inputAddress.isEmpty())
|
if (!inputAddress.isEmpty())
|
||||||
rp->remoteChannel = inputAddress;
|
rp->remoteChannel = inputAddress;
|
||||||
else
|
else
|
||||||
@@ -430,7 +446,7 @@ StartApplicationParameters StartApplicationDialog::parameters() const
|
|||||||
{
|
{
|
||||||
StartApplicationParameters result;
|
StartApplicationParameters result;
|
||||||
result.serverPort = d->serverPortSpinBox->value();
|
result.serverPort = d->serverPortSpinBox->value();
|
||||||
result.serverAddress = d->serverAddressEdit->text();
|
result.serverAddress = d->channelOverrideEdit->text();
|
||||||
result.runnable.executable = d->localExecutablePathChooser->path();
|
result.runnable.executable = d->localExecutablePathChooser->path();
|
||||||
result.serverStartScript = d->serverStartScriptPathChooser->path();
|
result.serverStartScript = d->serverStartScriptPathChooser->path();
|
||||||
result.kitId = d->kitChooser->currentKitId();
|
result.kitId = d->kitChooser->currentKitId();
|
||||||
@@ -447,7 +463,7 @@ void StartApplicationDialog::setParameters(const StartApplicationParameters &p)
|
|||||||
{
|
{
|
||||||
d->kitChooser->setCurrentKitId(p.kitId);
|
d->kitChooser->setCurrentKitId(p.kitId);
|
||||||
d->serverPortSpinBox->setValue(p.serverPort);
|
d->serverPortSpinBox->setValue(p.serverPort);
|
||||||
d->serverAddressEdit->setText(p.serverAddress);
|
d->channelOverrideEdit->setText(p.serverAddress);
|
||||||
d->localExecutablePathChooser->setPath(p.runnable.executable);
|
d->localExecutablePathChooser->setPath(p.runnable.executable);
|
||||||
d->serverStartScriptPathChooser->setPath(p.serverStartScript);
|
d->serverStartScriptPathChooser->setPath(p.serverStartScript);
|
||||||
d->debuginfoPathChooser->setPath(p.debugInfoLocation);
|
d->debuginfoPathChooser->setPath(p.debugInfoLocation);
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ private:
|
|||||||
StartApplicationParameters parameters() const;
|
StartApplicationParameters parameters() const;
|
||||||
void setParameters(const StartApplicationParameters &p);
|
void setParameters(const StartApplicationParameters &p);
|
||||||
void setHistory(const QList<StartApplicationParameters> &l);
|
void setHistory(const QList<StartApplicationParameters> &l);
|
||||||
|
void onChannelOverrideChanged(const QString &channel);
|
||||||
|
|
||||||
StartApplicationDialogPrivate *d;
|
StartApplicationDialogPrivate *d;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -292,12 +292,6 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void raiseApplication()
|
|
||||||
{
|
|
||||||
QTC_ASSERT(runControl(), return);
|
|
||||||
runControl()->bringApplicationToForeground();
|
|
||||||
}
|
|
||||||
|
|
||||||
void scheduleResetLocation()
|
void scheduleResetLocation()
|
||||||
{
|
{
|
||||||
m_stackHandler.scheduleResetLocation();
|
m_stackHandler.scheduleResetLocation();
|
||||||
@@ -1323,7 +1317,7 @@ void DebuggerEngine::notifyInferiorPid(const ProcessHandle &pid)
|
|||||||
showMessage(tr("Taking notice of pid %1").arg(pid.pid()));
|
showMessage(tr("Taking notice of pid %1").arg(pid.pid()));
|
||||||
DebuggerStartMode sm = runParameters().startMode;
|
DebuggerStartMode sm = runParameters().startMode;
|
||||||
if (sm == StartInternal || sm == StartExternal || sm == AttachExternal)
|
if (sm == StartInternal || sm == StartExternal || sm == AttachExternal)
|
||||||
QTimer::singleShot(0, d, &DebuggerEnginePrivate::raiseApplication);
|
d->m_inferiorPid.activate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -421,18 +421,6 @@ namespace Internal {
|
|||||||
void addCdbOptionPages(QList<IOptionsPage*> *opts);
|
void addCdbOptionPages(QList<IOptionsPage*> *opts);
|
||||||
void addGdbOptionPages(QList<IOptionsPage*> *opts);
|
void addGdbOptionPages(QList<IOptionsPage*> *opts);
|
||||||
|
|
||||||
/// DebuggerRunControlFactory
|
|
||||||
|
|
||||||
class DebuggerRunControlFactory : public IRunControlFactory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IRunConfigurationAspect *createRunConfigurationAspect(RunConfiguration *rc) override
|
|
||||||
{
|
|
||||||
return new DebuggerRunConfigurationAspect(rc);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static QIcon visibleStartIcon(Id id, bool toolBarStyle)
|
static QIcon visibleStartIcon(Id id, bool toolBarStyle)
|
||||||
{
|
{
|
||||||
if (id == Id(Constants::DEBUG)) {
|
if (id == Id(Constants::DEBUG)) {
|
||||||
@@ -1495,7 +1483,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
|
|||||||
m_localsAndExpressionsWindow->setObjectName(QLatin1String(DOCKWIDGET_WATCHERS));
|
m_localsAndExpressionsWindow->setObjectName(QLatin1String(DOCKWIDGET_WATCHERS));
|
||||||
m_localsAndExpressionsWindow->setWindowTitle(m_localsWindow->windowTitle());
|
m_localsAndExpressionsWindow->setWindowTitle(m_localsWindow->windowTitle());
|
||||||
|
|
||||||
m_plugin->addAutoReleasedObject(new DebuggerRunControlFactory);
|
RunConfiguration::registerAspect<DebuggerRunConfigurationAspect>();
|
||||||
|
|
||||||
// The main "Start Debugging" action.
|
// The main "Start Debugging" action.
|
||||||
act = m_startAction = new QAction(this);
|
act = m_startAction = new QAction(this);
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <debugger/debuggerstartparameters.h>
|
#include <debugger/debuggerstartparameters.h>
|
||||||
|
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/qtcfallthrough.h>
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -102,7 +103,7 @@ void GdbAttachEngine::handleAttach(const DebuggerResponse &response)
|
|||||||
notifyEngineIll();
|
notifyEngineIll();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// if msg != "ptrace: ..." fall through
|
Q_FALLTHROUGH(); // if msg != "ptrace: ..."
|
||||||
default:
|
default:
|
||||||
showStatusMessage(tr("Failed to attach to application: %1")
|
showStatusMessage(tr("Failed to attach to application: %1")
|
||||||
.arg(QString(response.data["msg"].data())));
|
.arg(QString(response.data["msg"].data())));
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
#include <coreplugin/messagebox.h>
|
#include <coreplugin/messagebox.h>
|
||||||
|
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
|
#include <utils/qtcfallthrough.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/qtcprocess.h>
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
@@ -367,7 +368,7 @@ void GdbRemoteServerEngine::handleAttach(const DebuggerResponse &response)
|
|||||||
notifyInferiorSetupFailed(msgPtraceError(runParameters().startMode));
|
notifyInferiorSetupFailed(msgPtraceError(runParameters().startMode));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// if msg != "ptrace: ..." fall through
|
Q_FALLTHROUGH(); // if msg != "ptrace: ..."
|
||||||
default:
|
default:
|
||||||
notifyInferiorSetupFailed(response.data["msg"].data());
|
notifyInferiorSetupFailed(response.data["msg"].data());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -327,7 +327,8 @@ void ModulesHandler::endUpdateAll()
|
|||||||
if (!item->updated)
|
if (!item->updated)
|
||||||
toDestroy.append(item);
|
toDestroy.append(item);
|
||||||
});
|
});
|
||||||
qDeleteAll(toDestroy);
|
for (TreeItem *item : toDestroy)
|
||||||
|
m_model->destroyItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
#include <utils/treemodel.h>
|
#include <utils/treemodel.h>
|
||||||
#include <utils/basetreeview.h>
|
#include <utils/basetreeview.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/qtcfallthrough.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
@@ -376,7 +377,7 @@ void QmlEngine::handleLauncherStarted()
|
|||||||
{
|
{
|
||||||
// FIXME: The QmlEngine never calls notifyInferiorPid() triggering the
|
// FIXME: The QmlEngine never calls notifyInferiorPid() triggering the
|
||||||
// raising, so do it here manually for now.
|
// raising, so do it here manually for now.
|
||||||
runControl()->bringApplicationToForeground();
|
runControl()->applicationProcessHandle().activate();
|
||||||
d->noDebugOutputTimer.start();
|
d->noDebugOutputTimer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,7 +506,7 @@ void QmlEngine::errorMessageBoxFinished(int result)
|
|||||||
}
|
}
|
||||||
case QMessageBox::Help: {
|
case QMessageBox::Help: {
|
||||||
HelpManager::handleHelpRequest("qthelp://org.qt-project.qtcreator/doc/creator-debugging-qml.html");
|
HelpManager::handleHelpRequest("qthelp://org.qt-project.qtcreator/doc/creator-debugging-qml.html");
|
||||||
// fall through
|
Q_FALLTHROUGH();
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if (state() == InferiorRunOk) {
|
if (state() == InferiorRunOk) {
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
#include "watchutils.h"
|
#include "watchutils.h"
|
||||||
#include "watchdata.h"
|
#include "watchdata.h"
|
||||||
|
|
||||||
|
#include <utils/qtcfallthrough.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -231,8 +233,10 @@ QString formatToolTipAddress(quint64 a)
|
|||||||
switch (rc.size()) {
|
switch (rc.size()) {
|
||||||
case 16:
|
case 16:
|
||||||
rc.insert(12, colon);
|
rc.insert(12, colon);
|
||||||
|
Q_FALLTHROUGH();
|
||||||
case 12:
|
case 12:
|
||||||
rc.insert(8, colon);
|
rc.insert(8, colon);
|
||||||
|
Q_FALLTHROUGH();
|
||||||
case 8:
|
case 8:
|
||||||
rc.insert(4, colon);
|
rc.insert(4, colon);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,10 +156,12 @@ void DiffFilesController::reload()
|
|||||||
|
|
||||||
void DiffFilesController::reloaded()
|
void DiffFilesController::reloaded()
|
||||||
{
|
{
|
||||||
const QList<FileData> fileDataList = m_futureWatcher.future().results();
|
const bool success = !m_futureWatcher.future().isCanceled();
|
||||||
|
const QList<FileData> fileDataList = success
|
||||||
|
? m_futureWatcher.future().results() : QList<FileData>();
|
||||||
|
|
||||||
setDiffFiles(fileDataList);
|
setDiffFiles(fileDataList);
|
||||||
reloadFinished(true);
|
reloadFinished(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DiffFilesController::cancelReload()
|
void DiffFilesController::cancelReload()
|
||||||
|
|||||||
@@ -36,17 +36,22 @@
|
|||||||
#include "iosdsymbuildstep.h"
|
#include "iosdsymbuildstep.h"
|
||||||
#include "iosqtversionfactory.h"
|
#include "iosqtversionfactory.h"
|
||||||
#include "iosrunfactories.h"
|
#include "iosrunfactories.h"
|
||||||
|
#include "iosrunner.h"
|
||||||
#include "iossettingspage.h"
|
#include "iossettingspage.h"
|
||||||
#include "iossimulator.h"
|
#include "iossimulator.h"
|
||||||
#include "iossimulatorfactory.h"
|
#include "iossimulatorfactory.h"
|
||||||
#include "iostoolhandler.h"
|
#include "iostoolhandler.h"
|
||||||
|
#include "iosrunconfiguration.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/devicesupport/devicemanager.h>
|
||||||
#include <projectexplorer/kitmanager.h>
|
#include <projectexplorer/kitmanager.h>
|
||||||
|
#include <projectexplorer/runconfiguration.h>
|
||||||
|
|
||||||
#include <qtsupport/qtversionmanager.h>
|
#include <qtsupport/qtversionmanager.h>
|
||||||
|
|
||||||
#include <QtPlugin>
|
#include <QtPlugin>
|
||||||
|
|
||||||
#include <projectexplorer/devicesupport/devicemanager.h>
|
using namespace ProjectExplorer;
|
||||||
|
|
||||||
namespace Ios {
|
namespace Ios {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -67,7 +72,6 @@ bool IosPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
|||||||
|
|
||||||
addAutoReleasedObject(new Internal::IosBuildConfigurationFactory);
|
addAutoReleasedObject(new Internal::IosBuildConfigurationFactory);
|
||||||
addAutoReleasedObject(new Internal::IosToolChainFactory);
|
addAutoReleasedObject(new Internal::IosToolChainFactory);
|
||||||
addAutoReleasedObject(new Internal::IosRunControlFactory);
|
|
||||||
addAutoReleasedObject(new Internal::IosRunConfigurationFactory);
|
addAutoReleasedObject(new Internal::IosRunConfigurationFactory);
|
||||||
addAutoReleasedObject(new Internal::IosSettingsPage);
|
addAutoReleasedObject(new Internal::IosSettingsPage);
|
||||||
addAutoReleasedObject(new Internal::IosQtVersionFactory);
|
addAutoReleasedObject(new Internal::IosQtVersionFactory);
|
||||||
@@ -78,6 +82,17 @@ bool IosPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
|||||||
addAutoReleasedObject(new Internal::IosDsymBuildStepFactory);
|
addAutoReleasedObject(new Internal::IosDsymBuildStepFactory);
|
||||||
addAutoReleasedObject(new Internal::IosDeployConfigurationFactory);
|
addAutoReleasedObject(new Internal::IosDeployConfigurationFactory);
|
||||||
|
|
||||||
|
auto constraint = [](RunConfiguration *runConfig) {
|
||||||
|
return qobject_cast<Internal::IosRunConfiguration *>(runConfig) != nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
RunControl::registerWorker<Internal::IosRunSupport>
|
||||||
|
(ProjectExplorer::Constants::NORMAL_RUN_MODE, constraint);
|
||||||
|
RunControl::registerWorker<Internal::IosDebugSupport>
|
||||||
|
(ProjectExplorer::Constants::DEBUG_RUN_MODE, constraint);
|
||||||
|
RunControl::registerWorker<Internal::IosQmlProfilerSupport>
|
||||||
|
(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE, constraint);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,6 @@
|
|||||||
|
|
||||||
#include "iosconstants.h"
|
#include "iosconstants.h"
|
||||||
#include "iosrunconfiguration.h"
|
#include "iosrunconfiguration.h"
|
||||||
#include "iosrunner.h"
|
|
||||||
#include "iosmanager.h"
|
#include "iosmanager.h"
|
||||||
|
|
||||||
#include <debugger/analyzer/analyzermanager.h>
|
#include <debugger/analyzer/analyzermanager.h>
|
||||||
@@ -143,53 +142,5 @@ RunConfiguration *IosRunConfigurationFactory::doRestore(Target *parent, const QV
|
|||||||
return new IosRunConfiguration(parent, id, pathFromId(id));
|
return new IosRunConfiguration(parent, id, pathFromId(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
IosRunControlFactory::IosRunControlFactory(QObject *parent)
|
|
||||||
: IRunControlFactory(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IosRunControlFactory::canRun(RunConfiguration *runConfiguration,
|
|
||||||
Core::Id mode) const
|
|
||||||
{
|
|
||||||
if (mode != ProjectExplorer::Constants::NORMAL_RUN_MODE
|
|
||||||
&& mode != ProjectExplorer::Constants::DEBUG_RUN_MODE
|
|
||||||
&& mode != ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return qobject_cast<IosRunConfiguration *>(runConfiguration);
|
|
||||||
}
|
|
||||||
|
|
||||||
RunControl *IosRunControlFactory::create(RunConfiguration *runConfig,
|
|
||||||
Core::Id mode, QString *errorMessage)
|
|
||||||
{
|
|
||||||
Q_UNUSED(errorMessage);
|
|
||||||
Q_ASSERT(canRun(runConfig, mode));
|
|
||||||
IosRunConfiguration *rc = qobject_cast<IosRunConfiguration *>(runConfig);
|
|
||||||
Q_ASSERT(rc);
|
|
||||||
Target *target = runConfig->target();
|
|
||||||
QTC_ASSERT(target, return 0);
|
|
||||||
|
|
||||||
Core::Id devId = DeviceKitInformation::deviceId(rc->target()->kit());
|
|
||||||
// The device can only run an application at a time, if an app is running stop it.
|
|
||||||
if (m_activeRunControls.contains(devId)) {
|
|
||||||
if (QPointer<RunControl> activeRunControl = m_activeRunControls[devId])
|
|
||||||
activeRunControl->initiateStop();
|
|
||||||
m_activeRunControls.remove(devId);
|
|
||||||
}
|
|
||||||
auto runControl = new RunControl(runConfig, mode);
|
|
||||||
if (mode == ProjectExplorer::Constants::NORMAL_RUN_MODE) {
|
|
||||||
(void) new Ios::Internal::IosRunSupport(runControl);
|
|
||||||
} else if (mode == ProjectExplorer::Constants::QML_PROFILER_RUN_MODE) {
|
|
||||||
(void) new IosQmlProfilerSupport(runControl);
|
|
||||||
} else {
|
|
||||||
(void) new IosDebugSupport(runControl);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (devId.isValid())
|
|
||||||
m_activeRunControls[devId] = runControl;
|
|
||||||
return runControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Ios
|
} // namespace Ios
|
||||||
|
|||||||
@@ -29,8 +29,6 @@
|
|||||||
#include <qmakeprojectmanager/qmakerunconfigurationfactory.h>
|
#include <qmakeprojectmanager/qmakerunconfigurationfactory.h>
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
class RunControl;
|
|
||||||
class RunConfigWidget;
|
|
||||||
class Target;
|
class Target;
|
||||||
class Node;
|
class Node;
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
@@ -68,20 +66,5 @@ private:
|
|||||||
const QVariantMap &map) override;
|
const QVariantMap &map) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
class IosRunControlFactory : public ProjectExplorer::IRunControlFactory
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit IosRunControlFactory(QObject *parent = 0);
|
|
||||||
|
|
||||||
bool canRun(ProjectExplorer::RunConfiguration *runConfiguration,
|
|
||||||
Core::Id mode) const override;
|
|
||||||
ProjectExplorer::RunControl *create(ProjectExplorer::RunConfiguration *runConfiguration,
|
|
||||||
Core::Id mode, QString *) override;
|
|
||||||
private:
|
|
||||||
mutable QMap<Core::Id, QPointer<ProjectExplorer::RunControl> > m_activeRunControls;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Ios
|
} // namespace Ios
|
||||||
|
|||||||
@@ -74,9 +74,29 @@ using namespace Utils;
|
|||||||
namespace Ios {
|
namespace Ios {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
|
static void stopRunningRunControl(RunControl *runControl)
|
||||||
|
{
|
||||||
|
static QMap<Core::Id, QPointer<RunControl>> activeRunControls;
|
||||||
|
|
||||||
|
RunConfiguration *runConfig = runControl->runConfiguration();
|
||||||
|
Target *target = runConfig->target();
|
||||||
|
Core::Id devId = DeviceKitInformation::deviceId(target->kit());
|
||||||
|
|
||||||
|
// The device can only run an application at a time, if an app is running stop it.
|
||||||
|
if (activeRunControls.contains(devId)) {
|
||||||
|
if (QPointer<RunControl> activeRunControl = activeRunControls[devId])
|
||||||
|
activeRunControl->initiateStop();
|
||||||
|
activeRunControls.remove(devId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (devId.isValid())
|
||||||
|
activeRunControls[devId] = runControl;
|
||||||
|
}
|
||||||
|
|
||||||
IosRunner::IosRunner(RunControl *runControl)
|
IosRunner::IosRunner(RunControl *runControl)
|
||||||
: RunWorker(runControl)
|
: RunWorker(runControl)
|
||||||
{
|
{
|
||||||
|
stopRunningRunControl(runControl);
|
||||||
auto runConfig = qobject_cast<IosRunConfiguration *>(runControl->runConfiguration());
|
auto runConfig = qobject_cast<IosRunConfiguration *>(runControl->runConfiguration());
|
||||||
m_bundleDir = runConfig->bundleDirectory().toString();
|
m_bundleDir = runConfig->bundleDirectory().toString();
|
||||||
m_arguments = QStringList(runConfig->commandLineArguments());
|
m_arguments = QStringList(runConfig->commandLineArguments());
|
||||||
@@ -513,10 +533,5 @@ void IosDebugSupport::start()
|
|||||||
DebuggerRunTool::start();
|
DebuggerRunTool::start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void IosDebugSupport::onFinished()
|
|
||||||
{
|
|
||||||
abortDebugger();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Ios
|
} // namespace Ios
|
||||||
|
|||||||
@@ -135,7 +135,6 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void start() override;
|
void start() override;
|
||||||
void onFinished() override;
|
|
||||||
|
|
||||||
const QString m_dumperLib;
|
const QString m_dumperLib;
|
||||||
IosRunner *m_runner;
|
IosRunner *m_runner;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
|
#include <utils/qtcfallthrough.h>
|
||||||
#include "utils/runextensions.h"
|
#include "utils/runextensions.h"
|
||||||
#include "utils/synchronousprocess.h"
|
#include "utils/synchronousprocess.h"
|
||||||
|
|
||||||
@@ -606,7 +607,7 @@ void IosDeviceToolHandlerPrivate::subprocessHasData()
|
|||||||
switch (state) {
|
switch (state) {
|
||||||
case NonStarted:
|
case NonStarted:
|
||||||
qCWarning(toolHandlerLog) << "IosToolHandler unexpected state in subprocessHasData: NonStarted";
|
qCWarning(toolHandlerLog) << "IosToolHandler unexpected state in subprocessHasData: NonStarted";
|
||||||
// pass
|
Q_FALLTHROUGH();
|
||||||
case Starting:
|
case Starting:
|
||||||
case StartedInferior:
|
case StartedInferior:
|
||||||
// read some data
|
// read some data
|
||||||
@@ -771,7 +772,7 @@ void IosDeviceToolHandlerPrivate::stop(int errorCode)
|
|||||||
switch (oldState) {
|
switch (oldState) {
|
||||||
case NonStarted:
|
case NonStarted:
|
||||||
qCWarning(toolHandlerLog) << "IosToolHandler::stop() when state was NonStarted";
|
qCWarning(toolHandlerLog) << "IosToolHandler::stop() when state was NonStarted";
|
||||||
// pass
|
Q_FALLTHROUGH();
|
||||||
case Starting:
|
case Starting:
|
||||||
switch (op){
|
switch (op){
|
||||||
case OpNone:
|
case OpNone:
|
||||||
@@ -786,7 +787,7 @@ void IosDeviceToolHandlerPrivate::stop(int errorCode)
|
|||||||
case OpDeviceInfo:
|
case OpDeviceInfo:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// pass
|
Q_FALLTHROUGH();
|
||||||
case StartedInferior:
|
case StartedInferior:
|
||||||
case XmlEndProcessed:
|
case XmlEndProcessed:
|
||||||
toolExited(errorCode);
|
toolExited(errorCode);
|
||||||
|
|||||||
@@ -420,7 +420,8 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
|
|||||||
if (tabIndex != -1) {
|
if (tabIndex != -1) {
|
||||||
RunControlTab &tab = m_runControlTabs[tabIndex];
|
RunControlTab &tab = m_runControlTabs[tabIndex];
|
||||||
// Reuse this tab
|
// Reuse this tab
|
||||||
delete tab.runControl;
|
if (tab.runControl)
|
||||||
|
tab.runControl->initiateFinish();
|
||||||
tab.runControl = rc;
|
tab.runControl = rc;
|
||||||
tab.window->setFormatter(rc ? rc->outputFormatter() : nullptr);
|
tab.window->setFormatter(rc ? rc->outputFormatter() : nullptr);
|
||||||
|
|
||||||
@@ -559,7 +560,7 @@ bool AppOutputPane::closeTabs(CloseTabMode mode)
|
|||||||
QList<RunControl *> AppOutputPane::allRunControls() const
|
QList<RunControl *> AppOutputPane::allRunControls() const
|
||||||
{
|
{
|
||||||
return Utils::transform<QList>(m_runControlTabs,[](const RunControlTab &tab) {
|
return Utils::transform<QList>(m_runControlTabs,[](const RunControlTab &tab) {
|
||||||
return tab.runControl;
|
return tab.runControl.data();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,7 +597,8 @@ bool AppOutputPane::closeTab(int tabIndex, CloseTabMode closeTabMode)
|
|||||||
|
|
||||||
m_tabWidget->removeTab(tabIndex);
|
m_tabWidget->removeTab(tabIndex);
|
||||||
delete m_runControlTabs[index].window;
|
delete m_runControlTabs[index].window;
|
||||||
delete m_runControlTabs[index].runControl;
|
m_runControlTabs[index].runControl->initiateFinish(); // Will self-destruct.
|
||||||
|
m_runControlTabs[index].runControl = 0;
|
||||||
m_runControlTabs.removeAt(index);
|
m_runControlTabs.removeAt(index);
|
||||||
updateCloseActions();
|
updateCloseActions();
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <QPointer>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
|
|
||||||
#include <coreplugin/ioutputpane.h>
|
#include <coreplugin/ioutputpane.h>
|
||||||
@@ -124,7 +125,7 @@ private:
|
|||||||
public:
|
public:
|
||||||
explicit RunControlTab(RunControl *runControl = nullptr,
|
explicit RunControlTab(RunControl *runControl = nullptr,
|
||||||
Core::OutputWindow *window = nullptr);
|
Core::OutputWindow *window = nullptr);
|
||||||
RunControl *runControl;
|
QPointer<RunControl> runControl;
|
||||||
Core::OutputWindow *window;
|
Core::OutputWindow *window;
|
||||||
BehaviorOnOutput behaviorOnOutput = Flash;
|
BehaviorOnOutput behaviorOnOutput = Flash;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1995,17 +1995,6 @@ static RunControlFactory findRunControlFactory(RunConfiguration *config, Core::I
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
IRunControlFactory *runControlFactory = ExtensionSystem::PluginManager::getObject<IRunControlFactory>(
|
|
||||||
[&config, &mode](IRunControlFactory *factory) {
|
|
||||||
return factory->canRun(config, mode);
|
|
||||||
});
|
|
||||||
|
|
||||||
if (runControlFactory) {
|
|
||||||
return [runControlFactory](RunConfiguration *rc, Id runMode, QString *errorMessage) {
|
|
||||||
return runControlFactory->create(rc, runMode, errorMessage);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,6 @@ namespace Utils { class ProcessHandle; }
|
|||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
class RunControl;
|
class RunControl;
|
||||||
class RunConfiguration;
|
class RunConfiguration;
|
||||||
class IRunControlFactory;
|
|
||||||
class Project;
|
class Project;
|
||||||
class Node;
|
class Node;
|
||||||
class FolderNode;
|
class FolderNode;
|
||||||
|
|||||||
@@ -489,5 +489,5 @@ void ProjectTreeWidgetFactory::restoreSettings(QSettings *settings, int position
|
|||||||
const QString baseKey = QLatin1String("ProjectTreeWidget.") + QString::number(position);
|
const QString baseKey = QLatin1String("ProjectTreeWidget.") + QString::number(position);
|
||||||
ptw->setProjectFilter(settings->value(baseKey + QLatin1String(".ProjectFilter"), false).toBool());
|
ptw->setProjectFilter(settings->value(baseKey + QLatin1String(".ProjectFilter"), false).toBool());
|
||||||
ptw->setGeneratedFilesFilter(settings->value(baseKey + QLatin1String(".GeneratedFilter"), true).toBool());
|
ptw->setGeneratedFilesFilter(settings->value(baseKey + QLatin1String(".GeneratedFilter"), true).toBool());
|
||||||
ptw->setAutoSynchronization(settings->value(baseKey + QLatin1String(".SyncWithEditor")).toBool());
|
ptw->setAutoSynchronization(settings->value(baseKey + QLatin1String(".SyncWithEditor"), true).toBool());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ private:
|
|||||||
QToolButton *m_toggleSync;
|
QToolButton *m_toggleSync;
|
||||||
|
|
||||||
QString m_modelId;
|
QString m_modelId;
|
||||||
bool m_autoSync = false;
|
bool m_autoSync = true;
|
||||||
Utils::FileName m_delayedRename;
|
Utils::FileName m_delayedRename;
|
||||||
|
|
||||||
static QList<ProjectTreeWidget *> m_projectTreeWidgets;
|
static QList<ProjectTreeWidget *> m_projectTreeWidgets;
|
||||||
|
|||||||
@@ -183,13 +183,16 @@ void IRunConfigurationAspect::resetProjectToGlobalSettings()
|
|||||||
for a target, but still be runnable via the output tab.
|
for a target, but still be runnable via the output tab.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
static std::vector<RunConfiguration::AspectFactory> theAspectFactories;
|
||||||
|
|
||||||
RunConfiguration::RunConfiguration(Target *target, Core::Id id) :
|
RunConfiguration::RunConfiguration(Target *target, Core::Id id) :
|
||||||
ProjectConfiguration(target, id)
|
ProjectConfiguration(target, id)
|
||||||
{
|
{
|
||||||
Q_ASSERT(target);
|
Q_ASSERT(target);
|
||||||
ctor();
|
ctor();
|
||||||
|
|
||||||
addExtraAspects();
|
for (const AspectFactory &factory : theAspectFactories)
|
||||||
|
addExtraAspect(factory(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
RunConfiguration::RunConfiguration(Target *target, RunConfiguration *source) :
|
RunConfiguration::RunConfiguration(Target *target, RunConfiguration *source) :
|
||||||
@@ -209,10 +212,9 @@ RunConfiguration::~RunConfiguration()
|
|||||||
qDeleteAll(m_aspects);
|
qDeleteAll(m_aspects);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunConfiguration::addExtraAspects()
|
void RunConfiguration::addAspectFactory(const AspectFactory &aspectFactory)
|
||||||
{
|
{
|
||||||
foreach (IRunControlFactory *factory, ExtensionSystem::PluginManager::getObjects<IRunControlFactory>())
|
theAspectFactories.push_back(aspectFactory);
|
||||||
addExtraAspect(factory->createRunConfigurationAspect(this));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunConfiguration::addExtraAspect(IRunConfigurationAspect *aspect)
|
void RunConfiguration::addExtraAspect(IRunConfigurationAspect *aspect)
|
||||||
@@ -365,7 +367,7 @@ IRunConfigurationAspect *RunConfiguration::extraAspect(Core::Id id) const
|
|||||||
|
|
||||||
A target specific \l RunConfiguration implementation can specify
|
A target specific \l RunConfiguration implementation can specify
|
||||||
what information it considers necessary to execute a process
|
what information it considers necessary to execute a process
|
||||||
on the target. Target specific) \n IRunControlFactory implementation
|
on the target. Target specific) \n RunWorker implementation
|
||||||
can use that information either unmodified or tweak it or ignore
|
can use that information either unmodified or tweak it or ignore
|
||||||
it when setting up a RunControl.
|
it when setting up a RunControl.
|
||||||
|
|
||||||
@@ -471,29 +473,6 @@ QList<IRunConfigurationFactory *> IRunConfigurationFactory::find(Target *parent)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
\class ProjectExplorer::IRunControlFactory
|
|
||||||
|
|
||||||
\brief The IRunControlFactory class creates RunControl objects matching a
|
|
||||||
run configuration.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*!
|
|
||||||
\fn RunConfigWidget *ProjectExplorer::IRunConfigurationAspect::createConfigurationWidget()
|
|
||||||
|
|
||||||
Returns a widget used to configure this runner. Ownership is transferred to
|
|
||||||
the caller.
|
|
||||||
|
|
||||||
Returns null if @p \a runConfiguration is not suitable for RunControls from this
|
|
||||||
factory, or no user-accessible
|
|
||||||
configuration is required.
|
|
||||||
*/
|
|
||||||
|
|
||||||
IRunControlFactory::IRunControlFactory(QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
using WorkerFactories = std::vector<RunControl::WorkerFactory>;
|
using WorkerFactories = std::vector<RunControl::WorkerFactory>;
|
||||||
|
|
||||||
static WorkerFactories &theWorkerFactories()
|
static WorkerFactories &theWorkerFactories()
|
||||||
@@ -504,50 +483,13 @@ static WorkerFactories &theWorkerFactories()
|
|||||||
|
|
||||||
bool RunControl::WorkerFactory::canRun(RunConfiguration *runConfiguration, Core::Id runMode) const
|
bool RunControl::WorkerFactory::canRun(RunConfiguration *runConfiguration, Core::Id runMode) const
|
||||||
{
|
{
|
||||||
if (runMode != runMode)
|
if (runMode != this->runMode)
|
||||||
return false;
|
return false;
|
||||||
if (!constraint)
|
if (!constraint)
|
||||||
return true;
|
return true;
|
||||||
return constraint(runConfiguration);
|
return constraint(runConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IRunControlFactory::canRun(RunConfiguration *runConfiguration, Core::Id runMode) const
|
|
||||||
{
|
|
||||||
for (const RunControl::WorkerFactory &factory : theWorkerFactories()) {
|
|
||||||
if (factory.canRun(runConfiguration, runMode))
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RunControl *IRunControlFactory::create(RunConfiguration *runConfiguration, Core::Id runMode, QString *)
|
|
||||||
{
|
|
||||||
for (const RunControl::WorkerFactory &factory : theWorkerFactories()) {
|
|
||||||
if (factory.canRun(runConfiguration, runMode)) {
|
|
||||||
auto runControl = new RunControl(runConfiguration, runMode);
|
|
||||||
factory.producer(runControl);
|
|
||||||
return runControl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
Returns an IRunConfigurationAspect to carry options for RunControls this
|
|
||||||
factory can create.
|
|
||||||
|
|
||||||
If no extra options are required, it is allowed to return null like the
|
|
||||||
default implementation does. This function is intended to be called from the
|
|
||||||
RunConfiguration constructor, so passing a RunConfiguration pointer makes
|
|
||||||
no sense because that object is under construction at the time.
|
|
||||||
*/
|
|
||||||
|
|
||||||
IRunConfigurationAspect *IRunControlFactory::createRunConfigurationAspect(RunConfiguration *rc)
|
|
||||||
{
|
|
||||||
Q_UNUSED(rc);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class ProjectExplorer::RunControl
|
\class ProjectExplorer::RunControl
|
||||||
\brief The RunControl class instances represent one item that is run.
|
\brief The RunControl class instances represent one item that is run.
|
||||||
@@ -562,18 +504,6 @@ IRunConfigurationAspect *IRunControlFactory::createRunConfigurationAspect(RunCon
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
const char PRIORITY_KEY[] = "RunControlFactoryPriority";
|
|
||||||
|
|
||||||
int ProjectExplorer::IRunControlFactory::priority() const
|
|
||||||
{
|
|
||||||
return property(PRIORITY_KEY).toInt(); // 0 by default.
|
|
||||||
}
|
|
||||||
|
|
||||||
void IRunControlFactory::setPriority(int priority)
|
|
||||||
{
|
|
||||||
setProperty(PRIORITY_KEY, priority);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
enum class RunWorkerState
|
enum class RunWorkerState
|
||||||
@@ -592,7 +522,7 @@ static QString stateName(RunWorkerState s)
|
|||||||
SN(RunWorkerState::Done)
|
SN(RunWorkerState::Done)
|
||||||
SN(RunWorkerState::Failed)
|
SN(RunWorkerState::Failed)
|
||||||
}
|
}
|
||||||
return QLatin1String("<unknown>");
|
return QString("<unknown: %1>").arg(int(s));
|
||||||
# undef SN
|
# undef SN
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -606,7 +536,7 @@ public:
|
|||||||
|
|
||||||
RunWorker *q;
|
RunWorker *q;
|
||||||
RunWorkerState state = RunWorkerState::Initialized;
|
RunWorkerState state = RunWorkerState::Initialized;
|
||||||
RunControl *runControl;
|
QPointer<RunControl> runControl;
|
||||||
QList<RunWorker *> dependencies;
|
QList<RunWorker *> dependencies;
|
||||||
QString id;
|
QString id;
|
||||||
|
|
||||||
@@ -625,6 +555,8 @@ enum class RunControlState
|
|||||||
Running, // All good and running.
|
Running, // All good and running.
|
||||||
Stopping, // initiateStop() was called, stop application/tool
|
Stopping, // initiateStop() was called, stop application/tool
|
||||||
Stopped, // all good, but stopped. Can possibly be re-started
|
Stopped, // all good, but stopped. Can possibly be re-started
|
||||||
|
Finishing, // Application tab manually closed
|
||||||
|
Finished // Final state, will self-destruct with deleteLater()
|
||||||
};
|
};
|
||||||
|
|
||||||
static QString stateName(RunControlState s)
|
static QString stateName(RunControlState s)
|
||||||
@@ -636,8 +568,10 @@ static QString stateName(RunControlState s)
|
|||||||
SN(RunControlState::Running)
|
SN(RunControlState::Running)
|
||||||
SN(RunControlState::Stopping)
|
SN(RunControlState::Stopping)
|
||||||
SN(RunControlState::Stopped)
|
SN(RunControlState::Stopped)
|
||||||
|
SN(RunControlState::Finishing)
|
||||||
|
SN(RunControlState::Finished)
|
||||||
}
|
}
|
||||||
return QLatin1String("<unknown>");
|
return QString("<unknown: %1>").arg(int(s));
|
||||||
# undef SN
|
# undef SN
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -659,8 +593,11 @@ public:
|
|||||||
|
|
||||||
~RunControlPrivate()
|
~RunControlPrivate()
|
||||||
{
|
{
|
||||||
QTC_CHECK(state == RunControlState::Stopped || state == RunControlState::Initialized);
|
QTC_CHECK(state == RunControlState::Finished || state == RunControlState::Initialized);
|
||||||
|
disconnect();
|
||||||
|
q = nullptr;
|
||||||
qDeleteAll(m_workers);
|
qDeleteAll(m_workers);
|
||||||
|
m_workers.clear();
|
||||||
delete outputFormatter;
|
delete outputFormatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,7 +612,7 @@ public:
|
|||||||
void initiateReStart();
|
void initiateReStart();
|
||||||
void continueStart();
|
void continueStart();
|
||||||
void initiateStop();
|
void initiateStop();
|
||||||
void continueStop();
|
void initiateFinish();
|
||||||
|
|
||||||
void onWorkerStarted(RunWorker *worker);
|
void onWorkerStarted(RunWorker *worker);
|
||||||
void onWorkerStopped(RunWorker *worker);
|
void onWorkerStopped(RunWorker *worker);
|
||||||
@@ -694,7 +631,7 @@ public:
|
|||||||
Utils::Icon icon;
|
Utils::Icon icon;
|
||||||
const QPointer<RunConfiguration> runConfiguration; // Not owned.
|
const QPointer<RunConfiguration> runConfiguration; // Not owned.
|
||||||
QPointer<Project> project; // Not owned.
|
QPointer<Project> project; // Not owned.
|
||||||
Utils::OutputFormatter *outputFormatter = nullptr;
|
QPointer<Utils::OutputFormatter> outputFormatter = nullptr;
|
||||||
std::function<bool(bool*)> promptToStop;
|
std::function<bool(bool*)> promptToStop;
|
||||||
std::vector<RunControl::WorkerFactory> m_factories;
|
std::vector<RunControl::WorkerFactory> m_factories;
|
||||||
|
|
||||||
@@ -759,6 +696,11 @@ void RunControl::initiateStop()
|
|||||||
d->initiateStop();
|
d->initiateStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RunControl::initiateFinish()
|
||||||
|
{
|
||||||
|
d->initiateFinish();
|
||||||
|
}
|
||||||
|
|
||||||
using WorkerCreators = QHash<Core::Id, RunControl::WorkerCreator>;
|
using WorkerCreators = QHash<Core::Id, RunControl::WorkerCreator>;
|
||||||
|
|
||||||
static WorkerCreators &theWorkerCreators()
|
static WorkerCreators &theWorkerCreators()
|
||||||
@@ -789,12 +731,22 @@ RunWorker *RunControl::createWorker(Core::Id id)
|
|||||||
|
|
||||||
RunControl::WorkerCreator RunControl::producer(RunConfiguration *runConfiguration, Core::Id runMode)
|
RunControl::WorkerCreator RunControl::producer(RunConfiguration *runConfiguration, Core::Id runMode)
|
||||||
{
|
{
|
||||||
for (const auto &factory : theWorkerFactories()) {
|
WorkerFactories candidates;
|
||||||
if (factory.runMode == runMode
|
for (const RunControl::WorkerFactory &factory : theWorkerFactories()) {
|
||||||
&& (!factory.constraint || factory.constraint(runConfiguration)))
|
if (factory.canRun(runConfiguration, runMode))
|
||||||
return factory.producer;
|
candidates.push_back(factory);
|
||||||
}
|
}
|
||||||
return {};
|
|
||||||
|
if (candidates.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
RunControl::WorkerFactory bestFactory = *candidates.begin();
|
||||||
|
for (const RunControl::WorkerFactory &factory : candidates) {
|
||||||
|
if (factory.priority > bestFactory.priority)
|
||||||
|
bestFactory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bestFactory.producer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunControl::addWorkerFactory(const RunControl::WorkerFactory &workerFactory)
|
void RunControl::addWorkerFactory(const RunControl::WorkerFactory &workerFactory)
|
||||||
@@ -880,15 +832,8 @@ void RunControlPrivate::initiateStop()
|
|||||||
{
|
{
|
||||||
checkState(RunControlState::Running);
|
checkState(RunControlState::Running);
|
||||||
setState(RunControlState::Stopping);
|
setState(RunControlState::Stopping);
|
||||||
debugMessage("Queue: Stopping");
|
debugMessage("Queue: Stopping for all workers");
|
||||||
|
|
||||||
continueStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunControlPrivate::continueStop()
|
|
||||||
{
|
|
||||||
debugMessage("Continue Stopping");
|
|
||||||
checkState(RunControlState::Stopping);
|
|
||||||
bool allDone = true;
|
bool allDone = true;
|
||||||
for (RunWorker *worker : m_workers) {
|
for (RunWorker *worker : m_workers) {
|
||||||
if (worker) {
|
if (worker) {
|
||||||
@@ -904,17 +849,17 @@ void RunControlPrivate::continueStop()
|
|||||||
allDone = false;
|
allDone = false;
|
||||||
break;
|
break;
|
||||||
case RunWorkerState::Starting:
|
case RunWorkerState::Starting:
|
||||||
worker->d->state = RunWorkerState::Stopping;
|
|
||||||
debugMessage(" " + workerId + " was Starting, queuing stop");
|
debugMessage(" " + workerId + " was Starting, queuing stop");
|
||||||
allDone = false;
|
worker->d->state = RunWorkerState::Stopping;
|
||||||
QTimer::singleShot(0, worker, &RunWorker::initiateStop);
|
QTimer::singleShot(0, worker, &RunWorker::initiateStop);
|
||||||
return; // Sic.
|
allDone = false;
|
||||||
|
break;
|
||||||
case RunWorkerState::Running:
|
case RunWorkerState::Running:
|
||||||
debugMessage(" " + workerId + " was Running, queuing stop");
|
debugMessage(" " + workerId + " was Running, queuing stop");
|
||||||
worker->d->state = RunWorkerState::Stopping;
|
worker->d->state = RunWorkerState::Stopping;
|
||||||
allDone = false;
|
allDone = false;
|
||||||
QTimer::singleShot(0, worker, &RunWorker::initiateStop);
|
QTimer::singleShot(0, worker, &RunWorker::initiateStop);
|
||||||
return; // Sic.
|
break;
|
||||||
case RunWorkerState::Done:
|
case RunWorkerState::Done:
|
||||||
debugMessage(" " + workerId + " was Done. Good.");
|
debugMessage(" " + workerId + " was Done. Good.");
|
||||||
break;
|
break;
|
||||||
@@ -927,8 +872,59 @@ void RunControlPrivate::continueStop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (allDone) {
|
if (allDone) {
|
||||||
debugMessage("All workers stopped. Set runControl to Stopped");
|
debugMessage("All stopped.");
|
||||||
setState(RunControlState::Stopped);
|
setState(RunControlState::Stopped);
|
||||||
|
} else {
|
||||||
|
debugMessage("Not all workers stopped. Waiting...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RunControlPrivate::initiateFinish()
|
||||||
|
{
|
||||||
|
setState(RunControlState::Finishing);
|
||||||
|
debugMessage("Ramping down");
|
||||||
|
|
||||||
|
bool allDone = true;
|
||||||
|
for (RunWorker *worker : m_workers) {
|
||||||
|
if (worker) {
|
||||||
|
const QString &workerId = worker->d->id;
|
||||||
|
debugMessage(" Examining worker " + workerId);
|
||||||
|
switch (worker->d->state) {
|
||||||
|
case RunWorkerState::Initialized:
|
||||||
|
debugMessage(" " + workerId + " was Initialized, setting to Done");
|
||||||
|
worker->d->state = RunWorkerState::Done;
|
||||||
|
break;
|
||||||
|
case RunWorkerState::Stopping:
|
||||||
|
debugMessage(" " + workerId + " was already Stopping. Keeping it that way");
|
||||||
|
allDone = false;
|
||||||
|
break;
|
||||||
|
case RunWorkerState::Starting:
|
||||||
|
debugMessage(" " + workerId + " was Starting, queuing stop");
|
||||||
|
worker->d->state = RunWorkerState::Stopping;
|
||||||
|
QTimer::singleShot(0, worker, &RunWorker::initiateStop);
|
||||||
|
allDone = false;
|
||||||
|
break;
|
||||||
|
case RunWorkerState::Running:
|
||||||
|
debugMessage(" " + workerId + " was Running, queuing stop");
|
||||||
|
worker->d->state = RunWorkerState::Stopping;
|
||||||
|
allDone = false;
|
||||||
|
QTimer::singleShot(0, worker, &RunWorker::initiateStop);
|
||||||
|
break;
|
||||||
|
case RunWorkerState::Done:
|
||||||
|
debugMessage(" " + workerId + " was Done. Good.");
|
||||||
|
break;
|
||||||
|
case RunWorkerState::Failed:
|
||||||
|
debugMessage(" " + workerId + " was Failed. Good");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
debugMessage("Found unknown deleted worker");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (allDone) {
|
||||||
|
setState(RunControlState::Finished);
|
||||||
|
} else {
|
||||||
|
debugMessage("Not all workers finished. Waiting...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -944,7 +940,6 @@ void RunControlPrivate::onWorkerStarted(RunWorker *worker)
|
|||||||
showError(tr("Unexpected run control state %1 when worker %2 started")
|
showError(tr("Unexpected run control state %1 when worker %2 started")
|
||||||
.arg(stateName(state))
|
.arg(stateName(state))
|
||||||
.arg(worker->d->id));
|
.arg(worker->d->id));
|
||||||
//setState(RunControlState::Stopped);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunControlPrivate::onWorkerFailed(RunWorker *worker, const QString &msg)
|
void RunControlPrivate::onWorkerFailed(RunWorker *worker, const QString &msg)
|
||||||
@@ -968,13 +963,72 @@ void RunControlPrivate::onWorkerStopped(RunWorker *worker)
|
|||||||
worker->d->state = RunWorkerState::Done;
|
worker->d->state = RunWorkerState::Done;
|
||||||
debugMessage(workerId + " stopped expectedly.");
|
debugMessage(workerId + " stopped expectedly.");
|
||||||
break;
|
break;
|
||||||
|
case RunWorkerState::Done:
|
||||||
|
worker->d->state = RunWorkerState::Done;
|
||||||
|
debugMessage(workerId + " stopped twice. Huh? But harmless.");
|
||||||
|
return; // Sic!
|
||||||
default:
|
default:
|
||||||
debugMessage(workerId + " stopped unexpectedly in state"
|
debugMessage(workerId + " stopped unexpectedly in state"
|
||||||
+ stateName(worker->d->state));
|
+ stateName(worker->d->state));
|
||||||
worker->d->state = RunWorkerState::Failed;
|
worker->d->state = RunWorkerState::Failed;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
continueStop();
|
|
||||||
|
debugMessage("Checking whether all stopped");
|
||||||
|
bool allDone = true;
|
||||||
|
for (RunWorker *worker : m_workers) {
|
||||||
|
if (worker) {
|
||||||
|
const QString &workerId = worker->d->id;
|
||||||
|
debugMessage(" Examining worker " + workerId);
|
||||||
|
switch (worker->d->state) {
|
||||||
|
case RunWorkerState::Initialized:
|
||||||
|
debugMessage(" " + workerId + " was Initialized, setting to Done");
|
||||||
|
worker->d->state = RunWorkerState::Done;
|
||||||
|
break;
|
||||||
|
case RunWorkerState::Starting:
|
||||||
|
worker->d->state = RunWorkerState::Stopping;
|
||||||
|
debugMessage(" " + workerId + " was Starting, queuing stop");
|
||||||
|
allDone = false;
|
||||||
|
break;
|
||||||
|
case RunWorkerState::Running:
|
||||||
|
debugMessage(" " + workerId + " was Running, queuing stop");
|
||||||
|
worker->d->state = RunWorkerState::Stopping;
|
||||||
|
allDone = false;
|
||||||
|
break;
|
||||||
|
case RunWorkerState::Stopping:
|
||||||
|
debugMessage(" " + workerId + " was already Stopping. Keeping it that way");
|
||||||
|
allDone = false;
|
||||||
|
break;
|
||||||
|
case RunWorkerState::Done:
|
||||||
|
debugMessage(" " + workerId + " was Done. Good.");
|
||||||
|
break;
|
||||||
|
case RunWorkerState::Failed:
|
||||||
|
debugMessage(" " + workerId + " was Failed. Good");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
debugMessage("Found unknown deleted worker");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state == RunControlState::Finishing) {
|
||||||
|
if (allDone) {
|
||||||
|
debugMessage("All finished. Deleting myself");
|
||||||
|
setState(RunControlState::Finished);
|
||||||
|
} else {
|
||||||
|
debugMessage("Not all workers finished. Waiting...");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (allDone) {
|
||||||
|
if (state == RunControlState::Stopped) {
|
||||||
|
debugMessage("All workers stopped, but runControl was already stopped.");
|
||||||
|
} else {
|
||||||
|
debugMessage("All workers stopped. Set runControl to Stopped");
|
||||||
|
setState(RunControlState::Stopped);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
debugMessage("Not all workers stopped. Waiting...");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunControlPrivate::showError(const QString &msg)
|
void RunControlPrivate::showError(const QString &msg)
|
||||||
@@ -1175,15 +1229,23 @@ bool RunControlPrivate::isAllowedTransition(RunControlState from, RunControlStat
|
|||||||
{
|
{
|
||||||
switch (from) {
|
switch (from) {
|
||||||
case RunControlState::Initialized:
|
case RunControlState::Initialized:
|
||||||
return to == RunControlState::Starting;
|
return to == RunControlState::Starting
|
||||||
|
|| to == RunControlState::Finishing;
|
||||||
case RunControlState::Starting:
|
case RunControlState::Starting:
|
||||||
return to == RunControlState::Running;
|
return to == RunControlState::Running
|
||||||
|
|| to == RunControlState::Finishing;
|
||||||
case RunControlState::Running:
|
case RunControlState::Running:
|
||||||
return to == RunControlState::Stopping
|
return to == RunControlState::Stopping
|
||||||
|| to == RunControlState::Stopped;
|
|| to == RunControlState::Stopped
|
||||||
|
|| to == RunControlState::Finishing;
|
||||||
case RunControlState::Stopping:
|
case RunControlState::Stopping:
|
||||||
return to == RunControlState::Stopped;
|
return to == RunControlState::Stopped
|
||||||
|
|| to == RunControlState::Finishing;
|
||||||
case RunControlState::Stopped:
|
case RunControlState::Stopped:
|
||||||
|
return to == RunControlState::Finishing;
|
||||||
|
case RunControlState::Finishing:
|
||||||
|
return to == RunControlState::Finished;
|
||||||
|
case RunControlState::Finished:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -1213,11 +1275,13 @@ void RunControlPrivate::setState(RunControlState newState)
|
|||||||
break;
|
break;
|
||||||
case RunControlState::Stopped:
|
case RunControlState::Stopped:
|
||||||
q->setApplicationProcessHandle(Utils::ProcessHandle());
|
q->setApplicationProcessHandle(Utils::ProcessHandle());
|
||||||
foreach (auto worker, m_workers)
|
|
||||||
if (worker)
|
|
||||||
worker->onFinished();
|
|
||||||
emit q->stopped();
|
emit q->stopped();
|
||||||
break;
|
break;
|
||||||
|
case RunControlState::Finished:
|
||||||
|
emit q->finished();
|
||||||
|
debugMessage("All finished. Deleting myself");
|
||||||
|
deleteLater();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1228,18 +1292,6 @@ void RunControlPrivate::debugMessage(const QString &msg)
|
|||||||
qCDebug(statesLog()) << msg;
|
qCDebug(statesLog()) << msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
Brings the application determined by this RunControl's \c applicationProcessHandle
|
|
||||||
to the foreground.
|
|
||||||
|
|
||||||
The default implementation raises the application on Mac, and does
|
|
||||||
nothing elsewhere.
|
|
||||||
*/
|
|
||||||
void RunControl::bringApplicationToForeground()
|
|
||||||
{
|
|
||||||
d->applicationProcessHandle.activate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RunControl::appendMessage(const QString &msg, Utils::OutputFormat format)
|
void RunControl::appendMessage(const QString &msg, Utils::OutputFormat format)
|
||||||
{
|
{
|
||||||
emit appendMessageRequested(this, msg, format);
|
emit appendMessageRequested(this, msg, format);
|
||||||
@@ -1358,8 +1410,9 @@ void SimpleTargetRunner::stop()
|
|||||||
void SimpleTargetRunner::onProcessStarted()
|
void SimpleTargetRunner::onProcessStarted()
|
||||||
{
|
{
|
||||||
// Console processes only know their pid after being started
|
// Console processes only know their pid after being started
|
||||||
runControl()->setApplicationProcessHandle(m_launcher.applicationPID());
|
ProcessHandle pid = m_launcher.applicationPID();
|
||||||
runControl()->bringApplicationToForeground();
|
runControl()->setApplicationProcessHandle(pid);
|
||||||
|
pid.activate();
|
||||||
reportStarted();
|
reportStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -245,6 +245,12 @@ public:
|
|||||||
|
|
||||||
static RunConfiguration *startupRunConfiguration();
|
static RunConfiguration *startupRunConfiguration();
|
||||||
|
|
||||||
|
using AspectFactory = std::function<IRunConfigurationAspect *(RunConfiguration *)>;
|
||||||
|
template <class T> static void registerAspect()
|
||||||
|
{
|
||||||
|
addAspectFactory([](RunConfiguration *rc) { return new T(rc); });
|
||||||
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void enabledChanged();
|
void enabledChanged();
|
||||||
void requestRunActionsUpdate();
|
void requestRunActionsUpdate();
|
||||||
@@ -260,7 +266,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void ctor();
|
void ctor();
|
||||||
|
|
||||||
void addExtraAspects();
|
static void addAspectFactory(const AspectFactory &aspectFactory);
|
||||||
|
|
||||||
QList<IRunConfigurationAspect *> m_aspects;
|
QList<IRunConfigurationAspect *> m_aspects;
|
||||||
};
|
};
|
||||||
@@ -295,22 +301,6 @@ private:
|
|||||||
virtual RunConfiguration *doRestore(Target *parent, const QVariantMap &map) = 0;
|
virtual RunConfiguration *doRestore(Target *parent, const QVariantMap &map) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PROJECTEXPLORER_EXPORT IRunControlFactory : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
explicit IRunControlFactory(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
virtual bool canRun(RunConfiguration *runConfiguration, Core::Id runMode) const;
|
|
||||||
virtual RunControl *create(RunConfiguration *runConfiguration, Core::Id runMode, QString *errorMessage);
|
|
||||||
|
|
||||||
virtual IRunConfigurationAspect *createRunConfigurationAspect(RunConfiguration *rc);
|
|
||||||
|
|
||||||
int priority() const;
|
|
||||||
protected:
|
|
||||||
void setPriority(int priority); // Higher values will be preferred.
|
|
||||||
};
|
|
||||||
|
|
||||||
class PROJECTEXPLORER_EXPORT RunConfigWidget : public QWidget
|
class PROJECTEXPLORER_EXPORT RunConfigWidget : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -397,6 +387,7 @@ public:
|
|||||||
void initiateStart();
|
void initiateStart();
|
||||||
void initiateReStart();
|
void initiateReStart();
|
||||||
void initiateStop();
|
void initiateStop();
|
||||||
|
void initiateFinish();
|
||||||
|
|
||||||
bool promptToStop(bool *optionalPrompt = nullptr) const;
|
bool promptToStop(bool *optionalPrompt = nullptr) const;
|
||||||
void setPromptToStop(const std::function<bool(bool *)> &promptToStop);
|
void setPromptToStop(const std::function<bool(bool *)> &promptToStop);
|
||||||
@@ -430,7 +421,6 @@ public:
|
|||||||
void setRunnable(const Runnable &runnable);
|
void setRunnable(const Runnable &runnable);
|
||||||
|
|
||||||
virtual void appendMessage(const QString &msg, Utils::OutputFormat format);
|
virtual void appendMessage(const QString &msg, Utils::OutputFormat format);
|
||||||
virtual void bringApplicationToForeground();
|
|
||||||
|
|
||||||
static bool showPromptToStopDialog(const QString &title, const QString &text,
|
static bool showPromptToStopDialog(const QString &title, const QString &text,
|
||||||
const QString &stopButtonText = QString(),
|
const QString &stopButtonText = QString(),
|
||||||
@@ -450,24 +440,28 @@ public:
|
|||||||
addWorkerFactory({runMode, constraint, producer});
|
addWorkerFactory({runMode, constraint, producer});
|
||||||
}
|
}
|
||||||
template <class Worker>
|
template <class Worker>
|
||||||
static void registerWorker(Core::Id runMode, const Constraint &constraint)
|
static void registerWorker(Core::Id runMode, const Constraint &constraint, int priority = 0)
|
||||||
{
|
{
|
||||||
auto producer = [](RunControl *rc) { return new Worker(rc); };
|
auto producer = [](RunControl *rc) { return new Worker(rc); };
|
||||||
addWorkerFactory({runMode, constraint, producer});
|
addWorkerFactory({runMode, constraint, producer, priority});
|
||||||
}
|
}
|
||||||
template <class Config, class Worker>
|
template <class Config, class Worker>
|
||||||
static void registerWorker(Core::Id runMode)
|
static void registerWorker(Core::Id runMode, int priority = 0)
|
||||||
{
|
{
|
||||||
auto constraint = [](RunConfiguration *runConfig) { return qobject_cast<Config *>(runConfig); };
|
auto constraint = [](RunConfiguration *runConfig) { return qobject_cast<Config *>(runConfig); };
|
||||||
auto producer = [](RunControl *rc) { return new Worker(rc); };
|
auto producer = [](RunControl *rc) { return new Worker(rc); };
|
||||||
addWorkerFactory({runMode, constraint, producer});
|
addWorkerFactory({runMode, constraint, producer, priority});
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WorkerFactory {
|
struct WorkerFactory {
|
||||||
Core::Id runMode;
|
Core::Id runMode;
|
||||||
Constraint constraint;
|
Constraint constraint;
|
||||||
WorkerCreator producer;
|
WorkerCreator producer;
|
||||||
|
int priority = 0;
|
||||||
|
|
||||||
|
WorkerFactory(const Core::Id &mode, Constraint constr, const WorkerCreator &prod,
|
||||||
|
int prio = 0)
|
||||||
|
: runMode(mode), constraint(constr), producer(prod), priority(prio) {}
|
||||||
bool canRun(RunConfiguration *runConfiguration, Core::Id runMode) const;
|
bool canRun(RunConfiguration *runConfiguration, Core::Id runMode) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -479,6 +473,7 @@ signals:
|
|||||||
void aboutToStart();
|
void aboutToStart();
|
||||||
void started();
|
void started();
|
||||||
void stopped();
|
void stopped();
|
||||||
|
void finished();
|
||||||
void applicationProcessHandleChanged(QPrivateSignal); // Use setApplicationProcessHandle
|
void applicationProcessHandleChanged(QPrivateSignal); // Use setApplicationProcessHandle
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/qtcfallthrough.h>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
@@ -358,6 +359,7 @@ bool FormEditorScene::event(QEvent * event)
|
|||||||
currentTool()->keyPressEvent(static_cast<QKeyEvent*>(event));
|
currentTool()->keyPressEvent(static_cast<QKeyEvent*>(event));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Q_FALLTHROUGH();
|
||||||
default: return QGraphicsScene::event(event);
|
default: return QGraphicsScene::event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1029,9 +1029,9 @@ bool NodeMetaInfoPrivate::cleverCheckType(const TypeName &otherType) const
|
|||||||
return typeName == convertedName.toUtf8();
|
return typeName == convertedName.toUtf8();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant::Type NodeMetaInfoPrivate::variantTypeId(const PropertyName &properyName) const
|
QVariant::Type NodeMetaInfoPrivate::variantTypeId(const PropertyName &propertyName) const
|
||||||
{
|
{
|
||||||
TypeName typeName = propertyType(properyName);
|
TypeName typeName = propertyType(propertyName);
|
||||||
if (typeName == "string")
|
if (typeName == "string")
|
||||||
return QVariant::String;
|
return QVariant::String;
|
||||||
|
|
||||||
|
|||||||
@@ -76,16 +76,6 @@ namespace Internal {
|
|||||||
|
|
||||||
Q_GLOBAL_STATIC(QmlProfilerSettings, qmlProfilerGlobalSettings)
|
Q_GLOBAL_STATIC(QmlProfilerSettings, qmlProfilerGlobalSettings)
|
||||||
|
|
||||||
|
|
||||||
class QmlProfilerRunControlFactory : public IRunControlFactory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IRunConfigurationAspect *createRunConfigurationAspect(RunConfiguration *rc) override
|
|
||||||
{
|
|
||||||
return new QmlProfilerRunConfigurationAspect(rc);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool QmlProfilerPlugin::initialize(const QStringList &arguments, QString *errorString)
|
bool QmlProfilerPlugin::initialize(const QStringList &arguments, QString *errorString)
|
||||||
{
|
{
|
||||||
Q_UNUSED(arguments)
|
Q_UNUSED(arguments)
|
||||||
@@ -101,7 +91,8 @@ void QmlProfilerPlugin::extensionsInitialized()
|
|||||||
(void) new QmlProfilerTool(this);
|
(void) new QmlProfilerTool(this);
|
||||||
|
|
||||||
addAutoReleasedObject(new QmlProfilerOptionsPage);
|
addAutoReleasedObject(new QmlProfilerOptionsPage);
|
||||||
addAutoReleasedObject(new QmlProfilerRunControlFactory);
|
|
||||||
|
RunConfiguration::registerAspect<QmlProfilerRunConfigurationAspect>();
|
||||||
|
|
||||||
auto constraint = [](RunConfiguration *runConfiguration) {
|
auto constraint = [](RunConfiguration *runConfiguration) {
|
||||||
Target *target = runConfiguration ? runConfiguration->target() : nullptr;
|
Target *target = runConfiguration ? runConfiguration->target() : nullptr;
|
||||||
|
|||||||
@@ -69,6 +69,8 @@
|
|||||||
|
|
||||||
#include <qtsupport/qtkitinformation.h>
|
#include <qtsupport/qtkitinformation.h>
|
||||||
|
|
||||||
|
#include <utils/qtcfallthrough.h>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
@@ -387,6 +389,7 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunner *runWorker)
|
|||||||
case QMessageBox::Help:
|
case QMessageBox::Help:
|
||||||
HelpManager::handleHelpRequest(
|
HelpManager::handleHelpRequest(
|
||||||
"qthelp://org.qt-project.qtcreator/doc/creator-debugging-qml.html");
|
"qthelp://org.qt-project.qtcreator/doc/creator-debugging-qml.html");
|
||||||
|
Q_FALLTHROUGH();
|
||||||
case QMessageBox::Cancel:
|
case QMessageBox::Cancel:
|
||||||
// The actual error message has already been logged.
|
// The actual error message has already been logged.
|
||||||
logState(tr("Failed to connect."));
|
logState(tr("Failed to connect."));
|
||||||
|
|||||||
@@ -53,6 +53,7 @@
|
|||||||
// Needed for the load&save actions in the context menu
|
// Needed for the load&save actions in the context menu
|
||||||
#include <debugger/analyzer/analyzermanager.h>
|
#include <debugger/analyzer/analyzermanager.h>
|
||||||
#include <coreplugin/findplaceholder.h>
|
#include <coreplugin/findplaceholder.h>
|
||||||
|
#include <utils/qtcfallthrough.h>
|
||||||
#include <utils/styledbar.h>
|
#include <utils/styledbar.h>
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
@@ -103,7 +104,7 @@ QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, QmlProfilerViewManag
|
|||||||
qint64 end = modelManager->traceTime()->endTime();
|
qint64 end = modelManager->traceTime()->endTime();
|
||||||
d->m_zoomControl->setTrace(start, end);
|
d->m_zoomControl->setTrace(start, end);
|
||||||
d->m_zoomControl->setRange(start, start + (end - start) / 10);
|
d->m_zoomControl->setRange(start, start + (end - start) / 10);
|
||||||
// Fall through
|
Q_FALLTHROUGH();
|
||||||
}
|
}
|
||||||
case QmlProfilerModelManager::Empty:
|
case QmlProfilerModelManager::Empty:
|
||||||
d->m_modelProxy->setModels(d->m_suspendedModels);
|
d->m_modelProxy->setModels(d->m_suspendedModels);
|
||||||
@@ -116,7 +117,7 @@ QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, QmlProfilerViewManag
|
|||||||
d->m_zoomControl->clear();
|
d->m_zoomControl->clear();
|
||||||
if (!d->m_suspendedModels.isEmpty())
|
if (!d->m_suspendedModels.isEmpty())
|
||||||
break; // Models are suspended already. AcquiringData was aborted.
|
break; // Models are suspended already. AcquiringData was aborted.
|
||||||
// Fall through
|
Q_FALLTHROUGH();
|
||||||
case QmlProfilerModelManager::AcquiringData:
|
case QmlProfilerModelManager::AcquiringData:
|
||||||
// Temporarily remove the models, while we're changing them
|
// Temporarily remove the models, while we're changing them
|
||||||
d->m_suspendedModels = d->m_modelProxy->models();
|
d->m_suspendedModels = d->m_modelProxy->models();
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
#include "scxmldocument.h"
|
#include "scxmldocument.h"
|
||||||
#include "scxmltag.h"
|
#include "scxmltag.h"
|
||||||
|
|
||||||
|
#include <utils/qtcfallthrough.h>
|
||||||
|
|
||||||
#include <QMimeData>
|
#include <QMimeData>
|
||||||
#include <QUndoStack>
|
#include <QUndoStack>
|
||||||
|
|
||||||
@@ -245,6 +247,7 @@ Qt::ItemFlags StructureModel::flags(const QModelIndex &index) const
|
|||||||
case Final:
|
case Final:
|
||||||
case History:
|
case History:
|
||||||
defaultFlags |= Qt::ItemIsDragEnabled;
|
defaultFlags |= Qt::ItemIsDragEnabled;
|
||||||
|
Q_FALLTHROUGH();
|
||||||
case Scxml:
|
case Scxml:
|
||||||
defaultFlags |= Qt::ItemIsDropEnabled;
|
defaultFlags |= Qt::ItemIsDropEnabled;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -3821,7 +3821,7 @@ void TextEditorWidgetPrivate::drawLineAnnotation(QPainter &painter, const QTextB
|
|||||||
QRectF annotationRect(x, lineRect.top(), q->viewport()->width() - x, lineRect.height());
|
QRectF annotationRect(x, lineRect.top(), q->viewport()->width() - x, lineRect.height());
|
||||||
if (annotationRect.width() <= 0)
|
if (annotationRect.width() <= 0)
|
||||||
break;
|
break;
|
||||||
mark->paintAnnotation(&painter, &annotationRect, q->fontMetrics());
|
mark->paintAnnotation(&painter, &annotationRect);
|
||||||
x += annotationRect.width() + itemOffset;
|
x += annotationRect.width() + itemOffset;
|
||||||
m_annotationRects[block.blockNumber()].append({annotationRect, mark});
|
m_annotationRects[block.blockNumber()].append({annotationRect, mark});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,42 +123,52 @@ void TextMark::paintIcon(QPainter *painter, const QRect &rect) const
|
|||||||
m_icon.paint(painter, rect, Qt::AlignCenter);
|
m_icon.paint(painter, rect, Qt::AlignCenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextMark::paintAnnotation(QPainter *painter,
|
void TextMark::paintAnnotation(QPainter *painter, QRectF *annotationRect) const
|
||||||
QRectF *annotationRect,
|
|
||||||
const QFontMetrics &fm) const
|
|
||||||
{
|
{
|
||||||
QString text = lineAnnotation();
|
QString text = lineAnnotation();
|
||||||
if (text.isEmpty())
|
if (text.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const bool drawIcon = !m_icon.isNull();
|
const AnnotationRects &rects = annotationRects(*annotationRect, painter->fontMetrics());
|
||||||
int textWidth = fm.width(text);
|
|
||||||
constexpr qreal margin = 1;
|
|
||||||
const qreal iconHeight = annotationRect->height() - 2 * margin;
|
|
||||||
const qreal iconWidth = iconHeight * m_widthFactor + 2 * margin;
|
|
||||||
qreal annotationWidth = (drawIcon ? textWidth + iconWidth : textWidth) + margin;
|
|
||||||
if (annotationRect->left() + annotationWidth > annotationRect->right()) {
|
|
||||||
textWidth = int(annotationRect->width() - (drawIcon ? iconWidth + margin : margin));
|
|
||||||
text = fm.elidedText(text, Qt::ElideRight, textWidth);
|
|
||||||
annotationWidth = annotationRect->width();
|
|
||||||
}
|
|
||||||
const QColor markColor = m_hasColor ? Utils::creatorTheme()->color(m_color).toHsl()
|
const QColor markColor = m_hasColor ? Utils::creatorTheme()->color(m_color).toHsl()
|
||||||
: painter->pen().color();
|
: painter->pen().color();
|
||||||
const AnnotationColors &colors =
|
const AnnotationColors &colors =
|
||||||
AnnotationColors::getAnnotationColors(markColor, painter->background().color());
|
AnnotationColors::getAnnotationColors(markColor, painter->background().color());
|
||||||
|
|
||||||
painter->save();
|
painter->save();
|
||||||
annotationRect->setWidth(annotationWidth);
|
|
||||||
painter->setPen(colors.rectColor);
|
painter->setPen(colors.rectColor);
|
||||||
painter->setBrush(colors.rectColor);
|
painter->setBrush(colors.rectColor);
|
||||||
painter->drawRect(*annotationRect);
|
painter->drawRect(rects.annotationRect);
|
||||||
painter->setPen(colors.textColor);
|
painter->setPen(colors.textColor);
|
||||||
if (drawIcon) {
|
paintIcon(painter, rects.iconRect.toAlignedRect());
|
||||||
paintIcon(painter, annotationRect->adjusted(
|
painter->drawText(rects.textRect, Qt::AlignLeft, rects.text);
|
||||||
margin, margin, -(textWidth + 2 * margin), -margin).toAlignedRect());
|
|
||||||
}
|
|
||||||
painter->drawText(annotationRect->adjusted(iconWidth, 0, 0, 0), Qt::AlignLeft, text);
|
|
||||||
painter->restore();
|
painter->restore();
|
||||||
|
*annotationRect = rects.annotationRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextMark::AnnotationRects TextMark::annotationRects(const QRectF &boundingRect,
|
||||||
|
const QFontMetrics &fm) const
|
||||||
|
{
|
||||||
|
AnnotationRects rects;
|
||||||
|
rects.annotationRect = boundingRect;
|
||||||
|
rects.text = lineAnnotation();
|
||||||
|
const bool drawIcon = !m_icon.isNull();
|
||||||
|
constexpr qreal margin = 1;
|
||||||
|
rects.iconRect = QRectF(boundingRect.left() + margin, boundingRect.top() + margin, 0, 0);
|
||||||
|
if (drawIcon) {
|
||||||
|
rects.iconRect.setHeight(boundingRect.height() - 2 * margin);
|
||||||
|
rects.iconRect.setWidth(rects.iconRect.height() * m_widthFactor);
|
||||||
|
}
|
||||||
|
rects.textRect = QRectF(rects.iconRect.right() + margin, boundingRect.top(),
|
||||||
|
qreal(fm.width(rects.text)), boundingRect.height());
|
||||||
|
rects.annotationRect.setRight(rects.textRect.right() + margin);
|
||||||
|
if (rects.annotationRect.right() > boundingRect.right()) {
|
||||||
|
rects.textRect.setRight(boundingRect.right() - margin);
|
||||||
|
rects.text = fm.elidedText(rects.text, Qt::ElideRight, int(rects.textRect.width()));
|
||||||
|
rects.annotationRect.setRight(boundingRect.right());
|
||||||
|
}
|
||||||
|
return rects;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextMark::updateLineNumber(int lineNumber)
|
void TextMark::updateLineNumber(int lineNumber)
|
||||||
|
|||||||
@@ -64,7 +64,15 @@ public:
|
|||||||
int lineNumber() const;
|
int lineNumber() const;
|
||||||
|
|
||||||
virtual void paintIcon(QPainter *painter, const QRect &rect) const;
|
virtual void paintIcon(QPainter *painter, const QRect &rect) const;
|
||||||
virtual void paintAnnotation(QPainter *painter, QRectF *annotationRect, const QFontMetrics &fm) const;
|
virtual void paintAnnotation(QPainter *painter, QRectF *annotationRect) const;
|
||||||
|
struct AnnotationRects
|
||||||
|
{
|
||||||
|
QRectF annotationRect;
|
||||||
|
QRectF iconRect;
|
||||||
|
QRectF textRect;
|
||||||
|
QString text;
|
||||||
|
};
|
||||||
|
virtual AnnotationRects annotationRects(const QRectF &boundingRect, const QFontMetrics &fm) const;
|
||||||
/// called if the filename of the document changed
|
/// called if the filename of the document changed
|
||||||
virtual void updateFileName(const QString &fileName);
|
virtual void updateFileName(const QString &fileName);
|
||||||
virtual void updateLineNumber(int lineNumber);
|
virtual void updateLineNumber(int lineNumber);
|
||||||
|
|||||||
@@ -562,6 +562,7 @@ RunWorker *MemcheckTool::createRunWorker(RunControl *runControl)
|
|||||||
connect(runTool, &MemcheckToolRunner::internalParserError, this, &MemcheckTool::internalParserError);
|
connect(runTool, &MemcheckToolRunner::internalParserError, this, &MemcheckTool::internalParserError);
|
||||||
connect(runTool, &MemcheckToolRunner::stopped, this, &MemcheckTool::engineFinished);
|
connect(runTool, &MemcheckToolRunner::stopped, this, &MemcheckTool::engineFinished);
|
||||||
|
|
||||||
|
m_stopAction->disconnect();
|
||||||
connect(m_stopAction, &QAction::triggered, runControl, &RunControl::initiateStop);
|
connect(m_stopAction, &QAction::triggered, runControl, &RunControl::initiateStop);
|
||||||
|
|
||||||
m_toolBusy = true;
|
m_toolBusy = true;
|
||||||
|
|||||||
@@ -106,7 +106,6 @@ void ValgrindToolRunner::stop()
|
|||||||
{
|
{
|
||||||
m_isStopping = true;
|
m_isStopping = true;
|
||||||
m_runner.stop();
|
m_runner.stop();
|
||||||
reportStopped(); // FIXME: Restrict to non-running scenarios?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ValgrindToolRunner::executable() const
|
QString ValgrindToolRunner::executable() const
|
||||||
|
|||||||
@@ -110,15 +110,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ValgrindRunControlFactory : public IRunControlFactory
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
IRunConfigurationAspect *createRunConfigurationAspect(RunConfiguration *rc) override
|
|
||||||
{
|
|
||||||
return new ValgrindRunConfigurationAspect(rc);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ValgrindPlugin::~ValgrindPlugin()
|
ValgrindPlugin::~ValgrindPlugin()
|
||||||
{
|
{
|
||||||
delete theGlobalSettings;
|
delete theGlobalSettings;
|
||||||
@@ -131,7 +122,8 @@ bool ValgrindPlugin::initialize(const QStringList &, QString *)
|
|||||||
theGlobalSettings->readSettings();
|
theGlobalSettings->readSettings();
|
||||||
|
|
||||||
addAutoReleasedObject(new ValgrindOptionsPage);
|
addAutoReleasedObject(new ValgrindOptionsPage);
|
||||||
addAutoReleasedObject(new ValgrindRunControlFactory);
|
|
||||||
|
RunConfiguration::registerAspect<ValgrindRunConfigurationAspect>();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/qtcfallthrough.h>
|
||||||
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
@@ -56,6 +57,7 @@ public:
|
|||||||
switch (v.type()) {
|
switch (v.type()) {
|
||||||
case QVariant::UInt:
|
case QVariant::UInt:
|
||||||
m_type = QVariant::Int;
|
m_type = QVariant::Int;
|
||||||
|
Q_FALLTHROUGH();
|
||||||
case QVariant::Int:
|
case QVariant::Int:
|
||||||
m_comp.intValue = v.toInt();
|
m_comp.intValue = v.toInt();
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -48,6 +48,37 @@ static void readPatch(QFutureInterface<QList<FileData>> &futureInterface,
|
|||||||
futureInterface.reportResult(fileDataList);
|
futureInterface.reportResult(fileDataList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////////////////////
|
||||||
|
|
||||||
|
// We need a way to disconnect from signals posted from different thread
|
||||||
|
// so that signals that are already posted from the other thread and not delivered
|
||||||
|
// yet will be ignored. Unfortunately, simple QObject::disconnect() doesn't
|
||||||
|
// work like that, since signals that are already posted and are awaiting
|
||||||
|
// to be delivered WILL BE delivered later, even after a call to QObject::disconnect().
|
||||||
|
// The delivery will happen when the control returns to the main event loop.
|
||||||
|
|
||||||
|
// This proxy class solves the above problem. Instead of a call to
|
||||||
|
// QObject::disconnect(), which would still deliver posted signals,
|
||||||
|
// we delete the proxy object immediately. In this way signals which are
|
||||||
|
// already posted and are awaiting to be delivered won't be delivered to the
|
||||||
|
// destroyed object.
|
||||||
|
|
||||||
|
// So the only reason for this proxy object is to be able to disconnect
|
||||||
|
// effectively from the signals posted from different threads.
|
||||||
|
|
||||||
|
class VcsCommandResultProxy : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
VcsCommandResultProxy(VcsCommand *command, VcsBaseDiffEditorControllerPrivate *target);
|
||||||
|
private:
|
||||||
|
void storeOutput(const QString &output);
|
||||||
|
void commandFinished(bool success);
|
||||||
|
|
||||||
|
VcsBaseDiffEditorControllerPrivate *m_target;
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////
|
||||||
|
|
||||||
class VcsBaseDiffEditorControllerPrivate
|
class VcsBaseDiffEditorControllerPrivate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -59,6 +90,7 @@ public:
|
|||||||
void processingFinished();
|
void processingFinished();
|
||||||
void processDiff(const QString &patch);
|
void processDiff(const QString &patch);
|
||||||
void cancelReload();
|
void cancelReload();
|
||||||
|
void storeOutput(const QString &output);
|
||||||
void commandFinished(bool success);
|
void commandFinished(bool success);
|
||||||
|
|
||||||
VcsBaseDiffEditorController *q;
|
VcsBaseDiffEditorController *q;
|
||||||
@@ -67,18 +99,43 @@ public:
|
|||||||
QString m_startupFile;
|
QString m_startupFile;
|
||||||
QString m_output;
|
QString m_output;
|
||||||
QPointer<VcsCommand> m_command;
|
QPointer<VcsCommand> m_command;
|
||||||
QFutureWatcher<QList<FileData>> m_processWatcher;
|
QPointer<VcsCommandResultProxy> m_commandResultProxy;
|
||||||
|
QFutureWatcher<QList<FileData>> *m_processWatcher = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
VcsBaseDiffEditorControllerPrivate::VcsBaseDiffEditorControllerPrivate(VcsBaseDiffEditorController *controller,
|
/////////////////////
|
||||||
|
|
||||||
|
VcsCommandResultProxy::VcsCommandResultProxy(VcsCommand *command,
|
||||||
|
VcsBaseDiffEditorControllerPrivate *target)
|
||||||
|
: QObject(target->q)
|
||||||
|
, m_target(target)
|
||||||
|
{
|
||||||
|
connect(command, &VcsCommand::stdOutText,
|
||||||
|
this, &VcsCommandResultProxy::storeOutput);
|
||||||
|
connect(command, &VcsCommand::finished,
|
||||||
|
this, &VcsCommandResultProxy::commandFinished);
|
||||||
|
connect(command, &VcsCommand::destroyed,
|
||||||
|
this, &QObject::deleteLater);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VcsCommandResultProxy::storeOutput(const QString &output)
|
||||||
|
{
|
||||||
|
m_target->storeOutput(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VcsCommandResultProxy::commandFinished(bool success)
|
||||||
|
{
|
||||||
|
m_target->commandFinished(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
VcsBaseDiffEditorControllerPrivate::VcsBaseDiffEditorControllerPrivate(
|
||||||
|
VcsBaseDiffEditorController *controller,
|
||||||
VcsBaseClientImpl *client,
|
VcsBaseClientImpl *client,
|
||||||
const QString &workingDirectory)
|
const QString &workingDirectory)
|
||||||
: q(controller)
|
: q(controller)
|
||||||
, m_client(client)
|
, m_client(client)
|
||||||
, m_directory(workingDirectory)
|
, m_directory(workingDirectory)
|
||||||
{
|
{
|
||||||
QObject::connect(&m_processWatcher, &QFutureWatcher<QList<FileData>>::finished, q,
|
|
||||||
[this] () { processingFinished(); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VcsBaseDiffEditorControllerPrivate::~VcsBaseDiffEditorControllerPrivate()
|
VcsBaseDiffEditorControllerPrivate::~VcsBaseDiffEditorControllerPrivate()
|
||||||
@@ -88,9 +145,18 @@ VcsBaseDiffEditorControllerPrivate::~VcsBaseDiffEditorControllerPrivate()
|
|||||||
|
|
||||||
void VcsBaseDiffEditorControllerPrivate::processingFinished()
|
void VcsBaseDiffEditorControllerPrivate::processingFinished()
|
||||||
{
|
{
|
||||||
bool success = !m_processWatcher.future().isCanceled();
|
QTC_ASSERT(m_processWatcher, return);
|
||||||
|
|
||||||
|
// success is false when the user clicked the cancel micro button
|
||||||
|
// inside the progress indicator
|
||||||
|
const bool success = !m_processWatcher->future().isCanceled();
|
||||||
const QList<FileData> fileDataList = success
|
const QList<FileData> fileDataList = success
|
||||||
? m_processWatcher.future().result() : QList<FileData>();
|
? m_processWatcher->future().result() : QList<FileData>();
|
||||||
|
|
||||||
|
// Prevent direct deletion of m_processWatcher since
|
||||||
|
// processingFinished() is called directly by the m_processWatcher.
|
||||||
|
m_processWatcher->deleteLater();
|
||||||
|
m_processWatcher = nullptr;
|
||||||
|
|
||||||
q->setDiffFiles(fileDataList, q->workingDirectory(), q->startupFile());
|
q->setDiffFiles(fileDataList, q->workingDirectory(), q->startupFile());
|
||||||
q->reloadFinished(success);
|
q->reloadFinished(success);
|
||||||
@@ -98,39 +164,67 @@ void VcsBaseDiffEditorControllerPrivate::processingFinished()
|
|||||||
|
|
||||||
void VcsBaseDiffEditorControllerPrivate::processDiff(const QString &patch)
|
void VcsBaseDiffEditorControllerPrivate::processDiff(const QString &patch)
|
||||||
{
|
{
|
||||||
m_processWatcher.setFuture(Utils::runAsync(&readPatch, patch));
|
cancelReload();
|
||||||
|
|
||||||
ProgressManager::addTask(m_processWatcher.future(),
|
m_processWatcher = new QFutureWatcher<QList<FileData>>();
|
||||||
q->tr("Processing diff"), "DiffEditor");
|
|
||||||
|
QObject::connect(m_processWatcher, &QFutureWatcher<QList<FileData>>::finished,
|
||||||
|
[this] () { processingFinished(); } );
|
||||||
|
|
||||||
|
m_processWatcher->setFuture(Utils::runAsync(&readPatch, patch));
|
||||||
|
|
||||||
|
ProgressManager::addTask(m_processWatcher->future(),
|
||||||
|
q->tr("Processing diff"), "DiffEditor");
|
||||||
}
|
}
|
||||||
|
|
||||||
void VcsBaseDiffEditorControllerPrivate::cancelReload()
|
void VcsBaseDiffEditorControllerPrivate::cancelReload()
|
||||||
{
|
{
|
||||||
if (m_command) {
|
if (m_command) {
|
||||||
m_command->disconnect();
|
|
||||||
m_command->cancel();
|
m_command->cancel();
|
||||||
m_command.clear();
|
m_command.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_processWatcher.future().isRunning()) {
|
// Disconnect effectively, don't deliver already posted signals
|
||||||
m_processWatcher.future().cancel();
|
if (m_commandResultProxy)
|
||||||
m_processWatcher.setFuture(QFuture<QList<FileData>>());
|
delete m_commandResultProxy.data();
|
||||||
|
|
||||||
|
if (m_processWatcher) {
|
||||||
|
// Cancel the running process without the further processingFinished()
|
||||||
|
// notification for this process.
|
||||||
|
m_processWatcher->future().cancel();
|
||||||
|
delete m_processWatcher;
|
||||||
|
m_processWatcher = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_output = QString();
|
m_output = QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VcsBaseDiffEditorControllerPrivate::storeOutput(const QString &output)
|
||||||
|
{
|
||||||
|
m_output = output;
|
||||||
|
}
|
||||||
|
|
||||||
void VcsBaseDiffEditorControllerPrivate::commandFinished(bool success)
|
void VcsBaseDiffEditorControllerPrivate::commandFinished(bool success)
|
||||||
{
|
{
|
||||||
if (m_command)
|
if (m_command)
|
||||||
m_command.clear();
|
m_command.clear();
|
||||||
|
|
||||||
|
// Prevent direct deletion of m_commandResultProxy inside the possible
|
||||||
|
// subsequent synchronous calls to cancelReload() [called e.g. by
|
||||||
|
// processCommandOutput() overload], since
|
||||||
|
// commandFinished() is called directly by the m_commandResultProxy.
|
||||||
|
// m_commandResultProxy is removed via deleteLater right after
|
||||||
|
// a call to this commandFinished() is finished
|
||||||
|
if (m_commandResultProxy)
|
||||||
|
m_commandResultProxy.clear();
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
cancelReload();
|
cancelReload();
|
||||||
q->reloadFinished(success);
|
q->reloadFinished(success);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
q->processCommandOutput(m_output);
|
q->processCommandOutput(QString(m_output)); // pass a copy of m_output
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////
|
/////////////////////
|
||||||
@@ -150,14 +244,15 @@ VcsBaseDiffEditorController::~VcsBaseDiffEditorController()
|
|||||||
|
|
||||||
void VcsBaseDiffEditorController::runCommand(const QList<QStringList> &args, unsigned flags, QTextCodec *codec)
|
void VcsBaseDiffEditorController::runCommand(const QList<QStringList> &args, unsigned flags, QTextCodec *codec)
|
||||||
{
|
{
|
||||||
|
// Cancel the possible ongoing reload without the commandFinished() nor
|
||||||
|
// processingFinished() notifications, as right after that
|
||||||
|
// we re-reload it from scratch. So no intermediate "Retrieving data failed."
|
||||||
|
// and "Waiting for data..." will be shown.
|
||||||
d->cancelReload();
|
d->cancelReload();
|
||||||
|
|
||||||
d->m_command = new VcsCommand(workingDirectory(), d->m_client->processEnvironment());
|
d->m_command = new VcsCommand(workingDirectory(), d->m_client->processEnvironment());
|
||||||
d->m_command->setCodec(codec ? codec : EditorManager::defaultTextCodec());
|
d->m_command->setCodec(codec ? codec : EditorManager::defaultTextCodec());
|
||||||
connect(d->m_command.data(), &VcsCommand::stdOutText, this,
|
d->m_commandResultProxy = new VcsCommandResultProxy(d->m_command.data(), d);
|
||||||
[this] (const QString &output) { d->m_output = output; });
|
|
||||||
connect(d->m_command.data(), &VcsCommand::finished, this,
|
|
||||||
[this] (bool success) { d->commandFinished(success); });
|
|
||||||
d->m_command->addFlags(flags);
|
d->m_command->addFlags(flags);
|
||||||
|
|
||||||
for (const QStringList &arg : args) {
|
for (const QStringList &arg : args) {
|
||||||
@@ -195,3 +290,5 @@ QString VcsBaseDiffEditorController::startupFile() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace VcsBase
|
} // namespace VcsBase
|
||||||
|
|
||||||
|
#include "vcsbasediffeditorcontroller.moc"
|
||||||
|
|||||||
@@ -1670,6 +1670,28 @@
|
|||||||
inkscape:connector-curvature="0"
|
inkscape:connector-curvature="0"
|
||||||
sodipodi:nodetypes="cccccccccccccccc" />
|
sodipodi:nodetypes="cccccccccccccccc" />
|
||||||
</g>
|
</g>
|
||||||
|
<g
|
||||||
|
id="share/qtcreator/templates/wizards/projects/nim/icon">
|
||||||
|
<rect
|
||||||
|
style="display:inline;fill:none"
|
||||||
|
id="rect5532-7-2-6-5-7"
|
||||||
|
width="92"
|
||||||
|
height="68"
|
||||||
|
x="190"
|
||||||
|
y="136" />
|
||||||
|
<path
|
||||||
|
id="path3799"
|
||||||
|
style="fill:#cecfd5"
|
||||||
|
d="m 263.88612,170.56484 c -2.25619,-7.49215 -13.9354,-14.04789 -27.88611,-14.04789 -14.23027,0 -25.62993,6.55574 -27.88613,14.04789 l -2.69076,2.30637 -3.80901,-7.33845 -2.93538,-12.37053 5.03208,2.0967 c 1.376,-1.39235 2.35711,-2.47631 5.87076,-4.40307 l 3.35472,-6.91911 5.66109,4.40307 c 3.80983,-0.90692 7.59785,-1.85747 11.95119,-1.67736 L 236,141.42071 l 5.45142,5.24175 c 4.35334,-0.18011 8.14136,0.77044 11.95119,1.67736 l 5.66109,-4.40307 3.35472,6.91911 c 3.51365,1.92676 4.49476,3.01072 5.87076,4.40307 l 5.03208,-2.0967 -2.93538,12.37053 -3.80901,7.33845 z"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="csccccccccccccccccccc" />
|
||||||
|
<path
|
||||||
|
id="path3801"
|
||||||
|
style="fill:#3a4055"
|
||||||
|
d="m 267.03116,171.19385 -3.14504,-0.83868 -5.6611,7.33846 L 250.46723,180 236,171.82286 221.53276,180 l -7.75779,-2.30637 -5.66109,-7.33846 -3.14505,0.83868 -3.35472,-5.87076 6.49977,18.45097 c 4.59209,9.55845 18.73642,14.25756 27.88613,14.25756 9.14969,0 23.29402,-4.69911 27.88611,-14.25756 l 6.49977,-18.45097 z"
|
||||||
|
inkscape:connector-curvature="0"
|
||||||
|
sodipodi:nodetypes="cccccccccccsccc" />
|
||||||
|
</g>
|
||||||
<g
|
<g
|
||||||
id="src/libs/utils/images/wizardicon-file"
|
id="src/libs/utils/images/wizardicon-file"
|
||||||
transform="translate(-102.49412,8.5102807)">
|
transform="translate(-102.49412,8.5102807)">
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 307 KiB After Width: | Height: | Size: 309 KiB |
@@ -157,7 +157,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
This propery is \c true when the user is resizing any of the items by
|
This property is \c true when the user is resizing any of the items by
|
||||||
dragging on the splitter handles.
|
dragging on the splitter handles.
|
||||||
*/
|
*/
|
||||||
property bool resizing: false
|
property bool resizing: false
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
This propery is \c true when the user is resizing any of the items by
|
This property is \c true when the user is resizing any of the items by
|
||||||
dragging on the splitter handles.
|
dragging on the splitter handles.
|
||||||
*/
|
*/
|
||||||
property bool resizing: false
|
property bool resizing: false
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ def prepareTestExamples():
|
|||||||
|
|
||||||
def switchSession(toSession):
|
def switchSession(toSession):
|
||||||
test.log("Switching to session '%s'" % toSession)
|
test.log("Switching to session '%s'" % toSession)
|
||||||
invokeMenuItem("File", "Session Manager...")
|
invokeMenuItem("File", "Sessions", "Manage...")
|
||||||
clickItem(waitForObject("{name='sessionView' type='ProjectExplorer::Internal::SessionView' visible='1' "
|
clickItem(waitForObject("{name='sessionView' type='ProjectExplorer::Internal::SessionView' visible='1' "
|
||||||
"window=':Session Manager_ProjectExplorer::Internal::SessionDialog'}"),
|
"window=':Session Manager_ProjectExplorer::Internal::SessionDialog'}"),
|
||||||
toSession, 5, 5, 0, Qt.LeftButton)
|
toSession, 5, 5, 0, Qt.LeftButton)
|
||||||
@@ -94,7 +94,7 @@ def createAndSwitchToSession(toSession):
|
|||||||
sessionInputDialog = ("{type='ProjectExplorer::Internal::SessionNameInputDialog' unnamed='1' "
|
sessionInputDialog = ("{type='ProjectExplorer::Internal::SessionNameInputDialog' unnamed='1' "
|
||||||
"visible='1' windowTitle='New Session Name'}")
|
"visible='1' windowTitle='New Session Name'}")
|
||||||
test.log("Switching to session '%s' after creating it." % toSession)
|
test.log("Switching to session '%s' after creating it." % toSession)
|
||||||
invokeMenuItem("File", "Session Manager...")
|
invokeMenuItem("File", "Sessions", "Manage...")
|
||||||
clickButton(waitForObject("{name='btCreateNew' text='New' type='QPushButton' visible='1' "
|
clickButton(waitForObject("{name='btCreateNew' text='New' type='QPushButton' visible='1' "
|
||||||
"window=':Session Manager_ProjectExplorer::Internal::SessionDialog'}"))
|
"window=':Session Manager_ProjectExplorer::Internal::SessionDialog'}"))
|
||||||
lineEdit = waitForObject("{type='QLineEdit' unnamed='1' visible='1' window=%s}"
|
lineEdit = waitForObject("{type='QLineEdit' unnamed='1' visible='1' window=%s}"
|
||||||
|
|||||||