diff options
Diffstat (limited to 'src/plugins/projectexplorer')
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 ¬ExistValue) +{ + 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 ¬ExistValue={}); + 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; } |