aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libs/tracing/qml/TimeMarks.qml11
-rw-r--r--src/libs/utils/theme/theme.h9
-rw-r--r--src/plugins/android/android.pro2
-rw-r--r--src/plugins/android/android.qbs2
-rw-r--r--src/plugins/android/androidavdmanager.cpp1
-rw-r--r--src/plugins/android/androidconfigurations.h1
-rw-r--r--src/plugins/android/androidconstants.h9
-rw-r--r--src/plugins/android/androidrunconfiguration.cpp12
-rw-r--r--src/plugins/android/androidrunnable.cpp37
-rw-r--r--src/plugins/android/androidrunnable.h57
-rw-r--r--src/plugins/android/androidrunner.cpp22
-rw-r--r--src/plugins/android/androidrunner.h5
-rw-r--r--src/plugins/android/androidrunnerworker.cpp50
-rw-r--r--src/plugins/android/androidrunnerworker.h10
-rw-r--r--src/plugins/autotest/testrunner.cpp287
-rw-r--r--src/plugins/autotest/testrunner.h19
-rw-r--r--src/plugins/clangcodemodel/clangtextmark.cpp4
-rw-r--r--src/plugins/clangtools/clangtidyclazytool.cpp4
-rw-r--r--src/plugins/clangtools/clangtools.qbs1
-rw-r--r--src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp42
-rw-r--r--src/plugins/clangtools/clangtoolsdiagnosticmodel.h12
-rw-r--r--src/plugins/cmakeprojectmanager/builddirmanager.cpp6
-rw-r--r--src/plugins/cmakeprojectmanager/servermodereader.cpp3
-rw-r--r--src/plugins/cppeditor/cppcodemodelinspectordialog.ui204
-rw-r--r--src/plugins/debugger/analyzer/detailederrorview.cpp104
-rw-r--r--src/plugins/debugger/analyzer/detailederrorview.h4
-rw-r--r--src/plugins/diffeditor/sidebysidediffeditorwidget.cpp20
-rw-r--r--src/plugins/diffeditor/sidebysidediffeditorwidget.h1
-rw-r--r--src/plugins/projectexplorer/buildstep.cpp18
-rw-r--r--src/plugins/projectexplorer/buildstep.h1
-rw-r--r--src/plugins/projectexplorer/project.cpp5
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp19
-rw-r--r--src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp2
-rw-r--r--src/plugins/qmljseditor/qmljstextmark.cpp4
-rw-r--r--src/plugins/texteditor/texteditor.cpp16
-rw-r--r--src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp22
-rw-r--r--src/shared/clang/clang_installation.pri8
-rw-r--r--src/tools/clangbackend/source/clangtype.cpp3
-rw-r--r--src/tools/clangbackend/source/sourcelocation.cpp3
39 files changed, 487 insertions, 553 deletions
diff --git a/src/libs/tracing/qml/TimeMarks.qml b/src/libs/tracing/qml/TimeMarks.qml
index 2fc1ef41c8..fc3d9e3c90 100644
--- a/src/libs/tracing/qml/TimeMarks.qml
+++ b/src/libs/tracing/qml/TimeMarks.qml
@@ -54,11 +54,18 @@ Item {
}
function prettyPrintScale(amount) {
+ var sign;
+ if (amount < 0) {
+ sign = "-";
+ amount = -amount;
+ } else {
+ sign = "";
+ }
var unitOffset = 0;
var unitAmount = 1;
for (unitOffset = 0; amount > unitAmount * 1024; ++unitOffset, unitAmount *= 1024) {}
var result = amount / unitAmount;
- return roundTo3Digits(result) + units[unitOffset];
+ return sign + roundTo3Digits(result) + units[unitOffset];
}
Connections {
@@ -134,7 +141,7 @@ Item {
anchors.bottomMargin: 2
anchors.leftMargin: 2
anchors.left: parent.left
- text: prettyPrintScale(index * row.stepVal)
+ text: prettyPrintScale(row.minVal + index * row.stepVal)
}
Rectangle {
diff --git a/src/libs/utils/theme/theme.h b/src/libs/utils/theme/theme.h
index 62eac0ade7..49c7c881ad 100644
--- a/src/libs/utils/theme/theme.h
+++ b/src/libs/utils/theme/theme.h
@@ -212,6 +212,11 @@ public:
IconsCodeModelOverlayBackgroundColor,
IconsCodeModelOverlayForegroundColor,
+ /* Code model text marks */
+
+ CodeModel_Error_TextMarkColor,
+ CodeModel_Warning_TextMarkColor,
+
/* Output panes */
OutputPanes_DebugTextColor,
@@ -287,10 +292,6 @@ public:
ProjectExplorer_TaskError_TextMarkColor,
ProjectExplorer_TaskWarn_TextMarkColor,
- /* ClangCodeModel Plugin */
- ClangCodeModel_Error_TextMarkColor,
- ClangCodeModel_Warning_TextMarkColor,
-
/* QmlDesigner Plugin */
QmlDesigner_BackgroundColor,
QmlDesigner_HighlightColor,
diff --git a/src/plugins/android/android.pro b/src/plugins/android/android.pro
index d26264df20..e17c7e284b 100644
--- a/src/plugins/android/android.pro
+++ b/src/plugins/android/android.pro
@@ -46,7 +46,6 @@ HEADERS += \
android_global.h \
androidbuildapkstep.h \
androidbuildapkwidget.h \
- androidrunnable.h \
androidtoolmanager.h \
androidsdkmanager.h \
androidavdmanager.h \
@@ -94,7 +93,6 @@ SOURCES += \
androidbuildapkstep.cpp \
androidbuildapkwidget.cpp \
androidqtsupport.cpp \
- androidrunnable.cpp \
androidtoolmanager.cpp \
androidsdkmanager.cpp \
androidavdmanager.cpp \
diff --git a/src/plugins/android/android.qbs b/src/plugins/android/android.qbs
index 4b9ce0545e..b573d3883b 100644
--- a/src/plugins/android/android.qbs
+++ b/src/plugins/android/android.qbs
@@ -86,8 +86,6 @@ Project {
"androidrunconfiguration.h",
"androidruncontrol.cpp",
"androidruncontrol.h",
- "androidrunnable.cpp",
- "androidrunnable.h",
"androidrunner.cpp",
"androidrunner.h",
"androidrunnerworker.cpp",
diff --git a/src/plugins/android/androidavdmanager.cpp b/src/plugins/android/androidavdmanager.cpp
index 85351e3228..44ed85b170 100644
--- a/src/plugins/android/androidavdmanager.cpp
+++ b/src/plugins/android/androidavdmanager.cpp
@@ -297,6 +297,7 @@ bool AndroidAvdManager::startAvdAsync(const QString &avdName) const
return false;
}
QProcess *avdProcess = new QProcess();
+ avdProcess->setReadChannelMode(QProcess::MergedChannels);
QObject::connect(avdProcess,
static_cast<void (QProcess::*)(int)>(&QProcess::finished),
avdProcess,
diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h
index 15d27413bd..58dde7479b 100644
--- a/src/plugins/android/androidconfigurations.h
+++ b/src/plugins/android/androidconfigurations.h
@@ -232,3 +232,4 @@ private:
} // namespace Android
+Q_DECLARE_METATYPE(Android::AndroidDeviceInfo)
diff --git a/src/plugins/android/androidconstants.h b/src/plugins/android/androidconstants.h
index 0015c69ff5..2ff36be77e 100644
--- a/src/plugins/android/androidconstants.h
+++ b/src/plugins/android/androidconstants.h
@@ -51,9 +51,11 @@ const char ANDROID_SETTINGS_ID[] = "BB.Android Configurations";
const char ANDROID_TOOLCHAIN_ID[] = "Qt4ProjectManager.ToolChain.Android";
const char ANDROIDQT[] = "Qt4ProjectManager.QtVersion.Android";
-const char ANDROID_AMSTARTARGS_ASPECT[] = "Android.AmStartArgs";
-const char ANDROID_PRESTARTSHELLCMDLIST_ASPECT[] = "Android.PreStartShellCmdList";
-const char ANDROID_POSTSTARTSHELLCMDLIST_ASPECT[] = "Android.PostStartShellCmdList";
+const char ANDROID_AMSTARTARGS[] = "Android.AmStartArgs";
+// Note: Can be set on RunConfiguration using an aspect and/or
+// the AndroidRunnerWorker using recordData()
+const char ANDROID_PRESTARTSHELLCMDLIST[] = "Android.PreStartShellCmdList";
+const char ANDROID_POSTFINISHSHELLCMDLIST[] = "Android.PostFinishShellCmdList";
const char ANDROID_DEVICE_TYPE[] = "Android.Device.Type";
const char ANDROID_DEVICE_ID[] = "Android Device";
@@ -69,6 +71,7 @@ const char ANDROID_DEPLOY_SETTINGS_FILE[] = "AndroidDeploySettingsFile";
const char ANDROID_PACKAGE_SOURCE_DIR[] = "AndroidPackageSourceDir";
const char ANDROID_EXTRA_LIBS[] = "AndroidExtraLibs";
+const char ANDROID_PACKAGENAME[] = "Android.PackageName";
const char ANDROID_PACKAGE_INSTALLATION_STEP_ID[] = "Qt4ProjectManager.AndroidPackageInstallationStep";
} // namespace Constants;
diff --git a/src/plugins/android/androidrunconfiguration.cpp b/src/plugins/android/androidrunconfiguration.cpp
index ac44a54698..ac1a6858be 100644
--- a/src/plugins/android/androidrunconfiguration.cpp
+++ b/src/plugins/android/androidrunconfiguration.cpp
@@ -111,20 +111,20 @@ AndroidRunConfiguration::AndroidRunConfiguration(Target *target, Core::Id id)
: RunConfiguration(target, id)
{
auto amStartArgsAspect = new BaseStringAspect(this);
- amStartArgsAspect->setId(Constants::ANDROID_AMSTARTARGS_ASPECT);
+ amStartArgsAspect->setId(Constants::ANDROID_AMSTARTARGS);
amStartArgsAspect->setSettingsKey("Android.AmStartArgsKey");
amStartArgsAspect->setLabelText(tr("Activity manager start options:"));
amStartArgsAspect->setDisplayStyle(BaseStringAspect::LineEditDisplay);
addExtraAspect(amStartArgsAspect);
auto preStartShellCmdAspect = new BaseStringListAspect(this);
- preStartShellCmdAspect->setId(Constants::ANDROID_PRESTARTSHELLCMDLIST_ASPECT);
+ preStartShellCmdAspect->setId(Constants::ANDROID_PRESTARTSHELLCMDLIST);
preStartShellCmdAspect->setSettingsKey("Android.PreStartShellCmdListKey");
preStartShellCmdAspect->setLabel(tr("Shell commands to run on Android device before application launch."));
addExtraAspect(preStartShellCmdAspect);
auto postStartShellCmdAspect = new BaseStringListAspect(this);
- postStartShellCmdAspect->setId(Constants::ANDROID_POSTSTARTSHELLCMDLIST_ASPECT);
+ postStartShellCmdAspect->setId(Constants::ANDROID_POSTFINISHSHELLCMDLIST);
postStartShellCmdAspect->setSettingsKey("Android.PostStartShellCmdListKey");
postStartShellCmdAspect->setLabel(tr("Shell commands to run on Android device after application quits."));
addExtraAspect(postStartShellCmdAspect);
@@ -140,7 +140,7 @@ QWidget *AndroidRunConfiguration::createConfigurationWidget()
auto widget = new QWidget;
auto layout = new QFormLayout(widget);
- extraAspect(Constants::ANDROID_AMSTARTARGS_ASPECT)->addToConfigurationLayout(layout);
+ extraAspect(Constants::ANDROID_AMSTARTARGS)->addToConfigurationLayout(layout);
auto warningIconLabel = new QLabel;
warningIconLabel->setPixmap(Utils::Icons::WARNING.pixmap());
@@ -148,8 +148,8 @@ QWidget *AndroidRunConfiguration::createConfigurationWidget()
auto warningLabel = new QLabel(tr("If the \"am start\" options conflict, the application might not start."));
layout->addRow(warningIconLabel, warningLabel);
- extraAspect(Constants::ANDROID_PRESTARTSHELLCMDLIST_ASPECT)->addToConfigurationLayout(layout);
- extraAspect(Constants::ANDROID_POSTSTARTSHELLCMDLIST_ASPECT)->addToConfigurationLayout(layout);
+ extraAspect(Constants::ANDROID_PRESTARTSHELLCMDLIST)->addToConfigurationLayout(layout);
+ extraAspect(Constants::ANDROID_POSTFINISHSHELLCMDLIST)->addToConfigurationLayout(layout);
auto wrapped = wrapWidget(widget);
auto detailsWidget = qobject_cast<DetailsWidget *>(wrapped);
diff --git a/src/plugins/android/androidrunnable.cpp b/src/plugins/android/androidrunnable.cpp
deleted file mode 100644
index ae70bd71dd..0000000000
--- a/src/plugins/android/androidrunnable.cpp
+++ /dev/null
@@ -1,37 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 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.
-**
-****************************************************************************/
-
-#include "androidrunnable.h"
-
-namespace Android {
-
-void *AndroidRunnable::staticTypeId = &AndroidRunnable::staticTypeId;
-
-AndroidRunnable::AndroidRunnable()
-{
- qRegisterMetaType<AndroidRunnable>("AndroidRunnable");
-}
-
-} // namespace Android
diff --git a/src/plugins/android/androidrunnable.h b/src/plugins/android/androidrunnable.h
deleted file mode 100644
index e549acf590..0000000000
--- a/src/plugins/android/androidrunnable.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 BogDan Vatra <bog_dan_ro@yahoo.com>
-** 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 "android_global.h"
-#include <projectexplorer/runnables.h>
-
-namespace Android {
-
-struct ANDROID_EXPORT AndroidRunnable
-{
- AndroidRunnable();
- QString packageName;
- QStringList beforeStartAdbCommands;
- QStringList afterFinishAdbCommands;
-
- QString displayName() const { return packageName; }
- static void *staticTypeId;
-};
-
-inline bool operator==(const AndroidRunnable &r1, const AndroidRunnable &r2)
-{
- return r1.packageName == r2.packageName
- && r1.beforeStartAdbCommands == r2.beforeStartAdbCommands
- && r1.afterFinishAdbCommands == r2.afterFinishAdbCommands;
-}
-
-inline bool operator!=(const AndroidRunnable &r1, const AndroidRunnable &r2)
-{
- return !(r1 == r2);
-}
-
-} // namespace Android
-Q_DECLARE_METATYPE(Android::AndroidRunnable)
diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp
index ce4a0c918c..4ea111aeb3 100644
--- a/src/plugins/android/androidrunner.cpp
+++ b/src/plugins/android/androidrunner.cpp
@@ -120,7 +120,8 @@ AndroidRunner::AndroidRunner(RunControl *runControl,
setDisplayName("AndroidRunner");
static const int metaTypes[] = {
qRegisterMetaType<QVector<QStringList> >("QVector<QStringList>"),
- qRegisterMetaType<Utils::Port>("Utils::Port")
+ qRegisterMetaType<Utils::Port>("Utils::Port"),
+ qRegisterMetaType<AndroidDeviceInfo>("Android::AndroidDeviceInfo")
};
Q_UNUSED(metaTypes);
@@ -128,21 +129,10 @@ AndroidRunner::AndroidRunner(RunControl *runControl,
connect(&m_checkAVDTimer, &QTimer::timeout, this, &AndroidRunner::checkAVD);
QString intent = intentName.isEmpty() ? AndroidManager::intentName(m_target) : intentName;
- m_androidRunnable.packageName = intent.left(intent.indexOf('/'));
-
- RunConfiguration *rc = runControl->runConfiguration();
- if (auto aspect = rc->extraAspect(Constants::ANDROID_PRESTARTSHELLCMDLIST_ASPECT)) {
- for (QString shellCmd : static_cast<BaseStringListAspect *>(aspect)->value())
- m_androidRunnable.beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd));
- }
-
- if (auto aspect = rc->extraAspect(Constants::ANDROID_POSTSTARTSHELLCMDLIST_ASPECT)) {
- for (QString shellCmd : static_cast<BaseStringListAspect *>(aspect)->value())
- m_androidRunnable.afterFinishAdbCommands.append(QString("shell %1").arg(shellCmd));
- }
+ m_packageName = intent.left(intent.indexOf('/'));
const int apiLevel = AndroidManager::deviceApiLevel(m_target);
- m_worker.reset(new AndroidRunnerWorker(this, m_androidRunnable));
+ m_worker.reset(new AndroidRunnerWorker(this, m_packageName));
m_worker->setIntentName(intent);
m_worker->setIsPreNougat(apiLevel <= 23);
m_worker->setExtraAppParams(extraAppParams);
@@ -193,7 +183,7 @@ void AndroidRunner::stop()
{
if (m_checkAVDTimer.isActive()) {
m_checkAVDTimer.stop();
- appendMessage("\n\n" + tr("\"%1\" terminated.").arg(m_androidRunnable.packageName),
+ appendMessage("\n\n" + tr("\"%1\" terminated.").arg(m_packageName),
Utils::DebugFormat);
return;
}
@@ -258,7 +248,7 @@ void AndroidRunner::launchAVD()
emit androidDeviceInfoChanged(info);
if (info.isValid()) {
AndroidAvdManager avdManager;
- if (avdManager.findAvd(info.avdname).isEmpty()) {
+ if (!info.avdname.isEmpty() && avdManager.findAvd(info.avdname).isEmpty()) {
bool launched = avdManager.startAvdAsync(info.avdname);
m_launchedAVDName = launched ? info.avdname:"";
} else {
diff --git a/src/plugins/android/androidrunner.h b/src/plugins/android/androidrunner.h
index 28212a08db..c1cd170c68 100644
--- a/src/plugins/android/androidrunner.h
+++ b/src/plugins/android/androidrunner.h
@@ -26,7 +26,6 @@
#pragma once
#include "androidconfigurations.h"
-#include "androidrunnable.h"
#include <projectexplorer/runconfiguration.h>
#include <qmldebug/qmldebugcommandlinearguments.h>
@@ -67,7 +66,7 @@ signals:
void asyncStart();
void asyncStop();
void qmlServerReady(const QUrl &serverUrl);
- void androidDeviceInfoChanged(const AndroidDeviceInfo &deviceInfo);
+ void androidDeviceInfoChanged(const Android::AndroidDeviceInfo &deviceInfo);
void avdDetected();
private:
@@ -80,7 +79,7 @@ private:
void checkAVD();
void launchAVD();
- AndroidRunnable m_androidRunnable;
+ QString m_packageName;
QString m_launchedAVDName;
QThread m_thread;
QTimer m_checkAVDTimer;
diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp
index 05071d1d06..62eedaa4c3 100644
--- a/src/plugins/android/androidrunnerworker.cpp
+++ b/src/plugins/android/androidrunnerworker.cpp
@@ -140,8 +140,8 @@ static void deleter(QProcess *p)
p->deleteLater();
}
-AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const AndroidRunnable &runnable)
- : m_androidRunnable(runnable)
+AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packageName)
+ : m_packageName(packageName)
, m_adbLogcatProcess(nullptr, deleter)
, m_psIsAlive(nullptr, deleter)
, m_logCatRegExp(regExpLogcat)
@@ -181,8 +181,22 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const AndroidRunnabl
m_deviceSerialNumber = AndroidManager::deviceSerialNumber(target);
m_apiLevel = AndroidManager::deviceApiLevel(target);
- if (auto aspect = runConfig->extraAspect(Constants::ANDROID_AMSTARTARGS_ASPECT))
+ if (auto aspect = runConfig->extraAspect(Constants::ANDROID_AMSTARTARGS))
m_amStartExtraArgs = static_cast<BaseStringAspect *>(aspect)->value().split(' ');
+
+ if (auto aspect = runConfig->extraAspect(Constants::ANDROID_PRESTARTSHELLCMDLIST)) {
+ for (const QString &shellCmd : static_cast<BaseStringListAspect *>(aspect)->value())
+ m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd));
+ }
+ for (const QString &shellCmd : runner->recordedData(Constants::ANDROID_PRESTARTSHELLCMDLIST).toStringList())
+ m_beforeStartAdbCommands.append(QString("shell %1").arg(shellCmd));
+
+ if (auto aspect = runConfig->extraAspect(Constants::ANDROID_POSTFINISHSHELLCMDLIST)) {
+ for (const QString &shellCmd : static_cast<BaseStringListAspect *>(aspect)->value())
+ m_afterFinishAdbCommands.append(QString("shell %1").arg(shellCmd));
+ }
+ for (const QString &shellCmd : runner->recordedData(Constants::ANDROID_POSTFINISHSHELLCMDLIST).toStringList())
+ m_afterFinishAdbCommands.append(QString("shell %1").arg(shellCmd));
}
AndroidRunnerWorker::~AndroidRunnerWorker()
@@ -229,7 +243,7 @@ bool AndroidRunnerWorker::runAdb(const QStringList &args, int timeoutS)
void AndroidRunnerWorker::adbKill(qint64 pid)
{
runAdb({"shell", "kill", "-9", QString::number(pid)});
- runAdb({"shell", "run-as", m_androidRunnable.packageName, "kill", "-9", QString::number(pid)});
+ runAdb({"shell", "run-as", m_packageName, "kill", "-9", QString::number(pid)});
}
QStringList AndroidRunnerWorker::selector() const
@@ -239,14 +253,14 @@ QStringList AndroidRunnerWorker::selector() const
void AndroidRunnerWorker::forceStop()
{
- runAdb({"shell", "am", "force-stop", m_androidRunnable.packageName}, 30);
+ runAdb({"shell", "am", "force-stop", m_packageName}, 30);
// try killing it via kill -9
const QByteArray out = Utils::SynchronousProcess()
.runBlocking(m_adb, selector() << QStringLiteral("shell") << pidScriptPreNougat)
.allRawOutput();
- qint64 pid = extractPID(out.simplified(), m_androidRunnable.packageName);
+ qint64 pid = extractPID(out.simplified(), m_packageName);
if (pid != -1) {
adbKill(pid);
}
@@ -346,7 +360,7 @@ void AndroidRunnerWorker::asyncStartHelper()
QTC_ASSERT(!m_adbLogcatProcess, /**/);
m_adbLogcatProcess = std::move(logcatProcess);
- for (const QString &entry: m_androidRunnable.beforeStartAdbCommands)
+ for (const QString &entry : m_beforeStartAdbCommands)
runAdb(entry.split(' ', QString::SkipEmptyParts));
QStringList args({"shell", "am", "start"});
@@ -356,14 +370,14 @@ void AndroidRunnerWorker::asyncStartHelper()
args << "-D";
QString gdbServerSocket;
// run-as <package-name> pwd fails on API 22 so route the pwd through shell.
- if (!runAdb({"shell", "run-as", m_androidRunnable.packageName, "/system/bin/sh", "-c", "pwd"})) {
+ if (!runAdb({"shell", "run-as", m_packageName, "/system/bin/sh", "-c", "pwd"})) {
emit remoteProcessFinished(tr("Failed to get process path. Reason: %1.").arg(m_lastRunAdbError));
return;
}
gdbServerSocket = QString::fromUtf8(m_lastRunAdbRawOutput.trimmed()) + "/debug-socket";
QString gdbServerExecutable;
- if (!runAdb({"shell", "run-as", m_androidRunnable.packageName, "ls", "lib/"})) {
+ if (!runAdb({"shell", "run-as", m_packageName, "ls", "lib/"})) {
emit remoteProcessFinished(tr("Failed to get process path. Reason: %1.").arg(m_lastRunAdbError));
return;
}
@@ -380,11 +394,11 @@ void AndroidRunnerWorker::asyncStartHelper()
return;
}
- runAdb({"shell", "run-as", m_androidRunnable.packageName, "killall", gdbServerExecutable});
- runAdb({"shell", "run-as", m_androidRunnable.packageName, "rm", gdbServerSocket});
+ runAdb({"shell", "run-as", m_packageName, "killall", gdbServerExecutable});
+ runAdb({"shell", "run-as", m_packageName, "rm", gdbServerSocket});
std::unique_ptr<QProcess, Deleter> gdbServerProcess(new QProcess, deleter);
gdbServerProcess->start(m_adb, selector() << "shell" << "run-as"
- << m_androidRunnable.packageName << "lib/" + gdbServerExecutable
+ << m_packageName << "lib/" + gdbServerExecutable
<< "--multi" << "+" + gdbServerSocket);
if (!gdbServerProcess->waitForStarted()) {
emit remoteProcessFinished(tr("Failed to start C++ debugger."));
@@ -398,7 +412,7 @@ void AndroidRunnerWorker::asyncStartHelper()
emit remoteProcessFinished(tr("Failed to forward C++ debugging ports. Reason: %1.").arg(m_lastRunAdbError));
return;
}
- m_androidRunnable.afterFinishAdbCommands.push_back(removeForward.join(' '));
+ m_afterFinishAdbCommands.push_back(removeForward.join(' '));
}
if (m_qmlDebugServices != QmlDebug::NoQmlDebugServices) {
@@ -411,7 +425,7 @@ void AndroidRunnerWorker::asyncStartHelper()
.arg(m_lastRunAdbError));
return;
}
- m_androidRunnable.afterFinishAdbCommands.push_back(removeForward.join(' '));
+ m_afterFinishAdbCommands.push_back(removeForward.join(' '));
args << "-e" << "qml_debug" << "true"
<< "-e" << "qmljsdebugger"
@@ -442,7 +456,7 @@ void AndroidRunnerWorker::asyncStart()
asyncStartHelper();
m_pidFinder = Utils::onResultReady(Utils::runAsync(findProcessPID, m_adb, selector(),
- m_androidRunnable.packageName, m_isPreNougat),
+ m_packageName, m_isPreNougat),
bind(&AndroidRunnerWorker::onProcessIdChanged, this, _1));
}
@@ -467,7 +481,7 @@ void AndroidRunnerWorker::handleJdbWaiting()
emit remoteProcessFinished(tr("Failed to forward jdb debugging ports. Reason: %1.").arg(m_lastRunAdbError));
return;
}
- m_androidRunnable.afterFinishAdbCommands.push_back(removeForward.join(' '));
+ m_afterFinishAdbCommands.push_back(removeForward.join(' '));
auto jdbPath = AndroidConfigurations::currentConfig().openJDKLocation().appendPath("bin");
if (Utils::HostOsInfo::isWindowsHost())
@@ -527,7 +541,7 @@ void AndroidRunnerWorker::onProcessIdChanged(qint64 pid)
m_processPID = pid;
if (pid == -1) {
emit remoteProcessFinished(QLatin1String("\n\n") + tr("\"%1\" died.")
- .arg(m_androidRunnable.packageName));
+ .arg(m_packageName));
// App died/killed. Reset log, monitor, jdb & gdb processes.
m_adbLogcatProcess.reset();
m_psIsAlive.reset();
@@ -535,7 +549,7 @@ void AndroidRunnerWorker::onProcessIdChanged(qint64 pid)
m_gdbServerProcess.reset();
// Run adb commands after application quit.
- for (const QString &entry: m_androidRunnable.afterFinishAdbCommands)
+ for (const QString &entry: m_afterFinishAdbCommands)
runAdb(entry.split(' ', QString::SkipEmptyParts));
} else {
// In debugging cases this will be funneled to the engine to actually start
diff --git a/src/plugins/android/androidrunnerworker.h b/src/plugins/android/androidrunnerworker.h
index 768b34a19c..e34207bf03 100644
--- a/src/plugins/android/androidrunnerworker.h
+++ b/src/plugins/android/androidrunnerworker.h
@@ -26,12 +26,12 @@
#pragma once
+#include <projectexplorer/runconfiguration.h>
+
#include <qmldebug/qmldebugcommandlinearguments.h>
#include <QFuture>
-#include "androidrunnable.h"
-
namespace Android {
class AndroidDeviceInfo;
@@ -44,7 +44,7 @@ class AndroidRunnerWorker : public QObject
{
Q_OBJECT
public:
- AndroidRunnerWorker(ProjectExplorer::RunWorker *runner, const AndroidRunnable &runnable);
+ AndroidRunnerWorker(ProjectExplorer::RunWorker *runner, const QString &packageName);
~AndroidRunnerWorker() override;
bool adbShellAmNeedsQuotes();
bool runAdb(const QStringList &args, int timeoutS = 10);
@@ -85,8 +85,10 @@ protected:
// Create the processes and timer in the worker thread, for correct thread affinity
bool m_isPreNougat = false;
- AndroidRunnable m_androidRunnable;
+ QString m_packageName;
QString m_intentName;
+ QStringList m_beforeStartAdbCommands;
+ QStringList m_afterFinishAdbCommands;
QString m_adb;
QStringList m_amStartExtraArgs;
qint64 m_processPID = -1;
diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp
index 6ed58bb39a..e70870b417 100644
--- a/src/plugins/autotest/testrunner.cpp
+++ b/src/plugins/autotest/testrunner.cpp
@@ -48,7 +48,6 @@
#include <utils/hostosinfo.h>
#include <utils/outputformat.h>
#include <utils/qtcprocess.h>
-#include <utils/runextensions.h>
#include <QComboBox>
#include <QDialogButtonBox>
@@ -56,8 +55,9 @@
#include <QFuture>
#include <QFutureInterface>
#include <QLabel>
+#include <QProcess>
#include <QPushButton>
-#include <QTime>
+#include <QTimer>
#include <debugger/debuggerkitinformation.h>
#include <debugger/debuggerruncontrol.h>
@@ -88,9 +88,9 @@ TestRunner::TestRunner(QObject *parent) :
&m_futureWatcher, &QFutureWatcher<TestResultPtr>::cancel);
connect(&m_futureWatcher, &QFutureWatcher<TestResultPtr>::canceled,
this, [this]() {
+ cancelCurrent(UserCanceled);
emit testResultReady(TestResultPtr(new FaultyTestResult(
Result::MessageFatal, tr("Test run canceled by user."))));
- m_executingTests = false; // avoid being stuck if finished() signal won't get emitted
});
}
@@ -103,13 +103,15 @@ TestRunner::~TestRunner()
void TestRunner::setSelectedTests(const QList<TestConfiguration *> &selected)
{
- qDeleteAll(m_selectedTests);
- m_selectedTests.clear();
- m_selectedTests = selected;
+ QTC_ASSERT(!m_executingTests, return);
+ qDeleteAll(m_selectedTests);
+ m_selectedTests.clear();
+ m_selectedTests.append(selected);
}
void TestRunner::runTest(TestRunMode mode, const TestTreeItem *item)
{
+ QTC_ASSERT(!m_executingTests, return);
TestConfiguration *configuration = item->asConfiguration(mode);
if (configuration) {
@@ -118,15 +120,16 @@ void TestRunner::runTest(TestRunMode mode, const TestTreeItem *item)
}
}
-static QString processInformation(const QProcess &proc)
+static QString processInformation(const QProcess *proc)
{
- QString information("\nCommand line: " + proc.program() + ' ' + proc.arguments().join(' '));
+ QTC_ASSERT(proc, return QString());
+ QString information("\nCommand line: " + proc->program() + ' ' + proc->arguments().join(' '));
QStringList important = { "PATH" };
if (Utils::HostOsInfo::isLinuxHost())
important.append("LD_LIBRARY_PATH");
else if (Utils::HostOsInfo::isMacHost())
important.append({ "DYLD_LIBRARY_PATH", "DYLD_FRAMEWORK_PATH" });
- const QProcessEnvironment &environment = proc.processEnvironment();
+ const QProcessEnvironment &environment = proc->processEnvironment();
for (const QString &var : important)
information.append('\n' + var + ": " + environment.value(var));
return information;
@@ -142,133 +145,131 @@ static QString rcInfo(const TestConfiguration * const config)
static QString constructOmittedDetailsString(const QStringList &omitted)
{
- QString details = TestRunner::tr("Omitted the following arguments specified on the run "
- "configuration page for \"%1\":");
- for (const QString &arg : omitted)
- details += "\n" + arg;
- return details;
+ return TestRunner::tr("Omitted the following arguments specified on the run "
+ "configuration page for \"%1\":") + '\n' + omitted.join('\n');
}
-static void performTestRun(QFutureInterface<TestResultPtr> &futureInterface,
- const QList<TestConfiguration *> selectedTests,
- const TestSettings &settings)
+void TestRunner::scheduleNext()
{
- const int timeout = settings.timeout;
- const bool omitRunConfigWarnings = settings.omitRunConfigWarn;
- QEventLoop eventLoop;
- int testCaseCount = 0;
- for (TestConfiguration *config : selectedTests) {
- config->completeTestInformation(TestRunMode::Run);
- if (config->project()) {
- testCaseCount += config->testCaseCount();
- if (!omitRunConfigWarnings && config->isGuessed()) {
- QString message = TestRunner::tr(
- "Project's run configuration was guessed for \"%1\".\n"
- "This might cause trouble during execution.\n"
- "(guessed from \"%2\")");
- message = message.arg(config->displayName()).arg(config->runConfigDisplayName());
- futureInterface.reportResult(
- TestResultPtr(new FaultyTestResult(Result::MessageWarn, message)));
- }
- } else {
- futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageWarn,
- TestRunner::tr("Project is null for \"%1\". Removing from test run.\n"
- "Check the test environment.").arg(config->displayName()))));
- }
+ QTC_ASSERT(!m_selectedTests.isEmpty(), onFinished(); return);
+ QTC_ASSERT(!m_currentConfig && !m_currentProcess, resetInternalPointers());
+ QTC_ASSERT(m_fakeFutureInterface, onFinished(); return);
+
+ m_currentConfig = m_selectedTests.dequeue();
+
+ QString commandFilePath = m_currentConfig->executableFilePath();
+ if (commandFilePath.isEmpty()) {
+ emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
+ tr("Executable path is empty. (%1)").arg(m_currentConfig->displayName()))));
+ delete m_currentConfig;
+ m_currentConfig = nullptr;
+ if (m_selectedTests.isEmpty())
+ onFinished();
+ else
+ onProcessFinished();
+ return;
}
+ if (!m_currentConfig->project())
+ onProcessFinished();
- QProcess testProcess;
- testProcess.setReadChannel(QProcess::StandardOutput);
+ m_currentProcess = new QProcess;
+ m_currentProcess->setReadChannel(QProcess::StandardOutput);
+ m_currentProcess->setProgram(commandFilePath);
- futureInterface.setProgressRange(0, testCaseCount);
- futureInterface.setProgressValue(0);
+ QTC_ASSERT(!m_currentOutputReader, delete m_currentOutputReader);
+ m_currentOutputReader = m_currentConfig->outputReader(*m_fakeFutureInterface, m_currentProcess);
+ QTC_ASSERT(m_currentOutputReader, onProcessFinished();return);
- for (const TestConfiguration *testConfiguration : selectedTests) {
- QString commandFilePath = testConfiguration->executableFilePath();
- if (commandFilePath.isEmpty()) {
- futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
- TestRunner::tr("Executable path is empty. (%1)")
- .arg(testConfiguration->displayName()))));
- continue;
- }
- testProcess.setProgram(commandFilePath);
-
- QScopedPointer<TestOutputReader> outputReader;
- outputReader.reset(testConfiguration->outputReader(futureInterface, &testProcess));
- QTC_ASSERT(outputReader, continue);
- TestRunner::connect(outputReader.data(), &TestOutputReader::newOutputAvailable,
- TestResultsPane::instance(), &TestResultsPane::addOutput);
- if (futureInterface.isCanceled())
- break;
-
- if (!testConfiguration->project())
- continue;
-
- QStringList omitted;
- testProcess.setArguments(testConfiguration->argumentsForTestRunner(&omitted));
- if (!omitted.isEmpty()) {
- const QString &details = constructOmittedDetailsString(omitted);
- futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageWarn,
- details.arg(testConfiguration->displayName()))));
- }
- testProcess.setWorkingDirectory(testConfiguration->workingDirectory());
- QProcessEnvironment environment = testConfiguration->environment().toProcessEnvironment();
- if (Utils::HostOsInfo::isWindowsHost())
- environment.insert("QT_LOGGING_TO_CONSOLE", "1");
- testProcess.setProcessEnvironment(environment);
- testProcess.start();
-
- bool ok = testProcess.waitForStarted();
- QTime executionTimer;
- executionTimer.start();
- bool canceledByTimeout = false;
- if (ok) {
- while (testProcess.state() == QProcess::Running) {
- if (executionTimer.elapsed() >= timeout) {
- canceledByTimeout = true;
- break;
- }
- if (futureInterface.isCanceled()) {
- testProcess.kill();
- testProcess.waitForFinished();
- return;
- }
- eventLoop.processEvents();
- }
- } else {
- futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
- TestRunner::tr("Failed to start test for project \"%1\".")
- .arg(testConfiguration->displayName()) + processInformation(testProcess)
- + rcInfo(testConfiguration))));
- }
- if (testProcess.exitStatus() == QProcess::CrashExit) {
- outputReader->reportCrash();
- futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
- TestRunner::tr("Test for project \"%1\" crashed.")
- .arg(testConfiguration->displayName()) + processInformation(testProcess)
- + rcInfo(testConfiguration))));
- } else if (!outputReader->hadValidOutput()) {
- futureInterface.reportResult(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
- TestRunner::tr("Test for project \"%1\" did not produce any expected output.")
- .arg(testConfiguration->displayName()) + processInformation(testProcess)
- + rcInfo(testConfiguration))));
- }
+ connect(m_currentOutputReader, &TestOutputReader::newOutputAvailable,
+ TestResultsPane::instance(), &TestResultsPane::addOutput);
- if (canceledByTimeout) {
- if (testProcess.state() != QProcess::NotRunning) {
- testProcess.kill();
- testProcess.waitForFinished();
- }
- futureInterface.reportResult(TestResultPtr(
- new FaultyTestResult(Result::MessageFatal, TestRunner::tr(
- "Test case canceled due to timeout.\nMaybe raise the timeout?"))));
+
+ QStringList omitted;
+ m_currentProcess->setArguments(m_currentConfig->argumentsForTestRunner(&omitted));
+ if (!omitted.isEmpty()) {
+ const QString &details = constructOmittedDetailsString(omitted);
+ emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageWarn,
+ details.arg(m_currentConfig->displayName()))));
+ }
+ m_currentProcess->setWorkingDirectory(m_currentConfig->workingDirectory());
+ QProcessEnvironment environment = m_currentConfig->environment().toProcessEnvironment();
+ if (Utils::HostOsInfo::isWindowsHost())
+ environment.insert("QT_LOGGING_TO_CONSOLE", "1");
+ const int timeout = AutotestPlugin::settings()->timeout;
+ if (timeout > 5 * 60 * 1000) // Qt5.5 introduced hard limit, Qt5.6.1 added env var to raise this
+ environment.insert("QTEST_FUNCTION_TIMEOUT", QString::number(timeout));
+ m_currentProcess->setProcessEnvironment(environment);
+
+ connect(m_currentProcess,
+ static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished),
+ this, &TestRunner::onProcessFinished);
+ QTimer::singleShot(timeout, m_currentProcess, [this]() { cancelCurrent(Timeout); });
+
+ m_currentProcess->start();
+ if (!m_currentProcess->waitForStarted()) {
+ emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
+ tr("Failed to start test for project \"%1\".").arg(m_currentConfig->displayName())
+ + processInformation(m_currentProcess) + rcInfo(m_currentConfig))));
+ }
+}
+
+void TestRunner::cancelCurrent(TestRunner::CancelReason reason)
+{
+ if (reason == UserCanceled) {
+ if (!m_fakeFutureInterface->isCanceled()) // depends on using the button / progress bar
+ m_fakeFutureInterface->reportCanceled();
+ }
+ if (m_currentProcess && m_currentProcess->state() != QProcess::NotRunning) {
+ m_currentProcess->kill();
+ m_currentProcess->waitForFinished();
+ }
+ if (reason == Timeout) {
+ emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
+ tr("Test case canceled due to timeout.\nMaybe raise the timeout?"))));
+ }
+}
+
+void TestRunner::onProcessFinished()
+{
+ m_fakeFutureInterface->setProgressValue(m_fakeFutureInterface->progressValue()
+ + m_currentConfig->testCaseCount());
+ if (!m_fakeFutureInterface->isCanceled()) {
+ if (m_currentProcess->exitStatus() == QProcess::CrashExit) {
+ m_currentOutputReader->reportCrash();
+ emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
+ tr("Test for project \"%1\" crashed.").arg(m_currentConfig->displayName())
+ + processInformation(m_currentProcess) + rcInfo(m_currentConfig))));
+ } else if (!m_currentOutputReader->hadValidOutput()) {
+ emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageFatal,
+ tr("Test for project \"%1\" did not produce any expected output.")
+ .arg(m_currentConfig->displayName()) + processInformation(m_currentProcess)
+ + rcInfo(m_currentConfig))));
}
}
- futureInterface.setProgressValue(testCaseCount);
+
+ resetInternalPointers();
+
+ if (!m_selectedTests.isEmpty() && !m_fakeFutureInterface->isCanceled()) {
+ scheduleNext();
+ } else {
+ m_fakeFutureInterface->reportFinished();
+ onFinished();
+ }
+}
+
+void TestRunner::resetInternalPointers()
+{
+ delete m_currentOutputReader;
+ delete m_currentProcess;
+ delete m_currentConfig;
+ m_currentOutputReader = nullptr;
+ m_currentProcess = nullptr;
+ m_currentConfig = nullptr;
}
void TestRunner::prepareToRunTests(TestRunMode mode)
{
+ QTC_ASSERT(!m_executingTests, return);
m_runMode = mode;
ProjectExplorer::Internal::ProjectExplorerSettings projectExplorerSettings =
ProjectExplorer::ProjectExplorerPlugin::projectExplorerSettings();
@@ -358,6 +359,32 @@ static ProjectExplorer::RunConfiguration *getRunConfiguration(const QString &dia
return runConfig;
}
+int TestRunner::precheckTestConfigurations()
+{
+ const bool omitWarnings = AutotestPlugin::settings()->omitRunConfigWarn;
+ int testCaseCount = 0;
+ for (TestConfiguration *config : m_selectedTests) {
+ config->completeTestInformation(TestRunMode::Run);
+ if (config->project()) {
+ testCaseCount += config->testCaseCount();
+ if (!omitWarnings && config->isGuessed()) {
+ QString message = tr(
+ "Project's run configuration was guessed for \"%1\".\n"
+ "This might cause trouble during execution.\n"
+ "(guessed from \"%2\")");
+ message = message.arg(config->displayName()).arg(config->runConfigDisplayName());
+ emit testResultReady(
+ TestResultPtr(new FaultyTestResult(Result::MessageWarn, message)));
+ }
+ } else {
+ emit testResultReady(TestResultPtr(new FaultyTestResult(Result::MessageWarn,
+ tr("Project is null for \"%1\". Removing from test run.\n"
+ "Check the test environment.").arg(config->displayName()))));
+ }
+ }
+ return testCaseCount;
+}
+
void TestRunner::runTests()
{
QList<TestConfiguration *> toBeRemoved;
@@ -381,10 +408,17 @@ void TestRunner::runTests()
return;
}
- QFuture<TestResultPtr> future = Utils::runAsync(&performTestRun, m_selectedTests,
- *AutotestPlugin::settings());
+ int testCaseCount = precheckTestConfigurations();
+
+ // Fake future interface - destruction will be handled by QFuture/QFutureWatcher
+ m_fakeFutureInterface = new QFutureInterface<TestResultPtr>(QFutureInterfaceBase::Running);
+ QFuture<TestResultPtr> future = m_fakeFutureInterface->future();
+ m_fakeFutureInterface->setProgressRange(0, testCaseCount);
+ m_fakeFutureInterface->setProgressValue(0);
m_futureWatcher.setFuture(future);
+
Core::ProgressManager::addTask(future, tr("Running Tests"), Autotest::Constants::TASK_INDEX);
+ scheduleNext();
}
static void processOutput(TestOutputReader *outputreader, const QString &msg,
@@ -552,6 +586,11 @@ void TestRunner::buildFinished(bool success)
void TestRunner::onFinished()
{
+ // if we've been canceled and we still have test configurations queued just throw them away
+ qDeleteAll(m_selectedTests);
+ m_selectedTests.clear();
+
+ m_fakeFutureInterface = nullptr;
m_executingTests = false;
emit testRunFinished();
}
diff --git a/src/plugins/autotest/testrunner.h b/src/plugins/autotest/testrunner.h
index 0638401ca0..95039b47ac 100644
--- a/src/plugins/autotest/testrunner.h
+++ b/src/plugins/autotest/testrunner.h
@@ -31,12 +31,13 @@
#include <QDialog>
#include <QFutureWatcher>
#include <QObject>
-#include <QProcess>
+#include <QQueue>
QT_BEGIN_NAMESPACE
class QComboBox;
class QDialogButtonBox;
class QLabel;
+class QProcess;
QT_END_NAMESPACE
namespace ProjectExplorer {
@@ -51,6 +52,8 @@ class TestRunner : public QObject
Q_OBJECT
public:
+ enum CancelReason { UserCanceled, Timeout };
+
static TestRunner* instance();
~TestRunner();
@@ -71,14 +74,24 @@ private:
void buildFinished(bool success);
void onFinished();
+ int precheckTestConfigurations();
+ void scheduleNext();
+ void cancelCurrent(CancelReason reason);
+ void onProcessFinished();
+ void resetInternalPointers();
+
void runTests();
void debugTests();
void runOrDebugTests();
explicit TestRunner(QObject *parent = 0);
QFutureWatcher<TestResultPtr> m_futureWatcher;
- QList<TestConfiguration *> m_selectedTests;
- bool m_executingTests;
+ QFutureInterface<TestResultPtr> *m_fakeFutureInterface = nullptr;
+ QQueue<TestConfiguration *> m_selectedTests;
+ bool m_executingTests = false;
+ TestConfiguration *m_currentConfig = nullptr;
+ QProcess *m_currentProcess = nullptr;
+ TestOutputReader *m_currentOutputReader = nullptr;
TestRunMode m_runMode = TestRunMode::Run;
// temporarily used if building before running is necessary
diff --git a/src/plugins/clangcodemodel/clangtextmark.cpp b/src/plugins/clangcodemodel/clangtextmark.cpp
index fbe08cb14d..51447e9147 100644
--- a/src/plugins/clangcodemodel/clangtextmark.cpp
+++ b/src/plugins/clangcodemodel/clangtextmark.cpp
@@ -83,8 +83,8 @@ ClangTextMark::ClangTextMark(const FileName &fileName,
updateIcon();
if (fullVisualization) {
setLineAnnotation(Utils::diagnosticCategoryPrefixRemoved(diagnostic.text.toString()));
- setColor(warning ? ::Utils::Theme::ClangCodeModel_Warning_TextMarkColor
- : ::Utils::Theme::ClangCodeModel_Error_TextMarkColor);
+ setColor(warning ? ::Utils::Theme::CodeModel_Warning_TextMarkColor
+ : ::Utils::Theme::CodeModel_Error_TextMarkColor);
}
}
diff --git a/src/plugins/clangtools/clangtidyclazytool.cpp b/src/plugins/clangtools/clangtidyclazytool.cpp
index fdf6a9adc6..2b977c4548 100644
--- a/src/plugins/clangtools/clangtidyclazytool.cpp
+++ b/src/plugins/clangtools/clangtidyclazytool.cpp
@@ -161,6 +161,10 @@ ClangTidyClazyTool::ClangTidyClazyTool()
// Apply fixits button
m_applyFixitsButton = new QToolButton;
m_applyFixitsButton->setText(tr("Apply Fixits"));
+ m_applyFixitsButton->setEnabled(false);
+ connect(m_diagnosticModel,
+ &ClangToolsDiagnosticModel::fixItsToApplyCountChanged,
+ [this](int c) { m_applyFixitsButton->setEnabled(c); });
connect(m_applyFixitsButton, &QToolButton::clicked, [this]() {
QVector<Diagnostic> diagnosticsWithFixits;
diff --git a/src/plugins/clangtools/clangtools.qbs b/src/plugins/clangtools/clangtools.qbs
index b9363f55a9..f947fb6115 100644
--- a/src/plugins/clangtools/clangtools.qbs
+++ b/src/plugins/clangtools/clangtools.qbs
@@ -6,6 +6,7 @@ QtcPlugin {
Depends { name: "Debugger" }
Depends { name: "Core" }
+ Depends { name: "TextEditor" }
Depends { name: "CppTools" }
Depends { name: "ExtensionSystem" }
Depends { name: "ProjectExplorer" }
diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp
index 1ffc3351e5..ddfc4e4bcf 100644
--- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp
+++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp
@@ -34,7 +34,6 @@
#include <utils/qtcassert.h>
#include <utils/utilsicons.h>
-#include <QCoreApplication>
#include <QFileInfo>
#include <cmath>
@@ -61,8 +60,13 @@ ClangToolsDiagnosticModel::ClangToolsDiagnosticModel(QObject *parent)
void ClangToolsDiagnosticModel::addDiagnostics(const QList<Diagnostic> &diagnostics)
{
- foreach (const Diagnostic &d, diagnostics)
- rootItem()->appendChild(new DiagnosticItem(d));
+ const auto onFixItChanged = [this](bool checked){
+ m_fixItsToApplyCount += checked ? +1 : -1;
+ emit fixItsToApplyCountChanged(m_fixItsToApplyCount);
+ };
+
+ for (const Diagnostic &d : diagnostics)
+ rootItem()->appendChild(new DiagnosticItem(d, onFixItChanged));
}
QList<Diagnostic> ClangToolsDiagnosticModel::diagnostics() const
@@ -199,7 +203,9 @@ static QString fullText(const Diagnostic &diagnostic)
}
-DiagnosticItem::DiagnosticItem(const Diagnostic &diag) : m_diagnostic(diag)
+DiagnosticItem::DiagnosticItem(const Diagnostic &diag, const OnCheckedFixit &onCheckedFixit)
+ : m_diagnostic(diag)
+ , m_onCheckedFixit(onCheckedFixit)
{
// Don't show explaining steps if they add no information.
if (diag.explainingSteps.count() == 1) {
@@ -214,21 +220,15 @@ DiagnosticItem::DiagnosticItem(const Diagnostic &diag) : m_diagnostic(diag)
Qt::ItemFlags DiagnosticItem::flags(int column) const
{
- if (column == DiagnosticView::FixItColumn && m_diagnostic.hasFixits)
- return TreeItem::flags(column) | Qt::ItemIsUserCheckable;
- return TreeItem::flags(column);
-}
-
-static QVariant locationData(int role, const Debugger::DiagnosticLocation &location)
-{
- switch (role) {
- case Debugger::DetailedErrorView::LocationRole:
- return QVariant::fromValue(location);
- case Qt::ToolTipRole:
- return location.filePath.isEmpty() ? QVariant() : QVariant(location.filePath);
- default:
- return QVariant();
+ const Qt::ItemFlags itemFlags = TreeItem::flags(column);
+ if (column == DiagnosticView::FixItColumn) {
+ if (m_diagnostic.hasFixits)
+ return itemFlags | Qt::ItemIsUserCheckable;
+ else
+ return itemFlags & ~Qt::ItemIsEnabled;
}
+
+ return itemFlags;
}
static QVariant iconData(const QString &type)
@@ -247,7 +247,7 @@ static QVariant iconData(const QString &type)
QVariant DiagnosticItem::data(int column, int role) const
{
if (column == Debugger::DetailedErrorView::LocationColumn)
- return locationData(role, m_diagnostic.location);
+ return Debugger::DetailedErrorView::locationData(role, m_diagnostic.location);
if (column == DiagnosticView::FixItColumn) {
if (role == Qt::CheckStateRole)
@@ -277,6 +277,8 @@ bool DiagnosticItem::setData(int column, const QVariant &data, int role)
if (column == DiagnosticView::FixItColumn && role == Qt::CheckStateRole) {
m_applyFixits = data.value<Qt::CheckState>() == Qt::Checked ? true : false;
update();
+ if (m_onCheckedFixit)
+ m_onCheckedFixit(m_applyFixits);
return true;
}
@@ -290,7 +292,7 @@ ExplainingStepItem::ExplainingStepItem(const ExplainingStep &step) : m_step(step
QVariant ExplainingStepItem::data(int column, int role) const
{
if (column == Debugger::DetailedErrorView::LocationColumn)
- return locationData(role, m_step.location);
+ return Debugger::DetailedErrorView::locationData(role, m_step.location);
if (column == DiagnosticView::FixItColumn)
return QVariant();
diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.h b/src/plugins/clangtools/clangtoolsdiagnosticmodel.h
index 0fbc99a5b7..61aa6055c5 100644
--- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.h
+++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.h
@@ -35,6 +35,8 @@
#include <QPointer>
#include <QSortFilterProxyModel>
+#include <functional>
+
namespace ProjectExplorer { class Project; }
namespace ClangTools {
@@ -43,7 +45,8 @@ namespace Internal {
class DiagnosticItem : public Utils::TreeItem
{
public:
- DiagnosticItem(const Diagnostic &diag);
+ using OnCheckedFixit = std::function<void(bool)>;
+ DiagnosticItem(const Diagnostic &diag, const OnCheckedFixit &onCheckedFixit);
Diagnostic diagnostic() const { return m_diagnostic; }
bool applyFixits() const { return m_applyFixits; }
@@ -56,6 +59,7 @@ private:
private:
const Diagnostic m_diagnostic;
bool m_applyFixits = false;
+ OnCheckedFixit m_onCheckedFixit;
};
class ClangToolsDiagnosticModel : public Utils::TreeModel<>
@@ -71,6 +75,12 @@ public:
enum ItemRole {
DiagnosticRole = Debugger::DetailedErrorView::FullTextRole + 1
};
+
+signals:
+ void fixItsToApplyCountChanged(int count);
+
+private:
+ int m_fixItsToApplyCount = 0;
};
class DiagnosticFilterModel : public QSortFilterProxyModel
diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
index 6af10c3553..27ac6a4504 100644
--- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp
+++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
@@ -196,6 +196,12 @@ void BuildDirManager::setParametersAndRequestParse(const BuildDirParameters &par
int newReaderReparseOptions,
int existingReaderReparseOptions)
{
+ if (!parameters.cmakeTool) {
+ TaskHub::addTask(Task::Error,
+ tr("The kit needs to define a CMake tool to parse this project."),
+ ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
+ return;
+ }
QTC_ASSERT(parameters.isValid(), return);
if (m_reader)
diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp
index 8432551696..097840072f 100644
--- a/src/plugins/cmakeprojectmanager/servermodereader.cpp
+++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp
@@ -279,8 +279,7 @@ static std::vector<std::unique_ptr<FileNode>> &&
removeKnownNodes(const QSet<Utils::FileName> &knownFiles,
std::vector<std::unique_ptr<FileNode>> &&files)
{
- std::remove_if(std::begin(files), std::end(files),
- [&knownFiles](const std::unique_ptr<FileNode> &n) {
+ Utils::erase(files, [&knownFiles](const std::unique_ptr<FileNode> &n) {
return knownFiles.contains(n->filePath());
});
return std::move(files);
diff --git a/src/plugins/cppeditor/cppcodemodelinspectordialog.ui b/src/plugins/cppeditor/cppcodemodelinspectordialog.ui
index 9eb8bdb1ba..7cb63c005b 100644
--- a/src/plugins/cppeditor/cppcodemodelinspectordialog.ui
+++ b/src/plugins/cppeditor/cppcodemodelinspectordialog.ui
@@ -19,6 +19,108 @@
<property name="currentIndex">
<number>0</number>
</property>
+ <widget class="QWidget" name="tab_2">
+ <attribute name="title">
+ <string notr="true">&amp;Project Parts</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_12">
+ <item>
+ <widget class="QSplitter" name="projectPartsSplitter">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <widget class="QTabWidget" name="projectPartTab">
+ <property name="currentIndex">
+ <number>3</number>
+ </property>
+ <widget class="QWidget" name="tab_17">
+ <attribute name="title">
+ <string notr="true">&amp;General</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_9">
+ <item>
+ <widget class="QTreeView" name="partGeneralView"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_13">
+ <attribute name="title">
+ <string notr="true">Project &amp;Files</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_14">
+ <item>
+ <widget class="QTreeView" name="projectFilesView"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_14">
+ <attribute name="title">
+ <string notr="true">&amp;Defines</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_19">
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string notr="true">Toolchain Defines</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_13">
+ <item>
+ <widget class="QPlainTextEdit" name="partToolchainDefinesEdit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string notr="true">Project Defines</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_15">
+ <item>
+ <widget class="QPlainTextEdit" name="partProjectDefinesEdit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_15">
+ <attribute name="title">
+ <string notr="true">&amp;Header Paths</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_16">
+ <item>
+ <widget class="QTreeView" name="projectHeaderPathsView"/>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="tab_16">
+ <attribute name="title">
+ <string notr="true">Pre&amp;compiled Headers</string>
+ </attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_18">
+ <item>
+ <widget class="QPlainTextEdit" name="partPrecompiledHeadersEdit">
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
<widget class="QWidget" name="tab">
<attribute name="title">
<string notr="true">&amp;Snapshots and Documents</string>
@@ -182,108 +284,6 @@
</item>
</layout>
</widget>
- <widget class="QWidget" name="tab_2">
- <attribute name="title">
- <string notr="true">&amp;Project Parts</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_12">
- <item>
- <widget class="QSplitter" name="projectPartsSplitter">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <widget class="QTabWidget" name="projectPartTab">
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="tab_17">
- <attribute name="title">
- <string notr="true">&amp;General</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_9">
- <item>
- <widget class="QTreeView" name="partGeneralView"/>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_13">
- <attribute name="title">
- <string notr="true">Project &amp;Files</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_14">
- <item>
- <widget class="QTreeView" name="projectFilesView"/>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_14">
- <attribute name="title">
- <string notr="true">&amp;Defines</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_19">
- <item>
- <widget class="QGroupBox" name="groupBox">
- <property name="title">
- <string notr="true">Toolchain Defines</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_13">
- <item>
- <widget class="QPlainTextEdit" name="partToolchainDefinesEdit">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_2">
- <property name="title">
- <string notr="true">Project Defines</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_15">
- <item>
- <widget class="QPlainTextEdit" name="partProjectDefinesEdit">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_15">
- <attribute name="title">
- <string notr="true">&amp;Header Paths</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_16">
- <item>
- <widget class="QTreeView" name="projectHeaderPathsView"/>
- </item>
- </layout>
- </widget>
- <widget class="QWidget" name="tab_16">
- <attribute name="title">
- <string notr="true">Pre&amp;compiled Headers</string>
- </attribute>
- <layout class="QVBoxLayout" name="verticalLayout_18">
- <item>
- <widget class="QPlainTextEdit" name="partPrecompiledHeadersEdit">
- <property name="readOnly">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </widget>
- </widget>
- </item>
- </layout>
- </widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string notr="true">&amp;Working Copy</string>
diff --git a/src/plugins/debugger/analyzer/detailederrorview.cpp b/src/plugins/debugger/analyzer/detailederrorview.cpp
index a5ee070a1a..85ea430f34 100644
--- a/src/plugins/debugger/analyzer/detailederrorview.cpp
+++ b/src/plugins/debugger/analyzer/detailederrorview.cpp
@@ -41,91 +41,14 @@
#include <QHeaderView>
#include <QMenu>
#include <QPainter>
-#include <QSharedPointer>
-#include <QTextDocument>
namespace Debugger {
-namespace Internal {
-
-class DetailedErrorDelegate : public QStyledItemDelegate
-{
- Q_OBJECT
-
-public:
- DetailedErrorDelegate(QTreeView *parent) : QStyledItemDelegate(parent) { }
-
-private:
- QString actualText(const QModelIndex &index) const
- {
- const auto location = index.model()->data(index, DetailedErrorView::LocationRole)
- .value<DiagnosticLocation>();
- return location.isValid()
- ? QString::fromLatin1("<a href=\"file://%1\">%2:%3:%4")
- .arg(location.filePath, QFileInfo(location.filePath).fileName())
- .arg(location.line)
- .arg(location.column)
- : QString();
- }
-
- using DocConstPtr = QSharedPointer<const QTextDocument>;
- DocConstPtr document(const QStyleOptionViewItem &option) const
- {
- const auto doc = QSharedPointer<QTextDocument>::create();
- doc->setHtml(option.text);
- doc->setTextWidth(option.rect.width());
- doc->setDocumentMargin(0);
- return doc;
- }
-
- QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
- {
- QStyleOptionViewItem opt = option;
- opt.text = actualText(index);
- initStyleOption(&opt, index);
-
- const DocConstPtr doc = document(opt);
- return QSize(doc->idealWidth(), doc->size().height());
- }
-
- void paint(QPainter *painter, const QStyleOptionViewItem &option,
- const QModelIndex &index) const override
- {
- QStyleOptionViewItem opt = option;
- initStyleOption(&opt, index);
-
- QStyle *style = opt.widget? opt.widget->style() : QApplication::style();
-
- // Painting item without text
- opt.text.clear();
- style->drawControl(QStyle::CE_ItemViewItem, &opt, painter);
- opt.text = actualText(index);
-
- QAbstractTextDocumentLayout::PaintContext ctx;
-
- // Highlighting text if item is selected
- if (opt.state & QStyle::State_Selected) {
- ctx.palette.setColor(QPalette::Text, opt.palette.color(QPalette::Active,
- QPalette::HighlightedText));
- }
-
- QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &opt);
- painter->save();
- painter->translate(textRect.topLeft());
- painter->setClipRect(textRect.translated(-textRect.topLeft()));
- document(opt)->documentLayout()->draw(painter, ctx);
- painter->restore();
- }
-};
-
-} // namespace Internal
-
DetailedErrorView::DetailedErrorView(QWidget *parent) :
QTreeView(parent),
m_copyAction(new QAction(this))
{
header()->setSectionResizeMode(QHeaderView::ResizeToContents);
- setItemDelegateForColumn(LocationColumn, new Internal::DetailedErrorDelegate(this));
m_copyAction->setText(tr("Copy"));
m_copyAction->setIcon(Utils::Icons::COPY.icon());
@@ -187,6 +110,31 @@ void DetailedErrorView::goBack()
setCurrentRow(prevRow >= 0 ? prevRow : rowCount() - 1);
}
+QVariant DetailedErrorView::locationData(int role, const DiagnosticLocation &location)
+{
+ switch (role) {
+ case Debugger::DetailedErrorView::LocationRole:
+ return QVariant::fromValue(location);
+ case Qt::DisplayRole:
+ return location.isValid() ? QString::fromLatin1("%1:%2:%3")
+ .arg(QFileInfo(location.filePath).fileName())
+ .arg(location.line)
+ .arg(location.column)
+ : QString();
+ case Qt::ToolTipRole:
+ return location.filePath.isEmpty() ? QVariant() : QVariant(location.filePath);
+ case Qt::FontRole: {
+ QFont font = QApplication::font();
+ font.setUnderline(true);
+ return font;
+ }
+ case Qt::ForegroundRole:
+ return QApplication::palette().link().color();
+ default:
+ return QVariant();
+ }
+}
+
int DetailedErrorView::rowCount() const
{
return model() ? model()->rowCount() : 0;
@@ -218,5 +166,3 @@ void DetailedErrorView::setCurrentRow(int row)
}
} // namespace Debugger
-
-#include "detailederrorview.moc"
diff --git a/src/plugins/debugger/analyzer/detailederrorview.h b/src/plugins/debugger/analyzer/detailederrorview.h
index 1614605412..845bbee362 100644
--- a/src/plugins/debugger/analyzer/detailederrorview.h
+++ b/src/plugins/debugger/analyzer/detailederrorview.h
@@ -32,6 +32,8 @@
namespace Debugger {
+class DiagnosticLocation;
+
class DEBUGGER_EXPORT DetailedErrorView : public QTreeView
{
Q_OBJECT
@@ -53,6 +55,8 @@ public:
LocationColumn,
};
+ static QVariant locationData(int role, const DiagnosticLocation &location);
+
private:
void contextMenuEvent(QContextMenuEvent *e) override;
void currentChanged(const QModelIndex &current, const QModelIndex &previous) override;
diff --git a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp
index 9d016400fb..f1e893cd1f 100644
--- a/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp
+++ b/src/plugins/diffeditor/sidebysidediffeditorwidget.cpp
@@ -179,6 +179,7 @@ SideDiffEditorWidget::SideDiffEditorWidget(QWidget *parent)
connect(documentLayout, &TextDocumentLayout::foldChanged,
this, &SideDiffEditorWidget::foldChanged);
setCodeFoldingSupported(true);
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
}
void SideDiffEditorWidget::saveState()
@@ -714,6 +715,13 @@ SideBySideDiffEditorWidget::SideBySideDiffEditorWidget(QWidget *parent)
connect(m_rightEditor, &SideDiffEditorWidget::foldChanged,
m_leftEditor, &SideDiffEditorWidget::setFolded);
+ connect(m_leftEditor->horizontalScrollBar(), &QAbstractSlider::rangeChanged,
+ this, &SideBySideDiffEditorWidget::syncHorizontalScrollBarPolicy);
+
+ connect(m_rightEditor->horizontalScrollBar(), &QAbstractSlider::rangeChanged,
+ this, &SideBySideDiffEditorWidget::syncHorizontalScrollBarPolicy);
+
+ syncHorizontalScrollBarPolicy();
m_splitter = new MiniSplitter(this);
m_splitter->addWidget(m_leftEditor);
@@ -1133,6 +1141,18 @@ void SideBySideDiffEditorWidget::rightCursorPositionChanged()
rightHSliderChanged();
}
+void SideBySideDiffEditorWidget::syncHorizontalScrollBarPolicy()
+{
+ const bool alwaysOn = m_leftEditor->horizontalScrollBar()->maximum()
+ || m_rightEditor->horizontalScrollBar()->maximum();
+ const Qt::ScrollBarPolicy newPolicy = alwaysOn
+ ? Qt::ScrollBarAlwaysOn : Qt::ScrollBarAsNeeded;
+ if (m_leftEditor->horizontalScrollBarPolicy() != newPolicy)
+ m_leftEditor->setHorizontalScrollBarPolicy(newPolicy);
+ if (m_rightEditor->horizontalScrollBarPolicy() != newPolicy)
+ m_rightEditor->setHorizontalScrollBarPolicy(newPolicy);
+}
+
void SideBySideDiffEditorWidget::handlePositionChange(SideDiffEditorWidget *source, SideDiffEditorWidget *dest)
{
if (m_controller.m_ignoreCurrentIndexChange)
diff --git a/src/plugins/diffeditor/sidebysidediffeditorwidget.h b/src/plugins/diffeditor/sidebysidediffeditorwidget.h
index c315cec975..ee6f5f0eb7 100644
--- a/src/plugins/diffeditor/sidebysidediffeditorwidget.h
+++ b/src/plugins/diffeditor/sidebysidediffeditorwidget.h
@@ -95,6 +95,7 @@ private:
void rightHSliderChanged();
void leftCursorPositionChanged();
void rightCursorPositionChanged();
+ void syncHorizontalScrollBarPolicy();
void handlePositionChange(SideDiffEditorWidget *source, SideDiffEditorWidget *dest);
void syncCursor(SideDiffEditorWidget *source, SideDiffEditorWidget *dest);
diff --git a/src/plugins/projectexplorer/buildstep.cpp b/src/plugins/projectexplorer/buildstep.cpp
index 265a718f14..232a95483a 100644
--- a/src/plugins/projectexplorer/buildstep.cpp
+++ b/src/plugins/projectexplorer/buildstep.cpp
@@ -337,22 +337,4 @@ BuildStep *BuildStepFactory::restore(BuildStepList *parent, const QVariantMap &m
return bs;
}
-BuildStep *BuildStepFactory::clone(BuildStepList *parent, BuildStep *product)
-{
- if ((m_info.flags & BuildStepInfo::Unclonable) != 0)
- return nullptr;
- if (m_info.id != product->id())
- return nullptr;
- BuildStep *bs = m_info.creator(parent);
- if (!bs)
- return nullptr;
- const QVariantMap map = product->toMap();
- if (!bs->fromMap(map)) {
- QTC_CHECK(false);
- delete bs;
- return nullptr;
- }
- return bs;
-}
-
} // ProjectExplorer
diff --git a/src/plugins/projectexplorer/buildstep.h b/src/plugins/projectexplorer/buildstep.h
index 840e31ee21..dd68e52216 100644
--- a/src/plugins/projectexplorer/buildstep.h
+++ b/src/plugins/projectexplorer/buildstep.h
@@ -132,7 +132,6 @@ public:
Core::Id stepId() const;
BuildStep *create(BuildStepList *parent, Core::Id id);
BuildStep *restore(BuildStepList *parent, const QVariantMap &map);
- BuildStep *clone(BuildStepList *parent, BuildStep *product);
virtual bool canHandle(BuildStepList *bsl) const;
diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp
index e9d5f3f83c..9c25e8d3b5 100644
--- a/src/plugins/projectexplorer/project.cpp
+++ b/src/plugins/projectexplorer/project.cpp
@@ -701,6 +701,11 @@ void Project::createTargetFromMap(const QVariantMap &map, int index)
Target *t = restoreTarget(targetMap);
if (!t)
return;
+ if (t->runConfigurations().isEmpty() && t->buildConfigurations().isEmpty()) {
+ delete t;
+ return;
+ }
+
addTarget(t);
}
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp
index 1584d88255..67183e1555 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorcontextobject.cpp
@@ -33,6 +33,7 @@
#include <coreplugin/messagebox.h>
#include <utils/algorithm.h>
+#include <utils/qtcassert.h>
#include <QQmlContext>
@@ -135,15 +136,13 @@ QStringList PropertyEditorContextObject::autoComplete(const QString &text, int p
void PropertyEditorContextObject::toogleExportAlias()
{
- if (!m_model || !m_model->rewriterView())
- return;
+ QTC_ASSERT(m_model && m_model->rewriterView(), return);
/* Ideally we should not missuse the rewriterView
* If we add more code here we have to forward the property editor view */
RewriterView *rewriterView = m_model->rewriterView();
- if (rewriterView->selectedModelNodes().isEmpty())
- return;
+ QTC_ASSERT(!rewriterView->selectedModelNodes().isEmpty(), return);
const ModelNode selectedNode = rewriterView->selectedModelNodes().constFirst();
@@ -174,15 +173,13 @@ void PropertyEditorContextObject::toogleExportAlias()
void PropertyEditorContextObject::changeTypeName(const QString &typeName)
{
- if (!m_model || !m_model->rewriterView())
- return;
+ QTC_ASSERT(m_model && m_model->rewriterView(), return);
/* Ideally we should not missuse the rewriterView
* If we add more code here we have to forward the property editor view */
RewriterView *rewriterView = m_model->rewriterView();
- if (rewriterView->selectedModelNodes().isEmpty())
- return;
+ QTC_ASSERT(!rewriterView->selectedModelNodes().isEmpty(), return);
ModelNode selectedNode = rewriterView->selectedModelNodes().constFirst();
@@ -210,15 +207,13 @@ void PropertyEditorContextObject::changeTypeName(const QString &typeName)
void PropertyEditorContextObject::insertKeyframe(const QString &propertyName)
{
- if (!m_model || !m_model->rewriterView())
- return;
+ QTC_ASSERT(m_model && m_model->rewriterView(), return);
/* Ideally we should not missuse the rewriterView
* If we add more code here we have to forward the property editor view */
RewriterView *rewriterView = m_model->rewriterView();
- if (rewriterView->selectedModelNodes().isEmpty())
- return;
+ QTC_ASSERT(!rewriterView->selectedModelNodes().isEmpty(), return);
ModelNode selectedNode = rewriterView->selectedModelNodes().constFirst();
diff --git a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
index 2cb48df217..6ac07433a4 100644
--- a/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
+++ b/src/plugins/qmldesigner/components/propertyeditor/propertyeditorqmlbackend.cpp
@@ -271,6 +271,8 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q
if (qmlObjectNode.isValid()) {
+ m_contextObject->setModel(propertyEditor->model());
+
qCInfo(propertyEditorBenchmark) << Q_FUNC_INFO;
QTime time;
diff --git a/src/plugins/qmljseditor/qmljstextmark.cpp b/src/plugins/qmljseditor/qmljstextmark.cpp
index 542450a9d4..4eac11b2c6 100644
--- a/src/plugins/qmljseditor/qmljstextmark.cpp
+++ b/src/plugins/qmljseditor/qmljstextmark.cpp
@@ -90,8 +90,8 @@ void QmlJSTextMark::init(bool warning, const QString message)
{
setIcon(warning ? Utils::Icons::CODEMODEL_WARNING.icon()
: Utils::Icons::CODEMODEL_ERROR.icon());
- setColor(warning ? Utils::Theme::ClangCodeModel_Warning_TextMarkColor
- : Utils::Theme::ClangCodeModel_Error_TextMarkColor);
+ setColor(warning ? Utils::Theme::CodeModel_Warning_TextMarkColor
+ : Utils::Theme::CodeModel_Error_TextMarkColor);
setDefaultToolTip(warning ? QApplication::translate("QmlJS Code Model Marks", "Code Model Warning")
: QApplication::translate("QmlJS Code Model Marks", "Code Model Error"));
setToolTip(message);
diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp
index 5a8486116b..ab10ab7d0b 100644
--- a/src/plugins/texteditor/texteditor.cpp
+++ b/src/plugins/texteditor/texteditor.cpp
@@ -5363,15 +5363,13 @@ void TextEditorWidgetPrivate::updateCurrentLineInScrollbar()
{
if (m_highlightCurrentLine && m_highlightScrollBarController) {
m_highlightScrollBarController->removeHighlights(Constants::SCROLL_BAR_CURRENT_LINE);
- if (m_highlightScrollBarController->scrollBar()->maximum() > 0) {
- const QTextCursor &tc = q->textCursor();
- if (QTextLayout *layout = tc.block().layout()) {
- const int pos = q->textCursor().block().firstLineNumber() +
- layout->lineForTextPosition(tc.positionInBlock()).lineNumber();
- m_highlightScrollBarController->addHighlight({Constants::SCROLL_BAR_CURRENT_LINE, pos,
- Theme::TextEditor_CurrentLine_ScrollBarColor,
- Highlight::HighestPriority});
- }
+ const QTextCursor &tc = q->textCursor();
+ if (QTextLayout *layout = tc.block().layout()) {
+ const int pos = q->textCursor().block().firstLineNumber() +
+ layout->lineForTextPosition(tc.positionInBlock()).lineNumber();
+ m_highlightScrollBarController->addHighlight({Constants::SCROLL_BAR_CURRENT_LINE, pos,
+ Theme::TextEditor_CurrentLine_ScrollBarColor,
+ Highlight::HighestPriority});
}
}
}
diff --git a/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp b/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp
index f574f89c24..49e668176d 100644
--- a/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp
+++ b/src/plugins/valgrind/xmlprotocol/errorlistmodel.cpp
@@ -173,24 +173,16 @@ ErrorItem::ErrorItem(const ErrorListModel *model, const Error &error)
}
}
-static QVariant location(const Frame &frame, int role)
+static QVariant locationData(int role, const Frame &frame)
{
- switch (role) {
- case Debugger::DetailedErrorView::LocationRole:
- return QVariant::fromValue(Debugger::DiagnosticLocation(frame.filePath(), frame.line(), 0));
- case Qt::ToolTipRole:
- return frame.filePath().isEmpty() ? QVariant() : QVariant(frame.filePath());
- default:
- return QVariant();
- }
+ const Debugger::DiagnosticLocation location(frame.filePath(), frame.line(), 0);
+ return Debugger::DetailedErrorView::locationData(role, location);
}
QVariant ErrorItem::data(int column, int role) const
{
- if (column == Debugger::DetailedErrorView::LocationColumn) {
- const Frame frame = m_model->findRelevantFrame(m_error);
- return location(frame, role);
- }
+ if (column == Debugger::DetailedErrorView::LocationColumn)
+ return locationData(role, m_model->findRelevantFrame(m_error));
// DiagnosticColumn
switch (role) {
@@ -243,7 +235,7 @@ QVariant StackItem::data(int column, int role) const
{
const ErrorItem * const errorItem = getErrorItem();
if (column == Debugger::DetailedErrorView::LocationColumn)
- return location(errorItem->modelPrivate()->findRelevantFrame(errorItem->error()), role);
+ return locationData(role, errorItem->modelPrivate()->findRelevantFrame(errorItem->error()));
// DiagnosticColumn
switch (role) {
@@ -271,7 +263,7 @@ FrameItem::FrameItem(const Frame &frame) : m_frame(frame)
QVariant FrameItem::data(int column, int role) const
{
if (column == Debugger::DetailedErrorView::LocationColumn)
- return location(m_frame, role);
+ return locationData(role, m_frame);
// DiagnosticColumn
switch (role) {
diff --git a/src/shared/clang/clang_installation.pri b/src/shared/clang/clang_installation.pri
index 34132a6b53..b9cc4c9704 100644
--- a/src/shared/clang/clang_installation.pri
+++ b/src/shared/clang/clang_installation.pri
@@ -101,10 +101,10 @@ isEmpty(LLVM_VERSION) {
$$llvmWarningOrError(\
"Cannot determine clang version. Set LLVM_INSTALL_DIR to build the Clang Code Model",\
"LLVM_INSTALL_DIR does not contain a valid llvm-config, candidate: $$llvm_config")
-} else:!versionIsAtLeast($$LLVM_VERSION, 5, 0, 0): {
+} else:!versionIsAtLeast($$LLVM_VERSION, 6, 0, 0): {
# CLANG-UPGRADE-CHECK: Adapt minimum version numbers.
$$llvmWarningOrError(\
- "LLVM/Clang version >= 5.0.0 required, version provided: $$LLVM_VERSION")
+ "LLVM/Clang version >= 6.0.0 required, version provided: $$LLVM_VERSION")
LLVM_VERSION =
} else {
LLVM_LIBDIR = $$quote($$system($$llvm_config --libdir, lines))
@@ -141,11 +141,11 @@ isEmpty(LLVM_VERSION) {
QTC_NO_CLANG_LIBTOOLING=$$(QTC_NO_CLANG_LIBTOOLING)
isEmpty(QTC_NO_CLANG_LIBTOOLING) {
QTC_FORCE_CLANG_LIBTOOLING = $$(QTC_FORCE_CLANG_LIBTOOLING)
- versionIsEqual($$LLVM_VERSION, 5, 0)|!isEmpty(QTC_FORCE_CLANG_LIBTOOLING) {
+ versionIsEqual($$LLVM_VERSION, 6, 0)|!isEmpty(QTC_FORCE_CLANG_LIBTOOLING) {
!contains(QMAKE_DEFAULT_LIBDIRS, $$LLVM_LIBDIR): LIBTOOLING_LIBS = -L$${LLVM_LIBDIR}
LIBTOOLING_LIBS += $$CLANGTOOLING_LIBS $$LLVM_STATIC_LIBS
} else {
- warning("Clang LibTooling is disabled because only version 5.0 is supported.")
+ warning("Clang LibTooling is disabled because only version 6.0 is supported.")
}
} else {
warning("Clang LibTooling is disabled.")
diff --git a/src/tools/clangbackend/source/clangtype.cpp b/src/tools/clangbackend/source/clangtype.cpp
index faa97a437e..633df3e596 100644
--- a/src/tools/clangbackend/source/clangtype.cpp
+++ b/src/tools/clangbackend/source/clangtype.cpp
@@ -163,8 +163,7 @@ static const char *builtinTypeToText(CXTypeKind kind)
// https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html
case CXType_Float128: return "__float128";
- // CLANG-UPGRADE-CHECK: CXType_Float16 available with >= clang-6.0:
-// case CXType_Float16: return "_Float16";
+ case CXType_Float16: return "_Float16";
// https://www.khronos.org/registry/OpenCL/sdk/2.1/docs/man/xhtml/scalarDataTypes.html
case CXType_Half:
diff --git a/src/tools/clangbackend/source/sourcelocation.cpp b/src/tools/clangbackend/source/sourcelocation.cpp
index 2450dcf590..7fbe8c03eb 100644
--- a/src/tools/clangbackend/source/sourcelocation.cpp
+++ b/src/tools/clangbackend/source/sourcelocation.cpp
@@ -93,8 +93,6 @@ SourceLocation::SourceLocation(CXTranslationUnit cxTranslationUnit,
return;
filePath_ = ClangString(clang_getFileName(cxFile));
-// CLANG-UPGRADE-CHECK: Remove HAS_GETFILECONTENTS_BACKPORTED check once we require clang >= 7.0
-#if defined(CINDEX_VERSION_HAS_GETFILECONTENTS_BACKPORTED) || CINDEX_VERSION_MINOR >= 47
if (column_ > 1) {
const uint lineStart = offset_ + 1 - column_;
const char *contents = clang_getFileContents(cxTranslationUnit, cxFile, nullptr);
@@ -106,7 +104,6 @@ SourceLocation::SourceLocation(CXTranslationUnit cxTranslationUnit,
column_ = static_cast<uint>(QString::fromUtf8(&contents[lineStart],
static_cast<int>(column_)).size());
}
-#endif
}
SourceLocation::SourceLocation(CXTranslationUnit cxTranslationUnit,