aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/projectexplorer
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/projectexplorer')
-rw-r--r--src/plugins/projectexplorer/buildtargetinfo.h3
-rw-r--r--src/plugins/projectexplorer/deployablefile.cpp2
-rw-r--r--src/plugins/projectexplorer/deployablefile.h3
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicemanager.cpp12
-rw-r--r--src/plugins/projectexplorer/devicesupport/idevice.cpp5
-rw-r--r--src/plugins/projectexplorer/devicesupport/idevice.h1
-rw-r--r--src/plugins/projectexplorer/expanddata.cpp2
-rw-r--r--src/plugins/projectexplorer/expanddata.h4
-rw-r--r--src/plugins/projectexplorer/gccparser.cpp8
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp162
-rw-r--r--src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h6
-rw-r--r--src/plugins/projectexplorer/parseissuesdialog.cpp32
-rw-r--r--src/plugins/projectexplorer/project.cpp10
-rw-r--r--src/plugins/projectexplorer/projectexplorer.cpp2
-rw-r--r--src/plugins/projectexplorer/projecttree.cpp4
-rw-r--r--src/plugins/projectexplorer/projecttree.h9
-rw-r--r--src/plugins/projectexplorer/runconfigurationaspects.cpp4
-rw-r--r--src/plugins/projectexplorer/runcontrol.cpp7
-rw-r--r--src/plugins/projectexplorer/task.cpp2
-rw-r--r--src/plugins/projectexplorer/task.h11
-rw-r--r--src/plugins/projectexplorer/treescanner.cpp2
21 files changed, 232 insertions, 59 deletions
diff --git a/src/plugins/projectexplorer/buildtargetinfo.h b/src/plugins/projectexplorer/buildtargetinfo.h
index 7d786de3ca..34d5f19624 100644
--- a/src/plugins/projectexplorer/buildtargetinfo.h
+++ b/src/plugins/projectexplorer/buildtargetinfo.h
@@ -30,6 +30,7 @@
#include <utils/algorithm.h>
#include <utils/environment.h>
#include <utils/fileutils.h>
+#include <utils/porting.h>
#include <QList>
@@ -48,7 +49,7 @@ public:
bool isQtcRunnable = true;
bool usesTerminal = false;
- uint runEnvModifierHash = 0; // Make sure to update this when runEnvModifier changes!
+ Utils::QHashValueType runEnvModifierHash = 0; // Make sure to update this when runEnvModifier changes!
std::function<void(Utils::Environment &, bool)> runEnvModifier;
};
diff --git a/src/plugins/projectexplorer/deployablefile.cpp b/src/plugins/projectexplorer/deployablefile.cpp
index 78fbcb165e..7ecfb59409 100644
--- a/src/plugins/projectexplorer/deployablefile.cpp
+++ b/src/plugins/projectexplorer/deployablefile.cpp
@@ -53,7 +53,7 @@ bool DeployableFile::isExecutable() const
return m_type == TypeExecutable;
}
-uint qHash(const DeployableFile &d)
+Utils::QHashValueType qHash(const DeployableFile &d)
{
return qHash(qMakePair(d.localFilePath().toString(), d.remoteDirectory()));
}
diff --git a/src/plugins/projectexplorer/deployablefile.h b/src/plugins/projectexplorer/deployablefile.h
index 4709206b16..e3760e4a02 100644
--- a/src/plugins/projectexplorer/deployablefile.h
+++ b/src/plugins/projectexplorer/deployablefile.h
@@ -28,6 +28,7 @@
#include "projectexplorer_export.h"
#include <utils/fileutils.h>
+#include <utils/porting.h>
#include <QString>
@@ -71,6 +72,6 @@ inline bool operator!=(const DeployableFile &d1, const DeployableFile &d2)
return !(d1 == d2);
}
-PROJECTEXPLORER_EXPORT uint qHash(const DeployableFile &d);
+PROJECTEXPLORER_EXPORT Utils::QHashValueType qHash(const DeployableFile &d);
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
index f7470cd079..1e671e5fe3 100644
--- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
+++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
@@ -484,6 +484,18 @@ DeviceManager::DeviceManager(bool isInstance) : d(std::make_unique<DeviceManager
return device->symLinkTarget(filePath);
};
+ deviceHooks.mapToGlobalPath = [](const FilePath &filePath) {
+ auto device = DeviceManager::deviceForPath(filePath);
+ QTC_ASSERT(device, return FilePath{});
+ return device->mapToGlobalPath(filePath);
+ };
+
+ deviceHooks.mapToDevicePath = [](const FilePath &filePath) {
+ auto device = DeviceManager::deviceForPath(filePath);
+ QTC_ASSERT(device, return QString{});
+ return device->mapToDevicePath(filePath);
+ };
+
deviceHooks.dirEntries = [](const FilePath &filePath, const QStringList &nameFilters,
QDir::Filters filters, QDir::SortFlags sort) {
auto device = DeviceManager::deviceForPath(filePath);
diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp
index 8c90a7fc14..f1bedcc441 100644
--- a/src/plugins/projectexplorer/devicesupport/idevice.cpp
+++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp
@@ -212,6 +212,11 @@ FilePath IDevice::mapToGlobalPath(const FilePath &pathOnDevice) const
return pathOnDevice;
}
+QString IDevice::mapToDevicePath(const FilePath &globalPath) const
+{
+ return globalPath.path();
+}
+
bool IDevice::handlesFile(const FilePath &filePath) const
{
Q_UNUSED(filePath);
diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h
index 873eb380bb..56bdbb5bd2 100644
--- a/src/plugins/projectexplorer/devicesupport/idevice.h
+++ b/src/plugins/projectexplorer/devicesupport/idevice.h
@@ -237,6 +237,7 @@ public:
bool isAnyUnixDevice() const;
virtual Utils::FilePath mapToGlobalPath(const Utils::FilePath &pathOnDevice) const;
+ virtual QString mapToDevicePath(const Utils::FilePath &globalPath) const;
virtual bool handlesFile(const Utils::FilePath &filePath) const;
virtual bool isExecutableFile(const Utils::FilePath &filePath) const;
diff --git a/src/plugins/projectexplorer/expanddata.cpp b/src/plugins/projectexplorer/expanddata.cpp
index bf3876475d..4b005b8fe5 100644
--- a/src/plugins/projectexplorer/expanddata.cpp
+++ b/src/plugins/projectexplorer/expanddata.cpp
@@ -50,7 +50,7 @@ QVariant ExpandData::toSettings() const
return QVariant::fromValue(QStringList({path, displayName}));
}
-int ProjectExplorer::Internal::qHash(const ExpandData &data)
+Utils::QHashValueType ProjectExplorer::Internal::qHash(const ExpandData &data)
{
return qHash(data.path) ^ qHash(data.displayName);
}
diff --git a/src/plugins/projectexplorer/expanddata.h b/src/plugins/projectexplorer/expanddata.h
index 9d6a656449..a7ff078680 100644
--- a/src/plugins/projectexplorer/expanddata.h
+++ b/src/plugins/projectexplorer/expanddata.h
@@ -25,6 +25,8 @@
#pragma once
+#include <utils/porting.h>
+
#include <QString>
#include <QHash>
#include <QDebug>
@@ -46,7 +48,7 @@ public:
QString displayName;
};
-int qHash(const ExpandData &data);
+Utils::QHashValueType qHash(const ExpandData &data);
} // namespace Internal
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/gccparser.cpp b/src/plugins/projectexplorer/gccparser.cpp
index 6479240c2b..30ebe45bf8 100644
--- a/src/plugins/projectexplorer/gccparser.cpp
+++ b/src/plugins/projectexplorer/gccparser.cpp
@@ -1367,6 +1367,14 @@ void ProjectExplorerPlugin::testGccOutputParsers_data()
CompileTask(Task::Error, ".pch/Qt6Core5Compat: No such file or directory", ".pch/Qt6Core5Compat"),
CompileTask(Task::Warning, "-Wformat-security ignored without -Wformat [-Wformat-security]")}
<< QString();
+
+ QTest::newRow("clean path")
+ << QString("/home/tim/path/to/sources/./and/more.h:15:22: error: blubb")
+ << OutputParserTester::STDERR
+ << QString() << QString()
+ << Tasks{CompileTask(Task::Error, "blubb", "/home/tim/path/to/sources/and/more.h",
+ 15, 22)}
+ << QString();
}
void ProjectExplorerPlugin::testGccOutputParsers()
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp
index ac73d2a047..31155c276c 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp
+++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp
@@ -87,6 +87,7 @@ const char PAGE_SHORT_TITLE_KEY[] = "trShortTitle";
const char PAGE_INDEX_KEY[] = "index";
const char OPTIONS_KEY[] = "options";
const char PLATFORM_INDEPENDENT_KEY[] = "platformIndependent";
+const char DEFAULT_VALUES[] = "defaultValues";
static QList<JsonWizardPageFactory *> s_pageFactories;
static QList<JsonWizardGeneratorFactory *> s_generatorFactories;
@@ -153,7 +154,131 @@ static JsonWizardFactory::Generator parseGenerator(const QVariant &value, QStrin
return gen;
}
-static JsonWizardFactory::Page parsePage(const QVariant &value, QString *errorMessage)
+//FIXME: createWizardFactories() has an almost identical loop. Make the loop return the results instead of
+//internal processing and create a separate function for it. Then process the results in
+//loadDefaultValues() and createWizardFactories()
+QVariantMap JsonWizardFactory::loadDefaultValues(const QString &fileName)
+{
+ QString verboseLog;
+
+ if (fileName.isEmpty()) {
+ return {};
+ }
+
+ QList <Core::IWizardFactory *> result;
+ foreach (const Utils::FilePath &path, searchPaths()) {
+ if (path.isEmpty())
+ continue;
+
+ FilePath dir = FilePath::fromString(path.toString());
+ if (!dir.exists()) {
+ if (verbose())
+ verboseLog.append(tr("Path \"%1\" does not exist when checking Json wizard search paths.\n")
+ .arg(path.toUserOutput()));
+ continue;
+ }
+
+ const QDir::Filters filters = QDir::Dirs|QDir::Readable|QDir::NoDotAndDotDot;
+ FilePaths dirs = dir.dirEntries(filters);
+
+ while (!dirs.isEmpty()) {
+ const FilePath current = dirs.takeFirst();
+ if (verbose())
+ verboseLog.append(tr("Checking \"%1\" for %2.\n")
+ .arg(QDir::toNativeSeparators(current.absolutePath().toString()))
+ .arg(fileName));
+ if (current.pathAppended(fileName).exists()) {
+ QFile configFile(current.pathAppended(fileName).toString());
+ configFile.open(QIODevice::ReadOnly);
+ QJsonParseError error;
+ const QByteArray fileData = configFile.readAll();
+ const QJsonDocument json = QJsonDocument::fromJson(fileData, &error);
+ configFile.close();
+
+ if (error.error != QJsonParseError::NoError) {
+ int line = 1;
+ int column = 1;
+ for (int i = 0; i < error.offset; ++i) {
+ if (fileData.at(i) == '\n') {
+ ++line;
+ column = 1;
+ } else {
+ ++column;
+ }
+ }
+ verboseLog.append(tr("* Failed to parse \"%1\":%2:%3: %4\n")
+ .arg(configFile.fileName())
+ .arg(line).arg(column)
+ .arg(error.errorString()));
+ continue;
+ }
+
+ if (!json.isObject()) {
+ verboseLog.append(tr("* Did not find a JSON object in \"%1\".\n")
+ .arg(configFile.fileName()));
+ continue;
+ }
+
+ if (verbose())
+ verboseLog.append(tr("* Configuration found and parsed.\n"));
+
+ return json.object().toVariantMap();
+ }
+ FilePaths subDirs = current.dirEntries(filters);
+ if (!subDirs.isEmpty()) {
+ // There is no QList::prepend(QList)...
+ dirs.swap(subDirs);
+ dirs.append(subDirs);
+ } else if (verbose()) {
+ verboseLog.append(tr("JsonWizard: \"%1\" not found\n").arg(fileName));
+ }
+ }
+ }
+
+ if (verbose()) { // Print to output pane for Windows.
+ qWarning("%s", qPrintable(verboseLog));
+ Core::MessageManager::writeDisrupting(verboseLog);
+ }
+
+ return {};
+}
+
+QVariant JsonWizardFactory::mergeDataValueMaps(const QVariant &valueMap, const QVariant &defaultValueMap)
+{
+ QVariantMap retVal;
+
+#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
+ const QVariantMap &map = defaultValueMap.toMap();
+ for (auto it = map.begin(), end = map.end(); it != end; ++it)
+ retVal.insert(it.key(), it.value());
+
+ const QVariantMap &map2 = valueMap.toMap();
+ for (auto it = map2.begin(), end = map2.end(); it != end; ++it)
+ retVal.insert(it.key(), it.value());
+#else
+ retVal.insert(defaultValueMap.toMap());
+ retVal.insert(valueMap.toMap());
+#endif
+ return retVal;
+}
+
+QVariant JsonWizardFactory::getDataValue(const QLatin1String &key, const QVariantMap &valueSet,
+ const QVariantMap &defaultValueSet, const QVariant &notExistValue)
+{
+ QVariant retVal = {};
+
+ if ((valueSet.contains(key) && valueSet.value(key).type() == QVariant::Map) ||
+ (defaultValueSet.contains(key) && defaultValueSet.value(key).type() == QVariant::Map)) {
+ retVal = mergeDataValueMaps(valueSet.value(key), defaultValueSet.value(key));
+ } else {
+ QVariant defaultValue = defaultValueSet.value(key, notExistValue);
+ retVal = valueSet.value(key, defaultValue);
+ }
+
+ return retVal;
+}
+
+JsonWizardFactory::Page JsonWizardFactory::parsePage(const QVariant &value, QString *errorMessage)
{
JsonWizardFactory::Page p;
@@ -163,7 +288,12 @@ static JsonWizardFactory::Page parsePage(const QVariant &value, QString *errorMe
}
const QVariantMap data = value.toMap();
- const QString strVal = data.value(QLatin1String(TYPE_ID_KEY)).toString();
+ QString defaultValueFile = data.value(QLatin1String(DEFAULT_VALUES)).toString();
+ if (!defaultValueFile.isEmpty())
+ defaultValueFile.append(QLatin1String(".json"));
+ const QVariantMap defaultData = loadDefaultValues(defaultValueFile);
+
+ const QString strVal = getDataValue(QLatin1String(TYPE_ID_KEY), data, defaultData).toString();
if (strVal.isEmpty()) {
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonWizardFactory", "Page has no typeId set.");
return p;
@@ -180,21 +310,31 @@ static JsonWizardFactory::Page parsePage(const QVariant &value, QString *errorMe
return p;
}
- const QString title = JsonWizardFactory::localizedString(data.value(QLatin1String(DISPLAY_NAME_KEY)));
- const QString subTitle = JsonWizardFactory::localizedString(data.value(QLatin1String(PAGE_SUB_TITLE_KEY)));
- const QString shortTitle = JsonWizardFactory::localizedString(data.value(QLatin1String(PAGE_SHORT_TITLE_KEY)));
+ const QString title = JsonWizardFactory::localizedString(getDataValue(QLatin1String(DISPLAY_NAME_KEY), data, defaultData));
+ const QString subTitle = JsonWizardFactory::localizedString(getDataValue(QLatin1String(PAGE_SUB_TITLE_KEY), data, defaultData));
+ const QString shortTitle = JsonWizardFactory::localizedString(getDataValue(QLatin1String(PAGE_SHORT_TITLE_KEY), data, defaultData));
bool ok;
- int index = data.value(QLatin1String(PAGE_INDEX_KEY), -1).toInt(&ok);
+ int index = getDataValue(QLatin1String(PAGE_INDEX_KEY), data, defaultData, -1).toInt(&ok);
if (!ok) {
*errorMessage = QCoreApplication::translate("ProjectExplorer::JsonWizardFactory", "Page with typeId \"%1\" has invalid \"index\".")
.arg(typeId.toString());
return p;
}
- QVariant enabled = data.value(QLatin1String(ENABLED_EXPRESSION_KEY), true);
+ QVariant enabled = getDataValue(QLatin1String(ENABLED_EXPRESSION_KEY), data, defaultData, true);
+
+ QVariant specifiedSubData = data.value(QLatin1String(DATA_KEY));
+ QVariant defaultSubData = defaultData.value(QLatin1String(DATA_KEY));
+ QVariant subData;
+
+ if (specifiedSubData.isNull())
+ subData = defaultSubData;
+ else if (specifiedSubData.type() == QVariant::Map)
+ subData = mergeDataValueMaps(specifiedSubData.toMap(), defaultSubData.toMap());
+ else if (specifiedSubData.type() == QVariant::List)
+ subData = specifiedSubData;
- QVariant subData = data.value(QLatin1String(DATA_KEY));
if (!factory->validateData(typeId, subData, errorMessage))
return p;
@@ -209,6 +349,9 @@ static JsonWizardFactory::Page parsePage(const QVariant &value, QString *errorMe
return p;
}
+//FIXME: loadDefaultValues() has an almost identical loop. Make the loop return the results instead of
+//internal processing and create a separate function for it. Then process the results in
+//loadDefaultValues() and loadDefaultValues()
QList<Core::IWizardFactory *> JsonWizardFactory::createWizardFactories()
{
QString errorMessage;
@@ -258,14 +401,12 @@ QList<Core::IWizardFactory *> JsonWizardFactory::createWizardFactories()
.arg(currentFile.fileName())
.arg(line).arg(column)
.arg(error.errorString()));
- qWarning() << "Failed to parse wizard: " << currentFile.fileName();
continue;
}
if (!json.isObject()) {
verboseLog.append(tr("* Did not find a JSON object in \"%1\".\n")
.arg(currentFile.fileName()));
- qWarning() << "Failed to parse wizard: " << currentFile.fileName();
continue;
}
@@ -283,7 +424,6 @@ QList<Core::IWizardFactory *> JsonWizardFactory::createWizardFactories()
JsonWizardFactory *factory = createWizardFactory(data, currentDir, &errorMessage);
if (!factory) {
verboseLog.append(tr("* Failed to create: %1\n").arg(errorMessage));
- qWarning() << "Failed to create wizard: " << currentFile.fileName();
continue;
}
diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h
index c3c6c5bd34..d69aaa00f0 100644
--- a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h
+++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h
@@ -100,6 +100,12 @@ private:
static void destroyAllFactories();
bool initialize(const QVariantMap &data, const Utils::FilePath &baseDir, QString *errorMessage);
+ JsonWizardFactory::Page parsePage(const QVariant &value, QString *errorMessage);
+ QVariantMap loadDefaultValues(const QString &fileName);
+ QVariant getDataValue(const QLatin1String &key, const QVariantMap &valueSet,
+ const QVariantMap &defaultValueSet, const QVariant &notExistValue={});
+ QVariant mergeDataValueMaps(const QVariant &valueMap, const QVariant &defaultValueMap);
+
QVariant m_enabledExpression;
Utils::FilePath m_wizardDir;
QList<Generator> m_generators;
diff --git a/src/plugins/projectexplorer/parseissuesdialog.cpp b/src/plugins/projectexplorer/parseissuesdialog.cpp
index 75be7e7bcb..f81db2da7d 100644
--- a/src/plugins/projectexplorer/parseissuesdialog.cpp
+++ b/src/plugins/projectexplorer/parseissuesdialog.cpp
@@ -32,9 +32,6 @@
#include "projectexplorerconstants.h"
#include "taskhub.h"
-#include <coreplugin/progressmanager/progressmanager.h>
-#include <utils/runextensions.h>
-
#include <QButtonGroup>
#include <QCheckBox>
#include <QDialogButtonBox>
@@ -137,21 +134,6 @@ ParseIssuesDialog::~ParseIssuesDialog()
delete d;
}
-static void parse(QFutureInterface<void> &future, const QString &output,
- const std::unique_ptr<Utils::OutputFormatter> &parser, bool isStderr)
-{
- const QStringList lines = output.split('\n');
- future.setProgressRange(0, lines.count());
- const Utils::OutputFormat format = isStderr ? Utils::StdErrFormat : Utils::StdOutFormat;
- for (const QString &line : lines) {
- parser->appendMessage(line + '\n', format);
- future.setProgressValue(future.progressValue() + 1);
- if (future.isCanceled())
- return;
- }
- parser->flush();
-}
-
void ParseIssuesDialog::accept()
{
const QList<Utils::OutputLineParser *> lineParsers =
@@ -161,14 +143,16 @@ void ParseIssuesDialog::accept()
"not provide an output parser."));
return;
}
- std::unique_ptr<Utils::OutputFormatter> parser(new Utils::OutputFormatter);
- parser->setLineParsers(lineParsers);
+ Utils::OutputFormatter parser;
+ parser.setLineParsers(lineParsers);
if (d->clearTasksCheckBox.isChecked())
TaskHub::clearTasks();
- const QFuture<void> f = Utils::runAsync(&parse, d->compileOutputEdit.toPlainText(),
- std::move(parser), d->stderrCheckBox.isChecked());
- Core::ProgressManager::addTask(f, tr("Parsing build output"),
- "ProgressExplorer.ParseExternalBuildOutput");
+ const QStringList lines = d->compileOutputEdit.toPlainText().split('\n');
+ const Utils::OutputFormat format = d->stderrCheckBox.isChecked()
+ ? Utils::StdErrFormat : Utils::StdOutFormat;
+ for (const QString &line : lines)
+ parser.appendMessage(line + '\n', format);
+ parser.flush();
QDialog::accept();
}
diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp
index a49011bc41..b283862c46 100644
--- a/src/plugins/projectexplorer/project.cpp
+++ b/src/plugins/projectexplorer/project.cpp
@@ -376,7 +376,7 @@ void Project::setExtraProjectFiles(const QSet<FilePath> &projectDocumentPaths,
const QSet<FilePath> toAdd = uniqueNewFiles - existingWatches;
const QSet<FilePath> toRemove = existingWatches - uniqueNewFiles;
- erase(d->m_extraProjectDocuments, [&toRemove](const std::unique_ptr<IDocument> &d) {
+ Utils::erase(d->m_extraProjectDocuments, [&toRemove](const std::unique_ptr<IDocument> &d) {
return toRemove.contains(d->filePath());
});
if (docUpdater) {
@@ -586,7 +586,8 @@ void Project::setRootProjectNode(std::unique_ptr<ProjectNode> &&root)
}
if (root) {
- ProjectTree::applyTreeManager(root.get());
+ ProjectTree::applyTreeManager(root.get(), ProjectTree::AsyncPhase);
+ ProjectTree::applyTreeManager(root.get(), ProjectTree::FinalPhase);
root->setParentFolderNode(d->m_containerNode.get());
}
@@ -804,8 +805,9 @@ void Project::createTargetFromMap(const QVariantMap &map, int index)
deviceTypeId = Constants::DESKTOP_DEVICE_TYPE;
const QString formerKitName = targetMap.value(Target::displayNameKey()).toString();
k = KitManager::registerKit([deviceTypeId, &formerKitName](Kit *kit) {
- const QString tempKitName = makeUniquelyNumbered(
- tr("Replacement for \"%1\"").arg(formerKitName),
+ const QString kitNameSuggestion = formerKitName.contains(tr("Replacement for"))
+ ? formerKitName : tr("Replacement for \"%1\"").arg(formerKitName);
+ const QString tempKitName = makeUniquelyNumbered(kitNameSuggestion,
transform(KitManager::kits(), &Kit::unexpandedDisplayName));
kit->setUnexpandedDisplayName(tempKitName);
DeviceTypeKitAspect::setDeviceTypeId(kit, deviceTypeId);
diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp
index f7fe67d213..46db91993a 100644
--- a/src/plugins/projectexplorer/projectexplorer.cpp
+++ b/src/plugins/projectexplorer/projectexplorer.cpp
@@ -2602,7 +2602,7 @@ void ProjectExplorerPluginPrivate::restoreSession()
dd->m_arguments = arguments;
// delay opening projects from the command line even more
QTimer::singleShot(0, m_instance, []() {
- ICore::openFiles(Utils::transform(dd->m_arguments, &FilePath::fromString),
+ ICore::openFiles(Utils::transform(dd->m_arguments, &FilePath::fromUserInput),
ICore::OpenFilesFlags(ICore::CanContainLineAndColumnNumbers | ICore::SwitchMode));
emit m_instance->finishedInitialization();
});
diff --git a/src/plugins/projectexplorer/projecttree.cpp b/src/plugins/projectexplorer/projecttree.cpp
index aa8e79f9ef..ee040d5a37 100644
--- a/src/plugins/projectexplorer/projecttree.cpp
+++ b/src/plugins/projectexplorer/projecttree.cpp
@@ -402,13 +402,13 @@ void ProjectTree::registerTreeManager(const TreeManagerFunction &treeChange)
s_instance->m_treeManagers.append(treeChange);
}
-void ProjectTree::applyTreeManager(FolderNode *folder)
+void ProjectTree::applyTreeManager(FolderNode *folder, ConstructionPhase phase)
{
if (!folder)
return;
for (TreeManagerFunction &f : s_instance->m_treeManagers)
- f(folder);
+ f(folder, phase);
}
bool ProjectTree::hasNode(const Node *node)
diff --git a/src/plugins/projectexplorer/projecttree.h b/src/plugins/projectexplorer/projecttree.h
index 060dad2290..3947666d3a 100644
--- a/src/plugins/projectexplorer/projecttree.h
+++ b/src/plugins/projectexplorer/projecttree.h
@@ -68,6 +68,11 @@ public:
const bool m_active = false;
};
+ enum ConstructionPhase {
+ AsyncPhase,
+ FinalPhase
+ };
+
// Integration with ProjectTreeWidget
static void registerWidget(Internal::ProjectTreeWidget *widget);
static void unregisterWidget(Internal::ProjectTreeWidget *widget);
@@ -79,9 +84,9 @@ public:
static void highlightProject(Project *project, const QString &message);
- using TreeManagerFunction = std::function<void(FolderNode *)>;
+ using TreeManagerFunction = std::function<void(FolderNode *, ConstructionPhase)>;
static void registerTreeManager(const TreeManagerFunction &treeChange);
- static void applyTreeManager(FolderNode *folder);
+ static void applyTreeManager(FolderNode *folder, ConstructionPhase phase);
// Nodes:
static bool hasNode(const Node *node);
diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp
index 0a3a2634b0..2291a86fbd 100644
--- a/src/plugins/projectexplorer/runconfigurationaspects.cpp
+++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp
@@ -251,7 +251,9 @@ FilePath WorkingDirectoryAspect::workingDirectory() const
const Environment env = m_envAspect ? m_envAspect->environment()
: Environment::systemEnvironment();
FilePath res = m_workingDirectory;
- const QString workingDir = m_workingDirectory.path();
+ QString workingDir = m_workingDirectory.path();
+ if (m_macroExpander)
+ workingDir = m_macroExpander->expandProcessArgs(workingDir);
res.setPath(PathChooser::expandedDirectory(workingDir, env, QString()));
return res;
}
diff --git a/src/plugins/projectexplorer/runcontrol.cpp b/src/plugins/projectexplorer/runcontrol.cpp
index 4cd0665f09..9ca0e228c3 100644
--- a/src/plugins/projectexplorer/runcontrol.cpp
+++ b/src/plugins/projectexplorer/runcontrol.cpp
@@ -349,7 +349,7 @@ public:
IDevice::ConstPtr device;
Utils::Id runMode;
Utils::Icon icon;
- const MacroExpander *macroExpander;
+ const MacroExpander *macroExpander = nullptr;
QPointer<RunConfiguration> runConfiguration; // Not owned. Avoid use.
QString buildKey;
QMap<Utils::Id, QVariantMap> settingsData;
@@ -389,11 +389,12 @@ void RunControl::setRunConfiguration(RunConfiguration *runConfig)
d->runConfigId = runConfig->id();
d->runnable = runConfig->runnable();
d->displayName = runConfig->expandedDisplayName();
- d->macroExpander = runConfig->macroExpander();
d->buildKey = runConfig->buildKey();
d->settingsData = runConfig->aspectData();
setTarget(runConfig->target());
+
+ d->macroExpander = runConfig->macroExpander();
}
void RunControl::setTarget(Target *target)
@@ -412,6 +413,7 @@ void RunControl::setTarget(Target *target)
}
setKit(target->kit());
+ d->macroExpander = target->macroExpander();
d->project = target->project();
}
@@ -420,6 +422,7 @@ void RunControl::setKit(Kit *kit)
QTC_ASSERT(kit, return);
QTC_CHECK(!d->kit);
d->kit = kit;
+ d->macroExpander = kit->macroExpander();
if (d->runnable.device)
setDevice(d->runnable.device);
diff --git a/src/plugins/projectexplorer/task.cpp b/src/plugins/projectexplorer/task.cpp
index fe880442ba..3ef9e397a9 100644
--- a/src/plugins/projectexplorer/task.cpp
+++ b/src/plugins/projectexplorer/task.cpp
@@ -171,7 +171,7 @@ bool operator<(const Task &a, const Task &b)
}
-uint qHash(const Task &task)
+Utils::QHashValueType qHash(const Task &task)
{
return task.taskId;
}
diff --git a/src/plugins/projectexplorer/task.h b/src/plugins/projectexplorer/task.h
index a21332c708..b95d51d34e 100644
--- a/src/plugins/projectexplorer/task.h
+++ b/src/plugins/projectexplorer/task.h
@@ -29,6 +29,7 @@
#include <utils/id.h>
#include <utils/fileutils.h>
+#include <utils/porting.h>
#include <QIcon>
#include <QMetaType>
@@ -135,13 +136,13 @@ public:
using Tasks = QVector<Task>;
-bool PROJECTEXPLORER_EXPORT operator==(const Task &t1, const Task &t2);
-uint PROJECTEXPLORER_EXPORT qHash(const Task &task);
+PROJECTEXPLORER_EXPORT bool operator==(const Task &t1, const Task &t2);
+PROJECTEXPLORER_EXPORT Utils::QHashValueType qHash(const Task &task);
-bool PROJECTEXPLORER_EXPORT operator<(const Task &a, const Task &b);
+PROJECTEXPLORER_EXPORT bool operator<(const Task &a, const Task &b);
-QString PROJECTEXPLORER_EXPORT toHtml(const Tasks &issues);
-bool PROJECTEXPLORER_EXPORT containsType(const Tasks &issues, Task::TaskType);
+PROJECTEXPLORER_EXPORT QString toHtml(const Tasks &issues);
+PROJECTEXPLORER_EXPORT bool containsType(const Tasks &issues, Task::TaskType);
} //namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/treescanner.cpp b/src/plugins/projectexplorer/treescanner.cpp
index ce6da40b1c..88e7b8d4a8 100644
--- a/src/plugins/projectexplorer/treescanner.cpp
+++ b/src/plugins/projectexplorer/treescanner.cpp
@@ -159,7 +159,7 @@ static std::unique_ptr<FolderNode> createFolderNode(const Utils::FilePath &direc
std::unique_ptr<FileNode> node(fn->clone());
fileSystemNode->addNestedNode(std::move(node));
}
- ProjectTree::applyTreeManager(fileSystemNode.get()); // QRC nodes
+ ProjectTree::applyTreeManager(fileSystemNode.get(), ProjectTree::AsyncPhase); // QRC nodes
return fileSystemNode;
}