From 1eb2535c625c4f19f243d09636d7f84a08c183a8 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 19 Jun 2024 10:36:29 +0200 Subject: [PATCH 01/36] ProjectExplorer: fix warnings of projectnodeshelper.h Change-Id: I79ed8b4ac9fa3e8c25438678011e455bfedbaabc Reviewed-by: Jarek Kobus --- .../projectexplorer/projectnodeshelper.h | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/plugins/projectexplorer/projectnodeshelper.h b/src/plugins/projectexplorer/projectnodeshelper.h index 24edc853165..37b015ec321 100644 --- a/src/plugins/projectexplorer/projectnodeshelper.h +++ b/src/plugins/projectexplorer/projectnodeshelper.h @@ -29,8 +29,8 @@ struct DirectoryScanResult static DirectoryScanResult scanForFiles( const QFuture &future, const Utils::FilePath &directory, - const QDir::Filters &filter, - const std::function factory, + QDir::Filters filter, + const std::function &factory, const QList &versionControls) { DirectoryScanResult result; @@ -57,10 +57,10 @@ static DirectoryScanResult scanForFiles( template QList scanForFilesRecursively( QPromise &promise, - double progressRange, + int progressRange, const Utils::FilePath &directory, - const QDir::Filters &filter, - const std::function factory, + QDir::Filters filter, + const std::function &factory, const QList &versionControls) { const QFuture future(promise.future()); @@ -69,10 +69,9 @@ QList scanForFilesRecursively( const DirectoryScanResult result = scanForFiles(future, directory, filter, factory, versionControls); QList fileNodes = result.nodes; - const double progressIncrement = progressRange - / static_cast( - fileNodes.count() + result.subDirectories.count()); - promise.setProgressValue(fileNodes.count() * progressIncrement); + const int progressIncrement = int( + progressRange / static_cast(fileNodes.count() + result.subDirectories.count())); + promise.setProgressValue(int(fileNodes.count() * progressIncrement)); QList> subDirectories; auto addSubDirectories = [&](const Utils::FilePaths &subdirs, int progressIncrement) { for (const Utils::FilePath &subdir : subdirs) { @@ -98,12 +97,13 @@ QList scanForFilesRecursively( const int progressRange = iterator->second; const DirectoryScanResult result = task.result(); fileNodes.append(result.nodes); - const int subDirCount = result.subDirectories.count(); + const qsizetype subDirCount = result.subDirectories.count(); if (subDirCount == 0) { promise.setProgressValue(promise.future().progressValue() + progressRange); } else { - const int fileCount = result.nodes.count(); - const int increment = progressRange / static_cast(fileCount + subDirCount); + const qsizetype fileCount = result.nodes.count(); + const int increment = int( + progressRange / static_cast(fileCount + subDirCount)); promise.setProgressValue( promise.future().progressValue() + increment * fileCount); addSubDirectories(result.subDirectories, increment); @@ -126,12 +126,12 @@ template QList scanForFiles( QPromise &promise, const Utils::FilePath &directory, - const QDir::Filters &filter, - const std::function factory) + QDir::Filters filter, + const std::function &factory) { promise.setProgressRange(0, 1000000); return Internal::scanForFilesRecursively(promise, - 1000000.0, + 1000000, directory, filter, factory, From d7ed05ae14e3ced9fc57707085da56de6a35cd9e Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 13 Jun 2024 12:57:55 +0200 Subject: [PATCH 02/36] ClangTools: Do not assume there is a corresponding open document ... when creating a TextMark. Amends 2ad12b5b2c24018c89e91ef0b2355b3ac65edbaf. Change-Id: Ic748012dadda0fc94814176589a3bdff20cb4cd6 Reviewed-by: David Schulz --- src/plugins/clangtools/diagnosticmark.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/plugins/clangtools/diagnosticmark.cpp b/src/plugins/clangtools/diagnosticmark.cpp index 90b4e19812d..5ea0895b947 100644 --- a/src/plugins/clangtools/diagnosticmark.cpp +++ b/src/plugins/clangtools/diagnosticmark.cpp @@ -20,10 +20,13 @@ using namespace Utils; namespace ClangTools { namespace Internal { +static TextMarkCategory clangToolsCategory() +{ + return {Tr::tr("Clang Tools"), Id(Constants::DIAGNOSTIC_MARK_ID)}; +} + DiagnosticMark::DiagnosticMark(const Diagnostic &diagnostic, TextDocument *document) - : TextMark(document, - diagnostic.location.line, - {Tr::tr("Clang Tools"), Id(Constants::DIAGNOSTIC_MARK_ID)}) + : TextMark(document, diagnostic.location.line, clangToolsCategory()) , m_diagnostic(diagnostic) { setSettingsPage(Constants::SETTINGS_PAGE_ID); @@ -60,7 +63,8 @@ DiagnosticMark::DiagnosticMark(const Diagnostic &diagnostic, TextDocument *docum } DiagnosticMark::DiagnosticMark(const Diagnostic &diagnostic) - : DiagnosticMark(diagnostic, TextDocument::textDocumentForFilePath(diagnostic.location.filePath)) + : TextMark(diagnostic.location.filePath, diagnostic.location.line, clangToolsCategory()) + , m_diagnostic(diagnostic) {} void DiagnosticMark::disable() From b0428120c46dd456f7fa9a45575ef75938a11380 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Tue, 18 Jun 2024 15:50:42 +0200 Subject: [PATCH 03/36] Doc: Describe the option for hiding unconfigured kits Task-number: QTCREATORBUG-30604 Change-Id: Ia36c9734937cb7de4e07b417ef36dee178f24f3c Reviewed-by: Eike Ziller --- dist/changelog/changes-14.0.0.md | 4 ++-- ...creator-preferences-build-run-general.webp | Bin 14392 -> 15290 bytes .../images/qtcreator-projects-kits.webp | Bin 13522 -> 11436 bytes .../creator-projects-settings-overview.qdoc | 3 +++ 4 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dist/changelog/changes-14.0.0.md b/dist/changelog/changes-14.0.0.md index 31a3e5daa04..c3d72f61d35 100644 --- a/dist/changelog/changes-14.0.0.md +++ b/dist/changelog/changes-14.0.0.md @@ -131,8 +131,8 @@ Editing Projects -------- -* Added the option to hide all unconfigured kits from the list in `Projects` - mode +* Added the `Hide Inactive Kits`/`Show All Kits` button to hide inactive kits + from the list in the `Projects` mode * Added support for user comments in the environment editor * Fixed the parsing of file links when color was used for the output ([QTCREATORBUG-30774](https://bugreports.qt.io/browse/QTCREATORBUG-30774)) diff --git a/doc/qtcreator/images/qtcreator-preferences-build-run-general.webp b/doc/qtcreator/images/qtcreator-preferences-build-run-general.webp index 4826e22fc62d08ede7e18bac673f5745310ee793..6a0bf6f48113c48889ded3b332cad4166ac0c015 100644 GIT binary patch literal 15290 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 Iaw(%A0C08wJpcdz literal 14392 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 literal 13522 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 diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-settings-overview.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-settings-overview.qdoc index 75544e47e80..0a7b13eb393 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-settings-overview.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-settings-overview.qdoc @@ -127,6 +127,9 @@ is not suitable for the project type. To view the warning and error messages, move the mouse pointer over the kit name. + To hide inactive kits from the list, select \uicontrol {Hide Inactive Kits}. + To show them again, select \uicontrol {Show All Kits}. + \section1 Manage kits To modify kit configuration or to \l{Add kits}{add kits} to the list or to From 044c1f686cc0b142f7033aba21ce2b26bfe4f008 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 18 Jun 2024 12:46:57 +0200 Subject: [PATCH 04/36] PE: Fix handling of settings Amends 81f8a3fd7d13bdfa6610b259df44aa0ef993a8f4. Fixes: QTCREATORBUG-30680 Change-Id: I47c2c50f1acb1888dc8e3514e942ebefaf87e6ca Reviewed-by: hjk Reviewed-by: Ulf Hermann --- src/plugins/projectexplorer/runconfiguration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 97d467fbc75..2f5dfc2513d 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -71,7 +71,7 @@ void GlobalOrProjectAspect::setProjectSettings(AspectContainer *settings) void GlobalOrProjectAspect::setGlobalSettings(AspectContainer *settings) { m_globalSettings = settings; - m_projectSettings->setAutoApply(false); + m_globalSettings->setAutoApply(false); } void GlobalOrProjectAspect::setUsingGlobalSettings(bool value) From 282960528e13c1c79751422e557846e5848344f9 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 19 Jun 2024 13:16:22 +0200 Subject: [PATCH 05/36] Valgrind: Remove no more needed fix This was needed to fix the handling of the project settings, since 044c1f686cc0b142f7033aba21ce2b26bfe4f008 no more needed. Change-Id: I960078b0ca39739ad566caeba46edf1a5050ebef Reviewed-by: hjk --- src/plugins/valgrind/valgrindsettings.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/plugins/valgrind/valgrindsettings.cpp b/src/plugins/valgrind/valgrindsettings.cpp index 47f45973747..0a92f391d3b 100644 --- a/src/plugins/valgrind/valgrindsettings.cpp +++ b/src/plugins/valgrind/valgrindsettings.cpp @@ -392,19 +392,8 @@ ValgrindSettings::ValgrindSettings(bool global) // clang-format on }); - if (global) { + if (global) readSettings(); - } else { - // FIXME: Is this needed? - connect(this, &AspectContainer::fromMapFinished, [this] { - // FIXME: Update project page e.g. on "Restore Global", aspects - // there are 'autoapply', and Aspect::cancel() is normally part of - // the 'manual apply' machinery. - setAutoApply(false); - cancel(); - setAutoApply(true); - }); - } } ValgrindSettings &globalSettings() From 39570fb675e16ff8f5f5feff9029af3d25797934 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 13 Jun 2024 11:24:01 +0200 Subject: [PATCH 06/36] Utils: Rename PathChooser::rawFilePath() to unxepandedFilePath() That's what the implementation does, and judging from the using code wasn't quite clear. Change-Id: I4ca776ba4da83a36162adad2dd595eb39eb0f43d Reviewed-by: Eike Ziller --- src/libs/utils/pathchooser.cpp | 4 ++-- src/libs/utils/pathchooser.h | 4 ++-- src/plugins/android/androidbuildapkstep.cpp | 2 +- src/plugins/android/createandroidmanifestwizard.cpp | 2 +- src/plugins/clangtools/settingswidget.cpp | 4 ++-- src/plugins/clearcase/settingspage.cpp | 2 +- src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp | 4 ++-- src/plugins/coreplugin/dialogs/externaltoolconfig.cpp | 6 +++--- src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp | 2 +- src/plugins/debugger/debuggersourcepathmappingwidget.cpp | 2 +- src/plugins/debugger/loadcoredialog.cpp | 4 ++-- src/plugins/haskell/haskellbuildconfiguration.cpp | 2 +- src/plugins/incredibuild/commandbuilderaspect.cpp | 2 +- src/plugins/mcusupport/mcupackage.cpp | 2 +- src/plugins/nim/project/nimtoolchain.cpp | 2 +- src/plugins/projectexplorer/runconfigurationaspects.cpp | 2 +- src/plugins/qbsprojectmanager/qbsbuildstep.cpp | 4 ++-- src/plugins/qtsupport/qtoptionspage.cpp | 2 +- 18 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp index 9b2177fedb6..8e941f52a34 100644 --- a/src/libs/utils/pathchooser.cpp +++ b/src/libs/utils/pathchooser.cpp @@ -342,14 +342,14 @@ void PathChooser::setEnvironment(const Environment &env) } } -FilePath PathChooser::rawFilePath() const +FilePath PathChooser::unexpandedFilePath() const { return FilePath::fromUserInput(d->m_lineEdit->text()); } FilePath PathChooser::filePath() const { - return d->expandedPath(rawFilePath()); + return d->expandedPath(unexpandedFilePath()); } FilePath PathChooser::absoluteFilePath() const diff --git a/src/libs/utils/pathchooser.h b/src/libs/utils/pathchooser.h index a3e259a748d..b0d70e90b8f 100644 --- a/src/libs/utils/pathchooser.h +++ b/src/libs/utils/pathchooser.h @@ -67,10 +67,10 @@ public: bool isValid() const; QString errorMessage() const; - FilePath filePath() const; // Close to what's in the line edit. + FilePath filePath() const; // Close to what's in the line edit. Expands macros. FilePath absoluteFilePath() const; // Relative paths resolved wrt the specified base dir. - FilePath rawFilePath() const; // The raw unexpanded input as FilePath. + FilePath unexpandedFilePath() const; // The raw unexpanded input as FilePath. FilePath baseDirectory() const; void setBaseDirectory(const FilePath &base); diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index 51f73180971..3ad6a4ba849 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -140,7 +140,7 @@ AndroidBuildApkWidget::AndroidBuildApkWidget(AndroidBuildApkStep *step) keystoreLocationChooser->setPromptDialogFilter(Tr::tr("Keystore files (*.keystore *.jks)")); keystoreLocationChooser->setPromptDialogTitle(Tr::tr("Select Keystore File")); connect(keystoreLocationChooser, &PathChooser::textChanged, this, [this, keystoreLocationChooser] { - const FilePath file = keystoreLocationChooser->rawFilePath(); + const FilePath file = keystoreLocationChooser->unexpandedFilePath(); m_step->setKeystorePath(file); m_signPackageCheckBox->setChecked(!file.isEmpty()); if (!file.isEmpty()) diff --git a/src/plugins/android/createandroidmanifestwizard.cpp b/src/plugins/android/createandroidmanifestwizard.cpp index 8f50666419a..18a7872e08d 100644 --- a/src/plugins/android/createandroidmanifestwizard.cpp +++ b/src/plugins/android/createandroidmanifestwizard.cpp @@ -151,7 +151,7 @@ ChooseDirectoryPage::ChooseDirectoryPage(CreateAndroidManifestWizard *wizard) m_layout->addRow(m_sourceDirectoryWarning); connect(m_androidPackageSourceDir, &PathChooser::textChanged, m_wizard, [this] { - m_wizard->setDirectory(m_androidPackageSourceDir->rawFilePath()); + m_wizard->setDirectory(m_androidPackageSourceDir->unexpandedFilePath()); }); if (wizard->copyGradle()) { diff --git a/src/plugins/clangtools/settingswidget.cpp b/src/plugins/clangtools/settingswidget.cpp index 113373f57e0..4b686e61ac9 100644 --- a/src/plugins/clangtools/settingswidget.cpp +++ b/src/plugins/clangtools/settingswidget.cpp @@ -99,12 +99,12 @@ SettingsWidget::~SettingsWidget() FilePath SettingsWidget::clangTidyPath() const { - return m_clangTidyPathChooser->rawFilePath(); + return m_clangTidyPathChooser->unexpandedFilePath(); } FilePath SettingsWidget::clazyStandalonePath() const { - return m_clazyStandalonePathChooser->rawFilePath(); + return m_clazyStandalonePathChooser->unexpandedFilePath(); } // ClangToolsOptionsPage diff --git a/src/plugins/clearcase/settingspage.cpp b/src/plugins/clearcase/settingspage.cpp index 010d3d1e98e..713ef78c344 100644 --- a/src/plugins/clearcase/settingspage.cpp +++ b/src/plugins/clearcase/settingspage.cpp @@ -177,7 +177,7 @@ SettingsPageWidget::SettingsPageWidget() void SettingsPageWidget::apply() { ClearCaseSettings rc; - rc.ccCommand = commandPathChooser->rawFilePath().toString(); + rc.ccCommand = commandPathChooser->unexpandedFilePath().toString(); rc.ccBinaryPath = commandPathChooser->filePath(); rc.timeOutS = timeOutSpinBox->value(); rc.autoCheckOut = autoCheckOutCheckBox->isChecked(); diff --git a/src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp b/src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp index c8db1a85cb6..d9e7a943c3d 100644 --- a/src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp +++ b/src/plugins/cmakeprojectmanager/configmodelitemdelegate.cpp @@ -94,8 +94,8 @@ void ConfigModelItemDelegate::setModelData(QWidget *editor, QAbstractItemModel * ConfigModel::DataItem data = ConfigModel::dataItemFromIndex(index); if (data.type == ConfigModel::DataItem::FILE || data.type == ConfigModel::DataItem::DIRECTORY) { auto edit = static_cast(editor); - if (edit->rawFilePath().toString() != data.value) - model->setData(index, edit->rawFilePath().toString(), Qt::EditRole); + if (edit->unexpandedFilePath().toString() != data.value) + model->setData(index, edit->unexpandedFilePath().toString(), Qt::EditRole); return; } else if (!data.values.isEmpty()) { auto edit = static_cast(editor); diff --git a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp index 76ff935975d..a758adf1053 100644 --- a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp +++ b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp @@ -700,12 +700,12 @@ void ExternalToolConfig::updateItem(const QModelIndex &index) tool->setDescription(m_description->text()); FilePaths executables = tool->executables(); if (executables.size() > 0) - executables[0] = m_executable->rawFilePath(); + executables[0] = m_executable->unexpandedFilePath(); else - executables << m_executable->rawFilePath(); + executables << m_executable->unexpandedFilePath(); tool->setExecutables(executables); tool->setArguments(m_arguments->text()); - tool->setWorkingDirectory(m_workingDirectory->rawFilePath()); + tool->setWorkingDirectory(m_workingDirectory->unexpandedFilePath()); tool->setBaseEnvironmentProviderId(Id::fromSetting(m_baseEnvironment->currentData())); tool->setEnvironmentUserChanges(m_environment); tool->setOutputHandling(ExternalTool::OutputHandling(m_outputBehavior->currentIndex())); diff --git a/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp b/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp index d8f07178b43..259ffb6aa4a 100644 --- a/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp @@ -231,7 +231,7 @@ bool SpotlightLocatorFilter::openConfigDialog(QWidget *parent, bool &needsRefres chooser->addSupportedWidget(caseSensitiveArgumentsEdit); const bool accepted = ILocatorFilter::openConfigDialog(parent, &configWidget); if (accepted) { - m_command = commandEdit->rawFilePath().toString(); + m_command = commandEdit->unexpandedFilePath().toString(); m_arguments = argumentsEdit->text(); m_caseSensitiveArguments = caseSensitiveArgumentsEdit->text(); m_sortResults = sortResults->isChecked(); diff --git a/src/plugins/debugger/debuggersourcepathmappingwidget.cpp b/src/plugins/debugger/debuggersourcepathmappingwidget.cpp index 98b84e2020e..e8f231473b2 100644 --- a/src/plugins/debugger/debuggersourcepathmappingwidget.cpp +++ b/src/plugins/debugger/debuggersourcepathmappingwidget.cpp @@ -309,7 +309,7 @@ QString DebuggerSourcePathMappingWidget::editSourceField() const QString DebuggerSourcePathMappingWidget::editTargetField() const { - return m_targetChooser->rawFilePath().toString(); + return m_targetChooser->unexpandedFilePath().toString(); } void DebuggerSourcePathMappingWidget::setEditFieldMapping(const Mapping &m) diff --git a/src/plugins/debugger/loadcoredialog.cpp b/src/plugins/debugger/loadcoredialog.cpp index 4c006199700..937c77b8e19 100644 --- a/src/plugins/debugger/loadcoredialog.cpp +++ b/src/plugins/debugger/loadcoredialog.cpp @@ -163,10 +163,10 @@ int AttachCoreDialog::exec() { connect(d->symbolFileName, &PathChooser::validChanged, this, &AttachCoreDialog::changed); connect(d->coreFileName, &PathChooser::validChanged, this, [this] { - coreFileChanged(d->coreFileName->rawFilePath()); + coreFileChanged(d->coreFileName->unexpandedFilePath()); }); connect(d->coreFileName, &PathChooser::textChanged, this, [this] { - coreFileChanged(d->coreFileName->rawFilePath()); + coreFileChanged(d->coreFileName->unexpandedFilePath()); }); connect(d->kitChooser, &KitChooser::currentIndexChanged, this, &AttachCoreDialog::changed); connect(d->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); diff --git a/src/plugins/haskell/haskellbuildconfiguration.cpp b/src/plugins/haskell/haskellbuildconfiguration.cpp index 1434833ff65..bb8ef948705 100644 --- a/src/plugins/haskell/haskellbuildconfiguration.cpp +++ b/src/plugins/haskell/haskellbuildconfiguration.cpp @@ -90,7 +90,7 @@ public: &Utils::PathChooser::textChanged, bc, [bc, buildDirectoryInput](const QString &) { - bc->setBuildDirectory(buildDirectoryInput->rawFilePath()); + bc->setBuildDirectory(buildDirectoryInput->unexpandedFilePath()); }); } }; diff --git a/src/plugins/incredibuild/commandbuilderaspect.cpp b/src/plugins/incredibuild/commandbuilderaspect.cpp index 38d0d858e8e..83476af36ff 100644 --- a/src/plugins/incredibuild/commandbuilderaspect.cpp +++ b/src/plugins/incredibuild/commandbuilderaspect.cpp @@ -132,7 +132,7 @@ void CommandBuilderAspect::addToLayout(Layouting::Layout &parent) d->makePathChooser->setBaseDirectory(PathChooser::homePath()); d->makePathChooser->setHistoryCompleter("IncrediBuild.BuildConsole.MakeCommand.History"); connect(d->makePathChooser, &PathChooser::rawPathChanged, this, [this] { - d->m_activeCommandBuilder->setCommand(d->makePathChooser->rawFilePath()); + d->m_activeCommandBuilder->setCommand(d->makePathChooser->unexpandedFilePath()); updateGui(); }); } diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp index 2ccc4bcc1a0..20ee020ae32 100644 --- a/src/plugins/mcusupport/mcupackage.cpp +++ b/src/plugins/mcusupport/mcupackage.cpp @@ -314,7 +314,7 @@ QWidget *McuPackage::widget() QObject::connect(this, &McuPackage::statusChanged, widget, [this] { updateStatusUi(); }); QObject::connect(m_fileChooser, &PathChooser::textChanged, this, [this] { - setPath(m_fileChooser->rawFilePath()); + setPath(m_fileChooser->unexpandedFilePath()); }); connect(this, &McuPackage::changed, m_fileChooser, [this] { diff --git a/src/plugins/nim/project/nimtoolchain.cpp b/src/plugins/nim/project/nimtoolchain.cpp index 80036592644..701883de0c0 100644 --- a/src/plugins/nim/project/nimtoolchain.cpp +++ b/src/plugins/nim/project/nimtoolchain.cpp @@ -141,7 +141,7 @@ public: // Connect connect(m_compilerCommand, &PathChooser::validChanged, this, [this] { - const FilePath path = m_compilerCommand->rawFilePath(); + const FilePath path = m_compilerCommand->unexpandedFilePath(); auto tc = static_cast(toolchain()); QTC_ASSERT(tc, return); tc->setCompilerCommand(path); diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp index a383438c8b5..01003a97668 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.cpp +++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp @@ -186,7 +186,7 @@ void WorkingDirectoryAspect::addToLayout(Layout &builder) m_chooser->setBaseDirectory(m_defaultWorkingDirectory); m_chooser->setFilePath(m_workingDirectory.isEmpty() ? m_defaultWorkingDirectory : m_workingDirectory); connect(m_chooser.data(), &PathChooser::textChanged, this, [this] { - m_workingDirectory = m_chooser->rawFilePath(); + m_workingDirectory = m_chooser->unexpandedFilePath(); m_resetButton->setEnabled(m_workingDirectory != m_defaultWorkingDirectory); }); diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp index 9d0a9f642cf..c079f007b16 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp +++ b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp @@ -610,7 +610,7 @@ void QbsBuildStepConfigWidget::changeUseDefaultInstallDir(bool useDefault) if (useDefault) config.remove(Constants::QBS_INSTALL_ROOT_KEY); else - config.insert(Constants::QBS_INSTALL_ROOT_KEY, installDirChooser->rawFilePath().toString()); + config.insert(Constants::QBS_INSTALL_ROOT_KEY, installDirChooser->unexpandedFilePath().toString()); m_qbsStep->setQbsConfiguration(config); } @@ -620,7 +620,7 @@ void QbsBuildStepConfigWidget::changeInstallDir() return; const GuardLocker locker(m_ignoreChanges); Store config = m_qbsStep->qbsConfiguration(QbsBuildStep::PreserveVariables); - config.insert(Constants::QBS_INSTALL_ROOT_KEY, installDirChooser->rawFilePath().toString()); + config.insert(Constants::QBS_INSTALL_ROOT_KEY, installDirChooser->unexpandedFilePath().toString()); m_qbsStep->setQbsConfiguration(config); } diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp index 7b08db2351a..3be1bc2570b 100644 --- a/src/plugins/qtsupport/qtoptionspage.cpp +++ b/src/plugins/qtsupport/qtoptionspage.cpp @@ -1036,7 +1036,7 @@ void QtSettingsPageWidget::linkWithQt() dialog.exec(); if (dialog.result() == QDialog::Accepted) { const std::optional settingsDir = settingsDirForQtDir(pathInput->baseDirectory(), - pathInput->rawFilePath()); + pathInput->unexpandedFilePath()); if (QTC_GUARD(settingsDir)) { const QString settingsFilePath = settingsFile(ICore::resourcePath().toString()); QSettings settings(settingsFilePath, QSettings::IniFormat); From 1563e0173ee3814e9717bd3bd959f3b39c70b5ee Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 13 Jun 2024 16:08:09 +0200 Subject: [PATCH 07/36] TextEditor: Fix some deprecation warnings QT_DEPRECATED_VERSION_X_6_1("Use setFontFamilies instead") inline void setFontFamily(const QString &family) { setProperty(FontFamilies, QVariant(QStringList(family))); } Change-Id: I22f48abf783404a80e9d8d604d1ff886c2a55f14 Reviewed-by: David Schulz --- .../qmldesigner/components/richtexteditor/richtexteditor.cpp | 2 +- src/plugins/texteditor/fontsettings.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmldesigner/components/richtexteditor/richtexteditor.cpp b/src/plugins/qmldesigner/components/richtexteditor/richtexteditor.cpp index 8a9ed00c400..940b121b9ed 100644 --- a/src/plugins/qmldesigner/components/richtexteditor/richtexteditor.cpp +++ b/src/plugins/qmldesigner/components/richtexteditor/richtexteditor.cpp @@ -532,7 +532,7 @@ void RichTextEditor::setupFontActions() w->setCurrentIndex(w->findText(m_textEdit->currentCharFormat().font().family())); connect(w, &QComboBox::textActivated, [this](const QString &f) { QTextCharFormat fmt; - fmt.setFontFamily(f); + fmt.setFontFamilies({f}); mergeFormatOnWordOrSelection(fmt); }); }); diff --git a/src/plugins/texteditor/fontsettings.cpp b/src/plugins/texteditor/fontsettings.cpp index 44b179d01c8..3cb58fd1282 100644 --- a/src/plugins/texteditor/fontsettings.cpp +++ b/src/plugins/texteditor/fontsettings.cpp @@ -156,7 +156,7 @@ QTextCharFormat FontSettings::toTextCharFormat(TextStyle category) const QTextCharFormat tf; if (category == C_TEXT) { - tf.setFontFamily(m_family); + tf.setFontFamilies({m_family}); tf.setFontPointSize(m_fontSize * m_fontZoom / 100.); tf.setFontStyleStrategy(m_antialias ? QFont::PreferAntialias : QFont::NoAntialias); } From 8404bb5c81068821a8aa23a05c95790e464067aa Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 20 Jun 2024 08:04:46 +0200 Subject: [PATCH 08/36] Lua: Add images to qbs build Change-Id: If898960c5e195ddcf733e847f09ea1301a48de11 Reviewed-by: Marcus Tillmanns --- src/plugins/lua/lua.qbs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/lua/lua.qbs b/src/plugins/lua/lua.qbs index 2a539bb0b4d..d4402c25ee3 100644 --- a/src/plugins/lua/lua.qbs +++ b/src/plugins/lua/lua.qbs @@ -82,6 +82,13 @@ QtcPlugin { ] } + Group { + name: "Lua images rcc" + Qt.core.resourcePrefix: "lua/images/" + fileTags: "qt.core.resource_data" + files: "images/**" + } + Export { Depends { name: "sol2" } Depends { name: "lua546" } From 611f6bdbeab7778e3df4e0e6c296fb6e21dafb18 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Wed, 19 Jun 2024 18:53:39 +0200 Subject: [PATCH 09/36] Lua: Don't destroy lua state too early The Lua state needs to stay alive as long as any references to it may be alive. Therefore this patch leaves the destruction to the end. Fixes: QTCREATORBUG-31087 Change-Id: Ic49723575f7d2fe474cba9546845b65d57d7dcd0 Reviewed-by: Eike Ziller --- src/plugins/lua/luaengine.h | 2 +- src/plugins/lua/luapluginspec.cpp | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/plugins/lua/luaengine.h b/src/plugins/lua/luaengine.h index f8fa085d6d0..7c8bbda7c89 100644 --- a/src/plugins/lua/luaengine.h +++ b/src/plugins/lua/luaengine.h @@ -51,7 +51,7 @@ protected: public: using PackageProvider = std::function; - ~LuaEngine(); + ~LuaEngine() override; static LuaEngine &instance(); Utils::expected_str loadPlugin(const Utils::FilePath &path); diff --git a/src/plugins/lua/luapluginspec.cpp b/src/plugins/lua/luapluginspec.cpp index 4d0e9d76708..3e6b1eb3edd 100644 --- a/src/plugins/lua/luapluginspec.cpp +++ b/src/plugins/lua/luapluginspec.cpp @@ -144,14 +144,11 @@ bool LuaPluginSpec::delayedInitialize() } ExtensionSystem::IPlugin::ShutdownFlag LuaPluginSpec::stop() { - d->activeLuaState.reset(); + d->activeLuaState->stack_clear(); return ExtensionSystem::IPlugin::ShutdownFlag::SynchronousShutdown; } -void LuaPluginSpec::kill() -{ - d->activeLuaState.reset(); -} +void LuaPluginSpec::kill() {} bool LuaPluginSpec::printToOutputPane() const { From 113275118eecd0be474ddfd95ccacb1a81cd4a77 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 19 Jun 2024 17:04:16 +0200 Subject: [PATCH 10/36] Doc: Describe overriding values from Preferences > CMake > General Collect the settings to a table with links to where each setting is documented. Task-number: QTCREATORBUG-30604 Change-Id: Ia06076cdd7f51851f58307119716b4ed3cef630e Reviewed-by: Cristian Adam --- dist/changelog/changes-14.0.0.md | 2 +- .../qtcreator-project-settings-cmake.webp | Bin 0 -> 3508 bytes .../src/cmake/creator-projects-cmake.qdoc | 3 +- .../creator-projects-settings-cmake.qdoc | 72 ++++++++++++++++++ .../creator-projects-settings-overview.qdoc | 1 + 5 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 doc/qtcreator/images/qtcreator-project-settings-cmake.webp create mode 100644 doc/qtcreator/src/cmake/creator-projects-settings-cmake.qdoc diff --git a/dist/changelog/changes-14.0.0.md b/dist/changelog/changes-14.0.0.md index c3d72f61d35..14040fa3ffc 100644 --- a/dist/changelog/changes-14.0.0.md +++ b/dist/changelog/changes-14.0.0.md @@ -148,7 +148,7 @@ Projects * Made CMake settings configurable per project * Implemented `Open Online Documentation` for CMake documentation -* Added `Clear CMake Configuration` to the context menu in the Projects view +* Added `Clear CMake Configuration` to the context menu in the `Projects` view ([QTCREATORBUG-24658](https://bugreports.qt.io/browse/QTCREATORBUG-24658)) * Fixed that the package manager auto-setup files were not removed with `Clear CMake Configuration` diff --git a/doc/qtcreator/images/qtcreator-project-settings-cmake.webp b/doc/qtcreator/images/qtcreator-project-settings-cmake.webp new file mode 100644 index 0000000000000000000000000000000000000000..f37c521a866470b734b8e2b88272408a2c59a115 GIT binary patch literal 3508 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 \uicontrol {Project Settings} > + \uicontrol CMake. + \image qtcreator-project-settings-cmake.webp {CMake settings for a project} + \li Clear \uicontrol {Use global settings}. + \li Configure CMake for the project. + \endlist + + Your choices override the values you set in \preferences > \uicontrol CMake > + \uicontrol General. + + \table + \header + \li Setting + \li Value + \li Read More + \row + \li Autorun CMake + \li Runs CMake to refresh project information when you edit + a \c CMakeLists.txt configuration file in a project. Also, + refreshes project information when you build the project. + \li \l{View CMake project contents} + \row + \li Package manager auto setup + \li Sets up the \l {Conan Package Manager}{Conan} or + \l {vcpkg Package Manager}{vcpkg} package manager for use with CMake. + \li \l{Using CMake with Package Managers} + \row + \li Ask before re-configuring with initial parameters + \li Asks before acting when you select + \uicontrol {Re-configure with Initial Variables}. + \li \l{Re-configuring with Initial Variables} + \row + \li Ask before reloading CMake presets + \li Asks before acting when you select \uicontrol Build > + \uicontrol {Reload CMake Presets}. + \li \l{CMake Presets} + \row + \li Show subfolders inside source group folders + \li Hides subfolder names and arranges the files according to their + source group in the \uicontrol Projects view. + \li \l{Hide subfolder names in Projects view} + \row + \li Show advanced options by default + \li Shows all CMake variables by default in + \uicontrol {Initial Configuration} and + \uicontrol {Current Configuration}. + \li \l{Viewing Advanced Variables} + \row + \li Use junctions for CMake configuration and build operations + \li On Windows, uses junction points for CMake configure, build, and + install operations. + \li \l{Using Junction Points on Windows} + \endtable + + \sa {Build with CMake}{How To: Build with CMake}, {CMake}, + {Configuring Projects} +*/ diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-settings-overview.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-settings-overview.qdoc index 0a7b13eb393..73723857773 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-settings-overview.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-settings-overview.qdoc @@ -84,6 +84,7 @@ \li \l{Link projects to Axivion dashboards}{Axivion} \li \l{Specify clangd settings}{Clangd} \li \l{Specify Clang tools settings}{Clang Tools} + \li \l{Override CMake settings for a project}{CMake} \li \l{Set Copilot preferences}{Copilot} \li \l{Configure C++ code model}{C++ Code Model} \li \l{Specify code style}{C++ Code Style} From 450397f12d89192fc6128ce6e2f6a961808d869b Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 19 Jun 2024 15:49:07 +0200 Subject: [PATCH 11/36] Doc: Update screenshots of environment editor Support for user comments in the editor was already described in an earlier change. Task-number: QTCREATORBUG-30604 Change-Id: I69f147681211256be9e25cf63c5b0b8dbd15f452 Reviewed-by: Christian Stenger --- dist/changelog/changes-14.0.0.md | 1 + .../images/qtcreator-build-environment.webp | Bin 15496 -> 15006 bytes .../images/qtcreator-edit-environment.webp | Bin 5658 -> 6388 bytes .../qtcreator-projects-environment.webp | Bin 6582 -> 7634 bytes .../images/qtcreator-run-environment.webp | Bin 15872 -> 18498 bytes 5 files changed, 1 insertion(+) diff --git a/dist/changelog/changes-14.0.0.md b/dist/changelog/changes-14.0.0.md index 14040fa3ffc..2c0715e9b3b 100644 --- a/dist/changelog/changes-14.0.0.md +++ b/dist/changelog/changes-14.0.0.md @@ -134,6 +134,7 @@ Projects * Added the `Hide Inactive Kits`/`Show All Kits` button to hide inactive kits from the list in the `Projects` mode * Added support for user comments in the environment editor + ([Documentation](https://doc-snapshots.qt.io/qtcreator-14.0/creator-how-to-edit-environment-settings.html)) * Fixed the parsing of file links when color was used for the output ([QTCREATORBUG-30774](https://bugreports.qt.io/browse/QTCREATORBUG-30774)) * Fixed that the column information was not used when opening files from links diff --git a/doc/qtcreator/images/qtcreator-build-environment.webp b/doc/qtcreator/images/qtcreator-build-environment.webp index 48bf4753d2469ec5e89a778c107822d3d058be93..9cc53e85148d189e03c44007fb1d7536a930f95c 100644 GIT binary patch literal 15006 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 literal 15496 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 literal 5658 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 b<+|ED_s_Q}y;;AfJ$d^)*ZR-#$AzW<_agOS diff --git a/doc/qtcreator/images/qtcreator-projects-environment.webp b/doc/qtcreator/images/qtcreator-projects-environment.webp index eeaed5eaa00e560fdc16ca2b501bdcf89b96d02c..6b33d6985222e01a862ecb210a5175af580a3762 100644 GIT binary patch literal 7634 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 diff --git a/doc/qtcreator/images/qtcreator-run-environment.webp b/doc/qtcreator/images/qtcreator-run-environment.webp index 3a0313f994ddb1c44ab80b63696bb58d45b19fd8..7bdd69ebab85d49a2772dd7ae9798b1b0f435d8f 100644 GIT binary patch literal 18498 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 z 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 literal 15872 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 YFRmw^2wb|m;)h{#=AHVyAC2q`0CHtq2mk;8 From 3f1906dc2003c2a42f7fa2c9f830d48a7d4dfdf2 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 19 Jun 2024 14:26:30 +0200 Subject: [PATCH 12/36] Debugger: add cdbext stub file ... and add some typing infos to the cdbbridge Change-Id: If85bc75976c869332ef658c32615f6b110459048 Reviewed-by: Christian Stenger --- share/qtcreator/CMakeLists.txt | 1 + share/qtcreator/debugger/cdbbridge.py | 69 +++++++++++++-------------- share/qtcreator/debugger/cdbext.pyi | 51 ++++++++++++++++++++ 3 files changed, 85 insertions(+), 36 deletions(-) create mode 100644 share/qtcreator/debugger/cdbext.pyi diff --git a/share/qtcreator/CMakeLists.txt b/share/qtcreator/CMakeLists.txt index 73a0837ede2..96791362ec7 100644 --- a/share/qtcreator/CMakeLists.txt +++ b/share/qtcreator/CMakeLists.txt @@ -19,6 +19,7 @@ set(resource_files debugger/.pylintrc debugger/boosttypes.py debugger/cdbbridge.py + debugger/cdbext.pyi debugger/creatortypes.py debugger/dumper.py debugger/gdbbridge.py diff --git a/share/qtcreator/debugger/cdbbridge.py b/share/qtcreator/debugger/cdbbridge.py index 0b53baf1661..c013cb321f7 100644 --- a/share/qtcreator/debugger/cdbbridge.py +++ b/share/qtcreator/debugger/cdbbridge.py @@ -85,12 +85,12 @@ class Dumper(DumperBase): del self.type_size_cache[typeid] del self.type_alignment_cache[typeid] - def enumValue(self, nativeValue): + def enumValue(self, nativeValue: cdbext.Value) -> str: val = nativeValue.nativeDebuggerValue() # remove '0n' decimal prefix of the native cdb value output return val.replace('(0n', '(') - def fromNativeValue(self, nativeValue): + def fromNativeValue(self, nativeValue: cdbext.Value) -> DumperBase.Value: self.check(isinstance(nativeValue, cdbext.Value)) val = self.Value(self) val.name = nativeValue.name() @@ -133,7 +133,7 @@ class Dumper(DumperBase): val.lbitsize = nativeValue.bitsize() return val - def nativeTypeId(self, nativeType): + def nativeTypeId(self, nativeType: cdbext.Type) -> str: self.check(isinstance(nativeType, cdbext.Type)) name = nativeType.name() if name is None or len(name) == 0: @@ -148,7 +148,7 @@ class Dumper(DumperBase): for f in nativeType.fields()]) return typeId - def from_native_type(self, nativeType): + def from_native_type(self, nativeType: cdbext.Type) -> str: self.check(isinstance(nativeType, cdbext.Type)) typeid = self.typeid_for_string(self.nativeTypeId(nativeType)) self.type_nativetype_cache[typeid] = nativeType @@ -187,7 +187,7 @@ class Dumper(DumperBase): self.nativeTypeEnumDisplay(nativeType, intval, form) return typeid - def listNativeValueChildren(self, nativeValue, include_bases): + def listNativeValueChildren(self, nativeValue: cdbext.Value, include_bases: bool) -> list[DumperBase.Value]: fields = [] index = 0 nativeMember = nativeValue.childFromIndex(index) @@ -202,19 +202,19 @@ class Dumper(DumperBase): nativeMember = nativeValue.childFromIndex(index) return fields - def listValueChildren(self, value, include_bases=True): + def listValueChildren(self, value: DumperBase.Value, include_bases=True) -> list[DumperBase.Value]: nativeValue = value.nativeValue if nativeValue is None: nativeValue = cdbext.createValue(value.address(), self.lookupNativeType(value.type.name, 0)) return self.listNativeValueChildren(nativeValue, include_bases) - def nativeListMembers(self, value, native_type, include_bases): + def nativeListMembers(self, value: DumperBase.Value, native_type: cdbext.Type, include_bases: bool) -> list[DumperBase.Value]: nativeValue = value.nativeValue if nativeValue is None: nativeValue = cdbext.createValue(value.address(), native_type) return self.listNativeValueChildren(nativeValue, include_bases) - def nativeStructAlignment(self, nativeType): + def nativeStructAlignment(self, nativeType: cdbext.Type) -> int: #DumperBase.warn("NATIVE ALIGN FOR %s" % nativeType.name) def handleItem(nativeFieldType, align): a = self.type_alignment(self.from_native_type(nativeFieldType)) @@ -224,13 +224,13 @@ class Dumper(DumperBase): align = handleItem(f.type(), align) return align - def nativeTypeEnumDisplay(self, nativeType, intval, form): + def nativeTypeEnumDisplay(self, nativeType: cdbext.Type, intval: int, form) -> str: value = self.nativeParseAndEvaluate('(%s)%d' % (nativeType.name(), intval)) if value is None: return '' return self.enumValue(value) - def enumExpression(self, enumType, enumValue): + def enumExpression(self, enumType: str, enumValue: str) -> str: ns = self.qtNamespace() return ns + "Qt::" + enumType + "(" \ + ns + "Qt::" + enumType + "::" + enumValue + ")" @@ -238,25 +238,25 @@ class Dumper(DumperBase): def pokeValue(self, typeName, *args): return None - def parseAndEvaluate(self, exp): + def parseAndEvaluate(self, exp: str) -> DumperBase.Value: return self.fromNativeValue(self.nativeParseAndEvaluate(exp)) - def nativeParseAndEvaluate(self, exp): + def nativeParseAndEvaluate(self, exp: str) -> cdbext.Value: return cdbext.parseAndEvaluate(exp) - def isWindowsTarget(self): + def isWindowsTarget(self) -> bool: return True - def isQnxTarget(self): + def isQnxTarget(self) -> bool: return False - def isArmArchitecture(self): + def isArmArchitecture(self) -> bool: return False - def isMsvcTarget(self): + def isMsvcTarget(self) -> bool: return True - def qtCoreModuleName(self): + def qtCoreModuleName(self) -> str: modules = cdbext.listOfModules() # first check for an exact module name match for coreName in ['Qt6Core', 'Qt6Cored', 'Qt5Cored', 'Qt5Core', 'QtCored4', 'QtCore4']: @@ -272,7 +272,7 @@ class Dumper(DumperBase): return coreName return None - def qtDeclarativeModuleName(self): + def qtDeclarativeModuleName(self) -> str: modules = cdbext.listOfModules() for declarativeModuleName in ['Qt6Qmld', 'Qt6Qml', 'Qt5Qmld', 'Qt5Qml']: if declarativeModuleName in modules: @@ -285,7 +285,7 @@ class Dumper(DumperBase): return declarativeModuleName return None - def qtHookDataSymbolName(self): + def qtHookDataSymbolName(self) -> str: hookSymbolName = 'qtHookData' coreModuleName = self.qtCoreModuleName() if coreModuleName is not None: @@ -299,7 +299,7 @@ class Dumper(DumperBase): self.qtHookDataSymbolName = lambda: hookSymbolName return hookSymbolName - def qtDeclarativeHookDataSymbolName(self): + def qtDeclarativeHookDataSymbolName(self) -> str: hookSymbolName = 'qtDeclarativeHookData' declarativeModuleName = self.qtDeclarativeModuleName() if declarativeModuleName is not None: @@ -314,7 +314,7 @@ class Dumper(DumperBase): self.qtDeclarativeHookDataSymbolName = lambda: hookSymbolName return hookSymbolName - def extractQtVersion(self): + def extractQtVersion(self) -> int: try: qtVersion = self.parseAndEvaluate( '((void**)&%s)[2]' % self.qtHookDataSymbolName()).integer() @@ -329,7 +329,7 @@ class Dumper(DumperBase): return None return qtVersion - def putVtableItem(self, address): + def putVtableItem(self, address: int): funcName = cdbext.getNameByAddress(address) if funcName is None: self.putItem(self.createPointerValue(address, 'void')) @@ -338,7 +338,7 @@ class Dumper(DumperBase): self.putType('void*') self.putAddress(address) - def putVTableChildren(self, item, itemCount): + def putVTableChildren(self, item: DumperBase.Value, itemCount: int) -> int: p = item.address() for i in range(itemCount): deref = self.extractPointer(p) @@ -350,12 +350,12 @@ class Dumper(DumperBase): p += self.ptrSize() return itemCount - def ptrSize(self): + def ptrSize(self) -> int: size = cdbext.pointerSize() self.ptrSize = lambda: size return size - def stripQintTypedefs(self, typeName): + def stripQintTypedefs(self, typeName: str) -> str: if typeName.startswith('qint'): prefix = '' size = typeName[4:] @@ -375,7 +375,7 @@ class Dumper(DumperBase): else: return typeName - def lookupNativeType(self, name, module=0): + def lookupNativeType(self, name: str, module=0) -> cdbext.Type: if name.startswith('void'): return FakeVoidType(name, self) return cdbext.lookupType(name, module) @@ -383,13 +383,13 @@ class Dumper(DumperBase): def reportResult(self, result, args): cdbext.reportResult('result={%s}' % result) - def readRawMemory(self, address, size): + def readRawMemory(self, address: int, size: int) -> int: mem = cdbext.readRawMemory(address, size) if len(mem) != size: raise Exception("Invalid memory request: %d bytes from 0x%x" % (size, address)) return mem - def findStaticMetaObject(self, type): + def findStaticMetaObject(self, type: DumperBase.Type) -> int: ptr = 0 if type.moduleName is not None: # Try to find the static meta object in the same module as the type definition. This is @@ -449,13 +449,10 @@ class Dumper(DumperBase): def report(self, stuff): sys.stdout.write(stuff + "\n") - def findValueByExpression(self, exp): - return cdbext.parseAndEvaluate(exp) - - def nativeValueDereferenceReference(self, value): + def nativeValueDereferenceReference(self, value: DumperBase.Value) -> DumperBase.Value: return self.nativeValueDereferencePointer(value) - def nativeValueDereferencePointer(self, value): + def nativeValueDereferencePointer(self, value: DumperBase.Value) -> DumperBase.Value: def nativeVtCastValue(nativeValue): # If we have a pointer to a derived instance of the pointer type cdb adds a # synthetic '__vtcast_' member as the first child @@ -490,7 +487,7 @@ class Dumper(DumperBase): def callHelper(self, rettype, value, function, args): raise Exception("cdb does not support calling functions") - def nameForCoreId(self, id): + def nameForCoreId(self, id: int) -> DumperBase.Value: for dll in ['Utilsd', 'Utils']: idName = cdbext.call('%s!Utils::nameForId(%d)' % (dll, id)) if idName is not None: @@ -500,7 +497,7 @@ class Dumper(DumperBase): def putCallItem(self, name, rettype, value, func, *args): return - def symbolAddress(self, symbolName): + def symbolAddress(self, symbolName: str) -> int: res = self.nativeParseAndEvaluate(symbolName) return None if res is None else res.address() @@ -726,7 +723,7 @@ class Dumper(DumperBase): self.putItem(value.dereference()) - def putCStyleArray(self, value): + def putCStyleArray(self, value: DumperBase.Value): arrayType = value.type innerType = arrayType.target() address = value.address() diff --git a/share/qtcreator/debugger/cdbext.pyi b/share/qtcreator/debugger/cdbext.pyi new file mode 100644 index 00000000000..27a3538cfe9 --- /dev/null +++ b/share/qtcreator/debugger/cdbext.pyi @@ -0,0 +1,51 @@ +class Type: ... + +class Field: + def name(self) -> str : ... + def isBaseClass(self) -> bool : ... + def type(self) -> Type : ... + def parentType(self) -> Type : ... + def bitsize(self) -> int : ... + def bitpos(self) -> int : ... + +class Type: + def name(self) -> str: ... + def bitsize(self) -> int : ... + def code(self) -> int : ... + def unqualified(self) -> bool : ... + def target(self) -> Type : ... + def targetName(self) -> str : ... + def stripTypedef(self) -> Type : ... + def fields(self) -> Field : ... + def module(self) -> str : ... + def moduleId(self) -> int : ... + def arrayElements(self) -> int : ... + def templateArguments(self) -> list[int | str] : ... + def resolved(self) -> bool : ... + +class Value: ... +class Value: + def name(self) -> str : ... + def type(self) -> Type : ... + def bitsize(self) -> int : ... + def asBytes(self) -> bytes : ... + def address(self) -> int : ... + def hasChildren(self) -> bool : ... + def expand(self) -> bool : ... + def nativeDebuggerValue(self) -> str : ... + def childFromName(self) -> Value : ... + def childFromField(self) -> Value : ... + def childFromIndex(self) -> Value : ... + +def parseAndEvaluate() -> Value : ... +def resolveSymbol() -> list[str] : ... +def getNameByAddress() -> str : ... +def getAddressByName() -> int : ... +def lookupType() -> Type | None : ... +def listOfLocals() -> list[Value] : ... +def listOfModules() -> list[str] : ... +def pointerSize() -> int : ... +def readRawMemory() -> bytes : ... +def createValue() -> Value | None : ... +def call() -> Value | None : ... +def reportResult() -> None : ... From f5dde315584ef1bea80dccf1e5571cbd58418a4d Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 19 Jun 2024 15:21:44 +0200 Subject: [PATCH 13/36] Move the shipped Lua plugins to the resources directory On macOS, files in Contents/PlugIns/ need to be codesigned individually. Since Lua plugins are not really binaries, per Apple's documentation that is to be avoided (and we currently only sign executables there). Just move Lua plugins generally to the resources directory, like we do for other scripts like the debugger Python scripts, and load them from there. Change-Id: Idabd6b7c0c7c6e842b1752488cb7073f00e7be49 Reviewed-by: Marcus Tillmanns --- cmake/QtCreatorAPI.cmake | 24 ------------------- qt_attributions.json | 4 ++-- share/qtcreator/CMakeLists.txt | 1 + .../qtcreator/lua-plugins}/luals/init.lua | 0 .../qtcreator/lua-plugins}/luals/luals.lua | 0 .../lua-plugins}/luatests/INSPECT-LICENSE.txt | 0 .../lua-plugins}/luatests/guidemo.lua | 0 .../lua-plugins}/luatests/inspect.lua | 0 .../lua-plugins}/luatests/luatests.lua | 0 .../lua-plugins}/luatests/qtctest.lua | 0 .../qtcreator/lua-plugins}/luatests/tests.lua | 0 .../luatests/tst_aspectcontainer.lua | 0 .../lua-plugins}/luatests/tst_fetch.lua | 0 .../lua-plugins}/luatests/tst_utils.lua | 0 .../qtcreator/lua-plugins}/rustls/init.lua | 0 .../qtcreator/lua-plugins}/rustls/rustls.lua | 0 .../lua-plugins}/tellajoke/tellajoke.lua | 0 src/app/main.cpp | 7 ++++-- src/plugins/CMakeLists.txt | 4 ---- src/plugins/luals/CMakeLists.txt | 4 ---- src/plugins/luals/luals.qbs | 8 ------- src/plugins/luatests/CMakeLists.txt | 11 --------- src/plugins/luatests/luatests.qbs | 14 ----------- src/plugins/rustls/CMakeLists.txt | 4 ---- src/plugins/rustls/rustls.qbs | 8 ------- src/plugins/tellajoke/CMakeLists.txt | 1 - src/plugins/tellajoke/tellajoke.qbs | 5 ---- 27 files changed, 8 insertions(+), 87 deletions(-) rename {src/plugins/luals => share/qtcreator/lua-plugins}/luals/init.lua (100%) rename {src/plugins/luals => share/qtcreator/lua-plugins}/luals/luals.lua (100%) rename {src/plugins/luatests => share/qtcreator/lua-plugins}/luatests/INSPECT-LICENSE.txt (100%) rename {src/plugins/luatests => share/qtcreator/lua-plugins}/luatests/guidemo.lua (100%) rename {src/plugins/luatests => share/qtcreator/lua-plugins}/luatests/inspect.lua (100%) rename {src/plugins/luatests => share/qtcreator/lua-plugins}/luatests/luatests.lua (100%) rename {src/plugins/luatests => share/qtcreator/lua-plugins}/luatests/qtctest.lua (100%) rename {src/plugins/luatests => share/qtcreator/lua-plugins}/luatests/tests.lua (100%) rename {src/plugins/luatests => share/qtcreator/lua-plugins}/luatests/tst_aspectcontainer.lua (100%) rename {src/plugins/luatests => share/qtcreator/lua-plugins}/luatests/tst_fetch.lua (100%) rename {src/plugins/luatests => share/qtcreator/lua-plugins}/luatests/tst_utils.lua (100%) rename {src/plugins/rustls => share/qtcreator/lua-plugins}/rustls/init.lua (100%) rename {src/plugins/rustls => share/qtcreator/lua-plugins}/rustls/rustls.lua (100%) rename {src/plugins/tellajoke => share/qtcreator/lua-plugins}/tellajoke/tellajoke.lua (100%) delete mode 100644 src/plugins/luals/CMakeLists.txt delete mode 100644 src/plugins/luals/luals.qbs delete mode 100644 src/plugins/luatests/CMakeLists.txt delete mode 100644 src/plugins/luatests/luatests.qbs delete mode 100644 src/plugins/rustls/CMakeLists.txt delete mode 100644 src/plugins/rustls/rustls.qbs delete mode 100644 src/plugins/tellajoke/CMakeLists.txt delete mode 100644 src/plugins/tellajoke/tellajoke.qbs diff --git a/cmake/QtCreatorAPI.cmake b/cmake/QtCreatorAPI.cmake index c0f61301111..c53b479982d 100644 --- a/cmake/QtCreatorAPI.cmake +++ b/cmake/QtCreatorAPI.cmake @@ -1119,27 +1119,3 @@ function(qtc_add_public_header header) COMPONENT Devel EXCLUDE_FROM_ALL ) endfunction() - -function (add_qtc_lua_plugin name) - cmake_parse_arguments(_arg "EXCLUDE_FROM_INSTALL" "" "SOURCES" ${ARGN}) - - if (${_arg_UNPARSED_ARGUMENTS}) - message(FATAL_ERROR "add_qtc_lua_plugin had unparsed arguments!") - endif() - - qtc_copy_to_builddir(${name} - FILES ${_arg_SOURCES} - DESTINATION ${IDE_PLUGIN_PATH} - ) - - if (NOT _arg_EXCLUDE_FROM_INSTALL) - foreach(SOURCE ${_arg_SOURCES}) - get_filename_component(SOURCE_DIR "${SOURCE}" DIRECTORY) - - install( - FILES ${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE} - DESTINATION ${IDE_PLUGIN_PATH}/${SOURCE_DIR} - ) - endforeach() - endif() -endfunction() diff --git a/qt_attributions.json b/qt_attributions.json index 56e4fe0595c..74bd2cae83f 100644 --- a/qt_attributions.json +++ b/qt_attributions.json @@ -618,11 +618,11 @@ "QDocModule": "qtcreator", "QtParts": ["tools"], "QtUsage": "Used for pretty printing from Lua scripts.", - "Path": "src/plugins/luatests/luatests", + "Path": "share/qtcreator/lua-plugins/luatests", "Description": "inspect.lua is a library for pretty printing complex objects in Lua.", "Homepage": "https://github.com/kikito/inspect.lua", "License": "MIT License", - "LicenseFile": "src/plugins/luatests/luatests/INSPECT-LICENSE.txt", + "LicenseFile": "share/qtcreator/lua-plugins/luatests/INSPECT-LICENSE.txt", "Copyright": "Copyright (c) 2022 Enrique García Cota" } ] diff --git a/share/qtcreator/CMakeLists.txt b/share/qtcreator/CMakeLists.txt index 96791362ec7..6a18147f9fd 100644 --- a/share/qtcreator/CMakeLists.txt +++ b/share/qtcreator/CMakeLists.txt @@ -4,6 +4,7 @@ set(resource_directories glsl indexer_preincludes jsonschemas + lua-plugins modeleditor qmldesigner qmlicons diff --git a/src/plugins/luals/luals/init.lua b/share/qtcreator/lua-plugins/luals/init.lua similarity index 100% rename from src/plugins/luals/luals/init.lua rename to share/qtcreator/lua-plugins/luals/init.lua diff --git a/src/plugins/luals/luals/luals.lua b/share/qtcreator/lua-plugins/luals/luals.lua similarity index 100% rename from src/plugins/luals/luals/luals.lua rename to share/qtcreator/lua-plugins/luals/luals.lua diff --git a/src/plugins/luatests/luatests/INSPECT-LICENSE.txt b/share/qtcreator/lua-plugins/luatests/INSPECT-LICENSE.txt similarity index 100% rename from src/plugins/luatests/luatests/INSPECT-LICENSE.txt rename to share/qtcreator/lua-plugins/luatests/INSPECT-LICENSE.txt diff --git a/src/plugins/luatests/luatests/guidemo.lua b/share/qtcreator/lua-plugins/luatests/guidemo.lua similarity index 100% rename from src/plugins/luatests/luatests/guidemo.lua rename to share/qtcreator/lua-plugins/luatests/guidemo.lua diff --git a/src/plugins/luatests/luatests/inspect.lua b/share/qtcreator/lua-plugins/luatests/inspect.lua similarity index 100% rename from src/plugins/luatests/luatests/inspect.lua rename to share/qtcreator/lua-plugins/luatests/inspect.lua diff --git a/src/plugins/luatests/luatests/luatests.lua b/share/qtcreator/lua-plugins/luatests/luatests.lua similarity index 100% rename from src/plugins/luatests/luatests/luatests.lua rename to share/qtcreator/lua-plugins/luatests/luatests.lua diff --git a/src/plugins/luatests/luatests/qtctest.lua b/share/qtcreator/lua-plugins/luatests/qtctest.lua similarity index 100% rename from src/plugins/luatests/luatests/qtctest.lua rename to share/qtcreator/lua-plugins/luatests/qtctest.lua diff --git a/src/plugins/luatests/luatests/tests.lua b/share/qtcreator/lua-plugins/luatests/tests.lua similarity index 100% rename from src/plugins/luatests/luatests/tests.lua rename to share/qtcreator/lua-plugins/luatests/tests.lua diff --git a/src/plugins/luatests/luatests/tst_aspectcontainer.lua b/share/qtcreator/lua-plugins/luatests/tst_aspectcontainer.lua similarity index 100% rename from src/plugins/luatests/luatests/tst_aspectcontainer.lua rename to share/qtcreator/lua-plugins/luatests/tst_aspectcontainer.lua diff --git a/src/plugins/luatests/luatests/tst_fetch.lua b/share/qtcreator/lua-plugins/luatests/tst_fetch.lua similarity index 100% rename from src/plugins/luatests/luatests/tst_fetch.lua rename to share/qtcreator/lua-plugins/luatests/tst_fetch.lua diff --git a/src/plugins/luatests/luatests/tst_utils.lua b/share/qtcreator/lua-plugins/luatests/tst_utils.lua similarity index 100% rename from src/plugins/luatests/luatests/tst_utils.lua rename to share/qtcreator/lua-plugins/luatests/tst_utils.lua diff --git a/src/plugins/rustls/rustls/init.lua b/share/qtcreator/lua-plugins/rustls/init.lua similarity index 100% rename from src/plugins/rustls/rustls/init.lua rename to share/qtcreator/lua-plugins/rustls/init.lua diff --git a/src/plugins/rustls/rustls/rustls.lua b/share/qtcreator/lua-plugins/rustls/rustls.lua similarity index 100% rename from src/plugins/rustls/rustls/rustls.lua rename to share/qtcreator/lua-plugins/rustls/rustls.lua diff --git a/src/plugins/tellajoke/tellajoke/tellajoke.lua b/share/qtcreator/lua-plugins/tellajoke/tellajoke.lua similarity index 100% rename from src/plugins/tellajoke/tellajoke/tellajoke.lua rename to share/qtcreator/lua-plugins/tellajoke/tellajoke.lua diff --git a/src/app/main.cpp b/src/app/main.cpp index 86c9106a565..4ec11d5e896 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -177,8 +177,11 @@ static inline int askMsgSendFailed() static inline QStringList getPluginPaths() { - QStringList rc(QDir::cleanPath(QApplication::applicationDirPath() - + '/' + RELATIVE_PLUGIN_PATH)); + QStringList rc; + rc << (QDir::cleanPath(QApplication::applicationDirPath() + + '/' + RELATIVE_PLUGIN_PATH)) + << (QDir::cleanPath(QApplication::applicationDirPath() + + '/' + RELATIVE_DATA_PATH + "/lua-plugins")); // Local plugin path: /plugins/ // where is e.g. // "%LOCALAPPDATA%\QtProject\qtcreator" on Windows Vista and later diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index a0bfe5b1cfc..423b17d9284 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -119,7 +119,3 @@ endif() add_subdirectory(qnx) add_subdirectory(mcusupport) add_subdirectory(qtapplicationmanager) -add_subdirectory(luatests) -add_subdirectory(tellajoke) -add_subdirectory(luals) -add_subdirectory(rustls) diff --git a/src/plugins/luals/CMakeLists.txt b/src/plugins/luals/CMakeLists.txt deleted file mode 100644 index cec9a052dee..00000000000 --- a/src/plugins/luals/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -add_qtc_lua_plugin(luals - SOURCES luals/luals.lua - luals/init.lua -) diff --git a/src/plugins/luals/luals.qbs b/src/plugins/luals/luals.qbs deleted file mode 100644 index ea05595f80a..00000000000 --- a/src/plugins/luals/luals.qbs +++ /dev/null @@ -1,8 +0,0 @@ -QtcLuaPlugin { - name: "luals" - - luafiles: [ - "init.lua", - "luals.lua", - ] -} diff --git a/src/plugins/luatests/CMakeLists.txt b/src/plugins/luatests/CMakeLists.txt deleted file mode 100644 index 0bad7da433b..00000000000 --- a/src/plugins/luatests/CMakeLists.txt +++ /dev/null @@ -1,11 +0,0 @@ -add_qtc_lua_plugin(luatests - SOURCES - luatests/luatests.lua - luatests/tests.lua - luatests/inspect.lua - luatests/qtctest.lua - luatests/tst_aspectcontainer.lua - luatests/tst_fetch.lua - luatests/tst_utils.lua - luatests/guidemo.lua -) diff --git a/src/plugins/luatests/luatests.qbs b/src/plugins/luatests/luatests.qbs deleted file mode 100644 index 687cd6579bd..00000000000 --- a/src/plugins/luatests/luatests.qbs +++ /dev/null @@ -1,14 +0,0 @@ -QtcLuaPlugin { - name: "luatests" - - luafiles: [ - "inspect.lua", - "guidemo.lua", - "luatests.lua", - "qtctest.lua", - "tests.lua", - "tst_aspectcontainer.lua", - "tst_fetch.lua", - "tst_utils.lua", - ] -} diff --git a/src/plugins/rustls/CMakeLists.txt b/src/plugins/rustls/CMakeLists.txt deleted file mode 100644 index 17184ddf139..00000000000 --- a/src/plugins/rustls/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -add_qtc_lua_plugin(rustls - SOURCES rustls/rustls.lua - rustls/init.lua -) diff --git a/src/plugins/rustls/rustls.qbs b/src/plugins/rustls/rustls.qbs deleted file mode 100644 index f629705f098..00000000000 --- a/src/plugins/rustls/rustls.qbs +++ /dev/null @@ -1,8 +0,0 @@ -QtcLuaPlugin { - name: "rustls" - - luafiles: [ - "init.lua", - "rustls.lua", - ] -} diff --git a/src/plugins/tellajoke/CMakeLists.txt b/src/plugins/tellajoke/CMakeLists.txt deleted file mode 100644 index c9dfcf23d20..00000000000 --- a/src/plugins/tellajoke/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -add_qtc_lua_plugin(tellajoke SOURCES tellajoke/tellajoke.lua) diff --git a/src/plugins/tellajoke/tellajoke.qbs b/src/plugins/tellajoke/tellajoke.qbs deleted file mode 100644 index d2efc1a64e8..00000000000 --- a/src/plugins/tellajoke/tellajoke.qbs +++ /dev/null @@ -1,5 +0,0 @@ -QtcLuaPlugin { - name: "tellajoke" - - luafiles: "tellajoke.lua" -} From 6e648ee931a3044f456ccaafcc4d7e08684e0458 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 20 Jun 2024 08:34:11 +0200 Subject: [PATCH 14/36] Lua: fix "conversion from 'size_t' to 'int'" warning Change-Id: Ibb6b17f82ebf992a48b29570c829376ef142ea10 Reviewed-by: Marcus Tillmanns --- src/plugins/lua/luaengine.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/plugins/lua/luaengine.cpp b/src/plugins/lua/luaengine.cpp index 29ca17fad6e..abfc78957b1 100644 --- a/src/plugins/lua/luaengine.cpp +++ b/src/plugins/lua/luaengine.cpp @@ -373,11 +373,9 @@ QJsonValue LuaEngine::toJson(const sol::table &table) QStringList LuaEngine::variadicToStringList(const sol::variadic_args &vargs) { QStringList strings; - int n = vargs.size(); - int i; - for (i = 1; i <= n; i++) { + for (size_t i = 1, n = vargs.size(); i <= n; i++) { size_t l; - const char *s = luaL_tolstring(vargs.lua_state(), i, &l); + const char *s = luaL_tolstring(vargs.lua_state(), int(i), &l); if (s != nullptr) strings.append(QString::fromUtf8(s, l)); } From cd3729b4aa5d6aa762c07db9ac3eaf41ee37ec36 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Thu, 20 Jun 2024 11:32:16 +0200 Subject: [PATCH 15/36] DAP: Handle failed "launch" response On Windows if the application being debugged has missing dlls it will not be able to be started by the debugger. Now the user will be informed that the application failed to start. Change-Id: I0a76a8c6cd122970b00adec371b254adc60915c0 Reviewed-by: Artem Sokolovskii --- src/plugins/debugger/dap/dapclient.cpp | 2 ++ src/plugins/debugger/dap/dapclient.h | 1 + src/plugins/debugger/dap/dapengine.cpp | 15 +++++++++++++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/plugins/debugger/dap/dapclient.cpp b/src/plugins/debugger/dap/dapclient.cpp index b67d7ec4754..c7839d55822 100644 --- a/src/plugins/debugger/dap/dapclient.cpp +++ b/src/plugins/debugger/dap/dapclient.cpp @@ -239,6 +239,8 @@ void DapClient::emitSignals(const QJsonDocument &doc) type = DapResponseType::SetFunctionBreakpoints; } else if (command == "attach") { type = DapResponseType::Attach; + } else if (command == "launch") { + type = DapResponseType::Launch; } emit responseReady(type, ob); return; diff --git a/src/plugins/debugger/dap/dapclient.h b/src/plugins/debugger/dap/dapclient.h index f4c3df2ef3a..268e1e1f37f 100644 --- a/src/plugins/debugger/dap/dapclient.h +++ b/src/plugins/debugger/dap/dapclient.h @@ -55,6 +55,7 @@ enum class DapResponseType SetBreakpoints, SetFunctionBreakpoints, Attach, + Launch, Unknown }; diff --git a/src/plugins/debugger/dap/dapengine.cpp b/src/plugins/debugger/dap/dapengine.cpp index e311bb36822..da659921c2e 100644 --- a/src/plugins/debugger/dap/dapengine.cpp +++ b/src/plugins/debugger/dap/dapengine.cpp @@ -645,6 +645,7 @@ void DapEngine::readDapStandardError() void DapEngine::handleResponse(DapResponseType type, const QJsonObject &response) { const QString command = response.value("command").toString(); + const bool success = response.value("success").toBool(); switch (type) { case DapResponseType::Initialize: @@ -675,7 +676,7 @@ void DapEngine::handleResponse(DapResponseType type, const QJsonObject &response case DapResponseType::StepIn: case DapResponseType::StepOut: case DapResponseType::StepOver: - if (response.value("success").toBool()) { + if (success) { showMessage(command, LogDebug); notifyInferiorRunOk(); } else { @@ -692,11 +693,21 @@ void DapEngine::handleResponse(DapResponseType type, const QJsonObject &response case DapResponseType::SetBreakpoints: handleBreakpointResponse(response); break; + case DapResponseType::Launch: + if (!success) { + notifyEngineRunFailed(); + AsynchronousMessageBox::critical( + Tr::tr("Failed to Start Application"), + Tr::tr("\"%1\" could not be started. Error message: %2") + .arg(runParameters().inferior.command.toUserOutput()) + .arg(response.value("message").toString())); + } + break; default: showMessage("UNKNOWN RESPONSE:" + command); }; - if (response.contains("success") && !response.value("success").toBool()) { + if (!success) { showMessage(QString("DAP COMMAND FAILED: %1").arg(command)); qCDebug(logCategory()) << "DAP COMMAND FAILED:" << command; return; From b1b27d4a4903cfec0a984764d532f05920e90a4c Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 20 Jun 2024 10:06:02 +0200 Subject: [PATCH 16/36] Dumper: Fix dumping QDir Change-Id: I5b02e8b0a000efe1c3bbbc22f7e624ea218e1cfc Reviewed-by: hjk --- share/qtcreator/debugger/qttypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index 004779e06a2..bff19802df0 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -569,7 +569,7 @@ def qdump__QDir(d, value): with SubItem(d, 'absolutePath'): d.putItem(d.createValue(privAddress + absoluteDirEntryOffset, '@QString')) with SubItem(d, 'entryInfoList'): - qdumpHelper_QList(d, privAddress + fileInfosOffset, '@QFileInfo') + qdumpHelper_QList(d, d.createValue(privAddress + fileInfosOffset, '@QList<@QFileInfo>'), '@QFileInfo') with SubItem(d, 'entryList'): d.putItem(d.createValue(privAddress + filesOffset, '@QStringList')) d.putFields(value) From 267f3929776c1f152431b9721520f1bfabe4586e Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 20 Jun 2024 10:13:59 +0200 Subject: [PATCH 17/36] Dumper: Fix dumping QLocale Change-Id: Ib34970549c147c593f39023ec0aed53885af6ce0 Reviewed-by: hjk --- share/qtcreator/debugger/qttypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/qtcreator/debugger/qttypes.py b/share/qtcreator/debugger/qttypes.py index bff19802df0..9f2f1354ce2 100644 --- a/share/qtcreator/debugger/qttypes.py +++ b/share/qtcreator/debugger/qttypes.py @@ -1256,7 +1256,7 @@ def qdump__QLocale(d, value): prefix = ns + 'QLocale::' try: - if qtVersionAtLeast(0x060700): + if d.qtVersionAtLeast(0x060700): res = d.call('const char *', value, 'name', prefix + 'TagSeparator::Underscore') else: res = d.call('const char *', value, 'name') From 987d29241484e9647348d01ed1c1f23f91ea4a33 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 18 Jun 2024 15:36:19 +0200 Subject: [PATCH 18/36] Disambiguate "Executable:" "the executable" versus "the file is executable" Fix translations where both variants were available (i.e. that used the adjective for the translation in Core, but the noun elsewhere). Fixes: QTCREATORBUG-31059 Change-Id: Id140612f201cea1feca007557bbedf030cfdf504 Reviewed-by: Alessandro Portale Reviewed-by: Leena Miettinen --- share/qtcreator/translations/qtcreator_de.ts | 6 ++++++ share/qtcreator/translations/qtcreator_hr.ts | 6 ++++++ share/qtcreator/translations/qtcreator_ru.ts | 6 ++++++ src/plugins/coreplugin/dialogs/externaltoolconfig.cpp | 2 +- src/plugins/coreplugin/dialogs/filepropertiesdialog.cpp | 2 +- src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp | 2 +- 6 files changed, 21 insertions(+), 3 deletions(-) diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts index 3dc80d58d94..cc2c1327d9e 100644 --- a/share/qtcreator/translations/qtcreator_de.ts +++ b/share/qtcreator/translations/qtcreator_de.ts @@ -21936,8 +21936,14 @@ Doppelklicken Sie einen Eintrag um ihn zu ändern. Executable: + adjective Ausführbar: + + Executable: + noun + Ausführbare Datei: + Symbolic link: Symbolischer Link: diff --git a/share/qtcreator/translations/qtcreator_hr.ts b/share/qtcreator/translations/qtcreator_hr.ts index acd2770cab3..93848c19411 100644 --- a/share/qtcreator/translations/qtcreator_hr.ts +++ b/share/qtcreator/translations/qtcreator_hr.ts @@ -2133,8 +2133,14 @@ Međutim, korištenje opuštenih i proširenih pravila također znači da nije m Executable: + adjective Izvršavajuća: + + Executable: + noun + Izvršna datoteka: + Symbolic link: Simbolička poveznica: diff --git a/share/qtcreator/translations/qtcreator_ru.ts b/share/qtcreator/translations/qtcreator_ru.ts index 7f57fe4f12d..44f5dfa5823 100644 --- a/share/qtcreator/translations/qtcreator_ru.ts +++ b/share/qtcreator/translations/qtcreator_ru.ts @@ -18313,8 +18313,14 @@ will also disable the following plugins: Executable: + adjective Можно запускать: + + Executable: + noun + Программа: + Symbolic link: Символьная ссылка: diff --git a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp index a758adf1053..2141ef61c2e 100644 --- a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp +++ b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp @@ -563,7 +563,7 @@ ExternalToolConfig::ExternalToolConfig() Form { Tr::tr("Description:"), m_description, br, - Tr::tr("Executable:"), m_executable, br, + Tr::tr("Executable:", "noun"), m_executable, br, Tr::tr("Arguments:"), m_arguments, br, Tr::tr("Working directory:"), m_workingDirectory, br, outputLabel, m_outputBehavior, br, diff --git a/src/plugins/coreplugin/dialogs/filepropertiesdialog.cpp b/src/plugins/coreplugin/dialogs/filepropertiesdialog.cpp index de3362a408f..2a480ff17b5 100644 --- a/src/plugins/coreplugin/dialogs/filepropertiesdialog.cpp +++ b/src/plugins/coreplugin/dialogs/filepropertiesdialog.cpp @@ -79,7 +79,7 @@ FilePropertiesDialog::FilePropertiesDialog(const FilePath &filePath, QWidget *pa Tr::tr("Last modified:"), m_lastModified, br, Tr::tr("Readable:"), m_readable, br, Tr::tr("Writable:"), m_writable, br, - Tr::tr("Executable:"), m_executable, br, + Tr::tr("Executable:", "adjective"), m_executable, br, Tr::tr("Symbolic link:"), m_symLink, br }, buttonBox diff --git a/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp b/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp index 259ffb6aa4a..bcc685c9532 100644 --- a/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp @@ -220,7 +220,7 @@ bool SpotlightLocatorFilter::openConfigDialog(QWidget *parent, bool &needsRefres caseSensitiveArgumentsEdit->setText(m_caseSensitiveArguments); auto sortResults = new QCheckBox(Tr::tr("Sort results")); sortResults->setChecked(m_sortResults); - layout->addRow(Tr::tr("Executable:"), commandEdit); + layout->addRow(Tr::tr("Executable:", "noun"), commandEdit); layout->addRow(Tr::tr("Arguments:"), argumentsEdit); layout->addRow(Tr::tr("Case sensitive:"), caseSensitiveArgumentsEdit); layout->addRow({}, sortResults); From 6b1e7eff93e5db580e94f8a9f6a6b31f389a8061 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 20 Jun 2024 13:58:56 +0200 Subject: [PATCH 19/36] Editor: Do not add to history twice for double clicking bookmarks Activating a bookmark via a double click resulted in both signals getting emitted doubleClicked as well as activated, and both were connected to BookmarkView::gotoBookmark. So the goto code was executed twice resulting in adding the position to the navigation history twice. Fix this by only connecting to activated since this is always emitted alongside the doubleClicked signal as well as when the item is activated by keyboard. Fixes: QTCREATORBUG-30842 Change-Id: I48ea50afa105f81a2be8ac94096dd29164fce5fe Reviewed-by: Christian Stenger --- src/plugins/texteditor/bookmarkmanager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/texteditor/bookmarkmanager.cpp b/src/plugins/texteditor/bookmarkmanager.cpp index a61cc587363..625eca0c251 100644 --- a/src/plugins/texteditor/bookmarkmanager.cpp +++ b/src/plugins/texteditor/bookmarkmanager.cpp @@ -218,7 +218,6 @@ BookmarkView::BookmarkView() setDragEnabled(true); setDragDropMode(QAbstractItemView::DragDrop); - connect(this, &QAbstractItemView::doubleClicked, this, &BookmarkView::gotoBookmark); connect(this, &QAbstractItemView::activated, this, &BookmarkView::gotoBookmark); } From 94663d0db7b24b638cc3c9bbd65a1f922b28e2c3 Mon Sep 17 00:00:00 2001 From: Ralf Habacker Date: Fri, 15 Mar 2024 16:25:06 +0100 Subject: [PATCH 20/36] cmake: Add support for custom startup programs for executable targets CMake supports the use of custom startup programs that are provided in the IDE to simplify execution. If the build system provides launchers, these are provided as an additional selection field of the run configuration including an entry without launcher. As of cmake version 3.29, the start programs are extracted from the API of the cmake file. For older cmake versions, a launcher is initialized from the cmake variable CMAKE_CROSSCOMPILING_EMULATOR, if available. Fixes: QTCREATORBUG-29880 Change-Id: I4345b56c9ca5befb5876a361e7da4675590399ca Reviewed-by: Christian Kandeler Reviewed-by: Cristian Adam --- .../cmakeprojectmanager/cmakebuildsystem.cpp | 12 ++ .../cmakeprojectmanager/cmakebuildtarget.h | 2 + .../fileapidataextractor.cpp | 16 ++ .../cmakeprojectmanager/fileapiparser.cpp | 14 ++ .../cmakeprojectmanager/fileapiparser.h | 1 + src/plugins/projectexplorer/buildtargetinfo.h | 4 + .../desktoprunconfiguration.cpp | 9 ++ .../projectexplorer/runconfiguration.cpp | 12 +- .../projectexplorer/runconfiguration.h | 45 ++++++ .../runconfigurationaspects.cpp | 150 ++++++++++++++++++ .../projectexplorer/runconfigurationaspects.h | 30 ++++ 11 files changed, 294 insertions(+), 1 deletion(-) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index 13aee2f2de9..ec5e3a4b89f 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -1977,6 +1977,9 @@ static FilePaths librarySearchPaths(const CMakeBuildSystem *bs, const QString &b const QList CMakeBuildSystem::appTargets() const { + const CMakeConfig &cm = configurationFromCMake(); + QString emulator = cm.stringValueOf("CMAKE_CROSSCOMPILING_EMULATOR"); + QList appTargetList; const bool forAndroid = DeviceTypeKitAspect::deviceTypeId(kit()) == Android::Constants::ANDROID_DEVICE_TYPE; @@ -1989,6 +1992,15 @@ const QList CMakeBuildSystem::appTargets() const BuildTargetInfo bti; bti.displayName = ct.title; + if (ct.launchers.size() > 0) + bti.launchers = ct.launchers; + else if (!emulator.isEmpty()) { + // fallback for cmake < 3.29 + QStringList args = emulator.split(";"); + FilePath command = FilePath::fromString(args.takeFirst()); + LauncherInfo launcherInfo = { "emulator", command, args }; + bti.launchers.append(Launcher(launcherInfo, ct.sourceDirectory)); + } bti.targetFilePath = ct.executable; bti.projectFilePath = ct.sourceDirectory.cleanPath(); bti.workingDirectory = ct.workingDirectory; diff --git a/src/plugins/cmakeprojectmanager/cmakebuildtarget.h b/src/plugins/cmakeprojectmanager/cmakebuildtarget.h index d40729a3970..934070bdfd1 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildtarget.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildtarget.h @@ -7,6 +7,7 @@ #include #include +#include #include @@ -30,6 +31,7 @@ class CMAKE_EXPORT CMakeBuildTarget public: QString title; Utils::FilePath executable; // TODO: rename to output? + QList launchers; TargetType targetType = UtilityType; bool linksToQtGui = false; bool qtcRunnable = true; diff --git a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp index 6f4050a3aa4..7a6de1749de 100644 --- a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp +++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp @@ -342,6 +342,22 @@ static CMakeBuildTarget toBuildTarget(const TargetDetails &t, } ct.libraryDirectories = filteredUnique(librarySeachPaths); qCInfo(cmakeLogger) << "libraryDirectories for target" << ct.title << ":" << ct.libraryDirectories; + + // If there are start programs, there should also be an option to select none + if (!t.launcherInfos.isEmpty()) { + LauncherInfo info { "unused", Utils::FilePath(), QStringList() }; + ct.launchers.append(Launcher(info, sourceDirectory)); + } + // if there is a test and an emulator launcher, add the emulator and + // also a combination as the last entry, but not the "test" launcher + // as it will not work for cross-compiled executables + if (t.launcherInfos.size() == 2 && t.launcherInfos[0].type == "test" && t.launcherInfos[1].type == "emulator") { + ct.launchers.append(Launcher(t.launcherInfos[1], sourceDirectory)); + ct.launchers.append(Launcher(t.launcherInfos[0], t.launcherInfos[1], sourceDirectory)); + } else if (t.launcherInfos.size() == 1) { + Launcher launcher(t.launcherInfos[0], sourceDirectory); + ct.launchers.append(launcher); + } } return ct; } diff --git a/src/plugins/cmakeprojectmanager/fileapiparser.cpp b/src/plugins/cmakeprojectmanager/fileapiparser.cpp index d404d124db8..d9ea457600f 100644 --- a/src/plugins/cmakeprojectmanager/fileapiparser.cpp +++ b/src/plugins/cmakeprojectmanager/fileapiparser.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -650,6 +651,19 @@ static TargetDetails extractTargetDetails(const QJsonObject &root, QString &erro }; }); } + { + const QJsonArray launchers = root.value("launchers").toArray(); + if (launchers.size() > 0) { + t.launcherInfos = transform(launchers, [](const QJsonValue &v) { + const QJsonObject o = v.toObject(); + QList arguments; + for (const QJsonValue &arg : o.value("arguments").toArray()) + arguments.append(arg.toString()); + FilePath command = FilePath::fromString(o.value("command").toString()); + return ProjectExplorer::LauncherInfo { o.value("type").toString(), command, arguments }; + }); + } + } return t; } diff --git a/src/plugins/cmakeprojectmanager/fileapiparser.h b/src/plugins/cmakeprojectmanager/fileapiparser.h index 9043d38c260..f6a59edae2a 100644 --- a/src/plugins/cmakeprojectmanager/fileapiparser.h +++ b/src/plugins/cmakeprojectmanager/fileapiparser.h @@ -197,6 +197,7 @@ public: QList artifacts; QString installPrefix; std::vector installDestination; + QList launcherInfos; std::optional link; std::optional archive; std::vector dependencies; diff --git a/src/plugins/projectexplorer/buildtargetinfo.h b/src/plugins/projectexplorer/buildtargetinfo.h index 4ba1c4de5b4..c99dec64308 100644 --- a/src/plugins/projectexplorer/buildtargetinfo.h +++ b/src/plugins/projectexplorer/buildtargetinfo.h @@ -5,12 +5,15 @@ #include "projectexplorer_export.h" +#include "runconfiguration.h" + #include #include #include namespace ProjectExplorer { +class Launcher; class PROJECTEXPLORER_EXPORT BuildTargetInfo { @@ -19,6 +22,7 @@ public: QString displayName; QString displayNameUniquifier; + QList launchers; Utils::FilePath targetFilePath; Utils::FilePath projectFilePath; Utils::FilePath workingDirectory; diff --git a/src/plugins/projectexplorer/desktoprunconfiguration.cpp b/src/plugins/projectexplorer/desktoprunconfiguration.cpp index a8d3284e9be..02f31c13452 100644 --- a/src/plugins/projectexplorer/desktoprunconfiguration.cpp +++ b/src/plugins/projectexplorer/desktoprunconfiguration.cpp @@ -70,6 +70,7 @@ private: FilePath executableToRun(const BuildTargetInfo &targetInfo) const; const Kind m_kind; + LauncherAspect launcher{this}; EnvironmentAspect environment{this}; ExecutableAspect executable{this}; ArgumentsAspect arguments{this}; @@ -90,6 +91,8 @@ void DesktopRunConfiguration::updateTargetInformation() auto terminalAspect = aspect(); terminalAspect->setUseTerminalHint(bti.targetFilePath.needsDevice() ? false : bti.usesTerminal); terminalAspect->setEnabled(!bti.targetFilePath.needsDevice()); + auto launcherAspect = aspect(); + launcherAspect->setVisible(false); if (m_kind == Qmake) { @@ -121,6 +124,12 @@ void DesktopRunConfiguration::updateTargetInformation() } else if (m_kind == CMake) { + if (bti.launchers.size() > 0) { + launcherAspect->setVisible(true); + // Use start program by default, if defined (see toBuildTarget() for details) + launcherAspect->setDefaultLauncher(bti.launchers.last()); + launcherAspect->updateLaunchers(bti.launchers); + } aspect()->setExecutable(bti.targetFilePath); aspect()->setDefaultWorkingDirectory(bti.workingDirectory); emit aspect()->environmentChanged(); diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 2f5dfc2513d..3c78b37cc44 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -173,6 +173,9 @@ RunConfiguration::RunConfiguration(Target *target, Utils::Id id) m_commandLineGetter = [this] { + Launcher launcher; + if (const auto launcherAspect = aspect()) + launcher = launcherAspect->currentLauncher(); FilePath executable; if (const auto executableAspect = aspect()) executable = executableAspect->executable(); @@ -180,7 +183,14 @@ RunConfiguration::RunConfiguration(Target *target, Utils::Id id) if (const auto argumentsAspect = aspect()) arguments = argumentsAspect->arguments(); - return CommandLine{executable, arguments, CommandLine::Raw}; + if (launcher.command.isEmpty()) + return CommandLine{executable, arguments, CommandLine::Raw}; + + CommandLine launcherCommand(launcher.command, launcher.arguments); + launcherCommand.addArg(executable.toString()); + launcherCommand.addArgs(arguments, CommandLine::Raw); + + return launcherCommand; }; } diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index 2054a840c14..b49ad3e7d77 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -28,6 +28,51 @@ class RunConfigurationFactory; class RunConfiguration; class RunConfigurationCreationInfo; class Target; +class BuildTargetInfo; + +/** + * Contains start program entries that are retrieved + * from the cmake file api + */ +class LauncherInfo +{ +public: + QString type; + Utils::FilePath command; + QStringList arguments; +}; + +/** + * Contains a start program entry that is displayed in the run configuration interface. + * + * This follows the design for the use of "Test Launcher", the + * Wrappers for running executables on the host system and "Emulator", + * wrappers for cross-compiled applications, which are supported for + * example by the cmake build system. + */ +class PROJECTEXPLORER_EXPORT Launcher +{ +public: + Launcher() = default; + + /// Create a single launcher from the \p launcherInfo parameter, which can be of type "Test launcher" or "Emulator" + Launcher(const LauncherInfo &launcherInfo, const Utils::FilePath &sourceDirectory); + + /// Create a combined launcher from the passed info parameters, with \p testLauncherInfo + /// as first and \p emulatorLauncherInfo appended + Launcher(const LauncherInfo &testLauncherInfo, const LauncherInfo &emulatorlauncherInfo, const Utils::FilePath &sourceDirectory); + + bool operator==(const Launcher &other) const + { + return id == other.id && displayName == other.displayName && command == other.command + && arguments == other.arguments; + } + + QString id; + QString displayName; + Utils::FilePath command; + QStringList arguments; +}; /** * An interface to facilitate switching between hunks of diff --git a/src/plugins/projectexplorer/runconfigurationaspects.cpp b/src/plugins/projectexplorer/runconfigurationaspects.cpp index 01003a97668..6f49b61c0e8 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.cpp +++ b/src/plugins/projectexplorer/runconfigurationaspects.cpp @@ -797,6 +797,156 @@ Interpreter::Interpreter(const QString &_id, , autoDetected(_autoDetected) {} +static QString launcherType2UiString(const QString &type) +{ + if (type == "test") + return Tr::tr("Test"); + else if (type == "emulator") + return Tr::tr("Emulator"); + return QString(); +} + +Launcher::Launcher(const LauncherInfo &launcherInfo, const FilePath &sourceDirectory) + : id(launcherInfo.type) + , arguments(launcherInfo.arguments) +{ + if (launcherInfo.type != "unused") { + command = launcherInfo.command; + if (command.isRelativePath()) + command = sourceDirectory.resolvePath(command); + displayName = QString("%1 (%2)").arg(launcherType2UiString(launcherInfo.type), + CommandLine(command, arguments).displayName()); + } +} + +Launcher::Launcher(const LauncherInfo &testLauncherInfo, const LauncherInfo &emulatorLauncherInfo, const Utils::FilePath &sourceDirectory) + : id(testLauncherInfo.type + " + " + emulatorLauncherInfo.type) + , command(testLauncherInfo.command) + , arguments(testLauncherInfo.arguments) +{ + if (command.isRelativePath()) + command = sourceDirectory.resolvePath(command); + FilePath command1 = emulatorLauncherInfo.command; + if (command1.isRelativePath()) + command1 = sourceDirectory.resolvePath(command1); + arguments.append(command1.toString()); + arguments.append(emulatorLauncherInfo.arguments); + displayName = QString("%1 + %2 (%3)").arg(launcherType2UiString(testLauncherInfo.type), + launcherType2UiString(emulatorLauncherInfo.type), + CommandLine(command, arguments).displayName()); +} + +/*! +\class ProjectExplorer::LauncherAspect +\inmodule QtCreator + +\brief With the LauncherAspect class, a user can specify a launcher program for +use with executable files for which a launcher program is optionally available. +*/ + +LauncherAspect::LauncherAspect(AspectContainer *container) + : BaseAspect(container) +{ + addDataExtractor(this, &LauncherAspect::currentLauncher, &Data::launcher); +} + +Launcher LauncherAspect::currentLauncher() const +{ + return Utils::findOrDefault(m_launchers, Utils::equal(&Launcher::id, m_currentId)); +} + +void LauncherAspect::updateLaunchers(const QList &launchers) +{ + if (m_launchers == launchers) + return; + m_launchers = launchers; + if (m_comboBox) + updateComboBox(); +} + +void LauncherAspect::setDefaultLauncher(const Launcher &launcher) +{ + if (m_defaultId == launcher.id) + return; + m_defaultId = launcher.id; + if (m_currentId.isEmpty()) + setCurrentLauncher(launcher); +} + +void LauncherAspect::setCurrentLauncher(const Launcher &launcher) +{ + if (m_comboBox) { + const int index = m_launchers.indexOf(launcher); + if (index < 0 || index >= m_comboBox->count()) + return; + m_comboBox->setCurrentIndex(index); + } else { + setCurrentLauncherId(launcher.id); + } +} + +void LauncherAspect::fromMap(const Store &map) +{ + setCurrentLauncherId(map.value(settingsKey(), m_defaultId).toString()); +} + +void LauncherAspect::toMap(Store &map) const +{ + if (m_currentId != m_defaultId) + saveToMap(map, m_currentId, QString(), settingsKey()); +} + +void LauncherAspect::addToLayout(Layout &builder) +{ + if (QTC_GUARD(m_comboBox.isNull())) + m_comboBox = new QComboBox; + + updateComboBox(); + connect(m_comboBox, &QComboBox::currentIndexChanged, + this, &LauncherAspect::updateCurrentLauncher); + + builder.addItems({Tr::tr("Launcher:"), m_comboBox.data()}); +} + +void LauncherAspect::setCurrentLauncherId(const QString &id) +{ + if (id == m_currentId) + return; + m_currentId = id; + emit changed(); +} + +void LauncherAspect::updateCurrentLauncher() +{ + const int index = m_comboBox->currentIndex(); + if (index < 0) + return; + QTC_ASSERT(index < m_launchers.size(), return); + m_comboBox->setToolTip(m_launchers[index].command.toUserOutput()); + setCurrentLauncherId(m_launchers[index].id); +} + +void LauncherAspect::updateComboBox() +{ + int currentIndex = -1; + int defaultIndex = -1; + m_comboBox->clear(); + for (const Launcher &launcher : std::as_const(m_launchers)) { + int index = m_comboBox->count(); + m_comboBox->addItem(launcher.displayName); + m_comboBox->setItemData(index, launcher.command.toUserOutput(), Qt::ToolTipRole); + if (launcher.id == m_currentId) + currentIndex = index; + if (launcher.id == m_defaultId) + defaultIndex = index; + } + if (currentIndex >= 0) + m_comboBox->setCurrentIndex(currentIndex); + else if (defaultIndex >= 0) + m_comboBox->setCurrentIndex(defaultIndex); + updateCurrentLauncher(); +} + /*! \class ProjectExplorer::X11ForwardingAspect \inmodule QtCreator diff --git a/src/plugins/projectexplorer/runconfigurationaspects.h b/src/plugins/projectexplorer/runconfigurationaspects.h index d891132ea7d..69b55c9974b 100644 --- a/src/plugins/projectexplorer/runconfigurationaspects.h +++ b/src/plugins/projectexplorer/runconfigurationaspects.h @@ -227,6 +227,36 @@ public: QString detectionSource; }; +class PROJECTEXPLORER_EXPORT LauncherAspect : public Utils::BaseAspect +{ + Q_OBJECT + +public: + LauncherAspect(Utils::AspectContainer *container = nullptr); + + Launcher currentLauncher() const; + void updateLaunchers(const QList &launchers); + void setDefaultLauncher(const Launcher &launcher); + void setCurrentLauncher(const Launcher &launcher); + void setSettingsDialogId(Utils::Id id) { m_settingsDialogId = id; } + + void fromMap(const Utils::Store &) override; + void toMap(Utils::Store &) const override; + void addToLayout(Layouting::Layout &parent) override; + + struct Data : Utils::BaseAspect::Data { Launcher launcher; }; + +private: + void setCurrentLauncherId(const QString &id); + void updateCurrentLauncher(); + void updateComboBox(); + QList m_launchers; + QPointer m_comboBox; + QString m_defaultId; + QString m_currentId; + Utils::Id m_settingsDialogId; +}; + class PROJECTEXPLORER_EXPORT MainScriptAspect : public Utils::FilePathAspect { Q_OBJECT From 805c687dbc85f655cd12cf3c20d82cd064f2b313 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 20 Jun 2024 15:14:41 +0200 Subject: [PATCH 21/36] ProjectExplorer: add rescan action to workspace project context menu Change-Id: I7a823853c3681da5ec5019a3f66bd98aa1c81cb2 Reviewed-by: Marcus Tillmanns --- .../projectexplorer/workspaceproject.cpp | 68 ++++++++++++++----- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/src/plugins/projectexplorer/workspaceproject.cpp b/src/plugins/projectexplorer/workspaceproject.cpp index 6cbb858921b..ab90393c9e9 100644 --- a/src/plugins/projectexplorer/workspaceproject.cpp +++ b/src/plugins/projectexplorer/workspaceproject.cpp @@ -32,7 +32,7 @@ const QLatin1StringView WORKSPACE_PROJECT_RUNCONFIG_ID{"WorkspaceProject.RunConf const QLatin1StringView PROJECT_NAME_KEY{"project.name"}; const QLatin1StringView FILES_EXCLUDE_KEY{"files.exclude"}; const QLatin1StringView EXCLUDE_ACTION_ID{"ProjectExplorer.ExcludeFromWorkspace"}; - +const QLatin1StringView RESCAN_ACTION_ID{"ProjectExplorer.RescanWorkspace"}; using namespace Utils; using namespace Core; @@ -308,29 +308,61 @@ void setupWorkspaceProject(QObject *guard) ProjectManager::registerProjectType(FOLDER_MIMETYPE); ProjectManager::registerProjectType(WORKSPACE_MIMETYPE); + QAction *excludeAction = nullptr; + ActionBuilder(guard, Id::fromString(EXCLUDE_ACTION_ID)) + .setContext(Id::fromString(WORKSPACE_PROJECT_ID)) + .setText(Tr::tr("Exclude from Project")) + .addToContainer(Constants::M_FOLDERCONTEXT, Constants::G_FOLDER_OTHER) + .addToContainer(Constants::M_FILECONTEXT, Constants::G_FILE_OTHER) + .bindContextAction(&excludeAction) + .setCommandAttribute(Command::CA_Hide) + .addOnTriggered(guard, [] { + Node *node = ProjectTree::currentNode(); + QTC_ASSERT(node, return); + const auto project = qobject_cast(node->getProject()); + QTC_ASSERT(project, return); + project->excludeNode(node); + }); + + QAction *rescanAction = nullptr; + ActionBuilder(guard, Id::fromString(RESCAN_ACTION_ID)) + .setContext(Id::fromString(WORKSPACE_PROJECT_ID)) + .setText(Tr::tr("Rescan Workspace")) + .addToContainer(Constants::M_PROJECTCONTEXT, Constants::G_PROJECT_REBUILD) + .bindContextAction(&rescanAction) + .setCommandAttribute(Command::CA_Hide) + .addOnTriggered(guard, [] { + Node *node = ProjectTree::currentNode(); + QTC_ASSERT(node, return); + const auto project = qobject_cast(node->getProject()); + QTC_ASSERT(project, return); + if (auto target = project->activeTarget()) { + if (target->buildSystem()) + target->buildSystem()->triggerParsing(); + } + }); + QObject::connect( ProjectTree::instance(), &ProjectTree::aboutToShowContextMenu, ProjectExplorerPlugin::instance(), - [](Node *node) { - const bool enabled = node && node->isEnabled() - && qobject_cast(node->getProject()); - ActionManager::command(Id::fromString(EXCLUDE_ACTION_ID))->action()->setEnabled(enabled); + [excludeAction, rescanAction](Node *node) { + const bool visible = node && qobject_cast(node->getProject()); + excludeAction->setVisible(visible); + rescanAction->setVisible(visible); + if (visible) { + excludeAction->setEnabled(node->isEnabled()); + bool enableRescan = false; + if (Project *project = node->getProject()) { + if (Target *target = project->activeTarget()) { + if (BuildSystem *buildSystem = target->buildSystem()) + enableRescan = !buildSystem->isParsing(); + } + } + rescanAction->setEnabled(enableRescan); + } }); - ActionBuilder excludeAction(guard, Id::fromString(EXCLUDE_ACTION_ID)); - excludeAction.setContext(Id::fromString(WORKSPACE_PROJECT_ID)); - excludeAction.setText(Tr::tr("Exclude from Project")); - excludeAction.addToContainer(Constants::M_FOLDERCONTEXT, Constants::G_FOLDER_OTHER); - excludeAction.addToContainer(Constants::M_FILECONTEXT, Constants::G_FILE_OTHER); - excludeAction.addOnTriggered([] { - Node *node = ProjectTree::currentNode(); - QTC_ASSERT(node, return); - const auto project = qobject_cast(node->getProject()); - QTC_ASSERT(project, return); - project->excludeNode(node); - }); - static WorkspaceProjectRunConfigurationFactory theRunConfigurationFactory; static WorkspaceProjectRunWorkerFactory theRunWorkerFactory; } From 561dbbf5de3d45a02318e0cc6a0eaf0a274f7091 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Thu, 20 Jun 2024 12:38:40 +0200 Subject: [PATCH 22/36] LLDB-DAP: Add "env" to "launch" command On Windows where there are no RPATHs we need to pass the environment to the "launch" event, otherwise applications can't be started. Also only add "sourceMap" and "preRunCommands" if the arrays are not empty. Change-Id: If631d36db8e28d2c30962b4e9c6a3aa3162000a1 Reviewed-by: Artem Sokolovskii --- src/plugins/debugger/dap/lldbdapengine.cpp | 56 ++++++++++++++-------- src/plugins/debugger/dap/lldbdapengine.h | 1 + 2 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/plugins/debugger/dap/lldbdapengine.cpp b/src/plugins/debugger/dap/lldbdapengine.cpp index 4dc38ca857e..8dfd75a75b2 100644 --- a/src/plugins/debugger/dap/lldbdapengine.cpp +++ b/src/plugins/debugger/dap/lldbdapengine.cpp @@ -115,6 +115,14 @@ LldbDapEngine::LldbDapEngine() setDebuggerType("DAP"); } +QJsonArray LldbDapEngine::environment() const +{ + QJsonArray envArray; + for (const QString &value : runParameters().inferior.environment.toDictionary().toStringList()) + envArray.append(value); + return envArray; +} + QJsonArray LldbDapEngine::sourceMap() const { QJsonArray sourcePathMapping; @@ -148,19 +156,25 @@ void LldbDapEngine::handleDapInitialize() // * https://github.com/llvm/llvm-project/blob/main/lldb/tools/lldb-dap/package.json const DebuggerRunParameters &rp = runParameters(); + const QJsonArray map = sourceMap(); + const QJsonArray commands = preRunCommands(); if (!isLocalAttachEngine()) { - m_dapClient->postRequest( - "launch", - QJsonObject{ - {"noDebug", false}, - {"program", rp.inferior.command.executable().path()}, - {"args", rp.inferior.command.arguments()}, - {"cwd", rp.inferior.workingDirectory.path()}, - {"sourceMap", sourceMap()}, - {"preRunCommands", preRunCommands()}, - {"__restart", ""}, - }); + const QJsonArray env = environment(); + QJsonObject launchJson{ + {"noDebug", false}, + {"program", rp.inferior.command.executable().path()}, + {"args", rp.inferior.command.arguments()}, + {"cwd", rp.inferior.workingDirectory.path()}, + {"env", env}, + {"__restart", ""}, + }; + if (!map.isEmpty()) + launchJson.insert("sourceMap", map); + if (!commands.isEmpty()) + launchJson.insert("preRunCommands", commands); + + m_dapClient->postRequest("launch", launchJson); qCDebug(logCategory()) << "handleDapLaunch"; return; @@ -168,15 +182,17 @@ void LldbDapEngine::handleDapInitialize() QTC_ASSERT(state() == EngineRunRequested, qCDebug(logCategory()) << state()); - m_dapClient->postRequest( - "attach", - QJsonObject{ - {"program", rp.inferior.command.executable().path()}, - {"pid", QString::number(rp.attachPID.pid())}, - {"sourceMap", sourceMap()}, - {"preRunCommands", preRunCommands()}, - {"__restart", ""}, - }); + QJsonObject attachJson{ + {"program", rp.inferior.command.executable().path()}, + {"pid", QString::number(rp.attachPID.pid())}, + {"__restart", ""}, + }; + if (!map.isEmpty()) + attachJson.insert("sourceMap", map); + if (!commands.isEmpty()) + attachJson.insert("preRunCommands", commands); + + m_dapClient->postRequest("attach", attachJson); qCDebug(logCategory()) << "handleDapAttach"; } diff --git a/src/plugins/debugger/dap/lldbdapengine.h b/src/plugins/debugger/dap/lldbdapengine.h index 0ebeb2d2ee1..f4f59903820 100644 --- a/src/plugins/debugger/dap/lldbdapengine.h +++ b/src/plugins/debugger/dap/lldbdapengine.h @@ -22,6 +22,7 @@ private: bool acceptsBreakpoint(const BreakpointParameters &bp) const override; const QLoggingCategory &logCategory() override; + QJsonArray environment() const; QJsonArray sourceMap() const; QJsonArray preRunCommands() const; }; From 729c8037581a087912a4b61acb2895fac60d6d8e Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 17 Jun 2024 12:25:54 +0200 Subject: [PATCH 23/36] ProjectExplorer: Ensure environment from aspect is always up to date Otherwise our (intential) delay when updating the environment from the text edit can lead to surprises for the user. Fixes: QTCREATORBUG-31052 Change-Id: Iaba8c496094ad95d8c099c67c0805317f32a2936 Reviewed-by: hjk --- src/libs/utils/namevaluesdialog.cpp | 22 ++++++++++--------- src/libs/utils/namevaluesdialog.h | 2 ++ .../projectexplorer/environmentaspect.cpp | 7 +++++- .../projectexplorer/environmentaspect.h | 3 ++- .../environmentaspectwidget.cpp | 4 ++++ .../projectexplorer/environmentwidget.cpp | 6 +++++ .../projectexplorer/environmentwidget.h | 2 ++ 7 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/libs/utils/namevaluesdialog.cpp b/src/libs/utils/namevaluesdialog.cpp index 5a45c54a75e..cd34a23955f 100644 --- a/src/libs/utils/namevaluesdialog.cpp +++ b/src/libs/utils/namevaluesdialog.cpp @@ -73,21 +73,14 @@ NameValueItemsWidget::NameValueItemsWidget(QWidget *parent) layout->addWidget(m_editor); layout->addWidget(new QLabel(helpText, this)); - const auto checkForItemChange = [this] { - const EnvironmentItems newItems = environmentItems(); - if (newItems != m_originalItems) { - m_originalItems = newItems; - emit userChangedItems(newItems); - } - }; const auto timer = new QTimer(this); timer->setSingleShot(true); timer->setInterval(1000); connect(m_editor, &QPlainTextEdit::textChanged, timer, qOverload<>(&QTimer::start)); - connect(timer, &QTimer::timeout, this, checkForItemChange); - connect(m_editor, &Internal::TextEditHelper::lostFocus, this, [timer, checkForItemChange] { + connect(timer, &QTimer::timeout, this, &NameValueItemsWidget::forceUpdateCheck); + connect(m_editor, &Internal::TextEditHelper::lostFocus, this, [this, timer] { timer->stop(); - checkForItemChange(); + forceUpdateCheck(); }); } @@ -159,6 +152,15 @@ bool NameValueItemsWidget::editVariable(const QString &name, Selection selection return false; } +void NameValueItemsWidget::forceUpdateCheck() +{ + const EnvironmentItems newItems = environmentItems(); + if (newItems != m_originalItems) { + m_originalItems = newItems; + emit userChangedItems(newItems); + } +} + NameValuesDialog::NameValuesDialog(const QString &windowTitle, QWidget *parent) : QDialog(parent) { diff --git a/src/libs/utils/namevaluesdialog.h b/src/libs/utils/namevaluesdialog.h index a1e884fe5b5..abf6b84b23e 100644 --- a/src/libs/utils/namevaluesdialog.h +++ b/src/libs/utils/namevaluesdialog.h @@ -29,6 +29,8 @@ public: enum class Selection { Name, Value }; bool editVariable(const QString &name, Selection selection); + void forceUpdateCheck(); + signals: void userChangedItems(const EnvironmentItems &items); diff --git a/src/plugins/projectexplorer/environmentaspect.cpp b/src/plugins/projectexplorer/environmentaspect.cpp index fb5aaa2c243..43107b6141d 100644 --- a/src/plugins/projectexplorer/environmentaspect.cpp +++ b/src/plugins/projectexplorer/environmentaspect.cpp @@ -69,7 +69,7 @@ void EnvironmentAspect::setUserEnvironmentChanges(const Utils::EnvironmentItems Utils::Environment EnvironmentAspect::environment() const { Environment env = modifiedBaseEnvironment(); - env.modify(m_userChanges); + env.modify(userEnvironmentChanges()); return env; } @@ -165,4 +165,9 @@ Environment EnvironmentAspect::BaseEnvironment::unmodifiedBaseEnvironment() cons return getter ? getter() : Environment(); } +Utils::EnvironmentItems EnvironmentAspect::userEnvironmentChanges() const +{ + emit userChangesUpdateRequested(); + return m_userChanges; +} } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/environmentaspect.h b/src/plugins/projectexplorer/environmentaspect.h index 26dd43f6a41..86d7d345008 100644 --- a/src/plugins/projectexplorer/environmentaspect.h +++ b/src/plugins/projectexplorer/environmentaspect.h @@ -32,7 +32,7 @@ public: int baseEnvironmentBase() const; void setBaseEnvironmentBase(int base); - Utils::EnvironmentItems userEnvironmentChanges() const { return m_userChanges; } + Utils::EnvironmentItems userEnvironmentChanges() const; void setUserEnvironmentChanges(const Utils::EnvironmentItems &diff); int addSupportedBaseEnvironment(const QString &displayName, @@ -68,6 +68,7 @@ signals: void baseEnvironmentChanged(); void userEnvironmentChangesChanged(const Utils::EnvironmentItems &diff); void environmentChanged(); + void userChangesUpdateRequested() const; protected: void fromMap(const Utils::Store &map) override; diff --git a/src/plugins/projectexplorer/environmentaspectwidget.cpp b/src/plugins/projectexplorer/environmentaspectwidget.cpp index d47b4e82cc3..148b4415658 100644 --- a/src/plugins/projectexplorer/environmentaspectwidget.cpp +++ b/src/plugins/projectexplorer/environmentaspectwidget.cpp @@ -26,6 +26,10 @@ EnvironmentAspectWidget::EnvironmentAspectWidget(EnvironmentAspect *aspect) { QTC_CHECK(m_aspect); + connect(m_aspect, &EnvironmentAspect::userChangesUpdateRequested, this, [this] { + m_environmentWidget->forceUpdateCheck(); + }); + setContentsMargins(0, 0, 0, 0); auto topLayout = new QVBoxLayout(this); topLayout->setContentsMargins(0, 0, 0, 25); diff --git a/src/plugins/projectexplorer/environmentwidget.cpp b/src/plugins/projectexplorer/environmentwidget.cpp index c438b7b1f2c..c62a9488594 100644 --- a/src/plugins/projectexplorer/environmentwidget.cpp +++ b/src/plugins/projectexplorer/environmentwidget.cpp @@ -332,6 +332,7 @@ void EnvironmentWidget::setBaseEnvironmentText(const QString &text) Utils::EnvironmentItems EnvironmentWidget::userChanges() const { + forceUpdateCheck(); return d->m_model->userChanges(); } @@ -352,6 +353,11 @@ void EnvironmentWidget::expand() d->m_detailsContainer->setState(Utils::DetailsWidget::Expanded); } +void EnvironmentWidget::forceUpdateCheck() const +{ + d->m_editor.forceUpdateCheck(); +} + void EnvironmentWidget::updateSummaryText() { // The summary is redundant with the text edit, so we hide it on expansion. diff --git a/src/plugins/projectexplorer/environmentwidget.h b/src/plugins/projectexplorer/environmentwidget.h index b1a26b036b3..f204ae978f0 100644 --- a/src/plugins/projectexplorer/environmentwidget.h +++ b/src/plugins/projectexplorer/environmentwidget.h @@ -38,6 +38,8 @@ public: void expand(); + void forceUpdateCheck() const; + signals: void userChangesChanged(); void detailsVisibleChanged(bool visible); From a1a6ccbf1ccca6b1248947b7c682f51e1d6fcad9 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 20 Jun 2024 12:40:21 +0200 Subject: [PATCH 24/36] Utils: Add FilePath::watch Change-Id: I1e5706f22aaa072c68b97496896cfa6d244d9849 Reviewed-by: hjk --- src/libs/utils/devicefileaccess.cpp | 33 ++++++++++++++++++++++++++++- src/libs/utils/devicefileaccess.h | 3 +++ src/libs/utils/filepath.cpp | 5 +++++ src/libs/utils/filepath.h | 12 +++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/libs/utils/devicefileaccess.cpp b/src/libs/utils/devicefileaccess.cpp index 303ffa6bf50..c8f920c07f7 100644 --- a/src/libs/utils/devicefileaccess.cpp +++ b/src/libs/utils/devicefileaccess.cpp @@ -17,9 +17,11 @@ #endif #include +#include #include #include #include +#include #include #include @@ -33,7 +35,6 @@ #include #endif -#include #include #include @@ -389,6 +390,13 @@ expected_str DeviceFileAccess::createTempFile(const FilePath &filePath Tr::tr("createTempFile is not implemented for \"%1\".").arg(filePath.toUserOutput())); } +Utils::expected_str> DeviceFileAccess::watch( + const FilePath &path) const +{ + Q_UNUSED(path); + return make_unexpected(Tr::tr("watch is not implemented.")); +} + // DesktopDeviceFileAccess DesktopDeviceFileAccess::~DesktopDeviceFileAccess() = default; @@ -767,6 +775,29 @@ expected_str DesktopDeviceFileAccess::createTempFile(const FilePath &f return filePath.withNewPath(file.fileName()); } +class DesktopFilePathWatcher : public FilePathWatcher +{ + QFileSystemWatcher m_watcher; + +public: + DesktopFilePathWatcher(const FilePath &path) { + connect(&m_watcher, &QFileSystemWatcher::fileChanged, this, [this, path] { + emit pathChanged(path); + }); + connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, [this, path] { + emit pathChanged(path); + }); + + m_watcher.addPath(path.path()); + } +}; + +Utils::expected_str> DesktopDeviceFileAccess::watch( + const FilePath &path) const +{ + return std::make_unique(path); +} + QDateTime DesktopDeviceFileAccess::lastModified(const FilePath &filePath) const { return QFileInfo(filePath.path()).lastModified(); diff --git a/src/libs/utils/devicefileaccess.h b/src/libs/utils/devicefileaccess.h index 8a0884ec1d0..451fb2db4be 100644 --- a/src/libs/utils/devicefileaccess.h +++ b/src/libs/utils/devicefileaccess.h @@ -72,6 +72,8 @@ protected: const QByteArray &data) const; virtual expected_str createTempFile(const FilePath &filePath); + + virtual Utils::expected_str> watch(const FilePath &path) const; }; class QTCREATOR_UTILS_EXPORT DesktopDeviceFileAccess : public DeviceFileAccess @@ -128,6 +130,7 @@ protected: expected_str createTempFile(const FilePath &filePath) override; + Utils::expected_str> watch(const FilePath &path) const override; }; class QTCREATOR_UTILS_EXPORT UnixDeviceFileAccess : public DeviceFileAccess diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index c4d77a29efc..23a6ff24129 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -313,6 +313,11 @@ bool FilePath::equalsCaseSensitive(const FilePath &other) const return equals(*this, other, Qt::CaseSensitive); } +Utils::expected_str> FilePath::watch() const +{ + return fileAccess()->watch(*this); +} + /*! Returns a QString for passing on to QString based APIs. diff --git a/src/libs/utils/filepath.h b/src/libs/utils/filepath.h index e742bf1a0de..d1845571203 100644 --- a/src/libs/utils/filepath.h +++ b/src/libs/utils/filepath.h @@ -55,6 +55,16 @@ public: using FilePaths = QList; +class QTCREATOR_UTILS_EXPORT FilePathWatcher : public QObject +{ + Q_OBJECT +public: + using QObject::QObject; + +signals: + void pathChanged(const Utils::FilePath &path); +}; + class QTCREATOR_UTILS_EXPORT FilePath { public: @@ -270,6 +280,8 @@ public: bool equalsCaseSensitive(const FilePath &other) const; + Utils::expected_str> watch() const; + private: // These are needed. QTCREATOR_UTILS_EXPORT friend bool operator==(const FilePath &first, const FilePath &second); From 366aaf5f787dc74d96df6ffe5e0f216a2c9e44fb Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 20 Jun 2024 12:41:14 +0200 Subject: [PATCH 25/36] Utils: Add detection "aarch64" Change-Id: I493afbd30a10fc027239022826bc5cb09424851d Reviewed-by: hjk --- src/libs/utils/osspecificaspects.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/utils/osspecificaspects.h b/src/libs/utils/osspecificaspects.h index 239290faec7..0af8ad52102 100644 --- a/src/libs/utils/osspecificaspects.h +++ b/src/libs/utils/osspecificaspects.h @@ -57,7 +57,7 @@ inline OsArch osArchFromString(const QString &architecture) return OsArchItanium; if (architecture == QLatin1String("arm")) return OsArchArm; - if (architecture == QLatin1String("arm64")) + if (architecture == QLatin1String("arm64") || architecture == QLatin1String("aarch64")) return OsArchArm64; return OsArchUnknown; } From 04f56b01d41277ece6eb902a0cbaa01880387645 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 20 Jun 2024 12:43:58 +0200 Subject: [PATCH 26/36] Docker: Add "isContainerRunning" Change-Id: I2e22f5fb0ed86b0f7d61dc47c23696c00ec875ea Reviewed-by: hjk --- src/plugins/docker/dockerapi.cpp | 20 ++++++++++++++++++++ src/plugins/docker/dockerapi.h | 2 ++ 2 files changed, 22 insertions(+) diff --git a/src/plugins/docker/dockerapi.cpp b/src/plugins/docker/dockerapi.cpp index ea62fd88113..ccfaaf104c3 100644 --- a/src/plugins/docker/dockerapi.cpp +++ b/src/plugins/docker/dockerapi.cpp @@ -54,6 +54,26 @@ bool DockerApi::canConnect() return result; } +bool DockerApi::isContainerRunning(const QString &containerId) +{ + Process process; + FilePath dockerExe = dockerClient(); + if (dockerExe.isEmpty() || !dockerExe.isExecutableFile()) + return false; + + process.setCommand( + CommandLine(dockerExe, QStringList{"inspect", "--format", "{{.State.Running}}", containerId})); + process.runBlocking(); + + if (process.result() == ProcessResult::FinishedWithSuccess) { + QString output = process.readAllStandardOutput().trimmed(); + if (output == "true") + return true; + } + + return false; +} + void DockerApi::checkCanConnect(bool async) { if (async) { diff --git a/src/plugins/docker/dockerapi.h b/src/plugins/docker/dockerapi.h index 3e697654a3a..87301a98d1a 100644 --- a/src/plugins/docker/dockerapi.h +++ b/src/plugins/docker/dockerapi.h @@ -44,6 +44,8 @@ public: static void recheckDockerDaemon(); QFuture>> networks(); + bool isContainerRunning(const QString &containerId); + signals: void dockerDaemonAvailableChanged(); From b32d23de3596875b271ebe4a07bf1428027b13b4 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 20 Jun 2024 12:44:45 +0200 Subject: [PATCH 27/36] ProjectExplorer: Add FileAccessFactory Change-Id: I2468934bae03f352b8011224f345795ba8941862 Reviewed-by: hjk --- src/plugins/projectexplorer/devicesupport/idevice.cpp | 9 +++++++++ src/plugins/projectexplorer/devicesupport/idevice.h | 1 + 2 files changed, 10 insertions(+) diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp index 1387f9edc44..90eca216fa7 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp @@ -139,6 +139,7 @@ public: IDevice::MachineType machineType = IDevice::Hardware; OsType osType = OsTypeOther; DeviceFileAccess *fileAccess = nullptr; + std::function fileAccessFactory; int version = 0; // This is used by devices that have been added by the SDK. Utils::SynchronizedValue sshParameters; @@ -251,6 +252,9 @@ bool IDevice::isAnyUnixDevice() const DeviceFileAccess *IDevice::fileAccess() const { + if (d->fileAccessFactory) + return d->fileAccessFactory(); + return d->fileAccess; } @@ -341,6 +345,11 @@ void IDevice::setFileAccess(DeviceFileAccess *fileAccess) d->fileAccess = fileAccess; } +void IDevice::setFileAccess(std::function fileAccessFactory) +{ + d->fileAccessFactory = fileAccessFactory; +} + IDevice::DeviceInfo IDevice::deviceInformation() const { const QString key = Tr::tr("Device"); diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h index b83c558e87b..490906bf901 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.h +++ b/src/plugins/projectexplorer/devicesupport/idevice.h @@ -241,6 +241,7 @@ protected: void setDisplayType(const QString &type); void setOsType(Utils::OsType osType); void setFileAccess(Utils::DeviceFileAccess *fileAccess); + void setFileAccess(std::function fileAccessFactory); private: IDevice(const IDevice &) = delete; From 1ab00ae5ec0e7c86df3ffe4e9280299a812e6279 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Fri, 21 Jun 2024 06:18:25 +0200 Subject: [PATCH 28/36] Fix Qbs build Amends f5dde315584ef1bea80dccf1e5571cbd58418a4d. Change-Id: I409b872ccab2bfe825df3c993aaf942d327e9381 Reviewed-by: Marcus Tillmanns --- qbs/imports/QtcLuaPlugin.qbs | 12 ------------ src/plugins/plugins.qbs | 4 ---- 2 files changed, 16 deletions(-) delete mode 100644 qbs/imports/QtcLuaPlugin.qbs diff --git a/qbs/imports/QtcLuaPlugin.qbs b/qbs/imports/QtcLuaPlugin.qbs deleted file mode 100644 index 1684590480c..00000000000 --- a/qbs/imports/QtcLuaPlugin.qbs +++ /dev/null @@ -1,12 +0,0 @@ -Product { - Depends { name: "qtc" } - - property stringList luafiles - - Group { - prefix: sourceDirectory + '/' + product.name + '/' - files: luafiles - qbs.install: true - qbs.installDir: qtc.ide_plugin_path + '/' + product.name - } -} diff --git a/src/plugins/plugins.qbs b/src/plugins/plugins.qbs index 820ff891224..7293d34d683 100644 --- a/src/plugins/plugins.qbs +++ b/src/plugins/plugins.qbs @@ -55,8 +55,6 @@ Project { "languageclient/languageclient.qbs", "languageclient/lualanguageclient/lualanguageclient.qbs", "lua/lua.qbs", - "luals/luals.qbs", - "luatests/luatests.qbs", "macros/macros.qbs", "marketplace/marketplace.qbs", "mcusupport/mcusupport.qbs", @@ -81,7 +79,6 @@ Project { "qtsupport/qtsupport.qbs", "remotelinux/remotelinux.qbs", "resourceeditor/resourceeditor.qbs", - "rustls/rustls.qbs", "saferenderer/saferenderer.qbs", "screenrecorder/screenrecorder.qbs", "scxmleditor/scxmleditor.qbs", @@ -90,7 +87,6 @@ Project { "squish/squish.qbs", "studiowelcome/studiowelcome.qbs", "subversion/subversion.qbs", - "tellajoke/tellajoke.qbs", "terminal/terminal.qbs", "texteditor/texteditor.qbs", "todo/todo.qbs", From 2f2ed24092c4b30c5a912c72fa61820a4222fc06 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 20 Jun 2024 16:34:44 +0200 Subject: [PATCH 29/36] Doc: Update info on CMake presets - Described overriding CMake project settings in CMake presets or a CMakeLists.txt.shared file - Added an example of setting debuggers - Added an example of cross-compiling and running on the wine emulator Task-number: QTCREATORBUG-30604 Change-Id: I04f26d98e21b1a1a214de5ab4451ac1e758e489e Reviewed-by: Cristian Adam --- dist/changelog/changes-14.0.0.md | 4 + .../cmake/creator-projects-cmake-presets.qdoc | 74 ++++++++++++++++++- .../creator-projects-settings-cmake.qdoc | 3 + .../src/conan/creator-projects-conan.qdoc | 13 +++- .../creator-projects-settings-sharing.qdoc | 36 ++++++++- 5 files changed, 123 insertions(+), 7 deletions(-) diff --git a/dist/changelog/changes-14.0.0.md b/dist/changelog/changes-14.0.0.md index 2c0715e9b3b..7d14123acae 100644 --- a/dist/changelog/changes-14.0.0.md +++ b/dist/changelog/changes-14.0.0.md @@ -163,7 +163,11 @@ Projects [QTCREATORBUG-29559](https://bugreports.qt.io/browse/QTCREATORBUG-29559), [QTCREATORBUG-30385](https://bugreports.qt.io/browse/QTCREATORBUG-30385)) * Made it possible to register debuggers + ([QTCREATORBUG-30836](https://bugreports.qt.io/browse/QTCREATORBUG-30836)) * Added support for custom build types + ([QTCREATORBUG-30014](https://bugreports.qt.io/browse/QTCREATORBUG-30014)) + + ([Documentation](https://doc-snapshots.qt.io/qtcreator-14.0/creator-build-settings-cmake-presets.html)) ### Workspace diff --git a/doc/qtcreator/src/cmake/creator-projects-cmake-presets.qdoc b/doc/qtcreator/src/cmake/creator-projects-cmake-presets.qdoc index 050b0b1f8c7..41937eb6b92 100644 --- a/doc/qtcreator/src/cmake/creator-projects-cmake-presets.qdoc +++ b/doc/qtcreator/src/cmake/creator-projects-cmake-presets.qdoc @@ -57,12 +57,26 @@ }, "environment": { "AN_ENVIRONMENT_FLAG": "1" + } + }, + "vendor": { + "qt.io/QtCreator/1.0": { + "AskBeforePresetsReload": false, + "AskReConfigureInitialParams": false, + "AutorunCMake": false, + "PackageManagerAutoSetup": false, + "ShowAdvancedOptionsByDefault": true, + "ShowSourceSubFolders": false, + "UseJunctionsForSourceAndBuildDirectories": true + } } - } ] } \endcode + For more information about the CMake project settings in the \c vendor + section, see \l {Override CMake settings for a project}. + \section1 MinGW Example The following example configures a Qt project with: @@ -74,6 +88,7 @@ \li generator – MinGW Makefiles \li path to a CMake executable \li path to the Qt installation via \c CMAKE_PREFIX_PATH + \li GNU gdb 11.2.0 for MinGW 11.2.0 64-bit debugger \endlist \badcode @@ -92,8 +107,17 @@ }, "environment": { "PATH": "C:/Qt/Tools/mingw1120_64/bin;$penv{PATH}" - } - } + }, + "vendor": { + "qt.io/QtCreator/1.0": { + "debugger": { + "DisplayName": "GNU gdb 11.2.0 for MinGW 11.2.0 64-bit", + "Abis": ["x86-windows-msys-pe-64bit"], + "Binary": "C:/Qt/Tools/mingw1120_64/bin/gdb.exe", + "EngineType": 1, + "Version": "11.2.0" + } + } ] } \endcode @@ -188,6 +212,50 @@ } \endcode + \section1 Cross-Compilation Example + + The following example configures a Qt project for cross-compilation on \macos + for Windows and running with the \c wine emulator on \macos: + + \list + \li generator – Ninja + \li build directory – \c /build-release + \li LLVM/MinGW toolchain + \li configuration type – \c CMAKE_BUILD_TYPE as \c Release + \li LLDB 18.1.6 debugger + \li \c wine emulator + \endlist + + \badcode + { + "version": 4, + "configurePresets": [ + { + "name": "llvm-mingw", + "displayName": "LLVM-MinGW 18.1.6", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build-release", + "toolchainFile": "llvm-mingw.cmake", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_CROSSCOMPILING_EMULATOR": "/opt/homebrew/bin/wine" + }, + "vendor": { + "qt.io/QtCreator/1.0": { + "debugger": { + "DisplayName": "LLDB 18.1.6 (CMake Preset)", + "Abis": ["x86-darwin-generic-mach_o-64bit", "arm-darwin-generic-mach_o-64bit"], + "Binary": "/Users/jdoe/llvm-mingw/bin/lldb", + "EngineType": 256, + "Version": "18.1.6" + } + } + } + } + ] + } + \endcode + \section1 Using Conditions The following configure presets are used if they match \c condition. That is, diff --git a/doc/qtcreator/src/cmake/creator-projects-settings-cmake.qdoc b/doc/qtcreator/src/cmake/creator-projects-settings-cmake.qdoc index 95921a00a64..24f65674e30 100644 --- a/doc/qtcreator/src/cmake/creator-projects-settings-cmake.qdoc +++ b/doc/qtcreator/src/cmake/creator-projects-settings-cmake.qdoc @@ -67,6 +67,9 @@ \li \l{Using Junction Points on Windows} \endtable + You can set these preferences as \l{Configure Presets}{CMake presets} or in + a \l{Share project settings}{CMakeLists.txt.shared} file. + \sa {Build with CMake}{How To: Build with CMake}, {CMake}, {Configuring Projects} */ diff --git a/doc/qtcreator/src/conan/creator-projects-conan.qdoc b/doc/qtcreator/src/conan/creator-projects-conan.qdoc index 0e7229ba7c3..67cdd9141ae 100644 --- a/doc/qtcreator/src/conan/creator-projects-conan.qdoc +++ b/doc/qtcreator/src/conan/creator-projects-conan.qdoc @@ -44,9 +44,16 @@ Then, you must edit the build settings of the project to specify the location of the file and the contents of the Conan install command. - Alternatively, you can automatically set up the Conan package manager for - use with CMake. + \section1 Automatic Package Manager Setup + + To automatically set up the Conan package manager for use with CMake, + go to \uicontrol Projects > \uicontrol {Project Settings} > \uicontrol CMake, + and select \uicontrol {Package manager auto setup}. + + To turn off the automatic package manager setup, set + \c PackageManagerAutoSetup to \c false in \l{Configure Presets} + {CMake presets} or a \l{Share project settings}{CMakeLists.txt.shared} file. \sa {Conan Build Configuration}, {Enable and disable plugins}, - {Using CMake with Package Managers} + {Override CMake settings for a project}, {Using CMake with Package Managers} */ diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-settings-sharing.qdoc b/doc/qtcreator/src/projects/creator-only/creator-projects-settings-sharing.qdoc index 3e48923ad36..09898e8f56e 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-settings-sharing.qdoc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-settings-sharing.qdoc @@ -20,7 +20,8 @@ has the same XML structure as a \e {.user} file, but only has the settings to share. - \note Use \l{CMake Presets} to share CMake project settings. + To share CMake project settings, use \l{CMake Presets} or a + \c {CMakeLists.txt.shared} file. \section1 Create a shared settings file @@ -72,5 +73,38 @@ a permanent sticky setting that was created just because you wanted to try something out. + \section1 Share CMake project settings + + The following is an example of a \c {CMakeLists.txt.shared} file: + + \badcode + + + + + ProjectExplorer.Project.PluginSettings + + + false + false + false + false + true + false + false + true + + + + + Version + 22 + + + \endcode + + For more information about the settings, see + \l {Override CMake settings for a project}. + \sa {Configuring Projects}, {CMake Presets} */ From 3b558792ebfd24247544d651235b6e5c47d893c1 Mon Sep 17 00:00:00 2001 From: Sami Shalayel Date: Mon, 17 Jun 2024 14:21:07 +0200 Subject: [PATCH 30/36] qmlls: ignore versions from Qt 6.7 or below Do not select qmlls executables from versions below 6.8 by default, as those have less features than QtC's builtin codemodel. Add an option to re-enable using qmlls versions from Qt 6.7 or below, which is off by default. Fixes: QTCREATORBUG-31088 Change-Id: I56bfd39bc980996a92232cbcb424252d755cdfc0 Reviewed-by: hjk Reviewed-by: David Schulz Reviewed-by: Eike Ziller --- .../qmljseditor/qmljseditingsettingspage.cpp | 17 ++++++++++++++++- src/plugins/qmljseditor/qmljseditordocument.cpp | 5 +++++ src/plugins/qmljseditor/qmllssettings.cpp | 3 +++ src/plugins/qmljseditor/qmllssettings.h | 6 +++++- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/plugins/qmljseditor/qmljseditingsettingspage.cpp b/src/plugins/qmljseditor/qmljseditingsettingspage.cpp index 644c0d1d50e..433f0f8b1e0 100644 --- a/src/plugins/qmljseditor/qmljseditingsettingspage.cpp +++ b/src/plugins/qmljseditor/qmljseditingsettingspage.cpp @@ -35,6 +35,7 @@ const char QML_CONTEXTPANEPIN_KEY[] = "QmlJSEditor.ContextPanePinned"; const char FOLD_AUX_DATA[] = "QmlJSEditor.FoldAuxData"; const char USE_QMLLS[] = "QmlJSEditor.UseQmlls"; const char USE_LATEST_QMLLS[] = "QmlJSEditor.UseLatestQmlls"; +const char IGNORE_MINIMUM_QMLLS_VERSION[] = "QmlJSEditor.IgnoreMinimumQmllsVersion"; const char DISABLE_BUILTIN_CODEMODEL[] = "QmlJSEditor.DisableBuiltinCodemodel"; const char GENERATE_QMLLS_INI_FILES[] = "QmlJSEditor.GenerateQmllsIniFiles"; const char UIQML_OPEN_MODE[] = "QmlJSEditor.openUiQmlMode"; @@ -107,6 +108,8 @@ void QmlJsEditingSettings::fromSettings(QtcSettings *settings) m_uiQmlOpenMode = settings->value(UIQML_OPEN_MODE, "").toString(); m_qmllsSettings.useQmlls = settings->value(USE_QMLLS, QVariant(true)).toBool(); m_qmllsSettings.useLatestQmlls = settings->value(USE_LATEST_QMLLS, QVariant(false)).toBool(); + m_qmllsSettings.ignoreMinimumQmllsVersion + = settings->value(IGNORE_MINIMUM_QMLLS_VERSION, QVariant(false)).toBool(); m_qmllsSettings.disableBuiltinCodemodel = settings->value(DISABLE_BUILTIN_CODEMODEL, QVariant(false)).toBool(); m_qmllsSettings.generateQmllsIniFiles @@ -138,6 +141,7 @@ void QmlJsEditingSettings::toSettings(QtcSettings *settings) const settings->setValue(UIQML_OPEN_MODE, m_uiQmlOpenMode); settings->setValue(USE_QMLLS, m_qmllsSettings.useQmlls); settings->setValue(USE_LATEST_QMLLS, m_qmllsSettings.useLatestQmlls); + settings->setValue(IGNORE_MINIMUM_QMLLS_VERSION, m_qmllsSettings.ignoreMinimumQmllsVersion); settings->setValue(DISABLE_BUILTIN_CODEMODEL, m_qmllsSettings.disableBuiltinCodemodel); settings->setValue(GENERATE_QMLLS_INI_FILES, m_qmllsSettings.generateQmllsIniFiles); settings->setValueWithDefault(FORMAT_COMMAND, m_formatCommand, {}); @@ -399,6 +403,13 @@ public: useQmlls = new QCheckBox(Tr::tr("Enable QML Language Server")); useQmlls->setChecked(s.qmllsSettings().useQmlls); + + ignoreMinimumQmllsVersion = new QCheckBox( + Tr::tr("Allow versions below Qt %1") + .arg(QmllsSettings::mininumQmllsVersion.toString())); + ignoreMinimumQmllsVersion->setChecked(s.qmllsSettings().ignoreMinimumQmllsVersion); + ignoreMinimumQmllsVersion->setEnabled(s.qmllsSettings().useQmlls); + disableBuiltInCodemodel = new QCheckBox( Tr::tr("Use QML Language Server advanced features (renaming, find usages and co.) " "(EXPERIMENTAL!)")); @@ -407,6 +418,7 @@ public: useLatestQmlls = new QCheckBox(Tr::tr("Use QML Language Server from latest Qt version")); useLatestQmlls->setChecked(s.qmllsSettings().useLatestQmlls); useLatestQmlls->setEnabled(s.qmllsSettings().useQmlls); + generateQmllsIniFiles = new QCheckBox( Tr::tr("Generate QML Language Server .qmlls.ini configurations for new projects.")); generateQmllsIniFiles->setChecked(s.qmllsSettings().generateQmllsIniFiles); @@ -415,6 +427,7 @@ public: useLatestQmlls->setEnabled(checked != Qt::Unchecked); disableBuiltInCodemodel->setEnabled(checked != Qt::Unchecked); generateQmllsIniFiles->setEnabled(checked != Qt::Unchecked); + ignoreMinimumQmllsVersion->setEnabled(checked != Qt::Unchecked); }); useCustomAnalyzer = new QCheckBox(Tr::tr("Use customized static analyzer")); @@ -467,7 +480,7 @@ public: }, Group{ title(Tr::tr("QML Language Server")), - Column{useQmlls, disableBuiltInCodemodel , useLatestQmlls, generateQmllsIniFiles}, + Column{useQmlls, ignoreMinimumQmllsVersion, disableBuiltInCodemodel, useLatestQmlls, generateQmllsIniFiles}, }, Group { title(Tr::tr("Static Analyzer")), @@ -513,6 +526,7 @@ public: s.qmllsSettings().useQmlls = useQmlls->isChecked(); s.qmllsSettings().disableBuiltinCodemodel = disableBuiltInCodemodel->isChecked(); s.qmllsSettings().useLatestQmlls = useLatestQmlls->isChecked(); + s.qmllsSettings().ignoreMinimumQmllsVersion = ignoreMinimumQmllsVersion->isChecked(); s.qmllsSettings().generateQmllsIniFiles = generateQmllsIniFiles->isChecked(); s.setUseCustomAnalyzer(useCustomAnalyzer->isChecked()); QSet disabled; @@ -571,6 +585,7 @@ private: QCheckBox *foldAuxData; QCheckBox *useQmlls; QCheckBox *useLatestQmlls; + QCheckBox *ignoreMinimumQmllsVersion; QCheckBox *disableBuiltInCodemodel; QCheckBox *generateQmllsIniFiles; QComboBox *uiQmlOpenComboBox; diff --git a/src/plugins/qmljseditor/qmljseditordocument.cpp b/src/plugins/qmljseditor/qmljseditordocument.cpp index cef1aefcd2b..3dfb9b8f137 100644 --- a/src/plugins/qmljseditor/qmljseditordocument.cpp +++ b/src/plugins/qmljseditor/qmljseditordocument.cpp @@ -745,6 +745,11 @@ static Utils::FilePath qmllsForFile(const Utils::FilePath &file, if (settings.useLatestQmlls) return settingsManager->latestQmlls(); QmlJS::ModelManagerInterface::ProjectInfo pInfo = modelManager->projectInfoForPath(file); + + if (!settings.ignoreMinimumQmllsVersion + && QVersionNumber::fromString(pInfo.qtVersionString) < settings.mininumQmllsVersion) { + return {}; + } return pInfo.qmllsPath; } diff --git a/src/plugins/qmljseditor/qmllssettings.cpp b/src/plugins/qmljseditor/qmllssettings.cpp index 15cb8908afb..8ca9936957f 100644 --- a/src/plugins/qmljseditor/qmllssettings.cpp +++ b/src/plugins/qmljseditor/qmllssettings.cpp @@ -33,9 +33,12 @@ static FilePath evaluateLatestQmlls() QVersionNumber latestVersion; FilePath latestQmakeFilePath; int latestUniqueId = std::numeric_limits::min(); + const QmllsSettings qmllsSettings = QmllsSettingsManager::instance()->lastSettings(); for (QtVersion *v : versions) { // check if we find qmlls QVersionNumber vNow = v->qtVersion(); + if (!qmllsSettings.ignoreMinimumQmllsVersion && vNow < qmllsSettings.mininumQmllsVersion) + continue; FilePath qmllsNow = QmlJS::ModelManagerInterface::qmllsForBinPath(v->hostBinPath(), vNow); if (!qmllsNow.isExecutableFile()) continue; diff --git a/src/plugins/qmljseditor/qmllssettings.h b/src/plugins/qmljseditor/qmllssettings.h index 90d8ff6ca8f..ad11a541c52 100644 --- a/src/plugins/qmljseditor/qmllssettings.h +++ b/src/plugins/qmljseditor/qmllssettings.h @@ -5,6 +5,7 @@ #include "qmljseditor_global.h" +#include #include #include #include @@ -13,8 +14,10 @@ namespace QmlJSEditor { struct QmllsSettings { + static const inline QVersionNumber mininumQmllsVersion = QVersionNumber(6,8); bool useQmlls = true; bool useLatestQmlls = false; + bool ignoreMinimumQmllsVersion = false; bool disableBuiltinCodemodel = false; bool generateQmllsIniFiles = false; @@ -22,7 +25,8 @@ struct QmllsSettings { return s1.useQmlls == s2.useQmlls && s1.useLatestQmlls == s2.useLatestQmlls && s1.disableBuiltinCodemodel == s2.disableBuiltinCodemodel - && s1.generateQmllsIniFiles == s2.generateQmllsIniFiles; + && s1.generateQmllsIniFiles == s2.generateQmllsIniFiles + && s1.ignoreMinimumQmllsVersion == s2.ignoreMinimumQmllsVersion; } friend bool operator!=(const QmllsSettings &s1, const QmllsSettings &s2) { return !(s1 == s2); } }; From 2809b27be8f67eb1c88f267285646d647113d83a Mon Sep 17 00:00:00 2001 From: Sami Shalayel Date: Mon, 17 Jun 2024 14:21:07 +0200 Subject: [PATCH 31/36] doc: document new qmlls checkbox for older versions Also document the new behavior in the documentation about enabling older qmlls versions. Task-number: QTCREATORBUG-31088 Change-Id: I619119f5fec077a50712566bd8fa32b414e239dc Reviewed-by: Leena Miettinen --- .../src/editors/creator-only/creator-language-server.qdoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/qtcreator/src/editors/creator-only/creator-language-server.qdoc b/doc/qtcreator/src/editors/creator-only/creator-language-server.qdoc index 8d82c2a52a9..281201fb300 100644 --- a/doc/qtcreator/src/editors/creator-only/creator-language-server.qdoc +++ b/doc/qtcreator/src/editors/creator-only/creator-language-server.qdoc @@ -255,6 +255,9 @@ \QMLLS of the highest registered Qt version, select \uicontrol {Use \QMLLS from latest Qt version}. + To use older \QMLLS versions, select + \uicontrol{Allow versions below Qt 6.8}. + \image qtcreator-qml-js-editing.webp {QML/JS Editing preferences} When using \c qmlls from Qt 6.7 or later, set \l{QT_QML_GENERATE_QMLLS_INI} From ca7fd2aaf30121c17d0f15de2f374fc06bc32735 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 19 Jun 2024 15:05:49 +0200 Subject: [PATCH 32/36] Debugger: remove overwritten createValue in the cdbbridge The function is nowadays generating values the exact same way as the base implementation. Change-Id: Ie1b167021d9d450959d9cf3c27b0ac8ec7d0d3af Reviewed-by: Christian Stenger --- share/qtcreator/debugger/cdbbridge.py | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/share/qtcreator/debugger/cdbbridge.py b/share/qtcreator/debugger/cdbbridge.py index c013cb321f7..347d2f89c9e 100644 --- a/share/qtcreator/debugger/cdbbridge.py +++ b/share/qtcreator/debugger/cdbbridge.py @@ -883,26 +883,6 @@ class Dumper(DumperBase): self.putItem(derefValue) self.currentChildType = savedCurrentChildType - def createValue(self, datish, typish): - if isinstance(datish, int): # Used as address. - return self.createValueFromAddressAndType(datish, typish) - if isinstance(datish, bytes): - val = self.Value(self) - val.typeid = self.create_typeid(typish) - #DumperBase.warn('CREATING %s WITH DATA %s' % (val.type.name, self.hexencode(datish))) - val.ldata = datish - val.check() - return val - raise RuntimeError('EXPECTING ADDRESS OR BYTES, GOT %s' % type(datish)) - - def createValueFromAddressAndType(self, address, typish): - val = self.Value(self) - val.typeid = self.create_typeid(typish) - val.laddress = address - if self.useDynamicType: - val.typeid = self.dynamic_typeid_at_address(val.typeid, address) - return val - def fetchInternalFunctions(self): coreModuleName = self.qtCoreModuleName() ns = self.qtNamespace() From b09850eabc876a9da098d9f03bca3d35bee84382 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Thu, 20 Jun 2024 16:54:48 +0200 Subject: [PATCH 33/36] Lua: Add icon for Qt Creator Lua Plugin wizard Change-Id: I00db10401aaaddc3dbb0fab96e577268aa43f149 Reviewed-by: Marcus Tillmanns --- src/plugins/lua/wizards/plugin/icon.png | Bin 0 -> 887 bytes src/plugins/lua/wizards/plugin/icon@2x.png | Bin 0 -> 1963 bytes src/plugins/lua/wizards/plugin/wizard.json | 3 +- src/plugins/lua/wizards/wizards.qrc | 2 + src/tools/icons/qtcreatoricons.svg | 42 +++++++++++++++++++++ 5 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 src/plugins/lua/wizards/plugin/icon.png create mode 100644 src/plugins/lua/wizards/plugin/icon@2x.png diff --git a/src/plugins/lua/wizards/plugin/icon.png b/src/plugins/lua/wizards/plugin/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..11ccac86ddd3c6016be2c2c3d68b2506e7169c3d GIT binary patch literal 887 zcmeAS@N?(olHy`uVBq!ia0y~yU@!n-4h9AWhN8@6(F_dCcAhSdAs)xqPP^+JoG5dg z|0cJ|-P@f7$_CB<8uWsggIAmpw_0@Vna2hW1^W0*`{i~nboPS?@?(<)}^PjExUH&9H{AWF& ztXI7HrszR#masDiP5&^&^G1bnF|WzaNxm8;QP9r(sLiS2uI3S;9`(y7D-JaIsP!|I zE%%wsAyyb2rTZ>YMsfZmONLuB_1YgsPI53Xdg0e{gIDTJY|U{6$@E>83VD;Q*iKqF zt0hXTRn#lxnN-|1M{aH6%~je~xA!U*@JzBQUZKA#_v5drng7mkGdnR~F8l1h z&v?z$*(EohTG^_*%;I**pgs zZ>(OvRs5>yxrv1aeOB62L`5#0&CJ*)%w8<}&o+vKn?--B6>~$kgMa4R=P6r`oZYeH zuiSg-8%eT>3?ZqfmIXgF*LroQc~-RCeUHs$Wnb!gO8Z#lvhFy@=vlbr#9f$w;r5}q z`rkPj8?yHNxpLk5Wl54;#RJw;kG}JLNiQqDe86<-gTL}K7N$N3+IFvUxg;f70bTxOrJ)%D9d!+p$rEq0h^SD`z#+rvr97 z|f`RR%8uOC11ym4L4_1nb^$E;3PE@&*>5pT9XK3V2y>iYU#{2({b&?%DOl@1*jzL&IfXNJu!# vUR|~7sFR-h?Z#uDj|LQ01{+L#ZuVJxxxii4DuD%Bpd97t>gTe~DWM4f$$gM2 literal 0 HcmV?d00001 diff --git a/src/plugins/lua/wizards/plugin/icon@2x.png b/src/plugins/lua/wizards/plugin/icon@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..49a2ad834e9227beea8a2634fe0d3a4224b46b97 GIT binary patch literal 1963 zcmeAS@N?(olHy`uVBq!ia0y~yU`POA4h9AWhU1?#o-i=57kRokhGg7(J1f^GI9%fR z|D~dWoI(eao=wu^di3p};vtu5KQ{TwR=LDnSrKrh@x7Ap!H!)Fn=|gPXu4{+T--5H zGPdK2gs5km^IW}~PYzG=JbGk>U@}W$aLcr^@84SQ-Tr-RUES@^tzYKcd+vVD^8EWR zcd8SsPdEN&tYe9I|2JY+>DNuEtG7>^w>SN(^?{;7SeqDIe(SMjWY`Z8r!TH3lRoBkhZQi;5bNXK^ zr?Q~l$V(h2yym-hT-?zbnGvlQxgu+FW5b*;({)V_WZ0Bv{GPRCi|K9txyF$%D+|9? zaVA(iKf#vH#NNR7?1=UM#xu=PiSCYvEHm%(SxoxKoMX0G&-Y5;gy%B6;vcTWWlZX8 zvUx6}+$zV=uC+v#wes9Tp;Ti==iHkro1^;{D_pkpe_QIn_`)h*t}E7= zZu9!V(atL?y`Da~BCLNzhV|#UjkC^8-SzsxRx^=v5{qkf-)NjD(`nrGkz1QiT;)&ta&_+dZdM?Sag+)cfvj>I$-%a`)e#+PL0cJ;Bn`)-^l$gk{d@KDSQw z1rouL_vJ0-dW9J=q;qq4<_nhb-JZ30!Dp5i0*C(m%jJ!%`eDhOU^4H|qzQZZTjw0! zmc}6-&=~Oj`+SkW`hO*7*zN>Zm#BKKt$kW@Zc)n(&cuVtOiWITgs#;UFPxHkR$`wb zSK(F1dS|J~yCx}*8G4?7*HfK!I&8J4x&K-QZIQ%E*}MZr`#kH82eMz=_BAE*=IMuD zS*|@=v)pG=b&A;3K+(+s!3%WPuhP0MmLYa*#foK1jMLN~sN6TQO@06Bj`N9i)jh1I z*(7G45^ic-@Fd3ecUA4XHwp8^li1^jyX}f{Xz{lz9`LIr(rARQFCKUS54un`)X_&JT5h@jz(IK1g>~! zKfJ(kU5d}TCS6)lHP*)dmt?~shBNC8Pjt-M8E}c^_9FhvNzP75mtXm&PU)?GY#X|R zacN_O(wr^tX01G)^Ul!p`o;M{0#{ybdv@TbXo~CM1->!?!abFTey;zvOYh}guljl2 z8-DAZzISfXR<#nnB1SRy#I^@Nu52^b&sx9KO_ML!{Knd!OKvPQ)jZ(h!gW61`uD2c zUwl>@c5X_mKU}o@nhL|o0M7O2SI?UsyHM);N)hv!QNrvIPOfS@)?NR+$*yXdy?c(G zbM_+!=3|`K-3j&fno*L6w zJKWbv95}Lf-QkOqoBN+IR87&kXuE7?{me_rOM$T|TZ@St7*%q*H zAN_lNHCMIH0Y}M(t&6&+xR=%Ql&3f-Gf!w>;&gZ$JIyD%-TISi+Rt+92ewnZ-c1U> zBYjTPZL`>9mrM5Asw(rDdR%9Iv5UE$^GZ^tBzNXIi!P3XUk*!aG6kl7FkEF2q_MwR zxmKIunVVLA$B)O>{}hw*m(0*ep2XTzKFQWRNb+=uLD^@W;A=k*@J-M&IruO#RcHa(ul|AxWq`qX_-*N3c>SoYLf-XgE<%n`r)4Av6GIS*~+ zEg0gHx8*lPzSG@2_kYa;h8ai9Yaa?qtt|MLR;5>BS8z|?>r?K+tPdNn{5-&E(R?E7 z{pVo&JyJ`~vHLYt8g1Ikp5w5^^;OM-T}#8-IreVJ07dDXX44Of-LRSo!-gg(D|t zyiC4q_-IT1`7hCj7u-|dX{Rjkt9!jZ@16d3E!Qh+rgn#TR6O_{&6!`sBrs1kW8W*@ zha4wlH~i$=aI#UmG$k5Q4W#z}3G`$=q-bvVa^AE#<^xYbPC--e#Gb{Ac%lqN}ab}suLW_^F mvGw(OUCEeTRa>|HX?%H5!DeSBlPwGk3=E#GelF{r5}E+{d#ZZ? literal 0 HcmV?d00001 diff --git a/src/plugins/lua/wizards/plugin/wizard.json b/src/plugins/lua/wizards/plugin/wizard.json index a295dc27d45..d96a35c7d0e 100644 --- a/src/plugins/lua/wizards/plugin/wizard.json +++ b/src/plugins/lua/wizards/plugin/wizard.json @@ -8,7 +8,8 @@ "trDescription": "Creates a custom Qt Creator Lua plugin.", "trDisplayName": "Qt Creator Lua Plugin", "trDisplayCategory": "Library", - "iconText": "LuaP", + "icon": "icon.png", + "iconKind": "Themed", "featuresRequired": [], "options": [ { diff --git a/src/plugins/lua/wizards/wizards.qrc b/src/plugins/lua/wizards/wizards.qrc index 098c2c3f418..076550cb4a6 100644 --- a/src/plugins/lua/wizards/wizards.qrc +++ b/src/plugins/lua/wizards/wizards.qrc @@ -7,5 +7,7 @@ plugin/project.json plugin/wizard.json plugin/.luarc.json + plugin/icon.png + plugin/icon@2x.png diff --git a/src/tools/icons/qtcreatoricons.svg b/src/tools/icons/qtcreatoricons.svg index 7aa9fe1bed7..01ec12e64ba 100644 --- a/src/tools/icons/qtcreatoricons.svg +++ b/src/tools/icons/qtcreatoricons.svg @@ -1975,6 +1975,48 @@ id="path4127-25-8" /> + + + + + + + + + Date: Fri, 21 Jun 2024 09:10:00 +0200 Subject: [PATCH 34/36] CMakePM: Do not hang on renaming source files from file(GLOB) Fixes: QTCREATORBUG-31016 Change-Id: I5b450cdb5a9af227ed058345adab1fc5b5a9043d Reviewed-by: Alessandro Portale --- src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index ec5e3a4b89f..e0d2b6773fb 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -985,7 +985,7 @@ bool CMakeBuildSystem::renameFile(Node *context, // Try the next occurrence. This can happen if set_source_file_properties is used fileToRename = projectFileArgumentPosition(targetName, oldRelPathName); - } while (fileToRename); + } while (fileToRename && !fileToRename->fromGlobbing); return true; } From 39695c3a17c321260aa362920c0e2b837a7edcf4 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Fri, 21 Jun 2024 07:37:18 +0200 Subject: [PATCH 35/36] Add lua-plugins to qbs build Amends 1ab00ae5ec0e7c86df3ffe4e9280299a812e6279. Change-Id: Ia87f2477a7fada63561b9dfb5b0de8f1a0cd81a2 Reviewed-by: Marcus Tillmanns --- share/share.qbs | 1 + 1 file changed, 1 insertion(+) diff --git a/share/share.qbs b/share/share.qbs index 2a1c8d8fce4..745a8131a94 100644 --- a/share/share.qbs +++ b/share/share.qbs @@ -17,6 +17,7 @@ Product { "designer/**/*", "glsl/**/*", "jsonschemas/**/*", + "lua-plugins/**/*", "modeleditor/**/*", "qml/**/*", "qmldesigner/**/*", From 65f766572289a7de60cc81de52857663e7467ef4 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 21 Jun 2024 09:18:59 +0200 Subject: [PATCH 36/36] Update qbs submodule to HEAD of 2.4 branch Change-Id: I960d309f14b4c4ec80469d9f6996210c15bf17cd Reviewed-by: Christian Stenger --- src/shared/qbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/shared/qbs b/src/shared/qbs index f67d43fc24b..2e54309c02a 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit f67d43fc24bec11a6b599d46304ea06e15218acd +Subproject commit 2e54309c02a56c602909ee3f4fef6c654a616c85