aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2017-07-18 15:23:29 +0200
committerEike Ziller <eike.ziller@qt.io>2017-07-18 15:23:29 +0200
commit361fdad3be3421496be4dab014a8bee369687387 (patch)
tree4412737d90b20953064b8f53817c014ddc9714c3 /src
parent5e38bdbfd8bef6c3bdcede9fe0be11f34e9a0f7c (diff)
parent41ae823bda7cc1bad4b85861d9b0e3087c130e4a (diff)
Merge remote-tracking branch 'origin/4.4'
Diffstat (limited to 'src')
-rw-r--r--src/libs/3rdparty/cplusplus/Parser.cpp4
-rw-r--r--src/libs/cplusplus/MatchingText.cpp6
-rw-r--r--src/libs/utils/qtcfallthrough.h54
-rw-r--r--src/libs/utils/utils-lib.pri1
-rw-r--r--src/libs/utils/utils.qbs1
-rw-r--r--src/plugins/clangcodemodel/clangbackendipcintegration.cpp22
-rw-r--r--src/plugins/clangcodemodel/clangbackendipcintegration.h4
-rw-r--r--src/plugins/clangcodemodel/clangdiagnosticmanager.cpp15
-rw-r--r--src/plugins/clangcodemodel/clangdiagnosticmanager.h3
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp2
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp46
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h1
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp19
-rw-r--r--src/plugins/clangstaticanalyzer/clangstaticanalyzertool.h3
-rw-r--r--src/plugins/coreplugin/dialogs/newdialog.cpp34
-rw-r--r--src/plugins/coreplugin/locator/locatorwidget.cpp18
-rw-r--r--src/plugins/coreplugin/locator/locatorwidget.h4
-rw-r--r--src/plugins/cppeditor/cppeditor.cpp29
-rw-r--r--src/plugins/cppeditor/cppeditordocument.cpp8
-rw-r--r--src/plugins/cppeditor/cppquickfixes.cpp3
-rw-r--r--src/plugins/cppeditor/cppuseselectionsupdater.cpp6
-rw-r--r--src/plugins/cpptools/compileroptionsbuilder.cpp10
-rw-r--r--src/plugins/debugger/debuggerdialogs.cpp36
-rw-r--r--src/plugins/debugger/debuggerdialogs.h1
-rw-r--r--src/plugins/debugger/debuggerengine.cpp8
-rw-r--r--src/plugins/debugger/debuggerplugin.cpp14
-rw-r--r--src/plugins/debugger/gdb/attachgdbadapter.cpp3
-rw-r--r--src/plugins/debugger/gdb/remotegdbserveradapter.cpp3
-rw-r--r--src/plugins/debugger/moduleshandler.cpp3
-rw-r--r--src/plugins/debugger/qml/qmlengine.cpp5
-rw-r--r--src/plugins/debugger/watchutils.cpp4
-rw-r--r--src/plugins/diffeditor/diffeditorplugin.cpp6
-rw-r--r--src/plugins/ios/iosplugin.cpp19
-rw-r--r--src/plugins/ios/iosrunfactories.cpp49
-rw-r--r--src/plugins/ios/iosrunfactories.h17
-rw-r--r--src/plugins/ios/iosrunner.cpp25
-rw-r--r--src/plugins/ios/iosrunner.h1
-rw-r--r--src/plugins/ios/iostoolhandler.cpp7
-rw-r--r--src/plugins/projectexplorer/appoutputpane.cpp8
-rw-r--r--src/plugins/projectexplorer/appoutputpane.h3
-rw-r--r--src/plugins/projectexplorer/projectexplorer.cpp11
-rw-r--r--src/plugins/projectexplorer/projectexplorer.h1
-rw-r--r--src/plugins/projectexplorer/projecttreewidget.cpp2
-rw-r--r--src/plugins/projectexplorer/projecttreewidget.h2
-rw-r--r--src/plugins/projectexplorer/runconfiguration.cpp299
-rw-r--r--src/plugins/projectexplorer/runconfiguration.h39
-rw-r--r--src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp2
-rw-r--r--src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp4
-rw-r--r--src/plugins/qmlprofiler/qmlprofilerplugin.cpp13
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertool.cpp3
-rw-r--r--src/plugins/qmlprofiler/qmlprofilertraceview.cpp5
-rw-r--r--src/plugins/scxmleditor/common/structuremodel.cpp3
-rw-r--r--src/plugins/texteditor/texteditor.cpp2
-rw-r--r--src/plugins/texteditor/textmark.cpp50
-rw-r--r--src/plugins/texteditor/textmark.h10
-rw-r--r--src/plugins/valgrind/memchecktool.cpp1
-rw-r--r--src/plugins/valgrind/valgrindengine.cpp1
-rw-r--r--src/plugins/valgrind/valgrindplugin.cpp12
-rw-r--r--src/plugins/vcsbase/vcsbaseclientsettings.cpp2
-rw-r--r--src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp133
-rw-r--r--src/tools/icons/qtcreatoricons.svg22
61 files changed, 703 insertions, 419 deletions
diff --git a/src/libs/3rdparty/cplusplus/Parser.cpp b/src/libs/3rdparty/cplusplus/Parser.cpp
index 8754206a0b..16f351077a 100644
--- a/src/libs/3rdparty/cplusplus/Parser.cpp
+++ b/src/libs/3rdparty/cplusplus/Parser.cpp
@@ -27,6 +27,8 @@
#include "ObjectiveCTypeQualifiers.h"
#include "QtContextKeywords.h"
+#include <utils/qtcfallthrough.h>
+
#include <unordered_map>
#include <utility>
@@ -442,7 +444,7 @@ bool Parser::skipUntilStatement()
case T_AT_THROW:
if (_languageFeatures.objCEnabled)
return true;
-
+ Q_FALLTHROUGH();
default:
consumeToken();
}
diff --git a/src/libs/cplusplus/MatchingText.cpp b/src/libs/cplusplus/MatchingText.cpp
index f783d4c508..3fdb573b91 100644
--- a/src/libs/cplusplus/MatchingText.cpp
+++ b/src/libs/cplusplus/MatchingText.cpp
@@ -143,9 +143,13 @@ bool MatchingText::contextAllowsAutoParentheses(const QTextCursor &cursor,
if (!textToInsert.isEmpty())
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('"'))
return false;
- else if (isInCommentHelper(cursor))
+
+ if (isInCommentHelper(cursor))
return false;
return true;
diff --git a/src/libs/utils/qtcfallthrough.h b/src/libs/utils/qtcfallthrough.h
new file mode 100644
index 0000000000..6eba622837
--- /dev/null
+++ b/src/libs/utils/qtcfallthrough.h
@@ -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
diff --git a/src/libs/utils/utils-lib.pri b/src/libs/utils/utils-lib.pri
index bfc9d6084e..3a6aa0a09a 100644
--- a/src/libs/utils/utils-lib.pri
+++ b/src/libs/utils/utils-lib.pri
@@ -239,6 +239,7 @@ HEADERS += \
$$PWD/asconst.h \
$$PWD/smallstringfwd.h \
$$PWD/optional.h \
+ $$PWD/qtcfallthrough.h \
$$PWD/../3rdparty/optional/optional.hpp
FORMS += $$PWD/filewizardpage.ui \
diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs
index 559129df16..6d68683fdd 100644
--- a/src/libs/utils/utils.qbs
+++ b/src/libs/utils/utils.qbs
@@ -175,6 +175,7 @@ Project {
"proxycredentialsdialog.cpp",
"proxycredentialsdialog.h",
"proxycredentialsdialog.ui",
+ "qtcfallthrough.h",
"qtcassert.cpp",
"qtcassert.h",
"qtcolorbutton.cpp",
diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp
index 5ff5b1aa7e..cfb52f1528 100644
--- a/src/plugins/clangcodemodel/clangbackendipcintegration.cpp
+++ b/src/plugins/clangcodemodel/clangbackendipcintegration.cpp
@@ -99,7 +99,7 @@ IpcReceiver::IpcReceiver()
IpcReceiver::~IpcReceiver()
{
- deleteAndClearWaitingAssistProcessors();
+ reset();
}
void IpcReceiver::setAliveHandler(const IpcReceiver::AliveHandler &handler)
@@ -116,12 +116,6 @@ void IpcReceiver::addExpectedCodeCompletedMessage(
m_assistProcessorsTable.insert(ticket, processor);
}
-void IpcReceiver::deleteAndClearWaitingAssistProcessors()
-{
- qDeleteAll(m_assistProcessorsTable.begin(), m_assistProcessorsTable.end());
- m_assistProcessorsTable.clear();
-}
-
void IpcReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget)
{
QMutableHashIterator<quint64, ClangCompletionAssistProcessor *> it(m_assistProcessorsTable);
@@ -155,6 +149,18 @@ bool IpcReceiver::isExpectingCodeCompletedMessage() const
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()
{
if (printAliveMessage())
@@ -719,7 +725,7 @@ void IpcCommunicator::onConnectedToBackend()
if (m_connectedCount > 1)
logRestartedDueToUnexpectedFinish();
- m_ipcReceiver.deleteAndClearWaitingAssistProcessors();
+ m_ipcReceiver.reset();
m_ipcSender.reset(new IpcSender(m_connection));
initializeBackendWithCurrentData();
diff --git a/src/plugins/clangcodemodel/clangbackendipcintegration.h b/src/plugins/clangcodemodel/clangbackendipcintegration.h
index 57a07e8097..e98565f48c 100644
--- a/src/plugins/clangcodemodel/clangbackendipcintegration.h
+++ b/src/plugins/clangcodemodel/clangbackendipcintegration.h
@@ -73,14 +73,14 @@ public:
void setAliveHandler(const AliveHandler &handler);
void addExpectedCodeCompletedMessage(quint64 ticket, ClangCompletionAssistProcessor *processor);
- void deleteAndClearWaitingAssistProcessors();
void deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidget *textEditorWidget);
QFuture<CppTools::CursorInfo> addExpectedReferencesMessage(quint64 ticket,
QTextDocument *textDocument);
-
bool isExpectingCodeCompletedMessage() const;
+ void reset();
+
private:
void alive() override;
void echo(const ClangBackEnd::EchoMessage &message) override;
diff --git a/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp b/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp
index c8da6e6c6a..1dd003c7c1 100644
--- a/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp
+++ b/src/plugins/clangcodemodel/clangdiagnosticmanager.cpp
@@ -278,6 +278,8 @@ namespace Internal {
ClangDiagnosticManager::ClangDiagnosticManager(TextEditor::TextDocument *textDocument)
: m_textDocument(textDocument)
{
+ m_textMarkDelay.setInterval(1500);
+ m_textMarkDelay.setSingleShot(true);
}
ClangDiagnosticManager::~ClangDiagnosticManager()
@@ -295,6 +297,7 @@ void ClangDiagnosticManager::cleanMarks()
}
void ClangDiagnosticManager::generateTextMarks()
{
+ QObject::disconnect(&m_textMarkDelay, &QTimer::timeout, 0, 0);
cleanMarks();
m_clangTextMarks.reserve(m_warningDiagnostics.size() + m_errorDiagnostics.size());
addClangTextMarks(m_warningDiagnostics);
@@ -350,6 +353,7 @@ ClangDiagnosticManager::diagnosticsAt(uint line, uint column) const
void ClangDiagnosticManager::invalidateDiagnostics()
{
+ m_textMarkDelay.start();
if (m_diagnosticsInvalidated)
return;
@@ -383,9 +387,18 @@ void ClangDiagnosticManager::processNewDiagnostics(
m_showTextMarkAnnotations = showTextMarkAnnotations;
filterDiagnostics(allDiagnostics);
- generateTextMarks();
generateEditorSelections();
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> &
diff --git a/src/plugins/clangcodemodel/clangdiagnosticmanager.h b/src/plugins/clangcodemodel/clangdiagnosticmanager.h
index 16b1c16d2d..1321702c99 100644
--- a/src/plugins/clangcodemodel/clangdiagnosticmanager.h
+++ b/src/plugins/clangcodemodel/clangdiagnosticmanager.h
@@ -34,6 +34,7 @@
#include <QList>
#include <QSet>
#include <QTextEdit>
+#include <QTimer>
#include <QVector>
#include <vector>
@@ -82,8 +83,10 @@ private:
QList<QTextEdit::ExtraSelection> m_extraSelections;
TextEditor::RefactorMarkers m_fixItAvailableMarkers;
std::vector<ClangTextMark *> m_clangTextMarks;
+ bool m_firstDiagnostics = true;
bool m_diagnosticsInvalidated = false;
bool m_showTextMarkAnnotations = false;
+ QTimer m_textMarkDelay;
};
} // namespace Internal
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp
index f10b2784bb..e18b9747b8 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerplugin.cpp
@@ -143,7 +143,7 @@ bool ClangStaticAnalyzerPlugin::initialize(const QStringList &arguments, QString
};
RunControl::registerWorker<ClangStaticAnalyzerToolRunner>
- (Constants::CLANGSTATICANALYZER_RUN_MODE, constraint);
+ (Constants::CLANGSTATICANALYZER_RUN_MODE, constraint, /*priority*/ -1);
return true;
}
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
index 612a35c52e..98a0788ebc 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.cpp
@@ -79,7 +79,9 @@ ClangStaticAnalyzerToolRunner::ClangStaticAnalyzerToolRunner(RunControl *runCont
RunConfiguration *runConfiguration = runControl->runConfiguration();
auto tool = ClangStaticAnalyzerTool::instance();
+ tool->stopAction()->disconnect();
connect(tool->stopAction(), &QAction::triggered, runControl, &RunControl::initiateStop);
+ tool->handleWorkerStart(this);
ProjectInfo projectInfoBeforeBuild = tool->projectInfoBeforeBuild();
QTC_ASSERT(projectInfoBeforeBuild.isValid(), return);
@@ -495,10 +497,14 @@ void ClangStaticAnalyzerToolRunner::start()
m_success = false;
ClangStaticAnalyzerTool::instance()->onEngineIsStarting();
+ connect(runControl(), &RunControl::stopped, this, [this] {
+ ClangStaticAnalyzerTool::instance()->onEngineFinished(m_success);
+ });
+
QTC_ASSERT(m_projectInfo.isValid(), reportFailure(); return);
const Utils::FileName projectFile = m_projectInfo.project()->projectFilePath();
- appendMessage(tr("Running Clang Static Analyzer on %1").arg(projectFile.toUserOutput())
- + QLatin1Char('\n'), Utils::NormalMessageFormat);
+ appendMessage(tr("Running Clang Static Analyzer on %1").arg(projectFile.toUserOutput()),
+ Utils::NormalMessageFormat);
// Check clang executable
bool isValidClangExecutable;
@@ -507,7 +513,7 @@ void ClangStaticAnalyzerToolRunner::start()
if (!isValidClangExecutable) {
const QString errorMessage = tr("Clang Static Analyzer: Invalid executable \"%1\", stop.")
.arg(executable);
- appendMessage(errorMessage + QLatin1Char('\n'), Utils::ErrorMessageFormat);
+ appendMessage(errorMessage, Utils::ErrorMessageFormat);
TaskHub::addTask(Task::Error, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup();
reportFailure();
@@ -522,7 +528,7 @@ void ClangStaticAnalyzerToolRunner::start()
= tr("Clang Static Analyzer: Running with possibly unsupported version, "
"could not determine version from executable \"%1\".")
.arg(versionCheckExecutable);
- appendMessage(warningMessage + QLatin1Char('\n'), Utils::StdErrFormat);
+ appendMessage(warningMessage, Utils::StdErrFormat);
TaskHub::addTask(Task::Warning, warningMessage, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup();
} else if (!version.isSupportedVersion()) {
@@ -531,7 +537,7 @@ void ClangStaticAnalyzerToolRunner::start()
"supported version is %2.")
.arg(version.toString())
.arg(ClangExecutableVersion::supportedVersionAsString());
- appendMessage(warningMessage + QLatin1Char('\n'), Utils::StdErrFormat);
+ appendMessage(warningMessage, Utils::StdErrFormat);
TaskHub::addTask(Task::Warning, warningMessage, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::requestPopup();
}
@@ -544,7 +550,7 @@ void ClangStaticAnalyzerToolRunner::start()
if (!temporaryDir.isValid()) {
const QString errorMessage
= 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::requestPopup();
reportFailure(errorMessage);
@@ -599,15 +605,11 @@ void ClangStaticAnalyzerToolRunner::stop()
}
m_runners.clear();
m_unitsToProcess.clear();
- appendMessage(tr("Clang Static Analyzer stopped by user.") + QLatin1Char('\n'),
+ appendMessage(tr("Clang Static Analyzer stopped by user."),
Utils::NormalMessageFormat);
m_progress.reportFinished();
- reportStopped();
-}
-
-void ClangStaticAnalyzerToolRunner::onFinished()
-{
ClangStaticAnalyzerTool::instance()->onEngineFinished(m_success);
+ reportStopped();
}
void ClangStaticAnalyzerToolRunner::analyzeNextFile()
@@ -629,7 +631,7 @@ void ClangStaticAnalyzerToolRunner::analyzeNextFile()
QTC_ASSERT(runner->run(unit.file, unit.arguments), return);
appendMessage(tr("Analyzing \"%1\".").arg(
- Utils::FileName::fromString(unit.file).toUserOutput()) + QLatin1Char('\n'),
+ Utils::FileName::fromString(unit.file).toUserOutput()),
Utils::StdOutFormat);
}
@@ -658,9 +660,8 @@ void ClangStaticAnalyzerToolRunner::onRunnerFinishedWithSuccess(const QString &l
if (!errorMessage.isEmpty()) {
qCDebug(LOG) << "onRunnerFinishedWithSuccess: Error reading log file:" << errorMessage;
const QString filePath = qobject_cast<ClangStaticAnalyzerRunner *>(sender())->filePath();
- appendMessage(tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage)
- + QLatin1Char('\n')
- , Utils::StdErrFormat);
+ appendMessage(tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage),
+ Utils::StdErrFormat);
} else {
++m_filesAnalyzed;
if (!diagnostics.isEmpty())
@@ -679,9 +680,8 @@ void ClangStaticAnalyzerToolRunner::onRunnerFinishedWithFailure(const QString &e
++m_filesNotAnalyzed;
m_success = false;
const QString filePath = qobject_cast<ClangStaticAnalyzerRunner *>(sender())->filePath();
- appendMessage(tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage)
- + QLatin1Char('\n')
- , Utils::StdErrFormat);
+ appendMessage(tr("Failed to analyze \"%1\": %2").arg(filePath, errorMessage),
+ Utils::StdErrFormat);
appendMessage(errorDetails, Utils::StdErrFormat);
TaskHub::addTask(Task::Warning, errorMessage, Debugger::Constants::ANALYZERTASK_ID);
TaskHub::addTask(Task::Warning, errorDetails, Debugger::Constants::ANALYZERTASK_ID);
@@ -699,7 +699,7 @@ void ClangStaticAnalyzerToolRunner::handleFinished()
void ClangStaticAnalyzerToolRunner::onProgressCanceled()
{
m_progress.reportCanceled();
- stop();
+ runControl()->initiateStop();
}
void ClangStaticAnalyzerToolRunner::updateProgressValue()
@@ -711,9 +711,7 @@ void ClangStaticAnalyzerToolRunner::finalize()
{
appendMessage(tr("Clang Static Analyzer finished: "
"Processed %1 files successfully, %2 failed.")
- .arg(m_filesAnalyzed)
- .arg(m_filesNotAnalyzed)
- + QLatin1Char('\n'),
+ .arg(m_filesAnalyzed).arg(m_filesNotAnalyzed),
Utils::NormalMessageFormat);
if (m_filesNotAnalyzed != 0) {
@@ -723,7 +721,7 @@ void ClangStaticAnalyzerToolRunner::finalize()
}
m_progress.reportFinished();
- reportStopped();
+ runControl()->initiateStop();
}
} // namespace Internal
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h
index 9719c42116..e75660287f 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerruncontrol.h
@@ -56,7 +56,6 @@ public:
void start() override;
void stop() override;
- void onFinished() override;
bool success() const { return m_success; } // For testing.
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
index c8f1f6c8ba..461f31049b 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
@@ -145,7 +145,6 @@ ClangStaticAnalyzerTool::ClangStaticAnalyzerTool()
{{ClangStaticAnalyzerDockId, m_diagnosticView, {}, Perspective::SplitVertical}}
));
- //Debugger::registerAction(Constants::CLANGSTATICANALYZER_RUN_MODE, {});
action = new QAction(tr("Clang Static Analyzer"), this);
action->setToolTip(toolTip);
menu->addAction(ActionManager::registerAction(action, "ClangStaticAnalyzer.Action"),
@@ -211,14 +210,12 @@ static bool dontStartAfterHintForDebugMode(Project *project)
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);
- if (dontStartAfterHintForDebugMode(project))
- return;
-
Debugger::selectPerspective(ClangStaticAnalyzerPerspectiveId);
m_diagnosticModel->clear();
setBusyCursor(true);
@@ -230,8 +227,13 @@ void ClangStaticAnalyzerTool::startTool()
m_toolBusy = true;
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);
DummyRunConfiguration *& rc = m_runConfigs[target];
if (!rc) {
@@ -245,6 +247,9 @@ void ClangStaticAnalyzerTool::startTool()
connect(SessionManager::instance(), &SessionManager::aboutToRemoveProject, this,
onProjectRemoved, Qt::UniqueConnection);
}
+ if (dontStartAfterHintForDebugMode(project))
+ return;
+
ProjectExplorerPlugin::runRunConfiguration(rc, Constants::CLANGSTATICANALYZER_RUN_MODE);
}
diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.h b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.h
index b3f05843d6..06550bce31 100644
--- a/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.h
+++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzertool.h
@@ -58,9 +58,10 @@ public:
// For testing.
QList<Diagnostic> diagnostics() const;
-
void startTool();
+ void handleWorkerStart(ProjectExplorer::RunWorker *runWorker);
+
void onEngineIsStarting();
void onNewDiagnosticsAvailable(const QList<Diagnostic> &diagnostics);
void onEngineFinished(bool success);
diff --git a/src/plugins/coreplugin/dialogs/newdialog.cpp b/src/plugins/coreplugin/dialogs/newdialog.cpp
index f38a43e73b..80f8eb8d4d 100644
--- a/src/plugins/coreplugin/dialogs/newdialog.cpp
+++ b/src/plugins/coreplugin/dialogs/newdialog.cpp
@@ -79,7 +79,7 @@ public:
invalidateFilter();
}
- bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
+ bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
{
if (!sourceParent.isValid())
return true;
@@ -91,6 +91,21 @@ public:
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:
Core::Id m_platform;
};
@@ -101,18 +116,18 @@ class TwoLevelProxyModel : public QAbstractProxyModel
public:
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));
return createIndex(row, column, ourModelIndex.internalPointer());
}
- QModelIndex parent(const QModelIndex &index) const
+ QModelIndex parent(const QModelIndex &index) const override
{
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())
return 0;
@@ -120,19 +135,19 @@ public:
return sourceModel()->rowCount(mapToSource(index));
}
- int columnCount(const QModelIndex &index) const
+ int columnCount(const QModelIndex &index) const override
{
return sourceModel()->columnCount(mapToSource(index));
}
- QModelIndex mapFromSource (const QModelIndex &index) const
+ QModelIndex mapFromSource (const QModelIndex &index) const override
{
if (!index.isValid())
return QModelIndex();
return createIndex(index.row(), index.column(), index.internalPointer());
}
- QModelIndex mapToSource (const QModelIndex &index) const
+ QModelIndex mapToSource (const QModelIndex &index) const override
{
if (!index.isValid())
return QModelIndex();
@@ -148,7 +163,7 @@ public:
FancyTopLevelDelegate(QObject *parent = 0)
: 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;
if (!(option.state & QStyle::State_Enabled)) {
@@ -168,11 +183,10 @@ public:
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);
-
size = size.expandedTo(QSize(0, ROW_HEIGHT));
return size;
diff --git a/src/plugins/coreplugin/locator/locatorwidget.cpp b/src/plugins/coreplugin/locator/locatorwidget.cpp
index 76f0ac1f5b..5073bcd33c 100644
--- a/src/plugins/coreplugin/locator/locatorwidget.cpp
+++ b/src/plugins/coreplugin/locator/locatorwidget.cpp
@@ -483,6 +483,16 @@ void CompletionList::keyPressEvent(QKeyEvent *event)
return;
}
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);
}
@@ -795,9 +805,9 @@ void LocatorWidget::handleSearchFinished()
m_showProgressTimer.stop();
setProgressIndicatorVisible(false);
m_updateRequested = false;
- if (m_rowRequestedForAccept >= 0) {
- acceptEntry(m_rowRequestedForAccept);
- m_rowRequestedForAccept = -1;
+ if (m_rowRequestedForAccept) {
+ acceptEntry(m_rowRequestedForAccept.value());
+ m_rowRequestedForAccept.reset();
return;
}
if (m_entriesWatcher->future().isCanceled()) {
@@ -892,7 +902,7 @@ void LocatorWidget::addSearchResults(int firstIndex, int endIndex)
m_locatorModel->addEntries(entries);
if (selectFirst) {
emit selectRow(0);
- if (m_rowRequestedForAccept >= 0)
+ if (m_rowRequestedForAccept)
m_rowRequestedForAccept = 0;
}
}
diff --git a/src/plugins/coreplugin/locator/locatorwidget.h b/src/plugins/coreplugin/locator/locatorwidget.h
index 4484faefdd..c4ce3c4a14 100644
--- a/src/plugins/coreplugin/locator/locatorwidget.h
+++ b/src/plugins/coreplugin/locator/locatorwidget.h
@@ -27,6 +27,8 @@
#include "locator.h"
+#include <utils/optional.h>
+
#include <QPointer>
#include <QWidget>
@@ -99,9 +101,9 @@ private:
bool m_needsClearResult = true;
bool m_updateRequested = false;
bool m_possibleToolTipRequest = false;
- int m_rowRequestedForAccept = -1;
QWidget *m_progressIndicator;
QTimer m_showProgressTimer;
+ Utils::optional<int> m_rowRequestedForAccept;
};
class LocatorPopup : public QWidget
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index 677cd1ebc3..65d0c42abf 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -245,13 +245,19 @@ void CppEditorWidget::finalizeInitialization()
});
// Toolbar: '#' Button
- d->m_preprocessorButton = new QToolButton(this);
- d->m_preprocessorButton->setText(QLatin1String("#"));
- Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
- connect(cmd, &Command::keySequenceChanged, this, &CppEditorWidget::updatePreprocessorButtonTooltip);
- updatePreprocessorButtonTooltip();
- connect(d->m_preprocessorButton, &QAbstractButton::clicked, this, &CppEditorWidget::showPreProcessorWidget);
- insertExtraToolBarWidget(TextEditorWidget::Left, d->m_preprocessorButton);
+ // TODO: Make "Additional Preprocessor Directives" also useful with Clang Code Model.
+ if (!d->m_modelManager->isClangCodeModelActive()) {
+ d->m_preprocessorButton = new QToolButton(this);
+ d->m_preprocessorButton->setText(QLatin1String("#"));
+ Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
+ connect(cmd, &Command::keySequenceChanged,
+ 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
d->m_showInfoBarActions = MinimizableInfoBars::createShowInfoBarActions([this](QWidget *w) {
@@ -429,13 +435,16 @@ bool CppEditorWidget::selectBlockDown()
void CppEditorWidget::updateWidgetHighlighting(QWidget *widget, bool highlight)
{
+ if (!widget)
+ return;
+
widget->setProperty("highlightWidget", highlight);
widget->update();
}
bool CppEditorWidget::isWidgetHighlighted(QWidget *widget)
{
- return widget->property("highlightWidget").toBool();
+ return widget ? widget->property("highlightWidget").toBool() : false;
}
void CppEditorWidget::renameSymbolUnderCursor()
@@ -586,7 +595,9 @@ void CppEditorWidget::renameSymbolUnderCursorClang()
void CppEditorWidget::updatePreprocessorButtonTooltip()
{
- QTC_ASSERT(d->m_preprocessorButton, return);
+ if (!d->m_preprocessorButton)
+ return;
+
Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
QTC_ASSERT(cmd, return);
d->m_preprocessorButton->setToolTip(cmd->action()->toolTip());
diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp
index c5a9d40e2e..d31a4eb899 100644
--- a/src/plugins/cppeditor/cppeditordocument.cpp
+++ b/src/plugins/cppeditor/cppeditordocument.cpp
@@ -201,12 +201,17 @@ void CppEditorDocument::onAboutToReload()
{
QTC_CHECK(!m_fileIsBeingReloaded);
m_fileIsBeingReloaded = true;
+
+ processor()->invalidateDiagnostics();
}
void CppEditorDocument::onReloadFinished()
{
QTC_CHECK(m_fileIsBeingReloaded);
m_fileIsBeingReloaded = false;
+
+ m_processorRevision = document()->revision();
+ processDocument();
}
void CppEditorDocument::reparseWithPreferredParseContext(const QString &parseContextId)
@@ -250,6 +255,9 @@ void CppEditorDocument::onFilePathChanged(const Utils::FileName &oldPath,
void CppEditorDocument::scheduleProcessDocument()
{
+ if (m_fileIsBeingReloaded)
+ return;
+
m_processorRevision = document()->revision();
m_processorTimer.start();
processor()->editorDocumentTimerRestarted();
diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp
index 67d360c3bb..640fa794ef 100644
--- a/src/plugins/cppeditor/cppquickfixes.cpp
+++ b/src/plugins/cppeditor/cppquickfixes.cpp
@@ -56,6 +56,7 @@
#include <utils/fancylineedit.h>
#include <utils/qtcassert.h>
+#include <utils/qtcfallthrough.h>
#include <QApplication>
#include <QComboBox>
@@ -4119,7 +4120,7 @@ public:
break;
case FromReference:
removeReferenceOperator(changes);
- // fallthrough intended
+ Q_FALLTHROUGH();
case FromVariable:
convertToPointer(changes);
break;
diff --git a/src/plugins/cppeditor/cppuseselectionsupdater.cpp b/src/plugins/cppeditor/cppuseselectionsupdater.cpp
index 5e03ebbe2d..81e1436ccd 100644
--- a/src/plugins/cppeditor/cppuseselectionsupdater.cpp
+++ b/src/plugins/cppeditor/cppuseselectionsupdater.cpp
@@ -98,8 +98,12 @@ void CppUseSelectionsUpdater::update(CallType callType)
// QFuture::waitForFinished seems to block completely, not even
// allowing to process events from QLocalSocket.
- while (!future.isFinished())
+ while (!future.isFinished()) {
+ if (future.isCanceled())
+ return;
+
QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+ }
processResults(future.result());
}
diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp
index 8f5fd397fb..170279c9b8 100644
--- a/src/plugins/cpptools/compileroptionsbuilder.cpp
+++ b/src/plugins/cpptools/compileroptionsbuilder.cpp
@@ -26,6 +26,7 @@
#include "compileroptionsbuilder.h"
#include <projectexplorer/projectexplorerconstants.h>
+#include <utils/qtcfallthrough.h>
#include <QDir>
#include <QRegularExpression>
@@ -201,7 +202,8 @@ static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objc
if (!objcExt) {
opts += QLatin1String("c++-header");
break;
- } // else: fall-through!
+ }
+ Q_FALLTHROUGH();
case ProjectFile::ObjCHeader:
case ProjectFile::ObjCXXHeader:
opts += QLatin1String("objective-c++-header");
@@ -211,7 +213,8 @@ static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objc
if (!objcExt) {
opts += QLatin1String("c");
break;
- } // else: fall-through!
+ }
+ Q_FALLTHROUGH();
case ProjectFile::ObjCSource:
opts += QLatin1String("objective-c");
break;
@@ -220,7 +223,8 @@ static QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objc
if (!objcExt) {
opts += QLatin1String("c++");
break;
- } // else: fall-through!
+ }
+ Q_FALLTHROUGH();
case ProjectFile::ObjCXXSource:
opts += QLatin1String("objective-c++");
break;
diff --git a/src/plugins/debugger/debuggerdialogs.cpp b/src/plugins/debugger/debuggerdialogs.cpp
index c247c22a43..f9017a7f41 100644
--- a/src/plugins/debugger/debuggerdialogs.cpp
+++ b/src/plugins/debugger/debuggerdialogs.cpp
@@ -71,8 +71,8 @@ class StartApplicationDialogPrivate
public:
KitChooser *kitChooser;
QLabel *serverPortLabel;
- QLabel *serverAddressLabel;
- QLineEdit *serverAddressEdit;
+ QLabel *channelOverrideLabel;
+ QLineEdit *channelOverrideEdit;
QSpinBox *serverPortSpinBox;
PathChooser *localExecutablePathChooser;
FancyLineEdit *arguments;
@@ -235,8 +235,11 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent)
d->serverPortSpinBox = new QSpinBox(this);
d->serverPortSpinBox->setRange(1, 65535);
- d->serverAddressLabel = new QLabel(tr("Override server address"), this);
- d->serverAddressEdit = new QLineEdit(this);
+ d->channelOverrideLabel = new QLabel(tr("Override server channel:"), 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->setExpectedKind(PathChooser::File);
@@ -292,7 +295,6 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent)
formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
formLayout->addRow(tr("&Kit:"), d->kitChooser);
formLayout->addRow(d->serverPortLabel, d->serverPortSpinBox);
- formLayout->addRow(d->serverAddressLabel, d->serverAddressEdit);
formLayout->addRow(tr("Local &executable:"), d->localExecutablePathChooser);
formLayout->addRow(tr("Command line &arguments:"), d->arguments);
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(d->serverStartScriptLabel, d->serverStartScriptPathChooser);
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(tr("&Recent:"), d->historyComboBox);
@@ -316,6 +323,9 @@ StartApplicationDialog::StartApplicationDialog(QWidget *parent)
connect(d->historyComboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &StartApplicationDialog::historyIndexChanged);
+ connect(d->channelOverrideEdit, &QLineEdit::textChanged,
+ this, &StartApplicationDialog::onChannelOverrideChanged);
+
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)
{
if (index < 0)
@@ -379,8 +395,8 @@ bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp, Kit
dialog.d->serverStartScriptLabel->setVisible(false);
dialog.d->serverPortSpinBox->setVisible(false);
dialog.d->serverPortLabel->setVisible(false);
- dialog.d->serverAddressLabel->setVisible(false);
- dialog.d->serverAddressEdit->setVisible(false);
+ dialog.d->channelOverrideLabel->setVisible(false);
+ dialog.d->channelOverrideEdit->setVisible(false);
}
if (dialog.exec() != QDialog::Accepted)
return false;
@@ -404,7 +420,7 @@ bool StartApplicationDialog::run(QWidget *parent, DebuggerRunParameters *rp, Kit
}
rp->inferior.executable = newParameters.runnable.executable;
- const QString inputAddress = dialog.d->serverAddressEdit->text();
+ const QString inputAddress = dialog.d->channelOverrideEdit->text();
if (!inputAddress.isEmpty())
rp->remoteChannel = inputAddress;
else
@@ -430,7 +446,7 @@ StartApplicationParameters StartApplicationDialog::parameters() const
{
StartApplicationParameters result;
result.serverPort = d->serverPortSpinBox->value();
- result.serverAddress = d->serverAddressEdit->text();
+ result.serverAddress = d->channelOverrideEdit->text();
result.runnable.executable = d->localExecutablePathChooser->path();
result.serverStartScript = d->serverStartScriptPathChooser->path();
result.kitId = d->kitChooser->currentKitId();
@@ -447,7 +463,7 @@ void StartApplicationDialog::setParameters(const StartApplicationParameters &p)
{
d->kitChooser->setCurrentKitId(p.kitId);
d->serverPortSpinBox->setValue(p.serverPort);
- d->serverAddressEdit->setText(p.serverAddress);
+ d->channelOverrideEdit->setText(p.serverAddress);
d->localExecutablePathChooser->setPath(p.runnable.executable);
d->serverStartScriptPathChooser->setPath(p.serverStartScript);
d->debuginfoPathChooser->setPath(p.debugInfoLocation);
diff --git a/src/plugins/debugger/debuggerdialogs.h b/src/plugins/debugger/debuggerdialogs.h
index 60cdedefeb..b291dbbe26 100644
--- a/src/plugins/debugger/debuggerdialogs.h
+++ b/src/plugins/debugger/debuggerdialogs.h
@@ -80,6 +80,7 @@ private:
StartApplicationParameters parameters() const;
void setParameters(const StartApplicationParameters &p);
void setHistory(const QList<StartApplicationParameters> &l);
+ void onChannelOverrideChanged(const QString &channel);
StartApplicationDialogPrivate *d;
};
diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp
index e60af1faa8..efc1680458 100644
--- a/src/plugins/debugger/debuggerengine.cpp
+++ b/src/plugins/debugger/debuggerengine.cpp
@@ -292,12 +292,6 @@ public:
}
}
- void raiseApplication()
- {
- QTC_ASSERT(runControl(), return);
- runControl()->bringApplicationToForeground();
- }
-
void scheduleResetLocation()
{
m_stackHandler.scheduleResetLocation();
@@ -1323,7 +1317,7 @@ void DebuggerEngine::notifyInferiorPid(const ProcessHandle &pid)
showMessage(tr("Taking notice of pid %1").arg(pid.pid()));
DebuggerStartMode sm = runParameters().startMode;
if (sm == StartInternal || sm == StartExternal || sm == AttachExternal)
- QTimer::singleShot(0, d, &DebuggerEnginePrivate::raiseApplication);
+ d->m_inferiorPid.activate();
}
}
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index 832a343540..38d867c878 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -421,18 +421,6 @@ namespace Internal {
void addCdbOptionPages(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)
{
if (id == Id(Constants::DEBUG)) {
@@ -1495,7 +1483,7 @@ bool DebuggerPluginPrivate::initialize(const QStringList &arguments,
m_localsAndExpressionsWindow->setObjectName(QLatin1String(DOCKWIDGET_WATCHERS));
m_localsAndExpressionsWindow->setWindowTitle(m_localsWindow->windowTitle());
- m_plugin->addAutoReleasedObject(new DebuggerRunControlFactory);
+ RunConfiguration::registerAspect<DebuggerRunConfigurationAspect>();
// The main "Start Debugging" action.
act = m_startAction = new QAction(this);
diff --git a/src/plugins/debugger/gdb/attachgdbadapter.cpp b/src/plugins/debugger/gdb/attachgdbadapter.cpp
index 11566a51be..519647d703 100644
--- a/src/plugins/debugger/gdb/attachgdbadapter.cpp
+++ b/src/plugins/debugger/gdb/attachgdbadapter.cpp
@@ -31,6 +31,7 @@
#include <debugger/debuggerstartparameters.h>
#include <utils/qtcassert.h>
+#include <utils/qtcfallthrough.h>
namespace Debugger {
namespace Internal {
@@ -102,7 +103,7 @@ void GdbAttachEngine::handleAttach(const DebuggerResponse &response)
notifyEngineIll();
break;
}
- // if msg != "ptrace: ..." fall through
+ Q_FALLTHROUGH(); // if msg != "ptrace: ..."
default:
showStatusMessage(tr("Failed to attach to application: %1")
.arg(QString(response.data["msg"].data())));
diff --git a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
index a36aa11bef..cf55a82dc6 100644
--- a/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
+++ b/src/plugins/debugger/gdb/remotegdbserveradapter.cpp
@@ -34,6 +34,7 @@
#include <coreplugin/messagebox.h>
#include <utils/hostosinfo.h>
+#include <utils/qtcfallthrough.h>
#include <utils/qtcassert.h>
#include <utils/qtcprocess.h>
@@ -367,7 +368,7 @@ void GdbRemoteServerEngine::handleAttach(const DebuggerResponse &response)
notifyInferiorSetupFailed(msgPtraceError(runParameters().startMode));
break;
}
- // if msg != "ptrace: ..." fall through
+ Q_FALLTHROUGH(); // if msg != "ptrace: ..."
default:
notifyInferiorSetupFailed(response.data["msg"].data());
}
diff --git a/src/plugins/debugger/moduleshandler.cpp b/src/plugins/debugger/moduleshandler.cpp
index 94d558851a..e37c44ccbb 100644
--- a/src/plugins/debugger/moduleshandler.cpp
+++ b/src/plugins/debugger/moduleshandler.cpp
@@ -327,7 +327,8 @@ void ModulesHandler::endUpdateAll()
if (!item->updated)
toDestroy.append(item);
});
- qDeleteAll(toDestroy);
+ for (TreeItem *item : toDestroy)
+ m_model->destroyItem(item);
}
} // namespace Internal
diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp
index 87b4a039d0..10e6d4f3b2 100644
--- a/src/plugins/debugger/qml/qmlengine.cpp
+++ b/src/plugins/debugger/qml/qmlengine.cpp
@@ -60,6 +60,7 @@
#include <utils/treemodel.h>
#include <utils/basetreeview.h>
#include <utils/qtcassert.h>
+#include <utils/qtcfallthrough.h>
#include <QDebug>
#include <QDir>
@@ -376,7 +377,7 @@ void QmlEngine::handleLauncherStarted()
{
// FIXME: The QmlEngine never calls notifyInferiorPid() triggering the
// raising, so do it here manually for now.
- runControl()->bringApplicationToForeground();
+ runControl()->applicationProcessHandle().activate();
d->noDebugOutputTimer.start();
}
@@ -505,7 +506,7 @@ void QmlEngine::errorMessageBoxFinished(int result)
}
case QMessageBox::Help: {
HelpManager::handleHelpRequest("qthelp://org.qt-project.qtcreator/doc/creator-debugging-qml.html");
- // fall through
+ Q_FALLTHROUGH();
}
default:
if (state() == InferiorRunOk) {
diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp
index f6e8dfeb45..2275807d22 100644
--- a/src/plugins/debugger/watchutils.cpp
+++ b/src/plugins/debugger/watchutils.cpp
@@ -29,6 +29,8 @@
#include "watchutils.h"
#include "watchdata.h"
+#include <utils/qtcfallthrough.h>
+
#include <QDebug>
#include <string.h>
@@ -231,8 +233,10 @@ QString formatToolTipAddress(quint64 a)
switch (rc.size()) {
case 16:
rc.insert(12, colon);
+ Q_FALLTHROUGH();
case 12:
rc.insert(8, colon);
+ Q_FALLTHROUGH();
case 8:
rc.insert(4, colon);
}
diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp
index 232c2addaa..6391c0ae0a 100644
--- a/src/plugins/diffeditor/diffeditorplugin.cpp
+++ b/src/plugins/diffeditor/diffeditorplugin.cpp
@@ -156,10 +156,12 @@ void DiffFilesController::reload()
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);
- reloadFinished(true);
+ reloadFinished(success);
}
void DiffFilesController::cancelReload()
diff --git a/src/plugins/ios/iosplugin.cpp b/src/plugins/ios/iosplugin.cpp
index 28e590167e..b2b33d8ae3 100644
--- a/src/plugins/ios/iosplugin.cpp
+++ b/src/plugins/ios/iosplugin.cpp
@@ -36,17 +36,22 @@
#include "iosdsymbuildstep.h"
#include "iosqtversionfactory.h"
#include "iosrunfactories.h"
+#include "iosrunner.h"
#include "iossettingspage.h"
#include "iossimulator.h"
#include "iossimulatorfactory.h"
#include "iostoolhandler.h"
+#include "iosrunconfiguration.h"
+#include <projectexplorer/devicesupport/devicemanager.h>
#include <projectexplorer/kitmanager.h>
+#include <projectexplorer/runconfiguration.h>
+
#include <qtsupport/qtversionmanager.h>
#include <QtPlugin>
-#include <projectexplorer/devicesupport/devicemanager.h>
+using namespace ProjectExplorer;
namespace Ios {
namespace Internal {
@@ -67,7 +72,6 @@ bool IosPlugin::initialize(const QStringList &arguments, QString *errorMessage)
addAutoReleasedObject(new Internal::IosBuildConfigurationFactory);
addAutoReleasedObject(new Internal::IosToolChainFactory);
- addAutoReleasedObject(new Internal::IosRunControlFactory);
addAutoReleasedObject(new Internal::IosRunConfigurationFactory);
addAutoReleasedObject(new Internal::IosSettingsPage);
addAutoReleasedObject(new Internal::IosQtVersionFactory);
@@ -78,6 +82,17 @@ bool IosPlugin::initialize(const QStringList &arguments, QString *errorMessage)
addAutoReleasedObject(new Internal::IosDsymBuildStepFactory);
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;
}
diff --git a/src/plugins/ios/iosrunfactories.cpp b/src/plugins/ios/iosrunfactories.cpp
index b2d42b671b..c41dcb8263 100644
--- a/src/plugins/ios/iosrunfactories.cpp
+++ b/src/plugins/ios/iosrunfactories.cpp
@@ -27,7 +27,6 @@
#include "iosconstants.h"
#include "iosrunconfiguration.h"
-#include "iosrunner.h"
#include "iosmanager.h"
#include <debugger/analyzer/analyzermanager.h>
@@ -143,53 +142,5 @@ RunConfiguration *IosRunConfigurationFactory::doRestore(Target *parent, const QV
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 Ios
diff --git a/src/plugins/ios/iosrunfactories.h b/src/plugins/ios/iosrunfactories.h
index 8e9b072639..318e57e04e 100644
--- a/src/plugins/ios/iosrunfactories.h
+++ b/src/plugins/ios/iosrunfactories.h
@@ -29,8 +29,6 @@
#include <qmakeprojectmanager/qmakerunconfigurationfactory.h>
namespace ProjectExplorer {
-class RunControl;
-class RunConfigWidget;
class Target;
class Node;
} // namespace ProjectExplorer
@@ -68,20 +66,5 @@ private:
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 Ios
diff --git a/src/plugins/ios/iosrunner.cpp b/src/plugins/ios/iosrunner.cpp
index 23400d34c7..7ecd50b836 100644
--- a/src/plugins/ios/iosrunner.cpp
+++ b/src/plugins/ios/iosrunner.cpp
@@ -74,9 +74,29 @@ using namespace Utils;
namespace Ios {
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)
: RunWorker(runControl)
{
+ stopRunningRunControl(runControl);
auto runConfig = qobject_cast<IosRunConfiguration *>(runControl->runConfiguration());
m_bundleDir = runConfig->bundleDirectory().toString();
m_arguments = QStringList(runConfig->commandLineArguments());
@@ -513,10 +533,5 @@ void IosDebugSupport::start()
DebuggerRunTool::start();
}
-void IosDebugSupport::onFinished()
-{
- abortDebugger();
-}
-
} // namespace Internal
} // namespace Ios
diff --git a/src/plugins/ios/iosrunner.h b/src/plugins/ios/iosrunner.h
index 203ae87909..2db7cf8c0d 100644
--- a/src/plugins/ios/iosrunner.h
+++ b/src/plugins/ios/iosrunner.h
@@ -135,7 +135,6 @@ public:
private:
void start() override;
- void onFinished() override;
const QString m_dumperLib;
IosRunner *m_runner;
diff --git a/src/plugins/ios/iostoolhandler.cpp b/src/plugins/ios/iostoolhandler.cpp
index f2afa71433..317c1f6f59 100644
--- a/src/plugins/ios/iostoolhandler.cpp
+++ b/src/plugins/ios/iostoolhandler.cpp
@@ -33,6 +33,7 @@
#include <coreplugin/icore.h>
#include <utils/qtcassert.h>
#include <utils/fileutils.h>
+#include <utils/qtcfallthrough.h>
#include "utils/runextensions.h"
#include "utils/synchronousprocess.h"
@@ -606,7 +607,7 @@ void IosDeviceToolHandlerPrivate::subprocessHasData()
switch (state) {
case NonStarted:
qCWarning(toolHandlerLog) << "IosToolHandler unexpected state in subprocessHasData: NonStarted";
- // pass
+ Q_FALLTHROUGH();
case Starting:
case StartedInferior:
// read some data
@@ -771,7 +772,7 @@ void IosDeviceToolHandlerPrivate::stop(int errorCode)
switch (oldState) {
case NonStarted:
qCWarning(toolHandlerLog) << "IosToolHandler::stop() when state was NonStarted";
- // pass
+ Q_FALLTHROUGH();
case Starting:
switch (op){
case OpNone:
@@ -786,7 +787,7 @@ void IosDeviceToolHandlerPrivate::stop(int errorCode)
case OpDeviceInfo:
break;
}
- // pass
+ Q_FALLTHROUGH();
case StartedInferior:
case XmlEndProcessed:
toolExited(errorCode);
diff --git a/src/plugins/projectexplorer/appoutputpane.cpp b/src/plugins/projectexplorer/appoutputpane.cpp
index 9e0617454b..1e6ef0efd6 100644
--- a/src/plugins/projectexplorer/appoutputpane.cpp
+++ b/src/plugins/projectexplorer/appoutputpane.cpp
@@ -420,7 +420,8 @@ void AppOutputPane::createNewOutputWindow(RunControl *rc)
if (tabIndex != -1) {
RunControlTab &tab = m_runControlTabs[tabIndex];
// Reuse this tab
- delete tab.runControl;
+ if (tab.runControl)
+ tab.runControl->initiateFinish();
tab.runControl = rc;
tab.window->setFormatter(rc ? rc->outputFormatter() : nullptr);
@@ -559,7 +560,7 @@ bool AppOutputPane::closeTabs(CloseTabMode mode)
QList<RunControl *> AppOutputPane::allRunControls() const
{
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);
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);
updateCloseActions();
diff --git a/src/plugins/projectexplorer/appoutputpane.h b/src/plugins/projectexplorer/appoutputpane.h
index ba3839ca6a..b260447ba5 100644
--- a/src/plugins/projectexplorer/appoutputpane.h
+++ b/src/plugins/projectexplorer/appoutputpane.h
@@ -25,6 +25,7 @@
#pragma once
+#include <QPointer>
#include <QVector>
#include <coreplugin/ioutputpane.h>
@@ -124,7 +125,7 @@ private:
public:
explicit RunControlTab(RunControl *runControl = nullptr,
Core::OutputWindow *window = nullptr);
- RunControl *runControl;
+ QPointer<RunControl> runControl;
Core::OutputWindow *window;
BehaviorOnOutput behaviorOnOutput = Flash;
};
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index 12c3e5f678..5380acb478 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -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 {};
}
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index 58958c08f2..2ffb0d200d 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -48,7 +48,6 @@ namespace Utils { class ProcessHandle; }
namespace ProjectExplorer {
class RunControl;
class RunConfiguration;
-class IRunControlFactory;
class Project;
class Node;
class FolderNode;
diff --git a/src/plugins/projectexplorer/projecttreewidget.cpp b/src/plugins/projectexplorer/projecttreewidget.cpp
index 372dbdb757..2a98fbe86e 100644
--- a/src/plugins/projectexplorer/projecttreewidget.cpp
+++ b/src/plugins/projectexplorer/projecttreewidget.cpp
@@ -489,5 +489,5 @@ void ProjectTreeWidgetFactory::restoreSettings(QSettings *settings, int position
const QString baseKey = QLatin1String("ProjectTreeWidget.") + QString::number(position);
ptw->setProjectFilter(settings->value(baseKey + QLatin1String(".ProjectFilter"), false).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());
}
diff --git a/src/plugins/projectexplorer/projecttreewidget.h b/src/plugins/projectexplorer/projecttreewidget.h
index 072cc1f1ab..69102fedb0 100644
--- a/src/plugins/projectexplorer/projecttreewidget.h
+++ b/src/plugins/projectexplorer/projecttreewidget.h
@@ -87,7 +87,7 @@ private:
QToolButton *m_toggleSync;
QString m_modelId;
- bool m_autoSync = false;
+ bool m_autoSync = true;
Utils::FileName m_delayedRename;
static QList<ProjectTreeWidget *> m_projectTreeWidgets;
diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp
index d098411706..bc3eaac911 100644
--- a/src/plugins/projectexplorer/runconfiguration.cpp
+++ b/src/plugins/projectexplorer/runconfiguration.cpp
@@ -183,13 +183,16 @@ void IRunConfigurationAspect::resetProjectToGlobalSettings()
for a target, but still be runnable via the output tab.
*/
+static std::vector<RunConfiguration::AspectFactory> theAspectFactories;
+
RunConfiguration::RunConfiguration(Target *target, Core::Id id) :
ProjectConfiguration(target, id)
{
Q_ASSERT(target);
ctor();
- addExtraAspects();
+ for (const AspectFactory &factory : theAspectFactories)
+ addExtraAspect(factory(this));
}
RunConfiguration::RunConfiguration(Target *target, RunConfiguration *source) :
@@ -209,10 +212,9 @@ RunConfiguration::~RunConfiguration()
qDeleteAll(m_aspects);
}
-void RunConfiguration::addExtraAspects()
+void RunConfiguration::addAspectFactory(const AspectFactory &aspectFactory)
{
- foreach (IRunControlFactory *factory, ExtensionSystem::PluginManager::getObjects<IRunControlFactory>())
- addExtraAspect(factory->createRunConfigurationAspect(this));
+ theAspectFactories.push_back(aspectFactory);
}
void RunConfiguration::addExtraAspect(IRunConfigurationAspect *aspect)
@@ -365,7 +367,7 @@ IRunConfigurationAspect *RunConfiguration::extraAspect(Core::Id id) const
A target specific \l RunConfiguration implementation can specify
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
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>;
static WorkerFactories &theWorkerFactories()
@@ -504,50 +483,13 @@ static WorkerFactories &theWorkerFactories()
bool RunControl::WorkerFactory::canRun(RunConfiguration *runConfiguration, Core::Id runMode) const
{
- if (runMode != runMode)
+ if (runMode != this->runMode)
return false;
if (!constraint)
return true;
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
\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 {
enum class RunWorkerState
@@ -592,7 +522,7 @@ static QString stateName(RunWorkerState s)
SN(RunWorkerState::Done)
SN(RunWorkerState::Failed)
}
- return QLatin1String("<unknown>");
+ return QString("<unknown: %1>").arg(int(s));
# undef SN
}
@@ -606,7 +536,7 @@ public:
RunWorker *q;
RunWorkerState state = RunWorkerState::Initialized;
- RunControl *runControl;
+ QPointer<RunControl> runControl;
QList<RunWorker *> dependencies;
QString id;
@@ -625,6 +555,8 @@ enum class RunControlState
Running, // All good and running.
Stopping, // initiateStop() was called, stop application/tool
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)
@@ -636,8 +568,10 @@ static QString stateName(RunControlState s)
SN(RunControlState::Running)
SN(RunControlState::Stopping)
SN(RunControlState::Stopped)
+ SN(RunControlState::Finishing)
+ SN(RunControlState::Finished)
}
- return QLatin1String("<unknown>");
+ return QString("<unknown: %1>").arg(int(s));
# undef SN
}
@@ -659,8 +593,11 @@ public:
~RunControlPrivate()
{
- QTC_CHECK(state == RunControlState::Stopped || state == RunControlState::Initialized);
+ QTC_CHECK(state == RunControlState::Finished || state == RunControlState::Initialized);
+ disconnect();
+ q = nullptr;
qDeleteAll(m_workers);
+ m_workers.clear();
delete outputFormatter;
}
@@ -675,7 +612,7 @@ public:
void initiateReStart();
void continueStart();
void initiateStop();
- void continueStop();
+ void initiateFinish();
void onWorkerStarted(RunWorker *worker);
void onWorkerStopped(RunWorker *worker);
@@ -694,7 +631,7 @@ public:
Utils::Icon icon;
const QPointer<RunConfiguration> runConfiguration; // Not owned.
QPointer<Project> project; // Not owned.
- Utils::OutputFormatter *outputFormatter = nullptr;
+ QPointer<Utils::OutputFormatter> outputFormatter = nullptr;
std::function<bool(bool*)> promptToStop;
std::vector<RunControl::WorkerFactory> m_factories;
@@ -759,6 +696,11 @@ void RunControl::initiateStop()
d->initiateStop();
}
+void RunControl::initiateFinish()
+{
+ d->initiateFinish();
+}
+
using WorkerCreators = QHash<Core::Id, RunControl::WorkerCreator>;
static WorkerCreators &theWorkerCreators()
@@ -789,12 +731,22 @@ RunWorker *RunControl::createWorker(Core::Id id)
RunControl::WorkerCreator RunControl::producer(RunConfiguration *runConfiguration, Core::Id runMode)
{
- for (const auto &factory : theWorkerFactories()) {
- if (factory.runMode == runMode
- && (!factory.constraint || factory.constraint(runConfiguration)))
- return factory.producer;
+ WorkerFactories candidates;
+ for (const RunControl::WorkerFactory &factory : theWorkerFactories()) {
+ if (factory.canRun(runConfiguration, runMode))
+ candidates.push_back(factory);
+ }
+
+ if (candidates.empty())
+ return {};
+
+ RunControl::WorkerFactory bestFactory = *candidates.begin();
+ for (const RunControl::WorkerFactory &factory : candidates) {
+ if (factory.priority > bestFactory.priority)
+ bestFactory = factory;
}
- return {};
+
+ return bestFactory.producer;
}
void RunControl::addWorkerFactory(const RunControl::WorkerFactory &workerFactory)
@@ -880,15 +832,58 @@ void RunControlPrivate::initiateStop()
{
checkState(RunControlState::Running);
setState(RunControlState::Stopping);
- debugMessage("Queue: Stopping");
+ debugMessage("Queue: Stopping for all workers");
- continueStop();
+ 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) {
+ debugMessage("All stopped.");
+ setState(RunControlState::Stopped);
+ } else {
+ debugMessage("Not all workers stopped. Waiting...");
+ }
}
-void RunControlPrivate::continueStop()
+void RunControlPrivate::initiateFinish()
{
- debugMessage("Continue Stopping");
- checkState(RunControlState::Stopping);
+ setState(RunControlState::Finishing);
+ debugMessage("Ramping down");
+
bool allDone = true;
for (RunWorker *worker : m_workers) {
if (worker) {
@@ -904,17 +899,17 @@ void RunControlPrivate::continueStop()
allDone = false;
break;
case RunWorkerState::Starting:
- worker->d->state = RunWorkerState::Stopping;
debugMessage(" " + workerId + " was Starting, queuing stop");
- allDone = false;
+ worker->d->state = RunWorkerState::Stopping;
QTimer::singleShot(0, worker, &RunWorker::initiateStop);
- return; // Sic.
+ 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);
- return; // Sic.
+ break;
case RunWorkerState::Done:
debugMessage(" " + workerId + " was Done. Good.");
break;
@@ -927,8 +922,9 @@ void RunControlPrivate::continueStop()
}
}
if (allDone) {
- debugMessage("All workers stopped. Set runControl to Stopped");
- setState(RunControlState::Stopped);
+ 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")
.arg(stateName(state))
.arg(worker->d->id));
- //setState(RunControlState::Stopped);
}
void RunControlPrivate::onWorkerFailed(RunWorker *worker, const QString &msg)
@@ -968,13 +963,72 @@ void RunControlPrivate::onWorkerStopped(RunWorker *worker)
worker->d->state = RunWorkerState::Done;
debugMessage(workerId + " stopped expectedly.");
break;
+ case RunWorkerState::Done:
+ worker->d->state = RunWorkerState::Done;
+ debugMessage(workerId + " stopped twice. Huh? But harmless.");
+ return; // Sic!
default:
debugMessage(workerId + " stopped unexpectedly in state"
+ stateName(worker->d->state));
worker->d->state = RunWorkerState::Failed;
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)
@@ -1175,15 +1229,23 @@ bool RunControlPrivate::isAllowedTransition(RunControlState from, RunControlStat
{
switch (from) {
case RunControlState::Initialized:
- return to == RunControlState::Starting;
+ return to == RunControlState::Starting
+ || to == RunControlState::Finishing;
case RunControlState::Starting:
- return to == RunControlState::Running;
+ return to == RunControlState::Running
+ || to == RunControlState::Finishing;
case RunControlState::Running:
return to == RunControlState::Stopping
- || to == RunControlState::Stopped;
+ || to == RunControlState::Stopped
+ || to == RunControlState::Finishing;
case RunControlState::Stopping:
- return to == RunControlState::Stopped;
+ return to == RunControlState::Stopped
+ || to == RunControlState::Finishing;
case RunControlState::Stopped:
+ return to == RunControlState::Finishing;
+ case RunControlState::Finishing:
+ return to == RunControlState::Finished;
+ case RunControlState::Finished:
return false;
}
return false;
@@ -1213,11 +1275,13 @@ void RunControlPrivate::setState(RunControlState newState)
break;
case RunControlState::Stopped:
q->setApplicationProcessHandle(Utils::ProcessHandle());
- foreach (auto worker, m_workers)
- if (worker)
- worker->onFinished();
emit q->stopped();
break;
+ case RunControlState::Finished:
+ emit q->finished();
+ debugMessage("All finished. Deleting myself");
+ deleteLater();
+ break;
default:
break;
}
@@ -1228,18 +1292,6 @@ void RunControlPrivate::debugMessage(const QString &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)
{
emit appendMessageRequested(this, msg, format);
@@ -1358,8 +1410,9 @@ void SimpleTargetRunner::stop()
void SimpleTargetRunner::onProcessStarted()
{
// Console processes only know their pid after being started
- runControl()->setApplicationProcessHandle(m_launcher.applicationPID());
- runControl()->bringApplicationToForeground();
+ ProcessHandle pid = m_launcher.applicationPID();
+ runControl()->setApplicationProcessHandle(pid);
+ pid.activate();
reportStarted();
}
diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h
index eb408c204a..8fabadb654 100644
--- a/src/plugins/projectexplorer/runconfiguration.h
+++ b/src/plugins/projectexplorer/runconfiguration.h
@@ -245,6 +245,12 @@ public:
static RunConfiguration *startupRunConfiguration();
+ using AspectFactory = std::function<IRunConfigurationAspect *(RunConfiguration *)>;
+ template <class T> static void registerAspect()
+ {
+ addAspectFactory([](RunConfiguration *rc) { return new T(rc); });
+ }
+
signals:
void enabledChanged();
void requestRunActionsUpdate();
@@ -260,7 +266,7 @@ protected:
private:
void ctor();
- void addExtraAspects();
+ static void addAspectFactory(const AspectFactory &aspectFactory);
QList<IRunConfigurationAspect *> m_aspects;
};
@@ -295,22 +301,6 @@ private:
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
{
Q_OBJECT
@@ -397,6 +387,7 @@ public:
void initiateStart();
void initiateReStart();
void initiateStop();
+ void initiateFinish();
bool promptToStop(bool *optionalPrompt = nullptr) const;
void setPromptToStop(const std::function<bool(bool *)> &promptToStop);
@@ -430,7 +421,6 @@ public:
void setRunnable(const Runnable &runnable);
virtual void appendMessage(const QString &msg, Utils::OutputFormat format);
- virtual void bringApplicationToForeground();
static bool showPromptToStopDialog(const QString &title, const QString &text,
const QString &stopButtonText = QString(),
@@ -450,24 +440,28 @@ public:
addWorkerFactory({runMode, constraint, producer});
}
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); };
- addWorkerFactory({runMode, constraint, producer});
+ addWorkerFactory({runMode, constraint, producer, priority});
}
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 producer = [](RunControl *rc) { return new Worker(rc); };
- addWorkerFactory({runMode, constraint, producer});
+ addWorkerFactory({runMode, constraint, producer, priority});
}
struct WorkerFactory {
Core::Id runMode;
Constraint constraint;
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;
};
@@ -479,6 +473,7 @@ signals:
void aboutToStart();
void started();
void stopped();
+ void finished();
void applicationProcessHandleChanged(QPrivateSignal); // Use setApplicationProcessHandle
private:
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp
index 950028bf3b..3601db1753 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp
@@ -44,6 +44,7 @@
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
+#include <utils/qtcfallthrough.h>
namespace QmlDesigner {
@@ -358,6 +359,7 @@ bool FormEditorScene::event(QEvent * event)
currentTool()->keyPressEvent(static_cast<QKeyEvent*>(event));
return true;
}
+ Q_FALLTHROUGH();
default: return QGraphicsScene::event(event);
}
diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp
index a95c455134..f5bb5d1ba6 100644
--- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp
+++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp
@@ -1029,9 +1029,9 @@ bool NodeMetaInfoPrivate::cleverCheckType(const TypeName &otherType) const
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")
return QVariant::String;
diff --git a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp
index 777a042fc1..ea89b6b6dc 100644
--- a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp
@@ -76,16 +76,6 @@ namespace Internal {
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)
{
Q_UNUSED(arguments)
@@ -101,7 +91,8 @@ void QmlProfilerPlugin::extensionsInitialized()
(void) new QmlProfilerTool(this);
addAutoReleasedObject(new QmlProfilerOptionsPage);
- addAutoReleasedObject(new QmlProfilerRunControlFactory);
+
+ RunConfiguration::registerAspect<QmlProfilerRunConfigurationAspect>();
auto constraint = [](RunConfiguration *runConfiguration) {
Target *target = runConfiguration ? runConfiguration->target() : nullptr;
diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp
index 227b6dff0b..e246bf885c 100644
--- a/src/plugins/qmlprofiler/qmlprofilertool.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp
@@ -69,6 +69,8 @@
#include <qtsupport/qtkitinformation.h>
+#include <utils/qtcfallthrough.h>
+
#include <QApplication>
#include <QDockWidget>
#include <QFileDialog>
@@ -387,6 +389,7 @@ void QmlProfilerTool::finalizeRunControl(QmlProfilerRunner *runWorker)
case QMessageBox::Help:
HelpManager::handleHelpRequest(
"qthelp://org.qt-project.qtcreator/doc/creator-debugging-qml.html");
+ Q_FALLTHROUGH();
case QMessageBox::Cancel:
// The actual error message has already been logged.
logState(tr("Failed to connect."));
diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp
index 8519d12422..a2a00b4f98 100644
--- a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp
+++ b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp
@@ -53,6 +53,7 @@
// Needed for the load&save actions in the context menu
#include <debugger/analyzer/analyzermanager.h>
#include <coreplugin/findplaceholder.h>
+#include <utils/qtcfallthrough.h>
#include <utils/styledbar.h>
#include <utils/algorithm.h>
@@ -103,7 +104,7 @@ QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, QmlProfilerViewManag
qint64 end = modelManager->traceTime()->endTime();
d->m_zoomControl->setTrace(start, end);
d->m_zoomControl->setRange(start, start + (end - start) / 10);
- // Fall through
+ Q_FALLTHROUGH();
}
case QmlProfilerModelManager::Empty:
d->m_modelProxy->setModels(d->m_suspendedModels);
@@ -116,7 +117,7 @@ QmlProfilerTraceView::QmlProfilerTraceView(QWidget *parent, QmlProfilerViewManag
d->m_zoomControl->clear();
if (!d->m_suspendedModels.isEmpty())
break; // Models are suspended already. AcquiringData was aborted.
- // Fall through
+ Q_FALLTHROUGH();
case QmlProfilerModelManager::AcquiringData:
// Temporarily remove the models, while we're changing them
d->m_suspendedModels = d->m_modelProxy->models();
diff --git a/src/plugins/scxmleditor/common/structuremodel.cpp b/src/plugins/scxmleditor/common/structuremodel.cpp
index f7b2e563e9..5f63319c16 100644
--- a/src/plugins/scxmleditor/common/structuremodel.cpp
+++ b/src/plugins/scxmleditor/common/structuremodel.cpp
@@ -27,6 +27,8 @@
#include "scxmldocument.h"
#include "scxmltag.h"
+#include <utils/qtcfallthrough.h>
+
#include <QMimeData>
#include <QUndoStack>
@@ -245,6 +247,7 @@ Qt::ItemFlags StructureModel::flags(const QModelIndex &index) const
case Final:
case History:
defaultFlags |= Qt::ItemIsDragEnabled;
+ Q_FALLTHROUGH();
case Scxml:
defaultFlags |= Qt::ItemIsDropEnabled;
break;
diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp
index 4c9711a67c..7e8c1c2345 100644
--- a/src/plugins/texteditor/texteditor.cpp
+++ b/src/plugins/texteditor/texteditor.cpp
@@ -3821,7 +3821,7 @@ void TextEditorWidgetPrivate::drawLineAnnotation(QPainter &painter, const QTextB
QRectF annotationRect(x, lineRect.top(), q->viewport()->width() - x, lineRect.height());
if (annotationRect.width() <= 0)
break;
- mark->paintAnnotation(&painter, &annotationRect, q->fontMetrics());
+ mark->paintAnnotation(&painter, &annotationRect);
x += annotationRect.width() + itemOffset;
m_annotationRects[block.blockNumber()].append({annotationRect, mark});
}
diff --git a/src/plugins/texteditor/textmark.cpp b/src/plugins/texteditor/textmark.cpp
index 15939a3f44..254999f1b3 100644
--- a/src/plugins/texteditor/textmark.cpp
+++ b/src/plugins/texteditor/textmark.cpp
@@ -123,42 +123,52 @@ void TextMark::paintIcon(QPainter *painter, const QRect &rect) const
m_icon.paint(painter, rect, Qt::AlignCenter);
}
-void TextMark::paintAnnotation(QPainter *painter,
- QRectF *annotationRect,
- const QFontMetrics &fm) const
+void TextMark::paintAnnotation(QPainter *painter, QRectF *annotationRect) const
{
QString text = lineAnnotation();
if (text.isEmpty())
return;
- const bool drawIcon = !m_icon.isNull();
- 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 AnnotationRects &rects = annotationRects(*annotationRect, painter->fontMetrics());
+
const QColor markColor = m_hasColor ? Utils::creatorTheme()->color(m_color).toHsl()
: painter->pen().color();
const AnnotationColors &colors =
AnnotationColors::getAnnotationColors(markColor, painter->background().color());
painter->save();
- annotationRect->setWidth(annotationWidth);
painter->setPen(colors.rectColor);
painter->setBrush(colors.rectColor);
- painter->drawRect(*annotationRect);
+ painter->drawRect(rects.annotationRect);
painter->setPen(colors.textColor);
+ paintIcon(painter, rects.iconRect.toAlignedRect());
+ painter->drawText(rects.textRect, Qt::AlignLeft, rects.text);
+ 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) {
- paintIcon(painter, annotationRect->adjusted(
- margin, margin, -(textWidth + 2 * margin), -margin).toAlignedRect());
+ rects.iconRect.setHeight(boundingRect.height() - 2 * margin);
+ rects.iconRect.setWidth(rects.iconRect.height() * m_widthFactor);
}
- painter->drawText(annotationRect->adjusted(iconWidth, 0, 0, 0), Qt::AlignLeft, text);
- painter->restore();
+ 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)
diff --git a/src/plugins/texteditor/textmark.h b/src/plugins/texteditor/textmark.h
index 89d3d96e02..ca484a8538 100644
--- a/src/plugins/texteditor/textmark.h
+++ b/src/plugins/texteditor/textmark.h
@@ -64,7 +64,15 @@ public:
int lineNumber() 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
virtual void updateFileName(const QString &fileName);
virtual void updateLineNumber(int lineNumber);
diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp
index a69e2eac60..cab6dea44c 100644
--- a/src/plugins/valgrind/memchecktool.cpp
+++ b/src/plugins/valgrind/memchecktool.cpp
@@ -562,6 +562,7 @@ RunWorker *MemcheckTool::createRunWorker(RunControl *runControl)
connect(runTool, &MemcheckToolRunner::internalParserError, this, &MemcheckTool::internalParserError);
connect(runTool, &MemcheckToolRunner::stopped, this, &MemcheckTool::engineFinished);
+ m_stopAction->disconnect();
connect(m_stopAction, &QAction::triggered, runControl, &RunControl::initiateStop);
m_toolBusy = true;
diff --git a/src/plugins/valgrind/valgrindengine.cpp b/src/plugins/valgrind/valgrindengine.cpp
index 3cb1a4245b..13beca1fa0 100644
--- a/src/plugins/valgrind/valgrindengine.cpp
+++ b/src/plugins/valgrind/valgrindengine.cpp
@@ -106,7 +106,6 @@ void ValgrindToolRunner::stop()
{
m_isStopping = true;
m_runner.stop();
- reportStopped(); // FIXME: Restrict to non-running scenarios?
}
QString ValgrindToolRunner::executable() const
diff --git a/src/plugins/valgrind/valgrindplugin.cpp b/src/plugins/valgrind/valgrindplugin.cpp
index 4cb71eab68..4e250b8b19 100644
--- a/src/plugins/valgrind/valgrindplugin.cpp
+++ b/src/plugins/valgrind/valgrindplugin.cpp
@@ -110,15 +110,6 @@ public:
}
};
-class ValgrindRunControlFactory : public IRunControlFactory
-{
-public:
- IRunConfigurationAspect *createRunConfigurationAspect(RunConfiguration *rc) override
- {
- return new ValgrindRunConfigurationAspect(rc);
- }
-};
-
ValgrindPlugin::~ValgrindPlugin()
{
delete theGlobalSettings;
@@ -131,7 +122,8 @@ bool ValgrindPlugin::initialize(const QStringList &, QString *)
theGlobalSettings->readSettings();
addAutoReleasedObject(new ValgrindOptionsPage);
- addAutoReleasedObject(new ValgrindRunControlFactory);
+
+ RunConfiguration::registerAspect<ValgrindRunConfigurationAspect>();
return true;
}
diff --git a/src/plugins/vcsbase/vcsbaseclientsettings.cpp b/src/plugins/vcsbase/vcsbaseclientsettings.cpp
index 35c2a7c119..ab67910c2f 100644
--- a/src/plugins/vcsbase/vcsbaseclientsettings.cpp
+++ b/src/plugins/vcsbase/vcsbaseclientsettings.cpp
@@ -29,6 +29,7 @@
#include <utils/fileutils.h>
#include <utils/hostosinfo.h>
#include <utils/qtcassert.h>
+#include <utils/qtcfallthrough.h>
#include <QSettings>
#include <QVariant>
@@ -56,6 +57,7 @@ public:
switch (v.type()) {
case QVariant::UInt:
m_type = QVariant::Int;
+ Q_FALLTHROUGH();
case QVariant::Int:
m_comp.intValue = v.toInt();
break;
diff --git a/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp b/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp
index b92a35f854..6b628cdb13 100644
--- a/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp
+++ b/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp
@@ -48,6 +48,37 @@ static void readPatch(QFutureInterface<QList<FileData>> &futureInterface,
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
{
public:
@@ -59,6 +90,7 @@ public:
void processingFinished();
void processDiff(const QString &patch);
void cancelReload();
+ void storeOutput(const QString &output);
void commandFinished(bool success);
VcsBaseDiffEditorController *q;
@@ -67,18 +99,43 @@ public:
QString m_startupFile;
QString m_output;
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,
const QString &workingDirectory)
: q(controller)
, m_client(client)
, m_directory(workingDirectory)
{
- QObject::connect(&m_processWatcher, &QFutureWatcher<QList<FileData>>::finished, q,
- [this] () { processingFinished(); });
}
VcsBaseDiffEditorControllerPrivate::~VcsBaseDiffEditorControllerPrivate()
@@ -88,9 +145,18 @@ VcsBaseDiffEditorControllerPrivate::~VcsBaseDiffEditorControllerPrivate()
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
- ? 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->reloadFinished(success);
@@ -98,39 +164,67 @@ void VcsBaseDiffEditorControllerPrivate::processingFinished()
void VcsBaseDiffEditorControllerPrivate::processDiff(const QString &patch)
{
- m_processWatcher.setFuture(Utils::runAsync(&readPatch, patch));
+ cancelReload();
+
+ m_processWatcher = new QFutureWatcher<QList<FileData>>();
- ProgressManager::addTask(m_processWatcher.future(),
- 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()
{
if (m_command) {
- m_command->disconnect();
m_command->cancel();
m_command.clear();
}
- if (m_processWatcher.future().isRunning()) {
- m_processWatcher.future().cancel();
- m_processWatcher.setFuture(QFuture<QList<FileData>>());
+ // Disconnect effectively, don't deliver already posted signals
+ if (m_commandResultProxy)
+ 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();
}
+void VcsBaseDiffEditorControllerPrivate::storeOutput(const QString &output)
+{
+ m_output = output;
+}
+
void VcsBaseDiffEditorControllerPrivate::commandFinished(bool success)
{
if (m_command)
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) {
cancelReload();
q->reloadFinished(success);
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)
{
+ // 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->m_command = new VcsCommand(workingDirectory(), d->m_client->processEnvironment());
d->m_command->setCodec(codec ? codec : EditorManager::defaultTextCodec());
- connect(d->m_command.data(), &VcsCommand::stdOutText, this,
- [this] (const QString &output) { d->m_output = output; });
- connect(d->m_command.data(), &VcsCommand::finished, this,
- [this] (bool success) { d->commandFinished(success); });
+ d->m_commandResultProxy = new VcsCommandResultProxy(d->m_command.data(), d);
d->m_command->addFlags(flags);
for (const QStringList &arg : args) {
@@ -195,3 +290,5 @@ QString VcsBaseDiffEditorController::startupFile() const
}
} // namespace VcsBase
+
+#include "vcsbasediffeditorcontroller.moc"
diff --git a/src/tools/icons/qtcreatoricons.svg b/src/tools/icons/qtcreatoricons.svg
index e24903e09e..0534a08b94 100644
--- a/src/tools/icons/qtcreatoricons.svg
+++ b/src/tools/icons/qtcreatoricons.svg
@@ -1671,6 +1671,28 @@
sodipodi:nodetypes="cccccccccccccccc" />
</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
id="src/libs/utils/images/wizardicon-file"
transform="translate(-102.49412,8.5102807)">
<rect