aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app/Info.plist2
-rw-r--r--src/app/app.pro2
-rw-r--r--src/libs/utils/environment.cpp4
-rw-r--r--src/plugins/autotest/autotestplugin.cpp14
-rw-r--r--src/plugins/autotest/autotestplugin.h2
-rw-r--r--src/plugins/autotest/gtest/gtesttreeitem.cpp11
-rw-r--r--src/plugins/autotest/qtest/qttesttreeitem.cpp5
-rw-r--r--src/plugins/autotest/quick/quicktestparser.cpp49
-rw-r--r--src/plugins/autotest/quick/quicktestparser.h3
-rw-r--r--src/plugins/autotest/quick/quicktesttreeitem.cpp23
-rw-r--r--src/plugins/autotest/quick/quicktesttreeitem.h2
-rw-r--r--src/plugins/autotest/testconfiguration.cpp34
-rw-r--r--src/plugins/autotest/testconfiguration.h2
-rw-r--r--src/plugins/autotest/testnavigationwidget.cpp6
-rw-r--r--src/plugins/autotest/testresultspane.cpp15
-rw-r--r--src/plugins/autotest/testtreeitem.cpp11
-rw-r--r--src/plugins/autotest/testtreeitem.h1
-rw-r--r--src/plugins/autotoolsprojectmanager/autotoolsproject.cpp33
-rw-r--r--src/plugins/cmakeprojectmanager/builddirmanager.cpp2
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildstep.cpp7
-rw-r--r--src/plugins/cmakeprojectmanager/cmakebuildstep.h1
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeproject.cpp4
-rw-r--r--src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp5
-rw-r--r--src/plugins/cmakeprojectmanager/servermodereader.cpp2
-rw-r--r--src/plugins/cmakeprojectmanager/tealeafreader.cpp2
-rw-r--r--src/plugins/coreplugin/vcsmanager.cpp15
-rw-r--r--src/plugins/cppeditor/cppinsertvirtualmethods.cpp3
-rw-r--r--src/plugins/cpptools/compileroptionsbuilder.cpp2
-rw-r--r--src/plugins/projectexplorer/projectmanager.h4
-rw-r--r--src/plugins/qbsprojectmanager/qbsnodes.cpp2
-rw-r--r--src/plugins/qbsprojectmanager/qbsproject.cpp4
-rw-r--r--src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp5
-rw-r--r--src/plugins/qbsprojectmanager/qbsrunconfiguration.h1
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeproject.cpp2
-rw-r--r--src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp13
-rw-r--r--src/plugins/qmakeprojectmanager/qmakestep.cpp7
-rw-r--r--src/plugins/updateinfo/updateinfoplugin.cpp1
-rw-r--r--src/plugins/vcsbase/vcsbasesubmiteditor.cpp15
-rw-r--r--src/plugins/welcome/welcomeplugin.cpp7
-rw-r--r--src/tools/iostool/iosdevicemanager.cpp173
40 files changed, 333 insertions, 163 deletions
diff --git a/src/app/Info.plist b/src/app/Info.plist
index 8772259386..6d31c52d26 100644
--- a/src/app/Info.plist
+++ b/src/app/Info.plist
@@ -253,6 +253,6 @@
<key>CFBundleShortVersionString</key>
<string>@SHORT_VERSION@</string>
<key>LSMinimumSystemVersion</key>
- <string>10.7.0</string>
+ <string>10.8</string>
</dict>
</plist>
diff --git a/src/app/app.pro b/src/app/app.pro
index eb8943f570..fee710e99d 100644
--- a/src/app/app.pro
+++ b/src/app/app.pro
@@ -38,7 +38,7 @@ win32 {
--app-icon qtcreator \
--output-partial-info-plist $$shell_quote($(TMPDIR)/qtcreator.Info.plist) \
--platform macosx \
- --minimum-deployment-target 10.7 \
+ --minimum-deployment-target $$QMAKE_MACOSX_DEPLOYMENT_TARGET \
--compile $$shell_quote($$IDE_DATA_PATH) \
$$shell_quote($$PWD/qtcreator.xcassets) > /dev/null
ASSETCATALOG.input = ASSETCATALOG.files
diff --git a/src/libs/utils/environment.cpp b/src/libs/utils/environment.cpp
index 0fc1ff0755..f2626e9773 100644
--- a/src/libs/utils/environment.cpp
+++ b/src/libs/utils/environment.cpp
@@ -26,6 +26,7 @@
#include "environment.h"
#include "algorithm.h"
+#include "qtcassert.h"
#include <QDir>
#include <QProcessEnvironment>
@@ -372,6 +373,7 @@ void Environment::modify(const QList<EnvironmentItem> & list)
} else {
// TODO use variable expansion
QString value = item.value;
+ int replaceCount = 0;
for (int i=0; i < value.size(); ++i) {
if (value.at(i) == '$') {
if ((i + 1) < value.size()) {
@@ -386,6 +388,8 @@ void Environment::modify(const QList<EnvironmentItem> & list)
Environment::const_iterator it = constFind(name);
if (it != constEnd())
value.replace(i, end-i+1, it.value());
+ ++replaceCount;
+ QTC_ASSERT(replaceCount < 100, break);
}
}
}
diff --git a/src/plugins/autotest/autotestplugin.cpp b/src/plugins/autotest/autotestplugin.cpp
index 571af4ba08..3d00400ccd 100644
--- a/src/plugins/autotest/autotestplugin.cpp
+++ b/src/plugins/autotest/autotestplugin.cpp
@@ -46,8 +46,8 @@
#include <coreplugin/actionmanager/command.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/coreconstants.h>
-
#include <extensionsystem/pluginmanager.h>
+#include <projectexplorer/buildmanager.h>
#include <QAction>
#include <QMessageBox>
@@ -102,6 +102,7 @@ void AutotestPlugin::initializeMenuEntries()
command->setDefaultKeySequence(QKeySequence(tr("Alt+Shift+T,Alt+A")));
connect(action, &QAction::triggered,
this, &AutotestPlugin::onRunAllTriggered);
+ action->setEnabled(false);
menu->addAction(command);
action = new QAction(tr("&Run Selected Tests"), this);
@@ -109,6 +110,7 @@ void AutotestPlugin::initializeMenuEntries()
command->setDefaultKeySequence(QKeySequence(tr("Alt+Shift+T,Alt+R")));
connect(action, &QAction::triggered,
this, &AutotestPlugin::onRunSelectedTriggered);
+ action->setEnabled(false);
menu->addAction(command);
action = new QAction(tr("Re&scan Tests"), this);
@@ -121,7 +123,12 @@ void AutotestPlugin::initializeMenuEntries()
ActionContainer *toolsMenu = ActionManager::actionContainer(Core::Constants::M_TOOLS);
toolsMenu->addMenu(menu);
- connect(toolsMenu->menu(), &QMenu::aboutToShow,
+ using namespace ProjectExplorer;
+ connect(BuildManager::instance(), &BuildManager::buildStateChanged,
+ this, &AutotestPlugin::updateMenuItemsEnabledState);
+ connect(BuildManager::instance(), &BuildManager::buildQueueFinished,
+ this, &AutotestPlugin::updateMenuItemsEnabledState);
+ connect(TestTreeModel::instance(), &TestTreeModel::testTreeModelChanged,
this, &AutotestPlugin::updateMenuItemsEnabledState);
}
@@ -176,7 +183,8 @@ void AutotestPlugin::onRunSelectedTriggered()
void AutotestPlugin::updateMenuItemsEnabledState()
{
- const bool enabled = !TestRunner::instance()->isTestRunning()
+ const bool enabled = !ProjectExplorer::BuildManager::isBuilding()
+ && !TestRunner::instance()->isTestRunning()
&& TestTreeModel::instance()->parser()->state() == TestCodeParser::Idle;
const bool hasTests = TestTreeModel::instance()->hasTests();
diff --git a/src/plugins/autotest/autotestplugin.h b/src/plugins/autotest/autotestplugin.h
index 8164efb21f..7c3f0712d4 100644
--- a/src/plugins/autotest/autotestplugin.h
+++ b/src/plugins/autotest/autotestplugin.h
@@ -60,7 +60,7 @@ private:
void updateMenuItemsEnabledState();
QList<QObject *> createTestObjects() const override;
const QSharedPointer<TestSettings> m_settings;
- TestFrameworkManager *m_frameworkManager = 0;
+ TestFrameworkManager *m_frameworkManager = nullptr;
};
} // namespace Internal
diff --git a/src/plugins/autotest/gtest/gtesttreeitem.cpp b/src/plugins/autotest/gtest/gtesttreeitem.cpp
index a57d44f358..5550e57642 100644
--- a/src/plugins/autotest/gtest/gtesttreeitem.cpp
+++ b/src/plugins/autotest/gtest/gtesttreeitem.cpp
@@ -104,6 +104,8 @@ TestConfiguration *GTestTreeItem::testConfiguration() const
default:
return nullptr;
}
+ if (config)
+ config->setInternalTargets(internalTargets());
return config;
}
@@ -124,6 +126,7 @@ QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
return result;
QHash<QString, int> proFilesWithTestSets;
+ QHash<QString, QSet<QString> > proFilesWithInternalTargets;
for (int row = 0, count = childCount(); row < count; ++row) {
const GTestTreeItem *child = static_cast<const GTestTreeItem *>(childItem(row));
@@ -132,6 +135,7 @@ QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
const TestTreeItem *grandChild = child->childItem(grandChildRow);
const QString &key = grandChild->proFile();
proFilesWithTestSets.insert(key, proFilesWithTestSets[key] + 1);
+ proFilesWithInternalTargets.insert(key, grandChild->internalTargets());
}
}
@@ -142,6 +146,7 @@ QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
tc->setTestCaseCount(it.value());
tc->setProjectFile(it.key());
tc->setProject(project);
+ tc->setInternalTargets(proFilesWithInternalTargets.value(it.key()));
result << tc;
}
@@ -162,6 +167,7 @@ QList<TestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
return result;
QHash<QString, TestCases> proFilesWithCheckedTestSets;
+ QHash<QString, QSet<QString> > proFilesWithInternalTargets;
for (int row = 0, count = childCount(); row < count; ++row) {
const GTestTreeItem *child = static_cast<const GTestTreeItem *>(childItem(row));
@@ -175,6 +181,8 @@ QList<TestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
auto &testCases = proFilesWithCheckedTestSets[child->childItem(0)->proFile()];
testCases.filters.append(gtestFilter(child->state()).arg(child->name()).arg('*'));
testCases.additionalTestCaseCount += grandChildCount - 1;
+ proFilesWithInternalTargets.insert(child->childItem(0)->proFile(),
+ child->internalTargets());
break;
}
case Qt::PartiallyChecked: {
@@ -183,6 +191,8 @@ QList<TestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
if (grandChild->checked() == Qt::Checked) {
proFilesWithCheckedTestSets[grandChild->proFile()].filters.append(
gtestFilter(child->state()).arg(child->name()).arg(grandChild->name()));
+ proFilesWithInternalTargets.insert(grandChild->proFile(),
+ grandChild->internalTargets());
}
}
break;
@@ -198,6 +208,7 @@ QList<TestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
tc->setTestCaseCount(tc->testCaseCount() + it.value().additionalTestCaseCount);
tc->setProjectFile(it.key());
tc->setProject(project);
+ tc->setInternalTargets(proFilesWithInternalTargets[it.key()]);
result << tc;
}
diff --git a/src/plugins/autotest/qtest/qttesttreeitem.cpp b/src/plugins/autotest/qtest/qttesttreeitem.cpp
index def491c196..2b4ad6d6c2 100644
--- a/src/plugins/autotest/qtest/qttesttreeitem.cpp
+++ b/src/plugins/autotest/qtest/qttesttreeitem.cpp
@@ -134,6 +134,8 @@ TestConfiguration *QtTestTreeItem::testConfiguration() const
default:
return nullptr;
}
+ if (config)
+ config->setInternalTargets(internalTargets());
return config;
}
@@ -160,6 +162,7 @@ QList<TestConfiguration *> QtTestTreeItem::getAllTestConfigurations() const
tc->setTestCaseCount(child->childCount());
tc->setProjectFile(child->proFile());
tc->setProject(project);
+ tc->setInternalTargets(child->internalTargets());
result << tc;
}
return result;
@@ -185,6 +188,7 @@ QList<TestConfiguration *> QtTestTreeItem::getSelectedTestConfigurations() const
testConfiguration->setTestCaseCount(child->childCount());
testConfiguration->setProjectFile(child->proFile());
testConfiguration->setProject(project);
+ testConfiguration->setInternalTargets(child->internalTargets());
result << testConfiguration;
continue;
case Qt::PartiallyChecked:
@@ -210,6 +214,7 @@ QList<TestConfiguration *> QtTestTreeItem::getSelectedTestConfigurations() const
testConfiguration->setTestCases(testCases);
testConfiguration->setProjectFile(child->proFile());
testConfiguration->setProject(project);
+ testConfiguration->setInternalTargets(child->internalTargets());
result << testConfiguration;
}
}
diff --git a/src/plugins/autotest/quick/quicktestparser.cpp b/src/plugins/autotest/quick/quicktestparser.cpp
index b7528f414c..0d897fe04e 100644
--- a/src/plugins/autotest/quick/quicktestparser.cpp
+++ b/src/plugins/autotest/quick/quicktestparser.cpp
@@ -36,6 +36,7 @@
#include <qmljs/qmljsdialect.h>
#include <qmljstools/qmljsmodelmanager.h>
#include <utils/hostosinfo.h>
+#include <utils/algorithm.h>
#include <utils/qtcassert.h>
namespace Autotest {
@@ -238,6 +239,49 @@ bool QuickTestParser::handleQtQuickTest(QFutureInterface<TestParseResultPtr> fut
return result;
}
+static QMap<QString, QDateTime> qmlFilesWithMTime(const QString &directory)
+{
+ const QFileInfoList &qmlFiles = QDir(directory).entryInfoList({ "*.qml" },
+ QDir::Files, QDir::Name);
+ QMap<QString, QDateTime> filesAndDates;
+ for (const QFileInfo &info : qmlFiles)
+ filesAndDates.insert(info.fileName(), info.lastModified());
+ return filesAndDates;
+}
+
+void QuickTestParser::handleDirectoryChanged(const QString &directory)
+{
+ const QMap<QString, QDateTime> &filesAndDates = qmlFilesWithMTime(directory);
+ const QMap<QString, QDateTime> &watched = m_watchedFiles.value(directory);
+ const QStringList &keys = watched.keys();
+ if (filesAndDates.keys() != keys) { // removed or added files
+ m_watchedFiles[directory] = filesAndDates;
+ TestTreeModel::instance()->parser()->emitUpdateTestTree(this);
+ } else { // we might still have different timestamps
+ const bool timestampChanged = Utils::anyOf(keys, [&](const QString &file) {
+ return filesAndDates.value(file) != watched.value(file);
+ });
+ if (timestampChanged) {
+ QmlJS::PathsAndLanguages paths;
+ paths.maybeInsert(Utils::FileName::fromString(directory), QmlJS::Dialect::Qml);
+ QFutureInterface<void> future;
+ QmlJS::ModelManagerInterface *qmlJsMM = QmlJS::ModelManagerInterface::instance();
+ QmlJS::ModelManagerInterface::importScan(future, qmlJsMM->workingCopy(), paths, qmlJsMM,
+ true /*emitDocumentChanges*/,
+ false /*onlyTheLib*/,
+ true /*forceRescan*/ );
+ }
+ }
+}
+
+void QuickTestParser::doUpdateWatchPaths(const QStringList &directories)
+{
+ for (const QString &dir : directories) {
+ m_directoryWatcher.addPath(dir);
+ m_watchedFiles[dir] = qmlFilesWithMTime(dir);
+ }
+}
+
QuickTestParser::QuickTestParser()
: CppParser()
{
@@ -246,11 +290,12 @@ QuickTestParser::QuickTestParser()
const QStringList &dirs = m_directoryWatcher.directories();
if (!dirs.isEmpty())
m_directoryWatcher.removePaths(dirs);
+ m_watchedFiles.clear();
});
connect(&m_directoryWatcher, &QFileSystemWatcher::directoryChanged,
- [this] { TestTreeModel::instance()->parser()->emitUpdateTestTree(this); });
+ this, &QuickTestParser::handleDirectoryChanged);
connect(this, &QuickTestParser::updateWatchPaths,
- &m_directoryWatcher, &QFileSystemWatcher::addPaths, Qt::QueuedConnection);
+ this, &QuickTestParser::doUpdateWatchPaths, Qt::QueuedConnection);
}
QuickTestParser::~QuickTestParser()
diff --git a/src/plugins/autotest/quick/quicktestparser.h b/src/plugins/autotest/quick/quicktestparser.h
index 26ba514f2f..2b38efed37 100644
--- a/src/plugins/autotest/quick/quicktestparser.h
+++ b/src/plugins/autotest/quick/quicktestparser.h
@@ -56,10 +56,13 @@ signals:
private:
bool handleQtQuickTest(QFutureInterface<TestParseResultPtr> futureInterface,
CPlusPlus::Document::Ptr document, const Core::Id &id) const;
+ void handleDirectoryChanged(const QString &directory);
+ void doUpdateWatchPaths(const QStringList &directories);
QList<QmlJS::Document::Ptr> scanDirectoryForQuickTestQmlFiles(const QString &srcDir) const;
QmlJS::Snapshot m_qmlSnapshot;
QHash<QString, QString> m_proFilesForQmlFiles;
QFileSystemWatcher m_directoryWatcher;
+ QMap<QString, QMap<QString, QDateTime> > m_watchedFiles;
};
} // namespace Internal
diff --git a/src/plugins/autotest/quick/quicktesttreeitem.cpp b/src/plugins/autotest/quick/quicktesttreeitem.cpp
index d6cd78b82a..5576f97b09 100644
--- a/src/plugins/autotest/quick/quicktesttreeitem.cpp
+++ b/src/plugins/autotest/quick/quicktesttreeitem.cpp
@@ -27,6 +27,7 @@
#include "quicktestconfiguration.h"
#include "quicktestparser.h"
+#include <cpptools/cppmodelmanager.h>
#include <projectexplorer/session.h>
#include <utils/qtcassert.h>
@@ -138,6 +139,8 @@ TestConfiguration *QuickTestTreeItem::testConfiguration() const
default:
return nullptr;
}
+ if (config)
+ config->setInternalTargets(internalTargets());
return config;
}
@@ -150,6 +153,7 @@ QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
return result;
QHash<QString, int> foundProFiles;
+ QHash<QString, QSet<QString> > proFilesWithTargets;
for (int row = 0, count = childCount(); row < count; ++row) {
const TestTreeItem *child = childItem(row);
// unnamed Quick Tests must be handled separately
@@ -158,12 +162,14 @@ QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
const TestTreeItem *grandChild = child->childItem(childRow);
const QString &proFile = grandChild->proFile();
foundProFiles.insert(proFile, foundProFiles[proFile] + 1);
+ proFilesWithTargets.insert(proFile, grandChild->internalTargets());
}
continue;
}
// named Quick Test
const QString &proFile = child->proFile();
foundProFiles.insert(proFile, foundProFiles[proFile] + child->childCount());
+ proFilesWithTargets.insert(proFile, child->internalTargets());
}
// create TestConfiguration for each project file
QHash<QString, int>::ConstIterator it = foundProFiles.begin();
@@ -173,6 +179,7 @@ QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
tc->setTestCaseCount(it.value());
tc->setProjectFile(it.key());
tc->setProject(project);
+ tc->setInternalTargets(proFilesWithTargets[it.key()]);
result << tc;
}
return result;
@@ -203,6 +210,7 @@ QList<TestConfiguration *> QuickTestTreeItem::getSelectedTestConfigurations() co
tc->setUnnamedOnly(true);
tc->setProjectFile(proFile);
tc->setProject(project);
+ tc->setInternalTargets(grandChild->internalTargets());
foundProFiles.insert(proFile, tc);
}
}
@@ -246,6 +254,7 @@ QList<TestConfiguration *> QuickTestTreeItem::getSelectedTestConfigurations() co
tc->setTestCases(testFunctions);
tc->setProjectFile(child->proFile());
tc->setProject(project);
+ tc->setInternalTargets(child->internalTargets());
foundProFiles.insert(child->proFile(), tc);
}
break;
@@ -306,6 +315,20 @@ bool QuickTestTreeItem::lessThan(const TestTreeItem *other, TestTreeItem::SortMo
return TestTreeItem::lessThan(other, mode);
}
+QSet<QString> QuickTestTreeItem::internalTargets() const
+{
+ QSet<QString> result;
+ const auto cppMM = CppTools::CppModelManager::instance();
+ const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject());
+ for (const CppTools::ProjectPart::Ptr projectPart : projectInfo.projectParts()) {
+ if (projectPart->projectFile == proFile()) {
+ result.insert(projectPart->buildSystemTarget);
+ break;
+ }
+ }
+ return result;
+}
+
TestTreeItem *QuickTestTreeItem::unnamedQuickTests() const
{
if (type() != Root)
diff --git a/src/plugins/autotest/quick/quicktesttreeitem.h b/src/plugins/autotest/quick/quicktesttreeitem.h
index 64f1cf0fb9..a0e860a52c 100644
--- a/src/plugins/autotest/quick/quicktesttreeitem.h
+++ b/src/plugins/autotest/quick/quicktesttreeitem.h
@@ -45,7 +45,7 @@ public:
TestTreeItem *find(const TestParseResult *result) override;
bool modify(const TestParseResult *result) override;
bool lessThan(const TestTreeItem *other, SortMode mode) const override;
-
+ QSet<QString> internalTargets() const override;
private:
TestTreeItem *unnamedQuickTests() const;
};
diff --git a/src/plugins/autotest/testconfiguration.cpp b/src/plugins/autotest/testconfiguration.cpp
index 880c42457a..52723a5b64 100644
--- a/src/plugins/autotest/testconfiguration.cpp
+++ b/src/plugins/autotest/testconfiguration.cpp
@@ -64,6 +64,7 @@ static bool isLocal(RunConfiguration *runConfiguration)
void TestConfiguration::completeTestInformation(int runMode)
{
QTC_ASSERT(!m_projectFile.isEmpty(), return);
+ QTC_ASSERT(!m_buildTargets.isEmpty(), return);
Project *project = SessionManager::startupProject();
if (!project)
@@ -73,23 +74,16 @@ void TestConfiguration::completeTestInformation(int runMode)
if (!target)
return;
- const auto cppMM = CppTools::CppModelManager::instance();
- const QVector<CppTools::ProjectPart::Ptr> projectParts = cppMM->projectInfo(project).projectParts();
- const QVector<CppTools::ProjectPart::Ptr> relevantParts
- = Utils::filtered(projectParts, [this] (const CppTools::ProjectPart::Ptr &part) {
- return part->selectedForBuilding && part->projectFile == m_projectFile;
- });
- const QSet<QString> buildSystemTargets
- = Utils::transform<QSet>(relevantParts, [] (const CppTools::ProjectPart::Ptr &part) {
- return part->buildSystemTarget;
- });
-
- const Utils::FileName fn = Utils::FileName::fromString(m_projectFile);
+ const QSet<QString> buildSystemTargets = m_buildTargets;
const BuildTargetInfo targetInfo
= Utils::findOrDefault(target->applicationTargets().list,
- [&buildSystemTargets, &fn] (const BuildTargetInfo &bti) {
- return Utils::anyOf(buildSystemTargets, [&fn, &bti](const QString &b) {
- return b == bti.targetName || (b.contains(bti.targetName) && bti.projectFilePath == fn);
+ [&buildSystemTargets] (const BuildTargetInfo &bti) {
+ return Utils::anyOf(buildSystemTargets, [&bti](const QString &b) {
+ const QStringList targWithProjectFile = b.split('|');
+ if (targWithProjectFile.size() != 2) // some build targets might miss the project file
+ return false;
+ return targWithProjectFile.at(0) == bti.targetName
+ && targWithProjectFile.at(1).startsWith(bti.projectFilePath.toString());
});
});
const Utils::FileName executable = targetInfo.targetFilePath; // empty if BTI is default created
@@ -97,7 +91,8 @@ void TestConfiguration::completeTestInformation(int runMode)
if (!isLocal(runConfig)) // TODO add device support
continue;
- if (buildSystemTargets.contains(runConfig->buildSystemTarget())) {
+ const QString bst = runConfig->buildSystemTarget() + '|' + m_projectFile;
+ if (buildSystemTargets.contains(bst)) {
Runnable runnable = runConfig->runnable();
if (!runnable.is<StandardRunnable>())
continue;
@@ -146,7 +141,7 @@ void TestConfiguration::completeTestInformation(int runMode)
}
if (m_displayName.isEmpty()) // happens e.g. when guessing the TestConfiguration or error
- m_displayName = buildSystemTargets.isEmpty() ? "unknown" : *buildSystemTargets.begin();
+ m_displayName = buildSystemTargets.isEmpty() ? "unknown" : (*buildSystemTargets.begin()).split('|').first();
}
/**
@@ -204,6 +199,11 @@ void TestConfiguration::setProject(Project *project)
m_project = project;
}
+void TestConfiguration::setInternalTargets(const QSet<QString> &targets)
+{
+ m_buildTargets = targets;
+}
+
QString TestConfiguration::executableFilePath() const
{
if (m_executableFile.isEmpty())
diff --git a/src/plugins/autotest/testconfiguration.h b/src/plugins/autotest/testconfiguration.h
index e220ea2d36..8d62085982 100644
--- a/src/plugins/autotest/testconfiguration.h
+++ b/src/plugins/autotest/testconfiguration.h
@@ -66,6 +66,7 @@ public:
void setDisplayName(const QString &displayName);
void setEnvironment(const Utils::Environment &env);
void setProject(ProjectExplorer::Project *project);
+ void setInternalTargets(const QSet<QString> &targets);
QStringList testCases() const { return m_testCases; }
int testCaseCount() const { return m_testCaseCount; }
@@ -97,6 +98,7 @@ private:
QPointer<ProjectExplorer::Project> m_project;
bool m_guessedConfiguration = false;
TestRunConfiguration *m_runConfig = 0;
+ QSet<QString> m_buildTargets;
};
class DebuggableTestConfiguration : public TestConfiguration
diff --git a/src/plugins/autotest/testnavigationwidget.cpp b/src/plugins/autotest/testnavigationwidget.cpp
index 6323e0d9f0..5e34c666e0 100644
--- a/src/plugins/autotest/testnavigationwidget.cpp
+++ b/src/plugins/autotest/testnavigationwidget.cpp
@@ -42,6 +42,7 @@
#include <utils/progressindicator.h>
#include <utils/utilsicons.h>
#include <coreplugin/actionmanager/actionmanager.h>
+#include <projectexplorer/buildmanager.h>
#include <QAction>
#include <QMenu>
@@ -113,7 +114,8 @@ TestNavigationWidget::~TestNavigationWidget()
void TestNavigationWidget::contextMenuEvent(QContextMenuEvent *event)
{
- const bool enabled = !TestRunner::instance()->isTestRunning()
+ const bool enabled = !ProjectExplorer::BuildManager::isBuilding()
+ && !TestRunner::instance()->isTestRunning()
&& m_model->parser()->state() == TestCodeParser::Idle;
const bool hasTests = m_model->hasTests();
@@ -170,8 +172,6 @@ void TestNavigationWidget::contextMenuEvent(QContextMenuEvent *event)
connect(selectAll, &QAction::triggered, m_view, &TestTreeView::selectAll);
connect(deselectAll, &QAction::triggered, m_view, &TestTreeView::deselectAll);
- runAll->setEnabled(enabled && hasTests);
- runSelected->setEnabled(enabled && hasTests);
selectAll->setEnabled(enabled && hasTests);
deselectAll->setEnabled(enabled && hasTests);
rescan->setEnabled(enabled);
diff --git a/src/plugins/autotest/testresultspane.cpp b/src/plugins/autotest/testresultspane.cpp
index b4fbab9785..41c9e216e6 100644
--- a/src/plugins/autotest/testresultspane.cpp
+++ b/src/plugins/autotest/testresultspane.cpp
@@ -34,12 +34,14 @@
#include "testcodeparser.h"
#include <aggregation/aggregate.h>
+#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/find/basetextfind.h>
#include <coreplugin/find/itemviewfind.h>
#include <coreplugin/icontext.h>
#include <coreplugin/icore.h>
+#include <projectexplorer/buildmanager.h>
#include <projectexplorer/projectexplorer.h>
#include <texteditor/texteditor.h>
#include <utils/theme/theme.h>
@@ -511,7 +513,9 @@ void TestResultsPane::onTestRunStarted()
m_testRunning = true;
m_stopTestRun->setEnabled(true);
m_runAll->setEnabled(false);
+ Core::ActionManager::command(Constants::ACTION_RUN_ALL_ID)->action()->setEnabled(false);
m_runSelected->setEnabled(false);
+ Core::ActionManager::command(Constants::ACTION_RUN_SELECTED_ID)->action()->setEnabled(false);
m_summaryWidget->setVisible(false);
}
@@ -519,8 +523,14 @@ void TestResultsPane::onTestRunFinished()
{
m_testRunning = false;
m_stopTestRun->setEnabled(false);
- m_runAll->setEnabled(true);
- m_runSelected->setEnabled(true);
+
+ const bool runEnabled = !ProjectExplorer::BuildManager::isBuilding()
+ && TestTreeModel::instance()->hasTests()
+ && TestTreeModel::instance()->parser()->state() == TestCodeParser::Idle;
+ m_runAll->setEnabled(runEnabled); // TODO unify Run* actions
+ Core::ActionManager::command(Constants::ACTION_RUN_ALL_ID)->action()->setEnabled(runEnabled);
+ m_runSelected->setEnabled(runEnabled);
+ Core::ActionManager::command(Constants::ACTION_RUN_SELECTED_ID)->action()->setEnabled(runEnabled);
updateSummaryLabel();
m_summaryWidget->setVisible(true);
m_model->removeCurrentTestMessage();
@@ -541,6 +551,7 @@ void TestResultsPane::updateRunActions()
QString whyNot;
TestTreeModel *model = TestTreeModel::instance();
const bool enable = !m_testRunning && !model->parser()->isParsing() && model->hasTests()
+ && !ProjectExplorer::BuildManager::isBuilding()
&& ProjectExplorer::ProjectExplorerPlugin::canRunStartupProject(
ProjectExplorer::Constants::NORMAL_RUN_MODE, &whyNot);
m_runAll->setEnabled(enable);
diff --git a/src/plugins/autotest/testtreeitem.cpp b/src/plugins/autotest/testtreeitem.cpp
index 9d69a6e50d..7f1992ae58 100644
--- a/src/plugins/autotest/testtreeitem.cpp
+++ b/src/plugins/autotest/testtreeitem.cpp
@@ -29,6 +29,7 @@
#include "testtreeitem.h"
#include <cplusplus/Icons.h>
+#include <cpptools/cppmodelmanager.h>
#include <texteditor/texteditor.h>
#include <QIcon>
@@ -281,6 +282,16 @@ bool TestTreeItem::lessThan(const TestTreeItem *other, SortMode mode) const
}
}
+QSet<QString> TestTreeItem::internalTargets() const
+{
+ auto cppMM = CppTools::CppModelManager::instance();
+ const QList<CppTools::ProjectPart::Ptr> projectParts = cppMM->projectPart(filePath());
+ QSet<QString> targets;
+ for (const CppTools::ProjectPart::Ptr part : projectParts)
+ targets.insert(part->buildSystemTarget);
+ return targets;
+}
+
void TestTreeItem::revalidateCheckState()
{
const Type ttiType = type();
diff --git a/src/plugins/autotest/testtreeitem.h b/src/plugins/autotest/testtreeitem.h
index 1c5c3f95a1..530a105e27 100644
--- a/src/plugins/autotest/testtreeitem.h
+++ b/src/plugins/autotest/testtreeitem.h
@@ -110,6 +110,7 @@ public:
virtual TestTreeItem *find(const TestParseResult *result) = 0;
virtual bool modify(const TestParseResult *result) = 0;
+ virtual QSet<QString> internalTargets() const;
protected:
typedef std::function<bool(const TestTreeItem *)> CompareFunction;
TestTreeItem *findChildBy(CompareFunction compare) const;
diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
index 7240fab3a5..38257ad754 100644
--- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
+++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp
@@ -119,7 +119,7 @@ Project::RestoreResult AutotoolsProject::fromMap(const QVariantMap &map, QString
void AutotoolsProject::loadProjectTree()
{
- if (m_makefileParserThread != 0) {
+ if (m_makefileParserThread) {
// The thread is still busy parsing a previus configuration.
// Wait until the thread has been finished and delete it.
// TODO: Discuss whether blocking is acceptable.
@@ -162,7 +162,7 @@ void AutotoolsProject::makefileParsingFinished()
// The parsing has been cancelled by the user. Don't show any
// project data at all.
m_makefileParserThread->deleteLater();
- m_makefileParserThread = 0;
+ m_makefileParserThread = nullptr;
return;
}
@@ -179,7 +179,7 @@ void AutotoolsProject::makefileParsingFinished()
// Apply sources to m_files, which are returned at AutotoolsProject::files()
const QFileInfo fileInfo = projectFilePath().toFileInfo();
const QDir dir = fileInfo.absoluteDir();
- QStringList files = m_makefileParserThread->sources();
+ const QStringList files = m_makefileParserThread->sources();
foreach (const QString& file, files)
m_files.append(dir.absoluteFilePath(file));
@@ -187,35 +187,36 @@ void AutotoolsProject::makefileParsingFinished()
// has been changed, the project tree must be reparsed.
const QStringList makefiles = m_makefileParserThread->makefiles();
foreach (const QString &makefile, makefiles) {
- files.append(makefile);
+ const QString absMakefile = dir.absoluteFilePath(makefile);
- const QString watchedFile = dir.absoluteFilePath(makefile);
- m_fileWatcher->addFile(watchedFile, Utils::FileSystemWatcher::WatchAllChanges);
- m_watchedFiles.append(watchedFile);
+ m_files.append(absMakefile);
+
+ m_fileWatcher->addFile(absMakefile, Utils::FileSystemWatcher::WatchAllChanges);
+ m_watchedFiles.append(absMakefile);
}
// Add configure.ac file to project and watch for changes.
const QLatin1String configureAc(QLatin1String("configure.ac"));
const QFile configureAcFile(fileInfo.absolutePath() + QLatin1Char('/') + configureAc);
if (configureAcFile.exists()) {
- files.append(configureAc);
- const QString configureAcFilePath = dir.absoluteFilePath(configureAc);
- m_fileWatcher->addFile(configureAcFilePath, Utils::FileSystemWatcher::WatchAllChanges);
- m_watchedFiles.append(configureAcFilePath);
+ const QString absConfigureAc = dir.absoluteFilePath(configureAc);
+ m_files.append(absConfigureAc);
+
+ m_fileWatcher->addFile(absConfigureAc, Utils::FileSystemWatcher::WatchAllChanges);
+ m_watchedFiles.append(absConfigureAc);
}
auto newRoot = new AutotoolsProjectNode(projectDirectory());
- for (const QString &f : files) {
- const Utils::FileName path = Utils::FileName::fromString(dir.absoluteFilePath(f));
- FileType ft = (f == "Makefile.am" || f == "configure.ac") ? FileType::Project : FileType::Resource;
- newRoot->addNestedNode(new FileNode(path, ft, false));
+ for (const QString &f : m_files) {
+ const Utils::FileName path = Utils::FileName::fromString(f);
+ newRoot->addNestedNode(new FileNode(path, FileNode::fileTypeForFileName(path), false));
}
setRootProjectNode(newRoot);
updateCppCodeModel();
m_makefileParserThread->deleteLater();
- m_makefileParserThread = 0;
+ m_makefileParserThread = nullptr;
emit parsingFinished();
}
diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
index dbfc4825eb..ca2fd4bd6a 100644
--- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp
+++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp
@@ -334,6 +334,8 @@ QList<CMakeBuildTarget> BuildDirManager::buildTargets() const
m_buildTargets.append(utilityTarget(CMakeBuildStep::allTarget(), this));
m_buildTargets.append(utilityTarget(CMakeBuildStep::cleanTarget(), this));
m_buildTargets.append(utilityTarget(CMakeBuildStep::installTarget(), this));
+ m_buildTargets.append(utilityTarget(CMakeBuildStep::testTarget(), this));
+
m_buildTargets.append(m_reader->buildTargets());
}
return m_buildTargets;
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
index 1ecb3e4bc8..d87a538f98 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp
@@ -404,9 +404,14 @@ QString CMakeBuildStep::installTarget()
return QString("install");
}
+QString CMakeBuildStep::testTarget()
+{
+ return QString("test");
+}
+
QStringList CMakeBuildStep::specialTargets()
{
- return { allTarget(), cleanTarget(), installTarget() };
+ return { allTarget(), cleanTarget(), installTarget(), testTarget() };
}
//
diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.h b/src/plugins/cmakeprojectmanager/cmakebuildstep.h
index e740baeaa7..70d89c8783 100644
--- a/src/plugins/cmakeprojectmanager/cmakebuildstep.h
+++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.h
@@ -80,6 +80,7 @@ public:
static QString cleanTarget();
static QString allTarget();
static QString installTarget();
+ static QString testTarget();
static QStringList specialTargets();
signals:
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
index ce4c54a9fe..101649702c 100644
--- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -498,8 +498,10 @@ void CMakeProject::updateApplicationAndDeploymentTargets()
if (ct.targetType == ExecutableType || ct.targetType == DynamicLibraryType)
deploymentData.addFile(ct.executable.toString(), deploymentPrefix + buildDir.relativeFilePath(ct.executable.toFileInfo().dir().path()), DeployableFile::TypeExecutable);
if (ct.targetType == ExecutableType) {
+ FileName srcWithTrailingSlash = FileName::fromString(ct.sourceDirectory.toString());
+ srcWithTrailingSlash.appendString('/');
// TODO: Put a path to corresponding .cbp file into projectFilePath?
- appTargetList.list << BuildTargetInfo(ct.title, ct.executable, ct.executable);
+ appTargetList.list << BuildTargetInfo(ct.title, ct.executable, srcWithTrailingSlash);
}
}
diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp
index 1205953c8b..bfb4fcbc71 100644
--- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp
@@ -247,7 +247,7 @@ RunConfiguration *CMakeRunConfigurationFactory::doCreate(Target *parent, Core::I
CMakeProject *project = static_cast<CMakeProject *>(parent->project());
const QString title(buildTargetFromId(id));
const CMakeBuildTarget &ct = project->buildTargetForTitle(title);
- return new CMakeRunConfiguration(parent, id, ct.executable.toString(), ct.workingDirectory, ct.title);
+ return new CMakeRunConfiguration(parent, id, title, ct.workingDirectory, ct.title);
}
bool CMakeRunConfigurationFactory::canClone(Target *parent, RunConfiguration *source) const
@@ -274,7 +274,8 @@ bool CMakeRunConfigurationFactory::canRestore(Target *parent, const QVariantMap
RunConfiguration *CMakeRunConfigurationFactory::doRestore(Target *parent, const QVariantMap &map)
{
- return new CMakeRunConfiguration(parent, idFromMap(map), QString(), Utils::FileName(), QString());
+ const Core::Id id = idFromMap(map);
+ return new CMakeRunConfiguration(parent, id, buildTargetFromId(id), Utils::FileName(), QString());
}
QString CMakeRunConfigurationFactory::buildTargetFromId(Core::Id id)
diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp
index 8bcc834688..84070ee98c 100644
--- a/src/plugins/cmakeprojectmanager/servermodereader.cpp
+++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp
@@ -316,7 +316,7 @@ void ServerModeReader::updateCodeModel(CppTools::RawProjectParts &rpps)
CppTools::RawProjectPart rpp;
rpp.setProjectFileLocation(fg->target->sourceDirectory.toString() + "/CMakeLists.txt");
- rpp.setBuildSystemTarget(fg->target->name);
+ rpp.setBuildSystemTarget(fg->target->name + '|' + rpp.projectFile);
rpp.setDisplayName(fg->target->name + QString::number(counter));
rpp.setDefines(defineArg.toUtf8());
rpp.setIncludePaths(includes);
diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.cpp b/src/plugins/cmakeprojectmanager/tealeafreader.cpp
index 0bfcac1d68..8c37220f26 100644
--- a/src/plugins/cmakeprojectmanager/tealeafreader.cpp
+++ b/src/plugins/cmakeprojectmanager/tealeafreader.cpp
@@ -367,7 +367,7 @@ void TeaLeafReader::updateCodeModel(CppTools::RawProjectParts &rpps)
includePaths += m_parameters.buildDirectory.toString();
CppTools::RawProjectPart rpp;
rpp.setProjectFileLocation(QString()); // No project file information available!
- rpp.setBuildSystemTarget(cbt.title);
+ rpp.setBuildSystemTarget(cbt.title + '|');
rpp.setIncludePaths(includePaths);
CppTools::RawProjectPartFlags cProjectFlags;
diff --git a/src/plugins/coreplugin/vcsmanager.cpp b/src/plugins/coreplugin/vcsmanager.cpp
index cec5642968..28ebd38270 100644
--- a/src/plugins/coreplugin/vcsmanager.cpp
+++ b/src/plugins/coreplugin/vcsmanager.cpp
@@ -94,21 +94,6 @@ public:
return nullptr;
}
- VcsInfo *findUpInCache(const QString &directory)
- {
- VcsInfo *result = nullptr;
- const QChar slash = QLatin1Char('/');
- // Split the path, trying to find the matching repository. We start from the reverse
- // in order to detected nested repositories correctly (say, a git checkout under SVN).
- for (int pos = directory.size() - 1; pos >= 0; pos = directory.lastIndexOf(slash, pos) - 1) {
- const QString directoryPart = directory.left(pos);
- result = findInCache(directoryPart);
- if (result)
- break;
- }
- return result;
- }
-
void clearCache()
{
m_cachedMatches.clear();
diff --git a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp
index 2d898353b2..655803cb03 100644
--- a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp
+++ b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp
@@ -588,7 +588,8 @@ public:
for (Scope::iterator it = clazz->memberBegin(); it != clazz->memberEnd(); ++it) {
if (const Function *func = (*it)->type()->asFunctionType()) {
// Filter virtual destructors
- if (func->name()->asDestructorNameId())
+ const Name *name = func->name();
+ if (!name || name->asDestructorNameId())
continue;
const Function *firstVirtual = 0;
diff --git a/src/plugins/cpptools/compileroptionsbuilder.cpp b/src/plugins/cpptools/compileroptionsbuilder.cpp
index e21fedef4c..0d89c12f33 100644
--- a/src/plugins/cpptools/compileroptionsbuilder.cpp
+++ b/src/plugins/cpptools/compileroptionsbuilder.cpp
@@ -393,7 +393,7 @@ void CompilerOptionsBuilder::addDefineFloat128ForMingw()
// CLANG-UPGRADE-CHECK: Workaround still needed?
// https://llvm.org/bugs/show_bug.cgi?id=30685
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID)
- addDefine("#define __float128 void");
+ addDefine("#define __float128 short");
}
QString CompilerOptionsBuilder::includeDirOption() const
diff --git a/src/plugins/projectexplorer/projectmanager.h b/src/plugins/projectexplorer/projectmanager.h
index 1e90f958c1..e504b1968e 100644
--- a/src/plugins/projectexplorer/projectmanager.h
+++ b/src/plugins/projectexplorer/projectmanager.h
@@ -27,6 +27,10 @@
#include "projectexplorer_export.h"
+#include <QString>
+
+#include <functional>
+
namespace Utils {
class FileName;
class MimeType;
diff --git a/src/plugins/qbsprojectmanager/qbsnodes.cpp b/src/plugins/qbsprojectmanager/qbsnodes.cpp
index 262145ec6d..e3dd87e23e 100644
--- a/src/plugins/qbsprojectmanager/qbsnodes.cpp
+++ b/src/plugins/qbsprojectmanager/qbsnodes.cpp
@@ -454,7 +454,7 @@ QList<ProjectExplorer::RunConfiguration *> QbsProductNode::runConfigurations() c
QbsRunConfiguration *qbsRc = qobject_cast<QbsRunConfiguration *>(rc);
if (!qbsRc)
continue;
- if (qbsRc->buildSystemTarget() == QbsProject::uniqueProductName(qbsProductData()))
+ if (qbsRc->uniqueProductName() == QbsProject::uniqueProductName(qbsProductData()))
result << qbsRc;
}
diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp
index e459d26a89..251c4f08b5 100644
--- a/src/plugins/qbsprojectmanager/qbsproject.cpp
+++ b/src/plugins/qbsprojectmanager/qbsproject.cpp
@@ -161,6 +161,8 @@ QbsProject::~QbsProject()
m_qbsUpdateFutureInterface = 0;
}
qDeleteAll(m_extraCompilers);
+ std::for_each(m_qbsDocuments.cbegin(), m_qbsDocuments.cend(),
+ [](Core::IDocument *doc) { doc->deleteLater(); });
}
QbsRootProjectNode *QbsProject::rootProjectNode() const
@@ -974,7 +976,7 @@ void QbsProject::updateCppCodeModel()
rpp.setDisplayName(grp.name());
rpp.setProjectFileLocation(grp.location().filePath(),
grp.location().line(), grp.location().column());
- rpp.setBuildSystemTarget(uniqueProductName(prd));
+ rpp.setBuildSystemTarget(prd.name() + '|' + rpp.projectFile);
QHash<QString, qbs::ArtifactData> filePathToSourceArtifact;
bool hasCFiles = false;
diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp
index 7f7e687d56..e8b90d4377 100644
--- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp
+++ b/src/plugins/qbsprojectmanager/qbsrunconfiguration.cpp
@@ -301,6 +301,11 @@ void QbsRunConfiguration::addToBaseEnvironment(Utils::Environment &env) const
QString QbsRunConfiguration::buildSystemTarget() const
{
+ return productDisplayNameFromId(id());
+}
+
+QString QbsRunConfiguration::uniqueProductName() const
+{
return m_uniqueProductName;
}
diff --git a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h b/src/plugins/qbsprojectmanager/qbsrunconfiguration.h
index 45b4c3b830..bff341af46 100644
--- a/src/plugins/qbsprojectmanager/qbsrunconfiguration.h
+++ b/src/plugins/qbsprojectmanager/qbsrunconfiguration.h
@@ -76,6 +76,7 @@ public:
void addToBaseEnvironment(Utils::Environment &env) const;
QString buildSystemTarget() const final;
+ QString uniqueProductName() const;
bool isConsoleApplication() const;
signals:
diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
index c241189d9e..806e500e57 100644
--- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp
@@ -287,7 +287,7 @@ void QmakeProject::updateCppCodeModel()
CppTools::RawProjectPart rpp;
rpp.setDisplayName(pro->displayName());
rpp.setProjectFileLocation(pro->filePath().toString());
- rpp.setBuildSystemTarget(pro->targetInformation().target);
+ rpp.setBuildSystemTarget(pro->targetInformation().target + '|' + rpp.projectFile);
// TODO: Handle QMAKE_CFLAGS
rpp.setFlagsForCxx({cxxToolChain, pro->variableValue(Variable::CppFlags)});
rpp.setDefines(pro->cxxDefines());
diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp
index 766e951345..666ec0ce51 100644
--- a/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanager.cpp
@@ -95,13 +95,22 @@ void QmakeManager::addLibrary()
void QmakeManager::addLibraryContextMenu()
{
+ QString projectPath;
+
Node *node = contextNode();
- if (dynamic_cast<QmakeProFileNode *>(node))
- addLibraryImpl(node->filePath().toString(), nullptr);
+ if (ContainerNode *cn = node->asContainerNode())
+ projectPath = cn->project()->projectFilePath().toString();
+ else if (dynamic_cast<QmakeProFileNode *>(node))
+ projectPath = node->filePath().toString();
+
+ addLibraryImpl(projectPath, nullptr);
}
void QmakeManager::addLibraryImpl(const QString &fileName, BaseTextEditor *editor)
{
+ if (fileName.isEmpty())
+ return;
+
Internal::AddLibraryWizard wizard(fileName, Core::ICore::dialogParent());
if (wizard.exec() != QDialog::Accepted)
return;
diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp
index 99dab8044d..54c8d0989d 100644
--- a/src/plugins/qmakeprojectmanager/qmakestep.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp
@@ -225,19 +225,18 @@ bool QMakeStep::init(QList<const BuildStep *> &earlierSteps)
m_makeArguments.clear();
}
- QString makefile = workingDirectory;
+ QString makefile = workingDirectory + '/';
if (qmakeBc->subNodeBuild()) {
QmakeProFile *pro = qmakeBc->subNodeBuild()->proFile();
if (pro && !pro->makefile().isEmpty())
makefile.append(pro->makefile());
else
- makefile.append(QLatin1String("/Makefile"));
+ makefile.append("Makefile");
} else if (!qmakeBc->makefile().isEmpty()) {
- makefile.append(QLatin1Char('/'));
makefile.append(qmakeBc->makefile());
} else {
- makefile.append(QLatin1String("/Makefile"));
+ makefile.append("Makefile");
}
// Check whether we need to run qmake
diff --git a/src/plugins/updateinfo/updateinfoplugin.cpp b/src/plugins/updateinfo/updateinfoplugin.cpp
index ec59aa52ea..f54d15fd5e 100644
--- a/src/plugins/updateinfo/updateinfoplugin.cpp
+++ b/src/plugins/updateinfo/updateinfoplugin.cpp
@@ -213,6 +213,7 @@ bool UpdateInfoPlugin::initialize(const QStringList & /* arguments */, QString *
addAutoReleasedObject(new SettingsPage(this));
QAction *checkForUpdatesAction = new QAction(tr("Check for Updates"), this);
+ checkForUpdatesAction->setMenuRole(QAction::ApplicationSpecificRole);
Core::Command *checkForUpdatesCommand = Core::ActionManager::registerAction(checkForUpdatesAction, "Updates.CheckForUpdates");
connect(checkForUpdatesAction, &QAction::triggered, this, &UpdateInfoPlugin::startCheckForUpdates);
ActionContainer *const helpContainer = ActionManager::actionContainer(Core::Constants::M_HELP);
diff --git a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp
index 97e47eac2d..a06b43ca06 100644
--- a/src/plugins/vcsbase/vcsbasesubmiteditor.cpp
+++ b/src/plugins/vcsbase/vcsbasesubmiteditor.cpp
@@ -50,6 +50,7 @@
#include <texteditor/texteditorsettings.h>
#include <projectexplorer/project.h>
+#include <projectexplorer/session.h>
#include <QDir>
#include <QFileInfo>
@@ -722,22 +723,10 @@ QIcon VcsBaseSubmitEditor::submitIcon()
void VcsBaseSubmitEditor::filterUntrackedFilesOfProject(const QString &repositoryDirectory,
QStringList *untrackedFiles)
{
- if (untrackedFiles->empty())
- return;
-
- ProjectExplorer::Project *vcsProject = VcsProjectCache::projectFor(repositoryDirectory);
- if (!vcsProject)
- return;
-
- const QSet<QString> projectFiles
- = QSet<QString>::fromList(vcsProject->files(ProjectExplorer::Project::SourceFiles));
-
- if (projectFiles.empty())
- return;
const QDir repoDir(repositoryDirectory);
for (QStringList::iterator it = untrackedFiles->begin(); it != untrackedFiles->end(); ) {
const QString path = repoDir.absoluteFilePath(*it);
- if (projectFiles.contains(path))
+ if (ProjectExplorer::SessionManager::projectForFile(FileName::fromString(path)))
++it;
else
it = untrackedFiles->erase(it);
diff --git a/src/plugins/welcome/welcomeplugin.cpp b/src/plugins/welcome/welcomeplugin.cpp
index 8a34fdd466..c7d6058012 100644
--- a/src/plugins/welcome/welcomeplugin.cpp
+++ b/src/plugins/welcome/welcomeplugin.cpp
@@ -48,6 +48,7 @@
#include <QHeaderView>
#include <QLabel>
#include <QMouseEvent>
+#include <QOpenGLWidget>
#include <QPainter>
#include <QStackedWidget>
#include <QTimer>
@@ -310,6 +311,12 @@ WelcomeMode::WelcomeMode()
layout->addWidget(new StyledBar(m_modeWidget));
layout->addItem(hbox);
+ if (Utils::HostOsInfo::isMacHost()) { // workaround QTBUG-61384
+ auto openglWidget = new QOpenGLWidget;
+ openglWidget->hide();
+ layout->addWidget(openglWidget);
+ }
+
setWidget(m_modeWidget);
}
diff --git a/src/tools/iostool/iosdevicemanager.cpp b/src/tools/iostool/iosdevicemanager.cpp
index dddd2287fe..fc6e0bb2e1 100644
--- a/src/tools/iostool/iosdevicemanager.cpp
+++ b/src/tools/iostool/iosdevicemanager.cpp
@@ -57,6 +57,8 @@
#include <QDir>
#include <QFile>
#include <QProcess>
+#include <QRegularExpression>
+#include <QVersionNumber>
#ifdef MOBILE_DEV_DIRECT_LINK
#include "MobileDevice.h"
@@ -259,6 +261,100 @@ static QString mobileDeviceErrorString(MobileDeviceLib *lib, am_res_t code)
return s;
}
+qint64 toBuildNumber(const QString &versionStr)
+{
+ QString buildNumber;
+ const QRegularExpression re("\\s\\((\\X+)\\)");
+ const QRegularExpressionMatch m = re.match(versionStr);
+ if (m.hasMatch())
+ buildNumber = m.captured(1);
+ return buildNumber.toLongLong(nullptr, 16);
+}
+
+static bool findXcodePath(QString *xcodePath)
+{
+ if (!xcodePath)
+ return false;
+
+ QProcess process;
+ process.start("/bin/bash", QStringList({"-c", "xcode-select -p"}));
+ if (!process.waitForFinished(3000))
+ return false;
+
+ *xcodePath = QString::fromLatin1(process.readAllStandardOutput()).trimmed();
+ return (process.exitStatus() == QProcess::NormalExit && QFile::exists(*xcodePath));
+}
+
+/*!
+ * \brief Finds the \e DeveloperDiskImage.dmg path corresponding to \a versionStr and \a buildStr.
+ *
+ * The algorithm sorts the \e DeviceSupport directories with decreasing order of their version and
+ * build number to find the appropriate \e DeviceSupport directory corresponding to \a versionStr
+ * and \a buildStr. Directories starting with major build number of \a versionStr are considered
+ * only, rest are filtered out.
+ *
+ * Returns \c true if \e DeveloperDiskImage.dmg is found, otherwise returns \c false. The absolute
+ * path to the \e DeveloperDiskImage.dmg is enumerated in \a path.
+ */
+static bool findDeveloperDiskImage(const QString &versionStr, const QString &buildStr,
+ QString *path = nullptr)
+{
+ const QVersionNumber deviceVersion = QVersionNumber::fromString(versionStr);
+ if (deviceVersion.isNull())
+ return false;
+
+ QString xcodePath;
+ if (!findXcodePath(&xcodePath)) {
+ if (debugAll)
+ qDebug() << "Error getting xcode installation path.";
+ return false;
+ }
+
+ // Returns device support directories matching the major version.
+ const auto findDeviceSupportDirs = [xcodePath, deviceVersion](const QString &subFolder) {
+ const QDir rootDir(QString("%1/%2").arg(xcodePath).arg(subFolder));
+ const QStringList filter(QString("%1.*").arg(deviceVersion.majorVersion()));
+ return rootDir.entryInfoList(filter, QDir::Dirs | QDir::NoDotAndDotDot);
+ };
+
+ // Compares version strings(considers build number) and return true if versionStrA > versionStrB.
+ const auto compareVersion = [](const QString &versionStrA, const QString &versionStrB) {
+ const auto versionA = QVersionNumber::fromString(versionStrA);
+ const auto versionB = QVersionNumber::fromString(versionStrB);
+ if (versionA == versionB)
+ return toBuildNumber(versionStrA) > toBuildNumber(versionStrB);
+ return versionA > versionB;
+ };
+
+ // To filter dirs without DeveloperDiskImage.dmg and dirs having higher version.
+ const auto filterDir = [compareVersion, versionStr, buildStr](const QFileInfo d) {
+ const auto devDiskImage = QString("%1/DeveloperDiskImage.dmg").arg(d.absoluteFilePath());
+ if (!QFile::exists(devDiskImage))
+ return true; // Dir's without DeveloperDiskImage.dmg
+ return compareVersion(d.fileName(), QString("%1 (%2)").arg(versionStr).arg(buildStr));
+ };
+
+ QFileInfoList deviceSupportDirs(findDeviceSupportDirs("iOS DeviceSupport"));
+ deviceSupportDirs << findDeviceSupportDirs("Platforms/iPhoneOS.platform/DeviceSupport");
+
+ // Remove dirs without DeveloperDiskImage.dmg and dirs having higher version.
+ auto endItr = std::remove_if(deviceSupportDirs.begin(), deviceSupportDirs.end(), filterDir);
+ deviceSupportDirs.erase(endItr, deviceSupportDirs.end());
+
+ if (deviceSupportDirs.isEmpty())
+ return false;
+
+ // Sort device support directories.
+ std::sort(deviceSupportDirs.begin(), deviceSupportDirs.end(),
+ [compareVersion](const QFileInfo &a, const QFileInfo &b) {
+ return compareVersion(a.fileName(), b.fileName());
+ });
+
+ if (path)
+ *path = QString("%1/DeveloperDiskImage.dmg").arg(deviceSupportDirs[0].absoluteFilePath());
+ return true;
+}
+
extern "C" {
typedef void (*DeviceAvailableCallback)(QString deviceId, AMDeviceRef, void *userData);
}
@@ -309,7 +405,6 @@ public:
private:
bool developerDiskImagePath(QString *path, QString *signaturePath);
- bool findDeveloperDiskImage(QString *diskImagePath, QString versionString, QString buildString);
private:
bool checkRead(qptrdiff nRead, int &maxRetry);
@@ -1232,7 +1327,6 @@ MobileDeviceLib *CommandSession::lib()
bool CommandSession::developerDiskImagePath(QString *path, QString *signaturePath)
{
- bool success = false;
if (device && path && connectDevice()) {
CFPropertyListRef cfProductVersion = lib()->deviceCopyValue(device, 0, CFSTR("ProductVersion"));
QString versionString;
@@ -1249,80 +1343,17 @@ bool CommandSession::developerDiskImagePath(QString *path, QString *signaturePat
CFRelease(cfBuildVersion);
disconnectDevice();
- if (findDeveloperDiskImage(path, versionString, buildString)) {
- success = QFile::exists(*path);
- if (success && debugAll)
+ if (findDeveloperDiskImage(versionString, buildString, path)) {
+ if (debugAll)
qDebug() << "Developers disk image found at" << path;
- if (success && signaturePath) {
+ if (signaturePath) {
*signaturePath = QString("%1.%2").arg(*path).arg("signature");
- success = QFile::exists(*signaturePath);
- }
- }
- }
- return success;
-}
-
-bool CommandSession::findDeveloperDiskImage(QString *diskImagePath, QString versionString, QString buildString)
-{
- if (!diskImagePath || versionString.isEmpty())
- return false;
-
- *diskImagePath = QString();
- QProcess process;
- process.start("/bin/bash", QStringList() << "-c" << "xcode-select -p");
- if (!process.waitForFinished(3000))
- addError("Error getting xcode installation path. Command did not finish in time");
-
- const QString xcodePath = QString::fromLatin1(process.readAllStandardOutput()).trimmed();
-
- if (process.exitStatus() == QProcess::NormalExit && QFile::exists(xcodePath)) {
-
- auto imageExists = [xcodePath](QString *foundPath, QString subFolder, QString version, QString build) -> bool {
- Q_ASSERT(foundPath);
- const QString subFolderPath = QString("%1/%2").arg(xcodePath).arg(subFolder);
- if (QFile::exists(subFolderPath)) {
- *foundPath = QString("%1/%2 (%3)/DeveloperDiskImage.dmg").arg(subFolderPath).arg(version).arg(build);
- if (QFile::exists(*foundPath)) {
- return true;
- }
-
- QDir subFolderDir(subFolderPath);
- QStringList nameFilterList;
- nameFilterList << QString("%1 (*)").arg(version);
- QFileInfoList builds = subFolderDir.entryInfoList(nameFilterList, QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name | QDir::Reversed);
- foreach (QFileInfo buildPathInfo, builds) {
- *foundPath = QString("%1/DeveloperDiskImage.dmg").arg(buildPathInfo.absoluteFilePath());
- if (QFile::exists(*foundPath)) {
- return true;
- }
- }
-
- *foundPath = QString("%1/%2/DeveloperDiskImage.dmg").arg(subFolderPath).arg(version);
- if (QFile::exists(*foundPath)) {
- return true;
- }
-
- }
- *foundPath = QString();
- return false;
- };
-
- QStringList versionParts = versionString.split(".", QString::SkipEmptyParts);
- while (versionParts.count() > 0) {
- if (imageExists(diskImagePath,"iOS DeviceSupport", versionParts.join("."), buildString))
- break;
- if (imageExists(diskImagePath,"Platforms/iPhoneOS.platform/DeviceSupport", versionParts.join("."), buildString))
- break;
-
- const QString latestImagePath = QString("%1/Platforms/iPhoneOS.platform/DeviceSupport/Latest/DeveloperDiskImage.dmg").arg(xcodePath);
- if (QFile::exists(latestImagePath)) {
- *diskImagePath = latestImagePath;
- break;
+ return QFile::exists(*signaturePath);
}
- versionParts.removeLast();
+ return true;
}
}
- return !diskImagePath->isEmpty();
+ return false;
}
AppOpSession::AppOpSession(const QString &deviceId, const QString &bundlePath,