From 5ebd4c833ea3e0d8aa38101e25d3e64b9dc853a3 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 13 Mar 2024 16:59:19 +0100 Subject: QtSupport: Restrict QtVersionManagerImpl lifetime to plugin lifetime This occasionally triggered crashes on static destruction when hard-killing Qt Creator. Giving QtVersionManagerImpl the plugin as QObject parent effectively re-instates the lifetime behavior from before we moved to delayed initialization. We keep the delayed initialization, at the (acceptable) prize of a somewhat quirky setup. Change-Id: I1b4be284a1b573325ed5cc441778eeb48b94c24b Reviewed-by: Eike Ziller Reviewed-by: --- src/plugins/qtsupport/qtsupportplugin.cpp | 2 ++ src/plugins/qtsupport/qtversionmanager.cpp | 15 ++++++++++++--- src/plugins/qtsupport/qtversionmanager.h | 2 ++ 3 files changed, 16 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/qtsupport/qtsupportplugin.cpp b/src/plugins/qtsupport/qtsupportplugin.cpp index db0f8888af..c8a7b7cf1f 100644 --- a/src/plugins/qtsupport/qtsupportplugin.cpp +++ b/src/plugins/qtsupport/qtsupportplugin.cpp @@ -83,6 +83,8 @@ void QtSupportPlugin::initialize() addTestCreator(createQtProjectImporterTest); #endif + setupQtVersionManager(this); + setupDesktopQtVersion(); setupEmbeddedLinuxQtVersion(); setupGettingStartedWelcomePage(); diff --git a/src/plugins/qtsupport/qtversionmanager.cpp b/src/plugins/qtsupport/qtversionmanager.cpp index 063a130984..746f4f8c5e 100644 --- a/src/plugins/qtsupport/qtversionmanager.cpp +++ b/src/plugins/qtsupport/qtversionmanager.cpp @@ -89,7 +89,8 @@ static PersistentSettingsWriter *m_writer = nullptr; class QtVersionManagerImpl : public QObject { public: - QtVersionManagerImpl() + QtVersionManagerImpl(QObject *parent) + : QObject(parent) { qRegisterMetaType(); @@ -135,10 +136,18 @@ public: QTimer m_fileWatcherTimer; }; +static QObject *s_guard = nullptr; + +void Internal::setupQtVersionManager(QObject *guard) +{ + s_guard = guard; +} + QtVersionManagerImpl &qtVersionManagerImpl() { - static QtVersionManagerImpl theQtVersionManager; - return theQtVersionManager; + QTC_CHECK(s_guard); + static auto theQtVersionManager = new QtVersionManagerImpl(s_guard); + return *theQtVersionManager; } void QtVersionManagerImpl::triggerQtVersionRestore() diff --git a/src/plugins/qtsupport/qtversionmanager.h b/src/plugins/qtsupport/qtversionmanager.h index 9fa2cfb5b1..9eb17a4d8c 100644 --- a/src/plugins/qtsupport/qtversionmanager.h +++ b/src/plugins/qtsupport/qtversionmanager.h @@ -70,4 +70,6 @@ private: static int getUniqueId(); }; +namespace Internal { void setupQtVersionManager(QObject *guard); } + } // namespace QtSupport -- cgit v1.2.3 From fc4067a1188b6cf05f649ac236e231fc5a985b03 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 12 Mar 2024 10:04:42 +0100 Subject: Debugger: Annotate internal debug output with engine type Makes it easier to reason in mixed setups. Change-Id: I4f7aa43847dab51d4041fb1b9850ed9860a6dafc Reviewed-by: Qt CI Bot Reviewed-by: Christian Stenger --- src/plugins/debugger/debuggerengine.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 1be2f56604..fde7704c5b 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -1765,6 +1765,10 @@ void DebuggerEngine::showMessage(const QString &msg, int channel, int timeout) c d->m_logWindow->showInput(LogInput, msg); d->m_logWindow->showOutput(LogInput, msg); break; + case LogOutput: + case LogWarning: + d->m_logWindow->showOutput(channel, msg); + break; case LogError: d->m_logWindow->showInput(LogError, "ERROR: " + msg); d->m_logWindow->showOutput(LogError, "ERROR: " + msg); @@ -1779,7 +1783,7 @@ void DebuggerEngine::showMessage(const QString &msg, int channel, int timeout) c emit appendMessageRequested(msg, StdErrFormat, false); break; default: - d->m_logWindow->showOutput(channel, msg); + d->m_logWindow->showOutput(channel, QString("[%1] %2").arg(debuggerName(), msg)); break; } } -- cgit v1.2.3 From 11752615c5db419bd4bf9842b4f0ba1f8aca8051 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 14 Mar 2024 09:38:10 +0100 Subject: Process: Don't call waitForFinished() when process is not running Fixes: QTCREATORBUG-30537 Change-Id: I8594fd6982e22044a43e5a67411b50f1bdc02426 Reviewed-by: Marcus Tillmanns --- src/libs/utils/process.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/libs/utils/process.cpp b/src/libs/utils/process.cpp index 111ebe89cf..802ae632f1 100644 --- a/src/libs/utils/process.cpp +++ b/src/libs/utils/process.cpp @@ -1934,7 +1934,7 @@ void Process::runBlocking(seconds timeout, EventLoopMode eventLoopMode) #endif } else { handleStart(); - if (!waitForFinished(timeout)) + if (state() != QProcess::NotRunning && !waitForFinished(timeout)) handleTimeout(); } if (blockingThresholdMs > 0) { -- cgit v1.2.3 From cca64b14f3b1d9909e7d24eea0ab3314e5b1217c Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 12 Mar 2024 16:12:03 +0100 Subject: ExternalTools: Fix drag and drop in the preferences It mostly broke when Qt changed containers from int to qsizetype: When we use QDataStream to serialize the value of `QList::indexOf`, but deserialize that into an `int` variable, we don't get the same value back. Fix that, and also use begin/endMoveRows, which results in a better selection behavior after dropping. Fixes: QTCREATORBUG-30469 Change-Id: Ic99181ea7f75958766977ce7cf9d17c3d96103e2 Reviewed-by: Christian Stenger Reviewed-by: Qt CI Bot --- .../coreplugin/dialogs/externaltoolconfig.cpp | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp index 1916a3ba25..fe724a893a 100644 --- a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp +++ b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp @@ -174,19 +174,27 @@ bool ExternalToolModel::dropMimeData(const QMimeData *data, return false; QDataStream stream(&ba, QIODevice::ReadOnly); QString category; - int pos = -1; + qsizetype pos = -1; stream >> category; stream >> pos; QList &items = m_tools[category]; QTC_ASSERT(pos >= 0 && pos < items.count(), return false); - beginRemoveRows(index(m_tools.keys().indexOf(category), 0), pos, pos); + const int sourceCategoryIndex = std::distance(m_tools.constBegin(), m_tools.constFind(category)); + const int targetCategoryIndex + = std::distance(m_tools.constBegin(), m_tools.constFind(toCategory)); + QTC_ASSERT(sourceCategoryIndex >= 0 && targetCategoryIndex >= 0, return false); + if (row < 0) // target row can be -1 when dropping onto the category itself + row = 0; + if (sourceCategoryIndex == targetCategoryIndex) { + if (row == pos || row == pos + 1) // would end at the same place, don't + return false; + } + beginMoveRows(index(sourceCategoryIndex, 0), pos, pos, index(targetCategoryIndex, 0), row); ExternalTool *tool = items.takeAt(pos); - endRemoveRows(); - if (row < 0) - row = m_tools.value(toCategory).count(); - beginInsertRows(index(m_tools.keys().indexOf(toCategory), 0), row, row); + if (category == toCategory && pos < row) // adapt the target row for the removed item + --row; m_tools[toCategory].insert(row, tool); - endInsertRows(); + endMoveRows(); return true; } -- cgit v1.2.3 From 5d005e73132db0fec6bf32fda06a402473997fa9 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 14 Mar 2024 14:43:25 +0100 Subject: QtSettingsPageWidget: Don't leak m_model Change-Id: Ia543612d741b60fa35528e1f1eeade232a8daa15 Reviewed-by: hjk --- src/plugins/qtsupport/qtoptionspage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp index 7eb349d1da..7b08db2351 100644 --- a/src/plugins/qtsupport/qtoptionspage.cpp +++ b/src/plugins/qtsupport/qtoptionspage.cpp @@ -309,7 +309,7 @@ QtSettingsPageWidget::QtSettingsPageWidget() {ProjectExplorer::Constants::msgAutoDetectedToolTip()}); m_manualItem = new StaticTreeItem(ProjectExplorer::Constants::msgManual()); - m_model = new TreeModel(); + m_model = new TreeModel(this); m_model->setHeader({Tr::tr("Name"), Tr::tr("qmake Path")}); m_model->rootItem()->appendChild(m_autoItem); m_model->rootItem()->appendChild(m_manualItem); -- cgit v1.2.3 From 59669a929e714bd04bd5e81e3a6019f13272b555 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 14 Mar 2024 13:43:36 +0100 Subject: LanguageClientSettingsPageWidget: Don't leak QActions Amends 16decfec672962e96551ca565d342ab20fc454b8 Change-Id: Ib567502944fd5efca9442c88af9f163391e147bd Reviewed-by: David Schulz --- src/plugins/languageclient/languageclientsettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/languageclient/languageclientsettings.cpp b/src/plugins/languageclient/languageclientsettings.cpp index 503e79e2b8..38c5a46159 100644 --- a/src/plugins/languageclient/languageclientsettings.cpp +++ b/src/plugins/languageclient/languageclientsettings.cpp @@ -184,7 +184,7 @@ LanguageClientSettingsPageWidget::LanguageClientSettingsPageWidget(LanguageClien auto addMenu = new QMenu(this); addMenu->clear(); for (const ClientType &type : clientTypes()) { - auto action = new QAction(type.name); + auto action = new QAction(type.name, this); connect(action, &QAction::triggered, this, [this, id = type.id]() { addItem(id); }); addMenu->addAction(action); } -- cgit v1.2.3 From c9d51cfa4adf008643918035cb1f5b224aa4c9d9 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 14 Mar 2024 10:57:48 +0100 Subject: Utils: Allow multiple edits of an environment variable There is no reason to limit the environment modifications to unique variables. The environment modifications are processed sequentially from top to bottom and there may modifications that are done on the same variable (e.g. once a prepend, once an append,..) Change-Id: I8a187737be1108e537a926239088c6352dc92957 Reviewed-by: Christian Kandeler --- src/libs/utils/namevaluesdialog.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/libs/utils/namevaluesdialog.cpp b/src/libs/utils/namevaluesdialog.cpp index 43511fe57f..35587f8791 100644 --- a/src/libs/utils/namevaluesdialog.cpp +++ b/src/libs/utils/namevaluesdialog.cpp @@ -21,8 +21,7 @@ namespace Internal { static EnvironmentItems cleanUp(const EnvironmentItems &items) { - EnvironmentItems uniqueItems; - QSet uniqueSet; + EnvironmentItems cleanedItems; for (int i = items.count() - 1; i >= 0; i--) { EnvironmentItem item = items.at(i); if (HostOsInfo::isWindowsHost()) @@ -30,10 +29,10 @@ static EnvironmentItems cleanUp(const EnvironmentItems &items) const QString &itemName = item.name; QString emptyName = itemName; emptyName.remove(QLatin1Char(' ')); - if (!emptyName.isEmpty() && Utils::insert(uniqueSet, itemName)) - uniqueItems.prepend(item); + if (!emptyName.isEmpty()) + cleanedItems.prepend(item); } - return uniqueItems; + return cleanedItems; } class TextEditHelper : public QPlainTextEdit -- cgit v1.2.3 From 92fca248429808db83e84162db51cf96e1eddefe Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 14 Mar 2024 16:01:03 +0100 Subject: SystemSettingsWidget: Don't leak label and combobox on non mac host Change-Id: I9968a38055a8c1224aa09aad34ef5b3a30bd3490 Reviewed-by: Eike Ziller --- src/plugins/coreplugin/systemsettings.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/plugins/coreplugin/systemsettings.cpp b/src/plugins/coreplugin/systemsettings.cpp index 4ef1b0687b..9a0a40d02e 100644 --- a/src/plugins/coreplugin/systemsettings.cpp +++ b/src/plugins/coreplugin/systemsettings.cpp @@ -161,7 +161,7 @@ class SystemSettingsWidget : public IOptionsPageWidget { public: SystemSettingsWidget() - : m_fileSystemCaseSensitivityChooser(new QComboBox) + : m_fileSystemCaseSensitivityChooser(HostOsInfo::isMacHost() ? new QComboBox : nullptr) , m_externalFileBrowserEdit(new QLineEdit) , m_terminalComboBox(new QComboBox) , m_terminalOpenArgs(new QLineEdit) @@ -188,9 +188,6 @@ public: m_terminalOpenArgs->setToolTip( Tr::tr("Command line arguments used for \"%1\".").arg(FileUtils::msgTerminalHereAction())); - auto fileSystemCaseSensitivityLabel = new QLabel(Tr::tr("File system case sensitivity:")); - fileSystemCaseSensitivityLabel->setToolTip( - Tr::tr("Influences how file names are matched to decide if they are the same.")); auto resetFileBrowserButton = new QPushButton(Tr::tr("Reset")); resetFileBrowserButton->setToolTip(Tr::tr("Reset to default.")); auto helpExternalFileBrowserButton = new QToolButton; @@ -223,6 +220,9 @@ public: } grid.addRow({Span(4, s.patchCommand)}); if (HostOsInfo::isMacHost()) { + auto fileSystemCaseSensitivityLabel = new QLabel(Tr::tr("File system case sensitivity:")); + fileSystemCaseSensitivityLabel->setToolTip( + Tr::tr("Influences how file names are matched to decide if they are the same.")); grid.addRow({fileSystemCaseSensitivityLabel, m_fileSystemCaseSensitivityChooser}); } -- cgit v1.2.3 From 4a7f3db615b70b088a1aaeabbfbd4a145aff806d Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 14 Mar 2024 16:00:06 +0100 Subject: ToolChainOptionsPage: Don't leak QMenu Change-Id: I2d123b72a28f9aa9c566f0b186817c94e5ecacd3 Reviewed-by: Christian Kandeler --- src/plugins/projectexplorer/toolchainoptionspage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/projectexplorer/toolchainoptionspage.cpp b/src/plugins/projectexplorer/toolchainoptionspage.cpp index 470e64cf19..53b5267719 100644 --- a/src/plugins/projectexplorer/toolchainoptionspage.cpp +++ b/src/plugins/projectexplorer/toolchainoptionspage.cpp @@ -193,7 +193,7 @@ public: m_toolChainView->expandAll(); m_addButton = new QPushButton(Tr::tr("Add"), this); - auto addMenu = new QMenu; + auto addMenu = new QMenu(this); for (ToolchainFactory *factory : std::as_const(m_factories)) { QList languages = factory->supportedLanguages(); if (languages.isEmpty()) -- cgit v1.2.3 From f8cf71e4ba6adb6f25611f7412748b530a3d955b Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 14 Mar 2024 20:30:24 +0100 Subject: Help: Don't crash on shutdown when (un)registedDocumentationNow() Put the future into the future synchronizer. Otherwise, when (un)registedDocumentationNow() is still executed on shutdown we are destroying the locked mutex and crash. Change-Id: Ic8e7f8252719a3015101a0f5fc7b48ba57956562 Reviewed-by: Eike Ziller --- src/plugins/help/helpmanager.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/plugins/help/helpmanager.cpp b/src/plugins/help/helpmanager.cpp index 7ec80e700d..a117afd916 100644 --- a/src/plugins/help/helpmanager.cpp +++ b/src/plugins/help/helpmanager.cpp @@ -8,6 +8,8 @@ #include #include +#include + #include #include #include @@ -138,6 +140,7 @@ void HelpManager::registerDocumentation(const QStringList &files) } QFuture future = Utils::asyncRun(®isterDocumentationNow, collectionFilePath(), files); + ExtensionSystem::PluginManager::futureSynchronizer()->addFuture(future); Utils::onResultReady(future, this, [](bool docsChanged){ if (docsChanged) { d->m_helpEngine->setupData(); @@ -200,6 +203,7 @@ void HelpManager::unregisterDocumentation(const QStringList &files) d->m_userRegisteredFiles.subtract(Utils::toSet(files)); QFuture future = Utils::asyncRun(&unregisterDocumentationNow, collectionFilePath(), files); + ExtensionSystem::PluginManager::futureSynchronizer()->addFuture(future); Utils::onResultReady(future, this, [](bool docsChanged){ if (docsChanged) { d->m_helpEngine->setupData(); -- cgit v1.2.3 From 9606f81bc84cf061a96d9b4a5b444f35b13a0079 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Thu, 14 Mar 2024 12:40:44 +0100 Subject: ScreenRecorder: Fix "show dialog or settings" logic If the user selects "Record Screen" while the ffmpeg/ffprobe are not set, the ScreenRecorder settings are shown. The ScreenRecorder dialog did open up after the settings page, even if the user just pressed OK without setting the tools. With this change, not the settings page return value determines whether to show the ScreenRecorder dialog, but rather a second check if the tools are set/registered. Change-Id: I35b8f4e3afe7ea5e6834fcff74ce8f73d3a115b4 Reviewed-by: Reviewed-by: Christian Stenger --- src/plugins/screenrecorder/screenrecorderplugin.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/screenrecorder/screenrecorderplugin.cpp b/src/plugins/screenrecorder/screenrecorderplugin.cpp index 662e8cc24c..a816a276bc 100644 --- a/src/plugins/screenrecorder/screenrecorderplugin.cpp +++ b/src/plugins/screenrecorder/screenrecorderplugin.cpp @@ -135,9 +135,11 @@ public: private: void showDialogOrSettings() { - if (!Internal::settings().toolsRegistered() && - !Core::ICore::showOptionsDialog(Constants::TOOLSSETTINGSPAGE_ID)) { - return; + if (!Internal::settings().toolsRegistered()) { + // Show options if ffmpeg/ffprobe are neither autodetected nor manually set + Core::ICore::showOptionsDialog(Constants::TOOLSSETTINGSPAGE_ID); + if (!Internal::settings().toolsRegistered()) + return; // User did not set ffmpeg/ffprobe } ScreenRecorderDialog::showDialog(); -- cgit v1.2.3 From 720ab253b151408d7cdf298ed1b2a159b0ba52cc Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 11 Mar 2024 09:37:31 +0100 Subject: German translation: Debugger MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ib650492a2a1c5cc1e8e1dcf5fd87e0b638239a9d Reviewed-by: Robert Löhning Reviewed-by: Christian Stenger Reviewed-by: --- src/plugins/debugger/debuggerrunconfigurationaspect.cpp | 9 +++++++-- src/plugins/debugger/watchhandler.cpp | 4 +++- 2 files changed, 10 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp index cff934e398..bef91c5992 100644 --- a/src/plugins/debugger/debuggerrunconfigurationaspect.cpp +++ b/src/plugins/debugger/debuggerrunconfigurationaspect.cpp @@ -77,10 +77,15 @@ DebuggerRunConfigurationAspect::DebuggerRunConfigurationAspect(Target *target) const auto setSummaryText = [this, details] { const auto describe = [](const TriStateAspect &aspect, const QString &name) { - if (aspect() == TriState::Enabled) + if (aspect() == TriState::Enabled) { + //: %1 is C++, QML, or Python return Tr::tr("Enable %1 debugger.").arg(name); - if (aspect() == TriState::Disabled) + } + if (aspect() == TriState::Disabled) { + //: %1 is C++, QML, or Python return Tr::tr("Disable %1 debugger.").arg(name); + } + //: %1 is C++, QML, or Python return Tr::tr("Try to determine need for %1 debugger.").arg(name); }; diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 987122fcf2..0cc67f5416 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -959,8 +959,10 @@ static QString displayType(const WatchItem *item) result += QString(":%1").arg(item->bitsize); result.remove('\''); result = watchModel(item)->removeNamespaces(result); - if (item->valuelen > 0) + if (item->valuelen > 0) { + //: of length , e.g. for strings and byte arrays result = Tr::tr("%1 of length %2").arg(result).arg(item->valuelen); + } return result; } -- cgit v1.2.3 From 3d8d85b5b9d670c678a63360839b9c386a0c5c8c Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Mon, 18 Mar 2024 10:40:07 +0100 Subject: Terminal: Ignore "height = 0" resize events ConPTY on windows will send "clear line" characters in response to resizing the PTY. During re-showing the terminal pane the widget receives a "height=0" resize event. We have to ignore this otherwise the conpty might try to clear the screen. Another issue was that we are calling resize on the pty even thought the process has ended and won't be able to respond to the clear attempty by the pty anymore. Fixes: QTCREATORBUG-30523 Change-Id: I24caeaffb31d255a0640952e2d35bda23fd16280 Reviewed-by: Cristian Adam --- src/libs/solutions/terminal/terminalview.cpp | 5 ++++- src/plugins/terminal/terminalwidget.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/libs/solutions/terminal/terminalview.cpp b/src/libs/solutions/terminal/terminalview.cpp index 0cebe6d9b9..472346b3fc 100644 --- a/src/libs/solutions/terminal/terminalview.cpp +++ b/src/libs/solutions/terminal/terminalview.cpp @@ -958,11 +958,14 @@ void TerminalView::applySizeChange() }; if (newLiveSize.height() <= 0) - newLiveSize.setHeight(1); + return; if (newLiveSize.width() <= 0) newLiveSize.setWidth(1); + if (d->m_surface->liveSize() == newLiveSize) + return; + resizePty(newLiveSize); d->m_surface->resize(newLiveSize); flushVTerm(true); diff --git a/src/plugins/terminal/terminalwidget.cpp b/src/plugins/terminal/terminalwidget.cpp index 2bd0fa403d..756f1a11be 100644 --- a/src/plugins/terminal/terminalwidget.cpp +++ b/src/plugins/terminal/terminalwidget.cpp @@ -336,7 +336,7 @@ qint64 TerminalWidget::writeToPty(const QByteArray &data) void TerminalWidget::resizePty(QSize newSize) { - if (m_process && m_process->ptyData()) + if (m_process && m_process->ptyData() && m_process->isRunning()) m_process->ptyData()->resize(newSize); } -- cgit v1.2.3 From 2c598814bb53fa9a84be5e53ed4dd5ba5af9cb20 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Mon, 18 Mar 2024 12:37:52 +0100 Subject: CMakePM: Always set the comiplers from the CMake Preset probe In cases when a CMake project is using a CMake preset with a toolchain file, the CMAKE_C|XX_COMIPLER value was not set in the CMakeCache.txt. This commit makes sure that the cache from the CMake preset probe contains CMAKE_C|XX_COMPILER values. Task-number: QTCREATORBUG-30474 Change-Id: I63ac6fe2b043e49dda98e286b6d85950e34be920 Reviewed-by: Alessandro Portale --- src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index d16b35f1ef..33c8d66355 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -245,6 +245,8 @@ static CMakeConfig configurationFromPresetProbe( cmakeListTxt.writeFileContents(QByteArray("cmake_minimum_required(VERSION 3.15)\n" "\n" "project(preset-probe)\n" + "set(CMAKE_C_COMPILER \"${CMAKE_C_COMPILER}\" CACHE FILEPATH \"\" FORCE)\n" + "set(CMAKE_CXX_COMPILER \"${CMAKE_CXX_COMPILER}\" CACHE FILEPATH \"\" FORCE)\n" "\n")); Process cmake; -- cgit v1.2.3 From 6a78272ac81be7145f4862046afdd6c3f342234b Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 18 Mar 2024 11:48:25 +0100 Subject: Fix visibility of vulnerability warning for QML debugging The warning was not shown when opening a project with the QML debugging option enabled. The `changeHandler` was explicitly called at construction, but at this point the `warningLabel` doesn't have a parent. The `setVisible` call was skipped in this case, to prevent opening a toplevel window (for a short time) for it until it has a parent. Unfortunately there is no Qt API for setting the "visibility to the parent". Instead invert the logic: Let the label have default visibility to start with (which is "visible if the parent is visible"), and force it to hidden in `changeHandler` if necessary. Amends eda5fbd64575c0c268ba173e778a256a84484191 Change-Id: I69b86a967ee1fe7bd3d5d035765349981b64eb72 Reviewed-by: Qt CI Bot Reviewed-by: Christian Stenger --- src/plugins/qtsupport/qtbuildaspects.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/qtsupport/qtbuildaspects.cpp b/src/plugins/qtsupport/qtbuildaspects.cpp index e941dcb187..2f6ee19220 100644 --- a/src/plugins/qtsupport/qtbuildaspects.cpp +++ b/src/plugins/qtsupport/qtbuildaspects.cpp @@ -35,7 +35,6 @@ void QmlDebuggingAspect::addToLayout(Layouting::LayoutItem &parent) SelectionAspect::addToLayout(parent); const auto warningLabel = createSubWidget(QString(), InfoLabel::Warning); warningLabel->setElideMode(Qt::ElideNone); - warningLabel->setVisible(false); parent.addRow({{}, warningLabel}); const auto changeHandler = [this, warningLabel] { QString warningText; @@ -51,7 +50,9 @@ void QmlDebuggingAspect::addToLayout(Layouting::LayoutItem &parent) warningLabel->setText(warningText); setVisible(supported); const bool warningLabelsVisible = supported && !warningText.isEmpty(); - if (warningLabel->parentWidget()) + // avoid explicitly showing the widget when it doesn't have a parent, but always + // explicitly hide it when necessary + if (warningLabel->parentWidget() || !warningLabelsVisible) warningLabel->setVisible(warningLabelsVisible); }; connect(KitManager::instance(), &KitManager::kitsChanged, warningLabel, changeHandler); -- cgit v1.2.3 From d5e8f70192494859b36b5539ab063e2cc0fdd896 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 18 Mar 2024 19:36:43 +0100 Subject: VcsBaseClientImpl: Don't leak VcsCommand instances The running VcsCommand may leak on shutdown. Make them always a child of a guard object. Change-Id: Ie2d07d15cd13f1c08636bb1e9c5face09c6a782d Reviewed-by: Reviewed-by: Orgad Shaneh --- src/plugins/bazaar/bazaarplugin.cpp | 2 +- src/plugins/cvs/cvsplugin.cpp | 3 ++- src/plugins/fossil/fossilplugin.cpp | 2 +- src/plugins/git/gitplugin.cpp | 2 +- src/plugins/mercurial/mercurialplugin.cpp | 5 ++--- src/plugins/subversion/subversionplugin.cpp | 5 ++--- src/plugins/vcsbase/vcsbaseclient.cpp | 12 ++++++++++-- src/plugins/vcsbase/vcsbaseclient.h | 3 +++ src/plugins/vcsbase/vcscommand.h | 1 + 9 files changed, 23 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/plugins/bazaar/bazaarplugin.cpp b/src/plugins/bazaar/bazaarplugin.cpp index 9a75fbf3b3..590cfd2327 100644 --- a/src/plugins/bazaar/bazaarplugin.cpp +++ b/src/plugins/bazaar/bazaarplugin.cpp @@ -953,7 +953,7 @@ VcsCommand *BazaarPluginPrivate::createInitialCheckoutCommand(const QString &url Environment env = m_client.processEnvironment(baseDirectory); env.set("BZR_PROGRESS_BAR", "text"); - auto command = VcsBaseClient::createVcsCommand(baseDirectory, env); + auto command = VcsBaseClient::createVcsCommand(this, baseDirectory, env); command->addJob({m_client.vcsBinary(baseDirectory), args}, -1); return command; } diff --git a/src/plugins/cvs/cvsplugin.cpp b/src/plugins/cvs/cvsplugin.cpp index 2688def71e..01c47b1646 100644 --- a/src/plugins/cvs/cvsplugin.cpp +++ b/src/plugins/cvs/cvsplugin.cpp @@ -410,7 +410,8 @@ VcsCommand *CvsPluginPrivate::createInitialCheckoutCommand(const QString &url, QStringList args; args << QLatin1String("checkout") << url << extraArgs; - auto command = VcsBaseClient::createVcsCommand(baseDirectory, Environment::systemEnvironment()); + auto command = VcsBaseClient::createVcsCommand(this, baseDirectory, + Environment::systemEnvironment()); command->setDisplayName(Tr::tr("CVS Checkout")); command->addJob({settings().binaryPath(), settings().addOptions(args)}, -1); return command; diff --git a/src/plugins/fossil/fossilplugin.cpp b/src/plugins/fossil/fossilplugin.cpp index c4ea13b446..ff6fa0fa3f 100644 --- a/src/plugins/fossil/fossilplugin.cpp +++ b/src/plugins/fossil/fossilplugin.cpp @@ -927,7 +927,7 @@ VcsCommand *FossilPluginPrivate::createInitialCheckoutCommand(const QString &sou checkoutPath.createDir(); // Setup the wizard page command job - auto command = VcsBaseClient::createVcsCommand(checkoutPath, + auto command = VcsBaseClient::createVcsCommand(this, checkoutPath, fossilClient().processEnvironment(checkoutPath)); if (!isLocalRepository diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 966abc40b8..af5b267101 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -1769,7 +1769,7 @@ VcsCommand *GitPluginPrivate::createInitialCheckoutCommand(const QString &url, QStringList args = {"clone", "--progress"}; args << extraArgs << url << localName; - auto command = VcsBaseClient::createVcsCommand(baseDirectory, + auto command = VcsBaseClient::createVcsCommand(this, baseDirectory, gitClient().processEnvironment(baseDirectory)); command->addFlags(RunFlags::SuppressStdErr); command->addJob({gitClient().vcsBinary(baseDirectory), args}, -1); diff --git a/src/plugins/mercurial/mercurialplugin.cpp b/src/plugins/mercurial/mercurialplugin.cpp index a9ab891c02..f87d181da4 100644 --- a/src/plugins/mercurial/mercurialplugin.cpp +++ b/src/plugins/mercurial/mercurialplugin.cpp @@ -736,9 +736,8 @@ VcsCommand *MercurialPluginPrivate::createInitialCheckoutCommand(const QString & { QStringList args; args << QLatin1String("clone") << extraArgs << url << localName; - auto command = VcsBaseClient::createVcsCommand(baseDirectory, - mercurialClient().processEnvironment( - baseDirectory)); + auto command = VcsBaseClient::createVcsCommand(this, baseDirectory, + mercurialClient().processEnvironment(baseDirectory)); command->addJob({settings().binaryPath(), args}, -1); return command; } diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index 64f32a11ff..b28224a866 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -1135,9 +1135,8 @@ VcsCommand *SubversionPluginPrivate::createInitialCheckoutCommand(const QString args << SubversionClient::AddAuthOptions(); args << Subversion::Constants::NON_INTERACTIVE_OPTION << extraArgs << url << localName; - auto command = VcsBaseClient::createVcsCommand(baseDirectory, - subversionClient().processEnvironment( - baseDirectory)); + auto command = VcsBaseClient::createVcsCommand(this, baseDirectory, + subversionClient().processEnvironment(baseDirectory)); command->addJob(args, -1); return command; } diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp index 81a816c009..cd937ea345 100644 --- a/src/plugins/vcsbase/vcsbaseclient.cpp +++ b/src/plugins/vcsbase/vcsbaseclient.cpp @@ -6,7 +6,6 @@ #include "vcsbaseclientsettings.h" #include "vcsbaseeditor.h" #include "vcsbaseeditorconfig.h" -#include "vcsbaseplugin.h" #include "vcsbasetr.h" #include "vcscommand.h" #include "vcsoutputwindow.h" @@ -72,7 +71,8 @@ FilePath VcsBaseClientImpl::vcsBinary(const Utils::FilePath &forDirectory) const VcsCommand *VcsBaseClientImpl::createCommand(const FilePath &workingDirectory, VcsBaseEditorWidget *editor) const { - auto cmd = createVcsCommand(workingDirectory, processEnvironment(workingDirectory)); + auto cmd = createVcsCommand(const_cast(this), + workingDirectory, processEnvironment(workingDirectory)); if (editor) { editor->setCommand(cmd); connect(cmd, &VcsCommand::done, editor, [editor, cmd] { @@ -214,6 +214,14 @@ VcsCommand *VcsBaseClientImpl::createVcsCommand(const FilePath &defaultWorkingDi return new VcsCommand(defaultWorkingDir, environment); } +VcsCommand *VcsBaseClientImpl::createVcsCommand(QObject *parent, const FilePath &defaultWorkingDir, + const Environment &environment) +{ + auto command = new VcsCommand(defaultWorkingDir, environment); + command->setParent(parent); + return command; +} + VcsBaseEditorWidget *VcsBaseClientImpl::createVcsEditor(Id kind, QString title, const FilePath &source, QTextCodec *codec, const char *registerDynamicProperty, diff --git a/src/plugins/vcsbase/vcsbaseclient.h b/src/plugins/vcsbase/vcsbaseclient.h index 99b818b59b..6c07f74486 100644 --- a/src/plugins/vcsbase/vcsbaseclient.h +++ b/src/plugins/vcsbase/vcsbaseclient.h @@ -44,8 +44,11 @@ public: virtual Utils::FilePath vcsBinary(const Utils::FilePath &forDirectory) const; int vcsTimeoutS() const; + // TODO: For master: remove this overload. static VcsCommand *createVcsCommand(const Utils::FilePath &defaultWorkingDir, const Utils::Environment &environment); + static VcsCommand *createVcsCommand(QObject *parent, const Utils::FilePath &defaultWorkingDir, + const Utils::Environment &environment); VcsBaseEditorWidget *createVcsEditor(Utils::Id kind, QString title, const Utils::FilePath &source, QTextCodec *codec, diff --git a/src/plugins/vcsbase/vcscommand.h b/src/plugins/vcsbase/vcscommand.h index 6271139544..0556f25511 100644 --- a/src/plugins/vcsbase/vcscommand.h +++ b/src/plugins/vcsbase/vcscommand.h @@ -65,6 +65,7 @@ class VCSBASE_EXPORT VcsCommand final : public QObject Q_OBJECT public: + // TODO: For master, make c'tor private and make it a friend to VcsBaseClientImpl. VcsCommand(const Utils::FilePath &workingDirectory, const Utils::Environment &environment); ~VcsCommand() override; -- cgit v1.2.3 From c2b94568d916977d898b23257dac2de6df0519e2 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 13 Mar 2024 10:32:09 +0100 Subject: LinuxDeviceTester: Fix a crash on closing dialog when tryToConnect() Make a call to tryToConnect() a yet another task inside the task tree. Prolong the lifetime of the linux device until the tryToConnect() running in a separate thread is finished. This fixes a crash when canceling the test and closing the preferences dialog while tryToConnect() is still running. Amends e8ad29d3affd115573d7ee7a5621a6ca6e168911 Change-Id: I5aca6c9c3de0792421b9774faf45cd463854265e Reviewed-by: Qt CI Bot Reviewed-by: hjk --- src/plugins/remotelinux/linuxdevice.cpp | 9 +-- src/plugins/remotelinux/linuxdevice.h | 2 +- src/plugins/remotelinux/linuxdevicetester.cpp | 85 ++++++++++++--------------- 3 files changed, 43 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index b9fcbb265a..2fc49ca8e3 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -24,7 +24,6 @@ #include #include -#include #include #include #include @@ -1674,12 +1673,10 @@ void LinuxDevice::setDisconnected(bool disconnected) d->setDisconnected(disconnected); } -QFuture LinuxDevice::tryToConnect() +bool LinuxDevice::tryToConnect() { - return Utils::asyncRun([this] { - QMutexLocker locker(&d->m_shellMutex); - return d->setupShell(sshParameters(), false); - }); + QMutexLocker locker(&d->m_shellMutex); + return d->setupShell(sshParameters(), false); } namespace Internal { diff --git a/src/plugins/remotelinux/linuxdevice.h b/src/plugins/remotelinux/linuxdevice.h index 0bb2468eac..06e0da3f2a 100644 --- a/src/plugins/remotelinux/linuxdevice.h +++ b/src/plugins/remotelinux/linuxdevice.h @@ -50,7 +50,7 @@ public: bool isDisconnected() const; void setDisconnected(bool disconnected); - QFuture tryToConnect(); + bool tryToConnect(); protected: LinuxDevice(); diff --git a/src/plugins/remotelinux/linuxdevicetester.cpp b/src/plugins/remotelinux/linuxdevicetester.cpp index d66e44be6e..3281d32c49 100644 --- a/src/plugins/remotelinux/linuxdevicetester.cpp +++ b/src/plugins/remotelinux/linuxdevicetester.cpp @@ -6,6 +6,8 @@ #include "linuxdevice.h" #include "remotelinuxtr.h" +#include + #include #include #include @@ -13,13 +15,12 @@ #include #include +#include #include #include #include #include -#include - using namespace ProjectExplorer; using namespace Tasking; using namespace Utils; @@ -39,6 +40,7 @@ public: QStringList commandsToTest() const; + GroupItem connectionTask() const; GroupItem echoTask(const QString &contents) const; GroupItem unameTask() const; GroupItem gathererTask() const; @@ -46,13 +48,9 @@ public: const Storage &storage) const; GroupItem transferTasks() const; GroupItem commandTasks() const; - void runCommandTests(); - - bool isRunning() const { return m_connectionTest || m_taskTreeRunner.isRunning(); } GenericLinuxDeviceTester *q = nullptr; LinuxDevice::Ptr m_device; - QFutureWatcher *m_connectionTest = nullptr; TaskTreeRunner m_taskTreeRunner; QStringList m_extraCommands; QList m_extraTests; @@ -98,6 +96,27 @@ QStringList GenericLinuxDeviceTesterPrivate::commandsToTest() const return commands; } +GroupItem GenericLinuxDeviceTesterPrivate::connectionTask() const +{ + const auto onSetup = [this](Async &task) { + emit q->progressMessage(Tr::tr("Connecting to device...")); + task.setConcurrentCallData([device = m_device] { return device->tryToConnect(); }); + task.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); + }; + const auto onDone = [this](const Async &task) { + const bool success = task.isResultAvailable() && task.result(); + if (success) { + // TODO: For master: move the '\n' outside of Tr(). + emit q->progressMessage(Tr::tr("Connected. Now doing extended checks.\n")); + } else { + emit q->errorMessage( + Tr::tr("Basic connectivity test failed, device is considered unusable.") + '\n'); + } + return toDoneResult(success); + }; + return AsyncTask(onSetup, onDone); +} + GroupItem GenericLinuxDeviceTesterPrivate::echoTask(const QString &contents) const { const auto onSetup = [this, contents](Process &process) { @@ -283,20 +302,6 @@ GroupItem GenericLinuxDeviceTesterPrivate::commandTasks() const return root; } -void GenericLinuxDeviceTesterPrivate::runCommandTests() -{ - const Group root { - echoTask("Hello"), // No quoting necessary - echoTask("Hello Remote World!"), // Checks quoting, too. - unameTask(), - gathererTask(), - transferTasks(), - m_extraTests, - commandTasks() - }; - m_taskTreeRunner.start(root); -} - } // namespace Internal using namespace Internal; @@ -323,39 +328,27 @@ void GenericLinuxDeviceTester::setExtraTests(const QList &extraTests) void GenericLinuxDeviceTester::testDevice(const IDevice::Ptr &deviceConfiguration) { - QTC_ASSERT(!d->isRunning(), return); - - emit progressMessage(Tr::tr("Connecting to device...")); + QTC_ASSERT(!d->m_taskTreeRunner.isRunning(), return); d->m_device = std::static_pointer_cast(deviceConfiguration); - d->m_connectionTest = new QFutureWatcher(this); - connect(d->m_connectionTest, &QFutureWatcher::finished, this, [this] { - const bool success = d->m_connectionTest->result(); - d->m_connectionTest->deleteLater(); - d->m_connectionTest = nullptr; - if (success) { - emit progressMessage(Tr::tr("Connected. Now doing extended checks.\n")); - d->runCommandTests(); - } else { - emit errorMessage( - Tr::tr("Basic connectivity test failed, device is considered unusable.")); - emit finished(TestFailure); - } - }); - d->m_connectionTest->setFuture(d->m_device->tryToConnect()); + const Group root { + d->connectionTask(), + d->echoTask("Hello"), // No quoting necessary + d->echoTask("Hello Remote World!"), // Checks quoting, too. + d->unameTask(), + d->gathererTask(), + d->transferTasks(), + d->m_extraTests, + d->commandTasks() + }; + d->m_taskTreeRunner.start(root); } void GenericLinuxDeviceTester::stopTest() { - QTC_ASSERT(d->isRunning(), return); - if (d->m_connectionTest) { - d->m_connectionTest->disconnect(); - d->m_connectionTest->cancel(); - d->m_connectionTest = nullptr; - } else { - d->m_taskTreeRunner.reset(); - } + QTC_ASSERT(d->m_taskTreeRunner.isRunning(), return); + d->m_taskTreeRunner.reset(); emit finished(TestFailure); } -- cgit v1.2.3 From 1b408947b010c9d343530dcc759cb372c78ccc58 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Tue, 19 Mar 2024 15:16:00 +0100 Subject: Welcome: Design update round #2 User feedback was gathered and in part implemented in form of a design update. Smaller fonts, icons and gaps in the projects/sessions screen and in the examples tiles. Change-Id: I69d0d9ae21ba855feceeb77d620aa5b556377808 Reviewed-by: Cristian Adam --- src/plugins/coreplugin/welcomepagehelper.cpp | 4 +- src/plugins/projectexplorer/projectwelcomepage.cpp | 130 ++++++++++----------- src/plugins/welcome/images/project.png | Bin 175 -> 172 bytes src/plugins/welcome/images/project@2x.png | Bin 225 -> 212 bytes src/plugins/welcome/images/session.png | Bin 192 -> 165 bytes src/plugins/welcome/images/session@2x.png | Bin 255 -> 187 bytes src/tools/icons/qtcreatoricons.svg | 42 ++++--- 7 files changed, 93 insertions(+), 83 deletions(-) (limited to 'src') diff --git a/src/plugins/coreplugin/welcomepagehelper.cpp b/src/plugins/coreplugin/welcomepagehelper.cpp index 9cad69cdf1..fe01944a6f 100644 --- a/src/plugins/coreplugin/welcomepagehelper.cpp +++ b/src/plugins/coreplugin/welcomepagehelper.cpp @@ -752,8 +752,8 @@ bool ListModelFilter::leaveFilterAcceptsRowBeforeFiltering(const ListItem *, boo return false; } -constexpr TextFormat titleTF {Theme::Token_Text_Default, StyleHelper::UiElementIconActive}; -constexpr TextFormat descriptionTF {titleTF.themeColor, StyleHelper::UiElementCaption}; +constexpr TextFormat titleTF {Theme::Token_Text_Default, StyleHelper::UiElementH6}; +constexpr TextFormat descriptionTF {titleTF.themeColor, StyleHelper::UiElementCaptionStrong}; constexpr TextFormat tagsLabelTF {Theme::Token_Text_Muted, StyleHelper::UiElementCaptionStrong}; constexpr TextFormat tagsTF {Theme::Token_Text_Accent, tagsLabelTF.uiElement}; diff --git a/src/plugins/projectexplorer/projectwelcomepage.cpp b/src/plugins/projectexplorer/projectwelcomepage.cpp index e51800575d..2974225644 100644 --- a/src/plugins/projectexplorer/projectwelcomepage.cpp +++ b/src/plugins/projectexplorer/projectwelcomepage.cpp @@ -47,10 +47,11 @@ const char PROJECT_BASE_ID[] = "Welcome.OpenRecentProject"; namespace ProjectExplorer { namespace Internal { -constexpr TextFormat projectNameTF {Theme::Token_Text_Accent, StyleHelper::UiElementH5}; -constexpr TextFormat projectPathTF {Theme::Token_Text_Muted, StyleHelper::UiElementIconActive}; -constexpr TextFormat sessionNameTF {projectNameTF.themeColor, projectNameTF.uiElement}; -constexpr TextFormat sessionProjetNameTF {Theme::Token_Text_Default, projectNameTF.uiElement}; +constexpr TextFormat projectNameTF {Theme::Token_Text_Accent, StyleHelper::UiElementH6}; +constexpr TextFormat projectPathTF {Theme::Token_Text_Muted, StyleHelper::UiElementCaptionStrong}; +constexpr TextFormat sessionNameTF = {projectNameTF.themeColor, projectNameTF.uiElement, + Qt::AlignVCenter | Qt::TextDontClip}; +constexpr TextFormat sessionProjectNameTF {Theme::Token_Text_Default, projectNameTF.uiElement}; constexpr TextFormat shortcutNumberTF {Theme::Token_Text_Default, StyleHelper::UiElementCaptionStrong, Qt::AlignCenter | Qt::TextDontClip}; @@ -315,36 +316,36 @@ public: void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &idx) const final { - // visible on withIcon() Gap + arrow visible on hover Extra margin right of project item - // | | | - // +----------+----------+ +--------+-------+ +----------+----------+ - // | | | | | | + // visible on withIcon() Gap + arrow visible on hover Extra margin right of project item + // | | | + // +-----------+----------+ +--------+-------+ +----------+----------+ + // | | | | | | // - // +------------+--------+--------+------------+--------+-------------+--------+-------+------------+---------------------+ --+ - // | | | |(VPaddingXs)| |(VPaddingXs) | | | | | | - // | | | +------------+ +-------------+ | | | | | - // |(HPaddingXs)||(HGapXs)| |(HGapXs)||(HGapXs)|| | | +-- Header - // | |(16x16) | +------------+ +-------------+ | | | | | - // | | | |(VPaddingXs)| |(VPaddingXs) | | | | | | - // |------------+--------+--------+------------+--------+-------------+--------+-------+ | | --+ - // | +-- | (VPaddingXs) | | | | - // | | +------------------------------+(HPaddingXs)| | | - // | | | | | | | - // | | +------------------------------+ | | | - // | Per project in session --+ | (EXSPaddingGapS) | |(sessionScrollBarGap)| | - // | | +------------------------------+ | | | - // | | | | | | | - // | | +------------------------------+ | | +-- Expansion - // | +-- | (VPaddingXs) | | | | - // +----------------------------------------------+------------------------------------+------------+ | | - // | (VPaddingXs) | | | - // +----------------------------------------+--------------+----------------------------------------+ | | - // +-- | || | | | - // | +----------------------------------------+--------------+----------------------------------------+ | | - // | | (VPaddingXs) | | | - // | +------------------------------------------------------------------------------------------------+---------------------+ --+ - // | | (VGapL) | +-- Gap between session items - // | +----------------------------------------------------------------------------------------------------------------------+ --+ + // +------------+--------+---------+------------+---------+-------------+--------+-------+------------+---------------------+ --+ + // | | | |(VPaddingXs)| |(VPaddingXs) | | | | | | + // | | | +------------+ +-------------+ | | | | | + // |(HPaddingXs)||(HGapXxs)| |(HGapXxs)||(HGapXs)|| | | +-- Header + // | |(16x16) | +------------+ +-------------+ | | | | | + // | | | |(VPaddingXs)| |(VPaddingXs) | | | | | | + // |------------+--------+---------+------------+---------+-------------+--------+-------+ | | --+ + // | +-- | (VPaddingXxs) | | | | + // | | +------------------------------+(HPaddingXs)| | | + // | | | | | | | + // | | +------------------------------+ | | | + // | Per project in session --+ | (ExPaddingGapS) | |(sessionScrollBarGap)| | + // | | +------------------------------+ | | | + // | | | | | | | + // | | +------------------------------+ | | +-- Expansion + // | +-- | (VPaddingXxs) | | | | + // +------------------------------------------------------+------------------------------+------------+ | | + // | (VPaddingXs) | | | + // +-----------------------------------------+--------------+-----------------------------------------+ | | + // +-- | || | | | + // | +-----------------------------------------+--------------+-----------------------------------------+ | | + // | | (VPaddingXs) | | | + // | +--------------------------------------------------------------------------------------------------+---------------------+ --+ + // | | (VGapL) | +-- Gap between session items + // | +------------------------------------------------------------------------------------------------------------------------+ --+ // | // \ session action "buttons" and dividers // +-----------------------------------------------+--------+---------+--------+ @@ -380,11 +381,11 @@ public: const int y = bgR.y(); const int numberX = x + s(HPaddingXs); - const int iconX = numberX + shortcutNumberWidth + s(HGapXs); + const int iconX = numberX + shortcutNumberWidth + s(HGapXxs); const int arrowX = bgR.right() - s(HPaddingXs) - arrowS.width(); const QRect arrowHoverR(arrowX - s(HGapXs) + 1, y, s(HGapXs) + arrowS.width() + s(HPaddingXs), hdR.height()); - const int textX = withIcon() ? iconX + iconS.width() + s(HGapXs) : iconX; + const int textX = withIcon() ? iconX + iconS.width() + s(HGapXxs) : iconX; const int iconY = y + (hdR.height() - iconS.height()) / 2; const int arrowY = y + (hdR.height() - arrowS.height()) / 2; @@ -419,8 +420,7 @@ public: fullSessionName = Tr::tr("%1 (last session)").arg(fullSessionName); if (isActiveSession && !isDefaultVirgin) fullSessionName = Tr::tr("%1 (current session)").arg(fullSessionName); - const QRect switchR(x, y, hdR.width() - arrowHoverR.width(), - hdR.height() + s(VGapL)); + const QRect switchR(x, y, hdR.width() - arrowHoverR.width(), arrowHoverR.height()); const bool switchActive = switchR.contains(mousePos); painter->setPen(sessionNameTF.color()); painter->setFont(sessionNameTF.font(switchActive)); @@ -432,7 +432,7 @@ public: m_activeSwitchToRect = switchR; } if (arrowVisible) { - if (arrowHoverR.adjusted(0, 0, 0, s(VGapL)).contains(mousePos)) { + if (arrowHoverR.adjusted(0, 0, 0, expanded ? 0 : s(VGapL)).contains(mousePos)) { m_activeExpandRect = arrowHoverR; } else { painter->save(); @@ -447,9 +447,9 @@ public: int yy = hdR.bottom(); if (expanded) { - const QFont projectNameFont = sessionProjetNameTF.font(); + const QFont projectNameFont = sessionProjectNameTF.font(); const QFontMetrics projectNameFm(projectNameFont); - const int projectNameLineHeight = sessionProjetNameTF.lineHeight(); + const int projectNameLineHeight = sessionProjectNameTF.lineHeight(); const QFont projectPathFont = projectPathTF.font(); const QFontMetrics projectPathFm(projectPathFont); const int projectPathLineHeight = projectPathTF.lineHeight(); @@ -457,15 +457,15 @@ public: const FilePaths projects = ProjectManager::projectsForSessionName(sessionName); for (const FilePath &projectPath : projects) { - yy += s(VPaddingXs); + yy += s(VPaddingXxs); { painter->setFont(projectNameFont); - painter->setPen(sessionProjetNameTF.color()); + painter->setPen(sessionProjectNameTF.color()); const QRect projectNameR(textX, yy, textWidth, projectNameLineHeight); const QString projectNameElided = projectNameFm.elidedText(projectPath.completeBaseName(), Qt::ElideMiddle, textWidth); - painter->drawText(projectNameR, sessionProjetNameTF.drawTextFlags, + painter->drawText(projectNameR, sessionProjectNameTF.drawTextFlags, projectNameElided); yy += projectNameLineHeight; yy += s(ExPaddingGapS); @@ -483,7 +483,7 @@ public: projectPathElided); yy += projectPathLineHeight; } - yy += s(VPaddingXs); + yy += s(VPaddingXxs); } yy += s(VGapXs); @@ -551,11 +551,11 @@ public: const QString sessionName = idx.data(Qt::DisplayRole).toString(); const FilePaths projects = ProjectManager::projectsForSessionName(sessionName); const int projectEntryHeight = - s(VPaddingXs) + s(VPaddingXxs) + projectNameTF.lineHeight() + s(ExPaddingGapS) + projectPathTF.lineHeight() - + s(VPaddingXs); + + s(VPaddingXxs); h += projects.size() * projectEntryHeight + s(VGapXs) + actionButtonHeight() @@ -622,24 +622,24 @@ class ProjectDelegate : public BaseDelegate public: void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &idx) const final { - // visible on withIcon() Extra margin right of project item - // | | - // +-------+-------+ +------+-----+ - // | | | | + // visible on with Icon() Extra margin right of project item + // | | + // +--------+-------+ +------+-----+ + // | | | | // - // +------------+--------+--------+------+--------+-------------+------------+------------+ - // | | | | | | (VPaddingXs)| | | - // | | | | | +-------------+ | | - // | | | | | || | | - // | | | | | +-------------+ | | - // |(HPaddingXs)||(HGapXs)||(HGapXs)| (VGapXs) |(HPaddingXs)|(HPaddingXs)| - // | |(16x16) | | | +-------------+ | | - // | | | | | || | | - // | | | | | +-------------+ | | - // | | | | | | (VPaddingXs)| | | - // +------------+--------+--------+------+--------+-------------+------------+------------+ --+ - // | (VGapL) | +-- Gap between project items - // +--------------------------------------------------------------------------------------+ --+ + // +------------+--------+---------+------+---------+-------------+------------+------------+ + // | | | | | | (VPaddingXs)| | | + // | | | | | +-------------+ | | + // | | | | | || | | + // | | | | | +-------------+ | | + // |(HPaddingXs)||(HGapXxs)||(HGapXxs)| (VGapXs) |(HPaddingXs)|(HPaddingXs)| + // | |(16x16) | | | +-------------+ | | + // | | | | | || | | + // | | | | | +-------------+ | | + // | | | | | | (VPaddingXs)| | | + // +------------+--------+---------+------+---------+-------------+------------+------------+ --+ + // | (VGapL) | +-- Gap between project items + // +----------------------------------------------------------------------------------------+ --+ const bool hovered = option.widget->isActiveWindow() && option.state & QStyle::State_MouseOver; @@ -651,9 +651,9 @@ public: const int x = bgR.x(); const int numberX = x + s(HPaddingXs); - const int iconX = numberX + shortcutNumberWidth + s(HGapXs); + const int iconX = numberX + shortcutNumberWidth + s(HGapXxs); const int iconWidth = iconS.width(); - const int textX = withIcon() ? iconX + iconWidth + s(HGapXs) : iconX; + const int textX = withIcon() ? iconX + iconWidth + s(HGapXxs) : iconX; const int textWidth = bgR.width() - s(HPaddingXs) - textX; const int y = bgR.y(); diff --git a/src/plugins/welcome/images/project.png b/src/plugins/welcome/images/project.png index 30862beb28..522902a48f 100644 Binary files a/src/plugins/welcome/images/project.png and b/src/plugins/welcome/images/project.png differ diff --git a/src/plugins/welcome/images/project@2x.png b/src/plugins/welcome/images/project@2x.png index c5cc11155b..8be7cc7c87 100644 Binary files a/src/plugins/welcome/images/project@2x.png and b/src/plugins/welcome/images/project@2x.png differ diff --git a/src/plugins/welcome/images/session.png b/src/plugins/welcome/images/session.png index aa14f11de8..ae77dc51a8 100644 Binary files a/src/plugins/welcome/images/session.png and b/src/plugins/welcome/images/session.png differ diff --git a/src/plugins/welcome/images/session@2x.png b/src/plugins/welcome/images/session@2x.png index c53cf12bfa..5f0701b711 100644 Binary files a/src/plugins/welcome/images/session@2x.png and b/src/plugins/welcome/images/session@2x.png differ diff --git a/src/tools/icons/qtcreatoricons.svg b/src/tools/icons/qtcreatoricons.svg index 9ced69d319..7d78434c75 100644 --- a/src/tools/icons/qtcreatoricons.svg +++ b/src/tools/icons/qtcreatoricons.svg @@ -7030,36 +7030,42 @@ style="fill:none;stroke:#000000;stroke-width:1.42;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + transform="translate(226,-226)" + width="100%" + height="100%" /> + d="m 216,215 5,3 -5,3 z m -4,-3 h 12 v 12 h -12 z" + sodipodi:nodetypes="ccccccccc" /> + transform="translate(25,-430)" + width="100%" + height="100%" /> + d="m 13,9 h 2.5 c 1,0 1,2 2,2 H 21 c 1,0 2,1 2,2 v 4 c 0,1 -1,2 -2,2 h -8 c -1,0 -2,-1 -2,-2 v -6 c 0,-1 1,-2 2,-2 z" + stroke-width="2" + id="path4726" + sodipodi:nodetypes="sccssssssss" + style="fill:none;stroke:#000000;stroke-opacity:1" /> + transform="translate(172,-228)" + width="100%" + height="100%" /> + transform="translate(22,-430)" + width="100%" + height="100%" /> Date: Wed, 20 Mar 2024 11:14:14 +0100 Subject: Doc: Adapt withTimeout() to the recent changes Change-Id: I6abd9515735c8197411081f04618eb09c7b28069 Reviewed-by: Reviewed-by: Leena Miettinen --- src/libs/solutions/tasking/tasktree.cpp | 31 ++++++++----------------------- 1 file changed, 8 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index c6e87d2774..9e28baab57 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -547,18 +547,6 @@ private: \endcode */ -/*! - \fn GroupItem Group::withTimeout(std::chrono::milliseconds timeout, const std::function &handler) const - - Attaches \c TimeoutTask to a copy of \c this group, elapsing after \a timeout in milliseconds, - with an optionally provided timeout \a handler, and returns the coupled item. - - When the group finishes before \a timeout passes, - the returned item finishes immediately with the group's result. - Otherwise, the \a handler is invoked (if provided), the group's tasks are canceled, - and the returned item finishes with an error. -*/ - /*! \class Tasking::Sync \inheaderfile solutions/tasking/tasktree.h @@ -758,17 +746,6 @@ private: \sa TaskSetupHandler, TaskDoneHandler */ -/*! - \fn template GroupItem CustomTask::withTimeout(std::chrono::milliseconds timeout, const std::function &handler) const - - Attaches \c TimeoutTask to a copy of \c this task, elapsing after \a timeout in milliseconds, - with an optionally provided timeout \a handler, and returns the coupled item. - - When the task finishes before \a timeout passes, the returned item finishes immediately - with the task's result. Otherwise, \a handler is invoked (if provided), - the task is canceled, and the returned item finishes with an error. -*/ - /*! \enum Tasking::WorkflowPolicy @@ -1415,6 +1392,14 @@ void GroupItem::addChildren(const QList &children) } } +/*! + Attaches \c TimeoutTask to a copy of \c this ExecutableItem, elapsing after \a timeout + in milliseconds, with an optionally provided timeout \a handler, and returns the coupled item. + + When the ExecutableItem finishes before \a timeout passes, the returned item finishes + immediately with the task's result. Otherwise, \a handler is invoked (if provided), + the task is canceled, and the returned item finishes with an error. +*/ ExecutableItem ExecutableItem::withTimeout(milliseconds timeout, const std::function &handler) const { -- cgit v1.2.3 From 7e0b7b8eb14c8bd093481effac31b8d3f45b4c47 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 19 Mar 2024 17:42:13 +0100 Subject: Update qbs submodule to HEAD of 2.3 branch Change-Id: Ib87697ebccf92f38c1ea30a1e56282b029840aae Reviewed-by: Qt CI Bot Reviewed-by: Christian Stenger Reviewed-by: --- src/shared/qbs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/shared/qbs b/src/shared/qbs index 44d658cbf4..5c88b6b11b 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit 44d658cbf479a597ba22bb661c8ca68d7a98be6d +Subproject commit 5c88b6b11b762cf5861c9d1570df4f1f050c826e -- cgit v1.2.3 From ab9f394138934c4cb581ca6f31a90e3cc3ad715a Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 20 Mar 2024 14:47:16 +0100 Subject: Doc: Describe shortly ExecutableItem class Change-Id: Ib146d1c99e51c56ca46172d293d00392f05ddd46 Reviewed-by: Leena Miettinen --- src/libs/solutions/tasking/tasktree.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src') diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 9e28baab57..e74d165b29 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -1392,6 +1392,18 @@ void GroupItem::addChildren(const QList &children) } } +/*! + \class Tasking::ExecutableItem + \inheaderfile solutions/tasking/tasktree.h + \inmodule TaskingSolution + \brief Base class for executable task items. + \reentrant + + \c ExecutableItem provides an additional interface for items containing executable tasks. + Use withTimeout() to attach a timeout to a task. + Use withLog() to include debugging information about the task startup and the execution result. +*/ + /*! Attaches \c TimeoutTask to a copy of \c this ExecutableItem, elapsing after \a timeout in milliseconds, with an optionally provided timeout \a handler, and returns the coupled item. -- cgit v1.2.3 From 1be9f9cdc7c2ea7ec45a8667b290cdd6822a2b1b Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 20 Mar 2024 15:17:02 +0100 Subject: Doc: Add docs for ExecutableItem::withLog() Change-Id: I105a106139f1a658e5feed022e224e4e933dbcc1 Reviewed-by: Leena Miettinen --- src/libs/solutions/tasking/tasktree.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src') diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index e74d165b29..7d37bf9758 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -1430,6 +1430,17 @@ ExecutableItem ExecutableItem::withTimeout(milliseconds timeout, static QString currentTime() { return QTime::currentTime().toString(Qt::ISODateWithMs); } +/*! + Attaches a custom debug printout to a copy of \c this ExecutableItem, + issued on task startup and after the task is finished, and returns the coupled item. + + The debug printout includes a timestamp of the event (start or finish) + and \a logName to identify the specific task in the debug log. + + The finish printout contains the additional information whether the execution was + synchronous or asynchronous, its result (the value described by the DoneWith enum), + and the total execution time in milliseconds. +*/ ExecutableItem ExecutableItem::withLog(const QString &logName) const { const auto header = [logName] { -- cgit v1.2.3 From 1f0afcaa7684afcd9ce1be48ef3a95b611e35bfd Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 20 Mar 2024 13:51:50 +0100 Subject: Qmake: Do not warn if build directory is child of source dir We changed the default build directory to be in a "build" subdirectory of the source directory, which should not trigger this warning. Fixes: QTCREATORBUG-30562 Change-Id: Ie9e6906602844fa08c187b92423839484a1cea92 Reviewed-by: Christian Kandeler --- src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp index f3a71728d0..496ddb76c1 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp @@ -372,7 +372,8 @@ QString QmakeBuildConfiguration::unalignedBuildDirWarning() bool QmakeBuildConfiguration::isBuildDirAtSafeLocation(const FilePath &sourceDir, const FilePath &buildDir) { - return buildDir.path().count('/') == sourceDir.path().count('/'); + return buildDir.path().count('/') == sourceDir.path().count('/') + || buildDir.isChildOf(sourceDir); } bool QmakeBuildConfiguration::isBuildDirAtSafeLocation() const -- cgit v1.2.3 From 5afdc477606bf8d92ac2b21724e81f6f0dcb0905 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 18 Mar 2024 16:58:32 +0100 Subject: LanguageClient: Prevent duplicate references due to file aliasing This problem has been observed with clangd, but it's probably a good idea to apply the check generally. Note that in the case of renaming, omitting the filtering can lead to file corruption. Task-number: QTCREATORBUG-30546 Change-Id: I007edbae2cba5f59e427ab07e183162df9e99367 Reviewed-by: David Schulz --- .../clangcodemodel/clangdfindreferences.cpp | 5 ++++ .../languageclient/languageclientsymbolsupport.cpp | 28 +++++++++++++++++++--- 2 files changed, 30 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/clangcodemodel/clangdfindreferences.cpp b/src/plugins/clangcodemodel/clangdfindreferences.cpp index b7e62d6e05..13968801e7 100644 --- a/src/plugins/clangcodemodel/clangdfindreferences.cpp +++ b/src/plugins/clangcodemodel/clangdfindreferences.cpp @@ -291,12 +291,17 @@ void ClangdFindReferences::Private::handleFindUsagesResult(const QList for (const Location &loc : locations) fileData[loc.uri()].rangesAndLineText.push_back({loc.range(), {}}); + QSet canonicalFilePaths; for (auto it = fileData.begin(); it != fileData.end();) { const Utils::FilePath filePath = client()->serverUriToHostPath(it.key()); if (!filePath.exists()) { // https://github.com/clangd/clangd/issues/935 it = fileData.erase(it); continue; } + if (!Utils::insert(canonicalFilePaths, filePath.canonicalPath())) { // QTCREATORBUG-30546 + it = fileData.erase(it); + continue; + } const QStringList lines = SymbolSupport::getFileContents(filePath); it->fileContent = lines.join('\n'); for (auto &rangeWithText : it.value().rangesAndLineText) { diff --git a/src/plugins/languageclient/languageclientsymbolsupport.cpp b/src/plugins/languageclient/languageclientsymbolsupport.cpp index e9c4443eed..3a9a1b0970 100644 --- a/src/plugins/languageclient/languageclientsymbolsupport.cpp +++ b/src/plugins/languageclient/languageclientsymbolsupport.cpp @@ -274,6 +274,10 @@ struct ItemData Utils::Text::Range range; QVariant userData; }; +bool operator==(const ItemData &id1, const ItemData &id2) +{ + return id1.range == id2.range && id1.userData == id2.userData; +} QStringList SymbolSupport::getFileContents(const Utils::FilePath &filePath) { @@ -342,15 +346,32 @@ Utils::SearchResultItems generateSearchResultItems( return result; } +using ItemDataPerPath = QMap>; +void filterFileAliases(ItemDataPerPath &itemDataPerPath) +{ + QSet canonicalPaths; + for (auto it = itemDataPerPath.begin(); it != itemDataPerPath.end(); ) { + const Utils::FilePath canonicalPath = it.key().canonicalPath(); + if (!Utils::insert(canonicalPaths, canonicalPath) + && it.value() == itemDataPerPath.value(canonicalPath)) { // QTCREATORBUG-30546 + it = itemDataPerPath.erase(it); + } else { + ++it; + } + } +} + Utils::SearchResultItems generateSearchResultItems( const LanguageClientArray &locations, const DocumentUri::PathMapper &pathMapper) { if (locations.isNull()) return {}; - QMap> rangesInDocument; - for (const Location &location : locations.toList()) + ItemDataPerPath rangesInDocument; + for (const Location &location : locations.toList()) { rangesInDocument[location.uri().toFilePath(pathMapper)] << ItemData{SymbolSupport::convertRange(location.range()), {}}; + } + filterFileAliases(rangesInDocument); return generateSearchResultItems(rangesInDocument); } @@ -552,7 +573,7 @@ Utils::SearchResultItems generateReplaceItems(const WorkspaceEdit &edits, return ItemData{SymbolSupport::convertRange(edit.range()), QVariant(edit)}; }); }; - QMap> rangesInDocument; + ItemDataPerPath rangesInDocument; auto documentChanges = edits.documentChanges().value_or(QList()); if (!documentChanges.isEmpty()) { for (const DocumentChange &documentChange : std::as_const(documentChanges)) { @@ -588,6 +609,7 @@ Utils::SearchResultItems generateReplaceItems(const WorkspaceEdit &edits, for (auto it = changes.begin(), end = changes.end(); it != end; ++it) rangesInDocument[it.key().toFilePath(pathMapper)] = convertEdits(it.value()); } + filterFileAliases(rangesInDocument); items += generateSearchResultItems(rangesInDocument, search, limitToProjects); return items; } -- cgit v1.2.3 From c10b34c1e104415fbb62483ea31a034e69dfcd36 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 19 Mar 2024 14:04:55 +0100 Subject: Axivion: Reuse the redirected url for further usage Do it even when the network reply fails, but contains the valid json content. Fixes: QTCREATORBUG-30536 Change-Id: I97f55ccf6997cd2c9ac6be72d673d9cee1a210de Reviewed-by: Reviewed-by: Christian Stenger --- src/plugins/axivion/axivionplugin.cpp | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/plugins/axivion/axivionplugin.cpp b/src/plugins/axivion/axivionplugin.cpp index f0f90d3f25..fa455c07eb 100644 --- a/src/plugins/axivion/axivionplugin.cpp +++ b/src/plugins/axivion/axivionplugin.cpp @@ -450,8 +450,10 @@ static Group dtoRecipe(const Storage> &dtoStorage) if (error) { if constexpr (std::is_same_v) { // Suppress logging error on unauthorized dashboard fetch - if (!dtoStorage->credential && error->type == "UnauthenticatedException") + if (!dtoStorage->credential && error->type == "UnauthenticatedException") { + dtoStorage->url = reply->url(); return DoneResult::Success; + } } errorString = Error(DashboardError(reply->url(), statusCode, @@ -530,13 +532,11 @@ static void handleCredentialError(const CredentialQuery &credential) static Group authorizationRecipe() { + const Storage serverUrlStorage; const Storage> unauthorizedDashboardStorage; - const auto onUnauthorizedGroupSetup = [unauthorizedDashboardStorage] { - if (isServerAccessEstablished()) - return SetupResult::StopWithSuccess; - - unauthorizedDashboardStorage->url = QUrl(settings().server.dashboard); - return SetupResult::Continue; + const auto onUnauthorizedGroupSetup = [serverUrlStorage, unauthorizedDashboardStorage] { + unauthorizedDashboardStorage->url = *serverUrlStorage; + return isServerAccessEstablished() ? SetupResult::StopWithSuccess : SetupResult::Continue; }; const auto onUnauthorizedDashboard = [unauthorizedDashboardStorage] { if (unauthorizedDashboardStorage->dtoData) { @@ -575,7 +575,7 @@ static Group authorizationRecipe() const Storage passwordStorage; const Storage> dashboardStorage; - const auto onPasswordGroupSetup = [passwordStorage, dashboardStorage] { + const auto onPasswordGroupSetup = [serverUrlStorage, passwordStorage, dashboardStorage] { if (dd->m_apiToken) return SetupResult::StopWithSuccess; @@ -589,7 +589,7 @@ static Group authorizationRecipe() const QString credential = settings().server.username + ':' + *passwordStorage; dashboardStorage->credential = "Basic " + credential.toUtf8().toBase64(); - dashboardStorage->url = QUrl(settings().server.dashboard); + dashboardStorage->url = *serverUrlStorage; return SetupResult::Continue; }; @@ -632,13 +632,13 @@ static Group authorizationRecipe() return DoneResult::Success; }; - const auto onDashboardGroupSetup = [dashboardStorage] { + const auto onDashboardGroupSetup = [serverUrlStorage, dashboardStorage] { if (dd->m_dashboardInfo || dd->m_serverAccess != ServerAccess::WithAuthorization || !dd->m_apiToken) { return SetupResult::StopWithSuccess; // Unauthorized access should have collect dashboard before } dashboardStorage->credential = "AxToken " + *dd->m_apiToken; - dashboardStorage->url = QUrl(settings().server.dashboard); + dashboardStorage->url = *serverUrlStorage; return SetupResult::Continue; }; const auto onDeleteCredentialSetup = [dashboardStorage](CredentialQuery &credential) { @@ -656,11 +656,16 @@ static Group authorizationRecipe() }; return { + serverUrlStorage, + onGroupSetup([serverUrlStorage] { *serverUrlStorage = QUrl(settings().server.dashboard); }), Group { unauthorizedDashboardStorage, onGroupSetup(onUnauthorizedGroupSetup), dtoRecipe(unauthorizedDashboardStorage), - Sync(onUnauthorizedDashboard) + Sync(onUnauthorizedDashboard), + onGroupDone([serverUrlStorage, unauthorizedDashboardStorage] { + *serverUrlStorage = unauthorizedDashboardStorage->url; + }), }, Group { LoopUntil(onCredentialLoopCondition), -- cgit v1.2.3 From 36a00855bb7236be8c4fb1199bb03d8c6603dc80 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 21 Mar 2024 15:02:33 +0100 Subject: Axivion: Fix reaction on setting changes While refactoring the signal got lost, bring it back. Change-Id: I6b7d2764a5acc390c189b8d0000adc74ee2a4a9c Reviewed-by: Jarek Kobus --- src/plugins/axivion/axivionsettings.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/plugins/axivion/axivionsettings.cpp b/src/plugins/axivion/axivionsettings.cpp index 9b24fa51f0..2af22e7cb9 100644 --- a/src/plugins/axivion/axivionsettings.cpp +++ b/src/plugins/axivion/axivionsettings.cpp @@ -261,6 +261,7 @@ AxivionSettingsWidget::AxivionSettingsWidget() void AxivionSettingsWidget::apply() { settings().server = m_dashboardDisplay->dashboardServer(); + emit settings().changed(); // ugly but needed settings().toSettings(); } -- cgit v1.2.3 From 551d5e1b0990ec26a4c76f6d5c50ca3981a78519 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Fri, 22 Mar 2024 08:05:53 +0100 Subject: Axivion: Provide find support on project list If the list of projects is long it is hard to get to the right project. Make it a bit easier. Change-Id: Ifb56bda163ea9450831682c4ea4ccc1a2cb8ffd4 Reviewed-by: Eike Ziller --- src/plugins/axivion/axivionprojectsettings.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/axivion/axivionprojectsettings.cpp b/src/plugins/axivion/axivionprojectsettings.cpp index 8cd63ba7ac..023c251ea4 100644 --- a/src/plugins/axivion/axivionprojectsettings.cpp +++ b/src/plugins/axivion/axivionprojectsettings.cpp @@ -7,6 +7,8 @@ #include "axivionsettings.h" #include "axiviontr.h" +#include + #include #include #include @@ -141,7 +143,7 @@ AxivionProjectSettingsWidget::AxivionProjectSettingsWidget(Project *project) noMargin, m_linkedProject, Tr::tr("Dashboard projects:"), - m_dashboardProjects, + Core::ItemViewFind::createSearchableWrapper(m_dashboardProjects), m_infoLabel, Row { m_fetchProjects, m_link, m_unlink, st } }.attachTo(this); -- cgit v1.2.3 From 34eeda4b0572b127cbcdb842368dae06b7e30422 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Fri, 22 Mar 2024 08:07:49 +0100 Subject: Axivion: Ensure buttons are exclusive Avoid having none of the buttons selected which looks confusing. Change-Id: I445c4da970c4dfbd8a35228e31092c788d0b5d37 Reviewed-by: Eike Ziller --- src/plugins/axivion/axivionoutputpane.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/plugins/axivion/axivionoutputpane.cpp b/src/plugins/axivion/axivionoutputpane.cpp index d1c896205f..79c90936cf 100644 --- a/src/plugins/axivion/axivionoutputpane.cpp +++ b/src/plugins/axivion/axivionoutputpane.cpp @@ -736,6 +736,10 @@ public: if (auto issues = static_cast(m_outputWidget->widget(1))) issues->updateUi(); }); + auto *butonGroup = new QButtonGroup(this); + butonGroup->addButton(m_showDashboard); + butonGroup->addButton(m_showIssues); + butonGroup->setExclusive(true); connect(m_outputWidget, &QStackedWidget::currentChanged, this, [this](int idx) { m_showDashboard->setChecked(idx == 0); -- cgit v1.2.3 From 99aed851ef8abdccb3c13686db61f644a51fe44c Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Fri, 22 Mar 2024 11:26:04 +0100 Subject: Axivion: Improve path mapping If the linked project is not the top level project our path mappings did not work. Try to get the correct file path by using QC internal find functionality. This helps for opening files by activating issues inside the issues table or when clicking links of the issue details. Unfortunately this does not help for the inline annotations or respective marks. Change-Id: Ie34e1b20ff8b1b2b37e9f04c1d41bc2a4c33f260 Reviewed-by: Eike Ziller --- src/plugins/axivion/axivionoutputpane.cpp | 2 +- src/plugins/axivion/axivionplugin.cpp | 24 +++++++++++++++++++++--- src/plugins/axivion/axivionplugin.h | 2 ++ 3 files changed, 24 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/plugins/axivion/axivionoutputpane.cpp b/src/plugins/axivion/axivionoutputpane.cpp index 79c90936cf..d66468590b 100644 --- a/src/plugins/axivion/axivionoutputpane.cpp +++ b/src/plugins/axivion/axivionoutputpane.cpp @@ -235,7 +235,7 @@ public: }).link; Project *project = ProjectManager::startupProject(); FilePath baseDir = project ? project->projectDirectory() : FilePath{}; - link.targetFilePath = baseDir.resolvePath(link.targetFilePath); + link.targetFilePath = findFileForIssuePath(link.targetFilePath); if (link.targetFilePath.exists()) EditorManager::openEditorAt(link); } diff --git a/src/plugins/axivion/axivionplugin.cpp b/src/plugins/axivion/axivionplugin.cpp index fa455c07eb..0f4686e403 100644 --- a/src/plugins/axivion/axivionplugin.cpp +++ b/src/plugins/axivion/axivionplugin.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -236,6 +237,7 @@ public: TaskTreeRunner m_taskTreeRunner; std::unordered_map> m_docMarksTrees; TaskTreeRunner m_issueInfoRunner; + FileInProjectFinder m_fileFinder; // FIXME maybe obsolete when path mapping is implemented }; static AxivionPluginPrivate *dd = nullptr; @@ -337,10 +339,17 @@ void AxivionPluginPrivate::onStartupProjectChanged(Project *project) m_currentProjectInfo = {}; updateDashboard(); - if (!m_project) + if (!m_project) { + m_fileFinder.setProjectDirectory({}); + m_fileFinder.setProjectFiles({}); return; + } - connect(m_project, &Project::fileListChanged, this, &AxivionPluginPrivate::handleOpenedDocs); + m_fileFinder.setProjectDirectory(m_project->projectDirectory()); + connect(m_project, &Project::fileListChanged, this, [this]{ + m_fileFinder.setProjectFiles(m_project->files(Project::AllFiles)); + handleOpenedDocs(); + }); const AxivionProjectSettings *projSettings = AxivionProjectSettings::projectSettings(m_project); fetchProjectInfo(projSettings->dashboardProjectName()); } @@ -961,7 +970,7 @@ void AxivionPluginPrivate::handleAnchorClicked(const QUrl &url) return; Link link; if (const QString path = query.queryItemValue("filename", QUrl::FullyDecoded); !path.isEmpty()) - link.targetFilePath = m_project->projectDirectory().pathAppended(path); + link.targetFilePath = findFileForIssuePath(FilePath::fromUserInput(path)); if (const QString line = query.queryItemValue("line"); !line.isEmpty()) link.targetLine = line.toInt(); // column entry is wrong - so, ignore it @@ -1040,6 +1049,15 @@ const std::optional currentDashboardInfo() return dd->m_dashboardInfo; } +Utils::FilePath findFileForIssuePath(const Utils::FilePath &issuePath) +{ + QTC_ASSERT(dd, return {}); + const FilePaths result = dd->m_fileFinder.findFile(QUrl::fromLocalFile(issuePath.toString())); + if (result.size() == 1) + return dd->m_project->projectDirectory().resolvePath(result.first()); + return {}; +} + } // Axivion::Internal #include "axivionplugin.moc" diff --git a/src/plugins/axivion/axivionplugin.h b/src/plugins/axivion/axivionplugin.h index db2f8494cb..059e950ecc 100644 --- a/src/plugins/axivion/axivionplugin.h +++ b/src/plugins/axivion/axivionplugin.h @@ -79,5 +79,7 @@ void fetchIssueInfo(const QString &id); const std::optional currentDashboardInfo(); +Utils::FilePath findFileForIssuePath(const Utils::FilePath &issuePath); + } // Axivion::Internal -- cgit v1.2.3