diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts index 1fd70e622cb..5f624cbfe13 100644 --- a/share/qtcreator/translations/qtcreator_de.ts +++ b/share/qtcreator/translations/qtcreator_de.ts @@ -45411,7 +45411,7 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e - Core::Internal::SystemSettingsWidget + Core::Internal::SystemSettings Command line arguments used for "%1". Kommandozeilenargumente für "%1". @@ -45444,10 +45444,6 @@ Wenn Sie noch keinen privaten Schlüssel besitzen, können Sie hier auch einen e Variables Variablen - - System - System - Core::ListItemDelegate diff --git a/share/qtcreator/translations/qtcreator_ja.ts b/share/qtcreator/translations/qtcreator_ja.ts index 7f212bbe547..5d84dd74efe 100644 --- a/share/qtcreator/translations/qtcreator_ja.ts +++ b/share/qtcreator/translations/qtcreator_ja.ts @@ -35870,10 +35870,6 @@ Android 5 ではローカルの Qt ライブラリをデプロイできません Core::Internal::SystemSettings - - System - システム - Terminal: ターミナル: @@ -35941,30 +35937,6 @@ Android 5 ではローカルの Qt ライブラリをデプロイできません Terminal 既定に戻します。 - - Command used for reverting diff chunks. - 差分チャンクを元に戻す際に使用するコマンドです。 - - - Case Sensitive (Default) - 区別する (既定) - - - Case Sensitive - 区別する - - - Case Insensitive (Default) - 区別しない (既定) - - - Case Insensitive - 区別しない - - - Variables - 変数 - Warn before opening text files greater than 右記より大きなテキストファイルを開く際には警告する @@ -48174,7 +48146,7 @@ Continue? - Core::Internal::SystemSettingsWidget + Core::Internal::SystemSettings Command line arguments used for "%1". "%1" に使用するコマンドライン引数。 diff --git a/share/qtcreator/translations/qtcreator_ru.ts b/share/qtcreator/translations/qtcreator_ru.ts index 21f3707a4ca..5bdbc409b9f 100644 --- a/share/qtcreator/translations/qtcreator_ru.ts +++ b/share/qtcreator/translations/qtcreator_ru.ts @@ -11187,7 +11187,7 @@ Do you want to kill it? - Core::Internal::SystemSettingsWidget + Core::Internal::SystemSettings Command line arguments used for "%1". Параметры командной строки для «%1». @@ -11220,10 +11220,6 @@ Do you want to kill it? Variables Переменные - - System - Система - Core::Internal::ThemeChooser diff --git a/src/app/main.cpp b/src/app/main.cpp index fbb02042c6b..48cdc283cf2 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -85,6 +85,7 @@ const char HELP_OPTION2[] = "-help"; const char HELP_OPTION3[] = "/h"; const char HELP_OPTION4[] = "--help"; const char VERSION_OPTION[] = "-version"; +const char VERSION_OPTION2[] = "--version"; const char CLIENT_OPTION[] = "-client"; const char SETTINGS_OPTION[] = "-settingspath"; const char INSTALL_SETTINGS_OPTION[] = "-installsettingspath"; @@ -117,7 +118,7 @@ static void displayHelpText(const QString &t) if (Utils::HostOsInfo::isWindowsHost() && qApp) QMessageBox::information(nullptr, QLatin1String(Core::Constants::IDE_DISPLAY_NAME), toHtml(t)); else - qWarning("%s", qPrintable(t)); + printf("%s", qPrintable(t)); } static void displayError(const QString &t) @@ -639,6 +640,7 @@ int main(int argc, char **argv) appOptions.insert(QLatin1String(HELP_OPTION3), false); appOptions.insert(QLatin1String(HELP_OPTION4), false); appOptions.insert(QLatin1String(VERSION_OPTION), false); + appOptions.insert(QLatin1String(VERSION_OPTION2), false); appOptions.insert(QLatin1String(CLIENT_OPTION), false); appOptions.insert(QLatin1String(PID_OPTION), true); appOptions.insert(QLatin1String(BLOCK_OPTION), false); @@ -682,7 +684,8 @@ int main(int argc, char **argv) displayError(msgCoreLoadFailure(coreplugin->errorString())); return 1; } - if (foundAppOptions.contains(QLatin1String(VERSION_OPTION))) { + if (foundAppOptions.contains(QLatin1String(VERSION_OPTION)) + || foundAppOptions.contains(QLatin1String(VERSION_OPTION2))) { printVersion(coreplugin); return 0; } diff --git a/src/libs/extensionsystem/optionsparser.cpp b/src/libs/extensionsystem/optionsparser.cpp index 8773523267f..e6cf0aabe69 100644 --- a/src/libs/extensionsystem/optionsparser.cpp +++ b/src/libs/extensionsystem/optionsparser.cpp @@ -155,7 +155,7 @@ bool OptionsParser::checkForScenarioOption() if (!m_pmPrivate->m_requestedScenario.isEmpty()) { if (m_errorString) { *m_errorString = QCoreApplication::translate("PluginManager", - "Cannot request scenario \"%1\" as the scenario \"%1\" was already requested.") + "Cannot request scenario \"%1\" as it was already requested.") .arg(m_currentArg, m_pmPrivate->m_requestedScenario); } m_hasError = true; diff --git a/src/libs/languageserverprotocol/jsonrpcmessages.cpp b/src/libs/languageserverprotocol/jsonrpcmessages.cpp index ab15f292390..8a8311369f0 100644 --- a/src/libs/languageserverprotocol/jsonrpcmessages.cpp +++ b/src/libs/languageserverprotocol/jsonrpcmessages.cpp @@ -46,7 +46,7 @@ JsonRpcMessage::JsonRpcMessage() constexpr int utf8mib = 106; -static QString docTypeName(const QJsonDocument &doc) +static QString docType(const QJsonDocument &doc) { if (doc.isArray()) return QString("array"); @@ -73,16 +73,12 @@ JsonRpcMessage::JsonRpcMessage(const BaseMessage &message) content = message.content; QJsonParseError error = {0, QJsonParseError::NoError}; const QJsonDocument doc = QJsonDocument::fromJson(content, &error); - if (doc.isObject()) { + if (doc.isObject()) m_jsonObject = doc.object(); - } else if (doc.isNull()) { - m_parseError = tr("LanguageServerProtocol::JsonRpcMessage", - "Could not parse JSON message \"%1\".") - .arg(error.errorString()); - } else { - m_parseError = tr("Expected a JSON object, but got a JSON \"%1\" value.") - .arg(docTypeName(doc)); - } + else if (doc.isNull()) + m_parseError = tr("Could not parse JSON message \"%1\".").arg(error.errorString()); + else + m_parseError = tr("Expected a JSON object, but got a JSON \"%1\" value.").arg(docType(doc)); } JsonRpcMessage::JsonRpcMessage(const QJsonObject &jsonObject) diff --git a/src/libs/utils/devicefileaccess.cpp b/src/libs/utils/devicefileaccess.cpp index 6123cd6751c..517004f2732 100644 --- a/src/libs/utils/devicefileaccess.cpp +++ b/src/libs/utils/devicefileaccess.cpp @@ -879,6 +879,9 @@ bool UnixDeviceFileAccess::iterateWithFind( return true; const FilePath fp = filePath.withNewPath(fileName); + // Do not return the entry for the directory we are searching in. + if (fp.path() == filePath.path()) + return true; return std::get<1>(callBack)(fp, fi); }; diff --git a/src/libs/utils/qtcassert.cpp b/src/libs/utils/qtcassert.cpp index 0c24ea0fc7f..003311faa28 100644 --- a/src/libs/utils/qtcassert.cpp +++ b/src/libs/utils/qtcassert.cpp @@ -37,8 +37,10 @@ void dumpBacktrace(int maxdepth) free(lines); #elif defined(_MSC_VER) DWORD machineType; -#if defined(Q_OS_WIN64) && !defined(_ARM64_) +#if defined(_M_X64) machineType = IMAGE_FILE_MACHINE_AMD64; +#elif defined(_M_ARM64) + machineType = IMAGE_FILE_MACHINE_ARM64; #else return; #endif @@ -50,13 +52,17 @@ void dumpBacktrace(int maxdepth) RtlCaptureContext(&ctx); STACKFRAME64 frame; memset(&frame, 0, sizeof(STACKFRAME64)); -#if defined(Q_OS_WIN64) && !defined(_ARM64_) - frame.AddrPC.Offset = ctx.Rip; frame.AddrPC.Mode = AddrModeFlat; - frame.AddrStack.Offset = ctx.Rsp; frame.AddrStack.Mode = AddrModeFlat; - frame.AddrFrame.Offset = ctx.Rbp; frame.AddrFrame.Mode = AddrModeFlat; +#if defined(_M_X64) + frame.AddrPC.Offset = ctx.Rip; + frame.AddrStack.Offset = ctx.Rsp; + frame.AddrFrame.Offset = ctx.Rbp; +#elif define(_M_ARM64) + frame.AddrPC.Offset = ctx.Pc; + frame.AddrStack.Offset = ctx.Sp; + frame.AddrFrame.Offset = ctx.Fp; #endif int depth = 0; diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index b6693adf689..8ff6d34119b 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -18,18 +18,20 @@ #include "tasktimers.h" #include +#include #include #include #include #include +#include #include #include #include +#include #include #include #include #include -#include #include #include #include @@ -389,6 +391,9 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir) setProgressTitleForToken(indexingToken(), project ? tr("Indexing %1 with clangd").arg(project->displayName()) : tr("Indexing session with clangd")); + setClickHandlerForToken(indexingToken(), [] { + ICore::showOptionsDialog(CppEditor::Constants::CPP_CLANGD_SETTINGS_ID); + }); setCurrentProject(project); setDocumentChangeUpdateThreshold(d->settings.documentUpdateThreshold); setSymbolStringifier(displayNameFromDocumentSymbol); @@ -430,7 +435,10 @@ ClangdClient::~ClangdClient() delete d; } -bool ClangdClient::isFullyIndexed() const { return d->isFullyIndexed; } +bool ClangdClient::isFullyIndexed() const +{ + return d->isFullyIndexed; +} void ClangdClient::openExtraFile(const Utils::FilePath &filePath, const QString &content) { diff --git a/src/plugins/clangcodemodel/clangdsemantichighlighting.cpp b/src/plugins/clangcodemodel/clangdsemantichighlighting.cpp index dcf6a898993..6714c91b04a 100644 --- a/src/plugins/clangcodemodel/clangdsemantichighlighting.cpp +++ b/src/plugins/clangcodemodel/clangdsemantichighlighting.cpp @@ -260,7 +260,7 @@ void doSemanticHighlighting( }; const std::function toResult - = [&ast, &isOutputParameter, &tokenRange] + = [&ast, &isOutputParameter, &tokenRange, ver = clangdVersion.majorVersion()] (const ExpandedSemanticToken &token) { TextStyles styles; if (token.type == "variable") { @@ -275,7 +275,9 @@ void doSemanticHighlighting( } else if (token.type == "function" || token.type == "method") { styles.mainStyle = token.modifiers.contains(QLatin1String("virtual")) ? C_VIRTUAL_METHOD : C_FUNCTION; - if (ast.isValid()) { + if (token.modifiers.contains("definition")) { + styles.mixinStyles.push_back(C_FUNCTION_DEFINITION); + } else if (ver < 16 && ast.isValid()) { const ClangdAstPath path = getAstPath(ast, tokenRange(token)); if (path.length() > 1) { const ClangdAstNode declNode = path.at(path.length() - 2); diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index 913f31a3fd9..679e41004bf 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -427,9 +427,15 @@ static bool isProjectDataUpToDate( return false; if (sessionModeEnabled() && project) return false; - const ProjectInfoList newProjectInfo = project - ? ProjectInfoList{CppModelManager::instance()->projectInfo(project)} - : CppModelManager::instance()->projectInfos(); + ProjectInfoList newProjectInfo; + if (project) { + if (const ProjectInfo::ConstPtr pi = CppModelManager::instance()->projectInfo(project)) + newProjectInfo.append(pi); + else + return false; + } else { + newProjectInfo = CppModelManager::instance()->projectInfos(); + } if (newProjectInfo.size() != projectInfo.size()) return false; for (int i = 0; i < projectInfo.size(); ++i) { @@ -450,8 +456,10 @@ void ClangModelManagerSupport::updateLanguageClient(ProjectExplorer::Project *pr if (sessionModeEnabled()) { project = nullptr; projectInfo = CppModelManager::instance()->projectInfos(); + } else if (const ProjectInfo::ConstPtr pi = CppModelManager::instance()->projectInfo(project)) { + projectInfo.append(pi); } else { - projectInfo.append(CppModelManager::instance()->projectInfo(project)); + return; } const Utils::FilePath jsonDbDir = getJsonDbDir(project); diff --git a/src/plugins/clangcodemodel/clangutils.cpp b/src/plugins/clangcodemodel/clangutils.cpp index fc7c174cbda..4efe2e69f4f 100644 --- a/src/plugins/clangcodemodel/clangutils.cpp +++ b/src/plugins/clangcodemodel/clangutils.cpp @@ -166,8 +166,9 @@ GenerateCompilationDbResult generateCompilationDB(QList p const UsePrecompiledHeaders usePch = getPchUsage(); const QJsonArray jsonProjectOptions = QJsonArray::fromStringList(projectOptions); for (const ProjectInfo::ConstPtr &projectInfo : std::as_const(projectInfoList)) { + QTC_ASSERT(projectInfo, continue); for (ProjectPart::ConstPtr projectPart : projectInfo->projectParts()) { - QTC_ASSERT(projectInfo, continue); + QTC_ASSERT(projectPart, continue); QStringList args; const CompilerOptionsBuilder optionsBuilder = clangOptionsBuilder( *projectPart, warningsConfig, clangIncludeDir, {}); diff --git a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp index 523bafca68d..32a00daf5b0 100644 --- a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp +++ b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp @@ -677,7 +677,7 @@ QVariant CMakeGeneratorKitAspect::defaultValue(const Kit *k) const return g.matches("Ninja"); }); if (it != known.constEnd()) { - const bool hasNinja = [k]() { + const bool hasNinja = [k, tool]() { Internal::CMakeSpecificSettings *settings = Internal::CMakeProjectPlugin::projectTypeSpecificSettings(); @@ -685,7 +685,7 @@ QVariant CMakeGeneratorKitAspect::defaultValue(const Kit *k) const auto findNinja = [](const Environment &env) -> bool { return !env.searchInPath("ninja").isEmpty(); }; - if (!findNinja(Environment::systemEnvironment())) + if (!findNinja(tool->filePath().deviceEnvironment())) return findNinja(k->buildEnvironment()); } return true; diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index 60c11157239..a64ad830d63 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -135,7 +135,7 @@ FilePaths CMakeProjectImporter::importCandidates() // If the binaryFilePath exists, do not try to import the existing build, so that // we don't have duplicates, one from the preset and one from the previous configuration. if (configPreset.binaryDir) { - Environment env = Environment::systemEnvironment(); + Environment env = projectDirectory().deviceEnvironment(); CMakePresets::Macros::expand(configPreset, env, projectDirectory()); QString binaryDir = configPreset.binaryDir.value(); @@ -165,15 +165,15 @@ static CMakeConfig configurationFromPresetProbe( cmake.setTimeoutS(30); cmake.setDisableUnixTerminal(); - Environment env = Environment::systemEnvironment(); + const FilePath cmakeExecutable = FilePath::fromString(configurePreset.cmakeExecutable.value()); + + Environment env = cmakeExecutable.deviceEnvironment(); CMakePresets::Macros::expand(configurePreset, env, importPath); env.setupEnglishOutput(); cmake.setEnvironment(env); cmake.setTimeOutMessageBoxEnabled(false); - const FilePath cmakeExecutable = FilePath::fromString(configurePreset.cmakeExecutable.value()); - QStringList args; args.emplace_back("-S"); args.emplace_back(importPath.path()); @@ -428,7 +428,7 @@ QList CMakeProjectImporter::examineDirectory(const FilePath &importPath, return preset.name == presetName; }); - Environment env = Environment::systemEnvironment(); + Environment env = projectDirectory().deviceEnvironment(); CMakePresets::Macros::expand(configurePreset, env, projectDirectory()); if (configurePreset.displayName) diff --git a/src/plugins/cmakeprojectmanager/presetsmacros.cpp b/src/plugins/cmakeprojectmanager/presetsmacros.cpp index 37896bfb700..1220444cbfb 100644 --- a/src/plugins/cmakeprojectmanager/presetsmacros.cpp +++ b/src/plugins/cmakeprojectmanager/presetsmacros.cpp @@ -280,7 +280,7 @@ bool evaluatePresetCondition(const PresetType &preset, const Utils::FilePath &so if (!preset.condition) return true; - Utils::Environment env = Utils::Environment::systemEnvironment(); + Utils::Environment env = sourceDirectory.deviceEnvironment(); expand(preset, env, sourceDirectory); PresetsDetails::Condition condition = preset.condition.value(); diff --git a/src/plugins/coreplugin/dialogs/newdialogwidget.h b/src/plugins/coreplugin/dialogs/newdialogwidget.h index 2231d9986c5..0b648724b17 100644 --- a/src/plugins/coreplugin/dialogs/newdialogwidget.h +++ b/src/plugins/coreplugin/dialogs/newdialogwidget.h @@ -6,6 +6,7 @@ #include "../iwizardfactory.h" #include "newdialog.h" +#include #include #include #include @@ -30,7 +31,7 @@ namespace Internal { class NewDialogWidget : public QDialog, public NewDialog { - Q_OBJECT + Q_DECLARE_TR_FUNCTIONS(Core::Internal::NewDialog) public: explicit NewDialogWidget(QWidget *parent); diff --git a/src/plugins/coreplugin/progressmanager/futureprogress.cpp b/src/plugins/coreplugin/progressmanager/futureprogress.cpp index 55fc29225d9..b2ea4fdd96a 100644 --- a/src/plugins/coreplugin/progressmanager/futureprogress.cpp +++ b/src/plugins/coreplugin/progressmanager/futureprogress.cpp @@ -121,7 +121,12 @@ FutureProgress::FutureProgress(QWidget *parent) : this, &FutureProgress::setProgressValue); connect(&d->m_watcher, &QFutureWatcherBase::progressTextChanged, this, &FutureProgress::setProgressText); - connect(d->m_progress, &Internal::ProgressBar::clicked, this, &FutureProgress::cancel); + connect(d->m_progress, &Internal::ProgressBar::clicked, this, [this] { + if (isCancelEnabled()) + cancel(); + else + emit clicked(); + }); setMinimumWidth(100); setMaximumWidth(300); } @@ -373,6 +378,16 @@ QSize FutureProgress::sizeHint() const return QSize(QWidget::sizeHint().width(), minimumHeight()); } +bool FutureProgress::isCancelEnabled() const +{ + return d->m_progress->isCancelEnabled(); +} + +void FutureProgress::setCancelEnabled(bool enabled) +{ + d->m_progress->setCancelEnabled(enabled); +} + void FutureProgressPrivate::fadeAway() { m_isFading = true; diff --git a/src/plugins/coreplugin/progressmanager/futureprogress.h b/src/plugins/coreplugin/progressmanager/futureprogress.h index 5277ef66c4e..0f6630cd8c4 100644 --- a/src/plugins/coreplugin/progressmanager/futureprogress.h +++ b/src/plugins/coreplugin/progressmanager/futureprogress.h @@ -59,6 +59,9 @@ public: QSize sizeHint() const override; + bool isCancelEnabled() const; + void setCancelEnabled(bool enabled); + signals: void clicked(); void finished(); diff --git a/src/plugins/coreplugin/systemsettings.cpp b/src/plugins/coreplugin/systemsettings.cpp index 82fbaee7dc4..1213812bd4a 100644 --- a/src/plugins/coreplugin/systemsettings.cpp +++ b/src/plugins/coreplugin/systemsettings.cpp @@ -65,7 +65,7 @@ static QString formatSize(qint64 size) class SystemSettingsWidget : public IOptionsPageWidget { - Q_DECLARE_TR_FUNCTIONS(Core::Internal::SystemSettingsWidget) + Q_DECLARE_TR_FUNCTIONS(Core::Internal::SystemSettings) public: SystemSettingsWidget() diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index d61f3c720a7..5c99329675a 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -879,6 +879,8 @@ void Client::deactivateDocument(TextEditor::TextDocument *document) TextEditor::TextEditorWidget *widget = textEditor->editorWidget(); widget->removeHoverHandler(&d->m_hoverHandler); widget->setExtraSelections(TextEditor::TextEditorWidget::CodeSemanticsSelection, {}); + widget->setRefactorMarkers( + TextEditor::RefactorMarker::filterOutType(widget->refactorMarkers(), id())); updateEditorToolBar(editor); } } @@ -1573,6 +1575,12 @@ void Client::setProgressTitleForToken(const LanguageServerProtocol::ProgressToke d->m_progressManager.setTitleForToken(token, message); } +void Client::setClickHandlerForToken(const LanguageServerProtocol::ProgressToken &token, + const std::function &handler) +{ + d->m_progressManager.setClickHandlerForToken(token, handler); +} + void Client::handleMessage(const LanguageServerProtocol::JsonRpcMessage &message) { LanguageClientManager::logJsonRpcMessage(LspLogMessage::ServerMessage, name(), message); diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h index 5f29f080590..7061b9514ec 100644 --- a/src/plugins/languageclient/client.h +++ b/src/plugins/languageclient/client.h @@ -197,6 +197,8 @@ protected: void setError(const QString &message); void setProgressTitleForToken(const LanguageServerProtocol::ProgressToken &token, const QString &message); + void setClickHandlerForToken(const LanguageServerProtocol::ProgressToken &token, + const std::function &handler); void handleMessage(const LanguageServerProtocol::JsonRpcMessage &message); virtual void handleDiagnostics(const LanguageServerProtocol::PublishDiagnosticsParams ¶ms); virtual DiagnosticManager *createDiagnosticManager(); diff --git a/src/plugins/languageclient/progressmanager.cpp b/src/plugins/languageclient/progressmanager.cpp index a2c6ae5ec2b..241c51b2937 100644 --- a/src/plugins/languageclient/progressmanager.cpp +++ b/src/plugins/languageclient/progressmanager.cpp @@ -41,6 +41,12 @@ void ProgressManager::setTitleForToken(const LanguageServerProtocol::ProgressTok m_titles.insert(token, message); } +void ProgressManager::setClickHandlerForToken(const LanguageServerProtocol::ProgressToken &token, + const std::function &handler) +{ + m_clickHandlers.insert(token, handler); +} + void ProgressManager::reset() { const QList &tokens = m_progress.keys(); @@ -72,6 +78,10 @@ void ProgressManager::beginProgress(const ProgressToken &token, const WorkDonePr const QString title = m_titles.value(token, begin.title()); Core::FutureProgress *progress = Core::ProgressManager::addTask( interface->future(), title, languageClientProgressId(token)); + progress->setCancelEnabled(false); + const std::function clickHandler = m_clickHandlers.value(token); + if (clickHandler) + QObject::connect(progress, &Core::FutureProgress::clicked, clickHandler); m_progress[token] = {progress, interface}; if (LOGPROGRESS().isDebugEnabled()) m_timer[token].start(); diff --git a/src/plugins/languageclient/progressmanager.h b/src/plugins/languageclient/progressmanager.h index 0a940a960b3..2170fb3f0d0 100644 --- a/src/plugins/languageclient/progressmanager.h +++ b/src/plugins/languageclient/progressmanager.h @@ -27,6 +27,8 @@ public: void handleProgress(const LanguageServerProtocol::ProgressParams ¶ms); void setTitleForToken(const LanguageServerProtocol::ProgressToken &token, const QString &message); + void setClickHandlerForToken(const LanguageServerProtocol::ProgressToken &token, + const std::function &handler); void reset(); static bool isProgressEndMessage(const LanguageServerProtocol::ProgressParams ¶ms); @@ -48,6 +50,7 @@ private: QMap m_progress; QMap m_titles; QMap m_timer; + QMap> m_clickHandlers; }; } // namespace LanguageClient diff --git a/src/plugins/projectexplorer/abstractprocessstep.cpp b/src/plugins/projectexplorer/abstractprocessstep.cpp index 65b2518ba37..74919217996 100644 --- a/src/plugins/projectexplorer/abstractprocessstep.cpp +++ b/src/plugins/projectexplorer/abstractprocessstep.cpp @@ -152,7 +152,8 @@ bool AbstractProcessStep::init() if (d->m_process) return false; - setupProcessParameters(processParameters()); + if (!setupProcessParameters(processParameters())) + return false; return true; } @@ -233,7 +234,7 @@ ProcessParameters *AbstractProcessStep::processParameters() return &d->m_param; } -void AbstractProcessStep::setupProcessParameters(ProcessParameters *params) const +bool AbstractProcessStep::setupProcessParameters(ProcessParameters *params) const { params->setMacroExpander(macroExpander()); @@ -242,13 +243,21 @@ void AbstractProcessStep::setupProcessParameters(ProcessParameters *params) cons d->m_environmentModifier(env); params->setEnvironment(env); - if (d->m_workingDirectoryProvider) - params->setWorkingDirectory(d->m_workingDirectoryProvider()); - else - params->setWorkingDirectory(buildDirectory()); - if (d->m_commandLineProvider) params->setCommandLine(d->m_commandLineProvider()); + + FilePath workingDirectory; + if (d->m_workingDirectoryProvider) + workingDirectory = d->m_workingDirectoryProvider(); + else + workingDirectory = buildDirectory(); + + const FilePath executable = params->effectiveCommand(); + + QTC_ASSERT(executable.ensureReachable(workingDirectory), return false); + params->setWorkingDirectory(workingDirectory.onDevice(executable)); + + return true; } void AbstractProcessStep::Private::cleanUp(int exitCode, QProcess::ExitStatus status) diff --git a/src/plugins/projectexplorer/abstractprocessstep.h b/src/plugins/projectexplorer/abstractprocessstep.h index 731bc7e89b5..47c8ccef1a2 100644 --- a/src/plugins/projectexplorer/abstractprocessstep.h +++ b/src/plugins/projectexplorer/abstractprocessstep.h @@ -21,7 +21,7 @@ class PROJECTEXPLORER_EXPORT AbstractProcessStep : public BuildStep public: ProcessParameters *processParameters(); - void setupProcessParameters(ProcessParameters *params) const; + bool setupProcessParameters(ProcessParameters *params) const; bool ignoreReturnValue() const; void setIgnoreReturnValue(bool b); diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index 125eb269722..a77b24bc059 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -2085,16 +2085,23 @@ std::optional MsvcToolChain::generateEnvironmentSettings(const Utils::E // Create a batch file to create and save the env settings Utils::TempFileSaver saver(Utils::TemporaryDirectory::masterDirectoryPath() + "/XXXXXX.bat"); - QByteArray call = "call "; - call += ProcessArgs::quoteArg(batchFile).toLocal8Bit(); - if (!batchArgs.isEmpty()) { - call += ' '; - call += batchArgs.toLocal8Bit(); - } + auto makeCall = [](const QString &batchFile, const QString &batchArgs) -> QByteArray { + QByteArray call = "call "; + call += ProcessArgs::quoteArg(batchFile).toLocal8Bit(); + if (!batchArgs.isEmpty()) { + call += ' '; + call += batchArgs.toLocal8Bit(); + } + return call; + }; + QByteArray callCleanEnv = makeCall(batchFile, "/clean_env"); + QByteArray call = makeCall(batchFile, batchArgs); + if (Utils::HostOsInfo::isWindowsHost()) saver.write("chcp 65001\r\n"); saver.write("set VSCMD_SKIP_SENDTELEMETRY=1\r\n"); saver.write("set CLINK_NOAUTORUN=1\r\n"); + saver.write(callCleanEnv + "\r\n"); saver.write(call + "\r\n"); saver.write("@echo " + marker.toLocal8Bit() + "\r\n"); saver.write("set\r\n");