From 58972890cc773827ec0e3be7f61f42b05d2bee2f Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 29 Sep 2023 10:53:11 +0200 Subject: [PATCH 0001/1546] Bump version to 13.0.0-beta1 Change-Id: Ibdf1ae2189f5dea88e2a02fccf551e3ed159bb02 Reviewed-by: David Schulz --- cmake/QtCreatorIDEBranding.cmake | 6 +++--- qbs/modules/qtc/qtc.qbs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cmake/QtCreatorIDEBranding.cmake b/cmake/QtCreatorIDEBranding.cmake index e5ef7a4b73d..5978c525128 100644 --- a/cmake/QtCreatorIDEBranding.cmake +++ b/cmake/QtCreatorIDEBranding.cmake @@ -1,6 +1,6 @@ -set(IDE_VERSION "11.0.82") # The IDE version. -set(IDE_VERSION_COMPAT "11.0.82") # The IDE Compatibility version. -set(IDE_VERSION_DISPLAY "12.0.0-beta1") # The IDE display version. +set(IDE_VERSION "12.0.82") # The IDE version. +set(IDE_VERSION_COMPAT "12.0.82") # The IDE Compatibility version. +set(IDE_VERSION_DISPLAY "13.0.0-beta1") # The IDE display version. set(IDE_COPYRIGHT_YEAR "2023") # The IDE current copyright year. set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation. diff --git a/qbs/modules/qtc/qtc.qbs b/qbs/modules/qtc/qtc.qbs index eca67fc9d55..1fe9fe91354 100644 --- a/qbs/modules/qtc/qtc.qbs +++ b/qbs/modules/qtc/qtc.qbs @@ -4,14 +4,14 @@ import qbs.FileInfo import qbs.Utilities Module { - property string qtcreator_display_version: '12.0.0-beta1' - property string ide_version_major: '11' + property string qtcreator_display_version: '13.0.0-beta1' + property string ide_version_major: '12' property string ide_version_minor: '0' property string ide_version_release: '82' property string qtcreator_version: ide_version_major + '.' + ide_version_minor + '.' + ide_version_release - property string ide_compat_version_major: '11' + property string ide_compat_version_major: '12' property string ide_compat_version_minor: '0' property string ide_compat_version_release: '82' property string qtcreator_compat_version: ide_compat_version_major + '.' From 8d21274b28c6ba3718ad319b5663a0cd907bad80 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Sun, 10 Sep 2023 15:40:49 +0900 Subject: [PATCH 0002/1546] FindInFiles: Add button to select directory from current document Enhanced UI by introducing a button for users to easily set the directory of the current document to the search path, addressing the limitation of the existing 'Browse...' button. Change-Id: If33f5c34428224ceb8854794b0dc222d588429cb Reviewed-by: Reviewed-by: Eike Ziller --- src/plugins/texteditor/findinfiles.cpp | 17 +++++++++++++++++ src/plugins/texteditor/findinfiles.h | 2 ++ 2 files changed, 19 insertions(+) diff --git a/src/plugins/texteditor/findinfiles.cpp b/src/plugins/texteditor/findinfiles.cpp index c8a6531ba65..bf4856fd487 100644 --- a/src/plugins/texteditor/findinfiles.cpp +++ b/src/plugins/texteditor/findinfiles.cpp @@ -108,6 +108,11 @@ void FindInFiles::searchEnginesSelectionChanged(int index) m_searchEngineWidget->setCurrentIndex(index); } +void FindInFiles::currentEditorChanged(Core::IEditor *editor) +{ + m_currentDirectory->setEnabled(editor && editor->document() && !editor->document()->filePath().isEmpty()); +} + QWidget *FindInFiles::createConfigWidget() { if (!m_configWidget) { @@ -149,6 +154,18 @@ QWidget *FindInFiles::createConfigWidget() for (const QString &dir: legacyHistory) completer->addEntry(dir); } + m_directory->addButton("Current", this, [this]() { + const IDocument *document = EditorManager::instance()->currentDocument(); + if (!document) + return; + m_directory->setFilePath(document->filePath().parentDir()); + }); + m_currentDirectory = m_directory->buttonAtIndex(1); + auto editorManager = EditorManager::instance(); + connect(editorManager, &EditorManager::currentEditorChanged, + this, &FindInFiles::currentEditorChanged); + currentEditorChanged(editorManager->currentEditor()); + dirLabel->setBuddy(m_directory); gridLayout->addWidget(m_directory, row++, 1, 1, 2); diff --git a/src/plugins/texteditor/findinfiles.h b/src/plugins/texteditor/findinfiles.h index 49c78d2a74b..757458e0880 100644 --- a/src/plugins/texteditor/findinfiles.h +++ b/src/plugins/texteditor/findinfiles.h @@ -48,9 +48,11 @@ private: FileContainerProvider fileContainerProvider() const override; void setValid(bool valid); void searchEnginesSelectionChanged(int index); + void currentEditorChanged(Core::IEditor *editor); QPointer m_configWidget; QPointer m_directory; + QAbstractButton *m_currentDirectory; QStackedWidget *m_searchEngineWidget = nullptr; QComboBox *m_searchEngineCombo = nullptr; bool m_isValid = false; From c74ed31d67671db0eac9c989a03c7605240a608e Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Fri, 29 Sep 2023 13:58:16 +0200 Subject: [PATCH 0003/1546] QtSupport: Fix VersionData cache Change-Id: I90d2b7d152123118b6244c86539868d185fde51b Reviewed-by: Christian Stenger --- src/plugins/qtsupport/baseqtversion.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index 8cc56857231..8bc703e1817 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -119,19 +119,19 @@ public: QHash versionInfo; bool versionInfoUpToDate = false; - static QHash fromVariantMap(const QVariantMap &map) + static QHash fromStore(const Store &map) { QHash result; for (auto it = map.constBegin(); it != map.constEnd(); ++it) - result.insert(ProKey(it.key()), ProString(it.value().toString())); + result.insert(ProKey(it.key().toByteArray()), ProString(it.value().toString())); return result; } - static QVariantMap toVariantMap(const QHash &map) + static Store toStore(const QHash &map) { - QVariantMap result; + Store result; for (auto it = map.constBegin(); it != map.constEnd(); ++it) - result.insert(it.key().toQString(), it.value().toQString()); + result.insert(it.key().toString().toQString().toUtf8(), it.value().toQString()); return result; } @@ -170,7 +170,7 @@ public: result.insert("HostDataPath", hostDataPath.toSettings()); result.insert("HostPrefixPath", hostPrefixPath.toSettings()); result.insert("QtAbis", Utils::transform(qtAbis, &Abi::toString)); - result.insert("VersionInfo", toVariantMap(versionInfo)); + result.insert("VersionInfo", QVariant::fromValue(toStore(versionInfo))); return result; } @@ -209,7 +209,7 @@ public: hostDataPath = FilePath::fromSettings(map.value("HostDataPath")); hostPrefixPath = FilePath::fromSettings(map.value("HostPrefixPath")); qtAbis = Utils::transform(map.value("QtAbis").toStringList(), &Abi::fromString); - versionInfo = fromVariantMap(map.value("VersionInfo").toMap()); + versionInfo = fromStore(map.value("VersionInfo").value()); } }; From 4c746e79f0efb650b7616bcc4876228eeb4ffe59 Mon Sep 17 00:00:00 2001 From: Mehdi Salem Date: Fri, 29 Sep 2023 18:10:44 +0200 Subject: [PATCH 0004/1546] integrate qtkeychain as 3rdparty lib Change-Id: I1efe32cf4964d2c4de5205462aa4ade74eb0e3b8 Reviewed-by: Eike Ziller --- README.md | 33 + .../overview/creator-acknowledgements.qdoc | 14 + .../src/overview/license-bsd-3-clause.qdocinc | 29 + src/libs/3rdparty/CMakeLists.txt | 1 + src/libs/3rdparty/qtkeychain/CMakeLists.txt | 66 ++ .../qtkeychain/CMakeLists.txt.upstream | 198 ++++++ src/libs/3rdparty/qtkeychain/COPYING | 23 + src/libs/3rdparty/qtkeychain/ChangeLog | 109 +++ .../qtkeychain/QtKeychainConfig.cmake.in | 28 + src/libs/3rdparty/qtkeychain/ReadMe.md | 29 + .../Modules/ECMPackageConfigHelpers.cmake | 202 ++++++ .../qtkeychain/cmake/Modules/ECMQueryQt.cmake | 100 +++ .../cmake/Modules/ECMSetupVersion.cmake | 202 ++++++ .../cmake/Modules/QtVersionOption.cmake | 36 + src/libs/3rdparty/qtkeychain/gnomekeyring.cpp | 86 +++ src/libs/3rdparty/qtkeychain/gnomekeyring_p.h | 94 +++ src/libs/3rdparty/qtkeychain/keychain.cpp | 235 +++++++ src/libs/3rdparty/qtkeychain/keychain.h | 282 ++++++++ .../3rdparty/qtkeychain/keychain_apple.mm | 263 ++++++++ src/libs/3rdparty/qtkeychain/keychain_p.h | 167 +++++ .../3rdparty/qtkeychain/keychain_unix.cpp | 633 ++++++++++++++++++ src/libs/3rdparty/qtkeychain/keychain_win.cpp | 193 ++++++ src/libs/3rdparty/qtkeychain/libsecret.cpp | 349 ++++++++++ src/libs/3rdparty/qtkeychain/libsecret_p.h | 33 + .../3rdparty/qtkeychain/org.kde.KWallet.xml | 276 ++++++++ .../3rdparty/qtkeychain/plaintextstore.cpp | 110 +++ .../3rdparty/qtkeychain/plaintextstore_p.h | 47 ++ .../3rdparty/qtkeychain/qkeychain_export.h | 11 + .../qtkeychain/translations/qtkeychain_de.ts | 234 +++++++ .../qtkeychain/translations/qtkeychain_fr.ts | 226 +++++++ .../qtkeychain/translations/qtkeychain_nl.ts | 320 +++++++++ .../qtkeychain/translations/qtkeychain_ro.ts | 235 +++++++ .../qtkeychain/translations/qtkeychain_ru.ts | 234 +++++++ .../qtkeychain/translations/qtkeychain_zh.ts | 234 +++++++ .../translations/translations.qrc.in | 5 + 35 files changed, 5337 insertions(+) create mode 100644 doc/qtcreator/src/overview/license-bsd-3-clause.qdocinc create mode 100644 src/libs/3rdparty/qtkeychain/CMakeLists.txt create mode 100644 src/libs/3rdparty/qtkeychain/CMakeLists.txt.upstream create mode 100644 src/libs/3rdparty/qtkeychain/COPYING create mode 100644 src/libs/3rdparty/qtkeychain/ChangeLog create mode 100644 src/libs/3rdparty/qtkeychain/QtKeychainConfig.cmake.in create mode 100644 src/libs/3rdparty/qtkeychain/ReadMe.md create mode 100644 src/libs/3rdparty/qtkeychain/cmake/Modules/ECMPackageConfigHelpers.cmake create mode 100644 src/libs/3rdparty/qtkeychain/cmake/Modules/ECMQueryQt.cmake create mode 100644 src/libs/3rdparty/qtkeychain/cmake/Modules/ECMSetupVersion.cmake create mode 100644 src/libs/3rdparty/qtkeychain/cmake/Modules/QtVersionOption.cmake create mode 100644 src/libs/3rdparty/qtkeychain/gnomekeyring.cpp create mode 100644 src/libs/3rdparty/qtkeychain/gnomekeyring_p.h create mode 100644 src/libs/3rdparty/qtkeychain/keychain.cpp create mode 100644 src/libs/3rdparty/qtkeychain/keychain.h create mode 100644 src/libs/3rdparty/qtkeychain/keychain_apple.mm create mode 100644 src/libs/3rdparty/qtkeychain/keychain_p.h create mode 100644 src/libs/3rdparty/qtkeychain/keychain_unix.cpp create mode 100644 src/libs/3rdparty/qtkeychain/keychain_win.cpp create mode 100644 src/libs/3rdparty/qtkeychain/libsecret.cpp create mode 100644 src/libs/3rdparty/qtkeychain/libsecret_p.h create mode 100644 src/libs/3rdparty/qtkeychain/org.kde.KWallet.xml create mode 100644 src/libs/3rdparty/qtkeychain/plaintextstore.cpp create mode 100644 src/libs/3rdparty/qtkeychain/plaintextstore_p.h create mode 100644 src/libs/3rdparty/qtkeychain/qkeychain_export.h create mode 100644 src/libs/3rdparty/qtkeychain/translations/qtkeychain_de.ts create mode 100644 src/libs/3rdparty/qtkeychain/translations/qtkeychain_fr.ts create mode 100644 src/libs/3rdparty/qtkeychain/translations/qtkeychain_nl.ts create mode 100644 src/libs/3rdparty/qtkeychain/translations/qtkeychain_ro.ts create mode 100644 src/libs/3rdparty/qtkeychain/translations/qtkeychain_ru.ts create mode 100644 src/libs/3rdparty/qtkeychain/translations/qtkeychain_zh.ts create mode 100644 src/libs/3rdparty/qtkeychain/translations/translations.qrc.in diff --git a/README.md b/README.md index 70500da736d..98504b7c751 100644 --- a/README.md +++ b/README.md @@ -1003,3 +1003,36 @@ SQLite (https://www.sqlite.org) is in the Public Domain. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +### QtKeychain + + QtKeychain provides the Axivion plugin with the means to securely store + and retrieve dashboard credentials. + + https://github.com/frankosterfeld/qtkeychain + + Distributed under the Modified BSD License + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/doc/qtcreator/src/overview/creator-acknowledgements.qdoc b/doc/qtcreator/src/overview/creator-acknowledgements.qdoc index a9773753b67..5c7a8371e05 100644 --- a/doc/qtcreator/src/overview/creator-acknowledgements.qdoc +++ b/doc/qtcreator/src/overview/creator-acknowledgements.qdoc @@ -976,5 +976,19 @@ \endcode + \li \b QtKeychain + + QtKeychain is a platform-independent Qt API to store passwords and + other secret data securely. + + + \list + \li \l https://github.com/frankosterfeld/qtkeychain + \endlist + + Distributed under the Modified BSD License. + + \include license-bsd-3-clause.qdocinc + \endlist */ diff --git a/doc/qtcreator/src/overview/license-bsd-3-clause.qdocinc b/doc/qtcreator/src/overview/license-bsd-3-clause.qdocinc new file mode 100644 index 00000000000..3f55574fef0 --- /dev/null +++ b/doc/qtcreator/src/overview/license-bsd-3-clause.qdocinc @@ -0,0 +1,29 @@ + \badcode + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + (1) Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + (2) Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + (3)The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + \endcode diff --git a/src/libs/3rdparty/CMakeLists.txt b/src/libs/3rdparty/CMakeLists.txt index 0cf9818ed54..165c5f5ca02 100644 --- a/src/libs/3rdparty/CMakeLists.txt +++ b/src/libs/3rdparty/CMakeLists.txt @@ -2,6 +2,7 @@ add_subdirectory(cplusplus) add_subdirectory(syntax-highlighting) add_subdirectory(libvterm) add_subdirectory(libptyqt) +add_subdirectory(qtkeychain) if(WIN32) add_subdirectory(winpty) diff --git a/src/libs/3rdparty/qtkeychain/CMakeLists.txt b/src/libs/3rdparty/qtkeychain/CMakeLists.txt new file mode 100644 index 00000000000..d8ba7e3178b --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/CMakeLists.txt @@ -0,0 +1,66 @@ +add_qtc_library(qtkeychain + DEPENDS Qt::Core + SOURCES + keychain.cpp keychain.h + qkeychain_export.h + PROPERTIES + QT_COMPILE_OPTIONS_DISABLE_WARNINGS ON +) + +if (WIN32) + option(USE_CREDENTIAL_STORE "Build with windows CredentialStore support" ON) + + extend_qtc_library(qtkeychain SOURCES keychain_win.cpp) + + extend_qtc_library(qtkeychain + CONDITION USE_CREDENTIAL_STORE + FEATURE_INFO "CredentialStore keychain support" + DEFINES USE_CREDENTIAL_STORE=1 + ) + extend_qtc_library(qtkeychain + CONDITION NOT USE_CREDENTIAL_STORE + SOURCES plaintextstore.cpp + DEPENDS crypt32 + ) + endif() +endif() + +extend_qtc_library(qtkeychain + CONDITION APPLE + SOURCES keychain_apple.mm + DEPENDS ${FWFoundation} ${FWSecurity} +) + +if (UNIX AND NOT APPLE) + find_package(Qt6 COMPONENTS DBus REQUIRED) + + option(LIBSECRET_SUPPORT "Build with libsecret support if available" ON) + if (LIBSECRET_SUPPORT) + find_package(PkgConfig REQUIRED) + + include(FindPkgConfig) + pkg_check_modules(LIBSECRET libsecret-1) + + extend_qtc_library(qtkeychain + CONDITION LIBSECRET_FOUND + FEATURE_INFO "libsecret keychain support" + DEFINES HAVE_LIBSECRET=1 + INCLUDES ${LIBSECRET_INCLUDE_DIRS} + DEPENDS ${LIBSECRET_LIBRARIES} + ) + endif() + + qt6_add_dbus_interface(dbus_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/org.kde.KWallet.xml kwallet_interface KWalletInterface) + + extend_qtc_library(qtkeychain + DEFINES KEYCHAIN_DBUS=1 + DEPENDS Qt::DBus + SOURCES + gnomekeyring.cpp + keychain_unix.cpp + libsecret.cpp + plaintextstore.cpp + ${dbus_SOURCES} + ) +endif() diff --git a/src/libs/3rdparty/qtkeychain/CMakeLists.txt.upstream b/src/libs/3rdparty/qtkeychain/CMakeLists.txt.upstream new file mode 100644 index 00000000000..3b4e30d1295 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/CMakeLists.txt.upstream @@ -0,0 +1,198 @@ +set(QTKEYCHAIN_VERSION 0.14.99) +set(QTKEYCHAIN_SOVERSION 1) + +project(qtkeychain VERSION ${QTKEYCHAIN_VERSION} LANGUAGES CXX) + +include(FindPkgConfig) + +### + +set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${PROJECT_SOURCE_DIR}/cmake/Modules") +include(GNUInstallDirs) +include(GenerateExportHeader) +include(CMakePackageConfigHelpers) +include(ECMSetupVersion) +include(CMakeDependentOption) + +option(BUILD_TRANSLATIONS "Build translations" ON) +option(BUILD_SHARED_LIBS "Build dynamic library" OFF) + +CMAKE_DEPENDENT_OPTION(BUILD_TRANSLATIONS_AS_RESOURCES "Bundle translations with the library" OFF + "BUILD_TRANSLATIONS" OFF) + +if (WIN32) + option(USE_CREDENTIAL_STORE "Build with windows CredentialStore support" ON) + + if (USE_CREDENTIAL_STORE) + add_definitions(-DUSE_CREDENTIAL_STORE=1) + endif() +endif() + + +find_package(Qt6 COMPONENTS Core REQUIRED) + +if(UNIX AND NOT APPLE) + find_package(Qt6 COMPONENTS DBus REQUIRED) + include_directories(${Qt6DBus_INCLUDE_DIRS}) + set(QTDBUS_LIBRARIES ${Qt6DBus_LIBRARIES}) +endif() + +if(BUILD_TRANSLATIONS) + find_package(Qt6 COMPONENTS LinguistTools REQUIRED) +endif() + +set(QTCORE_LIBRARIES ${Qt6Core_LIBRARIES}) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +list(APPEND qtkeychain_LIBRARIES ${QTCORE_LIBRARIES}) +set(qtkeychain_SOURCES + keychain.cpp + qkeychain_export.h + keychain.h +) + +if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + # CMake < 3.15 sneaks in /W# flags for us, so we need a replacement, + # or we'll get a warning (cf. CMP0092) + if (CMAKE_CXX_FLAGS MATCHES "/W[0-4]") + string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") + endif() +else() + # MSVC's STL / Qt headers are not MSVC -Wall clean, so don't enable it there + add_definitions( -Wall -Werror=return-type ) +endif() + +if(WIN32) + list(APPEND qtkeychain_SOURCES keychain_win.cpp) + if (NOT USE_CREDENTIAL_STORE) + list(APPEND qtkeychain_LIBRARIES crypt32) + list(APPEND qtkeychain_SOURCES plaintextstore.cpp) + endif() + #FIXME: mingw bug; otherwise getting undefined refs to RtlSecureZeroMemory there + if(MINGW) + add_definitions( -O2 ) + endif() +endif() + +if(APPLE) + list(APPEND qtkeychain_SOURCES keychain_apple.mm) + list(APPEND qtkeychain_LIBRARIES "-framework Foundation" "-framework Security") +endif() + +if(UNIX AND NOT APPLE) + option(LIBSECRET_SUPPORT "Build with libsecret support if available" ON) + find_package(PkgConfig REQUIRED) + pkg_check_modules(LIBSECRET libsecret-1) + + if(LIBSECRET_SUPPORT AND LIBSECRET_FOUND) + add_definitions(-DHAVE_LIBSECRET=1) + INCLUDE_DIRECTORIES(${LIBSECRET_INCLUDE_DIRS}) + LINK_DIRECTORIES(${LIBSECRET_LIBRARY_DIRS}) + list(APPEND qtkeychain_LIBRARIES_PRIVATE ${LIBSECRET_LIBRARIES}) + endif() + + add_definitions(-DKEYCHAIN_DBUS=1) + list(APPEND qtkeychain_SOURCES keychain_unix.cpp gnomekeyring.cpp libsecret.cpp plaintextstore.cpp) + qt6_add_dbus_interface(qtkeychain_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/org.kde.KWallet.xml kwallet_interface KWalletInterface) + list(APPEND qtkeychain_LIBRARIES ${QTDBUS_LIBRARIES} ) +endif() + +qt6_wrap_cpp(qtkeychain_MOC_OUTFILES keychain.h keychain_p.h gnomekeyring_p.h) + +set(qtkeychain_TR_FILES + translations/qtkeychain_de.ts + translations/qtkeychain_fr.ts + translations/qtkeychain_ro.ts + translations/qtkeychain_ru.ts + translations/qtkeychain_zh.ts +) + +set(QTKEYCHAIN_TARGET_NAME qtkeychain) +add_library(${QTKEYCHAIN_TARGET_NAME} ${qtkeychain_SOURCES} ${qtkeychain_MOC_OUTFILES} ${qtkeychain_QM_FILES}) +if(WIN32) + set_target_properties( ${QTKEYCHAIN_TARGET_NAME} PROPERTIES DEBUG_POSTFIX "d" ) +endif() + +file(GLOB qtkeychain_TR_SOURCES *.cpp *.h *.ui) +if ( BUILD_TRANSLATIONS ) + qt6_create_translation(qtkeychain_MESSAGES ${qtkeychain_TR_SOURCES} ${qtkeychain_TR_FILES}) + qt6_add_translation(qtkeychain_QM_FILES ${qtkeychain_TR_FILES}) + add_custom_target(messages DEPENDS ${qtkeychain_MESSAGES}) + add_custom_target(translations DEPENDS ${qtkeychain_QM_FILES} messages) + # https://github.com/frankosterfeld/qtkeychain/issues/185 + add_dependencies(${QTKEYCHAIN_TARGET_NAME} translations) + + if (BUILD_TRANSLATIONS_AS_RESOURCES) + set(QM_FILE_LIST "") + foreach(FILE ${qtkeychain_QM_FILES}) + list(APPEND QM_FILE_LIST "${FILE}") + endforeach() + string(REPLACE ";" "" QM_FILE_LIST ${QM_FILE_LIST}) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/translations/translations.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc) + target_sources(${QTKEYCHAIN_TARGET_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/translations.qrc) + else() + set(QTKEYCHAIN_TRANSLATIONS_DIR + ${CMAKE_INSTALL_DATADIR}/qtkeychain/translations + CACHE PATH "The location of the QtKeychain translations" ) + install(FILES ${qtkeychain_QM_FILES} DESTINATION ${QTKEYCHAIN_TRANSLATIONS_DIR}) + endif() +endif( BUILD_TRANSLATIONS ) + +target_link_libraries(${QTKEYCHAIN_TARGET_NAME} PUBLIC ${qtkeychain_LIBRARIES} PRIVATE ${qtkeychain_LIBRARIES_PRIVATE}) +if(NOT INTERFACE_INCLUDE_SUFFIX) + set(INTERFACE_INCLUDE_SUFFIX include) +endif() +target_include_directories(${QTKEYCHAIN_TARGET_NAME} PUBLIC $) + +generate_export_header(${QTKEYCHAIN_TARGET_NAME} + EXPORT_FILE_NAME qkeychain_export.h + EXPORT_MACRO_NAME QKEYCHAIN_EXPORT +) + +set_target_properties(${QTKEYCHAIN_TARGET_NAME} PROPERTIES + VERSION ${QTKEYCHAIN_VERSION} + SOVERSION ${QTKEYCHAIN_SOVERSION} + INSTALL_RPATH_USE_LINK_PATH TRUE +) + +if (NOT APPLE) + set_target_properties(${QTKEYCHAIN_TARGET_NAME} PROPERTIES + INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}" + ) +endif() + +install(FILES keychain.h ${CMAKE_CURRENT_BINARY_DIR}/qkeychain_export.h + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/qtkeychain/ +) + +install(TARGETS ${QTKEYCHAIN_TARGET_NAME} + EXPORT QtKeychainLibraryDepends + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) + +### +### CMake config file +### + +configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/QtKeychainConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/QtKeychainConfig.cmake" + INSTALL_DESTINATION QtKeychain) + +ecm_setup_version("${QTKEYCHAIN_VERSION}" VARIABLE_PREFIX SNORE + PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/QtKeychainConfigVersion.cmake" + SOVERSION ${QTKEYCHAIN_VERSION}) + +install(EXPORT QtKeychainLibraryDepends + DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/QtKeychain" +) + +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/QtKeychainConfig.cmake + ${CMAKE_CURRENT_BINARY_DIR}/QtKeychainConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/QtKeychain +) + diff --git a/src/libs/3rdparty/qtkeychain/COPYING b/src/libs/3rdparty/qtkeychain/COPYING new file mode 100644 index 00000000000..69f70fff716 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/COPYING @@ -0,0 +1,23 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to + endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/libs/3rdparty/qtkeychain/ChangeLog b/src/libs/3rdparty/qtkeychain/ChangeLog new file mode 100644 index 00000000000..cb383c52968 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/ChangeLog @@ -0,0 +1,109 @@ +ChangeLog +========= + +version 0.14.1 (release 2023-06-01) + + - Export QKeychain::isAvailable() to make it usable in a shared build (Volker Krause ) + - Protect against creating the QtKeychain::QtKeychain alias target twice (Volker Krause ) + +version 0.14.0 (release 2023-05-12) + + - Add Qt 6 Android support (Igor Bugaev ) + - Add QtQuick client example ((Igor Bugaev ) + - Added Dutch translation (Heimen Stoffels ) + - Fix potential freezing with Apple keychain (Claudio Cambra ) + - Add API to check whether a secure backend is available at all (Volker Krause ) + +version 0.13.2 (release 2021-11-18) + + - CMake: Deprecate QTKEYCHAIN_STATIC in favor of BUILD_SHARED_LIBS (be@mixxx.org) + +version 0.13.1 (release 2021-11-08) + + - KWallet: Fix deletion of entries (Issue #199) + +version 0.13.0 (release 2021-11-07) + + - Linux: Require libsecret if not explicitly disabled + - Unify implementations for macOS and iOS + - CMake: lots of fixes + +version 0.12.0 (release 2020-12-16) + + * Add Qt 6 support, drop Qt 4 support + * Require C++11 + * Add Android support (Mathias Hasselmann) + +version 0.11.1 (release 2020-09-08) + + * Build system fixes + +version 0.11.0 (release 2020-09-08) + + * Important: Debug builds on Windows now get the "d" suffix + * Various build system fixes + * Add Haiku support (François Revol ) + * Translation: Russian (Alexander Gorishnyak ) + * Translation: Update French (David Geiger ) + +version 0.10.0 (release 2019-12-17) + + * Detect XFCE desktop correctly. (Sandro Knauß ) + * Windows Use CRED_PERSIST_ENTERPRISE (Olivier Goffart ) + * Windows: Improve CredWrite() error handling (Christian Kamm ) + * Fix build with Qt 5.12.x (Sergey Ilinykh ) + * Fix Qt 4 build (Robert-André Mauchin ) + * Translation: Mandarin (Taiwan) (Poren Chiang ) + * Translation: French (François Revol ) + +version 0.9.1 (release 2018-08-20) + * Windows Credential Store: Use CRED_PERSIST_ENTERPRISE (Olivier Goffart ) + * Secret: Don't match the schema name #114 (Christian Kamm ) + * Fix qmake build on Windows (Alexander Gorishnyak ) + +version 0.9.0 (release 2018-07-13) + * Fall back on libsecret if kwallet is not available (Christian Kamm ) + * Only require QtLinguist if building translations (Victor Kropp ) + * Fix building on Windows without credential store (Dmitry Ivanov ) + * Fix Qt 4 build (Sandro Knauß ) + * Make build of test application optional (Boris Pek ) + +version 0.8.0 (release 2017-04-19) + * Buildsystem improvements (Kristofer Tingdahl , Hannah von Reth , Giuseppe D'Angelo ) + * Enable C++11 support for Qt >= 5.7 (Dmitry Ivanov ) + * Doxygen documentation ( Elvis Angelaccio ) + * Libsecret support (Armin Novak ) + * iOS support (Mathias Hasselmann ) + +version 0.7.0 (release 2016-05-23) + * Bump SO version due to 0.6 being binary-incompatible to previous releases + +version 0.6.2 (release 2016-04-04) + * KWallet: Fixes a crash when storing passwords, seen on Debian/KDE4 + +version 0.6.1 (release 2016-03-31) + * Fix KWallet not working (regressions in 0.6.0) + +version 0.6.0 (release 2016-03-18) + * Added support for the Windows Credential Store + +version 0.5.0 (release 2015-05-04) + * Added support for KWallet5 (KDE5/KF) + +version 0.4.0 (release 2014-09-01) + * KWallet: Handle case where no wallet exists yet (Liviu Cristian Mirea Ghiban ) + * Improved desktop environment detection at runtime (Daniel Molkentin ) + +version 0.3.0 (release 2014-03-13) + * Gnome Keyring supported added (Francois Ferrand ) + * Improved Qt 5 support + * KWallet: Distinguish empty passwords from non-existing entries + * KWallet: Do not use hardcoded wallet name + * German translation (Daniel Molkentin ) + * Romanian translation (Arthur Țițeică ) + +version 0.2.0: no official release + +version 0.1.0 (release 2013-01-16) + * Initial release + diff --git a/src/libs/3rdparty/qtkeychain/QtKeychainConfig.cmake.in b/src/libs/3rdparty/qtkeychain/QtKeychainConfig.cmake.in new file mode 100644 index 00000000000..084d45e57f0 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/QtKeychainConfig.cmake.in @@ -0,0 +1,28 @@ +# - Config file for the QtKeychain package +# It defines the following variables +# QTKEYCHAIN_INCLUDE_DIRS - include directories for QtKeychain +# QTKEYCHAIN_LIBRARIES - libraries to link against +# as well as the following imported targets +# qt5keychain / qt6keychain +# Qt5Keychain::Qt5Keychain / Qt6Keychain::Qt6Keychain + +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/QtKeychainLibraryDepends.cmake") + +include(CMakeFindDependencyMacro) + +find_dependency(Qt6Core) + +if(UNIX AND NOT APPLE AND NOT ANDROID) + find_dependency(Qt6DBus) +endif() + +set(QTKEYCHAIN_LIBRARIES "@QTKEYCHAIN_TARGET_NAME@") +get_target_property(QTKEYCHAIN_INCLUDE_DIRS "@QTKEYCHAIN_TARGET_NAME@" INTERFACE_INCLUDE_DIRECTORIES) + +if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.18.0 AND NOT TARGET QtKeychain::QtKeychain) + add_library(QtKeychain::QtKeychain ALIAS qtkeychain) +endif() + +check_required_components(QtKeychain) diff --git a/src/libs/3rdparty/qtkeychain/ReadMe.md b/src/libs/3rdparty/qtkeychain/ReadMe.md new file mode 100644 index 00000000000..cf0a2e1311a --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/ReadMe.md @@ -0,0 +1,29 @@ +QtKeychain +========== + +QtKeychain is a Qt API to store passwords and other secret data securely. How the data is stored depends on the platform: + + * **macOS:** Passwords are stored in the macOS Keychain. + + * **Linux/Unix:** If running, GNOME Keyring is used, otherwise QtKeychain tries to use KWallet (via D-Bus), if available. Libsecret (common API for desktop-specific solutions) + is also supported. + + * **Windows:** By default, the Windows Credential Store is used (requires Windows 7 or newer). +Pass `-DUSE_CREDENTIAL_STORE=OFF` to cmake to disable it. If disabled, QtKeychain uses the Windows API function +[CryptProtectData](http://msdn.microsoft.com/en-us/library/windows/desktop/aa380261%28v=vs.85%29.aspx "CryptProtectData function") +to encrypt the password with the user's logon credentials. The encrypted data is then persisted via QSettings. + + * **Android and iOS:** Passwords are stored in the Android keystore system and iOS keychain, respectively. + +In unsupported environments QtKeychain will report an error. It will not store any data unencrypted unless explicitly requested (`setInsecureFallback( true )`). + + +Requirements +------------ + +QtKeychain 0.12 and newer supports Qt 5 and Qt 6 and requires a compiler with C++11 support. Older versions support Qt 4 and Qt 5. + +License +------- + +QtKeychain is available under the [Modified BSD License](http://www.gnu.org/licenses/license-list.html#ModifiedBSD). See the file COPYING for details. diff --git a/src/libs/3rdparty/qtkeychain/cmake/Modules/ECMPackageConfigHelpers.cmake b/src/libs/3rdparty/qtkeychain/cmake/Modules/ECMPackageConfigHelpers.cmake new file mode 100644 index 00000000000..8d48772b70d --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/cmake/Modules/ECMPackageConfigHelpers.cmake @@ -0,0 +1,202 @@ +#.rst: +# ECMPackageConfigHelpers +# ----------------------- +# +# Helper macros for generating CMake package config files. +# +# ``write_basic_package_version_file()`` is the same as the one provided by the +# `CMakePackageConfigHelpers +# `_ +# module in CMake; see that module's documentation for +# more information. +# +# :: +# +# ecm_configure_package_config_file( +# INSTALL_DESTINATION +# [PATH_VARS [ [...]] +# [NO_SET_AND_CHECK_MACRO] +# [NO_CHECK_REQUIRED_COMPONENTS_MACRO]) +# +# +# This behaves in the same way as configure_package_config_file() from CMake +# 2.8.12, except that it adds an extra helper macro: find_dependency(). It is +# highly recommended that you read the `documentation for +# CMakePackageConfigHelpers +# `_ +# for more information, particularly with regard to the PATH_VARS argument. +# +# Note that there is no argument that will disable the find_dependency() macro; +# if you do not require this macro, you should use +# ``configure_package_config_file`` from the CMakePackageConfigHelpers module. +# +# CMake 3.0 includes a CMakeFindDependencyMacro module that provides the +# find_dependency() macro (which you can ``include()`` in your package config +# file), so this file is only useful for projects wishing to provide config +# files that will work with CMake 2.8.12. +# +# Additional Config File Macros +# ============================= +# +# :: +# +# find_dependency( [ [EXACT]]) +# +# find_dependency() should be used instead of find_package() to find package +# dependencies. It forwards the correct parameters for EXACT, QUIET and +# REQUIRED which were passed to the original find_package() call. It also sets +# an informative diagnostic message if the dependency could not be found. +# +# Since pre-1.0.0. + +#============================================================================= +# SPDX-FileCopyrightText: 2014 Alex Merry +# SPDX-FileCopyrightText: 2013 Stephen Kelly +# +# SPDX-License-Identifier: BSD-3-Clause + +include(${CMAKE_ROOT}/Modules/CMakePackageConfigHelpers.cmake) + +set(_ecm_package_config_helpers_included TRUE) + +if(NOT CMAKE_MINIMUM_REQUIRED_VERSION VERSION_LESS 2.8.13) + message(AUTHOR_WARNING "Your project already requires a version of CMake that includes the find_dependency macro via the CMakeFindDependencyMacro module. You should use CMakePackageConfigHelpers instead of ECMPackageConfigHelpers.") +endif() + +function(ECM_CONFIGURE_PACKAGE_CONFIG_FILE _inputFile _outputFile) + set(options NO_SET_AND_CHECK_MACRO NO_CHECK_REQUIRED_COMPONENTS_MACRO) + set(oneValueArgs INSTALL_DESTINATION ) + set(multiValueArgs PATH_VARS ) + + cmake_parse_arguments(CCF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(CCF_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown keywords given to CONFIGURE_PACKAGE_CONFIG_FILE(): \"${CCF_UNPARSED_ARGUMENTS}\"") + endif() + + if(NOT CCF_INSTALL_DESTINATION) + message(FATAL_ERROR "No INSTALL_DESTINATION given to CONFIGURE_PACKAGE_CONFIG_FILE()") + endif() + + if(IS_ABSOLUTE "${CCF_INSTALL_DESTINATION}") + set(absInstallDir "${CCF_INSTALL_DESTINATION}") + else() + set(absInstallDir "${CMAKE_INSTALL_PREFIX}/${CCF_INSTALL_DESTINATION}") + endif() + + file(RELATIVE_PATH PACKAGE_RELATIVE_PATH "${absInstallDir}" "${CMAKE_INSTALL_PREFIX}" ) + + foreach(var ${CCF_PATH_VARS}) + if(NOT DEFINED ${var}) + message(FATAL_ERROR "Variable ${var} does not exist") + else() + if(IS_ABSOLUTE "${${var}}") + string(REPLACE "${CMAKE_INSTALL_PREFIX}" "\${PACKAGE_PREFIX_DIR}" + PACKAGE_${var} "${${var}}") + else() + set(PACKAGE_${var} "\${PACKAGE_PREFIX_DIR}/${${var}}") + endif() + endif() + endforeach() + + get_filename_component(inputFileName "${_inputFile}" NAME) + + set(PACKAGE_INIT " +####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() (ECM variant) ####### +####### Any changes to this file will be overwritten by the next CMake run ####### +####### The input file was ${inputFileName} ####### + +get_filename_component(PACKAGE_PREFIX_DIR \"\${CMAKE_CURRENT_LIST_DIR}/${PACKAGE_RELATIVE_PATH}\" ABSOLUTE) +") + + if("${absInstallDir}" MATCHES "^(/usr)?/lib(64)?/.+") + # Handle "/usr move" symlinks created by some Linux distros. + set(PACKAGE_INIT "${PACKAGE_INIT} +# Use original install prefix when loaded through a \"/usr move\" +# cross-prefix symbolic link such as /lib -> /usr/lib. +get_filename_component(_realCurr \"\${CMAKE_CURRENT_LIST_DIR}\" REALPATH) +get_filename_component(_realOrig \"${absInstallDir}\" REALPATH) +if(_realCurr STREQUAL _realOrig) + set(PACKAGE_PREFIX_DIR \"${CMAKE_INSTALL_PREFIX}\") +endif() +unset(_realOrig) +unset(_realCurr) +") + endif() + + if(NOT CCF_NO_SET_AND_CHECK_MACRO) + set(PACKAGE_INIT "${PACKAGE_INIT} +macro(set_and_check _var _file) + set(\${_var} \"\${_file}\") + if(NOT EXISTS \"\${_file}\") + message(FATAL_ERROR \"File or directory \${_file} referenced by variable \${_var} does not exist !\") + endif() +endmacro() + +include(CMakeFindDependencyMacro OPTIONAL RESULT_VARIABLE _CMakeFindDependencyMacro_FOUND) + +if (NOT _CMakeFindDependencyMacro_FOUND) + macro(find_dependency dep) + if (NOT \${dep}_FOUND) + + set(ecm_fd_version) + if (\${ARGC} GREATER 1) + set(ecm_fd_version \${ARGV1}) + endif() + set(ecm_fd_exact_arg) + if(\${CMAKE_FIND_PACKAGE_NAME}_FIND_VERSION_EXACT) + set(ecm_fd_exact_arg EXACT) + endif() + set(ecm_fd_quiet_arg) + if(\${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY) + set(ecm_fd_quiet_arg QUIET) + endif() + set(ecm_fd_required_arg) + if(\${CMAKE_FIND_PACKAGE_NAME}_FIND_REQUIRED) + set(ecm_fd_required_arg REQUIRED) + endif() + + find_package(\${dep} \${ecm_fd_version} + \${ecm_fd_exact_arg} + \${ecm_fd_quiet_arg} + \${ecm_fd_required_arg} + ) + + if (NOT \${dep}_FOUND) + set(\${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE \"\${CMAKE_FIND_PACKAGE_NAME} could not be found because dependency \${dep} could not be found.\") + set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND False) + return() + endif() + + set(ecm_fd_version) + set(ecm_fd_required_arg) + set(ecm_fd_quiet_arg) + set(ecm_fd_exact_arg) + endif() + endmacro() +endif() + +") + endif() + + + if(NOT CCF_NO_CHECK_REQUIRED_COMPONENTS_MACRO) + set(PACKAGE_INIT "${PACKAGE_INIT} +macro(check_required_components _NAME) + foreach(comp \${\${_NAME}_FIND_COMPONENTS}) + if(NOT \${_NAME}_\${comp}_FOUND) + if(\${_NAME}_FIND_REQUIRED_\${comp}) + set(\${_NAME}_FOUND FALSE) + endif() + endif() + endforeach() +endmacro() +") + endif() + + set(PACKAGE_INIT "${PACKAGE_INIT} +####################################################################################") + + configure_file("${_inputFile}" "${_outputFile}" @ONLY) + +endfunction() diff --git a/src/libs/3rdparty/qtkeychain/cmake/Modules/ECMQueryQt.cmake b/src/libs/3rdparty/qtkeychain/cmake/Modules/ECMQueryQt.cmake new file mode 100644 index 00000000000..98eb50089e4 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/cmake/Modules/ECMQueryQt.cmake @@ -0,0 +1,100 @@ +# SPDX-FileCopyrightText: 2014 Rohan Garg +# SPDX-FileCopyrightText: 2014 Alex Merry +# SPDX-FileCopyrightText: 2014-2016 Aleix Pol +# SPDX-FileCopyrightText: 2017 Friedrich W. H. Kossebau +# SPDX-FileCopyrightText: 2022 Ahmad Samir +# +# SPDX-License-Identifier: BSD-3-Clause +#[=======================================================================[.rst: +ECMQueryQt +--------------- +This module can be used to query the installation paths used by Qt. + +For Qt5 this uses ``qmake``, and for Qt6 this used ``qtpaths`` (the latter has built-in +support to query the paths of a target platform when cross-compiling). + +This module defines the following function: +:: + + ecm_query_qt( [TRY]) + +Passing ``TRY`` will result in the method not making the build fail if the executable +used for querying has not been found, but instead simply print a warning message and +return an empty string. + +Example usage: + +.. code-block:: cmake + + include(ECMQueryQt) + ecm_query_qt(bin_dir QT_INSTALL_BINS) + +If the call succeeds ``${bin_dir}`` will be set to ``/path/to/bin/dir`` (e.g. +``/usr/lib64/qt/bin/``). + +Since: 5.93 +#]=======================================================================] + +include(${CMAKE_CURRENT_LIST_DIR}/QtVersionOption.cmake) +include(CheckLanguage) +check_language(CXX) +if (CMAKE_CXX_COMPILER) + # Enable the CXX language to let CMake look for config files in library dirs. + # See: https://gitlab.kitware.com/cmake/cmake/-/issues/23266 + enable_language(CXX) +endif() + +if (QT_MAJOR_VERSION STREQUAL "5") + # QUIET to accommodate the TRY option + find_package(Qt${QT_MAJOR_VERSION}Core QUIET) + if(TARGET Qt5::qmake) + get_target_property(_qmake_executable_default Qt5::qmake LOCATION) + + set(QUERY_EXECUTABLE ${_qmake_executable_default} + CACHE FILEPATH "Location of the Qt5 qmake executable") + set(_exec_name_text "Qt5 qmake") + set(_cli_option "-query") + endif() +elseif(QT_MAJOR_VERSION STREQUAL "6") + # QUIET to accommodate the TRY option + find_package(Qt6 COMPONENTS CoreTools QUIET CONFIG) + if (TARGET Qt6::qtpaths) + get_target_property(_qtpaths_executable Qt6::qtpaths LOCATION) + + set(QUERY_EXECUTABLE ${_qtpaths_executable} + CACHE FILEPATH "Location of the Qt6 qtpaths executable") + set(_exec_name_text "Qt6 qtpaths") + set(_cli_option "--query") + endif() +endif() + +function(ecm_query_qt result_variable qt_variable) + set(options TRY) + set(oneValueArgs) + set(multiValueArgs) + + cmake_parse_arguments(ARGS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(NOT QUERY_EXECUTABLE) + if(ARGS_TRY) + set(${result_variable} "" PARENT_SCOPE) + message(STATUS "No ${_exec_name_text} executable found. Can't check ${qt_variable}") + return() + else() + message(FATAL_ERROR "No ${_exec_name_text} executable found. Can't check ${qt_variable} as required") + endif() + endif() + execute_process( + COMMAND ${QUERY_EXECUTABLE} ${_cli_option} "${qt_variable}" + RESULT_VARIABLE return_code + OUTPUT_VARIABLE output + ) + if(return_code EQUAL 0) + string(STRIP "${output}" output) + file(TO_CMAKE_PATH "${output}" output_path) + set(${result_variable} "${output_path}" PARENT_SCOPE) + else() + message(WARNING "Failed call: ${_command} \"${qt_variable}\"") + message(FATAL_ERROR "${_exec_name_text} call failed: ${return_code}") + endif() +endfunction() diff --git a/src/libs/3rdparty/qtkeychain/cmake/Modules/ECMSetupVersion.cmake b/src/libs/3rdparty/qtkeychain/cmake/Modules/ECMSetupVersion.cmake new file mode 100644 index 00000000000..65c1688ab00 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/cmake/Modules/ECMSetupVersion.cmake @@ -0,0 +1,202 @@ +#.rst: +# ECMSetupVersion +# --------------- +# +# Handle library version information. +# +# :: +# +# ecm_setup_version( +# VARIABLE_PREFIX +# [SOVERSION ] +# [VERSION_HEADER ] +# [PACKAGE_VERSION_FILE [COMPATIBILITY ]] ) +# +# This parses a version string and sets up a standard set of version variables. +# It can optionally also create a C version header file and a CMake package +# version file to install along with the library. +# +# If the ```` argument is of the form ``..`` +# (or ``...``), The following CMake variables are +# set:: +# +# _VERSION_MAJOR - +# _VERSION_MINOR - +# _VERSION_PATCH - +# _VERSION - +# _VERSION_STRING - (for compatibility: use _VERSION instead) +# _SOVERSION - , or if SOVERSION was not given +# +# If CMake policy CMP0048 is not NEW, the following CMake variables will also +# be set:: +# +# PROJECT_VERSION_MAJOR - +# PROJECT_VERSION_MINOR - +# PROJECT_VERSION_PATCH - +# PROJECT_VERSION - +# PROJECT_VERSION_STRING - (for compatibility: use PROJECT_VERSION instead) +# +# If the VERSION_HEADER option is used, a simple C header is generated with the +# given filename. If filename is a relative path, it is interpreted as relative +# to CMAKE_CURRENT_BINARY_DIR. The generated header contains the following +# macros:: +# +# _VERSION_MAJOR - as an integer +# _VERSION_MINOR - as an integer +# _VERSION_PATCH - as an integer +# _VERSION_STRING - as a C string +# _VERSION - the version as an integer +# +# ``_VERSION`` has ```` in the bottom 8 bits, ```` in the +# next 8 bits and ```` in the remaining bits. Note that ```` and +# ```` must be less than 256. +# +# If the PACKAGE_VERSION_FILE option is used, a simple CMake package version +# file is created using the write_basic_package_version_file() macro provided by +# CMake. It should be installed in the same location as the Config.cmake file of +# the library so that it can be found by find_package(). If the filename is a +# relative path, it is interpreted as relative to CMAKE_CURRENT_BINARY_DIR. The +# optional COMPATIBILITY option is forwarded to +# write_basic_package_version_file(), and defaults to AnyNewerVersion. +# +# If CMake policy CMP0048 is NEW, an alternative form of the command is +# available:: +# +# ecm_setup_version(PROJECT +# [VARIABLE_PREFIX ] +# [SOVERSION ] +# [VERSION_HEADER ] +# [PACKAGE_VERSION_FILE ] ) +# +# This will use the version information set by the project() command. +# VARIABLE_PREFIX defaults to the project name. Note that PROJECT must be the +# first argument. In all other respects, it behaves like the other form of the +# command. +# +# Since pre-1.0.0. +# +# COMPATIBILITY option available since 1.6.0. + +#============================================================================= +# SPDX-FileCopyrightText: 2014 Alex Merry +# SPDX-FileCopyrightText: 2012 Alexander Neundorf +# +# SPDX-License-Identifier: BSD-3-Clause + +include(CMakePackageConfigHelpers) + +# save the location of the header template while CMAKE_CURRENT_LIST_DIR +# has the value we want +set(_ECM_SETUP_VERSION_HEADER_TEMPLATE "${CMAKE_CURRENT_LIST_DIR}/ECMVersionHeader.h.in") + +function(ecm_setup_version _version) + set(options ) + set(oneValueArgs VARIABLE_PREFIX SOVERSION VERSION_HEADER PACKAGE_VERSION_FILE COMPATIBILITY) + set(multiValueArgs ) + + cmake_parse_arguments(ESV "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + if(ESV_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown keywords given to ECM_SETUP_VERSION(): \"${ESV_UNPARSED_ARGUMENTS}\"") + endif() + + set(project_manages_version FALSE) + set(use_project_version FALSE) + # CMP0048 only exists in CMake 3.0.0 and later + if(CMAKE_VERSION VERSION_LESS 3.0.0) + set(project_version_policy "OLD") + else() + cmake_policy(GET CMP0048 project_version_policy) + endif() + if(project_version_policy STREQUAL "NEW") + set(project_manages_version TRUE) + if(_version STREQUAL "PROJECT") + set(use_project_version TRUE) + endif() + elseif(_version STREQUAL "PROJECT") + message(FATAL_ERROR "ecm_setup_version given PROJECT argument, but CMP0048 is not NEW") + endif() + + set(should_set_prefixed_vars TRUE) + if(NOT ESV_VARIABLE_PREFIX) + if(use_project_version) + set(ESV_VARIABLE_PREFIX "${PROJECT_NAME}") + set(should_set_prefixed_vars FALSE) + else() + message(FATAL_ERROR "Required argument PREFIX missing in ECM_SETUP_VERSION() call") + endif() + endif() + + if(use_project_version) + set(_version "${PROJECT_VERSION}") + set(_major "${PROJECT_VERSION_MAJOR}") + set(_minor "${PROJECT_VERSION_MINOR}") + set(_patch "${PROJECT_VERSION_PATCH}") + else() + string(REGEX REPLACE "^0*([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" _major "${_version}") + string(REGEX REPLACE "^[0-9]+\\.0*([0-9]+)\\.[0-9]+.*" "\\1" _minor "${_version}") + string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.0*([0-9]+).*" "\\1" _patch "${_version}") + endif() + + if(NOT ESV_SOVERSION) + set(ESV_SOVERSION ${_major}) + endif() + + if(should_set_prefixed_vars) + set(${ESV_VARIABLE_PREFIX}_VERSION "${_version}") + set(${ESV_VARIABLE_PREFIX}_VERSION_MAJOR ${_major}) + set(${ESV_VARIABLE_PREFIX}_VERSION_MINOR ${_minor}) + set(${ESV_VARIABLE_PREFIX}_VERSION_PATCH ${_patch}) + endif() + + set(${ESV_VARIABLE_PREFIX}_SOVERSION ${ESV_SOVERSION}) + + if(NOT project_manages_version) + set(PROJECT_VERSION "${_version}") + set(PROJECT_VERSION_MAJOR "${_major}") + set(PROJECT_VERSION_MINOR "${_minor}") + set(PROJECT_VERSION_PATCH "${_patch}") + endif() + + # compat + set(PROJECT_VERSION_STRING "${PROJECT_VERSION}") + set(${ESV_VARIABLE_PREFIX}_VERSION_STRING "${${ESV_VARIABLE_PREFIX}_VERSION}") + + if(ESV_VERSION_HEADER) + set(HEADER_PREFIX "${ESV_VARIABLE_PREFIX}") + set(HEADER_VERSION "${_version}") + set(HEADER_VERSION_MAJOR "${_major}") + set(HEADER_VERSION_MINOR "${_minor}") + set(HEADER_VERSION_PATCH "${_patch}") + configure_file("${_ECM_SETUP_VERSION_HEADER_TEMPLATE}" "${ESV_VERSION_HEADER}") + endif() + + if(ESV_PACKAGE_VERSION_FILE) + if(NOT ESV_COMPATIBILITY) + set(ESV_COMPATIBILITY AnyNewerVersion) + endif() + write_basic_package_version_file("${ESV_PACKAGE_VERSION_FILE}" VERSION ${_version} COMPATIBILITY ${ESV_COMPATIBILITY}) + endif() + + if(should_set_prefixed_vars) + set(${ESV_VARIABLE_PREFIX}_VERSION_MAJOR "${${ESV_VARIABLE_PREFIX}_VERSION_MAJOR}" PARENT_SCOPE) + set(${ESV_VARIABLE_PREFIX}_VERSION_MINOR "${${ESV_VARIABLE_PREFIX}_VERSION_MINOR}" PARENT_SCOPE) + set(${ESV_VARIABLE_PREFIX}_VERSION_PATCH "${${ESV_VARIABLE_PREFIX}_VERSION_PATCH}" PARENT_SCOPE) + set(${ESV_VARIABLE_PREFIX}_VERSION "${${ESV_VARIABLE_PREFIX}_VERSION}" PARENT_SCOPE) + endif() + + # always set the soversion + set(${ESV_VARIABLE_PREFIX}_SOVERSION "${${ESV_VARIABLE_PREFIX}_SOVERSION}" PARENT_SCOPE) + + if(NOT project_manages_version) + set(PROJECT_VERSION "${PROJECT_VERSION}" PARENT_SCOPE) + set(PROJECT_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}" PARENT_SCOPE) + set(PROJECT_VERSION_MINOR "${PROJECT_VERSION_MINOR}" PARENT_SCOPE) + set(PROJECT_VERSION_PATCH "${PROJECT_VERSION_PATCH}" PARENT_SCOPE) + endif() + + # always set the compatibility variables + set(PROJECT_VERSION_STRING "${PROJECT_VERSION_STRING}" PARENT_SCOPE) + set(${ESV_VARIABLE_PREFIX}_VERSION_STRING "${${ESV_VARIABLE_PREFIX}_VERSION}" PARENT_SCOPE) + +endfunction() diff --git a/src/libs/3rdparty/qtkeychain/cmake/Modules/QtVersionOption.cmake b/src/libs/3rdparty/qtkeychain/cmake/Modules/QtVersionOption.cmake new file mode 100644 index 00000000000..ea37da22de1 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/cmake/Modules/QtVersionOption.cmake @@ -0,0 +1,36 @@ +# SPDX-FileCopyrightText: 2021 Volker Krause +# +# SPDX-License-Identifier: BSD-3-Clause + +#[=======================================================================[.rst: +QtVersionOption +--------------- + +Adds a build option to select the major Qt version if necessary, +that is, if the major Qt version has not yet been determined otherwise +(e.g. by a corresponding ``find_package()`` call). +This module is typically included by other modules requiring knowledge +about the major Qt version. + +``QT_MAJOR_VERSION`` is defined to either be "5" or "6". + +Since 5.82.0. +#]=======================================================================] + +if (DEFINED QT_MAJOR_VERSION) + return() +endif() + +if (TARGET Qt5::Core) + set(QT_MAJOR_VERSION 5) +elseif (TARGET Qt6::Core) + set(QT_MAJOR_VERSION 6) +else() + option(BUILD_WITH_QT6 "Build against Qt 6" OFF) + + if (BUILD_WITH_QT6) + set(QT_MAJOR_VERSION 6) + else() + set(QT_MAJOR_VERSION 5) + endif() +endif() diff --git a/src/libs/3rdparty/qtkeychain/gnomekeyring.cpp b/src/libs/3rdparty/qtkeychain/gnomekeyring.cpp new file mode 100644 index 00000000000..6347052dcbf --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/gnomekeyring.cpp @@ -0,0 +1,86 @@ +#include "gnomekeyring_p.h" + +const char* GnomeKeyring::GNOME_KEYRING_DEFAULT = nullptr; + +bool GnomeKeyring::isAvailable() +{ + const GnomeKeyring& keyring = instance(); + return keyring.isLoaded() && + keyring.NETWORK_PASSWORD && + keyring.is_available && + keyring.find_password && + keyring.store_password && + keyring.delete_password && + keyring.is_available(); +} + +GnomeKeyring::gpointer GnomeKeyring::store_network_password( + const gchar* keyring, + const gchar* display_name, + const gchar* user, + const gchar* server, + const gchar* type, + const gchar* password, + OperationDoneCallback callback, + gpointer data, + GDestroyNotify destroy_data ) +{ + if ( !isAvailable() ) + return 0; + return instance().store_password( instance().NETWORK_PASSWORD, + keyring, display_name, password, callback, + data, destroy_data, + "user", user, + "server", server, + "type", type, + static_cast(0) ); +} + +GnomeKeyring::gpointer GnomeKeyring::find_network_password( + const gchar* user, const gchar* server, const gchar* type, + OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data ) +{ + if ( !isAvailable() ) + return 0; + + return instance().find_password( instance().NETWORK_PASSWORD, + callback, data, destroy_data, + "user", user, "server", server, "type", type, + static_cast(0) ); +} + +GnomeKeyring::gpointer GnomeKeyring::delete_network_password( const gchar* user, + const gchar* server, + OperationDoneCallback callback, + gpointer data, + GDestroyNotify destroy_data ) +{ + if ( !isAvailable() ) + return 0; + return instance().delete_password( instance().NETWORK_PASSWORD, + callback, data, destroy_data, + "user", user, "server", server, static_cast(0) ); +} + +GnomeKeyring::GnomeKeyring() + : QLibrary(QLatin1String("gnome-keyring"), 0) +{ + static const PasswordSchema schema = { + ITEM_NETWORK_PASSWORD, + {{ "user", ATTRIBUTE_TYPE_STRING }, + { "server", ATTRIBUTE_TYPE_STRING }, + { "type", ATTRIBUTE_TYPE_STRING }, + { 0, static_cast( 0 ) }} + }; + + NETWORK_PASSWORD = &schema; + is_available = reinterpret_cast( resolve( "gnome_keyring_is_available" ) ); + find_password = reinterpret_cast( resolve( "gnome_keyring_find_password" ) ); + store_password = reinterpret_cast( resolve( "gnome_keyring_store_password" ) ); + delete_password = reinterpret_cast( resolve( "gnome_keyring_delete_password" ) ); +} + +GnomeKeyring& GnomeKeyring::instance() { + static GnomeKeyring keyring; + return keyring; +} diff --git a/src/libs/3rdparty/qtkeychain/gnomekeyring_p.h b/src/libs/3rdparty/qtkeychain/gnomekeyring_p.h new file mode 100644 index 00000000000..87c062c375a --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/gnomekeyring_p.h @@ -0,0 +1,94 @@ +#ifndef QTKEYCHAIN_GNOME_P_H +#define QTKEYCHAIN_GNOME_P_H + +#include + +class GnomeKeyring : private QLibrary { + Q_OBJECT + +public: + enum Result { + RESULT_OK, + RESULT_DENIED, + RESULT_NO_KEYRING_DAEMON, + RESULT_ALREADY_UNLOCKED, + RESULT_NO_SUCH_KEYRING, + RESULT_BAD_ARGUMENTS, + RESULT_IO_ERROR, + RESULT_CANCELLED, + RESULT_KEYRING_ALREADY_EXISTS, + RESULT_NO_MATCH + }; + + enum ItemType { + ITEM_GENERIC_SECRET = 0, + ITEM_NETWORK_PASSWORD, + ITEM_NOTE, + ITEM_CHAINED_KEYRING_PASSWORD, + ITEM_ENCRYPTION_KEY_PASSWORD, + ITEM_PK_STORAGE = 0x100 + }; + + enum AttributeType { + ATTRIBUTE_TYPE_STRING, + ATTRIBUTE_TYPE_UINT32 + }; + + typedef char gchar; + typedef void* gpointer; + typedef bool gboolean; + typedef struct { + ItemType item_type; + struct { + const gchar* name; + AttributeType type; + } attributes[32]; + } PasswordSchema; + + typedef void ( *OperationGetStringCallback )( Result result, bool binary, + const char* string, gpointer data ); + typedef void ( *OperationDoneCallback )( Result result, gpointer data ); + typedef void ( *GDestroyNotify )( gpointer data ); + + static const char* GNOME_KEYRING_DEFAULT; + + static bool isAvailable(); + + static gpointer store_network_password( const gchar* keyring, const gchar* display_name, + const gchar* user, const gchar* server, + const gchar* type, const gchar* password, + OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data ); + + static gpointer find_network_password( const gchar* user, const gchar* server, + const gchar* type, + OperationGetStringCallback callback, + gpointer data, GDestroyNotify destroy_data ); + + static gpointer delete_network_password( const gchar* user, const gchar* server, + OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data ); +private: + GnomeKeyring(); + + static GnomeKeyring& instance(); + + const PasswordSchema* NETWORK_PASSWORD; + typedef gboolean ( is_available_fn )( void ); + typedef gpointer ( store_password_fn )( const PasswordSchema* schema, const gchar* keyring, + const gchar* display_name, const gchar* password, + OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data, + ... ); + typedef gpointer ( find_password_fn )( const PasswordSchema* schema, + OperationGetStringCallback callback, gpointer data, GDestroyNotify destroy_data, + ... ); + typedef gpointer ( delete_password_fn )( const PasswordSchema* schema, + OperationDoneCallback callback, gpointer data, GDestroyNotify destroy_data, + ... ); + + is_available_fn* is_available; + find_password_fn* find_password; + store_password_fn* store_password; + delete_password_fn* delete_password; +}; + + +#endif diff --git a/src/libs/3rdparty/qtkeychain/keychain.cpp b/src/libs/3rdparty/qtkeychain/keychain.cpp new file mode 100644 index 00000000000..90ee4eb502a --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/keychain.cpp @@ -0,0 +1,235 @@ +/****************************************************************************** + * Copyright (C) 2011-2015 Frank Osterfeld * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution * + * details, check the accompanying file 'COPYING'. * + *****************************************************************************/ +#include "keychain.h" +#include "keychain_p.h" + +using namespace QKeychain; + +Job::Job( JobPrivate *q, QObject *parent ) + : QObject( parent ) + , d ( q ) { +} + +Job::~Job() { + delete d; +} + +QString Job::service() const { + return d->service; +} + +QSettings* Job::settings() const { + return d->settings; +} + +void Job::setSettings( QSettings* settings ) { + d->settings = settings; +} + +void Job::start() { + QMetaObject::invokeMethod( this, "doStart", Qt::QueuedConnection ); +} + +bool Job::autoDelete() const { + return d->autoDelete; +} + +void Job::setAutoDelete( bool autoDelete ) { + d->autoDelete = autoDelete; +} + +bool Job::insecureFallback() const { + return d->insecureFallback; +} + +void Job::setInsecureFallback( bool insecureFallback ) { + d->insecureFallback = insecureFallback; +} + +void Job::doStart() { + JobExecutor::instance()->enqueue( this ); +} + +void Job::emitFinished() { + emit finished( this ); + if ( d->autoDelete ) + deleteLater(); +} + +void Job::emitFinishedWithError( Error error, const QString& errorString ) { + d->error = error; + d->errorString = errorString; + emitFinished(); +} + +void Job::scheduledStart() { + d->scheduledStart(); +} + +Error Job::error() const { + return d->error; +} + +QString Job::errorString() const { + return d->errorString; +} + +void Job::setError( Error error ) { + d->error = error; +} + +void Job::setErrorString( const QString& errorString ) { + d->errorString = errorString; +} + +ReadPasswordJob::ReadPasswordJob( const QString& service, QObject* parent ) + : Job( new ReadPasswordJobPrivate( service, this ), parent ) { + +} + +ReadPasswordJob::~ReadPasswordJob() { +} + +QString ReadPasswordJob::textData() const { + return QString::fromUtf8( d->data ); +} + +QByteArray ReadPasswordJob::binaryData() const { + return d->data; +} + +QString Job::key() const { + return d->key; +} + +void Job::setKey( const QString& key_ ) { + d->key = key_; +} + +WritePasswordJob::WritePasswordJob( const QString& service, QObject* parent ) + : Job( new WritePasswordJobPrivate( service, this ), parent ) { +} + +WritePasswordJob::~WritePasswordJob() { +} + +void WritePasswordJob::setBinaryData( const QByteArray& data ) { + d->data = data; + d->mode = JobPrivate::Binary; +} + +void WritePasswordJob::setTextData( const QString& data ) { + d->data = data.toUtf8(); + d->mode = JobPrivate::Text; +} + +DeletePasswordJob::DeletePasswordJob( const QString& service, QObject* parent ) + : Job( new DeletePasswordJobPrivate( service, this ), parent ) { +} + +DeletePasswordJob::~DeletePasswordJob() { +} + +DeletePasswordJobPrivate::DeletePasswordJobPrivate(const QString &service_, DeletePasswordJob *qq) : + JobPrivate(service_, qq) { + +} + +JobExecutor::JobExecutor() + : QObject( 0 ) + , m_jobRunning( false ) { +} + +void JobExecutor::enqueue( Job* job ) { + m_queue.enqueue( job ); + startNextIfNoneRunning(); +} + +void JobExecutor::startNextIfNoneRunning() { + if ( m_queue.isEmpty() || m_jobRunning ) + return; + QPointer next; + while ( !next && !m_queue.isEmpty() ) { + next = m_queue.dequeue(); + } + if ( next ) { + connect( next, SIGNAL(finished(QKeychain::Job*)), this, SLOT(jobFinished(QKeychain::Job*)) ); + connect( next, SIGNAL(destroyed(QObject*)), this, SLOT(jobDestroyed(QObject*)) ); + m_jobRunning = true; + next->scheduledStart(); + } +} + +void JobExecutor::jobDestroyed( QObject* object ) { + Job* job = static_cast(object); + Q_UNUSED( object ) // for release mode + job->disconnect( this ); + m_jobRunning = false; + startNextIfNoneRunning(); +} + +void JobExecutor::jobFinished( Job* job ) { + Q_UNUSED( job ) // for release mode + job->disconnect( this ); + m_jobRunning = false; + startNextIfNoneRunning(); +} + +JobExecutor* JobExecutor::s_instance = 0; + +JobExecutor* JobExecutor::instance() { + if ( !s_instance ) + s_instance = new JobExecutor; + return s_instance; +} + +ReadPasswordJobPrivate::ReadPasswordJobPrivate(const QString &service_, ReadPasswordJob *qq) : + JobPrivate(service_, qq) { + +} + +JobPrivate::JobPrivate(const QString &service_, Job *qq) + : q(qq) + , mode( Text ) + , error( NoError ) + , service( service_ ) + , autoDelete( true ) + , insecureFallback( false ) +{ +} + +QString JobPrivate::modeToString(Mode m) +{ + switch (m) { + case Text: + return QLatin1String("Text"); + case Binary: + return QLatin1String("Binary"); + } + + Q_ASSERT_X(false, Q_FUNC_INFO, "Unhandled Mode value"); + return QString(); +} + +JobPrivate::Mode JobPrivate::stringToMode(const QString& s) +{ + if (s == QLatin1String("Text") || s == QLatin1String("1")) + return Text; + if (s == QLatin1String("Binary") || s == QLatin1String("2")) + return Binary; + + qCritical("Unexpected mode string '%s'", qPrintable(s)); + + return Text; +} + +WritePasswordJobPrivate::WritePasswordJobPrivate(const QString &service_, WritePasswordJob *qq) : + JobPrivate(service_, qq) { + +} diff --git a/src/libs/3rdparty/qtkeychain/keychain.h b/src/libs/3rdparty/qtkeychain/keychain.h new file mode 100644 index 00000000000..8c006cbcddb --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/keychain.h @@ -0,0 +1,282 @@ +/****************************************************************************** + * Copyright (C) 2011-2015 Frank Osterfeld * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution * + * details, check the accompanying file 'COPYING'. * + *****************************************************************************/ +#ifndef KEYCHAIN_H +#define KEYCHAIN_H + +#if !defined(QTKEYCHAIN_NO_EXPORT) +#include "qkeychain_export.h" +#else +#define QKEYCHAIN_EXPORT +#endif + +#include +#include + +class QSettings; + +#define QTKEYCHAIN_VERSION 0x000100 + +namespace QKeychain { + +/** + * Error codes + */ +enum Error { + NoError=0, /**< No error occurred, operation was successful */ + EntryNotFound, /**< For the given key no data was found */ + CouldNotDeleteEntry, /**< Could not delete existing secret data */ + AccessDeniedByUser, /**< User denied access to keychain */ + AccessDenied, /**< Access denied for other reasons */ + NoBackendAvailable, /**< No platform-specific keychain service available */ + NotImplemented, /**< Not implemented on platform */ + OtherError /**< Something else went wrong (errorString() might provide details) */ +}; + +class JobExecutor; +class JobPrivate; + +/** + * @brief Abstract base class for all QKeychain jobs. + */ +class QKEYCHAIN_EXPORT Job : public QObject { + Q_OBJECT +public: + ~Job() override; + + /** + * @return The QSettings instance used as plaintext storage if insecureFallback() is true. + * @see setSettings() + * @see insecureFallback() + */ + QSettings* settings() const; + + /** + * @return Set the QSettings instance that will be used as plaintext storage if insecureFallback() is true. + * @see settings() + * @see insecureFallback() + */ + void setSettings( QSettings* settings ); + + /** + * Call this method to start the job. + * Typically you want to connect some slot to the finished() signal first: + * + * \code + * SomeClass::startJob() + * { + * connect(job, &Job::finished, this, &SomeClass::slotJobFinished); + * job->start(); + * } + * + * SomeClass::slotJobFinished(Job *job) + * { + * if (job->error()) { + * // handle error + * } else { + * // do job-specific stuff + * } + * } + * \endcode + * + * @see finished() + */ + void start(); + + QString service() const; + + /** + * @note Call this method only after finished() has been emitted. + * @return The error code of the job (0 if no error). + */ + Error error() const; + + /** + * @return An error message that might provide details if error() returns OtherError. + */ + QString errorString() const; + + /** + * @return Whether this job autodeletes itself once finished() has been emitted. Default is true. + * @see setAutoDelete() + */ + bool autoDelete() const; + + /** + * Set whether this job should autodelete itself once finished() has been emitted. + * @see autoDelete() + */ + void setAutoDelete( bool autoDelete ); + + /** + * @return Whether this job will use plaintext storage on unsupported platforms. Default is false. + * @see setInsecureFallback() + */ + bool insecureFallback() const; + + /** + * Set whether this job should use plaintext storage on unsupported platforms. + * @see insecureFallback() + */ + void setInsecureFallback( bool insecureFallback ); + + /** + * @return The string used as key by this job. + * @see setKey() + */ + QString key() const; + + /** + * Set the @p key that this job will use to read or write data from/to the keychain. + * The key can be an empty string. + * @see key() + */ + void setKey( const QString& key ); + + void emitFinished(); + void emitFinishedWithError(Error, const QString& errorString); + +Q_SIGNALS: + /** + * Emitted when this job is finished. + * You can connect to this signal to be notified about the job's completion. + * @see start() + */ + void finished( QKeychain::Job* ); + +protected: + explicit Job( JobPrivate *q, QObject* parent=nullptr ); + Q_INVOKABLE void doStart(); + +private: + void setError( Error error ); + void setErrorString( const QString& errorString ); + + void scheduledStart(); + +protected: + JobPrivate* const d; + +friend class JobExecutor; +friend class JobPrivate; +friend class ReadPasswordJobPrivate; +friend class WritePasswordJobPrivate; +friend class DeletePasswordJobPrivate; +}; + +class ReadPasswordJobPrivate; + +/** + * @brief Job for reading secrets from the keychain. + * You can use a ReadPasswordJob to read passwords or binary data from the keychain. + * This job requires a "service" string, which is basically a namespace of keys within the keychain. + * This means that you can read all the pairs stored in the same service string. + */ +class QKEYCHAIN_EXPORT ReadPasswordJob : public Job { + Q_OBJECT +public: + /** + * Create a new ReadPasswordJob. + * @param service The service string used by this job (can be empty). + * @param parent The parent of this job. + */ + explicit ReadPasswordJob( const QString& service, QObject* parent=nullptr ); + ~ReadPasswordJob() override; + + /** + * @return The binary data stored as value of this job's key(). + * @see Job::key() + */ + QByteArray binaryData() const; + + /** + * @return The string stored as value of this job's key(). + * @see Job::key() + * @warning Returns meaningless data if the data was stored as binary data. + * @see WritePasswordJob::setTextData() + */ + QString textData() const; + +private: + friend class QKeychain::ReadPasswordJobPrivate; +}; + +class WritePasswordJobPrivate; + +/** + * @brief Job for writing secrets to the keychain. + * You can use a WritePasswordJob to store passwords or binary data in the keychain. + * This job requires a "service" string, which is basically a namespace of keys within the keychain. + * This means that you can store different pairs under the same service string. + */ +class QKEYCHAIN_EXPORT WritePasswordJob : public Job { + Q_OBJECT +public: + /** + * Create a new WritePasswordJob. + * @param service The service string used by this job (can be empty). + * @param parent The parent of this job. + */ + explicit WritePasswordJob( const QString& service, QObject* parent=nullptr ); + ~WritePasswordJob() override; + + /** + * Set the @p data that the job will store in the keychain as binary data. + * @warning setBinaryData() and setTextData() are mutually exclusive. + */ + void setBinaryData( const QByteArray& data ); + + /** + * Set the @p data that the job will store in the keychain as string. + * Typically @p data is a password. + * @warning setBinaryData() and setTextData() are mutually exclusive. + */ + void setTextData( const QString& data ); + +private: + + friend class QKeychain::WritePasswordJobPrivate; +}; + +class DeletePasswordJobPrivate; + +/** + * @brief Job for deleting secrets from the keychain. + * You can use a DeletePasswordJob to delete passwords or binary data from the keychain. + * This job requires a "service" string, which is basically a namespace of keys within the keychain. + * This means that you can delete all the pairs stored in the same service string. + */ +class QKEYCHAIN_EXPORT DeletePasswordJob : public Job { + Q_OBJECT +public: + /** + * Create a new DeletePasswordJob. + * @param service The service string used by this job (can be empty). + * @param parent The parent of this job. + */ + explicit DeletePasswordJob( const QString& service, QObject* parent=nullptr ); + ~DeletePasswordJob() override; + +private: + friend class QKeychain::DeletePasswordJobPrivate; +}; + +/** + * Checks whether there is a viable secure backend available. + * This particularly matters on UNIX platforms where multiple different backends + * exist and none might be available. + * + * Note that using the insecure fallback will work even if no secure backend is available. + * + * @since 0.14.0 + */ +QKEYCHAIN_EXPORT bool isAvailable(); + +} // namespace QtKeychain + +#endif diff --git a/src/libs/3rdparty/qtkeychain/keychain_apple.mm b/src/libs/3rdparty/qtkeychain/keychain_apple.mm new file mode 100644 index 00000000000..f9a8266be05 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/keychain_apple.mm @@ -0,0 +1,263 @@ +/****************************************************************************** + * Copyright (C) 2016 Mathias Hasselmann * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution * + * details, check the accompanying file 'COPYING'. * + *****************************************************************************/ + +#include "keychain_p.h" + +#import +#import + +using namespace QKeychain; + +struct ErrorDescription +{ + QKeychain::Error code; + QString message; + + ErrorDescription(QKeychain::Error code, const QString &message) + : code(code), message(message) {} + + static ErrorDescription fromStatus(OSStatus status) + { + switch(status) { + case errSecSuccess: + return ErrorDescription(QKeychain::NoError, Job::tr("No error")); + case errSecItemNotFound: + return ErrorDescription(QKeychain::EntryNotFound, Job::tr("The specified item could not be found in the keychain")); + case errSecUserCanceled: + return ErrorDescription(QKeychain::AccessDeniedByUser, Job::tr("User canceled the operation")); + case errSecInteractionNotAllowed: + return ErrorDescription(QKeychain::AccessDenied, Job::tr("User interaction is not allowed")); + case errSecNotAvailable: + return ErrorDescription(QKeychain::AccessDenied, Job::tr("No keychain is available. You may need to restart your computer")); + case errSecAuthFailed: + return ErrorDescription(QKeychain::AccessDenied, Job::tr("The user name or passphrase you entered is not correct")); + case errSecVerifyFailed: + return ErrorDescription(QKeychain::AccessDenied, Job::tr("A cryptographic verification failure has occurred")); + case errSecUnimplemented: + return ErrorDescription(QKeychain::NotImplemented, Job::tr("Function or operation not implemented")); + case errSecIO: + return ErrorDescription(QKeychain::OtherError, Job::tr("I/O error")); + case errSecOpWr: + return ErrorDescription(QKeychain::OtherError, Job::tr("Already open with with write permission")); + case errSecParam: + return ErrorDescription(QKeychain::OtherError, Job::tr("Invalid parameters passed to a function")); + case errSecAllocate: + return ErrorDescription(QKeychain::OtherError, Job::tr("Failed to allocate memory")); + case errSecBadReq: + return ErrorDescription(QKeychain::OtherError, Job::tr("Bad parameter or invalid state for operation")); + case errSecInternalComponent: + return ErrorDescription(QKeychain::OtherError, Job::tr("An internal component failed")); + case errSecDuplicateItem: + return ErrorDescription(QKeychain::OtherError, Job::tr("The specified item already exists in the keychain")); + case errSecDecode: + return ErrorDescription(QKeychain::OtherError, Job::tr("Unable to decode the provided data")); + } + + return ErrorDescription(QKeychain::OtherError, Job::tr("Unknown error")); + } +}; + +@interface AppleKeychainInterface : NSObject + +- (instancetype)initWithJob:(Job *)job andPrivateJob:(JobPrivate *)privateJob; +- (void)keychainTaskFinished; +- (void)keychainReadTaskFinished:(NSData *)retrievedData; +- (void)keychainTaskFinishedWithError:(OSStatus)status descriptiveMessage:(NSString *)descriptiveMessage; + +@end + +@interface AppleKeychainInterface() +{ + QPointer _job; + QPointer _privateJob; +} +@end + +@implementation AppleKeychainInterface + +- (instancetype)initWithJob:(Job *)job andPrivateJob:(JobPrivate *)privateJob +{ + self = [super init]; + if (self) { + _job = job; + _privateJob = privateJob; + } + return self; +} + +- (void)dealloc +{ + [NSNotificationCenter.defaultCenter removeObserver:self]; + [super dealloc]; +} + +- (void)keychainTaskFinished +{ + if (_job) { + _job->emitFinished(); + } +} + +- (void)keychainReadTaskFinished:(NSData *)retrievedData +{ + _privateJob->data.clear(); + _privateJob->mode = JobPrivate::Binary; + + if (retrievedData != nil) { + if (_privateJob) { + _privateJob->data = QByteArray::fromNSData(retrievedData); + } + } + + if (_job) { + _job->emitFinished(); + } +} + +- (void)keychainTaskFinishedWithError:(OSStatus)status descriptiveMessage:(NSString *)descriptiveMessage +{ + const auto localisedDescriptiveMessage = Job::tr([descriptiveMessage UTF8String]); + + const ErrorDescription error = ErrorDescription::fromStatus(status); + const auto fullMessage = localisedDescriptiveMessage.isEmpty() ? error.message : QStringLiteral("%1: %2").arg(localisedDescriptiveMessage, error.message); + + if (_job) { + _job->emitFinishedWithError(error.code, fullMessage); + } +} + +@end + + +static void StartReadPassword(const QString &service, const QString &key, AppleKeychainInterface * const interface) +{ + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + NSDictionary * const query = @{ + (__bridge NSString *)kSecClass: (__bridge NSString *)kSecClassGenericPassword, + (__bridge NSString *)kSecAttrService: service.toNSString(), + (__bridge NSString *)kSecAttrAccount: key.toNSString(), + (__bridge NSString *)kSecReturnData: @YES, + }; + + CFTypeRef dataRef = nil; + const OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef) query, &dataRef); + + if (status == errSecSuccess) { + const CFDataRef castedDataRef = (CFDataRef)dataRef; + NSData * const data = (__bridge NSData *)castedDataRef; + dispatch_async(dispatch_get_main_queue(), ^{ + [interface keychainReadTaskFinished:data]; + [interface release]; + }); + } else { + NSString * const descriptiveErrorString = @"Could not retrieve private key from keystore"; + dispatch_async(dispatch_get_main_queue(), ^{ + [interface keychainTaskFinishedWithError:status descriptiveMessage:descriptiveErrorString]; + [interface release]; + }); + } + + if (dataRef) { + CFRelease(dataRef); + } + }); +} + +static void StartWritePassword(const QString &service, const QString &key, const QByteArray &data, AppleKeychainInterface * const interface) +{ + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + NSDictionary * const query = @{ + (__bridge NSString *)kSecClass: (__bridge NSString *)kSecClassGenericPassword, + (__bridge NSString *)kSecAttrService: service.toNSString(), + (__bridge NSString *)kSecAttrAccount: key.toNSString(), + }; + + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, nil); + + if (status == errSecSuccess) { + NSDictionary * const update = @{ + (__bridge NSString *)kSecValueData: data.toNSData(), + }; + + status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)update); + } else { + NSDictionary * const insert = @{ + (__bridge NSString *)kSecClass: (__bridge NSString *)kSecClassGenericPassword, + (__bridge NSString *)kSecAttrService: service.toNSString(), + (__bridge NSString *)kSecAttrAccount: key.toNSString(), + (__bridge NSString *)kSecValueData: data.toNSData(), + }; + + status = SecItemAdd((__bridge const CFDictionaryRef)insert, nil); + } + + if (status == errSecSuccess) { + dispatch_async(dispatch_get_main_queue(), ^{ + [interface keychainTaskFinished]; + [interface release]; + }); + } else { + NSString * const descriptiveErrorString = @"Could not store data in settings"; + + dispatch_async(dispatch_get_main_queue(), ^{ + [interface keychainTaskFinishedWithError:status descriptiveMessage:descriptiveErrorString]; + [interface release]; + }); + } + }); +} + +static void StartDeletePassword(const QString &service, const QString &key, AppleKeychainInterface * const interface) +{ + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + NSDictionary * const query = @{ + (__bridge NSString *)kSecClass: (__bridge NSString *)kSecClassGenericPassword, + (__bridge NSString *)kSecAttrService: service.toNSString(), + (__bridge NSString *)kSecAttrAccount: key.toNSString(), + }; + + const OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query); + + if (status == errSecSuccess) { + dispatch_async(dispatch_get_main_queue(), ^{ + [interface keychainTaskFinished]; + [interface release]; + }); + } else { + NSString * const descriptiveErrorString = @"Could not remove private key from keystore"; + dispatch_async(dispatch_get_main_queue(), ^{ + [interface keychainTaskFinishedWithError:status descriptiveMessage:descriptiveErrorString]; + [interface release]; + }); + } + }); +} + +void ReadPasswordJobPrivate::scheduledStart() +{ + AppleKeychainInterface * const interface = [[AppleKeychainInterface alloc] initWithJob:q andPrivateJob:this]; + StartReadPassword(service, key, interface); +} + +void WritePasswordJobPrivate::scheduledStart() +{ + AppleKeychainInterface * const interface = [[AppleKeychainInterface alloc] initWithJob:q andPrivateJob:this]; + StartWritePassword(service, key, data, interface); +} + +void DeletePasswordJobPrivate::scheduledStart() +{ + AppleKeychainInterface * const interface = [[AppleKeychainInterface alloc] initWithJob:q andPrivateJob:this]; + StartDeletePassword(service, key, interface); +} + +bool QKeychain::isAvailable() +{ + return true; +} diff --git a/src/libs/3rdparty/qtkeychain/keychain_p.h b/src/libs/3rdparty/qtkeychain/keychain_p.h new file mode 100644 index 00000000000..a66cb423d1c --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/keychain_p.h @@ -0,0 +1,167 @@ +/****************************************************************************** + * Copyright (C) 2011-2015 Frank Osterfeld * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution * + * details, check the accompanying file 'COPYING'. * + *****************************************************************************/ +#ifndef KEYCHAIN_P_H +#define KEYCHAIN_P_H + +#include +#include +#include +#include +#include + +#if defined(KEYCHAIN_DBUS) + +#include + +#include "kwallet_interface.h" +#else + +class QDBusPendingCallWatcher; + +#endif + +#include "keychain.h" + +namespace QKeychain { + +class JobExecutor; + +class JobPrivate : public QObject { + Q_OBJECT +public: + enum Mode { + Text, + Binary + }; + + virtual void scheduledStart() = 0; + + static QString modeToString(Mode m); + static Mode stringToMode(const QString& s); + + Job* const q; + Mode mode; + QByteArray data; + +#if defined(KEYCHAIN_DBUS) + org::kde::KWallet* iface; + int walletHandle; + + static void gnomeKeyring_readCb( int result, const char* string, JobPrivate* data ); + static void gnomeKeyring_writeCb( int result, JobPrivate* self ); + + virtual void fallbackOnError(const QDBusError& err) = 0; + +protected Q_SLOTS: + void kwalletWalletFound( QDBusPendingCallWatcher* watcher ); + virtual void kwalletFinished( QDBusPendingCallWatcher* watcher ); + virtual void kwalletOpenFinished( QDBusPendingCallWatcher* watcher ); +#else + void kwalletWalletFound( QDBusPendingCallWatcher* ) {} + virtual void kwalletFinished( QDBusPendingCallWatcher* ) {} + virtual void kwalletOpenFinished( QDBusPendingCallWatcher* ) {} +#endif + +protected: + JobPrivate( const QString& service_, Job *q ); + +protected: + QKeychain::Error error; + QString errorString; + QString service; + bool autoDelete; + bool insecureFallback; + QPointer settings; + QString key; + +friend class Job; +friend class JobExecutor; +friend class ReadPasswordJob; +friend class WritePasswordJob; +friend class PlainTextStore; +}; + +class ReadPasswordJobPrivate : public JobPrivate { + Q_OBJECT +public: + explicit ReadPasswordJobPrivate( const QString &service_, ReadPasswordJob* qq ); + void scheduledStart() override; + +#if defined(KEYCHAIN_DBUS) + void fallbackOnError(const QDBusError& err) override; + +private Q_SLOTS: + void kwalletOpenFinished( QDBusPendingCallWatcher* watcher ) override; + void kwalletEntryTypeFinished( QDBusPendingCallWatcher* watcher ); + void kwalletFinished( QDBusPendingCallWatcher* watcher ) override; +#else //moc's too dumb to respect above macros, so just define empty slot implementations +private Q_SLOTS: + void kwalletOpenFinished( QDBusPendingCallWatcher* ) override {} + void kwalletEntryTypeFinished( QDBusPendingCallWatcher* ) {} + void kwalletFinished( QDBusPendingCallWatcher* ) override {} +#endif + + friend class ReadPasswordJob; +}; + +class WritePasswordJobPrivate : public JobPrivate { + Q_OBJECT +public: + explicit WritePasswordJobPrivate( const QString &service_, WritePasswordJob* qq ); + void scheduledStart() override; + +#if defined(KEYCHAIN_DBUS) + void fallbackOnError(const QDBusError& err) override; +#endif + + friend class WritePasswordJob; +}; + +class DeletePasswordJobPrivate : public JobPrivate { + Q_OBJECT +public: + explicit DeletePasswordJobPrivate( const QString &service_, DeletePasswordJob* qq ); + + void scheduledStart() override; + +#if defined(KEYCHAIN_DBUS) + void fallbackOnError(const QDBusError& err) override; +#endif + +protected: + void doStart(); + + friend class DeletePasswordJob; +}; + +class JobExecutor : public QObject { + Q_OBJECT +public: + + static JobExecutor* instance(); + + void enqueue( Job* job ); + +private: + explicit JobExecutor(); + void startNextIfNoneRunning(); + +private Q_SLOTS: + void jobFinished( QKeychain::Job* ); + void jobDestroyed( QObject* object ); + +private: + static JobExecutor* s_instance; + QQueue > m_queue; + bool m_jobRunning; +}; + +} + +#endif // KEYCHAIN_P_H diff --git a/src/libs/3rdparty/qtkeychain/keychain_unix.cpp b/src/libs/3rdparty/qtkeychain/keychain_unix.cpp new file mode 100644 index 00000000000..a3e83a96875 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/keychain_unix.cpp @@ -0,0 +1,633 @@ +/****************************************************************************** + * Copyright (C) 2011-2015 Frank Osterfeld * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution * + * details, check the accompanying file 'COPYING'. * + *****************************************************************************/ +#include "keychain_p.h" +#include "gnomekeyring_p.h" +#include "libsecret_p.h" +#include "plaintextstore_p.h" + +#include + +using namespace QKeychain; + +enum KeyringBackend { + Backend_LibSecretKeyring, + Backend_GnomeKeyring, + Backend_Kwallet4, + Backend_Kwallet5, + Backend_Kwallet6, +}; + +enum DesktopEnvironment { + DesktopEnv_Gnome, + DesktopEnv_Kde4, + DesktopEnv_Plasma5, + DesktopEnv_Plasma6, + DesktopEnv_Unity, + DesktopEnv_Xfce, + DesktopEnv_Other +}; + +static constexpr const char KWALLET6_DBUS_IFACE[] = "org.kde.kwalletd6"; +static constexpr const char KWALLET6_DBUS_PATH[] = "/modules/kwalletd6"; +static constexpr const char KWALLET5_DBUS_IFACE[] = "org.kde.kwalletd5"; +static constexpr const char KWALLET5_DBUS_PATH[] = "/modules/kwalletd5"; +static constexpr const char KWALLET4_DBUS_IFACE[] = "org.kde.kwalletd"; +static constexpr const char KWALLET4_DBUS_PATH[] = "/modules/kwalletd"; + +// the following detection algorithm is derived from chromium, +// licensed under BSD, see base/nix/xdg_util.cc + +static DesktopEnvironment getKdeVersion() { + QByteArray value = qgetenv("KDE_SESSION_VERSION"); + if ( value == "6" ) { + return DesktopEnv_Plasma6; + } else if ( value == "5" ) { + return DesktopEnv_Plasma5; + } else if (value == "4" ) { + return DesktopEnv_Kde4; + } else { + // most likely KDE3 + return DesktopEnv_Other; + } +} + +static DesktopEnvironment detectDesktopEnvironment() { + QByteArray xdgCurrentDesktop = qgetenv("XDG_CURRENT_DESKTOP"); + if ( xdgCurrentDesktop == "GNOME" ) { + return DesktopEnv_Gnome; + } else if ( xdgCurrentDesktop == "Unity" ) { + return DesktopEnv_Unity; + } else if ( xdgCurrentDesktop == "KDE" ) { + return getKdeVersion(); + } else if ( xdgCurrentDesktop == "XFCE" ) { + return DesktopEnv_Xfce; + } + + QByteArray desktopSession = qgetenv("DESKTOP_SESSION"); + if ( desktopSession == "gnome" ) { + return DesktopEnv_Gnome; + } else if ( desktopSession == "kde" ) { + return getKdeVersion(); + } else if ( desktopSession == "kde4" ) { + return DesktopEnv_Kde4; + } else if ( desktopSession.contains("xfce") || desktopSession == "xubuntu" ) { + return DesktopEnv_Xfce; + } + + if ( !qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty() ) { + return DesktopEnv_Gnome; + } else if ( !qgetenv("KDE_FULL_SESSION").isEmpty() ) { + return getKdeVersion(); + } + + return DesktopEnv_Other; +} + +static bool isKwalletAvailable(const char *dbusIface, const char *dbusPath) +{ + if (!QDBusConnection::sessionBus().isConnected()) + return false; + + org::kde::KWallet iface( + QLatin1String(dbusIface), + QLatin1String(dbusPath), + QDBusConnection::sessionBus()); + + // At this point iface.isValid() can return false even though the + // interface is activatable by making a call. Hence we check whether + // a wallet can be opened. + + iface.setTimeout(500); + QDBusMessage reply = iface.call(QLatin1String("networkWallet")); + return reply.type() == QDBusMessage::ReplyMessage; +} + +static KeyringBackend detectKeyringBackend() +{ + /* The secret service dbus api, accessible through libsecret, is supposed + * to unify password services. + * + * Unfortunately at the time of Kubuntu 18.04 the secret service backend + * in KDE is gnome-keyring-daemon - using it has several complications: + * - the default collection isn't opened on session start, so users need + * to manually unlock it when the first application uses it + * - it's separate from the kwallet5 keyring, so switching to it means the + * existing keyring data can't be accessed anymore + * + * Thus we still prefer kwallet backends on KDE even if libsecret is + * available. + */ + + switch (detectDesktopEnvironment()) { + case DesktopEnv_Kde4: + return Backend_Kwallet4; + + case DesktopEnv_Plasma5: + if (isKwalletAvailable(KWALLET5_DBUS_IFACE, KWALLET5_DBUS_PATH)) { + return Backend_Kwallet5; + } + if (LibSecretKeyring::isAvailable()) { + return Backend_LibSecretKeyring; + } + if (GnomeKeyring::isAvailable()) { + return Backend_GnomeKeyring; + } + // During startup the keychain backend might just not have started yet + return Backend_Kwallet5; + + case DesktopEnv_Plasma6: + if (isKwalletAvailable(KWALLET6_DBUS_IFACE, KWALLET6_DBUS_PATH)) { + return Backend_Kwallet6; + } + if (LibSecretKeyring::isAvailable()) { + return Backend_LibSecretKeyring; + } + if (GnomeKeyring::isAvailable()) { + return Backend_GnomeKeyring; + } + // During startup the keychain backend might just not have started yet + return Backend_Kwallet6; + + case DesktopEnv_Gnome: + case DesktopEnv_Unity: + case DesktopEnv_Xfce: + case DesktopEnv_Other: + default: + if (LibSecretKeyring::isAvailable()) { + return Backend_LibSecretKeyring; + } + if (GnomeKeyring::isAvailable()) { + return Backend_GnomeKeyring; + } + if (isKwalletAvailable(KWALLET6_DBUS_IFACE, KWALLET6_DBUS_PATH)) { + return Backend_Kwallet6; + } + if (isKwalletAvailable(KWALLET5_DBUS_IFACE, KWALLET5_DBUS_PATH)) { + return Backend_Kwallet5; + } + // During startup the keychain backend might just not have started yet + // + // This doesn't need to be libsecret because LibSecretKeyring::isAvailable() + // only fails if the libsecret shared library couldn't be loaded. In contrast + // to that GnomeKeyring::isAvailable() can return false if the shared library + // *was* loaded but its libgnome_keyring::is_available() returned false. + // + // In the future there should be a difference between "API available" and + // "keychain available". + return Backend_GnomeKeyring; + } + +} + +static KeyringBackend getKeyringBackend() +{ + static KeyringBackend backend = detectKeyringBackend(); + return backend; +} + +static void kwalletReadPasswordScheduledStartImpl(const char * service, const char * path, ReadPasswordJobPrivate * priv) { + if ( QDBusConnection::sessionBus().isConnected() ) + { + priv->iface = new org::kde::KWallet( QLatin1String(service), QLatin1String(path), QDBusConnection::sessionBus(), priv ); + const QDBusPendingReply reply = priv->iface->networkWallet(); + QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, priv ); + priv->connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), priv, SLOT(kwalletWalletFound(QDBusPendingCallWatcher*)) ); + } + else + { + // D-Bus is not reachable so none can tell us something about KWalletd + QDBusError err( QDBusError::NoServer, ReadPasswordJobPrivate::tr("D-Bus is not running") ); + priv->fallbackOnError( err ); + } +} + +void ReadPasswordJobPrivate::scheduledStart() { + switch ( getKeyringBackend() ) { + case Backend_LibSecretKeyring: { + if ( !LibSecretKeyring::findPassword(key, q->service(), this) ) { + q->emitFinishedWithError( OtherError, tr("Unknown error") ); + } + } break; + case Backend_GnomeKeyring: + this->mode = JobPrivate::Text; + if ( !GnomeKeyring::find_network_password( key.toUtf8().constData(), + q->service().toUtf8().constData(), + "plaintext", + reinterpret_cast( &JobPrivate::gnomeKeyring_readCb ), + this, 0 ) ) + q->emitFinishedWithError( OtherError, tr("Unknown error") ); + break; + + case Backend_Kwallet4: + kwalletReadPasswordScheduledStartImpl(KWALLET4_DBUS_IFACE, KWALLET4_DBUS_PATH, this); + break; + case Backend_Kwallet5: + kwalletReadPasswordScheduledStartImpl(KWALLET5_DBUS_IFACE, KWALLET5_DBUS_PATH, this); + break; + case Backend_Kwallet6: + kwalletReadPasswordScheduledStartImpl(KWALLET6_DBUS_IFACE, KWALLET6_DBUS_PATH, this); + break; + } +} + +void JobPrivate::kwalletWalletFound(QDBusPendingCallWatcher *watcher) +{ + watcher->deleteLater(); + const QDBusPendingReply reply = *watcher; + const QDBusPendingReply pendingReply = iface->open( reply.value(), 0, q->service() ); + QDBusPendingCallWatcher* pendingWatcher = new QDBusPendingCallWatcher( pendingReply, this ); + connect( pendingWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(kwalletOpenFinished(QDBusPendingCallWatcher*)) ); +} + +static QPair mapGnomeKeyringError( int result ) +{ + Q_ASSERT( result != GnomeKeyring::RESULT_OK ); + + switch ( result ) { + case GnomeKeyring::RESULT_DENIED: + return qMakePair( AccessDenied, QObject::tr("Access to keychain denied") ); + case GnomeKeyring::RESULT_NO_KEYRING_DAEMON: + return qMakePair( NoBackendAvailable, QObject::tr("No keyring daemon") ); + case GnomeKeyring::RESULT_ALREADY_UNLOCKED: + return qMakePair( OtherError, QObject::tr("Already unlocked") ); + case GnomeKeyring::RESULT_NO_SUCH_KEYRING: + return qMakePair( OtherError, QObject::tr("No such keyring") ); + case GnomeKeyring::RESULT_BAD_ARGUMENTS: + return qMakePair( OtherError, QObject::tr("Bad arguments") ); + case GnomeKeyring::RESULT_IO_ERROR: + return qMakePair( OtherError, QObject::tr("I/O error") ); + case GnomeKeyring::RESULT_CANCELLED: + return qMakePair( OtherError, QObject::tr("Cancelled") ); + case GnomeKeyring::RESULT_KEYRING_ALREADY_EXISTS: + return qMakePair( OtherError, QObject::tr("Keyring already exists") ); + case GnomeKeyring::RESULT_NO_MATCH: + return qMakePair( EntryNotFound, QObject::tr("No match") ); + default: + break; + } + + return qMakePair( OtherError, QObject::tr("Unknown error") ); +} + +void JobPrivate::gnomeKeyring_readCb( int result, const char* string, JobPrivate* self ) +{ + if ( result == GnomeKeyring::RESULT_OK ) { + if (self->mode == JobPrivate::Text) + self->data = QByteArray(string); + else + self->data = QByteArray::fromBase64(string); + + self->q->emitFinished(); + } else if (self->mode == JobPrivate::Text) { + self->mode = JobPrivate::Binary; + if ( !GnomeKeyring::find_network_password( self->key.toUtf8().constData(), + self->q->service().toUtf8().constData(), + "base64", + reinterpret_cast( &JobPrivate::gnomeKeyring_readCb ), + self, 0 ) ) + self->q->emitFinishedWithError( OtherError, tr("Unknown error") ); + } else { + const QPair errorResult = mapGnomeKeyringError( result ); + self->q->emitFinishedWithError( errorResult.first, errorResult.second ); + } +} + +void ReadPasswordJobPrivate::fallbackOnError(const QDBusError& err ) +{ + PlainTextStore plainTextStore( q->service(), q->settings() ); + + if ( q->insecureFallback() && plainTextStore.contains( key ) ) { + mode = plainTextStore.readMode( key ); + data = plainTextStore.readData( key ); + + if ( plainTextStore.error() != NoError ) + q->emitFinishedWithError( plainTextStore.error(), plainTextStore.errorString() ); + else + q->emitFinished(); + } else { + if ( err.type() == QDBusError::ServiceUnknown ) //KWalletd not running + q->emitFinishedWithError( NoBackendAvailable, tr("No keychain service available") ); + else + q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) ); + } +} + +void ReadPasswordJobPrivate::kwalletOpenFinished( QDBusPendingCallWatcher* watcher ) { + watcher->deleteLater(); + const QDBusPendingReply reply = *watcher; + + if ( reply.isError() ) { + fallbackOnError( reply.error() ); + return; + } + + PlainTextStore plainTextStore( q->service(), q->settings() ); + + if ( plainTextStore.contains( key ) ) { + // We previously stored data in the insecure QSettings, but now have KWallet available. + // Do the migration + + data = plainTextStore.readData( key ); + const WritePasswordJobPrivate::Mode mode = plainTextStore.readMode( key ); + plainTextStore.remove( key ); + + q->emitFinished(); + + + WritePasswordJob* j = new WritePasswordJob( q->service(), 0 ); + j->setSettings( q->settings() ); + j->setKey( key ); + j->setAutoDelete( true ); + if ( mode == WritePasswordJobPrivate::Binary ) + j->setBinaryData( data ); + else if ( mode == WritePasswordJobPrivate::Text ) + j->setTextData( QString::fromUtf8( data ) ); + else + Q_ASSERT( false ); + + j->start(); + + return; + } + + walletHandle = reply.value(); + + if ( walletHandle < 0 ) { + q->emitFinishedWithError( AccessDenied, tr("Access to keychain denied") ); + return; + } + + const QDBusPendingReply nextReply = iface->entryType( walletHandle, q->service(), key, q->service() ); + QDBusPendingCallWatcher* nextWatcher = new QDBusPendingCallWatcher( nextReply, this ); + connect( nextWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletEntryTypeFinished(QDBusPendingCallWatcher*)) ); +} + +//Must be in sync with KWallet::EntryType (kwallet.h) +enum KWalletEntryType { + Unknown=0, + Password, + Stream, + Map +}; + +void ReadPasswordJobPrivate::kwalletEntryTypeFinished( QDBusPendingCallWatcher* watcher ) { + watcher->deleteLater(); + if ( watcher->isError() ) { + const QDBusError err = watcher->error(); + q->emitFinishedWithError( OtherError, tr("Could not determine data type: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) ); + return; + } + + const QDBusPendingReply reply = *watcher; + const int value = reply.value(); + + switch ( value ) { + case Unknown: + q->emitFinishedWithError( EntryNotFound, tr("Entry not found") ); + return; + case Password: + mode = Text; + break; + case Stream: + mode = Binary; + break; + case Map: + q->emitFinishedWithError( EntryNotFound, tr("Unsupported entry type 'Map'") ); + return; + default: + q->emitFinishedWithError( OtherError, tr("Unknown kwallet entry type '%1'").arg( value ) ); + return; + } + + const QDBusPendingCall nextReply = (mode == Text) + ? QDBusPendingCall( iface->readPassword( walletHandle, q->service(), key, q->service() ) ) + : QDBusPendingCall( iface->readEntry( walletHandle, q->service(), key, q->service() ) ); + QDBusPendingCallWatcher* nextWatcher = new QDBusPendingCallWatcher( nextReply, this ); + connect( nextWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletFinished(QDBusPendingCallWatcher*)) ); +} + +void ReadPasswordJobPrivate::kwalletFinished( QDBusPendingCallWatcher* watcher ) { + if ( !watcher->isError() ) { + if ( mode == Binary ) { + QDBusPendingReply reply = *watcher; + if (reply.isValid()) { + data = reply.value(); + } + } else { + QDBusPendingReply reply = *watcher; + if (reply.isValid()) { + data = reply.value().toUtf8(); + } + } + } + + JobPrivate::kwalletFinished(watcher); +} + +static void kwalletWritePasswordScheduledStart( const char * service, const char * path, JobPrivate * priv ) { + if ( QDBusConnection::sessionBus().isConnected() ) + { + priv->iface = new org::kde::KWallet( QLatin1String(service), QLatin1String(path), QDBusConnection::sessionBus(), priv ); + const QDBusPendingReply reply = priv->iface->networkWallet(); + QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher( reply, priv ); + priv->connect( watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), priv, SLOT(kwalletWalletFound(QDBusPendingCallWatcher*)) ); + } + else + { + // D-Bus is not reachable so none can tell us something about KWalletd + QDBusError err( QDBusError::NoServer, WritePasswordJobPrivate::tr("D-Bus is not running") ); + priv->fallbackOnError( err ); + } +} + +void WritePasswordJobPrivate::scheduledStart() { + switch ( getKeyringBackend() ) { + case Backend_LibSecretKeyring: { + if ( !LibSecretKeyring::writePassword(service, key, service, mode, + data, this) ) { + q->emitFinishedWithError( OtherError, tr("Unknown error") ); + } + } break; + case Backend_GnomeKeyring: { + QString type; + QByteArray password; + + switch(mode) { + case JobPrivate::Text: + type = QLatin1String("plaintext"); + password = data; + break; + default: + type = QLatin1String("base64"); + password = data.toBase64(); + break; + } + + QByteArray service = q->service().toUtf8(); + if ( !GnomeKeyring::store_network_password( GnomeKeyring::GNOME_KEYRING_DEFAULT, + service.constData(), + key.toUtf8().constData(), + service.constData(), + type.toUtf8().constData(), + password.constData(), + reinterpret_cast( &JobPrivate::gnomeKeyring_writeCb ), + this, 0 ) ) + q->emitFinishedWithError( OtherError, tr("Unknown error") ); + } + break; + + case Backend_Kwallet4: + kwalletWritePasswordScheduledStart(KWALLET4_DBUS_IFACE, KWALLET4_DBUS_PATH, this); + break; + case Backend_Kwallet5: + kwalletWritePasswordScheduledStart(KWALLET5_DBUS_IFACE, KWALLET5_DBUS_PATH, this); + break; + case Backend_Kwallet6: + kwalletWritePasswordScheduledStart(KWALLET6_DBUS_IFACE, KWALLET6_DBUS_PATH, this); + break; + } +} + +void WritePasswordJobPrivate::fallbackOnError(const QDBusError &err) +{ + if ( !q->insecureFallback() ) { + q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2").arg( QDBusError::errorString( err.type() ), err.message() ) ); + return; + } + + PlainTextStore plainTextStore( q->service(), q->settings() ); + plainTextStore.write( key, data, mode ); + + if ( plainTextStore.error() != NoError ) + q->emitFinishedWithError( plainTextStore.error(), plainTextStore.errorString() ); + else + q->emitFinished(); +} + +void JobPrivate::gnomeKeyring_writeCb(int result, JobPrivate* self ) +{ + if ( result == GnomeKeyring::RESULT_OK ) { + self->q->emitFinished(); + } else { + const QPair errorResult = mapGnomeKeyringError( result ); + self->q->emitFinishedWithError( errorResult.first, errorResult.second ); + } +} + +void JobPrivate::kwalletOpenFinished( QDBusPendingCallWatcher* watcher ) { + watcher->deleteLater(); + QDBusPendingReply reply = *watcher; + + if ( reply.isError() ) { + fallbackOnError( reply.error() ); + return; + } + + PlainTextStore plainTextStore( q->service(), q->settings() ); + if ( plainTextStore.contains( key ) ) { + // If we had previously written to QSettings, but we now have a kwallet available, migrate and delete old insecure data + plainTextStore.remove( key ); + } + + const int handle = reply.value(); + + if ( handle < 0 ) { + q->emitFinishedWithError( AccessDenied, tr("Access to keychain denied") ); + return; + } + + QDBusPendingReply nextReply; + + if ( !data.isNull() ) { + if ( mode == Text ) { + nextReply = iface->writePassword( handle, q->service(), key, QString::fromUtf8(data), q->service() ); + } else { + Q_ASSERT( mode == Binary ); + nextReply = iface->writeEntry( handle, q->service(), key, data, q->service() ); + } + } else { + nextReply = iface->removeEntry( handle, q->service(), key, q->service() ); + } + + QDBusPendingCallWatcher* nextWatcher = new QDBusPendingCallWatcher( nextReply, this ); + connect( nextWatcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(kwalletFinished(QDBusPendingCallWatcher*)) ); +} + +void JobPrivate::kwalletFinished( QDBusPendingCallWatcher* watcher ) { + if ( !watcher->isError() ) { + if ( mode == Binary ) { + QDBusPendingReply reply = *watcher; + if (reply.isValid()) { + data = reply.value(); + } + } else { + QDBusPendingReply reply = *watcher; + if (reply.isValid()) { + data = reply.value().toUtf8(); + } + } + } + + q->emitFinished(); +} + +void DeletePasswordJobPrivate::scheduledStart() { + switch ( getKeyringBackend() ) { + case Backend_LibSecretKeyring: { + if ( !LibSecretKeyring::deletePassword(key, q->service(), this) ) { + q->emitFinishedWithError( OtherError, tr("Unknown error") ); + } + } break; + case Backend_GnomeKeyring: { + if ( !GnomeKeyring::delete_network_password( + key.toUtf8().constData(), q->service().toUtf8().constData(), + reinterpret_cast( &JobPrivate::gnomeKeyring_writeCb ), + this, 0 ) ) + q->emitFinishedWithError( OtherError, tr("Unknown error") ); + } + break; + + case Backend_Kwallet4: + kwalletWritePasswordScheduledStart(KWALLET4_DBUS_IFACE, KWALLET4_DBUS_PATH, this); + break; + case Backend_Kwallet5: + kwalletWritePasswordScheduledStart(KWALLET5_DBUS_IFACE, KWALLET5_DBUS_PATH, this); + break; + case Backend_Kwallet6: + kwalletWritePasswordScheduledStart(KWALLET6_DBUS_IFACE, KWALLET6_DBUS_PATH, this); + break; + } +} + +void DeletePasswordJobPrivate::fallbackOnError(const QDBusError &err) { + QScopedPointer local( !q->settings() ? new QSettings( q->service() ) : 0 ); + QSettings* actual = q->settings() ? q->settings() : local.data(); + + if ( !q->insecureFallback() ) { + q->emitFinishedWithError( OtherError, tr("Could not open wallet: %1; %2") + .arg( QDBusError::errorString( err.type() ), err.message() ) ); + return; + } + + actual->remove( key ); + actual->sync(); + + q->emitFinished(); + + + q->emitFinished(); +} + +bool QKeychain::isAvailable() +{ + return LibSecretKeyring::isAvailable() || GnomeKeyring::isAvailable() + || isKwalletAvailable(KWALLET6_DBUS_IFACE, KWALLET6_DBUS_PATH) + || isKwalletAvailable(KWALLET5_DBUS_IFACE, KWALLET5_DBUS_PATH); +} diff --git a/src/libs/3rdparty/qtkeychain/keychain_win.cpp b/src/libs/3rdparty/qtkeychain/keychain_win.cpp new file mode 100644 index 00000000000..98dd34cbab3 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/keychain_win.cpp @@ -0,0 +1,193 @@ +/****************************************************************************** + * Copyright (C) 2011-2015 Frank Osterfeld * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution * + * details, check the accompanying file 'COPYING'. * + *****************************************************************************/ +#include "keychain_p.h" +#include "plaintextstore_p.h" + +#include +#include + +#include + +using namespace QKeychain; + +#if defined(USE_CREDENTIAL_STORE) +#include + +void ReadPasswordJobPrivate::scheduledStart() { + LPCWSTR name = (LPCWSTR)key.utf16(); + PCREDENTIALW cred; + + if (!CredReadW(name, CRED_TYPE_GENERIC, 0, &cred)) { + Error err; + QString msg; + switch(GetLastError()) { + case ERROR_NOT_FOUND: + err = EntryNotFound; + msg = tr("Password entry not found"); + break; + default: + err = OtherError; + msg = tr("Could not decrypt data"); + break; + } + + q->emitFinishedWithError( err, msg ); + return; + } + + data = QByteArray((char*)cred->CredentialBlob, cred->CredentialBlobSize); + CredFree(cred); + + q->emitFinished(); +} + +void WritePasswordJobPrivate::scheduledStart() { + CREDENTIALW cred; + char *pwd = data.data(); + LPWSTR name = (LPWSTR)key.utf16(); + + memset(&cred, 0, sizeof(cred)); + cred.Comment = const_cast(L"QtKeychain"); + cred.Type = CRED_TYPE_GENERIC; + cred.TargetName = name; + cred.CredentialBlobSize = data.size(); + cred.CredentialBlob = (LPBYTE)pwd; + cred.Persist = CRED_PERSIST_ENTERPRISE; + + if (CredWriteW(&cred, 0)) { + q->emitFinished(); + return; + } + + DWORD err = GetLastError(); + + // Detect size-exceeded errors and provide nicer messages. + // Unfortunately these error codes aren't documented. + // Found empirically on Win10 1803 build 17134.523. + if (err == RPC_X_BAD_STUB_DATA) { + const size_t maxBlob = CRED_MAX_CREDENTIAL_BLOB_SIZE; + if (cred.CredentialBlobSize > maxBlob) { + q->emitFinishedWithError( + OtherError, + tr("Credential size exceeds maximum size of %1").arg(maxBlob)); + return; + } + } + if (err == RPC_S_INVALID_BOUND) { + const size_t maxTargetName = CRED_MAX_GENERIC_TARGET_NAME_LENGTH; + if (key.size() > maxTargetName) { + q->emitFinishedWithError( + OtherError, + tr("Credential key exceeds maximum size of %1").arg(maxTargetName)); + return; + } + } + + q->emitFinishedWithError( OtherError, tr("Writing credentials failed: Win32 error code %1").arg(err) ); +} + +void DeletePasswordJobPrivate::scheduledStart() { + LPCWSTR name = (LPCWSTR)key.utf16(); + + if (!CredDeleteW(name, CRED_TYPE_GENERIC, 0)) { + Error err; + QString msg; + switch(GetLastError()) { + case ERROR_NOT_FOUND: + err = EntryNotFound; + msg = tr("Password entry not found"); + break; + default: + err = OtherError; + msg = tr("Could not decrypt data"); + break; + } + + q->emitFinishedWithError( err, msg ); + } else { + q->emitFinished(); + } +} +#else +void ReadPasswordJobPrivate::scheduledStart() { + PlainTextStore plainTextStore( q->service(), q->settings() ); + QByteArray encrypted = plainTextStore.readData( key ); + if ( plainTextStore.error() != NoError ) { + q->emitFinishedWithError( plainTextStore.error(), plainTextStore.errorString() ); + return; + } + + DATA_BLOB blob_in, blob_out; + + blob_in.pbData = reinterpret_cast( encrypted.data() ); + blob_in.cbData = encrypted.size(); + + const BOOL ret = CryptUnprotectData( &blob_in, + nullptr, + nullptr, + nullptr, + nullptr, + 0, + &blob_out ); + if ( !ret ) { + q->emitFinishedWithError( OtherError, tr("Could not decrypt data") ); + return; + } + + data = QByteArray( reinterpret_cast( blob_out.pbData ), blob_out.cbData ); + SecureZeroMemory( blob_out.pbData, blob_out.cbData ); + LocalFree( blob_out.pbData ); + + q->emitFinished(); +} + +void WritePasswordJobPrivate::scheduledStart() { + DATA_BLOB blob_in, blob_out; + blob_in.pbData = reinterpret_cast( data.data() ); + blob_in.cbData = data.size(); + const BOOL res = CryptProtectData( &blob_in, + L"QKeychain-encrypted data", + nullptr, + nullptr, + nullptr, + 0, + &blob_out ); + if ( !res ) { + q->emitFinishedWithError( OtherError, tr("Encryption failed") ); //TODO more details available? + return; + } + + const QByteArray encrypted( reinterpret_cast( blob_out.pbData ), blob_out.cbData ); + LocalFree( blob_out.pbData ); + + PlainTextStore plainTextStore( q->service(), q->settings() ); + plainTextStore.write( key, encrypted, Binary ); + if ( plainTextStore.error() != NoError ) { + q->emitFinishedWithError( plainTextStore.error(), plainTextStore.errorString() ); + return; + } + + q->emitFinished(); +} + +void DeletePasswordJobPrivate::scheduledStart() { + PlainTextStore plainTextStore( q->service(), q->settings() ); + plainTextStore.remove( key ); + if ( plainTextStore.error() != NoError ) { + q->emitFinishedWithError( plainTextStore.error(), plainTextStore.errorString() ); + } else { + q->emitFinished(); + } +} +#endif + +bool QKeychain::isAvailable() +{ + return true; +} diff --git a/src/libs/3rdparty/qtkeychain/libsecret.cpp b/src/libs/3rdparty/qtkeychain/libsecret.cpp new file mode 100644 index 00000000000..6ee024989e8 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/libsecret.cpp @@ -0,0 +1,349 @@ +#if defined(HAVE_LIBSECRET) + +#undef signals +#include +#define signals + +#endif + +#include "libsecret_p.h" + + +#include + +#if defined(HAVE_LIBSECRET) +const SecretSchema* qtkeychainSchema(void) { + static const SecretSchema schema = { + "org.qt.keychain", SECRET_SCHEMA_DONT_MATCH_NAME, + { + { "user", SECRET_SCHEMA_ATTRIBUTE_STRING }, + { "server", SECRET_SCHEMA_ATTRIBUTE_STRING }, + { "type", SECRET_SCHEMA_ATTRIBUTE_STRING } + } + }; + + return &schema; +} + +typedef struct { + QKeychain::JobPrivate *self; + QString user; + QString server; +} callbackArg; + +typedef void (*secret_password_lookup_t) (const SecretSchema *schema, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + ...) G_GNUC_NULL_TERMINATED; +typedef gchar *(*secret_password_lookup_finish_t) (GAsyncResult *result, + GError **error); +typedef void (*secret_password_store_t) (const SecretSchema *schema, + const gchar *collection, + const gchar *label, + const gchar *password, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + ...) G_GNUC_NULL_TERMINATED; +typedef gboolean (*secret_password_store_finish_t) (GAsyncResult *result, + GError **error); +typedef void (*secret_password_clear_t) (const SecretSchema *schema, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data, + ...) G_GNUC_NULL_TERMINATED; +typedef gboolean (*secret_password_clear_finish_t) (GAsyncResult *result, + GError **error); +typedef void (*secret_password_free_t) (gchar *password); +typedef GQuark (*secret_error_get_quark_t) (void) G_GNUC_CONST; + +static secret_password_lookup_t secret_password_lookup_fn = nullptr; +static secret_password_lookup_finish_t secret_password_lookup_finish_fn = nullptr; +static secret_password_store_t secret_password_store_fn = nullptr; +static secret_password_store_finish_t secret_password_store_finish_fn = nullptr; +static secret_password_clear_t secret_password_clear_fn = nullptr; +static secret_password_clear_finish_t secret_password_clear_finish_fn = nullptr; +static secret_password_free_t secret_password_free_fn = nullptr; +static secret_error_get_quark_t secret_error_get_quark_fn = nullptr; + +static QKeychain::Error gerrorToCode(const GError *error) { + if (error->domain != secret_error_get_quark_fn()) { + return QKeychain::OtherError; + } + + switch(error->code) { + case SECRET_ERROR_NO_SUCH_OBJECT: + return QKeychain::EntryNotFound; + case SECRET_ERROR_IS_LOCKED: + return QKeychain::AccessDenied; + default: + return QKeychain::OtherError; + } +} + +static void +on_password_lookup (GObject *source, + GAsyncResult *result, + gpointer inst) +{ + GError *error = nullptr; + callbackArg *arg = (callbackArg*)inst; + gchar *password = secret_password_lookup_finish_fn (result, &error); + + Q_UNUSED(source); + + if (arg) { + if (error) { + QKeychain::Error code = gerrorToCode(error); + + arg->self->q->emitFinishedWithError( code, QString::fromUtf8(error->message) ); + } else { + if (password) { + QByteArray raw = QByteArray(password); + switch(arg->self->mode) { + case QKeychain::JobPrivate::Binary: + arg->self->data = QByteArray::fromBase64(raw); + break; + case QKeychain::JobPrivate::Text: + default: + arg->self->data = raw; + } + + arg->self->q->emitFinished(); + } else if (arg->self->mode == QKeychain::JobPrivate::Text) { + arg->self->mode = QKeychain::JobPrivate::Binary; + secret_password_lookup_fn (qtkeychainSchema(), nullptr, + on_password_lookup, arg, + "user", arg->user.toUtf8().constData(), + "server", arg->server.toUtf8().constData(), + "type", "base64", + nullptr); + return; + } else { + arg->self->q->emitFinishedWithError( QKeychain::EntryNotFound, QObject::tr("Entry not found") ); + } + } + } + if (error) { + g_error_free (error); + } + + if (password) { + secret_password_free_fn (password); + } + + if (arg) { + delete arg; + } +} + +static void +on_password_stored (GObject *source, + GAsyncResult *result, + gpointer inst) +{ + GError *error = nullptr; + QKeychain::JobPrivate *self = (QKeychain::JobPrivate*)inst; + + Q_UNUSED(source); + + secret_password_store_finish_fn (result, &error); + + if (self) { + if (error) { + self->q->emitFinishedWithError( gerrorToCode(error), + QString::fromUtf8(error->message) ); + } else { + self->q->emitFinished(); + } + } + if (error) { + g_error_free (error); + } +} + +static void +on_password_cleared (GObject *source, + GAsyncResult *result, + gpointer inst) +{ + GError *error = nullptr; + QKeychain::JobPrivate *self = (QKeychain::JobPrivate*)inst; + gboolean removed = secret_password_clear_finish_fn (result, &error); + + Q_UNUSED(source); + if (self) { + if ( error ) { + self->q->emitFinishedWithError( gerrorToCode(error), + QString::fromUtf8(error->message) ); + } else { + Q_UNUSED(removed); + self->q->emitFinished(); + } + } + if (error) { + g_error_free (error); + } +} + +static QString modeToString(QKeychain::JobPrivate::Mode mode) { + switch(mode) { + case QKeychain::JobPrivate::Binary: + return "base64"; + default: + return "plaintext"; + } +} +#endif + +bool LibSecretKeyring::isAvailable() { +#if defined(HAVE_LIBSECRET) + const LibSecretKeyring& keyring = instance(); + if (!keyring.isLoaded()) + return false; + if (secret_password_lookup_fn == nullptr) + return false; + if (secret_password_lookup_finish_fn == nullptr) + return false; + if (secret_password_store_fn == nullptr) + return false; + if (secret_password_store_finish_fn == nullptr) + return false; + if (secret_password_clear_fn == nullptr) + return false; + if (secret_password_clear_finish_fn == nullptr) + return false; + if (secret_password_free_fn == nullptr) + return false; + if (secret_error_get_quark_fn == nullptr) + return false; + return true; +#else + return false; +#endif +} + +bool LibSecretKeyring::findPassword(const QString &user, const QString &server, + QKeychain::JobPrivate *self) +{ +#if defined(HAVE_LIBSECRET) + if (!isAvailable()) { + return false; + } + + self->mode = QKeychain::JobPrivate::Text; + self->data = QByteArray(); + + callbackArg *arg = new callbackArg; + arg->self = self; + arg->user = user; + arg->server = server; + + secret_password_lookup_fn (qtkeychainSchema(), nullptr, on_password_lookup, arg, + "user", user.toUtf8().constData(), + "server", server.toUtf8().constData(), + "type", "plaintext", + nullptr); + return true; +#else + Q_UNUSED(user) + Q_UNUSED(server) + Q_UNUSED(self) + return false; +#endif +} + +bool LibSecretKeyring::writePassword(const QString &display_name, + const QString &user, + const QString &server, + const QKeychain::JobPrivate::Mode mode, + const QByteArray &password, + QKeychain::JobPrivate *self) +{ +#if defined(HAVE_LIBSECRET) + if (!isAvailable()) { + return false; + } + + QString type = modeToString(mode); + QByteArray pwd; + switch(mode) { + case QKeychain::JobPrivate::Binary: + pwd = password.toBase64(); + break; + default: + pwd = password; + break; + } + + secret_password_store_fn (qtkeychainSchema(), SECRET_COLLECTION_DEFAULT, + display_name.toUtf8().constData(), + pwd.constData(), nullptr, on_password_stored, self, + "user", user.toUtf8().constData(), + "server", server.toUtf8().constData(), + "type", type.toUtf8().constData(), + nullptr); + return true; +#else + Q_UNUSED(display_name) + Q_UNUSED(user) + Q_UNUSED(server) + Q_UNUSED(mode) + Q_UNUSED(password) + Q_UNUSED(self) + return false; +#endif +} + +bool LibSecretKeyring::deletePassword(const QString &key, const QString &service, + QKeychain::JobPrivate* self) +{ +#if defined(HAVE_LIBSECRET) + if (!isAvailable()) { + return false; + } + + secret_password_clear_fn (qtkeychainSchema(), nullptr, on_password_cleared, self, + "user", key.toUtf8().constData(), + "server", service.toUtf8().constData(), + nullptr); + return true; +#else + Q_UNUSED(key) + Q_UNUSED(service) + Q_UNUSED(self) + return false; +#endif +} + +LibSecretKeyring::LibSecretKeyring() + : QLibrary(QLatin1String("secret-1"), 0) +{ +#ifdef HAVE_LIBSECRET + if (load()) { + secret_password_lookup_fn = + (secret_password_lookup_t)resolve("secret_password_lookup"); + secret_password_lookup_finish_fn = + (secret_password_lookup_finish_t)resolve("secret_password_lookup_finish"); + secret_password_store_fn = + (secret_password_store_t)resolve("secret_password_store"); + secret_password_store_finish_fn = + (secret_password_store_finish_t)resolve("secret_password_store_finish"); + secret_password_clear_fn = + (secret_password_clear_t)resolve("secret_password_clear"); + secret_password_clear_finish_fn = + (secret_password_clear_finish_t)resolve("secret_password_clear_finish"); + secret_password_free_fn = + (secret_password_free_t)resolve("secret_password_free"); + secret_error_get_quark_fn = + (secret_error_get_quark_t)resolve("secret_error_get_quark"); + } +#endif +} + +LibSecretKeyring &LibSecretKeyring::instance() { + static LibSecretKeyring instance; + + return instance; +} diff --git a/src/libs/3rdparty/qtkeychain/libsecret_p.h b/src/libs/3rdparty/qtkeychain/libsecret_p.h new file mode 100644 index 00000000000..bd966fe0f7c --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/libsecret_p.h @@ -0,0 +1,33 @@ +#ifndef QTKEYCHAIN_LIBSECRET_P_H +#define QTKEYCHAIN_LIBSECRET_P_H + +#include + +#include "keychain_p.h" + +class LibSecretKeyring : public QLibrary { +public: + static bool isAvailable(); + + static bool findPassword(const QString& user, + const QString& server, + QKeychain::JobPrivate* self); + + static bool writePassword(const QString& display_name, + const QString& user, + const QString& server, + const QKeychain::JobPrivate::Mode type, + const QByteArray& password, + QKeychain::JobPrivate* self); + + static bool deletePassword(const QString &key, const QString &service, + QKeychain::JobPrivate* self); + +private: + LibSecretKeyring(); + + static LibSecretKeyring &instance(); +}; + + +#endif diff --git a/src/libs/3rdparty/qtkeychain/org.kde.KWallet.xml b/src/libs/3rdparty/qtkeychain/org.kde.KWallet.xml new file mode 100644 index 00000000000..ec4bd6e9c32 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/org.kde.KWallet.xml @@ -0,0 +1,276 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/libs/3rdparty/qtkeychain/plaintextstore.cpp b/src/libs/3rdparty/qtkeychain/plaintextstore.cpp new file mode 100644 index 00000000000..b9d027264d4 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/plaintextstore.cpp @@ -0,0 +1,110 @@ +/****************************************************************************** + * Copyright (C) 2011-2015 Frank Osterfeld * + * Copyright (C) 2016 Mathias Hasselmann * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution * + * details, check the accompanying file 'COPYING'. * + *****************************************************************************/ + +#include "plaintextstore_p.h" + +using namespace QKeychain; + +namespace { +#ifdef Q_OS_WIN +inline QString dataKey(const QString &key) { return key; } +#else // Q_OS_WIN +inline QString dataKey(const QString &key) { return key + QLatin1String("/data"); } +inline QString typeKey(const QString &key) { return key + QLatin1String("/type"); } +#endif // Q_OS_WIN +} + + +PlainTextStore::PlainTextStore(const QString &service, QSettings *settings) + : m_localSettings(settings ? 0 : new QSettings(service)) + , m_actualSettings(settings ? settings : m_localSettings.data()) + , m_error(NoError) +{ +} + +bool PlainTextStore::contains(const QString &key) const +{ + return m_actualSettings->contains(dataKey(key)); +} + +QByteArray PlainTextStore::readData(const QString &key) +{ + return read(dataKey(key)).toByteArray(); +} + +#ifndef Q_OS_WIN + +JobPrivate::Mode PlainTextStore::readMode(const QString &key) +{ + return JobPrivate::stringToMode(read(typeKey(key)).toString()); +} + +#endif // Q_OS_WIN + +void PlainTextStore::write(const QString &key, const QByteArray &data, JobPrivate::Mode mode) +{ + if (m_actualSettings->status() != QSettings::NoError) + return; + +#ifndef Q_OS_WIN + m_actualSettings->setValue(typeKey(key), JobPrivate::modeToString(mode)); +#else // Q_OS_WIN + Q_UNUSED(mode); +#endif // Q_OS_WIN + m_actualSettings->setValue(dataKey(key), data); + m_actualSettings->sync(); + + if (m_actualSettings->status() == QSettings::AccessError) { + setError(AccessDenied, tr("Could not store data in settings: access error")); + } else if (m_actualSettings->status() != QSettings::NoError) { + setError(OtherError, tr("Could not store data in settings: format error")); + } else { + setError(NoError, QString()); + } +} + +void PlainTextStore::remove(const QString &key) +{ + if (m_actualSettings->status() != QSettings::NoError) + return; + +#ifndef Q_OS_WIN + m_actualSettings->remove(typeKey(key)); +#endif // Q_OS_WIN + m_actualSettings->remove(dataKey(key)); + m_actualSettings->sync(); + + if (m_actualSettings->status() == QSettings::AccessError) { + setError(AccessDenied, tr("Could not delete data from settings: access error")); + } else if (m_actualSettings->status() != QSettings::NoError) { + setError(OtherError, tr("Could not delete data from settings: format error")); + } else { + setError(NoError, QString()); + } +} + +void PlainTextStore::setError(Error error, const QString &errorString) +{ + m_error = error; + m_errorString = errorString; +} + +QVariant PlainTextStore::read(const QString &key) +{ + const QVariant value = m_actualSettings->value(key); + + if (value.isNull()) { + setError(EntryNotFound, tr("Entry not found")); + } else { + setError(NoError, QString()); + } + + return value; +} diff --git a/src/libs/3rdparty/qtkeychain/plaintextstore_p.h b/src/libs/3rdparty/qtkeychain/plaintextstore_p.h new file mode 100644 index 00000000000..7ec05aaca17 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/plaintextstore_p.h @@ -0,0 +1,47 @@ +/****************************************************************************** + * Copyright (C) 2011-2015 Frank Osterfeld * + * Copyright (C) 2016 Mathias Hasselmann * + * * + * This program is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution * + * details, check the accompanying file 'COPYING'. * + *****************************************************************************/ + +#ifndef QTKEYCHAIN_PLAINTEXTSTORE_P_H +#define QTKEYCHAIN_PLAINTEXTSTORE_P_H + +#include "keychain_p.h" + +namespace QKeychain { + +class PlainTextStore { + Q_DECLARE_TR_FUNCTIONS(QKeychain::PlainTextStore) + +public: + explicit PlainTextStore(const QString &service, QSettings *settings); + + Error error() const { return m_error; } + QString errorString() const { return m_errorString; } + + bool contains(const QString &key) const; + + QByteArray readData(const QString &key); + JobPrivate::Mode readMode(const QString &key); + + void write(const QString &key, const QByteArray &data, JobPrivate::Mode mode); + void remove(const QString &key); + +private: + void setError(Error error, const QString &errorString); + QVariant read(const QString &key); + + const QScopedPointer m_localSettings; + QSettings *const m_actualSettings; + QString m_errorString; + Error m_error; +}; + +} + +#endif // QTKEYCHAIN_PLAINTEXTSTORE_P_H diff --git a/src/libs/3rdparty/qtkeychain/qkeychain_export.h b/src/libs/3rdparty/qtkeychain/qkeychain_export.h new file mode 100644 index 00000000000..14dc72287fb --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/qkeychain_export.h @@ -0,0 +1,11 @@ +#pragma once + +#include + +#if defined(QTKEYCHAIN_LIBRARY) +# define QKEYCHAIN_EXPORT Q_DECL_EXPORT +#elif defined(QTKEYCHAIN_STATIC_LIBRARY) +# define QKEYCHAIN_EXPORT +#else +# define QKEYCHAIN_EXPORT Q_DECL_IMPORT +#endif diff --git a/src/libs/3rdparty/qtkeychain/translations/qtkeychain_de.ts b/src/libs/3rdparty/qtkeychain/translations/qtkeychain_de.ts new file mode 100644 index 00000000000..59ed992ed1b --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/translations/qtkeychain_de.ts @@ -0,0 +1,234 @@ + + + + + QKeychain::DeletePasswordJobPrivate + + + Password entry not found + + + + + Could not decrypt data + Kann Daten nicht entschlüsseln + + + + + Unknown error + Unbekannter Fehler + + + + Could not open wallet: %1; %2 + Konnte Brieftasche nicht öffnen: %1; %2 + + + Password not found + Passwort nicht gefunden + + + + QKeychain::JobPrivate + + + Unknown error + Unbekannter Fehler + + + + Access to keychain denied + Zugriff auf Schlüsselbund verweigert + + + + QKeychain::PlainTextStore + + + Could not store data in settings: access error + + + + + Could not store data in settings: format error + + + + + Could not delete data from settings: access error + + + + + Could not delete data from settings: format error + + + + + Entry not found + Eintrag nicht gefunden + + + + QKeychain::ReadPasswordJobPrivate + + + + Unknown error + Unbekannter Fehler + + + + D-Bus is not running + + + + + No keychain service available + Kein Schlüsselbund-Dienst verfügbar + + + + Could not open wallet: %1; %2 + Konnte Brieftasche nicht öffnen: %1; %2 + + + + Access to keychain denied + Zugriff auf Schlüsselbund verweigert + + + + Could not determine data type: %1; %2 + Datentyp kann nicht ermittelt werden: %1: %2 + + + + Unsupported entry type 'Map' + + + + + Unknown kwallet entry type '%1' + + + + + Entry not found + Eintrag nicht gefunden + + + + Password entry not found + + + + + + Could not decrypt data + Kann Daten nicht entschlüsseln + + + + QKeychain::WritePasswordJobPrivate + + + + Unknown error + Unbekannter Fehler + + + + D-Bus is not running + + + + + Could not open wallet: %1; %2 + Konnte Brieftasche nicht öffnen: %1; %2 + + + + Credential size exceeds maximum size of %1 + + + + + Credential key exceeds maximum size of %1 + + + + + Writing credentials failed: Win32 error code %1 + + + + + Encryption failed + Verschlüsselung fehlgeschlagen + + + Password not found + Passwort nicht gefunden + + + + QObject + + + Access to keychain denied + Zugriff auf Schlüsselbund verweigert + + + + No keyring daemon + Kein Schlüsselbund-Dienst + + + + Already unlocked + Bereits entsperrt + + + + No such keyring + Kein solcher Schlüsselbund + + + + Bad arguments + Ungültige Argumente + + + + I/O error + Ein-/Ausgabe-Fehler + + + + Cancelled + Abgebrochen + + + + Keyring already exists + Schlüsselbund existiert bereits + + + + No match + Kein Treffer + + + + Unknown error + Unbekannter Fehler + + + + Entry not found + Eintrag nicht gefunden + + + diff --git a/src/libs/3rdparty/qtkeychain/translations/qtkeychain_fr.ts b/src/libs/3rdparty/qtkeychain/translations/qtkeychain_fr.ts new file mode 100644 index 00000000000..5eee2e34daa --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/translations/qtkeychain_fr.ts @@ -0,0 +1,226 @@ + + + + + QKeychain::DeletePasswordJobPrivate + + + Password entry not found + Mot de passe introuvable + + + + Could not decrypt data + Impossible de déchiffrer les données + + + + + Unknown error + Erreur inconnue + + + + Could not open wallet: %1; %2 + Impossible d'ouvrir le portefeuille : %1; %2 + + + + QKeychain::JobPrivate + + + Unknown error + Erreur inconnue + + + + Access to keychain denied + Accès au trousseau refusé + + + + QKeychain::PlainTextStore + + + Could not store data in settings: access error + Impossible de stocker les données dans les paramètres : Erreur d'accès + + + + Could not store data in settings: format error + Impossible de stocker les données dans les paramètres : Erreur de format + + + + Could not delete data from settings: access error + Impossible de supprimer les données depuis les paramètres : Erreur d'accès + + + + Could not delete data from settings: format error + Impossible de supprimer les données depuis les paramètres : Erreur de format + + + + Entry not found + Entrée introuvable + + + + QKeychain::ReadPasswordJobPrivate + + + + Unknown error + Erreur inconnue + + + + D-Bus is not running + D-Bus n'est pas en cours d'exécution + + + + No keychain service available + Aucun service de trousseau disponible + + + + Could not open wallet: %1; %2 + Impossible d'ouvrir le trousseau : %1; %2 + + + + Access to keychain denied + Accès au trousseau refusé + + + + Could not determine data type: %1; %2 + Impossible de déterminer le type de données : %1: %2 + + + + Unsupported entry type 'Map' + Type d'entrée non supporté 'Map' + + + + Unknown kwallet entry type '%1' + Type de trousseau inconnu '%1' + + + + Entry not found + Entrée introuvable + + + + Password entry not found + Entrée de mot de passe introuvable + + + + + Could not decrypt data + Impossible de déchiffrer les données + + + + QKeychain::WritePasswordJobPrivate + + + + Unknown error + Erreur inconnue + + + + D-Bus is not running + D-Bus n'est pas en cours d'exécution + + + + Could not open wallet: %1; %2 + Impossible d'ouvrir le trousseau : %1; %2 + + + + Credential size exceeds maximum size of %1 + + + + + Credential key exceeds maximum size of %1 + + + + + Writing credentials failed: Win32 error code %1 + + + + + Encryption failed + Le chiffrement a échoué + + + + QObject + + + Access to keychain denied + Accès au trousseau refusé + + + + No keyring daemon + Aucun démon de trousseau + + + + Already unlocked + Déjà déverrouillé + + + + No such keyring + Aucun trousseau + + + + Bad arguments + Mauvais arguments + + + + I/O error + Erreur d'E/S + + + + Cancelled + Annulé + + + + Keyring already exists + Trousseau déjà existant + + + + No match + Aucune correspondance + + + + Unknown error + Erreur inconnue + + + + Entry not found + Entrée introuvable + + + diff --git a/src/libs/3rdparty/qtkeychain/translations/qtkeychain_nl.ts b/src/libs/3rdparty/qtkeychain/translations/qtkeychain_nl.ts new file mode 100644 index 00000000000..7033a98457b --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/translations/qtkeychain_nl.ts @@ -0,0 +1,320 @@ + + + + + KeyChainClass + + + Read key failed: %1 + De sleutel kan niet worden ingelezen: %1 + + + + Write key failed: %1 + De sleutel kan niet worden weggeschreven: %1 + + + + Delete key failed: %1 + De sleutel kan niet worden verwijderd: %1 + + + + QKeychain::DeletePasswordJobPrivate + + + Could not open keystore + De sleutelbos kan niet worden geopend + + + + Could not remove private key from keystore + De privésleutel kan niet worden verwijderd uit de sleutelbos + + + + Password not found + Het wachtwoord is niet gevonden + + + + + Unknown error + Onbekende foutmelding + + + + Could not open wallet: %1; %2 + De sleutelbos kan niet worden geopend: %1; %2 + + + + Password entry not found + Het wachtwoord is niet gevonden + + + + Could not decrypt data + De gegevens kunnen niet worden ongrendeld + + + + QKeychain::JobPrivate + + + Unknown error + Onbekende foutmelding + + + + Access to keychain denied + U heeft geen toegang tot de sleutelbos + + + + QKeychain::PlainTextStore + + + Could not store data in settings: access error + De gegevens kunnen niet worden opgeslagen in de instellingen: toegangsfout + + + + Could not store data in settings: format error + De gegevens kunnen niet worden opgeslagen in de instellingen: opmaakfout + + + + Could not delete data from settings: access error + De gegevens kunnen niet worden verwijderd uit de instellingen: toegangsfout + + + + Could not delete data from settings: format error + De gegevens kunnen niet worden verwijderd uit de instellingen: opmaakfout + + + + Entry not found + Het item is niet gevonden + + + + QKeychain::ReadPasswordJobPrivate + + + + Entry not found + Het item is niet gevonden + + + + Could not open keystore + De sleutelbos kan niet worden geopend + + + + Could not retrieve private key from keystore + De privésleutel kan niet worden verwijderd uit de sleutelbos + + + + Could not create decryption cipher + De ontgrendelcode kan niet worden aangemaakt + + + + Password not found + Het wachtwoord is niet gevonden + + + + D-Bus is not running + D-Bus is niet actief + + + + + Unknown error + Onbekende foutmelding + + + + No keychain service available + De sleutelbosdienst is niet beschikbaar + + + + Could not open wallet: %1; %2 + De sleutelbos kan niet worden geopend: %1; %2 + + + + Access to keychain denied + U heeft geen toegang tot de sleutelbos + + + + Could not determine data type: %1; %2 + De gegevensdrager kan niet worden bepaald: %1; %2 + + + + Unsupported entry type 'Map' + Niet-ondersteund itemtype ‘Map’ + + + + Unknown kwallet entry type '%1' + Onbekend KWallet-item van type ‘%1’ + + + + Password entry not found + Het wachtwoord is niet gevonden + + + + + Could not decrypt data + De gegevens kunnen niet worden ongrendeld + + + + QKeychain::WritePasswordJobPrivate + + + Could not open keystore + De sleutelbos kan niet worden geopend + + + + Could not create private key generator + De privésleutelgenerator kan niet worden gestart + + + + Could not generate new private key + Er kan geen nieuwe privésleutel worden gegenereerd + + + + Could not retrieve private key from keystore + De privésleutel kan niet worden opgehaald uit de sleutelbos + + + + Could not create encryption cipher + De vergrendelcode kan niet worden aangemaakt + + + + Could not encrypt data + De gegevens kunnen niet worden ontgrendeld + + + + Password not found + Het wachtwoord is niet gevonden + + + + D-Bus is not running + D-Bus is niet actief + + + + + Unknown error + Onbekende foutmelding + + + + Could not open wallet: %1; %2 + De sleutelbos kan niet worden geopend: %1; %2 + + + + Credential size exceeds maximum size of %1 + De omvang overschrijdt de maximumomvang van %1 + + + + Credential key exceeds maximum size of %1 + De sleutel overschrijdt de maximumomvang van %1 + + + + Writing credentials failed: Win32 error code %1 + De gegevens kunnen niet worden weggeschreven: Win32-foutcode %1 + + + + Encryption failed + Het ontgrendelen is mislukt + + + + QObject + + + error 0x%1: %2 + foutmelding 0x%1: %2 + + + + Access to keychain denied + U heeft geen toegang tot de sleutelbos + + + + No keyring daemon + De sleutelbosdienst is niet actief + + + + Already unlocked + De sleutelbos is reeds ontgrendeld + + + + No such keyring + De sleutelbos bestaat niet + + + + Bad arguments + Onjuiste opties + + + + I/O error + I/O-fout + + + + Cancelled + Geannuleerd + + + + Keyring already exists + De sleutelbos bestaat reeds + + + + No match + Er zijn geen overeenkomsten + + + + Unknown error + Onbekende foutmelding + + + + Entry not found + Het item is niet gevonden + + + diff --git a/src/libs/3rdparty/qtkeychain/translations/qtkeychain_ro.ts b/src/libs/3rdparty/qtkeychain/translations/qtkeychain_ro.ts new file mode 100644 index 00000000000..fb4e5906764 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/translations/qtkeychain_ro.ts @@ -0,0 +1,235 @@ + + + + + QKeychain::DeletePasswordJobPrivate + + + Password entry not found + + + + + Could not decrypt data + Nu se poate decripta data + + + + + Unknown error + Eroare necunoscută + + + + Could not open wallet: %1; %2 + Nu se poate deschide portofelul: %1; %2 + + + Password not found + Parola nu a fost găsită + + + + QKeychain::JobPrivate + + + Unknown error + Eroare necunoscută + + + + Access to keychain denied + Acces interzis la serviciul de chei + + + + QKeychain::PlainTextStore + + + Could not store data in settings: access error + + + + + Could not store data in settings: format error + + + + + Could not delete data from settings: access error + + + + + Could not delete data from settings: format error + + + + + Entry not found + Înregistrarea nu a fost găsită + + + + QKeychain::ReadPasswordJobPrivate + + + + Unknown error + Eroare necunoscută + + + + D-Bus is not running + D-Bus nu rulează + + + + No keychain service available + Nu există niciun serviciu de chei disponibil + Kein Schlüsselbund-Dienst verfügbar + + + + Could not open wallet: %1; %2 + Nu se poate deschide portofelul: %1; %2 + + + + Access to keychain denied + Acces interzis la serviciul de chei + + + + Could not determine data type: %1; %2 + Nu se poate stabili tipul de date: %1: %2 + + + + Unsupported entry type 'Map' + Tip de înregistrare nesuportat 'Map' + + + + Unknown kwallet entry type '%1' + Tip de înregistrare kwallet necunoscut '%1' + + + + Entry not found + Înregistrarea nu a fost găsită + + + + Password entry not found + + + + + + Could not decrypt data + Nu se poate decripta data + + + + QKeychain::WritePasswordJobPrivate + + + + Unknown error + Eroare necunoscută + + + + D-Bus is not running + D-Bus nu rulează + + + + Could not open wallet: %1; %2 + Nu se poate deschide portofelul: %1; %2 + + + + Credential size exceeds maximum size of %1 + + + + + Credential key exceeds maximum size of %1 + + + + + Writing credentials failed: Win32 error code %1 + + + + + Encryption failed + Criptarea a eșuat + + + Password not found + Parola nu a fost găsită + + + + QObject + + + Access to keychain denied + Acces interzis la serviciul de chei + + + + No keyring daemon + Niciun demon pentru inelul de chei + + + + Already unlocked + Deja deblocat + + + + No such keyring + Nu există astfel de inel de chei + + + + Bad arguments + Argumente greșite + + + + I/O error + Eroare de I/E + + + + Cancelled + Anulat + + + + Keyring already exists + Inelul de chei deja există + + + + No match + Nicio potrivire + + + + Unknown error + Eroare necunoscută + + + + Entry not found + Înregistrarea nu a fost găsită + + + diff --git a/src/libs/3rdparty/qtkeychain/translations/qtkeychain_ru.ts b/src/libs/3rdparty/qtkeychain/translations/qtkeychain_ru.ts new file mode 100644 index 00000000000..c4cec0bb52f --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/translations/qtkeychain_ru.ts @@ -0,0 +1,234 @@ + + + + + QKeychain::DeletePasswordJobPrivate + + + + Unknown error + Неизвестная ошибка + + + + Could not open wallet: %1; %2 + Не удалось открыть бумажник: %1; %2 + + + + Password entry not found + Пароль не найден + + + + Could not decrypt data + Не удалось расшифровать данные + + + Password not found + Пароль не найден + + + + QKeychain::JobPrivate + + + Unknown error + Неизвестная ошибка + + + + Access to keychain denied + Доступ к связке ключей запрещён + + + + QKeychain::PlainTextStore + + + Could not store data in settings: access error + Не удалось сохранить данные в настройках: ошибка доступа + + + + Could not store data in settings: format error + Не удалось сохранить данные в настройках: ошибка формата + + + + Could not delete data from settings: access error + Не удалось удалить данные из настроек: ошибка доступа + + + + Could not delete data from settings: format error + Не удалось удалить данные из настроек: ошибка формата + + + + Entry not found + Запись не найдена + + + + QKeychain::ReadPasswordJobPrivate + + + D-Bus is not running + D-Bus не запущен + + + + + Unknown error + Неизвестная ошибка + + + + No keychain service available + Служба связки ключей недоступна + + + + Could not open wallet: %1; %2 + Не удалось открыть кошелёк: %1; %2 + + + + Access to keychain denied + Доступ к связке ключей запрещён + + + + Could not determine data type: %1; %2 + Не удалось определить тип данных: %1; %2 + + + + Entry not found + Запись не найдена + + + + Unsupported entry type 'Map' + Неподдерживаемый тип записи 'Map' + + + + Unknown kwallet entry type '%1' + Неизвестный тип записи kwallet '%1' + + + + Password entry not found + Пароль не найден + + + + + Could not decrypt data + Не удалось расшифровать данные + + + + QKeychain::WritePasswordJobPrivate + + + D-Bus is not running + D-Bus не запущен + + + + + Unknown error + Неизвестная ошибка + + + + Could not open wallet: %1; %2 + Не удалось открыть кошелёк: %1; %2 + + + + Credential size exceeds maximum size of %1 + Учётные данные превышают максимальный размер %1 + + + + Credential key exceeds maximum size of %1 + Ключ учётных данных превышает максимальный размер %1 + + + + Writing credentials failed: Win32 error code %1 + Не удалось сохранить учётные данные: код ошибки win32 %1 + + + + Encryption failed + Шифрование не удалось + + + Password not found + Пароль не найден + + + + QObject + + + Access to keychain denied + Доступ к связке ключей запрещён + + + + No keyring daemon + Нет демона связки ключей + + + + Already unlocked + Уже разблокировано + + + + No such keyring + Связка ключей не найдена + + + + Bad arguments + Неверные аргументы + + + + I/O error + Ошибка ввода/вывода + + + + Cancelled + Отменено + + + + Keyring already exists + Связка ключей уже существует + + + + No match + Нет совпадений + + + + Unknown error + Неизвестная ошибка + + + + Entry not found + Запись не найдена + + + diff --git a/src/libs/3rdparty/qtkeychain/translations/qtkeychain_zh.ts b/src/libs/3rdparty/qtkeychain/translations/qtkeychain_zh.ts new file mode 100644 index 00000000000..5d4d64a4995 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/translations/qtkeychain_zh.ts @@ -0,0 +1,234 @@ + + + + + QKeychain::DeletePasswordJobPrivate + + + Password entry not found + + + + + Could not decrypt data + 無法解密資料 + + + + + Unknown error + 未知的錯誤 + + + + Could not open wallet: %1; %2 + 無法開啟錢包:%1; %2 + + + Password not found + 找不到密碼 + + + + QKeychain::JobPrivate + + + Unknown error + 未知的錯誤 + + + + Access to keychain denied + 鑰匙圈存取被拒絕 + + + + QKeychain::PlainTextStore + + + Could not store data in settings: access error + + + + + Could not store data in settings: format error + + + + + Could not delete data from settings: access error + + + + + Could not delete data from settings: format error + + + + + Entry not found + 找不到項目 + + + + QKeychain::ReadPasswordJobPrivate + + + + Unknown error + 未知的錯誤 + + + + D-Bus is not running + D-Bus 不在執行中 + + + + No keychain service available + 沒有可用的鑰匙圈服務 + + + + Could not open wallet: %1; %2 + 無法開啟錢包:%1; %2 + + + + Access to keychain denied + 鑰匙圈存取被拒絕 + + + + Could not determine data type: %1; %2 + 無法判斷資料型別:%1; %2 + + + + Unsupported entry type 'Map' + 不支援的項目類型 'Map' + + + + Unknown kwallet entry type '%1' + 未知的 kwallet 項目類型 '%1' + + + + Entry not found + 找不到項目 + + + + Password entry not found + + + + + + Could not decrypt data + 無法解密資料 + + + + QKeychain::WritePasswordJobPrivate + + + + Unknown error + 未知的錯誤 + + + + D-Bus is not running + D-Bus 不在執行中 + + + + Could not open wallet: %1; %2 + 無法開啟錢包:%1; %2 + + + + Credential size exceeds maximum size of %1 + + + + + Credential key exceeds maximum size of %1 + + + + + Writing credentials failed: Win32 error code %1 + + + + + Encryption failed + 加密失敗 + + + Password not found + 找不到密碼 + + + + QObject + + + Access to keychain denied + 鑰匙圈存取被拒絕 + + + + No keyring daemon + 沒有可用的鑰匙圈背景程式 + + + + Already unlocked + 已解鎖 + + + + No such keyring + 鑰匙圈不存在 + + + + Bad arguments + 引數錯誤 + + + + I/O error + I/O 錯誤 + + + + Cancelled + 已取消 + + + + Keyring already exists + 鑰匙圈已存在 + + + + No match + 無相符項目 + + + + Unknown error + 未知的錯誤 + + + + Entry not found + 找不到項目 + + + diff --git a/src/libs/3rdparty/qtkeychain/translations/translations.qrc.in b/src/libs/3rdparty/qtkeychain/translations/translations.qrc.in new file mode 100644 index 00000000000..f49df661508 --- /dev/null +++ b/src/libs/3rdparty/qtkeychain/translations/translations.qrc.in @@ -0,0 +1,5 @@ + + + @QM_FILE_LIST@ + + From a41b38540449b0df8e968da11428305982aac38c Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 4 Oct 2023 09:39:21 +0200 Subject: [PATCH 0005/1546] QtKeyChain: Fix CMakeLists.txt Otherwise getting: CMake Error at src/libs/3rdparty/qtkeychain/CMakeLists.txt:26 (endif): Flow control statements are not properly nested. Amends 4c746e79f0efb650b7616bcc4876228eeb4ffe59 Change-Id: I28c62432113e41426673a3bf4753d1001a8a4f9a Reviewed-by: Eike Ziller --- src/libs/3rdparty/qtkeychain/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/3rdparty/qtkeychain/CMakeLists.txt b/src/libs/3rdparty/qtkeychain/CMakeLists.txt index d8ba7e3178b..8e31ed44d6a 100644 --- a/src/libs/3rdparty/qtkeychain/CMakeLists.txt +++ b/src/libs/3rdparty/qtkeychain/CMakeLists.txt @@ -22,7 +22,6 @@ if (WIN32) SOURCES plaintextstore.cpp DEPENDS crypt32 ) - endif() endif() extend_qtc_library(qtkeychain From 9c6080165381fb4a04971959c64eacac81a89e3e Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 2 Oct 2023 15:34:56 +0200 Subject: [PATCH 0006/1546] CppEditor: Use a _data() function for the "move def to decl" tests Change-Id: I4da6aa383da82b968d371a8b74acee1fc7e8bef1 Reviewed-by: Reviewed-by: Qt CI Bot Reviewed-by: Christian Stenger --- src/plugins/cppeditor/cppquickfix_test.cpp | 341 ++++++++------------- src/plugins/cppeditor/cppquickfix_test.h | 15 +- 2 files changed, 132 insertions(+), 224 deletions(-) diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 0c4a07a2c27..de03b5c24c9 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -7244,42 +7244,35 @@ void QuickfixTest::testMoveFuncDefOutsideUnnamedTemplate() QuickFixOperationTest(singleDocument(original, expected), &factory); } -/// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncToCpp() -void QuickfixTest::testMoveFuncDefToDeclMemberFunc() +void QuickfixTest::testMoveFuncDefToDecl_data() { - QList testDocuments; - QByteArray original; - QByteArray expected; + QTest::addColumn("headers"); + QTest::addColumn("sources"); - // Header File - original = + QByteArray originalHeader; + QByteArray expectedHeader; + QByteArray originalSource; + QByteArray expectedSource; + + originalHeader = "class Foo {\n" " inline int number() const;\n" "};\n"; - expected = + expectedHeader = "class Foo {\n" " inline int number() const {return 5;}\n" "};\n"; - testDocuments << CppTestDocument::create("file.h", original, expected); - - // Source File - original = + originalSource = "#include \"file.h\"\n" "\n" "int Foo::num@ber() const {return 5;}\n"; - expected = + expectedSource = "#include \"file.h\"\n" "\n\n"; - testDocuments << CppTestDocument::create("file.cpp", original, expected); + QTest::newRow("member function, two files") << QByteArrayList{originalHeader, expectedHeader} + << QByteArrayList{originalSource, expectedSource}; - MoveFuncDefToDecl factory; - QuickFixOperationTest(testDocuments, &factory); -} - -/// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncOutside() -void QuickfixTest::testMoveFuncDefToDeclMemberFuncOutside() -{ - QByteArray original = + originalSource = "class Foo {\n" " inline int number() const;\n" "};\n" @@ -7289,33 +7282,23 @@ void QuickfixTest::testMoveFuncDefToDeclMemberFuncOutside() " return 5;\n" "}\n"; - QByteArray expected = + expectedSource = "class Foo {\n" " inline int number() const\n" " {\n" " return 5;\n" " }\n" "};\n\n\n"; + QTest::newRow("member function, one file") << QByteArrayList() + << QByteArrayList{originalSource, expectedSource}; - MoveFuncDefToDecl factory; - QuickFixOperationTest(singleDocument(original, expected), &factory); -} - -/// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncToCppNS() -void QuickfixTest::testMoveFuncDefToDeclMemberFuncToCppNS() -{ - QList testDocuments; - QByteArray original; - QByteArray expected; - - // Header File - original = + originalHeader = "namespace MyNs {\n" "class Foo {\n" " inline int number() const;\n" "};\n" "}\n"; - expected = + expectedHeader = "namespace MyNs {\n" "class Foo {\n" " inline int number() const\n" @@ -7324,38 +7307,25 @@ void QuickfixTest::testMoveFuncDefToDeclMemberFuncToCppNS() " }\n" "};\n" "}\n"; - testDocuments << CppTestDocument::create("file.h", original, expected); - - // Source File - original = + originalSource = "#include \"file.h\"\n" "\n" "int MyNs::Foo::num@ber() const\n" "{\n" " return 5;\n" "}\n"; - expected = "#include \"file.h\"\n\n\n"; - testDocuments << CppTestDocument::create("file.cpp", original, expected); + expectedSource = "#include \"file.h\"\n\n\n"; + QTest::newRow("member function, two files, namespace") + << QByteArrayList{originalHeader, expectedHeader} + << QByteArrayList{originalSource, expectedSource}; - MoveFuncDefToDecl factory; - QuickFixOperationTest(testDocuments, &factory); -} - -/// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncToCppNSUsing() -void QuickfixTest::testMoveFuncDefToDeclMemberFuncToCppNSUsing() -{ - QList testDocuments; - QByteArray original; - QByteArray expected; - - // Header File - original = + originalHeader = "namespace MyNs {\n" "class Foo {\n" " inline int number() const;\n" "};\n" "}\n"; - expected = + expectedHeader = "namespace MyNs {\n" "class Foo {\n" " inline int number() const\n" @@ -7364,10 +7334,7 @@ void QuickfixTest::testMoveFuncDefToDeclMemberFuncToCppNSUsing() " }\n" "};\n" "}\n"; - testDocuments << CppTestDocument::create("file.h", original, expected); - - // Source File - original = + originalSource = "#include \"file.h\"\n" "using namespace MyNs;\n" "\n" @@ -7375,20 +7342,15 @@ void QuickfixTest::testMoveFuncDefToDeclMemberFuncToCppNSUsing() "{\n" " return 5;\n" "}\n"; - expected = + expectedSource = "#include \"file.h\"\n" "using namespace MyNs;\n" "\n\n"; - testDocuments << CppTestDocument::create("file.cpp", original, expected); + QTest::newRow("member function, two files, namespace with using-directive") + << QByteArrayList{originalHeader, expectedHeader} + << QByteArrayList{originalSource, expectedSource}; - MoveFuncDefToDecl factory; - QuickFixOperationTest(testDocuments, &factory); -} - -/// Check: revert test_quickfix_MoveFuncDefOutside_MemberFuncOutsideWithNs() -void QuickfixTest::testMoveFuncDefToDeclMemberFuncOutsideWithNs() -{ - QByteArray original = + originalSource = "namespace MyNs {\n" "class Foo {\n" " inline int number() const;\n" @@ -7399,7 +7361,7 @@ void QuickfixTest::testMoveFuncDefToDeclMemberFuncOutsideWithNs() " return 5;\n" "}" "\n}\n"; - QByteArray expected = + expectedSource = "namespace MyNs {\n" "class Foo {\n" " inline int number() const\n" @@ -7408,28 +7370,16 @@ void QuickfixTest::testMoveFuncDefToDeclMemberFuncOutsideWithNs() " }\n" "};\n\n\n}\n"; - MoveFuncDefToDecl factory; - QuickFixOperationTest(singleDocument(original, expected), &factory); -} + QTest::newRow("member function, one file, namespace") + << QByteArrayList() << QByteArrayList{originalSource, expectedSource}; -/// Check: revert test_quickfix_MoveFuncDefOutside_FreeFuncToCpp() -void QuickfixTest::testMoveFuncDefToDeclFreeFuncToCpp() -{ - QList testDocuments; - QByteArray original; - QByteArray expected; - - // Header File - original = "int number() const;\n"; - expected = + originalHeader = "int number() const;\n"; + expectedHeader = "inline int number() const\n" "{\n" " return 5;\n" "}\n"; - testDocuments << CppTestDocument::create("file.h", original, expected); - - // Source File - original = + originalSource = "#include \"file.h\"\n" "\n" "\n" @@ -7437,60 +7387,35 @@ void QuickfixTest::testMoveFuncDefToDeclFreeFuncToCpp() "{\n" " return 5;\n" "}\n"; - expected = "#include \"file.h\"\n\n\n\n"; - testDocuments << CppTestDocument::create("file.cpp", original, expected); + expectedSource = "#include \"file.h\"\n\n\n\n"; + QTest::newRow("free function") << QByteArrayList{originalHeader, expectedHeader} + << QByteArrayList{originalSource, expectedSource}; - MoveFuncDefToDecl factory; - QuickFixOperationTest(testDocuments, &factory); -} - -/// Check: revert test_quickfix_MoveFuncDefOutside_FreeFuncToCppNS() -void QuickfixTest::testMoveFuncDefToDeclFreeFuncToCppNS() -{ - QList testDocuments; - QByteArray original; - QByteArray expected; - - // Header File - original = + originalHeader = "namespace MyNamespace {\n" "int number() const;\n" "}\n"; - expected = + expectedHeader = "namespace MyNamespace {\n" "inline int number() const\n" "{\n" " return 5;\n" "}\n" "}\n"; - testDocuments << CppTestDocument::create("file.h", original, expected); - - // Source File - original = + originalSource = "#include \"file.h\"\n" "\n" "int MyNamespace::nu@mber() const\n" "{\n" " return 5;\n" "}\n"; - expected = + expectedSource = "#include \"file.h\"\n" "\n\n"; - testDocuments << CppTestDocument::create("file.cpp", original, expected); + QTest::newRow("free function, namespace") << QByteArrayList{originalHeader, expectedHeader} + << QByteArrayList{originalSource, expectedSource}; - MoveFuncDefToDecl factory; - QuickFixOperationTest(testDocuments, &factory); -} - -/// Check: revert test_quickfix_MoveFuncDefOutside_CtorWithInitialization() -void QuickfixTest::testMoveFuncDefToDeclCtorWithInitialization() -{ - QList testDocuments; - QByteArray original; - QByteArray expected; - - // Header File - original = + originalHeader = "class Foo {\n" "public:\n" " Foo();\n" @@ -7498,7 +7423,7 @@ void QuickfixTest::testMoveFuncDefToDeclCtorWithInitialization() " int a;\n" " float b;\n" "};\n"; - expected = + expectedHeader = "class Foo {\n" "public:\n" " Foo() : a(42), b(3.141) {}\n" @@ -7506,25 +7431,16 @@ void QuickfixTest::testMoveFuncDefToDeclCtorWithInitialization() " int a;\n" " float b;\n" "};\n"; - testDocuments << CppTestDocument::create("file.h", original, expected); - - // Source File - original = + originalSource = "#include \"file.h\"\n" "\n" "Foo::F@oo() : a(42), b(3.141) {}" ; - expected ="#include \"file.h\"\n\n"; - testDocuments << CppTestDocument::create("file.cpp", original, expected); + expectedSource ="#include \"file.h\"\n\n"; + QTest::newRow("constructor") << QByteArrayList{originalHeader, expectedHeader} + << QByteArrayList{originalSource, expectedSource}; - MoveFuncDefToDecl factory; - QuickFixOperationTest(testDocuments, &factory); -} - -/// Check: Definition should not be placed behind the variable. QTCREATORBUG-10303 -void QuickfixTest::testMoveFuncDefToDeclStructWithAssignedVariable() -{ - QByteArray original = + originalSource = "struct Foo\n" "{\n" " void foo();\n" @@ -7533,8 +7449,7 @@ void QuickfixTest::testMoveFuncDefToDeclStructWithAssignedVariable() "{\n" " return;\n" "}"; - - QByteArray expected = + expectedSource = "struct Foo\n" "{\n" " void foo()\n" @@ -7542,11 +7457,83 @@ void QuickfixTest::testMoveFuncDefToDeclStructWithAssignedVariable() " return;\n" " }\n" "} bar;\n"; + QTest::newRow("QTCREATORBUG-10303") << QByteArrayList() + << QByteArrayList{originalSource, expectedSource}; + + originalSource = + "struct Base {\n" + " virtual int foo() = 0;\n" + "};\n" + "struct Derived : Base {\n" + " int foo() override;\n" + "};\n" + "\n" + "int Derived::fo@o()\n" + "{\n" + " return 5;\n" + "}\n"; + expectedSource = + "struct Base {\n" + " virtual int foo() = 0;\n" + "};\n" + "struct Derived : Base {\n" + " int foo() override\n" + " {\n" + " return 5;\n" + " }\n" + "};\n\n\n"; + QTest::newRow("overridden virtual") << QByteArrayList() + << QByteArrayList{originalSource, expectedSource}; + + originalSource = + "template\n" + "class Foo { void func(); };\n" + "\n" + "template\n" + "void Foo::fu@nc() {}\n"; + expectedSource = + "template\n" + "class Foo { void fu@nc() {} };\n\n\n"; + QTest::newRow("class template") << QByteArrayList() + << QByteArrayList{originalSource, expectedSource}; + + originalSource = + "class Foo\n" + "{\n" + " template\n" + " void func();\n" + "};\n" + "\n" + "template\n" + "void Foo::fu@nc() {}\n"; + expectedSource = + "class Foo\n" + "{\n" + " template\n" + " void func() {}\n" + "};\n\n\n"; + QTest::newRow("function template") << QByteArrayList() + << QByteArrayList{originalSource, expectedSource}; +} + +void QuickfixTest::testMoveFuncDefToDecl() +{ + QFETCH(QByteArrayList, headers); + QFETCH(QByteArrayList, sources); + + QVERIFY(headers.isEmpty() || headers.size() == 2); + QVERIFY(sources.size() == 2); + + QList testDocuments; + if (!headers.isEmpty()) + testDocuments << CppTestDocument::create("file.h", headers.first(), headers.last()); + testDocuments << CppTestDocument::create("file.cpp", sources.first(), sources.last()); MoveFuncDefToDecl factory; - QuickFixOperationTest(singleDocument(original, expected), &factory); + QuickFixOperationTest(testDocuments, &factory); } + void QuickfixTest::testMoveFuncDefToDeclMacroUses() { QByteArray original = @@ -7578,76 +7565,6 @@ void QuickfixTest::testMoveFuncDefToDeclMacroUses() ProjectExplorer::HeaderPaths(), 0, "QTCREATORBUG-12314"); } -void QuickfixTest::testMoveFuncDefToDeclOverride() -{ - QByteArray original = - "struct Base {\n" - " virtual int foo() = 0;\n" - "};\n" - "struct Derived : Base {\n" - " int foo() override;\n" - "};\n" - "\n" - "int Derived::fo@o()\n" - "{\n" - " return 5;\n" - "}\n"; - - QByteArray expected = - "struct Base {\n" - " virtual int foo() = 0;\n" - "};\n" - "struct Derived : Base {\n" - " int foo() override\n" - " {\n" - " return 5;\n" - " }\n" - "};\n\n\n"; - - MoveFuncDefToDecl factory; - QuickFixOperationTest(singleDocument(original, expected), &factory); -} - -void QuickfixTest::testMoveFuncDefToDeclTemplate() -{ - QByteArray original = - "template\n" - "class Foo { void func(); };\n" - "\n" - "template\n" - "void Foo::fu@nc() {}\n"; - - QByteArray expected = - "template\n" - "class Foo { void fu@nc() {} };\n\n\n"; - - MoveFuncDefToDecl factory; - QuickFixOperationTest(singleDocument(original, expected), &factory); -} - -void QuickfixTest::testMoveFuncDefToDeclTemplateFunction() -{ - QByteArray original = - "class Foo\n" - "{\n" - " template\n" - " void func();\n" - "};\n" - "\n" - "template\n" - "void Foo::fu@nc() {}\n"; - - QByteArray expected = - "class Foo\n" - "{\n" - " template\n" - " void func() {}\n" - "};\n\n\n"; - - MoveFuncDefToDecl factory; - QuickFixOperationTest(singleDocument(original, expected), &factory); -} - /// Check: Move all definitions from header to cpp. void QuickfixTest::testMoveAllFuncDefOutsideMemberFuncToCpp() { diff --git a/src/plugins/cppeditor/cppquickfix_test.h b/src/plugins/cppeditor/cppquickfix_test.h index 89f05b0f160..99aff71696e 100644 --- a/src/plugins/cppeditor/cppquickfix_test.h +++ b/src/plugins/cppeditor/cppquickfix_test.h @@ -186,19 +186,10 @@ private slots: void testMoveAllFuncDefOutsideClassWithBaseClass(); void testMoveAllFuncDefOutsideIgnoreMacroCode(); - void testMoveFuncDefToDeclMemberFunc(); - void testMoveFuncDefToDeclMemberFuncOutside(); - void testMoveFuncDefToDeclMemberFuncToCppNS(); - void testMoveFuncDefToDeclMemberFuncToCppNSUsing(); - void testMoveFuncDefToDeclMemberFuncOutsideWithNs(); - void testMoveFuncDefToDeclFreeFuncToCpp(); - void testMoveFuncDefToDeclFreeFuncToCppNS(); - void testMoveFuncDefToDeclCtorWithInitialization(); - void testMoveFuncDefToDeclStructWithAssignedVariable(); + void testMoveFuncDefToDecl_data(); + void testMoveFuncDefToDecl(); + void testMoveFuncDefToDeclMacroUses(); - void testMoveFuncDefToDeclOverride(); - void testMoveFuncDefToDeclTemplate(); - void testMoveFuncDefToDeclTemplateFunction(); void testAssignToLocalVariableTemplates(); From ec46988fb76494b8c9e4b46bcb2f6b2ef374f365 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 4 Jul 2023 15:31:00 +0200 Subject: [PATCH 0007/1546] Disable output view actions if they are not applicable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In Qt Creator the output views are always accessible: The status bar shows their buttons, and if an output view is opened in a mode that doesn't have an OutputPanePlaceHolder (which defines the location), the edit mode is opened. This is not the case in Design Studio: The status bar is different, and design mode can only be opened with an open project, so e.g. after startup in the welcome screen the output view actions should be disabled. Achieve that by disabling the actions when the output view buttons in the status bar are not shown and the current mode doesn't have an OutputPanePlaceHolder. Amends 4642c5fd7ddf73b4753037c3616c2d60d5899b6e and 3befa60970f2dac2223df4f017c74f7444596015 Change-Id: I57b9ce3f80006fc2e842e38e93f1f7b50c5749f1 Reviewed-by: Henning Gründl Reviewed-by: Qt CI Bot --- src/plugins/coreplugin/outputpane.cpp | 16 +++++- src/plugins/coreplugin/outputpane.h | 2 + src/plugins/coreplugin/outputpanemanager.cpp | 54 +++++++++++++++----- src/plugins/coreplugin/outputpanemanager.h | 4 ++ 4 files changed, 61 insertions(+), 15 deletions(-) diff --git a/src/plugins/coreplugin/outputpane.cpp b/src/plugins/coreplugin/outputpane.cpp index 81473320bbd..d4011370c92 100644 --- a/src/plugins/coreplugin/outputpane.cpp +++ b/src/plugins/coreplugin/outputpane.cpp @@ -1,17 +1,20 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "imode.h" #include "modemanager.h" #include "outputpane.h" #include "outputpanemanager.h" +#include + #include #include #include using namespace Utils; +Q_GLOBAL_STATIC(QList, sPlaceholders) + namespace Core { class OutputPanePlaceHolderPrivate { @@ -36,6 +39,7 @@ OutputPanePlaceHolder *OutputPanePlaceHolderPrivate::m_current = nullptr; OutputPanePlaceHolder::OutputPanePlaceHolder(Id mode, QSplitter *parent) : QWidget(parent), d(new OutputPanePlaceHolderPrivate(mode, parent)) { + sPlaceholders->append(this); setVisible(false); setLayout(new QVBoxLayout); QSizePolicy sp; @@ -170,6 +174,11 @@ int OutputPanePlaceHolder::nonMaximizedSize() const return d->m_nonMaximizedSize; } +Id OutputPanePlaceHolder::mode() const +{ + return d->m_mode; +} + void OutputPanePlaceHolder::resizeEvent(QResizeEvent *event) { if (d->m_isMaximized || event->size().height() == 0) @@ -199,6 +208,11 @@ bool OutputPanePlaceHolder::isCurrentVisible() return OutputPanePlaceHolderPrivate::m_current && OutputPanePlaceHolderPrivate::m_current->isVisible(); } +bool OutputPanePlaceHolder::modeHasOutputPanePlaceholder(Utils::Id mode) +{ + return Utils::anyOf(*sPlaceholders, Utils::equal(&OutputPanePlaceHolder::mode, mode)); +} + } // namespace Core diff --git a/src/plugins/coreplugin/outputpane.h b/src/plugins/coreplugin/outputpane.h index 7158e1b5f54..2d3f240f749 100644 --- a/src/plugins/coreplugin/outputpane.h +++ b/src/plugins/coreplugin/outputpane.h @@ -27,11 +27,13 @@ public: static OutputPanePlaceHolder *getCurrent(); static bool isCurrentVisible(); + static bool modeHasOutputPanePlaceholder(Utils::Id mode); bool isMaximized() const; void setMaximized(bool maximize); void ensureSizeHintAsMinimum(); int nonMaximizedSize() const; + Utils::Id mode() const; signals: void visibilityChangeRequested(bool visible); diff --git a/src/plugins/coreplugin/outputpanemanager.cpp b/src/plugins/coreplugin/outputpanemanager.cpp index 66fddd1b5d4..20931a1feb5 100644 --- a/src/plugins/coreplugin/outputpanemanager.cpp +++ b/src/plugins/coreplugin/outputpanemanager.cpp @@ -373,10 +373,10 @@ OutputPaneManager::OutputPaneManager(QWidget *parent) : m_titleLabel->setContentsMargins(5, 0, 5, 0); - auto clearAction = new QAction(this); - clearAction->setIcon(Utils::Icons::CLEAN.icon()); - clearAction->setText(Tr::tr("Clear")); - connect(clearAction, &QAction::triggered, this, &OutputPaneManager::clearPage); + m_clearAction = new QAction(this); + m_clearAction->setIcon(Utils::Icons::CLEAN.icon()); + m_clearAction->setText(Tr::tr("Clear")); + connect(m_clearAction, &QAction::triggered, this, &OutputPaneManager::clearPage); m_nextAction = new QAction(this); m_nextAction->setIcon(Utils::Icons::ARROW_DOWN_TOOLBAR.icon()); @@ -442,9 +442,9 @@ OutputPaneManager::OutputPaneManager(QWidget *parent) : Command *cmd; - cmd = ActionManager::registerAction(clearAction, Constants::OUTPUTPANE_CLEAR); + cmd = ActionManager::registerAction(m_clearAction, Constants::OUTPUTPANE_CLEAR); clearButton->setDefaultAction( - ProxyAction::proxyActionWithIcon(clearAction, Utils::Icons::CLEAN_TOOLBAR.icon())); + ProxyAction::proxyActionWithIcon(m_clearAction, Utils::Icons::CLEAN_TOOLBAR.icon())); mpanes->addAction(cmd, "Coreplugin.OutputPane.ActionsGroup"); cmd = ActionManager::registerAction(m_prevAction, "Coreplugin.OutputPane.previtem"); @@ -502,11 +502,8 @@ void OutputPaneManager::initialize() }); connect(outPane, &IOutputPane::navigateStateUpdate, m_instance, [idx, outPane] { - if (m_instance->currentIndex() == idx) { - m_instance->m_prevAction->setEnabled(outPane->canNavigate() - && outPane->canPrevious()); - m_instance->m_nextAction->setEnabled(outPane->canNavigate() && outPane->canNext()); - } + if (m_instance->currentIndex() == idx) + m_instance->updateActions(outPane); }); QWidget *toolButtonsContainer = new QWidget(m_instance->m_opToolBarWidgets); @@ -569,7 +566,14 @@ void OutputPaneManager::initialize() m_instance, &OutputPaneManager::popupMenu); + updateMaximizeButton(false); // give it an initial name + m_instance->readSettings(); + + connect(ModeManager::instance(), &ModeManager::currentModeChanged, m_instance, [] { + const int index = m_instance->currentIndex(); + m_instance->updateActions(index >= 0 ? g_outputPanes.at(index).pane : nullptr); + }); } OutputPaneManager::~OutputPaneManager() = default; @@ -649,6 +653,21 @@ void OutputPaneManager::readSettings() setCurrentIndex(currentIdx); } +void OutputPaneManager::updateActions(IOutputPane *pane) +{ + const bool enabledForMode = m_buttonsWidget->isVisibleTo(m_buttonsWidget->window()) + || OutputPanePlaceHolder::modeHasOutputPanePlaceholder( + ModeManager::currentModeId()); + m_clearAction->setEnabled(enabledForMode); + m_minMaxAction->setEnabled(enabledForMode); + m_instance->m_prevAction->setEnabled(enabledForMode && pane && pane->canNavigate() + && pane->canPrevious()); + m_instance->m_nextAction->setEnabled(enabledForMode && pane && pane->canNavigate() + && pane->canNext()); + for (const OutputPaneData &d : std::as_const(g_outputPanes)) + d.action->setEnabled(enabledForMode); +} + void OutputPaneManager::slotNext() { int idx = currentIndex(); @@ -737,6 +756,15 @@ void OutputPaneManager::focusInEvent(QFocusEvent *e) w->setFocus(e->reason()); } +bool OutputPaneManager::eventFilter(QObject *o, QEvent *e) +{ + if (o == m_buttonsWidget && (e->type() == QEvent::Show || e->type() == QEvent::Hide)) { + const int index = currentIndex(); + updateActions(index >= 0 ? g_outputPanes.at(index).pane : nullptr); + } + return false; +} + void OutputPaneManager::setCurrentIndex(int idx) { static int lastIndex = -1; @@ -756,9 +784,7 @@ void OutputPaneManager::setCurrentIndex(int idx) if (OutputPanePlaceHolder::isCurrentVisible()) pane->visibilityChanged(true); - bool canNavigate = pane->canNavigate(); - m_prevAction->setEnabled(canNavigate && pane->canPrevious()); - m_nextAction->setEnabled(canNavigate && pane->canNext()); + updateActions(pane); g_outputPanes.at(idx).button->setChecked(OutputPanePlaceHolder::isCurrentVisible()); m_titleLabel->setText(pane->displayName()); } diff --git a/src/plugins/coreplugin/outputpanemanager.h b/src/plugins/coreplugin/outputpanemanager.h index 74c14012ccc..b89d49595d3 100644 --- a/src/plugins/coreplugin/outputpanemanager.h +++ b/src/plugins/coreplugin/outputpanemanager.h @@ -17,6 +17,7 @@ QT_END_NAMESPACE namespace Core { class ICore; +class IOutputPane; namespace Internal { @@ -50,6 +51,7 @@ public slots: protected: void focusInEvent(QFocusEvent *e) override; + bool eventFilter(QObject *o, QEvent *e) override; private: // the only class that is allowed to create and destroy @@ -71,10 +73,12 @@ private: void setCurrentIndex(int idx); void buttonTriggered(int idx); void readSettings(); + void updateActions(IOutputPane *pane); QLabel *m_titleLabel = nullptr; OutputPaneManageButton *m_manageButton = nullptr; + QAction *m_clearAction = nullptr; QAction *m_minMaxAction = nullptr; QAction *m_nextAction = nullptr; QAction *m_prevAction = nullptr; From d4a5096c76dea225c526b0febe3220dcaf661ee3 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 5 Oct 2023 07:08:26 +0200 Subject: [PATCH 0008/1546] QtKeyChain: Improve cmake build Do not hard require pkgconfig or QtDbus. Change-Id: Ic989a1937ecf8d8e3e270166a363740c8a6ec3ff Reviewed-by: Eike Ziller --- src/libs/3rdparty/qtkeychain/CMakeLists.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libs/3rdparty/qtkeychain/CMakeLists.txt b/src/libs/3rdparty/qtkeychain/CMakeLists.txt index 8e31ed44d6a..7b2cc6d88f8 100644 --- a/src/libs/3rdparty/qtkeychain/CMakeLists.txt +++ b/src/libs/3rdparty/qtkeychain/CMakeLists.txt @@ -31,11 +31,11 @@ extend_qtc_library(qtkeychain ) if (UNIX AND NOT APPLE) - find_package(Qt6 COMPONENTS DBus REQUIRED) + find_package(Qt6 COMPONENTS DBus) option(LIBSECRET_SUPPORT "Build with libsecret support if available" ON) if (LIBSECRET_SUPPORT) - find_package(PkgConfig REQUIRED) + find_package(PkgConfig) include(FindPkgConfig) pkg_check_modules(LIBSECRET libsecret-1) @@ -53,6 +53,8 @@ if (UNIX AND NOT APPLE) ${CMAKE_CURRENT_SOURCE_DIR}/org.kde.KWallet.xml kwallet_interface KWalletInterface) extend_qtc_library(qtkeychain + CONDITION TARGET Qt::DBus + FEATURE_INFO "keychain dbus support" DEFINES KEYCHAIN_DBUS=1 DEPENDS Qt::DBus SOURCES From 6b81c93a666644caab255804ad222af0087a2334 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 2 Oct 2023 13:27:17 +0200 Subject: [PATCH 0009/1546] CppEditor: Add a second variant of "move def to decl" quickfix This time with the cursor on the declaration. Fixes: QTCREATORBUG-9515 Change-Id: I50b2ac8516f4df98e4cc9e3ffa60a9e5cf079c4e Reviewed-by: Reviewed-by: Christian Stenger --- src/plugins/cppeditor/cppquickfix_test.cpp | 49 ++++++---- src/plugins/cppeditor/cppquickfixes.cpp | 100 ++++++++++++++++++--- src/plugins/cppeditor/cppquickfixes.h | 13 ++- 3 files changed, 134 insertions(+), 28 deletions(-) diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index de03b5c24c9..ee18f28603c 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -7256,7 +7256,7 @@ void QuickfixTest::testMoveFuncDefToDecl_data() originalHeader = "class Foo {\n" - " inline int number() const;\n" + " inline int @number() const;\n" "};\n"; expectedHeader = "class Foo {\n" @@ -7274,7 +7274,7 @@ void QuickfixTest::testMoveFuncDefToDecl_data() originalSource = "class Foo {\n" - " inline int number() const;\n" + " inline int @number() const;\n" "};\n" "\n" "int Foo::num@ber() const\n" @@ -7295,7 +7295,7 @@ void QuickfixTest::testMoveFuncDefToDecl_data() originalHeader = "namespace MyNs {\n" "class Foo {\n" - " inline int number() const;\n" + " inline int @number() const;\n" "};\n" "}\n"; expectedHeader = @@ -7322,7 +7322,7 @@ void QuickfixTest::testMoveFuncDefToDecl_data() originalHeader = "namespace MyNs {\n" "class Foo {\n" - " inline int number() const;\n" + " inline int numbe@r() const;\n" "};\n" "}\n"; expectedHeader = @@ -7353,7 +7353,7 @@ void QuickfixTest::testMoveFuncDefToDecl_data() originalSource = "namespace MyNs {\n" "class Foo {\n" - " inline int number() const;\n" + " inline int @number() const;\n" "};\n" "\n" "int Foo::numb@er() const\n" @@ -7373,7 +7373,7 @@ void QuickfixTest::testMoveFuncDefToDecl_data() QTest::newRow("member function, one file, namespace") << QByteArrayList() << QByteArrayList{originalSource, expectedSource}; - originalHeader = "int number() const;\n"; + originalHeader = "int nu@mber() const;\n"; expectedHeader = "inline int number() const\n" "{\n" @@ -7393,7 +7393,7 @@ void QuickfixTest::testMoveFuncDefToDecl_data() originalHeader = "namespace MyNamespace {\n" - "int number() const;\n" + "int n@umber() const;\n" "}\n"; expectedHeader = "namespace MyNamespace {\n" @@ -7418,7 +7418,7 @@ void QuickfixTest::testMoveFuncDefToDecl_data() originalHeader = "class Foo {\n" "public:\n" - " Foo();\n" + " Fo@o();\n" "private:\n" " int a;\n" " float b;\n" @@ -7443,7 +7443,7 @@ void QuickfixTest::testMoveFuncDefToDecl_data() originalSource = "struct Foo\n" "{\n" - " void foo();\n" + " void f@oo();\n" "} bar;\n" "void Foo::fo@o()\n" "{\n" @@ -7465,7 +7465,7 @@ void QuickfixTest::testMoveFuncDefToDecl_data() " virtual int foo() = 0;\n" "};\n" "struct Derived : Base {\n" - " int foo() override;\n" + " int @foo() override;\n" "};\n" "\n" "int Derived::fo@o()\n" @@ -7487,7 +7487,7 @@ void QuickfixTest::testMoveFuncDefToDecl_data() originalSource = "template\n" - "class Foo { void func(); };\n" + "class Foo { void @func(); };\n" "\n" "template\n" "void Foo::fu@nc() {}\n"; @@ -7501,7 +7501,7 @@ void QuickfixTest::testMoveFuncDefToDecl_data() "class Foo\n" "{\n" " template\n" - " void func();\n" + " void @func();\n" "};\n" "\n" "template\n" @@ -7524,15 +7524,32 @@ void QuickfixTest::testMoveFuncDefToDecl() QVERIFY(headers.isEmpty() || headers.size() == 2); QVERIFY(sources.size() == 2); + QByteArray &declDoc = !headers.empty() ? headers.first() : sources.first(); + const int declCursorPos = declDoc.indexOf('@'); + QVERIFY(declCursorPos != -1); + const int defCursorPos = sources.first().lastIndexOf('@'); + QVERIFY(defCursorPos != -1); + QVERIFY(declCursorPos != defCursorPos); + + declDoc.remove(declCursorPos, 1); QList testDocuments; if (!headers.isEmpty()) testDocuments << CppTestDocument::create("file.h", headers.first(), headers.last()); testDocuments << CppTestDocument::create("file.cpp", sources.first(), sources.last()); - MoveFuncDefToDecl factory; - QuickFixOperationTest(testDocuments, &factory); -} + MoveFuncDefToDeclPush pushFactory; + QuickFixOperationTest(testDocuments, &pushFactory); + declDoc.insert(declCursorPos, '@'); + sources.first().remove(defCursorPos, 1); + testDocuments.clear(); + if (!headers.isEmpty()) + testDocuments << CppTestDocument::create("file.h", headers.first(), headers.last()); + testDocuments << CppTestDocument::create("file.cpp", sources.first(), sources.last()); + + MoveFuncDefToDeclPull pullFactory; + QuickFixOperationTest(testDocuments, &pullFactory); +} void QuickfixTest::testMoveFuncDefToDeclMacroUses() { @@ -7560,7 +7577,7 @@ void QuickfixTest::testMoveFuncDefToDeclMacroUses() " }\n" "};\n\n\n\n"; - MoveFuncDefToDecl factory; + MoveFuncDefToDeclPush factory; QuickFixOperationTest(singleDocument(original, expected), &factory, ProjectExplorer::HeaderPaths(), 0, "QTCREATORBUG-12314"); } diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index a65c9b61a47..77b5bd5e452 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -6763,20 +6763,25 @@ namespace { class MoveFuncDefToDeclOp : public CppQuickFixOperation { public: + enum Type { Push, Pull }; MoveFuncDefToDeclOp(const CppQuickFixInterface &interface, const FilePath &fromFilePath, const FilePath &toFilePath, - FunctionDefinitionAST *funcDef, const QString &declText, + FunctionDefinitionAST *funcAst, Function *func, const QString &declText, const ChangeSet::Range &fromRange, - const ChangeSet::Range &toRange) + const ChangeSet::Range &toRange, + Type type) : CppQuickFixOperation(interface, 0) , m_fromFilePath(fromFilePath) , m_toFilePath(toFilePath) - , m_funcAST(funcDef) + , m_funcAST(funcAst) + , m_func(func) , m_declarationText(declText) , m_fromRange(fromRange) , m_toRange(toRange) { - if (m_toFilePath == m_fromFilePath) { + if (type == Type::Pull) { + setDescription(Tr::tr("Move Definition Here")); + } else if (m_toFilePath == m_fromFilePath) { setDescription(Tr::tr("Move Definition to Class")); } else { const FilePath resolved = m_toFilePath.relativePathFrom(m_fromFilePath.parentDir()); @@ -6784,12 +6789,17 @@ public: } } +private: void perform() override { CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr fromFile = refactoring.file(m_fromFilePath); CppRefactoringFilePtr toFile = refactoring.file(m_toFilePath); + ensureFuncDefAstAndRange(*fromFile); + if (!m_funcAST) + return; + const QString wholeFunctionText = m_declarationText + fromFile->textOf(fromFile->endOf(m_funcAST->declarator), fromFile->endOf(m_funcAST->function_body)); @@ -6811,18 +6821,44 @@ public: } } -private: + void ensureFuncDefAstAndRange(CppRefactoringFile &defFile) + { + if (m_funcAST) { + QTC_CHECK(m_fromRange.end > m_fromRange.start); + return; + } + QTC_ASSERT(m_func, return); + const QList astPath = ASTPath(defFile.cppDocument())(m_func->line(), + m_func->column()); + if (astPath.isEmpty()) + return; + for (auto it = std::rbegin(astPath); it != std::rend(astPath); ++it) { + m_funcAST = (*it)->asFunctionDefinition(); + if (!m_funcAST) + continue; + AST *astForRange = m_funcAST; + const auto prev = std::next(it); + if (prev != std::rend(astPath)) { + if (const auto templAst = (*prev)->asTemplateDeclaration()) + astForRange = templAst; + } + m_fromRange = defFile.range(astForRange); + return; + } + } + const FilePath m_fromFilePath; const FilePath m_toFilePath; FunctionDefinitionAST *m_funcAST; + Function *m_func; const QString m_declarationText; - const ChangeSet::Range m_fromRange; + ChangeSet::Range m_fromRange; const ChangeSet::Range m_toRange; }; } // anonymous namespace -void MoveFuncDefToDecl::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void MoveFuncDefToDeclPush::match(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); AST *completeDefAST = nullptr; @@ -6937,10 +6973,53 @@ void MoveFuncDefToDecl::match(const CppQuickFixInterface &interface, QuickFixOpe result << new MoveFuncDefToDeclOp(interface, interface.filePath(), declFilePath, - funcAST, declText, - defRange, declRange); + funcAST, func, declText, + defRange, declRange, MoveFuncDefToDeclOp::Push); } +void MoveFuncDefToDeclPull::match(const CppQuickFixInterface &interface, + QuickFixOperations &result) +{ + const QList &path = interface.path(); + for (auto it = std::rbegin(path); it != std::rend(path); ++it) { + SimpleDeclarationAST * const simpleDecl = (*it)->asSimpleDeclaration(); + if (!simpleDecl) + continue; + const auto prev = std::next(it); + if (prev != std::rend(path) && (*prev)->asStatement()) + return; + if (!simpleDecl->symbols || !simpleDecl->symbols->value || simpleDecl->symbols->next) + return; + Declaration * const decl = simpleDecl->symbols->value->asDeclaration(); + if (!decl) + return; + Function * const funcDecl = decl->type()->asFunctionType(); + if (!funcDecl) + return; + if (funcDecl->isSignal() || funcDecl->isPureVirtual() || funcDecl->isFriend()) + return; + + // Is there a definition? + SymbolFinder symbolFinder; + Function * const funcDef = symbolFinder.findMatchingDefinition(decl, interface.snapshot(), + true); + if (!funcDef) + return; + + QString declText = interface.currentFile()->textOf(simpleDecl); + declText.chop(1); // semicolon + declText.prepend(inlinePrefix(interface.filePath(), [funcDecl] { + return !funcDecl->enclosingScope()->asClass(); + })); + result << new MoveFuncDefToDeclOp(interface, funcDef->filePath(), decl->filePath(), nullptr, + funcDef, declText, {}, + interface.currentFile()->range(simpleDecl), + MoveFuncDefToDeclOp::Pull); + return; + } +} + + namespace { class AssignToLocalVariableOperation : public CppQuickFixOperation @@ -9744,7 +9823,8 @@ void createCppQuickFixes() new MoveFuncDefOutside; new MoveAllFuncDefOutside; - new MoveFuncDefToDecl; + new MoveFuncDefToDeclPush; + new MoveFuncDefToDeclPull; new AssignToLocalVariable; diff --git a/src/plugins/cppeditor/cppquickfixes.h b/src/plugins/cppeditor/cppquickfixes.h index 8825e6df911..d4c038318b4 100644 --- a/src/plugins/cppeditor/cppquickfixes.h +++ b/src/plugins/cppeditor/cppquickfixes.h @@ -520,9 +520,18 @@ public: }; /*! - Moves the definition of a function to its declaration. + Moves the definition of a function to its declaration, with the cursor on the definition. */ -class MoveFuncDefToDecl: public CppQuickFixFactory +class MoveFuncDefToDeclPush : public CppQuickFixFactory +{ +public: + void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; +}; + +/*! + Moves the definition of a function to its declaration, with the cursor on the declaration. + */ +class MoveFuncDefToDeclPull : public CppQuickFixFactory { public: void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; From 007fd9fa9b9588ff66f2cc5863c42069f61307cb Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 4 Oct 2023 15:42:20 +0200 Subject: [PATCH 0010/1546] ProjectExplorer: Let users define a common run environment That is, environment variables that should be set in all run configurations of all projects, but not e.g. in build configurations. Fixes: QTCREATORBUG-29530 Change-Id: If48d6d9bf006a293c2cbbf0d8d1aa16f9bf604f4 Reviewed-by: Reviewed-by: Christian Stenger --- .../projectexplorer/environmentaspect.cpp | 9 +++++ .../projectexplorer/projectexplorer.cpp | 5 +++ .../projectexplorersettings.cpp | 35 +++++++++++++++++++ .../projectexplorer/projectexplorersettings.h | 3 ++ 4 files changed, 52 insertions(+) diff --git a/src/plugins/projectexplorer/environmentaspect.cpp b/src/plugins/projectexplorer/environmentaspect.cpp index 89d75e36195..af4d8449d1c 100644 --- a/src/plugins/projectexplorer/environmentaspect.cpp +++ b/src/plugins/projectexplorer/environmentaspect.cpp @@ -6,6 +6,8 @@ #include "buildconfiguration.h" #include "environmentaspectwidget.h" #include "kit.h" +#include "projectexplorer.h" +#include "projectexplorersettings.h" #include "projectexplorertr.h" #include "target.h" @@ -28,6 +30,13 @@ EnvironmentAspect::EnvironmentAspect(AspectContainer *container) setId("EnvironmentAspect"); setConfigWidgetCreator([this] { return new EnvironmentAspectWidget(this); }); addDataExtractor(this, &EnvironmentAspect::environment, &Data::environment); + if (qobject_cast(container)) { + addModifier([](Environment &env) { + env.modify(ProjectExplorerPlugin::projectExplorerSettings().appEnvChanges); + }); + connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::settingsChanged, + this, &EnvironmentAspect::environmentChanged); + } } void EnvironmentAspect::setDeviceSelector(Target *target, DeviceSelector selector) diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 6a4eba09116..bd1cecbf7eb 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -274,6 +274,7 @@ const char CLEAR_ISSUES_ON_REBUILD_SETTINGS_KEY[] = "ProjectExplorer/Settings/Cl const char ABORT_BUILD_ALL_ON_ERROR_SETTINGS_KEY[] = "ProjectExplorer/Settings/AbortBuildAllOnError"; const char LOW_BUILD_PRIORITY_SETTINGS_KEY[] = "ProjectExplorer/Settings/LowBuildPriority"; +const char APP_ENV_CHANGES_SETTINGS_KEY[] = "ProjectExplorer/Settings/AppEnvChanges"; const char CUSTOM_PARSER_COUNT_KEY[] = "ProjectExplorer/Settings/CustomParserCount"; const char CUSTOM_PARSER_PREFIX_KEY[] = "ProjectExplorer/Settings/CustomParser"; @@ -1701,6 +1702,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er dd->m_projectExplorerSettings.lowBuildPriority = s->value(Constants::LOW_BUILD_PRIORITY_SETTINGS_KEY, defaultSettings.lowBuildPriority) .toBool(); + dd->m_projectExplorerSettings.appEnvChanges = EnvironmentItem::fromStringList( + s->value(Constants::APP_ENV_CHANGES_SETTINGS_KEY).toStringList()); const int customParserCount = s->value(Constants::CUSTOM_PARSER_COUNT_KEY).toInt(); for (int i = 0; i < customParserCount; ++i) { @@ -2260,6 +2263,8 @@ void ProjectExplorerPluginPrivate::savePersistentSettings() s->setValueWithDefault(Constants::STOP_BEFORE_BUILD_SETTINGS_KEY, int(dd->m_projectExplorerSettings.stopBeforeBuild), int(defaultSettings.stopBeforeBuild)); + s->setValueWithDefault(Constants::APP_ENV_CHANGES_SETTINGS_KEY, + EnvironmentItem::toStringList(dd->m_projectExplorerSettings.appEnvChanges)); buildPropertiesSettings().writeSettings(); // FIXME: Should not be needed. diff --git a/src/plugins/projectexplorer/projectexplorersettings.cpp b/src/plugins/projectexplorer/projectexplorersettings.cpp index 14f66b885bf..aa60eb49926 100644 --- a/src/plugins/projectexplorer/projectexplorersettings.cpp +++ b/src/plugins/projectexplorer/projectexplorersettings.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -20,6 +21,7 @@ #include #include #include +#include #include using namespace Core; @@ -52,8 +54,10 @@ public: private: void slotDirectoryButtonGroupChanged(); + void updateAppEnvChangesLabel(); mutable ProjectExplorerSettings m_settings; + Utils::EnvironmentItems m_appEnvChanges; QRadioButton *m_currentDirectoryRadioButton; QRadioButton *m_directoryRadioButton; PathChooser *m_projectsDirectoryPathChooser; @@ -70,6 +74,7 @@ private: QComboBox *m_stopBeforeBuildComboBox; QComboBox *m_terminalModeComboBox; QCheckBox *m_jomCheckbox; + Utils::ElidingLabel *m_appEnvLabel; QButtonGroup *m_directoryButtonGroup; }; @@ -122,6 +127,25 @@ ProjectExplorerSettingsWidget::ProjectExplorerSettingsWidget() "Disable it if you experience problems with your builds."); jomLabel->setWordWrap(true); + const QString appEnvToolTip = Tr::tr("Environment changes to apply to run configurations, " + "but not build configurations."); + const auto appEnvDescriptionLabel = new QLabel(Tr::tr("Application environment:")); + appEnvDescriptionLabel->setToolTip(appEnvToolTip); + m_appEnvLabel = new Utils::ElidingLabel; + m_appEnvLabel->setElideMode(Qt::ElideRight); + m_appEnvLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + const auto appEnvButton = new QPushButton(Tr::tr("Change...")); + appEnvButton->setSizePolicy(QSizePolicy::Fixed, appEnvButton->sizePolicy().verticalPolicy()); + appEnvButton->setToolTip(appEnvToolTip); + connect(appEnvButton, &QPushButton::clicked, this, [appEnvButton, this] { + std::optional changes + = EnvironmentDialog::getEnvironmentItems(appEnvButton, m_appEnvChanges); + if (!changes) + return; + m_appEnvChanges = *changes; + updateAppEnvChangesLabel(); + }); + using namespace Layouting; Column { Group { @@ -149,6 +173,7 @@ ProjectExplorerSettingsWidget::ProjectExplorerSettingsWidget() m_abortBuildAllOnErrorCheckBox, m_lowBuildPriorityCheckBox, Form { + appEnvDescriptionLabel, Row{m_appEnvLabel, appEnvButton, st}, br, Tr::tr("Build before deploying:"), m_buildBeforeDeployComboBox, br, Tr::tr("Stop applications before building:"), m_stopBeforeBuildComboBox, br, Tr::tr("Default for \"Run in terminal\":"), m_terminalModeComboBox, br, @@ -174,6 +199,7 @@ ProjectExplorerSettingsWidget::ProjectExplorerSettingsWidget() setSettings(ProjectExplorerPlugin::projectExplorerSettings()); setProjectsDirectory(DocumentManager::projectsDirectory()); setUseProjectsDirectory(DocumentManager::useProjectsDirectory()); + updateAppEnvChangesLabel(); } ProjectExplorerSettings ProjectExplorerSettingsWidget::settings() const @@ -193,12 +219,14 @@ ProjectExplorerSettings ProjectExplorerSettingsWidget::settings() const m_settings.clearIssuesOnRebuild = m_clearIssuesCheckBox->isChecked(); m_settings.abortBuildAllOnError = m_abortBuildAllOnErrorCheckBox->isChecked(); m_settings.lowBuildPriority = m_lowBuildPriorityCheckBox->isChecked(); + m_settings.appEnvChanges = m_appEnvChanges; return m_settings; } void ProjectExplorerSettingsWidget::setSettings(const ProjectExplorerSettings &pes) { m_settings = pes; + m_appEnvChanges = pes.appEnvChanges; m_buildBeforeDeployComboBox->setCurrentIndex( m_buildBeforeDeployComboBox->findData(int(m_settings.buildBeforeDeploy))); m_deployProjectBeforeRunCheckBox->setChecked(m_settings.deployBeforeRun); @@ -245,6 +273,13 @@ void ProjectExplorerSettingsWidget::slotDirectoryButtonGroupChanged() m_projectsDirectoryPathChooser->setEnabled(enable); } +void ProjectExplorerSettingsWidget::updateAppEnvChangesLabel() +{ + const QString shortSummary = EnvironmentItem::toStringList(m_appEnvChanges).join("; "); + m_appEnvLabel->setText(shortSummary.isEmpty() ? Tr::tr("No changes to apply.") + : shortSummary); +} + // ProjectExplorerSettingsPage ProjectExplorerSettingsPage::ProjectExplorerSettingsPage() diff --git a/src/plugins/projectexplorer/projectexplorersettings.h b/src/plugins/projectexplorer/projectexplorersettings.h index 48cc85c414b..244d4c76f87 100644 --- a/src/plugins/projectexplorer/projectexplorersettings.h +++ b/src/plugins/projectexplorer/projectexplorersettings.h @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -34,6 +35,7 @@ public: && p1.closeSourceFilesWithProject == p2.closeSourceFilesWithProject && p1.clearIssuesOnRebuild == p2.clearIssuesOnRebuild && p1.abortBuildAllOnError == p2.abortBuildAllOnError + && p1.appEnvChanges == p2.appEnvChanges && p1.lowBuildPriority == p2.lowBuildPriority; } @@ -52,6 +54,7 @@ public: ? StopBeforeBuild::SameProject : StopBeforeBuild::None; TerminalMode terminalMode = TerminalMode::Off; + Utils::EnvironmentItems appEnvChanges; // Add a UUid which is used to identify the development environment. // This is used to warn the user when he is trying to open a .user file that was created From ef63c39266b410cef2ab6d79ca3ef3e1615cf574 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Tue, 10 Oct 2023 20:30:00 +0900 Subject: [PATCH 0011/1546] Remove QtQuick 1 support from C++ Class wizard QtQuick 1 is not part of Qt since Qt 5.6 Change-Id: I9fbbafe8a10a81dc6f4833301ecb124d459d5b3b Reviewed-by: Reviewed-by: Eike Ziller Reviewed-by: hjk --- ...eator-projects-custom-wizards-json.qdocinc | 4 ++-- .../templates/wizards/classes/cpp/file.h | 2 -- .../templates/wizards/classes/cpp/wizard.json | 19 ++++--------------- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/doc/qtcreator/src/projects/creator-only/creator-projects-custom-wizards-json.qdocinc b/doc/qtcreator/src/projects/creator-only/creator-projects-custom-wizards-json.qdocinc index 852bfeb2461..59374c149df 100644 --- a/doc/qtcreator/src/projects/creator-only/creator-projects-custom-wizards-json.qdocinc +++ b/doc/qtcreator/src/projects/creator-only/creator-projects-custom-wizards-json.qdocinc @@ -237,7 +237,7 @@ { "key": "SrcPath", "value": "%{Path}/%{SrcFileName}" }, { "key": "CN", "value": "%{JS: Cpp.className(value('Class'))}" }, { "key": "Base", "value": "%{JS: value('BaseCB') === '' ? value('BaseEdit') : value('BaseCB')}" }, - { "key": "isQObject", "value": "%{JS: (value('Base') === 'QObject' || value('Base') === 'QWidget' || value('Base') === 'QMainWindow' || value('Base') === 'QDeclarativeItem' || value('Base') === 'QQuickItem' ) ? 'true' : 'false'}" }, + { "key": "isQObject", "value": "%{JS: (value('Base') === 'QObject' || value('Base') === 'QWidget' || value('Base') === 'QMainWindow' || value('Base') === 'QQuickItem' ) ? 'true' : 'false'}" }, { "key": "GUARD", "value": "%{JS: Cpp.classToHeaderGuard(value('Class'), Util.suffix(value('HdrFileName'))}" }, { "key": "SharedDataInit", "value": "%{JS: value('IncludeQSharedData') ? 'data(new %{CN}Data)' : '' }" } ], @@ -699,7 +699,7 @@ "data": { "items": [ { "trKey": "", "value": "" }, - "QObject", "QWidget", "QMainWindow", "QDeclarativeItem", "QQuickItem" ] + "QObject", "QWidget", "QMainWindow", "QQuickItem" ] } }, \endcode diff --git a/share/qtcreator/templates/wizards/classes/cpp/file.h b/share/qtcreator/templates/wizards/classes/cpp/file.h index aa5e50913ad..4d49c2c3ca2 100644 --- a/share/qtcreator/templates/wizards/classes/cpp/file.h +++ b/share/qtcreator/templates/wizards/classes/cpp/file.h @@ -10,12 +10,10 @@ %{JS: QtSupport.qtIncludes([ ( '%{IncludeQObject}' ) ? 'QtCore/%{IncludeQObject}' : '', ( '%{IncludeQWidget}' ) ? 'QtGui/%{IncludeQWidget}' : '', ( '%{IncludeQMainWindow}' ) ? 'QtGui/%{IncludeQMainWindow}' : '', - ( '%{IncludeQDeclarativeItem}' ) ? 'QtDeclarative/%{IncludeQDeclarativeItem}' : '', ( '%{IncludeQSharedData}' ) ? 'QtCore/QSharedDataPointer' : '' ], [ ( '%{IncludeQObject}' ) ? 'QtCore/%{IncludeQObject}' : '', ( '%{IncludeQWidget}' ) ? 'QtWidgets/%{IncludeQWidget}' : '', ( '%{IncludeQMainWindow}' ) ? 'QtWidgets/%{IncludeQMainWindow}' : '', - ( '%{IncludeQDeclarativeItem}' ) ? 'QtQuick1/%{IncludeQDeclarativeItem}' : '', ( '%{IncludeQQuickItem}' ) ? 'QtDeclarative/%{IncludeQQuickItem}' : '', ( '%{AddQmlElementMacro}' && !'%{IncludeQQuickItem}' ) ? 'QtQml/QQmlEngine' : '', ( '%{IncludeQSharedData}' ) ? 'QtCore/QSharedDataPointer' : '' ])}\ diff --git a/share/qtcreator/templates/wizards/classes/cpp/wizard.json b/share/qtcreator/templates/wizards/classes/cpp/wizard.json index 06e856c1ab5..22aa8fb152e 100644 --- a/share/qtcreator/templates/wizards/classes/cpp/wizard.json +++ b/share/qtcreator/templates/wizards/classes/cpp/wizard.json @@ -16,7 +16,7 @@ { "key": "SrcPath", "value": "%{Path}/%{SrcFileName}" }, { "key": "CN", "value": "%{JS: Cpp.className(value('Class'))}" }, { "key": "Base", "value": "%{JS: value('BaseCB') === '' ? value('BaseEdit') : value('BaseCB')}" }, - { "key": "isQObject", "value": "%{JS: [ 'QObject', 'QWidget', 'QMainWindow', 'QDeclarativeItem', 'QQuickItem'].indexOf(value('Base')) >= 0 }" }, + { "key": "isQObject", "value": "%{JS: [ 'QObject', 'QWidget', 'QMainWindow', 'QQuickItem'].indexOf(value('Base')) >= 0 }" }, { "key": "GUARD", "value": "%{JS: Cpp.classToHeaderGuard(value('Class'), Util.suffix(value('HdrFileName')))}" }, { "key": "SharedDataInit", "value": "%{JS: (value('IncludeQSharedData')) ? 'data(new %{CN}Data)' : '' }" }, { "key": "Dependencies", "value": "%{JS: '' + (value('IncludeQObject') || value('IncludeQSharedData') || value('BaseCB') === 'QObject' ? ':Qt.core' : '') + (value('IncludeQWidget') || value('IncludeQMainWindow') || value('BaseCB') === 'QWidget' || value('BaseCB') === 'QMainWindow' ? ':Qt.widgets' : '') + (value('IncludeQQuickItem') || value('BaseCB') === 'QQuickItem' ? ':Qt.quick' : '')}"} @@ -48,7 +48,7 @@ "data": { "items": [ { "trKey": "", "value": "" }, - "QObject", "QWidget", "QMainWindow", "QDeclarativeItem", "QQuickItem" ] + "QObject", "QWidget", "QMainWindow", "QQuickItem" ] } }, { @@ -102,20 +102,9 @@ "checked": "%{JS: value('BaseCB') === 'QMainWindow'}" } }, - { - "name": "IncludeQDeclarativeItem", - "trDisplayName": "Include QDeclarativeItem - Qt Quick 1", - "type": "CheckBox", - "data": - { - "checkedValue": "QDeclarativeItem", - "uncheckedValue": "", - "checked": "%{JS: value('BaseCB') === 'QDeclarativeItem'}" - } - }, { "name": "IncludeQQuickItem", - "trDisplayName": "Include QQuickItem - Qt Quick 2", + "trDisplayName": "Include QQuickItem", "type": "CheckBox", "data": { @@ -143,7 +132,7 @@ { "checkedValue": "AddQObjectMacro", "uncheckedValue": "", - "checked": "%{JS: [ 'QObject', 'QWidget', 'QMainWindow', 'QDeclarativeItem', 'QQuickItem'].indexOf(value('Base')) >= 0 }" + "checked": "%{JS: [ 'QObject', 'QWidget', 'QMainWindow', 'QQuickItem'].indexOf(value('Base')) >= 0 }" } }, { From a1f994c1a76962013d6174f98a3b6d066b33ac99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20De=20Canni=C3=A8re?= Date: Wed, 27 Sep 2023 15:24:57 +0200 Subject: [PATCH 0012/1546] Doc: Change documentation entry for removed M325 static analysis warning The code generating the M325 warning was reverted with [1]. Consequently, the documentation about it needs to be adapted to inform users of this change. [1] eb5cdb4293be8c4c878425ea9d45f5c105205bb2 Change-Id: If5e17cbf949dd2f432ebccb4720361dd855180b6 Reviewed-by: Sami Shalayel --- doc/qtcreator/src/editors/creator-code-syntax.qdoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/qtcreator/src/editors/creator-code-syntax.qdoc b/doc/qtcreator/src/editors/creator-code-syntax.qdoc index 87203f8bd3a..61a6a91b4ef 100644 --- a/doc/qtcreator/src/editors/creator-code-syntax.qdoc +++ b/doc/qtcreator/src/editors/creator-code-syntax.qdoc @@ -662,7 +662,7 @@ \li M325 \li Warning \li Logical value does not depend on actual values - \li + \li Removed: This warning is no longer being used since Qt Creator version 12. \row \li M326 From 4ca57ffd87232ba0d61bd0f225831daa54cda0d7 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 7 Sep 2023 10:43:39 +0200 Subject: [PATCH 0013/1546] Doc: Add qtquickcontrols as a dependency ...to fix a broken link to Button docs. Change-Id: Ie40f45d5ca033a2bdb6540822d6b7124ab4529e2 Reviewed-by: Leena Miettinen --- doc/qtcreator/config/qtcreator-project.qdocconf | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/qtcreator/config/qtcreator-project.qdocconf b/doc/qtcreator/config/qtcreator-project.qdocconf index d36bba7595c..4b350b2f443 100644 --- a/doc/qtcreator/config/qtcreator-project.qdocconf +++ b/doc/qtcreator/config/qtcreator-project.qdocconf @@ -27,6 +27,7 @@ depends += qtwidgets \ qtcore \ qtqml \ qtquick \ + qtquickcontrols \ qmake \ qtdesigner \ qtdoc \ From 8608cc2a13a215732079a137dd8385beea82c00b Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 13 Oct 2023 11:38:05 +0200 Subject: [PATCH 0014/1546] TextEditor: improve unindent If there are no spaces in front of the text cursor unindent the whole line. Fixes: QTCREATORBUG-29742 Change-Id: I7daaf1670c1378e6b40b959ef7114c87ffe4115c Reviewed-by: Marcus Tillmanns --- src/plugins/texteditor/textdocument.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp index ddc25d2a276..3556a08caa0 100644 --- a/src/plugins/texteditor/textdocument.cpp +++ b/src/plugins/texteditor/textdocument.cpp @@ -151,12 +151,16 @@ MultiTextCursor TextDocumentPrivate::indentOrUnindent(const MultiTextCursor &cur } } } else { - QString text = startBlock.text(); + const QString text = startBlock.text(); int indentPosition = tabSettings.positionAtColumn(text, column, nullptr, true); - int spaces = tabSettings.spacesLeftFromPosition(text, indentPosition); - int startColumn = tabSettings.columnAt(text, indentPosition - spaces); - int targetColumn = tabSettings.indentedColumn(tabSettings.columnAt(text, indentPosition), - doIndent); + int spaces = TabSettings::spacesLeftFromPosition(text, indentPosition); + if (!doIndent && spaces == 0) { + indentPosition = tabSettings.firstNonSpace(text); + spaces = TabSettings::spacesLeftFromPosition(text, indentPosition); + } + const int startColumn = tabSettings.columnAt(text, indentPosition - spaces); + const int targetColumn + = tabSettings.indentedColumn(tabSettings.columnAt(text, indentPosition), doIndent); cursor.setPosition(startBlock.position() + indentPosition); cursor.setPosition(startBlock.position() + indentPosition - spaces, QTextCursor::KeepAnchor); From 808c78eec8c8a8be7452b91a9cef837b3aa6d831 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 13 Oct 2023 12:40:21 +0200 Subject: [PATCH 0015/1546] TextEditor: make unindents the default for backspace Task-number: QTCREATORBUG-29745 Change-Id: Ic26ded3bfd8ae45a3046dc07f8c9037e373453b3 Reviewed-by: Marcus Tillmanns --- src/plugins/texteditor/typingsettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/texteditor/typingsettings.cpp b/src/plugins/texteditor/typingsettings.cpp index 3f9a42f9f7f..ebf8452305f 100644 --- a/src/plugins/texteditor/typingsettings.cpp +++ b/src/plugins/texteditor/typingsettings.cpp @@ -21,7 +21,7 @@ namespace TextEditor { TypingSettings::TypingSettings(): m_autoIndent(true), m_tabKeyBehavior(TabNeverIndents), - m_smartBackspaceBehavior(BackspaceNeverIndents), + m_smartBackspaceBehavior(BackspaceUnindents), m_preferSingleLineComments(false) { } From 13f5367611af2084eca5202428f1e0cacec9f0bf Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 16 Oct 2023 15:07:08 +0200 Subject: [PATCH 0016/1546] Core: Use icon based on document's full path This makes a difference when one wants to e.g. mark non existing files. Change-Id: Id7c2a53fa91fb9638e9a08a746614a3f04da400f Reviewed-by: Eike Ziller --- src/plugins/coreplugin/editormanager/documentmodel.cpp | 2 ++ src/plugins/coreplugin/editormanager/documentmodel.h | 2 ++ src/plugins/coreplugin/editormanager/openeditorsview.cpp | 6 ++++-- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/plugins/coreplugin/editormanager/documentmodel.cpp b/src/plugins/coreplugin/editormanager/documentmodel.cpp index e8183401bf6..d7eb164dd2e 100644 --- a/src/plugins/coreplugin/editormanager/documentmodel.cpp +++ b/src/plugins/coreplugin/editormanager/documentmodel.cpp @@ -307,6 +307,8 @@ QVariant DocumentModelPrivate::data(const QModelIndex &index, int role) const return QVariant(); case Qt::ToolTipRole: return entry->filePath().isEmpty() ? entry->displayName() : entry->filePath().toUserOutput(); + case DocumentModel::FilePathRole: + return entry->filePath().toVariant(); default: break; } diff --git a/src/plugins/coreplugin/editormanager/documentmodel.h b/src/plugins/coreplugin/editormanager/documentmodel.h index 6c7d0f0be32..3ac2a52c202 100644 --- a/src/plugins/coreplugin/editormanager/documentmodel.h +++ b/src/plugins/coreplugin/editormanager/documentmodel.h @@ -69,6 +69,8 @@ public: static QList editorsForDocuments(const QList &entries); static QList editorsForOpenedDocuments(); + static const int FilePathRole = Qt::UserRole + 23; + private: DocumentModel(); }; diff --git a/src/plugins/coreplugin/editormanager/openeditorsview.cpp b/src/plugins/coreplugin/editormanager/openeditorsview.cpp index ebf2d751ec9..34e58565a94 100644 --- a/src/plugins/coreplugin/editormanager/openeditorsview.cpp +++ b/src/plugins/coreplugin/editormanager/openeditorsview.cpp @@ -17,6 +17,8 @@ #include #include +using namespace Utils; + namespace Core::Internal { class ProxyModel : public QAbstractProxyModel @@ -253,8 +255,8 @@ QVariant ProxyModel::data(const QModelIndex &index, int role) const const QVariant sourceDecoration = QAbstractProxyModel::data(index, role); if (sourceDecoration.isValid()) return sourceDecoration; - const QString fileName = QAbstractProxyModel::data(index, Qt::DisplayRole).toString(); - return Utils::FileIconProvider::icon(Utils::FilePath::fromString(fileName)); + const QVariant filePath = QAbstractProxyModel::data(index, DocumentModel::FilePathRole); + return FileIconProvider::icon(FilePath::fromVariant(filePath)); } return QAbstractProxyModel::data(index, role); From f1085b324eb27f9a4d2c2d67243a3ba015e34b22 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Fri, 13 Oct 2023 16:21:45 +0900 Subject: [PATCH 0017/1546] ProjectExplorer: Avoid accidental changes on spinbox via mouse scroll - Introduced an Utils::attachWheelBlocker() to disable mouse wheel events on the "Parallel Jobs" field. - This prevents unintentional modifications when users inadvertently scroll over the input. Change-Id: Iccb93305fbcf399cae683412078782b5ea9f4ad6 Reviewed-by: Reviewed-by: Jarek Kobus --- src/libs/utils/CMakeLists.txt | 1 + src/libs/utils/aspects.cpp | 3 +++ src/libs/utils/guiutils.cpp | 34 ++++++++++++++++++++++++ src/libs/utils/guiutils.h | 14 ++++++++++ src/plugins/help/generalsettingspage.cpp | 2 ++ 5 files changed, 54 insertions(+) create mode 100644 src/libs/utils/guiutils.cpp create mode 100644 src/libs/utils/guiutils.h diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt index 6a890815d07..be022f6a838 100644 --- a/src/libs/utils/CMakeLists.txt +++ b/src/libs/utils/CMakeLists.txt @@ -69,6 +69,7 @@ add_qtc_library(Utils genericconstants.h globalfilechangeblocker.cpp globalfilechangeblocker.h guard.cpp guard.h + guiutils.cpp guiutils.h headerviewstretcher.cpp headerviewstretcher.h highlightingitemdelegate.cpp highlightingitemdelegate.h historycompleter.cpp historycompleter.h diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp index b14a429ed92..f8923ce3ed1 100644 --- a/src/libs/utils/aspects.cpp +++ b/src/libs/utils/aspects.cpp @@ -7,6 +7,7 @@ #include "checkablemessagebox.h" #include "environment.h" #include "fancylineedit.h" +#include "guiutils.h" #include "iconbutton.h" #include "layoutbuilder.h" #include "passworddialog.h" @@ -2195,6 +2196,7 @@ void IntegerAspect::addToLayout(Layouting::LayoutItem &parent) d->m_spinBox->setRange(int(d->m_minimumValue.value() / d->m_displayScaleFactor), int(d->m_maximumValue.value() / d->m_displayScaleFactor)); d->m_spinBox->setValue(int(value() / d->m_displayScaleFactor)); // Must happen after setRange() + attachWheelBlocker(d->m_spinBox); addLabeledItem(parent, d->m_spinBox); connect(d->m_spinBox.data(), &QSpinBox::valueChanged, this, &IntegerAspect::handleGuiChanged); @@ -2294,6 +2296,7 @@ void DoubleAspect::addToLayout(LayoutItem &builder) d->m_spinBox->setSpecialValueText(d->m_specialValueText); if (d->m_maximumValue && d->m_maximumValue) d->m_spinBox->setRange(d->m_minimumValue.value(), d->m_maximumValue.value()); + attachWheelBlocker(d->m_spinBox); bufferToGui(); // Must happen after setRange()! addLabeledItem(builder, d->m_spinBox); connect(d->m_spinBox.data(), &QDoubleSpinBox::valueChanged, diff --git a/src/libs/utils/guiutils.cpp b/src/libs/utils/guiutils.cpp new file mode 100644 index 00000000000..bfafff677f7 --- /dev/null +++ b/src/libs/utils/guiutils.cpp @@ -0,0 +1,34 @@ +// Copyright (C) 2023 Tasuku Suzuki +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "guiutils.h" + +#include +#include + +namespace Utils { + +namespace Internal { + +class WheelEventFilter : public QObject +{ +public: + bool eventFilter(QObject *watched, QEvent *event) override { + auto widget = qobject_cast(watched); + return event->type() == QEvent::Wheel + && widget + && widget->focusPolicy() != Qt::WheelFocus + && !widget->hasFocus(); + } +}; + +} // namespace Internal + +void QTCREATOR_UTILS_EXPORT attachWheelBlocker(QWidget *widget) +{ + static Internal::WheelEventFilter instance; + widget->installEventFilter(&instance); + widget->setFocusPolicy(Qt::StrongFocus); +} + +} // namespace Utils diff --git a/src/libs/utils/guiutils.h b/src/libs/utils/guiutils.h new file mode 100644 index 00000000000..d478c7d90db --- /dev/null +++ b/src/libs/utils/guiutils.h @@ -0,0 +1,14 @@ +// Copyright (C) 2023 Tasuku Suzuki +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "utils_global.h" + +class QWidget; + +namespace Utils { + +void QTCREATOR_UTILS_EXPORT attachWheelBlocker(QWidget *widget); + +} // namespace Utils diff --git a/src/plugins/help/generalsettingspage.cpp b/src/plugins/help/generalsettingspage.cpp index ff1e7e82182..5f1731bb0c5 100644 --- a/src/plugins/help/generalsettingspage.cpp +++ b/src/plugins/help/generalsettingspage.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -105,6 +106,7 @@ GeneralSettingsPageWidget::GeneralSettingsPageWidget() zoomSpinBox->setSingleStep(10); zoomSpinBox->setValue(100); zoomSpinBox->setSuffix(Tr::tr("%")); + attachWheelBlocker(zoomSpinBox); antialiasCheckBox = new QCheckBox(Tr::tr("Antialias")); auto fontGroupBox = new QGroupBox(Tr::tr("Font")); From df7619de8dda2cf827f1ebe584572723b4417692 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 17 Oct 2023 08:37:14 +0200 Subject: [PATCH 0018/1546] Utils: Fix qbs build Amends f1085b324eb27f9a4d2c2d67243a3ba015e34b22. Change-Id: Iac52d63e1662d7e4fbd8093ea4ee713eb16d6497 Reviewed-by: Jarek Kobus --- src/libs/utils/utils.qbs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs index 51d6857d122..f67c80e1dd5 100644 --- a/src/libs/utils/utils.qbs +++ b/src/libs/utils/utils.qbs @@ -145,6 +145,8 @@ QtcLibrary { "globalfilechangeblocker.h", "guard.cpp", "guard.h", + "guiutils.cpp", + "guiutils.h", "highlightingitemdelegate.cpp", "highlightingitemdelegate.h", "historycompleter.cpp", From 5977c26f2e464e073f5f182785aec4176c03eaa9 Mon Sep 17 00:00:00 2001 From: Aaron McCarthy Date: Fri, 21 Jul 2023 22:45:06 +1000 Subject: [PATCH 0019/1546] QbsProjectManager: Provide classpath data to Java language server Change-Id: Idf09ae566139a752184defe26fee082af8be31aa Reviewed-by: Christian Kandeler --- src/plugins/android/androidconstants.h | 1 + src/plugins/android/javalanguageserver.cpp | 19 ++++++++++++++++--- src/plugins/qbsprojectmanager/qbsnodes.cpp | 16 ++++++++++++++++ .../qbsprojectmanagerconstants.h | 1 + src/plugins/qbsprojectmanager/qbssession.cpp | 1 + 5 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/plugins/android/androidconstants.h b/src/plugins/android/androidconstants.h index 1bc1712e24f..dd3a06fa607 100644 --- a/src/plugins/android/androidconstants.h +++ b/src/plugins/android/androidconstants.h @@ -56,6 +56,7 @@ const char AndroidMkSpecAbis[] = "AndroidMkSpecAbis"; // QStringList const char AndroidSoLibPath[] = "AndroidSoLibPath"; // QStringList const char AndroidTargets[] = "AndroidTargets"; // QStringList const char AndroidApplicationArgs[] = "AndroidApplicationArgs"; // QString +const char AndroidClassPaths[] = "AndroidClassPath"; // QStringList // For qbs support const char AndroidApk[] = "Android.APK"; // QStringList diff --git a/src/plugins/android/javalanguageserver.cpp b/src/plugins/android/javalanguageserver.cpp index d6ea811f00b..db8d0745f62 100644 --- a/src/plugins/android/javalanguageserver.cpp +++ b/src/plugins/android/javalanguageserver.cpp @@ -291,16 +291,29 @@ void JLSClient::updateProjectFiles() return; const FilePath packageSourceDir = FilePath::fromVariant( node->data(Constants::AndroidPackageSourceDir)); - FilePath sourceDir = packageSourceDir.pathAppended("src"); - if (!sourceDir.exists()) - return; + + FilePath sourceDir = packageSourceDir.pathAppended("src/main/java"); + if (!sourceDir.exists()) { + sourceDir = packageSourceDir.pathAppended("src"); + if (!sourceDir.exists()) { + return; + } + } + sourceDir = sourceDir.relativeChildPath(projectDir); + + const QStringList classPaths = node->data(Constants::AndroidClassPaths).toStringList(); + const FilePath &sdkLocation = AndroidConfigurations::currentConfig().sdkLocation(); const QString &targetSDK = AndroidManager::buildTargetSDK(m_currentTarget); const FilePath androidJar = sdkLocation / QString("platforms/%2/android.jar") .arg(targetSDK); FilePaths libs = {androidJar}; libs << packageSourceDir.pathAppended("libs").dirEntries({{"*.jar"}, QDir::Files}); + + for (const QString &path : classPaths) + libs << FilePath::fromString(path); + generateProjectFile(projectDir, qtSrc, project()->displayName()); generateClassPathFile(projectDir, sourceDir, libs); } diff --git a/src/plugins/qbsprojectmanager/qbsnodes.cpp b/src/plugins/qbsprojectmanager/qbsnodes.cpp index 460be9f7d8e..2d034108811 100644 --- a/src/plugins/qbsprojectmanager/qbsnodes.cpp +++ b/src/plugins/qbsprojectmanager/qbsnodes.cpp @@ -219,6 +219,22 @@ QVariant QbsProductNode::data(Id role) const qbsAbis << archToAbi[architecture]; return qbsAbis; } + + if (role == Android::Constants::AndroidPackageSourceDir) { + return m_productData.value("properties").toObject() + .value("sourceDirectory").toString(); + } + + if (role == Android::Constants::AndroidClassPaths) { + QStringList paths; + for (const auto &p : m_productData.value("module-properties").toObject() + .value(Constants::JAVA_ADDITIONAL_CLASSPATHS).toArray()) { + if (p.isString()) + paths << p.toString(); + } + return paths; + } + return {}; } diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h b/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h index 8b35e0f0880..7334cea7381 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h +++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h @@ -68,6 +68,7 @@ const char CPP_PLATFORMLINKERFLAGS[] = "cpp.platformLinkerFlags"; const char CPP_VCVARSALLPATH[] = "cpp.vcvarsallPath"; const char XCODE_DEVELOPERPATH[] = "xcode.developerPath"; const char XCODE_SDK[] = "xcode.sdk"; +const char JAVA_ADDITIONAL_CLASSPATHS[] = "java.additionalClassPaths"; // Settings page const char QBS_SETTINGS_CATEGORY[] = "K.Qbs"; diff --git a/src/plugins/qbsprojectmanager/qbssession.cpp b/src/plugins/qbsprojectmanager/qbssession.cpp index 49d8b31b56f..999e83d2d79 100644 --- a/src/plugins/qbsprojectmanager/qbssession.cpp +++ b/src/plugins/qbsprojectmanager/qbssession.cpp @@ -372,6 +372,7 @@ void QbsSession::insertRequestedModuleProperties(QJsonObject &request) "cpp.useObjcPrecompiledHeader", "cpp.useObjcxxPrecompiledHeader", "cpp.warningLevel", + "java.additionalClassPaths", "qbs.architecture", "qbs.architectures", "qbs.sysroot", From d16d1718f30e3481100f9629ae7acd7ac03a0c02 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 17 Oct 2023 10:34:57 +0200 Subject: [PATCH 0020/1546] ClangCodeModel: Forward to the built-in code model ... if the user tries to complete inside a comment or string. Fixes: QTCREATORBUG-20828 Change-Id: I245e1bd16acaf696601cabe33f27210da21cc12a Reviewed-by: David Schulz Reviewed-by: --- .../clangcodemodel/clangdcompletion.cpp | 26 +++++-------------- .../clangcodemodel/test/clangdtests.cpp | 14 +--------- src/plugins/clangcodemodel/test/clangdtests.h | 1 - .../test/data/clangtestdata.qrc | 1 - .../completion/doxygenKeywordsCompletion.cpp | 1 - src/plugins/cppeditor/cppeditorwidget.cpp | 3 ++- src/plugins/cppeditor/cpptoolsreuse.cpp | 20 ++++++++------ src/plugins/cppeditor/cpptoolsreuse.h | 2 ++ 8 files changed, 24 insertions(+), 44 deletions(-) delete mode 100644 src/plugins/clangcodemodel/test/data/completion/doxygenKeywordsCompletion.cpp diff --git a/src/plugins/clangcodemodel/clangdcompletion.cpp b/src/plugins/clangcodemodel/clangdcompletion.cpp index 9141d39228d..ee8b6579838 100644 --- a/src/plugins/clangcodemodel/clangdcompletion.cpp +++ b/src/plugins/clangcodemodel/clangdcompletion.cpp @@ -12,7 +12,6 @@ #include #include -#include #include #include #include @@ -44,7 +43,7 @@ namespace ClangCodeModel::Internal { static Q_LOGGING_CATEGORY(clangdLogCompletion, "qtc.clangcodemodel.clangd.completion", QtWarningMsg); -enum class CustomAssistMode { Doxygen, Preprocessor, IncludePath }; +enum class CustomAssistMode { Preprocessor, IncludePath }; class CustomAssistProcessor : public IAssistProcessor { @@ -126,6 +125,12 @@ IAssistProcessor *ClangdCompletionAssistProvider::createProcessor( << interface->textAt(interface->position(), -10); qCDebug(clangdLogCompletion) << "text after cursor is" << interface->textAt(interface->position(), 10); + + if (!interface->isBaseObject()) { + qCDebug(clangdLogCompletion) << "encountered assist interface for built-in code model"; + return CppEditor::getCppCompletionAssistProcessor(); + } + ClangCompletionContextAnalyzer contextAnalyzer(interface->textDocument(), interface->position(), false, {}); contextAnalyzer.analyze(); @@ -133,13 +138,6 @@ IAssistProcessor *ClangdCompletionAssistProvider::createProcessor( case ClangCompletionContextAnalyzer::PassThroughToLibClangAfterLeftParen: qCDebug(clangdLogCompletion) << "creating function hint processor"; return new ClangdFunctionHintProcessor(m_client); - case ClangCompletionContextAnalyzer::CompleteDoxygenKeyword: - qCDebug(clangdLogCompletion) << "creating doxygen processor"; - return new CustomAssistProcessor(m_client, - contextAnalyzer.positionForProposal(), - contextAnalyzer.positionEndOfExpression(), - contextAnalyzer.completionOperator(), - CustomAssistMode::Doxygen); case ClangCompletionContextAnalyzer::CompletePreprocessorDirective: qCDebug(clangdLogCompletion) << "creating macro processor"; return new CustomAssistProcessor(m_client, @@ -147,10 +145,6 @@ IAssistProcessor *ClangdCompletionAssistProvider::createProcessor( contextAnalyzer.positionEndOfExpression(), contextAnalyzer.completionOperator(), CustomAssistMode::Preprocessor); - case ClangCompletionContextAnalyzer::CompleteSignal: - case ClangCompletionContextAnalyzer::CompleteSlot: - if (!interface->isBaseObject()) - return CppEditor::getCppCompletionAssistProcessor(); default: break; } @@ -415,12 +409,6 @@ IAssistProposal *CustomAssistProcessor::perform() { QList completions; switch (m_mode) { - case CustomAssistMode::Doxygen: - for (int i = 1; i < T_DOXY_LAST_TAG; ++i) { - completions << createItem(QLatin1String(doxygenTagSpell(i)), - CPlusPlus::Icons::keywordIcon()); - } - break; case CustomAssistMode::Preprocessor: { static QIcon macroIcon = Utils::CodeModelIcon::iconForType(CodeModelIcon::Macro); for (const QString &completion diff --git a/src/plugins/clangcodemodel/test/clangdtests.cpp b/src/plugins/clangcodemodel/test/clangdtests.cpp index bfc6d1d4f8d..a74eedbc3bb 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.cpp +++ b/src/plugins/clangcodemodel/test/clangdtests.cpp @@ -1500,7 +1500,7 @@ ClangdTestCompletion::ClangdTestCompletion() setProjectFileName("completion.pro"); setSourceFileNames({"completionWithProject.cpp", "constructorCompletion.cpp", "classAndConstructorCompletion.cpp", "dotToArrowCorrection.cpp", - "doxygenKeywordsCompletion.cpp", "functionAddress.cpp", + "functionAddress.cpp", "functionCompletion.cpp", "functionCompletionFiltered2.cpp", "functionCompletionFiltered.cpp", "globalCompletion.cpp", "includeDirectiveCompletion.cpp", "mainwindow.cpp", @@ -1518,18 +1518,6 @@ void ClangdTestCompletion::initTestCase() startCollectingHighlightingInfo(); } -void ClangdTestCompletion::testCompleteDoxygenKeywords() -{ - ProposalModelPtr proposal; - getProposal("doxygenKeywordsCompletion.cpp", proposal); - - QVERIFY(proposal); - QVERIFY(hasItem(proposal, "brief")); - QVERIFY(hasItem(proposal, "param")); - QVERIFY(hasItem(proposal, "return")); - QVERIFY(!hasSnippet(proposal, "class ")); -} - void ClangdTestCompletion::testCompletePreprocessorKeywords() { ProposalModelPtr proposal; diff --git a/src/plugins/clangcodemodel/test/clangdtests.h b/src/plugins/clangcodemodel/test/clangdtests.h index 9d6e42d3a9e..b823c050e89 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.h +++ b/src/plugins/clangcodemodel/test/clangdtests.h @@ -137,7 +137,6 @@ public: private slots: void initTestCase() override; - void testCompleteDoxygenKeywords(); void testCompletePreprocessorKeywords(); void testCompleteIncludeDirective(); diff --git a/src/plugins/clangcodemodel/test/data/clangtestdata.qrc b/src/plugins/clangcodemodel/test/data/clangtestdata.qrc index f61e3f0633b..480d85fedc4 100644 --- a/src/plugins/clangcodemodel/test/data/clangtestdata.qrc +++ b/src/plugins/clangcodemodel/test/data/clangtestdata.qrc @@ -29,7 +29,6 @@ completion/classAndConstructorCompletion.cpp completion/completionWithProject.cpp completion/constructorCompletion.cpp - completion/doxygenKeywordsCompletion.cpp completion/functionCompletion.cpp completion/functionCompletionFiltered.cpp completion/functionCompletionFiltered2.cpp diff --git a/src/plugins/clangcodemodel/test/data/completion/doxygenKeywordsCompletion.cpp b/src/plugins/clangcodemodel/test/data/completion/doxygenKeywordsCompletion.cpp deleted file mode 100644 index 3c4f6c9a2da..00000000000 --- a/src/plugins/clangcodemodel/test/data/completion/doxygenKeywordsCompletion.cpp +++ /dev/null @@ -1 +0,0 @@ -//! \ /* COMPLETE HERE */ diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp index 0419ef6b035..9666dc48a7d 100644 --- a/src/plugins/cppeditor/cppeditorwidget.cpp +++ b/src/plugins/cppeditor/cppeditorwidget.cpp @@ -1268,7 +1268,8 @@ std::unique_ptr CppEditorWidget::createAssistInterface(AssistKi if (cap) return cap->createAssistInterface(textDocument()->filePath(), this, getFeatures(), reason); - if (isOldStyleSignalOrSlot()) { + if (isOldStyleSignalOrSlot() + || isInCommentOrString(textCursor(), LanguageFeatures::defaultFeatures())) { return CppModelManager::completionAssistProvider() ->createAssistInterface(textDocument()->filePath(), this, getFeatures(), reason); } diff --git a/src/plugins/cppeditor/cpptoolsreuse.cpp b/src/plugins/cppeditor/cpptoolsreuse.cpp index 543f046237d..9951eea9ff5 100644 --- a/src/plugins/cppeditor/cpptoolsreuse.cpp +++ b/src/plugins/cppeditor/cpptoolsreuse.cpp @@ -293,29 +293,33 @@ bool isInCommentOrString(const TextEditor::AssistInterface *interface, { QTextCursor tc(interface->textDocument()); tc.setPosition(interface->position()); + return isInCommentOrString(tc, features); +} +bool isInCommentOrString(const QTextCursor &cursor, CPlusPlus::LanguageFeatures features) +{ SimpleLexer tokenize; features.qtMocRunEnabled = true; tokenize.setLanguageFeatures(features); tokenize.setSkipComments(false); - const Tokens &tokens = tokenize(tc.block().text(), - BackwardsScanner::previousBlockState(tc.block())); - const int tokenIdx = SimpleLexer::tokenBefore(tokens, qMax(0, tc.positionInBlock() - 1)); + const Tokens &tokens = tokenize(cursor.block().text(), + BackwardsScanner::previousBlockState(cursor.block())); + const int tokenIdx = SimpleLexer::tokenBefore(tokens, qMax(0, cursor.positionInBlock() - 1)); const Token tk = (tokenIdx == -1) ? Token() : tokens.at(tokenIdx); if (tk.isComment()) return true; - if (!tk.isLiteral()) + if (!tk.isStringLiteral()) return false; if (tokens.size() == 3 && tokens.at(0).kind() == T_POUND - && tokens.at(1).kind() == T_IDENTIFIER) { - const QString &line = tc.block().text(); + && tokens.at(1).kind() == T_IDENTIFIER) { + const QString &line = cursor.block().text(); const Token &idToken = tokens.at(1); QStringView identifier = QStringView(line).mid(idToken.utf16charsBegin(), idToken.utf16chars()); if (identifier == QLatin1String("include") - || identifier == QLatin1String("include_next") - || (features.objCEnabled && identifier == QLatin1String("import"))) { + || identifier == QLatin1String("include_next") + || (features.objCEnabled && identifier == QLatin1String("import"))) { return false; } } diff --git a/src/plugins/cppeditor/cpptoolsreuse.h b/src/plugins/cppeditor/cpptoolsreuse.h index fc90b900a24..d40e00d994c 100644 --- a/src/plugins/cppeditor/cpptoolsreuse.h +++ b/src/plugins/cppeditor/cpptoolsreuse.h @@ -54,6 +54,8 @@ const CPlusPlus::Macro CPPEDITOR_EXPORT *findCanonicalMacro(const QTextCursor &c bool CPPEDITOR_EXPORT isInCommentOrString(const TextEditor::AssistInterface *interface, CPlusPlus::LanguageFeatures features); +bool CPPEDITOR_EXPORT isInCommentOrString(const QTextCursor &cursor, + CPlusPlus::LanguageFeatures features); TextEditor::QuickFixOperations CPPEDITOR_EXPORT quickFixOperations(const TextEditor::AssistInterface *interface); From a60b43f028360bd262d0465177f813b1670dbcd8 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 17 Oct 2023 13:22:14 +0200 Subject: [PATCH 0021/1546] Designer: Use proper formatting and indentation ... when inserting member functions via "go to slot". Fixes: QTCREATORBUG-11730 Change-Id: I5de6947069e2c376758d0a79f6d1d710882aee66 Reviewed-by: David Schulz --- src/plugins/coreplugin/core_global.h | 12 ++++++++++ src/plugins/coreplugin/systemsettings.h | 6 +++-- src/plugins/designer/gotoslot_test.cpp | 16 +++++++++++++ src/plugins/designer/qtcreatorintegration.cpp | 23 +++++++++++++------ 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/src/plugins/coreplugin/core_global.h b/src/plugins/coreplugin/core_global.h index a66c7f433e1..0e4d60a5d14 100644 --- a/src/plugins/coreplugin/core_global.h +++ b/src/plugins/coreplugin/core_global.h @@ -12,3 +12,15 @@ #else # define CORE_EXPORT Q_DECL_IMPORT #endif + +#if defined(WITH_TESTS) +# if defined(CORE_LIBRARY) +# define CORE_TEST_EXPORT Q_DECL_EXPORT +# elif defined(CORE_STATIC_LIBRARY) +# define CORE_TEST_EXPORT +# else +# define CORE_TEST_EXPORT Q_DECL_IMPORT +# endif +#else +# define CORE_TEST_EXPORT +#endif diff --git a/src/plugins/coreplugin/systemsettings.h b/src/plugins/coreplugin/systemsettings.h index 1b0415faf91..1c4bdfc9e37 100644 --- a/src/plugins/coreplugin/systemsettings.h +++ b/src/plugins/coreplugin/systemsettings.h @@ -3,11 +3,13 @@ #pragma once +#include "core_global.h" + #include namespace Core::Internal { -class SystemSettings final : public Utils::AspectContainer +class CORE_TEST_EXPORT SystemSettings final : public Utils::AspectContainer { public: SystemSettings(); @@ -37,6 +39,6 @@ public: Utils::BoolAspect askBeforeExit{this}; }; -SystemSettings &systemSettings(); +CORE_TEST_EXPORT SystemSettings &systemSettings(); } // Core::Internal diff --git a/src/plugins/designer/gotoslot_test.cpp b/src/plugins/designer/gotoslot_test.cpp index f804c2259e3..49fccf58716 100644 --- a/src/plugins/designer/gotoslot_test.cpp +++ b/src/plugins/designer/gotoslot_test.cpp @@ -6,6 +6,7 @@ #include "formeditor.h" #include +#include #include #include #include @@ -215,6 +216,21 @@ namespace Internal { /// header and source files are correctly updated. void FormEditorPlugin::test_gotoslot() { + class SystemSettingsMgr { + public: + SystemSettingsMgr() + : m_saveAfterRefactor(Core::Internal::systemSettings().autoSaveAfterRefactoring.value()) + { + Core::Internal::systemSettings().autoSaveAfterRefactoring.setValue(false); + } + ~SystemSettingsMgr() + { + Core::Internal::systemSettings().autoSaveAfterRefactoring.setValue(m_saveAfterRefactor); + } + private: + const bool m_saveAfterRefactor; + } systemSettingsMgr; + QFETCH(QStringList, files); (GoToSlotTestCase(Utils::transform(files, FilePath::fromString))); } diff --git a/src/plugins/designer/qtcreatorintegration.cpp b/src/plugins/designer/qtcreatorintegration.cpp index fb4c1afd5d6..01459ee0b06 100644 --- a/src/plugins/designer/qtcreatorintegration.cpp +++ b/src/plugins/designer/qtcreatorintegration.cpp @@ -56,8 +56,6 @@ #include -enum { indentation = 4 }; - Q_LOGGING_CATEGORY(log, "qtc.designer", QtWarningMsg); using namespace Designer::Internal; @@ -624,12 +622,23 @@ bool QtCreatorIntegration::navigateToSlot(const QString &objectName, Overview o; const QString className = o.prettyName(cl->name()); const QString definition = location.prefix() + "void " + className + "::" - + functionNameWithParameterNames + "\n{\n" + QString(indentation, ' ') + "\n}\n" + + functionNameWithParameterNames + "\n{\n\n}\n" + location.suffix(); - editor->insert(definition); - Core::EditorManager::openEditorAt({location.filePath(), - int(location.line() + location.prefix().count('\n') + 2), - indentation}); + const RefactoringFilePtr file = refactoring.file(location.filePath()); + const int insertionPos = Utils::Text::positionInText(file->document(), + location.line(), location.column()); + ChangeSet changeSet; + changeSet.insert(insertionPos, definition); + file->setChangeSet(changeSet); + file->apply(); + const int indentationPos = file->document()->toPlainText().indexOf('}', insertionPos) - 1; + QTextCursor cursor(editor->textDocument()->document()); + cursor.setPosition(indentationPos); + editor->textDocument()->autoIndent(cursor); + const int openPos = file->document()->toPlainText().indexOf('}', indentationPos) - 1; + int line, column; + Utils::Text::convertPosition(file->document(), openPos, &line, &column); + Core::EditorManager::openEditorAt({location.filePath(), line, column}); return true; } From 1f96b1b7ed327be9de1609fd5d13bc59fbbc8ac0 Mon Sep 17 00:00:00 2001 From: Andreas Loth Date: Tue, 19 Sep 2023 12:17:18 +0200 Subject: [PATCH 0022/1546] Axivion: Analyze Dashboard server response for errors Change-Id: Id66c3ad5d8a6c7d73e7ad781893c936b0829cfbf Reviewed-by: Reviewed-by: hjk --- src/plugins/axivion/CMakeLists.txt | 1 + src/plugins/axivion/axivion.qbs | 8 +- src/plugins/axivion/axivionplugin.cpp | 3 +- .../axivion/dashboard/dashboardclient.cpp | 55 +++++++-- .../axivion/dashboard/dashboardclient.h | 3 +- src/plugins/axivion/dashboard/error.cpp | 107 ++++++++++++++++++ src/plugins/axivion/dashboard/error.h | 86 ++++++++++++++ 7 files changed, 247 insertions(+), 16 deletions(-) create mode 100644 src/plugins/axivion/dashboard/error.cpp create mode 100644 src/plugins/axivion/dashboard/error.h diff --git a/src/plugins/axivion/CMakeLists.txt b/src/plugins/axivion/CMakeLists.txt index c71df674750..ff089f1a98e 100644 --- a/src/plugins/axivion/CMakeLists.txt +++ b/src/plugins/axivion/CMakeLists.txt @@ -14,4 +14,5 @@ add_qtc_plugin(Axivion dashboard/dto.cpp dashboard/dto.h dashboard/concat.cpp dashboard/concat.h dashboard/dashboardclient.cpp dashboard/dashboardclient.h + dashboard/error.h dashboard/error.cpp ) diff --git a/src/plugins/axivion/axivion.qbs b/src/plugins/axivion/axivion.qbs index bdd20a89349..1fb4dd7bfa8 100644 --- a/src/plugins/axivion/axivion.qbs +++ b/src/plugins/axivion/axivion.qbs @@ -26,14 +26,12 @@ QtcPlugin { "axivionsettings.cpp", "axivionsettings.h", "axiviontr.h", - "dashboard/dashboardclient.cpp", - "dashboard/dashboardclient.h", ] cpp.includePaths: base.concat(["."]) // needed for the generated stuff below Group { - name: "Generated DTOs" + name: "Dashboard Communication" prefix: "dashboard/" files: [ @@ -41,6 +39,10 @@ QtcPlugin { "concat.h", "dto.cpp", "dto.h", + "dashboardclient.cpp", + "dashboardclient.h", + "error.cpp", + "error.h", ] } } diff --git a/src/plugins/axivion/axivionplugin.cpp b/src/plugins/axivion/axivionplugin.cpp index 0c09ecb475d..2a6af5a5cad 100644 --- a/src/plugins/axivion/axivionplugin.cpp +++ b/src/plugins/axivion/axivionplugin.cpp @@ -259,7 +259,8 @@ void AxivionPluginPrivate::handleProjectInfo(DashboardClient::RawProjectInfo raw { m_runningQuery = false; if (!rawInfo) { - Core::MessageManager::writeFlashing(QStringLiteral(u"Axivion: ") + rawInfo.error()); + Core::MessageManager::writeFlashing( + QStringLiteral(u"Axivion: %1").arg(rawInfo.error().message())); return; } m_currentProjectInfo = std::make_shared(std::move(rawInfo.value())); diff --git a/src/plugins/axivion/dashboard/dashboardclient.cpp b/src/plugins/axivion/dashboard/dashboardclient.cpp index 7e1a2761ec3..e0c5bf7a124 100644 --- a/src/plugins/axivion/dashboard/dashboardclient.cpp +++ b/src/plugins/axivion/dashboard/dashboardclient.cpp @@ -30,13 +30,17 @@ static void deleteLater(QObject *obj) obj->deleteLater(); } -using RawBody = Utils::expected_str>; +using RawBody = Utils::expected, Error>; + +static constexpr int httpStatusCodeOk = 200; +static constexpr QLatin1String jsonContentType{ "application/json" }; class RawBodyReader final { public: - RawBodyReader(std::shared_ptr reply) - : m_reply(std::move(reply)) + RawBodyReader(std::shared_ptr reply, QAnyStringView expectedContentType) + : m_reply(std::move(reply)), + m_expectedContentType(expectedContentType) { } ~RawBodyReader() { } @@ -44,19 +48,47 @@ public: RawBody operator()() { QNetworkReply::NetworkError error = m_reply->error(); - if (error != QNetworkReply::NetworkError::NoError) - return tl::make_unexpected(QString::number(error) - + QLatin1String(": ") - + m_reply->errorString()); - return DataWithOrigin(m_reply->url(), m_reply->readAll()); + int statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + QString contentType = m_reply->header(QNetworkRequest::ContentTypeHeader) + .toString() + .split(';') + .constFirst() + .trimmed() + .toLower(); + if (error == QNetworkReply::NetworkError::NoError + && statusCode == httpStatusCodeOk + && contentType == m_expectedContentType) { + return DataWithOrigin(m_reply->url(), m_reply->readAll()); + } + if (contentType == jsonContentType) { + try { + return tl::make_unexpected(DashboardError( + m_reply->url(), + statusCode, + m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(), + Dto::ErrorDto::deserialize(m_reply->readAll()))); + } catch (const Dto::invalid_dto_exception &) { + // ignore + } + } + if (statusCode != 0) { + return tl::make_unexpected(HttpError( + m_reply->url(), + statusCode, + m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(), + QString::fromUtf8(m_reply->readAll()))); // encoding? + } + return tl::make_unexpected( + NetworkError(m_reply->url(), error, m_reply->errorString())); } private: std::shared_ptr m_reply; + QAnyStringView m_expectedContentType; }; template -static Utils::expected_str> RawBodyParser(RawBody rawBody) +static Utils::expected, Error> RawBodyParser(RawBody rawBody) { if (!rawBody) return tl::make_unexpected(std::move(rawBody.error())); @@ -65,7 +97,8 @@ static Utils::expected_str> RawBodyParser(RawBody rawBody) return DataWithOrigin(std::move(rawBody.value().origin), std::move(data)); } catch (const Dto::invalid_dto_exception &e) { - return tl::make_unexpected(QString::fromUtf8(e.what())); + return tl::make_unexpected(GeneralError(std::move(rawBody.value().origin), + QString::fromUtf8(e.what()))); } } @@ -91,7 +124,7 @@ QFuture DashboardClient::fetchProjectInfo(const std::shared_ptr reply{ this->m_networkAccessManager.get(request), deleteLater }; return QtFuture::connect(reply.get(), &QNetworkReply::finished) .onCanceled(reply.get(), [reply] { reply->abort(); }) - .then(RawBodyReader(reply)) + .then(RawBodyReader(reply, jsonContentType)) .then(QtFuture::Launch::Async, &RawBodyParser); } diff --git a/src/plugins/axivion/dashboard/dashboardclient.h b/src/plugins/axivion/dashboard/dashboardclient.h index eda623b878b..eb9d58c799f 100644 --- a/src/plugins/axivion/dashboard/dashboardclient.h +++ b/src/plugins/axivion/dashboard/dashboardclient.h @@ -8,6 +8,7 @@ */ #include "dashboard/dto.h" +#include "dashboard/error.h" #include #include @@ -32,7 +33,7 @@ class DashboardClient { public: using ProjectInfo = DataWithOrigin; - using RawProjectInfo = Utils::expected_str; + using RawProjectInfo = Utils::expected; DashboardClient(Utils::NetworkAccessManager &networkAccessManager); diff --git a/src/plugins/axivion/dashboard/error.cpp b/src/plugins/axivion/dashboard/error.cpp new file mode 100644 index 00000000000..f583a6f7815 --- /dev/null +++ b/src/plugins/axivion/dashboard/error.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2022-current by Axivion GmbH + * https://www.axivion.com/ + * + * SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + */ + +#include "dashboard/error.h" + +#include +#include + +namespace Axivion::Internal +{ + +CommunicationError::CommunicationError(QUrl replyUrl) + : replyUrl(std::move(replyUrl)) +{ +} + +GeneralError::GeneralError(QUrl replyUrl, QString message) + : CommunicationError(replyUrl), + message(std::move(message)) +{ +} + +NetworkError::NetworkError(QUrl replyUrl, + QNetworkReply::NetworkError networkError, + QString networkErrorString) + : CommunicationError(std::move(replyUrl)), + networkError(std::move(networkError)), + networkErrorString(std::move(networkErrorString)) +{ +} + +HttpError::HttpError(QUrl replyUrl, int httpStatusCode, QString httpReasonPhrase, QString body) + : CommunicationError(std::move(replyUrl)), + httpStatusCode(httpStatusCode), + httpReasonPhrase(std::move(httpReasonPhrase)), + body(std::move(body)) +{ +} + +DashboardError::DashboardError(QUrl replyUrl, int httpStatusCode, QString httpReasonPhrase, Dto::ErrorDto error) + : CommunicationError(std::move(replyUrl)), + httpStatusCode(httpStatusCode), + httpReasonPhrase(std::move(httpReasonPhrase)), + dashboardVersion(std::move(error.dashboardVersionNumber)), + type(std::move(error.type)), + message(std::move(error.message)) +{ +} + +Error::Error(GeneralError error) : m_error(std::move(error)) +{ +} + +Error::Error(NetworkError error) : m_error(std::move(error)) +{ +} + +Error::Error(HttpError error) : m_error(std::move(error)) +{ +} + +Error::Error(DashboardError error) : m_error(std::move(error)) +{ +} + +// https://www.cppstories.com/2018/09/visit-variants/ +template struct overloaded : Ts... { using Ts::operator()...; }; +template overloaded(Ts...) -> overloaded; // line not needed in C++20... + +QString Error::message() const +{ + return std::visit( + overloaded{ + [](const GeneralError &error) { + return QStringLiteral(u"GeneralError (%1) %2") + .arg(error.replyUrl.toString(), + error.message); + }, + [](const NetworkError &error) { + return QStringLiteral(u"NetworkError (%1) %2: %3") + .arg(error.replyUrl.toString(), + QString::number(error.networkError), + error.networkErrorString); + }, + [](const HttpError &error) { + return QStringLiteral(u"HttpError (%1) %2: %3\n%4") + .arg(error.replyUrl.toString(), + QString::number(error.httpStatusCode), + error.httpReasonPhrase, + error.body); + }, + [](const DashboardError &error) { + return QStringLiteral(u"DashboardError (%1) [%2 %3] %4: %5") + .arg(error.replyUrl.toString(), + QString::number(error.httpStatusCode), + error.httpReasonPhrase, + error.type, + error.message); + }, + }, this->m_error); +} + +} // namespace Axivion::Internal diff --git a/src/plugins/axivion/dashboard/error.h b/src/plugins/axivion/dashboard/error.h new file mode 100644 index 00000000000..4e2a434ab81 --- /dev/null +++ b/src/plugins/axivion/dashboard/error.h @@ -0,0 +1,86 @@ +#pragma once + +/* + * Copyright (C) 2022-current by Axivion GmbH + * https://www.axivion.com/ + * + * SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + */ + +#include "dashboard/dto.h" + +#include + +#include + +namespace Axivion::Internal +{ + +class CommunicationError +{ +public: + QUrl replyUrl; + + CommunicationError(QUrl replyUrl); +}; + +class GeneralError : public CommunicationError +{ +public: + QString message; + + GeneralError(QUrl replyUrl, QString message); +}; + +class NetworkError : public CommunicationError +{ +public: + QNetworkReply::NetworkError networkError; + QString networkErrorString; + + NetworkError(QUrl replyUrl, QNetworkReply::NetworkError networkError, QString networkErrorString); +}; + +class HttpError : public CommunicationError +{ +public: + int httpStatusCode; + QString httpReasonPhrase; + QString body; + + HttpError(QUrl replyUrl, int httpStatusCode, QString httpReasonPhrase, QString body); +}; + +class DashboardError : public CommunicationError +{ +public: + int httpStatusCode; + QString httpReasonPhrase; + std::optional dashboardVersion; + QString type; + QString message; + + DashboardError(QUrl replyUrl, int httpStatusCode, QString httpReasonPhrase, Dto::ErrorDto error); +}; + +class Error +{ +public: + Error(GeneralError error); + + Error(NetworkError error); + + Error(HttpError error); + + Error(DashboardError error); + + QString message() const; + +private: + std::variant m_error; +}; + +} // namespace Axivion::Internal From bdd3f8f8e269147c0c4c335d539f5c48fc32fd9a Mon Sep 17 00:00:00 2001 From: Andreas Loth Date: Mon, 25 Sep 2023 16:57:28 +0200 Subject: [PATCH 0023/1546] Axivion: Use better names Change-Id: I5b4d35ee7f842ad1389293fcc13507bc57c7067f Reviewed-by: hjk --- .../axivion/dashboard/dashboardclient.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/plugins/axivion/dashboard/dashboardclient.cpp b/src/plugins/axivion/dashboard/dashboardclient.cpp index e0c5bf7a124..db5d8799a98 100644 --- a/src/plugins/axivion/dashboard/dashboardclient.cpp +++ b/src/plugins/axivion/dashboard/dashboardclient.cpp @@ -30,22 +30,22 @@ static void deleteLater(QObject *obj) obj->deleteLater(); } -using RawBody = Utils::expected, Error>; +using ResponseData = Utils::expected, Error>; static constexpr int httpStatusCodeOk = 200; static constexpr QLatin1String jsonContentType{ "application/json" }; -class RawBodyReader final +class ResponseReader final { public: - RawBodyReader(std::shared_ptr reply, QAnyStringView expectedContentType) + ResponseReader(std::shared_ptr reply, QAnyStringView expectedContentType) : m_reply(std::move(reply)), m_expectedContentType(expectedContentType) { } - ~RawBodyReader() { } + ~ResponseReader() { } - RawBody operator()() + ResponseData operator()() { QNetworkReply::NetworkError error = m_reply->error(); int statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); @@ -88,7 +88,7 @@ private: }; template -static Utils::expected, Error> RawBodyParser(RawBody rawBody) +static Utils::expected, Error> parseResponse(ResponseData rawBody) { if (!rawBody) return tl::make_unexpected(std::move(rawBody.error())); @@ -124,8 +124,8 @@ QFuture DashboardClient::fetchProjectInfo(const std::shared_ptr reply{ this->m_networkAccessManager.get(request), deleteLater }; return QtFuture::connect(reply.get(), &QNetworkReply::finished) .onCanceled(reply.get(), [reply] { reply->abort(); }) - .then(RawBodyReader(reply, jsonContentType)) - .then(QtFuture::Launch::Async, &RawBodyParser); + .then(ResponseReader(reply, jsonContentType)) + .then(QtFuture::Launch::Async, &parseResponse); } } From ce5a7db2e15f0e70edecc8763841d2d663387707 Mon Sep 17 00:00:00 2001 From: Andreas Loth Date: Mon, 25 Sep 2023 17:10:22 +0200 Subject: [PATCH 0024/1546] Axivion: Extract fetch function Change-Id: Ifcb67827e628eba0ad7c9e2371e64cbdebab9032 Reviewed-by: hjk --- .../axivion/dashboard/dashboardclient.cpp | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/plugins/axivion/dashboard/dashboardclient.cpp b/src/plugins/axivion/dashboard/dashboardclient.cpp index db5d8799a98..169bf8984cd 100644 --- a/src/plugins/axivion/dashboard/dashboardclient.cpp +++ b/src/plugins/axivion/dashboard/dashboardclient.cpp @@ -102,15 +102,12 @@ static Utils::expected, Error> parseResponse(ResponseData rawB } } -QFuture DashboardClient::fetchProjectInfo(const QString &projectName) +QFuture fetch(Utils::NetworkAccessManager &networkAccessManager, + const std::optional &base, + const QUrl &target) { const AxivionServer &server = settings().server; - QString dashboard = server.dashboard; - if (!dashboard.endsWith(QLatin1Char('/'))) - dashboard += QLatin1Char('/'); - QUrl url = QUrl(dashboard) - .resolved(QUrl(QStringLiteral(u"api/projects/"))) - .resolved(QUrl(projectName)); + QUrl url = base ? base->resolved(target) : target; QNetworkRequest request{ url }; request.setRawHeader(QByteArrayLiteral(u8"Accept"), QByteArrayLiteral(u8"Application/Json")); @@ -121,10 +118,22 @@ QFuture DashboardClient::fetchProjectInfo(const + QByteArrayLiteral(u8"Plugin/") + QCoreApplication::applicationVersion().toUtf8(); request.setRawHeader(QByteArrayLiteral(u8"X-Axivion-User-Agent"), ua); - std::shared_ptr reply{ this->m_networkAccessManager.get(request), deleteLater }; + std::shared_ptr reply{ networkAccessManager.get(request), deleteLater }; return QtFuture::connect(reply.get(), &QNetworkReply::finished) .onCanceled(reply.get(), [reply] { reply->abort(); }) - .then(ResponseReader(reply, jsonContentType)) + .then(ResponseReader(reply, jsonContentType)); +} + +QFuture DashboardClient::fetchProjectInfo(const QString &projectName) +{ + const AxivionServer &server = settings().server; + QString dashboard = server.dashboard; + if (!dashboard.endsWith(QLatin1Char('/'))) + dashboard += QLatin1Char('/'); + QUrl url = QUrl(dashboard) + .resolved(QUrl(QStringLiteral(u"api/projects/"))) + .resolved(QUrl(projectName)); + return fetch(this->m_networkAccessManager, std::nullopt, url) .then(QtFuture::Launch::Async, &parseResponse); } From df7353eaa769260dc73694066431620a7f364fa0 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 18 Oct 2023 08:35:39 +0200 Subject: [PATCH 0025/1546] ProjectExplorer: remove unused function from KitAspectFactory Change-Id: I5278279dd654dfc81de894fa7df235048d340079 Reviewed-by: Christian Kandeler --- src/plugins/projectexplorer/filterkitaspectsdialog.cpp | 2 -- src/plugins/projectexplorer/kitmanager.h | 2 -- src/plugins/projectexplorer/kitmanagerconfigwidget.cpp | 3 +-- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/plugins/projectexplorer/filterkitaspectsdialog.cpp b/src/plugins/projectexplorer/filterkitaspectsdialog.cpp index ce9ab5e2849..9564d6cb41c 100644 --- a/src/plugins/projectexplorer/filterkitaspectsdialog.cpp +++ b/src/plugins/projectexplorer/filterkitaspectsdialog.cpp @@ -82,8 +82,6 @@ public: { setHeader({Tr::tr("Setting"), Tr::tr("Visible")}); for (const KitAspectFactory * const factory : KitManager::kitAspectFactories()) { - if (kit && !factory->isApplicableToKit(kit)) - continue; const QSet irrelevantAspects = kit ? kit->irrelevantAspects() : KitManager::irrelevantAspects(); auto * const item = new FilterTreeItem(factory, diff --git a/src/plugins/projectexplorer/kitmanager.h b/src/plugins/projectexplorer/kitmanager.h index 377f96498ce..4d62ea4960d 100644 --- a/src/plugins/projectexplorer/kitmanager.h +++ b/src/plugins/projectexplorer/kitmanager.h @@ -79,8 +79,6 @@ public: virtual void addToMacroExpander(ProjectExplorer::Kit *kit, Utils::MacroExpander *expander) const; - virtual bool isApplicableToKit(const Kit *) const { return true; } - virtual void onKitsLoaded() {} protected: diff --git a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp index b939921ebec..9954bfb156f 100644 --- a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp +++ b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp @@ -212,9 +212,8 @@ void KitManagerConfigWidget::updateVisibility() { for (KitAspect *aspect : std::as_const(m_kitAspects)) { const KitAspectFactory *factory = aspect->factory(); - const bool visibleInKit = factory->isApplicableToKit(m_modifiedKit.get()); const bool irrelevant = m_modifiedKit->irrelevantAspects().contains(factory->id()); - aspect->setVisible(visibleInKit && !irrelevant); + aspect->setVisible(!irrelevant); } } From d851db61c6a1aa1098f1ffa33433bfa4ee21295c Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 16 Oct 2023 16:27:37 +0200 Subject: [PATCH 0026/1546] CppEditor: Special handling for included header corresponding to source ... when inserting additional header files. Fixes: QTCREATORBUG-21826 Change-Id: I1b62f8a9ee3fbc222fc8ee23e840d3c55cbee390 Reviewed-by: Christian Stenger --- src/plugins/cppeditor/cppquickfix_test.cpp | 38 ++++++++++++++++++++++ src/plugins/cppeditor/cppquickfixes.cpp | 2 +- src/plugins/cppeditor/includeutils.cpp | 32 ++++++++++++++++-- src/plugins/cppeditor/includeutils.h | 5 ++- 4 files changed, 72 insertions(+), 5 deletions(-) diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index ee18f28603c..dc7346c6226 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -6286,6 +6286,44 @@ void QuickfixTest::testAddIncludeForUndefinedIdentifier_data() << TestIncludePaths::globalIncludePath() << testDocuments << firstRefactoringOperation << ""; testDocuments.clear(); + + original = "class A{};"; + testDocuments << CppTestDocument::create("a.h", original, original); + original = "class B{};"; + testDocuments << CppTestDocument::create("b.h", original, original); + original = + "#include \"b.h\"\n" + "@A a;\n" + "B b;"; + expected = + "#include \"b.h\"\n\n" + "#include \"a.h\"\n" + "A a;\n" + "B b;"; + testDocuments << CppTestDocument::create("b.cpp", original, expected); + QTest::newRow("preserve first header") + << TestIncludePaths::globalIncludePath() + << testDocuments << firstRefactoringOperation << ""; + testDocuments.clear(); + + original = "class C{};"; + testDocuments << CppTestDocument::create("c.h", original, original); + original = "class B{};"; + testDocuments << CppTestDocument::create("b.h", original, original); + original = + "#include \"c.h\"\n" + "C c;\n" + "@B b;"; + expected = + "#include \"b.h\"\n" + "#include \"c.h\"\n" + "C c;\n" + "B b;"; + testDocuments << CppTestDocument::create("x.cpp", original, expected); + QTest::newRow("do not preserve first header") + << TestIncludePaths::globalIncludePath() + << testDocuments << firstRefactoringOperation << ""; + testDocuments.clear(); } void QuickfixTest::testAddIncludeForUndefinedIdentifier() diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 77b5bd5e452..c4f32dc1e31 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -212,7 +212,7 @@ void insertNewIncludeDirective(const QString &include, CppRefactoringFilePtr fil { // Find optimal position using namespace IncludeUtils; - LineForNewIncludeDirective finder(file->document(), cppDocument, + LineForNewIncludeDirective finder(file->filePath(), file->document(), cppDocument, LineForNewIncludeDirective::IgnoreMocIncludes, LineForNewIncludeDirective::AutoDetect); unsigned newLinesToPrepend = 0; diff --git a/src/plugins/cppeditor/includeutils.cpp b/src/plugins/cppeditor/includeutils.cpp index c7daa4e9d8f..1774997b6d4 100644 --- a/src/plugins/cppeditor/includeutils.cpp +++ b/src/plugins/cppeditor/includeutils.cpp @@ -103,11 +103,13 @@ int lineAfterFirstComment(const QTextDocument *textDocument) } // anonymous namespace -LineForNewIncludeDirective::LineForNewIncludeDirective(const QTextDocument *textDocument, +LineForNewIncludeDirective::LineForNewIncludeDirective(const FilePath &filePath, + const QTextDocument *textDocument, const Document::Ptr cppDocument, MocIncludeMode mocIncludeMode, IncludeStyle includeStyle) - : m_textDocument(textDocument) + : m_filePath(filePath) + , m_textDocument(textDocument) , m_cppDocument(cppDocument) , m_includeStyle(includeStyle) { @@ -204,7 +206,31 @@ int LineForNewIncludeDirective::operator()(const QString &newIncludeFileName, using IncludeGroups = QList; - const IncludeGroups groupsNewline = IncludeGroup::detectIncludeGroupsByNewLines(m_includes); + IncludeGroups groupsNewline = IncludeGroup::detectIncludeGroupsByNewLines(m_includes); + + // If the first group consists only of the header(s) for the including source file, + // then it must stay as it is. + if (groupsNewline.first().size() <= 2) { + bool firstGroupIsSpecial = true; + const QString baseName = m_filePath.baseName(); + const QString privBaseName = baseName + "_p"; + for (const auto &include : groupsNewline.first().includes()) { + const QString inclBaseName = FilePath::fromString(include.unresolvedFileName()) + .baseName(); + if (inclBaseName != baseName && inclBaseName != privBaseName) { + firstGroupIsSpecial = false; + break; + } + } + if (firstGroupIsSpecial) { + if (groupsNewline.size() == 1) { + *newLinesToPrepend = 1; + return groupsNewline.first().last().line() + 1; + } + groupsNewline.removeFirst(); + } + } + const bool includeAtTop = (newIncludeType == Client::IncludeLocal && m_includeStyle == LocalBeforeGlobal) || (newIncludeType == Client::IncludeGlobal && m_includeStyle == GlobalBeforeLocal); diff --git a/src/plugins/cppeditor/includeutils.h b/src/plugins/cppeditor/includeutils.h index cd28ee1dab5..c05d0c36b43 100644 --- a/src/plugins/cppeditor/includeutils.h +++ b/src/plugins/cppeditor/includeutils.h @@ -6,6 +6,8 @@ #include #include +#include + #include #include #include @@ -59,7 +61,7 @@ public: enum MocIncludeMode { RespectMocIncludes, IgnoreMocIncludes }; enum IncludeStyle { LocalBeforeGlobal, GlobalBeforeLocal, AutoDetect }; - LineForNewIncludeDirective(const QTextDocument *textDocument, + LineForNewIncludeDirective(const Utils::FilePath &filePath, const QTextDocument *textDocument, const CPlusPlus::Document::Ptr cppDocument, MocIncludeMode mocIncludeMode = IgnoreMocIncludes, IncludeStyle includeStyle = AutoDetect); @@ -74,6 +76,7 @@ private: QList getGroupsByIncludeType(const QList &groups, IncludeType includeType); + const Utils::FilePath m_filePath; const QTextDocument *m_textDocument; const CPlusPlus::Document::Ptr m_cppDocument; From 5ac19328fd784b169a1856b667481ec1b4d4529c Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 19 Oct 2023 12:07:25 +0200 Subject: [PATCH 0027/1546] Ios: Remove unused methods Change-Id: I57ac8a80218811ebb1be6f217d37fe925de23395 Reviewed-by: Eike Ziller --- src/plugins/ios/createsimulatordialog.cpp | 4 ++-- src/plugins/ios/simulatorcontrol.cpp | 23 ++++------------------- src/plugins/ios/simulatorcontrol.h | 6 ++---- 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/src/plugins/ios/createsimulatordialog.cpp b/src/plugins/ios/createsimulatordialog.cpp index aff8a673dfc..32884c5e426 100644 --- a/src/plugins/ios/createsimulatordialog.cpp +++ b/src/plugins/ios/createsimulatordialog.cpp @@ -60,10 +60,10 @@ CreateSimulatorDialog::CreateSimulatorDialog(QWidget *parent) enableOk(); }); - m_futureSync.addFuture(Utils::onResultReady(SimulatorControl::updateDeviceTypes(this), this, + m_futureSync.addFuture(Utils::onResultReady(SimulatorControl::updateDeviceTypes(), this, &CreateSimulatorDialog::populateDeviceTypes)); - QFuture> runtimesfuture = SimulatorControl::updateRuntimes(this); + QFuture> runtimesfuture = SimulatorControl::updateRuntimes(); Utils::onResultReady(runtimesfuture, this, [this](const QList &runtimes) { m_runtimes = runtimes; }); diff --git a/src/plugins/ios/simulatorcontrol.cpp b/src/plugins/ios/simulatorcontrol.cpp index 0832a5faf37..f7f3804983a 100644 --- a/src/plugins/ios/simulatorcontrol.cpp +++ b/src/plugins/ios/simulatorcontrol.cpp @@ -190,8 +190,6 @@ static void takeSceenshot(QPromise &promise, const QString &filePath); static QList s_availableDevices; -static QList s_availableDeviceTypes; -static QList s_availableRuntimes; QList SimulatorControl::availableSimulators() { @@ -234,27 +232,14 @@ static QList getAvailableSimulators() return availableDevices; } -QFuture> SimulatorControl::updateDeviceTypes(QObject *context) +QFuture> SimulatorControl::updateDeviceTypes() { - QFuture> future = Utils::asyncRun(getAvailableDeviceTypes); - Utils::onResultReady(future, context, [](const QList &deviceTypes) { - s_availableDeviceTypes = deviceTypes; - }); - return future; + return Utils::asyncRun(getAvailableDeviceTypes); } -QList SimulatorControl::availableRuntimes() +QFuture> SimulatorControl::updateRuntimes() { - return s_availableRuntimes; -} - -QFuture> SimulatorControl::updateRuntimes(QObject *context) -{ - QFuture> future = Utils::asyncRun(getAvailableRuntimes); - Utils::onResultReady(future, context, [](const QList &runtimes) { - s_availableRuntimes = runtimes; - }); - return future; + return Utils::asyncRun(getAvailableRuntimes); } QFuture> SimulatorControl::updateAvailableSimulators(QObject *context) diff --git a/src/plugins/ios/simulatorcontrol.h b/src/plugins/ios/simulatorcontrol.h index 402100fbeac..1e5d9375ad8 100644 --- a/src/plugins/ios/simulatorcontrol.h +++ b/src/plugins/ios/simulatorcontrol.h @@ -64,10 +64,8 @@ public: }; public: - static QList availableDeviceTypes(); - static QFuture> updateDeviceTypes(QObject *context); - static QList availableRuntimes(); - static QFuture> updateRuntimes(QObject *context); + static QFuture> updateDeviceTypes(); + static QFuture> updateRuntimes(); static QList availableSimulators(); static QFuture> updateAvailableSimulators(QObject *context); static bool isSimulatorRunning(const QString &simUdid); From 6f4b9639cef17d70e6e9851821d4d8c68d486498 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 11 Oct 2023 12:39:47 +0200 Subject: [PATCH 0028/1546] TextEditor: highlight selected text Change-Id: Ib46908decef51d478f6954a116108c48e4a07ed3 Reviewed-by: Marcus Tillmanns --- share/qtcreator/themes/dark.creatortheme | 1 + share/qtcreator/themes/default.creatortheme | 1 + .../themes/design-light.creatortheme | 1 + share/qtcreator/themes/design.creatortheme | 1 + share/qtcreator/themes/flat-dark.creatortheme | 1 + .../qtcreator/themes/flat-light.creatortheme | 1 + share/qtcreator/themes/flat.creatortheme | 1 + src/libs/utils/textutils.cpp | 19 +++ src/libs/utils/textutils.h | 4 + src/libs/utils/theme/theme.h | 1 + .../find/highlightscrollbarcontroller.cpp | 6 + src/plugins/texteditor/displaysettings.cpp | 4 + src/plugins/texteditor/displaysettings.h | 1 + .../texteditor/displaysettingspage.cpp | 8 + src/plugins/texteditor/textdocument.cpp | 13 +- src/plugins/texteditor/texteditor.cpp | 146 ++++++++++++++++++ src/plugins/texteditor/texteditorconstants.h | 1 + src/plugins/texteditor/texteditoroverlay.cpp | 9 +- 18 files changed, 215 insertions(+), 4 deletions(-) diff --git a/share/qtcreator/themes/dark.creatortheme b/share/qtcreator/themes/dark.creatortheme index e5b312ed159..7cd5888e15e 100644 --- a/share/qtcreator/themes/dark.creatortheme +++ b/share/qtcreator/themes/dark.creatortheme @@ -432,6 +432,7 @@ VcsBase_FileUnmerged_TextColor=ffff4040 Bookmarks_TextMarkColor=ff8080ff TextEditor_SearchResult_ScrollBarColor=ff00c000 +TextEditor_Selection_ScrollBarColor=ff888888 TextEditor_CurrentLine_ScrollBarColor=ffffffff ProjectExplorer_TaskError_TextMarkColor=error diff --git a/share/qtcreator/themes/default.creatortheme b/share/qtcreator/themes/default.creatortheme index 241502d1e53..d47e0df1a68 100644 --- a/share/qtcreator/themes/default.creatortheme +++ b/share/qtcreator/themes/default.creatortheme @@ -424,6 +424,7 @@ VcsBase_FileUnmerged_TextColor=ffee0000 Bookmarks_TextMarkColor=ffa0a0ff TextEditor_SearchResult_ScrollBarColor=ff00c000 +TextEditor_Selection_ScrollBarColor=ffcccccc TextEditor_CurrentLine_ScrollBarColor=ff404040 ProjectExplorer_TaskError_TextMarkColor=error diff --git a/share/qtcreator/themes/design-light.creatortheme b/share/qtcreator/themes/design-light.creatortheme index 5c9a0c6277a..9e1e86d3188 100644 --- a/share/qtcreator/themes/design-light.creatortheme +++ b/share/qtcreator/themes/design-light.creatortheme @@ -437,6 +437,7 @@ VcsBase_FileUnmerged_TextColor=ffee0000 Bookmarks_TextMarkColor=ffa0a0ff TextEditor_SearchResult_ScrollBarColor=ff00c000 +TextEditor_Selection_ScrollBarColor=ffcccccc TextEditor_CurrentLine_ScrollBarColor=ff404040 ProjectExplorer_TaskError_TextMarkColor=error diff --git a/share/qtcreator/themes/design.creatortheme b/share/qtcreator/themes/design.creatortheme index 6abbcc5de49..cc2499c6e72 100644 --- a/share/qtcreator/themes/design.creatortheme +++ b/share/qtcreator/themes/design.creatortheme @@ -440,6 +440,7 @@ VcsBase_FileUnmerged_TextColor=ffff4040 Bookmarks_TextMarkColor=ff8080ff TextEditor_SearchResult_ScrollBarColor=ff00c000 +TextEditor_Selection_ScrollBarColor=ff888888 TextEditor_CurrentLine_ScrollBarColor=ffffffff ProjectExplorer_TaskError_TextMarkColor=error diff --git a/share/qtcreator/themes/flat-dark.creatortheme b/share/qtcreator/themes/flat-dark.creatortheme index d015c149f0b..b384c8f7baf 100644 --- a/share/qtcreator/themes/flat-dark.creatortheme +++ b/share/qtcreator/themes/flat-dark.creatortheme @@ -436,6 +436,7 @@ VcsBase_FileUnmerged_TextColor=ffff4040 Bookmarks_TextMarkColor=ff8080ff TextEditor_SearchResult_ScrollBarColor=ff00c000 +TextEditor_Selection_ScrollBarColor=ff888888 TextEditor_CurrentLine_ScrollBarColor=ffffffff ProjectExplorer_TaskError_TextMarkColor=error diff --git a/share/qtcreator/themes/flat-light.creatortheme b/share/qtcreator/themes/flat-light.creatortheme index 21ded057ece..1afd27f2888 100644 --- a/share/qtcreator/themes/flat-light.creatortheme +++ b/share/qtcreator/themes/flat-light.creatortheme @@ -433,6 +433,7 @@ VcsBase_FileUnmerged_TextColor=ffee0000 Bookmarks_TextMarkColor=ffa0a0ff TextEditor_SearchResult_ScrollBarColor=ff00c000 +TextEditor_Selection_ScrollBarColor=ffcccccc TextEditor_CurrentLine_ScrollBarColor=ff404040 ProjectExplorer_TaskError_TextMarkColor=error diff --git a/share/qtcreator/themes/flat.creatortheme b/share/qtcreator/themes/flat.creatortheme index 6dc677d9ff3..e1bda7b18a3 100644 --- a/share/qtcreator/themes/flat.creatortheme +++ b/share/qtcreator/themes/flat.creatortheme @@ -431,6 +431,7 @@ VcsBase_FileUnmerged_TextColor=ffee0000 Bookmarks_TextMarkColor=ffa0a0ff TextEditor_SearchResult_ScrollBarColor=ff00c000 +TextEditor_Selection_ScrollBarColor=ffcccccc TextEditor_CurrentLine_ScrollBarColor=ff404040 ProjectExplorer_TaskError_TextMarkColor=error diff --git a/src/libs/utils/textutils.cpp b/src/libs/utils/textutils.cpp index f8ada6cca68..31fd1b84640 100644 --- a/src/libs/utils/textutils.cpp +++ b/src/libs/utils/textutils.cpp @@ -15,6 +15,17 @@ bool Position::operator==(const Position &other) const return line == other.line && column == other.column; } +int Position::positionInDocument(QTextDocument *doc) const +{ + if (!isValid()) + return -1; + QTC_ASSERT(doc, return -1); + QTextBlock block = doc->findBlockByNumber(line - 1); + if (!block.isValid()) + return -1; + return block.position() + column; +} + /*! Returns the text position of a \a fileName and sets the \a postfixPos if it can find a positional postfix. @@ -107,6 +118,14 @@ bool Range::operator==(const Range &other) const return begin == other.begin && end == other.end; } +QTextCursor Range::toTextCursor(QTextDocument *doc) const +{ + QTextCursor cursor(doc); + cursor.setPosition(begin.positionInDocument(doc)); + cursor.setPosition(end.positionInDocument(doc), QTextCursor::KeepAnchor); + return cursor; +} + bool convertPosition(const QTextDocument *document, int pos, int *line, int *column) { QTextBlock block = document->findBlock(pos); diff --git a/src/libs/utils/textutils.h b/src/libs/utils/textutils.h index d21ca20d4d9..b96a84eec32 100644 --- a/src/libs/utils/textutils.h +++ b/src/libs/utils/textutils.h @@ -30,6 +30,8 @@ public: bool isValid() const { return line > 0 && column >= 0; } + int positionInDocument(QTextDocument *doc) const; + static Position fromFileName(QStringView fileName, int &postfixPos); static Position fromPositionInDocument(const QTextDocument *document, int pos); static Position fromCursor(const QTextCursor &cursor); @@ -49,6 +51,8 @@ public: bool operator==(const Range &other) const; bool operator!=(const Range &other) const { return !(operator==(other)); } + + QTextCursor toTextCursor(QTextDocument *doc) const; }; // line is 1-based, column is 0-based diff --git a/src/libs/utils/theme/theme.h b/src/libs/utils/theme/theme.h index 0dbdb61fbe4..c7bf0a5f3af 100644 --- a/src/libs/utils/theme/theme.h +++ b/src/libs/utils/theme/theme.h @@ -259,6 +259,7 @@ public: /* TextEditor Plugin */ TextEditor_SearchResult_ScrollBarColor, + TextEditor_Selection_ScrollBarColor, TextEditor_CurrentLine_ScrollBarColor, /* Debugger Plugin */ diff --git a/src/plugins/coreplugin/find/highlightscrollbarcontroller.cpp b/src/plugins/coreplugin/find/highlightscrollbarcontroller.cpp index 47a857b26af..adaceda64d2 100644 --- a/src/plugins/coreplugin/find/highlightscrollbarcontroller.cpp +++ b/src/plugins/coreplugin/find/highlightscrollbarcontroller.cpp @@ -4,6 +4,7 @@ #include "highlightscrollbarcontroller.h" #include +#include #include #include #include @@ -12,6 +13,8 @@ using namespace Utils; +static Q_LOGGING_CATEGORY(LOG, "qtc.utils.highlightscrollbar", QtWarningMsg) + namespace Core { /*! @@ -403,6 +406,7 @@ void HighlightScrollBarController::addHighlight(Highlight highlight) if (!m_overlay) return; + qCDebug(LOG) << "addHighlight" << highlight.category.toString() << highlight.position; m_highlights[highlight.category] << highlight; m_overlay->scheduleUpdate(); } @@ -412,6 +416,7 @@ void HighlightScrollBarController::removeHighlights(Id category) if (!m_overlay) return; + qCDebug(LOG) << "removeHighlights" << category.toString(); m_highlights.remove(category); m_overlay->scheduleUpdate(); } @@ -421,6 +426,7 @@ void HighlightScrollBarController::removeAllHighlights() if (!m_overlay) return; + qCDebug(LOG) << "removeAllHighlights"; m_highlights.clear(); m_overlay->scheduleUpdate(); } diff --git a/src/plugins/texteditor/displaysettings.cpp b/src/plugins/texteditor/displaysettings.cpp index 5cd8e86c151..fac753b5943 100644 --- a/src/plugins/texteditor/displaysettings.cpp +++ b/src/plugins/texteditor/displaysettings.cpp @@ -37,6 +37,7 @@ const char animateWithinFileTimeMaxKey[] = "AnimateWithinFileTimeMax"; const char displayAnnotationsKey[] = "DisplayAnnotations"; const char annotationAlignmentKey[] = "AnnotationAlignment"; const char minimalAnnotationContentKey[] = "MinimalAnnotationContent"; +const char highlightSelectionKey[] = "HighlightSelection"; const char groupPostfix[] = "textDisplaySettings"; void DisplaySettings::toSettings(QtcSettings *s) const @@ -61,6 +62,7 @@ void DisplaySettings::toSettings(QtcSettings *s) const s->setValue(animateNavigationWithinFileKey, m_animateNavigationWithinFile); s->setValue(displayAnnotationsKey, m_displayAnnotations); s->setValue(annotationAlignmentKey, static_cast(m_annotationAlignment)); + s->setValue(highlightSelectionKey, m_highlightSelection); s->endGroup(); } @@ -92,6 +94,7 @@ void DisplaySettings::fromSettings(QtcSettings *s) s->value(annotationAlignmentKey, static_cast(m_annotationAlignment)).toInt()); m_minimalAnnotationContent = s->value(minimalAnnotationContentKey, m_minimalAnnotationContent).toInt(); + m_highlightSelection = s->value(highlightSelectionKey, m_highlightSelection).toBool(); s->endGroup(); } @@ -119,6 +122,7 @@ bool DisplaySettings::equals(const DisplaySettings &ds) const && m_displayAnnotations == ds.m_displayAnnotations && m_annotationAlignment == ds.m_annotationAlignment && m_minimalAnnotationContent == ds.m_minimalAnnotationContent + && m_highlightSelection == ds.m_highlightSelection ; } diff --git a/src/plugins/texteditor/displaysettings.h b/src/plugins/texteditor/displaysettings.h index 1c8a27f037d..bb42a9ac935 100644 --- a/src/plugins/texteditor/displaysettings.h +++ b/src/plugins/texteditor/displaysettings.h @@ -52,6 +52,7 @@ public: bool m_displayFileLineEnding = true; bool m_scrollBarHighlights = true; bool m_animateNavigationWithinFile = false; + bool m_highlightSelection = true; int m_animateWithinFileTimeMax = 333; // read only setting bool m_displayAnnotations = true; AnnotationAlignment m_annotationAlignment = AnnotationAlignment::RightSide; diff --git a/src/plugins/texteditor/displaysettingspage.cpp b/src/plugins/texteditor/displaysettingspage.cpp index 2449618bf05..e46c5b7c5b4 100644 --- a/src/plugins/texteditor/displaysettingspage.cpp +++ b/src/plugins/texteditor/displaysettingspage.cpp @@ -98,6 +98,10 @@ public: visualizeWhitespace = new QCheckBox(Tr::tr("&Visualize whitespace")); visualizeWhitespace->setToolTip(Tr::tr("Shows tabs and spaces.")); + highlightSelection = new QCheckBox(Tr::tr("&Highlight Selection")); + highlightSelection->setToolTip(Tr::tr("Adds a colored background and a marker to the " + "scrollbar to occurrences of the selected text.")); + leftAligned = new QRadioButton(Tr::tr("Next to editor content")); atMargin = new QRadioButton(Tr::tr("Next to right margin")); rightAligned = new QRadioButton(Tr::tr("Aligned at right side")); @@ -143,6 +147,7 @@ public: autoFoldFirstComment, scrollBarHighlights, animateNavigationWithinFile, + highlightSelection, }, Column { highlightCurrentLine, @@ -195,6 +200,7 @@ public: QCheckBox *openLinksInNextSplit; QCheckBox *highlightMatchingParentheses; QCheckBox *visualizeWhitespace; + QCheckBox *highlightSelection; QGroupBox *displayAnnotations; QRadioButton *leftAligned; QRadioButton *atMargin; @@ -238,6 +244,7 @@ void DisplaySettingsWidget::settingsFromUI(DisplaySettings &displaySettings, displaySettings.m_scrollBarHighlights = scrollBarHighlights->isChecked(); displaySettings.m_animateNavigationWithinFile = animateNavigationWithinFile->isChecked(); displaySettings.m_displayAnnotations = displayAnnotations->isChecked(); + displaySettings.m_highlightSelection = highlightSelection->isChecked(); if (leftAligned->isChecked()) displaySettings.m_annotationAlignment = AnnotationAlignment::NextToContent; else if (atMargin->isChecked()) @@ -276,6 +283,7 @@ void DisplaySettingsWidget::settingsToUI() scrollBarHighlights->setChecked(displaySettings.m_scrollBarHighlights); animateNavigationWithinFile->setChecked(displaySettings.m_animateNavigationWithinFile); displayAnnotations->setChecked(displaySettings.m_displayAnnotations); + highlightSelection->setChecked(displaySettings.m_highlightSelection); switch (displaySettings.m_annotationAlignment) { case AnnotationAlignment::NextToContent: leftAligned->setChecked(true); break; case AnnotationAlignment::NextToMargin: atMargin->setChecked(true); break; diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp index 3556a08caa0..2a133673afd 100644 --- a/src/plugins/texteditor/textdocument.cpp +++ b/src/plugins/texteditor/textdocument.cpp @@ -79,6 +79,13 @@ public: IAssistProvider *m_quickFixProvider = nullptr; QScopedPointer m_indenter; QScopedPointer m_formatter; + struct PlainTextCache + { + int revision = -1; + QString plainText; + }; + + PlainTextCache m_plainTextCache; int m_autoSaveRevision = -1; bool m_silentReload = false; @@ -305,7 +312,11 @@ QString TextDocument::convertToPlainText(const QString &rawText) QString TextDocument::plainText() const { - return convertToPlainText(d->m_document.toRawText()); + if (d->m_plainTextCache.revision != d->m_document.revision()) { + d->m_plainTextCache.plainText = convertToPlainText(d->m_document.toRawText()); + d->m_plainTextCache.revision = d->m_document.revision(); + } + return d->m_plainTextCache.plainText; } QString TextDocument::textAt(int pos, int length) const diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 70265e14a47..a667e29fbaa 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -605,6 +605,7 @@ public: void paintRightMarginLine(const PaintEventData &data, QPainter &painter) const; void paintBlockHighlight(const PaintEventData &data, QPainter &painter) const; void paintSearchResultOverlay(const PaintEventData &data, QPainter &painter) const; + void paintSelectionOverlay(const PaintEventData &data, QPainter &painter) const; void paintIfDefedOutBlocks(const PaintEventData &data, QPainter &painter) const; void paintFindScope(const PaintEventData &data, QPainter &painter) const; void paintCurrentLineHighlight(const PaintEventData &data, QPainter &painter) const; @@ -690,6 +691,7 @@ public: int length; }; void addSearchResultsToScrollBar(const QVector &results); + void addSelectionHighlightToScrollBar(const QVector &selections); void adjustScrollBarRanges(); void setFindScope(const MultiTextCursor &scope); @@ -766,6 +768,7 @@ public: TextEditorOverlay *m_overlay = nullptr; SnippetOverlay *m_snippetOverlay = nullptr; TextEditorOverlay *m_searchResultOverlay = nullptr; + TextEditorOverlay *m_selectionHighlightOverlay = nullptr; bool snippetCheckCursor(const QTextCursor &cursor); void snippetTabOrBacktab(bool forward); @@ -811,6 +814,7 @@ public: QString m_findText; FindFlags m_findFlags; void highlightSearchResults(const QTextBlock &block, const PaintEventData &data) const; + void highlightSelection(const QTextBlock &block) const; QTimer m_delayedUpdateTimer; void setExtraSelections(Utils::Id kind, const QList &selections); @@ -871,7 +875,9 @@ public: CommentDefinition m_commentDefinition; QFuture m_searchFuture; + QFuture m_selectionHighlightFuture; QVector m_searchResults; + QVector m_selectionResults; QTimer m_scrollBarUpdateTimer; HighlightScrollBarController *m_highlightScrollBarController = nullptr; bool m_scrollBarUpdateScheduled = false; @@ -995,6 +1001,7 @@ TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent) , m_overlay(new TextEditorOverlay(q)) , m_snippetOverlay(new SnippetOverlay(q)) , m_searchResultOverlay(new TextEditorOverlay(q)) + , m_selectionHighlightOverlay(new TextEditorOverlay(q)) , m_refactorOverlay(new RefactorOverlay(q)) , m_marksVisible(false) , m_codeFoldingVisible(false) @@ -1010,6 +1017,7 @@ TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent) , m_clipboardAssistProvider(new ClipboardAssistProvider) , m_autoCompleter(new AutoCompleter) { + m_selectionHighlightOverlay->show(); auto aggregate = new Aggregation::Aggregate; m_find = new TextEditorWidgetFind(q); connect(m_find, &BaseTextFind::highlightAllRequested, @@ -1139,6 +1147,8 @@ TextEditorWidgetPrivate::~TextEditorWidgetPrivate() delete m_highlightScrollBarController; if (m_searchFuture.isRunning()) m_searchFuture.cancel(); + if (m_selectionHighlightFuture.isRunning()) + m_selectionHighlightFuture.cancel(); } static QFrame *createSeparator(const QString &styleSheet) @@ -3346,10 +3356,12 @@ void TextEditorWidgetPrivate::documentAboutToBeReloaded() m_overlay->clear(); m_snippetOverlay->clear(); m_searchResultOverlay->clear(); + m_selectionHighlightOverlay->clear(); m_refactorOverlay->clear(); // clear search results m_searchResults.clear(); + m_selectionResults.clear(); } void TextEditorWidgetPrivate::documentReloadFinished(bool success) @@ -4070,6 +4082,35 @@ void TextEditorWidgetPrivate::highlightSearchResults(const QTextBlock &block, co } } +void TextEditorWidgetPrivate::highlightSelection(const QTextBlock &block) const +{ + if (!m_displaySettings.m_highlightSelection || m_cursors.hasMultipleCursors()) + return; + const QString selection = m_cursors.selectedText(); + if (selection.trimmed().isEmpty()) + return; + + const int blockPosition = block.position(); + + QString text = block.text(); + text.replace(QChar::Nbsp, QLatin1Char(' ')); + const int l = selection.length(); + + for (int idx = text.indexOf(selection, 0, Qt::CaseInsensitive); + idx >= 0; + idx = text.indexOf(selection, idx + 1, Qt::CaseInsensitive)) { + const int start = blockPosition + idx; + const int end = start + l; + if (!Utils::contains(m_selectionHighlightOverlay->selections(), + [&](const OverlaySelection &selection) { + return selection.m_cursor_begin.position() == start + && selection.m_cursor_end.position() == end; + })) { + m_selectionHighlightOverlay->addOverlaySelection(start, end, {}, {}); + } + } +} + void TextEditorWidgetPrivate::startCursorFlashTimer() { const int flashTime = QApplication::cursorFlashTime(); @@ -4108,6 +4149,44 @@ void TextEditorWidgetPrivate::updateCursorSelections() selections << QTextEdit::ExtraSelection{cursor, selectionFormat}; } q->setExtraSelections(TextEditorWidget::CursorSelection, selections); + + m_selectionHighlightOverlay->clear(); + + if (m_selectionHighlightFuture.isRunning()) + m_selectionHighlightFuture.cancel(); + + m_selectionResults.clear(); + if (!m_highlightScrollBarController) + return; + m_highlightScrollBarController->removeHighlights(Constants::SCROLL_BAR_SELECTION); + + if (!m_displaySettings.m_highlightSelection || m_cursors.hasMultipleCursors()) + return; + + const QString txt = m_cursors.selectedText(); + if (txt.trimmed().isEmpty()) + return; + + m_selectionHighlightFuture = Utils::asyncRun(Utils::searchInContents, + txt, + FindFlags{}, + m_document->filePath(), + m_document->plainText()); + + Utils::onResultReady(m_selectionHighlightFuture, + this, + [this](const SearchResultItems &resultList) { + QList results; + for (const SearchResultItem &item : resultList) { + int start = item.mainRange().begin.positionInDocument( + m_document->document()); + int end = item.mainRange().end.positionInDocument( + m_document->document()); + results << SearchResult{start, end - start}; + } + m_selectionResults = results; + addSelectionHighlightToScrollBar(results); + }); } void TextEditorWidgetPrivate::moveCursor(QTextCursor::MoveOperation operation, @@ -4489,6 +4568,40 @@ void TextEditorWidgetPrivate::paintSearchResultOverlay(const PaintEventData &dat data.eventRect); } +void TextEditorWidgetPrivate::paintSelectionOverlay(const PaintEventData &data, + QPainter &painter) const +{ + if (m_cursors.hasMultipleCursors()) + return; + const QString expr = m_cursors.selectedText(); + if (expr.isEmpty()) + return; + + const int margin = 5; + QTextBlock block = data.block; + QPointF offset = data.offset; + while (block.isValid()) { + QRectF blockBoundingRect = q->blockBoundingRect(block).translated(offset); + + if (blockBoundingRect.bottom() >= data.eventRect.top() - margin + && blockBoundingRect.top() <= data.eventRect.bottom() + margin) { + highlightSelection(block); + } + offset.ry() += blockBoundingRect.height(); + + if (offset.y() > data.viewportRect.height() + margin) + break; + + block = TextEditor::nextVisibleBlock(block, data.doc); + } + + QColor selection = m_document->fontSettings().toTextCharFormat(C_SELECTION).background().color(); + const QColor text = m_document->fontSettings().toTextCharFormat(C_TEXT).background().color(); + selection.setAlphaF(StyleHelper::luminance(text) > 0.5 ? 0.25 : 0.5); + + m_selectionHighlightOverlay->fill(&painter, selection, data.eventRect); +} + void TextEditorWidgetPrivate::paintIfDefedOutBlocks(const PaintEventData &data, QPainter &painter) const { @@ -5076,6 +5189,8 @@ void TextEditorWidget::paintEvent(QPaintEvent *e) d->paintFindScope(data, painter); // paint search results on top of the find scope d->paintSearchResultOverlay(data, painter); + // paint selection highlights + d->paintSelectionOverlay(data, painter); } while (data.block.isValid()) { @@ -6947,6 +7062,33 @@ void TextEditorWidgetPrivate::addSearchResultsToScrollBar(const QVector &selections) +{ + if (!m_highlightScrollBarController) + return; + for (const SearchResult &result : selections) { + const QTextBlock &block = q->document()->findBlock(result.start); + if (block.isValid() && block.isVisible()) { + if (q->lineWrapMode() == QPlainTextEdit::WidgetWidth) { + const int firstLine = block.layout()->lineForTextPosition(result.start - block.position()).lineNumber(); + const int lastLine = block.layout()->lineForTextPosition(result.start - block.position() + result.length).lineNumber(); + for (int line = firstLine; line <= lastLine; ++line) { + m_highlightScrollBarController->addHighlight( + {Constants::SCROLL_BAR_SELECTION, block.firstLineNumber() + line, + Theme::TextEditor_Selection_ScrollBarColor, Highlight::NormalPriority}); + } + } else { + m_highlightScrollBarController->addHighlight( + {Constants::SCROLL_BAR_SELECTION, + block.blockNumber(), + Theme::TextEditor_Selection_ScrollBarColor, + Highlight::NormalPriority}); + } + } + } +} + Highlight markToHighlight(TextMark *mark, int lineNumber) { return Highlight(mark->category().id, @@ -6968,6 +7110,9 @@ void TextEditorWidgetPrivate::updateHighlightScrollBarNow() // update search results addSearchResultsToScrollBar(m_searchResults); + // update search selection + addSelectionHighlightToScrollBar(m_selectionResults); + // update text marks const TextMarks marks = m_document->marks(); for (TextMark *mark : marks) { @@ -7900,6 +8045,7 @@ void TextEditorWidget::setDisplaySettings(const DisplaySettings &ds) d->updateFileLineEndingVisible(); d->updateHighlights(); d->setupScrollBar(); + d->updateCursorSelections(); viewport()->update(); extraArea()->update(); } diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h index 4cac6a9dd7f..262ce6a5c45 100644 --- a/src/plugins/texteditor/texteditorconstants.h +++ b/src/plugins/texteditor/texteditorconstants.h @@ -216,6 +216,7 @@ const char JUMP_TO_FILE_UNDER_CURSOR[] = "TextEditor.JumpToFileUnderCursor"; const char JUMP_TO_FILE_UNDER_CURSOR_IN_NEXT_SPLIT[] = "TextEditor.JumpToFileUnderCursorInNextSplit"; const char SCROLL_BAR_SEARCH_RESULT[] = "TextEditor.ScrollBarSearchResult"; +const char SCROLL_BAR_SELECTION[] = "TextEditor.ScrollBarSelection"; const char SCROLL_BAR_CURRENT_LINE[] = "TextEditor.ScrollBarCurrentLine"; const TEXTEDITOR_EXPORT char *nameForStyle(TextStyle style); diff --git a/src/plugins/texteditor/texteditoroverlay.cpp b/src/plugins/texteditor/texteditoroverlay.cpp index c5155008926..ab2e9f1279c 100644 --- a/src/plugins/texteditor/texteditoroverlay.cpp +++ b/src/plugins/texteditor/texteditoroverlay.cpp @@ -82,10 +82,13 @@ void TextEditorOverlay::addOverlaySelection(int begin, int end, if (m_selections.isEmpty()) m_firstSelectionOriginalBegin = begin; - else if (begin < m_firstSelectionOriginalBegin) - qWarning() << "overlay selections not in order"; - m_selections.append(selection); + const auto it = std::find_if(m_selections.cbegin(), + m_selections.cend(), + [&](const OverlaySelection &selection) { + return begin > selection.m_cursor_begin.position(); + }); + m_selections.insert(it, selection); update(); } From 30ef90c3221ced0241a18f6f0ffe676b4480f900 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 23 Oct 2023 11:29:47 +0200 Subject: [PATCH 0029/1546] Terminal: add finished signal Change-Id: I9d560d1f1bbaa94ae75420002744073a1e8fad1a Reviewed-by: Marcus Tillmanns --- src/plugins/terminal/terminalwidget.cpp | 10 +++++----- src/plugins/terminal/terminalwidget.h | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/plugins/terminal/terminalwidget.cpp b/src/plugins/terminal/terminalwidget.cpp index 604a0d82bc8..44b55c85960 100644 --- a/src/plugins/terminal/terminalwidget.cpp +++ b/src/plugins/terminal/terminalwidget.cpp @@ -151,10 +151,10 @@ void TerminalWidget::setupPty() connect(m_process.get(), &Process::done, this, [this] { QString errorMessage; + const int exitCode = QTC_GUARD(m_process) ? m_process->exitCode() : -1; if (m_process) { - if (m_process->exitCode() != 0) { - errorMessage - = Tr::tr("Terminal process exited with code %1").arg(m_process->exitCode()); + if (exitCode != 0) { + errorMessage = Tr::tr("Terminal process exited with code %1").arg(exitCode); if (!m_process->errorString().isEmpty()) errorMessage += QString(" (%1)").arg(m_process->errorString()); @@ -181,14 +181,14 @@ void TerminalWidget::setupPty() writeToTerminal(msg, true); } else { - QString exitMsg = Tr::tr("Process exited with code: %1") - .arg(m_process ? m_process->exitCode() : -1); + QString exitMsg = Tr::tr("Process exited with code: %1").arg(exitCode); QByteArray msg = QString("\r\n%1").arg(exitMsg).toUtf8(); writeToTerminal(msg, true); } } else if (!errorMessage.isEmpty()) { Core::MessageManager::writeFlashing(errorMessage); } + emit finised(exitCode); }); connect(m_process.get(), &Process::started, this, [this] { diff --git a/src/plugins/terminal/terminalwidget.h b/src/plugins/terminal/terminalwidget.h index e30366bf0cc..c19bc608b6e 100644 --- a/src/plugins/terminal/terminalwidget.h +++ b/src/plugins/terminal/terminalwidget.h @@ -50,6 +50,7 @@ public: signals: void started(qint64 pid); + void finised(int exitCode); void cwdChanged(const Utils::FilePath &cwd); void commandChanged(const Utils::CommandLine &cmd); void titleChanged(); From 2e93051aaf4aa84eae027e61d0b7c5f347ea9eba Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 23 Oct 2023 13:38:10 +0200 Subject: [PATCH 0030/1546] TextEditor: improve sort selected lines Try to get a sensible scope when there is no selection when sorting lines. Use the indent level of the current block and select all blocks that are not empty with the same indent level around that block before sorting the lines. Change-Id: I68cbd95f95a0cc4425a0339b992225c3946a6858 Reviewed-by: Christian Stenger Reviewed-by: Marcus Tillmanns --- src/plugins/texteditor/texteditor.cpp | 104 +++++++++++------- src/plugins/texteditor/texteditor.h | 2 +- .../texteditor/texteditoractionhandler.cpp | 4 +- src/plugins/texteditor/texteditorconstants.h | 2 +- tests/system/suite_tools/tst_sort/test.py | 2 +- 5 files changed, 70 insertions(+), 44 deletions(-) diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index a667e29fbaa..39b38036055 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -668,8 +668,6 @@ public: void transformSelection(TransformationMethod method); - void transformSelectedLines(ListTransformationMethod method); - void slotUpdateExtraAreaWidth(std::optional width = {}); void slotUpdateRequest(const QRect &r, int dy); void slotUpdateBlockNotify(const QTextBlock &); @@ -2420,9 +2418,72 @@ void TextEditorWidget::lowercaseSelection() d->transformSelection([](const QString &str) { return str.toLower(); }); } -void TextEditorWidget::sortSelectedLines() +void TextEditorWidget::sortLines() { - d->transformSelectedLines([](QStringList &list) { list.sort(); }); + if (d->m_cursors.hasMultipleCursors()) + return; + + QTextCursor cursor = textCursor(); + if (!cursor.hasSelection()) { + // try to get a sensible scope for the sort + const QTextBlock currentBlock = cursor.block(); + QString text = currentBlock.text(); + if (text.simplified().isEmpty()) + return; + const TabSettings ts = textDocument()->tabSettings(); + const int currentIndent = ts.columnAt(text, TabSettings::firstNonSpace(text)); + + int anchor = currentBlock.position(); + for (auto block = currentBlock.previous(); block.isValid(); block = block.previous()) { + text = block.text(); + if (text.simplified().isEmpty() + || ts.columnAt(text, TabSettings::firstNonSpace(text)) != currentIndent) { + break; + } + anchor = block.position(); + } + + int pos = currentBlock.position(); + for (auto block = currentBlock.next(); block.isValid(); block = block.next()) { + text = block.text(); + if (text.simplified().isEmpty() + || ts.columnAt(text, TabSettings::firstNonSpace(text)) != currentIndent) { + break; + } + pos = block.position(); + } + if (anchor == pos) + return; + + cursor.setPosition(anchor); + cursor.setPosition(pos, QTextCursor::KeepAnchor); + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + } + + const bool downwardDirection = cursor.anchor() < cursor.position(); + int startPosition = cursor.selectionStart(); + int endPosition = cursor.selectionEnd(); + + cursor.setPosition(startPosition); + cursor.movePosition(QTextCursor::StartOfBlock); + startPosition = cursor.position(); + + cursor.setPosition(endPosition, QTextCursor::KeepAnchor); + if (cursor.positionInBlock() == 0) + cursor.movePosition(QTextCursor::PreviousBlock, QTextCursor::KeepAnchor); + cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); + endPosition = qMax(cursor.position(), endPosition); + + const QString text = cursor.selectedText(); + QStringList lines = text.split(QChar::ParagraphSeparator); + lines.sort(); + cursor.insertText(lines.join(QChar::ParagraphSeparator)); + + // (re)select the changed lines + // Note: this assumes the transformation did not change the length + cursor.setPosition(downwardDirection ? startPosition : endPosition); + cursor.setPosition(downwardDirection ? endPosition : startPosition, QTextCursor::KeepAnchor); + setTextCursor(cursor); } void TextEditorWidget::indent() @@ -9039,41 +9100,6 @@ void TextEditorWidgetPrivate::transformSelection(TransformationMethod method) q->setMultiTextCursor(cursor); } -void TextEditorWidgetPrivate::transformSelectedLines(ListTransformationMethod method) -{ - if (!method || m_cursors.hasMultipleCursors()) - return; - - QTextCursor cursor = q->textCursor(); - if (!cursor.hasSelection()) - return; - - const bool downwardDirection = cursor.anchor() < cursor.position(); - int startPosition = cursor.selectionStart(); - int endPosition = cursor.selectionEnd(); - - cursor.setPosition(startPosition); - cursor.movePosition(QTextCursor::StartOfBlock); - startPosition = cursor.position(); - - cursor.setPosition(endPosition, QTextCursor::KeepAnchor); - if (cursor.positionInBlock() == 0) - cursor.movePosition(QTextCursor::PreviousBlock, QTextCursor::KeepAnchor); - cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); - endPosition = qMax(cursor.position(), endPosition); - - const QString text = cursor.selectedText(); - QStringList lines = text.split(QChar::ParagraphSeparator); - method(lines); - cursor.insertText(lines.join(QChar::ParagraphSeparator)); - - // (re)select the changed lines - // Note: this assumes the transformation did not change the length - cursor.setPosition(downwardDirection ? startPosition : endPosition); - cursor.setPosition(downwardDirection ? endPosition : startPosition, QTextCursor::KeepAnchor); - q->setTextCursor(cursor); -} - void TextEditorWidget::inSnippetMode(bool *active) { *active = d->m_snippetOverlay->isVisible(); diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h index 2af45826368..51f3cadec88 100644 --- a/src/plugins/texteditor/texteditor.h +++ b/src/plugins/texteditor/texteditor.h @@ -426,7 +426,7 @@ public: void uppercaseSelection(); void lowercaseSelection(); - void sortSelectedLines(); + void sortLines(); void cleanWhitespace(); diff --git a/src/plugins/texteditor/texteditoractionhandler.cpp b/src/plugins/texteditor/texteditoractionhandler.cpp index 49b83b8a756..f16c94249bb 100644 --- a/src/plugins/texteditor/texteditoractionhandler.cpp +++ b/src/plugins/texteditor/texteditoractionhandler.cpp @@ -366,8 +366,8 @@ void TextEditorActionHandlerPrivate::createActions() [] (TextEditorWidget *w) { w->lowercaseSelection(); }, true, Tr::tr("Lowercase Selection"), QKeySequence(Core::useMacShortcuts ? Tr::tr("Meta+U") : Tr::tr("Alt+U")), G_EDIT_TEXT, advancedEditMenu); - m_modifyingActions << registerAction(SORT_SELECTED_LINES, - [] (TextEditorWidget *w) { w->sortSelectedLines(); }, false, Tr::tr("&Sort Selected Lines"), + m_modifyingActions << registerAction(SORT_LINES, + [] (TextEditorWidget *w) { w->sortLines(); }, false, Tr::tr("&Sort Lines"), QKeySequence(Core::useMacShortcuts ? Tr::tr("Meta+Shift+S") : Tr::tr("Alt+Shift+S")), G_EDIT_TEXT, advancedEditMenu); registerAction(FOLD, diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h index 262ce6a5c45..e2115261882 100644 --- a/src/plugins/texteditor/texteditorconstants.h +++ b/src/plugins/texteditor/texteditorconstants.h @@ -157,7 +157,7 @@ const char INSERT_LINE_ABOVE[] = "TextEditor.InsertLineAboveCurrentLine"; const char INSERT_LINE_BELOW[] = "TextEditor.InsertLineBelowCurrentLine"; const char UPPERCASE_SELECTION[] = "TextEditor.UppercaseSelection"; const char LOWERCASE_SELECTION[] = "TextEditor.LowercaseSelection"; -const char SORT_SELECTED_LINES[] = "TextEditor.SortSelectedLines"; +const char SORT_LINES[] = "TextEditor.SortSelectedLines"; const char CUT_LINE[] = "TextEditor.CutLine"; const char COPY_LINE[] = "TextEditor.CopyLine"; const char ADD_SELECT_NEXT_FIND_MATCH[] = "TextEditor.AddSelectionNextFindMatch"; diff --git a/tests/system/suite_tools/tst_sort/test.py b/tests/system/suite_tools/tst_sort/test.py index a8eac9fa830..f2eed1eeae6 100644 --- a/tests/system/suite_tools/tst_sort/test.py +++ b/tests/system/suite_tools/tst_sort/test.py @@ -15,7 +15,7 @@ def main(): "visible='1' window=':Qt Creator_Core::Internal::MainWindow'}", 3000) placeCursorToLine(editor, "bbb") invokeMenuItem("Edit", "Select All") - invokeMenuItem("Edit", "Advanced", "Sort Selected Lines") + invokeMenuItem("Edit", "Advanced", "Sort Lines") test.verify(waitFor("str(editor.plainText) == sorted", 2000), "Verify that sorted text\n%s\nmatches the expected text\n%s" % (editor.plainText, sorted)) invokeMenuItem('File', 'Revert "unsorted.txt" to Saved') From 03acf2810d2c834fd5a1822ee7d164dcc54ea341 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 24 Oct 2023 09:02:47 +0200 Subject: [PATCH 0031/1546] Utils: remove misleading comment from aspect changed signal Change-Id: Ic1d3fb9c72326696899404514cab597a59f5fc89 Reviewed-by: Marcus Tillmanns --- src/libs/utils/aspects.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/utils/aspects.h b/src/libs/utils/aspects.h index e46ce5ab9b8..0d3d18171d1 100644 --- a/src/libs/utils/aspects.h +++ b/src/libs/utils/aspects.h @@ -201,7 +201,7 @@ public: void writeToSettingsImmediatly() const; signals: - void changed(); // "internal" + void changed(); void volatileValueChanged(); void labelLinkActivated(const QString &link); void checkedChanged(); From 0089d3cc3de60c57519130d031d7d29cedc43a5e Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 25 Oct 2023 09:19:28 +0200 Subject: [PATCH 0032/1546] ProjectTreeWidget: Remove unused event filter The object that is installed as an event filter doesn't implement eventFilter. Change-Id: Icc51346e0c9eadf7448a4889df4c447d3bc3082c Reviewed-by: Christian Kandeler --- src/plugins/projectexplorer/projecttreewidget.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/projectexplorer/projecttreewidget.cpp b/src/plugins/projectexplorer/projecttreewidget.cpp index cb505a43a7c..e850d43e7ea 100644 --- a/src/plugins/projectexplorer/projecttreewidget.cpp +++ b/src/plugins/projectexplorer/projecttreewidget.cpp @@ -210,7 +210,6 @@ ProjectTreeWidget::ProjectTreeWidget(QWidget *parent) : QWidget(parent) m_view->setModel(m_model); m_view->setItemDelegate(new ProjectTreeItemDelegate(m_view)); setFocusProxy(m_view); - m_view->installEventFilter(this); auto layout = new QVBoxLayout(); layout->addWidget(ItemViewFind::createSearchableWrapper( From 59cb505dd04c9225b17c3c275f77db8fa6783769 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 25 Oct 2023 13:16:16 +0200 Subject: [PATCH 0033/1546] Terminal: fix typo Change-Id: I92ccb9cee06517d7be86e2393209096e1b47c36a Reviewed-by: Marcus Tillmanns --- src/plugins/terminal/terminalwidget.cpp | 2 +- src/plugins/terminal/terminalwidget.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/terminal/terminalwidget.cpp b/src/plugins/terminal/terminalwidget.cpp index 183b843b741..434a0571936 100644 --- a/src/plugins/terminal/terminalwidget.cpp +++ b/src/plugins/terminal/terminalwidget.cpp @@ -188,7 +188,7 @@ void TerminalWidget::setupPty() } else if (!errorMessage.isEmpty()) { Core::MessageManager::writeFlashing(errorMessage); } - emit finised(exitCode); + emit finished(exitCode); }); connect(m_process.get(), &Process::started, this, [this] { diff --git a/src/plugins/terminal/terminalwidget.h b/src/plugins/terminal/terminalwidget.h index c19bc608b6e..fa1b20e8f97 100644 --- a/src/plugins/terminal/terminalwidget.h +++ b/src/plugins/terminal/terminalwidget.h @@ -50,7 +50,7 @@ public: signals: void started(qint64 pid); - void finised(int exitCode); + void finished(int exitCode); void cwdChanged(const Utils::FilePath &cwd); void commandChanged(const Utils::CommandLine &cmd); void titleChanged(); From 52f45056f0109abe3c488b6e82b2f12ae9861818 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 24 Oct 2023 15:05:36 +0200 Subject: [PATCH 0034/1546] Projects tree: Fix collapsing behavior of Left key Work around a Qt issue that the left key directly jumps to the parent if the horizontal scroll bar is not left-most. Task-number: QTBUG-118515 Change-Id: Icfc2a58863a3847a84bca05fc2de4b28e384106c Reviewed-by: Alessandro Portale --- src/libs/utils/navigationtreeview.cpp | 17 +++++++++++++++++ src/libs/utils/navigationtreeview.h | 1 + 2 files changed, 18 insertions(+) diff --git a/src/libs/utils/navigationtreeview.cpp b/src/libs/utils/navigationtreeview.cpp index 61ef04d8167..5db3d5ccec1 100644 --- a/src/libs/utils/navigationtreeview.cpp +++ b/src/libs/utils/navigationtreeview.cpp @@ -69,6 +69,23 @@ void NavigationTreeView::scrollTo(const QModelIndex &index, QAbstractItemView::S hBar->setValue(scrollX); } +QModelIndex NavigationTreeView::moveCursor(CursorAction cursorAction, + Qt::KeyboardModifiers modifiers) +{ + if (cursorAction == MoveLeft) { + // work around QTBUG-118515 + // Left key moves to parent instead of collapsing current item, if scroll position + // is not left-most + QScrollBar *sb = horizontalScrollBar(); + QModelIndex current = currentIndex(); + if (sb->value() != sb->minimum() && model()->hasChildren(current) && isExpanded(current)) { + collapse(current); + return current; + } + } + return TreeView::moveCursor(cursorAction, modifiers); +} + // This is a workaround to stop Qt from redrawing the project tree every // time the user opens or closes a menu when it has focus. Would be nicer to // fix it in Qt. diff --git a/src/libs/utils/navigationtreeview.h b/src/libs/utils/navigationtreeview.h index a3a0e2b07de..b4f9a19034a 100644 --- a/src/libs/utils/navigationtreeview.h +++ b/src/libs/utils/navigationtreeview.h @@ -14,6 +14,7 @@ class QTCREATOR_UTILS_EXPORT NavigationTreeView : public TreeView public: explicit NavigationTreeView(QWidget *parent = nullptr); void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override; + QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) override; protected: void focusInEvent(QFocusEvent *event) override; From 2697a960a861cc0a531fe6b4517791c43d8d3ef5 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 23 Oct 2023 17:13:41 +0200 Subject: [PATCH 0035/1546] GenericDeployStep: Get rid of isDeploymentNecessary() Make it a part deployRecipe(). Change-Id: Ice297fbcd1c50e09d92110452c92aee7259eabcb Reviewed-by: Christian Kandeler --- .../abstractremotelinuxdeploystep.cpp | 5 ++ .../abstractremotelinuxdeploystep.h | 3 + src/plugins/remotelinux/genericdeploystep.cpp | 55 +++++++++++-------- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp b/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp index 1130767a928..9e72ea0f0cd 100644 --- a/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp +++ b/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp @@ -133,6 +133,11 @@ void AbstractRemoteLinuxDeployStep::handleStdErrData(const QString &data) emit addOutput(data, OutputFormat::Stderr, DontAppendNewline); } +void AbstractRemoteLinuxDeployStep::addSkipDeploymentMessage() +{ + addProgressMessage(Tr::tr("No deployment action necessary. Skipping.")); +} + bool AbstractRemoteLinuxDeployStep::isDeploymentNecessary() const { return true; diff --git a/src/plugins/remotelinux/abstractremotelinuxdeploystep.h b/src/plugins/remotelinux/abstractremotelinuxdeploystep.h index ee56491a8bf..60a2d616399 100644 --- a/src/plugins/remotelinux/abstractremotelinuxdeploystep.h +++ b/src/plugins/remotelinux/abstractremotelinuxdeploystep.h @@ -42,6 +42,9 @@ protected: void addErrorMessage(const QString &message); void addWarningMessage(const QString &message); +protected: + void addSkipDeploymentMessage(); + private: virtual bool isDeploymentNecessary() const; virtual Tasking::GroupItem deployRecipe() = 0; diff --git a/src/plugins/remotelinux/genericdeploystep.cpp b/src/plugins/remotelinux/genericdeploystep.cpp index 4ae804689c2..16073b8dcb5 100644 --- a/src/plugins/remotelinux/genericdeploystep.cpp +++ b/src/plugins/remotelinux/genericdeploystep.cpp @@ -63,36 +63,22 @@ public: } private: - bool isDeploymentNecessary() const final; GroupItem deployRecipe() final; - GroupItem mkdirTask(); - GroupItem transferTask(); + GroupItem mkdirTask(const TreeStorage &storage); + GroupItem transferTask(const TreeStorage &storage); StringAspect flags{this}; BoolAspect ignoreMissingFiles{this}; SelectionAspect method{this}; - - mutable FilesToTransfer m_files; }; -bool GenericDeployStep::isDeploymentNecessary() const -{ - const QList files = target()->deploymentData().allFiles(); - m_files.clear(); - for (const DeployableFile &f : files) - m_files.append({f.localFilePath(), deviceConfiguration()->filePath(f.remoteFilePath())}); - if (ignoreMissingFiles()) - Utils::erase(m_files, [](const FileToTransfer &file) { return !file.m_source.exists(); }); - return !m_files.empty(); -} - -GroupItem GenericDeployStep::mkdirTask() +GroupItem GenericDeployStep::mkdirTask(const TreeStorage &storage) { using ResultType = expected_str; - const auto onSetup = [this](Async &async) { + const auto onSetup = [storage](Async &async) { FilePaths remoteDirs; - for (const FileToTransfer &file : std::as_const(m_files)) + for (const FileToTransfer &file : *storage) remoteDirs << file.m_target.parentDir(); FilePath::sort(remoteDirs); @@ -147,9 +133,9 @@ static FileTransferMethod supportedTransferMethodFor(const FileToTransfer &fileT return FileTransferMethod::GenericCopy; } -GroupItem GenericDeployStep::transferTask() +GroupItem GenericDeployStep::transferTask(const TreeStorage &storage) { - const auto setupHandler = [this](FileTransfer &transfer) { + const auto setupHandler = [this, storage](FileTransfer &transfer) { FileTransferMethod preferredTransferMethod = FileTransferMethod::Rsync; if (method() == 0) preferredTransferMethod = FileTransferMethod::Rsync; @@ -161,7 +147,7 @@ GroupItem GenericDeployStep::transferTask() FileTransferMethod transferMethod = preferredTransferMethod; if (transferMethod != FileTransferMethod::GenericCopy) { - for (const FileToTransfer &fileToTransfer : m_files) { + for (const FileToTransfer &fileToTransfer : *storage) { const FileTransferMethod supportedMethod = supportedTransferMethodFor( fileToTransfer); @@ -175,7 +161,7 @@ GroupItem GenericDeployStep::transferTask() transfer.setTransferMethod(transferMethod); transfer.setRsyncFlags(flags()); - transfer.setFilesToTransfer(m_files); + transfer.setFilesToTransfer(*storage); connect(&transfer, &FileTransfer::progress, this, &GenericDeployStep::handleStdOutData); }; const auto errorHandler = [this](const FileTransfer &transfer) { @@ -194,7 +180,28 @@ GroupItem GenericDeployStep::transferTask() GroupItem GenericDeployStep::deployRecipe() { - return Group { mkdirTask(), transferTask() }; + const TreeStorage storage; + + const auto onSetup = [this, storage] { + const QList deployableFiles = target()->deploymentData().allFiles(); + FilesToTransfer &files = *storage; + for (const DeployableFile &f : deployableFiles) { + if (!ignoreMissingFiles() || f.localFilePath().exists()) + files.append({f.localFilePath(), deviceConfiguration()->filePath(f.remoteFilePath())}); + } + if (files.isEmpty()) { + addSkipDeploymentMessage(); + return SetupResult::StopWithDone; + } + return SetupResult::Continue; + }; + + return Group { + Storage(storage), + onGroupSetup(onSetup), + mkdirTask(storage), + transferTask(storage) + }; } // Factory From 45d8d723b62658a84eed77291b3cee74fdb4f20d Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 26 Oct 2023 09:07:15 +0200 Subject: [PATCH 0036/1546] Core: Add VSCode keyboard mapping Change-Id: I9924eaeba3013ce114890bc0be414ef4eafaddb2 Reviewed-by: Eike Ziller --- .../schemes/MS_Visual_Studio_Code.kms | 28 +++++++++++++++++++ .../coreplugin/actionmanager/commandsfile.cpp | 7 ++++- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 share/qtcreator/schemes/MS_Visual_Studio_Code.kms diff --git a/share/qtcreator/schemes/MS_Visual_Studio_Code.kms b/share/qtcreator/schemes/MS_Visual_Studio_Code.kms new file mode 100644 index 00000000000..cce5508957e --- /dev/null +++ b/share/qtcreator/schemes/MS_Visual_Studio_Code.kms @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/plugins/coreplugin/actionmanager/commandsfile.cpp b/src/plugins/coreplugin/actionmanager/commandsfile.cpp index 18866662ba2..9cf530d7ff4 100644 --- a/src/plugins/coreplugin/actionmanager/commandsfile.cpp +++ b/src/plugins/coreplugin/actionmanager/commandsfile.cpp @@ -106,7 +106,12 @@ QMap> CommandsFile::importCommands() const QTC_ASSERT(!currentId.isEmpty(), continue); const QXmlStreamAttributes attributes = r.attributes(); if (attributes.hasAttribute(ctx.valueAttribute)) { - const QString keyString = fromAttribute(attributes.value(ctx.valueAttribute)); + QString keyString = fromAttribute(attributes.value(ctx.valueAttribute)); + if (HostOsInfo::isMacHost()) + keyString = keyString.replace("AlwaysCtrl", "Meta"); + else + keyString = keyString.replace("AlwaysCtrl", "Ctrl"); + QList keys = result.value(currentId); result.insert(currentId, keys << QKeySequence(keyString)); } From b8535e4cf1f6c9fb1bd61b126dc8207575b5600a Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 25 Oct 2023 15:58:15 +0200 Subject: [PATCH 0037/1546] Editors: Do not ignore DoNotMakeVisible `EditorManagerPrivate::activateEditor` first calls `placeEditor` and since 9295bfe3e47a83aa32b7d18f4f0082714528ab27 this calls `view->setCurrentEditor(...)` even if `DoNotChangeCurrentEditor` and `DoNotMakeVisible` are set. Do not call `view->setCurrentEditor` in `placeEditor`. That call is done if needed later in `activateEditor` (directly or via `setCurrentEditor`). Task-number: QTCREATORBUG-29644 Change-Id: I7d394b190428fedfd32d2a15df2ed0438332534d Reviewed-by: David Schulz --- src/plugins/coreplugin/editormanager/editormanager.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index ad31e04ea98..c41a3a880eb 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -1356,7 +1356,6 @@ IEditor *EditorManagerPrivate::placeEditor(EditorView *view, IEditor *editor) // pull the IEditor over to the new view sourceView->removeEditor(editor); view->addEditor(editor); - view->setCurrentEditor(editor); // possibly adapts old state to new layout editor->restoreState(state); if (!sourceView->currentEditor()) { @@ -1375,7 +1374,6 @@ IEditor *EditorManagerPrivate::placeEditor(EditorView *view, IEditor *editor) } } view->addEditor(editor); - view->setCurrentEditor(editor); // possibly adapts old state to new layout editor->restoreState(state); return editor; From df240005807afd6904dfefcd5f60bcc8b92ca22a Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 23 Oct 2023 17:13:41 +0200 Subject: [PATCH 0038/1546] TarPackageDeployStep: Get rid of isDeploymentNecessary() Make it a part of deployRecipe(). Change-Id: I131cb34171e3d4e09c6e8fa8a13dbfd768d55aa4 Reviewed-by: Christian Kandeler --- src/plugins/remotelinux/tarpackagedeploystep.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/plugins/remotelinux/tarpackagedeploystep.cpp b/src/plugins/remotelinux/tarpackagedeploystep.cpp index 570ecdb958d..7475f47d479 100644 --- a/src/plugins/remotelinux/tarpackagedeploystep.cpp +++ b/src/plugins/remotelinux/tarpackagedeploystep.cpp @@ -53,7 +53,6 @@ public: private: QString remoteFilePath() const; - bool isDeploymentNecessary() const final; GroupItem deployRecipe() final; GroupItem uploadTask(); GroupItem installTask(); @@ -66,11 +65,6 @@ QString TarPackageDeployStep::remoteFilePath() const return QLatin1String("/tmp/") + m_packageFilePath.fileName(); } -bool TarPackageDeployStep::isDeploymentNecessary() const -{ - return hasLocalFileChanged(DeployableFile(m_packageFilePath, {})); -} - GroupItem TarPackageDeployStep::uploadTask() { const auto setupHandler = [this](FileTransfer &transfer) { @@ -117,7 +111,13 @@ GroupItem TarPackageDeployStep::installTask() GroupItem TarPackageDeployStep::deployRecipe() { - return Group { uploadTask(), installTask() }; + const auto onSetup = [this] { + if (hasLocalFileChanged(DeployableFile(m_packageFilePath, {}))) + return SetupResult::Continue; + addSkipDeploymentMessage(); + return SetupResult::StopWithDone; + }; + return Group { onGroupSetup(onSetup), uploadTask(), installTask() }; } From 56e33e3dbcdec7ba70d79cda55169bb27a55f9a1 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 26 Oct 2023 17:46:55 +0200 Subject: [PATCH 0039/1546] TaskTree: Remove unused include This is template only header. Change-Id: Ic70ee5442cde4d3cfb36fe0beefcccf52222756c Reviewed-by: Reviewed-by: Eike Ziller --- src/libs/solutions/tasking/concurrentcall.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libs/solutions/tasking/concurrentcall.h b/src/libs/solutions/tasking/concurrentcall.h index 7c0d1cf47ef..d9a757c9ad3 100644 --- a/src/libs/solutions/tasking/concurrentcall.h +++ b/src/libs/solutions/tasking/concurrentcall.h @@ -3,8 +3,6 @@ #pragma once -#include "tasking_global.h" - #include "tasktree.h" #include From d60a67e800a95daff3134fa57ba423d77c4b96f6 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 23 Oct 2023 17:13:41 +0200 Subject: [PATCH 0040/1546] KillAppStep: Get rid of isDeploymentNecessary() Make it a part of deployRecipe(). Change-Id: Ia52be36ccc2f387dce3d1c9e946179b9ef328717 Reviewed-by: Reviewed-by: Christian Kandeler --- src/plugins/remotelinux/killappstep.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/remotelinux/killappstep.cpp b/src/plugins/remotelinux/killappstep.cpp index b70e597fb84..3986ebe6b9b 100644 --- a/src/plugins/remotelinux/killappstep.cpp +++ b/src/plugins/remotelinux/killappstep.cpp @@ -38,7 +38,6 @@ public: } private: - bool isDeploymentNecessary() const final { return !m_remoteExecutable.isEmpty(); } GroupItem deployRecipe() final; FilePath m_remoteExecutable; @@ -47,9 +46,14 @@ private: GroupItem KillAppStep::deployRecipe() { const auto setupHandler = [this](DeviceProcessKiller &killer) { + if (m_remoteExecutable.isEmpty()) { + addSkipDeploymentMessage(); + return SetupResult::StopWithDone; + } killer.setProcessPath(m_remoteExecutable); addProgressMessage(Tr::tr("Trying to kill \"%1\" on remote device...") .arg(m_remoteExecutable.path())); + return SetupResult::Continue; }; const auto doneHandler = [this](const DeviceProcessKiller &) { addProgressMessage(Tr::tr("Remote application killed.")); From 01c2a30539352d70c3e3eff8c8ecc39d571cf000 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 23 Oct 2023 20:31:36 +0200 Subject: [PATCH 0041/1546] GenericDirectUploadStep: Get rid of isDeploymentNecessary() Make it a part of deployRecipe(). Change-Id: I775f34f31746aa177f341e2b26f225e34bb14a3c Reviewed-by: Christian Kandeler --- .../remotelinux/genericdirectuploadstep.cpp | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/plugins/remotelinux/genericdirectuploadstep.cpp b/src/plugins/remotelinux/genericdirectuploadstep.cpp index 1bf020ecb23..623ba68bd3f 100644 --- a/src/plugins/remotelinux/genericdirectuploadstep.cpp +++ b/src/plugins/remotelinux/genericdirectuploadstep.cpp @@ -31,6 +31,7 @@ const int MaxConcurrentStatCalls = 10; struct UploadStorage { + QList deployableFiles; QList filesToUpload; }; @@ -54,7 +55,6 @@ public: }); } - bool isDeploymentNecessary() const final; GroupItem deployRecipe() final; QDateTime timestampFromStat(const DeployableFile &file, Process *statProc); @@ -70,8 +70,6 @@ public: GroupItem chmodTask(const DeployableFile &file); GroupItem chmodTree(const TreeStorage &storage); - mutable QList m_deployableFiles; - BoolAspect incremental{this}; BoolAspect ignoreMissingFiles{this}; }; @@ -91,18 +89,6 @@ static QList collectFilesToUpload(const DeployableFile &deployab return collected; } -bool GenericDirectUploadStep::isDeploymentNecessary() const -{ - m_deployableFiles = target()->deploymentData().allFiles(); - QList collected; - for (int i = 0; i < m_deployableFiles.count(); ++i) - collected.append(collectFilesToUpload(m_deployableFiles.at(i))); - - QTC_CHECK(collected.size() >= m_deployableFiles.size()); - m_deployableFiles = collected; - return !m_deployableFiles.isEmpty(); -} - QDateTime GenericDirectUploadStep::timestampFromStat(const DeployableFile &file, Process *statProc) { @@ -257,9 +243,26 @@ GroupItem GenericDirectUploadStep::chmodTree(const TreeStorage &s GroupItem GenericDirectUploadStep::deployRecipe() { + const TreeStorage storage; + + const auto setupHandler = [this, storage] { + const QList deployableFiles = target()->deploymentData().allFiles(); + QList collected; + for (const DeployableFile &file : deployableFiles) + collected.append(collectFilesToUpload(file)); + + QTC_CHECK(collected.size() >= deployableFiles.size()); + if (collected.isEmpty()) { + addSkipDeploymentMessage(); + return SetupResult::StopWithDone; + } + storage->deployableFiles = collected; + return SetupResult::Continue; + }; + const auto preFilesToStat = [this](UploadStorage *storage) { QList filesToStat; - for (const DeployableFile &file : std::as_const(m_deployableFiles)) { + for (const DeployableFile &file : std::as_const(storage->deployableFiles)) { if (!incremental() || hasLocalFileChanged(file)) { storage->filesToUpload.append(file); continue; @@ -287,9 +290,9 @@ GroupItem GenericDirectUploadStep::deployRecipe() addProgressMessage(Tr::tr("All files successfully deployed.")); }; - const TreeStorage storage; const Group root { - Tasking::Storage(storage), + Storage(storage), + onGroupSetup(setupHandler), statTree(storage, preFilesToStat, preStatEndHandler), uploadTask(storage), Group { From 316c8ca24bc393b6fd16c8e6b082c6e7855f60f8 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 23 Oct 2023 20:33:29 +0200 Subject: [PATCH 0042/1546] AbstractRemoteLinuxDeployStep: Get rid of isDeploymentNecessary() Change-Id: I05904b19d3a0bf7e918ea79d4963c1c995f55f6a Reviewed-by: Qt CI Bot Reviewed-by: Christian Kandeler --- .../remotelinux/abstractremotelinuxdeploystep.cpp | 9 --------- src/plugins/remotelinux/abstractremotelinuxdeploystep.h | 1 - 2 files changed, 10 deletions(-) diff --git a/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp b/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp index 9e72ea0f0cd..4540deea51d 100644 --- a/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp +++ b/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp @@ -138,11 +138,6 @@ void AbstractRemoteLinuxDeployStep::addSkipDeploymentMessage() addProgressMessage(Tr::tr("No deployment action necessary. Skipping.")); } -bool AbstractRemoteLinuxDeployStep::isDeploymentNecessary() const -{ - return true; -} - GroupItem AbstractRemoteLinuxDeployStep::runRecipe() { const auto onSetup = [this] { @@ -151,10 +146,6 @@ GroupItem AbstractRemoteLinuxDeployStep::runRecipe() addErrorMessage(canDeploy.error()); return SetupResult::StopWithError; } - if (!isDeploymentNecessary()) { - addProgressMessage(Tr::tr("No deployment action necessary. Skipping.")); - return SetupResult::StopWithDone; - } return SetupResult::Continue; }; const auto onDone = [this] { diff --git a/src/plugins/remotelinux/abstractremotelinuxdeploystep.h b/src/plugins/remotelinux/abstractremotelinuxdeploystep.h index 60a2d616399..1312e47331a 100644 --- a/src/plugins/remotelinux/abstractremotelinuxdeploystep.h +++ b/src/plugins/remotelinux/abstractremotelinuxdeploystep.h @@ -46,7 +46,6 @@ protected: void addSkipDeploymentMessage(); private: - virtual bool isDeploymentNecessary() const; virtual Tasking::GroupItem deployRecipe() = 0; Tasking::GroupItem runRecipe() final; From f5e6e71af21b07af1d9f5d65aeac668763efab49 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 23 Oct 2023 20:49:05 +0200 Subject: [PATCH 0043/1546] GenericDirectUploadStep: Simplify task tree The nested Group seems superfluous. Change-Id: Ia555fa9e6f457b0000806d86daf98a3ac7fb33c3 Reviewed-by: Christian Kandeler Reviewed-by: --- src/plugins/remotelinux/genericdirectuploadstep.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/plugins/remotelinux/genericdirectuploadstep.cpp b/src/plugins/remotelinux/genericdirectuploadstep.cpp index 623ba68bd3f..d9fc3d72a35 100644 --- a/src/plugins/remotelinux/genericdirectuploadstep.cpp +++ b/src/plugins/remotelinux/genericdirectuploadstep.cpp @@ -295,10 +295,8 @@ GroupItem GenericDirectUploadStep::deployRecipe() onGroupSetup(setupHandler), statTree(storage, preFilesToStat, preStatEndHandler), uploadTask(storage), - Group { - chmodTree(storage), - statTree(storage, postFilesToStat, postStatEndHandler) - }, + chmodTree(storage), + statTree(storage, postFilesToStat, postStatEndHandler), onGroupDone(doneHandler) }; return root; From 0f91eb8de156b3e3b2ab6442584deced311f51e9 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 20 Oct 2023 15:21:26 +0200 Subject: [PATCH 0044/1546] LanguageClient: Support QLocalSocket as transport medium Change-Id: I1ea921151548bb210968430bfa3c9ccd5f0869a3 Reviewed-by: Qt CI Bot Reviewed-by: David Schulz --- .../languageclientinterface.cpp | 54 +++++++++++++++++++ .../languageclient/languageclientinterface.h | 15 ++++++ 2 files changed, 69 insertions(+) diff --git a/src/plugins/languageclient/languageclientinterface.cpp b/src/plugins/languageclient/languageclientinterface.cpp index d42e74c9b36..4a42219061b 100644 --- a/src/plugins/languageclient/languageclientinterface.cpp +++ b/src/plugins/languageclient/languageclientinterface.cpp @@ -5,8 +5,11 @@ #include "languageclienttr.h" +#include #include +#include + using namespace LanguageServerProtocol; using namespace Utils; @@ -170,4 +173,55 @@ void StdIOClientInterface::readOutput() parseData(out); } +class LocalSocketClientInterface::Private +{ +public: + Private(LocalSocketClientInterface *q, const QString &serverName) + : q(q), serverName(serverName) {} + + void discardSocket(); + + LocalSocketClientInterface * const q; + const QString serverName; + std::unique_ptr socket; +}; + +LocalSocketClientInterface::LocalSocketClientInterface(const QString &serverName) + : d(new Private(this, serverName)) +{ +} + +LocalSocketClientInterface::~LocalSocketClientInterface() +{ + d->discardSocket(); + delete d; +} + +void LocalSocketClientInterface::startImpl() +{ + d->discardSocket(); + d->socket.reset(new QLocalSocket); + d->socket->setServerName(d->serverName); // TODO: Map path? + connect(d->socket.get(), &QLocalSocket::errorOccurred, this, + [this] { emit error(d->socket->errorString()); }); + connect(d->socket.get(), &QLocalSocket::readyRead, this, + [this] { parseData(d->socket->readAll()); }); + connect(d->socket.get(), &QLocalSocket::connected, this, &StdIOClientInterface::started); + connect(d->socket.get(), &QLocalSocket::disconnected, this, &StdIOClientInterface::finished); + d->socket->connectToServer(); +} + +void LocalSocketClientInterface::sendData(const QByteArray &data) +{ + d->socket->write(data); +} + +void LocalSocketClientInterface::Private::discardSocket() +{ + if (socket) { + socket->disconnect(q); + socket->disconnectFromServer(); + } +} + } // namespace LanguageClient diff --git a/src/plugins/languageclient/languageclientinterface.h b/src/plugins/languageclient/languageclientinterface.h index 7577f136913..a6dee5e4eeb 100644 --- a/src/plugins/languageclient/languageclientinterface.h +++ b/src/plugins/languageclient/languageclientinterface.h @@ -81,4 +81,19 @@ private: Utils::TemporaryFile m_logFile; }; +class LANGUAGECLIENT_EXPORT LocalSocketClientInterface : public BaseClientInterface +{ +public: + LocalSocketClientInterface(const QString &serverName); + ~LocalSocketClientInterface() override; + + void startImpl() override; + +private: + void sendData(const QByteArray &data) final; + + class Private; + Private * const d; +}; + } // namespace LanguageClient From 55082abed0cdf27dc31b38823e1a2034cfcbe191 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 30 Oct 2023 09:05:35 +0100 Subject: [PATCH 0045/1546] AutoTest: Remove dead entities Mostly unused functions which where planned to be used or which have become obsolete due to numerous refactorings. Change-Id: I1c951ad7902c3180c5cc8d8d6ec2d9fa58693701 Reviewed-by: David Schulz Reviewed-by: Qt CI Bot --- src/plugins/autotest/boost/boosttesttreeitem.h | 1 - src/plugins/autotest/gtest/gtesttreeitem.h | 1 - src/plugins/autotest/itemdatacache.h | 1 - src/plugins/autotest/testconfiguration.cpp | 10 ---------- src/plugins/autotest/testconfiguration.h | 4 ---- src/plugins/autotest/testprojectsettings.h | 4 ---- src/plugins/autotest/testresultspane.cpp | 12 ------------ src/plugins/autotest/testresultspane.h | 2 -- src/plugins/autotest/testtreemodel.cpp | 6 ------ src/plugins/autotest/testtreemodel.h | 1 - 10 files changed, 42 deletions(-) diff --git a/src/plugins/autotest/boost/boosttesttreeitem.h b/src/plugins/autotest/boost/boosttesttreeitem.h index daa7192ff50..02bda0d9ee6 100644 --- a/src/plugins/autotest/boost/boosttesttreeitem.h +++ b/src/plugins/autotest/boost/boosttesttreeitem.h @@ -44,7 +44,6 @@ public: void setFullName(const QString &fullName) { m_fullName = fullName; } QString fullName() const { return m_fullName; } void setStates(TestStates states) { m_state = states; } - void setState(TestState state) { m_state |= state; } TestStates state() const { return m_state; } QList getAllTestConfigurations() const override; diff --git a/src/plugins/autotest/gtest/gtesttreeitem.h b/src/plugins/autotest/gtest/gtesttreeitem.h index 19e2448cbd9..0a2a5bc1ba9 100644 --- a/src/plugins/autotest/gtest/gtesttreeitem.h +++ b/src/plugins/autotest/gtest/gtesttreeitem.h @@ -44,7 +44,6 @@ public: bool modify(const TestParseResult *result) override; TestTreeItem *createParentGroupNode() const override; - void setStates(TestStates states) { m_state = states; } void setState(TestState state) { m_state |= state; } TestStates state() const { return m_state; } TestTreeItem *findChildByNameStateAndFile(const QString &name, diff --git a/src/plugins/autotest/itemdatacache.h b/src/plugins/autotest/itemdatacache.h index 63c4f2de771..5752aebb1cf 100644 --- a/src/plugins/autotest/itemdatacache.h +++ b/src/plugins/autotest/itemdatacache.h @@ -45,7 +45,6 @@ public: }; void clear() { m_cache.clear(); } - bool isEmpty() const { return m_cache.isEmpty(); } QVariantMap toSettings(const T &valueToIgnore) const { diff --git a/src/plugins/autotest/testconfiguration.cpp b/src/plugins/autotest/testconfiguration.cpp index 3312704a56e..9661d3e580e 100644 --- a/src/plugins/autotest/testconfiguration.cpp +++ b/src/plugins/autotest/testconfiguration.cpp @@ -283,11 +283,6 @@ void TestConfiguration::setProjectFile(const FilePath &projectFile) m_projectFile = projectFile; } -void TestConfiguration::setBuildDirectory(const FilePath &buildDirectory) -{ - m_buildDir = buildDirectory; -} - void TestConfiguration::setInternalTarget(const QString &target) { m_buildTargets.clear(); @@ -309,9 +304,4 @@ bool DebuggableTestConfiguration::isDebugRunMode() const return m_runMode == TestRunMode::Debug || m_runMode == TestRunMode::DebugWithoutDeploy; } -ITestFramework *TestConfiguration::framework() const -{ - return static_cast(testBase()); -} - } // namespace Autotest diff --git a/src/plugins/autotest/testconfiguration.h b/src/plugins/autotest/testconfiguration.h index a7f4eabf5bf..f784841bfc2 100644 --- a/src/plugins/autotest/testconfiguration.h +++ b/src/plugins/autotest/testconfiguration.h @@ -77,17 +77,14 @@ public: void setTestCases(const QStringList &testCases); void setProjectFile(const Utils::FilePath &projectFile); - void setBuildDirectory(const Utils::FilePath &buildDirectory); void setInternalTarget(const QString &target); void setInternalTargets(const QSet &targets); void setOriginalRunConfiguration(ProjectExplorer::RunConfiguration *runConfig); - ITestFramework *framework() const; QStringList testCases() const { return m_testCases; } Utils::FilePath buildDirectory() const { return m_buildDir; } Utils::FilePath projectFile() const { return m_projectFile; } QSet internalTargets() const { return m_buildTargets; } - ProjectExplorer::RunConfiguration *originalRunConfiguration() const { return m_origRunConfig; } Internal::TestRunConfiguration *runConfiguration() const { return m_runConfig; } bool isDeduced() const { return m_deducedConfiguration; } QString runConfigDisplayName() const { return m_deducedConfiguration ? m_deducedFrom @@ -113,7 +110,6 @@ public: : TestConfiguration(framework), m_runMode(runMode) {} void setRunMode(TestRunMode mode) { m_runMode = mode; } - TestRunMode runMode() const { return m_runMode; } bool isDebugRunMode() const; void setMixedDebugging(bool enable) { m_mixedDebugging = enable; } bool mixedDebugging() const { return m_mixedDebugging; } diff --git a/src/plugins/autotest/testprojectsettings.h b/src/plugins/autotest/testprojectsettings.h index 11f31adfab5..09528e5aee7 100644 --- a/src/plugins/autotest/testprojectsettings.h +++ b/src/plugins/autotest/testprojectsettings.h @@ -26,12 +26,8 @@ public: bool useGlobalSettings() const { return m_useGlobalSettings; } void setRunAfterBuild(RunAfterBuildMode mode) {m_runAfterBuild = mode; } RunAfterBuildMode runAfterBuild() const { return m_runAfterBuild; } - void setActiveFrameworks(const QHash &enabledFrameworks) - { m_activeTestFrameworks = enabledFrameworks; } QHash activeFrameworks() const { return m_activeTestFrameworks; } void activateFramework(const Utils::Id &id, bool activate); - void setActiveTestTools(const QHash &enabledTestTools) - { m_activeTestTools = enabledTestTools; } QHash activeTestTools() const { return m_activeTestTools; } void activateTestTool(const Utils::Id &id, bool activate); Internal::ItemDataCache *checkStateCache() { return &m_checkStateCache; } diff --git a/src/plugins/autotest/testresultspane.cpp b/src/plugins/autotest/testresultspane.cpp index d22ad892e45..6d9eea70991 100644 --- a/src/plugins/autotest/testresultspane.cpp +++ b/src/plugins/autotest/testresultspane.cpp @@ -417,18 +417,6 @@ void TestResultsPane::onItemActivated(const QModelIndex &index) EditorManager::openEditorAt(Link{testResult.fileName(), testResult.line(), 0}); } -void TestResultsPane::onRunAllTriggered() -{ - TestRunner *runner = TestRunner::instance(); - runner->runTests(TestRunMode::Run, TestTreeModel::instance()->getAllTestCases()); -} - -void TestResultsPane::onRunSelectedTriggered() -{ - TestRunner *runner = TestRunner::instance(); - runner->runTests(TestRunMode::Run, TestTreeModel::instance()->getSelectedTests()); -} - void TestResultsPane::initializeFilterMenu() { const bool omitIntern = testSettings().omitInternalMsg(); diff --git a/src/plugins/autotest/testresultspane.h b/src/plugins/autotest/testresultspane.h index d762890c97c..811f749b48f 100644 --- a/src/plugins/autotest/testresultspane.h +++ b/src/plugins/autotest/testresultspane.h @@ -78,8 +78,6 @@ private: explicit TestResultsPane(QObject *parent = nullptr); void onItemActivated(const QModelIndex &index); - void onRunAllTriggered(); - void onRunSelectedTriggered(); void checkAllFilter(bool checked); void filterMenuTriggered(QAction *action); bool eventFilter(QObject *object, QEvent *event) override; diff --git a/src/plugins/autotest/testtreemodel.cpp b/src/plugins/autotest/testtreemodel.cpp index 85b8156ff39..85e98b7c218 100644 --- a/src/plugins/autotest/testtreemodel.cpp +++ b/src/plugins/autotest/testtreemodel.cpp @@ -900,12 +900,6 @@ void TestTreeSortFilterModel::setSortMode(ITestTreeItem::SortMode sortMode) invalidate(); } -void TestTreeSortFilterModel::setFilterMode(FilterMode filterMode) -{ - m_filterMode = filterMode; - invalidateFilter(); -} - void TestTreeSortFilterModel::toggleFilter(FilterMode filterMode) { m_filterMode = toFilterMode(m_filterMode ^ filterMode); diff --git a/src/plugins/autotest/testtreemodel.h b/src/plugins/autotest/testtreemodel.h index 291c6d4017d..05c2e5e75de 100644 --- a/src/plugins/autotest/testtreemodel.h +++ b/src/plugins/autotest/testtreemodel.h @@ -114,7 +114,6 @@ public: explicit TestTreeSortFilterModel(TestTreeModel *sourceModel, QObject *parent = nullptr); void setSortMode(ITestTreeItem::SortMode sortMode); - void setFilterMode(FilterMode filterMode); void toggleFilter(FilterMode filterMode); static FilterMode toFilterMode(int f); From 7faec2f4695c7929fb98aa8fcceef8e8f492324c Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 23 Oct 2023 23:10:30 +0200 Subject: [PATCH 0046/1546] ProcessReaper: Simplify takeReaperSetupList() Change-Id: I1904a8e94ebee608e2fdffd888799a45399ac4a2 Reviewed-by: Eike Ziller Reviewed-by: --- src/libs/utils/processreaper.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/libs/utils/processreaper.cpp b/src/libs/utils/processreaper.cpp index f7235d55290..b161aee7fcf 100644 --- a/src/libs/utils/processreaper.cpp +++ b/src/libs/utils/processreaper.cpp @@ -167,9 +167,7 @@ private: QList takeReaperSetupList() { QMutexLocker locker(&m_mutex); - const QList reaperSetupList = m_reaperSetupList; - m_reaperSetupList.clear(); - return reaperSetupList; + return std::exchange(m_reaperSetupList, {}); } void flush() From 3d0832cd4a61e75c65f9791522d74e52af53370c Mon Sep 17 00:00:00 2001 From: Yuri Vilmanis Date: Mon, 30 Oct 2023 17:42:23 +1030 Subject: [PATCH 0047/1546] Reserve space for m_scratchBuffer Change-Id: I2ecddb9af2c75c8e8a4d7b87995d4d0831b0481e Reviewed-by: Christian Kandeler --- src/libs/cplusplus/pp-engine.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/cplusplus/pp-engine.cpp b/src/libs/cplusplus/pp-engine.cpp index f4e8dbdbd0c..74ca1ceb516 100644 --- a/src/libs/cplusplus/pp-engine.cpp +++ b/src/libs/cplusplus/pp-engine.cpp @@ -740,6 +740,7 @@ Preprocessor::Preprocessor(Client *client, Environment *env) , m_expandFunctionlikeMacros(true) , m_keepComments(false) { + m_scratchBuffer.reserve(256); } QByteArray Preprocessor::run(const Utils::FilePath &filePath, From 7bec91c53e3b696f0818a0af635d5aabe30bb5fd Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 31 Oct 2023 20:32:57 +0100 Subject: [PATCH 0048/1546] GitClient: Some minor corrections Use GroupItem instead of ProcessTask inside topRevision(). Replace some [=] captures with more explicit ones. Change-Id: I2e321f7121f80fd2689ecf57cd9735ba56a7962e Reviewed-by: Orgad Shaneh --- src/plugins/git/branchmodel.cpp | 19 +++++++++---------- src/plugins/git/branchview.cpp | 7 ++++--- src/plugins/git/gitclient.cpp | 6 +++--- src/plugins/git/gitclient.h | 7 ++++--- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp index f01d2903d61..3bae1a991f6 100644 --- a/src/plugins/git/branchmodel.cpp +++ b/src/plugins/git/branchmodel.cpp @@ -391,7 +391,7 @@ void BranchModel::clear() d->rootNode->children.takeLast(); d->currentSha.clear(); - d->currentDateTime = QDateTime(); + d->currentDateTime = {}; d->currentBranch = nullptr; d->headNode = nullptr; d->obsoleteLocalBranches.clear(); @@ -410,14 +410,13 @@ void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError) return; } - const ProcessTask topRevisionProc = - gitClient().topRevision(workingDirectory, - [=](const QString &ref, const QDateTime &dateTime) { - d->currentSha = ref; - d->currentDateTime = dateTime; - }); + const GroupItem topRevisionProc = gitClient().topRevision(workingDirectory, + [this](const QString &ref, const QDateTime &dateTime) { + d->currentSha = ref; + d->currentDateTime = dateTime; + }); - const auto setupForEachRef = [=](Process &process) { + const auto setupForEachRef = [this, workingDirectory](Process &process) { d->workingDirectory = workingDirectory; QStringList args = {"for-each-ref", "--format=%(objectname)\t%(refname)\t%(upstream:short)\t" @@ -429,7 +428,7 @@ void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError) gitClient().setupCommand(process, workingDirectory, args); }; - const auto forEachRefDone = [=](const Process &process) { + const auto forEachRefDone = [this](const Process &process) { const QString output = process.stdOut(); const QStringList lines = output.split('\n'); for (const QString &l : lines) @@ -450,7 +449,7 @@ void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError) } }; - const auto forEachRefError = [=](const Process &process) { + const auto forEachRefError = [workingDirectory, showError](const Process &process) { if (showError == ShowError::No) return; const QString message = Tr::tr("Cannot run \"%1\" in \"%2\": %3") diff --git a/src/plugins/git/branchview.cpp b/src/plugins/git/branchview.cpp index 77d700147ae..b5282b709e8 100644 --- a/src/plugins/git/branchview.cpp +++ b/src/plugins/git/branchview.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -546,14 +547,14 @@ TaskTree *BranchView::onFastForwardMerge(const std::function &callback) const TreeStorage storage; - const auto setupMergeBase = [=](Process &process) { - gitClient().setupCommand(process, m_repository, {"merge-base", "HEAD", branch}); + const auto setupMergeBase = [repository = m_repository, branch](Process &process) { + gitClient().setupCommand(process, repository, {"merge-base", "HEAD", branch}); }; const auto onMergeBaseDone = [storage](const Process &process) { storage->mergeBase = process.cleanedStdOut().trimmed(); }; - const ProcessTask topRevisionProc = gitClient().topRevision( + const GroupItem topRevisionProc = gitClient().topRevision( m_repository, [storage](const QString &revision, const QDateTime &) { storage->topRevision = revision; diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 3b561368f0e..532d0a6ef82 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -1715,13 +1715,13 @@ bool GitClient::synchronousRevParseCmd(const FilePath &workingDirectory, const Q } // Retrieve head revision -ProcessTask GitClient::topRevision(const FilePath &workingDirectory, +GroupItem GitClient::topRevision(const FilePath &workingDirectory, const std::function &callback) { - const auto setupProcess = [=](Process &process) { + const auto setupProcess = [this, workingDirectory](Process &process) { setupCommand(process, workingDirectory, {"show", "-s", "--pretty=format:%H:%ct", HEAD}); }; - const auto onProcessDone = [=](const Process &process) { + const auto onProcessDone = [callback](const Process &process) { const QStringList output = process.cleanedStdOut().trimmed().split(':'); QDateTime dateTime; if (output.size() > 1) { diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 03649f0f4e1..d92ea2031ed 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -9,10 +9,10 @@ #include #include -#include #include -#include + +#include #include #include @@ -24,6 +24,7 @@ class QMenu; QT_END_NAMESPACE namespace Core { class ICore; } +namespace Tasking { class GroupItem; } namespace DiffEditor { class ChunkSelection; @@ -245,7 +246,7 @@ public: QString synchronousTopic(const Utils::FilePath &workingDirectory) const; bool synchronousRevParseCmd(const Utils::FilePath &workingDirectory, const QString &ref, QString *output, QString *errorMessage = nullptr) const; - Utils::ProcessTask topRevision(const Utils::FilePath &workingDirectory, + Tasking::GroupItem topRevision(const Utils::FilePath &workingDirectory, const std::function &callback); bool isRemoteCommit(const Utils::FilePath &workingDirectory, const QString &commit); From f32ea12f2e0cb597b56de22c77bee5ef17eff1c1 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 31 Oct 2023 10:59:40 +0100 Subject: [PATCH 0049/1546] ProjectExplorer: Allow removing non sdk kits Change-Id: If3d9862d617cf8a207285da9e4cf75362c4a0c79 Reviewed-by: Christian Kandeler --- src/plugins/projectexplorer/kit.cpp | 1 + src/plugins/projectexplorer/kitoptionspage.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/kit.cpp b/src/plugins/projectexplorer/kit.cpp index a43ca8f3816..bcdcd5c0700 100644 --- a/src/plugins/projectexplorer/kit.cpp +++ b/src/plugins/projectexplorer/kit.cpp @@ -207,6 +207,7 @@ void Kit::copyFrom(const Kit *k) { copyKitCommon(this, k); d->m_autodetected = k->d->m_autodetected; + d->m_sdkProvided = k->d->m_sdkProvided; d->m_autoDetectionSource = k->d->m_autoDetectionSource; d->m_unexpandedDisplayName = k->d->m_unexpandedDisplayName; d->m_fileSystemFriendlyName = k->d->m_fileSystemFriendlyName; diff --git a/src/plugins/projectexplorer/kitoptionspage.cpp b/src/plugins/projectexplorer/kitoptionspage.cpp index 62c119a46a2..15a865cfe80 100644 --- a/src/plugins/projectexplorer/kitoptionspage.cpp +++ b/src/plugins/projectexplorer/kitoptionspage.cpp @@ -677,7 +677,7 @@ void KitOptionsPageWidget::updateState() if (Kit *k = currentKit()) { canCopy = true; - canDelete = !k->isAutoDetected(); + canDelete = !k->isSdkProvided(); canMakeDefault = !m_model->isDefaultKit(k); } From 02230db8e3a1b3cd5c934c4e4ef85343cb41cd63 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 30 Oct 2023 14:17:29 +0100 Subject: [PATCH 0050/1546] Axivion: Fix build for Qt6.2 on Windows Change-Id: Ia371db59ba19278a8df306b9f79331bef49fc7bb Reviewed-by: David Schulz Reviewed-by: Reviewed-by: Andreas Loth --- src/plugins/axivion/dashboard/dashboardclient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/axivion/dashboard/dashboardclient.cpp b/src/plugins/axivion/dashboard/dashboardclient.cpp index 169bf8984cd..5137ad32461 100644 --- a/src/plugins/axivion/dashboard/dashboardclient.cpp +++ b/src/plugins/axivion/dashboard/dashboardclient.cpp @@ -33,7 +33,7 @@ static void deleteLater(QObject *obj) using ResponseData = Utils::expected, Error>; static constexpr int httpStatusCodeOk = 200; -static constexpr QLatin1String jsonContentType{ "application/json" }; +static const QLatin1String jsonContentType{ "application/json" }; class ResponseReader final { From 0a3bfc9323329cff6cc7c536763f4005236bf2ae Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Thu, 19 Oct 2023 13:01:13 +0900 Subject: [PATCH 0051/1546] ProjectExplorer: Auto-focus on name field when adding a Kit This eliminates one redundant click for users every time they add a Kit. Change-Id: Ia0c994d0569466182a92ab591d6d2ee344d7cf63 Reviewed-by: Reviewed-by: Christian Kandeler --- src/plugins/projectexplorer/kitmanagerconfigwidget.cpp | 6 ++++++ src/plugins/projectexplorer/kitmanagerconfigwidget.h | 1 + src/plugins/projectexplorer/kitoptionspage.cpp | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp index 9954bfb156f..54e2cafc9e6 100644 --- a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp +++ b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp @@ -141,6 +141,12 @@ QIcon KitManagerConfigWidget::displayIcon() const return m_modifiedKit->displayIcon(); } +void KitManagerConfigWidget::setFocusToName() +{ + m_nameEdit->selectAll(); + m_nameEdit->setFocus(); +} + void KitManagerConfigWidget::apply() { // TODO: Rework the mechanism so this won't be necessary. diff --git a/src/plugins/projectexplorer/kitmanagerconfigwidget.h b/src/plugins/projectexplorer/kitmanagerconfigwidget.h index 86f637c5e35..1a499f7dabf 100644 --- a/src/plugins/projectexplorer/kitmanagerconfigwidget.h +++ b/src/plugins/projectexplorer/kitmanagerconfigwidget.h @@ -31,6 +31,7 @@ public: QString displayName() const; QIcon displayIcon() const; + void setFocusToName(); void apply(); void discard(); bool isDirty() const; diff --git a/src/plugins/projectexplorer/kitoptionspage.cpp b/src/plugins/projectexplorer/kitoptionspage.cpp index 15a865cfe80..e3c84549ca8 100644 --- a/src/plugins/projectexplorer/kitoptionspage.cpp +++ b/src/plugins/projectexplorer/kitoptionspage.cpp @@ -632,6 +632,9 @@ void KitOptionsPageWidget::addNewKit() QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); + + if (m_currentWidget) + m_currentWidget->setFocusToName(); } Kit *KitOptionsPageWidget::currentKit() const @@ -652,6 +655,9 @@ void KitOptionsPageWidget::cloneKit() QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); + + if (m_currentWidget) + m_currentWidget->setFocusToName(); } void KitOptionsPageWidget::removeKit() From 1acf00d3e1e6bd1177d65854a6c99276bd57c182 Mon Sep 17 00:00:00 2001 From: Yuri Vilmanis Date: Mon, 30 Oct 2023 17:41:50 +1030 Subject: [PATCH 0052/1546] Avoid unnecessary string and list copies Change-Id: I78bc4d307be69ce3bbfaa3ca3dd7c85e654af8d6 Reviewed-by: Christian Kandeler --- src/libs/cplusplus/FastPreprocessor.cpp | 4 ++-- src/libs/utils/filepath.cpp | 22 ++++++++++++++++------ src/libs/utils/filepath.h | 2 +- src/libs/utils/templateengine.cpp | 10 +++++----- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/libs/cplusplus/FastPreprocessor.cpp b/src/libs/cplusplus/FastPreprocessor.cpp index 580334d0744..8dcc8509b15 100644 --- a/src/libs/cplusplus/FastPreprocessor.cpp +++ b/src/libs/cplusplus/FastPreprocessor.cpp @@ -38,7 +38,7 @@ QByteArray FastPreprocessor::run(Document::Ptr newDoc, mergeEnvironment(i.key()); } - const QList includes = doc->resolvedIncludes(); + const QList &includes = doc->resolvedIncludes(); for (const Document::Include &i : includes) mergeEnvironment(i.resolvedFileName()); @@ -69,7 +69,7 @@ void FastPreprocessor::mergeEnvironment(const FilePath &filePath) { if (Utils::insert(_merged, filePath)) { if (Document::Ptr doc = _snapshot.document(filePath)) { - const QList includes = doc->resolvedIncludes(); + const QList &includes = doc->resolvedIncludes(); for (const Document::Include &i : includes) mergeEnvironment(i.resolvedFileName()); diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index 8b898344278..78e31c235f9 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -453,7 +453,7 @@ QStringView FilePath::host() const QStringView FilePath::pathView() const { - return QStringView(m_data).left(m_pathLen); + return QStringView(m_data.constData(), m_pathLen); } QString FilePath::path() const @@ -469,7 +469,17 @@ void FilePath::setParts(const QStringView scheme, const QStringView host, QStrin path = path.mid(3); m_hash = 0; - m_data = path.toString() + scheme.toString() + host.toString(); + + // The equivalent of: + // m_data = path.toString() + scheme.toString() + host.toString(); + // but with less copying. + // Note: The QStringBuilder optimization does not currently work in this case. + m_data.resize(0); + m_data.reserve(m_schemeLen + m_hostLen + m_pathLen); + m_data.append(path); + m_data.append(scheme); + m_data.append(host); + m_schemeLen = scheme.size(); m_hostLen = host.size(); m_pathLen = path.size(); @@ -1480,7 +1490,7 @@ FilePath FilePath::relativePathFrom(const FilePath &anchor) const absoluteAnchorPath = anchor.absoluteFilePath(); else return {}; - QString relativeFilePath = calcRelativePath(absPath.path(), absoluteAnchorPath.path()); + QString relativeFilePath = calcRelativePath(absPath.pathView(), absoluteAnchorPath.pathView()); if (!filename.isEmpty()) { if (relativeFilePath == ".") relativeFilePath.clear(); @@ -1505,14 +1515,14 @@ FilePath FilePath::relativePathFrom(const FilePath &anchor) const \see FilePath::isRelativePath(), FilePath::relativePathFrom(), FilePath::relativeChildPath() */ -QString FilePath::calcRelativePath(const QString &absolutePath, const QString &absoluteAnchorPath) +QString FilePath::calcRelativePath(QStringView absolutePath, QStringView absoluteAnchorPath) { if (absolutePath.isEmpty() || absoluteAnchorPath.isEmpty()) return QString(); // TODO using split() instead of parsing the strings by char index is slow // and needs more memory (but the easiest implementation for now) - const QStringList splits1 = absolutePath.split('/'); - const QStringList splits2 = absoluteAnchorPath.split('/'); + const QList splits1 = absolutePath.split('/'); + const QList splits2 = absoluteAnchorPath.split('/'); int i = 0; while (i < splits1.count() && i < splits2.count() && splits1.at(i) == splits2.at(i)) ++i; diff --git a/src/libs/utils/filepath.h b/src/libs/utils/filepath.h index a35a3a09403..2264e3761a2 100644 --- a/src/libs/utils/filepath.h +++ b/src/libs/utils/filepath.h @@ -258,7 +258,7 @@ public: [[nodiscard]] static int rootLength(const QStringView path); // Assumes no scheme and host [[nodiscard]] static int schemeAndHostLength(const QStringView path); - static QString calcRelativePath(const QString &absolutePath, const QString &absoluteAnchorPath); + static QString calcRelativePath(QStringView absolutePath, QStringView absoluteAnchorPath); //! Returns a filepath the represents the same file on a local drive expected_str localSource() const; diff --git a/src/libs/utils/templateengine.cpp b/src/libs/utils/templateengine.cpp index a917ea27cb8..9aa583226c3 100644 --- a/src/libs/utils/templateengine.cpp +++ b/src/libs/utils/templateengine.cpp @@ -46,11 +46,11 @@ PreprocessStackEntry::PreprocessStackEntry(PreprocessorSection s, bool p, bool c class PreprocessContext { public: PreprocessContext(); - bool process(const QString &in, QString *out, QString *errorMessage); + bool process(QStringView in, QString *out, QString *errorMessage); private: void reset(); - PreprocessorSection preprocessorLine(const QString & in, QString *ifExpression) const; + PreprocessorSection preprocessorLine(QStringView in, QString *ifExpression) const; mutable QRegularExpression m_ifPattern; mutable QRegularExpression m_elsifPattern; @@ -81,7 +81,7 @@ void PreprocessContext::reset() // Determine type of line and return enumeration, cut out // expression for '@if/@elsif'. -PreprocessorSection PreprocessContext::preprocessorLine(const QString &in, +PreprocessorSection PreprocessContext::preprocessorLine(QStringView in, QString *ifExpression) const { QRegularExpressionMatch match = m_ifPattern.match(in); @@ -111,7 +111,7 @@ static inline QString msgEmptyStack(int line) return QString::fromLatin1("Unmatched '@endif' at line %1.").arg(line); } -bool PreprocessContext::process(const QString &in, QString *out, QString *errorMessage) +bool PreprocessContext::process(QStringView in, QString *out, QString *errorMessage) { out->clear(); if (in.isEmpty()) @@ -121,7 +121,7 @@ bool PreprocessContext::process(const QString &in, QString *out, QString *errorM reset(); const QChar newLine = QLatin1Char('\n'); - const QStringList lines = in.split(newLine); + const QList lines = in.split(newLine); const int lineCount = lines.size(); bool first = true; for (int l = 0; l < lineCount; l++) { From 20d355e2359d82f1ebeac7787a98655e95346241 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 16 Oct 2023 10:25:22 +0200 Subject: [PATCH 0053/1546] ProjectExplorer: add relevant kit aspects filter Change-Id: I1a2d940c31a3e9f687f2c9d45d68ca9c1f9e1f61 Reviewed-by: Christian Kandeler --- .../filterkitaspectsdialog.cpp | 7 ++-- src/plugins/projectexplorer/kit.cpp | 37 +++++++++++++++++-- src/plugins/projectexplorer/kit.h | 3 ++ .../kitmanagerconfigwidget.cpp | 7 +--- 4 files changed, 41 insertions(+), 13 deletions(-) diff --git a/src/plugins/projectexplorer/filterkitaspectsdialog.cpp b/src/plugins/projectexplorer/filterkitaspectsdialog.cpp index 9564d6cb41c..131ca9ebae3 100644 --- a/src/plugins/projectexplorer/filterkitaspectsdialog.cpp +++ b/src/plugins/projectexplorer/filterkitaspectsdialog.cpp @@ -82,10 +82,9 @@ public: { setHeader({Tr::tr("Setting"), Tr::tr("Visible")}); for (const KitAspectFactory * const factory : KitManager::kitAspectFactories()) { - const QSet irrelevantAspects = kit ? kit->irrelevantAspects() - : KitManager::irrelevantAspects(); - auto * const item = new FilterTreeItem(factory, - !irrelevantAspects.contains(factory->id())); + const bool enabled = kit ? kit->isAspectRelevant(factory->id()) + : !KitManager::irrelevantAspects().contains(factory->id()); + auto * const item = new FilterTreeItem(factory, enabled); rootItem()->appendChild(item); } static const auto cmp = [](const TreeItem *item1, const TreeItem *item2) { diff --git a/src/plugins/projectexplorer/kit.cpp b/src/plugins/projectexplorer/kit.cpp index bcdcd5c0700..5478860979d 100644 --- a/src/plugins/projectexplorer/kit.cpp +++ b/src/plugins/projectexplorer/kit.cpp @@ -42,6 +42,7 @@ const char ICON_KEY[] = "PE.Profile.Icon"; const char DEVICE_TYPE_FOR_ICON_KEY[] = "PE.Profile.DeviceTypeForIcon"; const char MUTABLE_INFO_KEY[] = "PE.Profile.MutableInfo"; const char STICKY_INFO_KEY[] = "PE.Profile.StickyInfo"; +const char RELEVANT_ASPECTS_KEY[] = "PE.Kit.RelevantAspects"; const char IRRELEVANT_ASPECTS_KEY[] = "PE.Kit.IrrelevantAspects"; namespace ProjectExplorer { @@ -104,6 +105,7 @@ public: QSet m_sticky; QSet m_mutable; std::optional> m_irrelevantAspects; + std::optional> m_relevantAspects; MacroExpander m_macroExpander; }; @@ -142,8 +144,9 @@ Kit::Kit(const Store &data) d->m_fileSystemFriendlyName = data.value(FILESYSTEMFRIENDLYNAME_KEY).toString(); d->m_iconPath = FilePath::fromString(data.value(ICON_KEY, d->m_iconPath.toString()).toString()); d->m_deviceTypeForIcon = Id::fromSetting(data.value(DEVICE_TYPE_FOR_ICON_KEY)); - const auto it = data.constFind(IRRELEVANT_ASPECTS_KEY); - if (it != data.constEnd()) + if (const auto it = data.constFind(RELEVANT_ASPECTS_KEY); it != data.constEnd()) + d->m_relevantAspects = transform>(it.value().toList(), &Id::fromSetting); + if (const auto it = data.constFind(IRRELEVANT_ASPECTS_KEY); it != data.constEnd()) d->m_irrelevantAspects = transform>(it.value().toList(), &Id::fromSetting); Store extra = storeFromVariant(data.value(DATA_KEY)); @@ -185,6 +188,7 @@ void Kit::copyKitCommon(Kit *target, const Kit *source) target->d->m_cachedIcon = source->d->m_cachedIcon; target->d->m_sticky = source->d->m_sticky; target->d->m_mutable = source->d->m_mutable; + target->d->m_relevantAspects = source->d->m_relevantAspects; target->d->m_irrelevantAspects = source->d->m_irrelevantAspects; target->d->m_hasValidityInfo = false; } @@ -235,8 +239,10 @@ bool Kit::hasWarning() const Tasks Kit::validate() const { Tasks result; - for (KitAspectFactory *factory : KitManager::kitAspectFactories()) - result.append(factory->validate(this)); + for (KitAspectFactory *factory : KitManager::kitAspectFactories()) { + if (isAspectRelevant(factory->id())) + result.append(factory->validate(this)); + } d->m_hasError = containsType(result, Task::TaskType::Error); d->m_hasWarning = containsType(result, Task::TaskType::Warning); @@ -480,6 +486,7 @@ bool Kit::isEqual(const Kit *other) const && d->m_deviceTypeForIcon == other->d->m_deviceTypeForIcon && d->m_unexpandedDisplayName == other->d->m_unexpandedDisplayName && d->m_fileSystemFriendlyName == other->d->m_fileSystemFriendlyName + && d->m_relevantAspects == other->d->m_relevantAspects && d->m_irrelevantAspects == other->d->m_irrelevantAspects && d->m_mutable == other->d->m_mutable; } @@ -509,6 +516,10 @@ Store Kit::toMap() const stickyInfo << id.toString(); data.insert(STICKY_INFO_KEY, stickyInfo); + if (d->m_relevantAspects) { + data.insert(RELEVANT_ASPECTS_KEY, transform(d->m_relevantAspects.value(), + &Id::toSetting)); + } if (d->m_irrelevantAspects) { data.insert(IRRELEVANT_ASPECTS_KEY, transform(d->m_irrelevantAspects.value(), &Id::toSetting)); @@ -662,6 +673,18 @@ bool Kit::isMutable(Id id) const return d->m_mutable.contains(id); } +void Kit::setRelevantAspects(const QSet &relevant) +{ + d->m_relevantAspects = relevant; +} + +QSet Kit::relevantAspects() const +{ + if (d->m_relevantAspects) + return *d->m_relevantAspects; + return {}; +} + void Kit::setIrrelevantAspects(const QSet &irrelevant) { d->m_irrelevantAspects = irrelevant; @@ -672,6 +695,12 @@ QSet Kit::irrelevantAspects() const return d->m_irrelevantAspects.value_or(KitManager::irrelevantAspects()); } +bool Kit::isAspectRelevant(const Utils::Id &aspect) const +{ + return d->m_relevantAspects ? d->m_relevantAspects->contains(aspect) + : !irrelevantAspects().contains(aspect); +} + QSet Kit::supportedPlatforms() const { QSet platforms; diff --git a/src/plugins/projectexplorer/kit.h b/src/plugins/projectexplorer/kit.h index e6611ed7212..3a8ccdfee8d 100644 --- a/src/plugins/projectexplorer/kit.h +++ b/src/plugins/projectexplorer/kit.h @@ -119,8 +119,11 @@ public: void makeReplacementKit(); bool isReplacementKit() const; + void setRelevantAspects(const QSet &relevant); + QSet relevantAspects() const; void setIrrelevantAspects(const QSet &irrelevant); QSet irrelevantAspects() const; + bool isAspectRelevant(const Utils::Id &aspect) const; QSet supportedPlatforms() const; QSet availableFeatures() const; diff --git a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp index 54e2cafc9e6..eb6b32b2c99 100644 --- a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp +++ b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp @@ -216,11 +216,8 @@ void KitManagerConfigWidget::addAspectToWorkingCopy(Layouting::LayoutItem &paren void KitManagerConfigWidget::updateVisibility() { - for (KitAspect *aspect : std::as_const(m_kitAspects)) { - const KitAspectFactory *factory = aspect->factory(); - const bool irrelevant = m_modifiedKit->irrelevantAspects().contains(factory->id()); - aspect->setVisible(!irrelevant); - } + for (KitAspect *aspect : std::as_const(m_kitAspects)) + aspect->setVisible(m_modifiedKit->isAspectRelevant(aspect->factory()->id())); } void KitManagerConfigWidget::makeStickySubWidgetsReadOnly() From 28b70672b40cadc61d34ff58dbd1e2c5500f28be Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 19 Oct 2023 13:00:48 +0200 Subject: [PATCH 0054/1546] Python: generate Python kits for new interpreter Change-Id: Ie4b23aae296f66900fba85a9e243bbf656e49ed4 Reviewed-by: Christian Kandeler --- src/plugins/python/pythonplugin.cpp | 5 ++ src/plugins/python/pythonsettings.cpp | 111 +++++++++++++++++++++++++- src/plugins/python/pythonsettings.h | 3 + 3 files changed, 118 insertions(+), 1 deletion(-) diff --git a/src/plugins/python/pythonplugin.cpp b/src/plugins/python/pythonplugin.cpp index a7e8cc3c747..fdfc0095554 100644 --- a/src/plugins/python/pythonplugin.cpp +++ b/src/plugins/python/pythonplugin.cpp @@ -5,6 +5,7 @@ #include "pysidebuildconfiguration.h" #include "pythoneditor.h" +#include "pythonkitaspect.h" #include "pythonproject.h" #include "pythonrunconfiguration.h" #include "pythonsettings.h" @@ -13,6 +14,7 @@ #include #include +#include #include #include #include @@ -60,6 +62,9 @@ void PythonPlugin::initialize() { d = new PythonPluginPrivate; + KitManager::setIrrelevantAspects(KitManager::irrelevantAspects() + + QSet{PythonKitAspect::id()}); + ProjectManager::registerProjectType(PythonMimeType); ProjectManager::registerProjectType(PythonMimeTypeLegacy); } diff --git a/src/plugins/python/pythonsettings.cpp b/src/plugins/python/pythonsettings.cpp index 410714af090..4e68f542519 100644 --- a/src/plugins/python/pythonsettings.cpp +++ b/src/plugins/python/pythonsettings.cpp @@ -4,6 +4,7 @@ #include "pythonsettings.h" #include "pythonconstants.h" +#include "pythonkitaspect.h" #include "pythonplugin.h" #include "pythontr.h" #include "pythonutils.h" @@ -11,6 +12,9 @@ #include #include +#include +#include + #include #include @@ -144,6 +148,7 @@ private: InterpreterDetailsWidget *m_detailsWidget = nullptr; QPushButton *m_deleteButton = nullptr; QPushButton *m_makeDefaultButton = nullptr; + QPushButton *m_generateKitButton = nullptr; QPushButton *m_cleanButton = nullptr; QString m_defaultId; @@ -153,6 +158,7 @@ private: void addItem(); void deleteItem(); void makeDefault(); + void generateKit(); void cleanUp(); }; @@ -199,6 +205,8 @@ InterpreterOptionsWidget::InterpreterOptionsWidget() m_deleteButton->setEnabled(false); m_makeDefaultButton = new QPushButton(Tr::tr("&Make Default")); m_makeDefaultButton->setEnabled(false); + m_generateKitButton = new QPushButton(Tr::tr("&Generate Kit")); + m_generateKitButton->setEnabled(false); m_cleanButton = new QPushButton(Tr::tr("&Clean Up"), this); m_cleanButton->setToolTip(Tr::tr("Remove all Python interpreters without a valid executable.")); @@ -209,6 +217,7 @@ InterpreterOptionsWidget::InterpreterOptionsWidget() addButton, m_deleteButton, m_makeDefaultButton, + m_generateKitButton, m_cleanButton, st }; @@ -230,6 +239,7 @@ InterpreterOptionsWidget::InterpreterOptionsWidget() connect(addButton, &QPushButton::pressed, this, &InterpreterOptionsWidget::addItem); connect(m_deleteButton, &QPushButton::pressed, this, &InterpreterOptionsWidget::deleteItem); connect(m_makeDefaultButton, &QPushButton::pressed, this, &InterpreterOptionsWidget::makeDefault); + connect(m_generateKitButton, &QPushButton::pressed, this, &InterpreterOptionsWidget::generateKit); connect(m_cleanButton, &QPushButton::pressed, this, &InterpreterOptionsWidget::cleanUp); connect(m_detailsWidget, &InterpreterDetailsWidget::changed, @@ -275,8 +285,11 @@ void InterpreterOptionsWidget::currentChanged(const QModelIndex &index, const QM if (index.isValid()) { m_detailsWidget->updateInterpreter(m_model.itemAt(index.row())->itemData); m_detailsWidget->show(); + m_generateKitButton->setEnabled( + !KitManager::kit(Id::fromString(m_model.itemAt(index.row())->itemData.id))); } else { m_detailsWidget->hide(); + m_generateKitButton->setEnabled(false); } m_deleteButton->setEnabled(index.isValid()); m_makeDefaultButton->setEnabled(index.isValid()); @@ -553,6 +566,13 @@ void InterpreterOptionsWidget::makeDefault() } } +void InterpreterOptionsWidget::generateKit() +{ + const QModelIndex &index = m_view->currentIndex(); + if (index.isValid()) + PythonSettings::addKitsForInterpreter(m_model.itemAt(index.row())->itemData); +} + void InterpreterOptionsWidget::cleanUp() { m_model.destroyItems( @@ -563,6 +583,7 @@ void InterpreterOptionsWidget::cleanUp() constexpr char settingsGroupKey[] = "Python"; constexpr char interpreterKey[] = "Interpeter"; constexpr char defaultKey[] = "DefaultInterpeter"; +constexpr char kitsGeneratedKey[] = "KitsGenerated"; constexpr char pylsEnabledKey[] = "PylsEnabled"; constexpr char pylsConfigurationKey[] = "PylsConfiguration"; @@ -786,12 +807,65 @@ PythonSettings::~PythonSettings() settingsInstance = nullptr; } +static void setRelevantAspectsToKit(Kit *k) +{ + QTC_ASSERT(k, return); + QSet relevantAspects = k->relevantAspects(); + relevantAspects.unite({PythonKitAspect::id(), EnvironmentKitAspect::id()}); + k->setRelevantAspects(relevantAspects); +} + +void PythonSettings::addKitsForInterpreter(const Interpreter &interpreter) +{ + if (!KitManager::isLoaded()) { + connect(KitManager::instance(), &KitManager::kitsLoaded, settingsInstance, [interpreter]() { + addKitsForInterpreter(interpreter); + }); + return; + } + + const Id kitId = Id::fromString(interpreter.id); + if (Kit *k = KitManager::kit(kitId)) { + setRelevantAspectsToKit(k); + } else { + KitManager::registerKit( + [interpreter](Kit *k) { + k->setAutoDetected(true); + k->setAutoDetectionSource("Python"); + k->setUnexpandedDisplayName(interpreter.name); + setRelevantAspectsToKit(k); + PythonKitAspect::setPython(k, interpreter.id); + }, + kitId); + } +} + +void PythonSettings::removeKitsForInterpreter(const Interpreter &interpreter) +{ + if (!KitManager::isLoaded()) { + connect(KitManager::instance(), &KitManager::kitsLoaded, settingsInstance, [interpreter]() { + removeKitsForInterpreter(interpreter); + }); + return; + } + + if (Kit *k = KitManager::kit(Id::fromString(interpreter.id))) + KitManager::deregisterKit(k); +} + void PythonSettings::setInterpreter(const QList &interpreters, const QString &defaultId) { if (defaultId == settingsInstance->m_defaultInterpreterId && interpreters == settingsInstance->m_interpreters) { return; } + QList toRemove = settingsInstance->m_interpreters; + for (const Interpreter &interpreter : interpreters) { + if (!Utils::eraseOne(toRemove, Utils::equal(&Interpreter::id, interpreter.id))) + addKitsForInterpreter(interpreter); + } + for (const Interpreter &interpreter : toRemove) + removeKitsForInterpreter(interpreter); settingsInstance->m_interpreters = interpreters; settingsInstance->m_defaultInterpreterId = defaultId; saveSettings(); @@ -833,6 +907,7 @@ void PythonSettings::addInterpreter(const Interpreter &interpreter, bool isDefau if (isDefault) settingsInstance->m_defaultInterpreterId = interpreter.id; saveSettings(); + addKitsForInterpreter(interpreter); } Interpreter PythonSettings::addInterpreter(const FilePath &interpreterPath, @@ -981,7 +1056,24 @@ void PythonSettings::initFromSettings(QtcSettings *settings) || interpreter.command.isExecutableFile(); }; - m_interpreters = Utils::filtered(m_interpreters, keepInterpreter); + const auto [valid, outdatedInterpreters] = Utils::partition(m_interpreters, keepInterpreter); + m_interpreters = valid; + + if (!settings->value(kitsGeneratedKey, false).toBool()) { + for (const Interpreter &interpreter : m_interpreters) { + if (interpreter.autoDetected) { + const FilePath &cmd = interpreter.command; + if (cmd.needsDevice() || cmd.parentDir().pathAppended("activate").exists()) + continue; + } + addKitsForInterpreter(interpreter); + } + } else { + fixupPythonKits(); + } + + for (const Interpreter &outdated : outdatedInterpreters) + removeKitsForInterpreter(outdated); m_defaultInterpreterId = settings->value(defaultKey).toString(); @@ -1014,6 +1106,7 @@ void PythonSettings::writeToSettings(QtcSettings *settings) settings->setValue(defaultKey, m_defaultInterpreterId); settings->setValue(pylsConfigurationKey, m_pylsConfiguration); settings->setValue(pylsEnabledKey, m_pylsEnabled); + settings->setValue(kitsGeneratedKey, true); settings->endGroup(); } @@ -1056,6 +1149,22 @@ void PythonSettings::listDetectedPython(const QString &detectionSource, QString logMessage->append(interpreter.name + '\n'); } +void PythonSettings::fixupPythonKits() +{ + if (!KitManager::isLoaded()) { + connect(KitManager::instance(), + &KitManager::kitsLoaded, + settingsInstance, + &PythonSettings::fixupPythonKits, + Qt::UniqueConnection); + return; + } + for (const Interpreter &interpreter : m_interpreters) { + if (auto k = KitManager::kit(Id::fromString(interpreter.id))) + setRelevantAspectsToKit(k); + } +} + void PythonSettings::saveSettings() { QTC_ASSERT(settingsInstance, return); diff --git a/src/plugins/python/pythonsettings.h b/src/plugins/python/pythonsettings.h index 373054094e1..827748ee3b9 100644 --- a/src/plugins/python/pythonsettings.h +++ b/src/plugins/python/pythonsettings.h @@ -42,6 +42,8 @@ public: const std::function)> &callback, const QString &nameSuffix = {}); static QList detectPythonVenvs(const Utils::FilePath &path); + static void addKitsForInterpreter(const Interpreter &interpreter); + static void removeKitsForInterpreter(const Interpreter &interpreter); signals: void interpretersChanged(const QList &interpreters, const QString &defaultId); @@ -57,6 +59,7 @@ public slots: void listDetectedPython(const QString &detectionSource, QString *logMessage); private: + void fixupPythonKits(); void initFromSettings(Utils::QtcSettings *settings); void writeToSettings(Utils::QtcSettings *settings); From b2cb87f06e198aab48e3aaeed67d99f83f25e2fa Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 16 Oct 2023 10:21:50 +0200 Subject: [PATCH 0055/1546] Python: add a python kit aspect Change-Id: If7aaa52025ec5834a44e9196548fbcc7456c89a8 Reviewed-by: Christian Stenger --- src/plugins/python/CMakeLists.txt | 1 + src/plugins/python/python.qbs | 2 + src/plugins/python/pythonconstants.h | 2 + src/plugins/python/pythonkitaspect.cpp | 151 +++++++++++++++++++++++++ src/plugins/python/pythonkitaspect.h | 20 ++++ 5 files changed, 176 insertions(+) create mode 100644 src/plugins/python/pythonkitaspect.cpp create mode 100644 src/plugins/python/pythonkitaspect.h diff --git a/src/plugins/python/CMakeLists.txt b/src/plugins/python/CMakeLists.txt index 25275cebdfc..8c48f9cdbba 100644 --- a/src/plugins/python/CMakeLists.txt +++ b/src/plugins/python/CMakeLists.txt @@ -12,6 +12,7 @@ add_qtc_plugin(Python pythonformattoken.h pythonhighlighter.cpp pythonhighlighter.h pythonindenter.cpp pythonindenter.h + pythonkitaspect.h pythonkitaspect.cpp pythonlanguageclient.cpp pythonlanguageclient.h pythonplugin.cpp pythonplugin.h pythonproject.cpp pythonproject.h diff --git a/src/plugins/python/python.qbs b/src/plugins/python/python.qbs index dd7aba1b697..057822a1e97 100644 --- a/src/plugins/python/python.qbs +++ b/src/plugins/python/python.qbs @@ -35,6 +35,8 @@ QtcPlugin { "pythonhighlighter.h", "pythonindenter.cpp", "pythonindenter.h", + "pythonkitaspect.cpp", + "pythonkitaspect.h", "pythonlanguageclient.cpp", "pythonlanguageclient.h", "pythonplugin.cpp", diff --git a/src/plugins/python/pythonconstants.h b/src/plugins/python/pythonconstants.h index 315aca8da66..add9d6b6d64 100644 --- a/src/plugins/python/pythonconstants.h +++ b/src/plugins/python/pythonconstants.h @@ -17,6 +17,8 @@ const char C_PYTHONOPTIONS_PAGE_ID[] = "PythonEditor.OptionsPage"; const char C_PYLSCONFIGURATION_PAGE_ID[] = "PythonEditor.PythonLanguageServerConfiguration"; const char C_PYTHON_SETTINGS_CATEGORY[] = "P.Python"; +const char PYTHON_TOOLKIT_ASPECT_ID[] = "Python.Interpreter"; + const char PYTHON_OPEN_REPL[] = "Python.OpenRepl"; const char PYTHON_OPEN_REPL_IMPORT[] = "Python.OpenReplImport"; const char PYTHON_OPEN_REPL_IMPORT_TOPLEVEL[] = "Python.OpenReplImportToplevel"; diff --git a/src/plugins/python/pythonkitaspect.cpp b/src/plugins/python/pythonkitaspect.cpp new file mode 100644 index 00000000000..2adbdd3e13d --- /dev/null +++ b/src/plugins/python/pythonkitaspect.cpp @@ -0,0 +1,151 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "pythonkitaspect.h" + +#include "pythonconstants.h" +#include "pythonsettings.h" +#include "pythontr.h" + +#include + +#include +#include + +#include + +using namespace ProjectExplorer; +using namespace Utils; + +namespace Python { + +using namespace Internal; + +class PythonKitAspectImpl final : public KitAspect +{ +public: + PythonKitAspectImpl(Kit *kit, const KitAspectFactory *kitInfo) + : KitAspect(kit, kitInfo) + { + m_comboBox = createSubWidget(); + m_comboBox->setSizePolicy(QSizePolicy::Ignored, m_comboBox->sizePolicy().verticalPolicy()); + + refresh(); + m_comboBox->setToolTip(kitInfo->description()); + connect(m_comboBox, &QComboBox::currentIndexChanged, this, [this] { + if (m_ignoreChanges.isLocked()) + return; + + PythonKitAspect::setPython(m_kit, m_comboBox->currentData().toString()); + }); + + m_manageButton = createManageButton(Constants::C_PYTHONOPTIONS_PAGE_ID); + } + + void makeReadOnly() override + { + m_manageButton->setEnabled(false); + m_comboBox->setEnabled(false); + } + + void refresh() override + { + const GuardLocker locker(m_ignoreChanges); + m_comboBox->clear(); + m_comboBox->addItem(Tr::tr("None"), QString()); + + for (const Interpreter &interpreter : PythonSettings::interpreters()) + m_comboBox->addItem(interpreter.name, interpreter.id); + + updateComboBox(PythonKitAspect::python(m_kit)); + } + + void updateComboBox(const std::optional &python) + { + const int index = python ? std::max(m_comboBox->findData(python->id), 0) : 0; + m_comboBox->setCurrentIndex(index); + } + +protected: + void addToLayoutImpl(Layouting::LayoutItem &parent) override + { + addMutableAction(m_comboBox); + parent.addItem(m_comboBox); + parent.addItem(m_manageButton); + } + +private: + Guard m_ignoreChanges; + QComboBox *m_comboBox = nullptr; + QWidget *m_manageButton = nullptr; +}; + +class PythonKitAspectFactory : public KitAspectFactory +{ +public: + PythonKitAspectFactory() + { + setId(PythonKitAspect::id()); + setDisplayName(Tr::tr("Python")); + setDescription(Tr::tr("The interpreter used for Python based projects.")); + setPriority(10000); + } + + Tasks validate(const Kit *k) const override + { + const std::optional python = PythonKitAspect::python(k); + if (!python) + return {}; + const FilePath path = python->command; + if (path.needsDevice()) + return {}; + if (path.isEmpty()) + return {BuildSystemTask(Task::Error, Tr::tr("No Python setup."))}; + if (!path.exists()) { + return {BuildSystemTask(Task::Error, + Tr::tr("Python %1 not found.").arg(path.toUserOutput()))}; + } + if (!path.isExecutableFile()) { + return {BuildSystemTask{Task::Error, + Tr::tr("Python %1 not executable.").arg(path.toUserOutput())}}; + } + return {}; + } + + ItemList toUserOutput(const Kit *k) const override + { + if (const std::optional python = PythonKitAspect::python(k)) { + return {{displayName(), + QString("%1 (%2)").arg(python->name).arg(python->command.toUserOutput())}}; + } + return {}; + } + + KitAspect *createKitAspect(Kit *k) const override { return new PythonKitAspectImpl(k, this); } +}; + +std::optional PythonKitAspect::python(const Kit *kit) +{ + QTC_ASSERT(kit, return {}); + const QString interpreterId = kit->value(id()).toString(); + if (interpreterId.isEmpty()) + return {}; + if (const Interpreter interpreter = PythonSettings::interpreter(interpreterId); interpreter.id == interpreterId) + return interpreter; + return {}; +} + +void PythonKitAspect::setPython(Kit *k, const QString &interpreterId) +{ + QTC_ASSERT(k, return); + k->setValue(PythonKitAspect::id(), interpreterId); +} + +Id PythonKitAspect::id() +{ + return Constants::PYTHON_TOOLKIT_ASPECT_ID; +} + +const PythonKitAspectFactory thePythonToolKitAspectFactory; + +} // namespace Python diff --git a/src/plugins/python/pythonkitaspect.h b/src/plugins/python/pythonkitaspect.h new file mode 100644 index 00000000000..927a608affc --- /dev/null +++ b/src/plugins/python/pythonkitaspect.h @@ -0,0 +1,20 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +namespace ProjectExplorer { class Kit; } + +namespace Python { + +class PythonKitAspect +{ +public: + static std::optional python(const ProjectExplorer::Kit *kit); + static void setPython(ProjectExplorer::Kit *k, const QString &interpreterId); + static Utils::Id id(); +}; + +}; // namespace Python From f5e12237a2ad17665749f10bebb83c3852b539ce Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 2 Nov 2023 10:15:06 +0100 Subject: [PATCH 0056/1546] Python: avoid detecting pythonw on windows Change-Id: I75fcba53fa671904405d3411409c6ea67335e81b Reviewed-by: Christian Stenger --- src/plugins/python/pythonsettings.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/plugins/python/pythonsettings.cpp b/src/plugins/python/pythonsettings.cpp index 4e68f542519..256919b0317 100644 --- a/src/plugins/python/pythonsettings.cpp +++ b/src/plugins/python/pythonsettings.cpp @@ -661,25 +661,12 @@ static QList pythonsFromRegistry() FilePath::fromUserInput(regVal.toString())}; } } - regVal = pythonRegistry.value("InstallPath/WindowedExecutablePath"); - if (regVal.isValid()) { - const FilePath &executable = FilePath::fromUserInput(regVal.toString()); - if (executable.exists()) { - pythons << Interpreter{QUuid::createUuid().toString(), - //: (Windowed) - Tr::tr("%1 (Windowed)").arg(name), - FilePath::fromUserInput(regVal.toString())}; - } - } regVal = pythonRegistry.value("InstallPath/."); if (regVal.isValid()) { const FilePath &path = FilePath::fromUserInput(regVal.toString()); const FilePath python = path.pathAppended("python").withExecutableSuffix(); if (python.exists()) pythons << createInterpreter(python, "Python " + versionGroup); - const FilePath pythonw = path.pathAppended("pythonw").withExecutableSuffix(); - if (pythonw.exists()) - pythons << createInterpreter(pythonw, "Python " + versionGroup, "(Windowed)"); } pythonRegistry.endGroup(); } @@ -697,10 +684,6 @@ static QList pythonsFromPath() if (executable.exists()) pythons << createInterpreter(executable, "Python from Path"); } - for (const FilePath &executable : FilePath("pythonw").searchAllInPath()) { - if (executable.exists()) - pythons << createInterpreter(executable, "Python from Path", "(Windowed)"); - } } else { const QStringList filters = {"python", "python[1-9].[0-9]", From 024f6538066f69a18a5ef627ab6320536a0b6a43 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 1 Nov 2023 09:42:48 +0100 Subject: [PATCH 0057/1546] Python: initialize run configuration with kit python Change-Id: I85ebe906bee2d9bc88c443f0189a685ac97ee30d Reviewed-by: Reviewed-by: Christian Stenger --- src/plugins/python/pythonrunconfiguration.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/python/pythonrunconfiguration.cpp b/src/plugins/python/pythonrunconfiguration.cpp index 12141ba1a93..30e85439b5c 100644 --- a/src/plugins/python/pythonrunconfiguration.cpp +++ b/src/plugins/python/pythonrunconfiguration.cpp @@ -8,6 +8,7 @@ #include "pysidebuildconfiguration.h" #include "pysideuicextracompiler.h" #include "pythonconstants.h" +#include "pythonkitaspect.h" #include "pythonlanguageclient.h" #include "pythonproject.h" #include "pythonsettings.h" @@ -365,6 +366,9 @@ public: x11Forwarding.setMacroExpander(macroExpander()); x11Forwarding.setVisible(HostOsInfo::isAnyUnixHost()); + if (const std::optional kitPython = PythonKitAspect::python(target->kit())) + interpreter.setCurrentInterpreter(*kitPython); + setCommandLineGetter([this] { CommandLine cmd{interpreter.currentInterpreter().command}; if (!buffered()) From 086fafbd493946304b103995f0b65b2d2323827a Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Thu, 2 Nov 2023 11:29:34 +0800 Subject: [PATCH 0058/1546] Move Main.qml onto its own line in Qt Quick project templates - Matches other commands in other templates (e.g. PROJECT_SOURCES). - Makes it that little bit easier for users to add more files. - Encourages users not to cram everything onto one line. I didn't change qtquickapplication_compat/CMakeLists.6.x.txt because I assume %{AdditionalQmlFiles} expands to many entries per line anyway (and if so, that should be changed too). Change-Id: I0cd33181e7000f070aa563e2341f739df8956e6d Reviewed-by: Alexey Edelev Reviewed-by: Reviewed-by: Ulf Hermann Reviewed-by: Eike Ziller --- .../wizards/projects/qtquickapplication/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt b/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt index 5f9fd95f1b2..5ab817b9bfe 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt @@ -24,7 +24,8 @@ qt_add_executable(%{TargetName} qt_add_qml_module(%{TargetName} URI %{ProjectName} VERSION 1.0 - QML_FILES Main.qml + QML_FILES + Main.qml ) # Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1. From 45d99c2ceeb1ce3810428b5cedc814ed3e5af626 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 30 Oct 2023 14:29:18 +0100 Subject: [PATCH 0059/1546] Fix running tests if system language is not english Force built-in tr strings when running tests. Some tests rely on these, e.g. the JSON wizard tests in ProjectExplorer. Change-Id: I27836adce0bd2f8c6919a8b1948e41f719c08b3e Reviewed-by: Christian Stenger Reviewed-by: --- src/app/main.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index 036d169c063..bedbb5d39c9 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -672,7 +672,9 @@ int main(int argc, char **argv) QTranslator translator; QTranslator qtTranslator; QStringList uiLanguages = QLocale::system().uiLanguages(); - QString overrideLanguage = settings->value("General/OverrideLanguage").toString(); + const QString overrideLanguage = options.hasTestOption + ? QString("C") // force built-in when running tests + : settings->value("General/OverrideLanguage").toString(); if (!overrideLanguage.isEmpty()) uiLanguages.prepend(overrideLanguage); if (!options.uiLanguage.isEmpty()) From 5f7be10349339519a5977be9db9a3f781709e20b Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 2 Nov 2023 15:08:23 +0100 Subject: [PATCH 0060/1546] Locator: Handle file create error Coverity-Id: 1561120 Change-Id: Iefa1f6e7bc7a28d9f0d7427051896c49a413f027 Reviewed-by: Leena Miettinen Reviewed-by: David Schulz --- src/plugins/coreplugin/locator/filesystemfilter.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/plugins/coreplugin/locator/filesystemfilter.cpp b/src/plugins/coreplugin/locator/filesystemfilter.cpp index 39eea1200fe..07bb25c1086 100644 --- a/src/plugins/coreplugin/locator/filesystemfilter.cpp +++ b/src/plugins/coreplugin/locator/filesystemfilter.cpp @@ -77,7 +77,13 @@ static void createAndOpenFile(const FilePath &filePath) if (!filePath.exists()) { if (askForCreating(Tr::tr("Create File"), filePath)) { QFile file(filePath.toFSPathString()); - file.open(QFile::WriteOnly); + if (!file.open(QFile::WriteOnly)) { + QMessageBox::warning(ICore::dialogParent(), + Tr::tr("Cannot Create File"), + Tr::tr("Cannot create file \"%1\".") + .arg(filePath.toUserOutput())); + return; + } file.close(); VcsManager::promptToAdd(filePath.absolutePath(), {filePath}); } From d0203a39fa9ec63ee155d536151c39447e83e056 Mon Sep 17 00:00:00 2001 From: Volodymyr Zibarov Date: Wed, 1 Nov 2023 10:30:01 +0200 Subject: [PATCH 0061/1546] ClangCodeModel: Add menu action to re-index files ... that depend on changed headers. When changing a header file the clangd code model is not updated for files that including it if they are not opened in editor. This is not to be done automatically, as it would be a performance hazard to rescan many files, for example when changing a widely used header. Add a menu action to trigger such re-indexing manually to solve the issue. Task-number: QTCREATORBUG-27387 Change-Id: Ia8033401f847627cee041b102f9ac6f3af3dd709 Reviewed-by: Volodymyr Zibarov Reviewed-by: Christian Kandeler --- .../clangcodemodel/clangcodemodelplugin.cpp | 15 +++ .../clangmodelmanagersupport.cpp | 105 ++++++++++++++++++ .../clangcodemodel/clangmodelmanagersupport.h | 4 +- 3 files changed, 122 insertions(+), 2 deletions(-) diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp index ac194abfbf9..e8b8f5e28df 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -83,6 +84,20 @@ void ClangCodeModelPlugin::initialize() CppEditor::CppModelManager::activateClangCodeModel(std::make_unique()); createCompilationDBAction(); + QAction * const updateStaleIndexEntries + = new QAction(Tr::tr("Update potentially stale clangd index entries"), this); + Command * const cmd = ActionManager::registerAction(updateStaleIndexEntries, + "ClangCodeModel.UpdateStaleIndexEntries"); + connect(updateStaleIndexEntries, &QAction::triggered, this, + [] { ClangModelManagerSupport::updateStaleIndexEntries(); }); + const QList menus; + namespace CppConstants = CppEditor::Constants; + for (ActionContainer * const menu : {ActionManager::actionContainer(CppConstants::M_TOOLS_CPP), + ActionManager::actionContainer(CppConstants::M_CONTEXT)}) { + QTC_ASSERT(menu, continue); + menu->addAction(cmd, CppEditor::Constants::G_GLOBAL); + } + #ifdef WITH_TESTS addTest(); addTest(); diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index a25ceef0ff5..caefe586308 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -48,7 +48,10 @@ #include #include +#include +#include #include +#include #include #include #include @@ -61,6 +64,41 @@ using namespace ProjectExplorer; using namespace Utils; namespace ClangCodeModel::Internal { +namespace { +class IndexFiles +{ +public: + QList files; + QDateTime minLastModifiedTime; +}; +} // namespace + +static Q_LOGGING_CATEGORY(clangdIndexLog, "qtc.clangcodemodel.clangd.index", QtWarningMsg); + +static QHash collectIndexedFiles(const Utils::FilePath &indexFolder) +{ + QHash result; + QDirIterator dirIt(indexFolder.toFSPathString(), QDir::Files); + while (dirIt.hasNext()) { + dirIt.next(); + FilePath path = FilePath::fromString(dirIt.filePath()); + if (path.suffix() != "idx") + continue; + + QString baseName = path.completeBaseName(); + const int dotPos = baseName.lastIndexOf('.'); + if (dotPos <= 0) + continue; + + baseName = baseName.left(dotPos); + IndexFiles &indexFiles = result[baseName]; + indexFiles.files.push_back(path); + QDateTime time = path.lastModified(); + if (indexFiles.minLastModifiedTime.isNull() || time < indexFiles.minLastModifiedTime) + indexFiles.minLastModifiedTime = time; + } + return result; +} static Project *fallbackProject() { @@ -644,6 +682,73 @@ ClangdClient *ClangModelManagerSupport::clientWithProject(const Project *project return clients.empty() ? nullptr : qobject_cast(clients.first()); } +void ClangModelManagerSupport::updateStaleIndexEntries() +{ + QHash lastModifiedCache; + for (const Project * const project : ProjectManager::projects()) { + const FilePath jsonDbDir = getJsonDbDir(project); + if (jsonDbDir.isEmpty()) + continue; + + const FilePath indexFolder = jsonDbDir / ".cache" / "clangd" / "index"; + if (!indexFolder.exists()) + continue; + + const QHash indexedFiles = collectIndexedFiles(indexFolder); + bool restartCodeModel = false; + const CPlusPlus::Snapshot snapshot = CppModelManager::snapshot(); + for (const CPlusPlus::Document::Ptr &document : snapshot) { + const FilePath sourceFile = document->filePath(); + if (sourceFile.fileName() == "") + continue; + + if (!project->isKnownFile(sourceFile)) { + qCDebug(clangdIndexLog) << "Not in project:" << sourceFile.fileName(); + continue; + } + + const auto indexFilesIt = indexedFiles.find(sourceFile.fileName()); + if (indexFilesIt == indexedFiles.end()) { + qCDebug(clangdIndexLog) << "No index files for:" << sourceFile.fileName(); + continue; + } + + const QDateTime sourceIndexedTime = indexFilesIt->minLastModifiedTime; + + bool rescan = false; + QSet allIncludes = snapshot.allIncludesForDocument(sourceFile); + for (const FilePath &includeFile : qAsConst(allIncludes)) { + auto includeFileTimeIt = lastModifiedCache.find(includeFile); + if (includeFileTimeIt == lastModifiedCache.end()) { + includeFileTimeIt = lastModifiedCache.insert(includeFile, + includeFile.lastModified()); + } + if (sourceIndexedTime < includeFileTimeIt.value()) { + qCDebug(clangdIndexLog) << "Rescan file:" << sourceFile.fileName() + << "indexed at" << sourceIndexedTime + << "changed include:" << includeFile.fileName() + << "last modified at" << includeFileTimeIt.value(); + rescan = true; + break; + } + } + if (rescan) { + for (const FilePath &indexFile : indexFilesIt->files) + indexFile.removeFile(); + restartCodeModel = true; + } + } + if (restartCodeModel) { + if (ClangdClient * const client = clientForProject(project)) { + const auto instance = dynamic_cast( + CppModelManager::modelManagerSupport(CppModelManager::Backend::Best)); + QTC_ASSERT(instance, return); + instance->scheduleClientRestart(client); + } + } + } +} + ClangdClient *ClangModelManagerSupport::clientForFile(const FilePath &file) { return qobject_cast(LanguageClientManager::clientForFilePath(file)); diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index cc361127836..595bfdd7950 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -14,8 +14,6 @@ #include #include -#include - QT_BEGIN_NAMESPACE class QMenu; class QTimer; @@ -50,6 +48,8 @@ public: static ClangdClient *clientForProject(const ProjectExplorer::Project *project); static ClangdClient *clientForFile(const Utils::FilePath &file); + static void updateStaleIndexEntries(); + private: void followSymbol(const CppEditor::CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, bool resolveTarget, From e006d4e86d06bc824efa25518abbea47711f22b6 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 3 Nov 2023 19:29:44 +0100 Subject: [PATCH 0062/1546] Android: Avoid "Empty filename passed to function" warning When launching Qt Creator with clean settings on Windows, the Android plugin might cause an "Empty filename passed to function" warning that comes from deep inside Qt. This hack works around that. Change-Id: Id668b981a1467a54d852082e95963e34554006e9 Reviewed-by: Cristian Adam --- src/plugins/android/androidconfigurations.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index 65dae8e7fb5..1c6f8c7cbce 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -505,6 +505,9 @@ FilePath AndroidConfig::toolchainPathFromNdk(const FilePath &ndkLocation, OsType toolchainPath = tcPath / llvmIter.fileName() / "prebuilt/"; } + if (toolchainPath.isEmpty()) + return {}; + // detect toolchain host QStringList hostPatterns; switch (hostOs) { From f8bbdf6f07b909690da5b55244cfa1ba064901c6 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 2 Oct 2023 17:54:48 +0200 Subject: [PATCH 0063/1546] Core: Inline ICore::init() into ICore constructor More natural setup. Change-Id: I5a51cdec3f955e4b887613bd3dea4b25d485e844 Reviewed-by: Eike Ziller --- src/plugins/coreplugin/coreplugin.cpp | 3 +-- src/plugins/coreplugin/icore.cpp | 27 ++++++++++----------------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp index bfd0669c338..17f1a08031f 100644 --- a/src/plugins/coreplugin/coreplugin.cpp +++ b/src/plugins/coreplugin/coreplugin.cpp @@ -157,12 +157,11 @@ bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage) CheckableMessageBox::initialize(ICore::settings()); new ActionManager(this); ActionManager::setPresentationModeEnabled(args.presentationMode); - m_core = new ICore; if (args.overrideColor.isValid()) ICore::setOverrideColor(args.overrideColor); + m_core = new ICore; m_locator = new Locator; std::srand(unsigned(QDateTime::currentDateTime().toSecsSinceEpoch())); - ICore::init(); m_editMode = new EditMode; ModeManager::activateMode(m_editMode->id()); m_folderNavigationWidgetFactory = new FolderNavigationWidgetFactory; diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index 1c04ebd2b6d..45afbfafd4f 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -244,7 +244,7 @@ private: void mousePressEvent(QMouseEvent *event) override; }; -} // Internal +static QColor s_overrideColor; // The Core Singleton static ICore *m_core = nullptr; @@ -253,9 +253,6 @@ static NewDialog *defaultDialogFactory(QWidget *parent) { return new NewDialogWidget(parent); } - -namespace Internal { - class ICorePrivate : public QObject { public: @@ -344,7 +341,6 @@ public: QToolButton *m_toggleLeftSideBarButton = nullptr; QToolButton *m_toggleRightSideBarButton = nullptr; - QColor m_overrideColor; QList> m_preCloseListeners; }; @@ -412,6 +408,10 @@ ICore::ICore() }); Utils::FileUtils::setDialogParentGetter(&ICore::dialogParent); + + d->m_progressManager->init(); // needs the status bar manager + MessageManager::init(); + OutputPaneManager::create(); } /*! @@ -1103,7 +1103,7 @@ void ICore::saveSettings(SaveSettingsReason reason) QtcSettings *settings = PluginManager::settings(); settings->beginGroup(settingsGroup); - if (!(d->m_overrideColor.isValid() && StyleHelper::baseColor() == d->m_overrideColor)) + if (!(s_overrideColor.isValid() && StyleHelper::baseColor() == s_overrideColor)) settings->setValueWithDefault(colorKey, StyleHelper::requestedBaseColor(), QColor(StyleHelper::DEFAULT_BASE_COLOR)); @@ -1347,13 +1347,6 @@ ICorePrivate::~ICorePrivate() } // Internal -void ICore::init() -{ - d->m_progressManager->init(); // needs the status bar manager - MessageManager::init(); - OutputPaneManager::create(); -} - void ICore::extensionsInitialized() { EditorManagerPrivate::extensionsInitialized(); @@ -2232,10 +2225,10 @@ void ICorePrivate::readSettings() QtcSettings *settings = PluginManager::settings(); settings->beginGroup(settingsGroup); - if (m_overrideColor.isValid()) { - StyleHelper::setBaseColor(m_overrideColor); + if (s_overrideColor.isValid()) { + StyleHelper::setBaseColor(s_overrideColor); // Get adapted base color. - m_overrideColor = StyleHelper::baseColor(); + s_overrideColor = StyleHelper::baseColor(); } else { StyleHelper::setBaseColor(settings->value(colorKey, QColor(StyleHelper::DEFAULT_BASE_COLOR)).value()); @@ -2545,7 +2538,7 @@ void ICorePrivate::restoreWindowState() void ICore::setOverrideColor(const QColor &color) { - d->m_overrideColor = color; + s_overrideColor = color; } } // namespace Core From 790f7deb08221e3c2968469a9505878a234ae916 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 23 Oct 2023 22:41:47 +0200 Subject: [PATCH 0064/1546] TaskTree: Allow custom deleter for custom task This will enable employing ProcessReaper automatically for QProcess tasks. Change-Id: I54b1d4604a9dfb11698e23bd66cf94d34675f722 Reviewed-by: Qt CI Bot Reviewed-by: Marcus Tillmanns --- src/libs/solutions/tasking/tasktree.h | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 5e1226eb2c4..ac6146eace1 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -9,6 +9,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE template class QFuture; @@ -30,7 +32,7 @@ signals: void done(bool success); private: - template friend class TaskAdapter; + template friend class TaskAdapter; friend class TaskNode; TaskInterface() = default; #ifdef Q_QDOC @@ -302,26 +304,28 @@ private: }; }; -template +template > class TaskAdapter : public TaskInterface { protected: - using Type = Task; - TaskAdapter() = default; - Task *task() { return &m_task; } - const Task *task() const { return &m_task; } + TaskAdapter() : m_task(new Task) {} + Task *task() { return m_task.get(); } + const Task *task() const { return m_task.get(); } private: + using TaskType = Task; + using DeleterType = Deleter; template friend class CustomTask; - Task m_task; + std::unique_ptr m_task; }; template class CustomTask final : public GroupItem { public: - using Task = typename Adapter::Type; - static_assert(std::is_base_of_v, Adapter>, + using Task = typename Adapter::TaskType; + using Deleter = typename Adapter::DeleterType; + static_assert(std::is_base_of_v, Adapter>, "The Adapter type for the CustomTask needs to be derived from " "TaskAdapter."); using EndHandler = std::function; @@ -355,9 +359,9 @@ private: template static GroupItem::TaskSetupHandler wrapSetup(SetupHandler &&handler) { static constexpr bool isDynamic = std::is_same_v, typename Adapter::Type &>>; + std::invoke_result_t, typename Adapter::TaskType &>>; constexpr bool isVoid = std::is_same_v, typename Adapter::Type &>>; + std::invoke_result_t, typename Adapter::TaskType &>>; static_assert(isDynamic || isVoid, "Task setup handler needs to take (Task &) as an argument and has to return " "void or SetupResult. The passed handler doesn't fulfill these requirements."); From aef960a68c04d30634f556533e7352bb009313e1 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 31 Oct 2023 16:27:46 +0100 Subject: [PATCH 0065/1546] TaskTree: Get rid of the fluent interface It wasn't really used and it interferes when refactoring. Change-Id: I8b8ba1740fef24502855e896e9b33ba816e1229f Reviewed-by: Qt CI Bot Reviewed-by: Marcus Tillmanns --- src/libs/solutions/tasking/tasktree.cpp | 82 -------------------- src/libs/solutions/tasking/tasktree.h | 17 ---- tests/auto/solutions/tasking/tst_tasking.cpp | 16 ---- 3 files changed, 115 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 5dc743f1324..a8a2ad3615d 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -452,53 +452,6 @@ private: When the running task finishes, one of \a done or \a error handlers is called, depending on whether it finished with success or an error, respectively. Both handlers are of std::function type. - - \sa onSetup(), onDone(), onError() -*/ - -/*! - \fn template template CustomTask &CustomTask::onSetup(SetupHandler &&handler) - - Attaches the setup \a handler to \c this task. - The \a handler is invoked when the task is about to be started. - - This function enables defining the task's details with a - \l {https://en.wikipedia.org/wiki/Fluent_interface}{fluent interface} style: - - \code - const auto onQuerySetup = [](NetworkQuery &task) { ... }; - const auto onQueryError = [](const NetworkQuery &task) { ... }; - - const Group group { - NetworkQueryTask(onQuerySetup, {}, onQueryError), - NetworkQueryTask().onSetup(onQuerySetup).onError(onQueryError), // fluent interface style - NetworkQueryTask(onQuerySetup, {}, onQueryError).withTimeout(500ms) - } - \endcode - - \sa CustomTask(), onDone(), onError() -*/ - -/*! - \fn template CustomTask &CustomTask::onDone(const EndHandler &handler) - - Attaches the done \a handler to \c this task. - The handler is invoked when the task finishes with success. - - This function enables defining the task's details with a fluent interface style. - - \sa CustomTask(), onSetup(), onError() -*/ - -/*! - \fn template CustomTask &CustomTask::onError(const EndHandler &handler) - - Attaches the error \a handler to \c this task. - The handler is invoked when the task finishes with an error. - - This function enables defining the task's details with a fluent interface style. - - \sa CustomTask(), onSetup(), onDone() */ /*! @@ -511,8 +464,6 @@ private: the returned item finishes immediately with the task's result. Otherwise, the \a handler is invoked (if provided), the task is stopped, and the returned item finishes with an error. - - \sa onSetup() */ /*! @@ -1002,39 +953,6 @@ void GroupItem::addChildren(const QList &children) } } -void GroupItem::setTaskSetupHandler(const TaskSetupHandler &handler) -{ - if (!handler) { - qWarning("Setting empty Setup Handler is no-op, skipping..."); - return; - } - if (m_taskHandler.m_setupHandler) - qWarning("Setup Handler redefinition, overriding..."); - m_taskHandler.m_setupHandler = handler; -} - -void GroupItem::setTaskDoneHandler(const TaskEndHandler &handler) -{ - if (!handler) { - qWarning("Setting empty Done Handler is no-op, skipping..."); - return; - } - if (m_taskHandler.m_doneHandler) - qWarning("Done Handler redefinition, overriding..."); - m_taskHandler.m_doneHandler = handler; -} - -void GroupItem::setTaskErrorHandler(const TaskEndHandler &handler) -{ - if (!handler) { - qWarning("Setting empty Error Handler is no-op, skipping..."); - return; - } - if (m_taskHandler.m_errorHandler) - qWarning("Error Handler redefinition, overriding..."); - m_taskHandler.m_errorHandler = handler; -} - GroupItem GroupItem::withTimeout(const GroupItem &item, milliseconds timeout, const GroupEndHandler &handler) { diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index ac6146eace1..f3b84eb32c2 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -189,9 +189,6 @@ protected: , m_taskHandler(handler) {} void addChildren(const QList &children); - void setTaskSetupHandler(const TaskSetupHandler &handler); - void setTaskDoneHandler(const TaskEndHandler &handler); - void setTaskErrorHandler(const TaskEndHandler &handler); static GroupItem groupHandler(const GroupHandler &handler) { return GroupItem({handler}); } static GroupItem parallelLimit(int limit) { return GroupItem({{}, limit}); } static GroupItem workflowPolicy(WorkflowPolicy policy) { return GroupItem({{}, {}, policy}); } @@ -336,20 +333,6 @@ public: : GroupItem({&createAdapter, wrapSetup(std::forward(setup)), wrapEnd(done), wrapEnd(error)}) {} - template - CustomTask &onSetup(SetupHandler &&handler) { - setTaskSetupHandler(wrapSetup(std::forward(handler))); - return *this; - } - CustomTask &onDone(const EndHandler &handler) { - setTaskDoneHandler(wrapEnd(handler)); - return *this; - } - CustomTask &onError(const EndHandler &handler) { - setTaskErrorHandler(wrapEnd(handler)); - return *this; - } - GroupItem withTimeout(std::chrono::milliseconds timeout, const GroupEndHandler &handler = {}) const { return GroupItem::withTimeout(*this, timeout, handler); diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index cd476670c8f..08161020528 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -114,8 +114,6 @@ void tst_Tasking::validConstructs() const auto doneHandler = [](const TaskObject &) {}; const auto errorHandler = [](const TaskObject &) {}; - // Not fluent interface - const Group task2 { parallel, TestTask(setupHandler), @@ -125,20 +123,6 @@ void tst_Tasking::validConstructs() TestTask(setupHandler, {}, errorHandler) }; - // Fluent interface - - const Group fluent { - parallel, - TestTask().onSetup(setupHandler), - TestTask().onSetup(setupHandler).onDone(doneHandler), - TestTask().onSetup(setupHandler).onDone(doneHandler).onError(errorHandler), - // possible to skip the empty done - TestTask().onSetup(setupHandler).onError(errorHandler), - // possible to set handlers in a different order - TestTask().onError(errorHandler).onDone(doneHandler).onSetup(setupHandler), - }; - - // When turning each of below blocks on, you should see the specific compiler error message. #if 0 From 09c4aad0ebf859cfadbb1b7019096c1cafed9129 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 31 Oct 2023 16:30:12 +0100 Subject: [PATCH 0066/1546] TaskTree: Keep just one done handler Instead of having separate handlers for done and errorOccurred. This will enable setting just one common done handler with an additional "bool success" argument. Task-number: QTCREATORBUG-29834 Change-Id: I52d826dd89461ff93772a6fe7a85e432d1e84665 Reviewed-by: Qt CI Bot Reviewed-by: Marcus Tillmanns --- src/libs/solutions/tasking/tasktree.cpp | 14 ++++++-------- src/libs/solutions/tasking/tasktree.h | 19 ++++++++++--------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index a8a2ad3615d..c8347af1bb8 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -1089,7 +1089,7 @@ public: // in order to unwind properly. SetupResult start(); void stop(); - void invokeEndHandler(bool success); + void invokeDoneHandler(bool success); bool isRunning() const { return m_task || m_container.isRunning(); } bool isTask() const { return bool(m_taskHandler.m_createHandler); } int taskCount() const { return isTask() ? 1 : m_container.m_constData.m_taskCount; } @@ -1451,7 +1451,7 @@ SetupResult TaskNode::start() const std::shared_ptr unwindAction = std::make_shared(SetupResult::Continue); QObject::connect(m_task.get(), &TaskInterface::done, taskTree(), [=](bool success) { - invokeEndHandler(success); + invokeDoneHandler(success); QObject::disconnect(m_task.get(), &TaskInterface::done, taskTree(), nullptr); m_task.release()->deleteLater(); QTC_ASSERT(parentContainer() && parentContainer()->isRunning(), return); @@ -1479,16 +1479,14 @@ void TaskNode::stop() // TODO: cancelHandler? // TODO: call TaskInterface::stop() ? - invokeEndHandler(false); + invokeDoneHandler(false); m_task.reset(); } -void TaskNode::invokeEndHandler(bool success) +void TaskNode::invokeDoneHandler(bool success) { - if (success && m_taskHandler.m_doneHandler) - invokeHandler(parentContainer(), m_taskHandler.m_doneHandler, *m_task.get()); - else if (!success && m_taskHandler.m_errorHandler) - invokeHandler(parentContainer(), m_taskHandler.m_errorHandler, *m_task.get()); + if (m_taskHandler.m_doneHandler) + invokeHandler(parentContainer(), m_taskHandler.m_doneHandler, *m_task.get(), success); m_container.m_constData.m_taskTreePrivate->advanceProgress(1); } diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index f3b84eb32c2..c6704463e3f 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -138,8 +138,8 @@ public: using TaskCreateHandler = std::function; // Called prior to task start, just after createHandler using TaskSetupHandler = std::function; - // Called on task done / error - using TaskEndHandler = std::function; + // Called on task done, just before delete later + using TaskDoneHandler = std::function; // Called when group entered using GroupSetupHandler = std::function; // Called when group done / error @@ -148,8 +148,7 @@ public: struct TaskHandler { TaskCreateHandler m_createHandler; TaskSetupHandler m_setupHandler = {}; - TaskEndHandler m_doneHandler = {}; - TaskEndHandler m_errorHandler = {}; + TaskDoneHandler m_doneHandler = {}; }; struct GroupHandler { @@ -331,7 +330,7 @@ public: template CustomTask(SetupHandler &&setup, const EndHandler &done = {}, const EndHandler &error = {}) : GroupItem({&createAdapter, wrapSetup(std::forward(setup)), - wrapEnd(done), wrapEnd(error)}) {} + wrapEnds(done, error)}) {} GroupItem withTimeout(std::chrono::milliseconds timeout, const GroupEndHandler &handler = {}) const { @@ -357,12 +356,14 @@ private: }; }; - static TaskEndHandler wrapEnd(const EndHandler &handler) { - if (!handler) + static TaskDoneHandler wrapEnds(const EndHandler &doneHandler, const EndHandler &errorHandler) { + if (!doneHandler && !errorHandler) return {}; - return [handler](const TaskInterface &taskInterface) { + return [doneHandler, errorHandler](const TaskInterface &taskInterface, bool success) { const Adapter &adapter = static_cast(taskInterface); - handler(*adapter.task()); + const auto handler = success ? doneHandler : errorHandler; + if (handler) + handler(*adapter.task()); }; }; }; From d35d0b5100746baa15f413ab6cb500c75dc2f2aa Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 31 Oct 2023 17:03:48 +0100 Subject: [PATCH 0067/1546] TaskTree: Add Task c'tor taking one handler for done and error The overloaded c'tor takes one done handler with an additional "bool success" argument. Task-number: QTCREATORBUG-29834 Change-Id: Id579d055721a2a07a5a9f0900aa4a73655f21610 Reviewed-by: Qt CI Bot Reviewed-by: Marcus Tillmanns --- src/libs/solutions/tasking/tasktree.h | 15 +++++++++ src/plugins/diffeditor/diffeditorplugin.cpp | 26 +++++++-------- src/plugins/git/gitclient.cpp | 20 +++++------ tests/auto/solutions/tasking/tst_tasking.cpp | 35 +++++++++----------- 4 files changed, 51 insertions(+), 45 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index c6704463e3f..5b94cfc3099 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -324,6 +324,7 @@ public: static_assert(std::is_base_of_v, Adapter>, "The Adapter type for the CustomTask needs to be derived from " "TaskAdapter."); + using DoneHandler = std::function; using EndHandler = std::function; static Adapter *createAdapter() { return new Adapter; } CustomTask() : GroupItem({&createAdapter}) {} @@ -332,6 +333,11 @@ public: : GroupItem({&createAdapter, wrapSetup(std::forward(setup)), wrapEnds(done, error)}) {} + template + CustomTask(SetupHandler &&setup, const DoneHandler &done) + : GroupItem({&createAdapter, wrapSetup(std::forward(setup)), wrapDone(done)}) + {} + GroupItem withTimeout(std::chrono::milliseconds timeout, const GroupEndHandler &handler = {}) const { return GroupItem::withTimeout(*this, timeout, handler); @@ -366,6 +372,15 @@ private: handler(*adapter.task()); }; }; + + static TaskDoneHandler wrapDone(const DoneHandler &handler) { + if (!handler) + return {}; + return [handler](const TaskInterface &taskInterface, bool success) { + const Adapter &adapter = static_cast(taskInterface); + handler(*adapter.task(), success); + }; + }; }; class TaskTreePrivate; diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp index 3112170bc41..bb2cf4e24dd 100644 --- a/src/plugins/diffeditor/diffeditorplugin.cpp +++ b/src/plugins/diffeditor/diffeditorplugin.cpp @@ -113,24 +113,22 @@ DiffFilesController::DiffFilesController(IDocument *document) const auto setupTree = [this, storage](TaskTree &taskTree) { QList> *outputList = storage.activeStorage(); - const auto setupDiff = [this](Async &async, const ReloadInput &reloadInput) { - async.setConcurrentCallData( - DiffFile(ignoreWhitespace(), contextLineCount()), reloadInput); - async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); - }; - const auto onDiffDone = [outputList](const Async &async, int i) { - if (async.isResultAvailable()) - (*outputList)[i] = async.result(); - }; - const QList inputList = reloadInputList(); outputList->resize(inputList.size()); - using namespace std::placeholders; - QList tasks {parallel, finishAllAndDone}; + QList tasks { parallel, finishAllAndDone }; for (int i = 0; i < inputList.size(); ++i) { - tasks.append(AsyncTask(std::bind(setupDiff, _1, inputList.at(i)), - std::bind(onDiffDone, _1, i))); + const auto setupDiff = [this, reloadInput = inputList.at(i)](Async &async) { + async.setConcurrentCallData( + DiffFile(ignoreWhitespace(), contextLineCount()), reloadInput); + async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); + }; + + const auto onDiffDone = [outputList, i](const Async &async) { + if (async.isResultAvailable()) + (*outputList)[i] = async.result(); + }; + tasks.append(AsyncTask(setupDiff, onDiffDone)); } taskTree.setRecipe(tasks); }; diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 532d0a6ef82..f05b66cfc10 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -497,23 +497,21 @@ ShowController::ShowController(IDocument *document, const QString &id) data->m_follows = {busyMessage}; data->m_follows.resize(parents.size()); - const auto setupFollow = [this](Process &process, const QString &parent) { - setupCommand(process, {"describe", "--tags", "--abbrev=0", parent}); - }; - const auto onFollowDone = [data, updateDescription](const Process &process, int index) { - data->m_follows[index] = process.cleanedStdOut().trimmed(); - updateDescription(*data); - }; const auto onFollowsError = [data, updateDescription] { data->m_follows.clear(); updateDescription(*data); }; - using namespace std::placeholders; - QList tasks {parallel, continueOnDone, onGroupError(onFollowsError)}; + QList tasks { parallel, continueOnDone, onGroupError(onFollowsError) }; for (int i = 0, total = parents.size(); i < total; ++i) { - tasks.append(ProcessTask(std::bind(setupFollow, _1, parents.at(i)), - std::bind(onFollowDone, _1, i))); + const auto setupFollow = [this, parent = parents.at(i)](Process &process) { + setupCommand(process, {"describe", "--tags", "--abbrev=0", parent}); + }; + const auto onFollowDone = [data, updateDescription, i](const Process &process) { + data->m_follows[i] = process.cleanedStdOut().trimmed(); + updateDescription(*data); + }; + tasks.append(ProcessTask(setupFollow, onFollowDone)); } taskTree.setRecipe(tasks); }; diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index 08161020528..72927b68d47 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -111,14 +111,16 @@ void tst_Tasking::validConstructs() }; const auto setupHandler = [](TaskObject &) {}; - const auto doneHandler = [](const TaskObject &) {}; + const auto finishHandler = [](const TaskObject &) {}; const auto errorHandler = [](const TaskObject &) {}; + const auto doneHandler = [](const TaskObject &, bool) {}; const Group task2 { parallel, TestTask(setupHandler), + TestTask(setupHandler, finishHandler), + TestTask(setupHandler, finishHandler, errorHandler), TestTask(setupHandler, doneHandler), - TestTask(setupHandler, doneHandler, errorHandler), // need to explicitly pass empty handler for done TestTask(setupHandler, {}, errorHandler) }; @@ -220,14 +222,8 @@ void tst_Tasking::testTree_data() }; const auto setupDone = [storage](int taskId) { - return [storage, taskId](const TaskObject &) { - storage->m_log.append({taskId, Handler::Done}); - }; - }; - - const auto setupError = [storage](int taskId) { - return [storage, taskId](const TaskObject &) { - storage->m_log.append({taskId, Handler::Error}); + return [storage, taskId](const TaskObject &, bool success) { + storage->m_log.append({taskId, success ? Handler::Done : Handler::Error}); }; }; @@ -237,14 +233,13 @@ void tst_Tasking::testTree_data() }; }; - const auto createTask = [storage, setupTask, setupDone, setupError]( + const auto createTask = [storage, setupTask, setupDone]( int taskId, bool successTask, milliseconds timeout = 0ms) -> GroupItem { if (successTask) - return TestTask(setupTask(taskId, timeout), setupDone(taskId), setupError(taskId)); + return TestTask(setupTask(taskId, timeout), setupDone(taskId)); const Group root { finishAllAndError, TestTask(setupTask(taskId, timeout)), - onGroupDone([storage, taskId] { storage->m_log.append({taskId, Handler::Done}); }), onGroupError([storage, taskId] { storage->m_log.append({taskId, Handler::Error}); }) }; return root; @@ -258,9 +253,9 @@ void tst_Tasking::testTree_data() return createTask(taskId, false, timeout); }; - const auto createDynamicTask = [storage, setupDynamicTask, setupDone, setupError]( - int taskId, SetupResult action) { - return TestTask(setupDynamicTask(taskId, action), setupDone(taskId), setupError(taskId)); + const auto createDynamicTask = [storage, setupDynamicTask, setupDone](int taskId, + SetupResult action) { + return TestTask(setupDynamicTask(taskId, action), setupDone(taskId)); }; const auto groupSetup = [storage](int taskId) { @@ -2121,7 +2116,7 @@ void tst_Tasking::testTree_data() // 2. With and without timeout handler. const Group root1 { Storage(storage), - TestTask(setupTask(1, 1000ms), setupDone(1), setupError(1)) + TestTask(setupTask(1, 1000ms), setupDone(1)) .withTimeout(1ms) }; const Log log1 { @@ -2133,7 +2128,7 @@ void tst_Tasking::testTree_data() const Group root2 { Storage(storage), - TestTask(setupTask(1, 1000ms), setupDone(1), setupError(1)) + TestTask(setupTask(1, 1000ms), setupDone(1)) .withTimeout(1ms, setupTimeout(1)) }; const Log log2 { @@ -2146,7 +2141,7 @@ void tst_Tasking::testTree_data() const Group root3 { Storage(storage), - TestTask(setupTask(1, 1ms), setupDone(1), setupError(1)) + TestTask(setupTask(1, 1ms), setupDone(1)) .withTimeout(1000ms) }; const Log doneLog { @@ -2158,7 +2153,7 @@ void tst_Tasking::testTree_data() const Group root4 { Storage(storage), - TestTask(setupTask(1, 1ms), setupDone(1), setupError(1)) + TestTask(setupTask(1, 1ms), setupDone(1)) .withTimeout(1000ms, setupTimeout(1)) }; QTest::newRow("TaskDoneWithTimeoutHandler") << TestData{storage, root4, doneLog, 2, From 60591642995477c099728d2ecf7d5d2533e642aa Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 2 Nov 2023 15:29:16 +0100 Subject: [PATCH 0068/1546] TaskTree: Make setup handler optional Change-Id: Idfcaaf5cc5f69895d8cf9bf6e4ee673e524b61fe Reviewed-by: Qt CI Bot Reviewed-by: Marcus Tillmanns Reviewed-by: --- src/libs/solutions/tasking/tasktree.cpp | 4 ++-- src/libs/solutions/tasking/tasktree.h | 17 ++++++++++------- tests/auto/solutions/tasking/tst_tasking.cpp | 6 +++++- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index c8347af1bb8..348481c8fc9 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -956,8 +956,8 @@ void GroupItem::addChildren(const QList &children) GroupItem GroupItem::withTimeout(const GroupItem &item, milliseconds timeout, const GroupEndHandler &handler) { - const TimeoutTask::EndHandler taskHandler = handler - ? [handler](const milliseconds &) { handler(); } : TimeoutTask::EndHandler(); + const TimeoutTask::EndFunction taskHandler = handler + ? [handler](const milliseconds &) { handler(); } : TimeoutTask::EndFunction(); return Group { parallel, stopOnFinished, diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 5b94cfc3099..99edad20272 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -324,17 +324,18 @@ public: static_assert(std::is_base_of_v, Adapter>, "The Adapter type for the CustomTask needs to be derived from " "TaskAdapter."); - using DoneHandler = std::function; - using EndHandler = std::function; + using SetupFunction = std::function; + using DoneFunction = std::function; + using EndFunction = std::function; static Adapter *createAdapter() { return new Adapter; } CustomTask() : GroupItem({&createAdapter}) {} - template - CustomTask(SetupHandler &&setup, const EndHandler &done = {}, const EndHandler &error = {}) + template + CustomTask(SetupHandler &&setup, const EndFunction &done = {}, const EndFunction &error = {}) : GroupItem({&createAdapter, wrapSetup(std::forward(setup)), wrapEnds(done, error)}) {} template - CustomTask(SetupHandler &&setup, const DoneHandler &done) + CustomTask(SetupHandler &&setup, const DoneFunction &done) : GroupItem({&createAdapter, wrapSetup(std::forward(setup)), wrapDone(done)}) {} @@ -346,6 +347,8 @@ public: private: template static GroupItem::TaskSetupHandler wrapSetup(SetupHandler &&handler) { + if constexpr (std::is_same_v>) + return {}; // When user passed {} for setup handler. static constexpr bool isDynamic = std::is_same_v, typename Adapter::TaskType &>>; constexpr bool isVoid = std::is_same_v Date: Tue, 31 Oct 2023 17:55:22 +0100 Subject: [PATCH 0069/1546] VcsBase: Use common done handler Instead of specifying two separate done and error handlers, specify just one that takes additional "bool success" argument. Task-number: QTCREATORBUG-29834 Change-Id: Ib92ef2dcd960372d9db6c8f50d4017a33c49ccd3 Reviewed-by: Marcus Tillmanns --- src/plugins/git/branchmodel.cpp | 27 ++--- src/plugins/git/gitclient.cpp | 104 +++++++++--------- src/plugins/subversion/subversionclient.cpp | 15 +-- .../vcsbase/vcsbasediffeditorcontroller.cpp | 11 +- 4 files changed, 74 insertions(+), 83 deletions(-) diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp index 3bae1a991f6..b7b1355cf4e 100644 --- a/src/plugins/git/branchmodel.cpp +++ b/src/plugins/git/branchmodel.cpp @@ -416,7 +416,7 @@ void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError) d->currentDateTime = dateTime; }); - const auto setupForEachRef = [this, workingDirectory](Process &process) { + const auto onForEachRefSetup = [this, workingDirectory](Process &process) { d->workingDirectory = workingDirectory; QStringList args = {"for-each-ref", "--format=%(objectname)\t%(refname)\t%(upstream:short)\t" @@ -428,7 +428,18 @@ void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError) gitClient().setupCommand(process, workingDirectory, args); }; - const auto forEachRefDone = [this](const Process &process) { + const auto onForEachRefDone = [this, workingDirectory, showError](const Process &process, + bool success) { + if (!success) { + if (showError == ShowError::No) + return; + const QString message = Tr::tr("Cannot run \"%1\" in \"%2\": %3") + .arg("git for-each-ref") + .arg(workingDirectory.toUserOutput()) + .arg(process.cleanedStdErr()); + VcsBase::VcsOutputWindow::appendError(message); + return; + } const QString output = process.stdOut(); const QStringList lines = output.split('\n'); for (const QString &l : lines) @@ -449,16 +460,6 @@ void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError) } }; - const auto forEachRefError = [workingDirectory, showError](const Process &process) { - if (showError == ShowError::No) - return; - const QString message = Tr::tr("Cannot run \"%1\" in \"%2\": %3") - .arg("git for-each-ref") - .arg(workingDirectory.toUserOutput()) - .arg(process.cleanedStdErr()); - VcsBase::VcsOutputWindow::appendError(message); - }; - const auto finalize = [this] { endResetModel(); d->refreshTask.release()->deleteLater(); @@ -466,7 +467,7 @@ void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError) const Group root { topRevisionProc, - ProcessTask(setupForEachRef, forEachRefDone, forEachRefError), + ProcessTask(onForEachRefSetup, onForEachRefDone), onGroupDone(finalize), onGroupError(finalize) }; diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index f05b66cfc10..91adbfad075 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -391,7 +391,7 @@ ShowController::ShowController(IDocument *document, const QString &id) setDescription(desc); }; - const auto setupDescription = [this, id](Process &process) { + const auto onDescriptionSetup = [this, id](Process &process) { process.setCodec(gitClient().encoding(GitClient::EncodingCommit, workingDirectory())); setupCommand(process, {"show", "-s", noColorOption, showFormatC, id}); VcsOutputWindow::appendCommand(process.workingDirectory(), process.commandLine()); @@ -418,72 +418,68 @@ ShowController::ShowController(IDocument *document, const QString &id) return SetupResult::Continue; }; - const auto setupBranches = [this, storage](Process &process) { + const auto onBranchesSetup = [this, storage](Process &process) { storage->m_branches = busyMessage; setupCommand(process, {"branch", noColorOption, "-a", "--contains", storage->m_commit}); VcsOutputWindow::appendCommand(process.workingDirectory(), process.commandLine()); }; - const auto onBranchesDone = [storage, updateDescription](const Process &process) { + const auto onBranchesDone = [storage, updateDescription](const Process &process, bool success) { ReloadStorage *data = storage.activeStorage(); data->m_branches.clear(); - const QString remotePrefix = "remotes/"; - const QString localPrefix = ""; - const int prefixLength = remotePrefix.length(); - QStringList branches; - QString previousRemote = localPrefix; - bool first = true; - const QStringList branchList = process.cleanedStdOut().split('\n'); - for (const QString &branch : branchList) { - const QString b = branch.mid(2).trimmed(); - if (b.isEmpty()) - continue; - if (b.startsWith(remotePrefix)) { - const int nextSlash = b.indexOf('/', prefixLength); - if (nextSlash < 0) + if (success) { + const QString remotePrefix = "remotes/"; + const QString localPrefix = ""; + const int prefixLength = remotePrefix.length(); + QStringList branches; + QString previousRemote = localPrefix; + bool first = true; + const QStringList branchList = process.cleanedStdOut().split('\n'); + for (const QString &branch : branchList) { + const QString b = branch.mid(2).trimmed(); + if (b.isEmpty()) continue; - const QString remote = b.mid(prefixLength, nextSlash - prefixLength); - if (remote != previousRemote) { - data->m_branches += branchesDisplay(previousRemote, &branches, &first) + '\n'; - branches.clear(); - previousRemote = remote; + if (b.startsWith(remotePrefix)) { + const int nextSlash = b.indexOf('/', prefixLength); + if (nextSlash < 0) + continue; + const QString remote = b.mid(prefixLength, nextSlash - prefixLength); + if (remote != previousRemote) { + data->m_branches += branchesDisplay(previousRemote, &branches, &first) + + '\n'; + branches.clear(); + previousRemote = remote; + } + branches << b.mid(nextSlash + 1); + } else { + branches << b; } - branches << b.mid(nextSlash + 1); - } else { - branches << b; } + if (branches.isEmpty()) { + if (previousRemote == localPrefix) + data->m_branches += Tr::tr(""); + } else { + data->m_branches += branchesDisplay(previousRemote, &branches, &first); + } + data->m_branches = data->m_branches.trimmed(); } - if (branches.isEmpty()) { - if (previousRemote == localPrefix) - data->m_branches += Tr::tr(""); - } else { - data->m_branches += branchesDisplay(previousRemote, &branches, &first); - } - data->m_branches = data->m_branches.trimmed(); - updateDescription(*data); - }; - const auto onBranchesError = [storage, updateDescription](const Process &) { - ReloadStorage *data = storage.activeStorage(); - data->m_branches.clear(); updateDescription(*data); }; - const auto setupPrecedes = [this, storage](Process &process) { + const auto onPrecedesSetup = [this, storage](Process &process) { storage->m_precedes = busyMessage; setupCommand(process, {"describe", "--contains", storage->m_commit}); }; - const auto onPrecedesDone = [storage, updateDescription](const Process &process) { - ReloadStorage *data = storage.activeStorage(); - data->m_precedes = process.cleanedStdOut().trimmed(); - const int tilde = data->m_precedes.indexOf('~'); - if (tilde != -1) - data->m_precedes.truncate(tilde); - if (data->m_precedes.endsWith("^0")) - data->m_precedes.chop(2); - updateDescription(*data); - }; - const auto onPrecedesError = [storage, updateDescription](const Process &) { + const auto onPrecedesDone = [storage, updateDescription](const Process &process, bool success) { ReloadStorage *data = storage.activeStorage(); data->m_precedes.clear(); + if (success) { + data->m_precedes = process.cleanedStdOut().trimmed(); + const int tilde = data->m_precedes.indexOf('~'); + if (tilde != -1) + data->m_precedes.truncate(tilde); + if (data->m_precedes.endsWith("^0")) + data->m_precedes.chop(2); + } updateDescription(*data); }; @@ -516,7 +512,7 @@ ShowController::ShowController(IDocument *document, const QString &id) taskTree.setRecipe(tasks); }; - const auto setupDiff = [this, id](Process &process) { + const auto onDiffSetup = [this, id](Process &process) { setupCommand(process, addConfigurationArguments( {"show", "--format=format:", // omit header, already generated noColorOption, decorateOption, id})); @@ -533,18 +529,18 @@ ShowController::ShowController(IDocument *document, const QString &id) onGroupSetup([this] { setStartupFile(VcsBase::source(this->document()).toString()); }), Group { finishAllAndDone, - ProcessTask(setupDescription, onDescriptionDone), + ProcessTask(onDescriptionSetup, onDescriptionDone), Group { parallel, finishAllAndDone, onGroupSetup(desciptionDetailsSetup), - ProcessTask(setupBranches, onBranchesDone, onBranchesError), - ProcessTask(setupPrecedes, onPrecedesDone, onPrecedesError), + ProcessTask(onBranchesSetup, onBranchesDone), + ProcessTask(onPrecedesSetup, onPrecedesDone), TaskTreeTask(setupFollows) } }, Group { - ProcessTask(setupDiff, onDiffDone), + ProcessTask(onDiffSetup, onDiffDone), postProcessTask(diffInputStorage) } }; diff --git a/src/plugins/subversion/subversionclient.cpp b/src/plugins/subversion/subversionclient.cpp index 98f0cfdde90..75231c21e51 100644 --- a/src/plugins/subversion/subversionclient.cpp +++ b/src/plugins/subversion/subversionclient.cpp @@ -165,7 +165,7 @@ SubversionDiffEditorController::SubversionDiffEditorController(IDocument *docume const TreeStorage diffInputStorage; - const auto setupDescription = [this](Process &process) { + const auto onDescriptionSetup = [this](Process &process) { if (m_changeNumber == 0) return SetupResult::StopWithDone; setupCommand(process, {"log", "-r", QString::number(m_changeNumber)}); @@ -175,14 +175,11 @@ SubversionDiffEditorController::SubversionDiffEditorController(IDocument *docume setDescription(Tr::tr("Waiting for data...")); return SetupResult::Continue; }; - const auto onDescriptionDone = [this](const Process &process) { - setDescription(process.cleanedStdOut()); - }; - const auto onDescriptionError = [this](const Process &) { - setDescription({}); + const auto onDescriptionDone = [this](const Process &process, bool success) { + setDescription(success ? process.cleanedStdOut() : QString()); }; - const auto setupDiff = [this](Process &process) { + const auto onDiffSetup = [this](Process &process) { QStringList args = QStringList{"diff"} << "--internal-diff"; if (ignoreWhitespace()) args << "-x" << "-uw"; @@ -205,10 +202,10 @@ SubversionDiffEditorController::SubversionDiffEditorController(IDocument *docume parallel, Group { finishAllAndDone, - ProcessTask(setupDescription, onDescriptionDone, onDescriptionError) + ProcessTask(onDescriptionSetup, onDescriptionDone) }, Group { - ProcessTask(setupDiff, onDiffDone), + ProcessTask(onDiffSetup, onDiffDone), postProcessTask(diffInputStorage) } }; diff --git a/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp b/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp index f7372fcd074..0a4c915608f 100644 --- a/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp +++ b/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp @@ -40,18 +40,15 @@ VcsBaseDiffEditorController::~VcsBaseDiffEditorController() GroupItem VcsBaseDiffEditorController::postProcessTask(const TreeStorage &inputStorage) { - const auto setupDiffProcessor = [inputStorage](Async> &async) { + const auto onSetup = [inputStorage](Async> &async) { async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); async.setConcurrentCallData(&DiffUtils::readPatchWithPromise, *inputStorage); }; - const auto onDiffProcessorDone = [this](const Async> &async) { - setDiffFiles(async.isResultAvailable() ? async.result() : QList()); + const auto onDone = [this](const Async> &async, bool success) { + setDiffFiles(success && async.isResultAvailable() ? async.result() : QList()); // TODO: We should set the right starting line here }; - const auto onDiffProcessorError = [this](const Async> &) { - setDiffFiles({}); - }; - return AsyncTask>(setupDiffProcessor, onDiffProcessorDone, onDiffProcessorError); + return AsyncTask>(onSetup, onDone); } void VcsBaseDiffEditorController::setupCommand(Process &process, const QStringList &args) const From 0fa16f8489fd627a388011bbdc36d2278455a25c Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 2 Nov 2023 16:14:50 +0100 Subject: [PATCH 0070/1546] TaskTree: Use common done handler Instead of specifying two separate done and error handlers, specify just one that takes additional "bool success" argument. Task-number: QTCREATORBUG-29834 Change-Id: Ie4f92236a38b03dac3dd33b2c80a317b62772a12 Reviewed-by: Marcus Tillmanns Reviewed-by: Qt CI Bot Reviewed-by: --- src/libs/utils/filestreamer.cpp | 22 ++--- src/plugins/android/androidsdkdownloader.cpp | 27 +++-- src/plugins/autotest/testrunner.cpp | 4 +- src/plugins/boot2qt/qdbmakedefaultappstep.cpp | 13 ++- .../boot2qt/qdbstopapplicationstep.cpp | 13 +-- src/plugins/clangtools/clangtoolrunner.cpp | 40 +++----- .../coreplugin/locator/ilocatorfilter.cpp | 5 +- .../coreplugin/locator/javascriptfilter.cpp | 15 +-- .../projectexplorer/abstractprocessstep.cpp | 4 +- src/plugins/projectexplorer/copystep.cpp | 12 +-- src/plugins/qmakeprojectmanager/qmakestep.cpp | 10 +- .../qnx/qnxdeployqtlibrariesdialog.cpp | 26 ++--- src/plugins/qnx/qnxdevicetester.cpp | 13 +-- src/plugins/qnx/slog2inforunner.cpp | 25 ++--- .../remotelinux/customcommanddeploystep.cpp | 13 ++- .../remotelinux/genericdirectuploadstep.cpp | 6 +- src/plugins/remotelinux/killappstep.cpp | 15 ++- src/plugins/remotelinux/linuxdevicetester.cpp | 98 ++++++++++--------- .../remotelinux/tarpackagecreationstep.cpp | 11 ++- .../remotelinux/tarpackagedeploystep.cpp | 30 +++--- .../tasking/imagescaling/imagescaling.cpp | 24 ++--- 21 files changed, 209 insertions(+), 217 deletions(-) diff --git a/src/libs/utils/filestreamer.cpp b/src/libs/utils/filestreamer.cpp index 24587563019..c85fe9e4801 100644 --- a/src/libs/utils/filestreamer.cpp +++ b/src/libs/utils/filestreamer.cpp @@ -252,7 +252,7 @@ signals: private: GroupItem remoteTask() final { - const auto setup = [this](Process &process) { + const auto onSetup = [this](Process &process) { m_writeBuffer = new WriteBuffer(false, &process); connect(m_writeBuffer, &WriteBuffer::writeRequested, &process, &Process::writeRaw); connect(m_writeBuffer, &WriteBuffer::closeWriteChannelRequested, @@ -266,23 +266,23 @@ private: process.setWriteData(m_writeData); connect(&process, &Process::started, this, [this] { emit started(); }); }; - const auto finalize = [this](const Process &) { + const auto onDone = [this](const Process &, bool) { delete m_writeBuffer; m_writeBuffer = nullptr; }; - return ProcessTask(setup, finalize, finalize); + return ProcessTask(onSetup, onDone); } GroupItem localTask() final { - const auto setup = [this](Async &async) { + const auto onSetup = [this](Async &async) { m_writeBuffer = new WriteBuffer(isBuffered(), &async); async.setConcurrentCallData(localWrite, m_filePath, m_writeData, m_writeBuffer); emit started(); }; - const auto finalize = [this](const Async &) { + const auto onDone = [this](const Async &, bool) { delete m_writeBuffer; m_writeBuffer = nullptr; }; - return AsyncTask(setup, finalize, finalize); + return AsyncTask(onSetup, onDone); } bool isBuffered() const { return m_writeData.isEmpty(); } @@ -327,17 +327,17 @@ static Group interDeviceTransferTask(const FilePath &source, const FilePath &des SingleBarrier writerReadyBarrier; TreeStorage storage; - const auto setupReader = [=](FileStreamReader &reader) { + const auto onReaderSetup = [=](FileStreamReader &reader) { reader.setFilePath(source); QTC_CHECK(storage->writer != nullptr); QObject::connect(&reader, &FileStreamReader::readyRead, storage->writer, &FileStreamWriter::write); }; - const auto finalizeReader = [=](const FileStreamReader &) { + const auto onReaderDone = [=](const FileStreamReader &, bool) { if (storage->writer) // writer may be deleted before the reader on TaskTree::stop(). storage->writer->closeWriteChannel(); }; - const auto setupWriter = [=](FileStreamWriter &writer) { + const auto onWriterSetup = [=](FileStreamWriter &writer) { writer.setFilePath(destination); QObject::connect(&writer, &FileStreamWriter::started, writerReadyBarrier->barrier(), &Barrier::advance); @@ -349,10 +349,10 @@ static Group interDeviceTransferTask(const FilePath &source, const FilePath &des Storage(writerReadyBarrier), parallel, Storage(storage), - FileStreamWriterTask(setupWriter), + FileStreamWriterTask(onWriterSetup), Group { waitForBarrierTask(writerReadyBarrier), - FileStreamReaderTask(setupReader, finalizeReader, finalizeReader) + FileStreamReaderTask(onReaderSetup, onReaderDone) } }; diff --git a/src/plugins/android/androidsdkdownloader.cpp b/src/plugins/android/androidsdkdownloader.cpp index 20d89436a7c..89e6d6f267b 100644 --- a/src/plugins/android/androidsdkdownloader.cpp +++ b/src/plugins/android/androidsdkdownloader.cpp @@ -130,10 +130,15 @@ void AndroidSdkDownloader::downloadAndExtractSdk() #endif }); }; - const auto onQueryDone = [this, storage](const NetworkQuery &query) { + const auto onQueryDone = [this, storage](const NetworkQuery &query, bool success) { QNetworkReply *reply = query.reply(); QTC_ASSERT(reply, return); const QUrl url = reply->url(); + if (!success) { + logError(Tr::tr("Downloading Android SDK Tools from URL %1 has failed: %2.") + .arg(url.toString(), reply->errorString())); + return; + } if (isHttpRedirect(reply)) { logError(Tr::tr("Download from %1 was redirected.").arg(url.toString())); return; @@ -146,13 +151,6 @@ void AndroidSdkDownloader::downloadAndExtractSdk() } *storage = sdkFileName; }; - const auto onQueryError = [this](const NetworkQuery &query) { - QNetworkReply *reply = query.reply(); - QTC_ASSERT(reply, return); - const QUrl url = reply->url(); - logError(Tr::tr("Downloading Android SDK Tools from URL %1 has failed: %2.") - .arg(url.toString(), reply->errorString())); - }; const auto onUnarchiveSetup = [this, storage](Unarchiver &unarchiver) { m_progressDialog->setRange(0, 0); @@ -173,19 +171,20 @@ void AndroidSdkDownloader::downloadAndExtractSdk() unarchiver.setDestDir(sdkFileName.parentDir()); return SetupResult::Continue; }; - const auto onUnarchiverDone = [this, storage](const Unarchiver &) { + const auto onUnarchiverDone = [this, storage](const Unarchiver &, bool success) { + if (!success) { + logError(Tr::tr("Unarchiving error.")); + return; + } m_androidConfig.setTemporarySdkToolsPath( (*storage)->parentDir().pathAppended(Constants::cmdlineToolsName)); QMetaObject::invokeMethod(this, [this] { emit sdkExtracted(); }, Qt::QueuedConnection); }; - const auto onUnarchiverError = [this](const Unarchiver &) { - logError(Tr::tr("Unarchiving error.")); - }; const Group root { Tasking::Storage(storage), - NetworkQueryTask(onQuerySetup, onQueryDone, onQueryError), - UnarchiverTask(onUnarchiveSetup, onUnarchiverDone, onUnarchiverError) + NetworkQueryTask(onQuerySetup, onQueryDone), + UnarchiverTask(onUnarchiveSetup, onUnarchiverDone) }; m_taskTree.reset(new TaskTree(root)); diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index ecfd2dc54dd..16ddf2717f4 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -410,7 +410,7 @@ void TestRunner::runTestsHelper() qCInfo(runnerLog) << "Working directory:" << process.workingDirectory(); qCDebug(runnerLog) << "Environment:" << process.environment().toStringList(); }; - const auto onProcessDone = [this, config, storage](const Process &process) { + const auto onProcessDone = [this, config, storage](const Process &process, bool) { TestStorage *testStorage = storage.activeStorage(); QTC_ASSERT(testStorage, return); if (process.result() == ProcessResult::StartFailed) { @@ -448,7 +448,7 @@ void TestRunner::runTestsHelper() finishAllAndDone, Tasking::Storage(storage), onGroupSetup(onSetup), - ProcessTask(onProcessSetup, onProcessDone, onProcessDone) + ProcessTask(onProcessSetup, onProcessDone) }; tasks.append(group); } diff --git a/src/plugins/boot2qt/qdbmakedefaultappstep.cpp b/src/plugins/boot2qt/qdbmakedefaultappstep.cpp index fbff89bd398..39d66f140d2 100644 --- a/src/plugins/boot2qt/qdbmakedefaultappstep.cpp +++ b/src/plugins/boot2qt/qdbmakedefaultappstep.cpp @@ -38,7 +38,7 @@ public: private: GroupItem deployRecipe() final { - const auto setupHandler = [this](Process &process) { + const auto onSetup = [this](Process &process) { QString remoteExe; if (RunConfiguration *rc = target()->activeRunConfiguration()) { if (auto exeAspect = rc->aspect()) @@ -55,16 +55,15 @@ private: handleStdErrData(proc->readAllStandardError()); }); }; - const auto doneHandler = [this](const Process &) { - if (selection() == 0) + const auto onDone = [this](const Process &process, bool success) { + if (!success) + addErrorMessage(Tr::tr("Remote process failed: %1").arg(process.errorString())); + else if (selection() == 0) addProgressMessage(Tr::tr("Application set as the default one.")); else addProgressMessage(Tr::tr("Reset the default application.")); }; - const auto errorHandler = [this](const Process &process) { - addErrorMessage(Tr::tr("Remote process failed: %1").arg(process.errorString())); - }; - return ProcessTask(setupHandler, doneHandler, errorHandler); + return ProcessTask(onSetup, onDone); } SelectionAspect selection{this}; diff --git a/src/plugins/boot2qt/qdbstopapplicationstep.cpp b/src/plugins/boot2qt/qdbstopapplicationstep.cpp index 4a51f843904..8a5002624ee 100644 --- a/src/plugins/boot2qt/qdbstopapplicationstep.cpp +++ b/src/plugins/boot2qt/qdbstopapplicationstep.cpp @@ -39,7 +39,7 @@ public: GroupItem QdbStopApplicationStep::deployRecipe() { - const auto setupHandler = [this](Process &process) { + const auto onSetup = [this](Process &process) { const auto device = DeviceKitAspect::device(target()->kit()); if (!device) { addErrorMessage(Tr::tr("No device to stop the application on.")); @@ -54,10 +54,11 @@ GroupItem QdbStopApplicationStep::deployRecipe() }); return SetupResult::Continue; }; - const auto doneHandler = [this](const Process &) { - addProgressMessage(Tr::tr("Stopped the running application.")); - }; - const auto errorHandler = [this](const Process &process) { + const auto onDone = [this](const Process &process, bool success) { + if (success) { + addProgressMessage(Tr::tr("Stopped the running application.")); + return; + } const QString errorOutput = process.cleanedStdErr(); const QString failureMessage = Tr::tr("Could not check and possibly stop running application."); if (process.exitStatus() == QProcess::CrashExit) { @@ -71,7 +72,7 @@ GroupItem QdbStopApplicationStep::deployRecipe() addErrorMessage(failureMessage); } }; - return ProcessTask(setupHandler, doneHandler, errorHandler); + return ProcessTask(onSetup, onDone); } // QdbStopApplicationStepFactory diff --git a/src/plugins/clangtools/clangtoolrunner.cpp b/src/plugins/clangtools/clangtoolrunner.cpp index e83037aa536..0bded02193d 100644 --- a/src/plugins/clangtools/clangtoolrunner.cpp +++ b/src/plugins/clangtools/clangtoolrunner.cpp @@ -163,24 +163,19 @@ GroupItem clangToolTask(const AnalyzeInputData &input, qCDebug(LOG).noquote() << "Starting" << commandLine.toUserOutput(); process.setCommand(commandLine); }; - const auto onProcessDone = [=](const Process &process) { + const auto onProcessDone = [=](const Process &process, bool success) { qCDebug(LOG).noquote() << "Output:\n" << process.cleanedStdOut(); - // Here we handle only the case of process success with stderr output. if (!outputHandler) return; - if (process.result() != ProcessResult::FinishedWithSuccess) - return; - const QString stdErr = process.cleanedStdErr(); - if (stdErr.isEmpty()) - return; - outputHandler( - {true, input.unit.file, {}, {}, input.tool, Tr::tr("%1 produced stderr output:") - .arg(storage->name), stdErr}); - }; - const auto onProcessError = [=](const Process &process) { - if (!outputHandler) + if (success) { + const QString stdErr = process.cleanedStdErr(); + if (stdErr.isEmpty()) + return; + outputHandler({true, input.unit.file, {}, {}, input.tool, + Tr::tr("%1 produced stderr output:").arg(storage->name), stdErr}); return; + } const QString details = Tr::tr("Command line: %1\nProcess Error: %2\nOutput:\n%3") .arg(process.commandLine().toUserOutput()) .arg(process.error()) @@ -203,31 +198,24 @@ GroupItem clangToolTask(const AnalyzeInputData &input, input.diagnosticsFilter); data.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); }; - const auto onReadDone = [=](const Async> &data) { + const auto onReadDone = [=](const Async> &data, bool success) { if (!outputHandler) return; const expected_str result = data.result(); - const bool success = result.has_value(); + const bool ok = success && result.has_value(); Diagnostics diagnostics; QString error; - if (success) + if (ok) diagnostics = *result; else error = result.error(); - outputHandler({success, + outputHandler({ok, input.unit.file, storage->outputFilePath, diagnostics, input.tool, error}); }; - const auto onReadError = [=](const Async> &data) { - if (!outputHandler) - return; - const expected_str result = data.result(); - outputHandler( - {false, input.unit.file, storage->outputFilePath, {}, input.tool, result.error()}); - }; const Group group { finishAllAndDone, @@ -235,8 +223,8 @@ GroupItem clangToolTask(const AnalyzeInputData &input, onGroupSetup(onSetup), Group { sequential, - ProcessTask(onProcessSetup, onProcessDone, onProcessError), - AsyncTask>(onReadSetup, onReadDone, onReadError) + ProcessTask(onProcessSetup, onProcessDone), + AsyncTask>(onReadSetup, onReadDone) } }; return group; diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.cpp b/src/plugins/coreplugin/locator/ilocatorfilter.cpp index feff0d9d1ca..fbfd557e467 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/ilocatorfilter.cpp @@ -441,8 +441,7 @@ void LocatorMatcher::start() emit serialOutputDataReady(serialOutputData); }); }; - const auto onCollectorDone = [collectorStorage](const ResultsCollector &collector) { - Q_UNUSED(collector) + const auto onCollectorDone = [collectorStorage](const ResultsCollector &, bool) { collectorStorage->m_collector = nullptr; }; @@ -480,7 +479,7 @@ void LocatorMatcher::start() const Group root { parallel, Storage(collectorStorage), - ResultsCollectorTask(onCollectorSetup, onCollectorDone, onCollectorDone), + ResultsCollectorTask(onCollectorSetup, onCollectorDone), Group { parallelTasks } diff --git a/src/plugins/coreplugin/locator/javascriptfilter.cpp b/src/plugins/coreplugin/locator/javascriptfilter.cpp index 21459d41dc6..777b352e846 100644 --- a/src/plugins/coreplugin/locator/javascriptfilter.cpp +++ b/src/plugins/coreplugin/locator/javascriptfilter.cpp @@ -394,7 +394,13 @@ LocatorMatcherTasks JavaScriptFilter::matchers() request.setEngine(engine); request.setEvaluateData(storage->input()); }; - const auto onJavaScriptDone = [storage](const JavaScriptRequest &request) { + const auto onJavaScriptDone = [storage](const JavaScriptRequest &request, bool success) { + if (!success) { + LocatorFilterEntry entry; + entry.displayName = request.output().m_output; + storage->reportOutput({entry}); + return; + } const auto acceptor = [](const QString &clipboardContents) { return [clipboardContents] { QGuiApplication::clipboard()->setText(clipboardContents); @@ -418,15 +424,10 @@ LocatorMatcherTasks JavaScriptFilter::matchers() storage->reportOutput({entry, copyResultEntry, copyExpressionEntry}); }; - const auto onJavaScriptError = [storage](const JavaScriptRequest &request) { - LocatorFilterEntry entry; - entry.displayName = request.output().m_output; - storage->reportOutput({entry}); - }; const Group root { onGroupSetup(onSetup), - JavaScriptRequestTask(onJavaScriptSetup, onJavaScriptDone, onJavaScriptError) + JavaScriptRequestTask(onJavaScriptSetup, onJavaScriptDone) }; return {{root, storage}}; diff --git a/src/plugins/projectexplorer/abstractprocessstep.cpp b/src/plugins/projectexplorer/abstractprocessstep.cpp index c5516d5dc5b..c64044259c8 100644 --- a/src/plugins/projectexplorer/abstractprocessstep.cpp +++ b/src/plugins/projectexplorer/abstractprocessstep.cpp @@ -164,8 +164,8 @@ GroupItem AbstractProcessStep::defaultProcessTask() const auto onSetup = [this](Process &process) { return setupProcess(process) ? SetupResult::Continue : SetupResult::StopWithError; }; - const auto onEnd = [this](const Process &process) { handleProcessDone(process); }; - return ProcessTask(onSetup, onEnd, onEnd); + const auto onDone = [this](const Process &process, bool) { handleProcessDone(process); }; + return ProcessTask(onSetup, onDone); } bool AbstractProcessStep::setupProcess(Process &process) diff --git a/src/plugins/projectexplorer/copystep.cpp b/src/plugins/projectexplorer/copystep.cpp index 98cd5df3f17..b6262a0fe12 100644 --- a/src/plugins/projectexplorer/copystep.cpp +++ b/src/plugins/projectexplorer/copystep.cpp @@ -52,13 +52,13 @@ private: streamer.setDestination(m_target); return SetupResult::Continue; }; - const auto onDone = [this](const FileStreamer &) { - addOutput(Tr::tr("Copying finished."), OutputFormat::NormalMessage); + const auto onDone = [this](const FileStreamer &, bool success) { + if (success) + addOutput(Tr::tr("Copying finished."), OutputFormat::NormalMessage); + else + addOutput(Tr::tr("Copying failed."), OutputFormat::ErrorMessage); }; - const auto onError = [this](const FileStreamer &) { - addOutput(Tr::tr("Copying failed."), OutputFormat::ErrorMessage); - }; - return FileStreamerTask(onSetup, onDone, onError); + return FileStreamerTask(onSetup, onDone); } FilePath m_source; diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 95a2d487e4b..53b7ab9048c 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -275,14 +275,14 @@ Tasking::GroupItem QMakeStep::runRecipe() return SetupResult::StopWithDone; }; - const auto setupQMake = [this](Process &process) { + const auto onQMakeSetup = [this](Process &process) { m_outputFormatter->setLineParsers({new QMakeParser}); ProcessParameters *pp = processParameters(); pp->setCommandLine(m_qmakeCommand); return setupProcess(process) ? SetupResult::Continue : SetupResult::StopWithError; }; - const auto setupMakeQMake = [this](Process &process) { + const auto onMakeQMakeSetup = [this](Process &process) { auto *parser = new GnuMakeParser; parser->addSearchDir(processParameters()->workingDirectory()); m_outputFormatter->setLineParsers({parser}); @@ -291,7 +291,7 @@ Tasking::GroupItem QMakeStep::runRecipe() return setupProcess(process) ? SetupResult::Continue : SetupResult::StopWithError; }; - const auto onProcessDone = [this](const Process &process) { handleProcessDone(process); }; + const auto onProcessDone = [this](const Process &process, bool) { handleProcessDone(process); }; const auto onDone = [this] { emit buildConfiguration()->buildDirectoryInitialized(); @@ -300,9 +300,9 @@ Tasking::GroupItem QMakeStep::runRecipe() QList processList = {onGroupSetup(onSetup), onGroupDone(onDone), - ProcessTask(setupQMake, onProcessDone, onProcessDone)}; + ProcessTask(onQMakeSetup, onProcessDone)}; if (m_runMakeQmake) - processList << ProcessTask(setupMakeQMake, onProcessDone, onProcessDone); + processList << ProcessTask(onMakeQMakeSetup, onProcessDone); return Group(processList); } diff --git a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp index 5855352975c..6c19ea10f67 100644 --- a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp +++ b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp @@ -119,13 +119,22 @@ QList collectFilesToUpload(const DeployableFile &deployable) GroupItem QnxDeployQtLibrariesDialogPrivate::checkDirTask() { - const auto setupHandler = [this](Process &process) { + const auto onSetup = [this](Process &process) { m_deployLogWindow->appendPlainText(Tr::tr("Checking existence of \"%1\"") .arg(fullRemoteDirectory())); process.setCommand({m_device->filePath("test"), {"-d", fullRemoteDirectory()}}); }; - const auto doneHandler = [this](const Process &process) { - Q_UNUSED(process) + const auto onDone = [this](const Process &process, bool success) { + if (!success) { + if (process.result() != ProcessResult::FinishedWithError) { + m_deployLogWindow->appendPlainText(Tr::tr("Connection failed: %1") + .arg(process.errorString())); + m_checkResult = CheckResult::Abort; + return; + } + m_checkResult = CheckResult::SkipRemoveDir; + return; + } const int answer = QMessageBox::question(q, q->windowTitle(), Tr::tr("The remote directory \"%1\" already exists.\n" "Deploying to that directory will remove any files already present.\n\n" @@ -133,16 +142,7 @@ GroupItem QnxDeployQtLibrariesDialogPrivate::checkDirTask() QMessageBox::Yes | QMessageBox::No); m_checkResult = answer == QMessageBox::Yes ? CheckResult::RemoveDir : CheckResult::Abort; }; - const auto errorHandler = [this](const Process &process) { - if (process.result() != ProcessResult::FinishedWithError) { - m_deployLogWindow->appendPlainText(Tr::tr("Connection failed: %1") - .arg(process.errorString())); - m_checkResult = CheckResult::Abort; - return; - } - m_checkResult = CheckResult::SkipRemoveDir; - }; - return ProcessTask(setupHandler, doneHandler, errorHandler); + return ProcessTask(onSetup, onDone); } GroupItem QnxDeployQtLibrariesDialogPrivate::removeDirTask() diff --git a/src/plugins/qnx/qnxdevicetester.cpp b/src/plugins/qnx/qnxdevicetester.cpp index cbead1aa3d6..b162abb7f69 100644 --- a/src/plugins/qnx/qnxdevicetester.cpp +++ b/src/plugins/qnx/qnxdevicetester.cpp @@ -43,7 +43,7 @@ void QnxDeviceTester::testDevice(const ProjectExplorer::IDevice::Ptr &device) using namespace Tasking; - auto setupHandler = [device, this](Process &process) { + auto onSetup = [device, this](Process &process) { emit progressMessage(Tr::tr("Checking that files can be created in %1...") .arg(Constants::QNX_TMP_DIR)); const QString pidFile = QString("%1/qtc_xxxx.pid").arg(Constants::QNX_TMP_DIR); @@ -51,17 +51,18 @@ void QnxDeviceTester::testDevice(const ProjectExplorer::IDevice::Ptr &device) {"-c", QLatin1String("rm %1 > /dev/null 2>&1; echo ABC > %1 && rm %1").arg(pidFile)}); process.setCommand(cmd); }; - auto doneHandler = [this](const Process &) { - emit progressMessage(Tr::tr("Files can be created in /var/run.") + '\n'); - }; - auto errorHandler = [this](const Process &process) { + auto onDone = [this](const Process &process, bool success) { + if (success) { + emit progressMessage(Tr::tr("Files can be created in /var/run.") + '\n'); + return; + } const QString message = process.result() == ProcessResult::StartFailed ? Tr::tr("An error occurred while checking that files can be created in %1.") .arg(Constants::QNX_TMP_DIR) + '\n' + process.errorString() : Tr::tr("Files cannot be created in %1.").arg(Constants::QNX_TMP_DIR); emit errorMessage(message + '\n'); }; - setExtraTests({ProcessTask(setupHandler, doneHandler, errorHandler)}); + setExtraTests({ProcessTask(onSetup, onDone)}); RemoteLinux::GenericLinuxDeviceTester::testDevice(device); } diff --git a/src/plugins/qnx/slog2inforunner.cpp b/src/plugins/qnx/slog2inforunner.cpp index 77700804b21..8be079c4300 100644 --- a/src/plugins/qnx/slog2inforunner.cpp +++ b/src/plugins/qnx/slog2inforunner.cpp @@ -34,27 +34,28 @@ void Slog2InfoRunner::start() using namespace Tasking; QTC_CHECK(!m_taskTree); - const auto testStartHandler = [this](Process &process) { + const auto onTestSetup = [this](Process &process) { process.setCommand({device()->filePath("slog2info"), {}}); }; - const auto testDoneHandler = [this](const Process &) { - m_found = true; - }; - const auto testErrorHandler = [this](const Process &) { + const auto onTestDone = [this](const Process &, bool success) { + if (success) { + m_found = true; + return; + } appendMessage(Tr::tr("Warning: \"slog2info\" is not found on the device, " "debug output not available."), ErrorMessageFormat); }; - const auto launchTimeStartHandler = [this](Process &process) { + const auto onLaunchTimeSetup = [this](Process &process) { process.setCommand({device()->filePath("date"), "+\"%d %H:%M:%S\"", CommandLine::Raw}); }; - const auto launchTimeDoneHandler = [this](const Process &process) { + const auto onLaunchTimeDone = [this](const Process &process) { QTC_CHECK(!m_applicationId.isEmpty()); QTC_CHECK(m_found); m_launchDateTime = QDateTime::fromString(process.cleanedStdOut().trimmed(), "dd HH:mm:ss"); }; - const auto logStartHandler = [this](Process &process) { + const auto onLogSetup = [this](Process &process) { process.setCommand({device()->filePath("slog2info"), {"-w"}}); connect(&process, &Process::readyReadStandardOutput, this, [&] { processLogInput(QString::fromLatin1(process.readAllRawStandardOutput())); @@ -63,15 +64,15 @@ void Slog2InfoRunner::start() appendMessage(QString::fromLatin1(process.readAllRawStandardError()), StdErrFormat); }); }; - const auto logErrorHandler = [this](const Process &process) { + const auto onLogError = [this](const Process &process) { appendMessage(Tr::tr("Cannot show slog2info output. Error: %1").arg(process.errorString()), StdErrFormat); }; const Group root { - ProcessTask(testStartHandler, testDoneHandler, testErrorHandler), - ProcessTask(launchTimeStartHandler, launchTimeDoneHandler), - ProcessTask(logStartHandler, {}, logErrorHandler) + ProcessTask(onTestSetup, onTestDone), + ProcessTask(onLaunchTimeSetup, onLaunchTimeDone), + ProcessTask(onLogSetup, {}, onLogError) }; m_taskTree.reset(new TaskTree(root)); diff --git a/src/plugins/remotelinux/customcommanddeploystep.cpp b/src/plugins/remotelinux/customcommanddeploystep.cpp index 2b5753243fb..1de16a6fedd 100644 --- a/src/plugins/remotelinux/customcommanddeploystep.cpp +++ b/src/plugins/remotelinux/customcommanddeploystep.cpp @@ -53,7 +53,7 @@ expected_str CustomCommandDeployStep::isDeploymentPossible() const GroupItem CustomCommandDeployStep::deployRecipe() { - const auto setupHandler = [this](Process &process) { + const auto onSetup = [this](Process &process) { addProgressMessage(Tr::tr("Starting remote command \"%1\"...").arg(commandLine())); process.setCommand({deviceConfiguration()->filePath("/bin/sh"), {"-c", commandLine()}}); @@ -65,11 +65,10 @@ GroupItem CustomCommandDeployStep::deployRecipe() handleStdErrData(proc->readAllStandardError()); }); }; - const auto doneHandler = [this](const Process &) { - addProgressMessage(Tr::tr("Remote command finished successfully.")); - }; - const auto errorHandler = [this](const Process &process) { - if (process.error() != QProcess::UnknownError + const auto onDone = [this](const Process &process, bool success) { + if (success) { + addProgressMessage(Tr::tr("Remote command finished successfully.")); + } else if (process.error() != QProcess::UnknownError || process.exitStatus() != QProcess::NormalExit) { addErrorMessage(Tr::tr("Remote process failed: %1").arg(process.errorString())); } else if (process.exitCode() != 0) { @@ -77,7 +76,7 @@ GroupItem CustomCommandDeployStep::deployRecipe() .arg(process.exitCode())); } }; - return ProcessTask(setupHandler, doneHandler, errorHandler); + return ProcessTask(onSetup, onDone); } diff --git a/src/plugins/remotelinux/genericdirectuploadstep.cpp b/src/plugins/remotelinux/genericdirectuploadstep.cpp index d9fc3d72a35..4878a6f20a0 100644 --- a/src/plugins/remotelinux/genericdirectuploadstep.cpp +++ b/src/plugins/remotelinux/genericdirectuploadstep.cpp @@ -135,17 +135,17 @@ GroupItem GenericDirectUploadStep::statTask(UploadStorage *storage, const DeployableFile &file, StatEndHandler statEndHandler) { - const auto setupHandler = [=](Process &process) { + const auto onSetup = [this, file](Process &process) { // We'd like to use --format=%Y, but it's not supported by busybox. process.setCommand({deviceConfiguration()->filePath("stat"), {"-t", Utils::ProcessArgs::quoteArgUnix(file.remoteFilePath())}}); }; - const auto endHandler = [=](const Process &process) { + const auto onDone = [this, storage, file, statEndHandler](const Process &process, bool) { Process *proc = const_cast(&process); const QDateTime timestamp = timestampFromStat(file, proc); statEndHandler(storage, file, timestamp); }; - return ProcessTask(setupHandler, endHandler, endHandler); + return ProcessTask(onSetup, onDone); } GroupItem GenericDirectUploadStep::statTree(const TreeStorage &storage, diff --git a/src/plugins/remotelinux/killappstep.cpp b/src/plugins/remotelinux/killappstep.cpp index 3986ebe6b9b..559ddbadcc8 100644 --- a/src/plugins/remotelinux/killappstep.cpp +++ b/src/plugins/remotelinux/killappstep.cpp @@ -45,7 +45,7 @@ private: GroupItem KillAppStep::deployRecipe() { - const auto setupHandler = [this](DeviceProcessKiller &killer) { + const auto onSetup = [this](DeviceProcessKiller &killer) { if (m_remoteExecutable.isEmpty()) { addSkipDeploymentMessage(); return SetupResult::StopWithDone; @@ -55,14 +55,13 @@ GroupItem KillAppStep::deployRecipe() .arg(m_remoteExecutable.path())); return SetupResult::Continue; }; - const auto doneHandler = [this](const DeviceProcessKiller &) { - addProgressMessage(Tr::tr("Remote application killed.")); + const auto onDone = [this](const DeviceProcessKiller &, bool success) { + const QString message = success ? Tr::tr("Remote application killed.") + : Tr::tr("Failed to kill remote application. " + "Assuming it was not running."); + addProgressMessage(message); }; - const auto errorHandler = [this](const DeviceProcessKiller &) { - addProgressMessage(Tr::tr("Failed to kill remote application. " - "Assuming it was not running.")); - }; - return DeviceProcessKillerTask(setupHandler, doneHandler, errorHandler); + return DeviceProcessKillerTask(onSetup, onDone); } KillAppStepFactory::KillAppStepFactory() diff --git a/src/plugins/remotelinux/linuxdevicetester.cpp b/src/plugins/remotelinux/linuxdevicetester.cpp index e908541aa57..dfbdea33306 100644 --- a/src/plugins/remotelinux/linuxdevicetester.cpp +++ b/src/plugins/remotelinux/linuxdevicetester.cpp @@ -92,38 +92,42 @@ QStringList GenericLinuxDeviceTesterPrivate::commandsToTest() const GroupItem GenericLinuxDeviceTesterPrivate::echoTask(const QString &contents) const { - const auto setup = [this, contents](Process &process) { + const auto onSetup = [this, contents](Process &process) { emit q->progressMessage(Tr::tr("Sending echo to device...")); process.setCommand({m_device->filePath("echo"), {contents}}); }; - const auto done = [this, contents](const Process &process) { + const auto onDone = [this, contents](const Process &process, bool success) { + if (!success) { + const QString stdErrOutput = process.cleanedStdErr(); + if (!stdErrOutput.isEmpty()) + emit q->errorMessage(Tr::tr("echo failed: %1").arg(stdErrOutput) + '\n'); + else + emit q->errorMessage(Tr::tr("echo failed.") + '\n'); + return; + } const QString reply = Utils::chopIfEndsWith(process.cleanedStdOut(), '\n'); - if (reply != contents) + if (reply != contents) { emit q->errorMessage(Tr::tr("Device replied to echo with unexpected contents: \"%1\"") - .arg(reply) + '\n'); - else - emit q->progressMessage(Tr::tr("Device replied to echo with expected contents.") + '\n'); + .arg(reply) + '\n'); + } else { + emit q->progressMessage(Tr::tr("Device replied to echo with expected contents.") + + '\n'); + } }; - const auto error = [this](const Process &process) { - const QString stdErrOutput = process.cleanedStdErr(); - if (!stdErrOutput.isEmpty()) - emit q->errorMessage(Tr::tr("echo failed: %1").arg(stdErrOutput) + '\n'); - else - emit q->errorMessage(Tr::tr("echo failed.") + '\n'); - }; - return ProcessTask(setup, done, error); + return ProcessTask(onSetup, onDone); } GroupItem GenericLinuxDeviceTesterPrivate::unameTask() const { - const auto setup = [this](Process &process) { + const auto onSetup = [this](Process &process) { emit q->progressMessage(Tr::tr("Checking kernel version...")); process.setCommand({m_device->filePath("uname"), {"-rsm"}}); }; - const auto done = [this](const Process &process) { - emit q->progressMessage(process.cleanedStdOut()); - }; - const auto error = [this](const Process &process) { + const auto onDone = [this](const Process &process, bool success) { + if (success) { + emit q->progressMessage(process.cleanedStdOut()); + return; + } const QString stdErrOutput = process.cleanedStdErr(); if (!stdErrOutput.isEmpty()) emit q->errorMessage(Tr::tr("uname failed: %1").arg(stdErrOutput) + '\n'); @@ -132,18 +136,21 @@ GroupItem GenericLinuxDeviceTesterPrivate::unameTask() const }; return Group { finishAllAndDone, - ProcessTask(setup, done, error) + ProcessTask(onSetup, onDone) }; } GroupItem GenericLinuxDeviceTesterPrivate::gathererTask() const { - const auto setup = [this](DeviceUsedPortsGatherer &gatherer) { + const auto onSetup = [this](DeviceUsedPortsGatherer &gatherer) { emit q->progressMessage(Tr::tr("Checking if specified ports are available...")); gatherer.setDevice(m_device); }; - const auto done = [this](const DeviceUsedPortsGatherer &gatherer) { - if (gatherer.usedPorts().isEmpty()) { + const auto onDone = [this](const DeviceUsedPortsGatherer &gatherer, bool success) { + if (!success) { + emit q->errorMessage(Tr::tr("Error gathering ports: %1").arg(gatherer.errorString()) + '\n' + + Tr::tr("Some tools will not work out of the box.\n")); + } else if (gatherer.usedPorts().isEmpty()) { emit q->progressMessage(Tr::tr("All specified ports are available.") + '\n'); } else { const QString portList = transform(gatherer.usedPorts(), [](const Port &port) { @@ -153,38 +160,34 @@ GroupItem GenericLinuxDeviceTesterPrivate::gathererTask() const .arg(portList) + '\n'); } }; - const auto error = [this](const DeviceUsedPortsGatherer &gatherer) { - emit q->errorMessage(Tr::tr("Error gathering ports: %1").arg(gatherer.errorString()) + '\n' - + Tr::tr("Some tools will not work out of the box.\n")); - }; return Group { finishAllAndDone, - DeviceUsedPortsGathererTask(setup, done, error) + DeviceUsedPortsGathererTask(onSetup, onDone) }; } GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod method, const TreeStorage &storage) const { - const auto setup = [this, method](FileTransfer &transfer) { + const auto onSetup = [this, method](FileTransfer &transfer) { emit q->progressMessage(Tr::tr("Checking whether \"%1\" works...") .arg(FileTransfer::transferMethodName(method))); transfer.setTransferMethod(method); transfer.setTestDevice(m_device); }; - const auto done = [this, method, storage](const FileTransfer &) { - const QString methodName = FileTransfer::transferMethodName(method); - emit q->progressMessage(Tr::tr("\"%1\" is functional.\n").arg(methodName)); - if (method == FileTransferMethod::Rsync) - m_device->setExtraData(Constants::SUPPORTS_RSYNC, true); - else if (method == FileTransferMethod::Sftp) - m_device->setExtraData(Constants::SUPPORTS_SFTP, true); - else - storage->useGenericCopy = true; - }; - const auto error = [this, method, storage](const FileTransfer &transfer) { + const auto onDone = [this, method, storage](const FileTransfer &transfer, bool success) { const QString methodName = FileTransfer::transferMethodName(method); + if (success) { + emit q->progressMessage(Tr::tr("\"%1\" is functional.\n").arg(methodName)); + if (method == FileTransferMethod::Rsync) + m_device->setExtraData(Constants::SUPPORTS_RSYNC, true); + else if (method == FileTransferMethod::Sftp) + m_device->setExtraData(Constants::SUPPORTS_SFTP, true); + else + storage->useGenericCopy = true; + return; + } const ProcessResultData resultData = transfer.resultData(); QString error; if (resultData.m_error == QProcess::FailedToStart) { @@ -218,7 +221,7 @@ GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod metho + "\n"); } }; - return FileTransferTestTask(setup, done, error); + return FileTransferTestTask(onSetup, onDone); } GroupItem GenericLinuxDeviceTesterPrivate::transferTasks() const @@ -238,23 +241,24 @@ GroupItem GenericLinuxDeviceTesterPrivate::transferTasks() const GroupItem GenericLinuxDeviceTesterPrivate::commandTask(const QString &commandName) const { - const auto setup = [this, commandName](Process &process) { + const auto onSetup = [this, commandName](Process &process) { emit q->progressMessage(Tr::tr("%1...").arg(commandName)); CommandLine command{m_device->filePath("/bin/sh"), {"-c"}}; command.addArgs(QLatin1String("\"command -v %1\"").arg(commandName), CommandLine::Raw); process.setCommand(command); }; - const auto done = [this, commandName](const Process &) { - emit q->progressMessage(Tr::tr("%1 found.").arg(commandName)); - }; - const auto error = [this, commandName](const Process &process) { + const auto onDone = [this, commandName](const Process &process, bool success) { + if (success) { + emit q->progressMessage(Tr::tr("%1 found.").arg(commandName)); + return; + } const QString message = process.result() == ProcessResult::StartFailed ? Tr::tr("An error occurred while checking for %1.").arg(commandName) + '\n' + process.errorString() : Tr::tr("%1 not found.").arg(commandName); emit q->errorMessage(message); }; - return ProcessTask(setup, done, error); + return ProcessTask(onSetup, onDone); } GroupItem GenericLinuxDeviceTesterPrivate::commandTasks() const diff --git a/src/plugins/remotelinux/tarpackagecreationstep.cpp b/src/plugins/remotelinux/tarpackagecreationstep.cpp index 74b5a8fa423..23b9c34e5ed 100644 --- a/src/plugins/remotelinux/tarpackagecreationstep.cpp +++ b/src/plugins/remotelinux/tarpackagecreationstep.cpp @@ -153,17 +153,18 @@ Tasking::GroupItem TarPackageCreationStep::runRecipe() async.setFutureSynchronizer(&m_synchronizer); return SetupResult::Continue; }; - const auto onDone = [this](const Async &) { + const auto onDone = [this](const Async &, bool success) { + if (!success) { + emit addOutput(Tr::tr("Packaging failed."), OutputFormat::ErrorMessage); + return; + } m_deploymentDataModified = false; emit addOutput(Tr::tr("Packaging finished successfully."), OutputFormat::NormalMessage); // TODO: Should it be the next task in sequence? connect(BuildManager::instance(), &BuildManager::buildQueueFinished, this, &TarPackageCreationStep::deployFinished); }; - const auto onError = [this](const Async &) { - emit addOutput(Tr::tr("Packaging failed."), OutputFormat::ErrorMessage); - }; - return AsyncTask(onSetup, onDone, onError); + return AsyncTask(onSetup, onDone); } void TarPackageCreationStep::fromMap(const Store &map) diff --git a/src/plugins/remotelinux/tarpackagedeploystep.cpp b/src/plugins/remotelinux/tarpackagedeploystep.cpp index 7475f47d479..6d393b00e40 100644 --- a/src/plugins/remotelinux/tarpackagedeploystep.cpp +++ b/src/plugins/remotelinux/tarpackagedeploystep.cpp @@ -67,26 +67,25 @@ QString TarPackageDeployStep::remoteFilePath() const GroupItem TarPackageDeployStep::uploadTask() { - const auto setupHandler = [this](FileTransfer &transfer) { + const auto onSetup = [this](FileTransfer &transfer) { const FilesToTransfer files {{m_packageFilePath, deviceConfiguration()->filePath(remoteFilePath())}}; transfer.setFilesToTransfer(files); connect(&transfer, &FileTransfer::progress, this, &TarPackageDeployStep::addProgressMessage); addProgressMessage(Tr::tr("Uploading package to device...")); }; - const auto doneHandler = [this](const FileTransfer &) { - addProgressMessage(Tr::tr("Successfully uploaded package file.")); + const auto onDone = [this](const FileTransfer &transfer, bool success) { + if (success) + addProgressMessage(Tr::tr("Successfully uploaded package file.")); + else + addErrorMessage(transfer.resultData().m_errorString); }; - const auto errorHandler = [this](const FileTransfer &transfer) { - const ProcessResultData result = transfer.resultData(); - addErrorMessage(result.m_errorString); - }; - return FileTransferTask(setupHandler, doneHandler, errorHandler); + return FileTransferTask(onSetup, onDone); } GroupItem TarPackageDeployStep::installTask() { - const auto setupHandler = [this](Process &process) { + const auto onSetup = [this](Process &process) { const QString cmdLine = QLatin1String("cd / && tar xvf ") + remoteFilePath() + " && (rm " + remoteFilePath() + " || :)"; process.setCommand({deviceConfiguration()->filePath("/bin/sh"), {"-c", cmdLine}}); @@ -99,14 +98,15 @@ GroupItem TarPackageDeployStep::installTask() }); addProgressMessage(Tr::tr("Installing package to device...")); }; - const auto doneHandler = [this](const Process &) { - saveDeploymentTimeStamp(DeployableFile(m_packageFilePath, {}), {}); - addProgressMessage(Tr::tr("Successfully installed package file.")); - }; - const auto errorHandler = [this](const Process &process) { + const auto onDone = [this](const Process &process, bool success) { + if (success) { + saveDeploymentTimeStamp(DeployableFile(m_packageFilePath, {}), {}); + addProgressMessage(Tr::tr("Successfully installed package file.")); + return; + } addErrorMessage(Tr::tr("Installing package failed.") + process.errorString()); }; - return ProcessTask(setupHandler, doneHandler, errorHandler); + return ProcessTask(onSetup, onDone); } GroupItem TarPackageDeployStep::deployRecipe() diff --git a/tests/manual/tasking/imagescaling/imagescaling.cpp b/tests/manual/tasking/imagescaling/imagescaling.cpp index e3acda749b2..5d2992d87cd 100644 --- a/tests/manual/tasking/imagescaling/imagescaling.cpp +++ b/tests/manual/tasking/imagescaling/imagescaling.cpp @@ -79,27 +79,27 @@ void Images::process() query.setNetworkAccessManager(&qnam); query.setRequest(QNetworkRequest(url)); }; - const auto onDownloadDone = [storage](const NetworkQuery &query) { - *storage = query.reply()->readAll(); - }; - const auto onDownloadError = [this, i](const NetworkQuery &query) { - labels[i]->setText(tr("Download\nError.\nCode: %1.").arg(query.reply()->error())); + const auto onDownloadDone = [this, storage, i](const NetworkQuery &query, bool success) { + if (success) + *storage = query.reply()->readAll(); + else + labels[i]->setText(tr("Download\nError.\nCode: %1.").arg(query.reply()->error())); }; const auto onScalingSetup = [storage](ConcurrentCall &data) { data.setConcurrentCallData(&scale, *storage); }; - const auto onScalingDone = [this, i](const ConcurrentCall &data) { - labels[i]->setPixmap(QPixmap::fromImage(data.result())); - }; - const auto onScalingError = [this, i](const ConcurrentCall &) { - labels[i]->setText(tr("Image\nData\nError.")); + const auto onScalingDone = [this, i](const ConcurrentCall &data, bool success) { + if (success) + labels[i]->setPixmap(QPixmap::fromImage(data.result())); + else + labels[i]->setText(tr("Image\nData\nError.")); }; const Group group { Storage(storage), - NetworkQueryTask(onDownloadSetup, onDownloadDone, onDownloadError), - ConcurrentCallTask(onScalingSetup, onScalingDone, onScalingError) + NetworkQueryTask(onDownloadSetup, onDownloadDone), + ConcurrentCallTask(onScalingSetup, onScalingDone) }; tasks.append(group); ++i; From b89baec2c158e98dfc511c8962666aa2d20448e8 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 19 Oct 2023 10:42:45 +0200 Subject: [PATCH 0071/1546] ProjectExplorer: Promote CppProjectUpdaterInterface ... to ProjectExplorer::ProjectUpdaterInterface and generalize it regarding language, but create a convience function for the C++ case, as that's the only user right now. Also add the self-registering factory boilerplate and adapt all buildsystems. Change-Id: If928512609d41c25fad2aa58633c8bffabc4c48f Reviewed-by: Eike Ziller --- .../autotoolsbuildsystem.cpp | 6 +- .../autotoolsbuildsystem.h | 4 +- .../cmakeprojectmanager/cmakebuildsystem.cpp | 4 +- .../cmakeprojectmanager/cmakebuildsystem.h | 6 +- .../compilationdatabaseproject.cpp | 8 ++- .../compilationdatabaseproject.h | 16 ++--- src/plugins/cppeditor/CMakeLists.txt | 1 - src/plugins/cppeditor/cppeditor.qbs | 1 - src/plugins/cppeditor/cppeditorplugin.cpp | 4 -- src/plugins/cppeditor/cppprojectupdater.cpp | 14 ++--- src/plugins/cppeditor/cppprojectupdater.h | 16 +++-- .../cppeditor/cppprojectupdaterinterface.h | 20 ------- .../genericprojectmanager/genericproject.cpp | 21 ++----- .../mesonprojectmanager/mesonbuildsystem.cpp | 7 ++- .../mesonprojectmanager/mesonbuildsystem.h | 6 +- src/plugins/projectexplorer/CMakeLists.txt | 1 + .../projectexplorer/projectexplorer.qbs | 1 + .../projectexplorer/projectupdater.cpp | 58 +++++++++++++++++++ src/plugins/projectexplorer/projectupdater.h | 45 ++++++++++++++ src/plugins/qbsprojectmanager/qbsproject.cpp | 5 +- src/plugins/qbsprojectmanager/qbsproject.h | 4 +- .../qmakeprojectmanager/qmakeproject.cpp | 4 +- .../qmakeprojectmanager/qmakeproject.h | 9 ++- 23 files changed, 165 insertions(+), 96 deletions(-) delete mode 100644 src/plugins/cppeditor/cppprojectupdaterinterface.h create mode 100644 src/plugins/projectexplorer/projectupdater.cpp create mode 100644 src/plugins/projectexplorer/projectupdater.h diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp b/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp index 113212be5fb..0b64294d0da 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.cpp @@ -5,9 +5,11 @@ #include "makefileparserthread.h" -#include #include +#include +#include #include + #include #include @@ -20,7 +22,7 @@ namespace AutotoolsProjectManager::Internal { AutotoolsBuildSystem::AutotoolsBuildSystem(Target *target) : BuildSystem(target) - , m_cppCodeModelUpdater(new CppEditor::CppProjectUpdater) + , m_cppCodeModelUpdater(ProjectUpdaterFactory::createCppProjectUpdater()) { connect(target, &Target::activeBuildConfigurationChanged, this, [this] { requestParse(); }); connect(target->project(), &Project::projectFileIsDirty, this, [this] { requestParse(); }); diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.h b/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.h index 8832323d6f9..45976a359a8 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.h +++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildsystem.h @@ -7,7 +7,7 @@ #include -namespace CppEditor { class CppProjectUpdater; } +namespace ProjectExplorer { class ProjectUpdater; } namespace AutotoolsProjectManager::Internal { @@ -42,7 +42,7 @@ private: /// Responsible for parsing the makefiles asynchronously in a thread std::unique_ptr m_makefileParserThread; - CppEditor::CppProjectUpdater *m_cppCodeModelUpdater = nullptr; + ProjectExplorer::ProjectUpdater *m_cppCodeModelUpdater = nullptr; }; } // AutotoolsProjectManager::Internal diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index b05fbbe9174..ff948fed01e 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -24,12 +24,12 @@ #include #include -#include #include #include #include #include +#include #include #include @@ -71,7 +71,7 @@ static Q_LOGGING_CATEGORY(cmakeBuildSystemLog, "qtc.cmake.buildsystem", QtWarnin CMakeBuildSystem::CMakeBuildSystem(CMakeBuildConfiguration *bc) : BuildSystem(bc) - , m_cppCodeModelUpdater(new CppEditor::CppProjectUpdater) + , m_cppCodeModelUpdater(ProjectUpdaterFactory::createCppProjectUpdater()) { // TreeScanner: connect(&m_treeScanner, &TreeScanner::finished, diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h index bf0f2c581d2..6086146223b 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.h @@ -10,14 +10,14 @@ #include #include -#include #include -namespace CppEditor { class CppProjectUpdater; } namespace ProjectExplorer { class ExtraCompiler; class FolderNode; + class ProjectUpdater; } + namespace Utils { class Process; class Link; @@ -225,7 +225,7 @@ private: ParseGuard m_currentGuard; - CppEditor::CppProjectUpdater *m_cppCodeModelUpdater = nullptr; + ProjectExplorer::ProjectUpdater *m_cppCodeModelUpdater = nullptr; QList m_extraCompilers; QList m_buildTargets; QSet m_cmakeFiles; diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp index 2ca95d6ecb7..99d0e89ae17 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp @@ -8,8 +8,9 @@ #include #include -#include + #include + #include #include #include @@ -21,8 +22,10 @@ #include #include #include +#include #include #include + #include #include @@ -43,7 +46,6 @@ namespace Internal { namespace { - bool isGccCompiler(const QString &compilerName) { return compilerName.contains("gcc") @@ -312,7 +314,7 @@ void createTree(std::unique_ptr &root, CompilationDatabaseBuildSystem::CompilationDatabaseBuildSystem(Target *target) : BuildSystem(target) - , m_cppCodeModelUpdater(std::make_unique()) + , m_cppCodeModelUpdater(ProjectUpdaterFactory::createCppProjectUpdater()) , m_deployFileWatcher(new FileSystemWatcher(this)) { connect(target->project(), &CompilationDatabaseProject::rootProjectDirectoryChanged, diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h index 71e2ac1a304..3b55927a9b2 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.h @@ -15,12 +15,15 @@ #include -namespace CppEditor { class CppProjectUpdater; } -namespace ProjectExplorer { class Kit; } +namespace ProjectExplorer { +class Kit; +class ProjectUpdater; +} // ProjectExplorer + namespace Utils { class FileSystemWatcher; } -namespace CompilationDatabaseProjectManager { -namespace Internal { +namespace CompilationDatabaseProjectManager::Internal { + class CompilationDbParser; class CompilationDatabaseProject : public ProjectExplorer::Project @@ -49,7 +52,7 @@ public: void buildTreeAndProjectParts(); QFutureWatcher m_parserWatcher; - std::unique_ptr m_cppCodeModelUpdater; + std::unique_ptr m_cppCodeModelUpdater; MimeBinaryCache m_mimeBinaryCache; QByteArray m_projectFileHash; CompilationDbParser *m_parser = nullptr; @@ -68,5 +71,4 @@ public: CompilationDatabaseBuildConfigurationFactory(); }; -} // namespace Internal -} // namespace CompilationDatabaseProjectManager +} // CompilationDatabaseProjectManager::Internal diff --git a/src/plugins/cppeditor/CMakeLists.txt b/src/plugins/cppeditor/CMakeLists.txt index 0c83b99b58f..49fe02c17e7 100644 --- a/src/plugins/cppeditor/CMakeLists.txt +++ b/src/plugins/cppeditor/CMakeLists.txt @@ -69,7 +69,6 @@ add_qtc_plugin(CppEditor cppprojectinfogenerator.cpp cppprojectinfogenerator.h cppprojectpartchooser.cpp cppprojectpartchooser.h cppprojectupdater.cpp cppprojectupdater.h - cppprojectupdaterinterface.h cppqtstyleindenter.cpp cppqtstyleindenter.h cppquickfix.cpp cppquickfix.h cppquickfixassistant.cpp cppquickfixassistant.h diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs index 160fd70aee2..45a7901817a 100644 --- a/src/plugins/cppeditor/cppeditor.qbs +++ b/src/plugins/cppeditor/cppeditor.qbs @@ -150,7 +150,6 @@ QtcPlugin { "cppprojectinfogenerator.h", "cppprojectupdater.cpp", "cppprojectupdater.h", - "cppprojectupdaterinterface.h", "cppquickfix.cpp", "cppquickfix.h", "cppquickfixassistant.cpp", diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp index 13d62e4cee2..30fa3bdad9d 100644 --- a/src/plugins/cppeditor/cppeditorplugin.cpp +++ b/src/plugins/cppeditor/cppeditorplugin.cpp @@ -68,8 +68,6 @@ #include #include -#include - #include #include #include @@ -165,7 +163,6 @@ class CppEditorPluginPrivate : public QObject public: ~CppEditorPluginPrivate() { - ExtensionSystem::PluginManager::removeObject(&m_cppProjectUpdaterFactory); delete m_clangdSettingsPage; } @@ -231,7 +228,6 @@ void CppEditorPlugin::initialize() d->m_codeModelSettings.fromSettings(ICore::settings()); CppModelManager::registerJsExtension(); - ExtensionSystem::PluginManager::addObject(&d->m_cppProjectUpdaterFactory); setupMenus(); registerVariables(); diff --git a/src/plugins/cppeditor/cppprojectupdater.cpp b/src/plugins/cppeditor/cppprojectupdater.cpp index c75ee0cb522..f64c75ea5c9 100644 --- a/src/plugins/cppeditor/cppprojectupdater.cpp +++ b/src/plugins/cppeditor/cppprojectupdater.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -24,11 +25,6 @@ namespace CppEditor { CppProjectUpdater::CppProjectUpdater() = default; CppProjectUpdater::~CppProjectUpdater() = default; -void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo) -{ - update(projectUpdateInfo, {}); -} - void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo, const QList &extraCompilers) { @@ -108,15 +104,13 @@ void CppProjectUpdater::cancel() } namespace Internal { + CppProjectUpdaterFactory::CppProjectUpdaterFactory() { - setObjectName("CppProjectUpdaterFactory"); + setLanguage(Constants::CXX_LANGUAGE_ID); + setCreator([] { return new CppProjectUpdater; }); } -CppProjectUpdaterInterface *CppProjectUpdaterFactory::create() -{ - return new CppProjectUpdater; -} } // namespace Internal } // namespace CppEditor diff --git a/src/plugins/cppeditor/cppprojectupdater.h b/src/plugins/cppeditor/cppprojectupdater.h index a8cebc5b1e0..2a8999b69ee 100644 --- a/src/plugins/cppeditor/cppprojectupdater.h +++ b/src/plugins/cppeditor/cppprojectupdater.h @@ -5,7 +5,8 @@ #include "cppeditor_global.h" -#include "cppprojectupdaterinterface.h" +#include +#include #include @@ -17,19 +18,17 @@ namespace CppEditor { namespace Internal { // registered in extensionsystem's object pool for plugins with weak dependency to CppEditor -class CppProjectUpdaterFactory : public QObject +class CppProjectUpdaterFactory final + : public ProjectExplorer::ProjectUpdaterFactory { - Q_OBJECT public: CppProjectUpdaterFactory(); - - // keep the namespace, for the type name in the invokeMethod call - Q_INVOKABLE CppEditor::CppProjectUpdaterInterface *create(); }; } // namespace Internal -class CPPEDITOR_EXPORT CppProjectUpdater final : public QObject, public CppProjectUpdaterInterface +class CPPEDITOR_EXPORT CppProjectUpdater final + : public QObject, public ProjectExplorer::ProjectUpdater { Q_OBJECT @@ -37,9 +36,8 @@ public: CppProjectUpdater(); ~CppProjectUpdater() override; - void update(const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo) override; void update(const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo, - const QList &extraCompilers); + const QList &extraCompilers) override; void cancel() override; private: diff --git a/src/plugins/cppeditor/cppprojectupdaterinterface.h b/src/plugins/cppeditor/cppprojectupdaterinterface.h deleted file mode 100644 index cb5b797fd2f..00000000000 --- a/src/plugins/cppeditor/cppprojectupdaterinterface.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace CppEditor { - -// FIXME: Remove -class CppProjectUpdaterInterface -{ -public: - virtual ~CppProjectUpdaterInterface() = default; - - virtual void update(const ProjectExplorer::ProjectUpdateInfo &projectUpdateInfo) = 0; - virtual void cancel() = 0; -}; - -} // namespace CppEditor diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index 20afb9f99c1..fcd621b9cce 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -3,8 +3,6 @@ #include "genericproject.h" -#include "genericbuildconfiguration.h" -#include "genericmakestep.h" #include "genericprojectconstants.h" #include "genericprojectmanagertr.h" @@ -13,10 +11,6 @@ #include #include -#include - -#include - #include #include #include @@ -27,6 +21,8 @@ #include #include #include +#include + #include #include #include @@ -156,7 +152,7 @@ private: QStringList m_cxxflags; QStringList m_cflags; - CppEditor::CppProjectUpdaterInterface *m_cppCodeModelUpdater = nullptr; + ProjectUpdater *m_cppCodeModelUpdater = nullptr; FileSystemWatcher m_deployFileWatcher; }; @@ -186,16 +182,7 @@ GenericProject::GenericProject(const Utils::FilePath &fileName) GenericBuildSystem::GenericBuildSystem(Target *target) : BuildSystem(target) { - QObject *projectUpdaterFactory = ExtensionSystem::PluginManager::getObjectByName( - "CppProjectUpdaterFactory"); - if (projectUpdaterFactory) { - const bool successFullyCreatedProjectUpdater - = QMetaObject::invokeMethod(projectUpdaterFactory, - "create", - Q_RETURN_ARG(CppEditor::CppProjectUpdaterInterface *, - m_cppCodeModelUpdater)); - QTC_CHECK(successFullyCreatedProjectUpdater); - } + m_cppCodeModelUpdater = ProjectUpdaterFactory::createCppProjectUpdater(); connect(target->project(), &Project::projectFileIsDirty, this, [this](const FilePath &p) { if (p.endsWith(".files")) diff --git a/src/plugins/mesonprojectmanager/mesonbuildsystem.cpp b/src/plugins/mesonprojectmanager/mesonbuildsystem.cpp index 8aacff10c92..806c2a7fe9f 100644 --- a/src/plugins/mesonprojectmanager/mesonbuildsystem.cpp +++ b/src/plugins/mesonprojectmanager/mesonbuildsystem.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include @@ -177,6 +177,7 @@ void MachineFileManager::cleanupMachineFiles() MesonBuildSystem::MesonBuildSystem(MesonBuildConfiguration *bc) : BuildSystem(bc) , m_parser(MesonToolKitAspect::mesonToolId(bc->kit()), bc->environment(), project()) + , m_cppCodeModelUpdater(ProjectUpdaterFactory::createCppProjectUpdater()) { qCDebug(mesonBuildSystemLog) << "Init"; connect(bc->target(), &ProjectExplorer::Target::kitChanged, this, [this] { @@ -239,8 +240,8 @@ void MesonBuildSystem::parsingCompleted(bool success) if (success) { setRootProjectNode(m_parser.takeProjectNode()); if (kit() && buildConfiguration()) { - ProjectExplorer::KitInfo kitInfo{kit()}; - m_cppCodeModelUpdater.update( + KitInfo kitInfo{kit()}; + m_cppCodeModelUpdater->update( {project(), QtSupport::CppKitInfo(kit()), buildConfiguration()->environment(), diff --git a/src/plugins/mesonprojectmanager/mesonbuildsystem.h b/src/plugins/mesonprojectmanager/mesonbuildsystem.h index b07d5aba4ce..bae78142a74 100644 --- a/src/plugins/mesonprojectmanager/mesonbuildsystem.h +++ b/src/plugins/mesonprojectmanager/mesonbuildsystem.h @@ -6,13 +6,13 @@ #include "mesonprojectparser.h" #include "kitdata.h" -#include - #include #include #include +namespace ProjectExplorer { class ProjectUpdater; } + namespace MesonProjectManager::Internal { class MesonBuildConfiguration; @@ -62,7 +62,7 @@ private: ProjectExplorer::BuildSystem::ParseGuard m_parseGuard; MesonProjectParser m_parser; - CppEditor::CppProjectUpdater m_cppCodeModelUpdater; + std::unique_ptr m_cppCodeModelUpdater; QStringList m_pendingConfigArgs; Utils::FileSystemWatcher m_IntroWatcher; KitData m_kitData; diff --git a/src/plugins/projectexplorer/CMakeLists.txt b/src/plugins/projectexplorer/CMakeLists.txt index 26c7d39d70a..35f9f776322 100644 --- a/src/plugins/projectexplorer/CMakeLists.txt +++ b/src/plugins/projectexplorer/CMakeLists.txt @@ -144,6 +144,7 @@ add_qtc_plugin(ProjectExplorer projectsettingswidget.cpp projectsettingswidget.h projecttree.cpp projecttree.h projecttreewidget.cpp projecttreewidget.h + projectupdater.cpp projectupdater.h projectwelcomepage.cpp projectwelcomepage.h projectwindow.cpp projectwindow.h projectwizardpage.cpp projectwizardpage.h diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs index 8f5e7e75f57..b4b97f9cd4a 100644 --- a/src/plugins/projectexplorer/projectexplorer.qbs +++ b/src/plugins/projectexplorer/projectexplorer.qbs @@ -119,6 +119,7 @@ QtcPlugin { "projecttree.cpp", "projecttree.h", "projecttreewidget.cpp", "projecttreewidget.h", + "projectupdater.cpp", "projectupdater.h", "projectwindow.cpp", "projectwindow.h", "projectwizardpage.cpp", "projectwizardpage.h", "rawprojectpart.cpp", "rawprojectpart.h", diff --git a/src/plugins/projectexplorer/projectupdater.cpp b/src/plugins/projectexplorer/projectupdater.cpp new file mode 100644 index 00000000000..15143019f44 --- /dev/null +++ b/src/plugins/projectexplorer/projectupdater.cpp @@ -0,0 +1,58 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "projectupdater.h" + +#include "projectexplorerconstants.h" + +#include +#include +#include + +#include + +using namespace Utils; + +namespace ProjectExplorer { + +static QList &projectUpdaterFactories() +{ + static QList theProjectUpdaterFactories; + return theProjectUpdaterFactories; +} + +ProjectUpdaterFactory::ProjectUpdaterFactory() +{ + projectUpdaterFactories().append(this); +} + +ProjectUpdaterFactory::~ProjectUpdaterFactory() +{ + projectUpdaterFactories().removeOne(this); +} + +void ProjectUpdaterFactory::setLanguage(Id language) +{ + m_language = language; +} + +void ProjectUpdaterFactory::setCreator(const std::function &creator) +{ + m_creator = creator; +} + +ProjectUpdater *ProjectUpdaterFactory::createProjectUpdater(Id language) +{ + const QList &factories = projectUpdaterFactories(); + ProjectUpdaterFactory *factory = + findOrDefault(factories, equal(&ProjectUpdaterFactory::m_language, language)); + QTC_ASSERT(factory, return nullptr); + return factory->m_creator(); +} + +ProjectUpdater *ProjectUpdaterFactory::createCppProjectUpdater() +{ + return createProjectUpdater(Constants::CXX_LANGUAGE_ID); +} + +} // ProjectExplorer diff --git a/src/plugins/projectexplorer/projectupdater.h b/src/plugins/projectexplorer/projectupdater.h new file mode 100644 index 00000000000..ac448ec2fd0 --- /dev/null +++ b/src/plugins/projectexplorer/projectupdater.h @@ -0,0 +1,45 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "projectexplorer_export.h" + +#include + +#include + +namespace ProjectExplorer { + +class ProjectUpdateInfo; +class ExtraCompiler; + +class PROJECTEXPLORER_EXPORT ProjectUpdater +{ +public: + virtual ~ProjectUpdater() = default; + + virtual void update(const ProjectUpdateInfo &projectUpdateInfo, + const QList &extraCompilers = {}) = 0; + virtual void cancel() = 0; +}; + +class PROJECTEXPLORER_EXPORT ProjectUpdaterFactory +{ +public: + ProjectUpdaterFactory(); + ~ProjectUpdaterFactory(); + + static ProjectUpdater *createProjectUpdater(Utils::Id language); + static ProjectUpdater *createCppProjectUpdater(); // Convenience for C++. + +protected: + void setLanguage(Utils::Id language); + void setCreator(const std::function &creator); + +private: + std::function m_creator; + Utils::Id m_language; +}; + +} // namespace ProjectExplorer diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 737f7fc17e9..043d88199eb 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -38,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -151,7 +151,8 @@ static bool supportsNodeAction(ProjectAction action, const Node *node) QbsBuildSystem::QbsBuildSystem(QbsBuildConfiguration *bc) : BuildSystem(bc->target()), m_session(new QbsSession(this)), - m_cppCodeModelUpdater(new CppEditor::CppProjectUpdater), + m_cppCodeModelUpdater( + ProjectUpdaterFactory::createProjectUpdater(ProjectExplorer::Constants::CXX_LANGUAGE_ID)), m_buildConfiguration(bc) { connect(m_session, &QbsSession::newGeneratedFilesForSources, this, diff --git a/src/plugins/qbsprojectmanager/qbsproject.h b/src/plugins/qbsprojectmanager/qbsproject.h index e3dcc6f3466..cefda5869f8 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.h +++ b/src/plugins/qbsprojectmanager/qbsproject.h @@ -20,7 +20,7 @@ #include -namespace CppEditor { class CppProjectUpdater; } +namespace ProjectExplorer { class ProjectUpdater; } namespace QbsProjectManager { namespace Internal { @@ -136,7 +136,7 @@ private: Utils::Environment m_lastParseEnv; std::unique_ptr m_parseRequest; - CppEditor::CppProjectUpdater *m_cppCodeModelUpdater = nullptr; + ProjectExplorer::ProjectUpdater *m_cppCodeModelUpdater = nullptr; QHash m_sourcesForGeneratedFiles; QList m_extraCompilers; diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 53639778950..a21ed6bd72a 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include @@ -31,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -202,7 +202,7 @@ DeploymentKnowledge QmakeProject::deploymentKnowledge() const QmakeBuildSystem::QmakeBuildSystem(QmakeBuildConfiguration *bc) : BuildSystem(bc) , m_qmakeVfs(new QMakeVfs) - , m_cppCodeModelUpdater(new CppEditor::CppProjectUpdater) + , m_cppCodeModelUpdater(ProjectUpdaterFactory::createCppProjectUpdater()) { setParseDelay(0); diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.h b/src/plugins/qmakeprojectmanager/qmakeproject.h index 10f2a563709..62cd3c01b2c 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.h +++ b/src/plugins/qmakeprojectmanager/qmakeproject.h @@ -20,8 +20,11 @@ class QMakeGlobals; class QMakeVfs; QT_END_NAMESPACE -namespace CppEditor { class CppProjectUpdater; } -namespace ProjectExplorer { class DeploymentData; } +namespace ProjectExplorer { +class DeploymentData; +class ProjectUpdater; +} // ProjectExplorer + namespace QtSupport { class ProFileReader; } namespace QmakeProjectManager { @@ -193,7 +196,7 @@ private: bool m_cancelEvaluate = false; QList m_partialEvaluate; - CppEditor::CppProjectUpdater *m_cppCodeModelUpdater = nullptr; + ProjectExplorer::ProjectUpdater *m_cppCodeModelUpdater = nullptr; Internal::CentralizedFolderWatcher *m_centralizedFolderWatcher = nullptr; From 2a5a2ca9f098679af73b982b363577c7bd67c33e Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 20 Oct 2023 14:16:36 +0200 Subject: [PATCH 0072/1546] Meson: Remove dependency from CppEditor Not needed anymore. Change-Id: I597821a56d374a8d800f2fde43b78805ee1e0278 Reviewed-by: Reviewed-by: Eike Ziller --- src/plugins/mesonprojectmanager/CMakeLists.txt | 2 +- src/plugins/mesonprojectmanager/mesonprojectmanager.qbs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/mesonprojectmanager/CMakeLists.txt b/src/plugins/mesonprojectmanager/CMakeLists.txt index da8f32ef701..e3373b2011c 100644 --- a/src/plugins/mesonprojectmanager/CMakeLists.txt +++ b/src/plugins/mesonprojectmanager/CMakeLists.txt @@ -1,7 +1,7 @@ add_qtc_plugin(MesonProjectManager PLUGIN_CLASS MesonProjectPlugin DEPENDS QmlJS - PLUGIN_DEPENDS Core CppEditor ProjectExplorer TextEditor QtSupport + PLUGIN_DEPENDS Core ProjectExplorer TextEditor QtSupport SOURCES arrayoptionlineedit.cpp arrayoptionlineedit.h diff --git a/src/plugins/mesonprojectmanager/mesonprojectmanager.qbs b/src/plugins/mesonprojectmanager/mesonprojectmanager.qbs index b0c84579132..4b725e0f6ca 100644 --- a/src/plugins/mesonprojectmanager/mesonprojectmanager.qbs +++ b/src/plugins/mesonprojectmanager/mesonprojectmanager.qbs @@ -12,7 +12,6 @@ Project { Depends { name: "Utils" } Depends { name: "Core" } - Depends { name: "CppEditor" } Depends { name: "ProjectExplorer" } Depends { name: "QtSupport" } From bbbc9d3fa99d0c6b687ba2416f6ebf72281b1597 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 20 Oct 2023 14:11:20 +0200 Subject: [PATCH 0073/1546] AutoTools: Remove dependency from CppEditor Not needed anymore. Change-Id: Ie1b6faffc1cde6348d37c0f7c32f9621f6442b69 Reviewed-by: Eike Ziller Reviewed-by: --- src/plugins/autotoolsprojectmanager/CMakeLists.txt | 2 +- src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/plugins/autotoolsprojectmanager/CMakeLists.txt b/src/plugins/autotoolsprojectmanager/CMakeLists.txt index 261403ce8c5..83bdeaf6ccb 100644 --- a/src/plugins/autotoolsprojectmanager/CMakeLists.txt +++ b/src/plugins/autotoolsprojectmanager/CMakeLists.txt @@ -1,6 +1,6 @@ add_qtc_plugin(AutotoolsProjectManager PLUGIN_CLASS AutotoolsProjectPlugin - PLUGIN_DEPENDS Core CppEditor ProjectExplorer QtSupport + PLUGIN_DEPENDS Core ProjectExplorer QtSupport SOURCES autogenstep.cpp autogenstep.h autoreconfstep.cpp autoreconfstep.h diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs index d9da0c1af9d..960a718c310 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs +++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectmanager.qbs @@ -8,7 +8,6 @@ QtcPlugin { Depends { name: "Core" } Depends { name: "ProjectExplorer" } - Depends { name: "CppEditor" } Depends { name: "QtSupport" } files: [ From 24d4cb65761b50d1cb5a4872b58220880212e966 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 3 Nov 2023 15:43:44 +0100 Subject: [PATCH 0074/1546] ProjectExplorer: Make the MAKEFLAGS warning self-explanatory Fixes: QTCREATORBUG-29816 Change-Id: If35fe74c52ec1c890f390eb0a645299ce9e926b4 Reviewed-by: Christian Stenger Reviewed-by: --- src/plugins/projectexplorer/makestep.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/plugins/projectexplorer/makestep.cpp b/src/plugins/projectexplorer/makestep.cpp index bcf3bab8f02..7929f2e325e 100644 --- a/src/plugins/projectexplorer/makestep.cpp +++ b/src/plugins/projectexplorer/makestep.cpp @@ -67,11 +67,6 @@ MakeStep::MakeStep(BuildStepList *parent, Id id) m_overrideMakeflagsAspect.setSettingsKey(id.toKey() + OVERRIDE_MAKEFLAGS_SUFFIX); m_overrideMakeflagsAspect.setLabel(text, BoolAspect::LabelPlacement::AtCheckBox); - m_nonOverrideWarning.setText("

" + - Tr::tr("MAKEFLAGS specifies parallel jobs. Check \"%1\" to override.") - .arg(text) + "

"); - m_nonOverrideWarning.setIconType(InfoLabel::Warning); - m_disabledForSubdirsAspect.setSettingsKey(id.toKey() + ".disabledForSubdirs"); m_disabledForSubdirsAspect.setLabel(Tr::tr("Disable in subdirectories:")); m_disabledForSubdirsAspect.setToolTip(Tr::tr("Runs this step only for a top-level build.")); @@ -354,8 +349,22 @@ QWidget *MakeStep::createConfigWidget() const bool jobCountEnabled = !userArgsContainsJobCount(); m_jobCountAspect.setEnabled(jobCountEnabled); m_overrideMakeflagsAspect.setEnabled(jobCountEnabled); - m_nonOverrideWarning.setVisible(makeflagsJobCountMismatch() - && !jobCountOverridesMakeflags()); + + QString warningText; + InfoLabel::InfoType iconType = InfoLabel::Information; + if (makeflagsJobCountMismatch()) { + if (m_overrideMakeflagsAspect.value()) { + warningText = Tr::tr("Overriding MAKEFLAGS environment variable."); + } else { + warningText = Tr::tr("MAKEFLAGS specifies a conflicting job count."); + iconType = InfoLabel::Warning; + } + } else { + warningText = Tr::tr("No conflict with MAKEFLAGS environment variable."); + } + m_nonOverrideWarning.setText(QString::fromLatin1("

%1

") + .arg(warningText)); + m_nonOverrideWarning.setIconType(iconType); }; updateDetails(); From 0dbd951654d044de483501377cfa48083038c9b7 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 6 Nov 2023 16:03:49 +0100 Subject: [PATCH 0075/1546] CppEditor: FilePath-ify SymbolSearcher Change-Id: Iff29c4c6287d12a361174264332e8734e914050a Reviewed-by: Reviewed-by: Christian Kandeler --- src/plugins/cppeditor/cppindexingsupport.cpp | 6 +++--- src/plugins/cppeditor/cppindexingsupport.h | 6 ++++-- src/plugins/cppeditor/symbolsearcher_test.cpp | 4 +++- src/plugins/cppeditor/symbolsfindfilter.cpp | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/plugins/cppeditor/cppindexingsupport.cpp b/src/plugins/cppeditor/cppindexingsupport.cpp index ada400556e5..21a5da4109f 100644 --- a/src/plugins/cppeditor/cppindexingsupport.cpp +++ b/src/plugins/cppeditor/cppindexingsupport.cpp @@ -30,10 +30,10 @@ namespace CppEditor { static Q_LOGGING_CATEGORY(indexerLog, "qtc.cppeditor.indexer", QtWarningMsg) SymbolSearcher::SymbolSearcher(const SymbolSearcher::Parameters ¶meters, - const QSet &fileNames) + const QSet &filePaths) : m_snapshot(CppModelManager::snapshot()) , m_parameters(parameters) - , m_fileNames(fileNames) + , m_filePaths(filePaths) {} namespace { @@ -261,7 +261,7 @@ void SymbolSearcher::runSearch(QPromise &promise) promise.suspendIfRequested(); if (promise.isCanceled()) break; - if (m_fileNames.isEmpty() || m_fileNames.contains(it.value()->filePath().path())) { + if (m_filePaths.isEmpty() || m_filePaths.contains(it.value()->filePath())) { SearchResultItems resultItems; auto filter = [&](const IndexItem::Ptr &info) -> IndexItem::VisitorResult { if (matcher.match(info->symbolName()).hasMatch()) { diff --git a/src/plugins/cppeditor/cppindexingsupport.h b/src/plugins/cppeditor/cppindexingsupport.h index 9995ca631cd..c04eb8ba76f 100644 --- a/src/plugins/cppeditor/cppindexingsupport.h +++ b/src/plugins/cppeditor/cppindexingsupport.h @@ -43,13 +43,15 @@ public: SearchScope scope; }; - SymbolSearcher(const SymbolSearcher::Parameters ¶meters, const QSet &fileNames); + SymbolSearcher(const SymbolSearcher::Parameters ¶meters, + const QSet &filePaths); + void runSearch(QPromise &promise); private: const CPlusPlus::Snapshot m_snapshot; const Parameters m_parameters; - const QSet m_fileNames; + const QSet m_filePaths; }; class CPPEDITOR_EXPORT CppIndexingSupport diff --git a/src/plugins/cppeditor/symbolsearcher_test.cpp b/src/plugins/cppeditor/symbolsearcher_test.cpp index 688df3d924f..a429dd186f1 100644 --- a/src/plugins/cppeditor/symbolsearcher_test.cpp +++ b/src/plugins/cppeditor/symbolsearcher_test.cpp @@ -14,6 +14,8 @@ #include +using namespace Utils; + namespace { QTC_DECLARE_MYTESTDATADIR("../../../tests/cppsymbolsearcher/") @@ -76,7 +78,7 @@ public: QVERIFY(parseFiles(testFile)); const QScopedPointer symbolSearcher( - new SymbolSearcher(searchParameters, QSet{testFile})); + new SymbolSearcher(searchParameters, QSet{FilePath::fromString(testFile)})); QFuture search = Utils::asyncRun(&SymbolSearcher::runSearch, symbolSearcher.data()); search.waitForFinished(); diff --git a/src/plugins/cppeditor/symbolsfindfilter.cpp b/src/plugins/cppeditor/symbolsfindfilter.cpp index bd05107c646..f53fd34c4d1 100644 --- a/src/plugins/cppeditor/symbolsfindfilter.cpp +++ b/src/plugins/cppeditor/symbolsfindfilter.cpp @@ -107,10 +107,10 @@ void SymbolsFindFilter::findAll(const QString &txt, FindFlags findFlags) void SymbolsFindFilter::startSearch(SearchResult *search) { SymbolSearcher::Parameters parameters = search->userData().value(); - QSet projectFileNames; + QSet projectFileNames; if (parameters.scope == SymbolSearcher::SearchProjectsOnly) { for (ProjectExplorer::Project *project : ProjectExplorer::ProjectManager::projects()) - projectFileNames += Utils::transform(project->files(ProjectExplorer::Project::AllFiles), &Utils::FilePath::toString); + projectFileNames += Utils::toSet(project->files(ProjectExplorer::Project::AllFiles)); } auto watcher = new QFutureWatcher; From b2e96147cbfbd5b81b162622feb1c2cb46e0f8a6 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Tue, 24 Oct 2023 18:12:09 +0200 Subject: [PATCH 0076/1546] Utils: Turn "Util.asciify" into a plain macro This monves the asciify function to stringutils and makes it directly available as "asciify:" prefix macro, so that the generation of a default build path does not go through JavaScript. "Util.asciify" remains available as core JavaScript extension for the case that it is used by third party code/wizards. This change also adds a test to tst_stringutils Change-Id: Iba2f20c0415ee8fe757c2f0058a90629b3fbeff0 Reviewed-by: hjk --- src/libs/utils/stringutils.cpp | 12 ++++++++++ src/libs/utils/stringutils.h | 2 ++ src/plugins/coreplugin/corejsextensions.cpp | 9 +------- src/plugins/coreplugin/coreplugin.cpp | 3 +++ .../buildpropertiessettings.cpp | 2 +- .../utils/stringutils/tst_stringutils.cpp | 22 +++++++++++++++++++ 6 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/libs/utils/stringutils.cpp b/src/libs/utils/stringutils.cpp index c3b6c596905..d8de512b32d 100644 --- a/src/libs/utils/stringutils.cpp +++ b/src/libs/utils/stringutils.cpp @@ -346,6 +346,18 @@ QString quoteAmpersands(const QString &text) return result.replace("&", "&&"); } +QString asciify(const QString &input) +{ + QString result; + for (const QChar &c : input) { + if (c.isPrint() && c.unicode() < 128) + result.append(c); + else + result.append(QString::fromLatin1("u%1").arg(c.unicode(), 4, 16, QChar('0'))); + } + return result; +} + QString formatElapsedTime(qint64 elapsed) { elapsed += 500; // round up diff --git a/src/libs/utils/stringutils.h b/src/libs/utils/stringutils.h index b27a2efc6f0..8ce794693da 100644 --- a/src/libs/utils/stringutils.h +++ b/src/libs/utils/stringutils.h @@ -32,6 +32,8 @@ QTCREATOR_UTILS_EXPORT QString commonPrefix(const QStringList &strings); QTCREATOR_UTILS_EXPORT QString stripAccelerator(const QString &text); // Quotes all ampersands QTCREATOR_UTILS_EXPORT QString quoteAmpersands(const QString &text); +// Convert non-ascii characters into foobar +QTCREATOR_UTILS_EXPORT QString asciify(const QString &input); QTCREATOR_UTILS_EXPORT bool readMultiLineString(const QJsonValue &value, QString *out); diff --git a/src/plugins/coreplugin/corejsextensions.cpp b/src/plugins/coreplugin/corejsextensions.cpp index cbbb71246ea..28f4790c2b6 100644 --- a/src/plugins/coreplugin/corejsextensions.cpp +++ b/src/plugins/coreplugin/corejsextensions.cpp @@ -139,14 +139,7 @@ QString UtilsJsExtension::mktemp(const QString &pattern) const QString UtilsJsExtension::asciify(const QString &input) const { - QString result; - for (const QChar &c : input) { - if (c.isPrint() && c.unicode() < 128) - result.append(c); - else - result.append(QString::fromLatin1("u%1").arg(c.unicode(), 4, 16, QChar('0'))); - } - return result; + return Utils::asciify(input); } QString UtilsJsExtension::qtQuickVersion(const QString &filePath) const diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp index 17f1a08031f..313b3e2bc3d 100644 --- a/src/plugins/coreplugin/coreplugin.cpp +++ b/src/plugins/coreplugin/coreplugin.cpp @@ -232,6 +232,9 @@ bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage) [] { return QUuid::createUuid().toString(); }); expander->registerPrefix("#:", Tr::tr("A comment."), [](const QString &) { return QString(); }); + expander->registerPrefix("asciify:", Tr::tr("Convert string into pure ascii."), + [expander] (const QString &s) { + return asciify(expander->expand(s)); }); Utils::PathChooser::setAboutToShowContextMenuHandler(&CorePlugin::addToPathChooserContextMenu); diff --git a/src/plugins/projectexplorer/buildpropertiessettings.cpp b/src/plugins/projectexplorer/buildpropertiessettings.cpp index 09c373befb2..07264c49f89 100644 --- a/src/plugins/projectexplorer/buildpropertiessettings.cpp +++ b/src/plugins/projectexplorer/buildpropertiessettings.cpp @@ -16,7 +16,7 @@ namespace ProjectExplorer { static QString defaultBuildDirectoryTemplate() { - return "../%{JS: Util.asciify(\"build-%{Project:Name}-%{Kit:FileSystemName}-%{BuildConfig:Name}\")}"; + return "../%{asciify:build-%{Project:Name}-%{Kit:FileSystemName}-%{BuildConfig:Name}}"; } BuildPropertiesSettings &buildPropertiesSettings() diff --git a/tests/auto/utils/stringutils/tst_stringutils.cpp b/tests/auto/utils/stringutils/tst_stringutils.cpp index 4863bfd9508..7442c06daa6 100644 --- a/tests/auto/utils/stringutils/tst_stringutils.cpp +++ b/tests/auto/utils/stringutils/tst_stringutils.cpp @@ -81,6 +81,8 @@ private slots: void testWildcardToRegularExpression(); void testSplitAtFirst_data(); void testSplitAtFirst(); + void testAsciify_data(); + void testAsciify(); private: TestMacroExpander mx; @@ -438,6 +440,26 @@ void tst_StringUtils::testSplitAtFirst() QCOMPARE(r, right); } +void tst_StringUtils::testAsciify_data() +{ + QTest::addColumn("input"); + QTest::addColumn("expected"); + + QTest::newRow("Basic Latin") << QString("Basic text") << QString("Basic text"); + QTest::newRow("Control character") << QString("\x07 text") << QString("u0007 text"); + QTest::newRow("Miscellaneous Technical") << QString("\u23F0 text") << QString("u23f0 text"); +} + +void tst_StringUtils::testAsciify() +{ + QFETCH(QString, input); + QFETCH(QString, expected); + + const QString asciified = Utils::asciify(input); + + QCOMPARE(asciified, expected); +} + QTEST_GUILESS_MAIN(tst_StringUtils) #include "tst_stringutils.moc" From 6d50724937b1ce1c22143d40bef8ad2c9f8ac3ba Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Tue, 7 Nov 2023 10:44:08 +0100 Subject: [PATCH 0077/1546] Core: Rename "asciify" macro to "Asciify" By convention, macro names start with a capital letter. Amends: b2e96147cbfbd5b81b162622feb1c2cb46e0f8a6 Change-Id: I2aa93deee7aec798128371d7f81a9c6fc9dd85c2 Reviewed-by: Eike Ziller --- src/plugins/coreplugin/coreplugin.cpp | 2 +- src/plugins/projectexplorer/buildpropertiessettings.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp index 313b3e2bc3d..8941e617321 100644 --- a/src/plugins/coreplugin/coreplugin.cpp +++ b/src/plugins/coreplugin/coreplugin.cpp @@ -232,7 +232,7 @@ bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage) [] { return QUuid::createUuid().toString(); }); expander->registerPrefix("#:", Tr::tr("A comment."), [](const QString &) { return QString(); }); - expander->registerPrefix("asciify:", Tr::tr("Convert string into pure ascii."), + expander->registerPrefix("Asciify:", Tr::tr("Convert string into pure ascii."), [expander] (const QString &s) { return asciify(expander->expand(s)); }); diff --git a/src/plugins/projectexplorer/buildpropertiessettings.cpp b/src/plugins/projectexplorer/buildpropertiessettings.cpp index 07264c49f89..774870c8889 100644 --- a/src/plugins/projectexplorer/buildpropertiessettings.cpp +++ b/src/plugins/projectexplorer/buildpropertiessettings.cpp @@ -16,7 +16,7 @@ namespace ProjectExplorer { static QString defaultBuildDirectoryTemplate() { - return "../%{asciify:build-%{Project:Name}-%{Kit:FileSystemName}-%{BuildConfig:Name}}"; + return "../%{Asciify:build-%{Project:Name}-%{Kit:FileSystemName}-%{BuildConfig:Name}}"; } BuildPropertiesSettings &buildPropertiesSettings() From 65341d7e5fc4fa7e4493e780cf2ae309bd4a64f7 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 26 Oct 2023 17:44:37 +0200 Subject: [PATCH 0078/1546] TaskTree: Introduce QProcessTask with internal reaper In order to make it possible to use QProcess in TaskTree outside of QtCreator. Change-Id: Icff4113a7799297c5941ee68ee1cc874806c3816 Reviewed-by: Qt CI Bot Reviewed-by: hjk Reviewed-by: --- src/libs/solutions/tasking/CMakeLists.txt | 1 + src/libs/solutions/tasking/qprocesstask.cpp | 265 ++++++++++++++++++++ src/libs/solutions/tasking/qprocesstask.h | 43 ++++ src/libs/solutions/tasking/tasking.qbs | 2 + 4 files changed, 311 insertions(+) create mode 100644 src/libs/solutions/tasking/qprocesstask.cpp create mode 100644 src/libs/solutions/tasking/qprocesstask.h diff --git a/src/libs/solutions/tasking/CMakeLists.txt b/src/libs/solutions/tasking/CMakeLists.txt index ae51b12a7bd..717163e1685 100644 --- a/src/libs/solutions/tasking/CMakeLists.txt +++ b/src/libs/solutions/tasking/CMakeLists.txt @@ -6,6 +6,7 @@ add_qtc_library(Tasking OBJECT barrier.cpp barrier.h concurrentcall.h networkquery.cpp networkquery.h + qprocesstask.cpp qprocesstask.h tasking_global.h tasktree.cpp tasktree.h EXPLICIT_MOC diff --git a/src/libs/solutions/tasking/qprocesstask.cpp b/src/libs/solutions/tasking/qprocesstask.cpp new file mode 100644 index 00000000000..7d63e658478 --- /dev/null +++ b/src/libs/solutions/tasking/qprocesstask.cpp @@ -0,0 +1,265 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "qprocesstask.h" + +#include +#include +#include +#include +#include +#include + +namespace Tasking { + +class ProcessReaperPrivate; + +class ProcessReaper final +{ +public: + static void reap(QProcess *process, int timeoutMs = 500); + ProcessReaper(); + ~ProcessReaper(); + +private: + static ProcessReaper *instance(); + + QThread m_thread; + ProcessReaperPrivate *m_private; +}; + +static const int s_timeoutThreshold = 10000; // 10 seconds + +static QString execWithArguments(QProcess *process) +{ + QStringList commandLine; + commandLine.append(process->program()); + commandLine.append(process->arguments()); + return commandLine.join(QChar::Space); +} + +struct ReaperSetup +{ + QProcess *m_process = nullptr; + int m_timeoutMs; +}; + +class Reaper : public QObject +{ + Q_OBJECT + +public: + Reaper(const ReaperSetup &reaperSetup) : m_reaperSetup(reaperSetup) {} + + void reap() + { + m_timer.start(); + connect(m_reaperSetup.m_process, &QProcess::finished, this, &Reaper::handleFinished); + if (emitFinished()) + return; + terminate(); + } + +signals: + void finished(); + +private: + void terminate() + { + m_reaperSetup.m_process->terminate(); + QTimer::singleShot(m_reaperSetup.m_timeoutMs, this, &Reaper::handleTerminateTimeout); + } + + void kill() { m_reaperSetup.m_process->kill(); } + + bool emitFinished() + { + if (m_reaperSetup.m_process->state() != QProcess::NotRunning) + return false; + + if (!m_finished) { + const int timeout = m_timer.elapsed(); + if (timeout > s_timeoutThreshold) { + qWarning() << "Finished parallel reaping of" << execWithArguments(m_reaperSetup.m_process) + << "in" << (timeout / 1000.0) << "seconds."; + } + + m_finished = true; + emit finished(); + } + return true; + } + + void handleFinished() + { + if (emitFinished()) + return; + qWarning() << "Finished process still running..."; + // In case the process is still running - wait until it has finished + QTimer::singleShot(m_reaperSetup.m_timeoutMs, this, &Reaper::handleFinished); + } + + void handleTerminateTimeout() + { + if (emitFinished()) + return; + kill(); + } + + bool m_finished = false; + QElapsedTimer m_timer; + const ReaperSetup m_reaperSetup; +}; + +class ProcessReaperPrivate : public QObject +{ + Q_OBJECT + +public: + // Called from non-reaper's thread + void scheduleReap(const ReaperSetup &reaperSetup) + { + if (QThread::currentThread() == thread()) + qWarning() << "Can't schedule reap from the reaper internal thread."; + + QMutexLocker locker(&m_mutex); + m_reaperSetupList.append(reaperSetup); + QMetaObject::invokeMethod(this, &ProcessReaperPrivate::flush); + } + + // Called from non-reaper's thread + void waitForFinished() + { + if (QThread::currentThread() == thread()) + qWarning() << "Can't wait for finished from the reaper internal thread."; + + QMetaObject::invokeMethod(this, &ProcessReaperPrivate::flush, + Qt::BlockingQueuedConnection); + QMutexLocker locker(&m_mutex); + if (m_reaperList.isEmpty()) + return; + + m_waitCondition.wait(&m_mutex); + } + +private: + // All the private methods are called from the reaper's thread + QList takeReaperSetupList() + { + QMutexLocker locker(&m_mutex); + return std::exchange(m_reaperSetupList, {}); + } + + void flush() + { + while (true) { + const QList reaperSetupList = takeReaperSetupList(); + if (reaperSetupList.isEmpty()) + return; + for (const ReaperSetup &reaperSetup : reaperSetupList) + reap(reaperSetup); + } + } + + void reap(const ReaperSetup &reaperSetup) + { + Reaper *reaper = new Reaper(reaperSetup); + connect(reaper, &Reaper::finished, this, [this, reaper, process = reaperSetup.m_process] { + QMutexLocker locker(&m_mutex); + const bool isRemoved = m_reaperList.removeOne(reaper); + if (!isRemoved) + qWarning() << "Reaper list doesn't contain the finished process."; + + delete reaper; + delete process; + if (m_reaperList.isEmpty()) + m_waitCondition.wakeOne(); + }, Qt::QueuedConnection); + + { + QMutexLocker locker(&m_mutex); + m_reaperList.append(reaper); + } + + reaper->reap(); + } + + QMutex m_mutex; + QWaitCondition m_waitCondition; + QList m_reaperSetupList; + QList m_reaperList; +}; + +static ProcessReaper *s_instance = nullptr; +static QMutex s_instanceMutex; + +// Call me with s_instanceMutex locked. +ProcessReaper *ProcessReaper::instance() +{ + if (!s_instance) + s_instance = new ProcessReaper; + return s_instance; +} + +ProcessReaper::ProcessReaper() + : m_private(new ProcessReaperPrivate) +{ + m_private->moveToThread(&m_thread); + QObject::connect(&m_thread, &QThread::finished, m_private, &QObject::deleteLater); + m_thread.start(); + m_thread.moveToThread(qApp->thread()); +} + +ProcessReaper::~ProcessReaper() +{ + if (QThread::currentThread() != qApp->thread()) + qWarning() << "Destructing process reaper from non-main thread."; + + instance()->m_private->waitForFinished(); + m_thread.quit(); + m_thread.wait(); +} + +void ProcessReaper::reap(QProcess *process, int timeoutMs) +{ + if (!process) + return; + + if (QThread::currentThread() != process->thread()) { + qWarning() << "Can't reap process from non-process's thread."; + return; + } + + process->disconnect(); + if (process->state() == QProcess::NotRunning) { + delete process; + return; + } + + // Neither can move object with a parent into a different thread + // nor reaping the process with a parent makes any sense. + process->setParent(nullptr); + + QMutexLocker locker(&s_instanceMutex); + ProcessReaperPrivate *priv = instance()->m_private; + + process->moveToThread(priv->thread()); + ReaperSetup reaperSetup {process, timeoutMs}; + priv->scheduleReap(reaperSetup); +} + +void QProcessDeleter::deleteAll() +{ + QMutexLocker locker(&s_instanceMutex); + delete s_instance; + s_instance = nullptr; +} + +void QProcessDeleter::operator()(QProcess *process) +{ + ProcessReaper::reap(process); +} + +} // namespace Tasking + +#include "qprocesstask.moc" diff --git a/src/libs/solutions/tasking/qprocesstask.h b/src/libs/solutions/tasking/qprocesstask.h new file mode 100644 index 00000000000..5cec4890e6f --- /dev/null +++ b/src/libs/solutions/tasking/qprocesstask.h @@ -0,0 +1,43 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "tasking_global.h" + +#include "tasktree.h" + +#include + +namespace Tasking { + +class TASKING_EXPORT QProcessDeleter +{ +public: + // Blocking, should be called after all QProcessAdapter instances are deleted. + static void deleteAll(); + void operator()(QProcess *process); +}; + +class TASKING_EXPORT QProcessAdapter : public TaskAdapter +{ +private: + void start() { + connect(task(), &QProcess::finished, this, [this] { + const bool success = task()->exitStatus() == QProcess::NormalExit + && task()->error() == QProcess::UnknownError + && task()->exitCode() == 0; + emit done(success); + }); + connect(task(), &QProcess::errorOccurred, this, [this](QProcess::ProcessError error) { + if (error != QProcess::FailedToStart) + return; + emit done(false); + }); + task()->start(); + } +}; + +using QProcessTask = CustomTask; + +} // namespace Tasking diff --git a/src/libs/solutions/tasking/tasking.qbs b/src/libs/solutions/tasking/tasking.qbs index fba42b10b1d..7840812faab 100644 --- a/src/libs/solutions/tasking/tasking.qbs +++ b/src/libs/solutions/tasking/tasking.qbs @@ -11,6 +11,8 @@ QtcLibrary { "concurrentcall.h", "networkquery.cpp", "networkquery.h", + "qprocesstask.cpp", + "qprocesstask.h", "tasking_global.h", "tasktree.cpp", "tasktree.h", From 63bfeba87f3ce2d42655548dfb097dc9e0bf26ab Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 27 Oct 2023 10:50:30 +0200 Subject: [PATCH 0079/1546] TaskTree: Add a test for QProcessTask Change-Id: If49ec3dded8ce92a2a78b55ce95b56e8683de1f5 Reviewed-by: Reviewed-by: hjk --- tests/auto/solutions/CMakeLists.txt | 1 + .../solutions/qprocesstask/CMakeLists.txt | 7 ++++ .../solutions/qprocesstask/qprocesstask.qbs | 25 ++++++++++++ .../qprocesstask/testsleep/CMakeLists.txt | 9 +++++ .../solutions/qprocesstask/testsleep/main.cpp | 12 ++++++ .../qprocesstask/testsleep/testsleep.qbs | 12 ++++++ .../qprocesstask/tst_qprocesstask.cpp | 40 +++++++++++++++++++ tests/auto/solutions/solutions.qbs | 1 + 8 files changed, 107 insertions(+) create mode 100644 tests/auto/solutions/qprocesstask/CMakeLists.txt create mode 100644 tests/auto/solutions/qprocesstask/qprocesstask.qbs create mode 100644 tests/auto/solutions/qprocesstask/testsleep/CMakeLists.txt create mode 100644 tests/auto/solutions/qprocesstask/testsleep/main.cpp create mode 100644 tests/auto/solutions/qprocesstask/testsleep/testsleep.qbs create mode 100644 tests/auto/solutions/qprocesstask/tst_qprocesstask.cpp diff --git a/tests/auto/solutions/CMakeLists.txt b/tests/auto/solutions/CMakeLists.txt index 694d940195d..848b48eca9a 100644 --- a/tests/auto/solutions/CMakeLists.txt +++ b/tests/auto/solutions/CMakeLists.txt @@ -1 +1,2 @@ +add_subdirectory(qprocesstask) add_subdirectory(tasking) diff --git a/tests/auto/solutions/qprocesstask/CMakeLists.txt b/tests/auto/solutions/qprocesstask/CMakeLists.txt new file mode 100644 index 00000000000..dab250943cf --- /dev/null +++ b/tests/auto/solutions/qprocesstask/CMakeLists.txt @@ -0,0 +1,7 @@ +add_subdirectory(testsleep) + +add_qtc_test(tst_qprocesstask + DEFINES "PROCESS_TESTAPP=\"${CMAKE_CURRENT_BINARY_DIR}/testsleep\"" + DEPENDS Tasking Qt::Network + SOURCES tst_qprocesstask.cpp +) diff --git a/tests/auto/solutions/qprocesstask/qprocesstask.qbs b/tests/auto/solutions/qprocesstask/qprocesstask.qbs new file mode 100644 index 00000000000..c1bc1ce889d --- /dev/null +++ b/tests/auto/solutions/qprocesstask/qprocesstask.qbs @@ -0,0 +1,25 @@ +import qbs.FileInfo + +Project { + QtcAutotest { + name: "QProcessTask autotest" + + Depends { name: "Qt"; submodules: ["network"] } + Depends { name: "Tasking" } + + files: [ + "tst_qprocesstask.cpp", + ] + cpp.defines: { + var defines = base; + if (qbs.targetOS === "windows") + defines.push("_CRT_SECURE_NO_WARNINGS"); + defines.push('PROCESS_TESTAPP="' + + FileInfo.joinPaths(destinationDirectory, "testsleep") + '"'); + return defines; + } + destinationDirectory: project.buildDirectory + '/' + + FileInfo.relativePath(project.ide_source_tree, sourceDirectory) + } + references: "testsleep/testsleep.qbs" +} diff --git a/tests/auto/solutions/qprocesstask/testsleep/CMakeLists.txt b/tests/auto/solutions/qprocesstask/testsleep/CMakeLists.txt new file mode 100644 index 00000000000..b1e6ceffe4e --- /dev/null +++ b/tests/auto/solutions/qprocesstask/testsleep/CMakeLists.txt @@ -0,0 +1,9 @@ +add_qtc_executable(testsleep + SOURCES main.cpp + SKIP_INSTALL + INTERNAL_ONLY +) + +set_target_properties(testsleep PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" +) diff --git a/tests/auto/solutions/qprocesstask/testsleep/main.cpp b/tests/auto/solutions/qprocesstask/testsleep/main.cpp new file mode 100644 index 00000000000..cfe8752e02a --- /dev/null +++ b/tests/auto/solutions/qprocesstask/testsleep/main.cpp @@ -0,0 +1,12 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include + +using namespace std; + +int main() +{ + this_thread::sleep_for(10s); + return 0; +} diff --git a/tests/auto/solutions/qprocesstask/testsleep/testsleep.qbs b/tests/auto/solutions/qprocesstask/testsleep/testsleep.qbs new file mode 100644 index 00000000000..ae9bbd9431d --- /dev/null +++ b/tests/auto/solutions/qprocesstask/testsleep/testsleep.qbs @@ -0,0 +1,12 @@ +import qbs.FileInfo + +QtApplication { + name: "testsleep" + + consoleApplication: true + + install: false + files: [ + "main.cpp", + ] +} diff --git a/tests/auto/solutions/qprocesstask/tst_qprocesstask.cpp b/tests/auto/solutions/qprocesstask/tst_qprocesstask.cpp new file mode 100644 index 00000000000..f4bff2e0981 --- /dev/null +++ b/tests/auto/solutions/qprocesstask/tst_qprocesstask.cpp @@ -0,0 +1,40 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include + +#include + +using namespace Tasking; + +class tst_QProcessTask : public QObject +{ + Q_OBJECT + +private slots: + void qProcessTask(); +}; + +#ifdef Q_OS_WIN +static const char s_processName[] = "testsleep.exe"; +#else +static const char s_processName[] = "testsleep"; +#endif + +void tst_QProcessTask::qProcessTask() +{ + const auto setupProcess = [](QProcess &process) { + process.setProgram(QLatin1String(PROCESS_TESTAPP) + '/' + s_processName); + }; + + { + TaskTree taskTree({QProcessTask(setupProcess)}); + taskTree.start(); + QTRY_VERIFY(taskTree.isRunning()); + } + QProcessDeleter::deleteAll(); +} + +QTEST_GUILESS_MAIN(tst_QProcessTask) + +#include "tst_qprocesstask.moc" diff --git a/tests/auto/solutions/solutions.qbs b/tests/auto/solutions/solutions.qbs index cc445753cc2..b96095f3dbe 100644 --- a/tests/auto/solutions/solutions.qbs +++ b/tests/auto/solutions/solutions.qbs @@ -3,6 +3,7 @@ import qbs Project { name: "Solutions autotests" references: [ + "qprocesstask/qprocesstask.qbs", "tasking/tasking.qbs", ] } From 6e6aa7102c03b58adbfb0e414f040f49a90394f9 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 2 Nov 2023 18:47:38 +0100 Subject: [PATCH 0080/1546] TaskTree: Introduce CallDoneIf enum Get rid of CustomTask c'tor taking 3 handlers. If the done handler needs to be called only on success or an error, add explicit 3rd arg of CallDoneIf type. Task-number: QTCREATORBUG-29834 Change-Id: I10e55415587e6cac46620dd5177ad8269584583c Reviewed-by: hjk Reviewed-by: --- src/libs/solutions/tasking/tasktree.cpp | 11 ++++-- src/libs/solutions/tasking/tasktree.h | 34 ++++++++++++------- src/plugins/autotest/testcodeparser.cpp | 4 +-- .../clangcodemodel/clangdlocatorfilters.cpp | 4 +-- src/plugins/clangtools/clangtool.cpp | 7 ++-- .../cmakeprojectmanager/cmakebuildstep.cpp | 2 +- .../coreplugin/locator/directoryfilter.cpp | 6 ++-- .../coreplugin/locator/ilocatorfilter.cpp | 2 +- .../coreplugin/plugininstallwizard.cpp | 4 +-- src/plugins/cppeditor/cppprojectupdater.cpp | 5 +-- src/plugins/debugger/loadcoredialog.cpp | 10 +++--- src/plugins/diffeditor/diffeditorplugin.cpp | 4 +-- src/plugins/git/branchview.cpp | 4 +-- src/plugins/git/gitclient.cpp | 32 ++++++++--------- src/plugins/help/helpindexfilter.cpp | 2 +- src/plugins/languageclient/locatorfilter.cpp | 4 +-- src/plugins/mercurial/mercurialclient.cpp | 4 +-- src/plugins/projectexplorer/extracompiler.cpp | 6 ++-- .../qnx/qnxdeployqtlibrariesdialog.cpp | 18 +++++----- src/plugins/qnx/qnxdevicetester.cpp | 2 +- src/plugins/qnx/slog2inforunner.cpp | 4 +-- .../remotelinux/filesystemaccess_test.cpp | 16 ++++----- src/plugins/remotelinux/genericdeploystep.cpp | 8 ++--- .../remotelinux/genericdirectuploadstep.cpp | 12 +++---- src/plugins/subversion/subversionclient.cpp | 2 +- src/plugins/updateinfo/updateinfoplugin.cpp | 12 +++---- src/plugins/valgrind/valgrindprocess.cpp | 2 +- tests/auto/solutions/tasking/tst_tasking.cpp | 24 ++++++------- tests/auto/utils/async/tst_async.cpp | 30 ++++++++-------- 29 files changed, 148 insertions(+), 127 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 348481c8fc9..f7c44d8aaf0 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -964,7 +964,7 @@ GroupItem GroupItem::withTimeout(const GroupItem &item, milliseconds timeout, Group { finishAllAndError, TimeoutTask([timeout](milliseconds &timeoutData) { timeoutData = timeout; }, - taskHandler) + taskHandler, CallDoneIf::Success) }, item }; @@ -1483,9 +1483,16 @@ void TaskNode::stop() m_task.reset(); } +static bool shouldCall(CallDoneIf callDoneIf, bool success) +{ + if (success) + return callDoneIf != CallDoneIf::Error; + return callDoneIf != CallDoneIf::Success; +} + void TaskNode::invokeDoneHandler(bool success) { - if (m_taskHandler.m_doneHandler) + if (m_taskHandler.m_doneHandler && shouldCall(m_taskHandler.m_callDoneIf, success)) invokeHandler(parentContainer(), m_taskHandler.m_doneHandler, *m_task.get(), success); m_container.m_constData.m_taskTreePrivate->advanceProgress(1); } diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 99edad20272..f09ec80ed7e 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -112,7 +112,8 @@ private: // 4. Always run all children, let them finish, ignore their results and report done afterwards. // 5. Always run all children, let them finish, ignore their results and report error afterwards. -enum class WorkflowPolicy { +enum class WorkflowPolicy +{ StopOnError, // 1a - Reports error on first child error, otherwise done (if all children were done). ContinueOnError, // 1b - The same, but children execution continues. Reports done when no children. StopOnDone, // 2a - Reports done on first child done, otherwise error (if all children were error). @@ -131,6 +132,14 @@ enum class SetupResult }; Q_ENUM_NS(SetupResult); +enum class CallDoneIf +{ + SuccessOrError, + Success, + Error +}; +Q_ENUM_NS(CallDoneIf); + class TASKING_EXPORT GroupItem { public: @@ -149,6 +158,7 @@ public: TaskCreateHandler m_createHandler; TaskSetupHandler m_setupHandler = {}; TaskDoneHandler m_doneHandler = {}; + CallDoneIf m_callDoneIf = CallDoneIf::SuccessOrError; }; struct GroupHandler { @@ -330,13 +340,15 @@ public: static Adapter *createAdapter() { return new Adapter; } CustomTask() : GroupItem({&createAdapter}) {} template - CustomTask(SetupHandler &&setup, const EndFunction &done = {}, const EndFunction &error = {}) - : GroupItem({&createAdapter, wrapSetup(std::forward(setup)), - wrapEnds(done, error)}) {} + CustomTask(SetupHandler &&setup, const EndFunction &done, CallDoneIf callDoneIf) + : GroupItem({&createAdapter, wrapSetup(std::forward(setup)), wrapEnd(done), + callDoneIf}) {} template - CustomTask(SetupHandler &&setup, const DoneFunction &done) - : GroupItem({&createAdapter, wrapSetup(std::forward(setup)), wrapDone(done)}) + CustomTask(SetupHandler &&setup, const DoneFunction &done = {}, + CallDoneIf callDoneIf = CallDoneIf::SuccessOrError) + : GroupItem({&createAdapter, wrapSetup(std::forward(setup)), wrapDone(done), + callDoneIf}) {} GroupItem withTimeout(std::chrono::milliseconds timeout, @@ -365,14 +377,12 @@ private: }; }; - static TaskDoneHandler wrapEnds(const EndFunction &doneHandler, const EndFunction &errorHandler) { - if (!doneHandler && !errorHandler) + static TaskDoneHandler wrapEnd(const EndFunction &handler) { + if (!handler) return {}; - return [doneHandler, errorHandler](const TaskInterface &taskInterface, bool success) { + return [handler](const TaskInterface &taskInterface, bool) { const Adapter &adapter = static_cast(taskInterface); - const auto handler = success ? doneHandler : errorHandler; - if (handler) - handler(*adapter.task()); + handler(*adapter.task()); }; }; diff --git a/src/plugins/autotest/testcodeparser.cpp b/src/plugins/autotest/testcodeparser.cpp index 9b68815bea6..c549c105547 100644 --- a/src/plugins/autotest/testcodeparser.cpp +++ b/src/plugins/autotest/testcodeparser.cpp @@ -377,7 +377,7 @@ void TestCodeParser::scanForTests(const QSet &filePaths, qCDebug(LOG) << "Using" << limit << "threads for scan."; QList tasks{parallelLimit(limit)}; for (const FilePath &file : filteredFiles) { - const auto setup = [this, codeParsers, file](Async &async) { + const auto onSetup = [this, codeParsers, file](Async &async) { async.setConcurrentCallData(parseFileForTests, codeParsers, file); async.setPriority(QThread::LowestPriority); async.setFutureSynchronizer(&m_futureSynchronizer); @@ -387,7 +387,7 @@ void TestCodeParser::scanForTests(const QSet &filePaths, for (const TestParseResultPtr &result : results) emit testParseResultReady(result); }; - tasks.append(AsyncTask(setup, onDone)); + tasks.append(AsyncTask(onSetup, onDone, CallDoneIf::Success)); } m_taskTree.reset(new TaskTree{tasks}); const auto onDone = [this] { m_taskTree.release()->deleteLater(); onFinished(true); }; diff --git a/src/plugins/clangcodemodel/clangdlocatorfilters.cpp b/src/plugins/clangcodemodel/clangdlocatorfilters.cpp index c3e9c42903f..ae3b8fc6620 100644 --- a/src/plugins/clangcodemodel/clangdlocatorfilters.cpp +++ b/src/plugins/clangcodemodel/clangdlocatorfilters.cpp @@ -171,7 +171,7 @@ static void filterCurrentResults(QPromise &promise, const LocatorStorage & [](const Entry &entry) { return entry.entry; })); } -LocatorMatcherTask currentDocumentMatcher() +static LocatorMatcherTask currentDocumentMatcher() { using namespace Tasking; @@ -193,7 +193,7 @@ LocatorMatcherTask currentDocumentMatcher() const Group root { Tasking::Storage(resultStorage), - CurrentDocumentSymbolsRequestTask(onQuerySetup, onQueryDone), + CurrentDocumentSymbolsRequestTask(onQuerySetup, onQueryDone, CallDoneIf::Success), AsyncTask(onFilterSetup) }; return {root, storage}; diff --git a/src/plugins/clangtools/clangtool.cpp b/src/plugins/clangtools/clangtool.cpp index c25108a4185..d98d9e3a4a4 100644 --- a/src/plugins/clangtools/clangtool.cpp +++ b/src/plugins/clangtools/clangtool.cpp @@ -692,7 +692,7 @@ Group ClangTool::runRecipe(const RunSettings &runSettings, m_runControl->postMessage(message, ErrorMessageFormat); setState(State::PreparationFailed); }; - topTasks.append(ProjectBuilderTask(onSetup, {}, onError)); + topTasks.append(ProjectBuilderTask(onSetup, onError, CallDoneIf::Error)); } const ProjectInfo::ConstPtr projectInfoBeforeBuild @@ -821,7 +821,10 @@ Group ClangTool::runRecipe(const RunSettings &runSettings, NormalMessageFormat); }; - topTasks.append(Group { Tasking::Storage(storage), TaskTreeTask(onTreeSetup, onTreeDone) }); + topTasks.append(Group { + Tasking::Storage(storage), + TaskTreeTask(onTreeSetup, onTreeDone, CallDoneIf::Success) + }); return {topTasks}; } diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp index 370799fe260..03a102a0d9c 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp @@ -374,7 +374,7 @@ GroupItem CMakeBuildStep::runRecipe() }; Group root { ignoreReturnValue() ? finishAllAndDone : stopOnError, - ProjectParserTask(onParserSetup, {}, onParserError), + ProjectParserTask(onParserSetup, onParserError, CallDoneIf::Error), defaultProcessTask(), onGroupDone(onEnd), onGroupError(onEnd) diff --git a/src/plugins/coreplugin/locator/directoryfilter.cpp b/src/plugins/coreplugin/locator/directoryfilter.cpp index 4b22bcbf63d..b354f238558 100644 --- a/src/plugins/coreplugin/locator/directoryfilter.cpp +++ b/src/plugins/coreplugin/locator/directoryfilter.cpp @@ -88,18 +88,18 @@ DirectoryFilter::DirectoryFilter(Id id) m_cache.setFilePaths({}); return SetupResult::StopWithDone; // Group stops, skips async task }; - const auto asyncSetup = [this](Async &async) { + const auto onSetup = [this](Async &async) { async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); async.setConcurrentCallData(&refresh, m_directories, m_filters, m_exclusionFilters, displayName()); }; - const auto asyncDone = [this](const Async &async) { + const auto onDone = [this](const Async &async) { if (async.isResultAvailable()) m_cache.setFilePaths(async.result()); }; const Group root { onGroupSetup(groupSetup), - AsyncTask(asyncSetup, asyncDone) + AsyncTask(onSetup, onDone, CallDoneIf::Success) }; setRefreshRecipe(root); } diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.cpp b/src/plugins/coreplugin/locator/ilocatorfilter.cpp index fbfd557e467..b8779c7f8f2 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/ilocatorfilter.cpp @@ -1526,7 +1526,7 @@ LocatorMatcherTask LocatorFileCache::matcher() const that->update(async.result()); }; - return {AsyncTask(onSetup, onDone), storage}; + return {AsyncTask(onSetup, onDone, CallDoneIf::Success), storage}; } } // Core diff --git a/src/plugins/coreplugin/plugininstallwizard.cpp b/src/plugins/coreplugin/plugininstallwizard.cpp index 9a0b92c871e..510bf6ca8e7 100644 --- a/src/plugins/coreplugin/plugininstallwizard.cpp +++ b/src/plugins/coreplugin/plugininstallwizard.cpp @@ -257,8 +257,8 @@ public: }; const Group root { - UnarchiverTask(onUnarchiverSetup, {}, onUnarchiverError), - AsyncTask(onCheckerSetup, onCheckerDone) + UnarchiverTask(onUnarchiverSetup, onUnarchiverError, CallDoneIf::Error), + AsyncTask(onCheckerSetup, onCheckerDone, CallDoneIf::Success) }; m_taskTree.reset(new TaskTree(root)); diff --git a/src/plugins/cppeditor/cppprojectupdater.cpp b/src/plugins/cppeditor/cppprojectupdater.cpp index f64c75ea5c9..1413c5132f2 100644 --- a/src/plugins/cppeditor/cppprojectupdater.cpp +++ b/src/plugins/cppeditor/cppprojectupdater.cpp @@ -52,7 +52,7 @@ void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo, ProjectInfo::ConstPtr projectInfo = nullptr; }; const TreeStorage storage; - const auto setupInfoGenerator = [=](Async &async) { + const auto onInfoGeneratorSetup = [=](Async &async) { async.setConcurrentCallData(infoGenerator); async.setFutureSynchronizer(&m_futureSynchronizer); }; @@ -61,7 +61,8 @@ void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo, storage->projectInfo = async.result(); }; QList tasks{parallel}; - tasks.append(AsyncTask(setupInfoGenerator, onInfoGeneratorDone)); + tasks.append(AsyncTask(onInfoGeneratorSetup, onInfoGeneratorDone, + CallDoneIf::Success)); for (QPointer compiler : compilers) { if (compiler && compiler->isDirty()) tasks.append(compiler->compileFileItem()); diff --git a/src/plugins/debugger/loadcoredialog.cpp b/src/plugins/debugger/loadcoredialog.cpp index d52d52e1115..0cb395b68a3 100644 --- a/src/plugins/debugger/loadcoredialog.cpp +++ b/src/plugins/debugger/loadcoredialog.cpp @@ -252,12 +252,14 @@ void AttachCoreDialog::accepted() parallel, AsyncTask{[=](auto &task) { task.setConcurrentCallData(copyFileAsync, this->coreFile()); - }, - [=](const auto &task) { d->coreFileResult = task.result(); }}, + }, + [=](const auto &task) { d->coreFileResult = task.result(); }, + CallDoneIf::Success}, AsyncTask{[=](auto &task) { task.setConcurrentCallData(copyFileAsync, this->symbolFile()); - }, - [=](const auto &task) { d->symbolFileResult = task.result(); }}, + }, + [=](const auto &task) { d->symbolFileResult = task.result(); }, + CallDoneIf::Success} }; d->taskTree.setRecipe(root); diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp index bb2cf4e24dd..ceab92cb7f6 100644 --- a/src/plugins/diffeditor/diffeditorplugin.cpp +++ b/src/plugins/diffeditor/diffeditorplugin.cpp @@ -118,7 +118,7 @@ DiffFilesController::DiffFilesController(IDocument *document) QList tasks { parallel, finishAllAndDone }; for (int i = 0; i < inputList.size(); ++i) { - const auto setupDiff = [this, reloadInput = inputList.at(i)](Async &async) { + const auto onDiffSetup = [this, reloadInput = inputList.at(i)](Async &async) { async.setConcurrentCallData( DiffFile(ignoreWhitespace(), contextLineCount()), reloadInput); async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); @@ -128,7 +128,7 @@ DiffFilesController::DiffFilesController(IDocument *document) if (async.isResultAvailable()) (*outputList)[i] = async.result(); }; - tasks.append(AsyncTask(setupDiff, onDiffDone)); + tasks.append(AsyncTask(onDiffSetup, onDiffDone, CallDoneIf::Success)); } taskTree.setRecipe(tasks); }; diff --git a/src/plugins/git/branchview.cpp b/src/plugins/git/branchview.cpp index b5282b709e8..988e148a3f2 100644 --- a/src/plugins/git/branchview.cpp +++ b/src/plugins/git/branchview.cpp @@ -547,7 +547,7 @@ TaskTree *BranchView::onFastForwardMerge(const std::function &callback) const TreeStorage storage; - const auto setupMergeBase = [repository = m_repository, branch](Process &process) { + const auto onMergeBaseSetup = [repository = m_repository, branch](Process &process) { gitClient().setupCommand(process, repository, {"merge-base", "HEAD", branch}); }; const auto onMergeBaseDone = [storage](const Process &process) { @@ -563,7 +563,7 @@ TaskTree *BranchView::onFastForwardMerge(const std::function &callback) const Group root { Tasking::Storage(storage), parallel, - ProcessTask(setupMergeBase, onMergeBaseDone), + ProcessTask(onMergeBaseSetup, onMergeBaseDone, CallDoneIf::Success), topRevisionProc, onGroupDone([storage, callback] { if (storage->mergeBase == storage->topRevision) diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 91adbfad075..38897f03630 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -238,7 +238,7 @@ GitDiffEditorController::GitDiffEditorController(IDocument *document, { const TreeStorage diffInputStorage; - const auto setupDiff = [=](Process &process) { + const auto onDiffSetup = [=](Process &process) { process.setCodec(VcsBaseEditor::getCodec(workingDirectory(), {})); setupCommand(process, {addConfigurationArguments(diffArgs(leftCommit, rightCommit, extraArgs))}); VcsOutputWindow::appendCommand(process.workingDirectory(), process.commandLine()); @@ -249,7 +249,7 @@ GitDiffEditorController::GitDiffEditorController(IDocument *document, const Group root { Tasking::Storage(diffInputStorage), - ProcessTask(setupDiff, onDiffDone), + ProcessTask(onDiffSetup, onDiffDone, CallDoneIf::Success), postProcessTask(diffInputStorage) }; setReloadRecipe(root); @@ -302,7 +302,7 @@ FileListDiffController::FileListDiffController(IDocument *document, const QStrin const TreeStorage storage; const TreeStorage diffInputStorage; - const auto setupStaged = [this, stagedFiles](Process &process) { + const auto onStagedSetup = [this, stagedFiles](Process &process) { if (stagedFiles.isEmpty()) return SetupResult::StopWithError; process.setCodec(VcsBaseEditor::getCodec(workingDirectory(), stagedFiles)); @@ -315,7 +315,7 @@ FileListDiffController::FileListDiffController(IDocument *document, const QStrin storage->m_stagedOutput = process.cleanedStdOut(); }; - const auto setupUnstaged = [this, unstagedFiles](Process &process) { + const auto onUnstagedSetup = [this, unstagedFiles](Process &process) { if (unstagedFiles.isEmpty()) return SetupResult::StopWithError; process.setCodec(VcsBaseEditor::getCodec(workingDirectory(), unstagedFiles)); @@ -328,7 +328,7 @@ FileListDiffController::FileListDiffController(IDocument *document, const QStrin storage->m_unstagedOutput = process.cleanedStdOut(); }; - const auto onStagingDone = [storage, diffInputStorage] { + const auto onDone = [storage, diffInputStorage] { *diffInputStorage = storage->m_stagedOutput + storage->m_unstagedOutput; }; @@ -338,9 +338,9 @@ FileListDiffController::FileListDiffController(IDocument *document, const QStrin Group { parallel, continueOnDone, - ProcessTask(setupStaged, onStagedDone), - ProcessTask(setupUnstaged, onUnstagedDone), - onGroupDone(onStagingDone) + ProcessTask(onStagedSetup, onStagedDone, CallDoneIf::Success), + ProcessTask(onUnstagedSetup, onUnstagedDone, CallDoneIf::Success), + onGroupDone(onDone) }, postProcessTask(diffInputStorage) }; @@ -500,14 +500,14 @@ ShowController::ShowController(IDocument *document, const QString &id) QList tasks { parallel, continueOnDone, onGroupError(onFollowsError) }; for (int i = 0, total = parents.size(); i < total; ++i) { - const auto setupFollow = [this, parent = parents.at(i)](Process &process) { + const auto onFollowSetup = [this, parent = parents.at(i)](Process &process) { setupCommand(process, {"describe", "--tags", "--abbrev=0", parent}); }; const auto onFollowDone = [data, updateDescription, i](const Process &process) { data->m_follows[i] = process.cleanedStdOut().trimmed(); updateDescription(*data); }; - tasks.append(ProcessTask(setupFollow, onFollowDone)); + tasks.append(ProcessTask(onFollowSetup, onFollowDone, CallDoneIf::Success)); } taskTree.setRecipe(tasks); }; @@ -529,18 +529,18 @@ ShowController::ShowController(IDocument *document, const QString &id) onGroupSetup([this] { setStartupFile(VcsBase::source(this->document()).toString()); }), Group { finishAllAndDone, - ProcessTask(onDescriptionSetup, onDescriptionDone), + ProcessTask(onDescriptionSetup, onDescriptionDone, CallDoneIf::Success), Group { parallel, finishAllAndDone, onGroupSetup(desciptionDetailsSetup), - ProcessTask(onBranchesSetup, onBranchesDone), - ProcessTask(onPrecedesSetup, onPrecedesDone), + ProcessTask(onBranchesSetup, onBranchesDone, CallDoneIf::Success), + ProcessTask(onPrecedesSetup, onPrecedesDone, CallDoneIf::Success), TaskTreeTask(setupFollows) } }, Group { - ProcessTask(onDiffSetup, onDiffDone), + ProcessTask(onDiffSetup, onDiffDone, CallDoneIf::Success), postProcessTask(diffInputStorage) } }; @@ -1712,7 +1712,7 @@ bool GitClient::synchronousRevParseCmd(const FilePath &workingDirectory, const Q GroupItem GitClient::topRevision(const FilePath &workingDirectory, const std::function &callback) { - const auto setupProcess = [this, workingDirectory](Process &process) { + const auto onProcessSetup = [this, workingDirectory](Process &process) { setupCommand(process, workingDirectory, {"show", "-s", "--pretty=format:%H:%ct", HEAD}); }; const auto onProcessDone = [callback](const Process &process) { @@ -1727,7 +1727,7 @@ GroupItem GitClient::topRevision(const FilePath &workingDirectory, callback(output.first(), dateTime); }; - return ProcessTask(setupProcess, onProcessDone); + return ProcessTask(onProcessSetup, onProcessDone, CallDoneIf::Success); } bool GitClient::isRemoteCommit(const FilePath &workingDirectory, const QString &commit) diff --git a/src/plugins/help/helpindexfilter.cpp b/src/plugins/help/helpindexfilter.cpp index 9da19214801..4c8910b1d86 100644 --- a/src/plugins/help/helpindexfilter.cpp +++ b/src/plugins/help/helpindexfilter.cpp @@ -105,7 +105,7 @@ LocatorMatcherTasks HelpIndexFilter::matchers() } }; - return {{AsyncTask(onSetup, onDone), storage}}; + return {{AsyncTask(onSetup, onDone, CallDoneIf::Success), storage}}; } void HelpIndexFilter::invalidateCache() diff --git a/src/plugins/languageclient/locatorfilter.cpp b/src/plugins/languageclient/locatorfilter.cpp index 7f78130bdb0..82a390d4ece 100644 --- a/src/plugins/languageclient/locatorfilter.cpp +++ b/src/plugins/languageclient/locatorfilter.cpp @@ -77,7 +77,7 @@ LocatorMatcherTask locatorMatcher(Client *client, int maxResultCount, const Group root { Tasking::Storage(resultStorage), - ClientWorkspaceSymbolRequestTask(onQuerySetup, onQueryDone), + ClientWorkspaceSymbolRequestTask(onQuerySetup, onQueryDone, CallDoneIf::Success), AsyncTask(onFilterSetup) }; return {root, storage}; @@ -136,7 +136,7 @@ LocatorMatcherTask currentDocumentMatcher() const Group root { Tasking::Storage(resultStorage), - CurrentDocumentSymbolsRequestTask(onQuerySetup, onQueryDone), + CurrentDocumentSymbolsRequestTask(onQuerySetup, onQueryDone, CallDoneIf::Success), AsyncTask(onFilterSetup) }; return {root, storage}; diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp index bd5e45f4e96..25ed1404111 100644 --- a/src/plugins/mercurial/mercurialclient.cpp +++ b/src/plugins/mercurial/mercurialclient.cpp @@ -55,7 +55,7 @@ MercurialDiffEditorController::MercurialDiffEditorController(IDocument *document const TreeStorage diffInputStorage; - const auto setupDiff = [=](Process &process) { + const auto onDiffSetup = [=](Process &process) { setupCommand(process, {addConfigurationArguments(args)}); VcsOutputWindow::appendCommand(process.workingDirectory(), process.commandLine()); }; @@ -65,7 +65,7 @@ MercurialDiffEditorController::MercurialDiffEditorController(IDocument *document const Group root { Tasking::Storage(diffInputStorage), - ProcessTask(setupDiff, onDiffDone), + ProcessTask(onDiffSetup, onDiffDone, CallDoneIf::Success), postProcessTask(diffInputStorage) }; setReloadRecipe(root); diff --git a/src/plugins/projectexplorer/extracompiler.cpp b/src/plugins/projectexplorer/extracompiler.cpp index a81ddda93fe..2535181b230 100644 --- a/src/plugins/projectexplorer/extracompiler.cpp +++ b/src/plugins/projectexplorer/extracompiler.cpp @@ -328,14 +328,14 @@ ProcessExtraCompiler::ProcessExtraCompiler(const Project *project, const FilePat GroupItem ProcessExtraCompiler::taskItemImpl(const ContentProvider &provider) { - const auto setupTask = [=](Async &async) { + const auto onSetup = [=](Async &async) { async.setThreadPool(extraCompilerThreadPool()); // The passed synchronizer has cancelOnWait set to true by default. async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); async.setConcurrentCallData(&ProcessExtraCompiler::runInThread, this, command(), workingDirectory(), arguments(), provider, buildEnvironment()); }; - const auto taskDone = [=](const Async &async) { + const auto onDone = [=](const Async &async) { if (!async.isResultAvailable()) return; const FileNameToContentsHash data = async.result(); @@ -345,7 +345,7 @@ GroupItem ProcessExtraCompiler::taskItemImpl(const ContentProvider &provider) setContent(it.key(), it.value()); updateCompileTime(); }; - return AsyncTask(setupTask, taskDone); + return AsyncTask(onSetup, onDone, CallDoneIf::Success); } FilePath ProcessExtraCompiler::workingDirectory() const diff --git a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp index 6c19ea10f67..b766de11f54 100644 --- a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp +++ b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp @@ -147,24 +147,24 @@ GroupItem QnxDeployQtLibrariesDialogPrivate::checkDirTask() GroupItem QnxDeployQtLibrariesDialogPrivate::removeDirTask() { - const auto setupHandler = [this](Process &process) { + const auto onSetup = [this](Process &process) { if (m_checkResult != CheckResult::RemoveDir) return SetupResult::StopWithDone; m_deployLogWindow->appendPlainText(Tr::tr("Removing \"%1\"").arg(fullRemoteDirectory())); process.setCommand({m_device->filePath("rm"), {"-rf", fullRemoteDirectory()}}); return SetupResult::Continue; }; - const auto errorHandler = [this](const Process &process) { + const auto onError = [this](const Process &process) { QTC_ASSERT(process.exitCode() == 0, return); m_deployLogWindow->appendPlainText(Tr::tr("Connection failed: %1") .arg(process.errorString())); }; - return ProcessTask(setupHandler, {}, errorHandler); + return ProcessTask(onSetup, onError, CallDoneIf::Error); } GroupItem QnxDeployQtLibrariesDialogPrivate::uploadTask() { - const auto setupHandler = [this](FileTransfer &transfer) { + const auto onSetup = [this](FileTransfer &transfer) { if (m_deployableFiles.isEmpty()) { emitProgressMessage(Tr::tr("No files need to be uploaded.")); return SetupResult::StopWithDone; @@ -190,19 +190,19 @@ GroupItem QnxDeployQtLibrariesDialogPrivate::uploadTask() this, &QnxDeployQtLibrariesDialogPrivate::emitProgressMessage); return SetupResult::Continue; }; - const auto errorHandler = [this](const FileTransfer &transfer) { + const auto onError = [this](const FileTransfer &transfer) { emitErrorMessage(transfer.resultData().m_errorString); }; - return FileTransferTask(setupHandler, {}, errorHandler); + return FileTransferTask(onSetup, onError, CallDoneIf::Error); } GroupItem QnxDeployQtLibrariesDialogPrivate::chmodTask(const DeployableFile &file) { - const auto setupHandler = [=](Process &process) { + const auto onSetup = [=](Process &process) { process.setCommand({m_device->filePath("chmod"), {"a+x", Utils::ProcessArgs::quoteArgUnix(file.remoteFilePath())}}); }; - const auto errorHandler = [=](const Process &process) { + const auto onError = [=](const Process &process) { const QString error = process.errorString(); if (!error.isEmpty()) { emitWarningMessage(Tr::tr("Remote chmod failed for file \"%1\": %2") @@ -212,7 +212,7 @@ GroupItem QnxDeployQtLibrariesDialogPrivate::chmodTask(const DeployableFile &fil .arg(file.remoteFilePath(), process.cleanedStdErr())); } }; - return ProcessTask(setupHandler, {}, errorHandler); + return ProcessTask(onSetup, onError, CallDoneIf::Error); } GroupItem QnxDeployQtLibrariesDialogPrivate::chmodTree() diff --git a/src/plugins/qnx/qnxdevicetester.cpp b/src/plugins/qnx/qnxdevicetester.cpp index b162abb7f69..1b4c35d5388 100644 --- a/src/plugins/qnx/qnxdevicetester.cpp +++ b/src/plugins/qnx/qnxdevicetester.cpp @@ -62,7 +62,7 @@ void QnxDeviceTester::testDevice(const ProjectExplorer::IDevice::Ptr &device) : Tr::tr("Files cannot be created in %1.").arg(Constants::QNX_TMP_DIR); emit errorMessage(message + '\n'); }; - setExtraTests({ProcessTask(onSetup, onDone)}); + setExtraTests({ProcessTask(onSetup, onDone, CallDoneIf::Success)}); RemoteLinux::GenericLinuxDeviceTester::testDevice(device); } diff --git a/src/plugins/qnx/slog2inforunner.cpp b/src/plugins/qnx/slog2inforunner.cpp index 8be079c4300..f56dea7c93c 100644 --- a/src/plugins/qnx/slog2inforunner.cpp +++ b/src/plugins/qnx/slog2inforunner.cpp @@ -71,8 +71,8 @@ void Slog2InfoRunner::start() const Group root { ProcessTask(onTestSetup, onTestDone), - ProcessTask(onLaunchTimeSetup, onLaunchTimeDone), - ProcessTask(onLogSetup, {}, onLogError) + ProcessTask(onLaunchTimeSetup, onLaunchTimeDone, CallDoneIf::Success), + ProcessTask(onLogSetup, onLogError, CallDoneIf::Error) }; m_taskTree.reset(new TaskTree(root)); diff --git a/src/plugins/remotelinux/filesystemaccess_test.cpp b/src/plugins/remotelinux/filesystemaccess_test.cpp index f8afdd22423..a66dd7524ca 100644 --- a/src/plugins/remotelinux/filesystemaccess_test.cpp +++ b/src/plugins/remotelinux/filesystemaccess_test.cpp @@ -443,32 +443,32 @@ void FileSystemAccessTest::testFileStreamer() return FileStreamerTask(setup); }; const auto localReader = [&] { - const auto setup = [&](FileStreamer &streamer) { + const auto onSetup = [&](FileStreamer &streamer) { streamer.setStreamMode(StreamMode::Reader); streamer.setSource(localSourcePath); }; const auto onDone = [&](const FileStreamer &streamer) { localData = streamer.readData(); }; - return FileStreamerTask(setup, onDone); + return FileStreamerTask(onSetup, onDone, CallDoneIf::Success); }; const auto remoteReader = [&] { - const auto setup = [&](FileStreamer &streamer) { + const auto onSetup = [&](FileStreamer &streamer) { streamer.setStreamMode(StreamMode::Reader); streamer.setSource(remoteSourcePath); }; const auto onDone = [&](const FileStreamer &streamer) { remoteData = streamer.readData(); }; - return FileStreamerTask(setup, onDone); + return FileStreamerTask(onSetup, onDone, CallDoneIf::Success); }; const auto transfer = [](const FilePath &source, const FilePath &dest, std::optional *result) { - const auto setupTransfer = [=](FileStreamer &streamer) { + const auto onTransferSetup = [=](FileStreamer &streamer) { streamer.setSource(source); streamer.setDestination(dest); }; - const auto setupReader = [=](FileStreamer &streamer) { + const auto onReaderSetup = [=](FileStreamer &streamer) { streamer.setStreamMode(StreamMode::Reader); streamer.setSource(dest); }; @@ -476,8 +476,8 @@ void FileSystemAccessTest::testFileStreamer() *result = streamer.readData(); }; const Group root { - FileStreamerTask(setupTransfer), - FileStreamerTask(setupReader, onReaderDone) + FileStreamerTask(onTransferSetup), + FileStreamerTask(onReaderSetup, onReaderDone, CallDoneIf::Success) }; return root; }; diff --git a/src/plugins/remotelinux/genericdeploystep.cpp b/src/plugins/remotelinux/genericdeploystep.cpp index 16073b8dcb5..4a14f6cdddf 100644 --- a/src/plugins/remotelinux/genericdeploystep.cpp +++ b/src/plugins/remotelinux/genericdeploystep.cpp @@ -109,7 +109,7 @@ GroupItem GenericDeployStep::mkdirTask(const TreeStorage &stora } }; - return AsyncTask(onSetup, {}, onError); + return AsyncTask(onSetup, onError, CallDoneIf::Error); } static FileTransferMethod supportedTransferMethodFor(const FileToTransfer &fileToTransfer) @@ -135,7 +135,7 @@ static FileTransferMethod supportedTransferMethodFor(const FileToTransfer &fileT GroupItem GenericDeployStep::transferTask(const TreeStorage &storage) { - const auto setupHandler = [this, storage](FileTransfer &transfer) { + const auto onSetup = [this, storage](FileTransfer &transfer) { FileTransferMethod preferredTransferMethod = FileTransferMethod::Rsync; if (method() == 0) preferredTransferMethod = FileTransferMethod::Rsync; @@ -164,7 +164,7 @@ GroupItem GenericDeployStep::transferTask(const TreeStorage &st transfer.setFilesToTransfer(*storage); connect(&transfer, &FileTransfer::progress, this, &GenericDeployStep::handleStdOutData); }; - const auto errorHandler = [this](const FileTransfer &transfer) { + const auto onError = [this](const FileTransfer &transfer) { const ProcessResultData result = transfer.resultData(); if (result.m_error == QProcess::FailedToStart) { addErrorMessage(Tr::tr("rsync failed to start: %1").arg(result.m_errorString)); @@ -175,7 +175,7 @@ GroupItem GenericDeployStep::transferTask(const TreeStorage &st + "\n" + result.m_errorString); } }; - return FileTransferTask(setupHandler, {}, errorHandler); + return FileTransferTask(onSetup, onError, CallDoneIf::Error); } GroupItem GenericDeployStep::deployRecipe() diff --git a/src/plugins/remotelinux/genericdirectuploadstep.cpp b/src/plugins/remotelinux/genericdirectuploadstep.cpp index 4878a6f20a0..0e23a586f31 100644 --- a/src/plugins/remotelinux/genericdirectuploadstep.cpp +++ b/src/plugins/remotelinux/genericdirectuploadstep.cpp @@ -166,7 +166,7 @@ GroupItem GenericDirectUploadStep::statTree(const TreeStorage &st GroupItem GenericDirectUploadStep::uploadTask(const TreeStorage &storage) { - const auto setupHandler = [this, storage](FileTransfer &transfer) { + const auto onSetup = [this, storage](FileTransfer &transfer) { if (storage->filesToUpload.isEmpty()) { addProgressMessage(Tr::tr("No files need to be uploaded.")); return SetupResult::StopWithDone; @@ -197,20 +197,20 @@ GroupItem GenericDirectUploadStep::uploadTask(const TreeStorage & this, &GenericDirectUploadStep::addProgressMessage); return SetupResult::Continue; }; - const auto errorHandler = [this](const FileTransfer &transfer) { + const auto onError = [this](const FileTransfer &transfer) { addErrorMessage(transfer.resultData().m_errorString); }; - return FileTransferTask(setupHandler, {}, errorHandler); + return FileTransferTask(onSetup, onError, CallDoneIf::Error); } GroupItem GenericDirectUploadStep::chmodTask(const DeployableFile &file) { - const auto setupHandler = [=](Process &process) { + const auto onSetup = [=](Process &process) { process.setCommand({deviceConfiguration()->filePath("chmod"), {"a+x", Utils::ProcessArgs::quoteArgUnix(file.remoteFilePath())}}); }; - const auto errorHandler = [=](const Process &process) { + const auto onError = [=](const Process &process) { const QString error = process.errorString(); if (!error.isEmpty()) { addWarningMessage(Tr::tr("Remote chmod failed for file \"%1\": %2") @@ -220,7 +220,7 @@ GroupItem GenericDirectUploadStep::chmodTask(const DeployableFile &file) .arg(file.remoteFilePath(), process.cleanedStdErr())); } }; - return ProcessTask(setupHandler, {}, errorHandler); + return ProcessTask(onSetup, onError, CallDoneIf::Error); } GroupItem GenericDirectUploadStep::chmodTree(const TreeStorage &storage) diff --git a/src/plugins/subversion/subversionclient.cpp b/src/plugins/subversion/subversionclient.cpp index 75231c21e51..2a36f8d0d26 100644 --- a/src/plugins/subversion/subversionclient.cpp +++ b/src/plugins/subversion/subversionclient.cpp @@ -205,7 +205,7 @@ SubversionDiffEditorController::SubversionDiffEditorController(IDocument *docume ProcessTask(onDescriptionSetup, onDescriptionDone) }, Group { - ProcessTask(onDiffSetup, onDiffDone), + ProcessTask(onDiffSetup, onDiffDone, CallDoneIf::Success), postProcessTask(diffInputStorage) } }; diff --git a/src/plugins/updateinfo/updateinfoplugin.cpp b/src/plugins/updateinfo/updateinfoplugin.cpp index 1b631cb82cf..1a4cea93396 100644 --- a/src/plugins/updateinfo/updateinfoplugin.cpp +++ b/src/plugins/updateinfo/updateinfoplugin.cpp @@ -127,22 +127,22 @@ void UpdateInfoPlugin::startCheckForUpdates() checkForUpdatesStopped(); }; - const auto setupUpdate = [doSetup](Process &process) { + const auto onUpdateSetup = [doSetup](Process &process) { doSetup(process, {"ch", "-g", "*=false,ifw.package.*=true"}); }; - const auto updateDone = [this](const Process &process) { + const auto onUpdateDone = [this](const Process &process) { d->m_updateOutput = process.cleanedStdOut(); }; - QList tasks { ProcessTask(setupUpdate, updateDone) }; + QList tasks { ProcessTask(onUpdateSetup, onUpdateDone, CallDoneIf::Success) }; if (d->m_settings.checkForQtVersions) { - const auto setupPackages = [doSetup](Process &process) { + const auto onPackagesSetup = [doSetup](Process &process) { doSetup(process, {"se", "qt[.]qt[0-9][.][0-9]+$", "-g", "*=false,ifw.package.*=true"}); }; - const auto packagesDone = [this](const Process &process) { + const auto onPackagesDone = [this](const Process &process) { d->m_packagesOutput = process.cleanedStdOut(); }; - tasks << ProcessTask(setupPackages, packagesDone); + tasks << ProcessTask(onPackagesSetup, onPackagesDone, CallDoneIf::Success); } d->m_taskTree.reset(new TaskTree(Group{tasks})); diff --git a/src/plugins/valgrind/valgrindprocess.cpp b/src/plugins/valgrind/valgrindprocess.cpp index 1280014f952..c62fb46891b 100644 --- a/src/plugins/valgrind/valgrindprocess.cpp +++ b/src/plugins/valgrind/valgrindprocess.cpp @@ -203,7 +203,7 @@ Group ValgrindProcessPrivate::runRecipe() const Group { onGroupSetup(onParserGroupSetup), waitForBarrierTask(xmlBarrier), - ParserTask(onParserSetup, {}, onParserError) + ParserTask(onParserSetup, onParserError, CallDoneIf::Error) } }; return root; diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index 546b876be57..58ab4513df5 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -77,9 +77,9 @@ void tst_Tasking::validConstructs() { const Group task { parallel, - TestTask([](TaskObject &) {}, [](const TaskObject &) {}), - TestTask([](TaskObject &) {}, [](const TaskObject &) {}), - TestTask([](TaskObject &) {}, [](const TaskObject &) {}) + TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}), + TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}), + TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}) }; const Group group1 { @@ -90,18 +90,18 @@ void tst_Tasking::validConstructs() parallel, Group { parallel, - TestTask([](TaskObject &) {}, [](const TaskObject &) {}), + TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}), Group { parallel, - TestTask([](TaskObject &) {}, [](const TaskObject &) {}), + TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}), Group { parallel, - TestTask([](TaskObject &) {}, [](const TaskObject &) {}) + TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}) } }, Group { parallel, - TestTask([](TaskObject &) {}, [](const TaskObject &) {}), + TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}), onGroupDone([] {}) } }, @@ -119,14 +119,12 @@ void tst_Tasking::validConstructs() parallel, TestTask(), TestTask(setupHandler), - TestTask(setupHandler, finishHandler), - TestTask(setupHandler, finishHandler, errorHandler), + TestTask(setupHandler, finishHandler, CallDoneIf::Success), TestTask(setupHandler, doneHandler), // need to explicitly pass empty handler for done - TestTask(setupHandler, {}, errorHandler), - TestTask({}, finishHandler), - TestTask({}, finishHandler, errorHandler), - TestTask({}, {}, errorHandler) + TestTask(setupHandler, errorHandler, CallDoneIf::Error), + TestTask({}, finishHandler, CallDoneIf::Success), + TestTask({}, errorHandler, CallDoneIf::Error) }; // When turning each of below blocks on, you should see the specific compiler error message. diff --git a/tests/auto/utils/async/tst_async.cpp b/tests/auto/utils/async/tst_async.cpp index 0e8bc1e2b03..b891a3106e1 100644 --- a/tests/auto/utils/async/tst_async.cpp +++ b/tests/auto/utils/async/tst_async.cpp @@ -434,10 +434,10 @@ void tst_Async::taskTree() }; const Group root { - AsyncTask(setupIntAsync, handleIntAsync), - AsyncTask(setupIntAsync, handleIntAsync), - AsyncTask(setupIntAsync, handleIntAsync), - AsyncTask(setupIntAsync, handleIntAsync), + AsyncTask(setupIntAsync, handleIntAsync, CallDoneIf::Success), + AsyncTask(setupIntAsync, handleIntAsync, CallDoneIf::Success), + AsyncTask(setupIntAsync, handleIntAsync, CallDoneIf::Success), + AsyncTask(setupIntAsync, handleIntAsync, CallDoneIf::Success), }; @@ -506,11 +506,11 @@ void tst_Async::mapReduce_data() return Group { executeMode, onGroupSetup(initTree), - AsyncTask(std::bind(setupHandler, _1, 1), handleAsync), - AsyncTask(std::bind(setupHandler, _1, 2), handleAsync), - AsyncTask(std::bind(setupHandler, _1, 3), handleAsync), - AsyncTask(std::bind(setupHandler, _1, 4), handleAsync), - AsyncTask(std::bind(setupHandler, _1, 5), handleAsync), + AsyncTask(std::bind(setupHandler, _1, 1), handleAsync, CallDoneIf::Success), + AsyncTask(std::bind(setupHandler, _1, 2), handleAsync, CallDoneIf::Success), + AsyncTask(std::bind(setupHandler, _1, 3), handleAsync, CallDoneIf::Success), + AsyncTask(std::bind(setupHandler, _1, 4), handleAsync, CallDoneIf::Success), + AsyncTask(std::bind(setupHandler, _1, 5), handleAsync, CallDoneIf::Success), onGroupDone(doneHandler) }; }; @@ -542,9 +542,9 @@ void tst_Async::mapReduce_data() const Group simpleRoot = { sequential, onGroupSetup([] { s_sum = 0; }), - AsyncTask(std::bind(setupSimpleAsync, _1, 1), handleSimpleAsync), - AsyncTask(std::bind(setupSimpleAsync, _1, 2), handleSimpleAsync), - AsyncTask(std::bind(setupSimpleAsync, _1, 3), handleSimpleAsync) + AsyncTask(std::bind(setupSimpleAsync, _1, 1), handleSimpleAsync, CallDoneIf::Success), + AsyncTask(std::bind(setupSimpleAsync, _1, 2), handleSimpleAsync, CallDoneIf::Success), + AsyncTask(std::bind(setupSimpleAsync, _1, 3), handleSimpleAsync, CallDoneIf::Success) }; QTest::newRow("Simple") << simpleRoot << 3.0 << QList({.5, 1.5, 3.}); @@ -557,9 +557,9 @@ void tst_Async::mapReduce_data() const Group stringRoot = { parallel, onGroupSetup([] { s_sum = 90.0; }), - AsyncTask(std::bind(setupStringAsync, _1, "blubb"), handleStringAsync), - AsyncTask(std::bind(setupStringAsync, _1, "foo"), handleStringAsync), - AsyncTask(std::bind(setupStringAsync, _1, "blah"), handleStringAsync) + AsyncTask(std::bind(setupStringAsync, _1, "blubb"), handleStringAsync, CallDoneIf::Success), + AsyncTask(std::bind(setupStringAsync, _1, "foo"), handleStringAsync, CallDoneIf::Success), + AsyncTask(std::bind(setupStringAsync, _1, "blah"), handleStringAsync, CallDoneIf::Success) }; QTest::newRow("String") << stringRoot << 1.5 << QList({}); } From 34cef824b534d10b24855d9a8dfb189e7a9af7dd Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 2 Nov 2023 19:10:55 +0100 Subject: [PATCH 0081/1546] TaskTree: Make it possible to tweak the success bit in done handler Make the arguments of done handler optional. Task-number: QTCREATORBUG-29834 Change-Id: I9c2af431feca87351c8c9129e61ce3889d137de5 Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 21 +++-- src/libs/solutions/tasking/tasktree.h | 97 +++++++++++--------- tests/auto/solutions/tasking/tst_tasking.cpp | 16 +--- 3 files changed, 72 insertions(+), 62 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index f7c44d8aaf0..fbc02a35f2f 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -956,15 +956,14 @@ void GroupItem::addChildren(const QList &children) GroupItem GroupItem::withTimeout(const GroupItem &item, milliseconds timeout, const GroupEndHandler &handler) { - const TimeoutTask::EndFunction taskHandler = handler - ? [handler](const milliseconds &) { handler(); } : TimeoutTask::EndFunction(); + const auto onSetup = [timeout](milliseconds &timeoutData) { timeoutData = timeout; }; return Group { parallel, stopOnFinished, Group { finishAllAndError, - TimeoutTask([timeout](milliseconds &timeoutData) { timeoutData = timeout; }, - taskHandler, CallDoneIf::Success) + handler ? TimeoutTask(onSetup, [handler] { handler(); }, CallDoneIf::Success) + : TimeoutTask(onSetup) }, item }; @@ -1089,7 +1088,7 @@ public: // in order to unwind properly. SetupResult start(); void stop(); - void invokeDoneHandler(bool success); + bool invokeDoneHandler(bool success); bool isRunning() const { return m_task || m_container.isRunning(); } bool isTask() const { return bool(m_taskHandler.m_createHandler); } int taskCount() const { return isTask() ? 1 : m_container.m_constData.m_taskCount; } @@ -1451,14 +1450,14 @@ SetupResult TaskNode::start() const std::shared_ptr unwindAction = std::make_shared(SetupResult::Continue); QObject::connect(m_task.get(), &TaskInterface::done, taskTree(), [=](bool success) { - invokeDoneHandler(success); + const bool result = invokeDoneHandler(success); QObject::disconnect(m_task.get(), &TaskInterface::done, taskTree(), nullptr); m_task.release()->deleteLater(); QTC_ASSERT(parentContainer() && parentContainer()->isRunning(), return); if (parentContainer()->isStarting()) - *unwindAction = toSetupResult(success); + *unwindAction = toSetupResult(result); else - parentContainer()->childDone(success); + parentContainer()->childDone(result); }); m_task->start(); @@ -1490,11 +1489,13 @@ static bool shouldCall(CallDoneIf callDoneIf, bool success) return callDoneIf != CallDoneIf::Success; } -void TaskNode::invokeDoneHandler(bool success) +bool TaskNode::invokeDoneHandler(bool success) { + bool result = success; if (m_taskHandler.m_doneHandler && shouldCall(m_taskHandler.m_callDoneIf, success)) - invokeHandler(parentContainer(), m_taskHandler.m_doneHandler, *m_task.get(), success); + result = invokeHandler(parentContainer(), m_taskHandler.m_doneHandler, *m_task.get(), success); m_container.m_constData.m_taskTreePrivate->advanceProgress(1); + return result; } /*! diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index f09ec80ed7e..fa3b47ffaab 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -147,8 +147,8 @@ public: using TaskCreateHandler = std::function; // Called prior to task start, just after createHandler using TaskSetupHandler = std::function; - // Called on task done, just before delete later - using TaskDoneHandler = std::function; + // Called on task done, just before deleteLater + using TaskDoneHandler = std::function; // Called when group entered using GroupSetupHandler = std::function; // Called when group done / error @@ -335,20 +335,14 @@ public: "The Adapter type for the CustomTask needs to be derived from " "TaskAdapter."); using SetupFunction = std::function; - using DoneFunction = std::function; - using EndFunction = std::function; + using DoneFunction = std::function; static Adapter *createAdapter() { return new Adapter; } - CustomTask() : GroupItem({&createAdapter}) {} - template - CustomTask(SetupHandler &&setup, const EndFunction &done, CallDoneIf callDoneIf) - : GroupItem({&createAdapter, wrapSetup(std::forward(setup)), wrapEnd(done), - callDoneIf}) {} - template - CustomTask(SetupHandler &&setup, const DoneFunction &done = {}, + template + CustomTask(SetupHandler &&setup = SetupFunction(), DoneHandler &&done = DoneFunction(), CallDoneIf callDoneIf = CallDoneIf::SuccessOrError) - : GroupItem({&createAdapter, wrapSetup(std::forward(setup)), wrapDone(done), - callDoneIf}) + : GroupItem({&createAdapter, wrapSetup(std::forward(setup)), + wrapDone(std::forward(done)), callDoneIf}) {} GroupItem withTimeout(std::chrono::milliseconds timeout, @@ -357,17 +351,17 @@ public: } private: - template - static GroupItem::TaskSetupHandler wrapSetup(SetupHandler &&handler) { - if constexpr (std::is_same_v>) - return {}; // When user passed {} for setup handler. - static constexpr bool isDynamic = std::is_same_v, typename Adapter::TaskType &>>; - constexpr bool isVoid = std::is_same_v, typename Adapter::TaskType &>>; + template + static GroupItem::TaskSetupHandler wrapSetup(Handler &&handler) { + if constexpr (std::is_same_v) + return {}; // When user passed {} for the setup handler. + static constexpr bool isDynamic + = std::is_same_v, Task &>>; + constexpr bool isVoid + = std::is_same_v, Task &>>; static_assert(isDynamic || isVoid, - "Task setup handler needs to take (Task &) as an argument and has to return " - "void or SetupResult. The passed handler doesn't fulfill these requirements."); + "Task setup handler needs to take (Task &) as an argument (optionally) and has to " + "return void or SetupResult. The passed handler doesn't fulfill these requirements."); return [=](TaskInterface &taskInterface) { Adapter &adapter = static_cast(taskInterface); if constexpr (isDynamic) @@ -377,21 +371,42 @@ private: }; }; - static TaskDoneHandler wrapEnd(const EndFunction &handler) { - if (!handler) - return {}; - return [handler](const TaskInterface &taskInterface, bool) { + template + static GroupItem::TaskDoneHandler wrapDone(Handler &&handler) { + if constexpr (std::is_same_v) + return {}; // When user passed {} for the done handler. + static constexpr bool is2ArgDynamic + = std::is_invocable_r_v, const Task &, bool>; + static constexpr bool is1ArgDynamic + = std::is_invocable_r_v, const Task &>; + static constexpr bool is0ArgDynamic + = std::is_invocable_r_v>; + static constexpr bool is2ArgVoid + = std::is_invocable_r_v, const Task &, bool>; + static constexpr bool is1ArgVoid + = std::is_invocable_r_v, const Task &>; + static constexpr bool is0ArgVoid + = std::is_invocable_r_v>; + static constexpr bool isInvocable = is2ArgDynamic || is1ArgDynamic || is0ArgDynamic + || is2ArgVoid || is1ArgVoid || is0ArgVoid; + static_assert(isInvocable, + "Task done handler needs to take (const Task &, bool) as arguments (optionally) and " + "has to return void or bool. The passed handler doesn't fulfill these requirements."); + return [=](const TaskInterface &taskInterface, bool success) { const Adapter &adapter = static_cast(taskInterface); - handler(*adapter.task()); - }; - }; - - static TaskDoneHandler wrapDone(const DoneFunction &handler) { - if (!handler) - return {}; - return [handler](const TaskInterface &taskInterface, bool success) { - const Adapter &adapter = static_cast(taskInterface); - handler(*adapter.task(), success); + if constexpr (is2ArgDynamic) + return std::invoke(handler, *adapter.task(), success); + if constexpr (is1ArgDynamic) + return std::invoke(handler, *adapter.task()); + if constexpr (is0ArgDynamic) + return std::invoke(handler); + if constexpr (is2ArgVoid) + std::invoke(handler, *adapter.task(), success); + else if constexpr (is1ArgVoid) + std::invoke(handler, *adapter.task()); + else if constexpr (is0ArgVoid) + std::invoke(handler); + return success; }; }; }; @@ -429,9 +444,9 @@ public: template void onStorageSetup(const TreeStorage &storage, StorageHandler &&handler) { - constexpr bool isInvokable = std::is_invocable_v, + constexpr bool isInvocable = std::is_invocable_v, StorageStruct &>; - static_assert(isInvokable, + static_assert(isInvocable, "Storage setup handler needs to take (Storage &) as an argument. " "The passed handler doesn't fulfill these requirements."); setupStorageHandler(storage, @@ -439,9 +454,9 @@ public: } template void onStorageDone(const TreeStorage &storage, StorageHandler &&handler) { - constexpr bool isInvokable = std::is_invocable_v, + constexpr bool isInvocable = std::is_invocable_v, const StorageStruct &>; - static_assert(isInvokable, + static_assert(isInvocable, "Storage done handler needs to take (const Storage &) as an argument. " "The passed handler doesn't fulfill these requirements."); setupStorageHandler(storage, diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index 58ab4513df5..6908817617e 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -223,9 +223,10 @@ void tst_Tasking::testTree_data() }; }; - const auto setupDone = [storage](int taskId) { - return [storage, taskId](const TaskObject &, bool success) { - storage->m_log.append({taskId, success ? Handler::Done : Handler::Error}); + const auto setupDone = [storage](int taskId, bool successTask = true) { + return [storage, taskId, successTask](const TaskObject &, bool success) { + storage->m_log.append({taskId, successTask && success ? Handler::Done : Handler::Error}); + return successTask && success; }; }; @@ -237,14 +238,7 @@ void tst_Tasking::testTree_data() const auto createTask = [storage, setupTask, setupDone]( int taskId, bool successTask, milliseconds timeout = 0ms) -> GroupItem { - if (successTask) - return TestTask(setupTask(taskId, timeout), setupDone(taskId)); - const Group root { - finishAllAndError, - TestTask(setupTask(taskId, timeout)), - onGroupError([storage, taskId] { storage->m_log.append({taskId, Handler::Error}); }) - }; - return root; + return TestTask(setupTask(taskId, timeout), setupDone(taskId, successTask)); }; const auto createSuccessTask = [createTask](int taskId, milliseconds timeout = 0ms) { From b5f77f6d55093e5d471a4047c2b71a6b0df8708e Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 2 Nov 2023 23:19:49 +0100 Subject: [PATCH 0082/1546] TaskTree: Get rid of unneeded done handlers' arguments Task-number: QTCREATORBUG-29834 Change-Id: I236dec27a292a1b006b7001d01ce620960380de9 Reviewed-by: Reviewed-by: Marcus Tillmanns --- src/libs/utils/filestreamer.cpp | 10 +++++----- src/plugins/autotest/testrunner.cpp | 2 +- src/plugins/clangtools/clangtool.cpp | 4 ++-- src/plugins/cmakeprojectmanager/cmakebuildstep.cpp | 2 +- src/plugins/coreplugin/locator/ilocatorfilter.cpp | 2 +- src/plugins/coreplugin/plugininstallwizard.cpp | 2 +- src/plugins/debugger/loadcoredialog.cpp | 8 ++++---- src/plugins/git/branchmodel.cpp | 2 +- src/plugins/projectexplorer/abstractprocessstep.cpp | 2 +- src/plugins/qmakeprojectmanager/qmakestep.cpp | 2 +- src/plugins/remotelinux/genericdirectuploadstep.cpp | 2 +- tests/auto/solutions/tasking/tst_tasking.cpp | 8 ++++---- 12 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/libs/utils/filestreamer.cpp b/src/libs/utils/filestreamer.cpp index c85fe9e4801..b11bb6d3215 100644 --- a/src/libs/utils/filestreamer.cpp +++ b/src/libs/utils/filestreamer.cpp @@ -266,7 +266,7 @@ private: process.setWriteData(m_writeData); connect(&process, &Process::started, this, [this] { emit started(); }); }; - const auto onDone = [this](const Process &, bool) { + const auto onDone = [this] { delete m_writeBuffer; m_writeBuffer = nullptr; }; @@ -278,7 +278,7 @@ private: async.setConcurrentCallData(localWrite, m_filePath, m_writeData, m_writeBuffer); emit started(); }; - const auto onDone = [this](const Async &, bool) { + const auto onDone = [this] { delete m_writeBuffer; m_writeBuffer = nullptr; }; @@ -327,17 +327,17 @@ static Group interDeviceTransferTask(const FilePath &source, const FilePath &des SingleBarrier writerReadyBarrier; TreeStorage storage; - const auto onReaderSetup = [=](FileStreamReader &reader) { + const auto onReaderSetup = [storage, source](FileStreamReader &reader) { reader.setFilePath(source); QTC_CHECK(storage->writer != nullptr); QObject::connect(&reader, &FileStreamReader::readyRead, storage->writer, &FileStreamWriter::write); }; - const auto onReaderDone = [=](const FileStreamReader &, bool) { + const auto onReaderDone = [storage] { if (storage->writer) // writer may be deleted before the reader on TaskTree::stop(). storage->writer->closeWriteChannel(); }; - const auto onWriterSetup = [=](FileStreamWriter &writer) { + const auto onWriterSetup = [writerReadyBarrier, storage, destination](FileStreamWriter &writer) { writer.setFilePath(destination); QObject::connect(&writer, &FileStreamWriter::started, writerReadyBarrier->barrier(), &Barrier::advance); diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index 16ddf2717f4..270a77dba4a 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -410,7 +410,7 @@ void TestRunner::runTestsHelper() qCInfo(runnerLog) << "Working directory:" << process.workingDirectory(); qCDebug(runnerLog) << "Environment:" << process.environment().toStringList(); }; - const auto onProcessDone = [this, config, storage](const Process &process, bool) { + const auto onProcessDone = [this, config, storage](const Process &process) { TestStorage *testStorage = storage.activeStorage(); QTC_ASSERT(testStorage, return); if (process.result() == ProcessResult::StartFailed) { diff --git a/src/plugins/clangtools/clangtool.cpp b/src/plugins/clangtools/clangtool.cpp index d98d9e3a4a4..3f06d5144bf 100644 --- a/src/plugins/clangtools/clangtool.cpp +++ b/src/plugins/clangtools/clangtool.cpp @@ -686,7 +686,7 @@ Group ClangTool::runRecipe(const RunSettings &runSettings, const auto onSetup = [runControl](QPointer &buildRunControl) { buildRunControl = runControl; }; - const auto onError = [this](const QPointer &) { + const auto onError = [this] { const QString message(Tr::tr("Failed to build the project.")); m_infoBarWidget->setError(InfoBarWidget::Error, message, [this] { showOutputPane(); }); m_runControl->postMessage(message, ErrorMessageFormat); @@ -803,7 +803,7 @@ Group ClangTool::runRecipe(const RunSettings &runSettings, return SetupResult::Continue; }; - const auto onTreeDone = [this, target, runSettings](const TaskTree &) { + const auto onTreeDone = [this, target, runSettings] { if (m_filesFailed != 0) { m_runControl->postMessage(Tr::tr("Error: Failed to analyze %n files.", nullptr, m_filesFailed), ErrorMessageFormat); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp index 03a102a0d9c..6de133a6a36 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp @@ -365,7 +365,7 @@ GroupItem CMakeBuildStep::runRecipe() parseTarget = target(); return SetupResult::Continue; }; - const auto onParserError = [this](const QPointer &) { + const auto onParserError = [this] { emit addOutput(Tr::tr("Project did not parse successfully, cannot build."), OutputFormat::ErrorMessage); }; diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.cpp b/src/plugins/coreplugin/locator/ilocatorfilter.cpp index b8779c7f8f2..924bd6d8495 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/ilocatorfilter.cpp @@ -441,7 +441,7 @@ void LocatorMatcher::start() emit serialOutputDataReady(serialOutputData); }); }; - const auto onCollectorDone = [collectorStorage](const ResultsCollector &, bool) { + const auto onCollectorDone = [collectorStorage] { collectorStorage->m_collector = nullptr; }; diff --git a/src/plugins/coreplugin/plugininstallwizard.cpp b/src/plugins/coreplugin/plugininstallwizard.cpp index 510bf6ca8e7..9dc67ddfb29 100644 --- a/src/plugins/coreplugin/plugininstallwizard.cpp +++ b/src/plugins/coreplugin/plugininstallwizard.cpp @@ -230,7 +230,7 @@ public: m_output->append(output); }); }; - const auto onUnarchiverError = [this](const Unarchiver &) { + const auto onUnarchiverError = [this] { m_label->setType(InfoLabel::Error); m_label->setText(Tr::tr("There was an error while unarchiving.")); }; diff --git a/src/plugins/debugger/loadcoredialog.cpp b/src/plugins/debugger/loadcoredialog.cpp index 0cb395b68a3..88722a4e259 100644 --- a/src/plugins/debugger/loadcoredialog.cpp +++ b/src/plugins/debugger/loadcoredialog.cpp @@ -250,13 +250,13 @@ void AttachCoreDialog::accepted() const Group root = { parallel, - AsyncTask{[=](auto &task) { - task.setConcurrentCallData(copyFileAsync, this->coreFile()); + AsyncTask{[this, copyFileAsync](auto &task) { + task.setConcurrentCallData(copyFileAsync, coreFile()); }, [=](const auto &task) { d->coreFileResult = task.result(); }, CallDoneIf::Success}, - AsyncTask{[=](auto &task) { - task.setConcurrentCallData(copyFileAsync, this->symbolFile()); + AsyncTask{[this, copyFileAsync](auto &task) { + task.setConcurrentCallData(copyFileAsync, symbolFile()); }, [=](const auto &task) { d->symbolFileResult = task.result(); }, CallDoneIf::Success} diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp index b7b1355cf4e..5ac32a4ba6c 100644 --- a/src/plugins/git/branchmodel.cpp +++ b/src/plugins/git/branchmodel.cpp @@ -429,7 +429,7 @@ void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError) }; const auto onForEachRefDone = [this, workingDirectory, showError](const Process &process, - bool success) { + bool success) { if (!success) { if (showError == ShowError::No) return; diff --git a/src/plugins/projectexplorer/abstractprocessstep.cpp b/src/plugins/projectexplorer/abstractprocessstep.cpp index c64044259c8..b18e79502e9 100644 --- a/src/plugins/projectexplorer/abstractprocessstep.cpp +++ b/src/plugins/projectexplorer/abstractprocessstep.cpp @@ -164,7 +164,7 @@ GroupItem AbstractProcessStep::defaultProcessTask() const auto onSetup = [this](Process &process) { return setupProcess(process) ? SetupResult::Continue : SetupResult::StopWithError; }; - const auto onDone = [this](const Process &process, bool) { handleProcessDone(process); }; + const auto onDone = [this](const Process &process) { handleProcessDone(process); }; return ProcessTask(onSetup, onDone); } diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 53b7ab9048c..c95416ebd04 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -291,7 +291,7 @@ Tasking::GroupItem QMakeStep::runRecipe() return setupProcess(process) ? SetupResult::Continue : SetupResult::StopWithError; }; - const auto onProcessDone = [this](const Process &process, bool) { handleProcessDone(process); }; + const auto onProcessDone = [this](const Process &process) { handleProcessDone(process); }; const auto onDone = [this] { emit buildConfiguration()->buildDirectoryInitialized(); diff --git a/src/plugins/remotelinux/genericdirectuploadstep.cpp b/src/plugins/remotelinux/genericdirectuploadstep.cpp index 0e23a586f31..9f3de9bc21b 100644 --- a/src/plugins/remotelinux/genericdirectuploadstep.cpp +++ b/src/plugins/remotelinux/genericdirectuploadstep.cpp @@ -140,7 +140,7 @@ GroupItem GenericDirectUploadStep::statTask(UploadStorage *storage, process.setCommand({deviceConfiguration()->filePath("stat"), {"-t", Utils::ProcessArgs::quoteArgUnix(file.remoteFilePath())}}); }; - const auto onDone = [this, storage, file, statEndHandler](const Process &process, bool) { + const auto onDone = [this, storage, file, statEndHandler](const Process &process) { Process *proc = const_cast(&process); const QDateTime timestamp = timestampFromStat(file, proc); statEndHandler(storage, file, timestamp); diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index 6908817617e..a6dc8a3a264 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -78,8 +78,8 @@ void tst_Tasking::validConstructs() const Group task { parallel, TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}), - TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}), - TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}) + TestTask([](TaskObject &) {}, [](const TaskObject &) {}), + TestTask([](TaskObject &) {}, [] {}) }; const Group group1 { @@ -93,10 +93,10 @@ void tst_Tasking::validConstructs() TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}), Group { parallel, - TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}), + TestTask([](TaskObject &) {}, [](const TaskObject &) {}), Group { parallel, - TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}) + TestTask([](TaskObject &) {}, [] {}) } }, Group { From 84edd54699805e86020b55d5713f2c1c4af8da5d Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 2 Nov 2023 23:34:52 +0100 Subject: [PATCH 0083/1546] TaskTree tests: Add more valid constructs Change-Id: I7adea93ea7bddaffe157f1c32b538a2c99cae9d7 Reviewed-by: Reviewed-by: Qt CI Bot Reviewed-by: hjk Reviewed-by: Marcus Tillmanns --- tests/auto/solutions/tasking/tst_tasking.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index a6dc8a3a264..fc6952abd91 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -79,7 +79,14 @@ void tst_Tasking::validConstructs() parallel, TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}), TestTask([](TaskObject &) {}, [](const TaskObject &) {}), - TestTask([](TaskObject &) {}, [] {}) + TestTask([](TaskObject &) {}, [] {}), + TestTask([](TaskObject &) {}, {}), + TestTask([](TaskObject &) {}), + TestTask({}, [](const TaskObject &, bool) {}), + TestTask({}, [](const TaskObject &) {}), + TestTask({}, [] {}), + TestTask({}, {}), + TestTask({}), }; const Group group1 { From dda75153fe456e8f298573d20f337af41e5b78cc Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 3 Nov 2023 09:42:55 +0100 Subject: [PATCH 0084/1546] TaskTree: Introduce DoneWith enum This makes it possible to recognize the cancel state when the task was automatically stopped because of task's parent group workflow policy or when the user called TaskTree::stop(). This addresses the 2nd point in the master task below. Task-number: QTCREATORBUG-28741 Task-number: QTCREATORBUG-29834 Change-Id: I2798b9ec1d2f1d667aff51ee0271a5a15a525dc1 Reviewed-by: hjk Reviewed-by: --- src/libs/solutions/tasking/tasktree.cpp | 20 ++++++------- src/libs/solutions/tasking/tasktree.h | 29 ++++++++++++------- src/plugins/android/androidsdkdownloader.cpp | 8 ++--- src/plugins/boot2qt/qdbmakedefaultappstep.cpp | 4 +-- .../boot2qt/qdbstopapplicationstep.cpp | 4 +-- src/plugins/clangtools/clangtoolrunner.cpp | 14 ++++----- .../coreplugin/locator/javascriptfilter.cpp | 12 ++++---- src/plugins/git/branchmodel.cpp | 4 +-- src/plugins/git/gitclient.cpp | 8 ++--- src/plugins/projectexplorer/copystep.cpp | 4 +-- .../qnx/qnxdeployqtlibrariesdialog.cpp | 4 +-- src/plugins/qnx/qnxdevicetester.cpp | 4 +-- src/plugins/qnx/slog2inforunner.cpp | 4 +-- .../remotelinux/customcommanddeploystep.cpp | 4 +-- src/plugins/remotelinux/killappstep.cpp | 7 ++--- src/plugins/remotelinux/linuxdevicetester.cpp | 20 ++++++------- .../remotelinux/tarpackagecreationstep.cpp | 4 +-- .../remotelinux/tarpackagedeploystep.cpp | 8 ++--- src/plugins/subversion/subversionclient.cpp | 4 +-- .../vcsbase/vcsbasediffeditorcontroller.cpp | 5 ++-- tests/auto/solutions/tasking/tst_tasking.cpp | 19 ++++++------ .../tasking/imagescaling/imagescaling.cpp | 8 ++--- 22 files changed, 104 insertions(+), 94 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index fbc02a35f2f..1ff4c6116ef 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -1088,7 +1088,7 @@ public: // in order to unwind properly. SetupResult start(); void stop(); - bool invokeDoneHandler(bool success); + bool invokeDoneHandler(DoneWith result); bool isRunning() const { return m_task || m_container.isRunning(); } bool isTask() const { return bool(m_taskHandler.m_createHandler); } int taskCount() const { return isTask() ? 1 : m_container.m_constData.m_taskCount; } @@ -1450,7 +1450,7 @@ SetupResult TaskNode::start() const std::shared_ptr unwindAction = std::make_shared(SetupResult::Continue); QObject::connect(m_task.get(), &TaskInterface::done, taskTree(), [=](bool success) { - const bool result = invokeDoneHandler(success); + const bool result = invokeDoneHandler(success ? DoneWith::Success : DoneWith::Error); QObject::disconnect(m_task.get(), &TaskInterface::done, taskTree(), nullptr); m_task.release()->deleteLater(); QTC_ASSERT(parentContainer() && parentContainer()->isRunning(), return); @@ -1478,24 +1478,24 @@ void TaskNode::stop() // TODO: cancelHandler? // TODO: call TaskInterface::stop() ? - invokeDoneHandler(false); + invokeDoneHandler(DoneWith::Cancel); m_task.reset(); } -static bool shouldCall(CallDoneIf callDoneIf, bool success) +static bool shouldCall(CallDoneIf callDoneIf, DoneWith result) { - if (success) + if (result == DoneWith::Success) return callDoneIf != CallDoneIf::Error; return callDoneIf != CallDoneIf::Success; } -bool TaskNode::invokeDoneHandler(bool success) +bool TaskNode::invokeDoneHandler(DoneWith result) { - bool result = success; - if (m_taskHandler.m_doneHandler && shouldCall(m_taskHandler.m_callDoneIf, success)) - result = invokeHandler(parentContainer(), m_taskHandler.m_doneHandler, *m_task.get(), success); + bool success = result == DoneWith::Success; + if (m_taskHandler.m_doneHandler && shouldCall(m_taskHandler.m_callDoneIf, result)) + success = invokeHandler(parentContainer(), m_taskHandler.m_doneHandler, *m_task.get(), result); m_container.m_constData.m_taskTreePrivate->advanceProgress(1); - return result; + return success; } /*! diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index fa3b47ffaab..946922dda3f 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -132,6 +132,14 @@ enum class SetupResult }; Q_ENUM_NS(SetupResult); +enum class DoneWith +{ + Success, + Error, + Cancel +}; +Q_ENUM_NS(DoneWith); + enum class CallDoneIf { SuccessOrError, @@ -148,7 +156,7 @@ public: // Called prior to task start, just after createHandler using TaskSetupHandler = std::function; // Called on task done, just before deleteLater - using TaskDoneHandler = std::function; + using TaskDoneHandler = std::function; // Called when group entered using GroupSetupHandler = std::function; // Called when group done / error @@ -335,7 +343,7 @@ public: "The Adapter type for the CustomTask needs to be derived from " "TaskAdapter."); using SetupFunction = std::function; - using DoneFunction = std::function; + using DoneFunction = std::function; static Adapter *createAdapter() { return new Adapter; } template @@ -376,37 +384,38 @@ private: if constexpr (std::is_same_v) return {}; // When user passed {} for the done handler. static constexpr bool is2ArgDynamic - = std::is_invocable_r_v, const Task &, bool>; + = std::is_invocable_r_v, const Task &, DoneWith>; static constexpr bool is1ArgDynamic = std::is_invocable_r_v, const Task &>; static constexpr bool is0ArgDynamic = std::is_invocable_r_v>; static constexpr bool is2ArgVoid - = std::is_invocable_r_v, const Task &, bool>; + = std::is_invocable_r_v, const Task &, DoneWith>; static constexpr bool is1ArgVoid = std::is_invocable_r_v, const Task &>; static constexpr bool is0ArgVoid = std::is_invocable_r_v>; - static constexpr bool isInvocable = is2ArgDynamic || is1ArgDynamic || is0ArgDynamic - || is2ArgVoid || is1ArgVoid || is0ArgVoid; + static constexpr bool isInvocable = is2ArgDynamic || is2ArgVoid + || is1ArgDynamic || is1ArgVoid + || is0ArgDynamic || is0ArgVoid; static_assert(isInvocable, "Task done handler needs to take (const Task &, bool) as arguments (optionally) and " "has to return void or bool. The passed handler doesn't fulfill these requirements."); - return [=](const TaskInterface &taskInterface, bool success) { + return [=](const TaskInterface &taskInterface, DoneWith result) { const Adapter &adapter = static_cast(taskInterface); if constexpr (is2ArgDynamic) - return std::invoke(handler, *adapter.task(), success); + return std::invoke(handler, *adapter.task(), result); if constexpr (is1ArgDynamic) return std::invoke(handler, *adapter.task()); if constexpr (is0ArgDynamic) return std::invoke(handler); if constexpr (is2ArgVoid) - std::invoke(handler, *adapter.task(), success); + std::invoke(handler, *adapter.task(), result); else if constexpr (is1ArgVoid) std::invoke(handler, *adapter.task()); else if constexpr (is0ArgVoid) std::invoke(handler); - return success; + return result == DoneWith::Success; }; }; }; diff --git a/src/plugins/android/androidsdkdownloader.cpp b/src/plugins/android/androidsdkdownloader.cpp index 89e6d6f267b..492417d2353 100644 --- a/src/plugins/android/androidsdkdownloader.cpp +++ b/src/plugins/android/androidsdkdownloader.cpp @@ -130,11 +130,11 @@ void AndroidSdkDownloader::downloadAndExtractSdk() #endif }); }; - const auto onQueryDone = [this, storage](const NetworkQuery &query, bool success) { + const auto onQueryDone = [this, storage](const NetworkQuery &query, DoneWith result) { QNetworkReply *reply = query.reply(); QTC_ASSERT(reply, return); const QUrl url = reply->url(); - if (!success) { + if (result != DoneWith::Success) { logError(Tr::tr("Downloading Android SDK Tools from URL %1 has failed: %2.") .arg(url.toString(), reply->errorString())); return; @@ -171,8 +171,8 @@ void AndroidSdkDownloader::downloadAndExtractSdk() unarchiver.setDestDir(sdkFileName.parentDir()); return SetupResult::Continue; }; - const auto onUnarchiverDone = [this, storage](const Unarchiver &, bool success) { - if (!success) { + const auto onUnarchiverDone = [this, storage](const Unarchiver &, DoneWith result) { + if (result != DoneWith::Success) { logError(Tr::tr("Unarchiving error.")); return; } diff --git a/src/plugins/boot2qt/qdbmakedefaultappstep.cpp b/src/plugins/boot2qt/qdbmakedefaultappstep.cpp index 39d66f140d2..3a777ddcb81 100644 --- a/src/plugins/boot2qt/qdbmakedefaultappstep.cpp +++ b/src/plugins/boot2qt/qdbmakedefaultappstep.cpp @@ -55,8 +55,8 @@ private: handleStdErrData(proc->readAllStandardError()); }); }; - const auto onDone = [this](const Process &process, bool success) { - if (!success) + const auto onDone = [this](const Process &process, DoneWith result) { + if (result != DoneWith::Success) addErrorMessage(Tr::tr("Remote process failed: %1").arg(process.errorString())); else if (selection() == 0) addProgressMessage(Tr::tr("Application set as the default one.")); diff --git a/src/plugins/boot2qt/qdbstopapplicationstep.cpp b/src/plugins/boot2qt/qdbstopapplicationstep.cpp index 8a5002624ee..ce437993f34 100644 --- a/src/plugins/boot2qt/qdbstopapplicationstep.cpp +++ b/src/plugins/boot2qt/qdbstopapplicationstep.cpp @@ -54,8 +54,8 @@ GroupItem QdbStopApplicationStep::deployRecipe() }); return SetupResult::Continue; }; - const auto onDone = [this](const Process &process, bool success) { - if (success) { + const auto onDone = [this](const Process &process, DoneWith result) { + if (result == DoneWith::Success) { addProgressMessage(Tr::tr("Stopped the running application.")); return; } diff --git a/src/plugins/clangtools/clangtoolrunner.cpp b/src/plugins/clangtools/clangtoolrunner.cpp index 0bded02193d..f3f228d5439 100644 --- a/src/plugins/clangtools/clangtoolrunner.cpp +++ b/src/plugins/clangtools/clangtoolrunner.cpp @@ -163,12 +163,12 @@ GroupItem clangToolTask(const AnalyzeInputData &input, qCDebug(LOG).noquote() << "Starting" << commandLine.toUserOutput(); process.setCommand(commandLine); }; - const auto onProcessDone = [=](const Process &process, bool success) { + const auto onProcessDone = [=](const Process &process, DoneWith result) { qCDebug(LOG).noquote() << "Output:\n" << process.cleanedStdOut(); if (!outputHandler) return; - if (success) { + if (result == DoneWith::Success) { const QString stdErr = process.cleanedStdErr(); if (stdErr.isEmpty()) return; @@ -198,17 +198,17 @@ GroupItem clangToolTask(const AnalyzeInputData &input, input.diagnosticsFilter); data.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); }; - const auto onReadDone = [=](const Async> &data, bool success) { + const auto onReadDone = [=](const Async> &data, DoneWith result) { if (!outputHandler) return; - const expected_str result = data.result(); - const bool ok = success && result.has_value(); + const expected_str diagnosticsResult = data.result(); + const bool ok = result == DoneWith::Success && diagnosticsResult.has_value(); Diagnostics diagnostics; QString error; if (ok) - diagnostics = *result; + diagnostics = *diagnosticsResult; else - error = result.error(); + error = diagnosticsResult.error(); outputHandler({ok, input.unit.file, storage->outputFilePath, diff --git a/src/plugins/coreplugin/locator/javascriptfilter.cpp b/src/plugins/coreplugin/locator/javascriptfilter.cpp index 777b352e846..920ce605755 100644 --- a/src/plugins/coreplugin/locator/javascriptfilter.cpp +++ b/src/plugins/coreplugin/locator/javascriptfilter.cpp @@ -394,8 +394,8 @@ LocatorMatcherTasks JavaScriptFilter::matchers() request.setEngine(engine); request.setEvaluateData(storage->input()); }; - const auto onJavaScriptDone = [storage](const JavaScriptRequest &request, bool success) { - if (!success) { + const auto onJavaScriptDone = [storage](const JavaScriptRequest &request, DoneWith result) { + if (result != DoneWith::Success) { LocatorFilterEntry entry; entry.displayName = request.output().m_output; storage->reportOutput({entry}); @@ -408,15 +408,15 @@ LocatorMatcherTasks JavaScriptFilter::matchers() }; }; const QString input = storage->input(); - const QString result = request.output().m_output; - const QString expression = input + " = " + result; + const QString output = request.output().m_output; + const QString expression = input + " = " + output; LocatorFilterEntry entry; entry.displayName = expression; LocatorFilterEntry copyResultEntry; - copyResultEntry.displayName = Tr::tr("Copy to clipboard: %1").arg(result); - copyResultEntry.acceptor = acceptor(result); + copyResultEntry.displayName = Tr::tr("Copy to clipboard: %1").arg(output); + copyResultEntry.acceptor = acceptor(output); LocatorFilterEntry copyExpressionEntry; copyExpressionEntry.displayName = Tr::tr("Copy to clipboard: %1").arg(expression); diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp index 5ac32a4ba6c..421624bb5e6 100644 --- a/src/plugins/git/branchmodel.cpp +++ b/src/plugins/git/branchmodel.cpp @@ -429,8 +429,8 @@ void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError) }; const auto onForEachRefDone = [this, workingDirectory, showError](const Process &process, - bool success) { - if (!success) { + DoneWith result) { + if (result != DoneWith::Success) { if (showError == ShowError::No) return; const QString message = Tr::tr("Cannot run \"%1\" in \"%2\": %3") diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 38897f03630..24b02b736b7 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -423,10 +423,10 @@ ShowController::ShowController(IDocument *document, const QString &id) setupCommand(process, {"branch", noColorOption, "-a", "--contains", storage->m_commit}); VcsOutputWindow::appendCommand(process.workingDirectory(), process.commandLine()); }; - const auto onBranchesDone = [storage, updateDescription](const Process &process, bool success) { + const auto onBranchesDone = [storage, updateDescription](const Process &process, DoneWith result) { ReloadStorage *data = storage.activeStorage(); data->m_branches.clear(); - if (success) { + if (result == DoneWith::Success) { const QString remotePrefix = "remotes/"; const QString localPrefix = ""; const int prefixLength = remotePrefix.length(); @@ -469,10 +469,10 @@ ShowController::ShowController(IDocument *document, const QString &id) storage->m_precedes = busyMessage; setupCommand(process, {"describe", "--contains", storage->m_commit}); }; - const auto onPrecedesDone = [storage, updateDescription](const Process &process, bool success) { + const auto onPrecedesDone = [storage, updateDescription](const Process &process, DoneWith result) { ReloadStorage *data = storage.activeStorage(); data->m_precedes.clear(); - if (success) { + if (result == DoneWith::Success) { data->m_precedes = process.cleanedStdOut().trimmed(); const int tilde = data->m_precedes.indexOf('~'); if (tilde != -1) diff --git a/src/plugins/projectexplorer/copystep.cpp b/src/plugins/projectexplorer/copystep.cpp index b6262a0fe12..412dc2dfc55 100644 --- a/src/plugins/projectexplorer/copystep.cpp +++ b/src/plugins/projectexplorer/copystep.cpp @@ -52,8 +52,8 @@ private: streamer.setDestination(m_target); return SetupResult::Continue; }; - const auto onDone = [this](const FileStreamer &, bool success) { - if (success) + const auto onDone = [this](const FileStreamer &, DoneWith result) { + if (result == DoneWith::Success) addOutput(Tr::tr("Copying finished."), OutputFormat::NormalMessage); else addOutput(Tr::tr("Copying failed."), OutputFormat::ErrorMessage); diff --git a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp index b766de11f54..141e2cd5e60 100644 --- a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp +++ b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp @@ -124,8 +124,8 @@ GroupItem QnxDeployQtLibrariesDialogPrivate::checkDirTask() .arg(fullRemoteDirectory())); process.setCommand({m_device->filePath("test"), {"-d", fullRemoteDirectory()}}); }; - const auto onDone = [this](const Process &process, bool success) { - if (!success) { + const auto onDone = [this](const Process &process, DoneWith result) { + if (result != DoneWith::Success) { if (process.result() != ProcessResult::FinishedWithError) { m_deployLogWindow->appendPlainText(Tr::tr("Connection failed: %1") .arg(process.errorString())); diff --git a/src/plugins/qnx/qnxdevicetester.cpp b/src/plugins/qnx/qnxdevicetester.cpp index 1b4c35d5388..f4a94f0efc4 100644 --- a/src/plugins/qnx/qnxdevicetester.cpp +++ b/src/plugins/qnx/qnxdevicetester.cpp @@ -51,8 +51,8 @@ void QnxDeviceTester::testDevice(const ProjectExplorer::IDevice::Ptr &device) {"-c", QLatin1String("rm %1 > /dev/null 2>&1; echo ABC > %1 && rm %1").arg(pidFile)}); process.setCommand(cmd); }; - auto onDone = [this](const Process &process, bool success) { - if (success) { + auto onDone = [this](const Process &process, DoneWith result) { + if (result == DoneWith::Success) { emit progressMessage(Tr::tr("Files can be created in /var/run.") + '\n'); return; } diff --git a/src/plugins/qnx/slog2inforunner.cpp b/src/plugins/qnx/slog2inforunner.cpp index f56dea7c93c..c6c2bff84a8 100644 --- a/src/plugins/qnx/slog2inforunner.cpp +++ b/src/plugins/qnx/slog2inforunner.cpp @@ -37,8 +37,8 @@ void Slog2InfoRunner::start() const auto onTestSetup = [this](Process &process) { process.setCommand({device()->filePath("slog2info"), {}}); }; - const auto onTestDone = [this](const Process &, bool success) { - if (success) { + const auto onTestDone = [this](const Process &, DoneWith result) { + if (result == DoneWith::Success) { m_found = true; return; } diff --git a/src/plugins/remotelinux/customcommanddeploystep.cpp b/src/plugins/remotelinux/customcommanddeploystep.cpp index 1de16a6fedd..0c90f8350be 100644 --- a/src/plugins/remotelinux/customcommanddeploystep.cpp +++ b/src/plugins/remotelinux/customcommanddeploystep.cpp @@ -65,8 +65,8 @@ GroupItem CustomCommandDeployStep::deployRecipe() handleStdErrData(proc->readAllStandardError()); }); }; - const auto onDone = [this](const Process &process, bool success) { - if (success) { + const auto onDone = [this](const Process &process, DoneWith result) { + if (result == DoneWith::Success) { addProgressMessage(Tr::tr("Remote command finished successfully.")); } else if (process.error() != QProcess::UnknownError || process.exitStatus() != QProcess::NormalExit) { diff --git a/src/plugins/remotelinux/killappstep.cpp b/src/plugins/remotelinux/killappstep.cpp index 559ddbadcc8..020311e596f 100644 --- a/src/plugins/remotelinux/killappstep.cpp +++ b/src/plugins/remotelinux/killappstep.cpp @@ -55,10 +55,9 @@ GroupItem KillAppStep::deployRecipe() .arg(m_remoteExecutable.path())); return SetupResult::Continue; }; - const auto onDone = [this](const DeviceProcessKiller &, bool success) { - const QString message = success ? Tr::tr("Remote application killed.") - : Tr::tr("Failed to kill remote application. " - "Assuming it was not running."); + const auto onDone = [this](const DeviceProcessKiller &, DoneWith result) { + const QString message = result == DoneWith::Success ? Tr::tr("Remote application killed.") + : Tr::tr("Failed to kill remote application. Assuming it was not running."); addProgressMessage(message); }; return DeviceProcessKillerTask(onSetup, onDone); diff --git a/src/plugins/remotelinux/linuxdevicetester.cpp b/src/plugins/remotelinux/linuxdevicetester.cpp index dfbdea33306..7dcbedbd96f 100644 --- a/src/plugins/remotelinux/linuxdevicetester.cpp +++ b/src/plugins/remotelinux/linuxdevicetester.cpp @@ -96,8 +96,8 @@ GroupItem GenericLinuxDeviceTesterPrivate::echoTask(const QString &contents) con emit q->progressMessage(Tr::tr("Sending echo to device...")); process.setCommand({m_device->filePath("echo"), {contents}}); }; - const auto onDone = [this, contents](const Process &process, bool success) { - if (!success) { + const auto onDone = [this, contents](const Process &process, DoneWith result) { + if (result != DoneWith::Success) { const QString stdErrOutput = process.cleanedStdErr(); if (!stdErrOutput.isEmpty()) emit q->errorMessage(Tr::tr("echo failed: %1").arg(stdErrOutput) + '\n'); @@ -123,8 +123,8 @@ GroupItem GenericLinuxDeviceTesterPrivate::unameTask() const emit q->progressMessage(Tr::tr("Checking kernel version...")); process.setCommand({m_device->filePath("uname"), {"-rsm"}}); }; - const auto onDone = [this](const Process &process, bool success) { - if (success) { + const auto onDone = [this](const Process &process, DoneWith result) { + if (result == DoneWith::Success) { emit q->progressMessage(process.cleanedStdOut()); return; } @@ -146,8 +146,8 @@ GroupItem GenericLinuxDeviceTesterPrivate::gathererTask() const emit q->progressMessage(Tr::tr("Checking if specified ports are available...")); gatherer.setDevice(m_device); }; - const auto onDone = [this](const DeviceUsedPortsGatherer &gatherer, bool success) { - if (!success) { + const auto onDone = [this](const DeviceUsedPortsGatherer &gatherer, DoneWith result) { + if (result != DoneWith::Success) { emit q->errorMessage(Tr::tr("Error gathering ports: %1").arg(gatherer.errorString()) + '\n' + Tr::tr("Some tools will not work out of the box.\n")); } else if (gatherer.usedPorts().isEmpty()) { @@ -176,9 +176,9 @@ GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod metho transfer.setTransferMethod(method); transfer.setTestDevice(m_device); }; - const auto onDone = [this, method, storage](const FileTransfer &transfer, bool success) { + const auto onDone = [this, method, storage](const FileTransfer &transfer, DoneWith result) { const QString methodName = FileTransfer::transferMethodName(method); - if (success) { + if (result == DoneWith::Success) { emit q->progressMessage(Tr::tr("\"%1\" is functional.\n").arg(methodName)); if (method == FileTransferMethod::Rsync) m_device->setExtraData(Constants::SUPPORTS_RSYNC, true); @@ -247,8 +247,8 @@ GroupItem GenericLinuxDeviceTesterPrivate::commandTask(const QString &commandNam command.addArgs(QLatin1String("\"command -v %1\"").arg(commandName), CommandLine::Raw); process.setCommand(command); }; - const auto onDone = [this, commandName](const Process &process, bool success) { - if (success) { + const auto onDone = [this, commandName](const Process &process, DoneWith result) { + if (result == DoneWith::Success) { emit q->progressMessage(Tr::tr("%1 found.").arg(commandName)); return; } diff --git a/src/plugins/remotelinux/tarpackagecreationstep.cpp b/src/plugins/remotelinux/tarpackagecreationstep.cpp index 23b9c34e5ed..6393197c5aa 100644 --- a/src/plugins/remotelinux/tarpackagecreationstep.cpp +++ b/src/plugins/remotelinux/tarpackagecreationstep.cpp @@ -153,8 +153,8 @@ Tasking::GroupItem TarPackageCreationStep::runRecipe() async.setFutureSynchronizer(&m_synchronizer); return SetupResult::Continue; }; - const auto onDone = [this](const Async &, bool success) { - if (!success) { + const auto onDone = [this](const Async &, DoneWith result) { + if (result != DoneWith::Success) { emit addOutput(Tr::tr("Packaging failed."), OutputFormat::ErrorMessage); return; } diff --git a/src/plugins/remotelinux/tarpackagedeploystep.cpp b/src/plugins/remotelinux/tarpackagedeploystep.cpp index 6d393b00e40..957cce45104 100644 --- a/src/plugins/remotelinux/tarpackagedeploystep.cpp +++ b/src/plugins/remotelinux/tarpackagedeploystep.cpp @@ -74,8 +74,8 @@ GroupItem TarPackageDeployStep::uploadTask() connect(&transfer, &FileTransfer::progress, this, &TarPackageDeployStep::addProgressMessage); addProgressMessage(Tr::tr("Uploading package to device...")); }; - const auto onDone = [this](const FileTransfer &transfer, bool success) { - if (success) + const auto onDone = [this](const FileTransfer &transfer, DoneWith result) { + if (result == DoneWith::Success) addProgressMessage(Tr::tr("Successfully uploaded package file.")); else addErrorMessage(transfer.resultData().m_errorString); @@ -98,8 +98,8 @@ GroupItem TarPackageDeployStep::installTask() }); addProgressMessage(Tr::tr("Installing package to device...")); }; - const auto onDone = [this](const Process &process, bool success) { - if (success) { + const auto onDone = [this](const Process &process, DoneWith result) { + if (result == DoneWith::Success) { saveDeploymentTimeStamp(DeployableFile(m_packageFilePath, {}), {}); addProgressMessage(Tr::tr("Successfully installed package file.")); return; diff --git a/src/plugins/subversion/subversionclient.cpp b/src/plugins/subversion/subversionclient.cpp index 2a36f8d0d26..e1f45c1b34a 100644 --- a/src/plugins/subversion/subversionclient.cpp +++ b/src/plugins/subversion/subversionclient.cpp @@ -175,8 +175,8 @@ SubversionDiffEditorController::SubversionDiffEditorController(IDocument *docume setDescription(Tr::tr("Waiting for data...")); return SetupResult::Continue; }; - const auto onDescriptionDone = [this](const Process &process, bool success) { - setDescription(success ? process.cleanedStdOut() : QString()); + const auto onDescriptionDone = [this](const Process &process, DoneWith result) { + setDescription(result == DoneWith::Success ? process.cleanedStdOut() : QString()); }; const auto onDiffSetup = [this](Process &process) { diff --git a/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp b/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp index 0a4c915608f..62f2a001d1d 100644 --- a/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp +++ b/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp @@ -44,8 +44,9 @@ GroupItem VcsBaseDiffEditorController::postProcessTask(const TreeStorage> &async, bool success) { - setDiffFiles(success && async.isResultAvailable() ? async.result() : QList()); + const auto onDone = [this](const Async> &async, DoneWith result) { + setDiffFiles(result == DoneWith::Success && async.isResultAvailable() + ? async.result() : QList()); // TODO: We should set the right starting line here }; return AsyncTask>(onSetup, onDone); diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index fc6952abd91..370d02b8eb8 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -77,12 +77,12 @@ void tst_Tasking::validConstructs() { const Group task { parallel, - TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}), + TestTask([](TaskObject &) {}, [](const TaskObject &, DoneWith) {}), TestTask([](TaskObject &) {}, [](const TaskObject &) {}), TestTask([](TaskObject &) {}, [] {}), TestTask([](TaskObject &) {}, {}), TestTask([](TaskObject &) {}), - TestTask({}, [](const TaskObject &, bool) {}), + TestTask({}, [](const TaskObject &, DoneWith) {}), TestTask({}, [](const TaskObject &) {}), TestTask({}, [] {}), TestTask({}, {}), @@ -97,7 +97,7 @@ void tst_Tasking::validConstructs() parallel, Group { parallel, - TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}), + TestTask([](TaskObject &) {}, [](const TaskObject &, DoneWith) {}), Group { parallel, TestTask([](TaskObject &) {}, [](const TaskObject &) {}), @@ -108,7 +108,7 @@ void tst_Tasking::validConstructs() }, Group { parallel, - TestTask([](TaskObject &) {}, [](const TaskObject &, bool) {}), + TestTask([](TaskObject &) {}, [](const TaskObject &, DoneWith) {}), onGroupDone([] {}) } }, @@ -120,7 +120,7 @@ void tst_Tasking::validConstructs() const auto setupHandler = [](TaskObject &) {}; const auto finishHandler = [](const TaskObject &) {}; const auto errorHandler = [](const TaskObject &) {}; - const auto doneHandler = [](const TaskObject &, bool) {}; + const auto doneHandler = [](const TaskObject &, DoneWith) {}; const Group task2 { parallel, @@ -230,10 +230,11 @@ void tst_Tasking::testTree_data() }; }; - const auto setupDone = [storage](int taskId, bool successTask = true) { - return [storage, taskId, successTask](const TaskObject &, bool success) { - storage->m_log.append({taskId, successTask && success ? Handler::Done : Handler::Error}); - return successTask && success; + const auto setupDone = [storage](int taskId, bool success = true) { + return [storage, taskId, success](const TaskObject &, DoneWith result) { + const bool done = success && result != DoneWith::Cancel; + storage->m_log.append({taskId, done ? Handler::Done : Handler::Error}); + return done; }; }; diff --git a/tests/manual/tasking/imagescaling/imagescaling.cpp b/tests/manual/tasking/imagescaling/imagescaling.cpp index 5d2992d87cd..fe90bcf546a 100644 --- a/tests/manual/tasking/imagescaling/imagescaling.cpp +++ b/tests/manual/tasking/imagescaling/imagescaling.cpp @@ -79,8 +79,8 @@ void Images::process() query.setNetworkAccessManager(&qnam); query.setRequest(QNetworkRequest(url)); }; - const auto onDownloadDone = [this, storage, i](const NetworkQuery &query, bool success) { - if (success) + const auto onDownloadDone = [this, storage, i](const NetworkQuery &query, DoneWith result) { + if (result == DoneWith::Success) *storage = query.reply()->readAll(); else labels[i]->setText(tr("Download\nError.\nCode: %1.").arg(query.reply()->error())); @@ -89,8 +89,8 @@ void Images::process() const auto onScalingSetup = [storage](ConcurrentCall &data) { data.setConcurrentCallData(&scale, *storage); }; - const auto onScalingDone = [this, i](const ConcurrentCall &data, bool success) { - if (success) + const auto onScalingDone = [this, i](const ConcurrentCall &data, DoneWith result) { + if (result == DoneWith::Success) labels[i]->setPixmap(QPixmap::fromImage(data.result())); else labels[i]->setText(tr("Image\nData\nError.")); From 35e03499f0790a46c3593207655e3fc9053ff4b5 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 3 Nov 2023 10:36:11 +0100 Subject: [PATCH 0085/1546] TaskTree tests: Detect canceled state Task-number: QTCREATORBUG-28741 Task-number: QTCREATORBUG-29834 Change-Id: I057d23efe754b2f6c3f7b6b28b357d0e1ec24eb6 Reviewed-by: Reviewed-by: hjk --- tests/auto/solutions/tasking/tst_tasking.cpp | 316 ++++++++++--------- 1 file changed, 159 insertions(+), 157 deletions(-) diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index 370d02b8eb8..cd015d12d67 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -19,10 +19,11 @@ Q_NAMESPACE enum class Handler { Setup, - Done, + Success, Error, + Canceled, GroupSetup, - GroupDone, + GroupSuccess, GroupError, Sync, BarrierAdvance, @@ -232,9 +233,10 @@ void tst_Tasking::testTree_data() const auto setupDone = [storage](int taskId, bool success = true) { return [storage, taskId, success](const TaskObject &, DoneWith result) { - const bool done = success && result != DoneWith::Cancel; - storage->m_log.append({taskId, done ? Handler::Done : Handler::Error}); - return done; + const Handler handler = result == DoneWith::Cancel ? Handler::Canceled + : success ? Handler::Success : Handler::Error; + storage->m_log.append({taskId, handler}); + return success && result != DoneWith::Cancel; }; }; @@ -245,7 +247,7 @@ void tst_Tasking::testTree_data() }; const auto createTask = [storage, setupTask, setupDone]( - int taskId, bool successTask, milliseconds timeout = 0ms) -> GroupItem { + int taskId, bool successTask, milliseconds timeout = 0ms) { return TestTask(setupTask(taskId, timeout), setupDone(taskId, successTask)); }; @@ -266,7 +268,7 @@ void tst_Tasking::testTree_data() return onGroupSetup([=] { storage->m_log.append({taskId, Handler::GroupSetup}); }); }; const auto groupDone = [storage](int taskId) { - return onGroupDone([=] { storage->m_log.append({taskId, Handler::GroupDone}); }); + return onGroupDone([=] { storage->m_log.append({taskId, Handler::GroupSuccess}); }); }; const auto groupError = [storage](int taskId) { return onGroupError([=] { storage->m_log.append({taskId, Handler::GroupError}); }); @@ -303,7 +305,7 @@ void tst_Tasking::testTree_data() groupError(0) }; - const Log logDone {{0, Handler::GroupDone}}; + const Log logDone {{0, Handler::GroupSuccess}}; const Log logError {{0, Handler::GroupError}}; QTest::newRow("Empty") << TestData{storage, root1, logDone, 0, OnDone::Success}; @@ -325,7 +327,7 @@ void tst_Tasking::testTree_data() const auto doneData = [storage, setupGroup](WorkflowPolicy policy) { return TestData{storage, setupGroup(SetupResult::StopWithDone, policy), - Log{{0, Handler::GroupDone}}, 0, OnDone::Success}; + Log{{0, Handler::GroupSuccess}}, 0, OnDone::Success}; }; const auto errorData = [storage, setupGroup](WorkflowPolicy policy) { return TestData{storage, setupGroup(SetupResult::StopWithError, policy), @@ -379,9 +381,9 @@ void tst_Tasking::testTree_data() }; const Log log { {1, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {2, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {3, Handler::Setup} }; QTest::newRow("DynamicMixed") << TestData{storage, root, log, 4, OnDone::Failure}; @@ -400,8 +402,8 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::Setup}, {3, Handler::Setup}, - {1, Handler::Error}, - {2, Handler::Error} + {1, Handler::Canceled}, + {2, Handler::Canceled} }; QTest::newRow("DynamicParallel") << TestData{storage, root, log, 4, OnDone::Failure}; } @@ -421,8 +423,8 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::Setup}, {3, Handler::Setup}, - {1, Handler::Error}, - {2, Handler::Error} + {1, Handler::Canceled}, + {2, Handler::Canceled} }; QTest::newRow("DynamicParallelGroup") << TestData{storage, root, log, 4, OnDone::Failure}; } @@ -446,8 +448,8 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::Setup}, {0, Handler::GroupSetup}, - {1, Handler::Error}, - {2, Handler::Error} + {1, Handler::Canceled}, + {2, Handler::Canceled} }; QTest::newRow("DynamicParallelGroupSetup") << TestData{storage, root, log, 4, OnDone::Failure}; @@ -486,13 +488,13 @@ void tst_Tasking::testTree_data() {4, Handler::GroupSetup}, {5, Handler::GroupSetup}, {5, Handler::Setup}, - {5, Handler::Done}, - {5, Handler::GroupDone}, - {4, Handler::GroupDone}, - {3, Handler::GroupDone}, - {2, Handler::GroupDone}, - {1, Handler::GroupDone}, - {0, Handler::GroupDone} + {5, Handler::Success}, + {5, Handler::GroupSuccess}, + {4, Handler::GroupSuccess}, + {3, Handler::GroupSuccess}, + {2, Handler::GroupSuccess}, + {1, Handler::GroupSuccess}, + {0, Handler::GroupSuccess} }; QTest::newRow("Nested") << TestData{storage, root, log, 1, OnDone::Success}; } @@ -514,12 +516,12 @@ void tst_Tasking::testTree_data() {3, Handler::Setup}, {4, Handler::Setup}, {5, Handler::Setup}, - {1, Handler::Done}, - {2, Handler::Done}, - {3, Handler::Done}, - {4, Handler::Done}, - {5, Handler::Done}, - {0, Handler::GroupDone} + {1, Handler::Success}, + {2, Handler::Success}, + {3, Handler::Success}, + {4, Handler::Success}, + {5, Handler::Success}, + {0, Handler::GroupSuccess} }; QTest::newRow("Parallel") << TestData{storage, root, log, 5, OnDone::Success}; } @@ -566,16 +568,16 @@ void tst_Tasking::testTree_data() }; const Log log { {1, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {2, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {3, Handler::Setup}, - {3, Handler::Done}, + {3, Handler::Success}, {4, Handler::Setup}, - {4, Handler::Done}, + {4, Handler::Success}, {5, Handler::Setup}, - {5, Handler::Done}, - {0, Handler::GroupDone} + {5, Handler::Success}, + {0, Handler::GroupSuccess} }; QTest::newRow("Sequential") << TestData{storage, root1, log, 5, OnDone::Success}; QTest::newRow("SequentialEncapsulated") << TestData{storage, root2, log, 5, OnDone::Success}; @@ -610,21 +612,21 @@ void tst_Tasking::testTree_data() }; const Log log { {1, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {2, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {3, Handler::Setup}, - {3, Handler::Done}, + {3, Handler::Success}, {4, Handler::Setup}, - {4, Handler::Done}, + {4, Handler::Success}, {5, Handler::Setup}, - {5, Handler::Done}, - {5, Handler::GroupDone}, - {4, Handler::GroupDone}, - {3, Handler::GroupDone}, - {2, Handler::GroupDone}, - {1, Handler::GroupDone}, - {0, Handler::GroupDone} + {5, Handler::Success}, + {5, Handler::GroupSuccess}, + {4, Handler::GroupSuccess}, + {3, Handler::GroupSuccess}, + {2, Handler::GroupSuccess}, + {1, Handler::GroupSuccess}, + {0, Handler::GroupSuccess} }; QTest::newRow("SequentialNested") << TestData{storage, root, log, 5, OnDone::Success}; } @@ -642,9 +644,9 @@ void tst_Tasking::testTree_data() }; const Log log { {1, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {2, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {3, Handler::Setup}, {3, Handler::Error}, {0, Handler::GroupError} @@ -662,7 +664,7 @@ void tst_Tasking::testTree_data() }; }; - const Log doneLog = {{0, Handler::GroupDone}}; + const Log doneLog = {{0, Handler::GroupSuccess}}; const Log errorLog = {{0, Handler::GroupError}}; const Group root1 = createRoot(WorkflowPolicy::StopOnError); @@ -708,13 +710,13 @@ void tst_Tasking::testTree_data() const Log doneLog = { {1, Handler::Setup}, - {1, Handler::Done}, - {0, Handler::GroupDone} + {1, Handler::Success}, + {0, Handler::GroupSuccess} }; const Log errorLog = { {1, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {0, Handler::GroupError} }; @@ -762,7 +764,7 @@ void tst_Tasking::testTree_data() const Log doneLog = { {1, Handler::Setup}, {1, Handler::Error}, - {0, Handler::GroupDone} + {0, Handler::GroupSuccess} }; const Log errorLog = { @@ -821,7 +823,7 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::Setup}, {1, Handler::Error}, - {2, Handler::Error}, + {2, Handler::Canceled}, {0, Handler::GroupError} }; @@ -829,7 +831,7 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::Setup}, {1, Handler::Error}, - {2, Handler::Done}, + {2, Handler::Success}, {0, Handler::GroupError} }; @@ -837,8 +839,8 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::Setup}, {1, Handler::Error}, - {2, Handler::Done}, - {0, Handler::GroupDone} + {2, Handler::Success}, + {0, Handler::GroupSuccess} }; const Group root1 = createRoot(WorkflowPolicy::StopOnError); @@ -893,9 +895,9 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::Setup}, {3, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {2, Handler::Error}, - {3, Handler::Error}, + {3, Handler::Canceled}, {0, Handler::GroupError} }; @@ -903,9 +905,9 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::Setup}, {3, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {2, Handler::Error}, - {3, Handler::Done}, + {3, Handler::Success}, {0, Handler::GroupError} }; @@ -913,20 +915,20 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::Setup}, {3, Handler::Setup}, - {1, Handler::Done}, - {2, Handler::Error}, - {3, Handler::Error}, - {0, Handler::GroupDone} + {1, Handler::Success}, + {2, Handler::Canceled}, + {3, Handler::Canceled}, + {0, Handler::GroupSuccess} }; const Log doneDoneLog = { {1, Handler::Setup}, {2, Handler::Setup}, {3, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {2, Handler::Error}, - {3, Handler::Done}, - {0, Handler::GroupDone} + {3, Handler::Success}, + {0, Handler::GroupSuccess} }; const Group root1 = createRoot(WorkflowPolicy::StopOnError); @@ -983,7 +985,7 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::Setup}, {2, Handler::Error}, - {1, Handler::Error}, + {1, Handler::Canceled}, {1, Handler::GroupError}, {2, Handler::GroupError} }; @@ -992,8 +994,8 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::Setup}, {2, Handler::Error}, - {1, Handler::Error}, - {1, Handler::GroupDone}, + {1, Handler::Canceled}, + {1, Handler::GroupSuccess}, {2, Handler::GroupError} }; @@ -1051,10 +1053,10 @@ void tst_Tasking::testTree_data() const Log errorLog = { {1, Handler::Setup}, {3, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {2, Handler::Setup}, {3, Handler::Error}, - {2, Handler::Error}, + {2, Handler::Canceled}, {1, Handler::GroupError}, {2, Handler::GroupError} }; @@ -1062,8 +1064,8 @@ void tst_Tasking::testTree_data() const Log shortDoneLog = { {1, Handler::Setup}, {3, Handler::Setup}, - {1, Handler::Done}, - {1, Handler::GroupDone}, + {1, Handler::Success}, + {1, Handler::GroupSuccess}, {3, Handler::Error}, {2, Handler::GroupError} }; @@ -1071,11 +1073,11 @@ void tst_Tasking::testTree_data() const Log longDoneLog = { {1, Handler::Setup}, {3, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {2, Handler::Setup}, {3, Handler::Error}, - {2, Handler::Error}, - {1, Handler::GroupDone}, + {2, Handler::Canceled}, + {1, Handler::GroupSuccess}, {2, Handler::GroupError} }; @@ -1135,7 +1137,7 @@ void tst_Tasking::testTree_data() {3, Handler::Setup}, {1, Handler::Error}, {1, Handler::GroupError}, - {3, Handler::Error}, + {3, Handler::Canceled}, {2, Handler::GroupError} }; @@ -1145,7 +1147,7 @@ void tst_Tasking::testTree_data() {1, Handler::Error}, {2, Handler::Setup}, {3, Handler::Error}, - {2, Handler::Error}, + {2, Handler::Canceled}, {1, Handler::GroupError}, {2, Handler::GroupError} }; @@ -1156,8 +1158,8 @@ void tst_Tasking::testTree_data() {1, Handler::Error}, {2, Handler::Setup}, {3, Handler::Error}, - {2, Handler::Error}, - {1, Handler::GroupDone}, + {2, Handler::Canceled}, + {1, Handler::GroupSuccess}, {2, Handler::GroupError} }; @@ -1207,7 +1209,7 @@ void tst_Tasking::testTree_data() const Group root1 = createRoot(WorkflowPolicy::StopOnError); const Log log1 { {1, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {2, Handler::Setup}, {2, Handler::Error}, {0, Handler::GroupError} @@ -1217,11 +1219,11 @@ void tst_Tasking::testTree_data() const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); const Log errorLog { {1, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {2, Handler::Setup}, {2, Handler::Error}, {3, Handler::Setup}, - {3, Handler::Done}, + {3, Handler::Success}, {0, Handler::GroupError} }; QTest::newRow("ContinueOnError") << TestData{storage, root2, errorLog, 3, OnDone::Failure}; @@ -1229,28 +1231,28 @@ void tst_Tasking::testTree_data() const Group root3 = createRoot(WorkflowPolicy::StopOnDone); const Log log3 { {1, Handler::Setup}, - {1, Handler::Done}, - {0, Handler::GroupDone} + {1, Handler::Success}, + {0, Handler::GroupSuccess} }; QTest::newRow("StopOnDone") << TestData{storage, root3, log3, 3, OnDone::Success}; const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); const Log doneLog { {1, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {2, Handler::Setup}, {2, Handler::Error}, {3, Handler::Setup}, - {3, Handler::Done}, - {0, Handler::GroupDone} + {3, Handler::Success}, + {0, Handler::GroupSuccess} }; QTest::newRow("ContinueOnDone") << TestData{storage, root4, doneLog, 3, OnDone::Success}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); const Log log5 { {1, Handler::Setup}, - {1, Handler::Done}, - {0, Handler::GroupDone} + {1, Handler::Success}, + {0, Handler::GroupSuccess} }; QTest::newRow("StopOnFinished") << TestData{storage, root5, log5, 3, OnDone::Success}; @@ -1283,15 +1285,15 @@ void tst_Tasking::testTree_data() const Log success { {1, Handler::Setup}, {2, Handler::Setup}, - {2, Handler::Done}, - {1, Handler::Error}, - {0, Handler::GroupDone} + {2, Handler::Success}, + {1, Handler::Canceled}, + {0, Handler::GroupSuccess} }; const Log failure { {1, Handler::Setup}, {2, Handler::Setup}, {2, Handler::Error}, - {1, Handler::Error}, + {1, Handler::Canceled}, {0, Handler::GroupError} }; @@ -1323,15 +1325,15 @@ void tst_Tasking::testTree_data() const Group root1 = createRoot(SetupResult::StopWithDone); const Log log1 { {1, Handler::Setup}, - {1, Handler::Done}, - {0, Handler::GroupDone} + {1, Handler::Success}, + {0, Handler::GroupSuccess} }; QTest::newRow("DynamicSetupDone") << TestData{storage, root1, log1, 4, OnDone::Success}; const Group root2 = createRoot(SetupResult::StopWithError); const Log log2 { {1, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {0, Handler::GroupError} }; QTest::newRow("DynamicSetupError") << TestData{storage, root2, log2, 4, OnDone::Failure}; @@ -1339,14 +1341,14 @@ void tst_Tasking::testTree_data() const Group root3 = createRoot(SetupResult::Continue); const Log log3 { {1, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {2, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {3, Handler::Setup}, - {3, Handler::Done}, + {3, Handler::Success}, {4, Handler::Setup}, - {4, Handler::Done}, - {0, Handler::GroupDone} + {4, Handler::Success}, + {0, Handler::GroupSuccess} }; QTest::newRow("DynamicSetupContinue") << TestData{storage, root3, log3, 4, OnDone::Success}; } @@ -1377,14 +1379,14 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::GroupSetup}, {2, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {3, Handler::GroupSetup}, {3, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {4, Handler::GroupSetup}, {4, Handler::Setup}, - {3, Handler::Done}, - {4, Handler::Done} + {3, Handler::Success}, + {4, Handler::Success} }; QTest::newRow("NestedParallel") << TestData{storage, root, log, 4, OnDone::Success}; } @@ -1419,16 +1421,16 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::GroupSetup}, {2, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {3, Handler::GroupSetup}, {3, Handler::Setup}, {4, Handler::GroupSetup}, {4, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {5, Handler::GroupSetup}, {5, Handler::Setup}, - {4, Handler::Done}, - {5, Handler::Done} + {4, Handler::Success}, + {5, Handler::Success} }; QTest::newRow("NestedParallelDone") << TestData{storage, root, log, 5, OnDone::Success}; } @@ -1463,10 +1465,10 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::GroupSetup}, {2, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {3, Handler::GroupSetup}, {3, Handler::Setup}, - {2, Handler::Error} + {2, Handler::Canceled} }; // Inside this test the task 2 should finish first, then synchonously: @@ -1502,10 +1504,10 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::GroupSetup}, {2, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {3, Handler::GroupSetup}, {3, Handler::Setup}, - {1, Handler::Error} + {1, Handler::Canceled} }; // This test ensures that the task 1 doesn't invoke its done handler, @@ -1548,13 +1550,13 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::GroupSetup}, {2, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {3, Handler::GroupSetup}, {3, Handler::Setup}, - {1, Handler::Error}, + {1, Handler::Canceled}, {5, Handler::GroupSetup}, {5, Handler::Setup}, - {5, Handler::Done} + {5, Handler::Success} }; QTest::newRow("NestedParallelError1") << TestData{storage, root1, log1, 5, OnDone::Failure}; @@ -1602,14 +1604,14 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::GroupSetup}, {2, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {3, Handler::GroupSetup}, {3, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {4, Handler::GroupSetup}, {4, Handler::Setup}, - {3, Handler::Done}, - {4, Handler::Done} + {3, Handler::Success}, + {4, Handler::Success} }; QTest::newRow("DeeplyNestedParallel") << TestData{storage, root, log, 4, OnDone::Success}; } @@ -1644,16 +1646,16 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::GroupSetup}, {2, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {3, Handler::GroupSetup}, {3, Handler::Setup}, {4, Handler::GroupSetup}, {4, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {5, Handler::GroupSetup}, {5, Handler::Setup}, - {4, Handler::Done}, - {5, Handler::Done} + {4, Handler::Success}, + {5, Handler::Success} }; QTest::newRow("DeeplyNestedParallelDone") << TestData{storage, root, log, 5, OnDone::Success}; @@ -1689,10 +1691,10 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {2, Handler::GroupSetup}, {2, Handler::Setup}, - {1, Handler::Done}, + {1, Handler::Success}, {3, Handler::GroupSetup}, {3, Handler::Setup}, - {2, Handler::Error} + {2, Handler::Canceled} }; QTest::newRow("DeeplyNestedParallelError") << TestData{storage, root, log, 5, OnDone::Failure}; @@ -1787,12 +1789,12 @@ void tst_Tasking::testTree_data() const Log log { {1, Handler::Sync}, {2, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {3, Handler::Sync}, {4, Handler::Setup}, - {4, Handler::Done}, + {4, Handler::Success}, {5, Handler::Sync}, - {0, Handler::GroupDone} + {0, Handler::GroupSuccess} }; QTest::newRow("SyncAndAsync") << TestData{storage, root, log, 2, OnDone::Success}; } @@ -1810,7 +1812,7 @@ void tst_Tasking::testTree_data() const Log log { {1, Handler::Sync}, {2, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {3, Handler::Sync}, {0, Handler::GroupError} }; @@ -1840,9 +1842,9 @@ void tst_Tasking::testTree_data() {1, Handler::BarrierAdvance}, {2, Handler::GroupSetup}, {2, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {3, Handler::Setup}, - {3, Handler::Done} + {3, Handler::Success} }; // Test that barrier advance, triggered from inside the task described by @@ -1865,9 +1867,9 @@ void tst_Tasking::testTree_data() {2, Handler::GroupSetup}, {1, Handler::BarrierAdvance}, {2, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {3, Handler::Setup}, - {3, Handler::Done} + {3, Handler::Success} }; // Test that barrier advance, triggered from inside the task described by @@ -1897,9 +1899,9 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {1, Handler::BarrierAdvance}, {2, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {3, Handler::Setup}, - {3, Handler::Done} + {3, Handler::Success} }; // Test that barrier advance, triggered from inside the task described by @@ -1928,8 +1930,8 @@ void tst_Tasking::testTree_data() {1, Handler::BarrierAdvance}, {4, Handler::Setup}, {5, Handler::Setup}, - {4, Handler::Done}, - {5, Handler::Done} + {4, Handler::Success}, + {5, Handler::Success} }; // Test two separate single barriers. @@ -1960,7 +1962,7 @@ void tst_Tasking::testTree_data() {1, Handler::BarrierAdvance}, {2, Handler::BarrierAdvance}, {3, Handler::Setup}, - {3, Handler::Done} + {3, Handler::Success} }; // Notice the different log order for each scenario. @@ -2002,9 +2004,9 @@ void tst_Tasking::testTree_data() {2, Handler::BarrierAdvance}, {2, Handler::GroupSetup}, {2, Handler::Setup}, - {2, Handler::Done}, + {2, Handler::Success}, {3, Handler::Setup}, - {3, Handler::Done} + {3, Handler::Success} }; // Test that multi barrier advance, triggered from inside the tasks described by @@ -2030,9 +2032,9 @@ void tst_Tasking::testTree_data() {1, Handler::BarrierAdvance}, {2, Handler::BarrierAdvance}, {3, Handler::Setup}, - {3, Handler::Done}, + {3, Handler::Success}, {4, Handler::Setup}, - {4, Handler::Done} + {4, Handler::Success} }; // Test that multi barrier advance, triggered from inside the tasks described by @@ -2065,9 +2067,9 @@ void tst_Tasking::testTree_data() {1, Handler::BarrierAdvance}, {2, Handler::BarrierAdvance}, {3, Handler::Setup}, - {3, Handler::Done}, + {3, Handler::Success}, {4, Handler::Setup}, - {4, Handler::Done} + {4, Handler::Success} }; // Test that multi barrier advance, triggered from inside the task described by @@ -2099,8 +2101,8 @@ void tst_Tasking::testTree_data() {2, Handler::BarrierAdvance}, {3, Handler::Setup}, {4, Handler::Setup}, - {3, Handler::Done}, - {4, Handler::Done} + {3, Handler::Success}, + {4, Handler::Success} }; // Notice the different log order for each scenario. @@ -2125,7 +2127,7 @@ void tst_Tasking::testTree_data() }; const Log log1 { {1, Handler::Setup}, - {1, Handler::Error} + {1, Handler::Canceled} }; QTest::newRow("TaskErrorWithTimeout") << TestData{storage, root1, log1, 2, OnDone::Failure}; @@ -2138,7 +2140,7 @@ void tst_Tasking::testTree_data() const Log log2 { {1, Handler::Setup}, {1, Handler::Timeout}, - {1, Handler::Error} + {1, Handler::Canceled} }; QTest::newRow("TaskErrorWithTimeoutHandler") << TestData{storage, root2, log2, 2, OnDone::Failure}; @@ -2150,7 +2152,7 @@ void tst_Tasking::testTree_data() }; const Log doneLog { {1, Handler::Setup}, - {1, Handler::Done} + {1, Handler::Success} }; QTest::newRow("TaskDoneWithTimeout") << TestData{storage, root3, doneLog, 2, OnDone::Success}; @@ -2176,7 +2178,7 @@ void tst_Tasking::testTree_data() }; const Log log1 { {1, Handler::Setup}, - {1, Handler::Error} + {1, Handler::Canceled} }; QTest::newRow("GroupErrorWithTimeout") << TestData{storage, root1, log1, 2, OnDone::Failure}; @@ -2191,7 +2193,7 @@ void tst_Tasking::testTree_data() const Log log2 { {1, Handler::Setup}, {1, Handler::Timeout}, - {1, Handler::Error} + {1, Handler::Canceled} }; QTest::newRow("GroupErrorWithTimeoutHandler") << TestData{storage, root2, log2, 2, OnDone::Failure}; @@ -2204,7 +2206,7 @@ void tst_Tasking::testTree_data() }; const Log doneLog { {1, Handler::Setup}, - {1, Handler::Done} + {1, Handler::Success} }; QTest::newRow("GroupDoneWithTimeout") << TestData{storage, root3, doneLog, 2, OnDone::Success}; From f84e3074cd48951476d7545569e6aa91e557feb5 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 3 Nov 2023 14:42:55 +0100 Subject: [PATCH 0086/1546] TaskTree: Make it possible to invoke done handler only with DoneResult Remove unused "const Task &" argument from done handlers. Task-number: QTCREATORBUG-29834 Change-Id: I0e69c1eba88d9fdb78de7ba1705ff3916999dc89 Reviewed-by: hjk Reviewed-by: --- src/libs/solutions/tasking/tasktree.h | 46 +++++++++++-------- src/plugins/android/androidsdkdownloader.cpp | 2 +- src/plugins/debugger/loadcoredialog.cpp | 4 +- src/plugins/diffeditor/diffeditorplugin.cpp | 4 +- src/plugins/git/gitclient.cpp | 4 +- src/plugins/projectexplorer/copystep.cpp | 2 +- .../qnx/qnxdeployqtlibrariesdialog.cpp | 8 ++-- src/plugins/qnx/slog2inforunner.cpp | 2 +- .../remotelinux/genericdirectuploadstep.cpp | 8 ++-- src/plugins/remotelinux/killappstep.cpp | 2 +- .../remotelinux/tarpackagecreationstep.cpp | 2 +- tests/auto/solutions/tasking/tst_tasking.cpp | 6 ++- 12 files changed, 50 insertions(+), 40 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 946922dda3f..cd918e78f30 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -368,8 +368,8 @@ private: constexpr bool isVoid = std::is_same_v, Task &>>; static_assert(isDynamic || isVoid, - "Task setup handler needs to take (Task &) as an argument (optionally) and has to " - "return void or SetupResult. The passed handler doesn't fulfill these requirements."); + "Task setup handler needs to take (Task &) as an argument and has to return " + "void or SetupResult. The passed handler doesn't fulfill these requirements."); return [=](TaskInterface &taskInterface) { Adapter &adapter = static_cast(taskInterface); if constexpr (isDynamic) @@ -383,37 +383,45 @@ private: static GroupItem::TaskDoneHandler wrapDone(Handler &&handler) { if constexpr (std::is_same_v) return {}; // When user passed {} for the done handler. - static constexpr bool is2ArgDynamic + static constexpr bool isBTD // stands for [B]ool, [T]ask, [D]oneWith = std::is_invocable_r_v, const Task &, DoneWith>; - static constexpr bool is1ArgDynamic + static constexpr bool isBT = std::is_invocable_r_v, const Task &>; - static constexpr bool is0ArgDynamic + static constexpr bool isBD + = std::is_invocable_r_v, DoneWith>; + static constexpr bool isB = std::is_invocable_r_v>; - static constexpr bool is2ArgVoid + static constexpr bool isVTD // stands for [V]oid, [T]ask, [D]oneWith = std::is_invocable_r_v, const Task &, DoneWith>; - static constexpr bool is1ArgVoid + static constexpr bool isVT = std::is_invocable_r_v, const Task &>; - static constexpr bool is0ArgVoid + static constexpr bool isVD + = std::is_invocable_r_v, DoneWith>; + static constexpr bool isV = std::is_invocable_r_v>; - static constexpr bool isInvocable = is2ArgDynamic || is2ArgVoid - || is1ArgDynamic || is1ArgVoid - || is0ArgDynamic || is0ArgVoid; + static constexpr bool isInvocable = isBTD || isBT || isBD || isB + || isVTD || isVT || isVD || isV; static_assert(isInvocable, - "Task done handler needs to take (const Task &, bool) as arguments (optionally) and " - "has to return void or bool. The passed handler doesn't fulfill these requirements."); + "Task done handler needs to take (const Task &, DoneWith), (const Task &), " + "(DoneWith) or (void) as arguments and has to return void or bool. " + "The passed handler doesn't fulfill these requirements."); return [=](const TaskInterface &taskInterface, DoneWith result) { const Adapter &adapter = static_cast(taskInterface); - if constexpr (is2ArgDynamic) + if constexpr (isBTD) return std::invoke(handler, *adapter.task(), result); - if constexpr (is1ArgDynamic) + if constexpr (isBT) return std::invoke(handler, *adapter.task()); - if constexpr (is0ArgDynamic) + if constexpr (isBD) + return std::invoke(handler, result); + if constexpr (isB) return std::invoke(handler); - if constexpr (is2ArgVoid) + if constexpr (isVTD) std::invoke(handler, *adapter.task(), result); - else if constexpr (is1ArgVoid) + else if constexpr (isVT) std::invoke(handler, *adapter.task()); - else if constexpr (is0ArgVoid) + else if constexpr (isVD) + std::invoke(handler, result); + else if constexpr (isV) std::invoke(handler); return result == DoneWith::Success; }; diff --git a/src/plugins/android/androidsdkdownloader.cpp b/src/plugins/android/androidsdkdownloader.cpp index 492417d2353..947b6042adf 100644 --- a/src/plugins/android/androidsdkdownloader.cpp +++ b/src/plugins/android/androidsdkdownloader.cpp @@ -171,7 +171,7 @@ void AndroidSdkDownloader::downloadAndExtractSdk() unarchiver.setDestDir(sdkFileName.parentDir()); return SetupResult::Continue; }; - const auto onUnarchiverDone = [this, storage](const Unarchiver &, DoneWith result) { + const auto onUnarchiverDone = [this, storage](DoneWith result) { if (result != DoneWith::Success) { logError(Tr::tr("Unarchiving error.")); return; diff --git a/src/plugins/debugger/loadcoredialog.cpp b/src/plugins/debugger/loadcoredialog.cpp index 88722a4e259..143bada6ae5 100644 --- a/src/plugins/debugger/loadcoredialog.cpp +++ b/src/plugins/debugger/loadcoredialog.cpp @@ -253,12 +253,12 @@ void AttachCoreDialog::accepted() AsyncTask{[this, copyFileAsync](auto &task) { task.setConcurrentCallData(copyFileAsync, coreFile()); }, - [=](const auto &task) { d->coreFileResult = task.result(); }, + [=](const Async &task) { d->coreFileResult = task.result(); }, CallDoneIf::Success}, AsyncTask{[this, copyFileAsync](auto &task) { task.setConcurrentCallData(copyFileAsync, symbolFile()); }, - [=](const auto &task) { d->symbolFileResult = task.result(); }, + [=](const Async &task) { d->symbolFileResult = task.result(); }, CallDoneIf::Success} }; diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp index ceab92cb7f6..2210f15ca8b 100644 --- a/src/plugins/diffeditor/diffeditorplugin.cpp +++ b/src/plugins/diffeditor/diffeditorplugin.cpp @@ -110,7 +110,7 @@ DiffFilesController::DiffFilesController(IDocument *document) const TreeStorage>> storage; - const auto setupTree = [this, storage](TaskTree &taskTree) { + const auto onTreeSetup = [this, storage](TaskTree &taskTree) { QList> *outputList = storage.activeStorage(); const QList inputList = reloadInputList(); @@ -147,7 +147,7 @@ DiffFilesController::DiffFilesController(IDocument *document) const Group root = { Storage(storage), - TaskTreeTask(setupTree), + TaskTreeTask(onTreeSetup), onGroupDone(onTreeDone), onGroupError(onTreeError) }; diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 24b02b736b7..9b0d3dad168 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -483,7 +483,7 @@ ShowController::ShowController(IDocument *document, const QString &id) updateDescription(*data); }; - const auto setupFollows = [this, storage, updateDescription](TaskTree &taskTree) { + const auto onFollowsSetup = [this, storage, updateDescription](TaskTree &taskTree) { ReloadStorage *data = storage.activeStorage(); QStringList parents; QString errorMessage; @@ -536,7 +536,7 @@ ShowController::ShowController(IDocument *document, const QString &id) onGroupSetup(desciptionDetailsSetup), ProcessTask(onBranchesSetup, onBranchesDone, CallDoneIf::Success), ProcessTask(onPrecedesSetup, onPrecedesDone, CallDoneIf::Success), - TaskTreeTask(setupFollows) + TaskTreeTask(onFollowsSetup) } }, Group { diff --git a/src/plugins/projectexplorer/copystep.cpp b/src/plugins/projectexplorer/copystep.cpp index 412dc2dfc55..be6c9bb730f 100644 --- a/src/plugins/projectexplorer/copystep.cpp +++ b/src/plugins/projectexplorer/copystep.cpp @@ -52,7 +52,7 @@ private: streamer.setDestination(m_target); return SetupResult::Continue; }; - const auto onDone = [this](const FileStreamer &, DoneWith result) { + const auto onDone = [this](DoneWith result) { if (result == DoneWith::Success) addOutput(Tr::tr("Copying finished."), OutputFormat::NormalMessage); else diff --git a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp index 141e2cd5e60..e0fa0f15764 100644 --- a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp +++ b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp @@ -198,11 +198,11 @@ GroupItem QnxDeployQtLibrariesDialogPrivate::uploadTask() GroupItem QnxDeployQtLibrariesDialogPrivate::chmodTask(const DeployableFile &file) { - const auto onSetup = [=](Process &process) { + const auto onSetup = [this, file](Process &process) { process.setCommand({m_device->filePath("chmod"), {"a+x", Utils::ProcessArgs::quoteArgUnix(file.remoteFilePath())}}); }; - const auto onError = [=](const Process &process) { + const auto onError = [this, file](const Process &process) { const QString error = process.errorString(); if (!error.isEmpty()) { emitWarningMessage(Tr::tr("Remote chmod failed for file \"%1\": %2") @@ -217,7 +217,7 @@ GroupItem QnxDeployQtLibrariesDialogPrivate::chmodTask(const DeployableFile &fil GroupItem QnxDeployQtLibrariesDialogPrivate::chmodTree() { - const auto setupChmodHandler = [=](TaskTree &tree) { + const auto onSetup = [this](TaskTree &tree) { QList filesToChmod; for (const DeployableFile &file : std::as_const(m_deployableFiles)) { if (file.isExecutable()) @@ -230,7 +230,7 @@ GroupItem QnxDeployQtLibrariesDialogPrivate::chmodTree() } tree.setRecipe(chmodList); }; - return TaskTreeTask{setupChmodHandler}; + return TaskTreeTask(onSetup); } Group QnxDeployQtLibrariesDialogPrivate::deployRecipe() diff --git a/src/plugins/qnx/slog2inforunner.cpp b/src/plugins/qnx/slog2inforunner.cpp index c6c2bff84a8..aa7d8b9aa80 100644 --- a/src/plugins/qnx/slog2inforunner.cpp +++ b/src/plugins/qnx/slog2inforunner.cpp @@ -37,7 +37,7 @@ void Slog2InfoRunner::start() const auto onTestSetup = [this](Process &process) { process.setCommand({device()->filePath("slog2info"), {}}); }; - const auto onTestDone = [this](const Process &, DoneWith result) { + const auto onTestDone = [this](DoneWith result) { if (result == DoneWith::Success) { m_found = true; return; diff --git a/src/plugins/remotelinux/genericdirectuploadstep.cpp b/src/plugins/remotelinux/genericdirectuploadstep.cpp index 9f3de9bc21b..a1d11de47ab 100644 --- a/src/plugins/remotelinux/genericdirectuploadstep.cpp +++ b/src/plugins/remotelinux/genericdirectuploadstep.cpp @@ -151,7 +151,7 @@ GroupItem GenericDirectUploadStep::statTask(UploadStorage *storage, GroupItem GenericDirectUploadStep::statTree(const TreeStorage &storage, FilesToStat filesToStat, StatEndHandler statEndHandler) { - const auto setupHandler = [=](TaskTree &tree) { + const auto onSetup = [this, storage, filesToStat, statEndHandler](TaskTree &tree) { UploadStorage *storagePtr = storage.activeStorage(); const QList files = filesToStat(storagePtr); QList statList{finishAllAndDone, parallelLimit(MaxConcurrentStatCalls)}; @@ -161,7 +161,7 @@ GroupItem GenericDirectUploadStep::statTree(const TreeStorage &st } tree.setRecipe({statList}); }; - return TaskTreeTask(setupHandler); + return TaskTreeTask(onSetup); } GroupItem GenericDirectUploadStep::uploadTask(const TreeStorage &storage) @@ -225,7 +225,7 @@ GroupItem GenericDirectUploadStep::chmodTask(const DeployableFile &file) GroupItem GenericDirectUploadStep::chmodTree(const TreeStorage &storage) { - const auto setupChmodHandler = [=](TaskTree &tree) { + const auto onSetup = [this, storage](TaskTree &tree) { QList filesToChmod; for (const DeployableFile &file : std::as_const(storage->filesToUpload)) { if (file.isExecutable()) @@ -238,7 +238,7 @@ GroupItem GenericDirectUploadStep::chmodTree(const TreeStorage &s } tree.setRecipe({chmodList}); }; - return TaskTreeTask(setupChmodHandler); + return TaskTreeTask(onSetup); } GroupItem GenericDirectUploadStep::deployRecipe() diff --git a/src/plugins/remotelinux/killappstep.cpp b/src/plugins/remotelinux/killappstep.cpp index 020311e596f..0ccfe3ee743 100644 --- a/src/plugins/remotelinux/killappstep.cpp +++ b/src/plugins/remotelinux/killappstep.cpp @@ -55,7 +55,7 @@ GroupItem KillAppStep::deployRecipe() .arg(m_remoteExecutable.path())); return SetupResult::Continue; }; - const auto onDone = [this](const DeviceProcessKiller &, DoneWith result) { + const auto onDone = [this](DoneWith result) { const QString message = result == DoneWith::Success ? Tr::tr("Remote application killed.") : Tr::tr("Failed to kill remote application. Assuming it was not running."); addProgressMessage(message); diff --git a/src/plugins/remotelinux/tarpackagecreationstep.cpp b/src/plugins/remotelinux/tarpackagecreationstep.cpp index 6393197c5aa..52920b3ebc7 100644 --- a/src/plugins/remotelinux/tarpackagecreationstep.cpp +++ b/src/plugins/remotelinux/tarpackagecreationstep.cpp @@ -153,7 +153,7 @@ Tasking::GroupItem TarPackageCreationStep::runRecipe() async.setFutureSynchronizer(&m_synchronizer); return SetupResult::Continue; }; - const auto onDone = [this](const Async &, DoneWith result) { + const auto onDone = [this](DoneWith result) { if (result != DoneWith::Success) { emit addOutput(Tr::tr("Packaging failed."), OutputFormat::ErrorMessage); return; diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index cd015d12d67..cf315f84a98 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -80,14 +80,16 @@ void tst_Tasking::validConstructs() parallel, TestTask([](TaskObject &) {}, [](const TaskObject &, DoneWith) {}), TestTask([](TaskObject &) {}, [](const TaskObject &) {}), + TestTask([](TaskObject &) {}, [](DoneWith) {}), TestTask([](TaskObject &) {}, [] {}), TestTask([](TaskObject &) {}, {}), TestTask([](TaskObject &) {}), TestTask({}, [](const TaskObject &, DoneWith) {}), TestTask({}, [](const TaskObject &) {}), + TestTask({}, [](DoneWith) {}), TestTask({}, [] {}), TestTask({}, {}), - TestTask({}), + TestTask({}) }; const Group group1 { @@ -232,7 +234,7 @@ void tst_Tasking::testTree_data() }; const auto setupDone = [storage](int taskId, bool success = true) { - return [storage, taskId, success](const TaskObject &, DoneWith result) { + return [storage, taskId, success](DoneWith result) { const Handler handler = result == DoneWith::Cancel ? Handler::Canceled : success ? Handler::Success : Handler::Error; storage->m_log.append({taskId, handler}); From d2500dc77b905a885d351367cf9154316ac73acf Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 31 Oct 2023 10:22:15 +0100 Subject: [PATCH 0087/1546] FancyMainWindow: Remove auto-hide title bars functionality This added complexity with the hovering to get the title bars shown, and discoverability issues with the action in the views menu to show all title bars, and the issue that some docks then had double titles, because we wanted some title to be shown even if the title bar is hidden. Instead only show the dock control buttons only on hover, which already removes a lot visual clutter that was the main reason for the whole exercise. One issue is that the title is now uselessly repeated for tabbed docks. Another is that the title bar style is ugly and not very compatible to what we otherwise have. Change-Id: Ib093e0a3f2f07ece74b9055015c5523994032c5a Reviewed-by: Marcus Tillmanns --- src/libs/utils/fancymainwindow.cpp | 165 ++++-------------- src/libs/utils/fancymainwindow.h | 5 - .../compilerexplorereditor.cpp | 17 +- .../compilerexplorer/compilerexplorereditor.h | 3 +- src/plugins/debugger/debuggermainwindow.cpp | 11 -- src/plugins/debugger/debuggerplugin.cpp | 12 -- src/plugins/designer/formeditor.cpp | 6 - 7 files changed, 39 insertions(+), 180 deletions(-) diff --git a/src/libs/utils/fancymainwindow.cpp b/src/libs/utils/fancymainwindow.cpp index ad5e4ed9c3a..1446f602689 100644 --- a/src/libs/utils/fancymainwindow.cpp +++ b/src/libs/utils/fancymainwindow.cpp @@ -21,7 +21,6 @@ #include #include -static const char AutoHideTitleBarsKey[] = "AutoHideTitleBars"; static const char ShowCentralWidgetKey[] = "ShowCentralWidget"; static const char StateKey[] = "State"; @@ -41,9 +40,7 @@ struct FancyMainWindowPrivate bool m_handleDockVisibilityChanges; QAction m_showCentralWidget; QAction m_menuSeparator1; - QAction m_menuSeparator2; QAction m_resetLayoutAction; - QAction m_autoHideTitleBars; }; class DockWidget : public QDockWidget @@ -51,19 +48,11 @@ class DockWidget : public QDockWidget public: DockWidget(QWidget *inner, FancyMainWindow *parent, bool immutable = false); - bool eventFilter(QObject *, QEvent *event) override; - void enterEvent(QEnterEvent *event) override; - void leaveEvent(QEvent *event) override; - void handleMouseTimeout(); - void handleToplevelChanged(bool floating); - FancyMainWindow *q; private: QPoint m_startPos; TitleBarWidget *m_titleBar; - QTimer m_timer; - bool m_immutable = false; }; // Stolen from QDockWidgetTitleButton @@ -130,7 +119,8 @@ class TitleBarWidget : public QWidget { public: TitleBarWidget(DockWidget *parent, const QStyleOptionDockWidget &opt) - : QWidget(parent), q(parent), m_active(true) + : QWidget(parent) + , q(parent) { m_titleLabel = new QLabel(this); @@ -147,8 +137,6 @@ public: m_closeButton->setAccessibleDescription(QDockWidget::tr("Closes the dock widget")); #endif - setActive(false); - const int minWidth = 10; const int maxWidth = 10000; const int inactiveHeight = 0; @@ -170,16 +158,23 @@ public: setProperty("managed_titlebar", 1); - connect(parent, &QDockWidget::featuresChanged, this, [this, parent] { - m_closeButton->setVisible(parent->features().testFlag(QDockWidget::DockWidgetClosable)); - m_floatButton->setVisible(parent->features().testFlag(QDockWidget::DockWidgetFloatable)); - }); + m_closeButton->setVisible(false); + m_floatButton->setVisible(false); + connect(parent, &QDockWidget::featuresChanged, this, [this] { updateChildren(); }); } void enterEvent(QEnterEvent *event) override { - setActive(true); + m_hovered = true; QWidget::enterEvent(event); + updateChildren(); + } + + void leaveEvent(QEvent *event) override + { + m_hovered = false; + QWidget::leaveEvent(event); + updateChildren(); } void setActive(bool on) @@ -190,35 +185,29 @@ public: void updateChildren() { - bool clickable = isClickable(); - m_titleLabel->setVisible(clickable); - - m_floatButton->setVisible(clickable + m_titleLabel->setVisible(m_active); + m_floatButton->setVisible(m_active && m_hovered && q->features().testFlag(QDockWidget::DockWidgetFloatable)); - m_closeButton->setVisible(clickable + m_closeButton->setVisible(m_active && m_hovered && q->features().testFlag(QDockWidget::DockWidgetClosable)); } - bool isClickable() const - { - return m_active || !q->q->autoHideTitleBars(); - } - QSize sizeHint() const override { ensurePolished(); - return isClickable() ? m_maximumActiveSize : m_maximumInactiveSize; + return m_active ? m_maximumActiveSize : m_maximumInactiveSize; } QSize minimumSizeHint() const override { ensurePolished(); - return isClickable() ? m_minimumActiveSize : m_minimumInactiveSize; + return m_active ? m_minimumActiveSize : m_minimumInactiveSize; } private: DockWidget *q; - bool m_active; + bool m_active = true; + bool m_hovered = false; QSize m_minimumActiveSize; QSize m_maximumActiveSize; QSize m_minimumInactiveSize; @@ -231,7 +220,8 @@ public: }; DockWidget::DockWidget(QWidget *inner, FancyMainWindow *parent, bool immutable) - : QDockWidget(parent), q(parent), m_immutable(immutable) + : QDockWidget(parent) + , q(parent) { setWidget(inner); setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable); @@ -249,14 +239,11 @@ DockWidget::DockWidget(QWidget *inner, FancyMainWindow *parent, bool immutable) m_titleBar->m_titleLabel->setText(title); setTitleBarWidget(m_titleBar); - if (immutable) + if (immutable) { + m_titleBar->setActive(false); return; + } - m_timer.setSingleShot(true); - m_timer.setInterval(500); - - connect(&m_timer, &QTimer::timeout, this, &DockWidget::handleMouseTimeout); - connect(this, &QDockWidget::topLevelChanged, this, &DockWidget::handleToplevelChanged); connect(toggleViewAction(), &QAction::triggered, this, [this] { if (isVisible()) raise(); @@ -271,54 +258,6 @@ DockWidget::DockWidget(QWidget *inner, FancyMainWindow *parent, bool immutable) origCloseButton, &QAbstractButton::clicked); } -bool DockWidget::eventFilter(QObject *, QEvent *event) -{ - if (!m_immutable && event->type() == QEvent::MouseMove && q->autoHideTitleBars()) { - auto me = static_cast(event); - int y = me->pos().y(); - int x = me->pos().x(); - int h = qMin(8, m_titleBar->m_floatButton->height()); - if (!isFloating() && widget() && 0 <= x && x < widget()->width() && 0 <= y && y <= h) { - m_timer.start(); - m_startPos = mapToGlobal(me->pos()); - } - } - return false; -} - -void DockWidget::enterEvent(QEnterEvent *event) -{ - if (!m_immutable) - QApplication::instance()->installEventFilter(this); - QDockWidget::enterEvent(event); -} - -void DockWidget::leaveEvent(QEvent *event) -{ - if (!m_immutable) { - if (!isFloating()) { - m_timer.stop(); - m_titleBar->setActive(false); - } - QApplication::instance()->removeEventFilter(this); - } - QDockWidget::leaveEvent(event); -} - -void DockWidget::handleMouseTimeout() -{ - QPoint dist = m_startPos - QCursor::pos(); - if (!isFloating() && dist.manhattanLength() < 4) - m_titleBar->setActive(true); -} - -void DockWidget::handleToplevelChanged(bool floating) -{ - m_titleBar->setActive(floating); -} - - - /*! \class Utils::FancyMainWindow \inmodule QtCreator @@ -331,30 +270,17 @@ void DockWidget::handleToplevelChanged(bool floating) in a Window-menu. */ -FancyMainWindowPrivate::FancyMainWindowPrivate(FancyMainWindow *parent) : - q(parent), - m_handleDockVisibilityChanges(true), - m_showCentralWidget(Tr::tr("Central Widget"), nullptr), - m_menuSeparator1(nullptr), - m_menuSeparator2(nullptr), - m_resetLayoutAction(Tr::tr("Reset to Default Layout"), nullptr), - m_autoHideTitleBars(Tr::tr("Automatically Hide View Title Bars"), nullptr) +FancyMainWindowPrivate::FancyMainWindowPrivate(FancyMainWindow *parent) + : q(parent) + , m_handleDockVisibilityChanges(true) + , m_showCentralWidget(Tr::tr("Central Widget"), nullptr) + , m_menuSeparator1(nullptr) + , m_resetLayoutAction(Tr::tr("Reset to Default Layout"), nullptr) { m_showCentralWidget.setCheckable(true); m_showCentralWidget.setChecked(true); m_menuSeparator1.setSeparator(true); - m_menuSeparator2.setSeparator(true); - - m_autoHideTitleBars.setCheckable(true); - m_autoHideTitleBars.setChecked(true); - - QObject::connect(&m_autoHideTitleBars, &QAction::toggled, q, [this](bool) { - for (QDockWidget *dock : q->dockWidgets()) { - if (auto titleBar = dynamic_cast(dock->titleBarWidget())) - titleBar->updateChildren(); - } - }); QObject::connect(&m_showCentralWidget, &QAction::toggled, q, [this](bool visible) { if (q->centralWidget()) @@ -463,7 +389,6 @@ QHash FancyMainWindow::saveSettings() const { QHash settings; settings.insert(StateKey, saveState(settingsVersion)); - settings.insert(AutoHideTitleBarsKey, d->m_autoHideTitleBars.isChecked()); settings.insert(ShowCentralWidgetKey, d->m_showCentralWidget.isChecked()); for (QDockWidget *dockWidget : dockWidgets()) { settings.insert(keyFromString(dockWidget->objectName()), @@ -479,8 +404,6 @@ void FancyMainWindow::restoreSettings(const QHash &settings) if (!restoreState(ba, settingsVersion)) qWarning() << "Restoring the state of dock widgets failed."; } - bool on = settings.value(AutoHideTitleBarsKey, true).toBool(); - d->m_autoHideTitleBars.setChecked(on); d->m_showCentralWidget.setChecked(settings.value(ShowCentralWidgetKey, true).toBool()); for (QDockWidget *widget : dockWidgets()) { widget->setProperty(dockWidgetActiveState, @@ -509,16 +432,6 @@ const QList FancyMainWindow::dockWidgets() const return result; } -bool FancyMainWindow::autoHideTitleBars() const -{ - return d->m_autoHideTitleBars.isChecked(); -} - -void FancyMainWindow::setAutoHideTitleBars(bool on) -{ - d->m_autoHideTitleBars.setChecked(on); -} - bool FancyMainWindow::isCentralWidgetShown() const { return d->m_showCentralWidget.isChecked(); @@ -551,8 +464,6 @@ void FancyMainWindow::addDockActionsToMenu(QMenu *menu) menu->addAction(action); menu->addAction(&d->m_showCentralWidget); menu->addAction(&d->m_menuSeparator1); - menu->addAction(&d->m_autoHideTitleBars); - menu->addAction(&d->m_menuSeparator2); menu->addAction(&d->m_resetLayoutAction); } @@ -561,16 +472,6 @@ QAction *FancyMainWindow::menuSeparator1() const return &d->m_menuSeparator1; } -QAction *FancyMainWindow::autoHideTitleBarsAction() const -{ - return &d->m_autoHideTitleBars; -} - -QAction *FancyMainWindow::menuSeparator2() const -{ - return &d->m_menuSeparator2; -} - QAction *FancyMainWindow::resetLayoutAction() const { return &d->m_resetLayoutAction; @@ -586,9 +487,7 @@ void FancyMainWindow::setDockActionsVisible(bool v) for (const QDockWidget *dockWidget : dockWidgets()) dockWidget->toggleViewAction()->setVisible(v); d->m_showCentralWidget.setVisible(v); - d->m_autoHideTitleBars.setVisible(v); d->m_menuSeparator1.setVisible(v); - d->m_menuSeparator2.setVisible(v); d->m_resetLayoutAction.setVisible(v); } diff --git a/src/libs/utils/fancymainwindow.h b/src/libs/utils/fancymainwindow.h index 40066de95f6..644482132b0 100644 --- a/src/libs/utils/fancymainwindow.h +++ b/src/libs/utils/fancymainwindow.h @@ -36,15 +36,10 @@ public: // Additional context menu actions QAction *menuSeparator1() const; - QAction *autoHideTitleBarsAction() const; - QAction *menuSeparator2() const; QAction *resetLayoutAction() const; QAction *showCentralWidgetAction() const; void addDockActionsToMenu(QMenu *menu); - bool autoHideTitleBars() const; - void setAutoHideTitleBars(bool on); - bool isCentralWidgetShown() const; void showCentralWidget(bool on); diff --git a/src/plugins/compilerexplorer/compilerexplorereditor.cpp b/src/plugins/compilerexplorer/compilerexplorereditor.cpp index f71010744ef..14679d48b6a 100644 --- a/src/plugins/compilerexplorer/compilerexplorereditor.cpp +++ b/src/plugins/compilerexplorer/compilerexplorereditor.cpp @@ -502,7 +502,6 @@ EditorWidget::EditorWidget(const QSharedPointer &document, , m_actionHandler(actionHandler) { setContextMenuPolicy(Qt::NoContextMenu); - setAutoHideTitleBars(false); setDockNestingEnabled(true); setDocumentMode(true); setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::TabPosition::South); @@ -541,13 +540,12 @@ void EditorWidget::focusInEvent(QFocusEvent *event) void EditorWidget::addCompiler(const std::shared_ptr &sourceSettings, const std::shared_ptr &compilerSettings, - int idx, - QDockWidget *parentDockWidget) + int idx) { auto compiler = new CompilerWidget(sourceSettings, compilerSettings, m_undoStack); compiler->setWindowTitle("Compiler #" + QString::number(idx)); compiler->setObjectName("compiler_" + QString::number(idx)); - QDockWidget *dockWidget = addDockForWidget(compiler, parentDockWidget); + QDockWidget *dockWidget = addDockForWidget(compiler); dockWidget->setFeatures(QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable); addDockWidget(Qt::RightDockWidgetArea, dockWidget); m_compilerWidgets.append(dockWidget); @@ -607,18 +605,15 @@ void EditorWidget::addSourceEditor(const std::shared_ptr &source addDockWidget(Qt::LeftDockWidgetArea, dockWidget); sourceSettings->compilers.forEachItem( - [this, sourceSettings, dockWidget](const std::shared_ptr &compilerSettings, - int idx) { - addCompiler(sourceSettings, compilerSettings, idx + 1, dockWidget); + [this, sourceSettings](const std::shared_ptr &compilerSettings, int idx) { + addCompiler(sourceSettings, compilerSettings, idx + 1); }); sourceSettings->compilers.setItemAddedCallback( - [this, sourceSettings, dockWidget]( - const std::shared_ptr &compilerSettings) { + [this, sourceSettings](const std::shared_ptr &compilerSettings) { addCompiler(sourceSettings->shared_from_this(), compilerSettings, - sourceSettings->compilers.size(), - dockWidget); + sourceSettings->compilers.size()); }); sourceSettings->compilers.setItemRemovedCallback( diff --git a/src/plugins/compilerexplorer/compilerexplorereditor.h b/src/plugins/compilerexplorer/compilerexplorereditor.h index 510e5e9eb3c..978bda4164f 100644 --- a/src/plugins/compilerexplorer/compilerexplorereditor.h +++ b/src/plugins/compilerexplorer/compilerexplorereditor.h @@ -215,8 +215,7 @@ protected: void addCompiler(const std::shared_ptr &sourceSettings, const std::shared_ptr &compilerSettings, - int idx, - QDockWidget *parentDockWidget); + int idx); void addSourceEditor(const std::shared_ptr &sourceSettings); void removeSourceEditor(const std::shared_ptr &sourceSettings); diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp index 81e3a4435aa..89dcc3dda03 100644 --- a/src/plugins/debugger/debuggermainwindow.cpp +++ b/src/plugins/debugger/debuggermainwindow.cpp @@ -49,7 +49,6 @@ namespace Utils { const char LAST_PERSPECTIVE_KEY[] = "LastPerspective"; const char MAINWINDOW_KEY[] = "Debugger.MainWindow"; -const char AUTOHIDE_TITLEBARS_KEY[] = "AutoHideTitleBars"; const char SHOW_CENTRALWIDGET_KEY[] = "ShowCentralWidget"; const char STATE_KEY[] = "State"; // Up to 4.10 const char STATE_KEY2[] = "State2"; // From 4.11 on @@ -286,14 +285,6 @@ DebuggerMainWindow::DebuggerMainWindow() "Debugger.Views.Separator1", debugcontext); cmd->setAttribute(Command::CA_Hide); viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE); - cmd = ActionManager::registerAction(autoHideTitleBarsAction(), - "Debugger.Views.AutoHideTitleBars", debugcontext); - cmd->setAttribute(Command::CA_Hide); - viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE); - cmd = ActionManager::registerAction(menuSeparator2(), - "Debugger.Views.Separator2", debugcontext); - cmd->setAttribute(Command::CA_Hide); - viewsMenu->addAction(cmd, Core::Constants::G_DEFAULT_THREE); cmd = ActionManager::registerAction(resetLayoutAction(), "Debugger.Views.ResetSimple", debugcontext); cmd->setAttribute(Command::CA_Hide); @@ -458,7 +449,6 @@ void DebuggerMainWindow::restorePersistentSettings() d->m_lastTypePerspectiveStates.insert(type, state); } - setAutoHideTitleBars(settings->value(AUTOHIDE_TITLEBARS_KEY, true).toBool()); showCentralWidget(settings->value(SHOW_CENTRALWIDGET_KEY, true).toBool()); d->m_persistentChangedDocks = Utils::toSet(settings->value(CHANGED_DOCK_KEY).toStringList()); settings->endGroup(); @@ -493,7 +483,6 @@ void DebuggerMainWindow::savePersistentSettings() const settings->beginGroup(MAINWINDOW_KEY); settings->setValue(CHANGED_DOCK_KEY, QStringList(Utils::toList(d->m_persistentChangedDocks))); settings->setValue(STATE_KEY2, states); - settings->setValue(AUTOHIDE_TITLEBARS_KEY, autoHideTitleBars()); settings->setValue(SHOW_CENTRALWIDGET_KEY, isCentralWidgetShown()); settings->endGroup(); diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index bb90a260cc9..ecb655f6c0e 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -712,16 +712,6 @@ public: // return isDebuggableScript; }; -static void addLabel(QWidget *widget, const QString &text) -{ - auto vbox = qobject_cast(widget->layout()); - QTC_ASSERT(vbox, return); - auto label = new QLabel(widget); - label->setText(text); - label->setContentsMargins(6, 6, 6, 6); - vbox->insertWidget(0, label); -}; - void DebuggerPluginPrivate::addFontSizeAdaptation(QWidget *widget) { QObject::connect(TextEditorSettings::instance(), @@ -759,7 +749,6 @@ QWidget *DebuggerPluginPrivate::createBreakpointManagerWindow(BaseTreeView *brea auto breakpointManagerWindow = addSearch(breakpointManagerView); breakpointManagerWindow->setWindowTitle(title); breakpointManagerWindow->setObjectName(objectName); - addLabel(breakpointManagerWindow, breakpointManagerWindow->windowTitle()); addFontSizeAdaptation(breakpointManagerWindow); return breakpointManagerWindow; } @@ -785,7 +774,6 @@ QWidget *DebuggerPluginPrivate::createEngineManagerWindow(BaseTreeView *engineMa auto engineManagerWindow = addSearch(engineManagerView); engineManagerWindow->setWindowTitle(title); engineManagerWindow->setObjectName(objectName); - addLabel(engineManagerWindow, engineManagerWindow->windowTitle()); addFontSizeAdaptation(engineManagerWindow); return engineManagerWindow; } diff --git a/src/plugins/designer/formeditor.cpp b/src/plugins/designer/formeditor.cpp index 776e74f0f90..798eac018a8 100644 --- a/src/plugins/designer/formeditor.cpp +++ b/src/plugins/designer/formeditor.cpp @@ -338,12 +338,6 @@ void FormEditorData::setupViewActions() Command *cmd = addToolAction(m_editorWidget->menuSeparator1(), m_contexts, "FormEditor.SeparatorLock", viewMenu); cmd->setAttribute(Command::CA_Hide); - cmd = addToolAction(m_editorWidget->autoHideTitleBarsAction(), m_contexts, "FormEditor.Locked", viewMenu); - cmd->setAttribute(Command::CA_Hide); - - cmd = addToolAction(m_editorWidget->menuSeparator2(), m_contexts, "FormEditor.SeparatorReset", viewMenu); - cmd->setAttribute(Command::CA_Hide); - cmd = addToolAction(m_editorWidget->resetLayoutAction(), m_contexts, "FormEditor.ResetToDefaultLayout", viewMenu); QObject::connect(m_editorWidget, &EditorWidget::resetLayout, From fbe359308dc3946bb68b6dedca237f353fa279f0 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 3 Nov 2023 15:53:01 +0100 Subject: [PATCH 0088/1546] TaskTree: Unify done / errorOccurred signals Get rid of TaskTree::errorOccurred signal. Provide additional DoneResult arg for done signal. Task-number: QTCREATORBUG-29834 Change-Id: I31a3a0701a14246b01f65303a1295f014c855ecf Reviewed-by: hjk Reviewed-by: --- src/libs/solutions/tasking/tasktree.cpp | 39 +++++------------- src/libs/solutions/tasking/tasktree.h | 2 +- src/libs/utils/filestreamer.cpp | 18 ++++---- src/plugins/android/androidsdkdownloader.cpp | 6 +-- src/plugins/autotest/testcodeparser.cpp | 8 ++-- src/plugins/autotest/testrunner.cpp | 1 - .../clangtools/documentclangtoolrunner.cpp | 1 - .../coreplugin/locator/ilocatorfilter.cpp | 13 ++---- src/plugins/coreplugin/locator/locator.cpp | 8 ++-- .../coreplugin/plugininstallwizard.cpp | 6 +-- .../progressmanager/taskprogress.cpp | 9 ++-- .../ctfvisualizer/ctfvisualizertool.cpp | 41 +++++++++---------- src/plugins/debugger/loadcoredialog.cpp | 2 +- .../diffeditor/diffeditorcontroller.cpp | 14 +++---- src/plugins/diffeditor/diffeditorcontroller.h | 1 - src/plugins/projectexplorer/buildmanager.cpp | 7 ++-- src/plugins/projectexplorer/extracompiler.cpp | 8 ++-- src/plugins/projectexplorer/runcontrol.cpp | 6 +-- .../qnx/qnxdeployqtlibrariesdialog.cpp | 6 +-- src/plugins/updateinfo/updateinfoplugin.cpp | 13 +++--- src/plugins/valgrind/valgrindprocess.cpp | 8 ++-- 21 files changed, 79 insertions(+), 138 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 1ff4c6116ef..2faadd22eca 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -985,8 +985,7 @@ public: void advanceProgress(int byValue); void emitStartedAndProgress(); void emitProgress(); - void emitDone(); - void emitError(); + void emitDone(DoneWith result); QList addStorages(const QList &storages); void callSetupHandler(TreeStorageBase storage, int storageId) { callStorageHandler(storage, storageId, &StorageHandler::m_setupHandler); @@ -1119,13 +1118,8 @@ void TaskTreePrivate::stop() QTC_ASSERT(m_root, return); if (!m_root->isRunning()) return; - // TODO: should we have canceled flag (passed to handler)? - // Just one done handler with result flag: - // FinishedWithSuccess, FinishedWithError, Canceled, TimedOut. - // Canceled either directly by user, or by workflow policy - doesn't matter, in both - // cases canceled from outside. m_root->stop(); - emitError(); + emitDone(DoneWith::Cancel); } void TaskTreePrivate::advanceProgress(int byValue) @@ -1151,18 +1145,11 @@ void TaskTreePrivate::emitProgress() emit q->progressValueChanged(m_progressValue); } -void TaskTreePrivate::emitDone() +void TaskTreePrivate::emitDone(DoneWith result) { QTC_CHECK(m_progressValue == m_root->taskCount()); GuardLocker locker(m_guard); - emit q->done(); -} - -void TaskTreePrivate::emitError() -{ - QTC_CHECK(m_progressValue == m_root->taskCount()); - GuardLocker locker(m_guard); - emit q->errorOccurred(); + emit q->done(result); } QList TaskTreePrivate::addStorages(const QList &storages) @@ -1348,10 +1335,8 @@ SetupResult TaskContainer::continueStart(SetupResult startAction, int nextChild) QTC_CHECK(parentContainer->isRunning()); if (!parentContainer->isStarting()) parentContainer->childDone(success); - } else if (success) { - m_constData.m_taskTreePrivate->emitDone(); } else { - m_constData.m_taskTreePrivate->emitError(); + m_constData.m_taskTreePrivate->emitDone(success ? DoneWith::Success : DoneWith::Error); } } return groupAction; @@ -2338,20 +2323,16 @@ bool TaskTree::runBlocking(const QFuture &future) bool ok = false; QEventLoop loop; - - const auto finalize = [&loop, &ok](bool success) { - ok = success; + connect(this, &TaskTree::done, &loop, [&loop, &ok](DoneWith result) { + ok = result == DoneWith::Success; // Otherwise, the tasks from inside the running tree that were deleteLater() // will be leaked. Refer to the QObject::deleteLater() docs. QMetaObject::invokeMethod(&loop, [&loop] { loop.quit(); }, Qt::QueuedConnection); - }; - + }); QFutureWatcher watcher; connect(&watcher, &QFutureWatcherBase::canceled, this, &TaskTree::stop); watcher.setFuture(future); - connect(this, &TaskTree::done, &loop, [finalize] { finalize(true); }); - connect(this, &TaskTree::errorOccurred, &loop, [finalize] { finalize(false); }); QTimer::singleShot(0, this, &TaskTree::start); loop.exec(QEventLoop::ExcludeUserInputEvents); @@ -2558,8 +2539,8 @@ void TaskTree::setupStorageHandler(const TreeStorageBase &storage, TaskTreeTaskAdapter::TaskTreeTaskAdapter() { - connect(task(), &TaskTree::done, this, [this] { emit done(true); }); - connect(task(), &TaskTree::errorOccurred, this, [this] { emit done(false); }); + connect(task(), &TaskTree::done, this, + [this](DoneWith result) { emit done(result == DoneWith::Success); }); } void TaskTreeTaskAdapter::start() diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index cd918e78f30..2483dfea821 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -482,7 +482,7 @@ public: signals: void started(); - void done(); + void done(DoneWith result); void errorOccurred(); void progressValueChanged(int value); // updated whenever task finished / skipped / stopped diff --git a/src/libs/utils/filestreamer.cpp b/src/libs/utils/filestreamer.cpp index b11bb6d3215..5d21d56cc61 100644 --- a/src/libs/utils/filestreamer.cpp +++ b/src/libs/utils/filestreamer.cpp @@ -32,12 +32,10 @@ public: const GroupItem task = m_filePath.needsDevice() ? remoteTask() : localTask(); m_taskTree.reset(new TaskTree({task})); - const auto finalize = [this](bool success) { + connect(m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) { m_taskTree.release()->deleteLater(); - emit done(success); - }; - connect(m_taskTree.get(), &TaskTree::done, this, [=] { finalize(true); }); - connect(m_taskTree.get(), &TaskTree::errorOccurred, this, [=] { finalize(false); }); + emit done(result == DoneWith::Success); + }); m_taskTree->start(); } @@ -466,14 +464,12 @@ void FileStreamer::start() // TODO: Preliminary check if local source exists? QTC_ASSERT(!d->m_taskTree, return); d->m_taskTree.reset(new TaskTree({d->task()})); - const auto finalize = [this](bool success) { - d->m_streamResult = success ? StreamResult::FinishedWithSuccess - : StreamResult::FinishedWithError; + connect(d->m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) { + d->m_streamResult = result == DoneWith::Success ? StreamResult::FinishedWithSuccess + : StreamResult::FinishedWithError; d->m_taskTree.release()->deleteLater(); emit done(); - }; - connect(d->m_taskTree.get(), &TaskTree::done, this, [=] { finalize(true); }); - connect(d->m_taskTree.get(), &TaskTree::errorOccurred, this, [=] { finalize(false); }); + }); d->m_taskTree->start(); } diff --git a/src/plugins/android/androidsdkdownloader.cpp b/src/plugins/android/androidsdkdownloader.cpp index 947b6042adf..1dd56e3f0b9 100644 --- a/src/plugins/android/androidsdkdownloader.cpp +++ b/src/plugins/android/androidsdkdownloader.cpp @@ -188,12 +188,10 @@ void AndroidSdkDownloader::downloadAndExtractSdk() }; m_taskTree.reset(new TaskTree(root)); - const auto onDone = [this] { + connect(m_taskTree.get(), &TaskTree::done, this, [this] { m_taskTree.release()->deleteLater(); m_progressDialog.reset(); - }; - connect(m_taskTree.get(), &TaskTree::done, this, onDone); - connect(m_taskTree.get(), &TaskTree::errorOccurred, this, onDone); + }); m_taskTree->start(); } diff --git a/src/plugins/autotest/testcodeparser.cpp b/src/plugins/autotest/testcodeparser.cpp index c549c105547..56cee3bc51e 100644 --- a/src/plugins/autotest/testcodeparser.cpp +++ b/src/plugins/autotest/testcodeparser.cpp @@ -390,11 +390,11 @@ void TestCodeParser::scanForTests(const QSet &filePaths, tasks.append(AsyncTask(onSetup, onDone, CallDoneIf::Success)); } m_taskTree.reset(new TaskTree{tasks}); - const auto onDone = [this] { m_taskTree.release()->deleteLater(); onFinished(true); }; - const auto onError = [this] { m_taskTree.release()->deleteLater(); onFinished(false); }; connect(m_taskTree.get(), &TaskTree::started, this, &TestCodeParser::parsingStarted); - connect(m_taskTree.get(), &TaskTree::done, this, onDone); - connect(m_taskTree.get(), &TaskTree::errorOccurred, this, onError); + connect(m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) { + m_taskTree.release()->deleteLater(); + onFinished(result == DoneWith::Success); + }); if (filteredFiles.size() > 5) { auto progress = new TaskProgress(m_taskTree.get()); progress->setDisplayName(Tr::tr("Scanning for Tests")); diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index 270a77dba4a..8d3f4bdf1de 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -455,7 +455,6 @@ void TestRunner::runTestsHelper() m_taskTree.reset(new TaskTree(tasks)); connect(m_taskTree.get(), &TaskTree::done, this, &TestRunner::onFinished); - connect(m_taskTree.get(), &TaskTree::errorOccurred, this, &TestRunner::onFinished); auto progress = new TaskProgress(m_taskTree.get()); progress->setDisplayName(Tr::tr("Running Tests")); diff --git a/src/plugins/clangtools/documentclangtoolrunner.cpp b/src/plugins/clangtools/documentclangtoolrunner.cpp index 5906cbc4e32..16c75c1eb07 100644 --- a/src/plugins/clangtools/documentclangtoolrunner.cpp +++ b/src/plugins/clangtools/documentclangtoolrunner.cpp @@ -225,7 +225,6 @@ void DocumentClangToolRunner::run() cleanup.dismiss(); m_taskTree.reset(new TaskTree(tasks)); connect(m_taskTree.get(), &TaskTree::done, this, &DocumentClangToolRunner::finalize); - connect(m_taskTree.get(), &TaskTree::errorOccurred, this, &DocumentClangToolRunner::finalize); m_taskTree->start(); } diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.cpp b/src/plugins/coreplugin/locator/ilocatorfilter.cpp index 924bd6d8495..30240a40ea2 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/ilocatorfilter.cpp @@ -486,15 +486,10 @@ void LocatorMatcher::start() }; d->m_taskTree->setRecipe(root); - - const auto onFinish = [this](bool success) { - return [this, success] { - emit done(success); - d->m_taskTree.release()->deleteLater(); - }; - }; - connect(d->m_taskTree.get(), &TaskTree::done, this, onFinish(true)); - connect(d->m_taskTree.get(), &TaskTree::errorOccurred, this, onFinish(false)); + connect(d->m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) { + emit done(result == DoneWith::Success); + d->m_taskTree.release()->deleteLater(); + }); d->m_taskTree->start(); } diff --git a/src/plugins/coreplugin/locator/locator.cpp b/src/plugins/coreplugin/locator/locator.cpp index f4ee927e13b..3dea793bb3d 100644 --- a/src/plugins/coreplugin/locator/locator.cpp +++ b/src/plugins/coreplugin/locator/locator.cpp @@ -396,11 +396,9 @@ void Locator::refresh(const QList &filters) } m_taskTree.reset(new TaskTree{tasks}); - connect(m_taskTree.get(), &TaskTree::done, this, [this] { - saveSettings(); - m_taskTree.release()->deleteLater(); - }); - connect(m_taskTree.get(), &TaskTree::errorOccurred, this, [this] { + connect(m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) { + if (result == DoneWith::Success) + saveSettings(); m_taskTree.release()->deleteLater(); }); auto progress = new TaskProgress(m_taskTree.get()); diff --git a/src/plugins/coreplugin/plugininstallwizard.cpp b/src/plugins/coreplugin/plugininstallwizard.cpp index 9dc67ddfb29..1b918836ece 100644 --- a/src/plugins/coreplugin/plugininstallwizard.cpp +++ b/src/plugins/coreplugin/plugininstallwizard.cpp @@ -262,12 +262,10 @@ public: }; m_taskTree.reset(new TaskTree(root)); - const auto onEnd = [this] { + connect(m_taskTree.get(), &TaskTree::done, this, [this] { m_cancelButton->setVisible(false); m_taskTree.release()->deleteLater(); - }; - connect(m_taskTree.get(), &TaskTree::done, this, onEnd); - connect(m_taskTree.get(), &TaskTree::errorOccurred, this, onEnd); + }); m_cancelButton->setVisible(true); m_taskTree->start(); diff --git a/src/plugins/coreplugin/progressmanager/taskprogress.cpp b/src/plugins/coreplugin/progressmanager/taskprogress.cpp index d60fa71e125..7f9de529033 100644 --- a/src/plugins/coreplugin/progressmanager/taskprogress.cpp +++ b/src/plugins/coreplugin/progressmanager/taskprogress.cpp @@ -128,13 +128,10 @@ TaskProgress::TaskProgress(TaskTree *taskTree) connect(d->m_taskTree, &TaskTree::progressValueChanged, this, [this](int value) { d->advanceProgress(value); }); - connect(d->m_taskTree, &TaskTree::done, this, [this] { + connect(d->m_taskTree, &TaskTree::done, this, [this](DoneWith result) { d->m_timer.stop(); - d->m_futureInterface.reportFinished(); - }); - connect(d->m_taskTree, &TaskTree::errorOccurred, this, [this] { - d->m_timer.stop(); - d->m_futureInterface.reportCanceled(); + if (result != DoneWith::Success) + d->m_futureInterface.reportCanceled(); d->m_futureInterface.reportFinished(); }); } diff --git a/src/plugins/ctfvisualizer/ctfvisualizertool.cpp b/src/plugins/ctfvisualizer/ctfvisualizertool.cpp index 7214e9130da..79589d44225 100644 --- a/src/plugins/ctfvisualizer/ctfvisualizertool.cpp +++ b/src/plugins/ctfvisualizer/ctfvisualizertool.cpp @@ -219,36 +219,33 @@ void CtfVisualizerTool::loadJson(const QString &fileName) m_traceManager->addEvent(asyncPtr->resultAt(index)); }); }; - const auto onDone = [this] { - m_traceManager->updateStatistics(); - if (m_traceManager->isEmpty()) { - QMessageBox::warning(Core::ICore::dialogParent(), - Tr::tr("CTF Visualizer"), - Tr::tr("The file does not contain any trace data.")); - } else if (!m_traceManager->errorString().isEmpty()) { - QMessageBox::warning(Core::ICore::dialogParent(), - Tr::tr("CTF Visualizer"), - m_traceManager->errorString()); + const auto onDone = [this](DoneWith result) { + if (result == DoneWith::Success) { + m_traceManager->updateStatistics(); + if (m_traceManager->isEmpty()) { + QMessageBox::warning(Core::ICore::dialogParent(), Tr::tr("CTF Visualizer"), + Tr::tr("The file does not contain any trace data.")); + } else if (!m_traceManager->errorString().isEmpty()) { + QMessageBox::warning(Core::ICore::dialogParent(), Tr::tr("CTF Visualizer"), + m_traceManager->errorString()); + } else { + m_traceManager->finalize(); + m_perspective.select(); + const auto end = m_traceManager->traceEnd() + m_traceManager->traceDuration() / 20; + zoomControl()->setTrace(m_traceManager->traceBegin(), end); + zoomControl()->setRange(m_traceManager->traceBegin(), end); + } + setAvailableThreads(m_traceManager->getSortedThreads()); } else { - m_traceManager->finalize(); - m_perspective.select(); - zoomControl()->setTrace(m_traceManager->traceBegin(), m_traceManager->traceEnd() + m_traceManager->traceDuration() / 20); - zoomControl()->setRange(m_traceManager->traceBegin(), m_traceManager->traceEnd() + m_traceManager->traceDuration() / 20); + QMessageBox::warning(Core::ICore::dialogParent(), Tr::tr("CTF Visualizer"), + Tr::tr("Cannot read the CTF file.")); } - setAvailableThreads(m_traceManager->getSortedThreads()); - m_loader.release()->deleteLater(); - }; - const auto onError = [this] { - QMessageBox::warning(Core::ICore::dialogParent(), - Tr::tr("CTF Visualizer"), - Tr::tr("Cannot read the CTF file.")); m_loader.release()->deleteLater(); }; const Group recipe { AsyncTask(onSetup) }; m_loader.reset(new TaskTree(recipe)); connect(m_loader.get(), &TaskTree::done, this, onDone); - connect(m_loader.get(), &TaskTree::errorOccurred, this, onError); auto progress = new TaskProgress(m_loader.get()); progress->setDisplayName(Tr::tr("Loading CTF File")); m_loader->start(); diff --git a/src/plugins/debugger/loadcoredialog.cpp b/src/plugins/debugger/loadcoredialog.cpp index 143bada6ae5..80573b9891c 100644 --- a/src/plugins/debugger/loadcoredialog.cpp +++ b/src/plugins/debugger/loadcoredialog.cpp @@ -173,7 +173,7 @@ int AttachCoreDialog::exec() connect(d->buttonBox, &QDialogButtonBox::accepted, this, &AttachCoreDialog::accepted); changed(); - connect(&d->taskTree, &TaskTree::done, this, [&]() { + connect(&d->taskTree, &TaskTree::done, this, [this] { setEnabled(true); d->progressIndicator->setVisible(false); d->progressLabel->setVisible(false); diff --git a/src/plugins/diffeditor/diffeditorcontroller.cpp b/src/plugins/diffeditor/diffeditorcontroller.cpp index 4756afc7828..8248ef5b1fc 100644 --- a/src/plugins/diffeditor/diffeditorcontroller.cpp +++ b/src/plugins/diffeditor/diffeditorcontroller.cpp @@ -110,20 +110,16 @@ void DiffEditorController::requestReload() { m_document->beginReload(); m_taskTree.reset(new TaskTree(m_reloadRecipe)); - connect(m_taskTree.get(), &TaskTree::done, this, [this] { reloadFinished(true); }); - connect(m_taskTree.get(), &TaskTree::errorOccurred, this, [this] { reloadFinished(false); }); + connect(m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) { + if (m_taskTree) + m_taskTree.release()->deleteLater(); + m_document->endReload(result == DoneWith::Success); + }); auto progress = new TaskProgress(m_taskTree.get()); progress->setDisplayName(m_displayName); m_taskTree->start(); } -void DiffEditorController::reloadFinished(bool success) -{ - if (m_taskTree) - m_taskTree.release()->deleteLater(); - m_document->endReload(success); -} - void DiffEditorController::addExtraActions(QMenu *menu, int fileIndex, int chunkIndex, const ChunkSelection &selection) { diff --git a/src/plugins/diffeditor/diffeditorcontroller.h b/src/plugins/diffeditor/diffeditorcontroller.h index 1fddc31c4dd..890a9e70410 100644 --- a/src/plugins/diffeditor/diffeditorcontroller.h +++ b/src/plugins/diffeditor/diffeditorcontroller.h @@ -66,7 +66,6 @@ protected: void forceContextLineCount(int lines); private: - void reloadFinished(bool success); friend class Internal::DiffEditorWidgetController; virtual void addExtraActions(QMenu *menu, int fileIndex, int chunkIndex, const ChunkSelection &selection); diff --git a/src/plugins/projectexplorer/buildmanager.cpp b/src/plugins/projectexplorer/buildmanager.cpp index 6c74b5cf828..b3b04a364ff 100644 --- a/src/plugins/projectexplorer/buildmanager.cpp +++ b/src/plugins/projectexplorer/buildmanager.cpp @@ -682,7 +682,8 @@ void BuildManager::startBuildQueue() topLevel.append(Group(targetTasks)); d->m_taskTree.reset(new TaskTree(Group{topLevel})); - const auto endHandler = [](bool success) { + const auto onDone = [](DoneWith result) { + const bool success = result == DoneWith::Success; d->m_taskTree.release()->deleteLater(); if (!success && d->m_progressFutureInterface) @@ -703,9 +704,7 @@ void BuildManager::startBuildQueue() startBuildQueue(); } }; - connect(d->m_taskTree.get(), &TaskTree::done, instance(), [endHandler] { endHandler(true); }); - connect(d->m_taskTree.get(), &TaskTree::errorOccurred, instance(), - [endHandler] { endHandler(false); }); + connect(d->m_taskTree.get(), &TaskTree::done, instance(), onDone); // Progress Reporting d->m_progressFutureInterface = new QFutureInterface; diff --git a/src/plugins/projectexplorer/extracompiler.cpp b/src/plugins/projectexplorer/extracompiler.cpp index 2535181b230..2765227e7c5 100644 --- a/src/plugins/projectexplorer/extracompiler.cpp +++ b/src/plugins/projectexplorer/extracompiler.cpp @@ -154,12 +154,10 @@ void ExtraCompiler::compileContent(const QByteArray &content) void ExtraCompiler::compileImpl(const ContentProvider &provider) { - const auto finalize = [=] { - d->m_taskTree.release()->deleteLater(); - }; d->m_taskTree.reset(new TaskTree({taskItemImpl(provider)})); - connect(d->m_taskTree.get(), &TaskTree::done, this, finalize); - connect(d->m_taskTree.get(), &TaskTree::errorOccurred, this, finalize); + connect(d->m_taskTree.get(), &TaskTree::done, this, [this] { + d->m_taskTree.release()->deleteLater(); + }); d->m_taskTree->start(); } diff --git a/src/plugins/projectexplorer/runcontrol.cpp b/src/plugins/projectexplorer/runcontrol.cpp index 8eb6f5e6ba0..3a69ad1b199 100644 --- a/src/plugins/projectexplorer/runcontrol.cpp +++ b/src/plugins/projectexplorer/runcontrol.cpp @@ -1053,12 +1053,10 @@ void RunControlPrivate::startTaskTree() m_taskTree.reset(new TaskTree(*m_runRecipe)); connect(m_taskTree.get(), &TaskTree::started, q, &RunControl::started); - const auto finalize = [this] { + connect(m_taskTree.get(), &TaskTree::done, this, [this] { m_taskTree.release()->deleteLater(); checkAutoDeleteAndEmitStopped(); - }; - connect(m_taskTree.get(), &TaskTree::done, this, finalize); - connect(m_taskTree.get(), &TaskTree::errorOccurred, this, finalize); + }); m_taskTree->start(); } diff --git a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp index e0fa0f15764..10976ad1d50 100644 --- a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp +++ b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp @@ -300,12 +300,10 @@ void QnxDeployQtLibrariesDialogPrivate::start() m_deployProgress->setRange(0, m_deployableFiles.count()); m_taskTree.reset(new TaskTree(deployRecipe())); - const auto endHandler = [this] { + connect(m_taskTree.get(), &TaskTree::done, this, [this] { m_taskTree.release()->deleteLater(); handleUploadFinished(); - }; - connect(m_taskTree.get(), &TaskTree::done, this, endHandler); - connect(m_taskTree.get(), &TaskTree::errorOccurred, this, endHandler); + }); m_taskTree->start(); } diff --git a/src/plugins/updateinfo/updateinfoplugin.cpp b/src/plugins/updateinfo/updateinfoplugin.cpp index 1a4cea93396..d5838becfbf 100644 --- a/src/plugins/updateinfo/updateinfoplugin.cpp +++ b/src/plugins/updateinfo/updateinfoplugin.cpp @@ -122,10 +122,6 @@ void UpdateInfoPlugin::startCheckForUpdates() process.setCommand({d->m_maintenanceTool, args}); process.setLowPriority(); }; - const auto doCleanup = [this] { - d->m_taskTree.release()->deleteLater(); - checkForUpdatesStopped(); - }; const auto onUpdateSetup = [doSetup](Process &process) { doSetup(process, {"ch", "-g", "*=false,ifw.package.*=true"}); @@ -146,11 +142,12 @@ void UpdateInfoPlugin::startCheckForUpdates() } d->m_taskTree.reset(new TaskTree(Group{tasks})); - connect(d->m_taskTree.get(), &TaskTree::done, this, [this, doCleanup] { - checkForUpdatesFinished(); - doCleanup(); + connect(d->m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) { + if (result == DoneWith::Success) + checkForUpdatesFinished(); + d->m_taskTree.release()->deleteLater(); + checkForUpdatesStopped(); }); - connect(d->m_taskTree.get(), &TaskTree::errorOccurred, this, doCleanup); d->m_progress = new TaskProgress(d->m_taskTree.get()); d->m_progress->setHalfLifeTimePerTask(30000); // 30 seconds d->m_progress->setDisplayName(Tr::tr("Checking for Updates")); diff --git a/src/plugins/valgrind/valgrindprocess.cpp b/src/plugins/valgrind/valgrindprocess.cpp index c62fb46891b..d8581f94d92 100644 --- a/src/plugins/valgrind/valgrindprocess.cpp +++ b/src/plugins/valgrind/valgrindprocess.cpp @@ -213,12 +213,10 @@ bool ValgrindProcessPrivate::run() { m_taskTree.reset(new TaskTree); m_taskTree->setRecipe(runRecipe()); - const auto finalize = [this](bool success) { + connect(m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) { m_taskTree.release()->deleteLater(); - emit q->done(success); - }; - connect(m_taskTree.get(), &TaskTree::done, this, [finalize] { finalize(true); }); - connect(m_taskTree.get(), &TaskTree::errorOccurred, this, [finalize] { finalize(false); }); + emit q->done(result == DoneWith::Success); + }); m_taskTree->start(); return bool(m_taskTree); } From 37b6cb7f905e37363d67ad5f7d267e0265a83514 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 3 Nov 2023 18:50:32 +0100 Subject: [PATCH 0089/1546] TaskTree: Get rid of onGroupError element Make it possible to setup onGroupDone element with additional OnDone argument. The onGroupDone handler may accept extra DoneResult argument. The onGroupDone handler may also tweak the success bit of a group. All above features conform to the behavior of the task done handler. Task-number: QTCREATORBUG-29834 Change-Id: I125bdfe155e585678fb33410632246401cbc9390 Reviewed-by: Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 58 +++-- src/libs/solutions/tasking/tasktree.h | 82 +++++--- src/plugins/android/androidbuildapkstep.cpp | 2 +- .../autotoolsprojectmanager/autogenstep.cpp | 7 +- .../autoreconfstep.cpp | 7 +- .../autotoolsprojectmanager/configurestep.cpp | 7 +- .../cmakeprojectmanager/cmakebuildstep.cpp | 6 +- .../coreplugin/locator/ilocatorfilter.cpp | 7 +- src/plugins/coreplugin/locator/locator.cpp | 2 +- src/plugins/cppeditor/cppprojectupdater.cpp | 12 +- src/plugins/diffeditor/diffeditorplugin.cpp | 19 +- src/plugins/git/branchmodel.cpp | 3 +- src/plugins/git/branchview.cpp | 2 +- src/plugins/git/gitclient.cpp | 8 +- src/plugins/projectexplorer/buildmanager.cpp | 10 +- .../qmakeprojectmanager/qmakemakestep.cpp | 2 +- src/plugins/qmakeprojectmanager/qmakestep.cpp | 2 +- .../qnx/qnxdeployqtlibrariesdialog.cpp | 2 +- .../abstractremotelinuxdeploystep.cpp | 13 +- .../remotelinux/genericdirectuploadstep.cpp | 2 +- src/plugins/remotelinux/linuxdevicetester.cpp | 29 ++- src/plugins/remotelinux/makeinstallstep.cpp | 17 +- tests/auto/solutions/tasking/tst_tasking.cpp | 198 +++++++----------- tests/auto/utils/async/tst_async.cpp | 2 +- tests/manual/tasking/demo/main.cpp | 22 +- tests/manual/tasking/demo/taskwidget.h | 5 +- .../tasking/imagescaling/imagescaling.cpp | 2 +- 27 files changed, 253 insertions(+), 275 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 2faadd22eca..615fbe0eb4c 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -707,6 +707,8 @@ private: \sa onGroupDone(), onGroupError() */ +// TODO: Fix docs + /*! \fn template GroupItem onGroupSetup(SetupHandler &&handler) @@ -726,6 +728,8 @@ private: \sa GroupItem::GroupSetupHandler, onGroupDone(), onGroupError() */ +// TODO: Fix docs + /*! Constructs a group's element holding the group done handler. The \a handler is invoked whenever the group finishes with success. @@ -740,10 +744,8 @@ private: \sa GroupItem::GroupEndHandler, onGroupSetup(), onGroupError() */ -GroupItem onGroupDone(const GroupItem::GroupEndHandler &handler) -{ - return Group::onGroupDone(handler); -} + +// TODO: Fix docs /*! Constructs a group's element holding the group error handler. @@ -759,10 +761,6 @@ GroupItem onGroupDone(const GroupItem::GroupEndHandler &handler) \sa GroupItem::GroupEndHandler, onGroupSetup(), onGroupDone() */ -GroupItem onGroupError(const GroupItem::GroupEndHandler &handler) -{ - return Group::onGroupError(handler); -} /*! Constructs a group's element describing the \l{Execution Mode}{execution mode}. @@ -924,12 +922,6 @@ void GroupItem::addChildren(const QList &children) m_groupData.m_groupHandler.m_doneHandler = child.m_groupData.m_groupHandler.m_doneHandler; } - if (child.m_groupData.m_groupHandler.m_errorHandler) { - QTC_ASSERT(!m_groupData.m_groupHandler.m_errorHandler, - qWarning("Group Error Handler redefinition, overriding...")); - m_groupData.m_groupHandler.m_errorHandler - = child.m_groupData.m_groupHandler.m_errorHandler; - } if (child.m_groupData.m_parallelLimit) { QTC_ASSERT(!m_groupData.m_parallelLimit, qWarning("Group Execution Mode redefinition, overriding...")); @@ -954,7 +946,7 @@ void GroupItem::addChildren(const QList &children) } GroupItem GroupItem::withTimeout(const GroupItem &item, milliseconds timeout, - const GroupEndHandler &handler) + const std::function &handler) { const auto onSetup = [timeout](milliseconds &timeoutData) { timeoutData = timeout; }; return Group { @@ -1032,7 +1024,7 @@ public: SetupResult startChildren(int nextChild); SetupResult childDone(bool success); void stop(); - void invokeEndHandler(); + bool invokeDoneHandler(DoneWith result); bool isRunning() const { return m_runtimeData.has_value(); } bool isStarting() const { return isRunning() && m_runtimeData->m_startGuard.isLocked(); } @@ -1329,14 +1321,14 @@ SetupResult TaskContainer::continueStart(SetupResult startAction, int nextChild) : startAction; QTC_CHECK(isRunning()); // TODO: superfluous if (groupAction != SetupResult::Continue) { - const bool success = m_runtimeData->updateSuccessBit(groupAction == SetupResult::StopWithDone); - invokeEndHandler(); + const bool bit = m_runtimeData->updateSuccessBit(groupAction == SetupResult::StopWithDone); + const bool result = invokeDoneHandler(bit ? DoneWith::Success : DoneWith::Error); if (TaskContainer *parentContainer = m_constData.m_parentContainer) { QTC_CHECK(parentContainer->isRunning()); if (!parentContainer->isStarting()) - parentContainer->childDone(success); + parentContainer->childDone(result); } else { - m_constData.m_taskTreePrivate->emitDone(success ? DoneWith::Success : DoneWith::Error); + m_constData.m_taskTreePrivate->emitDone(result ? DoneWith::Success : DoneWith::Error); } } return groupAction; @@ -1406,15 +1398,22 @@ void TaskContainer::stop() m_constData.m_taskTreePrivate->advanceProgress(skippedTaskCount); } -void TaskContainer::invokeEndHandler() +static bool shouldCall(CallDoneIf callDoneIf, DoneWith result) { + if (result == DoneWith::Success) + return callDoneIf != CallDoneIf::Error; + return callDoneIf != CallDoneIf::Success; +} + +bool TaskContainer::invokeDoneHandler(DoneWith result) +{ + bool success = result == DoneWith::Success; const GroupItem::GroupHandler &groupHandler = m_constData.m_groupHandler; - if (m_runtimeData->m_successBit && groupHandler.m_doneHandler) - invokeHandler(this, groupHandler.m_doneHandler); - else if (!m_runtimeData->m_successBit && groupHandler.m_errorHandler) - invokeHandler(this, groupHandler.m_errorHandler); + if (groupHandler.m_doneHandler && shouldCall(groupHandler.m_callDoneIf, result)) + success = invokeHandler(this, groupHandler.m_doneHandler, result); m_runtimeData->callStorageDoneHandlers(); m_runtimeData.reset(); + return success; } SetupResult TaskNode::start() @@ -1457,7 +1456,7 @@ void TaskNode::stop() if (!m_task) { m_container.stop(); m_container.m_runtimeData->updateSuccessBit(false); - m_container.invokeEndHandler(); + m_container.invokeDoneHandler(DoneWith::Cancel); return; } @@ -1467,13 +1466,6 @@ void TaskNode::stop() m_task.reset(); } -static bool shouldCall(CallDoneIf callDoneIf, DoneWith result) -{ - if (result == DoneWith::Success) - return callDoneIf != CallDoneIf::Error; - return callDoneIf != CallDoneIf::Success; -} - bool TaskNode::invokeDoneHandler(DoneWith result) { bool success = result == DoneWith::Success; diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 2483dfea821..deacc7c6167 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -157,10 +157,10 @@ public: using TaskSetupHandler = std::function; // Called on task done, just before deleteLater using TaskDoneHandler = std::function; - // Called when group entered + // Called when group entered, after group's storages are created using GroupSetupHandler = std::function; - // Called when group done / error - using GroupEndHandler = std::function; + // Called when group done, before group's storages are deleted + using GroupDoneHandler = std::function; struct TaskHandler { TaskCreateHandler m_createHandler; @@ -171,8 +171,8 @@ public: struct GroupHandler { GroupSetupHandler m_setupHandler; - GroupEndHandler m_doneHandler = {}; - GroupEndHandler m_errorHandler = {}; + GroupDoneHandler m_doneHandler = {}; + CallDoneIf m_callDoneIf = CallDoneIf::SuccessOrError; }; struct GroupData { @@ -210,7 +210,7 @@ protected: static GroupItem parallelLimit(int limit) { return GroupItem({{}, limit}); } static GroupItem workflowPolicy(WorkflowPolicy policy) { return GroupItem({{}, {}, policy}); } static GroupItem withTimeout(const GroupItem &item, std::chrono::milliseconds timeout, - const GroupEndHandler &handler = {}); + const std::function &handler = {}); private: Type m_type = Type::Group; @@ -227,32 +227,30 @@ public: Group(std::initializer_list children) { addChildren(children); } // GroupData related: - template - static GroupItem onGroupSetup(SetupHandler &&handler) { - return groupHandler({wrapGroupSetup(std::forward(handler))}); + template + static GroupItem onGroupSetup(Handler &&handler) { + return groupHandler({wrapGroupSetup(std::forward(handler))}); } - static GroupItem onGroupDone(const GroupEndHandler &handler) { - return groupHandler({{}, handler}); - } - static GroupItem onGroupError(const GroupEndHandler &handler) { - return groupHandler({{}, {}, handler}); + template + static GroupItem onGroupDone(Handler &&handler, CallDoneIf callDoneIf = CallDoneIf::SuccessOrError) { + return groupHandler({{}, wrapGroupDone(std::forward(handler)), callDoneIf}); } using GroupItem::parallelLimit; // Default: 1 (sequential). 0 means unlimited (parallel). using GroupItem::workflowPolicy; // Default: WorkflowPolicy::StopOnError. GroupItem withTimeout(std::chrono::milliseconds timeout, - const GroupEndHandler &handler = {}) const { + const std::function &handler = {}) const { return GroupItem::withTimeout(*this, timeout, handler); } private: - template - static GroupSetupHandler wrapGroupSetup(SetupHandler &&handler) + template + static GroupSetupHandler wrapGroupSetup(Handler &&handler) { static constexpr bool isDynamic - = std::is_same_v>>; + = std::is_same_v>>; constexpr bool isVoid - = std::is_same_v>>; + = std::is_same_v>>; static_assert(isDynamic || isVoid, "Group setup handler needs to take no arguments and has to return " "void or SetupResult. The passed handler doesn't fulfill these requirements."); @@ -263,16 +261,49 @@ private: return SetupResult::Continue; }; }; + template + static GroupDoneHandler wrapGroupDone(Handler &&handler) + { + static constexpr bool isBD // stands for [B]ool, [D]oneWith + = std::is_invocable_r_v, DoneWith>; + static constexpr bool isB + = std::is_invocable_r_v>; + static constexpr bool isVD // stands for [V]oid, [D]oneWith + = std::is_invocable_r_v, DoneWith>; + static constexpr bool isV + = std::is_invocable_r_v>; + static constexpr bool isInvocable = isBD || isB || isVD || isV; + + static_assert(isInvocable, + "Group done handler needs to take (DoneWith) or (void) " + "as arguments and has to return void or bool. " + "The passed handler doesn't fulfill these requirements."); + return [=](DoneWith result) { + if constexpr (isBD) + return std::invoke(handler, result); + if constexpr (isB) + return std::invoke(handler); + if constexpr (isVD) + std::invoke(handler, result); + else if constexpr (isV) + std::invoke(handler); + return result == DoneWith::Success; + }; + }; }; -template -static GroupItem onGroupSetup(SetupHandler &&handler) +template +static GroupItem onGroupSetup(Handler &&handler) { - return Group::onGroupSetup(std::forward(handler)); + return Group::onGroupSetup(std::forward(handler)); +} + +template +static GroupItem onGroupDone(Handler &&handler, CallDoneIf callDoneIf = CallDoneIf::SuccessOrError) +{ + return Group::onGroupDone(std::forward(handler), callDoneIf); } -TASKING_EXPORT GroupItem onGroupDone(const GroupItem::GroupEndHandler &handler); -TASKING_EXPORT GroupItem onGroupError(const GroupItem::GroupEndHandler &handler); TASKING_EXPORT GroupItem parallelLimit(int limit); TASKING_EXPORT GroupItem workflowPolicy(WorkflowPolicy policy); @@ -354,7 +385,8 @@ public: {} GroupItem withTimeout(std::chrono::milliseconds timeout, - const GroupEndHandler &handler = {}) const { + const std::function &handler = {}) const + { return GroupItem::withTimeout(*this, timeout, handler); } diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index 3e840715499..1e8dfbc3fb0 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -834,7 +834,7 @@ Tasking::GroupItem AndroidBuildApkStep::runRecipe() const Group root { onGroupSetup(onSetup), - onGroupDone(onDone), + onGroupDone(onDone, CallDoneIf::Success), defaultProcessTask() }; return root; diff --git a/src/plugins/autotoolsprojectmanager/autogenstep.cpp b/src/plugins/autotoolsprojectmanager/autogenstep.cpp index ec54184478b..2c44a6bfeed 100644 --- a/src/plugins/autotoolsprojectmanager/autogenstep.cpp +++ b/src/plugins/autotoolsprojectmanager/autogenstep.cpp @@ -94,9 +94,12 @@ Tasking::GroupItem AutogenStep::runRecipe() } return SetupResult::Continue; }; - const auto onDone = [this] { m_runAutogen = false; }; - return Group { onGroupSetup(onSetup), onGroupDone(onDone), defaultProcessTask() }; + return Group { + onGroupSetup(onSetup), + onGroupDone([this] { m_runAutogen = false; }, CallDoneIf::Success), + defaultProcessTask() + }; } // AutogenStepFactory diff --git a/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp b/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp index 9dea7d6f7fb..bea7767bf57 100644 --- a/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp +++ b/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp @@ -79,9 +79,12 @@ private: } return SetupResult::Continue; }; - const auto onDone = [this] { m_runAutoreconf = false; }; - return Group { onGroupSetup(onSetup), onGroupDone(onDone), defaultProcessTask() }; + return Group { + onGroupSetup(onSetup), + onGroupDone([this] { m_runAutoreconf = false; }, CallDoneIf::Success), + defaultProcessTask() + }; } bool m_runAutoreconf = false; diff --git a/src/plugins/autotoolsprojectmanager/configurestep.cpp b/src/plugins/autotoolsprojectmanager/configurestep.cpp index 14c7a3eefa6..fe4f5a10f5d 100644 --- a/src/plugins/autotoolsprojectmanager/configurestep.cpp +++ b/src/plugins/autotoolsprojectmanager/configurestep.cpp @@ -98,9 +98,12 @@ Tasking::GroupItem ConfigureStep::runRecipe() } return SetupResult::Continue; }; - const auto onDone = [this] { m_runConfigure = false; }; - return Group { onGroupSetup(onSetup), onGroupDone(onDone), defaultProcessTask() }; + return Group { + onGroupSetup(onSetup), + onGroupDone([this] { m_runConfigure = false; }, CallDoneIf::Success), + defaultProcessTask() + }; } // ConfigureStepFactory diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp index 6de133a6a36..4083e411614 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp @@ -369,15 +369,11 @@ GroupItem CMakeBuildStep::runRecipe() emit addOutput(Tr::tr("Project did not parse successfully, cannot build."), OutputFormat::ErrorMessage); }; - const auto onEnd = [this] { - updateDeploymentData(); - }; Group root { ignoreReturnValue() ? finishAllAndDone : stopOnError, ProjectParserTask(onParserSetup, onParserError, CallDoneIf::Error), defaultProcessTask(), - onGroupDone(onEnd), - onGroupError(onEnd) + onGroupDone([this] { updateDeploymentData(); }) }; return root; } diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.cpp b/src/plugins/coreplugin/locator/ilocatorfilter.cpp index 30240a40ea2..923d9659846 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/ilocatorfilter.cpp @@ -457,10 +457,6 @@ void LocatorMatcher::start() }; }; - const auto onDone = [](const TreeStorage &storage) { - return [storage] { storage->finalize(); }; - }; - int index = 0; for (const LocatorMatcherTask &task : std::as_const(d->m_tasks)) { const auto storage = task.storage; @@ -468,8 +464,7 @@ void LocatorMatcher::start() finishAllAndDone, Storage(storage), onGroupSetup(onSetup(storage, index)), - onGroupDone(onDone(storage)), - onGroupError(onDone(storage)), + onGroupDone([storage] { storage->finalize(); }), task.task }; parallelTasks << group; diff --git a/src/plugins/coreplugin/locator/locator.cpp b/src/plugins/coreplugin/locator/locator.cpp index 3dea793bb3d..306b0df3016 100644 --- a/src/plugins/coreplugin/locator/locator.cpp +++ b/src/plugins/coreplugin/locator/locator.cpp @@ -390,7 +390,7 @@ void Locator::refresh(const QList &filters) const Group group { finishAllAndDone, *task, - onGroupDone([this, filter] { m_refreshingFilters.removeOne(filter); }) + onGroupDone([this, filter] { m_refreshingFilters.removeOne(filter); }, CallDoneIf::Success) }; tasks.append(group); } diff --git a/src/plugins/cppeditor/cppprojectupdater.cpp b/src/plugins/cppeditor/cppprojectupdater.cpp index 1413c5132f2..7f269ac2e2f 100644 --- a/src/plugins/cppeditor/cppprojectupdater.cpp +++ b/src/plugins/cppeditor/cppprojectupdater.cpp @@ -68,7 +68,10 @@ void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo, tasks.append(compiler->compileFileItem()); } - const auto onDone = [this, storage, compilers] { + const auto onDone = [this, storage, compilers](DoneWith result) { + m_taskTree.release()->deleteLater(); + if (result != DoneWith::Success) + return; QList extraCompilers; QSet compilerFiles; for (const QPointer &compiler : compilers) { @@ -80,17 +83,12 @@ void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo, GeneratedCodeModelSupport::update(extraCompilers); auto updateFuture = CppModelManager::updateProjectInfo(storage->projectInfo, compilerFiles); m_futureSynchronizer.addFuture(updateFuture); - m_taskTree.release()->deleteLater(); - }; - const auto onError = [this] { - m_taskTree.release()->deleteLater(); }; const Group root { Tasking::Storage(storage), Group(tasks), - onGroupDone(onDone), - onGroupError(onError) + onGroupDone(onDone) }; m_taskTree.reset(new TaskTree(root)); auto progress = new Core::TaskProgress(m_taskTree.get()); diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp index 2210f15ca8b..9deebb7f9cb 100644 --- a/src/plugins/diffeditor/diffeditorplugin.cpp +++ b/src/plugins/diffeditor/diffeditorplugin.cpp @@ -132,24 +132,21 @@ DiffFilesController::DiffFilesController(IDocument *document) } taskTree.setRecipe(tasks); }; - const auto onTreeDone = [this, storage] { - const QList> &results = *storage; + const auto onTreeDone = [this, storage](DoneWith result) { QList finalList; - for (const std::optional &result : results) { - if (result.has_value()) - finalList.append(*result); + if (result == DoneWith::Success) { + const QList> &results = *storage; + for (const std::optional &result : results) { + if (result.has_value()) + finalList.append(*result); + } } setDiffFiles(finalList); }; - const auto onTreeError = [this, storage] { - setDiffFiles({}); - }; const Group root = { Storage(storage), - TaskTreeTask(onTreeSetup), - onGroupDone(onTreeDone), - onGroupError(onTreeError) + TaskTreeTask(onTreeSetup, onTreeDone) }; setReloadRecipe(root); } diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp index 421624bb5e6..91d74f50b93 100644 --- a/src/plugins/git/branchmodel.cpp +++ b/src/plugins/git/branchmodel.cpp @@ -468,8 +468,7 @@ void BranchModel::refresh(const FilePath &workingDirectory, ShowError showError) const Group root { topRevisionProc, ProcessTask(onForEachRefSetup, onForEachRefDone), - onGroupDone(finalize), - onGroupError(finalize) + onGroupDone(finalize) }; d->refreshTask.reset(new TaskTree(root)); d->refreshTask->start(); diff --git a/src/plugins/git/branchview.cpp b/src/plugins/git/branchview.cpp index 988e148a3f2..960890c2dea 100644 --- a/src/plugins/git/branchview.cpp +++ b/src/plugins/git/branchview.cpp @@ -568,7 +568,7 @@ TaskTree *BranchView::onFastForwardMerge(const std::function &callback) onGroupDone([storage, callback] { if (storage->mergeBase == storage->topRevision) callback(); - }) + }, CallDoneIf::Success) }; auto taskTree = new TaskTree(root); taskTree->start(); diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 9b0d3dad168..79c165bb462 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -340,7 +340,7 @@ FileListDiffController::FileListDiffController(IDocument *document, const QStrin continueOnDone, ProcessTask(onStagedSetup, onStagedDone, CallDoneIf::Success), ProcessTask(onUnstagedSetup, onUnstagedDone, CallDoneIf::Success), - onGroupDone(onDone) + onGroupDone(onDone, CallDoneIf::Success) }, postProcessTask(diffInputStorage) }; @@ -498,7 +498,11 @@ ShowController::ShowController(IDocument *document, const QString &id) updateDescription(*data); }; - QList tasks { parallel, continueOnDone, onGroupError(onFollowsError) }; + QList tasks { + parallel, + continueOnDone, + onGroupDone(onFollowsError, CallDoneIf::Error) + }; for (int i = 0, total = parents.size(); i < total; ++i) { const auto onFollowSetup = [this, parent = parents.at(i)](Process &process) { setupCommand(process, {"describe", "--tags", "--abbrev=0", parent}); diff --git a/src/plugins/projectexplorer/buildmanager.cpp b/src/plugins/projectexplorer/buildmanager.cpp index b3b04a364ff..46d90d14e80 100644 --- a/src/plugins/projectexplorer/buildmanager.cpp +++ b/src/plugins/projectexplorer/buildmanager.cpp @@ -648,15 +648,14 @@ void BuildManager::startBuildQueue() if (d->m_futureProgress) d->m_futureProgress.data()->setTitle(name); }; - const auto onRecipeDone = [buildStep] { + const auto onRecipeDone = [buildStep, target](DoneWith result) { disconnect(buildStep, &BuildStep::progress, instance(), nullptr); d->m_outputWindow->flush(); ++d->m_progress; d->m_progressFutureInterface->setProgressValueAndText( 100 * d->m_progress, msgProgress(d->m_progress, d->m_maxProgress)); - }; - const auto onRecipeError = [buildStep, target, onRecipeDone] { - onRecipeDone(); + if (result == DoneWith::Success) + return; const QString projectName = buildStep->project()->displayName(); const QString targetName = target->displayName(); addToOutputWindow(Tr::tr("Error while building/deploying project %1 (kit: %2)") @@ -673,8 +672,7 @@ void BuildManager::startBuildQueue() const Group recipeGroup { onGroupSetup(onRecipeSetup), buildStep->runRecipe(), - onGroupDone(onRecipeDone), - onGroupError(onRecipeError), + onGroupDone(onRecipeDone) }; targetTasks.append(recipeGroup); } diff --git a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp index 617c0d63e80..8340aac70a9 100644 --- a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp @@ -229,7 +229,7 @@ Tasking::GroupItem QmakeMakeStep::runRecipe() return Group { ignoreReturnValue() ? finishAllAndDone : stopOnError, onGroupSetup(onSetup), - onGroupError(onError), + onGroupDone(onError, CallDoneIf::Error), defaultProcessTask() }; } diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index c95416ebd04..2225ea5da80 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -299,7 +299,7 @@ Tasking::GroupItem QMakeStep::runRecipe() }; QList processList = {onGroupSetup(onSetup), - onGroupDone(onDone), + onGroupDone(onDone, CallDoneIf::Success), ProcessTask(onQMakeSetup, onProcessDone)}; if (m_runMakeQmake) processList << ProcessTask(onMakeQMakeSetup, onProcessDone); diff --git a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp index 10976ad1d50..1cf995c82fd 100644 --- a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp +++ b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp @@ -272,7 +272,7 @@ Group QnxDeployQtLibrariesDialogPrivate::deployRecipe() uploadTask(), chmodTree() }, - onGroupDone(doneHandler) + onGroupDone(doneHandler, CallDoneIf::Success) }; return root; } diff --git a/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp b/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp index 4540deea51d..27ac24232d8 100644 --- a/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp +++ b/src/plugins/remotelinux/abstractremotelinuxdeploystep.cpp @@ -148,17 +148,16 @@ GroupItem AbstractRemoteLinuxDeployStep::runRecipe() } return SetupResult::Continue; }; - const auto onDone = [this] { - emit addOutput(Tr::tr("Deploy step finished."), OutputFormat::NormalMessage); - }; - const auto onError = [this] { - emit addOutput(Tr::tr("Deploy step failed."), OutputFormat::ErrorMessage); + const auto onDone = [this](DoneWith result) { + if (result == DoneWith::Success) + emit addOutput(Tr::tr("Deploy step finished."), OutputFormat::NormalMessage); + else + emit addOutput(Tr::tr("Deploy step failed."), OutputFormat::ErrorMessage); }; return Group { onGroupSetup(onSetup), deployRecipe(), - onGroupDone(onDone), - onGroupError(onError) + onGroupDone(onDone) }; } diff --git a/src/plugins/remotelinux/genericdirectuploadstep.cpp b/src/plugins/remotelinux/genericdirectuploadstep.cpp index a1d11de47ab..65798386991 100644 --- a/src/plugins/remotelinux/genericdirectuploadstep.cpp +++ b/src/plugins/remotelinux/genericdirectuploadstep.cpp @@ -297,7 +297,7 @@ GroupItem GenericDirectUploadStep::deployRecipe() uploadTask(storage), chmodTree(storage), statTree(storage, postFilesToStat, postStatEndHandler), - onGroupDone(doneHandler) + onGroupDone(doneHandler, CallDoneIf::Success) }; return root; } diff --git a/src/plugins/remotelinux/linuxdevicetester.cpp b/src/plugins/remotelinux/linuxdevicetester.cpp index 7dcbedbd96f..3a08c092b9c 100644 --- a/src/plugins/remotelinux/linuxdevicetester.cpp +++ b/src/plugins/remotelinux/linuxdevicetester.cpp @@ -227,16 +227,17 @@ GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod metho GroupItem GenericLinuxDeviceTesterPrivate::transferTasks() const { TreeStorage storage; - return Group{continueOnDone, - Tasking::Storage(storage), - transferTask(FileTransferMethod::GenericCopy, storage), - transferTask(FileTransferMethod::Sftp, storage), - transferTask(FileTransferMethod::Rsync, storage), - onGroupError([this] { - emit q->errorMessage(Tr::tr("Deployment to this device will not " - "work out of the box.") - + "\n"); - })}; + return Group { + continueOnDone, + Tasking::Storage(storage), + transferTask(FileTransferMethod::GenericCopy, storage), + transferTask(FileTransferMethod::Sftp, storage), + transferTask(FileTransferMethod::Rsync, storage), + onGroupDone([this] { + emit q->errorMessage(Tr::tr("Deployment to this device will not work out of the box.") + + "\n"); + }, CallDoneIf::Error) + }; } GroupItem GenericLinuxDeviceTesterPrivate::commandTask(const QString &commandName) const @@ -299,8 +300,8 @@ void GenericLinuxDeviceTester::testDevice(const IDevice::Ptr &deviceConfiguratio d->m_device = deviceConfiguration; - auto allFinished = [this](DeviceTester::TestResult testResult) { - emit finished(testResult); + auto onDone = [this](DoneWith result) { + emit finished(result == DoneWith::Success ? TestSuccess : TestFailure); d->m_taskTree.release()->deleteLater(); }; @@ -313,9 +314,7 @@ void GenericLinuxDeviceTester::testDevice(const IDevice::Ptr &deviceConfiguratio }; if (!d->m_extraTests.isEmpty()) taskItems << Group { d->m_extraTests }; - taskItems << d->commandTasks() - << onGroupDone(std::bind(allFinished, TestSuccess)) - << onGroupError(std::bind(allFinished, TestFailure)); + taskItems << d->commandTasks() << onGroupDone(onDone); d->m_taskTree.reset(new TaskTree(taskItems)); d->m_taskTree->start(); diff --git a/src/plugins/remotelinux/makeinstallstep.cpp b/src/plugins/remotelinux/makeinstallstep.cpp index a061bc4215a..08e65e61261 100644 --- a/src/plugins/remotelinux/makeinstallstep.cpp +++ b/src/plugins/remotelinux/makeinstallstep.cpp @@ -192,7 +192,14 @@ Tasking::GroupItem MakeInstallStep::runRecipe() { using namespace Tasking; - const auto onDone = [this] { + const auto onDone = [this](DoneWith result) { + if (result != DoneWith::Success) { + if (m_noInstallTarget && m_isCmakeProject) { + emit addTask(DeploymentTask(Task::Warning, Tr::tr("You need to add an install " + "statement to your CMakeLists.txt file for deployment to work."))); + } + return; + } const FilePath rootDir = makeCommand().withNewPath(m_installRoot().path()); // FIXME: Needed? m_deploymentData = DeploymentData(); @@ -215,14 +222,8 @@ Tasking::GroupItem MakeInstallStep::runRecipe() buildSystem()->setDeploymentData(m_deploymentData); }; - const auto onError = [this] { - if (m_noInstallTarget && m_isCmakeProject) { - emit addTask(DeploymentTask(Task::Warning, Tr::tr("You need to add an install " - "statement to your CMakeLists.txt file for deployment to work."))); - } - }; - return Group { onGroupDone(onDone), onGroupError(onError), defaultProcessTask() }; + return Group { onGroupDone(onDone), defaultProcessTask() }; } void MakeInstallStep::updateCommandFromAspect() diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index cf315f84a98..03be490df8f 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -24,7 +24,7 @@ enum class Handler { Canceled, GroupSetup, GroupSuccess, - GroupError, + GroupError, // TODO: Add GroupCanceled Sync, BarrierAdvance, Timeout @@ -116,8 +116,7 @@ void tst_Tasking::validConstructs() } }, task, - onGroupDone([] {}), - onGroupError([] {}) + onGroupDone([] {}) }; const auto setupHandler = [](TaskObject &) {}; @@ -213,6 +212,11 @@ GroupItem createBarrierAdvance(const TreeStorage &storage, }); } +static Handler resultToGroupHandler(DoneWith result) +{ + return result == DoneWith::Success ? Handler::GroupSuccess : Handler::GroupError; +} + void tst_Tasking::testTree_data() { QTest::addColumn("testData"); @@ -267,13 +271,14 @@ void tst_Tasking::testTree_data() }; const auto groupSetup = [storage](int taskId) { - return onGroupSetup([=] { storage->m_log.append({taskId, Handler::GroupSetup}); }); + return onGroupSetup([storage, taskId] { + storage->m_log.append({taskId, Handler::GroupSetup}); + }); }; const auto groupDone = [storage](int taskId) { - return onGroupDone([=] { storage->m_log.append({taskId, Handler::GroupSuccess}); }); - }; - const auto groupError = [storage](int taskId) { - return onGroupError([=] { storage->m_log.append({taskId, Handler::GroupError}); }); + return onGroupDone([storage, taskId](DoneWith result) { + storage->m_log.append({taskId, resultToGroupHandler(result)}); + }); }; const auto createSync = [storage](int taskId) { return Sync([=] { storage->m_log.append({taskId, Handler::Sync}); }); @@ -285,26 +290,22 @@ void tst_Tasking::testTree_data() { const Group root1 { Storage(storage), - groupDone(0), - groupError(0) + groupDone(0) }; const Group root2 { Storage(storage), onGroupSetup([] { return SetupResult::Continue; }), - groupDone(0), - groupError(0) + groupDone(0) }; const Group root3 { Storage(storage), onGroupSetup([] { return SetupResult::StopWithDone; }), - groupDone(0), - groupError(0) + groupDone(0) }; const Group root4 { Storage(storage), onGroupSetup([] { return SetupResult::StopWithError; }), - groupDone(0), - groupError(0) + groupDone(0) }; const Log logDone {{0, Handler::GroupSuccess}}; @@ -322,8 +323,7 @@ void tst_Tasking::testTree_data() Storage(storage), workflowPolicy(policy), onGroupSetup([setupResult] { return setupResult; }), - groupDone(0), - groupError(0) + groupDone(0) }; }; @@ -641,8 +641,7 @@ void tst_Tasking::testTree_data() createFailingTask(3), createSuccessTask(4), createSuccessTask(5), - groupDone(0), - groupError(0) + groupDone(0) }; const Log log { {1, Handler::Setup}, @@ -657,12 +656,11 @@ void tst_Tasking::testTree_data() } { - const auto createRoot = [storage, groupDone, groupError](WorkflowPolicy policy) { + const auto createRoot = [storage, groupDone](WorkflowPolicy policy) { return Group { Storage(storage), workflowPolicy(policy), - groupDone(0), - groupError(0) + groupDone(0) }; }; @@ -699,14 +697,13 @@ void tst_Tasking::testTree_data() } { - const auto createRoot = [storage, createSuccessTask, groupDone, groupError]( + const auto createRoot = [storage, createSuccessTask, groupDone]( WorkflowPolicy policy) { return Group { Storage(storage), workflowPolicy(policy), createSuccessTask(1), - groupDone(0), - groupError(0) + groupDone(0) }; }; @@ -752,14 +749,13 @@ void tst_Tasking::testTree_data() } { - const auto createRoot = [storage, createFailingTask, groupDone, groupError]( + const auto createRoot = [storage, createFailingTask, groupDone]( WorkflowPolicy policy) { return Group { Storage(storage), workflowPolicy(policy), createFailingTask(1), - groupDone(0), - groupError(0) + groupDone(0) }; }; @@ -808,16 +804,15 @@ void tst_Tasking::testTree_data() // These tests check whether the proper root's group end handler is called // when the group is stopped. Test it with different workflow policies. // The root starts one short failing task together with one long task. - const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone, - groupError](WorkflowPolicy policy) { + const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone]( + WorkflowPolicy policy) { return Group { Storage(storage), parallel, workflowPolicy(policy), createFailingTask(1, 1ms), createSuccessTask(2, 1ms), - groupDone(0), - groupError(0) + groupDone(0) }; }; @@ -879,8 +874,8 @@ void tst_Tasking::testTree_data() // when the group is stopped. Test it with different workflow policies. // The root starts in parallel: one very short successful task, one short failing task // and one long task. - const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone, - groupError](WorkflowPolicy policy) { + const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone]( + WorkflowPolicy policy) { return Group { Storage(storage), parallel, @@ -888,8 +883,7 @@ void tst_Tasking::testTree_data() createSuccessTask(1), createFailingTask(2, 1ms), createSuccessTask(3, 1ms), - groupDone(0), - groupError(0) + groupDone(0) }; }; @@ -966,24 +960,22 @@ void tst_Tasking::testTree_data() // These tests check whether the proper subgroup's end handler is called // when the group is stopped. Test it with different workflow policies. // The subgroup starts one long task. - const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone, - groupError](WorkflowPolicy policy) { + const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone]( + WorkflowPolicy policy) { return Group { Storage(storage), parallel, Group { workflowPolicy(policy), createSuccessTask(1, 1000ms), - groupDone(1), - groupError(1) + groupDone(1) }, createFailingTask(2, 1ms), - groupDone(2), - groupError(2) + groupDone(2) }; }; - const Log errorLog = { + const Log log = { {1, Handler::Setup}, {2, Handler::Setup}, {2, Handler::Error}, @@ -992,50 +984,43 @@ void tst_Tasking::testTree_data() {2, Handler::GroupError} }; - const Log doneLog = { - {1, Handler::Setup}, - {2, Handler::Setup}, - {2, Handler::Error}, - {1, Handler::Canceled}, - {1, Handler::GroupSuccess}, - {2, Handler::GroupError} - }; - const Group root1 = createRoot(WorkflowPolicy::StopOnError); QTest::newRow("StopGroupWithStopOnError") - << TestData{storage, root1, errorLog, 2, OnDone::Failure}; + << TestData{storage, root1, log, 2, OnDone::Failure}; const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); QTest::newRow("StopGroupWithContinueOnError") - << TestData{storage, root2, errorLog, 2, OnDone::Failure}; + << TestData{storage, root2, log, 2, OnDone::Failure}; const Group root3 = createRoot(WorkflowPolicy::StopOnDone); QTest::newRow("StopGroupWithStopOnDone") - << TestData{storage, root3, errorLog, 2, OnDone::Failure}; + << TestData{storage, root3, log, 2, OnDone::Failure}; const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); QTest::newRow("StopGroupWithContinueOnDone") - << TestData{storage, root4, errorLog, 2, OnDone::Failure}; + << TestData{storage, root4, log, 2, OnDone::Failure}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("StopGroupWithStopOnFinished") - << TestData{storage, root5, errorLog, 2, OnDone::Failure}; + << TestData{storage, root5, log, 2, OnDone::Failure}; + // TODO: Behavioral change! Fix Docs! + // Cancellation always invokes error handler (i.e. DoneWith is Cancel) const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); QTest::newRow("StopGroupWithFinishAllAndDone") - << TestData{storage, root6, doneLog, 2, OnDone::Failure}; + << TestData{storage, root6, log, 2, OnDone::Failure}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); QTest::newRow("StopGroupWithFinishAllAndError") - << TestData{storage, root7, errorLog, 2, OnDone::Failure}; + << TestData{storage, root7, log, 2, OnDone::Failure}; } { // These tests check whether the proper subgroup's end handler is called // when the group is stopped. Test it with different workflow policies. // The sequential subgroup starts one short successful task followed by one long task. - const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone, - groupError](WorkflowPolicy policy) { + const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone]( + WorkflowPolicy policy) { return Group { Storage(storage), parallel, @@ -1043,12 +1028,10 @@ void tst_Tasking::testTree_data() workflowPolicy(policy), createSuccessTask(1), createSuccessTask(2, 1000ms), - groupDone(1), - groupError(1) + groupDone(1) }, createFailingTask(3, 1ms), - groupDone(2), - groupError(2) + groupDone(2) }; }; @@ -1063,7 +1046,7 @@ void tst_Tasking::testTree_data() {2, Handler::GroupError} }; - const Log shortDoneLog = { + const Log doneLog = { {1, Handler::Setup}, {3, Handler::Setup}, {1, Handler::Success}, @@ -1072,17 +1055,6 @@ void tst_Tasking::testTree_data() {2, Handler::GroupError} }; - const Log longDoneLog = { - {1, Handler::Setup}, - {3, Handler::Setup}, - {1, Handler::Success}, - {2, Handler::Setup}, - {3, Handler::Error}, - {2, Handler::Canceled}, - {1, Handler::GroupSuccess}, - {2, Handler::GroupError} - }; - const Group root1 = createRoot(WorkflowPolicy::StopOnError); QTest::newRow("StopGroupAfterDoneWithStopOnError") << TestData{storage, root1, errorLog, 3, OnDone::Failure}; @@ -1093,19 +1065,21 @@ void tst_Tasking::testTree_data() const Group root3 = createRoot(WorkflowPolicy::StopOnDone); QTest::newRow("StopGroupAfterDoneWithStopOnDone") - << TestData{storage, root3, shortDoneLog, 3, OnDone::Failure}; + << TestData{storage, root3, doneLog, 3, OnDone::Failure}; + // TODO: Behavioral change! const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); QTest::newRow("StopGroupAfterDoneWithContinueOnDone") - << TestData{storage, root4, longDoneLog, 3, OnDone::Failure}; + << TestData{storage, root4, errorLog, 3, OnDone::Failure}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("StopGroupAfterDoneWithStopOnFinished") - << TestData{storage, root5, shortDoneLog, 3, OnDone::Failure}; + << TestData{storage, root5, doneLog, 3, OnDone::Failure}; + // TODO: Behavioral change! const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); QTest::newRow("StopGroupAfterDoneWithFinishAllAndDone") - << TestData{storage, root6, longDoneLog, 3, OnDone::Failure}; + << TestData{storage, root6, errorLog, 3, OnDone::Failure}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); QTest::newRow("StopGroupAfterDoneWithFinishAllAndError") @@ -1116,8 +1090,8 @@ void tst_Tasking::testTree_data() // These tests check whether the proper subgroup's end handler is called // when the group is stopped. Test it with different workflow policies. // The sequential subgroup starts one short failing task followed by one long task. - const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone, - groupError](WorkflowPolicy policy) { + const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone]( + WorkflowPolicy policy) { return Group { Storage(storage), parallel, @@ -1125,16 +1099,14 @@ void tst_Tasking::testTree_data() workflowPolicy(policy), createFailingTask(1), createSuccessTask(2, 1000ms), - groupDone(1), - groupError(1) + groupDone(1) }, createFailingTask(3, 1ms), - groupDone(2), - groupError(2) + groupDone(2) }; }; - const Log shortErrorLog = { + const Log shortLog = { {1, Handler::Setup}, {3, Handler::Setup}, {1, Handler::Error}, @@ -1143,7 +1115,7 @@ void tst_Tasking::testTree_data() {2, Handler::GroupError} }; - const Log longErrorLog = { + const Log longLog = { {1, Handler::Setup}, {3, Handler::Setup}, {1, Handler::Error}, @@ -1154,57 +1126,46 @@ void tst_Tasking::testTree_data() {2, Handler::GroupError} }; - const Log doneLog = { - {1, Handler::Setup}, - {3, Handler::Setup}, - {1, Handler::Error}, - {2, Handler::Setup}, - {3, Handler::Error}, - {2, Handler::Canceled}, - {1, Handler::GroupSuccess}, - {2, Handler::GroupError} - }; - const Group root1 = createRoot(WorkflowPolicy::StopOnError); QTest::newRow("StopGroupAfterErrorWithStopOnError") - << TestData{storage, root1, shortErrorLog, 3, OnDone::Failure}; + << TestData{storage, root1, shortLog, 3, OnDone::Failure}; const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); QTest::newRow("StopGroupAfterErrorWithContinueOnError") - << TestData{storage, root2, longErrorLog, 3, OnDone::Failure}; + << TestData{storage, root2, longLog, 3, OnDone::Failure}; const Group root3 = createRoot(WorkflowPolicy::StopOnDone); QTest::newRow("StopGroupAfterErrorWithStopOnDone") - << TestData{storage, root3, longErrorLog, 3, OnDone::Failure}; + << TestData{storage, root3, longLog, 3, OnDone::Failure}; const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); QTest::newRow("StopGroupAfterErrorWithContinueOnDone") - << TestData{storage, root4, longErrorLog, 3, OnDone::Failure}; + << TestData{storage, root4, longLog, 3, OnDone::Failure}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("StopGroupAfterErrorWithStopOnFinished") - << TestData{storage, root5, shortErrorLog, 3, OnDone::Failure}; + << TestData{storage, root5, shortLog, 3, OnDone::Failure}; + // TODO: Behavioral change! const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); QTest::newRow("StopGroupAfterErrorWithFinishAllAndDone") - << TestData{storage, root6, doneLog, 3, OnDone::Failure}; + << TestData{storage, root6, longLog, 3, OnDone::Failure}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); QTest::newRow("StopGroupAfterErrorWithFinishAllAndError") - << TestData{storage, root7, longErrorLog, 3, OnDone::Failure}; + << TestData{storage, root7, longLog, 3, OnDone::Failure}; } { - const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone, - groupError](WorkflowPolicy policy) { + const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone]( + WorkflowPolicy policy) { return Group { Storage(storage), workflowPolicy(policy), createSuccessTask(1), createFailingTask(2), createSuccessTask(3), - groupDone(0), - groupError(0) + groupDone(0) }; }; @@ -1266,7 +1227,7 @@ void tst_Tasking::testTree_data() } { - const auto createRoot = [storage, createTask, groupDone, groupError]( + const auto createRoot = [storage, createTask, groupDone]( bool firstSuccess, bool secondSuccess) { return Group { parallel, @@ -1274,8 +1235,7 @@ void tst_Tasking::testTree_data() Storage(storage), createTask(1, firstSuccess, 1000ms), createTask(2, secondSuccess, 1ms), - groupDone(0), - groupError(0) + groupDone(0) }; }; @@ -1306,8 +1266,7 @@ void tst_Tasking::testTree_data() } { - const auto createRoot = [storage, createSuccessTask, groupDone, groupError]( - SetupResult setupResult) { + const auto createRoot = [storage, createSuccessTask, groupDone](SetupResult setupResult) { return Group { Storage(storage), Group { @@ -1319,8 +1278,7 @@ void tst_Tasking::testTree_data() createSuccessTask(3), createSuccessTask(4) }, - groupDone(0), - groupError(0) + groupDone(0) }; }; @@ -1809,7 +1767,7 @@ void tst_Tasking::testTree_data() createSyncWithReturn(3, false), createSuccessTask(4), createSync(5), - groupError(0) + groupDone(0) }; const Log log { {1, Handler::Sync}, diff --git a/tests/auto/utils/async/tst_async.cpp b/tests/auto/utils/async/tst_async.cpp index b891a3106e1..82e1abf730d 100644 --- a/tests/auto/utils/async/tst_async.cpp +++ b/tests/auto/utils/async/tst_async.cpp @@ -511,7 +511,7 @@ void tst_Async::mapReduce_data() AsyncTask(std::bind(setupHandler, _1, 3), handleAsync, CallDoneIf::Success), AsyncTask(std::bind(setupHandler, _1, 4), handleAsync, CallDoneIf::Success), AsyncTask(std::bind(setupHandler, _1, 5), handleAsync, CallDoneIf::Success), - onGroupDone(doneHandler) + onGroupDone(doneHandler, CallDoneIf::Success) }; }; diff --git a/tests/manual/tasking/demo/main.cpp b/tests/manual/tasking/demo/main.cpp index c48b894580f..51c1c3d9554 100644 --- a/tests/manual/tasking/demo/main.cpp +++ b/tests/manual/tasking/demo/main.cpp @@ -25,7 +25,7 @@ static QWidget *hr() return frame; } -QWidget *taskGroup(QWidget *groupWidget, const QList &widgets) +static QWidget *taskGroup(QWidget *groupWidget, const QList &widgets) { QWidget *widget = new QWidget; QBoxLayout *layout = new QHBoxLayout(widget); @@ -42,6 +42,11 @@ QWidget *taskGroup(QWidget *groupWidget, const QList &widgets) return widget; } +static State resultToState(DoneWith result) +{ + return result == DoneWith::Success ? State::Done : State::Error; +} + int main(int argc, char *argv[]) { QApplication app(argc, argv); @@ -172,8 +177,7 @@ int main(int argc, char *argv[]) const Group root { widget->isSuccess() ? stopOnError : finishAllAndError, TimeoutTask(setupTask), - onGroupDone([widget] { widget->setState(State::Done); }), - onGroupError([widget] { widget->setState(State::Error); }) + onGroupDone([widget](DoneWith result) { widget->setState(resultToState(result)); }) }; return root; }; @@ -183,15 +187,13 @@ int main(int argc, char *argv[]) rootGroup->executeMode(), rootGroup->workflowPolicy(), onGroupSetup([rootGroup] { rootGroup->setState(State::Running); }), - onGroupDone([rootGroup] { rootGroup->setState(State::Done); }), - onGroupError([rootGroup] { rootGroup->setState(State::Error); }), + onGroupDone([rootGroup](DoneWith result) { rootGroup->setState(resultToState(result)); }), Group { groupTask_1->executeMode(), groupTask_1->workflowPolicy(), onGroupSetup([groupTask_1] { groupTask_1->setState(State::Running); }), - onGroupDone([groupTask_1] { groupTask_1->setState(State::Done); }), - onGroupError([groupTask_1] { groupTask_1->setState(State::Error); }), + onGroupDone([groupTask_1](DoneWith result) { groupTask_1->setState(resultToState(result)); }), createTask(task_1_1), createTask(task_1_2), @@ -203,8 +205,7 @@ int main(int argc, char *argv[]) groupTask_4->executeMode(), groupTask_4->workflowPolicy(), onGroupSetup([groupTask_4] { groupTask_4->setState(State::Running); }), - onGroupDone([groupTask_4] { groupTask_4->setState(State::Done); }), - onGroupError([groupTask_4] { groupTask_4->setState(State::Error); }), + onGroupDone([groupTask_4](DoneWith result) { groupTask_4->setState(resultToState(result)); }), createTask(task_4_1), createTask(task_4_2), @@ -212,8 +213,7 @@ int main(int argc, char *argv[]) groupTask_4_3->executeMode(), groupTask_4_3->workflowPolicy(), onGroupSetup([groupTask_4_3] { groupTask_4_3->setState(State::Running); }), - onGroupDone([groupTask_4_3] { groupTask_4_3->setState(State::Done); }), - onGroupError([groupTask_4_3] { groupTask_4_3->setState(State::Error); }), + onGroupDone([groupTask_4_3](DoneWith result) { groupTask_4_3->setState(resultToState(result)); }), createTask(task_4_3_1), createTask(task_4_3_2), diff --git a/tests/manual/tasking/demo/taskwidget.h b/tests/manual/tasking/demo/taskwidget.h index a737e315a4e..2bf3f8719b6 100644 --- a/tests/manual/tasking/demo/taskwidget.h +++ b/tests/manual/tasking/demo/taskwidget.h @@ -20,8 +20,9 @@ QT_END_NAMESPACE enum class State { Initial, Running, - Done, - Error + Done, // TODO: Rename to Success + Error, + // TODO: Add Canceled state }; enum class ExecuteMode { diff --git a/tests/manual/tasking/imagescaling/imagescaling.cpp b/tests/manual/tasking/imagescaling/imagescaling.cpp index fe90bcf546a..ca33779497d 100644 --- a/tests/manual/tasking/imagescaling/imagescaling.cpp +++ b/tests/manual/tasking/imagescaling/imagescaling.cpp @@ -68,7 +68,7 @@ void Images::process() finishAllAndDone, parallel, onGroupSetup(onRootSetup), - onGroupDone(onRootDone) + onGroupDone(onRootDone, CallDoneIf::Success) }; int i = 0; From af63dcaf9608239f9ffdc50d90230a8ac591e3ad Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 3 Nov 2023 20:38:02 +0100 Subject: [PATCH 0090/1546] TaskTree demo: Visualize Canceled state The running task tree may cancel automatically some tasks / groups. Visualize the canceled task / group with cyan color. Add footer with state legend. Task-number: QTCREATORBUG-29834 Change-Id: Ie799fa7b803ca3cc5ac21c580c2f86cd41b3242b Reviewed-by: hjk --- tests/manual/tasking/demo/main.cpp | 35 ++++++++++++---- tests/manual/tasking/demo/taskwidget.cpp | 53 +++++++++++++++++++----- tests/manual/tasking/demo/taskwidget.h | 23 +++++++--- 3 files changed, 86 insertions(+), 25 deletions(-) diff --git a/tests/manual/tasking/demo/main.cpp b/tests/manual/tasking/demo/main.cpp index 51c1c3d9554..91a92805963 100644 --- a/tests/manual/tasking/demo/main.cpp +++ b/tests/manual/tasking/demo/main.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -44,7 +45,12 @@ static QWidget *taskGroup(QWidget *groupWidget, const QList &widgets) static State resultToState(DoneWith result) { - return result == DoneWith::Success ? State::Done : State::Error; + switch (result) { + case DoneWith::Success : return State::Success; + case DoneWith::Error : return State::Error; + case DoneWith::Cancel : return State::Canceled; + } + return State::Initial; } int main(int argc, char *argv[]) @@ -69,16 +75,17 @@ int main(int argc, char *argv[]) // Task GUI - QList allStateWidgets; + QList allGroupWidgets; + QList allTaskWidgets; - auto createGroupWidget = [&allStateWidgets] { - auto *widget = new GroupWidget(); - allStateWidgets.append(widget); + auto createGroupWidget = [&allGroupWidgets] { + auto *widget = new GroupWidget; + allGroupWidgets.append(widget); return widget; }; - auto createTaskWidget = [&allStateWidgets] { - auto *widget = new TaskWidget(); - allStateWidgets.append(widget); + auto createTaskWidget = [&allTaskWidgets] { + auto *widget = new TaskWidget; + allTaskWidgets.append(widget); return widget; }; @@ -162,6 +169,14 @@ int main(int argc, char *argv[]) mainLayout->addLayout(subLayout); mainLayout->addWidget(hr()); mainLayout->addWidget(scrollArea); + mainLayout->addWidget(hr()); + QBoxLayout *footerLayout = new QHBoxLayout; + footerLayout->addWidget(new StateLabel(State::Initial)); + footerLayout->addWidget(new StateLabel(State::Running)); + footerLayout->addWidget(new StateLabel(State::Success)); + footerLayout->addWidget(new StateLabel(State::Error)); + footerLayout->addWidget(new StateLabel(State::Canceled)); + mainLayout->addLayout(footerLayout); } // Task tree (takes initial configuation from GUI) @@ -250,7 +265,9 @@ int main(int argc, char *argv[]) stopTaskTree(); taskTree.reset(); - for (StateWidget *widget : allStateWidgets) + for (GroupWidget *widget : allGroupWidgets) + widget->setState(State::Initial); + for (TaskWidget *widget : allTaskWidgets) widget->setState(State::Initial); progressBar->setValue(0); }; diff --git a/tests/manual/tasking/demo/taskwidget.cpp b/tests/manual/tasking/demo/taskwidget.cpp index 97d3d2b9ef7..4433557b7e9 100644 --- a/tests/manual/tasking/demo/taskwidget.cpp +++ b/tests/manual/tasking/demo/taskwidget.cpp @@ -26,8 +26,9 @@ static QColor stateToColor(State state) { switch (state) { case State::Initial: return Qt::gray; case State::Running: return Qt::yellow; - case State::Done: return Qt::green; + case State::Success: return Qt::green; case State::Error: return Qt::red; + case State::Canceled: return Qt::cyan; } return {}; } @@ -35,9 +36,14 @@ static QColor stateToColor(State state) { class StateIndicator : public QLabel { public: - StateIndicator(QWidget *parent = nullptr) + StateIndicator(State initialState = State::Initial, QWidget *parent = nullptr) : QLabel(parent) + , m_state(initialState) { + setAlignment(Qt::AlignCenter); + QFont f = font(); + f.setBold(true); + setFont(f); m_progressIndicator = new ProgressIndicator(this); m_progressIndicator->hide(); updateState(); @@ -59,13 +65,20 @@ private: m_progressIndicator->show(); else m_progressIndicator->hide(); + setText(m_state == State::Canceled ? "X" : ""); } State m_state = State::Initial; ProgressIndicator *m_progressIndicator = nullptr; }; -StateWidget::StateWidget() - : m_stateIndicator(new StateIndicator(this)) {} +StateWidget::StateWidget(State initialState) + : m_stateIndicator(new StateIndicator(initialState, this)) +{ + QBoxLayout *layout = new QHBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(m_stateIndicator); + setFixedSize(30, 30); +} void StateWidget::setState(State state) { @@ -73,17 +86,17 @@ void StateWidget::setState(State state) } TaskWidget::TaskWidget() - : m_infoLabel(new QLabel("Sleep:")) + : m_stateWidget(new StateWidget) + , m_infoLabel(new QLabel("Sleep:")) , m_spinBox(new QSpinBox) , m_checkBox(new QCheckBox("Report success")) { - m_stateIndicator->setFixedSize(30, 30); m_spinBox->setSuffix(" sec"); setBusyTime(1); setSuccess(true); QBoxLayout *layout = new QHBoxLayout(this); - layout->addWidget(m_stateIndicator); + layout->addWidget(m_stateWidget); layout->addWidget(m_infoLabel); layout->addWidget(m_spinBox); layout->addWidget(m_checkBox); @@ -112,10 +125,11 @@ bool TaskWidget::isSuccess() const } GroupWidget::GroupWidget() - : m_executeCombo(new QComboBox) + : m_stateWidget(new StateWidget) + , m_executeCombo(new QComboBox) , m_workflowCombo(new QComboBox) { - m_stateIndicator->setFixedWidth(30); + m_stateWidget->setFixedSize(30, QWIDGETSIZE_MAX); m_executeCombo->addItem("Sequential", int(ExecuteMode::Sequential)); m_executeCombo->addItem("Parallel", int(ExecuteMode::Parallel)); @@ -134,7 +148,7 @@ GroupWidget::GroupWidget() }); QBoxLayout *layout = new QHBoxLayout(this); - layout->addWidget(m_stateIndicator); + layout->addWidget(m_stateWidget); QBoxLayout *subLayout = new QVBoxLayout; subLayout->addWidget(new QLabel("Execute Mode:")); subLayout->addWidget(m_executeCombo); @@ -178,3 +192,22 @@ GroupItem GroupWidget::workflowPolicy() const { return Tasking::workflowPolicy(m_workflowPolicy); } + +static QString stateToString(State state) +{ + switch (state) { + case State::Initial : return "Initial"; + case State::Running : return "Running"; + case State::Success : return "Success"; + case State::Error : return "Error"; + case State::Canceled : return "Canceled"; + } + return ""; +} + +StateLabel::StateLabel(State state) +{ + QBoxLayout *layout = new QHBoxLayout(this); + layout->addWidget(new StateWidget(state)); + layout->addWidget(new QLabel(stateToString(state))); +} diff --git a/tests/manual/tasking/demo/taskwidget.h b/tests/manual/tasking/demo/taskwidget.h index 2bf3f8719b6..bb7f949b817 100644 --- a/tests/manual/tasking/demo/taskwidget.h +++ b/tests/manual/tasking/demo/taskwidget.h @@ -20,9 +20,9 @@ QT_END_NAMESPACE enum class State { Initial, Running, - Done, // TODO: Rename to Success + Success, Error, - // TODO: Add Canceled state + Canceled }; enum class ExecuteMode { @@ -33,35 +33,39 @@ enum class ExecuteMode { class StateWidget : public QWidget { public: - StateWidget(); - + StateWidget(State initialState = State::Initial); void setState(State state); protected: StateIndicator *m_stateIndicator = nullptr; }; -class TaskWidget : public StateWidget +class TaskWidget : public QWidget { public: TaskWidget(); + void setState(State state) { m_stateWidget->setState(state); } + void setBusyTime(int seconds); int busyTime() const; void setSuccess(bool success); bool isSuccess() const; private: + StateWidget *m_stateWidget = nullptr; QLabel *m_infoLabel = nullptr; QSpinBox *m_spinBox = nullptr; QCheckBox *m_checkBox = nullptr; }; -class GroupWidget : public StateWidget +class GroupWidget : public QWidget { public: GroupWidget(); + void setState(State state) { m_stateWidget->setState(state); } + void setExecuteMode(ExecuteMode mode); Tasking::GroupItem executeMode() const; @@ -72,6 +76,7 @@ private: void updateExecuteMode(); void updateWorkflowPolicy(); + StateWidget *m_stateWidget = nullptr; QComboBox *m_executeCombo = nullptr; QComboBox *m_workflowCombo = nullptr; @@ -79,4 +84,10 @@ private: Tasking::WorkflowPolicy m_workflowPolicy = Tasking::WorkflowPolicy::StopOnError; }; +class StateLabel : public QWidget +{ +public: + StateLabel(State state); +}; + #endif // TASKWIDGET_H From 1da7f18fb7a48bf327edcda2edbb7287196e58b2 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Fri, 3 Nov 2023 23:07:26 +0100 Subject: [PATCH 0091/1546] TaskTree: Introduce List element The List element of GroupItem type is a helper for constructing Group content with an initializer lists. Since there is no easy way of mixing items and lists of items inside the initializer list, the List element encloses the list of children in a single GroupItem element making it possible to mix the lists of GroupItems with individual GroupItem elements on a single initializer list. This addresses the 25th point in the master task below. Task-number: QTCREATORBUG-28741 Change-Id: I5fa4b76677f5aa7dcf875b9e9a16d86a26d380a7 Reviewed-by: Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 11 +++++++-- src/libs/solutions/tasking/tasktree.h | 10 ++++++++ tests/manual/tasking/demo/main.cpp | 33 ++++++++++--------------- 3 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 615fbe0eb4c..283586e5bf7 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -902,10 +902,17 @@ void TreeStorageBase::activateStorage(int id) const void GroupItem::addChildren(const QList &children) { - QTC_ASSERT(m_type == Type::Group, qWarning("Only Group may have children, skipping..."); - return); + QTC_ASSERT(m_type == Type::Group || m_type == Type::List, + qWarning("Only Group or List may have children, skipping..."); return); + if (m_type == Type::List) { + m_children.append(children); + return; + } for (const GroupItem &child : children) { switch (child.m_type) { + case Type::List: + addChildren(child.m_children); + break; case Type::Group: m_children.append(child); break; diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index deacc7c6167..82e242dbb12 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -188,6 +188,7 @@ public: protected: enum class Type { + List, Group, GroupData, Storage, @@ -195,6 +196,7 @@ protected: }; GroupItem() = default; + GroupItem(Type type) : m_type(type) { } GroupItem(const GroupData &data) : m_type(Type::GroupData) , m_groupData(data) {} @@ -220,6 +222,14 @@ private: TaskHandler m_taskHandler; }; +// TODO: Add tests. +class TASKING_EXPORT List final : public GroupItem +{ +public: + List(const QList &children) : GroupItem(Type::List) { addChildren(children); } + List(std::initializer_list children) : GroupItem(Type::List) { addChildren(children); } +}; + class TASKING_EXPORT Group final : public GroupItem { public: diff --git a/tests/manual/tasking/demo/main.cpp b/tests/manual/tasking/demo/main.cpp index 91a92805963..b1b1d70a6df 100644 --- a/tests/manual/tasking/demo/main.cpp +++ b/tests/manual/tasking/demo/main.cpp @@ -183,6 +183,15 @@ int main(int argc, char *argv[]) std::unique_ptr taskTree; + const auto createGroup = [](GroupWidget *widget) { + return List { + widget->executeMode(), + widget->workflowPolicy(), + onGroupSetup([widget] { widget->setState(State::Running); }), + onGroupDone([widget](DoneWith result) { widget->setState(resultToState(result)); }), + }; + }; + const auto createTask = [](TaskWidget *widget) { const milliseconds timeout{widget->busyTime() * 1000}; const auto setupTask = [widget, timeout](milliseconds &taskObject) { @@ -199,17 +208,9 @@ int main(int argc, char *argv[]) const auto recipe = [&] { const Group root { - rootGroup->executeMode(), - rootGroup->workflowPolicy(), - onGroupSetup([rootGroup] { rootGroup->setState(State::Running); }), - onGroupDone([rootGroup](DoneWith result) { rootGroup->setState(resultToState(result)); }), - + createGroup(rootGroup), Group { - groupTask_1->executeMode(), - groupTask_1->workflowPolicy(), - onGroupSetup([groupTask_1] { groupTask_1->setState(State::Running); }), - onGroupDone([groupTask_1](DoneWith result) { groupTask_1->setState(resultToState(result)); }), - + createGroup(groupTask_1), createTask(task_1_1), createTask(task_1_2), createTask(task_1_3) @@ -217,19 +218,11 @@ int main(int argc, char *argv[]) createTask(task_2), createTask(task_3), Group { - groupTask_4->executeMode(), - groupTask_4->workflowPolicy(), - onGroupSetup([groupTask_4] { groupTask_4->setState(State::Running); }), - onGroupDone([groupTask_4](DoneWith result) { groupTask_4->setState(resultToState(result)); }), - + createGroup(groupTask_4), createTask(task_4_1), createTask(task_4_2), Group { - groupTask_4_3->executeMode(), - groupTask_4_3->workflowPolicy(), - onGroupSetup([groupTask_4_3] { groupTask_4_3->setState(State::Running); }), - onGroupDone([groupTask_4_3](DoneWith result) { groupTask_4_3->setState(resultToState(result)); }), - + createGroup(groupTask_4_3), createTask(task_4_3_1), createTask(task_4_3_2), createTask(task_4_3_3), From 273518c82f53fd7e60936145554b16631bb91d2e Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sat, 4 Nov 2023 09:44:33 +0100 Subject: [PATCH 0092/1546] TaskTree tests: Introduce GroupCanceled check Task-number: QTCREATORBUG-29834 Change-Id: I1bf716e662b279c1a85b7f95f81a61be39ee3110 Reviewed-by: hjk --- tests/auto/solutions/tasking/tst_tasking.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index 03be490df8f..029e5de3b19 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -24,7 +24,8 @@ enum class Handler { Canceled, GroupSetup, GroupSuccess, - GroupError, // TODO: Add GroupCanceled + GroupError, + GroupCanceled, Sync, BarrierAdvance, Timeout @@ -214,7 +215,12 @@ GroupItem createBarrierAdvance(const TreeStorage &storage, static Handler resultToGroupHandler(DoneWith result) { - return result == DoneWith::Success ? Handler::GroupSuccess : Handler::GroupError; + switch (result) { + case DoneWith::Success : return Handler::GroupSuccess; + case DoneWith::Error : return Handler::GroupError; + case DoneWith::Cancel : return Handler::GroupCanceled; + } + return Handler::GroupCanceled; } void tst_Tasking::testTree_data() @@ -980,7 +986,7 @@ void tst_Tasking::testTree_data() {2, Handler::Setup}, {2, Handler::Error}, {1, Handler::Canceled}, - {1, Handler::GroupError}, + {1, Handler::GroupCanceled}, {2, Handler::GroupError} }; @@ -1042,7 +1048,7 @@ void tst_Tasking::testTree_data() {2, Handler::Setup}, {3, Handler::Error}, {2, Handler::Canceled}, - {1, Handler::GroupError}, + {1, Handler::GroupCanceled}, {2, Handler::GroupError} }; @@ -1122,7 +1128,7 @@ void tst_Tasking::testTree_data() {2, Handler::Setup}, {3, Handler::Error}, {2, Handler::Canceled}, - {1, Handler::GroupError}, + {1, Handler::GroupCanceled}, {2, Handler::GroupError} }; From 2c0a59384c9d250ecfbbe6d66f4848b82c6a2811 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sat, 4 Nov 2023 12:44:19 +0100 Subject: [PATCH 0093/1546] TaskTree: Rename workflow policies Make naming consistent with recent changes. "Done" is meant to be an event name when the task / group finishes. "Done" may finish with "Success" or an "Error". This addresses the 26th point in the master task below. Task-number: QTCREATORBUG-28741 Change-Id: Icc882710dc4896626dc9332440aa13a692af54c4 Reviewed-by: hjk Reviewed-by: --- src/libs/solutions/tasking/tasktree.cpp | 66 +++++----- src/libs/solutions/tasking/tasktree.h | 28 ++-- src/plugins/autotest/testrunner.cpp | 4 +- src/plugins/clangtools/clangtoolrunner.cpp | 2 +- .../clangtools/documentclangtoolrunner.cpp | 2 +- .../cmakeprojectmanager/cmakebuildstep.cpp | 2 +- .../coreplugin/locator/ilocatorfilter.cpp | 2 +- src/plugins/coreplugin/locator/locator.cpp | 2 +- src/plugins/diffeditor/diffeditorplugin.cpp | 2 +- src/plugins/git/gitclient.cpp | 8 +- .../projectexplorer/abstractprocessstep.cpp | 2 +- .../qmakeprojectmanager/qmakemakestep.cpp | 2 +- .../qnx/qnxdeployqtlibrariesdialog.cpp | 4 +- .../remotelinux/genericdirectuploadstep.cpp | 4 +- src/plugins/remotelinux/linuxdevicetester.cpp | 6 +- src/plugins/subversion/subversionclient.cpp | 2 +- tests/auto/solutions/tasking/tst_tasking.cpp | 122 +++++++++--------- tests/manual/tasking/demo/main.cpp | 4 +- .../tasking/imagescaling/imagescaling.cpp | 2 +- 19 files changed, 133 insertions(+), 133 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 283586e5bf7..0ea24db041f 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -234,7 +234,7 @@ private: \code const Group group { - finishAllAndDone, + finishAllAndSuccess, NetworkQueryTask(...), Group { NetworkQueryTask(...), @@ -311,7 +311,7 @@ private: \code const Group group { - finishAllAndDone, + finishAllAndSuccess, NetworkQueryTask(...), Group { NetworkQueryTask(...), @@ -484,14 +484,14 @@ private: afterwards, even when some other tasks in the group finished with success. If all child tasks finish successfully, the group finishes with success. If a group is empty, it finishes with success. - \value StopOnDone - Corresponds to the stopOnDone global element. + \value StopOnSuccess + Corresponds to the stopOnSuccess global element. If any child task finishes with success, the group stops and finishes with success. If all child tasks finished with an error, the group finishes with an error. If a group is empty, it finishes with an error. - \value ContinueOnDone - Corresponds to the continueOnDone global element. - Similar to stopOnDone, but in case any child finishes successfully, + \value ContinueOnSuccess + Corresponds to the continueOnSuccess global element. + Similar to stopOnSuccess, but in case any child finishes successfully, the execution continues until all tasks finish, and the group reports success afterwards, even when some other tasks in the group finished with an error. If all child tasks finish with an error, the group finishes with an error. @@ -504,8 +504,8 @@ private: In sequential mode, only the first task is started, and when finished, the group finishes too, so the other tasks are always skipped. If a group is empty, it finishes with an error. - \value FinishAllAndDone - Corresponds to the finishAllAndDone global element. + \value FinishAllAndSuccess + Corresponds to the finishAllAndSuccess global element. The group executes all tasks and ignores their return results. When all tasks finished, the group finishes with success. If a group is empty, it finishes with success. @@ -516,7 +516,7 @@ private: If a group is empty, it finishes with an error. Whenever a child task's result causes the Group to stop, - i.e. in case of StopOnError, StopOnDone, or StopOnFinished policies, + i.e. in case of StopOnError, StopOnSuccess, or StopOnFinished policies, the Group stops the other running child tasks (if any - for example in parallel mode), and skips executing tasks it has not started yet (for example, in the sequential mode - those, that are placed after the failed task). Both stopping and skipping child tasks @@ -541,12 +541,12 @@ private: \li An error when at least one child task failed, success otherwise \li Success \row - \li StopOnDone + \li StopOnSuccess \li Stops when any child task finished with success and reports success \li Success when at least one child task succeeded, an error otherwise \li An error \row - \li ContinueOnDone + \li ContinueOnSuccess \li Yes \li Success when at least one child task succeeded, an error otherwise \li An error @@ -556,7 +556,7 @@ private: \li Success or an error, depending on the finished child task's result \li An error \row - \li FinishAllAndDone + \li FinishAllAndSuccess \li Yes \li Success \li Success @@ -569,7 +569,7 @@ private: If a child of a group is also a group, the child group runs its tasks according to its own workflow policy. When a parent group stops the running child group because - of parent group's workflow policy, i.e. when the StopOnError, StopOnDone, or StopOnFinished + of parent group's workflow policy, i.e. when the StopOnError, StopOnSuccess, or StopOnFinished policy was used for the parent, the child group's result is reported according to the \b Result column and to the \b {child group's workflow policy} row in the table above. */ @@ -613,13 +613,13 @@ private: */ /*! - \variable stopOnDone - A convenient global group's element describing the StopOnDone workflow policy. + \variable stopOnSuccess + A convenient global group's element describing the StopOnSuccess workflow policy. */ /*! - \variable continueOnDone - A convenient global group's element describing the ContinueOnDone workflow policy. + \variable continueOnSuccess + A convenient global group's element describing the ContinueOnSuccess workflow policy. */ /*! @@ -628,8 +628,8 @@ private: */ /*! - \variable finishAllAndDone - A convenient global group's element describing the FinishAllAndDone workflow policy. + \variable finishAllAndSuccess + A convenient global group's element describing the FinishAllAndSuccess workflow policy. */ /*! @@ -734,7 +734,7 @@ private: Constructs a group's element holding the group done handler. The \a handler is invoked whenever the group finishes with success. Depending on the group's workflow policy, this handler may also be called - when the running group is stopped (e.g. when finishAllAndDone element was used). + when the running group is stopped (e.g. when finishAllAndSuccess element was used). When the \a handler is invoked, all of the group's child tasks are already finished. @@ -813,8 +813,8 @@ GroupItem parallelLimit(int limit) For convenience, global elements may be used instead. - \sa stopOnError, continueOnError, stopOnDone, continueOnDone, stopOnFinished, finishAllAndDone, - finishAllAndError, WorkflowPolicy + \sa stopOnError, continueOnError, stopOnSuccess, continueOnSuccess, stopOnFinished, + finishAllAndSuccess, finishAllAndError, WorkflowPolicy */ GroupItem workflowPolicy(WorkflowPolicy policy) { @@ -826,10 +826,10 @@ const GroupItem parallel = parallelLimit(0); const GroupItem stopOnError = workflowPolicy(WorkflowPolicy::StopOnError); const GroupItem continueOnError = workflowPolicy(WorkflowPolicy::ContinueOnError); -const GroupItem stopOnDone = workflowPolicy(WorkflowPolicy::StopOnDone); -const GroupItem continueOnDone = workflowPolicy(WorkflowPolicy::ContinueOnDone); +const GroupItem stopOnSuccess = workflowPolicy(WorkflowPolicy::StopOnSuccess); +const GroupItem continueOnSuccess = workflowPolicy(WorkflowPolicy::ContinueOnSuccess); const GroupItem stopOnFinished = workflowPolicy(WorkflowPolicy::StopOnFinished); -const GroupItem finishAllAndDone = workflowPolicy(WorkflowPolicy::FinishAllAndDone); +const GroupItem finishAllAndSuccess = workflowPolicy(WorkflowPolicy::FinishAllAndSuccess); const GroupItem finishAllAndError = workflowPolicy(WorkflowPolicy::FinishAllAndError); static SetupResult toSetupResult(bool success) @@ -1251,10 +1251,10 @@ static bool initialSuccessBit(WorkflowPolicy workflowPolicy) switch (workflowPolicy) { case WorkflowPolicy::StopOnError: case WorkflowPolicy::ContinueOnError: - case WorkflowPolicy::FinishAllAndDone: + case WorkflowPolicy::FinishAllAndSuccess: return true; - case WorkflowPolicy::StopOnDone: - case WorkflowPolicy::ContinueOnDone: + case WorkflowPolicy::StopOnSuccess: + case WorkflowPolicy::ContinueOnSuccess: case WorkflowPolicy::StopOnFinished: case WorkflowPolicy::FinishAllAndError: return false; @@ -1280,7 +1280,7 @@ TaskContainer::RuntimeData::~RuntimeData() bool TaskContainer::RuntimeData::updateSuccessBit(bool success) { - if (m_constData.m_workflowPolicy == WorkflowPolicy::FinishAllAndDone + if (m_constData.m_workflowPolicy == WorkflowPolicy::FinishAllAndSuccess || m_constData.m_workflowPolicy == WorkflowPolicy::FinishAllAndError || m_constData.m_workflowPolicy == WorkflowPolicy::StopOnFinished) { if (m_constData.m_workflowPolicy == WorkflowPolicy::StopOnFinished) @@ -1288,8 +1288,8 @@ bool TaskContainer::RuntimeData::updateSuccessBit(bool success) return m_successBit; } - const bool donePolicy = m_constData.m_workflowPolicy == WorkflowPolicy::StopOnDone - || m_constData.m_workflowPolicy == WorkflowPolicy::ContinueOnDone; + const bool donePolicy = m_constData.m_workflowPolicy == WorkflowPolicy::StopOnSuccess + || m_constData.m_workflowPolicy == WorkflowPolicy::ContinueOnSuccess; m_successBit = donePolicy ? (m_successBit || success) : (m_successBit && success); return m_successBit; } @@ -1373,7 +1373,7 @@ SetupResult TaskContainer::childDone(bool success) QTC_CHECK(isRunning()); const int limit = m_runtimeData->currentLimit(); // Read before bumping m_doneCount and stop() const bool shouldStop = m_constData.m_workflowPolicy == WorkflowPolicy::StopOnFinished - || (m_constData.m_workflowPolicy == WorkflowPolicy::StopOnDone && success) + || (m_constData.m_workflowPolicy == WorkflowPolicy::StopOnSuccess && success) || (m_constData.m_workflowPolicy == WorkflowPolicy::StopOnError && !success); if (shouldStop) stop(); diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 82e242dbb12..594663d0cc6 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -101,26 +101,26 @@ private: }; // WorkflowPolicy: -// 1. When all children finished with done -> report done, otherwise: +// 1. When all children finished with success -> report success, otherwise: // a) Report error on first error and stop executing other children (including their subtree). // b) On first error - continue executing all children and report error afterwards. // 2. When all children finished with error -> report error, otherwise: -// a) Report done on first done and stop executing other children (including their subtree). -// b) On first done - continue executing all children and report done afterwards. +// a) Report success on first success and stop executing other children (including their subtree). +// b) On first success - continue executing all children and report success afterwards. // 3. Stops on first finished child. In sequential mode it will never run other children then the first one. // Useful only in parallel mode. -// 4. Always run all children, let them finish, ignore their results and report done afterwards. +// 4. Always run all children, let them finish, ignore their results and report success afterwards. // 5. Always run all children, let them finish, ignore their results and report error afterwards. enum class WorkflowPolicy { - StopOnError, // 1a - Reports error on first child error, otherwise done (if all children were done). - ContinueOnError, // 1b - The same, but children execution continues. Reports done when no children. - StopOnDone, // 2a - Reports done on first child done, otherwise error (if all children were error). - ContinueOnDone, // 2b - The same, but children execution continues. Reports error when no children. - StopOnFinished, // 3 - Stops on first finished child and report its result. - FinishAllAndDone, // 4 - Reports done after all children finished. - FinishAllAndError // 5 - Reports error after all children finished. + StopOnError, // 1a - Reports error on first child error, otherwise success (if all children were success). + ContinueOnError, // 1b - The same, but children execution continues. Reports success when no children. + StopOnSuccess, // 2a - Reports success on first child success, otherwise error (if all children were error). + ContinueOnSuccess, // 2b - The same, but children execution continues. Reports error when no children. + StopOnFinished, // 3 - Stops on first finished child and report its result. + FinishAllAndSuccess, // 4 - Reports success after all children finished. + FinishAllAndError // 5 - Reports error after all children finished. }; Q_ENUM_NS(WorkflowPolicy); @@ -322,10 +322,10 @@ TASKING_EXPORT extern const GroupItem parallel; TASKING_EXPORT extern const GroupItem stopOnError; TASKING_EXPORT extern const GroupItem continueOnError; -TASKING_EXPORT extern const GroupItem stopOnDone; -TASKING_EXPORT extern const GroupItem continueOnDone; +TASKING_EXPORT extern const GroupItem stopOnSuccess; +TASKING_EXPORT extern const GroupItem continueOnSuccess; TASKING_EXPORT extern const GroupItem stopOnFinished; -TASKING_EXPORT extern const GroupItem finishAllAndDone; +TASKING_EXPORT extern const GroupItem finishAllAndSuccess; TASKING_EXPORT extern const GroupItem finishAllAndError; class TASKING_EXPORT Storage final : public GroupItem diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index 8d3f4bdf1de..4308316214c 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -347,7 +347,7 @@ void TestRunner::runTestsHelper() std::unique_ptr m_outputReader; }; - QList tasks{finishAllAndDone}; + QList tasks{finishAllAndSuccess}; for (ITestConfiguration *config : m_selectedTests) { QTC_ASSERT(config, continue); @@ -445,7 +445,7 @@ void TestRunner::runTestsHelper() } }; const Group group { - finishAllAndDone, + finishAllAndSuccess, Tasking::Storage(storage), onGroupSetup(onSetup), ProcessTask(onProcessSetup, onProcessDone) diff --git a/src/plugins/clangtools/clangtoolrunner.cpp b/src/plugins/clangtools/clangtoolrunner.cpp index f3f228d5439..d6ddae635b2 100644 --- a/src/plugins/clangtools/clangtoolrunner.cpp +++ b/src/plugins/clangtools/clangtoolrunner.cpp @@ -218,7 +218,7 @@ GroupItem clangToolTask(const AnalyzeInputData &input, }; const Group group { - finishAllAndDone, + finishAllAndSuccess, Tasking::Storage(storage), onGroupSetup(onSetup), Group { diff --git a/src/plugins/clangtools/documentclangtoolrunner.cpp b/src/plugins/clangtools/documentclangtoolrunner.cpp index 16c75c1eb07..fb8ef748016 100644 --- a/src/plugins/clangtools/documentclangtoolrunner.cpp +++ b/src/plugins/clangtools/documentclangtoolrunner.cpp @@ -215,7 +215,7 @@ void DocumentClangToolRunner::run() return !m_document->isModified() || isVFSOverlaySupported(executable); }; const auto outputHandler = [this](const AnalyzeOutputData &output) { onDone(output); }; - tasks.append(Group{finishAllAndDone, clangToolTask(input, setupHandler, outputHandler)}); + tasks.append(Group{finishAllAndSuccess, clangToolTask(input, setupHandler, outputHandler)}); }; addClangTool(ClangToolType::Tidy); addClangTool(ClangToolType::Clazy); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp index 4083e411614..ba36aec1055 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp @@ -370,7 +370,7 @@ GroupItem CMakeBuildStep::runRecipe() OutputFormat::ErrorMessage); }; Group root { - ignoreReturnValue() ? finishAllAndDone : stopOnError, + ignoreReturnValue() ? finishAllAndSuccess : stopOnError, ProjectParserTask(onParserSetup, onParserError, CallDoneIf::Error), defaultProcessTask(), onGroupDone([this] { updateDeploymentData(); }) diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.cpp b/src/plugins/coreplugin/locator/ilocatorfilter.cpp index 923d9659846..9cfc8fe24e0 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/ilocatorfilter.cpp @@ -461,7 +461,7 @@ void LocatorMatcher::start() for (const LocatorMatcherTask &task : std::as_const(d->m_tasks)) { const auto storage = task.storage; const Group group { - finishAllAndDone, + finishAllAndSuccess, Storage(storage), onGroupSetup(onSetup(storage, index)), onGroupDone([storage] { storage->finalize(); }), diff --git a/src/plugins/coreplugin/locator/locator.cpp b/src/plugins/coreplugin/locator/locator.cpp index 306b0df3016..9dcd9b34fc2 100644 --- a/src/plugins/coreplugin/locator/locator.cpp +++ b/src/plugins/coreplugin/locator/locator.cpp @@ -388,7 +388,7 @@ void Locator::refresh(const QList &filters) continue; const Group group { - finishAllAndDone, + finishAllAndSuccess, *task, onGroupDone([this, filter] { m_refreshingFilters.removeOne(filter); }, CallDoneIf::Success) }; diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp index 9deebb7f9cb..89acf370861 100644 --- a/src/plugins/diffeditor/diffeditorplugin.cpp +++ b/src/plugins/diffeditor/diffeditorplugin.cpp @@ -116,7 +116,7 @@ DiffFilesController::DiffFilesController(IDocument *document) const QList inputList = reloadInputList(); outputList->resize(inputList.size()); - QList tasks { parallel, finishAllAndDone }; + QList tasks { parallel, finishAllAndSuccess }; for (int i = 0; i < inputList.size(); ++i) { const auto onDiffSetup = [this, reloadInput = inputList.at(i)](Async &async) { async.setConcurrentCallData( diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 79c165bb462..9ed9fc8c0e7 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -337,7 +337,7 @@ FileListDiffController::FileListDiffController(IDocument *document, const QStrin Tasking::Storage(diffInputStorage), Group { parallel, - continueOnDone, + continueOnSuccess, ProcessTask(onStagedSetup, onStagedDone, CallDoneIf::Success), ProcessTask(onUnstagedSetup, onUnstagedDone, CallDoneIf::Success), onGroupDone(onDone, CallDoneIf::Success) @@ -500,7 +500,7 @@ ShowController::ShowController(IDocument *document, const QString &id) QList tasks { parallel, - continueOnDone, + continueOnSuccess, onGroupDone(onFollowsError, CallDoneIf::Error) }; for (int i = 0, total = parents.size(); i < total; ++i) { @@ -532,11 +532,11 @@ ShowController::ShowController(IDocument *document, const QString &id) parallel, onGroupSetup([this] { setStartupFile(VcsBase::source(this->document()).toString()); }), Group { - finishAllAndDone, + finishAllAndSuccess, ProcessTask(onDescriptionSetup, onDescriptionDone, CallDoneIf::Success), Group { parallel, - finishAllAndDone, + finishAllAndSuccess, onGroupSetup(desciptionDetailsSetup), ProcessTask(onBranchesSetup, onBranchesDone, CallDoneIf::Success), ProcessTask(onPrecedesSetup, onPrecedesDone, CallDoneIf::Success), diff --git a/src/plugins/projectexplorer/abstractprocessstep.cpp b/src/plugins/projectexplorer/abstractprocessstep.cpp index b18e79502e9..41d49f93494 100644 --- a/src/plugins/projectexplorer/abstractprocessstep.cpp +++ b/src/plugins/projectexplorer/abstractprocessstep.cpp @@ -283,7 +283,7 @@ void AbstractProcessStep::setDisplayedParameters(ProcessParameters *params) GroupItem AbstractProcessStep::runRecipe() { - return Group { ignoreReturnValue() ? finishAllAndDone : stopOnError, defaultProcessTask() }; + return Group { ignoreReturnValue() ? finishAllAndSuccess : stopOnError, defaultProcessTask() }; } } // namespace ProjectExplorer diff --git a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp index 8340aac70a9..ef0ffbfac29 100644 --- a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp @@ -227,7 +227,7 @@ Tasking::GroupItem QmakeMakeStep::runRecipe() }; return Group { - ignoreReturnValue() ? finishAllAndDone : stopOnError, + ignoreReturnValue() ? finishAllAndSuccess : stopOnError, onGroupSetup(onSetup), onGroupDone(onError, CallDoneIf::Error), defaultProcessTask() diff --git a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp index 1cf995c82fd..b5d3b24d7be 100644 --- a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp +++ b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp @@ -223,7 +223,7 @@ GroupItem QnxDeployQtLibrariesDialogPrivate::chmodTree() if (file.isExecutable()) filesToChmod << file; } - QList chmodList{finishAllAndDone, parallelLimit(MaxConcurrentStatCalls)}; + QList chmodList{finishAllAndSuccess, parallelLimit(MaxConcurrentStatCalls)}; for (const DeployableFile &file : std::as_const(filesToChmod)) { QTC_ASSERT(file.isValid(), continue); chmodList.append(chmodTask(file)); @@ -263,7 +263,7 @@ Group QnxDeployQtLibrariesDialogPrivate::deployRecipe() const Group root { onGroupSetup(setupHandler), Group { - finishAllAndDone, + finishAllAndSuccess, checkDirTask() }, Group { diff --git a/src/plugins/remotelinux/genericdirectuploadstep.cpp b/src/plugins/remotelinux/genericdirectuploadstep.cpp index 65798386991..bfc2c67c2ff 100644 --- a/src/plugins/remotelinux/genericdirectuploadstep.cpp +++ b/src/plugins/remotelinux/genericdirectuploadstep.cpp @@ -154,7 +154,7 @@ GroupItem GenericDirectUploadStep::statTree(const TreeStorage &st const auto onSetup = [this, storage, filesToStat, statEndHandler](TaskTree &tree) { UploadStorage *storagePtr = storage.activeStorage(); const QList files = filesToStat(storagePtr); - QList statList{finishAllAndDone, parallelLimit(MaxConcurrentStatCalls)}; + QList statList{finishAllAndSuccess, parallelLimit(MaxConcurrentStatCalls)}; for (const DeployableFile &file : std::as_const(files)) { QTC_ASSERT(file.isValid(), continue); statList.append(statTask(storagePtr, file, statEndHandler)); @@ -231,7 +231,7 @@ GroupItem GenericDirectUploadStep::chmodTree(const TreeStorage &s if (file.isExecutable()) filesToChmod << file; } - QList chmodList{finishAllAndDone, parallelLimit(MaxConcurrentStatCalls)}; + QList chmodList{finishAllAndSuccess, parallelLimit(MaxConcurrentStatCalls)}; for (const DeployableFile &file : std::as_const(filesToChmod)) { QTC_ASSERT(file.isValid(), continue); chmodList.append(chmodTask(file)); diff --git a/src/plugins/remotelinux/linuxdevicetester.cpp b/src/plugins/remotelinux/linuxdevicetester.cpp index 3a08c092b9c..5f1029dbfa5 100644 --- a/src/plugins/remotelinux/linuxdevicetester.cpp +++ b/src/plugins/remotelinux/linuxdevicetester.cpp @@ -135,7 +135,7 @@ GroupItem GenericLinuxDeviceTesterPrivate::unameTask() const emit q->errorMessage(Tr::tr("uname failed.") + '\n'); }; return Group { - finishAllAndDone, + finishAllAndSuccess, ProcessTask(onSetup, onDone) }; } @@ -162,7 +162,7 @@ GroupItem GenericLinuxDeviceTesterPrivate::gathererTask() const }; return Group { - finishAllAndDone, + finishAllAndSuccess, DeviceUsedPortsGathererTask(onSetup, onDone) }; } @@ -228,7 +228,7 @@ GroupItem GenericLinuxDeviceTesterPrivate::transferTasks() const { TreeStorage storage; return Group { - continueOnDone, + continueOnSuccess, Tasking::Storage(storage), transferTask(FileTransferMethod::GenericCopy, storage), transferTask(FileTransferMethod::Sftp, storage), diff --git a/src/plugins/subversion/subversionclient.cpp b/src/plugins/subversion/subversionclient.cpp index e1f45c1b34a..fbe19892160 100644 --- a/src/plugins/subversion/subversionclient.cpp +++ b/src/plugins/subversion/subversionclient.cpp @@ -201,7 +201,7 @@ SubversionDiffEditorController::SubversionDiffEditorController(IDocument *docume Tasking::Storage(diffInputStorage), parallel, Group { - finishAllAndDone, + finishAllAndSuccess, ProcessTask(onDescriptionSetup, onDescriptionDone) }, Group { diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index 029e5de3b19..9f8035182e7 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -344,18 +344,18 @@ void tst_Tasking::testTree_data() QTest::newRow("DoneAndStopOnError") << doneData(WorkflowPolicy::StopOnError); QTest::newRow("DoneAndContinueOnError") << doneData(WorkflowPolicy::ContinueOnError); - QTest::newRow("DoneAndStopOnDone") << doneData(WorkflowPolicy::StopOnDone); - QTest::newRow("DoneAndContinueOnDone") << doneData(WorkflowPolicy::ContinueOnDone); + QTest::newRow("DoneAndStopOnSuccess") << doneData(WorkflowPolicy::StopOnSuccess); + QTest::newRow("DoneAndContinueOnSuccess") << doneData(WorkflowPolicy::ContinueOnSuccess); QTest::newRow("DoneAndStopOnFinished") << doneData(WorkflowPolicy::StopOnFinished); - QTest::newRow("DoneAndFinishAllAndDone") << doneData(WorkflowPolicy::FinishAllAndDone); + QTest::newRow("DoneAndFinishAllAndSuccess") << doneData(WorkflowPolicy::FinishAllAndSuccess); QTest::newRow("DoneAndFinishAllAndError") << doneData(WorkflowPolicy::FinishAllAndError); QTest::newRow("ErrorAndStopOnError") << errorData(WorkflowPolicy::StopOnError); QTest::newRow("ErrorAndContinueOnError") << errorData(WorkflowPolicy::ContinueOnError); - QTest::newRow("ErrorAndStopOnDone") << errorData(WorkflowPolicy::StopOnDone); - QTest::newRow("ErrorAndContinueOnDone") << errorData(WorkflowPolicy::ContinueOnDone); + QTest::newRow("ErrorAndStopOnSuccess") << errorData(WorkflowPolicy::StopOnSuccess); + QTest::newRow("ErrorAndContinueOnSuccess") << errorData(WorkflowPolicy::ContinueOnSuccess); QTest::newRow("ErrorAndStopOnFinished") << errorData(WorkflowPolicy::StopOnFinished); - QTest::newRow("ErrorAndFinishAllAndDone") << errorData(WorkflowPolicy::FinishAllAndDone); + QTest::newRow("ErrorAndFinishAllAndSuccess") << errorData(WorkflowPolicy::FinishAllAndSuccess); QTest::newRow("ErrorAndFinishAllAndError") << errorData(WorkflowPolicy::FinishAllAndError); } @@ -681,20 +681,20 @@ void tst_Tasking::testTree_data() QTest::newRow("EmptyContinueOnError") << TestData{storage, root2, doneLog, 0, OnDone::Success}; - const Group root3 = createRoot(WorkflowPolicy::StopOnDone); - QTest::newRow("EmptyStopOnDone") << TestData{storage, root3, errorLog, 0, + const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); + QTest::newRow("EmptyStopOnSuccess") << TestData{storage, root3, errorLog, 0, OnDone::Failure}; - const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); - QTest::newRow("EmptyContinueOnDone") << TestData{storage, root4, errorLog, 0, + const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); + QTest::newRow("EmptyContinueOnSuccess") << TestData{storage, root4, errorLog, 0, OnDone::Failure}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("EmptyStopOnFinished") << TestData{storage, root5, errorLog, 0, OnDone::Failure}; - const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); - QTest::newRow("EmptyFinishAllAndDone") << TestData{storage, root6, doneLog, 0, + const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); + QTest::newRow("EmptyFinishAllAndSuccess") << TestData{storage, root6, doneLog, 0, OnDone::Success}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); @@ -733,20 +733,20 @@ void tst_Tasking::testTree_data() QTest::newRow("DoneContinueOnError") << TestData{storage, root2, doneLog, 1, OnDone::Success}; - const Group root3 = createRoot(WorkflowPolicy::StopOnDone); - QTest::newRow("DoneStopOnDone") << TestData{storage, root3, doneLog, 1, + const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); + QTest::newRow("DoneStopOnSuccess") << TestData{storage, root3, doneLog, 1, OnDone::Success}; - const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); - QTest::newRow("DoneContinueOnDone") << TestData{storage, root4, doneLog, 1, + const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); + QTest::newRow("DoneContinueOnSuccess") << TestData{storage, root4, doneLog, 1, OnDone::Success}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("DoneStopOnFinished") << TestData{storage, root5, doneLog, 1, OnDone::Success}; - const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); - QTest::newRow("DoneFinishAllAndDone") << TestData{storage, root6, doneLog, 1, + const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); + QTest::newRow("DoneFinishAllAndSuccess") << TestData{storage, root6, doneLog, 1, OnDone::Success}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); @@ -785,20 +785,20 @@ void tst_Tasking::testTree_data() QTest::newRow("ErrorContinueOnError") << TestData{storage, root2, errorLog, 1, OnDone::Failure}; - const Group root3 = createRoot(WorkflowPolicy::StopOnDone); - QTest::newRow("ErrorStopOnDone") << TestData{storage, root3, errorLog, 1, + const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); + QTest::newRow("ErrorStopOnSuccess") << TestData{storage, root3, errorLog, 1, OnDone::Failure}; - const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); - QTest::newRow("ErrorContinueOnDone") << TestData{storage, root4, errorLog, 1, + const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); + QTest::newRow("ErrorContinueOnSuccess") << TestData{storage, root4, errorLog, 1, OnDone::Failure}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("ErrorStopOnFinished") << TestData{storage, root5, errorLog, 1, OnDone::Failure}; - const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); - QTest::newRow("ErrorFinishAllAndDone") << TestData{storage, root6, doneLog, 1, + const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); + QTest::newRow("ErrorFinishAllAndSuccess") << TestData{storage, root6, doneLog, 1, OnDone::Success}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); @@ -854,20 +854,20 @@ void tst_Tasking::testTree_data() QTest::newRow("StopRootWithContinueOnError") << TestData{storage, root2, errorDoneLog, 2, OnDone::Failure}; - const Group root3 = createRoot(WorkflowPolicy::StopOnDone); - QTest::newRow("StopRootWithStopOnDone") + const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); + QTest::newRow("StopRootWithStopOnSuccess") << TestData{storage, root3, doneLog, 2, OnDone::Success}; - const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); - QTest::newRow("StopRootWithContinueOnDone") + const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); + QTest::newRow("StopRootWithContinueOnSuccess") << TestData{storage, root4, doneLog, 2, OnDone::Success}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("StopRootWithStopOnFinished") << TestData{storage, root5, errorErrorLog, 2, OnDone::Failure}; - const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); - QTest::newRow("StopRootWithFinishAllAndDone") + const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); + QTest::newRow("StopRootWithFinishAllAndSuccess") << TestData{storage, root6, doneLog, 2, OnDone::Success}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); @@ -941,20 +941,20 @@ void tst_Tasking::testTree_data() QTest::newRow("StopRootAfterDoneWithContinueOnError") << TestData{storage, root2, errorDoneLog, 3, OnDone::Failure}; - const Group root3 = createRoot(WorkflowPolicy::StopOnDone); - QTest::newRow("StopRootAfterDoneWithStopOnDone") + const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); + QTest::newRow("StopRootAfterDoneWithStopOnSuccess") << TestData{storage, root3, doneErrorLog, 3, OnDone::Success}; - const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); - QTest::newRow("StopRootAfterDoneWithContinueOnDone") + const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); + QTest::newRow("StopRootAfterDoneWithContinueOnSuccess") << TestData{storage, root4, doneDoneLog, 3, OnDone::Success}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("StopRootAfterDoneWithStopOnFinished") << TestData{storage, root5, doneErrorLog, 3, OnDone::Success}; - const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); - QTest::newRow("StopRootAfterDoneWithFinishAllAndDone") + const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); + QTest::newRow("StopRootAfterDoneWithFinishAllAndSuccess") << TestData{storage, root6, doneDoneLog, 3, OnDone::Success}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); @@ -998,12 +998,12 @@ void tst_Tasking::testTree_data() QTest::newRow("StopGroupWithContinueOnError") << TestData{storage, root2, log, 2, OnDone::Failure}; - const Group root3 = createRoot(WorkflowPolicy::StopOnDone); - QTest::newRow("StopGroupWithStopOnDone") + const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); + QTest::newRow("StopGroupWithStopOnSuccess") << TestData{storage, root3, log, 2, OnDone::Failure}; - const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); - QTest::newRow("StopGroupWithContinueOnDone") + const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); + QTest::newRow("StopGroupWithContinueOnSuccess") << TestData{storage, root4, log, 2, OnDone::Failure}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); @@ -1011,9 +1011,9 @@ void tst_Tasking::testTree_data() << TestData{storage, root5, log, 2, OnDone::Failure}; // TODO: Behavioral change! Fix Docs! - // Cancellation always invokes error handler (i.e. DoneWith is Cancel) - const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); - QTest::newRow("StopGroupWithFinishAllAndDone") + // Cancellation always invokes error handler (i.e. DoneWith is Canceled) + const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); + QTest::newRow("StopGroupWithFinishAllAndSuccess") << TestData{storage, root6, log, 2, OnDone::Failure}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); @@ -1069,13 +1069,13 @@ void tst_Tasking::testTree_data() QTest::newRow("StopGroupAfterDoneWithContinueOnError") << TestData{storage, root2, errorLog, 3, OnDone::Failure}; - const Group root3 = createRoot(WorkflowPolicy::StopOnDone); - QTest::newRow("StopGroupAfterDoneWithStopOnDone") + const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); + QTest::newRow("StopGroupAfterDoneWithStopOnSuccess") << TestData{storage, root3, doneLog, 3, OnDone::Failure}; // TODO: Behavioral change! - const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); - QTest::newRow("StopGroupAfterDoneWithContinueOnDone") + const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); + QTest::newRow("StopGroupAfterDoneWithContinueOnSuccess") << TestData{storage, root4, errorLog, 3, OnDone::Failure}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); @@ -1083,8 +1083,8 @@ void tst_Tasking::testTree_data() << TestData{storage, root5, doneLog, 3, OnDone::Failure}; // TODO: Behavioral change! - const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); - QTest::newRow("StopGroupAfterDoneWithFinishAllAndDone") + const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); + QTest::newRow("StopGroupAfterDoneWithFinishAllAndSuccess") << TestData{storage, root6, errorLog, 3, OnDone::Failure}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); @@ -1140,12 +1140,12 @@ void tst_Tasking::testTree_data() QTest::newRow("StopGroupAfterErrorWithContinueOnError") << TestData{storage, root2, longLog, 3, OnDone::Failure}; - const Group root3 = createRoot(WorkflowPolicy::StopOnDone); - QTest::newRow("StopGroupAfterErrorWithStopOnDone") + const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); + QTest::newRow("StopGroupAfterErrorWithStopOnSuccess") << TestData{storage, root3, longLog, 3, OnDone::Failure}; - const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); - QTest::newRow("StopGroupAfterErrorWithContinueOnDone") + const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); + QTest::newRow("StopGroupAfterErrorWithContinueOnSuccess") << TestData{storage, root4, longLog, 3, OnDone::Failure}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); @@ -1153,8 +1153,8 @@ void tst_Tasking::testTree_data() << TestData{storage, root5, shortLog, 3, OnDone::Failure}; // TODO: Behavioral change! - const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); - QTest::newRow("StopGroupAfterErrorWithFinishAllAndDone") + const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); + QTest::newRow("StopGroupAfterErrorWithFinishAllAndSuccess") << TestData{storage, root6, longLog, 3, OnDone::Failure}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); @@ -1197,15 +1197,15 @@ void tst_Tasking::testTree_data() }; QTest::newRow("ContinueOnError") << TestData{storage, root2, errorLog, 3, OnDone::Failure}; - const Group root3 = createRoot(WorkflowPolicy::StopOnDone); + const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); const Log log3 { {1, Handler::Setup}, {1, Handler::Success}, {0, Handler::GroupSuccess} }; - QTest::newRow("StopOnDone") << TestData{storage, root3, log3, 3, OnDone::Success}; + QTest::newRow("StopOnSuccess") << TestData{storage, root3, log3, 3, OnDone::Success}; - const Group root4 = createRoot(WorkflowPolicy::ContinueOnDone); + const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); const Log doneLog { {1, Handler::Setup}, {1, Handler::Success}, @@ -1215,7 +1215,7 @@ void tst_Tasking::testTree_data() {3, Handler::Success}, {0, Handler::GroupSuccess} }; - QTest::newRow("ContinueOnDone") << TestData{storage, root4, doneLog, 3, OnDone::Success}; + QTest::newRow("ContinueOnSuccess") << TestData{storage, root4, doneLog, 3, OnDone::Success}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); const Log log5 { @@ -1225,8 +1225,8 @@ void tst_Tasking::testTree_data() }; QTest::newRow("StopOnFinished") << TestData{storage, root5, log5, 3, OnDone::Success}; - const Group root6 = createRoot(WorkflowPolicy::FinishAllAndDone); - QTest::newRow("FinishAllAndDone") << TestData{storage, root6, doneLog, 3, OnDone::Success}; + const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); + QTest::newRow("FinishAllAndSuccess") << TestData{storage, root6, doneLog, 3, OnDone::Success}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); QTest::newRow("FinishAllAndError") << TestData{storage, root7, errorLog, 3, OnDone::Failure}; diff --git a/tests/manual/tasking/demo/main.cpp b/tests/manual/tasking/demo/main.cpp index b1b1d70a6df..b87a094cfb1 100644 --- a/tests/manual/tasking/demo/main.cpp +++ b/tests/manual/tasking/demo/main.cpp @@ -125,8 +125,8 @@ int main(int argc, char *argv[]) task_4_4->setBusyTime(6); task_4_4->setBusyTime(3); - groupTask_1->setWorkflowPolicy(WorkflowPolicy::ContinueOnDone); - groupTask_4->setWorkflowPolicy(WorkflowPolicy::FinishAllAndDone); + groupTask_1->setWorkflowPolicy(WorkflowPolicy::ContinueOnSuccess); + groupTask_4->setWorkflowPolicy(WorkflowPolicy::FinishAllAndSuccess); groupTask_4_3->setExecuteMode(ExecuteMode::Parallel); groupTask_4_3->setWorkflowPolicy(WorkflowPolicy::StopOnError); diff --git a/tests/manual/tasking/imagescaling/imagescaling.cpp b/tests/manual/tasking/imagescaling/imagescaling.cpp index ca33779497d..5e13a83a39a 100644 --- a/tests/manual/tasking/imagescaling/imagescaling.cpp +++ b/tests/manual/tasking/imagescaling/imagescaling.cpp @@ -65,7 +65,7 @@ void Images::process() cancelButton->setEnabled(false); }; QList tasks { - finishAllAndDone, + finishAllAndSuccess, parallel, onGroupSetup(onRootSetup), onGroupDone(onRootDone, CallDoneIf::Success) From 4c38f68d0fcaf3f064197bb166b54b9c2040cebe Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sat, 4 Nov 2023 12:57:23 +0100 Subject: [PATCH 0094/1546] TaskTree: Rename StopWithDone -> StopWithSuccess Make naming consistent with recent changes. "Done" is meant to be an event name when the task / group finishes. "Done" may finish with "Success" or an "Error". This addresses the 26th point in the task below. Task-number: QTCREATORBUG-28741 Change-Id: I53ed6905b1c385c398f49e122e8ca60aa3ad0806 Reviewed-by: Reviewed-by: hjk --- src/libs/solutions/tasking/barrier.h | 2 +- src/libs/solutions/tasking/tasktree.cpp | 36 +++++++++---------- src/libs/solutions/tasking/tasktree.h | 6 ++-- src/plugins/android/androidbuildapkstep.cpp | 4 +-- .../androidpackageinstallationstep.cpp | 2 +- src/plugins/autotest/testrunner.cpp | 4 +-- .../autotoolsprojectmanager/autogenstep.cpp | 2 +- .../autoreconfstep.cpp | 2 +- .../autotoolsprojectmanager/configurestep.cpp | 2 +- .../cmakeprojectmanager/cmakebuildstep.cpp | 2 +- src/plugins/coreplugin/actionsfilter.cpp | 2 +- .../coreplugin/locator/directoryfilter.cpp | 2 +- .../coreplugin/locator/ilocatorfilter.cpp | 4 +-- .../coreplugin/locator/javascriptfilter.cpp | 2 +- .../locator/spotlightlocatorfilter.cpp | 2 +- src/plugins/git/gitclient.cpp | 2 +- src/plugins/languageclient/locatorfilter.cpp | 2 +- .../python/pysidebuildconfiguration.cpp | 2 +- .../qmakeprojectmanager/qmakemakestep.cpp | 4 +-- src/plugins/qmakeprojectmanager/qmakestep.cpp | 4 +-- .../qnx/qnxdeployqtlibrariesdialog.cpp | 8 ++--- src/plugins/remotelinux/genericdeploystep.cpp | 2 +- .../remotelinux/genericdirectuploadstep.cpp | 6 ++-- src/plugins/remotelinux/killappstep.cpp | 2 +- .../remotelinux/tarpackagecreationstep.cpp | 2 +- .../remotelinux/tarpackagedeploystep.cpp | 2 +- src/plugins/subversion/subversionclient.cpp | 2 +- src/plugins/valgrind/valgrindprocess.cpp | 2 +- tests/auto/solutions/tasking/tst_tasking.cpp | 14 ++++---- 29 files changed, 64 insertions(+), 64 deletions(-) diff --git a/src/libs/solutions/tasking/barrier.h b/src/libs/solutions/tasking/barrier.h index 71081209f4d..3001916fb68 100644 --- a/src/libs/solutions/tasking/barrier.h +++ b/src/libs/solutions/tasking/barrier.h @@ -82,7 +82,7 @@ GroupItem waitForBarrierTask(const MultiBarrier &sharedBarrier) Barrier *activeSharedBarrier = activeBarrier->barrier(); const std::optional result = activeSharedBarrier->result(); if (result.has_value()) - return result.value() ? SetupResult::StopWithDone : SetupResult::StopWithError; + return result.value() ? SetupResult::StopWithSuccess : SetupResult::StopWithError; QObject::connect(activeSharedBarrier, &Barrier::done, &barrier, &Barrier::stopWithResult); return SetupResult::Continue; }); diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 0ea24db041f..dae251f6d00 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -417,7 +417,7 @@ private: const auto onFirstSetup = [input](ConcurrentCall &task) { if (input == "Skip") - return SetupResult::StopWithDone; // This task won't start, the next one will + return SetupResult::StopWithSuccess; // This task won't start, the next one will if (input == "Error") return SetupResult::StopWithError; // This task and the next one won't start task.setConcurrentCallData(parseAndLog, input); @@ -439,10 +439,10 @@ private: the return value of the handler instructs the running tree on how to proceed after the handler's invocation is finished. The default return value of SetupResult::Continue instructs the tree to continue running, i.e. to execute the associated \c Task. - The return value of SetupResult::StopWithDone or SetupResult::StopWithError instructs + The return value of SetupResult::StopWithSuccess or SetupResult::StopWithError instructs the tree to skip the task's execution and finish immediately with success or an error, respectively. - When the return type is either SetupResult::StopWithDone or SetupResult::StopWithError, + When the return type is either SetupResult::StopWithSuccess or SetupResult::StopWithError, the task's \a done or \a error handler (even if provided) are not called afterwards. The \a setup handler may be of a shortened form of std::function, @@ -647,7 +647,7 @@ private: Default. The group's or task's execution continues normally. When a group's or task's setup handler returns void, it's assumed that it returned Continue. - \value StopWithDone + \value StopWithSuccess The group's or task's execution stops immediately with success. When returned from the group's setup handler, all child tasks are skipped, and the group's onGroupDone() handler is invoked (if provided). @@ -675,15 +675,15 @@ private: The return value of the handler instructs the running group on how to proceed after the handler's invocation is finished. The default return value of SetupResult::Continue instructs the group to continue running, i.e. to start executing its child tasks. - The return value of SetupResult::StopWithDone or SetupResult::StopWithError + The return value of SetupResult::StopWithSuccess or SetupResult::StopWithError instructs the group to skip the child tasks' execution and finish immediately with success or an error, respectively. - When the return type is either SetupResult::StopWithDone + When the return type is either SetupResult::StopWithSuccess of SetupResult::StopWithError, the group's done or error handler (if provided) is called synchronously immediately afterwards. - \note Even if the group setup handler returns StopWithDone or StopWithError, + \note Even if the group setup handler returns StopWithSuccess or StopWithError, one of the group's done or error handlers is invoked. This behavior differs from that of task handlers and might change in the future. @@ -834,7 +834,7 @@ const GroupItem finishAllAndError = workflowPolicy(WorkflowPolicy::FinishAllAndE static SetupResult toSetupResult(bool success) { - return success ? SetupResult::StopWithDone : SetupResult::StopWithError; + return success ? SetupResult::StopWithSuccess : SetupResult::StopWithError; } bool TreeStorageBase::isValid() const @@ -1312,7 +1312,7 @@ SetupResult TaskContainer::start() if (startAction != SetupResult::Continue) { m_constData.m_taskTreePrivate->advanceProgress(m_constData.m_taskCount); // Non-Continue SetupResult takes precedence over the workflow policy. - m_runtimeData->m_successBit = startAction == SetupResult::StopWithDone; + m_runtimeData->m_successBit = startAction == SetupResult::StopWithSuccess; } } if (startAction == SetupResult::Continue) { @@ -1328,7 +1328,7 @@ SetupResult TaskContainer::continueStart(SetupResult startAction, int nextChild) : startAction; QTC_CHECK(isRunning()); // TODO: superfluous if (groupAction != SetupResult::Continue) { - const bool bit = m_runtimeData->updateSuccessBit(groupAction == SetupResult::StopWithDone); + const bool bit = m_runtimeData->updateSuccessBit(groupAction == SetupResult::StopWithSuccess); const bool result = invokeDoneHandler(bit ? DoneWith::Success : DoneWith::Error); if (TaskContainer *parentContainer = m_constData.m_parentContainer) { QTC_CHECK(parentContainer->isRunning()); @@ -1354,7 +1354,7 @@ SetupResult TaskContainer::startChildren(int nextChild) if (startAction == SetupResult::Continue) continue; - const SetupResult finalizeAction = childDone(startAction == SetupResult::StopWithDone); + const SetupResult finalizeAction = childDone(startAction == SetupResult::StopWithSuccess); if (finalizeAction == SetupResult::Continue) continue; @@ -1699,7 +1699,7 @@ bool TaskNode::invokeDoneHandler(DoneWith result) setup handler doesn't return SetupResult (that is, its return type is void). \row - \li StopWithDone + \li StopWithSuccess \li The task won't be started and it will report success to its parent. \row \li StopWithError @@ -1739,7 +1739,7 @@ bool TaskNode::invokeDoneHandler(DoneWith result) The error handler is also optional. When used, it must always be the third argument. You can omit the handlers or substitute the ones that you do not need with curly braces ({}). - \note If the task setup handler returns StopWithDone or StopWithError, + \note If the task setup handler returns StopWithSuccess or StopWithError, neither the done nor error handler is invoked. \section1 Group Handlers @@ -1773,7 +1773,7 @@ bool TaskNode::invokeDoneHandler(DoneWith result) whole group. If you do not specify a group start handler or its return type is void, the default group's action is SetupResult::Continue, so that all tasks are started normally. Otherwise, when the start handler returns - SetupResult::StopWithDone or SetupResult::StopWithError, the tasks are not + SetupResult::StopWithSuccess or SetupResult::StopWithError, the tasks are not started (they are skipped) and the group itself reports success or failure, depending on the returned value, respectively. @@ -1785,7 +1785,7 @@ bool TaskNode::invokeDoneHandler(DoneWith result) ProcessTask(...) // Process 1 }, Group { - onGroupSetup([] { qDebug() << "Group 2 setup"; return SetupResult::StopWithDone; }), + onGroupSetup([] { qDebug() << "Group 2 setup"; return SetupResult::StopWithSuccess; }), ProcessTask(...) // Process 2 }, Group { @@ -1823,7 +1823,7 @@ bool TaskNode::invokeDoneHandler(DoneWith result) \li \row \li Group 2 starts - \li Returns StopWithDone, so Process 2 is skipped and Group 2 reports + \li Returns StopWithSuccess, so Process 2 is skipped and Group 2 reports success. \row \li Group 2 finishes (success) @@ -1856,7 +1856,7 @@ bool TaskNode::invokeDoneHandler(DoneWith result) onGroupSetup([] { qDebug() << "Root setup"; }), ProcessTask(...), onGroupDone([] { qDebug() << "Root finished with success"; }), - onGroupError([] { qDebug() << "Root finished with error"; }) + onGroupError([] { qDebug() << "Root finished with an error"; }) }; \endcode @@ -1864,7 +1864,7 @@ bool TaskNode::invokeDoneHandler(DoneWith result) onGroupDone() or onGroupError() each to a group, an assert is triggered at runtime that includes an error message. - \note Even if the group setup handler returns StopWithDone or StopWithError, + \note Even if the group setup handler returns StopWithSuccess or StopWithError, one of the group's done or error handlers is invoked. This behavior differs from that of task handlers and might change in the future. diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 594663d0cc6..95fe3203901 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -127,7 +127,7 @@ Q_ENUM_NS(WorkflowPolicy); enum class SetupResult { Continue, - StopWithDone, + StopWithSuccess, StopWithError }; Q_ENUM_NS(SetupResult); @@ -352,10 +352,10 @@ private: static_assert(isBool || isVoid, "Sync element: The synchronous function has to return void or bool."); if constexpr (isBool) { - return onGroupSetup([function] { return function() ? SetupResult::StopWithDone + return onGroupSetup([function] { return function() ? SetupResult::StopWithSuccess : SetupResult::StopWithError; }); } - return onGroupSetup([function] { function(); return SetupResult::StopWithDone; }); + return onGroupSetup([function] { function(); return SetupResult::StopWithSuccess; }); }; }; diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index 1e8dfbc3fb0..b04ad7ad40d 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -814,12 +814,12 @@ Tasking::GroupItem AndroidBuildApkStep::runRecipe() if (m_skipBuilding) { reportWarningOrError(Tr::tr("Android deploy settings file not found, " "not building an APK."), Task::Error); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } if (AndroidManager::skipInstallationAndPackageSteps(target())) { reportWarningOrError(Tr::tr("Product type is not an application, not building an APK."), Task::Warning); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } if (setupHelper()) return SetupResult::Continue; diff --git a/src/plugins/android/androidpackageinstallationstep.cpp b/src/plugins/android/androidpackageinstallationstep.cpp index 7aea1208510..e5398654b84 100644 --- a/src/plugins/android/androidpackageinstallationstep.cpp +++ b/src/plugins/android/androidpackageinstallationstep.cpp @@ -128,7 +128,7 @@ Tasking::GroupItem AndroidPackageInstallationStep::runRecipe() if (AndroidManager::skipInstallationAndPackageSteps(target())) { reportWarningOrError(Tr::tr("Product type is not an application, not running the " "Make install step."), Task::Warning); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } for (const QString &dir : std::as_const(m_androidDirsToClean)) { diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index 4308316214c..3a19a972d0b 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -355,11 +355,11 @@ void TestRunner::runTestsHelper() const auto onSetup = [this, config] { if (!config->project()) - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; if (config->testExecutable().isEmpty()) { reportResult(ResultType::MessageFatal, Tr::tr("Executable path is empty. (%1)").arg(config->displayName())); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } return SetupResult::Continue; }; diff --git a/src/plugins/autotoolsprojectmanager/autogenstep.cpp b/src/plugins/autotoolsprojectmanager/autogenstep.cpp index 2c44a6bfeed..020a9ad96ce 100644 --- a/src/plugins/autotoolsprojectmanager/autogenstep.cpp +++ b/src/plugins/autotoolsprojectmanager/autogenstep.cpp @@ -90,7 +90,7 @@ Tasking::GroupItem AutogenStep::runRecipe() if (!m_runAutogen) { emit addOutput(Tr::tr("Configuration unchanged, skipping autogen step."), OutputFormat::NormalMessage); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } return SetupResult::Continue; }; diff --git a/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp b/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp index bea7767bf57..810272ecad3 100644 --- a/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp +++ b/src/plugins/autotoolsprojectmanager/autoreconfstep.cpp @@ -75,7 +75,7 @@ private: emit addOutput(::AutotoolsProjectManager::Tr::tr( "Configuration unchanged, skipping autoreconf step."), OutputFormat::NormalMessage); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } return SetupResult::Continue; }; diff --git a/src/plugins/autotoolsprojectmanager/configurestep.cpp b/src/plugins/autotoolsprojectmanager/configurestep.cpp index fe4f5a10f5d..97fdf3576e6 100644 --- a/src/plugins/autotoolsprojectmanager/configurestep.cpp +++ b/src/plugins/autotoolsprojectmanager/configurestep.cpp @@ -88,7 +88,7 @@ Tasking::GroupItem ConfigureStep::runRecipe() if (!m_runConfigure) { emit addOutput(Tr::tr("Configuration unchanged, skipping configure step."), OutputFormat::NormalMessage); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } ProcessParameters *param = processParameters(); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp index ba36aec1055..18b02a1be7a 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp @@ -360,7 +360,7 @@ GroupItem CMakeBuildStep::runRecipe() else if (bs->isWaitingForParse()) message = Tr::tr("Running CMake in preparation to build..."); else - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; emit addOutput(message, OutputFormat::NormalMessage); parseTarget = target(); return SetupResult::Continue; diff --git a/src/plugins/coreplugin/actionsfilter.cpp b/src/plugins/coreplugin/actionsfilter.cpp index 3b805f76f72..cc4939830ec 100644 --- a/src/plugins/coreplugin/actionsfilter.cpp +++ b/src/plugins/coreplugin/actionsfilter.cpp @@ -190,7 +190,7 @@ LocatorMatcherTasks ActionsFilter::matchers() collectEntriesForCommands(); if (storage->input().simplified().isEmpty()) { storage->reportOutput(m_entries); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); async.setConcurrentCallData(matches, *storage, m_entries); diff --git a/src/plugins/coreplugin/locator/directoryfilter.cpp b/src/plugins/coreplugin/locator/directoryfilter.cpp index b354f238558..8d0c3c85fd7 100644 --- a/src/plugins/coreplugin/locator/directoryfilter.cpp +++ b/src/plugins/coreplugin/locator/directoryfilter.cpp @@ -86,7 +86,7 @@ DirectoryFilter::DirectoryFilter(Id id) if (!m_directories.isEmpty()) return SetupResult::Continue; // Async task will run m_cache.setFilePaths({}); - return SetupResult::StopWithDone; // Group stops, skips async task + return SetupResult::StopWithSuccess; // Group stops, skips async task }; const auto onSetup = [this](Async &async) { async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.cpp b/src/plugins/coreplugin/locator/ilocatorfilter.cpp index 9cfc8fe24e0..f66dc0383f5 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/ilocatorfilter.cpp @@ -1488,10 +1488,10 @@ LocatorMatcherTask LocatorFileCache::matcher() const const auto onSetup = [storage, weak](Async &async) { auto that = weak.lock(); if (!that) // LocatorMatcher is running after *this LocatorFileCache was destructed. - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; if (!that->ensureValidated()) - return SetupResult::StopWithDone; // The cache is invalid and + return SetupResult::StopWithSuccess; // The cache is invalid and // no provider is set or it returned empty generator that->bumpExecutionId(); diff --git a/src/plugins/coreplugin/locator/javascriptfilter.cpp b/src/plugins/coreplugin/locator/javascriptfilter.cpp index 920ce605755..73c723e9888 100644 --- a/src/plugins/coreplugin/locator/javascriptfilter.cpp +++ b/src/plugins/coreplugin/locator/javascriptfilter.cpp @@ -385,7 +385,7 @@ LocatorMatcherTasks JavaScriptFilter::matchers() return AcceptResult(); }; storage->reportOutput({entry}); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } return SetupResult::Continue; }; diff --git a/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp b/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp index a7c18867ff9..c9f7e43d7da 100644 --- a/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp @@ -190,7 +190,7 @@ LocatorMatcherTasks SpotlightLocatorFilter::matchers() const Link link = Link::fromString(storage->input(), true); const FilePath input = link.targetFilePath; if (input.isEmpty()) - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; // only pass the file name part to allow searches like "somepath/*foo" const std::unique_ptr expander(createMacroExpander(input.fileName())); diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 9ed9fc8c0e7..fa67e79ec47 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -414,7 +414,7 @@ ShowController::ShowController(IDocument *document, const QString &id) const auto desciptionDetailsSetup = [storage] { if (!storage->m_postProcessDescription) - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; return SetupResult::Continue; }; diff --git a/src/plugins/languageclient/locatorfilter.cpp b/src/plugins/languageclient/locatorfilter.cpp index 82a390d4ece..2b4c73a263a 100644 --- a/src/plugins/languageclient/locatorfilter.cpp +++ b/src/plugins/languageclient/locatorfilter.cpp @@ -69,7 +69,7 @@ LocatorMatcherTask locatorMatcher(Client *client, int maxResultCount, const auto onFilterSetup = [storage, resultStorage, client, filter](Async &async) { const QList results = *resultStorage; if (results.isEmpty()) - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); async.setConcurrentCallData(filterResults, *storage, client, results, filter); return SetupResult::Continue; diff --git a/src/plugins/python/pysidebuildconfiguration.cpp b/src/plugins/python/pysidebuildconfiguration.cpp index 8525e248c4f..9aa87316562 100644 --- a/src/plugins/python/pysidebuildconfiguration.cpp +++ b/src/plugins/python/pysidebuildconfiguration.cpp @@ -65,7 +65,7 @@ Tasking::GroupItem PySideBuildStep::runRecipe() const auto onSetup = [this] { if (!processParameters()->effectiveCommand().isExecutableFile()) - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; return SetupResult::Continue; }; diff --git a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp index ef0ffbfac29..15f356700a4 100644 --- a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp @@ -206,7 +206,7 @@ Tasking::GroupItem QmakeMakeStep::runRecipe() const auto onSetup = [this] { if (m_scriptTarget || m_ignoredNonTopLevelBuild) - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; if (!m_makeFileToCheck.exists()) { const bool success = ignoreReturnValue(); @@ -214,7 +214,7 @@ Tasking::GroupItem QmakeMakeStep::runRecipe() emit addOutput(Tr::tr("Cannot find Makefile. Check your build settings."), OutputFormat::NormalMessage); } - return success ? SetupResult::StopWithDone : SetupResult::StopWithError; + return success ? SetupResult::StopWithSuccess : SetupResult::StopWithError; } return SetupResult::Continue; }; diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 2225ea5da80..632905961b4 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -267,12 +267,12 @@ Tasking::GroupItem QMakeStep::runRecipe() const auto onSetup = [this] { if (m_scriptTemplate) - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; if (m_needToRunQMake) return SetupResult::Continue; emit addOutput(Tr::tr("Configuration unchanged, skipping qmake step."), OutputFormat::NormalMessage); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; }; const auto onQMakeSetup = [this](Process &process) { diff --git a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp index b5d3b24d7be..c0f16c628ae 100644 --- a/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp +++ b/src/plugins/qnx/qnxdeployqtlibrariesdialog.cpp @@ -149,7 +149,7 @@ GroupItem QnxDeployQtLibrariesDialogPrivate::removeDirTask() { const auto onSetup = [this](Process &process) { if (m_checkResult != CheckResult::RemoveDir) - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; m_deployLogWindow->appendPlainText(Tr::tr("Removing \"%1\"").arg(fullRemoteDirectory())); process.setCommand({m_device->filePath("rm"), {"-rf", fullRemoteDirectory()}}); return SetupResult::Continue; @@ -167,7 +167,7 @@ GroupItem QnxDeployQtLibrariesDialogPrivate::uploadTask() const auto onSetup = [this](FileTransfer &transfer) { if (m_deployableFiles.isEmpty()) { emitProgressMessage(Tr::tr("No files need to be uploaded.")); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } emitProgressMessage(Tr::tr("%n file(s) need to be uploaded.", "", m_deployableFiles.size())); @@ -183,7 +183,7 @@ GroupItem QnxDeployQtLibrariesDialogPrivate::uploadTask() } if (files.isEmpty()) { emitProgressMessage(Tr::tr("No files need to be uploaded.")); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } transfer.setFilesToTransfer(files); QObject::connect(&transfer, &FileTransfer::progress, @@ -250,7 +250,7 @@ Group QnxDeployQtLibrariesDialogPrivate::deployRecipe() return SetupResult::Continue; emitProgressMessage(Tr::tr("No deployment action necessary. Skipping.")); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; }; const auto doneHandler = [this] { emitProgressMessage(Tr::tr("All files successfully deployed.")); diff --git a/src/plugins/remotelinux/genericdeploystep.cpp b/src/plugins/remotelinux/genericdeploystep.cpp index 4a14f6cdddf..71f5aaabff2 100644 --- a/src/plugins/remotelinux/genericdeploystep.cpp +++ b/src/plugins/remotelinux/genericdeploystep.cpp @@ -191,7 +191,7 @@ GroupItem GenericDeployStep::deployRecipe() } if (files.isEmpty()) { addSkipDeploymentMessage(); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } return SetupResult::Continue; }; diff --git a/src/plugins/remotelinux/genericdirectuploadstep.cpp b/src/plugins/remotelinux/genericdirectuploadstep.cpp index bfc2c67c2ff..de7f4703837 100644 --- a/src/plugins/remotelinux/genericdirectuploadstep.cpp +++ b/src/plugins/remotelinux/genericdirectuploadstep.cpp @@ -169,7 +169,7 @@ GroupItem GenericDirectUploadStep::uploadTask(const TreeStorage & const auto onSetup = [this, storage](FileTransfer &transfer) { if (storage->filesToUpload.isEmpty()) { addProgressMessage(Tr::tr("No files need to be uploaded.")); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } addProgressMessage(Tr::tr("%n file(s) need to be uploaded.", "", storage->filesToUpload.size())); @@ -190,7 +190,7 @@ GroupItem GenericDirectUploadStep::uploadTask(const TreeStorage & } if (files.isEmpty()) { addProgressMessage(Tr::tr("No files need to be uploaded.")); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } transfer.setFilesToTransfer(files); QObject::connect(&transfer, &FileTransfer::progress, @@ -254,7 +254,7 @@ GroupItem GenericDirectUploadStep::deployRecipe() QTC_CHECK(collected.size() >= deployableFiles.size()); if (collected.isEmpty()) { addSkipDeploymentMessage(); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } storage->deployableFiles = collected; return SetupResult::Continue; diff --git a/src/plugins/remotelinux/killappstep.cpp b/src/plugins/remotelinux/killappstep.cpp index 0ccfe3ee743..0f8df90df52 100644 --- a/src/plugins/remotelinux/killappstep.cpp +++ b/src/plugins/remotelinux/killappstep.cpp @@ -48,7 +48,7 @@ GroupItem KillAppStep::deployRecipe() const auto onSetup = [this](DeviceProcessKiller &killer) { if (m_remoteExecutable.isEmpty()) { addSkipDeploymentMessage(); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } killer.setProcessPath(m_remoteExecutable); addProgressMessage(Tr::tr("Trying to kill \"%1\" on remote device...") diff --git a/src/plugins/remotelinux/tarpackagecreationstep.cpp b/src/plugins/remotelinux/tarpackagecreationstep.cpp index 52920b3ebc7..2589c22b238 100644 --- a/src/plugins/remotelinux/tarpackagecreationstep.cpp +++ b/src/plugins/remotelinux/tarpackagecreationstep.cpp @@ -145,7 +145,7 @@ Tasking::GroupItem TarPackageCreationStep::runRecipe() if (!m_packagingNeeded) { emit addOutput(Tr::tr("Tarball up to date, skipping packaging."), OutputFormat::NormalMessage); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; } async.setConcurrentCallData(&TarPackageCreationStep::doPackage, this, diff --git a/src/plugins/remotelinux/tarpackagedeploystep.cpp b/src/plugins/remotelinux/tarpackagedeploystep.cpp index 957cce45104..7eff5c55314 100644 --- a/src/plugins/remotelinux/tarpackagedeploystep.cpp +++ b/src/plugins/remotelinux/tarpackagedeploystep.cpp @@ -115,7 +115,7 @@ GroupItem TarPackageDeployStep::deployRecipe() if (hasLocalFileChanged(DeployableFile(m_packageFilePath, {}))) return SetupResult::Continue; addSkipDeploymentMessage(); - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; }; return Group { onGroupSetup(onSetup), uploadTask(), installTask() }; } diff --git a/src/plugins/subversion/subversionclient.cpp b/src/plugins/subversion/subversionclient.cpp index fbe19892160..721158f2cc0 100644 --- a/src/plugins/subversion/subversionclient.cpp +++ b/src/plugins/subversion/subversionclient.cpp @@ -167,7 +167,7 @@ SubversionDiffEditorController::SubversionDiffEditorController(IDocument *docume const auto onDescriptionSetup = [this](Process &process) { if (m_changeNumber == 0) - return SetupResult::StopWithDone; + return SetupResult::StopWithSuccess; setupCommand(process, {"log", "-r", QString::number(m_changeNumber)}); CommandLine command = process.commandLine(); command << SubversionClient::AddAuthOptions(); diff --git a/src/plugins/valgrind/valgrindprocess.cpp b/src/plugins/valgrind/valgrindprocess.cpp index d8581f94d92..e4178f84397 100644 --- a/src/plugins/valgrind/valgrindprocess.cpp +++ b/src/plugins/valgrind/valgrindprocess.cpp @@ -181,7 +181,7 @@ Group ValgrindProcessPrivate::runRecipe() const }; const auto onParserGroupSetup = [this] { - return m_localServerAddress.isNull() ? SetupResult::StopWithDone : SetupResult::Continue; + return m_localServerAddress.isNull() ? SetupResult::StopWithSuccess : SetupResult::Continue; }; const auto onParserSetup = [this, storage](Parser &parser) { diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index 9f8035182e7..ed10565092b 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -305,7 +305,7 @@ void tst_Tasking::testTree_data() }; const Group root3 { Storage(storage), - onGroupSetup([] { return SetupResult::StopWithDone; }), + onGroupSetup([] { return SetupResult::StopWithSuccess; }), groupDone(0) }; const Group root4 { @@ -334,7 +334,7 @@ void tst_Tasking::testTree_data() }; const auto doneData = [storage, setupGroup](WorkflowPolicy policy) { - return TestData{storage, setupGroup(SetupResult::StopWithDone, policy), + return TestData{storage, setupGroup(SetupResult::StopWithSuccess, policy), Log{{0, Handler::GroupSuccess}}, 0, OnDone::Success}; }; const auto errorData = [storage, setupGroup](WorkflowPolicy policy) { @@ -362,8 +362,8 @@ void tst_Tasking::testTree_data() { const Group root { Storage(storage), - createDynamicTask(1, SetupResult::StopWithDone), - createDynamicTask(2, SetupResult::StopWithDone) + createDynamicTask(1, SetupResult::StopWithSuccess), + createDynamicTask(2, SetupResult::StopWithSuccess) }; const Log log {{1, Handler::Setup}, {2, Handler::Setup}}; QTest::newRow("DynamicTaskDone") << TestData{storage, root, log, 2, OnDone::Success}; @@ -1288,7 +1288,7 @@ void tst_Tasking::testTree_data() }; }; - const Group root1 = createRoot(SetupResult::StopWithDone); + const Group root1 = createRoot(SetupResult::StopWithSuccess); const Log log1 { {1, Handler::Setup}, {1, Handler::Success}, @@ -1371,7 +1371,7 @@ void tst_Tasking::testTree_data() }, Group { groupSetup(3), - createDynamicTask(3, SetupResult::StopWithDone) + createDynamicTask(3, SetupResult::StopWithSuccess) }, Group { groupSetup(4), @@ -1596,7 +1596,7 @@ void tst_Tasking::testTree_data() }, Group { groupSetup(3), - Group { createDynamicTask(3, SetupResult::StopWithDone) } + Group { createDynamicTask(3, SetupResult::StopWithSuccess) } }, Group { groupSetup(4), From 8fe1899c25e3f1c7de66c95170cdef42690b3860 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sat, 4 Nov 2023 17:52:18 +0100 Subject: [PATCH 0095/1546] TaskTree: Unify static assertions for all handlers Introduce GroupItem::isInvocable() helper. Add more compile tests. Task-number: QTCREATORBUG-29834 Change-Id: I444efeda77d1fa584567403224595b821f2a2d43 Reviewed-by: Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.h | 154 +++++++++---------- tests/auto/solutions/tasking/tst_tasking.cpp | 91 +++++++++-- 2 files changed, 150 insertions(+), 95 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 95fe3203901..fcc5df34392 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -214,6 +214,17 @@ protected: static GroupItem withTimeout(const GroupItem &item, std::chrono::milliseconds timeout, const std::function &handler = {}); + // Checks if Function may be invoked with Args and if Function's return type is Result. + template > + static constexpr bool isInvocable() + { + // Note, that std::is_invocable_r_v doesn't check Result type properly. + if constexpr (std::is_invocable_r_v) + return std::is_same_v>; + return false; + } + private: Type m_type = Type::Group; QList m_children; @@ -254,40 +265,33 @@ public: } private: - template + template static GroupSetupHandler wrapGroupSetup(Handler &&handler) { - static constexpr bool isDynamic - = std::is_same_v>>; - constexpr bool isVoid - = std::is_same_v>>; - static_assert(isDynamic || isVoid, - "Group setup handler needs to take no arguments and has to return " - "void or SetupResult. The passed handler doesn't fulfill these requirements."); + // S, V stands for: [S]etupResult, [V]oid + static constexpr bool isS = isInvocable(); + static constexpr bool isV = isInvocable(); + static_assert(isS || isV, + "Group setup handler needs to take no arguments and has to return void or SetupResult. " + "The passed handler doesn't fulfill these requirements."); return [=] { - if constexpr (isDynamic) + if constexpr (isS) return std::invoke(handler); std::invoke(handler); return SetupResult::Continue; }; }; - template + template static GroupDoneHandler wrapGroupDone(Handler &&handler) { - static constexpr bool isBD // stands for [B]ool, [D]oneWith - = std::is_invocable_r_v, DoneWith>; - static constexpr bool isB - = std::is_invocable_r_v>; - static constexpr bool isVD // stands for [V]oid, [D]oneWith - = std::is_invocable_r_v, DoneWith>; - static constexpr bool isV - = std::is_invocable_r_v>; - static constexpr bool isInvocable = isBD || isB || isVD || isV; - - static_assert(isInvocable, - "Group done handler needs to take (DoneWith) or (void) " - "as arguments and has to return void or bool. " - "The passed handler doesn't fulfill these requirements."); + // B, V, D stands for: [B]ool, [V]oid, [D]oneWith + static constexpr bool isBD = isInvocable(); + static constexpr bool isB = isInvocable(); + static constexpr bool isVD = isInvocable(); + static constexpr bool isV = isInvocable(); + static_assert(isBD || isB || isVD || isV, + "Group done handler needs to take (DoneWith) or (void) as an argument and has to " + "return void or bool. The passed handler doesn't fulfill these requirements."); return [=](DoneWith result) { if constexpr (isBD) return std::invoke(handler, result); @@ -338,24 +342,28 @@ public: class TASKING_EXPORT Sync final : public GroupItem { public: - template - Sync(Function &&function) { addChildren({init(std::forward(function))}); } + template + Sync(Handler &&handler) { + addChildren({ onGroupSetup(wrapHandler(std::forward(handler))) }); + } private: - template - static GroupItem init(Function &&function) { - constexpr bool isInvocable = std::is_invocable_v>; - static_assert(isInvocable, - "Sync element: The synchronous function can't take any arguments."); - constexpr bool isBool = std::is_same_v>>; - constexpr bool isVoid = std::is_same_v>>; - static_assert(isBool || isVoid, - "Sync element: The synchronous function has to return void or bool."); - if constexpr (isBool) { - return onGroupSetup([function] { return function() ? SetupResult::StopWithSuccess - : SetupResult::StopWithError; }); - } - return onGroupSetup([function] { function(); return SetupResult::StopWithSuccess; }); + template + static GroupSetupHandler wrapHandler(Handler &&handler) { + // B, V stands for: [B]ool, [V]oid + static constexpr bool isB = isInvocable(); + static constexpr bool isV = isInvocable(); + static_assert(isB || isV, + "Sync handler needs to take no arguments and has to return void or bool. " + "The passed handler doesn't fulfill these requirements."); + return [=] { + if constexpr (isB) { + return std::invoke(handler) ? SetupResult::StopWithSuccess + : SetupResult::StopWithError; + } + std::invoke(handler); + return SetupResult::StopWithSuccess; + }; }; }; @@ -401,49 +409,39 @@ public: } private: - template + template static GroupItem::TaskSetupHandler wrapSetup(Handler &&handler) { if constexpr (std::is_same_v) return {}; // When user passed {} for the setup handler. - static constexpr bool isDynamic - = std::is_same_v, Task &>>; - constexpr bool isVoid - = std::is_same_v, Task &>>; - static_assert(isDynamic || isVoid, - "Task setup handler needs to take (Task &) as an argument and has to return " - "void or SetupResult. The passed handler doesn't fulfill these requirements."); + // S, V stands for: [S]etupResult, [V]oid + static constexpr bool isS = isInvocable(); + static constexpr bool isV = isInvocable(); + static_assert(isS || isV, + "Task setup handler needs to take (Task &) as an argument and has to return void or " + "SetupResult. The passed handler doesn't fulfill these requirements."); return [=](TaskInterface &taskInterface) { Adapter &adapter = static_cast(taskInterface); - if constexpr (isDynamic) + if constexpr (isS) return std::invoke(handler, *adapter.task()); std::invoke(handler, *adapter.task()); return SetupResult::Continue; }; }; - template + template static GroupItem::TaskDoneHandler wrapDone(Handler &&handler) { if constexpr (std::is_same_v) return {}; // When user passed {} for the done handler. - static constexpr bool isBTD // stands for [B]ool, [T]ask, [D]oneWith - = std::is_invocable_r_v, const Task &, DoneWith>; - static constexpr bool isBT - = std::is_invocable_r_v, const Task &>; - static constexpr bool isBD - = std::is_invocable_r_v, DoneWith>; - static constexpr bool isB - = std::is_invocable_r_v>; - static constexpr bool isVTD // stands for [V]oid, [T]ask, [D]oneWith - = std::is_invocable_r_v, const Task &, DoneWith>; - static constexpr bool isVT - = std::is_invocable_r_v, const Task &>; - static constexpr bool isVD - = std::is_invocable_r_v, DoneWith>; - static constexpr bool isV - = std::is_invocable_r_v>; - static constexpr bool isInvocable = isBTD || isBT || isBD || isB - || isVTD || isVT || isVD || isV; - static_assert(isInvocable, + // B, V, T, D stands for: [B]ool, [V]oid, [T]ask, [D]oneWith + static constexpr bool isBTD = isInvocable(); + static constexpr bool isBT = isInvocable(); + static constexpr bool isBD = isInvocable(); + static constexpr bool isB = isInvocable(); + static constexpr bool isVTD = isInvocable(); + static constexpr bool isVT = isInvocable(); + static constexpr bool isVD = isInvocable(); + static constexpr bool isV = isInvocable(); + static_assert(isBTD || isBT || isBD || isB || isVTD || isVT || isVD || isV, "Task done handler needs to take (const Task &, DoneWith), (const Task &), " "(DoneWith) or (void) as arguments and has to return void or bool. " "The passed handler doesn't fulfill these requirements."); @@ -503,23 +501,19 @@ public: template void onStorageSetup(const TreeStorage &storage, StorageHandler &&handler) { - constexpr bool isInvocable = std::is_invocable_v, - StorageStruct &>; - static_assert(isInvocable, + static_assert(std::is_invocable_v, StorageStruct &>, "Storage setup handler needs to take (Storage &) as an argument. " - "The passed handler doesn't fulfill these requirements."); + "The passed handler doesn't fulfill this requirement."); setupStorageHandler(storage, wrapHandler(std::forward(handler)), {}); } template void onStorageDone(const TreeStorage &storage, StorageHandler &&handler) { - constexpr bool isInvocable = std::is_invocable_v, - const StorageStruct &>; - static_assert(isInvocable, + static_assert(std::is_invocable_v, const StorageStruct &>, "Storage done handler needs to take (const Storage &) as an argument. " - "The passed handler doesn't fulfill these requirements."); - setupStorageHandler(storage, - {}, wrapHandler(std::forward(handler))); + "The passed handler doesn't fulfill this requirement."); + setupStorageHandler(storage, {}, + wrapHandler(std::forward(handler))); } signals: @@ -536,7 +530,7 @@ private: template StorageVoidHandler wrapHandler(StorageHandler &&handler) { return [=](void *voidStruct) { - StorageStruct *storageStruct = static_cast(voidStruct); + auto *storageStruct = static_cast(voidStruct); std::invoke(handler, *storageStruct); }; } diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index ed10565092b..67442fde1bd 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -139,28 +139,89 @@ void tst_Tasking::validConstructs() // When turning each of below blocks on, you should see the specific compiler error message. + // Sync handler needs to take no arguments and has to return void or bool. #if 0 - { - // "Sync element: The synchronous function has to return void or bool." - const auto setupSync = [] { return 3; }; - const Sync sync(setupSync); - } + Sync([] { return 7; }); +#endif +#if 0 + Sync([](int) { }); +#endif +#if 0 + Sync([](int) { return true; }); #endif + // Group setup handler needs to take no arguments and has to return void or SetupResult. #if 0 - { - // "Sync element: The synchronous function can't take any arguments." - const auto setupSync = [](int) { }; - const Sync sync(setupSync); - } + onGroupSetup([] { return 7; }); +#endif +#if 0 + onGroupSetup([](int) { }); #endif + // Group done handler needs to take (DoneWith) or (void) as an argument and has to + // return void or bool. #if 0 - { - // "Sync element: The synchronous function can't take any arguments." - const auto setupSync = [](int) { return true; }; - const Sync sync(setupSync); - } + onGroupDone([] { return 7; }); +#endif +#if 0 + onGroupDone([](DoneWith) { return 7; }); +#endif +#if 0 + onGroupDone([](int) { }); +#endif +#if 0 + onGroupDone([](DoneWith, int) { }); +#endif + + // Task setup handler needs to take (Task &) as an argument and has to return void or + // SetupResult. +#if 0 + TestTask([] {}); +#endif +#if 0 + TestTask([] { return 7; }); +#endif +#if 0 + TestTask([](TaskObject &) { return 7; }); +#endif +#if 0 + TestTask([](TaskObject &, int) { return SetupResult::Continue; }); +#endif + + // Task done handler needs to take (const Task &, DoneWith), (const Task &), + // (DoneWith) or (void) as arguments and has to return void or bool. +#if 0 + TestTask({}, [](const TaskObject &, DoneWith) { return 7; }); +#endif +#if 0 + TestTask({}, [](const TaskObject &) { return 7; }); +#endif +#if 0 + TestTask({}, [] { return 7; }); +#endif +#if 0 + TestTask({}, [](const TaskObject &, DoneWith, int) {}); +#endif +#if 0 + TestTask({}, [](const TaskObject &, int) {}); +#endif +#if 0 + TestTask({}, [](DoneWith, int) {}); +#endif +#if 0 + TestTask({}, [](int) {}); +#endif +#if 0 + TestTask({}, [](const TaskObject &, DoneWith, int) { return true; }); +#endif +#if 0 + TestTask({}, [](const TaskObject &, int) { return true; }); +#endif +#if 0 + TestTask({}, [](DoneWith, int) { return true; }); +#endif +#if 0 + TestTask({}, [](int) { return true; }); #endif } From c4070da464d10d787f344dce713f944da4a9c328 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sat, 4 Nov 2023 21:46:10 +0100 Subject: [PATCH 0096/1546] TaskTree tests: Add tests for tweaking setup and done results Task-number: QTCREATORBUG-29834 Change-Id: Ie1fcef1be874661aa2196566eaf98d7d6da4f678 Reviewed-by: hjk --- tests/auto/solutions/tasking/tst_tasking.cpp | 355 ++++++++++++++----- 1 file changed, 266 insertions(+), 89 deletions(-) diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index 67442fde1bd..ae0b3d63329 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -17,6 +17,12 @@ namespace PrintableEnums { Q_NAMESPACE +// TODO: Is it possible to check for synchronous invocation of subsequent events, so that +// we may be sure that the control didn't went back to the main event loop between 2 events? +// In theory: yes! We can add a signal / handler to the task tree sent before / after +// receiving done signal from each task! +// TODO: Check if the TaskTree's main guard isn't locked when receiving done signal from each task. + enum class Handler { Setup, Success, @@ -26,6 +32,11 @@ enum class Handler { GroupSuccess, GroupError, GroupCanceled, + TweakSetupToSuccess, + TweakSetupToError, + TweakSetupToContinue, + TweakDoneToSuccess, + TweakDoneToError, Sync, BarrierAdvance, Timeout @@ -284,6 +295,21 @@ static Handler resultToGroupHandler(DoneWith result) return Handler::GroupCanceled; } +static Handler setupToTweakHandler(SetupResult result) +{ + switch (result) { + case SetupResult::Continue : return Handler::TweakSetupToContinue; + case SetupResult::StopWithSuccess : return Handler::TweakSetupToSuccess; + case SetupResult::StopWithError : return Handler::TweakSetupToError; + } + return Handler::TweakSetupToContinue; +} + +static Handler doneToTweakHandler(bool result) +{ + return result ? Handler::TweakDoneToSuccess : Handler::TweakDoneToError; +} + void tst_Tasking::testTree_data() { QTest::addColumn("testData"); @@ -297,19 +323,20 @@ void tst_Tasking::testTree_data() }; }; - const auto setupDynamicTask = [storage](int taskId, SetupResult action) { - return [storage, taskId, action](TaskObject &) { + const auto setupTaskWithTweak = [storage](int taskId, SetupResult desiredResult) { + return [storage, taskId, desiredResult](TaskObject &) { storage->m_log.append({taskId, Handler::Setup}); - return action; + storage->m_log.append({taskId, setupToTweakHandler(desiredResult)}); + return desiredResult; }; }; - const auto setupDone = [storage](int taskId, bool success = true) { - return [storage, taskId, success](DoneWith result) { + const auto setupDone = [storage](int taskId, bool desiredResult = true) { + return [storage, taskId, desiredResult](DoneWith result) { const Handler handler = result == DoneWith::Cancel ? Handler::Canceled - : success ? Handler::Success : Handler::Error; + : desiredResult ? Handler::Success : Handler::Error; storage->m_log.append({taskId, handler}); - return success && result != DoneWith::Cancel; + return desiredResult && result != DoneWith::Cancel; }; }; @@ -332,9 +359,9 @@ void tst_Tasking::testTree_data() return createTask(taskId, false, timeout); }; - const auto createDynamicTask = [storage, setupDynamicTask, setupDone](int taskId, - SetupResult action) { - return TestTask(setupDynamicTask(taskId, action), setupDone(taskId)); + const auto createTaskWithSetupTweak = [storage, setupTaskWithTweak, setupDone]( + int taskId, SetupResult desiredResult) { + return TestTask(setupTaskWithTweak(taskId, desiredResult), setupDone(taskId)); }; const auto groupSetup = [storage](int taskId) { @@ -347,11 +374,29 @@ void tst_Tasking::testTree_data() storage->m_log.append({taskId, resultToGroupHandler(result)}); }); }; - const auto createSync = [storage](int taskId) { - return Sync([=] { storage->m_log.append({taskId, Handler::Sync}); }); + const auto groupSetupWithTweak = [storage](int taskId, SetupResult desiredResult) { + return onGroupSetup([storage, taskId, desiredResult] { + storage->m_log.append({taskId, Handler::GroupSetup}); + storage->m_log.append({taskId, setupToTweakHandler(desiredResult)}); + return desiredResult; + }); }; - const auto createSyncWithReturn = [storage](int taskId, bool success) { - return Sync([=] { storage->m_log.append({taskId, Handler::Sync}); return success; }); + const auto groupDoneWithTweak = [storage](int taskId, bool desiredResult) { + return onGroupDone([storage, taskId, desiredResult](DoneWith result) { + storage->m_log.append({taskId, resultToGroupHandler(result)}); + storage->m_log.append({taskId, doneToTweakHandler(desiredResult)}); + return desiredResult; + }); + }; + const auto createSync = [storage](int taskId) { + return Sync([storage, taskId] { storage->m_log.append({taskId, Handler::Sync}); }); + }; + const auto createSyncWithTweak = [storage](int taskId, bool desiredResult) { + return Sync([storage, taskId, desiredResult] { + storage->m_log.append({taskId, Handler::Sync}); + storage->m_log.append({taskId, doneToTweakHandler(desiredResult)}); + return desiredResult; + }); }; { @@ -423,104 +468,121 @@ void tst_Tasking::testTree_data() { const Group root { Storage(storage), - createDynamicTask(1, SetupResult::StopWithSuccess), - createDynamicTask(2, SetupResult::StopWithSuccess) - }; - const Log log {{1, Handler::Setup}, {2, Handler::Setup}}; - QTest::newRow("DynamicTaskDone") << TestData{storage, root, log, 2, OnDone::Success}; - } - - { - const Group root { - Storage(storage), - createDynamicTask(1, SetupResult::StopWithError), - createDynamicTask(2, SetupResult::StopWithError) - }; - const Log log {{1, Handler::Setup}}; - QTest::newRow("DynamicTaskError") << TestData{storage, root, log, 2, OnDone::Failure}; - } - - { - const Group root { - Storage(storage), - createDynamicTask(1, SetupResult::Continue), - createDynamicTask(2, SetupResult::Continue), - createDynamicTask(3, SetupResult::StopWithError), - createDynamicTask(4, SetupResult::Continue) + createTaskWithSetupTweak(1, SetupResult::StopWithSuccess), + createTaskWithSetupTweak(2, SetupResult::StopWithSuccess) }; const Log log { {1, Handler::Setup}, + {1, Handler::TweakSetupToSuccess}, + {2, Handler::Setup}, + {2, Handler::TweakSetupToSuccess} + }; + QTest::newRow("TweekTaskSuccess") << TestData{storage, root, log, 2, OnDone::Success}; + } + + { + const Group root { + Storage(storage), + createTaskWithSetupTweak(1, SetupResult::StopWithError), + createTaskWithSetupTweak(2, SetupResult::StopWithError) + }; + const Log log { + {1, Handler::Setup}, + {1, Handler::TweakSetupToError} + }; + QTest::newRow("TweekTaskError") << TestData{storage, root, log, 2, OnDone::Failure}; + } + + { + const Group root { + Storage(storage), + createTaskWithSetupTweak(1, SetupResult::Continue), + createTaskWithSetupTweak(2, SetupResult::Continue), + createTaskWithSetupTweak(3, SetupResult::StopWithError), + createTaskWithSetupTweak(4, SetupResult::Continue) + }; + const Log log { + {1, Handler::Setup}, + {1, Handler::TweakSetupToContinue}, {1, Handler::Success}, {2, Handler::Setup}, + {2, Handler::TweakSetupToContinue}, {2, Handler::Success}, - {3, Handler::Setup} + {3, Handler::Setup}, + {3, Handler::TweakSetupToError} }; - QTest::newRow("DynamicMixed") << TestData{storage, root, log, 4, OnDone::Failure}; + QTest::newRow("TweekMixed") << TestData{storage, root, log, 4, OnDone::Failure}; } { const Group root { parallel, Storage(storage), - createDynamicTask(1, SetupResult::Continue), - createDynamicTask(2, SetupResult::Continue), - createDynamicTask(3, SetupResult::StopWithError), - createDynamicTask(4, SetupResult::Continue) + createTaskWithSetupTweak(1, SetupResult::Continue), + createTaskWithSetupTweak(2, SetupResult::Continue), + createTaskWithSetupTweak(3, SetupResult::StopWithError), + createTaskWithSetupTweak(4, SetupResult::Continue) }; const Log log { {1, Handler::Setup}, + {1, Handler::TweakSetupToContinue}, {2, Handler::Setup}, + {2, Handler::TweakSetupToContinue}, {3, Handler::Setup}, + {3, Handler::TweakSetupToError}, {1, Handler::Canceled}, {2, Handler::Canceled} }; - QTest::newRow("DynamicParallel") << TestData{storage, root, log, 4, OnDone::Failure}; + QTest::newRow("TweekParallel") << TestData{storage, root, log, 4, OnDone::Failure}; } { const Group root { parallel, Storage(storage), - createDynamicTask(1, SetupResult::Continue), - createDynamicTask(2, SetupResult::Continue), + createTaskWithSetupTweak(1, SetupResult::Continue), + createTaskWithSetupTweak(2, SetupResult::Continue), Group { - createDynamicTask(3, SetupResult::StopWithError) + createTaskWithSetupTweak(3, SetupResult::StopWithError) }, - createDynamicTask(4, SetupResult::Continue) + createTaskWithSetupTweak(4, SetupResult::Continue) }; const Log log { {1, Handler::Setup}, + {1, Handler::TweakSetupToContinue}, {2, Handler::Setup}, + {2, Handler::TweakSetupToContinue}, {3, Handler::Setup}, + {3, Handler::TweakSetupToError}, {1, Handler::Canceled}, {2, Handler::Canceled} }; - QTest::newRow("DynamicParallelGroup") << TestData{storage, root, log, 4, OnDone::Failure}; + QTest::newRow("TweekParallelGroup") << TestData{storage, root, log, 4, OnDone::Failure}; } { const Group root { parallel, Storage(storage), - createDynamicTask(1, SetupResult::Continue), - createDynamicTask(2, SetupResult::Continue), + createTaskWithSetupTweak(1, SetupResult::Continue), + createTaskWithSetupTweak(2, SetupResult::Continue), Group { - onGroupSetup([storage] { - storage->m_log.append({0, Handler::GroupSetup}); - return SetupResult::StopWithError; - }), - createDynamicTask(3, SetupResult::Continue) + groupSetupWithTweak(0, SetupResult::StopWithError), + createTaskWithSetupTweak(3, SetupResult::Continue) }, - createDynamicTask(4, SetupResult::Continue) + createTaskWithSetupTweak(4, SetupResult::Continue) }; const Log log { {1, Handler::Setup}, + {1, Handler::TweakSetupToContinue}, {2, Handler::Setup}, + {2, Handler::TweakSetupToContinue}, {0, Handler::GroupSetup}, + {0, Handler::TweakSetupToError}, {1, Handler::Canceled}, {2, Handler::Canceled} }; - QTest::newRow("DynamicParallelGroupSetup") + QTest::newRow("TweekParallelGroupSetup") << TestData{storage, root, log, 4, OnDone::Failure}; } @@ -1333,17 +1395,117 @@ void tst_Tasking::testTree_data() } { - const auto createRoot = [storage, createSuccessTask, groupDone](SetupResult setupResult) { + // This test checks whether group setup handler's result is properly dispatched. + const auto createRoot = [storage, createSuccessTask, groupDone, groupSetupWithTweak]( + SetupResult desiredResult) { return Group { Storage(storage), Group { + groupSetupWithTweak(1, desiredResult), createSuccessTask(1) }, + groupDone(0) + }; + }; + + const Group root1 = createRoot(SetupResult::StopWithSuccess); + const Log log1 { + {1, Handler::GroupSetup}, + {1, Handler::TweakSetupToSuccess}, + {0, Handler::GroupSuccess} + }; + QTest::newRow("GroupSetupTweakToSuccess") + << TestData{storage, root1, log1, 1, OnDone::Success}; + + const Group root2 = createRoot(SetupResult::StopWithError); + const Log log2 { + {1, Handler::GroupSetup}, + {1, Handler::TweakSetupToError}, + {0, Handler::GroupError} + }; + QTest::newRow("GroupSetupTweakToError") + << TestData{storage, root2, log2, 1, OnDone::Failure}; + + const Group root3 = createRoot(SetupResult::Continue); + const Log log3 { + {1, Handler::GroupSetup}, + {1, Handler::TweakSetupToContinue}, + {1, Handler::Setup}, + {1, Handler::Success}, + {0, Handler::GroupSuccess} + }; + QTest::newRow("GroupSetupTweakToContinue") + << TestData{storage, root3, log3, 1, OnDone::Success}; + } + + { + // This test checks whether group done handler's result is properly dispatched. + const auto createRoot = [storage, createTask, groupDone, groupDoneWithTweak]( + bool successTask, bool desiredResult) { + return Group { + Storage(storage), Group { - onGroupSetup([=] { return setupResult; }), - createSuccessTask(2), - createSuccessTask(3), - createSuccessTask(4) + createTask(1, successTask), + groupDoneWithTweak(1, desiredResult) + }, + groupDone(0) + }; + }; + + const Group root1 = createRoot(true, true); + const Log log1 { + {1, Handler::Setup}, + {1, Handler::Success}, + {1, Handler::GroupSuccess}, + {1, Handler::TweakDoneToSuccess}, + {0, Handler::GroupSuccess} + }; + QTest::newRow("GroupDoneWithSuccessTweakToSuccess") + << TestData{storage, root1, log1, 1, OnDone::Success}; + + const Group root2 = createRoot(true, false); + const Log log2 { + {1, Handler::Setup}, + {1, Handler::Success}, + {1, Handler::GroupSuccess}, + {1, Handler::TweakDoneToError}, + {0, Handler::GroupError} + }; + QTest::newRow("GroupDoneWithSuccessTweakToError") + << TestData{storage, root2, log2, 1, OnDone::Failure}; + + const Group root3 = createRoot(false, true); + const Log log3 { + {1, Handler::Setup}, + {1, Handler::Error}, + {1, Handler::GroupError}, + {1, Handler::TweakDoneToSuccess}, + {0, Handler::GroupSuccess} + }; + QTest::newRow("GroupDoneWithErrorTweakToSuccess") + << TestData{storage, root3, log3, 1, OnDone::Success}; + + const Group root4 = createRoot(false, false); + const Log log4 { + {1, Handler::Setup}, + {1, Handler::Error}, + {1, Handler::GroupError}, + {1, Handler::TweakDoneToError}, + {0, Handler::GroupError} + }; + QTest::newRow("GroupDoneWithErrorTweakToError") + << TestData{storage, root4, log4, 1, OnDone::Failure}; + } + + { + // This test checks whether task setup handler's result is properly dispatched. + const auto createRoot = [storage, createSuccessTask, groupDone, createTaskWithSetupTweak]( + SetupResult desiredResult) { + return Group { + Storage(storage), + Group { + createTaskWithSetupTweak(1, desiredResult), + createSuccessTask(2) }, groupDone(0) }; @@ -1352,32 +1514,34 @@ void tst_Tasking::testTree_data() const Group root1 = createRoot(SetupResult::StopWithSuccess); const Log log1 { {1, Handler::Setup}, - {1, Handler::Success}, + {1, Handler::TweakSetupToSuccess}, + {2, Handler::Setup}, + {2, Handler::Success}, {0, Handler::GroupSuccess} }; - QTest::newRow("DynamicSetupDone") << TestData{storage, root1, log1, 4, OnDone::Success}; + QTest::newRow("TaskSetupTweakToSuccess") + << TestData{storage, root1, log1, 2, OnDone::Success}; const Group root2 = createRoot(SetupResult::StopWithError); const Log log2 { {1, Handler::Setup}, - {1, Handler::Success}, + {1, Handler::TweakSetupToError}, {0, Handler::GroupError} }; - QTest::newRow("DynamicSetupError") << TestData{storage, root2, log2, 4, OnDone::Failure}; + QTest::newRow("TaskSetupTweakToError") + << TestData{storage, root2, log2, 2, OnDone::Failure}; const Group root3 = createRoot(SetupResult::Continue); const Log log3 { {1, Handler::Setup}, + {1, Handler::TweakSetupToContinue}, {1, Handler::Success}, {2, Handler::Setup}, {2, Handler::Success}, - {3, Handler::Setup}, - {3, Handler::Success}, - {4, Handler::Setup}, - {4, Handler::Success}, {0, Handler::GroupSuccess} }; - QTest::newRow("DynamicSetupContinue") << TestData{storage, root3, log3, 4, OnDone::Success}; + QTest::newRow("TaskSetupTweakToContinue") + << TestData{storage, root3, log3, 2, OnDone::Success}; } { @@ -1432,7 +1596,7 @@ void tst_Tasking::testTree_data() }, Group { groupSetup(3), - createDynamicTask(3, SetupResult::StopWithSuccess) + createTaskWithSetupTweak(3, SetupResult::StopWithSuccess) }, Group { groupSetup(4), @@ -1451,6 +1615,7 @@ void tst_Tasking::testTree_data() {1, Handler::Success}, {3, Handler::GroupSetup}, {3, Handler::Setup}, + {3, Handler::TweakSetupToSuccess}, {4, Handler::GroupSetup}, {4, Handler::Setup}, {2, Handler::Success}, @@ -1476,7 +1641,7 @@ void tst_Tasking::testTree_data() }, Group { groupSetup(3), - createDynamicTask(3, SetupResult::StopWithError) + createTaskWithSetupTweak(3, SetupResult::StopWithError) }, Group { groupSetup(4), @@ -1495,6 +1660,7 @@ void tst_Tasking::testTree_data() {1, Handler::Success}, {3, Handler::GroupSetup}, {3, Handler::Setup}, + {3, Handler::TweakSetupToError}, {2, Handler::Canceled} }; @@ -1515,7 +1681,7 @@ void tst_Tasking::testTree_data() }, Group { groupSetup(3), - createDynamicTask(3, SetupResult::StopWithError) + createTaskWithSetupTweak(3, SetupResult::StopWithError) }, Group { groupSetup(4), @@ -1534,6 +1700,7 @@ void tst_Tasking::testTree_data() {2, Handler::Success}, {3, Handler::GroupSetup}, {3, Handler::Setup}, + {3, Handler::TweakSetupToError}, {1, Handler::Canceled} }; @@ -1560,7 +1727,7 @@ void tst_Tasking::testTree_data() }, Group { groupSetup(3), - createDynamicTask(3, SetupResult::StopWithError) + createTaskWithSetupTweak(3, SetupResult::StopWithError) }, Group { groupSetup(4), @@ -1580,6 +1747,7 @@ void tst_Tasking::testTree_data() {2, Handler::Success}, {3, Handler::GroupSetup}, {3, Handler::Setup}, + {3, Handler::TweakSetupToError}, {1, Handler::Canceled}, {5, Handler::GroupSetup}, {5, Handler::Setup}, @@ -1657,7 +1825,7 @@ void tst_Tasking::testTree_data() }, Group { groupSetup(3), - Group { createDynamicTask(3, SetupResult::StopWithSuccess) } + Group { createTaskWithSetupTweak(3, SetupResult::StopWithSuccess) } }, Group { groupSetup(4), @@ -1676,6 +1844,7 @@ void tst_Tasking::testTree_data() {1, Handler::Success}, {3, Handler::GroupSetup}, {3, Handler::Setup}, + {3, Handler::TweakSetupToSuccess}, {4, Handler::GroupSetup}, {4, Handler::Setup}, {2, Handler::Success}, @@ -1684,7 +1853,7 @@ void tst_Tasking::testTree_data() {4, Handler::Success}, {5, Handler::Success} }; - QTest::newRow("DeeplyNestedParallelDone") + QTest::newRow("DeeplyNestedParallelSuccess") << TestData{storage, root, log, 5, OnDone::Success}; } @@ -1702,7 +1871,7 @@ void tst_Tasking::testTree_data() }, Group { groupSetup(3), - Group { createDynamicTask(3, SetupResult::StopWithError) } + Group { createTaskWithSetupTweak(3, SetupResult::StopWithError) } }, Group { groupSetup(4), @@ -1721,6 +1890,7 @@ void tst_Tasking::testTree_data() {1, Handler::Success}, {3, Handler::GroupSetup}, {3, Handler::Setup}, + {3, Handler::TweakSetupToError}, {2, Handler::Canceled} }; QTest::newRow("DeeplyNestedParallelError") @@ -1749,18 +1919,23 @@ void tst_Tasking::testTree_data() { const Group root { Storage(storage), - createSyncWithReturn(1, true), - createSyncWithReturn(2, true), - createSyncWithReturn(3, true), - createSyncWithReturn(4, true), - createSyncWithReturn(5, true) + createSyncWithTweak(1, true), + createSyncWithTweak(2, true), + createSyncWithTweak(3, true), + createSyncWithTweak(4, true), + createSyncWithTweak(5, true) }; const Log log { {1, Handler::Sync}, + {1, Handler::TweakDoneToSuccess}, {2, Handler::Sync}, + {2, Handler::TweakDoneToSuccess}, {3, Handler::Sync}, + {3, Handler::TweakDoneToSuccess}, {4, Handler::Sync}, - {5, Handler::Sync} + {4, Handler::TweakDoneToSuccess}, + {5, Handler::Sync}, + {5, Handler::TweakDoneToSuccess} }; QTest::newRow("SyncWithReturn") << TestData{storage, root, log, 0, OnDone::Success}; } @@ -1791,14 +1966,15 @@ void tst_Tasking::testTree_data() parallel, createSync(1), createSync(2), - createSyncWithReturn(3, false), + createSyncWithTweak(3, false), createSync(4), createSync(5) }; const Log log { {1, Handler::Sync}, {2, Handler::Sync}, - {3, Handler::Sync} + {3, Handler::Sync}, + {3, Handler::TweakDoneToError} }; QTest::newRow("SyncError") << TestData{storage, root, log, 0, OnDone::Failure}; } @@ -1831,7 +2007,7 @@ void tst_Tasking::testTree_data() Storage(storage), createSync(1), createSuccessTask(2), - createSyncWithReturn(3, false), + createSyncWithTweak(3, false), createSuccessTask(4), createSync(5), groupDone(0) @@ -1841,6 +2017,7 @@ void tst_Tasking::testTree_data() {2, Handler::Setup}, {2, Handler::Success}, {3, Handler::Sync}, + {3, Handler::TweakDoneToError}, {0, Handler::GroupError} }; QTest::newRow("SyncAndAsyncError") << TestData{storage, root, log, 2, OnDone::Failure}; From a0db7c79910caf843a260e4891c29f41e43c7776 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sun, 5 Nov 2023 00:03:13 +0100 Subject: [PATCH 0097/1546] TaskTree: Simplify calling storage done handlers on destruction Get rid of callStorageDoneHandlers() function which is very similar to the d'tor's body. Introduce m_callStorageDoneHandlersOnDestruction flag instead. Change-Id: Ib9ca3e5fb3e2c5bc7fb8de8f305244bbd5558f4e Reviewed-by: Reviewed-by: Qt CI Bot Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index dae251f6d00..8b779d18e49 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -1056,13 +1056,13 @@ public: ~RuntimeData(); static QList createStorages(const TaskContainer::ConstData &constData); - void callStorageDoneHandlers(); bool updateSuccessBit(bool success); int currentLimit() const; const ConstData &m_constData; const QList m_storageIdList; bool m_successBit = true; + bool m_callStorageDoneHandlersOnDestruction = false; int m_doneCount = 0; Guard m_startGuard; }; @@ -1237,15 +1237,6 @@ QList TaskContainer::RuntimeData::createStorages(const TaskContainer::Const return storageIdList; } -void TaskContainer::RuntimeData::callStorageDoneHandlers() -{ - for (int i = m_constData.m_storageList.size() - 1; i >= 0; --i) { // iterate in reverse order - const TreeStorageBase storage = m_constData.m_storageList[i]; - const int storageId = m_storageIdList.value(i); - m_constData.m_taskTreePrivate->callDoneHandler(storage, storageId); - } -} - static bool initialSuccessBit(WorkflowPolicy workflowPolicy) { switch (workflowPolicy) { @@ -1274,6 +1265,8 @@ TaskContainer::RuntimeData::~RuntimeData() for (int i = m_constData.m_storageList.size() - 1; i >= 0; --i) { // iterate in reverse order const TreeStorageBase storage = m_constData.m_storageList[i]; const int storageId = m_storageIdList.value(i); + if (m_callStorageDoneHandlersOnDestruction) + m_constData.m_taskTreePrivate->callDoneHandler(storage, storageId); storage.deleteStorage(storageId); } } @@ -1418,7 +1411,7 @@ bool TaskContainer::invokeDoneHandler(DoneWith result) const GroupItem::GroupHandler &groupHandler = m_constData.m_groupHandler; if (groupHandler.m_doneHandler && shouldCall(groupHandler.m_callDoneIf, result)) success = invokeHandler(this, groupHandler.m_doneHandler, result); - m_runtimeData->callStorageDoneHandlers(); + m_runtimeData->m_callStorageDoneHandlersOnDestruction = true; m_runtimeData.reset(); return success; } From de24f309a4e47a4ca0e2f3f45b9f6df1bda859cb Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sun, 5 Nov 2023 00:25:16 +0100 Subject: [PATCH 0098/1546] TaskTree: Get rid of public getters from GroupItem Make friends to concerned classes instead. Change-Id: I6b59b9e50129ab340c33fb3b6910bcbdc4b769f0 Reviewed-by: Reviewed-by: hjk Reviewed-by: Qt CI Bot --- src/libs/solutions/tasking/tasktree.cpp | 15 +++++++-------- src/libs/solutions/tasking/tasktree.h | 7 ++----- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 8b779d18e49..37bc8385e21 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -1078,7 +1078,7 @@ class TaskNode public: TaskNode(TaskTreePrivate *taskTreePrivate, const GroupItem &task, TaskContainer *parentContainer) - : m_taskHandler(task.taskHandler()) + : m_taskHandler(task.m_taskHandler) , m_container(taskTreePrivate, task, this, parentContainer) {} @@ -1202,10 +1202,9 @@ ReturnType invokeHandler(TaskContainer *container, Handler &&handler, Args &&... } static QList createChildren(TaskTreePrivate *taskTreePrivate, TaskContainer *container, - const GroupItem &task) + const QList &children) { QList result; - const QList &children = task.children(); for (const GroupItem &child : children) result.append(new TaskNode(taskTreePrivate, child, container)); return result; @@ -1217,11 +1216,11 @@ TaskContainer::ConstData::ConstData(TaskTreePrivate *taskTreePrivate, const Grou : m_taskTreePrivate(taskTreePrivate) , m_parentNode(parentNode) , m_parentContainer(parentContainer) - , m_parallelLimit(task.groupData().m_parallelLimit.value_or(1)) - , m_workflowPolicy(task.groupData().m_workflowPolicy.value_or(WorkflowPolicy::StopOnError)) - , m_groupHandler(task.groupData().m_groupHandler) - , m_storageList(taskTreePrivate->addStorages(task.storageList())) - , m_children(createChildren(taskTreePrivate, thisContainer, task)) + , m_parallelLimit(task.m_groupData.m_parallelLimit.value_or(1)) + , m_workflowPolicy(task.m_groupData.m_workflowPolicy.value_or(WorkflowPolicy::StopOnError)) + , m_groupHandler(task.m_groupData.m_groupHandler) + , m_storageList(taskTreePrivate->addStorages(task.m_storageList)) + , m_children(createChildren(taskTreePrivate, thisContainer, task.m_children)) , m_taskCount(std::accumulate(m_children.cbegin(), m_children.cend(), 0, [](int r, TaskNode *n) { return r + n->taskCount(); })) {} diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index fcc5df34392..d6375023b9f 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -181,11 +181,6 @@ public: std::optional m_workflowPolicy = {}; }; - QList children() const { return m_children; } - GroupData groupData() const { return m_groupData; } - QList storageList() const { return m_storageList; } - TaskHandler taskHandler() const { return m_taskHandler; } - protected: enum class Type { List, @@ -226,6 +221,8 @@ protected: } private: + friend class TaskContainer; + friend class TaskNode; Type m_type = Type::Group; QList m_children; GroupData m_groupData; From e78d6bd3c420347fee20641689ab8c61bfb3e10c Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sat, 4 Nov 2023 23:51:17 +0100 Subject: [PATCH 0099/1546] TaskTree: Implement storage shadowing Make it possible to have the same storage instance placed in different groups. When the same storage is placed in two nested groups, implement storage shadowing so that when the inner group is activated it activates only the innermost storage and shadows any possible the same storages in parent groups. Keep placing the same storage twice in one group forbidden. This functionality is required to implement the task tree loops (see 3rd point in the master task below). This addresses the 23th point in the master task below. Task-number: QTCREATORBUG-28741 Change-Id: Iba00bc32319430136a794974c14a1ab65272eaa9 Reviewed-by: Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 69 +++++++++-------- src/libs/solutions/tasking/tasktree.h | 1 + tests/auto/solutions/tasking/tst_tasking.cpp | 79 +++++++++++++++++++- 3 files changed, 116 insertions(+), 33 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 37bc8385e21..84e6f544553 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -865,6 +865,11 @@ void *TreeStorageBase::activeStorageVoid() const return it.value(); } +int TreeStorageBase::activeStorageId() const +{ + return m_storageData->m_activeStorage; +} + int TreeStorageBase::createStorage() const { QTC_ASSERT(m_storageData->m_constructor, return 0); // TODO: add isValid()? @@ -895,6 +900,7 @@ void TreeStorageBase::activateStorage(int id) const return; } QTC_ASSERT(m_storageData->m_activeStorage == 0, return); + // TODO: Unneeded check? OTOH, it's quite important... const auto it = m_storageData->m_storageHash.find(id); QTC_ASSERT(it != m_storageData->m_storageHash.end(), return); m_storageData->m_activeStorage = id; @@ -946,7 +952,15 @@ void GroupItem::addChildren(const QList &children) m_children.append(child); break; case Type::Storage: - m_storageList.append(child.m_storageList); + // Check for duplicates, as can't have the same storage twice on the same level. + for (const TreeStorageBase &storage : child.m_storageList) { + if (m_storageList.contains(storage)) { + QTC_ASSERT(false, qWarning("Can't add the same storage into one Group twice, " + "skipping...")); + continue; + } + m_storageList.append(storage); + } break; } } @@ -985,7 +999,6 @@ public: void emitStartedAndProgress(); void emitProgress(); void emitDone(DoneWith result); - QList addStorages(const QList &storages); void callSetupHandler(TreeStorageBase storage, int storageId) { callStorageHandler(storage, storageId, &StorageHandler::m_setupHandler); } @@ -1151,45 +1164,33 @@ void TaskTreePrivate::emitDone(DoneWith result) emit q->done(result); } -QList TaskTreePrivate::addStorages(const QList &storages) -{ - QList addedStorages; - for (const TreeStorageBase &storage : storages) { - QTC_ASSERT(!m_storages.contains(storage), qWarning("Can't add the same storage into " - "one TaskTree twice, skipping..."); continue); - addedStorages << storage; - m_storages << storage; - } - return addedStorages; -} - class ExecutionContextActivator { public: - ExecutionContextActivator(TaskContainer *container) - : m_container(container) { activateContext(m_container); } - ~ExecutionContextActivator() { deactivateContext(m_container); } + ExecutionContextActivator(TaskContainer *container) { activateContext(container); } + ~ExecutionContextActivator() { + for (int i = m_activeStorages.size() - 1; i >= 0; --i) // iterate in reverse order + m_activeStorages[i].activateStorage(0); + } private: - static void activateContext(TaskContainer *container) + void activateContext(TaskContainer *container) { QTC_ASSERT(container && container->isRunning(), return); const TaskContainer::ConstData &constData = container->m_constData; + for (int i = 0; i < constData.m_storageList.size(); ++i) { + const TreeStorageBase &storage = constData.m_storageList[i]; + if (storage.activeStorageId()) + continue; // Storage shadowing: The storage is already active, skipping it... + m_activeStorages.append(storage); + storage.activateStorage(container->m_runtimeData->m_storageIdList.value(i)); + } + // Go to the parent after activating this storages so that storage shadowing works + // in the direction from child to parent root. if (constData.m_parentContainer) activateContext(constData.m_parentContainer); - for (int i = 0; i < constData.m_storageList.size(); ++i) - constData.m_storageList[i].activateStorage(container->m_runtimeData->m_storageIdList.value(i)); } - static void deactivateContext(TaskContainer *container) - { - QTC_ASSERT(container && container->isRunning(), return); - const TaskContainer::ConstData &constData = container->m_constData; - for (int i = constData.m_storageList.size() - 1; i >= 0; --i) // iterate in reverse order - constData.m_storageList[i].activateStorage(0); - if (constData.m_parentContainer) - deactivateContext(constData.m_parentContainer); - } - TaskContainer *m_container = nullptr; + QList m_activeStorages; }; template addStorages(task.m_storageList)) + , m_storageList(task.m_storageList) , m_children(createChildren(taskTreePrivate, thisContainer, task.m_children)) , m_taskCount(std::accumulate(m_children.cbegin(), m_children.cend(), 0, [](int r, TaskNode *n) { return r + n->taskCount(); })) -{} +{ + for (const TreeStorageBase &storage : m_storageList) + m_taskTreePrivate->m_storages << storage; +} QList TaskContainer::RuntimeData::createStorages(const TaskContainer::ConstData &constData) { @@ -2170,6 +2174,7 @@ void TaskTree::setRecipe(const Group &recipe) QTC_ASSERT(!isRunning(), qWarning("The TaskTree is already running, ignoring..."); return); QTC_ASSERT(!d->m_guard.isLocked(), qWarning("The setRecipe() is called from one of the" "TaskTree handlers, ignoring..."); return); + // TODO: Should we clear the m_storageHandlers, too? d->m_storages.clear(); d->m_root.reset(new TaskNode(d, recipe, nullptr)); } diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index d6375023b9f..a575d7c10c9 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -52,6 +52,7 @@ private: TreeStorageBase(StorageConstructor ctor, StorageDestructor dtor); void *activeStorageVoid() const; + int activeStorageId() const; int createStorage() const; void deleteStorage(int id) const; diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index ae0b3d63329..994d3d54967 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -4,6 +4,7 @@ #include #include +#include using namespace Tasking; @@ -39,7 +40,8 @@ enum class Handler { TweakDoneToError, Sync, BarrierAdvance, - Timeout + Timeout, + Storage }; Q_ENUM_NS(Handler); @@ -2425,6 +2427,81 @@ void tst_Tasking::testTree_data() QTest::newRow("GroupDoneWithTimeoutHandler") << TestData{storage, root4, doneLog, 2, OnDone::Success}; } + + { + // This test check if storage shadowing works OK. + + // This helper storage collect the pointers to storages created by shadowedStorage. + const TreeStorage> helperStorage; // One instance in this test. + // This storage is repeated in nested groups, the innermost storage will shadow outer ones. + const TreeStorage shadowedStorage; // Three instances in this test. + + const auto groupSetupWithStorage = [storage, helperStorage, shadowedStorage](int taskId) { + return onGroupSetup([storage, helperStorage, shadowedStorage, taskId] { + storage->m_log.append({taskId, Handler::GroupSetup}); + helperStorage->insert(taskId, shadowedStorage.activeStorage()); + *shadowedStorage = taskId; + }); + }; + const auto groupDoneWithStorage = [storage, helperStorage, shadowedStorage](int taskId) { + return onGroupDone([storage, helperStorage, shadowedStorage, taskId](DoneWith result) { + storage->m_log.append({taskId, resultToGroupHandler(result)}); + auto it = helperStorage->find(taskId); + if (it == helperStorage->end()) { + qWarning() << "The helperStorage is missing the shadowedStorage."; + return; + } else if (*it != shadowedStorage.activeStorage()) { + qWarning() << "Wrong active instance of the shadowedStorage."; + return; + } else if (**it != taskId) { + qWarning() << "Wrong data of the active instance of the shadowedStorage."; + return; + } + helperStorage->erase(it); + storage->m_log.append({*shadowedStorage, Handler::Storage}); + }); + }; + + const Group root { + Storage(storage), + Storage(helperStorage), + Storage(shadowedStorage), + groupSetupWithStorage(1), + Group { + Storage(shadowedStorage), + groupSetupWithStorage(2), + Group { + Storage(shadowedStorage), + groupSetupWithStorage(3), + groupDoneWithStorage(3) + }, + Group { + Storage(shadowedStorage), + groupSetupWithStorage(4), + groupDoneWithStorage(4) + }, + groupDoneWithStorage(2) + }, + groupDoneWithStorage(1) + }; + + const Log log { + {1, Handler::GroupSetup}, + {2, Handler::GroupSetup}, + {3, Handler::GroupSetup}, + {3, Handler::GroupSuccess}, + {3, Handler::Storage}, + {4, Handler::GroupSetup}, + {4, Handler::GroupSuccess}, + {4, Handler::Storage}, + {2, Handler::GroupSuccess}, + {2, Handler::Storage}, + {1, Handler::GroupSuccess}, + {1, Handler::Storage}, + }; + + QTest::newRow("StorageShadowing") << TestData{storage, root, log, 0, OnDone::Success}; + } } void tst_Tasking::testTree() From 01877b57d6d0851e040cb79a332faf62df37f882 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sun, 5 Nov 2023 16:55:00 +0100 Subject: [PATCH 0100/1546] TaskTree: Make storages thread-safe Make it possible to safely run concurrently 2 task trees in 2 separate threads containing the common recipe with common storages. This addresses the 24th point in the master task below. Task-number: QTCREATORBUG-28741 Change-Id: I3a413277e1f0640c38d6b85236e9aca09552e38f Reviewed-by: Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 120 ++++++++++++++++-------- src/libs/solutions/tasking/tasktree.h | 46 +++++++-- 2 files changed, 115 insertions(+), 51 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 84e6f544553..0f176447903 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -843,67 +843,101 @@ bool TreeStorageBase::isValid() const } TreeStorageBase::TreeStorageBase(StorageConstructor ctor, StorageDestructor dtor) - : m_storageData(new StorageData{ctor, dtor}) { } + : m_storageData(new StorageData{ctor, dtor}) +{} -TreeStorageBase::StorageData::~StorageData() +TreeStorageBase::ThreadData::ThreadData(TreeStorageBase::StorageData *storageData) + : m_storageData(storageData) +{ + QTC_CHECK(m_storageData->m_constructor); + QTC_CHECK(m_storageData->m_destructor); +} + +TreeStorageBase::ThreadData::~ThreadData() { QTC_CHECK(m_storageHash.isEmpty()); + // TODO: Issue a warning about the leak instead? for (void *ptr : std::as_const(m_storageHash)) - m_destructor(ptr); + m_storageData->m_destructor(ptr); } -void *TreeStorageBase::activeStorageVoid() const +int TreeStorageBase::ThreadData::createStorage() { - QTC_ASSERT(m_storageData->m_activeStorage, qWarning( - "The referenced storage is not reachable in the running tree. " - "A nullptr will be returned which might lead to a crash in the calling code. " - "It is possible that no storage was added to the tree, " - "or the storage is not reachable from where it is referenced."); - return nullptr); - const auto it = m_storageData->m_storageHash.constFind(m_storageData->m_activeStorage); - QTC_ASSERT(it != m_storageData->m_storageHash.constEnd(), return nullptr); - return it.value(); + QTC_ASSERT(m_activeStorage == 0, return 0); // TODO: should be allowed? + const int newId = m_storageData->m_storageInstanceCounter.fetch_add(1) + 1; + m_storageHash.insert(newId, m_storageData->m_constructor()); + return newId; } -int TreeStorageBase::activeStorageId() const +bool TreeStorageBase::ThreadData::deleteStorage(int id) { - return m_storageData->m_activeStorage; + QTC_ASSERT(m_activeStorage == 0, return false); // TODO: should be allowed? + const auto it = m_storageHash.constFind(id); + QTC_ASSERT(it != m_storageHash.constEnd(), return false); + m_storageData->m_destructor(it.value()); + m_storageHash.erase(it); + return m_storageHash.empty(); } int TreeStorageBase::createStorage() const { - QTC_ASSERT(m_storageData->m_constructor, return 0); // TODO: add isValid()? - QTC_ASSERT(m_storageData->m_destructor, return 0); - QTC_ASSERT(m_storageData->m_activeStorage == 0, return 0); // TODO: should be allowed? - const int newId = ++m_storageData->m_storageCounter; - m_storageData->m_storageHash.insert(newId, m_storageData->m_constructor()); - return newId; + return threadData().createStorage(); } void TreeStorageBase::deleteStorage(int id) const { - QTC_ASSERT(m_storageData->m_constructor, return); // TODO: add isValid()? - QTC_ASSERT(m_storageData->m_destructor, return); - QTC_ASSERT(m_storageData->m_activeStorage == 0, return); // TODO: should be allowed? - const auto it = m_storageData->m_storageHash.constFind(id); - QTC_ASSERT(it != m_storageData->m_storageHash.constEnd(), return); - m_storageData->m_destructor(it.value()); - m_storageData->m_storageHash.erase(it); + if (!threadData().deleteStorage(id)) + return; + + QMutexLocker lock(&m_storageData->m_threadDataMutex); + m_storageData->m_threadDataMap.erase( + m_storageData->m_threadDataMap.find(QThread::currentThread())); } + // passing 0 deactivates currently active storage -void TreeStorageBase::activateStorage(int id) const +void TreeStorageBase::ThreadData::activateStorage(int id) { if (id == 0) { - QTC_ASSERT(m_storageData->m_activeStorage, return); - m_storageData->m_activeStorage = 0; + QTC_ASSERT(m_activeStorage, return); + m_activeStorage = 0; return; } - QTC_ASSERT(m_storageData->m_activeStorage == 0, return); + QTC_ASSERT(m_activeStorage == 0, return); // TODO: Unneeded check? OTOH, it's quite important... - const auto it = m_storageData->m_storageHash.find(id); - QTC_ASSERT(it != m_storageData->m_storageHash.end(), return); - m_storageData->m_activeStorage = id; + const auto it = m_storageHash.find(id); + QTC_ASSERT(it != m_storageHash.end(), return); + m_activeStorage = id; +} + +void *TreeStorageBase::ThreadData::activeStorageVoid() const +{ + QTC_ASSERT(m_activeStorage, qWarning( + "The referenced storage is not reachable in the running tree. " + "A nullptr will be returned which might lead to a crash in the calling code. " + "It is possible that no storage was added to the tree, " + "or the storage is not reachable from where it is referenced."); return nullptr); + const auto it = m_storageHash.constFind(m_activeStorage); + QTC_ASSERT(it != m_storageHash.constEnd(), return nullptr); + return it.value(); +} + +int TreeStorageBase::ThreadData::activeStorageId() const +{ + return m_activeStorage; +} + +TreeStorageBase::StorageData::~StorageData() +{ + QMutexLocker lock(&m_threadDataMutex); + QTC_CHECK(m_threadDataMap.empty()); +} + +TreeStorageBase::ThreadData &TreeStorageBase::threadData() const +{ + QMutexLocker lock(&m_storageData->m_threadDataMutex); + return m_storageData->m_threadDataMap.emplace(QThread::currentThread(), + m_storageData.get()).first->second; } void GroupItem::addChildren(const QList &children) @@ -1017,10 +1051,13 @@ public: return; GuardLocker locker(m_guard); const StorageHandler storageHandler = *it; - storage.activateStorage(storageId); + // TODO: we don't necessarily need to activate the storage here, it's enough to + // get a pointer to the relevant storage instance. + auto &threadData = storage.threadData(); + threadData.activateStorage(storageId); if (storageHandler.*ptr) - (storageHandler.*ptr)(storage.activeStorageVoid()); - storage.activateStorage(0); + (storageHandler.*ptr)(threadData.activeStorageVoid()); + threadData.activateStorage(0); } TaskTree *q = nullptr; @@ -1170,7 +1207,7 @@ public: ExecutionContextActivator(TaskContainer *container) { activateContext(container); } ~ExecutionContextActivator() { for (int i = m_activeStorages.size() - 1; i >= 0; --i) // iterate in reverse order - m_activeStorages[i].activateStorage(0); + m_activeStorages[i].threadData().activateStorage(0); } private: @@ -1180,10 +1217,11 @@ private: const TaskContainer::ConstData &constData = container->m_constData; for (int i = 0; i < constData.m_storageList.size(); ++i) { const TreeStorageBase &storage = constData.m_storageList[i]; - if (storage.activeStorageId()) + auto &threadData = storage.threadData(); + if (threadData.activeStorageId()) continue; // Storage shadowing: The storage is already active, skipping it... m_activeStorages.append(storage); - storage.activateStorage(container->m_runtimeData->m_storageIdList.value(i)); + threadData.activateStorage(container->m_runtimeData->m_storageIdList.value(i)); } // Go to the parent after activating this storages so that storage shadowing works // in the direction from child to parent root. diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index a575d7c10c9..5743beff518 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -6,9 +6,11 @@ #include "tasking_global.h" #include +#include #include #include +#include #include QT_BEGIN_NAMESPACE @@ -51,12 +53,33 @@ private: using StorageDestructor = std::function; TreeStorageBase(StorageConstructor ctor, StorageDestructor dtor); - void *activeStorageVoid() const; - int activeStorageId() const; + struct StorageData; + + struct TASKING_EXPORT ThreadData + { + Q_DISABLE_COPY_MOVE(ThreadData) + + ThreadData(StorageData *storageData); + ~ThreadData(); + + int createStorage(); + bool deleteStorage(int id); // Returns true if it was the last storage. + + void activateStorage(int id); + + void *activeStorageVoid() const; + int activeStorageId() const; + + private: + StorageData *m_storageData = nullptr; + QHash m_storageHash; + int m_activeStorage = 0; // 0 means no active storage. + }; + + ThreadData &threadData() const; int createStorage() const; void deleteStorage(int id) const; - void activateStorage(int id) const; friend bool operator==(const TreeStorageBase &first, const TreeStorageBase &second) { return first.m_storageData == second.m_storageData; } @@ -67,13 +90,16 @@ private: friend size_t qHash(const TreeStorageBase &storage, uint seed = 0) { return size_t(storage.m_storageData.get()) ^ seed; } - struct StorageData { + struct StorageData + { ~StorageData(); - StorageConstructor m_constructor = {}; - StorageDestructor m_destructor = {}; - QHash m_storageHash = {}; - int m_activeStorage = 0; // 0 means no active storage - int m_storageCounter = 0; + const StorageConstructor m_constructor = {}; + const StorageDestructor m_destructor = {}; + QMutex m_threadDataMutex = {}; + // Use std::map on purpose, so that it doesn't invalidate references on modifications. + // Don't optimize it by using std::unordered_map. + std::map m_threadDataMap = {}; + std::atomic_int m_storageInstanceCounter = 0; // Bumped on each creation. }; QSharedPointer m_storageData; @@ -91,7 +117,7 @@ public: StorageStruct &operator*() const noexcept { return *activeStorage(); } StorageStruct *operator->() const noexcept { return activeStorage(); } StorageStruct *activeStorage() const { - return static_cast(activeStorageVoid()); + return static_cast(threadData().activeStorageVoid()); // HERE } private: From a88f807e866c9bd0312a840ab2b8223d2c98cada Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 6 Nov 2023 08:29:33 +0100 Subject: [PATCH 0101/1546] TaskTree tests: Add stress test for storages Run the same recipe concurrently. Test whether handling the same storage concurrently works properly. This addresses the 24th point in the master task below. Task-number: QTCREATORBUG-28741 Change-Id: Ic3358bef335b96b7dc2b88ad8102c440db5dafbf Reviewed-by: hjk --- tests/auto/solutions/tasking/CMakeLists.txt | 2 +- tests/auto/solutions/tasking/tasking.qbs | 2 +- tests/auto/solutions/tasking/tst_tasking.cpp | 260 +++++++++++++------ 3 files changed, 185 insertions(+), 79 deletions(-) diff --git a/tests/auto/solutions/tasking/CMakeLists.txt b/tests/auto/solutions/tasking/CMakeLists.txt index f55c3b1c7b2..899c39bd90c 100644 --- a/tests/auto/solutions/tasking/CMakeLists.txt +++ b/tests/auto/solutions/tasking/CMakeLists.txt @@ -1,4 +1,4 @@ add_qtc_test(tst_solutions_tasking - DEPENDS Tasking Qt::Network + DEPENDS Tasking Qt::Concurrent Qt::Network SOURCES tst_tasking.cpp ) diff --git a/tests/auto/solutions/tasking/tasking.qbs b/tests/auto/solutions/tasking/tasking.qbs index d6ffa884920..beb1d305ed9 100644 --- a/tests/auto/solutions/tasking/tasking.qbs +++ b/tests/auto/solutions/tasking/tasking.qbs @@ -1,7 +1,7 @@ QtcAutotest { name: "Tasking autotest" - Depends { name: "Qt"; submodules: ["network"] } + Depends { name: "Qt"; submodules: ["concurrent", "network"] } Depends { name: "Tasking" } files: "tst_tasking.cpp" diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index 994d3d54967..d5d5386172a 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include +#include #include #include @@ -48,6 +49,18 @@ Q_ENUM_NS(Handler); enum class OnDone { Success, Failure }; Q_ENUM_NS(OnDone); +enum class ThreadResult +{ + Success, + FailOnTaskCountCheck, + FailOnRunningCheck, + FailOnProgressCheck, + FailOnLogCheck, + FailOnDoneStatusCheck, + Canceled +}; +Q_ENUM_NS(ThreadResult); + } // namespace PrintableEnums using namespace PrintableEnums; @@ -56,17 +69,18 @@ using Log = QList>; struct CustomStorage { - CustomStorage() { ++s_count; } - ~CustomStorage() { --s_count; } + CustomStorage() { s_count.fetch_add(1); } + ~CustomStorage() { s_count.fetch_add(-1); } Log m_log; - static int instanceCount() { return s_count; } + static int instanceCount() { return s_count.load(); } private: - static int s_count; + static std::atomic_int s_count; }; -int CustomStorage::s_count = 0; +std::atomic_int CustomStorage::s_count = 0; -struct TestData { +struct TestData +{ TreeStorage storage; Group root; Log expectedLog; @@ -82,6 +96,8 @@ private slots: void validConstructs(); // compile test void testTree_data(); void testTree(); + void testInThread_data(); + void testInThread(); void storageIO_data(); void storageIO(); void storageOperators(); @@ -312,6 +328,83 @@ static Handler doneToTweakHandler(bool result) return result ? Handler::TweakDoneToSuccess : Handler::TweakDoneToError; } +static TestData storageShadowing() +{ + // This test check if storage shadowing works OK. + + const TreeStorage storage; + // This helper storage collect the pointers to storages created by shadowedStorage. + const TreeStorage> helperStorage; // One instance in this test. + // This storage is repeated in nested groups, the innermost storage will shadow outer ones. + const TreeStorage shadowedStorage; // Three instances in this test. + + const auto groupSetupWithStorage = [storage, helperStorage, shadowedStorage](int taskId) { + return onGroupSetup([storage, helperStorage, shadowedStorage, taskId] { + storage->m_log.append({taskId, Handler::GroupSetup}); + helperStorage->insert(taskId, shadowedStorage.activeStorage()); + *shadowedStorage = taskId; + }); + }; + const auto groupDoneWithStorage = [storage, helperStorage, shadowedStorage](int taskId) { + return onGroupDone([storage, helperStorage, shadowedStorage, taskId](DoneWith result) { + storage->m_log.append({taskId, resultToGroupHandler(result)}); + auto it = helperStorage->find(taskId); + if (it == helperStorage->end()) { + qWarning() << "The helperStorage is missing the shadowedStorage."; + return; + } else if (*it != shadowedStorage.activeStorage()) { + qWarning() << "Wrong active instance of the shadowedStorage."; + return; + } else if (**it != taskId) { + qWarning() << "Wrong data of the active instance of the shadowedStorage."; + return; + } + helperStorage->erase(it); + storage->m_log.append({*shadowedStorage, Handler::Storage}); + }); + }; + + const Group root { + Storage(storage), + Storage(helperStorage), + Storage(shadowedStorage), + groupSetupWithStorage(1), + Group { + Storage(shadowedStorage), + groupSetupWithStorage(2), + Group { + Storage(shadowedStorage), + groupSetupWithStorage(3), + groupDoneWithStorage(3) + }, + Group { + Storage(shadowedStorage), + groupSetupWithStorage(4), + groupDoneWithStorage(4) + }, + groupDoneWithStorage(2) + }, + groupDoneWithStorage(1) + }; + + const Log log { + {1, Handler::GroupSetup}, + {2, Handler::GroupSetup}, + {3, Handler::GroupSetup}, + {3, Handler::GroupSuccess}, + {3, Handler::Storage}, + {4, Handler::GroupSetup}, + {4, Handler::GroupSuccess}, + {4, Handler::Storage}, + {2, Handler::GroupSuccess}, + {2, Handler::Storage}, + {1, Handler::GroupSuccess}, + {1, Handler::Storage}, + }; + + return {storage, root, log, 0, OnDone::Success}; +} + void tst_Tasking::testTree_data() { QTest::addColumn("testData"); @@ -2430,77 +2523,7 @@ void tst_Tasking::testTree_data() { // This test check if storage shadowing works OK. - - // This helper storage collect the pointers to storages created by shadowedStorage. - const TreeStorage> helperStorage; // One instance in this test. - // This storage is repeated in nested groups, the innermost storage will shadow outer ones. - const TreeStorage shadowedStorage; // Three instances in this test. - - const auto groupSetupWithStorage = [storage, helperStorage, shadowedStorage](int taskId) { - return onGroupSetup([storage, helperStorage, shadowedStorage, taskId] { - storage->m_log.append({taskId, Handler::GroupSetup}); - helperStorage->insert(taskId, shadowedStorage.activeStorage()); - *shadowedStorage = taskId; - }); - }; - const auto groupDoneWithStorage = [storage, helperStorage, shadowedStorage](int taskId) { - return onGroupDone([storage, helperStorage, shadowedStorage, taskId](DoneWith result) { - storage->m_log.append({taskId, resultToGroupHandler(result)}); - auto it = helperStorage->find(taskId); - if (it == helperStorage->end()) { - qWarning() << "The helperStorage is missing the shadowedStorage."; - return; - } else if (*it != shadowedStorage.activeStorage()) { - qWarning() << "Wrong active instance of the shadowedStorage."; - return; - } else if (**it != taskId) { - qWarning() << "Wrong data of the active instance of the shadowedStorage."; - return; - } - helperStorage->erase(it); - storage->m_log.append({*shadowedStorage, Handler::Storage}); - }); - }; - - const Group root { - Storage(storage), - Storage(helperStorage), - Storage(shadowedStorage), - groupSetupWithStorage(1), - Group { - Storage(shadowedStorage), - groupSetupWithStorage(2), - Group { - Storage(shadowedStorage), - groupSetupWithStorage(3), - groupDoneWithStorage(3) - }, - Group { - Storage(shadowedStorage), - groupSetupWithStorage(4), - groupDoneWithStorage(4) - }, - groupDoneWithStorage(2) - }, - groupDoneWithStorage(1) - }; - - const Log log { - {1, Handler::GroupSetup}, - {2, Handler::GroupSetup}, - {3, Handler::GroupSetup}, - {3, Handler::GroupSuccess}, - {3, Handler::Storage}, - {4, Handler::GroupSetup}, - {4, Handler::GroupSuccess}, - {4, Handler::Storage}, - {2, Handler::GroupSuccess}, - {2, Handler::Storage}, - {1, Handler::GroupSuccess}, - {1, Handler::Storage}, - }; - - QTest::newRow("StorageShadowing") << TestData{storage, root, log, 0, OnDone::Success}; + QTest::newRow("StorageShadowing") << storageShadowing(); } } @@ -2525,6 +2548,89 @@ void tst_Tasking::testTree() QCOMPARE(result, testData.onDone); } +void tst_Tasking::testInThread_data() +{ + QTest::addColumn("testData"); + QTest::newRow("StorageShadowing") << storageShadowing(); +} + +struct TestResult +{ + int executeCount = 0; + ThreadResult threadResult = ThreadResult::Success; +}; + +static const int s_loopCount = 1000; +static const int s_threadCount = 12; + +static void runInThread(QPromise &promise, const TestData &testData) +{ + for (int i = 0; i < s_loopCount; ++i) { + if (promise.isCanceled()) { + promise.addResult(TestResult{i, ThreadResult::Canceled}); + return; + } + + TaskTree taskTree({testData.root.withTimeout(1000ms)}); + if (taskTree.taskCount() - 1 != testData.taskCount) { // -1 for the timeout task above + promise.addResult(TestResult{i, ThreadResult::FailOnTaskCountCheck}); + return; + } + Log actualLog; + const auto collectLog = [&actualLog](const CustomStorage &storage) { + actualLog = storage.m_log; + }; + taskTree.onStorageDone(testData.storage, collectLog); + + const OnDone result = taskTree.runBlocking(QFuture(promise.future())) + ? OnDone::Success : OnDone::Failure; + + if (taskTree.isRunning()) { + promise.addResult(TestResult{i, ThreadResult::FailOnRunningCheck}); + return; + } + if (taskTree.progressValue() != taskTree.progressMaximum()) { + promise.addResult(TestResult{i, ThreadResult::FailOnProgressCheck}); + return; + } + if (actualLog != testData.expectedLog) { + promise.addResult(TestResult{i, ThreadResult::FailOnLogCheck}); + return; + } + if (result != testData.onDone) { + promise.addResult(TestResult{i, ThreadResult::FailOnDoneStatusCheck}); + return; + } + } + promise.addResult(TestResult{s_loopCount, ThreadResult::Success}); +} + +void tst_Tasking::testInThread() +{ + QFETCH(TestData, testData); + + const auto onSetup = [testData](ConcurrentCall &task) { + task.setConcurrentCallData(runInThread, testData); + }; + const auto onDone = [testData](const ConcurrentCall &task) { + QVERIFY(task.future().resultCount()); + const TestResult result = task.result(); + QCOMPARE(result.executeCount, s_loopCount); + QCOMPARE(result.threadResult, ThreadResult::Success); + }; + + QList tasks = { parallel }; + for (int i = 0; i < s_threadCount; ++i) + tasks.append(ConcurrentCallTask(onSetup, onDone)); + + TaskTree taskTree(Group{tasks}); + const OnDone result = taskTree.runBlocking() ? OnDone::Success : OnDone::Failure; + QCOMPARE(taskTree.isRunning(), false); + + QCOMPARE(CustomStorage::instanceCount(), 0); + QCOMPARE(result, testData.onDone); +} + struct StorageIO { int value = 0; From 88ac19f188b660271061c6ad878fa9e8166c0844 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sun, 5 Nov 2023 14:26:26 +0100 Subject: [PATCH 0102/1546] TaskTree tests: Add tests triggering runtime asserts This addresses the 15th point in the master task below. Task-number: QTCREATORBUG-28741 Change-Id: I9d449a6ce1538071f300b68b2929bcd437d1bb0f Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 10 +-- tests/auto/solutions/tasking/tst_tasking.cpp | 69 ++++++++++++++++++++ 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 0f176447903..ba90500bccb 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -959,30 +959,30 @@ void GroupItem::addChildren(const QList &children) case Type::GroupData: if (child.m_groupData.m_groupHandler.m_setupHandler) { QTC_ASSERT(!m_groupData.m_groupHandler.m_setupHandler, - qWarning("Group Setup Handler redefinition, overriding...")); + qWarning("Group setup handler redefinition, overriding...")); m_groupData.m_groupHandler.m_setupHandler = child.m_groupData.m_groupHandler.m_setupHandler; } if (child.m_groupData.m_groupHandler.m_doneHandler) { QTC_ASSERT(!m_groupData.m_groupHandler.m_doneHandler, - qWarning("Group Done Handler redefinition, overriding...")); + qWarning("Group done handler redefinition, overriding...")); m_groupData.m_groupHandler.m_doneHandler = child.m_groupData.m_groupHandler.m_doneHandler; } if (child.m_groupData.m_parallelLimit) { QTC_ASSERT(!m_groupData.m_parallelLimit, - qWarning("Group Execution Mode redefinition, overriding...")); + qWarning("Group execution mode redefinition, overriding...")); m_groupData.m_parallelLimit = child.m_groupData.m_parallelLimit; } if (child.m_groupData.m_workflowPolicy) { QTC_ASSERT(!m_groupData.m_workflowPolicy, - qWarning("Group Workflow Policy redefinition, overriding...")); + qWarning("Group workflow policy redefinition, overriding...")); m_groupData.m_workflowPolicy = child.m_groupData.m_workflowPolicy; } break; case Type::TaskHandler: QTC_ASSERT(child.m_taskHandler.m_createHandler, - qWarning("Task Create Handler can't be null, skipping..."); return); + qWarning("Task create handler can't be null, skipping..."); return); m_children.append(child); break; case Type::Storage: diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index d5d5386172a..aa8068cfbcd 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -94,6 +94,7 @@ class tst_Tasking : public QObject private slots: void validConstructs(); // compile test + void runtimeCheck(); // checks done on runtime void testTree_data(); void testTree(); void testInThread_data(); @@ -254,6 +255,74 @@ void tst_Tasking::validConstructs() #endif } +void tst_Tasking::runtimeCheck() +{ + { + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("^SOFT ASSERT: ")); + QTest::ignoreMessage(QtWarningMsg, + "Can't add the same storage into one Group twice, skipping..."); + const TreeStorage storage; + + Group { + Storage(storage), + Storage(storage), + }; + } + + { + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("^SOFT ASSERT: ")); + QTest::ignoreMessage(QtWarningMsg, + "Can't add the same storage into one Group twice, skipping..."); + const TreeStorage storage1; + const auto storage2 = storage1; + + Group { + Storage(storage1), + Storage(storage2), + }; + } + + { + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("^SOFT ASSERT: ")); + QTest::ignoreMessage(QtWarningMsg, + "Group setup handler redefinition, overriding..."); + Group { + onGroupSetup([] {}), + onGroupSetup([] {}), + }; + } + + { + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("^SOFT ASSERT: ")); + QTest::ignoreMessage(QtWarningMsg, + "Group done handler redefinition, overriding..."); + Group { + onGroupDone([] {}), + onGroupDone([] {}), + }; + } + + { + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("^SOFT ASSERT: ")); + QTest::ignoreMessage(QtWarningMsg, + "Group execution mode redefinition, overriding..."); + Group { + sequential, + sequential, + }; + } + + { + QTest::ignoreMessage(QtDebugMsg, QRegularExpression("^SOFT ASSERT: ")); + QTest::ignoreMessage(QtWarningMsg, + "Group workflow policy redefinition, overriding..."); + Group { + stopOnError, + stopOnError, + }; + } +} + class TickAndDone : public QObject { Q_OBJECT From 7ff13f1eaa0d1207abda40741e9df87c13f43e7e Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 6 Nov 2023 17:48:56 +0100 Subject: [PATCH 0103/1546] TaskTree: Introduce DoneResult, use it for Sync setup Instead of using ambiguous bool. Change-Id: Iec45b920a839ac3383abc2d0676e5834f282dddf Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.h | 17 ++++++++---- src/plugins/cppeditor/cppincludesfilter.cpp | 2 +- .../nim/project/nimcompilercleanstep.cpp | 8 +++--- tests/auto/solutions/tasking/tst_tasking.cpp | 27 +++++++++++-------- 4 files changed, 33 insertions(+), 21 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 5743beff518..02ca981d3ba 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -159,6 +159,13 @@ enum class SetupResult }; Q_ENUM_NS(SetupResult); +enum class DoneResult +{ + Success, + Error +}; +Q_ENUM_NS(DoneResult); + enum class DoneWith { Success, @@ -374,16 +381,16 @@ public: private: template static GroupSetupHandler wrapHandler(Handler &&handler) { - // B, V stands for: [B]ool, [V]oid - static constexpr bool isB = isInvocable(); + // D, V stands for: [D]oneResult, [V]oid + static constexpr bool isB = isInvocable(); static constexpr bool isV = isInvocable(); static_assert(isB || isV, - "Sync handler needs to take no arguments and has to return void or bool. " + "Sync handler needs to take no arguments and has to return void or DoneResult. " "The passed handler doesn't fulfill these requirements."); return [=] { if constexpr (isB) { - return std::invoke(handler) ? SetupResult::StopWithSuccess - : SetupResult::StopWithError; + return std::invoke(handler) == DoneResult::Success ? SetupResult::StopWithSuccess + : SetupResult::StopWithError; } std::invoke(handler); return SetupResult::StopWithSuccess; diff --git a/src/plugins/cppeditor/cppincludesfilter.cpp b/src/plugins/cppeditor/cppincludesfilter.cpp index e1df13f7a2d..d955dbeb43b 100644 --- a/src/plugins/cppeditor/cppincludesfilter.cpp +++ b/src/plugins/cppeditor/cppincludesfilter.cpp @@ -59,7 +59,7 @@ CppIncludesFilter::CppIncludesFilter() setDefaultShortcutString("ai"); setDefaultIncludedByDefault(true); const auto invalidate = [this] { m_cache.invalidate(); }; - setRefreshRecipe(Tasking::Sync([invalidate] { invalidate(); return true; })); + setRefreshRecipe(Tasking::Sync([invalidate] { invalidate(); })); setPriority(ILocatorFilter::Low); connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::fileListChanged, diff --git a/src/plugins/nim/project/nimcompilercleanstep.cpp b/src/plugins/nim/project/nimcompilercleanstep.cpp index edfe1b370cb..cb497638b57 100644 --- a/src/plugins/nim/project/nimcompilercleanstep.cpp +++ b/src/plugins/nim/project/nimcompilercleanstep.cpp @@ -63,19 +63,19 @@ GroupItem NimCompilerCleanStep::runRecipe() if (!m_buildDir.exists()) { emit addOutput(Tr::tr("Build directory \"%1\" does not exist.") .arg(m_buildDir.toUserOutput()), OutputFormat::ErrorMessage); - return false; + return DoneResult::Error; } if (!removeCacheDirectory()) { emit addOutput(Tr::tr("Failed to delete the cache directory."), OutputFormat::ErrorMessage); - return false; + return DoneResult::Error; } if (!removeOutFilePath()) { emit addOutput(Tr::tr("Failed to delete the out file."), OutputFormat::ErrorMessage); - return false; + return DoneResult::Error; } emit addOutput(Tr::tr("Clean step completed successfully."), OutputFormat::NormalMessage); - return true; + return DoneResult::Success; }; return Sync(onSetup); } diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index aa8068cfbcd..c46072a78d3 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -397,6 +397,11 @@ static Handler doneToTweakHandler(bool result) return result ? Handler::TweakDoneToSuccess : Handler::TweakDoneToError; } +static Handler doneToTweakHandler(DoneResult result) +{ + return result == DoneResult::Success ? Handler::TweakDoneToSuccess : Handler::TweakDoneToError; +} + static TestData storageShadowing() { // This test check if storage shadowing works OK. @@ -555,11 +560,11 @@ void tst_Tasking::testTree_data() const auto createSync = [storage](int taskId) { return Sync([storage, taskId] { storage->m_log.append({taskId, Handler::Sync}); }); }; - const auto createSyncWithTweak = [storage](int taskId, bool desiredResult) { - return Sync([storage, taskId, desiredResult] { + const auto createSyncWithTweak = [storage](int taskId, DoneResult result) { + return Sync([storage, taskId, result] { storage->m_log.append({taskId, Handler::Sync}); - storage->m_log.append({taskId, doneToTweakHandler(desiredResult)}); - return desiredResult; + storage->m_log.append({taskId, doneToTweakHandler(result)}); + return result; }); }; @@ -2083,11 +2088,11 @@ void tst_Tasking::testTree_data() { const Group root { Storage(storage), - createSyncWithTweak(1, true), - createSyncWithTweak(2, true), - createSyncWithTweak(3, true), - createSyncWithTweak(4, true), - createSyncWithTweak(5, true) + createSyncWithTweak(1, DoneResult::Success), + createSyncWithTweak(2, DoneResult::Success), + createSyncWithTweak(3, DoneResult::Success), + createSyncWithTweak(4, DoneResult::Success), + createSyncWithTweak(5, DoneResult::Success) }; const Log log { {1, Handler::Sync}, @@ -2130,7 +2135,7 @@ void tst_Tasking::testTree_data() parallel, createSync(1), createSync(2), - createSyncWithTweak(3, false), + createSyncWithTweak(3, DoneResult::Error), createSync(4), createSync(5) }; @@ -2171,7 +2176,7 @@ void tst_Tasking::testTree_data() Storage(storage), createSync(1), createSuccessTask(2), - createSyncWithTweak(3, false), + createSyncWithTweak(3, DoneResult::Error), createSuccessTask(4), createSync(5), groupDone(0) From 0f6e6cebf712673c09b50390ffe6b4bc448a9bae Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 6 Nov 2023 18:52:19 +0100 Subject: [PATCH 0104/1546] TaskTree: Use DoneResult in Task done handler Instead of using ambiguous bool. Change-Id: I7eb8e97947f23161c5c2bf5e22575e49bea35d61 Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 17 ++-- src/libs/solutions/tasking/tasktree.h | 36 ++++----- tests/auto/solutions/tasking/tst_tasking.cpp | 85 ++++++++++---------- 3 files changed, 72 insertions(+), 66 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index ba90500bccb..0452a047709 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -837,6 +837,11 @@ static SetupResult toSetupResult(bool success) return success ? SetupResult::StopWithSuccess : SetupResult::StopWithError; } +static DoneResult toDoneResult(DoneWith doneWith) +{ + return doneWith == DoneWith::Success ? DoneResult::Success : DoneResult::Error; +} + bool TreeStorageBase::isValid() const { return m_storageData && m_storageData->m_constructor && m_storageData->m_destructor; @@ -1136,7 +1141,7 @@ public: // in order to unwind properly. SetupResult start(); void stop(); - bool invokeDoneHandler(DoneWith result); + bool invokeDoneHandler(DoneWith doneWith); bool isRunning() const { return m_task || m_container.isRunning(); } bool isTask() const { return bool(m_taskHandler.m_createHandler); } int taskCount() const { return isTask() ? 1 : m_container.m_constData.m_taskCount; } @@ -1507,13 +1512,13 @@ void TaskNode::stop() m_task.reset(); } -bool TaskNode::invokeDoneHandler(DoneWith result) +bool TaskNode::invokeDoneHandler(DoneWith doneWith) { - bool success = result == DoneWith::Success; - if (m_taskHandler.m_doneHandler && shouldCall(m_taskHandler.m_callDoneIf, result)) - success = invokeHandler(parentContainer(), m_taskHandler.m_doneHandler, *m_task.get(), result); + DoneResult result = toDoneResult(doneWith); + if (m_taskHandler.m_doneHandler && shouldCall(m_taskHandler.m_callDoneIf, doneWith)) + result = invokeHandler(parentContainer(), m_taskHandler.m_doneHandler, *m_task.get(), doneWith); m_container.m_constData.m_taskTreePrivate->advanceProgress(1); - return success; + return result == DoneResult::Success; } /*! diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 02ca981d3ba..3690fcf291e 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -190,7 +190,7 @@ public: // Called prior to task start, just after createHandler using TaskSetupHandler = std::function; // Called on task done, just before deleteLater - using TaskDoneHandler = std::function; + using TaskDoneHandler = std::function; // Called when group entered, after group's storages are created using GroupSetupHandler = std::function; // Called when group done, before group's storages are deleted @@ -423,7 +423,7 @@ public: "The Adapter type for the CustomTask needs to be derived from " "TaskAdapter."); using SetupFunction = std::function; - using DoneFunction = std::function; + using DoneFunction = std::function; static Adapter *createAdapter() { return new Adapter; } template @@ -463,38 +463,38 @@ private: static GroupItem::TaskDoneHandler wrapDone(Handler &&handler) { if constexpr (std::is_same_v) return {}; // When user passed {} for the done handler. - // B, V, T, D stands for: [B]ool, [V]oid, [T]ask, [D]oneWith - static constexpr bool isBTD = isInvocable(); - static constexpr bool isBT = isInvocable(); - static constexpr bool isBD = isInvocable(); - static constexpr bool isB = isInvocable(); - static constexpr bool isVTD = isInvocable(); + // D, V, T, W stands for: [D]oneResult, [V]oid, [T]ask, done[W]ith + static constexpr bool isDTW = isInvocable(); + static constexpr bool isDT = isInvocable(); + static constexpr bool isDW = isInvocable(); + static constexpr bool isD = isInvocable(); + static constexpr bool isVTW = isInvocable(); static constexpr bool isVT = isInvocable(); - static constexpr bool isVD = isInvocable(); + static constexpr bool isVW = isInvocable(); static constexpr bool isV = isInvocable(); - static_assert(isBTD || isBT || isBD || isB || isVTD || isVT || isVD || isV, + static_assert(isDTW || isDT || isDW || isD || isVTW || isVT || isVW || isV, "Task done handler needs to take (const Task &, DoneWith), (const Task &), " - "(DoneWith) or (void) as arguments and has to return void or bool. " + "(DoneWith) or (void) as arguments and has to return void or DoneResult. " "The passed handler doesn't fulfill these requirements."); return [=](const TaskInterface &taskInterface, DoneWith result) { const Adapter &adapter = static_cast(taskInterface); - if constexpr (isBTD) + if constexpr (isDTW) return std::invoke(handler, *adapter.task(), result); - if constexpr (isBT) + if constexpr (isDT) return std::invoke(handler, *adapter.task()); - if constexpr (isBD) + if constexpr (isDW) return std::invoke(handler, result); - if constexpr (isB) + if constexpr (isD) return std::invoke(handler); - if constexpr (isVTD) + if constexpr (isVTW) std::invoke(handler, *adapter.task(), result); else if constexpr (isVT) std::invoke(handler, *adapter.task()); - else if constexpr (isVD) + else if constexpr (isVW) std::invoke(handler, result); else if constexpr (isV) std::invoke(handler); - return result == DoneWith::Success; + return result == DoneWith::Success ? DoneResult::Success : DoneResult::Error; }; }; }; diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index c46072a78d3..9dc0bcdaf88 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -372,32 +372,32 @@ GroupItem createBarrierAdvance(const TreeStorage &storage, }); } -static Handler resultToGroupHandler(DoneWith result) +static Handler resultToGroupHandler(DoneWith doneWith) { - switch (result) { - case DoneWith::Success : return Handler::GroupSuccess; - case DoneWith::Error : return Handler::GroupError; - case DoneWith::Cancel : return Handler::GroupCanceled; + switch (doneWith) { + case DoneWith::Success: return Handler::GroupSuccess; + case DoneWith::Error: return Handler::GroupError; + case DoneWith::Cancel: return Handler::GroupCanceled; } return Handler::GroupCanceled; } -static Handler setupToTweakHandler(SetupResult result) +static Handler toTweakSetupHandler(SetupResult result) { switch (result) { - case SetupResult::Continue : return Handler::TweakSetupToContinue; - case SetupResult::StopWithSuccess : return Handler::TweakSetupToSuccess; - case SetupResult::StopWithError : return Handler::TweakSetupToError; + case SetupResult::Continue: return Handler::TweakSetupToContinue; + case SetupResult::StopWithSuccess: return Handler::TweakSetupToSuccess; + case SetupResult::StopWithError: return Handler::TweakSetupToError; } return Handler::TweakSetupToContinue; } -static Handler doneToTweakHandler(bool result) +static Handler toTweakDoneHandler(bool success) { - return result ? Handler::TweakDoneToSuccess : Handler::TweakDoneToError; + return success ? Handler::TweakDoneToSuccess : Handler::TweakDoneToError; } -static Handler doneToTweakHandler(DoneResult result) +static Handler toTweakDoneHandler(DoneResult result) { return result == DoneResult::Success ? Handler::TweakDoneToSuccess : Handler::TweakDoneToError; } @@ -492,20 +492,21 @@ void tst_Tasking::testTree_data() }; }; - const auto setupTaskWithTweak = [storage](int taskId, SetupResult desiredResult) { - return [storage, taskId, desiredResult](TaskObject &) { + const auto setupTaskWithTweak = [storage](int taskId, SetupResult result) { + return [storage, taskId, result](TaskObject &) { storage->m_log.append({taskId, Handler::Setup}); - storage->m_log.append({taskId, setupToTweakHandler(desiredResult)}); - return desiredResult; + storage->m_log.append({taskId, toTweakSetupHandler(result)}); + return result; }; }; - const auto setupDone = [storage](int taskId, bool desiredResult = true) { - return [storage, taskId, desiredResult](DoneWith result) { - const Handler handler = result == DoneWith::Cancel ? Handler::Canceled - : desiredResult ? Handler::Success : Handler::Error; + const auto setupDone = [storage](int taskId, DoneResult result = DoneResult::Success) { + return [storage, taskId, result](DoneWith doneWith) { + const Handler handler = doneWith == DoneWith::Cancel ? Handler::Canceled + : result == DoneResult::Success ? Handler::Success : Handler::Error; storage->m_log.append({taskId, handler}); - return desiredResult && result != DoneWith::Cancel; + return doneWith == DoneWith::Cancel ? DoneResult::Error + : result == DoneResult::Success ? DoneResult::Success : DoneResult::Error; }; }; @@ -516,16 +517,16 @@ void tst_Tasking::testTree_data() }; const auto createTask = [storage, setupTask, setupDone]( - int taskId, bool successTask, milliseconds timeout = 0ms) { - return TestTask(setupTask(taskId, timeout), setupDone(taskId, successTask)); + int taskId, DoneResult result, milliseconds timeout = 0ms) { + return TestTask(setupTask(taskId, timeout), setupDone(taskId, result)); }; const auto createSuccessTask = [createTask](int taskId, milliseconds timeout = 0ms) { - return createTask(taskId, true, timeout); + return createTask(taskId, DoneResult::Success, timeout); }; const auto createFailingTask = [createTask](int taskId, milliseconds timeout = 0ms) { - return createTask(taskId, false, timeout); + return createTask(taskId, DoneResult::Error, timeout); }; const auto createTaskWithSetupTweak = [storage, setupTaskWithTweak, setupDone]( @@ -546,14 +547,14 @@ void tst_Tasking::testTree_data() const auto groupSetupWithTweak = [storage](int taskId, SetupResult desiredResult) { return onGroupSetup([storage, taskId, desiredResult] { storage->m_log.append({taskId, Handler::GroupSetup}); - storage->m_log.append({taskId, setupToTweakHandler(desiredResult)}); + storage->m_log.append({taskId, toTweakSetupHandler(desiredResult)}); return desiredResult; }); }; const auto groupDoneWithTweak = [storage](int taskId, bool desiredResult) { return onGroupDone([storage, taskId, desiredResult](DoneWith result) { storage->m_log.append({taskId, resultToGroupHandler(result)}); - storage->m_log.append({taskId, doneToTweakHandler(desiredResult)}); + storage->m_log.append({taskId, toTweakDoneHandler(desiredResult)}); return desiredResult; }); }; @@ -563,7 +564,7 @@ void tst_Tasking::testTree_data() const auto createSyncWithTweak = [storage](int taskId, DoneResult result) { return Sync([storage, taskId, result] { storage->m_log.append({taskId, Handler::Sync}); - storage->m_log.append({taskId, doneToTweakHandler(result)}); + storage->m_log.append({taskId, toTweakDoneHandler(result)}); return result; }); }; @@ -1525,22 +1526,22 @@ void tst_Tasking::testTree_data() } { - const auto createRoot = [storage, createTask, groupDone]( - bool firstSuccess, bool secondSuccess) { + const auto createRoot = [storage, createTask, groupDone](DoneResult firstResult, + DoneResult secondResult) { return Group { parallel, stopOnFinished, Storage(storage), - createTask(1, firstSuccess, 1000ms), - createTask(2, secondSuccess, 1ms), + createTask(1, firstResult, 1000ms), + createTask(2, secondResult, 1ms), groupDone(0) }; }; - const Group root1 = createRoot(true, true); - const Group root2 = createRoot(true, false); - const Group root3 = createRoot(false, true); - const Group root4 = createRoot(false, false); + const Group root1 = createRoot(DoneResult::Success, DoneResult::Success); + const Group root2 = createRoot(DoneResult::Success, DoneResult::Error); + const Group root3 = createRoot(DoneResult::Error, DoneResult::Success); + const Group root4 = createRoot(DoneResult::Error, DoneResult::Error); const Log success { {1, Handler::Setup}, @@ -1610,18 +1611,18 @@ void tst_Tasking::testTree_data() { // This test checks whether group done handler's result is properly dispatched. const auto createRoot = [storage, createTask, groupDone, groupDoneWithTweak]( - bool successTask, bool desiredResult) { + DoneResult firstResult, bool desiredResult) { return Group { Storage(storage), Group { - createTask(1, successTask), + createTask(1, firstResult), groupDoneWithTweak(1, desiredResult) }, groupDone(0) }; }; - const Group root1 = createRoot(true, true); + const Group root1 = createRoot(DoneResult::Success, true); const Log log1 { {1, Handler::Setup}, {1, Handler::Success}, @@ -1632,7 +1633,7 @@ void tst_Tasking::testTree_data() QTest::newRow("GroupDoneWithSuccessTweakToSuccess") << TestData{storage, root1, log1, 1, OnDone::Success}; - const Group root2 = createRoot(true, false); + const Group root2 = createRoot(DoneResult::Success, false); const Log log2 { {1, Handler::Setup}, {1, Handler::Success}, @@ -1643,7 +1644,7 @@ void tst_Tasking::testTree_data() QTest::newRow("GroupDoneWithSuccessTweakToError") << TestData{storage, root2, log2, 1, OnDone::Failure}; - const Group root3 = createRoot(false, true); + const Group root3 = createRoot(DoneResult::Error, true); const Log log3 { {1, Handler::Setup}, {1, Handler::Error}, @@ -1654,7 +1655,7 @@ void tst_Tasking::testTree_data() QTest::newRow("GroupDoneWithErrorTweakToSuccess") << TestData{storage, root3, log3, 1, OnDone::Success}; - const Group root4 = createRoot(false, false); + const Group root4 = createRoot(DoneResult::Error, false); const Log log4 { {1, Handler::Setup}, {1, Handler::Error}, From f771faf82d3995d3c30a7fc17e321bd2fe9ebf54 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 6 Nov 2023 19:17:28 +0100 Subject: [PATCH 0105/1546] TaskTree: Use DoneResult in Group done handler Instead of using ambiguous bool. Change-Id: Icf63f0b129d4b81cc4324d7a100f5aaf2c8af44b Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 12 ++++----- src/libs/solutions/tasking/tasktree.h | 22 ++++++++-------- tests/auto/solutions/tasking/tst_tasking.cpp | 27 ++++++++------------ 3 files changed, 28 insertions(+), 33 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 0452a047709..7bc9c8a5970 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -1086,7 +1086,7 @@ public: SetupResult startChildren(int nextChild); SetupResult childDone(bool success); void stop(); - bool invokeDoneHandler(DoneWith result); + bool invokeDoneHandler(DoneWith doneWith); bool isRunning() const { return m_runtimeData.has_value(); } bool isStarting() const { return isRunning() && m_runtimeData->m_startGuard.isLocked(); } @@ -1451,15 +1451,15 @@ static bool shouldCall(CallDoneIf callDoneIf, DoneWith result) return callDoneIf != CallDoneIf::Success; } -bool TaskContainer::invokeDoneHandler(DoneWith result) +bool TaskContainer::invokeDoneHandler(DoneWith doneWith) { - bool success = result == DoneWith::Success; + DoneResult result = toDoneResult(doneWith); const GroupItem::GroupHandler &groupHandler = m_constData.m_groupHandler; - if (groupHandler.m_doneHandler && shouldCall(groupHandler.m_callDoneIf, result)) - success = invokeHandler(this, groupHandler.m_doneHandler, result); + if (groupHandler.m_doneHandler && shouldCall(groupHandler.m_callDoneIf, doneWith)) + result = invokeHandler(this, groupHandler.m_doneHandler, doneWith); m_runtimeData->m_callStorageDoneHandlersOnDestruction = true; m_runtimeData.reset(); - return success; + return result == DoneResult::Success; } SetupResult TaskNode::start() diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 3690fcf291e..60fe56fcf7c 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -194,7 +194,7 @@ public: // Called when group entered, after group's storages are created using GroupSetupHandler = std::function; // Called when group done, before group's storages are deleted - using GroupDoneHandler = std::function; + using GroupDoneHandler = std::function; struct TaskHandler { TaskCreateHandler m_createHandler; @@ -315,24 +315,24 @@ private: template static GroupDoneHandler wrapGroupDone(Handler &&handler) { - // B, V, D stands for: [B]ool, [V]oid, [D]oneWith - static constexpr bool isBD = isInvocable(); - static constexpr bool isB = isInvocable(); - static constexpr bool isVD = isInvocable(); + // D, V, W stands for: [D]oneResult, [V]oid, Done[W]ith + static constexpr bool isDW = isInvocable(); + static constexpr bool isD = isInvocable(); + static constexpr bool isVW = isInvocable(); static constexpr bool isV = isInvocable(); - static_assert(isBD || isB || isVD || isV, + static_assert(isDW || isD || isVW || isV, "Group done handler needs to take (DoneWith) or (void) as an argument and has to " - "return void or bool. The passed handler doesn't fulfill these requirements."); + "return void or DoneResult. The passed handler doesn't fulfill these requirements."); return [=](DoneWith result) { - if constexpr (isBD) + if constexpr (isDW) return std::invoke(handler, result); - if constexpr (isB) + if constexpr (isD) return std::invoke(handler); - if constexpr (isVD) + if constexpr (isVW) std::invoke(handler, result); else if constexpr (isV) std::invoke(handler); - return result == DoneWith::Success; + return result == DoneWith::Success ? DoneResult::Success : DoneResult::Error; }; }; }; diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index 9dc0bcdaf88..2b9addfdfe7 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -392,11 +392,6 @@ static Handler toTweakSetupHandler(SetupResult result) return Handler::TweakSetupToContinue; } -static Handler toTweakDoneHandler(bool success) -{ - return success ? Handler::TweakDoneToSuccess : Handler::TweakDoneToError; -} - static Handler toTweakDoneHandler(DoneResult result) { return result == DoneResult::Success ? Handler::TweakDoneToSuccess : Handler::TweakDoneToError; @@ -551,11 +546,11 @@ void tst_Tasking::testTree_data() return desiredResult; }); }; - const auto groupDoneWithTweak = [storage](int taskId, bool desiredResult) { - return onGroupDone([storage, taskId, desiredResult](DoneWith result) { - storage->m_log.append({taskId, resultToGroupHandler(result)}); - storage->m_log.append({taskId, toTweakDoneHandler(desiredResult)}); - return desiredResult; + const auto groupDoneWithTweak = [storage](int taskId, DoneResult result) { + return onGroupDone([storage, taskId, result](DoneWith doneWith) { + storage->m_log.append({taskId, resultToGroupHandler(doneWith)}); + storage->m_log.append({taskId, toTweakDoneHandler(result)}); + return result; }); }; const auto createSync = [storage](int taskId) { @@ -1611,18 +1606,18 @@ void tst_Tasking::testTree_data() { // This test checks whether group done handler's result is properly dispatched. const auto createRoot = [storage, createTask, groupDone, groupDoneWithTweak]( - DoneResult firstResult, bool desiredResult) { + DoneResult firstResult, DoneResult secondResult) { return Group { Storage(storage), Group { createTask(1, firstResult), - groupDoneWithTweak(1, desiredResult) + groupDoneWithTweak(1, secondResult) }, groupDone(0) }; }; - const Group root1 = createRoot(DoneResult::Success, true); + const Group root1 = createRoot(DoneResult::Success, DoneResult::Success); const Log log1 { {1, Handler::Setup}, {1, Handler::Success}, @@ -1633,7 +1628,7 @@ void tst_Tasking::testTree_data() QTest::newRow("GroupDoneWithSuccessTweakToSuccess") << TestData{storage, root1, log1, 1, OnDone::Success}; - const Group root2 = createRoot(DoneResult::Success, false); + const Group root2 = createRoot(DoneResult::Success, DoneResult::Error); const Log log2 { {1, Handler::Setup}, {1, Handler::Success}, @@ -1644,7 +1639,7 @@ void tst_Tasking::testTree_data() QTest::newRow("GroupDoneWithSuccessTweakToError") << TestData{storage, root2, log2, 1, OnDone::Failure}; - const Group root3 = createRoot(DoneResult::Error, true); + const Group root3 = createRoot(DoneResult::Error, DoneResult::Success); const Log log3 { {1, Handler::Setup}, {1, Handler::Error}, @@ -1655,7 +1650,7 @@ void tst_Tasking::testTree_data() QTest::newRow("GroupDoneWithErrorTweakToSuccess") << TestData{storage, root3, log3, 1, OnDone::Success}; - const Group root4 = createRoot(DoneResult::Error, false); + const Group root4 = createRoot(DoneResult::Error, DoneResult::Error); const Log log4 { {1, Handler::Setup}, {1, Handler::Error}, From 0938e6cf4dddf64f723f30b878b27d7a1a77a54f Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 6 Nov 2023 20:08:42 +0100 Subject: [PATCH 0106/1546] TaskTree: Use DoneWith in TaskTree::runBlocking() Instead of using ambiguous bool. Reuse it in place of OnDone enum in tests. Change-Id: Ie83e82d9debb88ca19f71ecab40f8ad081293f41 Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 24 +- src/libs/solutions/tasking/tasktree.h | 12 +- src/libs/utils/filestreamer.cpp | 4 +- .../remotelinux/filesystemaccess_test.cpp | 2 +- tests/auto/solutions/tasking/tst_tasking.cpp | 268 +++++++++--------- tests/auto/utils/async/tst_async.cpp | 4 +- 6 files changed, 155 insertions(+), 159 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 7bc9c8a5970..e9628a7f9bf 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -2342,7 +2342,7 @@ bool TaskTree::isRunning() const \sa start() */ -bool TaskTree::runBlocking() +DoneWith TaskTree::runBlocking() { QPromise dummy; dummy.start(); @@ -2353,17 +2353,17 @@ bool TaskTree::runBlocking() \overload runBlocking() The passed \a future is used for listening to the cancel event. - When the task tree finishes with an error, this method cancels the passed \a future. + When the task tree is canceled, this method cancels the passed \a future. */ -bool TaskTree::runBlocking(const QFuture &future) +DoneWith TaskTree::runBlocking(const QFuture &future) { if (future.isCanceled()) - return false; + return DoneWith::Cancel; - bool ok = false; + DoneWith doneWith = DoneWith::Cancel; QEventLoop loop; - connect(this, &TaskTree::done, &loop, [&loop, &ok](DoneWith result) { - ok = result == DoneWith::Success; + connect(this, &TaskTree::done, &loop, [&loop, &doneWith](DoneWith result) { + doneWith = result; // Otherwise, the tasks from inside the running tree that were deleteLater() // will be leaked. Refer to the QObject::deleteLater() docs. QMetaObject::invokeMethod(&loop, [&loop] { loop.quit(); }, Qt::QueuedConnection); @@ -2375,11 +2375,11 @@ bool TaskTree::runBlocking(const QFuture &future) QTimer::singleShot(0, this, &TaskTree::start); loop.exec(QEventLoop::ExcludeUserInputEvents); - if (!ok) { + if (doneWith == DoneWith::Cancel) { auto nonConstFuture = future; nonConstFuture.cancel(); } - return ok; + return doneWith; } /*! @@ -2395,7 +2395,7 @@ bool TaskTree::runBlocking(const QFuture &future) \sa start() */ -bool TaskTree::runBlocking(const Group &recipe, milliseconds timeout) +DoneWith TaskTree::runBlocking(const Group &recipe, milliseconds timeout) { QPromise dummy; dummy.start(); @@ -2406,9 +2406,9 @@ bool TaskTree::runBlocking(const Group &recipe, milliseconds timeout) \overload runBlocking(const Group &recipe, milliseconds timeout) The passed \a future is used for listening to the cancel event. - When the task tree finishes with an error, this method cancels the passed \a future. + When the task tree is canceled, this method cancels the passed \a future. */ -bool TaskTree::runBlocking(const Group &recipe, const QFuture &future, milliseconds timeout) +DoneWith TaskTree::runBlocking(const Group &recipe, const QFuture &future, milliseconds timeout) { const Group root = timeout == milliseconds::max() ? recipe : Group { recipe.withTimeout(timeout) }; diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 60fe56fcf7c..fa9edd3b6e0 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -519,12 +519,12 @@ public: // Helper methods. They execute a local event loop with ExcludeUserInputEvents. // The passed future is used for listening to the cancel event. // Don't use it in main thread. To be used in non-main threads or in auto tests. - bool runBlocking(); - bool runBlocking(const QFuture &future); - static bool runBlocking(const Group &recipe, - std::chrono::milliseconds timeout = std::chrono::milliseconds::max()); - static bool runBlocking(const Group &recipe, const QFuture &future, - std::chrono::milliseconds timeout = std::chrono::milliseconds::max()); + DoneWith runBlocking(); + DoneWith runBlocking(const QFuture &future); + static DoneWith runBlocking(const Group &recipe, + std::chrono::milliseconds timeout = std::chrono::milliseconds::max()); + static DoneWith runBlocking(const Group &recipe, const QFuture &future, + std::chrono::milliseconds timeout = std::chrono::milliseconds::max()); int taskCount() const; int progressMaximum() const { return taskCount(); } diff --git a/src/libs/utils/filestreamer.cpp b/src/libs/utils/filestreamer.cpp index 5d21d56cc61..d4d34c477fa 100644 --- a/src/libs/utils/filestreamer.cpp +++ b/src/libs/utils/filestreamer.cpp @@ -369,8 +369,8 @@ static void transfer(QPromise &promise, const FilePath &source, const File if (promise.isCanceled()) return; - if (!TaskTree::runBlocking(transferTask(source, destination), promise.future())) - promise.future().cancel(); + if (TaskTree::runBlocking(transferTask(source, destination), promise.future()) != DoneWith::Success) + promise.future().cancel(); // TODO: Is this needed? } class FileStreamerPrivate : public QObject diff --git a/src/plugins/remotelinux/filesystemaccess_test.cpp b/src/plugins/remotelinux/filesystemaccess_test.cpp index a66dd7524ca..11bea2487a6 100644 --- a/src/plugins/remotelinux/filesystemaccess_test.cpp +++ b/src/plugins/remotelinux/filesystemaccess_test.cpp @@ -504,7 +504,7 @@ void FileSystemAccessTest::testFileStreamer() }; using namespace std::chrono_literals; - QVERIFY(TaskTree::runBlocking(root, 10000ms)); + QCOMPARE(TaskTree::runBlocking(root, 10000ms), DoneWith::Success); QVERIFY(localData); QCOMPARE(*localData, data); diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index 2b9addfdfe7..4f639f3e013 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -46,9 +46,6 @@ enum class Handler { }; Q_ENUM_NS(Handler); -enum class OnDone { Success, Failure }; -Q_ENUM_NS(OnDone); - enum class ThreadResult { Success, @@ -85,7 +82,7 @@ struct TestData Group root; Log expectedLog; int taskCount = 0; - OnDone onDone = OnDone::Success; + DoneWith onDone = DoneWith::Success; }; class tst_Tasking : public QObject @@ -471,7 +468,7 @@ static TestData storageShadowing() {1, Handler::Storage}, }; - return {storage, root, log, 0, OnDone::Success}; + return {storage, root, log, 0, DoneWith::Success}; } void tst_Tasking::testTree_data() @@ -588,10 +585,10 @@ void tst_Tasking::testTree_data() const Log logDone {{0, Handler::GroupSuccess}}; const Log logError {{0, Handler::GroupError}}; - QTest::newRow("Empty") << TestData{storage, root1, logDone, 0, OnDone::Success}; - QTest::newRow("EmptyContinue") << TestData{storage, root2, logDone, 0, OnDone::Success}; - QTest::newRow("EmptyDone") << TestData{storage, root3, logDone, 0, OnDone::Success}; - QTest::newRow("EmptyError") << TestData{storage, root4, logError, 0, OnDone::Failure}; + QTest::newRow("Empty") << TestData{storage, root1, logDone, 0, DoneWith::Success}; + QTest::newRow("EmptyContinue") << TestData{storage, root2, logDone, 0, DoneWith::Success}; + QTest::newRow("EmptyDone") << TestData{storage, root3, logDone, 0, DoneWith::Success}; + QTest::newRow("EmptyError") << TestData{storage, root4, logError, 0, DoneWith::Error}; } { @@ -606,11 +603,11 @@ void tst_Tasking::testTree_data() const auto doneData = [storage, setupGroup](WorkflowPolicy policy) { return TestData{storage, setupGroup(SetupResult::StopWithSuccess, policy), - Log{{0, Handler::GroupSuccess}}, 0, OnDone::Success}; + Log{{0, Handler::GroupSuccess}}, 0, DoneWith::Success}; }; const auto errorData = [storage, setupGroup](WorkflowPolicy policy) { return TestData{storage, setupGroup(SetupResult::StopWithError, policy), - Log{{0, Handler::GroupError}}, 0, OnDone::Failure}; + Log{{0, Handler::GroupError}}, 0, DoneWith::Error}; }; QTest::newRow("DoneAndStopOnError") << doneData(WorkflowPolicy::StopOnError); @@ -642,7 +639,7 @@ void tst_Tasking::testTree_data() {2, Handler::Setup}, {2, Handler::TweakSetupToSuccess} }; - QTest::newRow("TweekTaskSuccess") << TestData{storage, root, log, 2, OnDone::Success}; + QTest::newRow("TweekTaskSuccess") << TestData{storage, root, log, 2, DoneWith::Success}; } { @@ -655,7 +652,7 @@ void tst_Tasking::testTree_data() {1, Handler::Setup}, {1, Handler::TweakSetupToError} }; - QTest::newRow("TweekTaskError") << TestData{storage, root, log, 2, OnDone::Failure}; + QTest::newRow("TweekTaskError") << TestData{storage, root, log, 2, DoneWith::Error}; } { @@ -676,7 +673,7 @@ void tst_Tasking::testTree_data() {3, Handler::Setup}, {3, Handler::TweakSetupToError} }; - QTest::newRow("TweekMixed") << TestData{storage, root, log, 4, OnDone::Failure}; + QTest::newRow("TweekMixed") << TestData{storage, root, log, 4, DoneWith::Error}; } { @@ -698,7 +695,7 @@ void tst_Tasking::testTree_data() {1, Handler::Canceled}, {2, Handler::Canceled} }; - QTest::newRow("TweekParallel") << TestData{storage, root, log, 4, OnDone::Failure}; + QTest::newRow("TweekParallel") << TestData{storage, root, log, 4, DoneWith::Error}; } { @@ -722,7 +719,7 @@ void tst_Tasking::testTree_data() {1, Handler::Canceled}, {2, Handler::Canceled} }; - QTest::newRow("TweekParallelGroup") << TestData{storage, root, log, 4, OnDone::Failure}; + QTest::newRow("TweekParallelGroup") << TestData{storage, root, log, 4, DoneWith::Error}; } { @@ -748,7 +745,7 @@ void tst_Tasking::testTree_data() {2, Handler::Canceled} }; QTest::newRow("TweekParallelGroupSetup") - << TestData{storage, root, log, 4, OnDone::Failure}; + << TestData{storage, root, log, 4, DoneWith::Error}; } { @@ -792,7 +789,7 @@ void tst_Tasking::testTree_data() {1, Handler::GroupSuccess}, {0, Handler::GroupSuccess} }; - QTest::newRow("Nested") << TestData{storage, root, log, 1, OnDone::Success}; + QTest::newRow("Nested") << TestData{storage, root, log, 1, DoneWith::Success}; } { @@ -819,7 +816,7 @@ void tst_Tasking::testTree_data() {5, Handler::Success}, {0, Handler::GroupSuccess} }; - QTest::newRow("Parallel") << TestData{storage, root, log, 5, OnDone::Success}; + QTest::newRow("Parallel") << TestData{storage, root, log, 5, DoneWith::Success}; } { @@ -875,10 +872,10 @@ void tst_Tasking::testTree_data() {5, Handler::Success}, {0, Handler::GroupSuccess} }; - QTest::newRow("Sequential") << TestData{storage, root1, log, 5, OnDone::Success}; - QTest::newRow("SequentialEncapsulated") << TestData{storage, root2, log, 5, OnDone::Success}; + QTest::newRow("Sequential") << TestData{storage, root1, log, 5, DoneWith::Success}; + QTest::newRow("SequentialEncapsulated") << TestData{storage, root2, log, 5, DoneWith::Success}; // We don't inspect subtrees, so taskCount is 3, not 5. - QTest::newRow("SequentialSubTree") << TestData{storage, root3, log, 3, OnDone::Success}; + QTest::newRow("SequentialSubTree") << TestData{storage, root3, log, 3, DoneWith::Success}; } { @@ -924,7 +921,7 @@ void tst_Tasking::testTree_data() {1, Handler::GroupSuccess}, {0, Handler::GroupSuccess} }; - QTest::newRow("SequentialNested") << TestData{storage, root, log, 5, OnDone::Success}; + QTest::newRow("SequentialNested") << TestData{storage, root, log, 5, DoneWith::Success}; } { @@ -946,7 +943,7 @@ void tst_Tasking::testTree_data() {3, Handler::Error}, {0, Handler::GroupError} }; - QTest::newRow("SequentialError") << TestData{storage, root, log, 5, OnDone::Failure}; + QTest::newRow("SequentialError") << TestData{storage, root, log, 5, DoneWith::Error}; } { @@ -963,31 +960,31 @@ void tst_Tasking::testTree_data() const Group root1 = createRoot(WorkflowPolicy::StopOnError); QTest::newRow("EmptyStopOnError") << TestData{storage, root1, doneLog, 0, - OnDone::Success}; + DoneWith::Success}; const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); QTest::newRow("EmptyContinueOnError") << TestData{storage, root2, doneLog, 0, - OnDone::Success}; + DoneWith::Success}; const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); QTest::newRow("EmptyStopOnSuccess") << TestData{storage, root3, errorLog, 0, - OnDone::Failure}; + DoneWith::Error}; const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); QTest::newRow("EmptyContinueOnSuccess") << TestData{storage, root4, errorLog, 0, - OnDone::Failure}; + DoneWith::Error}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("EmptyStopOnFinished") << TestData{storage, root5, errorLog, 0, - OnDone::Failure}; + DoneWith::Error}; const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); QTest::newRow("EmptyFinishAllAndSuccess") << TestData{storage, root6, doneLog, 0, - OnDone::Success}; + DoneWith::Success}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); QTest::newRow("EmptyFinishAllAndError") << TestData{storage, root7, errorLog, 0, - OnDone::Failure}; + DoneWith::Error}; } { @@ -1015,31 +1012,31 @@ void tst_Tasking::testTree_data() const Group root1 = createRoot(WorkflowPolicy::StopOnError); QTest::newRow("DoneStopOnError") << TestData{storage, root1, doneLog, 1, - OnDone::Success}; + DoneWith::Success}; const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); QTest::newRow("DoneContinueOnError") << TestData{storage, root2, doneLog, 1, - OnDone::Success}; + DoneWith::Success}; const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); QTest::newRow("DoneStopOnSuccess") << TestData{storage, root3, doneLog, 1, - OnDone::Success}; + DoneWith::Success}; const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); QTest::newRow("DoneContinueOnSuccess") << TestData{storage, root4, doneLog, 1, - OnDone::Success}; + DoneWith::Success}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("DoneStopOnFinished") << TestData{storage, root5, doneLog, 1, - OnDone::Success}; + DoneWith::Success}; const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); QTest::newRow("DoneFinishAllAndSuccess") << TestData{storage, root6, doneLog, 1, - OnDone::Success}; + DoneWith::Success}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); QTest::newRow("DoneFinishAllAndError") << TestData{storage, root7, errorLog, 1, - OnDone::Failure}; + DoneWith::Error}; } { @@ -1067,31 +1064,31 @@ void tst_Tasking::testTree_data() const Group root1 = createRoot(WorkflowPolicy::StopOnError); QTest::newRow("ErrorStopOnError") << TestData{storage, root1, errorLog, 1, - OnDone::Failure}; + DoneWith::Error}; const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); QTest::newRow("ErrorContinueOnError") << TestData{storage, root2, errorLog, 1, - OnDone::Failure}; + DoneWith::Error}; const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); QTest::newRow("ErrorStopOnSuccess") << TestData{storage, root3, errorLog, 1, - OnDone::Failure}; + DoneWith::Error}; const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); QTest::newRow("ErrorContinueOnSuccess") << TestData{storage, root4, errorLog, 1, - OnDone::Failure}; + DoneWith::Error}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("ErrorStopOnFinished") << TestData{storage, root5, errorLog, 1, - OnDone::Failure}; + DoneWith::Error}; const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); QTest::newRow("ErrorFinishAllAndSuccess") << TestData{storage, root6, doneLog, 1, - OnDone::Success}; + DoneWith::Success}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); QTest::newRow("ErrorFinishAllAndError") << TestData{storage, root7, errorLog, 1, - OnDone::Failure}; + DoneWith::Error}; } { @@ -1136,31 +1133,31 @@ void tst_Tasking::testTree_data() const Group root1 = createRoot(WorkflowPolicy::StopOnError); QTest::newRow("StopRootWithStopOnError") - << TestData{storage, root1, errorErrorLog, 2, OnDone::Failure}; + << TestData{storage, root1, errorErrorLog, 2, DoneWith::Error}; const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); QTest::newRow("StopRootWithContinueOnError") - << TestData{storage, root2, errorDoneLog, 2, OnDone::Failure}; + << TestData{storage, root2, errorDoneLog, 2, DoneWith::Error}; const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); QTest::newRow("StopRootWithStopOnSuccess") - << TestData{storage, root3, doneLog, 2, OnDone::Success}; + << TestData{storage, root3, doneLog, 2, DoneWith::Success}; const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); QTest::newRow("StopRootWithContinueOnSuccess") - << TestData{storage, root4, doneLog, 2, OnDone::Success}; + << TestData{storage, root4, doneLog, 2, DoneWith::Success}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("StopRootWithStopOnFinished") - << TestData{storage, root5, errorErrorLog, 2, OnDone::Failure}; + << TestData{storage, root5, errorErrorLog, 2, DoneWith::Error}; const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); QTest::newRow("StopRootWithFinishAllAndSuccess") - << TestData{storage, root6, doneLog, 2, OnDone::Success}; + << TestData{storage, root6, doneLog, 2, DoneWith::Success}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); QTest::newRow("StopRootWithFinishAllAndError") - << TestData{storage, root7, errorDoneLog, 2, OnDone::Failure}; + << TestData{storage, root7, errorDoneLog, 2, DoneWith::Error}; } { @@ -1223,31 +1220,31 @@ void tst_Tasking::testTree_data() const Group root1 = createRoot(WorkflowPolicy::StopOnError); QTest::newRow("StopRootAfterDoneWithStopOnError") - << TestData{storage, root1, errorErrorLog, 3, OnDone::Failure}; + << TestData{storage, root1, errorErrorLog, 3, DoneWith::Error}; const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); QTest::newRow("StopRootAfterDoneWithContinueOnError") - << TestData{storage, root2, errorDoneLog, 3, OnDone::Failure}; + << TestData{storage, root2, errorDoneLog, 3, DoneWith::Error}; const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); QTest::newRow("StopRootAfterDoneWithStopOnSuccess") - << TestData{storage, root3, doneErrorLog, 3, OnDone::Success}; + << TestData{storage, root3, doneErrorLog, 3, DoneWith::Success}; const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); QTest::newRow("StopRootAfterDoneWithContinueOnSuccess") - << TestData{storage, root4, doneDoneLog, 3, OnDone::Success}; + << TestData{storage, root4, doneDoneLog, 3, DoneWith::Success}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("StopRootAfterDoneWithStopOnFinished") - << TestData{storage, root5, doneErrorLog, 3, OnDone::Success}; + << TestData{storage, root5, doneErrorLog, 3, DoneWith::Success}; const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); QTest::newRow("StopRootAfterDoneWithFinishAllAndSuccess") - << TestData{storage, root6, doneDoneLog, 3, OnDone::Success}; + << TestData{storage, root6, doneDoneLog, 3, DoneWith::Success}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); QTest::newRow("StopRootAfterDoneWithFinishAllAndError") - << TestData{storage, root7, errorDoneLog, 3, OnDone::Failure}; + << TestData{storage, root7, errorDoneLog, 3, DoneWith::Error}; } { @@ -1280,33 +1277,33 @@ void tst_Tasking::testTree_data() const Group root1 = createRoot(WorkflowPolicy::StopOnError); QTest::newRow("StopGroupWithStopOnError") - << TestData{storage, root1, log, 2, OnDone::Failure}; + << TestData{storage, root1, log, 2, DoneWith::Error}; const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); QTest::newRow("StopGroupWithContinueOnError") - << TestData{storage, root2, log, 2, OnDone::Failure}; + << TestData{storage, root2, log, 2, DoneWith::Error}; const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); QTest::newRow("StopGroupWithStopOnSuccess") - << TestData{storage, root3, log, 2, OnDone::Failure}; + << TestData{storage, root3, log, 2, DoneWith::Error}; const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); QTest::newRow("StopGroupWithContinueOnSuccess") - << TestData{storage, root4, log, 2, OnDone::Failure}; + << TestData{storage, root4, log, 2, DoneWith::Error}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("StopGroupWithStopOnFinished") - << TestData{storage, root5, log, 2, OnDone::Failure}; + << TestData{storage, root5, log, 2, DoneWith::Error}; // TODO: Behavioral change! Fix Docs! // Cancellation always invokes error handler (i.e. DoneWith is Canceled) const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); QTest::newRow("StopGroupWithFinishAllAndSuccess") - << TestData{storage, root6, log, 2, OnDone::Failure}; + << TestData{storage, root6, log, 2, DoneWith::Error}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); QTest::newRow("StopGroupWithFinishAllAndError") - << TestData{storage, root7, log, 2, OnDone::Failure}; + << TestData{storage, root7, log, 2, DoneWith::Error}; } { @@ -1351,33 +1348,33 @@ void tst_Tasking::testTree_data() const Group root1 = createRoot(WorkflowPolicy::StopOnError); QTest::newRow("StopGroupAfterDoneWithStopOnError") - << TestData{storage, root1, errorLog, 3, OnDone::Failure}; + << TestData{storage, root1, errorLog, 3, DoneWith::Error}; const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); QTest::newRow("StopGroupAfterDoneWithContinueOnError") - << TestData{storage, root2, errorLog, 3, OnDone::Failure}; + << TestData{storage, root2, errorLog, 3, DoneWith::Error}; const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); QTest::newRow("StopGroupAfterDoneWithStopOnSuccess") - << TestData{storage, root3, doneLog, 3, OnDone::Failure}; + << TestData{storage, root3, doneLog, 3, DoneWith::Error}; // TODO: Behavioral change! const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); QTest::newRow("StopGroupAfterDoneWithContinueOnSuccess") - << TestData{storage, root4, errorLog, 3, OnDone::Failure}; + << TestData{storage, root4, errorLog, 3, DoneWith::Error}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("StopGroupAfterDoneWithStopOnFinished") - << TestData{storage, root5, doneLog, 3, OnDone::Failure}; + << TestData{storage, root5, doneLog, 3, DoneWith::Error}; // TODO: Behavioral change! const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); QTest::newRow("StopGroupAfterDoneWithFinishAllAndSuccess") - << TestData{storage, root6, errorLog, 3, OnDone::Failure}; + << TestData{storage, root6, errorLog, 3, DoneWith::Error}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); QTest::newRow("StopGroupAfterDoneWithFinishAllAndError") - << TestData{storage, root7, errorLog, 3, OnDone::Failure}; + << TestData{storage, root7, errorLog, 3, DoneWith::Error}; } { @@ -1422,32 +1419,32 @@ void tst_Tasking::testTree_data() const Group root1 = createRoot(WorkflowPolicy::StopOnError); QTest::newRow("StopGroupAfterErrorWithStopOnError") - << TestData{storage, root1, shortLog, 3, OnDone::Failure}; + << TestData{storage, root1, shortLog, 3, DoneWith::Error}; const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); QTest::newRow("StopGroupAfterErrorWithContinueOnError") - << TestData{storage, root2, longLog, 3, OnDone::Failure}; + << TestData{storage, root2, longLog, 3, DoneWith::Error}; const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); QTest::newRow("StopGroupAfterErrorWithStopOnSuccess") - << TestData{storage, root3, longLog, 3, OnDone::Failure}; + << TestData{storage, root3, longLog, 3, DoneWith::Error}; const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); QTest::newRow("StopGroupAfterErrorWithContinueOnSuccess") - << TestData{storage, root4, longLog, 3, OnDone::Failure}; + << TestData{storage, root4, longLog, 3, DoneWith::Error}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); QTest::newRow("StopGroupAfterErrorWithStopOnFinished") - << TestData{storage, root5, shortLog, 3, OnDone::Failure}; + << TestData{storage, root5, shortLog, 3, DoneWith::Error}; // TODO: Behavioral change! const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); QTest::newRow("StopGroupAfterErrorWithFinishAllAndSuccess") - << TestData{storage, root6, longLog, 3, OnDone::Failure}; + << TestData{storage, root6, longLog, 3, DoneWith::Error}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); QTest::newRow("StopGroupAfterErrorWithFinishAllAndError") - << TestData{storage, root7, longLog, 3, OnDone::Failure}; + << TestData{storage, root7, longLog, 3, DoneWith::Error}; } { @@ -1471,7 +1468,7 @@ void tst_Tasking::testTree_data() {2, Handler::Error}, {0, Handler::GroupError} }; - QTest::newRow("StopOnError") << TestData{storage, root1, log1, 3, OnDone::Failure}; + QTest::newRow("StopOnError") << TestData{storage, root1, log1, 3, DoneWith::Error}; const Group root2 = createRoot(WorkflowPolicy::ContinueOnError); const Log errorLog { @@ -1483,7 +1480,7 @@ void tst_Tasking::testTree_data() {3, Handler::Success}, {0, Handler::GroupError} }; - QTest::newRow("ContinueOnError") << TestData{storage, root2, errorLog, 3, OnDone::Failure}; + QTest::newRow("ContinueOnError") << TestData{storage, root2, errorLog, 3, DoneWith::Error}; const Group root3 = createRoot(WorkflowPolicy::StopOnSuccess); const Log log3 { @@ -1491,7 +1488,7 @@ void tst_Tasking::testTree_data() {1, Handler::Success}, {0, Handler::GroupSuccess} }; - QTest::newRow("StopOnSuccess") << TestData{storage, root3, log3, 3, OnDone::Success}; + QTest::newRow("StopOnSuccess") << TestData{storage, root3, log3, 3, DoneWith::Success}; const Group root4 = createRoot(WorkflowPolicy::ContinueOnSuccess); const Log doneLog { @@ -1503,7 +1500,7 @@ void tst_Tasking::testTree_data() {3, Handler::Success}, {0, Handler::GroupSuccess} }; - QTest::newRow("ContinueOnSuccess") << TestData{storage, root4, doneLog, 3, OnDone::Success}; + QTest::newRow("ContinueOnSuccess") << TestData{storage, root4, doneLog, 3, DoneWith::Success}; const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); const Log log5 { @@ -1511,13 +1508,13 @@ void tst_Tasking::testTree_data() {1, Handler::Success}, {0, Handler::GroupSuccess} }; - QTest::newRow("StopOnFinished") << TestData{storage, root5, log5, 3, OnDone::Success}; + QTest::newRow("StopOnFinished") << TestData{storage, root5, log5, 3, DoneWith::Success}; const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); - QTest::newRow("FinishAllAndSuccess") << TestData{storage, root6, doneLog, 3, OnDone::Success}; + QTest::newRow("FinishAllAndSuccess") << TestData{storage, root6, doneLog, 3, DoneWith::Success}; const Group root7 = createRoot(WorkflowPolicy::FinishAllAndError); - QTest::newRow("FinishAllAndError") << TestData{storage, root7, errorLog, 3, OnDone::Failure}; + QTest::newRow("FinishAllAndError") << TestData{storage, root7, errorLog, 3, DoneWith::Error}; } { @@ -1553,10 +1550,10 @@ void tst_Tasking::testTree_data() {0, Handler::GroupError} }; - QTest::newRow("StopOnFinished1") << TestData{storage, root1, success, 2, OnDone::Success}; - QTest::newRow("StopOnFinished2") << TestData{storage, root2, failure, 2, OnDone::Failure}; - QTest::newRow("StopOnFinished3") << TestData{storage, root3, success, 2, OnDone::Success}; - QTest::newRow("StopOnFinished4") << TestData{storage, root4, failure, 2, OnDone::Failure}; + QTest::newRow("StopOnFinished1") << TestData{storage, root1, success, 2, DoneWith::Success}; + QTest::newRow("StopOnFinished2") << TestData{storage, root2, failure, 2, DoneWith::Error}; + QTest::newRow("StopOnFinished3") << TestData{storage, root3, success, 2, DoneWith::Success}; + QTest::newRow("StopOnFinished4") << TestData{storage, root4, failure, 2, DoneWith::Error}; } { @@ -1580,7 +1577,7 @@ void tst_Tasking::testTree_data() {0, Handler::GroupSuccess} }; QTest::newRow("GroupSetupTweakToSuccess") - << TestData{storage, root1, log1, 1, OnDone::Success}; + << TestData{storage, root1, log1, 1, DoneWith::Success}; const Group root2 = createRoot(SetupResult::StopWithError); const Log log2 { @@ -1589,7 +1586,7 @@ void tst_Tasking::testTree_data() {0, Handler::GroupError} }; QTest::newRow("GroupSetupTweakToError") - << TestData{storage, root2, log2, 1, OnDone::Failure}; + << TestData{storage, root2, log2, 1, DoneWith::Error}; const Group root3 = createRoot(SetupResult::Continue); const Log log3 { @@ -1600,7 +1597,7 @@ void tst_Tasking::testTree_data() {0, Handler::GroupSuccess} }; QTest::newRow("GroupSetupTweakToContinue") - << TestData{storage, root3, log3, 1, OnDone::Success}; + << TestData{storage, root3, log3, 1, DoneWith::Success}; } { @@ -1626,7 +1623,7 @@ void tst_Tasking::testTree_data() {0, Handler::GroupSuccess} }; QTest::newRow("GroupDoneWithSuccessTweakToSuccess") - << TestData{storage, root1, log1, 1, OnDone::Success}; + << TestData{storage, root1, log1, 1, DoneWith::Success}; const Group root2 = createRoot(DoneResult::Success, DoneResult::Error); const Log log2 { @@ -1637,7 +1634,7 @@ void tst_Tasking::testTree_data() {0, Handler::GroupError} }; QTest::newRow("GroupDoneWithSuccessTweakToError") - << TestData{storage, root2, log2, 1, OnDone::Failure}; + << TestData{storage, root2, log2, 1, DoneWith::Error}; const Group root3 = createRoot(DoneResult::Error, DoneResult::Success); const Log log3 { @@ -1648,7 +1645,7 @@ void tst_Tasking::testTree_data() {0, Handler::GroupSuccess} }; QTest::newRow("GroupDoneWithErrorTweakToSuccess") - << TestData{storage, root3, log3, 1, OnDone::Success}; + << TestData{storage, root3, log3, 1, DoneWith::Success}; const Group root4 = createRoot(DoneResult::Error, DoneResult::Error); const Log log4 { @@ -1659,7 +1656,7 @@ void tst_Tasking::testTree_data() {0, Handler::GroupError} }; QTest::newRow("GroupDoneWithErrorTweakToError") - << TestData{storage, root4, log4, 1, OnDone::Failure}; + << TestData{storage, root4, log4, 1, DoneWith::Error}; } { @@ -1685,7 +1682,7 @@ void tst_Tasking::testTree_data() {0, Handler::GroupSuccess} }; QTest::newRow("TaskSetupTweakToSuccess") - << TestData{storage, root1, log1, 2, OnDone::Success}; + << TestData{storage, root1, log1, 2, DoneWith::Success}; const Group root2 = createRoot(SetupResult::StopWithError); const Log log2 { @@ -1694,7 +1691,7 @@ void tst_Tasking::testTree_data() {0, Handler::GroupError} }; QTest::newRow("TaskSetupTweakToError") - << TestData{storage, root2, log2, 2, OnDone::Failure}; + << TestData{storage, root2, log2, 2, DoneWith::Error}; const Group root3 = createRoot(SetupResult::Continue); const Log log3 { @@ -1706,7 +1703,7 @@ void tst_Tasking::testTree_data() {0, Handler::GroupSuccess} }; QTest::newRow("TaskSetupTweakToContinue") - << TestData{storage, root3, log3, 2, OnDone::Success}; + << TestData{storage, root3, log3, 2, DoneWith::Success}; } { @@ -1744,7 +1741,7 @@ void tst_Tasking::testTree_data() {3, Handler::Success}, {4, Handler::Success} }; - QTest::newRow("NestedParallel") << TestData{storage, root, log, 4, OnDone::Success}; + QTest::newRow("NestedParallel") << TestData{storage, root, log, 4, DoneWith::Success}; } { @@ -1789,7 +1786,7 @@ void tst_Tasking::testTree_data() {4, Handler::Success}, {5, Handler::Success} }; - QTest::newRow("NestedParallelDone") << TestData{storage, root, log, 5, OnDone::Success}; + QTest::newRow("NestedParallelDone") << TestData{storage, root, log, 5, DoneWith::Success}; } { @@ -1919,11 +1916,11 @@ void tst_Tasking::testTree_data() {5, Handler::Success} }; QTest::newRow("NestedParallelError1") - << TestData{storage, root1, log1, 5, OnDone::Failure}; + << TestData{storage, root1, log1, 5, DoneWith::Error}; QTest::newRow("NestedParallelError2") - << TestData{storage, root2, log2, 5, OnDone::Failure}; + << TestData{storage, root2, log2, 5, DoneWith::Error}; QTest::newRow("NestedParallelError3") - << TestData{storage, root3, log3, 5, OnDone::Failure}; + << TestData{storage, root3, log3, 5, DoneWith::Error}; } { @@ -1973,7 +1970,7 @@ void tst_Tasking::testTree_data() {3, Handler::Success}, {4, Handler::Success} }; - QTest::newRow("DeeplyNestedParallel") << TestData{storage, root, log, 4, OnDone::Success}; + QTest::newRow("DeeplyNestedParallel") << TestData{storage, root, log, 4, DoneWith::Success}; } { @@ -2019,7 +2016,7 @@ void tst_Tasking::testTree_data() {5, Handler::Success} }; QTest::newRow("DeeplyNestedParallelSuccess") - << TestData{storage, root, log, 5, OnDone::Success}; + << TestData{storage, root, log, 5, DoneWith::Success}; } { @@ -2059,7 +2056,7 @@ void tst_Tasking::testTree_data() {2, Handler::Canceled} }; QTest::newRow("DeeplyNestedParallelError") - << TestData{storage, root, log, 5, OnDone::Failure}; + << TestData{storage, root, log, 5, DoneWith::Error}; } { @@ -2078,7 +2075,7 @@ void tst_Tasking::testTree_data() {4, Handler::Sync}, {5, Handler::Sync} }; - QTest::newRow("SyncSequential") << TestData{storage, root, log, 0, OnDone::Success}; + QTest::newRow("SyncSequential") << TestData{storage, root, log, 0, DoneWith::Success}; } { @@ -2102,7 +2099,7 @@ void tst_Tasking::testTree_data() {5, Handler::Sync}, {5, Handler::TweakDoneToSuccess} }; - QTest::newRow("SyncWithReturn") << TestData{storage, root, log, 0, OnDone::Success}; + QTest::newRow("SyncWithReturn") << TestData{storage, root, log, 0, DoneWith::Success}; } { @@ -2122,7 +2119,7 @@ void tst_Tasking::testTree_data() {4, Handler::Sync}, {5, Handler::Sync} }; - QTest::newRow("SyncParallel") << TestData{storage, root, log, 0, OnDone::Success}; + QTest::newRow("SyncParallel") << TestData{storage, root, log, 0, DoneWith::Success}; } { @@ -2141,7 +2138,7 @@ void tst_Tasking::testTree_data() {3, Handler::Sync}, {3, Handler::TweakDoneToError} }; - QTest::newRow("SyncError") << TestData{storage, root, log, 0, OnDone::Failure}; + QTest::newRow("SyncError") << TestData{storage, root, log, 0, DoneWith::Error}; } { @@ -2164,7 +2161,7 @@ void tst_Tasking::testTree_data() {5, Handler::Sync}, {0, Handler::GroupSuccess} }; - QTest::newRow("SyncAndAsync") << TestData{storage, root, log, 2, OnDone::Success}; + QTest::newRow("SyncAndAsync") << TestData{storage, root, log, 2, DoneWith::Success}; } { @@ -2185,7 +2182,7 @@ void tst_Tasking::testTree_data() {3, Handler::TweakDoneToError}, {0, Handler::GroupError} }; - QTest::newRow("SyncAndAsyncError") << TestData{storage, root, log, 2, OnDone::Failure}; + QTest::newRow("SyncAndAsyncError") << TestData{storage, root, log, 2, DoneWith::Error}; } { @@ -2336,15 +2333,15 @@ void tst_Tasking::testTree_data() // Notice the different log order for each scenario. QTest::newRow("BarrierSequential") - << TestData{storage, root1, log1, 4, OnDone::Success}; + << TestData{storage, root1, log1, 4, DoneWith::Success}; QTest::newRow("BarrierParallelAdvanceFirst") - << TestData{storage, root2, log2, 4, OnDone::Success}; + << TestData{storage, root2, log2, 4, DoneWith::Success}; QTest::newRow("BarrierParallelWaitForFirst") - << TestData{storage, root3, log3, 4, OnDone::Success}; + << TestData{storage, root3, log3, 4, DoneWith::Success}; QTest::newRow("BarrierParallelMultiWaitFor") - << TestData{storage, root4, log4, 5, OnDone::Success}; + << TestData{storage, root4, log4, 5, DoneWith::Success}; QTest::newRow("BarrierParallelTwoSingleBarriers") - << TestData{storage, root5, log5, 5, OnDone::Success}; + << TestData{storage, root5, log5, 5, DoneWith::Success}; } { @@ -2476,13 +2473,13 @@ void tst_Tasking::testTree_data() // Notice the different log order for each scenario. QTest::newRow("MultiBarrierSequential") - << TestData{storage, root1, log1, 5, OnDone::Success}; + << TestData{storage, root1, log1, 5, DoneWith::Success}; QTest::newRow("MultiBarrierParallelAdvanceFirst") - << TestData{storage, root2, log2, 5, OnDone::Success}; + << TestData{storage, root2, log2, 5, DoneWith::Success}; QTest::newRow("MultiBarrierParallelWaitForFirst") - << TestData{storage, root3, log3, 5, OnDone::Success}; + << TestData{storage, root3, log3, 5, DoneWith::Success}; QTest::newRow("MultiBarrierParallelMultiWaitFor") - << TestData{storage, root4, log4, 6, OnDone::Success}; + << TestData{storage, root4, log4, 6, DoneWith::Success}; } { @@ -2499,7 +2496,7 @@ void tst_Tasking::testTree_data() {1, Handler::Canceled} }; QTest::newRow("TaskErrorWithTimeout") << TestData{storage, root1, log1, 2, - OnDone::Failure}; + DoneWith::Error}; const Group root2 { Storage(storage), @@ -2512,7 +2509,7 @@ void tst_Tasking::testTree_data() {1, Handler::Canceled} }; QTest::newRow("TaskErrorWithTimeoutHandler") << TestData{storage, root2, log2, 2, - OnDone::Failure}; + DoneWith::Error}; const Group root3 { Storage(storage), @@ -2524,7 +2521,7 @@ void tst_Tasking::testTree_data() {1, Handler::Success} }; QTest::newRow("TaskDoneWithTimeout") << TestData{storage, root3, doneLog, 2, - OnDone::Success}; + DoneWith::Success}; const Group root4 { Storage(storage), @@ -2532,7 +2529,7 @@ void tst_Tasking::testTree_data() .withTimeout(1000ms, setupTimeout(1)) }; QTest::newRow("TaskDoneWithTimeoutHandler") << TestData{storage, root4, doneLog, 2, - OnDone::Success}; + DoneWith::Success}; } { @@ -2550,7 +2547,7 @@ void tst_Tasking::testTree_data() {1, Handler::Canceled} }; QTest::newRow("GroupErrorWithTimeout") << TestData{storage, root1, log1, 2, - OnDone::Failure}; + DoneWith::Error}; // Test Group::withTimeout(), passing custom handler const Group root2 { @@ -2565,7 +2562,7 @@ void tst_Tasking::testTree_data() {1, Handler::Canceled} }; QTest::newRow("GroupErrorWithTimeoutHandler") << TestData{storage, root2, log2, 2, - OnDone::Failure}; + DoneWith::Error}; const Group root3 { Storage(storage), @@ -2578,7 +2575,7 @@ void tst_Tasking::testTree_data() {1, Handler::Success} }; QTest::newRow("GroupDoneWithTimeout") << TestData{storage, root3, doneLog, 2, - OnDone::Success}; + DoneWith::Success}; // Test Group::withTimeout(), passing custom handler const Group root4 { @@ -2588,7 +2585,7 @@ void tst_Tasking::testTree_data() }.withTimeout(1000ms, setupTimeout(1)) }; QTest::newRow("GroupDoneWithTimeoutHandler") << TestData{storage, root4, doneLog, 2, - OnDone::Success}; + DoneWith::Success}; } { @@ -2608,7 +2605,7 @@ void tst_Tasking::testTree() actualLog = storage.m_log; }; taskTree.onStorageDone(testData.storage, collectLog); - const OnDone result = taskTree.runBlocking() ? OnDone::Success : OnDone::Failure; + const DoneWith result = taskTree.runBlocking(); QCOMPARE(taskTree.isRunning(), false); QCOMPARE(taskTree.progressValue(), taskTree.progressMaximum()); @@ -2652,8 +2649,7 @@ static void runInThread(QPromise &promise, const TestData &testData) }; taskTree.onStorageDone(testData.storage, collectLog); - const OnDone result = taskTree.runBlocking(QFuture(promise.future())) - ? OnDone::Success : OnDone::Failure; + const DoneWith result = taskTree.runBlocking(QFuture(promise.future())); if (taskTree.isRunning()) { promise.addResult(TestResult{i, ThreadResult::FailOnRunningCheck}); @@ -2694,7 +2690,7 @@ void tst_Tasking::testInThread() tasks.append(ConcurrentCallTask(onSetup, onDone)); TaskTree taskTree(Group{tasks}); - const OnDone result = taskTree.runBlocking() ? OnDone::Success : OnDone::Failure; + const DoneWith result = taskTree.runBlocking(); QCOMPARE(taskTree.isRunning(), false); QCOMPARE(CustomStorage::instanceCount(), 0); diff --git a/tests/auto/utils/async/tst_async.cpp b/tests/auto/utils/async/tst_async.cpp index 82e1abf730d..2f12ec7cc47 100644 --- a/tests/auto/utils/async/tst_async.cpp +++ b/tests/auto/utils/async/tst_async.cpp @@ -441,7 +441,7 @@ void tst_Async::taskTree() }; - QVERIFY(TaskTree::runBlocking(root, 1000ms)); + QCOMPARE(TaskTree::runBlocking(root, 1000ms), DoneWith::Success); QCOMPARE(value, 16); } @@ -577,7 +577,7 @@ void tst_Async::mapReduce() QFETCH(double, sum); QFETCH(QList, results); - QVERIFY(TaskTree::runBlocking(root, 1000ms)); + QCOMPARE(TaskTree::runBlocking(root, 1000ms), DoneWith::Success); QCOMPARE(s_results, results); QCOMPARE(s_sum, sum); } From 89ab44c32dbf91b449ee468e7e27d684d65b6a09 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 7 Nov 2023 00:28:06 +0100 Subject: [PATCH 0107/1546] TaskTree: Hide Storage internals in cpp Change-Id: Iaa37aabd7e982302569291612b21a879da11c1a1 Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 117 +++++++++++++++--------- src/libs/solutions/tasking/tasktree.h | 50 ++-------- 2 files changed, 80 insertions(+), 87 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index e9628a7f9bf..39ef90839b1 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -5,11 +5,15 @@ #include #include +#include +#include #include #include #include #include +#include + using namespace std::chrono; namespace Tasking { @@ -842,23 +846,64 @@ static DoneResult toDoneResult(DoneWith doneWith) return doneWith == DoneWith::Success ? DoneResult::Success : DoneResult::Error; } -bool TreeStorageBase::isValid() const +class StorageThreadData { - return m_storageData && m_storageData->m_constructor && m_storageData->m_destructor; -} + Q_DISABLE_COPY_MOVE(StorageThreadData) -TreeStorageBase::TreeStorageBase(StorageConstructor ctor, StorageDestructor dtor) - : m_storageData(new StorageData{ctor, dtor}) -{} +public: + StorageThreadData(StorageData *storageData); + ~StorageThreadData(); -TreeStorageBase::ThreadData::ThreadData(TreeStorageBase::StorageData *storageData) + int createStorage(); + bool deleteStorage(int id); // Returns true if it was the last storage. + + void activateStorage(int id); + + void *activeStorageVoid() const; + int activeStorageId() const { return m_activeStorage; } + +private: + StorageData *m_storageData = nullptr; + QHash m_storageHash; + int m_activeStorage = 0; // 0 means no active storage. +}; + +class StorageData +{ +public: + ~StorageData(); + StorageThreadData &threadData() { + QMutexLocker lock(&m_threadDataMutex); + return m_threadDataMap.emplace(QThread::currentThread(), this).first->second; + } + + void deleteStorage(int id) + { + if (!threadData().deleteStorage(id)) + return; + + QMutexLocker lock(&m_threadDataMutex); + m_threadDataMap.erase( + m_threadDataMap.find(QThread::currentThread())); + } + + const TreeStorageBase::StorageConstructor m_constructor = {}; + const TreeStorageBase::StorageDestructor m_destructor = {}; + QMutex m_threadDataMutex = {}; + // Use std::map on purpose, so that it doesn't invalidate references on modifications. + // Don't optimize it by using std::unordered_map. + std::map m_threadDataMap = {}; + std::atomic_int m_storageInstanceCounter = 0; // Bumped on each creation. +}; + +StorageThreadData::StorageThreadData(StorageData *storageData) : m_storageData(storageData) { QTC_CHECK(m_storageData->m_constructor); QTC_CHECK(m_storageData->m_destructor); } -TreeStorageBase::ThreadData::~ThreadData() +StorageThreadData::~StorageThreadData() { QTC_CHECK(m_storageHash.isEmpty()); // TODO: Issue a warning about the leak instead? @@ -866,7 +911,7 @@ TreeStorageBase::ThreadData::~ThreadData() m_storageData->m_destructor(ptr); } -int TreeStorageBase::ThreadData::createStorage() +int StorageThreadData::createStorage() { QTC_ASSERT(m_activeStorage == 0, return 0); // TODO: should be allowed? const int newId = m_storageData->m_storageInstanceCounter.fetch_add(1) + 1; @@ -874,7 +919,7 @@ int TreeStorageBase::ThreadData::createStorage() return newId; } -bool TreeStorageBase::ThreadData::deleteStorage(int id) +bool StorageThreadData::deleteStorage(int id) { QTC_ASSERT(m_activeStorage == 0, return false); // TODO: should be allowed? const auto it = m_storageHash.constFind(id); @@ -884,24 +929,8 @@ bool TreeStorageBase::ThreadData::deleteStorage(int id) return m_storageHash.empty(); } -int TreeStorageBase::createStorage() const -{ - return threadData().createStorage(); -} - -void TreeStorageBase::deleteStorage(int id) const -{ - if (!threadData().deleteStorage(id)) - return; - - QMutexLocker lock(&m_storageData->m_threadDataMutex); - m_storageData->m_threadDataMap.erase( - m_storageData->m_threadDataMap.find(QThread::currentThread())); -} - - // passing 0 deactivates currently active storage -void TreeStorageBase::ThreadData::activateStorage(int id) +void StorageThreadData::activateStorage(int id) { if (id == 0) { QTC_ASSERT(m_activeStorage, return); @@ -915,7 +944,7 @@ void TreeStorageBase::ThreadData::activateStorage(int id) m_activeStorage = id; } -void *TreeStorageBase::ThreadData::activeStorageVoid() const +void *StorageThreadData::activeStorageVoid() const { QTC_ASSERT(m_activeStorage, qWarning( "The referenced storage is not reachable in the running tree. " @@ -927,22 +956,24 @@ void *TreeStorageBase::ThreadData::activeStorageVoid() const return it.value(); } -int TreeStorageBase::ThreadData::activeStorageId() const -{ - return m_activeStorage; -} - -TreeStorageBase::StorageData::~StorageData() +StorageData::~StorageData() { QMutexLocker lock(&m_threadDataMutex); QTC_CHECK(m_threadDataMap.empty()); } -TreeStorageBase::ThreadData &TreeStorageBase::threadData() const +bool TreeStorageBase::isValid() const { - QMutexLocker lock(&m_storageData->m_threadDataMutex); - return m_storageData->m_threadDataMap.emplace(QThread::currentThread(), - m_storageData.get()).first->second; + return m_storageData && m_storageData->m_constructor && m_storageData->m_destructor; +} + +TreeStorageBase::TreeStorageBase(StorageConstructor ctor, StorageDestructor dtor) + : m_storageData(new StorageData{ctor, dtor}) +{} + +void *TreeStorageBase::activeStorageVoid() const +{ + return m_storageData->threadData().activeStorageVoid(); } void GroupItem::addChildren(const QList &children) @@ -1058,7 +1089,7 @@ public: const StorageHandler storageHandler = *it; // TODO: we don't necessarily need to activate the storage here, it's enough to // get a pointer to the relevant storage instance. - auto &threadData = storage.threadData(); + auto &threadData = storage.m_storageData->threadData(); threadData.activateStorage(storageId); if (storageHandler.*ptr) (storageHandler.*ptr)(threadData.activeStorageVoid()); @@ -1212,7 +1243,7 @@ public: ExecutionContextActivator(TaskContainer *container) { activateContext(container); } ~ExecutionContextActivator() { for (int i = m_activeStorages.size() - 1; i >= 0; --i) // iterate in reverse order - m_activeStorages[i].threadData().activateStorage(0); + m_activeStorages[i].m_storageData->threadData().activateStorage(0); } private: @@ -1222,7 +1253,7 @@ private: const TaskContainer::ConstData &constData = container->m_constData; for (int i = 0; i < constData.m_storageList.size(); ++i) { const TreeStorageBase &storage = constData.m_storageList[i]; - auto &threadData = storage.threadData(); + auto &threadData = storage.m_storageData->threadData(); if (threadData.activeStorageId()) continue; // Storage shadowing: The storage is already active, skipping it... m_activeStorages.append(storage); @@ -1276,7 +1307,7 @@ QList TaskContainer::RuntimeData::createStorages(const TaskContainer::Const { QList storageIdList; for (const TreeStorageBase &storage : constData.m_storageList) { - const int storageId = storage.createStorage(); + const int storageId = storage.m_storageData->threadData().createStorage(); storageIdList.append(storageId); constData.m_taskTreePrivate->callSetupHandler(storage, storageId); } @@ -1313,7 +1344,7 @@ TaskContainer::RuntimeData::~RuntimeData() const int storageId = m_storageIdList.value(i); if (m_callStorageDoneHandlersOnDestruction) m_constData.m_taskTreePrivate->callDoneHandler(storage, storageId); - storage.deleteStorage(storageId); + storage.m_storageData->deleteStorage(storageId); } } diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index fa9edd3b6e0..deef203daf9 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -5,12 +5,9 @@ #include "tasking_global.h" -#include -#include #include #include -#include #include QT_BEGIN_NAMESPACE @@ -23,6 +20,7 @@ namespace Tasking { Q_NAMESPACE_EXPORT(TASKING_EXPORT) class ExecutionContextActivator; +class StorageData; class TaskContainer; class TaskTreePrivate; @@ -46,40 +44,15 @@ protected: class TASKING_EXPORT TreeStorageBase { public: - bool isValid() const; - -private: using StorageConstructor = std::function; using StorageDestructor = std::function; + bool isValid() const; + +private: TreeStorageBase(StorageConstructor ctor, StorageDestructor dtor); - struct StorageData; - - struct TASKING_EXPORT ThreadData - { - Q_DISABLE_COPY_MOVE(ThreadData) - - ThreadData(StorageData *storageData); - ~ThreadData(); - - int createStorage(); - bool deleteStorage(int id); // Returns true if it was the last storage. - - void activateStorage(int id); - - void *activeStorageVoid() const; - int activeStorageId() const; - - private: - StorageData *m_storageData = nullptr; - QHash m_storageHash; - int m_activeStorage = 0; // 0 means no active storage. - }; - - ThreadData &threadData() const; - int createStorage() const; - void deleteStorage(int id) const; + void *activeStorageVoid() const; friend bool operator==(const TreeStorageBase &first, const TreeStorageBase &second) { return first.m_storageData == second.m_storageData; } @@ -90,17 +63,6 @@ private: friend size_t qHash(const TreeStorageBase &storage, uint seed = 0) { return size_t(storage.m_storageData.get()) ^ seed; } - struct StorageData - { - ~StorageData(); - const StorageConstructor m_constructor = {}; - const StorageDestructor m_destructor = {}; - QMutex m_threadDataMutex = {}; - // Use std::map on purpose, so that it doesn't invalidate references on modifications. - // Don't optimize it by using std::unordered_map. - std::map m_threadDataMap = {}; - std::atomic_int m_storageInstanceCounter = 0; // Bumped on each creation. - }; QSharedPointer m_storageData; template friend class TreeStorage; @@ -117,7 +79,7 @@ public: StorageStruct &operator*() const noexcept { return *activeStorage(); } StorageStruct *operator->() const noexcept { return activeStorage(); } StorageStruct *activeStorage() const { - return static_cast(threadData().activeStorageVoid()); // HERE + return static_cast(activeStorageVoid()); } private: From c50f9aa45e80969ae50944d51e8580d778fa2ad3 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 7 Nov 2023 00:58:03 +0100 Subject: [PATCH 0108/1546] TaskTree: Reuse QT_STRINGIFY macro Replace QTC_ prefix with QT_ for internal macros. Change-Id: I650e15cd328747e88696a63c9929a6bf46fe9ab4 Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 128 ++++++++++++------------ 1 file changed, 63 insertions(+), 65 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 39ef90839b1..cb71f516eea 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -19,18 +19,16 @@ using namespace std::chrono; namespace Tasking { // That's cut down qtcassert.{c,h} to avoid the dependency. -#define QTC_STRINGIFY_HELPER(x) #x -#define QTC_STRINGIFY(x) QTC_STRINGIFY_HELPER(x) -#define QTC_STRING(cond) qDebug("SOFT ASSERT: \"%s\" in %s: %s", cond, __FILE__, QTC_STRINGIFY(__LINE__)) -#define QTC_ASSERT(cond, action) if (Q_LIKELY(cond)) {} else { QTC_STRING(#cond); action; } do {} while (0) -#define QTC_CHECK(cond) if (cond) {} else { QTC_STRING(#cond); } do {} while (0) +#define QT_STRING(cond) qDebug("SOFT ASSERT: \"%s\" in %s: %s", cond, __FILE__, QT_STRINGIFY(__LINE__)) +#define QT_ASSERT(cond, action) if (Q_LIKELY(cond)) {} else { QT_STRING(#cond); action; } do {} while (0) +#define QT_CHECK(cond) if (cond) {} else { QT_STRING(#cond); } do {} while (0) class Guard { Q_DISABLE_COPY(Guard) public: Guard() = default; - ~Guard() { QTC_CHECK(m_lockCount == 0); } + ~Guard() { QT_CHECK(m_lockCount == 0); } bool isLocked() const { return m_lockCount; } private: int m_lockCount = 0; @@ -899,13 +897,13 @@ public: StorageThreadData::StorageThreadData(StorageData *storageData) : m_storageData(storageData) { - QTC_CHECK(m_storageData->m_constructor); - QTC_CHECK(m_storageData->m_destructor); + QT_CHECK(m_storageData->m_constructor); + QT_CHECK(m_storageData->m_destructor); } StorageThreadData::~StorageThreadData() { - QTC_CHECK(m_storageHash.isEmpty()); + QT_CHECK(m_storageHash.isEmpty()); // TODO: Issue a warning about the leak instead? for (void *ptr : std::as_const(m_storageHash)) m_storageData->m_destructor(ptr); @@ -913,7 +911,7 @@ StorageThreadData::~StorageThreadData() int StorageThreadData::createStorage() { - QTC_ASSERT(m_activeStorage == 0, return 0); // TODO: should be allowed? + QT_ASSERT(m_activeStorage == 0, return 0); // TODO: should be allowed? const int newId = m_storageData->m_storageInstanceCounter.fetch_add(1) + 1; m_storageHash.insert(newId, m_storageData->m_constructor()); return newId; @@ -921,9 +919,9 @@ int StorageThreadData::createStorage() bool StorageThreadData::deleteStorage(int id) { - QTC_ASSERT(m_activeStorage == 0, return false); // TODO: should be allowed? + QT_ASSERT(m_activeStorage == 0, return false); // TODO: should be allowed? const auto it = m_storageHash.constFind(id); - QTC_ASSERT(it != m_storageHash.constEnd(), return false); + QT_ASSERT(it != m_storageHash.constEnd(), return false); m_storageData->m_destructor(it.value()); m_storageHash.erase(it); return m_storageHash.empty(); @@ -933,33 +931,33 @@ bool StorageThreadData::deleteStorage(int id) void StorageThreadData::activateStorage(int id) { if (id == 0) { - QTC_ASSERT(m_activeStorage, return); + QT_ASSERT(m_activeStorage, return); m_activeStorage = 0; return; } - QTC_ASSERT(m_activeStorage == 0, return); + QT_ASSERT(m_activeStorage == 0, return); // TODO: Unneeded check? OTOH, it's quite important... const auto it = m_storageHash.find(id); - QTC_ASSERT(it != m_storageHash.end(), return); + QT_ASSERT(it != m_storageHash.end(), return); m_activeStorage = id; } void *StorageThreadData::activeStorageVoid() const { - QTC_ASSERT(m_activeStorage, qWarning( + QT_ASSERT(m_activeStorage, qWarning( "The referenced storage is not reachable in the running tree. " "A nullptr will be returned which might lead to a crash in the calling code. " "It is possible that no storage was added to the tree, " "or the storage is not reachable from where it is referenced."); return nullptr); const auto it = m_storageHash.constFind(m_activeStorage); - QTC_ASSERT(it != m_storageHash.constEnd(), return nullptr); + QT_ASSERT(it != m_storageHash.constEnd(), return nullptr); return it.value(); } StorageData::~StorageData() { QMutexLocker lock(&m_threadDataMutex); - QTC_CHECK(m_threadDataMap.empty()); + QT_CHECK(m_threadDataMap.empty()); } bool TreeStorageBase::isValid() const @@ -978,8 +976,8 @@ void *TreeStorageBase::activeStorageVoid() const void GroupItem::addChildren(const QList &children) { - QTC_ASSERT(m_type == Type::Group || m_type == Type::List, - qWarning("Only Group or List may have children, skipping..."); return); + QT_ASSERT(m_type == Type::Group || m_type == Type::List, + qWarning("Only Group or List may have children, skipping..."); return); if (m_type == Type::List) { m_children.append(children); return; @@ -994,39 +992,39 @@ void GroupItem::addChildren(const QList &children) break; case Type::GroupData: if (child.m_groupData.m_groupHandler.m_setupHandler) { - QTC_ASSERT(!m_groupData.m_groupHandler.m_setupHandler, - qWarning("Group setup handler redefinition, overriding...")); + QT_ASSERT(!m_groupData.m_groupHandler.m_setupHandler, + qWarning("Group setup handler redefinition, overriding...")); m_groupData.m_groupHandler.m_setupHandler = child.m_groupData.m_groupHandler.m_setupHandler; } if (child.m_groupData.m_groupHandler.m_doneHandler) { - QTC_ASSERT(!m_groupData.m_groupHandler.m_doneHandler, - qWarning("Group done handler redefinition, overriding...")); + QT_ASSERT(!m_groupData.m_groupHandler.m_doneHandler, + qWarning("Group done handler redefinition, overriding...")); m_groupData.m_groupHandler.m_doneHandler = child.m_groupData.m_groupHandler.m_doneHandler; } if (child.m_groupData.m_parallelLimit) { - QTC_ASSERT(!m_groupData.m_parallelLimit, - qWarning("Group execution mode redefinition, overriding...")); + QT_ASSERT(!m_groupData.m_parallelLimit, + qWarning("Group execution mode redefinition, overriding...")); m_groupData.m_parallelLimit = child.m_groupData.m_parallelLimit; } if (child.m_groupData.m_workflowPolicy) { - QTC_ASSERT(!m_groupData.m_workflowPolicy, - qWarning("Group workflow policy redefinition, overriding...")); + QT_ASSERT(!m_groupData.m_workflowPolicy, + qWarning("Group workflow policy redefinition, overriding...")); m_groupData.m_workflowPolicy = child.m_groupData.m_workflowPolicy; } break; case Type::TaskHandler: - QTC_ASSERT(child.m_taskHandler.m_createHandler, - qWarning("Task create handler can't be null, skipping..."); return); + QT_ASSERT(child.m_taskHandler.m_createHandler, + qWarning("Task create handler can't be null, skipping..."); return); m_children.append(child); break; case Type::Storage: // Check for duplicates, as can't have the same storage twice on the same level. for (const TreeStorageBase &storage : child.m_storageList) { if (m_storageList.contains(storage)) { - QTC_ASSERT(false, qWarning("Can't add the same storage into one Group twice, " - "skipping...")); + QT_ASSERT(false, qWarning("Can't add the same storage into one Group twice, " + "skipping...")); continue; } m_storageList.append(storage); @@ -1187,20 +1185,20 @@ private: void TaskTreePrivate::start() { - QTC_ASSERT(m_root, return); + QT_ASSERT(m_root, return); m_progressValue = 0; emitStartedAndProgress(); // TODO: check storage handlers for not existing storages in tree for (auto it = m_storageHandlers.cbegin(); it != m_storageHandlers.cend(); ++it) { - QTC_ASSERT(m_storages.contains(it.key()), qWarning("The registered storage doesn't " - "exist in task tree. Its handlers will never be called.")); + QT_ASSERT(m_storages.contains(it.key()), qWarning("The registered storage doesn't " + "exist in task tree. Its handlers will never be called.")); } m_root->start(); } void TaskTreePrivate::stop() { - QTC_ASSERT(m_root, return); + QT_ASSERT(m_root, return); if (!m_root->isRunning()) return; m_root->stop(); @@ -1211,8 +1209,8 @@ void TaskTreePrivate::advanceProgress(int byValue) { if (byValue == 0) return; - QTC_CHECK(byValue > 0); - QTC_CHECK(m_progressValue + byValue <= m_root->taskCount()); + QT_CHECK(byValue > 0); + QT_CHECK(m_progressValue + byValue <= m_root->taskCount()); m_progressValue += byValue; emitProgress(); } @@ -1232,7 +1230,7 @@ void TaskTreePrivate::emitProgress() void TaskTreePrivate::emitDone(DoneWith result) { - QTC_CHECK(m_progressValue == m_root->taskCount()); + QT_CHECK(m_progressValue == m_root->taskCount()); GuardLocker locker(m_guard); emit q->done(result); } @@ -1249,7 +1247,7 @@ public: private: void activateContext(TaskContainer *container) { - QTC_ASSERT(container && container->isRunning(), return); + QT_ASSERT(container && container->isRunning(), return); const TaskContainer::ConstData &constData = container->m_constData; for (int i = 0; i < constData.m_storageList.size(); ++i) { const TreeStorageBase &storage = constData.m_storageList[i]; @@ -1327,7 +1325,7 @@ static bool initialSuccessBit(WorkflowPolicy workflowPolicy) case WorkflowPolicy::FinishAllAndError: return false; } - QTC_CHECK(false); + QT_CHECK(false); return false; } @@ -1373,7 +1371,7 @@ int TaskContainer::RuntimeData::currentLimit() const SetupResult TaskContainer::start() { - QTC_CHECK(!isRunning()); + QT_CHECK(!isRunning()); m_runtimeData.emplace(m_constData); SetupResult startAction = SetupResult::Continue; @@ -1396,12 +1394,12 @@ SetupResult TaskContainer::continueStart(SetupResult startAction, int nextChild) { const SetupResult groupAction = startAction == SetupResult::Continue ? startChildren(nextChild) : startAction; - QTC_CHECK(isRunning()); // TODO: superfluous + QT_CHECK(isRunning()); // TODO: superfluous if (groupAction != SetupResult::Continue) { const bool bit = m_runtimeData->updateSuccessBit(groupAction == SetupResult::StopWithSuccess); const bool result = invokeDoneHandler(bit ? DoneWith::Success : DoneWith::Error); if (TaskContainer *parentContainer = m_constData.m_parentContainer) { - QTC_CHECK(parentContainer->isRunning()); + QT_CHECK(parentContainer->isRunning()); if (!parentContainer->isStarting()) parentContainer->childDone(result); } else { @@ -1413,7 +1411,7 @@ SetupResult TaskContainer::continueStart(SetupResult startAction, int nextChild) SetupResult TaskContainer::startChildren(int nextChild) { - QTC_CHECK(isRunning()); + QT_CHECK(isRunning()); GuardLocker locker(m_runtimeData->m_startGuard); for (int i = nextChild; i < m_constData.m_children.size(); ++i) { const int limit = m_runtimeData->currentLimit(); @@ -1440,7 +1438,7 @@ SetupResult TaskContainer::startChildren(int nextChild) SetupResult TaskContainer::childDone(bool success) { - QTC_CHECK(isRunning()); + QT_CHECK(isRunning()); const int limit = m_runtimeData->currentLimit(); // Read before bumping m_doneCount and stop() const bool shouldStop = m_constData.m_workflowPolicy == WorkflowPolicy::StopOnFinished || (m_constData.m_workflowPolicy == WorkflowPolicy::StopOnSuccess && success) @@ -1495,7 +1493,7 @@ bool TaskContainer::invokeDoneHandler(DoneWith doneWith) SetupResult TaskNode::start() { - QTC_CHECK(!isRunning()); + QT_CHECK(!isRunning()); if (!isTask()) return m_container.start(); @@ -1514,7 +1512,7 @@ SetupResult TaskNode::start() const bool result = invokeDoneHandler(success ? DoneWith::Success : DoneWith::Error); QObject::disconnect(m_task.get(), &TaskInterface::done, taskTree(), nullptr); m_task.release()->deleteLater(); - QTC_ASSERT(parentContainer() && parentContainer()->isRunning(), return); + QT_ASSERT(parentContainer() && parentContainer()->isRunning(), return); if (parentContainer()->isStarting()) *unwindAction = toSetupResult(result); else @@ -2228,8 +2226,8 @@ TaskTree::TaskTree(const Group &recipe) : TaskTree() */ TaskTree::~TaskTree() { - QTC_ASSERT(!d->m_guard.isLocked(), qWarning("Deleting TaskTree instance directly from " - "one of its handlers will lead to a crash!")); + QT_ASSERT(!d->m_guard.isLocked(), qWarning("Deleting TaskTree instance directly from " + "one of its handlers will lead to a crash!")); // TODO: delete storages explicitly here? delete d; } @@ -2245,9 +2243,9 @@ TaskTree::~TaskTree() */ void TaskTree::setRecipe(const Group &recipe) { - QTC_ASSERT(!isRunning(), qWarning("The TaskTree is already running, ignoring..."); return); - QTC_ASSERT(!d->m_guard.isLocked(), qWarning("The setRecipe() is called from one of the" - "TaskTree handlers, ignoring..."); return); + QT_ASSERT(!isRunning(), qWarning("The TaskTree is already running, ignoring..."); return); + QT_ASSERT(!d->m_guard.isLocked(), qWarning("The setRecipe() is called from one of the" + "TaskTree handlers, ignoring..."); return); // TODO: Should we clear the m_storageHandlers, too? d->m_storages.clear(); d->m_root.reset(new TaskNode(d, recipe, nullptr)); @@ -2281,9 +2279,9 @@ void TaskTree::setRecipe(const Group &recipe) */ void TaskTree::start() { - QTC_ASSERT(!isRunning(), qWarning("The TaskTree is already running, ignoring..."); return); - QTC_ASSERT(!d->m_guard.isLocked(), qWarning("The start() is called from one of the" - "TaskTree handlers, ignoring..."); return); + QT_ASSERT(!isRunning(), qWarning("The TaskTree is already running, ignoring..."); return); + QT_ASSERT(!d->m_guard.isLocked(), qWarning("The start() is called from one of the" + "TaskTree handlers, ignoring..."); return); d->start(); } @@ -2348,8 +2346,8 @@ void TaskTree::start() */ void TaskTree::stop() { - QTC_ASSERT(!d->m_guard.isLocked(), qWarning("The stop() is called from one of the" - "TaskTree handlers, ignoring..."); return); + QT_ASSERT(!d->m_guard.isLocked(), qWarning("The stop() is called from one of the" + "TaskTree handlers, ignoring..."); return); d->stop(); } @@ -2596,13 +2594,13 @@ void TaskTree::setupStorageHandler(const TreeStorageBase &storage, return; } if (setupHandler) { - QTC_ASSERT(!it->m_setupHandler, - qWarning("The storage has its setup handler defined, overriding...")); + QT_ASSERT(!it->m_setupHandler, + qWarning("The storage has its setup handler defined, overriding...")); it->m_setupHandler = setupHandler; } if (doneHandler) { - QTC_ASSERT(!it->m_doneHandler, - qWarning("The storage has its done handler defined, overriding...")); + QT_ASSERT(!it->m_doneHandler, + qWarning("The storage has its done handler defined, overriding...")); it->m_doneHandler = doneHandler; } } @@ -2660,14 +2658,14 @@ static void removeTimerId(int timerId) { QMutexLocker lock(&s_mutex); const auto it = s_timerIdToTimerData.constFind(timerId); - QTC_ASSERT(it != s_timerIdToTimerData.cend(), - qWarning("Removing active timerId failed."); return); + QT_ASSERT(it != s_timerIdToTimerData.cend(), + qWarning("Removing active timerId failed."); return); const system_clock::time_point deadline = it->m_deadline; s_timerIdToTimerData.erase(it); const int removedCount = s_deadlineToTimerId.remove(deadline, timerId); - QTC_ASSERT(removedCount == 1, qWarning("Removing active timerId failed."); return); + QT_ASSERT(removedCount == 1, qWarning("Removing active timerId failed."); return); } static void handleTimeout(int timerId) From b98be3d5a046f983f0c0f02ef7a7343047729190 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 12 Oct 2023 14:17:17 +0200 Subject: [PATCH 0109/1546] FreezeDetector: Don't report nested calls to notify Report only top level, otherwise reports may overlap. Change-Id: I30c2b2ca6368bd43c68ce8275af2e58e0c6c12c5 Reviewed-by: Qt CI Bot Reviewed-by: hjk --- src/shared/qtsingleapplication/qtsingleapplication.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/shared/qtsingleapplication/qtsingleapplication.cpp b/src/shared/qtsingleapplication/qtsingleapplication.cpp index c38d568004c..ce91306c75f 100644 --- a/src/shared/qtsingleapplication/qtsingleapplication.cpp +++ b/src/shared/qtsingleapplication/qtsingleapplication.cpp @@ -182,13 +182,17 @@ public: void setFreezeTreshold(std::chrono::milliseconds freezeAbove) { m_threshold = freezeAbove; } bool notify(QObject *receiver, QEvent *event) override { + if (m_inNotify) + return QtSingleApplication::notify(receiver, event); using namespace std::chrono; const auto start = system_clock::now(); const QPointer p(receiver); const QString className = QLatin1String(receiver->metaObject()->className()); const QString name = receiver->objectName(); + m_inNotify = true; const bool ret = QtSingleApplication::notify(receiver, event); + m_inNotify = false; const auto end = system_clock::now(); const auto freeze = duration_cast(end - start); @@ -207,6 +211,7 @@ public: } private: + bool m_inNotify = false; const QString m_align; std::chrono::milliseconds m_threshold = std::chrono::milliseconds(100); }; From 3bf61cc36c5626df2d2e536e8066dedeb6160ef0 Mon Sep 17 00:00:00 2001 From: Artem Sokolovskii Date: Tue, 17 Oct 2023 16:08:52 +0200 Subject: [PATCH 0110/1546] DAP: Move to a unified way to handle breakpoints Rely on SetBreakpoints response instead of breakpoint event. Change-Id: Iff052a13c442fb1fcd945cf1a80f1354c43c15c5 Reviewed-by: hjk --- src/plugins/debugger/breakhandler.cpp | 2 +- src/plugins/debugger/dap/cmakedapengine.cpp | 31 +--- src/plugins/debugger/dap/cmakedapengine.h | 8 +- src/plugins/debugger/dap/dapclient.cpp | 2 + src/plugins/debugger/dap/dapclient.h | 1 + src/plugins/debugger/dap/dapengine.cpp | 150 +++++++++++++------- src/plugins/debugger/dap/dapengine.h | 2 +- src/plugins/debugger/dap/gdbdapengine.cpp | 5 + src/plugins/debugger/dap/gdbdapengine.h | 2 +- src/plugins/debugger/dap/pydapengine.cpp | 26 ---- src/plugins/debugger/dap/pydapengine.h | 5 - 11 files changed, 116 insertions(+), 118 deletions(-) diff --git a/src/plugins/debugger/breakhandler.cpp b/src/plugins/debugger/breakhandler.cpp index 53696f8e910..74626fbc863 100644 --- a/src/plugins/debugger/breakhandler.cpp +++ b/src/plugins/debugger/breakhandler.cpp @@ -1241,7 +1241,7 @@ static bool isAllowedTransition(BreakpointState from, BreakpointState to) void BreakpointItem::gotoState(BreakpointState target, BreakpointState assumedCurrent) { - QTC_ASSERT(m_state == assumedCurrent, qDebug() << m_state); + QTC_ASSERT(m_state == assumedCurrent, qDebug() << target << m_state); setState(target); } diff --git a/src/plugins/debugger/dap/cmakedapengine.cpp b/src/plugins/debugger/dap/cmakedapengine.cpp index 2c6400b0feb..3e7a23cb243 100644 --- a/src/plugins/debugger/dap/cmakedapengine.cpp +++ b/src/plugins/debugger/dap/cmakedapengine.cpp @@ -142,6 +142,11 @@ void CMakeDapEngine::setupEngine() }); } +bool CMakeDapEngine::acceptsBreakpoint(const BreakpointParameters &bp) const +{ + return bp.fileName.endsWith(".txt") || bp.fileName.endsWith(".cmake"); +} + bool CMakeDapEngine::hasCapability(unsigned cap) const { return cap & (ReloadModuleCapability @@ -151,32 +156,6 @@ bool CMakeDapEngine::hasCapability(unsigned cap) const /*| RunToLineCapability*/); // disable while the #25176 bug is not fixed } -void CMakeDapEngine::insertBreakpoint(const Breakpoint &bp) -{ - DapEngine::insertBreakpoint(bp); - notifyBreakpointInsertOk(bp); // Needed for CMake support issue:25176 -} - -void CMakeDapEngine::removeBreakpoint(const Breakpoint &bp) -{ - DapEngine::removeBreakpoint(bp); - notifyBreakpointRemoveOk(bp); // Needed for CMake support issue:25176 -} - -void CMakeDapEngine::updateBreakpoint(const Breakpoint &bp) -{ - DapEngine::updateBreakpoint(bp); - - /* Needed for CMake support issue:25176 */ - BreakpointParameters parameters = bp->requestedParameters(); - if (parameters.enabled != bp->isEnabled()) { - parameters.pending = false; - bp->setParameters(parameters); - } - notifyBreakpointChangeOk(bp); - /* Needed for CMake support issue:25176 */ -} - const QLoggingCategory &CMakeDapEngine::logCategory() { static const QLoggingCategory logCategory = QLoggingCategory("qtc.dbg.dapengine.cmake", diff --git a/src/plugins/debugger/dap/cmakedapengine.h b/src/plugins/debugger/dap/cmakedapengine.h index c7d02e3b858..c5464908979 100644 --- a/src/plugins/debugger/dap/cmakedapengine.h +++ b/src/plugins/debugger/dap/cmakedapengine.h @@ -15,14 +15,8 @@ public: private: void setupEngine() override; - /* Needed for CMake support issue:25176 */ - void insertBreakpoint(const Breakpoint &bp) override; - void updateBreakpoint(const Breakpoint &bp) override; - void removeBreakpoint(const Breakpoint &bp) override; - /* Needed for CMake support issue:25176 */ - + bool acceptsBreakpoint(const BreakpointParameters &bp) const override; bool hasCapability(unsigned cap) const override; - const QLoggingCategory &logCategory() override; }; diff --git a/src/plugins/debugger/dap/dapclient.cpp b/src/plugins/debugger/dap/dapclient.cpp index f63d45b2bb9..b1fa0ad1f85 100644 --- a/src/plugins/debugger/dap/dapclient.cpp +++ b/src/plugins/debugger/dap/dapclient.cpp @@ -224,6 +224,8 @@ void DapClient::emitSignals(const QJsonDocument &doc) type = DapResponseType::Pause; } else if (command == "evaluate") { type = DapResponseType::Evaluate; + } else if (command == "setBreakpoints") { + type = DapResponseType::SetBreakpoints; } emit responseReady(type, ob); return; diff --git a/src/plugins/debugger/dap/dapclient.h b/src/plugins/debugger/dap/dapclient.h index d2a6f52bb22..b0cd30a8b26 100644 --- a/src/plugins/debugger/dap/dapclient.h +++ b/src/plugins/debugger/dap/dapclient.h @@ -52,6 +52,7 @@ enum class DapResponseType StepOver, Pause, Evaluate, + SetBreakpoints, Unknown }; diff --git a/src/plugins/debugger/dap/dapengine.cpp b/src/plugins/debugger/dap/dapengine.cpp index b39e664f211..e71c2aa4c9f 100644 --- a/src/plugins/debugger/dap/dapengine.cpp +++ b/src/plugins/debugger/dap/dapengine.cpp @@ -325,19 +325,27 @@ void DapEngine::insertBreakpoint(const Breakpoint &bp) QTC_CHECK(bp->state() == BreakpointInsertionRequested); notifyBreakpointInsertProceeding(bp); + BreakpointParameters parameters = bp->requestedParameters(); + if (!parameters.enabled) { // hack for disabling breakpoints + parameters.pending = false; + bp->setParameters(parameters); + notifyBreakpointInsertOk(bp); + return; + } + dapInsertBreakpoint(bp); } void DapEngine::dapInsertBreakpoint(const Breakpoint &bp) { - bp->setResponseId(QString::number(m_nextBreakpointId++)); const BreakpointParameters ¶ms = bp->requestedParameters(); QJsonArray breakpoints; for (const auto &breakpoint : breakHandler()->breakpoints()) { const BreakpointParameters &bpParams = breakpoint->requestedParameters(); QJsonObject jsonBp = createBreakpoint(bpParams); - if (!jsonBp.isEmpty() && params.fileName.path() == bpParams.fileName.path()) { + if (!jsonBp.isEmpty() && params.fileName.path() == bpParams.fileName.path() + && bpParams.enabled) { breakpoints.append(jsonBp); } } @@ -376,7 +384,8 @@ void DapEngine::dapRemoveBreakpoint(const Breakpoint &bp) QJsonArray breakpoints; for (const auto &breakpoint : breakHandler()->breakpoints()) { const BreakpointParameters &bpParams = breakpoint->requestedParameters(); - if (breakpoint->responseId() != bp->responseId() && params.fileName == bpParams.fileName) { + if (breakpoint->responseId() != bp->responseId() && params.fileName == bpParams.fileName + && bpParams.enabled) { QJsonObject jsonBp = createBreakpoint(bpParams); breakpoints.append(jsonBp); } @@ -599,6 +608,9 @@ void DapEngine::handleResponse(DapResponseType type, const QJsonObject &response case DapResponseType::Evaluate: handleEvaluateResponse(response); break; + case DapResponseType::SetBreakpoints: + handleBreakpointResponse(response); + break; default: showMessage("UNKNOWN RESPONSE:" + command); }; @@ -693,6 +705,90 @@ void DapEngine::handleEvaluateResponse(const QJsonObject &response) m_variablesHandler->handleNext(); } +void DapEngine::handleBreakpointResponse(const QJsonObject &response) +{ + const QJsonObject body = response.value("body").toObject(); + QJsonArray breakpoints = body.value("breakpoints").toArray(); + + QHash map; + for (QJsonValueRef jsonbp : breakpoints) { + QJsonObject breakpoint = jsonbp.toObject(); + QString fileName = breakpoint.value("source").toObject().value("path").toString(); + int line = breakpoint.value("line").toInt(); + + map.insert(fileName + ":" + QString::number(line), breakpoint); + } + + const Breakpoints bps = breakHandler()->breakpoints(); + for (const Breakpoint &bp : bps) { + BreakpointParameters parameters = bp->requestedParameters(); + QString mapKey = parameters.fileName.toString() + ":" + + QString::number(parameters.textPosition.line); + if (map.find(mapKey) != map.end()) { + if (bp->state() == BreakpointRemoveProceeding) { + notifyBreakpointRemoveFailed(bp); + } else if (bp->state() == BreakpointInsertionProceeding + && !map.value(mapKey).value("verified").toBool()) { + notifyBreakpointInsertFailed(bp); + } else if (bp->state() == BreakpointInsertionProceeding) { + parameters.pending = false; + bp->setParameters(parameters); + notifyBreakpointInsertOk(bp); + } + if (!bp.isNull()) + bp->setResponseId(QString::number(map.value(mapKey).value("id").toInt())); + map.remove(mapKey); + } else { + if (bp->state() == BreakpointRemoveProceeding) { + notifyBreakpointRemoveOk(bp); + } + } + + if (!bp.isNull() && bp->state() == BreakpointUpdateProceeding) { + BreakpointParameters parameters = bp->requestedParameters(); + if (parameters.enabled != bp->isEnabled()) { + parameters.pending = false; + bp->setParameters(parameters); + notifyBreakpointChangeOk(bp); + continue; + } + } + } + + for (const Breakpoint &bp : breakHandler()->breakpoints()) { + if (bp->state() == BreakpointInsertionProceeding) { + if (!bp->isEnabled()) + continue; + + QString path = bp->requestedParameters().fileName.toString(); + int line = bp->requestedParameters().textPosition.line; + + QJsonObject jsonBreakpoint; + QString key; + for (QString bpKey : map.keys()) { + QJsonObject breakpoint = map.value(bpKey); + if (path == bp->requestedParameters().fileName.toString() + && abs(breakpoint.value("line").toInt() - line) + < abs(jsonBreakpoint.value("line").toInt() - line)) { + jsonBreakpoint = breakpoint; + key = bpKey; + } + } + + if (!jsonBreakpoint.isEmpty() && jsonBreakpoint.value("verified").toBool()) { + BreakpointParameters parameters = bp->requestedParameters(); + parameters.pending = false; + parameters.textPosition.line = jsonBreakpoint.value("line").toInt(); + parameters.textPosition.column = jsonBreakpoint.value("column").toInt(); + bp->setParameters(parameters); + bp->setResponseId(QString::number(jsonBreakpoint.value("id").toInt())); + notifyBreakpointInsertOk(bp); + map.remove(key); + } + } + } +} + void DapEngine::handleEvent(DapEventType type, const QJsonObject &event) { const QString eventType = event.value("event").toString(); @@ -716,9 +812,6 @@ void DapEngine::handleEvent(DapEventType type, const QJsonObject &event) if (body.value("reason").toString() == "started" && body.value("threadId").toInt() == 1) claimInitialBreakpoints(); break; - case DapEventType::DapBreakpoint: - handleBreakpointEvent(event); - break; case DapEventType::Output: { const QString category = body.value("category").toString(); const QString output = body.value("output").toString(); @@ -761,51 +854,6 @@ void DapEngine::handleStoppedEvent(const QJsonObject &event) m_dapClient->threads(); } -void DapEngine::handleBreakpointEvent(const QJsonObject &event) -{ - const QJsonObject body = event.value("body").toObject(); - QJsonObject breakpoint = body.value("breakpoint").toObject(); - - Breakpoint bp = breakHandler()->findBreakpointByResponseId( - QString::number(breakpoint.value("id").toInt())); - qCDebug(logCategory()) << "breakpoint id :" << breakpoint.value("id").toInt(); - - if (bp) { - BreakpointParameters parameters = bp->requestedParameters(); - if (parameters.enabled != bp->isEnabled()) { - parameters.pending = false; - bp->setParameters(parameters); - notifyBreakpointChangeOk(bp); - return; - } - } - - if (body.value("reason").toString() == "new") { - if (breakpoint.value("verified").toBool()) { - notifyBreakpointInsertOk(bp); - const BreakpointParameters ¶ms = bp->requestedParameters(); - if (params.oneShot) - continueInferior(); - qCDebug(logCategory()) << "breakpoint inserted"; - } else { - notifyBreakpointInsertFailed(bp); - qCDebug(logCategory()) << "breakpoint insertion failed"; - } - return; - } - - if (body.value("reason").toString() == "removed") { - if (breakpoint.value("verified").toBool()) { - notifyBreakpointRemoveOk(bp); - qCDebug(logCategory()) << "breakpoint removed"; - } else { - notifyBreakpointRemoveFailed(bp); - qCDebug(logCategory()) << "breakpoint remove failed"; - } - return; - } -} - void DapEngine::refreshLocals(const QJsonArray &variables) { WatchItem *currentItem = watchHandler()->findItem(m_variablesHandler->currentItem().iname); diff --git a/src/plugins/debugger/dap/dapengine.h b/src/plugins/debugger/dap/dapengine.h index 6f0ae730c17..732a5b53931 100644 --- a/src/plugins/debugger/dap/dapengine.h +++ b/src/plugins/debugger/dap/dapengine.h @@ -128,9 +128,9 @@ protected: void handleScopesResponse(const QJsonObject &response); void handleThreadsResponse(const QJsonObject &response); void handleEvaluateResponse(const QJsonObject &response); + void handleBreakpointResponse(const QJsonObject &response); void handleEvent(DapEventType type, const QJsonObject &event); - void handleBreakpointEvent(const QJsonObject &event); void handleStoppedEvent(const QJsonObject &event); void updateAll() override; diff --git a/src/plugins/debugger/dap/gdbdapengine.cpp b/src/plugins/debugger/dap/gdbdapengine.cpp index 3934aebe9d8..fd944e91151 100644 --- a/src/plugins/debugger/dap/gdbdapengine.cpp +++ b/src/plugins/debugger/dap/gdbdapengine.cpp @@ -161,6 +161,11 @@ void GdbDapEngine::setupEngine() m_dapClient->dataProvider()->start(); } +bool GdbDapEngine::acceptsBreakpoint(const BreakpointParameters &bp) const +{ + return bp.fileName.endsWith(".cpp") || bp.fileName.endsWith(".h"); +} + const QLoggingCategory &GdbDapEngine::logCategory() { static const QLoggingCategory logCategory = QLoggingCategory("qtc.dbg.dapengine.gdb", diff --git a/src/plugins/debugger/dap/gdbdapengine.h b/src/plugins/debugger/dap/gdbdapengine.h index 3638a6d3aba..29634a9da14 100644 --- a/src/plugins/debugger/dap/gdbdapengine.h +++ b/src/plugins/debugger/dap/gdbdapengine.h @@ -19,7 +19,7 @@ private: void handleDapConfigurationDone() override; bool isLocalAttachEngine() const; - + bool acceptsBreakpoint(const BreakpointParameters &bp) const override; const QLoggingCategory &logCategory() override; }; diff --git a/src/plugins/debugger/dap/pydapengine.cpp b/src/plugins/debugger/dap/pydapengine.cpp index 4bbb479126f..37b5712b518 100644 --- a/src/plugins/debugger/dap/pydapengine.cpp +++ b/src/plugins/debugger/dap/pydapengine.cpp @@ -204,32 +204,6 @@ bool PyDapEngine::acceptsBreakpoint(const BreakpointParameters &bp) const return bp.fileName.endsWith(".py"); } -void PyDapEngine::insertBreakpoint(const Breakpoint &bp) -{ - DapEngine::insertBreakpoint(bp); - notifyBreakpointInsertOk(bp); // Needed for Python support issue:1386 -} - -void PyDapEngine::removeBreakpoint(const Breakpoint &bp) -{ - DapEngine::removeBreakpoint(bp); - notifyBreakpointRemoveOk(bp); // Needed for Python support issue:1386 -} - -void PyDapEngine::updateBreakpoint(const Breakpoint &bp) -{ - DapEngine::updateBreakpoint(bp); - - /* Needed for Python support issue:1386 */ - BreakpointParameters parameters = bp->requestedParameters(); - if (parameters.enabled != bp->isEnabled()) { - parameters.pending = false; - bp->setParameters(parameters); - } - notifyBreakpointChangeOk(bp); - /* Needed for Python support issue:1386 */ -} - bool PyDapEngine::isLocalAttachEngine() const { return runParameters().startMode == AttachToLocalProcess; diff --git a/src/plugins/debugger/dap/pydapengine.h b/src/plugins/debugger/dap/pydapengine.h index 2c5f53e63a9..fb2bd4be7b5 100644 --- a/src/plugins/debugger/dap/pydapengine.h +++ b/src/plugins/debugger/dap/pydapengine.h @@ -20,11 +20,6 @@ private: bool isLocalAttachEngine() const; bool acceptsBreakpoint(const BreakpointParameters &bp) const override; - /* Needed for Python support issue:1386 */ - void insertBreakpoint(const Breakpoint &bp) override; - void updateBreakpoint(const Breakpoint &bp) override; - void removeBreakpoint(const Breakpoint &bp) override; - /* Needed for Python support issue:1386 */ const QLoggingCategory &logCategory() override; From 72fb52f767ea912440a44dc0d60a770b01c0c430 Mon Sep 17 00:00:00 2001 From: Artem Sokolovskii Date: Mon, 23 Oct 2023 13:31:53 +0200 Subject: [PATCH 0111/1546] DAP: Move acceptsBreakpoint to mime type Change-Id: I3234e7981202c7d668b8c3c86c818ca47f7be589 Reviewed-by: hjk Reviewed-by: --- src/plugins/debugger/dap/cmakedapengine.cpp | 11 ++++++-- src/plugins/debugger/dap/dapengine.cpp | 6 ++++- src/plugins/debugger/dap/gdbdapengine.cpp | 13 ++++++++- src/plugins/debugger/dap/pydapengine.cpp | 30 ++++++++++++++------- 4 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/plugins/debugger/dap/cmakedapengine.cpp b/src/plugins/debugger/dap/cmakedapengine.cpp index 3e7a23cb243..769fe248238 100644 --- a/src/plugins/debugger/dap/cmakedapengine.cpp +++ b/src/plugins/debugger/dap/cmakedapengine.cpp @@ -9,6 +9,7 @@ #include +#include #include #include @@ -23,6 +24,11 @@ using namespace Core; using namespace Utils; +namespace { +const char CMAKE_MIMETYPE[] = "text/x-cmake"; +const char CMAKE_PROJECT_MIMETYPE[] = "text/x-cmake-project"; +} // namespace + namespace Debugger::Internal { class LocalSocketDataProvider : public IDataProvider @@ -144,7 +150,8 @@ void CMakeDapEngine::setupEngine() bool CMakeDapEngine::acceptsBreakpoint(const BreakpointParameters &bp) const { - return bp.fileName.endsWith(".txt") || bp.fileName.endsWith(".cmake"); + const auto mimeType = Utils::mimeTypeForFile(bp.fileName); + return mimeType.matchesName(CMAKE_MIMETYPE) || mimeType.matchesName(CMAKE_PROJECT_MIMETYPE); } bool CMakeDapEngine::hasCapability(unsigned cap) const @@ -153,7 +160,7 @@ bool CMakeDapEngine::hasCapability(unsigned cap) const | BreakConditionCapability | ShowModuleSymbolsCapability /*| AddWatcherCapability*/ // disable while the #25282 bug is not fixed - /*| RunToLineCapability*/); // disable while the #25176 bug is not fixed + | RunToLineCapability); } const QLoggingCategory &CMakeDapEngine::logCategory() diff --git a/src/plugins/debugger/dap/dapengine.cpp b/src/plugins/debugger/dap/dapengine.cpp index e71c2aa4c9f..5c6de71777d 100644 --- a/src/plugins/debugger/dap/dapengine.cpp +++ b/src/plugins/debugger/dap/dapengine.cpp @@ -734,6 +734,8 @@ void DapEngine::handleBreakpointResponse(const QJsonObject &response) parameters.pending = false; bp->setParameters(parameters); notifyBreakpointInsertOk(bp); + if (parameters.oneShot) + continueInferior(); } if (!bp.isNull()) bp->setResponseId(QString::number(map.value(mapKey).value("id").toInt())); @@ -783,6 +785,8 @@ void DapEngine::handleBreakpointResponse(const QJsonObject &response) bp->setParameters(parameters); bp->setResponseId(QString::number(jsonBreakpoint.value("id").toInt())); notifyBreakpointInsertOk(bp); + if (parameters.oneShot) + continueInferior(); map.remove(key); } } @@ -841,7 +845,7 @@ void DapEngine::handleStoppedEvent(const QJsonObject &event) const BreakpointParameters ¶ms = bp->requestedParameters(); gotoLocation(Location(params.fileName, params.textPosition)); if (params.oneShot) - removeBreakpoint(bp); + bp->globalBreakpoint()->deleteBreakpoint(); } } diff --git a/src/plugins/debugger/dap/gdbdapengine.cpp b/src/plugins/debugger/dap/gdbdapengine.cpp index fd944e91151..1b208924e85 100644 --- a/src/plugins/debugger/dap/gdbdapengine.cpp +++ b/src/plugins/debugger/dap/gdbdapengine.cpp @@ -9,6 +9,7 @@ #include +#include #include #include @@ -22,6 +23,13 @@ using namespace Core; using namespace Utils; +namespace { +const char C_HEADER_MIMETYPE[] = "text/x-chdr"; +const char C_SOURCE_MIMETYPE[] = "text/x-csrc"; +const char CPP_SOURCE_MIMETYPE[] = "text/x-c++src"; +const char CPP_HEADER_MIMETYPE[] = "text/x-c++hdr"; +} // namespace + namespace Debugger::Internal { class ProcessDataProvider : public IDataProvider @@ -163,7 +171,10 @@ void GdbDapEngine::setupEngine() bool GdbDapEngine::acceptsBreakpoint(const BreakpointParameters &bp) const { - return bp.fileName.endsWith(".cpp") || bp.fileName.endsWith(".h"); + const auto mimeType = Utils::mimeTypeForFile(bp.fileName); + return mimeType.matchesName(C_HEADER_MIMETYPE) || mimeType.matchesName(C_SOURCE_MIMETYPE) + || mimeType.matchesName(CPP_HEADER_MIMETYPE) + || mimeType.matchesName(CPP_SOURCE_MIMETYPE); } const QLoggingCategory &GdbDapEngine::logCategory() diff --git a/src/plugins/debugger/dap/pydapengine.cpp b/src/plugins/debugger/dap/pydapengine.cpp index 37b5712b518..9f59d05f9ea 100644 --- a/src/plugins/debugger/dap/pydapengine.cpp +++ b/src/plugins/debugger/dap/pydapengine.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -26,6 +27,13 @@ using namespace Core; using namespace Utils; +namespace { +const char C_PY_MIMETYPE[] = "text/x-python"; +const char C_PY_GUI_MIMETYPE[] = "text/x-python-gui"; +const char C_PY3_MIMETYPE[] = "text/x-python3"; +const char C_PY_MIME_ICON[] = "text-x-python"; +} // namespace + namespace Debugger::Internal { const char installDebugPyInfoBarId[] = "Python::InstallDebugPy"; @@ -199,16 +207,6 @@ void PyDapEngine::quitDebugger() DebuggerEngine::quitDebugger(); } -bool PyDapEngine::acceptsBreakpoint(const BreakpointParameters &bp) const -{ - return bp.fileName.endsWith(".py"); -} - -bool PyDapEngine::isLocalAttachEngine() const -{ - return runParameters().startMode == AttachToLocalProcess; -} - void PyDapEngine::setupEngine() { QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state()); @@ -265,6 +263,18 @@ void PyDapEngine::setupEngine() m_dapClient->dataProvider()->start(); } +bool PyDapEngine::acceptsBreakpoint(const BreakpointParameters &bp) const +{ + const auto mimeType = Utils::mimeTypeForFile(bp.fileName); + return mimeType.matchesName(C_PY3_MIMETYPE) || mimeType.matchesName(C_PY_GUI_MIMETYPE) + || mimeType.matchesName(C_PY_MIMETYPE) || mimeType.matchesName(C_PY_MIME_ICON); +} + +bool PyDapEngine::isLocalAttachEngine() const +{ + return runParameters().startMode == AttachToLocalProcess; +} + const QLoggingCategory &PyDapEngine::logCategory() { static const QLoggingCategory logCategory = QLoggingCategory("qtc.dbg.dapengine.python", From c83a0be72d700bc56d32afc8eaaf84ac134f419e Mon Sep 17 00:00:00 2001 From: Daniel Trevitz Date: Fri, 15 Sep 2023 10:56:08 -0400 Subject: [PATCH 0112/1546] Only download from remote when we absolutely have to If the kit includes a correctly configured sysroot gdbserver will tell us our hostPath. Respect that hostPath if it exists, otherwise fall back to remote debug. Also, populate the hostPath with the symbol file from the run parameters. Task-number: QTCREATORBUG-29614 Change-Id: I3838cd44aa96d7dfcd4ded660b8102a1532c5362 Reviewed-by: hjk --- src/plugins/debugger/gdb/gdbengine.cpp | 5 +++-- src/plugins/debugger/moduleshandler.cpp | 9 ++++++++- src/plugins/debugger/moduleshandler.h | 2 +- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 09755f68e6d..59d6d50a5b7 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -469,10 +469,10 @@ void GdbEngine::handleAsyncOutput(const QStringView asyncClass, const GdbMi &res Module module; module.startAddress = 0; module.endAddress = 0; - module.hostPath = result["host-name"].data(); + module.hostPath = Utils::FilePath::fromString(result["host-name"].data()); const QString target = result["target-name"].data(); module.modulePath = runParameters().inferior.command.executable().withNewPath(target); - module.moduleName = QFileInfo(module.hostPath).baseName(); + module.moduleName = module.hostPath.baseName(); modulesHandler()->updateModule(module); } else if (asyncClass == u"library-unloaded") { // Archer has 'id="/usr/lib/libdrm.so.2", @@ -3926,6 +3926,7 @@ void GdbEngine::handleGdbStarted() module.startAddress = 0; module.endAddress = 0; module.modulePath = rp.inferior.command.executable(); + module.hostPath = rp.symbolFile; module.moduleName = ""; modulesHandler()->updateModule(module); diff --git a/src/plugins/debugger/moduleshandler.cpp b/src/plugins/debugger/moduleshandler.cpp index 5d0d6d6a8b7..9072d02463d 100644 --- a/src/plugins/debugger/moduleshandler.cpp +++ b/src/plugins/debugger/moduleshandler.cpp @@ -273,9 +273,16 @@ void ModulesHandler::removeModule(const FilePath &modulePath) m_model->destroyItem(item); } +static FilePath pickPath(const FilePath &hostPath, const FilePath &modulePath) +{ + if (!hostPath.isEmpty() && hostPath.exists()) + return hostPath; + return modulePath; // Checking if this exists can be slow, delay it for as long as possible +} + void ModulesHandler::updateModule(const Module &module) { - const FilePath path = module.modulePath; + const FilePath path = pickPath(module.hostPath, module.modulePath); if (path.isEmpty()) return; diff --git a/src/plugins/debugger/moduleshandler.h b/src/plugins/debugger/moduleshandler.h index 03434edab28..97ab677b359 100644 --- a/src/plugins/debugger/moduleshandler.h +++ b/src/plugins/debugger/moduleshandler.h @@ -71,7 +71,7 @@ public: }; QString moduleName; Utils::FilePath modulePath; - QString hostPath; + Utils::FilePath hostPath; SymbolReadState symbolsRead = UnknownReadState; quint64 startAddress = 0; quint64 endAddress = 0; From 30ac04bffdf56a300ebdbe775aa95531e2ff0c5b Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 6 Nov 2023 21:00:53 +0100 Subject: [PATCH 0113/1546] Process tests: Use QSignalSpy and QTRY_xxx instead of timeouts Avoid arbitrary timeouts causing flakiness of tests. Change-Id: I2b7634ab08ee29be06002eb22f01a5efdf78d407 Reviewed-by: Marcus Tillmanns --- tests/auto/utils/process/tst_process.cpp | 26 +++++++++++------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/tests/auto/utils/process/tst_process.cpp b/tests/auto/utils/process/tst_process.cpp index 334c9754ba4..600c081b7fb 100644 --- a/tests/auto/utils/process/tst_process.cpp +++ b/tests/auto/utils/process/tst_process.cpp @@ -1367,20 +1367,18 @@ void tst_Process::recursiveBlockingProcess() QString::number(recursionDepth)); { Process process; + QSignalSpy readSpy(&process, &Process::readyReadStandardOutput); + QSignalSpy doneSpy(&process, &Process::done); subConfig.setupSubProcess(&process); process.start(); - QVERIFY(process.waitForStarted(1000)); - // The readyRead() is generated from the innermost nested process, so it means - // we need to give enough time for all nested processes to start their - // process launchers successfully. - QVERIFY(process.waitForReadyRead(2000)); + QTRY_COMPARE(readSpy.count(), 1); // Wait until 1st ready read signal comes. QCOMPARE(process.readAllRawStandardOutput(), s_leafProcessStarted); QCOMPARE(runningTestProcessCount(), recursionDepth); - QVERIFY(!process.waitForFinished(10)); + QCOMPARE(doneSpy.count(), 0); process.terminate(); - QVERIFY(process.waitForReadyRead(1000)); + QTRY_COMPARE(readSpy.count(), 2); // Wait until 2nd ready read signal comes. QCOMPARE(process.readAllRawStandardOutput(), s_leafProcessTerminated); - QVERIFY(process.waitForFinished(1000)); + QTRY_COMPARE(doneSpy.count(), 1); // Wait until done signal comes. QCOMPARE(process.exitStatus(), QProcess::NormalExit); QCOMPARE(process.exitCode(), s_crashCode); } @@ -1424,16 +1422,16 @@ void tst_Process::quitBlockingProcess() QString::number(recursionDepth)); Process process; + QSignalSpy readSpy(&process, &Process::readyReadStandardOutput); + QSignalSpy doneSpy(&process, &Process::done); subConfig.setupSubProcess(&process); - bool done = false; - connect(&process, &Process::done, this, [&done] { done = true; }); process.start(); QVERIFY(process.waitForStarted()); - QVERIFY(!done); + QCOMPARE(doneSpy.count(), 0); QVERIFY(process.isRunning()); - QVERIFY(process.waitForReadyRead(1000)); + QTRY_COMPARE(readSpy.count(), 1); // Wait until ready read signal comes. QCOMPARE(process.readAllRawStandardOutput(), s_leafProcessStarted); switch (quitType) { @@ -1443,7 +1441,7 @@ void tst_Process::quitBlockingProcess() case QuitType::Close: process.close(); break; } - QVERIFY(!done); + QCOMPARE(doneSpy.count(), 0); if (doneExpected) { QVERIFY(process.isRunning()); @@ -1451,7 +1449,7 @@ void tst_Process::quitBlockingProcess() QVERIFY(process.waitForFinished()); QVERIFY(!process.isRunning()); - QVERIFY(done); + QCOMPARE(doneSpy.count(), 1); if (gracefulQuit) { if (HostOsInfo::isWindowsHost()) From 64b6f0f02bb54baf6f49e6b5f3fc0566ec65de1d Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 5 Sep 2023 11:25:04 +0200 Subject: [PATCH 0114/1546] ProjectExplorer: Hide GccToolChain::WarningFlagAdder declaration It's only used in the .cpp. Change-Id: Ib9ce5ca49dfe2440d553c98cf688dcd6d31ac084 Reviewed-by: Christian Kandeler --- src/plugins/projectexplorer/gcctoolchain.cpp | 77 +++++++++++--------- src/plugins/projectexplorer/gcctoolchain.h | 14 ---- 2 files changed, 43 insertions(+), 48 deletions(-) diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 78b5ba4737a..8a39318aaea 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -48,6 +48,49 @@ using namespace Utils; namespace ProjectExplorer { namespace Internal { +class WarningFlagAdder +{ +public: + WarningFlagAdder(const QString &flag, WarningFlags &flags) : + m_flags(flags) + { + if (!flag.startsWith("-W")) { + m_triggered = true; + return; + } + + m_doesEnable = !flag.startsWith("-Wno-"); + if (m_doesEnable) + m_flagUtf8 = flag.mid(2).toUtf8(); + else + m_flagUtf8 = flag.mid(5).toUtf8(); + } + + void operator()(const char name[], WarningFlags flagsSet) + { + if (m_triggered) + return; + if (0 == strcmp(m_flagUtf8.data(), name)) { + m_triggered = true; + if (m_doesEnable) + m_flags |= flagsSet; + else + m_flags &= ~flagsSet; + } + } + + bool triggered() const + { + return m_triggered; + } + +private: + QByteArray m_flagUtf8; + WarningFlags &m_flags; + bool m_doesEnable = false; + bool m_triggered = false; +}; + static const QStringList languageOption(Id languageId) { if (languageId == Constants::C_LANGUAGE_ID) @@ -1975,40 +2018,6 @@ void GccToolChainConfigWidget::updateParentToolChainComboBox() } } -GccToolChain::WarningFlagAdder::WarningFlagAdder(const QString &flag, WarningFlags &flags) : - m_flags(flags) -{ - if (!flag.startsWith("-W")) { - m_triggered = true; - return; - } - - m_doesEnable = !flag.startsWith("-Wno-"); - if (m_doesEnable) - m_flagUtf8 = flag.mid(2).toUtf8(); - else - m_flagUtf8 = flag.mid(5).toUtf8(); -} - -void GccToolChain::WarningFlagAdder::operator ()(const char name[], WarningFlags flagsSet) -{ - if (m_triggered) - return; - if (0 == strcmp(m_flagUtf8.data(), name)) - { - m_triggered = true; - if (m_doesEnable) - m_flags |= flagsSet; - else - m_flags &= ~flagsSet; - } -} - -bool GccToolChain::WarningFlagAdder::triggered() const -{ - return m_triggered; -} - } // namespace ProjectExplorer // Unit tests: diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h index 207d93f5bd8..52ffabc839b 100644 --- a/src/plugins/projectexplorer/gcctoolchain.h +++ b/src/plugins/projectexplorer/gcctoolchain.h @@ -127,20 +127,6 @@ protected: int priority() const override { return m_priority; } - class WarningFlagAdder - { - public: - WarningFlagAdder(const QString &flag, Utils::WarningFlags &flags); - void operator ()(const char name[], Utils::WarningFlags flagsSet); - - bool triggered() const; - private: - QByteArray m_flagUtf8; - Utils::WarningFlags &m_flags; - bool m_doesEnable = false; - bool m_triggered = false; - }; - QString sysRoot() const override; private: From bad0601166dc061ae9e99128e7df51ca6f2bda1d Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 22 Aug 2023 11:59:14 +0200 Subject: [PATCH 0115/1546] ProjectExplorer: De-Q_OBJECT-ify DeviceManagerModel The provided features are not used (anymore?). Change-Id: I79a170082bdfce9290a623fd26573a600a3f2c22 Reviewed-by: Reviewed-by: Christian Kandeler --- .../devicesupport/devicemanagermodel.cpp | 27 ++++++++++--------- .../devicesupport/devicemanagermodel.h | 3 +-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp b/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp index edb9999d6a0..7e8a74d0a3a 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicemanagermodel.cpp @@ -7,20 +7,21 @@ #include "../projectexplorertr.h" #include -#include -#include +using namespace Utils; namespace ProjectExplorer { namespace Internal { + class DeviceManagerModelPrivate { public: const DeviceManager *deviceManager; QList devices; - QList filter; - Utils::Id typeToKeep; + QList filter; + Id typeToKeep; }; + } // namespace Internal DeviceManagerModel::DeviceManagerModel(const DeviceManager *deviceManager, QObject *parent) : @@ -40,13 +41,13 @@ DeviceManagerModel::DeviceManagerModel(const DeviceManager *deviceManager, QObje DeviceManagerModel::~DeviceManagerModel() = default; -void DeviceManagerModel::setFilter(const QList &filter) +void DeviceManagerModel::setFilter(const QList &filter) { d->filter = filter; handleDeviceListChanged(); } -void DeviceManagerModel::setTypeFilter(Utils::Id type) +void DeviceManagerModel::setTypeFilter(Id type) { if (d->typeToKeep == type) return; @@ -54,7 +55,7 @@ void DeviceManagerModel::setTypeFilter(Utils::Id type) handleDeviceListChanged(); } -void DeviceManagerModel::updateDevice(Utils::Id id) +void DeviceManagerModel::updateDevice(Id id) { handleDeviceUpdated(id); } @@ -66,10 +67,10 @@ IDevice::ConstPtr DeviceManagerModel::device(int pos) const return d->devices.at(pos); } -Utils::Id DeviceManagerModel::deviceId(int pos) const +Id DeviceManagerModel::deviceId(int pos) const { IDevice::ConstPtr dev = device(pos); - return dev ? dev->id() : Utils::Id(); + return dev ? dev->id() : Id(); } int DeviceManagerModel::indexOf(IDevice::ConstPtr dev) const @@ -84,7 +85,7 @@ int DeviceManagerModel::indexOf(IDevice::ConstPtr dev) const return -1; } -void DeviceManagerModel::handleDeviceAdded(Utils::Id id) +void DeviceManagerModel::handleDeviceAdded(Id id) { if (d->filter.contains(id)) return; @@ -97,7 +98,7 @@ void DeviceManagerModel::handleDeviceAdded(Utils::Id id) endInsertRows(); } -void DeviceManagerModel::handleDeviceRemoved(Utils::Id id) +void DeviceManagerModel::handleDeviceRemoved(Id id) { const int idx = indexForId(id); QTC_ASSERT(idx != -1, return); @@ -106,7 +107,7 @@ void DeviceManagerModel::handleDeviceRemoved(Utils::Id id) endRemoveRows(); } -void DeviceManagerModel::handleDeviceUpdated(Utils::Id id) +void DeviceManagerModel::handleDeviceUpdated(Id id) { const int idx = indexForId(id); if (idx < 0) // This occurs when a device not matching the type filter is updated @@ -160,7 +161,7 @@ bool DeviceManagerModel::matchesTypeFilter(const IDevice::ConstPtr &dev) const return !d->typeToKeep.isValid() || dev->type() == d->typeToKeep; } -int DeviceManagerModel::indexForId(Utils::Id id) const +int DeviceManagerModel::indexForId(Id id) const { for (int i = 0; i < d->devices.count(); ++i) { if (d->devices.at(i)->id() == id) diff --git a/src/plugins/projectexplorer/devicesupport/devicemanagermodel.h b/src/plugins/projectexplorer/devicesupport/devicemanagermodel.h index 0a0a7d53b46..f6dd9ee70fe 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanagermodel.h +++ b/src/plugins/projectexplorer/devicesupport/devicemanagermodel.h @@ -14,12 +14,11 @@ namespace Utils { class Id; } namespace ProjectExplorer { namespace Internal { class DeviceManagerModelPrivate; } -class IDevice; + class DeviceManager; class PROJECTEXPLORER_EXPORT DeviceManagerModel : public QAbstractListModel { - Q_OBJECT public: explicit DeviceManagerModel(const DeviceManager *deviceManager, QObject *parent = nullptr); ~DeviceManagerModel() override; From 79f07f9d4c7f3fdb8700ef4691acfc8be27e08df Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Tue, 10 Oct 2023 17:21:17 +0200 Subject: [PATCH 0116/1546] VcsBase: Add Qt Jira and Gerrit URLs support This way one can simply click on the url in git log. Change-Id: I91abda71a48f079e554a48a70a0f05e8417731ed Reviewed-by: Orgad Shaneh --- src/plugins/vcsbase/vcsbaseeditor.cpp | 42 ++++++++++++++++++++------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index 1ad32d4684f..1b6f4811369 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -371,16 +371,22 @@ private: public: int startColumn; QString url; + qsizetype urlLength; }; UrlData m_urlData; QRegularExpression m_pattern; + QRegularExpression m_jiraPattern; + QRegularExpression m_gerritPattern; }; UrlTextCursorHandler::UrlTextCursorHandler(VcsBaseEditorWidget *editorWidget) : AbstractTextCursorHandler(editorWidget) { setUrlPattern(QLatin1String("https?\\://[^\\s]+")); + + m_jiraPattern = QRegularExpression("(Fixes|Task-number): ([A-Z]+-[0-9]+)"); + m_gerritPattern = QRegularExpression("Change-Id: (I[a-f0-9]{40})"); } bool UrlTextCursorHandler::findContentsUnderCursor(const QTextCursor &cursor) @@ -389,23 +395,37 @@ bool UrlTextCursorHandler::findContentsUnderCursor(const QTextCursor &cursor) m_urlData.url.clear(); m_urlData.startColumn = -1; + m_urlData.urlLength = 0; QTextCursor cursorForUrl = cursor; cursorForUrl.select(QTextCursor::LineUnderCursor); if (cursorForUrl.hasSelection()) { const QString line = cursorForUrl.selectedText(); const int cursorCol = cursor.columnNumber(); - QRegularExpressionMatchIterator i = m_pattern.globalMatch(line); - while (i.hasNext()) { - const QRegularExpressionMatch match = i.next(); - const int urlMatchIndex = match.capturedStart(); - const QString url = match.captured(0); - if (urlMatchIndex <= cursorCol && cursorCol <= urlMatchIndex + url.length()) { - m_urlData.startColumn = urlMatchIndex; - m_urlData.url = url; - break; - } + + struct { + QRegularExpression &pattern; + int matchNumber; + QString urlPrefix; + } RegexUrls[] = { + {m_pattern, 0, ""}, + {m_jiraPattern, 2, "https://bugreports.qt.io/browse/"}, + {m_gerritPattern, 1, "https://codereview.qt-project.org/r/"}, }; + for (const auto &r : RegexUrls) { + QRegularExpressionMatchIterator i = r.pattern.globalMatch(line); + while (i.hasNext()) { + const QRegularExpressionMatch match = i.next(); + const int urlMatchIndex = match.capturedStart(r.matchNumber); + const QString url = match.captured(r.matchNumber); + if (urlMatchIndex <= cursorCol && cursorCol <= urlMatchIndex + url.length()) { + m_urlData.startColumn = urlMatchIndex; + m_urlData.url = r.urlPrefix + url; + m_urlData.urlLength = url.length(); + break; + } + } + } } return m_urlData.startColumn != -1; @@ -418,7 +438,7 @@ void UrlTextCursorHandler::highlightCurrentContents() sel.cursor = currentCursor(); sel.cursor.setPosition(currentCursor().position() - (currentCursor().columnNumber() - m_urlData.startColumn)); - sel.cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, m_urlData.url.length()); + sel.cursor.movePosition(QTextCursor::Right, QTextCursor::KeepAnchor, m_urlData.urlLength); sel.format.setFontUnderline(true); sel.format.setForeground(linkColor); sel.format.setUnderlineColor(linkColor); From baaf00d43ff9c5e09d4eb219da4b2d5d06807abd Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 5 Oct 2023 15:32:26 +0200 Subject: [PATCH 0117/1546] Core: Re-order EditorView functions a bit More canonical. Also remove two unused slots markers plus a bit code cosmetics. Change-Id: I4015ffecc5cb2f7d0bb7d8e35c4a59c425a42a6d Reviewed-by: Eike Ziller --- .../coreplugin/editormanager/editorview.cpp | 21 +++++-- .../coreplugin/editormanager/editorview.h | 63 +++++++++---------- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/src/plugins/coreplugin/editormanager/editorview.cpp b/src/plugins/coreplugin/editormanager/editorview.cpp index 9edef863c9a..6aa20510cb4 100644 --- a/src/plugins/coreplugin/editormanager/editorview.cpp +++ b/src/plugins/coreplugin/editormanager/editorview.cpp @@ -7,11 +7,9 @@ #include "editormanager_p.h" #include "documentmodel.h" #include "documentmodel_p.h" -#include "../actionmanager/actionmanager.h" #include "../editormanager/ieditor.h" #include "../editortoolbar.h" #include "../findplaceholder.h" -#include "../icore.h" #include "../minisplitter.h" #include @@ -22,8 +20,6 @@ #include #include -#include - #include #include #include @@ -36,10 +32,11 @@ #include using namespace Core; -using namespace Core::Internal; using namespace Utils; -// ================EditorView==================== +namespace Core::Internal { + +// EditorView EditorView::EditorView(SplitterOrView *parentSplitterOrView, QWidget *parent) : QWidget(parent), @@ -225,6 +222,16 @@ void EditorView::setCloseSplitIcon(const QIcon &icon) m_toolBar->setCloseSplitIcon(icon); } +bool EditorView::canGoForward() const +{ + return m_currentNavigationHistoryPosition < m_navigationHistory.size() - 1; +} + +bool EditorView::canGoBack() const +{ + return m_currentNavigationHistoryPosition > 0; +} + void EditorView::updateEditorHistory(IEditor *editor, QList &history) { if (!editor) @@ -997,3 +1004,5 @@ EditLocation EditLocation::load(const QByteArray &data) stream >> loc.state; return loc; } + +} // Core::Internal diff --git a/src/plugins/coreplugin/editormanager/editorview.h b/src/plugins/coreplugin/editormanager/editorview.h index 4bf172d26b5..e38486ea918 100644 --- a/src/plugins/coreplugin/editormanager/editorview.h +++ b/src/plugins/coreplugin/editormanager/editorview.h @@ -7,13 +7,9 @@ #include #include -#include #include -#include +#include #include -#include - -#include #include #include @@ -84,6 +80,21 @@ public: void setCloseSplitEnabled(bool enable); void setCloseSplitIcon(const QIcon &icon); + bool canGoForward() const; + bool canGoBack() const; + + void goBackInNavigationHistory(); + void goForwardInNavigationHistory(); + + void goToEditLocation(const EditLocation &location); + + void addCurrentPositionToNavigationHistory(const QByteArray &saveState = QByteArray()); + void cutForwardNavigationHistory(); + + QList editorHistory() const { return m_editorHistory; } + + void copyNavigationHistoryFrom(EditorView* other); + void updateEditorHistory(IEditor *editor); static void updateEditorHistory(IEditor *editor, QList &history); signals: @@ -112,6 +123,8 @@ private: void updateToolBar(IEditor *editor); void checkProjectLoaded(IEditor *editor); + void updateCurrentPositionInNavigationHistory(); + SplitterOrView *m_parentSplitterOrView; EditorToolBar *m_toolBar; @@ -129,26 +142,6 @@ private: QList m_navigationHistory; QList m_editorHistory; int m_currentNavigationHistoryPosition = 0; - void updateCurrentPositionInNavigationHistory(); - -public: - inline bool canGoForward() const { return m_currentNavigationHistoryPosition < m_navigationHistory.size()-1; } - inline bool canGoBack() const { return m_currentNavigationHistoryPosition > 0; } - -public slots: - void goBackInNavigationHistory(); - void goForwardInNavigationHistory(); - -public: - void goToEditLocation(const EditLocation &location); - - void addCurrentPositionToNavigationHistory(const QByteArray &saveState = QByteArray()); - void cutForwardNavigationHistory(); - - inline QList editorHistory() const { return m_editorHistory; } - - void copyNavigationHistoryFrom(EditorView* other); - void updateEditorHistory(IEditor *editor); }; class SplitterOrView : public QWidget @@ -162,15 +155,15 @@ public: void split(Qt::Orientation orientation, bool activateView = true); void unsplit(); - inline bool isView() const { return m_view != nullptr; } - inline bool isSplitter() const { return m_splitter != nullptr; } + bool isView() const { return m_view != nullptr; } + bool isSplitter() const { return m_splitter != nullptr; } - inline IEditor *editor() const { return m_view ? m_view->currentEditor() : nullptr; } - inline QList editors() const { return m_view ? m_view->editors() : QList(); } - inline bool hasEditor(IEditor *editor) const { return m_view && m_view->hasEditor(editor); } - inline bool hasEditors() const { return m_view && m_view->editorCount() != 0; } - inline EditorView *view() const { return m_view; } - inline QSplitter *splitter() const { return m_splitter; } + IEditor *editor() const { return m_view ? m_view->currentEditor() : nullptr; } + QList editors() const { return m_view ? m_view->editors() : QList(); } + bool hasEditor(IEditor *editor) const { return m_view && m_view->hasEditor(editor); } + bool hasEditors() const { return m_view && m_view->editorCount() != 0; } + EditorView *view() const { return m_view; } + QSplitter *splitter() const { return m_splitter; } QSplitter *takeSplitter(); EditorView *takeView(); @@ -196,5 +189,5 @@ private: QSplitter *m_splitter; }; -} -} +} // Internal +} // Core From 1f660c9afd4c56dfeb6b5b4209f94e3099882f4a Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 7 Nov 2023 19:55:28 +0100 Subject: [PATCH 0118/1546] TaskTree: Add more description for the ProcessReaper Amends 65341d7e5fc4fa7e4493e780cf2ae309bd4a64f7 Change-Id: Ia74a77a21080d55688ff0fed5a4ea8b02b963bf7 Reviewed-by: hjk --- src/libs/solutions/tasking/qprocesstask.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/libs/solutions/tasking/qprocesstask.h b/src/libs/solutions/tasking/qprocesstask.h index 5cec4890e6f..ea75600e521 100644 --- a/src/libs/solutions/tasking/qprocesstask.h +++ b/src/libs/solutions/tasking/qprocesstask.h @@ -11,6 +11,25 @@ namespace Tasking { +// Deleting a running QProcess may block the caller thread up to 30 seconds and issue warnings. +// To avoid these issues we move the running QProcess into a separate thread +// managed by the internal ProcessReaper, instead of deleting it immediately. +// Inside the ProcessReaper's thread we try to finish the process in a most gentle way: +// we call QProcess::terminate() with 500 ms timeout, and if the process is still running +// after the timeout passed, we call QProcess::kill() and wait for the process to finish. +// All these waitings are done is a separate thread, so the main thread doesn't block at all +// when the QProcessTask is destructed. Finally, on application quit, QProcessDeleter::deleteAll() +// should be called to in order to synchronize all the processes being reaped in a separate thread. +// The call to QProcessDeleter::deleteAll() is blocking, but it's unavoidable - sooner or later +// all the processes needs to finish ultimately, so better: block later! +// In this way we terminate running processes in the most safe way and keep the main thread +// responsive. That's a common case when the running QProcess needs to quit quite quicky, +// and the caller thread wants to forget about it, hoping it will be terminated in the most +// sensible way. + +// The implementation of the internal reaper is inspired by the Utils::ProcessReaper taken +// from the QtCreator codebase. + class TASKING_EXPORT QProcessDeleter { public: From c25a7a038140d502f322a8c526f190fb88b33a72 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 7 Nov 2023 20:12:26 +0100 Subject: [PATCH 0119/1546] TaskTree: Address some code style issues Amends af63dcaf9608239f9ffdc50d90230a8ac591e3ad Change-Id: I9c727751afe306be5da36e772201eff1f36ac18a Reviewed-by: hjk --- src/libs/solutions/tasking/qprocesstask.h | 24 +++++++++++++---------- tests/manual/tasking/demo/main.cpp | 6 +++--- tests/manual/tasking/demo/taskwidget.cpp | 12 ++++++------ 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/src/libs/solutions/tasking/qprocesstask.h b/src/libs/solutions/tasking/qprocesstask.h index ea75600e521..335f1d7ba3c 100644 --- a/src/libs/solutions/tasking/qprocesstask.h +++ b/src/libs/solutions/tasking/qprocesstask.h @@ -16,16 +16,20 @@ namespace Tasking { // managed by the internal ProcessReaper, instead of deleting it immediately. // Inside the ProcessReaper's thread we try to finish the process in a most gentle way: // we call QProcess::terminate() with 500 ms timeout, and if the process is still running -// after the timeout passed, we call QProcess::kill() and wait for the process to finish. -// All these waitings are done is a separate thread, so the main thread doesn't block at all -// when the QProcessTask is destructed. Finally, on application quit, QProcessDeleter::deleteAll() -// should be called to in order to synchronize all the processes being reaped in a separate thread. -// The call to QProcessDeleter::deleteAll() is blocking, but it's unavoidable - sooner or later -// all the processes needs to finish ultimately, so better: block later! -// In this way we terminate running processes in the most safe way and keep the main thread -// responsive. That's a common case when the running QProcess needs to quit quite quicky, -// and the caller thread wants to forget about it, hoping it will be terminated in the most -// sensible way. +// after this timeout passed, we call QProcess::kill() and wait for the process to finish. +// All these handlings are done is a separate thread, so the main thread doesn't block at all +// when the QProcessTask is destructed. +// Finally, on application quit, QProcessDeleter::deleteAll() should be called in order +// to synchronize all the processes being still potentially reaped in a separate thread. +// The call to QProcessDeleter::deleteAll() is blocking in case some processes +// are still being reaped. +// This strategy seems most sensible, since when passing the running QProcess into the +// ProcessReaper we don't block immediately, but postpone the possible (not certain) block +// until the end of an application. +// In this way we terminate the running processes in the most safe way and keep the main thread +// responsive. That's a common case when the running application wants to terminate the QProcess +// immediately (e.g. on Cancel button pressed), without keeping and managing the handle +// to the still running QProcess. // The implementation of the internal reaper is inspired by the Utils::ProcessReaper taken // from the QtCreator codebase. diff --git a/tests/manual/tasking/demo/main.cpp b/tests/manual/tasking/demo/main.cpp index b87a094cfb1..75dd97fa5a7 100644 --- a/tests/manual/tasking/demo/main.cpp +++ b/tests/manual/tasking/demo/main.cpp @@ -46,9 +46,9 @@ static QWidget *taskGroup(QWidget *groupWidget, const QList &widgets) static State resultToState(DoneWith result) { switch (result) { - case DoneWith::Success : return State::Success; - case DoneWith::Error : return State::Error; - case DoneWith::Cancel : return State::Canceled; + case DoneWith::Success: return State::Success; + case DoneWith::Error: return State::Error; + case DoneWith::Cancel: return State::Canceled; } return State::Initial; } diff --git a/tests/manual/tasking/demo/taskwidget.cpp b/tests/manual/tasking/demo/taskwidget.cpp index 4433557b7e9..6e698374665 100644 --- a/tests/manual/tasking/demo/taskwidget.cpp +++ b/tests/manual/tasking/demo/taskwidget.cpp @@ -196,13 +196,13 @@ GroupItem GroupWidget::workflowPolicy() const static QString stateToString(State state) { switch (state) { - case State::Initial : return "Initial"; - case State::Running : return "Running"; - case State::Success : return "Success"; - case State::Error : return "Error"; - case State::Canceled : return "Canceled"; + case State::Initial: return "Initial"; + case State::Running: return "Running"; + case State::Success: return "Success"; + case State::Error: return "Error"; + case State::Canceled: return "Canceled"; } - return ""; + return {}; } StateLabel::StateLabel(State state) From 1cc4e32a4bb97ac96da24c3b85778766a905b3e3 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 8 Nov 2023 09:49:03 +0100 Subject: [PATCH 0120/1546] TaskTree tests: Fix testInThread test on mac Amends a88f807e866c9bd0312a840ab2b8223d2c98cada Change-Id: I852a8b75a634d1266c442f775ae7b8f066923ce5 Reviewed-by: Christian Stenger --- tests/auto/solutions/tasking/tst_tasking.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index 4f639f3e013..c2116cbb940 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -2676,7 +2676,7 @@ void tst_Tasking::testInThread() QFETCH(TestData, testData); const auto onSetup = [testData](ConcurrentCall &task) { - task.setConcurrentCallData(runInThread, testData); + task.setConcurrentCallData(&runInThread, testData); }; const auto onDone = [testData](const ConcurrentCall &task) { QVERIFY(task.future().resultCount()); From fc7c11fb6599b7e18a39a52ad9351e092c1d449b Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 22 Aug 2023 10:25:30 +0200 Subject: [PATCH 0121/1546] ProjectExplorer: Consolidate creation of KitAspect's "Manage..." Change-Id: I001a21f41bcd5ff0614bdf98893b56137c06546f Reviewed-by: Eike Ziller --- .../cmakeprojectmanager/cmakekitaspect.cpp | 9 +++---- src/plugins/debugger/debuggerkitaspect.cpp | 8 +++--- .../toolkitaspectwidget.cpp | 4 +-- .../mesonprojectmanager/toolkitaspectwidget.h | 2 -- src/plugins/projectexplorer/kitaspects.cpp | 15 +++-------- src/plugins/projectexplorer/kitmanager.cpp | 27 ++++++++++++------- src/plugins/projectexplorer/kitmanager.h | 8 ++++-- .../kitmanagerconfigwidget.cpp | 6 ++--- src/plugins/python/pythonkitaspect.cpp | 7 ++--- src/plugins/qtsupport/qtkitaspect.cpp | 7 ++--- 10 files changed, 41 insertions(+), 52 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakekitaspect.cpp b/src/plugins/cmakeprojectmanager/cmakekitaspect.cpp index 6c112f01d5c..a39b9d70123 100644 --- a/src/plugins/cmakeprojectmanager/cmakekitaspect.cpp +++ b/src/plugins/cmakeprojectmanager/cmakekitaspect.cpp @@ -120,10 +120,10 @@ private: class CMakeKitAspectImpl final : public KitAspect { public: - CMakeKitAspectImpl(Kit *kit, const KitAspectFactory *factory) : KitAspect(kit, factory), - m_comboBox(createSubWidget()), - m_manageButton(createManageButton(Constants::Settings::TOOLS_ID)) + CMakeKitAspectImpl(Kit *kit, const KitAspectFactory *factory) + : KitAspect(kit, factory), m_comboBox(createSubWidget()) { + setManagingPage(Constants::Settings::TOOLS_ID); m_comboBox->setSizePolicy(QSizePolicy::Ignored, m_comboBox->sizePolicy().verticalPolicy()); m_comboBox->setEnabled(false); m_comboBox->setToolTip(factory->description()); @@ -142,7 +142,6 @@ public: ~CMakeKitAspectImpl() override { delete m_comboBox; - delete m_manageButton; } private: @@ -153,7 +152,6 @@ private: { addMutableAction(m_comboBox); builder.addItem(m_comboBox); - builder.addItem(m_manageButton); } void refresh() override @@ -213,7 +211,6 @@ private: Guard m_ignoreChanges; QComboBox *m_comboBox; - QWidget *m_manageButton; }; CMakeKitAspectFactory::CMakeKitAspectFactory() diff --git a/src/plugins/debugger/debuggerkitaspect.cpp b/src/plugins/debugger/debuggerkitaspect.cpp index b881e90332d..fdc6f776902 100644 --- a/src/plugins/debugger/debuggerkitaspect.cpp +++ b/src/plugins/debugger/debuggerkitaspect.cpp @@ -41,6 +41,8 @@ public: DebuggerKitAspectImpl(Kit *workingCopy, const KitAspectFactory *factory) : KitAspect(workingCopy, factory) { + setManagingPage(ProjectExplorer::Constants::DEBUGGER_SETTINGS_PAGE_ID); + m_comboBox = createSubWidget(); m_comboBox->setSizePolicy(QSizePolicy::Ignored, m_comboBox->sizePolicy().verticalPolicy()); m_comboBox->setEnabled(true); @@ -56,13 +58,11 @@ public: m_kit->setValue(DebuggerKitAspect::id(), id); }); - m_manageButton = createManageButton(ProjectExplorer::Constants::DEBUGGER_SETTINGS_PAGE_ID); } ~DebuggerKitAspectImpl() override { delete m_comboBox; - delete m_manageButton; } private: @@ -70,12 +70,11 @@ private: { addMutableAction(m_comboBox); parent.addItem(m_comboBox); - parent.addItem(m_manageButton); } void makeReadOnly() override { - m_manageButton->setEnabled(false); + KitAspect::makeReadOnly(); m_comboBox->setEnabled(false); } @@ -124,7 +123,6 @@ private: Guard m_ignoreChanges; QComboBox *m_comboBox; - QWidget *m_manageButton; }; } // namespace Internal diff --git a/src/plugins/mesonprojectmanager/toolkitaspectwidget.cpp b/src/plugins/mesonprojectmanager/toolkitaspectwidget.cpp index e3398aa9f79..6ae9d85129c 100644 --- a/src/plugins/mesonprojectmanager/toolkitaspectwidget.cpp +++ b/src/plugins/mesonprojectmanager/toolkitaspectwidget.cpp @@ -17,9 +17,10 @@ ToolKitAspectWidget::ToolKitAspectWidget(ProjectExplorer::Kit *kit, ToolType type) : ProjectExplorer::KitAspect(kit, factory) , m_toolsComboBox(createSubWidget()) - , m_manageButton(createManageButton(Constants::SettingsPage::TOOLS_ID)) , m_type{type} { + setManagingPage(Constants::SettingsPage::TOOLS_ID); + m_toolsComboBox->setSizePolicy(QSizePolicy::Ignored, m_toolsComboBox->sizePolicy().verticalPolicy()); m_toolsComboBox->setEnabled(false); @@ -37,7 +38,6 @@ ToolKitAspectWidget::ToolKitAspectWidget(ProjectExplorer::Kit *kit, ToolKitAspectWidget::~ToolKitAspectWidget() { delete m_toolsComboBox; - delete m_manageButton; } void ToolKitAspectWidget::addTool(const MesonTools::Tool_t &tool) diff --git a/src/plugins/mesonprojectmanager/toolkitaspectwidget.h b/src/plugins/mesonprojectmanager/toolkitaspectwidget.h index 9a354dc1e75..1ca8d1f1e5b 100644 --- a/src/plugins/mesonprojectmanager/toolkitaspectwidget.h +++ b/src/plugins/mesonprojectmanager/toolkitaspectwidget.h @@ -40,7 +40,6 @@ private: { addMutableAction(m_toolsComboBox); parent.addItem(m_toolsComboBox); - parent.addItem(m_manageButton); } void refresh() override @@ -58,7 +57,6 @@ private: } QComboBox *m_toolsComboBox; - QWidget *m_manageButton; ToolType m_type; }; diff --git a/src/plugins/projectexplorer/kitaspects.cpp b/src/plugins/projectexplorer/kitaspects.cpp index 489f267b7a1..78aecdba6ba 100644 --- a/src/plugins/projectexplorer/kitaspects.cpp +++ b/src/plugins/projectexplorer/kitaspects.cpp @@ -227,13 +227,12 @@ public: refresh(); - m_manageButton = createManageButton(Constants::TOOLCHAIN_SETTINGS_PAGE_ID); + setManagingPage(Constants::TOOLCHAIN_SETTINGS_PAGE_ID); } ~ToolChainKitAspectImpl() override { delete m_mainWidget; - delete m_manageButton; } private: @@ -241,7 +240,6 @@ private: { addMutableAction(m_mainWidget); builder.addItem(m_mainWidget); - builder.addItem(m_manageButton); } void refresh() override @@ -313,7 +311,6 @@ private: } QWidget *m_mainWidget = nullptr; - QWidget *m_manageButton = nullptr; QHash m_languageComboboxMap; Guard m_ignoreChanges; bool m_isReadOnly = false; @@ -869,11 +866,11 @@ public: m_comboBox(createSubWidget()), m_model(new DeviceManagerModel(DeviceManager::instance())) { + setManagingPage(Constants::DEVICE_SETTINGS_PAGE_ID); m_comboBox->setSizePolicy(QSizePolicy::Preferred, m_comboBox->sizePolicy().verticalPolicy()); m_comboBox->setModel(m_model); m_comboBox->setMinimumContentsLength(16); // Don't stretch too much for Kit Page - m_manageButton = createManageButton(Constants::DEVICE_SETTINGS_PAGE_ID); refresh(); m_comboBox->setToolTip(factory->description()); @@ -889,7 +886,6 @@ public: { delete m_comboBox; delete m_model; - delete m_manageButton; } private: @@ -897,7 +893,6 @@ private: { addMutableAction(m_comboBox); builder.addItem(m_comboBox); - builder.addItem(m_manageButton); } void makeReadOnly() override { m_comboBox->setEnabled(false); } @@ -929,7 +924,6 @@ private: Guard m_ignoreChanges; QComboBox *m_comboBox; - QWidget *m_manageButton; DeviceManagerModel *m_model; Id m_selectedId; }; @@ -1153,9 +1147,9 @@ public: m_comboBox(createSubWidget()), m_model(new DeviceManagerModel(DeviceManager::instance())) { + setManagingPage(Constants::DEVICE_SETTINGS_PAGE_ID); m_comboBox->setSizePolicy(QSizePolicy::Ignored, m_comboBox->sizePolicy().verticalPolicy()); m_comboBox->setModel(m_model); - m_manageButton = createManageButton(Constants::DEVICE_SETTINGS_PAGE_ID); refresh(); m_comboBox->setToolTip(factory->description()); @@ -1171,7 +1165,6 @@ public: { delete m_comboBox; delete m_model; - delete m_manageButton; } private: @@ -1179,7 +1172,6 @@ private: { addMutableAction(m_comboBox); builder.addItem(m_comboBox); - builder.addItem(m_manageButton); } void makeReadOnly() override { m_comboBox->setEnabled(false); } @@ -1219,7 +1211,6 @@ private: Guard m_ignoreChanges; QComboBox *m_comboBox; - QWidget *m_manageButton; DeviceManagerModel *m_model; Id m_selectedId; }; diff --git a/src/plugins/projectexplorer/kitmanager.cpp b/src/plugins/projectexplorer/kitmanager.cpp index 73d9d48feab..27e25e615c7 100644 --- a/src/plugins/projectexplorer/kitmanager.cpp +++ b/src/plugins/projectexplorer/kitmanager.cpp @@ -772,6 +772,17 @@ KitAspect::~KitAspect() delete m_mutableAction; } +void KitAspect::makeStickySubWidgetsReadOnly() +{ + if (!m_kit->isSticky(m_factory->id())) + return; + + if (m_manageButton) + m_manageButton->setEnabled(false); + + makeReadOnly(); +} + void KitAspect::addToLayout(Layouting::LayoutItem &parentItem) { auto label = createSubWidget(m_factory->displayName() + ':'); @@ -782,6 +793,13 @@ void KitAspect::addToLayout(Layouting::LayoutItem &parentItem) parentItem.addItem(label); addToLayoutImpl(parentItem); + if (m_managingPageId.isValid()) { + m_manageButton = createSubWidget(msgManage()); + connect(m_manageButton, &QPushButton::clicked, [this] { + Core::ICore::showOptionsDialog(m_managingPageId); + }); + parentItem.addItem(m_manageButton); + } parentItem.addItem(Layouting::br); } @@ -792,15 +810,6 @@ void KitAspect::addMutableAction(QWidget *child) child->setContextMenuPolicy(Qt::ActionsContextMenu); } -QWidget *KitAspect::createManageButton(Id pageId) -{ - auto button = createSubWidget(msgManage()); - connect(button, &QPushButton::clicked, this, [pageId] { - Core::ICore::showOptionsDialog(pageId); - }); - return button; -} - QString KitAspect::msgManage() { return Tr::tr("Manage..."); diff --git a/src/plugins/projectexplorer/kitmanager.h b/src/plugins/projectexplorer/kitmanager.h index 4d62ea4960d..401cf292225 100644 --- a/src/plugins/projectexplorer/kitmanager.h +++ b/src/plugins/projectexplorer/kitmanager.h @@ -108,7 +108,6 @@ public: KitAspect(Kit *kit, const KitAspectFactory *factory); ~KitAspect(); - virtual void makeReadOnly() = 0; virtual void refresh() = 0; void addToLayout(Layouting::LayoutItem &parentItem) override; @@ -119,14 +118,19 @@ public: const KitAspectFactory *factory() const { return m_factory; } QAction *mutableAction() const { return m_mutableAction; } void addMutableAction(QWidget *child); - QWidget *createManageButton(Utils::Id pageId); + void setManagingPage(Utils::Id pageId) { m_managingPageId = pageId; } + + void makeStickySubWidgetsReadOnly(); protected: + virtual void makeReadOnly() {} virtual void addToLayoutImpl(Layouting::LayoutItem &parentItem) = 0; Kit *m_kit; const KitAspectFactory *m_factory; QAction *m_mutableAction = nullptr; + Utils::Id m_managingPageId; + QPushButton *m_manageButton = nullptr; }; class PROJECTEXPLORER_EXPORT KitManager final : public QObject diff --git a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp index eb6b32b2c99..2c142dec886 100644 --- a/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp +++ b/src/plugins/projectexplorer/kitmanagerconfigwidget.cpp @@ -222,10 +222,8 @@ void KitManagerConfigWidget::updateVisibility() void KitManagerConfigWidget::makeStickySubWidgetsReadOnly() { - for (KitAspect *aspect : std::as_const(m_kitAspects)) { - if (aspect->kit()->isSticky(aspect->factory()->id())) - aspect->makeReadOnly(); - } + for (KitAspect *aspect : std::as_const(m_kitAspects)) + aspect->makeStickySubWidgetsReadOnly(); } Kit *KitManagerConfigWidget::workingCopy() const diff --git a/src/plugins/python/pythonkitaspect.cpp b/src/plugins/python/pythonkitaspect.cpp index 2adbdd3e13d..ec3609c8cd9 100644 --- a/src/plugins/python/pythonkitaspect.cpp +++ b/src/plugins/python/pythonkitaspect.cpp @@ -27,6 +27,8 @@ public: PythonKitAspectImpl(Kit *kit, const KitAspectFactory *kitInfo) : KitAspect(kit, kitInfo) { + setManagingPage(Constants::C_PYTHONOPTIONS_PAGE_ID); + m_comboBox = createSubWidget(); m_comboBox->setSizePolicy(QSizePolicy::Ignored, m_comboBox->sizePolicy().verticalPolicy()); @@ -38,13 +40,10 @@ public: PythonKitAspect::setPython(m_kit, m_comboBox->currentData().toString()); }); - - m_manageButton = createManageButton(Constants::C_PYTHONOPTIONS_PAGE_ID); } void makeReadOnly() override { - m_manageButton->setEnabled(false); m_comboBox->setEnabled(false); } @@ -71,13 +70,11 @@ protected: { addMutableAction(m_comboBox); parent.addItem(m_comboBox); - parent.addItem(m_manageButton); } private: Guard m_ignoreChanges; QComboBox *m_comboBox = nullptr; - QWidget *m_manageButton = nullptr; }; class PythonKitAspectFactory : public KitAspectFactory diff --git a/src/plugins/qtsupport/qtkitaspect.cpp b/src/plugins/qtsupport/qtkitaspect.cpp index d6fa4a21225..982f1e2726c 100644 --- a/src/plugins/qtsupport/qtkitaspect.cpp +++ b/src/plugins/qtsupport/qtkitaspect.cpp @@ -35,11 +35,11 @@ class QtKitAspectImpl final : public KitAspect public: QtKitAspectImpl(Kit *k, const KitAspectFactory *ki) : KitAspect(k, ki) { + setManagingPage(Constants::QTVERSION_SETTINGS_PAGE_ID); + m_combo = createSubWidget(); m_combo->setSizePolicy(QSizePolicy::Ignored, m_combo->sizePolicy().verticalPolicy()); - m_manageButton = createManageButton(Constants::QTVERSION_SETTINGS_PAGE_ID); - refresh(); m_combo->setToolTip(ki->description()); @@ -57,7 +57,6 @@ public: ~QtKitAspectImpl() final { delete m_combo; - delete m_manageButton; } private: @@ -67,7 +66,6 @@ private: { addMutableAction(m_combo); parent.addItem(m_combo); - parent.addItem(m_manageButton); } void refresh() final @@ -126,7 +124,6 @@ private: Guard m_ignoreChanges; QComboBox *m_combo; - QWidget *m_manageButton; }; } // namespace Internal From 6685f0255d8703126c1046d2af5aaea6ca110cd2 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 19 Oct 2023 17:17:37 +0200 Subject: [PATCH 0122/1546] Utils/all: Move mime constants into a central place They are reasonably standardized, and generally usable cross-plugin, so this can help to avoid a few cross-plugin compiletime dependencies. Change-Id: Icb2b010c3e12dee69df54ab16f6f8e90d9cffba6 Reviewed-by: Eike Ziller --- src/libs/utils/CMakeLists.txt | 1 + src/libs/utils/mimeconstants.h | 48 ++++++++++++++++++ src/libs/utils/utils.qbs | 1 + src/plugins/android/androidconstants.h | 1 - src/plugins/android/javaeditor.cpp | 5 +- src/plugins/android/javalanguageserver.cpp | 6 ++- .../autotoolsbuildconfiguration.cpp | 4 +- .../autotoolsprojectconstants.h | 13 ++--- .../autotoolsprojectplugin.cpp | 4 +- src/plugins/bineditor/bineditorconstants.h | 1 - src/plugins/bineditor/bineditorplugin.cpp | 28 +++++------ src/plugins/clangcodemodel/clangdclient.cpp | 3 +- .../cmakebuildconfiguration.cpp | 3 +- .../cmakeprojectmanager/cmakebuildsystem.cpp | 29 +++++------ .../cmakeprojectmanager/cmakeeditor.cpp | 10 ++-- .../cmakeprojectmanager/cmakeproject.cpp | 5 +- .../cmakeprojectconstants.h | 2 - .../cmakeprojectplugin.cpp | 3 +- .../fileapidataextractor.cpp | 9 ++-- src/plugins/cpaster/protocol.cpp | 49 +++++++++---------- src/plugins/cppeditor/cppcompletionassist.cpp | 23 ++++----- src/plugins/cppeditor/cppeditorconstants.h | 10 ---- src/plugins/cppeditor/cppeditordocument.cpp | 5 +- src/plugins/cppeditor/cppeditorplugin.cpp | 34 +++++++------ src/plugins/cppeditor/cppfilesettingspage.cpp | 10 ++-- src/plugins/cppeditor/cppprojectfile.cpp | 25 +++++----- src/plugins/cppeditor/cpptoolssettings.cpp | 10 ++-- src/plugins/designer/cpp/formclasswizard.cpp | 9 +++- src/plugins/designer/designerconstants.h | 1 - src/plugins/designer/formeditor.cpp | 3 +- src/plugins/designer/formeditorfactory.cpp | 5 +- src/plugins/designer/formeditorplugin.cpp | 11 +++-- src/plugins/designer/formwindowfile.cpp | 5 +- src/plugins/glsleditor/glsleditor.cpp | 11 +++-- src/plugins/glsleditor/glsleditorconstants.h | 6 --- src/plugins/glsleditor/glsleditorplugin.cpp | 12 +++-- .../customwizard/customwizardparameters.cpp | 6 +-- .../projectexplorerconstants.h | 12 ----- src/plugins/projectexplorer/projectnodes.cpp | 16 +++--- src/plugins/qbsprojectmanager/qbsproject.cpp | 17 ++++--- .../qbsprojectmanagerplugin.cpp | 8 +-- .../qmakeprojectmanager/profileeditor.cpp | 18 +++---- .../qmakebuildconfiguration.cpp | 3 +- .../qmakeprojectmanager/qmakeparsernodes.cpp | 36 +++++++------- .../qmakeprojectmanager/qmakeproject.cpp | 5 +- .../qmakeprojectmanagerconstants.h | 6 --- .../qmakeprojectmanagerplugin.cpp | 3 +- .../qmakeprojectmanager/wizards/qtwizard.cpp | 8 ++- .../bindingeditor/bindingeditorwidget.cpp | 18 ++++--- src/plugins/qmldesigner/qmldesignerplugin.cpp | 7 +-- src/plugins/qmljseditor/qmljseditor.cpp | 21 ++++---- src/plugins/qmljseditor/qmllsclient.cpp | 10 ++-- src/plugins/qmljstools/qmljsmodelmanager.cpp | 32 ++++++------ src/plugins/qmljstools/qmljstoolsconstants.h | 8 --- src/plugins/qmljstools/qmljstoolssettings.cpp | 17 ++++--- src/plugins/qmlpreview/qmlpreviewplugin.cpp | 18 ++++--- .../qmlprojectmanager/qmlmainfileaspect.cpp | 11 +++-- src/plugins/qmlprojectmanager/qmlproject.cpp | 3 +- .../qmlprojectmanager/qmlprojectconstants.h | 10 ++-- .../qmlprojectmanager/qmlprojectplugin.cpp | 5 +- src/plugins/qtsupport/externaleditors.cpp | 7 ++- .../resourceeditor/resourceeditorconstants.h | 2 - .../resourceeditor/resourceeditorfactory.cpp | 9 ++-- .../resourceeditor/resourceeditorw.cpp | 3 +- src/plugins/resourceeditor/resourcenode.cpp | 12 ++--- src/plugins/scxmleditor/scxmleditordata.cpp | 3 +- .../scxmleditor/scxmleditordocument.cpp | 6 +-- .../scxmleditor/scxmleditorfactory.cpp | 6 +-- 68 files changed, 396 insertions(+), 355 deletions(-) create mode 100644 src/libs/utils/mimeconstants.h diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt index be022f6a838..023af544643 100644 --- a/src/libs/utils/CMakeLists.txt +++ b/src/libs/utils/CMakeLists.txt @@ -92,6 +92,7 @@ add_qtc_library(Utils listutils.h macroexpander.cpp macroexpander.h mathutils.cpp mathutils.h + mimeconstants.h mimeutils.h minimizableinfobars.cpp minimizableinfobars.h diff --git a/src/libs/utils/mimeconstants.h b/src/libs/utils/mimeconstants.h new file mode 100644 index 00000000000..2e9e393661c --- /dev/null +++ b/src/libs/utils/mimeconstants.h @@ -0,0 +1,48 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +namespace Utils::Constants { + +const char FORM_MIMETYPE[] = "application/x-designer"; +const char GLSL_MIMETYPE[] = "application/x-glsl"; +const char JSON_MIMETYPE[] = "application/json"; +const char JS_MIMETYPE[] = "application/javascript"; +const char OCTET_STREAM_MIMETYPE[] = "application/octet-stream"; +const char QBS_MIMETYPE[] = "application/x-qt.qbs+qml"; +const char QMLPROJECT_MIMETYPE[] = "application/x-qmlproject"; +const char QMLTYPES_MIMETYPE[] = "application/x-qt.meta-info+qml"; +const char QMLUI_MIMETYPE[] = "application/x-qt.ui+qml"; +const char SCXML_MIMETYPE[] = "application/scxml+xml"; + +const char AMBIGUOUS_HEADER_MIMETYPE[] = "application/vnd.qtc.ambiguousheader"; // not a real MIME type +const char PROFILE_MIMETYPE[] = "application/vnd.qt.qmakeprofile"; +const char PROINCLUDEFILE_MIMETYPE [] = "application/vnd.qt.qmakeproincludefile"; +const char PROFEATUREFILE_MIMETYPE [] = "application/vnd.qt.qmakeprofeaturefile"; +const char PROCONFIGURATIONFILE_MIMETYPE [] = "application/vnd.qt.qmakeproconfigurationfile"; +const char PROCACHEFILE_MIMETYPE [] = "application/vnd.qt.qmakeprocachefile"; +const char PROSTASHFILE_MIMETYPE [] = "application/vnd.qt.qmakeprostashfile"; +const char RESOURCE_MIMETYPE[] = "application/vnd.qt.xml.resource"; + +const char CMAKE_MIMETYPE[] = "text/x-cmake"; +const char CMAKE_PROJECT_MIMETYPE[] = "text/x-cmake-project"; +const char CPP_HEADER_MIMETYPE[] = "text/x-c++hdr"; +const char CPP_SOURCE_MIMETYPE[] = "text/x-c++src"; +const char CUDA_SOURCE_MIMETYPE[] = "text/vnd.nvidia.cuda.csrc"; +const char C_HEADER_MIMETYPE[] = "text/x-chdr"; +const char C_SOURCE_MIMETYPE[] = "text/x-csrc"; +const char GLSL_MIMETYPE_FRAG[] = "text/x-glsl-frag"; +const char GLSL_MIMETYPE_FRAG_ES[] = "text/x-glsl-es-frag"; +const char GLSL_MIMETYPE_VERT[] = "text/x-glsl-vert"; +const char GLSL_MIMETYPE_VERT_ES[] = "text/x-glsl-es-vert"; +const char JAVA_MIMETYPE[] = "text/x-java"; +const char LINGUIST_MIMETYPE[] = "text/vnd.trolltech.linguist"; +const char MAKEFILE_MIMETYPE[] = "text/x-makefile"; +const char MOC_MIMETYPE[] = "text/x-moc"; +const char OBJECTIVE_CPP_SOURCE_MIMETYPE[] = "text/x-objc++src"; +const char OBJECTIVE_C_SOURCE_MIMETYPE[] = "text/x-objcsrc"; +const char QDOC_MIMETYPE[] = "text/x-qdoc"; +const char QML_MIMETYPE[] = "text/x-qml"; + +} // Utils::Constants diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs index f67c80e1dd5..ca8d616dd2c 100644 --- a/src/libs/utils/utils.qbs +++ b/src/libs/utils/utils.qbs @@ -186,6 +186,7 @@ QtcLibrary { "macroexpander.h", "mathutils.cpp", "mathutils.h", + "mimeconstants.h", "mimeutils.h", "minimizableinfobars.cpp", "minimizableinfobars.h", diff --git a/src/plugins/android/androidconstants.h b/src/plugins/android/androidconstants.h index dd3a06fa607..842e105cf52 100644 --- a/src/plugins/android/androidconstants.h +++ b/src/plugins/android/androidconstants.h @@ -30,7 +30,6 @@ const char ANDROID_BUILD_DIRECTORY[] = "android-build"; const char ANDROID_APP_PROCESS_DIRECTORY[] = "android-app-process"; const char JAVA_EDITOR_ID[] = "java.editor"; const char JLS_SETTINGS_ID[] = "Java::JLSSettingsID"; -const char JAVA_MIMETYPE[] = "text/x-java"; const char ANDROID_ARCHITECTURE[] = "Android.Architecture"; const char ANDROID_PACKAGE_SOURCE_DIR[] = "ANDROID_PACKAGE_SOURCE_DIR"; const char ANDROID_EXTRA_LIBS[] = "ANDROID_EXTRA_LIBS"; diff --git a/src/plugins/android/javaeditor.cpp b/src/plugins/android/javaeditor.cpp index 8f7323c0f83..edd63e073bb 100644 --- a/src/plugins/android/javaeditor.cpp +++ b/src/plugins/android/javaeditor.cpp @@ -15,6 +15,7 @@ #include #include +#include #include namespace Android::Internal { @@ -23,7 +24,7 @@ static TextEditor::TextDocument *createJavaDocument() { auto doc = new TextEditor::TextDocument; doc->setId(Constants::JAVA_EDITOR_ID); - doc->setMimeType(QLatin1String(Constants::JAVA_MIMETYPE)); + doc->setMimeType(Utils::Constants::JAVA_MIMETYPE); doc->setIndenter(new JavaIndenter(doc->document())); return doc; } @@ -44,7 +45,7 @@ JavaEditorFactory::JavaEditorFactory() }; setId(Constants::JAVA_EDITOR_ID); setDisplayName(::Core::Tr::tr("Java Editor")); - addMimeType(Constants::JAVA_MIMETYPE); + addMimeType(Utils::Constants::JAVA_MIMETYPE); setDocumentCreator(createJavaDocument); setUseGenericHighlighter(true); diff --git a/src/plugins/android/javalanguageserver.cpp b/src/plugins/android/javalanguageserver.cpp index db8d0745f62..8f1da2e80c6 100644 --- a/src/plugins/android/javalanguageserver.cpp +++ b/src/plugins/android/javalanguageserver.cpp @@ -10,12 +10,16 @@ #include #include #include + #include #include #include #include + #include + #include +#include #include #include #include @@ -80,7 +84,7 @@ JLSSettings::JLSSettings() m_settingsTypeId = Constants::JLS_SETTINGS_ID; m_name = "Java Language Server"; m_startBehavior = RequiresProject; - m_languageFilter.mimeTypes = QStringList(Constants::JAVA_MIMETYPE); + m_languageFilter.mimeTypes = QStringList(Utils::Constants::JAVA_MIMETYPE); const FilePath &javaPath = Environment::systemEnvironment().searchInPath("java"); if (javaPath.exists()) m_executable = javaPath; diff --git a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp index 583a4c471c8..c2224a92b00 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsbuildconfiguration.cpp @@ -13,6 +13,8 @@ #include #include +#include + using namespace ProjectExplorer; using namespace Utils; @@ -53,7 +55,7 @@ AutotoolsBuildConfigurationFactory::AutotoolsBuildConfigurationFactory() ("AutotoolsProjectManager.AutotoolsBuildConfiguration"); setSupportedProjectType(Constants::AUTOTOOLS_PROJECT_ID); - setSupportedProjectMimeTypeName(Constants::MAKEFILE_MIMETYPE); + setSupportedProjectMimeTypeName(Utils::Constants::MAKEFILE_MIMETYPE); setBuildGenerator([](const Kit *, const FilePath &projectPath, bool forSetup) { BuildInfo info; diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectconstants.h b/src/plugins/autotoolsprojectmanager/autotoolsprojectconstants.h index 2a36f30459f..4f460b337b3 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsprojectconstants.h +++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectconstants.h @@ -3,13 +3,7 @@ #pragma once -namespace AutotoolsProjectManager { -/** - * Collects project constants, that are shared between several classes. - */ -namespace Constants { - -const char MAKEFILE_MIMETYPE[] = "text/x-makefile"; +namespace AutotoolsProjectManager::Constants { // Steps const char AUTOGEN_STEP_ID[] = "AutotoolsProjectManager.AutogenStep"; @@ -17,8 +11,7 @@ const char AUTORECONF_STEP_ID[] = "AutotoolsProjectManager.AutoreconfStep"; const char CONFIGURE_STEP_ID[] = "AutotoolsProjectManager.ConfigureStep"; const char MAKE_STEP_ID[] = "AutotoolsProjectManager.MakeStep"; -//Project +// Project const char AUTOTOOLS_PROJECT_ID[] = "AutotoolsProjectManager.AutotoolsProject"; -} // namespace Constants -} // namespace AutotoolsProjectManager +} // AutotoolsProjectManager::Constants diff --git a/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp b/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp index 7dd53126506..a1dc54db772 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsprojectplugin.cpp @@ -18,6 +18,8 @@ #include +#include + using namespace ProjectExplorer; namespace AutotoolsProjectManager::Internal { @@ -34,7 +36,7 @@ class AutotoolsProject : public Project { public: explicit AutotoolsProject(const Utils::FilePath &fileName) - : Project(Constants::MAKEFILE_MIMETYPE, fileName) + : Project(Utils::Constants::MAKEFILE_MIMETYPE, fileName) { setId(Constants::AUTOTOOLS_PROJECT_ID); setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); diff --git a/src/plugins/bineditor/bineditorconstants.h b/src/plugins/bineditor/bineditorconstants.h index 6905ad97d85..2bcd51e435f 100644 --- a/src/plugins/bineditor/bineditorconstants.h +++ b/src/plugins/bineditor/bineditorconstants.h @@ -6,7 +6,6 @@ namespace BinEditor::Constants { const char C_BINEDITOR[] = "BinEditor.BinaryEditor"; -const char C_BINEDITOR_MIMETYPE[] = "application/octet-stream"; const char C_ENCODING_SETTING[] = "BinEditor/TextEncoding"; } // BinEditor::Constants diff --git a/src/plugins/bineditor/bineditorplugin.cpp b/src/plugins/bineditor/bineditorplugin.cpp index 54b91401ad5..1e1c2c2da86 100644 --- a/src/plugins/bineditor/bineditorplugin.cpp +++ b/src/plugins/bineditor/bineditorplugin.cpp @@ -8,12 +8,24 @@ #include "bineditortr.h" #include "bineditorwidget.h" +#include +#include #include +#include +#include #include +#include #include +#include + +#include #include +#include +#include +#include + #include #include #include @@ -23,18 +35,6 @@ #include #include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - using namespace Utils; using namespace Core; @@ -189,7 +189,7 @@ public: IDocument(parent) { setId(Core::Constants::K_DEFAULT_BINARY_EDITOR_ID); - setMimeType(QLatin1String(BinEditor::Constants::C_BINEDITOR_MIMETYPE)); + setMimeType(Utils::Constants::OCTET_STREAM_MIMETYPE); m_widget = parent; EditorService *es = m_widget->editorService(); es->setFetchDataHandler([this](quint64 address) { provideData(address); }); @@ -450,7 +450,7 @@ BinEditorFactory::BinEditorFactory() { setId(Core::Constants::K_DEFAULT_BINARY_EDITOR_ID); setDisplayName(::Core::Tr::tr("Binary Editor")); - addMimeType(Constants::C_BINEDITOR_MIMETYPE); + addMimeType(Utils::Constants::OCTET_STREAM_MIMETYPE); setEditorCreator([] { auto widget = new BinEditorWidget(); diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index 565c8306a0b..ecf82f67e8d 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -59,6 +59,7 @@ #include #include #include +#include #include #include #include @@ -397,7 +398,7 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir, c { setName(Tr::tr("clangd")); LanguageFilter langFilter; - using namespace CppEditor::Constants; + using namespace Utils::Constants; langFilter.mimeTypes = QStringList{C_HEADER_MIMETYPE, C_SOURCE_MIMETYPE, CPP_HEADER_MIMETYPE, CPP_SOURCE_MIMETYPE, OBJECTIVE_CPP_SOURCE_MIMETYPE, OBJECTIVE_C_SOURCE_MIMETYPE, CUDA_SOURCE_MIMETYPE}; diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index ed81a8fea95..c00d8f4f510 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -1875,7 +1876,7 @@ CMakeBuildConfigurationFactory::CMakeBuildConfigurationFactory() registerBuildConfiguration(Constants::CMAKE_BUILDCONFIGURATION_ID); setSupportedProjectType(CMakeProjectManager::Constants::CMAKE_PROJECT_ID); - setSupportedProjectMimeTypeName(Constants::CMAKE_PROJECT_MIMETYPE); + setSupportedProjectMimeTypeName(Utils::Constants::CMAKE_PROJECT_MIMETYPE); setBuildGenerator([](const Kit *k, const FilePath &projectPath, bool forSetup) { QList result; diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index bd686268336..6262a9342e6 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -23,8 +23,6 @@ #include #include -#include - #include #include #include @@ -38,15 +36,13 @@ #include -#include - #include #include #include #include -#include #include +#include #include #include @@ -100,8 +96,8 @@ CMakeBuildSystem::CMakeBuildSystem(CMakeBuildConfiguration *bc) if (type == FileType::Unknown) { if (mimeType.isValid()) { const QString mt = mimeType.name(); - if (mt == CMakeProjectManager::Constants::CMAKE_PROJECT_MIMETYPE - || mt == CMakeProjectManager::Constants::CMAKE_MIMETYPE) + if (mt == Utils::Constants::CMAKE_PROJECT_MIMETYPE + || mt == Utils::Constants::CMAKE_MIMETYPE) type = FileType::Project; } } @@ -239,17 +235,18 @@ static QString newFilesForFunction(const std::string &cmakeFunction, FilePaths qmlFiles; for (const auto &file : filePaths) { + using namespace Utils::Constants; const auto mimeType = Utils::mimeTypeForFile(file); - if (mimeType.matchesName(CppEditor::Constants::CPP_SOURCE_MIMETYPE) - || mimeType.matchesName(CppEditor::Constants::CPP_HEADER_MIMETYPE) - || mimeType.matchesName(CppEditor::Constants::OBJECTIVE_C_SOURCE_MIMETYPE) - || mimeType.matchesName(CppEditor::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)) { + if (mimeType.matchesName(CPP_SOURCE_MIMETYPE) + || mimeType.matchesName(CPP_HEADER_MIMETYPE) + || mimeType.matchesName(OBJECTIVE_C_SOURCE_MIMETYPE) + || mimeType.matchesName(OBJECTIVE_CPP_SOURCE_MIMETYPE)) { sourceFiles << file; - } else if (mimeType.matchesName(QmlJSTools::Constants::QML_MIMETYPE) - || mimeType.matchesName(QmlJSTools::Constants::QMLUI_MIMETYPE) - || mimeType.matchesName(QmlJSTools::Constants::QMLPROJECT_MIMETYPE) - || mimeType.matchesName(QmlJSTools::Constants::JS_MIMETYPE) - || mimeType.matchesName(QmlJSTools::Constants::JSON_MIMETYPE)) { + } else if (mimeType.matchesName(QML_MIMETYPE) + || mimeType.matchesName(QMLUI_MIMETYPE) + || mimeType.matchesName(QMLPROJECT_MIMETYPE) + || mimeType.matchesName(JS_MIMETYPE) + || mimeType.matchesName(JSON_MIMETYPE)) { qmlFiles << file; } else { resourceFiles << file; diff --git a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp index 85822697d2e..981dcf8d7d9 100644 --- a/src/plugins/cmakeprojectmanager/cmakeeditor.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeeditor.cpp @@ -15,15 +15,19 @@ #include #include #include + #include #include #include #include #include #include + #include #include #include + +#include #include #include @@ -411,7 +415,7 @@ static TextDocument *createCMakeDocument() { auto doc = new TextDocument; doc->setId(Constants::CMAKE_EDITOR_ID); - doc->setMimeType(QLatin1String(Constants::CMAKE_MIMETYPE)); + doc->setMimeType(Utils::Constants::CMAKE_MIMETYPE); return doc; } @@ -505,8 +509,8 @@ CMakeEditorFactory::CMakeEditorFactory() { setId(Constants::CMAKE_EDITOR_ID); setDisplayName(::Core::Tr::tr("CMake Editor")); - addMimeType(Constants::CMAKE_MIMETYPE); - addMimeType(Constants::CMAKE_PROJECT_MIMETYPE); + addMimeType(Utils::Constants::CMAKE_MIMETYPE); + addMimeType(Utils::Constants::CMAKE_PROJECT_MIMETYPE); setEditorCreator([] { return new CMakeEditor; }); setEditorWidgetCreator([] { return new CMakeEditorWidget; }); diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index f29ef14ac23..084925c8fc1 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -17,8 +17,11 @@ #include #include #include + #include +#include + using namespace ProjectExplorer; using namespace Utils; using namespace CMakeProjectManager::Internal; @@ -29,7 +32,7 @@ namespace CMakeProjectManager { \class CMakeProject */ CMakeProject::CMakeProject(const FilePath &fileName) - : Project(Constants::CMAKE_MIMETYPE, fileName) + : Project(Utils::Constants::CMAKE_MIMETYPE, fileName) { setId(CMakeProjectManager::Constants::CMAKE_PROJECT_ID); setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h b/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h index 2e9a6ea58e0..1bd9e1ce7a2 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h +++ b/src/plugins/cmakeprojectmanager/cmakeprojectconstants.h @@ -6,8 +6,6 @@ namespace CMakeProjectManager { namespace Constants { -const char CMAKE_MIMETYPE[] = "text/x-cmake"; -const char CMAKE_PROJECT_MIMETYPE[] = "text/x-cmake-project"; const char CMAKE_EDITOR_ID[] = "CMakeProject.CMakeEditor"; const char RUN_CMAKE[] = "CMakeProject.RunCMake"; const char RUN_CMAKE_PROFILER[] = "CMakeProject.RunCMakeProfiler"; diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp index 811d2c0e4b3..b600a87f3c3 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -82,7 +83,7 @@ void CMakeProjectPlugin::initialize() TextEditor::SnippetProvider::registerGroup(Constants::CMAKE_SNIPPETS_GROUP_ID, Tr::tr("CMake", "SnippetProvider")); - ProjectManager::registerProjectType(Constants::CMAKE_PROJECT_MIMETYPE); + ProjectManager::registerProjectType(Utils::Constants::CMAKE_PROJECT_MIMETYPE); //register actions Command *command = ActionManager::registerAction(&d->buildTargetContextAction, diff --git a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp index b5b692da080..1b60cd08619 100644 --- a/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp +++ b/src/plugins/cmakeprojectmanager/fileapidataextractor.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -68,8 +69,8 @@ static CMakeFileResult extractCMakeFilesData(const QFuture &cancelFuture, absolute.path = sfn; const auto mimeType = Utils::mimeTypeForFile(info.path); - if (mimeType.matchesName(Constants::CMAKE_MIMETYPE) - || mimeType.matchesName(Constants::CMAKE_PROJECT_MIMETYPE)) { + if (mimeType.matchesName(Utils::Constants::CMAKE_MIMETYPE) + || mimeType.matchesName(Utils::Constants::CMAKE_PROJECT_MIMETYPE)) { expected_str fileContent = sfn.fileContents(); std::string errorString; if (fileContent) { @@ -445,9 +446,9 @@ static RawProjectParts generateRawProjectParts(const QFuture &cancelFuture const QString headerMimeType = [&]() -> QString { if (ci.language == "C") { - return CppEditor::Constants::C_HEADER_MIMETYPE; + return Utils::Constants::C_HEADER_MIMETYPE; } else if (ci.language == "CXX") { - return CppEditor::Constants::CPP_HEADER_MIMETYPE; + return Utils::Constants::CPP_HEADER_MIMETYPE; } return {}; }(); diff --git a/src/plugins/cpaster/protocol.cpp b/src/plugins/cpaster/protocol.cpp index c2630d09c13..dcc3af47c18 100644 --- a/src/plugins/cpaster/protocol.cpp +++ b/src/plugins/cpaster/protocol.cpp @@ -5,16 +5,12 @@ #include "cpastertr.h" -#include - -#include -#include -#include -#include -#include #include #include +#include +#include + #include #include #include @@ -59,32 +55,33 @@ void Protocol::list() Protocol::ContentType Protocol::contentType(const QString &mt) { - if (mt == QLatin1String(CppEditor::Constants::C_SOURCE_MIMETYPE) - || mt == QLatin1String(CppEditor::Constants::C_HEADER_MIMETYPE) - || mt == QLatin1String(GlslEditor::Constants::GLSL_MIMETYPE) - || mt == QLatin1String(GlslEditor::Constants::GLSL_MIMETYPE_VERT) - || mt == QLatin1String(GlslEditor::Constants::GLSL_MIMETYPE_FRAG) - || mt == QLatin1String(GlslEditor::Constants::GLSL_MIMETYPE_VERT_ES) - || mt == QLatin1String(GlslEditor::Constants::GLSL_MIMETYPE_FRAG_ES)) + using namespace Utils::Constants; + if (mt == QLatin1String(C_SOURCE_MIMETYPE) + || mt == QLatin1String(C_HEADER_MIMETYPE) + || mt == QLatin1String(GLSL_MIMETYPE) + || mt == QLatin1String(GLSL_MIMETYPE_VERT) + || mt == QLatin1String(GLSL_MIMETYPE_FRAG) + || mt == QLatin1String(GLSL_MIMETYPE_VERT_ES) + || mt == QLatin1String(GLSL_MIMETYPE_FRAG_ES)) return C; - if (mt == QLatin1String(CppEditor::Constants::CPP_SOURCE_MIMETYPE) - || mt == QLatin1String(CppEditor::Constants::CPP_HEADER_MIMETYPE) - || mt == QLatin1String(CppEditor::Constants::OBJECTIVE_C_SOURCE_MIMETYPE) - || mt == QLatin1String(CppEditor::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)) + if (mt == QLatin1String(CPP_SOURCE_MIMETYPE) + || mt == QLatin1String(CPP_HEADER_MIMETYPE) + || mt == QLatin1String(OBJECTIVE_C_SOURCE_MIMETYPE) + || mt == QLatin1String(OBJECTIVE_CPP_SOURCE_MIMETYPE)) return Cpp; - if (mt == QLatin1String(QmlJSTools::Constants::QML_MIMETYPE) - || mt == QLatin1String(QmlJSTools::Constants::QMLUI_MIMETYPE) - || mt == QLatin1String(QmlJSTools::Constants::QMLPROJECT_MIMETYPE) - || mt == QLatin1String(QmlJSTools::Constants::QBS_MIMETYPE) - || mt == QLatin1String(QmlJSTools::Constants::JS_MIMETYPE) - || mt == QLatin1String(QmlJSTools::Constants::JSON_MIMETYPE)) + if (mt == QLatin1String(QML_MIMETYPE) + || mt == QLatin1String(QMLUI_MIMETYPE) + || mt == QLatin1String(QMLPROJECT_MIMETYPE) + || mt == QLatin1String(QBS_MIMETYPE) + || mt == QLatin1String(JS_MIMETYPE) + || mt == QLatin1String(JSON_MIMETYPE)) return JavaScript; if (mt == QLatin1String("text/x-patch")) return Diff; if (mt == QLatin1String("text/xml") || mt == QLatin1String("application/xml") - || mt == QLatin1String(ResourceEditor::Constants::C_RESOURCE_MIMETYPE) - || mt == QLatin1String(Designer::Constants::FORM_MIMETYPE)) + || mt == QLatin1String(RESOURCE_MIMETYPE) + || mt == QLatin1String(FORM_MIMETYPE)) return Xml; return Text; } diff --git a/src/plugins/cppeditor/cppcompletionassist.cpp b/src/plugins/cppeditor/cppcompletionassist.cpp index 82d15774330..eb5b7b4d07d 100644 --- a/src/plugins/cppeditor/cppcompletionassist.cpp +++ b/src/plugins/cppeditor/cppcompletionassist.cpp @@ -5,13 +5,20 @@ #include "builtineditordocumentparser.h" #include "cppdoxygen.h" -#include "cppeditorconstants.h" #include "cppmodelmanager.h" #include "cpptoolsreuse.h" -#include "editordocumenthandle.h" #include + +#include +#include +#include +#include +#include +#include + #include + #include #include #include @@ -21,17 +28,11 @@ #include #include +#include #include #include #include -#include -#include -#include -#include -#include -#include - #include #include #include @@ -1267,8 +1268,8 @@ bool InternalCppCompletionAssistProcessor::objcKeywordsWanted() const return false; const Utils::MimeType mt = Utils::mimeTypeForFile(interface()->filePath()); - return mt.matchesName(QLatin1String(CppEditor::Constants::OBJECTIVE_C_SOURCE_MIMETYPE)) - || mt.matchesName(QLatin1String(CppEditor::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)); + return mt.matchesName(QLatin1String(Utils::Constants::OBJECTIVE_C_SOURCE_MIMETYPE)) + || mt.matchesName(QLatin1String(Utils::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)); } int InternalCppCompletionAssistProcessor::startCompletionInternal(const Utils::FilePath &filePath, diff --git a/src/plugins/cppeditor/cppeditorconstants.h b/src/plugins/cppeditor/cppeditorconstants.h index 3e3c02dc434..1c5cffee98f 100644 --- a/src/plugins/cppeditor/cppeditorconstants.h +++ b/src/plugins/cppeditor/cppeditorconstants.h @@ -67,16 +67,6 @@ const char SHOW_PREPROCESSED_FILE[] = "CppTools.ShowPreprocessedFile"; const char SHOW_PREPROCESSED_FILE_SPLIT[] = "CppTools.ShowPreprocessedFileSplit"; const char TASK_INDEX[] = "CppTools.Task.Index"; const char TASK_SEARCH[] = "CppTools.Task.Search"; -const char C_SOURCE_MIMETYPE[] = "text/x-csrc"; -const char CUDA_SOURCE_MIMETYPE[] = "text/vnd.nvidia.cuda.csrc"; -const char C_HEADER_MIMETYPE[] = "text/x-chdr"; -const char CPP_SOURCE_MIMETYPE[] = "text/x-c++src"; -const char OBJECTIVE_C_SOURCE_MIMETYPE[] = "text/x-objcsrc"; -const char OBJECTIVE_CPP_SOURCE_MIMETYPE[] = "text/x-objc++src"; -const char CPP_HEADER_MIMETYPE[] = "text/x-c++hdr"; -const char QDOC_MIMETYPE[] = "text/x-qdoc"; -const char MOC_MIMETYPE[] = "text/x-moc"; -const char AMBIGUOUS_HEADER_MIMETYPE[] = "application/vnd.qtc.ambiguousheader"; // not a real MIME type // QSettings keys for use by the "New Class" wizards. const char CPPEDITOR_SETTINGSGROUP[] = "CppTools"; diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp index 16cae978a82..18c729f7778 100644 --- a/src/plugins/cppeditor/cppeditordocument.cpp +++ b/src/plugins/cppeditor/cppeditordocument.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -180,8 +181,8 @@ void CppEditorDocument::invalidateFormatterCache() void CppEditorDocument::onMimeTypeChanged() { const QString &mt = mimeType(); - m_isObjCEnabled = (mt == QLatin1String(Constants::OBJECTIVE_C_SOURCE_MIMETYPE) - || mt == QLatin1String(Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)); + m_isObjCEnabled = (mt == QLatin1String(Utils::Constants::OBJECTIVE_C_SOURCE_MIMETYPE) + || mt == QLatin1String(Utils::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE)); m_completionAssistProvider = CppModelManager::completionAssistProvider(); initializeTimer(); diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp index 30fa3bdad9d..a11a71b0b1f 100644 --- a/src/plugins/cppeditor/cppeditorplugin.cpp +++ b/src/plugins/cppeditor/cppeditorplugin.cpp @@ -86,6 +86,7 @@ #include #include #include +#include #include #include #include @@ -127,12 +128,12 @@ public: { setId(Constants::CPPEDITOR_ID); setDisplayName(::Core::Tr::tr("C++ Editor")); - addMimeType(Constants::C_SOURCE_MIMETYPE); - addMimeType(Constants::C_HEADER_MIMETYPE); - addMimeType(Constants::CPP_SOURCE_MIMETYPE); - addMimeType(Constants::CPP_HEADER_MIMETYPE); - addMimeType(Constants::QDOC_MIMETYPE); - addMimeType(Constants::MOC_MIMETYPE); + addMimeType(Utils::Constants::C_SOURCE_MIMETYPE); + addMimeType(Utils::Constants::C_HEADER_MIMETYPE); + addMimeType(Utils::Constants::CPP_SOURCE_MIMETYPE); + addMimeType(Utils::Constants::CPP_HEADER_MIMETYPE); + addMimeType(Utils::Constants::QDOC_MIMETYPE); + addMimeType(Utils::Constants::MOC_MIMETYPE); setDocumentCreator([]() { return new CppEditorDocument; }); setEditorWidgetCreator([]() { return new CppEditorWidget; }); @@ -259,15 +260,15 @@ void CppEditorPlugin::extensionsInitialized() FileIconProvider::registerIconOverlayForMimeType( creatorTheme()->imageFile(Theme::IconOverlayCppSource, ProjectExplorer::Constants::FILEOVERLAY_CPP), - Constants::CPP_SOURCE_MIMETYPE); + Utils::Constants::CPP_SOURCE_MIMETYPE); FileIconProvider::registerIconOverlayForMimeType( creatorTheme()->imageFile(Theme::IconOverlayCSource, ProjectExplorer::Constants::FILEOVERLAY_C), - Constants::C_SOURCE_MIMETYPE); + Utils::Constants::C_SOURCE_MIMETYPE); FileIconProvider::registerIconOverlayForMimeType( creatorTheme()->imageFile(Theme::IconOverlayCppHeader, ProjectExplorer::Constants::FILEOVERLAY_H), - Constants::CPP_HEADER_MIMETYPE); + Utils::Constants::CPP_HEADER_MIMETYPE); } static void insertIntoMenus(const QList &menus, @@ -734,25 +735,26 @@ static FilePaths findFilesInProject(const QStringList &names, const Project *pro // source belonging to a header and vice versa static QStringList matchingCandidateSuffixes(ProjectFile::Kind kind) { + using namespace Utils::Constants; switch (kind) { case ProjectFile::AmbiguousHeader: case ProjectFile::CHeader: case ProjectFile::CXXHeader: case ProjectFile::ObjCHeader: case ProjectFile::ObjCXXHeader: - return mimeTypeForName(Constants::C_SOURCE_MIMETYPE).suffixes() - + mimeTypeForName(Constants::CPP_SOURCE_MIMETYPE).suffixes() - + mimeTypeForName(Constants::OBJECTIVE_C_SOURCE_MIMETYPE).suffixes() - + mimeTypeForName(Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE).suffixes() - + mimeTypeForName(Constants::CUDA_SOURCE_MIMETYPE).suffixes(); + return mimeTypeForName(C_SOURCE_MIMETYPE).suffixes() + + mimeTypeForName(CPP_SOURCE_MIMETYPE).suffixes() + + mimeTypeForName(OBJECTIVE_C_SOURCE_MIMETYPE).suffixes() + + mimeTypeForName(OBJECTIVE_CPP_SOURCE_MIMETYPE).suffixes() + + mimeTypeForName(CUDA_SOURCE_MIMETYPE).suffixes(); case ProjectFile::CSource: case ProjectFile::ObjCSource: - return mimeTypeForName(Constants::C_HEADER_MIMETYPE).suffixes(); + return mimeTypeForName(C_HEADER_MIMETYPE).suffixes(); case ProjectFile::CXXSource: case ProjectFile::ObjCXXSource: case ProjectFile::CudaSource: case ProjectFile::OpenCLSource: - return mimeTypeForName(Constants::CPP_HEADER_MIMETYPE).suffixes(); + return mimeTypeForName(CPP_HEADER_MIMETYPE).suffixes(); default: return {}; } diff --git a/src/plugins/cppeditor/cppfilesettingspage.cpp b/src/plugins/cppeditor/cppfilesettingspage.cpp index 4303fe67d4f..4ed79c4065e 100644 --- a/src/plugins/cppeditor/cppfilesettingspage.cpp +++ b/src/plugins/cppeditor/cppfilesettingspage.cpp @@ -8,11 +8,13 @@ #include #include + #include #include #include #include +#include #include #include #include @@ -85,11 +87,11 @@ void CppFileSettings::fromSettings(QtcSettings *s) static bool applySuffixes(const QString &sourceSuffix, const QString &headerSuffix) { Utils::MimeType mt; - mt = Utils::mimeTypeForName(QLatin1String(Constants::CPP_SOURCE_MIMETYPE)); + mt = Utils::mimeTypeForName(QLatin1String(Utils::Constants::CPP_SOURCE_MIMETYPE)); if (!mt.isValid()) return false; mt.setPreferredSuffix(sourceSuffix); - mt = Utils::mimeTypeForName(QLatin1String(Constants::CPP_HEADER_MIMETYPE)); + mt = Utils::mimeTypeForName(QLatin1String(Utils::Constants::CPP_HEADER_MIMETYPE)); if (!mt.isValid()) return false; mt.setPreferredSuffix(headerSuffix); @@ -324,14 +326,14 @@ CppFileSettingsWidget::CppFileSettingsWidget(CppFileSettings *settings) }.attachTo(this); // populate suffix combos - const MimeType sourceMt = Utils::mimeTypeForName(QLatin1String(Constants::CPP_SOURCE_MIMETYPE)); + const MimeType sourceMt = Utils::mimeTypeForName(Utils::Constants::CPP_SOURCE_MIMETYPE); if (sourceMt.isValid()) { const QStringList suffixes = sourceMt.suffixes(); for (const QString &suffix : suffixes) m_sourceSuffixComboBox->addItem(suffix); } - const MimeType headerMt = Utils::mimeTypeForName(QLatin1String(Constants::CPP_HEADER_MIMETYPE)); + const MimeType headerMt = Utils::mimeTypeForName(Utils::Constants::CPP_HEADER_MIMETYPE); if (headerMt.isValid()) { const QStringList suffixes = headerMt.suffixes(); for (const QString &suffix : suffixes) diff --git a/src/plugins/cppeditor/cppprojectfile.cpp b/src/plugins/cppeditor/cppprojectfile.cpp index c960150a259..580ad1762da 100644 --- a/src/plugins/cppeditor/cppprojectfile.cpp +++ b/src/plugins/cppeditor/cppprojectfile.cpp @@ -3,11 +3,9 @@ #include "cppprojectfile.h" -#include "cppeditorconstants.h" - -#include #include #include +#include #include @@ -29,25 +27,26 @@ bool ProjectFile::operator==(const ProjectFile &other) const ProjectFile::Kind ProjectFile::classifyByMimeType(const QString &mt) { - if (mt == CppEditor::Constants::C_SOURCE_MIMETYPE) + using namespace Utils::Constants; + if (mt == C_SOURCE_MIMETYPE) return CSource; - if (mt == CppEditor::Constants::C_HEADER_MIMETYPE) + if (mt == C_HEADER_MIMETYPE) return CHeader; - if (mt == CppEditor::Constants::CPP_SOURCE_MIMETYPE) + if (mt == CPP_SOURCE_MIMETYPE) return CXXSource; - if (mt == CppEditor::Constants::CPP_HEADER_MIMETYPE) + if (mt == CPP_HEADER_MIMETYPE) return CXXHeader; - if (mt == CppEditor::Constants::OBJECTIVE_C_SOURCE_MIMETYPE) + if (mt == OBJECTIVE_C_SOURCE_MIMETYPE) return ObjCSource; - if (mt == CppEditor::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE) + if (mt == OBJECTIVE_CPP_SOURCE_MIMETYPE) return ObjCXXSource; - if (mt == CppEditor::Constants::QDOC_MIMETYPE) + if (mt == QDOC_MIMETYPE) return CXXSource; - if (mt == CppEditor::Constants::MOC_MIMETYPE) + if (mt == MOC_MIMETYPE) return CXXSource; - if (mt == CppEditor::Constants::CUDA_SOURCE_MIMETYPE) + if (mt == CUDA_SOURCE_MIMETYPE) return CudaSource; - if (mt == CppEditor::Constants::AMBIGUOUS_HEADER_MIMETYPE) + if (mt == AMBIGUOUS_HEADER_MIMETYPE) return AmbiguousHeader; return Unsupported; } diff --git a/src/plugins/cppeditor/cpptoolssettings.cpp b/src/plugins/cppeditor/cpptoolssettings.cpp index ad3dfd18388..fa4df4b9b65 100644 --- a/src/plugins/cppeditor/cpptoolssettings.cpp +++ b/src/plugins/cppeditor/cpptoolssettings.cpp @@ -17,6 +17,7 @@ #include #include +#include #include static const char idKey[] = "CppGlobal"; @@ -131,10 +132,11 @@ CppToolsSettings::CppToolsSettings() d->m_globalCodeStyle->fromSettings(Constants::CPP_SETTINGS_ID); // mimetypes to be handled - TextEditorSettings::registerMimeTypeForLanguageId(Constants::C_SOURCE_MIMETYPE, Constants::CPP_SETTINGS_ID); - TextEditorSettings::registerMimeTypeForLanguageId(Constants::C_HEADER_MIMETYPE, Constants::CPP_SETTINGS_ID); - TextEditorSettings::registerMimeTypeForLanguageId(Constants::CPP_SOURCE_MIMETYPE, Constants::CPP_SETTINGS_ID); - TextEditorSettings::registerMimeTypeForLanguageId(Constants::CPP_HEADER_MIMETYPE, Constants::CPP_SETTINGS_ID); + using namespace Utils::Constants; + TextEditorSettings::registerMimeTypeForLanguageId(C_SOURCE_MIMETYPE, Constants::CPP_SETTINGS_ID); + TextEditorSettings::registerMimeTypeForLanguageId(C_HEADER_MIMETYPE, Constants::CPP_SETTINGS_ID); + TextEditorSettings::registerMimeTypeForLanguageId(CPP_SOURCE_MIMETYPE, Constants::CPP_SETTINGS_ID); + TextEditorSettings::registerMimeTypeForLanguageId(CPP_HEADER_MIMETYPE, Constants::CPP_SETTINGS_ID); } CppToolsSettings::~CppToolsSettings() diff --git a/src/plugins/designer/cpp/formclasswizard.cpp b/src/plugins/designer/cpp/formclasswizard.cpp index 1582cd26de5..0290259527c 100644 --- a/src/plugins/designer/cpp/formclasswizard.cpp +++ b/src/plugins/designer/cpp/formclasswizard.cpp @@ -3,13 +3,18 @@ #include "formclasswizard.h" #include "formclasswizarddialog.h" + #include #include -#include + #include + #include + #include +#include + #include using namespace Utils; @@ -34,7 +39,7 @@ QString FormClassWizard::sourceSuffix() const QString FormClassWizard::formSuffix() const { - return preferredSuffix(Constants::FORM_MIMETYPE); + return preferredSuffix(Utils::Constants::FORM_MIMETYPE); } Core::BaseFileWizard *FormClassWizard::create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const diff --git a/src/plugins/designer/designerconstants.h b/src/plugins/designer/designerconstants.h index 0f05b67124b..8869c927906 100644 --- a/src/plugins/designer/designerconstants.h +++ b/src/plugins/designer/designerconstants.h @@ -23,7 +23,6 @@ const char M_FORMEDITOR_PREVIEW[] = "FormEditor.Menu.Preview"; // Wizard type const char FORM_FILE_TYPE[] = "Qt4FormFiles"; -const char FORM_MIMETYPE[] = "application/x-designer"; enum DesignerSubWindows { diff --git a/src/plugins/designer/formeditor.cpp b/src/plugins/designer/formeditor.cpp index 798eac018a8..cbd405c3d57 100644 --- a/src/plugins/designer/formeditor.cpp +++ b/src/plugins/designer/formeditor.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -423,7 +424,7 @@ void FormEditorData::fullInit() designerContexts.add(Core::Constants::C_EDITORMANAGER); ICore::addContextObject(new DesignerContext(designerContexts, m_modeWidget, this)); - DesignMode::registerDesignWidget(m_modeWidget, QStringList(FORM_MIMETYPE), m_contexts); + DesignMode::registerDesignWidget(m_modeWidget, QStringList(Utils::Constants::FORM_MIMETYPE), m_contexts); setupViewActions(); diff --git a/src/plugins/designer/formeditorfactory.cpp b/src/plugins/designer/formeditorfactory.cpp index 278cb065f40..de3308f716a 100644 --- a/src/plugins/designer/formeditorfactory.cpp +++ b/src/plugins/designer/formeditorfactory.cpp @@ -8,8 +8,11 @@ #include "formeditor.h" #include + #include + #include +#include using namespace Core; using namespace Designer::Constants; @@ -22,7 +25,7 @@ FormEditorFactory::FormEditorFactory() { setId(K_DESIGNER_XML_EDITOR_ID); setDisplayName(Tr::tr(C_DESIGNER_XML_DISPLAY_NAME)); - addMimeType(FORM_MIMETYPE); + addMimeType(Utils::Constants::FORM_MIMETYPE); setEditorCreator([] { return Designer::Internal::createEditor(); }); FileIconProvider::registerIconOverlayForSuffix(ProjectExplorer::Constants::FILEOVERLAY_UI, "ui"); diff --git a/src/plugins/designer/formeditorplugin.cpp b/src/plugins/designer/formeditorplugin.cpp index e997b26b939..0f9c77b0b44 100644 --- a/src/plugins/designer/formeditorplugin.cpp +++ b/src/plugins/designer/formeditorplugin.cpp @@ -25,8 +25,12 @@ #include #include #include + #include + #include + +#include #include #include @@ -161,11 +165,12 @@ static FilePath otherFile() const Utils::MimeType currentMimeType = Utils::mimeTypeForFile(current); // Determine potential suffixes of candidate files // 'ui' -> 'cpp', 'cpp/h' -> 'ui'. + using namespace Utils::Constants; QStringList candidateSuffixes; if (currentMimeType.matchesName(FORM_MIMETYPE)) { - candidateSuffixes += Utils::mimeTypeForName(CppEditor::Constants::CPP_SOURCE_MIMETYPE).suffixes(); - } else if (currentMimeType.matchesName(CppEditor::Constants::CPP_SOURCE_MIMETYPE) - || currentMimeType.matchesName(CppEditor::Constants::CPP_HEADER_MIMETYPE)) { + candidateSuffixes += Utils::mimeTypeForName(CPP_SOURCE_MIMETYPE).suffixes(); + } else if (currentMimeType.matchesName(CPP_SOURCE_MIMETYPE) + || currentMimeType.matchesName(CPP_HEADER_MIMETYPE)) { candidateSuffixes += Utils::mimeTypeForName(FORM_MIMETYPE).suffixes(); } else { return {}; diff --git a/src/plugins/designer/formwindowfile.cpp b/src/plugins/designer/formwindowfile.cpp index 6923981e923..c4b59131e53 100644 --- a/src/plugins/designer/formwindowfile.cpp +++ b/src/plugins/designer/formwindowfile.cpp @@ -5,7 +5,8 @@ #include "designerconstants.h" #include "resourcehandler.h" -#include +#include +#include #include #include @@ -27,7 +28,7 @@ namespace Internal { FormWindowFile::FormWindowFile(QDesignerFormWindowInterface *form, QObject *parent) : m_formWindow(form) { - setMimeType(Designer::Constants::FORM_MIMETYPE); + setMimeType(Utils::Constants::FORM_MIMETYPE); setParent(parent); setId(Utils::Id(Designer::Constants::K_DESIGNER_XML_EDITOR_ID)); // Designer needs UTF-8 regardless of settings. diff --git a/src/plugins/glsleditor/glsleditor.cpp b/src/plugins/glsleditor/glsleditor.cpp index 893aaf47d36..7d29f50b124 100644 --- a/src/plugins/glsleditor/glsleditor.cpp +++ b/src/plugins/glsleditor/glsleditor.cpp @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -365,11 +366,11 @@ GlslEditorFactory::GlslEditorFactory() { setId(Constants::C_GLSLEDITOR_ID); setDisplayName(::Core::Tr::tr(Constants::C_GLSLEDITOR_DISPLAY_NAME)); - addMimeType(Constants::GLSL_MIMETYPE); - addMimeType(Constants::GLSL_MIMETYPE_VERT); - addMimeType(Constants::GLSL_MIMETYPE_FRAG); - addMimeType(Constants::GLSL_MIMETYPE_VERT_ES); - addMimeType(Constants::GLSL_MIMETYPE_FRAG_ES); + addMimeType(Utils::Constants::GLSL_MIMETYPE); + addMimeType(Utils::Constants::GLSL_MIMETYPE_VERT); + addMimeType(Utils::Constants::GLSL_MIMETYPE_FRAG); + addMimeType(Utils::Constants::GLSL_MIMETYPE_VERT_ES); + addMimeType(Utils::Constants::GLSL_MIMETYPE_FRAG_ES); setDocumentCreator([]() { return new TextDocument(Constants::C_GLSLEDITOR_ID); }); setEditorWidgetCreator([]() { return new GlslEditorWidget; }); diff --git a/src/plugins/glsleditor/glsleditorconstants.h b/src/plugins/glsleditor/glsleditorconstants.h index 925105cfe8f..585b357e7c9 100644 --- a/src/plugins/glsleditor/glsleditorconstants.h +++ b/src/plugins/glsleditor/glsleditorconstants.h @@ -16,11 +16,5 @@ const char M_REFACTORING_MENU_INSERTION_POINT[] = "GLSLEditor.RefactorGroup"; const char C_GLSLEDITOR_ID[] = "GLSLEditor.GLSLEditor"; const char C_GLSLEDITOR_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("QtC::Core", "GLSL Editor"); -const char GLSL_MIMETYPE[] = "application/x-glsl"; -const char GLSL_MIMETYPE_VERT[] = "text/x-glsl-vert"; -const char GLSL_MIMETYPE_FRAG[] = "text/x-glsl-frag"; -const char GLSL_MIMETYPE_VERT_ES[] = "text/x-glsl-es-vert"; -const char GLSL_MIMETYPE_FRAG_ES[] = "text/x-glsl-es-frag"; - } // namespace Constants } // namespace GlslEditor diff --git a/src/plugins/glsleditor/glsleditorplugin.cpp b/src/plugins/glsleditor/glsleditorplugin.cpp index 5d238a4f2b4..537ec7a30a0 100644 --- a/src/plugins/glsleditor/glsleditorplugin.cpp +++ b/src/plugins/glsleditor/glsleditorplugin.cpp @@ -21,6 +21,7 @@ #include #include +#include #include @@ -117,11 +118,12 @@ void GlslEditorPlugin::initialize() void GlslEditorPlugin::extensionsInitialized() { - FileIconProvider::registerIconOverlayForMimeType(":/glsleditor/images/glslfile.png", Constants::GLSL_MIMETYPE); - FileIconProvider::registerIconOverlayForMimeType(":/glsleditor/images/glslfile.png", Constants::GLSL_MIMETYPE_VERT); - FileIconProvider::registerIconOverlayForMimeType(":/glsleditor/images/glslfile.png", Constants::GLSL_MIMETYPE_FRAG); - FileIconProvider::registerIconOverlayForMimeType(":/glsleditor/images/glslfile.png", Constants::GLSL_MIMETYPE_VERT_ES); - FileIconProvider::registerIconOverlayForMimeType(":/glsleditor/images/glslfile.png", Constants::GLSL_MIMETYPE_FRAG_ES); + using namespace Utils::Constants; + FileIconProvider::registerIconOverlayForMimeType(":/glsleditor/images/glslfile.png", GLSL_MIMETYPE); + FileIconProvider::registerIconOverlayForMimeType(":/glsleditor/images/glslfile.png", GLSL_MIMETYPE_VERT); + FileIconProvider::registerIconOverlayForMimeType(":/glsleditor/images/glslfile.png", GLSL_MIMETYPE_FRAG); + FileIconProvider::registerIconOverlayForMimeType(":/glsleditor/images/glslfile.png", GLSL_MIMETYPE_VERT_ES); + FileIconProvider::registerIconOverlayForMimeType(":/glsleditor/images/glslfile.png", GLSL_MIMETYPE_FRAG_ES); } const GlslEditorPlugin::InitFile *GlslEditorPlugin::fragmentShaderInit(int variant) diff --git a/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp b/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp index 516bab9f574..43aa3ba8b5d 100644 --- a/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp +++ b/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp @@ -7,10 +7,10 @@ #include "../projectexplorertr.h" #include -#include #include #include +#include #include #include #include @@ -885,10 +885,10 @@ void CustomWizardContext::reset() const QTime currentTime = QTime::currentTime(); baseReplacements.clear(); baseReplacements.insert(QLatin1String("CppSourceSuffix"), - Utils::mimeTypeForName(QLatin1String(CppEditor::Constants::CPP_SOURCE_MIMETYPE)) + Utils::mimeTypeForName(QLatin1String(Utils::Constants::CPP_SOURCE_MIMETYPE)) .preferredSuffix()); baseReplacements.insert(QLatin1String("CppHeaderSuffix"), - Utils::mimeTypeForName(QLatin1String(CppEditor::Constants::CPP_HEADER_MIMETYPE)) + Utils::mimeTypeForName(QLatin1String(Utils::Constants::CPP_HEADER_MIMETYPE)) .preferredSuffix()); baseReplacements.insert(QLatin1String("CurrentDate"), currentDate.toString(Qt::ISODate)); diff --git a/src/plugins/projectexplorer/projectexplorerconstants.h b/src/plugins/projectexplorer/projectexplorerconstants.h index 6677081f4ca..dbf650b7c49 100644 --- a/src/plugins/projectexplorer/projectexplorerconstants.h +++ b/src/plugins/projectexplorer/projectexplorerconstants.h @@ -73,18 +73,6 @@ const char G_FILE_OPEN[] = "ProjectFile.Group.Open"; const char G_FILE_OTHER[] = "ProjectFile.Group.Other"; const char G_FILE_CONFIG[] = "ProjectFile.Group.Config"; -// Mime types -const char C_SOURCE_MIMETYPE[] = "text/x-csrc"; -const char C_HEADER_MIMETYPE[] = "text/x-chdr"; -const char CPP_SOURCE_MIMETYPE[] = "text/x-c++src"; -const char CPP_HEADER_MIMETYPE[] = "text/x-c++hdr"; -const char LINGUIST_MIMETYPE[] = "text/vnd.trolltech.linguist"; -const char FORM_MIMETYPE[] = "application/x-designer"; -const char QML_MIMETYPE[] = "text/x-qml"; // separate def also in qmljstoolsconstants.h -const char QMLUI_MIMETYPE[] = "application/x-qt.ui+qml"; -const char RESOURCE_MIMETYPE[] = "application/vnd.qt.xml.resource"; -const char SCXML_MIMETYPE[] = "application/scxml+xml"; - // Kits settings category const char KITS_SETTINGS_CATEGORY[] = "A.Kits"; diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index 11ab5fe0561..0ef47153fb9 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -291,22 +292,21 @@ void Node::setParentFolderNode(FolderNode *parentFolder) m_parentFolderNode = parentFolder; } -FileType Node::fileTypeForMimeType(const Utils::MimeType &mt) +FileType Node::fileTypeForMimeType(const MimeType &mt) { + using namespace Utils::Constants; FileType type = FileType::Source; if (mt.isValid()) { const QString mtName = mt.name(); - if (mtName == Constants::C_HEADER_MIMETYPE - || mtName == Constants::CPP_HEADER_MIMETYPE) + if (mtName == C_HEADER_MIMETYPE || mtName == CPP_HEADER_MIMETYPE) type = FileType::Header; - else if (mtName == Constants::FORM_MIMETYPE) + else if (mtName == FORM_MIMETYPE) type = FileType::Form; - else if (mtName == Constants::RESOURCE_MIMETYPE) + else if (mtName == RESOURCE_MIMETYPE) type = FileType::Resource; - else if (mtName == Constants::SCXML_MIMETYPE) + else if (mtName == SCXML_MIMETYPE) type = FileType::StateChart; - else if (mtName == Constants::QML_MIMETYPE - || mtName == Constants::QMLUI_MIMETYPE) + else if (mtName == QML_MIMETYPE || mtName == QMLUI_MIMETYPE) type = FileType::QML; } else { type = FileType::Unknown; diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 043d88199eb..a10a2e739d8 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -24,8 +24,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -44,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -672,20 +672,21 @@ void QbsBuildSystem::updateDocuments() static QString getMimeType(const QJsonObject &sourceArtifact) { + using namespace Utils::Constants; const auto tags = sourceArtifact.value("file-tags").toArray(); if (tags.contains("hpp")) { if (CppEditor::ProjectFile::isAmbiguousHeader(sourceArtifact.value("file-path").toString())) - return QString(CppEditor::Constants::AMBIGUOUS_HEADER_MIMETYPE); - return QString(CppEditor::Constants::CPP_HEADER_MIMETYPE); + return QString(AMBIGUOUS_HEADER_MIMETYPE); + return QString(CPP_HEADER_MIMETYPE); } if (tags.contains("cpp")) - return QString(CppEditor::Constants::CPP_SOURCE_MIMETYPE); + return QString(CPP_SOURCE_MIMETYPE); if (tags.contains("c")) - return QString(CppEditor::Constants::C_SOURCE_MIMETYPE); + return QString(C_SOURCE_MIMETYPE); if (tags.contains("objc")) - return QString(CppEditor::Constants::OBJECTIVE_C_SOURCE_MIMETYPE); + return QString(OBJECTIVE_C_SOURCE_MIMETYPE); if (tags.contains("objcpp")) - return QString(CppEditor::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE); + return QString(OBJECTIVE_CPP_SOURCE_MIMETYPE); return {}; } diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp index fc0eb4abebb..546634d7926 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp +++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp @@ -8,7 +8,6 @@ #include "qbscleanstep.h" #include "qbsinstallstep.h" #include "qbsnodes.h" -#include "qbsprofilemanager.h" #include "qbsprofilessettingspage.h" #include "qbsproject.h" #include "qbsprojectmanagerconstants.h" @@ -36,11 +35,8 @@ #include #include -#include -#include - -#include #include +#include #include #include @@ -88,7 +84,7 @@ void QbsProjectManagerPlugin::initialize() Utils::FileIconProvider::registerIconOverlayForSuffix(ProjectExplorer::Constants::FILEOVERLAY_QT, "qbs"); Core::HelpManager::registerDocumentation({Core::HelpManager::documentationPath() + "/qbs.qch"}); - ProjectManager::registerProjectType(QmlJSTools::Constants::QBS_MIMETYPE); + ProjectManager::registerProjectType(Utils::Constants::QBS_MIMETYPE); //menus // Build Menu: diff --git a/src/plugins/qmakeprojectmanager/profileeditor.cpp b/src/plugins/qmakeprojectmanager/profileeditor.cpp index 1a3e15fdd59..c510e139012 100644 --- a/src/plugins/qmakeprojectmanager/profileeditor.cpp +++ b/src/plugins/qmakeprojectmanager/profileeditor.cpp @@ -18,12 +18,11 @@ #include #include -#include - #include #include #include +#include #include #include @@ -243,7 +242,7 @@ static TextDocument *createProFileDocument() { auto doc = new TextDocument; doc->setId(Constants::PROFILE_EDITOR_ID); - doc->setMimeType(QLatin1String(Constants::PROFILE_MIMETYPE)); + doc->setMimeType(Utils::Constants::PROFILE_MIMETYPE); // qmake project files do not support UTF8-BOM // If the BOM would be added qmake would fail and Qt Creator couldn't parse the project file doc->setSupportsUtf8Bom(false); @@ -256,14 +255,15 @@ static TextDocument *createProFileDocument() ProFileEditorFactory::ProFileEditorFactory() { + using namespace Utils::Constants; setId(Constants::PROFILE_EDITOR_ID); setDisplayName(::Core::Tr::tr(Constants::PROFILE_EDITOR_DISPLAY_NAME)); - addMimeType(Constants::PROFILE_MIMETYPE); - addMimeType(Constants::PROINCLUDEFILE_MIMETYPE); - addMimeType(Constants::PROFEATUREFILE_MIMETYPE); - addMimeType(Constants::PROCONFIGURATIONFILE_MIMETYPE); - addMimeType(Constants::PROCACHEFILE_MIMETYPE); - addMimeType(Constants::PROSTASHFILE_MIMETYPE); + addMimeType(PROFILE_MIMETYPE); + addMimeType(PROINCLUDEFILE_MIMETYPE); + addMimeType(PROFEATUREFILE_MIMETYPE); + addMimeType(PROCONFIGURATIONFILE_MIMETYPE); + addMimeType(PROCACHEFILE_MIMETYPE); + addMimeType(PROSTASHFILE_MIMETYPE); setDocumentCreator(createProFileDocument); setEditorWidgetCreator([]() { return new ProFileEditorWidget; }); diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp index 8806e2a79b3..53f08114fa8 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -718,7 +719,7 @@ QmakeBuildConfigurationFactory::QmakeBuildConfigurationFactory() { registerBuildConfiguration(Constants::QMAKE_BC_ID); setSupportedProjectType(Constants::QMAKEPROJECT_ID); - setSupportedProjectMimeTypeName(Constants::PROFILE_MIMETYPE); + setSupportedProjectMimeTypeName(Utils::Constants::PROFILE_MIMETYPE); setIssueReporter([](Kit *k, const FilePath &projectPath, const FilePath &buildDir) { QtSupport::QtVersion *version = QtSupport::QtKitAspect::qtVersion(k); Tasks issues; diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp index 8a18d238017..ac8af4d3cee 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -31,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -501,7 +501,7 @@ bool QmakePriFile::addSubProject(const FilePath &proFile) uniqueProFilePaths.append(simplifyProFilePath(proFile)); FilePaths failedFiles; - changeFiles(QLatin1String(Constants::PROFILE_MIMETYPE), uniqueProFilePaths, &failedFiles, AddToProFile); + changeFiles(Utils::Constants::PROFILE_MIMETYPE, uniqueProFilePaths, &failedFiles, AddToProFile); return failedFiles.isEmpty(); } @@ -509,12 +509,12 @@ bool QmakePriFile::addSubProject(const FilePath &proFile) bool QmakePriFile::removeSubProjects(const FilePath &proFilePath) { FilePaths failedOriginalFiles; - changeFiles(QLatin1String(Constants::PROFILE_MIMETYPE), {proFilePath}, &failedOriginalFiles, RemoveFromProFile); + changeFiles(Utils::Constants::PROFILE_MIMETYPE, {proFilePath}, &failedOriginalFiles, RemoveFromProFile); FilePaths simplifiedProFiles = Utils::transform(failedOriginalFiles, &simplifyProFilePath); FilePaths failedSimplifiedFiles; - changeFiles(QLatin1String(Constants::PROFILE_MIMETYPE), simplifiedProFiles, &failedSimplifiedFiles, RemoveFromProFile); + changeFiles(Utils::Constants::PROFILE_MIMETYPE, simplifiedProFiles, &failedSimplifiedFiles, RemoveFromProFile); return failedSimplifiedFiles.isEmpty(); } @@ -538,7 +538,7 @@ bool QmakePriFile::addFiles(const FilePaths &filePaths, FilePaths *notAdded) for (auto it = typeFileMap.constBegin(); it != typeFileMap.constEnd(); ++it) { const FilePaths &typeFiles = *it; FilePaths qrcFiles; // the list of qrc files referenced from ui files - if (it.key() == QLatin1String(ProjectExplorer::Constants::RESOURCE_MIMETYPE)) { + if (it.key() == QLatin1String(Utils::Constants::RESOURCE_MIMETYPE)) { for (const FilePath &formFile : typeFiles) { const FilePaths resourceFiles = formResources(formFile); for (const FilePath &resourceFile : resourceFiles) @@ -563,7 +563,7 @@ bool QmakePriFile::addFiles(const FilePaths &filePaths, FilePaths *notAdded) changeFiles(it.key(), uniqueFilePaths, &failedFiles, AddToProFile); if (notAdded) *notAdded += failedFiles; - changeFiles(QLatin1String(ProjectExplorer::Constants::RESOURCE_MIMETYPE), uniqueQrcFiles, &failedFiles, AddToProFile); + changeFiles(QLatin1String(Utils::Constants::RESOURCE_MIMETYPE), uniqueQrcFiles, &failedFiles, AddToProFile); if (notAdded) *notAdded += failedFiles; } @@ -998,32 +998,34 @@ QStringList QmakePriFile::varNames(FileType type, QtSupport::ProFileReader *read //! QString QmakePriFile::varNameForAdding(const QString &mimeType) { - if (mimeType == QLatin1String(ProjectExplorer::Constants::CPP_HEADER_MIMETYPE) - || mimeType == QLatin1String(ProjectExplorer::Constants::C_HEADER_MIMETYPE)) { + using namespace Utils::Constants; + + if (mimeType == QLatin1String(CPP_HEADER_MIMETYPE) + || mimeType == QLatin1String(C_HEADER_MIMETYPE)) { return QLatin1String("HEADERS"); } - if (mimeType == QLatin1String(ProjectExplorer::Constants::CPP_SOURCE_MIMETYPE) - || mimeType == QLatin1String(CppEditor::Constants::OBJECTIVE_CPP_SOURCE_MIMETYPE) - || mimeType == QLatin1String(ProjectExplorer::Constants::C_SOURCE_MIMETYPE)) { + if (mimeType == QLatin1String(CPP_SOURCE_MIMETYPE) + || mimeType == QLatin1String(OBJECTIVE_CPP_SOURCE_MIMETYPE) + || mimeType == QLatin1String(C_SOURCE_MIMETYPE)) { return QLatin1String("SOURCES"); } - if (mimeType == QLatin1String(ProjectExplorer::Constants::RESOURCE_MIMETYPE)) + if (mimeType == QLatin1String(RESOURCE_MIMETYPE)) return QLatin1String("RESOURCES"); - if (mimeType == QLatin1String(ProjectExplorer::Constants::FORM_MIMETYPE)) + if (mimeType == QLatin1String(FORM_MIMETYPE)) return QLatin1String("FORMS"); - if (mimeType == QLatin1String(ProjectExplorer::Constants::QML_MIMETYPE) - || mimeType == QLatin1String(ProjectExplorer::Constants::QMLUI_MIMETYPE)) { + if (mimeType == QLatin1String(QML_MIMETYPE) + || mimeType == QLatin1String(QMLUI_MIMETYPE)) { return QLatin1String("DISTFILES"); } - if (mimeType == QLatin1String(ProjectExplorer::Constants::SCXML_MIMETYPE)) + if (mimeType == QLatin1String(SCXML_MIMETYPE)) return QLatin1String("STATECHARTS"); - if (mimeType == QLatin1String(Constants::PROFILE_MIMETYPE)) + if (mimeType == QLatin1String(PROFILE_MIMETYPE)) return QLatin1String("SUBDIRS"); return QLatin1String("DISTFILES"); diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index b2bca450e7f..c9d58b7dcde 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -50,6 +50,7 @@ #include #include +#include #include #include @@ -89,7 +90,7 @@ public: IDocument(nullptr), m_priFile(qmakePriFile) { setId("Qmake.PriFile"); - setMimeType(QLatin1String(QmakeProjectManager::Constants::PROFILE_MIMETYPE)); + setMimeType(Utils::Constants::PROFILE_MIMETYPE); setFilePath(filePath); Core::DocumentManager::addDocument(this); } @@ -153,7 +154,7 @@ private: */ QmakeProject::QmakeProject(const FilePath &fileName) : - Project(QmakeProjectManager::Constants::PROFILE_MIMETYPE, fileName) + Project(Utils::Constants::PROFILE_MIMETYPE, fileName) { setId(Constants::QMAKEPROJECT_ID); setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerconstants.h b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerconstants.h index b97e1e63201..0ff6a42d2c4 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerconstants.h +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerconstants.h @@ -14,12 +14,6 @@ const char M_CONTEXT[] = "ProFileEditor.ContextMenu"; // Kinds const char PROFILE_EDITOR_ID[] = "Qt4.proFileEditor"; const char PROFILE_EDITOR_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("QtC::Core", ".pro File Editor"); -const char PROFILE_MIMETYPE[] = "application/vnd.qt.qmakeprofile"; -const char PROINCLUDEFILE_MIMETYPE [] = "application/vnd.qt.qmakeproincludefile"; -const char PROFEATUREFILE_MIMETYPE [] = "application/vnd.qt.qmakeprofeaturefile"; -const char PROCONFIGURATIONFILE_MIMETYPE [] = "application/vnd.qt.qmakeproconfigurationfile"; -const char PROCACHEFILE_MIMETYPE [] = "application/vnd.qt.qmakeprocachefile"; -const char PROSTASHFILE_MIMETYPE [] = "application/vnd.qt.qmakeprostashfile"; // Actions const char RUNQMAKE[] = "Qt4Builder.RunQMake"; diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp index 7e06ff6bbab..e40147ea68f 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectmanagerplugin.cpp @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -124,7 +125,7 @@ void QmakeProjectManagerPlugin::initialize() d = new QmakeProjectManagerPluginPrivate; //create and register objects - ProjectManager::registerProjectType(QmakeProjectManager::Constants::PROFILE_MIMETYPE); + ProjectManager::registerProjectType(Utils::Constants::PROFILE_MIMETYPE); IWizardFactory::registerFactoryCreator([] { return new SubdirsProjectWizard; }); IWizardFactory::registerFactoryCreator([] { return new CustomWidgetWizard; }); diff --git a/src/plugins/qmakeprojectmanager/wizards/qtwizard.cpp b/src/plugins/qmakeprojectmanager/wizards/qtwizard.cpp index f7735415c47..c76e0be174c 100644 --- a/src/plugins/qmakeprojectmanager/wizards/qtwizard.cpp +++ b/src/plugins/qmakeprojectmanager/wizards/qtwizard.cpp @@ -23,9 +23,7 @@ #include #include - -#include -#include +#include using namespace ProjectExplorer; using namespace QtSupport; @@ -52,12 +50,12 @@ QString QtWizard::headerSuffix() QString QtWizard::formSuffix() { - return preferredSuffix(QLatin1String(ProjectExplorer::Constants::FORM_MIMETYPE)); + return preferredSuffix(QLatin1String(Utils::Constants::FORM_MIMETYPE)); } QString QtWizard::profileSuffix() { - return preferredSuffix(QLatin1String(Constants::PROFILE_MIMETYPE)); + return preferredSuffix(QLatin1String(Utils::Constants::PROFILE_MIMETYPE)); } bool QtWizard::postGenerateFiles(const QWizard *w, const Core::GeneratedFiles &l, QString *errorMessage) const diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp index 109bcd0854e..f0c10d7420a 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp @@ -3,10 +3,14 @@ #include "bindingeditorwidget.h" +#include + #include #include #include -#include + +#include + #include #include #include @@ -14,11 +18,11 @@ #include #include #include -#include -#include -#include +#include + #include +#include #include #include @@ -145,9 +149,9 @@ BindingEditorFactory::BindingEditorFactory() setDisplayName(::Core::Tr::tr("Binding Editor")); setEditorActionHandlers(0); addMimeType(BINDINGEDITOR_CONTEXT_ID); - addMimeType(QmlJSTools::Constants::QML_MIMETYPE); - addMimeType(QmlJSTools::Constants::QMLTYPES_MIMETYPE); - addMimeType(QmlJSTools::Constants::JS_MIMETYPE); + addMimeType(Utils::Constants::QML_MIMETYPE); + addMimeType(Utils::Constants::QMLTYPES_MIMETYPE); + addMimeType(Utils::Constants::JS_MIMETYPE); setDocumentCreator([]() { return new BindingDocument; }); setEditorWidgetCreator([]() { return new BindingEditorWidget; }); diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 8536b332401..c7ed127b6ef 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -63,6 +63,7 @@ #include #include +#include #include #include @@ -119,7 +120,7 @@ QtQuickDesignerFactory::QtQuickDesignerFactory() { setDisplayName(::Core::Tr::tr("Qt Quick Designer")); - addMimeType(QmlJSTools::Constants::QMLUI_MIMETYPE); + addMimeType(Utils::Constants::QMLUI_MIMETYPE); setDocumentCreator([this]() { auto document = new QmlJSEditor::QmlJSEditorDocument(id()); document->setIsDesignModePreferred( @@ -382,8 +383,8 @@ void QmlDesignerPlugin::integrateIntoQtCreator(QWidget *modeWidget) d->shortCutManager.registerActions(qmlDesignerMainContext, qmlDesignerFormEditorContext, qmlDesignerEditor3dContext, qmlDesignerNavigatorContext); - const QStringList mimeTypes = { QmlJSTools::Constants::QML_MIMETYPE, - QmlJSTools::Constants::QMLUI_MIMETYPE }; + const QStringList mimeTypes = { Utils::Constants::QML_MIMETYPE, + Utils::Constants::QMLUI_MIMETYPE }; Core::DesignMode::registerDesignWidget(modeWidget, mimeTypes, context->context()); diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index 69948be3835..d6b132b9700 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -55,8 +55,9 @@ #include #include -#include #include +#include +#include #include #include @@ -66,7 +67,6 @@ #include #include -#include #include #include #include @@ -160,10 +160,8 @@ void QmlJSEditorWidget::finalizeInitialization() void QmlJSEditorWidget::restoreState(const QByteArray &state) { - QStringList qmlTypes { QmlJSTools::Constants::QML_MIMETYPE, - QmlJSTools::Constants::QBS_MIMETYPE, - QmlJSTools::Constants::QMLTYPES_MIMETYPE, - QmlJSTools::Constants::QMLUI_MIMETYPE }; + using namespace Utils::Constants; + QStringList qmlTypes = {QML_MIMETYPE, QBS_MIMETYPE, QMLTYPES_MIMETYPE, QMLUI_MIMETYPE}; if (QmlJsEditingSettings::get().foldAuxData() && qmlTypes.contains(textDocument()->mimeType())) { int version = 0; @@ -1133,11 +1131,12 @@ QmlJSEditorFactory::QmlJSEditorFactory(Utils::Id _id) setId(_id); setDisplayName(::Core::Tr::tr("QMLJS Editor")); - addMimeType(QmlJSTools::Constants::QML_MIMETYPE); - addMimeType(QmlJSTools::Constants::QMLPROJECT_MIMETYPE); - addMimeType(QmlJSTools::Constants::QBS_MIMETYPE); - addMimeType(QmlJSTools::Constants::QMLTYPES_MIMETYPE); - addMimeType(QmlJSTools::Constants::JS_MIMETYPE); + using namespace Utils::Constants; + addMimeType(QML_MIMETYPE); + addMimeType(QMLPROJECT_MIMETYPE); + addMimeType(QBS_MIMETYPE); + addMimeType(QMLTYPES_MIMETYPE); + addMimeType(JS_MIMETYPE); setDocumentCreator([this]() { return new QmlJSEditorDocument(id()); }); setEditorWidgetCreator([]() { return new QmlJSEditorWidget; }); diff --git a/src/plugins/qmljseditor/qmllsclient.cpp b/src/plugins/qmljseditor/qmllsclient.cpp index 4cc8769bb1b..6ec46774f30 100644 --- a/src/plugins/qmljseditor/qmllsclient.cpp +++ b/src/plugins/qmljseditor/qmllsclient.cpp @@ -12,7 +12,8 @@ #include #include -#include + +#include #include @@ -53,10 +54,9 @@ QmllsClient *QmllsClient::clientForQmlls(const FilePath &qmlls) client->setName(Tr::tr("Qmlls (%1)").arg(qmlls.toUserOutput())); client->setActivateDocumentAutomatically(true); LanguageFilter filter; - using namespace QmlJSTools::Constants; - filter.mimeTypes = QStringList() - << QML_MIMETYPE << QMLUI_MIMETYPE << QBS_MIMETYPE << QMLPROJECT_MIMETYPE - << QMLTYPES_MIMETYPE << JS_MIMETYPE << JSON_MIMETYPE; + using namespace Utils::Constants; + filter.mimeTypes = {QML_MIMETYPE, QMLUI_MIMETYPE, QBS_MIMETYPE, QMLPROJECT_MIMETYPE, + QMLTYPES_MIMETYPE, JS_MIMETYPE, JSON_MIMETYPE}; client->setSupportedLanguage(filter); client->start(); qmllsClients()[qmlls] = client; diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp index c472fdcf795..8612a047775 100644 --- a/src/plugins/qmljstools/qmljsmodelmanager.cpp +++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qmljsmodelmanager.h" -#include "qmljstoolsconstants.h" #include "qmljssemanticinfo.h" #include "qmljsbundleprovider.h" @@ -28,24 +27,22 @@ #include #include #include + #include #include + #include #include #include +#include #include -#include -#include -#include #include #include #include #include #include -#include -#include using namespace Utils; using namespace Core; @@ -117,10 +114,12 @@ ModelManagerInterface::ProjectInfo ModelManager::defaultProjectInfoForProject( projectInfo.qmlDumpEnvironment = Utils::Environment::systemEnvironment(); Target *activeTarget = nullptr; if (project) { - const QSet qmlTypeNames = { Constants::QML_MIMETYPE ,Constants::QBS_MIMETYPE, - Constants::QMLPROJECT_MIMETYPE, - Constants::QMLTYPES_MIMETYPE, - Constants::QMLUI_MIMETYPE }; + using namespace Utils::Constants; + const QSet qmlTypeNames = { QML_MIMETYPE , + QBS_MIMETYPE, + QMLPROJECT_MIMETYPE, + QMLTYPES_MIMETYPE, + QMLUI_MIMETYPE }; projectInfo.sourceFiles = project->files([&qmlTypeNames](const Node *n) { if (!Project::SourceFiles(n)) return false; @@ -224,27 +223,28 @@ QHash ModelManager::initLanguageForSuffix() const QHash res = ModelManagerInterface::languageForSuffix(); if (ICore::instance()) { - MimeType jsSourceTy = Utils::mimeTypeForName(Constants::JS_MIMETYPE); + using namespace Utils::Constants;; + MimeType jsSourceTy = Utils::mimeTypeForName(JS_MIMETYPE); const QStringList jsSuffixes = jsSourceTy.suffixes(); for (const QString &suffix : jsSuffixes) res[suffix] = Dialect::JavaScript; - MimeType qmlSourceTy = Utils::mimeTypeForName(Constants::QML_MIMETYPE); + MimeType qmlSourceTy = Utils::mimeTypeForName(QML_MIMETYPE); const QStringList qmlSuffixes = qmlSourceTy.suffixes(); for (const QString &suffix : qmlSuffixes) res[suffix] = Dialect::Qml; - MimeType qbsSourceTy = Utils::mimeTypeForName(Constants::QBS_MIMETYPE); + MimeType qbsSourceTy = Utils::mimeTypeForName(QBS_MIMETYPE); const QStringList qbsSuffixes = qbsSourceTy.suffixes(); for (const QString &suffix : qbsSuffixes) res[suffix] = Dialect::QmlQbs; - MimeType qmlProjectSourceTy = Utils::mimeTypeForName(Constants::QMLPROJECT_MIMETYPE); + MimeType qmlProjectSourceTy = Utils::mimeTypeForName(QMLPROJECT_MIMETYPE); const QStringList qmlProjSuffixes = qmlProjectSourceTy.suffixes(); for (const QString &suffix : qmlProjSuffixes) res[suffix] = Dialect::QmlProject; - MimeType qmlUiSourceTy = Utils::mimeTypeForName(Constants::QMLUI_MIMETYPE); + MimeType qmlUiSourceTy = Utils::mimeTypeForName(QMLUI_MIMETYPE); const QStringList qmlUiSuffixes = qmlUiSourceTy.suffixes(); for (const QString &suffix : qmlUiSuffixes) res[suffix] = Dialect::QmlQtQuick2Ui; - MimeType jsonSourceTy = Utils::mimeTypeForName(Constants::JSON_MIMETYPE); + MimeType jsonSourceTy = Utils::mimeTypeForName(JSON_MIMETYPE); const QStringList jsonSuffixes = jsonSourceTy.suffixes(); for (const QString &suffix : jsonSuffixes) res[suffix] = Dialect::Json; diff --git a/src/plugins/qmljstools/qmljstoolsconstants.h b/src/plugins/qmljstools/qmljstoolsconstants.h index f7555f54a75..13e5f845f75 100644 --- a/src/plugins/qmljstools/qmljstoolsconstants.h +++ b/src/plugins/qmljstools/qmljstoolsconstants.h @@ -8,14 +8,6 @@ namespace QmlJSTools { namespace Constants { -const char QML_MIMETYPE[] = "text/x-qml"; // separate def also in projectexplorerconstants.h -const char QBS_MIMETYPE[] = "application/x-qt.qbs+qml"; -const char QMLPROJECT_MIMETYPE[] = "application/x-qmlproject"; -const char QMLTYPES_MIMETYPE[] = "application/x-qt.meta-info+qml"; -const char QMLUI_MIMETYPE[] = "application/x-qt.ui+qml"; -const char JS_MIMETYPE[] = "application/javascript"; -const char JSON_MIMETYPE[] = "application/json"; - const char QML_JS_CODE_STYLE_SETTINGS_ID[] = "A.Code Style"; const char QML_JS_CODE_STYLE_SETTINGS_NAME[] = QT_TRANSLATE_NOOP("QtC::QmlJSTools", "Code Style"); diff --git a/src/plugins/qmljstools/qmljstoolssettings.cpp b/src/plugins/qmljstools/qmljstoolssettings.cpp index b5cdac7e200..6ba30acb424 100644 --- a/src/plugins/qmljstools/qmljstoolssettings.cpp +++ b/src/plugins/qmljstools/qmljstoolssettings.cpp @@ -13,6 +13,8 @@ #include #include +#include +#include #include using namespace TextEditor; @@ -69,13 +71,14 @@ QmlJSToolsSettings::QmlJSToolsSettings() m_globalCodeStyle->fromSettings(QmlJSTools::Constants::QML_JS_SETTINGS_ID); // mimetypes to be handled - TextEditorSettings::registerMimeTypeForLanguageId(Constants::QML_MIMETYPE, Constants::QML_JS_SETTINGS_ID); - TextEditorSettings::registerMimeTypeForLanguageId(Constants::QMLUI_MIMETYPE, Constants::QML_JS_SETTINGS_ID); - TextEditorSettings::registerMimeTypeForLanguageId(Constants::QBS_MIMETYPE, Constants::QML_JS_SETTINGS_ID); - TextEditorSettings::registerMimeTypeForLanguageId(Constants::QMLPROJECT_MIMETYPE, Constants::QML_JS_SETTINGS_ID); - TextEditorSettings::registerMimeTypeForLanguageId(Constants::QMLTYPES_MIMETYPE, Constants::QML_JS_SETTINGS_ID); - TextEditorSettings::registerMimeTypeForLanguageId(Constants::JS_MIMETYPE, Constants::QML_JS_SETTINGS_ID); - TextEditorSettings::registerMimeTypeForLanguageId(Constants::JSON_MIMETYPE, Constants::QML_JS_SETTINGS_ID); + using namespace Utils::Constants; + TextEditorSettings::registerMimeTypeForLanguageId(QML_MIMETYPE, Constants::QML_JS_SETTINGS_ID); + TextEditorSettings::registerMimeTypeForLanguageId(QMLUI_MIMETYPE, Constants::QML_JS_SETTINGS_ID); + TextEditorSettings::registerMimeTypeForLanguageId(QBS_MIMETYPE, Constants::QML_JS_SETTINGS_ID); + TextEditorSettings::registerMimeTypeForLanguageId(QMLPROJECT_MIMETYPE, Constants::QML_JS_SETTINGS_ID); + TextEditorSettings::registerMimeTypeForLanguageId(QMLTYPES_MIMETYPE, Constants::QML_JS_SETTINGS_ID); + TextEditorSettings::registerMimeTypeForLanguageId(JS_MIMETYPE, Constants::QML_JS_SETTINGS_ID); + TextEditorSettings::registerMimeTypeForLanguageId(JSON_MIMETYPE, Constants::QML_JS_SETTINGS_ID); } QmlJSToolsSettings::~QmlJSToolsSettings() diff --git a/src/plugins/qmlpreview/qmlpreviewplugin.cpp b/src/plugins/qmlpreview/qmlpreviewplugin.cpp index 011b6f43d2f..e4c0adc7d09 100644 --- a/src/plugins/qmlpreview/qmlpreviewplugin.cpp +++ b/src/plugins/qmlpreview/qmlpreviewplugin.cpp @@ -33,7 +33,6 @@ #include #include -#include #include @@ -43,6 +42,8 @@ #include +#include + #include #include #include @@ -417,25 +418,26 @@ void QmlPreviewPluginPrivate::checkEditor() return; QmlJS::Dialect::Enum dialect = QmlJS::Dialect::AnyLanguage; Core::IDocument *doc = m_lastEditor->document(); + using namespace Utils::Constants; const QString mimeType = doc->mimeType(); - if (mimeType == QmlJSTools::Constants::JS_MIMETYPE) + if (mimeType == JS_MIMETYPE) dialect = QmlJS::Dialect::JavaScript; - else if (mimeType == QmlJSTools::Constants::JSON_MIMETYPE) + else if (mimeType == JSON_MIMETYPE) dialect = QmlJS::Dialect::Json; - else if (mimeType == QmlJSTools::Constants::QML_MIMETYPE) + else if (mimeType == QML_MIMETYPE) dialect = QmlJS::Dialect::Qml; // --- Can we detect those via mime types? // else if (mimeType == ???) // dialect = QmlJS::Dialect::QmlQtQuick1; // else if (mimeType == ???) // dialect = QmlJS::Dialect::QmlQtQuick2; - else if (mimeType == QmlJSTools::Constants::QBS_MIMETYPE) + else if (mimeType == QBS_MIMETYPE) dialect = QmlJS::Dialect::QmlQbs; - else if (mimeType == QmlJSTools::Constants::QMLPROJECT_MIMETYPE) + else if (mimeType == QMLPROJECT_MIMETYPE) dialect = QmlJS::Dialect::QmlProject; - else if (mimeType == QmlJSTools::Constants::QMLTYPES_MIMETYPE) + else if (mimeType == QMLTYPES_MIMETYPE) dialect = QmlJS::Dialect::QmlTypeInfo; - else if (mimeType == QmlJSTools::Constants::QMLUI_MIMETYPE) + else if (mimeType == QMLUI_MIMETYPE) dialect = QmlJS::Dialect::QmlQtQuick2Ui; else dialect = QmlJS::Dialect::NoLanguage; diff --git a/src/plugins/qmlprojectmanager/qmlmainfileaspect.cpp b/src/plugins/qmlprojectmanager/qmlmainfileaspect.cpp index 1f5b0e69a38..68ca5460c4f 100644 --- a/src/plugins/qmlprojectmanager/qmlmainfileaspect.cpp +++ b/src/plugins/qmlprojectmanager/qmlmainfileaspect.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include @@ -216,25 +217,25 @@ bool QmlMainFileAspect::isQmlFilePresent() { bool qmlFileFound = false; if (mainScriptSource() == FileInEditor && !mainScript().isEmpty()) { + using namespace Utils::Constants; IDocument *document = EditorManager::currentDocument(); const MimeType mainScriptMimeType = mimeTypeForFile(mainScript()); if (document) { m_currentFileFilename = document->filePath(); - if (mainScriptMimeType.matchesName(ProjectExplorer::Constants::QML_MIMETYPE) - || mainScriptMimeType.matchesName(ProjectExplorer::Constants::QMLUI_MIMETYPE)) { + if (mainScriptMimeType.matchesName(QML_MIMETYPE) + || mainScriptMimeType.matchesName(QMLUI_MIMETYPE)) { qmlFileFound = true; } } if (!document - || mainScriptMimeType.matchesName(QmlJSTools::Constants::QMLPROJECT_MIMETYPE)) { + || mainScriptMimeType.matchesName(QMLPROJECT_MIMETYPE)) { // find a qml file with lowercase filename. This is slow, but only done // in initialization/other border cases. const FilePaths files = m_target->project()->files(Project::SourceFiles); for (const FilePath &filename : files) { if (!filename.isEmpty() && filename.baseName().at(0).isLower()) { const MimeType type = mimeTypeForFile(filename); - if (type.matchesName(ProjectExplorer::Constants::QML_MIMETYPE) - || type.matchesName(ProjectExplorer::Constants::QMLUI_MIMETYPE)) { + if (type.matchesName(QML_MIMETYPE) || type.matchesName(QMLUI_MIMETYPE)) { m_currentFileFilename = filename; qmlFileFound = true; break; diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index 360595e8fa4..28937ac49b2 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -44,7 +45,7 @@ using namespace Utils; namespace QmlProjectManager { QmlProject::QmlProject(const Utils::FilePath &fileName) - : Project(QString::fromLatin1(Constants::QMLPROJECT_MIMETYPE), fileName) + : Project(Utils::Constants::QMLPROJECT_MIMETYPE, fileName) { setId(QmlProjectManager::Constants::QML_PROJECT_ID); setProjectLanguages(Core::Context(ProjectExplorer::Constants::QMLJS_LANGUAGE_ID)); diff --git a/src/plugins/qmlprojectmanager/qmlprojectconstants.h b/src/plugins/qmlprojectmanager/qmlprojectconstants.h index f33018f2b4b..16b9b9d753b 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectconstants.h +++ b/src/plugins/qmlprojectmanager/qmlprojectconstants.h @@ -3,12 +3,8 @@ #pragma once -#include +namespace QmlProjectManager::Constants { -namespace QmlProjectManager { -namespace Constants { - -const char * const QMLPROJECT_MIMETYPE = QmlJSTools::Constants::QMLPROJECT_MIMETYPE; const char customFileSelectorsData[] = "CustomFileSelectorsData"; const char supportedLanguagesData[] = "SupportedLanguagesData"; const char primaryLanguageData[] = "PrimaryLanguageData"; @@ -25,5 +21,5 @@ const char enviromentLaunchedQDS[] = "QTC_LAUNCHED_QDS"; const char ALWAYS_OPEN_UI_MODE[] = "J.QtQuick/QmlJSEditor.openUiQmlMode"; const char QML_RESOURCE_PATH[] = "qmldesigner/propertyEditorQmlSources/imports"; const char LANDING_PAGE_PATH[] = "qmldesigner/landingpage"; -} // namespace Constants -} // namespace QmlProjectManager + +} // QmlProjectManager::Constants diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp index 24fd05a5540..88af8f0358d 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -252,7 +253,7 @@ void QmlProjectPlugin::initialize() d->landingPageWidget = new QdsLandingPageWidget(); - const QStringList mimeTypes = {QmlJSTools::Constants::QMLUI_MIMETYPE}; + const QStringList mimeTypes = {Utils::Constants::QMLUI_MIMETYPE}; auto context = new Internal::DesignModeContext(d->landingPageWidget); Core::ICore::addContextObject(context); @@ -262,7 +263,7 @@ void QmlProjectPlugin::initialize() this, &QmlProjectPlugin::editorModeChanged); } - ProjectManager::registerProjectType(QmlJSTools::Constants::QMLPROJECT_MIMETYPE); + ProjectManager::registerProjectType(Utils::Constants::QMLPROJECT_MIMETYPE); Utils::FileIconProvider::registerIconOverlayForSuffix(":/qmlproject/images/qmlproject.png", "qmlproject"); diff --git a/src/plugins/qtsupport/externaleditors.cpp b/src/plugins/qtsupport/externaleditors.cpp index 36abc53dbdf..4dffd9fa55d 100644 --- a/src/plugins/qtsupport/externaleditors.cpp +++ b/src/plugins/qtsupport/externaleditors.cpp @@ -13,12 +13,11 @@ #include -#include - #include #include #include #include +#include #include #include @@ -261,7 +260,7 @@ DesignerExternalEditor::DesignerExternalEditor() { setId("Qt.Designer"); setDisplayName(::Core::Tr::tr("Qt Designer")); - setMimeTypes({ProjectExplorer::Constants::FORM_MIMETYPE}); + setMimeTypes({Utils::Constants::FORM_MIMETYPE}); setEditorStarter([this](const FilePath &filePath, QString *errorMessage) { LaunchData data; @@ -333,7 +332,7 @@ LinguistEditor::LinguistEditor() { setId("Qt.Linguist"); setDisplayName(::Core::Tr::tr("Qt Linguist")); - setMimeTypes({ProjectExplorer::Constants::LINGUIST_MIMETYPE}); + setMimeTypes({Utils::Constants::LINGUIST_MIMETYPE}); setEditorStarter([](const FilePath &filePath, QString *errorMessage) { LaunchData data; return getEditorLaunchData(linguistBinary, filePath, &data, errorMessage) diff --git a/src/plugins/resourceeditor/resourceeditorconstants.h b/src/plugins/resourceeditor/resourceeditorconstants.h index 82872c1ac55..e49787dc630 100644 --- a/src/plugins/resourceeditor/resourceeditorconstants.h +++ b/src/plugins/resourceeditor/resourceeditorconstants.h @@ -14,8 +14,6 @@ const char C_RESOURCEEDITOR_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("QtC::Core", "Res const char REFRESH[] = "ResourceEditor.Refresh"; -const char C_RESOURCE_MIMETYPE[] = "application/vnd.qt.xml.resource"; - const char C_ADD_PREFIX[] = "ResourceEditor.AddPrefix"; const char C_REMOVE_PREFIX[] = "ResourceEditor.RemovePrefix"; const char C_RENAME_PREFIX[] = "ResourceEditor.RenamePrefix"; diff --git a/src/plugins/resourceeditor/resourceeditorfactory.cpp b/src/plugins/resourceeditor/resourceeditorfactory.cpp index 69ccefbe33b..862e5e7a9e7 100644 --- a/src/plugins/resourceeditor/resourceeditorfactory.cpp +++ b/src/plugins/resourceeditor/resourceeditorfactory.cpp @@ -9,10 +9,11 @@ #include #include -#include -#include -#include +#include + +#include +#include using namespace ResourceEditor::Constants; @@ -21,7 +22,7 @@ namespace ResourceEditor::Internal { ResourceEditorFactory::ResourceEditorFactory(ResourceEditorPlugin *plugin) { setId(RESOURCEEDITOR_ID); - setMimeTypes(QStringList(QLatin1String(C_RESOURCE_MIMETYPE))); + setMimeTypes(QStringList(Utils::Constants::RESOURCE_MIMETYPE)); setDisplayName(::Core::Tr::tr(C_RESOURCEEDITOR_DISPLAY_NAME)); Utils::FileIconProvider::registerIconOverlayForSuffix( diff --git a/src/plugins/resourceeditor/resourceeditorw.cpp b/src/plugins/resourceeditor/resourceeditorw.cpp index ddea065cadc..baa05697b20 100644 --- a/src/plugins/resourceeditor/resourceeditorw.cpp +++ b/src/plugins/resourceeditor/resourceeditorw.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -33,7 +34,7 @@ ResourceEditorDocument::ResourceEditorDocument(QObject *parent) : m_model(new RelativeResourceModel(this)) { setId(ResourceEditor::Constants::RESOURCEEDITOR_ID); - setMimeType(QLatin1String(ResourceEditor::Constants::C_RESOURCE_MIMETYPE)); + setMimeType(Utils::Constants::RESOURCE_MIMETYPE); connect(m_model, &RelativeResourceModel::dirtyChanged, this, &ResourceEditorDocument::dirtyChanged); connect(m_model, &ResourceModel::contentsChanged, diff --git a/src/plugins/resourceeditor/resourcenode.cpp b/src/plugins/resourceeditor/resourcenode.cpp index d402e3ed89e..e7198a41f74 100644 --- a/src/plugins/resourceeditor/resourcenode.cpp +++ b/src/plugins/resourceeditor/resourcenode.cpp @@ -3,17 +3,15 @@ #include "resourcenode.h" -#include "resourceeditorconstants.h" #include "resourceeditortr.h" #include "qrceditor/resourcefile_p.h" #include -#include - #include #include #include +#include #include #include #include @@ -40,7 +38,7 @@ public: : IDocument(nullptr), m_node(node) { setId("ResourceNodeWatcher"); - setMimeType(ResourceEditor::Constants::C_RESOURCE_MIMETYPE); + setMimeType(Utils::Constants::RESOURCE_MIMETYPE); setFilePath(node->filePath()); } @@ -106,9 +104,9 @@ static bool hasPriority(const FilePaths &files) return false; QString type = Utils::mimeTypeForFile(files.at(0)).name(); if (type.startsWith(QLatin1String("image/")) - || type == QLatin1String(QmlJSTools::Constants::QML_MIMETYPE) - || type == QLatin1String(QmlJSTools::Constants::QMLUI_MIMETYPE) - || type == QLatin1String(QmlJSTools::Constants::JS_MIMETYPE)) + || type == QLatin1String(Utils::Constants::QML_MIMETYPE) + || type == QLatin1String(Utils::Constants::QMLUI_MIMETYPE) + || type == QLatin1String(Utils::Constants::JS_MIMETYPE)) return true; return false; } diff --git a/src/plugins/scxmleditor/scxmleditordata.cpp b/src/plugins/scxmleditor/scxmleditordata.cpp index 3b3ca00ecac..6aa5b181d72 100644 --- a/src/plugins/scxmleditor/scxmleditordata.cpp +++ b/src/plugins/scxmleditor/scxmleditordata.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -128,7 +129,7 @@ void ScxmlEditorData::fullInit() context->setWidget(m_modeWidget); ICore::addContextObject(context); - DesignMode::registerDesignWidget(m_modeWidget, QStringList(QLatin1String(ProjectExplorer::Constants::SCXML_MIMETYPE)), m_contexts); + DesignMode::registerDesignWidget(m_modeWidget, QStringList(Utils::Constants::SCXML_MIMETYPE), m_contexts); } IEditor *ScxmlEditorData::createEditor() diff --git a/src/plugins/scxmleditor/scxmleditordocument.cpp b/src/plugins/scxmleditor/scxmleditordocument.cpp index 64907f8489a..0af7c6c0a6d 100644 --- a/src/plugins/scxmleditor/scxmleditordocument.cpp +++ b/src/plugins/scxmleditor/scxmleditordocument.cpp @@ -5,10 +5,10 @@ #include "mainwidget.h" #include "scxmleditorconstants.h" -#include -#include #include + #include +#include #include #include @@ -24,7 +24,7 @@ using namespace ScxmlEditor::Internal; ScxmlEditorDocument::ScxmlEditorDocument(MainWidget *designWidget, QObject *parent) : m_designWidget(designWidget) { - setMimeType(QLatin1String(ProjectExplorer::Constants::SCXML_MIMETYPE)); + setMimeType(Utils::Constants::SCXML_MIMETYPE); setParent(parent); setId(Utils::Id(ScxmlEditor::Constants::K_SCXML_EDITOR_ID)); diff --git a/src/plugins/scxmleditor/scxmleditorfactory.cpp b/src/plugins/scxmleditor/scxmleditorfactory.cpp index 55b86922052..9ef8e7250af 100644 --- a/src/plugins/scxmleditor/scxmleditorfactory.cpp +++ b/src/plugins/scxmleditor/scxmleditorfactory.cpp @@ -8,11 +8,11 @@ #include #include -#include + #include +#include #include -#include using namespace ScxmlEditor::Constants; using namespace ScxmlEditor::Internal; @@ -21,7 +21,7 @@ ScxmlEditorFactory::ScxmlEditorFactory() { setId(K_SCXML_EDITOR_ID); setDisplayName(::Core::Tr::tr(C_SCXMLEDITOR_DISPLAY_NAME)); - addMimeType(ProjectExplorer::Constants::SCXML_MIMETYPE); + addMimeType(Utils::Constants::SCXML_MIMETYPE); Utils::FileIconProvider::registerIconOverlayForSuffix(":/projectexplorer/images/fileoverlay_scxml.png", "scxml"); From b8c7186a364bac561f12b0b2ec7fb33b337ec053 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 9 Oct 2023 14:04:56 +0200 Subject: [PATCH 0123/1546] Core: Simplify system env setup code a bit Change-Id: Ic25c4b1e9371f9c46a2d95a243964f0a3ef1f878 Reviewed-by: Christian Stenger --- src/plugins/coreplugin/coreplugin.cpp | 19 +++++-------------- src/plugins/coreplugin/coreplugin.h | 4 +--- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp index 8941e617321..82356fd5be7 100644 --- a/src/plugins/coreplugin/coreplugin.cpp +++ b/src/plugins/coreplugin/coreplugin.cpp @@ -61,15 +61,8 @@ static CorePlugin *m_instance = nullptr; const char kWarnCrashReportingSetting[] = "WarnCrashReporting"; const char kEnvironmentChanges[] = "Core/EnvironmentChanges"; -void CorePlugin::setupSystemEnvironment() -{ - m_instance->m_startupSystemEnvironment = Environment::systemEnvironment(); - const EnvironmentItems changes = EnvironmentItem::fromStringList( - ICore::settings()->value(kEnvironmentChanges).toStringList()); - setEnvironmentChanges(changes); -} - CorePlugin::CorePlugin() + : m_startupSystemEnvironment(Environment::systemEnvironment()) { qRegisterMetaType(); qRegisterMetaType(); @@ -81,7 +74,10 @@ CorePlugin::CorePlugin() qRegisterMetaType(); qRegisterMetaType(); m_instance = this; - setupSystemEnvironment(); + + const EnvironmentItems changes = EnvironmentItem::fromStringList( + ICore::settings()->value(kEnvironmentChanges).toStringList()); + setEnvironmentChanges(changes); } CorePlugin::~CorePlugin() @@ -329,11 +325,6 @@ QObject *CorePlugin::remoteCommand(const QStringList & /* options */, return res; } -Environment CorePlugin::startupSystemEnvironment() -{ - return m_instance->m_startupSystemEnvironment; -} - EnvironmentItems CorePlugin::environmentChanges() { return m_instance->m_environmentChanges; diff --git a/src/plugins/coreplugin/coreplugin.h b/src/plugins/coreplugin/coreplugin.h index f06caa83d7d..987c6d15817 100644 --- a/src/plugins/coreplugin/coreplugin.h +++ b/src/plugins/coreplugin/coreplugin.h @@ -50,7 +50,6 @@ public: const QString &workingDirectory, const QStringList &args) override; - static Utils::Environment startupSystemEnvironment(); static Utils::EnvironmentItems environmentChanges(); static void setEnvironmentChanges(const Utils::EnvironmentItems &changes); static QString msgCrashpadInformation(); @@ -71,7 +70,6 @@ private slots: private: static void addToPathChooserContextMenu(Utils::PathChooser *pathChooser, QMenu *menu); - static void setupSystemEnvironment(); void checkSettings(); void warnAboutCrashReporing(); @@ -80,7 +78,7 @@ private: Locator *m_locator = nullptr; std::unique_ptr m_sessionManager; FolderNavigationWidgetFactory *m_folderNavigationWidgetFactory = nullptr; - Utils::Environment m_startupSystemEnvironment; + const Utils::Environment m_startupSystemEnvironment; Utils::EnvironmentItems m_environmentChanges; }; From ae2d429edb35e62cf64e4862f7078246026fae59 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 8 Nov 2023 10:45:49 +0100 Subject: [PATCH 0124/1546] ClangTools: Use "Diagnostics" as view title The tool is already shown in the perspective selector, and the view shows the found diagnostics. Change-Id: I0c9f7e1aa21801c176623ecb751412637ff6c025 Reviewed-by: Christian Kandeler Reviewed-by: Marcus Tillmanns --- src/plugins/clangtools/clangtool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/clangtools/clangtool.cpp b/src/plugins/clangtools/clangtool.cpp index 3f06d5144bf..4033785e796 100644 --- a/src/plugins/clangtools/clangtool.cpp +++ b/src/plugins/clangtools/clangtool.cpp @@ -555,7 +555,7 @@ ClangTool::ClangTool(const QString &name, Id id, ClangToolType type) mainLayout->addWidget(m_diagnosticView); auto mainWidget = new QWidget; mainWidget->setObjectName(id.toString() + "IssuesView"); - mainWidget->setWindowTitle(name); + mainWidget->setWindowTitle(Tr::tr("Diagnostics")); mainWidget->setLayout(mainLayout); m_perspective.addWindow(mainWidget, Perspective::SplitVertical, nullptr); From e2cc01d2131f02a56960a4717845f761a82e7e47 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 8 Nov 2023 11:59:49 +0100 Subject: [PATCH 0125/1546] ProjectExplorer: Remove unused code from KitAreaWidget Change-Id: Ic90d820f51a785967ba2d7a176ec14430119285b Reviewed-by: Christian Kandeler --- .../projectexplorer/miniprojecttargetselector.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/plugins/projectexplorer/miniprojecttargetselector.cpp b/src/plugins/projectexplorer/miniprojecttargetselector.cpp index 3fa03df9583..4279e2287be 100644 --- a/src/plugins/projectexplorer/miniprojecttargetselector.cpp +++ b/src/plugins/projectexplorer/miniprojecttargetselector.cpp @@ -559,9 +559,8 @@ void doLayout(KitAspect *aspect, Layouting::LayoutItem &builder) class KitAreaWidget : public QWidget { - Q_OBJECT public: - explicit KitAreaWidget(QWidget *parent = nullptr) + explicit KitAreaWidget(QWidget *parent) : QWidget(parent) { connect(KitManager::instance(), &KitManager::kitUpdated, this, &KitAreaWidget::updateKit); @@ -571,8 +570,6 @@ public: void setKit(Kit *k) { - qDeleteAll(m_labels); - m_labels.clear(); qDeleteAll(m_kitAspects); m_kitAspects.clear(); @@ -587,7 +584,6 @@ public: KitAspect *aspect = factory->createKitAspect(k); m_kitAspects << aspect; auto label = new QLabel(aspect->displayName()); - m_labels << label; grid.addItems({label, aspect, Layouting::br}); } } @@ -600,7 +596,7 @@ public: } private: - void updateKit(ProjectExplorer::Kit *k) + void updateKit(Kit *k) { if (!m_kit || m_kit != k) return; @@ -629,7 +625,6 @@ private: } Kit *m_kit = nullptr; - QList m_labels; QList m_kitAspects; }; From 16233c51cd31c94248ddaa78ba515451d12e2298 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 16 Aug 2023 09:08:45 +0200 Subject: [PATCH 0126/1546] ProjectExplorer: Don't internally chain KitManager signal emission Rather, emit directly in sequence. Saves a few cycles in the signal/slot machinery simplifies reasoning on the user side which signals to expect. Change-Id: Ib75f47a73e9731b506b9df3c713684a9cf59aa67 Reviewed-by: Christian Stenger --- src/plugins/projectexplorer/kitmanager.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/plugins/projectexplorer/kitmanager.cpp b/src/plugins/projectexplorer/kitmanager.cpp index 27e25e615c7..25987985edc 100644 --- a/src/plugins/projectexplorer/kitmanager.cpp +++ b/src/plugins/projectexplorer/kitmanager.cpp @@ -141,10 +141,6 @@ KitManager *KitManager::instance() KitManager::KitManager() { d = new KitManagerPrivate; - - connect(this, &KitManager::kitAdded, this, &KitManager::kitsChanged); - connect(this, &KitManager::kitRemoved, this, &KitManager::kitsChanged); - connect(this, &KitManager::kitUpdated, this, &KitManager::kitsChanged); } void KitManager::destroy() @@ -619,10 +615,12 @@ void KitManager::notifyAboutUpdate(Kit *k) if (!k || !isLoaded()) return; - if (Utils::contains(d->m_kitList, k)) + if (Utils::contains(d->m_kitList, k)) { emit instance()->kitUpdated(k); - else + emit instance()->kitsChanged(); + } else { emit instance()->unmanagedKitUpdated(k); + } } Kit *KitManager::registerKit(const std::function &init, Utils::Id id) @@ -645,6 +643,7 @@ Kit *KitManager::registerKit(const std::function &init, Utils::Id setDefaultKit(kptr); emit instance()->kitAdded(kptr); + emit instance()->kitsChanged(); return kptr; } @@ -660,6 +659,7 @@ void KitManager::deregisterKit(Kit *k) setDefaultKit(newDefault); } emit instance()->kitRemoved(k); + emit instance()->kitsChanged(); } void KitManager::setDefaultKit(Kit *k) From 79421fd597adfa7901e9fa7c45858adbcee2ae5a Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 8 Nov 2023 13:52:27 +0100 Subject: [PATCH 0127/1546] TaskTree: Rename StopOnFinished into StopOnSuccessOrError In order to conform to CallDoneIf::SuccessOrError. Amends 2c0a59384c9d250ecfbbe6d66f4848b82c6a2811 Change-Id: I2704667ca8d005c63c13b62786010ce430f0b550 Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 31 +++++------ src/libs/solutions/tasking/tasktree.h | 16 +++--- tests/auto/solutions/tasking/tst_tasking.cpp | 54 +++++++++++--------- 3 files changed, 53 insertions(+), 48 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 3a4f76f1469..b9355d07b18 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -498,8 +498,8 @@ private: afterwards, even when some other tasks in the group finished with an error. If all child tasks finish with an error, the group finishes with an error. If a group is empty, it finishes with an error. - \value StopOnFinished - Corresponds to the stopOnFinished global element. + \value StopOnSuccessOrError + Corresponds to the stopOnSuccessOrError global element. The group starts as many tasks as it can. When any task finishes, the group stops and reports the task's result. Useful only in parallel mode. @@ -518,7 +518,7 @@ private: If a group is empty, it finishes with an error. Whenever a child task's result causes the Group to stop, - i.e. in case of StopOnError, StopOnSuccess, or StopOnFinished policies, + i.e. in case of StopOnError, StopOnSuccess, or StopOnSuccessOrError policies, the Group stops the other running child tasks (if any - for example in parallel mode), and skips executing tasks it has not started yet (for example, in the sequential mode - those, that are placed after the failed task). Both stopping and skipping child tasks @@ -553,7 +553,7 @@ private: \li Success when at least one child task succeeded, an error otherwise \li An error \row - \li StopOnFinished + \li StopOnSuccessOrError \li Stops when any child task finished and reports child task's result \li Success or an error, depending on the finished child task's result \li An error @@ -571,8 +571,9 @@ private: If a child of a group is also a group, the child group runs its tasks according to its own workflow policy. When a parent group stops the running child group because - of parent group's workflow policy, i.e. when the StopOnError, StopOnSuccess, or StopOnFinished - policy was used for the parent, the child group's result is reported according to the + of parent group's workflow policy, i.e. when the StopOnError, StopOnSuccess, + or StopOnSuccessOrError policy was used for the parent, + the child group's result is reported according to the \b Result column and to the \b {child group's workflow policy} row in the table above. */ @@ -625,8 +626,8 @@ private: */ /*! - \variable stopOnFinished - A convenient global group's element describing the StopOnFinished workflow policy. + \variable stopOnSuccessOrError + A convenient global group's element describing the StopOnSuccessOrError workflow policy. */ /*! @@ -815,7 +816,7 @@ GroupItem parallelLimit(int limit) For convenience, global elements may be used instead. - \sa stopOnError, continueOnError, stopOnSuccess, continueOnSuccess, stopOnFinished, + \sa stopOnError, continueOnError, stopOnSuccess, continueOnSuccess, stopOnSuccessOrError, finishAllAndSuccess, finishAllAndError, WorkflowPolicy */ GroupItem workflowPolicy(WorkflowPolicy policy) @@ -830,7 +831,7 @@ const GroupItem stopOnError = workflowPolicy(WorkflowPolicy::StopOnError); const GroupItem continueOnError = workflowPolicy(WorkflowPolicy::ContinueOnError); const GroupItem stopOnSuccess = workflowPolicy(WorkflowPolicy::StopOnSuccess); const GroupItem continueOnSuccess = workflowPolicy(WorkflowPolicy::ContinueOnSuccess); -const GroupItem stopOnFinished = workflowPolicy(WorkflowPolicy::StopOnFinished); +const GroupItem stopOnSuccessOrError = workflowPolicy(WorkflowPolicy::StopOnSuccessOrError); const GroupItem finishAllAndSuccess = workflowPolicy(WorkflowPolicy::FinishAllAndSuccess); const GroupItem finishAllAndError = workflowPolicy(WorkflowPolicy::FinishAllAndError); @@ -1040,7 +1041,7 @@ GroupItem GroupItem::withTimeout(const GroupItem &item, milliseconds timeout, const auto onSetup = [timeout](milliseconds &timeoutData) { timeoutData = timeout; }; return Group { parallel, - stopOnFinished, + stopOnSuccessOrError, Group { finishAllAndError, handler ? TimeoutTask(onSetup, [handler] { handler(); }, CallDoneIf::Success) @@ -1321,7 +1322,7 @@ static bool initialSuccessBit(WorkflowPolicy workflowPolicy) return true; case WorkflowPolicy::StopOnSuccess: case WorkflowPolicy::ContinueOnSuccess: - case WorkflowPolicy::StopOnFinished: + case WorkflowPolicy::StopOnSuccessOrError: case WorkflowPolicy::FinishAllAndError: return false; } @@ -1350,8 +1351,8 @@ bool TaskContainer::RuntimeData::updateSuccessBit(bool success) { if (m_constData.m_workflowPolicy == WorkflowPolicy::FinishAllAndSuccess || m_constData.m_workflowPolicy == WorkflowPolicy::FinishAllAndError - || m_constData.m_workflowPolicy == WorkflowPolicy::StopOnFinished) { - if (m_constData.m_workflowPolicy == WorkflowPolicy::StopOnFinished) + || m_constData.m_workflowPolicy == WorkflowPolicy::StopOnSuccessOrError) { + if (m_constData.m_workflowPolicy == WorkflowPolicy::StopOnSuccessOrError) m_successBit = success; return m_successBit; } @@ -1440,7 +1441,7 @@ SetupResult TaskContainer::childDone(bool success) { QT_CHECK(isRunning()); const int limit = m_runtimeData->currentLimit(); // Read before bumping m_doneCount and stop() - const bool shouldStop = m_constData.m_workflowPolicy == WorkflowPolicy::StopOnFinished + const bool shouldStop = m_constData.m_workflowPolicy == WorkflowPolicy::StopOnSuccessOrError || (m_constData.m_workflowPolicy == WorkflowPolicy::StopOnSuccess && success) || (m_constData.m_workflowPolicy == WorkflowPolicy::StopOnError && !success); if (shouldStop) diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index deef203daf9..ab0dd551c6e 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -103,13 +103,13 @@ private: enum class WorkflowPolicy { - StopOnError, // 1a - Reports error on first child error, otherwise success (if all children were success). - ContinueOnError, // 1b - The same, but children execution continues. Reports success when no children. - StopOnSuccess, // 2a - Reports success on first child success, otherwise error (if all children were error). - ContinueOnSuccess, // 2b - The same, but children execution continues. Reports error when no children. - StopOnFinished, // 3 - Stops on first finished child and report its result. - FinishAllAndSuccess, // 4 - Reports success after all children finished. - FinishAllAndError // 5 - Reports error after all children finished. + StopOnError, // 1a - Reports error on first child error, otherwise success (if all children were success). + ContinueOnError, // 1b - The same, but children execution continues. Reports success when no children. + StopOnSuccess, // 2a - Reports success on first child success, otherwise error (if all children were error). + ContinueOnSuccess, // 2b - The same, but children execution continues. Reports error when no children. + StopOnSuccessOrError, // 3 - Stops on first finished child and report its result. + FinishAllAndSuccess, // 4 - Reports success after all children finished. + FinishAllAndError // 5 - Reports error after all children finished. }; Q_ENUM_NS(WorkflowPolicy); @@ -321,7 +321,7 @@ TASKING_EXPORT extern const GroupItem stopOnError; TASKING_EXPORT extern const GroupItem continueOnError; TASKING_EXPORT extern const GroupItem stopOnSuccess; TASKING_EXPORT extern const GroupItem continueOnSuccess; -TASKING_EXPORT extern const GroupItem stopOnFinished; +TASKING_EXPORT extern const GroupItem stopOnSuccessOrError; TASKING_EXPORT extern const GroupItem finishAllAndSuccess; TASKING_EXPORT extern const GroupItem finishAllAndError; diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index c2116cbb940..ec90218f3a4 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -614,7 +614,7 @@ void tst_Tasking::testTree_data() QTest::newRow("DoneAndContinueOnError") << doneData(WorkflowPolicy::ContinueOnError); QTest::newRow("DoneAndStopOnSuccess") << doneData(WorkflowPolicy::StopOnSuccess); QTest::newRow("DoneAndContinueOnSuccess") << doneData(WorkflowPolicy::ContinueOnSuccess); - QTest::newRow("DoneAndStopOnFinished") << doneData(WorkflowPolicy::StopOnFinished); + QTest::newRow("DoneAndStopOnSuccessOrError") << doneData(WorkflowPolicy::StopOnSuccessOrError); QTest::newRow("DoneAndFinishAllAndSuccess") << doneData(WorkflowPolicy::FinishAllAndSuccess); QTest::newRow("DoneAndFinishAllAndError") << doneData(WorkflowPolicy::FinishAllAndError); @@ -622,7 +622,7 @@ void tst_Tasking::testTree_data() QTest::newRow("ErrorAndContinueOnError") << errorData(WorkflowPolicy::ContinueOnError); QTest::newRow("ErrorAndStopOnSuccess") << errorData(WorkflowPolicy::StopOnSuccess); QTest::newRow("ErrorAndContinueOnSuccess") << errorData(WorkflowPolicy::ContinueOnSuccess); - QTest::newRow("ErrorAndStopOnFinished") << errorData(WorkflowPolicy::StopOnFinished); + QTest::newRow("ErrorAndStopOnSuccessOrError") << errorData(WorkflowPolicy::StopOnSuccessOrError); QTest::newRow("ErrorAndFinishAllAndSuccess") << errorData(WorkflowPolicy::FinishAllAndSuccess); QTest::newRow("ErrorAndFinishAllAndError") << errorData(WorkflowPolicy::FinishAllAndError); } @@ -974,8 +974,8 @@ void tst_Tasking::testTree_data() QTest::newRow("EmptyContinueOnSuccess") << TestData{storage, root4, errorLog, 0, DoneWith::Error}; - const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); - QTest::newRow("EmptyStopOnFinished") << TestData{storage, root5, errorLog, 0, + const Group root5 = createRoot(WorkflowPolicy::StopOnSuccessOrError); + QTest::newRow("EmptyStopOnSuccessOrError") << TestData{storage, root5, errorLog, 0, DoneWith::Error}; const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); @@ -1026,8 +1026,8 @@ void tst_Tasking::testTree_data() QTest::newRow("DoneContinueOnSuccess") << TestData{storage, root4, doneLog, 1, DoneWith::Success}; - const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); - QTest::newRow("DoneStopOnFinished") << TestData{storage, root5, doneLog, 1, + const Group root5 = createRoot(WorkflowPolicy::StopOnSuccessOrError); + QTest::newRow("DoneStopOnSuccessOrError") << TestData{storage, root5, doneLog, 1, DoneWith::Success}; const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); @@ -1078,8 +1078,8 @@ void tst_Tasking::testTree_data() QTest::newRow("ErrorContinueOnSuccess") << TestData{storage, root4, errorLog, 1, DoneWith::Error}; - const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); - QTest::newRow("ErrorStopOnFinished") << TestData{storage, root5, errorLog, 1, + const Group root5 = createRoot(WorkflowPolicy::StopOnSuccessOrError); + QTest::newRow("ErrorStopOnSuccessOrError") << TestData{storage, root5, errorLog, 1, DoneWith::Error}; const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); @@ -1147,8 +1147,8 @@ void tst_Tasking::testTree_data() QTest::newRow("StopRootWithContinueOnSuccess") << TestData{storage, root4, doneLog, 2, DoneWith::Success}; - const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); - QTest::newRow("StopRootWithStopOnFinished") + const Group root5 = createRoot(WorkflowPolicy::StopOnSuccessOrError); + QTest::newRow("StopRootWithStopOnSuccessOrError") << TestData{storage, root5, errorErrorLog, 2, DoneWith::Error}; const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); @@ -1234,8 +1234,8 @@ void tst_Tasking::testTree_data() QTest::newRow("StopRootAfterDoneWithContinueOnSuccess") << TestData{storage, root4, doneDoneLog, 3, DoneWith::Success}; - const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); - QTest::newRow("StopRootAfterDoneWithStopOnFinished") + const Group root5 = createRoot(WorkflowPolicy::StopOnSuccessOrError); + QTest::newRow("StopRootAfterDoneWithStopOnSuccessOrError") << TestData{storage, root5, doneErrorLog, 3, DoneWith::Success}; const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); @@ -1291,8 +1291,8 @@ void tst_Tasking::testTree_data() QTest::newRow("StopGroupWithContinueOnSuccess") << TestData{storage, root4, log, 2, DoneWith::Error}; - const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); - QTest::newRow("StopGroupWithStopOnFinished") + const Group root5 = createRoot(WorkflowPolicy::StopOnSuccessOrError); + QTest::newRow("StopGroupWithStopOnSuccessOrError") << TestData{storage, root5, log, 2, DoneWith::Error}; // TODO: Behavioral change! Fix Docs! @@ -1363,8 +1363,8 @@ void tst_Tasking::testTree_data() QTest::newRow("StopGroupAfterDoneWithContinueOnSuccess") << TestData{storage, root4, errorLog, 3, DoneWith::Error}; - const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); - QTest::newRow("StopGroupAfterDoneWithStopOnFinished") + const Group root5 = createRoot(WorkflowPolicy::StopOnSuccessOrError); + QTest::newRow("StopGroupAfterDoneWithStopOnSuccessOrError") << TestData{storage, root5, doneLog, 3, DoneWith::Error}; // TODO: Behavioral change! @@ -1433,8 +1433,8 @@ void tst_Tasking::testTree_data() QTest::newRow("StopGroupAfterErrorWithContinueOnSuccess") << TestData{storage, root4, longLog, 3, DoneWith::Error}; - const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); - QTest::newRow("StopGroupAfterErrorWithStopOnFinished") + const Group root5 = createRoot(WorkflowPolicy::StopOnSuccessOrError); + QTest::newRow("StopGroupAfterErrorWithStopOnSuccessOrError") << TestData{storage, root5, shortLog, 3, DoneWith::Error}; // TODO: Behavioral change! @@ -1502,13 +1502,13 @@ void tst_Tasking::testTree_data() }; QTest::newRow("ContinueOnSuccess") << TestData{storage, root4, doneLog, 3, DoneWith::Success}; - const Group root5 = createRoot(WorkflowPolicy::StopOnFinished); + const Group root5 = createRoot(WorkflowPolicy::StopOnSuccessOrError); const Log log5 { {1, Handler::Setup}, {1, Handler::Success}, {0, Handler::GroupSuccess} }; - QTest::newRow("StopOnFinished") << TestData{storage, root5, log5, 3, DoneWith::Success}; + QTest::newRow("StopOnSuccessOrError") << TestData{storage, root5, log5, 3, DoneWith::Success}; const Group root6 = createRoot(WorkflowPolicy::FinishAllAndSuccess); QTest::newRow("FinishAllAndSuccess") << TestData{storage, root6, doneLog, 3, DoneWith::Success}; @@ -1522,7 +1522,7 @@ void tst_Tasking::testTree_data() DoneResult secondResult) { return Group { parallel, - stopOnFinished, + stopOnSuccessOrError, Storage(storage), createTask(1, firstResult, 1000ms), createTask(2, secondResult, 1ms), @@ -1550,10 +1550,14 @@ void tst_Tasking::testTree_data() {0, Handler::GroupError} }; - QTest::newRow("StopOnFinished1") << TestData{storage, root1, success, 2, DoneWith::Success}; - QTest::newRow("StopOnFinished2") << TestData{storage, root2, failure, 2, DoneWith::Error}; - QTest::newRow("StopOnFinished3") << TestData{storage, root3, success, 2, DoneWith::Success}; - QTest::newRow("StopOnFinished4") << TestData{storage, root4, failure, 2, DoneWith::Error}; + QTest::newRow("StopOnSuccessOrError1") + << TestData{storage, root1, success, 2, DoneWith::Success}; + QTest::newRow("StopOnSuccessOrError2") + << TestData{storage, root2, failure, 2, DoneWith::Error}; + QTest::newRow("StopOnSuccessOrError3") + << TestData{storage, root3, success, 2, DoneWith::Success}; + QTest::newRow("StopOnSuccessOrError4") + << TestData{storage, root4, failure, 2, DoneWith::Error}; } { From 76dbc9e42bb8f499ccf2a8f988d28e3c4db724cd Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Wed, 8 Nov 2023 14:19:37 +0100 Subject: [PATCH 0128/1546] Utils: Remove handling of macOS < 10.14 in theme_mac.mm Qt Creator should only be built and be running on macOS 10.14 or later. This cleanup is in preparation for other following changes. Task-number: QTCREATORBUG-29783 Change-Id: Idd549051b899726f2db8fed320a2ef15e948d2d7 Reviewed-by: Marcus Tillmanns --- src/libs/utils/theme/theme_mac.mm | 32 +++++++------------------------ 1 file changed, 7 insertions(+), 25 deletions(-) diff --git a/src/libs/utils/theme/theme_mac.mm b/src/libs/utils/theme/theme_mac.mm index 52f4a2c1299..e01ace28f94 100644 --- a/src/libs/utils/theme/theme_mac.mm +++ b/src/libs/utils/theme/theme_mac.mm @@ -4,47 +4,29 @@ #include "theme_mac.h" #include -#include #include -#if !QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) -@interface NSApplication (MojaveForwardDeclarations) -@property (strong) NSAppearance *appearance NS_AVAILABLE_MAC(10_14); -@end -#endif - namespace Utils { namespace Internal { bool currentAppearanceMatches(bool dark) { -#if QT_MACOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_14) - if (__builtin_available(macOS 10.14, *)) { - auto appearance = [NSApp.effectiveAppearance - bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]]; - return - [appearance isEqualToString:(dark ? NSAppearanceNameDarkAqua : NSAppearanceNameAqua)]; - } -#endif - return true; + auto appearance = [NSApp.effectiveAppearance + bestMatchFromAppearancesWithNames:@[NSAppearanceNameAqua, NSAppearanceNameDarkAqua]]; + return + [appearance isEqualToString:(dark ? NSAppearanceNameDarkAqua : NSAppearanceNameAqua)]; } void forceMacAppearance(bool dark) { -#if __has_builtin(__builtin_available) - if (__builtin_available(macOS 10.14, *)) -#else // Xcode 8 - if (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::MacOS, 10, 14, 0)) -#endif - NSApp.appearance = [NSAppearance - appearanceNamed:(dark ? NSAppearanceNameDarkAqua : NSAppearanceNameAqua)]; + NSApp.appearance = [NSAppearance + appearanceNamed:(dark ? NSAppearanceNameDarkAqua : NSAppearanceNameAqua)]; } bool currentAppearanceIsDark() { - // double negation, so we get "false" for macOS 10.13 - return !currentAppearanceMatches(false /*==light*/); + return currentAppearanceMatches(true); } void setMacOSHelpMenu(QMenu *menu) From b75df9eb833be14873b2ff688b652400da850d4b Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 23 Oct 2023 18:48:29 +0200 Subject: [PATCH 0129/1546] AdvancedDockingSystem: Avoid using sender() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iabc97c99046e1ebabddf988c675a51a93875ddf5 Reviewed-by: Qt CI Bot Reviewed-by: Reviewed-by: Henning Gründl --- src/libs/advanceddockingsystem/autohidetab.cpp | 13 +++---------- src/libs/advanceddockingsystem/autohidetab.h | 2 -- .../advanceddockingsystem/dockareatitlebar.cpp | 16 +++------------- .../advanceddockingsystem/dockareatitlebar.h | 1 - src/libs/advanceddockingsystem/dockwidgettab.cpp | 12 +++--------- src/libs/advanceddockingsystem/dockwidgettab.h | 1 - 6 files changed, 9 insertions(+), 36 deletions(-) diff --git a/src/libs/advanceddockingsystem/autohidetab.cpp b/src/libs/advanceddockingsystem/autohidetab.cpp index dd3f3f6c820..eafab68efef 100644 --- a/src/libs/advanceddockingsystem/autohidetab.cpp +++ b/src/libs/advanceddockingsystem/autohidetab.cpp @@ -21,8 +21,6 @@ namespace ADS { -static const char *const g_locationProperty = "Location"; - /** * Private data class of CDockWidgetTab class (pimpl) */ @@ -74,8 +72,9 @@ struct AutoHideTabPrivate QAction *createAutoHideToAction(const QString &title, SideBarLocation location, QMenu *menu) { auto action = menu->addAction(title); - action->setProperty("Location", location); - QObject::connect(action, &QAction::triggered, q, &AutoHideTab::onAutoHideToActionClicked); + QObject::connect(action, &QAction::triggered, q, [this, location] { + m_dockWidget->setAutoHide(true, location); + }); action->setEnabled(location != q->sideBarLocation()); return action; } @@ -277,12 +276,6 @@ void AutoHideTab::requestCloseDockWidget() d->m_dockWidget->requestCloseDockWidget(); } -void AutoHideTab::onAutoHideToActionClicked() -{ - int location = sender()->property(g_locationProperty).toInt(); - d->m_dockWidget->setAutoHide(true, (SideBarLocation) location); -} - void AutoHideTab::setSideBar(AutoHideSideBar *sideTabBar) { d->m_sideBar = sideTabBar; diff --git a/src/libs/advanceddockingsystem/autohidetab.h b/src/libs/advanceddockingsystem/autohidetab.h index d8a4a2a1e61..d97aeb17fe4 100644 --- a/src/libs/advanceddockingsystem/autohidetab.h +++ b/src/libs/advanceddockingsystem/autohidetab.h @@ -38,8 +38,6 @@ private: friend class DockContainerWidget; friend DockContainerWidgetPrivate; - void onAutoHideToActionClicked(); - protected: void setSideBar(AutoHideSideBar *sideTabBar); void removeFromSideBar(); diff --git a/src/libs/advanceddockingsystem/dockareatitlebar.cpp b/src/libs/advanceddockingsystem/dockareatitlebar.cpp index 7a2e6770621..00627ef19fb 100644 --- a/src/libs/advanceddockingsystem/dockareatitlebar.cpp +++ b/src/libs/advanceddockingsystem/dockareatitlebar.cpp @@ -35,8 +35,6 @@ namespace ADS { -static const char *const g_locationProperty = "Location"; - /** * Private data class of DockAreaTitleBar class (pimpl) */ @@ -125,11 +123,9 @@ public: QAction *createAutoHideToAction(const QString &title, SideBarLocation location, QMenu *menu) { auto action = menu->addAction(title); - action->setProperty("Location", location); - QObject::connect(action, - &QAction::triggered, - q, - &DockAreaTitleBar::onAutoHideToActionClicked); + QObject::connect(action, &QAction::triggered, q, [this, location] { + m_dockArea->toggleAutoHide(location); + }); return action; } }; // class DockAreaTitleBarPrivate @@ -526,12 +522,6 @@ void DockAreaTitleBar::onAutoHideDockAreaActionClicked() d->m_dockArea->toggleAutoHide(); } -void DockAreaTitleBar::onAutoHideToActionClicked() -{ - int location = sender()->property(g_locationProperty).toInt(); - d->m_dockArea->toggleAutoHide((SideBarLocation) location); -} - TitleBarButton *DockAreaTitleBar::button(eTitleBarButton which) const { switch (which) { diff --git a/src/libs/advanceddockingsystem/dockareatitlebar.h b/src/libs/advanceddockingsystem/dockareatitlebar.h index 738dea476de..ac130bf197a 100644 --- a/src/libs/advanceddockingsystem/dockareatitlebar.h +++ b/src/libs/advanceddockingsystem/dockareatitlebar.h @@ -89,7 +89,6 @@ private: void onCurrentTabChanged(int index); void onAutoHideButtonClicked(); void onAutoHideDockAreaActionClicked(); - void onAutoHideToActionClicked(); protected: /** diff --git a/src/libs/advanceddockingsystem/dockwidgettab.cpp b/src/libs/advanceddockingsystem/dockwidgettab.cpp index d450c6ddd19..44a7c33d89e 100644 --- a/src/libs/advanceddockingsystem/dockwidgettab.cpp +++ b/src/libs/advanceddockingsystem/dockwidgettab.cpp @@ -35,7 +35,6 @@ namespace ADS { -static const char *const g_locationProperty = "Location"; using TabLabelType = ElidingLabel; /** @@ -181,8 +180,9 @@ public: QAction *createAutoHideToAction(const QString &title, SideBarLocation location, QMenu *menu) { auto action = menu->addAction(title); - action->setProperty("Location", location); - QObject::connect(action, &QAction::triggered, q, &DockWidgetTab::onAutoHideToActionClicked); + QObject::connect(action, &QAction::triggered, q, [this, location] { + m_dockWidget->toggleAutoHide(location); + }); return action; } @@ -656,12 +656,6 @@ void DockWidgetTab::autoHideDockWidget() d->m_dockWidget->setAutoHide(true); } -void DockWidgetTab::onAutoHideToActionClicked() -{ - int location = sender()->property(g_locationProperty).toInt(); - d->m_dockWidget->toggleAutoHide((SideBarLocation) location); -} - bool DockWidgetTab::event(QEvent *event) { #ifndef QT_NO_TOOLTIP diff --git a/src/libs/advanceddockingsystem/dockwidgettab.h b/src/libs/advanceddockingsystem/dockwidgettab.h index 1b3c6f9d116..b985d1150f6 100644 --- a/src/libs/advanceddockingsystem/dockwidgettab.h +++ b/src/libs/advanceddockingsystem/dockwidgettab.h @@ -55,7 +55,6 @@ private: void onDockWidgetFeaturesChanged(); void detachDockWidget(); void autoHideDockWidget(); - void onAutoHideToActionClicked(); protected: void mousePressEvent(QMouseEvent *event) override; From 611bef47ce2cd515c92f0321b73df5680bfff666 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 23 Oct 2023 19:52:57 +0200 Subject: [PATCH 0130/1546] DockFocusController: Avoid using sender() for visibilityChanged() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use Qt::SingleShotConnection connection instead and remove disconnect. Change-Id: If3ec082bb2341277bfeb781b13986492a88172e6 Reviewed-by: Henning Gründl Reviewed-by: Qt CI Bot --- .../dockfocuscontroller.cpp | 20 +++++-------------- .../dockfocuscontroller.h | 1 - 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/src/libs/advanceddockingsystem/dockfocuscontroller.cpp b/src/libs/advanceddockingsystem/dockfocuscontroller.cpp index ab665ea0ae7..a9fd274004c 100644 --- a/src/libs/advanceddockingsystem/dockfocuscontroller.cpp +++ b/src/libs/advanceddockingsystem/dockfocuscontroller.cpp @@ -158,24 +158,14 @@ void DockFocusControllerPrivate::updateDockWidgetFocus(DockWidget *dockWidget) emit m_dockManager->focusedDockWidgetChanged(old, dockWidget); } else { m_oldFocusedDockWidget = old; - QObject::connect(dockWidget, - &DockWidget::visibilityChanged, - q, - &DockFocusController::onDockWidgetVisibilityChanged); + QObject::connect(dockWidget, &DockWidget::visibilityChanged, q, + [this, dockWidget](bool visible) { + if (visible) + emit m_dockManager->focusedDockWidgetChanged(m_oldFocusedDockWidget, dockWidget); + }, Qt::SingleShotConnection); } } -void DockFocusController::onDockWidgetVisibilityChanged(bool visible) -{ - auto dockWidget = qobject_cast(sender()); - QObject::disconnect(dockWidget, - &DockWidget::visibilityChanged, - this, - &DockFocusController::onDockWidgetVisibilityChanged); - if (dockWidget && visible) - emit d->m_dockManager->focusedDockWidgetChanged(d->m_oldFocusedDockWidget, dockWidget); -} - DockFocusController::DockFocusController(DockManager *dockManager) : QObject(dockManager) , d(new DockFocusControllerPrivate(this)) diff --git a/src/libs/advanceddockingsystem/dockfocuscontroller.h b/src/libs/advanceddockingsystem/dockfocuscontroller.h index a9e11e13662..992dee27736 100644 --- a/src/libs/advanceddockingsystem/dockfocuscontroller.h +++ b/src/libs/advanceddockingsystem/dockfocuscontroller.h @@ -30,7 +30,6 @@ private: void onFocusWindowChanged(QWindow *focusWindow); void onFocusedDockAreaViewToggled(bool open); void onStateRestored(); - void onDockWidgetVisibilityChanged(bool visible); public: /** From 9a8531c22f5fa16d052725081363856b15657bf0 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 23 Oct 2023 19:56:59 +0200 Subject: [PATCH 0131/1546] DockFocusController: Avoid using sender() in onFocusedDockAreaViewToggled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since m_focusedArea is always a sender of the signal connected to the onFocusedDockAreaViewToggled() slot, reuse it in place of sender(). Change-Id: I17b817132c8b74e825f0accb9c1d467bfdf24ac3 Reviewed-by: Henning Gründl Reviewed-by: Qt CI Bot --- .../advanceddockingsystem/dockfocuscontroller.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/libs/advanceddockingsystem/dockfocuscontroller.cpp b/src/libs/advanceddockingsystem/dockfocuscontroller.cpp index a9fd274004c..549e13c5a94 100644 --- a/src/libs/advanceddockingsystem/dockfocuscontroller.cpp +++ b/src/libs/advanceddockingsystem/dockfocuscontroller.cpp @@ -267,16 +267,9 @@ void DockFocusController::onFocusedDockAreaViewToggled(bool open) if (d->m_dockManager->isRestoringState() || !d->m_focusedArea || open) return; - DockAreaWidget *dockArea = qobject_cast(sender()); - if (!dockArea || open) - return; - - auto container = dockArea->dockContainer(); - auto openedDockAreas = container->openedDockAreas(); - if (openedDockAreas.isEmpty()) - return; - - d->updateDockWidgetFocus(openedDockAreas[0]->currentDockWidget()); + const auto openedDockAreas = d->m_focusedArea->dockContainer()->openedDockAreas(); + if (!openedDockAreas.isEmpty()) + d->updateDockWidgetFocus(openedDockAreas.first()->currentDockWidget()); } void DockFocusController::notifyWidgetOrAreaRelocation(QWidget *droppedWidget) From 05e7308c08301b5bda20334cb1f3f71d2d7c0e85 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 8 Nov 2023 15:59:22 +0100 Subject: [PATCH 0132/1546] ProjectExplorer: Use more Ids instead of Kit in KitModel The idea is to slowly move towards a uniform approach to handle the Kits/Qt Version/Debugger/Toolchain/... managers/settings. Change-Id: I6ddba968a51d9468bb0dfec74b2fb8b902d11294 Reviewed-by: Christian Kandeler --- .../projectexplorer/kitoptionspage.cpp | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/plugins/projectexplorer/kitoptionspage.cpp b/src/plugins/projectexplorer/kitoptionspage.cpp index e3c84549ca8..87b0465c7ab 100644 --- a/src/plugins/projectexplorer/kitoptionspage.cpp +++ b/src/plugins/projectexplorer/kitoptionspage.cpp @@ -176,7 +176,6 @@ public: Kit *kit(const QModelIndex &); KitNode *kitNode(const QModelIndex &); - QModelIndex indexOf(Kit *k) const; QModelIndex indexOf(Id kitId) const; void setDefaultKit(const QModelIndex &index); @@ -187,7 +186,7 @@ public: void apply(); void markForRemoval(Kit *k); - Kit *markForAddition(Kit *baseKit); + Id markForAddition(Kit *baseKit); void updateVisibility(); @@ -264,12 +263,6 @@ QModelIndex KitModel::indexOf(Id kitId) const return n ? indexForItem(n) : QModelIndex(); } -QModelIndex KitModel::indexOf(Kit *k) const -{ - KitNode *n = findWorkingCopy(k); - return n ? indexForItem(n) : QModelIndex(); -} - void KitModel::setDefaultKit(const QModelIndex &index) { if (KitNode *n = kitNode(index)) @@ -348,7 +341,7 @@ void KitModel::markForRemoval(Kit *k) validateKitNames(); } -Kit *KitModel::markForAddition(Kit *baseKit) +Id KitModel::markForAddition(Kit *baseKit) { const QString newName = newKitName(baseKit ? baseKit->unexpandedDisplayName() : QString()); KitNode *node = createNode(nullptr); @@ -367,7 +360,7 @@ Kit *KitModel::markForAddition(Kit *baseKit) if (!m_defaultNode) setDefaultNode(node); - return k; + return k->id(); } void KitModel::updateVisibility() @@ -625,9 +618,9 @@ void KitOptionsPageWidget::kitSelectionChanged() void KitOptionsPageWidget::addNewKit() { - Kit *k = m_model->markForAddition(nullptr); + Id kitId = m_model->markForAddition(nullptr); - QModelIndex newIdx = m_sortModel->mapFromSource(m_model->indexOf(k)); + QModelIndex newIdx = m_sortModel->mapFromSource(m_model->indexOf(kitId)); m_selectionModel->select(newIdx, QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent @@ -648,8 +641,8 @@ void KitOptionsPageWidget::cloneKit() if (!current) return; - Kit *k = m_model->markForAddition(current); - QModelIndex newIdx = m_sortModel->mapFromSource(m_model->indexOf(k)); + Id kitId = m_model->markForAddition(current); + QModelIndex newIdx = m_sortModel->mapFromSource(m_model->indexOf(kitId)); m_kitsView->scrollTo(newIdx); m_selectionModel->select(newIdx, QItemSelectionModel::Clear From 792d88aa052a62d34483f31be30d501a3516741a Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 5 Jul 2023 14:16:10 +0200 Subject: [PATCH 0133/1546] Core: Introduce Menu and Action classes Idea is to have a bit more "object { propertySetter }" kind of pattern for common cases and to couple actions and menus only via Ids, not real objects. In a LayoutBuilder context this might later look like Menu { id(BOOKMARKS_MENU), title(Tr::tr("&Bookmarks")), container(Core::Constants::M_TOOLS) } in the end. Overall line count increases but I claim it reduces complexity on the user code side. Change-Id: I166e0c8c6b3036430dc464fd652fb37ded21c09a Reviewed-by: Eike Ziller --- .../actionmanager/actionmanager.cpp | 161 ++++++++++++++++++ .../coreplugin/actionmanager/actionmanager.h | 49 ++++++ src/plugins/texteditor/texteditorplugin.cpp | 128 +++++++------- 3 files changed, 273 insertions(+), 65 deletions(-) diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index d58fe42cec0..f791e9e22e2 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -66,6 +66,165 @@ void PresentationModeHandler::showShortcutPopup(const QString &shortcut) Utils::FadingIndicator::showText(window, shortcut); } +} // Core::Internal + + +namespace Core { + +class ActionPrivate +{ +public: + void ensureCommand() + { + if (!command) { + QTC_ASSERT(actionId.isValid(), return); + QTC_ASSERT(!context.isEmpty(), return); + command = ActionManager::registerAction(&action, actionId, context); + } + } + + QAction action; + Id actionId; + Context context; + Command *command = nullptr; +}; + +Action::Action() + : d(new ActionPrivate) +{ +} + +Action::~Action() +{ + delete d; +} + +void Action::setText(const QString &text) +{ + d->action.setText(text); +} + +void Action::setCommandAttribute(Command::CommandAttribute attr) +{ + d->ensureCommand(); + QTC_ASSERT(d->command, return); + d->command->setAttribute(attr); +} + +void Action::setContainer(Utils::Id containerId, Utils::Id groupId) +{ + d->ensureCommand(); + QTC_ASSERT(d->command, return); + if (containerId.isValid()) { + ActionContainer *container = ActionManager::actionContainer(containerId); + container->addAction(d->command, groupId); + } +} + +void Action::setOnTriggered(const std::function &func) +{ + QObject::connect(&d->action, &QAction::triggered, &d->action, func); +} + +void Action::setOnTriggered(QObject *guard, const std::function &func) +{ + QObject::connect(&d->action, &QAction::triggered, guard, func); +} + +void Action::setDefaultKeySequence(const QKeySequence &seq) +{ + d->ensureCommand(); + QTC_ASSERT(d->command, return); + d->command->setDefaultKeySequence(seq); +} + +void Action::setDefaultKeySequence(const QString &mac, const QString &nonMac) +{ + d->ensureCommand(); + QTC_ASSERT(d->command, return); + d->command->setDefaultKeySequence(QKeySequence(useMacShortcuts ? mac : nonMac)); +} + +void Action::setIcon(const QIcon &icon) +{ + d->action.setIcon(icon); +} + +void Action::setIconVisibleInMenu(bool on) +{ + d->action.setIconVisibleInMenu(on); +} + +void Action::setTouchBarIcon(const QIcon &icon) +{ + d->ensureCommand(); + QTC_ASSERT(d->command, return); + d->command->setTouchBarIcon(icon); +} + +void Action::setEnabled(bool on) +{ + d->action.setEnabled(on); +} + +Command *Action::command() const +{ + d->ensureCommand(); + QTC_CHECK(d->command); + return d->command; +} + +void Action::setId(Id id) +{ + d->actionId = id; +} + +void Action::setContext(Id id) +{ + d->context = Context(id); +} + +void Action::setContext(const Context &context) +{ + d->context = context; +} + +// Separator + +ActionSeparator::ActionSeparator(Id id) +{ + ActionContainer *container = ActionManager::actionContainer(id); + QTC_ASSERT(container, return); + container->addSeparator(); +} + +// Menu + +Menu::Menu() = default; + +void Menu::setId(Id id) +{ + QTC_ASSERT(!m_menu, return); + m_menu = ActionManager::createMenu(id); +} + +void Menu::setTitle(const QString &title) +{ + QTC_ASSERT(m_menu, return); + m_menu->menu()->setTitle(title); +} + +void Menu::setContainer(Id containerId, Id groupId) +{ + QTC_ASSERT(m_menu, return); + ActionContainer *container = ActionManager::actionContainer(containerId); + container->addMenu(m_menu, groupId); +} + +void Menu::addSeparator() +{ + QTC_ASSERT(m_menu, return); + m_menu->addSeparator(); } /*! @@ -536,3 +695,5 @@ void ActionManagerPrivate::saveSettings() saveSettings(j.value()); } } + +} // Core diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.h b/src/plugins/coreplugin/actionmanager/actionmanager.h index a0b522610f8..ba2eb4b0e06 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager.h @@ -11,6 +11,8 @@ #include #include +#include + QT_BEGIN_NAMESPACE class QAction; class QString; @@ -29,6 +31,53 @@ class ICorePrivate; class MainWindow; } // Internal +class CORE_EXPORT Action +{ +public: + Action(); + ~Action(); + + void setId(Utils::Id id); + void setContext(const Utils::Id id); + void setContext(const Core::Context &context); + void setText(const QString &text); + void setCommandAttribute(Core::Command::CommandAttribute attr); + void setContainer(Utils::Id containerId, Utils::Id groupId = {}); + void setOnTriggered(const std::function &func); + void setOnTriggered(QObject *guard, const std::function &func); + void setDefaultKeySequence(const QKeySequence &seq); + void setDefaultKeySequence(const QString &mac, const QString &nonMac); + void setIcon(const QIcon &icon); + void setIconVisibleInMenu(bool on); + void setTouchBarIcon(const QIcon &icon); + void setEnabled(bool on); + + Command *command() const; + +private: + class ActionPrivate *d = nullptr; +}; + +class CORE_EXPORT Menu +{ +public: + Menu(); + + void setId(Utils::Id id); + void setTitle(const QString &title); + void setContainer(Utils::Id containerId, Utils::Id groupId = {}); + void addSeparator(); + +private: + ActionContainer *m_menu = nullptr; +}; + +class CORE_EXPORT ActionSeparator +{ +public: + ActionSeparator(Utils::Id id); +}; + class CORE_EXPORT ActionManager : public QObject { Q_OBJECT diff --git a/src/plugins/texteditor/texteditorplugin.cpp b/src/plugins/texteditor/texteditorplugin.cpp index f8de8503937..cc7ad90cc83 100644 --- a/src/plugins/texteditor/texteditorplugin.cpp +++ b/src/plugins/texteditor/texteditorplugin.cpp @@ -86,12 +86,14 @@ public: BookmarkFilter m_bookmarkFilter{&m_bookmarkManager}; BookmarkViewFactory m_bookmarkViewFactory{&m_bookmarkManager}; - QAction m_toggleAction{Tr::tr("Toggle Bookmark")}; - QAction m_editAction{Tr::tr("Edit Bookmark")}; - QAction m_prevAction{Tr::tr("Previous Bookmark")}; - QAction m_nextAction{Tr::tr("Next Bookmark")}; - QAction m_docPrevAction{Tr::tr("Previous Bookmark in Document")}; - QAction m_docNextAction{Tr::tr("Next Bookmark in Document")}; + Menu m_bookmarkMenu; + Action m_toggleAction; + Action m_editAction; + Action m_prevAction; + Action m_nextAction; + Action m_docPrevAction; + Action m_docNextAction; + QAction m_editBookmarkAction{Tr::tr("Edit Bookmark")}; QAction m_bookmarkMarginAction{Tr::tr("Toggle Bookmark")}; @@ -113,66 +115,32 @@ public: TextEditorPluginPrivate::TextEditorPluginPrivate() { - ActionContainer *mtools = ActionManager::actionContainer(Core::Constants::M_TOOLS); - ActionContainer *touchBar = ActionManager::actionContainer(Core::Constants::TOUCH_BAR); - ActionContainer *mbm = ActionManager::createMenu(Id("Bookmarks.Menu")); - - mbm->menu()->setTitle(Tr::tr("&Bookmarks")); - mtools->addMenu(mbm); - + const Id bookmarkMenuId = "Bookmarks.Menu"; const Context editorManagerContext(Core::Constants::C_EDITORMANAGER); - // Toggle - Command *cmd = ActionManager::registerAction(&m_toggleAction, "Bookmarks.Toggle", - editorManagerContext); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Meta+M") : Tr::tr("Ctrl+M"))); - cmd->setTouchBarIcon(Icons::MACOS_TOUCHBAR_BOOKMARK.icon()); - mbm->addAction(cmd); - touchBar->addAction(cmd, Core::Constants::G_TOUCHBAR_EDITOR); + m_bookmarkMenu.setId(bookmarkMenuId); + m_bookmarkMenu.setTitle(Tr::tr("&Bookmarks")); + m_bookmarkMenu.setContainer(Core::Constants::M_TOOLS); - cmd = ActionManager::registerAction(&m_editAction, "Bookmarks.Edit", editorManagerContext); - cmd->setDefaultKeySequence( - QKeySequence(useMacShortcuts ? Tr::tr("Meta+Shift+M") : Tr::tr("Ctrl+Shift+M"))); - mbm->addAction(cmd); - - mbm->addSeparator(); - - // Previous - m_prevAction.setIcon(Icons::PREV_TOOLBAR.icon()); - m_prevAction.setIconVisibleInMenu(false); - cmd = ActionManager::registerAction(&m_prevAction, BOOKMARKS_PREV_ACTION, editorManagerContext); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Meta+,") - : Tr::tr("Ctrl+,"))); - mbm->addAction(cmd); - - // Next - m_nextAction.setIcon(Icons::NEXT_TOOLBAR.icon()); - m_nextAction.setIconVisibleInMenu(false); - cmd = ActionManager::registerAction(&m_nextAction, BOOKMARKS_NEXT_ACTION, editorManagerContext); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Meta+.") - : Tr::tr("Ctrl+."))); - mbm->addAction(cmd); - - mbm->addSeparator(); - - // Previous Doc - cmd = ActionManager::registerAction(&m_docPrevAction, "Bookmarks.PreviousDocument", - editorManagerContext); - mbm->addAction(cmd); - - // Next Doc - cmd = ActionManager::registerAction(&m_docNextAction, "Bookmarks.NextDocument", - editorManagerContext); - mbm->addAction(cmd); - - connect(&m_toggleAction, &QAction::triggered, this, [this] { + m_toggleAction.setId("Bookmarks.Toggle"); + m_toggleAction.setContext(editorManagerContext); + m_toggleAction.setText(Tr::tr("Toggle Bookmark")); + m_toggleAction.setDefaultKeySequence(Tr::tr("Meta+M"), Tr::tr("Ctrl+M")); + m_toggleAction.setTouchBarIcon(Icons::MACOS_TOUCHBAR_BOOKMARK.icon()); + m_toggleAction.setContainer(bookmarkMenuId); + m_toggleAction.setOnTriggered(this, [this] { IEditor *editor = EditorManager::currentEditor(); auto widget = TextEditorWidget::fromEditor(editor); if (widget && editor && !editor->document()->isTemporary()) m_bookmarkManager.toggleBookmark(editor->document()->filePath(), editor->currentLine()); }); - connect(&m_editAction, &QAction::triggered, this, [this] { + m_editAction.setId("Bookmarks.Edit"); + m_editAction.setContext(editorManagerContext); + m_editAction.setText(Tr::tr("Edit Bookmark")); + m_editAction.setDefaultKeySequence(Tr::tr("Meta+Shift+M"), Tr::tr("Ctrl+Shift+M")); + m_editAction.setContainer(bookmarkMenuId); + m_editAction.setOnTriggered(this, [this] { IEditor *editor = EditorManager::currentEditor(); auto widget = TextEditorWidget::fromEditor(editor); if (widget && editor && !editor->document()->isTemporary()) { @@ -184,12 +152,39 @@ TextEditorPluginPrivate::TextEditorPluginPrivate() } }); - connect(&m_prevAction, &QAction::triggered, &m_bookmarkManager, &BookmarkManager::prev); - connect(&m_nextAction, &QAction::triggered, &m_bookmarkManager, &BookmarkManager::next); - connect(&m_docPrevAction, &QAction::triggered, - &m_bookmarkManager, &BookmarkManager::prevInDocument); - connect(&m_docNextAction, &QAction::triggered, - &m_bookmarkManager, &BookmarkManager::nextInDocument); + m_bookmarkMenu.addSeparator(); + + m_prevAction.setId(BOOKMARKS_PREV_ACTION); + m_prevAction.setContext(editorManagerContext); + m_prevAction.setText(Tr::tr("Previous Bookmark")); + m_prevAction.setDefaultKeySequence(Tr::tr("Meta+,"), Tr::tr("Ctrl+,")); + m_prevAction.setContainer(bookmarkMenuId); + m_prevAction.setIcon(Icons::PREV_TOOLBAR.icon()); + m_prevAction.setIconVisibleInMenu(false); + m_prevAction.setOnTriggered(this, [this] { m_bookmarkManager.prev(); }); + + m_nextAction.setId(BOOKMARKS_NEXT_ACTION); + m_nextAction.setContext(editorManagerContext); + m_nextAction.setText(Tr::tr("Next Bookmark")); + m_nextAction.setIcon(Icons::NEXT_TOOLBAR.icon()); + m_nextAction.setIconVisibleInMenu(false); + m_nextAction.setDefaultKeySequence(Tr::tr("Meta+."), Tr::tr("Ctrl+.")); + m_nextAction.setContainer(bookmarkMenuId); + m_nextAction.setOnTriggered(this, [this] { m_bookmarkManager.next(); }); + + m_bookmarkMenu.addSeparator(); + + m_docPrevAction.setId("Bookmarks.PreviousDocument"); + m_docPrevAction.setContext(editorManagerContext); + m_docPrevAction.setText(Tr::tr("Previous Bookmark in Document")); + m_docPrevAction.setContainer(bookmarkMenuId); + m_docPrevAction.setOnTriggered(this, [this] { m_bookmarkManager.prevInDocument(); }); + + m_docNextAction.setId("Bookmarks.NextDocument"); + m_docNextAction.setContext(Core::Constants::C_EDITORMANAGER); + m_docNextAction.setText(Tr::tr("Next Bookmark in Document")); + m_docNextAction.setContainer(bookmarkMenuId); + m_docNextAction.setOnTriggered(this, [this] { m_bookmarkManager.nextInDocument(); }); connect(&m_editBookmarkAction, &QAction::triggered, this, [this] { m_bookmarkManager.editByFileAndLine(m_marginActionFileName, m_marginActionLineNumber); @@ -203,11 +198,14 @@ TextEditorPluginPrivate::TextEditorPluginPrivate() m_bookmarkManager.toggleBookmark(m_marginActionFileName, m_marginActionLineNumber); }); + ActionContainer *touchBar = ActionManager::actionContainer(Core::Constants::TOUCH_BAR); + touchBar->addAction(m_toggleAction.command(), Core::Constants::G_TOUCHBAR_EDITOR); + // EditorManager connect(EditorManager::instance(), &EditorManager::editorAboutToClose, - this, &TextEditorPluginPrivate::editorAboutToClose); + this, &TextEditorPluginPrivate::editorAboutToClose); connect(EditorManager::instance(), &EditorManager::editorOpened, - this, &TextEditorPluginPrivate::editorOpened); + this, &TextEditorPluginPrivate::editorOpened); } void TextEditorPluginPrivate::updateActions(bool enableToggle, int state) From fd1956a91c7ad829b8fbac65bfc43a8310933187 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Wed, 8 Nov 2023 17:24:45 +0100 Subject: [PATCH 0134/1546] QmakeProjectManager: Remove unused functions These project wizard related functions are unused remnants from when a couple of wizards were still implemented in C++. The wizards have since been reimplemented as .json wizards. Change-Id: I4cef7ef26cb66e86ef968645c68f3234d4dc15b6 Reviewed-by: Christian Kandeler Reviewed-by: Eike Ziller --- .../wizards/qtprojectparameters.cpp | 78 ------------------- .../wizards/qtprojectparameters.h | 4 - 2 files changed, 82 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/wizards/qtprojectparameters.cpp b/src/plugins/qmakeprojectmanager/wizards/qtprojectparameters.cpp index 1612e36753b..1e2487223f3 100644 --- a/src/plugins/qmakeprojectmanager/wizards/qtprojectparameters.cpp +++ b/src/plugins/qmakeprojectmanager/wizards/qtprojectparameters.cpp @@ -39,79 +39,6 @@ static inline void writeQtModulesList(QTextStream &str, } } -void QtProjectParameters::writeProFile(QTextStream &str) const -{ - QStringList allSelectedModules = selectedModules; - // Handling of widgets module. - const bool addWidgetsModule = - (flags & WidgetsRequiredFlag) && qtVersionSupport != SupportQt4Only - && !allSelectedModules.contains(QLatin1String("widgets")); - - const bool addConditionalPrintSupport = qtVersionSupport == SupportQt4And5 - && allSelectedModules.removeAll(QLatin1String("printsupport")) > 0; - - if (addWidgetsModule && qtVersionSupport == SupportQt5Only) - allSelectedModules.append(QLatin1String("widgets")); - writeQtModulesList(str, allSelectedModules, '+'); - writeQtModulesList(str, deselectedModules, '-'); - if (addWidgetsModule && qtVersionSupport == SupportQt4And5) - str << "greaterThan(QT_MAJOR_VERSION, 4): QT += widgets\n\n"; - if (addConditionalPrintSupport) - str << "greaterThan(QT_MAJOR_VERSION, 4): QT += printsupport\n\n"; - - const QString &effectiveTarget = target.isEmpty() ? fileName : target; - if (!effectiveTarget.isEmpty()) - str << "TARGET = " << effectiveTarget << '\n'; - switch (type) { - case ConsoleApp: - // Mac: Command line apps should not be bundles - str << "CONFIG += console\n" - "CONFIG -= app_bundle\n\n" - "TEMPLATE = app\n"; - break; - case GuiApp: - str << "TEMPLATE = app\n"; - break; - case StaticLibrary: - str << "TEMPLATE = lib\nCONFIG += staticlib\n"; - break; - case SharedLibrary: - str << "TEMPLATE = lib\n\nDEFINES += " << libraryMacro(fileName) << '\n'; - break; - case QtPlugin: - str << "TEMPLATE = lib\nCONFIG += plugin\n"; - break; - default: - break; - } - - if (!targetDirectory.isEmpty() && !targetDirectory.contains("QT_INSTALL_")) - str << "\nDESTDIR = " << targetDirectory << '\n'; - - if (qtVersionSupport != SupportQt4Only) { - str << "\n" - "# You can make your code fail to compile if you use deprecated APIs.\n" - "# In order to do so, uncomment the following line.\n" - "#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0\n"; - } -} - -void QtProjectParameters::writeProFileHeader(QTextStream &str) -{ - const QChar hash = QLatin1Char ('#'); - const QChar nl = QLatin1Char('\n'); - const QChar blank = QLatin1Char(' '); - // Format as '#-------\n#
\n#---------' - QString header = QLatin1String(" Project created by "); - header += QCoreApplication::applicationName(); - header += blank; - header += QDateTime::currentDateTime().toString(Qt::ISODate); - const QString line = QString(header.size(), QLatin1Char('-')); - str << hash << line << nl << hash << nl << hash << header << nl - << hash < Date: Wed, 8 Nov 2023 15:23:52 +0100 Subject: [PATCH 0135/1546] GenericProject: Use new Core::Action Change-Id: I694b29565089baa14b316bca07a8ac29747ac32a Reviewed-by: Eike Ziller --- .../genericprojectplugin.cpp | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.cpp b/src/plugins/genericprojectmanager/genericprojectplugin.cpp index 8999016c2aa..6d3ab2eaf5c 100644 --- a/src/plugins/genericprojectmanager/genericprojectplugin.cpp +++ b/src/plugins/genericprojectmanager/genericprojectplugin.cpp @@ -13,8 +13,6 @@ #include #include -#include -#include #include #include @@ -23,11 +21,8 @@ #include #include -#include #include -#include - using namespace Core; using namespace ProjectExplorer; using namespace Utils; @@ -44,8 +39,8 @@ public: ProjectFilesFactory projectFilesFactory; GenericMakeStepFactory makeStepFactory; GenericBuildConfigurationFactory buildConfigFactory; - - QAction editFilesAction{Tr::tr("Edit Files..."), nullptr}; + Action editAction; + Action removeDirAction; }; GenericProjectPlugin::~GenericProjectPlugin() @@ -64,23 +59,21 @@ GenericProjectPluginPrivate::GenericProjectPluginPrivate() IWizardFactory::registerFactoryCreator([] { return new GenericProjectWizard; }); - ActionContainer *mproject = ActionManager::actionContainer(PEC::M_PROJECTCONTEXT); - - Command *command = ActionManager::registerAction(&editFilesAction, - "GenericProjectManager.EditFiles", Context(Constants::GENERICPROJECT_ID)); - command->setAttribute(Command::CA_Hide); - mproject->addAction(command, PEC::G_PROJECT_FILES); - - connect(&editFilesAction, &QAction::triggered, this, [] { + editAction.setId("GenericProjectManager.EditFiles"); + editAction.setContext(Constants::GENERICPROJECT_ID); + editAction.setText(Tr::tr("Edit Files...")); + editAction.setCommandAttribute(Command::CA_Hide); + editAction.setContainer(PEC::M_PROJECTCONTEXT, PEC::G_PROJECT_FILES); + editAction.setOnTriggered([] { if (auto genericProject = qobject_cast(ProjectTree::currentProject())) genericProject->editFilesTriggered(); }); - const auto removeDirAction = new QAction(Tr::tr("Remove Directory"), this); - Command * const cmd = ActionManager::registerAction(removeDirAction, "GenericProject.RemoveDir", - Context(PEC::C_PROJECT_TREE)); - ActionManager::actionContainer(PEC::M_FOLDERCONTEXT)->addAction(cmd, PEC::G_FOLDER_OTHER); - connect(removeDirAction, &QAction::triggered, this, [] { + removeDirAction.setId("GenericProject.RemoveDir"); + removeDirAction.setContext(PEC::C_PROJECT_TREE); + removeDirAction.setText(Tr::tr("Remove Directory")); + removeDirAction.setContainer(PEC::M_FOLDERCONTEXT, PEC::G_FOLDER_OTHER); + removeDirAction.setOnTriggered([] { const auto folderNode = ProjectTree::currentNode()->asFolderNode(); QTC_ASSERT(folderNode, return); const auto project = qobject_cast(folderNode->getProject()); From 09e495f01a6ef1592b51dde08f459fadafaa9e05 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 7 Nov 2023 11:05:48 +0100 Subject: [PATCH 0136/1546] ClangCodeModel: Fall back to built-in code model when following symbols In normal interactive mode, users likely want fuzzy look-up, e.g. to a non-matching overload if no exact match is present. Fixes: QTCREATORBUG-29814 Change-Id: I55ca32c001e619d374cc015a7dd2f1564ed2a2c9 Reviewed-by: Christian Stenger Reviewed-by: David Schulz --- src/plugins/clangcodemodel/clangdfollowsymbol.cpp | 3 +-- .../clangcodemodel/clangmodelmanagersupport.cpp | 15 +++++++++++++-- .../clangcodemodel/clangmodelmanagersupport.h | 5 +++-- .../cppeditor/cppbuiltinmodelmanagersupport.cpp | 5 +++++ .../cppeditor/cppbuiltinmodelmanagersupport.h | 2 +- src/plugins/cppeditor/cppeditorwidget.cpp | 5 +++-- src/plugins/cppeditor/cppmodelmanager.cpp | 7 ++++--- src/plugins/cppeditor/cppmodelmanager.h | 4 +++- src/plugins/cppeditor/cppmodelmanagersupport.h | 3 ++- src/plugins/cppeditor/cppquickfixes.cpp | 4 +++- src/plugins/cppeditor/cpptoolsreuse.h | 2 ++ 11 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/plugins/clangcodemodel/clangdfollowsymbol.cpp b/src/plugins/clangcodemodel/clangdfollowsymbol.cpp index 8be15c7327d..aa3f2e69abe 100644 --- a/src/plugins/clangcodemodel/clangdfollowsymbol.cpp +++ b/src/plugins/clangcodemodel/clangdfollowsymbol.cpp @@ -199,8 +199,7 @@ void ClangdFollowSymbol::emitDone(const Link &link) return; d->done = true; - if (link.hasValidTarget()) - d->callback(link); + d->callback(link); emit done(); } diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index caefe586308..6ffd946bafe 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -299,17 +300,27 @@ ClangModelManagerSupport::~ClangModelManagerSupport() void ClangModelManagerSupport::followSymbol(const CursorInEditor &data, const LinkHandler &processLinkCallback, + FollowSymbolMode mode, bool resolveTarget, bool inNextSplit) { if (ClangdClient * const client = clientForFile(data.filePath()); client && client->isFullyIndexed()) { + LinkHandler extendedCallback = [editor = QPointer(data.editorWidget()), data, + processLinkCallback, mode, resolveTarget, inNextSplit] + (const Link &link) { + if (link.hasValidTarget() || mode == FollowSymbolMode::Exact || !editor) + return processLinkCallback(link); + CppModelManager::followSymbol(data, processLinkCallback, resolveTarget, inNextSplit, + mode, CppModelManager::Backend::Builtin); + + }; client->followSymbol(data.textDocument(), data.cursor(), data.editorWidget(), - processLinkCallback, resolveTarget, FollowTo::SymbolDef, inNextSplit); + extendedCallback, resolveTarget, FollowTo::SymbolDef, inNextSplit); return; } CppModelManager::followSymbol(data, processLinkCallback, resolveTarget, inNextSplit, - CppModelManager::Backend::Builtin); + mode, CppModelManager::Backend::Builtin); } void ClangModelManagerSupport::followSymbolToType(const CursorInEditor &data, diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.h b/src/plugins/clangcodemodel/clangmodelmanagersupport.h index 595bfdd7950..a598bea8bbd 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.h +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.h @@ -52,8 +52,9 @@ public: private: void followSymbol(const CppEditor::CursorInEditor &data, - const Utils::LinkHandler &processLinkCallback, bool resolveTarget, - bool inNextSplit) override; + const Utils::LinkHandler &processLinkCallback, + CppEditor::FollowSymbolMode mode, + bool resolveTarget, bool inNextSplit) override; void followSymbolToType(const CppEditor::CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, bool inNextSplit) override; diff --git a/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.cpp b/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.cpp index 01a208f7032..4d20932e3c0 100644 --- a/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.cpp +++ b/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.cpp @@ -101,8 +101,13 @@ TextEditor::BaseHoverHandler *BuiltinModelManagerSupport::createHoverHandler() void BuiltinModelManagerSupport::followSymbol(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, + FollowSymbolMode mode, bool resolveTarget, bool inNextSplit) { + // findMatchingDefinition() has an "strict" parameter, but it doesn't seem worth to + // pass the mode down all the way. In practice, we are always fuzzy. + Q_UNUSED(mode) + SymbolFinder finder; m_followSymbol->findLink(data, processLinkCallback, resolveTarget, CppModelManager::snapshot(), diff --git a/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.h b/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.h index 04de866d5ce..8ecbe856b65 100644 --- a/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.h +++ b/src/plugins/cppeditor/cppbuiltinmodelmanagersupport.h @@ -29,7 +29,7 @@ public: private: void followSymbol(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, - bool resolveTarget, bool inNextSplit) override; + FollowSymbolMode mode, bool resolveTarget, bool inNextSplit) override; void followSymbolToType(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, bool inNextSplit) override; diff --git a/src/plugins/cppeditor/cppeditorwidget.cpp b/src/plugins/cppeditor/cppeditorwidget.cpp index 9666dc48a7d..d215d2ba4e6 100644 --- a/src/plugins/cppeditor/cppeditorwidget.cpp +++ b/src/plugins/cppeditor/cppeditorwidget.cpp @@ -625,7 +625,7 @@ void CppEditorWidget::renameUsages(const QString &replacement, QTextCursor curso }; CppModelManager::followSymbol( CursorInEditor{cursor, textDocument()->filePath(), this, textDocument()}, - continuation, true, false); + continuation, true, false, FollowSymbolMode::Exact); } void CppEditorWidget::renameUsages(const Utils::FilePath &filePath, const QString &replacement, @@ -986,7 +986,8 @@ void CppEditorWidget::findLinkAt(const QTextCursor &cursor, CppModelManager::followSymbol(CursorInEditor{cursor, filePath, this, textDocument()}, callbackWrapper, resolveTarget, - inNextSplit); + inNextSplit, + FollowSymbolMode::Fuzzy); } void CppEditorWidget::findTypeAt(const QTextCursor &cursor, diff --git a/src/plugins/cppeditor/cppmodelmanager.cpp b/src/plugins/cppeditor/cppmodelmanager.cpp index 52f0ea89845..7ff5a2522f4 100644 --- a/src/plugins/cppeditor/cppmodelmanager.cpp +++ b/src/plugins/cppeditor/cppmodelmanager.cpp @@ -2065,10 +2065,11 @@ TextEditor::BaseHoverHandler *CppModelManager::createHoverHandler() void CppModelManager::followSymbol(const CursorInEditor &data, const LinkHandler &processLinkCallback, - bool resolveTarget, bool inNextSplit, Backend backend) + bool resolveTarget, bool inNextSplit, + FollowSymbolMode mode, Backend backend) { - modelManagerSupport(backend)->followSymbol(data, processLinkCallback, - resolveTarget, inNextSplit); + modelManagerSupport(backend)->followSymbol(data, processLinkCallback, mode, + resolveTarget, inNextSplit); } void CppModelManager::followSymbolToType(const CursorInEditor &data, diff --git a/src/plugins/cppeditor/cppmodelmanager.h b/src/plugins/cppeditor/cppmodelmanager.h index bdda63ee550..8867d5cd0f2 100644 --- a/src/plugins/cppeditor/cppmodelmanager.h +++ b/src/plugins/cppeditor/cppmodelmanager.h @@ -5,6 +5,7 @@ #include "cppeditor_global.h" +#include "cpptoolsreuse.h" #include "cursorineditor.h" #include "projectinfo.h" #include "projectpart.h" @@ -174,7 +175,8 @@ public: enum class Backend { Builtin, Best }; static void followSymbol(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, - bool resolveTarget, bool inNextSplit, Backend backend = Backend::Best); + bool resolveTarget, bool inNextSplit, + FollowSymbolMode mode, Backend backend = Backend::Best); static void followSymbolToType(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, bool inNextSplit, Backend backend = Backend::Best); diff --git a/src/plugins/cppeditor/cppmodelmanagersupport.h b/src/plugins/cppeditor/cppmodelmanagersupport.h index 392712d86ae..a43a1e0b02b 100644 --- a/src/plugins/cppeditor/cppmodelmanagersupport.h +++ b/src/plugins/cppeditor/cppmodelmanagersupport.h @@ -4,6 +4,7 @@ #pragma once #include "cppeditor_global.h" +#include "cpptoolsreuse.h" #include "cursorineditor.h" #include @@ -12,7 +13,6 @@ #include #include -#include namespace Core { class SearchResult; } namespace TextEditor { @@ -41,6 +41,7 @@ public: virtual void followSymbol(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, + FollowSymbolMode mode, bool resolveTarget, bool inNextSplit) = 0; virtual void followSymbolToType(const CursorInEditor &data, const Utils::LinkHandler &processLinkCallback, diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index d3d244b81c0..088449002ca 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -3017,6 +3017,7 @@ void AddDeclarationForUndeclaredIdentifier::match(const CppQuickFixInterface &in collectOperations(interface, result); }; CppModelManager::followSymbol(cursorInEditor, followSymbolFallback, false, false, + FollowSymbolMode::Exact, CppModelManager::Backend::Builtin); } @@ -9649,7 +9650,8 @@ private: (const Link &link) { moveComments(link, symbolLoc, comments); }; - CppModelManager::followSymbol(cursorInEditor, callback, true, false); + CppModelManager::followSymbol(cursorInEditor, callback, true, false, + FollowSymbolMode::Exact); } static void moveComments(const Link &targetLoc, const Link &symbolLoc, diff --git a/src/plugins/cppeditor/cpptoolsreuse.h b/src/plugins/cppeditor/cpptoolsreuse.h index d40e00d994c..50078bdd791 100644 --- a/src/plugins/cppeditor/cpptoolsreuse.h +++ b/src/plugins/cppeditor/cpptoolsreuse.h @@ -33,6 +33,8 @@ class CppRefactoringFile; class ProjectInfo; class CppCompletionAssistProcessor; +enum class FollowSymbolMode { Exact, Fuzzy }; + void CPPEDITOR_EXPORT moveCursorToEndOfIdentifier(QTextCursor *tc); void CPPEDITOR_EXPORT moveCursorToStartOfIdentifier(QTextCursor *tc); From 2f7bfd3ef897a2ce9f1f9863f072879bf169671e Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 9 Nov 2023 10:26:06 +0100 Subject: [PATCH 0137/1546] TextEditorActionHandler: Reduce noise By using namespace Core Change-Id: I97f4f6c42d5e0e9487b174b6837dc4cbb3452f2b Reviewed-by: David Schulz --- .../texteditor/texteditoractionhandler.cpp | 80 +++++++++++-------- 1 file changed, 46 insertions(+), 34 deletions(-) diff --git a/src/plugins/texteditor/texteditoractionhandler.cpp b/src/plugins/texteditor/texteditoractionhandler.cpp index f16c94249bb..cf94a3f03e3 100644 --- a/src/plugins/texteditor/texteditoractionhandler.cpp +++ b/src/plugins/texteditor/texteditoractionhandler.cpp @@ -29,6 +29,8 @@ #include +using namespace Core; + namespace TextEditor { namespace Internal { @@ -37,13 +39,17 @@ class TextEditorActionHandlerPrivate : public QObject public: TextEditorActionHandlerPrivate(Utils::Id editorId, Utils::Id contextId, uint optionalActions); - QAction *registerActionHelper(Utils::Id id, bool scriptable, const QString &title, - const QKeySequence &keySequence, Utils::Id menueGroup, - Core::ActionContainer *container, - std::function slot) + QAction *registerActionHelper(Utils::Id id, + bool scriptable, + const QString &title, + const QKeySequence &keySequence, + Utils::Id menueGroup, + ActionContainer *container, + std::function slot) { auto result = new QAction(title, this); - Core::Command *command = Core::ActionManager::registerAction(result, id, Core::Context(m_contextId), scriptable); + Command *command + = ActionManager::registerAction(result, id, Context(m_contextId), scriptable); if (!keySequence.isEmpty()) command->setDefaultKeySequence(keySequence); @@ -60,7 +66,7 @@ public: const QString &title = QString(), const QKeySequence &keySequence = QKeySequence(), Utils::Id menueGroup = Utils::Id(), - Core::ActionContainer *container = nullptr) + ActionContainer *container = nullptr) { return registerActionHelper(id, scriptable, @@ -77,24 +83,24 @@ public: } QAction *registerBoolAction(Utils::Id id, - std::function slot, - bool scriptable = false, - const QString &title = QString(), - const QKeySequence &keySequence = QKeySequence(), - Utils::Id menueGroup = Utils::Id(), - Core::ActionContainer *container = nullptr) + std::function slot, + bool scriptable = false, + const QString &title = QString(), + const QKeySequence &keySequence = QKeySequence(), + Utils::Id menueGroup = Utils::Id(), + ActionContainer *container = nullptr) { return registerActionHelper(id, scriptable, title, keySequence, menueGroup, container, [this, slot](bool on) { if (m_currentEditorWidget) slot(m_currentEditorWidget, on); }); } QAction *registerIntAction(Utils::Id id, - std::function slot, - bool scriptable = false, - const QString &title = QString(), - const QKeySequence &keySequence = QKeySequence(), - Utils::Id menueGroup = Utils::Id(), - Core::ActionContainer *container = nullptr) + std::function slot, + bool scriptable = false, + const QString &title = QString(), + const QKeySequence &keySequence = QKeySequence(), + Utils::Id menueGroup = Utils::Id(), + ActionContainer *container = nullptr) { return registerActionHelper(id, scriptable, title, keySequence, menueGroup, container, [this, slot](bool on) { if (m_currentEditorWidget) slot(m_currentEditorWidget, on); }); @@ -108,7 +114,7 @@ public: void updateUndoAction(bool on); void updateCopyAction(bool on); - void updateCurrentEditor(Core::IEditor *editor); + void updateCurrentEditor(IEditor *editor); void setCanUndoCallback(const TextEditorActionHandler::Predicate &callback); void setCanRedoCallback(const TextEditorActionHandler::Predicate &callback); @@ -139,7 +145,7 @@ public: uint m_optionalActions = TextEditorActionHandler::None; QPointer m_currentEditorWidget; - QPointer m_currentEditor; + QPointer m_currentEditor; Utils::Id m_editorId; Utils::Id m_contextId; @@ -156,8 +162,10 @@ TextEditorActionHandlerPrivate::TextEditorActionHandlerPrivate , m_contextId(contextId) { createActions(); - connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged, - this, &TextEditorActionHandlerPrivate::updateCurrentEditor); + connect(EditorManager::instance(), + &EditorManager::currentEditorChanged, + this, + &TextEditorActionHandlerPrivate::updateCurrentEditor); connect(TextEditorSettings::instance(), &TextEditorSettings::fontSettingsChanged, this, &TextEditorActionHandlerPrivate::updateActions); } @@ -179,11 +187,12 @@ void TextEditorActionHandlerPrivate::createActions() [] (TextEditorWidget *w) { w->paste(); }, true); registerAction(SELECTALL, [] (TextEditorWidget *w) { w->selectAll(); }, true); - registerAction(GOTO, [] (TextEditorWidget *) { - Core::LocatorManager::showFilter(TextEditorPlugin::lineNumberFilter()); - }); - m_modifyingActions << registerAction(PRINT, - [] (TextEditorWidget *widget) { widget->print(Core::ICore::printer()); }); + registerAction(GOTO, [](TextEditorWidget *) { + LocatorManager::showFilter(TextEditorPlugin::lineNumberFilter()); + }); + m_modifyingActions << registerAction(PRINT, [](TextEditorWidget *widget) { + widget->print(ICore::printer()); + }); m_modifyingActions << registerAction(DELETE_LINE, [] (TextEditorWidget *w) { w->deleteLine(); }, true, Tr::tr("Delete &Line")); m_modifyingActions << registerAction(DELETE_END_OF_LINE, @@ -192,9 +201,12 @@ void TextEditorActionHandlerPrivate::createActions() [] (TextEditorWidget *w) { w->deleteEndOfWord(); }, true, Tr::tr("Delete Word from Cursor On")); m_modifyingActions << registerAction(DELETE_END_OF_WORD_CAMEL_CASE, [] (TextEditorWidget *w) { w->deleteEndOfWordCamelCase(); }, true, Tr::tr("Delete Word Camel Case from Cursor On")); - m_modifyingActions << registerAction(DELETE_START_OF_LINE, - [] (TextEditorWidget *w) { w->deleteStartOfLine(); }, true, Tr::tr("Delete Line up to Cursor"), - Core::useMacShortcuts ? QKeySequence(Tr::tr("Ctrl+Backspace")) : QKeySequence()); + m_modifyingActions << registerAction( + DELETE_START_OF_LINE, + [](TextEditorWidget *w) { w->deleteStartOfLine(); }, + true, + Tr::tr("Delete Line up to Cursor"), + Core::useMacShortcuts ? QKeySequence(Tr::tr("Ctrl+Backspace")) : QKeySequence()); m_modifyingActions << registerAction(DELETE_START_OF_WORD, [] (TextEditorWidget *w) { w->deleteStartOfWord(); }, true, Tr::tr("Delete Word up to Cursor")); m_modifyingActions << registerAction(DELETE_START_OF_WORD_CAMEL_CASE, @@ -273,7 +285,7 @@ void TextEditorActionHandlerPrivate::createActions() QKeySequence(Tr::tr("Ctrl+Down"))); // register "Edit" Menu Actions - Core::ActionContainer *editMenu = Core::ActionManager::actionContainer(M_EDIT); + ActionContainer *editMenu = ActionManager::actionContainer(M_EDIT); registerAction(SELECT_ENCODING, [] (TextEditorWidget *w) { w->selectEncoding(); }, false, Tr::tr("Select Encoding..."), QKeySequence(), G_EDIT_OTHER, editMenu); @@ -285,7 +297,7 @@ void TextEditorActionHandlerPrivate::createActions() QKeySequence(Core::useMacShortcuts ? Tr::tr("Ctrl+Alt+Shift+V") : QString()), G_EDIT_COPYPASTE, editMenu); // register "Edit -> Advanced" Menu Actions - Core::ActionContainer *advancedEditMenu = Core::ActionManager::actionContainer(M_EDIT_ADVANCED); + ActionContainer *advancedEditMenu = ActionManager::actionContainer(M_EDIT_ADVANCED); m_autoIndentAction = registerAction(AUTO_INDENT_SELECTION, [] (TextEditorWidget *w) { w->autoIndent(); }, true, Tr::tr("Auto-&indent Selection"), QKeySequence(Tr::tr("Ctrl+I")), @@ -567,7 +579,7 @@ void TextEditorActionHandlerPrivate::updateCopyAction(bool hasCopyableText) m_copyHtmlAction->setEnabled(hasCopyableText); } -void TextEditorActionHandlerPrivate::updateCurrentEditor(Core::IEditor *editor) +void TextEditorActionHandlerPrivate::updateCurrentEditor(IEditor *editor) { if (m_currentEditorWidget) m_currentEditorWidget->disconnect(this); @@ -619,7 +631,7 @@ TextEditorActionHandler::~TextEditorActionHandler() void TextEditorActionHandler::updateCurrentEditor() { - d->updateCurrentEditor(Core::EditorManager::currentEditor()); + d->updateCurrentEditor(EditorManager::currentEditor()); } void TextEditorActionHandler::updateActions() From 08546615f223cc1008c244ea37672986ca0e7aa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Olivier=20De=20Canni=C3=A8re?= Date: Thu, 9 Nov 2023 10:37:34 +0100 Subject: [PATCH 0138/1546] Qml Debugger: Do not focus the current frame when adding a watch The other debuggers do not cause the view to jump to the current frame when adding a watch. Make the Qml debugger also not do this. This is done in a slightly hacky way by preventing the gotoLocation of the next handleFrame call to be executed. Ideally, the logic to retrieve the value of locals should be separated from the logic to jump to a specific frame. Right now the jump is implicit when updating the locals. Fixes: QTCREATORBUG-29329 Change-Id: I4b8f5c99ae41c92c3394f86da481303d4765f897 Reviewed-by: hjk Reviewed-by: Fabian Kosmale --- src/plugins/debugger/debuggerengine.cpp | 1 + src/plugins/debugger/debuggerengine.h | 1 + src/plugins/debugger/qml/qmlengine.cpp | 16 ++++++++++------ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 04befbf071c..72bdb341a3e 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -2411,6 +2411,7 @@ void DebuggerEngine::updateWatchData(const QString &iname) // e.g. when changing the expression in a watcher. UpdateParameters params; params.partialVariable = iname; + params.qmlFocusOnFrame = false; doUpdateLocals(params); } diff --git a/src/plugins/debugger/debuggerengine.h b/src/plugins/debugger/debuggerengine.h index 354ebb95fe0..aed61bbc2e4 100644 --- a/src/plugins/debugger/debuggerengine.h +++ b/src/plugins/debugger/debuggerengine.h @@ -214,6 +214,7 @@ public: } QString partialVariable; + bool qmlFocusOnFrame = true; // QTCREATORBUG-29874 }; class Location diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index d418d9cb4dc..3f18b5f5fc8 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -141,7 +141,7 @@ public: void evaluate(const QString expr, qint64 context, const QmlCallback &cb); void lookup(const LookupItems &items); void backtrace(); - void updateLocals(); + void updateLocals(bool focusOnFrame = true); void scope(int number, int frameNumber = -1); void scripts(int types = 4, const QList ids = QList(), bool includeSource = false, const QVariant filter = QVariant()); @@ -216,6 +216,8 @@ public: FileInProjectFinder fileFinder; + bool skipFocusOnNextHandleFrame = false; + private: ConsoleItem *constructLogItemTree(const QmlV8ObjectData &objectData, QList &seenHandles); void constructChildLogItems(ConsoleItem *item, const QmlV8ObjectData &objectData, @@ -791,7 +793,7 @@ void QmlEngine::assignValueInDebugger(WatchItem *item, StackHandler *handler = stackHandler(); QString exp = QString("%1 = %2;").arg(expression).arg(value.toString()); if (handler->isContentsValid() && handler->currentFrame().isUsable()) { - d->evaluate(exp, -1, [this](const QVariantMap &) { d->updateLocals(); }); + d->evaluate(exp, -1, [this](const QVariantMap &) { d->updateLocals(false); }); } else { showMessage(Tr::tr("Cannot evaluate %1 in current stack frame.") .arg(expression), ConsoleOutput); @@ -941,8 +943,7 @@ void QmlEngine::quitDebugger() void QmlEngine::doUpdateLocals(const UpdateParameters ¶ms) { - Q_UNUSED(params) - d->updateLocals(); + d->updateLocals(params.qmlFocusOnFrame); } Context QmlEngine::languageContext() const @@ -1292,13 +1293,14 @@ void QmlEnginePrivate::backtrace() runCommand(cmd, CB(handleBacktrace)); } -void QmlEnginePrivate::updateLocals() +void QmlEnginePrivate::updateLocals(bool focusOnFrame) { // { "seq" : , // "type" : "request", // "command" : "frame", // "arguments" : { "number" : } // } + skipFocusOnNextHandleFrame = focusOnFrame; DebuggerCommand cmd(FRAME); cmd.arg(NUMBER, stackIndexLookup.value(engine->stackHandler()->currentIndex())); @@ -2136,7 +2138,9 @@ void QmlEnginePrivate::handleFrame(const QVariantMap &response) currentFrameScopes.append(scopeIndex); this->scope(scopeIndex); } - engine->gotoLocation(stackHandler->currentFrame()); + + if (skipFocusOnNextHandleFrame) + engine->gotoLocation(stackHandler->currentFrame()); // Send watchers list if (stackHandler->isContentsValid() && stackHandler->currentFrame().isUsable()) { From c26521aeb33ab7a009cff43d5d2c3737f4257a2e Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 9 Nov 2023 12:56:19 +0100 Subject: [PATCH 0139/1546] Core: Fix Action setters In some cases the data needs to be forwarded to the command's action. Change-Id: I3ae066cbac393d78808d697beb3df29cbdee3315 Reviewed-by: Eike Ziller --- .../actionmanager/actionmanager.cpp | 55 ++++++++++++++++++- .../coreplugin/actionmanager/actionmanager.h | 6 ++ 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index f791e9e22e2..0462c4de658 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -78,14 +78,13 @@ public: { if (!command) { QTC_ASSERT(actionId.isValid(), return); - QTC_ASSERT(!context.isEmpty(), return); command = ActionManager::registerAction(&action, actionId, context); } } QAction action; Id actionId; - Context context; + Context context{Constants::C_GLOBAL}; Command *command = nullptr; }; @@ -102,6 +101,8 @@ Action::~Action() void Action::setText(const QString &text) { d->action.setText(text); + if (d->command) + d->command->action()->setText(text); } void Action::setCommandAttribute(Command::CommandAttribute attr) @@ -126,7 +127,12 @@ void Action::setOnTriggered(const std::function &func) QObject::connect(&d->action, &QAction::triggered, &d->action, func); } -void Action::setOnTriggered(QObject *guard, const std::function &func) +void Action::setOnTriggered(QObject *guard, const std::function &func) +{ + QObject::connect(&d->action, &QAction::triggered, guard, func); +} + +void Action::setOnTriggered(QObject *guard, const std::function &func) { QObject::connect(&d->action, &QAction::triggered, guard, func); } @@ -148,11 +154,15 @@ void Action::setDefaultKeySequence(const QString &mac, const QString &nonMac) void Action::setIcon(const QIcon &icon) { d->action.setIcon(icon); + if (d->command) + d->command->action()->setIcon(icon); } void Action::setIconVisibleInMenu(bool on) { d->action.setIconVisibleInMenu(on); + if (d->command) + d->command->action()->setIconVisibleInMenu(on); } void Action::setTouchBarIcon(const QIcon &icon) @@ -165,6 +175,32 @@ void Action::setTouchBarIcon(const QIcon &icon) void Action::setEnabled(bool on) { d->action.setEnabled(on); + // Explicitly not needed, done via context update: + // if (d->command) + // d->command->action()->... +} + +void Action::setChecked(bool on) +{ + d->action.setChecked(on); + // Explicitly not needed, done via context update: + // if (d->command) + // d->command->action()->... +} + +void Action::setVisible(bool on) +{ + d->action.setVisible(on); + // Explicitly not needed, done via context update: + // if (d->command) + // d->command->action()->.... +} + +void Action::setCheckable(bool on) +{ + d->action.setCheckable(on); + if (d->command) + d->command->action()->setCheckable(on); } Command *Action::command() const @@ -174,6 +210,18 @@ Command *Action::command() const return d->command; } +QAction *Action::commandAction() const +{ + d->ensureCommand(); + QTC_ASSERT(d->command, return nullptr); + return d->command->action(); +} + +QAction *Action::contextAction() const +{ + return &d->action; +} + void Action::setId(Id id) { d->actionId = id; @@ -186,6 +234,7 @@ void Action::setContext(Id id) void Action::setContext(const Context &context) { + QTC_ASSERT(!context.isEmpty(), return); d->context = context; } diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.h b/src/plugins/coreplugin/actionmanager/actionmanager.h index ba2eb4b0e06..7a735737d99 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager.h @@ -45,14 +45,20 @@ public: void setContainer(Utils::Id containerId, Utils::Id groupId = {}); void setOnTriggered(const std::function &func); void setOnTriggered(QObject *guard, const std::function &func); + void setOnTriggered(QObject *guard, const std::function &func); void setDefaultKeySequence(const QKeySequence &seq); void setDefaultKeySequence(const QString &mac, const QString &nonMac); void setIcon(const QIcon &icon); void setIconVisibleInMenu(bool on); void setTouchBarIcon(const QIcon &icon); void setEnabled(bool on); + void setChecked(bool on); + void setVisible(bool on); + void setCheckable(bool on); Command *command() const; + QAction *commandAction() const; + QAction *contextAction() const; private: class ActionPrivate *d = nullptr; From ec99782105d90d054cdbbf27f4005ecd52a368de Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 9 Nov 2023 17:09:54 +0100 Subject: [PATCH 0140/1546] Revert "ProjectExplorer: Use more Ids instead of Kit in KitModel" This reverts commit 05e7308c08301b5bda20334cb1f3f71d2d7c0e85. Currently kit cloning crashes, and the trivial fix loses re-foucssing on the newly cloned kit. Change-Id: Id34d4430f97ab5825d5203096fbd1551464f80cb Reviewed-by: Christian Kandeler --- .../projectexplorer/kitoptionspage.cpp | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/plugins/projectexplorer/kitoptionspage.cpp b/src/plugins/projectexplorer/kitoptionspage.cpp index 87b0465c7ab..e3c84549ca8 100644 --- a/src/plugins/projectexplorer/kitoptionspage.cpp +++ b/src/plugins/projectexplorer/kitoptionspage.cpp @@ -176,6 +176,7 @@ public: Kit *kit(const QModelIndex &); KitNode *kitNode(const QModelIndex &); + QModelIndex indexOf(Kit *k) const; QModelIndex indexOf(Id kitId) const; void setDefaultKit(const QModelIndex &index); @@ -186,7 +187,7 @@ public: void apply(); void markForRemoval(Kit *k); - Id markForAddition(Kit *baseKit); + Kit *markForAddition(Kit *baseKit); void updateVisibility(); @@ -263,6 +264,12 @@ QModelIndex KitModel::indexOf(Id kitId) const return n ? indexForItem(n) : QModelIndex(); } +QModelIndex KitModel::indexOf(Kit *k) const +{ + KitNode *n = findWorkingCopy(k); + return n ? indexForItem(n) : QModelIndex(); +} + void KitModel::setDefaultKit(const QModelIndex &index) { if (KitNode *n = kitNode(index)) @@ -341,7 +348,7 @@ void KitModel::markForRemoval(Kit *k) validateKitNames(); } -Id KitModel::markForAddition(Kit *baseKit) +Kit *KitModel::markForAddition(Kit *baseKit) { const QString newName = newKitName(baseKit ? baseKit->unexpandedDisplayName() : QString()); KitNode *node = createNode(nullptr); @@ -360,7 +367,7 @@ Id KitModel::markForAddition(Kit *baseKit) if (!m_defaultNode) setDefaultNode(node); - return k->id(); + return k; } void KitModel::updateVisibility() @@ -618,9 +625,9 @@ void KitOptionsPageWidget::kitSelectionChanged() void KitOptionsPageWidget::addNewKit() { - Id kitId = m_model->markForAddition(nullptr); + Kit *k = m_model->markForAddition(nullptr); - QModelIndex newIdx = m_sortModel->mapFromSource(m_model->indexOf(kitId)); + QModelIndex newIdx = m_sortModel->mapFromSource(m_model->indexOf(k)); m_selectionModel->select(newIdx, QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent @@ -641,8 +648,8 @@ void KitOptionsPageWidget::cloneKit() if (!current) return; - Id kitId = m_model->markForAddition(current); - QModelIndex newIdx = m_sortModel->mapFromSource(m_model->indexOf(kitId)); + Kit *k = m_model->markForAddition(current); + QModelIndex newIdx = m_sortModel->mapFromSource(m_model->indexOf(k)); m_kitsView->scrollTo(newIdx); m_selectionModel->select(newIdx, QItemSelectionModel::Clear From 9c4ba3ff21fc4691adb0017cd9ec92c567ba7bf8 Mon Sep 17 00:00:00 2001 From: Artem Sokolovskii Date: Wed, 8 Nov 2023 16:51:15 +0100 Subject: [PATCH 0141/1546] QuickFix: Fix add definition for templated function - Fix add definition for templated function in templated class - Fix "inline" placement for templated function Fixes: QTCREATORBUG-29408 Change-Id: I15f7793c9ae1e49d8338c1120135ddd1afbca4ca Reviewed-by: Christian Kandeler --- src/libs/cplusplus/TypePrettyPrinter.cpp | 92 +++++++------- src/plugins/cppeditor/cppquickfix_test.cpp | 137 +++++++++++++++++++++ src/plugins/cppeditor/cppquickfix_test.h | 6 + src/plugins/cppeditor/cppquickfixes.cpp | 27 +++- src/plugins/cppeditor/cppquickfixes.h | 1 + 5 files changed, 215 insertions(+), 48 deletions(-) diff --git a/src/libs/cplusplus/TypePrettyPrinter.cpp b/src/libs/cplusplus/TypePrettyPrinter.cpp index b563c4010e7..7ae1aa3397b 100644 --- a/src/libs/cplusplus/TypePrettyPrinter.cpp +++ b/src/libs/cplusplus/TypePrettyPrinter.cpp @@ -362,34 +362,38 @@ static bool endsWithPtrOrRef(const QString &type) void TypePrettyPrinter::visit(Function *type) { bool showTemplateParameters = _overview->showTemplateParameters; - QStringList nameParts = _name.split("::"); - int i = nameParts.length() - 1; - for (Scope *s = type->enclosingScope(); s && i >= 0; s = s->enclosingScope()) { - if (s->asClass()) - showTemplateParameters = true; - if (Template *templ = s->asTemplate(); templ && showTemplateParameters) { - QString &n = nameParts[i]; - const int paramCount = templ->templateParameterCount(); - if (paramCount > 0) { - n += '<'; - for (int index = 0; index < paramCount; ++index) { - if (index) - n += QLatin1String(", "); - QString arg = _overview->prettyName( - templ->templateParameterAt(index)->name()); - if (arg.isEmpty()) { - arg += 'T'; - arg += QString::number(index + 1); - } - n += arg; + QStringList nameParts = _name.split("::"); + int i = nameParts.length() - 1; + Scope *s = type->enclosingScope(); + if (s && s->asTemplate()) + s = s->enclosingScope(); + + for (; s && i >= 0; s = s->enclosingScope()) { + if (s->asClass()) + showTemplateParameters = true; + + if (Template *templ = s->asTemplate(); templ && showTemplateParameters) { + QString &n = nameParts[i]; + const int paramCount = templ->templateParameterCount(); + if (paramCount > 0) { + n += '<'; + for (int index = 0; index < paramCount; ++index) { + if (index) + n += QLatin1String(", "); + QString arg = _overview->prettyName(templ->templateParameterAt(index)->name()); + if (arg.isEmpty()) { + arg += 'T'; + arg += QString::number(index + 1); } - n += '>'; + n += arg; } + n += '>'; } - if (s->identifier()) - --i; + } else if (s->identifier()) { + --i; } - _name = nameParts.join("::"); + } + _name = nameParts.join("::"); if (_needsParens) { _text.prepend(QLatin1Char('(')); @@ -429,28 +433,30 @@ void TypePrettyPrinter::visit(Function *type) } if (_overview->showEnclosingTemplate) { - if (Template *templ = type->enclosingTemplate()) { - QString templateScope = "template<"; - const int paramCount = templ->templateParameterCount(); - for (int i = 0; i < paramCount; ++i) { - if (Symbol *param = templ->templateParameterAt(i)) { - if (i > 0) - templateScope.append(", "); - if (TypenameArgument *typenameArg = param->asTypenameArgument()) { - templateScope.append(QLatin1String(typenameArg->isClassDeclarator() - ? "class " : "typename ")); - QString name = _overview->prettyName(typenameArg->name()); - if (name.isEmpty()) - name.append('T').append(QString::number(i + 1)); - templateScope.append(name); - } else if (Argument *arg = param->asArgument()) { - templateScope.append(operator()(arg->type(), - _overview->prettyName(arg->name()))); + for (Scope *s = type->enclosingScope(); s && i >= 0; s = s->enclosingScope()) { + if (Template *templ = s->asTemplate()) { + QString templateScope = "template<"; + const int paramCount = templ->templateParameterCount(); + for (int i = 0; i < paramCount; ++i) { + if (Symbol *param = templ->templateParameterAt(i)) { + if (i > 0) + templateScope.append(", "); + if (TypenameArgument *typenameArg = param->asTypenameArgument()) { + templateScope.append(QLatin1String( + typenameArg->isClassDeclarator() ? "class " : "typename ")); + QString name = _overview->prettyName(typenameArg->name()); + if (name.isEmpty()) + name.append('T').append(QString::number(i + 1)); + templateScope.append(name); + } else if (Argument *arg = param->asArgument()) { + templateScope.append(operator()(arg->type(), + _overview->prettyName(arg->name()))); + } } } + if (paramCount > 0) + _text.prepend(templateScope + ">\n"); } - if (paramCount > 0) - _text.prepend(templateScope + ">\n"); } } diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index dc7346c6226..c656d2dd476 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -4999,6 +4999,34 @@ void QuickfixTest::testInsertDefFromDeclTemplateFunction() QuickFixOperationTest(singleDocument(original, expected), &factory); } +void QuickfixTest::testInsertDefFromDeclTemplateClassAndTemplateFunction() +{ + QByteArray original = + "template" + "class Foo\n" + "{\n" + " template\n" + " void fun@c();\n" + "};\n"; + QByteArray expected = + "template" + "class Foo\n" + "{\n" + " template\n" + " void fun@c();\n" + "};\n" + "\n" + "template\n" + "template\n" + "void Foo::func()\n" + "{\n" + "\n" + "}\n"; + + InsertDefFromDecl factory; + QuickFixOperationTest(singleDocument(original, expected), &factory); +} + void QuickfixTest::testInsertDefFromDeclFunctionWithSignedUnsignedArgument() { QByteArray original; @@ -5398,6 +5426,115 @@ SpaceBeforeParens: Always prefs->setCodeStyleSettings(settings); } +QList singleHeader(const QByteArray &original, const QByteArray &expected) +{ + return {CppTestDocument::create("file.h", original, expected)}; +} + +void QuickfixTest::testInsertDefOutsideFromDeclTemplateClassAndTemplateFunction() +{ + QByteArray original = + "template" + "class Foo\n" + "{\n" + " template\n" + " void fun@c();\n" + "};\n"; + QByteArray expected = + "template" + "class Foo\n" + "{\n" + " template\n" + " void fun@c();\n" + "};\n" + "\n" + "template\n" + "template\n" + "inline void Foo::func()\n" + "{\n" + "\n" + "}\n"; + + InsertDefFromDecl factory; + factory.m_defPosOutsideClass = true; + QuickFixOperationTest(singleHeader(original, expected), &factory); +} + +void QuickfixTest::testInsertDefOutsideFromDeclTemplateClass() +{ + QByteArray original = + "template" + "class Foo\n" + "{\n" + " void fun@c();\n" + "};\n"; + QByteArray expected = + "template" + "class Foo\n" + "{\n" + " void fun@c();\n" + "};\n" + "\n" + "template\n" + "inline void Foo::func()\n" + "{\n" + "\n" + "}\n"; + + InsertDefFromDecl factory; + factory.m_defPosOutsideClass = true; + QuickFixOperationTest(singleHeader(original, expected), &factory); +} + +void QuickfixTest::testInsertDefOutsideFromDeclTemplateFunction() +{ + QByteArray original = + "class Foo\n" + "{\n" + " template\n" + " void fun@c();\n" + "};\n"; + QByteArray expected = + "class Foo\n" + "{\n" + " template\n" + " void fun@c();\n" + "};\n" + "\n" + "template\n" + "inline void Foo::func()\n" + "{\n" + "\n" + "}\n"; + + InsertDefFromDecl factory; + factory.m_defPosOutsideClass = true; + QuickFixOperationTest(singleHeader(original, expected), &factory); +} + +void QuickfixTest::testInsertDefOutsideFromDeclFunction() +{ + QByteArray original = + "class Foo\n" + "{\n" + " void fun@c();\n" + "};\n"; + QByteArray expected = + "class Foo\n" + "{\n" + " void fun@c();\n" + "};\n" + "\n" + "inline void Foo::func()\n" + "{\n" + "\n" + "}\n"; + + InsertDefFromDecl factory; + factory.m_defPosOutsideClass = true; + QuickFixOperationTest(singleHeader(original, expected), &factory); +} + // Function for one of InsertDeclDef section cases void insertToSectionDeclFromDef(const QByteArray §ion, int sectionIndex) { diff --git a/src/plugins/cppeditor/cppquickfix_test.h b/src/plugins/cppeditor/cppquickfix_test.h index 99aff71696e..cc589f1908a 100644 --- a/src/plugins/cppeditor/cppquickfix_test.h +++ b/src/plugins/cppeditor/cppquickfix_test.h @@ -136,6 +136,7 @@ private slots: void testInsertDefFromDeclTemplateClass(); void testInsertDefFromDeclTemplateClassWithValueParam(); void testInsertDefFromDeclTemplateFunction(); + void testInsertDefFromDeclTemplateClassAndTemplateFunction(); void testInsertDefFromDeclFunctionWithSignedUnsignedArgument(); void testInsertDefFromDeclNotTriggeredForFriendFunc(); void testInsertDefFromDeclMinimalFunctionParameterType(); @@ -144,6 +145,11 @@ private slots: void testInsertDefsFromDecls(); void testInsertAndFormatDefsFromDecls(); + void testInsertDefOutsideFromDeclTemplateClassAndTemplateFunction(); + void testInsertDefOutsideFromDeclTemplateClass(); + void testInsertDefOutsideFromDeclTemplateFunction(); + void testInsertDefOutsideFromDeclFunction(); + void testInsertDeclFromDef(); void testInsertDeclFromDefTemplateFuncTypename(); void testInsertDeclFromDefTemplateFuncInt(); diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 088449002ca..5128f7195ff 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -2782,10 +2782,27 @@ public: } const QString name = oo.prettyName(LookupContext::minimalName(decl, targetCoN, control)); - const QString defText = inlinePrefix( - targetFilePath, [defPos] { return defPos == DefPosOutsideClass; }) - + oo.prettyType(tn, name) - + QLatin1String("\n{\n\n}"); + + const QString inlinePref = inlinePrefix(targetFilePath, [defPos] { + return defPos == DefPosOutsideClass; + }); + + const QString prettyType = oo.prettyType(tn, name); + + QString input = prettyType; + int index = 0; + while (input.startsWith("template")) { + QRegularExpression templateRegex("template\\s*<[^>]*>"); + QRegularExpressionMatch match = templateRegex.match(input); + if (match.hasMatch()) { + index += match.captured().size() + 1; + input = input.mid(match.captured().size() + 1); + } + } + + QString defText = prettyType; + defText.insert(index, inlinePref); + defText += QLatin1String("\n{\n\n}"); const int targetPos = targetFile->position(loc.line(), loc.column()); const int targetPos2 = qMax(0, targetFile->position(loc.line(), 1) - 1); @@ -2901,7 +2918,7 @@ void InsertDefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOpe const bool isFreeFunction = func->enclosingClass() == nullptr; // Insert Position: Outside Class - if (!isFreeFunction) { + if (!isFreeFunction || m_defPosOutsideClass) { result << new InsertDefOperation(interface, decl, declAST, InsertionLocation(), DefPosOutsideClass, diff --git a/src/plugins/cppeditor/cppquickfixes.h b/src/plugins/cppeditor/cppquickfixes.h index d4c038318b4..4598c2951bd 100644 --- a/src/plugins/cppeditor/cppquickfixes.h +++ b/src/plugins/cppeditor/cppquickfixes.h @@ -357,6 +357,7 @@ class InsertDefFromDecl: public CppQuickFixFactory { public: void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + bool m_defPosOutsideClass = false; }; class AddDeclarationForUndeclaredIdentifier : public CppQuickFixFactory From d391c0c74e515964cef64b4f16a92b39932ac134 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 9 Nov 2023 12:04:30 +0100 Subject: [PATCH 0142/1546] Core: Use Core::Action for 'About...' stuff ... and add the necessary Action::setMenuRole() Change-Id: I2bb309ae115c1e015ff848e0712327360ead23cd Reviewed-by: Christian Stenger --- .../actionmanager/actionmanager.cpp | 7 +++ .../coreplugin/actionmanager/actionmanager.h | 8 +-- src/plugins/coreplugin/icore.cpp | 52 +++++++++---------- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index 0462c4de658..a0e907576d5 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -203,6 +203,13 @@ void Action::setCheckable(bool on) d->command->action()->setCheckable(on); } +void Action::setMenuRole(QAction::MenuRole role) +{ + d->action.setMenuRole(role); + if (d->command) + d->command->action()->setMenuRole(role); +} + Command *Action::command() const { d->ensureCommand(); diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.h b/src/plugins/coreplugin/actionmanager/actionmanager.h index 7a735737d99..d51e5845fdf 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager.h @@ -8,16 +8,11 @@ #include "../icontext.h" #include "command.h" -#include +#include #include #include -QT_BEGIN_NAMESPACE -class QAction; -class QString; -QT_END_NAMESPACE - namespace Core { class ActionContainer; @@ -55,6 +50,7 @@ public: void setChecked(bool on); void setVisible(bool on); void setCheckable(bool on); + void setMenuRole(QAction::MenuRole role); Command *command() const; QAction *commandAction() const; diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index 45afbfafd4f..237d1eb34c9 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -339,6 +339,9 @@ public: QAction *m_setModeSelectorStyleIconsOnlyAction = nullptr; QAction *m_themeAction = nullptr; + Action m_aboutIdeAction; + Action m_aboutPluginsAction; + QToolButton *m_toggleLeftSideBarButton = nullptr; QToolButton *m_toggleRightSideBarButton = nullptr; QList> m_preCloseListeners; @@ -1885,35 +1888,30 @@ void ICorePrivate::registerDefaultActions() mhelp->addSeparator(Constants::G_HELP_ABOUT); // About IDE Action - icon = Icon::fromTheme("help-about"); - if (HostOsInfo::isMacHost()) - tmpaction = new QAction(icon, - Tr::tr("About &%1").arg(QGuiApplication::applicationDisplayName()), - this); // it's convention not to add dots to the about menu - else - tmpaction - = new QAction(icon, - Tr::tr("About &%1...").arg(QGuiApplication::applicationDisplayName()), - this); - tmpaction->setMenuRole(QAction::AboutRole); - cmd = ActionManager::registerAction(tmpaction, Constants::ABOUT_QTCREATOR); - mhelp->addAction(cmd, Constants::G_HELP_ABOUT); - tmpaction->setEnabled(true); - connect(tmpaction, &QAction::triggered, this, &ICorePrivate::aboutQtCreator); + m_aboutIdeAction.setId(Constants::ABOUT_QTCREATOR); + m_aboutIdeAction.setIcon(Icon::fromTheme("help-about")); + m_aboutIdeAction.setText( + (HostOsInfo::isMacHost() ? Tr::tr("About &%1") : Tr::tr("About &%1...")) + .arg(QGuiApplication::applicationDisplayName())); + m_aboutIdeAction.setMenuRole(QAction::AboutRole); + m_aboutIdeAction.setContainer(Constants::M_HELP, Constants::G_HELP_ABOUT); + m_aboutIdeAction.setEnabled(true); + m_aboutIdeAction.setOnTriggered(this, [this] { aboutQtCreator(); }); + + // About Plugins Action + m_aboutPluginsAction.setId(Constants::ABOUT_PLUGINS); + m_aboutPluginsAction.setText(Tr::tr("About &Plugins...")); + m_aboutPluginsAction.setMenuRole(QAction::ApplicationSpecificRole); + m_aboutPluginsAction.setContainer(Constants::M_HELP, Constants::G_HELP_ABOUT); + m_aboutPluginsAction.setEnabled(true); + m_aboutPluginsAction.setOnTriggered(this, [this] { aboutPlugins(); }); - //About Plugins Action - tmpaction = new QAction(Tr::tr("About &Plugins..."), this); - tmpaction->setMenuRole(QAction::ApplicationSpecificRole); - cmd = ActionManager::registerAction(tmpaction, Constants::ABOUT_PLUGINS); - mhelp->addAction(cmd, Constants::G_HELP_ABOUT); - tmpaction->setEnabled(true); - connect(tmpaction, &QAction::triggered, this, &ICorePrivate::aboutPlugins); // About Qt Action - // tmpaction = new QAction(Tr::tr("About &Qt..."), this); - // cmd = ActionManager::registerAction(tmpaction, Constants:: ABOUT_QT); - // mhelp->addAction(cmd, Constants::G_HELP_ABOUT); - // tmpaction->setEnabled(true); - // connect(tmpaction, &QAction::triggered, qApp, &QApplication::aboutQt); + // aboutQtAction.setId(Constants:: ABOUT_QT); + // aboutQtAction.setText(Tr::tr("About &Qt..."), this); + // aboutQtAction.setContainer(Constants::M_HELP, Constants::G_HELP_ABOUT); + // aboutQtAction.setEnabled(true); + // aboutQtAction.setOnTriggered(this, &QApplication::aboutQt); // Change Log Action tmpaction = new QAction(Tr::tr("Change Log..."), this); From ef9be25469a0eff547a4c3ef77ea77f1c7a59630 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 9 Nov 2023 14:19:29 +0100 Subject: [PATCH 0143/1546] Core: Have Core::Action for Help->Contact and Change Log Change-Id: I606bc69c860222c66b241d25363941dd71aeab85 Reviewed-by: Christian Stenger --- src/plugins/coreplugin/icore.cpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index 237d1eb34c9..4bda3ca4d98 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -337,10 +337,11 @@ public: QAction *m_setModeSelectorStyleIconsAndTextAction = nullptr; QAction *m_setModeSelectorStyleHiddenAction = nullptr; QAction *m_setModeSelectorStyleIconsOnlyAction = nullptr; - QAction *m_themeAction = nullptr; Action m_aboutIdeAction; Action m_aboutPluginsAction; + Action m_changeLogAction; + Action m_contactAction; QToolButton *m_toggleLeftSideBarButton = nullptr; QToolButton *m_toggleRightSideBarButton = nullptr; @@ -1914,19 +1915,19 @@ void ICorePrivate::registerDefaultActions() // aboutQtAction.setOnTriggered(this, &QApplication::aboutQt); // Change Log Action - tmpaction = new QAction(Tr::tr("Change Log..."), this); - tmpaction->setMenuRole(QAction::ApplicationSpecificRole); - cmd = ActionManager::registerAction(tmpaction, Constants::CHANGE_LOG); - mhelp->addAction(cmd, Constants::G_HELP_ABOUT); - tmpaction->setEnabled(true); - connect(tmpaction, &QAction::triggered, this, &ICorePrivate::changeLog); + m_changeLogAction.setId(Constants::CHANGE_LOG); + m_changeLogAction.setText(Tr::tr("Change Log...")); + m_changeLogAction.setMenuRole(QAction::ApplicationSpecificRole); + m_changeLogAction.setContainer(Constants::M_HELP, Constants::G_HELP_ABOUT); + m_changeLogAction.setEnabled(true); + m_changeLogAction.setOnTriggered(this, [this] { changeLog(); }); // Contact - tmpaction = new QAction(Tr::tr("Contact..."), this); - cmd = ActionManager::registerAction(tmpaction, "QtCreator.Contact"); - mhelp->addAction(cmd, Constants::G_HELP_ABOUT); - tmpaction->setEnabled(true); - connect(tmpaction, &QAction::triggered, this, &ICorePrivate::contact); + m_contactAction.setId("QtCreator.Contact"); + m_contactAction.setText(Tr::tr("Contact...")); + m_contactAction.setContainer(Constants::M_HELP, Constants::G_HELP_ABOUT); + m_contactAction.setEnabled(true); + m_contactAction.setOnTriggered(this, [this] { contact(); }); // About sep if (!HostOsInfo::isMacHost()) { // doesn't have the "About" actions in the Help menu From 9c45399d142a115315a5dfa3f95dafca801048de Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 8 Nov 2023 13:47:53 +0100 Subject: [PATCH 0144/1546] Beautifier: Simplify plugin setup Change-Id: I9614acaa46075ae1a627997d0261d7c647c7352c Reviewed-by: Christian Stenger --- src/plugins/beautifier/CMakeLists.txt | 2 +- src/plugins/beautifier/beautifier.qbs | 1 - src/plugins/beautifier/beautifierplugin.cpp | 81 ++++++++++++--------- src/plugins/beautifier/beautifierplugin.h | 21 ------ 4 files changed, 46 insertions(+), 59 deletions(-) delete mode 100644 src/plugins/beautifier/beautifierplugin.h diff --git a/src/plugins/beautifier/CMakeLists.txt b/src/plugins/beautifier/CMakeLists.txt index e2ea02a75b9..08a9637fca3 100644 --- a/src/plugins/beautifier/CMakeLists.txt +++ b/src/plugins/beautifier/CMakeLists.txt @@ -5,7 +5,7 @@ add_qtc_plugin(Beautifier artisticstyle/artisticstyle.cpp artisticstyle/artisticstyle.h beautifier.qrc beautifierconstants.h - beautifierplugin.cpp beautifierplugin.h + beautifierplugin.cpp beautifiertool.cpp beautifiertool.h beautifiertr.h clangformat/clangformat.cpp clangformat/clangformat.h diff --git a/src/plugins/beautifier/beautifier.qbs b/src/plugins/beautifier/beautifier.qbs index 1d540b96cca..c2ab7405a45 100644 --- a/src/plugins/beautifier/beautifier.qbs +++ b/src/plugins/beautifier/beautifier.qbs @@ -14,7 +14,6 @@ QtcPlugin { "beautifier.qrc", "beautifierconstants.h", "beautifierplugin.cpp", - "beautifierplugin.h", "beautifiertool.h", "beautifiertool.cpp", "beautifiertr.h", diff --git a/src/plugins/beautifier/beautifierplugin.cpp b/src/plugins/beautifier/beautifierplugin.cpp index e7a4b7593fc..4e780729175 100644 --- a/src/plugins/beautifier/beautifierplugin.cpp +++ b/src/plugins/beautifier/beautifierplugin.cpp @@ -1,8 +1,6 @@ // Copyright (C) 2016 Lorenz Haas // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "beautifierplugin.h" - #include "beautifierconstants.h" #include "beautifiertr.h" #include "generalsettings.h" @@ -20,6 +18,8 @@ #include #include +#include + #include #include #include @@ -35,12 +35,14 @@ #include +using namespace Core; using namespace TextEditor; +using namespace Utils; namespace Beautifier::Internal { -bool isAutoFormatApplicable(const Core::IDocument *document, - const QList &allowedMimeTypes) +static bool isAutoFormatApplicable(const IDocument *document, + const QList &allowedMimeTypes) { if (!document) return false; @@ -48,8 +50,8 @@ bool isAutoFormatApplicable(const Core::IDocument *document, if (allowedMimeTypes.isEmpty()) return true; - const Utils::MimeType documentMimeType = Utils::mimeTypeForName(document->mimeType()); - return Utils::anyOf(allowedMimeTypes, [&documentMimeType](const Utils::MimeType &mime) { + const MimeType documentMimeType = mimeTypeForName(document->mimeType()); + return anyOf(allowedMimeTypes, [&documentMimeType](const MimeType &mime) { return documentMimeType.inherits(mime.name()); }); } @@ -59,37 +61,15 @@ class BeautifierPluginPrivate : public QObject public: BeautifierPluginPrivate(); - void updateActions(Core::IEditor *editor = nullptr); + void updateActions(IEditor *editor = nullptr); - void autoFormatOnSave(Core::IDocument *document); + void autoFormatOnSave(IDocument *document); ArtisticStyle artisticStyleBeautifier; ClangFormat clangFormatBeautifier; Uncrustify uncrustifyBeautifier; }; -static BeautifierPluginPrivate *dd = nullptr; - -void BeautifierPlugin::initialize() -{ - Core::ActionContainer *menu = Core::ActionManager::createMenu(Constants::MENU_ID); - menu->menu()->setTitle(Tr::tr("Bea&utifier")); - menu->setOnAllDisabledBehavior(Core::ActionContainer::Show); - Core::ActionManager::actionContainer(Core::Constants::M_TOOLS)->addMenu(menu); -} - -void BeautifierPlugin::extensionsInitialized() -{ - dd = new BeautifierPluginPrivate; -} - -ExtensionSystem::IPlugin::ShutdownFlag BeautifierPlugin::aboutToShutdown() -{ - delete dd; - dd = nullptr; - return SynchronousShutdown; -} - BeautifierPluginPrivate::BeautifierPluginPrivate() { for (BeautifierTool *tool : BeautifierTool::allTools()) @@ -97,20 +77,20 @@ BeautifierPluginPrivate::BeautifierPluginPrivate() updateActions(); - const Core::EditorManager *editorManager = Core::EditorManager::instance(); - connect(editorManager, &Core::EditorManager::currentEditorChanged, + const EditorManager *editorManager = EditorManager::instance(); + connect(editorManager, &EditorManager::currentEditorChanged, this, &BeautifierPluginPrivate::updateActions); - connect(editorManager, &Core::EditorManager::aboutToSave, + connect(editorManager, &EditorManager::aboutToSave, this, &BeautifierPluginPrivate::autoFormatOnSave); } -void BeautifierPluginPrivate::updateActions(Core::IEditor *editor) +void BeautifierPluginPrivate::updateActions(IEditor *editor) { for (BeautifierTool *tool : BeautifierTool::allTools()) tool->updateActions(editor); } -void BeautifierPluginPrivate::autoFormatOnSave(Core::IDocument *document) +void BeautifierPluginPrivate::autoFormatOnSave(IDocument *document) { if (!generalSettings().autoFormatOnSave()) return; @@ -142,7 +122,7 @@ void BeautifierPluginPrivate::autoFormatOnSave(Core::IDocument *document) const TextEditor::Command command = (*tool)->textCommand(); if (!command.isValid()) return; - const QList editors = Core::DocumentModel::editorsForDocument(document); + const QList editors = DocumentModel::editorsForDocument(document); if (editors.isEmpty()) return; if (auto widget = TextEditorWidget::fromEditor(editors.first())) @@ -150,4 +130,33 @@ void BeautifierPluginPrivate::autoFormatOnSave(Core::IDocument *document) } } +class BeautifierPlugin final : public ExtensionSystem::IPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Beautifier.json") + + void initialize() final + { + ActionContainer *menu = ActionManager::createMenu(Constants::MENU_ID); + menu->menu()->setTitle(Tr::tr("Bea&utifier")); + menu->setOnAllDisabledBehavior(ActionContainer::Show); + ActionManager::actionContainer(Core::Constants::M_TOOLS)->addMenu(menu); + } + + void extensionsInitialized() final + { + d = new BeautifierPluginPrivate; + } + + ShutdownFlag aboutToShutdown() final + { + delete d; + return SynchronousShutdown; + } + + BeautifierPluginPrivate *d = nullptr; +}; + } // Beautifier::Internal + +#include "beautifierplugin.moc" diff --git a/src/plugins/beautifier/beautifierplugin.h b/src/plugins/beautifier/beautifierplugin.h deleted file mode 100644 index e64403d9a7c..00000000000 --- a/src/plugins/beautifier/beautifierplugin.h +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (C) 2016 Lorenz Haas -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include -#include - -namespace Beautifier::Internal { - -class BeautifierPlugin : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Beautifier.json") - - void initialize() override; - void extensionsInitialized() override; - ShutdownFlag aboutToShutdown() override; -}; - -} // Beautifier::Internal From 4b98bebb862ea4ec64cd4d884938b71b076517a9 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Thu, 9 Nov 2023 18:10:14 +0100 Subject: [PATCH 0145/1546] Utils: Change prefix of global static variable names from m_ to s_ Change-Id: Ibf50f1e4db1791e6800b508f80fe1e0cc9d12ef7 Reviewed-by: Cristian Adam --- src/libs/utils/stylehelper.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/libs/utils/stylehelper.cpp b/src/libs/utils/stylehelper.cpp index 8d8655c11b5..49a83234258 100644 --- a/src/libs/utils/stylehelper.cpp +++ b/src/libs/utils/stylehelper.cpp @@ -37,10 +37,10 @@ static int range(float x, int min, int max) namespace Utils { -static StyleHelper::ToolbarStyle m_toolbarStyle = StyleHelper::defaultToolbarStyle; +static StyleHelper::ToolbarStyle s_toolbarStyle = StyleHelper::defaultToolbarStyle; // Invalid by default, setBaseColor needs to be called at least once -static QColor m_baseColor; -static QColor m_requestedBaseColor; +static QColor s_baseColor; +static QColor s_requestedBaseColor; QColor StyleHelper::mergedColors(const QColor &colorA, const QColor &colorB, int factor) { @@ -81,17 +81,17 @@ QColor StyleHelper::toolBarDropShadowColor() int StyleHelper::navigationWidgetHeight() { - return m_toolbarStyle == ToolbarStyleCompact ? 24 : 30; + return s_toolbarStyle == ToolbarStyleCompact ? 24 : 30; } void StyleHelper::setToolbarStyle(ToolbarStyle style) { - m_toolbarStyle = style; + s_toolbarStyle = style; } StyleHelper::ToolbarStyle StyleHelper::toolbarStyle() { - return m_toolbarStyle; + return s_toolbarStyle; } qreal StyleHelper::sidebarFontSize() @@ -130,12 +130,12 @@ QColor StyleHelper::baseColor(bool lightColored) static const QColor windowColor = QApplication::palette().color(QPalette::Window); static const bool windowColorAsBase = creatorTheme()->flag(Theme::WindowColorAsBase); - return (lightColored || windowColorAsBase) ? windowColor : m_baseColor; + return (lightColored || windowColorAsBase) ? windowColor : s_baseColor; } QColor StyleHelper::requestedBaseColor() { - return m_requestedBaseColor; + return s_requestedBaseColor; } QColor StyleHelper::toolbarBaseColor(bool lightColored) @@ -196,7 +196,7 @@ QColor StyleHelper::buttonTextColor() // from the users request. void StyleHelper::setBaseColor(const QColor &newcolor) { - m_requestedBaseColor = newcolor; + s_requestedBaseColor = newcolor; const QColor themeBaseColor = creatorTheme()->color(Theme::PanelStatusBarBackgroundColor); const QColor defaultBaseColor = QColor(DEFAULT_BASE_COLOR); @@ -213,8 +213,8 @@ void StyleHelper::setBaseColor(const QColor &newcolor) value); } - if (color.isValid() && color != m_baseColor) { - m_baseColor = color; + if (color.isValid() && color != s_baseColor) { + s_baseColor = color; const QWidgetList widgets = QApplication::allWidgets(); for (QWidget *w : widgets) w->update(); From d6ea403d0f9c76f1dede7369894589dc6bbd0caf Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 8 Nov 2023 11:58:46 +0100 Subject: [PATCH 0146/1546] Improve styling of dock title widgets Use styled bar and set size to the "single row tool bar" size, which makes it fit better with the rest of the layout/UI. For example there is no "black-white-black" bars in the analyzer views with timelines like QML Profiler, or in the Compiler Explorer. Also the top bar(s) are nicely aligned e.g. in the default debugger layout when the debugger is running. Also switch to custom buttons. Change-Id: I52f95e3fbb32718b131fde39d75a20105fb0304a Reviewed-by: hjk Reviewed-by: Alessandro Portale Reviewed-by: Marcus Tillmanns --- src/libs/utils/fancymainwindow.cpp | 39 +++++++++++++----------------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/src/libs/utils/fancymainwindow.cpp b/src/libs/utils/fancymainwindow.cpp index 1446f602689..771025f8e51 100644 --- a/src/libs/utils/fancymainwindow.cpp +++ b/src/libs/utils/fancymainwindow.cpp @@ -7,6 +7,8 @@ #include "qtcassert.h" #include "qtcsettings.h" #include "stringutils.h" +#include "styledbar.h" +#include "utilsicons.h" #include "utilstr.h" #include @@ -98,6 +100,10 @@ public: void paintEvent(QPaintEvent *event) override; }; +const int titleMinWidth = 10; +const int titleMaxWidth = 10000; +const int titleInactiveHeight = 0; + void DockWidgetTitleButton::paintEvent(QPaintEvent *) { QPainter p(this); @@ -115,20 +121,21 @@ void DockWidgetTitleButton::paintEvent(QPaintEvent *) style()->drawComplexControl(QStyle::CC_ToolButton, &opt, &p, this); } -class TitleBarWidget : public QWidget +class TitleBarWidget : public StyledBar { public: - TitleBarWidget(DockWidget *parent, const QStyleOptionDockWidget &opt) - : QWidget(parent) + TitleBarWidget(DockWidget *parent) + : StyledBar(parent) , q(parent) { m_titleLabel = new QLabel(this); m_floatButton = new DockWidgetTitleButton(this); - m_floatButton->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarNormalButton, &opt, q)); + m_floatButton->setIcon( + Icon({{":/utils/images/app-on-top.png", Theme::IconsBaseColor}}).icon()); m_closeButton = new DockWidgetTitleButton(this); - m_closeButton->setIcon(q->style()->standardIcon(QStyle::SP_TitleBarCloseButton, &opt, q)); + m_closeButton->setIcon(Icons::CLOSE_TOOLBAR.icon()); #ifndef QT_NO_ACCESSIBILITY m_floatButton->setAccessibleName(QDockWidget::tr("Float")); @@ -137,16 +144,6 @@ public: m_closeButton->setAccessibleDescription(QDockWidget::tr("Closes the dock widget")); #endif - const int minWidth = 10; - const int maxWidth = 10000; - const int inactiveHeight = 0; - const int activeHeight = m_closeButton->sizeHint().height() + 2; - - m_minimumInactiveSize = QSize(minWidth, inactiveHeight); - m_maximumInactiveSize = QSize(maxWidth, inactiveHeight); - m_minimumActiveSize = QSize(minWidth, activeHeight); - m_maximumActiveSize = QSize(maxWidth, activeHeight); - auto layout = new QHBoxLayout(this); layout->setSpacing(0); layout->setContentsMargins(4, 0, 0, 0); @@ -195,23 +192,21 @@ public: QSize sizeHint() const override { ensurePolished(); - return m_active ? m_maximumActiveSize : m_maximumInactiveSize; + return m_active ? QSize(titleMaxWidth, StyledBar::minimumHeight()) + : QSize(titleMaxWidth, titleInactiveHeight); } QSize minimumSizeHint() const override { ensurePolished(); - return m_active ? m_minimumActiveSize : m_minimumInactiveSize; + return m_active ? QSize(titleMinWidth, StyledBar::minimumHeight()) + : QSize(titleMinWidth, titleInactiveHeight); } private: DockWidget *q; bool m_active = true; bool m_hovered = false; - QSize m_minimumActiveSize; - QSize m_maximumActiveSize; - QSize m_minimumInactiveSize; - QSize m_maximumInactiveSize; public: QLabel *m_titleLabel; @@ -235,7 +230,7 @@ DockWidget::DockWidget(QWidget *inner, FancyMainWindow *parent, bool immutable) QStyleOptionDockWidget opt; initStyleOption(&opt); - m_titleBar = new TitleBarWidget(this, opt); + m_titleBar = new TitleBarWidget(this); m_titleBar->m_titleLabel->setText(title); setTitleBarWidget(m_titleBar); From cd6311a125a33f31f4496c1ef76f318dd207cded Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 10 Nov 2023 08:56:45 +0100 Subject: [PATCH 0147/1546] Core: Remove Q_OBJECT from CommandPrivate We don't really use any of the additional functionality. Change-Id: I5fd7b7c9ce5dac457179f1fe8dcfbf3d3395cc93 Reviewed-by: Eike Ziller --- src/plugins/coreplugin/actionmanager/command_p.h | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/plugins/coreplugin/actionmanager/command_p.h b/src/plugins/coreplugin/actionmanager/command_p.h index d90b807c553..6940be23fc6 100644 --- a/src/plugins/coreplugin/actionmanager/command_p.h +++ b/src/plugins/coreplugin/actionmanager/command_p.h @@ -10,20 +10,17 @@ #include #include -#include -#include -#include -#include #include +#include +#include +#include #include -namespace Core { -namespace Internal { +namespace Core::Internal { class CommandPrivate : public QObject { - Q_OBJECT public: CommandPrivate(Command *parent); @@ -56,5 +53,4 @@ public: bool m_contextInitialized = false; }; -} // namespace Internal -} // namespace Core +} // namespace Core::Internal From 09f43e79cf7bb76004ed75578feb30ab4f2f1708 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 9 Nov 2023 15:33:11 +0100 Subject: [PATCH 0148/1546] Dock widgets: Add collapse/uncollapse functionality Add a button that can be used to collapse a dock widget's contents temporarily, as an alternative to removing and re-adding it. To achieve that, remove the inner widget of the dock widget and store it in an inner pointer. Just setting the inner widget invisible/visible does not work, because the title widget of a dock widget with invisible inner widget becomes 0 for some reason. We also need to add a dummy widget with a maximum height, to make the dock widget resize and not be resizable afterwards. Do not allow collapsing if the dock is the only one in the area, in a horizontal layout, floating, or tabbed. Change-Id: Ibc1acb59d58069f08184e65c4814642acb0028ee Reviewed-by: Marcus Tillmanns --- src/libs/utils/fancymainwindow.cpp | 94 ++++++++++++++++++++- src/libs/utils/fancymainwindow.h | 2 + src/plugins/debugger/debuggermainwindow.cpp | 2 +- 3 files changed, 96 insertions(+), 2 deletions(-) diff --git a/src/libs/utils/fancymainwindow.cpp b/src/libs/utils/fancymainwindow.cpp index 771025f8e51..0e26d5bfc0b 100644 --- a/src/libs/utils/fancymainwindow.cpp +++ b/src/libs/utils/fancymainwindow.cpp @@ -49,9 +49,12 @@ class DockWidget : public QDockWidget { public: DockWidget(QWidget *inner, FancyMainWindow *parent, bool immutable = false); + ~DockWidget(); FancyMainWindow *q; + QWidget *m_hiddenInnerWidget = nullptr; + private: QPoint m_startPos; TitleBarWidget *m_titleBar; @@ -130,6 +133,23 @@ public: { m_titleLabel = new QLabel(this); + m_collapseButton = new DockWidgetTitleButton(this); + updateCollapse(); + connect(m_collapseButton, &DockWidgetTitleButton::clicked, this, [this] { + if (supportsCollapse()) { + if (!q->m_hiddenInnerWidget) { + q->m_hiddenInnerWidget = q->widget(); + auto w = new QWidget; + w->setMaximumHeight(0); + q->setWidget(w); + } else { + ensureWidgetShown(); + } + } + updateCollapse(); + }); + connect(q->q, &FancyMainWindow::dockWidgetsChanged, this, &TitleBarWidget::updateCollapse); + m_floatButton = new DockWidgetTitleButton(this); m_floatButton->setIcon( Icon({{":/utils/images/app-on-top.png", Theme::IconsBaseColor}}).icon()); @@ -147,6 +167,7 @@ public: auto layout = new QHBoxLayout(this); layout->setSpacing(0); layout->setContentsMargins(4, 0, 0, 0); + layout->addWidget(m_collapseButton); layout->addWidget(m_titleLabel); layout->addStretch(); layout->addWidget(m_floatButton); @@ -187,6 +208,7 @@ public: && q->features().testFlag(QDockWidget::DockWidgetFloatable)); m_closeButton->setVisible(m_active && m_hovered && q->features().testFlag(QDockWidget::DockWidgetClosable)); + updateCollapse(); } QSize sizeHint() const override @@ -203,6 +225,50 @@ public: : QSize(titleMinWidth, titleInactiveHeight); } + bool supportsCollapse() const + { + // not if floating + if (q->isFloating()) + return false; + // not if tabbed + if (!filtered(q->q->tabifiedDockWidgets(q), [](QDockWidget *w) { + return w->isVisible(); + }).isEmpty()) + return false; + const QList docksInArea + = filtered(q->q->dockWidgets(), [this, area = q->q->dockWidgetArea(q)](QDockWidget *w) { + return w != q && w->isVisible() && q->q->dockWidgetArea(w) == area; + }); + // not if only dock in area + if (docksInArea.isEmpty()) + return false; + // not if in horizontal layout + if (anyOf(docksInArea, [y = q->y()](QDockWidget *w) { return w->y() == y; })) + return false; + return true; + } + + void ensureWidgetShown() + { + if (q->m_hiddenInnerWidget) { + delete q->widget(); + q->setWidget(q->m_hiddenInnerWidget); + q->m_hiddenInnerWidget = nullptr; + } + } + + void updateCollapse() + { + const bool supported = m_active && supportsCollapse(); + m_collapseButton->setVisible(supported); + if (!supported) + ensureWidgetShown(); + if (q->m_hiddenInnerWidget) + m_collapseButton->setIcon(Icons::NEXT_TOOLBAR.icon()); + else + m_collapseButton->setIcon(Icons::ARROW_DOWN_TOOLBAR.icon()); + } + private: DockWidget *q; bool m_active = true; @@ -210,6 +276,7 @@ private: public: QLabel *m_titleLabel; + DockWidgetTitleButton *m_collapseButton; DockWidgetTitleButton *m_floatButton; DockWidgetTitleButton *m_closeButton; }; @@ -253,6 +320,11 @@ DockWidget::DockWidget(QWidget *inner, FancyMainWindow *parent, bool immutable) origCloseButton, &QAbstractButton::clicked); } +DockWidget::~DockWidget() +{ + delete m_hiddenInnerWidget; +} + /*! \class Utils::FancyMainWindow \inmodule QtCreator @@ -316,6 +388,19 @@ QDockWidget *FancyMainWindow::addDockForWidget(QWidget *widget, bool immutable) }, Qt::QueuedConnection); dockWidget->setProperty(dockWidgetActiveState, true); + + connect(dockWidget, + &QDockWidget::dockLocationChanged, + this, + &FancyMainWindow::dockWidgetsChanged); + connect(dockWidget, + &QDockWidget::topLevelChanged, + this, + &FancyMainWindow::dockWidgetsChanged); + connect(dockWidget, + &QDockWidget::visibilityChanged, + this, + &FancyMainWindow::dockWidgetsChanged); } return dockWidget; @@ -396,7 +481,7 @@ void FancyMainWindow::restoreSettings(const QHash &settings) { QByteArray ba = settings.value(StateKey, QByteArray()).toByteArray(); if (!ba.isEmpty()) { - if (!restoreState(ba, settingsVersion)) + if (!restoreFancyState(ba, settingsVersion)) qWarning() << "Restoring the state of dock widgets failed."; } d->m_showCentralWidget.setChecked(settings.value(ShowCentralWidgetKey, true).toBool()); @@ -406,6 +491,13 @@ void FancyMainWindow::restoreSettings(const QHash &settings) } } +bool FancyMainWindow::restoreFancyState(const QByteArray &state, int version) +{ + const bool result = restoreState(state, version); + emit dockWidgetsChanged(); + return result; +} + static void findDockChildren(QWidget *parent, QList &result) { for (QObject *child : parent->children()) { diff --git a/src/libs/utils/fancymainwindow.h b/src/libs/utils/fancymainwindow.h index 644482132b0..df9f2c1281e 100644 --- a/src/libs/utils/fancymainwindow.h +++ b/src/libs/utils/fancymainwindow.h @@ -33,6 +33,7 @@ public: void restoreSettings(const QtcSettings *settings); QHash saveSettings() const; void restoreSettings(const QHash &settings); + bool restoreFancyState(const QByteArray &state, int version = 0); // Additional context menu actions QAction *menuSeparator1() const; @@ -47,6 +48,7 @@ signals: // Emitted by resetLayoutAction(). Connect to a slot // restoring the default layout. void resetLayout(); + void dockWidgetsChanged(); public slots: void setDockActionsVisible(bool v); diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp index 89dcc3dda03..03948aaf320 100644 --- a/src/plugins/debugger/debuggermainwindow.cpp +++ b/src/plugins/debugger/debuggermainwindow.cpp @@ -1004,7 +1004,7 @@ void PerspectivePrivate::restoreLayout() if (state.mainWindowState.isEmpty()) { qCDebug(perspectivesLog) << "PERSPECTIVE " << m_id << "RESTORE NOT POSSIBLE, NO STORED STATE"; } else { - bool result = theMainWindow->restoreState(state.mainWindowState); + bool result = theMainWindow->restoreFancyState(state.mainWindowState); qCDebug(perspectivesLog) << "PERSPECTIVE " << m_id << "RESTORED, SUCCESS: " << result; } From ab8ba7f264aed3758ee52a1a1bb7bf4bd5a7060d Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 9 Nov 2023 10:51:53 +0100 Subject: [PATCH 0149/1546] Core: Replace new "Action" by an "ActionBuilder" This needs not be stored somewhere but does its work latest at destruction automatically. Change-Id: If929f5a5ccc15b085f110d8d9db8f72ff2a5fac5 Reviewed-by: Eike Ziller Reviewed-by: hjk --- .../actionmanager/actionmanager.cpp | 170 ++++---- .../coreplugin/actionmanager/actionmanager.h | 12 +- src/plugins/coreplugin/icore.cpp | 405 +++++++++--------- .../genericprojectplugin.cpp | 6 +- src/plugins/texteditor/texteditorplugin.cpp | 110 ++--- 5 files changed, 352 insertions(+), 351 deletions(-) diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index a0e907576d5..3b417dbeb0c 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -71,175 +71,164 @@ void PresentationModeHandler::showShortcutPopup(const QString &shortcut) namespace Core { -class ActionPrivate +class ActionBuilderPrivate { public: - void ensureCommand() + ActionBuilderPrivate(QObject *contextActionParent, const Id actionId) + : action(new QAction(contextActionParent)) + , actionId(actionId) { - if (!command) { - QTC_ASSERT(actionId.isValid(), return); - command = ActionManager::registerAction(&action, actionId, context); - } + command = ActionManager::createCommand(actionId); } - QAction action; + void registerAction() + { + QTC_ASSERT(actionId.isValid(), return); + ActionManager::registerAction(action, actionId, context); + } + + QAction *action = nullptr; + Command *command = nullptr; + Id actionId; Context context{Constants::C_GLOBAL}; - Command *command = nullptr; }; -Action::Action() - : d(new ActionPrivate) +ActionBuilder::ActionBuilder(QObject *contextActionParent, const Id actionId) + : d(new ActionBuilderPrivate(contextActionParent, actionId)) { } -Action::~Action() +ActionBuilder::~ActionBuilder() { - delete d; + d->registerAction(); } -void Action::setText(const QString &text) +void ActionBuilder::setText(const QString &text) { - d->action.setText(text); - if (d->command) - d->command->action()->setText(text); + d->action->setText(text); } -void Action::setCommandAttribute(Command::CommandAttribute attr) +void ActionBuilder::setCommandAttribute(Command::CommandAttribute attr) { - d->ensureCommand(); - QTC_ASSERT(d->command, return); d->command->setAttribute(attr); } -void Action::setContainer(Utils::Id containerId, Utils::Id groupId) +void ActionBuilder::setCommandDescription(const QString &desc) { - d->ensureCommand(); - QTC_ASSERT(d->command, return); - if (containerId.isValid()) { - ActionContainer *container = ActionManager::actionContainer(containerId); - container->addAction(d->command, groupId); - } + d->command->setDescription(desc); } -void Action::setOnTriggered(const std::function &func) +void ActionBuilder::setContainer(Id containerId, Id groupId) { - QObject::connect(&d->action, &QAction::triggered, &d->action, func); + QTC_ASSERT(containerId.isValid(), return); + ActionContainer *container = ActionManager::actionContainer(containerId); + QTC_ASSERT(container, return); + container->addAction(d->command, groupId); } -void Action::setOnTriggered(QObject *guard, const std::function &func) +void ActionBuilder::setOnTriggered(const std::function &func) { - QObject::connect(&d->action, &QAction::triggered, guard, func); + QObject::connect(d->action, &QAction::triggered, d->action, func); } -void Action::setOnTriggered(QObject *guard, const std::function &func) +void ActionBuilder::setOnTriggered(QObject *guard, const std::function &func) { - QObject::connect(&d->action, &QAction::triggered, guard, func); + QObject::connect(d->action, &QAction::triggered, guard, func); } -void Action::setDefaultKeySequence(const QKeySequence &seq) +void ActionBuilder::setOnTriggered(QObject *guard, const std::function &func) +{ + QObject::connect(d->action, &QAction::triggered, guard, func); +} + +void ActionBuilder::setDefaultKeySequence(const QKeySequence &seq) { - d->ensureCommand(); - QTC_ASSERT(d->command, return); d->command->setDefaultKeySequence(seq); } -void Action::setDefaultKeySequence(const QString &mac, const QString &nonMac) +void ActionBuilder::setDefaultKeySequences(const QList &seqs) +{ + d->command->setDefaultKeySequences(seqs); +} + +void ActionBuilder::setDefaultKeySequence(const QString &mac, const QString &nonMac) { - d->ensureCommand(); - QTC_ASSERT(d->command, return); d->command->setDefaultKeySequence(QKeySequence(useMacShortcuts ? mac : nonMac)); } -void Action::setIcon(const QIcon &icon) +void ActionBuilder::setIcon(const QIcon &icon) { - d->action.setIcon(icon); - if (d->command) - d->command->action()->setIcon(icon); + d->action->setIcon(icon); } -void Action::setIconVisibleInMenu(bool on) +void ActionBuilder::setIconVisibleInMenu(bool on) { - d->action.setIconVisibleInMenu(on); - if (d->command) - d->command->action()->setIconVisibleInMenu(on); + d->action->setIconVisibleInMenu(on); } -void Action::setTouchBarIcon(const QIcon &icon) +void ActionBuilder::setTouchBarIcon(const QIcon &icon) { - d->ensureCommand(); - QTC_ASSERT(d->command, return); d->command->setTouchBarIcon(icon); } -void Action::setEnabled(bool on) +void ActionBuilder::setEnabled(bool on) { - d->action.setEnabled(on); - // Explicitly not needed, done via context update: - // if (d->command) - // d->command->action()->... + d->action->setEnabled(on); } -void Action::setChecked(bool on) +void ActionBuilder::setChecked(bool on) { - d->action.setChecked(on); - // Explicitly not needed, done via context update: - // if (d->command) - // d->command->action()->... + d->action->setChecked(on); } -void Action::setVisible(bool on) +void ActionBuilder::setVisible(bool on) { - d->action.setVisible(on); - // Explicitly not needed, done via context update: - // if (d->command) - // d->command->action()->.... + d->action->setVisible(on); } -void Action::setCheckable(bool on) +void ActionBuilder::setCheckable(bool on) { - d->action.setCheckable(on); - if (d->command) - d->command->action()->setCheckable(on); + d->action->setCheckable(on); } -void Action::setMenuRole(QAction::MenuRole role) +void ActionBuilder::setMenuRole(QAction::MenuRole role) { - d->action.setMenuRole(role); - if (d->command) - d->command->action()->setMenuRole(role); + d->action->setMenuRole(role); } -Command *Action::command() const +Command *ActionBuilder::command() const { - d->ensureCommand(); - QTC_CHECK(d->command); return d->command; } -QAction *Action::commandAction() const +QAction *ActionBuilder::commandAction() const { - d->ensureCommand(); - QTC_ASSERT(d->command, return nullptr); return d->command->action(); } -QAction *Action::contextAction() const +QAction *ActionBuilder::contextAction() const { - return &d->action; + return d->action; } -void Action::setId(Id id) +void ActionBuilder::bindContextAction(QAction **dest) +{ + QTC_ASSERT(dest, return); + *dest = d->action; +} + +void ActionBuilder::setId(Id id) { d->actionId = id; } -void Action::setContext(Id id) +void ActionBuilder::setContext(Id id) { d->context = Context(id); } -void Action::setContext(const Context &context) +void ActionBuilder::setContext(const Context &context) { QTC_ASSERT(!context.isEmpty(), return); d->context = context; @@ -484,6 +473,21 @@ Command *ActionManager::registerAction(QAction *action, Id id, const Context &co return cmd; } +/*! + Creates a Command or returns an existing Command with the specified \a id. + + The created command doesn't have any actions associated with it yet, so + it cannot actually be triggered. + But the system is aware of it, it appears in the keyboard shortcut + settings, and QActions can later be registered for it. + If you already have a QAction, ID and Context that you want to register, + there is no need to call this. Just directly call registerAction(). +*/ +Command *ActionManager::createCommand(Utils::Id id) +{ + return d->overridableAction(id); +} + /*! Returns the Command instance that has been created with registerAction() for the specified \a id. diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.h b/src/plugins/coreplugin/actionmanager/actionmanager.h index d51e5845fdf..cecd2d29b28 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager.h @@ -26,22 +26,24 @@ class ICorePrivate; class MainWindow; } // Internal -class CORE_EXPORT Action +class CORE_EXPORT ActionBuilder { public: - Action(); - ~Action(); + ActionBuilder(QObject *contextActionParent, const Utils::Id actionId = {}); + ~ActionBuilder(); void setId(Utils::Id id); void setContext(const Utils::Id id); void setContext(const Core::Context &context); void setText(const QString &text); void setCommandAttribute(Core::Command::CommandAttribute attr); + void setCommandDescription(const QString &desc); void setContainer(Utils::Id containerId, Utils::Id groupId = {}); void setOnTriggered(const std::function &func); void setOnTriggered(QObject *guard, const std::function &func); void setOnTriggered(QObject *guard, const std::function &func); void setDefaultKeySequence(const QKeySequence &seq); + void setDefaultKeySequences(const QList &seqs); void setDefaultKeySequence(const QString &mac, const QString &nonMac); void setIcon(const QIcon &icon); void setIconVisibleInMenu(bool on); @@ -55,9 +57,10 @@ public: Command *command() const; QAction *commandAction() const; QAction *contextAction() const; + void bindContextAction(QAction **dest); private: - class ActionPrivate *d = nullptr; + class ActionBuilderPrivate *d = nullptr; }; class CORE_EXPORT Menu @@ -96,6 +99,7 @@ public: const Context &context = Context(Constants::C_GLOBAL), bool scriptable = false); + static Command *createCommand(Utils::Id id); static Command *command(Utils::Id id); static ActionContainer *actionContainer(Utils::Id id); diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index 4bda3ca4d98..3dfd69840a3 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -321,15 +321,7 @@ public: SystemEditor *m_systemEditor = nullptr; // actions - QAction *m_focusToEditor = nullptr; - QAction *m_newAction = nullptr; - QAction *m_openAction = nullptr; - QAction *m_openWithAction = nullptr; - QAction *m_openFromDeviceAction = nullptr; QAction *m_saveAllAction = nullptr; - QAction *m_exitAction = nullptr; - QAction *m_optionsAction = nullptr; - QAction *m_loggerAction = nullptr; QAction *m_toggleLeftSideBarAction = nullptr; QAction *m_toggleRightSideBarAction = nullptr; QAction *m_toggleMenubarAction = nullptr; @@ -338,11 +330,6 @@ public: QAction *m_setModeSelectorStyleHiddenAction = nullptr; QAction *m_setModeSelectorStyleIconsOnlyAction = nullptr; - Action m_aboutIdeAction; - Action m_aboutPluginsAction; - Action m_changeLogAction; - Action m_contactAction; - QToolButton *m_toggleLeftSideBarButton = nullptr; QToolButton *m_toggleRightSideBarButton = nullptr; QList> m_preCloseListeners; @@ -1569,19 +1556,18 @@ void ICorePrivate::registerDefaultActions() // Return to editor shortcut: Note this requires Qt to fix up // handling of shortcut overrides in menus, item views, combos.... - m_focusToEditor = new QAction(Tr::tr("Return to Editor"), this); - Command *cmd = ActionManager::registerAction(m_focusToEditor, Constants::S_RETURNTOEDITOR); - cmd->setDefaultKeySequence(QKeySequence(Qt::Key_Escape)); - connect(m_focusToEditor, &QAction::triggered, this, &ICorePrivate::setFocusToEditor); + ActionBuilder focusToEditor(this, Constants::S_RETURNTOEDITOR); + focusToEditor.setText(Tr::tr("Return to Editor")); + focusToEditor.setDefaultKeySequence(QKeySequence(Qt::Key_Escape)); + focusToEditor.setOnTriggered(this, [] { setFocusToEditor(); }); - // New File Action - QIcon icon = Icon::fromTheme("document-new"); - - m_newAction = new QAction(icon, Tr::tr("&New Project..."), this); - cmd = ActionManager::registerAction(m_newAction, Constants::NEW); - cmd->setDefaultKeySequence(QKeySequence("Ctrl+Shift+N")); - mfile->addAction(cmd, Constants::G_FILE_NEW); - connect(m_newAction, &QAction::triggered, this, [] { + // New Project Action + ActionBuilder newProjectAction(this, Constants::NEW); + newProjectAction.setText(Tr::tr("&New Project...")); + newProjectAction.setIcon(Icon::fromTheme("document-new")); + newProjectAction.setDefaultKeySequence(QKeySequence("Ctrl+Shift+N")); + newProjectAction.setContainer(Constants::M_FILE, Constants::G_FILE_NEW); + newProjectAction.setOnTriggered(this, [] { if (!ICore::isNewItemDialogRunning()) { ICore::showNewItemDialog( Tr::tr("New Project", "Title of dialog"), @@ -1594,42 +1580,45 @@ void ICorePrivate::registerDefaultActions() } }); - auto action = new QAction(icon, Tr::tr("New File..."), this); - cmd = ActionManager::registerAction(action, Constants::NEW_FILE); - cmd->setDefaultKeySequence(QKeySequence::New); - mfile->addAction(cmd, Constants::G_FILE_NEW); - connect(action, &QAction::triggered, this, [] { + // New File Action + ActionBuilder newFileAction(this, Constants::NEW_FILE); + newFileAction.setText(Tr::tr("New File...")); + newFileAction.setIcon(Icon::fromTheme("document-new")); + newFileAction.setDefaultKeySequence(QKeySequence::New); + newFileAction.setContainer(Constants::M_FILE, Constants::G_FILE_NEW); + newFileAction.setOnTriggered(this, [] { if (!ICore::isNewItemDialogRunning()) { - ICore::showNewItemDialog(Tr::tr("New File", "Title of dialog"), - Utils::filtered(Core::IWizardFactory::allWizardFactories(), - Utils::equal(&Core::IWizardFactory::kind, - Core::IWizardFactory::FileWizard)), - FilePath()); + ICore::showNewItemDialog( + Tr::tr("New File", "Title of dialog"), + Utils::filtered(Core::IWizardFactory::allWizardFactories(), + Utils::equal(&Core::IWizardFactory::kind, + Core::IWizardFactory::FileWizard)), + FilePath()); } else { ICore::raiseWindow(ICore::newItemDialog()); } }); // Open Action - icon = Icon::fromTheme("document-open"); - m_openAction = new QAction(icon, Tr::tr("&Open File or Project..."), this); - cmd = ActionManager::registerAction(m_openAction, Constants::OPEN); - cmd->setDefaultKeySequence(QKeySequence::Open); - mfile->addAction(cmd, Constants::G_FILE_OPEN); - connect(m_openAction, &QAction::triggered, this, &ICorePrivate::openFile); + ActionBuilder openAction(this, Constants::OPEN); + openAction.setText(Tr::tr("&Open File or Project...")); + openAction.setIcon(Icon::fromTheme("document-open")); + openAction.setDefaultKeySequence(QKeySequence::Open); + openAction.setContainer(Constants::M_FILE, Constants::G_FILE_OPEN); + openAction.setOnTriggered(this, [] { openFile(); }); // Open With Action - m_openWithAction = new QAction(Tr::tr("Open File &With..."), this); - cmd = ActionManager::registerAction(m_openWithAction, Constants::OPEN_WITH); - mfile->addAction(cmd, Constants::G_FILE_OPEN); - connect(m_openWithAction, &QAction::triggered, m_core, &ICore::openFileWith); + ActionBuilder openWithAction(this, Constants::OPEN_WITH); + openWithAction.setText(Tr::tr("Open File &With...")); + openWithAction.setContainer(Constants::M_FILE, Constants::G_FILE_OPEN); + openWithAction.setOnTriggered(this, &ICore::openFileWith); if (FSEngine::isAvailable()) { // Open From Device Action - m_openFromDeviceAction = new QAction(Tr::tr("Open From Device..."), this); - cmd = ActionManager::registerAction(m_openFromDeviceAction, Constants::OPEN_FROM_DEVICE); - mfile->addAction(cmd, Constants::G_FILE_OPEN); - connect(m_openFromDeviceAction, &QAction::triggered, this, &ICorePrivate::openFileFromDevice); + ActionBuilder openFromDeviceAction(this, Constants::OPEN_FROM_DEVICE); + openFromDeviceAction.setText(Tr::tr("Open From Device...")); + openFromDeviceAction.setContainer(Constants::M_FILE, Constants::G_FILE_OPEN); + openFromDeviceAction.setOnTriggered(this, [this] { openFileFromDevice(); }); } // File->Recent Files Menu @@ -1639,128 +1628,128 @@ void ICorePrivate::registerDefaultActions() ac->setOnAllDisabledBehavior(ActionContainer::Show); // Save Action - icon = Icon::fromTheme("document-save"); - QAction *tmpaction = new QAction(icon, Tr::tr("&Save"), this); - tmpaction->setEnabled(false); - cmd = ActionManager::registerAction(tmpaction, Constants::SAVE); - cmd->setDefaultKeySequence(QKeySequence::Save); - cmd->setAttribute(Command::CA_UpdateText); - cmd->setDescription(Tr::tr("Save")); - mfile->addAction(cmd, Constants::G_FILE_SAVE); + ActionBuilder saveAction(this, Constants::SAVE); + saveAction.setText(Tr::tr("&Save")); + saveAction.setIcon(Icon::fromTheme("document-save")); + saveAction.setEnabled(false); + saveAction.setDefaultKeySequence(QKeySequence::Save); + saveAction.setCommandAttribute(Command::CA_UpdateText); + saveAction.setCommandDescription(Tr::tr("Save")); + saveAction.setContainer(Constants::M_FILE, Constants::G_FILE_SAVE); // Save As Action - icon = Icon::fromTheme("document-save-as"); - tmpaction = new QAction(icon, Tr::tr("Save &As..."), this); - tmpaction->setEnabled(false); - cmd = ActionManager::registerAction(tmpaction, Constants::SAVEAS); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Ctrl+Shift+S") : QString())); - cmd->setAttribute(Command::CA_UpdateText); - cmd->setDescription(Tr::tr("Save As...")); - mfile->addAction(cmd, Constants::G_FILE_SAVE); + ActionBuilder saveAsAction(this, Constants::SAVEAS); + saveAsAction.setText(Tr::tr("Save &As...")); + saveAsAction.setIcon(Icon::fromTheme("document-save-as")); + saveAsAction.setEnabled(false); + saveAsAction.setDefaultKeySequence(Tr::tr("Ctrl+Shift+S"), QString()); + saveAsAction.setCommandAttribute(Command::CA_UpdateText); + saveAsAction.setCommandDescription(Tr::tr("Save As...")); + saveAsAction.setContainer(Constants::M_FILE, Constants::G_FILE_SAVE); // SaveAll Action DocumentManager::registerSaveAllAction(); // Print Action - icon = Icon::fromTheme("document-print"); - tmpaction = new QAction(icon, Tr::tr("&Print..."), this); - tmpaction->setEnabled(false); - cmd = ActionManager::registerAction(tmpaction, Constants::PRINT); - cmd->setDefaultKeySequence(QKeySequence::Print); - mfile->addAction(cmd, Constants::G_FILE_PRINT); + ActionBuilder printAction(this, Constants::PRINT); + printAction.setText(Tr::tr("&Print...")); + printAction.setIcon(Icon::fromTheme("document-print")); + printAction.setEnabled(false); + printAction.setDefaultKeySequence(QKeySequence::Print); + printAction.setContainer(Constants::M_FILE, Constants::G_FILE_PRINT); // Exit Action - icon = Icon::fromTheme("application-exit"); - m_exitAction = new QAction(icon, Tr::tr("E&xit"), this); - m_exitAction->setMenuRole(QAction::QuitRole); - cmd = ActionManager::registerAction(m_exitAction, Constants::EXIT); - cmd->setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+Q"))); - mfile->addAction(cmd, Constants::G_FILE_OTHER); - connect(m_exitAction, &QAction::triggered, m_core, &ICore::exit); + ActionBuilder exitAction(this, Constants::EXIT); + exitAction.setText(Tr::tr("E&xit")); + exitAction.setIcon(Icon::fromTheme("application-exit")); + exitAction.setMenuRole(QAction::QuitRole); + exitAction.setDefaultKeySequence(Tr::tr("Ctrl+Q")); + exitAction.setContainer(Constants::M_FILE, Constants::G_FILE_OTHER); + exitAction.setOnTriggered(this, &ICore::exit); // Undo Action - icon = Icon::fromTheme("edit-undo"); - tmpaction = new QAction(icon, Tr::tr("&Undo"), this); - cmd = ActionManager::registerAction(tmpaction, Constants::UNDO); - cmd->setDefaultKeySequence(QKeySequence::Undo); - cmd->setAttribute(Command::CA_UpdateText); - cmd->setDescription(Tr::tr("Undo")); - medit->addAction(cmd, Constants::G_EDIT_UNDOREDO); - tmpaction->setEnabled(false); + ActionBuilder undoAction(this, Constants::UNDO); + undoAction.setText(Tr::tr("&Undo")); + undoAction.setIcon(Icon::fromTheme("edit-undo")); + undoAction.setDefaultKeySequence(QKeySequence::Undo); + undoAction.setCommandAttribute(Command::CA_UpdateText); + undoAction.setCommandDescription(Tr::tr("Undo")); + undoAction.setContainer(Constants::M_EDIT, Constants::G_EDIT_UNDOREDO); + undoAction.setEnabled(false); // Redo Action - icon = Icon::fromTheme("edit-redo"); - tmpaction = new QAction(icon, Tr::tr("&Redo"), this); - cmd = ActionManager::registerAction(tmpaction, Constants::REDO); - cmd->setDefaultKeySequence(QKeySequence::Redo); - cmd->setAttribute(Command::CA_UpdateText); - cmd->setDescription(Tr::tr("Redo")); - medit->addAction(cmd, Constants::G_EDIT_UNDOREDO); - tmpaction->setEnabled(false); + ActionBuilder redoAction(this, Constants::REDO); + redoAction.setIcon(Icon::fromTheme("edit-redo")); + redoAction.setText(Tr::tr("&Redo")); + redoAction.setDefaultKeySequence(QKeySequence::Redo); + redoAction.setCommandAttribute(Command::CA_UpdateText); + redoAction.setCommandDescription(Tr::tr("Redo")); + redoAction.setContainer(Constants::M_EDIT, Constants::G_EDIT_UNDOREDO); + redoAction.setEnabled(false); // Cut Action - icon = Icon::fromTheme("edit-cut"); - tmpaction = new QAction(icon, Tr::tr("Cu&t"), this); - cmd = ActionManager::registerAction(tmpaction, Constants::CUT); - cmd->setDefaultKeySequence(QKeySequence::Cut); - medit->addAction(cmd, Constants::G_EDIT_COPYPASTE); - tmpaction->setEnabled(false); + ActionBuilder cutAction(this, Constants::CUT); + cutAction.setText(Tr::tr("Cu&t")); + cutAction.setIcon(Icon::fromTheme("edit-cut")); + cutAction.setDefaultKeySequence(QKeySequence::Cut); + cutAction.setContainer(Constants::M_EDIT, Constants::G_EDIT_COPYPASTE); + cutAction.setEnabled(false); // Copy Action - icon = Icon::fromTheme("edit-copy"); - tmpaction = new QAction(icon, Tr::tr("&Copy"), this); - cmd = ActionManager::registerAction(tmpaction, Constants::COPY); - cmd->setDefaultKeySequence(QKeySequence::Copy); - medit->addAction(cmd, Constants::G_EDIT_COPYPASTE); - tmpaction->setEnabled(false); + ActionBuilder copyAction(this, Constants::COPY); + copyAction.setText(Tr::tr("&Copy")); + copyAction.setIcon(Icon::fromTheme("edit-copy")); + copyAction.setDefaultKeySequence(QKeySequence::Copy); + copyAction.setContainer(Constants::M_EDIT, Constants::G_EDIT_COPYPASTE); + copyAction.setEnabled(false); // Paste Action - icon = Icon::fromTheme("edit-paste"); - tmpaction = new QAction(icon, Tr::tr("&Paste"), this); - cmd = ActionManager::registerAction(tmpaction, Constants::PASTE); - cmd->setDefaultKeySequence(QKeySequence::Paste); - medit->addAction(cmd, Constants::G_EDIT_COPYPASTE); - tmpaction->setEnabled(false); + ActionBuilder pasteAction(this, Constants::PASTE); + pasteAction.setText(Tr::tr("&Paste")); + pasteAction.setIcon(Icon::fromTheme("edit-paste")); + pasteAction.setDefaultKeySequence(QKeySequence::Paste); + pasteAction.setContainer(Constants::M_EDIT, Constants::G_EDIT_COPYPASTE); + pasteAction.setEnabled(false); // Select All - icon = Icon::fromTheme("edit-select-all"); - tmpaction = new QAction(icon, Tr::tr("Select &All"), this); - cmd = ActionManager::registerAction(tmpaction, Constants::SELECTALL); - cmd->setDefaultKeySequence(QKeySequence::SelectAll); - medit->addAction(cmd, Constants::G_EDIT_SELECTALL); - tmpaction->setEnabled(false); + ActionBuilder selectAllAction(this, Constants::SELECTALL); + selectAllAction.setText(Tr::tr("Select &All")); + selectAllAction.setIcon(Icon::fromTheme("edit-select-all")); + selectAllAction.setDefaultKeySequence(QKeySequence::SelectAll); + selectAllAction.setContainer(Constants::M_EDIT, Constants::G_EDIT_SELECTALL); + selectAllAction.setEnabled(false); // Goto Action - icon = Icon::fromTheme("go-jump"); - tmpaction = new QAction(icon, Tr::tr("&Go to Line..."), this); - cmd = ActionManager::registerAction(tmpaction, Constants::GOTO); - cmd->setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+L"))); - medit->addAction(cmd, Constants::G_EDIT_OTHER); - tmpaction->setEnabled(false); + ActionBuilder gotoLineAction(this, Constants::GOTO); + gotoLineAction.setText(Tr::tr("&Go to Line...")); + gotoLineAction.setIcon(Icon::fromTheme("go-jump")); + gotoLineAction.setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+L"))); + gotoLineAction.setContainer(Constants::M_EDIT, Constants::G_EDIT_OTHER); + gotoLineAction.setEnabled(false); // Zoom In Action - icon = Icon::fromTheme("zoom-in"); - tmpaction = new QAction(icon, Tr::tr("Zoom In"), this); - cmd = ActionManager::registerAction(tmpaction, Constants::ZOOM_IN); - cmd->setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl++"))); - tmpaction->setEnabled(false); + ActionBuilder zoomInAction(this, Constants::ZOOM_IN); + zoomInAction.setText(Tr::tr("Zoom In")); + zoomInAction.setIcon(Icon::fromTheme("zoom-in")); + zoomInAction.setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl++"))); + zoomInAction.setEnabled(false); // Zoom Out Action - icon = Icon::fromTheme("zoom-out"); - tmpaction = new QAction(icon, Tr::tr("Zoom Out"), this); - cmd = ActionManager::registerAction(tmpaction, Constants::ZOOM_OUT); + ActionBuilder zoomOutAction(this, Constants::ZOOM_OUT); + zoomOutAction.setText(Tr::tr("Zoom Out")); + zoomOutAction.setIcon(Icon::fromTheme("zoom-out")); if (useMacShortcuts) - cmd->setDefaultKeySequences({QKeySequence(Tr::tr("Ctrl+-")), QKeySequence(Tr::tr("Ctrl+Shift+-"))}); + zoomOutAction.setDefaultKeySequences({QKeySequence(Tr::tr("Ctrl+-")), QKeySequence(Tr::tr("Ctrl+Shift+-"))}); else - cmd->setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+-"))); - tmpaction->setEnabled(false); + zoomOutAction.setDefaultKeySequence(Tr::tr("Ctrl+-")); + zoomOutAction.setEnabled(false); // Zoom Reset Action - icon = Icon::fromTheme("zoom-original"); - tmpaction = new QAction(icon, Tr::tr("Original Size"), this); - cmd = ActionManager::registerAction(tmpaction, Constants::ZOOM_RESET); - cmd->setDefaultKeySequence(QKeySequence(Core::useMacShortcuts ? Tr::tr("Meta+0") : Tr::tr("Ctrl+0"))); - tmpaction->setEnabled(false); + ActionBuilder zoomOriginalAction(this, Constants::ZOOM_RESET); + zoomOriginalAction.setText(Tr::tr("Original Size")); + zoomOriginalAction.setIcon(Icon::fromTheme("zoom-original")); + zoomOriginalAction.setDefaultKeySequence(Tr::tr("Meta+0"), Tr::tr("Ctrl+0")); + zoomOriginalAction.setEnabled(false); // Debug Qt Creator menu mtools->appendGroup(Constants::G_TOOLS_DEBUG); @@ -1768,21 +1757,21 @@ void ICorePrivate::registerDefaultActions() mtoolsdebug->menu()->setTitle(Tr::tr("Debug %1").arg(QGuiApplication::applicationDisplayName())); mtools->addMenu(mtoolsdebug, Constants::G_TOOLS_DEBUG); - m_loggerAction = new QAction(Tr::tr("Show Logs..."), this); - cmd = ActionManager::registerAction(m_loggerAction, Constants::LOGGER); - mtoolsdebug->addAction(cmd); - connect(m_loggerAction, &QAction::triggered, this, [] { LoggingViewer::showLoggingView(); }); + ActionBuilder loggerAction(this, Constants::LOGGER); + loggerAction.setText(Tr::tr("Show Logs...")); + loggerAction.setContainer(Constants::M_TOOLS_DEBUG); + loggerAction.setOnTriggered(this, &LoggingViewer::showLoggingView); // Options Action medit->appendGroup(Constants::G_EDIT_PREFERENCES); medit->addSeparator(Constants::G_EDIT_PREFERENCES); - m_optionsAction = new QAction(Tr::tr("Pr&eferences..."), this); - m_optionsAction->setMenuRole(QAction::PreferencesRole); - cmd = ActionManager::registerAction(m_optionsAction, Constants::OPTIONS); - cmd->setDefaultKeySequence(QKeySequence::Preferences); - medit->addAction(cmd, Constants::G_EDIT_PREFERENCES); - connect(m_optionsAction, &QAction::triggered, this, [] { ICore::showOptionsDialog(Id()); }); + ActionBuilder optionsAction(this, Constants::OPTIONS); + optionsAction.setText(Tr::tr("Pr&eferences...")); + optionsAction.setMenuRole(QAction::PreferencesRole); + optionsAction.setDefaultKeySequence(QKeySequence::Preferences); + optionsAction.setContainer(Constants::M_EDIT, Constants::G_EDIT_PREFERENCES); + optionsAction.setOnTriggered(this, [] { ICore::showOptionsDialog(Id()); }); mwindow->addSeparator(Constants::G_WINDOW_LIST); @@ -1790,7 +1779,7 @@ void ICorePrivate::registerDefaultActions() // Minimize Action QAction *minimizeAction = new QAction(Tr::tr("Minimize"), this); minimizeAction->setEnabled(false); // actual implementation in WindowSupport - cmd = ActionManager::registerAction(minimizeAction, Constants::MINIMIZE_WINDOW); + Command *cmd = ActionManager::registerAction(minimizeAction, Constants::MINIMIZE_WINDOW); cmd->setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+M"))); mwindow->addAction(cmd, Constants::G_WINDOW_SIZE); @@ -1805,7 +1794,7 @@ void ICorePrivate::registerDefaultActions() QAction *toggleFullScreenAction = new QAction(Tr::tr("Full Screen"), this); toggleFullScreenAction->setCheckable(!HostOsInfo::isMacHost()); toggleFullScreenAction->setEnabled(false); // actual implementation in WindowSupport - cmd = ActionManager::registerAction(toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN); + Command *cmd = ActionManager::registerAction(toggleFullScreenAction, Constants::TOGGLE_FULLSCREEN); cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Ctrl+Meta+F") : Tr::tr("Ctrl+Shift+F11"))); if (HostOsInfo::isMacHost()) cmd->setAttribute(Command::CA_UpdateText); @@ -1824,36 +1813,36 @@ void ICorePrivate::registerDefaultActions() } // Show Left Sidebar Action - m_toggleLeftSideBarAction = new QAction(Utils::Icons::TOGGLE_LEFT_SIDEBAR.icon(), - Tr::tr(Constants::TR_SHOW_LEFT_SIDEBAR), - this); - m_toggleLeftSideBarAction->setCheckable(true); - cmd = ActionManager::registerAction(m_toggleLeftSideBarAction, Constants::TOGGLE_LEFT_SIDEBAR); - cmd->setAttribute(Command::CA_UpdateText); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Ctrl+0") : Tr::tr("Alt+0"))); - connect(m_toggleLeftSideBarAction, &QAction::triggered, - this, [this](bool visible) { setSidebarVisible(visible, Side::Left); }); - ProxyAction *toggleLeftSideBarProxyAction = - ProxyAction::proxyActionWithIcon(cmd->action(), Utils::Icons::TOGGLE_LEFT_SIDEBAR_TOOLBAR.icon()); - m_toggleLeftSideBarButton->setDefaultAction(toggleLeftSideBarProxyAction); - mview->addAction(cmd, Constants::G_VIEW_VIEWS); - m_toggleLeftSideBarAction->setEnabled(false); + ActionBuilder toggleLeftSideBarAction(this, Constants::TOGGLE_LEFT_SIDEBAR); + toggleLeftSideBarAction.setIcon(Utils::Icons::TOGGLE_LEFT_SIDEBAR.icon()); + toggleLeftSideBarAction.setText(Tr::tr(Constants::TR_SHOW_LEFT_SIDEBAR)); + toggleLeftSideBarAction.setCheckable(true); + toggleLeftSideBarAction.setCommandAttribute(Command::CA_UpdateText); + toggleLeftSideBarAction.setDefaultKeySequence(Tr::tr("Ctrl+0"), Tr::tr("Alt+0")); + toggleLeftSideBarAction.setContainer(Constants::M_VIEW, Constants::G_VIEW_VIEWS); + toggleLeftSideBarAction.setOnTriggered(this, + [this](bool visible) { setSidebarVisible(visible, Side::Left); }); + + m_toggleLeftSideBarAction = toggleLeftSideBarAction.contextAction(); + m_toggleLeftSideBarButton->setDefaultAction(ProxyAction::proxyActionWithIcon( + toggleLeftSideBarAction.commandAction(), Utils::Icons::TOGGLE_LEFT_SIDEBAR_TOOLBAR.icon())); + m_toggleLeftSideBarButton->setEnabled(false); // Show Right Sidebar Action - m_toggleRightSideBarAction = new QAction(Utils::Icons::TOGGLE_RIGHT_SIDEBAR.icon(), - Tr::tr(Constants::TR_SHOW_RIGHT_SIDEBAR), - this); - m_toggleRightSideBarAction->setCheckable(true); - cmd = ActionManager::registerAction(m_toggleRightSideBarAction, Constants::TOGGLE_RIGHT_SIDEBAR); - cmd->setAttribute(Command::CA_UpdateText); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Ctrl+Shift+0") : Tr::tr("Alt+Shift+0"))); - connect(m_toggleRightSideBarAction, &QAction::triggered, - this, [this](bool visible) { setSidebarVisible(visible, Side::Right); }); - ProxyAction *toggleRightSideBarProxyAction = - ProxyAction::proxyActionWithIcon(cmd->action(), Utils::Icons::TOGGLE_RIGHT_SIDEBAR_TOOLBAR.icon()); - m_toggleRightSideBarButton->setDefaultAction(toggleRightSideBarProxyAction); - mview->addAction(cmd, Constants::G_VIEW_VIEWS); - m_toggleRightSideBarButton->setEnabled(false); + ActionBuilder toggleRightSideBarAction(this, Constants::TOGGLE_RIGHT_SIDEBAR); + toggleRightSideBarAction.setIcon(Utils::Icons::TOGGLE_RIGHT_SIDEBAR.icon()); + toggleRightSideBarAction.setText(Tr::tr(Constants::TR_SHOW_RIGHT_SIDEBAR)); + toggleRightSideBarAction.setCheckable(true); + toggleRightSideBarAction.setCommandAttribute(Command::CA_UpdateText); + toggleRightSideBarAction.setDefaultKeySequence(Tr::tr("Ctrl+Shift+0"), Tr::tr("Alt+Shift+0")); + toggleRightSideBarAction.setContainer(Constants::M_VIEW, Constants::G_VIEW_VIEWS); + toggleRightSideBarAction.setEnabled(false); + toggleRightSideBarAction.setOnTriggered(this, + [this](bool visible) { setSidebarVisible(visible, Side::Right); }); + + m_toggleRightSideBarAction = toggleRightSideBarAction.contextAction(); + m_toggleRightSideBarButton->setDefaultAction(ProxyAction::proxyActionWithIcon( + toggleRightSideBarAction.commandAction(), Utils::Icons::TOGGLE_RIGHT_SIDEBAR_TOOLBAR.icon())); // Show Menubar Action if (globalMenuBar() && !globalMenuBar()->isNativeMenuBar()) { @@ -1889,49 +1878,49 @@ void ICorePrivate::registerDefaultActions() mhelp->addSeparator(Constants::G_HELP_ABOUT); // About IDE Action - m_aboutIdeAction.setId(Constants::ABOUT_QTCREATOR); - m_aboutIdeAction.setIcon(Icon::fromTheme("help-about")); - m_aboutIdeAction.setText( - (HostOsInfo::isMacHost() ? Tr::tr("About &%1") : Tr::tr("About &%1...")) - .arg(QGuiApplication::applicationDisplayName())); - m_aboutIdeAction.setMenuRole(QAction::AboutRole); - m_aboutIdeAction.setContainer(Constants::M_HELP, Constants::G_HELP_ABOUT); - m_aboutIdeAction.setEnabled(true); - m_aboutIdeAction.setOnTriggered(this, [this] { aboutQtCreator(); }); + ActionBuilder aboutIdeAction(this, Constants::ABOUT_QTCREATOR); + aboutIdeAction.setIcon(Icon::fromTheme("help-about")); + aboutIdeAction.setText( + (HostOsInfo::isMacHost() ? Tr::tr("About &%1") : Tr::tr("About &%1...")) + .arg(QGuiApplication::applicationDisplayName())); + aboutIdeAction.setMenuRole(QAction::AboutRole); + aboutIdeAction.setContainer(Constants::M_HELP, Constants::G_HELP_ABOUT); + aboutIdeAction.setEnabled(true); + aboutIdeAction.setOnTriggered(this, [this] { aboutQtCreator(); }); // About Plugins Action - m_aboutPluginsAction.setId(Constants::ABOUT_PLUGINS); - m_aboutPluginsAction.setText(Tr::tr("About &Plugins...")); - m_aboutPluginsAction.setMenuRole(QAction::ApplicationSpecificRole); - m_aboutPluginsAction.setContainer(Constants::M_HELP, Constants::G_HELP_ABOUT); - m_aboutPluginsAction.setEnabled(true); - m_aboutPluginsAction.setOnTriggered(this, [this] { aboutPlugins(); }); + ActionBuilder aboutPluginsAction(this, Constants::ABOUT_PLUGINS); + aboutPluginsAction.setText(Tr::tr("About &Plugins...")); + aboutPluginsAction.setMenuRole(QAction::ApplicationSpecificRole); + aboutPluginsAction.setContainer(Constants::M_HELP, Constants::G_HELP_ABOUT); + aboutPluginsAction.setEnabled(true); + aboutPluginsAction.setOnTriggered(this, [this] { aboutPlugins(); }); // About Qt Action - // aboutQtAction.setId(Constants:: ABOUT_QT); + // ActionBuilder aboutQtAction(this, Constants:: ABOUT_QT); // aboutQtAction.setText(Tr::tr("About &Qt..."), this); // aboutQtAction.setContainer(Constants::M_HELP, Constants::G_HELP_ABOUT); // aboutQtAction.setEnabled(true); // aboutQtAction.setOnTriggered(this, &QApplication::aboutQt); // Change Log Action - m_changeLogAction.setId(Constants::CHANGE_LOG); - m_changeLogAction.setText(Tr::tr("Change Log...")); - m_changeLogAction.setMenuRole(QAction::ApplicationSpecificRole); - m_changeLogAction.setContainer(Constants::M_HELP, Constants::G_HELP_ABOUT); - m_changeLogAction.setEnabled(true); - m_changeLogAction.setOnTriggered(this, [this] { changeLog(); }); + ActionBuilder changeLogAction(this, Constants::CHANGE_LOG); + changeLogAction.setText(Tr::tr("Change Log...")); + changeLogAction.setMenuRole(QAction::ApplicationSpecificRole); + changeLogAction.setContainer(Constants::M_HELP, Constants::G_HELP_ABOUT); + changeLogAction.setEnabled(true); + changeLogAction.setOnTriggered(this, [this] { changeLog(); }); // Contact - m_contactAction.setId("QtCreator.Contact"); - m_contactAction.setText(Tr::tr("Contact...")); - m_contactAction.setContainer(Constants::M_HELP, Constants::G_HELP_ABOUT); - m_contactAction.setEnabled(true); - m_contactAction.setOnTriggered(this, [this] { contact(); }); + ActionBuilder contactAction(this, "QtCreator.Contact"); + contactAction.setText(Tr::tr("Contact...")); + contactAction.setContainer(Constants::M_HELP, Constants::G_HELP_ABOUT); + contactAction.setEnabled(true); + contactAction.setOnTriggered(this, [this] { contact(); }); // About sep if (!HostOsInfo::isMacHost()) { // doesn't have the "About" actions in the Help menu - tmpaction = new QAction(this); + auto tmpaction = new QAction(this); tmpaction->setSeparator(true); cmd = ActionManager::registerAction(tmpaction, "QtCreator.Help.Sep.About"); mhelp->addAction(cmd, Constants::G_HELP_ABOUT); diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.cpp b/src/plugins/genericprojectmanager/genericprojectplugin.cpp index 6d3ab2eaf5c..9db1af67539 100644 --- a/src/plugins/genericprojectmanager/genericprojectplugin.cpp +++ b/src/plugins/genericprojectmanager/genericprojectplugin.cpp @@ -39,8 +39,6 @@ public: ProjectFilesFactory projectFilesFactory; GenericMakeStepFactory makeStepFactory; GenericBuildConfigurationFactory buildConfigFactory; - Action editAction; - Action removeDirAction; }; GenericProjectPlugin::~GenericProjectPlugin() @@ -59,7 +57,7 @@ GenericProjectPluginPrivate::GenericProjectPluginPrivate() IWizardFactory::registerFactoryCreator([] { return new GenericProjectWizard; }); - editAction.setId("GenericProjectManager.EditFiles"); + ActionBuilder editAction(this, "GenericProjectManager.EditFiles"); editAction.setContext(Constants::GENERICPROJECT_ID); editAction.setText(Tr::tr("Edit Files...")); editAction.setCommandAttribute(Command::CA_Hide); @@ -69,7 +67,7 @@ GenericProjectPluginPrivate::GenericProjectPluginPrivate() genericProject->editFilesTriggered(); }); - removeDirAction.setId("GenericProject.RemoveDir"); + ActionBuilder removeDirAction(this, "GenericProject.RemoveDir"); removeDirAction.setContext(PEC::C_PROJECT_TREE); removeDirAction.setText(Tr::tr("Remove Directory")); removeDirAction.setContainer(PEC::M_FOLDERCONTEXT, PEC::G_FOLDER_OTHER); diff --git a/src/plugins/texteditor/texteditorplugin.cpp b/src/plugins/texteditor/texteditorplugin.cpp index cc7ad90cc83..95491ba24ae 100644 --- a/src/plugins/texteditor/texteditorplugin.cpp +++ b/src/plugins/texteditor/texteditorplugin.cpp @@ -87,12 +87,12 @@ public: BookmarkViewFactory m_bookmarkViewFactory{&m_bookmarkManager}; Menu m_bookmarkMenu; - Action m_toggleAction; - Action m_editAction; - Action m_prevAction; - Action m_nextAction; - Action m_docPrevAction; - Action m_docNextAction; + QAction *m_toggleAction = nullptr; + QAction *m_editAction = nullptr; + QAction *m_prevAction = nullptr; + QAction *m_nextAction = nullptr; + QAction *m_docPrevAction = nullptr; + QAction *m_docNextAction = nullptr; QAction m_editBookmarkAction{Tr::tr("Edit Bookmark")}; QAction m_bookmarkMarginAction{Tr::tr("Toggle Bookmark")}; @@ -122,25 +122,27 @@ TextEditorPluginPrivate::TextEditorPluginPrivate() m_bookmarkMenu.setTitle(Tr::tr("&Bookmarks")); m_bookmarkMenu.setContainer(Core::Constants::M_TOOLS); - m_toggleAction.setId("Bookmarks.Toggle"); - m_toggleAction.setContext(editorManagerContext); - m_toggleAction.setText(Tr::tr("Toggle Bookmark")); - m_toggleAction.setDefaultKeySequence(Tr::tr("Meta+M"), Tr::tr("Ctrl+M")); - m_toggleAction.setTouchBarIcon(Icons::MACOS_TOUCHBAR_BOOKMARK.icon()); - m_toggleAction.setContainer(bookmarkMenuId); - m_toggleAction.setOnTriggered(this, [this] { + ActionBuilder toggleAction(this, "Bookmarks.Toggle"); + toggleAction.setContext(editorManagerContext); + toggleAction.setText(Tr::tr("Toggle Bookmark")); + toggleAction.setDefaultKeySequence(Tr::tr("Meta+M"), Tr::tr("Ctrl+M")); + toggleAction.setTouchBarIcon(Icons::MACOS_TOUCHBAR_BOOKMARK.icon()); + toggleAction.setContainer(bookmarkMenuId); + toggleAction.bindContextAction(&m_toggleAction); + toggleAction.setOnTriggered(this, [this] { IEditor *editor = EditorManager::currentEditor(); auto widget = TextEditorWidget::fromEditor(editor); if (widget && editor && !editor->document()->isTemporary()) m_bookmarkManager.toggleBookmark(editor->document()->filePath(), editor->currentLine()); }); - m_editAction.setId("Bookmarks.Edit"); - m_editAction.setContext(editorManagerContext); - m_editAction.setText(Tr::tr("Edit Bookmark")); - m_editAction.setDefaultKeySequence(Tr::tr("Meta+Shift+M"), Tr::tr("Ctrl+Shift+M")); - m_editAction.setContainer(bookmarkMenuId); - m_editAction.setOnTriggered(this, [this] { + ActionBuilder editAction(this, "Bookmarks.Edit"); + editAction.setContext(editorManagerContext); + editAction.setText(Tr::tr("Edit Bookmark")); + editAction.setDefaultKeySequence(Tr::tr("Meta+Shift+M"), Tr::tr("Ctrl+Shift+M")); + editAction.setContainer(bookmarkMenuId); + editAction.bindContextAction(&m_editAction); + editAction.setOnTriggered(this, [this] { IEditor *editor = EditorManager::currentEditor(); auto widget = TextEditorWidget::fromEditor(editor); if (widget && editor && !editor->document()->isTemporary()) { @@ -154,37 +156,41 @@ TextEditorPluginPrivate::TextEditorPluginPrivate() m_bookmarkMenu.addSeparator(); - m_prevAction.setId(BOOKMARKS_PREV_ACTION); - m_prevAction.setContext(editorManagerContext); - m_prevAction.setText(Tr::tr("Previous Bookmark")); - m_prevAction.setDefaultKeySequence(Tr::tr("Meta+,"), Tr::tr("Ctrl+,")); - m_prevAction.setContainer(bookmarkMenuId); - m_prevAction.setIcon(Icons::PREV_TOOLBAR.icon()); - m_prevAction.setIconVisibleInMenu(false); - m_prevAction.setOnTriggered(this, [this] { m_bookmarkManager.prev(); }); + ActionBuilder prevAction(this, BOOKMARKS_PREV_ACTION); + prevAction.setContext(editorManagerContext); + prevAction.setText(Tr::tr("Previous Bookmark")); + prevAction.setDefaultKeySequence(Tr::tr("Meta+,"), Tr::tr("Ctrl+,")); + prevAction.setContainer(bookmarkMenuId); + prevAction.setIcon(Icons::PREV_TOOLBAR.icon()); + prevAction.setIconVisibleInMenu(false); + prevAction.bindContextAction(&m_prevAction); + prevAction.setOnTriggered(this, [this] { m_bookmarkManager.prev(); }); - m_nextAction.setId(BOOKMARKS_NEXT_ACTION); - m_nextAction.setContext(editorManagerContext); - m_nextAction.setText(Tr::tr("Next Bookmark")); - m_nextAction.setIcon(Icons::NEXT_TOOLBAR.icon()); - m_nextAction.setIconVisibleInMenu(false); - m_nextAction.setDefaultKeySequence(Tr::tr("Meta+."), Tr::tr("Ctrl+.")); - m_nextAction.setContainer(bookmarkMenuId); - m_nextAction.setOnTriggered(this, [this] { m_bookmarkManager.next(); }); + ActionBuilder nextAction(this, BOOKMARKS_NEXT_ACTION); + nextAction.setContext(editorManagerContext); + nextAction.setText(Tr::tr("Next Bookmark")); + nextAction.setIcon(Icons::NEXT_TOOLBAR.icon()); + nextAction.setIconVisibleInMenu(false); + nextAction.setDefaultKeySequence(Tr::tr("Meta+."), Tr::tr("Ctrl+.")); + nextAction.setContainer(bookmarkMenuId); + nextAction.bindContextAction(&m_nextAction); + nextAction.setOnTriggered(this, [this] { m_bookmarkManager.next(); }); m_bookmarkMenu.addSeparator(); - m_docPrevAction.setId("Bookmarks.PreviousDocument"); - m_docPrevAction.setContext(editorManagerContext); - m_docPrevAction.setText(Tr::tr("Previous Bookmark in Document")); - m_docPrevAction.setContainer(bookmarkMenuId); - m_docPrevAction.setOnTriggered(this, [this] { m_bookmarkManager.prevInDocument(); }); + ActionBuilder docPrevAction(this, "Bookmarks.PreviousDocument"); + docPrevAction.setContext(editorManagerContext); + docPrevAction.setText(Tr::tr("Previous Bookmark in Document")); + docPrevAction.setContainer(bookmarkMenuId); + docPrevAction.bindContextAction(&m_docPrevAction); + docPrevAction.setOnTriggered(this, [this] { m_bookmarkManager.prevInDocument(); }); - m_docNextAction.setId("Bookmarks.NextDocument"); - m_docNextAction.setContext(Core::Constants::C_EDITORMANAGER); - m_docNextAction.setText(Tr::tr("Next Bookmark in Document")); - m_docNextAction.setContainer(bookmarkMenuId); - m_docNextAction.setOnTriggered(this, [this] { m_bookmarkManager.nextInDocument(); }); + ActionBuilder docNextAction(this, "Bookmarks.NextDocument"); + docNextAction.setContext(Core::Constants::C_EDITORMANAGER); + docNextAction.setText(Tr::tr("Next Bookmark in Document")); + docNextAction.setContainer(bookmarkMenuId); + docNextAction.bindContextAction(&m_docNextAction); + docNextAction.setOnTriggered(this, [this] { m_bookmarkManager.nextInDocument(); }); connect(&m_editBookmarkAction, &QAction::triggered, this, [this] { m_bookmarkManager.editByFileAndLine(m_marginActionFileName, m_marginActionLineNumber); @@ -199,7 +205,7 @@ TextEditorPluginPrivate::TextEditorPluginPrivate() }); ActionContainer *touchBar = ActionManager::actionContainer(Core::Constants::TOUCH_BAR); - touchBar->addAction(m_toggleAction.command(), Core::Constants::G_TOUCHBAR_EDITOR); + touchBar->addAction(toggleAction.command(), Core::Constants::G_TOUCHBAR_EDITOR); // EditorManager connect(EditorManager::instance(), &EditorManager::editorAboutToClose, @@ -213,12 +219,12 @@ void TextEditorPluginPrivate::updateActions(bool enableToggle, int state) const bool hasbm = state >= BookmarkManager::HasBookMarks; const bool hasdocbm = state == BookmarkManager::HasBookmarksInDocument; - m_toggleAction.setEnabled(enableToggle); - m_editAction.setEnabled(enableToggle); - m_prevAction.setEnabled(hasbm); - m_nextAction.setEnabled(hasbm); - m_docPrevAction.setEnabled(hasdocbm); - m_docNextAction.setEnabled(hasdocbm); + m_toggleAction->setEnabled(enableToggle); + m_editAction->setEnabled(enableToggle); + m_prevAction->setEnabled(hasbm); + m_nextAction->setEnabled(hasbm); + m_docPrevAction->setEnabled(hasdocbm); + m_docNextAction->setEnabled(hasdocbm); } void TextEditorPluginPrivate::editorOpened(IEditor *editor) From 812b3e2ee5bccc96937332e541043f339fc30a24 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 10 Nov 2023 15:00:12 +0100 Subject: [PATCH 0150/1546] Macros: Remove Q_OBJECT macro from some classes that don't need it Plus some code cosmetics. Change-Id: Ifa9c4e7322ae7a2d5c1480f7afc58f020efcbc1c Reviewed-by: Christian Stenger --- src/plugins/macros/actionmacrohandler.cpp | 8 +++----- src/plugins/macros/actionmacrohandler.h | 8 ++------ src/plugins/macros/findmacrohandler.cpp | 6 ++++-- src/plugins/macros/findmacrohandler.h | 11 ++++------- src/plugins/macros/imacrohandler.h | 16 ++++++---------- src/plugins/macros/texteditormacrohandler.cpp | 5 +++-- src/plugins/macros/texteditormacrohandler.h | 8 ++------ 7 files changed, 24 insertions(+), 38 deletions(-) diff --git a/src/plugins/macros/actionmacrohandler.cpp b/src/plugins/macros/actionmacrohandler.cpp index 0dc4fd95773..c6510171d82 100644 --- a/src/plugins/macros/actionmacrohandler.cpp +++ b/src/plugins/macros/actionmacrohandler.cpp @@ -21,10 +21,9 @@ using namespace Core; using namespace Utils; -namespace Macros { -namespace Internal { +namespace Macros::Internal { -static const char EVENTNAME[] = "Action"; +const char EVENTNAME[] = "Action"; static quint8 ACTIONNAME = 0; ActionMacroHandler::ActionMacroHandler() @@ -82,5 +81,4 @@ void ActionMacroHandler::addCommand(Id id) registerCommand(id); } -} // namespace Internal -} // namespace Macros +} // namespace Macros::Internal diff --git a/src/plugins/macros/actionmacrohandler.h b/src/plugins/macros/actionmacrohandler.h index 32bd1c70421..f8251f03b70 100644 --- a/src/plugins/macros/actionmacrohandler.h +++ b/src/plugins/macros/actionmacrohandler.h @@ -9,13 +9,10 @@ #include -namespace Macros { -namespace Internal { +namespace Macros::Internal { class ActionMacroHandler : public IMacroHandler { - Q_OBJECT - public: ActionMacroHandler(); @@ -31,5 +28,4 @@ private: QSet m_commandIds; }; -} // namespace Internal -} // namespace Macros +} // namespace Macros::Internal diff --git a/src/plugins/macros/findmacrohandler.cpp b/src/plugins/macros/findmacrohandler.cpp index 878854e7b17..319a7cfc49f 100644 --- a/src/plugins/macros/findmacrohandler.cpp +++ b/src/plugins/macros/findmacrohandler.cpp @@ -13,10 +13,10 @@ #include -using namespace Macros; -using namespace Macros::Internal; using namespace Utils; +namespace Macros::Internal { + static const char EVENTNAME[] = "Find"; static const quint8 TYPE = 0; static const quint8 BEFORE = 1; @@ -202,3 +202,5 @@ void FindMacroHandler::startRecording(Macro* macro) if (current) changeEditor(current); } + +} // namespace Macros::Internal diff --git a/src/plugins/macros/findmacrohandler.h b/src/plugins/macros/findmacrohandler.h index ef157051c75..32469ebd27e 100644 --- a/src/plugins/macros/findmacrohandler.h +++ b/src/plugins/macros/findmacrohandler.h @@ -6,21 +6,19 @@ #include "imacrohandler.h" #include + #include namespace Core { class IEditor; } -namespace Macros { -namespace Internal { +namespace Macros::Internal { class FindMacroHandler : public IMacroHandler { - Q_OBJECT - public: FindMacroHandler(); - void startRecording(Macro* macro) override; + void startRecording(Macro *macro) override; bool canExecuteEvent(const MacroEvent ¯oEvent) override; bool executeEvent(const MacroEvent ¯oEvent) override; @@ -36,5 +34,4 @@ private: void changeEditor(Core::IEditor *editor); }; -} // namespace Internal -} // namespace Macros +} // namespace Macros::Internal diff --git a/src/plugins/macros/imacrohandler.h b/src/plugins/macros/imacrohandler.h index 53eb744fc16..fcaf743cd12 100644 --- a/src/plugins/macros/imacrohandler.h +++ b/src/plugins/macros/imacrohandler.h @@ -5,26 +5,23 @@ #include -namespace Macros { -namespace Internal { +namespace Macros::Internal { class Macro; class MacroEvent; class MacroManager; -class IMacroHandler: public QObject +class IMacroHandler : public QObject { - Q_OBJECT - public: - virtual void startRecording(Macro* macro); - virtual void endRecordingMacro(Macro* macro); + virtual void startRecording(Macro *macro); + virtual void endRecordingMacro(Macro *macro); virtual bool canExecuteEvent(const MacroEvent ¯oEvent) = 0; virtual bool executeEvent(const MacroEvent ¯oEvent) = 0; protected: - void addMacroEvent(const MacroEvent& event); + void addMacroEvent(const MacroEvent &event); void setCurrentMacro(Macro *macro); @@ -36,5 +33,4 @@ private: Macro *m_currentMacro = nullptr; }; -} // namespace Internal -} // namespace Macros +} // namespace Macros::Internal diff --git a/src/plugins/macros/texteditormacrohandler.cpp b/src/plugins/macros/texteditormacrohandler.cpp index 1125b1e8cde..1147c02b0db 100644 --- a/src/plugins/macros/texteditormacrohandler.cpp +++ b/src/plugins/macros/texteditormacrohandler.cpp @@ -18,8 +18,7 @@ #include #include -using namespace Macros; -using namespace Macros::Internal; +namespace Macros::Internal { static const char KEYEVENTNAME[] = "TextEditorKey"; static quint8 TEXT = 0; @@ -118,3 +117,5 @@ void TextEditorMacroHandler::closeEditor(Core::IEditor *editor) m_currentEditor->widget()->removeEventFilter(this); m_currentEditor = nullptr; } + +} // namespace Macro::Internal diff --git a/src/plugins/macros/texteditormacrohandler.h b/src/plugins/macros/texteditormacrohandler.h index 57a9e1982bd..60e742fb325 100644 --- a/src/plugins/macros/texteditormacrohandler.h +++ b/src/plugins/macros/texteditormacrohandler.h @@ -9,13 +9,10 @@ namespace Core { class IEditor; } namespace TextEditor { class BaseTextEditor; } -namespace Macros { -namespace Internal { +namespace Macros::Internal { class TextEditorMacroHandler : public IMacroHandler { - Q_OBJECT - public: TextEditorMacroHandler(); @@ -34,5 +31,4 @@ private: TextEditor::BaseTextEditor *m_currentEditor = nullptr; }; -} // namespace Internal -} // namespace Macros +} // namespace Macros::Internal From 82c77b1304c66267f2fbf40dd7470769454c3f82 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 10 Nov 2023 12:12:18 +0100 Subject: [PATCH 0151/1546] AutoTest: Use ActionBuilder Change-Id: If109c8b6916bb59ec5c7d58b50dc9a61ca1b4a96 Reviewed-by: Christian Stenger --- src/plugins/autotest/autotestplugin.cpp | 194 ++++++++---------- .../actionmanager/actionmanager.cpp | 5 + .../coreplugin/actionmanager/actionmanager.h | 1 + 3 files changed, 94 insertions(+), 106 deletions(-) diff --git a/src/plugins/autotest/autotestplugin.cpp b/src/plugins/autotest/autotestplugin.cpp index 67b264dcd00..7a1da0edc22 100644 --- a/src/plugins/autotest/autotestplugin.cpp +++ b/src/plugins/autotest/autotestplugin.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include #include @@ -191,90 +190,78 @@ void AutotestPluginPrivate::initializeMenuEntries() menu->menu()->setTitle(Tr::tr("&Tests")); menu->setOnAllDisabledBehavior(ActionContainer::Show); - QAction *action = new QAction(Tr::tr("Run &All Tests"), this); - action->setIcon(Utils::Icons::RUN_SMALL.icon()); - action->setToolTip(Tr::tr("Run All Tests")); - Command *command = ActionManager::registerAction(action, Constants::ACTION_RUN_ALL_ID); - command->setDefaultKeySequence( - QKeySequence(useMacShortcuts ? Tr::tr("Ctrl+Meta+T, Ctrl+Meta+A") : Tr::tr("Alt+Shift+T,Alt+A"))); - connect(action, &QAction::triggered, - std::bind(&AutotestPluginPrivate::onRunAllTriggered, this, TestRunMode::Run)); - action->setEnabled(false); - menu->addAction(command); + ActionBuilder runAll(this, Constants::ACTION_RUN_ALL_ID); + runAll.setText(Tr::tr("Run &All Tests")); + runAll.setIcon(Utils::Icons::RUN_SMALL.icon()); + runAll.setToolTip(Tr::tr("Run All Tests")); + runAll.setDefaultKeySequence(Tr::tr("Ctrl+Meta+T, Ctrl+Meta+A"), Tr::tr("Alt+Shift+T,Alt+A")); + runAll.setContainer(Constants::MENU_ID); + runAll.setEnabled(false); + runAll.setOnTriggered(this, [this] { onRunAllTriggered(TestRunMode::Run); }); - action = new QAction(Tr::tr("Run All Tests Without Deployment"), this); - action->setIcon(Utils::Icons::RUN_SMALL.icon()); - action->setToolTip(Tr::tr("Run All Tests Without Deployment")); - command = ActionManager::registerAction(action, Constants::ACTION_RUN_ALL_NODEPLOY_ID); - command->setDefaultKeySequence( - QKeySequence(useMacShortcuts ? Tr::tr("Ctrl+Meta+T, Ctrl+Meta+E") : Tr::tr("Alt+Shift+T,Alt+E"))); - connect(action, &QAction::triggered, - std::bind(&AutotestPluginPrivate::onRunAllTriggered, this, TestRunMode::RunWithoutDeploy)); - action->setEnabled(false); - menu->addAction(command); + ActionBuilder runAllNoDeploy(this, Constants::ACTION_RUN_ALL_NODEPLOY_ID); + runAllNoDeploy.setText(Tr::tr("Run All Tests Without Deployment")); + runAllNoDeploy.setIcon(Utils::Icons::RUN_SMALL.icon()); + runAllNoDeploy.setToolTip(Tr::tr("Run All Tests Without Deployment")); + runAllNoDeploy.setDefaultKeySequence(Tr::tr("Ctrl+Meta+T, Ctrl+Meta+E"), Tr::tr("Alt+Shift+T,Alt+E")); + runAllNoDeploy.setContainer(Constants::MENU_ID); + runAllNoDeploy.setEnabled(false); + runAllNoDeploy.setOnTriggered(this, [this] { onRunAllTriggered(TestRunMode::RunWithoutDeploy); }); - action = new QAction(Tr::tr("&Run Selected Tests"), this); - action->setIcon(Utils::Icons::RUN_SELECTED.icon()); - action->setToolTip(Tr::tr("Run Selected Tests")); - command = ActionManager::registerAction(action, Constants::ACTION_RUN_SELECTED_ID); - command->setDefaultKeySequence( - QKeySequence(useMacShortcuts ? Tr::tr("Ctrl+Meta+T, Ctrl+Meta+R") : Tr::tr("Alt+Shift+T,Alt+R"))); - connect(action, &QAction::triggered, - std::bind(&AutotestPluginPrivate::onRunSelectedTriggered, this, TestRunMode::Run)); - action->setEnabled(false); - menu->addAction(command); + ActionBuilder runSelected(this, Constants::ACTION_RUN_SELECTED_ID); + runSelected.setText(Tr::tr("&Run Selected Tests")); + runSelected.setIcon(Utils::Icons::RUN_SELECTED.icon()); + runSelected.setToolTip(Tr::tr("Run Selected Tests")); + runSelected.setDefaultKeySequence(Tr::tr("Ctrl+Meta+T, Ctrl+Meta+R"), Tr::tr("Alt+Shift+T,Alt+R")); + runSelected.setContainer(Constants::MENU_ID); + runSelected.setEnabled(false); + runSelected.setOnTriggered(this, [this] { onRunSelectedTriggered(TestRunMode::Run); }); - action = new QAction(Tr::tr("&Run Selected Tests Without Deployment"), this); - action->setIcon(Utils::Icons::RUN_SELECTED.icon()); - action->setToolTip(Tr::tr("Run Selected Tests Without Deployment")); - command = ActionManager::registerAction(action, Constants::ACTION_RUN_SELECTED_NODEPLOY_ID); - command->setDefaultKeySequence( - QKeySequence(useMacShortcuts ? Tr::tr("Ctrl+Meta+T, Ctrl+Meta+W") : Tr::tr("Alt+Shift+T,Alt+W"))); - connect(action, &QAction::triggered, - std::bind(&AutotestPluginPrivate::onRunSelectedTriggered, this, TestRunMode::RunWithoutDeploy)); - action->setEnabled(false); - menu->addAction(command); + ActionBuilder runSelectedNoDeploy(this, Constants::ACTION_RUN_SELECTED_NODEPLOY_ID); + runSelectedNoDeploy.setText(Tr::tr("&Run Selected Tests Without Deployment")); + runSelectedNoDeploy.setIcon(Utils::Icons::RUN_SELECTED.icon()); + runSelectedNoDeploy.setToolTip(Tr::tr("Run Selected Tests Without Deployment")); + runSelectedNoDeploy.setDefaultKeySequence(Tr::tr("Ctrl+Meta+T, Ctrl+Meta+W"), Tr::tr("Alt+Shift+T,Alt+W")); + runSelectedNoDeploy.setContainer(Constants::MENU_ID); + runSelectedNoDeploy.setEnabled(false); + runSelectedNoDeploy.setOnTriggered(this, [this] { onRunSelectedTriggered(TestRunMode::RunWithoutDeploy); }); - action = new QAction(Tr::tr("Run &Failed Tests"), this); - action->setIcon(Icons::RUN_FAILED.icon()); - action->setToolTip(Tr::tr("Run Failed Tests")); - command = ActionManager::registerAction(action, Constants::ACTION_RUN_FAILED_ID); - command->setDefaultKeySequence( - useMacShortcuts ? Tr::tr("Ctrl+Meta+T, Ctrl+Meta+F") : Tr::tr("Alt+Shift+T,Alt+F")); - connect(action, &QAction::triggered, this, &AutotestPluginPrivate::onRunFailedTriggered); - action->setEnabled(false); - menu->addAction(command); + ActionBuilder runFailed(this, Constants::ACTION_RUN_FAILED_ID); + runFailed.setText(Tr::tr("Run &Failed Tests")); + runFailed.setIcon(Icons::RUN_FAILED.icon()); + runFailed.setToolTip(Tr::tr("Run Failed Tests")); + runFailed.setDefaultKeySequence(Tr::tr("Ctrl+Meta+T, Ctrl+Meta+F"), Tr::tr("Alt+Shift+T,Alt+F")); + runFailed.setContainer(Constants::MENU_ID); + runFailed.setEnabled(false); + runFailed.setOnTriggered(this, [this] { onRunFailedTriggered(); }); - action = new QAction(Tr::tr("Run Tests for &Current File"), this); - action->setIcon(Utils::Icons::RUN_FILE.icon()); - action->setToolTip(Tr::tr("Run Tests for Current File")); - command = ActionManager::registerAction(action, Constants::ACTION_RUN_FILE_ID); - command->setDefaultKeySequence( - QKeySequence(useMacShortcuts ? Tr::tr("Ctrl+Meta+T, Ctrl+Meta+C") : Tr::tr("Alt+Shift+T,Alt+C"))); - connect(action, &QAction::triggered, this, &AutotestPluginPrivate::onRunFileTriggered); - action->setEnabled(false); - menu->addAction(command); + ActionBuilder runCurrent(this, Constants::ACTION_RUN_FILE_ID); + runCurrent.setText(Tr::tr("Run Tests for &Current File")); + runCurrent.setIcon(Utils::Icons::RUN_FILE.icon()); + runCurrent.setToolTip(Tr::tr("Run Tests for Current File")); + runCurrent.setDefaultKeySequence(Tr::tr("Ctrl+Meta+T, Ctrl+Meta+C"), Tr::tr("Alt+Shift+T,Alt+C")); + runCurrent.setContainer(Constants::MENU_ID); + runCurrent.setEnabled(false); + runCurrent.setOnTriggered(this, [this] { onRunFileTriggered(); }); - action = new QAction(Tr::tr("Disable Temporarily"), this); - action->setToolTip(Tr::tr("Disable scanning and other actions until explicitly rescanning, " - "re-enabling, or restarting Qt Creator.")); - action->setCheckable(true); - command = ActionManager::registerAction(action, Constants::ACTION_DISABLE_TMP); - connect(action, &QAction::triggered, this, &AutotestPluginPrivate::onDisableTemporarily); - menu->addAction(command); + ActionBuilder disableTemp(this, Constants::ACTION_DISABLE_TMP); + disableTemp.setText(Tr::tr("Disable Temporarily")); + disableTemp.setToolTip(Tr::tr("Disable scanning and other actions until explicitly rescanning, " + "re-enabling, or restarting Qt Creator.")); + disableTemp.setCheckable(true); + disableTemp.setContainer(Constants::MENU_ID); + disableTemp.setOnTriggered(this, [this](bool on) { onDisableTemporarily(on); }); - action = new QAction(Tr::tr("Re&scan Tests"), this); - command = ActionManager::registerAction(action, Constants::ACTION_SCAN_ID); - command->setDefaultKeySequence( - QKeySequence(useMacShortcuts ? Tr::tr("Ctrl+Meta+T, Ctrl+Meta+S") : Tr::tr("Alt+Shift+T,Alt+S"))); - - connect(action, &QAction::triggered, this, [] { + ActionBuilder rescan(this, Constants::ACTION_SCAN_ID); + rescan.setText(Tr::tr("Re&scan Tests")); + rescan.setDefaultKeySequence(Tr::tr("Ctrl+Meta+T, Ctrl+Meta+S"), Tr::tr("Alt+Shift+T,Alt+S")); + rescan.setContainer(Constants::MENU_ID); + rescan.setOnTriggered(this, [] { if (dd->m_testCodeParser.state() == TestCodeParser::DisabledTemporarily) dd->onDisableTemporarily(false); // Rescan Test should explicitly re-enable else dd->m_testCodeParser.updateTestTree(); }); - menu->addAction(command); ActionContainer *toolsMenu = ActionManager::actionContainer(Core::Constants::M_TOOLS); toolsMenu->addMenu(menu); @@ -306,47 +293,42 @@ void AutotestPlugin::extensionsInitialized() if (!contextMenu) // if QC is started without CppEditor plugin return; - ActionContainer * const runTestMenu = ActionManager::createMenu("Autotest.TestUnderCursor"); + const Id menuId = "Autotest.TestUnderCursor"; + ActionContainer * const runTestMenu = ActionManager::createMenu(menuId); runTestMenu->menu()->setTitle(Tr::tr("Run Test Under Cursor")); contextMenu->addSeparator(); contextMenu->addMenu(runTestMenu); contextMenu->addSeparator(); - QAction *action = new QAction(Tr::tr("&Run Test"), this); - action->setEnabled(false); - action->setIcon(Utils::Icons::RUN_SMALL.icon()); + ActionBuilder runTest(this, Constants::ACTION_RUN_UCURSOR); + runTest.setText(Tr::tr("&Run Test")); + runTest.setEnabled(false); + runTest.setIcon(Utils::Icons::RUN_SMALL.icon()); + runTest.setContainer(menuId); + runTest.setOnTriggered([] { dd->onRunUnderCursorTriggered(TestRunMode::Run); }); - Command *command = ActionManager::registerAction(action, Constants::ACTION_RUN_UCURSOR); - connect(action, &QAction::triggered, - std::bind(&AutotestPluginPrivate::onRunUnderCursorTriggered, dd, TestRunMode::Run)); - runTestMenu->addAction(command); + ActionBuilder runTestNoDeploy(this, Constants::ACTION_RUN_UCURSOR_NODEPLOY); + runTestNoDeploy.setText(Tr::tr("Run Test Without Deployment")); + runTestNoDeploy.setIcon(Utils::Icons::RUN_SMALL.icon()); + runTestNoDeploy.setEnabled(false); + runTestNoDeploy.setContainer(menuId); + runTestNoDeploy.setOnTriggered( + [] { dd->onRunUnderCursorTriggered(TestRunMode::RunWithoutDeploy); }); - action = new QAction(Tr::tr("Run Test Without Deployment"), this); - action->setEnabled(false); - action->setIcon(Utils::Icons::RUN_SMALL.icon()); + ActionBuilder debugTest(this, Constants::ACTION_RUN_DBG_UCURSOR); + debugTest.setText(Tr::tr("&Debug Test")); + debugTest.setIcon(ProjectExplorer::Icons::DEBUG_START_SMALL.icon()); + debugTest.setEnabled(false); + debugTest.setContainer(menuId); + debugTest.setOnTriggered([] { dd->onRunUnderCursorTriggered(TestRunMode::Debug); }); - command = ActionManager::registerAction(action, Constants::ACTION_RUN_UCURSOR_NODEPLOY); - connect(action, &QAction::triggered, - std::bind(&AutotestPluginPrivate::onRunUnderCursorTriggered, dd, TestRunMode::RunWithoutDeploy)); - runTestMenu->addAction(command); - - action = new QAction(Tr::tr("&Debug Test"), this); - action->setEnabled(false); - action->setIcon(ProjectExplorer::Icons::DEBUG_START_SMALL.icon()); - - command = ActionManager::registerAction(action, Constants::ACTION_RUN_DBG_UCURSOR); - connect(action, &QAction::triggered, - std::bind(&AutotestPluginPrivate::onRunUnderCursorTriggered, dd, TestRunMode::Debug)); - runTestMenu->addAction(command); - - action = new QAction(Tr::tr("Debug Test Without Deployment"), this); - action->setEnabled(false); - action->setIcon(ProjectExplorer::Icons::DEBUG_START_SMALL.icon()); - - command = ActionManager::registerAction(action, Constants::ACTION_RUN_DBG_UCURSOR_NODEPLOY); - connect(action, &QAction::triggered, - std::bind(&AutotestPluginPrivate::onRunUnderCursorTriggered, dd, TestRunMode::DebugWithoutDeploy)); - runTestMenu->addAction(command); + ActionBuilder debugTestNoDeploy(this, Constants::ACTION_RUN_DBG_UCURSOR_NODEPLOY); + debugTestNoDeploy.setText(Tr::tr("Debug Test Without Deployment")); + debugTestNoDeploy.setIcon(ProjectExplorer::Icons::DEBUG_START_SMALL.icon()); + debugTestNoDeploy.setEnabled(false); + debugTestNoDeploy.setContainer(menuId); + debugTestNoDeploy.setOnTriggered( + [] { dd->onRunUnderCursorTriggered(TestRunMode::DebugWithoutDeploy); }); } ExtensionSystem::IPlugin::ShutdownFlag AutotestPlugin::aboutToShutdown() diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index 3b417dbeb0c..a8fd5c1f29b 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -109,6 +109,11 @@ void ActionBuilder::setText(const QString &text) d->action->setText(text); } +void ActionBuilder::setToolTip(const QString &toolTip) +{ + d->action->setToolTip(toolTip); +} + void ActionBuilder::setCommandAttribute(Command::CommandAttribute attr) { d->command->setAttribute(attr); diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.h b/src/plugins/coreplugin/actionmanager/actionmanager.h index cecd2d29b28..3806e7d48c6 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager.h @@ -36,6 +36,7 @@ public: void setContext(const Utils::Id id); void setContext(const Core::Context &context); void setText(const QString &text); + void setToolTip(const QString &toolTip); void setCommandAttribute(Core::Command::CommandAttribute attr); void setCommandDescription(const QString &desc); void setContainer(Utils::Id containerId, Utils::Id groupId = {}); From d74a85bbac5b488975960fc548d16fb7c545c011 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 10 Nov 2023 15:12:09 +0100 Subject: [PATCH 0152/1546] Macro: Inline SaveDialog Not worth the file pair. Also modernize MacroManager a bit. Change-Id: I88f6add3147390e3900beebacc4a3f5255eac7ea Reviewed-by: Christian Stenger --- src/plugins/macros/CMakeLists.txt | 1 - src/plugins/macros/macromanager.cpp | 75 ++++++++++++++++++++++------- src/plugins/macros/macromanager.h | 15 ++---- src/plugins/macros/macros.qbs | 2 - src/plugins/macros/savedialog.cpp | 55 --------------------- src/plugins/macros/savedialog.h | 30 ------------ 6 files changed, 62 insertions(+), 116 deletions(-) delete mode 100644 src/plugins/macros/savedialog.cpp delete mode 100644 src/plugins/macros/savedialog.h diff --git a/src/plugins/macros/CMakeLists.txt b/src/plugins/macros/CMakeLists.txt index 588a9a330f3..564a602f542 100644 --- a/src/plugins/macros/CMakeLists.txt +++ b/src/plugins/macros/CMakeLists.txt @@ -14,6 +14,5 @@ add_qtc_plugin(Macros macrosplugin.cpp macrosplugin.h macrotextfind.cpp macrotextfind.h macrostr.h - savedialog.cpp savedialog.h texteditormacrohandler.cpp texteditormacrohandler.h ) diff --git a/src/plugins/macros/macromanager.cpp b/src/plugins/macros/macromanager.cpp index b5151b7ee25..1eef4e43e14 100644 --- a/src/plugins/macros/macromanager.cpp +++ b/src/plugins/macros/macromanager.cpp @@ -10,32 +10,34 @@ #include "macroevent.h" #include "macrosconstants.h" #include "macrostr.h" -#include "savedialog.h" #include "texteditormacrohandler.h" +#include +#include +#include +#include +#include +#include +#include +#include + #include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include +#include +#include #include #include -#include -#include - -#include #include +#include +#include +#include #include +#include -namespace Macros { -namespace Internal { +namespace Macros::Internal { /*! \namespace Macros @@ -202,9 +204,47 @@ bool MacroManagerPrivate::executeMacro(Macro *macro) return !error; } +class SaveDialog : public QDialog +{ +public: + SaveDialog() + : QDialog(Core::ICore::dialogParent()) + { + resize(219, 91); + setWindowTitle(Tr::tr("Save Macro")); + + m_name = new QLineEdit; + m_name->setValidator(new QRegularExpressionValidator(QRegularExpression("\\w*"), this)); + + m_description = new QLineEdit; + + auto buttonBox = new QDialogButtonBox; + buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Save); + + using namespace Layouting; + + Form { + Tr::tr("Name:"), m_name, br, + Tr::tr("Description:"), m_description, br, + buttonBox + }.attachTo(this); + + connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); + } + + QString name() const { return m_name->text(); } + + QString description() const { return m_description->text(); } + +private: + QLineEdit *m_name; + QLineEdit *m_description; +}; + void MacroManagerPrivate::showSaveDialog() { - SaveDialog dialog(Core::ICore::dialogParent()); + SaveDialog dialog; if (dialog.exec()) { if (dialog.name().isEmpty()) return; @@ -376,5 +416,4 @@ QString MacroManager::macrosDirectory() return QString(); } -} // Internal -} // Macros +} // Macros::Internal diff --git a/src/plugins/macros/macromanager.h b/src/plugins/macros/macromanager.h index df331979318..936c9156a67 100644 --- a/src/plugins/macros/macromanager.h +++ b/src/plugins/macros/macromanager.h @@ -6,20 +6,17 @@ #include #include -namespace Macros { -namespace Internal { +namespace Macros::Internal { class IMacroHandler; class Macro; class MacroOptionsWidget; -class MacroManager : public QObject +class MacroManager final : public QObject { - Q_OBJECT - public: MacroManager(); - ~MacroManager() override; + ~MacroManager() final; static MacroManager *instance(); @@ -35,15 +32,13 @@ public: bool executeMacro(const QString &name); void endMacro(); -protected: +private: friend class Internal::MacroOptionsWidget; void deleteMacro(const QString &name); void changeMacro(const QString &name, const QString &description); -private: class MacroManagerPrivate *d; }; -} // namespace Internal -} // namespace Macros +} // namespace Macros::Internal diff --git a/src/plugins/macros/macros.qbs b/src/plugins/macros/macros.qbs index 9aa7441b771..66e92375a0b 100644 --- a/src/plugins/macros/macros.qbs +++ b/src/plugins/macros/macros.qbs @@ -34,8 +34,6 @@ QtcPlugin { "macrostr.h", "macrotextfind.cpp", "macrotextfind.h", - "savedialog.cpp", - "savedialog.h", "texteditormacrohandler.cpp", "texteditormacrohandler.h", ] diff --git a/src/plugins/macros/savedialog.cpp b/src/plugins/macros/savedialog.cpp deleted file mode 100644 index cb45f96da03..00000000000 --- a/src/plugins/macros/savedialog.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2016 Nicolas Arnaud-Cormos -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "savedialog.h" - -#include "macrostr.h" - -#include - -#include -#include -#include -#include - -namespace Macros::Internal { - -SaveDialog::SaveDialog(QWidget *parent) : - QDialog(parent) -{ - resize(219, 91); - setWindowTitle(Tr::tr("Save Macro")); - - m_name = new QLineEdit; - m_name->setValidator(new QRegularExpressionValidator(QRegularExpression(QLatin1String("\\w*")), this)); - - m_description = new QLineEdit; - - auto buttonBox = new QDialogButtonBox; - buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Save); - - using namespace Layouting; - - Form { - Tr::tr("Name:"), m_name, br, - Tr::tr("Description:"), m_description, br, - buttonBox - }.attachTo(this); - - connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); - connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); -} - -SaveDialog::~SaveDialog() = default; - -QString SaveDialog::name() const -{ - return m_name->text(); -} - -QString SaveDialog::description() const -{ - return m_description->text(); -} - -} // Macros::Internal diff --git a/src/plugins/macros/savedialog.h b/src/plugins/macros/savedialog.h deleted file mode 100644 index 69fd7419b92..00000000000 --- a/src/plugins/macros/savedialog.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2016 Nicolas Arnaud-Cormos -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -QT_BEGIN_NAMESPACE -class QLineEdit; -QT_END_NAMESPACE - -namespace Macros::Internal { - -class SaveDialog : public QDialog -{ - Q_OBJECT - -public: - explicit SaveDialog(QWidget *parent = nullptr); - ~SaveDialog() override; - - QString name() const; - QString description() const; - -private: - QLineEdit *m_name; - QLineEdit *m_description; -}; - -} // Macros::Internal From 65bb9e35052ab8dc10ddcfb331f847c156ff0c37 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 10 Nov 2023 15:23:16 +0100 Subject: [PATCH 0153/1546] Macros: Move plugin class definition to .cpp Change-Id: I7ac41e64dd4b3b52876aaafd77218c330e220f67 Reviewed-by: Christian Stenger --- src/plugins/macros/CMakeLists.txt | 2 +- src/plugins/macros/macros.qbs | 1 - src/plugins/macros/macrosplugin.cpp | 100 +++++++++++++++------------- src/plugins/macros/macrosplugin.h | 26 -------- 4 files changed, 56 insertions(+), 73 deletions(-) delete mode 100644 src/plugins/macros/macrosplugin.h diff --git a/src/plugins/macros/CMakeLists.txt b/src/plugins/macros/CMakeLists.txt index 564a602f542..fa611f17784 100644 --- a/src/plugins/macros/CMakeLists.txt +++ b/src/plugins/macros/CMakeLists.txt @@ -11,7 +11,7 @@ add_qtc_plugin(Macros macrooptionspage.cpp macrooptionspage.h macros.qrc macrosconstants.h - macrosplugin.cpp macrosplugin.h + macrosplugin.cpp macrotextfind.cpp macrotextfind.h macrostr.h texteditormacrohandler.cpp texteditormacrohandler.h diff --git a/src/plugins/macros/macros.qbs b/src/plugins/macros/macros.qbs index 66e92375a0b..45060f9032c 100644 --- a/src/plugins/macros/macros.qbs +++ b/src/plugins/macros/macros.qbs @@ -30,7 +30,6 @@ QtcPlugin { "macros.qrc", "macrosconstants.h", "macrosplugin.cpp", - "macrosplugin.h", "macrostr.h", "macrotextfind.cpp", "macrotextfind.h", diff --git a/src/plugins/macros/macrosplugin.cpp b/src/plugins/macros/macrosplugin.cpp index c87686fea3c..947c5151d3d 100644 --- a/src/plugins/macros/macrosplugin.cpp +++ b/src/plugins/macros/macrosplugin.cpp @@ -1,16 +1,12 @@ // Copyright (C) 2016 Nicolas Arnaud-Cormos // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "macrosplugin.h" - #include "macrolocatorfilter.h" #include "macromanager.h" #include "macrooptionspage.h" #include "macrosconstants.h" #include "macrostr.h" -#include - #include #include #include @@ -18,14 +14,17 @@ #include #include +#include + +#include + #include #include #include -namespace Macros { -namespace Internal { +namespace Macros::Internal { -class MacrosPluginPrivate +class MacrosPluginPrivate final { public: MacroManager macroManager; @@ -33,50 +32,61 @@ public: MacroLocatorFilter locatorFilter; }; -MacrosPlugin::~MacrosPlugin() +class MacrosPlugin final : public ExtensionSystem::IPlugin { - delete d; -} + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Macros.json") -void MacrosPlugin::initialize() -{ - d = new MacrosPluginPrivate; +public: + ~MacrosPlugin() final + { + delete d; + } - Core::Context textContext(TextEditor::Constants::C_TEXTEDITOR); + void initialize() final + { + d = new MacrosPluginPrivate; - // Menus - Core::ActionContainer *mtools = Core::ActionManager::actionContainer(Core::Constants::M_TOOLS); - Core::ActionContainer *mmacrotools = Core::ActionManager::createMenu(Constants::M_TOOLS_MACRO); - QMenu *menu = mmacrotools->menu(); - menu->setTitle(Tr::tr("Text Editing &Macros")); - menu->setEnabled(true); - mtools->addMenu(mmacrotools); + Core::Context textContext(TextEditor::Constants::C_TEXTEDITOR); - QAction *startMacro = new QAction(Tr::tr("Record Macro"), this); - Core::Command *command = Core::ActionManager::registerAction(startMacro, Constants::START_MACRO, textContext); - command->setDefaultKeySequence(QKeySequence(Core::useMacShortcuts ? Tr::tr("Ctrl+[") : Tr::tr("Alt+["))); - mmacrotools->addAction(command); - connect(startMacro, &QAction::triggered, &d->macroManager, &MacroManager::startMacro); + // Menus + Core::ActionContainer *mtools = Core::ActionManager::actionContainer(Core::Constants::M_TOOLS); + Core::ActionContainer *mmacrotools = Core::ActionManager::createMenu(Constants::M_TOOLS_MACRO); + QMenu *menu = mmacrotools->menu(); + menu->setTitle(Tr::tr("Text Editing &Macros")); + menu->setEnabled(true); + mtools->addMenu(mmacrotools); - QAction *endMacro = new QAction(Tr::tr("Stop Recording Macro"), this); - endMacro->setEnabled(false); - command = Core::ActionManager::registerAction(endMacro, Constants::END_MACRO); - command->setDefaultKeySequence(QKeySequence(Core::useMacShortcuts ? Tr::tr("Ctrl+]") : Tr::tr("Alt+]"))); - mmacrotools->addAction(command); - connect(endMacro, &QAction::triggered, &d->macroManager, &MacroManager::endMacro); + QAction *startMacro = new QAction(Tr::tr("Record Macro"), this); + Core::Command *command = Core::ActionManager::registerAction(startMacro, Constants::START_MACRO, textContext); + command->setDefaultKeySequence(QKeySequence(Core::useMacShortcuts ? Tr::tr("Ctrl+[") : Tr::tr("Alt+["))); + mmacrotools->addAction(command); + connect(startMacro, &QAction::triggered, &d->macroManager, &MacroManager::startMacro); - QAction *executeLastMacro = new QAction(Tr::tr("Play Last Macro"), this); - command = Core::ActionManager::registerAction(executeLastMacro, Constants::EXECUTE_LAST_MACRO, textContext); - command->setDefaultKeySequence(QKeySequence(Core::useMacShortcuts ? Tr::tr("Meta+R") : Tr::tr("Alt+R"))); - mmacrotools->addAction(command); - connect(executeLastMacro, &QAction::triggered, &d->macroManager, &MacroManager::executeLastMacro); + QAction *endMacro = new QAction(Tr::tr("Stop Recording Macro"), this); + endMacro->setEnabled(false); + command = Core::ActionManager::registerAction(endMacro, Constants::END_MACRO); + command->setDefaultKeySequence(QKeySequence(Core::useMacShortcuts ? Tr::tr("Ctrl+]") : Tr::tr("Alt+]"))); + mmacrotools->addAction(command); + connect(endMacro, &QAction::triggered, &d->macroManager, &MacroManager::endMacro); - QAction *saveLastMacro = new QAction(Tr::tr("Save Last Macro"), this); - saveLastMacro->setEnabled(false); - command = Core::ActionManager::registerAction(saveLastMacro, Constants::SAVE_LAST_MACRO, textContext); - mmacrotools->addAction(command); - connect(saveLastMacro, &QAction::triggered, &d->macroManager, &MacroManager::saveLastMacro); -} + QAction *executeLastMacro = new QAction(Tr::tr("Play Last Macro"), this); + command = Core::ActionManager::registerAction(executeLastMacro, Constants::EXECUTE_LAST_MACRO, textContext); + command->setDefaultKeySequence(QKeySequence(Core::useMacShortcuts ? Tr::tr("Meta+R") : Tr::tr("Alt+R"))); + mmacrotools->addAction(command); + connect(executeLastMacro, &QAction::triggered, &d->macroManager, &MacroManager::executeLastMacro); -} // Internal -} // Macros + QAction *saveLastMacro = new QAction(Tr::tr("Save Last Macro"), this); + saveLastMacro->setEnabled(false); + command = Core::ActionManager::registerAction(saveLastMacro, Constants::SAVE_LAST_MACRO, textContext); + mmacrotools->addAction(command); + connect(saveLastMacro, &QAction::triggered, &d->macroManager, &MacroManager::saveLastMacro); + } + +private: + MacrosPluginPrivate *d = nullptr; +}; + +} // Macros::Internal + +#include "macrosplugin.moc" diff --git a/src/plugins/macros/macrosplugin.h b/src/plugins/macros/macrosplugin.h deleted file mode 100644 index da7daf3ec60..00000000000 --- a/src/plugins/macros/macrosplugin.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2016 Nicolas Arnaud-Cormos -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace Macros { -namespace Internal { - -class MacrosPlugin final : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Macros.json") - -public: - ~MacrosPlugin() final; - - void initialize() final; - -private: - class MacrosPluginPrivate *d = nullptr; -}; - -} // namespace Internal -} // namespace Macros From 50679424dc61eac73f113fb72d5bc21040159b24 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 10 Nov 2023 13:09:55 +0100 Subject: [PATCH 0154/1546] Beautifier: Use ActionBuilder to create actions Change-Id: Ibdaa87ec16dce4f532fd9bfd61914f08220a2f4c Reviewed-by: Christian Stenger --- .../artisticstyle/artisticstyle.cpp | 11 +++-- .../beautifier/clangformat/clangformat.cpp | 42 ++++++++++--------- .../beautifier/uncrustify/uncrustify.cpp | 22 +++++----- 3 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/plugins/beautifier/artisticstyle/artisticstyle.cpp b/src/plugins/beautifier/artisticstyle/artisticstyle.cpp index 95c3d43ecbf..c6ac2bfe19f 100644 --- a/src/plugins/beautifier/artisticstyle/artisticstyle.cpp +++ b/src/plugins/beautifier/artisticstyle/artisticstyle.cpp @@ -236,12 +236,15 @@ public: ArtisticStyle::ArtisticStyle() { - Core::ActionContainer *menu = Core::ActionManager::createMenu("ArtisticStyle.Menu"); + const Id menuId = "ArtisticStyle.Menu"; + Core::ActionContainer *menu = Core::ActionManager::createMenu(menuId); menu->menu()->setTitle(Tr::tr("&Artistic Style")); - m_formatFile = new QAction(msgFormatCurrentFile(), this); - menu->addAction(Core::ActionManager::registerAction(m_formatFile, "ArtisticStyle.FormatFile")); - connect(m_formatFile, &QAction::triggered, this, &ArtisticStyle::formatFile); + Core::ActionBuilder formatFile(this, "ArtisticStyle.FormatFile"); + formatFile.setText(msgFormatCurrentFile()); + formatFile.bindContextAction(&m_formatFile); + formatFile.setContainer(menuId); + formatFile.setOnTriggered(this, [this] { this->formatFile(); }); Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu); diff --git a/src/plugins/beautifier/clangformat/clangformat.cpp b/src/plugins/beautifier/clangformat/clangformat.cpp index 0d6c9235da0..6a31cbb374a 100644 --- a/src/plugins/beautifier/clangformat/clangformat.cpp +++ b/src/plugins/beautifier/clangformat/clangformat.cpp @@ -312,31 +312,33 @@ public: ClangFormat::ClangFormat() { - Core::ActionContainer *menu = Core::ActionManager::createMenu("ClangFormat.Menu"); + const Id menuId = "ClangFormat.Menu"; + Core::ActionContainer *menu = Core::ActionManager::createMenu(menuId); menu->menu()->setTitle(Tr::tr("&ClangFormat")); - m_formatFile = new QAction(msgFormatCurrentFile(), this); - Core::Command *cmd - = Core::ActionManager::registerAction(m_formatFile, "ClangFormat.FormatFile"); - menu->addAction(cmd); - connect(m_formatFile, &QAction::triggered, this, &ClangFormat::formatFile); + Core::ActionBuilder formatFile(this, "ClangFormat.FormatFile"); + formatFile.setText(msgFormatCurrentFile()); + formatFile.bindContextAction(&m_formatFile); + formatFile.setContainer(menuId); + formatFile.setOnTriggered(this, [this] { this->formatFile(); }); - m_formatLines = new QAction(msgFormatLines(), this); - cmd = Core::ActionManager::registerAction(m_formatLines, "ClangFormat.FormatLines"); - menu->addAction(cmd); - connect(m_formatLines, &QAction::triggered, this, &ClangFormat::formatLines); + Core::ActionBuilder formatLines(this, "ClangFormat.FormatLines"); + formatLines.setText(msgFormatLines()); + formatLines.bindContextAction(&m_formatLines); + formatLines.setContainer(menuId); + formatLines.setOnTriggered(this, [this] { this->formatLines(); }); - m_formatRange = new QAction(msgFormatAtCursor(), this); - cmd = Core::ActionManager::registerAction(m_formatRange, "ClangFormat.FormatAtCursor"); - menu->addAction(cmd); - connect(m_formatRange, &QAction::triggered, this, &ClangFormat::formatAtCursor); + Core::ActionBuilder formatAtCursor(this, "ClangFormat.FormatAtCursor"); + formatAtCursor.setText(msgFormatAtCursor()); + formatAtCursor.bindContextAction(&m_formatRange); + formatAtCursor.setContainer(menuId); + formatAtCursor.setOnTriggered(this, [this] { this->formatAtCursor(); }); - m_disableFormattingSelectedText = new QAction(msgDisableFormattingSelectedText(), this); - cmd = Core::ActionManager::registerAction( - m_disableFormattingSelectedText, "ClangFormat.DisableFormattingSelectedText"); - menu->addAction(cmd); - connect(m_disableFormattingSelectedText, &QAction::triggered, - this, &ClangFormat::disableFormattingSelectedText); + Core::ActionBuilder formatDisable(this, "ClangFormat.DisableFormattingSelectedText"); + formatDisable.setText(msgDisableFormattingSelectedText()); + formatDisable.bindContextAction(&m_disableFormattingSelectedText); + formatDisable.setContainer(menuId); + formatDisable.setOnTriggered(this, [this] { disableFormattingSelectedText(); }); Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu); diff --git a/src/plugins/beautifier/uncrustify/uncrustify.cpp b/src/plugins/beautifier/uncrustify/uncrustify.cpp index 29722d4df19..340ee416f1c 100644 --- a/src/plugins/beautifier/uncrustify/uncrustify.cpp +++ b/src/plugins/beautifier/uncrustify/uncrustify.cpp @@ -233,19 +233,21 @@ public: Uncrustify::Uncrustify() { - Core::ActionContainer *menu = Core::ActionManager::createMenu("Uncrustify.Menu"); + const Id menuId = "Uncrustify.Menu"; + Core::ActionContainer *menu = Core::ActionManager::createMenu(menuId); menu->menu()->setTitle(Tr::tr("&Uncrustify")); - m_formatFile = new QAction(msgFormatCurrentFile(), this); - Core::Command *cmd - = Core::ActionManager::registerAction(m_formatFile, "Uncrustify.FormatFile"); - menu->addAction(cmd); - connect(m_formatFile, &QAction::triggered, this, &Uncrustify::formatFile); + Core::ActionBuilder formatFile(this, "Uncrustify.FormatFile"); + formatFile.setText(msgFormatCurrentFile()); + formatFile.bindContextAction(&m_formatFile); + formatFile.setContainer(menuId); + formatFile.setOnTriggered(this, [this] { this->formatFile(); }); - m_formatRange = new QAction(msgFormatSelectedText(), this); - cmd = Core::ActionManager::registerAction(m_formatRange, "Uncrustify.FormatSelectedText"); - menu->addAction(cmd); - connect(m_formatRange, &QAction::triggered, this, &Uncrustify::formatSelectedText); + Core::ActionBuilder formatRange(this, "Uncrustify.FormatSelectedText"); + formatRange.setText(msgFormatSelectedText()); + formatRange.bindContextAction(&m_formatRange); + formatRange.setContainer(menuId); + formatRange.setOnTriggered(this, [this] { this->formatSelectedText(); }); Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu); From 9e556d114227a51481058ef10ab94beefaed814a Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 10 Nov 2023 13:36:44 +0100 Subject: [PATCH 0155/1546] CoPilot: Use ActionBuilder Change-Id: I4a7dcce271a40038c8518be58e8fa626789ade61 Reviewed-by: Christian Stenger --- src/plugins/copilot/copilotplugin.cpp | 81 ++++++++++++--------------- 1 file changed, 35 insertions(+), 46 deletions(-) diff --git a/src/plugins/copilot/copilotplugin.cpp b/src/plugins/copilot/copilotplugin.cpp index 47364c60d7d..fdbdaac553b 100644 --- a/src/plugins/copilot/copilotplugin.cpp +++ b/src/plugins/copilot/copilotplugin.cpp @@ -57,79 +57,68 @@ void cycleSuggestion(TextEditor::TextEditorWidget *editor, Direction direction) void CopilotPlugin::initialize() { - QAction *requestAction = new QAction(this); - requestAction->setText(Tr::tr("Request Copilot Suggestion")); - requestAction->setToolTip( - Tr::tr("Request Copilot suggestion at the current editor's cursor position.")); - - connect(requestAction, &QAction::triggered, this, [this] { + ActionBuilder requestAction(this, Constants::COPILOT_REQUEST_SUGGESTION); + requestAction.setText(Tr::tr("Request Copilot Suggestion")); + requestAction.setToolTip(Tr::tr( + "Request Copilot suggestion at the current editor's cursor position.")); + requestAction.setOnTriggered(this, [this] { if (auto editor = TextEditor::TextEditorWidget::currentTextEditorWidget()) { if (m_client && m_client->reachable()) m_client->requestCompletions(editor); } }); - ActionManager::registerAction(requestAction, Constants::COPILOT_REQUEST_SUGGESTION); - - QAction *nextSuggestionAction = new QAction(this); - nextSuggestionAction->setText(Tr::tr("Show Next Copilot Suggestion")); - nextSuggestionAction->setToolTip(Tr::tr( + ActionBuilder nextSuggestionAction(this, Constants::COPILOT_NEXT_SUGGESTION); + nextSuggestionAction.setText(Tr::tr("Show Next Copilot Suggestion")); + nextSuggestionAction.setToolTip(Tr::tr( "Cycles through the received Copilot Suggestions showing the next available Suggestion.")); - - connect(nextSuggestionAction, &QAction::triggered, this, [] { + nextSuggestionAction.setOnTriggered(this, [] { if (auto editor = TextEditor::TextEditorWidget::currentTextEditorWidget()) cycleSuggestion(editor, Next); }); - ActionManager::registerAction(nextSuggestionAction, Constants::COPILOT_NEXT_SUGGESTION); - - QAction *previousSuggestionAction = new QAction(this); - previousSuggestionAction->setText(Tr::tr("Show Previous Copilot Suggestion")); - previousSuggestionAction->setToolTip(Tr::tr("Cycles through the received Copilot Suggestions " - "showing the previous available Suggestion.")); - - connect(previousSuggestionAction, &QAction::triggered, this, [] { + ActionBuilder previousSuggestionAction(this, Constants::COPILOT_PREVIOUS_SUGGESTION); + previousSuggestionAction.setText(Tr::tr("Show Previous Copilot Suggestion")); + previousSuggestionAction.setToolTip(Tr::tr("Cycles through the received Copilot Suggestions " + "showing the previous available Suggestion.")); + previousSuggestionAction.setOnTriggered(this, [] { if (auto editor = TextEditor::TextEditorWidget::currentTextEditorWidget()) cycleSuggestion(editor, Previous); }); - ActionManager::registerAction(previousSuggestionAction, Constants::COPILOT_PREVIOUS_SUGGESTION); - - QAction *disableAction = new QAction(this); - disableAction->setText(Tr::tr("Disable Copilot")); - disableAction->setToolTip(Tr::tr("Disable Copilot.")); - connect(disableAction, &QAction::triggered, this, [] { + ActionBuilder disableAction(this, Constants::COPILOT_DISABLE); + disableAction.setText(Tr::tr("Disable Copilot")); + disableAction.setToolTip(Tr::tr("Disable Copilot.")); + disableAction.setOnTriggered(this, [] { settings().enableCopilot.setValue(true); settings().apply(); }); - ActionManager::registerAction(disableAction, Constants::COPILOT_DISABLE); - QAction *enableAction = new QAction(this); - enableAction->setText(Tr::tr("Enable Copilot")); - enableAction->setToolTip(Tr::tr("Enable Copilot.")); - connect(enableAction, &QAction::triggered, this, [] { + ActionBuilder enableAction(this, Constants::COPILOT_ENABLE); + enableAction.setText(Tr::tr("Enable Copilot")); + enableAction.setToolTip(Tr::tr("Enable Copilot.")); + enableAction.setOnTriggered(this, [] { settings().enableCopilot.setValue(false); settings().apply(); }); - ActionManager::registerAction(enableAction, Constants::COPILOT_ENABLE); - QAction *toggleAction = new QAction(this); - toggleAction->setText(Tr::tr("Toggle Copilot")); - toggleAction->setCheckable(true); - toggleAction->setChecked(settings().enableCopilot()); - toggleAction->setIcon(COPILOT_ICON.icon()); - connect(toggleAction, &QAction::toggled, this, [](bool checked) { + ActionBuilder toggleAction(this, Constants::COPILOT_TOGGLE); + toggleAction.setText(Tr::tr("Toggle Copilot")); + toggleAction.setCheckable(true); + toggleAction.setChecked(settings().enableCopilot()); + toggleAction.setIcon(COPILOT_ICON.icon()); + toggleAction.setOnTriggered(this, [](bool checked) { settings().enableCopilot.setValue(checked); settings().apply(); }); - ActionManager::registerAction(toggleAction, Constants::COPILOT_TOGGLE); - - auto updateActions = [toggleAction, requestAction] { + QAction *toggleAct = toggleAction.contextAction(); + QAction *requestAct = requestAction.contextAction(); + auto updateActions = [toggleAct, requestAct] { const bool enabled = settings().enableCopilot(); - toggleAction->setToolTip(enabled ? Tr::tr("Disable Copilot.") : Tr::tr("Enable Copilot.")); - toggleAction->setChecked(enabled); - requestAction->setEnabled(enabled); + toggleAct->setToolTip(enabled ? Tr::tr("Disable Copilot.") : Tr::tr("Enable Copilot.")); + toggleAct->setChecked(enabled); + requestAct->setEnabled(enabled); }; connect(&settings().enableCopilot, &BaseAspect::changed, this, updateActions); @@ -137,7 +126,7 @@ void CopilotPlugin::initialize() updateActions(); auto toggleButton = new QToolButton; - toggleButton->setDefaultAction(toggleAction); + toggleButton->setDefaultAction(toggleAction.contextAction()); StatusBarManager::addStatusBarWidget(toggleButton, StatusBarManager::RightCorner); auto panelFactory = new ProjectPanelFactory; From 845337436c33fada679b4772f6974c7eace3375b Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 8 Nov 2023 21:33:24 +0100 Subject: [PATCH 0156/1546] Async tests: Add tests taking static function Change-Id: Id10b40c7d50c36b8e9406f1ae7ab8915c908212c Reviewed-by: Qt CI Bot Reviewed-by: Eike Ziller --- tests/auto/utils/async/tst_async.cpp | 55 ++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/tests/auto/utils/async/tst_async.cpp b/tests/auto/utils/async/tst_async.cpp index 2f12ec7cc47..ee7025bad1d 100644 --- a/tests/auto/utils/async/tst_async.cpp +++ b/tests/auto/utils/async/tst_async.cpp @@ -33,12 +33,25 @@ void report3(QPromise &promise) promise.addResult(1); } +static void staticReport3(QPromise &promise) +{ + promise.addResult(0); + promise.addResult(2); + promise.addResult(1); +} + void reportN(QPromise &promise, int n) { for (int i = 0; i < n; ++i) promise.addResult(0); } +static void staticReportN(QPromise &promise, int n) +{ + for (int i = 0; i < n; ++i) + promise.addResult(0); +} + void reportString1(QPromise &promise, const QString &s) { promise.addResult(s); @@ -135,6 +148,24 @@ std::shared_ptr> createAsyncTask(Function &&function, Args &&. void tst_Async::runAsync() { + // tesing QtConcurrent::run() + QCOMPARE(QtConcurrent::run(&report3).results(), + QList({0, 2, 1})); + QCOMPARE(QtConcurrent::run(report3).results(), + QList({0, 2, 1})); + QCOMPARE(QtConcurrent::run(&staticReport3).results(), + QList({0, 2, 1})); + QCOMPARE(QtConcurrent::run(staticReport3).results(), + QList({0, 2, 1})); + QCOMPARE(QtConcurrent::run(&reportN, 2).results(), + QList({0, 0})); + QCOMPARE(QtConcurrent::run(reportN, 2).results(), + QList({0, 0})); + QCOMPARE(QtConcurrent::run(&staticReportN, 2).results(), + QList({0, 0})); + QCOMPARE(QtConcurrent::run(staticReportN, 2).results(), + QList({0, 0})); + // free function pointer QCOMPARE(createAsyncTask(&report3)->results(), QList({0, 2, 1})); @@ -144,15 +175,31 @@ void tst_Async::runAsync() QList({0, 2, 1})); QCOMPARE(Utils::asyncRun(report3).results(), QList({0, 2, 1})); + QCOMPARE(createAsyncTask(&staticReport3)->results(), + QList({0, 2, 1})); + QCOMPARE(Utils::asyncRun(&staticReport3).results(), + QList({0, 2, 1})); + QCOMPARE(createAsyncTask(staticReport3)->results(), + QList({0, 2, 1})); + QCOMPARE(Utils::asyncRun(staticReport3).results(), + QList({0, 2, 1})); - QCOMPARE(createAsyncTask(reportN, 4)->results(), - QList({0, 0, 0, 0})); - QCOMPARE(Utils::asyncRun(reportN, 4).results(), - QList({0, 0, 0, 0})); + QCOMPARE(createAsyncTask(&reportN, 2)->results(), + QList({0, 0})); + QCOMPARE(Utils::asyncRun(&reportN, 2).results(), + QList({0, 0})); QCOMPARE(createAsyncTask(reportN, 2)->results(), QList({0, 0})); QCOMPARE(Utils::asyncRun(reportN, 2).results(), QList({0, 0})); + QCOMPARE(createAsyncTask(&staticReportN, 2)->results(), + QList({0, 0})); + QCOMPARE(Utils::asyncRun(&staticReportN, 2).results(), + QList({0, 0})); + QCOMPARE(createAsyncTask(staticReportN, 2)->results(), + QList({0, 0})); + QCOMPARE(Utils::asyncRun(staticReportN, 2).results(), + QList({0, 0})); QString s = QLatin1String("string"); const QString &crs = QLatin1String("cr string"); From 32914fe66b75913cac593d698ccdfceec2095e51 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 20 Jun 2023 16:06:50 +0200 Subject: [PATCH 0157/1546] ExtensionSystem: Allow opt-in plugin loading without restart Change-Id: I682e51d047c43ff5bf4647ef7e015222707f3204 Reviewed-by: Marcus Tillmanns Reviewed-by: Eike Ziller --- src/libs/extensionsystem/pluginmanager.cpp | 31 ++++++++++++++-------- src/libs/extensionsystem/pluginmanager.h | 1 + src/libs/extensionsystem/pluginspec.cpp | 17 ++++++++++++ src/libs/extensionsystem/pluginspec.h | 1 + src/libs/extensionsystem/pluginspec_p.h | 2 ++ src/libs/extensionsystem/pluginview.cpp | 6 ++--- src/libs/extensionsystem/pluginview.h | 3 ++- src/plugins/coreplugin/plugindialog.cpp | 20 +++++++++++--- src/plugins/coreplugin/plugindialog.h | 1 + 9 files changed, 63 insertions(+), 19 deletions(-) diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index 1f86693f907..7114813bd71 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -322,6 +322,13 @@ void PluginManager::loadPlugins() d->loadPlugins(); } +void PluginManager::loadPlugin(PluginSpec *spec) +{ + d->loadPlugin(spec, PluginSpec::Loaded); + d->loadPlugin(spec, PluginSpec::Initialized); + d->loadPlugin(spec, PluginSpec::Running); +} + /*! Returns \c true if any plugin has errors even though it is enabled. Most useful to call after loadPlugins(). @@ -1616,17 +1623,19 @@ void PluginManagerPrivate::loadPlugin(PluginSpec *spec, PluginSpec::State destSt break; } // check if dependencies have loaded without error - const QHash deps = spec->dependencySpecs(); - for (auto it = deps.cbegin(), end = deps.cend(); it != end; ++it) { - if (it.key().type != PluginDependency::Required) - continue; - PluginSpec *depSpec = it.value(); - if (depSpec->state() != destState) { - spec->d->hasError = true; - spec->d->errorString = - Tr::tr("Cannot load plugin because dependency failed to load: %1(%2)\nReason: %3") - .arg(depSpec->name(), depSpec->version(), depSpec->errorString()); - return; + if (!spec->isSoftLoadable()) { + const QHash deps = spec->dependencySpecs(); + for (auto it = deps.cbegin(), end = deps.cend(); it != end; ++it) { + if (it.key().type != PluginDependency::Required) + continue; + PluginSpec *depSpec = it.value(); + if (depSpec->state() != destState) { + spec->d->hasError = true; + spec->d->errorString = + Tr::tr("Cannot load plugin because dependency failed to load: %1(%2)\nReason: %3") + .arg(depSpec->name(), depSpec->version(), depSpec->errorString()); + return; + } } } switch (destState) { diff --git a/src/libs/extensionsystem/pluginmanager.h b/src/libs/extensionsystem/pluginmanager.h index e7c6a315259..97bb7f26473 100644 --- a/src/libs/extensionsystem/pluginmanager.h +++ b/src/libs/extensionsystem/pluginmanager.h @@ -68,6 +68,7 @@ public: // Plugin operations static QVector loadQueue(); static void loadPlugins(); + static void loadPlugin(PluginSpec *); static QStringList pluginPaths(); static void setPluginPaths(const QStringList &paths); static QString pluginIID(); diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp index bbc4e3541c0..cd26e814647 100644 --- a/src/libs/extensionsystem/pluginspec.cpp +++ b/src/libs/extensionsystem/pluginspec.cpp @@ -386,6 +386,11 @@ bool PluginSpec::isForceDisabled() const return d->forceDisabled; } +bool PluginSpec::isSoftLoadable() const +{ + return d->softLoadable; +} + /*! The plugin dependencies. This is valid after the PluginSpec::Read state is reached. */ @@ -570,6 +575,7 @@ namespace { const char PLUGIN_REQUIRED[] = "Required"; const char PLUGIN_EXPERIMENTAL[] = "Experimental"; const char PLUGIN_DISABLED_BY_DEFAULT[] = "DisabledByDefault"; + const char PLUGIN_SOFTLOADABLE[] = "SoftLoadable"; const char VENDOR[] = "Vendor"; const char COPYRIGHT[] = "Copyright"; const char LICENSE[] = "License"; @@ -683,6 +689,11 @@ void PluginSpecPrivate::setForceDisabled(bool value) forceDisabled = value; } +void PluginSpecPrivate::setSoftLoadable(bool value) +{ + softLoadable = value; +} + /*! \internal */ @@ -796,6 +807,12 @@ bool PluginSpecPrivate::readMetaData(const QJsonObject &pluginMetaData) enabledByDefault = false; enabledBySettings = enabledByDefault; + value = metaData.value(QLatin1String(PLUGIN_SOFTLOADABLE)); + if (!value.isUndefined() && !value.isBool()) + return reportError(msgValueIsNotABool(PLUGIN_SOFTLOADABLE)); + softLoadable = value.toBool(false); + qCDebug(pluginLog) << "softLoadable =" << softLoadable; + value = metaData.value(QLatin1String(VENDOR)); if (!value.isUndefined() && !value.isString()) return reportError(msgValueIsNotAString(VENDOR)); diff --git a/src/libs/extensionsystem/pluginspec.h b/src/libs/extensionsystem/pluginspec.h index 6030bc568e4..68cebae9b67 100644 --- a/src/libs/extensionsystem/pluginspec.h +++ b/src/libs/extensionsystem/pluginspec.h @@ -100,6 +100,7 @@ public: bool isEnabledIndirectly() const; bool isForceEnabled() const; bool isForceDisabled() const; + bool isSoftLoadable() const; QVector dependencies() const; QJsonObject metaData() const; const PerformanceData &performanceData() const; diff --git a/src/libs/extensionsystem/pluginspec_p.h b/src/libs/extensionsystem/pluginspec_p.h index f802902e53c..d171265b13c 100644 --- a/src/libs/extensionsystem/pluginspec_p.h +++ b/src/libs/extensionsystem/pluginspec_p.h @@ -45,6 +45,7 @@ public: void setEnabledByDefault(bool value); void setForceEnabled(bool value); void setForceDisabled(bool value); + void setSoftLoadable(bool value); std::optional loader; std::optional staticPlugin; @@ -69,6 +70,7 @@ public: bool enabledIndirectly = false; bool forceEnabled = false; bool forceDisabled = false; + bool softLoadable = false; QString location; QString filePath; diff --git a/src/libs/extensionsystem/pluginview.cpp b/src/libs/extensionsystem/pluginview.cpp index 71a8d3de764..ccb4d66362c 100644 --- a/src/libs/extensionsystem/pluginview.cpp +++ b/src/libs/extensionsystem/pluginview.cpp @@ -237,9 +237,7 @@ public: if (column == LoadedColumn && role == Qt::CheckStateRole) { const QVector affectedPlugins = Utils::filtered(m_plugins, [](PluginSpec *spec) { return !spec->isRequired(); }); - if (m_view->setPluginsEnabled(Utils::transform(affectedPlugins, - [](PluginSpec *s) { return s; }), - data.toBool())) { + if (m_view->setPluginsEnabled(toSet(affectedPlugins), data.toBool())) { update(); return true; } @@ -419,8 +417,8 @@ bool PluginView::setPluginsEnabled(const QSet &plugins, bool enabl spec->d->setEnabledBySettings(enable); item->updateColumn(LoadedColumn); item->parent()->updateColumn(LoadedColumn); - emit pluginSettingsChanged(spec); } + emit pluginsChanged(affectedPlugins, enable); return true; } diff --git a/src/libs/extensionsystem/pluginview.h b/src/libs/extensionsystem/pluginview.h index 09f1a5ce529..e241273ace3 100644 --- a/src/libs/extensionsystem/pluginview.h +++ b/src/libs/extensionsystem/pluginview.h @@ -7,6 +7,7 @@ #include +#include #include #include @@ -40,7 +41,7 @@ public: signals: void currentPluginChanged(ExtensionSystem::PluginSpec *spec); void pluginActivated(ExtensionSystem::PluginSpec *spec); - void pluginSettingsChanged(ExtensionSystem::PluginSpec *spec); + void pluginsChanged(const QSet &spec, bool enabled); private: PluginSpec *pluginForIndex(const QModelIndex &index) const; diff --git a/src/plugins/coreplugin/plugindialog.cpp b/src/plugins/coreplugin/plugindialog.cpp index 5e22463000c..5dcdcde9d88 100644 --- a/src/plugins/coreplugin/plugindialog.cpp +++ b/src/plugins/coreplugin/plugindialog.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -21,6 +22,7 @@ #include #include +using namespace ExtensionSystem; using namespace Utils; namespace Core { @@ -59,8 +61,16 @@ PluginDialog::PluginDialog(QWidget *parent) this, &PluginDialog::updateButtons); connect(m_view, &ExtensionSystem::PluginView::pluginActivated, this, &PluginDialog::openDetails); - connect(m_view, &ExtensionSystem::PluginView::pluginSettingsChanged, this, [this] { - m_isRestartRequired = true; + connect(m_view, &ExtensionSystem::PluginView::pluginsChanged, + this, [this](const QSet &plugins, bool enable) { + for (PluginSpec *plugin : plugins) { + if (enable && plugin->isSoftLoadable()) { + m_softLoad.insert(plugin); + } else { + m_softLoad.remove(plugin); // In case it was added, harmless otherwise. + m_isRestartRequired = true; + } + } }); connect(m_detailsButton, &QAbstractButton::clicked, this, [this] { openDetails(m_view->currentPlugin()); }); @@ -75,7 +85,11 @@ PluginDialog::PluginDialog(QWidget *parent) void PluginDialog::closeDialog() { - ExtensionSystem::PluginManager::writeSettings(); + PluginManager::writeSettings(); + + for (PluginSpec *plugin : m_softLoad) + PluginManager::loadPlugin(plugin); + if (m_isRestartRequired) { RestartDialog restartDialog(ICore::dialogParent(), Tr::tr("Plugin changes will take effect after restart.")); diff --git a/src/plugins/coreplugin/plugindialog.h b/src/plugins/coreplugin/plugindialog.h index 46633623410..e908e908bc4 100644 --- a/src/plugins/coreplugin/plugindialog.h +++ b/src/plugins/coreplugin/plugindialog.h @@ -38,6 +38,7 @@ private: QPushButton *m_errorDetailsButton; QPushButton *m_installButton; bool m_isRestartRequired = false; + QSet m_softLoad; }; } // namespace Internal From e799bcae6c0b040725a8ebd9c0a01ebe7e38d039 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 9 Nov 2023 14:22:52 +0100 Subject: [PATCH 0158/1546] Core: Register mimetype of softload plugin Change-Id: I81713d951caaf4e2d97fa1a58c4f512a280af351 Reviewed-by: Eike Ziller --- src/plugins/coreplugin/coreplugin.cpp | 15 ++++++++++----- src/plugins/coreplugin/coreplugin.h | 3 +++ src/plugins/coreplugin/plugindialog.cpp | 5 ++++- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/plugins/coreplugin/coreplugin.cpp b/src/plugins/coreplugin/coreplugin.cpp index 82356fd5be7..9034d58563f 100644 --- a/src/plugins/coreplugin/coreplugin.cpp +++ b/src/plugins/coreplugin/coreplugin.cpp @@ -126,17 +126,22 @@ CoreArguments parseArguments(const QStringList &arguments) return args; } +void CorePlugin::loadMimeFromPlugin(const ExtensionSystem::PluginSpec *plugin) +{ + const QJsonObject metaData = plugin->metaData(); + const QJsonValue mimetypes = metaData.value("Mimetypes"); + QString mimetypeString; + if (Utils::readMultiLineString(mimetypes, &mimetypeString)) + Utils::addMimeTypes(plugin->name() + ".mimetypes", mimetypeString.trimmed().toUtf8()); +} + bool CorePlugin::initialize(const QStringList &arguments, QString *errorMessage) { // register all mime types from all plugins for (ExtensionSystem::PluginSpec *plugin : ExtensionSystem::PluginManager::plugins()) { if (!plugin->isEffectivelyEnabled()) continue; - const QJsonObject metaData = plugin->metaData(); - const QJsonValue mimetypes = metaData.value("Mimetypes"); - QString mimetypeString; - if (Utils::readMultiLineString(mimetypes, &mimetypeString)) - Utils::addMimeTypes(plugin->name() + ".mimetypes", mimetypeString.trimmed().toUtf8()); + loadMimeFromPlugin(plugin); } if (ThemeEntry::availableThemes().isEmpty()) { diff --git a/src/plugins/coreplugin/coreplugin.h b/src/plugins/coreplugin/coreplugin.h index 987c6d15817..148f9b5c97f 100644 --- a/src/plugins/coreplugin/coreplugin.h +++ b/src/plugins/coreplugin/coreplugin.h @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -54,6 +55,8 @@ public: static void setEnvironmentChanges(const Utils::EnvironmentItems &changes); static QString msgCrashpadInformation(); + static void loadMimeFromPlugin(const ExtensionSystem::PluginSpec *plugin); + public slots: void fileOpenRequest(const QString &); diff --git a/src/plugins/coreplugin/plugindialog.cpp b/src/plugins/coreplugin/plugindialog.cpp index 5dcdcde9d88..8aa87d4e829 100644 --- a/src/plugins/coreplugin/plugindialog.cpp +++ b/src/plugins/coreplugin/plugindialog.cpp @@ -3,6 +3,7 @@ #include "plugindialog.h" +#include "coreplugin.h" #include "coreplugintr.h" #include "dialogs/restartdialog.h" #include "icore.h" @@ -87,8 +88,10 @@ void PluginDialog::closeDialog() { PluginManager::writeSettings(); - for (PluginSpec *plugin : m_softLoad) + for (PluginSpec *plugin : m_softLoad) { PluginManager::loadPlugin(plugin); + CorePlugin::loadMimeFromPlugin(plugin); + } if (m_isRestartRequired) { RestartDialog restartDialog(ICore::dialogParent(), From fc9b2b0b2b9e09788b236e4c66c5c71646e4a47b Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 10 Nov 2023 17:06:22 +0100 Subject: [PATCH 0159/1546] LanguageClient: Use Core::ActionBuilder Change-Id: Ie66ac478c35658fe82393143dc3dece41ddf591b Reviewed-by: Christian Stenger --- src/plugins/languageclient/languageclientplugin.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/plugins/languageclient/languageclientplugin.cpp b/src/plugins/languageclient/languageclientplugin.cpp index 235ea9b5593..18e0eca21eb 100644 --- a/src/plugins/languageclient/languageclientplugin.cpp +++ b/src/plugins/languageclient/languageclientplugin.cpp @@ -52,14 +52,10 @@ void LanguageClientPlugin::initialize() Tr::tr("Generic StdIO Language Server"), []() { return new StdIOSettings; }}); - //register actions - ActionContainer *toolsDebugContainer = ActionManager::actionContainer( - Core::Constants::M_TOOLS_DEBUG); - - auto inspectAction = new QAction(Tr::tr("Inspect Language Clients..."), this); - connect(inspectAction, &QAction::triggered, this, &LanguageClientManager::showInspector); - toolsDebugContainer->addAction( - ActionManager::registerAction(inspectAction, "LanguageClient.InspectLanguageClients")); + ActionBuilder inspectAction(this, "LanguageClient.InspectLanguageClients"); + inspectAction.setText(Tr::tr("Inspect Language Clients...")); + inspectAction.setContainer(Core::Constants::M_TOOLS_DEBUG); + inspectAction.setOnTriggered(this, &LanguageClientManager::showInspector); } void LanguageClientPlugin::extensionsInitialized() From 79f7eaab9c41514b3e7abe3b719bae52ce1c5561 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Thu, 9 Nov 2023 14:27:59 +0100 Subject: [PATCH 0160/1546] CompilerExplorer: Allow softload Change-Id: If907e7a846ce7d87a5a2ac7b09ef70174410da01 Reviewed-by: Eike Ziller --- src/plugins/compilerexplorer/CompilerExplorer.json.in | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/compilerexplorer/CompilerExplorer.json.in b/src/plugins/compilerexplorer/CompilerExplorer.json.in index db289e41a8a..108bd6a5df6 100644 --- a/src/plugins/compilerexplorer/CompilerExplorer.json.in +++ b/src/plugins/compilerexplorer/CompilerExplorer.json.in @@ -3,6 +3,7 @@ "Version" : "${IDE_VERSION}", "CompatVersion" : "${IDE_VERSION_COMPAT}", "DisabledByDefault" : true, + "SoftLoadable" : true, "Vendor" : "The Qt Company Ltd", "Copyright" : "(C) ${IDE_COPYRIGHT_YEAR} The Qt Company Ltd", "License" : [ "Commercial Usage", From bb7b6d55d2583f4f8f97d0a3b6ff16a31cf045b7 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 13 Nov 2023 11:01:01 +0100 Subject: [PATCH 0161/1546] ExtensionSystem: Fix qbs build Amends 32914fe66b75913cac593d698ccdfceec2095e51. Change-Id: I0bf7f94ae128109f44f4dedc71c418b36c34911e Reviewed-by: hjk --- src/libs/extensionsystem/pluginview.cpp | 3 --- src/libs/extensionsystem/pluginview.h | 6 +++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libs/extensionsystem/pluginview.cpp b/src/libs/extensionsystem/pluginview.cpp index ccb4d66362c..4551278bd7e 100644 --- a/src/libs/extensionsystem/pluginview.cpp +++ b/src/libs/extensionsystem/pluginview.cpp @@ -5,7 +5,6 @@ #include "extensionsystemtr.h" #include "pluginmanager.h" -#include "pluginspec.h" #include "pluginspec_p.h" #include @@ -55,8 +54,6 @@ The settings for the plugin list entry corresponding to \a spec changed. */ -Q_DECLARE_METATYPE(ExtensionSystem::PluginSpec*) - using namespace Utils; namespace ExtensionSystem { diff --git a/src/libs/extensionsystem/pluginview.h b/src/libs/extensionsystem/pluginview.h index e241273ace3..cd0c60b69a7 100644 --- a/src/libs/extensionsystem/pluginview.h +++ b/src/libs/extensionsystem/pluginview.h @@ -4,9 +4,11 @@ #pragma once #include "extensionsystem_global.h" +#include "pluginspec.h" #include +#include #include #include @@ -57,4 +59,6 @@ private: friend class Internal::PluginItem; }; -} // namespae ExtensionSystem +} // namespace ExtensionSystem + +Q_DECLARE_METATYPE(ExtensionSystem::PluginSpec *) From 48843d3f6b4613e3e8815d796407aa63a6404b5d Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 13 Nov 2023 11:18:34 +0100 Subject: [PATCH 0162/1546] Mimedatabase: Remove warning for registering MIME types late Since it is now possible to load some plugins during runtime, registering MIME types during runtime is valid. Change-Id: I08aba2c40934f7b8de85172a46e8a123bd7b4ef0 Reviewed-by: Marcus Tillmanns --- src/libs/utils/mimetypes2/mimeutils.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/libs/utils/mimetypes2/mimeutils.cpp b/src/libs/utils/mimetypes2/mimeutils.cpp index 711dc97187a..787353ceb24 100644 --- a/src/libs/utils/mimetypes2/mimeutils.cpp +++ b/src/libs/utils/mimetypes2/mimeutils.cpp @@ -69,13 +69,6 @@ void setMimeStartupPhase(MimeStartupPhase phase) void addMimeTypes(const QString &id, const QByteArray &data) { auto d = MimeDatabasePrivate::instance(); - { - QReadLocker locker(&d->m_initMutex); - if (d->m_startupPhase >= int(MimeStartupPhase::PluginsDelayedInitializing)) { - qWarning("Adding items for ID \"%s\" to MimeDatabase after initialization time", - qPrintable(id)); - } - } QMutexLocker locker(&d->mutex); d->addMimeData(id, data); From 0ae211586e2dbc40190b485ef0680cc9f1fda4b1 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 13 Nov 2023 11:05:44 +0100 Subject: [PATCH 0163/1546] UI text: Fix "the the" in visible UI text, comments, and docs Change-Id: I9b126ffa15b808fdb6f900a36453a9864248d35e Reviewed-by: Eike Ziller --- share/qtcreator/translations/qtcreator_de.ts | 2 +- share/qtcreator/translations/qtcreator_fr.ts | 2 +- share/qtcreator/translations/qtcreator_zh_CN.ts | 2 +- src/libs/advanceddockingsystem/dockareatabbar.cpp | 2 +- src/plugins/coreplugin/editormanager/ieditor.cpp | 2 +- src/plugins/coreplugin/find/basetextfind.cpp | 2 +- src/plugins/ios/createsimulatordialog.cpp | 6 +++--- .../buildsystem/projectitem/converters.cpp | 4 ++-- src/plugins/squish/squishsettings.cpp | 2 +- 9 files changed, 12 insertions(+), 12 deletions(-) diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts index 0f9b15ff734..baf7b75a9f2 100644 --- a/share/qtcreator/translations/qtcreator_de.ts +++ b/share/qtcreator/translations/qtcreator_de.ts @@ -50433,7 +50433,7 @@ Testfall "%2" wird nicht aufgezeichnet. Maximale Post-Mortem-Wartezeit: - Specifies how many seconds Squish should wait after the the first AUT process has exited. + Specifies how many seconds Squish should wait after the first AUT process has exited. Legt fest, wie viele Sekunden Squish wartet, nachdem der erste AUT-Prozess beendet ist. diff --git a/share/qtcreator/translations/qtcreator_fr.ts b/share/qtcreator/translations/qtcreator_fr.ts index 673d54af1ea..d87f7a9e68d 100644 --- a/share/qtcreator/translations/qtcreator_fr.ts +++ b/share/qtcreator/translations/qtcreator_fr.ts @@ -48829,7 +48829,7 @@ Refus d'enregistrer le cas de test « %2 ». Temps maximal d'attente après la fin : - Specifies how many seconds Squish should wait after the the first AUT process has exited. + Specifies how many seconds Squish should wait after the first AUT process has exited. Spécifie combien de secondes Squish doit attendre après la fin du premier processus de l'AUT. diff --git a/share/qtcreator/translations/qtcreator_zh_CN.ts b/share/qtcreator/translations/qtcreator_zh_CN.ts index ff7a8e061ce..4e361b52d34 100644 --- a/share/qtcreator/translations/qtcreator_zh_CN.ts +++ b/share/qtcreator/translations/qtcreator_zh_CN.ts @@ -41142,7 +41142,7 @@ Refusing to record test case "%2". - Specifies how many seconds Squish should wait after the the first AUT process has exited. + Specifies how many seconds Squish should wait after the first AUT process has exited. diff --git a/src/libs/advanceddockingsystem/dockareatabbar.cpp b/src/libs/advanceddockingsystem/dockareatabbar.cpp index 57e7c52da78..5575c53f5ac 100644 --- a/src/libs/advanceddockingsystem/dockareatabbar.cpp +++ b/src/libs/advanceddockingsystem/dockareatabbar.cpp @@ -140,7 +140,7 @@ void DockAreaTabBar::onCloseOtherTabsRequested(DockWidgetTab *sourceTab) ? 1 : 0; closeTab(i); - // If the the dock widget blocks closing, i.e. if the flag CustomCloseHandling is set, + // If the dock widget blocks closing, i.e. if the flag CustomCloseHandling is set, // and the dock widget is still open, then we do not need to correct the index. if (currentTab->dockWidget()->isClosed()) i -= offset; diff --git a/src/plugins/coreplugin/editormanager/ieditor.cpp b/src/plugins/coreplugin/editormanager/ieditor.cpp index 892358c6892..ec29a07bda2 100644 --- a/src/plugins/coreplugin/editormanager/ieditor.cpp +++ b/src/plugins/coreplugin/editormanager/ieditor.cpp @@ -14,7 +14,7 @@ IEditor instances are usually created by a corresponding IEditorFactory. An IEditor instance provides an editor widget for a single IDocument via - the IContext::widget() method. If the the editor type supports it, multiple + the IContext::widget() method. If the editor type supports it, multiple editors can be opened for the same document. Multiple IEditor instances share ownership of the same IDocument instance in that case. diff --git a/src/plugins/coreplugin/find/basetextfind.cpp b/src/plugins/coreplugin/find/basetextfind.cpp index a11bf7d33da..aab6e1d0889 100644 --- a/src/plugins/coreplugin/find/basetextfind.cpp +++ b/src/plugins/coreplugin/find/basetextfind.cpp @@ -249,7 +249,7 @@ void BaseTextFind::replace(const QString &before, const QString &after, FindFlag setTextCursor(cursor); } -// QTextCursor::insert moves all other QTextCursors that are the the insertion point forward. +// QTextCursor::insert moves all other QTextCursors that are the insertion point forward. // We do not want that for the replace operation, because then e.g. the find scope would move when // replacing a match at the start. static void insertTextAfterSelection(const QString &text, QTextCursor &cursor) diff --git a/src/plugins/ios/createsimulatordialog.cpp b/src/plugins/ios/createsimulatordialog.cpp index 32884c5e426..e658fef07c6 100644 --- a/src/plugins/ios/createsimulatordialog.cpp +++ b/src/plugins/ios/createsimulatordialog.cpp @@ -77,7 +77,7 @@ CreateSimulatorDialog::~CreateSimulatorDialog() } /*! - Returns the the simulator name entered by user. + Returns the simulator name entered by user. */ QString CreateSimulatorDialog::name() const { @@ -85,7 +85,7 @@ QString CreateSimulatorDialog::name() const } /*! - Returns the the simulator runtime (OS version) selected by user. + Returns the simulator runtime (OS version) selected by user. Though the runtimes are filtered by the selected device type but the runtime camppatibility is not checked. i.e. User can select the Runtime iOS 10.2 for iPhone 4 but the combination is not possible as iOS 10.2 is not compatible with iPhone 4. In this case the command to create @@ -97,7 +97,7 @@ RuntimeInfo CreateSimulatorDialog::runtime() const } /*! - Returns the the selected device type. + Returns the selected device type. */ DeviceTypeInfo CreateSimulatorDialog::deviceType() const { diff --git a/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp b/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp index 3d75f4c9e45..ce0233fcf20 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp @@ -218,7 +218,7 @@ QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile) QJsonObject mcuObject; QJsonObject shaderToolObject; - // convert the the non-object props + // convert the non-object props for (const QString &propName : rootNode->propertyNames()) { QJsonObject *currentObj = &rootObject; QString objKey = QString(propName).remove("QDS.", Qt::CaseInsensitive); @@ -267,7 +267,7 @@ QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile) versionObject.insert("qt", "5"); } - // convert the the object props + // convert the object props for (const QmlJS::SimpleReaderNode::Ptr &childNode : rootNode->children()) { if (childNode->name().contains("files", Qt::CaseInsensitive)) { PropsPair propsPair; diff --git a/src/plugins/squish/squishsettings.cpp b/src/plugins/squish/squishsettings.cpp index bfa0a127d18..a8e0518a3de 100644 --- a/src/plugins/squish/squishsettings.cpp +++ b/src/plugins/squish/squishsettings.cpp @@ -160,7 +160,7 @@ SquishServerSettings::SquishServerSettings() responseTimeout.setSuffix("s"); postMortemWaitTime.setLabel(Tr::tr("Maximum post-mortem wait time:")); - postMortemWaitTime.setToolTip(Tr::tr("Specifies how many seconds Squish should wait after the the " + postMortemWaitTime.setToolTip(Tr::tr("Specifies how many seconds Squish should wait after the " "first AUT process has exited.")); postMortemWaitTime.setRange(1, 65535); postMortemWaitTime.setDefaultValue(1500); From e7088c391cd1a7b4380b2099081a5cc407430685 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 8 Nov 2023 18:45:25 +0100 Subject: [PATCH 0164/1546] TaskTree: Remove errorOccurred signal Amends fbe359308dc3946bb68b6dedca237f353fa279f0 Change-Id: If1a8fbc0a98bc8128e375749a45e5761c7486cd4 Reviewed-by: hjk Reviewed-by: Qt CI Bot --- src/libs/solutions/tasking/tasktree.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index ab0dd551c6e..77cc318fe36 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -512,7 +512,6 @@ public: signals: void started(); void done(DoneWith result); - void errorOccurred(); void progressValueChanged(int value); // updated whenever task finished / skipped / stopped private: From 62f1cfdba276f6a9bb412a2a1ae149d4f4cc39b6 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 10 Nov 2023 16:12:01 +0100 Subject: [PATCH 0165/1546] Macros: Use ActionBuilder Change-Id: Iea9d79e97b503122830e281c2997289ab5862803 Reviewed-by: Christian Stenger --- src/plugins/macros/macrosplugin.cpp | 59 +++++++++++++++-------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/src/plugins/macros/macrosplugin.cpp b/src/plugins/macros/macrosplugin.cpp index 947c5151d3d..9fdf3f5357c 100644 --- a/src/plugins/macros/macrosplugin.cpp +++ b/src/plugins/macros/macrosplugin.cpp @@ -8,9 +8,8 @@ #include "macrostr.h" #include -#include #include -#include +#include #include #include @@ -18,10 +17,10 @@ #include -#include -#include #include +using namespace Core; + namespace Macros::Internal { class MacrosPluginPrivate final @@ -47,40 +46,44 @@ public: { d = new MacrosPluginPrivate; - Core::Context textContext(TextEditor::Constants::C_TEXTEDITOR); + Context textContext(TextEditor::Constants::C_TEXTEDITOR); // Menus - Core::ActionContainer *mtools = Core::ActionManager::actionContainer(Core::Constants::M_TOOLS); - Core::ActionContainer *mmacrotools = Core::ActionManager::createMenu(Constants::M_TOOLS_MACRO); + ActionContainer *mtools = ActionManager::actionContainer(Core::Constants::M_TOOLS); + ActionContainer *mmacrotools = ActionManager::createMenu(Constants::M_TOOLS_MACRO); QMenu *menu = mmacrotools->menu(); menu->setTitle(Tr::tr("Text Editing &Macros")); menu->setEnabled(true); mtools->addMenu(mmacrotools); - QAction *startMacro = new QAction(Tr::tr("Record Macro"), this); - Core::Command *command = Core::ActionManager::registerAction(startMacro, Constants::START_MACRO, textContext); - command->setDefaultKeySequence(QKeySequence(Core::useMacShortcuts ? Tr::tr("Ctrl+[") : Tr::tr("Alt+["))); - mmacrotools->addAction(command); - connect(startMacro, &QAction::triggered, &d->macroManager, &MacroManager::startMacro); + ActionBuilder startMacro(this, Constants::START_MACRO); + startMacro.setText(Tr::tr("Record Macro")); + startMacro.setContext(textContext); + startMacro.setDefaultKeySequence(Tr::tr("Ctrl+["), Tr::tr("Alt+[")); + startMacro.setContainer(Constants::M_TOOLS_MACRO); + startMacro.setOnTriggered(this, [this] { d->macroManager.startMacro(); }); - QAction *endMacro = new QAction(Tr::tr("Stop Recording Macro"), this); - endMacro->setEnabled(false); - command = Core::ActionManager::registerAction(endMacro, Constants::END_MACRO); - command->setDefaultKeySequence(QKeySequence(Core::useMacShortcuts ? Tr::tr("Ctrl+]") : Tr::tr("Alt+]"))); - mmacrotools->addAction(command); - connect(endMacro, &QAction::triggered, &d->macroManager, &MacroManager::endMacro); + ActionBuilder endMacro(this, Constants::END_MACRO); + endMacro.setText(Tr::tr("Stop Recording Macro")); + endMacro.setContext(textContext); + endMacro.setEnabled(false); + endMacro.setDefaultKeySequence(Tr::tr("Ctrl+]"), Tr::tr("Alt+]")); + endMacro.setContainer(Constants::M_TOOLS_MACRO); + endMacro.setOnTriggered(this, [this] { d->macroManager.endMacro(); }); - QAction *executeLastMacro = new QAction(Tr::tr("Play Last Macro"), this); - command = Core::ActionManager::registerAction(executeLastMacro, Constants::EXECUTE_LAST_MACRO, textContext); - command->setDefaultKeySequence(QKeySequence(Core::useMacShortcuts ? Tr::tr("Meta+R") : Tr::tr("Alt+R"))); - mmacrotools->addAction(command); - connect(executeLastMacro, &QAction::triggered, &d->macroManager, &MacroManager::executeLastMacro); + ActionBuilder executeLastMacro(this, Constants::EXECUTE_LAST_MACRO); + executeLastMacro.setText(Tr::tr("Play Last Macro")); + executeLastMacro.setContext(textContext); + executeLastMacro.setDefaultKeySequence(Tr::tr("Meta+R"), Tr::tr("Alt+R")); + executeLastMacro.setContainer(Constants::M_TOOLS_MACRO); + executeLastMacro.setOnTriggered(this, [this] { d->macroManager.executeLastMacro(); }); - QAction *saveLastMacro = new QAction(Tr::tr("Save Last Macro"), this); - saveLastMacro->setEnabled(false); - command = Core::ActionManager::registerAction(saveLastMacro, Constants::SAVE_LAST_MACRO, textContext); - mmacrotools->addAction(command); - connect(saveLastMacro, &QAction::triggered, &d->macroManager, &MacroManager::saveLastMacro); + ActionBuilder saveLastMacro(this, Constants::SAVE_LAST_MACRO); + saveLastMacro.setContext(textContext); + saveLastMacro.setText(Tr::tr("Save Last Macro")); + saveLastMacro.setEnabled(false); + saveLastMacro.setContainer(Constants::M_TOOLS_MACRO); + saveLastMacro.setOnTriggered(this, [this] { d->macroManager.saveLastMacro(); }); } private: From afeae79cae6885fbca0b03ba4d5af07c1a7eb201 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 10 Nov 2023 17:26:47 +0100 Subject: [PATCH 0166/1546] CppEditor: Move CppOutlineWidgetFactory implenentation details to .cpp And remove a few Q_OBJECT Change-Id: Ifbde77b435a2285fd7849a9780b125e385fe5b20 Reviewed-by: Christian Stenger --- src/plugins/cppeditor/cppoutline.cpp | 133 ++++++++++++++++++--------- src/plugins/cppeditor/cppoutline.h | 79 ++-------------- 2 files changed, 94 insertions(+), 118 deletions(-) diff --git a/src/plugins/cppeditor/cppoutline.cpp b/src/plugins/cppeditor/cppoutline.cpp index bbb641dc959..ed7c66df0d9 100644 --- a/src/plugins/cppeditor/cppoutline.cpp +++ b/src/plugins/cppeditor/cppoutline.cpp @@ -6,73 +6,117 @@ #include "cppeditordocument.h" #include "cppeditoroutline.h" #include "cppeditortr.h" +#include "cppeditorwidget.h" #include "cppmodelmanager.h" #include "cppoutlinemodel.h" -#include #include +#include + #include #include + +#include #include -#include -#include #include +#include +#include +#include -namespace CppEditor { -namespace Internal { +namespace CppEditor::Internal { -CppOutlineTreeView::CppOutlineTreeView(QWidget *parent) : - Utils::NavigationTreeView(parent) +class CppOutlineTreeView final : public Utils::NavigationTreeView { - setExpandsOnDoubleClick(false); - setDragEnabled(true); - setDragDropMode(QAbstractItemView::DragOnly); -} +public: + CppOutlineTreeView(QWidget *parent) : + Utils::NavigationTreeView(parent) + { + setExpandsOnDoubleClick(false); + setDragEnabled(true); + setDragDropMode(QAbstractItemView::DragOnly); + } -void CppOutlineTreeView::contextMenuEvent(QContextMenuEvent *event) + void contextMenuEvent(QContextMenuEvent *event) final + { + if (!event) + return; + + QMenu contextMenu; + + QAction *action = contextMenu.addAction(Tr::tr("Expand All")); + connect(action, &QAction::triggered, this, &QTreeView::expandAll); + action = contextMenu.addAction(Tr::tr("Collapse All")); + connect(action, &QAction::triggered, this, &QTreeView::collapseAll); + + contextMenu.exec(event->globalPos()); + + event->accept(); + } +}; + +class CppOutlineFilterModel : public QSortFilterProxyModel { - if (!event) - return; +public: + CppOutlineFilterModel(OutlineModel &sourceModel, QObject *parent) + : QSortFilterProxyModel(parent) + , m_sourceModel(sourceModel) + {} - QMenu contextMenu; + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const final + { + // ignore artificial "" entry - if (!sourceParent.isValid() && sourceRow == 0) - return false; - // ignore generated symbols, e.g. by macro expansion (Q_OBJECT) - const QModelIndex sourceIndex = m_sourceModel.index(sourceRow, 0, sourceParent); - if (m_sourceModel.isGenerated(sourceIndex)) - return false; + // IOutlineWidget + QList filterMenuActions() const final; + void setCursorSynchronization(bool syncWithCursor) final; + bool isSorted() const final; + void setSorted(bool sorted) final; - return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); -} + void restoreSettings(const QVariantMap &map) final; + QVariantMap settings() const final; -Qt::DropActions CppOutlineFilterModel::supportedDragActions() const -{ - return sourceModel()->supportedDragActions(); -} +private: + void modelUpdated(); + void updateIndex(); + void updateIndexNow(); + void updateTextCursor(const QModelIndex &index); + void onItemActivated(const QModelIndex &index); + bool syncCursor(); + CppEditorWidget *m_editor; + CppOutlineTreeView *m_treeView; + OutlineModel * const m_model; + QSortFilterProxyModel *m_proxyModel; + QTimer m_updateIndexTimer; + + bool m_enableCursorSync; + bool m_blockCursorSync; + bool m_sorted; +}; CppOutlineWidget::CppOutlineWidget(CppEditorWidget *editor) : m_editor(editor), @@ -229,5 +273,4 @@ TextEditor::IOutlineWidget *CppOutlineWidgetFactory::createWidget(Core::IEditor return new CppOutlineWidget(cppEditorWidget); } -} // namespace Internal -} // namespace CppEditor +} // namespace CppEditor::Internal diff --git a/src/plugins/cppeditor/cppoutline.h b/src/plugins/cppeditor/cppoutline.h index 8b845cba653..724f623bd3a 100644 --- a/src/plugins/cppeditor/cppoutline.h +++ b/src/plugins/cppeditor/cppoutline.h @@ -3,83 +3,16 @@ #pragma once -#include "cppeditorwidget.h" -#include "cppoutlinemodel.h" - #include -#include +namespace CppEditor::Internal { -#include -#include - -namespace CppEditor { -namespace Internal { - -class CppOutlineTreeView : public Utils::NavigationTreeView +class CppOutlineWidgetFactory final : public TextEditor::IOutlineWidgetFactory { - Q_OBJECT public: - CppOutlineTreeView(QWidget *parent); - - void contextMenuEvent(QContextMenuEvent *event) override; + bool supportsEditor(Core::IEditor *editor) const final; + bool supportsSorting() const final { return true; } + TextEditor::IOutlineWidget *createWidget(Core::IEditor *editor) final; }; -class CppOutlineFilterModel : public QSortFilterProxyModel -{ - Q_OBJECT -public: - CppOutlineFilterModel(OutlineModel &sourceModel, QObject *parent); - // QSortFilterProxyModel - bool filterAcceptsRow(int sourceRow, - const QModelIndex &sourceParent) const override; - Qt::DropActions supportedDragActions() const override; -private: - OutlineModel &m_sourceModel; -}; - -class CppOutlineWidget : public TextEditor::IOutlineWidget -{ - Q_OBJECT -public: - CppOutlineWidget(CppEditorWidget *editor); - - // IOutlineWidget - QList filterMenuActions() const override; - void setCursorSynchronization(bool syncWithCursor) override; - bool isSorted() const override; - void setSorted(bool sorted) override; - - void restoreSettings(const QVariantMap &map) override; - QVariantMap settings() const override; -private: - void modelUpdated(); - void updateIndex(); - void updateIndexNow(); - void updateTextCursor(const QModelIndex &index); - void onItemActivated(const QModelIndex &index); - bool syncCursor(); - -private: - CppEditorWidget *m_editor; - CppOutlineTreeView *m_treeView; - OutlineModel * const m_model; - QSortFilterProxyModel *m_proxyModel; - QTimer m_updateIndexTimer; - - bool m_enableCursorSync; - bool m_blockCursorSync; - bool m_sorted; -}; - -class CppOutlineWidgetFactory : public TextEditor::IOutlineWidgetFactory -{ - Q_OBJECT -public: - bool supportsEditor(Core::IEditor *editor) const override; - bool supportsSorting() const override { return true; } - TextEditor::IOutlineWidget *createWidget(Core::IEditor *editor) override; -}; - -} // namespace Internal -} // namespace CppEditor +} // namespace CppEditor::Internal From ab549936f8410e707f554981d22c9694bea06019 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 13 Nov 2023 14:34:31 +0100 Subject: [PATCH 0167/1546] Core: Remove commented code that adds `About Qt` action This is better handled via the `System Information` action nowadays Change-Id: I220ba9e7db433f0c644dd3a04cc1cc6bf13aa56d Reviewed-by: hjk --- src/plugins/coreplugin/icore.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index 3dfd69840a3..56c1b18937d 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -1896,13 +1896,6 @@ void ICorePrivate::registerDefaultActions() aboutPluginsAction.setEnabled(true); aboutPluginsAction.setOnTriggered(this, [this] { aboutPlugins(); }); - // About Qt Action - // ActionBuilder aboutQtAction(this, Constants:: ABOUT_QT); - // aboutQtAction.setText(Tr::tr("About &Qt..."), this); - // aboutQtAction.setContainer(Constants::M_HELP, Constants::G_HELP_ABOUT); - // aboutQtAction.setEnabled(true); - // aboutQtAction.setOnTriggered(this, &QApplication::aboutQt); - // Change Log Action ActionBuilder changeLogAction(this, Constants::CHANGE_LOG); changeLogAction.setText(Tr::tr("Change Log...")); From 78c38ab9bf42bfd567ff5f98f4d346fd9e7e69cf Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 10 Nov 2023 20:06:28 +0100 Subject: [PATCH 0168/1546] Core: Inform about active UI scaling related environment variables There are a couple of environment variables which can influence the UI scaling behavior. If any of those is set, now show an info label next to the policy combo box in the Environment/Interface settings. Change-Id: I91619d73bf53761f9cd4d7ae8bbf9b49b2010012 Reviewed-by: Cristian Adam --- src/app/main.cpp | 2 +- src/libs/utils/stylehelper.h | 2 ++ src/plugins/coreplugin/generalsettings.cpp | 21 ++++++++++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/app/main.cpp b/src/app/main.cpp index bedbb5d39c9..b555596f875 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -283,7 +283,7 @@ static void setHighDpiEnvironmentVariable() { if (Utils::StyleHelper::defaultHighDpiScaleFactorRoundingPolicy() == Qt::HighDpiScaleFactorRoundingPolicy::Unset - || qEnvironmentVariableIsSet("QT_SCALE_FACTOR_ROUNDING_POLICY")) + || qEnvironmentVariableIsSet(Utils::StyleHelper::C_QT_SCALE_FACTOR_ROUNDING_POLICY)) return; std::unique_ptr settings(createUserSettings()); diff --git a/src/libs/utils/stylehelper.h b/src/libs/utils/stylehelper.h index ac5e53a4bd4..a7656b3eb3a 100644 --- a/src/libs/utils/stylehelper.h +++ b/src/libs/utils/stylehelper.h @@ -39,6 +39,8 @@ constexpr char C_SHOW_BORDER[] = "showborder"; constexpr char C_TOP_BORDER[] = "topBorder"; constexpr char C_TOOLBAR_ACTIONWIDGET[] = "toolbar_actionWidget"; +constexpr char C_QT_SCALE_FACTOR_ROUNDING_POLICY[] = "QT_SCALE_FACTOR_ROUNDING_POLICY"; + enum ToolbarStyle { ToolbarStyleCompact, ToolbarStyleRelaxed, diff --git a/src/plugins/coreplugin/generalsettings.cpp b/src/plugins/coreplugin/generalsettings.cpp index 3087b0d8c4b..4f9f8b9fb34 100644 --- a/src/plugins/coreplugin/generalsettings.cpp +++ b/src/plugins/coreplugin/generalsettings.cpp @@ -146,6 +146,7 @@ GeneralSettingsWidget::GeneralSettingsWidget() int(Policy::RoundPreferFloor)); m_policyComboBox->addItem(Tr::tr("Don't Round"), int(Policy::PassThrough)); m_policyComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents); + m_policyComboBox->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); const Policy userPolicy = ICore::settings()->value(settingsKeyDpiPolicy, @@ -153,7 +154,25 @@ GeneralSettingsWidget::GeneralSettingsWidget() .value(); m_policyComboBox->setCurrentIndex(m_policyComboBox->findData(int(userPolicy))); - form.addRow({Tr::tr("DPI rounding policy:"), m_policyComboBox, st}); + form.addRow({Tr::tr("DPI rounding policy:"), m_policyComboBox}); + static const char *envVars[] = { + StyleHelper::C_QT_SCALE_FACTOR_ROUNDING_POLICY, "QT_ENABLE_HIGHDPI_SCALING", + "QT_FONT_DPI", "QT_SCALE_FACTOR", "QT_SCREEN_SCALE_FACTORS", "QT_USE_PHYSICAL_DPI", + }; + if (anyOf(envVars, qEnvironmentVariableIsSet)) { + QString toolTip = Tr::tr("The following environment variables are set and can " + "influence the UI scaling behavior of %1:") + .arg(QGuiApplication::applicationDisplayName()) + "\n"; + for (auto var : envVars) { + if (qEnvironmentVariableIsSet(var)) + toolTip.append(QLatin1String("\n") + var + "=" + qEnvironmentVariable(var)); + } + auto envVarInfo = new InfoLabel(Tr::tr("Environment influences UI scaling behavior.")); + envVarInfo->setAdditionalToolTip(toolTip); + form.addItem(envVarInfo); + } else { + form.addItem(st); + } } form.addRow({empty, generalSettings().showShortcutsInContextMenus}); From 9e00e1d6a09e363454477e59a91733800f3399c2 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 13 Nov 2023 16:15:33 +0100 Subject: [PATCH 0169/1546] Plugin wizard: Use Tr::tr Create plugins that use the Tr::tr pattern for translations. Change-Id: I9b6e6222951936c614c5ac45248e3d0bb58104ec Reviewed-by: hjk Reviewed-by: Alessandro Portale --- .../templates/wizards/qtcreatorplugin/CMakeLists.txt | 1 + .../templates/wizards/qtcreatorplugin/myplugin.cpp | 11 ++++++----- .../templates/wizards/qtcreatorplugin/myplugintr.h | 12 ++++++++++++ .../templates/wizards/qtcreatorplugin/wizard.json | 5 +++++ 4 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 share/qtcreator/templates/wizards/qtcreatorplugin/myplugintr.h diff --git a/share/qtcreator/templates/wizards/qtcreatorplugin/CMakeLists.txt b/share/qtcreator/templates/wizards/qtcreatorplugin/CMakeLists.txt index a60e46cb7cd..be6f16a3fb6 100644 --- a/share/qtcreator/templates/wizards/qtcreatorplugin/CMakeLists.txt +++ b/share/qtcreator/templates/wizards/qtcreatorplugin/CMakeLists.txt @@ -54,4 +54,5 @@ add_qtc_plugin(%{PluginName} %{HdrFileName} %{GlobalHdrFileName} %{ConstantsHdrFileName} + %{TrHdrFileName} ) diff --git a/share/qtcreator/templates/wizards/qtcreatorplugin/myplugin.cpp b/share/qtcreator/templates/wizards/qtcreatorplugin/myplugin.cpp index e25c6a22c33..aee6863fb63 100644 --- a/share/qtcreator/templates/wizards/qtcreatorplugin/myplugin.cpp +++ b/share/qtcreator/templates/wizards/qtcreatorplugin/myplugin.cpp @@ -1,5 +1,6 @@ #include "%{HdrFileName}" #include "%{ConstantsHdrFileName}" +#include "%{TrHdrFileName}" #include #include @@ -39,14 +40,14 @@ void %{CN}::initialize() // bool IPlugin::initialize(const QStringList &arguments, QString *errorString) // overload. - auto action = new QAction(tr("%{PluginName} Action"), this); + auto action = new QAction(Tr::tr("%{PluginName} Action"), this); Core::Command *cmd = Core::ActionManager::registerAction(action, Constants::ACTION_ID, Core::Context(Core::Constants::C_GLOBAL)); - cmd->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Meta+A"))); + cmd->setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+Alt+Meta+A"))); connect(action, &QAction::triggered, this, &%{CN}::triggerAction); Core::ActionContainer *menu = Core::ActionManager::createMenu(Constants::MENU_ID); - menu->menu()->setTitle(tr("%{PluginName}")); + menu->menu()->setTitle(Tr::tr("%{PluginName}")); menu->addAction(cmd); Core::ActionManager::actionContainer(Core::Constants::M_TOOLS)->addMenu(menu); } @@ -69,8 +70,8 @@ ExtensionSystem::IPlugin::ShutdownFlag %{CN}::aboutToShutdown() void %{CN}::triggerAction() { QMessageBox::information(Core::ICore::mainWindow(), - tr("Action Triggered"), - tr("This is an action from %{PluginName}.")); + Tr::tr("Action Triggered"), + Tr::tr("This is an action from %{PluginName}.")); } } // namespace %{PluginName}::Internal diff --git a/share/qtcreator/templates/wizards/qtcreatorplugin/myplugintr.h b/share/qtcreator/templates/wizards/qtcreatorplugin/myplugintr.h new file mode 100644 index 00000000000..1dc9ed3dafc --- /dev/null +++ b/share/qtcreator/templates/wizards/qtcreatorplugin/myplugintr.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +namespace %{PluginName} { + +struct Tr +{ + Q_DECLARE_TR_FUNCTIONS(QtC::%{PluginName}) +}; + +} // namespace %{PluginName} diff --git a/share/qtcreator/templates/wizards/qtcreatorplugin/wizard.json b/share/qtcreator/templates/wizards/qtcreatorplugin/wizard.json index 0d3e20ef5e2..e1feaa53bbb 100644 --- a/share/qtcreator/templates/wizards/qtcreatorplugin/wizard.json +++ b/share/qtcreator/templates/wizards/qtcreatorplugin/wizard.json @@ -22,6 +22,7 @@ { "key": "HdrFileName", "value": "%{JS: Util.fileName(value('PluginNameLower'), Util.preferredSuffix('text/x-c++hdr'))}" }, { "key": "GlobalHdrFileName", "value": "%{JS: Util.fileName(value('PluginNameLower') + '_global', Util.preferredSuffix('text/x-c++hdr'))}" }, { "key": "ConstantsHdrFileName", "value": "%{JS: Util.fileName(value('PluginNameLower') + 'constants', Util.preferredSuffix('text/x-c++hdr'))}" }, + { "key": "TrHdrFileName", "value": "%{JS: Util.fileName(value('PluginNameLower') + 'tr', Util.preferredSuffix('text/x-c++hdr'))}" }, { "key": "CN", "value": "%{JS: Cpp.className(value('PluginName') + 'Plugin')}" }, { "key": "HasTranslation", "value": "%{JS: value('TsFileName') !== ''}" } ], @@ -181,6 +182,10 @@ "source": "mypluginconstants.h", "target": "%{ConstantsHdrFileName}" }, + { + "source": "myplugintr.h", + "target": "%{TrHdrFileName}" + }, { "source": "MyPlugin.json.in", "target": "%{PluginJsonFile}" From bb27b3b02a996a53d9c0e808a523c46768d56654 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 13 Nov 2023 16:17:16 +0100 Subject: [PATCH 0170/1546] ExtensionSystem: Use dependency order when loading plugins at runtime And also run IPlugin::delayedInitialize when loading plugins at runtime Amends 32914fe66b75913cac593d698ccdfceec2095e51 Change-Id: Ib2a6c4c6122dd1ac915f7755b0d7ea232fa635e8 Reviewed-by: Marcus Tillmanns --- src/libs/extensionsystem/pluginmanager.cpp | 32 +++++++++++++++++++--- src/libs/extensionsystem/pluginmanager.h | 2 +- src/libs/extensionsystem/pluginmanager_p.h | 1 + src/plugins/coreplugin/plugindialog.cpp | 5 ++-- 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index 7114813bd71..22ce4786046 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -322,11 +322,9 @@ void PluginManager::loadPlugins() d->loadPlugins(); } -void PluginManager::loadPlugin(PluginSpec *spec) +void PluginManager::loadPluginsAtRuntime(const QSet &plugins) { - d->loadPlugin(spec, PluginSpec::Loaded); - d->loadPlugin(spec, PluginSpec::Initialized); - d->loadPlugin(spec, PluginSpec::Running); + d->loadPluginsAtRuntime(plugins); } /*! @@ -1389,6 +1387,32 @@ void PluginManagerPrivate::loadPlugins() delayedInitializeTimer.start(); } +void PluginManagerPrivate::loadPluginsAtRuntime(const QSet &plugins) +{ + QTC_CHECK(allOf(plugins, [](PluginSpec *spec) { return spec->isSoftLoadable(); })); + // load the plugins ordered by dependency + const QList queue = filtered(loadQueue(), [&plugins](PluginSpec *spec) { + return plugins.contains(spec); + }); + std::queue localDelayedInitializeQueue; + for (PluginSpec *spec : queue) + loadPlugin(spec, PluginSpec::Loaded); + for (PluginSpec *spec : queue) + loadPlugin(spec, PluginSpec::Initialized); + Utils::reverseForeach(queue, + [this](PluginSpec *spec) { loadPlugin(spec, PluginSpec::Running); }); + Utils::reverseForeach(queue, [](PluginSpec *spec) { + if (spec->state() == PluginSpec::Running) { + const bool delay = spec->d->delayedInitialize(); + if (delay) + QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); + } else { + // Plugin initialization failed, so cleanup after it + spec->d->kill(); + } + }); +} + /*! \internal */ diff --git a/src/libs/extensionsystem/pluginmanager.h b/src/libs/extensionsystem/pluginmanager.h index 97bb7f26473..a38f3c3fe7b 100644 --- a/src/libs/extensionsystem/pluginmanager.h +++ b/src/libs/extensionsystem/pluginmanager.h @@ -68,7 +68,7 @@ public: // Plugin operations static QVector loadQueue(); static void loadPlugins(); - static void loadPlugin(PluginSpec *); + static void loadPluginsAtRuntime(const QSet &plugins); static QStringList pluginPaths(); static void setPluginPaths(const QStringList &paths); static QString pluginIID(); diff --git a/src/libs/extensionsystem/pluginmanager_p.h b/src/libs/extensionsystem/pluginmanager_p.h index 3de21388bbb..c92eb5be2e4 100644 --- a/src/libs/extensionsystem/pluginmanager_p.h +++ b/src/libs/extensionsystem/pluginmanager_p.h @@ -51,6 +51,7 @@ public: // Plugin operations void checkForProblematicPlugins(); void loadPlugins(); + void loadPluginsAtRuntime(const QSet &plugins); void shutdown(); void setPluginPaths(const QStringList &paths); const QVector loadQueue(); diff --git a/src/plugins/coreplugin/plugindialog.cpp b/src/plugins/coreplugin/plugindialog.cpp index 8aa87d4e829..cedf5438a61 100644 --- a/src/plugins/coreplugin/plugindialog.cpp +++ b/src/plugins/coreplugin/plugindialog.cpp @@ -88,10 +88,9 @@ void PluginDialog::closeDialog() { PluginManager::writeSettings(); - for (PluginSpec *plugin : m_softLoad) { - PluginManager::loadPlugin(plugin); + PluginManager::loadPluginsAtRuntime(m_softLoad); + for (PluginSpec *plugin : std::as_const(m_softLoad)) CorePlugin::loadMimeFromPlugin(plugin); - } if (m_isRestartRequired) { RestartDialog restartDialog(ICore::dialogParent(), From e3856289fe10a76e303dd65d255302d4921eee49 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 13 Nov 2023 14:22:14 +0100 Subject: [PATCH 0171/1546] ClangCodeModel: Fix capitalization of menu item Amends d0203a39fa9ec63ee155d536151c39447e83e056 Change-Id: Ie7d63927907027dfddc579f66e6e9b1c51a10bd9 Reviewed-by: Christian Kandeler Reviewed-by: --- src/plugins/clangcodemodel/clangcodemodelplugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp index e8b8f5e28df..cf967f24998 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp @@ -84,8 +84,8 @@ void ClangCodeModelPlugin::initialize() CppEditor::CppModelManager::activateClangCodeModel(std::make_unique()); createCompilationDBAction(); - QAction * const updateStaleIndexEntries - = new QAction(Tr::tr("Update potentially stale clangd index entries"), this); + QAction *const updateStaleIndexEntries + = new QAction(Tr::tr("Update Potentially Stale Clangd Index Entries"), this); Command * const cmd = ActionManager::registerAction(updateStaleIndexEntries, "ClangCodeModel.UpdateStaleIndexEntries"); connect(updateStaleIndexEntries, &QAction::triggered, this, From 031b2162ee776d68262e9495fdcfc5b52b70de5d Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 14 Nov 2023 09:58:35 +0100 Subject: [PATCH 0172/1546] Use Tr::tr in HelloWorld plugin The header was already there Change-Id: I767bcc671cb05579de83f3d8e753f887230745ec Reviewed-by: hjk --- src/plugins/helloworld/helloworldplugin.cpp | 15 +++++++++------ src/plugins/helloworld/helloworldwindow.cpp | 6 ++++-- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/plugins/helloworld/helloworldplugin.cpp b/src/plugins/helloworld/helloworldplugin.cpp index 9269910ce55..88e0d1ea3f1 100644 --- a/src/plugins/helloworld/helloworldplugin.cpp +++ b/src/plugins/helloworld/helloworldplugin.cpp @@ -3,6 +3,8 @@ #include "helloworldplugin.h" +#include "helloworldtr.h" + #include #include #include @@ -25,9 +27,9 @@ class HelloMode : public Core::IMode public: HelloMode() { - setWidget(new QPushButton(tr("Hello World PushButton!"))); + setWidget(new QPushButton(Tr::tr("Hello World PushButton!"))); setContext(Core::Context("HelloWorld.MainView")); - setDisplayName(tr("Hello world!")); + setDisplayName(Tr::tr("Hello world!")); setIcon(QIcon()); setPriority(0); setId("HelloWorld.HelloWorldMode"); @@ -63,7 +65,7 @@ void HelloWorldPlugin::initialize() Core::Context context("HelloWorld.MainView"); // Create an action to be triggered by a menu entry - auto helloWorldAction = new QAction(tr("Say \"&Hello World!\""), this); + auto helloWorldAction = new QAction(Tr::tr("Say \"&Hello World!\""), this); connect(helloWorldAction, &QAction::triggered, this, &HelloWorldPlugin::sayHelloWorld); // Register the action with the action manager @@ -75,7 +77,7 @@ void HelloWorldPlugin::initialize() Core::ActionContainer *helloWorldMenu = Core::ActionManager::createMenu("HelloWorld.HelloWorldMenu"); QMenu *menu = helloWorldMenu->menu(); - menu->setTitle(tr("&Hello World")); + menu->setTitle(Tr::tr("&Hello World")); menu->setEnabled(true); // Add the Hello World action command to the menu @@ -109,8 +111,9 @@ void HelloWorldPlugin::sayHelloWorld() { // When passing nullptr for the parent, the message box becomes an // application-global modal dialog box - QMessageBox::information( - nullptr, tr("Hello World!"), tr("Hello World! Beautiful day today, isn't it?")); + QMessageBox::information(nullptr, + Tr::tr("Hello World!"), + Tr::tr("Hello World! Beautiful day today, isn't it?")); } } // namespace HelloWorld::Internal diff --git a/src/plugins/helloworld/helloworldwindow.cpp b/src/plugins/helloworld/helloworldwindow.cpp index b906bc39be5..8d958b36494 100644 --- a/src/plugins/helloworld/helloworldwindow.cpp +++ b/src/plugins/helloworld/helloworldwindow.cpp @@ -3,6 +3,8 @@ #include "helloworldwindow.h" +#include "helloworldtr.h" + #include #include @@ -12,6 +14,6 @@ HelloWorldWindow::HelloWorldWindow(QWidget *parent) : QWidget(parent) { auto layout = new QVBoxLayout(this); - layout->addWidget(new QTextEdit(tr("Focus me to activate my context!"))); - setWindowTitle(tr("Hello, world!")); + layout->addWidget(new QTextEdit(Tr::tr("Focus me to activate my context!"))); + setWindowTitle(Tr::tr("Hello, world!")); } From 5922227642a726ac4e79134ae28ac7046339a5bb Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 10 Nov 2023 16:24:01 +0100 Subject: [PATCH 0173/1546] Boot2Qt: Use ActionBuilder to create flash action Clearer code. Change-Id: I9fc8f7f8ddc704689fed6e40d92f827067d19e40 Reviewed-by: Christian Stenger --- src/plugins/boot2qt/qdbplugin.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/plugins/boot2qt/qdbplugin.cpp b/src/plugins/boot2qt/qdbplugin.cpp index de1a7557c83..ec61e7c33a7 100644 --- a/src/plugins/boot2qt/qdbplugin.cpp +++ b/src/plugins/boot2qt/qdbplugin.cpp @@ -36,6 +36,7 @@ #include +using namespace Core; using namespace ProjectExplorer; using namespace Utils; @@ -80,21 +81,16 @@ void registerFlashAction(QObject *parentForAction) } const char flashActionId[] = "Qdb.FlashAction"; - if (Core::ActionManager::command(flashActionId)) + if (ActionManager::command(flashActionId)) return; // The action has already been registered. - Core::ActionContainer *toolsContainer = - Core::ActionManager::actionContainer(Core::Constants::M_TOOLS); + ActionContainer *toolsContainer = ActionManager::actionContainer(Core::Constants::M_TOOLS); toolsContainer->insertGroup(Core::Constants::G_TOOLS_DEBUG, flashActionId); - Core::Context globalContext(Core::Constants::C_GLOBAL); - - QAction *flashAction = new QAction(Tr::tr("Flash Boot to Qt Device"), parentForAction); - Core::Command *flashCommand = Core::ActionManager::registerAction(flashAction, - flashActionId, - globalContext); - QObject::connect(flashAction, &QAction::triggered, startFlashingWizard); - toolsContainer->addAction(flashCommand, flashActionId); + ActionBuilder flashAction(parentForAction, flashActionId); + flashAction.setText(Tr::tr("Flash Boot to Qt Device")); + flashAction.setContainer(Core::Constants::G_TOOLS_DEBUG, flashActionId); + flashAction.setOnTriggered(&startFlashingWizard); } class QdbDeployStepFactory : public BuildStepFactory From 5acce4bd7f80784e253f63a3e8aaafb7ad756adb Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 14 Nov 2023 09:07:07 +0100 Subject: [PATCH 0174/1546] Core: Don't leak ActionBuilderPrivate Change-Id: If98ac5c30ea376b8f9a62b63dae13c1c803b32c5 Reviewed-by: Marcus Tillmanns --- src/plugins/coreplugin/actionmanager/actionmanager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index a8fd5c1f29b..08e2acb4bc9 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -102,6 +102,7 @@ ActionBuilder::ActionBuilder(QObject *contextActionParent, const Id actionId) ActionBuilder::~ActionBuilder() { d->registerAction(); + delete d; } void ActionBuilder::setText(const QString &text) From f6e403b219d779e358396a57960d607ff557652e Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 9 Nov 2023 08:28:12 +0100 Subject: [PATCH 0175/1546] Python: split buildsystem and project into separate files Change-Id: Ic226ff6685cb6657a5e83258aab151754d80b3bf Reviewed-by: Christian Stenger --- src/plugins/python/CMakeLists.txt | 1 + src/plugins/python/python.qbs | 2 + src/plugins/python/pythonbuildsystem.cpp | 364 +++++++++++++++++++ src/plugins/python/pythonbuildsystem.h | 50 +++ src/plugins/python/pythonproject.cpp | 425 +---------------------- src/plugins/python/pythonproject.h | 21 ++ 6 files changed, 453 insertions(+), 410 deletions(-) create mode 100644 src/plugins/python/pythonbuildsystem.cpp create mode 100644 src/plugins/python/pythonbuildsystem.h diff --git a/src/plugins/python/CMakeLists.txt b/src/plugins/python/CMakeLists.txt index 8c48f9cdbba..25861c9ceed 100644 --- a/src/plugins/python/CMakeLists.txt +++ b/src/plugins/python/CMakeLists.txt @@ -7,6 +7,7 @@ add_qtc_plugin(Python pysidebuildconfiguration.cpp pysidebuildconfiguration.h pysideuicextracompiler.cpp pysideuicextracompiler.h python.qrc + pythonbuildsystem.cpp pythonbuildsystem.h pythonconstants.h pythoneditor.cpp pythoneditor.h pythonformattoken.h diff --git a/src/plugins/python/python.qbs b/src/plugins/python/python.qbs index 057822a1e97..eee19bb0c7f 100644 --- a/src/plugins/python/python.qbs +++ b/src/plugins/python/python.qbs @@ -27,6 +27,8 @@ QtcPlugin { "pysideuicextracompiler.cpp", "pysideuicextracompiler.h", "python.qrc", + "pythonbuildsystem.cpp", + "pythonbuildsystem.h", "pythonconstants.h", "pythoneditor.cpp", "pythoneditor.h", diff --git a/src/plugins/python/pythonbuildsystem.cpp b/src/plugins/python/pythonbuildsystem.cpp new file mode 100644 index 00000000000..5754063d858 --- /dev/null +++ b/src/plugins/python/pythonbuildsystem.cpp @@ -0,0 +1,364 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "pythonbuildsystem.h" + +#include "pythonconstants.h" +#include "pythonproject.h" +#include "pythontr.h" + +#include +#include + +#include + +#include + +#include +#include + +#include +#include +#include + +using namespace Core; +using namespace ProjectExplorer; +using namespace Utils; + +namespace Python::Internal { + +static QJsonObject readObjJson(const FilePath &projectFile, QString *errorMessage) +{ + const expected_str fileContentsResult = projectFile.fileContents(); + if (!fileContentsResult) { + *errorMessage = fileContentsResult.error(); + return {}; + } + + const QByteArray content = *fileContentsResult; + + // This assumes the project file is formed with only one field called + // 'files' that has a list associated of the files to include in the project. + if (content.isEmpty()) { + *errorMessage = Tr::tr("Unable to read \"%1\": The file is empty.") + .arg(projectFile.toUserOutput()); + return QJsonObject(); + } + + QJsonParseError error; + const QJsonDocument doc = QJsonDocument::fromJson(content, &error); + if (doc.isNull()) { + const int line = content.left(error.offset).count('\n') + 1; + *errorMessage = Tr::tr("Unable to parse \"%1\":%2: %3") + .arg(projectFile.toUserOutput()).arg(line) + .arg(error.errorString()); + return QJsonObject(); + } + + return doc.object(); +} + +static QStringList readLines(const FilePath &projectFile) +{ + QSet visited; + QStringList lines; + + const expected_str contents = projectFile.fileContents(); + if (contents) { + QTextStream stream(contents.value()); + + while (true) { + const QString line = stream.readLine(); + if (line.isNull()) + break; + if (!Utils::insert(visited, line)) + continue; + lines.append(line); + } + } + + return lines; +} + +static QStringList readLinesJson(const FilePath &projectFile, QString *errorMessage) +{ + QSet visited; + QStringList lines; + + const QJsonObject obj = readObjJson(projectFile, errorMessage); + const QJsonArray files = obj.value("files").toArray(); + for (const QJsonValue &file : files) { + const QString fileName = file.toString(); + if (Utils::insert(visited, fileName)) + lines.append(fileName); + } + + return lines; +} + +static QStringList readImportPathsJson(const FilePath &projectFile, QString *errorMessage) +{ + QStringList importPaths; + + const QJsonObject obj = readObjJson(projectFile, errorMessage); + if (obj.contains("qmlImportPaths")) { + const QJsonValue dirs = obj.value("qmlImportPaths"); + const QJsonArray dirs_array = dirs.toArray(); + + QSet visited; + + for (const auto &dir : dirs_array) + visited.insert(dir.toString()); + + importPaths.append(Utils::toList(visited)); + } + + return importPaths; +} + +PythonBuildSystem::PythonBuildSystem(Target *target) + : BuildSystem(target) +{ + connect(target->project(), &Project::projectFileIsDirty, this, [this] { triggerParsing(); }); + triggerParsing(); +} + +bool PythonBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const +{ + if (node->asFileNode()) { + return action == ProjectAction::Rename + || action == ProjectAction::RemoveFile; + } + if (node->isFolderNodeType() || node->isProjectNodeType()) { + return action == ProjectAction::AddNewFile + || action == ProjectAction::RemoveFile + || action == ProjectAction::AddExistingFile; + } + return BuildSystem::supportsAction(context, action, node); +} + +static FileType getFileType(const FilePath &f) +{ + if (f.endsWith(".py")) + return FileType::Source; + if (f.endsWith(".qrc")) + return FileType::Resource; + if (f.endsWith(".ui")) + return FileType::Form; + if (f.endsWith(".qml") || f.endsWith(".js")) + return FileType::QML; + return Node::fileTypeForFileName(f); +} + +void PythonBuildSystem::triggerParsing() +{ + ParseGuard guard = guardParsingRun(); + parse(); + + QList appTargets; + + auto newRoot = std::make_unique(projectDirectory()); + + const FilePath projectFile = projectFilePath(); + const QString displayName = projectFile.relativePathFrom(projectDirectory()).toUserOutput(); + newRoot->addNestedNode( + std::make_unique(projectFile, displayName, FileType::Project)); + + for (const FileEntry &entry : std::as_const(m_files)) { + const QString displayName = entry.filePath.relativePathFrom(projectDirectory()).toUserOutput(); + const FileType fileType = getFileType(entry.filePath); + + newRoot->addNestedNode(std::make_unique(entry.filePath, displayName, fileType)); + const MimeType mt = mimeTypeForFile(entry.filePath, MimeMatchMode::MatchExtension); + if (mt.matchesName(Constants::C_PY_MIMETYPE) || mt.matchesName(Constants::C_PY3_MIMETYPE) + || mt.matchesName(Constants::C_PY_GUI_MIMETYPE)) { + BuildTargetInfo bti; + bti.displayName = displayName; + bti.buildKey = entry.filePath.toString(); + bti.targetFilePath = entry.filePath; + bti.projectFilePath = projectFile; + bti.isQtcRunnable = entry.filePath.fileName() == "main.py"; + appTargets.append(bti); + } + } + setRootProjectNode(std::move(newRoot)); + + setApplicationTargets(appTargets); + + auto modelManager = QmlJS::ModelManagerInterface::instance(); + if (modelManager) { + const auto hiddenRccFolders = project()->files(Project::HiddenRccFolders); + auto projectInfo = modelManager->defaultProjectInfoForProject(project(), hiddenRccFolders); + + for (const FileEntry &importPath : std::as_const(m_qmlImportPaths)) { + if (!importPath.filePath.isEmpty()) + projectInfo.importPaths.maybeInsert(importPath.filePath, QmlJS::Dialect::Qml); + } + + modelManager->updateProjectInfo(projectInfo, project()); + } + + guard.markAsSuccess(); + + emitBuildSystemUpdated(); +} + +bool PythonBuildSystem::save() +{ + const FilePath filePath = projectFilePath(); + const QStringList rawList = Utils::transform(m_files, &FileEntry::rawEntry); + const FileChangeBlocker changeGuard(filePath); + bool result = false; + + QByteArray newContents; + + // New project file + if (filePath.endsWith(".pyproject")) { + expected_str contents = filePath.fileContents(); + if (contents) { + QJsonDocument doc = QJsonDocument::fromJson(*contents); + QJsonObject project = doc.object(); + project["files"] = QJsonArray::fromStringList(rawList); + doc.setObject(project); + newContents = doc.toJson(); + } else { + MessageManager::writeDisrupting(contents.error()); + } + } else { // Old project file + newContents = rawList.join('\n').toUtf8(); + } + + const expected_str writeResult = filePath.writeFileContents(newContents); + if (writeResult) + result = true; + else + MessageManager::writeDisrupting(writeResult.error()); + + return result; +} + +bool PythonBuildSystem::addFiles(Node *, const FilePaths &filePaths, FilePaths *) +{ + const FilePath projectDir = projectDirectory(); + + auto comp = [](const FileEntry &left, const FileEntry &right) { + return left.rawEntry < right.rawEntry; + }; + + const bool isSorted = std::is_sorted(m_files.begin(), m_files.end(), comp); + + for (const FilePath &filePath : filePaths) { + if (!projectDir.isSameDevice(filePath)) + return false; + m_files.append(FileEntry{filePath.relativePathFrom(projectDir).toString(), filePath}); + } + + if (isSorted) + std::sort(m_files.begin(), m_files.end(), comp); + + return save(); +} + +RemovedFilesFromProject PythonBuildSystem::removeFiles(Node *, const FilePaths &filePaths, FilePaths *) +{ + + for (const FilePath &filePath : filePaths) { + Utils::eraseOne(m_files, + [filePath](const FileEntry &entry) { return filePath == entry.filePath; }); + } + + return save() ? RemovedFilesFromProject::Ok : RemovedFilesFromProject::Error; +} + +bool PythonBuildSystem::deleteFiles(Node *, const FilePaths &) +{ + return true; +} + +bool PythonBuildSystem::renameFile(Node *, const FilePath &oldFilePath, const FilePath &newFilePath) +{ + for (FileEntry &entry : m_files) { + if (entry.filePath == oldFilePath) { + entry.filePath = newFilePath; + entry.rawEntry = newFilePath.relativeChildPath(projectDirectory()).toString(); + break; + } + } + + return save(); +} + +void PythonBuildSystem::parse() +{ + m_files.clear(); + m_qmlImportPaths.clear(); + + QStringList files; + QStringList qmlImportPaths; + + const FilePath filePath = projectFilePath(); + // The PySide project file is JSON based + if (filePath.endsWith(".pyproject")) { + QString errorMessage; + files = readLinesJson(filePath, &errorMessage); + if (!errorMessage.isEmpty()) + MessageManager::writeFlashing(errorMessage); + + errorMessage.clear(); + qmlImportPaths = readImportPathsJson(filePath, &errorMessage); + if (!errorMessage.isEmpty()) + MessageManager::writeFlashing(errorMessage); + } else if (filePath.endsWith(".pyqtc")) { + // To keep compatibility with PyQt we keep the compatibility with plain + // text files as project files. + files = readLines(filePath); + } + + m_files = processEntries(files); + m_qmlImportPaths = processEntries(qmlImportPaths); +} + +/** + * Expands environment variables in the given \a string when they are written + * like $$(VARIABLE). + */ +static void expandEnvironmentVariables(const Environment &env, QString &string) +{ + const QRegularExpression candidate("\\$\\$\\((.+)\\)"); + + QRegularExpressionMatch match; + int index = string.indexOf(candidate, 0, &match); + while (index != -1) { + const QString value = env.value(match.captured(1)); + + string.replace(index, match.capturedLength(), value); + index += value.length(); + + index = string.indexOf(candidate, index, &match); + } +} + +/** + * Expands environment variables and converts the path from relative to the + * project to an absolute path for all given raw paths + */ +QList PythonBuildSystem::processEntries( + const QStringList &rawPaths) const +{ + QList processed; + const FilePath projectDir = projectDirectory(); + const Environment env = projectDirectory().deviceEnvironment(); + + for (const QString &rawPath : rawPaths) { + FilePath resolvedPath; + QString path = rawPath.trimmed(); + if (!path.isEmpty()) { + expandEnvironmentVariables(env, path); + resolvedPath = projectDir.resolvePath(path); + } + processed << FileEntry{rawPath, resolvedPath}; + } + return processed; +} + +} // namespace Internal diff --git a/src/plugins/python/pythonbuildsystem.h b/src/plugins/python/pythonbuildsystem.h new file mode 100644 index 00000000000..8bd79391dc2 --- /dev/null +++ b/src/plugins/python/pythonbuildsystem.h @@ -0,0 +1,50 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +namespace Python::Internal { + +class PythonBuildSystem : public ProjectExplorer::BuildSystem +{ +public: + explicit PythonBuildSystem(ProjectExplorer::Target *target); + + bool supportsAction(ProjectExplorer::Node *context, + ProjectExplorer::ProjectAction action, + const ProjectExplorer::Node *node) const override; + bool addFiles(ProjectExplorer::Node *, + const Utils::FilePaths &filePaths, + Utils::FilePaths *) override; + ProjectExplorer::RemovedFilesFromProject removeFiles(ProjectExplorer::Node *, + const Utils::FilePaths &filePaths, + Utils::FilePaths *) override; + bool deleteFiles(ProjectExplorer::Node *, const Utils::FilePaths &) override; + bool renameFile(ProjectExplorer::Node *, + const Utils::FilePath &oldFilePath, + const Utils::FilePath &newFilePath) override; + QString name() const override { return QLatin1String("python"); } + + void parse(); + bool save(); + + bool writePyProjectFile(const Utils::FilePath &filePath, QString &content, + const QStringList &rawList, QString *errorMessage); + + void triggerParsing() final; + +private: + struct FileEntry { + QString rawEntry; + Utils::FilePath filePath; + }; + QList processEntries(const QStringList &paths) const; + + QList m_files; + QList m_qmlImportPaths; +}; + + +} // namespace Python::Internal diff --git a/src/plugins/python/pythonproject.cpp b/src/plugins/python/pythonproject.cpp index 036d5e7ce4b..c259b088406 100644 --- a/src/plugins/python/pythonproject.cpp +++ b/src/plugins/python/pythonproject.cpp @@ -3,33 +3,12 @@ #include "pythonproject.h" +#include "pythonbuildsystem.h" #include "pythonconstants.h" -#include "pythontr.h" -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include #include -#include -#include -#include - -#include -#include -#include +#include using namespace Core; using namespace ProjectExplorer; @@ -37,155 +16,6 @@ using namespace Utils; namespace Python::Internal { -class PythonBuildSystem : public BuildSystem -{ -public: - explicit PythonBuildSystem(Target *target); - - bool supportsAction(Node *context, ProjectAction action, const Node *node) const override; - bool addFiles(Node *, const FilePaths &filePaths, FilePaths *) override; - RemovedFilesFromProject removeFiles(Node *, const FilePaths &filePaths, FilePaths *) override; - bool deleteFiles(Node *, const FilePaths &) override; - bool renameFile(Node *, - const FilePath &oldFilePath, - const FilePath &newFilePath) override; - QString name() const override { return QLatin1String("python"); } - - void parse(); - bool save(); - - bool writePyProjectFile(const FilePath &filePath, QString &content, - const QStringList &rawList, QString *errorMessage); - - void triggerParsing() final; - -private: - struct FileEntry { - QString rawEntry; - FilePath filePath; - }; - QList processEntries(const QStringList &paths) const; - - QList m_files; - QList m_qmlImportPaths; -}; - -/** - * @brief Provides displayName relative to project node - */ -class PythonFileNode : public FileNode -{ -public: - PythonFileNode(const FilePath &filePath, const QString &nodeDisplayName, - FileType fileType = FileType::Source) - : FileNode(filePath, fileType) - , m_displayName(nodeDisplayName) - {} - - QString displayName() const override { return m_displayName; } -private: - QString m_displayName; -}; - -static QJsonObject readObjJson(const FilePath &projectFile, QString *errorMessage) -{ - const expected_str fileContentsResult = projectFile.fileContents(); - if (!fileContentsResult) { - *errorMessage = fileContentsResult.error(); - return {}; - } - - const QByteArray content = *fileContentsResult; - - // This assumes the project file is formed with only one field called - // 'files' that has a list associated of the files to include in the project. - if (content.isEmpty()) { - *errorMessage = Tr::tr("Unable to read \"%1\": The file is empty.") - .arg(projectFile.toUserOutput()); - return QJsonObject(); - } - - QJsonParseError error; - const QJsonDocument doc = QJsonDocument::fromJson(content, &error); - if (doc.isNull()) { - const int line = content.left(error.offset).count('\n') + 1; - *errorMessage = Tr::tr("Unable to parse \"%1\":%2: %3") - .arg(projectFile.toUserOutput()).arg(line) - .arg(error.errorString()); - return QJsonObject(); - } - - return doc.object(); -} - -static QStringList readLines(const FilePath &projectFile) -{ - QSet visited; - QStringList lines; - - const expected_str contents = projectFile.fileContents(); - if (contents) { - QTextStream stream(contents.value()); - - while (true) { - const QString line = stream.readLine(); - if (line.isNull()) - break; - if (!Utils::insert(visited, line)) - continue; - lines.append(line); - } - } - - return lines; -} - -static QStringList readLinesJson(const FilePath &projectFile, QString *errorMessage) -{ - QSet visited; - QStringList lines; - - const QJsonObject obj = readObjJson(projectFile, errorMessage); - for (const QJsonValue &file : obj.value("files").toArray()) { - const QString fileName = file.toString(); - if (Utils::insert(visited, fileName)) - lines.append(fileName); - } - - return lines; -} - -static QStringList readImportPathsJson(const FilePath &projectFile, QString *errorMessage) -{ - QStringList importPaths; - - const QJsonObject obj = readObjJson(projectFile, errorMessage); - if (obj.contains("qmlImportPaths")) { - const QJsonValue dirs = obj.value("qmlImportPaths"); - const QJsonArray dirs_array = dirs.toArray(); - - QSet visited; - - for (const auto &dir : dirs_array) - visited.insert(dir.toString()); - - importPaths.append(Utils::toList(visited)); - } - - return importPaths; -} - -class PythonProjectNode : public ProjectNode -{ -public: - PythonProjectNode(const FilePath &path) - : ProjectNode(path) - { - setDisplayName(path.completeBaseName()); - setAddFileFilter("*.py"); - } -}; - PythonProject::PythonProject(const FilePath &fileName) : Project(Constants::C_PY_MIMETYPE, fileName) { @@ -196,229 +26,6 @@ PythonProject::PythonProject(const FilePath &fileName) setBuildSystemCreator([](Target *t) { return new PythonBuildSystem(t); }); } -static FileType getFileType(const FilePath &f) -{ - if (f.endsWith(".py")) - return FileType::Source; - if (f.endsWith(".qrc")) - return FileType::Resource; - if (f.endsWith(".ui")) - return FileType::Form; - if (f.endsWith(".qml") || f.endsWith(".js")) - return FileType::QML; - return Node::fileTypeForFileName(f); -} - -void PythonBuildSystem::triggerParsing() -{ - ParseGuard guard = guardParsingRun(); - parse(); - - QList appTargets; - - auto newRoot = std::make_unique(projectDirectory()); - - const FilePath projectFile = projectFilePath(); - const QString displayName = projectFile.relativePathFrom(projectDirectory()).toUserOutput(); - newRoot->addNestedNode( - std::make_unique(projectFile, displayName, FileType::Project)); - - for (const FileEntry &entry : std::as_const(m_files)) { - const QString displayName = entry.filePath.relativePathFrom(projectDirectory()).toUserOutput(); - const FileType fileType = getFileType(entry.filePath); - - newRoot->addNestedNode(std::make_unique(entry.filePath, displayName, fileType)); - const MimeType mt = mimeTypeForFile(entry.filePath, MimeMatchMode::MatchExtension); - if (mt.matchesName(Constants::C_PY_MIMETYPE) || mt.matchesName(Constants::C_PY3_MIMETYPE) - || mt.matchesName(Constants::C_PY_GUI_MIMETYPE)) { - BuildTargetInfo bti; - bti.displayName = displayName; - bti.buildKey = entry.filePath.toString(); - bti.targetFilePath = entry.filePath; - bti.projectFilePath = projectFile; - bti.isQtcRunnable = entry.filePath.fileName() == "main.py"; - appTargets.append(bti); - } - } - setRootProjectNode(std::move(newRoot)); - - setApplicationTargets(appTargets); - - auto modelManager = QmlJS::ModelManagerInterface::instance(); - if (modelManager) { - const auto hiddenRccFolders = project()->files(Project::HiddenRccFolders); - auto projectInfo = modelManager->defaultProjectInfoForProject(project(), hiddenRccFolders); - - for (const FileEntry &importPath : std::as_const(m_qmlImportPaths)) { - if (!importPath.filePath.isEmpty()) - projectInfo.importPaths.maybeInsert(importPath.filePath, QmlJS::Dialect::Qml); - } - - modelManager->updateProjectInfo(projectInfo, project()); - } - - guard.markAsSuccess(); - - emitBuildSystemUpdated(); -} - -bool PythonBuildSystem::save() -{ - const FilePath filePath = projectFilePath(); - const QStringList rawList = Utils::transform(m_files, &FileEntry::rawEntry); - const FileChangeBlocker changeGuarg(filePath); - bool result = false; - - QByteArray newContents; - - // New project file - if (filePath.endsWith(".pyproject")) { - expected_str contents = filePath.fileContents(); - if (contents) { - QJsonDocument doc = QJsonDocument::fromJson(*contents); - QJsonObject project = doc.object(); - project["files"] = QJsonArray::fromStringList(rawList); - doc.setObject(project); - newContents = doc.toJson(); - } else { - MessageManager::writeDisrupting(contents.error()); - } - } else { // Old project file - newContents = rawList.join('\n').toUtf8(); - } - - const expected_str writeResult = filePath.writeFileContents(newContents); - if (writeResult) - result = true; - else - MessageManager::writeDisrupting(writeResult.error()); - - return result; -} - -bool PythonBuildSystem::addFiles(Node *, const FilePaths &filePaths, FilePaths *) -{ - const Utils::FilePath projectDir = projectDirectory(); - - auto comp = [](const FileEntry &left, const FileEntry &right) { - return left.rawEntry < right.rawEntry; - }; - - const bool isSorted = std::is_sorted(m_files.begin(), m_files.end(), comp); - - for (const FilePath &filePath : filePaths) { - if (!projectDir.isSameDevice(filePath)) - return false; - m_files.append(FileEntry{filePath.relativePathFrom(projectDir).toString(), filePath}); - } - - if (isSorted) - std::sort(m_files.begin(), m_files.end(), comp); - - return save(); -} - -RemovedFilesFromProject PythonBuildSystem::removeFiles(Node *, const FilePaths &filePaths, FilePaths *) -{ - - for (const FilePath &filePath : filePaths) { - Utils::eraseOne(m_files, - [filePath](const FileEntry &entry) { return filePath == entry.filePath; }); - } - - return save() ? RemovedFilesFromProject::Ok : RemovedFilesFromProject::Error; -} - -bool PythonBuildSystem::deleteFiles(Node *, const FilePaths &) -{ - return true; -} - -bool PythonBuildSystem::renameFile(Node *, const FilePath &oldFilePath, const FilePath &newFilePath) -{ - for (FileEntry &entry : m_files) { - if (entry.filePath == oldFilePath) { - entry.filePath = newFilePath; - entry.rawEntry = newFilePath.relativeChildPath(projectDirectory()).toString(); - break; - } - } - - return save(); -} - -void PythonBuildSystem::parse() -{ - m_files.clear(); - m_qmlImportPaths.clear(); - - QStringList files; - QStringList qmlImportPaths; - - const FilePath filePath = projectFilePath(); - // The PySide project file is JSON based - if (filePath.endsWith(".pyproject")) { - QString errorMessage; - files = readLinesJson(filePath, &errorMessage); - if (!errorMessage.isEmpty()) - MessageManager::writeFlashing(errorMessage); - - errorMessage.clear(); - qmlImportPaths = readImportPathsJson(filePath, &errorMessage); - if (!errorMessage.isEmpty()) - MessageManager::writeFlashing(errorMessage); - } else if (filePath.endsWith(".pyqtc")) { - // To keep compatibility with PyQt we keep the compatibility with plain - // text files as project files. - files = readLines(filePath); - } - - m_files = processEntries(files); - m_qmlImportPaths = processEntries(qmlImportPaths); -} - -/** - * Expands environment variables in the given \a string when they are written - * like $$(VARIABLE). - */ -static void expandEnvironmentVariables(const Environment &env, QString &string) -{ - const QRegularExpression candidate("\\$\\$\\((.+)\\)"); - - QRegularExpressionMatch match; - int index = string.indexOf(candidate, 0, &match); - while (index != -1) { - const QString value = env.value(match.captured(1)); - - string.replace(index, match.capturedLength(), value); - index += value.length(); - - index = string.indexOf(candidate, index, &match); - } -} - -/** - * Expands environment variables and converts the path from relative to the - * project to an absolute path for all given raw paths - */ -QList PythonBuildSystem::processEntries( - const QStringList &rawPaths) const -{ - QList processed; - const FilePath projectDir = projectDirectory(); - const Environment env = projectDirectory().deviceEnvironment(); - - for (const QString &rawPath : rawPaths) { - FilePath resolvedPath; - QString path = rawPath.trimmed(); - if (!path.isEmpty()) { - expandEnvironmentVariables(env, path); - resolvedPath = projectDir.resolvePath(path); - } - processed << FileEntry{rawPath, resolvedPath}; - } - return processed; -} Project::RestoreResult PythonProject::fromMap(const Store &map, QString *errorMessage) { @@ -431,25 +38,23 @@ Project::RestoreResult PythonProject::fromMap(const Store &map, QString *errorMe return res; } -PythonBuildSystem::PythonBuildSystem(Target *target) - : BuildSystem(target) +PythonProjectNode::PythonProjectNode(const FilePath &path) + : ProjectNode(path) { - connect(target->project(), &Project::projectFileIsDirty, this, [this] { triggerParsing(); }); - triggerParsing(); + setDisplayName(path.completeBaseName()); + setAddFileFilter("*.py"); } -bool PythonBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const +PythonFileNode::PythonFileNode(const FilePath &filePath, + const QString &nodeDisplayName, + FileType fileType) + : FileNode(filePath, fileType) + , m_displayName(nodeDisplayName) +{} + +QString PythonFileNode::displayName() const { - if (node->asFileNode()) { - return action == ProjectAction::Rename - || action == ProjectAction::RemoveFile; - } - if (node->isFolderNodeType() || node->isProjectNodeType()) { - return action == ProjectAction::AddNewFile - || action == ProjectAction::RemoveFile - || action == ProjectAction::AddExistingFile; - } - return BuildSystem::supportsAction(context, action, node); + return m_displayName; } } // Python::Internal diff --git a/src/plugins/python/pythonproject.h b/src/plugins/python/pythonproject.h index c249548d2a1..39e1da8bc73 100644 --- a/src/plugins/python/pythonproject.h +++ b/src/plugins/python/pythonproject.h @@ -4,6 +4,9 @@ #pragma once #include +#include + +namespace Utils { class FilePath; } namespace Python::Internal { @@ -12,6 +15,24 @@ const char PythonMimeTypeLegacy[] = "text/x-pyqt-project"; const char PythonProjectId[] = "PythonProject"; const char PythonErrorTaskCategory[] = "Task.Category.Python"; +class PythonFileNode : public ProjectExplorer::FileNode +{ +public: + PythonFileNode(const Utils::FilePath &filePath, + const QString &nodeDisplayName, + ProjectExplorer::FileType fileType = ProjectExplorer::FileType::Source); + + QString displayName() const override; +private: + QString m_displayName; +}; + +class PythonProjectNode : public ProjectExplorer::ProjectNode +{ +public: + explicit PythonProjectNode(const Utils::FilePath &path); +}; + class PythonProject : public ProjectExplorer::Project { Q_OBJECT From 4c1044981f2b9e7844ecdeb62358f44371e189dc Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 14 Nov 2023 09:09:12 +0100 Subject: [PATCH 0176/1546] Plugin wizard: Add missing license templates Change-Id: I3b43ebdb9823a5a7430946ca789188628a910b9d Reviewed-by: Alessandro Portale --- share/qtcreator/templates/wizards/qtcreatorplugin/myplugin.cpp | 1 + share/qtcreator/templates/wizards/qtcreatorplugin/myplugin.h | 1 + share/qtcreator/templates/wizards/qtcreatorplugin/myplugintr.h | 1 + 3 files changed, 3 insertions(+) diff --git a/share/qtcreator/templates/wizards/qtcreatorplugin/myplugin.cpp b/share/qtcreator/templates/wizards/qtcreatorplugin/myplugin.cpp index aee6863fb63..c6724f1b0a8 100644 --- a/share/qtcreator/templates/wizards/qtcreatorplugin/myplugin.cpp +++ b/share/qtcreator/templates/wizards/qtcreatorplugin/myplugin.cpp @@ -1,3 +1,4 @@ +%{Cpp:LicenseTemplate}\ #include "%{HdrFileName}" #include "%{ConstantsHdrFileName}" #include "%{TrHdrFileName}" diff --git a/share/qtcreator/templates/wizards/qtcreatorplugin/myplugin.h b/share/qtcreator/templates/wizards/qtcreatorplugin/myplugin.h index 90051d00dbd..6e1fad933c0 100644 --- a/share/qtcreator/templates/wizards/qtcreatorplugin/myplugin.h +++ b/share/qtcreator/templates/wizards/qtcreatorplugin/myplugin.h @@ -1,3 +1,4 @@ +%{Cpp:LicenseTemplate}\ #pragma once #include "%{GlobalHdrFileName}" diff --git a/share/qtcreator/templates/wizards/qtcreatorplugin/myplugintr.h b/share/qtcreator/templates/wizards/qtcreatorplugin/myplugintr.h index 1dc9ed3dafc..944cb17457d 100644 --- a/share/qtcreator/templates/wizards/qtcreatorplugin/myplugintr.h +++ b/share/qtcreator/templates/wizards/qtcreatorplugin/myplugintr.h @@ -1,3 +1,4 @@ +%{Cpp:LicenseTemplate}\ #pragma once #include From 00f76a3c2c1a14d03722be9620e52dcb98aebd61 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 10 Nov 2023 16:35:18 +0100 Subject: [PATCH 0177/1546] Boot2Qt: Move Plugin class definition to .cpp Change-Id: I9c3952e5ea1993888ccbd54a243392e2004d0b60 Reviewed-by: Christian Stenger --- src/plugins/boot2qt/CMakeLists.txt | 2 +- src/plugins/boot2qt/boot2qt.qbs | 1 - src/plugins/boot2qt/qdbplugin.cpp | 69 +++++++++++++++--------------- src/plugins/boot2qt/qdbplugin.h | 27 ------------ 4 files changed, 35 insertions(+), 64 deletions(-) delete mode 100644 src/plugins/boot2qt/qdbplugin.h diff --git a/src/plugins/boot2qt/CMakeLists.txt b/src/plugins/boot2qt/CMakeLists.txt index 156150422b6..26002e6fee7 100644 --- a/src/plugins/boot2qt/CMakeLists.txt +++ b/src/plugins/boot2qt/CMakeLists.txt @@ -9,7 +9,7 @@ add_qtc_plugin(Boot2Qt qdbdevice.cpp qdbdevice.h qdbdevicedebugsupport.cpp qdbdevicedebugsupport.h qdbmakedefaultappstep.cpp qdbmakedefaultappstep.h - qdbplugin.cpp qdbplugin.h + qdbplugin.cpp qdbqtversion.cpp qdbqtversion.h qdbrunconfiguration.cpp qdbrunconfiguration.h qdbstopapplicationstep.cpp qdbstopapplicationstep.h diff --git a/src/plugins/boot2qt/boot2qt.qbs b/src/plugins/boot2qt/boot2qt.qbs index 6be777e17c1..77aa8a0296b 100644 --- a/src/plugins/boot2qt/boot2qt.qbs +++ b/src/plugins/boot2qt/boot2qt.qbs @@ -28,7 +28,6 @@ QtcPlugin { "qdbmakedefaultappstep.cpp", "qdbmakedefaultappstep.h", "qdbplugin.cpp", - "qdbplugin.h", "qdbstopapplicationstep.cpp", "qdbstopapplicationstep.h", "qdbtr.h", diff --git a/src/plugins/boot2qt/qdbplugin.cpp b/src/plugins/boot2qt/qdbplugin.cpp index ec61e7c33a7..df1b5458f32 100644 --- a/src/plugins/boot2qt/qdbplugin.cpp +++ b/src/plugins/boot2qt/qdbplugin.cpp @@ -1,8 +1,6 @@ // Copyright (C) 2019 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "qdbplugin.h" - #include "device-detection/devicedetector.h" #include "qdbconstants.h" #include "qdbdevice.h" @@ -18,10 +16,10 @@ #include #include +#include + #include #include -#include -#include #include #include #include @@ -30,12 +28,9 @@ #include -#include #include #include -#include - using namespace Core; using namespace ProjectExplorer; using namespace Utils; @@ -124,10 +119,10 @@ public: } }; -class QdbPluginPrivate : public QObject +class QdbPluginPrivate final : public QObject { public: - void setupDeviceDetection(); + void setupDeviceDetection() { m_deviceDetector.start(); } QdbLinuxDeviceFactory m_qdbDeviceFactory; QdbQtVersionFactory m_qtVersionFactory; @@ -153,39 +148,43 @@ public: DeviceDetector m_deviceDetector; }; -QdbPlugin::~QdbPlugin() +class QdbPlugin final : public ExtensionSystem::IPlugin { - delete d; -} + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Boot2Qt.json") -void QdbPlugin::initialize() -{ - d = new QdbPluginPrivate; +public: + ~QdbPlugin() final { delete d; } - registerFlashAction(this); -} +private: + void initialize() final + { + d = new QdbPluginPrivate; -void QdbPlugin::extensionsInitialized() -{ - DeviceManager * const dm = DeviceManager::instance(); - if (dm->isLoaded()) { - d->setupDeviceDetection(); - } else { - connect(dm, &DeviceManager::devicesLoaded, - d, &QdbPluginPrivate::setupDeviceDetection); + registerFlashAction(this); } -} -ExtensionSystem::IPlugin::ShutdownFlag QdbPlugin::aboutToShutdown() -{ - d->m_deviceDetector.stop(); + void extensionsInitialized() final + { + DeviceManager * const dm = DeviceManager::instance(); + if (dm->isLoaded()) { + d->setupDeviceDetection(); + } else { + connect(dm, &DeviceManager::devicesLoaded, + d, &QdbPluginPrivate::setupDeviceDetection); + } + } - return SynchronousShutdown; -} + ShutdownFlag aboutToShutdown() final + { + d->m_deviceDetector.stop(); -void QdbPluginPrivate::setupDeviceDetection() -{ - m_deviceDetector.start(); -} + return SynchronousShutdown; + } + + class QdbPluginPrivate *d = nullptr; +}; } // Qdb::Internal + +#include "qdbplugin.moc" diff --git a/src/plugins/boot2qt/qdbplugin.h b/src/plugins/boot2qt/qdbplugin.h deleted file mode 100644 index 0f2b75a8ac3..00000000000 --- a/src/plugins/boot2qt/qdbplugin.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2019 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace Qdb::Internal { - -class QdbPlugin final : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Boot2Qt.json") - -public: - QdbPlugin() = default; - ~QdbPlugin() final; - -private: - void initialize() final; - void extensionsInitialized() final; - ShutdownFlag aboutToShutdown() final; - - class QdbPluginPrivate *d = nullptr; -}; - -} // Qdb::Internal From 6491e378e4a8543e033324aba43be9083a1b8990 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 13 Nov 2023 09:57:26 +0100 Subject: [PATCH 0178/1546] Core: Use ActionBuilder to set up find menu entries Change-Id: I93784d6c571988be5476f0f8e9cce7411ae392be Reviewed-by: Reviewed-by: Eike Ziller --- .../actionmanager/actionmanager.cpp | 15 + .../coreplugin/actionmanager/actionmanager.h | 3 + src/plugins/coreplugin/find/findplugin.cpp | 44 +-- src/plugins/coreplugin/find/findtoolbar.cpp | 281 ++++++++++-------- 4 files changed, 196 insertions(+), 147 deletions(-) diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index 08e2acb4bc9..1287d117182 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -110,6 +110,11 @@ void ActionBuilder::setText(const QString &text) d->action->setText(text); } +void ActionBuilder::setIconText(const QString &text) +{ + d->action->setIconText(text); +} + void ActionBuilder::setToolTip(const QString &toolTip) { d->action->setToolTip(toolTip); @@ -148,6 +153,11 @@ void ActionBuilder::setOnTriggered(QObject *guard, const std::functionaction, &QAction::triggered, guard, func); } +void ActionBuilder::setOnToggled(QObject *guard, const std::function &func) +{ + QObject::connect(d->action, &QAction::toggled, guard, func); +} + void ActionBuilder::setDefaultKeySequence(const QKeySequence &seq) { d->command->setDefaultKeySequence(seq); @@ -224,6 +234,11 @@ void ActionBuilder::bindContextAction(QAction **dest) *dest = d->action; } +void ActionBuilder::augmentActionWithShortcutToolTip() +{ + d->command->augmentActionWithShortcutToolTip(d->action); +} + void ActionBuilder::setId(Id id) { d->actionId = id; diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.h b/src/plugins/coreplugin/actionmanager/actionmanager.h index 3806e7d48c6..320842e0b77 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager.h @@ -36,6 +36,7 @@ public: void setContext(const Utils::Id id); void setContext(const Core::Context &context); void setText(const QString &text); + void setIconText(const QString &text); void setToolTip(const QString &toolTip); void setCommandAttribute(Core::Command::CommandAttribute attr); void setCommandDescription(const QString &desc); @@ -43,6 +44,7 @@ public: void setOnTriggered(const std::function &func); void setOnTriggered(QObject *guard, const std::function &func); void setOnTriggered(QObject *guard, const std::function &func); + void setOnToggled(QObject *guard, const std::function &func); void setDefaultKeySequence(const QKeySequence &seq); void setDefaultKeySequences(const QList &seqs); void setDefaultKeySequence(const QString &mac, const QString &nonMac); @@ -59,6 +61,7 @@ public: QAction *commandAction() const; QAction *contextAction() const; void bindContextAction(QAction **dest); + void augmentActionWithShortcutToolTip(); private: class ActionBuilderPrivate *d = nullptr; diff --git a/src/plugins/coreplugin/find/findplugin.cpp b/src/plugins/coreplugin/find/findplugin.cpp index d7cb36e7ae2..d644c7f5f47 100644 --- a/src/plugins/coreplugin/find/findplugin.cpp +++ b/src/plugins/coreplugin/find/findplugin.cpp @@ -267,20 +267,20 @@ void FindPrivate::setupMenu() mfind->appendGroup(Constants::G_FIND_FILTERS); mfind->appendGroup(Constants::G_FIND_FLAGS); mfind->appendGroup(Constants::G_FIND_ACTIONS); - Command *cmd; mfind->addSeparator(Constants::G_FIND_FLAGS); mfind->addSeparator(Constants::G_FIND_ACTIONS); ActionContainer *mfindadvanced = ActionManager::createMenu(Constants::M_FIND_ADVANCED); mfindadvanced->menu()->setTitle(Tr::tr("Advanced Find")); mfind->addMenu(mfindadvanced, Constants::G_FIND_FILTERS); - m_openFindDialog = new QAction(Tr::tr("Open Advanced Find..."), this); - m_openFindDialog->setIconText(Tr::tr("Advanced...")); - cmd = ActionManager::registerAction(m_openFindDialog, Constants::ADVANCED_FIND); - cmd->setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+Shift+F"))); - mfindadvanced->addAction(cmd); - connect(m_openFindDialog, &QAction::triggered, - this, [] { Find::openFindDialog(nullptr); }); + + ActionBuilder openFindDialog(this, Constants::ADVANCED_FIND); + openFindDialog.setText(Tr::tr("Open Advanced Find...")); + openFindDialog.setIconText(Tr::tr("Advanced...")); + openFindDialog.bindContextAction(&m_openFindDialog); + openFindDialog.setDefaultKeySequence(Tr::tr("Ctrl+Shift+F")); + openFindDialog.setContainer(Constants::M_FIND_ADVANCED); + openFindDialog.setOnTriggered(this, [] { Find::openFindDialog(nullptr); }); } static QString filterActionName(const IFindFilter *filter) @@ -290,30 +290,30 @@ static QString filterActionName(const IFindFilter *filter) void FindPrivate::setupFilterMenuItems() { - Command *cmd; - - ActionContainer *mfindadvanced = ActionManager::actionContainer(Constants::M_FIND_ADVANCED); bool haveEnabledFilters = false; const Id base("FindFilter."); const QList sortedFilters = Utils::sorted(IFindFilter::allFindFilters(), &IFindFilter::displayName); for (IFindFilter *filter : sortedFilters) { - QAction *action = new QAction(filterActionName(filter), this); + ActionBuilder findScope(this, base.withSuffix(filter->id())); + findScope.setText(filterActionName(filter)); bool isEnabled = filter->isEnabled(); if (isEnabled) haveEnabledFilters = true; - action->setEnabled(isEnabled); - cmd = ActionManager::registerAction(action, base.withSuffix(filter->id())); - cmd->setDefaultKeySequence(filter->defaultShortcut()); - cmd->setAttribute(Command::CA_UpdateText); - mfindadvanced->addAction(cmd); - connect(action, &QAction::triggered, this, [filter] { Find::openFindDialog(filter); }); - connect(filter, &IFindFilter::enabledChanged, this, [filter, action] { - action->setEnabled(filter->isEnabled()); + findScope.setEnabled(isEnabled); + findScope.setDefaultKeySequence(filter->defaultShortcut()); + findScope.setCommandAttribute(Command::CA_UpdateText); + findScope.setContainer(Constants::M_FIND_ADVANCED); + findScope.setOnTriggered(this, [filter] { Find::openFindDialog(filter); }); + + QAction *findScopeAction = findScope.contextAction(); + connect(filter, &IFindFilter::enabledChanged, this, [filter, findScopeAction] { + findScopeAction->setEnabled(filter->isEnabled()); d->m_openFindDialog->setEnabled(d->isAnyFilterEnabled()); }); - connect(filter, &IFindFilter::displayNameChanged, - this, [filter, action] { action->setText(filterActionName(filter)); }); + connect(filter, &IFindFilter::displayNameChanged, this, [filter, findScopeAction] { + findScopeAction->setText(filterActionName(filter)); + }); } d->m_findDialog->setFindFilters(sortedFilters); d->m_openFindDialog->setEnabled(haveEnabledFilters); diff --git a/src/plugins/coreplugin/find/findtoolbar.cpp b/src/plugins/coreplugin/find/findtoolbar.cpp index 616f4c47719..3ae5efc3590 100644 --- a/src/plugins/coreplugin/find/findtoolbar.cpp +++ b/src/plugins/coreplugin/find/findtoolbar.cpp @@ -236,8 +236,6 @@ FindToolBar::FindToolBar(CurrentDocumentFind *currentDocumentFind) // register actions Context findcontext(Constants::C_FINDTOOLBAR); - ActionContainer *mfind = ActionManager::actionContainer(Constants::M_FIND); - Command *cmd; auto advancedAction = new QAction(Tr::tr("Open Advanced Find..."), this); advancedAction->setIconText(Tr::tr("Advanced...")); @@ -249,158 +247,191 @@ FindToolBar::FindToolBar(CurrentDocumentFind *currentDocumentFind) Find::openFindDialog(nullptr, m_findEdit->text()); }); - m_goToCurrentFindAction = new QAction(this); - ActionManager::registerAction(m_goToCurrentFindAction, Constants::S_RETURNTOEDITOR, - findcontext); - connect(m_goToCurrentFindAction, &QAction::triggered, - this, &FindToolBar::setFocusToCurrentFindSupport); + ActionBuilder goToCurrentFindAction(this, Constants::S_RETURNTOEDITOR); + goToCurrentFindAction.setContext(findcontext); + goToCurrentFindAction.bindContextAction(&m_goToCurrentFindAction); + goToCurrentFindAction.setOnTriggered(this, [this] { setFocusToCurrentFindSupport(); }); - QIcon icon = Icon::fromTheme("edit-find-replace"); - m_findInDocumentAction = new QAction(icon, Tr::tr("Find/Replace"), this); - cmd = ActionManager::registerAction(m_findInDocumentAction, Constants::FIND_IN_DOCUMENT); - cmd->setDefaultKeySequence(QKeySequence::Find); - mfind->addAction(cmd, Constants::G_FIND_CURRENTDOCUMENT); - connect(m_findInDocumentAction, &QAction::triggered, this, [this] { openFind(); }); + ActionBuilder findInDocumentAction(this, Constants::FIND_IN_DOCUMENT); + findInDocumentAction.setText(Tr::tr("Find/Replace")); + findInDocumentAction.setIcon(Icon::fromTheme("edit-find-replace")); + findInDocumentAction.bindContextAction(&m_findInDocumentAction); + findInDocumentAction.setDefaultKeySequence(QKeySequence::Find); + findInDocumentAction.setContainer(Constants::M_FIND, Constants::G_FIND_CURRENTDOCUMENT); + findInDocumentAction.setOnTriggered(this, [this] { openFind(); }); // Pressing the find shortcut while focus is in the tool bar should not change the search text, // so register a different find action for the tool bar - auto localFindAction = new QAction(this); - ActionManager::registerAction(localFindAction, Constants::FIND_IN_DOCUMENT, findcontext); - connect(localFindAction, &QAction::triggered, this, [this] { + ActionBuilder localFindAction(this, Constants::FIND_IN_DOCUMENT); + localFindAction.setText(m_findInDocumentAction->text()); + localFindAction.setContext(findcontext); + localFindAction.setOnTriggered(this, [this] { openFindToolBar(FindToolBar::OpenFlags(UpdateAll & ~UpdateFindText)); }); if (QApplication::clipboard()->supportsFindBuffer()) { - m_enterFindStringAction = new QAction(Tr::tr("Enter Find String"), this); - cmd = ActionManager::registerAction(m_enterFindStringAction, "Find.EnterFindString"); - cmd->setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+E"))); - mfind->addAction(cmd, Constants::G_FIND_ACTIONS); - connect(m_enterFindStringAction, &QAction::triggered, - this, &FindToolBar::putSelectionToFindClipboard); + ActionBuilder enterFindStringAction(this, "Find.EnterFindString"); + enterFindStringAction.setText(Tr::tr("Enter Find String")); + enterFindStringAction.setDefaultKeySequence(Tr::tr("Ctrl+E")); + enterFindStringAction.setContainer(Constants::M_FIND, Constants::G_FIND_ACTIONS); + enterFindStringAction.bindContextAction(&m_enterFindStringAction); + enterFindStringAction.setOnTriggered(this, [this] { putSelectionToFindClipboard(); }); connect(QApplication::clipboard(), &QClipboard::findBufferChanged, this, &FindToolBar::updateFromFindClipboard); } - m_findNextAction = new QAction(Tr::tr("Find Next"), this); - cmd = ActionManager::registerAction(m_findNextAction, Constants::FIND_NEXT); - cmd->setDefaultKeySequence(QKeySequence::FindNext); - mfind->addAction(cmd, Constants::G_FIND_ACTIONS); - connect(m_findNextAction, &QAction::triggered, this, &FindToolBar::invokeGlobalFindNext); - m_localFindNextAction = new QAction(m_findNextAction->text(), this); - cmd = ActionManager::registerAction(m_localFindNextAction, Constants::FIND_NEXT, findcontext); - cmd->augmentActionWithShortcutToolTip(m_localFindNextAction); - connect(m_localFindNextAction, &QAction::triggered, this, &FindToolBar::invokeFindNext); + ActionBuilder findNextAction(this, Constants::FIND_NEXT); + findNextAction.setText(Tr::tr("Find Next")); + findNextAction.bindContextAction(&m_findNextAction); + findNextAction.setDefaultKeySequence(QKeySequence::FindNext); + findNextAction.setContainer(Constants::M_FIND, Constants::G_FIND_ACTIONS); + findNextAction.setOnTriggered(this, [this] { invokeGlobalFindNext(); }); + + ActionBuilder localFindNextAction(this, Constants::FIND_NEXT); + localFindNextAction.setText(m_findNextAction->text()); + localFindNextAction.bindContextAction(&m_localFindNextAction); + localFindNextAction.setContext(findcontext); + localFindNextAction.augmentActionWithShortcutToolTip(); + localFindNextAction.setOnTriggered(this, [this] { invokeFindNext(); }); m_findNextButton->setDefaultAction(m_localFindNextAction); - m_findPreviousAction = new QAction(Tr::tr("Find Previous"), this); - cmd = ActionManager::registerAction(m_findPreviousAction, Constants::FIND_PREVIOUS); - cmd->setDefaultKeySequence(QKeySequence::FindPrevious); - mfind->addAction(cmd, Constants::G_FIND_ACTIONS); - connect(m_findPreviousAction, &QAction::triggered, this, &FindToolBar::invokeGlobalFindPrevious); - m_localFindPreviousAction = new QAction(m_findPreviousAction->text(), this); - cmd = ActionManager::registerAction(m_localFindPreviousAction, Constants::FIND_PREVIOUS, findcontext); - cmd->augmentActionWithShortcutToolTip(m_localFindPreviousAction); - connect(m_localFindPreviousAction, &QAction::triggered, this, &FindToolBar::invokeFindPrevious); + ActionBuilder findPreviousAction(this, Constants::FIND_PREVIOUS); + findPreviousAction.setText(Tr::tr("Find Previous")); + findPreviousAction.bindContextAction(&m_findPreviousAction); + findPreviousAction.setDefaultKeySequence(QKeySequence::FindPrevious); + findPreviousAction.setContainer(Constants::M_FIND, Constants::G_FIND_ACTIONS); + findPreviousAction.setOnTriggered(this, [this] { invokeGlobalFindPrevious(); }); + + ActionBuilder localFindPreviousAction(this, Constants::FIND_PREVIOUS); + localFindPreviousAction.setText(m_findPreviousAction->text()); + localFindPreviousAction.bindContextAction(&m_localFindPreviousAction); + localFindPreviousAction.setContext(findcontext); + localFindPreviousAction.augmentActionWithShortcutToolTip(); + localFindPreviousAction.setOnTriggered(this, [this] { invokeFindPrevious(); }); m_findPreviousButton->setDefaultAction(m_localFindPreviousAction); - m_findNextSelectedAction = new QAction(Tr::tr("Find Next (Selected)"), this); - cmd = ActionManager::registerAction(m_findNextSelectedAction, Constants::FIND_NEXT_SELECTED); - cmd->setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+F3"))); - mfind->addAction(cmd, Constants::G_FIND_ACTIONS); - connect(m_findNextSelectedAction, &QAction::triggered, this, &FindToolBar::findNextSelected); + ActionBuilder findNextSelectedAction(this, Constants::FIND_NEXT_SELECTED); + findNextSelectedAction.setText(Tr::tr("Find Next (Selected)")); + findNextSelectedAction.bindContextAction(&m_findNextSelectedAction); + findNextSelectedAction.setDefaultKeySequence(Tr::tr("Ctrl+F3")); + findNextSelectedAction.setContainer(Constants::M_FIND, Constants::G_FIND_ACTIONS); + findNextSelectedAction.setOnTriggered(this, [this] { findNextSelected(); }); - m_findPreviousSelectedAction = new QAction(Tr::tr("Find Previous (Selected)"), this); - cmd = ActionManager::registerAction(m_findPreviousSelectedAction, Constants::FIND_PREV_SELECTED); - cmd->setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+Shift+F3"))); - mfind->addAction(cmd, Constants::G_FIND_ACTIONS); - connect(m_findPreviousSelectedAction, &QAction::triggered, - this, &FindToolBar::findPreviousSelected); + ActionBuilder findPreviousSelectedAction(this, Constants::FIND_PREV_SELECTED); + findPreviousSelectedAction.setText(Tr::tr("Find Previous (Selected)")); + findPreviousSelectedAction.bindContextAction(&m_findPreviousSelectedAction); + findPreviousSelectedAction.setDefaultKeySequence(Tr::tr("Ctrl+Shift+F3")); + findPreviousSelectedAction.setContainer(Constants::M_FIND, Constants::G_FIND_ACTIONS); + findPreviousSelectedAction.setOnTriggered(this, [this] { findPreviousSelected(); }); - m_selectAllAction = new QAction(Tr::tr("Select All"), this); - cmd = ActionManager::registerAction(m_selectAllAction, Constants::FIND_SELECT_ALL); - cmd->setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+Alt+Return"))); - mfind->addAction(cmd, Constants::G_FIND_ACTIONS); - connect(m_selectAllAction, &QAction::triggered, this, &FindToolBar::selectAll); - m_localSelectAllAction = new QAction(m_selectAllAction->text(), this); - cmd = ActionManager::registerAction(m_localSelectAllAction, Constants::FIND_SELECT_ALL, findcontext); - cmd->augmentActionWithShortcutToolTip(m_localSelectAllAction); - connect(m_localSelectAllAction, &QAction::triggered, this, &FindToolBar::selectAll); + ActionBuilder selectAllAction(this, Constants::FIND_SELECT_ALL); + selectAllAction.setText(Tr::tr("Select All")); + selectAllAction.bindContextAction(&m_selectAllAction); + selectAllAction.setDefaultKeySequence(Tr::tr("Ctrl+Alt+Return")); + selectAllAction.setContainer(Constants::M_FIND, Constants::G_FIND_ACTIONS); + selectAllAction.setOnTriggered(this, [this] { selectAll(); }); + + ActionBuilder localSelectAllAction(this, Constants::FIND_SELECT_ALL); + localSelectAllAction.setText(m_selectAllAction->text()); + localSelectAllAction.setContext(findcontext); + localSelectAllAction.bindContextAction(&m_localSelectAllAction); + localSelectAllAction.augmentActionWithShortcutToolTip(); + localSelectAllAction.setOnTriggered(this, [this] { selectAll(); }); m_selectAllButton->setDefaultAction(m_localSelectAllAction); - m_replaceAction = new QAction(Tr::tr("Replace"), this); - cmd = ActionManager::registerAction(m_replaceAction, Constants::REPLACE); - cmd->setDefaultKeySequence(QKeySequence()); - mfind->addAction(cmd, Constants::G_FIND_ACTIONS); - connect(m_replaceAction, &QAction::triggered, this, &FindToolBar::invokeGlobalReplace); - m_localReplaceAction = new QAction(m_replaceAction->text(), this); - cmd = ActionManager::registerAction(m_localReplaceAction, Constants::REPLACE, findcontext); - cmd->augmentActionWithShortcutToolTip(m_localReplaceAction); - connect(m_localReplaceAction, &QAction::triggered, this, &FindToolBar::invokeReplace); + ActionBuilder replaceAction(this, Constants::REPLACE); + replaceAction.setText(Tr::tr("Replace")); + replaceAction.bindContextAction(&m_replaceAction); + replaceAction.setDefaultKeySequence({}); + replaceAction.setContainer(Constants::M_FIND, Constants::G_FIND_ACTIONS); + replaceAction.setOnTriggered(this, [this] { invokeGlobalReplace(); }); + + ActionBuilder localReplaceAction(this, Constants::REPLACE); + localReplaceAction.setText(m_replaceAction->text()); + localReplaceAction.setContext(findcontext); + localReplaceAction.bindContextAction(&m_localReplaceAction); + localReplaceAction.augmentActionWithShortcutToolTip(); + localReplaceAction.setOnTriggered(this, [this] { invokeReplace(); }); m_replaceButton->setDefaultAction(m_localReplaceAction); - m_replaceNextAction = new QAction(Tr::tr("Replace && Find"), this); - cmd = ActionManager::registerAction(m_replaceNextAction, Constants::REPLACE_NEXT); - cmd->setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+="))); - mfind->addAction(cmd, Constants::G_FIND_ACTIONS); - connect(m_replaceNextAction, &QAction::triggered, this, &FindToolBar::invokeGlobalReplaceNext); - m_localReplaceNextAction = new QAction(m_replaceNextAction->text(), this); - m_localReplaceNextAction->setIconText(m_replaceNextAction->text()); // Workaround QTBUG-23396 - cmd = ActionManager::registerAction(m_localReplaceNextAction, Constants::REPLACE_NEXT, findcontext); - cmd->augmentActionWithShortcutToolTip(m_localReplaceNextAction); - connect(m_localReplaceNextAction, &QAction::triggered, this, &FindToolBar::invokeReplaceNext); + ActionBuilder replaceNextAction(this, Constants::REPLACE_NEXT); + replaceNextAction.setText(Tr::tr("Replace && Find")); + replaceNextAction.bindContextAction(&m_replaceNextAction); + replaceNextAction.setDefaultKeySequence(Tr::tr("Ctrl+=")); + replaceNextAction.setContainer(Constants::M_FIND, Constants::G_FIND_ACTIONS); + replaceNextAction.setOnTriggered(this, [this] { invokeGlobalReplaceNext(); }); + + ActionBuilder localReplaceNextAction(this, Constants::REPLACE_NEXT); + localReplaceNextAction.setText(m_replaceNextAction->text()); + localReplaceNextAction.setIconText(m_replaceNextAction->text()); // Workaround QTBUG-23396 + localReplaceNextAction.setContext(findcontext); + localReplaceNextAction.bindContextAction(&m_localReplaceNextAction); + localReplaceNextAction.augmentActionWithShortcutToolTip(); + localReplaceNextAction.setOnTriggered(this, [this] { invokeReplaceNext(); }); m_replaceNextButton->setDefaultAction(m_localReplaceNextAction); - m_replacePreviousAction = new QAction(Tr::tr("Replace && Find Previous"), this); - cmd = ActionManager::registerAction(m_replacePreviousAction, Constants::REPLACE_PREVIOUS); - mfind->addAction(cmd, Constants::G_FIND_ACTIONS); - connect(m_replacePreviousAction, &QAction::triggered, - this, &FindToolBar::invokeGlobalReplacePrevious); - m_localReplacePreviousAction = new QAction(m_replacePreviousAction->text(), this); - cmd = ActionManager::registerAction(m_localReplacePreviousAction, Constants::REPLACE_PREVIOUS, findcontext); - cmd->augmentActionWithShortcutToolTip(m_localReplacePreviousAction); - connect(m_localReplacePreviousAction, &QAction::triggered, - this, &FindToolBar::invokeReplacePrevious); + ActionBuilder replacePreviousAction(this, Constants::REPLACE_PREVIOUS); + replacePreviousAction.setText(Tr::tr("Replace && Find Previous")); + replacePreviousAction.bindContextAction(&m_replacePreviousAction); + replacePreviousAction.setContainer(Constants::M_FIND, Constants::G_FIND_ACTIONS); + replacePreviousAction.setOnTriggered(this, [this] { invokeGlobalReplacePrevious(); }); - m_replaceAllAction = new QAction(Tr::tr("Replace All"), this); - cmd = ActionManager::registerAction(m_replaceAllAction, Constants::REPLACE_ALL); - mfind->addAction(cmd, Constants::G_FIND_ACTIONS); - connect(m_replaceAllAction, &QAction::triggered, this, &FindToolBar::invokeGlobalReplaceAll); - m_localReplaceAllAction = new QAction(m_replaceAllAction->text(), this); - cmd = ActionManager::registerAction(m_localReplaceAllAction, Constants::REPLACE_ALL, findcontext); - cmd->augmentActionWithShortcutToolTip(m_localReplaceAllAction); - connect(m_localReplaceAllAction, &QAction::triggered, this, &FindToolBar::invokeReplaceAll); + ActionBuilder localReplacePreviousAction(this, Constants::REPLACE_PREVIOUS); + localReplacePreviousAction.setText(m_replacePreviousAction->text()); + localReplacePreviousAction.setContext(findcontext); + localReplacePreviousAction.bindContextAction(&m_localReplacePreviousAction); + localReplacePreviousAction.augmentActionWithShortcutToolTip(); + localReplacePreviousAction.setOnTriggered(this, [this] { invokeReplacePrevious(); }); + + ActionBuilder replaceAllAction(this, Constants::REPLACE_ALL); + replaceAllAction.setText(Tr::tr("Replace All")); + replaceAllAction.bindContextAction(&m_replaceAllAction); + replaceAllAction.setDefaultKeySequence(Tr::tr("Ctrl+Alt+Return")); + replaceAllAction.setContainer(Constants::M_FIND, Constants::G_FIND_ACTIONS); + replaceAllAction.setOnTriggered(this, [this] { invokeGlobalReplaceAll(); }); + + ActionBuilder localReplaceAllAction(this, Constants::REPLACE_ALL); + localReplaceAllAction.setText(m_replaceAllAction->text()); + localReplaceAllAction.setContext(findcontext); + localReplaceAllAction.bindContextAction(&m_localReplaceAllAction); + localReplaceAllAction.augmentActionWithShortcutToolTip(); + localReplaceAllAction.setOnTriggered(this, [this] { invokeReplaceAll(); }); m_replaceAllButton->setDefaultAction(m_localReplaceAllAction); - m_caseSensitiveAction = new QAction(Tr::tr("Case Sensitive"), this); - m_caseSensitiveAction->setIcon(Icons::FIND_CASE_INSENSITIVELY.icon()); - m_caseSensitiveAction->setCheckable(true); - m_caseSensitiveAction->setChecked(false); - cmd = ActionManager::registerAction(m_caseSensitiveAction, Constants::CASE_SENSITIVE); - mfind->addAction(cmd, Constants::G_FIND_FLAGS); - connect(m_caseSensitiveAction, &QAction::toggled, this, &FindToolBar::setCaseSensitive); + ActionBuilder caseSensitiveAction(this, Constants::CASE_SENSITIVE); + caseSensitiveAction.setText(Tr::tr("Case Sensitive")); + caseSensitiveAction.bindContextAction(&m_caseSensitiveAction); + caseSensitiveAction.setIcon(Icons::FIND_CASE_INSENSITIVELY.icon()); + caseSensitiveAction.setCheckable(true); + caseSensitiveAction.setChecked(false); + caseSensitiveAction.setContainer(Constants::M_FIND, Constants::G_FIND_FLAGS); + caseSensitiveAction.setOnToggled(this, [this](bool on) { setCaseSensitive(on); }); - m_wholeWordAction = new QAction(Tr::tr("Whole Words Only"), this); - m_wholeWordAction->setIcon(Icons::FIND_WHOLE_WORD.icon()); - m_wholeWordAction->setCheckable(true); - m_wholeWordAction->setChecked(false); - cmd = ActionManager::registerAction(m_wholeWordAction, Constants::WHOLE_WORDS); - mfind->addAction(cmd, Constants::G_FIND_FLAGS); - connect(m_wholeWordAction, &QAction::toggled, this, &FindToolBar::setWholeWord); + ActionBuilder wholeWordAction(this, Constants::WHOLE_WORDS); + wholeWordAction.setText(Tr::tr("Whole Words Only")); + wholeWordAction.bindContextAction(&m_wholeWordAction); + wholeWordAction.setIcon(Icons::FIND_WHOLE_WORD.icon()); + wholeWordAction.setCheckable(true); + wholeWordAction.setChecked(false); + wholeWordAction.setContainer(Constants::M_FIND, Constants::G_FIND_FLAGS); + wholeWordAction.setOnToggled(this, [this](bool on) { setWholeWord(on); }); - m_regularExpressionAction = new QAction(Tr::tr("Use Regular Expressions"), this); - m_regularExpressionAction->setIcon(Icons::FIND_REGEXP.icon()); - m_regularExpressionAction->setCheckable(true); - m_regularExpressionAction->setChecked(false); - cmd = ActionManager::registerAction(m_regularExpressionAction, Constants::REGULAR_EXPRESSIONS); - mfind->addAction(cmd, Constants::G_FIND_FLAGS); - connect(m_regularExpressionAction, &QAction::toggled, this, &FindToolBar::setRegularExpressions); + ActionBuilder regularExpressionAction(this, Constants::REGULAR_EXPRESSIONS); + regularExpressionAction.setText(Tr::tr("Use Regular Expressions")); + regularExpressionAction.bindContextAction(&m_regularExpressionAction); + regularExpressionAction.setIcon(Icons::FIND_REGEXP.icon()); + regularExpressionAction.setCheckable(true); + regularExpressionAction.setChecked(false); + regularExpressionAction.setContainer(Constants::M_FIND, Constants::G_FIND_FLAGS); + regularExpressionAction.setOnToggled(this, [this](bool on) { setRegularExpressions(on); }); - m_preserveCaseAction = new QAction(Tr::tr("Preserve Case when Replacing"), this); - m_preserveCaseAction->setIcon(Icons::FIND_PRESERVE_CASE.icon()); - m_preserveCaseAction->setCheckable(true); - m_preserveCaseAction->setChecked(false); - cmd = ActionManager::registerAction(m_preserveCaseAction, Constants::PRESERVE_CASE); - mfind->addAction(cmd, Constants::G_FIND_FLAGS); - connect(m_preserveCaseAction, &QAction::toggled, this, &FindToolBar::setPreserveCase); + ActionBuilder preserveCaseAction(this, Constants::PRESERVE_CASE); + preserveCaseAction.setText(Tr::tr("Preserve Case when Replacing")); + preserveCaseAction.bindContextAction(&m_preserveCaseAction); + preserveCaseAction.setIcon(Icons::FIND_PRESERVE_CASE.icon()); + preserveCaseAction.setCheckable(true); + preserveCaseAction.setChecked(false); + preserveCaseAction.setContainer(Constants::M_FIND, Constants::G_FIND_FLAGS); + preserveCaseAction.setOnToggled(this, [this](bool on) { setPreserveCase(on); }); connect(m_currentDocumentFind, &CurrentDocumentFind::candidateChanged, this, &FindToolBar::adaptToCandidate); From f96feadad01c0032b6d4a5bc7f8a8f4afdadc0e7 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Tue, 14 Nov 2023 14:24:48 +0100 Subject: [PATCH 0179/1546] Fix missing overrides and redundant virtual Change-Id: Id2a247b6032602c2295d928067c2462d3f9b5221 Reviewed-by: Marcus Tillmanns --- src/libs/solutions/tasking/qprocesstask.h | 2 +- src/libs/utils/aspects.cpp | 2 +- src/libs/utils/process.cpp | 6 +- src/libs/utils/stringutils.h | 2 +- src/libs/utils/styleanimator.h | 2 +- src/libs/utils/transientscroll.h | 4 +- .../android/createandroidmanifestwizard.h | 2 +- src/plugins/autotest/testconfiguration.h | 2 +- src/plugins/autotest/testtreeitem.h | 8 +- src/plugins/axivion/dashboard/dto.h | 92 +++++++++---------- .../cmakebuildconfiguration.h | 4 +- src/plugins/conan/conanplugin.cpp | 2 +- .../cppeditor/cppinsertvirtualmethods.cpp | 4 +- src/plugins/cppeditor/cppquickfix_test.cpp | 4 +- .../cppeditor/fileandtokenactions_test.cpp | 18 ++-- src/plugins/docker/dockerdevice.cpp | 2 +- src/plugins/fossil/fossilclient.cpp | 2 +- .../incredibuild/incredibuildplugin.cpp | 2 +- .../languageclient/languageclientsettings.cpp | 2 +- .../mcusupport/mcusupportimportprovider.h | 16 ++-- .../mesonprojectmanager/buildoptions.h | 2 +- .../mesontoolkitaspect.cpp | 4 +- .../ninjatoolkitaspect.cpp | 2 +- src/plugins/nim/editor/nimtexteditorwidget.h | 2 +- .../projectexplorer/projectconfiguration.h | 4 +- src/plugins/projectexplorer/toolchain.h | 4 +- src/plugins/qtsupport/qtkitaspect.cpp | 2 +- src/plugins/valgrind/callgrindtextmark.h | 2 +- src/plugins/vcpkg/vcpkgplugin.cpp | 2 +- src/plugins/vcsbase/submiteditorwidget.h | 2 +- src/plugins/welcome/welcomeplugin.cpp | 2 +- tests/auto/cplusplus/ast/tst_ast.cpp | 8 +- tests/auto/cplusplus/c99/tst_c99.cpp | 8 +- tests/auto/cplusplus/cxx11/tst_cxx11.cpp | 12 +-- .../cplusplus/findusages/tst_findusages.cpp | 2 +- tests/auto/cplusplus/lookup/tst_lookup.cpp | 2 +- .../preprocessor/tst_preprocessor.cpp | 46 +++++----- .../auto/cplusplus/semantic/tst_semantic.cpp | 10 +- .../translationunit/tst_translationunit.cpp | 2 +- .../circularplugins/plugin3/plugin3.h | 2 +- .../pluginspec/testplugin/testplugin.h | 4 +- .../auto/profilewriter/tst_profilewriter.cpp | 2 +- tests/auto/utils/process/tst_process.cpp | 3 +- tests/auto/utils/settings/tst_settings.cpp | 2 +- .../utils/stringutils/tst_stringutils.cpp | 3 +- .../tst_unixdevicefileaccess.cpp | 4 +- tests/manual/debugger/gui/mainwindow.cpp | 4 +- .../debugger/simple/simple_test_app.cpp | 14 +-- tests/manual/fakevim/main.cpp | 2 +- tests/manual/proparser/main.cpp | 8 +- 50 files changed, 174 insertions(+), 170 deletions(-) diff --git a/src/libs/solutions/tasking/qprocesstask.h b/src/libs/solutions/tasking/qprocesstask.h index 335f1d7ba3c..5fa4c19a41c 100644 --- a/src/libs/solutions/tasking/qprocesstask.h +++ b/src/libs/solutions/tasking/qprocesstask.h @@ -45,7 +45,7 @@ public: class TASKING_EXPORT QProcessAdapter : public TaskAdapter { private: - void start() { + void start() override { connect(task(), &QProcess::finished, this, [this] { const bool success = task()->exitStatus() == QProcess::NormalExit && task()->error() == QProcess::UnknownError diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp index aff4f8ffca8..43fc9d9bcc4 100644 --- a/src/libs/utils/aspects.cpp +++ b/src/libs/utils/aspects.cpp @@ -3227,7 +3227,7 @@ public: : QWidget(parent) , m_index(idx) {} - void paintEvent(QPaintEvent *event) + void paintEvent(QPaintEvent *event) override { QPainter p(this); QPalette pal = palette(); diff --git a/src/libs/utils/process.cpp b/src/libs/utils/process.cpp index 534dcff78f1..da7d65de0c5 100644 --- a/src/libs/utils/process.cpp +++ b/src/libs/utils/process.cpp @@ -202,7 +202,7 @@ public: class DefaultImpl : public ProcessInterface { private: - virtual void start() final; + void start() final; virtual void doDefaultStart(const QString &program, const QStringList &arguments) = 0; bool dissolveCommand(QString *program, QStringList *arguments); bool ensureProgramExists(const QString &program); @@ -481,7 +481,7 @@ private: } } - virtual ProcessBlockingInterface *processBlockingInterface() const { return m_blockingImpl; } + ProcessBlockingInterface *processBlockingInterface() const override { return m_blockingImpl; } void doDefaultStart(const QString &program, const QStringList &arguments) final { @@ -614,7 +614,7 @@ private: } } - virtual ProcessBlockingInterface *processBlockingInterface() const { return m_blockingImpl; } + ProcessBlockingInterface *processBlockingInterface() const override { return m_blockingImpl; } void doDefaultStart(const QString &program, const QStringList &arguments) final { diff --git a/src/libs/utils/stringutils.h b/src/libs/utils/stringutils.h index 8ce794693da..3e729e672c3 100644 --- a/src/libs/utils/stringutils.h +++ b/src/libs/utils/stringutils.h @@ -129,7 +129,7 @@ class QTCREATOR_UTILS_EXPORT MarkdownHighlighter : public QSyntaxHighlighter { public: MarkdownHighlighter(QTextDocument *parent); - void highlightBlock(const QString &text); + void highlightBlock(const QString &text) override; private: QBrush codeBgBrush(); diff --git a/src/libs/utils/styleanimator.h b/src/libs/utils/styleanimator.h index 6745890d148..87b7b82e097 100644 --- a/src/libs/utils/styleanimator.h +++ b/src/libs/utils/styleanimator.h @@ -99,7 +99,7 @@ public Q_SLOTS: protected: virtual bool isUpdateNeeded() const; - virtual void updateCurrentTime(int time) override; + void updateCurrentTime(int time) override; private: int m_delay; diff --git a/src/libs/utils/transientscroll.h b/src/libs/utils/transientscroll.h index b10f77541d6..eb19c8d8f14 100644 --- a/src/libs/utils/transientscroll.h +++ b/src/libs/utils/transientscroll.h @@ -24,7 +24,7 @@ public: virtual ~TransientScrollAreaSupport(); protected: - virtual bool eventFilter(QObject *watched, QEvent *event) override; + bool eventFilter(QObject *watched, QEvent *event) override; private: explicit TransientScrollAreaSupport(QAbstractScrollArea *scrollArea); @@ -66,6 +66,6 @@ public: private: GlobalTransientSupport(); static GlobalTransientSupport *instance(); - virtual bool eventFilter(QObject *watched, QEvent *event) override; + bool eventFilter(QObject *watched, QEvent *event) override; }; } diff --git a/src/plugins/android/createandroidmanifestwizard.h b/src/plugins/android/createandroidmanifestwizard.h index 4d5a309583f..aa231cbf7b6 100644 --- a/src/plugins/android/createandroidmanifestwizard.h +++ b/src/plugins/android/createandroidmanifestwizard.h @@ -19,7 +19,7 @@ public: QString buildKey() const; void setBuildKey(const QString &buildKey); - void accept(); + void accept() override; bool copyGradle(); void setDirectory(const Utils::FilePath &directory); diff --git a/src/plugins/autotest/testconfiguration.h b/src/plugins/autotest/testconfiguration.h index f784841bfc2..31293325c52 100644 --- a/src/plugins/autotest/testconfiguration.h +++ b/src/plugins/autotest/testconfiguration.h @@ -124,7 +124,7 @@ public: explicit TestToolConfiguration(ITestBase *testBase) : ITestConfiguration(testBase) {} Utils::CommandLine commandLine() const { return m_commandLine; } void setCommandLine(const Utils::CommandLine &cmdline) { m_commandLine = cmdline; } - virtual Utils::FilePath testExecutable() const override { return m_commandLine.executable(); }; + Utils::FilePath testExecutable() const override { return m_commandLine.executable(); }; private: Utils::CommandLine m_commandLine; diff --git a/src/plugins/autotest/testtreeitem.h b/src/plugins/autotest/testtreeitem.h index 4f4065c62d8..913db7e7aef 100644 --- a/src/plugins/autotest/testtreeitem.h +++ b/src/plugins/autotest/testtreeitem.h @@ -55,9 +55,9 @@ public: const Utils::FilePath &filePath = {}, Type type = Root); - virtual QVariant data(int column, int role) const override; - virtual bool setData(int column, const QVariant &data, int role) override; - virtual Qt::ItemFlags flags(int column) const override; + QVariant data(int column, int role) const override; + bool setData(int column, const QVariant &data, int role) override; + Qt::ItemFlags flags(int column) const override; virtual Qt::CheckState checked() const; virtual bool canProvideTestConfiguration() const { return false; } @@ -102,7 +102,7 @@ public: Type type = Root); virtual TestTreeItem *copyWithoutChildren() = 0; - virtual QVariant data(int column, int role) const override; + QVariant data(int column, int role) const override; bool modifyTestCaseOrSuiteContent(const TestParseResult *result); bool modifyTestFunctionContent(const TestParseResult *result); bool modifyDataTagContent(const TestParseResult *result); diff --git a/src/plugins/axivion/dashboard/dto.h b/src/plugins/axivion/dashboard/dto.h index 97ca5d602dc..5f018780557 100644 --- a/src/plugins/axivion/dashboard/dto.h +++ b/src/plugins/axivion/dashboard/dto.h @@ -126,7 +126,7 @@ namespace Axivion::Internal::Dto // Throws std::bad_variant_access const bool &getBool() const; - virtual QByteArray serialize() const override; + QByteArray serialize() const override; private: std::variant< @@ -179,7 +179,7 @@ namespace Axivion::Internal::Dto std::optional languageName ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -252,7 +252,7 @@ namespace Axivion::Internal::Dto QString newPassword ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -292,7 +292,7 @@ namespace Axivion::Internal::Dto QString displayColor ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -314,7 +314,7 @@ namespace Axivion::Internal::Dto QString text ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -342,7 +342,7 @@ namespace Axivion::Internal::Dto QString csrfToken ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -389,7 +389,7 @@ namespace Axivion::Internal::Dto std::optional line ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -510,7 +510,7 @@ namespace Axivion::Internal::Dto std::optional> data ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -577,7 +577,7 @@ namespace Axivion::Internal::Dto std::optional commentDeletionId ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -723,7 +723,7 @@ namespace Axivion::Internal::Dto qint32 endColumn ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -754,7 +754,7 @@ namespace Axivion::Internal::Dto QString color ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -814,7 +814,7 @@ namespace Axivion::Internal::Dto std::optional selected ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -898,7 +898,7 @@ namespace Axivion::Internal::Dto Any maxValue ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -960,7 +960,7 @@ namespace Axivion::Internal::Dto QString entityId ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -1020,7 +1020,7 @@ namespace Axivion::Internal::Dto std::optional> groups ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -1048,7 +1048,7 @@ namespace Axivion::Internal::Dto QString url ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -1087,7 +1087,7 @@ namespace Axivion::Internal::Dto std::optional disabled ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -1178,7 +1178,7 @@ namespace Axivion::Internal::Dto QString buildDate ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -1244,7 +1244,7 @@ namespace Axivion::Internal::Dto qint32 Removed ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -1358,7 +1358,7 @@ namespace Axivion::Internal::Dto std::optional cloneRatio ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -1423,7 +1423,7 @@ namespace Axivion::Internal::Dto void setTypeEnum(ApiTokenType newValue); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -1557,7 +1557,7 @@ namespace Axivion::Internal::Dto void setTypeEnum(ApiTokenType newValue); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -1672,7 +1672,7 @@ namespace Axivion::Internal::Dto void setAlignmentEnum(TableCellAlignment newValue); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -1816,7 +1816,7 @@ namespace Axivion::Internal::Dto std::optional csrfTokenUrl ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -1838,7 +1838,7 @@ namespace Axivion::Internal::Dto std::vector comments ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -1885,7 +1885,7 @@ namespace Axivion::Internal::Dto void setPrefixEnum(IssueKind newValue); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -1907,7 +1907,7 @@ namespace Axivion::Internal::Dto std::vector tags ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2022,7 +2022,7 @@ namespace Axivion::Internal::Dto void setKindEnum(IssueKind newValue); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2065,7 +2065,7 @@ namespace Axivion::Internal::Dto void setSeverityEnum(std::optional newValue); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2087,7 +2087,7 @@ namespace Axivion::Internal::Dto std::vector rules ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2127,7 +2127,7 @@ namespace Axivion::Internal::Dto void setDirectionEnum(SortDirection newValue); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2185,7 +2185,7 @@ namespace Axivion::Internal::Dto void setTypeEnum(std::optional newValue); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2213,7 +2213,7 @@ namespace Axivion::Internal::Dto std::vector rows ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2241,7 +2241,7 @@ namespace Axivion::Internal::Dto std::vector entities ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2291,7 +2291,7 @@ namespace Axivion::Internal::Dto std::vector lineMarkers ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2372,7 +2372,7 @@ namespace Axivion::Internal::Dto void setKindEnum(IssueKind newValue); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2470,7 +2470,7 @@ namespace Axivion::Internal::Dto std::optional totalRemovedCount ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2498,7 +2498,7 @@ namespace Axivion::Internal::Dto std::vector metrics ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2552,7 +2552,7 @@ namespace Axivion::Internal::Dto std::vector> values ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2582,7 +2582,7 @@ namespace Axivion::Internal::Dto std::vector rows ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2660,7 +2660,7 @@ namespace Axivion::Internal::Dto void setKindEnum(IssueKindForNamedFilterCreation newValue); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2792,7 +2792,7 @@ namespace Axivion::Internal::Dto void setTypeEnum(std::optional newValue); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2854,7 +2854,7 @@ namespace Axivion::Internal::Dto std::optional visibility ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2916,7 +2916,7 @@ namespace Axivion::Internal::Dto bool hasHiddenIssues ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -2953,7 +2953,7 @@ namespace Axivion::Internal::Dto bool hasWarnings ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; /** @@ -3023,7 +3023,7 @@ namespace Axivion::Internal::Dto QString axivionDefaultFilter ); - virtual QByteArray serialize() const override; + QByteArray serialize() const override; }; } diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h index a23ae568012..765c960bd1a 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h @@ -44,8 +44,8 @@ public: ConfigureEnvironmentAspect(Utils::AspectContainer *container, ProjectExplorer::BuildConfiguration *buildConfig); - void fromMap(const Utils::Store &map); - void toMap(Utils::Store &map) const; + void fromMap(const Utils::Store &map) override; + void toMap(Utils::Store &map) const override; }; } // namespace Internal diff --git a/src/plugins/conan/conanplugin.cpp b/src/plugins/conan/conanplugin.cpp index 0a0d3e20244..d33d261eff1 100644 --- a/src/plugins/conan/conanplugin.cpp +++ b/src/plugins/conan/conanplugin.cpp @@ -18,7 +18,7 @@ class ConanPlugin final : public ExtensionSystem::IPlugin Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Conan.json") - void initialize() + void initialize() override { d = std::make_unique(); } diff --git a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp index 24e7d6b0166..88beb673c0a 100644 --- a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp +++ b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp @@ -1270,8 +1270,8 @@ public: m_settings->overrideReplacement = QLatin1String("override"); } - bool gather() { return true; } - void saveSettings() { } + bool gather() override { return true; } + void saveSettings() override { } }; void InsertVirtualMethodsTest::test_data() diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 4d64b9ea070..4dba3176fb3 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -268,7 +268,7 @@ public: AddIncludeForUndefinedIdentifierTestFactory(const QString &include) : m_include(include) {} - void match(const CppQuickFixInterface &cppQuickFixInterface, QuickFixOperations &result) + void match(const CppQuickFixInterface &cppQuickFixInterface, QuickFixOperations &result) override { result << new AddIncludeForUndefinedIdentifierOp(cppQuickFixInterface, 0, m_include); } @@ -283,7 +283,7 @@ public: AddForwardDeclForUndefinedIdentifierTestFactory(const QString &className, int symbolPos) : m_className(className), m_symbolPos(symbolPos) {} - void match(const CppQuickFixInterface &cppQuickFixInterface, QuickFixOperations &result) + void match(const CppQuickFixInterface &cppQuickFixInterface, QuickFixOperations &result) override { result << new AddForwardDeclForUndefinedIdentifierOp(cppQuickFixInterface, 0, m_className, m_symbolPos); diff --git a/src/plugins/cppeditor/fileandtokenactions_test.cpp b/src/plugins/cppeditor/fileandtokenactions_test.cpp index 75dd0719a5c..ed6b80cecc8 100644 --- a/src/plugins/cppeditor/fileandtokenactions_test.cpp +++ b/src/plugins/cppeditor/fileandtokenactions_test.cpp @@ -292,7 +292,7 @@ class NoOpTokenAction : public TestActionsTestCase::AbstractAction { public: /// Do nothing on each token - void run(CppEditorWidget *) {} + void run(CppEditorWidget *) override {} }; class FollowSymbolUnderCursorTokenAction : public TestActionsTestCase::AbstractAction @@ -300,7 +300,7 @@ class FollowSymbolUnderCursorTokenAction : public TestActionsTestCase::AbstractA public: /// Follow symbol under cursor /// Warning: May block if file does not exist (e.g. a not generated ui_* file). - void run(CppEditorWidget *editorWidget); + void run(CppEditorWidget *editorWidget) override; }; void FollowSymbolUnderCursorTokenAction::run(CppEditorWidget *editorWidget) @@ -326,7 +326,7 @@ class SwitchDeclarationDefinitionTokenAction : public TestActionsTestCase::Abstr { public: /// Switch Declaration/Definition on each token - void run(CppEditorWidget *); + void run(CppEditorWidget *) override; }; void SwitchDeclarationDefinitionTokenAction::run(CppEditorWidget *) @@ -351,7 +351,7 @@ class FindUsagesTokenAction : public TestActionsTestCase::AbstractAction { public: /// Find Usages on each token - void run(CppEditorWidget *editor); + void run(CppEditorWidget *editor) override; }; void FindUsagesTokenAction::run(CppEditorWidget *editor) @@ -364,7 +364,7 @@ class RenameSymbolUnderCursorTokenAction : public TestActionsTestCase::AbstractA { public: /// Rename Symbol Under Cursor on each token (Renaming is not applied) - void run(CppEditorWidget *); + void run(CppEditorWidget *) override; }; void RenameSymbolUnderCursorTokenAction::run(CppEditorWidget *) @@ -377,7 +377,7 @@ class OpenTypeHierarchyTokenAction : public TestActionsTestCase::AbstractAction { public: /// Open Type Hierarchy on each token - void run(CppEditorWidget *); + void run(CppEditorWidget *) override; }; void OpenTypeHierarchyTokenAction::run(CppEditorWidget *) @@ -391,7 +391,7 @@ class InvokeCompletionTokenAction : public TestActionsTestCase::AbstractAction public: /// Invoke completion menu on each token. /// Warning: May create tool tip artefacts if focus is lost. - void run(CppEditorWidget *editorWidget); + void run(CppEditorWidget *editorWidget) override; }; void InvokeCompletionTokenAction::run(CppEditorWidget *editorWidget) @@ -417,7 +417,7 @@ class RunAllQuickFixesTokenAction : public TestActionsTestCase::AbstractAction { public: /// Trigger all Quick Fixes and apply the matching ones - void run(CppEditorWidget *editorWidget); + void run(CppEditorWidget *editorWidget) override; }; // TODO: Some QuickFixes operate on selections. @@ -456,7 +456,7 @@ void RunAllQuickFixesTokenAction::run(CppEditorWidget *editorWidget) class SwitchHeaderSourceFileAction : public TestActionsTestCase::AbstractAction { public: - void run(CppEditorWidget *); + void run(CppEditorWidget *) override; }; void SwitchHeaderSourceFileAction::run(CppEditorWidget *) diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index 03e6c0f00e8..88aaa35ad21 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -116,7 +116,7 @@ private: {settings().dockerBinaryPath(), {"container", "start", "-i", "-a", m_containerId}}); } - CommandLine createFallbackCommand(const CommandLine &cmdLine) + CommandLine createFallbackCommand(const CommandLine &cmdLine) override { CommandLine result = cmdLine; result.setExecutable(m_devicePath.withNewPath(cmdLine.executable().path())); diff --git a/src/plugins/fossil/fossilclient.cpp b/src/plugins/fossil/fossilclient.cpp index 3c3de5e523c..fb7a97abb2a 100644 --- a/src/plugins/fossil/fossilclient.cpp +++ b/src/plugins/fossil/fossilclient.cpp @@ -840,7 +840,7 @@ class FossilLogHighlighter : QSyntaxHighlighter { public: explicit FossilLogHighlighter(QTextDocument *parent); - virtual void highlightBlock(const QString &text) final; + void highlightBlock(const QString &text) final; private: const QRegularExpression m_revisionIdRx; diff --git a/src/plugins/incredibuild/incredibuildplugin.cpp b/src/plugins/incredibuild/incredibuildplugin.cpp index 8bff118b66e..384ee0a760b 100644 --- a/src/plugins/incredibuild/incredibuildplugin.cpp +++ b/src/plugins/incredibuild/incredibuildplugin.cpp @@ -21,7 +21,7 @@ class IncrediBuildPlugin final : public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "IncrediBuild.json") public: - void initialize() + void initialize() override { d = std::make_unique(); } diff --git a/src/plugins/languageclient/languageclientsettings.cpp b/src/plugins/languageclient/languageclientsettings.cpp index 7b6c4a41bfe..95a33eff352 100644 --- a/src/plugins/languageclient/languageclientsettings.cpp +++ b/src/plugins/languageclient/languageclientsettings.cpp @@ -131,7 +131,7 @@ public: m_settings.reset(LanguageClientManager::currentSettings()); resetCurrentSettings(row); } - void finish() + void finish() override { m_settings.reset(LanguageClientManager::currentSettings()); m_changedSettings.clear(); diff --git a/src/plugins/mcusupport/mcusupportimportprovider.h b/src/plugins/mcusupport/mcusupportimportprovider.h index 829fa711505..c1a130ed3d2 100644 --- a/src/plugins/mcusupport/mcusupportimportprovider.h +++ b/src/plugins/mcusupport/mcusupportimportprovider.h @@ -20,14 +20,14 @@ public: ~McuSupportImportProvider() {} // Overridden functions - virtual QList imports(ValueOwner *valueOwner, - const Document *context, - Snapshot *snapshot) const override; - virtual void loadBuiltins(ImportsPerDocument *importsPerDocument, - Imports *imports, - const Document *context, - ValueOwner *valueOwner, - Snapshot *snapshot) override; + QList imports(ValueOwner *valueOwner, + const Document *context, + Snapshot *snapshot) const override; + void loadBuiltins(ImportsPerDocument *importsPerDocument, + Imports *imports, + const Document *context, + ValueOwner *valueOwner, + Snapshot *snapshot) override; // Add to the interfaces needed for a document // path: opened qml document diff --git a/src/plugins/mesonprojectmanager/buildoptions.h b/src/plugins/mesonprojectmanager/buildoptions.h index dcb99833246..0e00beb999e 100644 --- a/src/plugins/mesonprojectmanager/buildoptions.h +++ b/src/plugins/mesonprojectmanager/buildoptions.h @@ -188,7 +188,7 @@ struct ArrayBuildOption : BuildOption } Type type() const override { return Type::array; } BuildOption *copy() const override { return new ArrayBuildOption{*this}; } - inline virtual QString mesonArg() const override + inline QString mesonArg() const override { return QString("-D%1=[%2]").arg(fullName()).arg(quoteAll(m_currentValue).join(',')); } diff --git a/src/plugins/mesonprojectmanager/mesontoolkitaspect.cpp b/src/plugins/mesonprojectmanager/mesontoolkitaspect.cpp index 59fc7ffb4a6..73d4f47b081 100644 --- a/src/plugins/mesonprojectmanager/mesontoolkitaspect.cpp +++ b/src/plugins/mesonprojectmanager/mesontoolkitaspect.cpp @@ -63,12 +63,12 @@ public: setup(k); } - KitAspect *createKitAspect(Kit *k) const + KitAspect *createKitAspect(Kit *k) const override { return new ToolKitAspectWidget{k, this, ToolKitAspectWidget::ToolType::Meson}; } - ItemList toUserOutput( const Kit *k) const + ItemList toUserOutput(const Kit *k) const override { const auto tool = MesonToolKitAspect::mesonTool(k); if (tool) diff --git a/src/plugins/mesonprojectmanager/ninjatoolkitaspect.cpp b/src/plugins/mesonprojectmanager/ninjatoolkitaspect.cpp index 4dae32a7b0d..49c87017444 100644 --- a/src/plugins/mesonprojectmanager/ninjatoolkitaspect.cpp +++ b/src/plugins/mesonprojectmanager/ninjatoolkitaspect.cpp @@ -64,7 +64,7 @@ public: setup(k); } - ItemList toUserOutput( const Kit *k) const + ItemList toUserOutput(const Kit *k) const override { const auto tool = NinjaToolKitAspect::ninjaTool(k); if (tool) diff --git a/src/plugins/nim/editor/nimtexteditorwidget.h b/src/plugins/nim/editor/nimtexteditorwidget.h index 2be4603966d..a163e70b535 100644 --- a/src/plugins/nim/editor/nimtexteditorwidget.h +++ b/src/plugins/nim/editor/nimtexteditorwidget.h @@ -15,7 +15,7 @@ public: protected: void findLinkAt(const QTextCursor &, const Utils::LinkHandler &processLinkCallback, - bool resolveTarget, bool inNextSplit); + bool resolveTarget, bool inNextSplit) override; private: void onFindLinkFinished(Suggest::NimSuggestClientRequest *request); diff --git a/src/plugins/projectexplorer/projectconfiguration.h b/src/plugins/projectexplorer/projectconfiguration.h index 329c660916c..098813c1768 100644 --- a/src/plugins/projectexplorer/projectconfiguration.h +++ b/src/plugins/projectexplorer/projectconfiguration.h @@ -45,9 +45,9 @@ public: bool hasError() const { return m_hasError; } // Note: Make sure subclasses call the superclasses' fromMap() function! - virtual void fromMap(const Utils::Store &map) override; + void fromMap(const Utils::Store &map) override; // Note: Make sure subclasses call the superclasses' toMap() function! - virtual void toMap(Utils::Store &map) const override; + void toMap(Utils::Store &map) const override; Target *target() const; Project *project() const; diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index d63f3476dfc..af154e1c198 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -143,7 +143,7 @@ public: // Used by the toolchainmanager to save user-generated tool chains. // Make sure to call this function when deriving! - virtual void toMap(Utils::Store &map) const; + void toMap(Utils::Store &map) const override; virtual Tasks validateKit(const Kit *k) const; virtual bool isJobCountSupported() const { return true; } @@ -180,7 +180,7 @@ protected: void toolChainUpdated(); // Make sure to call this function when deriving! - virtual void fromMap(const Utils::Store &data); + void fromMap(const Utils::Store &data) override; void reportError(); bool hasError() const; diff --git a/src/plugins/qtsupport/qtkitaspect.cpp b/src/plugins/qtsupport/qtkitaspect.cpp index 982f1e2726c..cd384a01e82 100644 --- a/src/plugins/qtsupport/qtkitaspect.cpp +++ b/src/plugins/qtsupport/qtkitaspect.cpp @@ -62,7 +62,7 @@ public: private: void makeReadOnly() final { m_combo->setEnabled(false); } - void addToLayoutImpl(Layouting::LayoutItem &parent) + void addToLayoutImpl(Layouting::LayoutItem &parent) override { addMutableAction(m_combo); parent.addItem(m_combo); diff --git a/src/plugins/valgrind/callgrindtextmark.h b/src/plugins/valgrind/callgrindtextmark.h index 998da19a7e2..7bfaeafadf6 100644 --- a/src/plugins/valgrind/callgrindtextmark.h +++ b/src/plugins/valgrind/callgrindtextmark.h @@ -26,7 +26,7 @@ public: const Valgrind::Callgrind::Function *function() const; private: - bool addToolTipContent(QLayout *target) const; + bool addToolTipContent(QLayout *target) const override; qreal costs() const; QPersistentModelIndex m_modelIndex; diff --git a/src/plugins/vcpkg/vcpkgplugin.cpp b/src/plugins/vcpkg/vcpkgplugin.cpp index 9dc717e08e1..c6d7c08f512 100644 --- a/src/plugins/vcpkg/vcpkgplugin.cpp +++ b/src/plugins/vcpkg/vcpkgplugin.cpp @@ -36,7 +36,7 @@ public: #endif } - virtual void extensionsInitialized() final { settings().setVcpkgRootEnvironmentVariable(); } + void extensionsInitialized() final { settings().setVcpkgRootEnvironmentVariable(); } std::unique_ptr d; }; diff --git a/src/plugins/vcsbase/submiteditorwidget.h b/src/plugins/vcsbase/submiteditorwidget.h index 21835382cf1..38fc1bf2744 100644 --- a/src/plugins/vcsbase/submiteditorwidget.h +++ b/src/plugins/vcsbase/submiteditorwidget.h @@ -84,7 +84,7 @@ signals: void submitActionEnabledChanged(bool); protected: - virtual void changeEvent(QEvent *event) override; + void changeEvent(QEvent *event) override; virtual QString cleanupDescription(const QString &) const; virtual QString commitName() const; void insertTopWidget(QWidget *w); diff --git a/src/plugins/welcome/welcomeplugin.cpp b/src/plugins/welcome/welcomeplugin.cpp index c0a2f25ac94..acfa754633c 100644 --- a/src/plugins/welcome/welcomeplugin.cpp +++ b/src/plugins/welcome/welcomeplugin.cpp @@ -72,7 +72,7 @@ class ResizeSignallingWidget : public QWidget Q_OBJECT public: - void resizeEvent(QResizeEvent *event); + void resizeEvent(QResizeEvent *event) override; signals: void resized(const QSize &size, const QSize &oldSize); diff --git a/tests/auto/cplusplus/ast/tst_ast.cpp b/tests/auto/cplusplus/ast/tst_ast.cpp index 5790cb090ac..3110288e21e 100644 --- a/tests/auto/cplusplus/ast/tst_ast.cpp +++ b/tests/auto/cplusplus/ast/tst_ast.cpp @@ -68,10 +68,10 @@ public: : errorCount(0) { } - virtual void report(int /*level*/, - const StringLiteral *fileName, - int line, int column, - const char *format, va_list ap) + void report(int /*level*/, + const StringLiteral *fileName, + int line, int column, + const char *format, va_list ap) override { ++errorCount; diff --git a/tests/auto/cplusplus/c99/tst_c99.cpp b/tests/auto/cplusplus/c99/tst_c99.cpp index b630247263b..030b0a73444 100644 --- a/tests/auto/cplusplus/c99/tst_c99.cpp +++ b/tests/auto/cplusplus/c99/tst_c99.cpp @@ -51,10 +51,10 @@ class tst_c99: public QObject { } - virtual void report(int level, - const StringLiteral *fileName, - int line, int column, - const char *format, va_list ap) + void report(int level, + const StringLiteral *fileName, + int line, int column, + const char *format, va_list ap) override { if (! errors) return; diff --git a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp index d27ba601467..1c71a31cbb2 100644 --- a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp +++ b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp @@ -54,10 +54,10 @@ class tst_cxx11: public QObject { } - virtual void report(int level, - const StringLiteral *fileName, - int line, int column, - const char *format, va_list ap) override + void report(int level, + const StringLiteral *fileName, + int line, int column, + const char *format, va_list ap) override { if (! errors) return; @@ -86,9 +86,9 @@ class tst_cxx11: public QObject } private: - bool preVisit(Symbol *) { return !m_function; } + bool preVisit(Symbol *) override { return !m_function; } - bool visit(Function *function) + bool visit(Function *function) override { if (function->name()) return true; diff --git a/tests/auto/cplusplus/findusages/tst_findusages.cpp b/tests/auto/cplusplus/findusages/tst_findusages.cpp index 779863f3477..78bebc39c35 100644 --- a/tests/auto/cplusplus/findusages/tst_findusages.cpp +++ b/tests/auto/cplusplus/findusages/tst_findusages.cpp @@ -35,7 +35,7 @@ public: return _exprs; } - virtual bool preVisit(AST *ast) { + bool preVisit(AST *ast) override { if (NameAST *nameAst = ast->asName()) if (!qstrcmp(_name, nameAst->name->identifier()->chars())) _exprs.append(nameAst); diff --git a/tests/auto/cplusplus/lookup/tst_lookup.cpp b/tests/auto/cplusplus/lookup/tst_lookup.cpp index 82caafa2cfd..2ae61b7b790 100644 --- a/tests/auto/cplusplus/lookup/tst_lookup.cpp +++ b/tests/auto/cplusplus/lookup/tst_lookup.cpp @@ -45,7 +45,7 @@ public: { accept(ast); } protected: - virtual bool visit(ClassSpecifierAST *ast) + bool visit(ClassSpecifierAST *ast) override { Class *classSymbol = ast->symbol; Q_ASSERT(classSymbol != 0); diff --git a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp index 54ceed08ca0..03cf4d930bd 100644 --- a/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp +++ b/tests/auto/cplusplus/preprocessor/tst_preprocessor.cpp @@ -102,40 +102,42 @@ public: virtual ~MockClient() {} - virtual void macroAdded(const Macro & macro) + void macroAdded(const Macro ¯o) override { m_definedMacros.append(macro.name()); m_definedMacrosLine.append(macro.line()); } - virtual void passedMacroDefinitionCheck(int /*bytesOffset*/, - int /*utf16charsOffset*/, - int line, - const Macro ¯o) + void passedMacroDefinitionCheck(int /*bytesOffset*/, + int /*utf16charsOffset*/, + int line, + const Macro ¯o) override { m_definitionsResolvedFromLines[macro.name()].append(line); } - virtual void failedMacroDefinitionCheck(int /*offset*/, - int /*utf16charsOffset*/, - const ByteArrayRef &name) + void failedMacroDefinitionCheck(int /*offset*/, + int /*utf16charsOffset*/, + const ByteArrayRef &name) override { m_unresolvedDefines.insert(name.toByteArray()); } - virtual void notifyMacroReference(int bytesOffset, int /*utf16charsOffset*/, - int line, const Macro ¯o) + void notifyMacroReference(int bytesOffset, + int /*utf16charsOffset*/, + int line, + const Macro ¯o) override { m_macroUsesLine[macro.name()].append(line); m_expandedMacrosOffset.append(bytesOffset); } - virtual void startExpandingMacro(int bytesOffset, - int /*utf16charsOffset*/, - int line, - const Macro ¯o, - const QVector &actuals - = QVector()) + void startExpandingMacro(int bytesOffset, + int /*utf16charsOffset*/, + int line, + const Macro ¯o, + const QVector &actuals + = QVector()) override { m_expandedMacros.append(macro.name()); m_expandedMacrosOffset.append(bytesOffset); @@ -144,16 +146,16 @@ public: m_usedMacros.insert(macro.name(), actuals); } - virtual void stopExpandingMacro(int /*offset*/, const Macro &/*macro*/) {} + void stopExpandingMacro(int /*offset*/, const Macro &/*macro*/) override {} - virtual void startSkippingBlocks(int utf16charsOffset) + void startSkippingBlocks(int utf16charsOffset) override { m_skippedBlocks.append(Block(utf16charsOffset)); } - virtual void stopSkippingBlocks(int utf16charsOffset) + void stopSkippingBlocks(int utf16charsOffset) override { m_skippedBlocks.last().end = utf16charsOffset; } - virtual void sourceNeeded(int line, const Utils::FilePath &includedFileName, IncludeType mode, - const Utils::FilePaths &initialIncludes = {}) + void sourceNeeded(int line, const Utils::FilePath &includedFileName, IncludeType mode, + const Utils::FilePaths &initialIncludes = {}) override { Q_UNUSED(initialIncludes) #if 1 @@ -223,7 +225,7 @@ public: *m_output = m_pp.run(fileName, src, nolines, true); } - virtual void markAsIncludeGuard(const QByteArray ¯oName) + void markAsIncludeGuard(const QByteArray ¯oName) override { m_includeGuardMacro = macroName; } QByteArray includeGuard() const diff --git a/tests/auto/cplusplus/semantic/tst_semantic.cpp b/tests/auto/cplusplus/semantic/tst_semantic.cpp index 08b59caac19..ad98205442c 100644 --- a/tests/auto/cplusplus/semantic/tst_semantic.cpp +++ b/tests/auto/cplusplus/semantic/tst_semantic.cpp @@ -90,10 +90,10 @@ public: : errorCount(0) { } - virtual void report(int /*level*/, - const StringLiteral *fileName, - int line, int column, - const char *format, va_list ap) + void report(int /*level*/, + const StringLiteral *fileName, + int line, int column, + const char *format, va_list ap) override { ++errorCount; @@ -757,7 +757,7 @@ public: return selectors; } - virtual bool visit(ObjCSelectorAST *ast) {selectors.append(ast); return false;} + bool visit(ObjCSelectorAST *ast) override {selectors.append(ast); return false;} private: QList selectors; diff --git a/tests/auto/cplusplus/translationunit/tst_translationunit.cpp b/tests/auto/cplusplus/translationunit/tst_translationunit.cpp index f4bab87a563..6759a6b14ba 100644 --- a/tests/auto/cplusplus/translationunit/tst_translationunit.cpp +++ b/tests/auto/cplusplus/translationunit/tst_translationunit.cpp @@ -109,7 +109,7 @@ private: Diagnostic() : errorCount(0) {} void report(int /*level*/, const StringLiteral *fileName, int line, - int column, const char *format, va_list ap) + int column, const char *format, va_list ap) override { ++errorCount; qDebug() << fileName->chars() << ':' << line << ':' << column diff --git a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin3/plugin3.h b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin3/plugin3.h index b3733854e62..f0ee8db5996 100644 --- a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin3/plugin3.h +++ b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin3/plugin3.h @@ -26,7 +26,7 @@ class PLUGIN3_EXPORT MyPlugin3 : public ExtensionSystem::IPlugin public: MyPlugin3(); - bool initialize(const QStringList &arguments, QString *errorString); + bool initialize(const QStringList &arguments, QString *errorString) override; }; } // namespace Plugin3 diff --git a/tests/auto/extensionsystem/pluginspec/testplugin/testplugin.h b/tests/auto/extensionsystem/pluginspec/testplugin/testplugin.h index 8cf246ce970..e2c9887ffcd 100644 --- a/tests/auto/extensionsystem/pluginspec/testplugin/testplugin.h +++ b/tests/auto/extensionsystem/pluginspec/testplugin/testplugin.h @@ -18,8 +18,8 @@ class MYPLUGIN_EXPORT MyPluginImpl : public ExtensionSystem::IPlugin public: MyPluginImpl(); - bool initialize(const QStringList &arguments, QString *errorString); - void extensionsInitialized(); + bool initialize(const QStringList &arguments, QString *errorString) override; + void extensionsInitialized() override; public slots: bool isInitialized() { return m_isInitialized; } diff --git a/tests/auto/profilewriter/tst_profilewriter.cpp b/tests/auto/profilewriter/tst_profilewriter.cpp index 23c2c37e7fa..535969ab517 100644 --- a/tests/auto/profilewriter/tst_profilewriter.cpp +++ b/tests/auto/profilewriter/tst_profilewriter.cpp @@ -23,7 +23,7 @@ static void print(const QString &fileName, int lineNo, const QString &msg) class ParseHandler : public QMakeParserHandler { public: - virtual void message(int /* type */, const QString &msg, const QString &fileName, int lineNo) + void message(int /* type */, const QString &msg, const QString &fileName, int lineNo) override { print(fileName, lineNo, msg); } }; diff --git a/tests/auto/utils/process/tst_process.cpp b/tests/auto/utils/process/tst_process.cpp index 600c081b7fb..4bea9979584 100644 --- a/tests/auto/utils/process/tst_process.cpp +++ b/tests/auto/utils/process/tst_process.cpp @@ -64,7 +64,8 @@ QtMessageHandler MessageHandler::s_oldMessageHandler = 0; class MacroMapExpander : public AbstractMacroExpander { public: - virtual bool resolveMacro(const QString &name, QString *ret, QSet &seen) + bool resolveMacro(const QString &name, QString *ret, QSet &seen) + override { // loop prevention const int count = seen.count(); diff --git a/tests/auto/utils/settings/tst_settings.cpp b/tests/auto/utils/settings/tst_settings.cpp index 7ce338025b0..8faea22c99c 100644 --- a/tests/auto/utils/settings/tst_settings.cpp +++ b/tests/auto/utils/settings/tst_settings.cpp @@ -113,7 +113,7 @@ public: VersionedBackUpStrategy(accessor) { } - FilePaths readFileCandidates(const Utils::FilePath &baseFileName) const + FilePaths readFileCandidates(const Utils::FilePath &baseFileName) const override { return Utils::filtered(static_cast(accessor())->fileNames(), [&baseFileName](const Utils::FilePath &f) { diff --git a/tests/auto/utils/stringutils/tst_stringutils.cpp b/tests/auto/utils/stringutils/tst_stringutils.cpp index 7442c06daa6..9219ef7c8b0 100644 --- a/tests/auto/utils/stringutils/tst_stringutils.cpp +++ b/tests/auto/utils/stringutils/tst_stringutils.cpp @@ -13,7 +13,8 @@ using namespace Utils; class TestMacroExpander : public Utils::AbstractMacroExpander { public: - virtual bool resolveMacro(const QString &name, QString *ret, QSet &seen) + bool resolveMacro(const QString &name, QString *ret, QSet &seen) + override { // loop prevention const int count = seen.count(); diff --git a/tests/auto/utils/unixdevicefileaccess/tst_unixdevicefileaccess.cpp b/tests/auto/utils/unixdevicefileaccess/tst_unixdevicefileaccess.cpp index a55577ef05e..09b508f6a68 100644 --- a/tests/auto/utils/unixdevicefileaccess/tst_unixdevicefileaccess.cpp +++ b/tests/auto/utils/unixdevicefileaccess/tst_unixdevicefileaccess.cpp @@ -30,8 +30,8 @@ class TestDFA : public UnixDeviceFileAccess public: using UnixDeviceFileAccess::UnixDeviceFileAccess; - virtual RunResult runInShell(const CommandLine &cmdLine, - const QByteArray &inputData = {}) const override + RunResult runInShell(const CommandLine &cmdLine, + const QByteArray &inputData = {}) const override { // Note: Don't convert into Utils::Process. See more comments in this change in gerrit. QProcess p; diff --git a/tests/manual/debugger/gui/mainwindow.cpp b/tests/manual/debugger/gui/mainwindow.cpp index bea62f56a5e..915e63765ec 100644 --- a/tests/manual/debugger/gui/mainwindow.cpp +++ b/tests/manual/debugger/gui/mainwindow.cpp @@ -172,7 +172,7 @@ class MyThread : public QThread { public: MyThread(int base, QObject *parent) : QThread(parent), m_base(base) {} - void run(); + void run() override; private: int m_base; }; @@ -196,7 +196,7 @@ void MyThread::run() class MyFastThread : public QThread { public: MyFastThread(QObject *parent) : QThread(parent) {} - void run() { qDebug() << "Done" << currentThreadId(); } + void run() override { qDebug() << "Done" << currentThreadId(); } }; diff --git a/tests/manual/debugger/simple/simple_test_app.cpp b/tests/manual/debugger/simple/simple_test_app.cpp index f32c1baaf15..d8421eeef12 100644 --- a/tests/manual/debugger/simple/simple_test_app.cpp +++ b/tests/manual/debugger/simple/simple_test_app.cpp @@ -314,7 +314,7 @@ struct BaseClass struct DerivedClass : BaseClass { DerivedClass() : b(2) {} - int foo() { return b; } + int foo() override { return b; } int b; }; @@ -4204,7 +4204,7 @@ namespace qthread { void setId(int id) { m_id = id; } - void run() + void run() override { int j = 2; ++j; @@ -4787,7 +4787,7 @@ namespace namespc { { public: MyFoo() {} - virtual void doit(int i) + void doit(int i) override { // Note there's a local 'n' and one in the base class. n = i; @@ -4799,7 +4799,7 @@ namespace namespc { class MyBar : public MyFoo { public: - virtual void doit(int i) + void doit(int i) override { n = i + 1; } @@ -4810,7 +4810,7 @@ namespace namespc { class MyAnon : public MyBar { public: - virtual void doit(int i) + void doit(int i) override { n = i + 3; } @@ -4821,7 +4821,7 @@ namespace namespc { class MyBaz : public MyAnon { public: - virtual void doit(int i) + void doit(int i) override { n = i + 5; } @@ -6549,7 +6549,7 @@ namespace bug5106 { { public: B5106(int c, int a, int b) : A5106(a, b), m_c(c) {Q_UNUSED(m_c)} - virtual int test() { return 4; BREAK_HERE; } + int test() override { return 4; BREAK_HERE; } private: int m_c; }; diff --git a/tests/manual/fakevim/main.cpp b/tests/manual/fakevim/main.cpp index dfdaa188f47..036a5f61b03 100644 --- a/tests/manual/fakevim/main.cpp +++ b/tests/manual/fakevim/main.cpp @@ -28,7 +28,7 @@ public: TextEdit::setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); } - void paintEvent(QPaintEvent *e) + void paintEvent(QPaintEvent *e) override { TextEdit::paintEvent(e); diff --git a/tests/manual/proparser/main.cpp b/tests/manual/proparser/main.cpp index 310eada39a4..952e5ce38e7 100644 --- a/tests/manual/proparser/main.cpp +++ b/tests/manual/proparser/main.cpp @@ -31,14 +31,14 @@ static void print(const QString &fileName, int lineNo, int type, const QString & class EvalHandler : public QMakeHandler { public: - virtual void message(int type, const QString &msg, const QString &fileName, int lineNo) + void message(int type, const QString &msg, const QString &fileName, int lineNo) override { print(fileName, lineNo, type, msg); } - virtual void fileMessage(int /*type*/, const QString &msg) + void fileMessage(int /*type*/, const QString &msg) override { qWarning("%s", qPrintable(msg)); } - virtual void aboutToEval(ProFile *, ProFile *, EvalFileType) {} - virtual void doneWithEval(ProFile *) {} + void aboutToEval(ProFile *, ProFile *, EvalFileType) override {} + void doneWithEval(ProFile *) override {} }; static EvalHandler evalHandler; From f25702ec0d2508594411ccfc820587f8c30b19c6 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Mon, 13 Nov 2023 17:26:26 +0100 Subject: [PATCH 0180/1546] Core: Use LayoutBuilder in the About dialog The GridLayout code was hard to read. Let's use LayoutBuilder. Change-Id: I90a2113e12541061fbf699f36328bb326bd1ebd9 Reviewed-by: hjk --- src/plugins/coreplugin/versiondialog.cpp | 32 ++++++++++++++---------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/plugins/coreplugin/versiondialog.cpp b/src/plugins/coreplugin/versiondialog.cpp index 8e68172de2c..833fc0a7071 100644 --- a/src/plugins/coreplugin/versiondialog.cpp +++ b/src/plugins/coreplugin/versiondialog.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -33,8 +34,6 @@ VersionDialog::VersionDialog(QWidget *parent) setWindowIcon(Icons::QTCREATORLOGO_BIG.icon()); setWindowTitle(Tr::tr("About %1").arg(QGuiApplication::applicationDisplayName())); - auto layout = new QGridLayout(this); - layout->setSizeConstraint(QLayout::SetFixedSize); const Utils::AppInfo appInfo = Utils::appInfo(); QString ideRev; @@ -78,22 +77,29 @@ VersionDialog::VersionDialog(QWidget *parent) "Qt Quick Compiler®, Qt Enterprise®, Qt Mobile® and Qt Embedded® are " "registered trademarks of The Qt Company Ltd."); - QLabel *copyRightLabel = new QLabel(description); + auto logoLabel = new QLabel; + logoLabel->setPixmap(Icons::QTCREATORLOGO_BIG.pixmap()); + + auto copyRightLabel = new QLabel(description); copyRightLabel->setWordWrap(true); copyRightLabel->setOpenExternalLinks(true); copyRightLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); - QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); - QPushButton *closeButton = buttonBox->button(QDialogButtonBox::Close); - QTC_CHECK(closeButton); - buttonBox->addButton(closeButton, QDialogButtonBox::ButtonRole(QDialogButtonBox::RejectRole | QDialogButtonBox::AcceptRole)); - connect(buttonBox , &QDialogButtonBox::rejected, this, &QDialog::reject); + auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); - QLabel *logoLabel = new QLabel; - logoLabel->setPixmap(Icons::QTCREATORLOGO_BIG.pixmap()); - layout->addWidget(logoLabel , 0, 0, 1, 1); - layout->addWidget(copyRightLabel, 0, 1, 4, 4); - layout->addWidget(buttonBox, 4, 0, 1, 5); + using namespace Layouting; + Column { + Row { + Column { logoLabel, st }, + Column { copyRightLabel }, + }, + buttonBox, + }.attachTo(this); + + layout()->setSizeConstraint(QLayout::SetFixedSize); + + connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); } bool VersionDialog::event(QEvent *event) From b19a26b1350e706dc596ec217db7c2c25eb490d7 Mon Sep 17 00:00:00 2001 From: Tasuku Suzuki Date: Sat, 14 Oct 2023 13:43:43 +0900 Subject: [PATCH 0181/1546] ProjectExplorer: Not create Manage Kits button if Kit options are hidden Project window doesn't use the button anywhere else. Change-Id: I97537524b615b9fd523828bc540b5412578c69c9 Reviewed-by: Eike Ziller Reviewed-by: --- src/plugins/projectexplorer/projectwindow.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/plugins/projectexplorer/projectwindow.cpp b/src/plugins/projectexplorer/projectwindow.cpp index 66ce26e41f6..cd4b2321174 100644 --- a/src/plugins/projectexplorer/projectwindow.cpp +++ b/src/plugins/projectexplorer/projectwindow.cpp @@ -560,10 +560,6 @@ public: m_importBuild->setEnabled(project && project->projectImporter()); }); - m_manageKits = new QPushButton(Tr::tr("Manage Kits...")); - connect(m_manageKits, &QPushButton::clicked, - this, &ProjectWindowPrivate::handleManageKits); - auto styledBar = new StyledBar; // The black blob on top of the side bar styledBar->setObjectName("ProjectModeStyledBar"); @@ -585,7 +581,11 @@ public: QStringList list = Core::ICore::settings()->value("HideOptionCategories").toStringList(); if (!list.contains("Kits")) { - innerLayout->addWidget(m_manageKits); + auto manageKits = new QPushButton(Tr::tr("Manage Kits...")); + connect(manageKits, &QPushButton::clicked, + this, &ProjectWindowPrivate::handleManageKits); + + innerLayout->addWidget(manageKits); innerLayout->addSpacerItem(new QSpacerItem(10, 30, QSizePolicy::Maximum, QSizePolicy::Maximum)); } @@ -812,7 +812,6 @@ public: QComboBox *m_projectSelection; SelectorTree *m_selectorTree; QPushButton *m_importBuild; - QPushButton *m_manageKits; QAction m_toggleRightSidebarAction; QDockWidget *m_outputDock; BuildSystemOutputWindow *m_buildSystemOutput; From 879b9b8803d47cdde388c2fb9446e07b28434396 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 14 Nov 2023 10:21:54 +0100 Subject: [PATCH 0182/1546] Core: Let ActionBuilder build a ParameterAction Simpler overall interface with only slight overhead when not used. Change-Id: I4846df70df0d442a264d81ac5f351407b2d5e40f Reviewed-by: Eike Ziller --- .../actionmanager/actionmanager.cpp | 25 ++++++++++++++++--- .../coreplugin/actionmanager/actionmanager.h | 10 ++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index 1287d117182..d0d97f22b28 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -9,11 +9,11 @@ #include #include +#include #include #include -#include #include #include #include @@ -75,7 +75,7 @@ class ActionBuilderPrivate { public: ActionBuilderPrivate(QObject *contextActionParent, const Id actionId) - : action(new QAction(contextActionParent)) + : action(new ParameterAction({}, {}, ParameterAction::AlwaysEnabled, contextActionParent)) , actionId(actionId) { command = ActionManager::createCommand(actionId); @@ -87,7 +87,7 @@ public: ActionManager::registerAction(action, actionId, context); } - QAction *action = nullptr; + ParameterAction *action = nullptr; Command *command = nullptr; Id actionId; @@ -213,6 +213,20 @@ void ActionBuilder::setMenuRole(QAction::MenuRole role) d->action->setMenuRole(role); } +void ActionBuilder::setParameterText(const QString ¶meterText, + const QString &emptyText, + EnablingMode mode) +{ + QTC_CHECK(parameterText.contains("%1")); + QTC_CHECK(!emptyText.contains("%1")); + + d->action->setEmptyText(emptyText); + d->action->setParameterText(parameterText); + d->action->setEnablingMode(mode == AlwaysEnabled + ? ParameterAction::AlwaysEnabled + : ParameterAction::EnabledWithParameter); +} + Command *ActionBuilder::command() const { return d->command; @@ -228,6 +242,11 @@ QAction *ActionBuilder::contextAction() const return d->action; } +ParameterAction *ActionBuilder::contextParameterAction() const +{ + return d->action; +} + void ActionBuilder::bindContextAction(QAction **dest) { QTC_ASSERT(dest, return); diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.h b/src/plugins/coreplugin/actionmanager/actionmanager.h index 320842e0b77..aba964a3746 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager.h @@ -13,6 +13,8 @@ #include +namespace Utils { class ParameterAction; } + namespace Core { class ActionContainer; @@ -57,10 +59,18 @@ public: void setCheckable(bool on); void setMenuRole(QAction::MenuRole role); + enum EnablingMode { AlwaysEnabled, EnabledWithParameter }; + void setParameterText(const QString ¶metrizedText, + const QString &emptyText, + EnablingMode mode = EnabledWithParameter); + + Command *command() const; QAction *commandAction() const; QAction *contextAction() const; + Utils::ParameterAction *contextParameterAction() const; void bindContextAction(QAction **dest); + void bindContextAction(Utils::ParameterAction **dest); void augmentActionWithShortcutToolTip(); private: From a252ea02057b4648245776ea88c25b7667210fc3 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 13 Nov 2023 15:16:57 +0100 Subject: [PATCH 0183/1546] CMakeProjectManager: Use Core::ActionBuilder in a few places Change-Id: If2e852e744a070805a542ad62291ad791b1bddf5 Reviewed-by: Christian Stenger --- .../cmakeprojectmanager.cpp | 160 ++++++++---------- .../actionmanager/actionmanager.cpp | 10 +- .../coreplugin/actionmanager/actionmanager.h | 2 +- 3 files changed, 76 insertions(+), 96 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp index 1dfc03af62f..886caa47f51 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp @@ -43,6 +43,7 @@ #include #include +using namespace Core; using namespace CppEditor; using namespace ProjectExplorer; using namespace Utils; @@ -50,128 +51,105 @@ using namespace Utils; namespace CMakeProjectManager::Internal { CMakeManager::CMakeManager() - : m_runCMakeAction( - new QAction(ProjectExplorer::Icons::CMAKE_LOGO.icon(), Tr::tr("Run CMake"), this)) - , m_clearCMakeCacheAction(new QAction(QIcon(), Tr::tr("Clear CMake Configuration"), this)) - , m_runCMakeActionContextMenu( - new QAction(ProjectExplorer::Icons::CMAKE_LOGO.icon(), Tr::tr("Run CMake"), this)) - , m_rescanProjectAction(new QAction(QIcon(), Tr::tr("Rescan Project"), this)) - , m_reloadCMakePresetsAction( - new QAction(Utils::Icons::RELOAD.icon(), Tr::tr("Reload CMake Presets"), this)) - , m_cmakeProfilerAction( - new QAction(ProjectExplorer::Icons::CMAKE_LOGO.icon(), Tr::tr("CMake Profiler"), this)) - , m_cmakeDebuggerAction(new QAction(ProjectExplorer::Icons::CMAKE_LOGO.icon(), - Tr::tr("Start CMake Debugging"), - this)) { - Core::ActionContainer *mbuild = - Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_BUILDPROJECT); - Core::ActionContainer *mproject = - Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_PROJECTCONTEXT); - Core::ActionContainer *msubproject = - Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_SUBPROJECTCONTEXT); - Core::ActionContainer *mfile = - Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_FILECONTEXT); - Core::ActionContainer *manalyzer = - Core::ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER); - Core::ActionContainer *mdebugger = - Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_DEBUG_STARTDEBUGGING); + namespace PEC = ProjectExplorer::Constants; - const Core::Context projectContext(CMakeProjectManager::Constants::CMAKE_PROJECT_ID); - const Core::Context globalContext(Core::Constants::C_GLOBAL); + const Context projectContext(CMakeProjectManager::Constants::CMAKE_PROJECT_ID); - Core::Command *command = Core::ActionManager::registerAction(m_runCMakeAction, - Constants::RUN_CMAKE, - globalContext); - command->setAttribute(Core::Command::CA_Hide); - mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_BUILD); - connect(m_runCMakeAction, &QAction::triggered, this, [this] { - runCMake(ProjectManager::startupBuildSystem()); - }); + ActionBuilder runCMakeAction(this, Constants::RUN_CMAKE); + runCMakeAction.setText(Tr::tr("Run CMake")); + runCMakeAction.setIcon(ProjectExplorer::Icons::CMAKE_LOGO.icon()); + runCMakeAction.bindContextAction(&m_runCMakeAction); + runCMakeAction.setCommandAttribute(Command::CA_Hide); + runCMakeAction.setContainer(PEC::M_BUILDPROJECT, PEC::G_BUILD_BUILD); + runCMakeAction.setOnTriggered(this, [this] { runCMake(ProjectManager::startupBuildSystem()); }); - command = Core::ActionManager::registerAction(m_clearCMakeCacheAction, - Constants::CLEAR_CMAKE_CACHE, - globalContext); - command->setAttribute(Core::Command::CA_Hide); - mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_BUILD); - connect(m_clearCMakeCacheAction, &QAction::triggered, this, [this] { + ActionBuilder clearCMakeCacheAction(this, Constants::CLEAR_CMAKE_CACHE); + clearCMakeCacheAction.setText(Tr::tr("Clear CMake Configuration")); + clearCMakeCacheAction.bindContextAction(&m_clearCMakeCacheAction); + clearCMakeCacheAction.setCommandAttribute(Command::CA_Hide); + clearCMakeCacheAction.setContainer(PEC::M_BUILDPROJECT, PEC::G_BUILD_BUILD); + clearCMakeCacheAction.setOnTriggered(this, [this] { clearCMakeCache(ProjectManager::startupBuildSystem()); }); - command = Core::ActionManager::registerAction(m_runCMakeActionContextMenu, - Constants::RUN_CMAKE_CONTEXT_MENU, - projectContext); - command->setAttribute(Core::Command::CA_Hide); - mproject->addAction(command, ProjectExplorer::Constants::G_PROJECT_BUILD); - msubproject->addAction(command, ProjectExplorer::Constants::G_PROJECT_BUILD); - connect(m_runCMakeActionContextMenu, &QAction::triggered, this, [this] { + ActionBuilder runCMakeActionContextMenu(this, Constants::RUN_CMAKE_CONTEXT_MENU); + runCMakeActionContextMenu.setText(Tr::tr("Run CMake")); + runCMakeActionContextMenu.setIcon(ProjectExplorer::Icons::CMAKE_LOGO.icon()); + runCMakeActionContextMenu.setContext(projectContext); + runCMakeActionContextMenu.bindContextAction(&m_runCMakeActionContextMenu); + runCMakeActionContextMenu.setCommandAttribute(Command::CA_Hide); + runCMakeActionContextMenu.setContainer(PEC::M_PROJECTCONTEXT, PEC::G_PROJECT_BUILD); + runCMakeActionContextMenu.setOnTriggered(this, [this] { runCMake(ProjectTree::currentBuildSystem()); }); - m_buildFileContextMenu = new QAction(Tr::tr("Build"), this); - command = Core::ActionManager::registerAction(m_buildFileContextMenu, - Constants::BUILD_FILE_CONTEXT_MENU, - projectContext); - command->setAttribute(Core::Command::CA_Hide); - mfile->addAction(command, ProjectExplorer::Constants::G_FILE_OTHER); - connect(m_buildFileContextMenu, &QAction::triggered, - this, &CMakeManager::buildFileContextMenu); + ActionBuilder buildFileContextAction(this, Constants::BUILD_FILE_CONTEXT_MENU); + buildFileContextAction.setText(Tr::tr("Build")); + buildFileContextAction.bindContextAction(&m_buildFileContextMenu); + buildFileContextAction.setContext(projectContext); + buildFileContextAction.setCommandAttribute(Command::CA_Hide); + buildFileContextAction.setContainer(PEC::M_FILECONTEXT, PEC::G_FILE_OTHER); + buildFileContextAction.setOnTriggered(this, [this] { buildFileContextMenu(); }); - command = Core::ActionManager::registerAction(m_rescanProjectAction, - Constants::RESCAN_PROJECT, - globalContext); - command->setAttribute(Core::Command::CA_Hide); - mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_BUILD); - connect(m_rescanProjectAction, &QAction::triggered, this, [this] { + ActionBuilder rescanProjectAction(this, Constants::RESCAN_PROJECT); + rescanProjectAction.setText(Tr::tr("Rescan Project")); + rescanProjectAction.bindContextAction(&m_rescanProjectAction); + rescanProjectAction.setCommandAttribute(Command::CA_Hide); + rescanProjectAction.setContainer(PEC::M_BUILDPROJECT, PEC::G_BUILD_BUILD); + rescanProjectAction.setOnTriggered(this, [this] { rescanProject(ProjectTree::currentBuildSystem()); }); - command = Core::ActionManager::registerAction(m_reloadCMakePresetsAction, - Constants::RELOAD_CMAKE_PRESETS, - globalContext); - command->setAttribute(Core::Command::CA_Hide); - mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_BUILD); - connect(m_reloadCMakePresetsAction, &QAction::triggered, this, [this] { - reloadCMakePresets(); - }); + ActionBuilder reloadCMakePresetsAction(this, Constants::RELOAD_CMAKE_PRESETS); + reloadCMakePresetsAction.setText(Tr::tr("Reload CMake Presets")); + reloadCMakePresetsAction.setIcon(Utils::Icons::RELOAD.icon()); + reloadCMakePresetsAction.bindContextAction(&m_reloadCMakePresetsAction); + reloadCMakePresetsAction.setCommandAttribute(Command::CA_Hide); + reloadCMakePresetsAction.setContainer(PEC::M_BUILDPROJECT, PEC::G_BUILD_BUILD); + reloadCMakePresetsAction.setOnTriggered(this, [this] { reloadCMakePresets(); }); m_buildFileAction = new Utils::ParameterAction(Tr::tr("Build File"), Tr::tr("Build File \"%1\""), Utils::ParameterAction::AlwaysEnabled, this); - command = Core::ActionManager::registerAction(m_buildFileAction, Constants::BUILD_FILE); - command->setAttribute(Core::Command::CA_Hide); - command->setAttribute(Core::Command::CA_UpdateText); + Command *command = ActionManager::registerAction(m_buildFileAction, Constants::BUILD_FILE); + command->setAttribute(Command::CA_Hide); + command->setAttribute(Command::CA_UpdateText); command->setDescription(m_buildFileAction->text()); command->setDefaultKeySequence(QKeySequence(Tr::tr("Ctrl+Alt+B"))); - mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_BUILD); + ActionContainer *mbuild = ActionManager::actionContainer(PEC::M_BUILDPROJECT); + mbuild->addAction(command, PEC::G_BUILD_BUILD); connect(m_buildFileAction, &QAction::triggered, this, [this] { buildFile(); }); // CMake Profiler - command = Core::ActionManager::registerAction(m_cmakeProfilerAction, - Constants::RUN_CMAKE_PROFILER, - globalContext); - command->setDescription(m_cmakeProfilerAction->text()); - if (manalyzer) - manalyzer->addAction(command, Debugger::Constants::G_ANALYZER_TOOLS); - connect(m_cmakeProfilerAction, &QAction::triggered, this, [this] { + ActionBuilder cmakeProfilerAction(this, Constants::RUN_CMAKE_PROFILER); + cmakeProfilerAction.setIcon(ProjectExplorer::Icons::CMAKE_LOGO.icon()); + cmakeProfilerAction.setText(Tr::tr("CMake Profiler")); + cmakeProfilerAction.bindContextAction(&m_cmakeProfilerAction); + cmakeProfilerAction.setCommandDescription(m_cmakeProfilerAction->text()); + cmakeProfilerAction.setContainer(Debugger::Constants::M_DEBUG_ANALYZER, + Debugger::Constants::G_ANALYZER_TOOLS, + false); + cmakeProfilerAction.setOnTriggered(this, [this] { runCMakeWithProfiling(ProjectManager::startupBuildSystem()); }); // CMake Debugger + ActionContainer *mdebugger = ActionManager::actionContainer(PEC::M_DEBUG_STARTDEBUGGING); mdebugger->appendGroup(Constants::CMAKE_DEBUGGING_GROUP); - mdebugger->addSeparator(Core::Context(Core::Constants::C_GLOBAL), + mdebugger->addSeparator(Context(Core::Constants::C_GLOBAL), Constants::CMAKE_DEBUGGING_GROUP, &m_cmakeDebuggerSeparator); - command = Core::ActionManager::registerAction(m_cmakeDebuggerAction, - Constants::RUN_CMAKE_DEBUGGER, - globalContext); - command->setDescription(m_cmakeDebuggerAction->text()); - mdebugger->addAction(command, Constants::CMAKE_DEBUGGING_GROUP); - connect(m_cmakeDebuggerAction, &QAction::triggered, this, [] { - ProjectExplorerPlugin::runStartupProject(ProjectExplorer::Constants::DAP_CMAKE_DEBUG_RUN_MODE, - false); + ActionBuilder cmakeDebuggerAction(this, Constants::RUN_CMAKE_DEBUGGER); + cmakeDebuggerAction.setText(Tr::tr("Start CMake Debugging")); + cmakeDebuggerAction.setIcon(ProjectExplorer::Icons::CMAKE_LOGO.icon()); + cmakeDebuggerAction.bindContextAction(&m_cmakeDebuggerAction); + cmakeDebuggerAction.setCommandDescription(m_cmakeDebuggerAction->text()); + cmakeDebuggerAction.setContainer(PEC::M_DEBUG_STARTDEBUGGING, Constants::CMAKE_DEBUGGING_GROUP); + cmakeDebuggerAction.setOnTriggered(this, [] { + ProjectExplorerPlugin::runStartupProject(PEC::DAP_CMAKE_DEBUG_RUN_MODE, false); }); connect(ProjectManager::instance(), &ProjectManager::startupProjectChanged, this, [this] { @@ -188,7 +166,7 @@ CMakeManager::CMakeManager() connect(BuildManager::instance(), &BuildManager::buildStateChanged, this, [this] { updateCmakeActions(ProjectTree::currentNode()); }); - connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged, + connect(EditorManager::instance(), &EditorManager::currentEditorChanged, this, &CMakeManager::updateBuildFileAction); connect(ProjectTree::instance(), &ProjectTree::currentNodeChanged, this, &CMakeManager::updateCmakeActions); diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index d0d97f22b28..1ba658837d7 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -130,12 +130,14 @@ void ActionBuilder::setCommandDescription(const QString &desc) d->command->setDescription(desc); } -void ActionBuilder::setContainer(Id containerId, Id groupId) +void ActionBuilder::setContainer(Id containerId, Id groupId, bool needsToExist) { QTC_ASSERT(containerId.isValid(), return); - ActionContainer *container = ActionManager::actionContainer(containerId); - QTC_ASSERT(container, return); - container->addAction(d->command, groupId); + if (ActionContainer *container = ActionManager::actionContainer(containerId)) { + container->addAction(d->command, groupId); + return; + } + QTC_CHECK(!needsToExist); } void ActionBuilder::setOnTriggered(const std::function &func) diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.h b/src/plugins/coreplugin/actionmanager/actionmanager.h index aba964a3746..3e869c064da 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager.h @@ -42,7 +42,7 @@ public: void setToolTip(const QString &toolTip); void setCommandAttribute(Core::Command::CommandAttribute attr); void setCommandDescription(const QString &desc); - void setContainer(Utils::Id containerId, Utils::Id groupId = {}); + void setContainer(Utils::Id containerId, Utils::Id groupId = {}, bool needsToExist = true); void setOnTriggered(const std::function &func); void setOnTriggered(QObject *guard, const std::function &func); void setOnTriggered(QObject *guard, const std::function &func); From 0269626a17baa00e7fd949ab8ca697ea47029175 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 14 Nov 2023 11:15:21 +0100 Subject: [PATCH 0184/1546] Make LineColumnButton re-usable Change-Id: I34e755018eef41e7e7cf254ccba72a1ec5a1c5ff Reviewed-by: David Schulz --- src/plugins/texteditor/texteditor.cpp | 174 +++++++++++++------------- src/plugins/texteditor/texteditor.h | 17 +++ 2 files changed, 106 insertions(+), 85 deletions(-) diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index d4820b16665..bb86f7d0290 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -148,114 +148,118 @@ using ListTransformationMethod = void(QStringList &); static constexpr char dropProperty[] = "dropProp"; -class LineColumnButton : public QToolButton +class LineColumnButtonPrivate { - Q_OBJECT public: - LineColumnButton(TextEditorWidget *parent) - : QToolButton(parent) - , m_editor(parent) - { - connect(m_editor, &QPlainTextEdit::cursorPositionChanged, this, &LineColumnButton::update); - connect(this, &QToolButton::pressed, ActionManager::instance(), [this] { - emit m_editor->activateEditor(EditorManager::IgnoreNavigationHistory); - QMetaObject::invokeMethod(ActionManager::instance(), [] { + QSize m_maxSize; + TextEditorWidget *m_editor; +}; + +} // namespace Internal + +LineColumnButton::LineColumnButton(TextEditorWidget *parent) + : QToolButton(parent) + , m_d(new LineColumnButtonPrivate) +{ + m_d->m_editor = parent; + connect(m_d->m_editor, &QPlainTextEdit::cursorPositionChanged, this, &LineColumnButton::update); + connect(this, &QToolButton::clicked, ActionManager::instance(), [this] { + emit m_d->m_editor->activateEditor(EditorManager::IgnoreNavigationHistory); + QMetaObject::invokeMethod( + ActionManager::instance(), + [] { if (Command *cmd = ActionManager::command(Core::Constants::GOTO)) { if (QAction *act = cmd->action()) act->trigger(); } - }, Qt::QueuedConnection); - }); + }, + Qt::QueuedConnection); + }); +} + +LineColumnButton::~LineColumnButton() = default; + +void LineColumnButton::update() +{ + const Utils::MultiTextCursor &cursors = m_d->m_editor->multiTextCursor(); + QString text; + if (cursors.hasMultipleCursors()) { + text = Tr::tr("Cursors: %2").arg(cursors.cursorCount()); + } else { + const QTextCursor cursor = cursors.mainCursor(); + const QTextBlock block = cursor.block(); + const int line = block.blockNumber() + 1; + const TabSettings &tabSettings = m_d->m_editor->textDocument()->tabSettings(); + const int column = tabSettings.columnAt(block.text(), cursor.positionInBlock()) + 1; + text = Tr::tr("Line: %1, Col: %2").arg(line).arg(column); + const QString toolTipText = Tr::tr("Cursor position: %1"); + setToolTip(toolTipText.arg(cursor.position())); } + int selection = 0; + for (const QTextCursor &cursor : cursors) + selection += cursor.selectionEnd() - cursor.selectionStart(); + if (selection > 0) + text += " " + Tr::tr("(Sel: %1)").arg(selection); + setText(text); +} -private: - void update() - { - const Utils::MultiTextCursor &cursors = m_editor->multiTextCursor(); - QString text; - if (cursors.hasMultipleCursors()) { - text = Tr::tr("Cursors: %2").arg(cursors.cursorCount()); - } else { - const QTextCursor cursor = cursors.mainCursor(); - const QTextBlock block = cursor.block(); - const int line = block.blockNumber() + 1; - const TabSettings &tabSettings = m_editor->textDocument()->tabSettings(); - const int column = tabSettings.columnAt(block.text(), cursor.positionInBlock()) + 1; - text = Tr::tr("Line: %1, Col: %2").arg(line).arg(column); - const QString toolTipText = Tr::tr("Cursor position: %1"); - setToolTip(toolTipText.arg(cursor.position())); - } - int selection = 0; - for (const QTextCursor &cursor : cursors) - selection += cursor.selectionEnd() - cursor.selectionStart(); - if (selection > 0) - text += " " + Tr::tr("(Sel: %1)").arg(selection); - setText(text); - } +bool LineColumnButton::event(QEvent *event) +{ + if (event->type() != QEvent::ToolTip) + return QToolButton::event(event); - bool event(QEvent *event) override - { - if (event->type() != QEvent::ToolTip) - return QToolButton::event(event); + QString tooltipText = "\n"; - QString tooltipText = "
\n"; + const MultiTextCursor multiCursor = m_d->m_editor->multiTextCursor(); + const QList cursors = multiCursor.cursors().mid(0, 15); - const MultiTextCursor multiCursor = m_editor->multiTextCursor(); - const QList cursors = multiCursor.cursors().mid(0, 15); + tooltipText += ""; + tooltipText += QString("").arg(Tr::tr("Cursors:")); + tooltipText += QString("").arg(multiCursor.cursorCount()); + tooltipText += "\n"; + auto addRow = [&](const QString header, auto cellText) { tooltipText += ""; - tooltipText += QString("").arg(Tr::tr("Cursors:")); - tooltipText += QString("").arg(multiCursor.cursorCount()); + tooltipText += QString("").arg(header); + for (const QTextCursor &c : cursors) + tooltipText += QString("").arg(cellText(c)); + if (multiCursor.cursorCount() > cursors.count()) + tooltipText += QString(""); tooltipText += "\n"; + }; - auto addRow = [&](const QString header, auto cellText) { - tooltipText += ""; - tooltipText += QString("").arg(header); - for (const QTextCursor &c : cursors) - tooltipText += QString("").arg(cellText(c)); - if (multiCursor.cursorCount() > cursors.count()) - tooltipText += QString(""); - tooltipText += "\n"; - }; + addRow(Tr::tr("Line:"), [](const QTextCursor &c) { return c.blockNumber() + 1; }); - addRow(Tr::tr("Line:"), [](const QTextCursor &c) { return c.blockNumber() + 1; }); + const TabSettings &tabSettings = m_d->m_editor->textDocument()->tabSettings(); + addRow(Tr::tr("Column:"), [&](const QTextCursor &c) { + return tabSettings.columnAt(c.block().text(), c.positionInBlock()) + 1; + }); - const TabSettings &tabSettings = m_editor->textDocument()->tabSettings(); - addRow(Tr::tr("Column:"), [&](const QTextCursor &c) { - return tabSettings.columnAt(c.block().text(), c.positionInBlock()) + 1; - }); + addRow(Tr::tr("Selection length:"), + [](const QTextCursor &c) { return c.selectionEnd() - c.selectionStart(); }); - addRow(Tr::tr("Selection length:"), - [](const QTextCursor &c) { return c.selectionEnd() - c.selectionStart(); }); + addRow(Tr::tr("Position in document:"), [](const QTextCursor &c) { return c.position(); }); - addRow(Tr::tr("Position in document:"), [](const QTextCursor &c) { return c.position(); }); + addRow(Tr::tr("Anchor:"), [](const QTextCursor &c) { return c.anchor(); }); - addRow(Tr::tr("Anchor:"), [](const QTextCursor &c) { return c.anchor(); }); + tooltipText += "
%1%1
%1%1%1%1...
%1%1...
\n"; - tooltipText += "\n"; + ToolTip::show(static_cast(event)->globalPos(), tooltipText, Qt::RichText); + event->accept(); + return true; +} - ToolTip::show(static_cast(event)->globalPos(), - tooltipText, - Qt::RichText); - event->accept(); - return true; - } +QSize LineColumnButton::sizeHint() const +{ + const QSize size = QToolButton::sizeHint(); + auto wider = [](const QSize &left, const QSize &right) { return left.width() < right.width(); }; + if (m_d->m_editor->multiTextCursor().hasSelection()) + return std::max(m_d->m_maxSize, size, wider); // do not save the size if we have a selection + m_d->m_maxSize = std::max(m_d->m_maxSize, size, wider); + return m_d->m_maxSize; +} - QSize sizeHint() const override - { - const QSize size = QToolButton::sizeHint(); - auto wider = [](const QSize &left, const QSize &right) { - return left.width() < right.width(); - }; - if (m_editor->multiTextCursor().hasSelection()) - return std::max(m_maxSize, size, wider); // do not save the size if we have a selection - m_maxSize = std::max(m_maxSize, size, wider); - return m_maxSize; - } - - mutable QSize m_maxSize; - TextEditorWidget *m_editor; -}; +namespace Internal { class TextEditorAnimator : public QObject { diff --git a/src/plugins/texteditor/texteditor.h b/src/plugins/texteditor/texteditor.h index 36de773977d..4807d4cdfbf 100644 --- a/src/plugins/texteditor/texteditor.h +++ b/src/plugins/texteditor/texteditor.h @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -56,6 +57,7 @@ using TextMarks = QList; namespace Internal { class BaseTextEditorPrivate; +class LineColumnButtonPrivate; class TextEditorFactoryPrivate; class TextEditorWidgetPrivate; class TextEditorOverlay; @@ -699,6 +701,21 @@ private: Internal::TextEditorFactoryPrivate *d; }; +class TEXTEDITOR_EXPORT LineColumnButton : public QToolButton +{ +public: + LineColumnButton(TextEditorWidget *parent); + ~LineColumnButton(); + +private: + void update(); + bool event(QEvent *event) override; + QSize sizeHint() const override; + +private: + std::unique_ptr m_d; +}; + } // namespace TextEditor QT_BEGIN_NAMESPACE From 3ae0185817477037d830dae2046ede8ce7b9683b Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 7 Nov 2023 12:44:11 +0100 Subject: [PATCH 0185/1546] TaskTree: Split completely const and runtime trees Separate completely const tree (data taken from recipe) from runtime tree. Build runtime tree incrementally, on demand. The const tree is created on TaskTree::setRecipe() and the runtime tree is created on TaskTree::start(). The const tree serves as a kind of template for creating the runtime task tree later, dynamically. Prepare for the implementation of the loop functionality (3rd point on the master task below). Task-number: QTCREATORBUG-28741 Change-Id: I80382e5ef43d53b36ca3c70472b193c5949f5ab9 Reviewed-by: Qt CI Bot Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 537 +++++++++++++----------- src/libs/solutions/tasking/tasktree.h | 21 +- 2 files changed, 294 insertions(+), 264 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index b9355d07b18..fd13268c2df 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -3,6 +3,7 @@ #include "tasktree.h" +#include #include #include #include @@ -1053,6 +1054,22 @@ GroupItem GroupItem::withTimeout(const GroupItem &item, milliseconds timeout, class TaskTreePrivate; class TaskNode; +class TaskRuntimeNode; +class TaskRuntimeContainer; + +class ExecutionContextActivator +{ +public: + ExecutionContextActivator(TaskRuntimeContainer *container) { activateContext(container); } + ~ExecutionContextActivator() { + for (int i = m_activeStorages.size() - 1; i >= 0; --i) // iterate in reverse order + m_activeStorages[i].m_storageData->threadData().activateStorage(0); + } + +private: + void activateContext(TaskRuntimeContainer *container); + QList m_activeStorages; +}; class TaskTreePrivate { @@ -1075,10 +1092,10 @@ public: callStorageHandler(storage, storageId, &StorageHandler::m_doneHandler); } struct StorageHandler { - TaskTree::StorageVoidHandler m_setupHandler = {}; - TaskTree::StorageVoidHandler m_doneHandler = {}; + TreeStorageBase::StorageVoidHandler m_setupHandler = {}; + TreeStorageBase::StorageVoidHandler m_doneHandler = {}; }; - typedef TaskTree::StorageVoidHandler StorageHandler::*HandlerPtr; // ptr to class member + typedef TreeStorageBase::StorageVoidHandler StorageHandler::*HandlerPtr; // ptr to class member void callStorageHandler(TreeStorageBase storage, int storageId, HandlerPtr ptr) { const auto it = m_storageHandlers.constFind(storage); @@ -1095,98 +1112,176 @@ public: threadData.activateStorage(0); } + // Node related methods + + // If returned value != Continue, childDone() needs to be called in parent container (in caller) + // in order to unwind properly. + SetupResult start(TaskRuntimeNode *node); + void stop(TaskRuntimeNode *node); + bool invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith); + + // Container related methods + + SetupResult start(TaskRuntimeContainer *container); + SetupResult continueStart(TaskRuntimeContainer *container, SetupResult startAction, int nextChild); + SetupResult startChildren(TaskRuntimeContainer *container, int nextChild); + SetupResult childDone(TaskRuntimeContainer *container, bool success); + void stop(TaskRuntimeContainer *container); + bool invokeDoneHandler(TaskRuntimeContainer *container, DoneWith doneWith); + + template > + ReturnType invokeHandler(TaskRuntimeContainer *container, Handler &&handler, Args &&...args) + { + ExecutionContextActivator activator(container); + GuardLocker locker(m_guard); + return std::invoke(std::forward(handler), std::forward(args)...); + } + TaskTree *q = nullptr; Guard m_guard; int m_progressValue = 0; QSet m_storages; QHash m_storageHandlers; std::unique_ptr m_root = nullptr; // Keep me last in order to destruct first + std::unique_ptr m_runtimeRoot = nullptr; }; class TaskContainer { - Q_DISABLE_COPY_MOVE(TaskContainer) + Q_DISABLE_COPY(TaskContainer) public: + TaskContainer(TaskContainer &&other) = default; TaskContainer(TaskTreePrivate *taskTreePrivate, const GroupItem &task, - TaskNode *parentNode, TaskContainer *parentContainer) - : m_constData(taskTreePrivate, task, parentNode, parentContainer, this) {} - SetupResult start(); - SetupResult continueStart(SetupResult startAction, int nextChild); - SetupResult startChildren(int nextChild); - SetupResult childDone(bool success); - void stop(); - bool invokeDoneHandler(DoneWith doneWith); - bool isRunning() const { return m_runtimeData.has_value(); } - bool isStarting() const { return isRunning() && m_runtimeData->m_startGuard.isLocked(); } + TaskNode *parentNode, TaskContainer *parentContainer); - struct ConstData { - ConstData(TaskTreePrivate *taskTreePrivate, const GroupItem &task, TaskNode *parentNode, - TaskContainer *parentContainer, TaskContainer *thisContainer); - ~ConstData() { qDeleteAll(m_children); } - TaskTreePrivate * const m_taskTreePrivate = nullptr; - TaskNode * const m_parentNode = nullptr; - TaskContainer * const m_parentContainer = nullptr; + TaskTreePrivate *const m_taskTreePrivate = nullptr; + TaskNode *const m_parentNode = nullptr; + TaskContainer *const m_parentContainer = nullptr; - const int m_parallelLimit = 1; - const WorkflowPolicy m_workflowPolicy = WorkflowPolicy::StopOnError; - const GroupItem::GroupHandler m_groupHandler; - const QList m_storageList; - const QList m_children; - const int m_taskCount = 0; - }; - - struct RuntimeData { - RuntimeData(const ConstData &constData); - ~RuntimeData(); - - static QList createStorages(const TaskContainer::ConstData &constData); - bool updateSuccessBit(bool success); - int currentLimit() const; - - const ConstData &m_constData; - const QList m_storageIdList; - bool m_successBit = true; - bool m_callStorageDoneHandlersOnDestruction = false; - int m_doneCount = 0; - Guard m_startGuard; - }; - - const ConstData m_constData; - std::optional m_runtimeData; + const int m_parallelLimit = 1; + const WorkflowPolicy m_workflowPolicy = WorkflowPolicy::StopOnError; + const GroupItem::GroupHandler m_groupHandler; + const QList m_storageList; + std::vector m_children; + const int m_taskCount = 0; }; class TaskNode { - Q_DISABLE_COPY_MOVE(TaskNode) + Q_DISABLE_COPY(TaskNode) public: + TaskNode(TaskNode &&other) = default; TaskNode(TaskTreePrivate *taskTreePrivate, const GroupItem &task, TaskContainer *parentContainer) : m_taskHandler(task.m_taskHandler) , m_container(taskTreePrivate, task, this, parentContainer) {} - // If returned value != Continue, childDone() needs to be called in parent container (in caller) - // in order to unwind properly. - SetupResult start(); - void stop(); - bool invokeDoneHandler(DoneWith doneWith); - bool isRunning() const { return m_task || m_container.isRunning(); } bool isTask() const { return bool(m_taskHandler.m_createHandler); } - int taskCount() const { return isTask() ? 1 : m_container.m_constData.m_taskCount; } - TaskContainer *parentContainer() const { return m_container.m_constData.m_parentContainer; } - TaskTree *taskTree() const { return m_container.m_constData.m_taskTreePrivate->q; } + int taskCount() const { return isTask() ? 1 : m_container.m_taskCount; } + TaskContainer *parentContainer() const { return m_container.m_parentContainer; } -private: const GroupItem::TaskHandler m_taskHandler; TaskContainer m_container; - std::unique_ptr m_task; }; +static bool initialSuccessBit(WorkflowPolicy workflowPolicy) +{ + switch (workflowPolicy) { + case WorkflowPolicy::StopOnError: + case WorkflowPolicy::ContinueOnError: + case WorkflowPolicy::FinishAllAndSuccess: + return true; + case WorkflowPolicy::StopOnSuccess: + case WorkflowPolicy::ContinueOnSuccess: + case WorkflowPolicy::StopOnSuccessOrError: + case WorkflowPolicy::FinishAllAndError: + return false; + } + QT_CHECK(false); + return false; +} + +class TaskRuntimeContainer +{ +public: + TaskRuntimeContainer(const TaskContainer &taskContainer, TaskRuntimeNode *parentNode, + TaskRuntimeContainer *parentContainer) + : m_taskContainer(taskContainer) + , m_parentNode(parentNode) + , m_parentContainer(parentContainer) + , m_storageIdList(createStorages(taskContainer)) + , m_successBit(initialSuccessBit(taskContainer.m_workflowPolicy)) + {} + + ~TaskRuntimeContainer() + { + for (int i = m_taskContainer.m_storageList.size() - 1; i >= 0; --i) { // iterate in reverse order + const TreeStorageBase storage = m_taskContainer.m_storageList[i]; + const int storageId = m_storageIdList.value(i); + if (m_callStorageDoneHandlersOnDestruction) + m_taskContainer.m_taskTreePrivate->callDoneHandler(storage, storageId); + storage.m_storageData->deleteStorage(storageId); + } + qDeleteAll(m_children); + } + + + static QList createStorages(const TaskContainer &container); + bool isStarting() const { return m_startGuard.isLocked(); } + bool updateSuccessBit(bool success); + int currentLimit() const; + + const TaskContainer &m_taskContainer; // Not owning. + TaskRuntimeNode *m_parentNode = nullptr; // Not owning. + TaskRuntimeContainer *m_parentContainer = nullptr; // Not owning. + const QList m_storageIdList; + + QList m_children; // Owning. + bool m_successBit = true; + bool m_callStorageDoneHandlersOnDestruction = false; + int m_doneCount = 0; + Guard m_startGuard; +}; + +class TaskRuntimeNode +{ +public: + TaskRuntimeNode(const TaskNode &taskNode, TaskRuntimeContainer *parentContainer) + : m_taskNode(taskNode) + , m_parentContainer(parentContainer) + {} + + const TaskNode &m_taskNode; // Not owning. + TaskRuntimeContainer *m_parentContainer = nullptr; // Not owning. + std::unique_ptr m_container; // Owning. + std::unique_ptr m_task; // Owning. +}; + +void ExecutionContextActivator::activateContext(TaskRuntimeContainer *container) +{ + const TaskContainer &taskContainer = container->m_taskContainer; + for (int i = 0; i < taskContainer.m_storageList.size(); ++i) { + const TreeStorageBase &storage = taskContainer.m_storageList[i]; + auto &threadData = storage.m_storageData->threadData(); + if (threadData.activeStorageId()) + continue; // Storage shadowing: The storage is already active, skipping it... + m_activeStorages.append(storage); + threadData.activateStorage(container->m_storageIdList.value(i)); + } + // Go to the parent after activating this storages so that storage shadowing works + // in the direction from child to parent root. + if (container->m_parentContainer) + activateContext(container->m_parentContainer); +} + void TaskTreePrivate::start() { QT_ASSERT(m_root, return); + QT_ASSERT(!m_runtimeRoot, return); m_progressValue = 0; emitStartedAndProgress(); // TODO: check storage handlers for not existing storages in tree @@ -1194,15 +1289,16 @@ void TaskTreePrivate::start() QT_ASSERT(m_storages.contains(it.key()), qWarning("The registered storage doesn't " "exist in task tree. Its handlers will never be called.")); } - m_root->start(); + m_runtimeRoot.reset(new TaskRuntimeNode(*m_root.get(), nullptr)); + start(m_runtimeRoot.get()); } void TaskTreePrivate::stop() { QT_ASSERT(m_root, return); - if (!m_root->isRunning()) + if (!m_runtimeRoot) return; - m_root->stop(); + stop(m_runtimeRoot.get()); emitDone(DoneWith::Cancel); } @@ -1236,57 +1332,18 @@ void TaskTreePrivate::emitDone(DoneWith result) emit q->done(result); } -class ExecutionContextActivator +static std::vector createChildren(TaskTreePrivate *taskTreePrivate, TaskContainer *container, + const QList &children) { -public: - ExecutionContextActivator(TaskContainer *container) { activateContext(container); } - ~ExecutionContextActivator() { - for (int i = m_activeStorages.size() - 1; i >= 0; --i) // iterate in reverse order - m_activeStorages[i].m_storageData->threadData().activateStorage(0); - } - -private: - void activateContext(TaskContainer *container) - { - QT_ASSERT(container && container->isRunning(), return); - const TaskContainer::ConstData &constData = container->m_constData; - for (int i = 0; i < constData.m_storageList.size(); ++i) { - const TreeStorageBase &storage = constData.m_storageList[i]; - auto &threadData = storage.m_storageData->threadData(); - if (threadData.activeStorageId()) - continue; // Storage shadowing: The storage is already active, skipping it... - m_activeStorages.append(storage); - threadData.activateStorage(container->m_runtimeData->m_storageIdList.value(i)); - } - // Go to the parent after activating this storages so that storage shadowing works - // in the direction from child to parent root. - if (constData.m_parentContainer) - activateContext(constData.m_parentContainer); - } - QList m_activeStorages; -}; - -template > -ReturnType invokeHandler(TaskContainer *container, Handler &&handler, Args &&...args) -{ - ExecutionContextActivator activator(container); - GuardLocker locker(container->m_constData.m_taskTreePrivate->m_guard); - return std::invoke(std::forward(handler), std::forward(args)...); -} - -static QList createChildren(TaskTreePrivate *taskTreePrivate, TaskContainer *container, - const QList &children) -{ - QList result; + std::vector result; + result.reserve(children.size()); for (const GroupItem &child : children) - result.append(new TaskNode(taskTreePrivate, child, container)); + result.emplace_back(taskTreePrivate, child, container); return result; } -TaskContainer::ConstData::ConstData(TaskTreePrivate *taskTreePrivate, const GroupItem &task, - TaskNode *parentNode, TaskContainer *parentContainer, - TaskContainer *thisContainer) +TaskContainer::TaskContainer(TaskTreePrivate *taskTreePrivate, const GroupItem &task, + TaskNode *parentNode, TaskContainer *parentContainer) : m_taskTreePrivate(taskTreePrivate) , m_parentNode(parentNode) , m_parentContainer(parentContainer) @@ -1294,184 +1351,157 @@ TaskContainer::ConstData::ConstData(TaskTreePrivate *taskTreePrivate, const Grou , m_workflowPolicy(task.m_groupData.m_workflowPolicy.value_or(WorkflowPolicy::StopOnError)) , m_groupHandler(task.m_groupData.m_groupHandler) , m_storageList(task.m_storageList) - , m_children(createChildren(taskTreePrivate, thisContainer, task.m_children)) + , m_children(createChildren(taskTreePrivate, this, task.m_children)) , m_taskCount(std::accumulate(m_children.cbegin(), m_children.cend(), 0, - [](int r, TaskNode *n) { return r + n->taskCount(); })) + [](int r, const TaskNode &n) { return r + n.taskCount(); })) { for (const TreeStorageBase &storage : m_storageList) m_taskTreePrivate->m_storages << storage; } -QList TaskContainer::RuntimeData::createStorages(const TaskContainer::ConstData &constData) +QList TaskRuntimeContainer::createStorages(const TaskContainer &container) { QList storageIdList; - for (const TreeStorageBase &storage : constData.m_storageList) { + for (const TreeStorageBase &storage : container.m_storageList) { const int storageId = storage.m_storageData->threadData().createStorage(); storageIdList.append(storageId); - constData.m_taskTreePrivate->callSetupHandler(storage, storageId); + container.m_taskTreePrivate->callSetupHandler(storage, storageId); } return storageIdList; } -static bool initialSuccessBit(WorkflowPolicy workflowPolicy) +bool TaskRuntimeContainer::updateSuccessBit(bool success) { - switch (workflowPolicy) { - case WorkflowPolicy::StopOnError: - case WorkflowPolicy::ContinueOnError: - case WorkflowPolicy::FinishAllAndSuccess: - return true; - case WorkflowPolicy::StopOnSuccess: - case WorkflowPolicy::ContinueOnSuccess: - case WorkflowPolicy::StopOnSuccessOrError: - case WorkflowPolicy::FinishAllAndError: - return false; - } - QT_CHECK(false); - return false; -} - -TaskContainer::RuntimeData::RuntimeData(const ConstData &constData) - : m_constData(constData) - , m_storageIdList(createStorages(constData)) - , m_successBit(initialSuccessBit(m_constData.m_workflowPolicy)) -{} - -TaskContainer::RuntimeData::~RuntimeData() -{ - for (int i = m_constData.m_storageList.size() - 1; i >= 0; --i) { // iterate in reverse order - const TreeStorageBase storage = m_constData.m_storageList[i]; - const int storageId = m_storageIdList.value(i); - if (m_callStorageDoneHandlersOnDestruction) - m_constData.m_taskTreePrivate->callDoneHandler(storage, storageId); - storage.m_storageData->deleteStorage(storageId); - } -} - -bool TaskContainer::RuntimeData::updateSuccessBit(bool success) -{ - if (m_constData.m_workflowPolicy == WorkflowPolicy::FinishAllAndSuccess - || m_constData.m_workflowPolicy == WorkflowPolicy::FinishAllAndError - || m_constData.m_workflowPolicy == WorkflowPolicy::StopOnSuccessOrError) { - if (m_constData.m_workflowPolicy == WorkflowPolicy::StopOnSuccessOrError) + if (m_taskContainer.m_workflowPolicy == WorkflowPolicy::FinishAllAndSuccess + || m_taskContainer.m_workflowPolicy == WorkflowPolicy::FinishAllAndError + || m_taskContainer.m_workflowPolicy == WorkflowPolicy::StopOnSuccessOrError) { + if (m_taskContainer.m_workflowPolicy == WorkflowPolicy::StopOnSuccessOrError) m_successBit = success; return m_successBit; } - const bool donePolicy = m_constData.m_workflowPolicy == WorkflowPolicy::StopOnSuccess - || m_constData.m_workflowPolicy == WorkflowPolicy::ContinueOnSuccess; + const bool donePolicy = m_taskContainer.m_workflowPolicy == WorkflowPolicy::StopOnSuccess + || m_taskContainer.m_workflowPolicy == WorkflowPolicy::ContinueOnSuccess; m_successBit = donePolicy ? (m_successBit || success) : (m_successBit && success); return m_successBit; } -int TaskContainer::RuntimeData::currentLimit() const +int TaskRuntimeContainer::currentLimit() const { - const int childCount = m_constData.m_children.size(); - return m_constData.m_parallelLimit - ? qMin(m_doneCount + m_constData.m_parallelLimit, childCount) : childCount; + // TODO: Handle children well + const int childCount = m_taskContainer.m_children.size(); + return m_taskContainer.m_parallelLimit + ? qMin(m_doneCount + m_taskContainer.m_parallelLimit, childCount) : childCount; } -SetupResult TaskContainer::start() +SetupResult TaskTreePrivate::start(TaskRuntimeContainer *container) { - QT_CHECK(!isRunning()); - m_runtimeData.emplace(m_constData); - SetupResult startAction = SetupResult::Continue; - if (m_constData.m_groupHandler.m_setupHandler) { - startAction = invokeHandler(this, m_constData.m_groupHandler.m_setupHandler); + if (container->m_taskContainer.m_groupHandler.m_setupHandler) { + startAction = invokeHandler(container, container->m_taskContainer.m_groupHandler.m_setupHandler); if (startAction != SetupResult::Continue) { - m_constData.m_taskTreePrivate->advanceProgress(m_constData.m_taskCount); + // TODO: Handle progress well. + advanceProgress(container->m_taskContainer.m_taskCount); // Non-Continue SetupResult takes precedence over the workflow policy. - m_runtimeData->m_successBit = startAction == SetupResult::StopWithSuccess; + container->m_successBit = startAction == SetupResult::StopWithSuccess; } } if (startAction == SetupResult::Continue) { - if (m_constData.m_children.isEmpty()) - startAction = toSetupResult(m_runtimeData->m_successBit); + if (container->m_taskContainer.m_children.empty()) + startAction = toSetupResult(container->m_successBit); + } else { // TODO: Check if repeater exists, call its handler. + } - return continueStart(startAction, 0); + return continueStart(container, startAction, 0); } -SetupResult TaskContainer::continueStart(SetupResult startAction, int nextChild) +SetupResult TaskTreePrivate::continueStart(TaskRuntimeContainer *container, SetupResult startAction, int nextChild) { - const SetupResult groupAction = startAction == SetupResult::Continue ? startChildren(nextChild) - : startAction; - QT_CHECK(isRunning()); // TODO: superfluous + const SetupResult groupAction = startAction == SetupResult::Continue ? startChildren(container, nextChild) + : startAction; if (groupAction != SetupResult::Continue) { - const bool bit = m_runtimeData->updateSuccessBit(groupAction == SetupResult::StopWithSuccess); - const bool result = invokeDoneHandler(bit ? DoneWith::Success : DoneWith::Error); - if (TaskContainer *parentContainer = m_constData.m_parentContainer) { - QT_CHECK(parentContainer->isRunning()); + const bool bit = container->updateSuccessBit(groupAction == SetupResult::StopWithSuccess); + TaskRuntimeContainer *parentContainer = container->m_parentContainer; + const bool result = invokeDoneHandler(container, bit ? DoneWith::Success : DoneWith::Error); + if (parentContainer) { if (!parentContainer->isStarting()) - parentContainer->childDone(result); + childDone(parentContainer, result); } else { - m_constData.m_taskTreePrivate->emitDone(result ? DoneWith::Success : DoneWith::Error); + m_runtimeRoot.reset(); + emitDone(result ? DoneWith::Success : DoneWith::Error); } } return groupAction; } -SetupResult TaskContainer::startChildren(int nextChild) +SetupResult TaskTreePrivate::startChildren(TaskRuntimeContainer *container, int nextChild) { - QT_CHECK(isRunning()); - GuardLocker locker(m_runtimeData->m_startGuard); - for (int i = nextChild; i < m_constData.m_children.size(); ++i) { - const int limit = m_runtimeData->currentLimit(); + GuardLocker locker(container->m_startGuard); + for (int i = nextChild; i < int(container->m_taskContainer.m_children.size()); ++i) { + const int limit = container->currentLimit(); if (i >= limit) break; - const SetupResult startAction = m_constData.m_children.at(i)->start(); + TaskRuntimeNode *newTask = new TaskRuntimeNode(container->m_taskContainer.m_children.at(i), container); + container->m_children.append(newTask); + + const SetupResult startAction = start(newTask); if (startAction == SetupResult::Continue) continue; - const SetupResult finalizeAction = childDone(startAction == SetupResult::StopWithSuccess); + const SetupResult finalizeAction = childDone(container, startAction == SetupResult::StopWithSuccess); if (finalizeAction == SetupResult::Continue) continue; int skippedTaskCount = 0; // Skip scheduled but not run yet. The current (i) was already notified. for (int j = i + 1; j < limit; ++j) - skippedTaskCount += m_constData.m_children.at(j)->taskCount(); - m_constData.m_taskTreePrivate->advanceProgress(skippedTaskCount); + skippedTaskCount += container->m_taskContainer.m_children.at(j).taskCount(); + // TODO: Handle progress well + advanceProgress(skippedTaskCount); return finalizeAction; } return SetupResult::Continue; } -SetupResult TaskContainer::childDone(bool success) +SetupResult TaskTreePrivate::childDone(TaskRuntimeContainer *container, bool success) { - QT_CHECK(isRunning()); - const int limit = m_runtimeData->currentLimit(); // Read before bumping m_doneCount and stop() - const bool shouldStop = m_constData.m_workflowPolicy == WorkflowPolicy::StopOnSuccessOrError - || (m_constData.m_workflowPolicy == WorkflowPolicy::StopOnSuccess && success) - || (m_constData.m_workflowPolicy == WorkflowPolicy::StopOnError && !success); + const int limit = container->currentLimit(); // Read before bumping m_doneCount and stop() + const WorkflowPolicy &workflowPolicy = container->m_taskContainer.m_workflowPolicy; + const bool shouldStop = workflowPolicy == WorkflowPolicy::StopOnSuccessOrError + || (workflowPolicy == WorkflowPolicy::StopOnSuccess && success) + || (workflowPolicy == WorkflowPolicy::StopOnError && !success); if (shouldStop) - stop(); + stop(container); - ++m_runtimeData->m_doneCount; - const bool updatedSuccess = m_runtimeData->updateSuccessBit(success); + ++container->m_doneCount; + const bool updatedSuccess = container->updateSuccessBit(success); const SetupResult startAction - = (shouldStop || m_runtimeData->m_doneCount == m_constData.m_children.size()) + = (shouldStop || container->m_doneCount == int(container->m_taskContainer.m_children.size())) ? toSetupResult(updatedSuccess) : SetupResult::Continue; - if (isStarting()) + if (container->isStarting()) return startAction; - return continueStart(startAction, limit); + return continueStart(container, startAction, limit); } -void TaskContainer::stop() +void TaskTreePrivate::stop(TaskRuntimeContainer *container) { - if (!isRunning()) - return; - - const int limit = m_runtimeData->currentLimit(); - for (int i = 0; i < limit; ++i) - m_constData.m_children.at(i)->stop(); + const int limit = container->currentLimit(); + for (int i = 0; i < limit; ++i) { + if (i == container->m_children.size()) + break; + TaskRuntimeNode *child = container->m_children.at(i); + if (child) + stop(child); + } int skippedTaskCount = 0; - for (int i = limit; i < m_constData.m_children.size(); ++i) - skippedTaskCount += m_constData.m_children.at(i)->taskCount(); + for (int i = limit; i < int(container->m_taskContainer.m_children.size()); ++i) + skippedTaskCount += container->m_taskContainer.m_children.at(i).taskCount(); - m_constData.m_taskTreePrivate->advanceProgress(skippedTaskCount); + // TODO: Handle progress well + advanceProgress(skippedTaskCount); } static bool shouldCall(CallDoneIf callDoneIf, DoneWith result) @@ -1481,73 +1511,78 @@ static bool shouldCall(CallDoneIf callDoneIf, DoneWith result) return callDoneIf != CallDoneIf::Success; } -bool TaskContainer::invokeDoneHandler(DoneWith doneWith) +bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeContainer *container, DoneWith doneWith) { DoneResult result = toDoneResult(doneWith); - const GroupItem::GroupHandler &groupHandler = m_constData.m_groupHandler; + const GroupItem::GroupHandler &groupHandler = container->m_taskContainer.m_groupHandler; if (groupHandler.m_doneHandler && shouldCall(groupHandler.m_callDoneIf, doneWith)) - result = invokeHandler(this, groupHandler.m_doneHandler, doneWith); - m_runtimeData->m_callStorageDoneHandlersOnDestruction = true; - m_runtimeData.reset(); + result = invokeHandler(container, groupHandler.m_doneHandler, doneWith); + container->m_callStorageDoneHandlersOnDestruction = true; + container->m_parentNode->m_container.reset(); return result == DoneResult::Success; } -SetupResult TaskNode::start() +SetupResult TaskTreePrivate::start(TaskRuntimeNode *node) { - QT_CHECK(!isRunning()); - if (!isTask()) - return m_container.start(); + if (!node->m_taskNode.isTask()) { + node->m_container.reset(new TaskRuntimeContainer(node->m_taskNode.m_container, node, + node->m_parentContainer)); + return start(node->m_container.get()); + } - m_task.reset(m_taskHandler.m_createHandler()); - const SetupResult startAction = m_taskHandler.m_setupHandler - ? invokeHandler(parentContainer(), m_taskHandler.m_setupHandler, *m_task.get()) + const GroupItem::TaskHandler &handler = node->m_taskNode.m_taskHandler; + node->m_task.reset(handler.m_createHandler()); + const SetupResult startAction = handler.m_setupHandler + ? invokeHandler(node->m_parentContainer, handler.m_setupHandler, *node->m_task.get()) : SetupResult::Continue; if (startAction != SetupResult::Continue) { - m_container.m_constData.m_taskTreePrivate->advanceProgress(1); - m_task.reset(); + // TODO: Handle progress well + advanceProgress(1); + node->m_task.reset(); return startAction; } const std::shared_ptr unwindAction = std::make_shared(SetupResult::Continue); - QObject::connect(m_task.get(), &TaskInterface::done, taskTree(), [=](bool success) { - const bool result = invokeDoneHandler(success ? DoneWith::Success : DoneWith::Error); - QObject::disconnect(m_task.get(), &TaskInterface::done, taskTree(), nullptr); - m_task.release()->deleteLater(); - QT_ASSERT(parentContainer() && parentContainer()->isRunning(), return); - if (parentContainer()->isStarting()) + QObject::connect(node->m_task.get(), &TaskInterface::done, + q, [this, node, unwindAction](bool success) { + const bool result = invokeDoneHandler(node, success ? DoneWith::Success : DoneWith::Error); + QObject::disconnect(node->m_task.get(), &TaskInterface::done, q, nullptr); + node->m_task.release()->deleteLater(); // TODO: delete later this??? + if (node->m_parentContainer->isStarting()) *unwindAction = toSetupResult(result); else - parentContainer()->childDone(result); + childDone(node->m_parentContainer, result); }); - m_task->start(); + node->m_task->start(); return *unwindAction; } -void TaskNode::stop() +void TaskTreePrivate::stop(TaskRuntimeNode *node) { - if (!isRunning()) - return; - - if (!m_task) { - m_container.stop(); - m_container.m_runtimeData->updateSuccessBit(false); - m_container.invokeDoneHandler(DoneWith::Cancel); + if (!node->m_task) { + if (!node->m_container) + return; + stop(node->m_container.get()); + node->m_container->updateSuccessBit(false); + invokeDoneHandler(node->m_container.get(), DoneWith::Cancel); return; } - // TODO: cancelHandler? - // TODO: call TaskInterface::stop() ? - invokeDoneHandler(DoneWith::Cancel); - m_task.reset(); + invokeDoneHandler(node, DoneWith::Cancel); + node->m_task.reset(); } -bool TaskNode::invokeDoneHandler(DoneWith doneWith) +bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith) { DoneResult result = toDoneResult(doneWith); - if (m_taskHandler.m_doneHandler && shouldCall(m_taskHandler.m_callDoneIf, doneWith)) - result = invokeHandler(parentContainer(), m_taskHandler.m_doneHandler, *m_task.get(), doneWith); - m_container.m_constData.m_taskTreePrivate->advanceProgress(1); + const GroupItem::TaskHandler &handler = node->m_taskNode.m_taskHandler; + if (handler.m_doneHandler && shouldCall(handler.m_callDoneIf, doneWith)) { + result = invokeHandler(node->m_parentContainer, + handler.m_doneHandler, *node->m_task.get(), doneWith); + } + // TODO: Handle progress well + advanceProgress(1); return result == DoneResult::Success; } @@ -2359,7 +2394,7 @@ void TaskTree::stop() */ bool TaskTree::isRunning() const { - return d->m_root && d->m_root->isRunning(); + return bool(d->m_runtimeRoot); } /*! @@ -2586,8 +2621,8 @@ int TaskTree::progressValue() const */ void TaskTree::setupStorageHandler(const TreeStorageBase &storage, - StorageVoidHandler setupHandler, - StorageVoidHandler doneHandler) + TreeStorageBase::StorageVoidHandler setupHandler, + TreeStorageBase::StorageVoidHandler doneHandler) { auto it = d->m_storageHandlers.find(storage); if (it == d->m_storageHandlers.end()) { diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 77cc318fe36..0be2aa097f4 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -19,9 +19,7 @@ namespace Tasking { Q_NAMESPACE_EXPORT(TASKING_EXPORT) -class ExecutionContextActivator; class StorageData; -class TaskContainer; class TaskTreePrivate; class TASKING_EXPORT TaskInterface : public QObject @@ -33,7 +31,7 @@ signals: private: template friend class TaskAdapter; - friend class TaskNode; + friend class TaskTreePrivate; TaskInterface() = default; #ifdef Q_QDOC protected: @@ -46,6 +44,7 @@ class TASKING_EXPORT TreeStorageBase public: using StorageConstructor = std::function; using StorageDestructor = std::function; + using StorageVoidHandler = std::function; bool isValid() const; @@ -66,9 +65,9 @@ private: QSharedPointer m_storageData; template friend class TreeStorage; - friend ExecutionContextActivator; - friend TaskContainer; - friend TaskTreePrivate; + friend class ExecutionContextActivator; + friend class TaskRuntimeContainer; + friend class TaskTreePrivate; }; template @@ -461,8 +460,6 @@ private: }; }; -class TaskTreePrivate; - class TASKING_EXPORT TaskTree final : public QObject { Q_OBJECT @@ -515,19 +512,17 @@ signals: void progressValueChanged(int value); // updated whenever task finished / skipped / stopped private: - using StorageVoidHandler = std::function; void setupStorageHandler(const TreeStorageBase &storage, - StorageVoidHandler setupHandler, - StorageVoidHandler doneHandler); + TreeStorageBase::StorageVoidHandler setupHandler, + TreeStorageBase::StorageVoidHandler doneHandler); template - StorageVoidHandler wrapHandler(StorageHandler &&handler) { + TreeStorageBase::StorageVoidHandler wrapHandler(StorageHandler &&handler) { return [=](void *voidStruct) { auto *storageStruct = static_cast(voidStruct); std::invoke(handler, *storageStruct); }; } - friend class TaskTreePrivate; TaskTreePrivate *d; }; From be1c0721577dd07d696b6647d877160b7d9d8188 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sun, 12 Nov 2023 14:10:45 +0100 Subject: [PATCH 0186/1546] TaskTree: Delete runtime data earlier Delete the runtime node just after the task / container is finished, instead of when all other tasks in parent container are finished. Change-Id: I5fa3bc92324e8274b023fbc20e4bbede9824f47a Reviewed-by: Qt CI Bot Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index fd13268c2df..2b361441dec 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -1234,6 +1234,7 @@ public: bool isStarting() const { return m_startGuard.isLocked(); } bool updateSuccessBit(bool success); int currentLimit() const; + void deleteChild(TaskRuntimeNode *node); const TaskContainer &m_taskContainer; // Not owning. TaskRuntimeNode *m_parentNode = nullptr; // Not owning. @@ -1394,6 +1395,14 @@ int TaskRuntimeContainer::currentLimit() const ? qMin(m_doneCount + m_taskContainer.m_parallelLimit, childCount) : childCount; } +void TaskRuntimeContainer::deleteChild(TaskRuntimeNode *node) +{ + const int index = m_children.indexOf(node); + QT_CHECK(index >= 0); + m_children[index] = nullptr; + delete node; +} + SetupResult TaskTreePrivate::start(TaskRuntimeContainer *container) { SetupResult startAction = SetupResult::Continue; @@ -1422,11 +1431,15 @@ SetupResult TaskTreePrivate::continueStart(TaskRuntimeContainer *container, Setu if (groupAction != SetupResult::Continue) { const bool bit = container->updateSuccessBit(groupAction == SetupResult::StopWithSuccess); TaskRuntimeContainer *parentContainer = container->m_parentContainer; + TaskRuntimeNode *parentNode = container->m_parentNode; + QT_CHECK(parentNode); const bool result = invokeDoneHandler(container, bit ? DoneWith::Success : DoneWith::Error); if (parentContainer) { + parentContainer->deleteChild(parentNode); if (!parentContainer->isStarting()) childDone(parentContainer, result); } else { + QT_CHECK(m_runtimeRoot.get() == parentNode); m_runtimeRoot.reset(); emitDone(result ? DoneWith::Success : DoneWith::Error); } @@ -1547,11 +1560,13 @@ SetupResult TaskTreePrivate::start(TaskRuntimeNode *node) q, [this, node, unwindAction](bool success) { const bool result = invokeDoneHandler(node, success ? DoneWith::Success : DoneWith::Error); QObject::disconnect(node->m_task.get(), &TaskInterface::done, q, nullptr); - node->m_task.release()->deleteLater(); // TODO: delete later this??? - if (node->m_parentContainer->isStarting()) + node->m_task.release()->deleteLater(); + TaskRuntimeContainer *parentContainer = node->m_parentContainer; + parentContainer->deleteChild(node); + if (parentContainer->isStarting()) *unwindAction = toSetupResult(result); else - childDone(node->m_parentContainer, result); + childDone(parentContainer, result); }); node->m_task->start(); From 2a1abb41430ef1be4cdd07ecefacb1dd23b41b93 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sun, 12 Nov 2023 15:26:28 +0100 Subject: [PATCH 0187/1546] TaskTree: Create more data on stack Use std::optional instead of std::unique_ptr. Change-Id: I5b182a10ebbd47c02de113c8d317ad531d603661 Reviewed-by: hjk Reviewed-by: Qt CI Bot Reviewed-by: --- src/libs/solutions/tasking/tasktree.cpp | 105 ++++++++++++------------ 1 file changed, 54 insertions(+), 51 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 2b361441dec..6e5fb6f1124 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -1071,6 +1071,47 @@ private: QList m_activeStorages; }; +class TaskContainer +{ + Q_DISABLE_COPY(TaskContainer) + +public: + TaskContainer(TaskContainer &&other) = default; + TaskContainer(TaskTreePrivate *taskTreePrivate, const GroupItem &task, + TaskNode *parentNode, TaskContainer *parentContainer); + + TaskTreePrivate *const m_taskTreePrivate = nullptr; + TaskNode *const m_parentNode = nullptr; + TaskContainer *const m_parentContainer = nullptr; + + const int m_parallelLimit = 1; + const WorkflowPolicy m_workflowPolicy = WorkflowPolicy::StopOnError; + const GroupItem::GroupHandler m_groupHandler; + const QList m_storageList; + std::vector m_children; + const int m_taskCount = 0; +}; + +class TaskNode +{ + Q_DISABLE_COPY(TaskNode) + +public: + TaskNode(TaskNode &&other) = default; + TaskNode(TaskTreePrivate *taskTreePrivate, const GroupItem &task, + TaskContainer *parentContainer) + : m_taskHandler(task.m_taskHandler) + , m_container(taskTreePrivate, task, this, parentContainer) + {} + + bool isTask() const { return bool(m_taskHandler.m_createHandler); } + int taskCount() const { return isTask() ? 1 : m_container.m_taskCount; } + TaskContainer *parentContainer() const { return m_container.m_parentContainer; } + + const GroupItem::TaskHandler m_taskHandler; + TaskContainer m_container; +}; + class TaskTreePrivate { Q_DISABLE_COPY_MOVE(TaskTreePrivate) @@ -1143,49 +1184,8 @@ public: int m_progressValue = 0; QSet m_storages; QHash m_storageHandlers; - std::unique_ptr m_root = nullptr; // Keep me last in order to destruct first - std::unique_ptr m_runtimeRoot = nullptr; -}; - -class TaskContainer -{ - Q_DISABLE_COPY(TaskContainer) - -public: - TaskContainer(TaskContainer &&other) = default; - TaskContainer(TaskTreePrivate *taskTreePrivate, const GroupItem &task, - TaskNode *parentNode, TaskContainer *parentContainer); - - TaskTreePrivate *const m_taskTreePrivate = nullptr; - TaskNode *const m_parentNode = nullptr; - TaskContainer *const m_parentContainer = nullptr; - - const int m_parallelLimit = 1; - const WorkflowPolicy m_workflowPolicy = WorkflowPolicy::StopOnError; - const GroupItem::GroupHandler m_groupHandler; - const QList m_storageList; - std::vector m_children; - const int m_taskCount = 0; -}; - -class TaskNode -{ - Q_DISABLE_COPY(TaskNode) - -public: - TaskNode(TaskNode &&other) = default; - TaskNode(TaskTreePrivate *taskTreePrivate, const GroupItem &task, - TaskContainer *parentContainer) - : m_taskHandler(task.m_taskHandler) - , m_container(taskTreePrivate, task, this, parentContainer) - {} - - bool isTask() const { return bool(m_taskHandler.m_createHandler); } - int taskCount() const { return isTask() ? 1 : m_container.m_taskCount; } - TaskContainer *parentContainer() const { return m_container.m_parentContainer; } - - const GroupItem::TaskHandler m_taskHandler; - TaskContainer m_container; + std::optional m_root; + std::unique_ptr m_runtimeRoot; // Keep me last in order to destruct first }; static bool initialSuccessBit(WorkflowPolicy workflowPolicy) @@ -1207,6 +1207,8 @@ static bool initialSuccessBit(WorkflowPolicy workflowPolicy) class TaskRuntimeContainer { + Q_DISABLE_COPY(TaskRuntimeContainer) + public: TaskRuntimeContainer(const TaskContainer &taskContainer, TaskRuntimeNode *parentNode, TaskRuntimeContainer *parentContainer) @@ -1250,6 +1252,8 @@ public: class TaskRuntimeNode { + Q_DISABLE_COPY(TaskRuntimeNode) + public: TaskRuntimeNode(const TaskNode &taskNode, TaskRuntimeContainer *parentContainer) : m_taskNode(taskNode) @@ -1258,7 +1262,7 @@ public: const TaskNode &m_taskNode; // Not owning. TaskRuntimeContainer *m_parentContainer = nullptr; // Not owning. - std::unique_ptr m_container; // Owning. + std::optional m_container; // Owning. std::unique_ptr m_task; // Owning. }; @@ -1290,7 +1294,7 @@ void TaskTreePrivate::start() QT_ASSERT(m_storages.contains(it.key()), qWarning("The registered storage doesn't " "exist in task tree. Its handlers will never be called.")); } - m_runtimeRoot.reset(new TaskRuntimeNode(*m_root.get(), nullptr)); + m_runtimeRoot.reset(new TaskRuntimeNode(*m_root, nullptr)); start(m_runtimeRoot.get()); } @@ -1538,9 +1542,8 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeContainer *container, DoneWit SetupResult TaskTreePrivate::start(TaskRuntimeNode *node) { if (!node->m_taskNode.isTask()) { - node->m_container.reset(new TaskRuntimeContainer(node->m_taskNode.m_container, node, - node->m_parentContainer)); - return start(node->m_container.get()); + node->m_container.emplace(node->m_taskNode.m_container, node, node->m_parentContainer); + return start(&*node->m_container); } const GroupItem::TaskHandler &handler = node->m_taskNode.m_taskHandler; @@ -1578,9 +1581,9 @@ void TaskTreePrivate::stop(TaskRuntimeNode *node) if (!node->m_task) { if (!node->m_container) return; - stop(node->m_container.get()); + stop(&*node->m_container); node->m_container->updateSuccessBit(false); - invokeDoneHandler(node->m_container.get(), DoneWith::Cancel); + invokeDoneHandler(&*node->m_container, DoneWith::Cancel); return; } @@ -2299,7 +2302,7 @@ void TaskTree::setRecipe(const Group &recipe) "TaskTree handlers, ignoring..."); return); // TODO: Should we clear the m_storageHandlers, too? d->m_storages.clear(); - d->m_root.reset(new TaskNode(d, recipe, nullptr)); + d->m_root.emplace(d, recipe, nullptr); } /*! From 6da404fa2c8505e1d6c817907d24823c1e9dd7b7 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sun, 12 Nov 2023 16:35:02 +0100 Subject: [PATCH 0188/1546] TaskTree: Keep list of unique_ptr for owned children Change-Id: Ib6bc1efa647b4e48b1a4188de480f06bc4e7699e Reviewed-by: Qt CI Bot Reviewed-by: hjk Reviewed-by: --- src/libs/solutions/tasking/tasktree.cpp | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 6e5fb6f1124..64ad3bf15c8 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -1228,10 +1228,8 @@ public: m_taskContainer.m_taskTreePrivate->callDoneHandler(storage, storageId); storage.m_storageData->deleteStorage(storageId); } - qDeleteAll(m_children); } - static QList createStorages(const TaskContainer &container); bool isStarting() const { return m_startGuard.isLocked(); } bool updateSuccessBit(bool success); @@ -1243,7 +1241,7 @@ public: TaskRuntimeContainer *m_parentContainer = nullptr; // Not owning. const QList m_storageIdList; - QList m_children; // Owning. + std::vector> m_children; // Owning. bool m_successBit = true; bool m_callStorageDoneHandlersOnDestruction = false; int m_doneCount = 0; @@ -1401,10 +1399,9 @@ int TaskRuntimeContainer::currentLimit() const void TaskRuntimeContainer::deleteChild(TaskRuntimeNode *node) { - const int index = m_children.indexOf(node); - QT_CHECK(index >= 0); - m_children[index] = nullptr; - delete node; + std::remove_if(m_children.begin(), m_children.end(), [node](const auto &ptr) { + return ptr.get() == node; + }); } SetupResult TaskTreePrivate::start(TaskRuntimeContainer *container) @@ -1460,7 +1457,7 @@ SetupResult TaskTreePrivate::startChildren(TaskRuntimeContainer *container, int break; TaskRuntimeNode *newTask = new TaskRuntimeNode(container->m_taskContainer.m_children.at(i), container); - container->m_children.append(newTask); + container->m_children.emplace_back(newTask); const SetupResult startAction = start(newTask); if (startAction == SetupResult::Continue) @@ -1504,17 +1501,13 @@ SetupResult TaskTreePrivate::childDone(TaskRuntimeContainer *container, bool suc void TaskTreePrivate::stop(TaskRuntimeContainer *container) { - const int limit = container->currentLimit(); - for (int i = 0; i < limit; ++i) { - if (i == container->m_children.size()) - break; - TaskRuntimeNode *child = container->m_children.at(i); + for (auto &child : container->m_children) { if (child) - stop(child); + stop(child.get()); } int skippedTaskCount = 0; - for (int i = limit; i < int(container->m_taskContainer.m_children.size()); ++i) + for (int i = container->currentLimit(); i < int(container->m_taskContainer.m_children.size()); ++i) skippedTaskCount += container->m_taskContainer.m_children.at(i).taskCount(); // TODO: Handle progress well From e5b7f474b38bd467d77faffe043fcd56f4e078d6 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sun, 12 Nov 2023 17:26:20 +0100 Subject: [PATCH 0189/1546] TaskTree: Get rid of unused data Change-Id: I60f38e7a0efeb02615d81181a9884963a66be39b Reviewed-by: Qt CI Bot Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 61 ++++++++++++------------- 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 64ad3bf15c8..d1401548592 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -1077,12 +1077,9 @@ class TaskContainer public: TaskContainer(TaskContainer &&other) = default; - TaskContainer(TaskTreePrivate *taskTreePrivate, const GroupItem &task, - TaskNode *parentNode, TaskContainer *parentContainer); + TaskContainer(TaskTreePrivate *taskTreePrivate, const GroupItem &task); TaskTreePrivate *const m_taskTreePrivate = nullptr; - TaskNode *const m_parentNode = nullptr; - TaskContainer *const m_parentContainer = nullptr; const int m_parallelLimit = 1; const WorkflowPolicy m_workflowPolicy = WorkflowPolicy::StopOnError; @@ -1098,15 +1095,13 @@ class TaskNode public: TaskNode(TaskNode &&other) = default; - TaskNode(TaskTreePrivate *taskTreePrivate, const GroupItem &task, - TaskContainer *parentContainer) + TaskNode(TaskTreePrivate *taskTreePrivate, const GroupItem &task) : m_taskHandler(task.m_taskHandler) - , m_container(taskTreePrivate, task, this, parentContainer) + , m_container(taskTreePrivate, task) {} bool isTask() const { return bool(m_taskHandler.m_createHandler); } int taskCount() const { return isTask() ? 1 : m_container.m_taskCount; } - TaskContainer *parentContainer() const { return m_container.m_parentContainer; } const GroupItem::TaskHandler m_taskHandler; TaskContainer m_container; @@ -1210,11 +1205,9 @@ class TaskRuntimeContainer Q_DISABLE_COPY(TaskRuntimeContainer) public: - TaskRuntimeContainer(const TaskContainer &taskContainer, TaskRuntimeNode *parentNode, - TaskRuntimeContainer *parentContainer) + TaskRuntimeContainer(const TaskContainer &taskContainer, TaskRuntimeNode *parentNode) : m_taskContainer(taskContainer) , m_parentNode(parentNode) - , m_parentContainer(parentContainer) , m_storageIdList(createStorages(taskContainer)) , m_successBit(initialSuccessBit(taskContainer.m_workflowPolicy)) {} @@ -1232,13 +1225,13 @@ public: static QList createStorages(const TaskContainer &container); bool isStarting() const { return m_startGuard.isLocked(); } - bool updateSuccessBit(bool success); int currentLimit() const; + TaskRuntimeContainer *parentContainer() const; + bool updateSuccessBit(bool success); void deleteChild(TaskRuntimeNode *node); const TaskContainer &m_taskContainer; // Not owning. TaskRuntimeNode *m_parentNode = nullptr; // Not owning. - TaskRuntimeContainer *m_parentContainer = nullptr; // Not owning. const QList m_storageIdList; std::vector> m_children; // Owning. @@ -1277,8 +1270,8 @@ void ExecutionContextActivator::activateContext(TaskRuntimeContainer *container) } // Go to the parent after activating this storages so that storage shadowing works // in the direction from child to parent root. - if (container->m_parentContainer) - activateContext(container->m_parentContainer); + if (container->parentContainer()) + activateContext(container->parentContainer()); } void TaskTreePrivate::start() @@ -1335,26 +1328,23 @@ void TaskTreePrivate::emitDone(DoneWith result) emit q->done(result); } -static std::vector createChildren(TaskTreePrivate *taskTreePrivate, TaskContainer *container, +static std::vector createChildren(TaskTreePrivate *taskTreePrivate, const QList &children) { std::vector result; result.reserve(children.size()); for (const GroupItem &child : children) - result.emplace_back(taskTreePrivate, child, container); + result.emplace_back(taskTreePrivate, child); return result; } -TaskContainer::TaskContainer(TaskTreePrivate *taskTreePrivate, const GroupItem &task, - TaskNode *parentNode, TaskContainer *parentContainer) +TaskContainer::TaskContainer(TaskTreePrivate *taskTreePrivate, const GroupItem &task) : m_taskTreePrivate(taskTreePrivate) - , m_parentNode(parentNode) - , m_parentContainer(parentContainer) , m_parallelLimit(task.m_groupData.m_parallelLimit.value_or(1)) , m_workflowPolicy(task.m_groupData.m_workflowPolicy.value_or(WorkflowPolicy::StopOnError)) , m_groupHandler(task.m_groupData.m_groupHandler) , m_storageList(task.m_storageList) - , m_children(createChildren(taskTreePrivate, this, task.m_children)) + , m_children(createChildren(taskTreePrivate, task.m_children)) , m_taskCount(std::accumulate(m_children.cbegin(), m_children.cend(), 0, [](int r, const TaskNode &n) { return r + n.taskCount(); })) { @@ -1373,6 +1363,19 @@ QList TaskRuntimeContainer::createStorages(const TaskContainer &container) return storageIdList; } +int TaskRuntimeContainer::currentLimit() const +{ + // TODO: Handle children well + const int childCount = m_taskContainer.m_children.size(); + return m_taskContainer.m_parallelLimit + ? qMin(m_doneCount + m_taskContainer.m_parallelLimit, childCount) : childCount; +} + +TaskRuntimeContainer *TaskRuntimeContainer::parentContainer() const +{ + return m_parentNode->m_parentContainer; +} + bool TaskRuntimeContainer::updateSuccessBit(bool success) { if (m_taskContainer.m_workflowPolicy == WorkflowPolicy::FinishAllAndSuccess @@ -1389,14 +1392,6 @@ bool TaskRuntimeContainer::updateSuccessBit(bool success) return m_successBit; } -int TaskRuntimeContainer::currentLimit() const -{ - // TODO: Handle children well - const int childCount = m_taskContainer.m_children.size(); - return m_taskContainer.m_parallelLimit - ? qMin(m_doneCount + m_taskContainer.m_parallelLimit, childCount) : childCount; -} - void TaskRuntimeContainer::deleteChild(TaskRuntimeNode *node) { std::remove_if(m_children.begin(), m_children.end(), [node](const auto &ptr) { @@ -1431,7 +1426,7 @@ SetupResult TaskTreePrivate::continueStart(TaskRuntimeContainer *container, Setu : startAction; if (groupAction != SetupResult::Continue) { const bool bit = container->updateSuccessBit(groupAction == SetupResult::StopWithSuccess); - TaskRuntimeContainer *parentContainer = container->m_parentContainer; + TaskRuntimeContainer *parentContainer = container->parentContainer(); TaskRuntimeNode *parentNode = container->m_parentNode; QT_CHECK(parentNode); const bool result = invokeDoneHandler(container, bit ? DoneWith::Success : DoneWith::Error); @@ -1535,7 +1530,7 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeContainer *container, DoneWit SetupResult TaskTreePrivate::start(TaskRuntimeNode *node) { if (!node->m_taskNode.isTask()) { - node->m_container.emplace(node->m_taskNode.m_container, node, node->m_parentContainer); + node->m_container.emplace(node->m_taskNode.m_container, node); return start(&*node->m_container); } @@ -2295,7 +2290,7 @@ void TaskTree::setRecipe(const Group &recipe) "TaskTree handlers, ignoring..."); return); // TODO: Should we clear the m_storageHandlers, too? d->m_storages.clear(); - d->m_root.emplace(d, recipe, nullptr); + d->m_root.emplace(d, recipe); } /*! From a53dfaf623c3167ae07e8360e7cf9599e2904f24 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 5 Oct 2023 16:45:07 +0200 Subject: [PATCH 0190/1546] Process: Switch the default implementation into QProcess Task-number: QTCREATORBUG-28811 Change-Id: I5647b760998a80f59583b478a65de6d615e1ca55 Reviewed-by: hjk --- src/libs/utils/process.cpp | 3 ++- tests/auto/utils/process/tst_process.cpp | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libs/utils/process.cpp b/src/libs/utils/process.cpp index da7d65de0c5..192b3bc880c 100644 --- a/src/libs/utils/process.cpp +++ b/src/libs/utils/process.cpp @@ -631,7 +631,8 @@ private: static ProcessImpl defaultProcessImpl() { - if (qtcEnvironmentVariableIsSet("QTC_USE_QPROCESS")) + const QString value = qtcEnvironmentVariable("QTC_USE_QPROCESS", "TRUE").toUpper(); + if (value != "FALSE" && value != "0") return ProcessImpl::QProcess; return ProcessImpl::ProcessLauncher; } diff --git a/tests/auto/utils/process/tst_process.cpp b/tests/auto/utils/process/tst_process.cpp index 4bea9979584..0e46f7c0940 100644 --- a/tests/auto/utils/process/tst_process.cpp +++ b/tests/auto/utils/process/tst_process.cpp @@ -1322,8 +1322,6 @@ void tst_Process::crashAfterOneSecond() QVERIFY(process.waitForStarted(1000)); QElapsedTimer timer; timer.start(); - // Please note that QProcess documentation says it should return false, but apparently - // it doesn't (try running this test with QTC_USE_QPROCESS=) QVERIFY(process.waitForFinished(30000)); QVERIFY(timer.elapsed() < 30000); QCOMPARE(process.state(), QProcess::NotRunning); From 5a2df08ae08becf75003f1824572397c7c5a7266 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 26 Oct 2023 12:53:25 +0200 Subject: [PATCH 0191/1546] TaskTree: Add a new example showing input / output data exchange This example shows how to separate the business logic of the recipe from the GUI and how to write a reusable recipe. It shows how to feed the recipe with the initial data and how to retrieve the final result from the recipe using onStorageSetup() and onStorageDone() handlers. Change-Id: I04c0c0c9bd6cf25ac4e91317e527ad12832e9143 Reviewed-by: Qt CI Bot Reviewed-by: hjk --- tests/manual/manual.qbs | 1 + tests/manual/tasking/CMakeLists.txt | 1 + .../tasking/dataexchange/CMakeLists.txt | 10 ++ .../tasking/dataexchange/dataexchange.qbs | 15 +++ tests/manual/tasking/dataexchange/main.cpp | 17 ++++ tests/manual/tasking/dataexchange/recipe.cpp | 86 +++++++++++++++++ tests/manual/tasking/dataexchange/recipe.h | 36 +++++++ tests/manual/tasking/dataexchange/viewer.cpp | 94 +++++++++++++++++++ tests/manual/tasking/dataexchange/viewer.h | 33 +++++++ 9 files changed, 293 insertions(+) create mode 100644 tests/manual/tasking/dataexchange/CMakeLists.txt create mode 100644 tests/manual/tasking/dataexchange/dataexchange.qbs create mode 100644 tests/manual/tasking/dataexchange/main.cpp create mode 100644 tests/manual/tasking/dataexchange/recipe.cpp create mode 100644 tests/manual/tasking/dataexchange/recipe.h create mode 100644 tests/manual/tasking/dataexchange/viewer.cpp create mode 100644 tests/manual/tasking/dataexchange/viewer.h diff --git a/tests/manual/manual.qbs b/tests/manual/manual.qbs index 25ed3b9e183..b9a42250a2d 100644 --- a/tests/manual/manual.qbs +++ b/tests/manual/manual.qbs @@ -13,6 +13,7 @@ Project { "shootout/shootout.qbs", "spinner/spinner.qbs", "subdirfilecontainer/subdirfilecontainer.qbs", + "tasking/dataexchange/dataexchange.qbs", "tasking/demo/demo.qbs", "tasking/imagescaling/imagescaling.qbs", "terminal/terminal.qbs", diff --git a/tests/manual/tasking/CMakeLists.txt b/tests/manual/tasking/CMakeLists.txt index a27004eb3ec..79a524afd2a 100644 --- a/tests/manual/tasking/CMakeLists.txt +++ b/tests/manual/tasking/CMakeLists.txt @@ -1,2 +1,3 @@ +add_subdirectory(dataexchange) add_subdirectory(demo) add_subdirectory(imagescaling) diff --git a/tests/manual/tasking/dataexchange/CMakeLists.txt b/tests/manual/tasking/dataexchange/CMakeLists.txt new file mode 100644 index 00000000000..d5ac9cb8aa8 --- /dev/null +++ b/tests/manual/tasking/dataexchange/CMakeLists.txt @@ -0,0 +1,10 @@ +add_qtc_test(tst_tasking_dataexchange + MANUALTEST + DEPENDS Tasking Qt::Concurrent Qt::Network Qt::Widgets + SOURCES + main.cpp + recipe.cpp + recipe.h + viewer.cpp + viewer.h +) diff --git a/tests/manual/tasking/dataexchange/dataexchange.qbs b/tests/manual/tasking/dataexchange/dataexchange.qbs new file mode 100644 index 00000000000..0cda959a31f --- /dev/null +++ b/tests/manual/tasking/dataexchange/dataexchange.qbs @@ -0,0 +1,15 @@ +QtcManualTest { + name: "Tasking dataexchange" + type: ["application"] + + Depends { name: "Qt"; submodules: ["concurrent", "network", "widgets"] } + Depends { name: "Tasking" } + + files: [ + "main.cpp", + "recipe.cpp", + "recipe.h", + "viewer.cpp", + "viewer.h", + ] +} diff --git a/tests/manual/tasking/dataexchange/main.cpp b/tests/manual/tasking/dataexchange/main.cpp new file mode 100644 index 00000000000..d1cd06fe1e8 --- /dev/null +++ b/tests/manual/tasking/dataexchange/main.cpp @@ -0,0 +1,17 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "viewer.h" +#include + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + app.setOrganizationName("QtProject"); + app.setApplicationName("Data Exchange"); + + Viewer viewer; + viewer.show(); + + return app.exec(); +} diff --git a/tests/manual/tasking/dataexchange/recipe.cpp b/tests/manual/tasking/dataexchange/recipe.cpp new file mode 100644 index 00000000000..4446eee7b9a --- /dev/null +++ b/tests/manual/tasking/dataexchange/recipe.cpp @@ -0,0 +1,86 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "recipe.h" + +#include +#include + +using namespace Tasking; + +static void readImage(QPromise &promise, const QByteArray &data) +{ + const auto image = QImage::fromData(data); + if (image.isNull()) + promise.future().cancel(); + else + promise.addResult(image); +} + +static void scaleImage(QPromise &promise, const QImage &inputImage, const QSize &size) +{ + promise.addResult(inputImage.scaled(size, Qt::KeepAspectRatio)); +} + +class InternalData +{ +public: + QByteArray dataSource; + QImage imageSource; +}; + +static int sizeForIndex(int index) { return (index + 1) * s_sizeInterval; } + +Group recipe(const Tasking::TreeStorage &externalStorage) +{ + TreeStorage internalStorage; + + const auto onDownloadSetup = [externalStorage](NetworkQuery &query) { + query.setNetworkAccessManager(externalStorage->inputNam); + query.setRequest(QNetworkRequest(externalStorage->inputUrl)); + }; + const auto onDownloadDone = [internalStorage, externalStorage](const NetworkQuery &query, + DoneWith doneWith) { + if (doneWith == DoneWith::Success) { + internalStorage->dataSource = query.reply()->readAll(); + } else { + externalStorage->outputError + = QString("Download Error. Code: %1.").arg(query.reply()->error()); + } + }; + + const auto onReadSetup = [internalStorage](ConcurrentCall &data) { + data.setConcurrentCallData(&readImage, internalStorage->dataSource); + }; + const auto onReadDone = [internalStorage, externalStorage](const ConcurrentCall &data, + DoneWith doneWith) { + if (doneWith == DoneWith::Success) + internalStorage->imageSource = data.result(); + else + externalStorage->outputError = "Image Data Error."; + }; + + QList parallelTasks; + parallelTasks.reserve(s_imageCount + 1); // +1 for parallelLimit + parallelTasks.append(parallelLimit(QThread::idealThreadCount() - 1)); + + for (int i = 0; i < s_imageCount; ++i) { + const int s = sizeForIndex(i); + const auto onScaleSetup = [internalStorage, s](ConcurrentCall &data) { + data.setConcurrentCallData(&scaleImage, internalStorage->imageSource, QSize(s, s)); + }; + const auto onScaleDone = [externalStorage, s](const ConcurrentCall &data) { + externalStorage->outputImages.insert(s, data.result()); + }; + parallelTasks.append(ConcurrentCallTask(onScaleSetup, onScaleDone)); + } + + const QList recipe { + Storage(externalStorage), + Storage(internalStorage), + NetworkQueryTask(onDownloadSetup, onDownloadDone), + ConcurrentCallTask(onReadSetup, onReadDone), + Group { parallelTasks } + }; + return recipe; +} diff --git a/tests/manual/tasking/dataexchange/recipe.h b/tests/manual/tasking/dataexchange/recipe.h new file mode 100644 index 00000000000..7b17e1349a3 --- /dev/null +++ b/tests/manual/tasking/dataexchange/recipe.h @@ -0,0 +1,36 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef RECIPE_H +#define RECIPE_H + +#include +#include +#include + +#include + +namespace Tasking { +class Group; +template +class TreeStorage; +} + +static const int s_sizeInterval = 10; +static const int s_imageCount = 100; +static const int s_maxSize = s_sizeInterval * s_imageCount; + +class QNetworkAccessManager; + +class ExternalData +{ +public: + QNetworkAccessManager *inputNam = nullptr; + QUrl inputUrl; + QMap outputImages; + std::optional outputError; +}; + +Tasking::Group recipe(const Tasking::TreeStorage &externalStorage); + +#endif // RECIPE_H diff --git a/tests/manual/tasking/dataexchange/viewer.cpp b/tests/manual/tasking/dataexchange/viewer.cpp new file mode 100644 index 00000000000..62a4bdd3e88 --- /dev/null +++ b/tests/manual/tasking/dataexchange/viewer.cpp @@ -0,0 +1,94 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#include "viewer.h" +#include "recipe.h" + +#include +#include + +using namespace Tasking; + +Viewer::Viewer(QWidget *parent) + : QWidget(parent) + , m_recipe(recipe(m_storage)) +{ + setWindowTitle(tr("Data Exchange")); + + QLabel *urlLabel = new QLabel(tr("Url:")); + m_lineEdit = new QLineEdit("https://media.licdn.com/dms/image/D4D22AQFj3ksh5rmnrg/" + "feedshare-shrink_800/0/1697023188446?e=1701302400&v=beta" + "&t=6dy5dmhzgONaLu139A6XmFSGqDohiezq1fH-q2mmu3w"); + QPushButton *startButton = new QPushButton(tr("Start")); + QPushButton *stopButton = new QPushButton(tr("Stop")); + QPushButton *resetButton = new QPushButton(tr("Reset")); + m_progressBar = new QProgressBar; + m_listWidget = new QListWidget; + m_statusBar = new QStatusBar; + + QBoxLayout *mainLayout = new QVBoxLayout(this); + QBoxLayout *subLayout1 = new QHBoxLayout; + QBoxLayout *subLayout2 = new QHBoxLayout; + subLayout1->addWidget(urlLabel); + subLayout1->addWidget(m_lineEdit); + subLayout2->addWidget(startButton); + subLayout2->addWidget(stopButton); + subLayout2->addWidget(resetButton); + subLayout2->addWidget(m_progressBar); + mainLayout->addLayout(subLayout1); + mainLayout->addLayout(subLayout2); + mainLayout->addWidget(m_listWidget); + mainLayout->addWidget(m_statusBar); + + m_listWidget->setIconSize(QSize(s_maxSize, s_maxSize)); + + const auto reset = [this] { + m_listWidget->clear(); + m_statusBar->clearMessage(); + m_progressBar->setValue(0); + }; + + connect(startButton, &QAbstractButton::clicked, this, [this, reset] { + reset(); + const auto setInput = [this](ExternalData &data) { + data.inputNam = &m_nam; + data.inputUrl = m_lineEdit->text(); + m_statusBar->showMessage(tr("Executing recipe...")); + }; + + const auto getOutput = [this](const ExternalData &data) { + if (data.outputError) { + m_statusBar->showMessage(*data.outputError); + return; + } + m_statusBar->showMessage(tr("Recipe executed successfully.")); + for (auto it = data.outputImages.begin(); it != data.outputImages.end(); ++it) { + m_listWidget->addItem(new QListWidgetItem(QPixmap::fromImage(it.value()), + QString("%1x%1").arg(it.key()))); + } + }; + + const auto onDone = [this] { m_taskTree.release()->deleteLater(); }; + + m_taskTree.reset(new TaskTree(m_recipe)); + m_taskTree->onStorageSetup(m_storage, setInput); + m_taskTree->onStorageDone(m_storage, getOutput); + m_progressBar->setMaximum(m_taskTree->progressMaximum()); + QObject::connect(m_taskTree.get(), &TaskTree::progressValueChanged, + m_progressBar, &QProgressBar::setValue); + QObject::connect(m_taskTree.get(), &TaskTree::done, this, onDone); + m_taskTree->start(); + }); + + connect(stopButton, &QAbstractButton::clicked, this, [this] { + if (m_taskTree) { + m_statusBar->showMessage(tr("Recipe stopped by user.")); + m_taskTree.reset(); + } + }); + + connect(resetButton, &QAbstractButton::clicked, this, [this, reset] { + m_taskTree.reset(); + reset(); + }); +} diff --git a/tests/manual/tasking/dataexchange/viewer.h b/tests/manual/tasking/dataexchange/viewer.h new file mode 100644 index 00000000000..81575596f5f --- /dev/null +++ b/tests/manual/tasking/dataexchange/viewer.h @@ -0,0 +1,33 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +#ifndef VIEWER_H +#define VIEWER_H + +#include "recipe.h" + +#include + +#include +#include + +class Viewer : public QWidget +{ + Q_OBJECT + +public: + Viewer(QWidget *parent = nullptr); + +private: + QLineEdit *m_lineEdit = nullptr; + QProgressBar *m_progressBar = nullptr; + QListWidget *m_listWidget = nullptr; + QStatusBar *m_statusBar = nullptr; + + QNetworkAccessManager m_nam; + const Tasking::TreeStorage m_storage; + const Tasking::Group m_recipe; + std::unique_ptr m_taskTree; +}; + +#endif // VIEWER_H From cf6b6b5a8ab32791c39703fd8a25a6205e0a6269 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 27 Sep 2023 16:20:18 +0200 Subject: [PATCH 0192/1546] QmakePM: Improve performance of import Shuffle order of parse and add short cuts in case we can stop parsing early. Change-Id: If03a5cbc0e51dc77f4b03b1cf1d07243f5b2a70b Reviewed-by: Christian Kandeler --- .../qmakeprojectmanager/makefileparse.cpp | 26 ++++++++++++++----- .../qmakeprojectmanager/makefileparse.h | 5 +++- .../qmakeprojectimporter.cpp | 4 +-- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/makefileparse.cpp b/src/plugins/qmakeprojectmanager/makefileparse.cpp index b5a6d82a1f9..de8ff427863 100644 --- a/src/plugins/qmakeprojectmanager/makefileparse.cpp +++ b/src/plugins/qmakeprojectmanager/makefileparse.cpp @@ -25,7 +25,13 @@ static QString findQMakeLine(const FilePath &makefile, const QString &key) { QFile fi(makefile.toString()); if (fi.exists() && fi.open(QFile::ReadOnly)) { + static const QString cmakeLine("# CMAKE generated file: DO NOT EDIT!"); QTextStream ts(&fi); + if (!ts.atEnd()) { + if (ts.readLine() == cmakeLine) + return {}; + ts.seek(0); + } while (!ts.atEnd()) { const QString line = ts.readLine(); if (line.startsWith(key)) @@ -48,7 +54,7 @@ void MakeFileParse::parseArgs(const QString &args, const QString &project, QList *assignments, QList *afterAssignments) { - const QRegularExpression regExp(QLatin1String("^([^\\s\\+-]*)\\s*(\\+=|=|-=|~=)(.*)$")); + static const QRegularExpression regExp(QLatin1String("^([^\\s\\+-]*)\\s*(\\+=|=|-=|~=)(.*)$")); bool after = false; bool ignoreNext = false; m_unparsedArguments = args; @@ -207,7 +213,7 @@ static FilePath findQMakeBinaryFromMakefile(const FilePath &makefile) QFile fi(makefile.toString()); if (fi.exists() && fi.open(QFile::ReadOnly)) { QTextStream ts(&fi); - const QRegularExpression r1(QLatin1String("^QMAKE\\s*=(.*)$")); + static const QRegularExpression r1(QLatin1String("^QMAKE\\s*=(.*)$")); while (!ts.atEnd()) { QString line = ts.readLine(); const QRegularExpressionMatch match = r1.match(line); @@ -228,7 +234,9 @@ static FilePath findQMakeBinaryFromMakefile(const FilePath &makefile) return {}; } -MakeFileParse::MakeFileParse(const FilePath &makefile, Mode mode) : m_mode(mode) +MakeFileParse::MakeFileParse(const FilePath &makefile, Mode mode, + std::optional projectPath) + : m_mode(mode) { qCDebug(logging()) << "Parsing makefile" << makefile; if (!makefile.exists()) { @@ -237,10 +245,6 @@ MakeFileParse::MakeFileParse(const FilePath &makefile, Mode mode) : m_mode(mode) return; } - // Qt Version! - m_qmakePath = findQMakeBinaryFromMakefile(makefile); - qCDebug(logging()) << " qmake:" << m_qmakePath; - QString project = findQMakeLine(makefile, QLatin1String("# Project:")).trimmed(); if (project.isEmpty()) { m_state = CouldNotParse; @@ -254,6 +258,14 @@ MakeFileParse::MakeFileParse(const FilePath &makefile, Mode mode) : m_mode(mode) // Src Pro file m_srcProFile = makefile.parentDir().resolvePath(project); qCDebug(logging()) << " source .pro file:" << m_srcProFile; + if (projectPath && m_srcProFile != *projectPath) { // shortcut when importing + m_state = Okay; + return; + } + + // Qt Version! + m_qmakePath = findQMakeBinaryFromMakefile(makefile); + qCDebug(logging()) << " qmake:" << m_qmakePath; QString command = findQMakeLine(makefile, QLatin1String("# Command:")).trimmed(); if (command.isEmpty()) { diff --git a/src/plugins/qmakeprojectmanager/makefileparse.h b/src/plugins/qmakeprojectmanager/makefileparse.h index 20bef6ce246..597ce717d13 100644 --- a/src/plugins/qmakeprojectmanager/makefileparse.h +++ b/src/plugins/qmakeprojectmanager/makefileparse.h @@ -7,6 +7,8 @@ #include #include +#include + namespace QmakeProjectManager { namespace Internal { @@ -21,7 +23,8 @@ class MakeFileParse { public: enum class Mode { FilterKnownConfigValues, DoNotFilterKnownConfigValues }; - MakeFileParse(const Utils::FilePath &makefile, Mode mode); + MakeFileParse(const Utils::FilePath &makefile, Mode mode, + std::optional projectFile = std::nullopt); enum MakefileState { MakefileMissing, CouldNotParse, Okay }; diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp index 832fb1a6809..ccd78c243a2 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp @@ -97,7 +97,7 @@ QList QmakeProjectImporter::examineDirectory(const FilePath &importPath, qCDebug(logs) << " Parsing makefile" << file; // find interesting makefiles const FilePath makefile = importPath / file; - MakeFileParse parse(makefile, MakeFileParse::Mode::FilterKnownConfigValues); + MakeFileParse parse(makefile, MakeFileParse::Mode::FilterKnownConfigValues, projectFilePath()); if (parse.makeFileState() != MakeFileParse::Okay) { qCDebug(logs) << " Parsing the makefile failed" << makefile; continue; @@ -108,7 +108,7 @@ QList QmakeProjectImporter::examineDirectory(const FilePath &importPath, } data->canonicalQmakeBinary = parse.qmakePath().canonicalPath(); - if (data->canonicalQmakeBinary.isEmpty()) { + if (!data->canonicalQmakeBinary.exists()) { qCDebug(logs) << " " << parse.qmakePath() << "doesn't exist anymore"; continue; } From 737c9ce41e3fac69f557d341bb5bbc996bfb9f67 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 13 Nov 2023 14:43:20 +0100 Subject: [PATCH 0193/1546] LanguageClient: Fix missing default context menu Change-Id: I7a3ae4f0af01cf05efd31082e3ac888a4613bb25 Reviewed-by: David Schulz --- .../languageclient/languageclientoutline.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/plugins/languageclient/languageclientoutline.cpp b/src/plugins/languageclient/languageclientoutline.cpp index b065754ec0d..8c45513ce9f 100644 --- a/src/plugins/languageclient/languageclientoutline.cpp +++ b/src/plugins/languageclient/languageclientoutline.cpp @@ -5,6 +5,7 @@ #include "documentsymbolcache.h" #include "languageclientmanager.h" +#include "languageclienttr.h" #include "languageclientutils.h" #include @@ -23,6 +24,7 @@ #include #include +#include #include using namespace LanguageServerProtocol; @@ -113,6 +115,8 @@ public: void restoreSettings(const QVariantMap &map) override; QVariantMap settings() const override; + void contextMenuEvent(QContextMenuEvent *event) override; + private: void handleResponse(const DocumentUri &uri, const DocumentSymbolsResult &response); void updateTextCursor(const QModelIndex &proxyIndex); @@ -204,6 +208,21 @@ QVariantMap LanguageClientOutlineWidget::settings() const return {{QString("LspOutline.Sort"), m_sorted}}; } +void LanguageClientOutlineWidget::contextMenuEvent(QContextMenuEvent *event) +{ + if (!event) + return; + + QMenu contextMenu; + QAction *action = contextMenu.addAction(Tr::tr("Expand All")); + connect(action, &QAction::triggered, &m_view, &QTreeView::expandAll); + action = contextMenu.addAction(Tr::tr("Collapse All")); + connect(action, &QAction::triggered, &m_view, &QTreeView::collapseAll); + + contextMenu.exec(event->globalPos()); + event->accept(); +} + void LanguageClientOutlineWidget::handleResponse(const DocumentUri &uri, const DocumentSymbolsResult &result) { From 4f7865eb4dc966538d82bb4bc4c403732722d1ea Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 14 Nov 2023 11:18:47 +0100 Subject: [PATCH 0194/1546] Python: Limit detection to unique python In case we are having symbolic links on python or its parent path(s) we added an interpreter for each of these. Resolve the python path explicitly and only add them if they are unique. Change-Id: I21b9d7d85e82c5ec3a18e182dfcde2b98936a8af Reviewed-by: David Schulz --- src/plugins/python/pythonsettings.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/plugins/python/pythonsettings.cpp b/src/plugins/python/pythonsettings.cpp index 256919b0317..fdd49f9842d 100644 --- a/src/plugins/python/pythonsettings.cpp +++ b/src/plugins/python/pythonsettings.cpp @@ -690,12 +690,15 @@ static QList pythonsFromPath() "python[1-9].[1-9][0-9]", "python[1-9]"}; const FilePaths dirs = Environment::systemEnvironment().path(); + QSet used; for (const FilePath &path : dirs) { const QDir dir(path.toString()); for (const QFileInfo &fi : dir.entryInfoList(filters)) { - const FilePath executable = Utils::FilePath::fromFileInfo(fi); - if (executable.exists()) + const FilePath executable = FilePath::fromUserInput(fi.canonicalFilePath()); + if (!used.contains(executable) && executable.exists()) { + used.insert(executable); pythons << createInterpreter(executable, "Python from Path"); + } } } } From ac121149b14cabfd3fbd340e3b8c4f82b846f8b8 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Wed, 15 Nov 2023 12:44:30 +0100 Subject: [PATCH 0195/1546] Core: Make strings in ICore::versionString() non-translated Change-Id: I462bab0160cb4b574da5a5ae6147915706a9f43e Reviewed-by: Marcus Tillmanns --- src/plugins/coreplugin/icore.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index 56c1b18937d..2e53dd9848e 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -804,10 +804,10 @@ QString ICore::versionString() { QString ideVersionDescription; if (QCoreApplication::applicationVersion() != appInfo().displayVersion) - ideVersionDescription = Tr::tr(" (%1)").arg(QCoreApplication::applicationVersion()); - return Tr::tr("%1 %2%3").arg(QGuiApplication::applicationDisplayName(), - appInfo().displayVersion, - ideVersionDescription); + ideVersionDescription = QString(" (%1)").arg(QCoreApplication::applicationVersion()); + return QString("%1 %2%3").arg(QGuiApplication::applicationDisplayName(), + appInfo().displayVersion, + ideVersionDescription); } /*! From 1f5f76cdf967e09ff33239784c186a79c212fb2a Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Tue, 14 Nov 2023 18:00:47 +0100 Subject: [PATCH 0196/1546] Core: Move generation of "about" text to ICore This introduces ICore::aboutInformationCompact() and ICore::aboutInformationHtml() and moves the existing code there. The former is used in the "System Information" dialog, the latter in "About". aboutInformationCompact() will be used for the "Copy and Close" feature in an follow-up patch. Task-number: QTCREATORBUG-29886 Change-Id: Iec818e376b3f02f52da00428285ad69b94d8adea Reviewed-by: Marcus Tillmanns Reviewed-by: Eike Ziller --- src/plugins/coreplugin/icore.cpp | 93 +++++++++++++++++++----- src/plugins/coreplugin/icore.h | 3 +- src/plugins/coreplugin/versiondialog.cpp | 44 +---------- 3 files changed, 77 insertions(+), 63 deletions(-) diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index 2e53dd9848e..cb6e2609030 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -810,16 +810,6 @@ QString ICore::versionString() ideVersionDescription); } -/*! - \internal -*/ -QString ICore::buildCompatibilityString() -{ - return Tr::tr("Based on Qt %1 (%2, %3)").arg(QLatin1String(qVersion()), - compilerString(), - QSysInfo::buildCpuArchitecture()); -} - /*! Returns the top level IContext of the current context, or \c nullptr if there is none. @@ -1006,15 +996,7 @@ void ICore::addPreCloseListener(const std::function &listener) */ QString ICore::systemInformation() { - QString result = PluginManager::systemInformation() + '\n'; - result += versionString() + '\n'; - result += buildCompatibilityString() + '\n'; - if (!Utils::appInfo().revision.isEmpty()) - result += QString("From revision %1\n").arg(Utils::appInfo().revision.left(10)); -#ifdef QTC_SHOW_BUILD_DATE - result += QString("Built on %1 %2\n").arg(QLatin1String(__DATE__), QLatin1String(__TIME__)); -#endif - return result; + return PluginManager::systemInformation() + '\n' + aboutInformationCompact() + '\n'; } static const QString &screenShotsPath() @@ -1146,6 +1128,79 @@ void ICore::appendAboutInformation(const QString &line) d->m_aboutInformation.append(line); } +/*! + \internal +*/ +QString ICore::aboutInformationCompact() +{ + QString information = QString("Product: %1\n").arg(versionString()); + information += QString("Based on: Qt %1 (%2, %3)\n") + .arg(QLatin1String(qVersion()), compilerString(), + QSysInfo::buildCpuArchitecture()); +#ifdef QTC_SHOW_BUILD_DATE + information += QString("Built on: %1 %2\n").arg(QLatin1String(__DATE__), + QLatin1String(__TIME__)); +#endif + const AppInfo &appInfo = Utils::appInfo(); + if (!appInfo.revision.isEmpty()) + information += QString("From revision: %1\n").arg(appInfo.revision.left(10)); + + return information; +} + +/*! + \internal +*/ +QString ICore::aboutInformationHtml() +{ + const QString buildCompatibilityString = Tr::tr("Based on Qt %1 (%2, %3)") + .arg(QLatin1String(qVersion()), compilerString(), + QSysInfo::buildCpuArchitecture()); + const AppInfo &appInfo = Utils::appInfo(); + QString ideRev; + if (!appInfo.revision.isEmpty()) + ideRev = Tr::tr("
From revision %1
") + .arg(appInfo.revisionUrl.isEmpty() + ? appInfo.revision + : QString::fromLatin1("%2") + .arg(appInfo.revisionUrl, appInfo.revision)); + QString buildDateInfo; +#ifdef QTC_SHOW_BUILD_DATE + buildDateInfo = Tr::tr("
Built on %1 %2
").arg(QLatin1String(__DATE__), + QLatin1String(__TIME__)); +#endif + + const QString br = QLatin1String("
"); + const QStringList additionalInfoLines = ICore::additionalAboutInformation(); + const QString additionalInfo = + QStringList(Utils::transform(additionalInfoLines, &QString::toHtmlEscaped)).join(br); + const QString information + = Tr::tr("

%1

" + "%2
" + "%3" + "%4" + "%5" + "
" + "Copyright 2008-%6 %7. All rights reserved.
" + "
" + "The program is provided AS IS with NO WARRANTY OF ANY KIND, " + "INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A " + "PARTICULAR PURPOSE.
") + .arg(ICore::versionString(), + buildCompatibilityString, + buildDateInfo, + ideRev, + additionalInfo.isEmpty() ? QString() : br + additionalInfo + br, + appInfo.year, + appInfo.author) + + "
" + + Tr::tr("The Qt logo as well as Qt®, Qt Quick®, Built with Qt®, Boot to Qt®, " + "Qt Quick Compiler®, Qt Enterprise®, Qt Mobile® and Qt Embedded® are " + "registered trademarks of The Qt Company Ltd."); + + return information; +} + void ICore::updateNewItemDialogState() { static bool wasRunning = false; diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h index cff938f5393..518939aeaae 100644 --- a/src/plugins/coreplugin/icore.h +++ b/src/plugins/coreplugin/icore.h @@ -136,6 +136,8 @@ public: static QStringList additionalAboutInformation(); static void clearAboutInformation(); static void appendAboutInformation(const QString &line); + static QString aboutInformationCompact(); + static QString aboutInformationHtml(); static QString systemInformation(); static void setupScreenShooter(const QString &name, QWidget *w, const QRect &rc = QRect()); static QString pluginPath(); @@ -146,7 +148,6 @@ public: static Utils::FilePath clazyStandaloneExecutable(const Utils::FilePath &clangBinDirectory); static Utils::FilePath clangIncludeDirectory(const QString &clangVersion, const Utils::FilePath &clangFallbackIncludeDir); - static QString buildCompatibilityString(); static QStatusBar *statusBar(); static void saveSettings(SaveSettingsReason reason); diff --git a/src/plugins/coreplugin/versiondialog.cpp b/src/plugins/coreplugin/versiondialog.cpp index 833fc0a7071..0df1454849b 100644 --- a/src/plugins/coreplugin/versiondialog.cpp +++ b/src/plugins/coreplugin/versiondialog.cpp @@ -35,52 +35,10 @@ VersionDialog::VersionDialog(QWidget *parent) setWindowTitle(Tr::tr("About %1").arg(QGuiApplication::applicationDisplayName())); - const Utils::AppInfo appInfo = Utils::appInfo(); - QString ideRev; - if (!appInfo.revision.isEmpty()) - ideRev = Tr::tr("
From revision %1
") - .arg(appInfo.revisionUrl.isEmpty() - ? appInfo.revision - : QString::fromLatin1("%2") - .arg(appInfo.revisionUrl, appInfo.revision)); - QString buildDateInfo; -#ifdef QTC_SHOW_BUILD_DATE - buildDateInfo = Tr::tr("
Built on %1 %2
").arg(QLatin1String(__DATE__), QLatin1String(__TIME__)); -#endif - - const QString br = QLatin1String("
"); - const QStringList additionalInfoLines = ICore::additionalAboutInformation(); - const QString additionalInfo = - QStringList(Utils::transform(additionalInfoLines, &QString::toHtmlEscaped)).join(br); - - const QString description - = Tr::tr("

%1

" - "%2
" - "%3" - "%4" - "%5" - "
" - "Copyright 2008-%6 %7. All rights reserved.
" - "
" - "The program is provided AS IS with NO WARRANTY OF ANY KIND, " - "INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A " - "PARTICULAR PURPOSE.
") - .arg(ICore::versionString(), - ICore::buildCompatibilityString(), - buildDateInfo, - ideRev, - additionalInfo.isEmpty() ? QString() : br + additionalInfo + br, - appInfo.year, - appInfo.author) - + "
" - + Tr::tr("The Qt logo as well as Qt®, Qt Quick®, Built with Qt®, Boot to Qt®, " - "Qt Quick Compiler®, Qt Enterprise®, Qt Mobile® and Qt Embedded® are " - "registered trademarks of The Qt Company Ltd."); - auto logoLabel = new QLabel; logoLabel->setPixmap(Icons::QTCREATORLOGO_BIG.pixmap()); - auto copyRightLabel = new QLabel(description); + auto copyRightLabel = new QLabel(ICore::aboutInformationHtml()); copyRightLabel->setWordWrap(true); copyRightLabel->setOpenExternalLinks(true); copyRightLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); From aabf03ec0650658388151c1a4b0cd781bfdcefa6 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Mon, 13 Nov 2023 17:52:16 +0100 Subject: [PATCH 0197/1546] Core: Add "Copy and Close" button to About dialog For the quick way to copy "I use this version" information. Fixes: QTCREATORBUG-29886 Change-Id: I0431c969a48b80438e07388d223477b5b3f56069 Reviewed-by: Reviewed-by: Marcus Tillmanns --- src/plugins/coreplugin/versiondialog.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/plugins/coreplugin/versiondialog.cpp b/src/plugins/coreplugin/versiondialog.cpp index 0df1454849b..643372f729d 100644 --- a/src/plugins/coreplugin/versiondialog.cpp +++ b/src/plugins/coreplugin/versiondialog.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,8 @@ VersionDialog::VersionDialog(QWidget *parent) copyRightLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); + QPushButton *copyButton = buttonBox->addButton(Tr::tr("Copy and Close"), + QDialogButtonBox::ApplyRole); using namespace Layouting; Column { @@ -56,6 +59,10 @@ VersionDialog::VersionDialog(QWidget *parent) layout()->setSizeConstraint(QLayout::SetFixedSize); + connect(copyButton, &QPushButton::pressed, this, [this] { + Utils::setClipboardAndSelection(ICore::aboutInformationCompact()); + accept(); + }); connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); } From 5639a3424c628163e1672dc572c4ed0b347a8cf3 Mon Sep 17 00:00:00 2001 From: Andreas Loth Date: Thu, 9 Nov 2023 13:51:51 +0100 Subject: [PATCH 0198/1546] Axivion: Use signal/slot to start reading the network response Prevent use-after-free when QtCreator is closed while a network request is still on the way. The previous future approach will try to use reply despite reply being destroyed by networkAccessManager's destructor. Now, the connection gets automatically disconnected when reply gets destroyed. Change-Id: I7a00006a2f38d3a774eb2769e6faeb339d18025a Reviewed-by: hjk Reviewed-by: --- .../axivion/dashboard/dashboardclient.cpp | 110 ++++++++---------- 1 file changed, 50 insertions(+), 60 deletions(-) diff --git a/src/plugins/axivion/dashboard/dashboardclient.cpp b/src/plugins/axivion/dashboard/dashboardclient.cpp index 5137ad32461..3d20440b60a 100644 --- a/src/plugins/axivion/dashboard/dashboardclient.cpp +++ b/src/plugins/axivion/dashboard/dashboardclient.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -25,67 +26,47 @@ DashboardClient::DashboardClient(Utils::NetworkAccessManager &networkAccessManag { } -static void deleteLater(QObject *obj) -{ - obj->deleteLater(); -} - using ResponseData = Utils::expected, Error>; static constexpr int httpStatusCodeOk = 200; static const QLatin1String jsonContentType{ "application/json" }; -class ResponseReader final +ResponseData readResponse(QNetworkReply& reply, QAnyStringView expectedContentType) { -public: - ResponseReader(std::shared_ptr reply, QAnyStringView expectedContentType) - : m_reply(std::move(reply)), - m_expectedContentType(expectedContentType) - { } - - ~ResponseReader() { } - - ResponseData operator()() - { - QNetworkReply::NetworkError error = m_reply->error(); - int statusCode = m_reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); - QString contentType = m_reply->header(QNetworkRequest::ContentTypeHeader) - .toString() - .split(';') - .constFirst() - .trimmed() - .toLower(); - if (error == QNetworkReply::NetworkError::NoError - && statusCode == httpStatusCodeOk - && contentType == m_expectedContentType) { - return DataWithOrigin(m_reply->url(), m_reply->readAll()); - } - if (contentType == jsonContentType) { - try { - return tl::make_unexpected(DashboardError( - m_reply->url(), - statusCode, - m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(), - Dto::ErrorDto::deserialize(m_reply->readAll()))); - } catch (const Dto::invalid_dto_exception &) { - // ignore - } - } - if (statusCode != 0) { - return tl::make_unexpected(HttpError( - m_reply->url(), - statusCode, - m_reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(), - QString::fromUtf8(m_reply->readAll()))); // encoding? - } - return tl::make_unexpected( - NetworkError(m_reply->url(), error, m_reply->errorString())); + QNetworkReply::NetworkError error = reply.error(); + int statusCode = reply.attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + QString contentType = reply.header(QNetworkRequest::ContentTypeHeader) + .toString() + .split(';') + .constFirst() + .trimmed() + .toLower(); + if (error == QNetworkReply::NetworkError::NoError + && statusCode == httpStatusCodeOk + && contentType == expectedContentType) { + return DataWithOrigin(reply.url(), reply.readAll()); } - -private: - std::shared_ptr m_reply; - QAnyStringView m_expectedContentType; -}; + if (contentType == jsonContentType) { + try { + return tl::make_unexpected(DashboardError( + reply.url(), + statusCode, + reply.attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(), + Dto::ErrorDto::deserialize(reply.readAll()))); + } catch (const Dto::invalid_dto_exception &) { + // ignore + } + } + if (statusCode != 0) { + return tl::make_unexpected(HttpError( + reply.url(), + statusCode, + reply.attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(), + QString::fromUtf8(reply.readAll()))); // encoding? + } + return tl::make_unexpected( + NetworkError(reply.url(), error, reply.errorString())); +} template static Utils::expected, Error> parseResponse(ResponseData rawBody) @@ -106,11 +87,13 @@ QFuture fetch(Utils::NetworkAccessManager &networkAccessManager, const std::optional &base, const QUrl &target) { + QPromise promise; + promise.start(); const AxivionServer &server = settings().server; QUrl url = base ? base->resolved(target) : target; QNetworkRequest request{ url }; request.setRawHeader(QByteArrayLiteral(u8"Accept"), - QByteArrayLiteral(u8"Application/Json")); + QByteArray(jsonContentType.data(), jsonContentType.size())); request.setRawHeader(QByteArrayLiteral(u8"Authorization"), QByteArrayLiteral(u8"AxToken ") + server.token.toUtf8()); QByteArray ua = QByteArrayLiteral(u8"Axivion") @@ -118,10 +101,17 @@ QFuture fetch(Utils::NetworkAccessManager &networkAccessManager, + QByteArrayLiteral(u8"Plugin/") + QCoreApplication::applicationVersion().toUtf8(); request.setRawHeader(QByteArrayLiteral(u8"X-Axivion-User-Agent"), ua); - std::shared_ptr reply{ networkAccessManager.get(request), deleteLater }; - return QtFuture::connect(reply.get(), &QNetworkReply::finished) - .onCanceled(reply.get(), [reply] { reply->abort(); }) - .then(ResponseReader(reply, jsonContentType)); + QFuture future = promise.future(); + QNetworkReply* reply = networkAccessManager.get(request); + QObject::connect(reply, + &QNetworkReply::finished, + reply, + [promise = std::move(promise), reply]() mutable { + promise.addResult(readResponse(*reply, jsonContentType)); + promise.finish(); + reply->deleteLater(); + }); + return future; } QFuture DashboardClient::fetchProjectInfo(const QString &projectName) @@ -137,4 +127,4 @@ QFuture DashboardClient::fetchProjectInfo(const .then(QtFuture::Launch::Async, &parseResponse); } -} +} // namespace Axivion::Internal From f9e2942a80035f044916bd1ce3270381b5a438a3 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 14 Nov 2023 14:56:11 +0100 Subject: [PATCH 0199/1546] Bazaar: Use Core::ActionBuilder to create menu entries Change-Id: Ibae72a912dee82ef8a0b7865d69f87fd65ee8f43 Reviewed-by: Christian Stenger --- src/plugins/bazaar/bazaarplugin.cpp | 317 +++++++++--------- .../actionmanager/actionmanager.cpp | 6 + 2 files changed, 171 insertions(+), 152 deletions(-) diff --git a/src/plugins/bazaar/bazaarplugin.cpp b/src/plugins/bazaar/bazaarplugin.cpp index 8a9268748dd..cb3f116e180 100644 --- a/src/plugins/bazaar/bazaarplugin.cpp +++ b/src/plugins/bazaar/bazaarplugin.cpp @@ -209,11 +209,6 @@ public: void uncommit(); void diffFromEditorSelected(const QStringList &files); - // Functions - void createFileActions(const Core::Context &context); - void createDirectoryActions(const Core::Context &context); - void createRepositoryActions(const Core::Context &context); - // Variables BazaarClient m_client; @@ -222,8 +217,7 @@ public: [] { return new CommitEditor; }, this }; - Core::CommandLocator *m_commandLocator = nullptr; - Core::ActionContainer *m_bazaarContainer = nullptr; + CommandLocator *m_commandLocator = nullptr; QList m_repositoryActionList; @@ -354,85 +348,179 @@ BazaarPluginPrivate::BazaarPluginPrivate() m_commandLocator->setDescription(Tr::tr("Triggers a Bazaar version control operation.")); // Create menu item for Bazaar - m_bazaarContainer = ActionManager::createMenu("Bazaar.BazaarMenu"); - QMenu *menu = m_bazaarContainer->menu(); + + const Id bazaarMenuId = "Bazaar.BazaarMenu"; + ActionContainer *bazaarMenu = ActionManager::createMenu(bazaarMenuId); + QMenu *menu = bazaarMenu->menu(); menu->setTitle(Tr::tr("Bazaar")); - createFileActions(context); - m_bazaarContainer->addSeparator(context); - createDirectoryActions(context); - m_bazaarContainer->addSeparator(context); - createRepositoryActions(context); - m_bazaarContainer->addSeparator(context); + // File Actions + + ActionBuilder annotateFile(this, ANNOTATE); + annotateFile.setParameterText(Tr::tr("Annotate \"%1\""), Tr::tr("Annotate Current File")); + annotateFile.setContext(context); + annotateFile.bindContextAction(&m_annotateFile); + annotateFile.setCommandAttribute(Command::CA_UpdateText); + annotateFile.setContainer(bazaarMenuId); + annotateFile.setOnTriggered(this, [this] { annotateCurrentFile(); }); + m_commandLocator->appendCommand(annotateFile.command()); + + ActionBuilder diffFile(this, DIFF); + diffFile.setParameterText(Tr::tr("Diff \"%1\""), Tr::tr("Diff Current File")); + diffFile.setContext(context); + diffFile.bindContextAction(&m_diffFile); + diffFile.setCommandAttribute(Command::CA_UpdateText); + diffFile.setDefaultKeySequence(Tr::tr("Meta+Z,Meta+D"), Tr::tr("Alt+Z,Alt+D")); + diffFile.setContainer(bazaarMenuId); + diffFile.setOnTriggered(this, [this] { diffCurrentFile(); }); + m_commandLocator->appendCommand(diffFile.command()); + + ActionBuilder logFile(this, LOG); + logFile.setParameterText(Tr::tr("Log \"%1\""), Tr::tr("Log Current File")); + logFile.setContext(context); + logFile.bindContextAction(&m_logFile); + logFile.setCommandAttribute(Command::CA_UpdateText); + logFile.setDefaultKeySequence(Tr::tr("Meta+Z,Meta+L"), Tr::tr("Alt+Z,Alt+L")); + logFile.setContainer(bazaarMenuId); + logFile.setOnTriggered(this, [this] { logCurrentFile(); }); + m_commandLocator->appendCommand(logFile.command()); + + ActionBuilder statusFile(this, STATUS); + statusFile.setParameterText(Tr::tr("Status \"%1\""), Tr::tr("Status Current File")); + statusFile.setContext(context); + statusFile.bindContextAction(&m_statusFile); + statusFile.setCommandAttribute(Command::CA_UpdateText); + statusFile.setDefaultKeySequence(Tr::tr("Meta+Z,Meta+S"), Tr::tr("Alt+Z,Alt+S")); + statusFile.setContainer(bazaarMenuId); + statusFile.setOnTriggered(this, [this] { statusCurrentFile(); }); + m_commandLocator->appendCommand(statusFile.command()); + + bazaarMenu->addSeparator(context); + + ActionBuilder addAction(this, ADD); + addAction.bindContextAction(&m_addAction); + addAction.setParameterText(Tr::tr("Add \"%1\""), Tr::tr("Add")); + addAction.setContext(context); + addAction.setCommandAttribute(Command::CA_UpdateText); + addAction.setContainer(bazaarMenuId); + addAction.setOnTriggered(this, [this] { addCurrentFile(); }); + m_commandLocator->appendCommand(addAction.command()); + + ActionBuilder deleteAction(this, DELETE); + deleteAction.setParameterText(Tr::tr("Delete \"%1\"...") , Tr::tr("Delete...")); + deleteAction.setContext(context); + deleteAction.bindContextAction(&m_deleteAction); + deleteAction.setCommandAttribute(Command::CA_UpdateText); + deleteAction.setContainer(bazaarMenuId); + deleteAction.setOnTriggered(this, [this] { promptToDeleteCurrentFile(); }); + m_commandLocator->appendCommand(deleteAction.command()); + + ActionBuilder revertFile(this, REVERT); + revertFile.setParameterText(Tr::tr("Revert \"%1\"..."), Tr::tr("Revert Current File...")); + revertFile.setContext(context); + revertFile.bindContextAction(&m_revertFile); + revertFile.setCommandAttribute(Command::CA_UpdateText); + revertFile.setContainer(bazaarMenuId); + revertFile.setOnTriggered(this, [this] { revertCurrentFile(); }); + m_commandLocator->appendCommand(revertFile.command()); + + bazaarMenu->addSeparator(context); + + // Directory Actions + + ActionBuilder diffMulti(this, DIFFMULTI); + diffMulti.setText(Tr::tr("Diff")); + diffMulti.setContext(context); + diffMulti.setContainer(bazaarMenuId); + diffMulti.setOnTriggered(this, [this] { diffRepository(); }); + m_repositoryActionList.append(diffMulti.contextAction()); + m_commandLocator->appendCommand(diffMulti.command()); + + ActionBuilder logMulti(this, LOGMULTI); + logMulti.setText(Tr::tr("Log")); + logMulti.setContext(context); + logMulti.setContainer(bazaarMenuId); + logMulti.setOnTriggered(this, [this] { logRepository(); }); + m_repositoryActionList.append(logMulti.contextAction()); + m_commandLocator->appendCommand(logMulti.command()); + + ActionBuilder revertMulti(this, REVERTMULTI); + revertMulti.setText(Tr::tr("Revert...")); + revertMulti.setContext(context); + revertMulti.setContainer(bazaarMenuId); + revertMulti.setOnTriggered(this, [this] { revertAll(); }); + m_repositoryActionList.append(revertMulti.contextAction()); + m_commandLocator->appendCommand(revertMulti.command()); + + ActionBuilder statusMulti(this, STATUSMULTI); + statusMulti.setText(Tr::tr("Status")); + statusMulti.setContext(context); + statusMulti.setContainer(bazaarMenuId); + statusMulti.setOnTriggered(this, [this] { this->statusMulti(); }); + m_repositoryActionList.append(statusMulti.contextAction()); + m_commandLocator->appendCommand(statusMulti.command()); + + bazaarMenu->addSeparator(context); + + // Repository Actions + + ActionBuilder pull(this, PULL); + pull.setText(Tr::tr("Pull...")); + pull.setContext(context); + pull.setContainer(bazaarMenuId); + pull.setOnTriggered(this, [this] { this->pull(); }); + m_repositoryActionList.append(pull.contextAction()); + m_commandLocator->appendCommand(pull.command()); + + ActionBuilder push(this, PUSH); + push.setText(Tr::tr("Push...")); + push.setContext(context); + push.setContainer(bazaarMenuId); + push.setOnTriggered(this, [this] { this->push(); }); + m_repositoryActionList.append(push.contextAction()); + m_commandLocator->appendCommand(push.command()); + + ActionBuilder update(this, UPDATE); + update.setText(Tr::tr("Update...")); + update.setContext(context); + update.setContainer(bazaarMenuId); + update.setOnTriggered(this, [this] { this->update(); }); + m_repositoryActionList.append(update.contextAction()); + m_commandLocator->appendCommand(update.command()); + + ActionBuilder commit(this, COMMIT); + commit.setText(Tr::tr("Commit...")); + commit.setContext(context); + commit.setContainer(bazaarMenuId); + commit.setDefaultKeySequence(Tr::tr("Meta+Z,Meta+C"), Tr::tr("Alt+Z,Alt+C")); + commit.setOnTriggered(this, [this] { this->commit(); }); + m_repositoryActionList.append(commit.contextAction()); + m_commandLocator->appendCommand(commit.command()); + + ActionBuilder uncommit(this, UNCOMMIT); + uncommit.setText(Tr::tr("Uncommit...")); + uncommit.setContext(context); + uncommit.setContainer(bazaarMenuId); + uncommit.setOnTriggered(this, [this] { this->uncommit(); }); + m_repositoryActionList.append(uncommit.contextAction()); + m_commandLocator->appendCommand(uncommit.command()); + + ActionBuilder createRepository(this, CREATE_REPOSITORY); + createRepository.setText(Tr::tr("Create Repository...")); + createRepository.setContext(context); + createRepository.setContainer(bazaarMenuId); + createRepository.setOnTriggered(this, [this] { this->createRepository(); }); + + bazaarMenu->addSeparator(context); // Request the Tools menu and add the Bazaar menu to it ActionContainer *toolsMenu = ActionManager::actionContainer(Core::Constants::M_TOOLS); - toolsMenu->addMenu(m_bazaarContainer); - m_menuAction = m_bazaarContainer->menu()->menuAction(); + toolsMenu->addMenu(bazaarMenu); + m_menuAction = bazaarMenu->menu()->menuAction(); connect(&settings(), &AspectContainer::applied, this, &IVersionControl::configurationChanged); } -void BazaarPluginPrivate::createFileActions(const Context &context) -{ - m_annotateFile = new ParameterAction(Tr::tr("Annotate Current File"), Tr::tr("Annotate \"%1\""), ParameterAction::EnabledWithParameter, this); - Command *command = ActionManager::registerAction(m_annotateFile, ANNOTATE, context); - command->setAttribute(Command::CA_UpdateText); - connect(m_annotateFile, &QAction::triggered, this, &BazaarPluginPrivate::annotateCurrentFile); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); - - m_diffFile = new ParameterAction(Tr::tr("Diff Current File"), Tr::tr("Diff \"%1\""), ParameterAction::EnabledWithParameter, this); - command = ActionManager::registerAction(m_diffFile, DIFF, context); - command->setAttribute(Command::CA_UpdateText); - command->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Meta+Z,Meta+D") - : Tr::tr("Alt+Z,Alt+D"))); - connect(m_diffFile, &QAction::triggered, this, &BazaarPluginPrivate::diffCurrentFile); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); - - m_logFile = new ParameterAction(Tr::tr("Log Current File"), Tr::tr("Log \"%1\""), ParameterAction::EnabledWithParameter, this); - command = ActionManager::registerAction(m_logFile, LOG, context); - command->setAttribute(Command::CA_UpdateText); - command->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Meta+Z,Meta+L") - : Tr::tr("Alt+Z,Alt+L"))); - connect(m_logFile, &QAction::triggered, this, &BazaarPluginPrivate::logCurrentFile); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); - - m_statusFile = new ParameterAction(Tr::tr("Status Current File"), Tr::tr("Status \"%1\""), ParameterAction::EnabledWithParameter, this); - command = ActionManager::registerAction(m_statusFile, STATUS, context); - command->setAttribute(Command::CA_UpdateText); - command->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Meta+Z,Meta+S") - : Tr::tr("Alt+Z,Alt+S"))); - connect(m_statusFile, &QAction::triggered, this, &BazaarPluginPrivate::statusCurrentFile); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); - - m_bazaarContainer->addSeparator(context); - - m_addAction = new ParameterAction(Tr::tr("Add"), Tr::tr("Add \"%1\""), ParameterAction::EnabledWithParameter, this); - command = ActionManager::registerAction(m_addAction, ADD, context); - command->setAttribute(Command::CA_UpdateText); - connect(m_addAction, &QAction::triggered, this, &BazaarPluginPrivate::addCurrentFile); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); - - m_deleteAction = new ParameterAction(Tr::tr("Delete..."), Tr::tr("Delete \"%1\"..."), ParameterAction::EnabledWithParameter, this); - command = ActionManager::registerAction(m_deleteAction, DELETE, context); - command->setAttribute(Command::CA_UpdateText); - connect(m_deleteAction, &QAction::triggered, this, &BazaarPluginPrivate::promptToDeleteCurrentFile); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); - - m_revertFile = new ParameterAction(Tr::tr("Revert Current File..."), Tr::tr("Revert \"%1\"..."), ParameterAction::EnabledWithParameter, this); - command = ActionManager::registerAction(m_revertFile, REVERT, context); - command->setAttribute(Command::CA_UpdateText); - connect(m_revertFile, &QAction::triggered, this, &BazaarPluginPrivate::revertCurrentFile); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); -} - void BazaarPluginPrivate::addCurrentFile() { const VcsBasePluginState state = currentState(); @@ -481,36 +569,6 @@ void BazaarPluginPrivate::statusCurrentFile() m_client.status(state.currentFileTopLevel(), state.relativeCurrentFile()); } -void BazaarPluginPrivate::createDirectoryActions(const Context &context) -{ - auto action = new QAction(Tr::tr("Diff"), this); - m_repositoryActionList.append(action); - Command *command = ActionManager::registerAction(action, DIFFMULTI, context); - connect(action, &QAction::triggered, this, &BazaarPluginPrivate::diffRepository); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); - - action = new QAction(Tr::tr("Log"), this); - m_repositoryActionList.append(action); - command = ActionManager::registerAction(action, LOGMULTI, context); - connect(action, &QAction::triggered, this, &BazaarPluginPrivate::logRepository); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); - - action = new QAction(Tr::tr("Revert..."), this); - m_repositoryActionList.append(action); - command = ActionManager::registerAction(action, REVERTMULTI, context); - connect(action, &QAction::triggered, this, &BazaarPluginPrivate::revertAll); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); - - action = new QAction(Tr::tr("Status"), this); - m_repositoryActionList.append(action); - command = ActionManager::registerAction(action, STATUSMULTI, context); - connect(action, &QAction::triggered, this, &BazaarPluginPrivate::statusMulti); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); -} void BazaarPluginPrivate::diffRepository() { @@ -546,51 +604,6 @@ void BazaarPluginPrivate::statusMulti() m_client.status(state.topLevel()); } -void BazaarPluginPrivate::createRepositoryActions(const Context &context) -{ - auto action = new QAction(Tr::tr("Pull..."), this); - m_repositoryActionList.append(action); - Command *command = ActionManager::registerAction(action, PULL, context); - connect(action, &QAction::triggered, this, &BazaarPluginPrivate::pull); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); - - action = new QAction(Tr::tr("Push..."), this); - m_repositoryActionList.append(action); - command = ActionManager::registerAction(action, PUSH, context); - connect(action, &QAction::triggered, this, &BazaarPluginPrivate::push); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); - - action = new QAction(Tr::tr("Update..."), this); - m_repositoryActionList.append(action); - command = ActionManager::registerAction(action, UPDATE, context); - connect(action, &QAction::triggered, this, &BazaarPluginPrivate::update); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); - - action = new QAction(Tr::tr("Commit..."), this); - m_repositoryActionList.append(action); - command = ActionManager::registerAction(action, COMMIT, context); - command->setDefaultKeySequence(QKeySequence(useMacShortcuts ? Tr::tr("Meta+Z,Meta+C") - : Tr::tr("Alt+Z,Alt+C"))); - connect(action, &QAction::triggered, this, &BazaarPluginPrivate::commit); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); - - action = new QAction(Tr::tr("Uncommit..."), this); - m_repositoryActionList.append(action); - command = ActionManager::registerAction(action, UNCOMMIT, context); - connect(action, &QAction::triggered, this, &BazaarPluginPrivate::uncommit); - m_bazaarContainer->addAction(command); - m_commandLocator->appendCommand(command); - - auto createRepositoryAction = new QAction(Tr::tr("Create Repository..."), this); - command = ActionManager::registerAction(createRepositoryAction, CREATE_REPOSITORY, context); - connect(createRepositoryAction, &QAction::triggered, this, &BazaarPluginPrivate::createRepository); - m_bazaarContainer->addAction(command); -} - void BazaarPluginPrivate::pull() { const VcsBasePluginState state = currentState(); diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index 1ba658837d7..b1b1aedd55a 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -255,6 +255,12 @@ void ActionBuilder::bindContextAction(QAction **dest) *dest = d->action; } +void ActionBuilder::bindContextAction(Utils::ParameterAction **dest) +{ + QTC_ASSERT(dest, return); + *dest = d->action; +} + void ActionBuilder::augmentActionWithShortcutToolTip() { d->command->augmentActionWithShortcutToolTip(d->action); From 3939ba93af8c6cc0dbd55cdb23a7c4c48539ac2a Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Tue, 7 Nov 2023 17:57:09 +0100 Subject: [PATCH 0200/1546] qtcreatorcdbext: Deploy lldb on Windows Starting with LLVM 17.0.1 we include lldb in the list of packages compiled on Windows. This commit deploys lldb.exe and its Python required machinery. Fixes: QTCREATORBUG-14539 Change-Id: I7f44c537cbaf31bf2f065762bdc9a48dd5efc64d Reviewed-by: Qt CI Bot Reviewed-by: David Schulz Reviewed-by: Eike Ziller --- scripts/build.py | 5 ++++- src/libs/qtcreatorcdbext/CMakeLists.txt | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/scripts/build.py b/scripts/build.py index 72c7d3571ad..6cd795a744f 100755 --- a/scripts/build.py +++ b/scripts/build.py @@ -245,7 +245,10 @@ def build_qtcreatorcdbext(args, paths): return if not os.path.exists(paths.qtcreatorcdbext_build): os.makedirs(paths.qtcreatorcdbext_build) - prefix_paths = [common.to_posix_path(os.path.abspath(fp)) for fp in args.prefix_paths] + prefix_paths = [os.path.abspath(fp) for fp in args.prefix_paths] + if paths.llvm: + prefix_paths += [paths.llvm] + prefix_paths = [common.to_posix_path(fp) for fp in prefix_paths] cmake_args = ['-DCMAKE_PREFIX_PATH=' + ';'.join(prefix_paths), '-DCMAKE_INSTALL_PREFIX=' + common.to_posix_path(paths.qtcreatorcdbext_install)] cmake_args += common_cmake_arguments(args) diff --git a/src/libs/qtcreatorcdbext/CMakeLists.txt b/src/libs/qtcreatorcdbext/CMakeLists.txt index 07a5493de34..97307164f65 100644 --- a/src/libs/qtcreatorcdbext/CMakeLists.txt +++ b/src/libs/qtcreatorcdbext/CMakeLists.txt @@ -201,4 +201,24 @@ if (_library_enabled) COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${deployPythonFiles} "${output_binary_dir}/lib/qtcreatorcdbext${ArchSuffix}/" VERBATIM ) + + # Deploy lldb.exe and its Python dependency + find_package(Clang QUIET) + if (LLVM_TOOLS_BINARY_DIR AND LLVM_LIBRARY_DIRS) + foreach(lldb_file lldb.exe lldb-vscode.exe liblldb.dll python311.zip python311.dll) + if (EXISTS ${LLVM_TOOLS_BINARY_DIR}/${lldb_file}) + install(FILES ${LLVM_TOOLS_BINARY_DIR}/${lldb_file} + DESTINATION bin/clang/bin + COMPONENT qtcreatorcdbext) + endif() + endforeach() + + if (EXISTS ${LLVM_LIBRARY_DIRS}/site-packages) + install(DIRECTORY ${LLVM_LIBRARY_DIRS}/site-packages + DESTINATION bin/clang/lib + COMPONENT qtcreatorcdbext + PATTERN _lldb.cp311-win_amd64.pyd EXCLUDE) + endif() + endif() + endif() From 35a2d598ab070a0c9e7fb72b332cbaed6728da9f Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Wed, 8 Nov 2023 15:30:40 +0100 Subject: [PATCH 0201/1546] Utils: Add SynchronizedValue Change-Id: I0af6998f540ba688fa54d9e43e33cb3cb0fc54e8 Reviewed-by: hjk --- src/libs/utils/synchronizedvalue.h | 370 ++++++++++++++++++ tests/auto/utils/CMakeLists.txt | 1 + .../utils/synchronizedvalue/CMakeLists.txt | 4 + .../synchronizedvalue/synchronizedvalue.qbs | 7 + .../tst_synchronizedvalue.cpp | 219 +++++++++++ tests/auto/utils/utils.qbs | 1 + 6 files changed, 602 insertions(+) create mode 100644 src/libs/utils/synchronizedvalue.h create mode 100644 tests/auto/utils/synchronizedvalue/CMakeLists.txt create mode 100644 tests/auto/utils/synchronizedvalue/synchronizedvalue.qbs create mode 100644 tests/auto/utils/synchronizedvalue/tst_synchronizedvalue.cpp diff --git a/src/libs/utils/synchronizedvalue.h b/src/libs/utils/synchronizedvalue.h new file mode 100644 index 00000000000..a95104ec4cb --- /dev/null +++ b/src/libs/utils/synchronizedvalue.h @@ -0,0 +1,370 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include +#include +#include + +namespace Utils { + +/*! + \brief A wrapper that provides thread-safe access to the wrapped type using a read/write mutex. + + Examples: + + \code + + void writeAndGet() { + SynchronizedValue synchronizedString; + // To update the value of the synchronized object, you can use the write function. + synchronizedString.write([](QString &str) { str = "Hello World"; }); + + // If you just need a value from the synchronized object, you can use the get function + qDebug() << "New value is:" << synchronizedString.get([](const QString &str) { return str; }); + } + + void read() { + SynchronizedValue> synchronized; + + QString both; + + // If you want to access multiple members of the synchronized object, you can use the read function + synchronized.read([&both](const QPair &pair) { + qDebug() << "First value is:" << pair.first(); + qDebug() << "Second value is:" << pair.second(); + both = pair.first() + pair.second(); + // ... + }); + } + + // You can use the SynchronizedValue::update() to return whether the value was changed: + void setString(const QString &newString) { + const bool wasChanged = m_synchronizedString.update([&newString](QString &str) { + if (newString == str) + return false; + str = newString; + return true; + })); + + if (wasChanged) + emit stringChanged(newString); + } + + // You can also use a lock type to get access + void withLocks() { + SynchronizedValue synchronizedData; + *synchronizedData.writeLocked() = "Hello World"; + qDebug() << *synchronizedData.readLocked() << "== Hello World"; + + auto lk = synchronizedData.writeLocked(); + assert(lk.ownsLock()); + *lk = "I am locked"; + } + + \endcode +*/ +template +class SynchronizedValue +{ + template + friend std::tuple synchronize(SV &...sv); + +public: + SynchronizedValue() = default; + + SynchronizedValue(const SynchronizedValue &other) + { + std::shared_lock lk(other.mutex); + value = other.value; + } + + SynchronizedValue(const T &other) + : value(other) + {} + + class shared_lock + { + public: + shared_lock(T const &value_, std::shared_mutex &mutex) + : lock(mutex) + , value(value_) + {} + + shared_lock(T const &value_, std::shared_mutex &mutex, std::try_to_lock_t) + : lock(mutex, std::try_to_lock) + , value(value_) + {} + + shared_lock(T const &value_, std::shared_mutex &mutex, std::defer_lock_t) + : lock(mutex, std::defer_lock) + , value(value_) + {} + + shared_lock(T const &value_, std::shared_mutex &mutex, std::adopt_lock_t) + : lock(mutex, std::adopt_lock) + , value(value_) + {} + + bool ownsLock() const { return lock.owns_lock(); } + + const T *operator->() const + { + Q_ASSERT(ownsLock()); + return &value; + } + + const T &operator*() const + { + Q_ASSERT(ownsLock()); + return value; + } + + private: + std::shared_lock lock; + T const &value; + }; + + class unique_lock + { + public: + unique_lock(T &value_, std::shared_mutex &mutex) + : lock(mutex) + , value(value_) + {} + + unique_lock(T &value_, std::shared_mutex &mutex, std::try_to_lock_t) + : lock(mutex, std::try_to_lock) + , value(value_) + {} + + unique_lock(T &value_, std::shared_mutex &mutex, std::defer_lock_t) + : lock(mutex, std::defer_lock) + , value(value_) + {} + + unique_lock(T &value_, std::shared_mutex &mutex, std::adopt_lock_t) + : lock(mutex, std::adopt_lock) + , value(value_) + {} + + bool ownsLock() const { return lock.owns_lock(); } + + T *operator->() const + { + Q_ASSERT(ownsLock()); + return &value; + } + + T &operator*() const + { + Q_ASSERT(ownsLock()); + return value; + } + + private: + std::unique_lock lock; + T &value; + }; + + [[nodiscard]] shared_lock readLocked() const { return shared_lock(value, mutex); } + [[nodiscard]] shared_lock readLocked(std::try_to_lock_t) const + { + return shared_lock(value, mutex, std::try_to_lock); + } + + [[nodiscard]] unique_lock writeLocked() { return unique_lock(value, mutex); } + [[nodiscard]] unique_lock writeLocked(std::try_to_lock_t) + { + return unique_lock(value, mutex, std::try_to_lock); + } + + //! Call func with a const reference to the wrapped object + void read(const std::function &func) const + { + std::shared_lock lk(mutex); + func(value); + } + + //! Call func with a const reference to the wrapped object and returns the result of func + template + [[nodiscard]] R get(const std::function &func) const + { + std::shared_lock lk(mutex); + return func(value); + } + + [[nodiscard]] T get() const + { + std::shared_lock lk(mutex); + return value; + } + + //! Call func with a mutable reference to the wrapped object + void write(const std::function &func) + { + std::unique_lock lk(mutex); + func(value); + } + + //! Call func with a mutable reference to the wrapped object and returns the result of func + template + [[nodiscard]] R update(const std::function &func) + { + std::unique_lock lk(mutex); + return func(value); + } + + SynchronizedValue &operator=(const SynchronizedValue &other) + { + std::unique_lock lk(mutex, std::defer_lock); + std::shared_lock lkOther(other.mutex, std::defer_lock); + std::lock(lk, lkOther); + value = other.value; + return *this; + } + + SynchronizedValue &operator=(const T &other) + { + std::unique_lock lk(mutex); + value = other; + return *this; + } + + bool operator!=(const SynchronizedValue &rhs) const + { + std::shared_lock lk(mutex, std ::defer_lock); + std::shared_lock lkOther(rhs.mutex, std ::defer_lock); + std::lock(lk, lkOther); + return value != rhs.value; + } + + bool operator==(const SynchronizedValue &rhs) const + { + std::shared_lock lk(mutex, std ::defer_lock); + std::shared_lock lkOther(rhs.mutex, std ::defer_lock); + std::lock(lk, lkOther); + return value == rhs.value; + } + + bool operator<(const SynchronizedValue &rhs) const + { + std::shared_lock lk(mutex, std ::defer_lock); + std::shared_lock lkOther(rhs.mutex, std ::defer_lock); + std::lock(lk, lkOther); + return value < rhs.value; + } + + bool operator<=(const SynchronizedValue &rhs) const + { + std::shared_lock lk(mutex, std ::defer_lock); + std::shared_lock lkOther(rhs.mutex, std ::defer_lock); + std::lock(lk, lkOther); + return value <= rhs.value; + } + + bool operator>(const SynchronizedValue &rhs) const + { + std::shared_lock lk(mutex, std ::defer_lock); + std::shared_lock lkOther(rhs.mutex, std ::defer_lock); + std::lock(lk, lkOther); + return value > rhs.value; + } + + bool operator>=(const SynchronizedValue &rhs) const + { + std::shared_lock lk(mutex, std ::defer_lock); + std::shared_lock lkOther(rhs.mutex, std ::defer_lock); + std::lock(lk, lkOther); + return value >= rhs.value; + } + + bool operator>(const T &rhs) const + { + std::shared_lock lk(mutex); + return value > rhs; + } + + bool operator>=(const T &rhs) const + { + std::shared_lock lk(mutex); + return value >= rhs; + } + + bool operator!=(const T &rhs) const + { + std::shared_lock lk(mutex); + return value != rhs; + } + + bool operator==(const T &rhs) const + { + std::shared_lock lk(mutex); + return value == rhs; + } + + bool operator<(const T &rhs) const + { + std::shared_lock lk(mutex); + return value < rhs; + } + + bool operator<=(const T &rhs) const + { + std::shared_lock lk(mutex); + return value <= rhs; + } + +private: + template + friend bool operator!=(const L &lhs, const SynchronizedValue &rhs) + { + return rhs != lhs; + } + + template + friend bool operator==(const L &lhs, const SynchronizedValue &rhs) + { + return rhs == lhs; + } + + template + friend bool operator<(const L &lhs, const SynchronizedValue &rhs) + { + return rhs > lhs; + } + + template + friend bool operator<=(const L &lhs, const SynchronizedValue &rhs) + { + return rhs >= lhs; + } + + template + friend bool operator>(const L &lhs, const SynchronizedValue &rhs) + { + return rhs < lhs; + } + + template + friend bool operator>=(const L &lhs, const SynchronizedValue &rhs) + { + return rhs <= lhs; + } + +private: + mutable std::shared_mutex mutex; + T value; +}; + +//! Lock a number of SynchronizedValue's using a dead-lock free algorithm. ( see std::lock() ) +template +std::tuple synchronize(SV &...sv) +{ + std::lock(sv.mutex...); + typedef std::tuple t_type; + return t_type(typename SV::unique_lock(sv.value, sv.mutex, std::adopt_lock)...); +} + +} // namespace Utils diff --git a/tests/auto/utils/CMakeLists.txt b/tests/auto/utils/CMakeLists.txt index e78cb3380cc..d19ac4acd63 100644 --- a/tests/auto/utils/CMakeLists.txt +++ b/tests/auto/utils/CMakeLists.txt @@ -8,6 +8,7 @@ add_subdirectory(fileutils) add_subdirectory(fsengine) add_subdirectory(fuzzymatcher) add_subdirectory(indexedcontainerproxyconstiterator) +add_subdirectory(synchronizedvalue) add_subdirectory(mathutils) add_subdirectory(multicursor) add_subdirectory(persistentsettings) diff --git a/tests/auto/utils/synchronizedvalue/CMakeLists.txt b/tests/auto/utils/synchronizedvalue/CMakeLists.txt new file mode 100644 index 00000000000..2e3d679d7fb --- /dev/null +++ b/tests/auto/utils/synchronizedvalue/CMakeLists.txt @@ -0,0 +1,4 @@ +add_qtc_test(tst_utils_synchronizedvalue + DEPENDS Utils + SOURCES tst_synchronizedvalue.cpp +) diff --git a/tests/auto/utils/synchronizedvalue/synchronizedvalue.qbs b/tests/auto/utils/synchronizedvalue/synchronizedvalue.qbs new file mode 100644 index 00000000000..d001951d3fa --- /dev/null +++ b/tests/auto/utils/synchronizedvalue/synchronizedvalue.qbs @@ -0,0 +1,7 @@ +import qbs + +QtcAutotest { + name: "synchronizedvalue autotest" + Depends { name: "Utils" } + files: "tst_synchronizedvalue.cpp" +} diff --git a/tests/auto/utils/synchronizedvalue/tst_synchronizedvalue.cpp b/tests/auto/utils/synchronizedvalue/tst_synchronizedvalue.cpp new file mode 100644 index 00000000000..6a1d8fe8cfc --- /dev/null +++ b/tests/auto/utils/synchronizedvalue/tst_synchronizedvalue.cpp @@ -0,0 +1,219 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include + +#include + +#include + +namespace Utils { + +struct TestData +{ + TestData() = default; + TestData(int iValue) + : i(iValue) + {} + + bool operator==(const TestData &other) const { return i == other.i && str == other.str; } + bool operator!=(const TestData &other) const { return !(*this == other); } + QString str; + int i{20}; +}; + +class tst_synchronizedvalue : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase() {} + + void read() + { + SynchronizedValue data; + + data.read([](const auto &d) { + QCOMPARE(d.str, QString()); + QCOMPARE(d.i, 20); + }); + } + + void ctor() + { + SynchronizedValue data(200); + QCOMPARE(data.get([](const auto &d) { return d.i; }), 200); + } + + void initializerCtor() + { + SynchronizedValue> data({1, 2, 3}); + QCOMPARE(data.get>([](const auto &d) { return d; }), QList({1, 2, 3})); + } + + void get() + { + SynchronizedValue data(200); + QCOMPARE(data.get([](const auto &d) { return d.i; }), 200); + } + + void constLock() + { + SynchronizedValue data(200); + QCOMPARE(data.readLocked()->i, 200); + QCOMPARE(data.get().i, 200); + + auto lk = data.readLocked(); + QCOMPARE(lk->i, 200); + + // This should fail to compile: + // data.readLocked()->i = 200; + } + + void lock() + { + SynchronizedValue data(123); + data.writeLocked()->i = 200; + QCOMPARE(data.get([](const auto &d) { return d.i; }), 200); + + { + auto wlk = data.writeLocked(); + wlk->str = "Write locked"; + } + + QCOMPARE(data.readLocked()->str, "Write locked"); + + SynchronizedValue lockedStr("Hello World"); + QCOMPARE(*lockedStr.readLocked(), "Hello World"); + *lockedStr.writeLocked() = "Hello World 2"; + QCOMPARE(*lockedStr.readLocked(), "Hello World 2"); + } + + void trivialGet() + { + SynchronizedValue data(200); + TestData d = data.get(); + QCOMPARE(data, d); + QCOMPARE(d.i, 200); + } + + void equalop() + { + SynchronizedValue data(200); + SynchronizedValue data2(300); + + data = data2; + + QCOMPARE(data.get([](const auto &d) { return d.i; }), 300); + QCOMPARE(data2.get([](const auto &d) { return d.i; }), 300); + + TestData dataNoLock(1337); + data = dataNoLock; + + QCOMPARE(data.get([](const auto &d) { return d.i; }), 1337); + } + + void compareEq() + { + SynchronizedValue data(200); + SynchronizedValue data2(300); + + QVERIFY(data != data2); + QVERIFY(!(data == data2)); + + data2.write([](auto &d) { d.i = 200; }); + + QVERIFY(data == data2); + QVERIFY(!(data != data2)); + } + + void operators() + { + SynchronizedValue data(200); + SynchronizedValue data2(300); + + QVERIFY(data < data2); + QVERIFY(data <= data2); + QVERIFY(data2 > data); + QVERIFY(data2 >= data); + QVERIFY(data2 != data); + QVERIFY(!(data2 == data)); + + QVERIFY(data > 100); + QVERIFY(data >= 100); + QVERIFY(data >= 200); + QVERIFY(data < 300); + QVERIFY(data <= 300); + + QVERIFY(100 < data); + QVERIFY(200 <= data); + QVERIFY(199 <= data); + QVERIFY(300 > data); + QVERIFY(200 >= data); + QVERIFY(201 >= data); + QVERIFY(200 == data); + QVERIFY(200 != data2); + } + + void copyCtor() + { + SynchronizedValue data(123); + SynchronizedValue data2(data); + + QCOMPARE(data.get([](const auto &d) { return d.i; }), 123); + QCOMPARE(data2.get([](const auto &d) { return d.i; }), 123); + + TestData dataNoLock(1337); + SynchronizedValue data3(dataNoLock); + + QCOMPARE(data3.get([](const auto &d) { return d.i; }), 1337); + } + + void multilock() + { + SynchronizedValue value(100); + + // Multiple reader, no writer + { + QCOMPARE(value.get(), 100); + auto firstLock = value.readLocked(); + QVERIFY(firstLock.ownsLock()); + auto secondLock = value.readLocked(); + QVERIFY(secondLock.ownsLock()); + + QCOMPARE(*firstLock, 100); + QCOMPARE(*secondLock, 100); + + auto thirdLock = value.writeLocked(std::try_to_lock); + QVERIFY(!thirdLock.ownsLock()); + } + + // Single writer, no readers + { + auto firstLock = value.writeLocked(); + QVERIFY(firstLock.ownsLock()); + auto secondLock = value.writeLocked(std::try_to_lock); + QVERIFY(!secondLock.ownsLock()); + + auto readLock = value.readLocked(std::try_to_lock); + QVERIFY(!readLock.ownsLock()); + } + } + + void synchronizeMultiple() + { + SynchronizedValue sv1; + SynchronizedValue sv2; + + auto [lk1, lk2] = synchronize(sv1, sv2); + + QVERIFY(lk1.ownsLock()); + QVERIFY(lk2.ownsLock()); + } +}; + +} // namespace Utils + +QTEST_GUILESS_MAIN(Utils::tst_synchronizedvalue) + +#include "tst_synchronizedvalue.moc" diff --git a/tests/auto/utils/utils.qbs b/tests/auto/utils/utils.qbs index 9f5a580435a..a8329b582c7 100644 --- a/tests/auto/utils/utils.qbs +++ b/tests/auto/utils/utils.qbs @@ -13,6 +13,7 @@ Project { "fsengine/fsengine.qbs", "fuzzymatcher/fuzzymatcher.qbs", "indexedcontainerproxyconstiterator/indexedcontainerproxyconstiterator.qbs", + "synchronizedvalue/synchronizedvalue.qbs", "mathutils/mathutils.qbs", "multicursor/multicursor.qbs", "persistentsettings/persistentsettings.qbs", From 8ae0e3dbf8dfff3fe2ffb2976fd151433a07edb9 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 15 Nov 2023 14:39:28 +0100 Subject: [PATCH 0202/1546] Bazaar: Make create repository a global action Also initialize text of parameter actions when defining the parameter action. Avoids empty items if the setParameter() call is done too late. Change-Id: I5e3398e5e537fc65f5c9c43cd62345b322f3143d Reviewed-by: hjk --- src/plugins/bazaar/bazaarplugin.cpp | 1 - src/plugins/coreplugin/actionmanager/actionmanager.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/bazaar/bazaarplugin.cpp b/src/plugins/bazaar/bazaarplugin.cpp index cb3f116e180..dea15cd2249 100644 --- a/src/plugins/bazaar/bazaarplugin.cpp +++ b/src/plugins/bazaar/bazaarplugin.cpp @@ -507,7 +507,6 @@ BazaarPluginPrivate::BazaarPluginPrivate() ActionBuilder createRepository(this, CREATE_REPOSITORY); createRepository.setText(Tr::tr("Create Repository...")); - createRepository.setContext(context); createRepository.setContainer(bazaarMenuId); createRepository.setOnTriggered(this, [this] { this->createRepository(); }); diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index b1b1aedd55a..dcaa32115b6 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -227,6 +227,7 @@ void ActionBuilder::setParameterText(const QString ¶meterText, d->action->setEnablingMode(mode == AlwaysEnabled ? ParameterAction::AlwaysEnabled : ParameterAction::EnabledWithParameter); + d->action->setText(emptyText); } Command *ActionBuilder::command() const From 5fcf4048467cd957b34364bce1699ad7b12309e2 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 14 Nov 2023 13:51:52 +0100 Subject: [PATCH 0203/1546] TextEditor: Consider angle brackets as braces too When performing "surround with brackets" allow this feature for angle brackets as well. Change-Id: I4192fd832aa3e692d9287b5b873e9ea31ec2b7e3 Reviewed-by: David Schulz --- src/plugins/texteditor/autocompleter.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/texteditor/autocompleter.cpp b/src/plugins/texteditor/autocompleter.cpp index 6a48718a20d..dccd5ecda3d 100644 --- a/src/plugins/texteditor/autocompleter.cpp +++ b/src/plugins/texteditor/autocompleter.cpp @@ -104,6 +104,8 @@ static QString surroundSelectionWithBrackets(const QString &textToInsert, const replacement = selection + QLatin1Char(')'); } else if (textToInsert == QLatin1String("[")) { replacement = selection + QLatin1Char(']'); + } else if (textToInsert == QLatin1String("<")) { + replacement = selection + QLatin1Char('>'); } else if (textToInsert == QLatin1String("{")) { //If the text spans multiple lines, insert on different lines replacement = selection; From 1049f8d329856d8846698578504af18398a4343a Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Wed, 15 Nov 2023 14:46:42 +0100 Subject: [PATCH 0204/1546] Utils: Remove unnecessary flag Change-Id: Iae99b5fd6d3740015deb0e30d45d480ffb54c4a2 Reviewed-by: Christian Stenger --- tests/auto/utils/filepath/filepath.qbs | 4 ---- tests/auto/utils/fileutils/fileutils.qbs | 4 ---- .../auto/utils/unixdevicefileaccess/unixdevicefileaccess.qbs | 4 ---- 3 files changed, 12 deletions(-) diff --git a/tests/auto/utils/filepath/filepath.qbs b/tests/auto/utils/filepath/filepath.qbs index 73c106b2e8c..61fd74ec764 100644 --- a/tests/auto/utils/filepath/filepath.qbs +++ b/tests/auto/utils/filepath/filepath.qbs @@ -3,9 +3,5 @@ import qbs QtcAutotest { name: "FilePath autotest" Depends { name: "Utils" } - Properties { - condition: qbs.toolchain.contains("gcc") - cpp.cxxFlags: base.concat(["-Wno-trigraphs"]) - } files: "tst_filepath.cpp" } diff --git a/tests/auto/utils/fileutils/fileutils.qbs b/tests/auto/utils/fileutils/fileutils.qbs index e19452481ed..96c1e1a5382 100644 --- a/tests/auto/utils/fileutils/fileutils.qbs +++ b/tests/auto/utils/fileutils/fileutils.qbs @@ -3,9 +3,5 @@ import qbs QtcAutotest { name: "FileUtils autotest" Depends { name: "Utils" } - Properties { - condition: qbs.toolchain.contains("gcc") - cpp.cxxFlags: base.concat(["-Wno-trigraphs"]) - } files: "tst_fileutils.cpp" } diff --git a/tests/auto/utils/unixdevicefileaccess/unixdevicefileaccess.qbs b/tests/auto/utils/unixdevicefileaccess/unixdevicefileaccess.qbs index 1776ef4a6ee..c7a6d26a80d 100644 --- a/tests/auto/utils/unixdevicefileaccess/unixdevicefileaccess.qbs +++ b/tests/auto/utils/unixdevicefileaccess/unixdevicefileaccess.qbs @@ -3,9 +3,5 @@ import qbs QtcAutotest { name: "UnixDeviceFileAccess autotest" Depends { name: "Utils" } - Properties { - condition: qbs.toolchain.contains("gcc") - cpp.cxxFlags: base.concat(["-Wno-trigraphs"]) - } files: "tst_unixdevicefileaccess.cpp" } From 62ad0014f12ed05863f408b9b748856222e27a58 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 7 Nov 2023 19:17:41 +0100 Subject: [PATCH 0205/1546] TaskTree test: Simplify subprocess name Fix the qbs build. Amends 63bfeba87f3ce2d42655548dfb097dc9e0bf26ab Change-Id: I271e5059ba8becf4aade8ce21ff9f40201f3734b Reviewed-by: Christian Stenger --- tests/auto/solutions/qprocesstask/CMakeLists.txt | 2 +- tests/auto/solutions/qprocesstask/qprocesstask.qbs | 2 +- tests/auto/solutions/qprocesstask/testsleep/testsleep.qbs | 3 +++ tests/auto/solutions/qprocesstask/tst_qprocesstask.cpp | 8 +------- 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/tests/auto/solutions/qprocesstask/CMakeLists.txt b/tests/auto/solutions/qprocesstask/CMakeLists.txt index dab250943cf..c1b1fd5396a 100644 --- a/tests/auto/solutions/qprocesstask/CMakeLists.txt +++ b/tests/auto/solutions/qprocesstask/CMakeLists.txt @@ -1,7 +1,7 @@ add_subdirectory(testsleep) add_qtc_test(tst_qprocesstask - DEFINES "PROCESS_TESTAPP=\"${CMAKE_CURRENT_BINARY_DIR}/testsleep\"" + DEFINES "PROCESS_TESTAPP=\"${CMAKE_CURRENT_BINARY_DIR}/testsleep/testsleep\"" DEPENDS Tasking Qt::Network SOURCES tst_qprocesstask.cpp ) diff --git a/tests/auto/solutions/qprocesstask/qprocesstask.qbs b/tests/auto/solutions/qprocesstask/qprocesstask.qbs index c1bc1ce889d..863c1b0bd82 100644 --- a/tests/auto/solutions/qprocesstask/qprocesstask.qbs +++ b/tests/auto/solutions/qprocesstask/qprocesstask.qbs @@ -15,7 +15,7 @@ Project { if (qbs.targetOS === "windows") defines.push("_CRT_SECURE_NO_WARNINGS"); defines.push('PROCESS_TESTAPP="' - + FileInfo.joinPaths(destinationDirectory, "testsleep") + '"'); + + FileInfo.joinPaths(destinationDirectory, "testsleep/testsleep") + '"'); return defines; } destinationDirectory: project.buildDirectory + '/' diff --git a/tests/auto/solutions/qprocesstask/testsleep/testsleep.qbs b/tests/auto/solutions/qprocesstask/testsleep/testsleep.qbs index ae9bbd9431d..5d8db7b2f8f 100644 --- a/tests/auto/solutions/qprocesstask/testsleep/testsleep.qbs +++ b/tests/auto/solutions/qprocesstask/testsleep/testsleep.qbs @@ -9,4 +9,7 @@ QtApplication { files: [ "main.cpp", ] + + destinationDirectory: project.buildDirectory + '/' + + FileInfo.relativePath(project.ide_source_tree, sourceDirectory) } diff --git a/tests/auto/solutions/qprocesstask/tst_qprocesstask.cpp b/tests/auto/solutions/qprocesstask/tst_qprocesstask.cpp index f4bff2e0981..3efd3fe465e 100644 --- a/tests/auto/solutions/qprocesstask/tst_qprocesstask.cpp +++ b/tests/auto/solutions/qprocesstask/tst_qprocesstask.cpp @@ -15,16 +15,10 @@ private slots: void qProcessTask(); }; -#ifdef Q_OS_WIN -static const char s_processName[] = "testsleep.exe"; -#else -static const char s_processName[] = "testsleep"; -#endif - void tst_QProcessTask::qProcessTask() { const auto setupProcess = [](QProcess &process) { - process.setProgram(QLatin1String(PROCESS_TESTAPP) + '/' + s_processName); + process.setProgram(QLatin1String(PROCESS_TESTAPP)); }; { From b6569b933313ba329f3614327207112a250d9f75 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 9 Aug 2023 18:32:32 +0200 Subject: [PATCH 0206/1546] QmlProjectManager: Allow opening remote .qmlproject This get rid of two instances of FilePath::toString and allows now to opens the default wizard-generated "Qt Quick UI Prototype" .qmlproject. As the QmlBuildSystem is still heavily tied to the local file system this here is only a baby step towards fully functionial remote .qmlproject support. Change-Id: I940f99472d45d9ade4966cf4f15b0692a51f2e7b Reviewed-by: Christian Stenger --- .../buildsystem/projectitem/converters.cpp | 2 +- .../buildsystem/projectitem/qmlprojectitem.cpp | 2 +- .../qmlprojectmanager/buildsystem/qmlbuildsystem.cpp | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp b/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp index ce0233fcf20..c77189a8b6c 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/projectitem/converters.cpp @@ -186,7 +186,7 @@ QJsonObject qmlProjectTojson(const Utils::FilePath &projectFile) { QmlJS::SimpleReader simpleQmlJSReader; - const QmlJS::SimpleReaderNode::Ptr rootNode = simpleQmlJSReader.readFile(projectFile.toString()); + const QmlJS::SimpleReaderNode::Ptr rootNode = simpleQmlJSReader.readFile(projectFile.toFSPathString()); if (!simpleQmlJSReader.errors().isEmpty() || !rootNode->isValid()) { qCritical() << "Unable to parse:" << projectFile; diff --git a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp index 99ad0826549..2761caff089 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/projectitem/qmlprojectitem.cpp @@ -78,7 +78,7 @@ void QmlProjectItem::setupFileFilters() fileFilterItem->setRecursive(fileGroup["recursive"].toBool(true)); fileFilterItem->setPathsProperty(fileGroup["directories"].toVariant().toStringList()); fileFilterItem->setPathsProperty(filesArr); - fileFilterItem->setDefaultDirectory(m_projectFile.parentDir().toString()); + fileFilterItem->setDefaultDirectory(m_projectFile.parentDir().toFSPathString()); #ifndef TESTS_ENABLED_QMLPROJECTITEM connect(fileFilterItem.get(), &FileFilterItem::filesChanged, diff --git a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp index 4016cc6ac6f..60107e469e0 100644 --- a/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp +++ b/src/plugins/qmlprojectmanager/buildsystem/qmlbuildsystem.cpp @@ -228,9 +228,9 @@ void QmlBuildSystem::parseProjectFiles() } - Utils::FilePath mainFilePath{Utils::FilePath::fromString(m_projectItem->mainFile())}; - if (!mainFilePath.isEmpty()) { - mainFilePath = canonicalProjectDir().resolvePath(m_projectItem->mainFile()); + const QString mainFileName = m_projectItem->mainFile(); + if (!mainFileName.isEmpty()) { + Utils::FilePath mainFilePath = canonicalProjectDir().resolvePath(mainFileName); Utils::FileReader reader; QString errorMessage; if (!reader.fetch(mainFilePath, &errorMessage)) { From f8671f3e3cb95b1c4911304955129045d4e110ce Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Tue, 14 Nov 2023 12:13:38 +0100 Subject: [PATCH 0207/1546] Utils: Introduce StyleHelper::UiFont() for centralized font definitions Custom font sizes of UI texts like titles and subtitles were usually defined on the spot in code. With the upcoming focus on unified fonts and colors in Qt Creator, a centralization of font styles in needed. This adds the font getter function StyleHelper::UiFont() and the enum UiElement that specifies types as H1..H6 and some custom ones. Change-Id: Ie0d6e6fb51fe24d8aee6b4242941cbff45fe3853 Reviewed-by: hjk Reviewed-by: Artem Sokolovskii --- src/libs/utils/stylehelper.cpp | 32 ++++++++++++++++++++++++++++++++ src/libs/utils/stylehelper.h | 11 +++++++++++ 2 files changed, 43 insertions(+) diff --git a/src/libs/utils/stylehelper.cpp b/src/libs/utils/stylehelper.cpp index 49a83234258..e3a68b90c96 100644 --- a/src/libs/utils/stylehelper.cpp +++ b/src/libs/utils/stylehelper.cpp @@ -938,4 +938,36 @@ QColor StyleHelper::ensureReadableOn(const QColor &background, const QColor &des return foreground; } +QFont StyleHelper::UiFont(UiElement element) +{ + QFont font; + + constexpr qreal panelTitleSize = HostOsInfo::isMacHost() ? 10 : 7.5; + + switch (element) { + case UiElementH1: + font.setPointSizeF(font.pointSizeF() * 1.6); + font.setBold(true); + break; + case UiElementH2: + font.setPointSizeF(font.pointSizeF() * 1.2); + font.setBold(true); + break; + case UiElementH3: + break; + case UiElementH4: + break; + case UiElementPanelTitle: { + font.setPointSizeF(panelTitleSize); + font.setBold(true); + break; + } + case UiElementPanelSubtitle: + font.setPointSizeF(panelTitleSize); + break; + } + + return font; +} + } // namespace Utils diff --git a/src/libs/utils/stylehelper.h b/src/libs/utils/stylehelper.h index a7656b3eb3a..b493c031001 100644 --- a/src/libs/utils/stylehelper.h +++ b/src/libs/utils/stylehelper.h @@ -47,6 +47,15 @@ enum ToolbarStyle { }; constexpr ToolbarStyle defaultToolbarStyle = ToolbarStyleCompact; +enum UiElement { + UiElementH1, + UiElementH2, + UiElementH3, + UiElementH4, + UiElementPanelTitle, + UiElementPanelSubtitle, +}; + // Height of the project explorer navigation bar QTCREATOR_UTILS_EXPORT int navigationWidgetHeight(); QTCREATOR_UTILS_EXPORT void setToolbarStyle(ToolbarStyle style); @@ -73,6 +82,8 @@ QTCREATOR_UTILS_EXPORT QColor sidebarShadow(); QTCREATOR_UTILS_EXPORT QColor toolBarDropShadowColor(); QTCREATOR_UTILS_EXPORT QColor notTooBrightHighlightColor(); +QTCREATOR_UTILS_EXPORT QFont UiFont(UiElement element); + // Sets the base color and makes sure all top level widgets are updated QTCREATOR_UTILS_EXPORT void setBaseColor(const QColor &color); From 6c57c519816e06df292559452fb2c8b91a7933d7 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Wed, 15 Nov 2023 10:37:30 +0100 Subject: [PATCH 0208/1546] Use StyleHelper::UiFont() Change-Id: I0c09578b76c48ddb255f44bb6117089dd092a72c Reviewed-by: hjk --- src/libs/utils/stylehelper.cpp | 5 ----- src/libs/utils/stylehelper.h | 1 - src/plugins/coreplugin/dialogs/settingsdialog.cpp | 12 +++--------- src/plugins/coreplugin/fancyactionbar.cpp | 10 +++------- src/plugins/coreplugin/fancytabwidget.cpp | 8 ++------ .../coreplugin/progressmanager/progressbar.cpp | 13 +++---------- .../coreplugin/progressmanager/progressbar.h | 1 - .../coreplugin/progressmanager/progressmanager.cpp | 4 +--- src/plugins/projectexplorer/buildprogress.cpp | 5 +---- .../projectexplorer/buildsettingspropertiespage.cpp | 11 +++-------- src/plugins/projectexplorer/panelswidget.cpp | 5 +---- src/plugins/projectexplorer/projectwindow.cpp | 9 +++------ .../projectexplorer/runsettingspropertiespage.cpp | 12 +++--------- src/plugins/projectexplorer/targetsettingspanel.cpp | 6 ++---- src/plugins/scxmleditor/common/dragshapebutton.cpp | 7 ++++--- src/plugins/welcome/introductionwidget.cpp | 4 +--- 16 files changed, 30 insertions(+), 83 deletions(-) diff --git a/src/libs/utils/stylehelper.cpp b/src/libs/utils/stylehelper.cpp index e3a68b90c96..5e76ee3386e 100644 --- a/src/libs/utils/stylehelper.cpp +++ b/src/libs/utils/stylehelper.cpp @@ -94,11 +94,6 @@ StyleHelper::ToolbarStyle StyleHelper::toolbarStyle() return s_toolbarStyle; } -qreal StyleHelper::sidebarFontSize() -{ - return HostOsInfo::isMacHost() ? 10 : 7.5; -} - QColor StyleHelper::notTooBrightHighlightColor() { QColor highlightColor = QApplication::palette().highlight().color(); diff --git a/src/libs/utils/stylehelper.h b/src/libs/utils/stylehelper.h index b493c031001..4cda97ff569 100644 --- a/src/libs/utils/stylehelper.h +++ b/src/libs/utils/stylehelper.h @@ -60,7 +60,6 @@ enum UiElement { QTCREATOR_UTILS_EXPORT int navigationWidgetHeight(); QTCREATOR_UTILS_EXPORT void setToolbarStyle(ToolbarStyle style); QTCREATOR_UTILS_EXPORT ToolbarStyle toolbarStyle(); -QTCREATOR_UTILS_EXPORT qreal sidebarFontSize(); QTCREATOR_UTILS_EXPORT QPalette sidebarFontPalette(const QPalette &original); // This is our color table, all colors derive from baseColor diff --git a/src/plugins/coreplugin/dialogs/settingsdialog.cpp b/src/plugins/coreplugin/dialogs/settingsdialog.cpp index 1fd3220680a..3d890b8515e 100644 --- a/src/plugins/coreplugin/dialogs/settingsdialog.cpp +++ b/src/plugins/coreplugin/dialogs/settingsdialog.cpp @@ -9,10 +9,11 @@ #include "../iwizardfactory.h" #include +#include #include #include -#include #include +#include #include #include @@ -569,14 +570,7 @@ void SettingsDialog::showPage(const Id pageId) void SettingsDialog::createGui() { - // Header label with large font and a bit of spacing (align with group boxes) - QFont headerLabelFont = m_headerLabel->font(); - headerLabelFont.setBold(true); - // Paranoia: Should a font be set in pixels... - const int pointSize = headerLabelFont.pointSize(); - if (pointSize > 0) - headerLabelFont.setPointSize(pointSize + 2); - m_headerLabel->setFont(headerLabelFont); + m_headerLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); auto headerHLayout = new QHBoxLayout; const int leftMargin = QApplication::style()->pixelMetric(QStyle::PM_LayoutLeftMargin); diff --git a/src/plugins/coreplugin/fancyactionbar.cpp b/src/plugins/coreplugin/fancyactionbar.cpp index a07dd718976..908e002791c 100644 --- a/src/plugins/coreplugin/fancyactionbar.cpp +++ b/src/plugins/coreplugin/fancyactionbar.cpp @@ -181,11 +181,9 @@ void FancyToolButton::paintEvent(QPaintEvent *event) const bool isTitledAction = defaultAction() && defaultAction()->property("titledAction").toBool(); // draw popup texts if (isTitledAction && !m_iconsOnly) { - QFont normalFont(painter.font()); + const QFont normalFont = StyleHelper::UiFont(StyleHelper::UiElementPanelSubtitle); QRect centerRect = rect(); - normalFont.setPointSizeF(StyleHelper::sidebarFontSize()); - QFont boldFont(normalFont); - boldFont.setBold(true); + const QFont boldFont = StyleHelper::UiFont(StyleHelper::UiElementPanelTitle); const QFontMetrics fm(normalFont); const QFontMetrics boldFm(boldFont); const int lineHeight = boldFm.height(); @@ -286,9 +284,7 @@ QSize FancyToolButton::sizeHint() const QSizeF buttonSize = iconSize().expandedTo(QSize(64, 38)); if (defaultAction() && defaultAction()->property("titledAction").toBool()) { - QFont boldFont(font()); - boldFont.setPointSizeF(StyleHelper::sidebarFontSize()); - boldFont.setBold(true); + const QFont boldFont = StyleHelper::UiFont(StyleHelper::UiElementPanelTitle); const QFontMetrics fm(boldFont); const qreal lineHeight = fm.height(); const int extraHeight = 10 // Spacing between top and projectName diff --git a/src/plugins/coreplugin/fancytabwidget.cpp b/src/plugins/coreplugin/fancytabwidget.cpp index 85935b27987..19b0dfda475 100644 --- a/src/plugins/coreplugin/fancytabwidget.cpp +++ b/src/plugins/coreplugin/fancytabwidget.cpp @@ -68,9 +68,7 @@ QSize FancyTabBar::tabSizeHint(bool minimum) const Core::Constants::MODEBAR_ICONSONLY_BUTTON_SIZE / (minimum ? 3 : 1)}; } - QFont boldFont(font()); - boldFont.setPointSizeF(StyleHelper::sidebarFontSize()); - boldFont.setBold(true); + const QFont boldFont = StyleHelper::UiFont(StyleHelper::UiElementPanelTitle); const QFontMetrics fm(boldFont); const int spacing = 8; const int width = 60 + spacing + 2; @@ -285,9 +283,7 @@ static void paintIconAndText(QPainter *painter, const QRect &rect, const QIcon &icon, const QString &text, bool enabled, bool selected) { - QFont boldFont(painter->font()); - boldFont.setPointSizeF(StyleHelper::sidebarFontSize()); - boldFont.setBold(true); + const QFont boldFont = StyleHelper::UiFont(StyleHelper::UiElementPanelTitle); painter->setFont(boldFont); const bool drawIcon = rect.height() > 36; diff --git a/src/plugins/coreplugin/progressmanager/progressbar.cpp b/src/plugins/coreplugin/progressmanager/progressbar.cpp index 689263534c6..fa1a3041658 100644 --- a/src/plugins/coreplugin/progressmanager/progressbar.cpp +++ b/src/plugins/coreplugin/progressmanager/progressbar.cpp @@ -166,7 +166,8 @@ QSize ProgressBar::sizeHint() const int width = 50; int height = PROGRESSBAR_HEIGHT + 5; if (m_titleVisible) { - const QFontMetrics fm(titleFont()); + const QFont font = StyleHelper::UiFont(StyleHelper::UiElementPanelTitle); + const QFontMetrics fm(font); width = qMax(width, fm.horizontalAdvance(m_title) + 16); height += fm.height() + 5; if (!m_subtitle.isEmpty()) { @@ -192,14 +193,6 @@ void ProgressBar::mouseReleaseEvent(QMouseEvent *event) QWidget::mouseReleaseEvent(event); } -QFont ProgressBar::titleFont() const -{ - QFont boldFont(font()); - boldFont.setPointSizeF(StyleHelper::sidebarFontSize()); - boldFont.setBold(true); - return boldFont; -} - void ProgressBar::mouseMoveEvent(QMouseEvent *ev) { update(); @@ -220,7 +213,7 @@ void ProgressBar::paintEvent(QPaintEvent *) percent = 1; QPainter p(this); - const QFont fnt(titleFont()); + const QFont fnt = StyleHelper::UiFont(StyleHelper::UiElementPanelTitle); const QFontMetrics fm(fnt); const int titleHeight = m_titleVisible ? fm.height() + 5 : 4; diff --git a/src/plugins/coreplugin/progressmanager/progressbar.h b/src/plugins/coreplugin/progressmanager/progressbar.h index 0762cdf833d..a56373bfa67 100644 --- a/src/plugins/coreplugin/progressmanager/progressbar.h +++ b/src/plugins/coreplugin/progressmanager/progressbar.h @@ -52,7 +52,6 @@ protected: void mouseReleaseEvent(QMouseEvent *event) override; private: - QFont titleFont() const; QFont subtitleFont() const; QString m_text; diff --git a/src/plugins/coreplugin/progressmanager/progressmanager.cpp b/src/plugins/coreplugin/progressmanager/progressmanager.cpp index a2d61902b1c..c7bc22f2a6c 100644 --- a/src/plugins/coreplugin/progressmanager/progressmanager.cpp +++ b/src/plugins/coreplugin/progressmanager/progressmanager.cpp @@ -661,9 +661,7 @@ void ProgressManagerPrivate::updateStatusDetailsWidget() } else if (progress->isSubtitleVisibleInStatusBar() && !progress->subtitle().isEmpty()) { if (!m_statusDetailsLabel) { m_statusDetailsLabel = new QLabel(m_summaryProgressWidget); - QFont font(m_statusDetailsLabel->font()); - font.setPointSizeF(StyleHelper::sidebarFontSize()); - font.setBold(true); + const QFont font = StyleHelper::UiFont(StyleHelper::UiElementPanelTitle); m_statusDetailsLabel->setFont(font); } m_statusDetailsLabel->setText(progress->subtitle()); diff --git a/src/plugins/projectexplorer/buildprogress.cpp b/src/plugins/projectexplorer/buildprogress.cpp index 7166ab474d9..d6c654ce5cc 100644 --- a/src/plugins/projectexplorer/buildprogress.cpp +++ b/src/plugins/projectexplorer/buildprogress.cpp @@ -49,10 +49,7 @@ BuildProgress::BuildProgress(TaskWindow *taskWindow, Qt::Orientation orientation warningLayout->addWidget(m_warningIcon); warningLayout->addWidget(m_warningLabel); - // ### TODO this setup should be done by style - QFont f = this->font(); - f.setPointSizeF(Utils::StyleHelper::sidebarFontSize()); - f.setBold(true); + const QFont f = Utils::StyleHelper::UiFont(Utils::StyleHelper::UiElementPanelTitle); m_errorLabel->setFont(f); m_warningLabel->setFont(f); m_errorLabel->setPalette(Utils::StyleHelper::sidebarFontPalette(m_errorLabel->palette())); diff --git a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp index 2caa44712e0..a53e489d82d 100644 --- a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include @@ -54,9 +54,7 @@ BuildSettingsWidget::BuildSettingsWidget(Target *target) : if (!BuildConfigurationFactory::find(m_target)) { auto noSettingsLabel = new QLabel(this); noSettingsLabel->setText(Tr::tr("No build settings available")); - QFont f = noSettingsLabel->font(); - f.setPointSizeF(f.pointSizeF() * 1.2); - noSettingsLabel->setFont(f); + noSettingsLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); vbox->addWidget(noSettingsLabel); return; } @@ -128,10 +126,7 @@ void BuildSettingsWidget::addSubWidget(NamedWidget *widget) auto label = new QLabel(this); label->setText(widget->displayName()); - QFont f = label->font(); - f.setBold(true); - f.setPointSizeF(f.pointSizeF() * 1.2); - label->setFont(f); + label->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); label->setContentsMargins(0, 18, 0, 0); diff --git a/src/plugins/projectexplorer/panelswidget.cpp b/src/plugins/projectexplorer/panelswidget.cpp index e83eb9045c8..38843bfe8d7 100644 --- a/src/plugins/projectexplorer/panelswidget.cpp +++ b/src/plugins/projectexplorer/panelswidget.cpp @@ -100,10 +100,7 @@ void PanelsWidget::addPropertiesPanel(const QString &displayName) auto nameLabel = new QLabel(m_root); nameLabel->setText(displayName); nameLabel->setContentsMargins(0, ABOVE_HEADING_MARGIN, 0, 0); - QFont f = nameLabel->font(); - f.setBold(true); - f.setPointSizeF(f.pointSizeF() * 1.6); - nameLabel->setFont(f); + nameLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH1)); m_layout->addWidget(nameLabel); m_layout->addWidget(Layouting::createHr()); } diff --git a/src/plugins/projectexplorer/projectwindow.cpp b/src/plugins/projectexplorer/projectwindow.cpp index cd4b2321174..44e62bc5279 100644 --- a/src/plugins/projectexplorer/projectwindow.cpp +++ b/src/plugins/projectexplorer/projectwindow.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -569,10 +570,7 @@ public: selectorView->setAutoFillBackground(true); auto activeLabel = new QLabel(Tr::tr("Active Project")); - QFont font = activeLabel->font(); - font.setBold(true); - font.setPointSizeF(font.pointSizeF() * 1.2); - activeLabel->setFont(font); + activeLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); auto innerLayout = new QVBoxLayout; innerLayout->setSpacing(10); @@ -905,8 +903,7 @@ void SelectorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti case 2: { QColor col = creatorTheme()->color(Theme::TextColorNormal); opt.palette.setColor(QPalette::Text, col); - opt.font.setBold(true); - opt.font.setPointSizeF(opt.font.pointSizeF() * 1.2); + opt.font = StyleHelper::UiFont(StyleHelper::UiElementH2); break; } } diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.cpp b/src/plugins/projectexplorer/runsettingspropertiespage.cpp index 2c675b0a043..a4800e41ea1 100644 --- a/src/plugins/projectexplorer/runsettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/runsettingspropertiespage.cpp @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include @@ -69,10 +69,7 @@ RunSettingsWidget::RunSettingsWidget(Target *target) : runLabel->setBuddy(m_runConfigurationCombo); - QFont f = runLabel->font(); - f.setBold(true); - f.setPointSizeF(f.pointSizeF() * 1.2); - + const QFont f = Utils::StyleHelper::UiFont(Utils::StyleHelper::UiElementH2); runTitle->setFont(f); deployTitle->setFont(f); @@ -501,10 +498,7 @@ void RunSettingsWidget::addSubWidget(QWidget *widget, QLabel *label) { widget->setContentsMargins({}); - QFont f = label->font(); - f.setBold(true); - f.setPointSizeF(f.pointSizeF() * 1.2); - label->setFont(f); + label->setFont(Utils::StyleHelper::UiFont(Utils::StyleHelper::UiElementH2)); label->setContentsMargins(0, 18, 0, 0); diff --git a/src/plugins/projectexplorer/targetsettingspanel.cpp b/src/plugins/projectexplorer/targetsettingspanel.cpp index 0a95a7219b5..dba282b51d8 100644 --- a/src/plugins/projectexplorer/targetsettingspanel.cpp +++ b/src/plugins/projectexplorer/targetsettingspanel.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -184,10 +185,7 @@ void TargetGroupItemPrivate::ensureWidget() auto label = new QLabel; label->setText(Tr::tr("No kit defined in this project.")); - QFont f = label->font(); - f.setPointSizeF(f.pointSizeF() * 1.4); - f.setBold(true); - label->setFont(f); + label->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); label->setContentsMargins(10, 10, 10, 10); label->setAlignment(Qt::AlignTop); diff --git a/src/plugins/scxmleditor/common/dragshapebutton.cpp b/src/plugins/scxmleditor/common/dragshapebutton.cpp index a644479ecf8..307827cb00e 100644 --- a/src/plugins/scxmleditor/common/dragshapebutton.cpp +++ b/src/plugins/scxmleditor/common/dragshapebutton.cpp @@ -3,6 +3,9 @@ #include "dragshapebutton.h" #include "baseitem.h" + +#include + #include #include #include @@ -17,9 +20,7 @@ DragShapeButton::DragShapeButton(QWidget *parent) setMinimumSize(75, 75); setMaximumSize(75, 75); setIconSize(QSize(45, 45)); - QFont f = font(); - f.setPointSize(8); - setFont(f); + setFont(Utils::StyleHelper::UiFont(Utils::StyleHelper::UiElementPanelSubtitle)); } void DragShapeButton::setShapeInfo(int groupIndex, int shapeIndex) diff --git a/src/plugins/welcome/introductionwidget.cpp b/src/plugins/welcome/introductionwidget.cpp index d89805037af..28e25fbf61f 100644 --- a/src/plugins/welcome/introductionwidget.cpp +++ b/src/plugins/welcome/introductionwidget.cpp @@ -78,9 +78,7 @@ IntroductionWidget::IntroductionWidget(QWidget *parent) m_continueLabel->setAlignment(Qt::AlignCenter); m_continueLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); m_continueLabel->setWordWrap(true); - auto fnt = font(); - fnt.setPointSizeF(fnt.pointSizeF() * 1.5); - m_continueLabel->setFont(fnt); + m_continueLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH1)); m_continueLabel->setPalette(palette()); layout->addWidget(m_continueLabel); m_bodyCss = "font-size: 16px;"; From 37ed2ce42f1309038bf16d34dfc90d9949158382 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 9 Nov 2023 01:17:07 +0100 Subject: [PATCH 0209/1546] TaskTree: Add tests for ConcurrentCall Change-Id: I493ab170656a61a841614dff87495fa324336c45 Reviewed-by: hjk --- src/libs/solutions/tasking/concurrentcall.h | 17 +- tests/auto/solutions/CMakeLists.txt | 1 + .../solutions/concurrentcall/CMakeLists.txt | 4 + .../concurrentcall/concurrentcall.qbs | 8 + .../concurrentcall/tst_concurrentcall.cpp | 243 ++++++++++++++++++ tests/auto/solutions/solutions.qbs | 1 + tests/auto/utils/async/tst_async.cpp | 10 +- 7 files changed, 271 insertions(+), 13 deletions(-) create mode 100644 tests/auto/solutions/concurrentcall/CMakeLists.txt create mode 100644 tests/auto/solutions/concurrentcall/concurrentcall.qbs create mode 100644 tests/auto/solutions/concurrentcall/tst_concurrentcall.cpp diff --git a/src/libs/solutions/tasking/concurrentcall.h b/src/libs/solutions/tasking/concurrentcall.h index d9a757c9ad3..6298b053724 100644 --- a/src/libs/solutions/tasking/concurrentcall.h +++ b/src/libs/solutions/tasking/concurrentcall.h @@ -31,6 +31,10 @@ public: { return m_future.resultCount() ? m_future.result() : ResultType(); } + QList results() const + { + return m_future.results(); + } QFuture future() const { return m_future; } private: @@ -38,9 +42,8 @@ private: void wrapConcurrent(Function &&function, Args &&...args) { m_startHandler = [=] { - if (m_threadPool) - return QtConcurrent::run(m_threadPool, function, args...); - return QtConcurrent::run(function, args...); + QThreadPool *threadPool = m_threadPool ? m_threadPool : QThreadPool::globalInstance(); + return QtConcurrent::run(threadPool, function, args...); }; } @@ -48,11 +51,9 @@ private: void wrapConcurrent(std::reference_wrapper &&wrapper, Args &&...args) { m_startHandler = [=] { - if (m_threadPool) { - return QtConcurrent::run(m_threadPool, - std::forward(wrapper.get()), args...); - } - return QtConcurrent::run(std::forward(wrapper.get()), args...); + QThreadPool *threadPool = m_threadPool ? m_threadPool : QThreadPool::globalInstance(); + return QtConcurrent::run(threadPool, std::forward(wrapper.get()), + args...); }; } diff --git a/tests/auto/solutions/CMakeLists.txt b/tests/auto/solutions/CMakeLists.txt index 848b48eca9a..b17f5c90453 100644 --- a/tests/auto/solutions/CMakeLists.txt +++ b/tests/auto/solutions/CMakeLists.txt @@ -1,2 +1,3 @@ +add_subdirectory(concurrentcall) add_subdirectory(qprocesstask) add_subdirectory(tasking) diff --git a/tests/auto/solutions/concurrentcall/CMakeLists.txt b/tests/auto/solutions/concurrentcall/CMakeLists.txt new file mode 100644 index 00000000000..28339eac881 --- /dev/null +++ b/tests/auto/solutions/concurrentcall/CMakeLists.txt @@ -0,0 +1,4 @@ +add_qtc_test(tst_concurrentcall + DEPENDS Tasking Qt::Concurrent Qt::Network + SOURCES tst_concurrentcall.cpp +) diff --git a/tests/auto/solutions/concurrentcall/concurrentcall.qbs b/tests/auto/solutions/concurrentcall/concurrentcall.qbs new file mode 100644 index 00000000000..12bd0cb8cfc --- /dev/null +++ b/tests/auto/solutions/concurrentcall/concurrentcall.qbs @@ -0,0 +1,8 @@ +QtcAutotest { + name: "ConcurrentCall autotest" + + Depends { name: "Qt"; submodules: ["concurrent", "network"] } + Depends { name: "Tasking" } + + files: "tst_concurrentcall.cpp" +} diff --git a/tests/auto/solutions/concurrentcall/tst_concurrentcall.cpp b/tests/auto/solutions/concurrentcall/tst_concurrentcall.cpp new file mode 100644 index 00000000000..8195238005a --- /dev/null +++ b/tests/auto/solutions/concurrentcall/tst_concurrentcall.cpp @@ -0,0 +1,243 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include + +#include + +using namespace Tasking; + +using namespace std::chrono; +using namespace std::chrono_literals; + +class MyObject +{ +public: + static void staticMember(QPromise &promise, int n) + { + for (int i = 0; i < n; ++i) + promise.addResult(0); + } + + void member(QPromise &promise, int n) const + { + for (int i = 0; i < n; ++i) + promise.addResult(0); + } +}; + +class tst_ConcurrentCall : public QObject +{ + Q_OBJECT + +private slots: + // void futureSynchonizer(); + void taskTree_data(); + void taskTree(); + +private: + QThreadPool m_threadPool; + MyObject m_myObject; +}; + +struct TestData +{ + TreeStorage storage; + Group root; +}; + +void report3(QPromise &promise) +{ + promise.addResult(0); + promise.addResult(2); + promise.addResult(1); +} + +static void staticReport3(QPromise &promise) +{ + promise.addResult(0); + promise.addResult(2); + promise.addResult(1); +} + +void reportN(QPromise &promise, int n) +{ + for (int i = 0; i < n; ++i) + promise.addResult(0); +} + +static void staticReportN(QPromise &promise, int n) +{ + for (int i = 0; i < n; ++i) + promise.addResult(0); +} + +class Functor { +public: + void operator()(QPromise &promise, int n) const + { + for (int i = 0; i < n; ++i) + promise.addResult(0); + } +}; + +// void tst_ConcurrentCall::futureSynchonizer() +// { +// auto lambda = [](QPromise &promise) { +// while (true) { +// if (promise.isCanceled()) { +// promise.future().cancel(); +// promise.finish(); +// return; +// } +// QThread::msleep(100); +// } +// }; + +// FutureSynchronizer synchronizer; +// synchronizer.setCancelOnWait(false); +// { +// Async task; +// task.setConcurrentCallData(lambda); +// task.setFutureSynchronizer(&synchronizer); +// task.start(); +// QThread::msleep(10); +// // We assume here that worker thread will still work for about 90 ms. +// QVERIFY(!task.isCanceled()); +// QVERIFY(!task.isDone()); +// } +// synchronizer.flushFinishedFutures(); +// QVERIFY(!synchronizer.isEmpty()); +// // The destructor of synchronizer should wait for about 90 ms for worker thread to be canceled +// } + +void multiplyBy2(QPromise &promise, int input) { promise.addResult(input * 2); } + +template +struct FutureArgType; + +template +struct FutureArgType> +{ + using Type = Arg; +}; + +template +struct ConcurrentResultType; + +template +struct ConcurrentResultType +{ + using Type = typename FutureArgType(), std::declval()...))>::Type; +}; + +template ::Type> +TestData createTestData(const QList &expectedResults, Function &&function, Args &&...args) +{ + TreeStorage storage; + + const auto onSetup = [=](ConcurrentCall &task) { + task.setConcurrentCallData(function, args...); + }; + const auto onDone = [storage, expectedResults](const ConcurrentCall &task) { + *storage = task.results() == expectedResults; + }; + + const Group root { + Storage(storage), + ConcurrentCallTask(onSetup, onDone) + }; + + return TestData{storage, root}; +} + +void tst_ConcurrentCall::taskTree_data() +{ + QTest::addColumn("testData"); + + const QList report3Result{0, 2, 1}; + const QList reportNResult{0, 0}; + + auto lambda = [](QPromise &promise, int n) { + for (int i = 0; i < n; ++i) + promise.addResult(0); + }; + const std::function &, int)> fun = [](QPromise &promise, int n) { + for (int i = 0; i < n; ++i) + promise.addResult(0); + }; + + QTest::newRow("RefGlobalNoArgs") + << createTestData(report3Result, &report3); + QTest::newRow("GlobalNoArgs") + << createTestData(report3Result, report3); + QTest::newRow("RefStaticNoArgs") + << createTestData(report3Result, &staticReport3); + QTest::newRow("StaticNoArgs") + << createTestData(report3Result, staticReport3); + QTest::newRow("RefGlobalIntArg") + << createTestData(reportNResult, &reportN, 2); + QTest::newRow("GlobalIntArg") + << createTestData(reportNResult, reportN, 2); + QTest::newRow("RefStaticIntArg") + << createTestData(reportNResult, &staticReportN, 2); + QTest::newRow("StaticIntArg") + << createTestData(reportNResult, staticReportN, 2); + QTest::newRow("Lambda") + << createTestData(reportNResult, lambda, 2); + QTest::newRow("Function") + << createTestData(reportNResult, fun, 2); + QTest::newRow("Functor") + << createTestData(reportNResult, Functor(), 2); + QTest::newRow("StaticMemberFunction") + << createTestData(reportNResult, &MyObject::staticMember, 2); + QTest::newRow("MemberFunction") + << createTestData(reportNResult, &MyObject::member, &m_myObject, 2); + + { + TreeStorage storage; + TreeStorage internalStorage; + + const auto onSetup = [internalStorage](ConcurrentCall &task) { + task.setConcurrentCallData(multiplyBy2, *internalStorage); + }; + const auto onDone = [internalStorage](const ConcurrentCall &task) { + *internalStorage = task.result(); + }; + + const Group root { + Storage(storage), + Storage(internalStorage), + onGroupSetup([internalStorage] { *internalStorage = 1; }), + ConcurrentCallTask(onSetup, onDone, CallDoneIf::Success), + ConcurrentCallTask(onSetup, onDone, CallDoneIf::Success), + ConcurrentCallTask(onSetup, onDone, CallDoneIf::Success), + ConcurrentCallTask(onSetup, onDone, CallDoneIf::Success), + onGroupDone([storage, internalStorage] { *storage = *internalStorage == 16; }) + }; + + QTest::newRow("Sequential") << TestData{storage, root}; + } +} + +void tst_ConcurrentCall::taskTree() +{ + QFETCH(TestData, testData); + + TaskTree taskTree({testData.root.withTimeout(1000ms)}); + bool actualResult = false; + const auto collectResult = [&actualResult](const bool &storage) { + actualResult = storage; + }; + taskTree.onStorageDone(testData.storage, collectResult); + const DoneWith result = taskTree.runBlocking(); + QCOMPARE(taskTree.isRunning(), false); + QCOMPARE(result, DoneWith::Success); + QVERIFY(actualResult); +} + +QTEST_GUILESS_MAIN(tst_ConcurrentCall) + +#include "tst_concurrentcall.moc" diff --git a/tests/auto/solutions/solutions.qbs b/tests/auto/solutions/solutions.qbs index b96095f3dbe..d36316a550f 100644 --- a/tests/auto/solutions/solutions.qbs +++ b/tests/auto/solutions/solutions.qbs @@ -3,6 +3,7 @@ import qbs Project { name: "Solutions autotests" references: [ + "concurrentcall/concurrentcall.qbs", "qprocesstask/qprocesstask.qbs", "tasking/tasking.qbs", ] diff --git a/tests/auto/utils/async/tst_async.cpp b/tests/auto/utils/async/tst_async.cpp index ee7025bad1d..0c3174d794d 100644 --- a/tests/auto/utils/async/tst_async.cpp +++ b/tests/auto/utils/async/tst_async.cpp @@ -62,7 +62,7 @@ void reportString2(QPromise &promise, QString s) promise.addResult(s); } -class Callable { +class Functor { public: void operator()(QPromise &promise, int n) const { @@ -262,11 +262,11 @@ void tst_Async::runAsync() QList({0, 0})); // operator() - QCOMPARE(createAsyncTask(Callable(), 3)->results(), + QCOMPARE(createAsyncTask(Functor(), 3)->results(), QList({0, 0, 0})); - QCOMPARE(Utils::asyncRun(Callable(), 3).results(), + QCOMPARE(Utils::asyncRun(Functor(), 3).results(), QList({0, 0, 0})); - const Callable c{}; + const Functor c{}; QCOMPARE(createAsyncTask(c, 2)->results(), QList({0, 0})); QCOMPARE(Utils::asyncRun(c, 2).results(), @@ -361,7 +361,7 @@ void tst_Async::crefFunction() QList({0, 0})); // callable with promise - const Callable c{}; + const Functor c{}; QCOMPARE(createAsyncTask(std::cref(c), 2)->results(), QList({0, 0})); QCOMPARE(Utils::asyncRun(std::cref(c), 2).results(), From e38c84d5db48a494f4508e3c188a01bce0648d4c Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 15 Nov 2023 14:00:11 +0100 Subject: [PATCH 0210/1546] Tests: Fix warning and test execution on Windows Avoids warning C4566: character represented by universal-character-name '\u23F0' cannot be represented in the current code page (1252) and the resulting test fail on Windows. Change-Id: I2bdd43b0648a954faa9e444df79a91027e6e891f Reviewed-by: Alessandro Portale --- tests/auto/utils/stringutils/tst_stringutils.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/utils/stringutils/tst_stringutils.cpp b/tests/auto/utils/stringutils/tst_stringutils.cpp index 9219ef7c8b0..0b5c5cd1527 100644 --- a/tests/auto/utils/stringutils/tst_stringutils.cpp +++ b/tests/auto/utils/stringutils/tst_stringutils.cpp @@ -448,7 +448,7 @@ void tst_StringUtils::testAsciify_data() QTest::newRow("Basic Latin") << QString("Basic text") << QString("Basic text"); QTest::newRow("Control character") << QString("\x07 text") << QString("u0007 text"); - QTest::newRow("Miscellaneous Technical") << QString("\u23F0 text") << QString("u23f0 text"); + QTest::newRow("Miscellaneous Technical") << QString(u8"\u23F0 text") << QString("u23f0 text"); } void tst_StringUtils::testAsciify() From ec722b9132657f8884c5a813592af4d0871ad03f Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 16 Nov 2023 09:20:19 +0100 Subject: [PATCH 0211/1546] DeviceShell tests: Use ProcessLauncher for shell process It looks like after recent switch to QProcess impl for Utils::Process, the DeviceShell::m_shellProcess blocks in DeviceShell::installShellScript() on a call to m_shellProcess->waitForReadyRead(5000). Until it's solved, bring back the ProcessLauncher impl for the shell process to unlock the CI tests. Amends a53dfaf623c3167ae07e8360e7cf9599e2904f24 Change-Id: I085ea5c1ae4f169c7c77acb8702ed48de0a95bac Reviewed-by: Christian Stenger --- src/libs/utils/deviceshell.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/utils/deviceshell.cpp b/src/libs/utils/deviceshell.cpp index 6d99d399841..f459e33d255 100644 --- a/src/libs/utils/deviceshell.cpp +++ b/src/libs/utils/deviceshell.cpp @@ -163,6 +163,8 @@ CommandLine DeviceShell::createFallbackCommand(const CommandLine &cmd) expected_str DeviceShell::start() { m_shellProcess = std::make_unique(); + // FIXME: This shouldn't be needed, it's a temporary workaround. + m_shellProcess->setProcessImpl(ProcessImpl::ProcessLauncher); connect(m_shellProcess.get(), &Process::done, m_shellProcess.get(), [this] { emit done(m_shellProcess->resultData()); }); connect(&m_thread, &QThread::finished, m_shellProcess.get(), [this] { closeShellProcess(); }, Qt::DirectConnection); From 6a8d7edd6fc84543d86c4dc4d788df141a9eb72e Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Nov 2023 09:44:06 +0100 Subject: [PATCH 0212/1546] ProjectExplorer: Temporarily leak ProjectPanelFactories The follow-up changes will remove dynamic allocations for ProjectPanelFactories one-by-one, so the leak will vanish in the end. For now this prevents double deletion during shutdown in the transition period. Change-Id: I24d3ad4a2f300a7af782e1973d9817061af39c18 Reviewed-by: Christian Stenger Reviewed-by: --- src/plugins/projectexplorer/projectexplorer.cpp | 1 - src/plugins/projectexplorer/projectpanelfactory.cpp | 6 ------ src/plugins/projectexplorer/projectpanelfactory.h | 3 --- 3 files changed, 10 deletions(-) diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 264b08a2467..3e6131b36d5 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -785,7 +785,6 @@ ProjectExplorerPlugin::~ProjectExplorerPlugin() // Force sequence of deletion: KitManager::destroy(); // remove all the profile information delete dd->m_toolChainManager; - ProjectPanelFactory::destroyFactories(); delete dd; dd = nullptr; m_instance = nullptr; diff --git a/src/plugins/projectexplorer/projectpanelfactory.cpp b/src/plugins/projectexplorer/projectpanelfactory.cpp index 06ffafff5d2..4a4881e3f8c 100644 --- a/src/plugins/projectexplorer/projectpanelfactory.cpp +++ b/src/plugins/projectexplorer/projectpanelfactory.cpp @@ -54,12 +54,6 @@ QList ProjectPanelFactory::factories() return s_factories; } -void ProjectPanelFactory::destroyFactories() -{ - qDeleteAll(s_factories); - s_factories.clear(); -} - Utils::Id ProjectPanelFactory::id() const { return m_id; diff --git a/src/plugins/projectexplorer/projectpanelfactory.h b/src/plugins/projectexplorer/projectpanelfactory.h index cb54df80aa6..5eb12c2ea34 100644 --- a/src/plugins/projectexplorer/projectpanelfactory.h +++ b/src/plugins/projectexplorer/projectpanelfactory.h @@ -53,9 +53,6 @@ public: ProjectSettingsWidget *createWidget(Project *project) const; private: - friend class ProjectExplorerPlugin; - static void destroyFactories(); - Utils::Id m_id; int m_priority = 0; QString m_displayName; From 8a727b594895ac548ec82e2756ad3d055b0890ab Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 14 Nov 2023 17:47:02 +0100 Subject: [PATCH 0213/1546] GitLab: Use new construction pattern for project panel factory Change-Id: I7a52d1a914daf64cb74214628c7f4728d32dbf5d Reviewed-by: Christian Stenger --- src/plugins/gitlab/gitlabplugin.cpp | 10 ++-- src/plugins/gitlab/gitlabprojectsettings.cpp | 54 ++++++++++++++++++-- src/plugins/gitlab/gitlabprojectsettings.h | 37 +------------- 3 files changed, 54 insertions(+), 47 deletions(-) diff --git a/src/plugins/gitlab/gitlabplugin.cpp b/src/plugins/gitlab/gitlabplugin.cpp index 5ae4df682b6..73e726c9807 100644 --- a/src/plugins/gitlab/gitlabplugin.cpp +++ b/src/plugins/gitlab/gitlabplugin.cpp @@ -81,13 +81,9 @@ void GitLabPlugin::initialize() { dd = new GitLabPluginPrivate; dd->parameters.fromSettings(Core::ICore::settings()); - auto panelFactory = new ProjectExplorer::ProjectPanelFactory; - panelFactory->setPriority(999); - panelFactory->setDisplayName(Tr::tr("GitLab")); - panelFactory->setCreateWidgetFunction([](ProjectExplorer::Project *project) { - return new GitLabProjectSettingsWidget(project); - }); - ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory); + + setupGitlabProjectPanel(); + QAction *openViewAction = new QAction(Tr::tr("GitLab..."), this); auto gitlabCommand = Core::ActionManager::registerAction(openViewAction, Constants::GITLAB_OPEN_VIEW); diff --git a/src/plugins/gitlab/gitlabprojectsettings.cpp b/src/plugins/gitlab/gitlabprojectsettings.cpp index b5bb12942b4..6b4a09c0ade 100644 --- a/src/plugins/gitlab/gitlabprojectsettings.cpp +++ b/src/plugins/gitlab/gitlabprojectsettings.cpp @@ -10,7 +10,11 @@ #include "resultparser.h" #include + #include +#include +#include + #include #include @@ -107,10 +111,33 @@ void GitLabProjectSettings::save() m_project->setNamedSettings(PSK_LAST_REQ, m_lastRequest); } -GitLabProjectSettingsWidget::GitLabProjectSettingsWidget(ProjectExplorer::Project *project, - QWidget *parent) - : ProjectExplorer::ProjectSettingsWidget(parent) - , m_projectSettings(GitLabPlugin::projectSettings(project)) +class GitLabProjectSettingsWidget : public ProjectExplorer::ProjectSettingsWidget +{ +public: + explicit GitLabProjectSettingsWidget(ProjectExplorer::Project *project); + +private: + enum CheckMode { Connection, Link }; + + void unlink(); + void checkConnection(CheckMode mode); + void onConnectionChecked(const Project &project, const Utils::Id &serverId, + const QString &remote, const QString &projName); + void updateUi(); + void updateEnabledStates(); + + GitLabProjectSettings *m_projectSettings = nullptr; + QComboBox *m_linkedGitLabServer = nullptr; + QComboBox *m_hostCB = nullptr; + QPushButton *m_linkWithGitLab = nullptr; + QPushButton *m_unlink = nullptr; + QPushButton *m_checkConnection = nullptr; + Utils::InfoLabel *m_infoLabel = nullptr; + CheckMode m_checkMode = Connection; +}; + +GitLabProjectSettingsWidget::GitLabProjectSettingsWidget(ProjectExplorer::Project *project) + : m_projectSettings(GitLabPlugin::projectSettings(project)) { setUseGlobalSettingsCheckBoxVisible(false); setUseGlobalSettingsLabelVisible(true); @@ -302,4 +329,23 @@ void GitLabProjectSettingsWidget::updateEnabledStates() } } +class GitlabProjectPanelFactory final : public ProjectExplorer::ProjectPanelFactory +{ +public: + GitlabProjectPanelFactory() + { + setPriority(999); + setDisplayName(Tr::tr("GitLab")); + setCreateWidgetFunction([](ProjectExplorer::Project *project) { + return new GitLabProjectSettingsWidget(project); + }); + ProjectExplorer::ProjectPanelFactory::registerFactory(this); + } +}; + +void setupGitlabProjectPanel() +{ + static GitlabProjectPanelFactory theGitlabProjectPanelFactory; +} + } // namespace GitLab diff --git a/src/plugins/gitlab/gitlabprojectsettings.h b/src/plugins/gitlab/gitlabprojectsettings.h index 19b4c1fea92..9064f3394e9 100644 --- a/src/plugins/gitlab/gitlabprojectsettings.h +++ b/src/plugins/gitlab/gitlabprojectsettings.h @@ -3,19 +3,10 @@ #pragma once -#include #include #include #include -#include - -QT_BEGIN_NAMESPACE -class QComboBox; -class QPushButton; -QT_END_NAMESPACE - -#include namespace ProjectExplorer { class Project; } @@ -56,32 +47,6 @@ private: bool m_linked = false; }; -class GitLabProjectSettingsWidget : public ProjectExplorer::ProjectSettingsWidget -{ - Q_OBJECT -public: - explicit GitLabProjectSettingsWidget(ProjectExplorer::Project *project, - QWidget *parent = nullptr); - -private: - enum CheckMode { Connection, Link }; - - void unlink(); - void checkConnection(CheckMode mode); - void onConnectionChecked(const Project &project, const Utils::Id &serverId, - const QString &remote, const QString &projName); - void updateUi(); - void updateEnabledStates(); - - GitLabProjectSettings *m_projectSettings = nullptr; - QComboBox *m_linkedGitLabServer = nullptr; - QComboBox *m_hostCB = nullptr; - QPushButton *m_linkWithGitLab = nullptr; - QPushButton *m_unlink = nullptr; - QPushButton *m_checkConnection = nullptr; - Utils::InfoLabel *m_infoLabel = nullptr; - CheckMode m_checkMode = Connection; -}; +void setupGitlabProjectPanel(); } // namespace GitLab - From f1f4df29b56d1a1dd7ed7bd2c98cfb491f4e006f Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 14 Nov 2023 18:00:23 +0100 Subject: [PATCH 0214/1546] Autotest: Use new construction pattern for project panel factory Change-Id: I09abb1d5dbb07a700053077b03e65a3dce4b3f1f Reviewed-by: Christian Stenger --- src/plugins/autotest/autotestplugin.cpp | 10 +--- .../autotest/projectsettingswidget.cpp | 55 ++++++++++++++++--- src/plugins/autotest/projectsettingswidget.h | 44 +-------------- 3 files changed, 51 insertions(+), 58 deletions(-) diff --git a/src/plugins/autotest/autotestplugin.cpp b/src/plugins/autotest/autotestplugin.cpp index 7a1da0edc22..c9b2372b0d4 100644 --- a/src/plugins/autotest/autotestplugin.cpp +++ b/src/plugins/autotest/autotestplugin.cpp @@ -45,7 +45,6 @@ #include #include #include -#include #include #include @@ -138,14 +137,7 @@ AutotestPluginPrivate::AutotestPluginPrivate() m_resultsPane = TestResultsPane::instance(); - auto panelFactory = new ProjectExplorer::ProjectPanelFactory(); - panelFactory->setPriority(666); -// panelFactory->setIcon(); // TODO ? - panelFactory->setDisplayName(Tr::tr("Testing")); - panelFactory->setCreateWidgetFunction([](ProjectExplorer::Project *project) { - return new ProjectTestSettingsWidget(project); - }); - ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory); + setupAutotestProjectPanel(); TestFrameworkManager::activateFrameworksAndToolsFromSettings(); m_testTreeModel.synchronizeTestFrameworks(); diff --git a/src/plugins/autotest/projectsettingswidget.cpp b/src/plugins/autotest/projectsettingswidget.cpp index 53870990b5d..84b3b612f64 100644 --- a/src/plugins/autotest/projectsettingswidget.cpp +++ b/src/plugins/autotest/projectsettingswidget.cpp @@ -9,25 +9,45 @@ #include "testprojectsettings.h" #include "testtreemodel.h" +#include +#include + #include #include #include #include +#include #include -namespace Autotest { -namespace Internal { +using namespace ProjectExplorer; + +namespace Autotest::Internal { enum ItemDataRole { BaseIdRole = Qt::UserRole + 1, BaseTypeRole }; -ProjectTestSettingsWidget::ProjectTestSettingsWidget(ProjectExplorer::Project *project, - QWidget *parent) - : ProjectExplorer::ProjectSettingsWidget(parent) - , m_projectSettings(AutotestPlugin::projectSettings(project)) +class ProjectTestSettingsWidget : public ProjectSettingsWidget +{ +public: + explicit ProjectTestSettingsWidget(Project *project); + +private: + void populateFrameworks(const QHash &frameworks, + const QHash &testTools); + void onActiveFrameworkChanged(QTreeWidgetItem *item, int column); + TestProjectSettings *m_projectSettings; + QComboBox *m_useGlobalSettings = nullptr; + QTreeWidget *m_activeFrameworks = nullptr; + QComboBox *m_runAfterBuild = nullptr; + QTimer m_syncTimer; + int m_syncType = 0; +}; + +ProjectTestSettingsWidget::ProjectTestSettingsWidget(Project *project) + : m_projectSettings(AutotestPlugin::projectSettings(project)) { setGlobalSettingsId(Constants::AUTOTEST_SETTINGS_ID); @@ -131,5 +151,24 @@ void ProjectTestSettingsWidget::onActiveFrameworkChanged(QTreeWidgetItem *item, m_syncType |= type; } -} // namespace Internal -} // namespace Autotest +class AutotestProjectPanelFactory final : public ProjectPanelFactory +{ +public: + AutotestProjectPanelFactory() + { + setPriority(666); + // setIcon(); // TODO ? + setDisplayName(Tr::tr("Testing")); + setCreateWidgetFunction([](Project *project) { + return new ProjectTestSettingsWidget(project); + }); + ProjectPanelFactory::registerFactory(this); + } +}; + +void setupAutotestProjectPanel() +{ + static AutotestProjectPanelFactory theAutotestProjectPanelFactory; +} + +} // Autotest::Internal diff --git a/src/plugins/autotest/projectsettingswidget.h b/src/plugins/autotest/projectsettingswidget.h index 92dc228b983..87669b766ab 100644 --- a/src/plugins/autotest/projectsettingswidget.h +++ b/src/plugins/autotest/projectsettingswidget.h @@ -3,46 +3,8 @@ #pragma once -#include +namespace Autotest::Internal { -#include -#include +void setupAutotestProjectPanel(); -QT_BEGIN_NAMESPACE -class QComboBox; -class QTreeWidget; -class QTreeWidgetItem; -QT_END_NAMESPACE - -namespace ProjectExplorer { class Project; } - -namespace Autotest { - -class ITestFramework; -class ITestTool; - -namespace Internal { - -class TestProjectSettings; - -class ProjectTestSettingsWidget : public ProjectExplorer::ProjectSettingsWidget -{ - Q_OBJECT -public: - explicit ProjectTestSettingsWidget(ProjectExplorer::Project *project, - QWidget *parent = nullptr); - -private: - void populateFrameworks(const QHash &frameworks, - const QHash &testTools); - void onActiveFrameworkChanged(QTreeWidgetItem *item, int column); - TestProjectSettings *m_projectSettings; - QComboBox *m_useGlobalSettings = nullptr; - QTreeWidget *m_activeFrameworks = nullptr; - QComboBox *m_runAfterBuild = nullptr; - QTimer m_syncTimer; - int m_syncType = 0; -}; - -} // namespace Internal -} // namespace Autotest +} // Autotest::Internal From 86aa945bd6e8ff6b46a37dfa382caca85e655049 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Nov 2023 08:21:59 +0100 Subject: [PATCH 0215/1546] Axivion: Use new construction pattern for project panel factory Change-Id: I49b71d1fec4c174446f758b4b44b374a979f4300 Reviewed-by: Christian Stenger --- src/plugins/axivion/axivionplugin.cpp | 8 ++------ .../axivion/axivionprojectsettings.cpp | 19 +++++++++++++++++-- src/plugins/axivion/axivionprojectsettings.h | 7 ++----- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/plugins/axivion/axivionplugin.cpp b/src/plugins/axivion/axivionplugin.cpp index d2f2d33d228..df153e1503c 100644 --- a/src/plugins/axivion/axivionplugin.cpp +++ b/src/plugins/axivion/axivionplugin.cpp @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -110,11 +109,8 @@ void AxivionPlugin::initialize() { dd = new AxivionPluginPrivate; - auto panelFactory = new ProjectExplorer::ProjectPanelFactory; - panelFactory->setPriority(250); - panelFactory->setDisplayName(Tr::tr("Axivion")); - panelFactory->setCreateWidgetFunction(&AxivionProjectSettings::createSettingsWidget); - ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory); + AxivionProjectSettings::setupProjectPanel(); + connect(ProjectExplorer::ProjectManager::instance(), &ProjectExplorer::ProjectManager::startupProjectChanged, dd, &AxivionPluginPrivate::onStartupProjectChanged); diff --git a/src/plugins/axivion/axivionprojectsettings.cpp b/src/plugins/axivion/axivionprojectsettings.cpp index d92a601435d..659933c3bf0 100644 --- a/src/plugins/axivion/axivionprojectsettings.cpp +++ b/src/plugins/axivion/axivionprojectsettings.cpp @@ -10,6 +10,7 @@ #include "axiviontr.h" #include +#include #include #include @@ -248,9 +249,23 @@ void AxivionProjectSettingsWidget::updateEnabledStates() } } -ProjectSettingsWidget *AxivionProjectSettings::createSettingsWidget(ProjectExplorer::Project *project) +class AxivionProjectPanelFactory : public ProjectExplorer::ProjectPanelFactory { - return new AxivionProjectSettingsWidget(project); +public: + AxivionProjectPanelFactory() + { + setPriority(250); + setDisplayName(Tr::tr("Axivion")); + setCreateWidgetFunction([](ProjectExplorer::Project *project) { + return new AxivionProjectSettingsWidget(project); + }); + ProjectExplorer::ProjectPanelFactory::registerFactory(this); + } +}; + +void AxivionProjectSettings::setupProjectPanel() +{ + static AxivionProjectPanelFactory theAxivionProjectPanelFactory; } } // Axivion::Internal diff --git a/src/plugins/axivion/axivionprojectsettings.h b/src/plugins/axivion/axivionprojectsettings.h index d11b001d9f3..7cbdfbbf472 100644 --- a/src/plugins/axivion/axivionprojectsettings.h +++ b/src/plugins/axivion/axivionprojectsettings.h @@ -5,10 +5,7 @@ #include -namespace ProjectExplorer { -class Project; -class ProjectSettingsWidget; -} +namespace ProjectExplorer { class Project; } namespace Axivion::Internal { @@ -22,7 +19,7 @@ public: static AxivionProjectSettings *projectSettings(ProjectExplorer::Project *project); static void destroyProjectSettings(); - static ProjectExplorer::ProjectSettingsWidget *createSettingsWidget(ProjectExplorer::Project *project); + static void setupProjectPanel(); private: void load(); From 9967877b7a88878448146c16d6312cc574543c08 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Nov 2023 08:38:12 +0100 Subject: [PATCH 0216/1546] ClangTools: : Use new construction pattern for project panel factory Change-Id: Ib03e50b5925027e791c3416e6f202ab258071a16 Reviewed-by: Christian Stenger --- src/plugins/clangtools/clangtoolsplugin.cpp | 16 +---- src/plugins/clangtools/clangtoolsplugin.h | 5 -- .../clangtoolsprojectsettingswidget.cpp | 59 ++++++++++++++++--- .../clangtoolsprojectsettingswidget.h | 46 +-------------- 4 files changed, 54 insertions(+), 72 deletions(-) diff --git a/src/plugins/clangtools/clangtoolsplugin.cpp b/src/plugins/clangtools/clangtoolsplugin.cpp index 6850cc96f42..613cb853391 100644 --- a/src/plugins/clangtools/clangtoolsplugin.cpp +++ b/src/plugins/clangtools/clangtoolsplugin.cpp @@ -36,7 +36,6 @@ #include #include -#include #include #include @@ -52,13 +51,6 @@ using namespace ProjectExplorer; namespace ClangTools::Internal { -static ProjectPanelFactory *m_projectPanelFactoryInstance = nullptr; - -ProjectPanelFactory *projectPanelFactory() -{ - return m_projectPanelFactoryInstance; -} - class ClangToolsPluginPrivate { public: @@ -102,13 +94,7 @@ void ClangToolsPlugin::initialize() registerAnalyzeActions(); - auto panelFactory = m_projectPanelFactoryInstance = new ProjectPanelFactory; - panelFactory->setPriority(100); - panelFactory->setId(Constants::PROJECT_PANEL_ID); - panelFactory->setDisplayName(Tr::tr("Clang Tools")); - panelFactory->setCreateWidgetFunction( - [](Project *project) { return new ClangToolsProjectSettingsWidget(project); }); - ProjectPanelFactory::registerFactory(panelFactory); + setupClangToolsProjectPanel(); connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged, diff --git a/src/plugins/clangtools/clangtoolsplugin.h b/src/plugins/clangtools/clangtoolsplugin.h index f3d996ddebb..b6aaad51d27 100644 --- a/src/plugins/clangtools/clangtoolsplugin.h +++ b/src/plugins/clangtools/clangtoolsplugin.h @@ -5,13 +5,8 @@ #include -namespace Core { class IDocument; } -namespace ProjectExplorer { class ProjectPanelFactory; } - namespace ClangTools::Internal { -ProjectExplorer::ProjectPanelFactory *projectPanelFactory(); - class ClangToolsPlugin final : public ExtensionSystem::IPlugin { Q_OBJECT diff --git a/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp b/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp index 8e1ac057f93..0012668dd61 100644 --- a/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp +++ b/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp @@ -15,6 +15,9 @@ #include #include +#include +#include + #include #include @@ -24,12 +27,12 @@ #include #include -namespace ClangTools { -namespace Internal { +using namespace ProjectExplorer; + +namespace ClangTools::Internal { class SuppressedDiagnosticsModel : public QAbstractTableModel { - Q_OBJECT public: SuppressedDiagnosticsModel(QObject *parent = nullptr) : QAbstractTableModel(parent) { } @@ -48,9 +51,31 @@ private: SuppressedDiagnosticsList m_diagnostics; }; -ClangToolsProjectSettingsWidget::ClangToolsProjectSettingsWidget(ProjectExplorer::Project *project, QWidget *parent) : - ProjectExplorer::ProjectSettingsWidget(parent), - m_projectSettings(ClangToolsProjectSettings::getSettings(project)) +class ClangToolsProjectSettingsWidget : public ProjectSettingsWidget +{ +public: + explicit ClangToolsProjectSettingsWidget(Project *project); + +private: + void onGlobalCustomChanged(bool useGlobal); + + void updateButtonStates(); + void updateButtonStateRemoveSelected(); + void updateButtonStateRemoveAll(); + void removeSelected(); + + QComboBox *m_globalCustomComboBox; + QPushButton *m_restoreGlobal; + RunSettingsWidget *m_runSettingsWidget; + QTreeView *m_diagnosticsView; + QPushButton *m_removeSelectedButton; + QPushButton *m_removeAllButton; + + QSharedPointer const m_projectSettings; +}; + +ClangToolsProjectSettingsWidget::ClangToolsProjectSettingsWidget(Project *project) + : m_projectSettings(ClangToolsProjectSettings::getSettings(project)) { setGlobalSettingsId(ClangTools::Constants::SETTINGS_PAGE_ID); m_restoreGlobal = new QPushButton(Tr::tr("Restore Global Settings")); @@ -218,7 +243,23 @@ QVariant SuppressedDiagnosticsModel::data(const QModelIndex &index, int role) co return QVariant(); } -} // namespace Internal -} // namespace ClangTools +class ClangToolsProjectPanelFactory final : public ProjectPanelFactory +{ +public: + ClangToolsProjectPanelFactory() + { + setPriority(100); + setId(Constants::PROJECT_PANEL_ID); + setDisplayName(Tr::tr("Clang Tools")); + setCreateWidgetFunction( + [](Project *project) { return new ClangToolsProjectSettingsWidget(project); }); + ProjectPanelFactory::registerFactory(this); + } +}; -#include "clangtoolsprojectsettingswidget.moc" +void setupClangToolsProjectPanel() +{ + static ClangToolsProjectPanelFactory theClangToolsProjectPanelFactory; +} + +} // namespace ClangTools::Internal diff --git a/src/plugins/clangtools/clangtoolsprojectsettingswidget.h b/src/plugins/clangtools/clangtoolsprojectsettingswidget.h index 2fee4d70621..bf9af49e74d 100644 --- a/src/plugins/clangtools/clangtoolsprojectsettingswidget.h +++ b/src/plugins/clangtools/clangtoolsprojectsettingswidget.h @@ -3,48 +3,8 @@ #pragma once -#include +namespace ClangTools::Internal { -#include +void setupClangToolsProjectPanel(); -QT_BEGIN_NAMESPACE -class QComboBox; -class QPushButton; -class QTreeView; -QT_END_NAMESPACE - -namespace ProjectExplorer { class Project; } - -namespace ClangTools { -namespace Internal { - -class ClangToolsProjectSettings; -class RunSettingsWidget; - -class ClangToolsProjectSettingsWidget : public ProjectExplorer::ProjectSettingsWidget -{ - Q_OBJECT - -public: - explicit ClangToolsProjectSettingsWidget(ProjectExplorer::Project *project, QWidget *parent = nullptr); - -private: - void onGlobalCustomChanged(bool useGlobal); - - void updateButtonStates(); - void updateButtonStateRemoveSelected(); - void updateButtonStateRemoveAll(); - void removeSelected(); - - QComboBox *m_globalCustomComboBox; - QPushButton *m_restoreGlobal; - RunSettingsWidget *m_runSettingsWidget; - QTreeView *m_diagnosticsView; - QPushButton *m_removeSelectedButton; - QPushButton *m_removeAllButton; - - QSharedPointer const m_projectSettings; -}; - -} // namespace Internal -} // namespace ClangTools +} // ClangTools::Interna; From 9f0198d8ed83eec0fd97ef635e4ca850efa63a21 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Nov 2023 09:08:13 +0100 Subject: [PATCH 0217/1546] Copilot: Use new construction pattern for project panel factory Change-Id: Id703f377f353390e63535a0c98078c66909cbdd4 Reviewed-by: Reviewed-by: Christian Stenger --- src/plugins/copilot/copilotplugin.cpp | 8 +----- src/plugins/copilot/copilotprojectpanel.cpp | 27 +++++++++++++++++---- src/plugins/copilot/copilotprojectpanel.h | 9 ++----- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/plugins/copilot/copilotplugin.cpp b/src/plugins/copilot/copilotplugin.cpp index fdbdaac553b..2ad525f5f37 100644 --- a/src/plugins/copilot/copilotplugin.cpp +++ b/src/plugins/copilot/copilotplugin.cpp @@ -17,8 +17,6 @@ #include -#include - #include #include @@ -129,11 +127,7 @@ void CopilotPlugin::initialize() toggleButton->setDefaultAction(toggleAction.contextAction()); StatusBarManager::addStatusBarWidget(toggleButton, StatusBarManager::RightCorner); - auto panelFactory = new ProjectPanelFactory; - panelFactory->setPriority(1000); - panelFactory->setDisplayName(Tr::tr("Copilot")); - panelFactory->setCreateWidgetFunction(&Internal::createCopilotProjectPanel); - ProjectPanelFactory::registerFactory(panelFactory); + setupCopilotProjectPanel(); } bool CopilotPlugin::delayedInitialize() diff --git a/src/plugins/copilot/copilotprojectpanel.cpp b/src/plugins/copilot/copilotprojectpanel.cpp index 034e43bc2dc..5b570a0de26 100644 --- a/src/plugins/copilot/copilotprojectpanel.cpp +++ b/src/plugins/copilot/copilotprojectpanel.cpp @@ -2,21 +2,22 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "copilotprojectpanel.h" + #include "copilotconstants.h" #include "copilotsettings.h" +#include "copilottr.h" #include +#include #include #include -#include - using namespace ProjectExplorer; namespace Copilot::Internal { -class CopilotProjectSettingsWidget : public ProjectExplorer::ProjectSettingsWidget +class CopilotProjectSettingsWidget final : public ProjectSettingsWidget { public: CopilotProjectSettingsWidget() @@ -26,10 +27,9 @@ public: } }; -ProjectSettingsWidget *createCopilotProjectPanel(Project *project) +static ProjectSettingsWidget *createCopilotProjectPanel(Project *project) { using namespace Layouting; - using namespace ProjectExplorer; auto widget = new CopilotProjectSettingsWidget; auto settings = new CopilotProjectSettings(project); @@ -57,4 +57,21 @@ ProjectSettingsWidget *createCopilotProjectPanel(Project *project) return widget; } +class CopilotProjectPanelFactory final : public ProjectPanelFactory +{ +public: + CopilotProjectPanelFactory() + { + setPriority(1000); + setDisplayName(Tr::tr("Copilot")); + setCreateWidgetFunction(&createCopilotProjectPanel); + ProjectPanelFactory::registerFactory(this); + } +}; + +void setupCopilotProjectPanel() +{ + static CopilotProjectPanelFactory theCopilotProjectPanelFactory; +} + } // namespace Copilot::Internal diff --git a/src/plugins/copilot/copilotprojectpanel.h b/src/plugins/copilot/copilotprojectpanel.h index 2f4be6d6f9c..4db9c087d5d 100644 --- a/src/plugins/copilot/copilotprojectpanel.h +++ b/src/plugins/copilot/copilotprojectpanel.h @@ -3,13 +3,8 @@ #pragma once -namespace ProjectExplorer { -class ProjectSettingsWidget; -class Project; -} // namespace ProjectExplorer - namespace Copilot::Internal { -ProjectExplorer::ProjectSettingsWidget *createCopilotProjectPanel(ProjectExplorer::Project *project); +void setupCopilotProjectPanel(); -} // namespace Copilot::Internal +} // Copilot::Internal From 8c337722d061d6dea27540cce9ac92e1c72bc1c8 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 15 Nov 2023 15:00:59 +0100 Subject: [PATCH 0218/1546] LLDB: check for msvc/windows target in lldbbridge Change-Id: I404630592e021688628d02ec71ea00cb2db8358e Reviewed-by: hjk Reviewed-by: Cristian Adam --- share/qtcreator/debugger/lldbbridge.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/share/qtcreator/debugger/lldbbridge.py b/share/qtcreator/debugger/lldbbridge.py index 7b5c002b432..4d9b74b2ea2 100644 --- a/share/qtcreator/debugger/lldbbridge.py +++ b/share/qtcreator/debugger/lldbbridge.py @@ -667,16 +667,16 @@ class Dumper(DumperBase): return None if val is None else self.fromNativeValue(val) def isWindowsTarget(self): - return False + return 'windows' in self.target.triple def isQnxTarget(self): return False def isArmArchitecture(self): - return False + return 'arm' in self.target.triple def isMsvcTarget(self): - return False + return 'msvc' in self.target.triple def prettySymbolByAddress(self, address): try: From 4773f89f8cf4027e3be17205eb371840ea849ec3 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Nov 2023 10:24:56 +0100 Subject: [PATCH 0219/1546] ProjectExplorer: Use new construction pattern for some project panels Change-Id: I0c7cd43a2fcd9480cab06270a4fee295cf5a5fc1 Reviewed-by: Christian Stenger --- .../codestylesettingspropertiespage.cpp | 70 ++++++++++++------- .../codestylesettingspropertiespage.h | 18 +---- .../editorsettingspropertiespage.cpp | 41 +++++++++++ .../editorsettingspropertiespage.h | 44 +----------- .../projectexplorer/projectexplorer.cpp | 14 +--- 5 files changed, 96 insertions(+), 91 deletions(-) diff --git a/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp b/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp index f7ed131e575..6f3f4761241 100644 --- a/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp @@ -6,6 +6,8 @@ #include "editorconfiguration.h" #include "project.h" #include "projectexplorertr.h" +#include "projectpanelfactory.h" +#include "projectsettingswidget.h" #include @@ -17,44 +19,64 @@ #include #include -#include #include using namespace TextEditor; namespace ProjectExplorer::Internal { -CodeStyleSettingsWidget::CodeStyleSettingsWidget(Project *project) +class CodeStyleSettingsWidget final : public ProjectSettingsWidget { - auto languageComboBox = new QComboBox(this); - auto stackedWidget = new QStackedWidget(this); +public: + explicit CodeStyleSettingsWidget(Project *project) + { + auto languageComboBox = new QComboBox(this); + auto stackedWidget = new QStackedWidget(this); - setGlobalSettingsId(CppEditor::Constants::CPP_CODE_STYLE_SETTINGS_ID); - setUseGlobalSettingsCheckBoxVisible(false); + setGlobalSettingsId(CppEditor::Constants::CPP_CODE_STYLE_SETTINGS_ID); + setUseGlobalSettingsCheckBoxVisible(false); - const EditorConfiguration *config = project->editorConfiguration(); + const EditorConfiguration *config = project->editorConfiguration(); - for (ICodeStylePreferencesFactory *factory : TextEditorSettings::codeStyleFactories()) { - Utils::Id languageId = factory->languageId(); - ICodeStylePreferences *codeStylePreferences = config->codeStyle(languageId); + for (ICodeStylePreferencesFactory *factory : TextEditorSettings::codeStyleFactories()) { + Utils::Id languageId = factory->languageId(); + ICodeStylePreferences *codeStylePreferences = config->codeStyle(languageId); - auto preview = factory->createCodeStyleEditor(codeStylePreferences, project, stackedWidget); - if (preview && preview->layout()) - preview->layout()->setContentsMargins(QMargins()); - stackedWidget->addWidget(preview); - languageComboBox->addItem(factory->displayName()); + auto preview = factory->createCodeStyleEditor(codeStylePreferences, project, stackedWidget); + if (preview && preview->layout()) + preview->layout()->setContentsMargins(QMargins()); + stackedWidget->addWidget(preview); + languageComboBox->addItem(factory->displayName()); + } + + connect(languageComboBox, &QComboBox::currentIndexChanged, + stackedWidget, &QStackedWidget::setCurrentIndex); + + using namespace Layouting; + + Column { + Row { new QLabel(Tr::tr("Language:")), languageComboBox, st }, + stackedWidget, + noMargin + }.attachTo(this); } +}; - connect(languageComboBox, &QComboBox::currentIndexChanged, - stackedWidget, &QStackedWidget::setCurrentIndex); +class CodeStyleProjectPanelFactory final : public ProjectPanelFactory +{ +public: + CodeStyleProjectPanelFactory() + { + setPriority(40); + setDisplayName(Tr::tr("Code Style")); + setCreateWidgetFunction([](Project *project) { return new CodeStyleSettingsWidget(project); }); + ProjectPanelFactory::registerFactory(this); + } +}; - using namespace Layouting; - - Column { - Row { new QLabel(Tr::tr("Language:")), languageComboBox, st }, - stackedWidget, - noMargin - }.attachTo(this); +void setupCodeStyleProjectPanel() +{ + static CodeStyleProjectPanelFactory theCodeStyleProjectPanelFactory; } } // ProjectExplorer::Internal diff --git a/src/plugins/projectexplorer/codestylesettingspropertiespage.h b/src/plugins/projectexplorer/codestylesettingspropertiespage.h index f07735f0eee..fed471a31a3 100644 --- a/src/plugins/projectexplorer/codestylesettingspropertiespage.h +++ b/src/plugins/projectexplorer/codestylesettingspropertiespage.h @@ -3,20 +3,8 @@ #pragma once -#include +namespace ProjectExplorer::Internal { -namespace ProjectExplorer { +void setupCodeStyleProjectPanel(); -class Project; - -namespace Internal { - -class CodeStyleSettingsWidget : public ProjectSettingsWidget -{ - Q_OBJECT -public: - explicit CodeStyleSettingsWidget(Project *project); -}; - -} // namespace Internal -} // namespace ProjectExplorer +} // ProjectExplorer::Internal diff --git a/src/plugins/projectexplorer/editorsettingspropertiespage.cpp b/src/plugins/projectexplorer/editorsettingspropertiespage.cpp index e0c2b93bb26..96deedfd625 100644 --- a/src/plugins/projectexplorer/editorsettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/editorsettingspropertiespage.cpp @@ -6,6 +6,8 @@ #include "editorconfiguration.h" #include "project.h" #include "projectexplorertr.h" +#include "projectpanelfactory.h" +#include "projectsettingswidget.h" #include #include @@ -25,6 +27,28 @@ namespace ProjectExplorer::Internal { +class EditorSettingsWidget : public ProjectSettingsWidget +{ +public: + explicit EditorSettingsWidget(Project *project); + +private: + void globalSettingsActivated(bool useGlobal); + void restoreDefaultValues(); + + void settingsToUi(const EditorConfiguration *config); + + Project *m_project; + + QPushButton *m_restoreButton; + QCheckBox *m_showWrapColumn; + QCheckBox *m_tintMarginArea; + QSpinBox *m_wrapColumn; + QCheckBox *m_useIndenter; + QGroupBox *m_displaySettings; + TextEditor::BehaviorSettingsWidget *m_behaviorSettings; +}; + EditorSettingsWidget::EditorSettingsWidget(Project *project) : m_project(project) { setGlobalSettingsId(TextEditor::Constants::TEXT_EDITOR_BEHAVIOR_SETTINGS); @@ -135,4 +159,21 @@ void EditorSettingsWidget::restoreDefaultValues() settingsToUi(config); } +class EditorSettingsProjectPanelFactory final : public ProjectPanelFactory +{ +public: + EditorSettingsProjectPanelFactory() + { + setPriority(30); + setDisplayName(Tr::tr("Editor")); + setCreateWidgetFunction([](Project *project) { return new EditorSettingsWidget(project); }); + ProjectPanelFactory::registerFactory(this); + } +}; + +void setupEditorSettingsProjectPanel() +{ + static EditorSettingsProjectPanelFactory theEditorSettingsProjectPanelFactory; +} + } // ProjectExplorer::Internal diff --git a/src/plugins/projectexplorer/editorsettingspropertiespage.h b/src/plugins/projectexplorer/editorsettingspropertiespage.h index ae9f3ccfe62..6aabd996443 100644 --- a/src/plugins/projectexplorer/editorsettingspropertiespage.h +++ b/src/plugins/projectexplorer/editorsettingspropertiespage.h @@ -3,46 +3,8 @@ #pragma once -#include +namespace ProjectExplorer::Internal { -QT_BEGIN_NAMESPACE -class QCheckBox; -class QGroupBox; -class QPushButton; -class QSpinBox; -QT_END_NAMESPACE +void setupEditorSettingsProjectPanel(); -namespace TextEditor { class BehaviorSettingsWidget; } - -namespace ProjectExplorer { - -class EditorConfiguration; -class Project; - -namespace Internal { - -class EditorSettingsWidget : public ProjectSettingsWidget -{ - Q_OBJECT -public: - explicit EditorSettingsWidget(Project *project); - -private: - void globalSettingsActivated(bool useGlobal); - void restoreDefaultValues(); - - void settingsToUi(const EditorConfiguration *config); - - Project *m_project; - - QPushButton *m_restoreButton; - QCheckBox *m_showWrapColumn; - QCheckBox *m_tintMarginArea; - QSpinBox *m_wrapColumn; - QCheckBox *m_useIndenter; - QGroupBox *m_displaySettings; - TextEditor::BehaviorSettingsWidget *m_behaviorSettings; -}; - -} // namespace Internal -} // namespace ProjectExplorer +} // ProjectExplorer::Internal diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 3e6131b36d5..c180d70658e 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -882,19 +882,11 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er &dd->m_outputPane, &AppOutputPane::projectRemoved); // ProjectPanelFactories - auto panelFactory = new ProjectPanelFactory; - panelFactory->setPriority(30); - panelFactory->setDisplayName(Tr::tr("Editor")); - panelFactory->setCreateWidgetFunction([](Project *project) { return new EditorSettingsWidget(project); }); - ProjectPanelFactory::registerFactory(panelFactory); - panelFactory = new ProjectPanelFactory; - panelFactory->setPriority(40); - panelFactory->setDisplayName(Tr::tr("Code Style")); - panelFactory->setCreateWidgetFunction([](Project *project) { return new CodeStyleSettingsWidget(project); }); - ProjectPanelFactory::registerFactory(panelFactory); + setupEditorSettingsProjectPanel(); + setupCodeStyleProjectPanel(); - panelFactory = new ProjectExplorer::ProjectPanelFactory; + auto panelFactory = new ProjectExplorer::ProjectPanelFactory; panelFactory->setPriority(45); panelFactory->setDisplayName(Tr::tr("Documentation Comments")); panelFactory->setCreateWidgetFunction([](ProjectExplorer::Project *project) { From d739a1495021a3ac2a18834b42bfe5f696dc3783 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Nov 2023 17:56:27 +0100 Subject: [PATCH 0220/1546] TextEditor: Delay-construct ClipboardAssistProvider Change-Id: I34d1e2e8f99e55e574e148bef700811fb33d9449 Reviewed-by: David Schulz --- .../texteditor/circularclipboardassist.cpp | 30 +++++++++++-------- .../texteditor/circularclipboardassist.h | 14 ++------- src/plugins/texteditor/texteditor.cpp | 5 +--- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/plugins/texteditor/circularclipboardassist.cpp b/src/plugins/texteditor/circularclipboardassist.cpp index fe569f54e66..4a8bce4c9c9 100644 --- a/src/plugins/texteditor/circularclipboardassist.cpp +++ b/src/plugins/texteditor/circularclipboardassist.cpp @@ -20,10 +20,9 @@ using namespace Utils; -namespace TextEditor { -namespace Internal { +namespace TextEditor::Internal { -class ClipboardProposalItem: public AssistProposalItem +class ClipboardProposalItem final : public AssistProposalItem { public: enum { maxLen = 80 }; @@ -39,9 +38,7 @@ public: setText(text); } - ~ClipboardProposalItem() noexcept override = default; - - void apply(TextDocumentManipulatorInterface &manipulator, int /*basePosition*/) const override + void apply(TextDocumentManipulatorInterface &manipulator, int /*basePosition*/) const final { //Move to last in circular clipboard @@ -62,10 +59,10 @@ private: QSharedPointer m_mimeData; }; -class ClipboardAssistProcessor: public IAssistProcessor +class ClipboardAssistProcessor final : public IAssistProcessor { public: - IAssistProposal *perform() override + IAssistProposal *perform() final { QIcon icon = Icon::fromTheme("edit-paste"); CircularClipboard * clipboard = CircularClipboard::instance(); @@ -84,10 +81,19 @@ public: } }; -IAssistProcessor *ClipboardAssistProvider::createProcessor(const AssistInterface *) const +class ClipboardAssistProvider final : public IAssistProvider { - return new ClipboardAssistProcessor; +public: + IAssistProcessor *createProcessor(const AssistInterface *) const final + { + return new ClipboardAssistProcessor; + } +}; + +IAssistProvider &clipboardAssistProvider() +{ + static ClipboardAssistProvider theClipboardAssistProvider; + return theClipboardAssistProvider; } -} // namespace Internal -} // namespace TextEditor +} // TextEditor::Internal diff --git a/src/plugins/texteditor/circularclipboardassist.h b/src/plugins/texteditor/circularclipboardassist.h index 8f591ed0d28..e97fd3374d7 100644 --- a/src/plugins/texteditor/circularclipboardassist.h +++ b/src/plugins/texteditor/circularclipboardassist.h @@ -5,16 +5,8 @@ #include "codeassist/iassistprovider.h" +namespace TextEditor::Internal { -namespace TextEditor { -namespace Internal { +IAssistProvider &clipboardAssistProvider(); -class ClipboardAssistProvider: public IAssistProvider -{ -public: - ClipboardAssistProvider(QObject *parent = nullptr) : IAssistProvider(parent) {} - IAssistProcessor *createProcessor(const AssistInterface *) const override; -}; - -} // namespace Internal -} // namespace TextEditor +} // TextEditor::Internal diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index bb86f7d0290..5b48392676f 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -883,8 +883,6 @@ public: TextMark* m_dragMark = nullptr; QTextCursor m_dndCursor; - QScopedPointer m_clipboardAssistProvider; - QScopedPointer m_autoCompleter; CommentDefinition m_commentDefinition; @@ -1028,7 +1026,6 @@ TextEditorWidgetPrivate::TextEditorWidgetPrivate(TextEditorWidget *parent) , m_maybeFakeTooltipEvent(false) , m_codeAssistant(parent) , m_hoverHandlerRunner(parent, m_hoverHandlers) - , m_clipboardAssistProvider(new ClipboardAssistProvider) , m_autoCompleter(new AutoCompleter) { m_selectionHighlightOverlay->show(); @@ -8301,7 +8298,7 @@ void TextEditorWidget::circularPaste() } if (circularClipBoard->size() > 1) { - invokeAssist(QuickFix, d->m_clipboardAssistProvider.data()); + invokeAssist(QuickFix, &clipboardAssistProvider()); return; } From 20bc29face360b0759cc769514da505859d00523 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Nov 2023 14:55:20 +0100 Subject: [PATCH 0221/1546] CppEditor: Use new construction pattern for project panels Change-Id: I60dffd8fb7c00671054b5e229ba8c0a0cb622b1d Reviewed-by: Christian Stenger --- .../cppeditor/cppcodemodelsettingspage.cpp | 100 ++++++++++-------- .../cppeditor/cppcodemodelsettingspage.h | 16 +-- src/plugins/cppeditor/cppeditorplugin.cpp | 27 +---- src/plugins/cppeditor/cppfilesettingspage.cpp | 22 +++- src/plugins/cppeditor/cppfilesettingspage.h | 2 + .../cppquickfixprojectsettingswidget.cpp | 46 +++++++- .../cppquickfixprojectsettingswidget.h | 29 +---- 7 files changed, 128 insertions(+), 114 deletions(-) diff --git a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp index dbd89e48236..8b494d0b4bf 100644 --- a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp +++ b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp @@ -12,6 +12,9 @@ #include #include +#include +#include + #include #include #include @@ -36,6 +39,8 @@ #include +using namespace ProjectExplorer; + namespace CppEditor::Internal { class CppCodeModelSettingsWidget final : public Core::IOptionsPageWidget @@ -578,56 +583,67 @@ ClangdSettingsPage::ClangdSettingsPage() setWidgetCreator([] { return new ClangdSettingsPageWidget; }); } - -class ClangdProjectSettingsWidget::Private +class ClangdProjectSettingsWidget : public ProjectSettingsWidget { public: - Private(const ClangdProjectSettings &s) : settings(s), widget(s.settings(), true) {} + ClangdProjectSettingsWidget(const ClangdProjectSettings &settings) + : m_settings(settings), m_widget(settings.settings(), true) + { + setGlobalSettingsId(Constants::CPP_CLANGD_SETTINGS_ID); + const auto layout = new QVBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(&m_widget); - ClangdProjectSettings settings; - ClangdSettingsWidget widget; - QCheckBox useGlobalSettingsCheckBox; + const auto updateGlobalSettingsCheckBox = [this] { + if (ClangdSettings::instance().granularity() == ClangdSettings::Granularity::Session) { + setUseGlobalSettingsCheckBoxEnabled(false); + setUseGlobalSettings(true); + } else { + setUseGlobalSettingsCheckBoxEnabled(true); + setUseGlobalSettings(m_settings.useGlobalSettings()); + } + m_widget.setEnabled(!useGlobalSettings()); + }; + + updateGlobalSettingsCheckBox(); + connect(&ClangdSettings::instance(), &ClangdSettings::changed, + this, updateGlobalSettingsCheckBox); + + connect(this, &ProjectSettingsWidget::useGlobalSettingsChanged, this, + [this](bool checked) { + m_widget.setEnabled(!checked); + m_settings.setUseGlobalSettings(checked); + if (!checked) + m_settings.setSettings(m_widget.settingsData()); + }); + + connect(&m_widget, &ClangdSettingsWidget::settingsDataChanged, this, [this] { + m_settings.setSettings(m_widget.settingsData()); + }); + } + +private: + ClangdProjectSettings m_settings; + ClangdSettingsWidget m_widget; }; -ClangdProjectSettingsWidget::ClangdProjectSettingsWidget(const ClangdProjectSettings &settings) - : d(new Private(settings)) +class ClangdProjectSettingsPanelFactory final : public ProjectPanelFactory { - setGlobalSettingsId(Constants::CPP_CLANGD_SETTINGS_ID); - const auto layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(&d->widget); +public: + ClangdProjectSettingsPanelFactory() + { + setPriority(100); + setDisplayName(Tr::tr("Clangd")); + setCreateWidgetFunction([](Project *project) { + return new ClangdProjectSettingsWidget(project); + }); + ProjectPanelFactory::registerFactory(this); + } +}; - const auto updateGlobalSettingsCheckBox = [this] { - if (ClangdSettings::instance().granularity() == ClangdSettings::Granularity::Session) { - setUseGlobalSettingsCheckBoxEnabled(false); - setUseGlobalSettings(true); - } else { - setUseGlobalSettingsCheckBoxEnabled(true); - setUseGlobalSettings(d->settings.useGlobalSettings()); - } - d->widget.setEnabled(!useGlobalSettings()); - }; - - updateGlobalSettingsCheckBox(); - connect(&ClangdSettings::instance(), &ClangdSettings::changed, - this, updateGlobalSettingsCheckBox); - - connect(this, &ProjectSettingsWidget::useGlobalSettingsChanged, this, - [this](bool checked) { - d->widget.setEnabled(!checked); - d->settings.setUseGlobalSettings(checked); - if (!checked) - d->settings.setSettings(d->widget.settingsData()); - }); - - connect(&d->widget, &ClangdSettingsWidget::settingsDataChanged, this, [this] { - d->settings.setSettings(d->widget.settingsData()); - }); -} - -ClangdProjectSettingsWidget::~ClangdProjectSettingsWidget() +void setupClangdProjectSettingsPanel() { - delete d; + static ClangdProjectSettingsPanelFactory theClangdProjectSettingsPanelFactory; } } // CppEditor::Internal diff --git a/src/plugins/cppeditor/cppcodemodelsettingspage.h b/src/plugins/cppeditor/cppcodemodelsettingspage.h index c841bfcf4c5..33895275c39 100644 --- a/src/plugins/cppeditor/cppcodemodelsettingspage.h +++ b/src/plugins/cppeditor/cppcodemodelsettingspage.h @@ -4,7 +4,6 @@ #pragma once #include "cppcodemodelsettings.h" -#include #include @@ -40,17 +39,6 @@ private: Private * const d; }; -class ClangdProjectSettingsWidget : public ProjectExplorer::ProjectSettingsWidget -{ - Q_OBJECT +void setupClangdProjectSettingsPanel(); -public: - ClangdProjectSettingsWidget(const ClangdProjectSettings &settings); - ~ClangdProjectSettingsWidget(); - -private: - class Private; - Private * const d; -}; - -} // CppEditor::Internal namespace +} // CppEditor::Internal diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp index a11a71b0b1f..37620e92b12 100644 --- a/src/plugins/cppeditor/cppeditorplugin.cpp +++ b/src/plugins/cppeditor/cppeditorplugin.cpp @@ -72,7 +72,6 @@ #include #include #include -#include #include #include @@ -524,32 +523,12 @@ void CppEditorPlugin::addGlobalActions() void CppEditorPlugin::setupProjectPanels() { - const auto quickFixSettingsPanelFactory = new ProjectPanelFactory; - quickFixSettingsPanelFactory->setPriority(100); - quickFixSettingsPanelFactory->setId(Constants::QUICK_FIX_PROJECT_PANEL_ID); - quickFixSettingsPanelFactory->setDisplayName(Tr::tr(Constants::QUICK_FIX_SETTINGS_DISPLAY_NAME)); - quickFixSettingsPanelFactory->setCreateWidgetFunction([](Project *project) { - return new CppQuickFixProjectSettingsWidget(project); - }); - ProjectPanelFactory::registerFactory(quickFixSettingsPanelFactory); - - const auto fileNamesPanelFactory = new ProjectPanelFactory; - fileNamesPanelFactory->setPriority(99); - fileNamesPanelFactory->setDisplayName(Tr::tr("C++ File Naming")); - fileNamesPanelFactory->setCreateWidgetFunction([](Project *project) { - return new CppFileSettingsForProjectWidget(project); - }); - ProjectPanelFactory::registerFactory(fileNamesPanelFactory); + setupCppQuickFixProjectPanel(); + setupCppFileSettingsProjectPanel(); if (CppModelManager::isClangCodeModelActive()) { d->m_clangdSettingsPage = new ClangdSettingsPage; - const auto clangdPanelFactory = new ProjectPanelFactory; - clangdPanelFactory->setPriority(100); - clangdPanelFactory->setDisplayName(Tr::tr("Clangd")); - clangdPanelFactory->setCreateWidgetFunction([](Project *project) { - return new ClangdProjectSettingsWidget(project); - }); - ProjectPanelFactory::registerFactory(clangdPanelFactory); + setupClangdProjectSettingsPanel(); } } diff --git a/src/plugins/cppeditor/cppfilesettingspage.cpp b/src/plugins/cppeditor/cppfilesettingspage.cpp index 1adca5c7b6f..84d874ca87b 100644 --- a/src/plugins/cppeditor/cppfilesettingspage.cpp +++ b/src/plugins/cppeditor/cppfilesettingspage.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include @@ -21,7 +22,6 @@ #include #include -#include #include #include #include @@ -29,6 +29,7 @@ #include #include +using namespace ProjectExplorer; using namespace Utils; namespace CppEditor::Internal { @@ -586,6 +587,25 @@ void CppFileSettingsForProjectWidget::Private::maybeClearHeaderSourceCache() } } +class CppFileSettingsProjectPanelFactory final : public ProjectPanelFactory +{ +public: + CppFileSettingsProjectPanelFactory() + { + setPriority(99); + setDisplayName(Tr::tr("C++ File Naming")); + setCreateWidgetFunction([](Project *project) { + return new CppFileSettingsForProjectWidget(project); + }); + ProjectPanelFactory::registerFactory(this); + } +}; + +void setupCppFileSettingsProjectPanel() +{ + static CppFileSettingsProjectPanelFactory theCppFileSettingsProjectPanelFactory; +} + } // namespace CppEditor::Internal #include diff --git a/src/plugins/cppeditor/cppfilesettingspage.h b/src/plugins/cppeditor/cppfilesettingspage.h index d82ca6e8bb3..fde1fb28395 100644 --- a/src/plugins/cppeditor/cppfilesettingspage.h +++ b/src/plugins/cppeditor/cppfilesettingspage.h @@ -85,4 +85,6 @@ private: Private * const d; }; +void setupCppFileSettingsProjectPanel(); + } // namespace CppEditor::Internal diff --git a/src/plugins/cppeditor/cppquickfixprojectsettingswidget.cpp b/src/plugins/cppeditor/cppquickfixprojectsettingswidget.cpp index c82985043f2..80866402b90 100644 --- a/src/plugins/cppeditor/cppquickfixprojectsettingswidget.cpp +++ b/src/plugins/cppeditor/cppquickfixprojectsettingswidget.cpp @@ -5,17 +5,35 @@ #include "cppeditorconstants.h" #include "cppeditortr.h" +#include "cppquickfixprojectsettings.h" #include "cppquickfixsettingswidget.h" +#include + #include #include #include +using namespace ProjectExplorer; + namespace CppEditor::Internal { -CppQuickFixProjectSettingsWidget::CppQuickFixProjectSettingsWidget(ProjectExplorer::Project *project, - QWidget *parent) - : ProjectExplorer::ProjectSettingsWidget(parent) +class CppQuickFixProjectSettingsWidget : public ProjectSettingsWidget +{ +public: + explicit CppQuickFixProjectSettingsWidget(Project *project); + +private: + void currentItemChanged(bool useGlobalSettings); + void buttonCustomClicked(); + + CppQuickFixSettingsWidget *m_settingsWidget; + CppQuickFixProjectsSettings::CppQuickFixProjectsSettingsPtr m_projectSettings; + + QPushButton *m_pushButton; +}; + +CppQuickFixProjectSettingsWidget::CppQuickFixProjectSettingsWidget(Project *project) { setGlobalSettingsId(CppEditor::Constants::QUICK_FIX_SETTINGS_ID); m_projectSettings = CppQuickFixProjectsSettings::getSettings(project); @@ -50,8 +68,6 @@ CppQuickFixProjectSettingsWidget::CppQuickFixProjectSettingsWidget(ProjectExplor }); } -CppQuickFixProjectSettingsWidget::~CppQuickFixProjectSettingsWidget() = default; - void CppQuickFixProjectSettingsWidget::currentItemChanged(bool useGlobalSettings) { if (useGlobalSettings) { @@ -88,4 +104,24 @@ void CppQuickFixProjectSettingsWidget::buttonCustomClicked() } } +class CppQuickFixProjectPanelFactory final : public ProjectPanelFactory +{ +public: + CppQuickFixProjectPanelFactory() + { + setPriority(100); + setId(Constants::QUICK_FIX_PROJECT_PANEL_ID); + setDisplayName(Tr::tr(Constants::QUICK_FIX_SETTINGS_DISPLAY_NAME)); + setCreateWidgetFunction([](Project *project) { + return new CppQuickFixProjectSettingsWidget(project); + }); + ProjectPanelFactory::registerFactory(this); + } +}; + +void setupCppQuickFixProjectPanel() +{ + static CppQuickFixProjectPanelFactory theCppQuickFixProjectPanelFactory; +} + } // CppEditor::Internal diff --git a/src/plugins/cppeditor/cppquickfixprojectsettingswidget.h b/src/plugins/cppeditor/cppquickfixprojectsettingswidget.h index 89a0936a5fd..a88395cc731 100644 --- a/src/plugins/cppeditor/cppquickfixprojectsettingswidget.h +++ b/src/plugins/cppeditor/cppquickfixprojectsettingswidget.h @@ -3,35 +3,8 @@ #pragma once -#include "cppquickfixprojectsettings.h" -#include - -QT_BEGIN_NAMESPACE -class QPushButton; -QT_END_NAMESPACE - -namespace ProjectExplorer { class Project; } - namespace CppEditor::Internal { -class CppQuickFixSettingsWidget; -class CppQuickFixProjectSettingsWidget : public ProjectExplorer::ProjectSettingsWidget -{ - Q_OBJECT - -public: - explicit CppQuickFixProjectSettingsWidget(ProjectExplorer::Project *project, - QWidget *parent = nullptr); - ~CppQuickFixProjectSettingsWidget(); - -private: - void currentItemChanged(bool useGlobalSettings); - void buttonCustomClicked(); - - CppQuickFixSettingsWidget *m_settingsWidget; - CppQuickFixProjectsSettings::CppQuickFixProjectsSettingsPtr m_projectSettings; - - QPushButton *m_pushButton; -}; +void setupCppQuickFixProjectPanel(); } // CppEditor::Internal From 4dc0cf076b12c34ef29c08f25414e962cab86c3d Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 16 Nov 2023 13:17:07 +0100 Subject: [PATCH 0222/1546] TextEditor: Remove unused member functions from RefactoringChanges Change-Id: I7e301fcf7be7690e88d9b31e60cf900660336a07 Reviewed-by: David Schulz --- src/plugins/texteditor/refactoringchanges.cpp | 15 --------------- src/plugins/texteditor/refactoringchanges.h | 2 -- 2 files changed, 17 deletions(-) diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp index 1398d55bcaa..8a14376f87c 100644 --- a/src/plugins/texteditor/refactoringchanges.cpp +++ b/src/plugins/texteditor/refactoringchanges.cpp @@ -87,16 +87,6 @@ bool RefactoringChanges::createFile(const FilePath &filePath, return true; } -bool RefactoringChanges::removeFile(const FilePath &filePath) const -{ - if (!filePath.exists()) - return false; - - // ### implement! - qWarning() << "RefactoringChanges::removeFile is not implemented"; - return true; -} - TextEditorWidget *RefactoringChanges::openEditor(const FilePath &filePath, bool activate, int line, @@ -116,11 +106,6 @@ TextEditorWidget *RefactoringChanges::openEditor(const FilePath &filePath, return TextEditorWidget::fromEditor(editor); } -RefactoringFilePtr RefactoringChanges::file(TextEditorWidget *editor) -{ - return RefactoringFilePtr(new RefactoringFile(editor)); -} - RefactoringFilePtr RefactoringChanges::file(const FilePath &filePath) const { return RefactoringFilePtr(new RefactoringFile(filePath, m_data)); diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h index f657095287a..9b8a322e973 100644 --- a/src/plugins/texteditor/refactoringchanges.h +++ b/src/plugins/texteditor/refactoringchanges.h @@ -110,13 +110,11 @@ public: explicit RefactoringChanges(RefactoringChangesData *data = nullptr); virtual ~RefactoringChanges(); - static RefactoringFilePtr file(TextEditorWidget *editor); RefactoringFilePtr file(const Utils::FilePath &filePath) const; bool createFile(const Utils::FilePath &filePath, const QString &contents, bool reindent = true, bool openEditor = true) const; - bool removeFile(const Utils::FilePath &filePath) const; protected: static TextEditorWidget *openEditor(const Utils::FilePath &filePath, From 9ef557e7ac3be74b0d011af4fd9c5ddad598f707 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Nov 2023 14:37:12 +0100 Subject: [PATCH 0223/1546] FakeVim: Simplify completion support setup That's the "word based" completion triggered by Ctrl-N. Change-Id: Ib35d7e6d2fa0fc144cd92d09d22c279d50aa2fdc Reviewed-by: David Schulz --- src/plugins/fakevim/fakevimplugin.cpp | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp index f14cbbb2027..ca17b3f49cd 100644 --- a/src/plugins/fakevim/fakevimplugin.cpp +++ b/src/plugins/fakevim/fakevimplugin.cpp @@ -347,8 +347,6 @@ using UserCommandMap = QMap; // /////////////////////////////////////////////////////////////////////// -class FakeVimPluginRunData; - class FakeVimPluginPrivate : public QObject { Q_OBJECT @@ -428,7 +426,6 @@ public: UserCommandMap m_defaultUserCommandMap; MiniBuffer *m_miniBuffer = nullptr; - FakeVimPluginRunData *runData = nullptr; QString m_lastHighlight; @@ -870,6 +867,8 @@ private: QString m_needle; }; +static FakeVimCompletionAssistProvider theFakeVimCompletionAssistProvider; + class FakeVimAssistProposalItem final : public AssistProposalItem { public: @@ -967,17 +966,7 @@ IAssistProcessor *FakeVimCompletionAssistProvider::createProcessor(const AssistI } -/////////////////////////////////////////////////////////////////////// -// -// FakeVimPluginRunData -// -/////////////////////////////////////////////////////////////////////// - -class FakeVimPluginRunData -{ -public: - FakeVimCompletionAssistProvider wordProvider; -}; +// FakeVimUserCommandsModel QVariant FakeVimUserCommandsModel::data(const QModelIndex &index, int role) const { @@ -1028,7 +1017,6 @@ FakeVimPluginPrivate::FakeVimPluginPrivate() void FakeVimPluginPrivate::initialize() { - runData = new FakeVimPluginRunData; /* // Set completion settings and keep them up to date. TextEditorSettings *textEditorSettings = TextEditorSettings::instance(); @@ -1591,7 +1579,7 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor) }); handler->simpleCompletionRequested.set([this, handler](const QString &needle, bool forward) { - runData->wordProvider.setActive(needle, forward, handler); + theFakeVimCompletionAssistProvider.setActive(needle, forward, handler); }); handler->windowCommandRequested.set([this, handler](const QString &map, int count) { @@ -1726,7 +1714,7 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor) handler->completionRequested.set([this, tew] { if (tew) - tew->invokeAssist(Completion, &runData->wordProvider); + tew->invokeAssist(Completion, &theFakeVimCompletionAssistProvider); }); handler->processOutput.set([](const QString &command, const QString &input, QString *output) { @@ -2037,9 +2025,6 @@ void FakeVimPlugin::initialize() ExtensionSystem::IPlugin::ShutdownFlag FakeVimPlugin::aboutToShutdown() { - delete dd->runData; - dd->runData = nullptr; - StatusBarManager::destroyStatusBarWidget(dd->m_miniBuffer); dd->m_miniBuffer = nullptr; return SynchronousShutdown; From 9ae6b3524a94c85252a276da92fea0097c60a628 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Nov 2023 10:46:17 +0100 Subject: [PATCH 0224/1546] ProjectExplorer: Use new construction pattern for comments panel Change-Id: I3140acc661e649bcec2e24808bd594c5bc6521d0 Reviewed-by: Christian Stenger --- .../projectcommentssettings.cpp | 94 +++++++++++-------- .../projectexplorer/projectcommentssettings.h | 13 +-- .../projectexplorer/projectexplorer.cpp | 14 +-- 3 files changed, 60 insertions(+), 61 deletions(-) diff --git a/src/plugins/projectexplorer/projectcommentssettings.cpp b/src/plugins/projectexplorer/projectcommentssettings.cpp index b07cea9b290..1858f96213e 100644 --- a/src/plugins/projectexplorer/projectcommentssettings.cpp +++ b/src/plugins/projectexplorer/projectcommentssettings.cpp @@ -4,22 +4,24 @@ #include "projectcommentssettings.h" #include "project.h" +#include "projectexplorertr.h" +#include "projectmanager.h" +#include "projectpanelfactory.h" +#include "projectsettingswidget.h" #include #include -#include #include using namespace TextEditor; using namespace Utils; -namespace ProjectExplorer { -namespace Internal { +namespace ProjectExplorer::Internal { const char kUseGlobalKey[] = "UseGlobalKey"; -ProjectCommentsSettings::ProjectCommentsSettings(ProjectExplorer::Project *project) +ProjectCommentsSettings::ProjectCommentsSettings(Project *project) : m_project(project) { loadSettings(); @@ -90,45 +92,63 @@ void ProjectCommentsSettings::saveSettings() m_project->setNamedSettings(CommentsSettings::mainSettingsKey(), variantFromStore(data)); } -class ProjectCommentsSettingsWidget::Private +class ProjectCommentsSettingsWidget final : public ProjectSettingsWidget { public: - Private(ProjectExplorer::Project *project) : settings(project) {} + ProjectCommentsSettingsWidget(Project *project) + : m_settings(project) + { + setGlobalSettingsId(TextEditor::Constants::TEXT_EDITOR_COMMENTS_SETTINGS); + const auto layout = new QVBoxLayout(this); + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(&m_widget); - ProjectCommentsSettings settings; - CommentsSettingsWidget widget{settings.settings()}; - QCheckBox useGlobalSettingsCheckBox; + const auto updateGlobalSettingsCheckBox = [this] { + setUseGlobalSettingsCheckBoxEnabled(true); + setUseGlobalSettings(m_settings.useGlobalSettings()); + m_widget.setEnabled(!useGlobalSettings()); + }; + updateGlobalSettingsCheckBox(); + connect(TextEditorSettings::instance(), &TextEditorSettings::commentsSettingsChanged, + this, updateGlobalSettingsCheckBox); + connect(this, &ProjectSettingsWidget::useGlobalSettingsChanged, this, + [this](bool checked) { + m_widget.setEnabled(!checked); + m_settings.setUseGlobalSettings(checked); + if (!checked) + m_settings.setSettings(m_widget.settingsData()); + }); + connect(&m_widget, &CommentsSettingsWidget::settingsChanged, this, [this] { + m_settings.setSettings(m_widget.settingsData()); + }); + } + +private: + ProjectCommentsSettings m_settings; + CommentsSettingsWidget m_widget{m_settings.settings()}; }; -ProjectCommentsSettingsWidget::ProjectCommentsSettingsWidget(ProjectExplorer::Project *project) - : d(new Private(project)) +class CommentsSettingsProjectPanelFactory final : public ProjectPanelFactory { - setGlobalSettingsId(TextEditor::Constants::TEXT_EDITOR_COMMENTS_SETTINGS); - const auto layout = new QVBoxLayout(this); - layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(&d->widget); +public: + CommentsSettingsProjectPanelFactory() + { + setPriority(45); + setDisplayName(Tr::tr("Documentation Comments")); + setCreateWidgetFunction([](Project *project) { + return new ProjectCommentsSettingsWidget(project); + }); - const auto updateGlobalSettingsCheckBox = [this] { - setUseGlobalSettingsCheckBoxEnabled(true); - setUseGlobalSettings(d->settings.useGlobalSettings()); - d->widget.setEnabled(!useGlobalSettings()); - }; - updateGlobalSettingsCheckBox(); - connect(TextEditorSettings::instance(), &TextEditorSettings::commentsSettingsChanged, - this, updateGlobalSettingsCheckBox); - connect(this, &ProjectSettingsWidget::useGlobalSettingsChanged, this, - [this](bool checked) { - d->widget.setEnabled(!checked); - d->settings.setUseGlobalSettings(checked); - if (!checked) - d->settings.setSettings(d->widget.settingsData()); - }); - connect(&d->widget, &CommentsSettingsWidget::settingsChanged, this, [this] { - d->settings.setSettings(d->widget.settingsData()); - }); + TextEditor::TextEditorSettings::setCommentsSettingsRetriever([](const FilePath &filePath) { + return ProjectCommentsSettings(ProjectManager::projectForFile(filePath)).settings(); + }); + ProjectPanelFactory::registerFactory(this); + } +}; + +void setupCommentsSettingsProjectPanel() +{ + static CommentsSettingsProjectPanelFactory theCommentsSettingsProjectPanelFactory; } -ProjectCommentsSettingsWidget::~ProjectCommentsSettingsWidget() { delete d; } - -} // namespace Internal -} // namespace ProjectExplorer +} // ProjectExplorer::Internal diff --git a/src/plugins/projectexplorer/projectcommentssettings.h b/src/plugins/projectexplorer/projectcommentssettings.h index 5beb4f27a7a..850078d7b7f 100644 --- a/src/plugins/projectexplorer/projectcommentssettings.h +++ b/src/plugins/projectexplorer/projectcommentssettings.h @@ -3,8 +3,6 @@ #pragma once -#include "projectsettingswidget.h" - #include namespace ProjectExplorer { @@ -33,16 +31,7 @@ private: bool m_useGlobalSettings = true; }; -class ProjectCommentsSettingsWidget : public ProjectSettingsWidget -{ -public: - ProjectCommentsSettingsWidget(ProjectExplorer::Project *project); - ~ProjectCommentsSettingsWidget(); - -private: - class Private; - Private * const d; -}; +void setupCommentsSettingsProjectPanel(); } // namespace Internal } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index c180d70658e..6a98483ad4a 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -885,19 +885,9 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er setupEditorSettingsProjectPanel(); setupCodeStyleProjectPanel(); + setupCommentsSettingsProjectPanel(); - auto panelFactory = new ProjectExplorer::ProjectPanelFactory; - panelFactory->setPriority(45); - panelFactory->setDisplayName(Tr::tr("Documentation Comments")); - panelFactory->setCreateWidgetFunction([](ProjectExplorer::Project *project) { - return new ProjectCommentsSettingsWidget(project); - }); - ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory); - TextEditor::TextEditorSettings::setCommentsSettingsRetriever([](const FilePath &filePath) { - return ProjectCommentsSettings(ProjectManager::projectForFile(filePath)).settings(); - }); - - panelFactory = new ProjectPanelFactory; + auto panelFactory = new ProjectPanelFactory; panelFactory->setPriority(50); panelFactory->setDisplayName(Tr::tr("Dependencies")); panelFactory->setCreateWidgetFunction([](Project *project) { return new DependenciesWidget(project); }); From 0de9d31e843424746701cddce2e6a2ddf77be5d2 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Nov 2023 12:41:58 +0100 Subject: [PATCH 0225/1546] ProjectExplorer: Use new construction pattern for dependencies panel Change-Id: Ic73e426150fa8479a62fc0b50b743e707efaad41 Reviewed-by: Christian Stenger --- .../projectexplorer/dependenciespanel.cpp | 130 +++++++++++++----- .../projectexplorer/dependenciespanel.h | 74 +--------- .../projectexplorer/projectexplorer.cpp | 7 +- 3 files changed, 98 insertions(+), 113 deletions(-) diff --git a/src/plugins/projectexplorer/dependenciespanel.cpp b/src/plugins/projectexplorer/dependenciespanel.cpp index 5c6990b67d8..1e9f2c1d0c2 100644 --- a/src/plugins/projectexplorer/dependenciespanel.cpp +++ b/src/plugins/projectexplorer/dependenciespanel.cpp @@ -6,6 +6,8 @@ #include "project.h" #include "projectexplorertr.h" #include "projectmanager.h" +#include "projectpanelfactory.h" +#include "projectsettingswidget.h" #include #include @@ -14,18 +16,33 @@ #include #include -#include -#include -#include - +#include #include #include -#include -#include #include +#include +#include +#include -namespace ProjectExplorer { -namespace Internal { +namespace ProjectExplorer::Internal { + +class DependenciesModel : public QAbstractListModel +{ +public: + explicit DependenciesModel(Project *project, QObject *parent = nullptr); + + int rowCount(const QModelIndex &index) const override; + int columnCount(const QModelIndex &index) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + +private: + void resetModel(); + + Project *m_project; + QList m_projects; +}; DependenciesModel::DependenciesModel(Project *project, QObject *parent) : QAbstractListModel(parent) @@ -124,6 +141,21 @@ Qt::ItemFlags DependenciesModel::flags(const QModelIndex &index) const // // DependenciesView // + +class DependenciesView : public QTreeView +{ +public: + explicit DependenciesView(QWidget *parent); + + QSize sizeHint() const override; + void setModel(QAbstractItemModel *model) override; + +private: + void updateSizeHint(); + + QSize m_sizeHint; +}; + DependenciesView::DependenciesView(QWidget *parent) : QTreeView(parent) { @@ -190,36 +222,62 @@ void DependenciesView::updateSizeHint() // DependenciesWidget // -DependenciesWidget::DependenciesWidget(Project *project, QWidget *parent) : ProjectSettingsWidget(parent), - m_project(project), - m_model(new DependenciesModel(project, this)) +class DependenciesWidget : public ProjectSettingsWidget { - setUseGlobalSettingsCheckBoxVisible(false); - setUseGlobalSettingsLabelVisible(false); - auto vbox = new QVBoxLayout(this); - vbox->setContentsMargins(0, 0, 0, 0); - m_detailsContainer = new Utils::DetailsWidget(this); - m_detailsContainer->setState(Utils::DetailsWidget::NoSummary); - vbox->addWidget(m_detailsContainer); +public: + explicit DependenciesWidget(Project *project) + : m_project(project), + m_model(new DependenciesModel(project, this)) + { + setUseGlobalSettingsCheckBoxVisible(false); + setUseGlobalSettingsLabelVisible(false); + auto vbox = new QVBoxLayout(this); + vbox->setContentsMargins(0, 0, 0, 0); + m_detailsContainer = new Utils::DetailsWidget(this); + m_detailsContainer->setState(Utils::DetailsWidget::NoSummary); + vbox->addWidget(m_detailsContainer); - auto detailsWidget = new QWidget(m_detailsContainer); - m_detailsContainer->setWidget(detailsWidget); - auto layout = new QGridLayout(detailsWidget); - layout->setContentsMargins(0, -1, 0, -1); - auto treeView = new DependenciesView(this); - treeView->setModel(m_model); - treeView->setHeaderHidden(true); - layout->addWidget(treeView, 0 ,0); - layout->addItem(new QSpacerItem(0, 0 , QSizePolicy::Expanding, QSizePolicy::Fixed), 0, 1); + auto detailsWidget = new QWidget(m_detailsContainer); + m_detailsContainer->setWidget(detailsWidget); + auto layout = new QGridLayout(detailsWidget); + layout->setContentsMargins(0, -1, 0, -1); + auto treeView = new DependenciesView(this); + treeView->setModel(m_model); + treeView->setHeaderHidden(true); + layout->addWidget(treeView, 0 ,0); + layout->addItem(new QSpacerItem(0, 0 , QSizePolicy::Expanding, QSizePolicy::Fixed), 0, 1); - m_cascadeSetActiveCheckBox = new QCheckBox; - m_cascadeSetActiveCheckBox->setText(Tr::tr("Synchronize configuration")); - m_cascadeSetActiveCheckBox->setToolTip(Tr::tr("Synchronize active kit, build, and deploy configuration between projects.")); - m_cascadeSetActiveCheckBox->setChecked(ProjectManager::isProjectConfigurationCascading()); - connect(m_cascadeSetActiveCheckBox, &QCheckBox::toggled, - ProjectManager::instance(), &ProjectManager::setProjectConfigurationCascading); - layout->addWidget(m_cascadeSetActiveCheckBox, 1, 0, 2, 1); + m_cascadeSetActiveCheckBox = new QCheckBox; + m_cascadeSetActiveCheckBox->setText(Tr::tr("Synchronize configuration")); + m_cascadeSetActiveCheckBox->setToolTip(Tr::tr("Synchronize active kit, build, and deploy configuration between projects.")); + m_cascadeSetActiveCheckBox->setChecked(ProjectManager::isProjectConfigurationCascading()); + connect(m_cascadeSetActiveCheckBox, &QCheckBox::toggled, + ProjectManager::instance(), &ProjectManager::setProjectConfigurationCascading); + layout->addWidget(m_cascadeSetActiveCheckBox, 1, 0, 2, 1); + } + +private: + Project *m_project; + DependenciesModel *m_model; + Utils::DetailsWidget *m_detailsContainer; + QCheckBox *m_cascadeSetActiveCheckBox; +}; + +class DependenciesProjectPanelFactory final : public ProjectPanelFactory +{ +public: + DependenciesProjectPanelFactory() + { + setPriority(50); + setDisplayName(Tr::tr("Dependencies")); + setCreateWidgetFunction([](Project *project) { return new DependenciesWidget(project); }); + ProjectPanelFactory::registerFactory(this); + } +}; + +void setupDependenciesProjectPanel() +{ + static DependenciesProjectPanelFactory theDependenciesProjectPanelFactory; } -} // namespace Internal -} // namespace ProjectExplorer +} // ProjectExplorer::Internal diff --git a/src/plugins/projectexplorer/dependenciespanel.h b/src/plugins/projectexplorer/dependenciespanel.h index 5362243f317..5a58d73a201 100644 --- a/src/plugins/projectexplorer/dependenciespanel.h +++ b/src/plugins/projectexplorer/dependenciespanel.h @@ -3,76 +3,8 @@ #pragma once -#include +namespace ProjectExplorer::Internal { -#include -#include +void setupDependenciesProjectPanel(); -QT_BEGIN_NAMESPACE -class QCheckBox; -QT_END_NAMESPACE - -namespace Utils { class DetailsWidget; } - -namespace ProjectExplorer { - -class Project; - -namespace Internal { - -// -// DependenciesModel -// - -class DependenciesModel : public QAbstractListModel -{ - Q_OBJECT - -public: - explicit DependenciesModel(Project *project, QObject *parent = nullptr); - - int rowCount(const QModelIndex &index) const override; - int columnCount(const QModelIndex &index) const override; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - Qt::ItemFlags flags(const QModelIndex &index) const override; - -private: - void resetModel(); - - Project *m_project; - QList m_projects; -}; - -class DependenciesView : public QTreeView -{ - Q_OBJECT - -public: - explicit DependenciesView(QWidget *parent); - - QSize sizeHint() const override; - void setModel(QAbstractItemModel *model) override; - -private: - void updateSizeHint(); - - QSize m_sizeHint; -}; - -class DependenciesWidget : public ProjectSettingsWidget -{ - Q_OBJECT - -public: - explicit DependenciesWidget(Project *project, QWidget *parent = nullptr); - -private: - Project *m_project; - DependenciesModel *m_model; - Utils::DetailsWidget *m_detailsContainer; - QCheckBox *m_cascadeSetActiveCheckBox; -}; - -} // namespace Internal -} // namespace ProjectExplorer +} // ProjectExplorer::Internal diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 6a98483ad4a..4908e23e084 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -886,14 +886,9 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er setupEditorSettingsProjectPanel(); setupCodeStyleProjectPanel(); setupCommentsSettingsProjectPanel(); + setupDependenciesProjectPanel(); auto panelFactory = new ProjectPanelFactory; - panelFactory->setPriority(50); - panelFactory->setDisplayName(Tr::tr("Dependencies")); - panelFactory->setCreateWidgetFunction([](Project *project) { return new DependenciesWidget(project); }); - ProjectPanelFactory::registerFactory(panelFactory); - - panelFactory = new ProjectPanelFactory; panelFactory->setPriority(60); panelFactory->setDisplayName(Tr::tr("Environment")); panelFactory->setCreateWidgetFunction([](Project *project) { From 4dc3730a30356761b3a765c84b7e11b34138ac9f Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Nov 2023 12:49:44 +0100 Subject: [PATCH 0226/1546] ProjectExplorer: Use new construction pattern for env panel Change-Id: I79edce493377d78a8f2a941a739cf898bef40dfd Reviewed-by: Christian Stenger --- .../projectexplorer/projectexplorer.cpp | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 4908e23e084..4f8c6b9ba77 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -401,6 +401,25 @@ public: } }; +class ProjectEnvironmentPanelFactory final : public ProjectPanelFactory +{ +public: + ProjectEnvironmentPanelFactory() + { + setPriority(60); + setDisplayName(Tr::tr("Environment")); + setCreateWidgetFunction([](Project *project) { + return new ProjectEnvironmentWidget(project); + }); + ProjectPanelFactory::registerFactory(this); + } +}; + +static void setupProjectEnvironmentPanel() +{ + static ProjectEnvironmentPanelFactory theProjectEnvironmentPanelFactory; +} + class AllProjectFilesFilter : public DirectoryFilter { public: @@ -887,14 +906,7 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er setupCodeStyleProjectPanel(); setupCommentsSettingsProjectPanel(); setupDependenciesProjectPanel(); - - auto panelFactory = new ProjectPanelFactory; - panelFactory->setPriority(60); - panelFactory->setDisplayName(Tr::tr("Environment")); - panelFactory->setCreateWidgetFunction([](Project *project) { - return new ProjectEnvironmentWidget(project); - }); - ProjectPanelFactory::registerFactory(panelFactory); + setupProjectEnvironmentPanel(); RunConfiguration::registerAspect(); From e7b140fbfbd491a892602f9bcb955364a822d8be Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Nov 2023 15:42:42 +0100 Subject: [PATCH 0227/1546] Todo: Use new construction pattern for project panel factory Unusual extra parameter for now due to the unusual extra connect. Can be avoided later by making the TodoItemsProvider a (on-demand created) singleton. Change-Id: I5269e8c5b7faa63653484dfa7098723a4e152e7d Reviewed-by: Christian Stenger --- src/plugins/todo/todoplugin.cpp | 12 +--- .../todo/todoprojectsettingswidget.cpp | 60 +++++++++++++++++-- src/plugins/todo/todoprojectsettingswidget.h | 42 ++----------- 3 files changed, 62 insertions(+), 52 deletions(-) diff --git a/src/plugins/todo/todoplugin.cpp b/src/plugins/todo/todoplugin.cpp index dfb0f866fb8..42b62333ced 100644 --- a/src/plugins/todo/todoplugin.cpp +++ b/src/plugins/todo/todoplugin.cpp @@ -44,16 +44,8 @@ TodoPluginPrivate::TodoPluginPrivate() createItemsProvider(); createTodoOutputPane(); - auto panelFactory = new ProjectExplorer::ProjectPanelFactory; - panelFactory->setPriority(100); - panelFactory->setDisplayName(Tr::tr("To-Do")); - panelFactory->setCreateWidgetFunction([this](ProjectExplorer::Project *project) { - auto widget = new TodoProjectSettingsWidget(project); - connect(widget, &TodoProjectSettingsWidget::projectSettingsChanged, - m_todoItemsProvider, [this, project] { m_todoItemsProvider->projectSettingsChanged(project); }); - return widget; - }); - ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory); + setupTodoSettingsProjectPanel(m_todoItemsProvider); + connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested, this, [this] { m_settings.save(Core::ICore::settings()); }); } diff --git a/src/plugins/todo/todoprojectsettingswidget.cpp b/src/plugins/todo/todoprojectsettingswidget.cpp index 6f68ccc37ba..61a4cbc958c 100644 --- a/src/plugins/todo/todoprojectsettingswidget.cpp +++ b/src/plugins/todo/todoprojectsettingswidget.cpp @@ -4,23 +4,52 @@ #include "todoprojectsettingswidget.h" #include "constants.h" +#include "todoitemsprovider.h" #include "todotr.h" #include +#include #include #include #include -namespace Todo { -namespace Internal { +using namespace ProjectExplorer; + +namespace Todo::Internal { static QString excludePlaceholder() { return Tr::tr(""); } +class TodoProjectSettingsWidget : public ProjectExplorer::ProjectSettingsWidget +{ + Q_OBJECT + +public: + explicit TodoProjectSettingsWidget(ProjectExplorer::Project *project); + ~TodoProjectSettingsWidget() override; + +signals: + void projectSettingsChanged(); + +private: + void addExcludedPatternButtonClicked(); + void removeExcludedPatternButtonClicked(); + void setExcludedPatternsButtonsEnabled(); + void excludedPatternChanged(QListWidgetItem *item); + QListWidgetItem *addToExcludedPatternsList(const QString &pattern); + void loadSettings(); + void saveSettings(); + void prepareItem(QListWidgetItem *item) const; + + ProjectExplorer::Project *m_project; + QListWidget *m_excludedPatternsList; + QPushButton *m_removeExcludedPatternButton; +}; + TodoProjectSettingsWidget::TodoProjectSettingsWidget(ProjectExplorer::Project *project) : m_project(project) { @@ -137,5 +166,28 @@ void TodoProjectSettingsWidget::excludedPatternChanged(QListWidgetItem *item) m_excludedPatternsList->setCurrentItem(nullptr); } -} // namespace Internal -} // namespace Todo +class TodoSettingsProjectPanelFactory : public ProjectPanelFactory +{ +public: + TodoSettingsProjectPanelFactory(TodoItemsProvider *provider) + { + setPriority(100); + setDisplayName(Tr::tr("To-Do")); + setCreateWidgetFunction([provider](Project *project) { + auto widget = new TodoProjectSettingsWidget(project); + QObject::connect(widget, &TodoProjectSettingsWidget::projectSettingsChanged, + provider, [project, provider] { provider->projectSettingsChanged(project); }); + return widget; + }); + ProjectPanelFactory::registerFactory(this); + } +}; + +void setupTodoSettingsProjectPanel(TodoItemsProvider *provider) +{ + static TodoSettingsProjectPanelFactory theTodoSettingsProjectPanelFactory(provider); +} + +} // Todo::Internal + +#include "todoprojectsettingswidget.moc" diff --git a/src/plugins/todo/todoprojectsettingswidget.h b/src/plugins/todo/todoprojectsettingswidget.h index 23b690f0d77..33ea207dfcc 100644 --- a/src/plugins/todo/todoprojectsettingswidget.h +++ b/src/plugins/todo/todoprojectsettingswidget.h @@ -3,44 +3,10 @@ #pragma once -#include +namespace Todo::Internal { -QT_BEGIN_NAMESPACE -class QListWidget; -class QListWidgetItem; -class QPushButton; -QT_END_NAMESPACE +class TodoItemsProvider; -namespace ProjectExplorer { class Project; } +void setupTodoSettingsProjectPanel(TodoItemsProvider *provider); -namespace Todo { -namespace Internal { - -class TodoProjectSettingsWidget : public ProjectExplorer::ProjectSettingsWidget -{ - Q_OBJECT - -public: - explicit TodoProjectSettingsWidget(ProjectExplorer::Project *project); - ~TodoProjectSettingsWidget() override; - -signals: - void projectSettingsChanged(); - -private: - void addExcludedPatternButtonClicked(); - void removeExcludedPatternButtonClicked(); - void setExcludedPatternsButtonsEnabled(); - void excludedPatternChanged(QListWidgetItem *item); - QListWidgetItem *addToExcludedPatternsList(const QString &pattern); - void loadSettings(); - void saveSettings(); - void prepareItem(QListWidgetItem *item) const; - - ProjectExplorer::Project *m_project; - QListWidget *m_excludedPatternsList; - QPushButton *m_removeExcludedPatternButton; -}; - -} // namespace Internal -} // namespace Todo +} // Todo::Internal From 2b39aa22fc6b259a04bc126dd1df30e70071999f Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Nov 2023 15:07:42 +0100 Subject: [PATCH 0228/1546] LanguageClient: Use new construction pattern for project panel Change-Id: If3fa41d33a5d9b39d2596d619251bff3cfdf4b5d Reviewed-by: Christian Stenger --- .../languageclient/languageclientplugin.cpp | 9 +-- .../languageclient/languageclientsettings.cpp | 69 +++++++++++++------ .../languageclient/languageclientsettings.h | 13 +--- 3 files changed, 52 insertions(+), 39 deletions(-) diff --git a/src/plugins/languageclient/languageclientplugin.cpp b/src/plugins/languageclient/languageclientplugin.cpp index 18e0eca21eb..2143d0c3115 100644 --- a/src/plugins/languageclient/languageclientplugin.cpp +++ b/src/plugins/languageclient/languageclientplugin.cpp @@ -11,8 +11,6 @@ #include #include -#include - #include #include @@ -40,12 +38,7 @@ void LanguageClientPlugin::initialize() { using namespace Core; - auto panelFactory = new ProjectExplorer::ProjectPanelFactory; - panelFactory->setPriority(35); - panelFactory->setDisplayName(Tr::tr("Language Server")); - panelFactory->setCreateWidgetFunction( - [](ProjectExplorer::Project *project) { return new ProjectSettingsWidget(project); }); - ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory); + setupLanguageClientProjectPanel(); LanguageClientManager::init(); LanguageClientSettings::registerClientType({Constants::LANGUAGECLIENT_STDIO_SETTINGS_ID, diff --git a/src/plugins/languageclient/languageclientsettings.cpp b/src/plugins/languageclient/languageclientsettings.cpp index 95a33eff352..0aeb2fc8d4b 100644 --- a/src/plugins/languageclient/languageclientsettings.cpp +++ b/src/plugins/languageclient/languageclientsettings.cpp @@ -15,6 +15,8 @@ #include #include +#include +#include #include #include @@ -66,6 +68,7 @@ constexpr char typedClientsKey[] = "typedClients"; constexpr char outlineSortedKey[] = "outlineSorted"; constexpr char mimeType[] = "application/language.client.setting"; +using namespace ProjectExplorer; using namespace Utils; namespace LanguageClient { @@ -1105,30 +1108,56 @@ void ProjectSettings::setJson(const QByteArray &json) LanguageClientManager::updateWorkspaceConfiguration(m_project, newConfig); } -ProjectSettingsWidget::ProjectSettingsWidget(ProjectExplorer::Project *project) - : m_settings(project) +class LanguageClientProjectSettingsWidget : public ProjectSettingsWidget { - setUseGlobalSettingsCheckBoxVisible(false); - setGlobalSettingsId(Constants::LANGUAGECLIENT_SETTINGS_PAGE); - setExpanding(true); +public: + explicit LanguageClientProjectSettingsWidget(Project *project) + : m_settings(project) + { + setUseGlobalSettingsCheckBoxVisible(false); + setGlobalSettingsId(Constants::LANGUAGECLIENT_SETTINGS_PAGE); + setExpanding(true); - TextEditor::BaseTextEditor *editor = jsonEditor(); - editor->document()->setContents(m_settings.json()); + TextEditor::BaseTextEditor *editor = jsonEditor(); + editor->document()->setContents(m_settings.json()); - auto layout = new QVBoxLayout; - setLayout(layout); - auto group = new QGroupBox(Tr::tr("Workspace Configuration")); - group->setLayout(new QVBoxLayout); - group->layout()->addWidget(new QLabel(Tr::tr( - "Additional JSON configuration sent to all running language servers for this project.\n" - "See the documentation of the specific language server for valid settings."))); - group->layout()->addWidget(editor->widget()); - layout->addWidget(group); + auto layout = new QVBoxLayout; + setLayout(layout); + auto group = new QGroupBox(Tr::tr("Workspace Configuration")); + group->setLayout(new QVBoxLayout); + group->layout()->addWidget(new QLabel(Tr::tr( + "Additional JSON configuration sent to all running language servers for this project.\n" + "See the documentation of the specific language server for valid settings."))); + group->layout()->addWidget(editor->widget()); + layout->addWidget(group); - connect(editor->editorWidget()->textDocument(), - &TextEditor::TextDocument::contentsChanged, - this, - [=]() { m_settings.setJson(editor->document()->contents()); }); + connect(editor->editorWidget()->textDocument(), + &TextEditor::TextDocument::contentsChanged, + this, + [=]() { m_settings.setJson(editor->document()->contents()); }); + } + +private: + ProjectSettings m_settings; +}; + +class LanguageClientProjectPanelFactory : public ProjectPanelFactory +{ +public: + LanguageClientProjectPanelFactory() + { + setPriority(35); + setDisplayName(Tr::tr("Language Server")); + setCreateWidgetFunction([](Project *project) { + return new LanguageClientProjectSettingsWidget(project); + }); + ProjectPanelFactory::registerFactory(this); + } +}; + +void setupLanguageClientProjectPanel() +{ + static LanguageClientProjectPanelFactory theLanguageClientProjectPanelFactory; } } // namespace LanguageClient diff --git a/src/plugins/languageclient/languageclientsettings.h b/src/plugins/languageclient/languageclientsettings.h index 7c33fedad1a..51109a05c9e 100644 --- a/src/plugins/languageclient/languageclientsettings.h +++ b/src/plugins/languageclient/languageclientsettings.h @@ -7,8 +7,6 @@ #include -#include - #include #include #include @@ -208,15 +206,8 @@ private: QByteArray m_json; }; -class ProjectSettingsWidget : public ProjectExplorer::ProjectSettingsWidget -{ -public: - explicit ProjectSettingsWidget(ProjectExplorer::Project *project); - -private: - ProjectSettings m_settings; -}; - LANGUAGECLIENT_EXPORT TextEditor::BaseTextEditor *jsonEditor(); +void setupLanguageClientProjectPanel(); + } // namespace LanguageClient From 3c5520efaa32e6921e03a5495cce44b56872c508 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Nov 2023 15:19:51 +0100 Subject: [PATCH 0229/1546] ProjectExplorer: Let ProjectPanelFactories auto-register Change-Id: Iaca1438f1199c2dd112b61a8ff74f4707867e7c5 Reviewed-by: Christian Stenger --- .../autotest/projectsettingswidget.cpp | 1 - .../axivion/axivionprojectsettings.cpp | 1 - .../clangtoolsprojectsettingswidget.cpp | 6 ++-- src/plugins/copilot/copilotprojectpanel.cpp | 1 - .../cppeditor/cppcodemodelsettingspage.cpp | 1 - src/plugins/cppeditor/cppfilesettingspage.cpp | 1 - .../cppquickfixprojectsettingswidget.cpp | 1 - src/plugins/gitlab/gitlabprojectsettings.cpp | 1 - .../languageclient/languageclientsettings.cpp | 1 - .../codestylesettingspropertiespage.cpp | 1 - .../projectexplorer/dependenciespanel.cpp | 1 - .../editorsettingspropertiespage.cpp | 1 - .../projectcommentssettings.cpp | 1 - .../projectexplorer/projectexplorer.cpp | 1 - .../projectexplorer/projectpanelfactory.cpp | 28 ++++++++++--------- .../projectexplorer/projectpanelfactory.h | 4 --- .../todo/todoprojectsettingswidget.cpp | 1 - 17 files changed, 18 insertions(+), 34 deletions(-) diff --git a/src/plugins/autotest/projectsettingswidget.cpp b/src/plugins/autotest/projectsettingswidget.cpp index 84b3b612f64..e82d9e90201 100644 --- a/src/plugins/autotest/projectsettingswidget.cpp +++ b/src/plugins/autotest/projectsettingswidget.cpp @@ -162,7 +162,6 @@ public: setCreateWidgetFunction([](Project *project) { return new ProjectTestSettingsWidget(project); }); - ProjectPanelFactory::registerFactory(this); } }; diff --git a/src/plugins/axivion/axivionprojectsettings.cpp b/src/plugins/axivion/axivionprojectsettings.cpp index 659933c3bf0..a06a411aad8 100644 --- a/src/plugins/axivion/axivionprojectsettings.cpp +++ b/src/plugins/axivion/axivionprojectsettings.cpp @@ -259,7 +259,6 @@ public: setCreateWidgetFunction([](ProjectExplorer::Project *project) { return new AxivionProjectSettingsWidget(project); }); - ProjectExplorer::ProjectPanelFactory::registerFactory(this); } }; diff --git a/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp b/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp index 0012668dd61..81db07183d0 100644 --- a/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp +++ b/src/plugins/clangtools/clangtoolsprojectsettingswidget.cpp @@ -251,9 +251,9 @@ public: setPriority(100); setId(Constants::PROJECT_PANEL_ID); setDisplayName(Tr::tr("Clang Tools")); - setCreateWidgetFunction( - [](Project *project) { return new ClangToolsProjectSettingsWidget(project); }); - ProjectPanelFactory::registerFactory(this); + setCreateWidgetFunction([](Project *project) { + return new ClangToolsProjectSettingsWidget(project); + }); } }; diff --git a/src/plugins/copilot/copilotprojectpanel.cpp b/src/plugins/copilot/copilotprojectpanel.cpp index 5b570a0de26..12aa5ad2c5d 100644 --- a/src/plugins/copilot/copilotprojectpanel.cpp +++ b/src/plugins/copilot/copilotprojectpanel.cpp @@ -65,7 +65,6 @@ public: setPriority(1000); setDisplayName(Tr::tr("Copilot")); setCreateWidgetFunction(&createCopilotProjectPanel); - ProjectPanelFactory::registerFactory(this); } }; diff --git a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp index 8b494d0b4bf..8bd2ce1eae2 100644 --- a/src/plugins/cppeditor/cppcodemodelsettingspage.cpp +++ b/src/plugins/cppeditor/cppcodemodelsettingspage.cpp @@ -637,7 +637,6 @@ public: setCreateWidgetFunction([](Project *project) { return new ClangdProjectSettingsWidget(project); }); - ProjectPanelFactory::registerFactory(this); } }; diff --git a/src/plugins/cppeditor/cppfilesettingspage.cpp b/src/plugins/cppeditor/cppfilesettingspage.cpp index 84d874ca87b..878879a8a74 100644 --- a/src/plugins/cppeditor/cppfilesettingspage.cpp +++ b/src/plugins/cppeditor/cppfilesettingspage.cpp @@ -597,7 +597,6 @@ public: setCreateWidgetFunction([](Project *project) { return new CppFileSettingsForProjectWidget(project); }); - ProjectPanelFactory::registerFactory(this); } }; diff --git a/src/plugins/cppeditor/cppquickfixprojectsettingswidget.cpp b/src/plugins/cppeditor/cppquickfixprojectsettingswidget.cpp index 80866402b90..feb9777e45b 100644 --- a/src/plugins/cppeditor/cppquickfixprojectsettingswidget.cpp +++ b/src/plugins/cppeditor/cppquickfixprojectsettingswidget.cpp @@ -115,7 +115,6 @@ public: setCreateWidgetFunction([](Project *project) { return new CppQuickFixProjectSettingsWidget(project); }); - ProjectPanelFactory::registerFactory(this); } }; diff --git a/src/plugins/gitlab/gitlabprojectsettings.cpp b/src/plugins/gitlab/gitlabprojectsettings.cpp index 6b4a09c0ade..a4e5a30850d 100644 --- a/src/plugins/gitlab/gitlabprojectsettings.cpp +++ b/src/plugins/gitlab/gitlabprojectsettings.cpp @@ -339,7 +339,6 @@ public: setCreateWidgetFunction([](ProjectExplorer::Project *project) { return new GitLabProjectSettingsWidget(project); }); - ProjectExplorer::ProjectPanelFactory::registerFactory(this); } }; diff --git a/src/plugins/languageclient/languageclientsettings.cpp b/src/plugins/languageclient/languageclientsettings.cpp index 0aeb2fc8d4b..a9fc9ebf6e9 100644 --- a/src/plugins/languageclient/languageclientsettings.cpp +++ b/src/plugins/languageclient/languageclientsettings.cpp @@ -1151,7 +1151,6 @@ public: setCreateWidgetFunction([](Project *project) { return new LanguageClientProjectSettingsWidget(project); }); - ProjectPanelFactory::registerFactory(this); } }; diff --git a/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp b/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp index 6f3f4761241..ed859e84337 100644 --- a/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp @@ -70,7 +70,6 @@ public: setPriority(40); setDisplayName(Tr::tr("Code Style")); setCreateWidgetFunction([](Project *project) { return new CodeStyleSettingsWidget(project); }); - ProjectPanelFactory::registerFactory(this); } }; diff --git a/src/plugins/projectexplorer/dependenciespanel.cpp b/src/plugins/projectexplorer/dependenciespanel.cpp index 1e9f2c1d0c2..3ca788eaf88 100644 --- a/src/plugins/projectexplorer/dependenciespanel.cpp +++ b/src/plugins/projectexplorer/dependenciespanel.cpp @@ -271,7 +271,6 @@ public: setPriority(50); setDisplayName(Tr::tr("Dependencies")); setCreateWidgetFunction([](Project *project) { return new DependenciesWidget(project); }); - ProjectPanelFactory::registerFactory(this); } }; diff --git a/src/plugins/projectexplorer/editorsettingspropertiespage.cpp b/src/plugins/projectexplorer/editorsettingspropertiespage.cpp index 96deedfd625..ba0e4936f91 100644 --- a/src/plugins/projectexplorer/editorsettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/editorsettingspropertiespage.cpp @@ -167,7 +167,6 @@ public: setPriority(30); setDisplayName(Tr::tr("Editor")); setCreateWidgetFunction([](Project *project) { return new EditorSettingsWidget(project); }); - ProjectPanelFactory::registerFactory(this); } }; diff --git a/src/plugins/projectexplorer/projectcommentssettings.cpp b/src/plugins/projectexplorer/projectcommentssettings.cpp index 1858f96213e..00175fbb6cc 100644 --- a/src/plugins/projectexplorer/projectcommentssettings.cpp +++ b/src/plugins/projectexplorer/projectcommentssettings.cpp @@ -142,7 +142,6 @@ public: TextEditor::TextEditorSettings::setCommentsSettingsRetriever([](const FilePath &filePath) { return ProjectCommentsSettings(ProjectManager::projectForFile(filePath)).settings(); }); - ProjectPanelFactory::registerFactory(this); } }; diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 4f8c6b9ba77..f2143cc1549 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -411,7 +411,6 @@ public: setCreateWidgetFunction([](Project *project) { return new ProjectEnvironmentWidget(project); }); - ProjectPanelFactory::registerFactory(this); } }; diff --git a/src/plugins/projectexplorer/projectpanelfactory.cpp b/src/plugins/projectexplorer/projectpanelfactory.cpp index 4a4881e3f8c..4eff3d1ed67 100644 --- a/src/plugins/projectexplorer/projectpanelfactory.cpp +++ b/src/plugins/projectexplorer/projectpanelfactory.cpp @@ -4,6 +4,7 @@ #include "projectpanelfactory.h" #include "project.h" +#include "projectsettingswidget.h" #include "projectwindow.h" #include @@ -14,10 +15,14 @@ using namespace Utils; namespace ProjectExplorer { static QList s_factories; +bool s_sorted = false; ProjectPanelFactory::ProjectPanelFactory() : m_supportsFunction([] (Project *) { return true; }) -{ } +{ + s_factories.append(this); + s_sorted = false; +} int ProjectPanelFactory::priority() const { @@ -39,27 +44,24 @@ void ProjectPanelFactory::setDisplayName(const QString &name) m_displayName = name; } -void ProjectPanelFactory::registerFactory(ProjectPanelFactory *factory) -{ - auto it = std::lower_bound(s_factories.begin(), s_factories.end(), factory, - [](ProjectPanelFactory *a, ProjectPanelFactory *b) { - return (a->priority() == b->priority() && a < b) || a->priority() < b->priority(); - }); - - s_factories.insert(it, factory); -} - QList ProjectPanelFactory::factories() { + if (!s_sorted) { + s_sorted = true; + std::sort(s_factories.begin(), s_factories.end(), + [](ProjectPanelFactory *a, ProjectPanelFactory *b) { + return (a->priority() == b->priority() && a < b) || a->priority() < b->priority(); + }); + } return s_factories; } -Utils::Id ProjectPanelFactory::id() const +Id ProjectPanelFactory::id() const { return m_id; } -void ProjectPanelFactory::setId(Utils::Id id) +void ProjectPanelFactory::setId(Id id) { m_id = id; } diff --git a/src/plugins/projectexplorer/projectpanelfactory.h b/src/plugins/projectexplorer/projectpanelfactory.h index 5eb12c2ea34..d09f1dd0c1b 100644 --- a/src/plugins/projectexplorer/projectpanelfactory.h +++ b/src/plugins/projectexplorer/projectpanelfactory.h @@ -15,7 +15,6 @@ namespace ProjectExplorer { class Project; -class ProjectExplorerPlugin; class PROJECTEXPLORER_EXPORT ProjectPanelFactory { @@ -42,9 +41,6 @@ public: using SupportsFunction = std::function; void setSupportsFunction(std::function function); - // This takes ownership. - static void registerFactory(ProjectPanelFactory *factory); - static QList factories(); Utils::TreeItem *createPanelItem(Project *project); diff --git a/src/plugins/todo/todoprojectsettingswidget.cpp b/src/plugins/todo/todoprojectsettingswidget.cpp index 61a4cbc958c..0f438626941 100644 --- a/src/plugins/todo/todoprojectsettingswidget.cpp +++ b/src/plugins/todo/todoprojectsettingswidget.cpp @@ -179,7 +179,6 @@ public: provider, [project, provider] { provider->projectSettingsChanged(project); }); return widget; }); - ProjectPanelFactory::registerFactory(this); } }; From 3a5e0299c07184fa416295ca576806d12e581ab4 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Thu, 16 Nov 2023 12:33:50 +0100 Subject: [PATCH 0230/1546] ScreenRecorder: Enable the plugin being SoftLoadable The plugin depends only on Core, and only registers one action. Sofloading works out of the box. Change-Id: I9e13a1c920452f942fa11365e8976e4ecc054f86 Reviewed-by: hjk --- src/plugins/screenrecorder/ScreenRecorder.json.in | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/screenrecorder/ScreenRecorder.json.in b/src/plugins/screenrecorder/ScreenRecorder.json.in index 87391fd4380..671147ff0dc 100644 --- a/src/plugins/screenrecorder/ScreenRecorder.json.in +++ b/src/plugins/screenrecorder/ScreenRecorder.json.in @@ -13,6 +13,7 @@ "Alternatively, this plugin may be used under the terms of the GNU General Public License version 3 as published by the Free Software Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT included in the packaging of this plugin. Please review the following information to ensure the GNU General Public License requirements will be met: https://www.gnu.org/licenses/gpl-3.0.html." ], "DisabledByDefault" : true, + "SoftLoadable" : true, "Description" : "Screen recording.", "Url" : "http://www.qt.io", ${IDE_PLUGIN_DEPENDENCIES} From 43e4c7913fae7ff7917b2893b461a17a8acc09ac Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Nov 2023 17:04:44 +0100 Subject: [PATCH 0231/1546] ClangCodeModel: Use ActionBuilder Change-Id: I40cd7fc9eb346b0b70ea24f980846d175cfde3d4 Reviewed-by: Christian Kandeler --- .../clangcodemodel/clangcodemodelplugin.cpp | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp index cf967f24998..6b7f888624a 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp @@ -84,19 +84,11 @@ void ClangCodeModelPlugin::initialize() CppEditor::CppModelManager::activateClangCodeModel(std::make_unique()); createCompilationDBAction(); - QAction *const updateStaleIndexEntries - = new QAction(Tr::tr("Update Potentially Stale Clangd Index Entries"), this); - Command * const cmd = ActionManager::registerAction(updateStaleIndexEntries, - "ClangCodeModel.UpdateStaleIndexEntries"); - connect(updateStaleIndexEntries, &QAction::triggered, this, - [] { ClangModelManagerSupport::updateStaleIndexEntries(); }); - const QList menus; - namespace CppConstants = CppEditor::Constants; - for (ActionContainer * const menu : {ActionManager::actionContainer(CppConstants::M_TOOLS_CPP), - ActionManager::actionContainer(CppConstants::M_CONTEXT)}) { - QTC_ASSERT(menu, continue); - menu->addAction(cmd, CppEditor::Constants::G_GLOBAL); - } + ActionBuilder updateStaleIndexEntries(this, "ClangCodeModel.UpdateStaleIndexEntries"); + updateStaleIndexEntries.setText(Tr::tr("Update Potentially Stale Clangd Index Entries")); + updateStaleIndexEntries.setOnTriggered(this, &ClangModelManagerSupport::updateStaleIndexEntries); + updateStaleIndexEntries.setContainer(CppEditor::Constants::M_TOOLS_CPP); + updateStaleIndexEntries.setContainer(CppEditor::Constants::M_CONTEXT); #ifdef WITH_TESTS addTest(); From a810995aae3cc2074f24373978e0fef92acca1e4 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Thu, 16 Nov 2023 18:31:57 +0100 Subject: [PATCH 0232/1546] Vcpkg: Enable soft loading of the plugin Change-Id: Iddca570d1f29e51221a3958d6fa246beb00d8168 Reviewed-by: Cristian Adam --- src/plugins/vcpkg/Vcpkg.json.in | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/vcpkg/Vcpkg.json.in b/src/plugins/vcpkg/Vcpkg.json.in index f3ab4f0a5d7..09fcaf06a70 100644 --- a/src/plugins/vcpkg/Vcpkg.json.in +++ b/src/plugins/vcpkg/Vcpkg.json.in @@ -13,6 +13,7 @@ "Alternatively, this plugin may be used under the terms of the GNU General Public License version 3 as published by the Free Software Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT included in the packaging of this plugin. Please review the following information to ensure the GNU General Public License requirements will be met: https://www.gnu.org/licenses/gpl-3.0.html." ], "Experimental" : true, + "SoftLoadable" : true, "Description" : "vcpkg integration.", "Url" : "http://www.qt.io", ${IDE_PLUGIN_DEPENDENCIES}, From 583a9dcea1008d86e3bb33dd735136024b0df0bd Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 14 Nov 2023 11:27:12 +0100 Subject: [PATCH 0233/1546] Add Line/Column indicator to Markdown editor And make the LineColumnButton independent of IEditor for that (since the IEditor for the Markdown editor is not a TextEditor. Change-Id: I52d378ec46d86b1c7928d18f7d39f9726bb6ad23 Reviewed-by: David Schulz Reviewed-by: Qt CI Bot --- src/plugins/texteditor/markdowneditor.cpp | 5 +++++ src/plugins/texteditor/texteditor.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/texteditor/markdowneditor.cpp b/src/plugins/texteditor/markdowneditor.cpp index 935d215f321..3532b6a4fa0 100644 --- a/src/plugins/texteditor/markdowneditor.cpp +++ b/src/plugins/texteditor/markdowneditor.cpp @@ -83,6 +83,7 @@ public: context->setWidget(m_textEditorWidget); context->setContext(Context(MARKDOWNVIEWER_TEXT_CONTEXT)); ICore::addContextObject(context); + m_lineColumnButton = new LineColumnButton(m_textEditorWidget); m_splitter->addWidget(m_textEditorWidget); // sets splitter->focusWidget() on non-Windows m_splitter->addWidget(m_previewWidget); @@ -115,6 +116,7 @@ public: m_toggleEditorVisible->setCheckable(true); m_toggleEditorVisible->setChecked(showEditor); m_textEditorWidget->setVisible(showEditor); + m_lineColumnButton->setVisible(showEditor); auto button = new CommandButton(EMPHASIS_ACTION); button->setText("i"); @@ -150,6 +152,7 @@ public: for (auto button : m_markDownButtons) m_toolbarLayout->addWidget(button); m_toolbarLayout->addStretch(); + m_toolbarLayout->addWidget(m_lineColumnButton); m_toolbarLayout->addWidget(m_togglePreviewVisible); m_toolbarLayout->addWidget(m_toggleEditorVisible); m_toolbarLayout->addWidget(m_swapViews); @@ -210,6 +213,7 @@ public: m_togglePreviewVisible); for (auto button : m_markDownButtons) button->setVisible(visible); + m_lineColumnButton->setVisible(visible); saveViewSettings(); }); connect(m_togglePreviewVisible, @@ -443,6 +447,7 @@ private: QWidget m_toolbar; QHBoxLayout *m_toolbarLayout; QList m_markDownButtons; + LineColumnButton *m_lineColumnButton; CommandButton *m_toggleEditorVisible; CommandButton *m_togglePreviewVisible; CommandButton *m_swapViews; diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index bb71933e0e7..653bd310ebb 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -164,7 +164,7 @@ LineColumnButton::LineColumnButton(TextEditorWidget *parent) m_d->m_editor = parent; connect(m_d->m_editor, &QPlainTextEdit::cursorPositionChanged, this, &LineColumnButton::update); connect(this, &QToolButton::clicked, ActionManager::instance(), [this] { - emit m_d->m_editor->activateEditor(EditorManager::IgnoreNavigationHistory); + m_d->m_editor->setFocus(); QMetaObject::invokeMethod( ActionManager::instance(), [] { From 156569fcc737685bd8326b3a903e14777cba935b Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 16 Nov 2023 14:07:17 +0100 Subject: [PATCH 0234/1546] TextEditor: Move code from RefactoringChanges to RefactoringFile Preparation for de-polymorphisation of RefactoringChangesData. Change-Id: Ia2a8f8e2a3a403f809e67c907d3474e7c1a52417 Reviewed-by: Qt CI Bot Reviewed-by: David Schulz Reviewed-by: --- src/plugins/texteditor/refactoringchanges.cpp | 69 ++++++++++--------- src/plugins/texteditor/refactoringchanges.h | 1 + 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp index e9016d3cb60..fdff2567588 100644 --- a/src/plugins/texteditor/refactoringchanges.cpp +++ b/src/plugins/texteditor/refactoringchanges.cpp @@ -54,37 +54,7 @@ bool RefactoringChanges::createFile(const FilePath &filePath, bool reindent, bool openEditor) const { - if (filePath.exists()) - return false; - - // Create a text document for the new file: - auto document = new QTextDocument; - QTextCursor cursor(document); - cursor.beginEditBlock(); - cursor.insertText(contents); - - // Reindent the contents: - if (reindent) { - cursor.select(QTextCursor::Document); - m_data->indentSelection(cursor, filePath, nullptr); - } - cursor.endEditBlock(); - - // Write the file to disk: - TextFileFormat format; - format.codec = EditorManager::defaultTextCodec(); - QString error; - bool saveOk = format.writeFile(filePath, document->toPlainText(), &error); - delete document; - if (!saveOk) - return false; - - m_data->fileChanged(filePath); - - if (openEditor) - RefactoringChanges::openEditor(filePath, /*bool activate =*/ false, -1, -1); - - return true; + return file(filePath)->create(contents, reindent, openEditor); } TextEditorWidget *RefactoringChanges::openEditor(const FilePath &filePath, @@ -134,6 +104,41 @@ RefactoringFile::RefactoringFile(const FilePath &filePath, } } +bool RefactoringFile::create(const QString &contents, bool reindent, bool openEditor) +{ + if (m_filePath.isEmpty() || m_filePath.exists() || m_editor) + return false; + + // Create a text document for the new file: + auto document = new QTextDocument; + QTextCursor cursor(document); + cursor.beginEditBlock(); + cursor.insertText(contents); + + // Reindent the contents: + if (reindent) { + cursor.select(QTextCursor::Document); + m_data->indentSelection(cursor, m_filePath, nullptr); + } + cursor.endEditBlock(); + + // Write the file to disk: + TextFileFormat format; + format.codec = EditorManager::defaultTextCodec(); + QString error; + bool saveOk = format.writeFile(m_filePath, document->toPlainText(), &error); + delete document; + if (!saveOk) + return false; + + fileChanged(); + + if (openEditor) + RefactoringChanges::openEditor(m_filePath, /*bool activate =*/ false, -1, -1); + + return true; +} + RefactoringFile::~RefactoringFile() { delete m_document; @@ -443,7 +448,7 @@ void RefactoringFile::doFormatting() formattingRanges.push_back({line, line}); } - static const QString clangFormatLineRemovalBlocker("// QTC_TEMP"); + static const QString clangFormatLineRemovalBlocker(""); for (const RangeInLines &r : std::as_const(formattingRanges)) { QTextBlock b = m_editor->document()->findBlockByNumber(r.startLine - 1); while (true) { diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h index 9b8a322e973..4678b977dff 100644 --- a/src/plugins/texteditor/refactoringchanges.h +++ b/src/plugins/texteditor/refactoringchanges.h @@ -60,6 +60,7 @@ public: void appendReindentRange(const Range &range); void setOpenEditor(bool activate = false, int pos = -1); bool apply(); + bool create(const QString &contents, bool reindent, bool openEditor); protected: // users may only get const access to RefactoringFiles created through From 413a6a6fde01be93dcc4e95e157509cca1fe1d68 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 16 Nov 2023 15:45:02 +0100 Subject: [PATCH 0235/1546] TextEditor: Make RefactoringChanges::file() virtual More preparation for de-virtualization of RefactoringChangesData. Change-Id: Ib5f7782a8dcaa2ae093b62aebedbd7bae9d4c3f1 Reviewed-by: David Schulz Reviewed-by: Qt CI Bot Reviewed-by: --- .../cppeditor/cppfunctiondecldeflink.cpp | 4 +- .../cppeditor/cppinsertvirtualmethods.cpp | 4 +- src/plugins/cppeditor/cppquickfixes.cpp | 96 +++++++++---------- .../cppeditor/cpprefactoringchanges.cpp | 7 +- src/plugins/cppeditor/cpprefactoringchanges.h | 5 +- .../cppeditor/insertionpointlocator.cpp | 8 +- .../qmljscomponentfromobjectdef.cpp | 2 +- src/plugins/qmljseditor/qmljsquickfix.cpp | 2 +- .../qmljstools/qmljsrefactoringchanges.cpp | 7 +- .../qmljstools/qmljsrefactoringchanges.h | 4 +- src/plugins/texteditor/refactoringchanges.h | 5 +- 11 files changed, 81 insertions(+), 63 deletions(-) diff --git a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp index 7055b00d038..4c300012724 100644 --- a/src/plugins/cppeditor/cppfunctiondecldeflink.cpp +++ b/src/plugins/cppeditor/cppfunctiondecldeflink.cpp @@ -199,7 +199,7 @@ void FunctionDeclDefLinkFinder::startFindLinkAt( // find the start/end offsets CppRefactoringChanges refactoringChanges(snapshot); - CppRefactoringFilePtr sourceFile = refactoringChanges.file(doc->filePath()); + CppRefactoringFilePtr sourceFile = refactoringChanges.cppFile(doc->filePath()); sourceFile->setCppDocument(doc); int start, end; declDefLinkStartEnd(sourceFile, parent, funcDecl, &start, &end); @@ -259,7 +259,7 @@ void FunctionDeclDefLink::apply(CppEditorWidget *editor, bool jumpToMatch) // first verify the interesting region of the target file is unchanged CppRefactoringChanges refactoringChanges(snapshot); - CppRefactoringFilePtr newTargetFile = refactoringChanges.file(targetFile->filePath()); + CppRefactoringFilePtr newTargetFile = refactoringChanges.cppFile(targetFile->filePath()); if (!newTargetFile->isValid()) return; const int targetStart = newTargetFile->position(targetLine, targetColumn); diff --git a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp index 88beb673c0a..7c173c703b4 100644 --- a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp +++ b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp @@ -763,7 +763,7 @@ public: Utils::ChangeSet headerChangeSet; const CppRefactoringChanges refactoring(snapshot()); const Utils::FilePath filePath = currentFile()->filePath(); - const CppRefactoringFilePtr headerFile = refactoring.file(filePath); + const CppRefactoringFilePtr headerFile = refactoring.cppFile(filePath); const LookupContext targetContext(headerFile->cppDocument(), snapshot()); const Class *targetClass = m_classAST->symbol; @@ -881,7 +881,7 @@ public: if (!clazz) return; - CppRefactoringFilePtr implementationFile = refactoring.file(m_cppFilePath); + CppRefactoringFilePtr implementationFile = refactoring.cppFile(m_cppFilePath); Utils::ChangeSet implementationChangeSet; const int insertPos = qMax(0, implementationFile->document()->characterCount() - 1); diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 3c8290e38cd..0ce5adb798d 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -404,7 +404,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); ChangeSet changes; if (negation) { @@ -498,7 +498,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); ChangeSet changes; changes.flip(currentFile->range(binary->left_expression), @@ -587,7 +587,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); ChangeSet changes; changes.replace(currentFile->range(pattern->binary_op_token), QLatin1String("||")); @@ -672,7 +672,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); ChangeSet changes; @@ -763,7 +763,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); ChangeSet changes; @@ -837,7 +837,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); ChangeSet changes; @@ -910,7 +910,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); ChangeSet changes; @@ -988,7 +988,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); const Token binaryToken = currentFile->tokenAt(condition->binary_op_token); @@ -1227,7 +1227,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); ChangeSet changes; @@ -1430,7 +1430,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); ChangeSet changes; @@ -1492,7 +1492,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); ChangeSet changes; changes.replace(start, end, replacement); @@ -1651,7 +1651,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); QString declaration = getDeclaration(); if (!declaration.isEmpty()) { @@ -1668,7 +1668,7 @@ private: QString getDeclaration() { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); Overview oo = CppCodeStyleSettings::currentProjectCodeStyleOverview(); const auto settings = CppQuickFixProjectsSettings::getQuickFixSettings( ProjectExplorer::ProjectTree::currentProject()); @@ -1704,7 +1704,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); QString newName = m_isAllUpper ? m_name.toLower() : m_name; for (int i = 1; i < newName.length(); ++i) { @@ -1786,7 +1786,7 @@ AddIncludeForUndefinedIdentifierOp::AddIncludeForUndefinedIdentifierOp( void AddIncludeForUndefinedIdentifierOp::perform() { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr file = refactoring.file(filePath()); + CppRefactoringFilePtr file = refactoring.cppFile(filePath()); insertNewIncludeDirective(m_include, file, semanticInfo().doc); } @@ -1808,7 +1808,7 @@ void AddForwardDeclForUndefinedIdentifierOp::perform() const QStringList namespaces = parts.mid(0, parts.length() - 1); CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr file = refactoring.file(filePath()); + CppRefactoringFilePtr file = refactoring.cppFile(filePath()); NSVisitor visitor(file.data(), namespaces, m_symbolPos); visitor.accept(file->cppDocument()->translationUnit()->ast()); @@ -2157,7 +2157,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); int targetEndPos = currentFile->endOf(m_targetParam); ChangeSet changes; @@ -2236,7 +2236,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); currentFile->setChangeSet(m_change); currentFile->apply(); } @@ -2397,7 +2397,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); ChangeSet changes; int start = currentFile->endOf(compoundStatement->lbrace_token); @@ -2541,7 +2541,7 @@ public: m_targetFilePath, m_targetSymbol, m_xsSpec); QTC_ASSERT(loc.isValid(), return); - CppRefactoringFilePtr targetFile = refactoring.file(m_targetFilePath); + CppRefactoringFilePtr targetFile = refactoring.cppFile(m_targetFilePath); int targetPosition1 = targetFile->position(loc.line(), loc.column()); int targetPosition2 = qMax(0, targetFile->position(loc.line(), 1) - 1); @@ -2717,7 +2717,7 @@ public: refactoring, targetFilePath); QTC_ASSERT(loc.isValid(), return); - CppRefactoringFilePtr targetFile = refactoring.file(loc.filePath()); + CppRefactoringFilePtr targetFile = refactoring.cppFile(loc.filePath()); Overview oo = CppCodeStyleSettings::currentProjectCodeStyleOverview(); oo.showFunctionSignatures = true; oo.showReturnTypes = true; @@ -2784,7 +2784,7 @@ public: // rewrite the function name if (nameIncludesOperatorName(decl->name())) { - CppRefactoringFilePtr file = refactoring.file(op->filePath()); + CppRefactoringFilePtr file = refactoring.cppFile(op->filePath()); const QString operatorNameText = file->textOf(declAST->core_declarator); oo.includeWhiteSpaceInOperatorName = operatorNameText.contains(QLatin1Char(' ')); } @@ -2994,7 +2994,7 @@ private: filePath, m_class, m_accessSpec); QTC_ASSERT(loc.isValid(), return); - CppRefactoringFilePtr targetFile = refactoring.file(filePath); + CppRefactoringFilePtr targetFile = refactoring.cppFile(filePath); const int targetPosition1 = targetFile->position(loc.line(), loc.column()); const int targetPosition2 = qMax(0, targetFile->position(loc.line(), 1) - 1); ChangeSet target; @@ -3579,7 +3579,7 @@ private: &changeSet.first, &changeSet.second); } for (auto it = changeSets.cbegin(); it != changeSets.cend(); ++it) { - const CppRefactoringFilePtr file = refactoring.file(it.key()); + const CppRefactoringFilePtr file = refactoring.cppFile(it.key()); for (const ChangeSet::Range &r : it.value().second) file->appendIndentRange(r); file->setChangeSet(it.value().first); @@ -3705,14 +3705,14 @@ public: : m_operation(operation) , m_changes(m_operation->snapshot()) , m_locator(m_changes) - , m_headerFile(m_changes.file(filePath)) + , m_headerFile(m_changes.cppFile(filePath)) , m_sourceFile([&] { FilePath cppFilePath = correspondingHeaderOrSource(filePath, &m_isHeaderHeaderFile); if (!m_isHeaderHeaderFile || !cppFilePath.exists()) { // there is no "source" file return m_headerFile; } else { - return m_changes.file(cppFilePath); + return m_changes.cppFile(cppFilePath); } }()) , m_class(clazz) @@ -5052,7 +5052,7 @@ public: { QTC_ASSERT(!m_funcReturn || !m_relevantDecls.isEmpty(), return); CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); ExtractFunctionOptions options; if (m_functionNameGetter) @@ -5208,7 +5208,7 @@ public: const FilePath filePath = FilePath::fromUtf8(matchingClass->fileName()); const InsertionLocation &location = locator.methodDeclarationInClass(filePath, matchingClass, options.access); - CppRefactoringFilePtr declFile = refactoring.file(filePath); + CppRefactoringFilePtr declFile = refactoring.cppFile(filePath); change.clear(); position = declFile->position(location.line(), location.column()); change.insert(position, location.prefix() + funcDecl + location.suffix()); @@ -5717,7 +5717,7 @@ public: } const FilePath declFilePath = matchingClass->filePath(); - result.file = refactoring.file(declFilePath); + result.file = refactoring.cppFile(declFilePath); ASTPath astPath(result.file->cppDocument()); const QList path = astPath(s->line(), s->column()); SimpleDeclarationAST *simpleDecl = nullptr; @@ -5740,7 +5740,7 @@ public: FilePath declFilePath = correspondingHeaderOrSource(filePath(), &isHeaderFile); if (!declFilePath.exists()) return FoundDeclaration(); - result.file = refactoring.file(declFilePath); + result.file = refactoring.cppFile(declFilePath); if (!result.file) return FoundDeclaration(); const LookupContext lc(result.file->cppDocument(), snapshot()); @@ -5769,7 +5769,7 @@ public: FunctionDeclaratorAST *functionDeclaratorOfDefinition = functionDeclarator(m_functionDefinition); const CppRefactoringChanges refactoring(snapshot()); - const CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + const CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); deduceTypeNameOfLiteral(currentFile->cppDocument()); ChangeSet changes; @@ -5951,7 +5951,7 @@ public: , m_identifierAST(identifierAST) , m_symbol(symbol) , m_refactoring(snapshot()) - , m_file(m_refactoring.file(filePath())) + , m_file(m_refactoring.cppFile(filePath())) , m_document(interface.semanticInfo().doc) { setDescription( @@ -6552,8 +6552,8 @@ public: const FilePath &fromFile, const FilePath &toFile) : m_operation(operation), m_type(type), m_changes(m_operation->snapshot()) { - m_fromFile = m_changes.file(fromFile); - m_toFile = (m_type == MoveOutside) ? m_fromFile : m_changes.file(toFile); + m_fromFile = m_changes.cppFile(fromFile); + m_toFile = (m_type == MoveOutside) ? m_fromFile : m_changes.cppFile(toFile); } void performMove(FunctionDefinitionAST *funcAST) @@ -6819,8 +6819,8 @@ private: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr fromFile = refactoring.file(m_fromFilePath); - CppRefactoringFilePtr toFile = refactoring.file(m_toFilePath); + CppRefactoringFilePtr fromFile = refactoring.cppFile(m_fromFilePath); + CppRefactoringFilePtr toFile = refactoring.cppFile(m_toFilePath); ensureFuncDefAstAndRange(*fromFile); if (!m_funcAST) @@ -6912,7 +6912,7 @@ void MoveFuncDefToDeclPush::match(const CppQuickFixInterface &interface, QuickFi return; const CppRefactoringChanges refactoring(interface.snapshot()); - const CppRefactoringFilePtr defFile = refactoring.file(interface.filePath()); + const CppRefactoringFilePtr defFile = refactoring.cppFile(interface.filePath()); const ChangeSet::Range defRange = defFile->range(completeDefAST); // Determine declaration (file, range, text); @@ -6944,7 +6944,7 @@ void MoveFuncDefToDeclPush::match(const CppQuickFixInterface &interface, QuickFi } declFilePath = matchingClass->filePath(); - const CppRefactoringFilePtr declFile = refactoring.file(declFilePath); + const CppRefactoringFilePtr declFile = refactoring.cppFile(declFilePath); ASTPath astPath(declFile->cppDocument()); const QList path = astPath(s->line(), s->column()); for (int idx = path.size() - 1; idx > 0; --idx) { @@ -6969,7 +6969,7 @@ void MoveFuncDefToDeclPush::match(const CppQuickFixInterface &interface, QuickFi if (isHeaderFile) return; - const CppRefactoringFilePtr declFile = refactoring.file(declFilePath); + const CppRefactoringFilePtr declFile = refactoring.cppFile(declFilePath); const LookupContext lc(declFile->cppDocument(), interface.snapshot()); const QList candidates = lc.lookup(func->name(), matchingNamespace); for (const LookupItem &candidate : candidates) { @@ -7059,7 +7059,7 @@ public: , m_name(name) , m_oo(CppCodeStyleSettings::currentProjectCodeStyleOverview()) , m_originalName(m_oo.prettyName(m_name)) - , m_file(CppRefactoringChanges(snapshot()).file(filePath())) + , m_file(CppRefactoringChanges(snapshot()).cppFile(filePath())) { setDescription(Tr::tr("Assign to Local Variable")); } @@ -7289,7 +7289,7 @@ public: const Utils::FilePath filePath = currentFile()->filePath(); const CppRefactoringChanges refactoring(snapshot()); - const CppRefactoringFilePtr file = refactoring.file(filePath); + const CppRefactoringFilePtr file = refactoring.cppFile(filePath); ChangeSet change; // Optimize post (in|de)crement operator to pre (in|de)crement operator @@ -7549,7 +7549,7 @@ public: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); const int startPos = currentFile->startOf(m_literal); const int endPos = currentFile->endOf(m_literal); @@ -7647,7 +7647,7 @@ private: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); currentFile->setChangeSet(m_changes); currentFile->apply(); } @@ -8397,7 +8397,7 @@ private: while (!nodesWithProcessedParents.empty()) { Node &node = nodesWithProcessedParents.back(); nodesWithProcessedParents.pop_back(); - CppRefactoringFilePtr file = refactoring.file(node.document->filePath()); + CppRefactoringFilePtr file = refactoring.cppFile(node.document->filePath()); const bool parentHasUsing = Utils::anyOf(node.includes, &Node::hasGlobalUsingDirective); const int startPos = parentHasUsing ? 0 @@ -8416,7 +8416,7 @@ private: void perform() override { CppRefactoringChanges refactoring(snapshot()); - CppRefactoringFilePtr currentFile = refactoring.file(filePath()); + CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); if (m_removeAllAtGlobalScope) { removeAllUsingsAtGlobalScope(refactoring); } else if (refactorFile(currentFile, @@ -8469,7 +8469,7 @@ private: if (!Utils::insert(m_processed, loc.first)) continue; - CppRefactoringFilePtr file = refactoring.file(loc.first->filePath()); + CppRefactoringFilePtr file = refactoring.cppFile(loc.first->filePath()); const bool noGlobalUsing = refactorFile(file, refactoring.snapshot(), file->position(loc.second, 1)); @@ -9686,11 +9686,11 @@ private: return; CppRefactoringChanges changes(CppModelManager::snapshot()); - const CppRefactoringFilePtr sourceFile = changes.file(symbolLoc.targetFilePath); + const CppRefactoringFilePtr sourceFile = changes.cppFile(symbolLoc.targetFilePath); const CppRefactoringFilePtr targetFile = targetLoc.targetFilePath == symbolLoc.targetFilePath ? sourceFile - : changes.file(targetLoc.targetFilePath); + : changes.cppFile(targetLoc.targetFilePath); const Document::Ptr &targetCppDoc = targetFile->cppDocument(); const QList targetAstPath = ASTPath(targetCppDoc)( targetLoc.targetLine, targetLoc.targetColumn + 1); diff --git a/src/plugins/cppeditor/cpprefactoringchanges.cpp b/src/plugins/cppeditor/cpprefactoringchanges.cpp index f4bcc471ad8..6da7e96b4fc 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.cpp +++ b/src/plugins/cppeditor/cpprefactoringchanges.cpp @@ -50,12 +50,17 @@ CppRefactoringFilePtr CppRefactoringChanges::file(TextEditor::TextEditorWidget * return result; } -CppRefactoringFilePtr CppRefactoringChanges::file(const FilePath &filePath) const +TextEditor::RefactoringFilePtr CppRefactoringChanges::file(const FilePath &filePath) const { CppRefactoringFilePtr result(new CppRefactoringFile(filePath, m_data)); return result; } +CppRefactoringFilePtr CppRefactoringChanges::cppFile(const Utils::FilePath &filePath) const +{ + return file(filePath).staticCast(); +} + CppRefactoringFileConstPtr CppRefactoringChanges::fileNoEditor(const FilePath &filePath) const { QTextDocument *document = nullptr; diff --git a/src/plugins/cppeditor/cpprefactoringchanges.h b/src/plugins/cppeditor/cpprefactoringchanges.h index 602efaf6d04..88d6424959a 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.h +++ b/src/plugins/cppeditor/cpprefactoringchanges.h @@ -93,7 +93,10 @@ public: static CppRefactoringFilePtr file(TextEditor::TextEditorWidget *editor, const CPlusPlus::Document::Ptr &document); - CppRefactoringFilePtr file(const Utils::FilePath &filePath) const; + TextEditor::RefactoringFilePtr file(const Utils::FilePath &filePath) const override; + + CppRefactoringFilePtr cppFile(const Utils::FilePath &filePath) const; + // safe to use from non-gui threads CppRefactoringFileConstPtr fileNoEditor(const Utils::FilePath &filePath) const; diff --git a/src/plugins/cppeditor/insertionpointlocator.cpp b/src/plugins/cppeditor/insertionpointlocator.cpp index 3eb1d4aebe3..8b2b03698e2 100644 --- a/src/plugins/cppeditor/insertionpointlocator.cpp +++ b/src/plugins/cppeditor/insertionpointlocator.cpp @@ -256,7 +256,7 @@ InsertionLocation InsertionPointLocator::methodDeclarationInClass( AccessSpec xsSpec, ForceAccessSpec forceAccessSpec) const { - const Document::Ptr doc = m_refactoringChanges.file(filePath)->cppDocument(); + const Document::Ptr doc = m_refactoringChanges.cppFile(filePath)->cppDocument(); if (doc) { FindInClass find(doc->translationUnit(), clazz); ClassSpecifierAST *classAST = find(); @@ -599,7 +599,7 @@ static InsertionLocation nextToSurroundingDefinitions(Symbol *declaration, targetDoc->translationUnit()->getPosition(definitionFunction->endOffset(), &line, &column); } else { // we don't have an offset to the start of the function definition, so we need to manually find it... - CppRefactoringFilePtr targetFile = changes.file(definitionFunction->filePath()); + CppRefactoringFilePtr targetFile = changes.cppFile(definitionFunction->filePath()); if (!targetFile->isValid()) return noResult; @@ -653,7 +653,7 @@ const QList InsertionPointLocator::methodDefinition( target = candidate; } - CppRefactoringFilePtr targetFile = m_refactoringChanges.file(target); + CppRefactoringFilePtr targetFile = m_refactoringChanges.cppFile(target); Document::Ptr doc = targetFile->cppDocument(); if (doc.isNull()) return result; @@ -761,7 +761,7 @@ InsertionLocation insertLocationForMethodDefinition(Symbol *symbol, { QTC_ASSERT(symbol, return InsertionLocation()); - CppRefactoringFilePtr file = refactoring.file(filePath); + CppRefactoringFilePtr file = refactoring.cppFile(filePath); QStringList requiredNamespaces; if (namespaceHandling == NamespaceHandling::CreateMissing) { requiredNamespaces = getNamespaceNames(symbol); diff --git a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp index 4f040d12dfc..97eff5c1e6b 100644 --- a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp +++ b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp @@ -248,7 +248,7 @@ void performComponentFromObjectDef(QmlJSEditorWidget *editor, { QmlJSRefactoringChanges refactoring(QmlJS::ModelManagerInterface::instance(), QmlJS::ModelManagerInterface::instance()->snapshot()); - QmlJSRefactoringFilePtr current = refactoring.file(Utils::FilePath::fromString(fileName)); + QmlJSRefactoringFilePtr current = refactoring.qmlJSFile(Utils::FilePath::fromString(fileName)); QmlJSQuickFixAssistInterface interface(editor, TextEditor::AssistReason::ExplicitlyInvoked); Operation operation(&interface, objDef); diff --git a/src/plugins/qmljseditor/qmljsquickfix.cpp b/src/plugins/qmljseditor/qmljsquickfix.cpp index 65840389158..6614c37ad37 100644 --- a/src/plugins/qmljseditor/qmljsquickfix.cpp +++ b/src/plugins/qmljseditor/qmljsquickfix.cpp @@ -31,7 +31,7 @@ QmlJSQuickFixOperation::QmlJSQuickFixOperation(const QmlJSQuickFixAssistInterfac void QmlJSQuickFixOperation::perform() { QmlJSRefactoringChanges refactoring(ModelManagerInterface::instance(), semanticInfo().snapshot); - QmlJSRefactoringFilePtr current = refactoring.file(fileName()); + QmlJSRefactoringFilePtr current = refactoring.qmlJSFile(fileName()); performChanges(current, refactoring); } diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp index e431b6ef718..67ab64858e7 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp @@ -81,11 +81,16 @@ QmlJSRefactoringChanges::QmlJSRefactoringChanges(ModelManagerInterface *modelMan { } -QmlJSRefactoringFilePtr QmlJSRefactoringChanges::file(const Utils::FilePath &filePath) const +TextEditor::RefactoringFilePtr QmlJSRefactoringChanges::file(const Utils::FilePath &filePath) const { return QmlJSRefactoringFilePtr(new QmlJSRefactoringFile(filePath, m_data)); } +QmlJSRefactoringFilePtr QmlJSRefactoringChanges::qmlJSFile(const Utils::FilePath &filePath) const +{ + return file(filePath).staticCast(); +} + QmlJSRefactoringFilePtr QmlJSRefactoringChanges::file( TextEditor::TextEditorWidget *editor, const Document::Ptr &document) { diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.h b/src/plugins/qmljstools/qmljsrefactoringchanges.h index b95da2076cf..fa4e381edd7 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.h +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.h @@ -56,7 +56,9 @@ public: static QmlJSRefactoringFilePtr file(TextEditor::TextEditorWidget *editor, const QmlJS::Document::Ptr &document); - QmlJSRefactoringFilePtr file(const Utils::FilePath &filePath) const; + TextEditor::RefactoringFilePtr file(const Utils::FilePath &filePath) const; + + QmlJSRefactoringFilePtr qmlJSFile(const Utils::FilePath &filePath) const; const QmlJS::Snapshot &snapshot() const; diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h index 4678b977dff..a0e71f12363 100644 --- a/src/plugins/texteditor/refactoringchanges.h +++ b/src/plugins/texteditor/refactoringchanges.h @@ -111,7 +111,10 @@ public: explicit RefactoringChanges(RefactoringChangesData *data = nullptr); virtual ~RefactoringChanges(); - RefactoringFilePtr file(const Utils::FilePath &filePath) const; + // TODO: Make pure virtual and introduce dedicated subclass for generic refactoring, + // so no one instantiates this one by mistake. + virtual RefactoringFilePtr file(const Utils::FilePath &filePath) const; + bool createFile(const Utils::FilePath &filePath, const QString &contents, bool reindent = true, From 4c0abb6d2c93704a1909b3f24dfb02c0e191fd31 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 09:23:45 +0100 Subject: [PATCH 0236/1546] ExtensionSystem: Make IPlugin::addTest* public This allows somewhat easier test setup by defining test classes nearer to the tested code. Change-Id: I7c300a442c9433355d97742b17b394a6d2352270 Reviewed-by: Eike Ziller --- src/libs/extensionsystem/iplugin.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/extensionsystem/iplugin.h b/src/libs/extensionsystem/iplugin.h index 5a8fceb3d6e..b121611390f 100644 --- a/src/libs/extensionsystem/iplugin.h +++ b/src/libs/extensionsystem/iplugin.h @@ -40,13 +40,13 @@ public: // Deprecated in 10.0, use addTest() virtual QVector createTestObjects() const; -protected: - virtual void initialize() {} - template void addTest(Args && ...args) { addTestCreator([args...] { return new Test(args...); }); } void addTestCreator(const TestCreator &creator); +protected: + virtual void initialize() {} + signals: void asynchronousShutdownFinished(); From 6f3bc431fc5a0bcde258f53d8c6e1d2d5ad80539 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 16 Nov 2023 16:09:26 +0100 Subject: [PATCH 0237/1546] TextEditor: Move more code into RefactoringFile We want to get rid of RefactoringChangesData. Change-Id: Ia428563a0ff70ec9660761beac3eb7168b8e9eca Reviewed-by: David Schulz --- src/plugins/clangcodemodel/clangdclient.cpp | 7 +- src/plugins/clangcodemodel/clangdclient.h | 3 +- .../cppeditor/cpprefactoringchanges.cpp | 28 +++--- src/plugins/cppeditor/cpprefactoringchanges.h | 18 ++-- src/plugins/languageclient/client.cpp | 4 +- src/plugins/languageclient/client.h | 2 +- .../languageclient/languageclientutils.cpp | 11 +-- .../qmljstools/qmljsrefactoringchanges.cpp | 90 +++++++++---------- .../qmljstools/qmljsrefactoringchanges.h | 7 +- src/plugins/texteditor/refactoringchanges.cpp | 38 +++----- src/plugins/texteditor/refactoringchanges.h | 16 ++-- 11 files changed, 97 insertions(+), 127 deletions(-) diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index ecf82f67e8d..3d14d1687e0 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -73,9 +73,7 @@ #include #include -#include #include -#include #include #include @@ -770,10 +768,9 @@ QList ClangdClient::additionalDocumentHighlights( qobject_cast(editorWidget), cursor); } -RefactoringChangesData *ClangdClient::createRefactoringChangesBackend() const +RefactoringFilePtr ClangdClient::createRefactoringFile(const FilePath &filePath) const { - return new CppEditor::CppRefactoringChangesData( - CppEditor::CppModelManager::snapshot()); + return CppEditor::CppRefactoringChanges(CppEditor::CppModelManager::snapshot()).file(filePath); } QVersionNumber ClangdClient::versionNumber() const diff --git a/src/plugins/clangcodemodel/clangdclient.h b/src/plugins/clangcodemodel/clangdclient.h index 4ac861127cc..fbe2a31bbc6 100644 --- a/src/plugins/clangcodemodel/clangdclient.h +++ b/src/plugins/clangcodemodel/clangdclient.h @@ -141,7 +141,8 @@ private: QTextCursor adjustedCursorForHighlighting(const QTextCursor &cursor, TextEditor::TextDocument *doc) override; const CustomInspectorTabs createCustomInspectorTabs() override; - TextEditor::RefactoringChangesData *createRefactoringChangesBackend() const override; + TextEditor::RefactoringFilePtr createRefactoringFile( + const Utils::FilePath &filePath) const override; LanguageClient::DiagnosticManager *createDiagnosticManager() override; LanguageClient::LanguageClientOutlineItem *createOutlineItem( const LanguageServerProtocol::DocumentSymbol &symbol) override; diff --git a/src/plugins/cppeditor/cpprefactoringchanges.cpp b/src/plugins/cppeditor/cpprefactoringchanges.cpp index 6da7e96b4fc..e5c33acfdb2 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.cpp +++ b/src/plugins/cppeditor/cpprefactoringchanges.cpp @@ -246,8 +246,9 @@ CppRefactoringChangesData *CppRefactoringFile::data() const void CppRefactoringFile::fileChanged() { + QTC_ASSERT(!m_filePath.isEmpty(), return); m_cppDocument.clear(); - RefactoringFile::fileChanged(); + CppModelManager::updateSourceFiles({filePath()}); } int CppRefactoringFile::tokenIndexForPosition(const std::vector &tokens, @@ -278,35 +279,28 @@ CppRefactoringChangesData::CppRefactoringChangesData(const Snapshot &snapshot) , m_workingCopy(CppModelManager::workingCopy()) {} -void CppRefactoringChangesData::indentSelection(const QTextCursor &selection, - const FilePath &filePath, - const TextEditor::TextDocument *textDocument) const +void CppRefactoringFile::indentSelection(const QTextCursor &selection, + const TextEditor::TextDocument *textDocument) const { if (textDocument) { // use the indenter from the textDocument if there is one, can be ClangFormat textDocument->indenter()->indent(selection, QChar::Null, textDocument->tabSettings()); } else { - const auto &tabSettings = ProjectExplorer::actualTabSettings(filePath, textDocument); - auto indenter = createIndenter(filePath, selection.document()); + const auto &tabSettings = ProjectExplorer::actualTabSettings(filePath(), textDocument); + auto indenter = createIndenter(filePath(), selection.document()); indenter->indent(selection, QChar::Null, tabSettings); } } -void CppRefactoringChangesData::reindentSelection(const QTextCursor &selection, - const FilePath &filePath, - const TextEditor::TextDocument *textDocument) const +void CppRefactoringFile::reindentSelection(const QTextCursor &selection, + const TextEditor::TextDocument *textDocument) const { if (textDocument) { // use the indenter from the textDocument if there is one, can be ClangFormat textDocument->indenter()->reindent(selection, textDocument->tabSettings()); } else { - const auto &tabSettings = ProjectExplorer::actualTabSettings(filePath, textDocument); - auto indenter = createIndenter(filePath, selection.document()); + const auto &tabSettings = ProjectExplorer::actualTabSettings(filePath(), textDocument); + auto indenter = createIndenter(filePath(), selection.document()); indenter->reindent(selection, tabSettings); } } -void CppRefactoringChangesData::fileChanged(const FilePath &filePath) -{ - CppModelManager::updateSourceFiles({filePath}); -} - -} // CppEditor +} // namespace CppEditor diff --git a/src/plugins/cppeditor/cpprefactoringchanges.h b/src/plugins/cppeditor/cpprefactoringchanges.h index 88d6424959a..878c38d4342 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.h +++ b/src/plugins/cppeditor/cpprefactoringchanges.h @@ -51,13 +51,19 @@ public: using TextEditor::RefactoringFile::textOf; QString textOf(const CPlusPlus::AST *ast) const; -protected: +private: CppRefactoringFile(const Utils::FilePath &filePath, const QSharedPointer &data); CppRefactoringFile(QTextDocument *document, const Utils::FilePath &filePath); explicit CppRefactoringFile(TextEditor::TextEditorWidget *editor); CppRefactoringChangesData *data() const; + void fileChanged() override; + void indentSelection(const QTextCursor &selection, + const TextEditor::TextDocument *textDocument) const override; + virtual void reindentSelection(const QTextCursor &selection, + const TextEditor::TextDocument *textDocument) const override; + int tokenIndexForPosition(const std::vector &tokens, int pos, int startIndex) const; @@ -72,16 +78,6 @@ class CPPEDITOR_EXPORT CppRefactoringChangesData : public TextEditor::Refactorin public: explicit CppRefactoringChangesData(const CPlusPlus::Snapshot &snapshot); - void indentSelection(const QTextCursor &selection, - const Utils::FilePath &filePath, - const TextEditor::TextDocument *textDocument) const override; - - void reindentSelection(const QTextCursor &selection, - const Utils::FilePath &filePath, - const TextEditor::TextDocument *textDocument) const override; - - void fileChanged(const Utils::FilePath &filePath) override; - CPlusPlus::Snapshot m_snapshot; WorkingCopy m_workingCopy; }; diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index 5a1fcc44668..c5b822aef67 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -1737,9 +1737,9 @@ void Client::log(const QString &message) const } } -TextEditor::RefactoringChangesData *Client::createRefactoringChangesBackend() const +TextEditor::RefactoringFilePtr Client::createRefactoringFile(const FilePath &filePath) const { - return new TextEditor::RefactoringChangesData; + return TextEditor::RefactoringChanges().file(filePath); } void Client::setCompletionResultsLimit(int limit) diff --git a/src/plugins/languageclient/client.h b/src/plugins/languageclient/client.h index fdeb1356d6c..65093237085 100644 --- a/src/plugins/languageclient/client.h +++ b/src/plugins/languageclient/client.h @@ -201,7 +201,7 @@ public: virtual const CustomInspectorTabs createCustomInspectorTabs() { return {}; } // Caller takes ownership - virtual TextEditor::RefactoringChangesData *createRefactoringChangesBackend() const; + virtual TextEditor::RefactoringFilePtr createRefactoringFile(const Utils::FilePath &filePath) const; void setCompletionResultsLimit(int limit); int completionResultsLimit() const; diff --git a/src/plugins/languageclient/languageclientutils.cpp b/src/plugins/languageclient/languageclientutils.cpp index 8fc032f06d6..76c3cdb2933 100644 --- a/src/plugins/languageclient/languageclientutils.cpp +++ b/src/plugins/languageclient/languageclientutils.cpp @@ -89,15 +89,10 @@ bool applyTextEdits(const Client *client, { if (edits.isEmpty()) return true; - RefactoringChangesData * const backend = client->createRefactoringChangesBackend(); - RefactoringChanges changes(backend); - RefactoringFilePtr file; - file = changes.file(filePath); + const RefactoringFilePtr file = client->createRefactoringFile(filePath); file->setChangeSet(editsToChangeSet(edits, file->document())); - if (backend) { - for (const TextEdit &edit : edits) - file->appendIndentRange(convertRange(file->document(), edit.range())); - } + for (const TextEdit &edit : edits) + file->appendIndentRange(convertRange(file->document(), edit.range())); return file->apply(); } diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp index 67ab64858e7..24bd14f52b0 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp @@ -24,53 +24,6 @@ public: , m_snapshot(snapshot) {} - void indentSelection(const QTextCursor &selection, - const Utils::FilePath &filePath, - const TextEditor::TextDocument *textDocument) const override - { - // ### shares code with QmlJSTextEditor::indent - QTextDocument *doc = selection.document(); - - QTextBlock block = doc->findBlock(selection.selectionStart()); - const QTextBlock end = doc->findBlock(selection.selectionEnd()).next(); - - const TextEditor::TabSettings &tabSettings = - ProjectExplorer::actualTabSettings(filePath, textDocument); - CreatorCodeFormatter codeFormatter(tabSettings); - codeFormatter.updateStateUntil(block); - do { - int depth = codeFormatter.indentFor(block); - if (depth != -1) { - if (QStringView(block.text()).trimmed().isEmpty()) { - // we do not want to indent empty lines (as one is indentent when pressing tab - // assuming that the user will start writing something), and get rid of that - // space if one had pressed tab in an empty line just before refactoring. - // If depth == -1 (inside a multiline string for example) leave the spaces. - depth = 0; - } - tabSettings.indentLine(block, depth); - } - codeFormatter.updateLineStateChange(block); - block = block.next(); - } while (block.isValid() && block != end); - } - - void reindentSelection(const QTextCursor &selection, - const Utils::FilePath &filePath, - const TextEditor::TextDocument *textDocument) const override - { - const TextEditor::TabSettings &tabSettings = - ProjectExplorer::actualTabSettings(filePath, textDocument); - - QmlJSEditor::Internal::Indenter indenter(selection.document()); - indenter.reindent(selection, tabSettings); - } - - void fileChanged(const Utils::FilePath &filePath) override - { - m_modelManager->updateSourceFiles({filePath}, true); - } - ModelManagerInterface *m_modelManager; Snapshot m_snapshot; }; @@ -193,8 +146,49 @@ QmlJSRefactoringChangesData *QmlJSRefactoringFile::data() const void QmlJSRefactoringFile::fileChanged() { + QTC_ASSERT(!m_filePath.isEmpty(), return); m_qmljsDocument.clear(); - RefactoringFile::fileChanged(); + data()->m_modelManager->updateSourceFiles({filePath()}, true); +} + +void QmlJSRefactoringFile::indentSelection(const QTextCursor &selection, + const TextEditor::TextDocument *textDocument) const +{ + // ### shares code with QmlJSTextEditor::indent + QTextDocument *doc = selection.document(); + + QTextBlock block = doc->findBlock(selection.selectionStart()); + const QTextBlock end = doc->findBlock(selection.selectionEnd()).next(); + + const TextEditor::TabSettings &tabSettings = + ProjectExplorer::actualTabSettings(filePath(), textDocument); + CreatorCodeFormatter codeFormatter(tabSettings); + codeFormatter.updateStateUntil(block); + do { + int depth = codeFormatter.indentFor(block); + if (depth != -1) { + if (QStringView(block.text()).trimmed().isEmpty()) { + // we do not want to indent empty lines (as one is indentent when pressing tab + // assuming that the user will start writing something), and get rid of that + // space if one had pressed tab in an empty line just before refactoring. + // If depth == -1 (inside a multiline string for example) leave the spaces. + depth = 0; + } + tabSettings.indentLine(block, depth); + } + codeFormatter.updateLineStateChange(block); + block = block.next(); + } while (block.isValid() && block != end); +} + +void QmlJSRefactoringFile::reindentSelection(const QTextCursor &selection, + const TextEditor::TextDocument *textDocument) const +{ + const TextEditor::TabSettings &tabSettings = + ProjectExplorer::actualTabSettings(filePath(), textDocument); + + QmlJSEditor::Internal::Indenter indenter(selection.document()); + indenter.reindent(selection, tabSettings); } } // namespace QmlJSTools diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.h b/src/plugins/qmljstools/qmljsrefactoringchanges.h index fa4e381edd7..8c5cf8501ae 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.h +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.h @@ -34,13 +34,18 @@ public: bool isCursorOn(QmlJS::AST::UiQualifiedId *ast) const; bool isCursorOn(QmlJS::SourceLocation loc) const; -protected: +private: QmlJSRefactoringFile(const Utils::FilePath &filePath, const QSharedPointer &data); QmlJSRefactoringFile(TextEditor::TextEditorWidget *editor, QmlJS::Document::Ptr document); QmlJSRefactoringChangesData *data() const; + void fileChanged() override; + void indentSelection(const QTextCursor &selection, + const TextEditor::TextDocument *textDocument) const override; + void reindentSelection(const QTextCursor &selection, + const TextEditor::TextDocument *textDocument) const override; mutable QmlJS::Document::Ptr m_qmljsDocument; diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp index fdff2567588..659d06b1b9a 100644 --- a/src/plugins/texteditor/refactoringchanges.cpp +++ b/src/plugins/texteditor/refactoringchanges.cpp @@ -118,7 +118,7 @@ bool RefactoringFile::create(const QString &contents, bool reindent, bool openEd // Reindent the contents: if (reindent) { cursor.select(QTextCursor::Document); - m_data->indentSelection(cursor, m_filePath, nullptr); + indentSelection(cursor, nullptr); } cursor.endEditBlock(); @@ -375,9 +375,9 @@ void RefactoringFile::indentOrReindent(const RefactoringSelections &ranges, QTextCursor selection(anchor); selection.setPosition(position.position(), QTextCursor::KeepAnchor); if (indent == Indent) - m_data->indentSelection(selection, m_filePath, document); + indentSelection(selection, document); else - m_data->reindentSelection(selection, m_filePath, document); + reindentSelection(selection, document); } } @@ -479,30 +479,20 @@ void RefactoringFile::doFormatting() } } -void RefactoringFile::fileChanged() +void RefactoringFile::indentSelection(const QTextCursor &selection, + const TextDocument *textDocument) const { - if (!m_filePath.isEmpty()) - m_data->fileChanged(m_filePath); + Q_UNUSED(selection) + Q_UNUSED(textDocument) +} + +void RefactoringFile::reindentSelection(const QTextCursor &selection, + const TextDocument *textDocument) const +{ + Q_UNUSED(selection) + Q_UNUSED(textDocument) } RefactoringChangesData::~RefactoringChangesData() = default; -void RefactoringChangesData::indentSelection(const QTextCursor &, - const FilePath &, - const TextDocument *) const -{ - qWarning() << Q_FUNC_INFO << "not implemented"; -} - -void RefactoringChangesData::reindentSelection(const QTextCursor &, - const FilePath &, - const TextDocument *) const -{ - qWarning() << Q_FUNC_INFO << "not implemented"; -} - -void RefactoringChangesData::fileChanged(const FilePath &) -{ -} - } // namespace TextEditor diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h index a0e71f12363..a147ba00826 100644 --- a/src/plugins/texteditor/refactoringchanges.h +++ b/src/plugins/texteditor/refactoringchanges.h @@ -72,8 +72,9 @@ protected: const QSharedPointer &data); QTextDocument *mutableDocument() const; + // derived classes may want to clear language specific extra data - virtual void fileChanged(); + virtual void fileChanged() {} enum IndentType {Indent, Reindent}; void indentOrReindent(const RefactoringSelections &ranges, IndentType indent); @@ -81,6 +82,11 @@ protected: void setupFormattingRanges(const QList &replaceList); void doFormatting(); + virtual void indentSelection(const QTextCursor &selection, + const TextDocument *textDocument) const; + virtual void reindentSelection(const QTextCursor &selection, + const TextDocument *textDocument) const; + Utils::FilePath m_filePath; QSharedPointer m_data; mutable Utils::TextFileFormat m_textFileFormat; @@ -140,14 +146,6 @@ class TEXTEDITOR_EXPORT RefactoringChangesData public: RefactoringChangesData() = default; virtual ~RefactoringChangesData(); - - virtual void indentSelection(const QTextCursor &selection, - const Utils::FilePath &filePath, - const TextDocument *textEditor) const; - virtual void reindentSelection(const QTextCursor &selection, - const Utils::FilePath &filePath, - const TextDocument *textEditor) const; - virtual void fileChanged(const Utils::FilePath &filePath); }; } // namespace TextEditor From 659f0f000c7e41210f5318d67ed23ee68c7dc16b Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 15 Nov 2023 10:33:31 +0100 Subject: [PATCH 0238/1546] TaskTree: Unify TaskInterface::done(DoneResult) signal Change the argument of TaskInterface::done() signal from bool into DoneResult. Make it consistent with other TaskTree API. Introduce toDoneResult(bool success) helper. Change-Id: I7b3041d7c1ed0317c76adbc1fd37448231e85f82 Reviewed-by: Qt CI Bot Reviewed-by: hjk --- src/libs/solutions/tasking/barrier.cpp | 10 +- src/libs/solutions/tasking/barrier.h | 16 +-- src/libs/solutions/tasking/concurrentcall.h | 4 +- src/libs/solutions/tasking/networkquery.cpp | 4 +- src/libs/solutions/tasking/networkquery.h | 2 +- src/libs/solutions/tasking/qprocesstask.h | 4 +- src/libs/solutions/tasking/tasktree.cpp | 21 +++- src/libs/solutions/tasking/tasktree.h | 114 +++++++++--------- src/libs/utils/async.h | 2 +- src/libs/utils/filestreamer.cpp | 11 +- src/libs/utils/filestreamer.h | 9 +- src/libs/utils/filestreamermanager.cpp | 6 +- src/libs/utils/process.cpp | 2 +- src/libs/utils/unarchiver.cpp | 12 +- src/libs/utils/unarchiver.h | 2 +- src/plugins/clangtools/clangtool.cpp | 10 +- .../cmakeprojectmanager/cmakebuildstep.cpp | 6 +- .../coreplugin/locator/ilocatorfilter.cpp | 2 +- .../coreplugin/locator/javascriptfilter.cpp | 6 +- src/plugins/ios/iosdeploystep.cpp | 8 +- src/plugins/languageclient/clientrequest.cpp | 3 +- .../currentdocumentsymbolsrequest.cpp | 7 +- .../currentdocumentsymbolsrequest.h | 2 +- src/plugins/projectexplorer/buildmanager.cpp | 4 +- .../devicesupport/deviceusedportsgatherer.h | 10 +- .../devicesupport/filetransfer.cpp | 7 +- .../projectexplorer/devicesupport/idevice.cpp | 9 +- .../projectexplorer/devicesupport/idevice.h | 2 +- src/plugins/qbsprojectmanager/qbsrequest.cpp | 13 +- src/plugins/qbsprojectmanager/qbsrequest.h | 2 +- .../qmldesigner/utils/fileextractor.cpp | 6 +- src/plugins/studiowelcome/examplecheckout.cpp | 6 +- src/plugins/valgrind/memchecktool.cpp | 4 +- src/plugins/valgrind/valgrindprocess.cpp | 8 +- src/plugins/valgrind/valgrindprocess.h | 2 +- src/plugins/valgrind/xmlprotocol/parser.cpp | 7 +- src/plugins/valgrind/xmlprotocol/parser.h | 2 +- tests/auto/solutions/tasking/tst_tasking.cpp | 2 +- tests/auto/valgrind/memcheck/modeldemo.cpp | 4 +- 39 files changed, 191 insertions(+), 160 deletions(-) diff --git a/src/libs/solutions/tasking/barrier.cpp b/src/libs/solutions/tasking/barrier.cpp index c4daa033b41..e160dbac769 100644 --- a/src/libs/solutions/tasking/barrier.cpp +++ b/src/libs/solutions/tasking/barrier.cpp @@ -35,18 +35,18 @@ void Barrier::advance() return; ++m_current; if (m_current == m_limit) - stopWithResult(true); + stopWithResult(DoneResult::Success); } -void Barrier::stopWithResult(bool success) +void Barrier::stopWithResult(DoneResult result) { // Calling stopWithResult on finished is OK when the same success is passed - QTC_ASSERT(isRunning() || (m_result && *m_result == success), return); + QTC_ASSERT(isRunning() || (m_result && *m_result == result), return); if (!isRunning()) // no-op return; m_current = -1; - m_result = success; - emit done(success); + m_result = result; + emit done(result); } } // namespace Tasking diff --git a/src/libs/solutions/tasking/barrier.h b/src/libs/solutions/tasking/barrier.h index 3001916fb68..13b6dfa48fd 100644 --- a/src/libs/solutions/tasking/barrier.h +++ b/src/libs/solutions/tasking/barrier.h @@ -19,17 +19,17 @@ public: void start(); void advance(); // If limit reached, stops with true - void stopWithResult(bool success); // Ignores limit + void stopWithResult(DoneResult result); // Ignores limit bool isRunning() const { return m_current >= 0; } int current() const { return m_current; } - std::optional result() const { return m_result; } + std::optional result() const { return m_result; } signals: - void done(bool success); + void done(DoneResult success); private: - std::optional m_result = {}; + std::optional m_result = {}; int m_limit = 1; int m_current = -1; }; @@ -80,9 +80,11 @@ GroupItem waitForBarrierTask(const MultiBarrier &sharedBarrier) return SetupResult::StopWithError; } Barrier *activeSharedBarrier = activeBarrier->barrier(); - const std::optional result = activeSharedBarrier->result(); - if (result.has_value()) - return result.value() ? SetupResult::StopWithSuccess : SetupResult::StopWithError; + const std::optional result = activeSharedBarrier->result(); + if (result.has_value()) { + return result.value() == DoneResult::Success ? SetupResult::StopWithSuccess + : SetupResult::StopWithError; + } QObject::connect(activeSharedBarrier, &Barrier::done, &barrier, &Barrier::stopWithResult); return SetupResult::Continue; }); diff --git a/src/libs/solutions/tasking/concurrentcall.h b/src/libs/solutions/tasking/concurrentcall.h index 6298b053724..300d0cd610f 100644 --- a/src/libs/solutions/tasking/concurrentcall.h +++ b/src/libs/solutions/tasking/concurrentcall.h @@ -78,12 +78,12 @@ public: void start() { if (!this->task()->m_startHandler) { - emit this->done(false); // TODO: Add runtime assert + emit this->done(DoneResult::Error); // TODO: Add runtime assert return; } m_watcher.reset(new QFutureWatcher); this->connect(m_watcher.get(), &QFutureWatcherBase::finished, this, [this] { - emit this->done(!m_watcher->isCanceled()); + emit this->done(toDoneResult(!m_watcher->isCanceled())); m_watcher.release()->deleteLater(); }); this->task()->m_future = this->task()->m_startHandler(); diff --git a/src/libs/solutions/tasking/networkquery.cpp b/src/libs/solutions/tasking/networkquery.cpp index 292d3c7d4aa..07d1c008171 100644 --- a/src/libs/solutions/tasking/networkquery.cpp +++ b/src/libs/solutions/tasking/networkquery.cpp @@ -16,13 +16,13 @@ void NetworkQuery::start() if (!m_manager) { qWarning("Can't start the NetworkQuery without the QNetworkAccessManager. " "Stopping with an error."); - emit done(false); + emit done(DoneResult::Error); return; } m_reply.reset(m_manager->get(m_request)); connect(m_reply.get(), &QNetworkReply::finished, this, [this] { disconnect(m_reply.get(), nullptr, this, nullptr); - emit done(m_reply->error() == QNetworkReply::NoError); + emit done(toDoneResult(m_reply->error() == QNetworkReply::NoError)); m_reply.release()->deleteLater(); }); if (m_reply->isRunning()) diff --git a/src/libs/solutions/tasking/networkquery.h b/src/libs/solutions/tasking/networkquery.h index 0cac720584a..bf08bd1e7b5 100644 --- a/src/libs/solutions/tasking/networkquery.h +++ b/src/libs/solutions/tasking/networkquery.h @@ -35,7 +35,7 @@ public: signals: void started(); - void done(bool success); + void done(DoneResult result); private: QNetworkRequest m_request; diff --git a/src/libs/solutions/tasking/qprocesstask.h b/src/libs/solutions/tasking/qprocesstask.h index 5fa4c19a41c..cc0b83698b8 100644 --- a/src/libs/solutions/tasking/qprocesstask.h +++ b/src/libs/solutions/tasking/qprocesstask.h @@ -50,12 +50,12 @@ private: const bool success = task()->exitStatus() == QProcess::NormalExit && task()->error() == QProcess::UnknownError && task()->exitCode() == 0; - emit done(success); + emit done(toDoneResult(success)); }); connect(task(), &QProcess::errorOccurred, this, [this](QProcess::ProcessError error) { if (error != QProcess::FailedToStart) return; - emit done(false); + emit done(DoneResult::Error); }); task()->start(); } diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index d1401548592..6058f3bd1cc 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -836,6 +836,11 @@ const GroupItem stopOnSuccessOrError = workflowPolicy(WorkflowPolicy::StopOnSucc const GroupItem finishAllAndSuccess = workflowPolicy(WorkflowPolicy::FinishAllAndSuccess); const GroupItem finishAllAndError = workflowPolicy(WorkflowPolicy::FinishAllAndError); +DoneResult toDoneResult(bool success) +{ + return success ? DoneResult::Success : DoneResult::Error; +} + static SetupResult toSetupResult(bool success) { return success ? SetupResult::StopWithSuccess : SetupResult::StopWithError; @@ -846,6 +851,11 @@ static DoneResult toDoneResult(DoneWith doneWith) return doneWith == DoneWith::Success ? DoneResult::Success : DoneResult::Error; } +static DoneWith toDoneWith(DoneResult result) +{ + return result == DoneResult::Success ? DoneWith::Success : DoneWith::Error; +} + class StorageThreadData { Q_DISABLE_COPY_MOVE(StorageThreadData) @@ -1548,8 +1558,8 @@ SetupResult TaskTreePrivate::start(TaskRuntimeNode *node) const std::shared_ptr unwindAction = std::make_shared(SetupResult::Continue); QObject::connect(node->m_task.get(), &TaskInterface::done, - q, [this, node, unwindAction](bool success) { - const bool result = invokeDoneHandler(node, success ? DoneWith::Success : DoneWith::Error); + q, [this, node, unwindAction](DoneResult doneResult) { + const bool result = invokeDoneHandler(node, toDoneWith(doneResult)); QObject::disconnect(node->m_task.get(), &TaskInterface::done, q, nullptr); node->m_task.release()->deleteLater(); TaskRuntimeContainer *parentContainer = node->m_parentContainer; @@ -2650,7 +2660,7 @@ void TaskTree::setupStorageHandler(const TreeStorageBase &storage, TaskTreeTaskAdapter::TaskTreeTaskAdapter() { connect(task(), &TaskTree::done, this, - [this](DoneWith result) { emit done(result == DoneWith::Success); }); + [this](DoneWith result) { emit done(toDoneResult(result)); }); } void TaskTreeTaskAdapter::start() @@ -2743,7 +2753,10 @@ TimeoutTaskAdapter::~TimeoutTaskAdapter() void TimeoutTaskAdapter::start() { - m_timerId = scheduleTimeout(*task(), this, [this] { m_timerId = {}; emit done(true); }); + m_timerId = scheduleTimeout(*task(), this, [this] { + m_timerId = {}; + emit done(DoneResult::Success); + }); } } // namespace Tasking diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 0be2aa097f4..5fa2d1e89da 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -19,6 +19,63 @@ namespace Tasking { Q_NAMESPACE_EXPORT(TASKING_EXPORT) +// WorkflowPolicy: +// 1. When all children finished with success -> report success, otherwise: +// a) Report error on first error and stop executing other children (including their subtree). +// b) On first error - continue executing all children and report error afterwards. +// 2. When all children finished with error -> report error, otherwise: +// a) Report success on first success and stop executing other children (including their subtree). +// b) On first success - continue executing all children and report success afterwards. +// 3. Stops on first finished child. In sequential mode it will never run other children then the first one. +// Useful only in parallel mode. +// 4. Always run all children, let them finish, ignore their results and report success afterwards. +// 5. Always run all children, let them finish, ignore their results and report error afterwards. + +enum class WorkflowPolicy +{ + StopOnError, // 1a - Reports error on first child error, otherwise success (if all children were success). + ContinueOnError, // 1b - The same, but children execution continues. Reports success when no children. + StopOnSuccess, // 2a - Reports success on first child success, otherwise error (if all children were error). + ContinueOnSuccess, // 2b - The same, but children execution continues. Reports error when no children. + StopOnSuccessOrError, // 3 - Stops on first finished child and report its result. + FinishAllAndSuccess, // 4 - Reports success after all children finished. + FinishAllAndError // 5 - Reports error after all children finished. +}; +Q_ENUM_NS(WorkflowPolicy); + +enum class SetupResult +{ + Continue, + StopWithSuccess, + StopWithError +}; +Q_ENUM_NS(SetupResult); + +enum class DoneResult +{ + Success, + Error +}; +Q_ENUM_NS(DoneResult); + +enum class DoneWith +{ + Success, + Error, + Cancel +}; +Q_ENUM_NS(DoneWith); + +enum class CallDoneIf +{ + SuccessOrError, + Success, + Error +}; +Q_ENUM_NS(CallDoneIf); + +TASKING_EXPORT DoneResult toDoneResult(bool success); + class StorageData; class TaskTreePrivate; @@ -27,7 +84,7 @@ class TASKING_EXPORT TaskInterface : public QObject Q_OBJECT signals: - void done(bool success); + void done(DoneResult result); private: template friend class TaskAdapter; @@ -88,61 +145,6 @@ private: } }; -// WorkflowPolicy: -// 1. When all children finished with success -> report success, otherwise: -// a) Report error on first error and stop executing other children (including their subtree). -// b) On first error - continue executing all children and report error afterwards. -// 2. When all children finished with error -> report error, otherwise: -// a) Report success on first success and stop executing other children (including their subtree). -// b) On first success - continue executing all children and report success afterwards. -// 3. Stops on first finished child. In sequential mode it will never run other children then the first one. -// Useful only in parallel mode. -// 4. Always run all children, let them finish, ignore their results and report success afterwards. -// 5. Always run all children, let them finish, ignore their results and report error afterwards. - -enum class WorkflowPolicy -{ - StopOnError, // 1a - Reports error on first child error, otherwise success (if all children were success). - ContinueOnError, // 1b - The same, but children execution continues. Reports success when no children. - StopOnSuccess, // 2a - Reports success on first child success, otherwise error (if all children were error). - ContinueOnSuccess, // 2b - The same, but children execution continues. Reports error when no children. - StopOnSuccessOrError, // 3 - Stops on first finished child and report its result. - FinishAllAndSuccess, // 4 - Reports success after all children finished. - FinishAllAndError // 5 - Reports error after all children finished. -}; -Q_ENUM_NS(WorkflowPolicy); - -enum class SetupResult -{ - Continue, - StopWithSuccess, - StopWithError -}; -Q_ENUM_NS(SetupResult); - -enum class DoneResult -{ - Success, - Error -}; -Q_ENUM_NS(DoneResult); - -enum class DoneWith -{ - Success, - Error, - Cancel -}; -Q_ENUM_NS(DoneWith); - -enum class CallDoneIf -{ - SuccessOrError, - Success, - Error -}; -Q_ENUM_NS(CallDoneIf); - class TASKING_EXPORT GroupItem { public: diff --git a/src/libs/utils/async.h b/src/libs/utils/async.h index 64ade0a9e3b..d10f4e2fed5 100644 --- a/src/libs/utils/async.h +++ b/src/libs/utils/async.h @@ -204,7 +204,7 @@ class AsyncTaskAdapter : public Tasking::TaskAdapter> public: AsyncTaskAdapter() { this->connect(this->task(), &AsyncBase::done, this, [this] { - emit this->done(!this->task()->isCanceled()); + emit this->done(Tasking::toDoneResult(!this->task()->isCanceled())); }); } void start() final { this->task()->start(); } diff --git a/src/libs/utils/filestreamer.cpp b/src/libs/utils/filestreamer.cpp index d4d34c477fa..0e834e0acf2 100644 --- a/src/libs/utils/filestreamer.cpp +++ b/src/libs/utils/filestreamer.cpp @@ -34,13 +34,13 @@ public: m_taskTree.reset(new TaskTree({task})); connect(m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) { m_taskTree.release()->deleteLater(); - emit done(result == DoneWith::Success); + emit done(toDoneResult(result == DoneWith::Success)); }); m_taskTree->start(); } signals: - void done(bool success); + void done(DoneResult result); protected: FilePath m_filePath; @@ -381,7 +381,7 @@ public: FilePath m_destination; QByteArray m_readBuffer; QByteArray m_writeBuffer; - StreamResult m_streamResult = StreamResult::FinishedWithError; + DoneResult m_streamResult = DoneResult::Error; std::unique_ptr m_taskTree; GroupItem task() { @@ -454,7 +454,7 @@ void FileStreamer::setWriteData(const QByteArray &writeData) d->m_writeBuffer = writeData; } -StreamResult FileStreamer::result() const +DoneResult FileStreamer::result() const { return d->m_streamResult; } @@ -465,8 +465,7 @@ void FileStreamer::start() QTC_ASSERT(!d->m_taskTree, return); d->m_taskTree.reset(new TaskTree({d->task()})); connect(d->m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) { - d->m_streamResult = result == DoneWith::Success ? StreamResult::FinishedWithSuccess - : StreamResult::FinishedWithError; + d->m_streamResult = toDoneResult(result == DoneWith::Success); d->m_taskTree.release()->deleteLater(); emit done(); }); diff --git a/src/libs/utils/filestreamer.h b/src/libs/utils/filestreamer.h index 828f27be8e1..8f569ff4363 100644 --- a/src/libs/utils/filestreamer.h +++ b/src/libs/utils/filestreamer.h @@ -19,8 +19,6 @@ namespace Utils { enum class StreamMode { Reader, Writer, Transfer }; -enum class StreamResult { FinishedWithSuccess, FinishedWithError }; - class QTCREATOR_UTILS_EXPORT FileStreamer final : public QObject { Q_OBJECT @@ -38,7 +36,7 @@ public: // Only for Writer mode void setWriteData(const QByteArray &writeData); - StreamResult result() const; + Tasking::DoneResult result() const; void start(); void stop(); @@ -53,8 +51,9 @@ private: class FileStreamerTaskAdapter : public Tasking::TaskAdapter { public: - FileStreamerTaskAdapter() { connect(task(), &FileStreamer::done, this, - [this] { emit done(task()->result() == StreamResult::FinishedWithSuccess); }); } + FileStreamerTaskAdapter() { + connect(task(), &FileStreamer::done, this, [this] { emit done(task()->result()); }); + } void start() override { task()->start(); } }; diff --git a/src/libs/utils/filestreamermanager.cpp b/src/libs/utils/filestreamermanager.cpp index 33df7b264ea..9cdfb15c039 100644 --- a/src/libs/utils/filestreamermanager.cpp +++ b/src/libs/utils/filestreamermanager.cpp @@ -129,7 +129,7 @@ FileStreamHandle FileStreamerManager::copy(const FilePath &source, const FilePat return execute(onSetup, {}, context); const auto onDone = [=](FileStreamer *streamer) { - if (streamer->result() == StreamResult::FinishedWithSuccess) + if (streamer->result() == Tasking::DoneResult::Success) cont({}); else cont(make_unexpected(Tr::tr("Failed copying file."))); @@ -153,7 +153,7 @@ FileStreamHandle FileStreamerManager::read(const FilePath &source, QObject *cont return execute(onSetup, {}, context); const auto onDone = [=](FileStreamer *streamer) { - if (streamer->result() == StreamResult::FinishedWithSuccess) + if (streamer->result() == Tasking::DoneResult::Success) cont(streamer->readData()); else cont(make_unexpected(Tr::tr("Failed reading file."))); @@ -179,7 +179,7 @@ FileStreamHandle FileStreamerManager::write(const FilePath &destination, const Q return execute(onSetup, {}, context); const auto onDone = [=](FileStreamer *streamer) { - if (streamer->result() == StreamResult::FinishedWithSuccess) + if (streamer->result() == Tasking::DoneResult::Success) cont(0); // TODO: return write count? else cont(make_unexpected(Tr::tr("Failed writing file."))); diff --git a/src/libs/utils/process.cpp b/src/libs/utils/process.cpp index 192b3bc880c..29f4a1f852b 100644 --- a/src/libs/utils/process.cpp +++ b/src/libs/utils/process.cpp @@ -2160,7 +2160,7 @@ void ProcessPrivate::storeEventLoopDebugInfo(const QVariant &value) ProcessTaskAdapter::ProcessTaskAdapter() { connect(task(), &Process::done, this, [this] { - emit done(task()->result() == ProcessResult::FinishedWithSuccess); + emit done(Tasking::toDoneResult(task()->result() == ProcessResult::FinishedWithSuccess)); }); } diff --git a/src/libs/utils/unarchiver.cpp b/src/libs/utils/unarchiver.cpp index 9435bc77a51..84365654253 100644 --- a/src/libs/utils/unarchiver.cpp +++ b/src/libs/utils/unarchiver.cpp @@ -10,6 +10,8 @@ #include +using namespace Tasking; + namespace Utils { namespace { @@ -128,16 +130,16 @@ static CommandLine unarchiveCommand(const CommandLine &commandTemplate, const Fi void Unarchiver::start() { - QTC_ASSERT(!m_process, emit done(false); return); + QTC_ASSERT(!m_process, emit done(DoneResult::Error); return); if (!m_sourceAndCommand) { emit outputReceived(Tr::tr("No source file set.")); - emit done(false); + emit done(DoneResult::Error); return; } if (m_destDir.isEmpty()) { emit outputReceived(Tr::tr("No destination directory set.")); - emit done(false); + emit done(DoneResult::Error); return; } @@ -154,7 +156,7 @@ void Unarchiver::start() const bool success = m_process->result() == ProcessResult::FinishedWithSuccess; if (!success) emit outputReceived(Tr::tr("Command failed.")); - emit done(success); + emit done(toDoneResult(success)); }); emit outputReceived(Tr::tr("Running %1\nin \"%2\".\n\n", "Running in ") @@ -167,7 +169,7 @@ void Unarchiver::start() UnarchiverTaskAdapter::UnarchiverTaskAdapter() { - connect(task(), &Unarchiver::done, this, &Tasking::TaskInterface::done); + connect(task(), &Unarchiver::done, this, &TaskInterface::done); } void UnarchiverTaskAdapter::start() diff --git a/src/libs/utils/unarchiver.h b/src/libs/utils/unarchiver.h index 3e2b2f89386..b255cd49900 100644 --- a/src/libs/utils/unarchiver.h +++ b/src/libs/utils/unarchiver.h @@ -37,7 +37,7 @@ public: signals: void outputReceived(const QString &output); - void done(bool success); + void done(Tasking::DoneResult result); private: std::optional m_sourceAndCommand; diff --git a/src/plugins/clangtools/clangtool.cpp b/src/plugins/clangtools/clangtool.cpp index 4033785e796..61b30cfa5f2 100644 --- a/src/plugins/clangtools/clangtool.cpp +++ b/src/plugins/clangtools/clangtool.cpp @@ -75,11 +75,13 @@ class ProjectBuilderTaskAdapter : public TaskAdapter> public: void start() final { connect(BuildManager::instance(), &BuildManager::buildQueueFinished, - this, &TaskInterface::done); + this, [this](bool success) { + emit done(toDoneResult(success)); + }); RunControl *runControl = *task(); - QTC_ASSERT(runControl, emit done(false); return); + QTC_ASSERT(runControl, emit done(DoneResult::Error); return); Target *target = runControl->target(); - QTC_ASSERT(target, emit done(false); return); + QTC_ASSERT(target, emit done(DoneResult::Error); return); if (!BuildManager::isBuilding(target)) { BuildManager::buildProjectWithDependencies(target->project(), ConfigSelection::Active, runControl); @@ -822,7 +824,7 @@ Group ClangTool::runRecipe(const RunSettings &runSettings, }; topTasks.append(Group { - Tasking::Storage(storage), + Storage(storage), TaskTreeTask(onTreeSetup, onTreeDone, CallDoneIf::Success) }); return {topTasks}; diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp index b2e13b84b54..e1330280f74 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp @@ -68,10 +68,12 @@ public: void start() final { Target *target = *task(); if (!target) { - emit done(false); + emit done(DoneResult::Error); return; } - connect(target, &Target::parsingFinished, this, &TaskInterface::done); + connect(target, &Target::parsingFinished, this, [this](bool success) { + emit done(toDoneResult(success)); + }); } }; diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.cpp b/src/plugins/coreplugin/locator/ilocatorfilter.cpp index f66dc0383f5..94cc24831c3 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/ilocatorfilter.cpp @@ -322,7 +322,7 @@ class ResultsCollectorTaskAdapter : public TaskAdapter { public: ResultsCollectorTaskAdapter() { - connect(task(), &ResultsCollector::done, this, [this] { emit done(true); }); + connect(task(), &ResultsCollector::done, this, [this] { emit done(DoneResult::Success); }); } void start() final { task()->start(); } }; diff --git a/src/plugins/coreplugin/locator/javascriptfilter.cpp b/src/plugins/coreplugin/locator/javascriptfilter.cpp index 73c723e9888..f1b8af35b9c 100644 --- a/src/plugins/coreplugin/locator/javascriptfilter.cpp +++ b/src/plugins/coreplugin/locator/javascriptfilter.cpp @@ -305,7 +305,7 @@ public: m_timer.reset(); m_output = output; m_id = {}; - emit done(output.m_result == JavaScriptResult::FinishedWithSuccess); + emit done(toDoneResult(output.m_result == JavaScriptResult::FinishedWithSuccess)); }; m_id = m_engine->addRequest(input); if (m_timeout > 0ms) { @@ -318,7 +318,7 @@ public: m_timer.release()->deleteLater(); m_id = {}; m_output = {Tr::tr("Engine aborted after timeout."), JavaScriptResult::Canceled}; - emit done(false); + emit done(DoneResult::Error); }); m_timer->start(); } @@ -328,7 +328,7 @@ public: JavaScriptOutput output() const { return m_output; } signals: - void done(bool success); + void done(DoneResult result); private: QPointer m_engine; diff --git a/src/plugins/ios/iosdeploystep.cpp b/src/plugins/ios/iosdeploystep.cpp index 3f80d9d931a..02f75d27671 100644 --- a/src/plugins/ios/iosdeploystep.cpp +++ b/src/plugins/ios/iosdeploystep.cpp @@ -41,7 +41,7 @@ public: void setExpectSuccess(bool success) { m_expectSuccess = success; } void start() { - QTC_ASSERT(m_deviceType, emit done(false); return); + QTC_ASSERT(m_deviceType, emit done(DoneResult::Error); return); QTC_ASSERT(!m_toolHandler, return); m_toolHandler.reset(new IosToolHandler(*m_deviceType)); @@ -65,19 +65,19 @@ public: TaskHub::addTask(DeploymentTask(Task::Error, Tr::tr("Deployment failed. " "The settings in the Devices window of Xcode might be incorrect."))); } - emit done(status == IosToolHandler::Success); + emit done(toDoneResult(status == IosToolHandler::Success)); }); connect(m_toolHandler.get(), &IosToolHandler::finished, this, [this] { disconnect(m_toolHandler.get(), nullptr, this, nullptr); m_toolHandler.release()->deleteLater(); TaskHub::addTask(DeploymentTask(Task::Error, Tr::tr("Deployment failed."))); - emit done(false); + emit done(DoneResult::Error); }); m_toolHandler->requestTransferApp(m_bundlePath, m_deviceType->identifier); } signals: - void done(bool success); + void done(DoneResult result); void progressValueChanged(int progress, const QString &info); // progress in % void errorMessage(const QString &message); diff --git a/src/plugins/languageclient/clientrequest.cpp b/src/plugins/languageclient/clientrequest.cpp index 630a1b01940..4e221f1b9d4 100644 --- a/src/plugins/languageclient/clientrequest.cpp +++ b/src/plugins/languageclient/clientrequest.cpp @@ -4,13 +4,14 @@ #include "clientrequest.h" using namespace LanguageServerProtocol; +using namespace Tasking; namespace LanguageClient { ClientWorkspaceSymbolRequestTaskAdapter::ClientWorkspaceSymbolRequestTaskAdapter() { task()->setResponseCallback([this](const WorkspaceSymbolRequest::Response &response){ - emit done(response.result().has_value()); + emit done(toDoneResult(response.result().has_value())); }); } diff --git a/src/plugins/languageclient/currentdocumentsymbolsrequest.cpp b/src/plugins/languageclient/currentdocumentsymbolsrequest.cpp index 2d272a72161..15506e0e99d 100644 --- a/src/plugins/languageclient/currentdocumentsymbolsrequest.cpp +++ b/src/plugins/languageclient/currentdocumentsymbolsrequest.cpp @@ -10,6 +10,7 @@ using namespace Core; using namespace LanguageServerProtocol; +using namespace Tasking; using namespace TextEditor; using namespace Utils; @@ -24,7 +25,7 @@ void CurrentDocumentSymbolsRequest::start() TextDocument *document = TextDocument::currentTextDocument(); Client *client = LanguageClientManager::clientForDocument(document); if (!client) { - emit done(false); + emit done(DoneResult::Error); return; } @@ -34,7 +35,7 @@ void CurrentDocumentSymbolsRequest::start() const auto reportFailure = [this] { clearConnections(); - emit done(false); + emit done(DoneResult::Error); }; const auto updateSymbols = [this, currentUri, pathMapper](const DocumentUri &uri, @@ -46,7 +47,7 @@ void CurrentDocumentSymbolsRequest::start() const FilePath filePath = pathMapper ? currentUri.toFilePath(pathMapper) : FilePath(); m_currentDocumentSymbolsData = {filePath, pathMapper, symbols}; clearConnections(); - emit done(true); + emit done(DoneResult::Success); }; m_connections.append(connect(EditorManager::instance(), &EditorManager::currentEditorChanged, diff --git a/src/plugins/languageclient/currentdocumentsymbolsrequest.h b/src/plugins/languageclient/currentdocumentsymbolsrequest.h index ef124154dfd..3ea7ee5f152 100644 --- a/src/plugins/languageclient/currentdocumentsymbolsrequest.h +++ b/src/plugins/languageclient/currentdocumentsymbolsrequest.h @@ -30,7 +30,7 @@ public: CurrentDocumentSymbolsData currentDocumentSymbolsData() const { return m_currentDocumentSymbolsData; } signals: - void done(bool success); + void done(Tasking::DoneResult result); private: void clearConnections(); diff --git a/src/plugins/projectexplorer/buildmanager.cpp b/src/plugins/projectexplorer/buildmanager.cpp index 46d90d14e80..ef2307309b4 100644 --- a/src/plugins/projectexplorer/buildmanager.cpp +++ b/src/plugins/projectexplorer/buildmanager.cpp @@ -67,14 +67,14 @@ private: this, [this, buildSystem](bool success) { disconnect(buildSystem, &BuildSystem::parsingFinished, this, nullptr); if (!success) { - emit done(false); + emit done(DoneResult::Error); return; } checkParsing(); }); return; } - emit done(true); + emit done(DoneResult::Success); } }; diff --git a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h index ee6b2760060..dead5f222a2 100644 --- a/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h +++ b/src/plugins/projectexplorer/devicesupport/deviceusedportsgatherer.h @@ -11,6 +11,8 @@ #include +using namespace Tasking; + namespace ProjectExplorer { namespace Internal { @@ -45,12 +47,12 @@ private: }; class PROJECTEXPLORER_EXPORT DeviceUsedPortsGathererTaskAdapter - : public Tasking::TaskAdapter + : public TaskAdapter { public: DeviceUsedPortsGathererTaskAdapter() { - connect(task(), &DeviceUsedPortsGatherer::portListReady, this, [this] { emit done(true); }); - connect(task(), &DeviceUsedPortsGatherer::error, this, [this] { emit done(false); }); + connect(task(), &DeviceUsedPortsGatherer::portListReady, this, [this] { emit done(DoneResult::Success); }); + connect(task(), &DeviceUsedPortsGatherer::error, this, [this] { emit done(DoneResult::Error); }); } void start() final { task()->start(); } }; @@ -87,6 +89,6 @@ private: QVector m_channelProviders; }; -using DeviceUsedPortsGathererTask = Tasking::CustomTask; +using DeviceUsedPortsGathererTask = CustomTask; } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/devicesupport/filetransfer.cpp b/src/plugins/projectexplorer/devicesupport/filetransfer.cpp index 05815797672..b31a8f44280 100644 --- a/src/plugins/projectexplorer/devicesupport/filetransfer.cpp +++ b/src/plugins/projectexplorer/devicesupport/filetransfer.cpp @@ -196,9 +196,10 @@ QString FileTransfer::transferMethodName(FileTransferMethod method) FileTransferTaskAdapter::FileTransferTaskAdapter() { connect(task(), &FileTransfer::done, this, [this](const ProcessResultData &result) { - emit done(result.m_exitStatus == QProcess::NormalExit - && result.m_error == QProcess::UnknownError - && result.m_exitCode == 0); + const bool success = result.m_exitStatus == QProcess::NormalExit + && result.m_error == QProcess::UnknownError + && result.m_exitCode == 0; + emit done(Tasking::toDoneResult(success)); }); } diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp index 489e6b337e6..59697554469 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp @@ -5,7 +5,6 @@ #include "devicemanager.h" #include "idevicefactory.h" -#include "processlist.h" #include "sshparameters.h" #include "../kit.h" @@ -710,6 +709,8 @@ void DeviceProcessSignalOperation::setDebuggerCommand(const FilePath &cmd) DeviceProcessSignalOperation::DeviceProcessSignalOperation() = default; +using namespace Tasking; + void DeviceProcessKiller::start() { m_signalOperation.reset(); @@ -718,7 +719,7 @@ void DeviceProcessKiller::start() const IDevice::ConstPtr device = DeviceManager::deviceForPath(m_processPath); if (!device) { m_errorString = Tr::tr("No device for given path: \"%1\".").arg(m_processPath.toUserOutput()); - emit done(false); + emit done(DoneResult::Error); return; } @@ -726,14 +727,14 @@ void DeviceProcessKiller::start() if (!m_signalOperation) { m_errorString = Tr::tr("Device for path \"%1\" does not support killing processes.") .arg(m_processPath.toUserOutput()); - emit done(false); + emit done(DoneResult::Error); return; } connect(m_signalOperation.get(), &DeviceProcessSignalOperation::finished, this, [this](const QString &errorMessage) { m_errorString = errorMessage; - emit done(m_errorString.isEmpty()); + emit done(toDoneResult(m_errorString.isEmpty())); }); m_signalOperation->killProcess(m_processPath.path()); diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h index a6f9d860b84..4642697c76b 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.h +++ b/src/plugins/projectexplorer/devicesupport/idevice.h @@ -279,7 +279,7 @@ public: QString errorString() const { return m_errorString; } signals: - void done(bool success); + void done(Tasking::DoneResult result); private: Utils::FilePath m_processPath; diff --git a/src/plugins/qbsprojectmanager/qbsrequest.cpp b/src/plugins/qbsprojectmanager/qbsrequest.cpp index 1355922b448..e6ac1c2fb89 100644 --- a/src/plugins/qbsprojectmanager/qbsrequest.cpp +++ b/src/plugins/qbsprojectmanager/qbsrequest.cpp @@ -13,6 +13,7 @@ #include using namespace ProjectExplorer; +using namespace Tasking; using namespace Utils; namespace QbsProjectManager::Internal { @@ -40,7 +41,7 @@ public: void cancel(); signals: - void done(bool success); + void done(DoneResult result); void progressChanged(int progress, const QString &info); // progress in % void outputAdded(const QString &output, ProjectExplorer::BuildStep::OutputFormat format); void taskAdded(const ProjectExplorer::Task &task); @@ -114,7 +115,7 @@ void QbsRequestObject::start() if (m_parseData) { connect(m_parseData->target(), &Target::parsingFinished, this, [this](bool success) { disconnect(m_parseData->target(), &Target::parsingFinished, this, nullptr); - emit done(success); + emit done(toDoneResult(success)); }); QMetaObject::invokeMethod(m_parseData.get(), &QbsBuildSystem::startParsing, Qt::QueuedConnection); @@ -127,7 +128,7 @@ void QbsRequestObject::start() emit outputAdded(item.description, BuildStep::OutputFormat::Stdout); emit taskAdded(CompileTask(Task::Error, item.description, item.filePath, item.line)); } - emit done(error.items.isEmpty()); + emit done(toDoneResult(error.items.isEmpty())); }; connect(m_session, &QbsSession::projectBuilt, this, handleDone); connect(m_session, &QbsSession::projectCleaned, this, handleDone); @@ -188,7 +189,7 @@ QbsRequest::~QbsRequest() void QbsRequest::start() { QTC_ASSERT(!m_requestObject, return); - QTC_ASSERT(m_parseData || (m_session && m_requestData), emit done(false); return); + QTC_ASSERT(m_parseData || (m_session && m_requestData), emit done(DoneResult::Error); return); m_requestObject = new QbsRequestObject; m_requestObject->setSession(m_session); @@ -199,10 +200,10 @@ void QbsRequest::start() m_requestObject->setParseData(m_parseData); } - connect(m_requestObject, &QbsRequestObject::done, this, [this](bool success) { + connect(m_requestObject, &QbsRequestObject::done, this, [this](DoneResult result) { m_requestObject->deleteLater(); m_requestObject = nullptr; - emit done(success); + emit done(result); }); connect(m_requestObject, &QbsRequestObject::progressChanged, this, &QbsRequest::progressChanged); diff --git a/src/plugins/qbsprojectmanager/qbsrequest.h b/src/plugins/qbsprojectmanager/qbsrequest.h index e86909504b6..bd3eb6db43c 100644 --- a/src/plugins/qbsprojectmanager/qbsrequest.h +++ b/src/plugins/qbsprojectmanager/qbsrequest.h @@ -28,7 +28,7 @@ public: void start(); signals: - void done(bool success); + void done(Tasking::DoneResult result); void progressChanged(int progress, const QString &info); // progress in % void outputAdded(const QString &output, ProjectExplorer::BuildStep::OutputFormat format); void taskAdded(const ProjectExplorer::Task &task); diff --git a/src/plugins/qmldesigner/utils/fileextractor.cpp b/src/plugins/qmldesigner/utils/fileextractor.cpp index 40381c5a27a..67dc68aca90 100644 --- a/src/plugins/qmldesigner/utils/fileextractor.cpp +++ b/src/plugins/qmldesigner/utils/fileextractor.cpp @@ -243,9 +243,9 @@ void FileExtractor::extract() emit detailedTextChanged(); }); - QObject::connect(m_unarchiver.get(), &Unarchiver::done, this, [this](bool success) { + QObject::connect(m_unarchiver.get(), &Unarchiver::done, this, [this](Tasking::DoneResult result) { m_unarchiver.release()->deleteLater(); - m_finished = success; + m_finished = result == Tasking::DoneResult::Success; m_timer.stop(); m_progress = 100; @@ -253,7 +253,7 @@ void FileExtractor::extract() emit targetFolderExistsChanged(); emit finishedChanged(); - QTC_CHECK(success); + QTC_CHECK(m_finished); }); m_unarchiver->start(); } diff --git a/src/plugins/studiowelcome/examplecheckout.cpp b/src/plugins/studiowelcome/examplecheckout.cpp index 7b13c59fa88..d0e30824917 100644 --- a/src/plugins/studiowelcome/examplecheckout.cpp +++ b/src/plugins/studiowelcome/examplecheckout.cpp @@ -37,6 +37,7 @@ #include +using namespace Tasking; using namespace Utils; void ExampleCheckout::registerTypes() @@ -124,8 +125,9 @@ DataModelDownloader::DataModelDownloader(QObject * /* parent */) auto unarchiver = new Unarchiver; unarchiver->setSourceAndCommand(*sourceAndCommand); unarchiver->setDestDir(tempFilePath()); - QObject::connect(unarchiver, &Unarchiver::done, this, [this, unarchiver](bool success) { - QTC_CHECK(success); + QObject::connect(unarchiver, &Unarchiver::done, this, + [this, unarchiver](DoneResult result) { + QTC_CHECK(result == DoneResult::Success); unarchiver->deleteLater(); emit finished(); }); diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp index 1cbd522571c..5a23bac90ea 100644 --- a/src/plugins/valgrind/memchecktool.cpp +++ b/src/plugins/valgrind/memchecktool.cpp @@ -1051,8 +1051,8 @@ void MemcheckToolPrivate::loadXmlLogFile(const QString &filePath) m_logParser.reset(new Parser); connect(m_logParser.get(), &Parser::error, this, &MemcheckToolPrivate::parserError); - connect(m_logParser.get(), &Parser::done, this, [this](bool success, const QString &err) { - if (!success) + connect(m_logParser.get(), &Parser::done, this, [this](DoneResult result, const QString &err) { + if (result == DoneResult::Error) internalParserError(err); loadingExternalXmlLogFileFinished(); m_logParser.release()->deleteLater(); diff --git a/src/plugins/valgrind/valgrindprocess.cpp b/src/plugins/valgrind/valgrindprocess.cpp index e4178f84397..9862d407998 100644 --- a/src/plugins/valgrind/valgrindprocess.cpp +++ b/src/plugins/valgrind/valgrindprocess.cpp @@ -93,7 +93,7 @@ public: const bool success = process->result() == ProcessResult::FinishedWithSuccess; if (!success) emit q->processErrorReceived(process->errorString(), process->error()); - emit q->done(success); + emit q->done(toDoneResult(success)); }); connect(process, &Process::readyReadStandardOutput, this, [this, process] { emit q->appendMessage(process->readAllStandardOutput(), StdOutFormat); @@ -215,7 +215,7 @@ bool ValgrindProcessPrivate::run() m_taskTree->setRecipe(runRecipe()); connect(m_taskTree.get(), &TaskTree::done, this, [this](DoneWith result) { m_taskTree.release()->deleteLater(); - emit q->done(result == DoneWith::Success); + emit q->done(toDoneResult(result == DoneWith::Success)); }); m_taskTree->start(); return bool(m_taskTree); @@ -268,8 +268,8 @@ bool ValgrindProcess::runBlocking() bool ok = false; QEventLoop loop; - const auto finalize = [&loop, &ok](bool success) { - ok = success; + const auto finalize = [&loop, &ok](DoneResult result) { + ok = result == DoneResult::Success; // Refer to the QObject::deleteLater() docs. QMetaObject::invokeMethod(&loop, [&loop] { loop.quit(); }, Qt::QueuedConnection); }; diff --git a/src/plugins/valgrind/valgrindprocess.h b/src/plugins/valgrind/valgrindprocess.h index 065d4ad47ad..7a4e722c0da 100644 --- a/src/plugins/valgrind/valgrindprocess.h +++ b/src/plugins/valgrind/valgrindprocess.h @@ -50,7 +50,7 @@ signals: void logMessageReceived(const QByteArray &); void processErrorReceived(const QString &, QProcess::ProcessError); void valgrindStarted(qint64 pid); - void done(bool success); + void done(Tasking::DoneResult result); // Parser's signals void status(const Valgrind::XmlProtocol::Status &status); diff --git a/src/plugins/valgrind/xmlprotocol/parser.cpp b/src/plugins/valgrind/xmlprotocol/parser.cpp index df464e33247..72a393fe7c5 100644 --- a/src/plugins/valgrind/xmlprotocol/parser.cpp +++ b/src/plugins/valgrind/xmlprotocol/parser.cpp @@ -25,6 +25,7 @@ #include #include +using namespace Tasking; using namespace Utils; namespace Valgrind::XmlProtocol { @@ -710,7 +711,7 @@ public: m_errorString = data.m_internalError; }); QObject::connect(m_watcher.get(), &QFutureWatcherBase::finished, q, [this] { - emit q->done(!m_errorString, *m_errorString); + emit q->done(toDoneResult(!m_errorString), *m_errorString); m_watcher.release()->deleteLater(); m_thread.reset(); m_socket.reset(); @@ -786,8 +787,8 @@ bool Parser::runBlocking() bool ok = false; QEventLoop loop; - const auto finalize = [&loop, &ok](bool success) { - ok = success; + const auto finalize = [&loop, &ok](DoneResult result) { + ok = result == DoneResult::Success; // Refer to the QObject::deleteLater() docs. QMetaObject::invokeMethod(&loop, [&loop] { loop.quit(); }, Qt::QueuedConnection); }; diff --git a/src/plugins/valgrind/xmlprotocol/parser.h b/src/plugins/valgrind/xmlprotocol/parser.h index df34601bc35..9116ad6d81a 100644 --- a/src/plugins/valgrind/xmlprotocol/parser.h +++ b/src/plugins/valgrind/xmlprotocol/parser.h @@ -45,7 +45,7 @@ signals: void errorCount(qint64 unique, qint64 count); void suppressionCount(const QString &name, qint64 count); void announceThread(const AnnounceThread &announceThread); - void done(bool success, const QString &errorString); + void done(Tasking::DoneResult result, const QString &errorString); private: std::unique_ptr d; diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index ec90218f3a4..da9929bff1f 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -345,7 +345,7 @@ class TickAndDoneTaskAdapter : public TaskAdapter { public: TickAndDoneTaskAdapter() { connect(task(), &TickAndDone::done, this, - [this] { emit done(true); }); } + [this] { emit done(DoneResult::Success); }); } void start() final { task()->start(); } }; diff --git a/tests/auto/valgrind/memcheck/modeldemo.cpp b/tests/auto/valgrind/memcheck/modeldemo.cpp index 4fe18f1bf8b..eec6c16ae81 100644 --- a/tests/auto/valgrind/memcheck/modeldemo.cpp +++ b/tests/auto/valgrind/memcheck/modeldemo.cpp @@ -36,8 +36,8 @@ int main(int argc, char *argv[]) QObject::connect(&runner, &ValgrindProcess::processErrorReceived, &app, [](const QString &err) { qDebug() << err; }); - QObject::connect(&runner, &ValgrindProcess::done, &app, [](bool success) { - qApp->exit(success ? 0 : 1); + QObject::connect(&runner, &ValgrindProcess::done, &app, [](Tasking::DoneResult result) { + qApp->exit(result == Tasking::DoneResult::Success ? 0 : 1); }); ErrorListModel model; QObject::connect(&runner, &ValgrindProcess::error, &model, &ErrorListModel::addError, From 1c8ac2e7d35002d84de9871d8c7130d145cb42f4 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 16 Nov 2023 19:55:35 +0100 Subject: [PATCH 0239/1546] TaskTree docs: Update docs about TaskInterface::done()'s arg Now it's DoneResult, instead of bool. Change-Id: Ia6eab42b08774d6b51f2bf4435ac083946f5d53d Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 6058f3bd1cc..71dece59855 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -85,11 +85,11 @@ private: */ /*! - \fn void TaskInterface::done(bool success) + \fn void TaskInterface::done(DoneResult result) Emit this signal from the \c TaskAdapter's subclass, when the \c Task is finished. - Pass \c true as a \a success argument when the task finishes with success; - otherwise, when an error occurs, pass \c false. + Pass \c DoneResult::Success as a \a result argument when the task finishes with success; + otherwise, when an error occurs, pass \c DoneResult::Error. */ /*! @@ -2174,8 +2174,7 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith To extend a TaskTree with a new task type, implement a simple adapter class derived from the TaskAdapter class template. The following class is an - adapter for a single shot timer, which may be considered as a new - asynchronous task: + adapter for a single shot timer, which may be considered as a new asynchronous task: \code class TimerTaskAdapter : public TaskAdapter @@ -2184,7 +2183,7 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith TimerTaskAdapter() { task()->setSingleShot(true); task()->setInterval(1000); - connect(task(), &QTimer::timeout, this, [this] { emit done(true); }); + connect(task(), &QTimer::timeout, this, [this] { emit done(DoneResult::Success); }); } private: void start() final { task()->start(); } @@ -2201,8 +2200,8 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith accessible through the TaskAdapter::task() method. The constructor of TimerTaskAdapter initially configures the QTimer object and connects to the QTimer::timeout signal. When the signal is triggered, TimerTaskAdapter - emits the \c done(true) signal to inform the task tree that the task finished - successfully. If it emits \c done(false), the task finished with an error. + emits the \c done(DoneResult::Success) signal to inform the task tree that the task finished + successfully. If it emits \c done(DoneResult::Error), the task finished with an error. The TaskAdapter::start() method starts the timer. To make QTimer accessible inside TaskTree under the \e TimerTask name, @@ -2212,14 +2211,10 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith The new task type is now registered, and you can use it in TaskTree: \code - const auto onTimerSetup = [](QTimer &task) { - task.setInterval(2000); - }; - const auto onTimerDone = [](const QTimer &task) { - qDebug() << "timer triggered"; - }; + const auto onSetup = [](QTimer &task) { task.setInterval(2000); }; + const auto onDone = [] { qDebug() << "timer triggered"; }; const Group root { - TimerTask(onTimerSetup, onTimerDone) + TimerTask(onSetup, onDone) }; \endcode From 5d6fc1fc3bec1bac6cdbd4aec65bd63658d4ac0a Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 16 Nov 2023 17:24:51 +0100 Subject: [PATCH 0240/1546] TextEditor: Remove RefactoringFile::m_data There is no use for a generic data member. Change-Id: Iabfbc0587db2cffcc1c19baed832aa866f696ffe Reviewed-by: Qt CI Bot Reviewed-by: Reviewed-by: David Schulz --- src/plugins/cppeditor/cpprefactoringchanges.cpp | 17 ++++++----------- src/plugins/cppeditor/cpprefactoringchanges.h | 5 ++--- .../qmljstools/qmljsrefactoringchanges.cpp | 15 +++++---------- .../qmljstools/qmljsrefactoringchanges.h | 5 ++--- src/plugins/texteditor/refactoringchanges.cpp | 9 +++------ src/plugins/texteditor/refactoringchanges.h | 4 +--- 6 files changed, 19 insertions(+), 36 deletions(-) diff --git a/src/plugins/cppeditor/cpprefactoringchanges.cpp b/src/plugins/cppeditor/cpprefactoringchanges.cpp index e5c33acfdb2..a1514a9efbf 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.cpp +++ b/src/plugins/cppeditor/cpprefactoringchanges.cpp @@ -52,7 +52,7 @@ CppRefactoringFilePtr CppRefactoringChanges::file(TextEditor::TextEditorWidget * TextEditor::RefactoringFilePtr CppRefactoringChanges::file(const FilePath &filePath) const { - CppRefactoringFilePtr result(new CppRefactoringFile(filePath, m_data)); + CppRefactoringFilePtr result(new CppRefactoringFile(filePath, m_data.staticCast())); return result; } @@ -67,7 +67,7 @@ CppRefactoringFileConstPtr CppRefactoringChanges::fileNoEditor(const FilePath &f if (const auto source = data()->m_workingCopy.source(filePath)) document = new QTextDocument(QString::fromUtf8(*source)); CppRefactoringFilePtr result(new CppRefactoringFile(document, filePath)); - result->m_data = m_data; + result->m_data = m_data.staticCast(); return result; } @@ -77,10 +77,10 @@ const Snapshot &CppRefactoringChanges::snapshot() const return data()->m_snapshot; } -CppRefactoringFile::CppRefactoringFile(const FilePath &filePath, const QSharedPointer &data) - : RefactoringFile(filePath, data) +CppRefactoringFile::CppRefactoringFile(const FilePath &filePath, const QSharedPointer &data) + : RefactoringFile(filePath), m_data(data) { - const Snapshot &snapshot = this->data()->m_snapshot; + const Snapshot &snapshot = data->m_snapshot; m_cppDocument = snapshot.document(filePath); m_formattingEnabled = true; } @@ -102,7 +102,7 @@ Document::Ptr CppRefactoringFile::cppDocument() const if (!m_cppDocument || !m_cppDocument->translationUnit() || !m_cppDocument->translationUnit()->ast()) { const QByteArray source = document()->toPlainText().toUtf8(); - const Snapshot &snapshot = data()->m_snapshot; + const Snapshot &snapshot = m_data->m_snapshot; m_cppDocument = snapshot.preprocessedDocument(source, filePath()); m_cppDocument->check(); @@ -239,11 +239,6 @@ const Token &CppRefactoringFile::tokenAt(unsigned index) const return cppDocument()->translationUnit()->tokenAt(index); } -CppRefactoringChangesData *CppRefactoringFile::data() const -{ - return static_cast(m_data.data()); -} - void CppRefactoringFile::fileChanged() { QTC_ASSERT(!m_filePath.isEmpty(), return); diff --git a/src/plugins/cppeditor/cpprefactoringchanges.h b/src/plugins/cppeditor/cpprefactoringchanges.h index 878c38d4342..972aae34918 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.h +++ b/src/plugins/cppeditor/cpprefactoringchanges.h @@ -52,12 +52,10 @@ public: QString textOf(const CPlusPlus::AST *ast) const; private: - CppRefactoringFile(const Utils::FilePath &filePath, const QSharedPointer &data); + CppRefactoringFile(const Utils::FilePath &filePath, const QSharedPointer &data); CppRefactoringFile(QTextDocument *document, const Utils::FilePath &filePath); explicit CppRefactoringFile(TextEditor::TextEditorWidget *editor); - CppRefactoringChangesData *data() const; - void fileChanged() override; void indentSelection(const QTextCursor &selection, const TextEditor::TextDocument *textDocument) const override; @@ -69,6 +67,7 @@ private: int startIndex) const; mutable CPlusPlus::Document::Ptr m_cppDocument; + QSharedPointer m_data; friend class CppRefactoringChanges; // for access to constructor }; diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp index 24bd14f52b0..617d5292e99 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp @@ -36,7 +36,7 @@ QmlJSRefactoringChanges::QmlJSRefactoringChanges(ModelManagerInterface *modelMan TextEditor::RefactoringFilePtr QmlJSRefactoringChanges::file(const Utils::FilePath &filePath) const { - return QmlJSRefactoringFilePtr(new QmlJSRefactoringFile(filePath, m_data)); + return QmlJSRefactoringFilePtr(new QmlJSRefactoringFile(filePath, m_data.staticCast())); } QmlJSRefactoringFilePtr QmlJSRefactoringChanges::qmlJSFile(const Utils::FilePath &filePath) const @@ -61,8 +61,8 @@ QmlJSRefactoringChangesData *QmlJSRefactoringChanges::data() const } QmlJSRefactoringFile::QmlJSRefactoringFile( - const Utils::FilePath &filePath, const QSharedPointer &data) - : RefactoringFile(filePath, data) + const Utils::FilePath &filePath, const QSharedPointer &data) + : RefactoringFile(filePath), m_data(data) { // the RefactoringFile is invalid if its not for a file with qml or js code if (ModelManagerInterface::guessLanguageOfFile(filePath) == Dialect::NoLanguage) @@ -81,7 +81,7 @@ Document::Ptr QmlJSRefactoringFile::qmljsDocument() const { if (!m_qmljsDocument) { const QString source = document()->toPlainText(); - const Snapshot &snapshot = data()->m_snapshot; + const Snapshot &snapshot = m_data->m_snapshot; Document::MutablePtr newDoc = snapshot.documentFromSource(source, @@ -139,16 +139,11 @@ bool QmlJSRefactoringFile::isCursorOn(SourceLocation loc) const return pos >= loc.begin() && pos <= loc.end(); } -QmlJSRefactoringChangesData *QmlJSRefactoringFile::data() const -{ - return static_cast(m_data.data()); -} - void QmlJSRefactoringFile::fileChanged() { QTC_ASSERT(!m_filePath.isEmpty(), return); m_qmljsDocument.clear(); - data()->m_modelManager->updateSourceFiles({filePath()}, true); + m_data->m_modelManager->updateSourceFiles({filePath()}, true); } void QmlJSRefactoringFile::indentSelection(const QTextCursor &selection, diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.h b/src/plugins/qmljstools/qmljsrefactoringchanges.h index 8c5cf8501ae..11d23b382d6 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.h +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.h @@ -36,11 +36,9 @@ public: private: QmlJSRefactoringFile(const Utils::FilePath &filePath, - const QSharedPointer &data); + const QSharedPointer &data); QmlJSRefactoringFile(TextEditor::TextEditorWidget *editor, QmlJS::Document::Ptr document); - QmlJSRefactoringChangesData *data() const; - void fileChanged() override; void indentSelection(const QTextCursor &selection, const TextEditor::TextDocument *textDocument) const override; @@ -48,6 +46,7 @@ private: const TextEditor::TextDocument *textDocument) const override; mutable QmlJS::Document::Ptr m_qmljsDocument; + QSharedPointer m_data; friend class QmlJSRefactoringChanges; }; diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp index 659d06b1b9a..1f655bf7d63 100644 --- a/src/plugins/texteditor/refactoringchanges.cpp +++ b/src/plugins/texteditor/refactoringchanges.cpp @@ -78,7 +78,7 @@ TextEditorWidget *RefactoringChanges::openEditor(const FilePath &filePath, RefactoringFilePtr RefactoringChanges::file(const FilePath &filePath) const { - return RefactoringFilePtr(new RefactoringFile(filePath, m_data)); + return RefactoringFilePtr(new RefactoringFile(filePath)); } RefactoringFile::RefactoringFile(QTextDocument *document, const FilePath &filePath) @@ -91,10 +91,7 @@ RefactoringFile::RefactoringFile(TextEditorWidget *editor) , m_editor(editor) { } -RefactoringFile::RefactoringFile(const FilePath &filePath, - const QSharedPointer &data) - : m_filePath(filePath) - , m_data(data) +RefactoringFile::RefactoringFile(const FilePath &filePath) : m_filePath(filePath) { QList editors = DocumentModel::editorsForFilePath(filePath); if (!editors.isEmpty()) { @@ -307,7 +304,7 @@ bool RefactoringFile::apply() bool result = true; // apply changes, if any - if (m_data && !(m_indentRanges.isEmpty() && m_changes.isEmpty())) { + if (!m_indentRanges.isEmpty() || !m_changes.isEmpty()) { QTextDocument *doc = mutableDocument(); if (doc) { QTextCursor c = cursor(); diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h index a147ba00826..95e250e9e01 100644 --- a/src/plugins/texteditor/refactoringchanges.h +++ b/src/plugins/texteditor/refactoringchanges.h @@ -68,8 +68,7 @@ protected: RefactoringFile(QTextDocument *document, const Utils::FilePath &filePath); RefactoringFile(TextEditorWidget *editor); - RefactoringFile(const Utils::FilePath &filePath, - const QSharedPointer &data); + RefactoringFile(const Utils::FilePath &filePath); QTextDocument *mutableDocument() const; @@ -88,7 +87,6 @@ protected: const TextDocument *textDocument) const; Utils::FilePath m_filePath; - QSharedPointer m_data; mutable Utils::TextFileFormat m_textFileFormat; mutable QTextDocument *m_document = nullptr; TextEditorWidget *m_editor = nullptr; From 246a878a34f89b99187f0e7cffe6671335b5d5ac Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 16 Nov 2023 17:33:35 +0100 Subject: [PATCH 0241/1546] TextEditor: Remove RefactoringChanges::m_data There is no use for a data member in the base class. Change-Id: I126d8713d2a7bf4061ecbd60b4c144d39c08d550 Reviewed-by: Qt CI Bot Reviewed-by: Reviewed-by: David Schulz --- src/plugins/cppeditor/cpprefactoringchanges.cpp | 14 ++++---------- src/plugins/cppeditor/cpprefactoringchanges.h | 2 +- src/plugins/qmljstools/qmljsrefactoringchanges.cpp | 11 +++-------- src/plugins/qmljstools/qmljsrefactoringchanges.h | 2 +- src/plugins/texteditor/refactoringchanges.cpp | 4 ---- src/plugins/texteditor/refactoringchanges.h | 3 --- 6 files changed, 9 insertions(+), 27 deletions(-) diff --git a/src/plugins/cppeditor/cpprefactoringchanges.cpp b/src/plugins/cppeditor/cpprefactoringchanges.cpp index a1514a9efbf..7ee709c118f 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.cpp +++ b/src/plugins/cppeditor/cpprefactoringchanges.cpp @@ -34,15 +34,10 @@ static std::unique_ptr createIndenter(const FilePath &file } CppRefactoringChanges::CppRefactoringChanges(const Snapshot &snapshot) - : RefactoringChanges(new CppRefactoringChangesData(snapshot)) + : m_data(new CppRefactoringChangesData(snapshot)) { } -CppRefactoringChangesData *CppRefactoringChanges::data() const -{ - return static_cast(m_data.data()); -} - CppRefactoringFilePtr CppRefactoringChanges::file(TextEditor::TextEditorWidget *editor, const Document::Ptr &document) { CppRefactoringFilePtr result(new CppRefactoringFile(editor)); @@ -52,8 +47,7 @@ CppRefactoringFilePtr CppRefactoringChanges::file(TextEditor::TextEditorWidget * TextEditor::RefactoringFilePtr CppRefactoringChanges::file(const FilePath &filePath) const { - CppRefactoringFilePtr result(new CppRefactoringFile(filePath, m_data.staticCast())); - return result; + return TextEditor::RefactoringFilePtr(new CppRefactoringFile(filePath, m_data)); } CppRefactoringFilePtr CppRefactoringChanges::cppFile(const Utils::FilePath &filePath) const @@ -64,7 +58,7 @@ CppRefactoringFilePtr CppRefactoringChanges::cppFile(const Utils::FilePath &file CppRefactoringFileConstPtr CppRefactoringChanges::fileNoEditor(const FilePath &filePath) const { QTextDocument *document = nullptr; - if (const auto source = data()->m_workingCopy.source(filePath)) + if (const auto source = m_data->m_workingCopy.source(filePath)) document = new QTextDocument(QString::fromUtf8(*source)); CppRefactoringFilePtr result(new CppRefactoringFile(document, filePath)); result->m_data = m_data.staticCast(); @@ -74,7 +68,7 @@ CppRefactoringFileConstPtr CppRefactoringChanges::fileNoEditor(const FilePath &f const Snapshot &CppRefactoringChanges::snapshot() const { - return data()->m_snapshot; + return m_data->m_snapshot; } CppRefactoringFile::CppRefactoringFile(const FilePath &filePath, const QSharedPointer &data) diff --git a/src/plugins/cppeditor/cpprefactoringchanges.h b/src/plugins/cppeditor/cpprefactoringchanges.h index 972aae34918..ab8fbae1a3f 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.h +++ b/src/plugins/cppeditor/cpprefactoringchanges.h @@ -98,7 +98,7 @@ public: const CPlusPlus::Snapshot &snapshot() const; private: - CppRefactoringChangesData *data() const; + const QSharedPointer m_data; }; } // namespace CppEditor diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp index 617d5292e99..f9182cefd8b 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp @@ -30,13 +30,13 @@ public: QmlJSRefactoringChanges::QmlJSRefactoringChanges(ModelManagerInterface *modelManager, const Snapshot &snapshot) - : RefactoringChanges(new QmlJSRefactoringChangesData(modelManager, snapshot)) + : m_data(new QmlJSRefactoringChangesData(modelManager, snapshot)) { } TextEditor::RefactoringFilePtr QmlJSRefactoringChanges::file(const Utils::FilePath &filePath) const { - return QmlJSRefactoringFilePtr(new QmlJSRefactoringFile(filePath, m_data.staticCast())); + return QmlJSRefactoringFilePtr(new QmlJSRefactoringFile(filePath, m_data)); } QmlJSRefactoringFilePtr QmlJSRefactoringChanges::qmlJSFile(const Utils::FilePath &filePath) const @@ -52,12 +52,7 @@ QmlJSRefactoringFilePtr QmlJSRefactoringChanges::file( const Snapshot &QmlJSRefactoringChanges::snapshot() const { - return data()->m_snapshot; -} - -QmlJSRefactoringChangesData *QmlJSRefactoringChanges::data() const -{ - return static_cast(m_data.data()); + return m_data->m_snapshot; } QmlJSRefactoringFile::QmlJSRefactoringFile( diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.h b/src/plugins/qmljstools/qmljsrefactoringchanges.h index 11d23b382d6..71db46a7c5a 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.h +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.h @@ -67,7 +67,7 @@ public: const QmlJS::Snapshot &snapshot() const; private: - QmlJSRefactoringChangesData *data() const; + const QSharedPointer m_data; }; } // namespace QmlJSTools diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp index 1f655bf7d63..dc278e45227 100644 --- a/src/plugins/texteditor/refactoringchanges.cpp +++ b/src/plugins/texteditor/refactoringchanges.cpp @@ -26,10 +26,6 @@ using namespace Utils; namespace TextEditor { -RefactoringChanges::RefactoringChanges(RefactoringChangesData *data) - : m_data(data ? data : new RefactoringChangesData) -{} - RefactoringChanges::~RefactoringChanges() = default; RefactoringSelections RefactoringChanges::rangesToSelections(QTextDocument *document, diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h index 95e250e9e01..f5ecaab3861 100644 --- a/src/plugins/texteditor/refactoringchanges.h +++ b/src/plugins/texteditor/refactoringchanges.h @@ -112,7 +112,6 @@ class TEXTEDITOR_EXPORT RefactoringChanges public: using Range = Utils::ChangeSet::Range; - explicit RefactoringChanges(RefactoringChangesData *data = nullptr); virtual ~RefactoringChanges(); // TODO: Make pure virtual and introduce dedicated subclass for generic refactoring, @@ -132,8 +131,6 @@ protected: static RefactoringSelections rangesToSelections(QTextDocument *document, const QList &ranges); - QSharedPointer m_data; - friend class RefactoringFile; }; From 5baf4d83c6c5763a455c41bfdf52fa74c0817065 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 16 Nov 2023 17:40:08 +0100 Subject: [PATCH 0242/1546] TextEditor: Remove now-unused RefactoringChangesData Change-Id: Idf82ce013f19422d2b5931669e1aaa4a3aa64b16 Reviewed-by: Reviewed-by: Qt CI Bot Reviewed-by: David Schulz --- src/plugins/cppeditor/cpprefactoringchanges.h | 2 +- src/plugins/qmljstools/qmljsrefactoringchanges.cpp | 2 +- src/plugins/texteditor/refactoringchanges.cpp | 2 -- src/plugins/texteditor/refactoringchanges.h | 10 ---------- 4 files changed, 2 insertions(+), 14 deletions(-) diff --git a/src/plugins/cppeditor/cpprefactoringchanges.h b/src/plugins/cppeditor/cpprefactoringchanges.h index ab8fbae1a3f..cdff9f30eb4 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.h +++ b/src/plugins/cppeditor/cpprefactoringchanges.h @@ -72,7 +72,7 @@ private: friend class CppRefactoringChanges; // for access to constructor }; -class CPPEDITOR_EXPORT CppRefactoringChangesData : public TextEditor::RefactoringChangesData +class CPPEDITOR_EXPORT CppRefactoringChangesData { public: explicit CppRefactoringChangesData(const CPlusPlus::Snapshot &snapshot); diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp index f9182cefd8b..6d16b1663cc 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp @@ -15,7 +15,7 @@ using namespace QmlJS; namespace QmlJSTools { -class QmlJSRefactoringChangesData : public TextEditor::RefactoringChangesData +class QmlJSRefactoringChangesData { public: QmlJSRefactoringChangesData(ModelManagerInterface *modelManager, diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp index dc278e45227..4391822d9c4 100644 --- a/src/plugins/texteditor/refactoringchanges.cpp +++ b/src/plugins/texteditor/refactoringchanges.cpp @@ -486,6 +486,4 @@ void RefactoringFile::reindentSelection(const QTextCursor &selection, Q_UNUSED(textDocument) } -RefactoringChangesData::~RefactoringChangesData() = default; - } // namespace TextEditor diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h index f5ecaab3861..85489563087 100644 --- a/src/plugins/texteditor/refactoringchanges.h +++ b/src/plugins/texteditor/refactoringchanges.h @@ -24,7 +24,6 @@ class TextDocument; class TextEditorWidget; class RefactoringChanges; class RefactoringFile; -class RefactoringChangesData; using RefactoringFilePtr = QSharedPointer; using RefactoringSelections = QVector>; @@ -134,13 +133,4 @@ protected: friend class RefactoringFile; }; -class TEXTEDITOR_EXPORT RefactoringChangesData -{ - Q_DISABLE_COPY(RefactoringChangesData) - -public: - RefactoringChangesData() = default; - virtual ~RefactoringChangesData(); -}; - } // namespace TextEditor From aa83b0ce6556e739f5d1699f8d51f258ce441439 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Thu, 16 Nov 2023 16:51:58 +0100 Subject: [PATCH 0243/1546] ProjectExplorer: Make CodeStyleSettingsWidget expanding This encourages the code style project settings panel to take the abundant vertical space. Change-Id: Ia14c4e3246a0ab4099850b3013e4ea915a7e1433 Reviewed-by: Reviewed-by: David Schulz --- src/plugins/projectexplorer/codestylesettingspropertiespage.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp b/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp index ed859e84337..0153a6a1958 100644 --- a/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/codestylesettingspropertiespage.cpp @@ -35,6 +35,7 @@ public: setGlobalSettingsId(CppEditor::Constants::CPP_CODE_STYLE_SETTINGS_ID); setUseGlobalSettingsCheckBoxVisible(false); + setExpanding(true); const EditorConfiguration *config = project->editorConfiguration(); From 7f60ce0666da1d5cc92cce92d63cb1b6b50fb64c Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Wed, 15 Nov 2023 16:25:09 +0100 Subject: [PATCH 0244/1546] Utils: Align enum StyleHelper::UiElement with upcoming design system #1 This change demotes the existing H1 and H2 to H3 and H4. It is supposed to not change the visual appearance. Change-Id: Idc3056307f0286a2d4d276ba79125ba93d5ac428 Reviewed-by: Cristian Adam --- src/libs/utils/stylehelper.cpp | 10 +++++----- src/plugins/coreplugin/dialogs/settingsdialog.cpp | 2 +- .../projectexplorer/buildsettingspropertiespage.cpp | 4 ++-- src/plugins/projectexplorer/panelswidget.cpp | 2 +- src/plugins/projectexplorer/projectwindow.cpp | 4 ++-- .../projectexplorer/runsettingspropertiespage.cpp | 4 ++-- src/plugins/projectexplorer/targetsettingspanel.cpp | 2 +- src/plugins/welcome/introductionwidget.cpp | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/libs/utils/stylehelper.cpp b/src/libs/utils/stylehelper.cpp index 5e76ee3386e..e6f520b7d13 100644 --- a/src/libs/utils/stylehelper.cpp +++ b/src/libs/utils/stylehelper.cpp @@ -941,17 +941,17 @@ QFont StyleHelper::UiFont(UiElement element) switch (element) { case UiElementH1: + break; + case UiElementH2: + break; + case UiElementH3: font.setPointSizeF(font.pointSizeF() * 1.6); font.setBold(true); break; - case UiElementH2: + case UiElementH4: font.setPointSizeF(font.pointSizeF() * 1.2); font.setBold(true); break; - case UiElementH3: - break; - case UiElementH4: - break; case UiElementPanelTitle: { font.setPointSizeF(panelTitleSize); font.setBold(true); diff --git a/src/plugins/coreplugin/dialogs/settingsdialog.cpp b/src/plugins/coreplugin/dialogs/settingsdialog.cpp index 3d890b8515e..a939de2b34c 100644 --- a/src/plugins/coreplugin/dialogs/settingsdialog.cpp +++ b/src/plugins/coreplugin/dialogs/settingsdialog.cpp @@ -570,7 +570,7 @@ void SettingsDialog::showPage(const Id pageId) void SettingsDialog::createGui() { - m_headerLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); + m_headerLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH4)); auto headerHLayout = new QHBoxLayout; const int leftMargin = QApplication::style()->pixelMetric(QStyle::PM_LayoutLeftMargin); diff --git a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp index a53e489d82d..6f410fe4a93 100644 --- a/src/plugins/projectexplorer/buildsettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/buildsettingspropertiespage.cpp @@ -54,7 +54,7 @@ BuildSettingsWidget::BuildSettingsWidget(Target *target) : if (!BuildConfigurationFactory::find(m_target)) { auto noSettingsLabel = new QLabel(this); noSettingsLabel->setText(Tr::tr("No build settings available")); - noSettingsLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); + noSettingsLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH4)); vbox->addWidget(noSettingsLabel); return; } @@ -126,7 +126,7 @@ void BuildSettingsWidget::addSubWidget(NamedWidget *widget) auto label = new QLabel(this); label->setText(widget->displayName()); - label->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); + label->setFont(StyleHelper::UiFont(StyleHelper::UiElementH4)); label->setContentsMargins(0, 18, 0, 0); diff --git a/src/plugins/projectexplorer/panelswidget.cpp b/src/plugins/projectexplorer/panelswidget.cpp index 38843bfe8d7..0278dd2282d 100644 --- a/src/plugins/projectexplorer/panelswidget.cpp +++ b/src/plugins/projectexplorer/panelswidget.cpp @@ -100,7 +100,7 @@ void PanelsWidget::addPropertiesPanel(const QString &displayName) auto nameLabel = new QLabel(m_root); nameLabel->setText(displayName); nameLabel->setContentsMargins(0, ABOVE_HEADING_MARGIN, 0, 0); - nameLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH1)); + nameLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH3)); m_layout->addWidget(nameLabel); m_layout->addWidget(Layouting::createHr()); } diff --git a/src/plugins/projectexplorer/projectwindow.cpp b/src/plugins/projectexplorer/projectwindow.cpp index 44e62bc5279..0c81de04b71 100644 --- a/src/plugins/projectexplorer/projectwindow.cpp +++ b/src/plugins/projectexplorer/projectwindow.cpp @@ -570,7 +570,7 @@ public: selectorView->setAutoFillBackground(true); auto activeLabel = new QLabel(Tr::tr("Active Project")); - activeLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); + activeLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH4)); auto innerLayout = new QVBoxLayout; innerLayout->setSpacing(10); @@ -903,7 +903,7 @@ void SelectorDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti case 2: { QColor col = creatorTheme()->color(Theme::TextColorNormal); opt.palette.setColor(QPalette::Text, col); - opt.font = StyleHelper::UiFont(StyleHelper::UiElementH2); + opt.font = StyleHelper::UiFont(StyleHelper::UiElementH4); break; } } diff --git a/src/plugins/projectexplorer/runsettingspropertiespage.cpp b/src/plugins/projectexplorer/runsettingspropertiespage.cpp index a4800e41ea1..d191971fb24 100644 --- a/src/plugins/projectexplorer/runsettingspropertiespage.cpp +++ b/src/plugins/projectexplorer/runsettingspropertiespage.cpp @@ -69,7 +69,7 @@ RunSettingsWidget::RunSettingsWidget(Target *target) : runLabel->setBuddy(m_runConfigurationCombo); - const QFont f = Utils::StyleHelper::UiFont(Utils::StyleHelper::UiElementH2); + const QFont f = Utils::StyleHelper::UiFont(Utils::StyleHelper::UiElementH4); runTitle->setFont(f); deployTitle->setFont(f); @@ -498,7 +498,7 @@ void RunSettingsWidget::addSubWidget(QWidget *widget, QLabel *label) { widget->setContentsMargins({}); - label->setFont(Utils::StyleHelper::UiFont(Utils::StyleHelper::UiElementH2)); + label->setFont(Utils::StyleHelper::UiFont(Utils::StyleHelper::UiElementH4)); label->setContentsMargins(0, 18, 0, 0); diff --git a/src/plugins/projectexplorer/targetsettingspanel.cpp b/src/plugins/projectexplorer/targetsettingspanel.cpp index dba282b51d8..72d4219a7d4 100644 --- a/src/plugins/projectexplorer/targetsettingspanel.cpp +++ b/src/plugins/projectexplorer/targetsettingspanel.cpp @@ -185,7 +185,7 @@ void TargetGroupItemPrivate::ensureWidget() auto label = new QLabel; label->setText(Tr::tr("No kit defined in this project.")); - label->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); + label->setFont(StyleHelper::UiFont(StyleHelper::UiElementH4)); label->setContentsMargins(10, 10, 10, 10); label->setAlignment(Qt::AlignTop); diff --git a/src/plugins/welcome/introductionwidget.cpp b/src/plugins/welcome/introductionwidget.cpp index 28e25fbf61f..eac31ad2956 100644 --- a/src/plugins/welcome/introductionwidget.cpp +++ b/src/plugins/welcome/introductionwidget.cpp @@ -78,7 +78,7 @@ IntroductionWidget::IntroductionWidget(QWidget *parent) m_continueLabel->setAlignment(Qt::AlignCenter); m_continueLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); m_continueLabel->setWordWrap(true); - m_continueLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH1)); + m_continueLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH3)); m_continueLabel->setPalette(palette()); layout->addWidget(m_continueLabel); m_bodyCss = "font-size: 16px;"; From b3acdae3386255324511119cd92d9012edf0eb9b Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 17 Nov 2023 11:02:38 +0100 Subject: [PATCH 0245/1546] Utils: Align enum StyleHelper::UiElement with upcoming design system #2 This change "PanelTitle" to "Caption". It is supposed to not change the visual appearance. Change-Id: I3342e6c80d8ce11b7ab1ac40b4395c265e1e07ec Reviewed-by: Cristian Adam --- src/libs/utils/stylehelper.cpp | 5 ++--- src/libs/utils/stylehelper.h | 4 ++-- src/plugins/coreplugin/fancyactionbar.cpp | 6 +++--- src/plugins/coreplugin/fancytabwidget.cpp | 4 ++-- src/plugins/coreplugin/progressmanager/progressbar.cpp | 4 ++-- src/plugins/coreplugin/progressmanager/progressmanager.cpp | 2 +- src/plugins/projectexplorer/buildprogress.cpp | 2 +- src/plugins/scxmleditor/common/dragshapebutton.cpp | 2 +- 8 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/libs/utils/stylehelper.cpp b/src/libs/utils/stylehelper.cpp index e6f520b7d13..de74a999407 100644 --- a/src/libs/utils/stylehelper.cpp +++ b/src/libs/utils/stylehelper.cpp @@ -952,12 +952,11 @@ QFont StyleHelper::UiFont(UiElement element) font.setPointSizeF(font.pointSizeF() * 1.2); font.setBold(true); break; - case UiElementPanelTitle: { + case UiElementCaptionStrong: font.setPointSizeF(panelTitleSize); font.setBold(true); break; - } - case UiElementPanelSubtitle: + case UiElementCaption: font.setPointSizeF(panelTitleSize); break; } diff --git a/src/libs/utils/stylehelper.h b/src/libs/utils/stylehelper.h index 4cda97ff569..8945c455337 100644 --- a/src/libs/utils/stylehelper.h +++ b/src/libs/utils/stylehelper.h @@ -52,8 +52,8 @@ enum UiElement { UiElementH2, UiElementH3, UiElementH4, - UiElementPanelTitle, - UiElementPanelSubtitle, + UiElementCaptionStrong, + UiElementCaption, }; // Height of the project explorer navigation bar diff --git a/src/plugins/coreplugin/fancyactionbar.cpp b/src/plugins/coreplugin/fancyactionbar.cpp index 908e002791c..45b3f475a18 100644 --- a/src/plugins/coreplugin/fancyactionbar.cpp +++ b/src/plugins/coreplugin/fancyactionbar.cpp @@ -181,9 +181,9 @@ void FancyToolButton::paintEvent(QPaintEvent *event) const bool isTitledAction = defaultAction() && defaultAction()->property("titledAction").toBool(); // draw popup texts if (isTitledAction && !m_iconsOnly) { - const QFont normalFont = StyleHelper::UiFont(StyleHelper::UiElementPanelSubtitle); + const QFont normalFont = StyleHelper::UiFont(StyleHelper::UiElementCaption); QRect centerRect = rect(); - const QFont boldFont = StyleHelper::UiFont(StyleHelper::UiElementPanelTitle); + const QFont boldFont = StyleHelper::UiFont(StyleHelper::UiElementCaptionStrong); const QFontMetrics fm(normalFont); const QFontMetrics boldFm(boldFont); const int lineHeight = boldFm.height(); @@ -284,7 +284,7 @@ QSize FancyToolButton::sizeHint() const QSizeF buttonSize = iconSize().expandedTo(QSize(64, 38)); if (defaultAction() && defaultAction()->property("titledAction").toBool()) { - const QFont boldFont = StyleHelper::UiFont(StyleHelper::UiElementPanelTitle); + const QFont boldFont = StyleHelper::UiFont(StyleHelper::UiElementCaptionStrong); const QFontMetrics fm(boldFont); const qreal lineHeight = fm.height(); const int extraHeight = 10 // Spacing between top and projectName diff --git a/src/plugins/coreplugin/fancytabwidget.cpp b/src/plugins/coreplugin/fancytabwidget.cpp index 19b0dfda475..3269b55cbfd 100644 --- a/src/plugins/coreplugin/fancytabwidget.cpp +++ b/src/plugins/coreplugin/fancytabwidget.cpp @@ -68,7 +68,7 @@ QSize FancyTabBar::tabSizeHint(bool minimum) const Core::Constants::MODEBAR_ICONSONLY_BUTTON_SIZE / (minimum ? 3 : 1)}; } - const QFont boldFont = StyleHelper::UiFont(StyleHelper::UiElementPanelTitle); + const QFont boldFont = StyleHelper::UiFont(StyleHelper::UiElementCaptionStrong); const QFontMetrics fm(boldFont); const int spacing = 8; const int width = 60 + spacing + 2; @@ -283,7 +283,7 @@ static void paintIconAndText(QPainter *painter, const QRect &rect, const QIcon &icon, const QString &text, bool enabled, bool selected) { - const QFont boldFont = StyleHelper::UiFont(StyleHelper::UiElementPanelTitle); + const QFont boldFont = StyleHelper::UiFont(StyleHelper::UiElementCaptionStrong); painter->setFont(boldFont); const bool drawIcon = rect.height() > 36; diff --git a/src/plugins/coreplugin/progressmanager/progressbar.cpp b/src/plugins/coreplugin/progressmanager/progressbar.cpp index fa1a3041658..ea25587922e 100644 --- a/src/plugins/coreplugin/progressmanager/progressbar.cpp +++ b/src/plugins/coreplugin/progressmanager/progressbar.cpp @@ -166,7 +166,7 @@ QSize ProgressBar::sizeHint() const int width = 50; int height = PROGRESSBAR_HEIGHT + 5; if (m_titleVisible) { - const QFont font = StyleHelper::UiFont(StyleHelper::UiElementPanelTitle); + const QFont font = StyleHelper::UiFont(StyleHelper::UiElementCaptionStrong); const QFontMetrics fm(font); width = qMax(width, fm.horizontalAdvance(m_title) + 16); height += fm.height() + 5; @@ -213,7 +213,7 @@ void ProgressBar::paintEvent(QPaintEvent *) percent = 1; QPainter p(this); - const QFont fnt = StyleHelper::UiFont(StyleHelper::UiElementPanelTitle); + const QFont fnt = StyleHelper::UiFont(StyleHelper::UiElementCaptionStrong); const QFontMetrics fm(fnt); const int titleHeight = m_titleVisible ? fm.height() + 5 : 4; diff --git a/src/plugins/coreplugin/progressmanager/progressmanager.cpp b/src/plugins/coreplugin/progressmanager/progressmanager.cpp index c7bc22f2a6c..6dceb339bf7 100644 --- a/src/plugins/coreplugin/progressmanager/progressmanager.cpp +++ b/src/plugins/coreplugin/progressmanager/progressmanager.cpp @@ -661,7 +661,7 @@ void ProgressManagerPrivate::updateStatusDetailsWidget() } else if (progress->isSubtitleVisibleInStatusBar() && !progress->subtitle().isEmpty()) { if (!m_statusDetailsLabel) { m_statusDetailsLabel = new QLabel(m_summaryProgressWidget); - const QFont font = StyleHelper::UiFont(StyleHelper::UiElementPanelTitle); + const QFont font = StyleHelper::UiFont(StyleHelper::UiElementCaptionStrong); m_statusDetailsLabel->setFont(font); } m_statusDetailsLabel->setText(progress->subtitle()); diff --git a/src/plugins/projectexplorer/buildprogress.cpp b/src/plugins/projectexplorer/buildprogress.cpp index d6c654ce5cc..7cd9eea59e3 100644 --- a/src/plugins/projectexplorer/buildprogress.cpp +++ b/src/plugins/projectexplorer/buildprogress.cpp @@ -49,7 +49,7 @@ BuildProgress::BuildProgress(TaskWindow *taskWindow, Qt::Orientation orientation warningLayout->addWidget(m_warningIcon); warningLayout->addWidget(m_warningLabel); - const QFont f = Utils::StyleHelper::UiFont(Utils::StyleHelper::UiElementPanelTitle); + const QFont f = Utils::StyleHelper::UiFont(Utils::StyleHelper::UiElementCaptionStrong); m_errorLabel->setFont(f); m_warningLabel->setFont(f); m_errorLabel->setPalette(Utils::StyleHelper::sidebarFontPalette(m_errorLabel->palette())); diff --git a/src/plugins/scxmleditor/common/dragshapebutton.cpp b/src/plugins/scxmleditor/common/dragshapebutton.cpp index 307827cb00e..4a4f0ae86ce 100644 --- a/src/plugins/scxmleditor/common/dragshapebutton.cpp +++ b/src/plugins/scxmleditor/common/dragshapebutton.cpp @@ -20,7 +20,7 @@ DragShapeButton::DragShapeButton(QWidget *parent) setMinimumSize(75, 75); setMaximumSize(75, 75); setIconSize(QSize(45, 45)); - setFont(Utils::StyleHelper::UiFont(Utils::StyleHelper::UiElementPanelSubtitle)); + setFont(Utils::StyleHelper::UiFont(Utils::StyleHelper::UiElementCaption)); } void DragShapeButton::setShapeInfo(int groupIndex, int shapeIndex) From 1da84754dba784d496622a8df9776b9855995d7c Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 17 Nov 2023 11:06:23 +0100 Subject: [PATCH 0246/1546] Utils: Align enum StyleHelper::UiElement with upcoming design system #3 The Qt Creator Design System defines display headings H1 and H2 with a "Titillium Web" font face. This change introduces the "Titillium Web" based as new H1 and H2 and lets the WelcomeScreen code obtain them via StyleHelper::UiFont(). It is supposed to not change the visual appearance. Change-Id: Ia2c5ac14858e574c4ffd31af1ed80ac1781cd970 Reviewed-by: Cristian Adam --- src/libs/utils/stylehelper.cpp | 15 +++++++++++++ src/plugins/coreplugin/iwelcomepage.cpp | 3 ++- src/plugins/coreplugin/welcomepagehelper.cpp | 22 +++---------------- src/plugins/coreplugin/welcomepagehelper.h | 1 - .../projectexplorer/projectwelcomepage.cpp | 6 ++--- src/plugins/welcome/welcomeplugin.cpp | 8 +++---- 6 files changed, 26 insertions(+), 29 deletions(-) diff --git a/src/libs/utils/stylehelper.cpp b/src/libs/utils/stylehelper.cpp index de74a999407..9dcb516e62a 100644 --- a/src/libs/utils/stylehelper.cpp +++ b/src/libs/utils/stylehelper.cpp @@ -933,6 +933,15 @@ QColor StyleHelper::ensureReadableOn(const QColor &background, const QColor &des return foreground; } +static QStringList brandFontFamilies() +{ + const static QStringList families = []{ + const int id = QFontDatabase::addApplicationFont(":/studiofonts/TitilliumWeb-Regular.ttf"); + return id >= 0 ? QFontDatabase::applicationFontFamilies(id) : QStringList(); + }(); + return families; +} + QFont StyleHelper::UiFont(UiElement element) { QFont font; @@ -941,8 +950,14 @@ QFont StyleHelper::UiFont(UiElement element) switch (element) { case UiElementH1: + font.setFamilies(brandFontFamilies()); + font.setPixelSize(30); + font.setWeight(QFont::Light); + font.setWordSpacing(2); break; case UiElementH2: + font.setFamilies(brandFontFamilies()); + font.setPixelSize(16); break; case UiElementH3: font.setPointSizeF(font.pointSizeF() * 1.6); diff --git a/src/plugins/coreplugin/iwelcomepage.cpp b/src/plugins/coreplugin/iwelcomepage.cpp index 9f339110767..e094728dc9c 100644 --- a/src/plugins/coreplugin/iwelcomepage.cpp +++ b/src/plugins/coreplugin/iwelcomepage.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -177,7 +178,7 @@ void WelcomePageButton::setSize(Size size) const int hMargin = size == SizeSmall ? 12 : 26; const int vMargin = size == SizeSmall ? 2 : 4; d->m_layout->setContentsMargins(hMargin, vMargin, hMargin, vMargin); - d->m_label->setFont(size == SizeSmall ? font() : WelcomePageHelpers::brandFont()); + d->m_label->setFont(size == SizeSmall ? font() : StyleHelper::UiFont(StyleHelper::UiElementH2)); } void WelcomePageButton::setWithAccentColor(bool withAccent) diff --git a/src/plugins/coreplugin/welcomepagehelper.cpp b/src/plugins/coreplugin/welcomepagehelper.cpp index d80942f13d4..2a190b547e0 100644 --- a/src/plugins/coreplugin/welcomepagehelper.cpp +++ b/src/plugins/coreplugin/welcomepagehelper.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include #include @@ -46,21 +45,6 @@ static QFont sizedFont(int size, const QWidget *widget) namespace WelcomePageHelpers { -QFont brandFont() -{ - const static QFont f = []{ - const int id = QFontDatabase::addApplicationFont(":/studiofonts/TitilliumWeb-Regular.ttf"); - QFont result; - result.setPixelSize(16); - if (id >= 0) { - const QStringList fontFamilies = QFontDatabase::applicationFontFamilies(id); - result.setFamilies(fontFamilies); - } - return result; - }(); - return f; -} - QWidget *panelBar(QWidget *parent) { auto frame = new QWidget(parent); @@ -83,7 +67,7 @@ SearchBox::SearchBox(QWidget *parent) m_lineEdit = new FancyLineEdit; m_lineEdit->setFiltering(true); m_lineEdit->setFrame(false); - m_lineEdit->setFont(WelcomePageHelpers::brandFont()); + m_lineEdit->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); m_lineEdit->setMinimumHeight(33); m_lineEdit->setAttribute(Qt::WA_MacShowFocusRect, false); @@ -801,7 +785,7 @@ ListModel *SectionedGridView::addSection(const Section §ion, const QListsetContentsMargins(0, ItemGap, 0, 0); - sectionLabel->setFont(Core::WelcomePageHelpers::brandFont()); + sectionLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); auto scrollArea = qobject_cast(widget(0)); auto vbox = qobject_cast(scrollArea->widget()->layout()); @@ -858,7 +842,7 @@ void SectionedGridView::zoomInSection(const Section §ion) noMargin }.emerge(); sectionLabel->setContentsMargins(0, ItemGap, 0, 0); - sectionLabel->setFont(Core::WelcomePageHelpers::brandFont()); + sectionLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); auto gridView = new GridView(zoomedInWidget); gridView->setItemDelegate(m_itemDelegate); diff --git a/src/plugins/coreplugin/welcomepagehelper.h b/src/plugins/coreplugin/welcomepagehelper.h index 1677e1e893a..61d57e448d0 100644 --- a/src/plugins/coreplugin/welcomepagehelper.h +++ b/src/plugins/coreplugin/welcomepagehelper.h @@ -35,7 +35,6 @@ constexpr QSize GridItemImageSize(GridItemWidth - GridItemGap - GridItemGap - 1 // Upper margin + 1 pixel - 67); // Bottom margin (for title + tags) -CORE_EXPORT QFont brandFont(); CORE_EXPORT QWidget *panelBar(QWidget *parent = nullptr); } // namespace WelcomePageHelpers diff --git a/src/plugins/projectexplorer/projectwelcomepage.cpp b/src/plugins/projectexplorer/projectwelcomepage.cpp index 4fb585dee57..e804c7d527e 100644 --- a/src/plugins/projectexplorer/projectwelcomepage.cpp +++ b/src/plugins/projectexplorer/projectwelcomepage.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include @@ -583,11 +583,11 @@ public: manageSessionsButton->setOnClicked([] { SessionManager::showSessionManager(); }); auto sessionsLabel = new QLabel(this); - sessionsLabel->setFont(brandFont()); + sessionsLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); sessionsLabel->setText(Tr::tr("Sessions")); auto recentProjectsLabel = new QLabel(this); - recentProjectsLabel->setFont(brandFont()); + recentProjectsLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); recentProjectsLabel->setText(Tr::tr("Projects")); auto sessionsList = new TreeView(this, "Sessions"); diff --git a/src/plugins/welcome/welcomeplugin.cpp b/src/plugins/welcome/welcomeplugin.cpp index acfa754633c..bfa77cc399b 100644 --- a/src/plugins/welcome/welcomeplugin.cpp +++ b/src/plugins/welcome/welcomeplugin.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -175,10 +176,7 @@ public: hbox->addSpacing(16); - QFont welcomeFont = brandFont(); - welcomeFont.setPixelSize(30); - welcomeFont.setWeight(QFont::Light); - welcomeFont.setWordSpacing(2); + const QFont welcomeFont = StyleHelper::UiFont(StyleHelper::UiElementH1); auto welcomeLabel = new QLabel("Welcome to"); welcomeLabel->setFont(welcomeFont); @@ -263,7 +261,7 @@ public: vbox->addItem(newVBox); auto newLabel = new QLabel(Tr::tr("New to Qt?"), mainWidget); - newLabel->setFont(brandFont()); + newLabel->setFont(StyleHelper::UiFont(StyleHelper::UiElementH2)); newLabel->setAlignment(Qt::AlignHCenter); newVBox->addWidget(newLabel); From 89d9a481e20d863b0e55c1c4864b0de9ec59eea1 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 17 Nov 2023 12:13:10 +0100 Subject: [PATCH 0247/1546] Revert "QmlProject: Fix crash" This reverts commit 4d55d6be189a70ab30d1a0089c2229992743520a, which broke all project loading. The crash was properly fixed elsewhere. Change-Id: I49f42dce1d7f69d6a1c3c769dc6a1399f26650d5 Reviewed-by: hjk --- src/plugins/projectexplorer/project.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index d75f21dd767..c0e245baf1c 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -852,8 +852,6 @@ void Project::createTargetFromMap(const Store &map, int index) "kit \"%2\" with id %3, which does not exist anymore. The new kit \"%4\" was " "created in its place, in an attempt not to lose custom project settings.") .arg(displayName(), formerKitName, id.toString(), k->displayName()))); - } else { - return; } auto t = std::make_unique(this, k, Target::_constructor_tag{}); From 07f5c7638d2849fccfb88ddfc4e2ecfc05e5b415 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 16 Nov 2023 23:40:22 +0100 Subject: [PATCH 0248/1546] TaskTree: Hide more API of GroupItem into protected section Rename TaskXxxHandlers into InterfaceXxxHandlers. Rename CustomTask::[Setup/Done]Function into Task[Setup/Done]Handler to conform with Group[Setup/Done]Handler. Fix the CustomTask::TaskSetupHandler type. Change-Id: I0c69fc75622eb8324278f713db22a6de314d44ef Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.h | 38 ++++++++++++++------------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 5fa2d1e89da..c320413ad5c 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -148,21 +148,23 @@ private: class TASKING_EXPORT GroupItem { public: - // Internal, provided by QTC_DECLARE_CUSTOM_TASK - using TaskCreateHandler = std::function; - // Called prior to task start, just after createHandler - using TaskSetupHandler = std::function; - // Called on task done, just before deleteLater - using TaskDoneHandler = std::function; // Called when group entered, after group's storages are created using GroupSetupHandler = std::function; // Called when group done, before group's storages are deleted using GroupDoneHandler = std::function; +protected: + // Internal, provided by CustomTask + using InterfaceCreateHandler = std::function; + // Called prior to task start, just after createHandler + using InterfaceSetupHandler = std::function; + // Called on task done, just before deleteLater + using InterfaceDoneHandler = std::function; + struct TaskHandler { - TaskCreateHandler m_createHandler; - TaskSetupHandler m_setupHandler = {}; - TaskDoneHandler m_doneHandler = {}; + InterfaceCreateHandler m_createHandler; + InterfaceSetupHandler m_setupHandler = {}; + InterfaceDoneHandler m_doneHandler = {}; CallDoneIf m_callDoneIf = CallDoneIf::SuccessOrError; }; @@ -178,7 +180,6 @@ public: std::optional m_workflowPolicy = {}; }; -protected: enum class Type { List, Group, @@ -220,6 +221,7 @@ protected: private: friend class TaskContainer; friend class TaskNode; + friend class TaskTreePrivate; Type m_type = Type::Group; QList m_children; GroupData m_groupData; @@ -385,12 +387,12 @@ public: static_assert(std::is_base_of_v, Adapter>, "The Adapter type for the CustomTask needs to be derived from " "TaskAdapter."); - using SetupFunction = std::function; - using DoneFunction = std::function; + using TaskSetupHandler = std::function; + using TaskDoneHandler = std::function; static Adapter *createAdapter() { return new Adapter; } - template - CustomTask(SetupHandler &&setup = SetupFunction(), DoneHandler &&done = DoneFunction(), + template + CustomTask(SetupHandler &&setup = TaskSetupHandler(), DoneHandler &&done = TaskDoneHandler(), CallDoneIf callDoneIf = CallDoneIf::SuccessOrError) : GroupItem({&createAdapter, wrapSetup(std::forward(setup)), wrapDone(std::forward(done)), callDoneIf}) @@ -404,8 +406,8 @@ public: private: template - static GroupItem::TaskSetupHandler wrapSetup(Handler &&handler) { - if constexpr (std::is_same_v) + static InterfaceSetupHandler wrapSetup(Handler &&handler) { + if constexpr (std::is_same_v) return {}; // When user passed {} for the setup handler. // S, V stands for: [S]etupResult, [V]oid static constexpr bool isS = isInvocable(); @@ -423,8 +425,8 @@ private: }; template - static GroupItem::TaskDoneHandler wrapDone(Handler &&handler) { - if constexpr (std::is_same_v) + static InterfaceDoneHandler wrapDone(Handler &&handler) { + if constexpr (std::is_same_v) return {}; // When user passed {} for the done handler. // D, V, T, W stands for: [D]oneResult, [V]oid, [T]ask, done[W]ith static constexpr bool isDTW = isInvocable(); From 4101260f41d0b6190ff6b3d2c2182f298b1717de Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Fri, 27 Oct 2023 08:02:13 +0200 Subject: [PATCH 0249/1546] Utils: Update mime type for linguist files Use new mimetype used inside freedesktop's definition. The old one is still used internally as alias. Change-Id: If8405c109a1bfb326db84f480d35bc62625358a3 Reviewed-by: Eike Ziller --- src/libs/utils/mimeconstants.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/utils/mimeconstants.h b/src/libs/utils/mimeconstants.h index 2e9e393661c..949c76938d7 100644 --- a/src/libs/utils/mimeconstants.h +++ b/src/libs/utils/mimeconstants.h @@ -37,7 +37,7 @@ const char GLSL_MIMETYPE_FRAG_ES[] = "text/x-glsl-es-frag"; const char GLSL_MIMETYPE_VERT[] = "text/x-glsl-vert"; const char GLSL_MIMETYPE_VERT_ES[] = "text/x-glsl-es-vert"; const char JAVA_MIMETYPE[] = "text/x-java"; -const char LINGUIST_MIMETYPE[] = "text/vnd.trolltech.linguist"; +const char LINGUIST_MIMETYPE[] = "text/vnd.qt.linguist"; const char MAKEFILE_MIMETYPE[] = "text/x-makefile"; const char MOC_MIMETYPE[] = "text/x-moc"; const char OBJECTIVE_CPP_SOURCE_MIMETYPE[] = "text/x-objc++src"; From fc1325d6c92cb7a84f8b75c2b13cdc79872cfd2e Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 09:21:04 +0100 Subject: [PATCH 0250/1546] BareMetal: Use new setup approach for toolchain factories Change-Id: Ic91ccab925f054d80fbfa8bc018b3e86d207b186 Reviewed-by: Jarek Kobus --- src/plugins/baremetal/baremetalplugin.cpp | 15 +++-------- src/plugins/baremetal/iarewtoolchain.cpp | 32 +++++++++++++++++------ src/plugins/baremetal/iarewtoolchain.h | 19 +------------- src/plugins/baremetal/keiltoolchain.cpp | 31 +++++++++++++++++----- src/plugins/baremetal/keiltoolchain.h | 17 +----------- src/plugins/baremetal/sdcctoolchain.cpp | 28 +++++++++++++++----- src/plugins/baremetal/sdcctoolchain.h | 17 +----------- 7 files changed, 77 insertions(+), 82 deletions(-) diff --git a/src/plugins/baremetal/baremetalplugin.cpp b/src/plugins/baremetal/baremetalplugin.cpp index b8383c65b9d..b1fdc14aed1 100644 --- a/src/plugins/baremetal/baremetalplugin.cpp +++ b/src/plugins/baremetal/baremetalplugin.cpp @@ -16,15 +16,7 @@ #include "keiltoolchain.h" #include "sdcctoolchain.h" -#include -#include -#include -#include -#include -#include - #include -#include using namespace ProjectExplorer; @@ -46,9 +38,6 @@ public: class BareMetalPluginPrivate { public: - IarToolChainFactory iarToolChainFactory; - KeilToolChainFactory keilToolChainFactory; - SdccToolChainFactory sdccToolChainFactory; BareMetalDeviceFactory deviceFactory; BareMetalRunConfigurationFactory runConfigurationFactory; BareMetalCustomRunConfigurationFactory customRunConfigurationFactory; @@ -67,6 +56,10 @@ BareMetalPlugin::~BareMetalPlugin() void BareMetalPlugin::initialize() { d = new BareMetalPluginPrivate; + + setupIarToolChain(); + setupKeilToolChain(); + setupSdccToolChain(); } void BareMetalPlugin::extensionsInitialized() diff --git a/src/plugins/baremetal/iarewtoolchain.cpp b/src/plugins/baremetal/iarewtoolchain.cpp index 262516b4b35..a281d4eb528 100644 --- a/src/plugins/baremetal/iarewtoolchain.cpp +++ b/src/plugins/baremetal/iarewtoolchain.cpp @@ -405,17 +405,33 @@ bool IarToolChain::operator==(const ToolChain &other) const } - // IarToolChainFactory -IarToolChainFactory::IarToolChainFactory() +class IarToolChainFactory final : public ToolChainFactory { - setDisplayName(Tr::tr("IAREW")); - setSupportedToolChainType(Constants::IAREW_TOOLCHAIN_TYPEID); - setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID, - ProjectExplorer::Constants::CXX_LANGUAGE_ID}); - setToolchainConstructor([] { return new IarToolChain; }); - setUserCreatable(true); +public: + IarToolChainFactory() + { + setDisplayName(Tr::tr("IAREW")); + setSupportedToolChainType(Constants::IAREW_TOOLCHAIN_TYPEID); + setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID, + ProjectExplorer::Constants::CXX_LANGUAGE_ID}); + setToolchainConstructor([] { return new IarToolChain; }); + setUserCreatable(true); + } + + Toolchains autoDetect(const ToolchainDetector &detector) const final; + Toolchains detectForImport(const ToolChainDescription &tcd) const final; + +private: + Toolchains autoDetectToolchains(const Candidates &candidates, + const Toolchains &alreadyKnown) const; + Toolchains autoDetectToolchain(const Candidate &candidate, Id languageId) const; +}; + +void setupIarToolChain() +{ + static IarToolChainFactory theIarToolChainFactory; } Toolchains IarToolChainFactory::autoDetect(const ToolchainDetector &detector) const diff --git a/src/plugins/baremetal/iarewtoolchain.h b/src/plugins/baremetal/iarewtoolchain.h index 1b67e9e051f..9fd6e516cd1 100644 --- a/src/plugins/baremetal/iarewtoolchain.h +++ b/src/plugins/baremetal/iarewtoolchain.h @@ -3,25 +3,8 @@ #pragma once -#include - namespace BareMetal::Internal { -class IarToolChainFactory final : public ProjectExplorer::ToolChainFactory -{ -public: - IarToolChainFactory(); - - ProjectExplorer::Toolchains autoDetect( - const ProjectExplorer::ToolchainDetector &detector) const final; - ProjectExplorer::Toolchains detectForImport( - const ProjectExplorer::ToolChainDescription &tcd) const final; - -private: - ProjectExplorer::Toolchains autoDetectToolchains(const Candidates &candidates, - const ProjectExplorer::Toolchains &alreadyKnown) const; - ProjectExplorer::Toolchains autoDetectToolchain( - const Candidate &candidate, Utils::Id languageId) const; -}; +void setupIarToolChain(); } // BareMetal::Internal diff --git a/src/plugins/baremetal/keiltoolchain.cpp b/src/plugins/baremetal/keiltoolchain.cpp index d39dc9f03b0..f6a097f0a41 100644 --- a/src/plugins/baremetal/keiltoolchain.cpp +++ b/src/plugins/baremetal/keiltoolchain.cpp @@ -538,14 +538,31 @@ QStringList KeilToolChain::extraCodeModelFlags() const // KeilToolchainFactory -KeilToolChainFactory::KeilToolChainFactory() +class KeilToolChainFactory final : public ToolChainFactory { - setDisplayName(Tr::tr("KEIL")); - setSupportedToolChainType(Constants::KEIL_TOOLCHAIN_TYPEID); - setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID, - ProjectExplorer::Constants::CXX_LANGUAGE_ID}); - setToolchainConstructor([] { return new KeilToolChain; }); - setUserCreatable(true); +public: + KeilToolChainFactory() + { + setDisplayName(Tr::tr("KEIL")); + setSupportedToolChainType(Constants::KEIL_TOOLCHAIN_TYPEID); + setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID, + ProjectExplorer::Constants::CXX_LANGUAGE_ID}); + setToolchainConstructor([] { return new KeilToolChain; }); + setUserCreatable(true); + } + + Toolchains autoDetect(const ToolchainDetector &detector) const final; + +private: + Toolchains autoDetectToolchains(const Candidates &candidates, + const Toolchains &alreadyKnown) const; + Toolchains autoDetectToolchain( + const Candidate &candidate, Utils::Id language) const; +}; + +void setupKeilToolChain() +{ + static KeilToolChainFactory theKeilToolChainFactory; } // Parse the 'tools.ini' file to fetch a toolchain version. diff --git a/src/plugins/baremetal/keiltoolchain.h b/src/plugins/baremetal/keiltoolchain.h index 6f897369095..652fe6141fb 100644 --- a/src/plugins/baremetal/keiltoolchain.h +++ b/src/plugins/baremetal/keiltoolchain.h @@ -3,23 +3,8 @@ #pragma once -#include - namespace BareMetal::Internal { -class KeilToolChainFactory final : public ProjectExplorer::ToolChainFactory -{ -public: - KeilToolChainFactory(); - - ProjectExplorer::Toolchains autoDetect( - const ProjectExplorer::ToolchainDetector &detector) const final; - -private: - ProjectExplorer::Toolchains autoDetectToolchains(const Candidates &candidates, - const ProjectExplorer::Toolchains &alreadyKnown) const; - ProjectExplorer::Toolchains autoDetectToolchain( - const Candidate &candidate, Utils::Id language) const; -}; +void setupKeilToolChain(); } // BareMetal::Internal diff --git a/src/plugins/baremetal/sdcctoolchain.cpp b/src/plugins/baremetal/sdcctoolchain.cpp index e57dd9fafe2..411b2317c5f 100644 --- a/src/plugins/baremetal/sdcctoolchain.cpp +++ b/src/plugins/baremetal/sdcctoolchain.cpp @@ -300,13 +300,29 @@ bool SdccToolChain::operator==(const ToolChain &other) const // SdccToolChainFactory -SdccToolChainFactory::SdccToolChainFactory() +class SdccToolChainFactory final : public ToolChainFactory { - setDisplayName(Tr::tr("SDCC")); - setSupportedToolChainType(Constants::SDCC_TOOLCHAIN_TYPEID); - setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID}); - setToolchainConstructor([] { return new SdccToolChain; }); - setUserCreatable(true); +public: + SdccToolChainFactory() + { + setDisplayName(Tr::tr("SDCC")); + setSupportedToolChainType(Constants::SDCC_TOOLCHAIN_TYPEID); + setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID}); + setToolchainConstructor([] { return new SdccToolChain; }); + setUserCreatable(true); + } + + Toolchains autoDetect(const ToolchainDetector &detector) const final; + +private: + Toolchains autoDetectToolchains(const Candidates &candidates, + const Toolchains &alreadyKnown) const; + Toolchains autoDetectToolchain(const Candidate &candidate, Id language) const; +}; + +void setupSdccToolChain() +{ + static SdccToolChainFactory theSdccToolChainFactory; } Toolchains SdccToolChainFactory::autoDetect(const ToolchainDetector &detector) const diff --git a/src/plugins/baremetal/sdcctoolchain.h b/src/plugins/baremetal/sdcctoolchain.h index 972eee000d5..431573afe48 100644 --- a/src/plugins/baremetal/sdcctoolchain.h +++ b/src/plugins/baremetal/sdcctoolchain.h @@ -3,23 +3,8 @@ #pragma once -#include - namespace BareMetal::Internal { -class SdccToolChainFactory final : public ProjectExplorer::ToolChainFactory -{ -public: - SdccToolChainFactory(); - - ProjectExplorer::Toolchains autoDetect( - const ProjectExplorer::ToolchainDetector &detector) const final; - -private: - ProjectExplorer::Toolchains autoDetectToolchains(const Candidates &candidates, - const ProjectExplorer::Toolchains &alreadyKnown) const; - ProjectExplorer::Toolchains autoDetectToolchain( - const Candidate &candidate, Utils::Id language) const; -}; +void setupSdccToolChain(); } // BareMetal::Internal From 7c7abec04fac951835f55fc6b6dee04283d214a8 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 09:48:11 +0100 Subject: [PATCH 0251/1546] BareMetal: Use new setup scheme for various factories Change-Id: I62f17efb8241acbfa954c07b0fa6f088990be7a2 Reviewed-by: Jarek Kobus --- .../baremetal/baremetaldebugsupport.cpp | 23 ++++++--- src/plugins/baremetal/baremetaldebugsupport.h | 8 +-- src/plugins/baremetal/baremetaldevice.cpp | 35 ++++++++----- src/plugins/baremetal/baremetaldevice.h | 15 +----- src/plugins/baremetal/baremetalplugin.cpp | 25 ++-------- .../baremetal/baremetalrunconfiguration.cpp | 49 +++++++++++++++---- .../baremetal/baremetalrunconfiguration.h | 16 +----- 7 files changed, 88 insertions(+), 83 deletions(-) diff --git a/src/plugins/baremetal/baremetaldebugsupport.cpp b/src/plugins/baremetal/baremetaldebugsupport.cpp index 18aad498535..6593797b90b 100644 --- a/src/plugins/baremetal/baremetaldebugsupport.cpp +++ b/src/plugins/baremetal/baremetaldebugsupport.cpp @@ -36,7 +36,7 @@ namespace BareMetal::Internal { class BareMetalDebugSupport final : public Debugger::DebuggerRunTool { public: - explicit BareMetalDebugSupport(ProjectExplorer::RunControl *runControl) + explicit BareMetalDebugSupport(RunControl *runControl) : Debugger::DebuggerRunTool(runControl) { const auto dev = qSharedPointerCast(device()); @@ -73,13 +73,22 @@ private: } }; -BareMetalDebugSupportFactory::BareMetalDebugSupportFactory() +class BareMetalDebugSupportFactory final : public RunWorkerFactory { - setProduct(); - addSupportedRunMode(ProjectExplorer::Constants::NORMAL_RUN_MODE); - addSupportedRunMode(ProjectExplorer::Constants::DEBUG_RUN_MODE); - addSupportedRunConfig(BareMetal::Constants::BAREMETAL_RUNCONFIG_ID); - addSupportedRunConfig(BareMetal::Constants::BAREMETAL_CUSTOMRUNCONFIG_ID); +public: + BareMetalDebugSupportFactory() + { + setProduct(); + addSupportedRunMode(ProjectExplorer::Constants::NORMAL_RUN_MODE); + addSupportedRunMode(ProjectExplorer::Constants::DEBUG_RUN_MODE); + addSupportedRunConfig(BareMetal::Constants::BAREMETAL_RUNCONFIG_ID); + addSupportedRunConfig(BareMetal::Constants::BAREMETAL_CUSTOMRUNCONFIG_ID); + } +}; + +void setupBareMetalDebugSupport() +{ + static BareMetalDebugSupportFactory theBareMetalDebugSupportFactory; } } // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetaldebugsupport.h b/src/plugins/baremetal/baremetaldebugsupport.h index ca16c1ab7ec..ff009c83c3c 100644 --- a/src/plugins/baremetal/baremetaldebugsupport.h +++ b/src/plugins/baremetal/baremetaldebugsupport.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace BareMetal::Internal { -class BareMetalDebugSupportFactory final : public ProjectExplorer::RunWorkerFactory -{ -public: - BareMetalDebugSupportFactory(); -}; +void setupBareMetalDebugSupport(); } // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetaldevice.cpp b/src/plugins/baremetal/baremetaldevice.cpp index e0d271f2591..eebdb949823 100644 --- a/src/plugins/baremetal/baremetaldevice.cpp +++ b/src/plugins/baremetal/baremetaldevice.cpp @@ -11,6 +11,8 @@ #include "debugserverprovidermanager.h" #include "idebugserverprovider.h" +#include + #include using namespace ProjectExplorer; @@ -93,19 +95,28 @@ IDeviceWidget *BareMetalDevice::createWidget() // Factory -BareMetalDeviceFactory::BareMetalDeviceFactory() - : IDeviceFactory(Constants::BareMetalOsType) +class BareMetalDeviceFactory final : public ProjectExplorer::IDeviceFactory { - setDisplayName(Tr::tr("Bare Metal Device")); - setCombinedIcon(":/baremetal/images/baremetaldevicesmall.png", - ":/baremetal/images/baremetaldevice.png"); - setConstructionFunction(&BareMetalDevice::create); - setCreator([] { - BareMetalDeviceConfigurationWizard wizard; - if (wizard.exec() != QDialog::Accepted) - return IDevice::Ptr(); - return wizard.device(); - }); +public: + BareMetalDeviceFactory() + : IDeviceFactory(Constants::BareMetalOsType) + { + setDisplayName(Tr::tr("Bare Metal Device")); + setCombinedIcon(":/baremetal/images/baremetaldevicesmall.png", + ":/baremetal/images/baremetaldevice.png"); + setConstructionFunction(&BareMetalDevice::create); + setCreator([] { + BareMetalDeviceConfigurationWizard wizard; + if (wizard.exec() != QDialog::Accepted) + return IDevice::Ptr(); + return wizard.device(); + }); + } +}; + +void setupBareMetalDevice() +{ + static BareMetalDeviceFactory theBareMetalDeviceFactory; } } // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetaldevice.h b/src/plugins/baremetal/baremetaldevice.h index b8aa72e12be..fdf6cb193c2 100644 --- a/src/plugins/baremetal/baremetaldevice.h +++ b/src/plugins/baremetal/baremetaldevice.h @@ -5,14 +5,9 @@ #pragma once #include -#include namespace BareMetal::Internal { -class IDebugServerProvider; - -// BareMetalDevice - class BareMetalDevice final : public ProjectExplorer::IDevice { public: @@ -28,7 +23,7 @@ public: QString debugServerProviderId() const; void setDebugServerProviderId(const QString &id); - void unregisterDebugServerProvider(IDebugServerProvider *provider); + void unregisterDebugServerProvider(class IDebugServerProvider *provider); protected: void fromMap(const Utils::Store &map) final; @@ -39,12 +34,6 @@ private: QString m_debugServerProviderId; }; -// BareMetalDeviceFactory - -class BareMetalDeviceFactory final : public ProjectExplorer::IDeviceFactory -{ -public: - BareMetalDeviceFactory(); -}; +void setupBareMetalDevice(); } // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetalplugin.cpp b/src/plugins/baremetal/baremetalplugin.cpp index b1fdc14aed1..09e17fcd6bc 100644 --- a/src/plugins/baremetal/baremetalplugin.cpp +++ b/src/plugins/baremetal/baremetalplugin.cpp @@ -16,34 +16,14 @@ #include "keiltoolchain.h" #include "sdcctoolchain.h" -#include - -using namespace ProjectExplorer; - namespace BareMetal::Internal { -class BareMetalDeployConfigurationFactory : public DeployConfigurationFactory -{ -public: - BareMetalDeployConfigurationFactory() - { - setConfigBaseId("BareMetal.DeployConfiguration"); - setDefaultDisplayName(Tr::tr("Deploy to BareMetal Device")); - addSupportedTargetDeviceType(Constants::BareMetalOsType); - } -}; - // BareMetalPluginPrivate class BareMetalPluginPrivate { public: - BareMetalDeviceFactory deviceFactory; - BareMetalRunConfigurationFactory runConfigurationFactory; - BareMetalCustomRunConfigurationFactory customRunConfigurationFactory; DebugServerProviderManager debugServerProviderManager; - BareMetalDeployConfigurationFactory deployConfigurationFactory; - BareMetalDebugSupportFactory runWorkerFactory; }; // BareMetalPlugin @@ -57,9 +37,14 @@ void BareMetalPlugin::initialize() { d = new BareMetalPluginPrivate; + setupBareMetalDevice(); + setupIarToolChain(); setupKeilToolChain(); setupSdccToolChain(); + + setupBareMetalDeployAndRunConfigurations(); + setupBareMetalDebugSupport(); } void BareMetalPlugin::extensionsInitialized() diff --git a/src/plugins/baremetal/baremetalrunconfiguration.cpp b/src/plugins/baremetal/baremetalrunconfiguration.cpp index 8b805732974..b057ff90d82 100644 --- a/src/plugins/baremetal/baremetalrunconfiguration.cpp +++ b/src/plugins/baremetal/baremetalrunconfiguration.cpp @@ -8,7 +8,9 @@ #include #include +#include #include +#include #include #include @@ -83,22 +85,51 @@ public: }; +// BareMetalDeployConfigurationFactory + +class BareMetalDeployConfigurationFactory : public DeployConfigurationFactory +{ +public: + BareMetalDeployConfigurationFactory() + { + setConfigBaseId("BareMetal.DeployConfiguration"); + setDefaultDisplayName(Tr::tr("Deploy to BareMetal Device")); + addSupportedTargetDeviceType(Constants::BareMetalOsType); + } +}; + // BareMetalRunConfigurationFactory -BareMetalRunConfigurationFactory::BareMetalRunConfigurationFactory() +class BareMetalRunConfigurationFactory final : public RunConfigurationFactory { - registerRunConfiguration(Constants::BAREMETAL_RUNCONFIG_ID); - setDecorateDisplayNames(true); - addSupportedTargetDeviceType(BareMetal::Constants::BareMetalOsType); -} +public: + BareMetalRunConfigurationFactory() + { + registerRunConfiguration(Constants::BAREMETAL_RUNCONFIG_ID); + setDecorateDisplayNames(true); + addSupportedTargetDeviceType(BareMetal::Constants::BareMetalOsType); + } +}; // BaseMetalCustomRunConfigurationFactory -BareMetalCustomRunConfigurationFactory::BareMetalCustomRunConfigurationFactory() - : FixedRunConfigurationFactory(Tr::tr("Custom Executable"), true) +class BareMetalCustomRunConfigurationFactory final : public FixedRunConfigurationFactory { - registerRunConfiguration(Constants::BAREMETAL_CUSTOMRUNCONFIG_ID); - addSupportedTargetDeviceType(BareMetal::Constants::BareMetalOsType); +public: + BareMetalCustomRunConfigurationFactory() + : FixedRunConfigurationFactory(Tr::tr("Custom Executable"), true) + { + registerRunConfiguration(Constants::BAREMETAL_CUSTOMRUNCONFIG_ID); + addSupportedTargetDeviceType(BareMetal::Constants::BareMetalOsType); + } +}; + + +void setupBareMetalDeployAndRunConfigurations() +{ + static BareMetalDeployConfigurationFactory theBareMetalDeployConfigurationFactory; + static BareMetalRunConfigurationFactory theBareMetalRunConfigurationFactory; + static BareMetalCustomRunConfigurationFactory theBareMetalCustomRunConfigurationFactory; } } // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetalrunconfiguration.h b/src/plugins/baremetal/baremetalrunconfiguration.h index 03277fe0686..f96e622195b 100644 --- a/src/plugins/baremetal/baremetalrunconfiguration.h +++ b/src/plugins/baremetal/baremetalrunconfiguration.h @@ -3,22 +3,8 @@ #pragma once -#include - namespace BareMetal::Internal { -class BareMetalRunConfigurationFactory final - : public ProjectExplorer::RunConfigurationFactory -{ -public: - BareMetalRunConfigurationFactory(); -}; - -class BareMetalCustomRunConfigurationFactory final - : public ProjectExplorer::FixedRunConfigurationFactory -{ -public: - BareMetalCustomRunConfigurationFactory(); -}; +void setupBareMetalDeployAndRunConfigurations(); } // BareMetal::Internal From c4c561556d9ac13ff206c988a1f7776f140ef975 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 10:19:48 +0100 Subject: [PATCH 0252/1546] BareMetal: Move DebugServerProviderManager closer to new setup system Change-Id: Ic8029b0436d4c0e86e0f707632139a2074b296eb Reviewed-by: Jarek Kobus --- src/plugins/baremetal/baremetalplugin.cpp | 19 +------------------ src/plugins/baremetal/baremetalplugin.h | 4 ---- .../baremetal/debugserverprovidermanager.cpp | 17 +++++++++++++---- .../baremetal/debugserverprovidermanager.h | 9 ++++----- 4 files changed, 18 insertions(+), 31 deletions(-) diff --git a/src/plugins/baremetal/baremetalplugin.cpp b/src/plugins/baremetal/baremetalplugin.cpp index 09e17fcd6bc..0f551623185 100644 --- a/src/plugins/baremetal/baremetalplugin.cpp +++ b/src/plugins/baremetal/baremetalplugin.cpp @@ -4,11 +4,9 @@ #include "baremetalplugin.h" -#include "baremetalconstants.h" #include "baremetaldebugsupport.h" #include "baremetaldevice.h" #include "baremetalrunconfiguration.h" -#include "baremetaltr.h" #include "debugserverprovidermanager.h" @@ -18,25 +16,10 @@ namespace BareMetal::Internal { -// BareMetalPluginPrivate - -class BareMetalPluginPrivate -{ -public: - DebugServerProviderManager debugServerProviderManager; -}; - // BareMetalPlugin -BareMetalPlugin::~BareMetalPlugin() -{ - delete d; -} - void BareMetalPlugin::initialize() { - d = new BareMetalPluginPrivate; - setupBareMetalDevice(); setupIarToolChain(); @@ -49,7 +32,7 @@ void BareMetalPlugin::initialize() void BareMetalPlugin::extensionsInitialized() { - DebugServerProviderManager::instance()->restoreProviders(); + setupDebugServerProviderManager(this); } } // BareMetal::Internal diff --git a/src/plugins/baremetal/baremetalplugin.h b/src/plugins/baremetal/baremetalplugin.h index cbad40df5c6..b529256b258 100644 --- a/src/plugins/baremetal/baremetalplugin.h +++ b/src/plugins/baremetal/baremetalplugin.h @@ -13,13 +13,9 @@ class BareMetalPlugin final : public ExtensionSystem::IPlugin Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "BareMetal.json") - ~BareMetalPlugin() final; - void initialize() final; void extensionsInitialized() final; - class BareMetalPluginPrivate *d = nullptr; - #ifdef WITH_TESTS private slots: void testIarOutputParsers_data(); diff --git a/src/plugins/baremetal/debugserverprovidermanager.cpp b/src/plugins/baremetal/debugserverprovidermanager.cpp index e7afc2ef10d..b32006d2c45 100644 --- a/src/plugins/baremetal/debugserverprovidermanager.cpp +++ b/src/plugins/baremetal/debugserverprovidermanager.cpp @@ -33,8 +33,6 @@ const char countKeyC[] = "DebugServerProvider.Count"; const char fileVersionKeyC[] = "Version"; const char fileNameKeyC[] = "debugserverproviders.xml"; -static DebugServerProviderManager *m_instance = nullptr; - // DebugServerProviderManager DebugServerProviderManager::DebugServerProviderManager() @@ -48,7 +46,6 @@ DebugServerProviderManager::DebugServerProviderManager() new StLinkUvscServerProviderFactory, new JLinkUvscServerProviderFactory}) { - m_instance = this; m_writer = new Utils::PersistentSettingsWriter( m_configFile, "QtCreatorDebugServerProviders"); @@ -69,14 +66,26 @@ DebugServerProviderManager::~DebugServerProviderManager() m_providers.clear(); qDeleteAll(m_factories); delete m_writer; - m_instance = nullptr; } +static DebugServerProviderManager *m_instance = nullptr; + DebugServerProviderManager *DebugServerProviderManager::instance() { + if (!m_instance) { + m_instance = new DebugServerProviderManager; + m_instance->restoreProviders(); + } + return m_instance; } +void setupDebugServerProviderManager(QObject *guard) +{ + DebugServerProviderManager::instance(); // force creation + m_instance->setParent(guard); +} + void DebugServerProviderManager::restoreProviders() { PersistentSettingsReader reader; diff --git a/src/plugins/baremetal/debugserverprovidermanager.h b/src/plugins/baremetal/debugserverprovidermanager.h index 08a9d3b51d6..87833a507fb 100644 --- a/src/plugins/baremetal/debugserverprovidermanager.h +++ b/src/plugins/baremetal/debugserverprovidermanager.h @@ -13,7 +13,6 @@ namespace Utils { class PersistentSettingsWriter; } namespace BareMetal::Internal { class BareMetalPlugin; -class BareMetalPluginPrivate; class IDebugServerProvider; class IDebugServerProviderFactory; @@ -25,7 +24,6 @@ class DebugServerProviderManager final : public QObject public: static DebugServerProviderManager *instance(); - ~DebugServerProviderManager() final; static QList providers(); static QList factories(); @@ -42,9 +40,10 @@ signals: void providersLoaded(); private: - void saveProviders(); DebugServerProviderManager(); + ~DebugServerProviderManager() final; + void saveProviders(); void restoreProviders(); static void notifyAboutUpdate(IDebugServerProvider *provider); @@ -53,9 +52,9 @@ private: const Utils::FilePath m_configFile; const QList m_factories; - friend class BareMetalPlugin; // for restoreProviders - friend class BareMetalPluginPrivate; // for constructor friend class IDebugServerProvider; }; +void setupDebugServerProviderManager(QObject *guard); + } // BareMetal::Internal From 15e499df069736341238778756b5479d91818fe5 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 11:19:40 +0100 Subject: [PATCH 0253/1546] BareMetal: Dissolve baremetalplugin.h Split test so they can be closer to the implementation, move rest to plugin.cpp. Change-Id: I30310f5b2658ac669d219c2978c6a3d6c9d8b107 Reviewed-by: Jarek Kobus --- src/plugins/baremetal/CMakeLists.txt | 2 +- src/plugins/baremetal/baremetal.qbs | 2 +- src/plugins/baremetal/baremetalplugin.cpp | 47 +++++++++++++++-------- src/plugins/baremetal/baremetalplugin.h | 30 --------------- src/plugins/baremetal/iarewparser.cpp | 11 ++---- src/plugins/baremetal/iarewparser.h | 11 ++++++ src/plugins/baremetal/keilparser.cpp | 6 +-- src/plugins/baremetal/keilparser.h | 11 ++++++ src/plugins/baremetal/sdccparser.cpp | 5 +-- src/plugins/baremetal/sdccparser.h | 11 ++++++ 10 files changed, 75 insertions(+), 61 deletions(-) delete mode 100644 src/plugins/baremetal/baremetalplugin.h diff --git a/src/plugins/baremetal/CMakeLists.txt b/src/plugins/baremetal/CMakeLists.txt index 7a25aa19598..71889e2eb60 100644 --- a/src/plugins/baremetal/CMakeLists.txt +++ b/src/plugins/baremetal/CMakeLists.txt @@ -8,7 +8,7 @@ add_qtc_plugin(BareMetal baremetaldeviceconfigurationwidget.cpp baremetaldeviceconfigurationwidget.h baremetaldeviceconfigurationwizard.cpp baremetaldeviceconfigurationwizard.h baremetaldeviceconfigurationwizardpages.cpp baremetaldeviceconfigurationwizardpages.h - baremetalplugin.cpp baremetalplugin.h + baremetalplugin.cpp baremetalrunconfiguration.cpp baremetalrunconfiguration.h baremetaltr.h debugserverproviderchooser.cpp debugserverproviderchooser.h diff --git a/src/plugins/baremetal/baremetal.qbs b/src/plugins/baremetal/baremetal.qbs index d45090def37..d76c3d32e66 100644 --- a/src/plugins/baremetal/baremetal.qbs +++ b/src/plugins/baremetal/baremetal.qbs @@ -22,7 +22,7 @@ QtcPlugin { "baremetaldeviceconfigurationwidget.cpp", "baremetaldeviceconfigurationwidget.h", "baremetaldeviceconfigurationwizard.cpp", "baremetaldeviceconfigurationwizard.h", "baremetaldeviceconfigurationwizardpages.cpp", "baremetaldeviceconfigurationwizardpages.h", - "baremetalplugin.cpp", "baremetalplugin.h", + "baremetalplugin.cpp", "baremetalrunconfiguration.cpp", "baremetalrunconfiguration.h", "baremetaltr.h", "debugserverproviderchooser.cpp", "debugserverproviderchooser.h", diff --git a/src/plugins/baremetal/baremetalplugin.cpp b/src/plugins/baremetal/baremetalplugin.cpp index 0f551623185..422cf123159 100644 --- a/src/plugins/baremetal/baremetalplugin.cpp +++ b/src/plugins/baremetal/baremetalplugin.cpp @@ -2,37 +2,52 @@ // Copyright (C) 2016 Denis Shienkov // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "baremetalplugin.h" - #include "baremetaldebugsupport.h" #include "baremetaldevice.h" #include "baremetalrunconfiguration.h" #include "debugserverprovidermanager.h" +#include "iarewparser.h" #include "iarewtoolchain.h" +#include "keilparser.h" #include "keiltoolchain.h" +#include "sdccparser.h" #include "sdcctoolchain.h" +#include + namespace BareMetal::Internal { -// BareMetalPlugin - -void BareMetalPlugin::initialize() +class BareMetalPlugin final : public ExtensionSystem::IPlugin { - setupBareMetalDevice(); + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "BareMetal.json") - setupIarToolChain(); - setupKeilToolChain(); - setupSdccToolChain(); + void initialize() final + { + setupBareMetalDevice(); - setupBareMetalDeployAndRunConfigurations(); - setupBareMetalDebugSupport(); -} + setupIarToolChain(); + setupKeilToolChain(); + setupSdccToolChain(); -void BareMetalPlugin::extensionsInitialized() -{ - setupDebugServerProviderManager(this); -} + setupBareMetalDeployAndRunConfigurations(); + setupBareMetalDebugSupport(); + +#ifdef WITH_TESTS + addTest(); + addTest(); + addTest(); +#endif + } + + void extensionsInitialized() final + { + setupDebugServerProviderManager(this); + } +}; } // BareMetal::Internal + +#include "baremetalplugin.moc" diff --git a/src/plugins/baremetal/baremetalplugin.h b/src/plugins/baremetal/baremetalplugin.h deleted file mode 100644 index b529256b258..00000000000 --- a/src/plugins/baremetal/baremetalplugin.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2016 Tim Sander -// Copyright (C) 2016 Denis Shienkov -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace BareMetal::Internal { - -class BareMetalPlugin final : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "BareMetal.json") - - void initialize() final; - void extensionsInitialized() final; - -#ifdef WITH_TESTS -private slots: - void testIarOutputParsers_data(); - void testIarOutputParsers(); - void testKeilOutputParsers_data(); - void testKeilOutputParsers(); - void testSdccOutputParsers_data(); - void testSdccOutputParsers(); -#endif // WITH_TESTS -}; - -} // BareMetal::Internal diff --git a/src/plugins/baremetal/iarewparser.cpp b/src/plugins/baremetal/iarewparser.cpp index c883a4af417..35d56c50323 100644 --- a/src/plugins/baremetal/iarewparser.cpp +++ b/src/plugins/baremetal/iarewparser.cpp @@ -226,14 +226,12 @@ void IarParser::flush() // Unit tests: #ifdef WITH_TESTS -#include "baremetalplugin.h" #include #include -namespace BareMetal { -namespace Internal { +namespace BareMetal::Internal { -void BareMetalPlugin::testIarOutputParsers_data() +void IarParserTest::testIarOutputParsers_data() { QTest::addColumn("input"); QTest::addColumn("inputChannel"); @@ -392,7 +390,7 @@ void BareMetalPlugin::testIarOutputParsers_data() << QString(); } -void BareMetalPlugin::testIarOutputParsers() +void IarParserTest::testIarOutputParsers() { OutputParserTester testbench; testbench.addLineParser(new IarParser); @@ -408,7 +406,6 @@ void BareMetalPlugin::testIarOutputParsers() outputLines); } -} // namespace Internal -} // namespace BareMetal +} // BareMetal::Internal #endif // WITH_TESTS diff --git a/src/plugins/baremetal/iarewparser.h b/src/plugins/baremetal/iarewparser.h index 3ed816f5e00..4c64e0b80f7 100644 --- a/src/plugins/baremetal/iarewparser.h +++ b/src/plugins/baremetal/iarewparser.h @@ -38,4 +38,15 @@ private: QStringList m_descriptionParts; }; +#ifdef WITH_TESTS +class IarParserTest final : public QObject +{ + Q_OBJECT + +private slots: + void testIarOutputParsers_data(); + void testIarOutputParsers(); +}; +#endif // WITH_TESTS + } // BareMetal::Internal diff --git a/src/plugins/baremetal/keilparser.cpp b/src/plugins/baremetal/keilparser.cpp index cde30f1ecb7..5d42203c071 100644 --- a/src/plugins/baremetal/keilparser.cpp +++ b/src/plugins/baremetal/keilparser.cpp @@ -247,13 +247,13 @@ void KeilParser::flush() // Unit tests: #ifdef WITH_TESTS -#include "baremetalplugin.h" + #include #include namespace BareMetal::Internal { -void BareMetalPlugin::testKeilOutputParsers_data() +void KeilParserTest::testKeilOutputParsers_data() { QTest::addColumn("input"); QTest::addColumn("inputChannel"); @@ -504,7 +504,7 @@ void BareMetalPlugin::testKeilOutputParsers_data() << QString(); } -void BareMetalPlugin::testKeilOutputParsers() +void KeilParserTest::testKeilOutputParsers() { OutputParserTester testbench; testbench.addLineParser(new KeilParser); diff --git a/src/plugins/baremetal/keilparser.h b/src/plugins/baremetal/keilparser.h index 871e57f4ca8..3dd315fca8f 100644 --- a/src/plugins/baremetal/keilparser.h +++ b/src/plugins/baremetal/keilparser.h @@ -35,4 +35,15 @@ private: QStringList m_snippets; }; +#ifdef WITH_TESTS +class KeilParserTest final : public QObject +{ + Q_OBJECT + +private slots: + void testKeilOutputParsers_data(); + void testKeilOutputParsers(); +}; +#endif // WITH_TESTS + } // BareMetal::Internal diff --git a/src/plugins/baremetal/sdccparser.cpp b/src/plugins/baremetal/sdccparser.cpp index 0612773c3ab..9115e3e5048 100644 --- a/src/plugins/baremetal/sdccparser.cpp +++ b/src/plugins/baremetal/sdccparser.cpp @@ -141,13 +141,12 @@ void SdccParser::flush() // Unit tests: #ifdef WITH_TESTS -#include "baremetalplugin.h" #include #include namespace BareMetal::Internal { -void BareMetalPlugin::testSdccOutputParsers_data() +void SdccParserTest::testSdccOutputParsers_data() { QTest::addColumn("input"); QTest::addColumn("inputChannel"); @@ -291,7 +290,7 @@ void BareMetalPlugin::testSdccOutputParsers_data() << QString(); } -void BareMetalPlugin::testSdccOutputParsers() +void SdccParserTest::testSdccOutputParsers() { OutputParserTester testbench; testbench.addLineParser(new SdccParser); diff --git a/src/plugins/baremetal/sdccparser.h b/src/plugins/baremetal/sdccparser.h index e2f089c1138..b2f904dfcde 100644 --- a/src/plugins/baremetal/sdccparser.h +++ b/src/plugins/baremetal/sdccparser.h @@ -25,4 +25,15 @@ private: int m_lines = 0; }; +#ifdef WITH_TESTS +class SdccParserTest final : public QObject +{ + Q_OBJECT + +private slots: + void testSdccOutputParsers_data(); + void testSdccOutputParsers(); +}; +#endif // WITH_TESTS + } // BareMetal::Internal From d1aaebc3b46a645943080a2668d9cff37709b13a Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Nov 2023 15:35:16 +0100 Subject: [PATCH 0254/1546] FakeVim: Move test declaration from plugin to separate object Also ugly, but differently. Change-Id: I832ac19c7d8a3457a40baaae60653a02a32dbd75 Reviewed-by: Jarek Kobus Reviewed-by: --- src/plugins/fakevim/fakevim_test.cpp | 355 ++++++++++++++++++-------- src/plugins/fakevim/fakevimplugin.cpp | 66 ++--- src/plugins/fakevim/fakevimplugin.h | 135 ---------- 3 files changed, 289 insertions(+), 267 deletions(-) diff --git a/src/plugins/fakevim/fakevim_test.cpp b/src/plugins/fakevim/fakevim_test.cpp index 450e3917d6b..6d1dd74b3ca 100644 --- a/src/plugins/fakevim/fakevim_test.cpp +++ b/src/plugins/fakevim/fakevim_test.cpp @@ -6,7 +6,6 @@ * All test are based on Vim behaviour. */ -#include "fakevimplugin.h" #include "fakevimhandler.h" #include @@ -35,10 +34,164 @@ #define LINE_START "\t\t<" #define LINE_END ">\n" +using namespace TextEditor; + +namespace FakeVim::Internal { + QString _(const char *c) { return QLatin1String(c); } QString _(const QByteArray &c) { return QLatin1String(c); } QString _(const QString &c) { return c; } +class FakeVimTester final : public QObject +{ + Q_OBJECT + +private slots: + void cleanup(); + + void test_vim_movement(); + + void test_vim_target_column_normal(); + void test_vim_target_column_visual_char(); + void test_vim_target_column_visual_block(); + void test_vim_target_column_visual_line(); + void test_vim_target_column_insert(); + void test_vim_target_column_replace(); + + void test_vim_insert(); + void test_vim_fFtT(); + void test_vim_transform_numbers(); + void test_vim_delete(); + + void test_vim_delete_inner_word(); + void test_vim_delete_a_word(); + void test_vim_change_a_word(); + + void test_vim_change_replace(); + + void test_vim_block_selection(); + void test_vim_block_selection_insert(); + + void test_vim_delete_inner_paragraph(); + void test_vim_delete_a_paragraph(); + void test_vim_change_inner_paragraph(); + void test_vim_change_a_paragraph(); + void test_vim_select_inner_paragraph(); + void test_vim_select_a_paragraph(); + + void test_vim_repeat(); + void test_vim_search(); + void test_vim_indent(); + void test_vim_marks(); + void test_vim_jumps(); + void test_vim_current_column(); + void test_vim_copy_paste(); + void test_vim_undo_redo(); + void test_vim_letter_case(); + void test_vim_code_autoindent(); + void test_vim_code_folding(); + void test_vim_code_completion(); + void test_vim_substitute(); + void test_vim_ex_commandbuffer_paste(); + void test_vim_ex_yank(); + void test_vim_ex_delete(); + void test_vim_ex_change(); + void test_vim_ex_shift(); + void test_vim_ex_move(); + void test_vim_ex_join(); + void test_advanced_commands(); + +//public: +// void changeStatusData(const QString &info) { m_statusData = info; } +// void changeStatusMessage(const QString &info, int) { m_statusMessage = info; } +// void changeExtraInformation(const QString &info) { m_infoMessage = info; } + +//private slots: +// // functional tests + void test_vim_indentation(); + + // command mode + void test_vim_command_oO(); + void test_vim_command_put_at_eol(); + void test_vim_command_Cxx_down_dot(); + void test_vim_command_Gyyp(); + void test_vim_command_J(); + void test_vim_command_Yp(); + void test_vim_command_cc(); + void test_vim_command_cw(); + void test_vim_command_cj(); + void test_vim_command_ck(); + void test_vim_command_c_dollar(); + void test_vim_command_C(); + void test_vim_command_dd(); + void test_vim_command_dd_2(); + void test_vim_command_d_dollar(); + void test_vim_command_dgg(); + void test_vim_command_dG(); + void test_vim_command_dj(); + void test_vim_command_dk(); + void test_vim_command_D(); + void test_vim_command_dfx_down(); + void test_vim_command_dollar(); + void test_vim_command_down(); + void test_vim_command_dw(); + void test_vim_command_e(); + void test_vim_command_i(); + void test_vim_command_left(); + void test_vim_command_ma_yank(); + void test_vim_command_r(); + void test_vim_command_right(); + void test_vim_command_up(); + void test_vim_command_w(); + void test_vim_command_x(); + void test_vim_command_yyp(); + void test_vim_command_y_dollar(); + void test_vim_command_percent(); + + void test_vim_visual_d(); + void test_vim_Visual_d(); + void test_vim_visual_block_D(); + + // Plugin emulation + void test_vim_commentary_emulation(); + void test_vim_commentary_file_names(); + void test_vim_replace_with_register_emulation(); + void test_vim_exchange_emulation(); + void test_vim_arg_text_obj_emulation(); + void test_vim_surround_emulation(); + + void test_macros(); + + void test_vim_qtcreator(); + + // special tests + void test_i_cw_i(); + + // map test should be last one since it changes default behaviour + void test_map(); + +//private: +// QString m_statusMessage; +// QString m_statusData; +// QString m_infoMessage; + +private: + struct TestData; + void setup(TestData *data); +}; + +using SetupTestCallback = void (*)(QString *, FakeVimHandler **, QWidget **); + +static SetupTestCallback setupTest = nullptr; + + +QObject *createFakeVimTester(SetupTestCallback cb) +{ + setupTest = cb; + return new FakeVimTester; +} + + // Format of message after comparison fails (used by KEYS, COMMAND). static const QString helpFormat = _( "\n\tBefore command [%1]:\n" \ @@ -109,8 +262,6 @@ static QByteArray textWithCursor(const QByteArray &text, const QTextBlock &block KEYS(".", textWithCursor(redo, newPosition)); \ } while (false) -using namespace FakeVim::Internal; -using namespace TextEditor; const QByteArray testLines = /* 0 1 2 3 4 */ @@ -151,7 +302,7 @@ static QByteArray cursor(int line, int column) static QByteArray lmid(int i, int n = -1) { return bajoin(l.mid(i, n)); } // Data for tests containing BaseTextEditorWidget and FakeVimHAndler. -struct FakeVimPlugin::TestData +struct FakeVimTester::TestData { FakeVimHandler *handler; QWidget *edit; @@ -244,7 +395,7 @@ struct FakeVimPlugin::TestData } }; -void FakeVimPlugin::setup(TestData *data) +void FakeVimTester::setup(TestData *data) { setupTest(&data->title, &data->handler, &data->edit); data->reset(); @@ -255,13 +406,13 @@ void FakeVimPlugin::setup(TestData *data) } -void FakeVimPlugin::cleanup() +void FakeVimTester::cleanup() { Core::EditorManager::closeAllEditors(false); } -void FakeVimPlugin::test_vim_indentation() +void FakeVimTester::test_vim_indentation() { TestData data; setup(&data); @@ -331,7 +482,7 @@ void FakeVimPlugin::test_vim_indentation() QCOMPARE(data.handler->tabExpand(9), _("\t ")); } -void FakeVimPlugin::test_vim_movement() +void FakeVimTester::test_vim_movement() { TestData data; setup(&data); @@ -512,7 +663,7 @@ void FakeVimPlugin::test_vim_movement() X ""); } -void FakeVimPlugin::test_vim_target_column_normal() +void FakeVimTester::test_vim_target_column_normal() { TestData data; setup(&data); @@ -535,7 +686,7 @@ void FakeVimPlugin::test_vim_target_column_normal() KEYS("^k", X "a" "b" "c" N "d" "e" N "" N "k" "l" "m" "n"); } -void FakeVimPlugin::test_vim_target_column_visual_char() +void FakeVimTester::test_vim_target_column_visual_char() { TestData data; setup(&data); @@ -560,7 +711,7 @@ void FakeVimPlugin::test_vim_target_column_visual_char() "a" "b" "c" N X "d" "e" N "" N "k" "l" "m" "n"); } -void FakeVimPlugin::test_vim_target_column_visual_block() +void FakeVimTester::test_vim_target_column_visual_block() { TestData data; setup(&data); @@ -586,7 +737,7 @@ void FakeVimPlugin::test_vim_target_column_visual_block() "a" "b" "c" N X "d" "e" N "" N "k" "l" "m" "n"); } -void FakeVimPlugin::test_vim_target_column_visual_line() +void FakeVimTester::test_vim_target_column_visual_line() { TestData data; setup(&data); @@ -602,7 +753,7 @@ void FakeVimPlugin::test_vim_target_column_visual_line() // Movement inside selection is not supported. } -void FakeVimPlugin::test_vim_target_column_insert() +void FakeVimTester::test_vim_target_column_insert() { TestData data; setup(&data); @@ -627,7 +778,7 @@ void FakeVimPlugin::test_vim_target_column_insert() X "a" "b" "c" N "d" "e" N "" N "k" "l" "m" "n"); } -void FakeVimPlugin::test_vim_target_column_replace() +void FakeVimTester::test_vim_target_column_replace() { TestData data; setup(&data); @@ -653,7 +804,7 @@ void FakeVimPlugin::test_vim_target_column_replace() X "a" "b" "c" N "d" "e" N "" N "k" "l" "m" "n"); } -void FakeVimPlugin::test_vim_insert() +void FakeVimTester::test_vim_insert() { TestData data; setup(&data); @@ -791,7 +942,7 @@ void FakeVimPlugin::test_vim_insert() KEYS(".", " abc" N " def"); } -void FakeVimPlugin::test_vim_fFtT() +void FakeVimTester::test_vim_fFtT() { TestData data; setup(&data); @@ -836,7 +987,7 @@ void FakeVimPlugin::test_vim_fFtT() KEYS("2;", "int main() { return (x > 0) ? 0 :" X " (x - 1); }"); } -void FakeVimPlugin::test_vim_transform_numbers() +void FakeVimTester::test_vim_transform_numbers() { TestData data; setup(&data); @@ -921,7 +1072,7 @@ void FakeVimPlugin::test_vim_transform_numbers() KEYS("", "007" X "7"); } -void FakeVimPlugin::test_vim_delete() +void FakeVimTester::test_vim_delete() { TestData data; setup(&data); @@ -1086,7 +1237,7 @@ void FakeVimPlugin::test_vim_delete() X ""); } -void FakeVimPlugin::test_vim_delete_inner_word() +void FakeVimTester::test_vim_delete_inner_word() { TestData data; setup(&data); @@ -1134,7 +1285,7 @@ void FakeVimPlugin::test_vim_delete_inner_word() KEYS("diw", "a " X " c"); } -void FakeVimPlugin::test_vim_delete_a_word() +void FakeVimTester::test_vim_delete_a_word() { TestData data; setup(&data); @@ -1204,7 +1355,7 @@ void FakeVimPlugin::test_vim_delete_a_word() KEYS("vh2awd", "ab" X "c"); } -void FakeVimPlugin::test_vim_change_a_word() +void FakeVimTester::test_vim_change_a_word() { TestData data; setup(&data); @@ -1236,7 +1387,7 @@ void FakeVimPlugin::test_vim_change_a_word() KEYS("cawZ", "a " X "Zc"); } -void FakeVimPlugin::test_vim_change_replace() +void FakeVimTester::test_vim_change_replace() { TestData data; setup(&data); @@ -1368,7 +1519,7 @@ void FakeVimPlugin::test_vim_change_replace() KEYS("2\"xp", "xyzabcabcab" X "c" N "def"); } -void FakeVimPlugin::test_vim_block_selection() +void FakeVimTester::test_vim_block_selection() { TestData data; setup(&data); @@ -1485,7 +1636,7 @@ void FakeVimPlugin::test_vim_block_selection() KEYS("u", "\"abc\"\"" X "def\""); } -void FakeVimPlugin::test_vim_block_selection_insert() +void FakeVimTester::test_vim_block_selection_insert() { TestData data; setup(&data); @@ -1555,7 +1706,7 @@ void FakeVimPlugin::test_vim_block_selection_insert() ); } -void FakeVimPlugin::test_vim_delete_inner_paragraph() +void FakeVimTester::test_vim_delete_inner_paragraph() { TestData data; setup(&data); @@ -1587,7 +1738,7 @@ void FakeVimPlugin::test_vim_delete_inner_paragraph() ); } -void FakeVimPlugin::test_vim_delete_a_paragraph() +void FakeVimTester::test_vim_delete_a_paragraph() { TestData data; setup(&data); @@ -1627,7 +1778,7 @@ void FakeVimPlugin::test_vim_delete_a_paragraph() ); } -void FakeVimPlugin::test_vim_change_inner_paragraph() +void FakeVimTester::test_vim_change_inner_paragraph() { TestData data; setup(&data); @@ -1660,7 +1811,7 @@ void FakeVimPlugin::test_vim_change_inner_paragraph() ); } -void FakeVimPlugin::test_vim_change_a_paragraph() +void FakeVimTester::test_vim_change_a_paragraph() { TestData data; setup(&data); @@ -1701,7 +1852,7 @@ void FakeVimPlugin::test_vim_change_a_paragraph() ); } -void FakeVimPlugin::test_vim_select_inner_paragraph() +void FakeVimTester::test_vim_select_inner_paragraph() { TestData data; setup(&data); @@ -1925,7 +2076,7 @@ void FakeVimPlugin::test_vim_select_inner_paragraph() ); } -void FakeVimPlugin::test_vim_select_a_paragraph() +void FakeVimTester::test_vim_select_a_paragraph() { TestData data; setup(&data); @@ -1981,7 +2132,7 @@ void FakeVimPlugin::test_vim_select_a_paragraph() ); } -void FakeVimPlugin::test_vim_repeat() +void FakeVimTester::test_vim_repeat() { TestData data; setup(&data); @@ -2030,7 +2181,7 @@ void FakeVimPlugin::test_vim_repeat() KEYS("gg.", "XXcd" N "XXXg" N "gXXj" N "jklm"); } -void FakeVimPlugin::test_vim_search() +void FakeVimTester::test_vim_search() { TestData data; setup(&data); @@ -2173,7 +2324,7 @@ void FakeVimPlugin::test_vim_search() KEYS("fe/def", "abc def ghi " X "def."); } -void FakeVimPlugin::test_vim_indent() +void FakeVimTester::test_vim_indent() { TestData data; setup(&data); @@ -2303,7 +2454,7 @@ void FakeVimPlugin::test_vim_indent() ""); } -void FakeVimPlugin::test_vim_marks() +void FakeVimTester::test_vim_marks() { TestData data; setup(&data); @@ -2343,7 +2494,7 @@ void FakeVimPlugin::test_vim_marks() KEYS("G" "`x", "a" X "bc" N "df" N "ghi"); } -void FakeVimPlugin::test_vim_jumps() +void FakeVimTester::test_vim_jumps() { TestData data; setup(&data); @@ -2382,7 +2533,7 @@ void FakeVimPlugin::test_vim_jumps() KEYS("", "abc" N "def" N "g" X "hi"); } -void FakeVimPlugin::test_vim_current_column() +void FakeVimTester::test_vim_current_column() { // Check if column is correct after command and vertical cursor movement. TestData data; @@ -2440,7 +2591,7 @@ void FakeVimPlugin::test_vim_current_column() KEYS("ccx", " xabc" N " " N " g" X "hi"); } -void FakeVimPlugin::test_vim_copy_paste() +void FakeVimTester::test_vim_copy_paste() { TestData data; setup(&data); @@ -2534,7 +2685,7 @@ void FakeVimPlugin::test_vim_copy_paste() KEYS("\"ayawAa", "aaa bbbaaa "); } -void FakeVimPlugin::test_vim_undo_redo() +void FakeVimTester::test_vim_undo_redo() { TestData data; setup(&data); @@ -2624,7 +2775,7 @@ void FakeVimPlugin::test_vim_undo_redo() KEYS("u", "abc" N " " X "def" N "ghi"); } -void FakeVimPlugin::test_vim_letter_case() +void FakeVimTester::test_vim_letter_case() { TestData data; setup(&data); @@ -2679,7 +2830,7 @@ void FakeVimPlugin::test_vim_letter_case() KEYS("u", " abcde" N " " X " fgh" N " ijk"); } -void FakeVimPlugin::test_vim_code_autoindent() +void FakeVimTester::test_vim_code_autoindent() { TestData data; setup(&data); @@ -2762,7 +2913,7 @@ void FakeVimPlugin::test_vim_code_autoindent() data.doCommand("set smartindent"); } -void FakeVimPlugin::test_vim_code_folding() +void FakeVimTester::test_vim_code_folding() { TestData data; setup(&data); @@ -2856,7 +3007,7 @@ void FakeVimPlugin::test_vim_code_folding() // Opening folds recursively isn't supported (previous position in fold isn't restored). } -void FakeVimPlugin::test_vim_code_completion() +void FakeVimTester::test_vim_code_completion() { // Test completion by simply bypassing FakeVim and inserting text directly in editor widget. TestData data; @@ -2907,7 +3058,7 @@ void FakeVimPlugin::test_vim_code_completion() ""); } -void FakeVimPlugin::test_vim_substitute() +void FakeVimTester::test_vim_substitute() { TestData data; setup(&data); @@ -3053,7 +3204,7 @@ void FakeVimPlugin::test_vim_substitute() COMMAND(R"(s#\#\##\#\#\#\##g)", X "abc####def####ghi"); } -void FakeVimPlugin::test_vim_ex_commandbuffer_paste() +void FakeVimTester::test_vim_ex_commandbuffer_paste() { TestData data; setup(&data); @@ -3062,7 +3213,7 @@ void FakeVimPlugin::test_vim_ex_commandbuffer_paste() KEYS("fyyiw0:s//0/g", "xyz def xyz def xyz"); } -void FakeVimPlugin::test_vim_ex_yank() +void FakeVimTester::test_vim_ex_yank() { TestData data; setup(&data); @@ -3167,7 +3318,7 @@ void FakeVimPlugin::test_vim_ex_yank() ); } -void FakeVimPlugin::test_vim_ex_delete() +void FakeVimTester::test_vim_ex_delete() { TestData data; setup(&data); @@ -3185,7 +3336,7 @@ void FakeVimPlugin::test_vim_ex_delete() COMMAND("5,.+1d", "abc" N "def" N "abc" N X "jkl"); } -void FakeVimPlugin::test_vim_ex_change() +void FakeVimTester::test_vim_ex_change() { TestData data; setup(&data); @@ -3195,7 +3346,7 @@ void FakeVimPlugin::test_vim_ex_change() KEYS(":-1,+1cXXX0", X "XXX" N "jkl"); } -void FakeVimPlugin::test_vim_ex_shift() +void FakeVimTester::test_vim_ex_shift() { TestData data; setup(&data); @@ -3210,7 +3361,7 @@ void FakeVimPlugin::test_vim_ex_shift() COMMAND("<<", "abc" N X "def" N "ghi" N "jkl"); } -void FakeVimPlugin::test_vim_ex_move() +void FakeVimTester::test_vim_ex_move() { TestData data; setup(&data); @@ -3268,7 +3419,7 @@ void FakeVimPlugin::test_vim_ex_move() data.doCommand("vunmap "); } -void FakeVimPlugin::test_vim_ex_join() +void FakeVimTester::test_vim_ex_join() { TestData data; setup(&data); @@ -3280,7 +3431,7 @@ void FakeVimPlugin::test_vim_ex_join() COMMAND("u", X " abc" N " def" N " ghi" N " jkl"); } -void FakeVimPlugin::test_advanced_commands() +void FakeVimTester::test_advanced_commands() { TestData data; setup(&data); @@ -3302,7 +3453,7 @@ void FakeVimPlugin::test_advanced_commands() COMMAND("%s/a\\|b\\||/X/g|%s/[^X]/Y/g", "XXY"); } -void FakeVimPlugin::test_map() +void FakeVimTester::test_map() { TestData data; setup(&data); @@ -3507,7 +3658,7 @@ void FakeVimPlugin::test_map() KEYS("ijk", "aj" X "kb__c def" N "gh__i jkl"); } -void FakeVimPlugin::test_vim_command_cc() +void FakeVimTester::test_vim_command_cc() { TestData data; setup(&data); @@ -3522,7 +3673,7 @@ void FakeVimPlugin::test_vim_command_cc() KEYS("3ccxyz", "xy|z" N "abc"); } -void FakeVimPlugin::test_vim_command_cw() +void FakeVimTester::test_vim_command_cw() { TestData data; setup(&data); @@ -3530,7 +3681,7 @@ void FakeVimPlugin::test_vim_command_cw() KEYS("cwx", X "x 456"); } -void FakeVimPlugin::test_vim_command_cj() +void FakeVimTester::test_vim_command_cj() { TestData data; setup(&data); @@ -3549,7 +3700,7 @@ void FakeVimPlugin::test_vim_command_cj() KEYS(".", "ab|c\n" + lmid(2)); } -void FakeVimPlugin::test_vim_command_ck() +void FakeVimTester::test_vim_command_ck() { TestData data; setup(&data); @@ -3560,7 +3711,7 @@ void FakeVimPlugin::test_vim_command_ck() KEYS("P", '|' + lmid(0,2)+'\n' + '\n' + lmid(2)); } -void FakeVimPlugin::test_vim_command_c_dollar() +void FakeVimTester::test_vim_command_c_dollar() { TestData data; setup(&data); @@ -3574,7 +3725,7 @@ void FakeVimPlugin::test_vim_command_c_dollar() KEYS("0c$abc", l[0]+'\n' + "ab|c\n" + lmid(2)); } -void FakeVimPlugin::test_vim_command_C() +void FakeVimTester::test_vim_command_C() { TestData data; setup(&data); @@ -3588,7 +3739,7 @@ void FakeVimPlugin::test_vim_command_C() KEYS("0Cabc", l[0] + "\nab|c\n" + lmid(2)); } -void FakeVimPlugin::test_vim_command_dw() +void FakeVimTester::test_vim_command_dw() { TestData data; setup(&data); @@ -3607,7 +3758,7 @@ void FakeVimPlugin::test_vim_command_dw() KEYS("dw", "|>\n" + lmid(3)); } -void FakeVimPlugin::test_vim_command_dd() +void FakeVimTester::test_vim_command_dd() { TestData data; setup(&data); @@ -3623,7 +3774,7 @@ void FakeVimPlugin::test_vim_command_dd() KEYS("dd", l[0] + "\n|" + lmid(9)); } -void FakeVimPlugin::test_vim_command_dd_2() +void FakeVimTester::test_vim_command_dd_2() { TestData data; setup(&data); @@ -3635,7 +3786,7 @@ void FakeVimPlugin::test_vim_command_dd_2() KEYS("u", l[0] + "\n|" + lmid(2)); } -void FakeVimPlugin::test_vim_command_d_dollar() +void FakeVimTester::test_vim_command_d_dollar() { TestData data; setup(&data); @@ -3646,7 +3797,7 @@ void FakeVimPlugin::test_vim_command_d_dollar() KEYS("0d$", l[0] + '\n'+"|\n" + lmid(2)); } -void FakeVimPlugin::test_vim_command_dj() +void FakeVimTester::test_vim_command_dj() { TestData data; setup(&data); @@ -3665,7 +3816,7 @@ void FakeVimPlugin::test_vim_command_dj() KEYS("p", lmid(0,1)+'\n' + lmid(3,1)+'\n' + '|'+lmid(1,2)+'\n' + lmid(4)); } -void FakeVimPlugin::test_vim_command_dk() +void FakeVimTester::test_vim_command_dk() { TestData data; setup(&data); @@ -3685,7 +3836,7 @@ void FakeVimPlugin::test_vim_command_dk() KEYS("p", lmid(2,1)+'\n' + '|' + lmid(0,2)+'\n' + lmid(3)); } -void FakeVimPlugin::test_vim_command_dgg() +void FakeVimTester::test_vim_command_dgg() { TestData data; setup(&data); @@ -3696,7 +3847,7 @@ void FakeVimPlugin::test_vim_command_dgg() KEYS("u", '|' + lmid(0)); } -void FakeVimPlugin::test_vim_command_dG() +void FakeVimTester::test_vim_command_dG() { TestData data; setup(&data); @@ -3715,7 +3866,7 @@ void FakeVimPlugin::test_vim_command_dG() KEYS("dG0", lmid(0, l.size()-3)+'\n' + '|'+lmid(l.size()-3,1)); } -void FakeVimPlugin::test_vim_command_D() +void FakeVimTester::test_vim_command_D() { TestData data; setup(&data); @@ -3726,7 +3877,7 @@ void FakeVimPlugin::test_vim_command_D() KEYS("0D", l[0] + "\n|\n" + lmid(2)); } -void FakeVimPlugin::test_vim_command_dollar() +void FakeVimTester::test_vim_command_dollar() { TestData data; setup(&data); @@ -3737,7 +3888,7 @@ void FakeVimPlugin::test_vim_command_dollar() KEYS("2j", cursor(4, -1)); } -void FakeVimPlugin::test_vim_command_down() +void FakeVimTester::test_vim_command_down() { TestData data; setup(&data); @@ -3748,7 +3899,7 @@ void FakeVimPlugin::test_vim_command_down() KEYS("4j", lmid(0,8)+'\n' + "| return app.exec();\n" + lmid(9)); } -void FakeVimPlugin::test_vim_command_dfx_down() +void FakeVimTester::test_vim_command_dfx_down() { TestData data; setup(&data); @@ -3764,7 +3915,7 @@ void FakeVimPlugin::test_vim_command_dfx_down() KEYS("u", l[0] + "\n#inc|lude \n" + lmid(2)); } -void FakeVimPlugin::test_vim_command_Cxx_down_dot() +void FakeVimTester::test_vim_command_Cxx_down_dot() { TestData data; setup(&data); @@ -3776,7 +3927,7 @@ void FakeVimPlugin::test_vim_command_Cxx_down_dot() KEYS(".", l[0] + "\n#incxx\n#inclx|x\n" + lmid(3)); } -void FakeVimPlugin::test_vim_command_e() +void FakeVimTester::test_vim_command_e() { TestData data; setup(&data); @@ -3801,7 +3952,7 @@ void FakeVimPlugin::test_vim_command_e() KEYS("10k","|\n" + lmid(1)); // home. } -void FakeVimPlugin::test_vim_command_i() +void FakeVimTester::test_vim_command_i() { TestData data; setup(&data); @@ -3838,7 +3989,7 @@ void FakeVimPlugin::test_vim_command_i() KEYS("u", "|a" + testLines); } -void FakeVimPlugin::test_vim_command_left() +void FakeVimTester::test_vim_command_left() { TestData data; setup(&data); @@ -3852,7 +4003,7 @@ void FakeVimPlugin::test_vim_command_left() KEYS("50h", lmid(0, 4) + "\n|int main(int argc, char *argv[])\n" + lmid(5)); } -void FakeVimPlugin::test_vim_command_r() +void FakeVimTester::test_vim_command_r() { TestData data; setup(&data); @@ -3868,7 +4019,7 @@ void FakeVimPlugin::test_vim_command_r() KEYS("h2rc",lmid(0, 4) + "\nint main(int argc, char *argvbc|c\n" + lmid(5)); } -void FakeVimPlugin::test_vim_command_right() +void FakeVimTester::test_vim_command_right() { TestData data; setup(&data); @@ -3880,7 +4031,7 @@ void FakeVimPlugin::test_vim_command_right() KEYS("50l", lmid(0, 4) + "\nint main(int argc, char *argv[]|)\n" + lmid(5)); } -void FakeVimPlugin::test_vim_command_up() +void FakeVimTester::test_vim_command_up() { TestData data; setup(&data); @@ -3894,7 +4045,7 @@ void FakeVimPlugin::test_vim_command_up() KEYS("2k", cursor(0, 0)); } -void FakeVimPlugin::test_vim_command_w() +void FakeVimTester::test_vim_command_w() { TestData data; setup(&data); @@ -3919,7 +4070,7 @@ void FakeVimPlugin::test_vim_command_w() KEYS("w", lmid(0,5)+'\n' + "|{\n" + lmid(6)); } -void FakeVimPlugin::test_vim_command_yyp() +void FakeVimTester::test_vim_command_yyp() { TestData data; setup(&data); @@ -3929,7 +4080,7 @@ void FakeVimPlugin::test_vim_command_yyp() KEYS("yyp", lmid(0, 4) + '\n' + lmid(4, 1) + "\n|" + lmid(4)); } -void FakeVimPlugin::test_vim_command_y_dollar() +void FakeVimTester::test_vim_command_y_dollar() { TestData data; setup(&data); @@ -3942,7 +4093,7 @@ void FakeVimPlugin::test_vim_command_y_dollar() KEYS("$y$P", l[0]+'\n'+ l[1]+">>|>>\n" + lmid(2)); } -void FakeVimPlugin::test_vim_command_percent() +void FakeVimTester::test_vim_command_percent() { TestData data; setup(&data); @@ -4026,7 +4177,7 @@ void FakeVimPlugin::test_vim_command_percent() ); } -void FakeVimPlugin::test_vim_command_Yp() +void FakeVimTester::test_vim_command_Yp() { TestData data; setup(&data); @@ -4036,7 +4187,7 @@ void FakeVimPlugin::test_vim_command_Yp() KEYS("Yp", lmid(0, 4) + '\n' + lmid(4, 1) + "\n|" + lmid(4)); } -void FakeVimPlugin::test_vim_command_ma_yank() +void FakeVimTester::test_vim_command_ma_yank() { TestData data; setup(&data); @@ -4058,7 +4209,7 @@ void FakeVimPlugin::test_vim_command_ma_yank() KEYS("\"ap", lmid(0,5) + "\n|" + lmid(0,4) +'\n' + lmid(4)); } -void FakeVimPlugin::test_vim_command_Gyyp() +void FakeVimTester::test_vim_command_Gyyp() { TestData data; setup(&data); @@ -4068,7 +4219,7 @@ void FakeVimPlugin::test_vim_command_Gyyp() KEYS("yyp", lmid(0) + '|' + lmid(9, 1)+'\n'); } -void FakeVimPlugin::test_i_cw_i() +void FakeVimTester::test_i_cw_i() { TestData data; setup(&data); @@ -4080,7 +4231,7 @@ void FakeVimPlugin::test_i_cw_i() KEYS("iaa", l[0] + "\nxya|ay" + lmid(1)); } -void FakeVimPlugin::test_vim_command_J() +void FakeVimTester::test_vim_command_J() { TestData data; setup(&data); @@ -4108,7 +4259,7 @@ void FakeVimPlugin::test_vim_command_J() KEYS("J", "# abc def"); } -void FakeVimPlugin::test_vim_command_put_at_eol() +void FakeVimTester::test_vim_command_put_at_eol() { TestData data; setup(&data); @@ -4122,7 +4273,7 @@ void FakeVimPlugin::test_vim_command_put_at_eol() KEYS("P", lmid(0,2)+">|>>\n" + lmid(2)); } -void FakeVimPlugin::test_vim_command_oO() +void FakeVimTester::test_vim_command_oO() { TestData data; setup(&data); @@ -4138,7 +4289,7 @@ void FakeVimPlugin::test_vim_command_oO() KEYS("Ol-2", "l1\n" "l2\n" + lmid(0) + "l-|2\n" + "l-1\n"); } -void FakeVimPlugin::test_vim_command_x() +void FakeVimTester::test_vim_command_x() { TestData data; setup(&data); @@ -4149,7 +4300,7 @@ void FakeVimPlugin::test_vim_command_x() KEYS("x", lmid(0,1)+'\n' + l[1].left(l[1].length()-2)+'|'+l[1].mid(l[1].length()-2,1)+'\n' + lmid(2)); } -void FakeVimPlugin::test_vim_visual_d() +void FakeVimTester::test_vim_visual_d() { TestData data; setup(&data); @@ -4181,7 +4332,7 @@ void FakeVimPlugin::test_vim_visual_d() KEYS("v$o0k$d", '|' + lmid(6)); } -void FakeVimPlugin::test_vim_Visual_d() +void FakeVimTester::test_vim_Visual_d() { TestData data; setup(&data); @@ -4198,7 +4349,7 @@ void FakeVimPlugin::test_vim_Visual_d() KEYS("P", '|' + lmid(0,1)+'\n' + lmid(3)); } -void FakeVimPlugin::test_vim_visual_block_D() +void FakeVimTester::test_vim_visual_block_D() { TestData data; setup(&data); @@ -4213,7 +4364,7 @@ void FakeVimPlugin::test_vim_visual_block_D() KEYS(".", X "a" N "g" N "" N "j"); } -void FakeVimPlugin::test_vim_commentary_emulation() +void FakeVimTester::test_vim_commentary_emulation() { TestData data; setup(&data); @@ -4239,7 +4390,7 @@ void FakeVimPlugin::test_vim_commentary_emulation() KEYS(".", X "abc" N "def"); } -void FakeVimPlugin::test_vim_commentary_file_names() +void FakeVimTester::test_vim_commentary_file_names() { TestData data; setup(&data); @@ -4266,7 +4417,7 @@ void FakeVimPlugin::test_vim_commentary_file_names() KEYS("gcc", X "// abc"); } -void FakeVimPlugin::test_vim_replace_with_register_emulation() +void FakeVimTester::test_vim_replace_with_register_emulation() { TestData data; setup(&data); @@ -4313,7 +4464,7 @@ void FakeVimPlugin::test_vim_replace_with_register_emulation() KEYS("v4lgr", "abc abci"); } -void FakeVimPlugin::test_vim_exchange_emulation() +void FakeVimTester::test_vim_exchange_emulation() { TestData data; setup(&data); @@ -4341,7 +4492,7 @@ void FakeVimPlugin::test_vim_exchange_emulation() KEYS(".", "def" N "abc"); } -void FakeVimPlugin::test_vim_arg_text_obj_emulation() +void FakeVimTester::test_vim_arg_text_obj_emulation() { TestData data; setup(&data); @@ -4365,7 +4516,7 @@ void FakeVimPlugin::test_vim_arg_text_obj_emulation() KEYS("dia", "foo()"); } -void FakeVimPlugin::test_vim_surround_emulation() +void FakeVimTester::test_vim_surround_emulation() { TestData data; setup(&data); @@ -4435,7 +4586,7 @@ void FakeVimPlugin::test_vim_surround_emulation() KEYS("ljSB", "{ab}c" N "{de}f"); } -void FakeVimPlugin::test_macros() +void FakeVimTester::test_macros() { TestData data; setup(&data); @@ -4507,7 +4658,7 @@ void FakeVimPlugin::test_macros() KEYS("j@q", "!!!" N X "!!!"); } -void FakeVimPlugin::test_vim_qtcreator() +void FakeVimTester::test_vim_qtcreator() { TestData data; setup(&data); @@ -4897,3 +5048,7 @@ void FakeVimPlugin::test_vim_qtcreator() "}" N ""); } + +} // FakeVim::Internal + +#include "fakevim_test.moc" diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp index ca17b3f49cd..c709b46266d 100644 --- a/src/plugins/fakevim/fakevimplugin.cpp +++ b/src/plugins/fakevim/fakevimplugin.cpp @@ -2007,37 +2007,7 @@ void FakeVimPluginPrivate::switchToFile(int n) // /////////////////////////////////////////////////////////////////////// -FakeVimPlugin::FakeVimPlugin() -{ - dd = new FakeVimPluginPrivate; -} - -FakeVimPlugin::~FakeVimPlugin() -{ - delete dd; - dd = nullptr; -} - -void FakeVimPlugin::initialize() -{ - dd->initialize(); -} - -ExtensionSystem::IPlugin::ShutdownFlag FakeVimPlugin::aboutToShutdown() -{ - StatusBarManager::destroyStatusBarWidget(dd->m_miniBuffer); - dd->m_miniBuffer = nullptr; - return SynchronousShutdown; -} - -void FakeVimPlugin::extensionsInitialized() -{ - dd->m_miniBuffer = new MiniBuffer; - StatusBarManager::addStatusBarWidget(dd->m_miniBuffer, StatusBarManager::LastLeftAligned); -} - -#ifdef WITH_TESTS -void FakeVimPlugin::setupTest(QString *title, FakeVimHandler **handler, QWidget **edit) +static void setupTest(QString *title, FakeVimHandler **handler, QWidget **edit) { *title = QString::fromLatin1("test.cpp"); IEditor *iedit = EditorManager::openEditorWithContents(Id(), title); @@ -2077,7 +2047,39 @@ void FakeVimPlugin::setupTest(QString *title, FakeVimHandler **handler, QWidget // QCOMPARE(EDITOR(toPlainText()), lines); (*handler)->handleCommand("set iskeyword=@,48-57,_,192-255,a-z,A-Z"); } -#endif + +QObject *createFakeVimTester( void (*setupTest)(QString *, FakeVimHandler **, QWidget **) ); // in fakevim_test.cpp + +FakeVimPlugin::FakeVimPlugin() +{ + addTestCreator([] { return createFakeVimTester(&setupTest); }); + dd = new FakeVimPluginPrivate; +} + +FakeVimPlugin::~FakeVimPlugin() +{ + delete dd; + dd = nullptr; +} + +void FakeVimPlugin::initialize() +{ + dd->initialize(); +} + +ExtensionSystem::IPlugin::ShutdownFlag FakeVimPlugin::aboutToShutdown() +{ + StatusBarManager::destroyStatusBarWidget(dd->m_miniBuffer); + dd->m_miniBuffer = nullptr; + return SynchronousShutdown; +} + +void FakeVimPlugin::extensionsInitialized() +{ + dd->m_miniBuffer = new MiniBuffer; + StatusBarManager::addStatusBarWidget(dd->m_miniBuffer, StatusBarManager::LastLeftAligned); +} + } // namespace Internal } // namespace FakeVim diff --git a/src/plugins/fakevim/fakevimplugin.h b/src/plugins/fakevim/fakevimplugin.h index c6a925ad2a7..dfdc5a3a30b 100644 --- a/src/plugins/fakevim/fakevimplugin.h +++ b/src/plugins/fakevim/fakevimplugin.h @@ -28,141 +28,6 @@ private: private: friend class FakeVimPluginPrivate; -#ifdef WITH_TESTS -private slots: - void cleanup(); - - void test_vim_movement(); - - void test_vim_target_column_normal(); - void test_vim_target_column_visual_char(); - void test_vim_target_column_visual_block(); - void test_vim_target_column_visual_line(); - void test_vim_target_column_insert(); - void test_vim_target_column_replace(); - - void test_vim_insert(); - void test_vim_fFtT(); - void test_vim_transform_numbers(); - void test_vim_delete(); - - void test_vim_delete_inner_word(); - void test_vim_delete_a_word(); - void test_vim_change_a_word(); - - void test_vim_change_replace(); - - void test_vim_block_selection(); - void test_vim_block_selection_insert(); - - void test_vim_delete_inner_paragraph(); - void test_vim_delete_a_paragraph(); - void test_vim_change_inner_paragraph(); - void test_vim_change_a_paragraph(); - void test_vim_select_inner_paragraph(); - void test_vim_select_a_paragraph(); - - void test_vim_repeat(); - void test_vim_search(); - void test_vim_indent(); - void test_vim_marks(); - void test_vim_jumps(); - void test_vim_current_column(); - void test_vim_copy_paste(); - void test_vim_undo_redo(); - void test_vim_letter_case(); - void test_vim_code_autoindent(); - void test_vim_code_folding(); - void test_vim_code_completion(); - void test_vim_substitute(); - void test_vim_ex_commandbuffer_paste(); - void test_vim_ex_yank(); - void test_vim_ex_delete(); - void test_vim_ex_change(); - void test_vim_ex_shift(); - void test_vim_ex_move(); - void test_vim_ex_join(); - void test_advanced_commands(); - -//public: -// void changeStatusData(const QString &info) { m_statusData = info; } -// void changeStatusMessage(const QString &info, int) { m_statusMessage = info; } -// void changeExtraInformation(const QString &info) { m_infoMessage = info; } - -//private slots: -// // functional tests - void test_vim_indentation(); - - // command mode - void test_vim_command_oO(); - void test_vim_command_put_at_eol(); - void test_vim_command_Cxx_down_dot(); - void test_vim_command_Gyyp(); - void test_vim_command_J(); - void test_vim_command_Yp(); - void test_vim_command_cc(); - void test_vim_command_cw(); - void test_vim_command_cj(); - void test_vim_command_ck(); - void test_vim_command_c_dollar(); - void test_vim_command_C(); - void test_vim_command_dd(); - void test_vim_command_dd_2(); - void test_vim_command_d_dollar(); - void test_vim_command_dgg(); - void test_vim_command_dG(); - void test_vim_command_dj(); - void test_vim_command_dk(); - void test_vim_command_D(); - void test_vim_command_dfx_down(); - void test_vim_command_dollar(); - void test_vim_command_down(); - void test_vim_command_dw(); - void test_vim_command_e(); - void test_vim_command_i(); - void test_vim_command_left(); - void test_vim_command_ma_yank(); - void test_vim_command_r(); - void test_vim_command_right(); - void test_vim_command_up(); - void test_vim_command_w(); - void test_vim_command_x(); - void test_vim_command_yyp(); - void test_vim_command_y_dollar(); - void test_vim_command_percent(); - - void test_vim_visual_d(); - void test_vim_Visual_d(); - void test_vim_visual_block_D(); - - // Plugin emulation - void test_vim_commentary_emulation(); - void test_vim_commentary_file_names(); - void test_vim_replace_with_register_emulation(); - void test_vim_exchange_emulation(); - void test_vim_arg_text_obj_emulation(); - void test_vim_surround_emulation(); - - void test_macros(); - - void test_vim_qtcreator(); - - // special tests - void test_i_cw_i(); - - // map test should be last one since it changes default behaviour - void test_map(); - -//private: -// QString m_statusMessage; -// QString m_statusData; -// QString m_infoMessage; - -private: - struct TestData; - void setup(TestData *data); - void setupTest(QString *title, FakeVimHandler **handler, QWidget **edit); -#endif }; } // namespace Internal From bde92e035e165eb208f89bd8440c67e446a12d94 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Nov 2023 15:51:58 +0100 Subject: [PATCH 0255/1546] FakeVim: Move plugin class definition to .cpp Change-Id: Iac485bbd6cd00ddfae189a6f82c9f5f2c7e9aaf9 Reviewed-by: Reviewed-by: Jarek Kobus --- src/plugins/fakevim/CMakeLists.txt | 2 +- src/plugins/fakevim/fakevim.qbs | 1 - src/plugins/fakevim/fakevimplugin.cpp | 65 ++++++++++++++------------- src/plugins/fakevim/fakevimplugin.h | 34 -------------- 4 files changed, 35 insertions(+), 67 deletions(-) delete mode 100644 src/plugins/fakevim/fakevimplugin.h diff --git a/src/plugins/fakevim/CMakeLists.txt b/src/plugins/fakevim/CMakeLists.txt index 1006bf6b0dd..856f1a7710a 100644 --- a/src/plugins/fakevim/CMakeLists.txt +++ b/src/plugins/fakevim/CMakeLists.txt @@ -5,7 +5,7 @@ add_qtc_plugin(FakeVim fakevim.qrc fakevimactions.cpp fakevimactions.h fakevimhandler.cpp fakevimhandler.h - fakevimplugin.cpp fakevimplugin.h + fakevimplugin.cpp fakevimtr.h ) diff --git a/src/plugins/fakevim/fakevim.qbs b/src/plugins/fakevim/fakevim.qbs index a4dad38428f..ecc682c9361 100644 --- a/src/plugins/fakevim/fakevim.qbs +++ b/src/plugins/fakevim/fakevim.qbs @@ -21,7 +21,6 @@ QtcPlugin { "fakevimhandler.cpp", "fakevimhandler.h", "fakevimplugin.cpp", - "fakevimplugin.h", "fakevimtr.h", ] diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp index c709b46266d..b922e8f2bab 100644 --- a/src/plugins/fakevim/fakevimplugin.cpp +++ b/src/plugins/fakevim/fakevimplugin.cpp @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "fakevimplugin.h" - #include "fakevimactions.h" #include "fakevimhandler.h" #include "fakevimtr.h" @@ -25,6 +23,8 @@ #include #include +#include + #include #include @@ -88,8 +88,7 @@ using namespace TextEditor; using namespace Core; using namespace Utils; -namespace FakeVim { -namespace Internal { +namespace FakeVim::Internal { const char INSTALL_HANDLER[] = "TextEditor.FakeVimHandler"; const char SETTINGS_CATEGORY[] = "D.FakeVim"; @@ -2050,38 +2049,42 @@ static void setupTest(QString *title, FakeVimHandler **handler, QWidget **edit) QObject *createFakeVimTester( void (*setupTest)(QString *, FakeVimHandler **, QWidget **) ); // in fakevim_test.cpp -FakeVimPlugin::FakeVimPlugin() +class FakeVimPlugin : public ExtensionSystem::IPlugin { - addTestCreator([] { return createFakeVimTester(&setupTest); }); - dd = new FakeVimPluginPrivate; -} + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "FakeVim.json") -FakeVimPlugin::~FakeVimPlugin() -{ - delete dd; - dd = nullptr; -} +public: + FakeVimPlugin() + { + addTestCreator([] { return createFakeVimTester(&setupTest); }); + dd = new FakeVimPluginPrivate; + } + ~FakeVimPlugin() override + { + delete dd; + dd = nullptr; + } -void FakeVimPlugin::initialize() -{ - dd->initialize(); -} + ExtensionSystem::IPlugin::ShutdownFlag aboutToShutdown() + { + StatusBarManager::destroyStatusBarWidget(dd->m_miniBuffer); + dd->m_miniBuffer = nullptr; + return SynchronousShutdown; + } -ExtensionSystem::IPlugin::ShutdownFlag FakeVimPlugin::aboutToShutdown() -{ - StatusBarManager::destroyStatusBarWidget(dd->m_miniBuffer); - dd->m_miniBuffer = nullptr; - return SynchronousShutdown; -} + void initialize() override + { + dd->initialize(); + } -void FakeVimPlugin::extensionsInitialized() -{ - dd->m_miniBuffer = new MiniBuffer; - StatusBarManager::addStatusBarWidget(dd->m_miniBuffer, StatusBarManager::LastLeftAligned); -} + void extensionsInitialized() override + { + dd->m_miniBuffer = new MiniBuffer; + StatusBarManager::addStatusBarWidget(dd->m_miniBuffer, StatusBarManager::LastLeftAligned); + } +}; - -} // namespace Internal -} // namespace FakeVim +} // FakeVim::Internal #include "fakevimplugin.moc" diff --git a/src/plugins/fakevim/fakevimplugin.h b/src/plugins/fakevim/fakevimplugin.h deleted file mode 100644 index dfdc5a3a30b..00000000000 --- a/src/plugins/fakevim/fakevimplugin.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace FakeVim { -namespace Internal { - -class FakeVimHandler; - -class FakeVimPlugin : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "FakeVim.json") - -public: - FakeVimPlugin(); - ~FakeVimPlugin() override; - -private: - // implementation of ExtensionSystem::IPlugin - void initialize() override; - ShutdownFlag aboutToShutdown() override; - void extensionsInitialized() override; - -private: - friend class FakeVimPluginPrivate; - -}; - -} // namespace Internal -} // namespace FakeVim From 3b05a6f58ec5c94ea199ffee82d8c99f9725ab96 Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Nov 2023 16:01:52 +0100 Subject: [PATCH 0256/1546] FakeVim: Merge Plugin and PluginPrivate classes There were different from the PluginPrivate-created-in-initialize pattern anyway. Change-Id: I690c9c0511203f3c4d6ec9eeca85c0a277330e2f Reviewed-by: Jarek Kobus --- src/plugins/fakevim/fakevimplugin.cpp | 251 +++++++++++--------------- 1 file changed, 109 insertions(+), 142 deletions(-) diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp index b922e8f2bab..5ac5734866a 100644 --- a/src/plugins/fakevim/fakevimplugin.cpp +++ b/src/plugins/fakevim/fakevimplugin.cpp @@ -96,7 +96,7 @@ const char SETTINGS_ID[] = "A.FakeVim.General"; const char SETTINGS_EX_CMDS_ID[] = "B.FakeVim.ExCommands"; const char SETTINGS_USER_CMDS_ID[] = "C.FakeVim.UserCommands"; -static class FakeVimPluginPrivate *dd = nullptr; +static class FakeVimPlugin *dd = nullptr; class MiniBuffer : public QStackedWidget { @@ -213,8 +213,6 @@ private: class RelativeNumbersColumn : public QWidget { - Q_OBJECT - public: RelativeNumbersColumn(TextEditorWidget *baseTextEditor) : QWidget(baseTextEditor) @@ -332,28 +330,37 @@ private: /////////////////////////////////////////////////////////////////////// // -// FakeVimOptionPage +// FakeVimPlugin // /////////////////////////////////////////////////////////////////////// using ExCommandMap = QMap; using UserCommandMap = QMap; - -/////////////////////////////////////////////////////////////////////// -// -// FakeVimPluginPrivate -// -/////////////////////////////////////////////////////////////////////// - -class FakeVimPluginPrivate : public QObject +class FakeVimPlugin final : public ExtensionSystem::IPlugin { Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "FakeVim.json") public: - FakeVimPluginPrivate(); + FakeVimPlugin(); - void initialize(); + ~FakeVimPlugin() final { dd = nullptr; } + + void initialize() final; + + void extensionsInitialized() final + { + m_miniBuffer = new MiniBuffer; + StatusBarManager::addStatusBarWidget(m_miniBuffer, StatusBarManager::LastLeftAligned); + } + + ExtensionSystem::IPlugin::ShutdownFlag aboutToShutdown() final + { + StatusBarManager::destroyStatusBarWidget(m_miniBuffer); + m_miniBuffer = nullptr; + return SynchronousShutdown; + } void editorOpened(Core::IEditor *); void editorAboutToClose(Core::IEditor *); @@ -964,7 +971,6 @@ IAssistProcessor *FakeVimCompletionAssistProvider::createProcessor(const AssistI return new FakeVimCompletionAssistProcessor(this); } - // FakeVimUserCommandsModel QVariant FakeVimUserCommandsModel::data(const QModelIndex &index, int role) const @@ -993,8 +999,55 @@ bool FakeVimUserCommandsModel::setData(const QModelIndex &index, return true; } -FakeVimPluginPrivate::FakeVimPluginPrivate() +static void setupTest(QString *title, FakeVimHandler **handler, QWidget **edit) { + *title = QString::fromLatin1("test.cpp"); + IEditor *iedit = EditorManager::openEditorWithContents(Id(), title); + EditorManager::activateEditor(iedit); + *edit = iedit->widget(); + *handler = dd->m_editorToHandler.value(iedit, {}).handler; + (*handler)->setupWidget(); + (*handler)->handleCommand("set startofline"); + +// *handler = 0; +// m_statusMessage.clear(); +// m_statusData.clear(); +// m_infoMessage.clear(); +// if (m_textedit) { +// m_textedit->setPlainText(lines); +// QTextCursor tc = m_textedit->textCursor(); +// tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); +// m_textedit->setTextCursor(tc); +// m_textedit->setPlainText(lines); +// *handler = new FakeVimHandler(m_textedit); +// } else { +// m_plaintextedit->setPlainText(lines); +// QTextCursor tc = m_plaintextedit->textCursor(); +// tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); +// m_plaintextedit->setTextCursor(tc); +// m_plaintextedit->setPlainText(lines); +// *handler = new FakeVimHandler(m_plaintextedit); +// } + +// connect(*handler, &FakeVimHandler::commandBufferChanged, +// this, &FakeVimPlugin::changeStatusMessage); +// connect(*handler, &FakeVimHandler::extraInformationChanged, +// this, &FakeVimPlugin::changeExtraInformation); +// connect(*handler, &FakeVimHandler::statusDataChanged, +// this, &FakeVimPlugin::changeStatusData); + +// QCOMPARE(EDITOR(toPlainText()), lines); + (*handler)->handleCommand("set iskeyword=@,48-57,_,192-255,a-z,A-Z"); +} + +QObject *createFakeVimTester( void (*setupTest)(QString *, FakeVimHandler **, QWidget **) ); // in fakevim_test.cpp + +FakeVimPlugin::FakeVimPlugin() +{ + dd = this; + + addTestCreator([] { return createFakeVimTester(&setupTest); }); + m_defaultExCommandMap[CppEditor::Constants::SWITCH_HEADER_SOURCE] = QRegularExpression("^A$"); m_defaultExCommandMap["Coreplugin.OutputPane.previtem"] = @@ -1014,7 +1067,7 @@ FakeVimPluginPrivate::FakeVimPluginPrivate() } } -void FakeVimPluginPrivate::initialize() +void FakeVimPlugin::initialize() { /* // Set completion settings and keep them up to date. @@ -1053,44 +1106,44 @@ void FakeVimPluginPrivate::initialize() connect(ICore::instance(), &ICore::coreAboutToClose, this, [] { // Don't attach to editors anymore. disconnect(EditorManager::instance(), &EditorManager::editorOpened, - dd, &FakeVimPluginPrivate::editorOpened); + dd, &FakeVimPlugin::editorOpened); }); // EditorManager connect(EditorManager::instance(), &EditorManager::editorAboutToClose, - this, &FakeVimPluginPrivate::editorAboutToClose); + this, &FakeVimPlugin::editorAboutToClose); connect(EditorManager::instance(), &EditorManager::editorOpened, - this, &FakeVimPluginPrivate::editorOpened); + this, &FakeVimPlugin::editorOpened); connect(EditorManager::instance(), &EditorManager::currentEditorAboutToChange, - this, &FakeVimPluginPrivate::currentEditorAboutToChange); + this, &FakeVimPlugin::currentEditorAboutToChange); connect(DocumentManager::instance(), &DocumentManager::allDocumentsRenamed, - this, &FakeVimPluginPrivate::allDocumentsRenamed); + this, &FakeVimPlugin::allDocumentsRenamed); connect(DocumentManager::instance(), &DocumentManager::documentRenamed, - this, &FakeVimPluginPrivate::documentRenamed); + this, &FakeVimPlugin::documentRenamed); FakeVimSettings &s = settings(); connect(&s.useFakeVim, &FvBoolAspect::changed, this, [this, &s] { setUseFakeVim(s.useFakeVim()); }); connect(&s.readVimRc, &FvBaseAspect::changed, - this, &FakeVimPluginPrivate::maybeReadVimRc); + this, &FakeVimPlugin::maybeReadVimRc); connect(&s.vimRcPath, &FvBaseAspect::changed, - this, &FakeVimPluginPrivate::maybeReadVimRc); + this, &FakeVimPlugin::maybeReadVimRc); connect(&s.relativeNumber, &FvBoolAspect::changed, this, [this, &s] { setShowRelativeLineNumbers(s.relativeNumber()); }); connect(&s.blinkingCursor, &FvBoolAspect::changed, this, [this, &s] { setCursorBlinking(s.blinkingCursor()); }); // Delayed operations. - connect(this, &FakeVimPluginPrivate::delayedQuitRequested, - this, &FakeVimPluginPrivate::handleDelayedQuit, Qt::QueuedConnection); - connect(this, &FakeVimPluginPrivate::delayedQuitAllRequested, - this, &FakeVimPluginPrivate::handleDelayedQuitAll, Qt::QueuedConnection); + connect(this, &FakeVimPlugin::delayedQuitRequested, + this, &FakeVimPlugin::handleDelayedQuit, Qt::QueuedConnection); + connect(this, &FakeVimPlugin::delayedQuitAllRequested, + this, &FakeVimPlugin::handleDelayedQuitAll, Qt::QueuedConnection); setCursorBlinking(s.blinkingCursor()); } -void FakeVimPluginPrivate::userActionTriggered(int key) +void FakeVimPlugin::userActionTriggered(int key) { IEditor *editor = EditorManager::currentEditor(); FakeVimHandler *handler = m_editorToHandler[editor].handler; @@ -1108,7 +1161,7 @@ void FakeVimPluginPrivate::userActionTriggered(int key) } } -void FakeVimPluginPrivate::updateAllHightLights() +void FakeVimPlugin::updateAllHightLights() { const QList editors = EditorManager::visibleEditors(); for (IEditor *editor : editors) { @@ -1118,7 +1171,7 @@ void FakeVimPluginPrivate::updateAllHightLights() } } -void FakeVimPluginPrivate::createRelativeNumberWidget(IEditor *editor) +void FakeVimPlugin::createRelativeNumberWidget(IEditor *editor) { if (auto textEditor = TextEditorWidget::fromEditor(editor)) { auto relativeNumbers = new RelativeNumbersColumn(textEditor); @@ -1130,7 +1183,7 @@ void FakeVimPluginPrivate::createRelativeNumberWidget(IEditor *editor) } } -void FakeVimPluginPrivate::readSettings() +void FakeVimPlugin::readSettings() { QtcSettings *settings = ICore::settings(); @@ -1157,7 +1210,7 @@ void FakeVimPluginPrivate::readSettings() settings->endArray(); } -void FakeVimPluginPrivate::maybeReadVimRc() +void FakeVimPlugin::maybeReadVimRc() { //qDebug() << theFakeVimSetting(ConfigReadVimRc) // << theFakeVimSetting(ConfigReadVimRc)->value(); @@ -1186,7 +1239,7 @@ static void triggerAction(Id id) action->trigger(); } -void FakeVimPluginPrivate::setActionChecked(Id id, bool check) +void FakeVimPlugin::setActionChecked(Id id, bool check) { Command *cmd = ActionManager::command(id); QTC_ASSERT(cmd, return); @@ -1237,7 +1290,7 @@ static int moveDownWeight(const QRect &cursor, const QRect &other) return w; } -void FakeVimPluginPrivate::moveSomewhere(FakeVimHandler *handler, DistFunction f, int count) +void FakeVimPlugin::moveSomewhere(FakeVimHandler *handler, DistFunction f, int count) { QTC_ASSERT(handler, return); QWidget *w = handler->widget(); @@ -1281,7 +1334,7 @@ void FakeVimPluginPrivate::moveSomewhere(FakeVimHandler *handler, DistFunction f EditorManager::activateEditor(bestEditor); } -void FakeVimPluginPrivate::keepOnlyWindow() +void FakeVimPlugin::keepOnlyWindow() { IEditor *currentEditor = EditorManager::currentEditor(); QList editors = EditorManager::visibleEditors(); @@ -1293,7 +1346,7 @@ void FakeVimPluginPrivate::keepOnlyWindow() } } -void FakeVimPluginPrivate::fold(FakeVimHandler *handler, int depth, bool fold) +void FakeVimPlugin::fold(FakeVimHandler *handler, int depth, bool fold) { QTC_ASSERT(handler, return); QTextDocument *doc = handler->textCursor().document(); @@ -1368,7 +1421,7 @@ public: } }; -void FakeVimPluginPrivate::editorOpened(IEditor *editor) +void FakeVimPlugin::editorOpened(IEditor *editor) { if (!editor) return; @@ -1741,31 +1794,31 @@ void FakeVimPluginPrivate::editorOpened(IEditor *editor) } } -void FakeVimPluginPrivate::editorAboutToClose(IEditor *editor) +void FakeVimPlugin::editorAboutToClose(IEditor *editor) { //qDebug() << "CLOSING: " << editor << editor->widget(); m_editorToHandler.remove(editor); } -void FakeVimPluginPrivate::currentEditorAboutToChange(IEditor *editor) +void FakeVimPlugin::currentEditorAboutToChange(IEditor *editor) { if (FakeVimHandler *handler = m_editorToHandler.value(editor, {}).handler) handler->enterCommandMode(); } -void FakeVimPluginPrivate::allDocumentsRenamed(const FilePath &oldPath, const FilePath &newPath) +void FakeVimPlugin::allDocumentsRenamed(const FilePath &oldPath, const FilePath &newPath) { renameFileNameInEditors(oldPath, newPath); FakeVimHandler::updateGlobalMarksFilenames(oldPath.toString(), newPath.toString()); } -void FakeVimPluginPrivate::documentRenamed( +void FakeVimPlugin::documentRenamed( IDocument *, const FilePath &oldPath, const FilePath &newPath) { renameFileNameInEditors(oldPath, newPath); } -void FakeVimPluginPrivate::renameFileNameInEditors(const FilePath &oldPath, const FilePath &newPath) +void FakeVimPlugin::renameFileNameInEditors(const FilePath &oldPath, const FilePath &newPath) { for (const HandlerAndData &handlerAndData : m_editorToHandler) { if (handlerAndData.handler->currentFileName() == oldPath.toString()) @@ -1773,7 +1826,7 @@ void FakeVimPluginPrivate::renameFileNameInEditors(const FilePath &oldPath, cons } } -void FakeVimPluginPrivate::setUseFakeVim(bool on) +void FakeVimPlugin::setUseFakeVim(bool on) { //qDebug() << "SET USE FAKEVIM" << on; Find::setUseFakeVim(on); @@ -1782,7 +1835,7 @@ void FakeVimPluginPrivate::setUseFakeVim(bool on) setCursorBlinking(settings().blinkingCursor()); } -void FakeVimPluginPrivate::setUseFakeVimInternal(bool on) +void FakeVimPlugin::setUseFakeVimInternal(bool on) { if (on) { //ICore *core = ICore::instance(); @@ -1805,7 +1858,7 @@ void FakeVimPluginPrivate::setUseFakeVimInternal(bool on) } } -void FakeVimPluginPrivate::setShowRelativeLineNumbers(bool on) +void FakeVimPlugin::setShowRelativeLineNumbers(bool on) { if (on && settings().useFakeVim()) { for (auto it = m_editorToHandler.constBegin(); it != m_editorToHandler.constEnd(); ++it) @@ -1813,7 +1866,7 @@ void FakeVimPluginPrivate::setShowRelativeLineNumbers(bool on) } } -void FakeVimPluginPrivate::setCursorBlinking(bool on) +void FakeVimPlugin::setCursorBlinking(bool on) { if (m_savedCursorFlashTime == 0) m_savedCursorFlashTime = QGuiApplication::styleHints()->cursorFlashTime(); @@ -1822,7 +1875,7 @@ void FakeVimPluginPrivate::setCursorBlinking(bool on) QGuiApplication::styleHints()->setCursorFlashTime(blink ? m_savedCursorFlashTime : 0); } -void FakeVimPluginPrivate::handleExCommand(FakeVimHandler *handler, bool *handled, const ExCommand &cmd) +void FakeVimPlugin::handleExCommand(FakeVimHandler *handler, bool *handled, const ExCommand &cmd) { QTC_ASSERT(handler, return); using namespace Core; @@ -1944,7 +1997,7 @@ void FakeVimPluginPrivate::handleExCommand(FakeVimHandler *handler, bool *handle } } -void FakeVimPluginPrivate::handleDelayedQuit(bool forced, IEditor *editor) +void FakeVimPlugin::handleDelayedQuit(bool forced, IEditor *editor) { // This tries to simulate vim behaviour. But the models of vim and // Qt Creator core do not match well... @@ -1954,23 +2007,23 @@ void FakeVimPluginPrivate::handleDelayedQuit(bool forced, IEditor *editor) EditorManager::closeEditors({editor}, !forced); } -void FakeVimPluginPrivate::handleDelayedQuitAll(bool forced) +void FakeVimPlugin::handleDelayedQuitAll(bool forced) { triggerAction(Core::Constants::REMOVE_ALL_SPLITS); EditorManager::closeAllEditors(!forced); } -void FakeVimPluginPrivate::quitFakeVim() +void FakeVimPlugin::quitFakeVim() { settings().useFakeVim.setValue(false); } -void FakeVimPluginPrivate::resetCommandBuffer() +void FakeVimPlugin::resetCommandBuffer() { showCommandBuffer(nullptr, QString(), -1, -1, 0); } -void FakeVimPluginPrivate::showCommandBuffer(FakeVimHandler *handler, const QString &contents, int cursorPos, int anchorPos, +void FakeVimPlugin::showCommandBuffer(FakeVimHandler *handler, const QString &contents, int cursorPos, int anchorPos, int messageLevel) { //qDebug() << "SHOW COMMAND BUFFER" << contents; @@ -1978,7 +2031,7 @@ void FakeVimPluginPrivate::showCommandBuffer(FakeVimHandler *handler, const QStr m_miniBuffer->setContents(contents, cursorPos, anchorPos, messageLevel, handler); } -int FakeVimPluginPrivate::currentFile() const +int FakeVimPlugin::currentFile() const { IEditor *editor = EditorManager::currentEditor(); if (editor) { @@ -1989,7 +2042,7 @@ int FakeVimPluginPrivate::currentFile() const return -1; } -void FakeVimPluginPrivate::switchToFile(int n) +void FakeVimPlugin::switchToFile(int n) { int size = DocumentModel::entryCount(); QTC_ASSERT(size, return); @@ -1999,92 +2052,6 @@ void FakeVimPluginPrivate::switchToFile(int n) EditorManager::activateEditorForEntry(DocumentModel::entries().at(n)); } - -/////////////////////////////////////////////////////////////////////// -// -// FakeVimPlugin -// -/////////////////////////////////////////////////////////////////////// - -static void setupTest(QString *title, FakeVimHandler **handler, QWidget **edit) -{ - *title = QString::fromLatin1("test.cpp"); - IEditor *iedit = EditorManager::openEditorWithContents(Id(), title); - EditorManager::activateEditor(iedit); - *edit = iedit->widget(); - *handler = dd->m_editorToHandler.value(iedit, {}).handler; - (*handler)->setupWidget(); - (*handler)->handleCommand("set startofline"); - -// *handler = 0; -// m_statusMessage.clear(); -// m_statusData.clear(); -// m_infoMessage.clear(); -// if (m_textedit) { -// m_textedit->setPlainText(lines); -// QTextCursor tc = m_textedit->textCursor(); -// tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); -// m_textedit->setTextCursor(tc); -// m_textedit->setPlainText(lines); -// *handler = new FakeVimHandler(m_textedit); -// } else { -// m_plaintextedit->setPlainText(lines); -// QTextCursor tc = m_plaintextedit->textCursor(); -// tc.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); -// m_plaintextedit->setTextCursor(tc); -// m_plaintextedit->setPlainText(lines); -// *handler = new FakeVimHandler(m_plaintextedit); -// } - -// connect(*handler, &FakeVimHandler::commandBufferChanged, -// this, &FakeVimPlugin::changeStatusMessage); -// connect(*handler, &FakeVimHandler::extraInformationChanged, -// this, &FakeVimPlugin::changeExtraInformation); -// connect(*handler, &FakeVimHandler::statusDataChanged, -// this, &FakeVimPlugin::changeStatusData); - -// QCOMPARE(EDITOR(toPlainText()), lines); - (*handler)->handleCommand("set iskeyword=@,48-57,_,192-255,a-z,A-Z"); -} - -QObject *createFakeVimTester( void (*setupTest)(QString *, FakeVimHandler **, QWidget **) ); // in fakevim_test.cpp - -class FakeVimPlugin : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "FakeVim.json") - -public: - FakeVimPlugin() - { - addTestCreator([] { return createFakeVimTester(&setupTest); }); - dd = new FakeVimPluginPrivate; - } - ~FakeVimPlugin() override - { - delete dd; - dd = nullptr; - } - - ExtensionSystem::IPlugin::ShutdownFlag aboutToShutdown() - { - StatusBarManager::destroyStatusBarWidget(dd->m_miniBuffer); - dd->m_miniBuffer = nullptr; - return SynchronousShutdown; - } - - void initialize() override - { - dd->initialize(); - } - - void extensionsInitialized() override - { - dd->m_miniBuffer = new MiniBuffer; - StatusBarManager::addStatusBarWidget(dd->m_miniBuffer, StatusBarManager::LastLeftAligned); - } -}; - } // FakeVim::Internal #include "fakevimplugin.moc" From 65dbc1eaf636b7b9af0fd71d8397658ad0527392 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 16:42:04 +0100 Subject: [PATCH 0257/1546] ImageViewer: Use new plugin setup system Change-Id: Ie2178c6b38a0b122ab225bae30ea25e1c57b73ad Reviewed-by: Jarek Kobus --- src/plugins/imageviewer/CMakeLists.txt | 2 +- src/plugins/imageviewer/imageviewer.cpp | 74 +++++++++-- src/plugins/imageviewer/imageviewer.h | 8 +- src/plugins/imageviewer/imageviewer.qbs | 1 - src/plugins/imageviewer/imageviewerplugin.cpp | 117 ++---------------- src/plugins/imageviewer/imageviewerplugin.h | 26 ---- 6 files changed, 77 insertions(+), 151 deletions(-) delete mode 100644 src/plugins/imageviewer/imageviewerplugin.h diff --git a/src/plugins/imageviewer/CMakeLists.txt b/src/plugins/imageviewer/CMakeLists.txt index 38659e8417a..dfa80763dd4 100644 --- a/src/plugins/imageviewer/CMakeLists.txt +++ b/src/plugins/imageviewer/CMakeLists.txt @@ -12,7 +12,7 @@ add_qtc_plugin(ImageViewer imageviewer.cpp imageviewer.h imageviewerconstants.h imageviewerfile.cpp imageviewerfile.h - imageviewerplugin.cpp imageviewerplugin.h + imageviewerplugin.cpp imageviewertr.h multiexportdialog.cpp multiexportdialog.h EXPLICIT_MOC imageviewer.h diff --git a/src/plugins/imageviewer/imageviewer.cpp b/src/plugins/imageviewer/imageviewer.cpp index d1893b703ae..d7694e654dc 100644 --- a/src/plugins/imageviewer/imageviewer.cpp +++ b/src/plugins/imageviewer/imageviewer.cpp @@ -9,11 +9,14 @@ #include "imageviewerfile.h" #include "imageviewertr.h" -#include #include #include -#include #include +#include +#include +#include +#include +#include #include #include @@ -390,15 +393,68 @@ void ImageViewer::updatePauseAction() // Factory -ImageViewerFactory::ImageViewerFactory() +class ImageViewerFactory final : public Core::IEditorFactory { - setId(Constants::IMAGEVIEWER_ID); - setDisplayName(Tr::tr("Image Viewer")); - setEditorCreator([] { return new ImageViewer; }); +public: + ImageViewerFactory() + { + setId(Constants::IMAGEVIEWER_ID); + setDisplayName(Tr::tr("Image Viewer")); + setEditorCreator([] { return new ImageViewer; }); - const QList supportedMimeTypes = QImageReader::supportedMimeTypes(); - for (const QByteArray &format : supportedMimeTypes) - addMimeType(QString::fromLatin1(format)); + const QList supportedMimeTypes = QImageReader::supportedMimeTypes(); + for (const QByteArray &format : supportedMimeTypes) + addMimeType(QString::fromLatin1(format)); + } +}; + +static void createAction(QObject *guard, Id id, + const std::function &onTriggered, + const QString &title = {}, + const QKeySequence &key = {}) +{ + ActionBuilder builder(guard, id); + builder.setText(title); + builder.setContext(Context(Constants::IMAGEVIEWER_ID)); + if (!key.isEmpty()) + builder.setDefaultKeySequence(key); + + builder.setOnTriggered(guard, [onTriggered] { + if (auto iv = qobject_cast(EditorManager::currentEditor())) + onTriggered(iv); + }); +} + +void setupImageViewer(QObject *guard) +{ + static ImageViewerFactory theImageViewerFactory; + + createAction(guard, Core::Constants::ZOOM_IN, &ImageViewer::zoomIn); + + createAction(guard, Core::Constants::ZOOM_OUT, &ImageViewer::zoomOut); + + createAction(guard, Core::Constants::ZOOM_RESET, &ImageViewer::resetToOriginalSize); + + createAction(guard, Constants::ACTION_FIT_TO_SCREEN, &ImageViewer::fitToScreen, + Tr::tr("Fit to Screen"), Tr::tr("Ctrl+=")); + + createAction( guard, Constants::ACTION_BACKGROUND, &ImageViewer::switchViewBackground, + Tr::tr("Switch Background"), Tr::tr("Ctrl+[")); + + createAction(guard, Constants::ACTION_OUTLINE, &ImageViewer::switchViewOutline, + Tr::tr("Switch Outline"), Tr::tr("Ctrl+]")); + + createAction(guard, Constants::ACTION_TOGGLE_ANIMATION, &ImageViewer::togglePlay, + Tr::tr("Toggle Animation")); + + createAction(guard, Constants::ACTION_EXPORT_IMAGE, &ImageViewer::exportImage, + Tr::tr("Export Image")); + + createAction(guard, Constants::ACTION_EXPORT_MULTI_IMAGES, &ImageViewer::exportMultiImages, + Tr::tr("Export Multiple Images")); + + createAction(guard, Constants::ACTION_COPY_DATA_URL, &ImageViewer::copyDataUrl, + Tr::tr("Copy as Data URL")); } } // ImageViewer::Internal diff --git a/src/plugins/imageviewer/imageviewer.h b/src/plugins/imageviewer/imageviewer.h index e2e7deea79d..22b535b22fb 100644 --- a/src/plugins/imageviewer/imageviewer.h +++ b/src/plugins/imageviewer/imageviewer.h @@ -5,8 +5,6 @@ #pragma once #include -#include -#include namespace ImageViewer::Internal { @@ -49,10 +47,6 @@ private: struct ImageViewerPrivate *d; }; -class ImageViewerFactory final : public Core::IEditorFactory -{ -public: - ImageViewerFactory(); -}; +void setupImageViewer(QObject *guard); } // ImageViewer::Internal diff --git a/src/plugins/imageviewer/imageviewer.qbs b/src/plugins/imageviewer/imageviewer.qbs index 4731cbffb5b..de601bc8b09 100644 --- a/src/plugins/imageviewer/imageviewer.qbs +++ b/src/plugins/imageviewer/imageviewer.qbs @@ -26,7 +26,6 @@ QtcPlugin { "imageviewerfile.cpp", "imageviewerfile.h", "imageviewerplugin.cpp", - "imageviewerplugin.h", "imageviewertr.h", ] } diff --git a/src/plugins/imageviewer/imageviewerplugin.cpp b/src/plugins/imageviewer/imageviewerplugin.cpp index 9805c4ef3d2..a8088a02395 100644 --- a/src/plugins/imageviewer/imageviewerplugin.cpp +++ b/src/plugins/imageviewer/imageviewerplugin.cpp @@ -2,121 +2,24 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "imageviewerplugin.h" - #include "imageviewer.h" -#include "imageviewerconstants.h" -#include "imageviewertr.h" -#include -#include -#include -#include -#include - -#include -#include -#include - -using namespace Core; -using namespace Utils; +#include namespace ImageViewer::Internal { -class ImageViewerAction final : public QAction +class ImageViewerPlugin : public ExtensionSystem::IPlugin { -public: - ImageViewerAction(Id id, - const std::function &onTriggered, - const QString &title = {}, - const QKeySequence &key = {}) - : QAction(title) - { - Command *command = ActionManager::registerAction(this, id, Context(Constants::IMAGEVIEWER_ID)); - if (!key.isEmpty()) - command->setDefaultKeySequence(key); + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "ImageViewer.json") - connect(this, &QAction::triggered, this, [onTriggered] { - if (auto iv = qobject_cast(EditorManager::currentEditor())) - onTriggered(iv); - }); +public: + void initialize() final + { + setupImageViewer(this); } }; -class ImageViewerPluginPrivate final -{ -public: - ImageViewerFactory imageViewerFactory; - - ImageViewerAction zoomInAction { - Core::Constants::ZOOM_IN, - &ImageViewer::zoomIn - }; - - ImageViewerAction zoomOutAction { - Core::Constants::ZOOM_OUT, - &ImageViewer::zoomOut - }; - - ImageViewerAction zoomResetAction { - Core::Constants::ZOOM_RESET, - &ImageViewer::resetToOriginalSize - }; - - ImageViewerAction fitToScreenAction { - Constants::ACTION_FIT_TO_SCREEN, - &ImageViewer::fitToScreen, - Tr::tr("Fit to Screen"), - Tr::tr("Ctrl+=") - }; - - ImageViewerAction switchBackgroundAction { - Constants::ACTION_BACKGROUND, - &ImageViewer::switchViewBackground, - Tr::tr("Switch Background"), - Tr::tr("Ctrl+[") - }; - - ImageViewerAction switchOutlineAction { - Constants::ACTION_OUTLINE, - &ImageViewer::switchViewOutline, - Tr::tr("Switch Outline"), - Tr::tr("Ctrl+]") - }; - - ImageViewerAction toggleAnimationAction { - Constants::ACTION_TOGGLE_ANIMATION, - &ImageViewer::togglePlay, - Tr::tr("Toggle Animation") - }; - - ImageViewerAction exportImageAction { - Constants::ACTION_EXPORT_IMAGE, - &ImageViewer::exportImage, - Tr::tr("Export Image") - }; - - ImageViewerAction exportMulitImagesAction { - Constants::ACTION_EXPORT_MULTI_IMAGES, - &ImageViewer::exportMultiImages, - Tr::tr("Export Multiple Images"), - }; - - ImageViewerAction copyDataUrlAction { - Constants::ACTION_COPY_DATA_URL, - &ImageViewer::copyDataUrl, - Tr::tr("Copy as Data URL"), - }; -}; - -ImageViewerPlugin::~ImageViewerPlugin() -{ - delete d; -} - -void ImageViewerPlugin::initialize() -{ - d = new ImageViewerPluginPrivate; -} - } // ImageViewer::Internal + +#include "imageviewerplugin.moc" diff --git a/src/plugins/imageviewer/imageviewerplugin.h b/src/plugins/imageviewer/imageviewerplugin.h deleted file mode 100644 index bb2253c6a3e..00000000000 --- a/src/plugins/imageviewer/imageviewerplugin.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2016 Denis Mingulov. -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace ImageViewer::Internal { - -class ImageViewerPlugin : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "ImageViewer.json") - -public: - ImageViewerPlugin() = default; - ~ImageViewerPlugin(); - -private: - void initialize() final; - - class ImageViewerPluginPrivate *d = nullptr; -}; - -} // ImageViewer::Internal From 43f1281674eb00fb0f2140d9386feaf44998639b Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 13:18:39 +0100 Subject: [PATCH 0258/1546] Qnx: Use new setup scheme for most factories Change-Id: Ie6154d816fb9d77948d73416b43bb933a56f6bbb Reviewed-by: Jarek Kobus --- src/plugins/qnx/qnxanalyzesupport.cpp | 17 ++++++-- src/plugins/qnx/qnxanalyzesupport.h | 8 +--- src/plugins/qnx/qnxdebugsupport.cpp | 17 ++++++-- src/plugins/qnx/qnxdebugsupport.h | 9 +--- src/plugins/qnx/qnxdevice.cpp | 36 ++++++++++------ src/plugins/qnx/qnxdevice.h | 8 +--- src/plugins/qnx/qnxplugin.cpp | 33 +++++++++------ src/plugins/qnx/qnxqtversion.cpp | 19 ++++++--- src/plugins/qnx/qnxqtversion.h | 6 +-- src/plugins/qnx/qnxrunconfiguration.cpp | 16 +++++-- src/plugins/qnx/qnxrunconfiguration.h | 8 +--- src/plugins/qnx/qnxtoolchain.cpp | 55 ++++++++++++++----------- src/plugins/qnx/qnxtoolchain.h | 13 +----- 13 files changed, 134 insertions(+), 111 deletions(-) diff --git a/src/plugins/qnx/qnxanalyzesupport.cpp b/src/plugins/qnx/qnxanalyzesupport.cpp index 4d5a73b2ab5..fe87c15eafd 100644 --- a/src/plugins/qnx/qnxanalyzesupport.cpp +++ b/src/plugins/qnx/qnxanalyzesupport.cpp @@ -48,11 +48,20 @@ public: } }; -QnxQmlProfilerWorkerFactory::QnxQmlProfilerWorkerFactory() +class QnxQmlProfilerWorkerFactory final : public RunWorkerFactory { - setProduct(); - // FIXME: Shouldn't this use the run mode id somehow? - addSupportedRunConfig(Constants::QNX_RUNCONFIG_ID); +public: + QnxQmlProfilerWorkerFactory() + { + setProduct(); + // FIXME: Shouldn't this use the run mode id somehow? + addSupportedRunConfig(Constants::QNX_RUNCONFIG_ID); + } +}; + +void setupQnxQmlProfiler() +{ + static QnxQmlProfilerWorkerFactory theQnxQmlProfilerWorkerFactory; } } // Qnx::Internal diff --git a/src/plugins/qnx/qnxanalyzesupport.h b/src/plugins/qnx/qnxanalyzesupport.h index 7797f21d30e..74b2473dea9 100644 --- a/src/plugins/qnx/qnxanalyzesupport.h +++ b/src/plugins/qnx/qnxanalyzesupport.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace Qnx::Internal { -class QnxQmlProfilerWorkerFactory final : public ProjectExplorer::RunWorkerFactory -{ -public: - QnxQmlProfilerWorkerFactory(); -}; +void setupQnxQmlProfiler(); } // Qnx::Internal diff --git a/src/plugins/qnx/qnxdebugsupport.cpp b/src/plugins/qnx/qnxdebugsupport.cpp index 7d915bb70c8..b2d923f2cbe 100644 --- a/src/plugins/qnx/qnxdebugsupport.cpp +++ b/src/plugins/qnx/qnxdebugsupport.cpp @@ -252,11 +252,20 @@ void showAttachToProcessDialog() // QnxDebugWorkerFactory -QnxDebugWorkerFactory::QnxDebugWorkerFactory() +class QnxDebugWorkerFactory final : public RunWorkerFactory { - setProduct(); - addSupportedRunMode(ProjectExplorer::Constants::DEBUG_RUN_MODE); - addSupportedRunConfig(Constants::QNX_RUNCONFIG_ID); +public: + QnxDebugWorkerFactory() + { + setProduct(); + addSupportedRunMode(ProjectExplorer::Constants::DEBUG_RUN_MODE); + addSupportedRunConfig(Constants::QNX_RUNCONFIG_ID); + } +}; + +void setupQnxDebugging() +{ + static QnxDebugWorkerFactory theQnxDebugWorkerFactory; } } // Qnx::Internal diff --git a/src/plugins/qnx/qnxdebugsupport.h b/src/plugins/qnx/qnxdebugsupport.h index 3cbb6ef7fea..8f5f3102831 100644 --- a/src/plugins/qnx/qnxdebugsupport.h +++ b/src/plugins/qnx/qnxdebugsupport.h @@ -3,16 +3,9 @@ #pragma once -#include - namespace Qnx::Internal { void showAttachToProcessDialog(); - -class QnxDebugWorkerFactory final : public ProjectExplorer::RunWorkerFactory -{ -public: - QnxDebugWorkerFactory(); -}; +void setupQnxDebugging(); } // Qnx::Internal diff --git a/src/plugins/qnx/qnxdevice.cpp b/src/plugins/qnx/qnxdevice.cpp index 5083fbb782a..3ec51317413 100644 --- a/src/plugins/qnx/qnxdevice.cpp +++ b/src/plugins/qnx/qnxdevice.cpp @@ -10,6 +10,7 @@ #include +#include #include #include @@ -86,20 +87,29 @@ public: DeviceTester *createDeviceTester() const final { return new QnxDeviceTester; } }; -QnxDeviceFactory::QnxDeviceFactory() : IDeviceFactory(Constants::QNX_QNX_OS_TYPE) +class QnxDeviceFactory final : public IDeviceFactory { - setDisplayName(Tr::tr("QNX Device")); - setCombinedIcon(":/qnx/images/qnxdevicesmall.png", - ":/qnx/images/qnxdevice.png"); - setQuickCreationAllowed(true); - setConstructionFunction([] { return IDevice::Ptr(new QnxDevice); }); - setCreator([]() -> IDevice::Ptr { - const IDevice::Ptr device = IDevice::Ptr(new QnxDevice); - SshDeviceWizard wizard(Tr::tr("New QNX Device Configuration Setup"), device); - if (wizard.exec() != QDialog::Accepted) - return {}; - return device; - }); +public: + QnxDeviceFactory() : IDeviceFactory(Constants::QNX_QNX_OS_TYPE) + { + setDisplayName(Tr::tr("QNX Device")); + setCombinedIcon(":/qnx/images/qnxdevicesmall.png", + ":/qnx/images/qnxdevice.png"); + setQuickCreationAllowed(true); + setConstructionFunction([] { return IDevice::Ptr(new QnxDevice); }); + setCreator([]() -> IDevice::Ptr { + const IDevice::Ptr device = IDevice::Ptr(new QnxDevice); + SshDeviceWizard wizard(Tr::tr("New QNX Device Configuration Setup"), device); + if (wizard.exec() != QDialog::Accepted) + return {}; + return device; + }); + } +}; + +void setupQnxDevice() +{ + static QnxDeviceFactory theQnxDeviceFactory; } } // Qnx::Internal diff --git a/src/plugins/qnx/qnxdevice.h b/src/plugins/qnx/qnxdevice.h index c4b484f478c..3e5c4e63177 100644 --- a/src/plugins/qnx/qnxdevice.h +++ b/src/plugins/qnx/qnxdevice.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace Qnx::Internal { -class QnxDeviceFactory final : public ProjectExplorer::IDeviceFactory -{ -public: - QnxDeviceFactory(); -}; +void setupQnxDevice(); } // Qnx::Internal diff --git a/src/plugins/qnx/qnxplugin.cpp b/src/plugins/qnx/qnxplugin.cpp index bd2aa2d8b18..3e6ae206e47 100644 --- a/src/plugins/qnx/qnxplugin.cpp +++ b/src/plugins/qnx/qnxplugin.cpp @@ -71,6 +71,14 @@ public: } }; +void setupQnxDeployment() +{ + static QnxDeployConfigurationFactory deployConfigFactory; + static QnxDeployStepFactory directUploadDeployFactory{RemoteLinux::Constants::DirectUploadStepId, + Constants::QNX_DIRECT_UPLOAD_STEP_ID}; + static QnxDeployStepFactory makeInstallStepFactory{RemoteLinux::Constants::MakeInstallStepId}; +} + class QnxPluginPrivate { public: @@ -80,17 +88,6 @@ public: QAction m_attachToQnxApplication{Tr::tr("Attach to remote QNX application..."), nullptr}; QnxSettingsPage settingsPage; - QnxQtVersionFactory qtVersionFactory; - QnxDeviceFactory deviceFactory; - QnxDeployConfigurationFactory deployConfigFactory; - QnxDeployStepFactory directUploadDeployFactory{RemoteLinux::Constants::DirectUploadStepId, - Constants::QNX_DIRECT_UPLOAD_STEP_ID}; - QnxDeployStepFactory makeInstallStepFactory{RemoteLinux::Constants::MakeInstallStepId}; - QnxRunConfigurationFactory runConfigFactory; - QnxToolChainFactory toolChainFactory; - SimpleTargetRunnerFactory runWorkerFactory{{runConfigFactory.runConfigurationId()}}; - QnxDebugWorkerFactory debugWorkerFactory; - QnxQmlProfilerWorkerFactory qmlProfilerWorkerFactory; }; class QnxPlugin final : public ExtensionSystem::IPlugin @@ -102,7 +99,19 @@ public: ~QnxPlugin() final { delete d; } private: - void initialize() final { d = new QnxPluginPrivate; } + void initialize() final + { + d = new QnxPluginPrivate; + + setupQnxDevice(); + setupQnxToolChain(); + setupQnxQtVersion(); + setupQnxDeployment(); + setupQnxRunnning(); + setupQnxDebugging(); + setupQnxQmlProfiler(); + } + void extensionsInitialized() final; QnxPluginPrivate *d = nullptr; diff --git a/src/plugins/qnx/qnxqtversion.cpp b/src/plugins/qnx/qnxqtversion.cpp index b5360c272df..6a74d620dbc 100644 --- a/src/plugins/qnx/qnxqtversion.cpp +++ b/src/plugins/qnx/qnxqtversion.cpp @@ -190,12 +190,21 @@ EnvironmentItems QnxQtVersion::environment() const // Factory -QnxQtVersionFactory::QnxQtVersionFactory() +class QnxQtVersionFactory : public QtSupport::QtVersionFactory { - setQtVersionCreator([] { return new QnxQtVersion; }); - setSupportedType(Constants::QNX_QNX_QT); - setPriority(50); - setRestrictionChecker([](const SetupData &setup) { return setup.isQnx; }); +public: + QnxQtVersionFactory() + { + setQtVersionCreator([] { return new QnxQtVersion; }); + setSupportedType(Constants::QNX_QNX_QT); + setPriority(50); + setRestrictionChecker([](const SetupData &setup) { return setup.isQnx; }); + } +}; + +void setupQnxQtVersion() +{ + static QnxQtVersionFactory theQnxQtVersionFactory; } } // Qnx::Internal diff --git a/src/plugins/qnx/qnxqtversion.h b/src/plugins/qnx/qnxqtversion.h index 7c3e81dac9f..db6c47666d8 100644 --- a/src/plugins/qnx/qnxqtversion.h +++ b/src/plugins/qnx/qnxqtversion.h @@ -57,10 +57,6 @@ private: mutable Utils::EnvironmentItems m_qnxEnv; }; -class QnxQtVersionFactory : public QtSupport::QtVersionFactory -{ -public: - QnxQtVersionFactory(); -}; +void setupQnxQtVersion(); } // Qnx::Internal diff --git a/src/plugins/qnx/qnxrunconfiguration.cpp b/src/plugins/qnx/qnxrunconfiguration.cpp index 26616e4e252..ebab271238d 100644 --- a/src/plugins/qnx/qnxrunconfiguration.cpp +++ b/src/plugins/qnx/qnxrunconfiguration.cpp @@ -84,10 +84,20 @@ public: // QnxRunConfigurationFactory -QnxRunConfigurationFactory::QnxRunConfigurationFactory() +class QnxRunConfigurationFactory final : public ProjectExplorer::RunConfigurationFactory { - registerRunConfiguration(Constants::QNX_RUNCONFIG_ID); - addSupportedTargetDeviceType(Constants::QNX_QNX_OS_TYPE); +public: + QnxRunConfigurationFactory() + { + registerRunConfiguration(Constants::QNX_RUNCONFIG_ID); + addSupportedTargetDeviceType(Constants::QNX_QNX_OS_TYPE); + } +}; + +void setupQnxRunnning() +{ + static QnxRunConfigurationFactory theQnxRunConfigurationFactory; + static SimpleTargetRunnerFactory theQnxRunWorkerFactory({Constants::QNX_RUNCONFIG_ID}); } } // Qnx::Internal diff --git a/src/plugins/qnx/qnxrunconfiguration.h b/src/plugins/qnx/qnxrunconfiguration.h index 9ed696762a0..23166ce0af9 100644 --- a/src/plugins/qnx/qnxrunconfiguration.h +++ b/src/plugins/qnx/qnxrunconfiguration.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace Qnx::Internal { -class QnxRunConfigurationFactory final : public ProjectExplorer::RunConfigurationFactory -{ -public: - QnxRunConfigurationFactory(); -}; +void setupQnxRunnning(); } // Qnx::Internal diff --git a/src/plugins/qnx/qnxtoolchain.cpp b/src/plugins/qnx/qnxtoolchain.cpp index 2e66fecacea..6cf6b715e72 100644 --- a/src/plugins/qnx/qnxtoolchain.cpp +++ b/src/plugins/qnx/qnxtoolchain.cpp @@ -162,30 +162,6 @@ bool QnxToolChain::operator ==(const ToolChain &other) const return sdpPath() == qnxTc->sdpPath() && cpuDir() == qnxTc->cpuDir(); } -// -------------------------------------------------------------------------- -// QnxToolChainFactory -// -------------------------------------------------------------------------- - -QnxToolChainFactory::QnxToolChainFactory() -{ - setDisplayName(Tr::tr("QCC")); - setSupportedToolChainType(Constants::QNX_TOOLCHAIN_ID); - setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID, - ProjectExplorer::Constants::CXX_LANGUAGE_ID}); - setToolchainConstructor([] { return new QnxToolChain; }); - setUserCreatable(true); -} - -Toolchains QnxToolChainFactory::autoDetect(const ToolchainDetector &detector) const -{ - // FIXME: Support detecting toolchains on remote devices - if (detector.device) - return {}; - - Toolchains tcs = QnxSettingsPage::autoDetect(detector.alreadyKnown); - return tcs; -} - //--------------------------------------------------------------------------------- // QnxToolChainConfigWidget //--------------------------------------------------------------------------------- @@ -275,4 +251,35 @@ void QnxToolChainConfigWidget::handleSdpPathChange() emit dirty(); } +// QnxToolChainFactory + +class QnxToolChainFactory : public ToolChainFactory +{ +public: + QnxToolChainFactory() + { + setDisplayName(Tr::tr("QCC")); + setSupportedToolChainType(Constants::QNX_TOOLCHAIN_ID); + setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID, + ProjectExplorer::Constants::CXX_LANGUAGE_ID}); + setToolchainConstructor([] { return new QnxToolChain; }); + setUserCreatable(true); + } + + Toolchains autoDetect(const ToolchainDetector &detector) const final + { + // FIXME: Support detecting toolchains on remote devices + if (detector.device) + return {}; + + Toolchains tcs = QnxSettingsPage::autoDetect(detector.alreadyKnown); + return tcs; + } +}; + +void setupQnxToolChain() +{ + static QnxToolChainFactory theQnxToolChainFactory; +} + } // Qnx::Internal diff --git a/src/plugins/qnx/qnxtoolchain.h b/src/plugins/qnx/qnxtoolchain.h index 7cbdc8f4983..4c028f057cb 100644 --- a/src/plugins/qnx/qnxtoolchain.h +++ b/src/plugins/qnx/qnxtoolchain.h @@ -26,17 +26,6 @@ protected: DetectedAbisResult detectSupportedAbis() const override; }; -// -------------------------------------------------------------------------- -// QnxToolChainFactory -// -------------------------------------------------------------------------- - -class QnxToolChainFactory : public ProjectExplorer::ToolChainFactory -{ -public: - QnxToolChainFactory(); - - ProjectExplorer::Toolchains autoDetect( - const ProjectExplorer::ToolchainDetector &detector) const final; -}; +void setupQnxToolChain(); } // Qnx::Internal From 73bff6d497b04d4fd43acfea9553d357faea3b60 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 13 Nov 2023 13:01:55 +0100 Subject: [PATCH 0259/1546] TaskTree: Fix TimeoutTask ordering Make ordering separate for each thread. Add stress test for it. Change-Id: Idb42ce2511b18c0e9dd4dcb216ca39b35b5c980e Reviewed-by: hjk Reviewed-by: Qt CI Bot --- src/libs/solutions/tasking/tasktree.cpp | 50 +++++---- tests/auto/solutions/tasking/tst_tasking.cpp | 110 +++++++++++++------ 2 files changed, 102 insertions(+), 58 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 71dece59855..bae7c2e17c5 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -2672,46 +2672,51 @@ struct TimerData TimeoutCallback m_callback; }; -QMutex s_mutex; -std::atomic_int s_timerId = 0; -QHash s_timerIdToTimerData = {}; -QMultiMap s_deadlineToTimerId = {}; +struct TimerThreadData +{ + Q_DISABLE_COPY_MOVE(TimerThreadData) + + QHash m_timerIdToTimerData = {}; + QMultiMap m_deadlineToTimerId = {}; + int m_timerIdCounter = 0; +}; + +// Please note the thread_local keyword below guarantees a separate instance per thread. +static thread_local TimerThreadData s_threadTimerData = {}; static QList prepareForActivation(int timerId) { - QMutexLocker lock(&s_mutex); - const auto it = s_timerIdToTimerData.constFind(timerId); - if (it == s_timerIdToTimerData.cend()) + const auto it = s_threadTimerData.m_timerIdToTimerData.constFind(timerId); + if (it == s_threadTimerData.m_timerIdToTimerData.cend()) return {}; // the timer was already activated const system_clock::time_point deadline = it->m_deadline; QList toActivate; - auto itMap = s_deadlineToTimerId.cbegin(); - while (itMap != s_deadlineToTimerId.cend()) { + auto itMap = s_threadTimerData.m_deadlineToTimerId.cbegin(); + while (itMap != s_threadTimerData.m_deadlineToTimerId.cend()) { if (itMap.key() > deadline) break; - const auto it = s_timerIdToTimerData.constFind(itMap.value()); - if (it != s_timerIdToTimerData.cend()) { + const auto it = s_threadTimerData.m_timerIdToTimerData.constFind(itMap.value()); + if (it != s_threadTimerData.m_timerIdToTimerData.cend()) { toActivate.append(it.value()); - s_timerIdToTimerData.erase(it); + s_threadTimerData.m_timerIdToTimerData.erase(it); } - itMap = s_deadlineToTimerId.erase(itMap); + itMap = s_threadTimerData.m_deadlineToTimerId.erase(itMap); } return toActivate; } static void removeTimerId(int timerId) { - QMutexLocker lock(&s_mutex); - const auto it = s_timerIdToTimerData.constFind(timerId); - QT_ASSERT(it != s_timerIdToTimerData.cend(), + const auto it = s_threadTimerData.m_timerIdToTimerData.constFind(timerId); + QT_ASSERT(it != s_threadTimerData.m_timerIdToTimerData.cend(), qWarning("Removing active timerId failed."); return); const system_clock::time_point deadline = it->m_deadline; - s_timerIdToTimerData.erase(it); + s_threadTimerData.m_timerIdToTimerData.erase(it); - const int removedCount = s_deadlineToTimerId.remove(deadline, timerId); + const int removedCount = s_threadTimerData.m_deadlineToTimerId.remove(deadline, timerId); QT_ASSERT(removedCount == 1, qWarning("Removing active timerId failed."); return); } @@ -2720,18 +2725,17 @@ static void handleTimeout(int timerId) const QList toActivate = prepareForActivation(timerId); for (const TimerData &timerData : toActivate) { if (timerData.m_context) - QMetaObject::invokeMethod(timerData.m_context.get(), timerData.m_callback); + timerData.m_callback(); } } static int scheduleTimeout(milliseconds timeout, QObject *context, const TimeoutCallback &callback) { - const int timerId = s_timerId.fetch_add(1) + 1; + const int timerId = ++s_threadTimerData.m_timerIdCounter; const system_clock::time_point deadline = system_clock::now() + timeout; QTimer::singleShot(timeout, context, [timerId] { handleTimeout(timerId); }); - QMutexLocker lock(&s_mutex); - s_timerIdToTimerData.emplace(timerId, TimerData{deadline, context, callback}); - s_deadlineToTimerId.insert(deadline, timerId); + s_threadTimerData.m_timerIdToTimerData.emplace(timerId, TimerData{deadline, context, callback}); + s_threadTimerData.m_deadlineToTimerId.insert(deadline, timerId); return timerId; } diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index da9929bff1f..108654190d5 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -394,7 +394,7 @@ static Handler toTweakDoneHandler(DoneResult result) return result == DoneResult::Success ? Handler::TweakDoneToSuccess : Handler::TweakDoneToError; } -static TestData storageShadowing() +static TestData storageShadowingData() { // This test check if storage shadowing works OK. @@ -471,6 +471,70 @@ static TestData storageShadowing() return {storage, root, log, 0, DoneWith::Success}; } +static TestData parallelData() +{ + TreeStorage storage; + + const auto setupTask = [storage](int taskId, milliseconds timeout) { + return [storage, taskId, timeout](TaskObject &taskObject) { + taskObject = timeout; + storage->m_log.append({taskId, Handler::Setup}); + }; + }; + + const auto setupDone = [storage](int taskId, DoneResult result = DoneResult::Success) { + return [storage, taskId, result](DoneWith doneWith) { + const Handler handler = doneWith == DoneWith::Cancel ? Handler::Canceled + : result == DoneResult::Success ? Handler::Success : Handler::Error; + storage->m_log.append({taskId, handler}); + return doneWith == DoneWith::Cancel ? DoneResult::Error + : result == DoneResult::Success ? DoneResult::Success : DoneResult::Error; + }; + }; + + const auto createTask = [storage, setupTask, setupDone]( + int taskId, DoneResult result, milliseconds timeout = 0ms) { + return TestTask(setupTask(taskId, timeout), setupDone(taskId, result)); + }; + + const auto createSuccessTask = [createTask](int taskId, milliseconds timeout = 0ms) { + return createTask(taskId, DoneResult::Success, timeout); + }; + + const auto groupDone = [storage](int taskId) { + return onGroupDone([storage, taskId](DoneWith result) { + storage->m_log.append({taskId, resultToGroupHandler(result)}); + }); + }; + + const Group root { + Storage(storage), + parallel, + createSuccessTask(1), + createSuccessTask(2), + createSuccessTask(3), + createSuccessTask(4), + createSuccessTask(5), + groupDone(0) + }; + + const Log log { + {1, Handler::Setup}, // Setup order is determined in parallel mode + {2, Handler::Setup}, + {3, Handler::Setup}, + {4, Handler::Setup}, + {5, Handler::Setup}, + {1, Handler::Success}, + {2, Handler::Success}, + {3, Handler::Success}, + {4, Handler::Success}, + {5, Handler::Success}, + {0, Handler::GroupSuccess} + }; + + return {storage, root, log, 5, DoneWith::Success}; +} + void tst_Tasking::testTree_data() { QTest::addColumn("testData"); @@ -792,32 +856,7 @@ void tst_Tasking::testTree_data() QTest::newRow("Nested") << TestData{storage, root, log, 1, DoneWith::Success}; } - { - const Group root { - Storage(storage), - parallel, - createSuccessTask(1), - createSuccessTask(2), - createSuccessTask(3), - createSuccessTask(4), - createSuccessTask(5), - groupDone(0) - }; - const Log log { - {1, Handler::Setup}, // Setup order is determined in parallel mode - {2, Handler::Setup}, - {3, Handler::Setup}, - {4, Handler::Setup}, - {5, Handler::Setup}, - {1, Handler::Success}, - {2, Handler::Success}, - {3, Handler::Success}, - {4, Handler::Success}, - {5, Handler::Success}, - {0, Handler::GroupSuccess} - }; - QTest::newRow("Parallel") << TestData{storage, root, log, 5, DoneWith::Success}; - } + QTest::newRow("Parallel") << parallelData(); { auto setupSubTree = [storage, createSuccessTask](TaskTree &taskTree) { @@ -2592,10 +2631,8 @@ void tst_Tasking::testTree_data() DoneWith::Success}; } - { - // This test check if storage shadowing works OK. - QTest::newRow("StorageShadowing") << storageShadowing(); - } + // This test check if storage shadowing works OK. + QTest::newRow("StorageShadowing") << storageShadowingData(); } void tst_Tasking::testTree() @@ -2622,13 +2659,15 @@ void tst_Tasking::testTree() void tst_Tasking::testInThread_data() { QTest::addColumn("testData"); - QTest::newRow("StorageShadowing") << storageShadowing(); + QTest::newRow("StorageShadowing") << storageShadowingData(); + QTest::newRow("Parallel") << parallelData(); } struct TestResult { int executeCount = 0; ThreadResult threadResult = ThreadResult::Success; + Log actualLog = {}; }; static const int s_loopCount = 1000; @@ -2664,7 +2703,7 @@ static void runInThread(QPromise &promise, const TestData &testData) return; } if (actualLog != testData.expectedLog) { - promise.addResult(TestResult{i, ThreadResult::FailOnLogCheck}); + promise.addResult(TestResult{i, ThreadResult::FailOnLogCheck, actualLog}); return; } if (result != testData.onDone) { @@ -2672,7 +2711,7 @@ static void runInThread(QPromise &promise, const TestData &testData) return; } } - promise.addResult(TestResult{s_loopCount, ThreadResult::Success}); + promise.addResult(TestResult{s_loopCount, ThreadResult::Success, testData.expectedLog}); } void tst_Tasking::testInThread() @@ -2685,8 +2724,9 @@ void tst_Tasking::testInThread() const auto onDone = [testData](const ConcurrentCall &task) { QVERIFY(task.future().resultCount()); const TestResult result = task.result(); - QCOMPARE(result.executeCount, s_loopCount); + QCOMPARE(result.actualLog, testData.expectedLog); QCOMPARE(result.threadResult, ThreadResult::Success); + QCOMPARE(result.executeCount, s_loopCount); }; QList tasks = { parallel }; From 9d44d1899df54d3a99d24c890a84cd24bbc48cb2 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Wed, 15 Nov 2023 23:36:10 +0100 Subject: [PATCH 0260/1546] TaskTree: Fix Timeout activation The activation of one timeout may cancel the other running timeout. Don't remove all timeouts which are to be activated before the activation loop. Remove and activate incrementally instead. Change-Id: I6147fb63b6ef9d6ada034330d98d1c13419012b4 Reviewed-by: hjk Reviewed-by: Qt CI Bot --- src/libs/solutions/tasking/tasktree.cpp | 49 ++++++++++++------------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index bae7c2e17c5..943776c89a4 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -2684,29 +2684,6 @@ struct TimerThreadData // Please note the thread_local keyword below guarantees a separate instance per thread. static thread_local TimerThreadData s_threadTimerData = {}; -static QList prepareForActivation(int timerId) -{ - const auto it = s_threadTimerData.m_timerIdToTimerData.constFind(timerId); - if (it == s_threadTimerData.m_timerIdToTimerData.cend()) - return {}; // the timer was already activated - - const system_clock::time_point deadline = it->m_deadline; - QList toActivate; - auto itMap = s_threadTimerData.m_deadlineToTimerId.cbegin(); - while (itMap != s_threadTimerData.m_deadlineToTimerId.cend()) { - if (itMap.key() > deadline) - break; - - const auto it = s_threadTimerData.m_timerIdToTimerData.constFind(itMap.value()); - if (it != s_threadTimerData.m_timerIdToTimerData.cend()) { - toActivate.append(it.value()); - s_threadTimerData.m_timerIdToTimerData.erase(it); - } - itMap = s_threadTimerData.m_deadlineToTimerId.erase(itMap); - } - return toActivate; -} - static void removeTimerId(int timerId) { const auto it = s_threadTimerData.m_timerIdToTimerData.constFind(timerId); @@ -2722,8 +2699,30 @@ static void removeTimerId(int timerId) static void handleTimeout(int timerId) { - const QList toActivate = prepareForActivation(timerId); - for (const TimerData &timerData : toActivate) { + const auto itData = s_threadTimerData.m_timerIdToTimerData.constFind(timerId); + if (itData == s_threadTimerData.m_timerIdToTimerData.cend()) + return; // The timer was already activated. + + const auto deadline = itData->m_deadline; + while (true) { + const auto itMap = s_threadTimerData.m_deadlineToTimerId.cbegin(); + if (itMap == s_threadTimerData.m_deadlineToTimerId.cend()) + return; + + if (itMap.key() > deadline) + return; + + const auto it = s_threadTimerData.m_timerIdToTimerData.constFind(itMap.value()); + if (it == s_threadTimerData.m_timerIdToTimerData.cend()) { + s_threadTimerData.m_deadlineToTimerId.erase(itMap); + QT_CHECK(false); + return; + } + + const TimerData timerData = it.value(); + s_threadTimerData.m_timerIdToTimerData.erase(it); + s_threadTimerData.m_deadlineToTimerId.erase(itMap); + if (timerData.m_context) timerData.m_callback(); } From 8798ed1aceb143605c773013195926c56efcdcec Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Fri, 17 Nov 2023 17:20:08 +0100 Subject: [PATCH 0261/1546] ProjectExplorer: Fix sorting of file names in subpaths in wizard summary In the wizard summary page, on Windows, the sorting of files in sub directories is not correct. The paths got converted to userOutput before they were tested for '/' and then assigned to a FilePath (which caused a QTC_CHEK warning in addition). This is reproducible with the "QDS compatible" Qt Quick application wizard. Fixes: QTCREATORBUG-29921 Change-Id: I45b623409831b21467e33481dcc3ca557f0f9afc Reviewed-by: Cristian Adam --- src/plugins/projectexplorer/projectwizardpage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/projectwizardpage.cpp b/src/plugins/projectexplorer/projectwizardpage.cpp index d8a815a7545..d3f60faeaeb 100644 --- a/src/plugins/projectexplorer/projectwizardpage.cpp +++ b/src/plugins/projectexplorer/projectwizardpage.cpp @@ -548,7 +548,7 @@ void ProjectWizardPage::setFiles(const FilePaths &files) str << m_commonDirectory.toUserOutput() << ":\n\n"; int prefixSize = m_commonDirectory.toUserOutput().size(); formattedFiles = Utils::transform(files, [prefixSize] (const FilePath &f) { - return f.toUserOutput().mid(prefixSize + 1); // +1 skips the initial dir separator + return f.toString().mid(prefixSize + 1); // +1 skips the initial dir separator }); } // Alphabetically, and files in sub-directories first From c8541962a61a06948cd4ed9c42c70a23980681fd Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 16 Nov 2023 10:01:51 +0100 Subject: [PATCH 0262/1546] DeviceShell: Get rid of unused variable Change-Id: I8f93364b347460b1daef1149d3ff5c28436b0754 Reviewed-by: Reviewed-by: Christian Stenger --- src/libs/utils/deviceshell.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libs/utils/deviceshell.cpp b/src/libs/utils/deviceshell.cpp index f459e33d255..77b197f80ba 100644 --- a/src/libs/utils/deviceshell.cpp +++ b/src/libs/utils/deviceshell.cpp @@ -171,8 +171,6 @@ expected_str DeviceShell::start() setupShellProcess(m_shellProcess.get()); - CommandLine cmdLine = m_shellProcess->commandLine(); - m_shellProcess->setProcessMode(ProcessMode::Writer); // Moving the process into its own thread ... From 9b429c7ebd02b5d9a2cbca3a6aa606ff69fd6e42 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 20 Nov 2023 06:57:05 +0100 Subject: [PATCH 0263/1546] ImageViewer: Fix build Remove now superfluous moc include. Change-Id: Id0d0a4110e4be9206bd09a4795ebc63b7b443221 Reviewed-by: Jarek Kobus --- src/plugins/imageviewer/imageviewerplugin.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/imageviewer/imageviewerplugin.cpp b/src/plugins/imageviewer/imageviewerplugin.cpp index a8088a02395..f2db22fc4d1 100644 --- a/src/plugins/imageviewer/imageviewerplugin.cpp +++ b/src/plugins/imageviewer/imageviewerplugin.cpp @@ -21,5 +21,3 @@ public: }; } // ImageViewer::Internal - -#include "imageviewerplugin.moc" From 34f374baec9b4914f1ee6c8415c0fd811c7714a5 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Nov 2023 16:17:55 +0100 Subject: [PATCH 0264/1546] Todo: Move TodoPlugin class definition to .cpp Change-Id: I5b82b14bf86655f0dab9379effb4ff156900b610 Reviewed-by: Christian Stenger --- src/plugins/todo/CMakeLists.txt | 2 +- src/plugins/todo/todo.qbs | 1 - src/plugins/todo/todoplugin.cpp | 45 ++++++++++++++++++++------------- src/plugins/todo/todoplugin.h | 28 -------------------- 4 files changed, 28 insertions(+), 48 deletions(-) delete mode 100644 src/plugins/todo/todoplugin.h diff --git a/src/plugins/todo/CMakeLists.txt b/src/plugins/todo/CMakeLists.txt index cc8b72a2d66..ac9b61e3096 100644 --- a/src/plugins/todo/CMakeLists.txt +++ b/src/plugins/todo/CMakeLists.txt @@ -18,7 +18,7 @@ add_qtc_plugin(Todo todooutputpane.cpp todooutputpane.h todooutputtreeview.cpp todooutputtreeview.h todooutputtreeviewdelegate.cpp todooutputtreeviewdelegate.h - todoplugin.cpp todoplugin.h + todoplugin.cpp todoplugin.qrc todoprojectsettingswidget.cpp todoprojectsettingswidget.h todotr.h diff --git a/src/plugins/todo/todo.qbs b/src/plugins/todo/todo.qbs index bbd3ed74cbe..f3ea7fc96fa 100644 --- a/src/plugins/todo/todo.qbs +++ b/src/plugins/todo/todo.qbs @@ -46,7 +46,6 @@ QtcPlugin { "todooutputtreeviewdelegate.cpp", "todooutputtreeviewdelegate.h", "todoplugin.cpp", - "todoplugin.h", "todoplugin.qrc", "todotr.h", ] diff --git a/src/plugins/todo/todoplugin.cpp b/src/plugins/todo/todoplugin.cpp index 42b62333ced..6da4a2bd8e5 100644 --- a/src/plugins/todo/todoplugin.cpp +++ b/src/plugins/todo/todoplugin.cpp @@ -2,8 +2,6 @@ // Copyright (C) 2016 Vasiliy Sorokin // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "todoplugin.h" - #include "optionsdialog.h" #include "todooutputpane.h" #include "todoitemsprovider.h" @@ -14,11 +12,11 @@ #include #include -#include +#include + #include -namespace Todo { -namespace Internal { +namespace Todo::Internal { class TodoPluginPrivate : public QObject { @@ -87,20 +85,31 @@ void TodoPluginPrivate::createTodoOutputPane() this, &TodoPluginPrivate::todoItemClicked); } -TodoPlugin::TodoPlugin() +class TodoPlugin final : public ExtensionSystem::IPlugin { - qRegisterMetaType("TodoItem"); -} + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Todo.json") -TodoPlugin::~TodoPlugin() -{ - delete d; -} +public: + TodoPlugin() + { + qRegisterMetaType("TodoItem"); + } -void TodoPlugin::initialize() -{ - d = new TodoPluginPrivate; -} + ~TodoPlugin() final + { + delete d; + } -} // namespace Internal -} // namespace Todo + void initialize() final + { + d = new TodoPluginPrivate; + } + +private: + TodoPluginPrivate *d = nullptr; +}; + +} // Todo::Internal + +#include "todoplugin.moc" diff --git a/src/plugins/todo/todoplugin.h b/src/plugins/todo/todoplugin.h deleted file mode 100644 index 73cf865cb52..00000000000 --- a/src/plugins/todo/todoplugin.h +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (C) 2016 Dmitry Savchenko -// Copyright (C) 2016 Vasiliy Sorokin -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace Todo { -namespace Internal { - -class TodoPlugin final : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Todo.json") - -public: - TodoPlugin(); - ~TodoPlugin() final; - - void initialize() final; - -private: - class TodoPluginPrivate *d = nullptr; -}; - -} // namespace Internal -} // namespace Todo From 4362318c140c552eb5346b6aca90e651e93869a1 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 17 Nov 2023 09:00:57 +0100 Subject: [PATCH 0265/1546] WizardFactory: Early return in clearWizardFactories Detect early if there is nothing to do Change-Id: Ic2c27c2d265cbc245d383531ad7d844457ea8121 Reviewed-by: Alessandro Portale --- src/plugins/coreplugin/iwizardfactory.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/coreplugin/iwizardfactory.cpp b/src/plugins/coreplugin/iwizardfactory.cpp index caa664d7e46..1851de352ea 100644 --- a/src/plugins/coreplugin/iwizardfactory.cpp +++ b/src/plugins/coreplugin/iwizardfactory.cpp @@ -378,6 +378,9 @@ void IWizardFactory::destroyFeatureProvider() void IWizardFactory::clearWizardFactories() { + if (!s_areFactoriesLoaded) + return; + for (IWizardFactory *factory : std::as_const(s_allFactories)) ActionManager::unregisterAction(factory->m_action, actionId(factory)); From b60fd77fc128133f408d67beda814c55e8364d3e Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 16 Nov 2023 14:53:44 +0100 Subject: [PATCH 0266/1546] Fix clearing the list of wizard factories Clearing the list of wizard factories did not result in updating the available JSON wizards. The JSON wizard paths were scanned only once at startup. Instead partially revert back to before 1cf6b031cfdf7344eb2ce6a403aa1029b7b8f75e and let the JSON "factory creator" parse the directories and return a list of wizard factories. Change-Id: Ifc253479973be801c5323588800bb264610187b6 Reviewed-by: Alessandro Portale Reviewed-by: --- src/plugins/coreplugin/iwizardfactory.cpp | 55 +++++++++++-------- src/plugins/coreplugin/iwizardfactory.h | 3 +- src/plugins/designer/formeditorplugin.cpp | 2 +- .../jsonwizard/jsonwizardfactory.cpp | 18 ++++-- .../jsonwizard/jsonwizardfactory.h | 2 +- .../projectexplorer/projectexplorer.cpp | 3 +- 6 files changed, 50 insertions(+), 33 deletions(-) diff --git a/src/plugins/coreplugin/iwizardfactory.cpp b/src/plugins/coreplugin/iwizardfactory.cpp index 1851de352ea..d3c30057f08 100644 --- a/src/plugins/coreplugin/iwizardfactory.cpp +++ b/src/plugins/coreplugin/iwizardfactory.cpp @@ -186,33 +186,35 @@ QList IWizardFactory::allWizardFactories() QHash sanityCheck; for (const FactoryCreator &fc : std::as_const(s_factoryCreators)) { - IWizardFactory *newFactory = fc(); - // skip factories referencing wizard page generators provided by plugins not loaded - if (!newFactory) - continue; - IWizardFactory *existingFactory = sanityCheck.value(newFactory->id()); + for (IWizardFactory *newFactory : fc()) { + if (!newFactory) // should not happen, but maybe something went wrong + continue; + IWizardFactory *existingFactory = sanityCheck.value(newFactory->id()); - QTC_ASSERT(existingFactory != newFactory, continue); - if (existingFactory) { - qWarning("%s", qPrintable(Tr::tr("Factory with id=\"%1\" already registered. Deleting.") - .arg(existingFactory->id().toString()))); - delete newFactory; - continue; - } - - QTC_ASSERT(!newFactory->m_action, continue); - newFactory->m_action = new QAction(newFactory->displayName(), newFactory); - ActionManager::registerAction(newFactory->m_action, actionId(newFactory)); - - connect(newFactory->m_action, &QAction::triggered, newFactory, [newFactory] { - if (!ICore::isNewItemDialogRunning()) { - FilePath path = newFactory->runPath({}); - newFactory->runWizard(path, ICore::dialogParent(), Id(), QVariantMap()); + QTC_ASSERT(existingFactory != newFactory, continue); + if (existingFactory) { + qWarning("%s", + qPrintable( + Tr::tr("Factory with id=\"%1\" already registered. Deleting.") + .arg(existingFactory->id().toString()))); + delete newFactory; + continue; } - }); - sanityCheck.insert(newFactory->id(), newFactory); - s_allFactories << newFactory; + QTC_ASSERT(!newFactory->m_action, continue); + newFactory->m_action = new QAction(newFactory->displayName(), newFactory); + ActionManager::registerAction(newFactory->m_action, actionId(newFactory)); + + connect(newFactory->m_action, &QAction::triggered, newFactory, [newFactory] { + if (!ICore::isNewItemDialogRunning()) { + FilePath path = newFactory->runPath({}); + newFactory->runWizard(path, ICore::dialogParent(), Id(), QVariantMap()); + } + }); + + sanityCheck.insert(newFactory->id(), newFactory); + s_allFactories << newFactory; + } } } @@ -322,6 +324,11 @@ void IWizardFactory::registerFactoryCreator(const IWizardFactory::FactoryCreator s_factoryCreators << creator; } +void IWizardFactory::registerFactoryCreator(const std::function &creator) +{ + s_factoryCreators << [creator] { return QList({creator()}); }; +} + QSet IWizardFactory::allAvailablePlatforms() { QSet platforms; diff --git a/src/plugins/coreplugin/iwizardfactory.h b/src/plugins/coreplugin/iwizardfactory.h index e9771f7aa1d..97b47ac3d3a 100644 --- a/src/plugins/coreplugin/iwizardfactory.h +++ b/src/plugins/coreplugin/iwizardfactory.h @@ -77,8 +77,9 @@ public: virtual bool isAvailable(Utils::Id platformId) const; QSet supportedPlatforms() const; - using FactoryCreator = std::function; + using FactoryCreator = std::function()>; static void registerFactoryCreator(const FactoryCreator &creator); + static void registerFactoryCreator(const std::function &creator); // Utility to find all registered wizards static QList allWizardFactories(); diff --git a/src/plugins/designer/formeditorplugin.cpp b/src/plugins/designer/formeditorplugin.cpp index 0f9c77b0b44..afbca7010bd 100644 --- a/src/plugins/designer/formeditorplugin.cpp +++ b/src/plugins/designer/formeditorplugin.cpp @@ -100,7 +100,7 @@ bool FormEditorPlugin::initialize([[maybe_unused]] const QStringList &arguments, wizard->setDescription(Tr::tr("Creates a Qt Designer form along with a matching class (C++ header and source file) " "for implementation purposes. You can add the form and class to an existing Qt Widget Project.")); - return wizard; + return {wizard}; }); #endif diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp index 4d364362fd1..c8299be8e85 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.cpp @@ -402,8 +402,9 @@ JsonWizardFactory::Page JsonWizardFactory::parsePage(const QVariant &value, QStr //FIXME: loadDefaultValues() has an almost identical loop. Make the loop return the results instead of //internal processing and create a separate function for it. Then process the results in //loadDefaultValues() and loadDefaultValues() -void JsonWizardFactory::createWizardFactories() +QList JsonWizardFactory::createWizardFactories() { + QList result; QString verboseLog; const QString wizardFileName = QLatin1String("wizard.json"); @@ -465,10 +466,16 @@ void JsonWizardFactory::createWizardFactories() continue; } - IWizardFactory::registerFactoryCreator([data, currentFile] { - QString errorMessage; - return createWizardFactory(data, currentFile.parentDir(), &errorMessage); - }); + QString errorMessage; + JsonWizardFactory *factory = createWizardFactory(data, + currentFile.parentDir(), + &errorMessage); + if (!factory) { + verboseLog.append(tr("* Failed to create: %1\n").arg(errorMessage)); + continue; + } + + result << factory; } } @@ -476,6 +483,7 @@ void JsonWizardFactory::createWizardFactories() qWarning("%s", qPrintable(verboseLog)); Core::MessageManager::writeDisrupting(verboseLog); } + return result; } JsonWizardFactory *JsonWizardFactory::createWizardFactory(const QVariantMap &data, diff --git a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h index 118b20330f2..c72808db66b 100644 --- a/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h +++ b/src/plugins/projectexplorer/jsonwizard/jsonwizardfactory.h @@ -63,7 +63,7 @@ private: // Create all wizards. As other plugins might register factories for derived // classes. Called when the new file dialog is shown for the first time. - static void createWizardFactories(); + static QList createWizardFactories(); static JsonWizardFactory *createWizardFactory(const QVariantMap &data, const Utils::FilePath &baseDir, QString *errorMessage); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index f2143cc1549..e88d4225414 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -2042,7 +2042,8 @@ void ProjectExplorerPluginPrivate::closeAllProjects() void ProjectExplorerPlugin::extensionsInitialized() { CustomWizard::createWizards(); - JsonWizardFactory::createWizardFactories(); + IWizardFactory::registerFactoryCreator( + [] { return JsonWizardFactory::createWizardFactories(); }); // Register factories for all project managers From 8116aaaab88f3499845004bd358e58e4de951887 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 16 Nov 2023 14:53:44 +0100 Subject: [PATCH 0267/1546] Fix missing wizard after loading CompilerExplorer without restart Wizards should be reloaded after plugins are loaded. They might either add wizard paths, or wizards that check for plugins might be loaded even though they were not loaded before. Emit PluginManager::pluginsChanged when plugins are loaded at runtime too, and connect that to clearing the list of wizard factories. Change-Id: I79e0fb4991074cba592296620f1758136d60b378 Reviewed-by: Alessandro Portale Reviewed-by: --- src/libs/extensionsystem/pluginmanager.cpp | 1 + src/plugins/coreplugin/iwizardfactory.cpp | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index 22ce4786046..072e8f0fa6b 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -1411,6 +1411,7 @@ void PluginManagerPrivate::loadPluginsAtRuntime(const QSet &plugin spec->d->kill(); } }); + emit q->pluginsChanged(); } /*! diff --git a/src/plugins/coreplugin/iwizardfactory.cpp b/src/plugins/coreplugin/iwizardfactory.cpp index d3c30057f08..9beccc8d070 100644 --- a/src/plugins/coreplugin/iwizardfactory.cpp +++ b/src/plugins/coreplugin/iwizardfactory.cpp @@ -431,6 +431,9 @@ void IWizardFactory::initialize() connect(resetAction, &QAction::triggered, &IWizardFactory::clearWizardFactories); connect(ICore::instance(), &ICore::newItemDialogStateChanged, resetAction, [resetAction] { resetAction->setEnabled(!ICore::isNewItemDialogRunning()); }); + connect(ExtensionSystem::PluginManager::instance(), + &ExtensionSystem::PluginManager::pluginsChanged, + &IWizardFactory::clearWizardFactories); s_inspectWizardAction = new QAction(Tr::tr("Inspect Wizard State"), ActionManager::instance()); ActionManager::registerAction(s_inspectWizardAction, "Wizard.Inspect"); From d924d4e886ec01a206a5af92ec7d336ebf3c13d5 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 12:04:35 +0100 Subject: [PATCH 0268/1546] Fossil: Delay-create FossilClient By three liens, the connect in the pluginprivate ctor will create it. Change-Id: I23c80884f293fae434de573b8684bde2c56bd45e Reviewed-by: Orgad Shaneh --- src/plugins/fossil/fossilclient.cpp | 12 ++- src/plugins/fossil/fossilclient.h | 9 +- src/plugins/fossil/fossileditor.cpp | 17 ++-- src/plugins/fossil/fossilplugin.cpp | 139 +++++++++++++--------------- src/plugins/fossil/fossilplugin.h | 5 - 5 files changed, 82 insertions(+), 100 deletions(-) diff --git a/src/plugins/fossil/fossilclient.cpp b/src/plugins/fossil/fossilclient.cpp index fb7a97abb2a..d05e596ae25 100644 --- a/src/plugins/fossil/fossilclient.cpp +++ b/src/plugins/fossil/fossilclient.cpp @@ -34,8 +34,7 @@ using namespace Utils; using namespace VcsBase; -namespace Fossil { -namespace Internal { +namespace Fossil::Internal { const RunFlags s_pullFlags = RunFlags::ShowStdOut | RunFlags::ShowSuccessMessage; @@ -1170,7 +1169,12 @@ VcsBaseEditorConfig *FossilClient::createLogEditor(VcsBaseEditorWidget *editor) return new FossilLogConfig(editor->toolBar()); } -} // namespace Internal -} // namespace Fossil +FossilClient &fossilClient() +{ + static FossilClient theFossilClient; + return theFossilClient; +} + +} // namespace Fossil::Internal #include "fossilclient.moc" diff --git a/src/plugins/fossil/fossilclient.h b/src/plugins/fossil/fossilclient.h index b3016378461..6df70502bd0 100644 --- a/src/plugins/fossil/fossilclient.h +++ b/src/plugins/fossil/fossilclient.h @@ -11,15 +11,13 @@ #include -namespace Fossil { -namespace Internal { +namespace Fossil::Internal { class FossilSettings; class FossilPluginPrivate; class FossilClient : public VcsBase::VcsBaseClient { - Q_OBJECT public: enum SupportedFeature { AnnotateBlameFeature = 0x2, @@ -109,7 +107,8 @@ private: friend class FossilPluginPrivate; }; +FossilClient &fossilClient(); + Q_DECLARE_OPERATORS_FOR_FLAGS(FossilClient::SupportedFeatures) -} // namespace Internal -} // namespace Fossil +} // namespace Fossil::Internal diff --git a/src/plugins/fossil/fossileditor.cpp b/src/plugins/fossil/fossileditor.cpp index 48268754089..01fc9e821a5 100644 --- a/src/plugins/fossil/fossileditor.cpp +++ b/src/plugins/fossil/fossileditor.cpp @@ -6,7 +6,6 @@ #include "annotationhighlighter.h" #include "constants.h" #include "fossilclient.h" -#include "fossilplugin.h" #include "fossiltr.h" #include @@ -14,8 +13,7 @@ #include #include -namespace Fossil { -namespace Internal { +namespace Fossil::Internal { class FossilEditorWidgetPrivate { @@ -26,7 +24,6 @@ public: QTC_ASSERT(m_exactChangesetId.isValid(), return); } - const QRegularExpression m_exactChangesetId; }; @@ -64,9 +61,8 @@ QString FossilEditorWidget::decorateVersion(const QString &revision) const static const int maxTextSize(120); const Utils::FilePath workingDirectory = source().parentDir(); - const FossilClient *client = FossilPlugin::client(); - const RevisionInfo revisionInfo = client->synchronousRevisionQuery(workingDirectory, revision, - true); + const RevisionInfo revisionInfo = + fossilClient().synchronousRevisionQuery(workingDirectory, revision, true); // format: 'revision (committer "comment...")' QString output = revision.left(shortChangesetIdSize) + " (" + revisionInfo.committer @@ -83,8 +79,8 @@ QString FossilEditorWidget::decorateVersion(const QString &revision) const QStringList FossilEditorWidget::annotationPreviousVersions(const QString &revision) const { const Utils::FilePath workingDirectory = source().parentDir(); - const FossilClient *client = FossilPlugin::client(); - const RevisionInfo revisionInfo = client->synchronousRevisionQuery(workingDirectory, revision); + const RevisionInfo revisionInfo = + fossilClient().synchronousRevisionQuery(workingDirectory, revision); if (revisionInfo.parentId.isEmpty()) return {}; @@ -99,5 +95,4 @@ VcsBase::BaseAnnotationHighlighter *FossilEditorWidget::createAnnotationHighligh return new FossilAnnotationHighlighter(changes); } -} // namespace Internal -} // namespace Fossil +} // namespace Fossil::Internal diff --git a/src/plugins/fossil/fossilplugin.cpp b/src/plugins/fossil/fossilplugin.cpp index 2e4d4f09611..d0a8dcc5301 100644 --- a/src/plugins/fossil/fossilplugin.cpp +++ b/src/plugins/fossil/fossilplugin.cpp @@ -52,20 +52,21 @@ #include #include +#ifdef WITH_TESTS +#include +#endif + using namespace Core; using namespace Utils; using namespace VcsBase; using namespace std::placeholders; -namespace Fossil { -namespace Internal { +namespace Fossil::Internal { -class FossilTopicCache : public IVersionControl::TopicCache +class FossilTopicCache final : public IVersionControl::TopicCache { public: - FossilTopicCache(FossilClient *client) : - m_client(client) - { } + FossilTopicCache() = default; protected: FilePath trackFile(const FilePath &repository) final @@ -75,11 +76,8 @@ protected: QString refreshTopic(const FilePath &repository) final { - return m_client->synchronousTopic(repository); + return fossilClient().synchronousTopic(repository); } - -private: - FossilClient *m_client; }; const VcsBaseEditorParameters fileLogParameters { @@ -183,8 +181,6 @@ public: bool pullOrPush(SyncMode mode); // Variables - FossilClient m_client; - VcsSubmitEditorFactory submitEditorFactory { submitEditorParameters, [] { return new CommitEditor; }, @@ -269,18 +265,13 @@ void FossilPlugin::extensionsInitialized() dd->extensionsInitialized(); } -FossilClient *FossilPlugin::client() -{ - return &dd->m_client; -} - FossilPluginPrivate::FossilPluginPrivate() : VcsBasePluginPrivate(Context(Constants::FOSSIL_CONTEXT)) { Context context(Constants::FOSSIL_CONTEXT); - setTopicCache(new FossilTopicCache(&m_client)); - connect(&m_client, &VcsBaseClient::changed, this, &FossilPluginPrivate::changed); + setTopicCache(new FossilTopicCache); + connect(&fossilClient(), &VcsBaseClient::changed, this, &FossilPluginPrivate::changed); m_commandLocator = new CommandLocator("Fossil", "fossil", "fossil", this); m_commandLocator->setDescription(Tr::tr("Triggers a Fossil version control operation.")); @@ -387,7 +378,7 @@ void FossilPluginPrivate::addCurrentFile() { const VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasFile(), return); - m_client.synchronousAdd(state.currentFileTopLevel(), state.relativeCurrentFile()); + fossilClient().synchronousAdd(state.currentFileTopLevel(), state.relativeCurrentFile()); } void FossilPluginPrivate::deleteCurrentFile() @@ -400,31 +391,31 @@ void FossilPluginPrivate::annotateCurrentFile() const VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasFile(), return); const int lineNumber = VcsBaseEditor::lineNumberOfCurrentEditor(state.currentFile()); - m_client.annotate(state.currentFileTopLevel(), state.relativeCurrentFile(), lineNumber); + fossilClient().annotate(state.currentFileTopLevel(), state.relativeCurrentFile(), lineNumber); } void FossilPluginPrivate::diffCurrentFile() { const VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasFile(), return); - m_client.diff(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile())); + fossilClient().diff(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile())); } void FossilPluginPrivate::logCurrentFile() { const VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasFile(), return); - FossilClient::SupportedFeatures features = m_client.supportedFeatures(); + FossilClient::SupportedFeatures features = fossilClient().supportedFeatures(); QStringList extraOptions; - extraOptions << "-n" << QString::number(m_client.settings().logCount()); + extraOptions << "-n" << QString::number(fossilClient().settings().logCount()); if (features.testFlag(FossilClient::TimelineWidthFeature)) - extraOptions << "-W" << QString::number(m_client.settings().timelineWidth()); + extraOptions << "-W" << QString::number(fossilClient().settings().timelineWidth()); // disable annotate context menu for older client versions, used to be supported for current revision only bool enableAnnotationContextMenu = features.testFlag(FossilClient::AnnotateRevisionFeature); - m_client.logCurrentFile(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile()), + fossilClient().logCurrentFile(state.currentFileTopLevel(), QStringList(state.relativeCurrentFile()), extraOptions, enableAnnotationContextMenu); } @@ -435,7 +426,7 @@ void FossilPluginPrivate::revertCurrentFile() RevertDialog dialog(Tr::tr("Revert"), ICore::dialogParent()); if (dialog.exec() == QDialog::Accepted) { - m_client.revertFile(state.currentFileTopLevel(), state.relativeCurrentFile(), + fossilClient().revertFile(state.currentFileTopLevel(), state.relativeCurrentFile(), dialog.revision()); } } @@ -444,7 +435,7 @@ void FossilPluginPrivate::statusCurrentFile() { const VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasFile(), return); - m_client.status(state.currentFileTopLevel(), state.relativeCurrentFile()); + fossilClient().status(state.currentFileTopLevel(), state.relativeCurrentFile()); } void FossilPluginPrivate::createDirectoryActions(const Context &context) @@ -488,21 +479,21 @@ void FossilPluginPrivate::diffRepository() { const VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasTopLevel(), return); - m_client.diff(state.topLevel()); + fossilClient().diff(state.topLevel()); } void FossilPluginPrivate::logRepository() { const VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasTopLevel(), return); - FossilClient::SupportedFeatures features = m_client.supportedFeatures(); + FossilClient::SupportedFeatures features = fossilClient().supportedFeatures(); QStringList extraOptions; - extraOptions << "-n" << QString::number(m_client.settings().logCount()); + extraOptions << "-n" << QString::number(fossilClient().settings().logCount()); if (features.testFlag(FossilClient::TimelineWidthFeature)) - extraOptions << "-W" << QString::number(m_client.settings().timelineWidth()); + extraOptions << "-W" << QString::number(fossilClient().settings().timelineWidth()); - m_client.log(state.topLevel(), {}, extraOptions); + fossilClient().log(state.topLevel(), {}, extraOptions); } void FossilPluginPrivate::revertAll() @@ -512,14 +503,14 @@ void FossilPluginPrivate::revertAll() RevertDialog dialog(Tr::tr("Revert"), ICore::dialogParent()); if (dialog.exec() == QDialog::Accepted) - m_client.revertAll(state.topLevel(), dialog.revision()); + fossilClient().revertAll(state.topLevel(), dialog.revision()); } void FossilPluginPrivate::statusMulti() { const VcsBasePluginState state = currentState(); QTC_ASSERT(state.hasTopLevel(), return); - m_client.status(state.topLevel()); + fossilClient().status(state.topLevel()); } void FossilPluginPrivate::createRepositoryActions(const Context &context) @@ -592,8 +583,8 @@ bool FossilPluginPrivate::pullOrPush(FossilPluginPrivate::SyncMode mode) QTC_ASSERT(state.hasTopLevel(), return false); PullOrPushDialog dialog(pullOrPushMode, ICore::dialogParent()); - dialog.setLocalBaseDirectory(m_client.settings().defaultRepoPath()); - const QString defaultURL(m_client.synchronousGetRepositoryURL(state.topLevel())); + dialog.setLocalBaseDirectory(fossilClient().settings().defaultRepoPath()); + const QString defaultURL(fossilClient().synchronousGetRepositoryURL(state.topLevel())); dialog.setDefaultRemoteLocation(defaultURL); if (dialog.exec() != QDialog::Accepted) return true; @@ -613,9 +604,9 @@ bool FossilPluginPrivate::pullOrPush(FossilPluginPrivate::SyncMode mode) extraOptions << "--private"; switch (mode) { case SyncPull: - return m_client.synchronousPull(state.topLevel(), remoteLocation, extraOptions); + return fossilClient().synchronousPull(state.topLevel(), remoteLocation, extraOptions); case SyncPush: - return m_client.synchronousPush(state.topLevel(), remoteLocation, extraOptions); + return fossilClient().synchronousPush(state.topLevel(), remoteLocation, extraOptions); default: return false; } @@ -628,7 +619,7 @@ void FossilPluginPrivate::update() RevertDialog dialog(Tr::tr("Update"), ICore::dialogParent()); if (dialog.exec() == QDialog::Accepted) - m_client.update(state.topLevel(), dialog.revision()); + fossilClient().update(state.topLevel(), dialog.revision()); } void FossilPluginPrivate::configureRepository() @@ -639,14 +630,14 @@ void FossilPluginPrivate::configureRepository() ConfigureDialog dialog; // retrieve current settings from the repository - RepositorySettings currentSettings = m_client.synchronousSettingsQuery(state.topLevel()); + RepositorySettings currentSettings = fossilClient().synchronousSettingsQuery(state.topLevel()); dialog.setSettings(currentSettings); if (dialog.exec() != QDialog::Accepted) return; const RepositorySettings newSettings = dialog.settings(); - m_client.synchronousConfigureRepository(state.topLevel(), newSettings, currentSettings); + fossilClient().synchronousConfigureRepository(state.topLevel(), newSettings, currentSettings); } void FossilPluginPrivate::commit() @@ -661,14 +652,14 @@ void FossilPluginPrivate::commit() QTC_ASSERT(state.hasTopLevel(), return); m_submitRepository = state.topLevel(); - connect(&m_client, &VcsBaseClient::parsedStatus, this, &FossilPluginPrivate::showCommitWidget); - m_client.emitParsedStatus(m_submitRepository, {}); + connect(&fossilClient(), &VcsBaseClient::parsedStatus, this, &FossilPluginPrivate::showCommitWidget); + fossilClient().emitParsedStatus(m_submitRepository, {}); } void FossilPluginPrivate::showCommitWidget(const QList &status) { //Once we receive our data release the connection so it can be reused elsewhere - disconnect(&m_client, &VcsBaseClient::parsedStatus, + disconnect(&fossilClient(), &VcsBaseClient::parsedStatus, this, &FossilPluginPrivate::showCommitWidget); if (status.isEmpty()) { @@ -702,10 +693,10 @@ void FossilPluginPrivate::showCommitWidget(const QListdocument()->setPreferredDisplayName(msg); - const RevisionInfo currentRevision = m_client.synchronousRevisionQuery(m_submitRepository); - const BranchInfo currentBranch = m_client.synchronousCurrentBranch(m_submitRepository); - const QString currentUser = m_client.synchronousUserDefaultQuery(m_submitRepository); - QStringList tags = m_client.synchronousTagQuery(m_submitRepository, currentRevision.id); + const RevisionInfo currentRevision = fossilClient().synchronousRevisionQuery(m_submitRepository); + const BranchInfo currentBranch = fossilClient().synchronousCurrentBranch(m_submitRepository); + const QString currentUser = fossilClient().synchronousUserDefaultQuery(m_submitRepository); + QStringList tags = fossilClient().synchronousTagQuery(m_submitRepository, currentRevision.id); // Fossil includes branch name in tag list -- remove. tags.removeAll(currentBranch.name); commitEditor->setFields(m_submitRepository, currentBranch, tags, currentUser, status); @@ -717,7 +708,7 @@ void FossilPluginPrivate::showCommitWidget(const QListisPrivateOptionEnabled()) extraOptions += "--private"; - m_client.commit(m_submitRepository, files, editorDocument->filePath().toString(), extraOptions); + fossilClient().commit(m_submitRepository, files, editorDocument->filePath().toString(), extraOptions); } return true; } @@ -850,12 +841,12 @@ Id FossilPluginPrivate::id() const bool FossilPluginPrivate::isVcsFileOrDirectory(const FilePath &filePath) const { - return m_client.isVcsFileOrDirectory(filePath); + return fossilClient().isVcsFileOrDirectory(filePath); } bool FossilPluginPrivate::managesDirectory(const FilePath &directory, FilePath *topLevel) const { - const FilePath topLevelFound = m_client.findTopLevelForFile(directory); + const FilePath topLevelFound = fossilClient().findTopLevelForFile(directory); if (topLevel) *topLevel = topLevelFound; return !topLevelFound.isEmpty(); @@ -863,12 +854,12 @@ bool FossilPluginPrivate::managesDirectory(const FilePath &directory, FilePath * bool FossilPluginPrivate::managesFile(const FilePath &workingDirectory, const QString &fileName) const { - return m_client.managesFile(workingDirectory, fileName); + return fossilClient().managesFile(workingDirectory, fileName); } bool FossilPluginPrivate::isConfigured() const { - const FilePath binary = m_client.vcsBinary(); + const FilePath binary = fossilClient().vcsBinary(); if (binary.isEmpty()) return false; @@ -876,7 +867,7 @@ bool FossilPluginPrivate::isConfigured() const return false; // Local repositories default path must be set and exist - const FilePath repoPath = m_client.settings().defaultRepoPath(); + const FilePath repoPath = fossilClient().settings().defaultRepoPath(); if (repoPath.isEmpty()) return false; @@ -910,35 +901,35 @@ bool FossilPluginPrivate::vcsOpen(const FilePath &filePath) bool FossilPluginPrivate::vcsAdd(const FilePath &filePath) { - return m_client.synchronousAdd(filePath.absolutePath(), filePath.fileName()); + return fossilClient().synchronousAdd(filePath.absolutePath(), filePath.fileName()); } bool FossilPluginPrivate::vcsDelete(const FilePath &filePath) { - return m_client.synchronousRemove(filePath.absolutePath(), filePath.fileName()); + return fossilClient().synchronousRemove(filePath.absolutePath(), filePath.fileName()); } bool FossilPluginPrivate::vcsMove(const FilePath &from, const FilePath &to) { const QFileInfo fromInfo = from.toFileInfo(); const QFileInfo toInfo = to.toFileInfo(); - return m_client.synchronousMove(from.absolutePath(), fromInfo.absoluteFilePath(), + return fossilClient().synchronousMove(from.absolutePath(), fromInfo.absoluteFilePath(), toInfo.absoluteFilePath()); } bool FossilPluginPrivate::vcsCreateRepository(const FilePath &directory) { - return m_client.synchronousCreateRepository(directory); + return fossilClient().synchronousCreateRepository(directory); } void FossilPluginPrivate::vcsAnnotate(const FilePath &filePath, int line) { - m_client.annotate(filePath.absolutePath(), filePath.fileName(), line); + fossilClient().annotate(filePath.absolutePath(), filePath.fileName(), line); } void FossilPluginPrivate::vcsDescribe(const FilePath &source, const QString &id) { - m_client.view(source, id); + fossilClient().view(source, id); } VcsCommand *FossilPluginPrivate::createInitialCheckoutCommand(const QString &sourceUrl, @@ -987,7 +978,7 @@ VcsCommand *FossilPluginPrivate::createInitialCheckoutCommand(const QString &sou checkoutPath.createDir(); // Setup the wizard page command job - auto command = VcsBaseClient::createVcsCommand(checkoutPath, m_client.processEnvironment()); + auto command = VcsBaseClient::createVcsCommand(checkoutPath, fossilClient().processEnvironment()); if (!isLocalRepository && !cloneRepository.exists()) { @@ -1019,11 +1010,11 @@ VcsCommand *FossilPluginPrivate::createInitialCheckoutCommand(const QString &sou // So here we want Fossil to save the remote details when specified. QStringList args; - args << m_client.vcsCommandString(FossilClient::CloneCommand) + args << fossilClient().vcsCommandString(FossilClient::CloneCommand) << extraOptions << sourceUrl << fossilFileNative; - command->addJob({m_client.vcsBinary(), args}, -1); + command->addJob({fossilClient().vcsBinary(), args}, -1); } // check out the cloned repository file into the working copy directory; @@ -1032,20 +1023,20 @@ VcsCommand *FossilPluginPrivate::createInitialCheckoutCommand(const QString &sou QStringList args({"open", fossilFileNative}); if (!checkoutBranch.isEmpty()) args << checkoutBranch; - command->addJob({m_client.vcsBinary(), args}, -1); + command->addJob({fossilClient().vcsBinary(), args}, -1); // set user default to admin user if specified if (!isLocalRepository && !adminUser.isEmpty()) { const QStringList args({ "user", "default", adminUser, "--user", adminUser}); - command->addJob({m_client.vcsBinary(), args}, -1); + command->addJob({fossilClient().vcsBinary(), args}, -1); } // turn-off autosync if requested if (!isLocalRepository && disableAutosync) { const QStringList args({"settings", "autosync", "off"}); - command->addJob({m_client.vcsBinary(), args}, -1); + command->addJob({fossilClient().vcsBinary(), args}, -1); } return command; @@ -1094,13 +1085,9 @@ RevertDialog::RevertDialog(const QString &title, QWidget *parent) }.attachTo(this); } -} // namespace Internal -} // namespace Fossil - #ifdef WITH_TESTS -#include -void Fossil::Internal::FossilPlugin::testDiffFileResolving_data() +void FossilPlugin::testDiffFileResolving_data() { QTest::addColumn("header"); QTest::addColumn("fileName"); @@ -1133,12 +1120,12 @@ void Fossil::Internal::FossilPlugin::testDiffFileResolving_data() << QByteArray("src/plugins/fossil/fossilclient.cpp"); } -void Fossil::Internal::FossilPlugin::testDiffFileResolving() +void FossilPlugin::testDiffFileResolving() { VcsBaseEditorWidget::testDiffFileResolving(dd->diffFactory); } -void Fossil::Internal::FossilPlugin::testLogResolving() +void FossilPlugin::testLogResolving() { QByteArray data( "=== 2014-03-08 ===\n" @@ -1151,3 +1138,5 @@ void Fossil::Internal::FossilPlugin::testLogResolving() VcsBaseEditorWidget::testLogResolving(dd->fileLogFactory, data, "ac6d1129b8", "56d6917c3b"); } #endif + +} // namespace Fossil::Internal diff --git a/src/plugins/fossil/fossilplugin.h b/src/plugins/fossil/fossilplugin.h index 033e22822c0..c9fafc3cafa 100644 --- a/src/plugins/fossil/fossilplugin.h +++ b/src/plugins/fossil/fossilplugin.h @@ -8,8 +8,6 @@ namespace Fossil { namespace Internal { -class FossilClient; - class FossilPlugin final : public ExtensionSystem::IPlugin { Q_OBJECT @@ -20,9 +18,6 @@ class FossilPlugin final : public ExtensionSystem::IPlugin bool initialize(const QStringList &arguments, QString *errorMessage) final; void extensionsInitialized() final; -public: - static FossilClient *client(); - #ifdef WITH_TESTS private slots: void testDiffFileResolving_data(); From 8aa78b119a93c28fd7c1cef3a1c1da186582ebcb Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 12:59:54 +0100 Subject: [PATCH 0269/1546] Fossil: Move plugin class definition to .cpp And split out the tests into a separate class. Change-Id: I908c4cec5d6a69850867cf2e51c050c8dd356a26 Reviewed-by: Orgad Shaneh --- src/plugins/fossil/CMakeLists.txt | 2 +- src/plugins/fossil/fossil.qbs | 2 +- src/plugins/fossil/fossilplugin.cpp | 67 ++++++++++++------- src/plugins/fossil/fossilplugin.h | 30 --------- .../fossil/wizard/fossiljsextension.cpp | 1 - 5 files changed, 44 insertions(+), 58 deletions(-) delete mode 100644 src/plugins/fossil/fossilplugin.h diff --git a/src/plugins/fossil/CMakeLists.txt b/src/plugins/fossil/CMakeLists.txt index 07485229450..11aac0bc633 100644 --- a/src/plugins/fossil/CMakeLists.txt +++ b/src/plugins/fossil/CMakeLists.txt @@ -11,7 +11,7 @@ add_qtc_plugin(Fossil fossilclient.cpp fossilclient.h fossilcommitwidget.cpp fossilcommitwidget.h fossileditor.cpp fossileditor.h - fossilplugin.cpp fossilplugin.h + fossilplugin.cpp fossilsettings.cpp fossilsettings.h fossiltr.h pullorpushdialog.cpp pullorpushdialog.h diff --git a/src/plugins/fossil/fossil.qbs b/src/plugins/fossil/fossil.qbs index e29b89dd34f..058032fce5f 100644 --- a/src/plugins/fossil/fossil.qbs +++ b/src/plugins/fossil/fossil.qbs @@ -21,7 +21,7 @@ QtcPlugin { "fossilclient.cpp", "fossilclient.h", "fossilcommitwidget.cpp", "fossilcommitwidget.h", "fossileditor.cpp", "fossileditor.h", - "fossilplugin.cpp", "fossilplugin.h", + "fossilplugin.cpp", "fossilsettings.cpp", "fossilsettings.h", "fossiltr.h", "pullorpushdialog.cpp", "pullorpushdialog.h", diff --git a/src/plugins/fossil/fossilplugin.cpp b/src/plugins/fossil/fossilplugin.cpp index d0a8dcc5301..d598c5c3239 100644 --- a/src/plugins/fossil/fossilplugin.cpp +++ b/src/plugins/fossil/fossilplugin.cpp @@ -1,8 +1,6 @@ // Copyright (c) 2018 Artur Shepilko // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "fossilplugin.h" - #include "commiteditor.h" #include "configuredialog.h" #include "constants.h" @@ -39,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -244,26 +243,6 @@ private: QLineEdit *m_revisionLineEdit = nullptr; }; -FossilPlugin::~FossilPlugin() -{ - delete dd; - dd = nullptr; -} - -bool FossilPlugin::initialize(const QStringList &arguments, QString *errorMessage) -{ - Q_UNUSED(arguments); - Q_UNUSED(errorMessage); - - dd = new FossilPluginPrivate; - - return true; -} - -void FossilPlugin::extensionsInitialized() -{ - dd->extensionsInitialized(); -} FossilPluginPrivate::FossilPluginPrivate() : VcsBasePluginPrivate(Context(Constants::FOSSIL_CONTEXT)) @@ -1087,7 +1066,17 @@ RevertDialog::RevertDialog(const QString &title, QWidget *parent) #ifdef WITH_TESTS -void FossilPlugin::testDiffFileResolving_data() +class FossilTests final : public QObject +{ + Q_OBJECT + +private slots: + void testDiffFileResolving_data(); + void testDiffFileResolving(); + void testLogResolving(); +}; + +void FossilTests::testDiffFileResolving_data() { QTest::addColumn("header"); QTest::addColumn("fileName"); @@ -1120,12 +1109,12 @@ void FossilPlugin::testDiffFileResolving_data() << QByteArray("src/plugins/fossil/fossilclient.cpp"); } -void FossilPlugin::testDiffFileResolving() +void FossilTests::testDiffFileResolving() { VcsBaseEditorWidget::testDiffFileResolving(dd->diffFactory); } -void FossilPlugin::testLogResolving() +void FossilTests::testLogResolving() { QByteArray data( "=== 2014-03-08 ===\n" @@ -1139,4 +1128,32 @@ void FossilPlugin::testLogResolving() } #endif +class FossilPlugin final : public ExtensionSystem::IPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Fossil.json") + + ~FossilPlugin() final + { + delete dd; + dd = nullptr; + } + + void initialize() final + { + dd = new FossilPluginPrivate; + +#ifdef WITH_TESTS + addTest(); +#endif + } + + void extensionsInitialized() final + { + dd->extensionsInitialized(); + } +}; + } // namespace Fossil::Internal + +#include "fossilplugin.moc" diff --git a/src/plugins/fossil/fossilplugin.h b/src/plugins/fossil/fossilplugin.h deleted file mode 100644 index c9fafc3cafa..00000000000 --- a/src/plugins/fossil/fossilplugin.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2018 Artur Shepilko -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace Fossil { -namespace Internal { - -class FossilPlugin final : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Fossil.json") - - ~FossilPlugin() final; - - bool initialize(const QStringList &arguments, QString *errorMessage) final; - void extensionsInitialized() final; - -#ifdef WITH_TESTS -private slots: - void testDiffFileResolving_data(); - void testDiffFileResolving(); - void testLogResolving(); -#endif -}; - -} // namespace Internal -} // namespace Fossil diff --git a/src/plugins/fossil/wizard/fossiljsextension.cpp b/src/plugins/fossil/wizard/fossiljsextension.cpp index aaf5d172b67..44c11f024a1 100644 --- a/src/plugins/fossil/wizard/fossiljsextension.cpp +++ b/src/plugins/fossil/wizard/fossiljsextension.cpp @@ -4,7 +4,6 @@ #include "fossiljsextension.h" #include "../constants.h" #include "../fossilclient.h" -#include "../fossilplugin.h" #include #include From 11d5fbe04cada3b844699483b740cd9dc3dc8320 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 17:01:21 +0100 Subject: [PATCH 0270/1546] ImageViewer: Move Viewer class definition to .cpp And de-pimpl. Change-Id: I2c4acc95a7d583b4bfbc98bee3c989425d9306c1 Reviewed-by: Jarek Kobus --- src/plugins/imageviewer/imageviewer.cpp | 311 +++++++++++++----------- src/plugins/imageviewer/imageviewer.h | 41 +--- 2 files changed, 169 insertions(+), 183 deletions(-) diff --git a/src/plugins/imageviewer/imageviewer.cpp b/src/plugins/imageviewer/imageviewer.cpp index d7694e654dc..fac7aaeefac 100644 --- a/src/plugins/imageviewer/imageviewer.cpp +++ b/src/plugins/imageviewer/imageviewer.cpp @@ -10,7 +10,6 @@ #include "imageviewertr.h" #include -#include #include #include #include @@ -26,42 +25,69 @@ #include #include -#include -#include #include #include #include -#include #include #include #include -#include using namespace Core; using namespace Utils; namespace ImageViewer::Internal{ -struct ImageViewerPrivate +class ImageViewer : public IEditor { - QString displayName; - QSharedPointer file; - ImageView *imageView; - QWidget *toolbar; + Q_OBJECT - QToolButton *shareButton; - CommandAction *actionExportImage; - CommandAction *actionMultiExportImages; - CommandAction *actionButtonCopyDataUrl; - CommandAction *actionBackground; - CommandAction *actionOutline; - CommandAction *actionFitToScreen; - CommandAction *actionOriginalSize; - CommandAction *actionZoomIn; - CommandAction *actionZoomOut; - CommandAction *actionPlayPause; - QLabel *labelImageSize; - QLabel *labelInfo; +public: + ImageViewer(); + ~ImageViewer() override; + + Core::IDocument *document() const override; + QWidget *toolBar() override; + + IEditor *duplicate() override; + + void exportImage(); + void exportMultiImages(); + void copyDataUrl(); + void imageSizeUpdated(const QSize &size); + void scaleFactorUpdate(qreal factor); + + void switchViewBackground(); + void switchViewOutline(); + void zoomIn(); + void zoomOut(); + void resetToOriginalSize(); + void fitToScreen(); + void updateToolButtons(); + void togglePlay(); + +private: + ImageViewer(const QSharedPointer &document); + void ctor(); + void playToggled(); + void updatePauseAction(); + + QSharedPointer m_file; + ImageView *m_imageView; + QWidget *m_toolbar; + + QToolButton *m_shareButton; + CommandAction *m_actionExportImage; + CommandAction *m_actionMultiExportImages; + CommandAction *m_actionButtonCopyDataUrl; + CommandAction *m_actionBackground; + CommandAction *m_actionOutline; + CommandAction *m_actionFitToScreen; + CommandAction *m_actionOriginalSize; + CommandAction *m_actionZoomIn; + CommandAction *m_actionZoomOut; + CommandAction *m_actionPlayPause; + QLabel *m_labelImageSize; + QLabel *m_labelInfo; }; /*! @@ -82,88 +108,86 @@ static bool updateIconByTheme(QAction *action, const QString &name) } ImageViewer::ImageViewer() - : d(new ImageViewerPrivate) { - d->file.reset(new ImageViewerFile); + m_file.reset(new ImageViewerFile); ctor(); } ImageViewer::ImageViewer(const QSharedPointer &document) - : d(new ImageViewerPrivate) { - d->file = document; + m_file = document; ctor(); } void ImageViewer::ctor() { - d->imageView = new ImageView(d->file.data()); - d->imageView->readSettings(ICore::settings()); - const ImageView::Settings settings = d->imageView->settings(); + m_imageView = new ImageView(m_file.data()); + m_imageView->readSettings(ICore::settings()); + const ImageView::Settings settings = m_imageView->settings(); setContext(Core::Context(Constants::IMAGEVIEWER_ID)); - setWidget(d->imageView); + setWidget(m_imageView); setDuplicateSupported(true); // toolbar - d->toolbar = new StyledBar; + m_toolbar = new StyledBar; - d->actionExportImage = new CommandAction(Constants::ACTION_EXPORT_IMAGE, d->toolbar); - d->actionMultiExportImages = new CommandAction(Constants::ACTION_EXPORT_MULTI_IMAGES, - d->toolbar); - d->actionButtonCopyDataUrl = new CommandAction(Constants::ACTION_COPY_DATA_URL, d->toolbar); - d->shareButton = new QToolButton; - d->shareButton->setToolTip(Tr::tr("Export")); - d->shareButton->setPopupMode(QToolButton::InstantPopup); - d->shareButton->setIcon(Icons::EXPORTFILE_TOOLBAR.icon()); - d->shareButton->setProperty(StyleHelper::C_NO_ARROW, true); - auto shareMenu = new QMenu(d->shareButton); - shareMenu->addAction(d->actionExportImage); - shareMenu->addAction(d->actionMultiExportImages); - shareMenu->addAction(d->actionButtonCopyDataUrl); - d->shareButton->setMenu(shareMenu); + m_actionExportImage = new CommandAction(Constants::ACTION_EXPORT_IMAGE, m_toolbar); + m_actionMultiExportImages = new CommandAction(Constants::ACTION_EXPORT_MULTI_IMAGES, + m_toolbar); + m_actionButtonCopyDataUrl = new CommandAction(Constants::ACTION_COPY_DATA_URL, m_toolbar); + m_shareButton = new QToolButton; + m_shareButton->setToolTip(Tr::tr("Export")); + m_shareButton->setPopupMode(QToolButton::InstantPopup); + m_shareButton->setIcon(Icons::EXPORTFILE_TOOLBAR.icon()); + m_shareButton->setProperty(StyleHelper::C_NO_ARROW, true); + auto shareMenu = new QMenu(m_shareButton); + shareMenu->addAction(m_actionExportImage); + shareMenu->addAction(m_actionMultiExportImages); + shareMenu->addAction(m_actionButtonCopyDataUrl); + m_shareButton->setMenu(shareMenu); - d->actionBackground = new CommandAction(Constants::ACTION_BACKGROUND, d->toolbar); - d->actionOutline = new CommandAction(Constants::ACTION_OUTLINE, d->toolbar); - d->actionFitToScreen = new CommandAction(Constants::ACTION_FIT_TO_SCREEN, d->toolbar); - d->actionOriginalSize = new CommandAction(Core::Constants::ZOOM_RESET, d->toolbar); - d->actionZoomIn = new CommandAction(Core::Constants::ZOOM_IN, d->toolbar); - d->actionZoomOut = new CommandAction(Core::Constants::ZOOM_OUT, d->toolbar); - d->actionPlayPause = new CommandAction(Constants::ACTION_TOGGLE_ANIMATION, d->toolbar); + m_actionBackground = new CommandAction(Constants::ACTION_BACKGROUND, m_toolbar); + m_actionOutline = new CommandAction(Constants::ACTION_OUTLINE, m_toolbar); + m_actionFitToScreen = new CommandAction(Constants::ACTION_FIT_TO_SCREEN, m_toolbar); + m_actionOriginalSize = new CommandAction(Core::Constants::ZOOM_RESET, m_toolbar); + m_actionZoomIn = new CommandAction(Core::Constants::ZOOM_IN, m_toolbar); + m_actionZoomOut = new CommandAction(Core::Constants::ZOOM_OUT, m_toolbar); + m_actionPlayPause = new CommandAction(Constants::ACTION_TOGGLE_ANIMATION, m_toolbar); - d->actionBackground->setCheckable(true); - d->actionBackground->setChecked(settings.showBackground); + m_actionBackground->setCheckable(true); + m_actionBackground->setChecked(settings.showBackground); - d->actionOutline->setCheckable(true); - d->actionOutline->setChecked(settings.showOutline); + m_actionOutline->setCheckable(true); + m_actionOutline->setChecked(settings.showOutline); - d->actionFitToScreen->setCheckable(true); - d->actionFitToScreen->setChecked(settings.fitToScreen); + m_actionFitToScreen->setCheckable(true); + m_actionFitToScreen->setChecked(settings.fitToScreen); - d->actionZoomIn->setAutoRepeat(true); + m_actionZoomIn->setAutoRepeat(true); - d->actionZoomOut->setAutoRepeat(true); + m_actionZoomOut->setAutoRepeat(true); const Icon backgroundIcon({{":/utils/images/desktopdevicesmall.png", Theme::IconsBaseColor}}); - d->actionBackground->setIcon(backgroundIcon.icon()); - d->actionOutline->setIcon(Icons::BOUNDING_RECT.icon()); - d->actionZoomIn->setIcon(ActionManager::command(Core::Constants::ZOOM_IN)->action()->icon()); - d->actionZoomOut->setIcon(ActionManager::command(Core::Constants::ZOOM_OUT)->action()->icon()); - d->actionOriginalSize->setIcon( + m_actionBackground->setIcon(backgroundIcon.icon()); + m_actionOutline->setIcon(Icons::BOUNDING_RECT.icon()); + m_actionZoomIn->setIcon(ActionManager::command(Core::Constants::ZOOM_IN)->action()->icon()); + m_actionZoomOut->setIcon(ActionManager::command(Core::Constants::ZOOM_OUT)->action()->icon()); + m_actionOriginalSize->setIcon( ActionManager::command(Core::Constants::ZOOM_RESET)->action()->icon()); - d->actionFitToScreen->setIcon(Icons::FITTOVIEW_TOOLBAR.icon()); + m_actionFitToScreen->setIcon(Icons::FITTOVIEW_TOOLBAR.icon()); // icons update - try to use system theme - updateIconByTheme(d->actionFitToScreen, QLatin1String("zoom-fit-best")); + updateIconByTheme(m_actionFitToScreen, QLatin1String("zoom-fit-best")); // a display - something is on the background - updateIconByTheme(d->actionBackground, QLatin1String("video-display")); + updateIconByTheme(m_actionBackground, QLatin1String("video-display")); // "emblem to specify the directory where the user stores photographs" // (photograph has outline - piece of paper) - updateIconByTheme(d->actionOutline, QLatin1String("emblem-photos")); + updateIconByTheme(m_actionOutline, QLatin1String("emblem-photos")); - auto setAsDefault = new QAction(Tr::tr("Set as Default"), d->toolbar); + auto setAsDefault = new QAction(Tr::tr("Set as Default"), m_toolbar); const auto updateSetAsDefaultToolTip = [this, setAsDefault] { - const ImageView::Settings settings = d->imageView->settings(); + const ImageView::Settings settings = m_imageView->settings(); const QString on = Tr::tr("on"); const QString off = Tr::tr("off"); setAsDefault->setToolTip( @@ -176,100 +200,99 @@ void ImageViewer::ctor() }; updateSetAsDefaultToolTip(); - d->labelImageSize = new QLabel; - d->labelInfo = new QLabel; + m_labelImageSize = new QLabel; + m_labelInfo = new QLabel; auto bar = new QToolBar; bar->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum); - bar->addWidget(d->shareButton); + bar->addWidget(m_shareButton); bar->addSeparator(); - bar->addAction(d->actionOriginalSize); - bar->addAction(d->actionZoomIn); - bar->addAction(d->actionZoomOut); - bar->addAction(d->actionPlayPause); - bar->addAction(d->actionPlayPause); + bar->addAction(m_actionOriginalSize); + bar->addAction(m_actionZoomIn); + bar->addAction(m_actionZoomOut); + bar->addAction(m_actionPlayPause); + bar->addAction(m_actionPlayPause); bar->addSeparator(); - bar->addAction(d->actionBackground); - bar->addAction(d->actionOutline); - bar->addAction(d->actionFitToScreen); + bar->addAction(m_actionBackground); + bar->addAction(m_actionOutline); + bar->addAction(m_actionFitToScreen); bar->addAction(setAsDefault); - auto horizontalLayout = new QHBoxLayout(d->toolbar); + auto horizontalLayout = new QHBoxLayout(m_toolbar); horizontalLayout->setSpacing(0); horizontalLayout->setContentsMargins(0, 0, 0, 0); horizontalLayout->addWidget(bar); horizontalLayout->addItem( new QSpacerItem(315, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); horizontalLayout->addWidget(new StyledSeparator); - horizontalLayout->addWidget(d->labelImageSize); + horizontalLayout->addWidget(m_labelImageSize); horizontalLayout->addWidget(new StyledSeparator); - horizontalLayout->addWidget(d->labelInfo); + horizontalLayout->addWidget(m_labelInfo); // connections - connect(d->actionExportImage, &QAction::triggered, d->imageView, &ImageView::exportImage); - connect(d->actionMultiExportImages, + connect(m_actionExportImage, &QAction::triggered, m_imageView, &ImageView::exportImage); + connect(m_actionMultiExportImages, &QAction::triggered, - d->imageView, + m_imageView, &ImageView::exportMultiImages); - connect(d->actionButtonCopyDataUrl, &QAction::triggered, d->imageView, &ImageView::copyDataUrl); - connect(d->actionZoomIn, &QAction::triggered, d->imageView, &ImageView::zoomIn); - connect(d->actionZoomOut, &QAction::triggered, d->imageView, &ImageView::zoomOut); - connect(d->actionFitToScreen, &QAction::triggered, d->imageView, &ImageView::setFitToScreen); - connect(d->imageView, + connect(m_actionButtonCopyDataUrl, &QAction::triggered, m_imageView, &ImageView::copyDataUrl); + connect(m_actionZoomIn, &QAction::triggered, m_imageView, &ImageView::zoomIn); + connect(m_actionZoomOut, &QAction::triggered, m_imageView, &ImageView::zoomOut); + connect(m_actionFitToScreen, &QAction::triggered, m_imageView, &ImageView::setFitToScreen); + connect(m_imageView, &ImageView::fitToScreenChanged, - d->actionFitToScreen, + m_actionFitToScreen, &QAction::setChecked); - connect(d->actionOriginalSize, + connect(m_actionOriginalSize, &QAction::triggered, - d->imageView, + m_imageView, &ImageView::resetToOriginalSize); - connect(d->actionBackground, &QAction::toggled, d->imageView, &ImageView::setViewBackground); - connect(d->actionOutline, &QAction::toggled, d->imageView, &ImageView::setViewOutline); - connect(d->actionPlayPause, &QAction::triggered, this, &ImageViewer::playToggled); - connect(d->file.data(), &ImageViewerFile::imageSizeChanged, + connect(m_actionBackground, &QAction::toggled, m_imageView, &ImageView::setViewBackground); + connect(m_actionOutline, &QAction::toggled, m_imageView, &ImageView::setViewOutline); + connect(m_actionPlayPause, &QAction::triggered, this, &ImageViewer::playToggled); + connect(m_file.data(), &ImageViewerFile::imageSizeChanged, this, &ImageViewer::imageSizeUpdated); - connect(d->file.data(), &ImageViewerFile::openFinished, - d->imageView, &ImageView::createScene); - connect(d->file.data(), &ImageViewerFile::openFinished, + connect(m_file.data(), &ImageViewerFile::openFinished, + m_imageView, &ImageView::createScene); + connect(m_file.data(), &ImageViewerFile::openFinished, this, &ImageViewer::updateToolButtons); - connect(d->file.data(), &ImageViewerFile::aboutToReload, - d->imageView, &ImageView::reset); - connect(d->file.data(), &ImageViewerFile::reloadFinished, - d->imageView, &ImageView::createScene); - connect(d->file.data(), &ImageViewerFile::movieStateChanged, + connect(m_file.data(), &ImageViewerFile::aboutToReload, + m_imageView, &ImageView::reset); + connect(m_file.data(), &ImageViewerFile::reloadFinished, + m_imageView, &ImageView::createScene); + connect(m_file.data(), &ImageViewerFile::movieStateChanged, this, &ImageViewer::updatePauseAction); - connect(d->imageView, &ImageView::scaleFactorChanged, + connect(m_imageView, &ImageView::scaleFactorChanged, this, &ImageViewer::scaleFactorUpdate); - connect(setAsDefault, &QAction::triggered, d->imageView, [this, updateSetAsDefaultToolTip] { - d->imageView->writeSettings(ICore::settings()); + connect(setAsDefault, &QAction::triggered, m_imageView, [this, updateSetAsDefaultToolTip] { + m_imageView->writeSettings(ICore::settings()); updateSetAsDefaultToolTip(); }); } ImageViewer::~ImageViewer() { - delete d->imageView; - delete d->toolbar; - delete d; + delete m_imageView; + delete m_toolbar; } IDocument *ImageViewer::document() const { - return d->file.data(); + return m_file.data(); } QWidget *ImageViewer::toolBar() { - return d->toolbar; + return m_toolbar; } IEditor *ImageViewer::duplicate() { - auto other = new ImageViewer(d->file); - other->d->imageView->createScene(); + auto other = new ImageViewer(m_file); + other->m_imageView->createScene(); other->updateToolButtons(); - other->d->labelImageSize->setText(d->labelImageSize->text()); + other->m_labelImageSize->setText(m_labelImageSize->text()); emit editorDuplicated(other); @@ -278,19 +301,19 @@ IEditor *ImageViewer::duplicate() void ImageViewer::exportImage() { - if (d->file->type() == ImageViewerFile::TypeSvg) - d->actionExportImage->trigger(); + if (m_file->type() == ImageViewerFile::TypeSvg) + m_actionExportImage->trigger(); } void ImageViewer::exportMultiImages() { - if (d->file->type() == ImageViewerFile::TypeSvg) - d->actionMultiExportImages->trigger(); + if (m_file->type() == ImageViewerFile::TypeSvg) + m_actionMultiExportImages->trigger(); } void ImageViewer::copyDataUrl() { - d->actionButtonCopyDataUrl->trigger(); + m_actionButtonCopyDataUrl->trigger(); } void ImageViewer::imageSizeUpdated(const QSize &size) @@ -298,64 +321,64 @@ void ImageViewer::imageSizeUpdated(const QSize &size) QString imageSizeText; if (size.isValid()) imageSizeText = QString::fromLatin1("%1x%2").arg(size.width()).arg(size.height()); - d->labelImageSize->setText(imageSizeText); + m_labelImageSize->setText(imageSizeText); } void ImageViewer::scaleFactorUpdate(qreal factor) { const QString info = QString::number(factor * 100, 'f', 2) + QLatin1Char('%'); - d->labelInfo->setText(info); + m_labelInfo->setText(info); } void ImageViewer::switchViewBackground() { - d->actionBackground->trigger(); + m_actionBackground->trigger(); } void ImageViewer::switchViewOutline() { - d->actionOutline->trigger(); + m_actionOutline->trigger(); } void ImageViewer::zoomIn() { - d->actionZoomIn->trigger(); + m_actionZoomIn->trigger(); } void ImageViewer::zoomOut() { - d->actionZoomOut->trigger(); + m_actionZoomOut->trigger(); } void ImageViewer::resetToOriginalSize() { - d->actionOriginalSize->trigger(); + m_actionOriginalSize->trigger(); } void ImageViewer::fitToScreen() { - d->actionFitToScreen->trigger(); + m_actionFitToScreen->trigger(); } void ImageViewer::updateToolButtons() { - const bool isSvg = d->file->type() == ImageViewerFile::TypeSvg; - d->actionExportImage->setEnabled(isSvg); - d->actionMultiExportImages->setEnabled(isSvg); + const bool isSvg = m_file->type() == ImageViewerFile::TypeSvg; + m_actionExportImage->setEnabled(isSvg); + m_actionMultiExportImages->setEnabled(isSvg); updatePauseAction(); } void ImageViewer::togglePlay() { - d->actionPlayPause->trigger(); + m_actionPlayPause->trigger(); } void ImageViewer::playToggled() { - QMovie *m = d->file->movie(); + QMovie *m = m_file->movie(); if (!m) return; - const QMovie::MovieState state = d->file->movie()->state(); + const QMovie::MovieState state = m_file->movie()->state(); switch (state) { case QMovie::NotRunning: m->start(); @@ -371,9 +394,9 @@ void ImageViewer::playToggled() void ImageViewer::updatePauseAction() { - const bool isMovie = d->file->type() == ImageViewerFile::TypeMovie; - const QMovie::MovieState state = isMovie ? d->file->movie()->state() : QMovie::NotRunning; - CommandAction *a = d->actionPlayPause; + const bool isMovie = m_file->type() == ImageViewerFile::TypeMovie; + const QMovie::MovieState state = isMovie ? m_file->movie()->state() : QMovie::NotRunning; + CommandAction *a = m_actionPlayPause; switch (state) { case QMovie::NotRunning: a->setToolTipBase(Tr::tr("Play Animation")); @@ -393,7 +416,7 @@ void ImageViewer::updatePauseAction() // Factory -class ImageViewerFactory final : public Core::IEditorFactory +class ImageViewerFactory final : public IEditorFactory { public: ImageViewerFactory() @@ -458,3 +481,5 @@ void setupImageViewer(QObject *guard) } } // ImageViewer::Internal + +#include "imageviewer.moc" diff --git a/src/plugins/imageviewer/imageviewer.h b/src/plugins/imageviewer/imageviewer.h index 22b535b22fb..8b34c2bc52e 100644 --- a/src/plugins/imageviewer/imageviewer.h +++ b/src/plugins/imageviewer/imageviewer.h @@ -4,49 +4,10 @@ #pragma once -#include +#include namespace ImageViewer::Internal { -class ImageViewerFile; - -class ImageViewer : public Core::IEditor -{ - Q_OBJECT - -public: - ImageViewer(); - ~ImageViewer() override; - - Core::IDocument *document() const override; - QWidget *toolBar() override; - - IEditor *duplicate() override; - - void exportImage(); - void exportMultiImages(); - void copyDataUrl(); - void imageSizeUpdated(const QSize &size); - void scaleFactorUpdate(qreal factor); - - void switchViewBackground(); - void switchViewOutline(); - void zoomIn(); - void zoomOut(); - void resetToOriginalSize(); - void fitToScreen(); - void updateToolButtons(); - void togglePlay(); - -private: - ImageViewer(const QSharedPointer &document); - void ctor(); - void playToggled(); - void updatePauseAction(); - - struct ImageViewerPrivate *d; -}; - void setupImageViewer(QObject *guard); } // ImageViewer::Internal From d9b8702d57ddfbb4469af26e7093dbdbbdb8f0ce Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 17:11:44 +0100 Subject: [PATCH 0271/1546] ImageViewer: Code cosmetics Change-Id: I946d1f0ce9be10f1f31441ac7f0b7fa7216b70db Reviewed-by: Jarek Kobus --- src/plugins/imageviewer/imageview.cpp | 18 +++--- src/plugins/imageviewer/imageview.h | 8 +-- src/plugins/imageviewer/imageviewer.cpp | 58 +++++++++---------- .../imageviewer/imageviewerconstants.h | 2 - src/plugins/imageviewer/imageviewerfile.cpp | 3 +- 5 files changed, 39 insertions(+), 50 deletions(-) diff --git a/src/plugins/imageviewer/imageview.cpp b/src/plugins/imageviewer/imageview.cpp index 01d9b3968fc..9ce18a41d3d 100644 --- a/src/plugins/imageviewer/imageview.cpp +++ b/src/plugins/imageviewer/imageview.cpp @@ -9,16 +9,14 @@ #include "imageviewertr.h" #include "multiexportdialog.h" +#include #include -#include #include #include #include #include -#include -#include #include #include #include @@ -42,14 +40,13 @@ const char kSettingsFitToScreen[] = "FitToScreen"; using namespace Utils; -namespace ImageViewer { +namespace ImageViewer::Internal { + namespace Constants { const qreal DEFAULT_SCALE_FACTOR = 1.2; const qreal zoomLevels[] = { 0.25, 0.5, 0.75, 1.0, 1.5, 2.0, 4.0, 8.0 }; } -namespace Internal { - static qreal nextLevel(qreal currentLevel) { auto iter = std::find_if(std::begin(Constants::zoomLevels), std::end(Constants::zoomLevels), [&](qreal val) { @@ -319,8 +316,9 @@ void ImageView::setFitToScreen(bool fit) emit fitToScreenChanged(m_settings.fitToScreen); } -void ImageView::readSettings(Utils::QtcSettings *settings) +void ImageView::readSettings() { + QtcSettings *settings = Core::ICore::settings(); const Settings def; settings->beginGroup(kSettingsGroup); m_settings.showBackground = settings->value(kSettingsBackground, def.showBackground).toBool(); @@ -329,8 +327,9 @@ void ImageView::readSettings(Utils::QtcSettings *settings) settings->endGroup(); } -void ImageView::writeSettings(Utils::QtcSettings *settings) const +void ImageView::writeSettings() const { + QtcSettings *settings = Core::ICore::settings(); const Settings def; settings->beginGroup(kSettingsGroup); settings->setValueWithDefault(kSettingsBackground, @@ -369,5 +368,4 @@ void ImageView::hideEvent(QHideEvent *) m_file->updateVisibility(); } -} // namespace Internal -} // namespace ImageView +} // namespace ImageView::Internal diff --git a/src/plugins/imageviewer/imageview.h b/src/plugins/imageviewer/imageview.h index e5cf20ea808..08d495dc89b 100644 --- a/src/plugins/imageviewer/imageview.h +++ b/src/plugins/imageviewer/imageview.h @@ -12,10 +12,6 @@ QT_BEGIN_NAMESPACE class QImage; QT_END_NAMESPACE -namespace Utils { -class QtcSettings; -} - namespace ImageViewer::Internal { class ImageViewerFile; @@ -53,8 +49,8 @@ public: void resetToOriginalSize(); void setFitToScreen(bool fit); - void readSettings(Utils::QtcSettings *settings); - void writeSettings(Utils::QtcSettings *settings) const; + void readSettings(); + void writeSettings() const; Settings settings() const; signals: diff --git a/src/plugins/imageviewer/imageviewer.cpp b/src/plugins/imageviewer/imageviewer.cpp index fac7aaeefac..a3e4e62c573 100644 --- a/src/plugins/imageviewer/imageviewer.cpp +++ b/src/plugins/imageviewer/imageviewer.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -122,7 +121,7 @@ ImageViewer::ImageViewer(const QSharedPointer &document) void ImageViewer::ctor() { m_imageView = new ImageView(m_file.data()); - m_imageView->readSettings(ICore::settings()); + m_imageView->readSettings(); const ImageView::Settings settings = m_imageView->settings(); setContext(Core::Context(Constants::IMAGEVIEWER_ID)); @@ -266,7 +265,7 @@ void ImageViewer::ctor() connect(m_imageView, &ImageView::scaleFactorChanged, this, &ImageViewer::scaleFactorUpdate); connect(setAsDefault, &QAction::triggered, m_imageView, [this, updateSetAsDefaultToolTip] { - m_imageView->writeSettings(ICore::settings()); + m_imageView->writeSettings(); updateSetAsDefaultToolTip(); }); } @@ -431,52 +430,51 @@ public: } }; -static void createAction(QObject *guard, Id id, - const std::function &onTriggered, - const QString &title = {}, - const QKeySequence &key = {}) -{ - ActionBuilder builder(guard, id); - builder.setText(title); - builder.setContext(Context(Constants::IMAGEVIEWER_ID)); - if (!key.isEmpty()) - builder.setDefaultKeySequence(key); - - builder.setOnTriggered(guard, [onTriggered] { - if (auto iv = qobject_cast(EditorManager::currentEditor())) - onTriggered(iv); - }); -} - void setupImageViewer(QObject *guard) { static ImageViewerFactory theImageViewerFactory; - createAction(guard, Core::Constants::ZOOM_IN, &ImageViewer::zoomIn); + auto createAction = [guard](Id id, + const std::function &onTriggered, + const QString &title = {}, + const QKeySequence &key = {}) { + ActionBuilder builder(guard, id); + builder.setText(title); + builder.setContext(Context(Constants::IMAGEVIEWER_ID)); + if (!key.isEmpty()) + builder.setDefaultKeySequence(key); - createAction(guard, Core::Constants::ZOOM_OUT, &ImageViewer::zoomOut); + builder.setOnTriggered(guard, [onTriggered] { + if (auto iv = qobject_cast(EditorManager::currentEditor())) + onTriggered(iv); + }); + }; - createAction(guard, Core::Constants::ZOOM_RESET, &ImageViewer::resetToOriginalSize); + createAction(Core::Constants::ZOOM_IN, &ImageViewer::zoomIn); - createAction(guard, Constants::ACTION_FIT_TO_SCREEN, &ImageViewer::fitToScreen, + createAction(Core::Constants::ZOOM_OUT, &ImageViewer::zoomOut); + + createAction(Core::Constants::ZOOM_RESET, &ImageViewer::resetToOriginalSize); + + createAction(Constants::ACTION_FIT_TO_SCREEN, &ImageViewer::fitToScreen, Tr::tr("Fit to Screen"), Tr::tr("Ctrl+=")); - createAction( guard, Constants::ACTION_BACKGROUND, &ImageViewer::switchViewBackground, + createAction(Constants::ACTION_BACKGROUND, &ImageViewer::switchViewBackground, Tr::tr("Switch Background"), Tr::tr("Ctrl+[")); - createAction(guard, Constants::ACTION_OUTLINE, &ImageViewer::switchViewOutline, + createAction(Constants::ACTION_OUTLINE, &ImageViewer::switchViewOutline, Tr::tr("Switch Outline"), Tr::tr("Ctrl+]")); - createAction(guard, Constants::ACTION_TOGGLE_ANIMATION, &ImageViewer::togglePlay, + createAction(Constants::ACTION_TOGGLE_ANIMATION, &ImageViewer::togglePlay, Tr::tr("Toggle Animation")); - createAction(guard, Constants::ACTION_EXPORT_IMAGE, &ImageViewer::exportImage, + createAction(Constants::ACTION_EXPORT_IMAGE, &ImageViewer::exportImage, Tr::tr("Export Image")); - createAction(guard, Constants::ACTION_EXPORT_MULTI_IMAGES, &ImageViewer::exportMultiImages, + createAction(Constants::ACTION_EXPORT_MULTI_IMAGES, &ImageViewer::exportMultiImages, Tr::tr("Export Multiple Images")); - createAction(guard, Constants::ACTION_COPY_DATA_URL, &ImageViewer::copyDataUrl, + createAction(Constants::ACTION_COPY_DATA_URL, &ImageViewer::copyDataUrl, Tr::tr("Copy as Data URL")); } diff --git a/src/plugins/imageviewer/imageviewerconstants.h b/src/plugins/imageviewer/imageviewerconstants.h index 3583ff39d65..8d12e6249cf 100644 --- a/src/plugins/imageviewer/imageviewerconstants.h +++ b/src/plugins/imageviewer/imageviewerconstants.h @@ -4,8 +4,6 @@ #pragma once -#include - namespace ImageViewer::Constants { const char IMAGEVIEWER_ID[] = "Editors.ImageViewer"; diff --git a/src/plugins/imageviewer/imageviewerfile.cpp b/src/plugins/imageviewer/imageviewerfile.cpp index 15a3d8d77b3..1d73a7fbeb4 100644 --- a/src/plugins/imageviewer/imageviewerfile.cpp +++ b/src/plugins/imageviewer/imageviewerfile.cpp @@ -6,16 +6,15 @@ #include "imageviewerconstants.h" #include "imageviewertr.h" -#include "utils/algorithm.h" #include #include +#include #include #include #include -#include #include #include #include From 69aa92159c6e07d429d9d0e69b05fe32ebf12a4c Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 15 Nov 2023 16:54:20 +0100 Subject: [PATCH 0272/1546] GitLab: Access GitlabParameter singleton more directly Change-Id: Ib4d333b6419bb2bdcdcf124d22d0473f6fd91cb9 Reviewed-by: Christian Stenger --- src/plugins/gitlab/gitlabdialog.cpp | 8 ++-- src/plugins/gitlab/gitlaboptionspage.cpp | 16 +++---- src/plugins/gitlab/gitlaboptionspage.h | 4 +- src/plugins/gitlab/gitlabparameters.cpp | 8 ++++ src/plugins/gitlab/gitlabparameters.h | 2 + src/plugins/gitlab/gitlabplugin.cpp | 46 +++++--------------- src/plugins/gitlab/gitlabplugin.h | 5 --- src/plugins/gitlab/gitlabprojectsettings.cpp | 10 ++--- src/plugins/gitlab/queryrunner.cpp | 5 +-- 9 files changed, 39 insertions(+), 65 deletions(-) diff --git a/src/plugins/gitlab/gitlabdialog.cpp b/src/plugins/gitlab/gitlabdialog.cpp index 9375c057f57..bffdf66fb5d 100644 --- a/src/plugins/gitlab/gitlabdialog.cpp +++ b/src/plugins/gitlab/gitlabdialog.cpp @@ -159,12 +159,11 @@ void GitLabDialog::resetTreeView(QTreeView *treeView, QAbstractItemModel *model) void GitLabDialog::updateRemotes() { m_remoteComboBox->clear(); - const GitLabParameters *global = GitLabPlugin::globalParameters(); - for (const GitLabServer &server : std::as_const(global->gitLabServers)) + for (const GitLabServer &server : std::as_const(gitLabParameters().gitLabServers)) m_remoteComboBox->addItem(server.displayString(), QVariant::fromValue(server)); m_remoteComboBox->setCurrentIndex(m_remoteComboBox->findData( - QVariant::fromValue(global->currentDefaultServer()))); + QVariant::fromValue(gitLabParameters().currentDefaultServer()))); } void GitLabDialog::keyPressEvent(QKeyEvent *event) @@ -198,8 +197,7 @@ void GitLabDialog::requestMainViewUpdate() if (!m_currentServerId.isValid()) m_currentServerId = m_remoteComboBox->currentData().value().id; if (m_currentServerId.isValid()) { - const GitLabParameters *global = GitLabPlugin::globalParameters(); - const GitLabServer server = global->serverForId(m_currentServerId); + const GitLabServer server = gitLabParameters().serverForId(m_currentServerId); m_remoteComboBox->setCurrentIndex(m_remoteComboBox->findData(QVariant::fromValue(server))); } m_remoteComboBox->setEnabled(!linked); diff --git a/src/plugins/gitlab/gitlaboptionspage.cpp b/src/plugins/gitlab/gitlaboptionspage.cpp index bb471c5a414..d550dd48452 100644 --- a/src/plugins/gitlab/gitlaboptionspage.cpp +++ b/src/plugins/gitlab/gitlaboptionspage.cpp @@ -132,7 +132,7 @@ void GitLabServerWidget::setGitLabServer(const GitLabServer &server) class GitLabOptionsWidget : public Core::IOptionsPageWidget { public: - explicit GitLabOptionsWidget(GitLabParameters *parameters); + GitLabOptionsWidget(); private: void showEditServerDialog(); @@ -151,8 +151,8 @@ private: FilePathAspect m_curl; }; -GitLabOptionsWidget::GitLabOptionsWidget(GitLabParameters *params) - : m_parameters(params) +GitLabOptionsWidget::GitLabOptionsWidget() + : m_parameters(&gitLabParameters()) { auto defaultLabel = new QLabel(Tr::tr("Default:"), this); m_defaultGitLabServer = new QComboBox(this); @@ -178,14 +178,14 @@ GitLabOptionsWidget::GitLabOptionsWidget(GitLabParameters *params) }, Column { m_add, m_edit, m_remove, st }, }.attachTo(this); - m_curl.setValue(params->curl); + m_curl.setValue(m_parameters->curl); - for (const auto &gitLabServer : params->gitLabServers) { + for (const auto &gitLabServer : m_parameters->gitLabServers) { m_defaultGitLabServer->addItem(gitLabServer.displayString(), QVariant::fromValue(gitLabServer)); } - const GitLabServer found = params->currentDefaultServer(); + const GitLabServer found = m_parameters->currentDefaultServer(); if (found.id.isValid()) { m_defaultGitLabServer->setCurrentIndex(m_defaultGitLabServer->findData( QVariant::fromValue(found))); @@ -298,12 +298,12 @@ void GitLabOptionsWidget::updateButtonsState() // GitLabOptionsPage -GitLabOptionsPage::GitLabOptionsPage(GitLabParameters *p) +GitLabOptionsPage::GitLabOptionsPage() { setId(Constants::GITLAB_SETTINGS); setDisplayName(Tr::tr("GitLab")); setCategory(VcsBase::Constants::VCS_SETTINGS_CATEGORY); - setWidgetCreator([p] { return new GitLabOptionsWidget(p); }); + setWidgetCreator([] { return new GitLabOptionsWidget; }); } } // namespace GitLab diff --git a/src/plugins/gitlab/gitlaboptionspage.h b/src/plugins/gitlab/gitlaboptionspage.h index 664f4a26fc1..9601f47cdaa 100644 --- a/src/plugins/gitlab/gitlaboptionspage.h +++ b/src/plugins/gitlab/gitlaboptionspage.h @@ -3,8 +3,6 @@ #pragma once -#include "gitlabparameters.h" - #include namespace GitLab { @@ -14,7 +12,7 @@ namespace Constants { const char GITLAB_SETTINGS[] = "GitLab"; } class GitLabOptionsPage : public Core::IOptionsPage { public: - explicit GitLabOptionsPage(GitLabParameters *p); + GitLabOptionsPage(); }; } // GitLab diff --git a/src/plugins/gitlab/gitlabparameters.cpp b/src/plugins/gitlab/gitlabparameters.cpp index e226d3a523f..fb3cefbd8f5 100644 --- a/src/plugins/gitlab/gitlabparameters.cpp +++ b/src/plugins/gitlab/gitlabparameters.cpp @@ -3,6 +3,8 @@ #include "gitlabparameters.h" +#include + #include #include #include @@ -202,4 +204,10 @@ GitLabServer GitLabParameters::serverForId(const Utils::Id &id) const }); } +GitLabParameters &gitLabParameters() +{ + static GitLabParameters theGitLabParameters; + return theGitLabParameters; +} + } // namespace GitLab diff --git a/src/plugins/gitlab/gitlabparameters.h b/src/plugins/gitlab/gitlabparameters.h index 7dcd6d9dafb..95e9962d837 100644 --- a/src/plugins/gitlab/gitlabparameters.h +++ b/src/plugins/gitlab/gitlabparameters.h @@ -74,6 +74,8 @@ public: Utils::FilePath curl; }; +GitLabParameters &gitLabParameters(); + } // namespace GitLab Q_DECLARE_METATYPE(GitLab::GitLabServer) diff --git a/src/plugins/gitlab/gitlabplugin.cpp b/src/plugins/gitlab/gitlabplugin.cpp index 73e726c9807..19a6f2eb142 100644 --- a/src/plugins/gitlab/gitlabplugin.cpp +++ b/src/plugins/gitlab/gitlabplugin.cpp @@ -45,13 +45,7 @@ public: void handleUser(const User &user); void handleEvents(const Events &events, const QDateTime &timeStamp); - void onSettingsChanged() { - if (dialog) - dialog->updateRemotes(); - } - - GitLabParameters parameters; - GitLabOptionsPage optionsPage{¶meters}; + GitLabOptionsPage optionsPage; QHash projectSettings; QPointer dialog; @@ -80,7 +74,7 @@ GitLabPlugin::~GitLabPlugin() void GitLabPlugin::initialize() { dd = new GitLabPluginPrivate; - dd->parameters.fromSettings(Core::ICore::settings()); + gitLabParameters().fromSettings(Core::ICore::settings()); setupGitlabProjectPanel(); @@ -98,7 +92,7 @@ void GitLabPlugin::initialize() void GitLabPlugin::openView() { if (dd->dialog.isNull()) { - while (!dd->parameters.isValid()) { + while (!gitLabParameters().isValid()) { QMessageBox::warning(Core::ICore::dialogParent(), Tr::tr("Error"), Tr::tr("Invalid GitLab configuration. For a fully functional " "configuration, you need to set up host name or address and " @@ -253,23 +247,6 @@ void GitLabPluginPrivate::handleEvents(const Events &events, const QDateTime &ti createAndSendEventsRequest(timeStamp, events.pageInfo.currentPage + 1); } -QList GitLabPlugin::allGitLabServers() -{ - QTC_ASSERT(dd, return {}); - return dd->parameters.gitLabServers; -} - -GitLabServer GitLabPlugin::gitLabServerForId(const Utils::Id &id) -{ - QTC_ASSERT(dd, return {}); - return dd->parameters.serverForId(id); -} - -GitLabParameters *GitLabPlugin::globalParameters() -{ - return &dd->parameters; -} - GitLabProjectSettings *GitLabPlugin::projectSettings(ProjectExplorer::Project *project) { QTC_ASSERT(project, return nullptr); @@ -280,17 +257,12 @@ GitLabProjectSettings *GitLabPlugin::projectSettings(ProjectExplorer::Project *p return settings; } -GitLabOptionsPage *GitLabPlugin::optionsPage() -{ - QTC_ASSERT(dd, return {}); - return &dd->optionsPage; -} - bool GitLabPlugin::handleCertificateIssue(const Utils::Id &serverId) { QTC_ASSERT(dd, return false); - GitLabServer server = dd->parameters.serverForId(serverId); + GitLabParameters ¶ms = gitLabParameters(); + GitLabServer server = params.serverForId(serverId); if (QMessageBox::question(Core::ICore::dialogParent(), Tr::tr("Certificate Error"), Tr::tr( @@ -299,10 +271,12 @@ bool GitLabPlugin::handleCertificateIssue(const Utils::Id &serverId) "Note: This can expose you to man-in-the-middle attack.") .arg(server.host)) == QMessageBox::Yes) { - int index = dd->parameters.gitLabServers.indexOf(server); + int index = params.gitLabServers.indexOf(server); server.validateCert = false; - dd->parameters.gitLabServers.replace(index, server); - dd->onSettingsChanged(); + params.gitLabServers.replace(index, server); + if (dd->dialog) + dd->dialog->updateRemotes(); + return true; } return false; diff --git a/src/plugins/gitlab/gitlabplugin.h b/src/plugins/gitlab/gitlabplugin.h index d49c17d89d2..ba07bf9f21d 100644 --- a/src/plugins/gitlab/gitlabplugin.h +++ b/src/plugins/gitlab/gitlabplugin.h @@ -13,7 +13,6 @@ namespace GitLab { class Events; class GitLabProjectSettings; -class GitLabOptionsPage; class GitLabPlugin : public ExtensionSystem::IPlugin { @@ -26,11 +25,7 @@ public: void initialize() override; - static QList allGitLabServers(); - static GitLabServer gitLabServerForId(const Utils::Id &id); - static GitLabParameters *globalParameters(); static GitLabProjectSettings *projectSettings(ProjectExplorer::Project *project); - static GitLabOptionsPage *optionsPage(); static bool handleCertificateIssue(const Utils::Id &serverId); static void linkedStateChanged(bool enabled); diff --git a/src/plugins/gitlab/gitlabprojectsettings.cpp b/src/plugins/gitlab/gitlabprojectsettings.cpp index a4e5a30850d..4c5c2d2a759 100644 --- a/src/plugins/gitlab/gitlabprojectsettings.cpp +++ b/src/plugins/gitlab/gitlabprojectsettings.cpp @@ -95,7 +95,7 @@ void GitLabProjectSettings::load() if (!m_id.isValid() || m_host.isEmpty()) m_linked = false; else - m_linked = GitLabPlugin::globalParameters()->serverForId(m_id).id.isValid(); + m_linked = gitLabParameters().serverForId(m_id).id.isValid(); } void GitLabProjectSettings::save() @@ -184,7 +184,7 @@ GitLabProjectSettingsWidget::GitLabProjectSettingsWidget(ProjectExplorer::Projec connect(m_hostCB, &QComboBox::currentIndexChanged, this, [this] { m_infoLabel->setVisible(false); }); - connect(GitLabPlugin::globalParameters(), &GitLabParameters::changed, + connect(&gitLabParameters(), &GitLabParameters::changed, this, &GitLabProjectSettingsWidget::updateUi); updateUi(); } @@ -266,7 +266,7 @@ void GitLabProjectSettingsWidget::onConnectionChecked(const Project &project, void GitLabProjectSettingsWidget::updateUi() { m_linkedGitLabServer->clear(); - const QList allServers = GitLabPlugin::allGitLabServers(); + const QList allServers = gitLabParameters().gitLabServers; for (const GitLabServer &server : allServers) { const QString display = server.host + " (" + server.description + ')'; m_linkedGitLabServer->addItem(display, QVariant::fromValue(server)); @@ -289,13 +289,13 @@ void GitLabProjectSettingsWidget::updateUi() const Utils::Id id = m_projectSettings->currentServer(); const QString serverHost = m_projectSettings->currentServerHost(); if (id.isValid()) { - const GitLabServer server = GitLabPlugin::gitLabServerForId(id); + const GitLabServer server = gitLabParameters().serverForId(id); auto [remoteHost, projName, port] = GitLabProjectSettings::remotePartsFromRemote(serverHost); if (server.id.isValid() && server.host == remoteHost) { // found config m_projectSettings->setLinked(true); m_hostCB->setCurrentIndex(m_hostCB->findData(QVariant::fromValue(serverHost))); m_linkedGitLabServer->setCurrentIndex( - m_linkedGitLabServer->findData(QVariant::fromValue(server))); + m_linkedGitLabServer->findData(QVariant::fromValue(server))); GitLabPlugin::linkedStateChanged(true); } else { m_projectSettings->setLinked(false); diff --git a/src/plugins/gitlab/queryrunner.cpp b/src/plugins/gitlab/queryrunner.cpp index 8c48855f0b7..ac82a6fca3c 100644 --- a/src/plugins/gitlab/queryrunner.cpp +++ b/src/plugins/gitlab/queryrunner.cpp @@ -83,8 +83,7 @@ QString Query::toString() const QueryRunner::QueryRunner(const Query &query, const Id &id, QObject *parent) : QObject(parent) { - const GitLabParameters *p = GitLabPlugin::globalParameters(); - const auto server = p->serverForId(id); + const auto server = gitLabParameters().serverForId(id); QStringList args = server.curlArguments(); if (query.hasPaginatedResults()) args << "-i"; @@ -95,7 +94,7 @@ QueryRunner::QueryRunner(const Query &query, const Id &id, QObject *parent) url.append(':' + QString::number(server.port)); url += query.toString(); args << url; - m_process.setCommand({p->curl, args}); + m_process.setCommand({gitLabParameters().curl, args}); connect(&m_process, &Process::done, this, [this, id] { if (m_process.result() != ProcessResult::FinishedWithSuccess) { const int exitCode = m_process.exitCode(); From ced3052e7ffe8a3f0ba0b8d371e648a92a87387a Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sun, 19 Nov 2023 14:18:41 +0100 Subject: [PATCH 0273/1546] TaskTree: Get rid of Storage subclass of GroupItem Make the c'tor of the GroupItem taking the TreeStorageBase public instead. This addresses the 20th point in the master task below. Task-number: QTCREATORBUG-28741 Change-Id: I78320ec24b4e4b915ab549135fb93b45c658b9f2 Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.h | 13 +- src/libs/utils/filestreamer.cpp | 4 +- src/plugins/android/androidsdkdownloader.cpp | 2 +- src/plugins/autotest/testrunner.cpp | 2 +- .../clangcodemodel/clangdlocatorfilters.cpp | 2 +- src/plugins/clangtools/clangtool.cpp | 2 +- src/plugins/clangtools/clangtoolrunner.cpp | 2 +- .../coreplugin/locator/ilocatorfilter.cpp | 4 +- src/plugins/cppeditor/cppprojectupdater.cpp | 2 +- src/plugins/diffeditor/diffeditorplugin.cpp | 2 +- src/plugins/git/branchview.cpp | 2 +- src/plugins/git/gitclient.cpp | 10 +- src/plugins/languageclient/locatorfilter.cpp | 4 +- src/plugins/mercurial/mercurialclient.cpp | 2 +- src/plugins/remotelinux/genericdeploystep.cpp | 2 +- .../remotelinux/genericdirectuploadstep.cpp | 2 +- src/plugins/remotelinux/linuxdevicetester.cpp | 2 +- src/plugins/subversion/subversionclient.cpp | 2 +- src/plugins/valgrind/valgrindprocess.cpp | 4 +- .../concurrentcall/tst_concurrentcall.cpp | 6 +- tests/auto/solutions/tasking/tst_tasking.cpp | 170 +++++++++--------- tests/manual/tasking/dataexchange/recipe.cpp | 4 +- .../tasking/imagescaling/imagescaling.cpp | 2 +- 23 files changed, 121 insertions(+), 126 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index c320413ad5c..ee983af941a 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -153,6 +153,10 @@ public: // Called when group done, before group's storages are deleted using GroupDoneHandler = std::function; + GroupItem(const TreeStorageBase &storage) + : m_type(Type::Storage) + , m_storageList{storage} {} + protected: // Internal, provided by CustomTask using InterfaceCreateHandler = std::function; @@ -193,9 +197,6 @@ protected: GroupItem(const GroupData &data) : m_type(Type::GroupData) , m_groupData(data) {} - GroupItem(const TreeStorageBase &storage) - : m_type(Type::Storage) - , m_storageList{storage} {} GroupItem(const TaskHandler &handler) : m_type(Type::TaskHandler) , m_taskHandler(handler) {} @@ -328,12 +329,6 @@ TASKING_EXPORT extern const GroupItem stopOnSuccessOrError; TASKING_EXPORT extern const GroupItem finishAllAndSuccess; TASKING_EXPORT extern const GroupItem finishAllAndError; -class TASKING_EXPORT Storage final : public GroupItem -{ -public: - Storage(const TreeStorageBase &storage) : GroupItem(storage) { } -}; - // Synchronous invocation. Similarly to Group - isn't counted as a task inside taskCount() class TASKING_EXPORT Sync final : public GroupItem { diff --git a/src/libs/utils/filestreamer.cpp b/src/libs/utils/filestreamer.cpp index 0e834e0acf2..d062d97757e 100644 --- a/src/libs/utils/filestreamer.cpp +++ b/src/libs/utils/filestreamer.cpp @@ -344,9 +344,9 @@ static Group interDeviceTransferTask(const FilePath &source, const FilePath &des }; const Group root { - Storage(writerReadyBarrier), + writerReadyBarrier, parallel, - Storage(storage), + storage, FileStreamWriterTask(onWriterSetup), Group { waitForBarrierTask(writerReadyBarrier), diff --git a/src/plugins/android/androidsdkdownloader.cpp b/src/plugins/android/androidsdkdownloader.cpp index 1dd56e3f0b9..a8d6ae0daaf 100644 --- a/src/plugins/android/androidsdkdownloader.cpp +++ b/src/plugins/android/androidsdkdownloader.cpp @@ -182,7 +182,7 @@ void AndroidSdkDownloader::downloadAndExtractSdk() }; const Group root { - Tasking::Storage(storage), + storage, NetworkQueryTask(onQuerySetup, onQueryDone), UnarchiverTask(onUnarchiveSetup, onUnarchiverDone) }; diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index 3a19a972d0b..542d860ae7b 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -446,7 +446,7 @@ void TestRunner::runTestsHelper() }; const Group group { finishAllAndSuccess, - Tasking::Storage(storage), + storage, onGroupSetup(onSetup), ProcessTask(onProcessSetup, onProcessDone) }; diff --git a/src/plugins/clangcodemodel/clangdlocatorfilters.cpp b/src/plugins/clangcodemodel/clangdlocatorfilters.cpp index ae3b8fc6620..069a987f6b4 100644 --- a/src/plugins/clangcodemodel/clangdlocatorfilters.cpp +++ b/src/plugins/clangcodemodel/clangdlocatorfilters.cpp @@ -192,7 +192,7 @@ static LocatorMatcherTask currentDocumentMatcher() }; const Group root { - Tasking::Storage(resultStorage), + resultStorage, CurrentDocumentSymbolsRequestTask(onQuerySetup, onQueryDone, CallDoneIf::Success), AsyncTask(onFilterSetup) }; diff --git a/src/plugins/clangtools/clangtool.cpp b/src/plugins/clangtools/clangtool.cpp index 61b30cfa5f2..5199d7a0cd6 100644 --- a/src/plugins/clangtools/clangtool.cpp +++ b/src/plugins/clangtools/clangtool.cpp @@ -824,7 +824,7 @@ Group ClangTool::runRecipe(const RunSettings &runSettings, }; topTasks.append(Group { - Storage(storage), + storage, TaskTreeTask(onTreeSetup, onTreeDone, CallDoneIf::Success) }); return {topTasks}; diff --git a/src/plugins/clangtools/clangtoolrunner.cpp b/src/plugins/clangtools/clangtoolrunner.cpp index 8769fa5cf78..eb07631f3de 100644 --- a/src/plugins/clangtools/clangtoolrunner.cpp +++ b/src/plugins/clangtools/clangtoolrunner.cpp @@ -223,7 +223,7 @@ GroupItem clangToolTask(const AnalyzeInputData &input, const Group group { finishAllAndSuccess, - Tasking::Storage(storage), + storage, onGroupSetup(onSetup), Group { sequential, diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.cpp b/src/plugins/coreplugin/locator/ilocatorfilter.cpp index 94cc24831c3..764c0774613 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/ilocatorfilter.cpp @@ -462,7 +462,7 @@ void LocatorMatcher::start() const auto storage = task.storage; const Group group { finishAllAndSuccess, - Storage(storage), + storage, onGroupSetup(onSetup(storage, index)), onGroupDone([storage] { storage->finalize(); }), task.task @@ -473,7 +473,7 @@ void LocatorMatcher::start() const Group root { parallel, - Storage(collectorStorage), + collectorStorage, ResultsCollectorTask(onCollectorSetup, onCollectorDone), Group { parallelTasks diff --git a/src/plugins/cppeditor/cppprojectupdater.cpp b/src/plugins/cppeditor/cppprojectupdater.cpp index 7f269ac2e2f..547dcd50c54 100644 --- a/src/plugins/cppeditor/cppprojectupdater.cpp +++ b/src/plugins/cppeditor/cppprojectupdater.cpp @@ -86,7 +86,7 @@ void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo, }; const Group root { - Tasking::Storage(storage), + storage, Group(tasks), onGroupDone(onDone) }; diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp index 89acf370861..04ab3c7d87e 100644 --- a/src/plugins/diffeditor/diffeditorplugin.cpp +++ b/src/plugins/diffeditor/diffeditorplugin.cpp @@ -145,7 +145,7 @@ DiffFilesController::DiffFilesController(IDocument *document) }; const Group root = { - Storage(storage), + storage, TaskTreeTask(onTreeSetup, onTreeDone) }; setReloadRecipe(root); diff --git a/src/plugins/git/branchview.cpp b/src/plugins/git/branchview.cpp index 960890c2dea..edb055a1fa1 100644 --- a/src/plugins/git/branchview.cpp +++ b/src/plugins/git/branchview.cpp @@ -561,7 +561,7 @@ TaskTree *BranchView::onFastForwardMerge(const std::function &callback) }); const Group root { - Tasking::Storage(storage), + storage, parallel, ProcessTask(onMergeBaseSetup, onMergeBaseDone, CallDoneIf::Success), topRevisionProc, diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index fa67e79ec47..0b490d74eb1 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -248,7 +248,7 @@ GitDiffEditorController::GitDiffEditorController(IDocument *document, }; const Group root { - Tasking::Storage(diffInputStorage), + diffInputStorage, ProcessTask(onDiffSetup, onDiffDone, CallDoneIf::Success), postProcessTask(diffInputStorage) }; @@ -333,8 +333,8 @@ FileListDiffController::FileListDiffController(IDocument *document, const QStrin }; const Group root { - Tasking::Storage(storage), - Tasking::Storage(diffInputStorage), + storage, + diffInputStorage, Group { parallel, continueOnSuccess, @@ -527,8 +527,8 @@ ShowController::ShowController(IDocument *document, const QString &id) }; const Group root { - Tasking::Storage(storage), - Tasking::Storage(diffInputStorage), + storage, + diffInputStorage, parallel, onGroupSetup([this] { setStartupFile(VcsBase::source(this->document()).toString()); }), Group { diff --git a/src/plugins/languageclient/locatorfilter.cpp b/src/plugins/languageclient/locatorfilter.cpp index 2b4c73a263a..bd4b3907506 100644 --- a/src/plugins/languageclient/locatorfilter.cpp +++ b/src/plugins/languageclient/locatorfilter.cpp @@ -76,7 +76,7 @@ LocatorMatcherTask locatorMatcher(Client *client, int maxResultCount, }; const Group root { - Tasking::Storage(resultStorage), + resultStorage, ClientWorkspaceSymbolRequestTask(onQuerySetup, onQueryDone, CallDoneIf::Success), AsyncTask(onFilterSetup) }; @@ -135,7 +135,7 @@ LocatorMatcherTask currentDocumentMatcher() }; const Group root { - Tasking::Storage(resultStorage), + resultStorage, CurrentDocumentSymbolsRequestTask(onQuerySetup, onQueryDone, CallDoneIf::Success), AsyncTask(onFilterSetup) }; diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp index 25ed1404111..00eb11ca201 100644 --- a/src/plugins/mercurial/mercurialclient.cpp +++ b/src/plugins/mercurial/mercurialclient.cpp @@ -64,7 +64,7 @@ MercurialDiffEditorController::MercurialDiffEditorController(IDocument *document }; const Group root { - Tasking::Storage(diffInputStorage), + diffInputStorage, ProcessTask(onDiffSetup, onDiffDone, CallDoneIf::Success), postProcessTask(diffInputStorage) }; diff --git a/src/plugins/remotelinux/genericdeploystep.cpp b/src/plugins/remotelinux/genericdeploystep.cpp index 71f5aaabff2..5c81bdfd249 100644 --- a/src/plugins/remotelinux/genericdeploystep.cpp +++ b/src/plugins/remotelinux/genericdeploystep.cpp @@ -197,7 +197,7 @@ GroupItem GenericDeployStep::deployRecipe() }; return Group { - Storage(storage), + storage, onGroupSetup(onSetup), mkdirTask(storage), transferTask(storage) diff --git a/src/plugins/remotelinux/genericdirectuploadstep.cpp b/src/plugins/remotelinux/genericdirectuploadstep.cpp index de7f4703837..4e751a1aea3 100644 --- a/src/plugins/remotelinux/genericdirectuploadstep.cpp +++ b/src/plugins/remotelinux/genericdirectuploadstep.cpp @@ -291,7 +291,7 @@ GroupItem GenericDirectUploadStep::deployRecipe() }; const Group root { - Storage(storage), + storage, onGroupSetup(setupHandler), statTree(storage, preFilesToStat, preStatEndHandler), uploadTask(storage), diff --git a/src/plugins/remotelinux/linuxdevicetester.cpp b/src/plugins/remotelinux/linuxdevicetester.cpp index 5f1029dbfa5..2e4598d9de8 100644 --- a/src/plugins/remotelinux/linuxdevicetester.cpp +++ b/src/plugins/remotelinux/linuxdevicetester.cpp @@ -229,7 +229,7 @@ GroupItem GenericLinuxDeviceTesterPrivate::transferTasks() const TreeStorage storage; return Group { continueOnSuccess, - Tasking::Storage(storage), + storage, transferTask(FileTransferMethod::GenericCopy, storage), transferTask(FileTransferMethod::Sftp, storage), transferTask(FileTransferMethod::Rsync, storage), diff --git a/src/plugins/subversion/subversionclient.cpp b/src/plugins/subversion/subversionclient.cpp index 721158f2cc0..c9d5df2d94a 100644 --- a/src/plugins/subversion/subversionclient.cpp +++ b/src/plugins/subversion/subversionclient.cpp @@ -198,7 +198,7 @@ SubversionDiffEditorController::SubversionDiffEditorController(IDocument *docume }; const Group root { - Tasking::Storage(diffInputStorage), + diffInputStorage, parallel, Group { finishAllAndSuccess, diff --git a/src/plugins/valgrind/valgrindprocess.cpp b/src/plugins/valgrind/valgrindprocess.cpp index 9862d407998..aee18e170f9 100644 --- a/src/plugins/valgrind/valgrindprocess.cpp +++ b/src/plugins/valgrind/valgrindprocess.cpp @@ -196,8 +196,8 @@ Group ValgrindProcessPrivate::runRecipe() const const Group root { parallel, - Storage(storage), - Storage(xmlBarrier), + storage, + xmlBarrier, onGroupSetup(onSetup), ProcessTask(onProcessSetup), Group { diff --git a/tests/auto/solutions/concurrentcall/tst_concurrentcall.cpp b/tests/auto/solutions/concurrentcall/tst_concurrentcall.cpp index 8195238005a..6f98ab4a073 100644 --- a/tests/auto/solutions/concurrentcall/tst_concurrentcall.cpp +++ b/tests/auto/solutions/concurrentcall/tst_concurrentcall.cpp @@ -146,7 +146,7 @@ TestData createTestData(const QList &expectedResults, Function &&fun }; const Group root { - Storage(storage), + storage, ConcurrentCallTask(onSetup, onDone) }; @@ -208,8 +208,8 @@ void tst_ConcurrentCall::taskTree_data() }; const Group root { - Storage(storage), - Storage(internalStorage), + storage, + internalStorage, onGroupSetup([internalStorage] { *internalStorage = 1; }), ConcurrentCallTask(onSetup, onDone, CallDoneIf::Success), ConcurrentCallTask(onSetup, onDone, CallDoneIf::Success), diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index 108654190d5..f37a50b4da1 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -261,8 +261,8 @@ void tst_Tasking::runtimeCheck() const TreeStorage storage; Group { - Storage(storage), - Storage(storage), + storage, + storage, }; } @@ -274,8 +274,8 @@ void tst_Tasking::runtimeCheck() const auto storage2 = storage1; Group { - Storage(storage1), - Storage(storage2), + storage1, + storage2, }; } @@ -431,20 +431,20 @@ static TestData storageShadowingData() }; const Group root { - Storage(storage), - Storage(helperStorage), - Storage(shadowedStorage), + storage, + helperStorage, + shadowedStorage, groupSetupWithStorage(1), Group { - Storage(shadowedStorage), + shadowedStorage, groupSetupWithStorage(2), Group { - Storage(shadowedStorage), + shadowedStorage, groupSetupWithStorage(3), groupDoneWithStorage(3) }, Group { - Storage(shadowedStorage), + shadowedStorage, groupSetupWithStorage(4), groupDoneWithStorage(4) }, @@ -508,7 +508,7 @@ static TestData parallelData() }; const Group root { - Storage(storage), + storage, parallel, createSuccessTask(1), createSuccessTask(2), @@ -627,21 +627,21 @@ void tst_Tasking::testTree_data() { const Group root1 { - Storage(storage), + storage, groupDone(0) }; const Group root2 { - Storage(storage), + storage, onGroupSetup([] { return SetupResult::Continue; }), groupDone(0) }; const Group root3 { - Storage(storage), + storage, onGroupSetup([] { return SetupResult::StopWithSuccess; }), groupDone(0) }; const Group root4 { - Storage(storage), + storage, onGroupSetup([] { return SetupResult::StopWithError; }), groupDone(0) }; @@ -658,7 +658,7 @@ void tst_Tasking::testTree_data() { const auto setupGroup = [=](SetupResult setupResult, WorkflowPolicy policy) { return Group { - Storage(storage), + storage, workflowPolicy(policy), onGroupSetup([setupResult] { return setupResult; }), groupDone(0) @@ -693,7 +693,7 @@ void tst_Tasking::testTree_data() { const Group root { - Storage(storage), + storage, createTaskWithSetupTweak(1, SetupResult::StopWithSuccess), createTaskWithSetupTweak(2, SetupResult::StopWithSuccess) }; @@ -708,7 +708,7 @@ void tst_Tasking::testTree_data() { const Group root { - Storage(storage), + storage, createTaskWithSetupTweak(1, SetupResult::StopWithError), createTaskWithSetupTweak(2, SetupResult::StopWithError) }; @@ -721,7 +721,7 @@ void tst_Tasking::testTree_data() { const Group root { - Storage(storage), + storage, createTaskWithSetupTweak(1, SetupResult::Continue), createTaskWithSetupTweak(2, SetupResult::Continue), createTaskWithSetupTweak(3, SetupResult::StopWithError), @@ -743,7 +743,7 @@ void tst_Tasking::testTree_data() { const Group root { parallel, - Storage(storage), + storage, createTaskWithSetupTweak(1, SetupResult::Continue), createTaskWithSetupTweak(2, SetupResult::Continue), createTaskWithSetupTweak(3, SetupResult::StopWithError), @@ -765,7 +765,7 @@ void tst_Tasking::testTree_data() { const Group root { parallel, - Storage(storage), + storage, createTaskWithSetupTweak(1, SetupResult::Continue), createTaskWithSetupTweak(2, SetupResult::Continue), Group { @@ -789,7 +789,7 @@ void tst_Tasking::testTree_data() { const Group root { parallel, - Storage(storage), + storage, createTaskWithSetupTweak(1, SetupResult::Continue), createTaskWithSetupTweak(2, SetupResult::Continue), Group { @@ -814,7 +814,7 @@ void tst_Tasking::testTree_data() { const Group root { - Storage(storage), + storage, Group { Group { Group { @@ -861,7 +861,7 @@ void tst_Tasking::testTree_data() { auto setupSubTree = [storage, createSuccessTask](TaskTree &taskTree) { const Group nestedRoot { - Storage(storage), + storage, createSuccessTask(2), createSuccessTask(3), createSuccessTask(4) @@ -874,7 +874,7 @@ void tst_Tasking::testTree_data() taskTree.onStorageDone(storage, collectSubLog); }; const Group root1 { - Storage(storage), + storage, createSuccessTask(1), createSuccessTask(2), createSuccessTask(3), @@ -883,7 +883,7 @@ void tst_Tasking::testTree_data() groupDone(0) }; const Group root2 { - Storage(storage), + storage, Group { createSuccessTask(1) }, Group { createSuccessTask(2) }, Group { createSuccessTask(3) }, @@ -892,7 +892,7 @@ void tst_Tasking::testTree_data() groupDone(0) }; const Group root3 { - Storage(storage), + storage, createSuccessTask(1), TaskTreeTask(setupSubTree), createSuccessTask(5), @@ -919,7 +919,7 @@ void tst_Tasking::testTree_data() { const Group root { - Storage(storage), + storage, Group { createSuccessTask(1), Group { @@ -965,7 +965,7 @@ void tst_Tasking::testTree_data() { const Group root { - Storage(storage), + storage, createSuccessTask(1), createSuccessTask(2), createFailingTask(3), @@ -988,7 +988,7 @@ void tst_Tasking::testTree_data() { const auto createRoot = [storage, groupDone](WorkflowPolicy policy) { return Group { - Storage(storage), + storage, workflowPolicy(policy), groupDone(0) }; @@ -1030,7 +1030,7 @@ void tst_Tasking::testTree_data() const auto createRoot = [storage, createSuccessTask, groupDone]( WorkflowPolicy policy) { return Group { - Storage(storage), + storage, workflowPolicy(policy), createSuccessTask(1), groupDone(0) @@ -1082,7 +1082,7 @@ void tst_Tasking::testTree_data() const auto createRoot = [storage, createFailingTask, groupDone]( WorkflowPolicy policy) { return Group { - Storage(storage), + storage, workflowPolicy(policy), createFailingTask(1), groupDone(0) @@ -1137,7 +1137,7 @@ void tst_Tasking::testTree_data() const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone]( WorkflowPolicy policy) { return Group { - Storage(storage), + storage, parallel, workflowPolicy(policy), createFailingTask(1, 1ms), @@ -1207,7 +1207,7 @@ void tst_Tasking::testTree_data() const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone]( WorkflowPolicy policy) { return Group { - Storage(storage), + storage, parallel, workflowPolicy(policy), createSuccessTask(1), @@ -1293,7 +1293,7 @@ void tst_Tasking::testTree_data() const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone]( WorkflowPolicy policy) { return Group { - Storage(storage), + storage, parallel, Group { workflowPolicy(policy), @@ -1352,7 +1352,7 @@ void tst_Tasking::testTree_data() const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone]( WorkflowPolicy policy) { return Group { - Storage(storage), + storage, parallel, Group { workflowPolicy(policy), @@ -1423,7 +1423,7 @@ void tst_Tasking::testTree_data() const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone]( WorkflowPolicy policy) { return Group { - Storage(storage), + storage, parallel, Group { workflowPolicy(policy), @@ -1490,7 +1490,7 @@ void tst_Tasking::testTree_data() const auto createRoot = [storage, createSuccessTask, createFailingTask, groupDone]( WorkflowPolicy policy) { return Group { - Storage(storage), + storage, workflowPolicy(policy), createSuccessTask(1), createFailingTask(2), @@ -1562,7 +1562,7 @@ void tst_Tasking::testTree_data() return Group { parallel, stopOnSuccessOrError, - Storage(storage), + storage, createTask(1, firstResult, 1000ms), createTask(2, secondResult, 1ms), groupDone(0) @@ -1604,7 +1604,7 @@ void tst_Tasking::testTree_data() const auto createRoot = [storage, createSuccessTask, groupDone, groupSetupWithTweak]( SetupResult desiredResult) { return Group { - Storage(storage), + storage, Group { groupSetupWithTweak(1, desiredResult), createSuccessTask(1) @@ -1648,7 +1648,7 @@ void tst_Tasking::testTree_data() const auto createRoot = [storage, createTask, groupDone, groupDoneWithTweak]( DoneResult firstResult, DoneResult secondResult) { return Group { - Storage(storage), + storage, Group { createTask(1, firstResult), groupDoneWithTweak(1, secondResult) @@ -1707,7 +1707,7 @@ void tst_Tasking::testTree_data() const auto createRoot = [storage, createSuccessTask, groupDone, createTaskWithSetupTweak]( SetupResult desiredResult) { return Group { - Storage(storage), + storage, Group { createTaskWithSetupTweak(1, desiredResult), createSuccessTask(2) @@ -1752,7 +1752,7 @@ void tst_Tasking::testTree_data() { const Group root { parallelLimit(2), - Storage(storage), + storage, Group { groupSetup(1), createSuccessTask(1) @@ -1790,7 +1790,7 @@ void tst_Tasking::testTree_data() { const Group root { parallelLimit(2), - Storage(storage), + storage, Group { groupSetup(1), createSuccessTask(1) @@ -1835,7 +1835,7 @@ void tst_Tasking::testTree_data() { const Group root1 { parallelLimit(2), - Storage(storage), + storage, Group { groupSetup(1), createSuccessTask(1) @@ -1875,7 +1875,7 @@ void tst_Tasking::testTree_data() // - tasks 4 and 5 should be skipped const Group root2 { parallelLimit(2), - Storage(storage), + storage, Group { groupSetup(1), createSuccessTask(1, 10ms) @@ -1919,7 +1919,7 @@ void tst_Tasking::testTree_data() // - task 5 should be started (because of root's continueOnError policy) const Group root3 { continueOnError, - Storage(storage), + storage, Group { parallelLimit(2), Group { @@ -1969,7 +1969,7 @@ void tst_Tasking::testTree_data() { const Group root { parallelLimit(2), - Storage(storage), + storage, Group { groupSetup(1), Group { @@ -2019,7 +2019,7 @@ void tst_Tasking::testTree_data() { const Group root { parallelLimit(2), - Storage(storage), + storage, Group { groupSetup(1), Group { createSuccessTask(1) } @@ -2065,7 +2065,7 @@ void tst_Tasking::testTree_data() { const Group root { parallelLimit(2), - Storage(storage), + storage, Group { groupSetup(1), Group { createSuccessTask(1) } @@ -2104,7 +2104,7 @@ void tst_Tasking::testTree_data() { const Group root { - Storage(storage), + storage, createSync(1), createSync(2), createSync(3), @@ -2123,7 +2123,7 @@ void tst_Tasking::testTree_data() { const Group root { - Storage(storage), + storage, createSyncWithTweak(1, DoneResult::Success), createSyncWithTweak(2, DoneResult::Success), createSyncWithTweak(3, DoneResult::Success), @@ -2147,7 +2147,7 @@ void tst_Tasking::testTree_data() { const Group root { - Storage(storage), + storage, parallel, createSync(1), createSync(2), @@ -2167,7 +2167,7 @@ void tst_Tasking::testTree_data() { const Group root { - Storage(storage), + storage, parallel, createSync(1), createSync(2), @@ -2186,7 +2186,7 @@ void tst_Tasking::testTree_data() { const Group root { - Storage(storage), + storage, createSync(1), createSuccessTask(2), createSync(3), @@ -2209,7 +2209,7 @@ void tst_Tasking::testTree_data() { const Group root { - Storage(storage), + storage, createSync(1), createSuccessTask(2), createSyncWithTweak(3, DoneResult::Error), @@ -2235,8 +2235,8 @@ void tst_Tasking::testTree_data() // setupBarrierAdvance, placed BEFORE the group containing the waitFor() element // in the tree order, works OK in SEQUENTIAL mode. const Group root1 { - Storage(storage), - Storage(barrier), + storage, + barrier, sequential, createBarrierAdvance(storage, barrier, 1), Group { @@ -2260,8 +2260,8 @@ void tst_Tasking::testTree_data() // setupTaskWithCondition, placed BEFORE the group containing the waitFor() element // in the tree order, works OK in PARALLEL mode. const Group root2 { - Storage(storage), - Storage(barrier), + storage, + barrier, parallel, createBarrierAdvance(storage, barrier, 1), Group { @@ -2292,8 +2292,8 @@ void tst_Tasking::testTree_data() // come from the not yet started next task, causing a deadlock. // The minimal requirement for this scenario to succeed is to set parallelLimit(2) or more. const Group root3 { - Storage(storage), - Storage(barrier), + storage, + barrier, parallel, Group { groupSetup(2), @@ -2317,8 +2317,8 @@ void tst_Tasking::testTree_data() // setupBarrierAdvance, placed BEFORE the groups containing the waitFor() element // in the tree order, wakes both waitFor tasks. const Group root4 { - Storage(storage), - Storage(barrier), + storage, + barrier, parallel, createBarrierAdvance(storage, barrier, 1), Group { @@ -2348,9 +2348,9 @@ void tst_Tasking::testTree_data() SingleBarrier barrier2; const Group root5 { - Storage(storage), - Storage(barrier), - Storage(barrier2), + storage, + barrier, + barrier2, parallel, createBarrierAdvance(storage, barrier, 1), createBarrierAdvance(storage, barrier2, 2), @@ -2394,8 +2394,8 @@ void tst_Tasking::testTree_data() // setupBarrierAdvance, placed BEFORE the group containing the waitFor() element // in the tree order, works OK in SEQUENTIAL mode. const Group root1 { - Storage(storage), - Storage(barrier), + storage, + barrier, sequential, createBarrierAdvance(storage, barrier, 1), createBarrierAdvance(storage, barrier, 2), @@ -2422,8 +2422,8 @@ void tst_Tasking::testTree_data() // setupBarrierAdvance, placed BEFORE the group containing the waitFor() element // in the tree order, works OK in PARALLEL mode. const Group root2 { - Storage(storage), - Storage(barrier), + storage, + barrier, parallel, createBarrierAdvance(storage, barrier, 1), createBarrierAdvance(storage, barrier, 2), @@ -2457,8 +2457,8 @@ void tst_Tasking::testTree_data() // come from the not yet started next task, causing a deadlock. // The minimal requirement for this scenario to succeed is to set parallelLimit(2) or more. const Group root3 { - Storage(storage), - Storage(barrier), + storage, + barrier, parallel, Group { groupSetup(2), @@ -2485,8 +2485,8 @@ void tst_Tasking::testTree_data() // setupBarrierAdvance, placed BEFORE the groups containing the waitFor() element // in the tree order, wakes both waitFor tasks. const Group root4 { - Storage(storage), - Storage(barrier), + storage, + barrier, parallel, createBarrierAdvance(storage, barrier, 1), createBarrierAdvance(storage, barrier, 2), @@ -2530,7 +2530,7 @@ void tst_Tasking::testTree_data() // 1. When the timeout has triggered or not. // 2. With and without timeout handler. const Group root1 { - Storage(storage), + storage, TestTask(setupTask(1, 1000ms), setupDone(1)) .withTimeout(1ms) }; @@ -2542,7 +2542,7 @@ void tst_Tasking::testTree_data() DoneWith::Error}; const Group root2 { - Storage(storage), + storage, TestTask(setupTask(1, 1000ms), setupDone(1)) .withTimeout(1ms, setupTimeout(1)) }; @@ -2555,7 +2555,7 @@ void tst_Tasking::testTree_data() DoneWith::Error}; const Group root3 { - Storage(storage), + storage, TestTask(setupTask(1, 1ms), setupDone(1)) .withTimeout(1000ms) }; @@ -2567,7 +2567,7 @@ void tst_Tasking::testTree_data() DoneWith::Success}; const Group root4 { - Storage(storage), + storage, TestTask(setupTask(1, 1ms), setupDone(1)) .withTimeout(1000ms, setupTimeout(1)) }; @@ -2580,7 +2580,7 @@ void tst_Tasking::testTree_data() // 1. When the timeout has triggered or not. // 2. With and without timeout handler. const Group root1 { - Storage(storage), + storage, Group { createSuccessTask(1, 1000ms) }.withTimeout(1ms) @@ -2594,7 +2594,7 @@ void tst_Tasking::testTree_data() // Test Group::withTimeout(), passing custom handler const Group root2 { - Storage(storage), + storage, Group { createSuccessTask(1, 1000ms) }.withTimeout(1ms, setupTimeout(1)) @@ -2608,7 +2608,7 @@ void tst_Tasking::testTree_data() DoneWith::Error}; const Group root3 { - Storage(storage), + storage, Group { createSuccessTask(1, 1ms) }.withTimeout(1000ms) @@ -2622,7 +2622,7 @@ void tst_Tasking::testTree_data() // Test Group::withTimeout(), passing custom handler const Group root4 { - Storage(storage), + storage, Group { createSuccessTask(1, 1ms) }.withTimeout(1000ms, setupTimeout(1)) @@ -2749,7 +2749,7 @@ struct StorageIO static Group inputOutputRecipe(const TreeStorage &storage) { return Group { - Storage(storage), + storage, onGroupSetup([storage] { ++storage->value; }), onGroupDone([storage] { storage->value *= 2; }) }; @@ -2819,7 +2819,7 @@ void tst_Tasking::storageDestructor() taskObject = 1000ms; }; const Group root { - Storage(storage), + storage, TestTask(setupSleepingTask) }; diff --git a/tests/manual/tasking/dataexchange/recipe.cpp b/tests/manual/tasking/dataexchange/recipe.cpp index 4446eee7b9a..389377c388d 100644 --- a/tests/manual/tasking/dataexchange/recipe.cpp +++ b/tests/manual/tasking/dataexchange/recipe.cpp @@ -76,8 +76,8 @@ Group recipe(const Tasking::TreeStorage &externalStorage) } const QList recipe { - Storage(externalStorage), - Storage(internalStorage), + externalStorage, + internalStorage, NetworkQueryTask(onDownloadSetup, onDownloadDone), ConcurrentCallTask(onReadSetup, onReadDone), Group { parallelTasks } diff --git a/tests/manual/tasking/imagescaling/imagescaling.cpp b/tests/manual/tasking/imagescaling/imagescaling.cpp index 5e13a83a39a..36b6a71ad83 100644 --- a/tests/manual/tasking/imagescaling/imagescaling.cpp +++ b/tests/manual/tasking/imagescaling/imagescaling.cpp @@ -97,7 +97,7 @@ void Images::process() }; const Group group { - Storage(storage), + storage, NetworkQueryTask(onDownloadSetup, onDownloadDone), ConcurrentCallTask(onScalingSetup, onScalingDone) }; From 767bb30b11b10dd5524994d69bb7e794f33d0d51 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sun, 19 Nov 2023 14:40:49 +0100 Subject: [PATCH 0274/1546] TaskTree: Hide more internals inside StorageBase class Rename storage internals. This addresses the 20th point in the master task below. Task-number: QTCREATORBUG-28741 Change-Id: I1ed42472060de6180d4665d6504598adb57828fe Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 46 ++++++++--------- src/libs/solutions/tasking/tasktree.h | 54 ++++++++++---------- tests/auto/solutions/tasking/tst_tasking.cpp | 6 +-- 3 files changed, 54 insertions(+), 52 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 943776c89a4..30226f72f22 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -897,8 +897,8 @@ public: m_threadDataMap.find(QThread::currentThread())); } - const TreeStorageBase::StorageConstructor m_constructor = {}; - const TreeStorageBase::StorageDestructor m_destructor = {}; + const StorageBase::StorageConstructor m_constructor = {}; + const StorageBase::StorageDestructor m_destructor = {}; QMutex m_threadDataMutex = {}; // Use std::map on purpose, so that it doesn't invalidate references on modifications. // Don't optimize it by using std::unordered_map. @@ -972,16 +972,16 @@ StorageData::~StorageData() QT_CHECK(m_threadDataMap.empty()); } -bool TreeStorageBase::isValid() const +bool StorageBase::isValid() const { return m_storageData && m_storageData->m_constructor && m_storageData->m_destructor; } -TreeStorageBase::TreeStorageBase(StorageConstructor ctor, StorageDestructor dtor) +StorageBase::StorageBase(StorageConstructor ctor, StorageDestructor dtor) : m_storageData(new StorageData{ctor, dtor}) {} -void *TreeStorageBase::activeStorageVoid() const +void *StorageBase::activeStorageVoid() const { return m_storageData->threadData().activeStorageVoid(); } @@ -1033,7 +1033,7 @@ void GroupItem::addChildren(const QList &children) break; case Type::Storage: // Check for duplicates, as can't have the same storage twice on the same level. - for (const TreeStorageBase &storage : child.m_storageList) { + for (const StorageBase &storage : child.m_storageList) { if (m_storageList.contains(storage)) { QT_ASSERT(false, qWarning("Can't add the same storage into one Group twice, " "skipping...")); @@ -1078,7 +1078,7 @@ public: private: void activateContext(TaskRuntimeContainer *container); - QList m_activeStorages; + QList m_activeStorages; }; class TaskContainer @@ -1094,7 +1094,7 @@ public: const int m_parallelLimit = 1; const WorkflowPolicy m_workflowPolicy = WorkflowPolicy::StopOnError; const GroupItem::GroupHandler m_groupHandler; - const QList m_storageList; + const QList m_storageList; std::vector m_children; const int m_taskCount = 0; }; @@ -1131,18 +1131,18 @@ public: void emitStartedAndProgress(); void emitProgress(); void emitDone(DoneWith result); - void callSetupHandler(TreeStorageBase storage, int storageId) { + void callSetupHandler(StorageBase storage, int storageId) { callStorageHandler(storage, storageId, &StorageHandler::m_setupHandler); } - void callDoneHandler(TreeStorageBase storage, int storageId) { + void callDoneHandler(StorageBase storage, int storageId) { callStorageHandler(storage, storageId, &StorageHandler::m_doneHandler); } struct StorageHandler { - TreeStorageBase::StorageVoidHandler m_setupHandler = {}; - TreeStorageBase::StorageVoidHandler m_doneHandler = {}; + StorageBase::StorageHandler m_setupHandler = {}; + StorageBase::StorageHandler m_doneHandler = {}; }; - typedef TreeStorageBase::StorageVoidHandler StorageHandler::*HandlerPtr; // ptr to class member - void callStorageHandler(TreeStorageBase storage, int storageId, HandlerPtr ptr) + typedef StorageBase::StorageHandler StorageHandler::*HandlerPtr; // ptr to class member + void callStorageHandler(StorageBase storage, int storageId, HandlerPtr ptr) { const auto it = m_storageHandlers.constFind(storage); if (it == m_storageHandlers.constEnd()) @@ -1187,8 +1187,8 @@ public: TaskTree *q = nullptr; Guard m_guard; int m_progressValue = 0; - QSet m_storages; - QHash m_storageHandlers; + QSet m_storages; + QHash m_storageHandlers; std::optional m_root; std::unique_ptr m_runtimeRoot; // Keep me last in order to destruct first }; @@ -1225,7 +1225,7 @@ public: ~TaskRuntimeContainer() { for (int i = m_taskContainer.m_storageList.size() - 1; i >= 0; --i) { // iterate in reverse order - const TreeStorageBase storage = m_taskContainer.m_storageList[i]; + const StorageBase storage = m_taskContainer.m_storageList[i]; const int storageId = m_storageIdList.value(i); if (m_callStorageDoneHandlersOnDestruction) m_taskContainer.m_taskTreePrivate->callDoneHandler(storage, storageId); @@ -1271,7 +1271,7 @@ void ExecutionContextActivator::activateContext(TaskRuntimeContainer *container) { const TaskContainer &taskContainer = container->m_taskContainer; for (int i = 0; i < taskContainer.m_storageList.size(); ++i) { - const TreeStorageBase &storage = taskContainer.m_storageList[i]; + const StorageBase &storage = taskContainer.m_storageList[i]; auto &threadData = storage.m_storageData->threadData(); if (threadData.activeStorageId()) continue; // Storage shadowing: The storage is already active, skipping it... @@ -1358,14 +1358,14 @@ TaskContainer::TaskContainer(TaskTreePrivate *taskTreePrivate, const GroupItem & , m_taskCount(std::accumulate(m_children.cbegin(), m_children.cend(), 0, [](int r, const TaskNode &n) { return r + n.taskCount(); })) { - for (const TreeStorageBase &storage : m_storageList) + for (const StorageBase &storage : m_storageList) m_taskTreePrivate->m_storages << storage; } QList TaskRuntimeContainer::createStorages(const TaskContainer &container) { QList storageIdList; - for (const TreeStorageBase &storage : container.m_storageList) { + for (const StorageBase &storage : container.m_storageList) { const int storageId = storage.m_storageData->threadData().createStorage(); storageIdList.append(storageId); container.m_taskTreePrivate->callSetupHandler(storage, storageId); @@ -2631,9 +2631,9 @@ int TaskTree::progressValue() const \sa onStorageSetup() */ -void TaskTree::setupStorageHandler(const TreeStorageBase &storage, - TreeStorageBase::StorageVoidHandler setupHandler, - TreeStorageBase::StorageVoidHandler doneHandler) +void TaskTree::setupStorageHandler(const StorageBase &storage, + StorageBase::StorageHandler setupHandler, + StorageBase::StorageHandler doneHandler) { auto it = d->m_storageHandlers.find(storage); if (it == d->m_storageHandlers.end()) { diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index ee983af941a..9f3deaefa4e 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -96,42 +96,44 @@ protected: virtual void start() = 0; }; -class TASKING_EXPORT TreeStorageBase +class TASKING_EXPORT StorageBase { public: - using StorageConstructor = std::function; - using StorageDestructor = std::function; - using StorageVoidHandler = std::function; - bool isValid() const; private: - TreeStorageBase(StorageConstructor ctor, StorageDestructor dtor); + using StorageConstructor = std::function; + using StorageDestructor = std::function; + using StorageHandler = std::function; + + StorageBase(StorageConstructor ctor, StorageDestructor dtor); void *activeStorageVoid() const; - friend bool operator==(const TreeStorageBase &first, const TreeStorageBase &second) + friend bool operator==(const StorageBase &first, const StorageBase &second) { return first.m_storageData == second.m_storageData; } - friend bool operator!=(const TreeStorageBase &first, const TreeStorageBase &second) + friend bool operator!=(const StorageBase &first, const StorageBase &second) { return first.m_storageData != second.m_storageData; } - friend size_t qHash(const TreeStorageBase &storage, uint seed = 0) + friend size_t qHash(const StorageBase &storage, uint seed = 0) { return size_t(storage.m_storageData.get()) ^ seed; } QSharedPointer m_storageData; template friend class TreeStorage; friend class ExecutionContextActivator; + friend class StorageData; friend class TaskRuntimeContainer; + friend class TaskTree; friend class TaskTreePrivate; }; template -class TreeStorage final : public TreeStorageBase +class TreeStorage final : public StorageBase { public: - TreeStorage() : TreeStorageBase(TreeStorage::ctor(), TreeStorage::dtor()) {} + TreeStorage() : StorageBase(TreeStorage::ctor(), TreeStorage::dtor()) {} StorageStruct &operator*() const noexcept { return *activeStorage(); } StorageStruct *operator->() const noexcept { return activeStorage(); } StorageStruct *activeStorage() const { @@ -153,7 +155,7 @@ public: // Called when group done, before group's storages are deleted using GroupDoneHandler = std::function; - GroupItem(const TreeStorageBase &storage) + GroupItem(const StorageBase &storage) : m_type(Type::Storage) , m_storageList{storage} {} @@ -226,7 +228,7 @@ private: Type m_type = Type::Group; QList m_children; GroupData m_groupData; - QList m_storageList; + QList m_storageList; TaskHandler m_taskHandler; }; @@ -488,21 +490,21 @@ public: int progressMaximum() const { return taskCount(); } int progressValue() const; // all finished / skipped / stopped tasks, groups itself excluded - template - void onStorageSetup(const TreeStorage &storage, StorageHandler &&handler) { - static_assert(std::is_invocable_v, StorageStruct &>, + template + void onStorageSetup(const TreeStorage &storage, Handler &&handler) { + static_assert(std::is_invocable_v, StorageStruct &>, "Storage setup handler needs to take (Storage &) as an argument. " "The passed handler doesn't fulfill this requirement."); setupStorageHandler(storage, - wrapHandler(std::forward(handler)), {}); + wrapHandler(std::forward(handler)), {}); } - template - void onStorageDone(const TreeStorage &storage, StorageHandler &&handler) { - static_assert(std::is_invocable_v, const StorageStruct &>, + template + void onStorageDone(const TreeStorage &storage, Handler &&handler) { + static_assert(std::is_invocable_v, const StorageStruct &>, "Storage done handler needs to take (const Storage &) as an argument. " "The passed handler doesn't fulfill this requirement."); setupStorageHandler(storage, {}, - wrapHandler(std::forward(handler))); + wrapHandler(std::forward(handler))); } signals: @@ -511,11 +513,11 @@ signals: void progressValueChanged(int value); // updated whenever task finished / skipped / stopped private: - void setupStorageHandler(const TreeStorageBase &storage, - TreeStorageBase::StorageVoidHandler setupHandler, - TreeStorageBase::StorageVoidHandler doneHandler); - template - TreeStorageBase::StorageVoidHandler wrapHandler(StorageHandler &&handler) { + void setupStorageHandler(const StorageBase &storage, + StorageBase::StorageHandler setupHandler, + StorageBase::StorageHandler doneHandler); + template + StorageBase::StorageHandler wrapHandler(Handler &&handler) { return [=](void *voidStruct) { auto *storageStruct = static_cast(voidStruct); std::invoke(handler, *storageStruct); diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index f37a50b4da1..fc4e0d26a3a 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -2789,9 +2789,9 @@ void tst_Tasking::storageIO() void tst_Tasking::storageOperators() { - TreeStorageBase storage1 = TreeStorage(); - TreeStorageBase storage2 = TreeStorage(); - TreeStorageBase storage3 = storage1; + StorageBase storage1 = TreeStorage(); + StorageBase storage2 = TreeStorage(); + StorageBase storage3 = storage1; QVERIFY(storage1 == storage3); QVERIFY(storage1 != storage2); From 9800f1bdc4d44206d5395f609c1082096cb5721e Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 08:25:17 +0100 Subject: [PATCH 0275/1546] Revert "ImageViewer: Fix build" This reverts commit 9b429c7ebd02b5d9a2cbca3a6aa606ff69fd6e42. There is a Q_OBJECT in line 12, the #include is needed. Change-Id: Ia4d333b6419bb2bdcdcf124d22d0473f6fd91cb1 Reviewed-by: Jarek Kobus --- src/plugins/imageviewer/imageviewerplugin.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/imageviewer/imageviewerplugin.cpp b/src/plugins/imageviewer/imageviewerplugin.cpp index f2db22fc4d1..a8088a02395 100644 --- a/src/plugins/imageviewer/imageviewerplugin.cpp +++ b/src/plugins/imageviewer/imageviewerplugin.cpp @@ -21,3 +21,5 @@ public: }; } // ImageViewer::Internal + +#include "imageviewerplugin.moc" From ce80a6dad5ef40449ea2584c2d5a41584095fa36 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sun, 19 Nov 2023 14:50:55 +0100 Subject: [PATCH 0276/1546] TaskTree: Rename TreeStorage<> -> Storage<> This addresses the 20th point in the master task below. Task-number: QTCREATORBUG-28741 Change-Id: I696beda87430fbe637abba8054012fb77516e220 Reviewed-by: hjk --- src/libs/solutions/tasking/barrier.h | 2 +- src/libs/solutions/tasking/tasktree.h | 10 +++---- src/libs/utils/filestreamer.cpp | 2 +- src/plugins/android/androidsdkdownloader.cpp | 2 +- src/plugins/autotest/testrunner.cpp | 2 +- .../clangcodemodel/clangdlocatorfilters.cpp | 4 +-- src/plugins/clangtools/clangtool.cpp | 2 +- src/plugins/clangtools/clangtoolrunner.cpp | 2 +- .../cmakelocatorfilter.cpp | 2 +- src/plugins/coreplugin/actionsfilter.cpp | 2 +- .../coreplugin/locator/commandlocator.cpp | 2 +- .../coreplugin/locator/executefilter.cpp | 2 +- .../locator/externaltoolsfilter.cpp | 2 +- .../coreplugin/locator/filesystemfilter.cpp | 2 +- .../coreplugin/locator/ilocatorfilter.cpp | 6 ++-- .../coreplugin/locator/ilocatorfilter.h | 2 +- .../coreplugin/locator/javascriptfilter.cpp | 2 +- .../locator/locatorfiltersfilter.cpp | 2 +- .../locator/opendocumentsfilter.cpp | 2 +- .../locator/spotlightlocatorfilter.cpp | 2 +- .../coreplugin/locator/urllocatorfilter.cpp | 2 +- src/plugins/cppeditor/cpplocatorfilter.cpp | 4 +-- src/plugins/cppeditor/cppprojectupdater.cpp | 2 +- src/plugins/diffeditor/diffeditorplugin.cpp | 2 +- src/plugins/git/branchview.cpp | 2 +- src/plugins/git/gitclient.cpp | 10 +++---- src/plugins/help/helpindexfilter.cpp | 2 +- src/plugins/ios/iosdeploystep.cpp | 2 +- src/plugins/languageclient/locatorfilter.cpp | 8 +++--- src/plugins/macros/macrolocatorfilter.cpp | 2 +- src/plugins/mercurial/mercurialclient.cpp | 2 +- .../projectexplorer/projectexplorer.cpp | 2 +- .../qmljstools/qmljsfunctionfilter.cpp | 2 +- src/plugins/remotelinux/genericdeploystep.cpp | 10 +++---- .../remotelinux/genericdirectuploadstep.cpp | 14 +++++----- src/plugins/remotelinux/linuxdevicetester.cpp | 6 ++-- src/plugins/subversion/subversionclient.cpp | 2 +- src/plugins/texteditor/bookmarkfilter.cpp | 2 +- src/plugins/texteditor/linenumberfilter.cpp | 2 +- src/plugins/valgrind/valgrindprocess.cpp | 2 +- .../vcsbase/vcsbasediffeditorcontroller.cpp | 2 +- .../vcsbase/vcsbasediffeditorcontroller.h | 2 +- .../concurrentcall/tst_concurrentcall.cpp | 8 +++--- tests/auto/solutions/tasking/tst_tasking.cpp | 28 +++++++++---------- tests/manual/tasking/dataexchange/recipe.cpp | 4 +-- tests/manual/tasking/dataexchange/recipe.h | 4 +-- tests/manual/tasking/dataexchange/viewer.h | 2 +- .../tasking/imagescaling/imagescaling.cpp | 2 +- 48 files changed, 93 insertions(+), 93 deletions(-) diff --git a/src/libs/solutions/tasking/barrier.h b/src/libs/solutions/tasking/barrier.h index 13b6dfa48fd..a9ed9949f06 100644 --- a/src/libs/solutions/tasking/barrier.h +++ b/src/libs/solutions/tasking/barrier.h @@ -59,7 +59,7 @@ private: }; template -using MultiBarrier = TreeStorage>; +using MultiBarrier = Storage>; // Can't write: "MultiBarrier barrier;". Only "MultiBarrier<> barrier;" would work. // Can't have one alias with default type in C++17, getting the following error: diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 9f3deaefa4e..022a466294f 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -121,7 +121,7 @@ private: QSharedPointer m_storageData; - template friend class TreeStorage; + template friend class Storage; friend class ExecutionContextActivator; friend class StorageData; friend class TaskRuntimeContainer; @@ -130,10 +130,10 @@ private: }; template -class TreeStorage final : public StorageBase +class Storage final : public StorageBase { public: - TreeStorage() : StorageBase(TreeStorage::ctor(), TreeStorage::dtor()) {} + Storage() : StorageBase(Storage::ctor(), Storage::dtor()) {} StorageStruct &operator*() const noexcept { return *activeStorage(); } StorageStruct *operator->() const noexcept { return activeStorage(); } StorageStruct *activeStorage() const { @@ -491,7 +491,7 @@ public: int progressValue() const; // all finished / skipped / stopped tasks, groups itself excluded template - void onStorageSetup(const TreeStorage &storage, Handler &&handler) { + void onStorageSetup(const Storage &storage, Handler &&handler) { static_assert(std::is_invocable_v, StorageStruct &>, "Storage setup handler needs to take (Storage &) as an argument. " "The passed handler doesn't fulfill this requirement."); @@ -499,7 +499,7 @@ public: wrapHandler(std::forward(handler)), {}); } template - void onStorageDone(const TreeStorage &storage, Handler &&handler) { + void onStorageDone(const Storage &storage, Handler &&handler) { static_assert(std::is_invocable_v, const StorageStruct &>, "Storage done handler needs to take (const Storage &) as an argument. " "The passed handler doesn't fulfill this requirement."); diff --git a/src/libs/utils/filestreamer.cpp b/src/libs/utils/filestreamer.cpp index d062d97757e..e80c8e5bd0c 100644 --- a/src/libs/utils/filestreamer.cpp +++ b/src/libs/utils/filestreamer.cpp @@ -323,7 +323,7 @@ static Group interDeviceTransferTask(const FilePath &source, const FilePath &des { struct TransferStorage { QPointer writer; }; SingleBarrier writerReadyBarrier; - TreeStorage storage; + Storage storage; const auto onReaderSetup = [storage, source](FileStreamReader &reader) { reader.setFilePath(source); diff --git a/src/plugins/android/androidsdkdownloader.cpp b/src/plugins/android/androidsdkdownloader.cpp index a8d6ae0daaf..eb52f78b431 100644 --- a/src/plugins/android/androidsdkdownloader.cpp +++ b/src/plugins/android/androidsdkdownloader.cpp @@ -104,7 +104,7 @@ void AndroidSdkDownloader::downloadAndExtractSdk() using namespace Tasking; - TreeStorage> storage; + Storage> storage; const auto onQuerySetup = [this](NetworkQuery &query) { query.setRequest(QNetworkRequest(m_androidConfig.sdkToolsUrl())); diff --git a/src/plugins/autotest/testrunner.cpp b/src/plugins/autotest/testrunner.cpp index 542d860ae7b..2c49614acce 100644 --- a/src/plugins/autotest/testrunner.cpp +++ b/src/plugins/autotest/testrunner.cpp @@ -351,7 +351,7 @@ void TestRunner::runTestsHelper() for (ITestConfiguration *config : m_selectedTests) { QTC_ASSERT(config, continue); - const TreeStorage storage; + const Storage storage; const auto onSetup = [this, config] { if (!config->project()) diff --git a/src/plugins/clangcodemodel/clangdlocatorfilters.cpp b/src/plugins/clangcodemodel/clangdlocatorfilters.cpp index 069a987f6b4..469dfeec95f 100644 --- a/src/plugins/clangcodemodel/clangdlocatorfilters.cpp +++ b/src/plugins/clangcodemodel/clangdlocatorfilters.cpp @@ -175,8 +175,8 @@ static LocatorMatcherTask currentDocumentMatcher() { using namespace Tasking; - TreeStorage storage; - TreeStorage resultStorage; + Storage storage; + Storage resultStorage; const auto onQuerySetup = [=](CurrentDocumentSymbolsRequest &request) { Q_UNUSED(request) diff --git a/src/plugins/clangtools/clangtool.cpp b/src/plugins/clangtools/clangtool.cpp index 5199d7a0cd6..7d9d13b4c65 100644 --- a/src/plugins/clangtools/clangtool.cpp +++ b/src/plugins/clangtools/clangtool.cpp @@ -659,7 +659,7 @@ Group ClangTool::runRecipe(const RunSettings &runSettings, QElapsedTimer m_timer; std::function m_elapsedHandler = {}; }; - const TreeStorage storage; + const Storage storage; std::shared_ptr tempDir(new TemporaryDirectory("clangtools-XXXXXX")); tempDir->setAutoRemove(qtcEnvironmentVariable("QTC_CLANG_DONT_DELETE_OUTPUT_FILES") != "1"); diff --git a/src/plugins/clangtools/clangtoolrunner.cpp b/src/plugins/clangtools/clangtoolrunner.cpp index eb07631f3de..1f1124dd400 100644 --- a/src/plugins/clangtools/clangtoolrunner.cpp +++ b/src/plugins/clangtools/clangtoolrunner.cpp @@ -119,7 +119,7 @@ GroupItem clangToolTask(const AnalyzeInputData &input, FilePath executable; FilePath outputFilePath; }; - const TreeStorage storage; + const Storage storage; const auto mainToolArguments = [=](const ClangToolStorage &data) { QStringList result; diff --git a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp index 8d63ee0fa91..8d9e07e5efb 100644 --- a/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakelocatorfilter.cpp @@ -27,7 +27,7 @@ static LocatorMatcherTasks cmakeMatchers(const BuildAcceptor &acceptor) { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [storage, acceptor] { const QString input = storage->input(); diff --git a/src/plugins/coreplugin/actionsfilter.cpp b/src/plugins/coreplugin/actionsfilter.cpp index cc4939830ec..93efa1dd2cc 100644 --- a/src/plugins/coreplugin/actionsfilter.cpp +++ b/src/plugins/coreplugin/actionsfilter.cpp @@ -178,7 +178,7 @@ LocatorMatcherTasks ActionsFilter::matchers() { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [this, storage](Async &async) { m_entries.clear(); diff --git a/src/plugins/coreplugin/locator/commandlocator.cpp b/src/plugins/coreplugin/locator/commandlocator.cpp index 6fd21a524ba..2d997dd020a 100644 --- a/src/plugins/coreplugin/locator/commandlocator.cpp +++ b/src/plugins/coreplugin/locator/commandlocator.cpp @@ -27,7 +27,7 @@ LocatorMatcherTasks CommandLocator::matchers() { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [storage, commands = m_commands] { const QString input = storage->input(); diff --git a/src/plugins/coreplugin/locator/executefilter.cpp b/src/plugins/coreplugin/locator/executefilter.cpp index 2a405c369ea..cd012629a33 100644 --- a/src/plugins/coreplugin/locator/executefilter.cpp +++ b/src/plugins/coreplugin/locator/executefilter.cpp @@ -42,7 +42,7 @@ LocatorMatcherTasks ExecuteFilter::matchers() { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [=] { const QString input = storage->input(); diff --git a/src/plugins/coreplugin/locator/externaltoolsfilter.cpp b/src/plugins/coreplugin/locator/externaltoolsfilter.cpp index 36fc78cba9b..86811e55b0b 100644 --- a/src/plugins/coreplugin/locator/externaltoolsfilter.cpp +++ b/src/plugins/coreplugin/locator/externaltoolsfilter.cpp @@ -29,7 +29,7 @@ LocatorMatcherTasks ExternalToolsFilter::matchers() { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [storage] { const QString input = storage->input(); diff --git a/src/plugins/coreplugin/locator/filesystemfilter.cpp b/src/plugins/coreplugin/locator/filesystemfilter.cpp index 07bb25c1086..00890829b45 100644 --- a/src/plugins/coreplugin/locator/filesystemfilter.cpp +++ b/src/plugins/coreplugin/locator/filesystemfilter.cpp @@ -308,7 +308,7 @@ LocatorMatcherTasks FileSystemFilter::matchers() { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [storage, includeHidden = m_includeHidden, shortcut = shortcutString()] (Async &async) { diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.cpp b/src/plugins/coreplugin/locator/ilocatorfilter.cpp index 764c0774613..307abb94594 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/ilocatorfilter.cpp @@ -429,7 +429,7 @@ void LocatorMatcher::start() { ResultsCollector *m_collector = nullptr; }; - TreeStorage collectorStorage; + Storage collectorStorage; const int filterCount = d->m_tasks.size(); const auto onCollectorSetup = [this, filterCount, collectorStorage](ResultsCollector &collector) { @@ -447,7 +447,7 @@ void LocatorMatcher::start() QList parallelTasks {parallelLimit(d->m_parallelLimit)}; - const auto onSetup = [this, collectorStorage](const TreeStorage &storage, + const auto onSetup = [this, collectorStorage](const Storage &storage, int index) { return [this, collectorStorage, storage, index] { ResultsCollector *collector = collectorStorage->m_collector; @@ -1482,7 +1482,7 @@ static void filter(QPromise &promise, const LocatorStor */ LocatorMatcherTask LocatorFileCache::matcher() const { - TreeStorage storage; + Storage storage; std::weak_ptr weak = d; const auto onSetup = [storage, weak](Async &async) { diff --git a/src/plugins/coreplugin/locator/ilocatorfilter.h b/src/plugins/coreplugin/locator/ilocatorfilter.h index 57da6a2d85f..09c2c289100 100644 --- a/src/plugins/coreplugin/locator/ilocatorfilter.h +++ b/src/plugins/coreplugin/locator/ilocatorfilter.h @@ -142,7 +142,7 @@ public: Tasking::GroupItem task = Tasking::Group{}; // When constructing the task, don't place the storage inside the task above. - Tasking::TreeStorage storage; + Tasking::Storage storage; }; using LocatorMatcherTasks = QList; diff --git a/src/plugins/coreplugin/locator/javascriptfilter.cpp b/src/plugins/coreplugin/locator/javascriptfilter.cpp index f1b8af35b9c..a991e201692 100644 --- a/src/plugins/coreplugin/locator/javascriptfilter.cpp +++ b/src/plugins/coreplugin/locator/javascriptfilter.cpp @@ -365,7 +365,7 @@ JavaScriptFilter::~JavaScriptFilter() = default; LocatorMatcherTasks JavaScriptFilter::matchers() { - TreeStorage storage; + Storage storage; if (!m_javaScriptEngine) m_javaScriptEngine.reset(new JavaScriptEngine); QPointer engine = m_javaScriptEngine.get(); diff --git a/src/plugins/coreplugin/locator/locatorfiltersfilter.cpp b/src/plugins/coreplugin/locator/locatorfiltersfilter.cpp index 782cb3f5576..fa44d967e67 100644 --- a/src/plugins/coreplugin/locator/locatorfiltersfilter.cpp +++ b/src/plugins/coreplugin/locator/locatorfiltersfilter.cpp @@ -28,7 +28,7 @@ LocatorMatcherTasks LocatorFiltersFilter::matchers() { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [storage, icon = m_icon] { if (!storage->input().isEmpty()) diff --git a/src/plugins/coreplugin/locator/opendocumentsfilter.cpp b/src/plugins/coreplugin/locator/opendocumentsfilter.cpp index a13f51484bf..719de23098b 100644 --- a/src/plugins/coreplugin/locator/opendocumentsfilter.cpp +++ b/src/plugins/coreplugin/locator/opendocumentsfilter.cpp @@ -72,7 +72,7 @@ static void matchEditors(QPromise &promise, const LocatorStorage &storage, LocatorMatcherTasks OpenDocumentsFilter::matchers() { - TreeStorage storage; + Storage storage; const auto onSetup = [storage](Async &async) { const QList editorsData = Utils::transform(DocumentModel::entries(), diff --git a/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp b/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp index c9f7e43d7da..7ecd298a8c9 100644 --- a/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/spotlightlocatorfilter.cpp @@ -180,7 +180,7 @@ LocatorMatcherTasks SpotlightLocatorFilter::matchers() { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [storage, command = m_command, diff --git a/src/plugins/coreplugin/locator/urllocatorfilter.cpp b/src/plugins/coreplugin/locator/urllocatorfilter.cpp index c9025b2237a..1c67d9e0328 100644 --- a/src/plugins/coreplugin/locator/urllocatorfilter.cpp +++ b/src/plugins/coreplugin/locator/urllocatorfilter.cpp @@ -165,7 +165,7 @@ LocatorMatcherTasks UrlLocatorFilter::matchers() { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [storage, urls = remoteUrls()] { const QString input = storage->input(); diff --git a/src/plugins/cppeditor/cpplocatorfilter.cpp b/src/plugins/cppeditor/cpplocatorfilter.cpp index 5e429ece522..c6d1be6663c 100644 --- a/src/plugins/cppeditor/cpplocatorfilter.cpp +++ b/src/plugins/cppeditor/cpplocatorfilter.cpp @@ -106,7 +106,7 @@ LocatorMatcherTask locatorMatcher(IndexItem::ItemType type, const EntryFromIndex { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [=](Async &async) { async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); @@ -304,7 +304,7 @@ LocatorMatcherTask currentDocumentMatcher() { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [=](Async &async) { async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); diff --git a/src/plugins/cppeditor/cppprojectupdater.cpp b/src/plugins/cppeditor/cppprojectupdater.cpp index 547dcd50c54..3e208a8bf63 100644 --- a/src/plugins/cppeditor/cppprojectupdater.cpp +++ b/src/plugins/cppeditor/cppprojectupdater.cpp @@ -51,7 +51,7 @@ void CppProjectUpdater::update(const ProjectUpdateInfo &projectUpdateInfo, struct UpdateStorage { ProjectInfo::ConstPtr projectInfo = nullptr; }; - const TreeStorage storage; + const Storage storage; const auto onInfoGeneratorSetup = [=](Async &async) { async.setConcurrentCallData(infoGenerator); async.setFutureSynchronizer(&m_futureSynchronizer); diff --git a/src/plugins/diffeditor/diffeditorplugin.cpp b/src/plugins/diffeditor/diffeditorplugin.cpp index 04ab3c7d87e..da2e4daaf21 100644 --- a/src/plugins/diffeditor/diffeditorplugin.cpp +++ b/src/plugins/diffeditor/diffeditorplugin.cpp @@ -108,7 +108,7 @@ DiffFilesController::DiffFilesController(IDocument *document) setDisplayName(Tr::tr("Diff")); using namespace Tasking; - const TreeStorage>> storage; + const Storage>> storage; const auto onTreeSetup = [this, storage](TaskTree &taskTree) { QList> *outputList = storage.activeStorage(); diff --git a/src/plugins/git/branchview.cpp b/src/plugins/git/branchview.cpp index edb055a1fa1..4b846d38e54 100644 --- a/src/plugins/git/branchview.cpp +++ b/src/plugins/git/branchview.cpp @@ -545,7 +545,7 @@ TaskTree *BranchView::onFastForwardMerge(const std::function &callback) QString topRevision; }; - const TreeStorage storage; + const Storage storage; const auto onMergeBaseSetup = [repository = m_repository, branch](Process &process) { gitClient().setupCommand(process, repository, {"merge-base", "HEAD", branch}); diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 0b490d74eb1..508b1d4b81f 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -236,7 +236,7 @@ GitDiffEditorController::GitDiffEditorController(IDocument *document, const QStringList &extraArgs) : GitBaseDiffEditorController(document) { - const TreeStorage diffInputStorage; + const Storage diffInputStorage; const auto onDiffSetup = [=](Process &process) { process.setCodec(VcsBaseEditor::getCodec(workingDirectory(), {})); @@ -299,8 +299,8 @@ FileListDiffController::FileListDiffController(IDocument *document, const QStrin QString m_unstagedOutput; }; - const TreeStorage storage; - const TreeStorage diffInputStorage; + const Storage storage; + const Storage diffInputStorage; const auto onStagedSetup = [this, stagedFiles](Process &process) { if (stagedFiles.isEmpty()) @@ -371,8 +371,8 @@ ShowController::ShowController(IDocument *document, const QString &id) QStringList m_follows; }; - const TreeStorage storage; - const TreeStorage diffInputStorage; + const Storage storage; + const Storage diffInputStorage; const auto updateDescription = [this](const ReloadStorage &storage) { QString desc = storage.m_header; diff --git a/src/plugins/help/helpindexfilter.cpp b/src/plugins/help/helpindexfilter.cpp index 4c8910b1d86..60fc93b7652 100644 --- a/src/plugins/help/helpindexfilter.cpp +++ b/src/plugins/help/helpindexfilter.cpp @@ -83,7 +83,7 @@ static void matches(QPromise &promise, const LocatorStorage &storag LocatorMatcherTasks HelpIndexFilter::matchers() { - TreeStorage storage; + Storage storage; const auto onSetup = [this, storage](Async &async) { if (m_needsUpdate) { diff --git a/src/plugins/ios/iosdeploystep.cpp b/src/plugins/ios/iosdeploystep.cpp index 02f75d27671..86493b7e975 100644 --- a/src/plugins/ios/iosdeploystep.cpp +++ b/src/plugins/ios/iosdeploystep.cpp @@ -107,7 +107,7 @@ public: private: void cleanup(); - Tasking::GroupItem runRecipe() final; + GroupItem runRecipe() final; void updateDisplayNames(); diff --git a/src/plugins/languageclient/locatorfilter.cpp b/src/plugins/languageclient/locatorfilter.cpp index bd4b3907506..ccebcd76799 100644 --- a/src/plugins/languageclient/locatorfilter.cpp +++ b/src/plugins/languageclient/locatorfilter.cpp @@ -48,8 +48,8 @@ LocatorMatcherTask locatorMatcher(Client *client, int maxResultCount, { using namespace Tasking; - TreeStorage storage; - TreeStorage> resultStorage; + Storage storage; + Storage> resultStorage; const auto onQuerySetup = [storage, client, maxResultCount](ClientWorkspaceSymbolRequest &request) { request.setClient(client); @@ -119,8 +119,8 @@ LocatorMatcherTask currentDocumentMatcher() { using namespace Tasking; - TreeStorage storage; - TreeStorage resultStorage; + Storage storage; + Storage resultStorage; const auto onQuerySetup = [](CurrentDocumentSymbolsRequest &request) { Q_UNUSED(request) diff --git a/src/plugins/macros/macrolocatorfilter.cpp b/src/plugins/macros/macrolocatorfilter.cpp index f43758bd034..4cc819d8b73 100644 --- a/src/plugins/macros/macrolocatorfilter.cpp +++ b/src/plugins/macros/macrolocatorfilter.cpp @@ -30,7 +30,7 @@ LocatorMatcherTasks MacroLocatorFilter::matchers() { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [storage, icon = m_icon] { const QString input = storage->input(); diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp index 00eb11ca201..e80ab8eabc6 100644 --- a/src/plugins/mercurial/mercurialclient.cpp +++ b/src/plugins/mercurial/mercurialclient.cpp @@ -53,7 +53,7 @@ MercurialDiffEditorController::MercurialDiffEditorController(IDocument *document using namespace Tasking; - const TreeStorage diffInputStorage; + const Storage diffInputStorage; const auto onDiffSetup = [=](Process &process) { setupCommand(process, {addConfigurationArguments(args)}); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index e88d4225414..b34d20ea367 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -4179,7 +4179,7 @@ static LocatorMatcherTasks runConfigurationMatchers(const RunAcceptor &acceptor) { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [storage, acceptor] { const QString input = storage->input(); diff --git a/src/plugins/qmljstools/qmljsfunctionfilter.cpp b/src/plugins/qmljstools/qmljsfunctionfilter.cpp index 34a60040f3c..0453d11b9c1 100644 --- a/src/plugins/qmljstools/qmljsfunctionfilter.cpp +++ b/src/plugins/qmljstools/qmljsfunctionfilter.cpp @@ -78,7 +78,7 @@ LocatorMatcherTasks QmlJSFunctionsFilter::matchers() { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [storage, entries = m_data->entries()](Async &async) { async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); diff --git a/src/plugins/remotelinux/genericdeploystep.cpp b/src/plugins/remotelinux/genericdeploystep.cpp index 5c81bdfd249..77aef3d522c 100644 --- a/src/plugins/remotelinux/genericdeploystep.cpp +++ b/src/plugins/remotelinux/genericdeploystep.cpp @@ -64,15 +64,15 @@ public: private: GroupItem deployRecipe() final; - GroupItem mkdirTask(const TreeStorage &storage); - GroupItem transferTask(const TreeStorage &storage); + GroupItem mkdirTask(const Storage &storage); + GroupItem transferTask(const Storage &storage); StringAspect flags{this}; BoolAspect ignoreMissingFiles{this}; SelectionAspect method{this}; }; -GroupItem GenericDeployStep::mkdirTask(const TreeStorage &storage) +GroupItem GenericDeployStep::mkdirTask(const Storage &storage) { using ResultType = expected_str; @@ -133,7 +133,7 @@ static FileTransferMethod supportedTransferMethodFor(const FileToTransfer &fileT return FileTransferMethod::GenericCopy; } -GroupItem GenericDeployStep::transferTask(const TreeStorage &storage) +GroupItem GenericDeployStep::transferTask(const Storage &storage) { const auto onSetup = [this, storage](FileTransfer &transfer) { FileTransferMethod preferredTransferMethod = FileTransferMethod::Rsync; @@ -180,7 +180,7 @@ GroupItem GenericDeployStep::transferTask(const TreeStorage &st GroupItem GenericDeployStep::deployRecipe() { - const TreeStorage storage; + const Storage storage; const auto onSetup = [this, storage] { const QList deployableFiles = target()->deploymentData().allFiles(); diff --git a/src/plugins/remotelinux/genericdirectuploadstep.cpp b/src/plugins/remotelinux/genericdirectuploadstep.cpp index 4e751a1aea3..97a8dcd1bb7 100644 --- a/src/plugins/remotelinux/genericdirectuploadstep.cpp +++ b/src/plugins/remotelinux/genericdirectuploadstep.cpp @@ -64,11 +64,11 @@ public: = std::function; GroupItem statTask(UploadStorage *storage, const DeployableFile &file, StatEndHandler statEndHandler); - GroupItem statTree(const TreeStorage &storage, FilesToStat filesToStat, + GroupItem statTree(const Storage &storage, FilesToStat filesToStat, StatEndHandler statEndHandler); - GroupItem uploadTask(const TreeStorage &storage); + GroupItem uploadTask(const Storage &storage); GroupItem chmodTask(const DeployableFile &file); - GroupItem chmodTree(const TreeStorage &storage); + GroupItem chmodTree(const Storage &storage); BoolAspect incremental{this}; BoolAspect ignoreMissingFiles{this}; @@ -148,7 +148,7 @@ GroupItem GenericDirectUploadStep::statTask(UploadStorage *storage, return ProcessTask(onSetup, onDone); } -GroupItem GenericDirectUploadStep::statTree(const TreeStorage &storage, +GroupItem GenericDirectUploadStep::statTree(const Storage &storage, FilesToStat filesToStat, StatEndHandler statEndHandler) { const auto onSetup = [this, storage, filesToStat, statEndHandler](TaskTree &tree) { @@ -164,7 +164,7 @@ GroupItem GenericDirectUploadStep::statTree(const TreeStorage &st return TaskTreeTask(onSetup); } -GroupItem GenericDirectUploadStep::uploadTask(const TreeStorage &storage) +GroupItem GenericDirectUploadStep::uploadTask(const Storage &storage) { const auto onSetup = [this, storage](FileTransfer &transfer) { if (storage->filesToUpload.isEmpty()) { @@ -223,7 +223,7 @@ GroupItem GenericDirectUploadStep::chmodTask(const DeployableFile &file) return ProcessTask(onSetup, onError, CallDoneIf::Error); } -GroupItem GenericDirectUploadStep::chmodTree(const TreeStorage &storage) +GroupItem GenericDirectUploadStep::chmodTree(const Storage &storage) { const auto onSetup = [this, storage](TaskTree &tree) { QList filesToChmod; @@ -243,7 +243,7 @@ GroupItem GenericDirectUploadStep::chmodTree(const TreeStorage &s GroupItem GenericDirectUploadStep::deployRecipe() { - const TreeStorage storage; + const Storage storage; const auto setupHandler = [this, storage] { const QList deployableFiles = target()->deploymentData().allFiles(); diff --git a/src/plugins/remotelinux/linuxdevicetester.cpp b/src/plugins/remotelinux/linuxdevicetester.cpp index 2e4598d9de8..11d9e7a3f5c 100644 --- a/src/plugins/remotelinux/linuxdevicetester.cpp +++ b/src/plugins/remotelinux/linuxdevicetester.cpp @@ -38,7 +38,7 @@ public: GroupItem unameTask() const; GroupItem gathererTask() const; GroupItem transferTask(FileTransferMethod method, - const TreeStorage &storage) const; + const Storage &storage) const; GroupItem transferTasks() const; GroupItem commandTask(const QString &commandName) const; GroupItem commandTasks() const; @@ -168,7 +168,7 @@ GroupItem GenericLinuxDeviceTesterPrivate::gathererTask() const } GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod method, - const TreeStorage &storage) const + const Storage &storage) const { const auto onSetup = [this, method](FileTransfer &transfer) { emit q->progressMessage(Tr::tr("Checking whether \"%1\" works...") @@ -226,7 +226,7 @@ GroupItem GenericLinuxDeviceTesterPrivate::transferTask(FileTransferMethod metho GroupItem GenericLinuxDeviceTesterPrivate::transferTasks() const { - TreeStorage storage; + Storage storage; return Group { continueOnSuccess, storage, diff --git a/src/plugins/subversion/subversionclient.cpp b/src/plugins/subversion/subversionclient.cpp index c9d5df2d94a..beca47372de 100644 --- a/src/plugins/subversion/subversionclient.cpp +++ b/src/plugins/subversion/subversionclient.cpp @@ -163,7 +163,7 @@ SubversionDiffEditorController::SubversionDiffEditorController(IDocument *docume using namespace Tasking; - const TreeStorage diffInputStorage; + const Storage diffInputStorage; const auto onDescriptionSetup = [this](Process &process) { if (m_changeNumber == 0) diff --git a/src/plugins/texteditor/bookmarkfilter.cpp b/src/plugins/texteditor/bookmarkfilter.cpp index 2756521cd89..c56ddff617d 100644 --- a/src/plugins/texteditor/bookmarkfilter.cpp +++ b/src/plugins/texteditor/bookmarkfilter.cpp @@ -29,7 +29,7 @@ LocatorMatcherTasks BookmarkFilter::matchers() { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [=] { storage->reportOutput(match(storage->input())); }; return {{Sync(onSetup), storage}}; diff --git a/src/plugins/texteditor/linenumberfilter.cpp b/src/plugins/texteditor/linenumberfilter.cpp index b718e5b4331..0ac0a83ee68 100644 --- a/src/plugins/texteditor/linenumberfilter.cpp +++ b/src/plugins/texteditor/linenumberfilter.cpp @@ -27,7 +27,7 @@ LocatorMatcherTasks LineNumberFilter::matchers() { using namespace Tasking; - TreeStorage storage; + Storage storage; const auto onSetup = [storage] { const QStringList lineAndColumn = storage->input().split(':'); diff --git a/src/plugins/valgrind/valgrindprocess.cpp b/src/plugins/valgrind/valgrindprocess.cpp index aee18e170f9..c750e2963f2 100644 --- a/src/plugins/valgrind/valgrindprocess.cpp +++ b/src/plugins/valgrind/valgrindprocess.cpp @@ -127,7 +127,7 @@ Group ValgrindProcessPrivate::runRecipe() const std::unique_ptr m_xmlSocket; }; - TreeStorage storage; + Storage storage; SingleBarrier xmlBarrier; const auto onSetup = [this, storage, xmlBarrier] { diff --git a/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp b/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp index 62f2a001d1d..cbd33f48fcf 100644 --- a/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp +++ b/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp @@ -38,7 +38,7 @@ VcsBaseDiffEditorController::~VcsBaseDiffEditorController() delete d; } -GroupItem VcsBaseDiffEditorController::postProcessTask(const TreeStorage &inputStorage) +GroupItem VcsBaseDiffEditorController::postProcessTask(const Storage &inputStorage) { const auto onSetup = [inputStorage](Async> &async) { async.setFutureSynchronizer(ExtensionSystem::PluginManager::futureSynchronizer()); diff --git a/src/plugins/vcsbase/vcsbasediffeditorcontroller.h b/src/plugins/vcsbase/vcsbasediffeditorcontroller.h index 2cd2ece26c8..f5a648d5b17 100644 --- a/src/plugins/vcsbase/vcsbasediffeditorcontroller.h +++ b/src/plugins/vcsbase/vcsbasediffeditorcontroller.h @@ -26,7 +26,7 @@ public: void setVcsBinary(const Utils::FilePath &path); protected: - Tasking::GroupItem postProcessTask(const Tasking::TreeStorage &inputStorage); + Tasking::GroupItem postProcessTask(const Tasking::Storage &inputStorage); void setupCommand(Utils::Process &process, const QStringList &args) const; diff --git a/tests/auto/solutions/concurrentcall/tst_concurrentcall.cpp b/tests/auto/solutions/concurrentcall/tst_concurrentcall.cpp index 6f98ab4a073..69d7f83c16c 100644 --- a/tests/auto/solutions/concurrentcall/tst_concurrentcall.cpp +++ b/tests/auto/solutions/concurrentcall/tst_concurrentcall.cpp @@ -42,7 +42,7 @@ private: struct TestData { - TreeStorage storage; + Storage storage; Group root; }; @@ -136,7 +136,7 @@ template ::Type> TestData createTestData(const QList &expectedResults, Function &&function, Args &&...args) { - TreeStorage storage; + Storage storage; const auto onSetup = [=](ConcurrentCall &task) { task.setConcurrentCallData(function, args...); @@ -197,8 +197,8 @@ void tst_ConcurrentCall::taskTree_data() << createTestData(reportNResult, &MyObject::member, &m_myObject, 2); { - TreeStorage storage; - TreeStorage internalStorage; + Storage storage; + Storage internalStorage; const auto onSetup = [internalStorage](ConcurrentCall &task) { task.setConcurrentCallData(multiplyBy2, *internalStorage); diff --git a/tests/auto/solutions/tasking/tst_tasking.cpp b/tests/auto/solutions/tasking/tst_tasking.cpp index fc4e0d26a3a..0d7f8bac3a2 100644 --- a/tests/auto/solutions/tasking/tst_tasking.cpp +++ b/tests/auto/solutions/tasking/tst_tasking.cpp @@ -78,7 +78,7 @@ std::atomic_int CustomStorage::s_count = 0; struct TestData { - TreeStorage storage; + Storage storage; Group root; Log expectedLog; int taskCount = 0; @@ -258,7 +258,7 @@ void tst_Tasking::runtimeCheck() QTest::ignoreMessage(QtDebugMsg, QRegularExpression("^SOFT ASSERT: ")); QTest::ignoreMessage(QtWarningMsg, "Can't add the same storage into one Group twice, skipping..."); - const TreeStorage storage; + const Storage storage; Group { storage, @@ -270,7 +270,7 @@ void tst_Tasking::runtimeCheck() QTest::ignoreMessage(QtDebugMsg, QRegularExpression("^SOFT ASSERT: ")); QTest::ignoreMessage(QtWarningMsg, "Can't add the same storage into one Group twice, skipping..."); - const TreeStorage storage1; + const Storage storage1; const auto storage2 = storage1; Group { @@ -352,7 +352,7 @@ public: using TickAndDoneTask = CustomTask; template -GroupItem createBarrierAdvance(const TreeStorage &storage, +GroupItem createBarrierAdvance(const Storage &storage, const SharedBarrierType &barrier, int taskId) { return TickAndDoneTask([storage, barrier, taskId](TickAndDone &tickAndDone) { @@ -398,11 +398,11 @@ static TestData storageShadowingData() { // This test check if storage shadowing works OK. - const TreeStorage storage; + const Storage storage; // This helper storage collect the pointers to storages created by shadowedStorage. - const TreeStorage> helperStorage; // One instance in this test. + const Storage> helperStorage; // One instance in this test. // This storage is repeated in nested groups, the innermost storage will shadow outer ones. - const TreeStorage shadowedStorage; // Three instances in this test. + const Storage shadowedStorage; // Three instances in this test. const auto groupSetupWithStorage = [storage, helperStorage, shadowedStorage](int taskId) { return onGroupSetup([storage, helperStorage, shadowedStorage, taskId] { @@ -473,7 +473,7 @@ static TestData storageShadowingData() static TestData parallelData() { - TreeStorage storage; + Storage storage; const auto setupTask = [storage](int taskId, milliseconds timeout) { return [storage, taskId, timeout](TaskObject &taskObject) { @@ -539,7 +539,7 @@ void tst_Tasking::testTree_data() { QTest::addColumn("testData"); - TreeStorage storage; + Storage storage; const auto setupTask = [storage](int taskId, milliseconds timeout) { return [storage, taskId, timeout](TaskObject &taskObject) { @@ -2746,7 +2746,7 @@ struct StorageIO int value = 0; }; -static Group inputOutputRecipe(const TreeStorage &storage) +static Group inputOutputRecipe(const Storage &storage) { return Group { storage, @@ -2773,7 +2773,7 @@ void tst_Tasking::storageIO() int actualOutput = 0; - const TreeStorage storage; + const Storage storage; TaskTree taskTree(inputOutputRecipe(storage)); const auto setInput = [input](StorageIO &storage) { storage.value = input; }; @@ -2789,8 +2789,8 @@ void tst_Tasking::storageIO() void tst_Tasking::storageOperators() { - StorageBase storage1 = TreeStorage(); - StorageBase storage2 = TreeStorage(); + StorageBase storage1 = Storage(); + StorageBase storage2 = Storage(); StorageBase storage3 = storage1; QVERIFY(storage1 == storage3); @@ -2814,7 +2814,7 @@ void tst_Tasking::storageDestructor() }; QCOMPARE(CustomStorage::instanceCount(), 0); { - TreeStorage storage; + Storage storage; const auto setupSleepingTask = [](TaskObject &taskObject) { taskObject = 1000ms; }; diff --git a/tests/manual/tasking/dataexchange/recipe.cpp b/tests/manual/tasking/dataexchange/recipe.cpp index 389377c388d..f89b31e27cc 100644 --- a/tests/manual/tasking/dataexchange/recipe.cpp +++ b/tests/manual/tasking/dataexchange/recipe.cpp @@ -31,9 +31,9 @@ public: static int sizeForIndex(int index) { return (index + 1) * s_sizeInterval; } -Group recipe(const Tasking::TreeStorage &externalStorage) +Group recipe(const Storage &externalStorage) { - TreeStorage internalStorage; + Storage internalStorage; const auto onDownloadSetup = [externalStorage](NetworkQuery &query) { query.setNetworkAccessManager(externalStorage->inputNam); diff --git a/tests/manual/tasking/dataexchange/recipe.h b/tests/manual/tasking/dataexchange/recipe.h index 7b17e1349a3..327a7e88166 100644 --- a/tests/manual/tasking/dataexchange/recipe.h +++ b/tests/manual/tasking/dataexchange/recipe.h @@ -13,7 +13,7 @@ namespace Tasking { class Group; template -class TreeStorage; +class Storage; } static const int s_sizeInterval = 10; @@ -31,6 +31,6 @@ public: std::optional outputError; }; -Tasking::Group recipe(const Tasking::TreeStorage &externalStorage); +Tasking::Group recipe(const Tasking::Storage &externalStorage); #endif // RECIPE_H diff --git a/tests/manual/tasking/dataexchange/viewer.h b/tests/manual/tasking/dataexchange/viewer.h index 81575596f5f..46fe6943ffd 100644 --- a/tests/manual/tasking/dataexchange/viewer.h +++ b/tests/manual/tasking/dataexchange/viewer.h @@ -25,7 +25,7 @@ private: QStatusBar *m_statusBar = nullptr; QNetworkAccessManager m_nam; - const Tasking::TreeStorage m_storage; + const Tasking::Storage m_storage; const Tasking::Group m_recipe; std::unique_ptr m_taskTree; }; diff --git a/tests/manual/tasking/imagescaling/imagescaling.cpp b/tests/manual/tasking/imagescaling/imagescaling.cpp index 36b6a71ad83..0da91089862 100644 --- a/tests/manual/tasking/imagescaling/imagescaling.cpp +++ b/tests/manual/tasking/imagescaling/imagescaling.cpp @@ -73,7 +73,7 @@ void Images::process() int i = 0; for (const QUrl &url : urls) { - TreeStorage storage; + Storage storage; const auto onDownloadSetup = [this, url](NetworkQuery &query) { query.setNetworkAccessManager(&qnam); From 39e39408b2b352ec70b11ee021b8f27c032c99ed Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sun, 19 Nov 2023 16:43:55 +0100 Subject: [PATCH 0277/1546] TaskTree: Get rid of StorageBase::isValid() Not used and not needed. Change-Id: I3ba4b86c57c1d3d6ecf5999e16d79142d50d8a07 Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 5 ----- src/libs/solutions/tasking/tasktree.h | 3 --- 2 files changed, 8 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 30226f72f22..916d56d5156 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -972,11 +972,6 @@ StorageData::~StorageData() QT_CHECK(m_threadDataMap.empty()); } -bool StorageBase::isValid() const -{ - return m_storageData && m_storageData->m_constructor && m_storageData->m_destructor; -} - StorageBase::StorageBase(StorageConstructor ctor, StorageDestructor dtor) : m_storageData(new StorageData{ctor, dtor}) {} diff --git a/src/libs/solutions/tasking/tasktree.h b/src/libs/solutions/tasking/tasktree.h index 022a466294f..1ac371a4905 100644 --- a/src/libs/solutions/tasking/tasktree.h +++ b/src/libs/solutions/tasking/tasktree.h @@ -98,9 +98,6 @@ protected: class TASKING_EXPORT StorageBase { -public: - bool isValid() const; - private: using StorageConstructor = std::function; using StorageDestructor = std::function; From 9c5831dc80d1b212cf26fccdffb27add70857aa6 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Mon, 20 Nov 2023 08:24:47 +0100 Subject: [PATCH 0278/1546] TaskTree demo: Tweak the done result instead of nesting a Group Tweak the return value of the TimeoutTask instead of nesting a Group with conditional workflow policy. Rename TaskWidget::isSuccess() into desiredResult(). Change-Id: I3d6f703427f13e8feb6d6db97c07b8b9f8b261a6 Reviewed-by: hjk --- tests/manual/tasking/demo/main.cpp | 21 ++++++++++++--------- tests/manual/tasking/demo/taskwidget.cpp | 10 +++++----- tests/manual/tasking/demo/taskwidget.h | 4 ++-- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/tests/manual/tasking/demo/main.cpp b/tests/manual/tasking/demo/main.cpp index 75dd97fa5a7..8d962d7940b 100644 --- a/tests/manual/tasking/demo/main.cpp +++ b/tests/manual/tasking/demo/main.cpp @@ -115,13 +115,13 @@ int main(int argc, char *argv[]) // Task initial configuration task_1_2->setBusyTime(2); - task_1_2->setSuccess(false); + task_1_2->setDesiredResult(DoneResult::Error); task_1_3->setBusyTime(3); task_4_3_1->setBusyTime(4); task_4_3_2->setBusyTime(2); task_4_3_3->setBusyTime(1); task_4_3_4->setBusyTime(3); - task_4_3_4->setSuccess(false); + task_4_3_4->setDesiredResult(DoneResult::Error); task_4_4->setBusyTime(6); task_4_4->setBusyTime(3); @@ -193,17 +193,20 @@ int main(int argc, char *argv[]) }; const auto createTask = [](TaskWidget *widget) { - const milliseconds timeout{widget->busyTime() * 1000}; - const auto setupTask = [widget, timeout](milliseconds &taskObject) { + const milliseconds timeout(widget->busyTime() * 1000); + const auto onSetup = [widget, timeout](milliseconds &taskObject) { taskObject = timeout; widget->setState(State::Running); }; - const Group root { - widget->isSuccess() ? stopOnError : finishAllAndError, - TimeoutTask(setupTask), - onGroupDone([widget](DoneWith result) { widget->setState(resultToState(result)); }) + const auto onDone = [widget, desiredResult = widget->desiredResult()](DoneWith doneWith) { + // The TimeoutTask, when not DoneWith::Cancel, always reports DoneWith::Success. + // Tweak the final result in case the desired result is Error. + const DoneWith result = doneWith == DoneWith::Success + && desiredResult == DoneResult::Error ? DoneWith::Error : doneWith; + widget->setState(resultToState(result)); + return desiredResult; }; - return root; + return TimeoutTask(onSetup, onDone); }; const auto recipe = [&] { diff --git a/tests/manual/tasking/demo/taskwidget.cpp b/tests/manual/tasking/demo/taskwidget.cpp index 6e698374665..56c2def3e6a 100644 --- a/tests/manual/tasking/demo/taskwidget.cpp +++ b/tests/manual/tasking/demo/taskwidget.cpp @@ -93,7 +93,7 @@ TaskWidget::TaskWidget() { m_spinBox->setSuffix(" sec"); setBusyTime(1); - setSuccess(true); + setDesiredResult(DoneResult::Success); QBoxLayout *layout = new QHBoxLayout(this); layout->addWidget(m_stateWidget); @@ -114,14 +114,14 @@ int TaskWidget::busyTime() const return m_spinBox->value(); } -void TaskWidget::setSuccess(bool success) +void TaskWidget::setDesiredResult(DoneResult result) { - m_checkBox->setChecked(success); + m_checkBox->setChecked(result == DoneResult::Success); } -bool TaskWidget::isSuccess() const +DoneResult TaskWidget::desiredResult() const { - return m_checkBox->isChecked(); + return m_checkBox->isChecked() ? DoneResult::Success : DoneResult::Error; } GroupWidget::GroupWidget() diff --git a/tests/manual/tasking/demo/taskwidget.h b/tests/manual/tasking/demo/taskwidget.h index bb7f949b817..781b3d428d0 100644 --- a/tests/manual/tasking/demo/taskwidget.h +++ b/tests/manual/tasking/demo/taskwidget.h @@ -49,8 +49,8 @@ public: void setBusyTime(int seconds); int busyTime() const; - void setSuccess(bool success); - bool isSuccess() const; + void setDesiredResult(Tasking::DoneResult result); + Tasking::DoneResult desiredResult() const; private: StateWidget *m_stateWidget = nullptr; From 20d82c48b353ea4a872f2c759608d8ca1ac27102 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sun, 19 Nov 2023 15:19:25 +0100 Subject: [PATCH 0279/1546] ScreenRecorder: Fix closing namespace comment Change-Id: I078543dcf3e4ba005427988a0b74ee30ce751ee5 Reviewed-by: hjk --- src/plugins/screenrecorder/screenrecordersettings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/screenrecorder/screenrecordersettings.cpp b/src/plugins/screenrecorder/screenrecordersettings.cpp index 0a94638f855..4647d9fb9e5 100644 --- a/src/plugins/screenrecorder/screenrecordersettings.cpp +++ b/src/plugins/screenrecorder/screenrecordersettings.cpp @@ -270,4 +270,4 @@ public: static const ScreenRecorderSettingsPage settingsPage; -} // ImageViewer::Internal +} // namespace ScreenRecorder::Internal From 3f9f249c0da976dee5d761fc707a9df1c9b23061 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 16 Nov 2023 17:38:20 +0100 Subject: [PATCH 0280/1546] Doc: Add a readme.md for using recolordocsicons.py In preparation of moving the instructions for taking screenshots from the Extending Qt Creator Manual to a QUIP. Change-Id: I034185e7ab4878cf36766db1e9a6b8de5d2b3fed Reviewed-by: Eike Ziller --- .../src/qtcreator-documentation.qdoc | 21 ++----------- src/tools/icons/README.md | 30 +++++++++++++++++++ 2 files changed, 32 insertions(+), 19 deletions(-) create mode 100644 src/tools/icons/README.md diff --git a/doc/qtcreatordev/src/qtcreator-documentation.qdoc b/doc/qtcreatordev/src/qtcreator-documentation.qdoc index 8b9e3bbacca..f3fbb1ee33b 100644 --- a/doc/qtcreatordev/src/qtcreator-documentation.qdoc +++ b/doc/qtcreatordev/src/qtcreator-documentation.qdoc @@ -358,25 +358,8 @@ If you receive a large number of icons that are not visible in either light or dark mode or have a solid background, run the \c recolordocsicons.py - Python script from the \c src/tools/icons/ directory. By default, the script - recolors icons in \c qtcreator/doc/qtcreator/images/icons. Use the - \c -docspath option to specify the path to another icon source directory. - - For example, if you saved the new icons in \c {C:\iconconversions}, switch to - the \c {qtcreator\src\tools\icons} folder and enter: - - \badcode - recolordocsicons.py -docspath C:\iconconversions - \endcode - - To run the script, you will need to install the following tools and add them - to the PATH: - - \list - \li Python 3.x (the script has been tested to work with 3.10) - \li ImageMagick - \li optipng - \endlist + Python script from the \c src/tools/icons/ directory. For options + and examples, see the \c README.md file. \section2 Saving Images diff --git a/src/tools/icons/README.md b/src/tools/icons/README.md new file mode 100644 index 00000000000..2958178f064 --- /dev/null +++ b/src/tools/icons/README.md @@ -0,0 +1,30 @@ +How to recolor icons for doc.qt.io +================================== + +You can view Qt Documentation online at https://doc.qt.io in dark and light +modes. To make the icons you use in the docs visible in both modes, save icon +files as gray-scale images with a transparent background. + +If you receive a large number of icons that are not visible in either light +or dark mode or have a solid background, run the ``recolordocsicons.py`` +Python script. + +## Running the script + +By default, the script recolors icons in `qtcreator/doc/qtcreator/images/icons`. + +Use the `-docspath` option to specify the path to another icon source folder. + +For example, if you saved the new icons in `C:\iconconversions`, switch to +the `qtcreator\src\tools\icons` folder and enter: + +`recolordocsicons.py -docspath C:\iconconversions` + +## Preparation + +To run the script, you will need to install the following tools and add them +to the PATH: + +- Python 3.x (the script has been tested to work with 3.10) +- ImageMagick +- optipng From 458beb85826d163d8ea1a5bc1366b9e2a392157c Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 20 Nov 2023 10:13:39 +0100 Subject: [PATCH 0281/1546] QmlDesigner: Hot fix for settings crash Change-Id: I05d27fb2dee65c50191e7dcd7c7bf8f195bb46e5 Reviewed-by: hjk Reviewed-by: Eike Ziller --- src/plugins/qmldesigner/designmodewidget.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/plugins/qmldesigner/designmodewidget.cpp b/src/plugins/qmldesigner/designmodewidget.cpp index 1387f42f9c9..04be9afc5d2 100644 --- a/src/plugins/qmldesigner/designmodewidget.cpp +++ b/src/plugins/qmldesigner/designmodewidget.cpp @@ -568,6 +568,9 @@ void DesignModeWidget::setMinimumSizeHintFromContentMinimumSize(bool value) m_minimumSizeHintMode = newMode; + if (!m_dockManager) + return; + const auto &dockWidgets = m_dockManager->dockWidgetsMap(); for (auto dockWidget : dockWidgets) dockWidget->setMinimumSizeHintMode(m_minimumSizeHintMode); From 01cecddce7332f4e8f74a7ea5ea2c5f09b91d376 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 11:09:40 +0100 Subject: [PATCH 0282/1546] FakeVim: Fix warning about unused lambda capture Change-Id: I136f52002e02611d41a309809408bcde57aceefe Reviewed-by: Jarek Kobus --- src/plugins/fakevim/fakevimplugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp index 5ac5734866a..a46aa2b2555 100644 --- a/src/plugins/fakevim/fakevimplugin.cpp +++ b/src/plugins/fakevim/fakevimplugin.cpp @@ -1630,7 +1630,7 @@ void FakeVimPlugin::editorOpened(IEditor *editor) *on = tew->multiTextCursor().hasMultipleCursors(); }); - handler->simpleCompletionRequested.set([this, handler](const QString &needle, bool forward) { + handler->simpleCompletionRequested.set([handler](const QString &needle, bool forward) { theFakeVimCompletionAssistProvider.setActive(needle, forward, handler); }); @@ -1764,7 +1764,7 @@ void FakeVimPlugin::editorOpened(IEditor *editor) handler->tabPreviousRequested.set([] { triggerAction(Core::Constants::GOTOPREVINHISTORY); }); - handler->completionRequested.set([this, tew] { + handler->completionRequested.set([tew] { if (tew) tew->invokeAssist(Completion, &theFakeVimCompletionAssistProvider); }); From 1dafa53b3bca031e99ddd925e9712723dc4fe323 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 11:26:52 +0100 Subject: [PATCH 0283/1546] ProjectExplorer: Fix a warning er/dependenciespanel.cpp:260:14: warning: private field 'm_project' is not used [-Wunused-private-field] Project *m_project; ^ Amends 0de9d31e84342. Take the opportunity to make the model a proper member to save an indirection. Change-Id: I10b14d54571c6c3960b2ff74522afe2729930630 Reviewed-by: Jarek Kobus --- .../projectexplorer/dependenciespanel.cpp | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/plugins/projectexplorer/dependenciespanel.cpp b/src/plugins/projectexplorer/dependenciespanel.cpp index 3ca788eaf88..97609e57d93 100644 --- a/src/plugins/projectexplorer/dependenciespanel.cpp +++ b/src/plugins/projectexplorer/dependenciespanel.cpp @@ -29,7 +29,18 @@ namespace ProjectExplorer::Internal { class DependenciesModel : public QAbstractListModel { public: - explicit DependenciesModel(Project *project, QObject *parent = nullptr); + explicit DependenciesModel(Project *project) + : m_project(project) + { + resetModel(); + + connect(ProjectManager::instance(), &ProjectManager::projectRemoved, + this, &DependenciesModel::resetModel); + connect(ProjectManager::instance(), &ProjectManager::projectAdded, + this, &DependenciesModel::resetModel); + connect(Core::SessionManager::instance(), &Core::SessionManager::sessionLoaded, + this, &DependenciesModel::resetModel); + } int rowCount(const QModelIndex &index) const override; int columnCount(const QModelIndex &index) const override; @@ -44,20 +55,6 @@ private: QList m_projects; }; -DependenciesModel::DependenciesModel(Project *project, QObject *parent) - : QAbstractListModel(parent) - , m_project(project) -{ - resetModel(); - - connect(ProjectManager::instance(), &ProjectManager::projectRemoved, - this, &DependenciesModel::resetModel); - connect(ProjectManager::instance(), &ProjectManager::projectAdded, - this, &DependenciesModel::resetModel); - connect(Core::SessionManager::instance(), &Core::SessionManager::sessionLoaded, - this, &DependenciesModel::resetModel); -} - void DependenciesModel::resetModel() { beginResetModel(); @@ -226,8 +223,7 @@ class DependenciesWidget : public ProjectSettingsWidget { public: explicit DependenciesWidget(Project *project) - : m_project(project), - m_model(new DependenciesModel(project, this)) + : m_model(project) { setUseGlobalSettingsCheckBoxVisible(false); setUseGlobalSettingsLabelVisible(false); @@ -242,7 +238,7 @@ public: auto layout = new QGridLayout(detailsWidget); layout->setContentsMargins(0, -1, 0, -1); auto treeView = new DependenciesView(this); - treeView->setModel(m_model); + treeView->setModel(&m_model); treeView->setHeaderHidden(true); layout->addWidget(treeView, 0 ,0); layout->addItem(new QSpacerItem(0, 0 , QSizePolicy::Expanding, QSizePolicy::Fixed), 0, 1); @@ -257,8 +253,7 @@ public: } private: - Project *m_project; - DependenciesModel *m_model; + DependenciesModel m_model; Utils::DetailsWidget *m_detailsContainer; QCheckBox *m_cascadeSetActiveCheckBox; }; From f163a4f9a194abeb10021a6d6706275d57b01261 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 17 Nov 2023 12:31:43 +0100 Subject: [PATCH 0284/1546] TextEditor: Move more code out of RefactoringChanges The only callers are in RefactoringFile, so put the functions there. Change-Id: I94141d759d32c20a334804e98dfeb262e10c5e11 Reviewed-by: Qt CI Bot Reviewed-by: David Schulz --- src/plugins/texteditor/refactoringchanges.cpp | 84 +++++++++---------- src/plugins/texteditor/refactoringchanges.h | 18 ++-- 2 files changed, 45 insertions(+), 57 deletions(-) diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp index 4391822d9c4..cfbfe58d3b5 100644 --- a/src/plugins/texteditor/refactoringchanges.cpp +++ b/src/plugins/texteditor/refactoringchanges.cpp @@ -28,23 +28,6 @@ namespace TextEditor { RefactoringChanges::~RefactoringChanges() = default; -RefactoringSelections RefactoringChanges::rangesToSelections(QTextDocument *document, - const QList &ranges) -{ - RefactoringSelections selections; - - for (const Range &range : ranges) { - QTextCursor start(document); - start.setPosition(range.start); - start.setKeepPositionOnInsert(true); - QTextCursor end(document); - end.setPosition(qMin(range.end, document->characterCount() - 1)); - selections.push_back({start, end}); - } - - return selections; -} - bool RefactoringChanges::createFile(const FilePath &filePath, const QString &contents, bool reindent, @@ -53,25 +36,6 @@ bool RefactoringChanges::createFile(const FilePath &filePath, return file(filePath)->create(contents, reindent, openEditor); } -TextEditorWidget *RefactoringChanges::openEditor(const FilePath &filePath, - bool activate, - int line, - int column) -{ - EditorManager::OpenEditorFlags flags = EditorManager::IgnoreNavigationHistory; - if (activate) - flags |= EditorManager::SwitchSplitIfAlreadyVisible; - else - flags |= EditorManager::DoNotChangeCurrentEditor; - if (line != -1) { - // openEditorAt uses a 1-based line and a 0-based column! - column -= 1; - } - IEditor *editor = EditorManager::openEditorAt(Link{filePath, line, column}, Id(), flags); - - return TextEditorWidget::fromEditor(editor); -} - RefactoringFilePtr RefactoringChanges::file(const FilePath &filePath) const { return RefactoringFilePtr(new RefactoringFile(filePath)); @@ -97,7 +61,7 @@ RefactoringFile::RefactoringFile(const FilePath &filePath) : m_filePath(filePath } } -bool RefactoringFile::create(const QString &contents, bool reindent, bool openEditor) +bool RefactoringFile::create(const QString &contents, bool reindent, bool openInEditor) { if (m_filePath.isEmpty() || m_filePath.exists() || m_editor) return false; @@ -126,8 +90,8 @@ bool RefactoringFile::create(const QString &contents, bool reindent, bool openEd fileChanged(); - if (openEditor) - RefactoringChanges::openEditor(m_filePath, /*bool activate =*/ false, -1, -1); + if (openInEditor) + openEditor(/*bool activate =*/ false, -1, -1); return true; } @@ -290,7 +254,7 @@ bool RefactoringFile::apply() lineAndColumn(m_editorCursorPosition, &line, &column); ensureCursorVisible = true; } - m_editor = RefactoringChanges::openEditor(m_filePath, m_activateEditor, line, column); + m_editor = openEditor(m_activateEditor, line, column); m_openEditor = false; m_activateEditor = false; m_editorCursorPosition = -1; @@ -313,11 +277,10 @@ bool RefactoringFile::apply() sort(m_reindentRanges); // build indent selections now, applying the changeset will change locations - const RefactoringSelections &indentSelections = - RefactoringChanges::rangesToSelections(doc, m_indentRanges); + const RefactoringSelections &indentSelections = rangesToSelections(doc, m_indentRanges); m_indentRanges.clear(); - const RefactoringSelections &reindentSelections = - RefactoringChanges::rangesToSelections(doc, m_reindentRanges); + const RefactoringSelections &reindentSelections + = rangesToSelections(doc, m_reindentRanges); m_reindentRanges.clear(); // apply changes @@ -486,4 +449,37 @@ void RefactoringFile::reindentSelection(const QTextCursor &selection, Q_UNUSED(textDocument) } +TextEditorWidget *RefactoringFile::openEditor(bool activate, int line, int column) +{ + EditorManager::OpenEditorFlags flags = EditorManager::IgnoreNavigationHistory; + if (activate) + flags |= EditorManager::SwitchSplitIfAlreadyVisible; + else + flags |= EditorManager::DoNotChangeCurrentEditor; + if (line != -1) { + // openEditorAt uses a 1-based line and a 0-based column! + column -= 1; + } + IEditor *editor = EditorManager::openEditorAt(Link{m_filePath, line, column}, Id(), flags); + + return TextEditorWidget::fromEditor(editor); +} + +RefactoringSelections RefactoringFile::rangesToSelections(QTextDocument *document, + const QList &ranges) +{ + RefactoringSelections selections; + + for (const Range &range : ranges) { + QTextCursor start(document); + start.setPosition(range.start); + start.setKeepPositionOnInsert(true); + QTextCursor end(document); + end.setPosition(qMin(range.end, document->characterCount() - 1)); + selections.push_back({start, end}); + } + + return selections; +} + } // namespace TextEditor diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h index 85489563087..107051f00a5 100644 --- a/src/plugins/texteditor/refactoringchanges.h +++ b/src/plugins/texteditor/refactoringchanges.h @@ -59,7 +59,7 @@ public: void appendReindentRange(const Range &range); void setOpenEditor(bool activate = false, int pos = -1); bool apply(); - bool create(const QString &contents, bool reindent, bool openEditor); + bool create(const QString &contents, bool reindent, bool openInEditor); protected: // users may only get const access to RefactoringFiles created through @@ -80,6 +80,10 @@ protected: void setupFormattingRanges(const QList &replaceList); void doFormatting(); + TextEditorWidget *openEditor(bool activate, int line, int column); + static RefactoringSelections rangesToSelections(QTextDocument *document, + const QList &ranges); + virtual void indentSelection(const QTextCursor &selection, const TextDocument *textDocument) const; virtual void reindentSelection(const QTextCursor &selection, @@ -109,8 +113,6 @@ protected: class TEXTEDITOR_EXPORT RefactoringChanges { public: - using Range = Utils::ChangeSet::Range; - virtual ~RefactoringChanges(); // TODO: Make pure virtual and introduce dedicated subclass for generic refactoring, @@ -121,16 +123,6 @@ public: const QString &contents, bool reindent = true, bool openEditor = true) const; - -protected: - static TextEditorWidget *openEditor(const Utils::FilePath &filePath, - bool activate, - int line, - int column); - static RefactoringSelections rangesToSelections(QTextDocument *document, - const QList &ranges); - - friend class RefactoringFile; }; } // namespace TextEditor From 18bbffddb49cbf1b6643db952907005369cc2523 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 10:55:51 +0100 Subject: [PATCH 0285/1546] Proparser: Silence compiler warning /data/dev/creator/src/shared/proparser/proitems.cpp:226:17: warning: variable 'totalLength' set but not used [-Wunused-but-set-variable] int totalLength = sz - startIdx; Change-Id: I64028926c5af69d2692c977d60c233b5404712ed Reviewed-by: Reviewed-by: Christian Stenger --- src/shared/proparser/proitems.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/shared/proparser/proitems.cpp b/src/shared/proparser/proitems.cpp index 4a5108f9253..57b894396f6 100644 --- a/src/shared/proparser/proitems.cpp +++ b/src/shared/proparser/proitems.cpp @@ -223,14 +223,9 @@ ProString &ProString::append(const ProStringList &other, bool *pending, bool ski if (!m_length && sz == startIdx + 1) { *this = other.at(startIdx); } else { - int totalLength = sz - startIdx; - for (int i = startIdx; i < sz; ++i) - totalLength += other.at(i).size(); bool putSpace = false; if (pending && !*pending && m_length) putSpace = true; - else - totalLength--; m_string = toQString(); m_offset = 0; From fabef397f9716e8b7fa3892b7c5bddaab5acc19d Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 11:48:11 +0100 Subject: [PATCH 0286/1546] Haskell: Move plugin class definition to .cpp ... and simplify setup a bit. Change-Id: Ic5a36c35c083232cb8df3c7a06aaac46bcef55e0 Reviewed-by: Christian Stenger --- src/plugins/haskell/CMakeLists.txt | 2 +- src/plugins/haskell/haskell.qbs | 2 +- src/plugins/haskell/haskellplugin.cpp | 49 ++++++++++++++------------- src/plugins/haskell/haskellplugin.h | 30 ---------------- 4 files changed, 28 insertions(+), 55 deletions(-) delete mode 100644 src/plugins/haskell/haskellplugin.h diff --git a/src/plugins/haskell/CMakeLists.txt b/src/plugins/haskell/CMakeLists.txt index d45326695cb..6cd82f1109b 100644 --- a/src/plugins/haskell/CMakeLists.txt +++ b/src/plugins/haskell/CMakeLists.txt @@ -9,7 +9,7 @@ add_qtc_plugin(Haskell haskelleditorfactory.cpp haskelleditorfactory.h haskellhighlighter.cpp haskellhighlighter.h haskellmanager.cpp haskellmanager.h - haskellplugin.cpp haskellplugin.h + haskellplugin.cpp haskellproject.cpp haskellproject.h haskellrunconfiguration.cpp haskellrunconfiguration.h haskellsettings.cpp haskellsettings.h diff --git a/src/plugins/haskell/haskell.qbs b/src/plugins/haskell/haskell.qbs index 5c1be115387..d1362f32b11 100644 --- a/src/plugins/haskell/haskell.qbs +++ b/src/plugins/haskell/haskell.qbs @@ -18,7 +18,7 @@ QtcPlugin { "haskell_global.h", "haskellhighlighter.cpp", "haskellhighlighter.h", "haskellmanager.cpp", "haskellmanager.h", - "haskellplugin.cpp", "haskellplugin.h", + "haskellplugin.cpp", "haskellproject.cpp", "haskellproject.h", "haskellrunconfiguration.cpp", "haskellrunconfiguration.h", "haskellsettings.cpp", "haskellsettings.h", diff --git a/src/plugins/haskell/haskellplugin.cpp b/src/plugins/haskell/haskellplugin.cpp index 9c082c67a9e..80039b96b21 100644 --- a/src/plugins/haskell/haskellplugin.cpp +++ b/src/plugins/haskell/haskellplugin.cpp @@ -1,8 +1,6 @@ // Copyright (c) 2017 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "haskellplugin.h" - #include "haskellbuildconfiguration.h" #include "haskellconstants.h" #include "haskelleditorfactory.h" @@ -16,6 +14,8 @@ #include #include +#include + #include #include #include @@ -24,8 +24,7 @@ #include -namespace Haskell { -namespace Internal { +namespace Haskell::Internal { class HaskellPluginPrivate { @@ -37,11 +36,6 @@ public: ProjectExplorer::SimpleTargetRunnerFactory runWorkerFactory{{Constants::C_HASKELL_RUNCONFIG_ID}}; }; -HaskellPlugin::~HaskellPlugin() -{ - delete d; -} - static void registerGhciAction(QObject *guard) { QAction *action = new QAction(Tr::tr("Run GHCi"), guard); @@ -52,23 +46,32 @@ static void registerGhciAction(QObject *guard) }); } -bool HaskellPlugin::initialize(const QStringList &arguments, QString *errorString) +class HaskellPlugin final : public ExtensionSystem::IPlugin { - Q_UNUSED(arguments) - Q_UNUSED(errorString) + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Haskell.json") - d = new HaskellPluginPrivate; +public: + ~HaskellPlugin() final { delete d; } - ProjectExplorer::ProjectManager::registerProjectType( - Constants::C_HASKELL_PROJECT_MIMETYPE); - TextEditor::SnippetProvider::registerGroup(Constants::C_HASKELLSNIPPETSGROUP_ID, - Tr::tr("Haskell", "SnippetProvider")); +private: + void initialize() final + { + d = new HaskellPluginPrivate; - registerGhciAction(this); + ProjectExplorer::ProjectManager::registerProjectType( + Constants::C_HASKELL_PROJECT_MIMETYPE); + TextEditor::SnippetProvider::registerGroup(Constants::C_HASKELLSNIPPETSGROUP_ID, + Tr::tr("Haskell", "SnippetProvider")); - ProjectExplorer::JsonWizardFactory::addWizardPath(":/haskell/share/wizards/"); - return true; -} + registerGhciAction(this); -} // namespace Internal -} // namespace Haskell + ProjectExplorer::JsonWizardFactory::addWizardPath(":/haskell/share/wizards/"); + } + + HaskellPluginPrivate *d = nullptr; +}; + +} // Haskell::Internal + +#include "haskellplugin.moc" diff --git a/src/plugins/haskell/haskellplugin.h b/src/plugins/haskell/haskellplugin.h deleted file mode 100644 index acae0d2001a..00000000000 --- a/src/plugins/haskell/haskellplugin.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2017 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include "haskell_global.h" - -#include - -namespace Haskell { -namespace Internal { - -class HaskellPlugin : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Haskell.json") - -public: - HaskellPlugin() = default; - ~HaskellPlugin() final; - -private: - bool initialize(const QStringList &arguments, QString *errorString) final; - void extensionsInitialized() final {} - - class HaskellPluginPrivate *d = nullptr; -}; - -} // namespace Internal -} // namespace Haskell From e7073421cc4d336a940540ed44d1a219b2b83a70 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 17 Nov 2023 12:36:19 +0100 Subject: [PATCH 0287/1546] TextEditor: Remove RefactoringChanges::createFile() Dissolve into only caller. Change-Id: I2eaac8bf31c0ecd2dfb863b7fae79af557ccad95 Reviewed-by: David Schulz --- src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp | 2 +- src/plugins/texteditor/refactoringchanges.cpp | 8 -------- src/plugins/texteditor/refactoringchanges.h | 5 ----- 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp index 97eff5c1e6b..41fa6df2924 100644 --- a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp +++ b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp @@ -166,7 +166,7 @@ public: const bool reindent = true; const bool openEditor = false; const Utils::FilePath newFilePath = newFileName; - if (!refactoring.createFile(newFileName, newComponentSource, reindent, openEditor)) + if (!refactoring.file(newFileName)->create(newComponentSource, reindent, openEditor)) return; if (path.toString() == currentFileName.toFileInfo().path()) { diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp index cfbfe58d3b5..cd0b12c080a 100644 --- a/src/plugins/texteditor/refactoringchanges.cpp +++ b/src/plugins/texteditor/refactoringchanges.cpp @@ -28,14 +28,6 @@ namespace TextEditor { RefactoringChanges::~RefactoringChanges() = default; -bool RefactoringChanges::createFile(const FilePath &filePath, - const QString &contents, - bool reindent, - bool openEditor) const -{ - return file(filePath)->create(contents, reindent, openEditor); -} - RefactoringFilePtr RefactoringChanges::file(const FilePath &filePath) const { return RefactoringFilePtr(new RefactoringFile(filePath)); diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h index 107051f00a5..5168a58b8d3 100644 --- a/src/plugins/texteditor/refactoringchanges.h +++ b/src/plugins/texteditor/refactoringchanges.h @@ -118,11 +118,6 @@ public: // TODO: Make pure virtual and introduce dedicated subclass for generic refactoring, // so no one instantiates this one by mistake. virtual RefactoringFilePtr file(const Utils::FilePath &filePath) const; - - bool createFile(const Utils::FilePath &filePath, - const QString &contents, - bool reindent = true, - bool openEditor = true) const; }; } // namespace TextEditor From 78b9edd2510cd54c50d7fa2dc7274c5134b85225 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 17 Nov 2023 12:44:49 +0100 Subject: [PATCH 0288/1546] TextEditor: Rename class RefactoringChanges ... and remove outdated comment. Change-Id: I6dcd0a38608192ccdd6734affd33e170d39e8299 Reviewed-by: David Schulz --- src/plugins/clangcodemodel/clangfixitoperation.cpp | 2 +- src/plugins/clangcodemodel/clangfixitoperation.h | 5 +---- src/plugins/clangtools/documentquickfixfactory.cpp | 2 +- src/plugins/cppeditor/cppmodelmanager.cpp | 2 +- src/plugins/cppeditor/cpprefactoringchanges.h | 2 +- src/plugins/languageclient/client.cpp | 2 +- src/plugins/qmljseditor/qmljsquickfix.cpp | 2 +- src/plugins/qmljstools/qmljsrefactoringchanges.h | 2 +- src/plugins/texteditor/basefilefind.cpp | 2 +- src/plugins/texteditor/refactoringchanges.cpp | 4 ++-- src/plugins/texteditor/refactoringchanges.h | 12 ++++-------- src/plugins/texteditor/textdocument.cpp | 2 +- 12 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/plugins/clangcodemodel/clangfixitoperation.cpp b/src/plugins/clangcodemodel/clangfixitoperation.cpp index 6f948e6af59..a05d1898870 100644 --- a/src/plugins/clangcodemodel/clangfixitoperation.cpp +++ b/src/plugins/clangcodemodel/clangfixitoperation.cpp @@ -46,7 +46,7 @@ static FileToFixits fixitsPerFile(const QList &fixIts) void ClangFixItOperation::perform() { - const TextEditor::RefactoringChanges refactoringChanges; + const TextEditor::RefactoringFileFactory refactoringChanges; const FileToFixits fileToFixIts = fixitsPerFile(fixIts); for (auto i = fileToFixIts.cbegin(), end = fileToFixIts.cend(); i != end; ++i) { diff --git a/src/plugins/clangcodemodel/clangfixitoperation.h b/src/plugins/clangcodemodel/clangfixitoperation.h index 140952e92fc..cc1fe7bab36 100644 --- a/src/plugins/clangcodemodel/clangfixitoperation.h +++ b/src/plugins/clangcodemodel/clangfixitoperation.h @@ -12,10 +12,7 @@ #include #include -namespace TextEditor { -class RefactoringChanges; -class RefactoringFile; -} +namespace TextEditor { class RefactoringFile; } namespace ClangCodeModel { namespace Internal { diff --git a/src/plugins/clangtools/documentquickfixfactory.cpp b/src/plugins/clangtools/documentquickfixfactory.cpp index e9807a8bcba..e737b3af6e7 100644 --- a/src/plugins/clangtools/documentquickfixfactory.cpp +++ b/src/plugins/clangtools/documentquickfixfactory.cpp @@ -41,7 +41,7 @@ static Range toRange(const QTextDocument *doc, DiagnosticRange locations) void ClangToolQuickFixOperation::perform() { - TextEditor::RefactoringChanges changes; + TextEditor::RefactoringFileFactory changes; QMap refactoringFiles; for (const ExplainingStep &step : m_diagnostic.explainingSteps) { diff --git a/src/plugins/cppeditor/cppmodelmanager.cpp b/src/plugins/cppeditor/cppmodelmanager.cpp index 7ff5a2522f4..2ed1177388f 100644 --- a/src/plugins/cppeditor/cppmodelmanager.cpp +++ b/src/plugins/cppeditor/cppmodelmanager.cpp @@ -1839,7 +1839,7 @@ void CppModelManager::renameIncludes(const FilePath &oldFilePath, const FilePath if (oldFilePath.absolutePath() != newFilePath.absolutePath()) return; - const TextEditor::RefactoringChanges changes; + const TextEditor::RefactoringFileFactory changes; QString oldFileName = oldFilePath.fileName(); QString newFileName = newFilePath.fileName(); diff --git a/src/plugins/cppeditor/cpprefactoringchanges.h b/src/plugins/cppeditor/cpprefactoringchanges.h index cdff9f30eb4..05539d940ab 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.h +++ b/src/plugins/cppeditor/cpprefactoringchanges.h @@ -81,7 +81,7 @@ public: WorkingCopy m_workingCopy; }; -class CPPEDITOR_EXPORT CppRefactoringChanges: public TextEditor::RefactoringChanges +class CPPEDITOR_EXPORT CppRefactoringChanges: public TextEditor::RefactoringFileFactory { public: explicit CppRefactoringChanges(const CPlusPlus::Snapshot &snapshot); diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index c5b822aef67..49779f16462 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -1739,7 +1739,7 @@ void Client::log(const QString &message) const TextEditor::RefactoringFilePtr Client::createRefactoringFile(const FilePath &filePath) const { - return TextEditor::RefactoringChanges().file(filePath); + return TextEditor::RefactoringFileFactory().file(filePath); } void Client::setCompletionResultsLimit(int limit) diff --git a/src/plugins/qmljseditor/qmljsquickfix.cpp b/src/plugins/qmljseditor/qmljsquickfix.cpp index 6614c37ad37..e260c2bb8a6 100644 --- a/src/plugins/qmljseditor/qmljsquickfix.cpp +++ b/src/plugins/qmljseditor/qmljsquickfix.cpp @@ -15,7 +15,7 @@ using namespace QmlJS; using namespace QmlJS::AST; using namespace QmlJSTools; -using TextEditor::RefactoringChanges; +using TextEditor::RefactoringFileFactory; namespace QmlJSEditor { diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.h b/src/plugins/qmljstools/qmljsrefactoringchanges.h index 71db46a7c5a..56051d4dfa3 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.h +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.h @@ -52,7 +52,7 @@ private: }; -class QMLJSTOOLS_EXPORT QmlJSRefactoringChanges: public TextEditor::RefactoringChanges +class QMLJSTOOLS_EXPORT QmlJSRefactoringChanges: public TextEditor::RefactoringFileFactory { public: QmlJSRefactoringChanges(QmlJS::ModelManagerInterface *modelManager, diff --git a/src/plugins/texteditor/basefilefind.cpp b/src/plugins/texteditor/basefilefind.cpp index 8ddadeb7c7e..b6ef9b4ff5a 100644 --- a/src/plugins/texteditor/basefilefind.cpp +++ b/src/plugins/texteditor/basefilefind.cpp @@ -539,7 +539,7 @@ FilePaths BaseFileFind::replaceAll(const QString &text, const SearchResultItems if (items.isEmpty()) return {}; - RefactoringChanges refactoring; + RefactoringFileFactory refactoring; QHash changes; for (const SearchResultItem &item : items) diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp index cd0b12c080a..8287ee09c17 100644 --- a/src/plugins/texteditor/refactoringchanges.cpp +++ b/src/plugins/texteditor/refactoringchanges.cpp @@ -26,9 +26,9 @@ using namespace Utils; namespace TextEditor { -RefactoringChanges::~RefactoringChanges() = default; +RefactoringFileFactory::~RefactoringFileFactory() = default; -RefactoringFilePtr RefactoringChanges::file(const FilePath &filePath) const +RefactoringFilePtr RefactoringFileFactory::file(const FilePath &filePath) const { return RefactoringFilePtr(new RefactoringFile(filePath)); } diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h index 5168a58b8d3..43e3524a2d3 100644 --- a/src/plugins/texteditor/refactoringchanges.h +++ b/src/plugins/texteditor/refactoringchanges.h @@ -22,9 +22,9 @@ QT_END_NAMESPACE namespace TextEditor { class TextDocument; class TextEditorWidget; -class RefactoringChanges; class RefactoringFile; using RefactoringFilePtr = QSharedPointer; +class RefactoringFileFactory; using RefactoringSelections = QVector>; // ### listen to the m_editor::destroyed signal? @@ -103,17 +103,13 @@ protected: bool m_appliedOnce = false; bool m_formattingEnabled = false; - friend class RefactoringChanges; // access to constructor + friend class RefactoringFileFactory; // access to constructor }; - /*! - This class batches changes to multiple file, which are applied as a single big - change. - */ -class TEXTEDITOR_EXPORT RefactoringChanges +class TEXTEDITOR_EXPORT RefactoringFileFactory { public: - virtual ~RefactoringChanges(); + virtual ~RefactoringFileFactory(); // TODO: Make pure virtual and introduce dedicated subclass for generic refactoring, // so no one instantiates this one by mistake. diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp index 2a133673afd..4276c81ad71 100644 --- a/src/plugins/texteditor/textdocument.cpp +++ b/src/plugins/texteditor/textdocument.cpp @@ -514,7 +514,7 @@ bool TextDocument::applyChangeSet(const ChangeSet &changeSet) { if (changeSet.isEmpty()) return true; - RefactoringChanges changes; + RefactoringFileFactory changes; const RefactoringFilePtr file = changes.file(filePath()); file->setChangeSet(changeSet); return file->apply(); From cf74409bac2dbc58204ef85d1ba13916f76a7093 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 17 Nov 2023 12:56:27 +0100 Subject: [PATCH 0289/1546] TextEditor: Introduce PlainRefactoringFileFactory This makes it immediately clear that there are more specialized variants available, which helps users make a conscious decision. Change-Id: I35feb4bed2d91fb4f83ede6e731d9ce89fd4af3f Reviewed-by: David Schulz --- .../clangcodemodel/clangfixitoperation.cpp | 2 +- .../clangtools/documentquickfixfactory.cpp | 2 +- src/plugins/cppeditor/cppmodelmanager.cpp | 2 +- src/plugins/languageclient/client.cpp | 2 +- src/plugins/texteditor/basefilefind.cpp | 2 +- src/plugins/texteditor/refactoringchanges.cpp | 14 +++++++------- src/plugins/texteditor/refactoringchanges.h | 17 ++++++++++------- src/plugins/texteditor/textdocument.cpp | 2 +- 8 files changed, 23 insertions(+), 20 deletions(-) diff --git a/src/plugins/clangcodemodel/clangfixitoperation.cpp b/src/plugins/clangcodemodel/clangfixitoperation.cpp index a05d1898870..b303a755e51 100644 --- a/src/plugins/clangcodemodel/clangfixitoperation.cpp +++ b/src/plugins/clangcodemodel/clangfixitoperation.cpp @@ -46,7 +46,7 @@ static FileToFixits fixitsPerFile(const QList &fixIts) void ClangFixItOperation::perform() { - const TextEditor::RefactoringFileFactory refactoringChanges; + const TextEditor::PlainRefactoringFileFactory refactoringChanges; const FileToFixits fileToFixIts = fixitsPerFile(fixIts); for (auto i = fileToFixIts.cbegin(), end = fileToFixIts.cend(); i != end; ++i) { diff --git a/src/plugins/clangtools/documentquickfixfactory.cpp b/src/plugins/clangtools/documentquickfixfactory.cpp index e737b3af6e7..41a570126f1 100644 --- a/src/plugins/clangtools/documentquickfixfactory.cpp +++ b/src/plugins/clangtools/documentquickfixfactory.cpp @@ -41,7 +41,7 @@ static Range toRange(const QTextDocument *doc, DiagnosticRange locations) void ClangToolQuickFixOperation::perform() { - TextEditor::RefactoringFileFactory changes; + TextEditor::PlainRefactoringFileFactory changes; QMap refactoringFiles; for (const ExplainingStep &step : m_diagnostic.explainingSteps) { diff --git a/src/plugins/cppeditor/cppmodelmanager.cpp b/src/plugins/cppeditor/cppmodelmanager.cpp index 2ed1177388f..2aa13841f96 100644 --- a/src/plugins/cppeditor/cppmodelmanager.cpp +++ b/src/plugins/cppeditor/cppmodelmanager.cpp @@ -1839,7 +1839,7 @@ void CppModelManager::renameIncludes(const FilePath &oldFilePath, const FilePath if (oldFilePath.absolutePath() != newFilePath.absolutePath()) return; - const TextEditor::RefactoringFileFactory changes; + const TextEditor::PlainRefactoringFileFactory changes; QString oldFileName = oldFilePath.fileName(); QString newFileName = newFilePath.fileName(); diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index 49779f16462..912bb622281 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -1739,7 +1739,7 @@ void Client::log(const QString &message) const TextEditor::RefactoringFilePtr Client::createRefactoringFile(const FilePath &filePath) const { - return TextEditor::RefactoringFileFactory().file(filePath); + return TextEditor::PlainRefactoringFileFactory().file(filePath); } void Client::setCompletionResultsLimit(int limit) diff --git a/src/plugins/texteditor/basefilefind.cpp b/src/plugins/texteditor/basefilefind.cpp index b6ef9b4ff5a..399e275fe4f 100644 --- a/src/plugins/texteditor/basefilefind.cpp +++ b/src/plugins/texteditor/basefilefind.cpp @@ -539,7 +539,7 @@ FilePaths BaseFileFind::replaceAll(const QString &text, const SearchResultItems if (items.isEmpty()) return {}; - RefactoringFileFactory refactoring; + PlainRefactoringFileFactory refactoring; QHash changes; for (const SearchResultItem &item : items) diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp index 8287ee09c17..88a2366a8d9 100644 --- a/src/plugins/texteditor/refactoringchanges.cpp +++ b/src/plugins/texteditor/refactoringchanges.cpp @@ -26,13 +26,6 @@ using namespace Utils; namespace TextEditor { -RefactoringFileFactory::~RefactoringFileFactory() = default; - -RefactoringFilePtr RefactoringFileFactory::file(const FilePath &filePath) const -{ - return RefactoringFilePtr(new RefactoringFile(filePath)); -} - RefactoringFile::RefactoringFile(QTextDocument *document, const FilePath &filePath) : m_filePath(filePath) , m_document(document) @@ -474,4 +467,11 @@ RefactoringSelections RefactoringFile::rangesToSelections(QTextDocument *documen return selections; } +RefactoringFileFactory::~RefactoringFileFactory() = default; + +RefactoringFilePtr PlainRefactoringFileFactory::file(const Utils::FilePath &filePath) const +{ + return RefactoringFilePtr(new RefactoringFile(filePath)); +} + } // namespace TextEditor diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h index 43e3524a2d3..5d270b2f652 100644 --- a/src/plugins/texteditor/refactoringchanges.h +++ b/src/plugins/texteditor/refactoringchanges.h @@ -20,12 +20,12 @@ class QTextDocument; QT_END_NAMESPACE namespace TextEditor { -class TextDocument; -class TextEditorWidget; +class PlainRefactoringFileFactory; class RefactoringFile; using RefactoringFilePtr = QSharedPointer; -class RefactoringFileFactory; using RefactoringSelections = QVector>; +class TextDocument; +class TextEditorWidget; // ### listen to the m_editor::destroyed signal? class TEXTEDITOR_EXPORT RefactoringFile @@ -103,17 +103,20 @@ protected: bool m_appliedOnce = false; bool m_formattingEnabled = false; - friend class RefactoringFileFactory; // access to constructor + friend class PlainRefactoringFileFactory; // access to constructor }; class TEXTEDITOR_EXPORT RefactoringFileFactory { public: virtual ~RefactoringFileFactory(); + virtual RefactoringFilePtr file(const Utils::FilePath &filePath) const = 0; +}; - // TODO: Make pure virtual and introduce dedicated subclass for generic refactoring, - // so no one instantiates this one by mistake. - virtual RefactoringFilePtr file(const Utils::FilePath &filePath) const; +class TEXTEDITOR_EXPORT PlainRefactoringFileFactory final : public RefactoringFileFactory +{ +public: + RefactoringFilePtr file(const Utils::FilePath &filePath) const override; }; } // namespace TextEditor diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp index 4276c81ad71..be0d1a95774 100644 --- a/src/plugins/texteditor/textdocument.cpp +++ b/src/plugins/texteditor/textdocument.cpp @@ -514,7 +514,7 @@ bool TextDocument::applyChangeSet(const ChangeSet &changeSet) { if (changeSet.isEmpty()) return true; - RefactoringFileFactory changes; + PlainRefactoringFileFactory changes; const RefactoringFilePtr file = changes.file(filePath()); file->setChangeSet(changeSet); return file->apply(); From ac952955a4e6a0471feba28079f38d84b9438a12 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 17 Nov 2023 13:14:13 +0100 Subject: [PATCH 0290/1546] TextEditor: Clean up RefactoringFile interface Change-Id: I1e415b6b51065d16bc49a25118931723b600c00b Reviewed-by: David Schulz Reviewed-by: Qt CI Bot --- .../cppeditor/cpprefactoringchanges.cpp | 8 +++---- .../qmljstools/qmljsrefactoringchanges.cpp | 6 ++--- src/plugins/texteditor/refactoringchanges.h | 23 ++++++++++--------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/plugins/cppeditor/cpprefactoringchanges.cpp b/src/plugins/cppeditor/cpprefactoringchanges.cpp index 7ee709c118f..e0e0249c0ee 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.cpp +++ b/src/plugins/cppeditor/cpprefactoringchanges.cpp @@ -76,19 +76,19 @@ CppRefactoringFile::CppRefactoringFile(const FilePath &filePath, const QSharedPo { const Snapshot &snapshot = data->m_snapshot; m_cppDocument = snapshot.document(filePath); - m_formattingEnabled = true; + enableFormatting(); } CppRefactoringFile::CppRefactoringFile(QTextDocument *document, const FilePath &filePath) : RefactoringFile(document, filePath) { - m_formattingEnabled = true; + enableFormatting(); } CppRefactoringFile::CppRefactoringFile(TextEditor::TextEditorWidget *editor) : RefactoringFile(editor) { - m_formattingEnabled = true; + enableFormatting(); } Document::Ptr CppRefactoringFile::cppDocument() const @@ -235,7 +235,7 @@ const Token &CppRefactoringFile::tokenAt(unsigned index) const void CppRefactoringFile::fileChanged() { - QTC_ASSERT(!m_filePath.isEmpty(), return); + QTC_ASSERT(!filePath().isEmpty(), return); m_cppDocument.clear(); CppModelManager::updateSourceFiles({filePath()}); } diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp index 6d16b1663cc..0e03454250a 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp @@ -61,7 +61,7 @@ QmlJSRefactoringFile::QmlJSRefactoringFile( { // the RefactoringFile is invalid if its not for a file with qml or js code if (ModelManagerInterface::guessLanguageOfFile(filePath) == Dialect::NoLanguage) - m_filePath.clear(); + invalidate(); } QmlJSRefactoringFile::QmlJSRefactoringFile(TextEditor::TextEditorWidget *editor, Document::Ptr document) @@ -69,7 +69,7 @@ QmlJSRefactoringFile::QmlJSRefactoringFile(TextEditor::TextEditorWidget *editor, , m_qmljsDocument(document) { if (document) - m_filePath = document->fileName(); + setFilePath(document->fileName()); // TODO: Is this really a different file path than in the editor? } Document::Ptr QmlJSRefactoringFile::qmljsDocument() const @@ -136,7 +136,7 @@ bool QmlJSRefactoringFile::isCursorOn(SourceLocation loc) const void QmlJSRefactoringFile::fileChanged() { - QTC_ASSERT(!m_filePath.isEmpty(), return); + QTC_ASSERT(!filePath().isEmpty(), return); m_qmljsDocument.clear(); m_data->m_modelManager->updateSourceFiles({filePath()}, true); } diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h index 5d270b2f652..20de8dad87c 100644 --- a/src/plugins/texteditor/refactoringchanges.h +++ b/src/plugins/texteditor/refactoringchanges.h @@ -31,6 +31,7 @@ class TextEditorWidget; class TEXTEDITOR_EXPORT RefactoringFile { Q_DISABLE_COPY(RefactoringFile) + friend class PlainRefactoringFileFactory; // access to constructor public: using Range = Utils::ChangeSet::Range; @@ -39,8 +40,7 @@ public: bool isValid() const; const QTextDocument *document() const; - // mustn't use the cursor to change the document - const QTextCursor cursor() const; + const QTextCursor cursor() const; // mustn't use the cursor to change the document Utils::FilePath filePath() const; TextEditorWidget *editor() const; @@ -69,10 +69,16 @@ protected: RefactoringFile(TextEditorWidget *editor); RefactoringFile(const Utils::FilePath &filePath); - QTextDocument *mutableDocument() const; + void invalidate() { m_filePath.clear(); } + void setFilePath(const Utils::FilePath &filePath) { m_filePath = filePath; } // FIXME: Really necessary? + void enableFormatting() { m_formattingEnabled = true; } - // derived classes may want to clear language specific extra data - virtual void fileChanged() {} +private: + virtual void fileChanged() {} // derived classes may want to clear language specific extra data + virtual void indentSelection(const QTextCursor &selection, + const TextDocument *textDocument) const; + virtual void reindentSelection(const QTextCursor &selection, + const TextDocument *textDocument) const; enum IndentType {Indent, Reindent}; void indentOrReindent(const RefactoringSelections &ranges, IndentType indent); @@ -84,10 +90,7 @@ protected: static RefactoringSelections rangesToSelections(QTextDocument *document, const QList &ranges); - virtual void indentSelection(const QTextCursor &selection, - const TextDocument *textDocument) const; - virtual void reindentSelection(const QTextCursor &selection, - const TextDocument *textDocument) const; + QTextDocument *mutableDocument() const; Utils::FilePath m_filePath; mutable Utils::TextFileFormat m_textFileFormat; @@ -102,8 +105,6 @@ protected: int m_editorCursorPosition = -1; bool m_appliedOnce = false; bool m_formattingEnabled = false; - - friend class PlainRefactoringFileFactory; // access to constructor }; class TEXTEDITOR_EXPORT RefactoringFileFactory From b8c2be4cf83aadc831ab795cee2b39421932f0e1 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 17 Nov 2023 13:26:13 +0100 Subject: [PATCH 0291/1546] CppEditor: Hide CppRefactoringChangesData Change-Id: I5d88651a9b3a295bd95de5ee5e9b117e449195b3 Reviewed-by: David Schulz Reviewed-by: Qt CI Bot --- .../cppeditor/cpprefactoringchanges.cpp | 13 +++++++++++ src/plugins/cppeditor/cpprefactoringchanges.h | 23 +++++-------------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/plugins/cppeditor/cpprefactoringchanges.cpp b/src/plugins/cppeditor/cpprefactoringchanges.cpp index e0e0249c0ee..e15dca72cb8 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.cpp +++ b/src/plugins/cppeditor/cpprefactoringchanges.cpp @@ -4,6 +4,7 @@ #include "cpprefactoringchanges.h" #include "cppeditorconstants.h" +#include "cppworkingcopy.h" #include @@ -22,6 +23,18 @@ using namespace CPlusPlus; using namespace Utils; namespace CppEditor { +namespace Internal { +class CppRefactoringChangesData +{ +public: + explicit CppRefactoringChangesData(const CPlusPlus::Snapshot &snapshot); + + CPlusPlus::Snapshot m_snapshot; + WorkingCopy m_workingCopy; +}; +} // namespace Internal + +using namespace Internal; static std::unique_ptr createIndenter(const FilePath &filePath, QTextDocument *textDocument) diff --git a/src/plugins/cppeditor/cpprefactoringchanges.h b/src/plugins/cppeditor/cpprefactoringchanges.h index 05539d940ab..35e26940de0 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.h +++ b/src/plugins/cppeditor/cpprefactoringchanges.h @@ -6,22 +6,19 @@ #include "cppeditor_global.h" #include "cppmodelmanager.h" -#include "cppworkingcopy.h" #include #include -#include - namespace CppEditor { - class CppRefactoringChanges; class CppRefactoringFile; -class CppRefactoringChangesData; using CppRefactoringFilePtr = QSharedPointer; using CppRefactoringFileConstPtr = QSharedPointer; +namespace Internal { class CppRefactoringChangesData; } + class CPPEDITOR_EXPORT CppRefactoringFile: public TextEditor::RefactoringFile { public: @@ -52,7 +49,8 @@ public: QString textOf(const CPlusPlus::AST *ast) const; private: - CppRefactoringFile(const Utils::FilePath &filePath, const QSharedPointer &data); + CppRefactoringFile(const Utils::FilePath &filePath, + const QSharedPointer &data); CppRefactoringFile(QTextDocument *document, const Utils::FilePath &filePath); explicit CppRefactoringFile(TextEditor::TextEditorWidget *editor); @@ -67,20 +65,11 @@ private: int startIndex) const; mutable CPlusPlus::Document::Ptr m_cppDocument; - QSharedPointer m_data; + QSharedPointer m_data; friend class CppRefactoringChanges; // for access to constructor }; -class CPPEDITOR_EXPORT CppRefactoringChangesData -{ -public: - explicit CppRefactoringChangesData(const CPlusPlus::Snapshot &snapshot); - - CPlusPlus::Snapshot m_snapshot; - WorkingCopy m_workingCopy; -}; - class CPPEDITOR_EXPORT CppRefactoringChanges: public TextEditor::RefactoringFileFactory { public: @@ -98,7 +87,7 @@ public: const CPlusPlus::Snapshot &snapshot() const; private: - const QSharedPointer m_data; + const QSharedPointer m_data; }; } // namespace CppEditor From 4bfc3476f444ad614a6aeba100d85e869ec69b1f Mon Sep 17 00:00:00 2001 From: Artem Sokolovskii Date: Thu, 4 May 2023 14:43:37 +0200 Subject: [PATCH 0292/1546] SyntaxHighlighter: Move highlighter creating to TextDocument Added setSyntaxHighlighterCreator function to TextDocument which allows the creation of highlighters inside TextDocument. Change-Id: I454f800c878c48a154dad5abd68b7a4f9ceb378a Reviewed-by: Jarek Kobus Reviewed-by: --- .../clangformat/clangformatconfigwidget.cpp | 3 +- src/plugins/cppeditor/cppeditordocument.cpp | 2 +- src/plugins/cppeditor/cpptoolsreuse.cpp | 2 +- src/plugins/diffeditor/diffeditor.cpp | 2 +- src/plugins/git/giteditor.cpp | 6 ++-- src/plugins/nim/editor/nimeditorfactory.cpp | 2 +- .../bindingeditor/bindingeditorwidget.cpp | 3 +- src/plugins/qmljseditor/qmljseditor.cpp | 4 +-- .../qmljseditor/qmljseditordocument.cpp | 2 +- src/plugins/texteditor/textdocument.cpp | 5 ++-- src/plugins/texteditor/textdocument.h | 4 ++- src/plugins/texteditor/texteditor.cpp | 28 ++++++++++--------- src/plugins/vcsbase/vcsbaseeditor.cpp | 9 ++++-- 13 files changed, 42 insertions(+), 30 deletions(-) diff --git a/src/plugins/clangformat/clangformatconfigwidget.cpp b/src/plugins/clangformat/clangformatconfigwidget.cpp index e3328bb2695..23916bf00f3 100644 --- a/src/plugins/clangformat/clangformatconfigwidget.cpp +++ b/src/plugins/clangformat/clangformatconfigwidget.cpp @@ -131,7 +131,8 @@ ClangFormatConfigWidget::ClangFormatConfigWidget(TextEditor::ICodeStylePreferenc d->preview->setPlainText(QLatin1String(CppEditor::Constants::DEFAULT_CODE_STYLE_SNIPPETS[0])); d->preview->textDocument()->setIndenter(new ClangFormatIndenter(d->preview->document())); d->preview->textDocument()->setFontSettings(TextEditor::TextEditorSettings::fontSettings()); - d->preview->textDocument()->setSyntaxHighlighter(new CppEditor::CppHighlighter); + d->preview->textDocument()->setSyntaxHighlighterCreator( + [] { return new CppEditor::CppHighlighter(); }); d->preview->textDocument()->indenter()->setFileName(fileName); using namespace Layouting; diff --git a/src/plugins/cppeditor/cppeditordocument.cpp b/src/plugins/cppeditor/cppeditordocument.cpp index 18c729f7778..dfc5af1c889 100644 --- a/src/plugins/cppeditor/cppeditordocument.cpp +++ b/src/plugins/cppeditor/cppeditordocument.cpp @@ -79,7 +79,7 @@ private: CppEditorDocument::CppEditorDocument() { setId(CppEditor::Constants::CPPEDITOR_ID); - setSyntaxHighlighter(new CppHighlighter); + setSyntaxHighlighterCreator([] { return new CppHighlighter(); }); ICodeStylePreferencesFactory *factory = TextEditorSettings::codeStyleFactory(Constants::CPP_SETTINGS_ID); diff --git a/src/plugins/cppeditor/cpptoolsreuse.cpp b/src/plugins/cppeditor/cpptoolsreuse.cpp index 9951eea9ff5..26627b6c66a 100644 --- a/src/plugins/cppeditor/cpptoolsreuse.cpp +++ b/src/plugins/cppeditor/cpptoolsreuse.cpp @@ -854,7 +854,7 @@ namespace Internal { void decorateCppEditor(TextEditor::TextEditorWidget *editor) { - editor->textDocument()->setSyntaxHighlighter(new CppHighlighter); + editor->textDocument()->setSyntaxHighlighterCreator([] { return new CppHighlighter(); }); editor->textDocument()->setIndenter( new CppQtStyleIndenter(editor->textDocument()->document())); editor->setAutoCompleter(new CppAutoCompleter); diff --git a/src/plugins/diffeditor/diffeditor.cpp b/src/plugins/diffeditor/diffeditor.cpp index d202fb4338a..4998dfbd9a0 100644 --- a/src/plugins/diffeditor/diffeditor.cpp +++ b/src/plugins/diffeditor/diffeditor.cpp @@ -93,7 +93,7 @@ DescriptionEditorWidget::DescriptionEditorWidget(QWidget *parent) context->setContext(Context(Constants::C_DIFF_EDITOR_DESCRIPTION)); ICore::addContextObject(context); - textDocument()->setSyntaxHighlighter(new SyntaxHighlighter); + textDocument()->setSyntaxHighlighterCreator([] { return new SyntaxHighlighter(); }); } QSize DescriptionEditorWidget::sizeHint() const diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp index a8613688ea8..05be7e7a4a4 100644 --- a/src/plugins/git/giteditor.cpp +++ b/src/plugins/git/giteditor.cpp @@ -246,9 +246,11 @@ void GitEditorWidget::init() return; const QChar commentChar = gitClient().commentChar(source()); if (isCommitEditor) - textDocument()->setSyntaxHighlighter(new GitSubmitHighlighter(commentChar)); + textDocument()->setSyntaxHighlighterCreator( + [commentChar] { return new GitSubmitHighlighter(commentChar); }); else if (isRebaseEditor) - textDocument()->setSyntaxHighlighter(new GitRebaseHighlighter(commentChar)); + textDocument()->setSyntaxHighlighterCreator( + [commentChar] { return new GitRebaseHighlighter(commentChar); }); } void GitEditorWidget::addDiffActions(QMenu *menu, const DiffChunk &chunk) diff --git a/src/plugins/nim/editor/nimeditorfactory.cpp b/src/plugins/nim/editor/nimeditorfactory.cpp index 08e0ea2c327..62e49595385 100644 --- a/src/plugins/nim/editor/nimeditorfactory.cpp +++ b/src/plugins/nim/editor/nimeditorfactory.cpp @@ -51,7 +51,7 @@ NimEditorFactory::NimEditorFactory() void NimEditorFactory::decorateEditor(TextEditorWidget *editor) { - editor->textDocument()->setSyntaxHighlighter(new NimHighlighter()); + editor->textDocument()->setSyntaxHighlighterCreator([] { return new NimHighlighter();}); editor->textDocument()->setIndenter(new NimIndenter(editor->textDocument()->document())); } diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp index f0c10d7420a..6f6e3ffaa84 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp @@ -167,7 +167,8 @@ BindingEditorFactory::BindingEditorFactory() void BindingEditorFactory::decorateEditor(TextEditor::TextEditorWidget *editor) { - editor->textDocument()->setSyntaxHighlighter(new QmlJSEditor::QmlJSHighlighter); + editor->textDocument()->setSyntaxHighlighterCreator( + [] { return new QmlJSEditor::QmlJSHighlighter(); }); editor->textDocument()->setIndenter(new QmlJSEditor::Internal::Indenter( editor->textDocument()->document())); editor->setAutoCompleter(new QmlJSEditor::AutoCompleter); diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index d6b132b9700..a590c0fd834 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -743,7 +743,7 @@ void QmlJSEditorWidget::inspectElementUnderCursor() const widget->setReadOnly(true); widget->textDocument()->setTemporary(true); - widget->textDocument()->setSyntaxHighlighter(new QmlJSHighlighter(widget->document())); + widget->textDocument()->setSyntaxHighlighterCreator([] {return new QmlJSHighlighter();}); const QString buf = inspectCppComponent(cppValue); widget->textDocument()->setPlainText(buf); @@ -1160,7 +1160,7 @@ QmlJSEditorFactory::QmlJSEditorFactory(Utils::Id _id) void QmlJSEditorFactory::decorateEditor(TextEditorWidget *editor) { - editor->textDocument()->setSyntaxHighlighter(new QmlJSHighlighter); + editor->textDocument()->setSyntaxHighlighterCreator([] { return new QmlJSHighlighter(); }); editor->textDocument()->setIndenter(new Internal::Indenter(editor->textDocument()->document())); editor->setAutoCompleter(new AutoCompleter); } diff --git a/src/plugins/qmljseditor/qmljseditordocument.cpp b/src/plugins/qmljseditor/qmljseditordocument.cpp index 37f49d08712..5923521ab06 100644 --- a/src/plugins/qmljseditor/qmljseditordocument.cpp +++ b/src/plugins/qmljseditor/qmljseditordocument.cpp @@ -820,7 +820,7 @@ QmlJSEditorDocument::QmlJSEditorDocument(Utils::Id id) d, &Internal::QmlJSEditorDocumentPrivate::invalidateFormatterCache); connect(this, &TextEditor::TextDocument::openFinishedSuccessfully, d, &Internal::QmlJSEditorDocumentPrivate::settingsChanged); - setSyntaxHighlighter(new QmlJSHighlighter(document())); + setSyntaxHighlighterCreator([] { return new QmlJSHighlighter(); }); setCodec(QTextCodec::codecForName("UTF-8")); // qml files are defined to be utf-8 setIndenter(new Internal::Indenter(document())); } diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp index be0d1a95774..2a6f4da0a7c 100644 --- a/src/plugins/texteditor/textdocument.cpp +++ b/src/plugins/texteditor/textdocument.cpp @@ -901,11 +901,12 @@ bool TextDocument::reload(QString *errorString, ReloadFlag flag, ChangeType type return reload(errorString); } -void TextDocument::setSyntaxHighlighter(SyntaxHighlighter *highlighter) +void TextDocument::setSyntaxHighlighterCreator(const SyntaxHighLighterCreator &creator) { if (d->m_highlighter) delete d->m_highlighter; - d->m_highlighter = highlighter; + + d->m_highlighter = creator(); d->m_highlighter->setParent(this); d->m_highlighter->setDocument(&d->m_document); } diff --git a/src/plugins/texteditor/textdocument.h b/src/plugins/texteditor/textdocument.h index a4dd3dd45f0..e05abbdba39 100644 --- a/src/plugins/texteditor/textdocument.h +++ b/src/plugins/texteditor/textdocument.h @@ -124,7 +124,9 @@ public: bool setPlainText(const QString &text); QTextDocument *document() const; - void setSyntaxHighlighter(SyntaxHighlighter *highlighter); + + using SyntaxHighLighterCreator = std::function; + void setSyntaxHighlighterCreator(const SyntaxHighLighterCreator &creator); SyntaxHighlighter *syntaxHighlighter() const; bool reload(QString *errorString, QTextCodec *codec); diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 653bd310ebb..0d433f35c96 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -3690,16 +3690,19 @@ void TextEditorWidgetPrivate::removeSyntaxInfoBar() void TextEditorWidgetPrivate::configureGenericHighlighter( const KSyntaxHighlighting::Definition &definition) { - auto highlighter = new Highlighter(); - m_document->setSyntaxHighlighter(highlighter); - if (definition.isValid()) { - highlighter->setDefinition(definition); setupFromDefinition(definition); } else { q->setCodeFoldingSupported(false); } + m_document->setSyntaxHighlighterCreator([definition] { + auto highlighter = new Highlighter(); + if (definition.isValid()) + highlighter->setDefinition(definition); + return highlighter; + }); + m_document->setFontSettings(TextEditorSettings::fontSettings()); } @@ -6222,8 +6225,7 @@ void TextEditorWidget::mouseReleaseEvent(QMouseEvent *e) if (self && self->openLink(symbolLink, inNextSplit)) self->d->clearLink(); }, true, inNextSplit); - } else if (button == Qt::MiddleButton - && !isReadOnly() + } else if (button == Qt::MiddleButton && !isReadOnly() && QGuiApplication::clipboard()->supportsSelection()) { if (!(e->modifiers() & Qt::AltModifier)) doSetTextCursor(cursorForPosition(e->pos())); @@ -6302,12 +6304,10 @@ void TextEditorWidget::keyReleaseEvent(QKeyEvent *e) { if (e->key() == Qt::Key_Control) { d->clearLink(); - } else if (e->key() == Qt::Key_Shift - && d->m_behaviorSettings.m_constrainHoverTooltips - && ToolTip::isVisible()) { + } else if (e->key() == Qt::Key_Shift && d->m_behaviorSettings.m_constrainHoverTooltips + && ToolTip::isVisible()) { ToolTip::hide(); - } else if (e->key() == Qt::Key_Alt - && d->m_maybeFakeTooltipEvent) { + } else if (e->key() == Qt::Key_Alt && d->m_maybeFakeTooltipEvent) { d->m_maybeFakeTooltipEvent = false; d->processTooltipRequest(textCursor()); } @@ -6912,7 +6912,9 @@ void TextEditorWidget::findTypeAt(const QTextCursor &cursor, bool TextEditorWidget::openLink(const Utils::Link &link, bool inNextSplit) { #ifdef WITH_TESTS - struct Signaller { ~Signaller() { emit EditorManager::instance()->linkOpened(); } } s; + struct Signaller { + ~Signaller() { emit EditorManager::instance()->linkOpened(); } + } s; #endif if (!link.hasValidTarget()) @@ -9442,7 +9444,7 @@ void TextEditorFactory::setEditorCreator(const EditorCreator &creator) doc->setIndenter(d->m_indenterCreator(doc->document())); if (d->m_syntaxHighlighterCreator) - doc->setSyntaxHighlighter(d->m_syntaxHighlighterCreator()); + doc->setSyntaxHighlighterCreator(d->m_syntaxHighlighterCreator); doc->setCompletionAssistProvider(d->m_completionAssistProvider ? d->m_completionAssistProvider : &basicSnippetProvider); diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index 1b6f4811369..bb89b1cd321 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -760,9 +760,11 @@ void VcsBaseEditorWidget::init() break; } if (hasDiff()) { - auto dh = new DiffAndLogHighlighter(d->m_diffFilePattern, d->m_logEntryPattern); setCodeFoldingSupported(true); - textDocument()->setSyntaxHighlighter(dh); + textDocument()->setSyntaxHighlighterCreator( + [diffFilePattern = d->m_diffFilePattern, logEntryPattern = d->m_logEntryPattern] { + return new DiffAndLogHighlighter(diffFilePattern, logEntryPattern); + }); } // override revisions display (green or red bar on the left, marking changes): setRevisionsVisible(false); @@ -1102,7 +1104,8 @@ void VcsBaseEditorWidget::slotActivateAnnotation() ah->setChangeNumbers(changes); ah->rehighlight(); } else { - textDocument()->setSyntaxHighlighter(createAnnotationHighlighter(changes)); + BaseAnnotationHighlighter *highlighter = createAnnotationHighlighter(changes); + textDocument()->setSyntaxHighlighterCreator([highlighter] { return highlighter; }); } } From 52f4c66b7ebf2d15f412edb942b7d185dc34089b Mon Sep 17 00:00:00 2001 From: Artem Sokolovskii Date: Wed, 17 May 2023 10:28:06 +0200 Subject: [PATCH 0293/1546] SyntiaxHighlighter: Move VCS highlighters creating to TextDocument Change-Id: I531b30d31fb630d2292eaf4d8c61ff1e95fed460 Reviewed-by: Jarek Kobus --- src/plugins/bazaar/bazaareditor.cpp | 4 ++-- src/plugins/bazaar/bazaareditor.h | 3 +-- src/plugins/clearcase/clearcaseeditor.cpp | 4 ++-- src/plugins/clearcase/clearcaseeditor.h | 3 +-- src/plugins/cvs/cvseditor.cpp | 4 ++-- src/plugins/cvs/cvseditor.h | 3 +-- src/plugins/fossil/fossileditor.cpp | 5 ++--- src/plugins/fossil/fossileditor.h | 3 +-- src/plugins/git/giteditor.cpp | 4 ++-- src/plugins/git/giteditor.h | 2 +- src/plugins/mercurial/mercurialeditor.cpp | 4 ++-- src/plugins/mercurial/mercurialeditor.h | 3 +-- src/plugins/perforce/perforceeditor.cpp | 4 ++-- src/plugins/perforce/perforceeditor.h | 3 +-- src/plugins/subversion/subversioneditor.cpp | 5 +++-- src/plugins/subversion/subversioneditor.h | 3 +-- src/plugins/vcsbase/vcsbaseeditor.cpp | 4 ++-- src/plugins/vcsbase/vcsbaseeditor.h | 5 ++++- 18 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/plugins/bazaar/bazaareditor.cpp b/src/plugins/bazaar/bazaareditor.cpp index 146b2e71932..305fa8eb8a3 100644 --- a/src/plugins/bazaar/bazaareditor.cpp +++ b/src/plugins/bazaar/bazaareditor.cpp @@ -59,9 +59,9 @@ QString BazaarEditorWidget::changeUnderCursor(const QTextCursor &cursorIn) const return {}; } -VcsBase::BaseAnnotationHighlighter *BazaarEditorWidget::createAnnotationHighlighter(const QSet &changes) const +VcsBase::BaseAnnotationHighlighterCreator BazaarEditorWidget::annotationHighlighterCreator() const { - return new BazaarAnnotationHighlighter(changes); + return [](const QSet &changes) { return new BazaarAnnotationHighlighter(changes); }; } } // Bazaar::Internal diff --git a/src/plugins/bazaar/bazaareditor.h b/src/plugins/bazaar/bazaareditor.h index 4f88d778f1a..2de63e70b4f 100644 --- a/src/plugins/bazaar/bazaareditor.h +++ b/src/plugins/bazaar/bazaareditor.h @@ -16,8 +16,7 @@ public: private: QString changeUnderCursor(const QTextCursor &cursor) const override; - VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter( - const QSet &changes) const override; + VcsBase::BaseAnnotationHighlighterCreator annotationHighlighterCreator() const override; const QRegularExpression m_changesetId; const QRegularExpression m_exactChangesetId; diff --git a/src/plugins/clearcase/clearcaseeditor.cpp b/src/plugins/clearcase/clearcaseeditor.cpp index df3cd3406d8..02b07383585 100644 --- a/src/plugins/clearcase/clearcaseeditor.cpp +++ b/src/plugins/clearcase/clearcaseeditor.cpp @@ -42,9 +42,9 @@ QString ClearCaseEditorWidget::changeUnderCursor(const QTextCursor &c) const return QString(); } -VcsBase::BaseAnnotationHighlighter *ClearCaseEditorWidget::createAnnotationHighlighter(const QSet &changes) const +VcsBase::BaseAnnotationHighlighterCreator ClearCaseEditorWidget::annotationHighlighterCreator() const { - return new ClearCaseAnnotationHighlighter(changes); + return [](const QSet &changes) { return new ClearCaseAnnotationHighlighter(changes); }; } } // ClearCase::Internal diff --git a/src/plugins/clearcase/clearcaseeditor.h b/src/plugins/clearcase/clearcaseeditor.h index 061807a45db..90b7a9c34ec 100644 --- a/src/plugins/clearcase/clearcaseeditor.h +++ b/src/plugins/clearcase/clearcaseeditor.h @@ -18,8 +18,7 @@ public: private: QString changeUnderCursor(const QTextCursor &) const override; - VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter( - const QSet &changes) const override; + VcsBase::BaseAnnotationHighlighterCreator annotationHighlighterCreator() const override; const QRegularExpression m_versionNumberPattern; }; diff --git a/src/plugins/cvs/cvseditor.cpp b/src/plugins/cvs/cvseditor.cpp index d28144e3146..4e0aac6956b 100644 --- a/src/plugins/cvs/cvseditor.cpp +++ b/src/plugins/cvs/cvseditor.cpp @@ -93,9 +93,9 @@ QString CvsEditorWidget::changeUnderCursor(const QTextCursor &c) const return {}; } -VcsBase::BaseAnnotationHighlighter *CvsEditorWidget::createAnnotationHighlighter(const QSet &changes) const +VcsBase::BaseAnnotationHighlighterCreator CvsEditorWidget::annotationHighlighterCreator() const { - return new CvsAnnotationHighlighter(changes); + return [](const QSet &changes) { return new CvsAnnotationHighlighter(changes); }; } QStringList CvsEditorWidget::annotationPreviousVersions(const QString &revision) const diff --git a/src/plugins/cvs/cvseditor.h b/src/plugins/cvs/cvseditor.h index 3e9ed8e639e..37db5222392 100644 --- a/src/plugins/cvs/cvseditor.h +++ b/src/plugins/cvs/cvseditor.h @@ -18,8 +18,7 @@ public: private: QString changeUnderCursor(const QTextCursor &) const override; - VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter( - const QSet &changes) const override; + VcsBase::BaseAnnotationHighlighterCreator annotationHighlighterCreator() const override; QStringList annotationPreviousVersions(const QString &revision) const override; const QRegularExpression m_revisionAnnotationPattern; diff --git a/src/plugins/fossil/fossileditor.cpp b/src/plugins/fossil/fossileditor.cpp index 01fc9e821a5..0b5e5255f34 100644 --- a/src/plugins/fossil/fossileditor.cpp +++ b/src/plugins/fossil/fossileditor.cpp @@ -89,10 +89,9 @@ QStringList FossilEditorWidget::annotationPreviousVersions(const QString &revisi return revisions; } -VcsBase::BaseAnnotationHighlighter *FossilEditorWidget::createAnnotationHighlighter( - const QSet &changes) const +VcsBase::BaseAnnotationHighlighterCreator FossilEditorWidget::annotationHighlighterCreator() const { - return new FossilAnnotationHighlighter(changes); + return [](const QSet &changes) { return new FossilAnnotationHighlighter(changes); }; } } // namespace Fossil::Internal diff --git a/src/plugins/fossil/fossileditor.h b/src/plugins/fossil/fossileditor.h index f2ca97e4418..70b398fc035 100644 --- a/src/plugins/fossil/fossileditor.h +++ b/src/plugins/fossil/fossileditor.h @@ -22,8 +22,7 @@ private: QString changeUnderCursor(const QTextCursor &cursor) const final; QString decorateVersion(const QString &revision) const final; QStringList annotationPreviousVersions(const QString &revision) const final; - VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter( - const QSet &changes) const final; + VcsBase::BaseAnnotationHighlighterCreator annotationHighlighterCreator() const final; FossilEditorWidgetPrivate *d; }; diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp index 05be7e7a4a4..66c3bc01bb7 100644 --- a/src/plugins/git/giteditor.cpp +++ b/src/plugins/git/giteditor.cpp @@ -117,9 +117,9 @@ QString GitEditorWidget::changeUnderCursor(const QTextCursor &c) const return {}; } -BaseAnnotationHighlighter *GitEditorWidget::createAnnotationHighlighter(const QSet &changes) const +VcsBase::BaseAnnotationHighlighterCreator GitEditorWidget::annotationHighlighterCreator() const { - return new GitAnnotationHighlighter(changes); + return [](const QSet &changes) { return new GitAnnotationHighlighter(changes); }; } /* Remove the date specification from annotation, which is tabular: diff --git a/src/plugins/git/giteditor.h b/src/plugins/git/giteditor.h index 23eb4d6ff3a..43fc8b10f54 100644 --- a/src/plugins/git/giteditor.h +++ b/src/plugins/git/giteditor.h @@ -42,7 +42,7 @@ private: void addDiffActions(QMenu *menu, const VcsBase::DiffChunk &chunk) override; void aboutToOpen(const Utils::FilePath &filePath, const Utils::FilePath &realFilePath) override; QString changeUnderCursor(const QTextCursor &) const override; - VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet &changes) const override; + VcsBase::BaseAnnotationHighlighterCreator annotationHighlighterCreator() const override; QString decorateVersion(const QString &revision) const override; QStringList annotationPreviousVersions(const QString &revision) const override; bool isValidRevision(const QString &revision) const override; diff --git a/src/plugins/mercurial/mercurialeditor.cpp b/src/plugins/mercurial/mercurialeditor.cpp index b08802b8d66..63008f19d61 100644 --- a/src/plugins/mercurial/mercurialeditor.cpp +++ b/src/plugins/mercurial/mercurialeditor.cpp @@ -48,9 +48,9 @@ QString MercurialEditorWidget::changeUnderCursor(const QTextCursor &cursorIn) co return {}; } -VcsBase::BaseAnnotationHighlighter *MercurialEditorWidget::createAnnotationHighlighter(const QSet &changes) const +VcsBase::BaseAnnotationHighlighterCreator MercurialEditorWidget::annotationHighlighterCreator() const { - return new MercurialAnnotationHighlighter(changes); + return [](const QSet &changes) { return new MercurialAnnotationHighlighter(changes); }; } QString MercurialEditorWidget::decorateVersion(const QString &revision) const diff --git a/src/plugins/mercurial/mercurialeditor.h b/src/plugins/mercurial/mercurialeditor.h index 9a9cd88aed9..d5162697a27 100644 --- a/src/plugins/mercurial/mercurialeditor.h +++ b/src/plugins/mercurial/mercurialeditor.h @@ -18,8 +18,7 @@ public: private: QString changeUnderCursor(const QTextCursor &cursor) const override; - VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter( - const QSet &changes) const override; + VcsBase::BaseAnnotationHighlighterCreator annotationHighlighterCreator() const override; QString decorateVersion(const QString &revision) const override; QStringList annotationPreviousVersions(const QString &revision) const override; diff --git a/src/plugins/perforce/perforceeditor.cpp b/src/plugins/perforce/perforceeditor.cpp index 623ac1ed8fe..88e790c3c03 100644 --- a/src/plugins/perforce/perforceeditor.cpp +++ b/src/plugins/perforce/perforceeditor.cpp @@ -51,9 +51,9 @@ QString PerforceEditorWidget::changeUnderCursor(const QTextCursor &c) const return m_changeNumberPattern.match(change).hasMatch() ? change : QString(); } -VcsBase::BaseAnnotationHighlighter *PerforceEditorWidget::createAnnotationHighlighter(const QSet &changes) const +VcsBase::BaseAnnotationHighlighterCreator PerforceEditorWidget::annotationHighlighterCreator() const { - return new PerforceAnnotationHighlighter(changes); + return [](const QSet &changes) { return new PerforceAnnotationHighlighter(changes); }; } QString PerforceEditorWidget::findDiffFile(const QString &f) const diff --git a/src/plugins/perforce/perforceeditor.h b/src/plugins/perforce/perforceeditor.h index ce0d05b6871..9ec6ae3b3b6 100644 --- a/src/plugins/perforce/perforceeditor.h +++ b/src/plugins/perforce/perforceeditor.h @@ -18,8 +18,7 @@ public: private: QString changeUnderCursor(const QTextCursor &) const override; - VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter( - const QSet &changes) const override; + VcsBase::BaseAnnotationHighlighterCreator annotationHighlighterCreator() const override; QString findDiffFile(const QString &f) const override; QStringList annotationPreviousVersions(const QString &v) const override; diff --git a/src/plugins/subversion/subversioneditor.cpp b/src/plugins/subversion/subversioneditor.cpp index 4549c6e14da..5e614532d6a 100644 --- a/src/plugins/subversion/subversioneditor.cpp +++ b/src/plugins/subversion/subversioneditor.cpp @@ -75,9 +75,10 @@ QString SubversionEditorWidget::changeUnderCursor(const QTextCursor &c) const return {}; } -VcsBase::BaseAnnotationHighlighter *SubversionEditorWidget::createAnnotationHighlighter(const QSet &changes) const +VcsBase::BaseAnnotationHighlighterCreator SubversionEditorWidget::annotationHighlighterCreator() const { - return new SubversionAnnotationHighlighter(changes); + return + [](const QSet &changes) { return new SubversionAnnotationHighlighter(changes); }; } QStringList SubversionEditorWidget::annotationPreviousVersions(const QString &v) const diff --git a/src/plugins/subversion/subversioneditor.h b/src/plugins/subversion/subversioneditor.h index 5538b396e99..a6443c23836 100644 --- a/src/plugins/subversion/subversioneditor.h +++ b/src/plugins/subversion/subversioneditor.h @@ -19,8 +19,7 @@ public: private: QString changeUnderCursor(const QTextCursor &) const override; - VcsBase::BaseAnnotationHighlighter *createAnnotationHighlighter( - const QSet &changes) const override; + VcsBase::BaseAnnotationHighlighterCreator annotationHighlighterCreator() const override; QStringList annotationPreviousVersions(const QString &) const override; QRegularExpression m_changeNumberPattern; diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index bb89b1cd321..b768c58c974 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -1104,8 +1104,8 @@ void VcsBaseEditorWidget::slotActivateAnnotation() ah->setChangeNumbers(changes); ah->rehighlight(); } else { - BaseAnnotationHighlighter *highlighter = createAnnotationHighlighter(changes); - textDocument()->setSyntaxHighlighterCreator([highlighter] { return highlighter; }); + BaseAnnotationHighlighterCreator creator = annotationHighlighterCreator(); + textDocument()->setSyntaxHighlighterCreator([creator, changes] { return creator(changes); }); } } diff --git a/src/plugins/vcsbase/vcsbaseeditor.h b/src/plugins/vcsbase/vcsbaseeditor.h index 1b588b3e6e7..b34f01ce7e4 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.h +++ b/src/plugins/vcsbase/vcsbaseeditor.h @@ -109,6 +109,9 @@ public: void finalizeInitialization() override; }; +using BaseAnnotationHighlighterCreator + = std::function &)>; + class VCSBASE_EXPORT VcsBaseEditorWidget : public TextEditor::TextEditorWidget { Q_OBJECT @@ -223,7 +226,7 @@ protected: // Implement to identify a change number at the cursor position virtual QString changeUnderCursor(const QTextCursor &) const = 0; // Factory functions for highlighters - virtual BaseAnnotationHighlighter *createAnnotationHighlighter(const QSet &changes) const = 0; + virtual BaseAnnotationHighlighterCreator annotationHighlighterCreator() const = 0; // Returns a local file name from the diff file specification // (text cursor at position above change hunk) QString fileNameFromDiffSpecification(const QTextBlock &inBlock, QString *header = nullptr) const; From 2b88b514daecae262d45e3639a16a2b3faa8d707 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 14:15:16 +0100 Subject: [PATCH 0294/1546] GenericProject: Move plugin class definition to .cpp Change-Id: I4da63d3d106431d7d0c8976e8d1705e40a68646c Reviewed-by: Jarek Kobus --- .../genericprojectmanager/CMakeLists.txt | 2 +- .../genericprojectmanager.qbs | 1 - .../genericprojectplugin.cpp | 42 ++++++++++++------- .../genericprojectplugin.h | 27 ------------ 4 files changed, 27 insertions(+), 45 deletions(-) delete mode 100644 src/plugins/genericprojectmanager/genericprojectplugin.h diff --git a/src/plugins/genericprojectmanager/CMakeLists.txt b/src/plugins/genericprojectmanager/CMakeLists.txt index 764ce9282c6..27c50924d24 100644 --- a/src/plugins/genericprojectmanager/CMakeLists.txt +++ b/src/plugins/genericprojectmanager/CMakeLists.txt @@ -11,6 +11,6 @@ add_qtc_plugin(GenericProjectManager genericprojectconstants.h genericprojectfileseditor.cpp genericprojectfileseditor.h genericprojectmanagertr.h - genericprojectplugin.cpp genericprojectplugin.h + genericprojectplugin.cpp genericprojectwizard.cpp genericprojectwizard.h ) diff --git a/src/plugins/genericprojectmanager/genericprojectmanager.qbs b/src/plugins/genericprojectmanager/genericprojectmanager.qbs index 5ce959e9a64..10b471081ce 100644 --- a/src/plugins/genericprojectmanager/genericprojectmanager.qbs +++ b/src/plugins/genericprojectmanager/genericprojectmanager.qbs @@ -34,7 +34,6 @@ QtcPlugin { "genericprojectfileseditor.h", "genericprojectmanagertr.h", "genericprojectplugin.cpp", - "genericprojectplugin.h", "genericprojectwizard.cpp", "genericprojectwizard.h", ] diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.cpp b/src/plugins/genericprojectmanager/genericprojectplugin.cpp index 9db1af67539..25721445f5e 100644 --- a/src/plugins/genericprojectmanager/genericprojectplugin.cpp +++ b/src/plugins/genericprojectmanager/genericprojectplugin.cpp @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "genericprojectplugin.h" - #include "genericbuildconfiguration.h" #include "genericmakestep.h" #include "genericproject.h" @@ -14,6 +12,8 @@ #include #include +#include + #include #include #include @@ -28,8 +28,7 @@ using namespace ProjectExplorer; using namespace Utils; namespace PEC = ProjectExplorer::Constants; -namespace GenericProjectManager { -namespace Internal { +namespace GenericProjectManager::Internal { class GenericProjectPluginPrivate : public QObject { @@ -41,16 +40,6 @@ public: GenericBuildConfigurationFactory buildConfigFactory; }; -GenericProjectPlugin::~GenericProjectPlugin() -{ - delete d; -} - -void GenericProjectPlugin::initialize() -{ - d = new GenericProjectPluginPrivate; -} - GenericProjectPluginPrivate::GenericProjectPluginPrivate() { ProjectManager::registerProjectType(Constants::GENERICMIMETYPE); @@ -83,5 +72,26 @@ GenericProjectPluginPrivate::GenericProjectPluginPrivate() }); } -} // namespace Internal -} // namespace GenericProjectManager +class GenericProjectPlugin final : public ExtensionSystem::IPlugin +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "GenericProjectManager.json") + +public: + ~GenericProjectPlugin() final + { + delete d; + } + +private: + void initialize() final + { + d = new GenericProjectPluginPrivate; + } + + GenericProjectPluginPrivate *d = nullptr; +}; + +} // GenericProjectManager::Internal + +#include "genericprojectplugin.moc" diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.h b/src/plugins/genericprojectmanager/genericprojectplugin.h deleted file mode 100644 index 9fab0fcc1b2..00000000000 --- a/src/plugins/genericprojectmanager/genericprojectplugin.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace GenericProjectManager { -namespace Internal { - -class GenericProjectPlugin : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "GenericProjectManager.json") - -public: - ~GenericProjectPlugin() override; - -private: - void initialize() override; - void extensionsInitialized() override { } - - class GenericProjectPluginPrivate *d = nullptr; -}; - -} // namespace Internal -} // namespace GenericProject From e28110f6fd9cce572972a4ec7d26d0c51a7c4b32 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 12:13:01 +0100 Subject: [PATCH 0295/1546] Haskell: Use new setup pattern for StackBuildStep Change-Id: Id78047e755a3419499d804ada3edb7ec75fa61d1 Reviewed-by: Jarek Kobus --- src/plugins/haskell/haskellplugin.cpp | 3 +- src/plugins/haskell/stackbuildstep.cpp | 70 +++++++++++++++----------- src/plugins/haskell/stackbuildstep.h | 29 ++--------- 3 files changed, 46 insertions(+), 56 deletions(-) diff --git a/src/plugins/haskell/haskellplugin.cpp b/src/plugins/haskell/haskellplugin.cpp index 80039b96b21..d32165075f8 100644 --- a/src/plugins/haskell/haskellplugin.cpp +++ b/src/plugins/haskell/haskellplugin.cpp @@ -31,7 +31,6 @@ class HaskellPluginPrivate public: HaskellEditorFactory editorFactory; HaskellBuildConfigurationFactory buildConfigFactory; - StackBuildStepFactory stackBuildStepFactory; HaskellRunConfigurationFactory runConfigFactory; ProjectExplorer::SimpleTargetRunnerFactory runWorkerFactory{{Constants::C_HASKELL_RUNCONFIG_ID}}; }; @@ -59,6 +58,8 @@ private: { d = new HaskellPluginPrivate; + setupHaskellStackBuildStep(); + ProjectExplorer::ProjectManager::registerProjectType( Constants::C_HASKELL_PROJECT_MIMETYPE); TextEditor::SnippetProvider::registerGroup(Constants::C_HASKELLSNIPPETSGROUP_ID, diff --git a/src/plugins/haskell/stackbuildstep.cpp b/src/plugins/haskell/stackbuildstep.cpp index 4006ae9daad..b7ba35fbb60 100644 --- a/src/plugins/haskell/stackbuildstep.cpp +++ b/src/plugins/haskell/stackbuildstep.cpp @@ -7,6 +7,7 @@ #include "haskellsettings.h" #include "haskelltr.h" +#include #include #include #include @@ -14,43 +15,54 @@ using namespace ProjectExplorer; -namespace Haskell { -namespace Internal { +namespace Haskell::Internal { -StackBuildStep::StackBuildStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id) - : AbstractProcessStep(bsl, id) -{ - setDefaultDisplayName(trDisplayName()); -} - -QWidget *StackBuildStep::createConfigWidget() -{ - return new QWidget; -} - -QString StackBuildStep::trDisplayName() +static QString trDisplayName() { return Tr::tr("Stack Build"); } -bool StackBuildStep::init() +class StackBuildStep final : public AbstractProcessStep { - if (AbstractProcessStep::init()) { - const auto projectDir = QDir(project()->projectDirectory().toString()); - processParameters()->setCommandLine( - {settings().stackPath(), - {"build", "--work-dir", projectDir.relativeFilePath(buildDirectory().toString())}}); - processParameters()->setEnvironment(buildEnvironment()); +public: + StackBuildStep(BuildStepList *bsl, Utils::Id id) + : AbstractProcessStep(bsl, id) + { + setDefaultDisplayName(trDisplayName()); } - return true; -} -StackBuildStepFactory::StackBuildStepFactory() + QWidget *createConfigWidget() final + { + return new QWidget; + } + + bool init() final + { + if (AbstractProcessStep::init()) { + const auto projectDir = QDir(project()->projectDirectory().toString()); + processParameters()->setCommandLine( + {settings().stackPath(), + {"build", "--work-dir", projectDir.relativeFilePath(buildDirectory().toString())}}); + processParameters()->setEnvironment(buildEnvironment()); + } + return true; + } +}; + +class StackBuildStepFactory final : public BuildStepFactory { - registerStep(Constants::C_STACK_BUILD_STEP_ID); - setDisplayName(StackBuildStep::StackBuildStep::trDisplayName()); - setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); +public: + StackBuildStepFactory() + { + registerStep(Constants::C_STACK_BUILD_STEP_ID); + setDisplayName(trDisplayName()); + setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); + } +}; + +void setupHaskellStackBuildStep() +{ + static StackBuildStepFactory theStackBuildStepFactory; } -} // namespace Internal -} // namespace Haskell +} // Haskell::Internal diff --git a/src/plugins/haskell/stackbuildstep.h b/src/plugins/haskell/stackbuildstep.h index dbfbf2e72cd..9c3ca89a325 100644 --- a/src/plugins/haskell/stackbuildstep.h +++ b/src/plugins/haskell/stackbuildstep.h @@ -3,31 +3,8 @@ #pragma once -#include +namespace Haskell::Internal { -namespace Haskell { -namespace Internal { +void setupHaskellStackBuildStep(); -class StackBuildStep : public ProjectExplorer::AbstractProcessStep -{ - Q_OBJECT - -public: - StackBuildStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id); - - QWidget *createConfigWidget() override; - - static QString trDisplayName(); - -protected: - bool init() override; -}; - -class StackBuildStepFactory : public ProjectExplorer::BuildStepFactory -{ -public: - StackBuildStepFactory(); -}; - -} // namespace Internal -} // namespace Haskell +} // Haskell::Internal From f0574fdb9baaad2a562c56fe5b87e27c366b9d81 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 12:49:42 +0100 Subject: [PATCH 0296/1546] Haskell: Use new setup pattern for HaskellBuildConfigurationFactory Change-Id: I4b8598157a8be20d3447dc7c4e3196700ec3d490 Reviewed-by: Jarek Kobus --- .../haskell/haskellbuildconfiguration.cpp | 165 ++++++++++-------- .../haskell/haskellbuildconfiguration.h | 41 +---- src/plugins/haskell/haskellplugin.cpp | 2 +- 3 files changed, 97 insertions(+), 111 deletions(-) diff --git a/src/plugins/haskell/haskellbuildconfiguration.cpp b/src/plugins/haskell/haskellbuildconfiguration.cpp index 18179da5eb4..1434833ff65 100644 --- a/src/plugins/haskell/haskellbuildconfiguration.cpp +++ b/src/plugins/haskell/haskellbuildconfiguration.cpp @@ -6,11 +6,14 @@ #include "haskellconstants.h" #include "haskelltr.h" +#include #include #include +#include #include #include #include + #include #include #include @@ -23,89 +26,107 @@ using namespace ProjectExplorer; -const char C_HASKELL_BUILDCONFIGURATION_ID[] = "Haskell.BuildConfiguration"; +namespace Haskell::Internal { -namespace Haskell { -namespace Internal { - -HaskellBuildConfigurationFactory::HaskellBuildConfigurationFactory() +class HaskellBuildConfiguration final : public BuildConfiguration { - registerBuildConfiguration(C_HASKELL_BUILDCONFIGURATION_ID); - setSupportedProjectType(Constants::C_HASKELL_PROJECT_ID); - setSupportedProjectMimeTypeName(Constants::C_HASKELL_PROJECT_MIMETYPE); +public: + HaskellBuildConfiguration(Target *target, Utils::Id id) + : BuildConfiguration(target, id) + { + setInitializer([this](const BuildInfo &info) { + setBuildDirectory(info.buildDirectory); + setBuildType(info.buildType); + setDisplayName(info.displayName); + }); + appendInitialBuildStep(Constants::C_STACK_BUILD_STEP_ID); + } - setBuildGenerator([](const Kit *k, const Utils::FilePath &projectPath, bool forSetup) { - BuildInfo info; - info.typeName = Tr::tr("Release"); - if (forSetup) { - info.displayName = info.typeName; - info.buildDirectory = projectPath.parentDir().pathAppended(".stack-work"); - } - info.kitId = k->id(); - info.buildType = BuildConfiguration::BuildType::Release; - return QList{info}; - }); -} + NamedWidget *createConfigWidget() final; -HaskellBuildConfiguration::HaskellBuildConfiguration(Target *target, Utils::Id id) - : BuildConfiguration(target, id) + BuildType buildType() const final + { + return m_buildType; + } + + void setBuildType(BuildType type) + { + m_buildType = type; + } + +private: + BuildType m_buildType = BuildType::Release; +}; + +class HaskellBuildConfigurationWidget final : public NamedWidget { - setInitializer([this](const BuildInfo &info) { - setBuildDirectory(info.buildDirectory); - setBuildType(info.buildType); - setDisplayName(info.displayName); - }); - appendInitialBuildStep(Constants::C_STACK_BUILD_STEP_ID); -} +public: + HaskellBuildConfigurationWidget(HaskellBuildConfiguration *bc) + : NamedWidget(Tr::tr("General")) + { + setLayout(new QVBoxLayout); + layout()->setContentsMargins(0, 0, 0, 0); + auto box = new Utils::DetailsWidget; + box->setState(Utils::DetailsWidget::NoSummary); + layout()->addWidget(box); + auto details = new QWidget; + box->setWidget(details); + details->setLayout(new QHBoxLayout); + details->layout()->setContentsMargins(0, 0, 0, 0); + details->layout()->addWidget(new QLabel(Tr::tr("Build directory:"))); + + auto buildDirectoryInput = new Utils::PathChooser; + buildDirectoryInput->setExpectedKind(Utils::PathChooser::Directory); + buildDirectoryInput->setFilePath(bc->buildDirectory()); + details->layout()->addWidget(buildDirectoryInput); + + connect(bc, + &BuildConfiguration::buildDirectoryChanged, + buildDirectoryInput, + [bc, buildDirectoryInput] { + buildDirectoryInput->setFilePath(bc->buildDirectory()); + }); + connect(buildDirectoryInput, + &Utils::PathChooser::textChanged, + bc, + [bc, buildDirectoryInput](const QString &) { + bc->setBuildDirectory(buildDirectoryInput->rawFilePath()); + }); + } +}; NamedWidget *HaskellBuildConfiguration::createConfigWidget() { return new HaskellBuildConfigurationWidget(this); } -BuildConfiguration::BuildType HaskellBuildConfiguration::buildType() const +class HaskellBuildConfigurationFactory final : public BuildConfigurationFactory { - return m_buildType; +public: + HaskellBuildConfigurationFactory() + { + registerBuildConfiguration("Haskell.BuildConfiguration"); + + setSupportedProjectType(Constants::C_HASKELL_PROJECT_ID); + setSupportedProjectMimeTypeName(Constants::C_HASKELL_PROJECT_MIMETYPE); + + setBuildGenerator([](const Kit *k, const Utils::FilePath &projectPath, bool forSetup) { + BuildInfo info; + info.typeName = Tr::tr("Release"); + if (forSetup) { + info.displayName = info.typeName; + info.buildDirectory = projectPath.parentDir().pathAppended(".stack-work"); + } + info.kitId = k->id(); + info.buildType = BuildConfiguration::BuildType::Release; + return QList{info}; + }); + } +}; + +void setupHaskellBuildConfiguration() +{ + static HaskellBuildConfigurationFactory theHaskellBuildConfigurationFactory; } -void HaskellBuildConfiguration::setBuildType(BuildConfiguration::BuildType type) -{ - m_buildType = type; -} - -HaskellBuildConfigurationWidget::HaskellBuildConfigurationWidget(HaskellBuildConfiguration *bc) - : NamedWidget(Tr::tr("General")) - , m_buildConfiguration(bc) -{ - setLayout(new QVBoxLayout); - layout()->setContentsMargins(0, 0, 0, 0); - auto box = new Utils::DetailsWidget; - box->setState(Utils::DetailsWidget::NoSummary); - layout()->addWidget(box); - auto details = new QWidget; - box->setWidget(details); - details->setLayout(new QHBoxLayout); - details->layout()->setContentsMargins(0, 0, 0, 0); - details->layout()->addWidget(new QLabel(Tr::tr("Build directory:"))); - - auto buildDirectoryInput = new Utils::PathChooser; - buildDirectoryInput->setExpectedKind(Utils::PathChooser::Directory); - buildDirectoryInput->setFilePath(m_buildConfiguration->buildDirectory()); - details->layout()->addWidget(buildDirectoryInput); - - connect(m_buildConfiguration, - &BuildConfiguration::buildDirectoryChanged, - buildDirectoryInput, - [this, buildDirectoryInput] { - buildDirectoryInput->setFilePath(m_buildConfiguration->buildDirectory()); - }); - connect(buildDirectoryInput, - &Utils::PathChooser::textChanged, - m_buildConfiguration, - [this, buildDirectoryInput](const QString &) { - m_buildConfiguration->setBuildDirectory(buildDirectoryInput->rawFilePath()); - }); -} - -} // namespace Internal -} // namespace Haskell +} // Haskell::Internal diff --git a/src/plugins/haskell/haskellbuildconfiguration.h b/src/plugins/haskell/haskellbuildconfiguration.h index e8cbc1dbc61..ee6c7065ee6 100644 --- a/src/plugins/haskell/haskellbuildconfiguration.h +++ b/src/plugins/haskell/haskellbuildconfiguration.h @@ -3,43 +3,8 @@ #pragma once -#include -#include +namespace Haskell::Internal { -namespace Haskell { -namespace Internal { +void setupHaskellBuildConfiguration(); -class HaskellBuildConfigurationFactory : public ProjectExplorer::BuildConfigurationFactory -{ -public: - HaskellBuildConfigurationFactory(); -}; - -class HaskellBuildConfiguration : public ProjectExplorer::BuildConfiguration -{ - Q_OBJECT - -public: - HaskellBuildConfiguration(ProjectExplorer::Target *target, Utils::Id id); - - ProjectExplorer::NamedWidget *createConfigWidget() override; - BuildType buildType() const override; - void setBuildType(BuildType type); - -private: - BuildType m_buildType = BuildType::Release; -}; - -class HaskellBuildConfigurationWidget : public ProjectExplorer::NamedWidget -{ - Q_OBJECT - -public: - HaskellBuildConfigurationWidget(HaskellBuildConfiguration *bc); - -private: - HaskellBuildConfiguration *m_buildConfiguration; -}; - -} // namespace Internal -} // namespace Haskell +} // Haskell::Internal diff --git a/src/plugins/haskell/haskellplugin.cpp b/src/plugins/haskell/haskellplugin.cpp index d32165075f8..3b6bebdd289 100644 --- a/src/plugins/haskell/haskellplugin.cpp +++ b/src/plugins/haskell/haskellplugin.cpp @@ -30,7 +30,6 @@ class HaskellPluginPrivate { public: HaskellEditorFactory editorFactory; - HaskellBuildConfigurationFactory buildConfigFactory; HaskellRunConfigurationFactory runConfigFactory; ProjectExplorer::SimpleTargetRunnerFactory runWorkerFactory{{Constants::C_HASKELL_RUNCONFIG_ID}}; }; @@ -59,6 +58,7 @@ private: d = new HaskellPluginPrivate; setupHaskellStackBuildStep(); + setupHaskellBuildConfiguration(); ProjectExplorer::ProjectManager::registerProjectType( Constants::C_HASKELL_PROJECT_MIMETYPE); From cc711d790363512e9c06fe84e997b8bbb42ea488 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 12:57:46 +0100 Subject: [PATCH 0297/1546] Haskell: Use new setup for HaskellEditorFactory Change-Id: I537248460291d5d649a1dc60a5f495003d76fa8b Reviewed-by: Jarek Kobus Reviewed-by: --- src/plugins/haskell/haskelleditorfactory.cpp | 43 +++++++++++++------- src/plugins/haskell/haskelleditorfactory.h | 8 +--- src/plugins/haskell/haskellplugin.cpp | 2 +- 3 files changed, 30 insertions(+), 23 deletions(-) diff --git a/src/plugins/haskell/haskelleditorfactory.cpp b/src/plugins/haskell/haskelleditorfactory.cpp index f3e65ffcd8e..a2ddcb293ab 100644 --- a/src/plugins/haskell/haskelleditorfactory.cpp +++ b/src/plugins/haskell/haskelleditorfactory.cpp @@ -10,38 +10,51 @@ #include #include + #include +#include #include #include +using namespace TextEditor; + namespace Haskell::Internal { static QWidget *createEditorWidget() { - auto widget = new TextEditor::TextEditorWidget; + auto widget = new TextEditorWidget; auto ghciButton = new Core::CommandButton(Constants::A_RUN_GHCI, widget); ghciButton->setText(Tr::tr("GHCi")); QObject::connect(ghciButton, &QToolButton::clicked, widget, [widget] { HaskellManager::openGhci(widget->textDocument()->filePath()); }); - widget->insertExtraToolBarWidget(TextEditor::TextEditorWidget::Left, ghciButton); + widget->insertExtraToolBarWidget(TextEditorWidget::Left, ghciButton); return widget; } -HaskellEditorFactory::HaskellEditorFactory() +class HaskellEditorFactory : public TextEditorFactory { - setId(Constants::C_HASKELLEDITOR_ID); - setDisplayName(::Core::Tr::tr("Haskell Editor")); - addMimeType("text/x-haskell"); - setEditorActionHandlers(TextEditor::TextEditorActionHandler::UnCommentSelection - | TextEditor::TextEditorActionHandler::FollowSymbolUnderCursor); - setDocumentCreator([] { return new TextEditor::TextDocument(Constants::C_HASKELLEDITOR_ID); }); - setIndenterCreator([](QTextDocument *doc) { return new TextEditor::TextIndenter(doc); }); - setEditorWidgetCreator(&createEditorWidget); - setCommentDefinition(Utils::CommentDefinition("--", "{-", "-}")); - setParenthesesMatchingEnabled(true); - setMarksVisible(true); - setSyntaxHighlighterCreator([] { return new HaskellHighlighter(); }); +public: + HaskellEditorFactory() + { + setId(Constants::C_HASKELLEDITOR_ID); + setDisplayName(::Core::Tr::tr("Haskell Editor")); + addMimeType("text/x-haskell"); + setEditorActionHandlers(TextEditorActionHandler::UnCommentSelection + | TextEditorActionHandler::FollowSymbolUnderCursor); + setDocumentCreator([] { return new TextDocument(Constants::C_HASKELLEDITOR_ID); }); + setIndenterCreator([](QTextDocument *doc) { return new TextIndenter(doc); }); + setEditorWidgetCreator(&createEditorWidget); + setCommentDefinition(Utils::CommentDefinition("--", "{-", "-}")); + setParenthesesMatchingEnabled(true); + setMarksVisible(true); + setSyntaxHighlighterCreator([] { return new HaskellHighlighter(); }); + } +}; + +void setupHaskellEditor() +{ + static HaskellEditorFactory theHaskellEditorFactory; } } // Haskell::Internal diff --git a/src/plugins/haskell/haskelleditorfactory.h b/src/plugins/haskell/haskelleditorfactory.h index 090a5b12782..6a21ed67a46 100644 --- a/src/plugins/haskell/haskelleditorfactory.h +++ b/src/plugins/haskell/haskelleditorfactory.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace Haskell::Internal { -class HaskellEditorFactory : public TextEditor::TextEditorFactory -{ -public: - HaskellEditorFactory(); -}; +void setupHaskellEditor(); } // Haskell::Internal diff --git a/src/plugins/haskell/haskellplugin.cpp b/src/plugins/haskell/haskellplugin.cpp index 3b6bebdd289..f1285340ac9 100644 --- a/src/plugins/haskell/haskellplugin.cpp +++ b/src/plugins/haskell/haskellplugin.cpp @@ -29,7 +29,6 @@ namespace Haskell::Internal { class HaskellPluginPrivate { public: - HaskellEditorFactory editorFactory; HaskellRunConfigurationFactory runConfigFactory; ProjectExplorer::SimpleTargetRunnerFactory runWorkerFactory{{Constants::C_HASKELL_RUNCONFIG_ID}}; }; @@ -59,6 +58,7 @@ private: setupHaskellStackBuildStep(); setupHaskellBuildConfiguration(); + setupHaskellEditor(); ProjectExplorer::ProjectManager::registerProjectType( Constants::C_HASKELL_PROJECT_MIMETYPE); From e6b052e0403e6ec49316d118150579e02a08efbc Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 13:05:52 +0100 Subject: [PATCH 0298/1546] Haskell: Use new setup for run related classes Change-Id: I9c6324aea586838d83bf81098499627c8c6c6d4a Reviewed-by: Jarek Kobus --- src/plugins/haskell/haskellplugin.cpp | 17 +++---------- .../haskell/haskellrunconfiguration.cpp | 24 ++++++++++++++----- src/plugins/haskell/haskellrunconfiguration.h | 8 +------ 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/plugins/haskell/haskellplugin.cpp b/src/plugins/haskell/haskellplugin.cpp index f1285340ac9..6da003c1a50 100644 --- a/src/plugins/haskell/haskellplugin.cpp +++ b/src/plugins/haskell/haskellplugin.cpp @@ -26,13 +26,6 @@ namespace Haskell::Internal { -class HaskellPluginPrivate -{ -public: - HaskellRunConfigurationFactory runConfigFactory; - ProjectExplorer::SimpleTargetRunnerFactory runWorkerFactory{{Constants::C_HASKELL_RUNCONFIG_ID}}; -}; - static void registerGhciAction(QObject *guard) { QAction *action = new QAction(Tr::tr("Run GHCi"), guard); @@ -49,15 +42,13 @@ class HaskellPlugin final : public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Haskell.json") public: - ~HaskellPlugin() final { delete d; } - -private: void initialize() final { - d = new HaskellPluginPrivate; - setupHaskellStackBuildStep(); setupHaskellBuildConfiguration(); + + setupHaskellRunSupport(); + setupHaskellEditor(); ProjectExplorer::ProjectManager::registerProjectType( @@ -69,8 +60,6 @@ private: ProjectExplorer::JsonWizardFactory::addWizardPath(":/haskell/share/wizards/"); } - - HaskellPluginPrivate *d = nullptr; }; } // Haskell::Internal diff --git a/src/plugins/haskell/haskellrunconfiguration.cpp b/src/plugins/haskell/haskellrunconfiguration.cpp index 0381f86784a..5c2162757b2 100644 --- a/src/plugins/haskell/haskellrunconfiguration.cpp +++ b/src/plugins/haskell/haskellrunconfiguration.cpp @@ -11,7 +11,9 @@ #include #include #include +#include #include +#include #include #include @@ -21,7 +23,7 @@ using namespace Utils; namespace Haskell::Internal { -class HaskellRunConfiguration : public RunConfiguration +class HaskellRunConfiguration final : public RunConfiguration { public: HaskellRunConfiguration(Target *target, Id id) @@ -46,7 +48,7 @@ public: } private: - Utils::ProcessRunData runnable() const final + ProcessRunData runnable() const final { const FilePath projectDirectory = project()->projectDirectory(); ProcessRunData r; @@ -75,11 +77,21 @@ private: // Factory -HaskellRunConfigurationFactory::HaskellRunConfigurationFactory() +class HaskellRunConfigurationFactory final : public ProjectExplorer::RunConfigurationFactory { - registerRunConfiguration(Constants::C_HASKELL_RUNCONFIG_ID); - addSupportedProjectType(Constants::C_HASKELL_PROJECT_ID); - addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); +public: + HaskellRunConfigurationFactory() + { + registerRunConfiguration(Constants::C_HASKELL_RUNCONFIG_ID); + addSupportedProjectType(Constants::C_HASKELL_PROJECT_ID); + addSupportedTargetDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); + } +}; + +void setupHaskellRunSupport() +{ + static HaskellRunConfigurationFactory runConfigFactory; + static SimpleTargetRunnerFactory runWorkerFactory{{Constants::C_HASKELL_RUNCONFIG_ID}}; } } // Haskell::Internal diff --git a/src/plugins/haskell/haskellrunconfiguration.h b/src/plugins/haskell/haskellrunconfiguration.h index 579f8110a75..a979b1813e0 100644 --- a/src/plugins/haskell/haskellrunconfiguration.h +++ b/src/plugins/haskell/haskellrunconfiguration.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace Haskell::Internal { -class HaskellRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory -{ -public: - HaskellRunConfigurationFactory(); -}; +void setupHaskellRunSupport(); } // Haskell::Internal From 8c3a1c7e5c24db154d43cda49f51d6adec4b5224 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 13:16:13 +0100 Subject: [PATCH 0299/1546] Haskell: Move haskell project setup closer to new setup pattern Change-Id: I3c6e6ad1a6f4b0a8d0a5598ad970c7539d1643e3 Reviewed-by: Jarek Kobus --- src/plugins/haskell/haskellplugin.cpp | 6 +-- src/plugins/haskell/haskellproject.cpp | 59 ++++++++++++++++++-------- src/plugins/haskell/haskellproject.h | 40 ++--------------- 3 files changed, 46 insertions(+), 59 deletions(-) diff --git a/src/plugins/haskell/haskellplugin.cpp b/src/plugins/haskell/haskellplugin.cpp index 6da003c1a50..632b9514a98 100644 --- a/src/plugins/haskell/haskellplugin.cpp +++ b/src/plugins/haskell/haskellplugin.cpp @@ -17,8 +17,6 @@ #include #include -#include -#include #include @@ -51,8 +49,8 @@ public: setupHaskellEditor(); - ProjectExplorer::ProjectManager::registerProjectType( - Constants::C_HASKELL_PROJECT_MIMETYPE); + setupHaskellProject(); + TextEditor::SnippetProvider::registerGroup(Constants::C_HASKELLSNIPPETSGROUP_ID, Tr::tr("Haskell", "SnippetProvider")); diff --git a/src/plugins/haskell/haskellproject.cpp b/src/plugins/haskell/haskellproject.cpp index f19840a67f5..01d652c49ef 100644 --- a/src/plugins/haskell/haskellproject.cpp +++ b/src/plugins/haskell/haskellproject.cpp @@ -5,14 +5,16 @@ #include "haskellconstants.h" -#include -#include - +#include #include +#include +#include +#include #include +#include #include -#include +#include #include #include @@ -21,8 +23,7 @@ using namespace ProjectExplorer; using namespace Utils; -namespace Haskell { -namespace Internal { +namespace Haskell::Internal { static QVector parseExecutableNames(const FilePath &projectFilePath) { @@ -42,18 +43,23 @@ static QVector parseExecutableNames(const FilePath &projectFilePath) return result; } -HaskellProject::HaskellProject(const Utils::FilePath &fileName) - : Project(Constants::C_HASKELL_PROJECT_MIMETYPE, fileName) +class HaskellBuildSystem final : public BuildSystem { - setId(Constants::C_HASKELL_PROJECT_ID); - setDisplayName(fileName.toFileInfo().completeBaseName()); - setBuildSystemCreator([](Target *t) { return new HaskellBuildSystem(t); }); -} +public: + HaskellBuildSystem(Target *t); -bool HaskellProject::isHaskellProject(Project *project) -{ - return project && project->id() == Constants::C_HASKELL_PROJECT_ID; -} + void triggerParsing() final; + + QString name() const final { return QLatin1String("haskell"); } + +private: + void updateApplicationTargets(); + void refresh(); + +private: + ParseGuard m_parseGuard; + TreeScanner m_scanner; +}; HaskellBuildSystem::HaskellBuildSystem(Target *t) : BuildSystem(t) @@ -108,5 +114,22 @@ void HaskellBuildSystem::updateApplicationTargets() target()->updateDefaultRunConfigurations(); } -} // namespace Internal -} // namespace Haskell +class HaskellProject final : public Project +{ +public: + explicit HaskellProject(const FilePath &fileName) + : Project(Constants::C_HASKELL_PROJECT_MIMETYPE, fileName) + { + setId(Constants::C_HASKELL_PROJECT_ID); + setDisplayName(fileName.toFileInfo().completeBaseName()); + setBuildSystemCreator([](Target *t) { return new HaskellBuildSystem(t); }); + } +}; + +void setupHaskellProject() +{ + ProjectManager::registerProjectType( + Constants::C_HASKELL_PROJECT_MIMETYPE); +} + +} // Haskell::Internal diff --git a/src/plugins/haskell/haskellproject.h b/src/plugins/haskell/haskellproject.h index 79bec049ae4..79627d9c5b0 100644 --- a/src/plugins/haskell/haskellproject.h +++ b/src/plugins/haskell/haskellproject.h @@ -3,42 +3,8 @@ #pragma once -#include -#include -#include -#include +namespace Haskell::Internal { -namespace Haskell { -namespace Internal { +void setupHaskellProject(); -class HaskellProject : public ProjectExplorer::Project -{ - Q_OBJECT - -public: - explicit HaskellProject(const Utils::FilePath &fileName); - - static bool isHaskellProject(Project *project); -}; - -class HaskellBuildSystem : public ProjectExplorer::BuildSystem -{ - Q_OBJECT - -public: - HaskellBuildSystem(ProjectExplorer::Target *t); - - void triggerParsing() override; - QString name() const final { return QLatin1String("haskell"); } - -private: - void updateApplicationTargets(); - void refresh(); - -private: - ParseGuard m_parseGuard; - ProjectExplorer::TreeScanner m_scanner; -}; - -} // namespace Internal -} // namespace Haskell +} // Haskell::Internal From e53308eb7df524810f0519ff38d2a6729d276ec6 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 13:49:00 +0100 Subject: [PATCH 0300/1546] Haskell: Use ActionBuilder to create action to run ghci Change-Id: I7bb4064a06e91b580c1d5f72dc4f0ff2ab8ef0cd Reviewed-by: Jarek Kobus --- src/plugins/haskell/haskellconstants.h | 6 ++---- src/plugins/haskell/haskelleditorfactory.cpp | 2 +- src/plugins/haskell/haskellmanager.cpp | 21 ++++++++++++++++---- src/plugins/haskell/haskellmanager.h | 12 ++++------- src/plugins/haskell/haskellplugin.cpp | 18 +---------------- 5 files changed, 25 insertions(+), 34 deletions(-) diff --git a/src/plugins/haskell/haskellconstants.h b/src/plugins/haskell/haskellconstants.h index 7561a53a040..b632eb6ac9c 100644 --- a/src/plugins/haskell/haskellconstants.h +++ b/src/plugins/haskell/haskellconstants.h @@ -3,8 +3,7 @@ #pragma once -namespace Haskell { -namespace Constants { +namespace Haskell::Constants { const char C_HASKELLEDITOR_ID[] = "Haskell.HaskellEditor"; const char C_HASKELLSNIPPETSGROUP_ID[] = "Haskell"; @@ -15,5 +14,4 @@ const char C_STACK_BUILD_STEP_ID[] = "Haskell.Stack.Build"; const char OPTIONS_GENERAL[] = "Haskell.A.General"; const char A_RUN_GHCI[] = "Haskell.RunGHCi"; -} // namespace Haskell -} // namespace Constants +} // Haskell::Constants diff --git a/src/plugins/haskell/haskelleditorfactory.cpp b/src/plugins/haskell/haskelleditorfactory.cpp index a2ddcb293ab..3371a8734c9 100644 --- a/src/plugins/haskell/haskelleditorfactory.cpp +++ b/src/plugins/haskell/haskelleditorfactory.cpp @@ -26,7 +26,7 @@ static QWidget *createEditorWidget() auto ghciButton = new Core::CommandButton(Constants::A_RUN_GHCI, widget); ghciButton->setText(Tr::tr("GHCi")); QObject::connect(ghciButton, &QToolButton::clicked, widget, [widget] { - HaskellManager::openGhci(widget->textDocument()->filePath()); + openGhci(widget->textDocument()->filePath()); }); widget->insertExtraToolBarWidget(TextEditorWidget::Left, ghciButton); return widget; diff --git a/src/plugins/haskell/haskellmanager.cpp b/src/plugins/haskell/haskellmanager.cpp index cc91ae7f816..bd0fe2d2cdb 100644 --- a/src/plugins/haskell/haskellmanager.cpp +++ b/src/plugins/haskell/haskellmanager.cpp @@ -3,24 +3,27 @@ #include "haskellmanager.h" +#include "haskellconstants.h" #include "haskellsettings.h" #include "haskelltr.h" +#include +#include + #include #include -#include #include #include -#include #include #include +using namespace Core; using namespace Utils; namespace Haskell::Internal { -FilePath HaskellManager::findProjectDirectory(const FilePath &filePath) +FilePath findProjectDirectory(const FilePath &filePath) { if (filePath.isEmpty()) return {}; @@ -36,7 +39,7 @@ FilePath HaskellManager::findProjectDirectory(const FilePath &filePath) return {}; } -void HaskellManager::openGhci(const FilePath &haskellFile) +void openGhci(const FilePath &haskellFile) { const QList mimeTypes = mimeTypesForFileName(haskellFile.toString()); const bool isHaskell = Utils::anyOf(mimeTypes, [](const MimeType &mt) { @@ -51,4 +54,14 @@ void HaskellManager::openGhci(const FilePath &haskellFile) p.start(); } +void setupHaskellActions(QObject *guard) +{ + ActionBuilder runGhci(guard, Haskell::Constants::A_RUN_GHCI); + runGhci.setText(Tr::tr("Run GHCi")); + runGhci.setOnTriggered(guard, [] { + if (IDocument *doc = EditorManager::currentDocument()) + openGhci(doc->filePath()); + }); +} + } // Haskell::Internal diff --git a/src/plugins/haskell/haskellmanager.h b/src/plugins/haskell/haskellmanager.h index 862f46460f1..ad540d86e97 100644 --- a/src/plugins/haskell/haskellmanager.h +++ b/src/plugins/haskell/haskellmanager.h @@ -5,17 +5,13 @@ #include -#include +namespace Utils { class FilePath; } namespace Haskell::Internal { -class HaskellManager -{ -public: - static HaskellManager *instance(); +Utils::FilePath findProjectDirectory(const Utils::FilePath &filePath); +void openGhci(const Utils::FilePath &haskellFile); - static Utils::FilePath findProjectDirectory(const Utils::FilePath &filePath); - static void openGhci(const Utils::FilePath &haskellFile); -}; +void setupHaskellActions(QObject *guard); } // Haskell::Internal diff --git a/src/plugins/haskell/haskellplugin.cpp b/src/plugins/haskell/haskellplugin.cpp index 632b9514a98..f8c32dc288d 100644 --- a/src/plugins/haskell/haskellplugin.cpp +++ b/src/plugins/haskell/haskellplugin.cpp @@ -10,30 +10,14 @@ #include "haskelltr.h" #include "stackbuildstep.h" -#include -#include -#include - #include #include #include -#include - namespace Haskell::Internal { -static void registerGhciAction(QObject *guard) -{ - QAction *action = new QAction(Tr::tr("Run GHCi"), guard); - Core::ActionManager::registerAction(action, Constants::A_RUN_GHCI); - QObject::connect(action, &QAction::triggered, guard, [] { - if (Core::IDocument *doc = Core::EditorManager::currentDocument()) - HaskellManager::openGhci(doc->filePath()); - }); -} - class HaskellPlugin final : public ExtensionSystem::IPlugin { Q_OBJECT @@ -54,7 +38,7 @@ public: TextEditor::SnippetProvider::registerGroup(Constants::C_HASKELLSNIPPETSGROUP_ID, Tr::tr("Haskell", "SnippetProvider")); - registerGhciAction(this); + setupHaskellActions(this); ProjectExplorer::JsonWizardFactory::addWizardPath(":/haskell/share/wizards/"); } From b26c43f133fd692e6ab7d8fba309f8e5204fd3ec Mon Sep 17 00:00:00 2001 From: Artem Sokolovskii Date: Wed, 1 Nov 2023 10:08:31 +0100 Subject: [PATCH 0301/1546] SyntaxHighlighter: Move static functions to other namespace - Created HighlighterHelper namespace and static functions were moved there from the highlighter class Change-Id: Ib93785a3819317d7c1d5cc480652d4635cb9339b Reviewed-by: Jarek Kobus --- src/plugins/texteditor/CMakeLists.txt | 1 + src/plugins/texteditor/highlighter.cpp | 191 +-------------- src/plugins/texteditor/highlighter.h | 19 -- src/plugins/texteditor/highlighterhelper.cpp | 223 ++++++++++++++++++ src/plugins/texteditor/highlighterhelper.h | 35 +++ .../texteditor/highlightersettingspage.cpp | 9 +- src/plugins/texteditor/texteditor.cpp | 27 ++- src/plugins/texteditor/texteditorplugin.cpp | 5 +- 8 files changed, 281 insertions(+), 229 deletions(-) create mode 100644 src/plugins/texteditor/highlighterhelper.cpp create mode 100644 src/plugins/texteditor/highlighterhelper.h diff --git a/src/plugins/texteditor/CMakeLists.txt b/src/plugins/texteditor/CMakeLists.txt index 7d4577413bc..3f38c4436fc 100644 --- a/src/plugins/texteditor/CMakeLists.txt +++ b/src/plugins/texteditor/CMakeLists.txt @@ -65,6 +65,7 @@ add_qtc_plugin(TextEditor formatter.h formattexteditor.cpp formattexteditor.h highlighter.cpp highlighter.h + highlighterhelper.cpp highlighterhelper.h highlightersettings.cpp highlightersettings.h highlightersettingspage.cpp highlightersettingspage.h icodestylepreferences.cpp icodestylepreferences.h diff --git a/src/plugins/texteditor/highlighter.cpp b/src/plugins/texteditor/highlighter.cpp index cc7bc395bd1..14e2f1ff168 100644 --- a/src/plugins/texteditor/highlighter.cpp +++ b/src/plugins/texteditor/highlighter.cpp @@ -3,12 +3,8 @@ #include "highlighter.h" -#include "highlightersettings.h" #include "tabsettings.h" #include "textdocumentlayout.h" -#include "texteditor.h" -#include "texteditortr.h" -#include "texteditorsettings.h" #include #include @@ -18,6 +14,7 @@ #include #include +#include #include #include #include @@ -33,23 +30,6 @@ namespace TextEditor { static Q_LOGGING_CATEGORY(highlighterLog, "qtc.editor.highlighter", QtWarningMsg) -const char kDefinitionForMimeType[] = "definitionForMimeType"; -const char kDefinitionForExtension[] = "definitionForExtension"; -const char kDefinitionForFilePath[] = "definitionForFilePath"; - -static KSyntaxHighlighting::Repository *highlightRepository() -{ - static KSyntaxHighlighting::Repository *repository = nullptr; - if (!repository) { - repository = new KSyntaxHighlighting::Repository(); - repository->addCustomSearchPath(TextEditorSettings::highlighterSettings().definitionFilesPath().toString()); - const FilePath dir = Core::ICore::resourcePath("generic-highlighter/syntax"); - if (dir.exists()) - repository->addCustomSearchPath(dir.parentDir().path()); - } - return repository; -} - TextStyle categoryForTextStyle(int style) { switch (style) { @@ -94,175 +74,6 @@ Highlighter::Highlighter() &categoryForTextStyle); } -Highlighter::Definition Highlighter::definitionForName(const QString &name) -{ - return highlightRepository()->definitionForName(name); -} - -Highlighter::Definitions Highlighter::definitionsForDocument(const TextDocument *document) -{ - QTC_ASSERT(document, return {}); - // First try to find definitions for the file path, only afterwards try the MIME type. - // An example where that is important is if there was a definition for "*.rb.xml", which - // cannot be referred to with a MIME type (since there is none), but there is the definition - // for XML files, which specifies a MIME type in addition to a glob pattern. - // If we check the MIME type first and then skip the pattern, the definition for "*.rb.xml" is - // never considered. - // The KSyntaxHighlighting CLI also completely ignores MIME types. - const FilePath &filePath = document->filePath(); - Definitions definitions = definitionsForFileName(filePath); - if (definitions.isEmpty()) { - // check for *.in filename since those are usually used for - // cmake configure_file input filenames without the .in extension - if (filePath.endsWith(".in")) - definitions = definitionsForFileName(FilePath::fromString(filePath.completeBaseName())); - if (filePath.fileName() == "qtquickcontrols2.conf") - definitions = definitionsForFileName(filePath.stringAppended(".ini")); - } - if (definitions.isEmpty()) { - const MimeType &mimeType = Utils::mimeTypeForName(document->mimeType()); - if (mimeType.isValid()) { - Utils::visitMimeParents(mimeType, [&](const MimeType &mt) -> bool { - // highlight definitions might not use the canonical name but an alias - const QStringList names = QStringList(mt.name()) + mt.aliases(); - for (const QString &name : names) { - definitions = definitionsForMimeType(name); - if (!definitions.isEmpty()) - return false; // stop - } - return true; // continue - }); - } - } - - return definitions; -} - -static Highlighter::Definition definitionForSetting(const Key &settingsKey, - const QString &mapKey) -{ - QtcSettings *settings = Core::ICore::settings(); - settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY); - const QString &definitionName = settings->value(settingsKey).toMap().value(mapKey).toString(); - settings->endGroup(); - return Highlighter::definitionForName(definitionName); -} - -Highlighter::Definitions Highlighter::definitionsForMimeType(const QString &mimeType) -{ - Definitions definitions = highlightRepository()->definitionsForMimeType(mimeType).toList(); - if (definitions.size() > 1) { - const Definition &rememberedDefinition = definitionForSetting(kDefinitionForMimeType, - mimeType); - if (rememberedDefinition.isValid() && definitions.contains(rememberedDefinition)) - definitions = {rememberedDefinition}; - } - return definitions; -} - -Highlighter::Definitions Highlighter::definitionsForFileName(const FilePath &fileName) -{ - Definitions definitions - = highlightRepository()->definitionsForFileName(fileName.fileName()).toList(); - - if (definitions.size() > 1) { - const QString &fileExtension = fileName.completeSuffix(); - const Definition &rememberedDefinition - = fileExtension.isEmpty() - ? definitionForSetting(kDefinitionForFilePath, - fileName.absoluteFilePath().toString()) - : definitionForSetting(kDefinitionForExtension, fileExtension); - if (rememberedDefinition.isValid() && definitions.contains(rememberedDefinition)) - definitions = {rememberedDefinition}; - } - - return definitions; -} - -void Highlighter::rememberDefinitionForDocument(const Highlighter::Definition &definition, - const TextDocument *document) -{ - QTC_ASSERT(document, return ); - if (!definition.isValid()) - return; - const QString &mimeType = document->mimeType(); - const FilePath &path = document->filePath(); - const QString &fileExtension = path.completeSuffix(); - QtcSettings *settings = Core::ICore::settings(); - settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY); - const Definitions &fileNameDefinitions = definitionsForFileName(path); - if (fileNameDefinitions.contains(definition)) { - if (!fileExtension.isEmpty()) { - const Key id(kDefinitionForExtension); - QMap map = settings->value(id).toMap(); - map.insert(fileExtension, definition.name()); - settings->setValue(id, map); - } else if (!path.isEmpty()) { - const Key id(kDefinitionForFilePath); - QMap map = settings->value(id).toMap(); - map.insert(path.absoluteFilePath().toString(), definition.name()); - settings->setValue(id, map); - } - } else if (!mimeType.isEmpty()) { - const Key id(kDefinitionForMimeType); - QMap map = settings->value(id).toMap(); - map.insert(mimeType, definition.name()); - settings->setValue(id, map); - } - settings->endGroup(); -} - -void Highlighter::clearDefinitionForDocumentCache() -{ - QtcSettings *settings = Core::ICore::settings(); - settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY); - settings->remove(kDefinitionForMimeType); - settings->remove(kDefinitionForExtension); - settings->remove(kDefinitionForFilePath); - settings->endGroup(); -} - -void Highlighter::addCustomHighlighterPath(const FilePath &path) -{ - highlightRepository()->addCustomSearchPath(path.toString()); -} - -void Highlighter::downloadDefinitions(std::function callback) -{ - auto downloader = - new KSyntaxHighlighting::DefinitionDownloader(highlightRepository()); - connect(downloader, &KSyntaxHighlighting::DefinitionDownloader::done, [downloader, callback]() { - Core::MessageManager::writeFlashing(Tr::tr("Highlighter updates: done")); - downloader->deleteLater(); - reload(); - if (callback) - callback(); - }); - connect(downloader, - &KSyntaxHighlighting::DefinitionDownloader::informationMessage, - [](const QString &message) { - Core::MessageManager::writeSilently(Tr::tr("Highlighter updates:") + ' ' + message); - }); - Core::MessageManager::writeDisrupting(Tr::tr("Highlighter updates: starting")); - downloader->start(); -} - -void Highlighter::reload() -{ - highlightRepository()->reload(); - for (auto editor : Core::DocumentModel::editorsForOpenedDocuments()) { - if (auto textEditor = qobject_cast(editor)) { - if (qobject_cast(textEditor->textDocument()->syntaxHighlighter())) - textEditor->editorWidget()->configureGenericHighlighter(); - } - } -} - -void Highlighter::handleShutdown() -{ - delete highlightRepository(); -} - static bool isOpeningParenthesis(QChar c) { return c == QLatin1Char('{') || c == QLatin1Char('[') || c == QLatin1Char('('); diff --git a/src/plugins/texteditor/highlighter.h b/src/plugins/texteditor/highlighter.h index 0183c9c171e..0b99265aa52 100644 --- a/src/plugins/texteditor/highlighter.h +++ b/src/plugins/texteditor/highlighter.h @@ -8,7 +8,6 @@ #include #include -#include namespace TextEditor { class TextDocument; @@ -18,26 +17,8 @@ class Highlighter : public SyntaxHighlighter, public KSyntaxHighlighting::Abstra Q_OBJECT Q_INTERFACES(KSyntaxHighlighting::AbstractHighlighter) public: - using Definition = KSyntaxHighlighting::Definition; - using Definitions = QList; Highlighter(); - static Definition definitionForName(const QString &name); - - static Definitions definitionsForDocument(const TextDocument *document); - static Definitions definitionsForMimeType(const QString &mimeType); - static Definitions definitionsForFileName(const Utils::FilePath &fileName); - - static void rememberDefinitionForDocument(const Definition &definition, - const TextDocument *document); - static void clearDefinitionForDocumentCache(); - - static void addCustomHighlighterPath(const Utils::FilePath &path); - static void downloadDefinitions(std::function callback = nullptr); - static void reload(); - - static void handleShutdown(); - protected: void highlightBlock(const QString &text) override; void applyFormat(int offset, int length, const KSyntaxHighlighting::Format &format) override; diff --git a/src/plugins/texteditor/highlighterhelper.cpp b/src/plugins/texteditor/highlighterhelper.cpp new file mode 100644 index 00000000000..abe8b3ceeca --- /dev/null +++ b/src/plugins/texteditor/highlighterhelper.cpp @@ -0,0 +1,223 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "highlighterhelper.h" + +#include "highlighter.h" +#include "highlightersettings.h" +#include "textdocument.h" +#include "texteditor.h" +#include "texteditorsettings.h" +#include "texteditortr.h" + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +using namespace Utils; + +namespace TextEditor::HighlighterHelper { + +const char kDefinitionForMimeType[] = "definitionForMimeType"; +const char kDefinitionForExtension[] = "definitionForExtension"; +const char kDefinitionForFilePath[] = "definitionForFilePath"; + +static KSyntaxHighlighting::Repository *highlightRepository() +{ + static KSyntaxHighlighting::Repository *repository = nullptr; + if (!repository) { + repository = new KSyntaxHighlighting::Repository(); + repository->addCustomSearchPath( + TextEditorSettings::highlighterSettings().definitionFilesPath().toString()); + const FilePath dir = Core::ICore::resourcePath("generic-highlighter/syntax"); + if (dir.exists()) + repository->addCustomSearchPath(dir.parentDir().path()); + } + return repository; +} + +Definition definitionForName(const QString &name) +{ + return highlightRepository()->definitionForName(name); +} + +Definitions definitionsForDocument(const TextEditor::TextDocument *document) +{ + QTC_ASSERT(document, return {}); + // First try to find definitions for the file path, only afterwards try the MIME type. + // An example where that is important is if there was a definition for "*.rb.xml", which + // cannot be referred to with a MIME type (since there is none), but there is the definition + // for XML files, which specifies a MIME type in addition to a glob pattern. + // If we check the MIME type first and then skip the pattern, the definition for "*.rb.xml" is + // never considered. + // The KSyntaxHighlighting CLI also completely ignores MIME types. + const FilePath &filePath = document->filePath(); + Definitions definitions = definitionsForFileName(filePath); + if (definitions.isEmpty()) { + // check for *.in filename since those are usually used for + // cmake configure_file input filenames without the .in extension + if (filePath.endsWith(".in")) + definitions = definitionsForFileName(FilePath::fromString(filePath.completeBaseName())); + if (filePath.fileName() == "qtquickcontrols2.conf") + definitions = definitionsForFileName(filePath.stringAppended(".ini")); + } + if (definitions.isEmpty()) { + const MimeType &mimeType = Utils::mimeTypeForName(document->mimeType()); + if (mimeType.isValid()) { + Utils::visitMimeParents(mimeType, [&](const MimeType &mt) -> bool { + // highlight definitions might not use the canonical name but an alias + const QStringList names = QStringList(mt.name()) + mt.aliases(); + for (const QString &name : names) { + definitions = definitionsForMimeType(name); + if (!definitions.isEmpty()) + return false; // stop + } + return true; // continue + }); + } + } + + return definitions; +} + +static Definition definitionForSetting(const Key &settingsKey, const QString &mapKey) +{ + QtcSettings *settings = Core::ICore::settings(); + settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY); + const QString &definitionName = settings->value(settingsKey).toMap().value(mapKey).toString(); + settings->endGroup(); + return HighlighterHelper::definitionForName(definitionName); +} + +Definitions definitionsForMimeType(const QString &mimeType) +{ + Definitions definitions = highlightRepository()->definitionsForMimeType(mimeType).toList(); + if (definitions.size() > 1) { + const Definition &rememberedDefinition = definitionForSetting(kDefinitionForMimeType, + mimeType); + if (rememberedDefinition.isValid() && definitions.contains(rememberedDefinition)) + definitions = {rememberedDefinition}; + } + return definitions; +} + +Definitions definitionsForFileName(const FilePath &fileName) +{ + Definitions definitions + = highlightRepository()->definitionsForFileName(fileName.fileName()).toList(); + + if (definitions.size() > 1) { + const QString &fileExtension = fileName.completeSuffix(); + const Definition &rememberedDefinition + = fileExtension.isEmpty() + ? definitionForSetting(kDefinitionForFilePath, + fileName.absoluteFilePath().toString()) + : definitionForSetting(kDefinitionForExtension, fileExtension); + if (rememberedDefinition.isValid() && definitions.contains(rememberedDefinition)) + definitions = {rememberedDefinition}; + } + + return definitions; +} + +void rememberDefinitionForDocument(const Definition &definition, + const TextEditor::TextDocument *document) +{ + QTC_ASSERT(document, return); + if (!definition.isValid()) + return; + const QString &mimeType = document->mimeType(); + const FilePath &path = document->filePath(); + const QString &fileExtension = path.completeSuffix(); + QtcSettings *settings = Core::ICore::settings(); + settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY); + const Definitions &fileNameDefinitions = definitionsForFileName(path); + if (fileNameDefinitions.contains(definition)) { + if (!fileExtension.isEmpty()) { + const Key id(kDefinitionForExtension); + QMap map = settings->value(id).toMap(); + map.insert(fileExtension, definition.name()); + settings->setValue(id, map); + } else if (!path.isEmpty()) { + const Key id(kDefinitionForFilePath); + QMap map = settings->value(id).toMap(); + map.insert(path.absoluteFilePath().toString(), definition.name()); + settings->setValue(id, map); + } + } else if (!mimeType.isEmpty()) { + const Key id(kDefinitionForMimeType); + QMap map = settings->value(id).toMap(); + map.insert(mimeType, definition.name()); + settings->setValue(id, map); + } + settings->endGroup(); +} + +void clearDefinitionForDocumentCache() +{ + QtcSettings *settings = Core::ICore::settings(); + settings->beginGroup(Constants::HIGHLIGHTER_SETTINGS_CATEGORY); + settings->remove(kDefinitionForMimeType); + settings->remove(kDefinitionForExtension); + settings->remove(kDefinitionForFilePath); + settings->endGroup(); +} + +void addCustomHighlighterPath(const FilePath &path) +{ + highlightRepository()->addCustomSearchPath(path.toString()); +} + +void downloadDefinitions(std::function callback) +{ + auto downloader = new KSyntaxHighlighting::DefinitionDownloader(highlightRepository()); + QObject::connect(downloader, + &KSyntaxHighlighting::DefinitionDownloader::done, + [downloader, callback]() { + Core::MessageManager::writeFlashing(Tr::tr("Highlighter updates: done")); + downloader->deleteLater(); + reload(); + if (callback) + callback(); + }); + QObject::connect(downloader, + &KSyntaxHighlighting::DefinitionDownloader::informationMessage, + [](const QString &message) { + Core::MessageManager::writeSilently(Tr::tr("Highlighter updates:") + ' ' + + message); + }); + Core::MessageManager::writeDisrupting(Tr::tr("Highlighter updates: starting")); + downloader->start(); +} + +void reload() +{ + highlightRepository()->reload(); + for (auto editor : Core::DocumentModel::editorsForOpenedDocuments()) { + if (auto textEditor = qobject_cast(editor)) { + if (qobject_cast(textEditor->textDocument()->syntaxHighlighter())) + textEditor->editorWidget()->configureGenericHighlighter(); + } + } +} + +void handleShutdown() +{ + delete highlightRepository(); +} + +} // namespace TextEditor::HighlighterHelper diff --git a/src/plugins/texteditor/highlighterhelper.h b/src/plugins/texteditor/highlighterhelper.h new file mode 100644 index 00000000000..6c2d2e2dc2f --- /dev/null +++ b/src/plugins/texteditor/highlighterhelper.h @@ -0,0 +1,35 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +#include + +namespace TextEditor { +class TextDocument; + +namespace HighlighterHelper { + +using Definition = KSyntaxHighlighting::Definition; +using Definitions = QList; + +Definition definitionForName(const QString &name); + +Definitions definitionsForDocument(const TextDocument *document); +Definitions definitionsForMimeType(const QString &mimeType); +Definitions definitionsForFileName(const Utils::FilePath &fileName); + +void rememberDefinitionForDocument(const Definition &definition, const TextDocument *document); +void clearDefinitionForDocumentCache(); + +void addCustomHighlighterPath(const Utils::FilePath &path); +void downloadDefinitions(std::function callback = nullptr); +void reload(); + +void handleShutdown(); + +} // namespace HighlighterHelper + +} // namespace TextEditor diff --git a/src/plugins/texteditor/highlightersettingspage.cpp b/src/plugins/texteditor/highlightersettingspage.cpp index 8b704a7157a..81eacbe7e06 100644 --- a/src/plugins/texteditor/highlightersettingspage.cpp +++ b/src/plugins/texteditor/highlightersettingspage.cpp @@ -3,8 +3,9 @@ #include "highlightersettingspage.h" -#include "highlightersettings.h" #include "highlighter.h" +#include "highlighterhelper.h" +#include "highlightersettings.h" #include "texteditortr.h" #include @@ -114,17 +115,17 @@ public: connect(downloadDefinitions, &QPushButton::pressed, [label = QPointer(updateStatus)]() { - Highlighter::downloadDefinitions([label] { + HighlighterHelper::downloadDefinitions([label] { if (label) label->setText(Tr::tr("Download finished")); }); }); connect(reloadDefinitions, &QPushButton::pressed, this, [] { - Highlighter::reload(); + HighlighterHelper::reload(); }); connect(resetCache, &QPushButton::clicked, this, [] { - Highlighter::clearDefinitionForDocumentCache(); + HighlighterHelper::clearDefinitionForDocumentCache(); }); } diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 0d433f35c96..8d20a7b23a9 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -17,6 +17,7 @@ #include "extraencodingsettings.h" #include "fontsettings.h" #include "highlighter.h" +#include "highlighterhelper.h" #include "highlightersettings.h" #include "icodestylepreferences.h" #include "marginsettings.h" @@ -724,7 +725,7 @@ public: void updateFileLineEndingVisible(); void reconfigure(); - void updateSyntaxInfoBar(const Highlighter::Definitions &definitions, const QString &fileName); + void updateSyntaxInfoBar(const HighlighterHelper::Definitions &definitions, const QString &fileName); void removeSyntaxInfoBar(); void configureGenericHighlighter(const KSyntaxHighlighting::Definition &definition); void setupFromDefinition(const KSyntaxHighlighting::Definition &definition); @@ -1930,7 +1931,7 @@ void TextEditorWidgetPrivate::foldLicenseHeader() QStringList commentMarker; if (auto highlighter = qobject_cast( q->textDocument()->syntaxHighlighter())) { - const Highlighter::Definition def = highlighter->definition(); + const HighlighterHelper::Definition def = highlighter->definition(); for (const QString &marker : {def.singleLineCommentMarker(), def.multiLineCommentMarker().first}) { if (!marker.isEmpty()) @@ -3638,7 +3639,7 @@ void TextEditorWidgetPrivate::reconfigure() q->configureGenericHighlighter(); } -void TextEditorWidgetPrivate::updateSyntaxInfoBar(const Highlighter::Definitions &definitions, +void TextEditorWidgetPrivate::updateSyntaxInfoBar(const HighlighterHelper::Definitions &definitions, const QString &fileName) { Id missing(Constants::INFO_MISSING_SYNTAX_DEFINITION); @@ -3653,7 +3654,7 @@ void TextEditorWidgetPrivate::updateSyntaxInfoBar(const Highlighter::Definitions InfoBarEntry::GlobalSuppression::Enabled); info.addCustomButton(Tr::tr("Download Definitions"), [missing, this]() { m_document->infoBar()->removeInfo(missing); - Highlighter::downloadDefinitions(); + HighlighterHelper::downloadDefinitions(); }); infoBar->removeInfo(multiple); @@ -3662,9 +3663,9 @@ void TextEditorWidgetPrivate::updateSyntaxInfoBar(const Highlighter::Definitions InfoBarEntry info(multiple, Tr::tr("More than one highlight definition was found for this file. " "Which one should be used to highlight this file?")); - info.setComboInfo(Utils::transform(definitions, &Highlighter::Definition::name), + info.setComboInfo(Utils::transform(definitions, &HighlighterHelper::Definition::name), [this](const InfoBarEntry::ComboInfo &info) { - this->configureGenericHighlighter(Highlighter::definitionForName(info.displayText)); + this->configureGenericHighlighter(HighlighterHelper::definitionForName(info.displayText)); }); info.addCustomButton(Tr::tr("Remember My Choice"), [multiple, this]() { @@ -3733,9 +3734,9 @@ KSyntaxHighlighting::Definition TextEditorWidgetPrivate::currentDefinition() void TextEditorWidgetPrivate::rememberCurrentSyntaxDefinition() { - const Highlighter::Definition &definition = currentDefinition(); + const HighlighterHelper::Definition &definition = currentDefinition(); if (definition.isValid()) - Highlighter::rememberDefinitionForDocument(definition, m_document.data()); + HighlighterHelper::rememberDefinitionForDocument(definition, m_document.data()); } void TextEditorWidgetPrivate::openLinkUnderCursor(bool openInNextSplit) @@ -9250,23 +9251,23 @@ QString TextEditorWidget::textAt(int from, int to) const void TextEditorWidget::configureGenericHighlighter() { - Highlighter::Definitions definitions = Highlighter::definitionsForDocument(textDocument()); - d->configureGenericHighlighter(definitions.isEmpty() ? Highlighter::Definition() + HighlighterHelper::Definitions definitions = HighlighterHelper::definitionsForDocument(textDocument()); + d->configureGenericHighlighter(definitions.isEmpty() ? HighlighterHelper::Definition() : definitions.first()); d->updateSyntaxInfoBar(definitions, textDocument()->filePath().fileName()); } void TextEditorWidget::configureGenericHighlighter(const Utils::MimeType &mimeType) { - Highlighter::Definitions definitions = Highlighter::definitionsForMimeType(mimeType.name()); - d->configureGenericHighlighter(definitions.isEmpty() ? Highlighter::Definition() + HighlighterHelper::Definitions definitions = HighlighterHelper::definitionsForMimeType(mimeType.name()); + d->configureGenericHighlighter(definitions.isEmpty() ? HighlighterHelper::Definition() : definitions.first()); d->removeSyntaxInfoBar(); } expected_str TextEditorWidget::configureGenericHighlighter(const QString &definitionName) { - Highlighter::Definition definition = TextEditor::Highlighter::definitionForName(definitionName); + HighlighterHelper::Definition definition = TextEditor::HighlighterHelper::definitionForName(definitionName); if (!definition.isValid()) return make_unexpected(Tr::tr("Could not find definition.")); diff --git a/src/plugins/texteditor/texteditorplugin.cpp b/src/plugins/texteditor/texteditorplugin.cpp index 95491ba24ae..937cc6ff7ee 100644 --- a/src/plugins/texteditor/texteditorplugin.cpp +++ b/src/plugins/texteditor/texteditorplugin.cpp @@ -9,7 +9,7 @@ #include "findinfiles.h" #include "findinopenfiles.h" #include "fontsettings.h" -#include "highlighter.h" +#include "highlighterhelper.h" #include "icodestylepreferences.h" #include "jsoneditor.h" #include "linenumberfilter.h" @@ -19,7 +19,6 @@ #include "snippets/snippetprovider.h" #include "tabsettings.h" #include "textdocument.h" -#include "textdocument.h" #include "texteditor.h" #include "texteditorconstants.h" #include "texteditorsettings.h" @@ -437,7 +436,7 @@ LineNumberFilter *TextEditorPlugin::lineNumberFilter() ExtensionSystem::IPlugin::ShutdownFlag TextEditorPlugin::aboutToShutdown() { - Highlighter::handleShutdown(); + HighlighterHelper::handleShutdown(); return SynchronousShutdown; } From 400dee55ef5f1229ef569b28bebb8d23f19b2f3a Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Mon, 20 Nov 2023 12:42:48 +0100 Subject: [PATCH 0302/1546] CMake build system: Push some plugins "dependecy levels" up The higher the "level", the more dependencies. Some plugins from that level have less dependencies than their level indicates and can "move up". Change-Id: I2735162ab0b64096f21bc025e3d6ecc7427a5bf4 Reviewed-by: Qt CI Bot Reviewed-by: Eike Ziller --- src/plugins/CMakeLists.txt | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index 15416d790d6..5d07d99608f 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -22,12 +22,15 @@ add_subdirectory(silversearcher) # Level 3: (only depends on Level 2 and below) add_subdirectory(axivion) +add_subdirectory(compilerexplorer) add_subdirectory(cppeditor) add_subdirectory(haskell) add_subdirectory(help) add_subdirectory(resourceeditor) add_subdirectory(nim) add_subdirectory(conan) +add_subdirectory(saferenderer) +add_subdirectory(terminal) add_subdirectory(vcpkg) # Level 4: (only depends on Level 3 and below) @@ -39,10 +42,12 @@ add_subdirectory(todo) add_subdirectory(vcsbase) # Level 5: +add_subdirectory(autotoolsprojectmanager) add_subdirectory(bazaar) add_subdirectory(beautifier) add_subdirectory(clangformat) add_subdirectory(clearcase) +add_subdirectory(cmakeprojectmanager) add_subdirectory(cvs) add_subdirectory(designer) add_subdirectory(docker) @@ -62,27 +67,27 @@ add_subdirectory(languageclient) if (WITH_QMLDESIGNER) add_subdirectory(qmldesignerbase) endif() +add_subdirectory(webassembly) # Level 6: -add_subdirectory(cmakeprojectmanager) add_subdirectory(debugger) add_subdirectory(coco) +add_subdirectory(copilot) add_subdirectory(gitlab) if (WITH_QMLDESIGNER) add_subdirectory(qmlprojectmanager) endif() +add_subdirectory(python) # Level 7: add_subdirectory(android) add_subdirectory(autotest) -add_subdirectory(autotoolsprojectmanager) add_subdirectory(baremetal) add_subdirectory(clangcodemodel) add_subdirectory(clangtools) add_subdirectory(cppcheck) add_subdirectory(incredibuild) add_subdirectory(ios) -add_subdirectory(python) add_subdirectory(qmljseditor) add_subdirectory(qmlpreview) add_subdirectory(qmlprofiler) @@ -108,10 +113,4 @@ if (WITH_QMLDESIGNER) add_subdirectory(insight) endif() add_subdirectory(qnx) -add_subdirectory(webassembly) add_subdirectory(mcusupport) -add_subdirectory(saferenderer) -add_subdirectory(copilot) -add_subdirectory(terminal) - -add_subdirectory(compilerexplorer) From fef6986fa83cfad9f0f5aa8a84bd0bd6f6ca9e94 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 21 Nov 2023 06:46:38 +0100 Subject: [PATCH 0303/1546] TextEditor: Fix Qbs build Amends b26c43f133fd692e6ab7d8fba309f8e5204fd3ec. Change-Id: Ib2dcee8280c1a91f7a8ade344fd43c4ecd787775 Reviewed-by: David Schulz --- src/plugins/texteditor/texteditor.qbs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/texteditor/texteditor.qbs b/src/plugins/texteditor/texteditor.qbs index 0c25f5bf5c6..77f80a51a58 100644 --- a/src/plugins/texteditor/texteditor.qbs +++ b/src/plugins/texteditor/texteditor.qbs @@ -84,6 +84,8 @@ QtcPlugin { "formattexteditor.h", "highlighter.cpp", "highlighter.h", + "highlighterhelper.cpp", + "highlighterhelper.h", "highlightersettings.cpp", "highlightersettings.h", "highlightersettingspage.cpp", From b18b156c71e3b3744816c65edf6ebc48f5dbf8b3 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 14:33:54 +0100 Subject: [PATCH 0304/1546] GenericProject: Consolidate project wizard related classes Change-Id: I61dcd07c27b8d691d8623eaec5d1d0a5fdb96608 Reviewed-by: Jarek Kobus --- .../genericprojectmanager/CMakeLists.txt | 1 - .../filesselectionwizardpage.cpp | 65 ---------- .../filesselectionwizardpage.h | 35 ------ .../genericprojectmanager.qbs | 2 - .../genericprojectplugin.cpp | 2 +- .../genericprojectwizard.cpp | 118 +++++++++++++++++- .../genericprojectwizard.h | 32 +---- 7 files changed, 114 insertions(+), 141 deletions(-) delete mode 100644 src/plugins/genericprojectmanager/filesselectionwizardpage.cpp delete mode 100644 src/plugins/genericprojectmanager/filesselectionwizardpage.h diff --git a/src/plugins/genericprojectmanager/CMakeLists.txt b/src/plugins/genericprojectmanager/CMakeLists.txt index 27c50924d24..27b75f6ecf4 100644 --- a/src/plugins/genericprojectmanager/CMakeLists.txt +++ b/src/plugins/genericprojectmanager/CMakeLists.txt @@ -4,7 +4,6 @@ add_qtc_plugin(GenericProjectManager PLUGIN_TEST_DEPENDS CppEditor PLUGIN_RECOMMENDS CppEditor SOURCES ${TEST_SOURCES} - filesselectionwizardpage.cpp filesselectionwizardpage.h genericbuildconfiguration.cpp genericbuildconfiguration.h genericmakestep.cpp genericmakestep.h genericproject.cpp genericproject.h diff --git a/src/plugins/genericprojectmanager/filesselectionwizardpage.cpp b/src/plugins/genericprojectmanager/filesselectionwizardpage.cpp deleted file mode 100644 index 66fde1ab1d1..00000000000 --- a/src/plugins/genericprojectmanager/filesselectionwizardpage.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "filesselectionwizardpage.h" - -#include "genericprojectconstants.h" -#include "genericprojectmanagertr.h" -#include "genericprojectwizard.h" - -#include -#include -#include - -#include - -#include - -namespace GenericProjectManager { -namespace Internal { - -FilesSelectionWizardPage::FilesSelectionWizardPage(GenericProjectWizardDialog *genericProjectWizard, - QWidget *parent) : - QWizardPage(parent), - m_genericProjectWizardDialog(genericProjectWizard), - m_filesWidget(new ProjectExplorer::SelectableFilesWidget(this)) -{ - auto layout = new QVBoxLayout(this); - - layout->addWidget(m_filesWidget); - m_filesWidget->enableFilterHistoryCompletion - (ProjectExplorer::Constants::ADD_FILES_DIALOG_FILTER_HISTORY_KEY); - m_filesWidget->setBaseDirEditable(false); - connect(m_filesWidget, &ProjectExplorer::SelectableFilesWidget::selectedFilesChanged, - this, &FilesSelectionWizardPage::completeChanged); - - setProperty(Utils::SHORT_TITLE_PROPERTY, Tr::tr("Files")); -} - -void FilesSelectionWizardPage::initializePage() -{ - m_filesWidget->resetModel(m_genericProjectWizardDialog->filePath(), Utils::FilePaths()); -} - -void FilesSelectionWizardPage::cleanupPage() -{ - m_filesWidget->cancelParsing(); -} - -bool FilesSelectionWizardPage::isComplete() const -{ - return m_filesWidget->hasFilesSelected(); -} - -Utils::FilePaths FilesSelectionWizardPage::selectedPaths() const -{ - return m_filesWidget->selectedPaths(); -} - -Utils::FilePaths FilesSelectionWizardPage::selectedFiles() const -{ - return m_filesWidget->selectedFiles(); -} - -} // namespace Internal -} // namespace GenericProjectManager diff --git a/src/plugins/genericprojectmanager/filesselectionwizardpage.h b/src/plugins/genericprojectmanager/filesselectionwizardpage.h deleted file mode 100644 index 6dae77b82ef..00000000000 --- a/src/plugins/genericprojectmanager/filesselectionwizardpage.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -#include - -namespace ProjectExplorer { class SelectableFilesWidget; } - -namespace GenericProjectManager { -namespace Internal { - -class GenericProjectWizardDialog; - -class FilesSelectionWizardPage : public QWizardPage -{ - Q_OBJECT - -public: - FilesSelectionWizardPage(GenericProjectWizardDialog *genericProjectWizard, QWidget *parent = nullptr); - bool isComplete() const override; - void initializePage() override; - void cleanupPage() override; - Utils::FilePaths selectedFiles() const; - Utils::FilePaths selectedPaths() const; - -private: - GenericProjectWizardDialog *m_genericProjectWizardDialog; - ProjectExplorer::SelectableFilesWidget *m_filesWidget; -}; - -} // namespace Internal -} // namespace GenericProjectManager diff --git a/src/plugins/genericprojectmanager/genericprojectmanager.qbs b/src/plugins/genericprojectmanager/genericprojectmanager.qbs index 10b471081ce..4ae706324f9 100644 --- a/src/plugins/genericprojectmanager/genericprojectmanager.qbs +++ b/src/plugins/genericprojectmanager/genericprojectmanager.qbs @@ -21,8 +21,6 @@ QtcPlugin { ] files: [ - "filesselectionwizardpage.cpp", - "filesselectionwizardpage.h", "genericbuildconfiguration.cpp", "genericbuildconfiguration.h", "genericmakestep.cpp", diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.cpp b/src/plugins/genericprojectmanager/genericprojectplugin.cpp index 25721445f5e..98070dd579d 100644 --- a/src/plugins/genericprojectmanager/genericprojectplugin.cpp +++ b/src/plugins/genericprojectmanager/genericprojectplugin.cpp @@ -44,7 +44,7 @@ GenericProjectPluginPrivate::GenericProjectPluginPrivate() { ProjectManager::registerProjectType(Constants::GENERICMIMETYPE); - IWizardFactory::registerFactoryCreator([] { return new GenericProjectWizard; }); + setupGenericProjectWizard(); ActionBuilder editAction(this, "GenericProjectManager.EditFiles"); editAction.setContext(Constants::GENERICPROJECT_ID); diff --git a/src/plugins/genericprojectmanager/genericprojectwizard.cpp b/src/plugins/genericprojectmanager/genericprojectwizard.cpp index 314c850b0d2..02a1d29b0cb 100644 --- a/src/plugins/genericprojectmanager/genericprojectwizard.cpp +++ b/src/plugins/genericprojectmanager/genericprojectwizard.cpp @@ -3,19 +3,22 @@ #include "genericprojectwizard.h" -#include "filesselectionwizardpage.h" #include "genericprojectconstants.h" #include "genericprojectmanagertr.h" #include +#include + +#include #include #include -#include +#include #include #include #include #include +#include #include #include @@ -24,22 +27,100 @@ #include #include #include +#include +#include +using namespace Core; +using namespace ProjectExplorer; using namespace Utils; -namespace GenericProjectManager { -namespace Internal { +namespace GenericProjectManager::Internal { const char ConfigFileTemplate[] = "// Add predefined macros for your project here. For example:\n" "// #define THE_ANSWER 42\n"; + +class GenericProjectWizardDialog; + +class FilesSelectionWizardPage : public QWizardPage +{ +public: + FilesSelectionWizardPage(GenericProjectWizardDialog *genericProjectWizard, QWidget *parent = nullptr); + + bool isComplete() const override; + void initializePage() override; + void cleanupPage() override; + FilePaths selectedFiles() const; + FilePaths selectedPaths() const; + +private: + GenericProjectWizardDialog *m_genericProjectWizardDialog; + ProjectExplorer::SelectableFilesWidget *m_filesWidget; +}; + +FilesSelectionWizardPage::FilesSelectionWizardPage(GenericProjectWizardDialog *genericProjectWizard, + QWidget *parent) : + QWizardPage(parent), + m_genericProjectWizardDialog(genericProjectWizard), + m_filesWidget(new ProjectExplorer::SelectableFilesWidget(this)) +{ + auto layout = new QVBoxLayout(this); + + layout->addWidget(m_filesWidget); + m_filesWidget->enableFilterHistoryCompletion + (ProjectExplorer::Constants::ADD_FILES_DIALOG_FILTER_HISTORY_KEY); + m_filesWidget->setBaseDirEditable(false); + connect(m_filesWidget, &ProjectExplorer::SelectableFilesWidget::selectedFilesChanged, + this, &FilesSelectionWizardPage::completeChanged); + + setProperty(Utils::SHORT_TITLE_PROPERTY, Tr::tr("Files")); +} + +void FilesSelectionWizardPage::cleanupPage() +{ + m_filesWidget->cancelParsing(); +} + +bool FilesSelectionWizardPage::isComplete() const +{ + return m_filesWidget->hasFilesSelected(); +} + +Utils::FilePaths FilesSelectionWizardPage::selectedPaths() const +{ + return m_filesWidget->selectedPaths(); +} + +Utils::FilePaths FilesSelectionWizardPage::selectedFiles() const +{ + return m_filesWidget->selectedFiles(); +} + ////////////////////////////////////////////////////////////////////////////// // // GenericProjectWizardDialog // ////////////////////////////////////////////////////////////////////////////// +class GenericProjectWizardDialog : public Core::BaseFileWizard +{ + Q_OBJECT + +public: + explicit GenericProjectWizardDialog(const Core::BaseFileWizardFactory *factory, QWidget *parent = nullptr); + + Utils::FilePath filePath() const; + void setFilePath(const Utils::FilePath &path); + Utils::FilePaths selectedFiles() const; + Utils::FilePaths selectedPaths() const; + + QString projectName() const; + + Utils::FileWizardPage *m_firstPage; + FilesSelectionWizardPage *m_secondPage; +}; + GenericProjectWizardDialog::GenericProjectWizardDialog(const Core::BaseFileWizardFactory *factory, QWidget *parent) : Core::BaseFileWizard(factory, QVariantMap(), parent) @@ -90,6 +171,20 @@ QString GenericProjectWizardDialog::projectName() const // ////////////////////////////////////////////////////////////////////////////// +class GenericProjectWizard : public Core::BaseFileWizardFactory +{ + Q_OBJECT + +public: + GenericProjectWizard(); + +protected: + Core::BaseFileWizard *create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const override; + Core::GeneratedFiles generateFiles(const QWizard *w, QString *errorMessage) const override; + bool postGenerateFiles(const QWizard *w, const Core::GeneratedFiles &l, + QString *errorMessage) const override; +}; + GenericProjectWizard::GenericProjectWizard() { setSupportedProjectTypes({Constants::GENERICPROJECT_ID}); @@ -198,5 +293,16 @@ bool GenericProjectWizard::postGenerateFiles(const QWizard *w, const Core::Gener return ProjectExplorer::CustomProjectWizard::postGenerateOpen(l, errorMessage); } -} // namespace Internal -} // namespace GenericProjectManager +void FilesSelectionWizardPage::initializePage() +{ + m_filesWidget->resetModel(m_genericProjectWizardDialog->filePath(), Utils::FilePaths()); +} + +void setupGenericProjectWizard() +{ + IWizardFactory::registerFactoryCreator([] { return new GenericProjectWizard; }); +} + +} // GenericProjectManager::Internal + +#include "genericprojectwizard.moc" diff --git a/src/plugins/genericprojectmanager/genericprojectwizard.h b/src/plugins/genericprojectmanager/genericprojectwizard.h index 127fe891986..49f39114c5d 100644 --- a/src/plugins/genericprojectmanager/genericprojectwizard.h +++ b/src/plugins/genericprojectmanager/genericprojectwizard.h @@ -15,37 +15,7 @@ namespace Internal { class FilesSelectionWizardPage; -class GenericProjectWizardDialog : public Core::BaseFileWizard -{ - Q_OBJECT - -public: - explicit GenericProjectWizardDialog(const Core::BaseFileWizardFactory *factory, QWidget *parent = nullptr); - - Utils::FilePath filePath() const; - void setFilePath(const Utils::FilePath &path); - Utils::FilePaths selectedFiles() const; - Utils::FilePaths selectedPaths() const; - - QString projectName() const; - - Utils::FileWizardPage *m_firstPage; - FilesSelectionWizardPage *m_secondPage; -}; - -class GenericProjectWizard : public Core::BaseFileWizardFactory -{ - Q_OBJECT - -public: - GenericProjectWizard(); - -protected: - Core::BaseFileWizard *create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const override; - Core::GeneratedFiles generateFiles(const QWizard *w, QString *errorMessage) const override; - bool postGenerateFiles(const QWizard *w, const Core::GeneratedFiles &l, - QString *errorMessage) const override; -}; +void setupGenericProjectWizard(); } // namespace Internal } // namespace GenericProjectManager From 50b9e601b0305253d5303fb49ea7b910d767d6d1 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 16 Nov 2023 08:18:27 +0100 Subject: [PATCH 0305/1546] LanguageClient: Fix coverity warnings Coverity-Id: 1569380 Change-Id: I925ef9f154f1d4c39d7631a7a94f37be4735aa8c Reviewed-by: David Schulz --- src/plugins/languageclient/languageclientsymbolsupport.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/languageclient/languageclientsymbolsupport.cpp b/src/plugins/languageclient/languageclientsymbolsupport.cpp index 4f93e537f70..e9c4443eed3 100644 --- a/src/plugins/languageclient/languageclientsymbolsupport.cpp +++ b/src/plugins/languageclient/languageclientsymbolsupport.cpp @@ -157,7 +157,6 @@ static MessageId sendGotoRequest(TextEditor::TextDocument *document, handleGotoResponse(response, callback, linkUnderCursor, client); }); return sendTextDocumentPositionParamsRequest(client, request, member); - return request.id(); } bool SymbolSupport::supportsFindLink(TextEditor::TextDocument *document, LinkTarget target) const From 5a3261f15ad4a010e685211b49d6ec7559c0bc77 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 14:57:22 +0100 Subject: [PATCH 0306/1546] GenericProject: Code cosmetics Compactify genericprojectwizard.cpp a bit. Also, rename GenericProjectWizard to GenericProjectWizardFactory and GenericProjectWizardDialog to GenericProjectWizard. That's what they are. Change-Id: I9a7ac55b047cc9e40cb0c4f7f25bc6239686bf99 Reviewed-by: Jarek Kobus --- .../genericprojectwizard.cpp | 414 ++++++++---------- 1 file changed, 192 insertions(+), 222 deletions(-) diff --git a/src/plugins/genericprojectmanager/genericprojectwizard.cpp b/src/plugins/genericprojectmanager/genericprojectwizard.cpp index 02a1d29b0cb..ae7e421c293 100644 --- a/src/plugins/genericprojectmanager/genericprojectwizard.cpp +++ b/src/plugins/genericprojectmanager/genericprojectwizard.cpp @@ -24,9 +24,7 @@ #include #include #include -#include #include -#include #include #include @@ -40,267 +38,239 @@ const char ConfigFileTemplate[] = "// Add predefined macros for your project here. For example:\n" "// #define THE_ANSWER 42\n"; +class GenericProjectWizard; -class GenericProjectWizardDialog; - -class FilesSelectionWizardPage : public QWizardPage +class FilesSelectionWizardPage final : public QWizardPage { public: - FilesSelectionWizardPage(GenericProjectWizardDialog *genericProjectWizard, QWidget *parent = nullptr); + explicit FilesSelectionWizardPage(GenericProjectWizard *genericProjectWizard) + : m_genericProjectWizardDialog(genericProjectWizard), + m_filesWidget(new SelectableFilesWidget(this)) + { + auto layout = new QVBoxLayout(this); - bool isComplete() const override; - void initializePage() override; - void cleanupPage() override; - FilePaths selectedFiles() const; - FilePaths selectedPaths() const; + layout->addWidget(m_filesWidget); + m_filesWidget->enableFilterHistoryCompletion + (ProjectExplorer::Constants::ADD_FILES_DIALOG_FILTER_HISTORY_KEY); + m_filesWidget->setBaseDirEditable(false); + connect(m_filesWidget, &SelectableFilesWidget::selectedFilesChanged, + this, &FilesSelectionWizardPage::completeChanged); + + setProperty(SHORT_TITLE_PROPERTY, Tr::tr("Files")); + } + + bool isComplete() const final + { + return m_filesWidget->hasFilesSelected(); + } + + void initializePage() final; + + void cleanupPage() final + { + m_filesWidget->cancelParsing(); + } + + FilePaths selectedFiles() const + { + return m_filesWidget->selectedFiles(); + } + + FilePaths selectedPaths() const + { + return m_filesWidget->selectedPaths(); + } private: - GenericProjectWizardDialog *m_genericProjectWizardDialog; - ProjectExplorer::SelectableFilesWidget *m_filesWidget; + GenericProjectWizard *m_genericProjectWizardDialog; + SelectableFilesWidget *m_filesWidget; }; -FilesSelectionWizardPage::FilesSelectionWizardPage(GenericProjectWizardDialog *genericProjectWizard, - QWidget *parent) : - QWizardPage(parent), - m_genericProjectWizardDialog(genericProjectWizard), - m_filesWidget(new ProjectExplorer::SelectableFilesWidget(this)) -{ - auto layout = new QVBoxLayout(this); - - layout->addWidget(m_filesWidget); - m_filesWidget->enableFilterHistoryCompletion - (ProjectExplorer::Constants::ADD_FILES_DIALOG_FILTER_HISTORY_KEY); - m_filesWidget->setBaseDirEditable(false); - connect(m_filesWidget, &ProjectExplorer::SelectableFilesWidget::selectedFilesChanged, - this, &FilesSelectionWizardPage::completeChanged); - - setProperty(Utils::SHORT_TITLE_PROPERTY, Tr::tr("Files")); -} - -void FilesSelectionWizardPage::cleanupPage() -{ - m_filesWidget->cancelParsing(); -} - -bool FilesSelectionWizardPage::isComplete() const -{ - return m_filesWidget->hasFilesSelected(); -} - -Utils::FilePaths FilesSelectionWizardPage::selectedPaths() const -{ - return m_filesWidget->selectedPaths(); -} - -Utils::FilePaths FilesSelectionWizardPage::selectedFiles() const -{ - return m_filesWidget->selectedFiles(); -} - -////////////////////////////////////////////////////////////////////////////// -// -// GenericProjectWizardDialog -// -////////////////////////////////////////////////////////////////////////////// - -class GenericProjectWizardDialog : public Core::BaseFileWizard -{ - Q_OBJECT - -public: - explicit GenericProjectWizardDialog(const Core::BaseFileWizardFactory *factory, QWidget *parent = nullptr); - - Utils::FilePath filePath() const; - void setFilePath(const Utils::FilePath &path); - Utils::FilePaths selectedFiles() const; - Utils::FilePaths selectedPaths() const; - - QString projectName() const; - - Utils::FileWizardPage *m_firstPage; - FilesSelectionWizardPage *m_secondPage; -}; - -GenericProjectWizardDialog::GenericProjectWizardDialog(const Core::BaseFileWizardFactory *factory, - QWidget *parent) : - Core::BaseFileWizard(factory, QVariantMap(), parent) -{ - setWindowTitle(Tr::tr("Import Existing Project")); - - // first page - m_firstPage = new Utils::FileWizardPage; - m_firstPage->setTitle(Tr::tr("Project Name and Location")); - m_firstPage->setFileNameLabel(Tr::tr("Project name:")); - m_firstPage->setPathLabel(Tr::tr("Location:")); - addPage(m_firstPage); - - // second page - m_secondPage = new FilesSelectionWizardPage(this); - m_secondPage->setTitle(Tr::tr("File Selection")); - addPage(m_secondPage); -} - -FilePath GenericProjectWizardDialog::filePath() const -{ - return m_firstPage->filePath(); -} - -FilePaths GenericProjectWizardDialog::selectedPaths() const -{ - return m_secondPage->selectedPaths(); -} - -FilePaths GenericProjectWizardDialog::selectedFiles() const -{ - return m_secondPage->selectedFiles(); -} - -void GenericProjectWizardDialog::setFilePath(const FilePath &path) -{ - m_firstPage->setFilePath(path); -} - -QString GenericProjectWizardDialog::projectName() const -{ - return m_firstPage->fileName(); -} - ////////////////////////////////////////////////////////////////////////////// // // GenericProjectWizard // ////////////////////////////////////////////////////////////////////////////// -class GenericProjectWizard : public Core::BaseFileWizardFactory +class GenericProjectWizard final : public BaseFileWizard { Q_OBJECT public: - GenericProjectWizard(); + GenericProjectWizard(const BaseFileWizardFactory *factory, QWidget *parent) + : BaseFileWizard(factory, QVariantMap(), parent) + { + setWindowTitle(Tr::tr("Import Existing Project")); -protected: - Core::BaseFileWizard *create(QWidget *parent, const Core::WizardDialogParameters ¶meters) const override; - Core::GeneratedFiles generateFiles(const QWizard *w, QString *errorMessage) const override; - bool postGenerateFiles(const QWizard *w, const Core::GeneratedFiles &l, - QString *errorMessage) const override; + // first page + m_firstPage = new FileWizardPage; + m_firstPage->setTitle(Tr::tr("Project Name and Location")); + m_firstPage->setFileNameLabel(Tr::tr("Project name:")); + m_firstPage->setPathLabel(Tr::tr("Location:")); + addPage(m_firstPage); + + // second page + m_secondPage = new FilesSelectionWizardPage(this); + m_secondPage->setTitle(Tr::tr("File Selection")); + addPage(m_secondPage); + } + + FilePath filePath() const + { + return m_firstPage->filePath(); + } + + void setFilePath(const FilePath &path) + { + m_firstPage->setFilePath(path); + } + + FilePaths selectedFiles() const + { + return m_secondPage->selectedFiles(); + } + + FilePaths selectedPaths() const + { + return m_secondPage->selectedPaths(); + } + + QString projectName() const + { + return m_firstPage->fileName(); + } + + FileWizardPage *m_firstPage; + FilesSelectionWizardPage *m_secondPage; }; -GenericProjectWizard::GenericProjectWizard() +////////////////////////////////////////////////////////////////////////////// +// +// GenericProjectWizardFactory +// +////////////////////////////////////////////////////////////////////////////// + +class GenericProjectWizardFactory final : public BaseFileWizardFactory { - setSupportedProjectTypes({Constants::GENERICPROJECT_ID}); - setIcon(ProjectExplorer::Icons::WIZARD_IMPORT_AS_PROJECT.icon()); - setDisplayName(Tr::tr("Import Existing Project")); - setId("Z.Makefile"); - setDescription( - Tr::tr("Imports existing projects that do not use qmake, CMake, Qbs, Meson, or Autotools. " - "This allows you to use %1 as a code editor.") - .arg(QGuiApplication::applicationDisplayName())); - setCategory(QLatin1String(ProjectExplorer::Constants::IMPORT_WIZARD_CATEGORY)); - setDisplayCategory(QLatin1String(ProjectExplorer::Constants::IMPORT_WIZARD_CATEGORY_DISPLAY)); - setFlags(Core::IWizardFactory::PlatformIndependent); -} + Q_OBJECT -Core::BaseFileWizard *GenericProjectWizard::create(QWidget *parent, - const Core::WizardDialogParameters ¶meters) const -{ - auto wizard = new GenericProjectWizardDialog(this, parent); - wizard->setFilePath(parameters.defaultPath()); - const QList pages = wizard->extensionPages(); - for (QWizardPage *p : pages) - wizard->addPage(p); - - return wizard; -} - -Core::GeneratedFiles GenericProjectWizard::generateFiles(const QWizard *w, - QString *errorMessage) const -{ - Q_UNUSED(errorMessage) - - auto wizard = qobject_cast(w); - const FilePath projectPath = wizard->filePath(); - const QString projectName = wizard->projectName(); - const FilePath creatorFileName = projectPath.pathAppended(projectName + ".creator"); - const FilePath filesFileName = projectPath.pathAppended(projectName + ".files"); - const FilePath includesFileName = projectPath.pathAppended(projectName + ".includes"); - const FilePath configFileName = projectPath.pathAppended(projectName + ".config"); - const FilePath cxxflagsFileName = projectPath.pathAppended(projectName + ".cxxflags"); - const FilePath cflagsFileName = projectPath.pathAppended(projectName + ".cflags"); - const QStringList paths = Utils::transform(wizard->selectedPaths(), &Utils::FilePath::toString); - - Utils::MimeType headerTy = Utils::mimeTypeForName(QLatin1String("text/x-chdr")); - - QStringList nameFilters = headerTy.globPatterns(); - - QStringList includePaths; - const QDir dir(projectPath.toString()); - for (const QString &path : paths) { - QFileInfo fileInfo(path); - if (fileInfo.fileName() != "include") - continue; - QDir thisDir(fileInfo.absoluteFilePath()); - - if (! thisDir.entryList(nameFilters, QDir::Files).isEmpty()) { - QString relative = dir.relativeFilePath(path); - if (relative.isEmpty()) - relative = QLatin1Char('.'); - includePaths.append(relative); - } +public: + GenericProjectWizardFactory() + { + setSupportedProjectTypes({Constants::GENERICPROJECT_ID}); + setIcon(ProjectExplorer::Icons::WIZARD_IMPORT_AS_PROJECT.icon()); + setDisplayName(Tr::tr("Import Existing Project")); + setId("Z.Makefile"); + setDescription( + Tr::tr("Imports existing projects that do not use qmake, CMake, Qbs, Meson, or Autotools. " + "This allows you to use %1 as a code editor.") + .arg(QGuiApplication::applicationDisplayName())); + setCategory(QLatin1String(ProjectExplorer::Constants::IMPORT_WIZARD_CATEGORY)); + setDisplayCategory(QLatin1String(ProjectExplorer::Constants::IMPORT_WIZARD_CATEGORY_DISPLAY)); + setFlags(IWizardFactory::PlatformIndependent); } - includePaths.append(QString()); // ensure newline at EOF - Core::GeneratedFile generatedCreatorFile(creatorFileName); - generatedCreatorFile.setContents(QLatin1String("[General]\n")); - generatedCreatorFile.setAttributes(Core::GeneratedFile::OpenProjectAttribute); +protected: + BaseFileWizard *create(QWidget *parent, const WizardDialogParameters ¶meters) const final + { + auto wizard = new GenericProjectWizard(this, parent); + wizard->setFilePath(parameters.defaultPath()); + const QList pages = wizard->extensionPages(); + for (QWizardPage *p : pages) + wizard->addPage(p); - QStringList sources = Utils::transform(wizard->selectedFiles(), &Utils::FilePath::toString); - for (int i = 0; i < sources.length(); ++i) - sources[i] = dir.relativeFilePath(sources[i]); - Utils::sort(sources); - sources.append(QString()); // ensure newline at EOF + return wizard; + } - Core::GeneratedFile generatedFilesFile(filesFileName); - generatedFilesFile.setContents(sources.join(QLatin1Char('\n'))); + GeneratedFiles generateFiles(const QWizard *w, QString *errorMessage) const final + { + Q_UNUSED(errorMessage) - Core::GeneratedFile generatedIncludesFile(includesFileName); - generatedIncludesFile.setContents(includePaths.join(QLatin1Char('\n'))); + auto wizard = qobject_cast(w); + const FilePath projectPath = wizard->filePath(); + const QString projectName = wizard->projectName(); + const FilePath creatorFileName = projectPath.pathAppended(projectName + ".creator"); + const FilePath filesFileName = projectPath.pathAppended(projectName + ".files"); + const FilePath includesFileName = projectPath.pathAppended(projectName + ".includes"); + const FilePath configFileName = projectPath.pathAppended(projectName + ".config"); + const FilePath cxxflagsFileName = projectPath.pathAppended(projectName + ".cxxflags"); + const FilePath cflagsFileName = projectPath.pathAppended(projectName + ".cflags"); + const QStringList paths = Utils::transform(wizard->selectedPaths(), &FilePath::toString); - Core::GeneratedFile generatedConfigFile(configFileName); - generatedConfigFile.setContents(QLatin1String(ConfigFileTemplate)); + MimeType headerTy = Utils::mimeTypeForName(QLatin1String("text/x-chdr")); - Core::GeneratedFile generatedCxxFlagsFile(cxxflagsFileName); - generatedCxxFlagsFile.setContents( - QLatin1String(Constants::GENERICPROJECT_CXXFLAGS_FILE_TEMPLATE)); + QStringList nameFilters = headerTy.globPatterns(); - Core::GeneratedFile generatedCFlagsFile(cflagsFileName); - generatedCFlagsFile.setContents(QLatin1String(Constants::GENERICPROJECT_CFLAGS_FILE_TEMPLATE)); + QStringList includePaths; + const QDir dir(projectPath.toString()); + for (const QString &path : paths) { + QFileInfo fileInfo(path); + if (fileInfo.fileName() != "include") + continue; + QDir thisDir(fileInfo.absoluteFilePath()); - Core::GeneratedFiles files; - files.append(generatedFilesFile); - files.append(generatedIncludesFile); - files.append(generatedConfigFile); - files.append(generatedCreatorFile); - files.append(generatedCxxFlagsFile); - files.append(generatedCFlagsFile); + if (! thisDir.entryList(nameFilters, QDir::Files).isEmpty()) { + QString relative = dir.relativeFilePath(path); + if (relative.isEmpty()) + relative = QLatin1Char('.'); + includePaths.append(relative); + } + } + includePaths.append(QString()); // ensure newline at EOF - return files; -} + GeneratedFile generatedCreatorFile(creatorFileName); + generatedCreatorFile.setContents(QLatin1String("[General]\n")); + generatedCreatorFile.setAttributes(GeneratedFile::OpenProjectAttribute); -bool GenericProjectWizard::postGenerateFiles(const QWizard *w, const Core::GeneratedFiles &l, - QString *errorMessage) const -{ - Q_UNUSED(w) - return ProjectExplorer::CustomProjectWizard::postGenerateOpen(l, errorMessage); -} + QStringList sources = Utils::transform(wizard->selectedFiles(), &FilePath::toString); + for (int i = 0; i < sources.length(); ++i) + sources[i] = dir.relativeFilePath(sources[i]); + Utils::sort(sources); + sources.append(QString()); // ensure newline at EOF + + GeneratedFile generatedFilesFile(filesFileName); + generatedFilesFile.setContents(sources.join(QLatin1Char('\n'))); + + GeneratedFile generatedIncludesFile(includesFileName); + generatedIncludesFile.setContents(includePaths.join(QLatin1Char('\n'))); + + GeneratedFile generatedConfigFile(configFileName); + generatedConfigFile.setContents(QLatin1String(ConfigFileTemplate)); + + GeneratedFile generatedCxxFlagsFile(cxxflagsFileName); + generatedCxxFlagsFile.setContents( + QLatin1String(Constants::GENERICPROJECT_CXXFLAGS_FILE_TEMPLATE)); + + GeneratedFile generatedCFlagsFile(cflagsFileName); + generatedCFlagsFile.setContents(QLatin1String(Constants::GENERICPROJECT_CFLAGS_FILE_TEMPLATE)); + + GeneratedFiles files; + files.append(generatedFilesFile); + files.append(generatedIncludesFile); + files.append(generatedConfigFile); + files.append(generatedCreatorFile); + files.append(generatedCxxFlagsFile); + files.append(generatedCFlagsFile); + + return files; + } + + bool postGenerateFiles(const QWizard *w, const GeneratedFiles &l, + QString *errorMessage) const final + { + Q_UNUSED(w) + return CustomProjectWizard::postGenerateOpen(l, errorMessage); + } +}; void FilesSelectionWizardPage::initializePage() { - m_filesWidget->resetModel(m_genericProjectWizardDialog->filePath(), Utils::FilePaths()); + m_filesWidget->resetModel(m_genericProjectWizardDialog->filePath(), FilePaths()); } void setupGenericProjectWizard() { - IWizardFactory::registerFactoryCreator([] { return new GenericProjectWizard; }); + IWizardFactory::registerFactoryCreator([] { return new GenericProjectWizardFactory; }); } } // GenericProjectManager::Internal From 102a3474e0997bb1084fbc8d4a74cff54e37795b Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 16 Nov 2023 09:09:38 +0100 Subject: [PATCH 0307/1546] AutoTest: Fix coverity warning Coverity-Id: 1360896 Change-Id: Icd284ec2b227eec314ec340c201b3fe4baeb529b Reviewed-by: David Schulz --- src/plugins/autotest/testresultdelegate.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/autotest/testresultdelegate.h b/src/plugins/autotest/testresultdelegate.h index f7d6aa1ab27..b5d988adb65 100644 --- a/src/plugins/autotest/testresultdelegate.h +++ b/src/plugins/autotest/testresultdelegate.h @@ -30,7 +30,7 @@ private: mutable QModelIndex m_lastProcessedIndex; mutable QFont m_lastProcessedFont; mutable QTextLayout m_lastCalculatedLayout; - mutable int m_lastCalculatedHeight; + mutable int m_lastCalculatedHeight = 0; mutable int m_lastWidth = -1; class LayoutPositions From 181b362fcf16bd420d51d80df4189e1e6f5dbefe Mon Sep 17 00:00:00 2001 From: hjk Date: Thu, 16 Nov 2023 19:21:46 +0100 Subject: [PATCH 0308/1546] Core: Use more ActionBuilder in EditorManager Change-Id: I5d1330536c0a6f60185a2e62fad35599f6e5698f Reviewed-by: Eike Ziller --- .../actionmanager/actionmanager.cpp | 8 +- .../coreplugin/actionmanager/actionmanager.h | 1 + .../editormanager/editormanager.cpp | 290 ++++++++++-------- .../editormanager/editormanager_p.h | 70 ++--- 4 files changed, 200 insertions(+), 169 deletions(-) diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index dcaa32115b6..90c52f16ef3 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -84,7 +84,7 @@ public: void registerAction() { QTC_ASSERT(actionId.isValid(), return); - ActionManager::registerAction(action, actionId, context); + ActionManager::registerAction(action, actionId, context, scriptable); } ParameterAction *action = nullptr; @@ -92,6 +92,7 @@ public: Id actionId; Context context{Constants::C_GLOBAL}; + bool scriptable = false; }; ActionBuilder::ActionBuilder(QObject *contextActionParent, const Id actionId) @@ -210,6 +211,11 @@ void ActionBuilder::setCheckable(bool on) d->action->setCheckable(on); } +void ActionBuilder::setScriptable(bool on) +{ + d->scriptable = on; +} + void ActionBuilder::setMenuRole(QAction::MenuRole role) { d->action->setMenuRole(role); diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.h b/src/plugins/coreplugin/actionmanager/actionmanager.h index 3e869c064da..ce6f12a4938 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager.h @@ -57,6 +57,7 @@ public: void setChecked(bool on); void setVisible(bool on); void setCheckable(bool on); + void setScriptable(bool on); void setMenuRole(QAction::MenuRole role); enum EnablingMode { AlwaysEnabled, EnabledWithParameter }; diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index c41a3a880eb..12157ffc071 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -362,18 +362,6 @@ static void setFocusToEditorViewAndUnmaximizePanes(EditorView *view) EditorManagerPrivate::EditorManagerPrivate(QObject *parent) : QObject(parent), - m_revertToSavedAction(new QAction(::Core::Tr::tr("Revert to Saved"), this)), - m_saveAction(new QAction(this)), - m_saveAsAction(new QAction(this)), - m_closeCurrentEditorAction(new QAction(::Core::Tr::tr("Close"), this)), - m_closeAllEditorsAction(new QAction(::Core::Tr::tr("Close All"), this)), - m_closeOtherDocumentsAction(new QAction(::Core::Tr::tr("Close Others"), this)), - m_closeAllEditorsExceptVisibleAction(new QAction(::Core::Tr::tr("Close All Except Visible"), this)), - m_gotoNextDocHistoryAction(new QAction(::Core::Tr::tr("Next Open Document in History"), this)), - m_gotoPreviousDocHistoryAction(new QAction(::Core::Tr::tr("Previous Open Document in History"), this)), - m_goBackAction(new QAction(Utils::Icons::PREV.icon(), ::Core::Tr::tr("Go Back"), this)), - m_goForwardAction(new QAction(Utils::Icons::NEXT.icon(), ::Core::Tr::tr("Go Forward"), this)), - m_gotoLastEditAction(new QAction(::Core::Tr::tr("Go to Last Edit"), this)), m_copyFilePathContextAction(new QAction(::Core::Tr::tr("Copy Full Path"), this)), m_copyLocationContextAction(new QAction(::Core::Tr::tr("Copy Path and Line Number"), this)), m_copyFileNameContextAction(new QAction(::Core::Tr::tr("Copy File Name"), this)), @@ -384,9 +372,7 @@ EditorManagerPrivate::EditorManagerPrivate(QObject *parent) : m_closeAllEditorsContextAction(new QAction(::Core::Tr::tr("Close All"), this)), m_closeOtherDocumentsContextAction(new QAction(::Core::Tr::tr("Close Others"), this)), m_closeAllEditorsExceptVisibleContextAction(new QAction(::Core::Tr::tr("Close All Except Visible"), this)), - m_openGraphicalShellAction(new QAction(FileUtils::msgGraphicalShellAction(), this)), m_openGraphicalShellContextAction(new QAction(FileUtils::msgGraphicalShellAction(), this)), - m_showInFileSystemViewAction(new QAction(FileUtils::msgFileSystemAction(), this)), m_showInFileSystemViewContextAction(new QAction(FileUtils::msgFileSystemAction(), this)), m_openTerminalAction(new QAction(FileUtils::msgTerminalHereAction(), this)), m_findInDirectoryAction(new QAction(FileUtils::msgFindInDirectory(), this)), @@ -428,24 +414,28 @@ void EditorManagerPrivate::init() // combined context for edit & design modes const Context editDesignContext(Constants::C_EDITORMANAGER, Constants::C_DESIGN_MODE); - ActionContainer *mfile = ActionManager::actionContainer(Constants::M_FILE); - // Revert to saved - m_revertToSavedAction->setIcon(Icon::fromTheme("document-revert")); - Command *cmd = ActionManager::registerAction(m_revertToSavedAction, - Constants::REVERTTOSAVED, editManagerContext); - cmd->setAttribute(Command::CA_UpdateText); - cmd->setDescription(::Core::Tr::tr("Revert File to Saved")); - mfile->addAction(cmd, Constants::G_FILE_SAVE); - connect(m_revertToSavedAction, &QAction::triggered, m_instance, &EditorManager::revertToSaved); + ActionBuilder revertToSaved(this, Constants::REVERTTOSAVED); + revertToSaved.setText(::Core::Tr::tr("Revert to Saved")); + revertToSaved.setIcon(Icon::fromTheme("document-revert")); + revertToSaved.setContext(editManagerContext); + revertToSaved.bindContextAction(&m_revertToSavedAction); + revertToSaved.setCommandAttribute(Command::CA_UpdateText); + revertToSaved.setCommandDescription(::Core::Tr::tr("Revert File to Saved")); + revertToSaved.setContainer(Constants::M_FILE, Constants::G_FILE_SAVE); + revertToSaved.setOnTriggered(this, &EditorManager::revertToSaved); // Save Action - ActionManager::registerAction(m_saveAction, Constants::SAVE, editManagerContext); - connect(m_saveAction, &QAction::triggered, m_instance, [] { EditorManager::saveDocument(); }); + ActionBuilder save(this, Constants::SAVE); + save.setContext(editManagerContext); + save.bindContextAction(&m_saveAction); + save.setOnTriggered(this, [this] { EditorManager::saveDocument(); }); // Save As Action - ActionManager::registerAction(m_saveAsAction, Constants::SAVEAS, editManagerContext); - connect(m_saveAsAction, &QAction::triggered, m_instance, &EditorManager::saveDocumentAs); + ActionBuilder saveAs(this, Constants::SAVEAS); + saveAs.setContext(editManagerContext); + saveAs.bindContextAction(&m_saveAsAction); + saveAs.setOnTriggered(this, &EditorManager::saveDocumentAs); // Window Menu ActionContainer *mwindow = ActionManager::actionContainer(Constants::M_WINDOW); @@ -455,49 +445,59 @@ void EditorManagerPrivate::init() mwindow->addSeparator(editManagerContext, Constants::G_WINDOW_NAVIGATE); // Close Action - cmd = ActionManager::registerAction(m_closeCurrentEditorAction, Constants::CLOSE, editManagerContext, true); - cmd->setDefaultKeySequence(QKeySequence(::Core::Tr::tr("Ctrl+W"))); - cmd->setAttribute(Command::CA_UpdateText); - cmd->setDescription(m_closeCurrentEditorAction->text()); - mfile->addAction(cmd, Constants::G_FILE_CLOSE); - connect(m_closeCurrentEditorAction, &QAction::triggered, - m_instance, &EditorManager::slotCloseCurrentEditorOrDocument); + ActionBuilder closeCurrentEditor(this, Constants::CLOSE); + closeCurrentEditor.bindContextAction(&m_closeCurrentEditorAction); + closeCurrentEditor.setContext(editManagerContext); + closeCurrentEditor.setScriptable(true); + closeCurrentEditor.setDefaultKeySequence(::Core::Tr::tr("Ctrl+W")); + closeCurrentEditor.setCommandAttribute(Command::CA_UpdateText); + closeCurrentEditor.setCommandDescription(m_closeCurrentEditorAction->text()); + closeCurrentEditor.setContainer(Constants::M_FILE, Constants::G_FILE_CLOSE); + closeCurrentEditor.setOnTriggered(this, &EditorManager::slotCloseCurrentEditorOrDocument); if (HostOsInfo::isWindowsHost()) { // workaround for QTCREATORBUG-72 - QAction *action = new QAction(::Core::Tr::tr("Alternative Close"), this); - cmd = ActionManager::registerAction(action, Constants::CLOSE_ALTERNATIVE, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(::Core::Tr::tr("Ctrl+F4"))); - cmd->setDescription(::Core::Tr::tr("Close")); - connect(action, &QAction::triggered, - m_instance, &EditorManager::slotCloseCurrentEditorOrDocument); + ActionBuilder workaround(this, Constants::CLOSE_ALTERNATIVE); + workaround.setContext(editManagerContext); + workaround.setDefaultKeySequence(::Core::Tr::tr("Ctrl+F4")); + workaround.setCommandDescription(::Core::Tr::tr("Close")); + workaround.setOnTriggered(this, &EditorManager::slotCloseCurrentEditorOrDocument); } // Close All Action - cmd = ActionManager::registerAction(m_closeAllEditorsAction, Constants::CLOSEALL, editManagerContext, true); - cmd->setDefaultKeySequence(QKeySequence(::Core::Tr::tr("Ctrl+Shift+W"))); - mfile->addAction(cmd, Constants::G_FILE_CLOSE); - connect(m_closeAllEditorsAction, &QAction::triggered, m_instance, &EditorManager::closeAllDocuments); + ActionBuilder closeAll(this, Constants::CLOSEALL); + closeAll.setText(::Core::Tr::tr("Close All")); + closeAll.setContext(editManagerContext); + closeAll.setScriptable(true); + closeAll.bindContextAction(&m_closeAllEditorsAction); + closeAll.setDefaultKeySequence(::Core::Tr::tr("Ctrl+Shift+W")); + closeAll.setContainer(Constants::M_FILE, Constants::G_FILE_CLOSE); + closeAll.setOnTriggered(this, &EditorManager::closeAllDocuments); // Close All Others Action - cmd = ActionManager::registerAction(m_closeOtherDocumentsAction, Constants::CLOSEOTHERS, editManagerContext, true); - mfile->addAction(cmd, Constants::G_FILE_CLOSE); - cmd->setAttribute(Command::CA_UpdateText); - connect(m_closeOtherDocumentsAction, &QAction::triggered, - m_instance, [] { EditorManager::closeOtherDocuments(); }); + ActionBuilder closeOthers(this, Constants::CLOSEOTHERS); + closeOthers.setText(::Core::Tr::tr("Close Others")); + closeOthers.bindContextAction(&m_closeOtherDocumentsAction); + closeOthers.setContext(editManagerContext); + closeOthers.setScriptable(true); + closeOthers.setContainer(Constants::M_FILE, Constants::G_FILE_CLOSE); + closeOthers.setCommandAttribute(Command::CA_UpdateText); + closeOthers.setOnTriggered(this, [] { EditorManager::closeOtherDocuments(); }); // Close All Others Except Visible Action - cmd = ActionManager::registerAction(m_closeAllEditorsExceptVisibleAction, Constants::CLOSEALLEXCEPTVISIBLE, editManagerContext, true); - mfile->addAction(cmd, Constants::G_FILE_CLOSE); - connect(m_closeAllEditorsExceptVisibleAction, - &QAction::triggered, - this, - &EditorManagerPrivate::closeAllEditorsExceptVisible); + ActionBuilder closeAllExceptVisible(this, Constants::CLOSEALLEXCEPTVISIBLE); + closeAllExceptVisible.setText(::Core::Tr::tr("Close All Except Visible")); + closeAllExceptVisible.bindContextAction(&m_closeAllEditorsExceptVisibleAction); + closeAllExceptVisible.setContext(editManagerContext); + closeAllExceptVisible.setScriptable(true); + closeAllExceptVisible.setContainer(Constants::M_FILE, Constants::G_FILE_CLOSE); + closeAllExceptVisible.setOnTriggered(this, &EditorManagerPrivate::closeAllEditorsExceptVisible); - cmd = ActionManager::registerAction(m_openGraphicalShellAction, - Constants::SHOWINGRAPHICALSHELL, - editManagerContext); - connect(m_openGraphicalShellAction, &QAction::triggered, this, [] { + ActionBuilder openGraphicalShell(this, Constants::SHOWINGRAPHICALSHELL); + openGraphicalShell.setText(FileUtils::msgGraphicalShellAction()); + openGraphicalShell.bindContextAction(&m_openGraphicalShellAction); + openGraphicalShell.setContext(editManagerContext); + openGraphicalShell.setOnTriggered(this, [] { if (!EditorManager::currentDocument()) return; const FilePath fp = EditorManager::currentDocument()->filePath(); @@ -505,10 +505,11 @@ void EditorManagerPrivate::init() FileUtils::showInGraphicalShell(ICore::dialogParent(), fp); }); - cmd = ActionManager::registerAction(m_showInFileSystemViewAction, - Constants::SHOWINFILESYSTEMVIEW, - editManagerContext); - connect(m_showInFileSystemViewAction, &QAction::triggered, this, [] { + ActionBuilder showInFileSystem(this, Constants::SHOWINFILESYSTEMVIEW); + showInFileSystem.setText(FileUtils::msgFileSystemAction()); + showInFileSystem.setContext(editManagerContext); + showInFileSystem.bindContextAction(&m_showInFileSystemViewAction); + showInFileSystem.setOnTriggered(this, [] { if (!EditorManager::currentDocument()) return; const FilePath fp = EditorManager::currentDocument()->filePath(); @@ -553,93 +554,116 @@ void EditorManagerPrivate::init() connect(m_openTerminalAction, &QAction::triggered, this, &EditorManagerPrivate::openTerminal); connect(m_findInDirectoryAction, &QAction::triggered, this, &EditorManagerPrivate::findInDirectory); - connect(m_filePropertiesAction, &QAction::triggered, this, [] { - if (!d->m_contextMenuEntry || d->m_contextMenuEntry->filePath().isEmpty()) + connect(m_filePropertiesAction, &QAction::triggered, this, [this] { + if (!m_contextMenuEntry || m_contextMenuEntry->filePath().isEmpty()) return; - DocumentManager::showFilePropertiesDialog(d->m_contextMenuEntry->filePath()); + DocumentManager::showFilePropertiesDialog(m_contextMenuEntry->filePath()); }); connect(m_pinAction, &QAction::triggered, this, &EditorManagerPrivate::togglePinned); // Goto Previous In History Action - cmd = ActionManager::registerAction(m_gotoPreviousDocHistoryAction, Constants::GOTOPREVINHISTORY, editDesignContext); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? ::Core::Tr::tr("Alt+Tab") : ::Core::Tr::tr("Ctrl+Tab"))); - mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE); - connect(m_gotoPreviousDocHistoryAction, &QAction::triggered, - this, &EditorManagerPrivate::gotoPreviousDocHistory); + ActionBuilder gotoPrevInHistory(this, Constants::GOTOPREVINHISTORY); + gotoPrevInHistory.setText(::Core::Tr::tr("Previous Open Document in History")); + gotoPrevInHistory.bindContextAction(&m_gotoPreviousDocHistoryAction); + gotoPrevInHistory.setContext(editDesignContext); + gotoPrevInHistory.setDefaultKeySequence(::Core::Tr::tr("Alt+Tab"), ::Core::Tr::tr("Ctrl+Tab")); + gotoPrevInHistory.setContainer(Constants::M_WINDOW, Constants::G_WINDOW_NAVIGATE); + gotoPrevInHistory.setOnTriggered(this, &EditorManagerPrivate::gotoPreviousDocHistory); // Goto Next In History Action - cmd = ActionManager::registerAction(m_gotoNextDocHistoryAction, Constants::GOTONEXTINHISTORY, editDesignContext); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? ::Core::Tr::tr("Alt+Shift+Tab") : ::Core::Tr::tr("Ctrl+Shift+Tab"))); - mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE); - connect(m_gotoNextDocHistoryAction, &QAction::triggered, - this, &EditorManagerPrivate::gotoNextDocHistory); + ActionBuilder gotoNextInHistory(this, Constants::GOTONEXTINHISTORY); + gotoNextInHistory.setText(::Core::Tr::tr("Next Open Document in History")); + gotoNextInHistory.bindContextAction(&m_gotoNextDocHistoryAction); + gotoNextInHistory.setContext(editDesignContext); + gotoNextInHistory.setDefaultKeySequence(::Core::Tr::tr("Alt+Shift+Tab"), ::Core::Tr::tr("Ctrl+Shift+Tab")); + gotoNextInHistory.setContainer(Constants::M_WINDOW, Constants::G_WINDOW_NAVIGATE); + gotoNextInHistory.setOnTriggered(this, &EditorManagerPrivate::gotoNextDocHistory); // Go back in navigation history - cmd = ActionManager::registerAction(m_goBackAction, Constants::GO_BACK, editDesignContext); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? ::Core::Tr::tr("Ctrl+Alt+Left") : ::Core::Tr::tr("Alt+Left"))); - mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE); - connect(m_goBackAction, &QAction::triggered, - m_instance, &EditorManager::goBackInNavigationHistory); + ActionBuilder goBack(this, Constants::GO_BACK); + goBack.setIcon(Utils::Icons::PREV.icon()); + goBack.setText(Core::Tr::tr("Go Back")); + goBack.bindContextAction(&m_goBackAction); + goBack.setContext(editDesignContext); + goBack.setDefaultKeySequence(::Core::Tr::tr("Ctrl+Alt+Left"), ::Core::Tr::tr("Alt+Left")); + goBack.setContainer(Constants::M_WINDOW, Constants::G_WINDOW_NAVIGATE); + goBack.setOnTriggered(this, &EditorManager::goBackInNavigationHistory); // Go forward in navigation history - cmd = ActionManager::registerAction(m_goForwardAction, Constants::GO_FORWARD, editDesignContext); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? ::Core::Tr::tr("Ctrl+Alt+Right") : ::Core::Tr::tr("Alt+Right"))); - mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE); - connect(m_goForwardAction, &QAction::triggered, - m_instance, &EditorManager::goForwardInNavigationHistory); + ActionBuilder goForward(this, Constants::GO_FORWARD); + goForward.setIcon(Utils::Icons::NEXT.icon()); + goForward.setText(Core::Tr::tr("Go Forward")); + goForward.bindContextAction(&m_goForwardAction); + goForward.setContext(editDesignContext); + goForward.setDefaultKeySequence(::Core::Tr::tr("Ctrl+Alt+Right"), ::Core::Tr::tr("Alt+Right")); + goForward.setContainer(Constants::M_WINDOW, Constants::G_WINDOW_NAVIGATE); + goForward.setOnTriggered(this, &EditorManager::goForwardInNavigationHistory); // Go to last edit - cmd = ActionManager::registerAction(m_gotoLastEditAction, Constants::GOTOLASTEDIT, editDesignContext); - mwindow->addAction(cmd, Constants::G_WINDOW_NAVIGATE); - connect(m_gotoLastEditAction, &QAction::triggered, - this, &EditorManagerPrivate::gotoLastEditLocation); + ActionBuilder gotoLastEdit(this, Constants::GOTOLASTEDIT); + gotoLastEdit.setText(::Core::Tr::tr("Go to Last Edit")); + gotoLastEdit.bindContextAction(&m_gotoLastEditAction); + gotoLastEdit.setContext(editDesignContext); + gotoLastEdit.setContainer(Constants::M_WINDOW, Constants::G_WINDOW_NAVIGATE); + gotoLastEdit.setOnTriggered(this, &EditorManagerPrivate::gotoLastEditLocation); - m_splitAction = new QAction(Utils::Icons::SPLIT_HORIZONTAL.icon(), ::Core::Tr::tr("Split"), this); - cmd = ActionManager::registerAction(m_splitAction, Constants::SPLIT, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? ::Core::Tr::tr("Meta+E,2") : ::Core::Tr::tr("Ctrl+E,2"))); - mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); - connect(m_splitAction, &QAction::triggered, this, [] { split(Qt::Vertical); }); + ActionBuilder split(this, Constants::SPLIT); + split.setText(::Core::Tr::tr("Split")); + split.setIcon(Utils::Icons::SPLIT_HORIZONTAL.icon()); + split.bindContextAction(&m_splitAction); + split.setContext(editManagerContext); + split.setDefaultKeySequence(::Core::Tr::tr("Meta+E,2"), ::Core::Tr::tr("Ctrl+E,2")); + split.setContainer(Constants::M_WINDOW, Constants::G_WINDOW_SPLIT); + split.setOnTriggered(this, [this] { this->split(Qt::Vertical); }); - m_splitSideBySideAction = new QAction(Utils::Icons::SPLIT_VERTICAL.icon(), - ::Core::Tr::tr("Split Side by Side"), this); - cmd = ActionManager::registerAction(m_splitSideBySideAction, Constants::SPLIT_SIDE_BY_SIDE, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? ::Core::Tr::tr("Meta+E,3") : ::Core::Tr::tr("Ctrl+E,3"))); - mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); - connect(m_splitSideBySideAction, &QAction::triggered, m_instance, &EditorManager::splitSideBySide); + ActionBuilder splitSideBySide(this, Constants::SPLIT_SIDE_BY_SIDE); + splitSideBySide.setIcon(Utils::Icons::SPLIT_VERTICAL.icon()); + splitSideBySide.setText(::Core::Tr::tr("Split Side by Side")); + splitSideBySide.bindContextAction(&m_splitSideBySideAction); + splitSideBySide.setContext(editManagerContext); + splitSideBySide.setDefaultKeySequence(::Core::Tr::tr("Meta+E,3"), Core::Tr::tr("Ctrl+E,3")); + splitSideBySide.setContainer(Constants::M_WINDOW, Constants::G_WINDOW_SPLIT); + splitSideBySide.setOnTriggered(this, &EditorManager::splitSideBySide); - m_splitNewWindowAction = new QAction(::Core::Tr::tr("Open in New Window"), this); - cmd = ActionManager::registerAction(m_splitNewWindowAction, Constants::SPLIT_NEW_WINDOW, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? ::Core::Tr::tr("Meta+E,4") : ::Core::Tr::tr("Ctrl+E,4"))); - mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); - connect(m_splitNewWindowAction, &QAction::triggered, - this, [] { splitNewWindow(currentEditorView()); }); + ActionBuilder splitNewWindow(this, Constants::SPLIT_NEW_WINDOW); + splitNewWindow.setText(::Core::Tr::tr("Open in New Window")); + splitNewWindow.bindContextAction(&m_splitNewWindowAction); + splitNewWindow.setContext(editManagerContext); + splitNewWindow.setDefaultKeySequence(::Core::Tr::tr("Meta+E,4"), ::Core::Tr::tr("Ctrl+E,4")); + splitNewWindow.setContainer(Constants::M_WINDOW, Constants::G_WINDOW_SPLIT); + splitNewWindow.setOnTriggered(this, [this] { this->splitNewWindow(currentEditorView()); }); - m_removeCurrentSplitAction = new QAction(::Core::Tr::tr("Remove Current Split"), this); - cmd = ActionManager::registerAction(m_removeCurrentSplitAction, Constants::REMOVE_CURRENT_SPLIT, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? ::Core::Tr::tr("Meta+E,0") : ::Core::Tr::tr("Ctrl+E,0"))); - mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); - connect(m_removeCurrentSplitAction, &QAction::triggered, - this, &EditorManagerPrivate::removeCurrentSplit); + ActionBuilder removeCurrentSplit(this, Constants::REMOVE_CURRENT_SPLIT); + removeCurrentSplit.setText(::Core::Tr::tr("Remove Current Split")); + removeCurrentSplit.bindContextAction(&m_removeCurrentSplitAction); + removeCurrentSplit.setContext(editManagerContext); + removeCurrentSplit.setDefaultKeySequence(::Core::Tr::tr("Meta+E,0"), ::Core::Tr::tr("Ctrl+E,0")); + removeCurrentSplit.setContainer(Constants::M_WINDOW, Constants::G_WINDOW_SPLIT); + removeCurrentSplit.setOnTriggered(this, &EditorManagerPrivate::removeCurrentSplit); - m_removeAllSplitsAction = new QAction(::Core::Tr::tr("Remove All Splits"), this); - cmd = ActionManager::registerAction(m_removeAllSplitsAction, Constants::REMOVE_ALL_SPLITS, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? ::Core::Tr::tr("Meta+E,1") : ::Core::Tr::tr("Ctrl+E,1"))); - mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); - connect(m_removeAllSplitsAction, &QAction::triggered, - this, &EditorManagerPrivate::removeAllSplits); + ActionBuilder removeAllSplits(this, Constants::REMOVE_ALL_SPLITS); + removeAllSplits.setText(::Core::Tr::tr("Remove All Splits")); + removeAllSplits.bindContextAction(&m_removeAllSplitsAction); + removeAllSplits.setContext(editManagerContext); + removeAllSplits.setDefaultKeySequence(::Core::Tr::tr("Meta+E,1"), ::Core::Tr::tr("Ctrl+E,1")); + removeAllSplits.setContainer(Constants::M_WINDOW, Constants::G_WINDOW_SPLIT); + removeAllSplits.setOnTriggered(this, &EditorManagerPrivate::removeAllSplits); - m_gotoPreviousSplitAction = new QAction(::Core::Tr::tr("Go to Previous Split or Window"), this); - cmd = ActionManager::registerAction(m_gotoPreviousSplitAction, Constants::GOTO_PREV_SPLIT, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? ::Core::Tr::tr("Meta+E,i") : ::Core::Tr::tr("Ctrl+E,i"))); - mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); - connect(m_gotoPreviousSplitAction, &QAction::triggered, - this, &EditorManagerPrivate::gotoPreviousSplit); + ActionBuilder gotoPreviousSplit(this, Constants::GOTO_PREV_SPLIT); + gotoPreviousSplit.setText(::Core::Tr::tr("Go to Previous Split or Window")); + gotoPreviousSplit.bindContextAction(&m_gotoPreviousSplitAction); + gotoPreviousSplit.setContext(editManagerContext); + gotoPreviousSplit.setDefaultKeySequence(::Core::Tr::tr("Meta+E,i"), ::Core::Tr::tr("Ctrl+E,i")); + gotoPreviousSplit.setContainer(Constants::M_WINDOW, Constants::G_WINDOW_SPLIT); + gotoPreviousSplit.setOnTriggered(this, &EditorManagerPrivate::gotoPreviousSplit); - m_gotoNextSplitAction = new QAction(::Core::Tr::tr("Go to Next Split or Window"), this); - cmd = ActionManager::registerAction(m_gotoNextSplitAction, Constants::GOTO_NEXT_SPLIT, editManagerContext); - cmd->setDefaultKeySequence(QKeySequence(useMacShortcuts ? ::Core::Tr::tr("Meta+E,o") : ::Core::Tr::tr("Ctrl+E,o"))); - mwindow->addAction(cmd, Constants::G_WINDOW_SPLIT); - connect(m_gotoNextSplitAction, &QAction::triggered, this, &EditorManagerPrivate::gotoNextSplit); + ActionBuilder gotoNextSplit(this, Constants::GOTO_NEXT_SPLIT); + gotoNextSplit.setText(::Core::Tr::tr("Go to Next Split or Window")); + gotoNextSplit.bindContextAction(&m_gotoNextSplitAction); + gotoNextSplit.setContext(editManagerContext); + gotoNextSplit.setDefaultKeySequence(QKeySequence(useMacShortcuts ? ::Core::Tr::tr("Meta+E,o") : ::Core::Tr::tr("Ctrl+E,o"))); + gotoNextSplit.setContainer(Constants::M_WINDOW, Constants::G_WINDOW_SPLIT); + gotoNextSplit.setOnTriggered(this, &EditorManagerPrivate::gotoNextSplit); ActionContainer *medit = ActionManager::actionContainer(Constants::M_EDIT); ActionContainer *advancedMenu = ActionManager::createMenu(Constants::M_EDIT_ADVANCED); @@ -667,8 +691,8 @@ void EditorManagerPrivate::init() connect(mainEditorArea, &EditorArea::windowTitleNeedsUpdate, this, &EditorManagerPrivate::updateWindowTitle); connect(mainEditorArea, &QObject::destroyed, this, &EditorManagerPrivate::editorAreaDestroyed); - d->m_editorAreas.append(mainEditorArea); - d->m_currentView = mainEditorArea->view(); + m_editorAreas.append(mainEditorArea); + m_currentView = mainEditorArea->view(); updateActions(); @@ -681,7 +705,7 @@ void EditorManagerPrivate::init() connect(m_autoSaveTimer, &QTimer::timeout, this, &EditorManagerPrivate::autoSave); updateAutoSave(); - d->m_openEditorsFactory = new OpenEditorsViewFactory(); + m_openEditorsFactory = new OpenEditorsViewFactory(); globalMacroExpander()->registerFileVariables(kCurrentDocumentPrefix, ::Core::Tr::tr("Current document"), [] { diff --git a/src/plugins/coreplugin/editormanager/editormanager_p.h b/src/plugins/coreplugin/editormanager/editormanager_p.h index 25c7007b5be..c4de25f3903 100644 --- a/src/plugins/coreplugin/editormanager/editormanager_p.h +++ b/src/plugins/coreplugin/editormanager/editormanager_p.h @@ -197,43 +197,43 @@ private: QTimer *m_autoSaveTimer = nullptr; // actions - QAction *m_revertToSavedAction; - QAction *m_saveAction; - QAction *m_saveAsAction; - QAction *m_closeCurrentEditorAction; - QAction *m_closeAllEditorsAction; - QAction *m_closeOtherDocumentsAction; - QAction *m_closeAllEditorsExceptVisibleAction; - QAction *m_gotoNextDocHistoryAction; - QAction *m_gotoPreviousDocHistoryAction; - QAction *m_goBackAction; - QAction *m_goForwardAction; - QAction *m_gotoLastEditAction; - QAction *m_splitAction; - QAction *m_splitSideBySideAction; - QAction *m_splitNewWindowAction; - QAction *m_removeCurrentSplitAction; - QAction *m_removeAllSplitsAction; - QAction *m_gotoPreviousSplitAction; - QAction *m_gotoNextSplitAction; + QAction *m_revertToSavedAction = nullptr; + QAction *m_saveAction = nullptr; + QAction *m_saveAsAction = nullptr; + QAction *m_closeCurrentEditorAction = nullptr; + QAction *m_closeAllEditorsAction = nullptr; + QAction *m_closeOtherDocumentsAction = nullptr; + QAction *m_closeAllEditorsExceptVisibleAction = nullptr; + QAction *m_gotoNextDocHistoryAction = nullptr; + QAction *m_gotoPreviousDocHistoryAction = nullptr; + QAction *m_goBackAction = nullptr; + QAction *m_goForwardAction = nullptr; + QAction *m_gotoLastEditAction = nullptr; + QAction *m_splitAction = nullptr; + QAction *m_splitSideBySideAction = nullptr; + QAction *m_splitNewWindowAction = nullptr; + QAction *m_removeCurrentSplitAction = nullptr; + QAction *m_removeAllSplitsAction = nullptr; + QAction *m_gotoPreviousSplitAction = nullptr; + QAction *m_gotoNextSplitAction = nullptr; - QAction *m_copyFilePathContextAction; - QAction *m_copyLocationContextAction; // Copy path and line number. - QAction *m_copyFileNameContextAction; - QAction *m_saveCurrentEditorContextAction; - QAction *m_saveAsCurrentEditorContextAction; - QAction *m_revertToSavedCurrentEditorContextAction; + QAction *m_copyFilePathContextAction = nullptr; + QAction *m_copyLocationContextAction = nullptr; // Copy path and line number. + QAction *m_copyFileNameContextAction = nullptr; + QAction *m_saveCurrentEditorContextAction = nullptr; + QAction *m_saveAsCurrentEditorContextAction = nullptr; + QAction *m_revertToSavedCurrentEditorContextAction = nullptr; - QAction *m_closeCurrentEditorContextAction; - QAction *m_closeAllEditorsContextAction; - QAction *m_closeOtherDocumentsContextAction; - QAction *m_closeAllEditorsExceptVisibleContextAction; - QAction *m_openGraphicalShellAction; - QAction *m_openGraphicalShellContextAction; - QAction *m_showInFileSystemViewAction; - QAction *m_showInFileSystemViewContextAction; - QAction *m_openTerminalAction; - QAction *m_findInDirectoryAction; + QAction *m_closeCurrentEditorContextAction = nullptr; + QAction *m_closeAllEditorsContextAction = nullptr; + QAction *m_closeOtherDocumentsContextAction = nullptr; + QAction *m_closeAllEditorsExceptVisibleContextAction = nullptr; + QAction *m_openGraphicalShellAction = nullptr; + QAction *m_openGraphicalShellContextAction = nullptr; + QAction *m_showInFileSystemViewAction = nullptr; + QAction *m_showInFileSystemViewContextAction = nullptr; + QAction *m_openTerminalAction = nullptr; + QAction *m_findInDirectoryAction = nullptr; QAction *m_filePropertiesAction = nullptr; QAction *m_pinAction = nullptr; DocumentModel::Entry *m_contextMenuEntry = nullptr; From 96dcd41d4172865c76ea3d7fc670ff5220d7a40b Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 15:18:28 +0100 Subject: [PATCH 0309/1546] GenericProject: Use new setup pattern for ProjectFilesFactory Change-Id: If5d64a8d6b09fbd3ceaea1736ce74ba2c837a456 Reviewed-by: Christian Stenger --- .../genericprojectfileseditor.cpp | 45 ++++++++++--------- .../genericprojectfileseditor.h | 14 ++---- .../genericprojectplugin.cpp | 2 +- 3 files changed, 28 insertions(+), 33 deletions(-) diff --git a/src/plugins/genericprojectmanager/genericprojectfileseditor.cpp b/src/plugins/genericprojectmanager/genericprojectfileseditor.cpp index 4eeb5d60802..eef322a1519 100644 --- a/src/plugins/genericprojectmanager/genericprojectfileseditor.cpp +++ b/src/plugins/genericprojectmanager/genericprojectfileseditor.cpp @@ -6,33 +6,36 @@ #include #include -#include -#include -#include +#include +#include +#include using namespace TextEditor; -namespace GenericProjectManager { -namespace Internal { +namespace GenericProjectManager::Internal { -// -// ProjectFilesFactory -// - -ProjectFilesFactory::ProjectFilesFactory() +class ProjectFilesFactory : public TextEditorFactory { - setId(Constants::FILES_EDITOR_ID); - setDisplayName(::Core::Tr::tr(".files Editor")); - addMimeType("application/vnd.qtcreator.generic.files"); - addMimeType("application/vnd.qtcreator.generic.includes"); - addMimeType("application/vnd.qtcreator.generic.config"); - addMimeType("application/vnd.qtcreator.generic.cxxflags"); - addMimeType("application/vnd.qtcreator.generic.cflags"); +public: + ProjectFilesFactory() + { + setId(Constants::FILES_EDITOR_ID); + setDisplayName(::Core::Tr::tr(".files Editor")); + addMimeType("application/vnd.qtcreator.generic.files"); + addMimeType("application/vnd.qtcreator.generic.includes"); + addMimeType("application/vnd.qtcreator.generic.config"); + addMimeType("application/vnd.qtcreator.generic.cxxflags"); + addMimeType("application/vnd.qtcreator.generic.cflags"); - setDocumentCreator([]() { return new TextDocument(Constants::FILES_EDITOR_ID); }); - setEditorActionHandlers(TextEditorActionHandler::None); + setDocumentCreator([]() { return new TextDocument(Constants::FILES_EDITOR_ID); }); + setEditorActionHandlers(TextEditorActionHandler::None); + } +}; + +void setupGenericProjectFiles() +{ + static ProjectFilesFactory theProjectFilesFactory; } -} // namespace Internal -} // namespace GenericProjectManager +} // GenericProjectManager::Internal diff --git a/src/plugins/genericprojectmanager/genericprojectfileseditor.h b/src/plugins/genericprojectmanager/genericprojectfileseditor.h index 0079788b1d0..382cf85faa9 100644 --- a/src/plugins/genericprojectmanager/genericprojectfileseditor.h +++ b/src/plugins/genericprojectmanager/genericprojectfileseditor.h @@ -3,16 +3,8 @@ #pragma once -#include +namespace GenericProjectManager::Internal { -namespace GenericProjectManager { -namespace Internal { +void setupGenericProjectFiles(); -class ProjectFilesFactory : public TextEditor::TextEditorFactory -{ -public: - ProjectFilesFactory(); -}; - -} // namespace Internal -} // namespace GenericProjectManager +} // GenericProjectManager::Internal diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.cpp b/src/plugins/genericprojectmanager/genericprojectplugin.cpp index 98070dd579d..1977c4659b4 100644 --- a/src/plugins/genericprojectmanager/genericprojectplugin.cpp +++ b/src/plugins/genericprojectmanager/genericprojectplugin.cpp @@ -35,7 +35,6 @@ class GenericProjectPluginPrivate : public QObject public: GenericProjectPluginPrivate(); - ProjectFilesFactory projectFilesFactory; GenericMakeStepFactory makeStepFactory; GenericBuildConfigurationFactory buildConfigFactory; }; @@ -45,6 +44,7 @@ GenericProjectPluginPrivate::GenericProjectPluginPrivate() ProjectManager::registerProjectType(Constants::GENERICMIMETYPE); setupGenericProjectWizard(); + setupGenericProjectFiles(); ActionBuilder editAction(this, "GenericProjectManager.EditFiles"); editAction.setContext(Constants::GENERICPROJECT_ID); From 8608dc955622555f3fa2bca243cba55620446ceb Mon Sep 17 00:00:00 2001 From: Serg Kryvonos Date: Mon, 20 Nov 2023 10:57:03 +0100 Subject: [PATCH 0310/1546] Use "Ninja Multi-Config" generator by default in configurePresets Multi-Config generators have additional library dependencies checks. Xcode and MSbuild are multi-config generators too. We need to make sure it kept configurable. Change-Id: I571e718bc71ffc3920f07d15a956e9153d74b0a5 Reviewed-by: Cristian Adam --- CMakePresets.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakePresets.json b/CMakePresets.json index 0e4b60e22b7..c3363eb0a34 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -4,7 +4,7 @@ { "name": "cmake-plugin-minimal", "displayName": "CMake, C++, Git, Debug minimal Build", - "generator": "Ninja", + "generator": "Ninja Multi-Config", "hidden" : true, "cacheVariables": { "BUILD_PLUGINS": "Core;Designer;DiffEditor;TextEditor;ProjectExplorer;CppEditor;CodePaster;Docker;Git;Help;QmakeProjectManager;CMakeProjectManager;ClangCodeModel;ClangTools;ClangFormat;Debugger;QtSupport;ResourceEditor;VcsBase;Welcome;LanguageClient;RemoteLinux", From 08bf1186240f581375558d915b0edb0b5ef3b34d Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 14:09:56 +0100 Subject: [PATCH 0311/1546] Qnx: Move QnxSettingsPage to new scheme Change-Id: I96287f7dc2b0d12f85164c137d1f1e6701ce468e Reviewed-by: Christian Stenger --- src/plugins/qnx/qnxplugin.cpp | 3 +- src/plugins/qnx/qnxsettingspage.cpp | 84 ++++++++++++++--------------- src/plugins/qnx/qnxsettingspage.h | 11 ++-- src/plugins/qnx/qnxtoolchain.cpp | 2 +- 4 files changed, 45 insertions(+), 55 deletions(-) diff --git a/src/plugins/qnx/qnxplugin.cpp b/src/plugins/qnx/qnxplugin.cpp index 3e6ae206e47..03b6613990c 100644 --- a/src/plugins/qnx/qnxplugin.cpp +++ b/src/plugins/qnx/qnxplugin.cpp @@ -86,8 +86,6 @@ public: QAction *m_debugSeparator = nullptr; QAction m_attachToQnxApplication{Tr::tr("Attach to remote QNX application..."), nullptr}; - - QnxSettingsPage settingsPage; }; class QnxPlugin final : public ExtensionSystem::IPlugin @@ -110,6 +108,7 @@ private: setupQnxRunnning(); setupQnxDebugging(); setupQnxQmlProfiler(); + setupQnxSettingsPage(this); } void extensionsInitialized() final; diff --git a/src/plugins/qnx/qnxsettingspage.cpp b/src/plugins/qnx/qnxsettingspage.cpp index 37ca5aafc2b..e888857c4cb 100644 --- a/src/plugins/qnx/qnxsettingspage.cpp +++ b/src/plugins/qnx/qnxsettingspage.cpp @@ -417,20 +417,21 @@ const QnxTarget *QnxConfiguration::findTargetByDebuggerPath( return it == m_targets.end() ? nullptr : &(*it); } +// QnxSettingsPage -// QnxSettingsPagePrivate +static QHash m_configurations; -class QnxSettingsPagePrivate : public QObject +static QnxConfiguration *configurationFromEnvFile(const FilePath &envFile) +{ + auto it = m_configurations.find(envFile); + return it == m_configurations.end() ? nullptr : &*it; +} + +class QnxSettingsPage : public QObject, public Core::IOptionsPage { public: - QnxSettingsPagePrivate() - { - connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested, - this, &QnxSettingsPagePrivate::saveConfigs); - // Can't do yet as not all devices are around. - connect(DeviceManager::instance(), &DeviceManager::devicesLoaded, - this, &QnxSettingsPagePrivate::restoreConfigurations); - } + explicit QnxSettingsPage(QObject *guard); + ~QnxSettingsPage() {} void saveConfigs() { @@ -469,19 +470,9 @@ public: } } - QnxConfiguration *configurationFromEnvFile(const FilePath &envFile) - { - auto it = m_configurations.find(envFile); - return it == m_configurations.end() ? nullptr : &*it; - } - - QHash m_configurations; PersistentSettingsWriter m_writer{qnxConfigSettingsFileName(), "QnxConfigurations"}; }; -static QnxSettingsPagePrivate *dd = nullptr; - - // QnxSettingsWidget class ArchitecturesList final : public QWidget @@ -492,7 +483,7 @@ public: m_envFile = envFile; delete layout(); - QnxConfiguration *config = dd->configurationFromEnvFile(envFile); + QnxConfiguration *config = configurationFromEnvFile(envFile); if (!config) return; @@ -608,7 +599,7 @@ void QnxSettingsWidget::addConfiguration() if (envFile.isEmpty()) return; - if (dd->m_configurations.contains(envFile)) { + if (m_configurations.contains(envFile)) { QMessageBox::warning(Core::ICore::dialogParent(), Tr::tr("Warning"), Tr::tr("Configuration already exists.")); @@ -634,7 +625,7 @@ void QnxSettingsWidget::removeConfiguration() const FilePath envFile = m_configsCombo->currentData().value(); QTC_ASSERT(!envFile.isEmpty(), return); - QnxConfiguration *config = dd->configurationFromEnvFile(envFile); + QnxConfiguration *config = configurationFromEnvFile(envFile); QTC_ASSERT(config, return); config->ensureContents(); @@ -657,7 +648,7 @@ void QnxSettingsWidget::updateInformation() { const FilePath envFile = m_configsCombo->currentData().value(); - if (QnxConfiguration *config = dd->configurationFromEnvFile(envFile)) { + if (QnxConfiguration *config = configurationFromEnvFile(envFile)) { config->ensureContents(); m_configName->setText(config->m_configName); m_configVersion->setText(config->m_version.toString()); @@ -679,7 +670,7 @@ void QnxSettingsWidget::updateInformation() void QnxSettingsWidget::populateConfigsCombo() { m_configsCombo->clear(); - for (const QnxConfiguration &config : std::as_const(dd->m_configurations)) { + for (const QnxConfiguration &config : std::as_const(m_configurations)) { config.ensureContents(); m_configsCombo->addItem(config.m_configName, QVariant::fromValue(config.m_envFile)); } @@ -717,13 +708,13 @@ void QnxSettingsWidget::apply() for (const ConfigState &configState : std::as_const(m_changedConfigs)) { switch (configState.state) { case Activated: { - QnxConfiguration *config = dd->configurationFromEnvFile(configState.envFile); + QnxConfiguration *config = configurationFromEnvFile(configState.envFile); QTC_ASSERT(config, break); config->activate(); break; } case Deactivated: { - QnxConfiguration *config = dd->configurationFromEnvFile(configState.envFile); + QnxConfiguration *config = configurationFromEnvFile(configState.envFile); QTC_ASSERT(config, break); config->deactivate(); break; @@ -731,14 +722,14 @@ void QnxSettingsWidget::apply() case Added: { QnxConfiguration config(configState.envFile); config.ensureContents(); - dd->m_configurations.insert(configState.envFile, config); + m_configurations.insert(configState.envFile, config); break; } case Removed: - QnxConfiguration *config = dd->configurationFromEnvFile(configState.envFile); + QnxConfiguration *config = configurationFromEnvFile(configState.envFile); QTC_ASSERT(config, break); config->deactivate(); - dd->m_configurations.remove(configState.envFile); + m_configurations.remove(configState.envFile); break; } } @@ -749,10 +740,25 @@ void QnxSettingsWidget::apply() // QnxSettingsPage -QList QnxSettingsPage::autoDetect(const QList &alreadyKnown) +QnxSettingsPage::QnxSettingsPage(QObject *guard) + : QObject(guard) +{ + setId("DD.Qnx Configuration"); + setDisplayName(Tr::tr("QNX")); + setCategory(ProjectExplorer::Constants::DEVICE_SETTINGS_CATEGORY); + setWidgetCreator([] { return new QnxSettingsWidget; }); + + connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested, + this, &QnxSettingsPage::saveConfigs); + // Can't do yet as not all devices are around. + connect(DeviceManager::instance(), &DeviceManager::devicesLoaded, + this, &QnxSettingsPage::restoreConfigurations); +} + +QList autoDetectHelper(const QList &alreadyKnown) { QList result; - for (const QnxConfiguration &config : std::as_const(dd->m_configurations)) { + for (const QnxConfiguration &config : std::as_const(m_configurations)) { config.ensureContents(); for (const QnxTarget &target : std::as_const(config.m_targets)) { result += Utils::filtered(alreadyKnown, [config, target](ToolChain *tc) { @@ -765,19 +771,9 @@ QList QnxSettingsPage::autoDetect(const QList &already return result; } -QnxSettingsPage::QnxSettingsPage() +void setupQnxSettingsPage(QObject *guard) { - setId("DD.Qnx Configuration"); - setDisplayName(Tr::tr("QNX")); - setCategory(ProjectExplorer::Constants::DEVICE_SETTINGS_CATEGORY); - setWidgetCreator([] { return new QnxSettingsWidget; }); - - dd = new QnxSettingsPagePrivate; -} - -QnxSettingsPage::~QnxSettingsPage() -{ - delete dd; + (void) new QnxSettingsPage(guard); } } // Qnx::Internal diff --git a/src/plugins/qnx/qnxsettingspage.h b/src/plugins/qnx/qnxsettingspage.h index f127d5f35e4..1c40e23c43d 100644 --- a/src/plugins/qnx/qnxsettingspage.h +++ b/src/plugins/qnx/qnxsettingspage.h @@ -9,14 +9,9 @@ namespace ProjectExplorer { class ToolChain; } namespace Qnx::Internal { -class QnxSettingsPage final : public Core::IOptionsPage -{ -public: - QnxSettingsPage(); - ~QnxSettingsPage(); +QList autoDetectHelper( + const QList &alreadyKnown); - static QList autoDetect( - const QList &alreadyKnown); -}; +void setupQnxSettingsPage(QObject *guard); } // Qnx::Internal diff --git a/src/plugins/qnx/qnxtoolchain.cpp b/src/plugins/qnx/qnxtoolchain.cpp index 6cf6b715e72..c3bdad566ba 100644 --- a/src/plugins/qnx/qnxtoolchain.cpp +++ b/src/plugins/qnx/qnxtoolchain.cpp @@ -272,7 +272,7 @@ public: if (detector.device) return {}; - Toolchains tcs = QnxSettingsPage::autoDetect(detector.alreadyKnown); + Toolchains tcs = autoDetectHelper(detector.alreadyKnown); return tcs; } }; From b9a0481a0de10cd4a014bfdb0ff0399484ed5fc4 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Nov 2023 14:24:13 +0100 Subject: [PATCH 0312/1546] HelloWorld: Use ActionBuilder Change-Id: I2e0c9de2293640712669c273e3b307ac95340fd6 Reviewed-by: Eike Ziller --- src/plugins/helloworld/helloworldplugin.cpp | 28 ++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/plugins/helloworld/helloworldplugin.cpp b/src/plugins/helloworld/helloworldplugin.cpp index 88e0d1ea3f1..746ce554984 100644 --- a/src/plugins/helloworld/helloworldplugin.cpp +++ b/src/plugins/helloworld/helloworldplugin.cpp @@ -64,30 +64,30 @@ void HelloWorldPlugin::initialize() // menu entry later. Core::Context context("HelloWorld.MainView"); - // Create an action to be triggered by a menu entry - auto helloWorldAction = new QAction(Tr::tr("Say \"&Hello World!\""), this); - connect(helloWorldAction, &QAction::triggered, this, &HelloWorldPlugin::sayHelloWorld); - - // Register the action with the action manager - Core::Command *command = - Core::ActionManager::registerAction( - helloWorldAction, "HelloWorld.HelloWorldAction", context); - // Create our own menu to place in the Tools menu - Core::ActionContainer *helloWorldMenu = - Core::ActionManager::createMenu("HelloWorld.HelloWorldMenu"); + Utils::Id menuId = "HelloWorld.HelloWorldMenu"; + + Core::ActionContainer *helloWorldMenu = Core::ActionManager::createMenu(menuId); QMenu *menu = helloWorldMenu->menu(); menu->setTitle(Tr::tr("&Hello World")); menu->setEnabled(true); - // Add the Hello World action command to the menu - helloWorldMenu->addAction(command); - // Request the Tools menu and add the Hello World menu to it Core::ActionContainer *toolsMenu = Core::ActionManager::actionContainer(Core::Constants::M_TOOLS); toolsMenu->addMenu(helloWorldMenu); + // Create an action to be triggered by a menu entry. + // The Action builder registers the action with the action manager + // on its destruction. + Core::ActionBuilder hello(this, "HelloWorld.HelloWorldAction"); + hello.setText(Tr::tr("Say \"&Hello World!\"")); + hello.setContext(context); + hello.setOnTriggered(this, [this] { sayHelloWorld(); }); + + // Add the Hello World action command to the menu + hello.setContainer(menuId); + // Add a mode with a push button based on BaseMode. m_helloMode = new HelloMode; } From 7e38745706a8c017a4d310af32ae0ca4c9150464 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 14:24:24 +0100 Subject: [PATCH 0313/1546] Qnx: Re-order code a bit Change-Id: Id2da2bdc67edd1abcc489767392aa791c7b0f667 Reviewed-by: Christian Stenger --- src/plugins/qnx/qnxplugin.cpp | 87 +++++++++++++---------------------- 1 file changed, 32 insertions(+), 55 deletions(-) diff --git a/src/plugins/qnx/qnxplugin.cpp b/src/plugins/qnx/qnxplugin.cpp index 03b6613990c..6fbb32eeb9d 100644 --- a/src/plugins/qnx/qnxplugin.cpp +++ b/src/plugins/qnx/qnxplugin.cpp @@ -20,17 +20,13 @@ #include #include +#include #include -#include -#include -#include #include #include #include -#include #include #include -#include #include @@ -79,28 +75,13 @@ void setupQnxDeployment() static QnxDeployStepFactory makeInstallStepFactory{RemoteLinux::Constants::MakeInstallStepId}; } -class QnxPluginPrivate -{ -public: - void updateDebuggerActions(); - - QAction *m_debugSeparator = nullptr; - QAction m_attachToQnxApplication{Tr::tr("Attach to remote QNX application..."), nullptr}; -}; - class QnxPlugin final : public ExtensionSystem::IPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Qnx.json") -public: - ~QnxPlugin() final { delete d; } - -private: void initialize() final { - d = new QnxPluginPrivate; - setupQnxDevice(); setupQnxToolChain(); setupQnxQtVersion(); @@ -111,44 +92,40 @@ private: setupQnxSettingsPage(this); } - void extensionsInitialized() final; + void extensionsInitialized() final + { + auto attachToQnxApplication = new QAction{Tr::tr("Attach to remote QNX application..."), this}; + // Attach support + connect(attachToQnxApplication, &QAction::triggered, this, &showAttachToProcessDialog); - QnxPluginPrivate *d = nullptr; + const Utils::Id QNX_DEBUGGING_GROUP = "Debugger.Group.Qnx"; + + QAction *debugSeparator = nullptr; + + Core::ActionContainer *mstart = Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_DEBUG_STARTDEBUGGING); + mstart->appendGroup(QNX_DEBUGGING_GROUP); + mstart->addSeparator(Core::Context(Core::Constants::C_GLOBAL), QNX_DEBUGGING_GROUP, + &debugSeparator); + + Core::Command *cmd = Core::ActionManager::registerAction + (attachToQnxApplication, "Debugger.AttachToQnxApplication"); + mstart->addAction(cmd, QNX_DEBUGGING_GROUP); + + connect(KitManager::instance(), &KitManager::kitsChanged, this, + [attachToQnxApplication, debugSeparator] { + auto isQnxKit = [](const Kit *kit) { + return DeviceTypeKitAspect::deviceTypeId(kit) == Constants::QNX_QNX_OS_TYPE + && !DeviceKitAspect::device(kit).isNull() && kit->isValid(); + }; + + const bool hasValidQnxKit = KitManager::kit(isQnxKit) != nullptr; + + attachToQnxApplication->setVisible(hasValidQnxKit); + debugSeparator->setVisible(hasValidQnxKit); + }); + } }; -void QnxPlugin::extensionsInitialized() -{ - // Attach support - connect(&d->m_attachToQnxApplication, &QAction::triggered, this, &showAttachToProcessDialog); - - const char QNX_DEBUGGING_GROUP[] = "Debugger.Group.Qnx"; - - Core::ActionContainer *mstart = Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_DEBUG_STARTDEBUGGING); - mstart->appendGroup(QNX_DEBUGGING_GROUP); - mstart->addSeparator(Core::Context(Core::Constants::C_GLOBAL), QNX_DEBUGGING_GROUP, - &d->m_debugSeparator); - - Core::Command *cmd = Core::ActionManager::registerAction - (&d->m_attachToQnxApplication, "Debugger.AttachToQnxApplication"); - mstart->addAction(cmd, QNX_DEBUGGING_GROUP); - - connect(KitManager::instance(), &KitManager::kitsChanged, - this, [this] { d->updateDebuggerActions(); }); -} - -void QnxPluginPrivate::updateDebuggerActions() -{ - auto isQnxKit = [](const Kit *kit) { - return DeviceTypeKitAspect::deviceTypeId(kit) == Constants::QNX_QNX_OS_TYPE - && !DeviceKitAspect::device(kit).isNull() && kit->isValid(); - }; - - const bool hasValidQnxKit = KitManager::kit(isQnxKit) != nullptr; - - m_attachToQnxApplication.setVisible(hasValidQnxKit); - m_debugSeparator->setVisible(hasValidQnxKit); -} - } // Qnx::Internal #include "qnxplugin.moc" From 116798e54479bd040da96cf79d422528ca49a5a8 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 17 Nov 2023 13:36:46 +0100 Subject: [PATCH 0314/1546] CppEditor/QmlJSTools: Simplify RefactoringFile::file() re-implementation Change-Id: I8f2af8de3786ecf4400bc42019d496bd52bb2545 Reviewed-by: Qt CI Bot Reviewed-by: David Schulz --- src/plugins/cppeditor/cpprefactoringchanges.cpp | 4 ++-- src/plugins/qmljstools/qmljsrefactoringchanges.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plugins/cppeditor/cpprefactoringchanges.cpp b/src/plugins/cppeditor/cpprefactoringchanges.cpp index e15dca72cb8..207d359cb88 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.cpp +++ b/src/plugins/cppeditor/cpprefactoringchanges.cpp @@ -60,12 +60,12 @@ CppRefactoringFilePtr CppRefactoringChanges::file(TextEditor::TextEditorWidget * TextEditor::RefactoringFilePtr CppRefactoringChanges::file(const FilePath &filePath) const { - return TextEditor::RefactoringFilePtr(new CppRefactoringFile(filePath, m_data)); + return cppFile(filePath); } CppRefactoringFilePtr CppRefactoringChanges::cppFile(const Utils::FilePath &filePath) const { - return file(filePath).staticCast(); + return CppRefactoringFilePtr(new CppRefactoringFile(filePath, m_data)); } CppRefactoringFileConstPtr CppRefactoringChanges::fileNoEditor(const FilePath &filePath) const diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp index 0e03454250a..66ce4102b43 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp @@ -36,12 +36,12 @@ QmlJSRefactoringChanges::QmlJSRefactoringChanges(ModelManagerInterface *modelMan TextEditor::RefactoringFilePtr QmlJSRefactoringChanges::file(const Utils::FilePath &filePath) const { - return QmlJSRefactoringFilePtr(new QmlJSRefactoringFile(filePath, m_data)); + return qmlJSFile(filePath); } QmlJSRefactoringFilePtr QmlJSRefactoringChanges::qmlJSFile(const Utils::FilePath &filePath) const { - return file(filePath).staticCast(); + return QmlJSRefactoringFilePtr(new QmlJSRefactoringFile(filePath, m_data)); } QmlJSRefactoringFilePtr QmlJSRefactoringChanges::file( From 1a37da15c7d9d8786d5c6919b61c498525afa4e5 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Thu, 16 Nov 2023 12:47:57 +0100 Subject: [PATCH 0315/1546] Debugger: Add our lldb to the system search paths This way the user doesn't have to manually register lldb.exe Change-Id: Id0a19de0962d8ba47a66a8d1909dfe2eb5ca0a6f Reviewed-by: David Schulz --- src/plugins/coreplugin/icore.cpp | 8 ++++++++ src/plugins/coreplugin/icore.h | 1 + src/plugins/debugger/CMakeLists.txt | 2 ++ src/plugins/debugger/debugger.qbs | 1 + src/plugins/debugger/debuggeritem.cpp | 7 +++++-- src/plugins/debugger/debuggeritemmanager.cpp | 7 ++++++- 6 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index cb6e2609030..354ce144e13 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -768,6 +768,14 @@ FilePath ICore::clazyStandaloneExecutable(const FilePath &clangBinDirectory) return clangBinary("clazy-standalone", clangBinDirectory); } +/*! + \internal + */ +FilePath ICore::lldbExecutable(const Utils::FilePath &lldbBinDirectory) +{ + return clangBinary("lldb", lldbBinDirectory); +} + static QString compilerString() { #if defined(Q_CC_CLANG) // must be before GNU, because clang claims to be GNU too diff --git a/src/plugins/coreplugin/icore.h b/src/plugins/coreplugin/icore.h index 518939aeaae..17c850f20d4 100644 --- a/src/plugins/coreplugin/icore.h +++ b/src/plugins/coreplugin/icore.h @@ -148,6 +148,7 @@ public: static Utils::FilePath clazyStandaloneExecutable(const Utils::FilePath &clangBinDirectory); static Utils::FilePath clangIncludeDirectory(const QString &clangVersion, const Utils::FilePath &clangFallbackIncludeDir); + static Utils::FilePath lldbExecutable(const Utils::FilePath &lldbBinDirectory); static QStatusBar *statusBar(); static void saveSettings(SaveSettingsReason reason); diff --git a/src/plugins/debugger/CMakeLists.txt b/src/plugins/debugger/CMakeLists.txt index 21920f8fef9..bc1880e9110 100644 --- a/src/plugins/debugger/CMakeLists.txt +++ b/src/plugins/debugger/CMakeLists.txt @@ -3,6 +3,8 @@ add_qtc_plugin(Debugger PLUGIN_DEPENDS Core CppEditor ProjectExplorer QtSupport TextEditor PLUGIN_RECOMMENDS QmakeProjectManager PLUGIN_TEST_DEPENDS QmakeProjectManager + DEFINES + CLANG_BINDIR="${LLVM_TOOLS_BINARY_DIR}" SOURCES analyzer/analyzerbase.qrc analyzer/analyzerconstants.h diff --git a/src/plugins/debugger/debugger.qbs b/src/plugins/debugger/debugger.qbs index 7ff685a63c5..4c1a769a675 100644 --- a/src/plugins/debugger/debugger.qbs +++ b/src/plugins/debugger/debugger.qbs @@ -15,6 +15,7 @@ QtcPlugin { Depends { name: "ProjectExplorer" } Depends { name: "QtSupport" } Depends { name: "TextEditor" } + Depends { name: "clang_defines" } pluginRecommends: ["BinEditor"] pluginTestDepends: ["QmakeProjectManager"] diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp index b95a40527ba..ba4a564a102 100644 --- a/src/plugins/debugger/debuggeritem.cpp +++ b/src/plugins/debugger/debuggeritem.cpp @@ -6,6 +6,8 @@ #include "debuggerprotocol.h" #include "debuggertr.h" +#include + #include #include @@ -148,8 +150,9 @@ void DebuggerItem::reinitializeFromFile(QString *error, Utils::Environment *cust // Prevent calling lldb on Windows because the lldb from the llvm package is linked against // python but does not contain a python dll. const bool isAndroidNdkLldb = DebuggerItem::addAndroidLldbPythonEnv(m_command, env); - if (HostOsInfo::isWindowsHost() && m_command.fileName().startsWith("lldb") - && !isAndroidNdkLldb) { + const FilePath qtcreatorLldb = Core::ICore::lldbExecutable(CLANG_BINDIR); + if (HostOsInfo::isWindowsHost() && m_command.fileName().startsWith("lldb") && !isAndroidNdkLldb + && qtcreatorLldb != m_command) { QString errorMessage; m_version = winGetDLLVersion(WinDLLFileVersion, m_command.absoluteFilePath().path(), diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp index 4abca97388a..bb19be2ad2d 100644 --- a/src/plugins/debugger/debuggeritemmanager.cpp +++ b/src/plugins/debugger/debuggeritemmanager.cpp @@ -635,9 +635,14 @@ void DebuggerItemModel::autoDetectGdbOrLldbDebuggers(const FilePaths &searchPath } FilePaths paths = searchPaths; - if (!searchPaths.front().needsDevice()) + if (!searchPaths.front().needsDevice()) { paths.append(searchGdbPathsFromRegistry()); + const FilePath lldb = Core::ICore::lldbExecutable(CLANG_BINDIR); + if (lldb.exists()) + suspects.append(lldb); + } + paths = Utils::filteredUnique(paths); const auto addSuspect = [&suspects](const FilePath &entry) { From 6910408f35145c60e3a78ce1a0ed7ce24bc801d4 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 21 Nov 2023 14:54:53 +0100 Subject: [PATCH 0316/1546] Fix compiler warnings "braces around scalar initializer" and "lambda capture 'this' is not used" Amends b60fd77fc128133f408d67beda814c55e8364d3e Amends 181b362fcf16bd420d51d80df4189e1e6f5dbefe Change-Id: Ie7c21db13644e98c0eec06a22f977ed4b923fae3 Reviewed-by: Alessandro Portale --- src/plugins/coreplugin/editormanager/editormanager.cpp | 2 +- src/plugins/designer/formeditorplugin.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index 12157ffc071..e08fee3c563 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -429,7 +429,7 @@ void EditorManagerPrivate::init() ActionBuilder save(this, Constants::SAVE); save.setContext(editManagerContext); save.bindContextAction(&m_saveAction); - save.setOnTriggered(this, [this] { EditorManager::saveDocument(); }); + save.setOnTriggered(this, [] { EditorManager::saveDocument(); }); // Save As Action ActionBuilder saveAs(this, Constants::SAVEAS); diff --git a/src/plugins/designer/formeditorplugin.cpp b/src/plugins/designer/formeditorplugin.cpp index afbca7010bd..0f9c77b0b44 100644 --- a/src/plugins/designer/formeditorplugin.cpp +++ b/src/plugins/designer/formeditorplugin.cpp @@ -100,7 +100,7 @@ bool FormEditorPlugin::initialize([[maybe_unused]] const QStringList &arguments, wizard->setDescription(Tr::tr("Creates a Qt Designer form along with a matching class (C++ header and source file) " "for implementation purposes. You can add the form and class to an existing Qt Widget Project.")); - return {wizard}; + return wizard; }); #endif From 84275809b4182faccced04e84de27689fba49146 Mon Sep 17 00:00:00 2001 From: Artem Sokolovskii Date: Fri, 19 May 2023 13:03:01 +0200 Subject: [PATCH 0317/1546] SyntaxHighlighter: Make setChangeNumbers private function Made setChangeNumbers private function in BaseAnnotationHighlighter and remove usage in other places. Moved annotationChanges to BaseAnnotationHighlighterPrivate from VcsBaseEditorWidget. This was done to move all instances of TextEditor::SyntaxHighlighter. In this regards only the public API of TextEditor::SyntaxHighlighter should be available from children and no other additional functions. Change-Id: Ibece9476a810e13c8722839820d5c575b0808f03 Reviewed-by: Jarek Kobus --- src/plugins/bazaar/annotationhighlighter.cpp | 10 +-- src/plugins/bazaar/annotationhighlighter.h | 4 +- src/plugins/bazaar/bazaareditor.cpp | 2 +- .../clearcase/annotationhighlighter.cpp | 10 +-- src/plugins/clearcase/annotationhighlighter.h | 4 +- src/plugins/clearcase/clearcaseeditor.cpp | 2 +- src/plugins/cvs/cvseditor.cpp | 10 +-- src/plugins/fossil/annotationhighlighter.cpp | 8 +- src/plugins/fossil/annotationhighlighter.h | 3 +- src/plugins/fossil/fossileditor.cpp | 2 +- src/plugins/git/annotationhighlighter.cpp | 9 +-- src/plugins/git/annotationhighlighter.h | 2 +- src/plugins/git/giteditor.cpp | 2 +- .../mercurial/annotationhighlighter.cpp | 6 +- src/plugins/mercurial/annotationhighlighter.h | 4 +- src/plugins/mercurial/mercurialeditor.cpp | 2 +- .../perforce/annotationhighlighter.cpp | 6 +- src/plugins/perforce/annotationhighlighter.h | 2 +- src/plugins/perforce/perforceeditor.cpp | 2 +- .../subversion/annotationhighlighter.cpp | 11 ++- .../subversion/annotationhighlighter.h | 2 +- src/plugins/subversion/subversioneditor.cpp | 3 +- src/plugins/texteditor/syntaxhighlighter.cpp | 5 ++ src/plugins/texteditor/syntaxhighlighter.h | 5 +- .../vcsbase/baseannotationhighlighter.cpp | 73 +++++++++++++++++-- .../vcsbase/baseannotationhighlighter.h | 20 ++++- src/plugins/vcsbase/vcsbaseeditor.cpp | 18 ++--- src/plugins/vcsbase/vcsbaseeditor.h | 8 +- 28 files changed, 156 insertions(+), 79 deletions(-) diff --git a/src/plugins/bazaar/annotationhighlighter.cpp b/src/plugins/bazaar/annotationhighlighter.cpp index 7b5e2ba0208..86220f52662 100644 --- a/src/plugins/bazaar/annotationhighlighter.cpp +++ b/src/plugins/bazaar/annotationhighlighter.cpp @@ -4,15 +4,13 @@ #include "annotationhighlighter.h" #include "constants.h" -#include - namespace Bazaar::Internal { -BazaarAnnotationHighlighter::BazaarAnnotationHighlighter(const ChangeNumbers &changeNumbers, +BazaarAnnotationHighlighter::BazaarAnnotationHighlighter(const VcsBase::Annotation &annotation, QTextDocument *document) - : VcsBase::BaseAnnotationHighlighter(changeNumbers, document), - m_changeset(QLatin1String(Constants::ANNOTATE_CHANGESET_ID)) -{ } + : VcsBase::BaseAnnotationHighlighter(annotation, document) + , m_changeset(QLatin1String(Constants::ANNOTATE_CHANGESET_ID)) +{} QString BazaarAnnotationHighlighter::changeNumber(const QString &block) const { diff --git a/src/plugins/bazaar/annotationhighlighter.h b/src/plugins/bazaar/annotationhighlighter.h index 7faac84bce3..c0a789d6c94 100644 --- a/src/plugins/bazaar/annotationhighlighter.h +++ b/src/plugins/bazaar/annotationhighlighter.h @@ -5,14 +5,12 @@ #include -#include - namespace Bazaar::Internal { class BazaarAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighter { public: - explicit BazaarAnnotationHighlighter(const ChangeNumbers &changeNumbers, + explicit BazaarAnnotationHighlighter(const VcsBase::Annotation &annotation, QTextDocument *document = nullptr); private: diff --git a/src/plugins/bazaar/bazaareditor.cpp b/src/plugins/bazaar/bazaareditor.cpp index 305fa8eb8a3..ec923e62d61 100644 --- a/src/plugins/bazaar/bazaareditor.cpp +++ b/src/plugins/bazaar/bazaareditor.cpp @@ -61,7 +61,7 @@ QString BazaarEditorWidget::changeUnderCursor(const QTextCursor &cursorIn) const VcsBase::BaseAnnotationHighlighterCreator BazaarEditorWidget::annotationHighlighterCreator() const { - return [](const QSet &changes) { return new BazaarAnnotationHighlighter(changes); }; + return VcsBase::getAnnotationHighlighterCreator(); } } // Bazaar::Internal diff --git a/src/plugins/clearcase/annotationhighlighter.cpp b/src/plugins/clearcase/annotationhighlighter.cpp index eaede4c11ec..25d076b13d0 100644 --- a/src/plugins/clearcase/annotationhighlighter.cpp +++ b/src/plugins/clearcase/annotationhighlighter.cpp @@ -5,10 +5,10 @@ namespace ClearCase::Internal { -ClearCaseAnnotationHighlighter::ClearCaseAnnotationHighlighter(const ChangeNumbers &changeNumbers, - QTextDocument *document) : - VcsBase::BaseAnnotationHighlighter(changeNumbers, document) -{ } +ClearCaseAnnotationHighlighter::ClearCaseAnnotationHighlighter(const VcsBase::Annotation &annotation, + QTextDocument *document) + : VcsBase::BaseAnnotationHighlighter(annotation, document) +{} QString ClearCaseAnnotationHighlighter::changeNumber(const QString &block) const { @@ -16,4 +16,4 @@ QString ClearCaseAnnotationHighlighter::changeNumber(const QString &block) const return pos > 1 ? block.left(pos) : QString(); } -} // ClearCase::Internal +} // namespace ClearCase::Internal diff --git a/src/plugins/clearcase/annotationhighlighter.h b/src/plugins/clearcase/annotationhighlighter.h index bb96ca906af..46830ee033f 100644 --- a/src/plugins/clearcase/annotationhighlighter.h +++ b/src/plugins/clearcase/annotationhighlighter.h @@ -12,7 +12,7 @@ class ClearCaseAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighter { Q_OBJECT public: - explicit ClearCaseAnnotationHighlighter(const ChangeNumbers &changeNumbers, + explicit ClearCaseAnnotationHighlighter(const VcsBase::Annotation &annotation, QTextDocument *document = nullptr); private: @@ -21,4 +21,4 @@ private: const QChar m_separator = QLatin1Char('|'); }; -} // ClearCase::Internal +} // namespace ClearCase::Internal diff --git a/src/plugins/clearcase/clearcaseeditor.cpp b/src/plugins/clearcase/clearcaseeditor.cpp index 02b07383585..9a80c7f09c5 100644 --- a/src/plugins/clearcase/clearcaseeditor.cpp +++ b/src/plugins/clearcase/clearcaseeditor.cpp @@ -44,7 +44,7 @@ QString ClearCaseEditorWidget::changeUnderCursor(const QTextCursor &c) const VcsBase::BaseAnnotationHighlighterCreator ClearCaseEditorWidget::annotationHighlighterCreator() const { - return [](const QSet &changes) { return new ClearCaseAnnotationHighlighter(changes); }; + return VcsBase::getAnnotationHighlighterCreator(); } } // ClearCase::Internal diff --git a/src/plugins/cvs/cvseditor.cpp b/src/plugins/cvs/cvseditor.cpp index 4e0aac6956b..85b9e8b7d88 100644 --- a/src/plugins/cvs/cvseditor.cpp +++ b/src/plugins/cvs/cvseditor.cpp @@ -25,10 +25,10 @@ namespace Cvs::Internal { class CvsAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighter { public: - explicit CvsAnnotationHighlighter(const ChangeNumbers &changeNumbers, - QTextDocument *document = nullptr) : - VcsBase::BaseAnnotationHighlighter(changeNumbers, document) - { } + explicit CvsAnnotationHighlighter(const VcsBase::Annotation &annotation, + QTextDocument *document = nullptr) + : VcsBase::BaseAnnotationHighlighter(annotation, document) + {} private: QString changeNumber(const QString &block) const override @@ -95,7 +95,7 @@ QString CvsEditorWidget::changeUnderCursor(const QTextCursor &c) const VcsBase::BaseAnnotationHighlighterCreator CvsEditorWidget::annotationHighlighterCreator() const { - return [](const QSet &changes) { return new CvsAnnotationHighlighter(changes); }; + return VcsBase::getAnnotationHighlighterCreator(); } QStringList CvsEditorWidget::annotationPreviousVersions(const QString &revision) const diff --git a/src/plugins/fossil/annotationhighlighter.cpp b/src/plugins/fossil/annotationhighlighter.cpp index f7ff18c8229..bd42e5bfc59 100644 --- a/src/plugins/fossil/annotationhighlighter.cpp +++ b/src/plugins/fossil/annotationhighlighter.cpp @@ -9,10 +9,10 @@ namespace Fossil { namespace Internal { -FossilAnnotationHighlighter::FossilAnnotationHighlighter(const ChangeNumbers &changeNumbers, - QTextDocument *document) : - VcsBase::BaseAnnotationHighlighter(changeNumbers, document), - m_changesetIdPattern(Constants::CHANGESET_ID) +FossilAnnotationHighlighter::FossilAnnotationHighlighter(const VcsBase::Annotation &annotation, + QTextDocument *document) + : VcsBase::BaseAnnotationHighlighter(annotation, document) + , m_changesetIdPattern(Constants::CHANGESET_ID) { QTC_CHECK(m_changesetIdPattern.isValid()); } diff --git a/src/plugins/fossil/annotationhighlighter.h b/src/plugins/fossil/annotationhighlighter.h index 8f283eb5d96..fba44146d93 100644 --- a/src/plugins/fossil/annotationhighlighter.h +++ b/src/plugins/fossil/annotationhighlighter.h @@ -4,7 +4,6 @@ #pragma once #include -#include namespace Fossil { namespace Internal { @@ -12,7 +11,7 @@ namespace Internal { class FossilAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighter { public: - explicit FossilAnnotationHighlighter(const ChangeNumbers &changeNumbers, + explicit FossilAnnotationHighlighter(const VcsBase::Annotation &annotation, QTextDocument *document = nullptr); private: diff --git a/src/plugins/fossil/fossileditor.cpp b/src/plugins/fossil/fossileditor.cpp index 0b5e5255f34..5e719515981 100644 --- a/src/plugins/fossil/fossileditor.cpp +++ b/src/plugins/fossil/fossileditor.cpp @@ -91,7 +91,7 @@ QStringList FossilEditorWidget::annotationPreviousVersions(const QString &revisi VcsBase::BaseAnnotationHighlighterCreator FossilEditorWidget::annotationHighlighterCreator() const { - return [](const QSet &changes) { return new FossilAnnotationHighlighter(changes); }; + return VcsBase::getAnnotationHighlighterCreator(); } } // namespace Fossil::Internal diff --git a/src/plugins/git/annotationhighlighter.cpp b/src/plugins/git/annotationhighlighter.cpp index 9696212555b..c37e349ef39 100644 --- a/src/plugins/git/annotationhighlighter.cpp +++ b/src/plugins/git/annotationhighlighter.cpp @@ -6,11 +6,10 @@ namespace Git { namespace Internal { -GitAnnotationHighlighter::GitAnnotationHighlighter(const ChangeNumbers &changeNumbers, - QTextDocument *document) : - VcsBase::BaseAnnotationHighlighter(changeNumbers, document) -{ -} +GitAnnotationHighlighter::GitAnnotationHighlighter(const VcsBase::Annotation &annotation, + QTextDocument *document) + : VcsBase::BaseAnnotationHighlighter(annotation, document) +{} QString GitAnnotationHighlighter::changeNumber(const QString &block) const { diff --git a/src/plugins/git/annotationhighlighter.h b/src/plugins/git/annotationhighlighter.h index 4c319211c5c..33f899f94ca 100644 --- a/src/plugins/git/annotationhighlighter.h +++ b/src/plugins/git/annotationhighlighter.h @@ -13,7 +13,7 @@ class GitAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighter { Q_OBJECT public: - explicit GitAnnotationHighlighter(const ChangeNumbers &changeNumbers, + explicit GitAnnotationHighlighter(const VcsBase::Annotation &annotation, QTextDocument *document = nullptr); private: diff --git a/src/plugins/git/giteditor.cpp b/src/plugins/git/giteditor.cpp index 66c3bc01bb7..2136846be0d 100644 --- a/src/plugins/git/giteditor.cpp +++ b/src/plugins/git/giteditor.cpp @@ -119,7 +119,7 @@ QString GitEditorWidget::changeUnderCursor(const QTextCursor &c) const VcsBase::BaseAnnotationHighlighterCreator GitEditorWidget::annotationHighlighterCreator() const { - return [](const QSet &changes) { return new GitAnnotationHighlighter(changes); }; + return VcsBase::getAnnotationHighlighterCreator(); } /* Remove the date specification from annotation, which is tabular: diff --git a/src/plugins/mercurial/annotationhighlighter.cpp b/src/plugins/mercurial/annotationhighlighter.cpp index ec75322a71e..51daa0fc4b7 100644 --- a/src/plugins/mercurial/annotationhighlighter.cpp +++ b/src/plugins/mercurial/annotationhighlighter.cpp @@ -6,10 +6,10 @@ namespace Mercurial::Internal { -MercurialAnnotationHighlighter::MercurialAnnotationHighlighter(const ChangeNumbers &changeNumbers, +MercurialAnnotationHighlighter::MercurialAnnotationHighlighter(const VcsBase::Annotation &annotation, QTextDocument *document) - : VcsBase::BaseAnnotationHighlighter(changeNumbers, document), - changeset(QLatin1String(Constants::CHANGESETID12)) + : VcsBase::BaseAnnotationHighlighter(annotation, document) + , changeset(QLatin1String(Constants::CHANGESETID12)) { } diff --git a/src/plugins/mercurial/annotationhighlighter.h b/src/plugins/mercurial/annotationhighlighter.h index 99523888e95..f6559d2b229 100644 --- a/src/plugins/mercurial/annotationhighlighter.h +++ b/src/plugins/mercurial/annotationhighlighter.h @@ -5,14 +5,12 @@ #include -#include - namespace Mercurial::Internal { class MercurialAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighter { public: - explicit MercurialAnnotationHighlighter(const ChangeNumbers &changeNumbers, + explicit MercurialAnnotationHighlighter(const VcsBase::Annotation &annotation, QTextDocument *document = nullptr); private: diff --git a/src/plugins/mercurial/mercurialeditor.cpp b/src/plugins/mercurial/mercurialeditor.cpp index 63008f19d61..1f95a4d1f7f 100644 --- a/src/plugins/mercurial/mercurialeditor.cpp +++ b/src/plugins/mercurial/mercurialeditor.cpp @@ -50,7 +50,7 @@ QString MercurialEditorWidget::changeUnderCursor(const QTextCursor &cursorIn) co VcsBase::BaseAnnotationHighlighterCreator MercurialEditorWidget::annotationHighlighterCreator() const { - return [](const QSet &changes) { return new MercurialAnnotationHighlighter(changes); }; + return VcsBase::getAnnotationHighlighterCreator(); } QString MercurialEditorWidget::decorateVersion(const QString &revision) const diff --git a/src/plugins/perforce/annotationhighlighter.cpp b/src/plugins/perforce/annotationhighlighter.cpp index 42872b98192..0079747c4ff 100644 --- a/src/plugins/perforce/annotationhighlighter.cpp +++ b/src/plugins/perforce/annotationhighlighter.cpp @@ -5,9 +5,9 @@ namespace Perforce::Internal { -PerforceAnnotationHighlighter::PerforceAnnotationHighlighter(const ChangeNumbers &changeNumbers, - QTextDocument *document) : - VcsBase::BaseAnnotationHighlighter(changeNumbers, document) +PerforceAnnotationHighlighter::PerforceAnnotationHighlighter(const VcsBase::Annotation &annotation, + QTextDocument *document) + : VcsBase::BaseAnnotationHighlighter(annotation, document) { } QString PerforceAnnotationHighlighter::changeNumber(const QString &block) const diff --git a/src/plugins/perforce/annotationhighlighter.h b/src/plugins/perforce/annotationhighlighter.h index 9c3066d3d2d..511969ffaf6 100644 --- a/src/plugins/perforce/annotationhighlighter.h +++ b/src/plugins/perforce/annotationhighlighter.h @@ -12,7 +12,7 @@ class PerforceAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighter { Q_OBJECT public: - explicit PerforceAnnotationHighlighter(const ChangeNumbers &changeNumbers, + explicit PerforceAnnotationHighlighter(const VcsBase::Annotation &annotation, QTextDocument *document = nullptr); private: diff --git a/src/plugins/perforce/perforceeditor.cpp b/src/plugins/perforce/perforceeditor.cpp index 88e790c3c03..178391760bd 100644 --- a/src/plugins/perforce/perforceeditor.cpp +++ b/src/plugins/perforce/perforceeditor.cpp @@ -53,7 +53,7 @@ QString PerforceEditorWidget::changeUnderCursor(const QTextCursor &c) const VcsBase::BaseAnnotationHighlighterCreator PerforceEditorWidget::annotationHighlighterCreator() const { - return [](const QSet &changes) { return new PerforceAnnotationHighlighter(changes); }; + return VcsBase::getAnnotationHighlighterCreator(); } QString PerforceEditorWidget::findDiffFile(const QString &f) const diff --git a/src/plugins/subversion/annotationhighlighter.cpp b/src/plugins/subversion/annotationhighlighter.cpp index 7d191824fd6..fc42b989e76 100644 --- a/src/plugins/subversion/annotationhighlighter.cpp +++ b/src/plugins/subversion/annotationhighlighter.cpp @@ -6,12 +6,11 @@ using namespace Subversion; using namespace Subversion::Internal; -SubversionAnnotationHighlighter::SubversionAnnotationHighlighter(const ChangeNumbers &changeNumbers, - QTextDocument *document) : - VcsBase::BaseAnnotationHighlighter(changeNumbers, document), - m_blank(QLatin1Char(' ')) -{ -} +SubversionAnnotationHighlighter::SubversionAnnotationHighlighter( + const VcsBase::Annotation &annotation, QTextDocument *document) + : VcsBase::BaseAnnotationHighlighter(annotation, document) + , m_blank(QLatin1Char(' ')) +{} QString SubversionAnnotationHighlighter::changeNumber(const QString &block) const { diff --git a/src/plugins/subversion/annotationhighlighter.h b/src/plugins/subversion/annotationhighlighter.h index cb8c9fc729e..014fc6add86 100644 --- a/src/plugins/subversion/annotationhighlighter.h +++ b/src/plugins/subversion/annotationhighlighter.h @@ -13,7 +13,7 @@ class SubversionAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighte { Q_OBJECT public: - explicit SubversionAnnotationHighlighter(const ChangeNumbers &changeNumbers, + explicit SubversionAnnotationHighlighter(const VcsBase::Annotation &annotation, QTextDocument *document = nullptr); private: diff --git a/src/plugins/subversion/subversioneditor.cpp b/src/plugins/subversion/subversioneditor.cpp index 5e614532d6a..ac44a4147cf 100644 --- a/src/plugins/subversion/subversioneditor.cpp +++ b/src/plugins/subversion/subversioneditor.cpp @@ -77,8 +77,7 @@ QString SubversionEditorWidget::changeUnderCursor(const QTextCursor &c) const VcsBase::BaseAnnotationHighlighterCreator SubversionEditorWidget::annotationHighlighterCreator() const { - return - [](const QSet &changes) { return new SubversionAnnotationHighlighter(changes); }; + return VcsBase::getAnnotationHighlighterCreator(); } QStringList SubversionEditorWidget::annotationPreviousVersions(const QString &v) const diff --git a/src/plugins/texteditor/syntaxhighlighter.cpp b/src/plugins/texteditor/syntaxhighlighter.cpp index 24a96522b38..36c4549487c 100644 --- a/src/plugins/texteditor/syntaxhighlighter.cpp +++ b/src/plugins/texteditor/syntaxhighlighter.cpp @@ -308,6 +308,9 @@ SyntaxHighlighter::~SyntaxHighlighter() void SyntaxHighlighter::setDocument(QTextDocument *doc) { Q_D(SyntaxHighlighter); + if (d->doc == doc) + return; + if (d->doc) { disconnect(d->doc, &QTextDocument::contentsChange, this, &SyntaxHighlighter::reformatBlocks); @@ -317,7 +320,9 @@ void SyntaxHighlighter::setDocument(QTextDocument *doc) blk.layout()->clearFormats(); cursor.endEditBlock(); } + QTextDocument *oldDoc = d->doc; d->doc = doc; + documentChanged(oldDoc, d->doc); if (d->doc) { if (!d->noAutomaticHighlighting) { connect(d->doc, &QTextDocument::contentsChange, this, &SyntaxHighlighter::reformatBlocks); diff --git a/src/plugins/texteditor/syntaxhighlighter.h b/src/plugins/texteditor/syntaxhighlighter.h index 856aef72487..78e0e031849 100644 --- a/src/plugins/texteditor/syntaxhighlighter.h +++ b/src/plugins/texteditor/syntaxhighlighter.h @@ -54,7 +54,7 @@ public: void setNoAutomaticHighlighting(bool noAutomatic); public slots: - void rehighlight(); + virtual void rehighlight(); void rehighlightBlock(const QTextBlock &block); protected: @@ -86,6 +86,9 @@ protected: QTextBlock currentBlock() const; +protected: + virtual void documentChanged(QTextDocument * /*oldDoc*/, QTextDocument * /*newDoc*/) {}; + private: void setTextFormatCategories(const QVector> &categories); void reformatBlocks(int from, int charsRemoved, int charsAdded); diff --git a/src/plugins/vcsbase/baseannotationhighlighter.cpp b/src/plugins/vcsbase/baseannotationhighlighter.cpp index 3a9f8963dc5..26e44ebd91c 100644 --- a/src/plugins/vcsbase/baseannotationhighlighter.cpp +++ b/src/plugins/vcsbase/baseannotationhighlighter.cpp @@ -8,10 +8,10 @@ #include -#include #include -#include +#include #include +#include typedef QMap ChangeNumberFormatMap; @@ -37,8 +37,10 @@ public: BaseAnnotationHighlighterPrivate(BaseAnnotationHighlighter *q_) : q(q_) { } void updateOtherFormats(); + QSet annotationChanges() const; ChangeNumberFormatMap m_changeNumberMap; + Annotation m_annotation; QColor m_background; BaseAnnotationHighlighter *const q; }; @@ -52,15 +54,39 @@ void BaseAnnotationHighlighterPrivate::updateOtherFormats() q->setChangeNumbers(Utils::toSet(m_changeNumberMap.keys())); } -BaseAnnotationHighlighter::BaseAnnotationHighlighter(const ChangeNumbers &changeNumbers, - QTextDocument *document) : - TextEditor::SyntaxHighlighter(document), - d(new BaseAnnotationHighlighterPrivate(this)) + +QSet BaseAnnotationHighlighterPrivate::annotationChanges() const +{ + if (!q->document()) + return {}; + + QSet changes; + const QString text = q->document()->toPlainText(); + QStringView txt = QStringView(text); + if (txt.isEmpty()) + return changes; + if (!m_annotation.separatorPattern.pattern().isEmpty()) { + const QRegularExpressionMatch match = m_annotation.separatorPattern.match(txt); + if (match.hasMatch()) + txt.truncate(match.capturedStart()); + } + QRegularExpressionMatchIterator i = m_annotation.entryPattern.globalMatch(txt); + while (i.hasNext()) { + const QRegularExpressionMatch match = i.next(); + changes.insert(match.captured(1)); + } + return changes; +} + + +BaseAnnotationHighlighter::BaseAnnotationHighlighter(const Annotation &annotation, QTextDocument *document) + : TextEditor::SyntaxHighlighter(document) + , d(new BaseAnnotationHighlighterPrivate(this)) { setDefaultTextFormatCategories(); - d->updateOtherFormats(); - setChangeNumbers(changeNumbers); + d->m_annotation = annotation; + d->updateOtherFormats(); } BaseAnnotationHighlighter::~BaseAnnotationHighlighter() @@ -68,6 +94,27 @@ BaseAnnotationHighlighter::~BaseAnnotationHighlighter() delete d; } +void BaseAnnotationHighlighter::documentChanged(QTextDocument *oldDoc, QTextDocument *newDoc) +{ + if (oldDoc) + disconnect(oldDoc, + &QTextDocument::contentsChange, + this, + &BaseAnnotationHighlighter::setChangeNumbersForAnnotation); + + if (newDoc) + connect(newDoc, + &QTextDocument::contentsChange, + this, + &BaseAnnotationHighlighter::setChangeNumbersForAnnotation); +} + +void BaseAnnotationHighlighter::setChangeNumbersForAnnotation() +{ + setChangeNumbers(d->annotationChanges()); + d->updateOtherFormats(); +} + void BaseAnnotationHighlighter::setChangeNumbers(const ChangeNumbers &changeNumbers) { d->m_changeNumberMap.clear(); @@ -105,4 +152,14 @@ void BaseAnnotationHighlighter::setFontSettings(const TextEditor::FontSettings & d->updateOtherFormats(); } +void BaseAnnotationHighlighter::rehighlight() +{ + const QSet changes = d->annotationChanges(); + if (changes.isEmpty()) + return; + + setChangeNumbers(changes); + TextEditor::SyntaxHighlighter::rehighlight(); +} + } // namespace VcsBase diff --git a/src/plugins/vcsbase/baseannotationhighlighter.h b/src/plugins/vcsbase/baseannotationhighlighter.h index 34cf6e45ce3..7c6f58c9feb 100644 --- a/src/plugins/vcsbase/baseannotationhighlighter.h +++ b/src/plugins/vcsbase/baseannotationhighlighter.h @@ -7,9 +7,18 @@ #include +#include + namespace VcsBase { class BaseAnnotationHighlighterPrivate; +class Annotation +{ +public: + QRegularExpression separatorPattern; + QRegularExpression entryPattern; +}; + class VCSBASE_EXPORT BaseAnnotationHighlighter : public TextEditor::SyntaxHighlighter { Q_OBJECT @@ -17,19 +26,26 @@ class VCSBASE_EXPORT BaseAnnotationHighlighter : public TextEditor::SyntaxHighli public: typedef QSet ChangeNumbers; - explicit BaseAnnotationHighlighter(const ChangeNumbers &changeNumbers, + explicit BaseAnnotationHighlighter(const Annotation &annotation, QTextDocument *document = nullptr); ~BaseAnnotationHighlighter() override; - void setChangeNumbers(const ChangeNumbers &changeNumbers); void highlightBlock(const QString &text) override; void setFontSettings(const TextEditor::FontSettings &fontSettings) override; +public slots: + void rehighlight() override; + +protected: + void documentChanged(QTextDocument *oldDoc, QTextDocument *newDoc) override; + private: // Implement this to return the change number of a line virtual QString changeNumber(const QString &block) const = 0; + void setChangeNumbers(const ChangeNumbers &changeNumbers); + void setChangeNumbersForAnnotation(); BaseAnnotationHighlighterPrivate *const d; friend class BaseAnnotationHighlighterPrivate; diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index b768c58c974..93fb8af7e09 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -549,8 +549,8 @@ public: QRegularExpression m_diffFilePattern; QRegularExpression m_logEntryPattern; - QRegularExpression m_annotationEntryPattern; - QRegularExpression m_annotationSeparatorPattern; + VcsBase::Annotation m_annotation; + QList m_entrySections; // line number where this section starts int m_cursorLine = -1; int m_firstLineNumber = -1; @@ -665,12 +665,12 @@ void VcsBaseEditorWidget::setLogEntryPattern(const QString &pattern) void VcsBaseEditorWidget::setAnnotationEntryPattern(const QString &pattern) { - regexpFromString(pattern, &d->m_annotationEntryPattern, QRegularExpression::MultilineOption); + regexpFromString(pattern, &d->m_annotation.entryPattern, QRegularExpression::MultilineOption); } void VcsBaseEditorWidget::setAnnotationSeparatorPattern(const QString &pattern) { - regexpFromString(pattern, &d->m_annotationSeparatorPattern); + regexpFromString(pattern, &d->m_annotation.separatorPattern); } bool VcsBaseEditorWidget::supportChangeLinks() const @@ -1101,11 +1101,11 @@ void VcsBaseEditorWidget::slotActivateAnnotation() disconnect(this, &QPlainTextEdit::textChanged, this, &VcsBaseEditorWidget::slotActivateAnnotation); if (auto ah = qobject_cast(textDocument()->syntaxHighlighter())) { - ah->setChangeNumbers(changes); ah->rehighlight(); } else { BaseAnnotationHighlighterCreator creator = annotationHighlighterCreator(); - textDocument()->setSyntaxHighlighterCreator([creator, changes] { return creator(changes); }); + textDocument()->setSyntaxHighlighterCreator( + [creator, annotation = d->m_annotation] { return creator(annotation); }); } } @@ -1550,12 +1550,12 @@ QSet VcsBaseEditorWidget::annotationChanges() const QStringView txt = QStringView(text); if (txt.isEmpty()) return changes; - if (!d->m_annotationSeparatorPattern.pattern().isEmpty()) { - const QRegularExpressionMatch match = d->m_annotationSeparatorPattern.match(txt); + if (!d->m_annotation.separatorPattern.pattern().isEmpty()) { + const QRegularExpressionMatch match = d->m_annotation.separatorPattern.match(txt); if (match.hasMatch()) txt.truncate(match.capturedStart()); } - QRegularExpressionMatchIterator i = d->m_annotationEntryPattern.globalMatch(txt); + QRegularExpressionMatchIterator i = d->m_annotation.entryPattern.globalMatch(txt); while (i.hasNext()) { const QRegularExpressionMatch match = i.next(); changes.insert(match.captured(1)); diff --git a/src/plugins/vcsbase/vcsbaseeditor.h b/src/plugins/vcsbase/vcsbaseeditor.h index b34f01ce7e4..ff1fec774db 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.h +++ b/src/plugins/vcsbase/vcsbaseeditor.h @@ -27,6 +27,7 @@ class VcsBaseEditorConfig; class VcsBaseEditorWidget; class VcsCommand; class VcsEditorFactory; +class Annotation; // Documentation inside enum EditorContentType @@ -110,7 +111,12 @@ public: }; using BaseAnnotationHighlighterCreator - = std::function &)>; + = std::function; +template +BaseAnnotationHighlighterCreator getAnnotationHighlighterCreator() +{ + return [](const VcsBase::Annotation &annotation) { return new T(annotation); }; +} class VCSBASE_EXPORT VcsBaseEditorWidget : public TextEditor::TextEditorWidget { From 10c37c1439567d15a380b42e6607cafa62f80571 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Nov 2023 14:35:16 +0100 Subject: [PATCH 0318/1546] Vcpkg: Dissolve plugin pimple ... by using the new setup pattern for the manifest editor. Change-Id: I9eed8481e7f8ca08af34cd3a04c9909cd56d3b6a Reviewed-by: Alessandro Portale --- src/plugins/vcpkg/vcpkgmanifesteditor.cpp | 30 +++++++++++++++-------- src/plugins/vcpkg/vcpkgmanifesteditor.h | 10 +++----- src/plugins/vcpkg/vcpkgplugin.cpp | 15 ++++-------- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/plugins/vcpkg/vcpkgmanifesteditor.cpp b/src/plugins/vcpkg/vcpkgmanifesteditor.cpp index 3e90b0f7076..eaaa52eb709 100644 --- a/src/plugins/vcpkg/vcpkgmanifesteditor.cpp +++ b/src/plugins/vcpkg/vcpkgmanifesteditor.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -153,16 +154,6 @@ static TextEditor::TextDocument *createVcpkgManifestDocument() return doc; } -VcpkgManifestEditorFactory::VcpkgManifestEditorFactory() -{ - setId(Constants::VCPKGMANIFEST_EDITOR_ID); - setDisplayName(Tr::tr("Vcpkg Manifest Editor")); - addMimeType(Constants::VCPKGMANIFEST_MIMETYPE); - setDocumentCreator(createVcpkgManifestDocument); - setEditorWidgetCreator([] { return new VcpkgManifestEditorWidget; }); - setUseGenericHighlighter(true); -} - QByteArray addDependencyToManifest(const QByteArray &manifest, const QString &package) { constexpr char dependenciesKey[] = "dependencies"; @@ -173,4 +164,23 @@ QByteArray addDependencyToManifest(const QByteArray &manifest, const QString &pa return QJsonDocument(jsonObject).toJson(); } +class VcpkgManifestEditorFactory final : public TextEditor::TextEditorFactory +{ +public: + VcpkgManifestEditorFactory() + { + setId(Constants::VCPKGMANIFEST_EDITOR_ID); + setDisplayName(Tr::tr("Vcpkg Manifest Editor")); + addMimeType(Constants::VCPKGMANIFEST_MIMETYPE); + setDocumentCreator(createVcpkgManifestDocument); + setEditorWidgetCreator([] { return new VcpkgManifestEditorWidget; }); + setUseGenericHighlighter(true); + } +}; + +void setupVcpkgManifestEditor() +{ + static VcpkgManifestEditorFactory theVcpkgManifestEditorFactory; +} + } // namespace Vcpkg::Internal diff --git a/src/plugins/vcpkg/vcpkgmanifesteditor.h b/src/plugins/vcpkg/vcpkgmanifesteditor.h index 3d88ba79655..0d92503f3c6 100644 --- a/src/plugins/vcpkg/vcpkgmanifesteditor.h +++ b/src/plugins/vcpkg/vcpkgmanifesteditor.h @@ -3,16 +3,12 @@ #pragma once -#include +#include namespace Vcpkg::Internal { -class VcpkgManifestEditorFactory : public TextEditor::TextEditorFactory -{ -public: - VcpkgManifestEditorFactory(); -}; - QByteArray addDependencyToManifest(const QByteArray &manifest, const QString &package); +void setupVcpkgManifestEditor(); + } // namespace Vcpkg::Internal diff --git a/src/plugins/vcpkg/vcpkgplugin.cpp b/src/plugins/vcpkg/vcpkgplugin.cpp index c6d7c08f512..2247bda2cf5 100644 --- a/src/plugins/vcpkg/vcpkgplugin.cpp +++ b/src/plugins/vcpkg/vcpkgplugin.cpp @@ -13,12 +13,6 @@ namespace Vcpkg::Internal { -class VcpkgPluginPrivate -{ -public: - VcpkgManifestEditorFactory vcpkgManifestEditorFactory; -}; - class VcpkgPlugin final : public ExtensionSystem::IPlugin { Q_OBJECT @@ -29,16 +23,17 @@ public: { ProjectExplorer::JsonWizardFactory::addWizardPath(":/vcpkg/wizards/"); - d = std::make_unique(); + setupVcpkgManifestEditor(); #ifdef WITH_TESTS addTest(); #endif } - void extensionsInitialized() final { settings().setVcpkgRootEnvironmentVariable(); } - - std::unique_ptr d; + void extensionsInitialized() final + { + settings().setVcpkgRootEnvironmentVariable(); + } }; } // namespace Vcpkg::Internal From 221d4ad563e6be93c146f294235e51138bc372c2 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 16 Nov 2023 11:58:48 +0100 Subject: [PATCH 0319/1546] BaseAnnotationHighlighter: Get rid of QTextDocument arg from c'tor It's always nullptr. Change-Id: Ia392b826f0afe8562b90b916722c374c5244d9aa Reviewed-by: Jarek Kobus --- src/plugins/bazaar/annotationhighlighter.cpp | 5 ++--- src/plugins/bazaar/annotationhighlighter.h | 3 +-- src/plugins/clearcase/annotationhighlighter.cpp | 5 ++--- src/plugins/clearcase/annotationhighlighter.h | 3 +-- src/plugins/cvs/cvseditor.cpp | 5 ++--- src/plugins/fossil/annotationhighlighter.cpp | 5 ++--- src/plugins/fossil/annotationhighlighter.h | 3 +-- src/plugins/git/annotationhighlighter.cpp | 5 ++--- src/plugins/git/annotationhighlighter.h | 3 +-- src/plugins/mercurial/annotationhighlighter.cpp | 5 ++--- src/plugins/mercurial/annotationhighlighter.h | 3 +-- src/plugins/perforce/annotationhighlighter.cpp | 5 ++--- src/plugins/perforce/annotationhighlighter.h | 3 +-- src/plugins/subversion/annotationhighlighter.cpp | 5 ++--- src/plugins/subversion/annotationhighlighter.h | 3 +-- src/plugins/vcsbase/baseannotationhighlighter.cpp | 5 ++--- src/plugins/vcsbase/baseannotationhighlighter.h | 3 +-- 17 files changed, 26 insertions(+), 43 deletions(-) diff --git a/src/plugins/bazaar/annotationhighlighter.cpp b/src/plugins/bazaar/annotationhighlighter.cpp index 86220f52662..e059ce23b14 100644 --- a/src/plugins/bazaar/annotationhighlighter.cpp +++ b/src/plugins/bazaar/annotationhighlighter.cpp @@ -6,9 +6,8 @@ namespace Bazaar::Internal { -BazaarAnnotationHighlighter::BazaarAnnotationHighlighter(const VcsBase::Annotation &annotation, - QTextDocument *document) - : VcsBase::BaseAnnotationHighlighter(annotation, document) +BazaarAnnotationHighlighter::BazaarAnnotationHighlighter(const VcsBase::Annotation &annotation) + : VcsBase::BaseAnnotationHighlighter(annotation) , m_changeset(QLatin1String(Constants::ANNOTATE_CHANGESET_ID)) {} diff --git a/src/plugins/bazaar/annotationhighlighter.h b/src/plugins/bazaar/annotationhighlighter.h index c0a789d6c94..2e72096ff67 100644 --- a/src/plugins/bazaar/annotationhighlighter.h +++ b/src/plugins/bazaar/annotationhighlighter.h @@ -10,8 +10,7 @@ namespace Bazaar::Internal { class BazaarAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighter { public: - explicit BazaarAnnotationHighlighter(const VcsBase::Annotation &annotation, - QTextDocument *document = nullptr); + explicit BazaarAnnotationHighlighter(const VcsBase::Annotation &annotation); private: QString changeNumber(const QString &block) const override; diff --git a/src/plugins/clearcase/annotationhighlighter.cpp b/src/plugins/clearcase/annotationhighlighter.cpp index 25d076b13d0..76d1ce61ed6 100644 --- a/src/plugins/clearcase/annotationhighlighter.cpp +++ b/src/plugins/clearcase/annotationhighlighter.cpp @@ -5,9 +5,8 @@ namespace ClearCase::Internal { -ClearCaseAnnotationHighlighter::ClearCaseAnnotationHighlighter(const VcsBase::Annotation &annotation, - QTextDocument *document) - : VcsBase::BaseAnnotationHighlighter(annotation, document) +ClearCaseAnnotationHighlighter::ClearCaseAnnotationHighlighter(const VcsBase::Annotation &annotation) + : VcsBase::BaseAnnotationHighlighter(annotation) {} QString ClearCaseAnnotationHighlighter::changeNumber(const QString &block) const diff --git a/src/plugins/clearcase/annotationhighlighter.h b/src/plugins/clearcase/annotationhighlighter.h index 46830ee033f..afa9a9ecb82 100644 --- a/src/plugins/clearcase/annotationhighlighter.h +++ b/src/plugins/clearcase/annotationhighlighter.h @@ -12,8 +12,7 @@ class ClearCaseAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighter { Q_OBJECT public: - explicit ClearCaseAnnotationHighlighter(const VcsBase::Annotation &annotation, - QTextDocument *document = nullptr); + explicit ClearCaseAnnotationHighlighter(const VcsBase::Annotation &annotation); private: QString changeNumber(const QString &block) const override; diff --git a/src/plugins/cvs/cvseditor.cpp b/src/plugins/cvs/cvseditor.cpp index 85b9e8b7d88..0643b6ec20a 100644 --- a/src/plugins/cvs/cvseditor.cpp +++ b/src/plugins/cvs/cvseditor.cpp @@ -25,9 +25,8 @@ namespace Cvs::Internal { class CvsAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighter { public: - explicit CvsAnnotationHighlighter(const VcsBase::Annotation &annotation, - QTextDocument *document = nullptr) - : VcsBase::BaseAnnotationHighlighter(annotation, document) + explicit CvsAnnotationHighlighter(const VcsBase::Annotation &annotation) + : VcsBase::BaseAnnotationHighlighter(annotation) {} private: diff --git a/src/plugins/fossil/annotationhighlighter.cpp b/src/plugins/fossil/annotationhighlighter.cpp index bd42e5bfc59..53f9e7a849b 100644 --- a/src/plugins/fossil/annotationhighlighter.cpp +++ b/src/plugins/fossil/annotationhighlighter.cpp @@ -9,9 +9,8 @@ namespace Fossil { namespace Internal { -FossilAnnotationHighlighter::FossilAnnotationHighlighter(const VcsBase::Annotation &annotation, - QTextDocument *document) - : VcsBase::BaseAnnotationHighlighter(annotation, document) +FossilAnnotationHighlighter::FossilAnnotationHighlighter(const VcsBase::Annotation &annotation) + : VcsBase::BaseAnnotationHighlighter(annotation) , m_changesetIdPattern(Constants::CHANGESET_ID) { QTC_CHECK(m_changesetIdPattern.isValid()); diff --git a/src/plugins/fossil/annotationhighlighter.h b/src/plugins/fossil/annotationhighlighter.h index fba44146d93..f8751881eb3 100644 --- a/src/plugins/fossil/annotationhighlighter.h +++ b/src/plugins/fossil/annotationhighlighter.h @@ -11,8 +11,7 @@ namespace Internal { class FossilAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighter { public: - explicit FossilAnnotationHighlighter(const VcsBase::Annotation &annotation, - QTextDocument *document = nullptr); + explicit FossilAnnotationHighlighter(const VcsBase::Annotation &annotation); private: QString changeNumber(const QString &block) const final; diff --git a/src/plugins/git/annotationhighlighter.cpp b/src/plugins/git/annotationhighlighter.cpp index c37e349ef39..cfc6a54c96f 100644 --- a/src/plugins/git/annotationhighlighter.cpp +++ b/src/plugins/git/annotationhighlighter.cpp @@ -6,9 +6,8 @@ namespace Git { namespace Internal { -GitAnnotationHighlighter::GitAnnotationHighlighter(const VcsBase::Annotation &annotation, - QTextDocument *document) - : VcsBase::BaseAnnotationHighlighter(annotation, document) +GitAnnotationHighlighter::GitAnnotationHighlighter(const VcsBase::Annotation &annotation) + : VcsBase::BaseAnnotationHighlighter(annotation) {} QString GitAnnotationHighlighter::changeNumber(const QString &block) const diff --git a/src/plugins/git/annotationhighlighter.h b/src/plugins/git/annotationhighlighter.h index 33f899f94ca..03da6f8fcc4 100644 --- a/src/plugins/git/annotationhighlighter.h +++ b/src/plugins/git/annotationhighlighter.h @@ -13,8 +13,7 @@ class GitAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighter { Q_OBJECT public: - explicit GitAnnotationHighlighter(const VcsBase::Annotation &annotation, - QTextDocument *document = nullptr); + explicit GitAnnotationHighlighter(const VcsBase::Annotation &annotation); private: QString changeNumber(const QString &block) const override; diff --git a/src/plugins/mercurial/annotationhighlighter.cpp b/src/plugins/mercurial/annotationhighlighter.cpp index 51daa0fc4b7..415876abca4 100644 --- a/src/plugins/mercurial/annotationhighlighter.cpp +++ b/src/plugins/mercurial/annotationhighlighter.cpp @@ -6,9 +6,8 @@ namespace Mercurial::Internal { -MercurialAnnotationHighlighter::MercurialAnnotationHighlighter(const VcsBase::Annotation &annotation, - QTextDocument *document) - : VcsBase::BaseAnnotationHighlighter(annotation, document) +MercurialAnnotationHighlighter::MercurialAnnotationHighlighter(const VcsBase::Annotation &annotation) + : VcsBase::BaseAnnotationHighlighter(annotation) , changeset(QLatin1String(Constants::CHANGESETID12)) { } diff --git a/src/plugins/mercurial/annotationhighlighter.h b/src/plugins/mercurial/annotationhighlighter.h index f6559d2b229..0d70c87603f 100644 --- a/src/plugins/mercurial/annotationhighlighter.h +++ b/src/plugins/mercurial/annotationhighlighter.h @@ -10,8 +10,7 @@ namespace Mercurial::Internal { class MercurialAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighter { public: - explicit MercurialAnnotationHighlighter(const VcsBase::Annotation &annotation, - QTextDocument *document = nullptr); + explicit MercurialAnnotationHighlighter(const VcsBase::Annotation &annotation); private: QString changeNumber(const QString &block) const override; diff --git a/src/plugins/perforce/annotationhighlighter.cpp b/src/plugins/perforce/annotationhighlighter.cpp index 0079747c4ff..f701a286b67 100644 --- a/src/plugins/perforce/annotationhighlighter.cpp +++ b/src/plugins/perforce/annotationhighlighter.cpp @@ -5,9 +5,8 @@ namespace Perforce::Internal { -PerforceAnnotationHighlighter::PerforceAnnotationHighlighter(const VcsBase::Annotation &annotation, - QTextDocument *document) - : VcsBase::BaseAnnotationHighlighter(annotation, document) +PerforceAnnotationHighlighter::PerforceAnnotationHighlighter(const VcsBase::Annotation &annotation) + : VcsBase::BaseAnnotationHighlighter(annotation) { } QString PerforceAnnotationHighlighter::changeNumber(const QString &block) const diff --git a/src/plugins/perforce/annotationhighlighter.h b/src/plugins/perforce/annotationhighlighter.h index 511969ffaf6..fa4483355b4 100644 --- a/src/plugins/perforce/annotationhighlighter.h +++ b/src/plugins/perforce/annotationhighlighter.h @@ -12,8 +12,7 @@ class PerforceAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighter { Q_OBJECT public: - explicit PerforceAnnotationHighlighter(const VcsBase::Annotation &annotation, - QTextDocument *document = nullptr); + explicit PerforceAnnotationHighlighter(const VcsBase::Annotation &annotation); private: QString changeNumber(const QString &block) const override; diff --git a/src/plugins/subversion/annotationhighlighter.cpp b/src/plugins/subversion/annotationhighlighter.cpp index fc42b989e76..b94cbe9c60c 100644 --- a/src/plugins/subversion/annotationhighlighter.cpp +++ b/src/plugins/subversion/annotationhighlighter.cpp @@ -6,9 +6,8 @@ using namespace Subversion; using namespace Subversion::Internal; -SubversionAnnotationHighlighter::SubversionAnnotationHighlighter( - const VcsBase::Annotation &annotation, QTextDocument *document) - : VcsBase::BaseAnnotationHighlighter(annotation, document) +SubversionAnnotationHighlighter::SubversionAnnotationHighlighter(const VcsBase::Annotation &annotation) + : VcsBase::BaseAnnotationHighlighter(annotation) , m_blank(QLatin1Char(' ')) {} diff --git a/src/plugins/subversion/annotationhighlighter.h b/src/plugins/subversion/annotationhighlighter.h index 014fc6add86..8da44f42978 100644 --- a/src/plugins/subversion/annotationhighlighter.h +++ b/src/plugins/subversion/annotationhighlighter.h @@ -13,8 +13,7 @@ class SubversionAnnotationHighlighter : public VcsBase::BaseAnnotationHighlighte { Q_OBJECT public: - explicit SubversionAnnotationHighlighter(const VcsBase::Annotation &annotation, - QTextDocument *document = nullptr); + explicit SubversionAnnotationHighlighter(const VcsBase::Annotation &annotation); private: QString changeNumber(const QString &block) const override; diff --git a/src/plugins/vcsbase/baseannotationhighlighter.cpp b/src/plugins/vcsbase/baseannotationhighlighter.cpp index 26e44ebd91c..a4fa4bc7f2a 100644 --- a/src/plugins/vcsbase/baseannotationhighlighter.cpp +++ b/src/plugins/vcsbase/baseannotationhighlighter.cpp @@ -78,9 +78,8 @@ QSet BaseAnnotationHighlighterPrivate::annotationChanges() const return changes; } - -BaseAnnotationHighlighter::BaseAnnotationHighlighter(const Annotation &annotation, QTextDocument *document) - : TextEditor::SyntaxHighlighter(document) +BaseAnnotationHighlighter::BaseAnnotationHighlighter(const Annotation &annotation) + : TextEditor::SyntaxHighlighter() , d(new BaseAnnotationHighlighterPrivate(this)) { setDefaultTextFormatCategories(); diff --git a/src/plugins/vcsbase/baseannotationhighlighter.h b/src/plugins/vcsbase/baseannotationhighlighter.h index 7c6f58c9feb..4b29697fe61 100644 --- a/src/plugins/vcsbase/baseannotationhighlighter.h +++ b/src/plugins/vcsbase/baseannotationhighlighter.h @@ -26,8 +26,7 @@ class VCSBASE_EXPORT BaseAnnotationHighlighter : public TextEditor::SyntaxHighli public: typedef QSet ChangeNumbers; - explicit BaseAnnotationHighlighter(const Annotation &annotation, - QTextDocument *document = nullptr); + explicit BaseAnnotationHighlighter(const Annotation &annotation); ~BaseAnnotationHighlighter() override; From 77ff522d71c981b944fe1094d150e592e6ac427a Mon Sep 17 00:00:00 2001 From: Serg Kryvonos Date: Tue, 21 Nov 2023 12:50:09 +0100 Subject: [PATCH 0320/1546] Allow TimerThreadData instance MinGW1120_64 compatibility with C++20 on. Change-Id: I40963e75e1b4e6afa8e9c873f57943539de16906 Reviewed-by: Jarek Kobus --- src/libs/solutions/tasking/tasktree.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 916d56d5156..ab4f4ccd41d 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -2671,6 +2671,7 @@ struct TimerThreadData { Q_DISABLE_COPY_MOVE(TimerThreadData) + TimerThreadData() = default; // defult constructor is required for initializing with {} since C++20 by Mingw 11.20 QHash m_timerIdToTimerData = {}; QMultiMap m_deadlineToTimerId = {}; int m_timerIdCounter = 0; From 0a3d71cd364ddf84562cdb00b8a2d2f9d19fcd24 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 16 Nov 2023 20:51:26 +0100 Subject: [PATCH 0321/1546] TaskTree: Update docs to the recent API changes Add new enum types. Update done handlers. Describe TaskAdapter's Deleter. Replace Utils::ProcessTask and FileTransferTask, which are specific to QtCreator, with QProcessTask and NetworkQueryTask, which come with the TaskTree solution. Remove the note about Storage not being reentrant, as currently it is already reentrant. Add reentrant marker to all classes. Fix some example snippets. Fixes: QTCREATORBUG-29834 Change-Id: I351447ffdbdd641239efd0320250d6a4a8b26f08 Reviewed-by: Leena Miettinen Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 645 ++++++++++++++---------- 1 file changed, 376 insertions(+), 269 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index ab4f4ccd41d..7eee7d64a23 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -66,6 +66,7 @@ private: \inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution \brief TaskInterface is the abstract base class for implementing custom task adapters. + \reentrant To implement a custom task adapter, derive your adapter from the \c TaskAdapter class template. TaskAdapter automatically creates and destroys @@ -88,8 +89,8 @@ private: \fn void TaskInterface::done(DoneResult result) Emit this signal from the \c TaskAdapter's subclass, when the \c Task is finished. - Pass \c DoneResult::Success as a \a result argument when the task finishes with success; - otherwise, when an error occurs, pass \c DoneResult::Error. + Pass DoneResult::Success as a \a result argument when the task finishes with success; + otherwise, when an error occurs, pass DoneResult::Error. */ /*! @@ -97,6 +98,7 @@ private: \inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution \brief A class template for implementing custom task adapters. + \reentrant The TaskAdapter class template is responsible for creating a task of the \c Task type, starting it, and reporting success or an error when the task is finished. @@ -118,49 +120,55 @@ private: // Adapts Worker's interface to work with task tree class WorkerTaskAdapter : public TaskAdapter {...}; - // Defines WorkerTask as a new task tree element + // Defines WorkerTask as a new custom task type to be placed inside Group items using WorkerTask = CustomTask; \endcode + Optionally, you may pass a custom \c Deleter for the associated \c Task + as a second template parameter of your \c TaskAdapter subclass. + When the \c Deleter parameter is omitted, the \c std::default_delete is used by default. + The custom \c Deleter is useful when the destructor of the running \c Task + may potentially block the caller thread. Instead of blocking, the custom deleter may move + the running task into a separate thread and implement the blocking destruction there. + In this way, the fast destruction (seen from the caller thread) of the running task + with a blocking destructor may be achieved. + For more information on implementing the custom task adapters, refer to \l {Task Adapters}. \sa start(), done(), task() */ /*! - \typealias TaskAdapter::Type + \fn template > TaskAdapter::TaskAdapter() - Type alias for the \c Task type. -*/ + Creates a task adapter for the given \c Task type. -/*! - \fn template TaskAdapter::TaskAdapter() - - Creates a task adapter for the given \c Task type. Internally, it creates - an instance of \c Task, which is accessible via the task() method. + Internally, it creates an instance of \c Task, which is accessible via the task() method. + The optionally provided \c Deleter is used instead of the \c Task destructor. + When \c Deleter is omitted, the \c std::default_delete is used by default. \sa task() */ /*! - \fn template Task *TaskAdapter::task() + \fn template > Task *TaskAdapter::task() Returns the pointer to the associated \c Task instance. */ /*! - \fn template Task *TaskAdapter::task() const + \fn template > Task *TaskAdapter::task() const \overload - Returns the const pointer to the associated \c Task instance. + Returns the \c const pointer to the associated \c Task instance. */ /*! \class Tasking::GroupItem \inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution - \brief GroupItem represents the basic element that may be a part of any - \l {Tasking::Group} {Group}. + \brief GroupItem represents the basic element that may be a part of any Group. + \reentrant GroupItem is a basic element that may be a part of any \l {Tasking::Group} {Group}. It encapsulates the functionality provided by any GroupItem's subclass. @@ -176,14 +184,14 @@ private: \li \l CustomTask \li Defines asynchronous task type and task's start, done, and error handlers. Aliased with a unique task name, such as, \c ConcurrentCallTask - or \l NetworkQueryTask. Asynchronous tasks are the main reason for using a task tree. + or NetworkQueryTask. Asynchronous tasks are the main reason for using a task tree. \row - \li \l Group + \li \l {Tasking::Group} {Group} \li A container for other group items. Since the group is of the GroupItem type, it's possible to nest it inside another group. The group is seen by its parent as a single asynchronous task. \row - \li \l Storage + \li Storage \li Enables the child tasks of a group to exchange data. When Storage is placed inside a group, the task tree instantiates the storage object just before the group is entered, @@ -192,9 +200,8 @@ private: \li Other group control items \li The items returned by \l {Tasking::parallelLimit()} {parallelLimit()} or \l {Tasking::workflowPolicy()} {workflowPolicy()} influence the group's behavior. - The items returned by \l {Tasking::onGroupSetup()} {onGroupSetup()}, - \l {Tasking::onGroupDone()} {onGroupDone()} or - \l {Tasking::onGroupError()} {onGroupError()} define custom handlers called when + The items returned by \l {Tasking::onGroupSetup()} {onGroupSetup()} or + \l {Tasking::onGroupDone()} {onGroupDone()} define custom handlers called when the group starts or ends execution. \endtable */ @@ -205,6 +212,7 @@ private: \inmodule TaskingSolution \brief Group represents the basic element for composing declarative recipes describing how to execute and handle a nested tree of asynchronous tasks. + \reentrant Group is a container for other group items. It encloses child tasks into one unit, which is seen by the group's parent as a single, asynchronous task. @@ -277,7 +285,7 @@ private: // the *storage or storage-> operators. sequential, Storage(storage), - NetworkQueryTask(onFirstSetup, onFirstDone), + NetworkQueryTask(onFirstSetup, onFirstDone, CallDoneIf::Success), ConcurrentCallTask(onSecondSetup) }; \endcode @@ -330,7 +338,7 @@ private: */ /*! - \fn GroupItem Group::withTimeout(std::chrono::milliseconds timeout, const GroupEndHandler &handler) const + \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. @@ -345,16 +353,17 @@ private: \class Tasking::CustomTask \inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution - \brief A class template used for declaring task items and defining their setup, - done, and error handlers. + \brief A class template used for declaring custom task items and defining their setup + and done handlers. + \reentrant - The CustomTask class template is used inside TaskTree for describing custom task items. + Describes custom task items within task tree recipes. - Custom task names are aliased with unique names using the CustomTask template + Custom task names are aliased with unique names using the \c CustomTask template with a given TaskAdapter subclass as a template parameter. - For example, \c ConcurrentCallTask is an alias to the CustomTask that is defined + For example, \c ConcurrentCallTask is an alias to the \c CustomTask that is defined to work with \c ConcurrentCall as an associated task class. - The following table contains all the built-in tasks and their associated task classes: + The following table contains example custom tasks and their associated task classes: \table \header @@ -387,29 +396,91 @@ private: /*! \typealias CustomTask::Task - Type alias for \c Adapter::Type. - - This is the associated task's type. + Type alias for the task type associated with the custom task's \c Adapter. */ /*! - \typealias CustomTask::EndHandler + \typealias CustomTask::Deleter - Type alias for \c std::function. + Type alias for the task's type deleter associated with the custom task's \c Adapter. */ /*! - \fn template template CustomTask::CustomTask(SetupHandler &&setup, const EndHandler &done, const EndHandler &error) + \typealias CustomTask::TaskSetupHandler - Constructs the CustomTask instance and attaches the \a setup, \a done, and \a error - handlers to the task. When the running task tree is about to start the task, + Type alias for \c std::function. + + The \c TaskSetupHandler is an optional argument of a custom task element's constructor. + Any function with the above signature, when passed as a task setup handler, + will be called by the running task tree after the task is created and before it is started. + + Inside the body of the handler, you may configure the task according to your needs. + The additional parameters, including storages, may be passed to the handler + via the lambda capture. + You can decide dynamically whether the task should be started or skipped with + success or an error. + + \note Do not start the task inside the start handler by yourself. Leave it for TaskTree, + otherwise the behavior is undefined. + + The return value of the handler instructs the running task tree on how to proceed + after the handler's invocation is finished. The return value of SetupResult::Continue + instructs the task tree to continue running, that is, to execute the associated \c Task. + The return value of SetupResult::StopWithSuccess or SetupResult::StopWithError + instructs the task tree to skip the task's execution and finish it immediately with + success or an error, respectively. + + When the return type is either SetupResult::StopWithSuccess or SetupResult::StopWithError, + the task's done handler (if provided) isn't called afterwards. + + The constructor of a custom task accepts also functions in the shortened form of + \c std::function, that is, the return value is \c void. + In this case, it's assumed that the return value is SetupResult::Continue. + + \sa CustomTask(), TaskDoneHandler, GroupSetupHandler +*/ + +/*! + \typealias CustomTask::TaskDoneHandler + + Type alias for \c std::function. + + The \c TaskDoneHandler is an optional argument of a custom task element's constructor. + Any function with the above signature, when passed as a task done handler, + will be called by the running task tree after the task execution finished and before + the final result of the execution is reported back to the parent group. + + Inside the body of the handler you may retrieve the final data from the finished task. + The additional parameters, including storages, may be passed to the handler + via the lambda capture. + It is also possible to decide dynamically whether the task should finish with its return + value, or the final result should be tweaked. + + The DoneWith argument is optional and your done handler may omit it. + When provided, it holds the info about the final result of a task that will be + reported to its parent. + + If you do not plan to read any data from the finished task, + you may omit the \c {const Task &} argument. + + The returned DoneResult value is optional and your handler may return \c void instead. + In this case, the final result of the task will be equal to the value indicated by + the DoneWith argument. When the handler returns the DoneResult value, + the task's final result may be tweaked inside the done handler's body by the returned value. + + \sa CustomTask(), TaskSetupHandler, GroupDoneHandler +*/ + +/*! + \fn template template CustomTask::CustomTask(SetupHandler &&setup = TaskSetupHandler(), DoneHandler &&done = TaskDoneHandler(), CallDoneIf callDoneIf = CallDoneIf::SuccessOrError) + + Constructs a \c CustomTask instance and attaches the \a setup and \a done handlers to the task. + When the running task tree is about to start the task, it instantiates the associated \l Task object, invokes \a setup handler with a \e reference - to the created task, and starts it. When the running task finishes with success or an error, - the task tree invokes \a done or \a error handler, respectively, - with a \e {const reference} to the created task. + to the created task, and starts it. When the running task finishes, + the task tree invokes a \a done handler, with a \c const \e reference to the created task. - The passed \a setup handler is either of the \c std::function or - \c std::function type. For example: + The passed \a setup handler is of the \l TaskSetupHandler type. For example: \code static void parseAndLog(const QString &input); @@ -438,35 +509,23 @@ private: }; \endcode - When the passed \a setup handler is of the \c std::function type, - the return value of the handler instructs the running tree on how to proceed after - the handler's invocation is finished. The default return value of SetupResult::Continue - instructs the tree to continue running, i.e. to execute the associated \c Task. - The return value of SetupResult::StopWithSuccess or SetupResult::StopWithError instructs - the tree to skip the task's execution and finish immediately with success or an error, - respectively. - When the return type is either SetupResult::StopWithSuccess or SetupResult::StopWithError, - the task's \a done or \a error handler (even if provided) are not called afterwards. + The \a done handler is of the \l TaskDoneHandler type. + By default, the \a done handler is invoked whenever the task finishes. + Pass a non-default value for the \a callDoneIf argument when you want the handler to be called + only on a successful or failed execution. - The \a setup handler may be of a shortened form of std::function, - i.e. the return value is void. In this case it's assumed that the return value is - SetupResult::Continue by default. - - When the running task finishes, one of \a done or \a error handlers is called, - depending on whether it finished with success or an error, respectively. - Both handlers are of std::function type. + \sa TaskSetupHandler, TaskDoneHandler */ /*! - \fn template GroupItem CustomTask::withTimeout(std::chrono::milliseconds timeout, const GroupItem::GroupEndHandler &handler) const + \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, the \a handler is invoked (if provided), the task is stopped, - and the returned item finishes with an error. + 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 stopped, and the returned item finishes with an error. */ /*! @@ -518,8 +577,8 @@ private: tasks finished, the group finishes with an error. If a group is empty, it finishes with an error. - Whenever a child task's result causes the Group to stop, - i.e. in case of StopOnError, StopOnSuccess, or StopOnSuccessOrError policies, + Whenever a child task's result causes the Group to stop, that is, + in case of StopOnError, StopOnSuccess, or StopOnSuccessOrError policies, the Group stops the other running child tasks (if any - for example in parallel mode), and skips executing tasks it has not started yet (for example, in the sequential mode - those, that are placed after the failed task). Both stopping and skipping child tasks @@ -572,7 +631,7 @@ private: If a child of a group is also a group, the child group runs its tasks according to its own workflow policy. When a parent group stops the running child group because - of parent group's workflow policy, i.e. when the StopOnError, StopOnSuccess, + of parent group's workflow policy, that is, when the StopOnError, StopOnSuccess, or StopOnSuccessOrError policy was used for the parent, the child group's result is reported according to the \b Result column and to the \b {child group's workflow policy} row in the table above. @@ -654,73 +713,138 @@ private: \value StopWithSuccess The group's or task's execution stops immediately with success. When returned from the group's setup handler, all child tasks are skipped, - and the group's onGroupDone() handler is invoked (if provided). + and the group's onGroupDone() handler is invoked with DoneWith::Success. The group reports success to its parent. The group's workflow policy is ignored. When returned from the task's setup handler, the task isn't started, its done handler isn't invoked, and the task reports success to its parent. \value StopWithError The group's or task's execution stops immediately with an error. When returned from the group's setup handler, all child tasks are skipped, - and the group's onGroupError() handler is invoked (if provided). + and the group's onGroupDone() handler is invoked with DoneWith::Error. The group reports an error to its parent. The group's workflow policy is ignored. When returned from the task's setup handler, the task isn't started, its error handler isn't invoked, and the task reports an error to its parent. */ +/*! + \enum Tasking::DoneResult + + This enum is optionally returned from the group's or task's done handler function. + When the done handler doesn't return any value, that is, its return type is \c void, + its final return value is automatically deduced by the running task tree and reported + to its parent group. + + When the done handler returns the DoneResult, you can tweak the final return value + inside the handler. + + When the DoneResult is returned by the group's done handler, the group's workflow policy + is ignored. + + This enum is also used inside the TaskInterface::done() signal and it indicates whether + the task finished with success or an error. + + \value Success + The group's or task's execution ends with success. + \value Error + The group's or task's execution ends with an error. +*/ + +/*! + \enum Tasking::DoneWith + + This enum is an optional argument for the group's or task's done handler. + It indicates whether the group or task finished with success or an error, or it was canceled. + + It is also used as an argument inside the TaskTree::done() signal, + indicating the final result of the TaskTree execution. + + \value Success + The group's or task's execution ended with success. + \value Error + The group's or task's execution ended with an error. + \value Cancel + The group's or task's execution was canceled. This happens when the user calls + TaskTree::stop() for the running task tree or when the group's workflow policy + results in stopping some of its running children. + Tweaking the done handler's final result by returning Tasking::DoneResult from + the handler is no-op when the group's or task's execution was canceled. +*/ + +/*! + \enum Tasking::CallDoneIf + + This enum is an optional argument for the \l onGroupDone() element or custom task's constructor. + It instructs the task tree on when the group's or task's done handler should be invoked. + + \value SuccessOrError + The done handler is always invoked. + \value Success + The done handler is invoked only after successful execution, + that is, when DoneWith::Success. + \value Error + The done handler is invoked only after failed execution, + that is, when DoneWith::Error or when DoneWith::Cancel. +*/ + /*! \typealias GroupItem::GroupSetupHandler Type alias for \c std::function. - The GroupSetupHandler is used when constructing the onGroupSetup() element. + The \c GroupSetupHandler is an argument of the onGroupSetup() element. Any function with the above signature, when passed as a group setup handler, will be called by the running task tree when the group execution starts. The return value of the handler instructs the running group on how to proceed after the handler's invocation is finished. The default return value of SetupResult::Continue - instructs the group to continue running, i.e. to start executing its child tasks. + instructs the group to continue running, that is, to start executing its child tasks. The return value of SetupResult::StopWithSuccess or SetupResult::StopWithError instructs the group to skip the child tasks' execution and finish immediately with success or an error, respectively. - When the return type is either SetupResult::StopWithSuccess - of SetupResult::StopWithError, the group's done or error handler (if provided) - is called synchronously immediately afterwards. + When the return type is either SetupResult::StopWithSuccess or SetupResult::StopWithError, + the group's done handler (if provided) is called synchronously immediately afterwards. \note Even if the group setup handler returns StopWithSuccess or StopWithError, - one of the group's done or error handlers is invoked. This behavior differs - from that of task handlers and might change in the future. + the group's done handler is invoked. This behavior differs from that of task done handler + and might change in the future. - The onGroupSetup() accepts also functions in the shortened form of \c std::function, - i.e. the return value is void. In this case it's assumed that the return value - is SetupResult::Continue by default. + The onGroupSetup() element accepts also functions in the shortened form of + \c std::function, that is, the return value is \c void. + In this case, it's assumed that the return value is SetupResult::Continue. - \sa onGroupSetup() + \sa onGroupSetup(), GroupDoneHandler, CustomTask::TaskSetupHandler */ /*! - \typealias GroupItem::GroupEndHandler + \typealias GroupItem::GroupDoneHandler - Type alias for \c std::function. + Type alias for \c std::function. - The GroupEndHandler is used when constructing the onGroupDone() and onGroupError() elements. - Any function with the above signature, when passed as a group done or error handler, - will be called by the running task tree when the group ends with success or an error, - respectively. + The \c GroupDoneHandler is an argument of the onGroupDone() element. + Any function with the above signature, when passed as a group done handler, + will be called by the running task tree when the group execution ends. - \sa onGroupDone(), onGroupError() + The DoneWith argument is optional and your done handler may omit it. + When provided, it holds the info about the final result of a group that will be + reported to its parent. + + The returned DoneResult value is optional and your handler may return \c void instead. + In this case, the final result of the group will be equal to the value indicated by + the DoneWith argument. When the handler returns the DoneResult value, + the group's final result may be tweaked inside the done handler's body by the returned value. + + \sa onGroupDone(), GroupSetupHandler, CustomTask::TaskDoneHandler */ -// TODO: Fix docs - /*! - \fn template GroupItem onGroupSetup(SetupHandler &&handler) + \fn template GroupItem onGroupSetup(Handler &&handler) Constructs a group's element holding the group setup handler. The \a handler is invoked whenever the group starts. - The passed \a handler is either of \c std::function or \c std::function - type. For more information on possible argument type, refer to + The passed \a handler is either of the \c std::function or the + \c std::function type. For more information on a possible handler type, refer to \l {GroupItem::GroupSetupHandler}. When the \a handler is invoked, none of the group's child tasks are running yet. @@ -729,41 +853,31 @@ private: after the storages are constructed, so that the \a handler may already perform some initial modifications to the active storages. - \sa GroupItem::GroupSetupHandler, onGroupDone(), onGroupError() + \sa GroupItem::GroupSetupHandler, onGroupDone() */ -// TODO: Fix docs - /*! + \fn template GroupItem onGroupDone(Handler &&handler, CallDoneIf callDoneIf = CallDoneIf::SuccessOrError) + Constructs a group's element holding the group done handler. - The \a handler is invoked whenever the group finishes with success. - Depending on the group's workflow policy, this handler may also be called - when the running group is stopped (e.g. when finishAllAndSuccess element was used). - - When the \a handler is invoked, all of the group's child tasks are already finished. - - If a group contains the Storage elements, the \a handler is invoked - before the storages are destructed, so that the \a handler may still - perform a last read of the active storages' data. - - \sa GroupItem::GroupEndHandler, onGroupSetup(), onGroupError() -*/ - -// TODO: Fix docs - -/*! - Constructs a group's element holding the group error handler. - The \a handler is invoked whenever the group finishes with an error. + By default, the \a handler is invoked whenever the group finishes. + Pass a non-default value for the \a callDoneIf argument when you want the handler to be called + only on a successful or failed execution. Depending on the group's workflow policy, this handler may also be called when the running group is stopped (e.g. when stopOnError element was used). + The passed \a handler is of the \c std::function type. + Optionally, each of the return DoneResult type or the argument DoneWith type may be omitted + (that is, its return type may be \c void). For more information on a possible handler type, + refer to \l {GroupItem::GroupDoneHandler}. + When the \a handler is invoked, all of the group's child tasks are already finished. If a group contains the Storage elements, the \a handler is invoked before the storages are destructed, so that the \a handler may still perform a last read of the active storages' data. - \sa GroupItem::GroupEndHandler, onGroupSetup(), onGroupDone() + \sa GroupItem::GroupDoneHandler, onGroupSetup() */ /*! @@ -784,7 +898,7 @@ private: \li When \a limit equals to 1, it means that only one child task may run at the time. This means the sequential execution, and the \l sequential element may be used instead. - In this case child tasks run in chain, so the next child task starts after + In this case, child tasks run in chain, so the next child task starts after the previous child task has finished. \li When other positive number is passed as \a limit, the group's child tasks run @@ -1602,46 +1716,46 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith \inheaderfile solutions/tasking/tasktree.h \inmodule TaskingSolution \brief The TaskTree class runs an async task tree structure defined in a declarative way. + \reentrant Use the Tasking namespace to build extensible, declarative task tree - structures that contain possibly asynchronous tasks, such as Process, - FileTransfer, or ConcurrentCall. TaskTree structures enable you + structures that contain possibly asynchronous tasks, such as QProcess, + NetworkQuery, or ConcurrentCall. TaskTree structures enable you to create a sophisticated mixture of a parallel or sequential flow of tasks in the form of a tree and to run it any time later. \section1 Root Element and Tasks The TaskTree has a mandatory Group root element, which may contain - any number of tasks of various types, such as ProcessTask, FileTransferTask, + any number of tasks of various types, such as QProcessTask, NetworkQueryTask, or ConcurrentCallTask: \code using namespace Tasking; const Group root { - ProcessTask(...), - ConcurrentCallTask(...), - FileTransferTask(...) + QProcessTask(...), + NetworkQueryTask(...), + ConcurrentCallTask(...) }; TaskTree *taskTree = new TaskTree(root); - connect(taskTree, &TaskTree::done, ...); // a successfully finished handler - connect(taskTree, &TaskTree::errorOccurred, ...); // an erroneously finished handler + connect(taskTree, &TaskTree::done, ...); // finish handler taskTree->start(); \endcode The task tree above has a top level element of the Group type that contains - tasks of the ProcessTask, FileTransferTask, and ConcurrentCallTask type. + tasks of the QProcessTask, NetworkQueryTask, and ConcurrentCallTask type. After taskTree->start() is called, the tasks are run in a chain, starting - with ProcessTask. When the ProcessTask finishes successfully, the ConcurrentCallTask - task is started. Finally, when the asynchronous task finishes successfully, the - FileTransferTask task is started. + with QProcessTask. When the QProcessTask finishes successfully, the NetworkQueryTask + task is started. Finally, when the network task finishes successfully, the + ConcurrentCallTask task is started. When the last running task finishes with success, the task tree is considered - to have run successfully and the TaskTree::done() signal is emitted. + to have run successfully and the done() signal is emitted with DoneWith::Success. When a task finishes with an error, the execution of the task tree is stopped and the remaining tasks are skipped. The task tree finishes with an error and - sends the TaskTree::errorOccurred() signal. + sends the TaskTree::done() signal with DoneWith::Error. \section1 Groups @@ -1653,27 +1767,27 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith const Group root { Group { parallel, - ProcessTask(...), + QProcessTask(...), ConcurrentCallTask(...) }, - FileTransferTask(...) + NetworkQueryTask(...) }; \endcode The example above differs from the first example in that the root element has - a subgroup that contains the ProcessTask and ConcurrentCallTask. The subgroup is a - sibling element of the FileTransferTask in the root. The subgroup contains an + a subgroup that contains the QProcessTask and ConcurrentCallTask. The subgroup is a + sibling element of the NetworkQueryTask in the root. The subgroup contains an additional \e parallel element that instructs its Group to execute its tasks in parallel. - So, when the tree above is started, the ProcessTask and ConcurrentCallTask start + So, when the tree above is started, the QProcessTask and ConcurrentCallTask start immediately and run in parallel. Since the root group doesn't contain a \e parallel element, its direct child tasks are run in sequence. Thus, the - FileTransferTask starts when the whole subgroup finishes. The group is + NetworkQueryTask starts when the whole subgroup finishes. The group is considered as finished when all its tasks have finished. The order in which the tasks finish is not relevant. - So, depending on which task lasts longer (ProcessTask or ConcurrentCallTask), the + So, depending on which task lasts longer (QProcessTask or ConcurrentCallTask), the following scenarios can take place: \table @@ -1687,8 +1801,8 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith \li Sub Group starts \li Sub Group starts \row - \li ProcessTask starts - \li ProcessTask starts + \li QProcessTask starts + \li QProcessTask starts \row \li ConcurrentCallTask starts \li ConcurrentCallTask starts @@ -1696,26 +1810,26 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith \li ... \li ... \row - \li \b {ProcessTask finishes} + \li \b {QProcessTask finishes} \li \b {ConcurrentCallTask finishes} \row \li ... \li ... \row \li \b {ConcurrentCallTask finishes} - \li \b {ProcessTask finishes} + \li \b {QProcessTask finishes} \row \li Sub Group finishes \li Sub Group finishes \row - \li FileTransferTask starts - \li FileTransferTask starts + \li NetworkQueryTask starts + \li NetworkQueryTask starts \row \li ... \li ... \row - \li FileTransferTask finishes - \li FileTransferTask finishes + \li NetworkQueryTask finishes + \li NetworkQueryTask finishes \row \li Root Group finishes \li Root Group finishes @@ -1728,24 +1842,24 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith The presented scenarios assume that all tasks run successfully. If a task fails during execution, the task tree finishes with an error. In particular, - when ProcessTask finishes with an error while ConcurrentCallTask is still being executed, + when QProcessTask finishes with an error while ConcurrentCallTask is still being executed, the ConcurrentCallTask is automatically stopped, the subgroup finishes with an error, - the FileTransferTask is skipped, and the tree finishes with an error. + the NetworkQueryTask is skipped, and the tree finishes with an error. \section1 Task Types Each task type is associated with its corresponding task class that executes - the task. For example, a ProcessTask inside a task tree is associated with - the Process class that executes the process. The associated objects are + the task. For example, a QProcessTask inside a task tree is associated with + the QProcess class that executes the process. The associated objects are automatically created, started, and destructed exclusively by the task tree at the appropriate time. - If a root group consists of five sequential ProcessTask tasks, and the task tree - executes the group, it creates an instance of Process for the first - ProcessTask and starts it. If the Process instance finishes successfully, - the task tree destructs it and creates a new Process instance for the - second ProcessTask, and so on. If the first task finishes with an error, the task - tree stops creating Process instances, and the root group finishes with an + If a root group consists of five sequential QProcessTask tasks, and the task tree + executes the group, it creates an instance of QProcess for the first + QProcessTask and starts it. If the QProcess instance finishes successfully, + the task tree destructs it and creates a new QProcess instance for the + second QProcessTask, and so on. If the first task finishes with an error, the task + tree stops creating QProcess instances, and the root group finishes with an error. The following table shows examples of task types and their corresponding task @@ -1757,8 +1871,8 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith \li Associated Task Class \li Brief Description \row - \li ProcessTask - \li Utils::Process + \li QProcessTask + \li QProcess \li Starts process. \row \li ConcurrentCallTask @@ -1767,11 +1881,11 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith \row \li TaskTreeTask \li Tasking::TaskTree - \li Starts a nested task tree. + \li Starts nested task tree. \row - \li FileTransferTask - \li ProjectExplorer::FileTransfer - \li Starts file transfer between different devices. + \li NetworkQueryTask + \li NetworkQuery + \li Starts network download. \endtable \section1 Task Handlers @@ -1786,17 +1900,17 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith handler should always take a \e reference to the associated task class object: \code - const auto onSetup = [](Process &process) { + const auto onSetup = [](QProcess &process) { process.setCommand({"sleep", {"3"}}); }; const Group root { - ProcessTask(onSetup) + QProcessTask(onSetup) }; \endcode - You can modify the passed Process in the setup handler, so that the task + You can modify the passed QProcess in the setup handler, so that the task tree can start the process according to your configuration. - You should not call \e {process.start();} in the setup handler, + You should not call \c {process.start();} in the setup handler, as the task tree calls it when needed. The setup handler is optional. When used, it must be the first argument of the task's constructor. @@ -1827,35 +1941,31 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith corresponding task normally or skip it and report success or an error. For more information about inter-task data exchange, see \l Storage. - \section2 Task's Done and Error Handlers + \section2 Task's Done Handler - When a running task finishes, the task tree invokes an optionally provided - done or error handler. Both handlers should always take a \e {const reference} - to the associated task class object: + When a running task finishes, the task tree invokes an optionally provided done handler. + The handler should always take a \c const \e reference to the associated task class object: \code - const auto onSetup = [](Process &process) { + const auto onSetup = [](QProcess &process) { process.setCommand({"sleep", {"3"}}); }; - const auto onDone = [](const Process &process) { - qDebug() << "Success" << process.cleanedStdOut(); - }; - const auto onError = [](const Process &process) { - qDebug() << "Failure" << process.cleanedStdErr(); + const auto onDone = [](const QProcess &process, DoneWith result) { + if (result == DoneWith::Success) + qDebug() << "Success" << process.cleanedStdOut(); + else + qDebug() << "Failure" << process.cleanedStdErr(); }; const Group root { - ProcessTask(onSetup, onDone, onError) + QProcessTask(onSetup, onDone) }; \endcode - The done and error handlers may collect output data from Process, and store it - for further processing or perform additional actions. The done handler is optional. - When used, it must be the second argument of the task's constructor. - The error handler is also optional. When used, it must always be the third argument. - You can omit the handlers or substitute the ones that you do not need with curly braces ({}). + The done handler may collect output data from QProcess, and store it + for further processing or perform additional actions. \note If the task setup handler returns StopWithSuccess or StopWithError, - neither the done nor error handler is invoked. + the done handler is not invoked. \section1 Group Handlers @@ -1874,7 +1984,7 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith }; const Group root { onGroupSetup(onSetup), - ProcessTask(...) + QProcessTask(...) }; \endcode @@ -1897,17 +2007,17 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith onGroupSetup([] { qDebug() << "Root setup"; }), Group { onGroupSetup([] { qDebug() << "Group 1 setup"; return SetupResult::Continue; }), - ProcessTask(...) // Process 1 + QProcessTask(...) // Process 1 }, Group { onGroupSetup([] { qDebug() << "Group 2 setup"; return SetupResult::StopWithSuccess; }), - ProcessTask(...) // Process 2 + QProcessTask(...) // Process 2 }, Group { onGroupSetup([] { qDebug() << "Group 3 setup"; return SetupResult::StopWithError; }), - ProcessTask(...) // Process 3 + QProcessTask(...) // Process 3 }, - ProcessTask(...) // Process 4 + QProcessTask(...) // Process 4 }; \endcode @@ -1957,31 +2067,33 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith not started yet, and reports an error. \endtable - \section2 Groups's Done and Error Handlers + \section2 Groups's Done Handler - A Group's done or error handler is executed after the successful or failed - execution of its tasks, respectively. The final value reported by the - group depends on its \l {Workflow Policy}. The handlers can apply other - necessary actions. The done and error handlers are defined inside the - onGroupDone() and onGroupError() elements of a group, respectively. They do not - take arguments: + A Group's done handler is executed after the successful or failed execution of its tasks. + The final value reported by the group depends on its \l {Workflow Policy}. + The handler can apply other necessary actions. + The done handler is defined inside the onGroupDone() element of a group. + It may take the optional DoneWith argument, indicating the successful or failed execution: \code const Group root { onGroupSetup([] { qDebug() << "Root setup"; }), - ProcessTask(...), - onGroupDone([] { qDebug() << "Root finished with success"; }), - onGroupError([] { qDebug() << "Root finished with an error"; }) + QProcessTask(...), + onGroupDone([](DoneWith result) { + if (result == DoneWith::Success) + qDebug() << "Root finished with success"; + else + qDebug() << "Root finished with an error"; + }) }; \endcode - The group done and error handlers are optional. If you add more than one - onGroupDone() or onGroupError() each to a group, an assert is triggered at - runtime that includes an error message. + The group done handler is optional. If you add more than one onGroupDone() to a group, + an assert is triggered at runtime that includes an error message. \note Even if the group setup handler returns StopWithSuccess or StopWithError, - one of the group's done or error handlers is invoked. This behavior differs - from that of task handlers and might change in the future. + the group's done handler is invoked. This behavior differs from that of task done handler + and might change in the future. \section1 Other Group Elements @@ -2051,8 +2163,8 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith const Group root { // [7] runtime: task tree creates an instance of CopyStorage when root is entered Storage(storage), - ConcurrentCallTask(onLoaderSetup, onLoaderDone), - ConcurrentCallTask(onSaverSetup, onSaverDone) + ConcurrentCallTask(onLoaderSetup, onLoaderDone, CallDoneIf::Success), + ConcurrentCallTask(onSaverSetup, onSaverDone, CallDoneIf::Success) }; return root; } @@ -2061,7 +2173,10 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith const QString destination = ...; TaskTree taskTree(copyRecipe(source, destination)); connect(&taskTree, &TaskTree::done, - &taskTree, [] { qDebug() << "The copying finished successfully."; }); + &taskTree, [](DoneWith result) { + if (result == DoneWith::Success) + qDebug() << "The copying finished successfully."; + }); tasktree.start(); \endcode @@ -2077,9 +2192,9 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith tree leaves this group, the existing instance of CopyStorage struct is destructed as it's no longer needed. - If several task trees that hold a copy of the common TreeStorage - instance run simultaneously, each task tree contains its own copy of the - CopyStorage struct. + If several task trees that hold a copy of the common TreeStorage instance + run simultaneously (including also a case when the task trees are run in different threads), + each task tree contains its own copy of the CopyStorage struct. You can access CopyStorage from any handler in the group with a storage object. This includes all handlers of all descendant tasks of the group with @@ -2104,24 +2219,20 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith \li Insert the TreeStorage instance into a group [7] \endlist - \note The current implementation assumes that all running task trees - containing copies of the same TreeStorage run in the same thread. Otherwise, - the behavior is undefined. - - \section1 TaskTree + \section1 TaskTree class TaskTree executes the tree structure of asynchronous tasks according to the recipe described by the Group root element. As TaskTree is also an asynchronous task, it can be a part of another TaskTree. To place a nested TaskTree inside another TaskTree, insert the TaskTreeTask - element into other tree's Group element. + element into another Group element. TaskTree reports progress of completed tasks when running. The progress value is increased when a task finishes or is skipped or stopped. - When TaskTree is finished and the TaskTree::done() or TaskTree::errorOccurred() - signal is emitted, the current value of the progress equals the maximum - progress value. Maximum progress equals the total number of tasks in a tree. + When TaskTree is finished and the TaskTree::done() signal is emitted, + the current value of the progress equals the maximum progress value. + Maximum progress equals the total number of tasks in a tree. A nested TaskTree is counted as a single task, and its child tasks are not counted in the top level tree. Groups themselves are not counted as tasks, but their tasks are counted. @@ -2193,15 +2304,16 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith later as an argument to the task's handlers. The instance of this class parameter automatically becomes a member of the TaskAdapter template, and is accessible through the TaskAdapter::task() method. The constructor - of TimerTaskAdapter initially configures the QTimer object and connects - to the QTimer::timeout signal. When the signal is triggered, TimerTaskAdapter - emits the \c done(DoneResult::Success) signal to inform the task tree that the task finished - successfully. If it emits \c done(DoneResult::Error), the task finished with an error. + of \c TimerTaskAdapter initially configures the QTimer object and connects + to the QTimer::timeout() signal. When the signal is triggered, \c TimerTaskAdapter + emits the TaskInterface::done(DoneResult::Success) signal to inform the task tree that + the task finished successfully. If it emits TaskInterface::done(DoneResult::Error), + the task finished with an error. The TaskAdapter::start() method starts the timer. - To make QTimer accessible inside TaskTree under the \e TimerTask name, - define TimerTask to be an alias to the Tasking::CustomTask. - TimerTask becomes a new task type, using TimerTaskAdapter. + To make QTimer accessible inside TaskTree under the \c TimerTask name, + define \c TimerTask to be an alias to the CustomTask<\c TimerTaskAdapter>. + \c TimerTask becomes a new custom task type, using \c TimerTaskAdapter. The new task type is now registered, and you can use it in TaskTree: @@ -2220,6 +2332,8 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith and objects of this class should be freely destructible. It should be allowed to destroy a running object, preferably without waiting for the running task to finish (that is, safe non-blocking destructor of a running task). + To achieve a non-blocking destruction of a task that has a blocking destructor, + consider using the optional \c Deleter template parameter of the TaskAdapter. */ /*! @@ -2235,6 +2349,8 @@ TaskTree::TaskTree() {} /*! + \overload + Constructs a task tree with a given \a recipe. After the task tree is started, it executes the tasks contained inside the \a recipe and handles finished tasks according to the passed description. @@ -2251,12 +2367,12 @@ TaskTree::TaskTree(const Group &recipe) : TaskTree() When the task tree is running while being destructed, it stops all the running tasks immediately. In this case, no handlers are called, not even the groups' and - tasks' error handlers or onStorageDone() handlers. The task tree also doesn't emit any - signals from the destructor, not even errorOccurred() or progressValueChanged() signals. + tasks' done handlers or onStorageDone() handlers. The task tree also doesn't emit any + signals from the destructor, not even done() or progressValueChanged() signals. This behavior may always be relied on. It is completely safe to destruct the running task tree. - It's a usual pattern to destruct the running task tree, even from the main thread. + It's a usual pattern to destruct the running task tree. It's guaranteed that the destruction will run quickly, without having to wait for the currently running tasks to finish, provided that the used tasks implement their destructors in a non-blocking way. @@ -2300,24 +2416,24 @@ void TaskTree::setRecipe(const Group &recipe) the task tree will execute the contained tasks and handle finished tasks. When the task tree is empty, that is, constructed with a default constructor, - a call to \e start is no-op and the relevant warning message is issued. + a call to \c start() is no-op and the relevant warning message is issued. - Otherwise, when the task tree is already running, a call to \e start is ignored and the + Otherwise, when the task tree is already running, a call to \e start() is ignored and the relevant warning message is issued. Otherwise, the task tree is started. The started task tree may finish synchronously, for example when the main group's start handler returns SetupResult::StopWithError. - For this reason, the connections to the done and errorOccurred signals should be - established before calling start. Use isRunning() in order to detect whether - the task tree is still running after a call to start(). + For this reason, the connection to the done signal should be established before calling + \c start(). Use isRunning() in order to detect whether the task tree is still running + after a call to \c start(). - The task tree implementation relies on the running event loop for listening to the tasks' - done signals. Make sure you have a QEventLoop or QCoreApplication or one of its + The task tree implementation relies on the running event loop. + Make sure you have a QEventLoop or QCoreApplication or one of its subclasses running (or about to be run) when calling this method. - \sa TaskTree(const Tasking::Group &recipe), setRecipe(), isRunning(), stop() + \sa TaskTree(const Tasking::Group &), setRecipe(), isRunning(), stop() */ void TaskTree::start() { @@ -2333,31 +2449,20 @@ void TaskTree::start() This signal is emitted when the task tree is started. The emission of this signal is followed synchronously by the progressValueChanged() signal with an initial \c 0 value. - \sa start(), done(), errorOccurred() + \sa start(), done() */ /*! - \fn void TaskTree::done() + \fn void TaskTree::done(DoneWith result) - This signal is emitted when the task tree finished with success. - The task tree neither calls any handler, nor emits any signal anymore after this signal - was emitted. + This signal is emitted when the task tree finished, passing the final \a result + of the execution. The task tree neither calls any handler, + nor emits any signal anymore after this signal was emitted. - Don't delete the task tree directly from this signal's handler. Use deleteLater() instead. + \note Do not delete the task tree directly from this signal's handler. + Use deleteLater() instead. - \sa started(), errorOccurred() -*/ - -/*! - \fn void TaskTree::errorOccurred() - - This signal is emitted when the task tree finished with an error. - The task tree neither calls any handler, nor emits any signal anymore after this signal - was emitted. - - Don't delete the task tree directly from this signal's handler. Use deleteLater() instead. - - \sa started(), done() + \sa started() */ /*! @@ -2366,20 +2471,20 @@ void TaskTree::start() Stops all the running tasks immediately. All running tasks finish with an error, invoking their error handlers. All running groups dispatch their handlers according to their workflow policies, - invoking one of their end handlers. The storages' onStorageDone() handlers are invoked, too. - The \l progressValueChanged signals are also being sent. + invoking their done handlers. The storages' onStorageDone() handlers are invoked, too. + The progressValueChanged() signals are also being sent. This behavior may always be relied on. - The \l stop is executed synchronously, so that after a call to \e stop + The \c stop() function is executed synchronously, so that after a call to \c stop() all running tasks are finished and the tree is already stopped. - It's guaranteed that the stop will run quickly, without any blocking wait for + It's guaranteed that \c stop() will run quickly, without any blocking wait for the currently running tasks to finish, provided the used tasks implement their destructors in a non-blocking way. When the task tree is empty, that is, constructed with a default constructor, - a call to \e stop is no-op and the relevant warning message is issued. + a call to \c stop() is no-op and the relevant warning message is issued. - Otherwise, when the task tree wasn't started, a call to stop is ignored. + Otherwise, when the task tree wasn't started, a call to \c stop() is ignored. \note Do not call this function directly from any of the running task's handlers or task tree's signals. @@ -2406,7 +2511,8 @@ bool TaskTree::isRunning() const /*! Executes a local event loop with QEventLoop::ExcludeUserInputEvents and starts the task tree. - Returns \c true if the task tree finished successfully; otherwise returns \c false. + Returns DoneWith::Success if the task tree finished successfully; + otherwise returns DoneWith::Error. \note Avoid using this method from the main thread. Use asynchronous start() instead. This method is to be used in non-main threads or in auto tests. @@ -2459,7 +2565,8 @@ DoneWith TaskTree::runBlocking(const QFuture &future) The optionally provided \a timeout is used to stop the tree automatically after \a timeout milliseconds have passed. - Returns \c true if the task tree finished successfully; otherwise returns \c false. + Returns DoneWith::Success if the task tree finished successfully; + otherwise returns DoneWith::Error. \note Avoid using this method from the main thread. Use asynchronous start() instead. This method is to be used in non-main threads or in auto tests. @@ -2508,8 +2615,8 @@ int TaskTree::taskCount() const The \a value gives the current total number of finished, stopped or skipped tasks. When the task tree is started, and after the started() signal was emitted, this signal is emitted with an initial \a value of \c 0. - When the task tree is about to finish, and before the done() or errorOccurred() signal - is emitted, this signal is emitted with the final \a value of progressMaximum(). + When the task tree is about to finish, and before the done() signal is emitted, + this signal is emitted with the final \a value of progressMaximum(). \sa progressValue(), progressMaximum() */ @@ -2545,14 +2652,14 @@ int TaskTree::progressValue() const Installs a storage setup \a handler for the \a storage to pass the initial data dynamically to the running task tree. - The \c StorageHandler takes a reference to the \c StorageStruct instance: + The \c StorageHandler takes a \e reference to the \c StorageStruct instance: \code static void save(const QString &fileName, const QByteArray &array) { ... } TreeStorage storage; - const auto onSaverSetup = [storage](ConcurrentCall &concurrent) { + const auto onSaverSetup = [storage](ConcurrentCall &concurrent) { concurrent.setConcurrentCallData(&save, "foo.txt", *storage); }; @@ -2586,23 +2693,23 @@ int TaskTree::progressValue() const Installs a storage done \a handler for the \a storage to retrieve the final data dynamically from the running task tree. - The \c StorageHandler takes a const reference to the \c StorageStruct instance: + The \c StorageHandler takes a \c const \e reference to the \c StorageStruct instance: \code static QByteArray load(const QString &fileName) { ... } TreeStorage storage; - const auto onLoaderSetup = [storage](ConcurrentCall &concurrent) { + const auto onLoaderSetup = [](ConcurrentCall &concurrent) { concurrent.setConcurrentCallData(&load, "foo.txt"); }; - const auto onLoaderDone = [storage](const ConcurrentCall &concurrent) { + const auto onLoaderDone = [storage](const ConcurrentCall &concurrent) { *storage = concurrent.result(); }; const Group root { Storage(storage), - ConcurrentCallTask(onLoaderDone, onLoaderDone) + ConcurrentCallTask(onLoaderDone, onLoaderDone, CallDoneIf::Success) }; TaskTree taskTree(root); From 86ef1476cbf10578c6c2cbaa3b5455504d0fe3b1 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Nov 2023 15:32:18 +0100 Subject: [PATCH 0322/1546] PerfProfiler: Use new setup for RunWorkerFactory Change-Id: I2792828a2e924191f4f24f666b5a61390048a0ae Reviewed-by: Jarek Kobus --- src/plugins/perfprofiler/perfprofilerplugin.cpp | 3 ++- .../perfprofiler/perfprofilerruncontrol.cpp | 15 ++++++++++++--- src/plugins/perfprofiler/perfprofilerruncontrol.h | 6 +----- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/plugins/perfprofiler/perfprofilerplugin.cpp b/src/plugins/perfprofiler/perfprofilerplugin.cpp index f7ac90eaa9a..1043d5026bd 100644 --- a/src/plugins/perfprofiler/perfprofilerplugin.cpp +++ b/src/plugins/perfprofiler/perfprofilerplugin.cpp @@ -25,7 +25,6 @@ public: RunConfiguration::registerAspect(); } - PerfProfilerRunWorkerFactory profilerWorkerFactory; PerfProfilerTool profilerTool; }; @@ -36,6 +35,8 @@ PerfProfilerPlugin::~PerfProfilerPlugin() void PerfProfilerPlugin::initialize() { + setupPerfProfilerRunWorker(); + d = new PerfProfilerPluginPrivate; #if WITH_TESTS diff --git a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp index 1919547383d..64f0edaf6ff 100644 --- a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp +++ b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp @@ -205,10 +205,19 @@ void PerfProfilerRunner::start() // PerfProfilerRunWorkerFactory -PerfProfilerRunWorkerFactory::PerfProfilerRunWorkerFactory() +class PerfProfilerRunWorkerFactory final : public RunWorkerFactory { - setProduct(); - addSupportedRunMode(ProjectExplorer::Constants::PERFPROFILER_RUN_MODE); +public: + PerfProfilerRunWorkerFactory() + { + setProduct(); + addSupportedRunMode(ProjectExplorer::Constants::PERFPROFILER_RUN_MODE); + } +}; + +void setupPerfProfilerRunWorker() +{ + static PerfProfilerRunWorkerFactory thePerfProfilerRunWorkerFactory; } } // PerfProfiler::Internal diff --git a/src/plugins/perfprofiler/perfprofilerruncontrol.h b/src/plugins/perfprofiler/perfprofilerruncontrol.h index 4a027900420..9db8655f417 100644 --- a/src/plugins/perfprofiler/perfprofilerruncontrol.h +++ b/src/plugins/perfprofiler/perfprofilerruncontrol.h @@ -23,10 +23,6 @@ private: ProjectExplorer::RunWorker *m_perfRecordWorker = nullptr; }; -class PerfProfilerRunWorkerFactory final : public ProjectExplorer::RunWorkerFactory -{ -public: - PerfProfilerRunWorkerFactory(); -}; +void setupPerfProfilerRunWorker(); } // PerfProfiler::Internal From ce99e7b748818701d523d9758c53f199cf0d62c7 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Nov 2023 15:41:14 +0100 Subject: [PATCH 0323/1546] PerfProfiler: Move PerfProfilerRunner class definition to .cpp Change-Id: I0a0c2b83c221cffc8dfaef9a40bca6662f8bbcea Reviewed-by: Jarek Kobus --- .../perfprofiler/perfprofilerruncontrol.cpp | 113 +++++++++--------- .../perfprofiler/perfprofilerruncontrol.h | 18 --- 2 files changed, 59 insertions(+), 72 deletions(-) diff --git a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp index 64f0edaf6ff..d646a99647b 100644 --- a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp +++ b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -28,10 +29,8 @@ using namespace Utils; namespace PerfProfiler::Internal { -class PerfParserWorker : public RunWorker +class PerfParserWorker final : public RunWorker { - Q_OBJECT - public: PerfParserWorker(RunControl *runControl) : RunWorker(runControl) @@ -61,7 +60,7 @@ public: connect(&m_reader, &PerfDataReader::processFailed, this, &RunWorker::reportFailure); } - void start() override + void start() final { CommandLine cmd{findPerfParser()}; m_reader.addTargetArguments(&cmd, runControl()); @@ -74,7 +73,7 @@ public: m_reader.startParser(); } - void stop() override + void stop() final { m_reader.stopParser(); } @@ -85,8 +84,7 @@ private: PerfDataReader m_reader; }; - -class LocalPerfRecordWorker : public RunWorker +class LocalPerfRecordWorker final : public RunWorker { Q_OBJECT @@ -97,7 +95,7 @@ public: setId("LocalPerfRecordWorker"); } - void start() override + void start() final { auto perfAspect = runControl()->aspect(); QTC_ASSERT(perfAspect, reportFailure(); return); @@ -119,7 +117,7 @@ public: return; } if (!m_process->cleanedStdErr().isEmpty()) - appendMessage(m_process->cleanedStdErr(), Utils::StdErrFormat); + appendMessage(m_process->cleanedStdErr(), StdErrFormat); reportStopped(); }); @@ -130,11 +128,11 @@ public: m_process->setCommand(cmd); m_process->setWorkingDirectory(runControl()->workingDirectory()); - appendMessage("Starting Perf: " + cmd.toUserOutput(), Utils::NormalMessageFormat); + appendMessage("Starting Perf: " + cmd.toUserOutput(), NormalMessageFormat); m_process->start(); } - void stop() override + void stop() final { if (m_process) m_process->terminate(); @@ -146,62 +144,69 @@ private: QPointer m_process; }; - -PerfProfilerRunner::PerfProfilerRunner(RunControl *runControl) - : RunWorker(runControl) +class PerfProfilerRunner final : public RunWorker { - setId("PerfProfilerRunner"); +public: + explicit PerfProfilerRunner(RunControl *runControl) + : RunWorker(runControl) + { + setId("PerfProfilerRunner"); - m_perfParserWorker = new PerfParserWorker(runControl); - addStopDependency(m_perfParserWorker); + m_perfParserWorker = new PerfParserWorker(runControl); + addStopDependency(m_perfParserWorker); - // If the parser is gone, there is no point in going on. - m_perfParserWorker->setEssential(true); + // If the parser is gone, there is no point in going on. + m_perfParserWorker->setEssential(true); - if ((m_perfRecordWorker = runControl->createWorker("PerfRecorder"))) { - m_perfParserWorker->addStartDependency(m_perfRecordWorker); - addStartDependency(m_perfParserWorker); + if ((m_perfRecordWorker = runControl->createWorker("PerfRecorder"))) { + m_perfParserWorker->addStartDependency(m_perfRecordWorker); + addStartDependency(m_perfParserWorker); - } else { - m_perfRecordWorker = new LocalPerfRecordWorker(runControl); + } else { + m_perfRecordWorker = new LocalPerfRecordWorker(runControl); - m_perfRecordWorker->addStartDependency(m_perfParserWorker); - addStartDependency(m_perfRecordWorker); + m_perfRecordWorker->addStartDependency(m_perfParserWorker); + addStartDependency(m_perfRecordWorker); - // In the local case, the parser won't automatically stop when the recorder does. So we need - // to mark the recorder as essential, too. - m_perfRecordWorker->setEssential(true); + // In the local case, the parser won't automatically stop when the recorder does. So we need + // to mark the recorder as essential, too. + m_perfRecordWorker->setEssential(true); + } + + m_perfParserWorker->addStopDependency(m_perfRecordWorker); + PerfProfilerTool::instance()->onWorkerCreation(runControl); } - m_perfParserWorker->addStopDependency(m_perfRecordWorker); - PerfProfilerTool::instance()->onWorkerCreation(runControl); -} + void start() final + { + auto tool = PerfProfilerTool::instance(); + connect(tool->stopAction(), &QAction::triggered, runControl(), &RunControl::initiateStop); + connect(runControl(), &RunControl::started, PerfProfilerTool::instance(), + &PerfProfilerTool::onRunControlStarted); + connect(runControl(), &RunControl::stopped, PerfProfilerTool::instance(), + &PerfProfilerTool::onRunControlFinished); -void PerfProfilerRunner::start() -{ - auto tool = PerfProfilerTool::instance(); - connect(tool->stopAction(), &QAction::triggered, runControl(), &RunControl::initiateStop); - connect(runControl(), &RunControl::started, PerfProfilerTool::instance(), - &PerfProfilerTool::onRunControlStarted); - connect(runControl(), &RunControl::stopped, PerfProfilerTool::instance(), - &PerfProfilerTool::onRunControlFinished); + PerfDataReader *reader = m_perfParserWorker->reader(); + if (auto prw = qobject_cast(m_perfRecordWorker)) { + // That's the local case. + Process *recorder = prw->recorder(); + connect(recorder, &Process::readyReadStandardError, this, [this, recorder] { + appendMessage(QString::fromLocal8Bit(recorder->readAllRawStandardError()), + StdErrFormat); + }); + connect(recorder, &Process::readyReadStandardOutput, this, [this, reader, recorder] { + if (!reader->feedParser(recorder->readAllRawStandardOutput())) + reportFailure(Tr::tr("Failed to transfer Perf data to perfparser.")); + }); + } - PerfDataReader *reader = m_perfParserWorker->reader(); - if (auto prw = qobject_cast(m_perfRecordWorker)) { - // That's the local case. - Process *recorder = prw->recorder(); - connect(recorder, &Process::readyReadStandardError, this, [this, recorder] { - appendMessage(QString::fromLocal8Bit(recorder->readAllRawStandardError()), - Utils::StdErrFormat); - }); - connect(recorder, &Process::readyReadStandardOutput, this, [this, reader, recorder] { - if (!reader->feedParser(recorder->readAllRawStandardOutput())) - reportFailure(Tr::tr("Failed to transfer Perf data to perfparser.")); - }); + reportStarted(); } - reportStarted(); -} +private: + PerfParserWorker *m_perfParserWorker = nullptr; + RunWorker *m_perfRecordWorker = nullptr; +}; // PerfProfilerRunWorkerFactory diff --git a/src/plugins/perfprofiler/perfprofilerruncontrol.h b/src/plugins/perfprofiler/perfprofilerruncontrol.h index 9db8655f417..487562c77ed 100644 --- a/src/plugins/perfprofiler/perfprofilerruncontrol.h +++ b/src/plugins/perfprofiler/perfprofilerruncontrol.h @@ -3,26 +3,8 @@ #pragma once -#include - namespace PerfProfiler::Internal { -class PerfParserWorker; -class PerfRecordWorker; - -class PerfProfilerRunner : public ProjectExplorer::RunWorker -{ - Q_OBJECT -public: - explicit PerfProfilerRunner(ProjectExplorer::RunControl *runControl); - - void start() override; - -private: - PerfParserWorker *m_perfParserWorker = nullptr; - ProjectExplorer::RunWorker *m_perfRecordWorker = nullptr; -}; - void setupPerfProfilerRunWorker(); } // PerfProfiler::Internal From 0e91fca8fd5907141b28def80f6ecc4b7d34d7d6 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Nov 2023 16:47:59 +0100 Subject: [PATCH 0324/1546] PerfProfiler: Make PerfProfilerTraceManager a standard singleton Change-Id: I7d2c01b38e0ff2cf9b38271df3dc0a611383a1bd Reviewed-by: Jarek Kobus --- .../perfprofilerflamegraphview.cpp | 2 +- .../perfprofiler/perfprofilerruncontrol.cpp | 2 +- .../perfprofilerstatisticsview.cpp | 2 +- src/plugins/perfprofiler/perfprofilertool.cpp | 50 ++++++++----------- src/plugins/perfprofiler/perfprofilertool.h | 2 - .../perfprofiler/perfprofilertracemanager.cpp | 14 ++++-- .../perfprofiler/perfprofilertracemanager.h | 3 +- 7 files changed, 36 insertions(+), 39 deletions(-) diff --git a/src/plugins/perfprofiler/perfprofilerflamegraphview.cpp b/src/plugins/perfprofiler/perfprofilerflamegraphview.cpp index 4734b54d775..79d71b34395 100644 --- a/src/plugins/perfprofiler/perfprofilerflamegraphview.cpp +++ b/src/plugins/perfprofiler/perfprofilerflamegraphview.cpp @@ -21,7 +21,7 @@ PerfProfilerFlameGraphView::PerfProfilerFlameGraphView(QWidget *parent, PerfProf { setObjectName(QLatin1String("PerfProfilerFlameGraphView")); - PerfProfilerTraceManager *manager = tool->traceManager(); + PerfProfilerTraceManager *manager = &traceManager(); m_model = new PerfProfilerFlameGraphModel(manager); engine()->addImportPath(":/qt/qml/"); diff --git a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp index d646a99647b..2d35f1790ee 100644 --- a/src/plugins/perfprofiler/perfprofilerruncontrol.cpp +++ b/src/plugins/perfprofiler/perfprofilerruncontrol.cpp @@ -38,7 +38,7 @@ public: setId("PerfParser"); auto tool = PerfProfilerTool::instance(); - m_reader.setTraceManager(tool->traceManager()); + m_reader.setTraceManager(&traceManager()); m_reader.triggerRecordingStateChange(tool->isRecording()); connect(tool, &PerfProfilerTool::recordingChanged, diff --git a/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp b/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp index c8a98f88048..aed78ee711c 100644 --- a/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp +++ b/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp @@ -67,7 +67,7 @@ PerfProfilerStatisticsView::PerfProfilerStatisticsView(QWidget *parent, PerfProf groupLayout->addWidget(splitterVertical); setLayout(groupLayout); - PerfProfilerTraceManager *manager = tool->traceManager(); + PerfProfilerTraceManager *manager = &traceManager(); PerfProfilerStatisticsMainModel *mainModel = new PerfProfilerStatisticsMainModel(manager); PerfProfilerStatisticsRelativesModel *children = mainModel->children(); diff --git a/src/plugins/perfprofiler/perfprofilertool.cpp b/src/plugins/perfprofiler/perfprofilertool.cpp index 6951622e52b..ad3a69b31b7 100644 --- a/src/plugins/perfprofiler/perfprofilertool.cpp +++ b/src/plugins/perfprofiler/perfprofilertool.cpp @@ -54,14 +54,13 @@ static PerfProfilerTool *s_instance; PerfProfilerTool::PerfProfilerTool() { s_instance = this; - m_traceManager = new PerfProfilerTraceManager(this); - m_traceManager->registerFeatures(PerfEventType::allFeatures(), + traceManager().registerFeatures(PerfEventType::allFeatures(), nullptr, std::bind(&PerfProfilerTool::initialize, this), std::bind(&PerfProfilerTool::finalize, this), std::bind(&PerfProfilerTool::clearUi, this)); - m_modelManager = new PerfTimelineModelManager(m_traceManager); + m_modelManager = new PerfTimelineModelManager(&traceManager()); m_zoomControl = new Timeline::TimelineZoomControl(this); ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER); ActionContainer *options = ActionManager::createMenu(Constants::PerfOptionsMenuId); @@ -92,7 +91,7 @@ PerfProfilerTool::PerfProfilerTool() command = Core::ActionManager::registerAction(m_limitToRange, Constants::PerfProfilerTaskLimit, globalContext); connect(m_limitToRange, &QAction::triggered, this, [this]() { - m_traceManager->restrictByFilter(m_traceManager->rangeAndThreadFilter( + traceManager().restrictByFilter(traceManager().rangeAndThreadFilter( m_zoomControl->selectionStart(), m_zoomControl->selectionEnd())); }); @@ -103,7 +102,7 @@ PerfProfilerTool::PerfProfilerTool() Constants::PerfProfilerTaskFullRange, globalContext); connect(m_showFullRange, &QAction::triggered, this, [this]() { - m_traceManager->restrictByFilter(m_traceManager->rangeAndThreadFilter(-1, -1)); + traceManager().restrictByFilter(traceManager().rangeAndThreadFilter(-1, -1)); }); options->addAction(command); @@ -263,7 +262,7 @@ void PerfProfilerTool::createViews() m_delayLabel->setIndent(10); - connect(m_traceManager, &PerfProfilerTraceManager::error, this, [](const QString &message) { + connect(&traceManager(), &PerfProfilerTraceManager::error, this, [](const QString &message) { QMessageBox *errorDialog = new QMessageBox(ICore::dialogParent()); errorDialog->setIcon(QMessageBox::Warning); errorDialog->setWindowTitle(Tr::tr("Performance Analyzer")); @@ -274,17 +273,17 @@ void PerfProfilerTool::createViews() errorDialog->show(); }); - connect(m_traceManager, &PerfProfilerTraceManager::loadFinished, this, [this]() { + connect(&traceManager(), &PerfProfilerTraceManager::loadFinished, this, [this]() { m_readerRunning = false; updateRunActions(); }); - connect(m_traceManager, &PerfProfilerTraceManager::saveFinished, this, [this]() { + connect(&traceManager(), &PerfProfilerTraceManager::saveFinished, this, [this]() { setToolActionsEnabled(true); }); connect(this, &PerfProfilerTool::aggregatedChanged, - m_traceManager, &PerfProfilerTraceManager::setAggregateAddresses); + &traceManager(), &PerfProfilerTraceManager::setAggregateAddresses); QMenu *menu1 = new QMenu(m_traceView); addLoadSaveActionsToMenu(menu1); @@ -353,11 +352,6 @@ PerfProfilerTool *PerfProfilerTool::instance() return s_instance; } -PerfProfilerTraceManager *PerfProfilerTool::traceManager() const -{ - return m_traceManager; -} - void PerfProfilerTool::addLoadSaveActionsToMenu(QMenu *menu) { menu->addAction(m_loadPerfData); @@ -379,8 +373,8 @@ void PerfProfilerTool::initialize() void PerfProfilerTool::finalize() { - const qint64 startTime = m_traceManager->traceStart(); - const qint64 endTime = m_traceManager->traceEnd(); + const qint64 startTime = traceManager().traceStart(); + const qint64 endTime = traceManager().traceEnd(); QTC_ASSERT(endTime >= startTime, return); m_zoomControl->setTrace(startTime, endTime); m_zoomControl->setRange(startTime, startTime + (endTime - startTime) / 10); @@ -398,7 +392,7 @@ void PerfProfilerTool::startLoading() void PerfProfilerTool::onReaderFinished() { m_readerRunning = false; - if (m_traceManager->traceDuration() <= 0) { + if (traceManager().traceDuration() <= 0) { QMessageBox::warning(Core::ICore::dialogParent(), Tr::tr("No Data Loaded"), Tr::tr("The profiler did not produce any samples. " @@ -408,7 +402,7 @@ void PerfProfilerTool::onReaderFinished() "Application Output view.")); clear(); } else { - m_traceManager->finalize(); + traceManager().finalize(); } } @@ -426,7 +420,7 @@ void PerfProfilerTool::onRunControlFinished() void PerfProfilerTool::onReaderStarted() { - m_traceManager->initialize(); + traceManager().initialize(); } void PerfProfilerTool::onWorkerCreation(RunControl *runControl) @@ -450,7 +444,7 @@ void PerfProfilerTool::updateRunActions() m_loadPerfData->setEnabled(true); m_loadTrace->setEnabled(true); } - m_saveTrace->setEnabled(!m_traceManager->isEmpty()); + m_saveTrace->setEnabled(!traceManager().isEmpty()); } void PerfProfilerTool::setToolActionsEnabled(bool on) @@ -498,13 +492,13 @@ void PerfProfilerTool::updateFilterMenu() QAction *disableAll = m_filterMenu->addAction(Tr::tr("Disable All")); m_filterMenu->addSeparator(); - QList threads = m_traceManager->threads().values(); + QList threads = traceManager().threads().values(); std::sort(threads.begin(), threads.end()); for (const PerfProfilerTraceManager::Thread &thread : std::as_const(threads)) { QAction *action = m_filterMenu->addAction( QString::fromLatin1("%1 (%2)") - .arg(QString::fromUtf8(m_traceManager->string(thread.name))) + .arg(QString::fromUtf8(traceManager().string(thread.name))) .arg(thread.tid)); action->setCheckable(true); action->setData(thread.tid); @@ -513,7 +507,7 @@ void PerfProfilerTool::updateFilterMenu() action->setEnabled(false); } else { connect(action, &QAction::toggled, this, [this, action](bool checked) { - m_traceManager->setThreadEnabled(action->data().toUInt(), checked); + traceManager().setThreadEnabled(action->data().toUInt(), checked); }); connect(enableAll, &QAction::triggered, action, [action]() { action->setChecked(true); }); @@ -594,7 +588,7 @@ void PerfProfilerTool::showLoadPerfDialog() m_fileFinder.setAdditionalSearchDirectories(collectQtIncludePaths(kit)); m_fileFinder.setSysroot(sysroot(kit)); m_fileFinder.setProjectFiles(sourceFiles()); - m_traceManager->loadFromPerfData(FilePath::fromUserInput(dlg.traceFilePath()), dlg.executableDirPath(), kit); + traceManager().loadFromPerfData(FilePath::fromUserInput(dlg.traceFilePath()), dlg.executableDirPath(), kit); } void PerfProfilerTool::showLoadTraceDialog() @@ -613,7 +607,7 @@ void PerfProfilerTool::showLoadTraceDialog() const Kit *kit = target ? target->kit() : nullptr; populateFileFinder(currentProject, kit); - m_traceManager->loadFromTraceFile(filePath); + traceManager().loadFromTraceFile(filePath); } void PerfProfilerTool::showSaveTraceDialog() @@ -628,7 +622,7 @@ void PerfProfilerTool::showSaveTraceDialog() filePath = filePath.stringAppended(".ptq"); setToolActionsEnabled(false); - m_traceManager->saveToTraceFile(filePath); + traceManager().saveToTraceFile(filePath); } void PerfProfilerTool::setAggregated(bool aggregated) @@ -688,8 +682,8 @@ void PerfProfilerTool::clear() void PerfProfilerTool::clearData() { - m_traceManager->clearAll(); - m_traceManager->setAggregateAddresses(m_aggregateButton->isChecked()); + traceManager().clearAll(); + traceManager().setAggregateAddresses(m_aggregateButton->isChecked()); m_zoomControl->clear(); } diff --git a/src/plugins/perfprofiler/perfprofilertool.h b/src/plugins/perfprofiler/perfprofilertool.h index 4244e7a2824..2325b738636 100644 --- a/src/plugins/perfprofiler/perfprofilertool.h +++ b/src/plugins/perfprofiler/perfprofilertool.h @@ -36,7 +36,6 @@ public: static PerfProfilerTool *instance(); - PerfProfilerTraceManager *traceManager() const; PerfTimelineModelManager *modelManager() const; Timeline::TimelineZoomControl *zoomControl() const; @@ -107,7 +106,6 @@ private: PerfProfilerStatisticsView *m_statisticsView = nullptr; PerfProfilerFlameGraphView *m_flameGraphView = nullptr; - PerfProfilerTraceManager *m_traceManager = nullptr; PerfTimelineModelManager *m_modelManager = nullptr; Timeline::TimelineZoomControl *m_zoomControl = nullptr; Utils::FileInProjectFinder m_fileFinder; diff --git a/src/plugins/perfprofiler/perfprofilertracemanager.cpp b/src/plugins/perfprofiler/perfprofilertracemanager.cpp index b9a591f9807..ffe81dd2dcb 100644 --- a/src/plugins/perfprofiler/perfprofilertracemanager.cpp +++ b/src/plugins/perfprofiler/perfprofilertracemanager.cpp @@ -102,11 +102,11 @@ bool PerfProfilerEventStorage::replay( return false; } -PerfProfilerTraceManager::PerfProfilerTraceManager(QObject *parent) +PerfProfilerTraceManager::PerfProfilerTraceManager() : Timeline::TimelineTraceManager( std::make_unique( std::bind(&PerfProfilerTraceManager::error, this, std::placeholders::_1)), - std::make_unique(), parent) + std::make_unique()) { m_reparseTimer.setInterval(100); m_reparseTimer.setSingleShot(true); @@ -124,9 +124,7 @@ PerfProfilerTraceManager::PerfProfilerTraceManager(QObject *parent) resetAttributes(); } -PerfProfilerTraceManager::~PerfProfilerTraceManager() -{ -} +PerfProfilerTraceManager::~PerfProfilerTraceManager() = default; void PerfProfilerTraceManager::registerFeatures(quint64 features, PerfEventLoader eventLoader, Initializer initializer, Finalizer finalizer, @@ -621,5 +619,11 @@ void PerfProfilerTraceManager::loadFromPerfData(const FilePath &filePath, reader->loadFromFile(filePath, executableDirPath, kit); } +PerfProfilerTraceManager &traceManager() +{ + static PerfProfilerTraceManager thePerfProfilerTraceManager; + return thePerfProfilerTraceManager; +} + } // namespace Internal } // namespace PerfProfiler diff --git a/src/plugins/perfprofiler/perfprofilertracemanager.h b/src/plugins/perfprofiler/perfprofilertracemanager.h index 799e1230248..f8186b723ee 100644 --- a/src/plugins/perfprofiler/perfprofilertracemanager.h +++ b/src/plugins/perfprofiler/perfprofilertracemanager.h @@ -87,7 +87,7 @@ public: static const QByteArray s_resourceObtainedIdName; static const QByteArray s_resourceMovedIdName; - explicit PerfProfilerTraceManager(QObject *parent = nullptr); + PerfProfilerTraceManager(); ~PerfProfilerTraceManager() override; void registerFeatures(quint64 features, PerfEventLoader eventLoader, @@ -228,6 +228,7 @@ inline QDataStream &operator<<(QDataStream &stream, const PerfProfilerTraceManag return stream << thread.pid << thread.tid << thread.start << thread.cpu << thread.name; } +PerfProfilerTraceManager &traceManager(); } // namespace Internal } // namespace PerfProfiler From f890718ffd7a0d102ea5e72d63cc1d3eb431b0af Mon Sep 17 00:00:00 2001 From: Serg Kryvonos Date: Tue, 21 Nov 2023 17:16:14 +0100 Subject: [PATCH 0325/1546] Git ignore Visual Studio CMake build directories Change-Id: Ie6530d3b624c1df774b5fbd682be8a452a88f3b5 Reviewed-by: Alexandru Croitor --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 7c56e80373d..93a8fbca1ae 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ CMakeLists.txt.user* /src/plugins/coreplugin/ide_version.h /src/libs/qt-breakpad/bin /.cmake/ +/.vs/ app_version.h phony.c @@ -286,3 +287,4 @@ tmp/ # qbs builds /*-debug/ /*-release/ +/out/ From ea7de2ec51ac841f1658ab9b80fd96e4a27ad315 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Nov 2023 17:27:14 +0100 Subject: [PATCH 0326/1546] PerfProfiler: Make PerfTimelineModelManager a standard singleton Change-Id: I8356850a31949bcd6f1866e8e45f119b7a9ab094 Reviewed-by: Jarek Kobus --- src/plugins/perfprofiler/perfprofilertool.cpp | 6 ---- src/plugins/perfprofiler/perfprofilertool.h | 2 -- .../perfprofiler/perfprofilertraceview.cpp | 6 ++-- .../perfprofiler/perftimelinemodel.cpp | 18 ++++------- src/plugins/perfprofiler/perftimelinemodel.h | 1 - .../perfprofiler/perftimelinemodelmanager.cpp | 31 +++++++++++-------- .../perfprofiler/perftimelinemodelmanager.h | 7 ++--- .../tests/perfprofilertracefile_test.cpp | 2 +- 8 files changed, 31 insertions(+), 42 deletions(-) diff --git a/src/plugins/perfprofiler/perfprofilertool.cpp b/src/plugins/perfprofiler/perfprofilertool.cpp index ad3a69b31b7..a9cf1a632f1 100644 --- a/src/plugins/perfprofiler/perfprofilertool.cpp +++ b/src/plugins/perfprofiler/perfprofilertool.cpp @@ -60,7 +60,6 @@ PerfProfilerTool::PerfProfilerTool() std::bind(&PerfProfilerTool::finalize, this), std::bind(&PerfProfilerTool::clearUi, this)); - m_modelManager = new PerfTimelineModelManager(&traceManager()); m_zoomControl = new Timeline::TimelineZoomControl(this); ActionContainer *menu = ActionManager::actionContainer(Debugger::Constants::M_DEBUG_ANALYZER); ActionContainer *options = ActionManager::createMenu(Constants::PerfOptionsMenuId); @@ -463,11 +462,6 @@ void PerfProfilerTool::setToolActionsEnabled(bool on) m_flameGraphView->setEnabled(on); } -PerfTimelineModelManager *PerfProfilerTool::modelManager() const -{ - return m_modelManager; -} - Timeline::TimelineZoomControl *PerfProfilerTool::zoomControl() const { return m_zoomControl; diff --git a/src/plugins/perfprofiler/perfprofilertool.h b/src/plugins/perfprofiler/perfprofilertool.h index 2325b738636..d456fe2b7ab 100644 --- a/src/plugins/perfprofiler/perfprofilertool.h +++ b/src/plugins/perfprofiler/perfprofilertool.h @@ -36,7 +36,6 @@ public: static PerfProfilerTool *instance(); - PerfTimelineModelManager *modelManager() const; Timeline::TimelineZoomControl *zoomControl() const; bool isRecording() const; @@ -106,7 +105,6 @@ private: PerfProfilerStatisticsView *m_statisticsView = nullptr; PerfProfilerFlameGraphView *m_flameGraphView = nullptr; - PerfTimelineModelManager *m_modelManager = nullptr; Timeline::TimelineZoomControl *m_zoomControl = nullptr; Utils::FileInProjectFinder m_fileFinder; bool m_readerRunning = false; diff --git a/src/plugins/perfprofiler/perfprofilertraceview.cpp b/src/plugins/perfprofiler/perfprofilertraceview.cpp index 0a778db2f7a..95a53c8257a 100644 --- a/src/plugins/perfprofiler/perfprofilertraceview.cpp +++ b/src/plugins/perfprofiler/perfprofilertraceview.cpp @@ -30,16 +30,16 @@ PerfProfilerTraceView::PerfProfilerTraceView(QWidget *parent, PerfProfilerTool * Timeline::TimelineTheme::setupTheme(engine()); rootContext()->setContextProperty(QLatin1String("timelineModelAggregator"), - tool->modelManager()); + &modelManager()); rootContext()->setContextProperty(QLatin1String("zoomControl"), tool->zoomControl()); setSource(QUrl(QLatin1String("qrc:/qt/qml/QtCreator/Tracing/MainView.qml"))); // Avoid ugly warnings when reading from null properties in QML. - connect(tool->modelManager(), &QObject::destroyed, this, [this]{ setSource(QUrl()); }); + connect(&modelManager(), &QObject::destroyed, this, [this]{ setSource(QUrl()); }); connect(tool->zoomControl(), &QObject::destroyed, this, [this]{ setSource(QUrl()); }); - connect(tool->modelManager(), &Timeline::TimelineModelAggregator::updateCursorPosition, + connect(&modelManager(), &Timeline::TimelineModelAggregator::updateCursorPosition, this, &PerfProfilerTraceView::updateCursorPosition); } diff --git a/src/plugins/perfprofiler/perftimelinemodel.cpp b/src/plugins/perfprofiler/perftimelinemodel.cpp index 2354d33ae84..fac136024b2 100644 --- a/src/plugins/perfprofiler/perftimelinemodel.cpp +++ b/src/plugins/perfprofiler/perftimelinemodel.cpp @@ -61,7 +61,7 @@ QVariantList PerfTimelineModel::labels() const sample.insert(QLatin1String("id"), PerfEvent::LastSpecialTypeId); result << sample; - const PerfProfilerTraceManager *manager = traceManager(); + const PerfProfilerTraceManager *manager = &traceManager(); const bool aggregated = manager->aggregateAddresses(); for (int i = 0; i < m_locationOrder.length(); ++i) { int locationId = m_locationOrder[i]; @@ -136,7 +136,7 @@ QVariantMap PerfTimelineModel::details(int index) const const StackFrame &frame = m_data[index]; - const PerfProfilerTraceManager *manager = traceManager(); + const PerfProfilerTraceManager *manager = &traceManager(); int typeId = selectionId(index); if (isSample(index)) { const PerfEventType::Attribute &attribute = manager->attribute(typeId); @@ -221,13 +221,12 @@ QVariantMap PerfTimelineModel::details(int index) const QVariantMap PerfTimelineModel::location(int index) const { - const PerfProfilerTraceManager *manager = traceManager(); const int typeId = selectionId(index); if (typeId < 0) // not a location return QVariantMap(); - const PerfEventType::Location &location = manager->location(typeId); - const QByteArray &file = manager->string(location.file); + const PerfEventType::Location &location = traceManager().location(typeId); + const QByteArray &file = traceManager().string(location.file); if (file.isEmpty()) return QVariantMap(); @@ -264,7 +263,7 @@ float PerfTimelineModel::relativeHeight(int index) const void PerfTimelineModel::updateTraceData(const PerfEvent &event) { - const PerfProfilerTraceManager *manager = traceManager(); + const PerfProfilerTraceManager *manager = &traceManager(); for (int i = 0; i < event.numAttributes(); ++i) { const PerfEventType::Attribute &attribute = manager->attribute(event.attributeId(i)); if (attribute.type != PerfEventType::TypeTracepoint) @@ -539,11 +538,6 @@ void PerfTimelineModel::computeExpandedLevels() setExpandedRowCount(expandedRows); } -const PerfProfilerTraceManager *PerfTimelineModel::traceManager() const -{ - return static_cast(parent())->traceManager(); -} - const PerfTimelineModel::LocationStats &PerfTimelineModel::locationStats(int locationId) const { static const LocationStats empty; @@ -573,7 +567,7 @@ bool PerfTimelineModel::isResourceTracePoint(int index) const if (!isSample(index)) return false; - const PerfProfilerTraceManager *manager = traceManager(); + const PerfProfilerTraceManager *manager = &traceManager(); const PerfEventType::Attribute &attribute = manager->attribute(typeId(index)); if (attribute.type != PerfEventType::TypeTracepoint) diff --git a/src/plugins/perfprofiler/perftimelinemodel.h b/src/plugins/perfprofiler/perftimelinemodel.h index 6f776339599..e6280c0cb89 100644 --- a/src/plugins/perfprofiler/perftimelinemodel.h +++ b/src/plugins/perfprofiler/perftimelinemodel.h @@ -132,7 +132,6 @@ private: QHash>> m_attributeValues; void computeExpandedLevels(); - const PerfProfilerTraceManager *traceManager() const; const LocationStats &locationStats(int selectionId) const; diff --git a/src/plugins/perfprofiler/perftimelinemodelmanager.cpp b/src/plugins/perfprofiler/perftimelinemodelmanager.cpp index c473b1c7f99..256d15fc736 100644 --- a/src/plugins/perfprofiler/perftimelinemodelmanager.cpp +++ b/src/plugins/perfprofiler/perftimelinemodelmanager.cpp @@ -9,10 +9,10 @@ namespace PerfProfiler { namespace Internal { -PerfTimelineModelManager::PerfTimelineModelManager(PerfProfilerTraceManager *traceManager) : - Timeline::TimelineModelAggregator(traceManager), m_traceManager(traceManager) +PerfTimelineModelManager::PerfTimelineModelManager() + : Timeline::TimelineModelAggregator(&traceManager()) { - traceManager->registerFeatures(PerfEventType::allFeatures(), + traceManager().registerFeatures(PerfEventType::allFeatures(), std::bind(&PerfTimelineModelManager::loadEvent, this, std::placeholders::_1, std::placeholders::_2), std::bind(&PerfTimelineModelManager::initialize, this), @@ -25,17 +25,16 @@ PerfTimelineModelManager::~PerfTimelineModelManager() clear(); } -static QString displayNameForThread(const PerfProfilerTraceManager::Thread &thread, - PerfProfilerTraceManager *manager) +static QString displayNameForThread(const PerfProfilerTraceManager::Thread &thread) { return QString::fromLatin1("%1 (%2)") - .arg(QString::fromUtf8(manager->string(thread.name))) + .arg(QString::fromUtf8(traceManager().string(thread.name))) .arg(thread.tid); } void PerfTimelineModelManager::initialize() { - for (const PerfProfilerTraceManager::Thread &thread : m_traceManager->threads()) { + for (const PerfProfilerTraceManager::Thread &thread : traceManager().threads()) { if (thread.enabled) { m_unfinished.insert(thread.tid, new PerfTimelineModel( thread.pid, thread.tid, thread.firstEvent, thread.lastEvent, @@ -47,13 +46,13 @@ void PerfTimelineModelManager::initialize() void PerfTimelineModelManager::finalize() { QVector finished; - QHash threads = m_traceManager->threads(); + QHash threads = traceManager().threads(); for (auto it = m_unfinished.begin(), end = m_unfinished.end(); it != end; ++it) { PerfTimelineModel *model = *it; - const PerfProfilerTraceManager::Thread &thread = m_traceManager->thread(model->tid()); + const PerfProfilerTraceManager::Thread &thread = traceManager().thread(model->tid()); if (thread.enabled) { - model->setDisplayName(displayNameForThread(thread, m_traceManager)); + model->setDisplayName(displayNameForThread(thread)); model->finalize(); finished.append(model); } else { @@ -62,7 +61,7 @@ void PerfTimelineModelManager::finalize() } m_unfinished.clear(); - const qint64 frequency = m_traceManager->samplingFrequency(); + const qint64 frequency = traceManager().samplingFrequency(); for (PerfTimelineModel *model : std::as_const(finished)) { model->setSamplingFrequency(frequency); threads.remove(model->tid()); @@ -73,7 +72,7 @@ void PerfTimelineModelManager::finalize() continue; PerfTimelineModel *model = new PerfTimelineModel( remaining.pid, remaining.tid, remaining.firstEvent, remaining.lastEvent, this); - model->setDisplayName(displayNameForThread(remaining, m_traceManager)); + model->setDisplayName(displayNameForThread(remaining)); model->finalize(); model->setSamplingFrequency(frequency); finished.append(model); @@ -92,7 +91,7 @@ void PerfTimelineModelManager::finalize() void PerfTimelineModelManager::loadEvent(const PerfEvent &event, const PerfEventType &type) { Q_UNUSED(type) - const int parallel = m_traceManager->threads().size(); + const int parallel = traceManager().threads().size(); auto i = m_unfinished.find(event.tid()); if (i == m_unfinished.end()) { i = m_unfinished.insert(event.tid(), new PerfTimelineModel( @@ -113,5 +112,11 @@ void PerfTimelineModelManager::clear() m_resourceContainers.clear(); } +PerfTimelineModelManager &modelManager() +{ + static PerfTimelineModelManager thePerfTimelineModelManager; + return thePerfTimelineModelManager; +} + } // namespace Internal } // namespace PerfProfiler diff --git a/src/plugins/perfprofiler/perftimelinemodelmanager.h b/src/plugins/perfprofiler/perftimelinemodelmanager.h index 8b7b9c1c8fc..bef3eb3386e 100644 --- a/src/plugins/perfprofiler/perftimelinemodelmanager.h +++ b/src/plugins/perfprofiler/perftimelinemodelmanager.h @@ -25,7 +25,7 @@ class PerfTimelineModelManager : public Timeline::TimelineModelAggregator { Q_OBJECT public: - explicit PerfTimelineModelManager(PerfProfilerTraceManager *traceManager); + PerfTimelineModelManager(); ~PerfTimelineModelManager(); void loadEvent(const PerfEvent &event, const PerfEventType &type); @@ -33,8 +33,6 @@ public: void finalize(); void clear(); - const PerfProfilerTraceManager *traceManager() const { return m_traceManager.data(); } - PerfResourceCounter<>::Container *resourceContainer(quint32 pid) { std::unique_ptr::Container> &container = m_resourceContainers[pid]; @@ -48,9 +46,10 @@ private: = typename std::unordered_map::Container>>; QHash m_unfinished; - QPointer m_traceManager; ContainerMap m_resourceContainers; }; +PerfTimelineModelManager &modelManager(); + } // namespace Internal } // namespace PerfProfiler diff --git a/src/plugins/perfprofiler/tests/perfprofilertracefile_test.cpp b/src/plugins/perfprofiler/tests/perfprofilertracefile_test.cpp index fd60588d124..a41f2d837d8 100644 --- a/src/plugins/perfprofiler/tests/perfprofilertracefile_test.cpp +++ b/src/plugins/perfprofiler/tests/perfprofilertracefile_test.cpp @@ -73,7 +73,7 @@ void PerfProfilerTraceFileTest::testSaveLoadTraceData() { MessageHandler messageHandler(&handleMessage); PerfProfilerTraceManager traceManager; - PerfTimelineModelManager modelManager(&traceManager); + PerfTimelineModelManager modelManager; { PerfProfilerTraceFile traceFile; traceFile.setTraceManager(&traceManager); From 00e3c59981b8266f6f6b415efeab0631f497e462 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Nov 2023 14:52:14 +0100 Subject: [PATCH 0327/1546] Todo: Merge optionsdialog to settings file pair First babystep towards aspectified settings. Change-Id: I05647f758066acf132331b58b43979f114069140 Reviewed-by: Jarek Kobus --- src/plugins/todo/CMakeLists.txt | 1 - src/plugins/todo/optionsdialog.cpp | 257 ---------------------------- src/plugins/todo/optionsdialog.h | 19 --- src/plugins/todo/settings.cpp | 262 ++++++++++++++++++++++++++++- src/plugins/todo/settings.h | 8 +- src/plugins/todo/todo.qbs | 2 - src/plugins/todo/todoplugin.cpp | 4 +- 7 files changed, 264 insertions(+), 289 deletions(-) delete mode 100644 src/plugins/todo/optionsdialog.cpp delete mode 100644 src/plugins/todo/optionsdialog.h diff --git a/src/plugins/todo/CMakeLists.txt b/src/plugins/todo/CMakeLists.txt index ac9b61e3096..a50e3982daf 100644 --- a/src/plugins/todo/CMakeLists.txt +++ b/src/plugins/todo/CMakeLists.txt @@ -7,7 +7,6 @@ add_qtc_plugin(Todo keyword.cpp keyword.h keyworddialog.cpp keyworddialog.h lineparser.cpp lineparser.h - optionsdialog.cpp optionsdialog.h qmljstodoitemsscanner.cpp qmljstodoitemsscanner.h settings.cpp settings.h todoicons.cpp todoicons.h diff --git a/src/plugins/todo/optionsdialog.cpp b/src/plugins/todo/optionsdialog.cpp deleted file mode 100644 index 3b300a7d10c..00000000000 --- a/src/plugins/todo/optionsdialog.cpp +++ /dev/null @@ -1,257 +0,0 @@ -// Copyright (C) 2016 Dmitry Savchenko -// Copyright (C) 2016 Vasiliy Sorokin -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "optionsdialog.h" - -#include "constants.h" -#include "keyword.h" -#include "keyworddialog.h" -#include "settings.h" -#include "todotr.h" - -#include - -#include -#include -#include -#include - -namespace Todo::Internal { - -class OptionsDialog final : public Core::IOptionsPageWidget -{ -public: - OptionsDialog(Settings *settings, const std::function &onApply); - - void apply() final; - - void setSettings(const Settings &settings); - -private: - void addKeywordButtonClicked(); - void editKeywordButtonClicked(); - void removeKeywordButtonClicked(); - void resetKeywordsButtonClicked(); - void setKeywordsButtonsEnabled(); - Settings settingsFromUi(); - void addToKeywordsList(const Keyword &keyword); - void editKeyword(QListWidgetItem *item); - QSet keywordNames(); - - Settings *m_settings = nullptr; - std::function m_onApply; - - QListWidget *m_keywordsList; - QPushButton *m_editKeywordButton; - QPushButton *m_removeKeywordButton; - QPushButton *resetKeywordsButton; - QRadioButton *m_scanInProjectRadioButton; - QRadioButton *m_scanInCurrentFileRadioButton; - QRadioButton *m_scanInSubprojectRadioButton; -}; - -OptionsDialog::OptionsDialog(Settings *settings, const std::function &onApply) - : m_settings(settings), m_onApply(onApply) -{ - m_keywordsList = new QListWidget; - m_keywordsList->setDragDropMode(QAbstractItemView::DragDrop); - m_keywordsList->setDefaultDropAction(Qt::MoveAction); - m_keywordsList->setSelectionBehavior(QAbstractItemView::SelectRows); - m_keywordsList->setSortingEnabled(false); - - auto addKeywordButton = new QPushButton(Tr::tr("Add")); - m_editKeywordButton = new QPushButton(Tr::tr("Edit")); - m_removeKeywordButton = new QPushButton(Tr::tr("Remove")); - resetKeywordsButton = new QPushButton(Tr::tr("Reset")); - - m_scanInProjectRadioButton = new QRadioButton(Tr::tr("Scan the whole active project")); - m_scanInProjectRadioButton->setEnabled(true); - - m_scanInCurrentFileRadioButton = new QRadioButton(Tr::tr("Scan only the currently edited document")); - m_scanInCurrentFileRadioButton->setChecked(true); - - m_scanInSubprojectRadioButton = new QRadioButton(Tr::tr("Scan the current subproject")); - - using namespace Layouting; - - Column { - Group { - title(Tr::tr("Keywords")), - Row { - m_keywordsList, - Column { - addKeywordButton, - m_editKeywordButton, - m_removeKeywordButton, - resetKeywordsButton, - st - } - } - }, - Group { - title(Tr::tr("Scanning scope")), - Column { - m_scanInProjectRadioButton, - m_scanInCurrentFileRadioButton, - m_scanInSubprojectRadioButton - } - } - }.attachTo(this); - - m_keywordsList->setIconSize(QSize(16, 16)); - setKeywordsButtonsEnabled(); - connect(addKeywordButton, &QAbstractButton::clicked, - this, &OptionsDialog::addKeywordButtonClicked); - connect(m_removeKeywordButton, &QAbstractButton::clicked, - this, &OptionsDialog::removeKeywordButtonClicked); - connect(m_editKeywordButton, &QAbstractButton::clicked, - this, &OptionsDialog::editKeywordButtonClicked); - connect(resetKeywordsButton, &QAbstractButton::clicked, - this, &OptionsDialog::resetKeywordsButtonClicked); - connect(m_keywordsList, &QListWidget::itemDoubleClicked, - this, &OptionsDialog::editKeyword); - connect(m_keywordsList, &QListWidget::itemSelectionChanged, - this, &OptionsDialog::setKeywordsButtonsEnabled); - - setSettings(*m_settings); -} - -void OptionsDialog::addToKeywordsList(const Keyword &keyword) -{ - auto item = new QListWidgetItem(icon(keyword.iconType), keyword.name); - item->setData(Qt::UserRole, static_cast(keyword.iconType)); - item->setForeground(keyword.color); - m_keywordsList->addItem(item); -} - -QSet OptionsDialog::keywordNames() -{ - const KeywordList keywords = settingsFromUi().keywords; - - QSet result; - for (const Keyword &keyword : keywords) - result << keyword.name; - - return result; -} - -void OptionsDialog::addKeywordButtonClicked() -{ - Keyword keyword; - KeywordDialog keywordDialog(keyword, keywordNames(), this); - if (keywordDialog.exec() == QDialog::Accepted) { - keyword = keywordDialog.keyword(); - addToKeywordsList(keyword); - } -} - -void OptionsDialog::editKeywordButtonClicked() -{ - QListWidgetItem *item = m_keywordsList->currentItem(); - editKeyword(item); -} - -void OptionsDialog::editKeyword(QListWidgetItem *item) -{ - Keyword keyword; - keyword.name = item->text(); - keyword.iconType = static_cast(item->data(Qt::UserRole).toInt()); - keyword.color = item->foreground().color(); - - QSet keywordNamesButThis = keywordNames(); - keywordNamesButThis.remove(keyword.name); - - KeywordDialog keywordDialog(keyword, keywordNamesButThis, this); - if (keywordDialog.exec() == QDialog::Accepted) { - keyword = keywordDialog.keyword(); - item->setIcon(icon(keyword.iconType)); - item->setText(keyword.name); - item->setData(Qt::UserRole, static_cast(keyword.iconType)); - item->setForeground(keyword.color); - } -} - -void OptionsDialog::removeKeywordButtonClicked() -{ - delete m_keywordsList->takeItem(m_keywordsList->currentRow()); -} - -void OptionsDialog::resetKeywordsButtonClicked() -{ - Settings newSettings; - newSettings.setDefault(); - setSettings(newSettings); -} - -void OptionsDialog::setKeywordsButtonsEnabled() -{ - const bool isSomethingSelected = !m_keywordsList->selectedItems().isEmpty(); - m_removeKeywordButton->setEnabled(isSomethingSelected); - m_editKeywordButton->setEnabled(isSomethingSelected); -} - -void OptionsDialog::setSettings(const Settings &settings) -{ - m_scanInCurrentFileRadioButton->setChecked(settings.scanningScope == ScanningScopeCurrentFile); - m_scanInProjectRadioButton->setChecked(settings.scanningScope == ScanningScopeProject); - m_scanInSubprojectRadioButton->setChecked(settings.scanningScope == ScanningScopeSubProject); - - m_keywordsList->clear(); - for (const Keyword &keyword : std::as_const(settings.keywords)) - addToKeywordsList(keyword); -} - -Settings OptionsDialog::settingsFromUi() -{ - Settings settings; - - if (m_scanInCurrentFileRadioButton->isChecked()) - settings.scanningScope = ScanningScopeCurrentFile; - else if (m_scanInSubprojectRadioButton->isChecked()) - settings.scanningScope = ScanningScopeSubProject; - else - settings.scanningScope = ScanningScopeProject; - - settings.keywords.clear(); - for (int i = 0; i < m_keywordsList->count(); ++i) { - QListWidgetItem *item = m_keywordsList->item(i); - - Keyword keyword; - keyword.name = item->text(); - keyword.iconType = static_cast(item->data(Qt::UserRole).toInt()); - keyword.color = item->foreground().color(); - - settings.keywords << keyword; - } - - return settings; -} - -void OptionsDialog::apply() -{ - Settings newSettings = settingsFromUi(); - - // "apply" itself is interpreted as "use these keywords, also for other themes". - newSettings.keywordsEdited = true; - - if (newSettings == *m_settings) - return; - - *m_settings = newSettings; - m_onApply(); -} - -// TodoOptionsPage - -TodoOptionsPage::TodoOptionsPage(Settings *settings, const std::function &onApply) -{ - setId(Constants::TODO_SETTINGS); - setDisplayName(Tr::tr("To-Do")); - setCategory("To-Do"); - setDisplayCategory(Tr::tr("To-Do")); - setCategoryIconPath(":/todoplugin/images/settingscategory_todo.png"); - setWidgetCreator([settings, onApply] { return new OptionsDialog(settings, onApply); }); -} - -} // Todo::Internal diff --git a/src/plugins/todo/optionsdialog.h b/src/plugins/todo/optionsdialog.h deleted file mode 100644 index 609fa56d9cb..00000000000 --- a/src/plugins/todo/optionsdialog.h +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) 2016 Dmitry Savchenko -// Copyright (C) 2016 Vasiliy Sorokin -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace Todo::Internal { - -class Settings; - -class TodoOptionsPage final : public Core::IOptionsPage -{ -public: - TodoOptionsPage(Settings *settings, const std::function &onApply); -}; - -} // Todo::Internal diff --git a/src/plugins/todo/settings.cpp b/src/plugins/todo/settings.cpp index d5aafadd37f..ebe9a6f7cac 100644 --- a/src/plugins/todo/settings.cpp +++ b/src/plugins/todo/settings.cpp @@ -3,17 +3,27 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "settings.h" + #include "constants.h" +#include "keyword.h" +#include "keyworddialog.h" +#include "todotr.h" #include +#include +#include #include #include +#include +#include +#include +#include + using namespace Utils; -namespace Todo { -namespace Internal { +namespace Todo::Internal { void Settings::save(QtcSettings *settings) const { @@ -133,6 +143,250 @@ bool operator !=(const Settings &s1, const Settings &s2) return !s1.equals(s2); } -} // namespace Internal -} // namespace Todo + +class OptionsDialog final : public Core::IOptionsPageWidget +{ +public: + OptionsDialog(Settings *settings, const std::function &onApply); + + void apply() final; + + void setSettings(const Settings &settings); + +private: + void addKeywordButtonClicked(); + void editKeywordButtonClicked(); + void removeKeywordButtonClicked(); + void resetKeywordsButtonClicked(); + void setKeywordsButtonsEnabled(); + Settings settingsFromUi(); + void addToKeywordsList(const Keyword &keyword); + void editKeyword(QListWidgetItem *item); + QSet keywordNames(); + + Settings *m_settings = nullptr; + std::function m_onApply; + + QListWidget *m_keywordsList; + QPushButton *m_editKeywordButton; + QPushButton *m_removeKeywordButton; + QPushButton *resetKeywordsButton; + QRadioButton *m_scanInProjectRadioButton; + QRadioButton *m_scanInCurrentFileRadioButton; + QRadioButton *m_scanInSubprojectRadioButton; +}; + +OptionsDialog::OptionsDialog(Settings *settings, const std::function &onApply) + : m_settings(settings), m_onApply(onApply) +{ + m_keywordsList = new QListWidget; + m_keywordsList->setDragDropMode(QAbstractItemView::DragDrop); + m_keywordsList->setDefaultDropAction(Qt::MoveAction); + m_keywordsList->setSelectionBehavior(QAbstractItemView::SelectRows); + m_keywordsList->setSortingEnabled(false); + + auto addKeywordButton = new QPushButton(Tr::tr("Add")); + m_editKeywordButton = new QPushButton(Tr::tr("Edit")); + m_removeKeywordButton = new QPushButton(Tr::tr("Remove")); + resetKeywordsButton = new QPushButton(Tr::tr("Reset")); + + m_scanInProjectRadioButton = new QRadioButton(Tr::tr("Scan the whole active project")); + m_scanInProjectRadioButton->setEnabled(true); + + m_scanInCurrentFileRadioButton = new QRadioButton(Tr::tr("Scan only the currently edited document")); + m_scanInCurrentFileRadioButton->setChecked(true); + + m_scanInSubprojectRadioButton = new QRadioButton(Tr::tr("Scan the current subproject")); + + using namespace Layouting; + + Column { + Group { + title(Tr::tr("Keywords")), + Row { + m_keywordsList, + Column { + addKeywordButton, + m_editKeywordButton, + m_removeKeywordButton, + resetKeywordsButton, + st + } + } + }, + Group { + title(Tr::tr("Scanning scope")), + Column { + m_scanInProjectRadioButton, + m_scanInCurrentFileRadioButton, + m_scanInSubprojectRadioButton + } + } + }.attachTo(this); + + m_keywordsList->setIconSize(QSize(16, 16)); + setKeywordsButtonsEnabled(); + connect(addKeywordButton, &QAbstractButton::clicked, + this, &OptionsDialog::addKeywordButtonClicked); + connect(m_removeKeywordButton, &QAbstractButton::clicked, + this, &OptionsDialog::removeKeywordButtonClicked); + connect(m_editKeywordButton, &QAbstractButton::clicked, + this, &OptionsDialog::editKeywordButtonClicked); + connect(resetKeywordsButton, &QAbstractButton::clicked, + this, &OptionsDialog::resetKeywordsButtonClicked); + connect(m_keywordsList, &QListWidget::itemDoubleClicked, + this, &OptionsDialog::editKeyword); + connect(m_keywordsList, &QListWidget::itemSelectionChanged, + this, &OptionsDialog::setKeywordsButtonsEnabled); + + setSettings(*m_settings); +} + +void OptionsDialog::addToKeywordsList(const Keyword &keyword) +{ + auto item = new QListWidgetItem(icon(keyword.iconType), keyword.name); + item->setData(Qt::UserRole, static_cast(keyword.iconType)); + item->setForeground(keyword.color); + m_keywordsList->addItem(item); +} + +QSet OptionsDialog::keywordNames() +{ + const KeywordList keywords = settingsFromUi().keywords; + + QSet result; + for (const Keyword &keyword : keywords) + result << keyword.name; + + return result; +} + +void OptionsDialog::addKeywordButtonClicked() +{ + Keyword keyword; + KeywordDialog keywordDialog(keyword, keywordNames(), this); + if (keywordDialog.exec() == QDialog::Accepted) { + keyword = keywordDialog.keyword(); + addToKeywordsList(keyword); + } +} + +void OptionsDialog::editKeywordButtonClicked() +{ + QListWidgetItem *item = m_keywordsList->currentItem(); + editKeyword(item); +} + +void OptionsDialog::editKeyword(QListWidgetItem *item) +{ + Keyword keyword; + keyword.name = item->text(); + keyword.iconType = static_cast(item->data(Qt::UserRole).toInt()); + keyword.color = item->foreground().color(); + + QSet keywordNamesButThis = keywordNames(); + keywordNamesButThis.remove(keyword.name); + + KeywordDialog keywordDialog(keyword, keywordNamesButThis, this); + if (keywordDialog.exec() == QDialog::Accepted) { + keyword = keywordDialog.keyword(); + item->setIcon(icon(keyword.iconType)); + item->setText(keyword.name); + item->setData(Qt::UserRole, static_cast(keyword.iconType)); + item->setForeground(keyword.color); + } +} + +void OptionsDialog::removeKeywordButtonClicked() +{ + delete m_keywordsList->takeItem(m_keywordsList->currentRow()); +} + +void OptionsDialog::resetKeywordsButtonClicked() +{ + Settings newSettings; + newSettings.setDefault(); + setSettings(newSettings); +} + +void OptionsDialog::setKeywordsButtonsEnabled() +{ + const bool isSomethingSelected = !m_keywordsList->selectedItems().isEmpty(); + m_removeKeywordButton->setEnabled(isSomethingSelected); + m_editKeywordButton->setEnabled(isSomethingSelected); +} + +void OptionsDialog::setSettings(const Settings &settings) +{ + m_scanInCurrentFileRadioButton->setChecked(settings.scanningScope == ScanningScopeCurrentFile); + m_scanInProjectRadioButton->setChecked(settings.scanningScope == ScanningScopeProject); + m_scanInSubprojectRadioButton->setChecked(settings.scanningScope == ScanningScopeSubProject); + + m_keywordsList->clear(); + for (const Keyword &keyword : std::as_const(settings.keywords)) + addToKeywordsList(keyword); +} + +Settings OptionsDialog::settingsFromUi() +{ + Settings settings; + + if (m_scanInCurrentFileRadioButton->isChecked()) + settings.scanningScope = ScanningScopeCurrentFile; + else if (m_scanInSubprojectRadioButton->isChecked()) + settings.scanningScope = ScanningScopeSubProject; + else + settings.scanningScope = ScanningScopeProject; + + settings.keywords.clear(); + for (int i = 0; i < m_keywordsList->count(); ++i) { + QListWidgetItem *item = m_keywordsList->item(i); + + Keyword keyword; + keyword.name = item->text(); + keyword.iconType = static_cast(item->data(Qt::UserRole).toInt()); + keyword.color = item->foreground().color(); + + settings.keywords << keyword; + } + + return settings; +} + +void OptionsDialog::apply() +{ + Settings newSettings = settingsFromUi(); + + // "apply" itself is interpreted as "use these keywords, also for other themes". + newSettings.keywordsEdited = true; + + if (newSettings == *m_settings) + return; + + *m_settings = newSettings; + m_onApply(); +} + +// TodoSettingsPage + +class TodoSettingsPage final : public Core::IOptionsPage +{ +public: + TodoSettingsPage(Settings *settings, const std::function &onApply) + { + setId(Constants::TODO_SETTINGS); + setDisplayName(Tr::tr("To-Do")); + setCategory("To-Do"); + setDisplayCategory(Tr::tr("To-Do")); + setCategoryIconPath(":/todoplugin/images/settingscategory_todo.png"); + setWidgetCreator([settings, onApply] { return new OptionsDialog(settings, onApply); }); + } +}; + +void setupTodoSettingsPage(Settings *settings, const std::function &onApply) +{ + static TodoSettingsPage theTodoSettingsPage(settings, onApply); +} + +} // Todo::Internal diff --git a/src/plugins/todo/settings.h b/src/plugins/todo/settings.h index 534b1a1b0ca..b5b70a8a35c 100644 --- a/src/plugins/todo/settings.h +++ b/src/plugins/todo/settings.h @@ -8,8 +8,7 @@ namespace Utils { class QtcSettings; } -namespace Todo { -namespace Internal { +namespace Todo::Internal { enum ScanningScope { ScanningScopeCurrentFile, @@ -34,7 +33,8 @@ public: bool operator ==(const Settings &s1, const Settings &s2); bool operator !=(const Settings &s1, const Settings &s2); -} // namespace Internal -} // namespace Todo +void setupTodoSettingsPage(Settings *settings, const std::function &onApply); + +} // Todo::Internal Q_DECLARE_METATYPE(Todo::Internal::ScanningScope) diff --git a/src/plugins/todo/todo.qbs b/src/plugins/todo/todo.qbs index f3ea7fc96fa..f0c038c4755 100644 --- a/src/plugins/todo/todo.qbs +++ b/src/plugins/todo/todo.qbs @@ -22,8 +22,6 @@ QtcPlugin { "keyworddialog.h", "lineparser.cpp", "lineparser.h", - "optionsdialog.cpp", - "optionsdialog.h", "todoprojectsettingswidget.cpp", "todoprojectsettingswidget.h", "qmljstodoitemsscanner.cpp", diff --git a/src/plugins/todo/todoplugin.cpp b/src/plugins/todo/todoplugin.cpp index 6da4a2bd8e5..df8acc1af8c 100644 --- a/src/plugins/todo/todoplugin.cpp +++ b/src/plugins/todo/todoplugin.cpp @@ -2,7 +2,6 @@ // Copyright (C) 2016 Vasiliy Sorokin // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "optionsdialog.h" #include "todooutputpane.h" #include "todoitemsprovider.h" #include "todoprojectsettingswidget.h" @@ -31,7 +30,6 @@ public: Settings m_settings; TodoOutputPane *m_todoOutputPane = nullptr; - TodoOptionsPage m_optionsPage{&m_settings, [this] { settingsChanged(m_settings); }}; TodoItemsProvider *m_todoItemsProvider = nullptr; }; @@ -42,6 +40,8 @@ TodoPluginPrivate::TodoPluginPrivate() createItemsProvider(); createTodoOutputPane(); + setupTodoSettingsPage(&m_settings, [this] { settingsChanged(m_settings); }); + setupTodoSettingsProjectPanel(m_todoItemsProvider); connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested, From da0f308bea85d5321153749d938c8f38b9a4ee25 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Nov 2023 18:09:22 +0100 Subject: [PATCH 0328/1546] QmlProfiler: Use new setup for runworker Change-Id: I3be81b59a0f9426909cd6dc3df2e0bacc8aea1be Reviewed-by: Jarek Kobus --- src/plugins/qmlprofiler/qmlprofilerplugin.cpp | 7 ++--- .../qmlprofiler/qmlprofilerruncontrol.cpp | 31 ++++++++++++++----- .../qmlprofiler/qmlprofilerruncontrol.h | 14 +-------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp index c60d8f15e6f..e55ae38d764 100644 --- a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp @@ -56,17 +56,14 @@ class QmlProfilerPluginPrivate { public: QmlProfilerTool m_profilerTool; - - // The full local profiler. - LocalQmlProfilerRunWorkerFactory localQmlProfilerRunWorkerFactory; - // The bits plugged in in remote setups. - QmlProfilerRunWorkerFactory qmlProfilerRunWorkerFactory; }; bool QmlProfilerPlugin::initialize(const QStringList &arguments, QString *errorString) { Q_UNUSED(arguments) + setupQmlProfilerRunning(); + #ifdef WITH_TESTS addTest(); addTest(); diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp index 1fc8f83bd03..4d04aea2900 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.cpp @@ -239,18 +239,33 @@ LocalQmlProfilerSupport::LocalQmlProfilerSupport(RunControl *runControl, const Q // Factories // The bits plugged in in remote setups. -QmlProfilerRunWorkerFactory::QmlProfilerRunWorkerFactory() +class QmlProfilerRunWorkerFactory final : public RunWorkerFactory { - setProduct(); - addSupportedRunMode(ProjectExplorer::Constants::QML_PROFILER_RUNNER); -} +public: + QmlProfilerRunWorkerFactory() + { + setProduct(); + addSupportedRunMode(ProjectExplorer::Constants::QML_PROFILER_RUNNER); + } +}; // The full local profiler. -LocalQmlProfilerRunWorkerFactory::LocalQmlProfilerRunWorkerFactory() +class LocalQmlProfilerRunWorkerFactory final : public RunWorkerFactory { - setProduct(); - addSupportedRunMode(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); - addSupportedDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); +public: + LocalQmlProfilerRunWorkerFactory() + { + setProduct(); + addSupportedRunMode(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); + addSupportedDeviceType(ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE); + } +}; + +void setupQmlProfilerRunning() +{ + static QmlProfilerRunWorkerFactory theQmlProfilerRunWorkerFactory; + static LocalQmlProfilerRunWorkerFactory theLocalQmlProfilerRunWorkerFactory; } + } // QmlProfiler::Internal diff --git a/src/plugins/qmlprofiler/qmlprofilerruncontrol.h b/src/plugins/qmlprofiler/qmlprofilerruncontrol.h index f23e59666e1..4dbbdf6600c 100644 --- a/src/plugins/qmlprofiler/qmlprofilerruncontrol.h +++ b/src/plugins/qmlprofiler/qmlprofilerruncontrol.h @@ -50,18 +50,6 @@ public: const QUrl &serverUrl); }; -// The bits plugged in in remote setups. -class QmlProfilerRunWorkerFactory final : public ProjectExplorer::RunWorkerFactory -{ -public: - QmlProfilerRunWorkerFactory(); -}; - -// The full local profiler. -class LocalQmlProfilerRunWorkerFactory final : public ProjectExplorer::RunWorkerFactory -{ -public: - LocalQmlProfilerRunWorkerFactory(); -}; +void setupQmlProfilerRunning(); } // QmlProfiler::Internal From 6b7d25074419303f71c08aab49cc5a8660ee9880 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Nov 2023 17:53:46 +0100 Subject: [PATCH 0329/1546] PerfProfiler: Simplify StatisticView setup Change-Id: Ie067025c1b9aec93c5f6a5baf68dbb616a066bcb Reviewed-by: Jarek Kobus --- .../perfprofiler/perfprofilerstatisticsmodel.cpp | 10 ++++------ .../perfprofiler/perfprofilerstatisticsmodel.h | 6 ++++-- .../perfprofiler/perfprofilerstatisticsview.cpp | 14 +++++++------- .../perfprofiler/perfprofilerstatisticsview.h | 8 +++----- src/plugins/perfprofiler/perfprofilertool.cpp | 2 +- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/plugins/perfprofiler/perfprofilerstatisticsmodel.cpp b/src/plugins/perfprofiler/perfprofilerstatisticsmodel.cpp index 112252923f5..9c622331452 100644 --- a/src/plugins/perfprofiler/perfprofilerstatisticsmodel.cpp +++ b/src/plugins/perfprofiler/perfprofilerstatisticsmodel.cpp @@ -150,7 +150,7 @@ QByteArray PerfProfilerStatisticsMainModel::metaInfo( int typeId, PerfProfilerStatisticsModel::Column column) const { // Need to look up stuff from tracemanager - PerfProfilerTraceManager *manager = static_cast(QObject::parent()); + PerfProfilerTraceManager *manager = &traceManager(); switch (column) { case BinaryLocation: case Function: { @@ -174,9 +174,7 @@ QByteArray PerfProfilerStatisticsMainModel::metaInfo( quint64 PerfProfilerStatisticsMainModel::address(int typeId) const { - PerfProfilerTraceManager *manager = - static_cast(QObject::parent()); - return manager->location(typeId).address; + return traceManager().location(typeId).address; } void PerfProfilerStatisticsMainModel::initialize() @@ -318,14 +316,14 @@ int PerfProfilerStatisticsMainModel::rowForTypeId(int typeId) const return m_backwardIndex[static_cast(it - m_data.begin())]; } -PerfProfilerStatisticsMainModel::PerfProfilerStatisticsMainModel(PerfProfilerTraceManager *parent) : +PerfProfilerStatisticsMainModel::PerfProfilerStatisticsMainModel(QObject *parent) : PerfProfilerStatisticsModel(Main, parent), m_startTime(std::numeric_limits::min()), m_endTime(std::numeric_limits::max()), m_totalSamples(0) { m_children = new PerfProfilerStatisticsRelativesModel(Children, this); m_parents = new PerfProfilerStatisticsRelativesModel(Parents, this); PerfProfilerStatisticsData *data = new PerfProfilerStatisticsData; - parent->registerFeatures(PerfEventType::attributeFeatures(), + traceManager().registerFeatures(PerfEventType::attributeFeatures(), std::bind(&PerfProfilerStatisticsData::loadEvent, data, std::placeholders::_1, std::placeholders::_2), std::bind(&PerfProfilerStatisticsMainModel::initialize, this), diff --git a/src/plugins/perfprofiler/perfprofilerstatisticsmodel.h b/src/plugins/perfprofiler/perfprofilerstatisticsmodel.h index 2913fcddeaf..5f5bd756125 100644 --- a/src/plugins/perfprofiler/perfprofilerstatisticsmodel.h +++ b/src/plugins/perfprofiler/perfprofilerstatisticsmodel.h @@ -55,10 +55,12 @@ protected: }; class PerfProfilerStatisticsRelativesModel; -class PerfProfilerStatisticsMainModel : public PerfProfilerStatisticsModel { + +class PerfProfilerStatisticsMainModel : public PerfProfilerStatisticsModel +{ Q_OBJECT public: - PerfProfilerStatisticsMainModel(PerfProfilerTraceManager *parent); + PerfProfilerStatisticsMainModel(QObject *parent); ~PerfProfilerStatisticsMainModel() override; PerfProfilerStatisticsRelativesModel *children() const { return m_children; } PerfProfilerStatisticsRelativesModel *parents() const { return m_parents; } diff --git a/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp b/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp index aed78ee711c..701308d3744 100644 --- a/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp +++ b/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp @@ -7,6 +7,8 @@ #include +#include + #include #include #include @@ -40,8 +42,7 @@ public: } }; -PerfProfilerStatisticsView::PerfProfilerStatisticsView(QWidget *parent, PerfProfilerTool *tool) : - QWidget(parent) +PerfProfilerStatisticsView::PerfProfilerStatisticsView() { setObjectName(QLatin1String("PerfProfilerStatisticsView")); @@ -67,8 +68,7 @@ PerfProfilerStatisticsView::PerfProfilerStatisticsView(QWidget *parent, PerfProf groupLayout->addWidget(splitterVertical); setLayout(groupLayout); - PerfProfilerTraceManager *manager = &traceManager(); - PerfProfilerStatisticsMainModel *mainModel = new PerfProfilerStatisticsMainModel(manager); + auto mainModel = new PerfProfilerStatisticsMainModel(this); PerfProfilerStatisticsRelativesModel *children = mainModel->children(); PerfProfilerStatisticsRelativesModel *parents = mainModel->parents(); @@ -77,11 +77,11 @@ PerfProfilerStatisticsView::PerfProfilerStatisticsView(QWidget *parent, PerfProf m_childrenView->setModel(children); m_parentsView->setModel(parents); - auto propagateSelection = [this, manager, children, parents](int locationId){ + auto propagateSelection = [this, children, parents](int locationId) { children->selectByTypeId(locationId); parents->selectByTypeId(locationId); - const PerfEventType::Location &location = manager->location(locationId); - const QByteArray &file = manager->string(location.file); + const PerfEventType::Location &location = traceManager().location(locationId); + const QByteArray &file = traceManager().string(location.file); if (!file.isEmpty()) emit gotoSourceLocation(QString::fromUtf8(file), location.line, location.column); emit typeSelected(locationId); diff --git a/src/plugins/perfprofiler/perfprofilerstatisticsview.h b/src/plugins/perfprofiler/perfprofilerstatisticsview.h index 1ae041731a8..58c80499b80 100644 --- a/src/plugins/perfprofiler/perfprofilerstatisticsview.h +++ b/src/plugins/perfprofiler/perfprofilerstatisticsview.h @@ -5,22 +5,20 @@ #include "perftimelinemodel.h" -#include - #include namespace PerfProfiler { namespace Internal { -class PerfProfilerStatisticsMainModel; -class PerfProfilerTool; class StatisticsView; class PerfProfilerStatisticsView : public QWidget { Q_OBJECT + public: - PerfProfilerStatisticsView(QWidget *parent, PerfProfilerTool *tool); + PerfProfilerStatisticsView(); + bool focusedTableHasValidSelection() const; void selectByTypeId(int symbol); diff --git a/src/plugins/perfprofiler/perfprofilertool.cpp b/src/plugins/perfprofiler/perfprofilertool.cpp index a9cf1a632f1..e06adb88b7d 100644 --- a/src/plugins/perfprofiler/perfprofilertool.cpp +++ b/src/plugins/perfprofiler/perfprofilertool.cpp @@ -176,7 +176,7 @@ void PerfProfilerTool::createViews() connect(m_traceView, &PerfProfilerTraceView::gotoSourceLocation, this, &PerfProfilerTool::gotoSourceLocation); - m_statisticsView = new PerfProfilerStatisticsView(nullptr, this); + m_statisticsView = new PerfProfilerStatisticsView; m_statisticsView->setWindowTitle(Tr::tr("Statistics")); m_flameGraphView = new PerfProfilerFlameGraphView(nullptr, this); From 530119c2e36698ff05fc934551572cf7ba9085e5 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 21 Nov 2023 18:17:47 +0100 Subject: [PATCH 0330/1546] PerfProfiler: Remove warnings Remove warnings about unused arguments and [this] lambda captures. Change-Id: Ic1ab0808008cf628a9114d4fcc7c38890f33d4dd Reviewed-by: hjk --- src/plugins/perfprofiler/perfprofilerflamegraphview.cpp | 6 ++---- src/plugins/perfprofiler/perfprofilerflamegraphview.h | 2 +- src/plugins/perfprofiler/perfprofilerstatisticsview.cpp | 1 - src/plugins/perfprofiler/perfprofilerstatisticsview.h | 2 -- src/plugins/perfprofiler/perfprofilertool.cpp | 6 +++--- 5 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/plugins/perfprofiler/perfprofilerflamegraphview.cpp b/src/plugins/perfprofiler/perfprofilerflamegraphview.cpp index 79d71b34395..076c9778882 100644 --- a/src/plugins/perfprofiler/perfprofilerflamegraphview.cpp +++ b/src/plugins/perfprofiler/perfprofilerflamegraphview.cpp @@ -3,8 +3,6 @@ #include "perfprofilerflamegraphmodel.h" #include "perfprofilerflamegraphview.h" -#include "perfprofilertool.h" -#include "perftimelinemodel.h" #include #include @@ -16,8 +14,8 @@ namespace PerfProfiler { namespace Internal { -PerfProfilerFlameGraphView::PerfProfilerFlameGraphView(QWidget *parent, PerfProfilerTool *tool) : - QQuickWidget(parent) +PerfProfilerFlameGraphView::PerfProfilerFlameGraphView(QWidget *parent) + : QQuickWidget(parent) { setObjectName(QLatin1String("PerfProfilerFlameGraphView")); diff --git a/src/plugins/perfprofiler/perfprofilerflamegraphview.h b/src/plugins/perfprofiler/perfprofilerflamegraphview.h index 945429440f0..e626ef8a17c 100644 --- a/src/plugins/perfprofiler/perfprofilerflamegraphview.h +++ b/src/plugins/perfprofiler/perfprofilerflamegraphview.h @@ -15,7 +15,7 @@ class PerfProfilerFlameGraphView : public QQuickWidget { Q_OBJECT public: - PerfProfilerFlameGraphView(QWidget *parent, PerfProfilerTool *tool); + PerfProfilerFlameGraphView(QWidget *parent); ~PerfProfilerFlameGraphView(); void selectByTypeId(int typeId); diff --git a/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp b/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp index 701308d3744..1ef10ca304a 100644 --- a/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp +++ b/src/plugins/perfprofiler/perfprofilerstatisticsview.cpp @@ -3,7 +3,6 @@ #include "perfprofilerstatisticsmodel.h" #include "perfprofilerstatisticsview.h" -#include "perfprofilertool.h" #include diff --git a/src/plugins/perfprofiler/perfprofilerstatisticsview.h b/src/plugins/perfprofiler/perfprofilerstatisticsview.h index 58c80499b80..e572eef7108 100644 --- a/src/plugins/perfprofiler/perfprofilerstatisticsview.h +++ b/src/plugins/perfprofiler/perfprofilerstatisticsview.h @@ -3,8 +3,6 @@ #pragma once -#include "perftimelinemodel.h" - #include namespace PerfProfiler { diff --git a/src/plugins/perfprofiler/perfprofilertool.cpp b/src/plugins/perfprofiler/perfprofilertool.cpp index e06adb88b7d..07847e3271b 100644 --- a/src/plugins/perfprofiler/perfprofilertool.cpp +++ b/src/plugins/perfprofiler/perfprofilertool.cpp @@ -100,7 +100,7 @@ PerfProfilerTool::PerfProfilerTool() command = Core::ActionManager::registerAction(m_showFullRange, Constants::PerfProfilerTaskFullRange, globalContext); - connect(m_showFullRange, &QAction::triggered, this, [this]() { + connect(m_showFullRange, &QAction::triggered, this, [] { traceManager().restrictByFilter(traceManager().rangeAndThreadFilter(-1, -1)); }); options->addAction(command); @@ -179,7 +179,7 @@ void PerfProfilerTool::createViews() m_statisticsView = new PerfProfilerStatisticsView; m_statisticsView->setWindowTitle(Tr::tr("Statistics")); - m_flameGraphView = new PerfProfilerFlameGraphView(nullptr, this); + m_flameGraphView = new PerfProfilerFlameGraphView(nullptr); m_flameGraphView->setWindowTitle(Tr::tr("Flame Graph")); connect(m_statisticsView, &PerfProfilerStatisticsView::gotoSourceLocation, @@ -500,7 +500,7 @@ void PerfProfilerTool::updateFilterMenu() if (thread.tid == 0) { action->setEnabled(false); } else { - connect(action, &QAction::toggled, this, [this, action](bool checked) { + connect(action, &QAction::toggled, this, [action](bool checked) { traceManager().setThreadEnabled(action->data().toUInt(), checked); }); connect(enableAll, &QAction::triggered, From 21beda0b77be7542098ad234ca283d8c90671d62 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Nov 2023 11:29:46 +0100 Subject: [PATCH 0331/1546] GenericProject: Use new setup for build related classes Change-Id: Ic11a48a5429efbf6f0e52e1b88f366a966ad91a7 Reviewed-by: Jarek Kobus --- .../genericbuildconfiguration.cpp | 44 ++++++++++-------- .../genericbuildconfiguration.h | 8 +--- .../genericprojectmanager/genericmakestep.cpp | 46 +++++++++++-------- .../genericprojectmanager/genericmakestep.h | 14 ++---- .../genericprojectplugin.cpp | 5 +- 5 files changed, 59 insertions(+), 58 deletions(-) diff --git a/src/plugins/genericprojectmanager/genericbuildconfiguration.cpp b/src/plugins/genericprojectmanager/genericbuildconfiguration.cpp index 5d1c4562762..878794f81fc 100644 --- a/src/plugins/genericprojectmanager/genericbuildconfiguration.cpp +++ b/src/plugins/genericprojectmanager/genericbuildconfiguration.cpp @@ -7,8 +7,10 @@ #include "genericprojectconstants.h" #include "genericprojectmanagertr.h" +#include #include #include +#include #include #include @@ -46,29 +48,35 @@ public: } }; - -// GenericBuildConfigurationFactory - -GenericBuildConfigurationFactory::GenericBuildConfigurationFactory() +class GenericBuildConfigurationFactory final : public BuildConfigurationFactory { - registerBuildConfiguration - ("GenericProjectManager.GenericBuildConfiguration"); +public: + GenericBuildConfigurationFactory() + { + registerBuildConfiguration + ("GenericProjectManager.GenericBuildConfiguration"); - setSupportedProjectType(Constants::GENERICPROJECT_ID); - setSupportedProjectMimeTypeName(Constants::GENERICMIMETYPE); + setSupportedProjectType(Constants::GENERICPROJECT_ID); + setSupportedProjectMimeTypeName(Constants::GENERICMIMETYPE); - setBuildGenerator([](const Kit *, const FilePath &projectPath, bool forSetup) { - BuildInfo info; - info.typeName = ProjectExplorer::Tr::tr("Build"); - info.buildDirectory = forSetup ? Project::projectDirectory(projectPath) : projectPath; + setBuildGenerator([](const Kit *, const FilePath &projectPath, bool forSetup) { + BuildInfo info; + info.typeName = ProjectExplorer::Tr::tr("Build"); + info.buildDirectory = forSetup ? Project::projectDirectory(projectPath) : projectPath; - if (forSetup) { - //: The name of the build configuration created by default for a generic project. - info.displayName = ProjectExplorer::Tr::tr("Default"); - } + if (forSetup) { + //: The name of the build configuration created by default for a generic project. + info.displayName = ProjectExplorer::Tr::tr("Default"); + } - return QList{info}; - }); + return QList{info}; + }); + } +}; + +void setupGenericBuildConfiguration() +{ + static GenericBuildConfigurationFactory theGenericBuildConfigurationFactory; } } // GenericProjectManager::Internal diff --git a/src/plugins/genericprojectmanager/genericbuildconfiguration.h b/src/plugins/genericprojectmanager/genericbuildconfiguration.h index 6fb8a3807b1..585aa6b4300 100644 --- a/src/plugins/genericprojectmanager/genericbuildconfiguration.h +++ b/src/plugins/genericprojectmanager/genericbuildconfiguration.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace GenericProjectManager::Internal { -class GenericBuildConfigurationFactory final : public ProjectExplorer::BuildConfigurationFactory -{ -public: - GenericBuildConfigurationFactory(); -}; +void setupGenericBuildConfiguration(); } // GenericProjectManager::Internal diff --git a/src/plugins/genericprojectmanager/genericmakestep.cpp b/src/plugins/genericprojectmanager/genericmakestep.cpp index df36c6ad4b2..48a60138be9 100644 --- a/src/plugins/genericprojectmanager/genericmakestep.cpp +++ b/src/plugins/genericprojectmanager/genericmakestep.cpp @@ -2,40 +2,48 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "genericmakestep.h" + #include "genericprojectconstants.h" +#include #include #include using namespace ProjectExplorer; +using namespace Utils; -namespace GenericProjectManager { -namespace Internal { +namespace GenericProjectManager::Internal { -class GenericMakeStep : public ProjectExplorer::MakeStep +class GenericMakeStep final : public MakeStep { public: - explicit GenericMakeStep(BuildStepList *parent, Utils::Id id); + GenericMakeStep(BuildStepList *parent, Id id) + : MakeStep(parent, id) + { + setAvailableBuildTargets({"all", "clean"}); + if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_BUILD) { + setSelectedBuildTarget("all"); + } else if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) { + setSelectedBuildTarget("clean"); + setIgnoreReturnValue(true); + } + } }; -GenericMakeStep::GenericMakeStep(BuildStepList *parent, Utils::Id id) - : MakeStep(parent, id) +class GenericMakeStepFactory final : public BuildStepFactory { - setAvailableBuildTargets({"all", "clean"}); - if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_BUILD) { - setSelectedBuildTarget("all"); - } else if (parent->id() == ProjectExplorer::Constants::BUILDSTEPS_CLEAN) { - setSelectedBuildTarget("clean"); - setIgnoreReturnValue(true); +public: + GenericMakeStepFactory() + { + registerStep(Constants::GENERIC_MS_ID); + setDisplayName(MakeStep::defaultDisplayName()); + setSupportedProjectType(Constants::GENERICPROJECT_ID); } -} +}; -GenericMakeStepFactory::GenericMakeStepFactory() +void setupGenericMakeStep() { - registerStep(Constants::GENERIC_MS_ID); - setDisplayName(MakeStep::defaultDisplayName()); - setSupportedProjectType(Constants::GENERICPROJECT_ID); + static GenericMakeStepFactory theGenericMakeStepFactory; } -} // namespace Internal -} // namespace GenericProjectManager +} // GenericProjectManager::Internal diff --git a/src/plugins/genericprojectmanager/genericmakestep.h b/src/plugins/genericprojectmanager/genericmakestep.h index d7f2ef092f1..7ee440366f5 100644 --- a/src/plugins/genericprojectmanager/genericmakestep.h +++ b/src/plugins/genericprojectmanager/genericmakestep.h @@ -3,16 +3,8 @@ #pragma once -#include +namespace GenericProjectManager::Internal { -namespace GenericProjectManager { -namespace Internal { +void setupGenericMakeStep(); -class GenericMakeStepFactory final : public ProjectExplorer::BuildStepFactory -{ -public: - GenericMakeStepFactory(); -}; - -} // namespace Internal -} // namespace GenericProjectManager +} // GenericProjectManager::Internal diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.cpp b/src/plugins/genericprojectmanager/genericprojectplugin.cpp index 1977c4659b4..05d392c70d2 100644 --- a/src/plugins/genericprojectmanager/genericprojectplugin.cpp +++ b/src/plugins/genericprojectmanager/genericprojectplugin.cpp @@ -34,9 +34,6 @@ class GenericProjectPluginPrivate : public QObject { public: GenericProjectPluginPrivate(); - - GenericMakeStepFactory makeStepFactory; - GenericBuildConfigurationFactory buildConfigFactory; }; GenericProjectPluginPrivate::GenericProjectPluginPrivate() @@ -45,6 +42,8 @@ GenericProjectPluginPrivate::GenericProjectPluginPrivate() setupGenericProjectWizard(); setupGenericProjectFiles(); + setupGenericMakeStep(); + setupGenericBuildConfiguration(); ActionBuilder editAction(this, "GenericProjectManager.EditFiles"); editAction.setContext(Constants::GENERICPROJECT_ID); From 4f97dc7090cb4673123d8fa6188eae99aff9d38f Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Nov 2023 14:02:59 +0100 Subject: [PATCH 0332/1546] Copilot: Move plugin class definition to .cpp Change-Id: Ic21b150c08924a273c3d10a3b386fc7dcb9c8e1a Reviewed-by: Christian Stenger --- src/plugins/copilot/CMakeLists.txt | 2 +- src/plugins/copilot/copilot.qbs | 1 - src/plugins/copilot/copilotclient.cpp | 8 +- src/plugins/copilot/copilotplugin.cpp | 197 ++++++++++++++------------ src/plugins/copilot/copilotplugin.h | 31 ---- 5 files changed, 109 insertions(+), 130 deletions(-) delete mode 100644 src/plugins/copilot/copilotplugin.h diff --git a/src/plugins/copilot/CMakeLists.txt b/src/plugins/copilot/CMakeLists.txt index f50890d0fd2..04b80abc3f3 100644 --- a/src/plugins/copilot/CMakeLists.txt +++ b/src/plugins/copilot/CMakeLists.txt @@ -6,7 +6,7 @@ add_qtc_plugin(Copilot copilotclient.cpp copilotclient.h copilotconstants.h copilothoverhandler.cpp copilothoverhandler.h - copilotplugin.cpp copilotplugin.h + copilotplugin.cpp copilotprojectpanel.cpp copilotprojectpanel.h copilotsettings.cpp copilotsettings.h copilotsuggestion.cpp copilotsuggestion.h diff --git a/src/plugins/copilot/copilot.qbs b/src/plugins/copilot/copilot.qbs index 6d2b2100472..680c29dd14d 100644 --- a/src/plugins/copilot/copilot.qbs +++ b/src/plugins/copilot/copilot.qbs @@ -19,7 +19,6 @@ QtcPlugin { "copilothoverhandler.cpp", "copilothoverhandler.h", "copilotplugin.cpp", - "copilotplugin.h", "copilotprojectpanel.cpp", "copilotprojectpanel.h", "copilotsettings.cpp", diff --git a/src/plugins/copilot/copilotclient.cpp b/src/plugins/copilot/copilotclient.cpp index 6b09882dee9..8a2dec3bb29 100644 --- a/src/plugins/copilot/copilotclient.cpp +++ b/src/plugins/copilot/copilotclient.cpp @@ -170,11 +170,11 @@ void CopilotClient::requestCompletions(TextEditorWidget *editor) if (!isEnabled(project)) return; - Utils::MultiTextCursor cursor = editor->multiTextCursor(); + MultiTextCursor cursor = editor->multiTextCursor(); if (cursor.hasMultipleCursors() || cursor.hasSelection() || editor->suggestionVisible()) return; - const Utils::FilePath filePath = editor->textDocument()->filePath(); + const FilePath filePath = editor->textDocument()->filePath(); GetCompletionRequest request{ {TextDocumentIdentifier(hostPathToServerUri(filePath)), documentVersion(filePath), @@ -198,7 +198,7 @@ void CopilotClient::handleCompletions(const GetCompletionRequest::Response &resp if (const auto requestParams = m_runningRequests.take(editor).params()) requestPosition = requestParams->position().toPositionInDocument(editor->document()); - const Utils::MultiTextCursor cursors = editor->multiTextCursor(); + const MultiTextCursor cursors = editor->multiTextCursor(); if (cursors.hasMultipleCursors()) return; @@ -331,7 +331,7 @@ void CopilotClient::proxyAuthenticationFailed() m_isAskingForPassword = true; - auto answer = Utils::PasswordDialog::getUserAndPassword( + auto answer = PasswordDialog::getUserAndPassword( Tr::tr("Copilot"), Tr::tr("Proxy username and password required:"), Tr::tr("Do not ask again. This will disable Copilot for now."), diff --git a/src/plugins/copilot/copilotplugin.cpp b/src/plugins/copilot/copilotplugin.cpp index 2ad525f5f37..78ca70b3fd9 100644 --- a/src/plugins/copilot/copilotplugin.cpp +++ b/src/plugins/copilot/copilotplugin.cpp @@ -1,8 +1,6 @@ // Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "copilotplugin.h" - #include "copilotclient.h" #include "copilotconstants.h" #include "copiloticons.h" @@ -15,6 +13,8 @@ #include #include +#include + #include #include @@ -22,20 +22,20 @@ #include #include +#include using namespace Utils; using namespace Core; using namespace ProjectExplorer; -namespace Copilot { -namespace Internal { +namespace Copilot::Internal { enum Direction { Previous, Next }; -void cycleSuggestion(TextEditor::TextEditorWidget *editor, Direction direction) +static void cycleSuggestion(TextEditor::TextEditorWidget *editor, Direction direction) { QTextBlock block = editor->textCursor().block(); - if (auto *suggestion = dynamic_cast( + if (auto suggestion = dynamic_cast( TextEditor::TextDocumentLayout::suggestion(block))) { int index = suggestion->currentCompletion(); if (direction == Previous) @@ -53,108 +53,119 @@ void cycleSuggestion(TextEditor::TextEditorWidget *editor, Direction direction) } } -void CopilotPlugin::initialize() +class CopilotPlugin final : public ExtensionSystem::IPlugin { - ActionBuilder requestAction(this, Constants::COPILOT_REQUEST_SUGGESTION); - requestAction.setText(Tr::tr("Request Copilot Suggestion")); - requestAction.setToolTip(Tr::tr( - "Request Copilot suggestion at the current editor's cursor position.")); - requestAction.setOnTriggered(this, [this] { - if (auto editor = TextEditor::TextEditorWidget::currentTextEditorWidget()) { - if (m_client && m_client->reachable()) - m_client->requestCompletions(editor); - } - }); + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Copilot.json") - ActionBuilder nextSuggestionAction(this, Constants::COPILOT_NEXT_SUGGESTION); - nextSuggestionAction.setText(Tr::tr("Show Next Copilot Suggestion")); - nextSuggestionAction.setToolTip(Tr::tr( - "Cycles through the received Copilot Suggestions showing the next available Suggestion.")); - nextSuggestionAction.setOnTriggered(this, [] { - if (auto editor = TextEditor::TextEditorWidget::currentTextEditorWidget()) - cycleSuggestion(editor, Next); - }); +public: + void initialize() final + { + ActionBuilder requestAction(this, Constants::COPILOT_REQUEST_SUGGESTION); + requestAction.setText(Tr::tr("Request Copilot Suggestion")); + requestAction.setToolTip(Tr::tr( + "Request Copilot suggestion at the current editor's cursor position.")); + requestAction.setOnTriggered(this, [this] { + if (auto editor = TextEditor::TextEditorWidget::currentTextEditorWidget()) { + if (m_client && m_client->reachable()) + m_client->requestCompletions(editor); + } + }); - ActionBuilder previousSuggestionAction(this, Constants::COPILOT_PREVIOUS_SUGGESTION); - previousSuggestionAction.setText(Tr::tr("Show Previous Copilot Suggestion")); - previousSuggestionAction.setToolTip(Tr::tr("Cycles through the received Copilot Suggestions " - "showing the previous available Suggestion.")); - previousSuggestionAction.setOnTriggered(this, [] { - if (auto editor = TextEditor::TextEditorWidget::currentTextEditorWidget()) - cycleSuggestion(editor, Previous); - }); + ActionBuilder nextSuggestionAction(this, Constants::COPILOT_NEXT_SUGGESTION); + nextSuggestionAction.setText(Tr::tr("Show Next Copilot Suggestion")); + nextSuggestionAction.setToolTip(Tr::tr( + "Cycles through the received Copilot Suggestions showing the next available Suggestion.")); + nextSuggestionAction.setOnTriggered(this, [] { + if (auto editor = TextEditor::TextEditorWidget::currentTextEditorWidget()) + cycleSuggestion(editor, Next); + }); - ActionBuilder disableAction(this, Constants::COPILOT_DISABLE); - disableAction.setText(Tr::tr("Disable Copilot")); - disableAction.setToolTip(Tr::tr("Disable Copilot.")); - disableAction.setOnTriggered(this, [] { - settings().enableCopilot.setValue(true); - settings().apply(); - }); + ActionBuilder previousSuggestionAction(this, Constants::COPILOT_PREVIOUS_SUGGESTION); + previousSuggestionAction.setText(Tr::tr("Show Previous Copilot Suggestion")); + previousSuggestionAction.setToolTip(Tr::tr("Cycles through the received Copilot Suggestions " + "showing the previous available Suggestion.")); + previousSuggestionAction.setOnTriggered(this, [] { + if (auto editor = TextEditor::TextEditorWidget::currentTextEditorWidget()) + cycleSuggestion(editor, Previous); + }); - ActionBuilder enableAction(this, Constants::COPILOT_ENABLE); - enableAction.setText(Tr::tr("Enable Copilot")); - enableAction.setToolTip(Tr::tr("Enable Copilot.")); - enableAction.setOnTriggered(this, [] { - settings().enableCopilot.setValue(false); - settings().apply(); - }); + ActionBuilder disableAction(this, Constants::COPILOT_DISABLE); + disableAction.setText(Tr::tr("Disable Copilot")); + disableAction.setToolTip(Tr::tr("Disable Copilot.")); + disableAction.setOnTriggered(this, [] { + settings().enableCopilot.setValue(true); + settings().apply(); + }); - ActionBuilder toggleAction(this, Constants::COPILOT_TOGGLE); - toggleAction.setText(Tr::tr("Toggle Copilot")); - toggleAction.setCheckable(true); - toggleAction.setChecked(settings().enableCopilot()); - toggleAction.setIcon(COPILOT_ICON.icon()); - toggleAction.setOnTriggered(this, [](bool checked) { - settings().enableCopilot.setValue(checked); - settings().apply(); - }); + ActionBuilder enableAction(this, Constants::COPILOT_ENABLE); + enableAction.setText(Tr::tr("Enable Copilot")); + enableAction.setToolTip(Tr::tr("Enable Copilot.")); + enableAction.setOnTriggered(this, [] { + settings().enableCopilot.setValue(false); + settings().apply(); + }); - QAction *toggleAct = toggleAction.contextAction(); - QAction *requestAct = requestAction.contextAction(); - auto updateActions = [toggleAct, requestAct] { - const bool enabled = settings().enableCopilot(); - toggleAct->setToolTip(enabled ? Tr::tr("Disable Copilot.") : Tr::tr("Enable Copilot.")); - toggleAct->setChecked(enabled); - requestAct->setEnabled(enabled); - }; + ActionBuilder toggleAction(this, Constants::COPILOT_TOGGLE); + toggleAction.setText(Tr::tr("Toggle Copilot")); + toggleAction.setCheckable(true); + toggleAction.setChecked(settings().enableCopilot()); + toggleAction.setIcon(COPILOT_ICON.icon()); + toggleAction.setOnTriggered(this, [](bool checked) { + settings().enableCopilot.setValue(checked); + settings().apply(); + }); - connect(&settings().enableCopilot, &BaseAspect::changed, this, updateActions); + QAction *toggleAct = toggleAction.contextAction(); + QAction *requestAct = requestAction.contextAction(); + auto updateActions = [toggleAct, requestAct] { + const bool enabled = settings().enableCopilot(); + toggleAct->setToolTip(enabled ? Tr::tr("Disable Copilot.") : Tr::tr("Enable Copilot.")); + toggleAct->setChecked(enabled); + requestAct->setEnabled(enabled); + }; - updateActions(); + connect(&settings().enableCopilot, &BaseAspect::changed, this, updateActions); - auto toggleButton = new QToolButton; - toggleButton->setDefaultAction(toggleAction.contextAction()); - StatusBarManager::addStatusBarWidget(toggleButton, StatusBarManager::RightCorner); + updateActions(); - setupCopilotProjectPanel(); -} + auto toggleButton = new QToolButton; + toggleButton->setDefaultAction(toggleAction.contextAction()); + StatusBarManager::addStatusBarWidget(toggleButton, StatusBarManager::RightCorner); -bool CopilotPlugin::delayedInitialize() -{ - restartClient(); + setupCopilotProjectPanel(); + } - connect(&settings(), &AspectContainer::applied, this, &CopilotPlugin::restartClient); + bool delayedInitialize() final + { + restartClient(); - return true; -} + connect(&settings(), &AspectContainer::applied, this, &CopilotPlugin::restartClient); -void CopilotPlugin::restartClient() -{ - LanguageClient::LanguageClientManager::shutdownClient(m_client); + return true; + } - if (!settings().nodeJsPath().isExecutableFile()) - return; - m_client = new CopilotClient(settings().nodeJsPath(), settings().distPath()); -} + void restartClient() + { + LanguageClient::LanguageClientManager::shutdownClient(m_client); -ExtensionSystem::IPlugin::ShutdownFlag CopilotPlugin::aboutToShutdown() -{ - if (!m_client) - return SynchronousShutdown; - connect(m_client, &QObject::destroyed, this, &IPlugin::asynchronousShutdownFinished); - return AsynchronousShutdown; -} + if (!settings().nodeJsPath().isExecutableFile()) + return; + m_client = new CopilotClient(settings().nodeJsPath(), settings().distPath()); + } -} // namespace Internal -} // namespace Copilot + ShutdownFlag aboutToShutdown() final + { + if (!m_client) + return SynchronousShutdown; + connect(m_client, &QObject::destroyed, this, &IPlugin::asynchronousShutdownFinished); + return AsynchronousShutdown; + } + +private: + QPointer m_client; +}; + +} // Copilot::Internal + +#include "copilotplugin.moc" diff --git a/src/plugins/copilot/copilotplugin.h b/src/plugins/copilot/copilotplugin.h deleted file mode 100644 index 9f709b2a101..00000000000 --- a/src/plugins/copilot/copilotplugin.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2023 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include "copilotclient.h" - -#include - -#include - -namespace Copilot { -namespace Internal { - -class CopilotPlugin : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Copilot.json") - -public: - void initialize() override; - bool delayedInitialize() override; - void restartClient(); - ShutdownFlag aboutToShutdown() override; - -private: - QPointer m_client; -}; - -} // namespace Internal -} // namespace Copilot From e0ad6041f0e0c85a7cf8e8ed9c3815c543e6cc6f Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 15:08:12 +0100 Subject: [PATCH 0333/1546] RemoteLinux: Use new factory setup pattern for most factories Change-Id: I667b879443d712054095c7bdbfe401014d41ac92 Reviewed-by: Christian Stenger --- .../remotelinux/customcommanddeploystep.cpp | 19 +++++-- .../remotelinux/customcommanddeploystep.h | 8 +-- src/plugins/remotelinux/killappstep.cpp | 19 +++++-- src/plugins/remotelinux/killappstep.h | 8 +-- src/plugins/remotelinux/linuxdevice.cpp | 35 +++++++----- src/plugins/remotelinux/linuxdevice.h | 9 +-- .../remotelinuxcustomrunconfiguration.cpp | 18 ++++-- .../remotelinuxcustomrunconfiguration.h | 9 +-- .../remotelinux/remotelinuxdebugsupport.cpp | 55 +++++++++++++------ .../remotelinux/remotelinuxdebugsupport.h | 20 +------ src/plugins/remotelinux/remotelinuxplugin.cpp | 36 +++++------- .../remotelinuxrunconfiguration.cpp | 17 ++++-- .../remotelinux/remotelinuxrunconfiguration.h | 8 +-- .../remotelinux/tarpackagecreationstep.cpp | 19 +++++-- .../remotelinux/tarpackagecreationstep.h | 8 +-- .../remotelinux/tarpackagedeploystep.cpp | 19 +++++-- .../remotelinux/tarpackagedeploystep.h | 8 +-- 17 files changed, 165 insertions(+), 150 deletions(-) diff --git a/src/plugins/remotelinux/customcommanddeploystep.cpp b/src/plugins/remotelinux/customcommanddeploystep.cpp index 0c90f8350be..211f48b4f47 100644 --- a/src/plugins/remotelinux/customcommanddeploystep.cpp +++ b/src/plugins/remotelinux/customcommanddeploystep.cpp @@ -82,12 +82,21 @@ GroupItem CustomCommandDeployStep::deployRecipe() // CustomCommandDeployStepFactory -CustomCommandDeployStepFactory::CustomCommandDeployStepFactory() +class CustomCommandDeployStepFactory final : public BuildStepFactory { - registerStep(Constants::CustomCommandDeployStepId); - setDisplayName(Tr::tr("Run custom remote command")); - setSupportedConfiguration(RemoteLinux::Constants::DeployToGenericLinux); - setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); +public: + CustomCommandDeployStepFactory() + { + registerStep(Constants::CustomCommandDeployStepId); + setDisplayName(Tr::tr("Run custom remote command")); + setSupportedConfiguration(RemoteLinux::Constants::DeployToGenericLinux); + setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); + } +}; + +void setupCustomCommandDeployStep() +{ + static CustomCommandDeployStepFactory theCustomCommandDeployStepFactory; } } // RemoteLinux::Internal diff --git a/src/plugins/remotelinux/customcommanddeploystep.h b/src/plugins/remotelinux/customcommanddeploystep.h index 7ecd2805d42..ab909988da3 100644 --- a/src/plugins/remotelinux/customcommanddeploystep.h +++ b/src/plugins/remotelinux/customcommanddeploystep.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace RemoteLinux::Internal { -class CustomCommandDeployStepFactory : public ProjectExplorer::BuildStepFactory -{ -public: - CustomCommandDeployStepFactory(); -}; +void setupCustomCommandDeployStep(); } // RemoteLinux::Internal diff --git a/src/plugins/remotelinux/killappstep.cpp b/src/plugins/remotelinux/killappstep.cpp index 0f8df90df52..1a105eb9474 100644 --- a/src/plugins/remotelinux/killappstep.cpp +++ b/src/plugins/remotelinux/killappstep.cpp @@ -63,12 +63,21 @@ GroupItem KillAppStep::deployRecipe() return DeviceProcessKillerTask(onSetup, onDone); } -KillAppStepFactory::KillAppStepFactory() +class KillAppStepFactory final : public BuildStepFactory { - registerStep(Constants::KillAppStepId); - setDisplayName(Tr::tr("Kill current application instance")); - setSupportedConfiguration(RemoteLinux::Constants::DeployToGenericLinux); - setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); +public: + KillAppStepFactory() + { + registerStep(Constants::KillAppStepId); + setDisplayName(Tr::tr("Kill current application instance")); + setSupportedConfiguration(RemoteLinux::Constants::DeployToGenericLinux); + setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); + } +}; + +void setupKillAppStep() +{ + static KillAppStepFactory theKillAppStepFactory; } } // RemoteLinux::Internal diff --git a/src/plugins/remotelinux/killappstep.h b/src/plugins/remotelinux/killappstep.h index d5d81212a27..6a2a586345b 100644 --- a/src/plugins/remotelinux/killappstep.h +++ b/src/plugins/remotelinux/killappstep.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace RemoteLinux::Internal { -class KillAppStepFactory : public ProjectExplorer::BuildStepFactory -{ -public: - KillAppStepFactory(); -}; +void setupKillAppStep(); } // RemoteLinux::Internal diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp index 3f875f1ef4b..e6239b5db25 100644 --- a/src/plugins/remotelinux/linuxdevice.cpp +++ b/src/plugins/remotelinux/linuxdevice.cpp @@ -1511,20 +1511,29 @@ void LinuxDevice::checkOsType() namespace Internal { -LinuxDeviceFactory::LinuxDeviceFactory() - : IDeviceFactory(Constants::GenericLinuxOsType) +class LinuxDeviceFactory final : public IDeviceFactory { - setDisplayName(Tr::tr("Remote Linux Device")); - setIcon(QIcon()); - setConstructionFunction(&LinuxDevice::create); - setQuickCreationAllowed(true); - setCreator([]() -> IDevice::Ptr { - const IDevice::Ptr device = LinuxDevice::create(); - SshDeviceWizard wizard(Tr::tr("New Remote Linux Device Configuration Setup"), device); - if (wizard.exec() != QDialog::Accepted) - return {}; - return device; - }); +public: + LinuxDeviceFactory() + : IDeviceFactory(Constants::GenericLinuxOsType) + { + setDisplayName(Tr::tr("Remote Linux Device")); + setIcon(QIcon()); + setConstructionFunction(&LinuxDevice::create); + setQuickCreationAllowed(true); + setCreator([]() -> IDevice::Ptr { + const IDevice::Ptr device = LinuxDevice::create(); + SshDeviceWizard wizard(Tr::tr("New Remote Linux Device Configuration Setup"), device); + if (wizard.exec() != QDialog::Accepted) + return {}; + return device; + }); + } +}; + +void setupLinuxDevice() +{ + static LinuxDeviceFactory theLinuxDeviceFactory; } } // namespace Internal diff --git a/src/plugins/remotelinux/linuxdevice.h b/src/plugins/remotelinux/linuxdevice.h index 40ce9c4860e..10c23841ecb 100644 --- a/src/plugins/remotelinux/linuxdevice.h +++ b/src/plugins/remotelinux/linuxdevice.h @@ -51,13 +51,6 @@ protected: friend class LinuxDevicePrivate; }; -namespace Internal { +namespace Internal { void setupLinuxDevice(); } -class LinuxDeviceFactory final : public ProjectExplorer::IDeviceFactory -{ -public: - LinuxDeviceFactory(); -}; - -} // namespace Internal } // namespace RemoteLinux diff --git a/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp b/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp index fd94144215c..327bc55416c 100644 --- a/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp +++ b/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.cpp @@ -84,11 +84,21 @@ Tasks RemoteLinuxCustomRunConfiguration::checkForIssues() const // RemoteLinuxCustomRunConfigurationFactory -RemoteLinuxCustomRunConfigurationFactory::RemoteLinuxCustomRunConfigurationFactory() - : FixedRunConfigurationFactory(Tr::tr("Custom Executable"), true) +class RemoteLinuxCustomRunConfigurationFactory + : public FixedRunConfigurationFactory { - registerRunConfiguration(Constants::CustomRunConfigId); - addSupportedTargetDeviceType(RemoteLinux::Constants::GenericLinuxOsType); +public: + RemoteLinuxCustomRunConfigurationFactory() + : FixedRunConfigurationFactory(Tr::tr("Custom Executable"), true) + { + registerRunConfiguration(Constants::CustomRunConfigId); + addSupportedTargetDeviceType(RemoteLinux::Constants::GenericLinuxOsType); + } +}; + +void setupRemoteLinuxCustomRunConfiguration() +{ + static RemoteLinuxCustomRunConfigurationFactory theRemoteLinuxCustomRunConfigurationFactory; } } // RemoteLinux::Internal diff --git a/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.h b/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.h index 1bf04573384..bd3dd0b8466 100644 --- a/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.h +++ b/src/plugins/remotelinux/remotelinuxcustomrunconfiguration.h @@ -3,15 +3,8 @@ #pragma once -#include - namespace RemoteLinux::Internal { -class RemoteLinuxCustomRunConfigurationFactory - : public ProjectExplorer::FixedRunConfigurationFactory -{ -public: - RemoteLinuxCustomRunConfigurationFactory(); -}; +void setupRemoteLinuxCustomRunConfiguration(); } // RemoteLinux::Internal diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp index d4cefc6394d..7a9b19145e8 100644 --- a/src/plugins/remotelinux/remotelinuxdebugsupport.cpp +++ b/src/plugins/remotelinux/remotelinuxdebugsupport.cpp @@ -89,29 +89,48 @@ static const QList supportedRunConfigs() }; } -RemoteLinuxRunWorkerFactory::RemoteLinuxRunWorkerFactory() +class RemoteLinuxRunWorkerFactory final : public RunWorkerFactory { - setProduct(); - addSupportedRunMode(ProjectExplorer::Constants::NORMAL_RUN_MODE); - addSupportedDeviceType(Constants::GenericLinuxOsType); - setSupportedRunConfigs(supportedRunConfigs()); -} +public: + RemoteLinuxRunWorkerFactory() + { + setProduct(); + addSupportedRunMode(ProjectExplorer::Constants::NORMAL_RUN_MODE); + addSupportedDeviceType(Constants::GenericLinuxOsType); + setSupportedRunConfigs(supportedRunConfigs()); + } +}; -RemoteLinuxDebugWorkerFactory::RemoteLinuxDebugWorkerFactory() +class RemoteLinuxDebugWorkerFactory final : public ProjectExplorer::RunWorkerFactory { - setProduct(); - addSupportedRunMode(ProjectExplorer::Constants::DEBUG_RUN_MODE); - addSupportedDeviceType(Constants::GenericLinuxOsType); - setSupportedRunConfigs(supportedRunConfigs()); -} +public: + RemoteLinuxDebugWorkerFactory() + { + setProduct(); + addSupportedRunMode(ProjectExplorer::Constants::DEBUG_RUN_MODE); + addSupportedDeviceType(Constants::GenericLinuxOsType); + setSupportedRunConfigs(supportedRunConfigs()); + } +}; -RemoteLinuxQmlToolingWorkerFactory::RemoteLinuxQmlToolingWorkerFactory() +class RemoteLinuxQmlToolingWorkerFactory final : public ProjectExplorer::RunWorkerFactory { - setProduct(); - addSupportedRunMode(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); - addSupportedRunMode(ProjectExplorer::Constants::QML_PREVIEW_RUN_MODE); - addSupportedDeviceType(Constants::GenericLinuxOsType); - setSupportedRunConfigs(supportedRunConfigs()); +public: + RemoteLinuxQmlToolingWorkerFactory() + { + setProduct(); + addSupportedRunMode(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); + addSupportedRunMode(ProjectExplorer::Constants::QML_PREVIEW_RUN_MODE); + addSupportedDeviceType(Constants::GenericLinuxOsType); + setSupportedRunConfigs(supportedRunConfigs()); + } +}; + +void setupRemoteLinuxRunAndDebugSupport() +{ + static RemoteLinuxRunWorkerFactory runWorkerFactory; + static RemoteLinuxDebugWorkerFactory debugWorkerFactory; + static RemoteLinuxQmlToolingWorkerFactory qmlToolingWorkerFactory; } } // RemoteLinux::Internal diff --git a/src/plugins/remotelinux/remotelinuxdebugsupport.h b/src/plugins/remotelinux/remotelinuxdebugsupport.h index dd781167f29..b8e596f8c1b 100644 --- a/src/plugins/remotelinux/remotelinuxdebugsupport.h +++ b/src/plugins/remotelinux/remotelinuxdebugsupport.h @@ -3,26 +3,8 @@ #pragma once -#include - namespace RemoteLinux::Internal { -class RemoteLinuxRunWorkerFactory final : public ProjectExplorer::RunWorkerFactory -{ -public: - explicit RemoteLinuxRunWorkerFactory(); -}; - -class RemoteLinuxDebugWorkerFactory final : public ProjectExplorer::RunWorkerFactory -{ -public: - explicit RemoteLinuxDebugWorkerFactory(); -}; - -class RemoteLinuxQmlToolingWorkerFactory final : public ProjectExplorer::RunWorkerFactory -{ -public: - explicit RemoteLinuxQmlToolingWorkerFactory(); -}; +void setupRemoteLinuxRunAndDebugSupport(); } // RemoteLinux::Internal diff --git a/src/plugins/remotelinux/remotelinuxplugin.cpp b/src/plugins/remotelinux/remotelinuxplugin.cpp index a84772b3f39..36a8b6aa098 100644 --- a/src/plugins/remotelinux/remotelinuxplugin.cpp +++ b/src/plugins/remotelinux/remotelinuxplugin.cpp @@ -77,26 +77,13 @@ public: } }; -class RemoteLinuxPluginPrivate +void setupRemoteLinuxDeployment() { -public: - LinuxDeviceFactory linuxDeviceFactory; - RemoteLinuxRunConfigurationFactory runConfigurationFactory; - RemoteLinuxCustomRunConfigurationFactory customRunConfigurationFactory; - RemoteLinuxDeployConfigurationFactory deployConfigurationFactory; - TarPackageCreationStepFactory tarPackageCreationStepFactory; - TarPackageDeployStepFactory tarPackageDeployStepFactory; - RemoteLinuxDeployStepFactory genericDirectUploadStepFactory; - RemoteLinuxDeployStepFactory rsyncDeployStepFactory; - CustomCommandDeployStepFactory customCommandDeployStepFactory; - KillAppStepFactory killAppStepFactory; - RemoteLinuxDeployStepFactory makeInstallStepFactory; - RemoteLinuxRunWorkerFactory runWorkerFactory; - RemoteLinuxDebugWorkerFactory debugWorkerFactory; - RemoteLinuxQmlToolingWorkerFactory qmlToolingWorkerFactory; -}; - -static RemoteLinuxPluginPrivate *dd = nullptr; + static RemoteLinuxDeployConfigurationFactory deployConfigurationFactory; + static RemoteLinuxDeployStepFactory genericDirectUploadStep; + static RemoteLinuxDeployStepFactory rsyncDeployStepFactory; + static RemoteLinuxDeployStepFactory makeInstallStepFactory; +} RemoteLinuxPlugin::RemoteLinuxPlugin() { @@ -107,12 +94,19 @@ RemoteLinuxPlugin::RemoteLinuxPlugin() RemoteLinuxPlugin::~RemoteLinuxPlugin() { FSEngine::unregisterDeviceScheme(u"ssh"); - delete dd; } void RemoteLinuxPlugin::initialize() { - dd = new RemoteLinuxPluginPrivate; + setupLinuxDevice(); + setupRemoteLinuxRunConfiguration(); + setupRemoteLinuxCustomRunConfiguration(); + setupRemoteLinuxRunAndDebugSupport(); + setupRemoteLinuxDeployment(); + setupTarPackageCreationStep(); + setupTarPackageDeployStep(); + setupCustomCommandDeployStep(); + setupKillAppStep(); #ifdef WITH_TESTS addTest(); diff --git a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp index 6e154f41aef..4ad48fac8d5 100644 --- a/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp +++ b/src/plugins/remotelinux/remotelinuxrunconfiguration.cpp @@ -92,11 +92,20 @@ RemoteLinuxRunConfiguration::RemoteLinuxRunConfiguration(Target *target, Id id) // RemoteLinuxRunConfigurationFactory -RemoteLinuxRunConfigurationFactory::RemoteLinuxRunConfigurationFactory() +class RemoteLinuxRunConfigurationFactory final : public ProjectExplorer::RunConfigurationFactory { - registerRunConfiguration(Constants::RunConfigId); - setDecorateDisplayNames(true); - addSupportedTargetDeviceType(RemoteLinux::Constants::GenericLinuxOsType); +public: + RemoteLinuxRunConfigurationFactory() + { + registerRunConfiguration(Constants::RunConfigId); + setDecorateDisplayNames(true); + addSupportedTargetDeviceType(RemoteLinux::Constants::GenericLinuxOsType); + } +}; + +void setupRemoteLinuxRunConfiguration() +{ + static RemoteLinuxRunConfigurationFactory theRemoteLinuxRunConfigurationFactory; } } // RemoteLinux::Internal diff --git a/src/plugins/remotelinux/remotelinuxrunconfiguration.h b/src/plugins/remotelinux/remotelinuxrunconfiguration.h index 4c953c6d799..cfa2df5084c 100644 --- a/src/plugins/remotelinux/remotelinuxrunconfiguration.h +++ b/src/plugins/remotelinux/remotelinuxrunconfiguration.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace RemoteLinux::Internal { -class RemoteLinuxRunConfigurationFactory final : public ProjectExplorer::RunConfigurationFactory -{ -public: - RemoteLinuxRunConfigurationFactory(); -}; +void setupRemoteLinuxRunConfiguration(); } // namespace RemoteLinux::Internal diff --git a/src/plugins/remotelinux/tarpackagecreationstep.cpp b/src/plugins/remotelinux/tarpackagecreationstep.cpp index 2589c22b238..e447930913c 100644 --- a/src/plugins/remotelinux/tarpackagecreationstep.cpp +++ b/src/plugins/remotelinux/tarpackagecreationstep.cpp @@ -446,13 +446,22 @@ bool TarPackageCreationStep::appendFile(QPromise &promise, return true; } -TarPackageCreationStepFactory::TarPackageCreationStepFactory() +class TarPackageCreationStepFactory final : public BuildStepFactory { - registerStep(Constants::TarPackageCreationStepId); - setDisplayName(Tr::tr("Create tarball")); +public: + TarPackageCreationStepFactory() + { + registerStep(Constants::TarPackageCreationStepId); + setDisplayName(Tr::tr("Create tarball")); - setSupportedConfiguration(RemoteLinux::Constants::DeployToGenericLinux); - setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); + setSupportedConfiguration(RemoteLinux::Constants::DeployToGenericLinux); + setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); + } +}; + +void setupTarPackageCreationStep() +{ + static TarPackageCreationStepFactory theTarPackageCreationStepFactory; } } // RemoteLinux::Internal diff --git a/src/plugins/remotelinux/tarpackagecreationstep.h b/src/plugins/remotelinux/tarpackagecreationstep.h index b3a42ecb965..c16d8a6e8e8 100644 --- a/src/plugins/remotelinux/tarpackagecreationstep.h +++ b/src/plugins/remotelinux/tarpackagecreationstep.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace RemoteLinux::Internal { -class TarPackageCreationStepFactory : public ProjectExplorer::BuildStepFactory -{ -public: - TarPackageCreationStepFactory(); -}; +void setupTarPackageCreationStep(); } // namespace RemoteLinux diff --git a/src/plugins/remotelinux/tarpackagedeploystep.cpp b/src/plugins/remotelinux/tarpackagedeploystep.cpp index 7eff5c55314..aa8fe3db309 100644 --- a/src/plugins/remotelinux/tarpackagedeploystep.cpp +++ b/src/plugins/remotelinux/tarpackagedeploystep.cpp @@ -123,12 +123,21 @@ GroupItem TarPackageDeployStep::deployRecipe() // TarPackageDeployStepFactory -TarPackageDeployStepFactory::TarPackageDeployStepFactory() +class TarPackageDeployStepFactory final : public BuildStepFactory { - registerStep(Constants::TarPackageDeployStepId); - setDisplayName(Tr::tr("Deploy tarball via SFTP upload")); - setSupportedConfiguration(RemoteLinux::Constants::DeployToGenericLinux); - setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); +public: + TarPackageDeployStepFactory() + { + registerStep(Constants::TarPackageDeployStepId); + setDisplayName(Tr::tr("Deploy tarball via SFTP upload")); + setSupportedConfiguration(RemoteLinux::Constants::DeployToGenericLinux); + setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); + } +}; + +void setupTarPackageDeployStep() +{ + static TarPackageDeployStepFactory theTarPackageDeployStepFactory; } } // RemoteLinux::Internal diff --git a/src/plugins/remotelinux/tarpackagedeploystep.h b/src/plugins/remotelinux/tarpackagedeploystep.h index f3d882cbb9e..1d63d1125c3 100644 --- a/src/plugins/remotelinux/tarpackagedeploystep.h +++ b/src/plugins/remotelinux/tarpackagedeploystep.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace RemoteLinux::Internal { -class TarPackageDeployStepFactory : public ProjectExplorer::BuildStepFactory -{ -public: - TarPackageDeployStepFactory(); -}; +void setupTarPackageDeployStep(); } // RemoteLinux::Internal From a3525a3d6731037acd5636cb99dc08355375e85b Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 15:22:02 +0100 Subject: [PATCH 0334/1546] RemoteLinux: Move some deploment related stuff into extra file pair Not necessary, but more uniform now. Change-Id: I11d13958c554d2d647c0910a6c6dbd4cca781bf2 Reviewed-by: Christian Stenger --- src/plugins/remotelinux/CMakeLists.txt | 1 + src/plugins/remotelinux/remotelinux.qbs | 2 + .../remotelinux/remotelinuxdeploysupport.cpp | 73 +++++++++++++++++++ .../remotelinux/remotelinuxdeploysupport.h | 10 +++ src/plugins/remotelinux/remotelinuxplugin.cpp | 66 +---------------- 5 files changed, 90 insertions(+), 62 deletions(-) create mode 100644 src/plugins/remotelinux/remotelinuxdeploysupport.cpp create mode 100644 src/plugins/remotelinux/remotelinuxdeploysupport.h diff --git a/src/plugins/remotelinux/CMakeLists.txt b/src/plugins/remotelinux/CMakeLists.txt index 188e3609ac5..50ffdff659f 100644 --- a/src/plugins/remotelinux/CMakeLists.txt +++ b/src/plugins/remotelinux/CMakeLists.txt @@ -19,6 +19,7 @@ add_qtc_plugin(RemoteLinux remotelinux_export.h remotelinuxcustomrunconfiguration.cpp remotelinuxcustomrunconfiguration.h remotelinuxdebugsupport.cpp remotelinuxdebugsupport.h + remotelinuxdeploysupport.cpp remotelinuxdeploysupport.h remotelinuxenvironmentaspect.cpp remotelinuxenvironmentaspect.h remotelinuxplugin.cpp remotelinuxplugin.h remotelinuxrunconfiguration.cpp remotelinuxrunconfiguration.h diff --git a/src/plugins/remotelinux/remotelinux.qbs b/src/plugins/remotelinux/remotelinux.qbs index 8eaab69e479..b292f981d85 100644 --- a/src/plugins/remotelinux/remotelinux.qbs +++ b/src/plugins/remotelinux/remotelinux.qbs @@ -40,6 +40,8 @@ QtcPlugin { "remotelinuxcustomrunconfiguration.h", "remotelinuxdebugsupport.cpp", "remotelinuxdebugsupport.h", + "remotelinuxdeploysupport.cpp", + "remotelinuxdeploysupport.h", "remotelinuxenvironmentaspect.cpp", "remotelinuxenvironmentaspect.h", "remotelinuxplugin.cpp", diff --git a/src/plugins/remotelinux/remotelinuxdeploysupport.cpp b/src/plugins/remotelinux/remotelinuxdeploysupport.cpp new file mode 100644 index 00000000000..c3a11b6f453 --- /dev/null +++ b/src/plugins/remotelinux/remotelinuxdeploysupport.cpp @@ -0,0 +1,73 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "remotelinuxdebugsupport.h" + +#include "genericdeploystep.h" +#include "genericdirectuploadstep.h" +#include "makeinstallstep.h" +#include "remotelinux_constants.h" +#include "remotelinuxtr.h" + +#include +#include +#include +#include + +#include + +using namespace ProjectExplorer; + +namespace RemoteLinux::Internal { + +template +class RemoteLinuxDeployStepFactory : public Factory +{ +public: + RemoteLinuxDeployStepFactory() + { + Factory::setSupportedConfiguration(RemoteLinux::Constants::DeployToGenericLinux); + Factory::setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); + } +}; + +class RemoteLinuxDeployConfigurationFactory : public DeployConfigurationFactory +{ +public: + RemoteLinuxDeployConfigurationFactory() + { + setConfigBaseId(RemoteLinux::Constants::DeployToGenericLinux); + addSupportedTargetDeviceType(RemoteLinux::Constants::GenericLinuxOsType); + setDefaultDisplayName(Tr::tr("Deploy to Remote Linux Host")); + setUseDeploymentDataView(); + + const auto needsMakeInstall = [](Target *target) + { + const Project * const prj = target->project(); + return prj->deploymentKnowledge() == DeploymentKnowledge::Bad + && prj->hasMakeInstallEquivalent(); + }; + setPostRestore([needsMakeInstall](DeployConfiguration *dc, const Utils::Store &map) { + // 4.9 -> 4.10. See QTCREATORBUG-22689. + if (map.value("_checkMakeInstall").toBool() && needsMakeInstall(dc->target())) { + dc->stepList()->insertStep(0, Constants::MakeInstallStepId); + } + }); + + addInitialStep(Constants::MakeInstallStepId, needsMakeInstall); + addInitialStep(Constants::KillAppStepId); + + // TODO: Rename RsyncDeployStep to something more generic. + addInitialStep(Constants::GenericDeployStepId); + } +}; + +void setupRemoteLinuxDeploySupport() +{ + static RemoteLinuxDeployConfigurationFactory deployConfigurationFactory; + static RemoteLinuxDeployStepFactory genericDirectUploadStep; + static RemoteLinuxDeployStepFactory rsyncDeployStepFactory; + static RemoteLinuxDeployStepFactory makeInstallStepFactory; +} + +} // RemoteLinux::Internal diff --git a/src/plugins/remotelinux/remotelinuxdeploysupport.h b/src/plugins/remotelinux/remotelinuxdeploysupport.h new file mode 100644 index 00000000000..4f777951af5 --- /dev/null +++ b/src/plugins/remotelinux/remotelinuxdeploysupport.h @@ -0,0 +1,10 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +namespace RemoteLinux::Internal { + +void setupRemoteLinuxDeploySupport(); + +} //RemoteLinux::Internal diff --git a/src/plugins/remotelinux/remotelinuxplugin.cpp b/src/plugins/remotelinux/remotelinuxplugin.cpp index 36a8b6aa098..bed919b5ee3 100644 --- a/src/plugins/remotelinux/remotelinuxplugin.cpp +++ b/src/plugins/remotelinux/remotelinuxplugin.cpp @@ -4,87 +4,29 @@ #include "remotelinuxplugin.h" #include "customcommanddeploystep.h" -#include "genericdeploystep.h" -#include "genericdirectuploadstep.h" #include "killappstep.h" #include "linuxdevice.h" -#include "makeinstallstep.h" #include "remotelinux_constants.h" #include "remotelinuxcustomrunconfiguration.h" #include "remotelinuxdebugsupport.h" +#include "remotelinuxdeploysupport.h" #include "remotelinuxrunconfiguration.h" #include "remotelinuxtr.h" #include "tarpackagecreationstep.h" #include "tarpackagedeploystep.h" +#include + #ifdef WITH_TESTS #include "filesystemaccess_test.h" #endif -#include -#include -#include -#include -#include - -#include - using namespace ProjectExplorer; using namespace Utils; namespace RemoteLinux { namespace Internal { -template -class RemoteLinuxDeployStepFactory : public Factory -{ -public: - RemoteLinuxDeployStepFactory() - { - Factory::setSupportedConfiguration(RemoteLinux::Constants::DeployToGenericLinux); - Factory::setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); - } -}; - -class RemoteLinuxDeployConfigurationFactory : public DeployConfigurationFactory -{ -public: - RemoteLinuxDeployConfigurationFactory() - { - setConfigBaseId(RemoteLinux::Constants::DeployToGenericLinux); - addSupportedTargetDeviceType(RemoteLinux::Constants::GenericLinuxOsType); - setDefaultDisplayName(Tr::tr("Deploy to Remote Linux Host")); - setUseDeploymentDataView(); - - const auto needsMakeInstall = [](Target *target) - { - const Project * const prj = target->project(); - return prj->deploymentKnowledge() == DeploymentKnowledge::Bad - && prj->hasMakeInstallEquivalent(); - }; - setPostRestore([needsMakeInstall](DeployConfiguration *dc, const Store &map) { - // 4.9 -> 4.10. See QTCREATORBUG-22689. - if (map.value("_checkMakeInstall").toBool() && needsMakeInstall(dc->target())) { - dc->stepList()->insertStep(0, Constants::MakeInstallStepId); - } - }); - - addInitialStep(Constants::MakeInstallStepId, needsMakeInstall); - addInitialStep(Constants::KillAppStepId); - - // TODO: Rename RsyncDeployStep to something more generic. - addInitialStep(Constants::GenericDeployStepId); - } -}; - -void setupRemoteLinuxDeployment() -{ - static RemoteLinuxDeployConfigurationFactory deployConfigurationFactory; - static RemoteLinuxDeployStepFactory genericDirectUploadStep; - static RemoteLinuxDeployStepFactory rsyncDeployStepFactory; - static RemoteLinuxDeployStepFactory makeInstallStepFactory; -} - RemoteLinuxPlugin::RemoteLinuxPlugin() { setObjectName(QLatin1String("RemoteLinuxPlugin")); @@ -102,7 +44,7 @@ void RemoteLinuxPlugin::initialize() setupRemoteLinuxRunConfiguration(); setupRemoteLinuxCustomRunConfiguration(); setupRemoteLinuxRunAndDebugSupport(); - setupRemoteLinuxDeployment(); + setupRemoteLinuxDeploySupport(); setupTarPackageCreationStep(); setupTarPackageDeployStep(); setupCustomCommandDeployStep(); From 70d3c5b20bcd4fa219ab31221e0fcf866ffc6699 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 15:25:36 +0100 Subject: [PATCH 0335/1546] RemoteLinux: Move plugin class definition to .cpp Change-Id: Iab0b0fc2d4d649486a3aa93594236e91d8144bb3 Reviewed-by: Christian Stenger --- src/plugins/remotelinux/CMakeLists.txt | 2 +- src/plugins/remotelinux/remotelinux.qbs | 1 - src/plugins/remotelinux/remotelinuxplugin.cpp | 62 ++++++++++--------- src/plugins/remotelinux/remotelinuxplugin.h | 25 -------- 4 files changed, 34 insertions(+), 56 deletions(-) delete mode 100644 src/plugins/remotelinux/remotelinuxplugin.h diff --git a/src/plugins/remotelinux/CMakeLists.txt b/src/plugins/remotelinux/CMakeLists.txt index 50ffdff659f..e19cc472dfd 100644 --- a/src/plugins/remotelinux/CMakeLists.txt +++ b/src/plugins/remotelinux/CMakeLists.txt @@ -21,7 +21,7 @@ add_qtc_plugin(RemoteLinux remotelinuxdebugsupport.cpp remotelinuxdebugsupport.h remotelinuxdeploysupport.cpp remotelinuxdeploysupport.h remotelinuxenvironmentaspect.cpp remotelinuxenvironmentaspect.h - remotelinuxplugin.cpp remotelinuxplugin.h + remotelinuxplugin.cpp remotelinuxrunconfiguration.cpp remotelinuxrunconfiguration.h remotelinuxsignaloperation.cpp remotelinuxsignaloperation.h remotelinuxtr.h diff --git a/src/plugins/remotelinux/remotelinux.qbs b/src/plugins/remotelinux/remotelinux.qbs index b292f981d85..07b2dd9b9c9 100644 --- a/src/plugins/remotelinux/remotelinux.qbs +++ b/src/plugins/remotelinux/remotelinux.qbs @@ -45,7 +45,6 @@ QtcPlugin { "remotelinuxenvironmentaspect.cpp", "remotelinuxenvironmentaspect.h", "remotelinuxplugin.cpp", - "remotelinuxplugin.h", "remotelinuxrunconfiguration.cpp", "remotelinuxrunconfiguration.h", "remotelinuxsignaloperation.cpp", diff --git a/src/plugins/remotelinux/remotelinuxplugin.cpp b/src/plugins/remotelinux/remotelinuxplugin.cpp index bed919b5ee3..e265a5491ca 100644 --- a/src/plugins/remotelinux/remotelinuxplugin.cpp +++ b/src/plugins/remotelinux/remotelinuxplugin.cpp @@ -1,8 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "remotelinuxplugin.h" - #include "customcommanddeploystep.h" #include "killappstep.h" #include "linuxdevice.h" @@ -11,49 +9,55 @@ #include "remotelinuxdebugsupport.h" #include "remotelinuxdeploysupport.h" #include "remotelinuxrunconfiguration.h" -#include "remotelinuxtr.h" #include "tarpackagecreationstep.h" #include "tarpackagedeploystep.h" +#include + #include #ifdef WITH_TESTS #include "filesystemaccess_test.h" #endif -using namespace ProjectExplorer; using namespace Utils; -namespace RemoteLinux { -namespace Internal { +namespace RemoteLinux::Internal { -RemoteLinuxPlugin::RemoteLinuxPlugin() +class RemoteLinuxPlugin final : public ExtensionSystem::IPlugin { - setObjectName(QLatin1String("RemoteLinuxPlugin")); - FSEngine::registerDeviceScheme(u"ssh"); -} + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "RemoteLinux.json") -RemoteLinuxPlugin::~RemoteLinuxPlugin() -{ - FSEngine::unregisterDeviceScheme(u"ssh"); -} +public: + RemoteLinuxPlugin() + { + FSEngine::registerDeviceScheme(u"ssh"); + } -void RemoteLinuxPlugin::initialize() -{ - setupLinuxDevice(); - setupRemoteLinuxRunConfiguration(); - setupRemoteLinuxCustomRunConfiguration(); - setupRemoteLinuxRunAndDebugSupport(); - setupRemoteLinuxDeploySupport(); - setupTarPackageCreationStep(); - setupTarPackageDeployStep(); - setupCustomCommandDeployStep(); - setupKillAppStep(); + ~RemoteLinuxPlugin() final + { + FSEngine::unregisterDeviceScheme(u"ssh"); + } + + void initialize() final + { + setupLinuxDevice(); + setupRemoteLinuxRunConfiguration(); + setupRemoteLinuxCustomRunConfiguration(); + setupRemoteLinuxRunAndDebugSupport(); + setupRemoteLinuxDeploySupport(); + setupTarPackageCreationStep(); + setupTarPackageDeployStep(); + setupCustomCommandDeployStep(); + setupKillAppStep(); #ifdef WITH_TESTS - addTest(); + addTest(); #endif -} + } +}; -} // namespace Internal -} // namespace RemoteLinux +} // RemoteLinux::Internal + +#include "remotelinuxplugin.moc" diff --git a/src/plugins/remotelinux/remotelinuxplugin.h b/src/plugins/remotelinux/remotelinuxplugin.h deleted file mode 100644 index ef75c1a3da2..00000000000 --- a/src/plugins/remotelinux/remotelinuxplugin.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace RemoteLinux { -namespace Internal { - -class RemoteLinuxPlugin final : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "RemoteLinux.json") - -public: - RemoteLinuxPlugin(); - ~RemoteLinuxPlugin() final; - -private: - void initialize() final; -}; - -} // namespace Internal -} // namespace RemoteLinux From eb08ae9145567845725b228095cf2125ac66dbe4 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Nov 2023 11:37:52 +0100 Subject: [PATCH 0336/1546] GenericProject: Dissolve plugin pimpl Not needed anymore. Change-Id: Ic14c4f2d5c8d34919665631272a4efd281899fc9 Reviewed-by: Christian Stenger --- .../genericprojectplugin.cpp | 82 +++++++------------ 1 file changed, 31 insertions(+), 51 deletions(-) diff --git a/src/plugins/genericprojectmanager/genericprojectplugin.cpp b/src/plugins/genericprojectmanager/genericprojectplugin.cpp index 05d392c70d2..2506391bf06 100644 --- a/src/plugins/genericprojectmanager/genericprojectplugin.cpp +++ b/src/plugins/genericprojectmanager/genericprojectplugin.cpp @@ -30,65 +30,45 @@ namespace PEC = ProjectExplorer::Constants; namespace GenericProjectManager::Internal { -class GenericProjectPluginPrivate : public QObject -{ -public: - GenericProjectPluginPrivate(); -}; - -GenericProjectPluginPrivate::GenericProjectPluginPrivate() -{ - ProjectManager::registerProjectType(Constants::GENERICMIMETYPE); - - setupGenericProjectWizard(); - setupGenericProjectFiles(); - setupGenericMakeStep(); - setupGenericBuildConfiguration(); - - ActionBuilder editAction(this, "GenericProjectManager.EditFiles"); - editAction.setContext(Constants::GENERICPROJECT_ID); - editAction.setText(Tr::tr("Edit Files...")); - editAction.setCommandAttribute(Command::CA_Hide); - editAction.setContainer(PEC::M_PROJECTCONTEXT, PEC::G_PROJECT_FILES); - editAction.setOnTriggered([] { - if (auto genericProject = qobject_cast(ProjectTree::currentProject())) - genericProject->editFilesTriggered(); - }); - - ActionBuilder removeDirAction(this, "GenericProject.RemoveDir"); - removeDirAction.setContext(PEC::C_PROJECT_TREE); - removeDirAction.setText(Tr::tr("Remove Directory")); - removeDirAction.setContainer(PEC::M_FOLDERCONTEXT, PEC::G_FOLDER_OTHER); - removeDirAction.setOnTriggered([] { - const auto folderNode = ProjectTree::currentNode()->asFolderNode(); - QTC_ASSERT(folderNode, return); - const auto project = qobject_cast(folderNode->getProject()); - QTC_ASSERT(project, return); - const FilePaths filesToRemove = transform( - folderNode->findNodes([](const Node *node) { return node->asFileNode(); }), - [](const Node *node) { return node->filePath();}); - project->removeFilesTriggered(filesToRemove); - }); -} - class GenericProjectPlugin final : public ExtensionSystem::IPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "GenericProjectManager.json") -public: - ~GenericProjectPlugin() final - { - delete d; - } - -private: void initialize() final { - d = new GenericProjectPluginPrivate; - } + ProjectManager::registerProjectType(Constants::GENERICMIMETYPE); - GenericProjectPluginPrivate *d = nullptr; + setupGenericProjectWizard(); + setupGenericProjectFiles(); + setupGenericMakeStep(); + setupGenericBuildConfiguration(); + + ActionBuilder editAction(this, "GenericProjectManager.EditFiles"); + editAction.setContext(Constants::GENERICPROJECT_ID); + editAction.setText(Tr::tr("Edit Files...")); + editAction.setCommandAttribute(Command::CA_Hide); + editAction.setContainer(PEC::M_PROJECTCONTEXT, PEC::G_PROJECT_FILES); + editAction.setOnTriggered([] { + if (auto genericProject = qobject_cast(ProjectTree::currentProject())) + genericProject->editFilesTriggered(); + }); + + ActionBuilder removeDirAction(this, "GenericProject.RemoveDir"); + removeDirAction.setContext(PEC::C_PROJECT_TREE); + removeDirAction.setText(Tr::tr("Remove Directory")); + removeDirAction.setContainer(PEC::M_FOLDERCONTEXT, PEC::G_FOLDER_OTHER); + removeDirAction.setOnTriggered([] { + const auto folderNode = ProjectTree::currentNode()->asFolderNode(); + QTC_ASSERT(folderNode, return); + const auto project = qobject_cast(folderNode->getProject()); + QTC_ASSERT(project, return); + const FilePaths filesToRemove = transform( + folderNode->findNodes([](const Node *node) { return node->asFileNode(); }), + [](const Node *node) { return node->filePath();}); + project->removeFilesTriggered(filesToRemove); + }); + } }; } // GenericProjectManager::Internal From 36d00b8a55f65c6e762311a141529bd251db0382 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Wed, 22 Nov 2023 08:22:31 +0100 Subject: [PATCH 0337/1546] FakeVim: Test build without tests Undefined symbols: FakeVim::Internal::createFakeVimTester Change-Id: I2acaeaeb6a3be84ecc95415cd6f20296c4913786 Reviewed-by: hjk --- src/plugins/fakevim/fakevimplugin.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/fakevim/fakevimplugin.cpp b/src/plugins/fakevim/fakevimplugin.cpp index a46aa2b2555..edd1b9e89e5 100644 --- a/src/plugins/fakevim/fakevimplugin.cpp +++ b/src/plugins/fakevim/fakevimplugin.cpp @@ -1040,13 +1040,17 @@ static void setupTest(QString *title, FakeVimHandler **handler, QWidget **edit) (*handler)->handleCommand("set iskeyword=@,48-57,_,192-255,a-z,A-Z"); } +#ifdef WITH_TESTS QObject *createFakeVimTester( void (*setupTest)(QString *, FakeVimHandler **, QWidget **) ); // in fakevim_test.cpp +#endif FakeVimPlugin::FakeVimPlugin() { dd = this; +#ifdef WITH_TESTS addTestCreator([] { return createFakeVimTester(&setupTest); }); +#endif m_defaultExCommandMap[CppEditor::Constants::SWITCH_HEADER_SOURCE] = QRegularExpression("^A$"); From db301c1bceccc9931b00abc656e75be1b85d76ee Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 17:36:30 +0100 Subject: [PATCH 0338/1546] ScxmlEditor: Use new setup for ScxmlEditorFactory Change-Id: Iabb25fb8b6cf774631eb5b910532b892321e3cea Reviewed-by: Jarek Kobus --- .../scxmleditor/scxmleditorfactory.cpp | 54 ++++++++++++------- src/plugins/scxmleditor/scxmleditorfactory.h | 20 ++----- src/plugins/scxmleditor/scxmleditorplugin.cpp | 8 +-- 3 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/plugins/scxmleditor/scxmleditorfactory.cpp b/src/plugins/scxmleditor/scxmleditorfactory.cpp index 9ef8e7250af..5a6f61c9773 100644 --- a/src/plugins/scxmleditor/scxmleditorfactory.cpp +++ b/src/plugins/scxmleditor/scxmleditorfactory.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -15,28 +16,43 @@ #include using namespace ScxmlEditor::Constants; -using namespace ScxmlEditor::Internal; -ScxmlEditorFactory::ScxmlEditorFactory() +namespace ScxmlEditor::Internal { + +class ScxmlEditorFactory final : public QObject, public Core::IEditorFactory { - setId(K_SCXML_EDITOR_ID); - setDisplayName(::Core::Tr::tr(C_SCXMLEDITOR_DISPLAY_NAME)); - addMimeType(Utils::Constants::SCXML_MIMETYPE); +public: + ScxmlEditorFactory(QObject *guard) + : QObject(guard) + { + setId(K_SCXML_EDITOR_ID); + setDisplayName(::Core::Tr::tr(C_SCXMLEDITOR_DISPLAY_NAME)); + addMimeType(Utils::Constants::SCXML_MIMETYPE); - Utils::FileIconProvider::registerIconOverlayForSuffix(":/projectexplorer/images/fileoverlay_scxml.png", "scxml"); + Utils::FileIconProvider::registerIconOverlayForSuffix(":/projectexplorer/images/fileoverlay_scxml.png", "scxml"); - setEditorCreator([this] { - if (!m_editorData) { - m_editorData = new ScxmlEditorData; - QGuiApplication::setOverrideCursor(Qt::WaitCursor); - m_editorData->fullInit(); - QGuiApplication::restoreOverrideCursor(); - } - return m_editorData->createEditor(); - }); + setEditorCreator([this] { + if (!m_editorData) { + m_editorData = new ScxmlEditorData; + QGuiApplication::setOverrideCursor(Qt::WaitCursor); + m_editorData->fullInit(); + QGuiApplication::restoreOverrideCursor(); + } + return m_editorData->createEditor(); + }); + } + ~ScxmlEditorFactory() + { + delete m_editorData; + } + +private: + ScxmlEditorData *m_editorData = nullptr; +}; + +void setupScxmlEditor(QObject *guard) +{ + (void) new ScxmlEditorFactory(guard); } -ScxmlEditorFactory::~ScxmlEditorFactory() -{ - delete m_editorData; -} +} // ScxmlEditorFactory diff --git a/src/plugins/scxmleditor/scxmleditorfactory.h b/src/plugins/scxmleditor/scxmleditorfactory.h index 4074281b8a0..98b1090ccd5 100644 --- a/src/plugins/scxmleditor/scxmleditorfactory.h +++ b/src/plugins/scxmleditor/scxmleditorfactory.h @@ -3,22 +3,10 @@ #pragma once -#include +#include -namespace ScxmlEditor { -namespace Internal { +namespace ScxmlEditor::Internal { -class ScxmlEditorData; +void setupScxmlEditor(QObject *guard); -class ScxmlEditorFactory final : public Core::IEditorFactory -{ -public: - ScxmlEditorFactory(); - ~ScxmlEditorFactory(); - -private: - ScxmlEditorData* m_editorData = nullptr; -}; - -} // namespace Internal -} // namespace ScxmlEditor +} // ScxmlEditor::Internal diff --git a/src/plugins/scxmleditor/scxmleditorplugin.cpp b/src/plugins/scxmleditor/scxmleditorplugin.cpp index 47d76a8c089..743664790bb 100644 --- a/src/plugins/scxmleditor/scxmleditorplugin.cpp +++ b/src/plugins/scxmleditor/scxmleditorplugin.cpp @@ -7,11 +7,9 @@ #include -#include - namespace ScxmlEditor::Internal { -class ScxmlEditorPlugin : public ExtensionSystem::IPlugin +class ScxmlEditorPlugin final : public ExtensionSystem::IPlugin { Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "ScxmlEditor.json") @@ -19,15 +17,13 @@ class ScxmlEditorPlugin : public ExtensionSystem::IPlugin private: void initialize() final { - editorFactory = std::make_unique(); + setupScxmlEditor(this); } void extensionsInitialized() final { Core::DesignMode::setDesignModeIsRequired(); } - - std::unique_ptr editorFactory; }; } // ScxmlEditor::Internal From 69b96ff7d2f19227970919d5af11c1483c420c7a Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 17:45:49 +0100 Subject: [PATCH 0339/1546] ScxmlEditor: Merge editor factory and data files Currently scxmleditordata.cpp and scxmleditorfactory.h are used to keep the diff small, these will be renamed immediately. Change-Id: I4d4878b7eb2f52fb5f326bde33badd7e31305336 Reviewed-by: Jarek Kobus --- src/plugins/scxmleditor/CMakeLists.txt | 4 +- src/plugins/scxmleditor/scxmleditor.qbs | 4 +- src/plugins/scxmleditor/scxmleditordata.cpp | 79 +++++++++++++++++-- src/plugins/scxmleditor/scxmleditordata.h | 50 ------------ .../scxmleditor/scxmleditorfactory.cpp | 58 -------------- 5 files changed, 77 insertions(+), 118 deletions(-) delete mode 100644 src/plugins/scxmleditor/scxmleditordata.h delete mode 100644 src/plugins/scxmleditor/scxmleditorfactory.cpp diff --git a/src/plugins/scxmleditor/CMakeLists.txt b/src/plugins/scxmleditor/CMakeLists.txt index 396a03820e3..4aa4fbad45b 100644 --- a/src/plugins/scxmleditor/CMakeLists.txt +++ b/src/plugins/scxmleditor/CMakeLists.txt @@ -86,9 +86,9 @@ add_qtc_plugin(ScxmlEditor scxmleditor_global.h scxmleditortr.h scxmleditorconstants.h - scxmleditordata.cpp scxmleditordata.h + scxmleditordata.cpp scxmleditordocument.cpp scxmleditordocument.h - scxmleditorfactory.cpp scxmleditorfactory.h + scxmleditorfactory.h scxmleditorplugin.cpp scxmleditorstack.cpp scxmleditorstack.h scxmltexteditor.cpp scxmltexteditor.h diff --git a/src/plugins/scxmleditor/scxmleditor.qbs b/src/plugins/scxmleditor/scxmleditor.qbs index 3f8bbad3d03..ae8c69f0d5b 100644 --- a/src/plugins/scxmleditor/scxmleditor.qbs +++ b/src/plugins/scxmleditor/scxmleditor.qbs @@ -21,9 +21,9 @@ QtcPlugin { files: [ "scxmleditor_global.h", "scxmleditortr.h", "scxmleditorconstants.h", - "scxmleditordata.cpp", "scxmleditordata.h", + "scxmleditordata.cpp", "scxmleditordocument.cpp", "scxmleditordocument.h", - "scxmleditorfactory.cpp", "scxmleditorfactory.h", + "scxmleditorfactory.h", "scxmleditorplugin.cpp", "scxmleditorstack.cpp", "scxmleditorstack.h", "scxmltexteditor.cpp", "scxmltexteditor.h", diff --git a/src/plugins/scxmleditor/scxmleditordata.cpp b/src/plugins/scxmleditor/scxmleditordata.cpp index 6aa5b181d72..f28965ff28a 100644 --- a/src/plugins/scxmleditor/scxmleditordata.cpp +++ b/src/plugins/scxmleditor/scxmleditordata.cpp @@ -3,7 +3,6 @@ #include "mainwidget.h" #include "scxmleditorconstants.h" -#include "scxmleditordata.h" #include "scxmleditordocument.h" #include "scxmleditorstack.h" #include "scxmleditortr.h" @@ -11,8 +10,12 @@ #include #include +#include #include #include +#include +#include +#include #include #include #include @@ -21,21 +24,24 @@ #include +#include #include #include #include #include #include +#include #include +#include +#include +using namespace Core; using namespace ScxmlEditor::Common; using namespace ScxmlEditor::PluginInterface; using namespace Utils; -namespace ScxmlEditor { - -namespace Internal { +namespace ScxmlEditor::Internal { class ScxmlTextEditorWidget : public TextEditor::TextEditorWidget { @@ -67,6 +73,32 @@ public: } }; +class ScxmlEditorData : public QObject +{ +public: + ScxmlEditorData(); + ~ScxmlEditorData() override; + + void fullInit(); + IEditor *createEditor(); + +private: + void updateToolBar(); + QWidget *createModeWidget(); + EditorToolBar *createMainToolBar(); + + Context m_contexts; + QWidget *m_modeWidget = nullptr; + ScxmlEditorStack *m_widgetStack = nullptr; + QToolBar *m_widgetToolBar = nullptr; + EditorToolBar *m_mainToolBar = nullptr; + QUndoGroup *m_undoGroup = nullptr; + QAction *m_undoAction = nullptr; + QAction *m_redoAction = nullptr; + + ScxmlTextEditorFactory *m_xmlEditorFactory = nullptr; +}; + ScxmlEditorData::ScxmlEditorData() { m_contexts.add(ScxmlEditor::Constants::C_SCXMLEDITOR); @@ -218,5 +250,40 @@ QWidget *ScxmlEditorData::createModeWidget() return widget; } -} // namespace Internal -} // namespace ScxmlEditor +class ScxmlEditorFactory final : public QObject, public Core::IEditorFactory +{ +public: + ScxmlEditorFactory(QObject *guard) + : QObject(guard) + { + setId(Constants::K_SCXML_EDITOR_ID); + setDisplayName(::Core::Tr::tr(Constants::C_SCXMLEDITOR_DISPLAY_NAME)); + addMimeType(Utils::Constants::SCXML_MIMETYPE); + + Utils::FileIconProvider::registerIconOverlayForSuffix(":/projectexplorer/images/fileoverlay_scxml.png", "scxml"); + + setEditorCreator([this] { + if (!m_editorData) { + m_editorData = new ScxmlEditorData; + QGuiApplication::setOverrideCursor(Qt::WaitCursor); + m_editorData->fullInit(); + QGuiApplication::restoreOverrideCursor(); + } + return m_editorData->createEditor(); + }); + } + ~ScxmlEditorFactory() + { + delete m_editorData; + } + +private: + ScxmlEditorData *m_editorData = nullptr; +}; + +void setupScxmlEditor(QObject *guard) +{ + (void) new ScxmlEditorFactory(guard); +} + +} // ScxmlEditor::Internal diff --git a/src/plugins/scxmleditor/scxmleditordata.h b/src/plugins/scxmleditor/scxmleditordata.h deleted file mode 100644 index b7f1412361b..00000000000 --- a/src/plugins/scxmleditor/scxmleditordata.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include -#include - -#include -#include -#include - -using namespace Core; - -namespace ScxmlEditor { -namespace Internal { - -class ScxmlTextEditorFactory; -class ScxmlEditorWidget; -class ScxmlEditorStack; - -class ScxmlEditorData : public QObject -{ - Q_OBJECT -public: - ScxmlEditorData(); - ~ScxmlEditorData() override; - - void fullInit(); - IEditor *createEditor(); - -private: - void updateToolBar(); - QWidget *createModeWidget(); - EditorToolBar *createMainToolBar(); - - Context m_contexts; - QWidget *m_modeWidget = nullptr; - ScxmlEditorStack *m_widgetStack = nullptr; - QToolBar *m_widgetToolBar = nullptr; - EditorToolBar *m_mainToolBar = nullptr; - QUndoGroup *m_undoGroup = nullptr; - QAction *m_undoAction = nullptr; - QAction *m_redoAction = nullptr; - - ScxmlTextEditorFactory *m_xmlEditorFactory = nullptr; -}; - -} // namespace Internal -} // namespace ScxmlEditor diff --git a/src/plugins/scxmleditor/scxmleditorfactory.cpp b/src/plugins/scxmleditor/scxmleditorfactory.cpp deleted file mode 100644 index 5a6f61c9773..00000000000 --- a/src/plugins/scxmleditor/scxmleditorfactory.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "scxmleditorfactory.h" - -#include "scxmleditorconstants.h" -#include "scxmleditordata.h" - -#include -#include -#include - -#include -#include - -#include - -using namespace ScxmlEditor::Constants; - -namespace ScxmlEditor::Internal { - -class ScxmlEditorFactory final : public QObject, public Core::IEditorFactory -{ -public: - ScxmlEditorFactory(QObject *guard) - : QObject(guard) - { - setId(K_SCXML_EDITOR_ID); - setDisplayName(::Core::Tr::tr(C_SCXMLEDITOR_DISPLAY_NAME)); - addMimeType(Utils::Constants::SCXML_MIMETYPE); - - Utils::FileIconProvider::registerIconOverlayForSuffix(":/projectexplorer/images/fileoverlay_scxml.png", "scxml"); - - setEditorCreator([this] { - if (!m_editorData) { - m_editorData = new ScxmlEditorData; - QGuiApplication::setOverrideCursor(Qt::WaitCursor); - m_editorData->fullInit(); - QGuiApplication::restoreOverrideCursor(); - } - return m_editorData->createEditor(); - }); - } - ~ScxmlEditorFactory() - { - delete m_editorData; - } - -private: - ScxmlEditorData *m_editorData = nullptr; -}; - -void setupScxmlEditor(QObject *guard) -{ - (void) new ScxmlEditorFactory(guard); -} - -} // ScxmlEditorFactory From 27084b18846e1bd1401d10f5827d431b8129ab3d Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 17 Nov 2023 18:06:55 +0100 Subject: [PATCH 0340/1546] ScxmlEditor: Rename scxmleditorfactory.h and scxmleditordata.cpp ... to scxmleditor.h and scxmleditor.cpp so it looks like a normal file pair again. Change-Id: I5be9d78cf39cba2a04525aca79e36b8283f08870 Reviewed-by: Reviewed-by: Jarek Kobus --- src/plugins/scxmleditor/CMakeLists.txt | 3 +-- .../scxmleditor/{scxmleditordata.cpp => scxmleditor.cpp} | 0 .../scxmleditor/{scxmleditorfactory.h => scxmleditor.h} | 0 src/plugins/scxmleditor/scxmleditor.qbs | 3 +-- src/plugins/scxmleditor/scxmleditorplugin.cpp | 2 +- 5 files changed, 3 insertions(+), 5 deletions(-) rename src/plugins/scxmleditor/{scxmleditordata.cpp => scxmleditor.cpp} (100%) rename src/plugins/scxmleditor/{scxmleditorfactory.h => scxmleditor.h} (100%) diff --git a/src/plugins/scxmleditor/CMakeLists.txt b/src/plugins/scxmleditor/CMakeLists.txt index 4aa4fbad45b..85a1c7fc706 100644 --- a/src/plugins/scxmleditor/CMakeLists.txt +++ b/src/plugins/scxmleditor/CMakeLists.txt @@ -86,9 +86,8 @@ add_qtc_plugin(ScxmlEditor scxmleditor_global.h scxmleditortr.h scxmleditorconstants.h - scxmleditordata.cpp + scxmleditor.cpp scxmleditor.h scxmleditordocument.cpp scxmleditordocument.h - scxmleditorfactory.h scxmleditorplugin.cpp scxmleditorstack.cpp scxmleditorstack.h scxmltexteditor.cpp scxmltexteditor.h diff --git a/src/plugins/scxmleditor/scxmleditordata.cpp b/src/plugins/scxmleditor/scxmleditor.cpp similarity index 100% rename from src/plugins/scxmleditor/scxmleditordata.cpp rename to src/plugins/scxmleditor/scxmleditor.cpp diff --git a/src/plugins/scxmleditor/scxmleditorfactory.h b/src/plugins/scxmleditor/scxmleditor.h similarity index 100% rename from src/plugins/scxmleditor/scxmleditorfactory.h rename to src/plugins/scxmleditor/scxmleditor.h diff --git a/src/plugins/scxmleditor/scxmleditor.qbs b/src/plugins/scxmleditor/scxmleditor.qbs index ae8c69f0d5b..b583163579d 100644 --- a/src/plugins/scxmleditor/scxmleditor.qbs +++ b/src/plugins/scxmleditor/scxmleditor.qbs @@ -21,9 +21,8 @@ QtcPlugin { files: [ "scxmleditor_global.h", "scxmleditortr.h", "scxmleditorconstants.h", - "scxmleditordata.cpp", + "scxmleditor.cpp", "scxmleditor.h", "scxmleditordocument.cpp", "scxmleditordocument.h", - "scxmleditorfactory.h", "scxmleditorplugin.cpp", "scxmleditorstack.cpp", "scxmleditorstack.h", "scxmltexteditor.cpp", "scxmltexteditor.h", diff --git a/src/plugins/scxmleditor/scxmleditorplugin.cpp b/src/plugins/scxmleditor/scxmleditorplugin.cpp index 743664790bb..f8a197b124d 100644 --- a/src/plugins/scxmleditor/scxmleditorplugin.cpp +++ b/src/plugins/scxmleditor/scxmleditorplugin.cpp @@ -1,7 +1,7 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "scxmleditorfactory.h" +#include "scxmleditor.h" #include From db71c461de278b7d03dcd0f4fd90185534308630 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 17 Nov 2023 13:40:59 +0100 Subject: [PATCH 0341/1546] TextEditor: Remove unneeded RefactoringFile::setFilePath() Change-Id: Ia44642191259b83539c093d04921317b6155fdee Reviewed-by: David Schulz Reviewed-by: Qt CI Bot --- src/plugins/qmljstools/qmljsrefactoringchanges.cpp | 2 -- src/plugins/texteditor/refactoringchanges.h | 1 - 2 files changed, 3 deletions(-) diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp index 66ce4102b43..ddc2ca25c83 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp @@ -68,8 +68,6 @@ QmlJSRefactoringFile::QmlJSRefactoringFile(TextEditor::TextEditorWidget *editor, : RefactoringFile(editor) , m_qmljsDocument(document) { - if (document) - setFilePath(document->fileName()); // TODO: Is this really a different file path than in the editor? } Document::Ptr QmlJSRefactoringFile::qmljsDocument() const diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h index 20de8dad87c..5155f162fd6 100644 --- a/src/plugins/texteditor/refactoringchanges.h +++ b/src/plugins/texteditor/refactoringchanges.h @@ -70,7 +70,6 @@ protected: RefactoringFile(const Utils::FilePath &filePath); void invalidate() { m_filePath.clear(); } - void setFilePath(const Utils::FilePath &filePath) { m_filePath = filePath; } // FIXME: Really necessary? void enableFormatting() { m_formattingEnabled = true; } private: From 209c386e6026feac25c710baf0ad29b82ee5c5d2 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Nov 2023 10:23:21 +0100 Subject: [PATCH 0342/1546] QmlProfiler: Dissolve plugin pimpl ... by using the new setup for QmlProfilerTool. Also, move the class definition to the .cpp. Change-Id: I3bc93f4960823914da9820fb2cb18de44f1c60c2 Reviewed-by: Jarek Kobus --- src/plugins/qmlprofiler/CMakeLists.txt | 2 +- src/plugins/qmlprofiler/qmlprofiler.qbs | 2 +- src/plugins/qmlprofiler/qmlprofilerplugin.cpp | 90 +++++++++---------- src/plugins/qmlprofiler/qmlprofilerplugin.h | 23 ----- src/plugins/qmlprofiler/qmlprofilertool.cpp | 19 ++-- src/plugins/qmlprofiler/qmlprofilertool.h | 3 + .../qmlprofiler/qmlprofilertraceview.cpp | 1 - 7 files changed, 62 insertions(+), 78 deletions(-) delete mode 100644 src/plugins/qmlprofiler/qmlprofilerplugin.h diff --git a/src/plugins/qmlprofiler/CMakeLists.txt b/src/plugins/qmlprofiler/CMakeLists.txt index a94dfce931a..9ef4fa63c56 100644 --- a/src/plugins/qmlprofiler/CMakeLists.txt +++ b/src/plugins/qmlprofiler/CMakeLists.txt @@ -49,7 +49,7 @@ set(QMLPROFILER_CPP_SOURCES qmlprofilereventtypes.h qmlprofilermodelmanager.cpp qmlprofilermodelmanager.h qmlprofilernotesmodel.cpp qmlprofilernotesmodel.h - qmlprofilerplugin.cpp qmlprofilerplugin.h + qmlprofilerplugin.cpp qmlprofilerrangemodel.cpp qmlprofilerrangemodel.h qmlprofilerrunconfigurationaspect.cpp qmlprofilerrunconfigurationaspect.h qmlprofilerruncontrol.cpp qmlprofilerruncontrol.h diff --git a/src/plugins/qmlprofiler/qmlprofiler.qbs b/src/plugins/qmlprofiler/qmlprofiler.qbs index 4ed25d1bca0..03bdd8fd8ed 100644 --- a/src/plugins/qmlprofiler/qmlprofiler.qbs +++ b/src/plugins/qmlprofiler/qmlprofiler.qbs @@ -40,7 +40,7 @@ QtcPlugin { "qmlprofilereventtypes.h", "qmlprofilermodelmanager.cpp", "qmlprofilermodelmanager.h", "qmlprofilernotesmodel.cpp", "qmlprofilernotesmodel.h", - "qmlprofilerplugin.cpp", "qmlprofilerplugin.h", + "qmlprofilerplugin.cpp", "qmlprofilerrunconfigurationaspect.cpp", "qmlprofilerrunconfigurationaspect.h", "qmlprofilerrangemodel.cpp", "qmlprofilerrangemodel.h", "qmlprofilerruncontrol.cpp", "qmlprofilerruncontrol.h", diff --git a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp index e55ae38d764..17006579fa2 100644 --- a/src/plugins/qmlprofiler/qmlprofilerplugin.cpp +++ b/src/plugins/qmlprofiler/qmlprofilerplugin.cpp @@ -1,7 +1,6 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "qmlprofilerplugin.h" #include "qmlprofilerrunconfigurationaspect.h" #include "qmlprofilerruncontrol.h" #include "qmlprofilersettings.h" @@ -48,65 +47,64 @@ #include #include +#include + using namespace ProjectExplorer; namespace QmlProfiler::Internal { -class QmlProfilerPluginPrivate +class QmlProfilerPlugin final : public ExtensionSystem::IPlugin { -public: - QmlProfilerTool m_profilerTool; -}; + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "QmlProfiler.json") -bool QmlProfilerPlugin::initialize(const QStringList &arguments, QString *errorString) -{ - Q_UNUSED(arguments) + bool initialize(const QStringList &arguments, QString *errorString) final + { + Q_UNUSED(arguments) - setupQmlProfilerRunning(); + setupQmlProfilerTool(); + setupQmlProfilerRunning(); #ifdef WITH_TESTS - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); + addTest(); + addTest(); + addTest(); + addTest(); + addTest(); + addTest(); + addTest(); + addTest(); + addTest(); + addTest(); + addTest(); + addTest(); + addTest(); + addTest(); + addTest(); + addTest(); + addTest(); + addTest(); + addTest(); - addTest(); // Trigger debug connector to be started + addTest(); // Trigger debug connector to be started #endif - return Utils::HostOsInfo::canCreateOpenGLContext(errorString); -} + return Utils::HostOsInfo::canCreateOpenGLContext(errorString); + } -void QmlProfilerPlugin::extensionsInitialized() -{ - d = new QmlProfilerPluginPrivate; + void extensionsInitialized() final + { + RunConfiguration::registerAspect(); + } - RunConfiguration::registerAspect(); -} + ShutdownFlag aboutToShutdown() final + { + destroyQmlProfilerTool(); -ExtensionSystem::IPlugin::ShutdownFlag QmlProfilerPlugin::aboutToShutdown() -{ - delete d; - d = nullptr; - - // Save settings. - // Disconnect from signals that are not needed during shutdown - // Hide UI (if you add UI that is not in the main window directly) - return SynchronousShutdown; -} + return SynchronousShutdown; + } +}; } // QmlProfiler::Internal + +#include "qmlprofilerplugin.moc" diff --git a/src/plugins/qmlprofiler/qmlprofilerplugin.h b/src/plugins/qmlprofiler/qmlprofilerplugin.h deleted file mode 100644 index d04f016a877..00000000000 --- a/src/plugins/qmlprofiler/qmlprofilerplugin.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2016 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace QmlProfiler::Internal { - -class QmlProfilerPlugin : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "QmlProfiler.json") - -private: - bool initialize(const QStringList &arguments, QString *errorString) final; - void extensionsInitialized() final; - ShutdownFlag aboutToShutdown() final; - - class QmlProfilerPluginPrivate *d = nullptr; -}; - -} // QmlProfiler::Internal diff --git a/src/plugins/qmlprofiler/qmlprofilertool.cpp b/src/plugins/qmlprofiler/qmlprofilertool.cpp index ea02239a64e..14369b6500d 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertool.cpp @@ -7,7 +7,6 @@ #include "qmlprofilerclientmanager.h" #include "qmlprofilerconstants.h" #include "qmlprofilermodelmanager.h" -#include "qmlprofilerplugin.h" #include "qmlprofilerrunconfigurationaspect.h" #include "qmlprofilerruncontrol.h" #include "qmlprofilersettings.h" @@ -75,8 +74,7 @@ using namespace QmlProfiler::Constants; using namespace ProjectExplorer; using namespace Utils; -namespace QmlProfiler { -namespace Internal { +namespace QmlProfiler::Internal { static QmlProfilerTool *m_instance = nullptr; @@ -919,8 +917,17 @@ void QmlProfilerTool::toggleVisibleFeature(QAction *action) d->m_profilerModelManager->visibleFeatures() | (1ULL << feature)); else d->m_profilerModelManager->setVisibleFeatures( - d->m_profilerModelManager->visibleFeatures() & (~(1ULL << feature))); + d->m_profilerModelManager->visibleFeatures() & (~(1ULL << feature))); } -} // namespace Internal -} // namespace QmlProfiler +void setupQmlProfilerTool() +{ + (void) new QmlProfilerTool; +} + +void destroyQmlProfilerTool() +{ + delete m_instance; +} + +} // QmlProfiler::Internal diff --git a/src/plugins/qmlprofiler/qmlprofilertool.h b/src/plugins/qmlprofiler/qmlprofilertool.h index 9db0691f1af..65bdc228c73 100644 --- a/src/plugins/qmlprofiler/qmlprofilertool.h +++ b/src/plugins/qmlprofiler/qmlprofilertool.h @@ -89,5 +89,8 @@ private: QmlProfilerToolPrivate *d; }; +void setupQmlProfilerTool(); +void destroyQmlProfilerTool(); + } // namespace Internal } // namespace QmlProfiler diff --git a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp index d07b731815a..290dc00dd81 100644 --- a/src/plugins/qmlprofiler/qmlprofilertraceview.cpp +++ b/src/plugins/qmlprofiler/qmlprofilertraceview.cpp @@ -4,7 +4,6 @@ #include "qmlprofileranimationsmodel.h" #include "qmlprofilermodelmanager.h" #include "qmlprofilernotesmodel.h" -#include "qmlprofilerplugin.h" #include "qmlprofilerrangemodel.h" #include "qmlprofilerstatemanager.h" #include "qmlprofilertool.h" From c11e1002b9c62b9a29dabd96b53e68d567332d67 Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Nov 2023 18:20:03 +0100 Subject: [PATCH 0343/1546] PerfProfiler: Use new setup for PerfProfilerTool and the plugin itself Change-Id: I6f732c631b7ad5edeb34961ff90d9db40fbd49c4 Reviewed-by: Jarek Kobus --- src/plugins/perfprofiler/CMakeLists.txt | 2 +- src/plugins/perfprofiler/perfprofiler.qbs | 1 - .../perfprofiler/perfprofilerplugin.cpp | 44 +++++++++---------- src/plugins/perfprofiler/perfprofilerplugin.h | 23 ---------- src/plugins/perfprofiler/perfprofilertool.cpp | 16 +++++-- src/plugins/perfprofiler/perfprofilertool.h | 3 ++ .../perfprofiler/perfprofilertracefile.cpp | 1 - .../perfrunconfigurationaspect.cpp | 1 - 8 files changed, 37 insertions(+), 54 deletions(-) delete mode 100644 src/plugins/perfprofiler/perfprofilerplugin.h diff --git a/src/plugins/perfprofiler/CMakeLists.txt b/src/plugins/perfprofiler/CMakeLists.txt index 360ee8a7ee9..0c4d6042043 100644 --- a/src/plugins/perfprofiler/CMakeLists.txt +++ b/src/plugins/perfprofiler/CMakeLists.txt @@ -18,7 +18,7 @@ set(PERFPROFILER_CPP_SOURCES perfprofilerconstants.h perfprofilerflamegraphmodel.cpp perfprofilerflamegraphmodel.h perfprofilerflamegraphview.cpp perfprofilerflamegraphview.h - perfprofilerplugin.cpp perfprofilerplugin.h + perfprofilerplugin.cpp perfprofilerruncontrol.cpp perfprofilerruncontrol.h perfprofilerstatisticsmodel.cpp perfprofilerstatisticsmodel.h perfprofilerstatisticsview.cpp perfprofilerstatisticsview.h diff --git a/src/plugins/perfprofiler/perfprofiler.qbs b/src/plugins/perfprofiler/perfprofiler.qbs index 93235770250..fe97d521f93 100644 --- a/src/plugins/perfprofiler/perfprofiler.qbs +++ b/src/plugins/perfprofiler/perfprofiler.qbs @@ -27,7 +27,6 @@ QtcPlugin { "perfprofiler_global.h", "perfprofilertr.h", "perfprofilerconstants.h", "perfprofilerplugin.cpp", - "perfprofilerplugin.h", "perfprofilertracemanager.cpp", "perfprofilertracemanager.h", "perftimelinemodel.cpp", diff --git a/src/plugins/perfprofiler/perfprofilerplugin.cpp b/src/plugins/perfprofiler/perfprofilerplugin.cpp index 1043d5026bd..93568849496 100644 --- a/src/plugins/perfprofiler/perfprofilerplugin.cpp +++ b/src/plugins/perfprofiler/perfprofilerplugin.cpp @@ -1,8 +1,6 @@ // Copyright (C) 2018 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "perfprofilerplugin.h" - #include "perfprofilerruncontrol.h" #include "perfprofilertool.h" #include "perfrunconfigurationaspect.h" @@ -12,37 +10,37 @@ # include "tests/perfresourcecounter_test.h" #endif // WITH_TESTS +#include using namespace ProjectExplorer; namespace PerfProfiler::Internal { -class PerfProfilerPluginPrivate +class PerfProfilerPlugin final : public ExtensionSystem::IPlugin { -public: - PerfProfilerPluginPrivate() + Q_OBJECT + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "PerfProfiler.json") + + void initialize() final { + setupPerfProfilerTool(); + setupPerfProfilerRunWorker(); RunConfiguration::registerAspect(); - } - - PerfProfilerTool profilerTool; -}; - -PerfProfilerPlugin::~PerfProfilerPlugin() -{ - delete d; -} - -void PerfProfilerPlugin::initialize() -{ - setupPerfProfilerRunWorker(); - - d = new PerfProfilerPluginPrivate; #if WITH_TESTS -// addTest(); // FIXME these tests have to get rewritten - addTest(); + // addTest(); // FIXME these tests have to get rewritten + addTest(); #endif // WITH_TESTS -} + } + + ShutdownFlag aboutToShutdown() final + { + destroyPerfProfilerTool(); + + return SynchronousShutdown; + } +}; } // PerfProfiler::Internal + +#include "perfprofilerplugin.moc" diff --git a/src/plugins/perfprofiler/perfprofilerplugin.h b/src/plugins/perfprofiler/perfprofilerplugin.h deleted file mode 100644 index 8421884f0fe..00000000000 --- a/src/plugins/perfprofiler/perfprofilerplugin.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (C) 2018 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include - -namespace PerfProfiler::Internal { - -class PerfProfilerPlugin : public ExtensionSystem::IPlugin -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "PerfProfiler.json") - -public: - ~PerfProfilerPlugin(); - - void initialize() final; - - class PerfProfilerPluginPrivate *d = nullptr; -}; - -} // PerfProfiler::Internal diff --git a/src/plugins/perfprofiler/perfprofilertool.cpp b/src/plugins/perfprofiler/perfprofilertool.cpp index 07847e3271b..81a2e83c7a0 100644 --- a/src/plugins/perfprofiler/perfprofilertool.cpp +++ b/src/plugins/perfprofiler/perfprofilertool.cpp @@ -46,8 +46,7 @@ using namespace PerfProfiler::Constants; using namespace Utils; using namespace std::placeholders; -namespace PerfProfiler { -namespace Internal { +namespace PerfProfiler::Internal { static PerfProfilerTool *s_instance; @@ -690,5 +689,14 @@ void PerfProfilerTool::clearUi() updateRunActions(); } -} // namespace Internal -} // namespace PerfProfiler +void setupPerfProfilerTool() +{ + (void) new PerfProfilerTool; +} + +void destroyPerfProfilerTool() +{ + delete s_instance; +} + +} // PerfProfiler::Internal diff --git a/src/plugins/perfprofiler/perfprofilertool.h b/src/plugins/perfprofiler/perfprofilertool.h index d456fe2b7ab..014ac091471 100644 --- a/src/plugins/perfprofiler/perfprofilertool.h +++ b/src/plugins/perfprofiler/perfprofilertool.h @@ -111,5 +111,8 @@ private: bool m_processRunning = false; }; +void setupPerfProfilerTool(); +void destroyPerfProfilerTool(); + } // namespace Internal } // namespace PerfProfiler diff --git a/src/plugins/perfprofiler/perfprofilertracefile.cpp b/src/plugins/perfprofiler/perfprofilertracefile.cpp index 9cc7befc4c9..3af5adf7d04 100644 --- a/src/plugins/perfprofiler/perfprofilertracefile.cpp +++ b/src/plugins/perfprofiler/perfprofilertracefile.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "perfprofilerconstants.h" -#include "perfprofilerplugin.h" #include "perfprofilertr.h" #include "perfprofilertracefile.h" diff --git a/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp b/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp index d801af2104c..748c266f0fe 100644 --- a/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp +++ b/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "perfprofilerconstants.h" -#include "perfprofilerplugin.h" #include "perfprofilertr.h" #include "perfrunconfigurationaspect.h" #include "perfsettings.h" From b49f847576653a2c61c73809d5001e391fba9f09 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Nov 2023 10:11:11 +0100 Subject: [PATCH 0344/1546] PerfProfiler: Use new setup for PerfRunConfigurationAspect Change-Id: Ib249fecdaeeec8c6fa3c24ae02563023ab7c749b Reviewed-by: Jarek Kobus --- .../perfprofiler/perfprofilerplugin.cpp | 4 +- .../perfrunconfigurationaspect.cpp | 38 ++++++++++++++----- .../perfprofiler/perfrunconfigurationaspect.h | 16 +------- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/src/plugins/perfprofiler/perfprofilerplugin.cpp b/src/plugins/perfprofiler/perfprofilerplugin.cpp index 93568849496..06b61ac5038 100644 --- a/src/plugins/perfprofiler/perfprofilerplugin.cpp +++ b/src/plugins/perfprofiler/perfprofilerplugin.cpp @@ -12,8 +12,6 @@ #include -using namespace ProjectExplorer; - namespace PerfProfiler::Internal { class PerfProfilerPlugin final : public ExtensionSystem::IPlugin @@ -25,7 +23,7 @@ class PerfProfilerPlugin final : public ExtensionSystem::IPlugin { setupPerfProfilerTool(); setupPerfProfilerRunWorker(); - RunConfiguration::registerAspect(); + setupPerfRunConfigurationAspect(); #if WITH_TESTS // addTest(); // FIXME these tests have to get rewritten diff --git a/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp b/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp index 748c266f0fe..ae6cde6c809 100644 --- a/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp +++ b/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp @@ -1,24 +1,44 @@ // Copyright (C) 2018 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#include "perfrunconfigurationaspect.h" + +#include "perfprofiler_global.h" #include "perfprofilerconstants.h" #include "perfprofilertr.h" -#include "perfrunconfigurationaspect.h" #include "perfsettings.h" +#include + #include +using namespace ProjectExplorer; + namespace PerfProfiler { -PerfRunConfigurationAspect::PerfRunConfigurationAspect(ProjectExplorer::Target *target) +class PerfRunConfigurationAspect + : public GlobalOrProjectAspect { - setProjectSettings(new PerfSettings(target)); - setGlobalSettings(&PerfProfiler::globalSettings()); - setId(Constants::PerfSettingsId); - setDisplayName(Tr::tr("Performance Analyzer Settings")); - setUsingGlobalSettings(true); - resetProjectToGlobalSettings(); - setConfigWidgetCreator([this] { return new Debugger::AnalyzerRunConfigWidget(this); }); + Q_OBJECT + +public: + PerfRunConfigurationAspect(Target *target) + { + setProjectSettings(new PerfSettings(target)); + setGlobalSettings(&PerfProfiler::globalSettings()); + setId(Constants::PerfSettingsId); + setDisplayName(Tr::tr("Performance Analyzer Settings")); + setUsingGlobalSettings(true); + resetProjectToGlobalSettings(); + setConfigWidgetCreator([this] { return new Debugger::AnalyzerRunConfigWidget(this); }); + } +}; + +void setupPerfRunConfigurationAspect() +{ + RunConfiguration::registerAspect(); } } // namespace PerfProfiler + +#include "perfrunconfigurationaspect.moc" diff --git a/src/plugins/perfprofiler/perfrunconfigurationaspect.h b/src/plugins/perfprofiler/perfrunconfigurationaspect.h index 8f3e3927aa1..88268023a7b 100644 --- a/src/plugins/perfprofiler/perfrunconfigurationaspect.h +++ b/src/plugins/perfprofiler/perfrunconfigurationaspect.h @@ -3,20 +3,8 @@ #pragma once -#include "perfprofiler_global.h" - -#include - -#include - namespace PerfProfiler { -class PERFPROFILER_EXPORT PerfRunConfigurationAspect : - public ProjectExplorer::GlobalOrProjectAspect -{ - Q_OBJECT -public: - PerfRunConfigurationAspect(ProjectExplorer::Target *target); -}; +void setupPerfRunConfigurationAspect(); -} // namespace PerfProfiler +} // PerfProfiler From 8a2ea1f63b1eb38fe79647f979ffe0002ef76ff8 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 21 Nov 2023 15:41:09 +0100 Subject: [PATCH 0345/1546] PE: Fix determining whether to use file missing overlay Amends d92043e69c7fd42183ba82a103e4b5eaef341667. Change-Id: I2d71c06fcce1b469b5dedd799a50c4dde19ab341 Reviewed-by: Burak Hancerli Reviewed-by: Alessandro Portale --- src/plugins/projectexplorer/projectnodes.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index b03716fd6ff..3a09b97b4c1 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -392,7 +392,9 @@ FileNode::FileNode(const Utils::FilePath &filePath, const FileType fileType) : m_fileType(fileType) { setFilePath(filePath); - setUseUnavailableMarker(!filePath.needsDevice() && !filePath.exists()); + const bool ignored = (fileType == FileType::Project || fileType == FileType::App + || fileType == FileType::Lib); + setUseUnavailableMarker(!ignored && !filePath.needsDevice() && !filePath.exists()); setListInProject(true); if (fileType == FileType::Project) setPriority(DefaultProjectFilePriority); From 8f0dc9d5311c8cc2a1a4d5f81eddc000e53c673d Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Sun, 19 Nov 2023 14:56:18 +0100 Subject: [PATCH 0346/1546] TaskTree: Update docs for Storage renamings This addresses the 20th point in the master task below. Task-number: QTCREATORBUG-28741 Change-Id: I7c6d1d6069b10a2afbfc6569f27b48929a417fb1 Reviewed-by: hjk Reviewed-by: Leena Miettinen --- src/libs/solutions/tasking/tasktree.cpp | 70 ++++++++++++------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 7eee7d64a23..f53d8a0b485 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -265,7 +265,7 @@ private: \code struct MyCustomStruct { QByteArray data; }; - TreeStorage storage; + Storage storage; const auto onFirstSetup = [](NetworkQuery &task) { ... }; const auto onFirstDone = [storage](const NetworkQuery &task) { @@ -284,7 +284,7 @@ private: // instance dynamically. It is later accessible from all handlers via // the *storage or storage-> operators. sequential, - Storage(storage), + storage, NetworkQueryTask(onFirstSetup, onFirstDone, CallDoneIf::Success), ConcurrentCallTask(onSecondSetup) }; @@ -2141,7 +2141,7 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith }; // [3] instance of custom inter-task struct manageable by task tree - const TreeStorage storage; + const Storage storage; const auto onLoaderSetup = [source](ConcurrentCall &async) { async.setConcurrentCallData(&load, source); @@ -2162,7 +2162,7 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith const Group root { // [7] runtime: task tree creates an instance of CopyStorage when root is entered - Storage(storage), + storage, ConcurrentCallTask(onLoaderSetup, onLoaderDone, CallDoneIf::Success), ConcurrentCallTask(onSaverSetup, onSaverDone, CallDoneIf::Success) }; @@ -2181,42 +2181,42 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith \endcode In the example above, the inter-task data consists of a QByteArray content - variable [2] enclosed in a CopyStorage custom struct [1]. If the loader - finishes successfully, it stores the data in a CopyStorage::content + variable [2] enclosed in a \c CopyStorage custom struct [1]. If the loader + finishes successfully, it stores the data in a \c CopyStorage::content variable [5]. The saver then uses the variable to configure the saving task [6]. - To enable a task tree to manage the CopyStorage struct, an instance of - TreeStorage is created [3]. If a copy of this object is - inserted as group's child task [7], an instance of CopyStorage struct is + To enable a task tree to manage the \c CopyStorage struct, an instance of + Storage<\c CopyStorage> is created [3]. If a copy of this object is + inserted as the group's child item [7], an instance of the \c CopyStorage struct is created dynamically when the task tree enters this group. When the task - tree leaves this group, the existing instance of CopyStorage struct is + tree leaves this group, the existing instance of the \c CopyStorage struct is destructed as it's no longer needed. - If several task trees that hold a copy of the common TreeStorage instance + If several task trees holding a copy of the common Storage<\c CopyStorage> instance run simultaneously (including also a case when the task trees are run in different threads), - each task tree contains its own copy of the CopyStorage struct. + each task tree contains its own copy of the \c CopyStorage struct. - You can access CopyStorage from any handler in the group with a storage object. + You can access \c CopyStorage from any handler in the group with a storage object. This includes all handlers of all descendant tasks of the group with a storage object. To access the custom struct in a handler, pass the - copy of the TreeStorage object to the handler (for example, in + copy of the Storage<\c CopyStorage> object to the handler (for example, in a lambda capture) [4]. When the task tree invokes a handler in a subtree containing the storage [7], - the task tree activates its own CopyStorage instance inside the - TreeStorage object. Therefore, the CopyStorage struct may be + the task tree activates its own \c CopyStorage instance inside the + Storage<\c CopyStorage> object. Therefore, the \c CopyStorage struct may be accessed only from within the handler body. To access the currently active - CopyStorage from within TreeStorage, use the TreeStorage::operator->(), - TreeStorage::operator*() or TreeStorage::activeStorage() method. + \c CopyStorage from within Storage<\c CopyStorage>, use the Storage::operator->(), + Storage::operator*(), or Storage::activeStorage() method. The following list summarizes how to employ a Storage object into the task tree: \list 1 - \li Define the custom structure MyStorage with custom data [1], [2] - \li Create an instance of TreeStorage storage [3] - \li Pass the TreeStorage instance to handlers [4] - \li Access the MyStorage instance in handlers [5], [6] - \li Insert the TreeStorage instance into a group [7] + \li Define the custom structure \c MyStorage with custom data [1], [2] + \li Create an instance of the Storage<\c MyStorage> storage [3] + \li Pass the Storage<\c MyStorage> instance to handlers [4] + \li Access the \c MyStorage instance in handlers [5], [6] + \li Insert the Storage<\c MyStorage> instance into a group [7] \endlist \section1 TaskTree class @@ -2242,17 +2242,17 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith handler: \code - TreeStorage storage; + Storage storage; const Group root = ...; // storage placed inside root's group and inside handlers TaskTree taskTree(root); - auto initStorage = [](CopyStorage &storage){ + auto initStorage = [](CopyStorage &storage) { storage.content = "initial content"; }; taskTree.onStorageSetup(storage, initStorage); taskTree.start(); \endcode - When the running task tree creates a CopyStorage instance, and before any + When the running task tree creates a \c CopyStorage instance, and before any handler inside a tree is called, the task tree calls the initStorage handler, to enable setting up initial data of the storage, unique to this particular run of taskTree. @@ -2262,17 +2262,17 @@ bool TaskTreePrivate::invokeDoneHandler(TaskRuntimeNode *node, DoneWith doneWith destroyed. To do this, install a storage done handler: \code - TreeStorage storage; + Storage storage; const Group root = ...; // storage placed inside root's group and inside handlers TaskTree taskTree(root); - auto collectStorage = [](const CopyStorage &storage){ + auto collectStorage = [](const CopyStorage &storage) { qDebug() << "final content" << storage.content; }; taskTree.onStorageDone(storage, collectStorage); taskTree.start(); \endcode - When the running task tree is about to destroy a CopyStorage instance, the + When the running task tree is about to destroy a \c CopyStorage instance, the task tree calls the collectStorage handler, to enable reading the final data from the storage, unique to this particular run of taskTree. @@ -2647,7 +2647,7 @@ int TaskTree::progressValue() const } /*! - \fn template void TaskTree::onStorageSetup(const TreeStorage &storage, StorageHandler &&handler) + \fn template void TaskTree::onStorageSetup(const Storage &storage, Handler &&handler) Installs a storage setup \a handler for the \a storage to pass the initial data dynamically to the running task tree. @@ -2657,14 +2657,14 @@ int TaskTree::progressValue() const \code static void save(const QString &fileName, const QByteArray &array) { ... } - TreeStorage storage; + Storage storage; const auto onSaverSetup = [storage](ConcurrentCall &concurrent) { concurrent.setConcurrentCallData(&save, "foo.txt", *storage); }; const Group root { - Storage(storage), + storage, ConcurrentCallTask(onSaverSetup) }; @@ -2688,7 +2688,7 @@ int TaskTree::progressValue() const */ /*! - \fn template void TaskTree::onStorageDone(const TreeStorage &storage, StorageHandler &&handler) + \fn template void TaskTree::onStorageDone(const Storage &storage, Handler &&handler) Installs a storage done \a handler for the \a storage to retrieve the final data dynamically from the running task tree. @@ -2698,7 +2698,7 @@ int TaskTree::progressValue() const \code static QByteArray load(const QString &fileName) { ... } - TreeStorage storage; + Storage storage; const auto onLoaderSetup = [](ConcurrentCall &concurrent) { concurrent.setConcurrentCallData(&load, "foo.txt"); @@ -2708,7 +2708,7 @@ int TaskTree::progressValue() const }; const Group root { - Storage(storage), + storage, ConcurrentCallTask(onLoaderDone, onLoaderDone, CallDoneIf::Success) }; From bf373f7e4188e028c126630c6f9f13847b9304d8 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 20 Nov 2023 16:04:11 +0100 Subject: [PATCH 0347/1546] ProjectExplorer: Use new setup pattern for gcc related toolchains Change-Id: I8b00f126a0824e5ec3b2ef3e63fdef41cd8917a1 Reviewed-by: Christian Kandeler --- src/plugins/projectexplorer/gcctoolchain.cpp | 99 +++++++++++++------ src/plugins/projectexplorer/gcctoolchain.h | 29 +----- .../projectexplorer/projectexplorer.cpp | 11 +-- 3 files changed, 72 insertions(+), 67 deletions(-) diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 8a39318aaea..d2ce8299e31 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -1109,7 +1109,7 @@ FilePath GccToolChain::detectInstallDir() const } // -------------------------------------------------------------------------- -// GccToolChainFactory +// GccToolchainFactory // -------------------------------------------------------------------------- static FilePaths gnuSearchPathsFromRegistry() @@ -1274,33 +1274,69 @@ static ToolChain *constructLinuxIccToolchain() return new GccToolChain(Constants::LINUXICC_TOOLCHAIN_TYPEID, GccToolChain::LinuxIcc); } -GccToolChainFactory::GccToolChainFactory(GccToolChain::SubType subType) - : m_autoDetecting(subType == GccToolChain::RealGcc) +namespace Internal { + +class GccToolchainFactory final : public ToolChainFactory { - switch (subType) { - case GccToolChain::RealGcc: - setDisplayName(Tr::tr("GCC")); - setSupportedToolChainType(Constants::GCC_TOOLCHAIN_TYPEID); - setToolchainConstructor(&constructRealGccToolchain); - break; - case GccToolChain::Clang: - setDisplayName(Tr::tr("Clang")); - setSupportedToolChainType(Constants::CLANG_TOOLCHAIN_TYPEID); - setToolchainConstructor(&constructClangToolchain); - break; - case GccToolChain::MinGW: - setDisplayName(Tr::tr("MinGW")); - setSupportedToolChainType(Constants::MINGW_TOOLCHAIN_TYPEID); - setToolchainConstructor(&constructMinGWToolchain); - break; - case GccToolChain::LinuxIcc: - setDisplayName(Tr::tr("ICC")); - setSupportedToolChainType(Constants::LINUXICC_TOOLCHAIN_TYPEID); - setToolchainConstructor(&constructLinuxIccToolchain); - break; +public: + explicit GccToolchainFactory(GccToolChain::SubType subType) + : m_autoDetecting(subType == GccToolChain::RealGcc) + { + switch (subType) { + case GccToolChain::RealGcc: + setDisplayName(Tr::tr("GCC")); + setSupportedToolChainType(Constants::GCC_TOOLCHAIN_TYPEID); + setToolchainConstructor(&constructRealGccToolchain); + break; + case GccToolChain::Clang: + setDisplayName(Tr::tr("Clang")); + setSupportedToolChainType(Constants::CLANG_TOOLCHAIN_TYPEID); + setToolchainConstructor(&constructClangToolchain); + break; + case GccToolChain::MinGW: + setDisplayName(Tr::tr("MinGW")); + setSupportedToolChainType(Constants::MINGW_TOOLCHAIN_TYPEID); + setToolchainConstructor(&constructMinGWToolchain); + break; + case GccToolChain::LinuxIcc: + setDisplayName(Tr::tr("ICC")); + setSupportedToolChainType(Constants::LINUXICC_TOOLCHAIN_TYPEID); + setToolchainConstructor(&constructLinuxIccToolchain); + break; + } + setSupportedLanguages({Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}); + setUserCreatable(true); } - setSupportedLanguages({Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}); - setUserCreatable(true); + + Toolchains autoDetect(const ToolchainDetector &detector) const final; + Toolchains detectForImport(const ToolChainDescription &tcd) const final; + +private: + static Toolchains autoDetectToolchains(const FilePaths &compilerPaths, + const Id language, + const Id requiredTypeId, + const Toolchains &known, + const GccToolChain::SubType subType); + static Toolchains autoDetectToolChain(const ToolChainDescription &tcd, + const GccToolChain::SubType subType); + static Toolchains autoDetectSdkClangToolchain(const Toolchains &known); + + const bool m_autoDetecting; +}; + +void setupGccToolchains() +{ +#ifndef Q_OS_WIN + static GccToolchainFactory theLinuxIccToolchainFactory{GccToolChain::LinuxIcc}; +#endif + +#ifndef Q_OS_MACOS + // Mingw offers cross-compiling to windows + static GccToolchainFactory theMingwToolchainFactory{GccToolChain::MinGW}; +#endif + + static GccToolchainFactory theGccToolchainFactory{GccToolChain::RealGcc}; + static GccToolchainFactory theClangToolchainFactory{GccToolChain::Clang}; } static FilePaths findCompilerCandidates(OsType os, @@ -1362,7 +1398,7 @@ static FilePaths findCompilerCandidates(OsType os, } -Toolchains GccToolChainFactory::autoDetect(const ToolchainDetector &detector) const +Toolchains GccToolchainFactory::autoDetect(const ToolchainDetector &detector) const { QTC_ASSERT(detector.device, return {}); @@ -1468,7 +1504,7 @@ Toolchains GccToolChainFactory::autoDetect(const ToolchainDetector &detector) co return result; } -Toolchains GccToolChainFactory::detectForImport(const ToolChainDescription &tcd) const +Toolchains GccToolchainFactory::detectForImport(const ToolChainDescription &tcd) const { Toolchains result; @@ -1515,7 +1551,7 @@ Toolchains GccToolChainFactory::detectForImport(const ToolChainDescription &tcd) return result; } -Toolchains GccToolChainFactory::autoDetectSdkClangToolchain(const Toolchains &known) +Toolchains GccToolchainFactory::autoDetectSdkClangToolchain(const Toolchains &known) { const FilePath compilerPath = Core::ICore::clangExecutable(CLANG_BINDIR); if (compilerPath.isEmpty()) @@ -1529,7 +1565,7 @@ Toolchains GccToolChainFactory::autoDetectSdkClangToolchain(const Toolchains &kn return {autoDetectToolChain({compilerPath, Constants::C_LANGUAGE_ID}, GccToolChain::Clang)}; } -Toolchains GccToolChainFactory::autoDetectToolchains(const FilePaths &compilerPaths, +Toolchains GccToolchainFactory::autoDetectToolchains(const FilePaths &compilerPaths, const Id language, const Id requiredTypeId, const Toolchains &known, @@ -1580,7 +1616,7 @@ Toolchains GccToolChainFactory::autoDetectToolchains(const FilePaths &compilerPa return result; } -Toolchains GccToolChainFactory::autoDetectToolChain(const ToolChainDescription &tcd, +Toolchains GccToolchainFactory::autoDetectToolChain(const ToolChainDescription &tcd, GccToolChain::SubType subType) { Toolchains result; @@ -1630,7 +1666,6 @@ Toolchains GccToolChainFactory::autoDetectToolChain(const ToolChainDescription & // GccToolChainConfigWidget // -------------------------------------------------------------------------- -namespace Internal { class TargetTripleWidget : public QWidget { Q_OBJECT diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h index 52ffabc839b..ec94b5df96b 100644 --- a/src/plugins/projectexplorer/gcctoolchain.h +++ b/src/plugins/projectexplorer/gcctoolchain.h @@ -17,7 +17,7 @@ namespace ProjectExplorer { namespace Internal { class GccToolChainConfigWidget; -class GccToolChainFactory; +class GccToolchainFactory; const QStringList gccPredefinedMacrosOptions(Utils::Id languageId); } @@ -149,7 +149,7 @@ private: mutable Utils::FilePath m_installDir; friend class Internal::GccToolChainConfigWidget; - friend class Internal::GccToolChainFactory; + friend class Internal::GccToolchainFactory; friend class ToolChainFactory; // "resolved" on macOS from /usr/bin/clang(++) etc to /usr/bin/clang(++) @@ -161,29 +161,6 @@ private: QMetaObject::Connection m_thisToolchainRemovedConnection; }; +namespace Internal { void setupGccToolchains(); } -namespace Internal { - -class GccToolChainFactory : public ToolChainFactory -{ -public: - explicit GccToolChainFactory(GccToolChain::SubType subType); - - Toolchains autoDetect(const ToolchainDetector &detector) const final; - Toolchains detectForImport(const ToolChainDescription &tcd) const final; - -private: - static Toolchains autoDetectToolchains(const Utils::FilePaths &compilerPaths, - const Utils::Id language, - const Utils::Id requiredTypeId, - const Toolchains &known, - const GccToolChain::SubType subType); - static Toolchains autoDetectToolChain(const ToolChainDescription &tcd, - const GccToolChain::SubType subType); - static Toolchains autoDetectSdkClangToolchain(const Toolchains &known); - - const bool m_autoDetecting; -}; - -} // namespace Internal } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index b34d20ea367..1229d3e1a92 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -643,17 +643,8 @@ public: WinDebugInterface m_winDebugInterface; MsvcToolChainFactory m_mscvToolChainFactory; ClangClToolChainFactory m_clangClToolChainFactory; -#else - GccToolChainFactory m_linuxToolChainFactory{GccToolChain::LinuxIcc}; #endif -#ifndef Q_OS_MACOS - // Mingw offers cross-compiling to windows - GccToolChainFactory m_mingwToolChainFactory{GccToolChain::MinGW}; -#endif - - GccToolChainFactory m_gccToolChainFactory{GccToolChain::RealGcc}; - GccToolChainFactory m_clangToolChainFactory{GccToolChain::Clang}; CustomToolChainFactory m_customToolChainFactory; DesktopDeviceFactory m_desktopDeviceFactory; @@ -821,6 +812,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er { Q_UNUSED(error) + setupGccToolchains(); + dd = new ProjectExplorerPluginPrivate; dd->extendFolderNavigationWidgetFactory(); From a56ed10c534d956cd883085be26bdb8162dab0f9 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 21 Nov 2023 20:50:42 +0100 Subject: [PATCH 0348/1546] TaskTree: Add docs for List element Change-Id: Iba859b1a1ff424f55d3fe0c7785de61c36d1418f Reviewed-by: Leena Miettinen Reviewed-by: hjk --- src/libs/solutions/tasking/tasktree.cpp | 65 ++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index f53d8a0b485..7edc0f36bdc 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -316,7 +316,7 @@ private: /*! \fn Group::Group(std::initializer_list children) - Constructs a group from std::initializer_list given by \a children. + Constructs a group from \c std::initializer_list given by \a children. This constructor is useful when all child items of the group are known at compile time: @@ -349,6 +349,69 @@ private: and the returned item finishes with an error. */ +/*! + \class Tasking::List + \inheaderfile solutions/tasking/tasktree.h + \inmodule TaskingSolution + \brief List is a helper element that wraps a list of GroupItem elements into a single + GroupItem element. + \reentrant + + \c List is useful when constructing a \l {Tasking::Group} {Group} element with lists of + GroupItem elements. If you define a helper function that returns a list of GroupItem elements, + it's not easy to place them directly into a group together with other items. Instead, you may + wrap the returned list with the \c List element and place it like a single GroupItem element + inside a \l {Tasking::Group} {Group}: + + \code + static QList getItems(); + + ... + + const Group root { + parallel, + finishAllAndSuccess, + // getItems(), // Wrong, compile error, as we can't mix QList with + // GroupItems within the initializer list of root Group. + List(getItems()), // OK, getItems() list is wrapped into a single GroupItem element + // via the List element. + onGroupSetup(...), + onGroupDone(...) + }; + \endcode + + \c List may contain nested \c List elements. \c List doesn't do anything on its own. + When parsed by the task tree, the \c List element is simply replaced with its contents. + + \note Don't confuse \c List with the \l {Tasking::Group} {Group} element, as + \l {Tasking::Group} {Group} keeps its children nested + after being parsed by the task tree, while \c List does not. +*/ + +/*! + \fn List::List(const QList &children) + + Constructs a \c List element with a given list of \a children. + + When the \c List element is parsed by the task tree, it is simply replaced with its children. + + If you want to create a subtree, use \l {Tasking::Group} {Group} instead. + + \sa {Tasking::Group} {Group} +*/ + +/*! + \fn List::List(std::initializer_list children) + + Constructs a \c List element from \c std::initializer_list given by \a children. + + When the \c List element is parsed by the task tree, it is simply replaced with its children. + + If you want to create a subtree, use \l {Tasking::Group} {Group} instead. + + \sa {Tasking::Group} {Group} +*/ + /*! \class Tasking::CustomTask \inheaderfile solutions/tasking/tasktree.h From d597189902caf228c17d6282ea6da8b620c73896 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Nov 2023 14:25:19 +0100 Subject: [PATCH 0349/1546] Revert "PerfProfiler: Use new setup for PerfRunConfigurationAspect" This reverts commit b49f847576653a2c61c73809d5001e391fba9f09. The class access is used in perfprofilerruncontrol.cpp. Change-Id: I1c0d9d1230224f04d39e71706064fd09b4071954 Reviewed-by: Jarek Kobus --- .../perfprofiler/perfprofilerplugin.cpp | 4 +- .../perfrunconfigurationaspect.cpp | 38 +++++-------------- .../perfprofiler/perfrunconfigurationaspect.h | 16 +++++++- 3 files changed, 26 insertions(+), 32 deletions(-) diff --git a/src/plugins/perfprofiler/perfprofilerplugin.cpp b/src/plugins/perfprofiler/perfprofilerplugin.cpp index 06b61ac5038..93568849496 100644 --- a/src/plugins/perfprofiler/perfprofilerplugin.cpp +++ b/src/plugins/perfprofiler/perfprofilerplugin.cpp @@ -12,6 +12,8 @@ #include +using namespace ProjectExplorer; + namespace PerfProfiler::Internal { class PerfProfilerPlugin final : public ExtensionSystem::IPlugin @@ -23,7 +25,7 @@ class PerfProfilerPlugin final : public ExtensionSystem::IPlugin { setupPerfProfilerTool(); setupPerfProfilerRunWorker(); - setupPerfRunConfigurationAspect(); + RunConfiguration::registerAspect(); #if WITH_TESTS // addTest(); // FIXME these tests have to get rewritten diff --git a/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp b/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp index ae6cde6c809..748c266f0fe 100644 --- a/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp +++ b/src/plugins/perfprofiler/perfrunconfigurationaspect.cpp @@ -1,44 +1,24 @@ // Copyright (C) 2018 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -#include "perfrunconfigurationaspect.h" - -#include "perfprofiler_global.h" #include "perfprofilerconstants.h" #include "perfprofilertr.h" +#include "perfrunconfigurationaspect.h" #include "perfsettings.h" -#include - #include -using namespace ProjectExplorer; - namespace PerfProfiler { -class PerfRunConfigurationAspect - : public GlobalOrProjectAspect +PerfRunConfigurationAspect::PerfRunConfigurationAspect(ProjectExplorer::Target *target) { - Q_OBJECT - -public: - PerfRunConfigurationAspect(Target *target) - { - setProjectSettings(new PerfSettings(target)); - setGlobalSettings(&PerfProfiler::globalSettings()); - setId(Constants::PerfSettingsId); - setDisplayName(Tr::tr("Performance Analyzer Settings")); - setUsingGlobalSettings(true); - resetProjectToGlobalSettings(); - setConfigWidgetCreator([this] { return new Debugger::AnalyzerRunConfigWidget(this); }); - } -}; - -void setupPerfRunConfigurationAspect() -{ - RunConfiguration::registerAspect(); + setProjectSettings(new PerfSettings(target)); + setGlobalSettings(&PerfProfiler::globalSettings()); + setId(Constants::PerfSettingsId); + setDisplayName(Tr::tr("Performance Analyzer Settings")); + setUsingGlobalSettings(true); + resetProjectToGlobalSettings(); + setConfigWidgetCreator([this] { return new Debugger::AnalyzerRunConfigWidget(this); }); } } // namespace PerfProfiler - -#include "perfrunconfigurationaspect.moc" diff --git a/src/plugins/perfprofiler/perfrunconfigurationaspect.h b/src/plugins/perfprofiler/perfrunconfigurationaspect.h index 88268023a7b..8f3e3927aa1 100644 --- a/src/plugins/perfprofiler/perfrunconfigurationaspect.h +++ b/src/plugins/perfprofiler/perfrunconfigurationaspect.h @@ -3,8 +3,20 @@ #pragma once +#include "perfprofiler_global.h" + +#include + +#include + namespace PerfProfiler { -void setupPerfRunConfigurationAspect(); +class PERFPROFILER_EXPORT PerfRunConfigurationAspect : + public ProjectExplorer::GlobalOrProjectAspect +{ + Q_OBJECT +public: + PerfRunConfigurationAspect(ProjectExplorer::Target *target); +}; -} // PerfProfiler +} // namespace PerfProfiler From 2bd02671d81dd550881cc7384d9bdf9d2bde4394 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 9 Nov 2023 10:06:14 +0100 Subject: [PATCH 0350/1546] ProjectExplorer: allow defining additional data in BuildTargetInfo Change-Id: I14987e4d56424628828feeeeadfac2c4b28468c8 Reviewed-by: Christian Stenger --- src/plugins/projectexplorer/buildtargetinfo.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/buildtargetinfo.h b/src/plugins/projectexplorer/buildtargetinfo.h index 505b5f2336d..4ba1c4de5b4 100644 --- a/src/plugins/projectexplorer/buildtargetinfo.h +++ b/src/plugins/projectexplorer/buildtargetinfo.h @@ -25,6 +25,8 @@ public: bool isQtcRunnable = true; bool usesTerminal = false; + QVariant additionalData; + size_t runEnvModifierHash = 0; // Make sure to update this when runEnvModifier changes! std::function runEnvModifier; @@ -38,7 +40,8 @@ public: && ti1.workingDirectory == ti2.workingDirectory && ti1.isQtcRunnable == ti2.isQtcRunnable && ti1.usesTerminal == ti2.usesTerminal - && ti1.runEnvModifierHash == ti2.runEnvModifierHash; + && ti1.runEnvModifierHash == ti2.runEnvModifierHash + && ti1.additionalData == ti2.additionalData; } friend bool operator!=(const BuildTargetInfo &ti1, const BuildTargetInfo &ti2) From 240748c106678218d7ed85e3a7a2d79db099b0e6 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 20 Nov 2023 11:28:41 +0100 Subject: [PATCH 0351/1546] TextEditor: Get rid of extra indent ranges in RefactoringFile Having extra indent regions complicates the interface, the implementation and the calling code. Instead, derive the indent regions from the change set and let callers opt out for the relatively few cases where indentation is not desired. Change-Id: I49d2854830a51778534ef260fb5c9f2c7685554a Reviewed-by: David Schulz --- .../clangcodemodel/clangfixitoperation.cpp | 6 +- .../cppeditor/cppinsertvirtualmethods.cpp | 4 - src/plugins/cppeditor/cppquickfixes.cpp | 67 +++----- .../cppeditor/cpprefactoringchanges.cpp | 42 +---- src/plugins/cppeditor/cpprefactoringchanges.h | 6 +- .../languageclient/languageclientutils.cpp | 2 - .../projectexplorer/projectexplorer.cpp | 6 + .../qmljscomponentfromobjectdef.cpp | 1 - src/plugins/qmljseditor/qmljsquickfixes.cpp | 3 - src/plugins/qmljseditor/qmljswrapinloader.cpp | 1 - src/plugins/qmljseditor/qmloutlinemodel.cpp | 3 - .../qmljstools/qmljsrefactoringchanges.cpp | 41 +---- .../qmljstools/qmljsrefactoringchanges.h | 5 +- src/plugins/texteditor/basefilefind.cpp | 1 + src/plugins/texteditor/refactoringchanges.cpp | 159 ++++++------------ src/plugins/texteditor/refactoringchanges.h | 22 +-- src/plugins/texteditor/tabsettings.cpp | 14 ++ src/plugins/texteditor/tabsettings.h | 9 +- 18 files changed, 120 insertions(+), 272 deletions(-) diff --git a/src/plugins/clangcodemodel/clangfixitoperation.cpp b/src/plugins/clangcodemodel/clangfixitoperation.cpp index b303a755e51..e173592ec06 100644 --- a/src/plugins/clangcodemodel/clangfixitoperation.cpp +++ b/src/plugins/clangcodemodel/clangfixitoperation.cpp @@ -3,7 +3,8 @@ #include "clangfixitoperation.h" -#include +#include +#include #include @@ -46,7 +47,8 @@ static FileToFixits fixitsPerFile(const QList &fixIts) void ClangFixItOperation::perform() { - const TextEditor::PlainRefactoringFileFactory refactoringChanges; + const CppEditor::CppRefactoringChanges refactoringChanges( + CppEditor::CppModelManager::snapshot()); const FileToFixits fileToFixIts = fixitsPerFile(fixIts); for (auto i = fileToFixIts.cbegin(), end = fileToFixIts.cend(); i != end; ++i) { diff --git a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp index 7c173c703b4..754042d168d 100644 --- a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp +++ b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp @@ -864,8 +864,6 @@ public: // Write header file if (!headerChangeSet.isEmpty()) { headerFile->setChangeSet(headerChangeSet); - headerFile->appendIndentRange(Utils::ChangeSet::Range(m_insertPosDecl, - m_insertPosDecl + 1)); headerFile->setOpenEditor(true, m_insertPosDecl); headerFile->apply(); } @@ -920,8 +918,6 @@ public: if (!implementationChangeSet.isEmpty()) { implementationFile->setChangeSet(implementationChangeSet); - implementationFile->appendIndentRange(Utils::ChangeSet::Range(insertPos, - insertPos + 1)); implementationFile->apply(); } } diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 0ce5adb798d..e5417ec6c01 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -599,7 +599,6 @@ public: changes.insert(end, QLatin1String(")")); currentFile->setChangeSet(changes); - currentFile->appendIndentRange(currentFile->range(pattern)); currentFile->apply(); } }; @@ -699,7 +698,6 @@ public: } currentFile->setChangeSet(changes); - currentFile->appendIndentRange(currentFile->range(declaration)); currentFile->apply(); } @@ -774,7 +772,6 @@ public: changes.insert(end, QLatin1String("\n}")); currentFile->setChangeSet(changes); - currentFile->appendIndentRange(ChangeSet::Range(start, end)); currentFile->apply(); } @@ -848,7 +845,6 @@ public: changes.insert(insertPos, QLatin1String(";\n")); currentFile->setChangeSet(changes); - currentFile->appendIndentRange(currentFile->range(pattern)); currentFile->apply(); } @@ -924,7 +920,6 @@ public: changes.insert(insertPos, QLatin1String(";\n")); currentFile->setChangeSet(changes); - currentFile->appendIndentRange(currentFile->range(pattern)); currentFile->apply(); } @@ -1012,7 +1007,6 @@ public: changes.insert(currentFile->endOf(pattern), QLatin1String("\n}")); currentFile->setChangeSet(changes); - currentFile->appendIndentRange(currentFile->range(pattern)); currentFile->apply(); } @@ -1041,7 +1035,6 @@ public: changes.remove(lExprEnd, currentFile->startOf(condition->right_expression)); currentFile->setChangeSet(changes); - currentFile->appendIndentRange(currentFile->range(pattern)); currentFile->apply(); } @@ -2405,7 +2398,6 @@ public: + values.join(QLatin1String(":\nbreak;\ncase ")) + QLatin1String(":\nbreak;")); currentFile->setChangeSet(changes); - currentFile->appendIndentRange(ChangeSet::Range(start, start + 1)); currentFile->apply(); } @@ -2542,14 +2534,12 @@ public: QTC_ASSERT(loc.isValid(), return); CppRefactoringFilePtr targetFile = refactoring.cppFile(m_targetFilePath); - int targetPosition1 = targetFile->position(loc.line(), loc.column()); - int targetPosition2 = qMax(0, targetFile->position(loc.line(), 1) - 1); + int targetPosition = targetFile->position(loc.line(), loc.column()); ChangeSet target; - target.insert(targetPosition1, loc.prefix() + m_decl); + target.insert(targetPosition, loc.prefix() + m_decl); targetFile->setChangeSet(target); - targetFile->appendIndentRange(ChangeSet::Range(targetPosition2, targetPosition1)); - targetFile->setOpenEditor(true, targetPosition1); + targetFile->setOpenEditor(true, targetPosition); targetFile->apply(); } @@ -2708,8 +2698,7 @@ public: DeclaratorAST *declAST, Declaration *decl, const FilePath &targetFilePath, - ChangeSet *changeSet = nullptr, - QList *indentRanges = nullptr) + ChangeSet *changeSet = nullptr) { CppRefactoringChanges refactoring(op->snapshot()); if (!loc.isValid()) @@ -2736,10 +2725,6 @@ public: ChangeSet * const target = changeSet ? changeSet : &localChangeSet; target->replace(targetPos - 1, targetPos, QLatin1String("\n {\n\n}")); // replace ';' const ChangeSet::Range indentRange(targetPos, targetPos + 4); - if (indentRanges) - indentRanges->append(indentRange); - else - targetFile->appendIndentRange(indentRange); if (!changeSet) { targetFile->setChangeSet(*target); @@ -2819,10 +2804,6 @@ public: ChangeSet * const target = changeSet ? changeSet : &localChangeSet; target->insert(targetPos, loc.prefix() + defText + loc.suffix()); const ChangeSet::Range indentRange(targetPos2, targetPos); - if (indentRanges) - indentRanges->append(indentRange); - else - targetFile->appendIndentRange(indentRange); if (!changeSet) { targetFile->setChangeSet(*target); @@ -2995,12 +2976,10 @@ private: QTC_ASSERT(loc.isValid(), return); CppRefactoringFilePtr targetFile = refactoring.cppFile(filePath); - const int targetPosition1 = targetFile->position(loc.line(), loc.column()); - const int targetPosition2 = qMax(0, targetFile->position(loc.line(), 1) - 1); + const int targetPosition = targetFile->position(loc.line(), loc.column()); ChangeSet target; - target.insert(targetPosition1, loc.prefix() + decl + ";\n"); + target.insert(targetPosition, loc.prefix() + decl + ";\n"); targetFile->setChangeSet(target); - targetFile->appendIndentRange(ChangeSet::Range(targetPosition2, targetPosition1)); targetFile->apply(); } @@ -3558,7 +3537,7 @@ private: SimpleDeclarationAST *m_decl = nullptr; }; - QHash>> changeSets; + QHash changeSets; for (const MemberFunctionImplSetting &setting : std::as_const(settings)) { DeclFinder finder(currentFile().data(), setting.func); finder.accept(m_classAST); @@ -3572,17 +3551,14 @@ private: currentFile()->lineAndColumn(currentFile()->endOf(finder.decl()), &line, &column); loc = InsertionLocation(filePath(), QString(), QString(), line, column); } - auto &changeSet = changeSets[targetFilePath]; + ChangeSet &changeSet = changeSets[targetFilePath]; InsertDefOperation::insertDefinition( this, loc, setting.defPos, finder.decl()->declarator_list->value, - setting.func->asDeclaration(),targetFilePath, - &changeSet.first, &changeSet.second); + setting.func->asDeclaration(),targetFilePath, &changeSet); } for (auto it = changeSets.cbegin(); it != changeSets.cend(); ++it) { const CppRefactoringFilePtr file = refactoring.cppFile(it.key()); - for (const ChangeSet::Range &r : it.value().second) - file->appendIndentRange(r); - file->setChangeSet(it.value().first); + file->setChangeSet(it.value()); file->apply(); } } @@ -3763,11 +3739,9 @@ protected: const InsertionLocation &loc, const QString &text) { - int targetPosition1 = file->position(loc.line(), loc.column()); - int targetPosition2 = qMax(0, file->position(loc.line(), 1) - 1); + int targetPosition = file->position(loc.line(), loc.column()); ChangeSet &changeSet = file == m_headerFile ? m_headerFileChangeSet : m_sourceFileChangeSet; - changeSet.insert(targetPosition1, loc.prefix() + text + loc.suffix()); - file->appendIndentRange(ChangeSet::Range(targetPosition2, targetPosition1)); + changeSet.insert(targetPosition, loc.prefix() + text + loc.suffix()); } FullySpecifiedType makeConstRef(FullySpecifiedType type) @@ -5190,7 +5164,6 @@ public: change.insert(position, funcDef); change.replace(m_extractionStart, m_extractionEnd, funcCall); currentFile->setChangeSet(change); - currentFile->appendIndentRange(ChangeSet::Range(position, position + 1)); currentFile->apply(); QTextCursor tc = currentFile->document()->find(QLatin1String("{"), position); @@ -5199,7 +5172,6 @@ public: change.clear(); change.insert(position, extract + '\n'); currentFile->setChangeSet(change); - currentFile->appendReindentRange(ChangeSet::Range(position, position + 1)); currentFile->apply(); // Write declaration, if necessary. @@ -5213,7 +5185,6 @@ public: position = declFile->position(location.line(), location.column()); change.insert(position, location.prefix() + funcDecl + location.suffix()); declFile->setChangeSet(change); - declFile->appendIndentRange(ChangeSet::Range(position, position + 1)); declFile->apply(); } } @@ -6579,7 +6550,6 @@ public: // insert definition at new position m_toFileChangeSet.insert(insertPos, funcDef); - m_toFile->appendIndentRange(ChangeSet::Range(insertPos, insertPos + funcDef.size())); m_toFile->setOpenEditor(true, insertPos); // remove definition from fromFile @@ -6605,6 +6575,7 @@ public: } if (!m_fromFileChangeSet.isEmpty()) { m_fromFile->setChangeSet(m_fromFileChangeSet); + m_fromFile->skipFormatting(); m_fromFile->apply(); } } @@ -6836,7 +6807,6 @@ private: if (m_toFilePath == m_fromFilePath) toTarget.remove(m_fromRange); toFile->setChangeSet(toTarget); - toFile->appendIndentRange(m_toRange); toFile->setOpenEditor(true, m_toRange.start); toFile->apply(); if (m_toFilePath != m_fromFilePath) { @@ -7649,6 +7619,13 @@ private: CppRefactoringChanges refactoring(snapshot()); CppRefactoringFilePtr currentFile = refactoring.cppFile(filePath()); currentFile->setChangeSet(m_changes); + + // It would probably be unexpected to users if we were to re-format here, though + // an argument could also be made for doing it, especially if "format instead of indent" + // is enabled, as a difference in line length might trigger a different ClangFormat + // re-flowing. + currentFile->skipFormatting(); + currentFile->apply(); } @@ -8426,8 +8403,10 @@ private: processIncludes(refactoring, filePath()); } - for (auto &file : std::as_const(m_changes)) + for (auto &file : std::as_const(m_changes)) { + file->skipFormatting(); file->apply(); + } } /** diff --git a/src/plugins/cppeditor/cpprefactoringchanges.cpp b/src/plugins/cppeditor/cpprefactoringchanges.cpp index 207d359cb88..68d18db7492 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.cpp +++ b/src/plugins/cppeditor/cpprefactoringchanges.cpp @@ -36,16 +36,6 @@ public: using namespace Internal; -static std::unique_ptr createIndenter(const FilePath &filePath, - QTextDocument *textDocument) -{ - TextEditor::ICodeStylePreferencesFactory *factory - = TextEditor::TextEditorSettings::codeStyleFactory(Constants::CPP_SETTINGS_ID); - std::unique_ptr indenter(factory->createIndenter(textDocument)); - indenter->setFileName(filePath); - return indenter; -} - CppRefactoringChanges::CppRefactoringChanges(const Snapshot &snapshot) : m_data(new CppRefactoringChangesData(snapshot)) { @@ -89,19 +79,16 @@ CppRefactoringFile::CppRefactoringFile(const FilePath &filePath, const QSharedPo { const Snapshot &snapshot = data->m_snapshot; m_cppDocument = snapshot.document(filePath); - enableFormatting(); } CppRefactoringFile::CppRefactoringFile(QTextDocument *document, const FilePath &filePath) : RefactoringFile(document, filePath) { - enableFormatting(); } CppRefactoringFile::CppRefactoringFile(TextEditor::TextEditorWidget *editor) : RefactoringFile(editor) { - enableFormatting(); } Document::Ptr CppRefactoringFile::cppDocument() const @@ -253,6 +240,11 @@ void CppRefactoringFile::fileChanged() CppModelManager::updateSourceFiles({filePath()}); } +Id CppRefactoringFile::indenterId() const +{ + return Constants::CPP_SETTINGS_ID; +} + int CppRefactoringFile::tokenIndexForPosition(const std::vector &tokens, int pos, int startIndex) const { @@ -281,28 +273,4 @@ CppRefactoringChangesData::CppRefactoringChangesData(const Snapshot &snapshot) , m_workingCopy(CppModelManager::workingCopy()) {} -void CppRefactoringFile::indentSelection(const QTextCursor &selection, - const TextEditor::TextDocument *textDocument) const -{ - if (textDocument) { // use the indenter from the textDocument if there is one, can be ClangFormat - textDocument->indenter()->indent(selection, QChar::Null, textDocument->tabSettings()); - } else { - const auto &tabSettings = ProjectExplorer::actualTabSettings(filePath(), textDocument); - auto indenter = createIndenter(filePath(), selection.document()); - indenter->indent(selection, QChar::Null, tabSettings); - } -} - -void CppRefactoringFile::reindentSelection(const QTextCursor &selection, - const TextEditor::TextDocument *textDocument) const -{ - if (textDocument) { // use the indenter from the textDocument if there is one, can be ClangFormat - textDocument->indenter()->reindent(selection, textDocument->tabSettings()); - } else { - const auto &tabSettings = ProjectExplorer::actualTabSettings(filePath(), textDocument); - auto indenter = createIndenter(filePath(), selection.document()); - indenter->reindent(selection, tabSettings); - } -} - } // namespace CppEditor diff --git a/src/plugins/cppeditor/cpprefactoringchanges.h b/src/plugins/cppeditor/cpprefactoringchanges.h index 35e26940de0..9a9cb09dc14 100644 --- a/src/plugins/cppeditor/cpprefactoringchanges.h +++ b/src/plugins/cppeditor/cpprefactoringchanges.h @@ -55,11 +55,7 @@ private: explicit CppRefactoringFile(TextEditor::TextEditorWidget *editor); void fileChanged() override; - void indentSelection(const QTextCursor &selection, - const TextEditor::TextDocument *textDocument) const override; - virtual void reindentSelection(const QTextCursor &selection, - const TextEditor::TextDocument *textDocument) const override; - + Utils::Id indenterId() const override; int tokenIndexForPosition(const std::vector &tokens, int pos, int startIndex) const; diff --git a/src/plugins/languageclient/languageclientutils.cpp b/src/plugins/languageclient/languageclientutils.cpp index 76c3cdb2933..8edf1666c8b 100644 --- a/src/plugins/languageclient/languageclientutils.cpp +++ b/src/plugins/languageclient/languageclientutils.cpp @@ -91,8 +91,6 @@ bool applyTextEdits(const Client *client, return true; const RefactoringFilePtr file = client->createRefactoringFile(filePath); file->setChangeSet(editsToChangeSet(edits, file->document())); - for (const TextEdit &edit : edits) - file->appendIndentRange(convertRange(file->document(), edit.range())); return file->apply(); } diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 1229d3e1a92..f0cf98190e8 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -40,6 +40,7 @@ #include "devicesupport/devicesettingspage.h" #include "devicesupport/sshsettings.h" #include "devicesupport/sshsettingspage.h" +#include "editorconfiguration.h" #include "editorsettingspropertiespage.h" #include "environmentaspect.h" #include "filesinallprojectsfind.h" @@ -116,6 +117,7 @@ #include #include +#include #include #include #include @@ -833,6 +835,10 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er IWizardFactory::registerFeatureProvider(new KitFeatureProvider); IWizardFactory::registerFactoryCreator([] { return new SimpleProjectWizard; }); + TextEditor::TabSettings::setRetriever([](const FilePath &filePath) { + return actualTabSettings(filePath, nullptr); + }); + ProjectManager *sessionManager = &dd->m_sessionManager; connect(sessionManager, &ProjectManager::projectAdded, this, &ProjectExplorerPlugin::fileListChanged); diff --git a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp index 41fa6df2924..134baa58274 100644 --- a/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp +++ b/src/plugins/qmljseditor/qmljscomponentfromobjectdef.cpp @@ -190,7 +190,6 @@ public: Utils::ChangeSet changes; changes.replace(start, end, replacement); currentFile->setChangeSet(changes); - currentFile->appendIndentRange(Range(start, end + 1)); currentFile->apply(); Core::IVersionControl *versionControl = Core::VcsManager::findVersionControlForDirectory( diff --git a/src/plugins/qmljseditor/qmljsquickfixes.cpp b/src/plugins/qmljseditor/qmljsquickfixes.cpp index 44ee1bd5226..126361451e2 100644 --- a/src/plugins/qmljseditor/qmljsquickfixes.cpp +++ b/src/plugins/qmljseditor/qmljsquickfixes.cpp @@ -71,8 +71,6 @@ public: QLatin1String("\n")); currentFile->setChangeSet(changes); - currentFile->appendIndentRange(Range(currentFile->startOf(_objectInitializer->lbraceToken), - currentFile->startOf(_objectInitializer->rbraceToken))); currentFile->apply(); } }; @@ -123,7 +121,6 @@ public: const int insertLoc = _message.location.begin() - _message.location.startColumn + 1; changes.insert(insertLoc, QString::fromLatin1("// %1\n").arg(_message.suppressionString())); currentFile->setChangeSet(changes); - currentFile->appendIndentRange(Range(insertLoc, insertLoc + 1)); currentFile->apply(); } }; diff --git a/src/plugins/qmljseditor/qmljswrapinloader.cpp b/src/plugins/qmljseditor/qmljswrapinloader.cpp index 70dc321f419..bf5fd44d4a7 100644 --- a/src/plugins/qmljseditor/qmljswrapinloader.cpp +++ b/src/plugins/qmljseditor/qmljswrapinloader.cpp @@ -147,7 +147,6 @@ public: " sourceComponent: %1\n" "}\n").arg(componentId, loaderId)); currentFile->setChangeSet(changes); - currentFile->appendIndentRange(Range(objDefStart, objDefEnd)); currentFile->apply(); } }; diff --git a/src/plugins/qmljseditor/qmloutlinemodel.cpp b/src/plugins/qmljseditor/qmloutlinemodel.cpp index 432628330f7..015e8a41eb1 100644 --- a/src/plugins/qmljseditor/qmloutlinemodel.cpp +++ b/src/plugins/qmljseditor/qmloutlinemodel.cpp @@ -860,9 +860,6 @@ void QmlOutlineModel::reparentNodes(QmlOutlineItem *targetItem, int row, QListfileName()); file->setChangeSet(changeSet); - for (const Utils::ChangeSet::Range &range : std::as_const(changedRanges)) { - file->appendIndentRange(range); - } file->apply(); } diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp index ddc2ca25c83..fea9c5d87a5 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.cpp +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.cpp @@ -2,9 +2,11 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "qmljsrefactoringchanges.h" + #include "qmljsqtstylecodeformatter.h" #include "qmljsmodelmanager.h" #include "qmljsindenter.h" +#include "qmljstoolsconstants.h" #include #include @@ -139,44 +141,9 @@ void QmlJSRefactoringFile::fileChanged() m_data->m_modelManager->updateSourceFiles({filePath()}, true); } -void QmlJSRefactoringFile::indentSelection(const QTextCursor &selection, - const TextEditor::TextDocument *textDocument) const +Utils::Id QmlJSRefactoringFile::indenterId() const { - // ### shares code with QmlJSTextEditor::indent - QTextDocument *doc = selection.document(); - - QTextBlock block = doc->findBlock(selection.selectionStart()); - const QTextBlock end = doc->findBlock(selection.selectionEnd()).next(); - - const TextEditor::TabSettings &tabSettings = - ProjectExplorer::actualTabSettings(filePath(), textDocument); - CreatorCodeFormatter codeFormatter(tabSettings); - codeFormatter.updateStateUntil(block); - do { - int depth = codeFormatter.indentFor(block); - if (depth != -1) { - if (QStringView(block.text()).trimmed().isEmpty()) { - // we do not want to indent empty lines (as one is indentent when pressing tab - // assuming that the user will start writing something), and get rid of that - // space if one had pressed tab in an empty line just before refactoring. - // If depth == -1 (inside a multiline string for example) leave the spaces. - depth = 0; - } - tabSettings.indentLine(block, depth); - } - codeFormatter.updateLineStateChange(block); - block = block.next(); - } while (block.isValid() && block != end); -} - -void QmlJSRefactoringFile::reindentSelection(const QTextCursor &selection, - const TextEditor::TextDocument *textDocument) const -{ - const TextEditor::TabSettings &tabSettings = - ProjectExplorer::actualTabSettings(filePath(), textDocument); - - QmlJSEditor::Internal::Indenter indenter(selection.document()); - indenter.reindent(selection, tabSettings); + return Constants::QML_JS_SETTINGS_ID; } } // namespace QmlJSTools diff --git a/src/plugins/qmljstools/qmljsrefactoringchanges.h b/src/plugins/qmljstools/qmljsrefactoringchanges.h index 56051d4dfa3..a5b995c0ea1 100644 --- a/src/plugins/qmljstools/qmljsrefactoringchanges.h +++ b/src/plugins/qmljstools/qmljsrefactoringchanges.h @@ -40,10 +40,7 @@ private: QmlJSRefactoringFile(TextEditor::TextEditorWidget *editor, QmlJS::Document::Ptr document); void fileChanged() override; - void indentSelection(const QTextCursor &selection, - const TextEditor::TextDocument *textDocument) const override; - void reindentSelection(const QTextCursor &selection, - const TextEditor::TextDocument *textDocument) const override; + Utils::Id indenterId() const override; mutable QmlJS::Document::Ptr m_qmljsDocument; QSharedPointer m_data; diff --git a/src/plugins/texteditor/basefilefind.cpp b/src/plugins/texteditor/basefilefind.cpp index 399e275fe4f..83a799caaad 100644 --- a/src/plugins/texteditor/basefilefind.cpp +++ b/src/plugins/texteditor/basefilefind.cpp @@ -595,6 +595,7 @@ FilePaths BaseFileFind::replaceAll(const QString &text, const SearchResultItems changeSet.replace(start, end, replacement); } file->setChangeSet(changeSet); + file->skipFormatting(); file->apply(); } diff --git a/src/plugins/texteditor/refactoringchanges.cpp b/src/plugins/texteditor/refactoringchanges.cpp index 88a2366a8d9..1cf089e4069 100644 --- a/src/plugins/texteditor/refactoringchanges.cpp +++ b/src/plugins/texteditor/refactoringchanges.cpp @@ -3,9 +3,12 @@ #include "refactoringchanges.h" +#include "icodestylepreferencesfactory.h" #include "textdocument.h" #include "texteditor.h" #include "texteditortr.h" +#include "texteditorsettings.h" +#include "textindenter.h" #include #include @@ -21,6 +24,8 @@ #include #include +#include + using namespace Core; using namespace Utils; @@ -60,7 +65,8 @@ bool RefactoringFile::create(const QString &contents, bool reindent, bool openIn // Reindent the contents: if (reindent) { cursor.select(QTextCursor::Document); - indentSelection(cursor, nullptr); + m_formattingCursors = {cursor}; + doFormatting(); } cursor.endEditBlock(); @@ -198,22 +204,6 @@ void RefactoringFile::setChangeSet(const ChangeSet &changeSet) m_changes = changeSet; } -void RefactoringFile::appendIndentRange(const Range &range) -{ - if (m_filePath.isEmpty()) - return; - - m_indentRanges.append(range); -} - -void RefactoringFile::appendReindentRange(const Range &range) -{ - if (m_filePath.isEmpty()) - return; - - m_reindentRanges.append(range); -} - void RefactoringFile::setOpenEditor(bool activate, int pos) { m_openEditor = true; @@ -249,7 +239,7 @@ bool RefactoringFile::apply() bool result = true; // apply changes, if any - if (!m_indentRanges.isEmpty() || !m_changes.isEmpty()) { + if (!m_changes.isEmpty()) { QTextDocument *doc = mutableDocument(); if (doc) { QTextCursor c = cursor(); @@ -258,24 +248,12 @@ bool RefactoringFile::apply() else c.beginEditBlock(); - sort(m_indentRanges); - sort(m_reindentRanges); - - // build indent selections now, applying the changeset will change locations - const RefactoringSelections &indentSelections = rangesToSelections(doc, m_indentRanges); - m_indentRanges.clear(); - const RefactoringSelections &reindentSelections - = rangesToSelections(doc, m_reindentRanges); - m_reindentRanges.clear(); - // apply changes setupFormattingRanges(m_changes.operationList()); m_changes.apply(&c); m_changes.clear(); // Do indentation and formatting. - indentOrReindent(indentSelections, Indent); - indentOrReindent(reindentSelections, Reindent); doFormatting(); c.endEditBlock(); @@ -308,27 +286,16 @@ bool RefactoringFile::apply() return result; } -void RefactoringFile::indentOrReindent(const RefactoringSelections &ranges, - RefactoringFile::IndentType indent) -{ - TextDocument * document = m_editor ? m_editor->textDocument() : nullptr; - for (const auto &[position, anchor]: ranges) { - QTextCursor selection(anchor); - selection.setPosition(position.position(), QTextCursor::KeepAnchor); - if (indent == Indent) - indentSelection(selection, document); - else - reindentSelection(selection, document); - } -} - void RefactoringFile::setupFormattingRanges(const QList &replaceList) { - if (!m_editor || !m_formattingEnabled) + if (!m_formattingEnabled) return; + QTextDocument * const doc = m_editor ? m_editor->document() : m_document; + QTC_ASSERT(doc, return); + for (const ChangeSet::EditOp &op : replaceList) { - QTextCursor cursor = m_editor->textCursor(); + QTextCursor cursor(doc); switch (op.type) { case ChangeSet::EditOp::Unset: break; @@ -361,55 +328,54 @@ void RefactoringFile::setupFormattingRanges(const QList &repl void RefactoringFile::doFormatting() { - if (m_formattingCursors.empty() || !m_editor) + if (m_formattingCursors.empty()) return; - RangesInLines formattingRanges; + QTextDocument *document = nullptr; + Indenter *indenter = nullptr; + std::unique_ptr indenterOwner; + TabSettings tabSettings; + if (m_editor) { + document = m_editor->document(); + indenter = m_editor->textDocument()->indenter(); + tabSettings = m_editor->textDocument()->tabSettings(); + } else { + document = m_document; + ICodeStylePreferencesFactory * const factory + = TextEditorSettings::codeStyleFactory(indenterId()); + indenterOwner.reset(factory ? factory->createIndenter(document) + : new TextIndenter(document)); + indenter = indenterOwner.get(); + tabSettings = TabSettings::settingsForFile(filePath()); + } + QTC_ASSERT(document, return); + QTC_ASSERT(indenter, return); - QTextCursor cursor = m_editor->textCursor(); - auto lineForPosition = [&](int pos) { - cursor.setPosition(pos); - return cursor.blockNumber() + 1; - }; - QList affectedLines; + Utils::sort(m_formattingCursors, [](const QTextCursor &tc1, const QTextCursor &tc2) { + return tc1.selectionStart() < tc2.selectionStart(); + }); + const int firstSelectedBlock = document->findBlock(m_formattingCursors.first().selectionStart()) + .blockNumber(); + static const QString clangFormatLineRemovalBlocker("// QTC_TEMP"); for (const QTextCursor &formattingCursor : std::as_const(m_formattingCursors)) { - int startLine = lineForPosition(formattingCursor.selectionStart()); - int endLine = lineForPosition(formattingCursor.selectionEnd()); - for (int line = startLine; line <= endLine; ++line) { - const auto it = std::lower_bound(affectedLines.begin(), affectedLines.end(), line); - if (it == affectedLines.end() || *it > line) - affectedLines.insert(it, line); - } - } - - for (int line : std::as_const(affectedLines)) { - if (!formattingRanges.empty() && formattingRanges.back().endLine == line - 1) - formattingRanges.back().endLine = line; - else - formattingRanges.push_back({line, line}); - } - - static const QString clangFormatLineRemovalBlocker(""); - for (const RangeInLines &r : std::as_const(formattingRanges)) { - QTextBlock b = m_editor->document()->findBlockByNumber(r.startLine - 1); + const QTextBlock firstBlock = document->findBlock(formattingCursor.selectionStart()); + const QTextBlock lastBlock = document->findBlock(formattingCursor.selectionEnd()); + QTextBlock b = firstBlock; while (true) { QTC_ASSERT(b.isValid(), break); if (b.text().simplified().isEmpty()) QTextCursor(b).insertText(clangFormatLineRemovalBlocker); - if (b.blockNumber() == r.endLine - 1) + if (b == lastBlock) break; b = b.next(); } } - // TODO: The proper solution seems to be to call formatOrIndent() here (and not - // use hardcoded indent regions anymore), but that would require intrusive changes - // to the C++ quickfixes and tests, where we rely on the built-in indenter behavior. - m_editor->textDocument()->indenter()->format(formattingRanges, - Indenter::FormattingMode::Settings); + for (const QTextCursor &tc : std::as_const(m_formattingCursors)) + indenter->autoIndent(tc, tabSettings); - for (QTextBlock b = m_editor->document()->findBlockByNumber( - formattingRanges.front().startLine - 1); b.isValid(); b = b.next()) { + for (QTextBlock b = document->findBlockByNumber(firstSelectedBlock); + b.isValid(); b = b.next()) { QString blockText = b.text(); if (blockText.remove(clangFormatLineRemovalBlocker) == b.text()) continue; @@ -420,20 +386,6 @@ void RefactoringFile::doFormatting() } } -void RefactoringFile::indentSelection(const QTextCursor &selection, - const TextDocument *textDocument) const -{ - Q_UNUSED(selection) - Q_UNUSED(textDocument) -} - -void RefactoringFile::reindentSelection(const QTextCursor &selection, - const TextDocument *textDocument) const -{ - Q_UNUSED(selection) - Q_UNUSED(textDocument) -} - TextEditorWidget *RefactoringFile::openEditor(bool activate, int line, int column) { EditorManager::OpenEditorFlags flags = EditorManager::IgnoreNavigationHistory; @@ -450,23 +402,6 @@ TextEditorWidget *RefactoringFile::openEditor(bool activate, int line, int colum return TextEditorWidget::fromEditor(editor); } -RefactoringSelections RefactoringFile::rangesToSelections(QTextDocument *document, - const QList &ranges) -{ - RefactoringSelections selections; - - for (const Range &range : ranges) { - QTextCursor start(document); - start.setPosition(range.start); - start.setKeepPositionOnInsert(true); - QTextCursor end(document); - end.setPosition(qMin(range.end, document->characterCount() - 1)); - selections.push_back({start, end}); - } - - return selections; -} - RefactoringFileFactory::~RefactoringFileFactory() = default; RefactoringFilePtr PlainRefactoringFileFactory::file(const Utils::FilePath &filePath) const diff --git a/src/plugins/texteditor/refactoringchanges.h b/src/plugins/texteditor/refactoringchanges.h index 5155f162fd6..94028825bc6 100644 --- a/src/plugins/texteditor/refactoringchanges.h +++ b/src/plugins/texteditor/refactoringchanges.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -55,12 +56,13 @@ public: Utils::ChangeSet changeSet() const; void setChangeSet(const Utils::ChangeSet &changeSet); - void appendIndentRange(const Range &range); - void appendReindentRange(const Range &range); void setOpenEditor(bool activate = false, int pos = -1); bool apply(); bool create(const QString &contents, bool reindent, bool openInEditor); + // TODO: Per EditOp? + void skipFormatting() { m_formattingEnabled = false; } + protected: // users may only get const access to RefactoringFiles created through // this constructor, because it can't be used to apply changes @@ -70,25 +72,15 @@ protected: RefactoringFile(const Utils::FilePath &filePath); void invalidate() { m_filePath.clear(); } - void enableFormatting() { m_formattingEnabled = true; } private: virtual void fileChanged() {} // derived classes may want to clear language specific extra data - virtual void indentSelection(const QTextCursor &selection, - const TextDocument *textDocument) const; - virtual void reindentSelection(const QTextCursor &selection, - const TextDocument *textDocument) const; - - enum IndentType {Indent, Reindent}; - void indentOrReindent(const RefactoringSelections &ranges, IndentType indent); + virtual Utils::Id indenterId() const { return {} ;} void setupFormattingRanges(const QList &replaceList); void doFormatting(); TextEditorWidget *openEditor(bool activate, int line, int column); - static RefactoringSelections rangesToSelections(QTextDocument *document, - const QList &ranges); - QTextDocument *mutableDocument() const; Utils::FilePath m_filePath; @@ -96,14 +88,12 @@ private: mutable QTextDocument *m_document = nullptr; TextEditorWidget *m_editor = nullptr; Utils::ChangeSet m_changes; - QList m_indentRanges; - QList m_reindentRanges; QList m_formattingCursors; bool m_openEditor = false; bool m_activateEditor = false; int m_editorCursorPosition = -1; bool m_appliedOnce = false; - bool m_formattingEnabled = false; + bool m_formattingEnabled = true; }; class TEXTEDITOR_EXPORT RefactoringFileFactory diff --git a/src/plugins/texteditor/tabsettings.cpp b/src/plugins/texteditor/tabsettings.cpp index e0c5142dcce..222335133d5 100644 --- a/src/plugins/texteditor/tabsettings.cpp +++ b/src/plugins/texteditor/tabsettings.cpp @@ -3,6 +3,9 @@ #include "tabsettings.h" +#include "icodestylepreferences.h" +#include "texteditorsettings.h" + #include #include #include @@ -347,4 +350,15 @@ bool TabSettings::equals(const TabSettings &ts) const && m_continuationAlignBehavior == ts.m_continuationAlignBehavior; } +static TabSettings::Retriever g_retriever = [](const FilePath &) { + return TextEditorSettings::codeStyle()->tabSettings(); +}; + +void TabSettings::setRetriever(const Retriever &retriever) { g_retriever = retriever; } + +TabSettings TabSettings::settingsForFile(const Utils::FilePath &filePath) +{ + return g_retriever(filePath); +} + } // namespace TextEditor diff --git a/src/plugins/texteditor/tabsettings.h b/src/plugins/texteditor/tabsettings.h index 9a446738d0c..6d9c08e6264 100644 --- a/src/plugins/texteditor/tabsettings.h +++ b/src/plugins/texteditor/tabsettings.h @@ -5,11 +5,14 @@ #include "texteditor_global.h" -#include +#include #include +#include #include +#include + namespace TextEditor { // Tab settings: Data type the GeneralSettingsPage acts on @@ -71,6 +74,10 @@ public: ContinuationAlignBehavior m_continuationAlignBehavior = ContinuationAlignWithSpaces; bool equals(const TabSettings &ts) const; + + using Retriever = std::function; + static void setRetriever(const Retriever &retriever); + static TabSettings settingsForFile(const Utils::FilePath &filePath); }; } // namespace TextEditor From 554bb75ad931f111060a5ec4e09b6ec8b92c0995 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Thu, 16 Nov 2023 13:26:16 +0100 Subject: [PATCH 0352/1546] Debugger: Fix assert when starting local debug When starting a local debugging session and the terminal is not used, no reason to assert that the remote pid is not valid etc. Change-Id: I1b62a98721425784ca80ce9261b07475c19f3ba1 Reviewed-by: hjk Reviewed-by: Christian Stenger Reviewed-by: --- src/plugins/debugger/lldb/lldbengine.cpp | 32 +++++++++++++----------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 12da7a86fc4..fa6fcae29c4 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -283,21 +283,23 @@ void LldbEngine::handleLldbStarted() cmd2.arg("attachpid", attachedPID); } else { cmd2.arg("startmode", rp.startMode); - // it is better not to check the start mode on the python sid (as we would have to duplicate the - // enum values), and thus we assume that if the rp.attachPID is valid we really have to attach - QTC_CHECK(rp.attachPID.isValid() && (rp.startMode == AttachToRemoteProcess - || rp.startMode == AttachToLocalProcess - || rp.startMode == AttachToRemoteServer)); - cmd2.arg("attachpid", rp.attachPID.pid()); - cmd2.arg("sysroot", rp.deviceSymbolsRoot.isEmpty() ? rp.sysRoot.toString() - : rp.deviceSymbolsRoot); - cmd2.arg("remotechannel", ((rp.startMode == AttachToRemoteProcess - || rp.startMode == AttachToRemoteServer) - ? rp.remoteChannel : QString())); - QTC_CHECK(!rp.continueAfterAttach || (rp.startMode == AttachToRemoteProcess - || rp.startMode == AttachToLocalProcess - || rp.startMode == AttachToRemoteServer)); - m_continueAtNextSpontaneousStop = false; + if (rp.startMode != StartInternal) { + // it is better not to check the start mode on the python sid (as we would have to duplicate the + // enum values), and thus we assume that if the rp.attachPID is valid we really have to attach + QTC_CHECK(rp.attachPID.isValid() && (rp.startMode == AttachToRemoteProcess + || rp.startMode == AttachToLocalProcess + || rp.startMode == AttachToRemoteServer)); + cmd2.arg("attachpid", rp.attachPID.pid()); + cmd2.arg("sysroot", rp.deviceSymbolsRoot.isEmpty() ? rp.sysRoot.toString() + : rp.deviceSymbolsRoot); + cmd2.arg("remotechannel", ((rp.startMode == AttachToRemoteProcess + || rp.startMode == AttachToRemoteServer) + ? rp.remoteChannel : QString())); + QTC_CHECK(!rp.continueAfterAttach || (rp.startMode == AttachToRemoteProcess + || rp.startMode == AttachToLocalProcess + || rp.startMode == AttachToRemoteServer)); + m_continueAtNextSpontaneousStop = false; + } } cmd2.callback = [this](const DebuggerResponse &response) { From 5733014ceba5ff82b091c3ec57580cbb2c1298e8 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Nov 2023 13:26:40 +0100 Subject: [PATCH 0353/1546] Squish: Re-organize wizard page setup Move things to new setup, inline stuff, code cosmetics. Change-Id: Ib521d93983d1cce3d8f52d49f1cd4e0fa64a622b Reviewed-by: Christian Stenger --- src/plugins/squish/squishplugin.cpp | 8 +- src/plugins/squish/squishwizardpages.cpp | 349 ++++++++++++++--------- src/plugins/squish/squishwizardpages.h | 116 +------- 3 files changed, 222 insertions(+), 251 deletions(-) diff --git a/src/plugins/squish/squishplugin.cpp b/src/plugins/squish/squishplugin.cpp index 7ed6a8c7290..acfd3e3d30e 100644 --- a/src/plugins/squish/squishplugin.cpp +++ b/src/plugins/squish/squishplugin.cpp @@ -44,11 +44,6 @@ public: ObjectsMapEditorFactory m_objectsMapEditorFactory; SquishOutputPane m_outputPane; SquishTools m_squishTools; - - SquishToolkitsPageFactory m_squishToolkitsPageFactory; - SquishScriptLanguagePageFactory m_squishScriptLanguagePageFactory; - SquishAUTPageFactory m_squishAUTPageFactory; - SquishGeneratorFactory m_squishGeneratorFactory; }; SquishPluginPrivate::SquishPluginPrivate() @@ -109,6 +104,9 @@ private: void initialize() final { d.reset(new SquishPluginPrivate); + + setupSquishWizardPages(); + ProjectExplorer::JsonWizardFactory::addWizardPath(":/squish/wizard/"); } diff --git a/src/plugins/squish/squishwizardpages.cpp b/src/plugins/squish/squishwizardpages.cpp index f812f0d4684..0ee6dab6b2c 100644 --- a/src/plugins/squish/squishwizardpages.cpp +++ b/src/plugins/squish/squishwizardpages.cpp @@ -10,8 +10,12 @@ #include +#include +#include + #include #include +#include #include #include @@ -22,28 +26,30 @@ #include #include -namespace Squish { -namespace Internal { +using namespace ProjectExplorer; +using namespace Utils; + +namespace Squish::Internal { /************************************ ToolkitsPage ***********************************************/ -SquishToolkitsPageFactory::SquishToolkitsPageFactory() +class SquishToolkitsPage final : public WizardPage { - setTypeIdsSuffix("SquishToolkits"); -} +public: + SquishToolkitsPage(); -Utils::WizardPage *SquishToolkitsPageFactory::create(ProjectExplorer::JsonWizard *, - Utils::Id typeId, const QVariant &) -{ - QTC_ASSERT(canCreate(typeId), return nullptr); - return new SquishToolkitsPage; -} + void initializePage() final; + bool isComplete() const final; + bool handleReject() final; -bool SquishToolkitsPageFactory::validateData(Utils::Id typeId, const QVariant &, QString *) -{ - QTC_ASSERT(canCreate(typeId), return false); - return true; -} +private: + void delayedInitialize(); + void fetchServerSettings(); + + QButtonGroup *m_buttonGroup = nullptr; + QLineEdit *m_hiddenLineEdit = nullptr; + InfoLabel *m_errorLabel = nullptr; +}; SquishToolkitsPage::SquishToolkitsPage() { @@ -66,11 +72,11 @@ SquishToolkitsPage::SquishToolkitsPage() groupBox->setLayout(buttonLayout); layout->addWidget(groupBox); - m_errorLabel = new Utils::InfoLabel(Tr::tr("Invalid Squish settings. Configure Squish " - "installation path inside " - "Preferences... > Squish > General to use " - "this wizard."), - Utils::InfoLabel::Error, this); + m_errorLabel = new InfoLabel(Tr::tr("Invalid Squish settings. Configure Squish " + "installation path inside " + "Preferences... > Squish > General to use " + "this wizard."), + InfoLabel::Error, this); m_errorLabel->setVisible(false); layout->addWidget(m_errorLabel); @@ -110,8 +116,8 @@ bool SquishToolkitsPage::handleReject() void SquishToolkitsPage::delayedInitialize() { - const Utils::FilePath server = settings().squishPath().pathAppended( - Utils::HostOsInfo::withExecutableSuffix("bin/squishserver")); + const FilePath server = settings().squishPath().pathAppended( + HostOsInfo::withExecutableSuffix("bin/squishserver")); if (server.isExecutableFile()) fetchServerSettings(); else @@ -148,88 +154,113 @@ void SquishToolkitsPage::fetchServerSettings() }); } +class SquishToolkitsPageFactory final : public JsonWizardPageFactory +{ +public: + SquishToolkitsPageFactory() + { + setTypeIdsSuffix("SquishToolkits"); + } + + WizardPage *create(JsonWizard *wizard, Id typeId, const QVariant &data) final + { + Q_UNUSED(wizard) + Q_UNUSED(data) + QTC_ASSERT(canCreate(typeId), return nullptr); + return new SquishToolkitsPage; + } + + bool validateData(Id typeId, const QVariant &data, QString *errorMessage) final + { + Q_UNUSED(data) + Q_UNUSED(errorMessage) + QTC_ASSERT(canCreate(typeId), return false); + return true; + } +}; + /********************************* ScriptLanguagePage ********************************************/ -SquishScriptLanguagePageFactory::SquishScriptLanguagePageFactory() +class SquishScriptLanguagePage final : public WizardPage { - setTypeIdsSuffix("SquishScriptLanguage"); -} +public: + SquishScriptLanguagePage() + { + setTitle(Tr::tr("Create New Squish Test Suite")); -Utils::WizardPage *SquishScriptLanguagePageFactory::create(ProjectExplorer::JsonWizard *, - Utils::Id typeId, const QVariant &) -{ - QTC_ASSERT(canCreate(typeId), return nullptr); - return new SquishScriptLanguagePage; -} + auto layout = new QHBoxLayout(this); + auto groupBox = new QGroupBox(Tr::tr("Available languages:"), this); + auto buttonLayout = new QVBoxLayout(groupBox); -bool SquishScriptLanguagePageFactory::validateData(Utils::Id typeId, const QVariant &, QString *) -{ - QTC_ASSERT(canCreate(typeId), return false); - return true; -} - -SquishScriptLanguagePage::SquishScriptLanguagePage() -{ - setTitle(Tr::tr("Create New Squish Test Suite")); - - auto layout = new QHBoxLayout(this); - auto groupBox = new QGroupBox(Tr::tr("Available languages:"), this); - auto buttonLayout = new QVBoxLayout(groupBox); - - auto buttonGroup = new QButtonGroup(this); - buttonGroup->setExclusive(true); - const QStringList languages = { "JavaScript", "Perl", "Python", "Ruby", "Tcl" }; - for (const QString &language : languages) { - auto button = new QRadioButton(language, this); - button->setChecked(language.startsWith('J')); - buttonGroup->addButton(button); - buttonLayout->addWidget(button); - } - groupBox->setLayout(buttonLayout); - - layout->addWidget(groupBox); - auto hiddenLineEdit = new QLineEdit(this); - hiddenLineEdit->setVisible(false); - layout->addWidget(hiddenLineEdit); - - connect(buttonGroup, &QButtonGroup::buttonToggled, - this, [this, hiddenLineEdit](QAbstractButton *button, bool checked) { - if (checked) { - hiddenLineEdit->setText(button->text()); - emit completeChanged(); + auto buttonGroup = new QButtonGroup(this); + buttonGroup->setExclusive(true); + const QStringList languages = { "JavaScript", "Perl", "Python", "Ruby", "Tcl" }; + for (const QString &language : languages) { + auto button = new QRadioButton(language, this); + button->setChecked(language.startsWith('J')); + buttonGroup->addButton(button); + buttonLayout->addWidget(button); } - }); - registerFieldWithName("ChosenLanguage", hiddenLineEdit); - hiddenLineEdit->setText(buttonGroup->checkedButton()->text()); -} + groupBox->setLayout(buttonLayout); + + layout->addWidget(groupBox); + auto hiddenLineEdit = new QLineEdit(this); + hiddenLineEdit->setVisible(false); + layout->addWidget(hiddenLineEdit); + + connect(buttonGroup, &QButtonGroup::buttonToggled, + this, [this, hiddenLineEdit](QAbstractButton *button, bool checked) { + if (checked) { + hiddenLineEdit->setText(button->text()); + emit completeChanged(); + } + }); + registerFieldWithName("ChosenLanguage", hiddenLineEdit); + hiddenLineEdit->setText(buttonGroup->checkedButton()->text()); + } +}; + +class SquishScriptLanguagePageFactory final : public JsonWizardPageFactory +{ +public: + SquishScriptLanguagePageFactory() + { + setTypeIdsSuffix("SquishScriptLanguage"); + } + + WizardPage *create(JsonWizard *wizard, Id typeId, const QVariant &data) final + { + Q_UNUSED(wizard) + Q_UNUSED(data) + QTC_ASSERT(canCreate(typeId), return nullptr); + return new SquishScriptLanguagePage; + } + bool validateData(Id typeId, const QVariant &, QString *) final + { + QTC_ASSERT(canCreate(typeId), return false); + return true; + } +}; + /************************************* AUTPage ***************************************************/ -SquishAUTPageFactory::SquishAUTPageFactory() +class SquishAUTPage final : public WizardPage { - setTypeIdsSuffix("SquishAUT"); -} +public: + SquishAUTPage() + { + auto layout = new QVBoxLayout(this); + m_autCombo = new QComboBox(this); + layout->addWidget(m_autCombo); + registerFieldWithName("ChosenAUT", m_autCombo, "currentText"); + } -Utils::WizardPage *SquishAUTPageFactory::create(ProjectExplorer::JsonWizard *, Utils::Id typeId, - const QVariant &) -{ - QTC_ASSERT(canCreate(typeId), return nullptr); - return new SquishAUTPage; -} + void initializePage() final; -bool SquishAUTPageFactory::validateData(Utils::Id typeId, const QVariant &, QString *) -{ - QTC_ASSERT(canCreate(typeId), return false); - return true; -} - -SquishAUTPage::SquishAUTPage() -{ - auto layout = new QVBoxLayout(this); - m_autCombo = new QComboBox(this); - layout->addWidget(m_autCombo); - registerFieldWithName("ChosenAUT", m_autCombo, "currentText"); -} +private: + QComboBox *m_autCombo = nullptr; +}; void SquishAUTPage::initializePage() { @@ -239,41 +270,49 @@ void SquishAUTPage::initializePage() m_autCombo->setCurrentIndex(0); } +class SquishAUTPageFactory final : public JsonWizardPageFactory +{ +public: + SquishAUTPageFactory() + { + setTypeIdsSuffix("SquishAUT"); + } + + WizardPage *create(JsonWizard *wizard, Id typeId, const QVariant &data) final + { + Q_UNUSED(wizard) + Q_UNUSED(data); + QTC_ASSERT(canCreate(typeId), return nullptr); + return new SquishAUTPage; + } + + bool validateData(Id typeId, const QVariant &data, QString *errorMessage) final + { + Q_UNUSED(data) + Q_UNUSED(errorMessage) + QTC_ASSERT(canCreate(typeId), return false); + return true; + } +}; + /********************************* SquishSuiteGenerator ******************************************/ -SquishGeneratorFactory::SquishGeneratorFactory() +class SquishFileGenerator final : public JsonWizardGenerator { - setTypeIdsSuffix("SquishSuiteGenerator"); -} +public: + bool setup(const QVariant &data, QString *errorMessage); + Core::GeneratedFiles fileList(MacroExpander *expander, + const FilePath &wizardDir, + const FilePath &projectDir, + QString *errorMessage) final; + bool writeFile(const ProjectExplorer::JsonWizard *wizard, Core::GeneratedFile *file, + QString *errorMessage) final; + bool allDone(const ProjectExplorer::JsonWizard *wizard, Core::GeneratedFile *file, + QString *errorMessage) final; -ProjectExplorer::JsonWizardGenerator *SquishGeneratorFactory::create(Utils::Id typeId, - const QVariant &data, - const QString &, - Utils::Id, - const QVariantMap &) -{ - QTC_ASSERT(canCreate(typeId), return nullptr); - - auto generator = new SquishFileGenerator; - QString errorMessage; - generator->setup(data, &errorMessage); - - if (!errorMessage.isEmpty()) { - qWarning() << "SquishSuiteGenerator setup error:" << errorMessage; - delete generator; - return nullptr; - } - return generator; -} - -bool SquishGeneratorFactory::validateData(Utils::Id typeId, const QVariant &data, - QString *errorMessage) -{ - QTC_ASSERT(canCreate(typeId), return false); - - QScopedPointer generator(new SquishFileGenerator); - return generator->setup(data, errorMessage); -} +private: + QString m_mode; +}; bool SquishFileGenerator::setup(const QVariant &data, QString *errorMessage) { @@ -316,9 +355,9 @@ static QString generateSuiteConf(const QString &aut, const QString &language, return content; } -Core::GeneratedFiles SquishFileGenerator::fileList(Utils::MacroExpander *expander, - const Utils::FilePath &wizardDir, - const Utils::FilePath &projectDir, +Core::GeneratedFiles SquishFileGenerator::fileList(MacroExpander *expander, + const FilePath &wizardDir, + const FilePath &projectDir, QString *errorMessage) { Q_UNUSED(wizardDir) @@ -332,12 +371,12 @@ Core::GeneratedFiles SquishFileGenerator::fileList(Utils::MacroExpander *expande aut = QString('"' + aut + '"'); const QString lang = expander->expand(QString{"%{Language}"}); const QString toolkit = expander->expand(QString{"%{Toolkit}"});; - const Utils::FilePath suiteConf = projectDir.pathAppended("suite.conf"); + const FilePath suiteConf = projectDir.pathAppended("suite.conf"); Core::GeneratedFiles result; if (expander->expand(QString{"%{VersionControl}"}) == "G.Git") { Core::GeneratedFile gitignore(projectDir.pathAppended(".gitignore")); - const Utils::FilePath orig = Core::ICore::resourcePath() + const FilePath orig = Core::ICore::resourcePath() .pathAppended("templates/wizards/projects/git.ignore"); if (QTC_GUARD(orig.exists())) { @@ -353,7 +392,7 @@ Core::GeneratedFiles SquishFileGenerator::fileList(Utils::MacroExpander *expande return result; } -bool SquishFileGenerator::writeFile(const ProjectExplorer::JsonWizard *, +bool SquishFileGenerator::writeFile(const JsonWizard *, Core::GeneratedFile *file, QString *errorMessage) { @@ -364,7 +403,7 @@ bool SquishFileGenerator::writeFile(const ProjectExplorer::JsonWizard *, return true; } -bool SquishFileGenerator::allDone(const ProjectExplorer::JsonWizard *wizard, +bool SquishFileGenerator::allDone(const JsonWizard *wizard, Core::GeneratedFile *file, QString *errorMessage) { Q_UNUSED(wizard) @@ -378,6 +417,50 @@ bool SquishFileGenerator::allDone(const ProjectExplorer::JsonWizard *wizard, return true; } +class SquishGeneratorFactory final : public JsonWizardGeneratorFactory +{ +public: + SquishGeneratorFactory() + { + setTypeIdsSuffix("SquishSuiteGenerator"); + } -} // namespace Internal -} // namespace Squish + JsonWizardGenerator *create(Id typeId, const QVariant &data, + const QString &path, Id platform, + const QVariantMap &variables) final + { + Q_UNUSED(path) + Q_UNUSED(platform) + Q_UNUSED(variables) + QTC_ASSERT(canCreate(typeId), return nullptr); + + auto generator = new SquishFileGenerator; + QString errorMessage; + generator->setup(data, &errorMessage); + + if (!errorMessage.isEmpty()) { + qWarning() << "SquishSuiteGenerator setup error:" << errorMessage; + delete generator; + return nullptr; + } + return generator; + } + + bool validateData(Id typeId, const QVariant &data, QString *errorMessage) final + { + QTC_ASSERT(canCreate(typeId), return false); + + QScopedPointer generator(new SquishFileGenerator); + return generator->setup(data, errorMessage); + } +}; + +void setupSquishWizardPages() +{ + static SquishToolkitsPageFactory theSquishToolkitsPageFactory; + static SquishScriptLanguagePageFactory theSquishScriptLanguagePageFactory; + static SquishAUTPageFactory theSquishAUTPageFactory; + static SquishGeneratorFactory theSquishGeneratorFactory; +} + +} // Squish::Internal diff --git a/src/plugins/squish/squishwizardpages.h b/src/plugins/squish/squishwizardpages.h index 84dda86ee7f..15f5e832cc9 100644 --- a/src/plugins/squish/squishwizardpages.h +++ b/src/plugins/squish/squishwizardpages.h @@ -3,118 +3,8 @@ #pragma once -#include -#include -#include +namespace Squish::Internal { -QT_BEGIN_NAMESPACE -class QButtonGroup; -class QComboBox; -class QLineEdit; -QT_END_NAMESPACE +void setupSquishWizardPages(); -namespace Utils { class InfoLabel; } - -namespace Squish { -namespace Internal { - -class SquishToolkitsPageFactory : public ProjectExplorer::JsonWizardPageFactory -{ -public: - SquishToolkitsPageFactory(); - - Utils::WizardPage *create(ProjectExplorer::JsonWizard *wizard, Utils::Id typeId, - const QVariant &data) override; - bool validateData(Utils::Id typeId, const QVariant &data, QString *errorMessage) override; -}; - -class SquishToolkitsPage : public Utils::WizardPage -{ - Q_OBJECT -public: - SquishToolkitsPage(); - ~SquishToolkitsPage() = default; - - void initializePage() override; - bool isComplete() const override; - bool handleReject() override; - -private: - void delayedInitialize(); - void fetchServerSettings(); - - QButtonGroup *m_buttonGroup = nullptr; - QLineEdit *m_hiddenLineEdit = nullptr; - Utils::InfoLabel *m_errorLabel = nullptr; -}; - -class SquishScriptLanguagePageFactory : public ProjectExplorer::JsonWizardPageFactory -{ -public: - SquishScriptLanguagePageFactory(); - - Utils::WizardPage *create(ProjectExplorer::JsonWizard *wizard, Utils::Id typeId, - const QVariant &data) override; - bool validateData(Utils::Id typeId, const QVariant &data, QString *errorMessage) override; -}; - -class SquishScriptLanguagePage : public Utils::WizardPage -{ - Q_OBJECT -public: - SquishScriptLanguagePage(); - ~SquishScriptLanguagePage() = default; -}; - -class SquishAUTPageFactory : public ProjectExplorer::JsonWizardPageFactory -{ -public: - SquishAUTPageFactory(); - - Utils::WizardPage *create(ProjectExplorer::JsonWizard *wizard, Utils::Id typeId, - const QVariant &data) override; - bool validateData(Utils::Id typeId, const QVariant &data, QString *errorMessage) override; -}; - -class SquishAUTPage : public Utils::WizardPage -{ - Q_OBJECT -public: - SquishAUTPage(); - ~SquishAUTPage() = default; - - void initializePage() override; -private: - QComboBox *m_autCombo = nullptr; -}; - -class SquishGeneratorFactory : public ProjectExplorer::JsonWizardGeneratorFactory -{ -public: - SquishGeneratorFactory(); - - ProjectExplorer::JsonWizardGenerator *create(Utils::Id typeId, const QVariant &data, - const QString &path, Utils::Id platform, - const QVariantMap &variables) override; - bool validateData(Utils::Id typeId, const QVariant &data, QString *errorMessage) override; -}; - -class SquishFileGenerator : public ProjectExplorer::JsonWizardGenerator -{ -public: - bool setup(const QVariant &data, QString *errorMessage); - Core::GeneratedFiles fileList(Utils::MacroExpander *expander, - const Utils::FilePath &wizardDir, - const Utils::FilePath &projectDir, - QString *errorMessage) override; - bool writeFile(const ProjectExplorer::JsonWizard *wizard, Core::GeneratedFile *file, - QString *errorMessage) override; - bool allDone(const ProjectExplorer::JsonWizard *wizard, Core::GeneratedFile *file, - QString *errorMessage) override; - -private: - QString m_mode; -}; - -} // namespace Internal -} // namespace Squish +} // Squish::Internal From ef717b9f22bcb7439b68350af37822b9f10d9a34 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Nov 2023 13:34:32 +0100 Subject: [PATCH 0354/1546] Squish: Use ActionBuilder Change-Id: Ie193b82cffa1e7bd0ddb45d11885212e1f119f65 Reviewed-by: Christian Stenger --- src/plugins/squish/squishplugin.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/plugins/squish/squishplugin.cpp b/src/plugins/squish/squishplugin.cpp index acfd3e3d30e..38b0b1ad8ad 100644 --- a/src/plugins/squish/squishplugin.cpp +++ b/src/plugins/squish/squishplugin.cpp @@ -50,14 +50,15 @@ SquishPluginPrivate::SquishPluginPrivate() { qRegisterMetaType("SquishResultItem*"); - ActionContainer *menu = ActionManager::createMenu("Squish.Menu"); + const Id menuId = "Squish.Menu"; + ActionContainer *menu = ActionManager::createMenu(menuId); menu->menu()->setTitle(Tr::tr("&Squish")); menu->setOnAllDisabledBehavior(ActionContainer::Show); - QAction *action = new QAction(Tr::tr("&Server Settings..."), this); - Command *command = ActionManager::registerAction(action, "Squish.ServerSettings"); - menu->addAction(command); - connect(action, &QAction::triggered, this, [] { + ActionBuilder serverSettings(this, "Squish.ServerSettings"); + serverSettings.setText(Tr::tr("&Server Settings...")); + serverSettings.setContainer(menuId); + serverSettings.setOnTriggered(this, [] { if (!settings().squishPath().exists()) { SquishMessages::criticalMessage(Tr::tr("Invalid Squish settings. Configure Squish " "installation path inside " From 229c23ce3918f3ba19c3944dbe03b24fff6bea34 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Tue, 21 Nov 2023 23:36:25 +0100 Subject: [PATCH 0355/1546] TaskTree: Add docs for Storage element Change-Id: I4faa691a8f6ad7f358a508ba25b60d1ea7476afd Reviewed-by: hjk Reviewed-by: Leena Miettinen --- src/libs/solutions/tasking/tasktree.cpp | 149 ++++++++++++++++++++++++ 1 file changed, 149 insertions(+) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index 7edc0f36bdc..fe8dc4c5c96 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -163,6 +163,155 @@ private: Returns the \c const pointer to the associated \c Task instance. */ +/*! + \class Tasking::Storage + \inheaderfile solutions/tasking/tasktree.h + \inmodule TaskingSolution + \brief A class template for custom data exchange in the running task tree. + \reentrant + + The Storage class template is responsible for dynamically creating and destructing objects + of the custom \c StorageStruct type. The creation and destruction are managed by the + running task tree. If a Storage object is placed inside a \l {Tasking::Group} {Group} element, + the running task tree creates the \c StorageStruct object when the group is started and before + the group's setup handler is called. Later, whenever any handler inside this group is called, + the task tree activates the previously created instance of the \c StorageStruct object. + This includes all tasks' and groups' setup and done handlers inside the group where the + Storage object was placed, also within the nested groups. + When a copy of the Storage object is passed to the handler via the lambda capture, + the handler may access the instance activated by the running task tree via the + Storage::operator->(), Storage::operator*(), or Storage::activeStorage() method. + If two handlers capture the same Storage object, one of them may store a custom data there, + and the other may read it afterwards. + When the group is finished, the previously created instance of the \c StorageStruct + object is destroyed after the group's done handler is called. + + An example of data exchange between tasks: + + \code + const Storage storage; + + const auto onFirstDone = [storage](const Task &task) { + // Assings QString, taken from the first task result, to the active QString instance + // of the Storage object. + *storage = task.getResultAsString(); + }; + + const auto onSecondSetup = [storage](Task &task) { + // Reads QString from the active QString instance of the Storage object and use it to + // configure the second task before start. + task.configureWithString(*storage); + }; + + const Group root { + // The running task tree creates QString instance when root in entered + storage, + // The done handler of the first task stores the QString in the storage + TaskItem(..., onFirstDone), + // The setup handler of the second task reads the QString from the storage + TaskItem(onSecondSetup, ...) + }; + \endcode + + Since the root group executes its tasks sequentially, the \c onFirstDone handler + is always called before the \c onSecondSetup handler. This means that the QString data, + read from the \c storage inside the \c onSecondSetup handler's body, + has already been set by the \c onFirstDone handler. + You can always rely on it in \l {Tasking::sequential} {sequential} execution mode. + + The Storage internals are shared between all of its copies. That is why the copies of the + Storage object inside the handlers' lambda captures still refer to the same Storage instance. + You may place multiple Storage objects inside one \l {Tasking::Group} {Group} element, + provided that they do not include copies of the same Storage object. + Otherwise, an assert is triggered at runtime that includes an error message. + However, you can place copies of the same Storage object in different + \l {Tasking::Group} {Group} elements of the same recipe. In this case, the running task + tree will create multiple instances of the \c StorageStruct objects (one for each copy) + and storage shadowing will take place. Storage shadowing works in a similar way + to C++ variable shadowing inside the nested blocks of code: + + \code + Storage storage; + + const Group root { + storage, // Top copy, 1st instance of StorageStruct + onGroupSetup([storage] { ... }), // Top copy is active + Group { + storage, // Nested copy, 2nd instance of StorageStruct, + // shadows Top copy + onGroupSetup([storage] { ... }), // Nested copy is active + }, + Group { + onGroupSetup([storage] { ... }), // Top copy is active + } + }; + \endcode + + The Storage objects may also be used for passing the initial data to the executed task tree, + and for reading the final data out of the task tree before it finishes. + To do this, use \l {TaskTree::onStorageSetup()} {onStorageSetup()} or + \l {TaskTree::onStorageDone()} {onStorageDone()}, respectively. + + \note If you use an unreachable Storage object inside the handler, + because you forgot to place the storage in the recipe, + or placed it, but not in any handler's ancestor group, + you may expect a crash, preceded by the following message: + \e {The referenced storage is not reachable in the running tree. + A nullptr will be returned which might lead to a crash in the calling code. + It is possible that no storage was added to the tree, + or the storage is not reachable from where it is referenced.} +*/ + +/*! + \fn template Storage::Storage() + + Creates a storage for the given \c StorageStruct type. + + \note All copies of \c this object are considered to be the same Storage instance. +*/ + +/*! + \fn template StorageStruct &Storage::operator*() const noexcept + + Returns a \e reference to the active \c StorageStruct object, created by the running task tree. + Use this function only from inside the handler body of any GroupItem element placed + in the recipe, otherwise you may expect a crash. + Make sure that Storage is placed in any group ancestor of the handler's group item. + + \note The returned reference is valid as long as the group that created this instance + is still running. + + \sa activeStorage(), operator->() +*/ + +/*! + \fn template StorageStruct *Storage::operator->() const noexcept + + Returns a \e pointer to the active \c StorageStruct object, created by the running task tree. + Use this function only from inside the handler body of any GroupItem element placed + in the recipe, otherwise you may expect a crash. + Make sure that Storage is placed in any group ancestor of the handler's group item. + + \note The returned pointer is valid as long as the group that created this instance + is still running. + + \sa activeStorage(), operator*() +*/ + +/*! + \fn template StorageStruct *Storage::activeStorage() const + + Returns a \e pointer to the active \c StorageStruct object, created by the running task tree. + Use this function only from inside the handler body of any GroupItem element placed + in the recipe, otherwise you may expect a crash. + Make sure that Storage is placed in any group ancestor of the handler's group item. + + \note The returned pointer is valid as long as the group that created this instance + is still running. + + \sa operator->(), operator*() +*/ + /*! \class Tasking::GroupItem \inheaderfile solutions/tasking/tasktree.h From 27d265137f882ff3301a1bc4ecb98fa62693289d Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Nov 2023 13:55:15 +0100 Subject: [PATCH 0356/1546] Beautifier: Move ArtisticStyle to new setup scheme Change-Id: I186fcbff69976f980c43d8bc887b5f76fb7f4916 Reviewed-by: Jarek Kobus --- .../artisticstyle/artisticstyle.cpp | 196 +++++++++--------- .../beautifier/artisticstyle/artisticstyle.h | 24 +-- src/plugins/beautifier/beautifierplugin.cpp | 3 +- 3 files changed, 106 insertions(+), 117 deletions(-) diff --git a/src/plugins/beautifier/artisticstyle/artisticstyle.cpp b/src/plugins/beautifier/artisticstyle/artisticstyle.cpp index c6ac2bfe19f..fb7dd8d33a0 100644 --- a/src/plugins/beautifier/artisticstyle/artisticstyle.cpp +++ b/src/plugins/beautifier/artisticstyle/artisticstyle.cpp @@ -53,7 +53,7 @@ static QString asDisplayName() { return Tr::tr("Artistic Style"); } const char SETTINGS_NAME[] = "artisticstyle"; -class ArtisticStyleSettings : public AbstractSettings +class ArtisticStyleSettings final : public AbstractSettings { public: ArtisticStyleSettings() @@ -93,7 +93,7 @@ public: read(); } - void createDocumentationFile() const override + void createDocumentationFile() const final { Process process; process.setTimeoutS(2); @@ -180,7 +180,7 @@ static ArtisticStyleSettings &settings() return theSettings; } -// ArtisticStyleOptionsPage +// ArtisticStyleSettingsPage class ArtisticStyleSettingsPageWidget : public Core::IOptionsPageWidget { @@ -232,113 +232,118 @@ public: } }; -// Style +// ArtisticStyle -ArtisticStyle::ArtisticStyle() +class ArtisticStyle final : public BeautifierTool { - const Id menuId = "ArtisticStyle.Menu"; - Core::ActionContainer *menu = Core::ActionManager::createMenu(menuId); - menu->menu()->setTitle(Tr::tr("&Artistic Style")); +public: + ArtisticStyle() + { + const Id menuId = "ArtisticStyle.Menu"; + Core::ActionContainer *menu = Core::ActionManager::createMenu(menuId); + menu->menu()->setTitle(Tr::tr("&Artistic Style")); - Core::ActionBuilder formatFile(this, "ArtisticStyle.FormatFile"); - formatFile.setText(msgFormatCurrentFile()); - formatFile.bindContextAction(&m_formatFile); - formatFile.setContainer(menuId); - formatFile.setOnTriggered(this, [this] { this->formatFile(); }); + Core::ActionBuilder formatFile(this, "ArtisticStyle.FormatFile"); + formatFile.setText(msgFormatCurrentFile()); + formatFile.bindContextAction(&m_formatFile); + formatFile.setContainer(menuId); + formatFile.setOnTriggered(this, [this] { this->formatFile(); }); - Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu); + Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu); - connect(&settings().supportedMimeTypes, &Utils::BaseAspect::changed, - this, [this] { updateActions(Core::EditorManager::currentEditor()); }); -} + connect(&settings().supportedMimeTypes, &Utils::BaseAspect::changed, + this, [this] { updateActions(Core::EditorManager::currentEditor()); }); + } -QString ArtisticStyle::id() const -{ - return "Artistic Style"; -} + QString id() const final + { + return "Artistic Style"; + } -void ArtisticStyle::updateActions(Core::IEditor *editor) -{ - m_formatFile->setEnabled(editor && settings().isApplicable(editor->document())); -} + void updateActions(Core::IEditor *editor) final + { + m_formatFile->setEnabled(editor && settings().isApplicable(editor->document())); + } -void ArtisticStyle::formatFile() -{ - const FilePath cfgFileName = configurationFile(); - if (cfgFileName.isEmpty()) - showError(BeautifierTool::msgCannotGetConfigurationFile(asDisplayName())); - else - formatCurrentFile(textCommand(cfgFileName.toFSPathString())); -} + Command textCommand() const final + { + const FilePath cfgFile = configurationFile(); + return cfgFile.isEmpty() ? Command() : textCommand(cfgFile.toFSPathString()); + } -FilePath ArtisticStyle::configurationFile() const -{ - if (settings().useCustomStyle()) - return settings().styleFileName(settings().customStyle()); + bool isApplicable(const Core::IDocument *document) const final + { + return settings().isApplicable(document); + } - if (settings().useOtherFiles()) { - if (const ProjectExplorer::Project *project + void formatFile() + { + const FilePath cfgFileName = configurationFile(); + if (cfgFileName.isEmpty()) + showError(BeautifierTool::msgCannotGetConfigurationFile(asDisplayName())); + else + formatCurrentFile(textCommand(cfgFileName.toFSPathString())); + } + + FilePath configurationFile() const + { + if (settings().useCustomStyle()) + return settings().styleFileName(settings().customStyle()); + + if (settings().useOtherFiles()) { + if (const ProjectExplorer::Project *project = ProjectExplorer::ProjectTree::currentProject()) { - const FilePaths astyleRcfiles = project->files( - [](const ProjectExplorer::Node *n) { return n->filePath().endsWith(".astylerc"); }); - for (const FilePath &file : astyleRcfiles) { - if (file.isReadableFile()) - return file; + const FilePaths astyleRcfiles = project->files( + [](const ProjectExplorer::Node *n) { return n->filePath().endsWith(".astylerc"); }); + for (const FilePath &file : astyleRcfiles) { + if (file.isReadableFile()) + return file; + } } } + + if (settings().useSpecificConfigFile()) { + const FilePath file = settings().specificConfigFile(); + if (file.exists()) + return file; + } + + if (settings().useHomeFile()) { + const FilePath homeDirectory = FileUtils::homePath(); + FilePath file = homeDirectory / ".astylerc"; + if (file.exists()) + return file; + file = homeDirectory / "astylerc"; + if (file.exists()) + return file; + } + + return {}; } - if (settings().useSpecificConfigFile()) { - const FilePath file = settings().specificConfigFile(); - if (file.exists()) - return file; + Command textCommand(const QString &cfgFile) const + { + Command cmd; + cmd.setExecutable(settings().command()); + cmd.addOption("-q"); + cmd.addOption("--options=" + cfgFile); + + const QVersionNumber version = settings().version(); + if (version > QVersionNumber(2, 3)) { + cmd.setProcessing(Command::PipeProcessing); + if (version == QVersionNumber(2, 4)) + cmd.setPipeAddsNewline(true); + cmd.setReturnsCRLF(Utils::HostOsInfo::isWindowsHost()); + cmd.addOption("-z2"); + } else { + cmd.addOption("%file"); + } + + return cmd; } - if (settings().useHomeFile()) { - const FilePath homeDirectory = FileUtils::homePath(); - FilePath file = homeDirectory / ".astylerc"; - if (file.exists()) - return file; - file = homeDirectory / "astylerc"; - if (file.exists()) - return file; - } - - return {}; -} - -Command ArtisticStyle::textCommand() const -{ - const FilePath cfgFile = configurationFile(); - return cfgFile.isEmpty() ? Command() : textCommand(cfgFile.toFSPathString()); -} - -bool ArtisticStyle::isApplicable(const Core::IDocument *document) const -{ - return settings().isApplicable(document); -} - -Command ArtisticStyle::textCommand(const QString &cfgFile) const -{ - Command cmd; - cmd.setExecutable(settings().command()); - cmd.addOption("-q"); - cmd.addOption("--options=" + cfgFile); - - const QVersionNumber version = settings().version(); - if (version > QVersionNumber(2, 3)) { - cmd.setProcessing(Command::PipeProcessing); - if (version == QVersionNumber(2, 4)) - cmd.setPipeAddsNewline(true); - cmd.setReturnsCRLF(Utils::HostOsInfo::isWindowsHost()); - cmd.addOption("-z2"); - } else { - cmd.addOption("%file"); - } - - return cmd; -} - + QAction *m_formatFile = nullptr; +}; // ArtisticStyleSettingsPage @@ -356,4 +361,9 @@ public: const ArtisticStyleSettingsPage settingsPage; +void setupArtisticStyle() +{ + static ArtisticStyle theArtisticStyle; +} + } // Beautifier::Internal diff --git a/src/plugins/beautifier/artisticstyle/artisticstyle.h b/src/plugins/beautifier/artisticstyle/artisticstyle.h index 2a20b7f1f2f..56f61d348fb 100644 --- a/src/plugins/beautifier/artisticstyle/artisticstyle.h +++ b/src/plugins/beautifier/artisticstyle/artisticstyle.h @@ -3,30 +3,8 @@ #pragma once -#include "../beautifiertool.h" - -QT_BEGIN_NAMESPACE -class QAction; -QT_END_NAMESPACE - namespace Beautifier::Internal { -class ArtisticStyle : public BeautifierTool -{ -public: - ArtisticStyle(); - - QString id() const override; - void updateActions(Core::IEditor *editor) override; - TextEditor::Command textCommand() const override; - bool isApplicable(const Core::IDocument *document) const override; - -private: - void formatFile(); - Utils::FilePath configurationFile() const; - TextEditor::Command textCommand(const QString &cfgFile) const; - - QAction *m_formatFile = nullptr; -}; +void setupArtisticStyle(); } // Beautifier::Internal diff --git a/src/plugins/beautifier/beautifierplugin.cpp b/src/plugins/beautifier/beautifierplugin.cpp index 4e780729175..e5929392836 100644 --- a/src/plugins/beautifier/beautifierplugin.cpp +++ b/src/plugins/beautifier/beautifierplugin.cpp @@ -65,7 +65,6 @@ public: void autoFormatOnSave(IDocument *document); - ArtisticStyle artisticStyleBeautifier; ClangFormat clangFormatBeautifier; Uncrustify uncrustifyBeautifier; }; @@ -141,6 +140,8 @@ class BeautifierPlugin final : public ExtensionSystem::IPlugin menu->menu()->setTitle(Tr::tr("Bea&utifier")); menu->setOnAllDisabledBehavior(ActionContainer::Show); ActionManager::actionContainer(Core::Constants::M_TOOLS)->addMenu(menu); + + setupArtisticStyle(); } void extensionsInitialized() final From 8ceaa67ea8b1a168767d4f70d2c542cdc6cd0697 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Nov 2023 14:58:56 +0100 Subject: [PATCH 0357/1546] Beautifier: New setup also for ClangFormat and Uncrustify Change-Id: I338e8947c09219f6a35d1361f2e10f8264b37ad3 Reviewed-by: Jarek Kobus --- src/plugins/beautifier/beautifierplugin.cpp | 6 +- .../beautifier/clangformat/clangformat.cpp | 119 +++++++++++------- .../beautifier/clangformat/clangformat.h | 30 +---- .../beautifier/uncrustify/uncrustify.cpp | 99 +++++++++------ .../beautifier/uncrustify/uncrustify.h | 26 +--- 5 files changed, 134 insertions(+), 146 deletions(-) diff --git a/src/plugins/beautifier/beautifierplugin.cpp b/src/plugins/beautifier/beautifierplugin.cpp index e5929392836..7972fc67773 100644 --- a/src/plugins/beautifier/beautifierplugin.cpp +++ b/src/plugins/beautifier/beautifierplugin.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "beautifierconstants.h" +#include "beautifiertool.h" #include "beautifiertr.h" #include "generalsettings.h" @@ -64,9 +65,6 @@ public: void updateActions(IEditor *editor = nullptr); void autoFormatOnSave(IDocument *document); - - ClangFormat clangFormatBeautifier; - Uncrustify uncrustifyBeautifier; }; BeautifierPluginPrivate::BeautifierPluginPrivate() @@ -142,6 +140,8 @@ class BeautifierPlugin final : public ExtensionSystem::IPlugin ActionManager::actionContainer(Core::Constants::M_TOOLS)->addMenu(menu); setupArtisticStyle(); + setupClangFormat(); + setupUncrustify(); } void extensionsInitialized() final diff --git a/src/plugins/beautifier/clangformat/clangformat.cpp b/src/plugins/beautifier/clangformat/clangformat.cpp index 6a31cbb374a..9e4721da04e 100644 --- a/src/plugins/beautifier/clangformat/clangformat.cpp +++ b/src/plugins/beautifier/clangformat/clangformat.cpp @@ -92,19 +92,19 @@ public: read(); } - void createDocumentationFile() const override; + void createDocumentationFile() const final; - QStringList completerWords() override; + QStringList completerWords() final; BoolAspect usePredefinedStyle{this}; SelectionAspect predefinedStyle{this}; SelectionAspect fallbackStyle{this}; StringAspect customStyle{this}; - Utils::FilePath styleFileName(const QString &key) const override; + Utils::FilePath styleFileName(const QString &key) const final; private: - void readStyles() override; + void readStyles() final; }; void ClangFormatSettings::createDocumentationFile() const @@ -310,53 +310,77 @@ public: // ClangFormat -ClangFormat::ClangFormat() +class ClangFormat final : public BeautifierTool { - const Id menuId = "ClangFormat.Menu"; - Core::ActionContainer *menu = Core::ActionManager::createMenu(menuId); - menu->menu()->setTitle(Tr::tr("&ClangFormat")); +public: + ClangFormat() + { + const Id menuId = "ClangFormat.Menu"; + Core::ActionContainer *menu = Core::ActionManager::createMenu(menuId); + menu->menu()->setTitle(Tr::tr("&ClangFormat")); - Core::ActionBuilder formatFile(this, "ClangFormat.FormatFile"); - formatFile.setText(msgFormatCurrentFile()); - formatFile.bindContextAction(&m_formatFile); - formatFile.setContainer(menuId); - formatFile.setOnTriggered(this, [this] { this->formatFile(); }); + Core::ActionBuilder formatFile(this, "ClangFormat.FormatFile"); + formatFile.setText(msgFormatCurrentFile()); + formatFile.bindContextAction(&m_formatFile); + formatFile.setContainer(menuId); + formatFile.setOnTriggered(this, [this] { this->formatFile(); }); - Core::ActionBuilder formatLines(this, "ClangFormat.FormatLines"); - formatLines.setText(msgFormatLines()); - formatLines.bindContextAction(&m_formatLines); - formatLines.setContainer(menuId); - formatLines.setOnTriggered(this, [this] { this->formatLines(); }); + Core::ActionBuilder formatLines(this, "ClangFormat.FormatLines"); + formatLines.setText(msgFormatLines()); + formatLines.bindContextAction(&m_formatLines); + formatLines.setContainer(menuId); + formatLines.setOnTriggered(this, [this] { this->formatLines(); }); - Core::ActionBuilder formatAtCursor(this, "ClangFormat.FormatAtCursor"); - formatAtCursor.setText(msgFormatAtCursor()); - formatAtCursor.bindContextAction(&m_formatRange); - formatAtCursor.setContainer(menuId); - formatAtCursor.setOnTriggered(this, [this] { this->formatAtCursor(); }); + Core::ActionBuilder formatAtCursor(this, "ClangFormat.FormatAtCursor"); + formatAtCursor.setText(msgFormatAtCursor()); + formatAtCursor.bindContextAction(&m_formatRange); + formatAtCursor.setContainer(menuId); + formatAtCursor.setOnTriggered(this, [this] { this->formatAtCursor(); }); - Core::ActionBuilder formatDisable(this, "ClangFormat.DisableFormattingSelectedText"); - formatDisable.setText(msgDisableFormattingSelectedText()); - formatDisable.bindContextAction(&m_disableFormattingSelectedText); - formatDisable.setContainer(menuId); - formatDisable.setOnTriggered(this, [this] { disableFormattingSelectedText(); }); + Core::ActionBuilder formatDisable(this, "ClangFormat.DisableFormattingSelectedText"); + formatDisable.setText(msgDisableFormattingSelectedText()); + formatDisable.bindContextAction(&m_disableFormattingSelectedText); + formatDisable.setContainer(menuId); + formatDisable.setOnTriggered(this, [this] { disableFormattingSelectedText(); }); - Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu); + Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu); - connect(&settings().supportedMimeTypes, &BaseAspect::changed, - this, [this] { updateActions(Core::EditorManager::currentEditor()); }); -} + connect(&settings().supportedMimeTypes, &BaseAspect::changed, + this, [this] { updateActions(Core::EditorManager::currentEditor()); }); + } -QString ClangFormat::id() const -{ - return "ClangFormat"; -} + QString id() const final + { + return "ClangFormat"; + } -void ClangFormat::updateActions(Core::IEditor *editor) -{ - const bool enabled = editor && settings().isApplicable(editor->document()); - m_formatFile->setEnabled(enabled); - m_formatRange->setEnabled(enabled); -} + void updateActions(Core::IEditor *editor) final + { + const bool enabled = editor && settings().isApplicable(editor->document()); + m_formatFile->setEnabled(enabled); + m_formatRange->setEnabled(enabled); + } + + TextEditor::Command textCommand() const final; + + bool isApplicable(const Core::IDocument *document) const final + { + return settings().isApplicable(document); + } + +private: + void formatFile(); + void formatAtPosition(const int pos, const int length); + void formatAtCursor(); + void formatLines(); + void disableFormattingSelectedText(); + TextEditor::Command textCommand(int offset, int length) const; + + QAction *m_formatFile = nullptr; + QAction *m_formatLines = nullptr; + QAction *m_formatRange = nullptr; + QAction *m_disableFormattingSelectedText = nullptr; +}; void ClangFormat::formatFile() { @@ -488,11 +512,6 @@ Command ClangFormat::textCommand() const return cmd; } -bool ClangFormat::isApplicable(const Core::IDocument *document) const -{ - return settings().isApplicable(document); -} - Command ClangFormat::textCommand(int offset, int length) const { Command cmd = textCommand(); @@ -501,7 +520,6 @@ Command ClangFormat::textCommand(int offset, int length) const return cmd; } - // ClangFormatSettingsPage class ClangFormatSettingsPage final : public Core::IOptionsPage @@ -518,4 +536,9 @@ public: const ClangFormatSettingsPage settingsPage; +void setupClangFormat() +{ + static ClangFormat theClangFormat; +} + } // Beautifier::Internal diff --git a/src/plugins/beautifier/clangformat/clangformat.h b/src/plugins/beautifier/clangformat/clangformat.h index 82f6ac160b9..8c54a1939f2 100644 --- a/src/plugins/beautifier/clangformat/clangformat.h +++ b/src/plugins/beautifier/clangformat/clangformat.h @@ -3,36 +3,8 @@ #pragma once -#include "../beautifiertool.h" - -QT_BEGIN_NAMESPACE -class QAction; -QT_END_NAMESPACE - namespace Beautifier::Internal { -class ClangFormat : public BeautifierTool -{ -public: - ClangFormat(); - - QString id() const override; - void updateActions(Core::IEditor *editor) override; - TextEditor::Command textCommand() const override; - bool isApplicable(const Core::IDocument *document) const override; - -private: - void formatFile(); - void formatAtPosition(const int pos, const int length); - void formatAtCursor(); - void formatLines(); - void disableFormattingSelectedText(); - TextEditor::Command textCommand(int offset, int length) const; - - QAction *m_formatFile = nullptr; - QAction *m_formatLines = nullptr; - QAction *m_formatRange = nullptr; - QAction *m_disableFormattingSelectedText = nullptr; -}; +void setupClangFormat(); } // Beautifier::Internal diff --git a/src/plugins/beautifier/uncrustify/uncrustify.cpp b/src/plugins/beautifier/uncrustify/uncrustify.cpp index 340ee416f1c..d943b1daed7 100644 --- a/src/plugins/beautifier/uncrustify/uncrustify.cpp +++ b/src/plugins/beautifier/uncrustify/uncrustify.cpp @@ -97,7 +97,7 @@ public: read(); } - void createDocumentationFile() const override + void createDocumentationFile() const final { Process process; process.setTimeoutS(2); @@ -228,44 +228,67 @@ public: } }; - // Uncrustify -Uncrustify::Uncrustify() +class Uncrustify final : public BeautifierTool { - const Id menuId = "Uncrustify.Menu"; - Core::ActionContainer *menu = Core::ActionManager::createMenu(menuId); - menu->menu()->setTitle(Tr::tr("&Uncrustify")); +public: + Uncrustify() + { + const Id menuId = "Uncrustify.Menu"; + Core::ActionContainer *menu = Core::ActionManager::createMenu(menuId); + menu->menu()->setTitle(Tr::tr("&Uncrustify")); - Core::ActionBuilder formatFile(this, "Uncrustify.FormatFile"); - formatFile.setText(msgFormatCurrentFile()); - formatFile.bindContextAction(&m_formatFile); - formatFile.setContainer(menuId); - formatFile.setOnTriggered(this, [this] { this->formatFile(); }); + Core::ActionBuilder formatFile(this, "Uncrustify.FormatFile"); + formatFile.setText(msgFormatCurrentFile()); + formatFile.bindContextAction(&m_formatFile); + formatFile.setContainer(menuId); + formatFile.setOnTriggered(this, [this] { this->formatFile(); }); - Core::ActionBuilder formatRange(this, "Uncrustify.FormatSelectedText"); - formatRange.setText(msgFormatSelectedText()); - formatRange.bindContextAction(&m_formatRange); - formatRange.setContainer(menuId); - formatRange.setOnTriggered(this, [this] { this->formatSelectedText(); }); + Core::ActionBuilder formatRange(this, "Uncrustify.FormatSelectedText"); + formatRange.setText(msgFormatSelectedText()); + formatRange.bindContextAction(&m_formatRange); + formatRange.setContainer(menuId); + formatRange.setOnTriggered(this, [this] { this->formatSelectedText(); }); - Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu); + Core::ActionManager::actionContainer(Constants::MENU_ID)->addMenu(menu); - connect(&settings().supportedMimeTypes, &Utils::BaseAspect::changed, - this, [this] { updateActions(Core::EditorManager::currentEditor()); }); -} + connect(&settings().supportedMimeTypes, &Utils::BaseAspect::changed, + this, [this] { updateActions(Core::EditorManager::currentEditor()); }); + } -QString Uncrustify::id() const -{ - return "Uncrustify"; -} + QString id() const final + { + return "Uncrustify"; + } -void Uncrustify::updateActions(Core::IEditor *editor) -{ - const bool enabled = editor && settings().isApplicable(editor->document()); - m_formatFile->setEnabled(enabled); - m_formatRange->setEnabled(enabled); -} + void updateActions(Core::IEditor *editor) final + { + const bool enabled = editor && settings().isApplicable(editor->document()); + m_formatFile->setEnabled(enabled); + m_formatRange->setEnabled(enabled); + } + + TextEditor::Command textCommand() const final + { + const FilePath cfgFile = configurationFile(); + return cfgFile.isEmpty() ? Command() : textCommand(cfgFile, false); + } + + bool isApplicable(const Core::IDocument *document) const final + { + return settings().isApplicable(document); + } + +private: + void formatFile(); + void formatSelectedText(); + Utils::FilePath configurationFile() const; + TextEditor::Command textCommand(const Utils::FilePath &cfgFile, bool fragment = false) const; + + QAction *m_formatFile = nullptr; + QAction *m_formatRange = nullptr; +}; void Uncrustify::formatFile() { @@ -338,17 +361,6 @@ FilePath Uncrustify::configurationFile() const return {}; } -Command Uncrustify::textCommand() const -{ - const FilePath cfgFile = configurationFile(); - return cfgFile.isEmpty() ? Command() : textCommand(cfgFile, false); -} - -bool Uncrustify::isApplicable(const Core::IDocument *document) const -{ - return settings().isApplicable(document); -} - Command Uncrustify::textCommand(const FilePath &cfgFile, bool fragment) const { Command cmd; @@ -387,4 +399,9 @@ public: const UncrustifySettingsPage settingsPage; +void setupUncrustify() +{ + static Uncrustify theUncrustify; +} + } // Beautifier::Internal diff --git a/src/plugins/beautifier/uncrustify/uncrustify.h b/src/plugins/beautifier/uncrustify/uncrustify.h index 090b06e0423..05c5ce72289 100644 --- a/src/plugins/beautifier/uncrustify/uncrustify.h +++ b/src/plugins/beautifier/uncrustify/uncrustify.h @@ -3,32 +3,8 @@ #pragma once -#include "../beautifiertool.h" - -QT_BEGIN_NAMESPACE -class QAction; -QT_END_NAMESPACE - namespace Beautifier::Internal { -class Uncrustify : public BeautifierTool -{ -public: - Uncrustify(); - - QString id() const override; - void updateActions(Core::IEditor *editor) override; - TextEditor::Command textCommand() const override; - bool isApplicable(const Core::IDocument *document) const override; - -private: - void formatFile(); - void formatSelectedText(); - Utils::FilePath configurationFile() const; - TextEditor::Command textCommand(const Utils::FilePath &cfgFile, bool fragment = false) const; - - QAction *m_formatFile = nullptr; - QAction *m_formatRange = nullptr; -}; +void setupUncrustify(); } // Beautifier::Internal From 6191e249350811acd07b062d82a0d215c3a4a60c Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Nov 2023 15:13:08 +0100 Subject: [PATCH 0358/1546] Beautifier: Dissolve plugin pimpl Change-Id: I00a5b92578e57c64da535af908bb661cdd901e8c Reviewed-by: Jarek Kobus --- src/plugins/beautifier/beautifierplugin.cpp | 129 ++++++++------------ 1 file changed, 52 insertions(+), 77 deletions(-) diff --git a/src/plugins/beautifier/beautifierplugin.cpp b/src/plugins/beautifier/beautifierplugin.cpp index 7972fc67773..6cdce4b254c 100644 --- a/src/plugins/beautifier/beautifierplugin.cpp +++ b/src/plugins/beautifier/beautifierplugin.cpp @@ -31,8 +31,6 @@ #include #include -#include -#include #include @@ -57,76 +55,6 @@ static bool isAutoFormatApplicable(const IDocument *document, }); } -class BeautifierPluginPrivate : public QObject -{ -public: - BeautifierPluginPrivate(); - - void updateActions(IEditor *editor = nullptr); - - void autoFormatOnSave(IDocument *document); -}; - -BeautifierPluginPrivate::BeautifierPluginPrivate() -{ - for (BeautifierTool *tool : BeautifierTool::allTools()) - generalSettings().autoFormatTools.addOption(tool->id()); - - updateActions(); - - const EditorManager *editorManager = EditorManager::instance(); - connect(editorManager, &EditorManager::currentEditorChanged, - this, &BeautifierPluginPrivate::updateActions); - connect(editorManager, &EditorManager::aboutToSave, - this, &BeautifierPluginPrivate::autoFormatOnSave); -} - -void BeautifierPluginPrivate::updateActions(IEditor *editor) -{ - for (BeautifierTool *tool : BeautifierTool::allTools()) - tool->updateActions(editor); -} - -void BeautifierPluginPrivate::autoFormatOnSave(IDocument *document) -{ - if (!generalSettings().autoFormatOnSave()) - return; - - if (!isAutoFormatApplicable(document, generalSettings().allowedMimeTypes())) - return; - - // Check if file is contained in the current project (if wished) - if (generalSettings().autoFormatOnlyCurrentProject()) { - const ProjectExplorer::Project *pro = ProjectExplorer::ProjectTree::currentProject(); - if (!pro - || pro->files([document](const ProjectExplorer::Node *n) { - return ProjectExplorer::Project::SourceFiles(n) - && n->filePath() == document->filePath(); - }) - .isEmpty()) { - return; - } - } - - // Find tool to use by id and format file! - const QString id = generalSettings().autoFormatTools.stringValue(); - const QList &tools = BeautifierTool::allTools(); - auto tool = std::find_if(std::begin(tools), std::end(tools), - [&id](const BeautifierTool *t){return t->id() == id;}); - if (tool != std::end(tools)) { - if (!(*tool)->isApplicable(document)) - return; - const TextEditor::Command command = (*tool)->textCommand(); - if (!command.isValid()) - return; - const QList editors = DocumentModel::editorsForDocument(document); - if (editors.isEmpty()) - return; - if (auto widget = TextEditorWidget::fromEditor(editors.first())) - TextEditor::formatEditor(widget, command); - } -} - class BeautifierPlugin final : public ExtensionSystem::IPlugin { Q_OBJECT @@ -146,16 +74,63 @@ class BeautifierPlugin final : public ExtensionSystem::IPlugin void extensionsInitialized() final { - d = new BeautifierPluginPrivate; + for (BeautifierTool *tool : BeautifierTool::allTools()) + generalSettings().autoFormatTools.addOption(tool->id()); + + updateActions(); + + const EditorManager *editorManager = EditorManager::instance(); + connect(editorManager, &EditorManager::currentEditorChanged, + this, &BeautifierPlugin::updateActions); + connect(editorManager, &EditorManager::aboutToSave, + this, &BeautifierPlugin::autoFormatOnSave); } - ShutdownFlag aboutToShutdown() final + void updateActions(IEditor *editor = nullptr) { - delete d; - return SynchronousShutdown; + for (BeautifierTool *tool : BeautifierTool::allTools()) + tool->updateActions(editor); } - BeautifierPluginPrivate *d = nullptr; + void autoFormatOnSave(IDocument *document) + { + if (!generalSettings().autoFormatOnSave()) + return; + + if (!isAutoFormatApplicable(document, generalSettings().allowedMimeTypes())) + return; + + // Check if file is contained in the current project (if wished) + if (generalSettings().autoFormatOnlyCurrentProject()) { + const ProjectExplorer::Project *pro = ProjectExplorer::ProjectTree::currentProject(); + if (!pro + || pro->files([document](const ProjectExplorer::Node *n) { + return ProjectExplorer::Project::SourceFiles(n) + && n->filePath() == document->filePath(); + }) + .isEmpty()) { + return; + } + } + + // Find tool to use by id and format file! + const QString id = generalSettings().autoFormatTools.stringValue(); + const QList &tools = BeautifierTool::allTools(); + auto tool = std::find_if(std::begin(tools), std::end(tools), + [&id](const BeautifierTool *t){return t->id() == id;}); + if (tool != std::end(tools)) { + if (!(*tool)->isApplicable(document)) + return; + const TextEditor::Command command = (*tool)->textCommand(); + if (!command.isValid()) + return; + const QList editors = DocumentModel::editorsForDocument(document); + if (editors.isEmpty()) + return; + if (auto widget = TextEditorWidget::fromEditor(editors.first())) + TextEditor::formatEditor(widget, command); + } + } }; } // Beautifier::Internal From d6de193e5eb78e0cfde5afeb22d626163eba40fb Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Wed, 22 Nov 2023 10:47:36 +0100 Subject: [PATCH 0359/1546] AutoTest: Remove unused variables Removes after refactorings now unused local or member. Change-Id: I56f16cb2058c6d15c3906550480ddcb32ef600c8 Reviewed-by: Qt CI Bot Reviewed-by: David Schulz --- src/plugins/autotest/itestparser.cpp | 1 - src/plugins/autotest/projectsettingswidget.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/src/plugins/autotest/itestparser.cpp b/src/plugins/autotest/itestparser.cpp index 9438fe4caf1..ebaaec9f537 100644 --- a/src/plugins/autotest/itestparser.cpp +++ b/src/plugins/autotest/itestparser.cpp @@ -124,7 +124,6 @@ std::optional> CppParser::filesContainingMacro(const QByteArray & if (!pp->selectedForBuilding) continue; - const ProjectExplorer::Macros macros = pp->projectMacros; if (Utils::anyOf(pp->projectMacros, Utils::equal(&ProjectExplorer::Macro::key, macroName))) result.unite(Utils::transform(pp->files, &CppEditor::ProjectFile::path)); } diff --git a/src/plugins/autotest/projectsettingswidget.cpp b/src/plugins/autotest/projectsettingswidget.cpp index e82d9e90201..48151dea290 100644 --- a/src/plugins/autotest/projectsettingswidget.cpp +++ b/src/plugins/autotest/projectsettingswidget.cpp @@ -39,7 +39,6 @@ private: const QHash &testTools); void onActiveFrameworkChanged(QTreeWidgetItem *item, int column); TestProjectSettings *m_projectSettings; - QComboBox *m_useGlobalSettings = nullptr; QTreeWidget *m_activeFrameworks = nullptr; QComboBox *m_runAfterBuild = nullptr; QTimer m_syncTimer; From 459cdf5f320efeff9a2d736d627b21f12fd633cd Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Nov 2023 13:05:19 +0100 Subject: [PATCH 0360/1546] Squish: Delay-create SquishTestTreeModel ... by a few lines. Change-Id: Ida09bd25cee700ab167c6546f9cd6a39b863b592 Reviewed-by: Reviewed-by: Christian Stenger --- src/plugins/squish/squishplugin.cpp | 4 +++- src/plugins/squish/squishtesttreemodel.cpp | 14 ++++---------- src/plugins/squish/squishtesttreemodel.h | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/src/plugins/squish/squishplugin.cpp b/src/plugins/squish/squishplugin.cpp index 38b0b1ad8ad..9ddbe2dc95d 100644 --- a/src/plugins/squish/squishplugin.cpp +++ b/src/plugins/squish/squishplugin.cpp @@ -39,7 +39,6 @@ public: bool initializeGlobalScripts(); - SquishTestTreeModel m_treeModel; SquishNavigationWidgetFactory m_navigationWidgetFactory; ObjectsMapEditorFactory m_objectsMapEditorFactory; SquishOutputPane m_outputPane; @@ -77,6 +76,9 @@ SquishPluginPrivate::SquishPluginPrivate() bool SquishPluginPrivate::initializeGlobalScripts() { + // The code expects squishTestTreeModel to exist, so force creation now. + (void) SquishTestTreeModel::instance(); + SquishFileHandler::instance()->setSharedFolders({}); const FilePath squishserver = settings().squishPath().pathAppended("bin/squishserver") diff --git a/src/plugins/squish/squishtesttreemodel.cpp b/src/plugins/squish/squishtesttreemodel.cpp index 5b826d4882d..827feb4ce88 100644 --- a/src/plugins/squish/squishtesttreemodel.cpp +++ b/src/plugins/squish/squishtesttreemodel.cpp @@ -162,11 +162,8 @@ void SquishTestTreeItem::revalidateCheckState() /**************************** SquishTestTreeModel **************************************/ -static SquishTestTreeModel *m_instance = nullptr; - -SquishTestTreeModel::SquishTestTreeModel(QObject *parent) - : TreeModel(new SquishTestTreeItem(QString(), SquishTestTreeItem::Root), - parent) +SquishTestTreeModel::SquishTestTreeModel() + : TreeModel(new SquishTestTreeItem(QString(), SquishTestTreeItem::Root)) , m_squishSharedFolders(new SquishTestTreeItem(Tr::tr("Shared Folders"), SquishTestTreeItem::Root)) , m_squishSuitesRoot(new SquishTestTreeItem(Tr::tr("Test Suites"), SquishTestTreeItem::Root)) , m_squishFileHandler(new SquishFileHandler(this)) @@ -184,17 +181,14 @@ SquishTestTreeModel::SquishTestTreeModel(QObject *parent) this, &SquishTestTreeModel::onTestCaseRemoved); connect(m_squishFileHandler, &SquishFileHandler::clearedSharedFolders, this, [this] { m_squishSharedFolders->removeChildren(); }); - - m_instance = this; } SquishTestTreeModel::~SquishTestTreeModel() {} SquishTestTreeModel *SquishTestTreeModel::instance() { - if (!m_instance) - m_instance = new SquishTestTreeModel; - return m_instance; + static SquishTestTreeModel theSquishTestTreeModel; + return &theSquishTestTreeModel; } static QPixmap scaledPixmap(const Utils::Icon &icon) diff --git a/src/plugins/squish/squishtesttreemodel.h b/src/plugins/squish/squishtesttreemodel.h index fe17c67c6c2..66c8ec54210 100644 --- a/src/plugins/squish/squishtesttreemodel.h +++ b/src/plugins/squish/squishtesttreemodel.h @@ -62,7 +62,7 @@ private: class SquishTestTreeModel : public Utils::TreeModel { public: - SquishTestTreeModel(QObject *parent = nullptr); + SquishTestTreeModel(); ~SquishTestTreeModel() override; static SquishTestTreeModel *instance(); From 4cc2e60c38f1874ab296ab360dd5640c595592d4 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 14 Nov 2023 13:55:31 +0100 Subject: [PATCH 0361/1546] ProjectExplorer: add function to setup a single BuildInfo Change-Id: I418c7bae6a1519126b75b6ce535379facc332062 Reviewed-by: Christian Kandeler --- src/plugins/projectexplorer/project.cpp | 45 ++++++++++++++----------- src/plugins/projectexplorer/project.h | 2 ++ 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index c0e245baf1c..84c8fb2e103 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -1033,31 +1033,36 @@ bool Project::hasMakeInstallEquivalent() const void Project::setup(const QList &infoList) { - std::vector> toRegister; - for (const BuildInfo &info : infoList) { - Kit *k = KitManager::kit(info.kitId); - if (!k) - continue; - Target *t = target(k); - if (!t) - t = findOrDefault(toRegister, equal(&Target::kit, k)); - if (!t) { - auto newTarget = std::make_unique(this, k, Target::_constructor_tag{}); - t = newTarget.get(); - toRegister.emplace_back(std::move(newTarget)); - } + for (const BuildInfo &info : infoList) + setup(info); +} - if (!info.factory) - continue; +BuildConfiguration *Project::setup(const BuildInfo &info) +{ + Kit *k = KitManager::kit(info.kitId); + if (!k) + return nullptr; + Target *t = target(k); + std::unique_ptr newTarget; + if (!t) { + newTarget = std::make_unique(this, k, Target::_constructor_tag{}); + t = newTarget.get(); + } - if (BuildConfiguration *bc = info.factory->create(t, info)) + QTC_ASSERT(t, return nullptr); + + BuildConfiguration *bc = nullptr; + if (info.factory) { + bc = info.factory->create(t, info); + if (bc) t->addBuildConfiguration(bc); } - for (std::unique_ptr &t : toRegister) { - t->updateDefaultDeployConfigurations(); - t->updateDefaultRunConfigurations(); - addTarget(std::move(t)); + if (newTarget) { + newTarget->updateDefaultDeployConfigurations(); + newTarget->updateDefaultRunConfigurations(); + addTarget(std::move(newTarget)); } + return bc; } MacroExpander *Project::macroExpander() const diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index e1bf1eb7b02..2304dd3850c 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -27,6 +27,7 @@ class MacroExpander; namespace ProjectExplorer { +class BuildConfiguration; class BuildInfo; class BuildSystem; class ContainerNode; @@ -134,6 +135,7 @@ public: bool hasMakeInstallEquivalent() const; void setup(const QList &infoList); + BuildConfiguration *setup(const BuildInfo &info); Utils::MacroExpander *macroExpander() const; ProjectNode *findNodeForBuildKey(const QString &buildKey) const; From 3e2ced7adb6ec08444415704f1818bf207270a39 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Wed, 22 Nov 2023 14:23:06 +0100 Subject: [PATCH 0362/1546] Core: Move ResizeSignallingWidget to WelcomePageHelpers This makes it available to ExtensionManager. Change-Id: I343c51286215556880838677a87f4df8c65d2308 Reviewed-by: Cristian Adam --- src/plugins/coreplugin/welcomepagehelper.cpp | 10 ++++++++++ src/plugins/coreplugin/welcomepagehelper.h | 12 ++++++++++++ src/plugins/welcome/welcomeplugin.cpp | 16 ---------------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/plugins/coreplugin/welcomepagehelper.cpp b/src/plugins/coreplugin/welcomepagehelper.cpp index 2a190b547e0..f1b6281d437 100644 --- a/src/plugins/coreplugin/welcomepagehelper.cpp +++ b/src/plugins/coreplugin/welcomepagehelper.cpp @@ -868,4 +868,14 @@ Section::Section(const QString &name, int priority, std::optional maxRows) , maxRows(maxRows) {} +ResizeSignallingWidget::ResizeSignallingWidget(QWidget *parent) + : QWidget(parent) +{ +} + +void ResizeSignallingWidget::resizeEvent(QResizeEvent *event) +{ + emit resized(event->size(), event->oldSize()); +} + } // namespace Core diff --git a/src/plugins/coreplugin/welcomepagehelper.h b/src/plugins/coreplugin/welcomepagehelper.h index 61d57e448d0..88379990d31 100644 --- a/src/plugins/coreplugin/welcomepagehelper.h +++ b/src/plugins/coreplugin/welcomepagehelper.h @@ -229,6 +229,18 @@ private: QString m_delayedSearchString; }; +class CORE_EXPORT ResizeSignallingWidget : public QWidget +{ + Q_OBJECT + +public: + explicit ResizeSignallingWidget(QWidget *parent = nullptr); + void resizeEvent(QResizeEvent *event) override; + +signals: + void resized(const QSize &size, const QSize &oldSize); +}; + } // namespace Core Q_DECLARE_METATYPE(Core::ListItem *) diff --git a/src/plugins/welcome/welcomeplugin.cpp b/src/plugins/welcome/welcomeplugin.cpp index bfa77cc399b..38df46e629b 100644 --- a/src/plugins/welcome/welcomeplugin.cpp +++ b/src/plugins/welcome/welcomeplugin.cpp @@ -68,22 +68,6 @@ static void addWeakVerticalSpacerToLayout(QVBoxLayout *layout, int maximumSize) layout->setStretchFactor(weakSpacer, 1); } -class ResizeSignallingWidget : public QWidget -{ - Q_OBJECT - -public: - void resizeEvent(QResizeEvent *event) override; - -signals: - void resized(const QSize &size, const QSize &oldSize); -}; - -void ResizeSignallingWidget::resizeEvent(QResizeEvent *event) -{ - emit resized(event->size(), event->oldSize()); -} - class WelcomeMode : public IMode { Q_OBJECT From d41a99520e7df3adb229e3e7ad18b4d7d447afec Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Thu, 23 Nov 2023 12:07:54 +0100 Subject: [PATCH 0363/1546] Core: Add parameter defaults to constructors Make Welcome* widgets more standard conformant. Change-Id: Id098067138e434f99a71add528601c250f78a33d Reviewed-by: Cristian Adam --- src/plugins/coreplugin/iwelcomepage.h | 2 +- src/plugins/coreplugin/welcomepagehelper.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/plugins/coreplugin/iwelcomepage.h b/src/plugins/coreplugin/iwelcomepage.h index fa1a5e7d6b6..9a64dd3a701 100644 --- a/src/plugins/coreplugin/iwelcomepage.h +++ b/src/plugins/coreplugin/iwelcomepage.h @@ -57,7 +57,7 @@ public: SizeLarge, }; - WelcomePageButton(QWidget *parent); + explicit WelcomePageButton(QWidget *parent = nullptr); ~WelcomePageButton() override; void mousePressEvent(QMouseEvent *) override; diff --git a/src/plugins/coreplugin/welcomepagehelper.h b/src/plugins/coreplugin/welcomepagehelper.h index 88379990d31..191e1768d1d 100644 --- a/src/plugins/coreplugin/welcomepagehelper.h +++ b/src/plugins/coreplugin/welcomepagehelper.h @@ -42,7 +42,7 @@ CORE_EXPORT QWidget *panelBar(QWidget *parent = nullptr); class CORE_EXPORT SearchBox : public WelcomePageFrame { public: - explicit SearchBox(QWidget *parent); + explicit SearchBox(QWidget *parent = nullptr); Utils::FancyLineEdit *m_lineEdit = nullptr; }; From 712fd89bb917044250d2182810fbf9128fc21ee4 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 23 Nov 2023 16:08:48 +0100 Subject: [PATCH 0364/1546] TaskTree: Fix testInThread(Parallel) test on macOS (second try) The test was failing on macOS on github. Change-Id: Ie5fb6aca78b2eac10dc4de988f312065f8ea4a8d Reviewed-by: Cristian Adam --- src/libs/solutions/tasking/tasktree.cpp | 41 ++++++++++++++++--------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/src/libs/solutions/tasking/tasktree.cpp b/src/libs/solutions/tasking/tasktree.cpp index fe8dc4c5c96..3657178b0bd 100644 --- a/src/libs/solutions/tasking/tasktree.cpp +++ b/src/libs/solutions/tasking/tasktree.cpp @@ -2992,7 +2992,7 @@ struct TimerThreadData TimerThreadData() = default; // defult constructor is required for initializing with {} since C++20 by Mingw 11.20 QHash m_timerIdToTimerData = {}; - QMultiMap m_deadlineToTimerId = {}; + QMap> m_deadlineToTimerId = {}; int m_timerIdCounter = 0; }; @@ -3008,8 +3008,11 @@ static void removeTimerId(int timerId) const system_clock::time_point deadline = it->m_deadline; s_threadTimerData.m_timerIdToTimerData.erase(it); - const int removedCount = s_threadTimerData.m_deadlineToTimerId.remove(deadline, timerId); + QList &ids = s_threadTimerData.m_deadlineToTimerId[deadline]; + const int removedCount = ids.removeAll(timerId); QT_ASSERT(removedCount == 1, qWarning("Removing active timerId failed."); return); + if (ids.isEmpty()) + s_threadTimerData.m_deadlineToTimerId.remove(deadline); } static void handleTimeout(int timerId) @@ -3020,26 +3023,34 @@ static void handleTimeout(int timerId) const auto deadline = itData->m_deadline; while (true) { - const auto itMap = s_threadTimerData.m_deadlineToTimerId.cbegin(); - if (itMap == s_threadTimerData.m_deadlineToTimerId.cend()) + auto itMap = s_threadTimerData.m_deadlineToTimerId.begin(); + if (itMap == s_threadTimerData.m_deadlineToTimerId.end()) return; if (itMap.key() > deadline) return; - const auto it = s_threadTimerData.m_timerIdToTimerData.constFind(itMap.value()); - if (it == s_threadTimerData.m_timerIdToTimerData.cend()) { - s_threadTimerData.m_deadlineToTimerId.erase(itMap); + std::optional timerData; + QList &idList = *itMap; + if (!idList.isEmpty()) { + const int first = idList.first(); + idList.removeFirst(); + + const auto it = s_threadTimerData.m_timerIdToTimerData.constFind(first); + if (it != s_threadTimerData.m_timerIdToTimerData.cend()) { + timerData = it.value(); + s_threadTimerData.m_timerIdToTimerData.erase(it); + } else { + QT_CHECK(false); + } + } else { QT_CHECK(false); - return; } - const TimerData timerData = it.value(); - s_threadTimerData.m_timerIdToTimerData.erase(it); - s_threadTimerData.m_deadlineToTimerId.erase(itMap); - - if (timerData.m_context) - timerData.m_callback(); + if (idList.isEmpty()) + s_threadTimerData.m_deadlineToTimerId.erase(itMap); + if (timerData && timerData->m_context) + timerData->m_callback(); } } @@ -3049,7 +3060,7 @@ static int scheduleTimeout(milliseconds timeout, QObject *context, const Timeout const system_clock::time_point deadline = system_clock::now() + timeout; QTimer::singleShot(timeout, context, [timerId] { handleTimeout(timerId); }); s_threadTimerData.m_timerIdToTimerData.emplace(timerId, TimerData{deadline, context, callback}); - s_threadTimerData.m_deadlineToTimerId.insert(deadline, timerId); + s_threadTimerData.m_deadlineToTimerId[deadline].append(timerId); return timerId; } From dca3d516b9cf6d8a6a816a78d8f9e30094f2b72b Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 14 Nov 2023 14:10:20 +0100 Subject: [PATCH 0365/1546] ProjectExplorer: expand BuildInfo Allow defining whether a widget in target setuppage has a build dir pathchooser and whether it is enabled by default. Change-Id: I85e9c602b1475c93d39472f2e68a0e4d5ac6e882 Reviewed-by: Christian Kandeler --- src/plugins/projectexplorer/buildinfo.h | 2 ++ src/plugins/projectexplorer/targetsetupwidget.cpp | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/buildinfo.h b/src/plugins/projectexplorer/buildinfo.h index 9325a250b38..dae99442076 100644 --- a/src/plugins/projectexplorer/buildinfo.h +++ b/src/plugins/projectexplorer/buildinfo.h @@ -22,6 +22,8 @@ public: QString displayName; QString typeName; Utils::FilePath buildDirectory; + bool showBuildDirConfigWidget = true; + bool enabledByDefault = true; Utils::Id kitId; BuildConfiguration::BuildType buildType = BuildConfiguration::Unknown; diff --git a/src/plugins/projectexplorer/targetsetupwidget.cpp b/src/plugins/projectexplorer/targetsetupwidget.cpp index 99b08d45f97..f851958b82f 100644 --- a/src/plugins/projectexplorer/targetsetupwidget.cpp +++ b/src/plugins/projectexplorer/targetsetupwidget.cpp @@ -125,7 +125,7 @@ void TargetSetupWidget::addBuildInfo(const BuildInfo &info, bool isImport) BuildInfoStore store; store.buildInfo = info; - store.isEnabled = true; + store.isEnabled = info.enabledByDefault; ++m_selected; if (info.factory) { @@ -138,6 +138,8 @@ void TargetSetupWidget::addBuildInfo(const BuildInfo &info, bool isImport) store.pathChooser = new PathChooser(); store.pathChooser->setExpectedKind(PathChooser::Directory); store.pathChooser->setFilePath(info.buildDirectory); + if (!info.showBuildDirConfigWidget) + store.pathChooser->setVisible(false); store.pathChooser->setHistoryCompleter("TargetSetup.BuildDir.History"); store.pathChooser->setReadOnly(isImport); m_newBuildsLayout->addWidget(store.pathChooser, pos * 2, 1); @@ -280,6 +282,7 @@ void TargetSetupWidget::updateDefaultBuildDirectories() if (!buildInfoStore.customBuildDir) { const GuardLocker locker(m_ignoreChanges); buildInfoStore.pathChooser->setFilePath(buildInfo.buildDirectory); + buildInfoStore.pathChooser->setVisible(buildInfo.showBuildDirConfigWidget); } found = true; break; From 18c234630531fbaee4d6889928834d7249cdb595 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 23 Nov 2023 15:10:48 +0100 Subject: [PATCH 0366/1546] ExtensionSystem: Add plugin details dialog to error dialog When a plugin fails to load, we show an error dialog with each of the failed plugins and their error message. Add a button that opens the plugin details dialog, and also show that on double click on a plugin in the list. Refactors opening a modal dialog with the details into its own function. Change-Id: Id55d0add3682860470ede63b141fbce2e8dab75f Reviewed-by: Reviewed-by: Alessandro Portale Reviewed-by: Qt CI Bot --- .../extensionsystem/plugindetailsview.cpp | 28 +++++++++++++++++++ src/libs/extensionsystem/plugindetailsview.h | 2 ++ .../extensionsystem/pluginerroroverview.cpp | 22 +++++++++++++-- src/plugins/coreplugin/plugindialog.cpp | 17 +---------- 4 files changed, 51 insertions(+), 18 deletions(-) diff --git a/src/libs/extensionsystem/plugindetailsview.cpp b/src/libs/extensionsystem/plugindetailsview.cpp index 49ba0815a35..73fa2b1229d 100644 --- a/src/libs/extensionsystem/plugindetailsview.cpp +++ b/src/libs/extensionsystem/plugindetailsview.cpp @@ -11,6 +11,8 @@ #include #include +#include +#include #include #include #include @@ -156,3 +158,29 @@ void PluginDetailsView::update(PluginSpec *spec) d->dependencies->addItems(Utils::transform(spec->dependencies(), &PluginDependency::toString)); } + +void PluginDetailsView::showModal(QWidget *parent, PluginSpec *spec) +{ + auto dialog = new QDialog(parent); + dialog->setModal(true); + dialog->setAttribute(Qt::WA_DeleteOnClose); + dialog->setWindowTitle(Tr::tr("Plugin Details of %1").arg(spec->name())); + auto details = new ExtensionSystem::PluginDetailsView(dialog); + details->update(spec); + QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Close, + Qt::Horizontal, + dialog); + + // clang-format off + using namespace Layouting; + Column { + details, + buttons, + }.attachTo(dialog); + // clang-format on + + connect(buttons, &QDialogButtonBox::accepted, dialog, &QDialog::accept); + connect(buttons, &QDialogButtonBox::rejected, dialog, &QDialog::reject); + dialog->resize(400, 500); + dialog->show(); +} diff --git a/src/libs/extensionsystem/plugindetailsview.h b/src/libs/extensionsystem/plugindetailsview.h index f4976e52570..f297937456e 100644 --- a/src/libs/extensionsystem/plugindetailsview.h +++ b/src/libs/extensionsystem/plugindetailsview.h @@ -23,6 +23,8 @@ public: void update(PluginSpec *spec); + static void showModal(QWidget *parent, PluginSpec *spec); + private: Internal::PluginDetailsViewPrivate *d = nullptr; }; diff --git a/src/libs/extensionsystem/pluginerroroverview.cpp b/src/libs/extensionsystem/pluginerroroverview.cpp index 69562e504df..ca29e08de24 100644 --- a/src/libs/extensionsystem/pluginerroroverview.cpp +++ b/src/libs/extensionsystem/pluginerroroverview.cpp @@ -4,6 +4,7 @@ #include "pluginerroroverview.h" #include "extensionsystemtr.h" +#include "plugindetailsview.h" #include "pluginmanager.h" #include "pluginspec.h" @@ -13,6 +14,7 @@ #include #include #include +#include #include Q_DECLARE_METATYPE(ExtensionSystem::PluginSpec *) @@ -24,6 +26,13 @@ PluginErrorOverview::PluginErrorOverview(QWidget *parent) { QListWidget *pluginList = new QListWidget(this); + const auto showPluginDetails = [this, pluginList](QListWidgetItem *item) { + QTC_ASSERT(item, return); + auto spec = item->data(Qt::UserRole).value(); + QTC_ASSERT(spec, return); + PluginDetailsView::showModal(this, spec); + }; + QTextEdit *pluginError = new QTextEdit(this); pluginError->setReadOnly(true); @@ -32,8 +41,17 @@ PluginErrorOverview::PluginErrorOverview(QWidget *parent) buttonBox->setStandardButtons(QDialogButtonBox::NoButton); buttonBox->addButton(Tr::tr("Continue"), QDialogButtonBox::AcceptRole); - connect(pluginList, &QListWidget::currentItemChanged, - this, [pluginError](QListWidgetItem *item) { + QPushButton *detailsButton = buttonBox->addButton(Tr::tr("Details"), QDialogButtonBox::HelpRole); + connect(detailsButton, &QPushButton::clicked, this, [pluginList, showPluginDetails] { + QListWidgetItem *item = pluginList->currentItem(); + showPluginDetails(item); + }); + connect(pluginList, + &QListWidget::itemDoubleClicked, + this, + [showPluginDetails](QListWidgetItem *item) { showPluginDetails(item); }); + + connect(pluginList, &QListWidget::currentItemChanged, this, [pluginError](QListWidgetItem *item) { if (item) pluginError->setText(item->data(Qt::UserRole).value()->errorString()); else diff --git a/src/plugins/coreplugin/plugindialog.cpp b/src/plugins/coreplugin/plugindialog.cpp index cedf5438a61..ef610bd3d36 100644 --- a/src/plugins/coreplugin/plugindialog.cpp +++ b/src/plugins/coreplugin/plugindialog.cpp @@ -122,22 +122,7 @@ void PluginDialog::openDetails(ExtensionSystem::PluginSpec *spec) { if (!spec) return; - QDialog dialog(this); - dialog.setWindowTitle(Tr::tr("Plugin Details of %1").arg(spec->name())); - auto details = new ExtensionSystem::PluginDetailsView(&dialog); - details->update(spec); - QDialogButtonBox *buttons = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, &dialog); - - using namespace Layouting; - Column { - details, - buttons, - }.attachTo(&dialog); - - connect(buttons, &QDialogButtonBox::accepted, &dialog, &QDialog::accept); - connect(buttons, &QDialogButtonBox::rejected, &dialog, &QDialog::reject); - dialog.resize(400, 500); - dialog.exec(); + PluginDetailsView::showModal(this, spec); } void PluginDialog::openErrorDetails() From b01b44a6b2213439b4aff68b98a232f022b2d3cd Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Nov 2023 08:26:41 +0100 Subject: [PATCH 0367/1546] ProjectExplorer: Use new setup pattern for msvc based toolchains ClangCL and MSVC itself. Change-Id: I500ffdcdb2ef71d14b112466613cdd9cb57dc89c Reviewed-by: David Schulz --- src/plugins/projectexplorer/msvctoolchain.cpp | 428 +++++++++++------- src/plugins/projectexplorer/msvctoolchain.h | 123 +---- .../projectexplorer/projectexplorer.cpp | 7 +- 3 files changed, 262 insertions(+), 296 deletions(-) diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index dd5181990de..12623a9907a 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -51,8 +51,7 @@ static const char environModsKeyC[] = KEY_ROOT "environmentModifications"; static Q_LOGGING_CATEGORY(Log, "qtc.projectexplorer.toolchain.msvc", QtWarningMsg); -namespace ProjectExplorer { -namespace Internal { +namespace ProjectExplorer::Internal { // -------------------------------------------------------------------------- // Helpers: @@ -1011,11 +1010,6 @@ void MsvcToolChain::fromMap(const Store &data) } } -std::unique_ptr MsvcToolChain::createConfigurationWidget() -{ - return std::make_unique(this); -} - bool MsvcToolChain::hostPrefersToolchain() const { return hostPrefersPlatform(platform()); @@ -1259,17 +1253,6 @@ MsvcToolChain::Platform MsvcToolChain::platform() const // call setFromMsvcToolChain(). // -------------------------------------------------------------------------- -MsvcBasedToolChainConfigWidget::MsvcBasedToolChainConfigWidget(ToolChain *tc) - : ToolChainConfigWidget(tc) - , m_nameDisplayLabel(new QLabel(this)) - , m_varsBatDisplayLabel(new QLabel(this)) -{ - m_nameDisplayLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); - m_mainLayout->addRow(m_nameDisplayLabel); - m_varsBatDisplayLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); - m_mainLayout->addRow(Tr::tr("Initialization:"), m_varsBatDisplayLabel); -} - static QString msvcVarsToDisplay(const MsvcToolChain &tc) { QString varsBatDisplay = QDir::toNativeSeparators(tc.varsBat()); @@ -1280,74 +1263,122 @@ static QString msvcVarsToDisplay(const MsvcToolChain &tc) return varsBatDisplay; } -void MsvcBasedToolChainConfigWidget::setFromMsvcToolChain() +class MsvcBasedToolChainConfigWidget : public ToolChainConfigWidget { - const auto *tc = static_cast(toolChain()); - QTC_ASSERT(tc, return ); - m_nameDisplayLabel->setText(tc->displayName()); - m_varsBatDisplayLabel->setText(msvcVarsToDisplay(*tc)); -} +public: + explicit MsvcBasedToolChainConfigWidget(ToolChain *tc) + : ToolChainConfigWidget(tc) + , m_nameDisplayLabel(new QLabel(this)) + , m_varsBatDisplayLabel(new QLabel(this)) + { + m_nameDisplayLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); + m_mainLayout->addRow(m_nameDisplayLabel); + m_varsBatDisplayLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); + m_mainLayout->addRow(Tr::tr("Initialization:"), m_varsBatDisplayLabel); + } + +protected: + void applyImpl() override {} + void discardImpl() override { setFromMsvcToolChain(); } + bool isDirtyImpl() const override { return false; } + void makeReadOnlyImpl() override {} + + void setFromMsvcToolChain() + { + const auto *tc = static_cast(toolChain()); + QTC_ASSERT(tc, return ); + m_nameDisplayLabel->setText(tc->displayName()); + m_varsBatDisplayLabel->setText(msvcVarsToDisplay(*tc)); + } + +protected: + QLabel *m_nameDisplayLabel; + QLabel *m_varsBatDisplayLabel; +}; // -------------------------------------------------------------------------- // MsvcToolChainConfigWidget // -------------------------------------------------------------------------- -MsvcToolChainConfigWidget::MsvcToolChainConfigWidget(ToolChain *tc) - : MsvcBasedToolChainConfigWidget(tc) - , m_varsBatPathCombo(new QComboBox(this)) - , m_varsBatArchCombo(new QComboBox(this)) - , m_varsBatArgumentsEdit(new QLineEdit(this)) - , m_abiWidget(new AbiWidget) +class MsvcToolChainConfigWidget final : public MsvcBasedToolChainConfigWidget { - m_mainLayout->removeRow(m_mainLayout->rowCount() - 1); +public: + explicit MsvcToolChainConfigWidget(ToolChain *tc) + : MsvcBasedToolChainConfigWidget(tc) + , m_varsBatPathCombo(new QComboBox(this)) + , m_varsBatArchCombo(new QComboBox(this)) + , m_varsBatArgumentsEdit(new QLineEdit(this)) + , m_abiWidget(new AbiWidget) + { + m_mainLayout->removeRow(m_mainLayout->rowCount() - 1); - QHBoxLayout *hLayout = new QHBoxLayout(); - m_varsBatPathCombo->setObjectName("varsBatCombo"); - m_varsBatPathCombo->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - m_varsBatPathCombo->setEditable(true); - for (const MsvcToolChain *tmpTc : std::as_const(g_availableMsvcToolchains)) { - const QString nativeVcVars = QDir::toNativeSeparators(tmpTc->varsBat()); - if (!tmpTc->varsBat().isEmpty() + QHBoxLayout *hLayout = new QHBoxLayout(); + m_varsBatPathCombo->setObjectName("varsBatCombo"); + m_varsBatPathCombo->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); + m_varsBatPathCombo->setEditable(true); + for (const MsvcToolChain *tmpTc : std::as_const(g_availableMsvcToolchains)) { + const QString nativeVcVars = QDir::toNativeSeparators(tmpTc->varsBat()); + if (!tmpTc->varsBat().isEmpty() && m_varsBatPathCombo->findText(nativeVcVars) == -1) { - m_varsBatPathCombo->addItem(nativeVcVars); + m_varsBatPathCombo->addItem(nativeVcVars); + } } - } - const bool isAmd64 + const bool isAmd64 = Utils::HostOsInfo::hostArchitecture() == Utils::HostOsInfo::HostArchitectureAMD64; - // TODO: Add missing values to MsvcToolChain::Platform - m_varsBatArchCombo->addItem(Tr::tr(""), isAmd64 ? MsvcToolChain::amd64 : MsvcToolChain::x86); - m_varsBatArchCombo->addItem("x86", MsvcToolChain::x86); - m_varsBatArchCombo->addItem("amd64", MsvcToolChain::amd64); - m_varsBatArchCombo->addItem("arm", MsvcToolChain::arm); - m_varsBatArchCombo->addItem("x86_amd64", MsvcToolChain::x86_amd64); - m_varsBatArchCombo->addItem("x86_arm", MsvcToolChain::x86_arm); - m_varsBatArchCombo->addItem("x86_arm64", MsvcToolChain::x86_arm64); - m_varsBatArchCombo->addItem("amd64_x86", MsvcToolChain::amd64_x86); - m_varsBatArchCombo->addItem("amd64_arm", MsvcToolChain::amd64_arm); - m_varsBatArchCombo->addItem("amd64_arm64", MsvcToolChain::amd64_arm64); - m_varsBatArchCombo->addItem("ia64", MsvcToolChain::ia64); - m_varsBatArchCombo->addItem("x86_ia64", MsvcToolChain::x86_ia64); - m_varsBatArchCombo->addItem("arm64", MsvcToolChain::arm64); - m_varsBatArchCombo->addItem("arm64_x86", MsvcToolChain::arm64_x86); - m_varsBatArchCombo->addItem("arm64_amd64", MsvcToolChain::arm64_amd64); - m_varsBatArgumentsEdit->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); - m_varsBatArgumentsEdit->setToolTip(Tr::tr("Additional arguments for the vcvarsall.bat call")); - hLayout->addWidget(m_varsBatPathCombo); - hLayout->addWidget(m_varsBatArchCombo); - hLayout->addWidget(m_varsBatArgumentsEdit); - m_mainLayout->addRow(Tr::tr("Initialization:"), hLayout); - m_mainLayout->addRow(Tr::tr("&ABI:"), m_abiWidget); - addErrorLabel(); - setFromMsvcToolChain(); + // TODO: Add missing values to MsvcToolChain::Platform + m_varsBatArchCombo->addItem(Tr::tr(""), isAmd64 ? MsvcToolChain::amd64 : MsvcToolChain::x86); + m_varsBatArchCombo->addItem("x86", MsvcToolChain::x86); + m_varsBatArchCombo->addItem("amd64", MsvcToolChain::amd64); + m_varsBatArchCombo->addItem("arm", MsvcToolChain::arm); + m_varsBatArchCombo->addItem("x86_amd64", MsvcToolChain::x86_amd64); + m_varsBatArchCombo->addItem("x86_arm", MsvcToolChain::x86_arm); + m_varsBatArchCombo->addItem("x86_arm64", MsvcToolChain::x86_arm64); + m_varsBatArchCombo->addItem("amd64_x86", MsvcToolChain::amd64_x86); + m_varsBatArchCombo->addItem("amd64_arm", MsvcToolChain::amd64_arm); + m_varsBatArchCombo->addItem("amd64_arm64", MsvcToolChain::amd64_arm64); + m_varsBatArchCombo->addItem("ia64", MsvcToolChain::ia64); + m_varsBatArchCombo->addItem("x86_ia64", MsvcToolChain::x86_ia64); + m_varsBatArchCombo->addItem("arm64", MsvcToolChain::arm64); + m_varsBatArchCombo->addItem("arm64_x86", MsvcToolChain::arm64_x86); + m_varsBatArchCombo->addItem("arm64_amd64", MsvcToolChain::arm64_amd64); + m_varsBatArgumentsEdit->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed); + m_varsBatArgumentsEdit->setToolTip(Tr::tr("Additional arguments for the vcvarsall.bat call")); + hLayout->addWidget(m_varsBatPathCombo); + hLayout->addWidget(m_varsBatArchCombo); + hLayout->addWidget(m_varsBatArgumentsEdit); + m_mainLayout->addRow(Tr::tr("Initialization:"), hLayout); + m_mainLayout->addRow(Tr::tr("&ABI:"), m_abiWidget); + addErrorLabel(); + setFromMsvcToolChain(); - connect(m_varsBatPathCombo, &QComboBox::currentTextChanged, - this, &MsvcToolChainConfigWidget::handleVcVarsChange); - connect(m_varsBatArchCombo, &QComboBox::currentTextChanged, - this, &MsvcToolChainConfigWidget::handleVcVarsArchChange); - connect(m_varsBatArgumentsEdit, &QLineEdit::textChanged, - this, &ToolChainConfigWidget::dirty); - connect(m_abiWidget, &AbiWidget::abiChanged, this, &ToolChainConfigWidget::dirty); -} + connect(m_varsBatPathCombo, &QComboBox::currentTextChanged, + this, &MsvcToolChainConfigWidget::handleVcVarsChange); + connect(m_varsBatArchCombo, &QComboBox::currentTextChanged, + this, &MsvcToolChainConfigWidget::handleVcVarsArchChange); + connect(m_varsBatArgumentsEdit, &QLineEdit::textChanged, + this, &ToolChainConfigWidget::dirty); + connect(m_abiWidget, &AbiWidget::abiChanged, this, &ToolChainConfigWidget::dirty); + } + +private: + void applyImpl() final; + void discardImpl() final; + bool isDirtyImpl() const final; + void makeReadOnlyImpl() final; + + void setFromMsvcToolChain(); + + void updateAbis(); + void handleVcVarsChange(const QString &vcVars); + void handleVcVarsArchChange(const QString &arch); + + QString vcVarsArguments() const; + + QComboBox *m_varsBatPathCombo; + QComboBox *m_varsBatArchCombo; + QLineEdit *m_varsBatArgumentsEdit; + AbiWidget *m_abiWidget; +}; void MsvcToolChainConfigWidget::applyImpl() { @@ -1472,42 +1503,64 @@ QString MsvcToolChainConfigWidget::vcVarsArguments() const return varsBatArg; } +std::unique_ptr MsvcToolChain::createConfigurationWidget() +{ + return std::make_unique(this); +} + // -------------------------------------------------------------------------- // ClangClToolChainConfigWidget // -------------------------------------------------------------------------- -ClangClToolChainConfigWidget::ClangClToolChainConfigWidget(ToolChain *tc) : - MsvcBasedToolChainConfigWidget(tc), - m_varsBatDisplayCombo(new QComboBox(this)) +class ClangClToolChainConfigWidget final : public MsvcBasedToolChainConfigWidget { - m_mainLayout->removeRow(m_mainLayout->rowCount() - 1); +public: + explicit ClangClToolChainConfigWidget(ToolChain *tc) + : MsvcBasedToolChainConfigWidget(tc) + , m_varsBatDisplayCombo(new QComboBox(this)) + { + m_mainLayout->removeRow(m_mainLayout->rowCount() - 1); - m_varsBatDisplayCombo->setObjectName("varsBatCombo"); - m_varsBatDisplayCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents); - m_mainLayout->addRow(Tr::tr("Initialization:"), m_varsBatDisplayCombo); + m_varsBatDisplayCombo->setObjectName("varsBatCombo"); + m_varsBatDisplayCombo->setSizeAdjustPolicy(QComboBox::AdjustToContents); + m_mainLayout->addRow(Tr::tr("Initialization:"), m_varsBatDisplayCombo); - if (tc->isAutoDetected()) { - m_llvmDirLabel = new QLabel(this); - m_llvmDirLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); - m_mainLayout->addRow(Tr::tr("&Compiler path:"), m_llvmDirLabel); - } else { - const QStringList gnuVersionArgs = QStringList("--version"); - m_compilerCommand = new Utils::PathChooser(this); - m_compilerCommand->setExpectedKind(Utils::PathChooser::ExistingCommand); - m_compilerCommand->setCommandVersionArguments(gnuVersionArgs); - m_compilerCommand->setHistoryCompleter("PE.Clang.Command.History"); - m_mainLayout->addRow(Tr::tr("&Compiler path:"), m_compilerCommand); + if (tc->isAutoDetected()) { + m_llvmDirLabel = new QLabel(this); + m_llvmDirLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); + m_mainLayout->addRow(Tr::tr("&Compiler path:"), m_llvmDirLabel); + } else { + const QStringList gnuVersionArgs = QStringList("--version"); + m_compilerCommand = new PathChooser(this); + m_compilerCommand->setExpectedKind(PathChooser::ExistingCommand); + m_compilerCommand->setCommandVersionArguments(gnuVersionArgs); + m_compilerCommand->setHistoryCompleter("PE.Clang.Command.History"); + m_mainLayout->addRow(Tr::tr("&Compiler path:"), m_compilerCommand); + } + addErrorLabel(); + setFromClangClToolChain(); + + if (m_compilerCommand) { + connect(m_compilerCommand, + &Utils::PathChooser::rawPathChanged, + this, + &ClangClToolChainConfigWidget::dirty); + } } - addErrorLabel(); - setFromClangClToolChain(); - if (m_compilerCommand) { - connect(m_compilerCommand, - &Utils::PathChooser::rawPathChanged, - this, - &ClangClToolChainConfigWidget::dirty); - } -} +protected: + void applyImpl() final; + void discardImpl() final; + bool isDirtyImpl() const override { return false; } + void makeReadOnlyImpl() final; + +private: + void setFromClangClToolChain(); + + QLabel *m_llvmDirLabel = nullptr; + QComboBox *m_varsBatDisplayCombo = nullptr; + PathChooser *m_compilerCommand = nullptr; +}; void ClangClToolChainConfigWidget::setFromClangClToolChain() { @@ -1789,9 +1842,9 @@ Macros ClangClToolChain::msvcPredefinedMacros(const QStringList &cxxflags, return Macro::toMacros(cpp.allRawOutput()); } -Utils::LanguageVersion ClangClToolChain::msvcLanguageVersion(const QStringList &cxxflags, - const Utils::Id &language, - const Macros ¯os) const +LanguageVersion ClangClToolChain::msvcLanguageVersion(const QStringList &cxxflags, + const Id &language, + const Macros ¯os) const { if (cxxflags.contains("--driver-mode=g++")) return ToolChain::languageVersion(language, macros); @@ -1810,18 +1863,30 @@ ClangClToolChain::BuiltInHeaderPathsRunner ClangClToolChain::createBuiltInHeader } // -------------------------------------------------------------------------- -// MsvcToolChainFactory +// MsvcToolchainFactory // -------------------------------------------------------------------------- -MsvcToolChainFactory::MsvcToolChainFactory() +class MsvcToolchainFactory : public ToolChainFactory { - setDisplayName(Tr::tr("MSVC")); - setSupportedToolChainType(Constants::MSVC_TOOLCHAIN_TYPEID); - setSupportedLanguages({Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}); - setToolchainConstructor([] { return new MsvcToolChain(Constants::MSVC_TOOLCHAIN_TYPEID); }); -} +public: + MsvcToolchainFactory() + { + setDisplayName(Tr::tr("MSVC")); + setSupportedToolChainType(Constants::MSVC_TOOLCHAIN_TYPEID); + setSupportedLanguages({Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}); + setToolchainConstructor([] { return new MsvcToolChain(Constants::MSVC_TOOLCHAIN_TYPEID); }); + } -QString MsvcToolChainFactory::vcVarsBatFor(const QString &basePath, + Toolchains autoDetect(const ToolchainDetector &detector) const final; + + bool canCreate() const final { return !g_availableMsvcToolchains.isEmpty(); } + + static QString vcVarsBatFor(const QString &basePath, + MsvcToolChain::Platform platform, + const QVersionNumber &v); +}; + +QString MsvcToolchainFactory::vcVarsBatFor(const QString &basePath, MsvcToolChain::Platform platform, const QVersionNumber &v) { @@ -1908,7 +1973,7 @@ static void detectCppBuildTools2015(Toolchains *list) } } -Toolchains MsvcToolChainFactory::autoDetect(const ToolchainDetector &detector) const +Toolchains MsvcToolchainFactory::autoDetect(const ToolchainDetector &detector) const { if (detector.device->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) { // FIXME currently no support for msvc toolchains on a device @@ -2010,60 +2075,6 @@ Toolchains MsvcToolChainFactory::autoDetect(const ToolchainDetector &detector) c return results; } -ClangClToolChainFactory::ClangClToolChainFactory() -{ - setDisplayName(Tr::tr("clang-cl")); - setSupportedLanguages({Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}); - setSupportedToolChainType(Constants::CLANG_CL_TOOLCHAIN_TYPEID); - setToolchainConstructor([] { return new ClangClToolChain; }); -} - -bool ClangClToolChainFactory::canCreate() const -{ - return !g_availableMsvcToolchains.isEmpty(); -} - -Toolchains ClangClToolChainFactory::autoDetect(const ToolchainDetector &detector) const -{ - if (detector.device->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) { - // FIXME currently no support for msvc toolchains on a device - return {}; - } -#ifdef Q_OS_WIN64 - const char registryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\LLVM\\LLVM"; -#else - const char registryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\LLVM\\LLVM"; -#endif - - Toolchains results; - Toolchains known = detector.alreadyKnown; - - FilePath qtCreatorsClang = Core::ICore::clangExecutable(CLANG_BINDIR); - if (!qtCreatorsClang.isEmpty()) { - qtCreatorsClang = qtCreatorsClang.parentDir().pathAppended("clang-cl.exe"); - results.append(detectClangClToolChainInPath(qtCreatorsClang, - detector.alreadyKnown, "", true)); - known.append(results); - } - - const QSettings registry(QLatin1String(registryNode), QSettings::NativeFormat); - if (registry.status() == QSettings::NoError) { - const FilePath path = FilePath::fromUserInput(registry.value(QStringLiteral(".")).toString()); - const FilePath clangClPath = path / "bin/clang-cl.exe"; - if (!path.isEmpty()) { - results.append(detectClangClToolChainInPath(clangClPath, known, "")); - known.append(results); - } - } - - const Utils::Environment systemEnvironment = Utils::Environment::systemEnvironment(); - const Utils::FilePath clangClPath = systemEnvironment.searchInPath("clang-cl.exe"); - if (!clangClPath.isEmpty()) - results.append(detectClangClToolChainInPath(clangClPath, known, "")); - - return results; -} - bool MsvcToolChain::operator==(const ToolChain &other) const { if (!ToolChain::operator==(other)) @@ -2184,11 +2195,6 @@ std::optional MsvcToolChain::generateEnvironmentSettings(const Utils::E return std::nullopt; } -bool MsvcToolChainFactory::canCreate() const -{ - return !g_availableMsvcToolchains.isEmpty(); -} - MsvcToolChain::WarningFlagAdder::WarningFlagAdder(const QString &flag, WarningFlags &flags) : m_flags(flags) { @@ -2227,7 +2233,81 @@ bool MsvcToolChain::WarningFlagAdder::triggered() const return m_triggered; } -} // namespace Internal -} // namespace ProjectExplorer +// -------------------------------------------------------------------------- +// ClangClToolchainFactory +// -------------------------------------------------------------------------- + +class ClangClToolchainFactory : public ToolChainFactory +{ +public: + ClangClToolchainFactory() + { + setDisplayName(Tr::tr("clang-cl")); + setSupportedLanguages({Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}); + setSupportedToolChainType(Constants::CLANG_CL_TOOLCHAIN_TYPEID); + setToolchainConstructor([] { return new ClangClToolChain; }); + } + + Toolchains autoDetect(const ToolchainDetector &detector) const final; + + bool canCreate() const final { return !g_availableMsvcToolchains.isEmpty(); } +}; + +Toolchains ClangClToolchainFactory::autoDetect(const ToolchainDetector &detector) const +{ + if (detector.device->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) { + // FIXME currently no support for msvc toolchains on a device + return {}; + } +#ifdef Q_OS_WIN64 + const char registryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\LLVM\\LLVM"; +#else + const char registryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\LLVM\\LLVM"; +#endif + + Toolchains results; + Toolchains known = detector.alreadyKnown; + + FilePath qtCreatorsClang = Core::ICore::clangExecutable(CLANG_BINDIR); + if (!qtCreatorsClang.isEmpty()) { + qtCreatorsClang = qtCreatorsClang.parentDir().pathAppended("clang-cl.exe"); + results.append(detectClangClToolChainInPath(qtCreatorsClang, + detector.alreadyKnown, "", true)); + known.append(results); + } + + const QSettings registry(QLatin1String(registryNode), QSettings::NativeFormat); + if (registry.status() == QSettings::NoError) { + const FilePath path = FilePath::fromUserInput(registry.value(QStringLiteral(".")).toString()); + const FilePath clangClPath = path / "bin/clang-cl.exe"; + if (!path.isEmpty()) { + results.append(detectClangClToolChainInPath(clangClPath, known, "")); + known.append(results); + } + } + + const Environment systemEnvironment = Environment::systemEnvironment(); + const FilePath clangClPath = systemEnvironment.searchInPath("clang-cl.exe"); + if (!clangClPath.isEmpty()) + results.append(detectClangClToolChainInPath(clangClPath, known, "")); + + return results; +} + +void setupMsvcToolchain() +{ +#ifdef Q_OS_WIN + static MsvcToolchainFactory theMsvcToolChainFactory; +#endif +} + +void setupClangClToolchain() +{ +#ifdef Q_OS_WIN + static ClangClToolchainFactory theClangClToolchainFactory; +#endif +} + +} // namespace ProjectExplorer::Internal Q_DECLARE_METATYPE(ProjectExplorer::Internal::MsvcToolChain::Platform) diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h index cfe2d4d7d9e..2165a1c84aa 100644 --- a/src/plugins/projectexplorer/msvctoolchain.h +++ b/src/plugins/projectexplorer/msvctoolchain.h @@ -14,16 +14,7 @@ #include -QT_FORWARD_DECLARE_CLASS(QLabel) -QT_FORWARD_DECLARE_CLASS(QComboBox) -QT_FORWARD_DECLARE_CLASS(QVersionNumber) - -namespace Utils { -class PathChooser; -} - -namespace ProjectExplorer { -namespace Internal { +namespace ProjectExplorer::Internal { // -------------------------------------------------------------------------- // MsvcToolChain @@ -170,113 +161,7 @@ private: Utils::FilePath m_clangPath; }; -// -------------------------------------------------------------------------- -// MsvcToolChainFactory -// -------------------------------------------------------------------------- +void setupMsvcToolchain(); +void setupClangClToolchain(); -class MsvcToolChainFactory : public ToolChainFactory -{ -public: - MsvcToolChainFactory(); - - Toolchains autoDetect(const ToolchainDetector &detector) const final; - - bool canCreate() const final; - - static QString vcVarsBatFor(const QString &basePath, - MsvcToolChain::Platform platform, - const QVersionNumber &v); -}; - -class ClangClToolChainFactory : public ToolChainFactory -{ -public: - ClangClToolChainFactory(); - - Toolchains autoDetect(const ToolchainDetector &detector) const final; - - bool canCreate() const final; -}; - -// -------------------------------------------------------------------------- -// MsvcBasedToolChainConfigWidget -// -------------------------------------------------------------------------- - -class MsvcBasedToolChainConfigWidget : public ToolChainConfigWidget -{ - Q_OBJECT - -public: - explicit MsvcBasedToolChainConfigWidget(ToolChain *); - -protected: - void applyImpl() override {} - void discardImpl() override { setFromMsvcToolChain(); } - bool isDirtyImpl() const override { return false; } - void makeReadOnlyImpl() override {} - - void setFromMsvcToolChain(); - -protected: - QLabel *m_nameDisplayLabel; - QLabel *m_varsBatDisplayLabel; -}; - -// -------------------------------------------------------------------------- -// MsvcToolChainConfigWidget -// -------------------------------------------------------------------------- - -class MsvcToolChainConfigWidget : public MsvcBasedToolChainConfigWidget -{ - Q_OBJECT - -public: - explicit MsvcToolChainConfigWidget(ToolChain *); - -private: - void applyImpl() override; - void discardImpl() override; - bool isDirtyImpl() const override; - void makeReadOnlyImpl() override; - - void setFromMsvcToolChain(); - - void updateAbis(); - void handleVcVarsChange(const QString &vcVars); - void handleVcVarsArchChange(const QString &arch); - - QString vcVarsArguments() const; - - QComboBox *m_varsBatPathCombo; - QComboBox *m_varsBatArchCombo; - QLineEdit *m_varsBatArgumentsEdit; - AbiWidget *m_abiWidget; -}; - -// -------------------------------------------------------------------------- -// ClangClToolChainConfigWidget -// -------------------------------------------------------------------------- - -class ClangClToolChainConfigWidget : public MsvcBasedToolChainConfigWidget -{ - Q_OBJECT - -public: - explicit ClangClToolChainConfigWidget(ToolChain *); - -protected: - void applyImpl() override; - void discardImpl() override; - bool isDirtyImpl() const override { return false; } - void makeReadOnlyImpl() override; - -private: - void setFromClangClToolChain(); - - QLabel *m_llvmDirLabel = nullptr; - QComboBox *m_varsBatDisplayCombo = nullptr; - Utils::PathChooser *m_compilerCommand = nullptr; -}; - -} // namespace Internal -} // namespace ProjectExplorer +} // namespace ProjectExplorer::Internal diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index f0cf98190e8..0d022cb659f 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -80,9 +80,10 @@ #ifdef Q_OS_WIN #include "windebuginterface.h" -#include "msvctoolchain.h" #endif +#include "msvctoolchain.h" + #include "customparser.h" #include "projecttree.h" #include "projectwelcomepage.h" @@ -643,8 +644,6 @@ public: #ifdef Q_OS_WIN WinDebugInterface m_winDebugInterface; - MsvcToolChainFactory m_mscvToolChainFactory; - ClangClToolChainFactory m_clangClToolChainFactory; #endif CustomToolChainFactory m_customToolChainFactory; @@ -815,6 +814,8 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er Q_UNUSED(error) setupGccToolchains(); + setupMsvcToolchain(); + setupClangClToolchain(); dd = new ProjectExplorerPluginPrivate; From 0d12bbf4329dc8eefa7bb02fd9278defe6304398 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 23 Nov 2023 23:37:57 +0100 Subject: [PATCH 0368/1546] ProjectExplorer: Remove unused member Change-Id: Ie7096da33d211f55d3ba37a5b685f5fb8ba89f23 Reviewed-by: Reviewed-by: Christian Kandeler --- src/plugins/projectexplorer/projectexplorer.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 0d022cb659f..e925ed66d2c 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -546,7 +546,6 @@ public: QMenu *m_openWithMenu; QMenu *m_openTerminalMenu; - QMultiMap m_actionMap; QAction *m_newAction; QAction *m_loadAction; ParameterAction *m_unloadAction; From 497b9b3c2cfba811591c609804da26b4ec5cf5fa Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Nov 2023 16:22:39 +0100 Subject: [PATCH 0369/1546] Android: Use new setup for a few factories Change-Id: I4538a2839b995f7bc245ae1a91f1979cc8c0dfdc Reviewed-by: Jarek Kobus --- src/plugins/android/androidbuildapkstep.cpp | 27 ++++++++++------- src/plugins/android/androidbuildapkstep.h | 12 ++------ src/plugins/android/androiddebugsupport.cpp | 17 ++++++++--- src/plugins/android/androiddebugsupport.h | 8 +---- src/plugins/android/androiddeployqtstep.cpp | 21 ++++++++++---- src/plugins/android/androiddeployqtstep.h | 8 +---- src/plugins/android/androidplugin.cpp | 29 ++++++++++++------- .../android/androidqmlpreviewworker.cpp | 22 ++++++++++---- src/plugins/android/androidqmlpreviewworker.h | 8 +---- .../android/androidqmltoolingsupport.cpp | 18 ++++++++---- .../android/androidqmltoolingsupport.h | 8 +---- .../android/androidrunconfiguration.cpp | 15 ++++++++-- src/plugins/android/androidrunconfiguration.h | 6 +--- src/plugins/android/androidruncontrol.cpp | 20 +++++++++---- src/plugins/android/androidruncontrol.h | 8 +---- src/plugins/android/androidsettingswidget.cpp | 21 ++++++++++---- src/plugins/android/androidsettingswidget.h | 8 +---- 17 files changed, 145 insertions(+), 111 deletions(-) diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index b04ad7ad40d..62b9f6fdcb0 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -64,8 +64,7 @@ using namespace ProjectExplorer; using namespace QtSupport; using namespace Utils; -namespace Android { -namespace Internal { +namespace Android::Internal { static Q_LOGGING_CATEGORY(buildapkstepLog, "qtc.android.build.androidbuildapkstep", QtWarningMsg) @@ -1072,14 +1071,22 @@ QString PasswordInputDialog::getPassword(Context context, std::function(Constants::ANDROID_BUILD_APK_ID); - setSupportedDeviceType(Constants::ANDROID_DEVICE_TYPE); - setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); - setDisplayName(Tr::tr("Build Android APK")); - setRepeatable(false); +public: + AndroidBuildApkStepFactory() + { + registerStep(Constants::ANDROID_BUILD_APK_ID); + setSupportedDeviceType(Constants::ANDROID_DEVICE_TYPE); + setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); + setDisplayName(Tr::tr("Build Android APK")); + setRepeatable(false); + } +}; + +void setupAndroidBuildApkStep() +{ + static AndroidBuildApkStepFactory theAndroidBuildApkStepFactory; } -} // namespace Internal -} // namespace Android +} // Android::Internal diff --git a/src/plugins/android/androidbuildapkstep.h b/src/plugins/android/androidbuildapkstep.h index 0280290dfd2..12ffe3ebd4f 100644 --- a/src/plugins/android/androidbuildapkstep.h +++ b/src/plugins/android/androidbuildapkstep.h @@ -13,8 +13,7 @@ QT_BEGIN_NAMESPACE class QAbstractItemModel; QT_END_NAMESPACE -namespace Android { -namespace Internal { +namespace Android::Internal { class AndroidBuildApkStep : public ProjectExplorer::AbstractProcessStep { @@ -84,11 +83,6 @@ private: Utils::FilePath m_inputFile; }; -class AndroidBuildApkStepFactory : public ProjectExplorer::BuildStepFactory -{ -public: - AndroidBuildApkStepFactory(); -}; +void setupAndroidBuildApkStep(); -} // namespace Internal -} // namespace Android +} // Android::Internal diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp index 7b836171502..f4ef4cc0305 100644 --- a/src/plugins/android/androiddebugsupport.cpp +++ b/src/plugins/android/androiddebugsupport.cpp @@ -200,11 +200,20 @@ void AndroidDebugSupport::stop() // AndroidDebugWorkerFactory -AndroidDebugWorkerFactory::AndroidDebugWorkerFactory() +class AndroidDebugWorkerFactory final : public RunWorkerFactory { - setProduct(); - addSupportedRunMode(ProjectExplorer::Constants::DEBUG_RUN_MODE); - addSupportedRunConfig(Constants::ANDROID_RUNCONFIG_ID); +public: + AndroidDebugWorkerFactory() + { + setProduct(); + addSupportedRunMode(ProjectExplorer::Constants::DEBUG_RUN_MODE); + addSupportedRunConfig(Constants::ANDROID_RUNCONFIG_ID); + } +}; + +void setupAndroidDebugWorker() +{ + static AndroidDebugWorkerFactory theAndroidDebugWorkerFactory; } } // Android::Internal diff --git a/src/plugins/android/androiddebugsupport.h b/src/plugins/android/androiddebugsupport.h index 3c91722179f..8fea7252664 100644 --- a/src/plugins/android/androiddebugsupport.h +++ b/src/plugins/android/androiddebugsupport.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace Android::Internal { -class AndroidDebugWorkerFactory final : public ProjectExplorer::RunWorkerFactory -{ -public: - AndroidDebugWorkerFactory(); -}; +void setupAndroidDebugWorker(); } // Android::Internal diff --git a/src/plugins/android/androiddeployqtstep.cpp b/src/plugins/android/androiddeployqtstep.cpp index 36ea8d42dc8..2f5205e7141 100644 --- a/src/plugins/android/androiddeployqtstep.cpp +++ b/src/plugins/android/androiddeployqtstep.cpp @@ -660,13 +660,22 @@ void AndroidDeployQtStep::reportWarningOrError(const QString &message, Task::Tas // AndroidDeployQtStepFactory -AndroidDeployQtStepFactory::AndroidDeployQtStepFactory() +class AndroidDeployQtStepFactory final : public BuildStepFactory { - registerStep(Constants::ANDROID_DEPLOY_QT_ID); - setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); - setSupportedDeviceType(Constants::ANDROID_DEVICE_TYPE); - setRepeatable(false); - setDisplayName(Tr::tr("Deploy to Android device")); +public: + AndroidDeployQtStepFactory() + { + registerStep(Constants::ANDROID_DEPLOY_QT_ID); + setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_DEPLOY); + setSupportedDeviceType(Constants::ANDROID_DEVICE_TYPE); + setRepeatable(false); + setDisplayName(Tr::tr("Deploy to Android device")); + } +}; + +void setupAndroidDeployQtStep() +{ + static AndroidDeployQtStepFactory theAndroidDeployQtStepFactory; } } // Android::Internal diff --git a/src/plugins/android/androiddeployqtstep.h b/src/plugins/android/androiddeployqtstep.h index dda4304b6af..3ed600a7f4a 100644 --- a/src/plugins/android/androiddeployqtstep.h +++ b/src/plugins/android/androiddeployqtstep.h @@ -4,14 +4,8 @@ #pragma once -#include - namespace Android::Internal { -class AndroidDeployQtStepFactory : public ProjectExplorer::BuildStepFactory -{ -public: - AndroidDeployQtStepFactory(); -}; +void setupAndroidDeployQtStep(); } // Android::Internal diff --git a/src/plugins/android/androidplugin.cpp b/src/plugins/android/androidplugin.cpp index 9eeee4dad29..82ddfaf5141 100644 --- a/src/plugins/android/androidplugin.cpp +++ b/src/plugins/android/androidplugin.cpp @@ -61,7 +61,7 @@ const char kSetupAndroidSetting[] = "ConfigureAndroid"; namespace Android::Internal { -class AndroidDeployConfigurationFactory : public DeployConfigurationFactory +class AndroidDeployConfigurationFactory final : public DeployConfigurationFactory { public: AndroidDeployConfigurationFactory() @@ -73,26 +73,22 @@ public: } }; +void setupAndroidDeployConfiguration() +{ + static AndroidDeployConfigurationFactory theAndroidDeployConfigurationFactory; +} + class AndroidPluginPrivate : public QObject { public: AndroidConfigurations androidConfiguration; - AndroidSettingsPage settingsPage; - AndroidDeployQtStepFactory deployQtStepFactory; AndroidQtVersionFactory qtVersionFactory; AndroidToolChainFactory toolChainFactory; - AndroidDeployConfigurationFactory deployConfigurationFactory; AndroidDeviceFactory deviceFactory; AndroidPotentialKit potentialKit; JavaEditorFactory javaEditorFactory; AndroidPackageInstallationFactory packackeInstallationFactory; AndroidManifestEditorFactory manifestEditorFactory; - AndroidRunConfigurationFactory runConfigFactory; - AndroidRunWorkerFactory runWorkerFactory; - AndroidDebugWorkerFactory debugWorkerFactory; - AndroidQmlToolingSupportFactory profilerWorkerFactory; - AndroidQmlPreviewWorkerFactory qmlPreviewWorkerFactory; - AndroidBuildApkStepFactory buildApkStepFactory; AndroidDeviceManager deviceManager; }; @@ -105,6 +101,19 @@ void AndroidPlugin::initialize() { d = new AndroidPluginPrivate; + setupAndroidSettingsPage(); + + setupAndroidBuildApkStep(); + + setupAndroidDeployConfiguration(); + setupAndroidDeployQtStep(); + + setupAndroidRunConfiguration(); + setupAndroidRunWorker(); + setupAndroidDebugWorker(); + setupAndroidQmlToolingSupport(); + setupAndroidQmlPreviewWorker(); + connect(KitManager::instance(), &KitManager::kitsLoaded, this, &AndroidPlugin::kitsRestored); diff --git a/src/plugins/android/androidqmlpreviewworker.cpp b/src/plugins/android/androidqmlpreviewworker.cpp index fc51e2a22dd..836dcebb15c 100644 --- a/src/plugins/android/androidqmlpreviewworker.cpp +++ b/src/plugins/android/androidqmlpreviewworker.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -489,13 +490,22 @@ bool AndroidQmlPreviewWorker::stopPreviewApp() // AndroidQmlPreviewWorkerFactory -AndroidQmlPreviewWorkerFactory::AndroidQmlPreviewWorkerFactory() +class AndroidQmlPreviewWorkerFactory final : public RunWorkerFactory { - setProduct(); - addSupportedRunMode(ProjectExplorer::Constants::QML_PREVIEW_RUN_MODE); - addSupportedRunConfig("QmlProjectManager.QmlRunConfiguration.Qml"); - addSupportedRunConfig(Constants::ANDROID_RUNCONFIG_ID); - addSupportedDeviceType(Android::Constants::ANDROID_DEVICE_TYPE); +public: + AndroidQmlPreviewWorkerFactory() + { + setProduct(); + addSupportedRunMode(ProjectExplorer::Constants::QML_PREVIEW_RUN_MODE); + addSupportedRunConfig("QmlProjectManager.QmlRunConfiguration.Qml"); + addSupportedRunConfig(Constants::ANDROID_RUNCONFIG_ID); + addSupportedDeviceType(Android::Constants::ANDROID_DEVICE_TYPE); + } +}; + +void setupAndroidQmlPreviewWorker() +{ + static AndroidQmlPreviewWorkerFactory theAndroidQmlPreviewWorkerFactory; } } // Android::Internal diff --git a/src/plugins/android/androidqmlpreviewworker.h b/src/plugins/android/androidqmlpreviewworker.h index 5b4b18b5dca..336f02764ac 100644 --- a/src/plugins/android/androidqmlpreviewworker.h +++ b/src/plugins/android/androidqmlpreviewworker.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace Android::Internal { -class AndroidQmlPreviewWorkerFactory final : public ProjectExplorer::RunWorkerFactory -{ -public: - AndroidQmlPreviewWorkerFactory(); -}; +void setupAndroidQmlPreviewWorker(); } // Android::Internal diff --git a/src/plugins/android/androidqmltoolingsupport.cpp b/src/plugins/android/androidqmltoolingsupport.cpp index fd1996fd0a3..e89e9e0414a 100644 --- a/src/plugins/android/androidqmltoolingsupport.cpp +++ b/src/plugins/android/androidqmltoolingsupport.cpp @@ -34,12 +34,20 @@ private: void stop() override { reportStopped(); } }; - -AndroidQmlToolingSupportFactory::AndroidQmlToolingSupportFactory() +class AndroidQmlToolingSupportFactory final : public RunWorkerFactory { - setProduct(); - addSupportedRunMode(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); - addSupportedRunConfig(Constants::ANDROID_RUNCONFIG_ID); +public: + AndroidQmlToolingSupportFactory() + { + setProduct(); + addSupportedRunMode(ProjectExplorer::Constants::QML_PROFILER_RUN_MODE); + addSupportedRunConfig(Constants::ANDROID_RUNCONFIG_ID); + } +}; + +void setupAndroidQmlToolingSupport() +{ + static AndroidQmlToolingSupportFactory theAndroidQmlToolingSupportFactory; } } // Android::Internal diff --git a/src/plugins/android/androidqmltoolingsupport.h b/src/plugins/android/androidqmltoolingsupport.h index 503bbe0d107..d5ac04a2a9a 100644 --- a/src/plugins/android/androidqmltoolingsupport.h +++ b/src/plugins/android/androidqmltoolingsupport.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace Android::Internal { -class AndroidQmlToolingSupportFactory final : public ProjectExplorer::RunWorkerFactory -{ -public: - AndroidQmlToolingSupportFactory(); -}; +void setupAndroidQmlToolingSupport(); } // Android::Internal diff --git a/src/plugins/android/androidrunconfiguration.cpp b/src/plugins/android/androidrunconfiguration.cpp index 3f241fc50a4..8a057a3faa1 100644 --- a/src/plugins/android/androidrunconfiguration.cpp +++ b/src/plugins/android/androidrunconfiguration.cpp @@ -96,10 +96,19 @@ public: BaseStringListAspect postStartShellCmd{this}; }; -AndroidRunConfigurationFactory::AndroidRunConfigurationFactory() +class AndroidRunConfigurationFactory : public RunConfigurationFactory { - registerRunConfiguration("Qt4ProjectManager.AndroidRunConfiguration:"); - addSupportedTargetDeviceType(Android::Constants::ANDROID_DEVICE_TYPE); +public: + AndroidRunConfigurationFactory() + { + registerRunConfiguration("Qt4ProjectManager.AndroidRunConfiguration:"); + addSupportedTargetDeviceType(Android::Constants::ANDROID_DEVICE_TYPE); + } +}; + +void setupAndroidRunConfiguration() +{ + static AndroidRunConfigurationFactory theAndroidRunConfigurationFactory; } } // namespace Android diff --git a/src/plugins/android/androidrunconfiguration.h b/src/plugins/android/androidrunconfiguration.h index 8652c4ddfc6..0be06985e9d 100644 --- a/src/plugins/android/androidrunconfiguration.h +++ b/src/plugins/android/androidrunconfiguration.h @@ -7,10 +7,6 @@ namespace Android { -class AndroidRunConfigurationFactory : public ProjectExplorer::RunConfigurationFactory -{ -public: - AndroidRunConfigurationFactory(); -}; +void setupAndroidRunConfiguration(); } // namespace Android diff --git a/src/plugins/android/androidruncontrol.cpp b/src/plugins/android/androidruncontrol.cpp index 4dc0aea4296..60a239e3d97 100644 --- a/src/plugins/android/androidruncontrol.cpp +++ b/src/plugins/android/androidruncontrol.cpp @@ -19,8 +19,7 @@ namespace Android::Internal { class AndroidRunSupport final : public AndroidRunner { public: - explicit AndroidRunSupport(ProjectExplorer::RunControl *runControl, - const QString &intentName = QString()); + explicit AndroidRunSupport(RunControl *runControl, const QString &intentName = QString()); ~AndroidRunSupport() override; }; @@ -35,11 +34,20 @@ AndroidRunSupport::~AndroidRunSupport() stop(); } -AndroidRunWorkerFactory::AndroidRunWorkerFactory() +class AndroidRunWorkerFactory final : public RunWorkerFactory { - setProduct(); - addSupportedRunMode(ProjectExplorer::Constants::NORMAL_RUN_MODE); - addSupportedRunConfig(Constants::ANDROID_RUNCONFIG_ID); +public: + AndroidRunWorkerFactory() + { + setProduct(); + addSupportedRunMode(ProjectExplorer::Constants::NORMAL_RUN_MODE); + addSupportedRunConfig(Constants::ANDROID_RUNCONFIG_ID); + } +}; + +void setupAndroidRunWorker() +{ + static AndroidRunWorkerFactory theAndroidRunWorkerFactory; } } // Android::Internal diff --git a/src/plugins/android/androidruncontrol.h b/src/plugins/android/androidruncontrol.h index f96c19443b0..9c6fee8f251 100644 --- a/src/plugins/android/androidruncontrol.h +++ b/src/plugins/android/androidruncontrol.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace Android::Internal { -class AndroidRunWorkerFactory final : public ProjectExplorer::RunWorkerFactory -{ -public: - AndroidRunWorkerFactory(); -}; +void setupAndroidRunWorker(); } // Android::Internal diff --git a/src/plugins/android/androidsettingswidget.cpp b/src/plugins/android/androidsettingswidget.cpp index ce8fbcf8614..d84f0349846 100644 --- a/src/plugins/android/androidsettingswidget.cpp +++ b/src/plugins/android/androidsettingswidget.cpp @@ -9,6 +9,8 @@ #include "androidsettingswidget.h" #include "androidtr.h" +#include + #include #include @@ -765,12 +767,21 @@ void AndroidSettingsWidget::downloadSdk() // AndroidSettingsPage -AndroidSettingsPage::AndroidSettingsPage() +class AndroidSettingsPage final : public Core::IOptionsPage { - setId(Constants::ANDROID_SETTINGS_ID); - setDisplayName(Tr::tr("Android")); - setCategory(ProjectExplorer::Constants::DEVICE_SETTINGS_CATEGORY); - setWidgetCreator([] { return new AndroidSettingsWidget; }); +public: + AndroidSettingsPage() + { + setId(Constants::ANDROID_SETTINGS_ID); + setDisplayName(Tr::tr("Android")); + setCategory(ProjectExplorer::Constants::DEVICE_SETTINGS_CATEGORY); + setWidgetCreator([] { return new AndroidSettingsWidget; }); + } +}; + +void setupAndroidSettingsPage() +{ + static AndroidSettingsPage theAndroidSettingsPage; } } // Android::Internal diff --git a/src/plugins/android/androidsettingswidget.h b/src/plugins/android/androidsettingswidget.h index 0b50d3df7d5..7f28a6a4c83 100644 --- a/src/plugins/android/androidsettingswidget.h +++ b/src/plugins/android/androidsettingswidget.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace Android::Internal { -class AndroidSettingsPage final : public Core::IOptionsPage -{ -public: - AndroidSettingsPage(); -}; +void setupAndroidSettingsPage(); } // Android::Internal From 353c3cc93081a7d44f42f611f38f0248a26175bd Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Nov 2023 17:46:57 +0100 Subject: [PATCH 0370/1546] Android: Use new setup for more plugin items Change-Id: Id5ff09813ab7b4be425d007abd4cc04d9c9472c1 Reviewed-by: Jarek Kobus --- src/plugins/android/androidconfigurations.cpp | 33 ++++---- src/plugins/android/androidconfigurations.h | 12 ++- src/plugins/android/androiddevice.cpp | 60 ++++++++------ src/plugins/android/androiddevice.h | 17 +--- .../android/androidmanifesteditorfactory.cpp | 45 +++++++---- .../android/androidmanifesteditorfactory.h | 19 +---- .../androidpackageinstallationstep.cpp | 29 ++++--- .../android/androidpackageinstallationstep.h | 14 +--- src/plugins/android/androidplugin.cpp | 23 +++--- src/plugins/android/androidpotentialkit.cpp | 78 +++++++++++-------- src/plugins/android/androidpotentialkit.h | 11 +-- src/plugins/android/androidqtversion.cpp | 36 +++++---- src/plugins/android/androidqtversion.h | 15 +--- src/plugins/android/androidtoolchain.cpp | 11 ++- src/plugins/android/androidtoolchain.h | 8 +- src/plugins/android/javaeditor.cpp | 48 ++++++------ src/plugins/android/javaeditor.h | 8 +- 17 files changed, 240 insertions(+), 227 deletions(-) diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index 1c6f8c7cbce..37e9c148c59 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -1104,6 +1104,19 @@ FilePath AndroidConfig::defaultSdkPath() /////////////////////////////////// // AndroidConfigurations /////////////////////////////////// + +AndroidConfigurations *m_instance = nullptr; + +AndroidConfigurations::AndroidConfigurations() + : m_sdkManager(new AndroidSdkManager(m_config)) +{ + load(); + connect(DeviceManager::instance(), &DeviceManager::devicesLoaded, + this, &AndroidConfigurations::updateAndroidDevice); + + m_instance = this; +} + void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs) { emit m_instance->aboutToUpdate(); @@ -1452,18 +1465,6 @@ void AndroidConfigurations::save() settings->endGroup(); } -AndroidConfigurations::AndroidConfigurations() - : m_sdkManager(new AndroidSdkManager(m_config)) -{ - load(); - connect(DeviceManager::instance(), &DeviceManager::devicesLoaded, - this, &AndroidConfigurations::updateAndroidDevice); - - m_instance = this; -} - -AndroidConfigurations::~AndroidConfigurations() = default; - static FilePath androidStudioPath() { #if defined(Q_OS_WIN) @@ -1562,8 +1563,6 @@ void AndroidConfigurations::updateAndroidDevice() AndroidDeviceManager::instance()->setupDevicesWatcher(); } -AndroidConfigurations *AndroidConfigurations::m_instance = nullptr; - #ifdef WITH_TESTS void AndroidPlugin::testAndroidConfigAvailableNdkPlatforms_data() { @@ -1620,6 +1619,12 @@ void AndroidPlugin::testAndroidConfigAvailableNdkPlatforms() const QList foundPlatforms = availableNdkPlatformsImpl(ndkPath, abis, hostOs); QCOMPARE(foundPlatforms, expectedPlatforms); } + #endif // WITH_TESTS +void setupAndroidConfigurations() +{ + static AndroidConfigurations theAndroidConfigurations; +} + } // namespace Android diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index c92deec331c..aa956bb4e09 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -23,10 +23,7 @@ namespace ProjectExplorer { class Abi; } namespace Android { -namespace Internal { -class AndroidSdkManager; -class AndroidPluginPrivate; -} +namespace Internal { class AndroidSdkManager; } class CreateAvdInfo { @@ -200,18 +197,19 @@ signals: void updated(); private: - friend class Android::Internal::AndroidPluginPrivate; + friend void setupAndroidConfigurations(); AndroidConfigurations(); - ~AndroidConfigurations() override; + void load(); void save(); static void updateAndroidDevice(); - static AndroidConfigurations *m_instance; AndroidConfig m_config; std::unique_ptr m_sdkManager; }; +void setupAndroidConfigurations(); + } // namespace Android Q_DECLARE_METATYPE(ProjectExplorer::Abis) diff --git a/src/plugins/android/androiddevice.cpp b/src/plugins/android/androiddevice.cpp index 23cfa76592f..3e42b42a930 100644 --- a/src/plugins/android/androiddevice.cpp +++ b/src/plugins/android/androiddevice.cpp @@ -41,8 +41,7 @@ namespace { static Q_LOGGING_CATEGORY(androidDeviceLog, "qtc.android.androiddevice", QtWarningMsg) } -namespace Android { -namespace Internal { +namespace Android::Internal { static constexpr char ipRegexStr[] = "(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})"; static const QRegularExpression ipRegex = QRegularExpression(ipRegexStr); @@ -831,33 +830,44 @@ AndroidDeviceManager::~AndroidDeviceManager() // Factory -AndroidDeviceFactory::AndroidDeviceFactory() - : IDeviceFactory(Constants::ANDROID_DEVICE_TYPE), - m_androidConfig(AndroidConfigurations::currentConfig()) +class AndroidDeviceFactory final : public ProjectExplorer::IDeviceFactory { - setDisplayName(Tr::tr("Android Device")); - setCombinedIcon(":/android/images/androiddevicesmall.png", - ":/android/images/androiddevice.png"); - setConstructionFunction(&AndroidDevice::create); - if (m_androidConfig.sdkToolsOk()) { - setCreator([this] { - AvdDialog dialog = AvdDialog(m_androidConfig, Core::ICore::dialogParent()); - if (dialog.exec() != QDialog::Accepted) - return IDevice::Ptr(); +public: + AndroidDeviceFactory() + : IDeviceFactory(Constants::ANDROID_DEVICE_TYPE), + m_androidConfig(AndroidConfigurations::currentConfig()) + { + setDisplayName(Tr::tr("Android Device")); + setCombinedIcon(":/android/images/androiddevicesmall.png", + ":/android/images/androiddevice.png"); + setConstructionFunction(&AndroidDevice::create); + if (m_androidConfig.sdkToolsOk()) { + setCreator([this] { + AvdDialog dialog = AvdDialog(m_androidConfig, Core::ICore::dialogParent()); + if (dialog.exec() != QDialog::Accepted) + return IDevice::Ptr(); - const IDevice::Ptr dev = dialog.device(); - if (const auto androidDev = static_cast(dev.data())) { - qCDebug(androidDeviceLog, "Created new Android AVD id \"%s\".", - qPrintable(androidDev->avdName())); - } else { - AndroidDeviceWidget::criticalDialog( + const IDevice::Ptr dev = dialog.device(); + if (const auto androidDev = static_cast(dev.data())) { + qCDebug(androidDeviceLog, "Created new Android AVD id \"%s\".", + qPrintable(androidDev->avdName())); + } else { + AndroidDeviceWidget::criticalDialog( Tr::tr("The device info returned from AvdDialog is invalid.")); - } + } - return IDevice::Ptr(dev); - }); + return IDevice::Ptr(dev); + }); + } } + +private: + const AndroidConfig &m_androidConfig; +}; + +void setupAndroidDevice() +{ + static AndroidDeviceFactory theAndroidDeviceFactory; } -} // namespace Internal -} // namespace Android +} // Android::Internal diff --git a/src/plugins/android/androiddevice.h b/src/plugins/android/androiddevice.h index 2ac753e50ab..80f1e365c9f 100644 --- a/src/plugins/android/androiddevice.h +++ b/src/plugins/android/androiddevice.h @@ -17,8 +17,7 @@ namespace Utils { class Process; } -namespace Android { -namespace Internal { +namespace Android::Internal { class AndroidDevice final : public ProjectExplorer::IDevice { @@ -70,15 +69,6 @@ private: std::unique_ptr m_avdSettings; }; -class AndroidDeviceFactory final : public ProjectExplorer::IDeviceFactory -{ -public: - AndroidDeviceFactory(); - -private: - const AndroidConfig &m_androidConfig; -}; - class AndroidDeviceManager : public QObject { public: @@ -114,5 +104,6 @@ private: friend class AndroidPluginPrivate; }; -} // namespace Internal -} // namespace Android +void setupAndroidDevice(); + +} // Android::Internal diff --git a/src/plugins/android/androidmanifesteditorfactory.cpp b/src/plugins/android/androidmanifesteditorfactory.cpp index 93f0d9a4ea7..7a900a687ec 100644 --- a/src/plugins/android/androidmanifesteditorfactory.cpp +++ b/src/plugins/android/androidmanifesteditorfactory.cpp @@ -7,22 +7,39 @@ #include "androidmanifesteditorwidget.h" #include "androidtr.h" +#include + +#include #include -using namespace Android; -using namespace Android::Internal; +namespace Android::Internal { -AndroidManifestEditorFactory::AndroidManifestEditorFactory() - : m_actionHandler(Constants::ANDROID_MANIFEST_EDITOR_ID, - Constants::ANDROID_MANIFEST_EDITOR_CONTEXT, - TextEditor::TextEditorActionHandler::UnCommentSelection, - [](Core::IEditor *editor) { return static_cast(editor)->textEditor(); }) +class AndroidManifestEditorFactory final : public Core::IEditorFactory { - setId(Constants::ANDROID_MANIFEST_EDITOR_ID); - setDisplayName(Tr::tr("Android Manifest editor")); - addMimeType(Constants::ANDROID_MANIFEST_MIME_TYPE); - setEditorCreator([] { - auto androidManifestEditorWidget = new AndroidManifestEditorWidget; - return androidManifestEditorWidget->editor(); - }); +public: + AndroidManifestEditorFactory() + : m_actionHandler(Constants::ANDROID_MANIFEST_EDITOR_ID, + Constants::ANDROID_MANIFEST_EDITOR_CONTEXT, + TextEditor::TextEditorActionHandler::UnCommentSelection, + [](Core::IEditor *editor) { return static_cast(editor)->textEditor(); }) + { + setId(Constants::ANDROID_MANIFEST_EDITOR_ID); + setDisplayName(Tr::tr("Android Manifest editor")); + addMimeType(Constants::ANDROID_MANIFEST_MIME_TYPE); + setEditorCreator([] { + auto androidManifestEditorWidget = new AndroidManifestEditorWidget; + return androidManifestEditorWidget->editor(); + }); + } + +private: + TextEditor::TextEditorActionHandler m_actionHandler; +}; + +void setupAndroidManifestEditor() +{ + static AndroidManifestEditorFactory theAndroidManifestEditorFactory; } + +} // Android::Internal + diff --git a/src/plugins/android/androidmanifesteditorfactory.h b/src/plugins/android/androidmanifesteditorfactory.h index 4ced1260c62..fe812fd94a6 100644 --- a/src/plugins/android/androidmanifesteditorfactory.h +++ b/src/plugins/android/androidmanifesteditorfactory.h @@ -3,21 +3,8 @@ #pragma once -#include +namespace Android::Internal { -#include +void setupAndroidManifestEditor(); -namespace Android { -namespace Internal { - -class AndroidManifestEditorFactory final : public Core::IEditorFactory -{ -public: - AndroidManifestEditorFactory(); - -private: - TextEditor::TextEditorActionHandler m_actionHandler; -}; - -} // namespace Internal -} // namespace Android +} // Android::Internal diff --git a/src/plugins/android/androidpackageinstallationstep.cpp b/src/plugins/android/androidpackageinstallationstep.cpp index e5398654b84..dc5b8ffc478 100644 --- a/src/plugins/android/androidpackageinstallationstep.cpp +++ b/src/plugins/android/androidpackageinstallationstep.cpp @@ -34,8 +34,7 @@ namespace { static Q_LOGGING_CATEGORY(packageInstallationStepLog, "qtc.android.packageinstallationstep", QtWarningMsg) } -namespace Android { -namespace Internal { +namespace Android::Internal { class AndroidPackageInstallationStep final : public AbstractProcessStep { @@ -182,18 +181,24 @@ void AndroidPackageInstallationStep::reportWarningOrError(const QString &message TaskHub::addTask(BuildSystemTask(type, message)); } -// // AndroidPackageInstallationStepFactory -// -AndroidPackageInstallationFactory::AndroidPackageInstallationFactory() +class AndroidPackageInstallationStepFactory final : public ProjectExplorer::BuildStepFactory { - registerStep(Constants::ANDROID_PACKAGE_INSTALL_STEP_ID); - setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); - setSupportedDeviceType(Android::Constants::ANDROID_DEVICE_TYPE); - setRepeatable(false); - setDisplayName(Tr::tr("Deploy to device")); +public: + AndroidPackageInstallationStepFactory() + { + registerStep(Constants::ANDROID_PACKAGE_INSTALL_STEP_ID); + setSupportedStepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); + setSupportedDeviceType(Android::Constants::ANDROID_DEVICE_TYPE); + setRepeatable(false); + setDisplayName(Tr::tr("Deploy to device")); + } +}; + +void setupAndroidPackageInstallationStep() +{ + static AndroidPackageInstallationStepFactory theAndroidPackageInstallationStepFactory; } -} // namespace Internal -} // namespace Android +} // Android::Internal diff --git a/src/plugins/android/androidpackageinstallationstep.h b/src/plugins/android/androidpackageinstallationstep.h index debc2a3cdbb..9226e27fe48 100644 --- a/src/plugins/android/androidpackageinstallationstep.h +++ b/src/plugins/android/androidpackageinstallationstep.h @@ -3,16 +3,8 @@ #pragma once -#include +namespace Android::Internal { -namespace Android { -namespace Internal { +void setupAndroidPackageInstallationStep(); -class AndroidPackageInstallationFactory final : public ProjectExplorer::BuildStepFactory -{ -public: - AndroidPackageInstallationFactory(); -}; - -} // namespace Internal -} // namespace Android +} // Android::Internal diff --git a/src/plugins/android/androidplugin.cpp b/src/plugins/android/androidplugin.cpp index 82ddfaf5141..2ad8e2c6851 100644 --- a/src/plugins/android/androidplugin.cpp +++ b/src/plugins/android/androidplugin.cpp @@ -81,14 +81,6 @@ void setupAndroidDeployConfiguration() class AndroidPluginPrivate : public QObject { public: - AndroidConfigurations androidConfiguration; - AndroidQtVersionFactory qtVersionFactory; - AndroidToolChainFactory toolChainFactory; - AndroidDeviceFactory deviceFactory; - AndroidPotentialKit potentialKit; - JavaEditorFactory javaEditorFactory; - AndroidPackageInstallationFactory packackeInstallationFactory; - AndroidManifestEditorFactory manifestEditorFactory; AndroidDeviceManager deviceManager; }; @@ -99,10 +91,18 @@ AndroidPlugin::~AndroidPlugin() void AndroidPlugin::initialize() { + setupAndroidConfigurations(); + + setupAndroidPotentialKit(); + setupAndroidDevice(); + setupAndroidQtVersion(); + setupAndroidToolchain(); + d = new AndroidPluginPrivate; setupAndroidSettingsPage(); + setupAndroidPackageInstallationStep(); setupAndroidBuildApkStep(); setupAndroidDeployConfiguration(); @@ -114,6 +114,9 @@ void AndroidPlugin::initialize() setupAndroidQmlToolingSupport(); setupAndroidQmlPreviewWorker(); + setupJavaEditor(); + setupAndroidManifestEditor(); + connect(KitManager::instance(), &KitManager::kitsLoaded, this, &AndroidPlugin::kitsRestored); @@ -166,7 +169,9 @@ void AndroidPlugin::askUserAboutAndroidSetup() info.addCustomButton(Tr::tr("Configure Android"), [this] { Core::ICore::infoBar()->removeInfo(kSetupAndroidSetting); Core::ICore::infoBar()->globallySuppressInfo(kSetupAndroidSetting); - QTimer::singleShot(0, this, [this] { d->potentialKit.executeFromMenu(); }); + QTimer::singleShot(0, this, [] { + Core::ICore::showOptionsDialog(Constants::ANDROID_SETTINGS_ID); + }); }); Core::ICore::infoBar()->addInfo(info); } diff --git a/src/plugins/android/androidpotentialkit.cpp b/src/plugins/android/androidpotentialkit.cpp index 08089d5f7f3..59b6e43eb17 100644 --- a/src/plugins/android/androidpotentialkit.cpp +++ b/src/plugins/android/androidpotentialkit.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -24,6 +25,8 @@ #include #include +using namespace ProjectExplorer; + namespace Android::Internal { class AndroidPotentialKitWidget : public Utils::DetailsWidget @@ -36,37 +39,6 @@ private: void recheck(); }; -QString AndroidPotentialKit::displayName() const -{ - return Tr::tr("Configure Android..."); -} - -void AndroidPotentialKit::executeFromMenu() -{ - Core::ICore::showOptionsDialog(Constants::ANDROID_SETTINGS_ID); -} - -QWidget *AndroidPotentialKit::createWidget(QWidget *parent) const -{ - if (!isEnabled()) - return nullptr; - return new AndroidPotentialKitWidget(parent); -} - -bool AndroidPotentialKit::isEnabled() const -{ - const QList kits = ProjectExplorer::KitManager::kits(); - for (const ProjectExplorer::Kit *kit : kits) { - if (kit->isAutoDetected() && !kit->isSdkProvided()) { - return false; - } - } - - return QtSupport::QtVersionManager::version([](const QtSupport::QtVersion *v) { - return v->type() == QString::fromLatin1(Constants::ANDROID_QT_TYPE); - }); -} - AndroidPotentialKitWidget::AndroidPotentialKitWidget(QWidget *parent) : Utils::DetailsWidget(parent) { @@ -104,8 +76,8 @@ void AndroidPotentialKitWidget::openOptions() void AndroidPotentialKitWidget::recheck() { - const QList kits = ProjectExplorer::KitManager::kits(); - for (const ProjectExplorer::Kit *kit : kits) { + const QList kits = KitManager::kits(); + for (const Kit *kit : kits) { if (kit->isAutoDetected() && !kit->isSdkProvided()) { setVisible(false); return; @@ -113,4 +85,44 @@ void AndroidPotentialKitWidget::recheck() } } +class AndroidPotentialKit final : public IPotentialKit +{ +public: + QString displayName() const final + { + return Tr::tr("Configure Android..."); + } + + void executeFromMenu() final + { + Core::ICore::showOptionsDialog(Constants::ANDROID_SETTINGS_ID); + } + + QWidget *createWidget(QWidget *parent) const final + { + if (!isEnabled()) + return nullptr; + return new AndroidPotentialKitWidget(parent); + } + + bool isEnabled() const final + { + const QList kits = KitManager::kits(); + for (const Kit *kit : kits) { + if (kit->isAutoDetected() && !kit->isSdkProvided()) { + return false; + } + } + + return QtSupport::QtVersionManager::version([](const QtSupport::QtVersion *v) { + return v->type() == QString::fromLatin1(Constants::ANDROID_QT_TYPE); + }); + } +}; + +void setupAndroidPotentialKit() +{ + static AndroidPotentialKit theAndroidPotentialKit; +} + } // Android::Internal diff --git a/src/plugins/android/androidpotentialkit.h b/src/plugins/android/androidpotentialkit.h index d1110294756..bc1ba9acc8c 100644 --- a/src/plugins/android/androidpotentialkit.h +++ b/src/plugins/android/androidpotentialkit.h @@ -3,17 +3,8 @@ #pragma once -#include - namespace Android::Internal { -class AndroidPotentialKit : public ProjectExplorer::IPotentialKit -{ -public: - QString displayName() const override; - void executeFromMenu() override; - QWidget *createWidget(QWidget *parent) const override; - bool isEnabled() const override; -}; +void setupAndroidPotentialKit(); } // Android::Internal diff --git a/src/plugins/android/androidqtversion.cpp b/src/plugins/android/androidqtversion.cpp index 5ba8775b67e..695202c051a 100644 --- a/src/plugins/android/androidqtversion.cpp +++ b/src/plugins/android/androidqtversion.cpp @@ -38,12 +38,10 @@ using namespace ProjectExplorer; -namespace Android { -namespace Internal { +namespace Android::Internal { AndroidQtVersion::AndroidQtVersion() - : QtSupport::QtVersion() - , m_guard(std::make_unique()) + : m_guard(std::make_unique()) { QObject::connect(AndroidConfigurations::instance(), &AndroidConfigurations::aboutToUpdate, @@ -265,17 +263,26 @@ QSet AndroidQtVersion::targetDeviceTypes() const // Factory -AndroidQtVersionFactory::AndroidQtVersionFactory() +class AndroidQtVersionFactory : public QtSupport::QtVersionFactory { - setQtVersionCreator([] { return new AndroidQtVersion; }); - setSupportedType(Constants::ANDROID_QT_TYPE); - setPriority(90); +public: + AndroidQtVersionFactory() + { + setQtVersionCreator([] { return new AndroidQtVersion; }); + setSupportedType(Constants::ANDROID_QT_TYPE); + setPriority(90); - setRestrictionChecker([](const SetupData &setup) { - return !setup.config.contains("android-no-sdk") - && (setup.config.contains("android") - || setup.platforms.contains("android")); - }); + setRestrictionChecker([](const SetupData &setup) { + return !setup.config.contains("android-no-sdk") + && (setup.config.contains("android") + || setup.platforms.contains("android")); + }); + } +}; + +void setupAndroidQtVersion() +{ + static AndroidQtVersionFactory theAndroidQtVersionFactory; } #ifdef WITH_TESTS @@ -341,5 +348,4 @@ void AndroidPlugin::testAndroidQtVersionParseBuiltWith() } #endif // WITH_TESTS -} // Internal -} // Android +} // Android::Internal diff --git a/src/plugins/android/androidqtversion.h b/src/plugins/android/androidqtversion.h index 95a69a6c2ea..80005a0315c 100644 --- a/src/plugins/android/androidqtversion.h +++ b/src/plugins/android/androidqtversion.h @@ -6,10 +6,7 @@ #include #include -#include - -namespace Android { -namespace Internal { +namespace Android::Internal { class AndroidQtVersion : public QtSupport::QtVersion { @@ -45,17 +42,13 @@ public: protected: void parseMkSpec(ProFileEvaluator *) const override; + private: std::unique_ptr m_guard; mutable QStringList m_androidAbis; mutable int m_minNdk = -1; }; -class AndroidQtVersionFactory : public QtSupport::QtVersionFactory -{ -public: - AndroidQtVersionFactory(); -}; +void setupAndroidQtVersion(); -} // namespace Internal -} // namespace Android +} // Android::Internal diff --git a/src/plugins/android/androidtoolchain.cpp b/src/plugins/android/androidtoolchain.cpp index 5d96d8c4bdc..e2c9bfd59d8 100644 --- a/src/plugins/android/androidtoolchain.cpp +++ b/src/plugins/android/androidtoolchain.cpp @@ -18,8 +18,7 @@ using namespace ProjectExplorer; using namespace Utils; -namespace Android { -namespace Internal { +namespace Android::Internal { static Q_LOGGING_CATEGORY(androidTCLog, "qtc.android.toolchainmanagement", QtWarningMsg); @@ -252,5 +251,9 @@ ToolChainList AndroidToolChainFactory::autodetectToolChainsFromNdks( return result; } -} // namespace Internal -} // namespace Android +void setupAndroidToolchain() +{ + static AndroidToolChainFactory theAndroidToolchainFactory; +} + +} // Android::Internal diff --git a/src/plugins/android/androidtoolchain.h b/src/plugins/android/androidtoolchain.h index bd33dc75704..1d5bdf5af86 100644 --- a/src/plugins/android/androidtoolchain.h +++ b/src/plugins/android/androidtoolchain.h @@ -7,8 +7,7 @@ #include -namespace Android { -namespace Internal { +namespace Android::Internal { using ToolChainList = QList; @@ -58,5 +57,6 @@ public: const bool isCustom = false); }; -} // namespace Internal -} // namespace Android +void setupAndroidToolchain(); + +} // Android diff --git a/src/plugins/android/javaeditor.cpp b/src/plugins/android/javaeditor.cpp index edd63e073bb..b0b844c1563 100644 --- a/src/plugins/android/javaeditor.cpp +++ b/src/plugins/android/javaeditor.cpp @@ -14,7 +14,6 @@ #include #include -#include #include #include @@ -29,29 +28,34 @@ static TextEditor::TextDocument *createJavaDocument() return doc; } -// -// JavaEditorFactory -// - -JavaEditorFactory::JavaEditorFactory() +class JavaEditorFactory : public TextEditor::TextEditorFactory { - static QStringList keywords = { - "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", - "continue", "default", "do", "double", "else", "enum", "extends", "final", "finally", - "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", - "long", "native", "new", "package", "private", "protected", "public", "return", "short", - "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", - "transient", "try", "void", "volatile", "while" - }; - setId(Constants::JAVA_EDITOR_ID); - setDisplayName(::Core::Tr::tr("Java Editor")); - addMimeType(Utils::Constants::JAVA_MIMETYPE); +public: + JavaEditorFactory() + { + static QStringList keywords = { + "abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", + "continue", "default", "do", "double", "else", "enum", "extends", "final", "finally", + "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", + "long", "native", "new", "package", "private", "protected", "public", "return", "short", + "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", + "transient", "try", "void", "volatile", "while" + }; + setId(Constants::JAVA_EDITOR_ID); + setDisplayName(::Core::Tr::tr("Java Editor")); + addMimeType(Utils::Constants::JAVA_MIMETYPE); - setDocumentCreator(createJavaDocument); - setUseGenericHighlighter(true); - setCommentDefinition(Utils::CommentDefinition::CppStyle); - setEditorActionHandlers(TextEditor::TextEditorActionHandler::UnCommentSelection); - setCompletionAssistProvider(new TextEditor::KeywordsCompletionAssistProvider(keywords)); + setDocumentCreator(createJavaDocument); + setUseGenericHighlighter(true); + setCommentDefinition(Utils::CommentDefinition::CppStyle); + setEditorActionHandlers(TextEditor::TextEditorActionHandler::UnCommentSelection); + setCompletionAssistProvider(new TextEditor::KeywordsCompletionAssistProvider(keywords)); + } +}; + +void setupJavaEditor() +{ + static JavaEditorFactory theJavaEditorFactory; } } // Android::Internal diff --git a/src/plugins/android/javaeditor.h b/src/plugins/android/javaeditor.h index dee2d0c712e..7a044564ad5 100644 --- a/src/plugins/android/javaeditor.h +++ b/src/plugins/android/javaeditor.h @@ -3,14 +3,8 @@ #pragma once -#include - namespace Android::Internal { -class JavaEditorFactory : public TextEditor::TextEditorFactory -{ -public: - JavaEditorFactory(); -}; +void setupJavaEditor(); } // Android::Internal From 9b2cbe9b71a80f2dde50a900b844406e0bc81e94 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Nov 2023 18:03:20 +0100 Subject: [PATCH 0371/1546] Android: New setup for AndroidDeviceManager Also remove the now-unneeded plugin pimpl. Change-Id: I37eaa91a2756e823d07323b54695e19860cb16ab Reviewed-by: Jarek Kobus Reviewed-by: --- src/plugins/android/androiddevice.cpp | 5 +++++ src/plugins/android/androiddevice.h | 6 ++++-- src/plugins/android/androidplugin.cpp | 13 +------------ src/plugins/android/androidplugin.h | 4 ---- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/plugins/android/androiddevice.cpp b/src/plugins/android/androiddevice.cpp index 3e42b42a930..971c2619a3a 100644 --- a/src/plugins/android/androiddevice.cpp +++ b/src/plugins/android/androiddevice.cpp @@ -870,4 +870,9 @@ void setupAndroidDevice() static AndroidDeviceFactory theAndroidDeviceFactory; } +void setupAndroidDeviceManager(QObject *guard) +{ + (void) new AndroidDeviceManager(guard); +} + } // Android::Internal diff --git a/src/plugins/android/androiddevice.h b/src/plugins/android/androiddevice.h index 80f1e365c9f..0c1ab9dd98e 100644 --- a/src/plugins/android/androiddevice.h +++ b/src/plugins/android/androiddevice.h @@ -87,8 +87,9 @@ public: QString getRunningAvdsSerialNumber(const QString &name) const; private: - AndroidDeviceManager(QObject *parent = nullptr); + explicit AndroidDeviceManager(QObject *parent); ~AndroidDeviceManager(); + void HandleDevicesListChange(const QString &serialNumber); void HandleAvdsListChange(); @@ -101,9 +102,10 @@ private: AndroidConfig &m_androidConfig; AndroidAvdManager m_avdManager; - friend class AndroidPluginPrivate; + friend void setupAndroidDeviceManager(QObject *guard); }; void setupAndroidDevice(); +void setupAndroidDeviceManager(QObject *guard); } // Android::Internal diff --git a/src/plugins/android/androidplugin.cpp b/src/plugins/android/androidplugin.cpp index 2ad8e2c6851..0d2bd90a8b3 100644 --- a/src/plugins/android/androidplugin.cpp +++ b/src/plugins/android/androidplugin.cpp @@ -78,17 +78,6 @@ void setupAndroidDeployConfiguration() static AndroidDeployConfigurationFactory theAndroidDeployConfigurationFactory; } -class AndroidPluginPrivate : public QObject -{ -public: - AndroidDeviceManager deviceManager; -}; - -AndroidPlugin::~AndroidPlugin() -{ - delete d; -} - void AndroidPlugin::initialize() { setupAndroidConfigurations(); @@ -98,7 +87,7 @@ void AndroidPlugin::initialize() setupAndroidQtVersion(); setupAndroidToolchain(); - d = new AndroidPluginPrivate; + setupAndroidDeviceManager(this); setupAndroidSettingsPage(); diff --git a/src/plugins/android/androidplugin.h b/src/plugins/android/androidplugin.h index e1c36608466..75b19d24f07 100644 --- a/src/plugins/android/androidplugin.h +++ b/src/plugins/android/androidplugin.h @@ -12,15 +12,11 @@ class AndroidPlugin final : public ExtensionSystem::IPlugin Q_OBJECT Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "Android.json") - ~AndroidPlugin() final; - void initialize() final; void kitsRestored(); void askUserAboutAndroidSetup(); - class AndroidPluginPrivate *d = nullptr; - #ifdef WITH_TESTS private slots: void testAndroidConfigAvailableNdkPlatforms_data(); From 2a331567f6a2bde6aac314dcddf5b006cacad878 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 23 Nov 2023 15:08:42 +0100 Subject: [PATCH 0372/1546] ExtensionSystem: Check for duplicate plugins If there are multiple plugins with the same name, do not load any of them, mark them with error. Fixes: QTCREATORBUG-26221 Change-Id: Id433a66203294b8302294eb09665043452e45ded Reviewed-by: Qt CI Bot Reviewed-by: Alessandro Portale Reviewed-by: --- src/libs/extensionsystem/pluginmanager.cpp | 22 ++++++++++++++++++++++ src/libs/extensionsystem/pluginmanager_p.h | 1 + 2 files changed, 23 insertions(+) diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index 072e8f0fa6b..267a144cf76 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -1058,6 +1058,27 @@ void PluginManagerPrivate::deleteAll() }); } +void PluginManagerPrivate::checkForDuplicatePlugins() +{ + QHash seen; + for (PluginSpec *spec : pluginSpecs) { + if (PluginSpec *other = seen.value(spec->name())) { + // Plugin with same name already there. We do not know, which version is the right one, + // keep it simple and fail both (if enabled). + if (spec->isEffectivelyEnabled() && other->isEffectivelyEnabled()) { + const QString error = Tr::tr( + "Multiple versions of the same plugin have been found."); + spec->d->hasError = true; + spec->d->errorString = error; + other->d->hasError = true; + other->d->errorString = error; + } + } else { + seen.insert(spec->name(), spec); + } + } +} + #ifdef WITH_TESTS using TestPlan = QMap; // Object -> selected test functions @@ -1766,6 +1787,7 @@ void PluginManagerPrivate::readPluginPaths() } resolveDependencies(); enableDependenciesIndirectly(); + checkForDuplicatePlugins(); // ensure deterministic plugin load order by sorting Utils::sort(pluginSpecs, &PluginSpec::name); emit q->pluginsChanged(); diff --git a/src/libs/extensionsystem/pluginmanager_p.h b/src/libs/extensionsystem/pluginmanager_p.h index c92eb5be2e4..e39208eddb8 100644 --- a/src/libs/extensionsystem/pluginmanager_p.h +++ b/src/libs/extensionsystem/pluginmanager_p.h @@ -151,6 +151,7 @@ private: QVector &circularityCheckQueue); void stopAll(); void deleteAll(); + void checkForDuplicatePlugins(); #ifdef WITH_TESTS void startTests(); From 2ef1ed9c22d95afcc424b3934cb52be120df9de3 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Nov 2023 14:39:32 +0100 Subject: [PATCH 0373/1546] ProjectExplorer: Rename Tool{C,c}hainConfigWidget That's the trend. Change-Id: I24a328f1190200b4499c6a11d9d3df074ce5973d Reviewed-by: Reviewed-by: Christian Kandeler --- src/plugins/baremetal/iarewtoolchain.cpp | 10 ++++----- src/plugins/baremetal/keiltoolchain.cpp | 10 ++++----- src/plugins/baremetal/sdcctoolchain.cpp | 10 ++++----- src/plugins/cppeditor/projectinfo_test.cpp | 2 +- src/plugins/nim/project/nimtoolchain.cpp | 6 ++--- src/plugins/nim/project/nimtoolchain.h | 2 +- .../projectexplorer/customtoolchain.cpp | 18 +++++++-------- src/plugins/projectexplorer/gcctoolchain.cpp | 10 ++++----- src/plugins/projectexplorer/gcctoolchain.h | 2 +- src/plugins/projectexplorer/msvctoolchain.cpp | 12 +++++----- src/plugins/projectexplorer/msvctoolchain.h | 4 ++-- src/plugins/projectexplorer/toolchain.h | 4 ++-- .../projectexplorer/toolchainconfigwidget.cpp | 22 +++++++++---------- .../projectexplorer/toolchainconfigwidget.h | 4 ++-- .../projectexplorer/toolchainoptionspage.cpp | 6 ++--- .../toolchainsettingsaccessor.cpp | 2 +- src/plugins/qnx/qnxtoolchain.cpp | 10 ++++----- src/plugins/qnx/qnxtoolchain.h | 2 +- 18 files changed, 68 insertions(+), 68 deletions(-) diff --git a/src/plugins/baremetal/iarewtoolchain.cpp b/src/plugins/baremetal/iarewtoolchain.cpp index a281d4eb528..e4fba3c3e62 100644 --- a/src/plugins/baremetal/iarewtoolchain.cpp +++ b/src/plugins/baremetal/iarewtoolchain.cpp @@ -257,7 +257,7 @@ static QString buildDisplayName(Abi::Architecture arch, Utils::Id language, class IarToolChain; -class IarToolChainConfigWidget final : public ToolChainConfigWidget +class IarToolChainConfigWidget final : public ToolchainConfigWidget { public: explicit IarToolChainConfigWidget(IarToolChain *tc); @@ -303,7 +303,7 @@ public: void addToEnvironment(Environment &env) const final; QList createOutputParsers() const final { return {new IarParser()}; } - std::unique_ptr createConfigurationWidget() final; + std::unique_ptr createConfigurationWidget() final; bool operator==(const ToolChain &other) const final; @@ -389,7 +389,7 @@ void IarToolChain::addToEnvironment(Environment &env) const env.prependOrSetPath(compilerCommand().parentDir()); } -std::unique_ptr IarToolChain::createConfigurationWidget() +std::unique_ptr IarToolChain::createConfigurationWidget() { return std::make_unique(this); } @@ -566,7 +566,7 @@ Toolchains IarToolChainFactory::autoDetectToolchain(const Candidate &candidate, // IarToolChainConfigWidget IarToolChainConfigWidget::IarToolChainConfigWidget(IarToolChain *tc) : - ToolChainConfigWidget(tc), + ToolchainConfigWidget(tc), m_compilerCommand(new PathChooser), m_abiWidget(new AbiWidget) { @@ -588,7 +588,7 @@ IarToolChainConfigWidget::IarToolChainConfigWidget(IarToolChain *tc) : connect(m_platformCodeGenFlagsLineEdit, &QLineEdit::editingFinished, this, &IarToolChainConfigWidget::handlePlatformCodeGenFlagsChange); connect(m_abiWidget, &AbiWidget::abiChanged, - this, &ToolChainConfigWidget::dirty); + this, &ToolchainConfigWidget::dirty); } void IarToolChainConfigWidget::applyImpl() diff --git a/src/plugins/baremetal/keiltoolchain.cpp b/src/plugins/baremetal/keiltoolchain.cpp index f6a097f0a41..ff3ec22dd56 100644 --- a/src/plugins/baremetal/keiltoolchain.cpp +++ b/src/plugins/baremetal/keiltoolchain.cpp @@ -395,7 +395,7 @@ static void addDefaultCpuArgs(const FilePath &compiler, QStringList &extraArgs) class KeilToolChain; -class KeilToolChainConfigWidget final : public ToolChainConfigWidget +class KeilToolChainConfigWidget final : public ToolchainConfigWidget { public: explicit KeilToolChainConfigWidget(KeilToolChain *tc); @@ -443,7 +443,7 @@ public: QList createOutputParsers() const final { return {new KeilParser}; } - std::unique_ptr createConfigurationWidget() final; + std::unique_ptr createConfigurationWidget() final; bool operator==(const ToolChain &other) const final; @@ -515,7 +515,7 @@ void KeilToolChain::addToEnvironment(Environment &env) const env.prependOrSetPath(compilerCommand().parentDir()); } -std::unique_ptr KeilToolChain::createConfigurationWidget() +std::unique_ptr KeilToolChain::createConfigurationWidget() { return std::make_unique(this); } @@ -725,7 +725,7 @@ Toolchains KeilToolChainFactory::autoDetectToolchain(const Candidate &candidate, // KeilToolchainConfigWidget KeilToolChainConfigWidget::KeilToolChainConfigWidget(KeilToolChain *tc) : - ToolChainConfigWidget(tc), + ToolchainConfigWidget(tc), m_compilerCommand(new PathChooser), m_abiWidget(new AbiWidget) { @@ -747,7 +747,7 @@ KeilToolChainConfigWidget::KeilToolChainConfigWidget(KeilToolChain *tc) : connect(m_platformCodeGenFlagsLineEdit, &QLineEdit::editingFinished, this, &KeilToolChainConfigWidget::handlePlatformCodeGenFlagsChange); connect(m_abiWidget, &AbiWidget::abiChanged, - this, &ToolChainConfigWidget::dirty); + this, &ToolchainConfigWidget::dirty); } void KeilToolChainConfigWidget::applyImpl() diff --git a/src/plugins/baremetal/sdcctoolchain.cpp b/src/plugins/baremetal/sdcctoolchain.cpp index 411b2317c5f..082688ff3bf 100644 --- a/src/plugins/baremetal/sdcctoolchain.cpp +++ b/src/plugins/baremetal/sdcctoolchain.cpp @@ -178,7 +178,7 @@ static FilePath compilerPathFromEnvironment(const QString &compilerName) class SdccToolChain; -class SdccToolChainConfigWidget final : public ToolChainConfigWidget +class SdccToolChainConfigWidget final : public ToolchainConfigWidget { public: explicit SdccToolChainConfigWidget(SdccToolChain *tc); @@ -218,7 +218,7 @@ public: void addToEnvironment(Environment &env) const final; QList createOutputParsers() const final { return {new SdccParser}; } - std::unique_ptr createConfigurationWidget() final; + std::unique_ptr createConfigurationWidget() final; bool operator==(const ToolChain &other) const final; @@ -283,7 +283,7 @@ void SdccToolChain::addToEnvironment(Environment &env) const env.prependOrSetPath(compilerCommand().parentDir()); } -std::unique_ptr SdccToolChain::createConfigurationWidget() +std::unique_ptr SdccToolChain::createConfigurationWidget() { return std::make_unique(this); } @@ -448,7 +448,7 @@ Toolchains SdccToolChainFactory::autoDetectToolchain(const Candidate &candidate, // SdccToolChainConfigWidget SdccToolChainConfigWidget::SdccToolChainConfigWidget(SdccToolChain *tc) : - ToolChainConfigWidget(tc), + ToolchainConfigWidget(tc), m_compilerCommand(new PathChooser), m_abiWidget(new AbiWidget) { @@ -465,7 +465,7 @@ SdccToolChainConfigWidget::SdccToolChainConfigWidget(SdccToolChain *tc) : connect(m_compilerCommand, &PathChooser::rawPathChanged, this, &SdccToolChainConfigWidget::handleCompilerCommandChange); connect(m_abiWidget, &AbiWidget::abiChanged, - this, &ToolChainConfigWidget::dirty); + this, &ToolchainConfigWidget::dirty); } void SdccToolChainConfigWidget::applyImpl() diff --git a/src/plugins/cppeditor/projectinfo_test.cpp b/src/plugins/cppeditor/projectinfo_test.cpp index 88115e2ea4f..4fb40cc44ab 100644 --- a/src/plugins/cppeditor/projectinfo_test.cpp +++ b/src/plugins/cppeditor/projectinfo_test.cpp @@ -344,7 +344,7 @@ private: void addToEnvironment(Utils::Environment &) const override {} Utils::FilePath makeCommand(const Utils::Environment &) const override { return {}; } QList createOutputParsers() const override { return {}; } - std::unique_ptr createConfigurationWidget() override + std::unique_ptr createConfigurationWidget() override { return {}; }; diff --git a/src/plugins/nim/project/nimtoolchain.cpp b/src/plugins/nim/project/nimtoolchain.cpp index 9d264922e98..a128846f9a0 100644 --- a/src/plugins/nim/project/nimtoolchain.cpp +++ b/src/plugins/nim/project/nimtoolchain.cpp @@ -120,11 +120,11 @@ bool NimToolChain::parseVersion(const FilePath &path, std::tuple // NimToolChainConfigWidget -class NimToolChainConfigWidget : public ToolChainConfigWidget +class NimToolChainConfigWidget : public ToolchainConfigWidget { public: explicit NimToolChainConfigWidget(NimToolChain *tc) - : ToolChainConfigWidget(tc) + : ToolchainConfigWidget(tc) , m_compilerCommand(new PathChooser) , m_compilerVersion(new QLineEdit) { @@ -196,7 +196,7 @@ void NimToolChainConfigWidget::fillUI() m_compilerVersion->setText(tc->compilerVersion()); } -std::unique_ptr NimToolChain::createConfigurationWidget() +std::unique_ptr NimToolChain::createConfigurationWidget() { return std::make_unique(this); } diff --git a/src/plugins/nim/project/nimtoolchain.h b/src/plugins/nim/project/nimtoolchain.h index f71edf44bbe..eb6d950d556 100644 --- a/src/plugins/nim/project/nimtoolchain.h +++ b/src/plugins/nim/project/nimtoolchain.h @@ -24,7 +24,7 @@ public: Utils::FilePath makeCommand(const Utils::Environment &env) const final; QString compilerVersion() const; QList createOutputParsers() const final; - std::unique_ptr createConfigurationWidget() final; + std::unique_ptr createConfigurationWidget() final; void fromMap(const Utils::Store &data) final; diff --git a/src/plugins/projectexplorer/customtoolchain.cpp b/src/plugins/projectexplorer/customtoolchain.cpp index f2ec50ed54a..a619ed2b897 100644 --- a/src/plugins/projectexplorer/customtoolchain.cpp +++ b/src/plugins/projectexplorer/customtoolchain.cpp @@ -80,7 +80,7 @@ public: void toMap(Store &data) const override; void fromMap(const Store &data) override; - std::unique_ptr createConfigurationWidget() override; + std::unique_ptr createConfigurationWidget() override; bool operator ==(const ToolChain &) const override; @@ -381,7 +381,7 @@ public: // CustomToolChainConfigWidget // -------------------------------------------------------------------------- -class CustomToolChainConfigWidget final : public ToolChainConfigWidget +class CustomToolChainConfigWidget final : public ToolchainConfigWidget { public: explicit CustomToolChainConfigWidget(CustomToolChain *); @@ -410,7 +410,7 @@ private: }; CustomToolChainConfigWidget::CustomToolChainConfigWidget(CustomToolChain *tc) : - ToolChainConfigWidget(tc), + ToolchainConfigWidget(tc), m_compilerCommand(new PathChooser), m_makeCommand(new PathChooser), m_abiWidget(new AbiWidget), @@ -459,15 +459,15 @@ CustomToolChainConfigWidget::CustomToolChainConfigWidget(CustomToolChain *tc) : m_predefinedDetails->updateSummaryText(); m_headerDetails->updateSummaryText(); - connect(m_compilerCommand, &PathChooser::rawPathChanged, this, &ToolChainConfigWidget::dirty); - connect(m_makeCommand, &PathChooser::rawPathChanged, this, &ToolChainConfigWidget::dirty); - connect(m_abiWidget, &AbiWidget::abiChanged, this, &ToolChainConfigWidget::dirty); + connect(m_compilerCommand, &PathChooser::rawPathChanged, this, &ToolchainConfigWidget::dirty); + connect(m_makeCommand, &PathChooser::rawPathChanged, this, &ToolchainConfigWidget::dirty); + connect(m_abiWidget, &AbiWidget::abiChanged, this, &ToolchainConfigWidget::dirty); connect(m_predefinedMacros, &QPlainTextEdit::textChanged, this, [this] { updateSummaries(m_predefinedDetails); }); connect(m_headerPaths, &QPlainTextEdit::textChanged, this, [this] { updateSummaries(m_headerDetails); }); - connect(m_cxx11Flags, &QLineEdit::textChanged, this, &ToolChainConfigWidget::dirty); - connect(m_mkspecs, &QLineEdit::textChanged, this, &ToolChainConfigWidget::dirty); + connect(m_cxx11Flags, &QLineEdit::textChanged, this, &ToolchainConfigWidget::dirty); + connect(m_mkspecs, &QLineEdit::textChanged, this, &ToolchainConfigWidget::dirty); connect(m_errorParserComboBox, &QComboBox::currentIndexChanged, this, &CustomToolChainConfigWidget::errorParserChanged); errorParserChanged(); @@ -549,7 +549,7 @@ void CustomToolChainConfigWidget::makeReadOnlyImpl() m_mainLayout->setEnabled(false); } -std::unique_ptr CustomToolChain::createConfigurationWidget() +std::unique_ptr CustomToolChain::createConfigurationWidget() { return std::make_unique(this); } diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index d2ce8299e31..c4a2dcd6b23 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -104,7 +104,7 @@ const QStringList gccPredefinedMacrosOptions(Id languageId) } class TargetTripleWidget; -class GccToolChainConfigWidget : public ToolChainConfigWidget +class GccToolChainConfigWidget : public ToolchainConfigWidget { public: explicit GccToolChainConfigWidget(GccToolChain *tc); @@ -1062,7 +1062,7 @@ bool GccToolChain::operator ==(const ToolChain &other) const && m_platformLinkerFlags == gccTc->m_platformLinkerFlags; } -std::unique_ptr GccToolChain::createConfigurationWidget() +std::unique_ptr GccToolChain::createConfigurationWidget() { return std::make_unique(this); } @@ -1708,7 +1708,7 @@ private: } GccToolChainConfigWidget::GccToolChainConfigWidget(GccToolChain *tc) : - ToolChainConfigWidget(tc), + ToolchainConfigWidget(tc), m_abiWidget(new AbiWidget), m_subType(tc->m_subType), m_compilerCommand(new PathChooser), @@ -1740,9 +1740,9 @@ GccToolChainConfigWidget::GccToolChainConfigWidget(GccToolChain *tc) : this, &GccToolChainConfigWidget::handlePlatformCodeGenFlagsChange); connect(m_platformLinkerFlagsLineEdit, &QLineEdit::editingFinished, this, &GccToolChainConfigWidget::handlePlatformLinkerFlagsChange); - connect(m_abiWidget, &AbiWidget::abiChanged, this, &ToolChainConfigWidget::dirty); + connect(m_abiWidget, &AbiWidget::abiChanged, this, &ToolchainConfigWidget::dirty); connect(m_targetTripleWidget, &TargetTripleWidget::valueChanged, - this, &ToolChainConfigWidget::dirty); + this, &ToolchainConfigWidget::dirty); if (m_subType == GccToolChain::Clang) { if (!HostOsInfo::isWindowsHost() || tc->typeId() != Constants::CLANG_TOOLCHAIN_TYPEID) diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h index ec94b5df96b..d701a8db320 100644 --- a/src/plugins/projectexplorer/gcctoolchain.h +++ b/src/plugins/projectexplorer/gcctoolchain.h @@ -55,7 +55,7 @@ public: void toMap(Utils::Store &data) const override; void fromMap(const Utils::Store &data) override; - std::unique_ptr createConfigurationWidget() override; + std::unique_ptr createConfigurationWidget() override; bool operator ==(const ToolChain &) const override; diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index 12623a9907a..cbe7673d7f6 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -1263,11 +1263,11 @@ static QString msvcVarsToDisplay(const MsvcToolChain &tc) return varsBatDisplay; } -class MsvcBasedToolChainConfigWidget : public ToolChainConfigWidget +class MsvcBasedToolChainConfigWidget : public ToolchainConfigWidget { public: explicit MsvcBasedToolChainConfigWidget(ToolChain *tc) - : ToolChainConfigWidget(tc) + : ToolchainConfigWidget(tc) , m_nameDisplayLabel(new QLabel(this)) , m_varsBatDisplayLabel(new QLabel(this)) { @@ -1356,8 +1356,8 @@ public: connect(m_varsBatArchCombo, &QComboBox::currentTextChanged, this, &MsvcToolChainConfigWidget::handleVcVarsArchChange); connect(m_varsBatArgumentsEdit, &QLineEdit::textChanged, - this, &ToolChainConfigWidget::dirty); - connect(m_abiWidget, &AbiWidget::abiChanged, this, &ToolChainConfigWidget::dirty); + this, &ToolchainConfigWidget::dirty); + connect(m_abiWidget, &AbiWidget::abiChanged, this, &ToolchainConfigWidget::dirty); } private: @@ -1503,7 +1503,7 @@ QString MsvcToolChainConfigWidget::vcVarsArguments() const return varsBatArg; } -std::unique_ptr MsvcToolChain::createConfigurationWidget() +std::unique_ptr MsvcToolChain::createConfigurationWidget() { return std::make_unique(this); } @@ -1800,7 +1800,7 @@ void ClangClToolChain::fromMap(const Store &data) m_clangPath = FilePath::fromString(clangPath); } -std::unique_ptr ClangClToolChain::createConfigurationWidget() +std::unique_ptr ClangClToolChain::createConfigurationWidget() { return std::make_unique(this); } diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h index 2165a1c84aa..7d560bc0395 100644 --- a/src/plugins/projectexplorer/msvctoolchain.h +++ b/src/plugins/projectexplorer/msvctoolchain.h @@ -40,7 +40,7 @@ public: void toMap(Utils::Store &data) const override; void fromMap(const Utils::Store &data) override; - std::unique_ptr createConfigurationWidget() override; + std::unique_ptr createConfigurationWidget() override; bool hostPrefersToolchain() const override; MacroInspectionRunner createMacroInspectionRunner() const override; @@ -139,7 +139,7 @@ public: QList createOutputParsers() const override; void toMap(Utils::Store &data) const override; void fromMap(const Utils::Store &data) override; - std::unique_ptr createConfigurationWidget() override; + std::unique_ptr createConfigurationWidget() override; BuiltInHeaderPathsRunner createBuiltInHeaderPathsRunner( const Utils::Environment &env) const override; diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index af154e1c198..df711d7a9e2 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -41,7 +41,7 @@ QString languageId(Language l); } // namespace Deprecated class GccToolChain; -class ToolChainConfigWidget; +class ToolchainConfigWidget; class ToolChainFactory; class Kit; @@ -138,7 +138,7 @@ public: virtual bool operator ==(const ToolChain &) const; - virtual std::unique_ptr createConfigurationWidget() = 0; + virtual std::unique_ptr createConfigurationWidget() = 0; ToolChain *clone() const; // Used by the toolchainmanager to save user-generated tool chains. diff --git a/src/plugins/projectexplorer/toolchainconfigwidget.cpp b/src/plugins/projectexplorer/toolchainconfigwidget.cpp index 84b80b4e047..6fca4890b3a 100644 --- a/src/plugins/projectexplorer/toolchainconfigwidget.cpp +++ b/src/plugins/projectexplorer/toolchainconfigwidget.cpp @@ -20,7 +20,7 @@ using namespace Utils; namespace ProjectExplorer { -ToolChainConfigWidget::ToolChainConfigWidget(ToolChain *tc) : +ToolchainConfigWidget::ToolchainConfigWidget(ToolChain *tc) : m_toolChain(tc) { Q_ASSERT(tc); @@ -46,38 +46,38 @@ ToolChainConfigWidget::ToolChainConfigWidget(ToolChain *tc) : m_mainLayout->addRow(Tr::tr("Name:"), m_nameLineEdit); - connect(m_nameLineEdit, &QLineEdit::textChanged, this, &ToolChainConfigWidget::dirty); + connect(m_nameLineEdit, &QLineEdit::textChanged, this, &ToolchainConfigWidget::dirty); } -void ToolChainConfigWidget::apply() +void ToolchainConfigWidget::apply() { m_toolChain->setDisplayName(m_nameLineEdit->text()); applyImpl(); } -void ToolChainConfigWidget::discard() +void ToolchainConfigWidget::discard() { m_nameLineEdit->setText(m_toolChain->displayName()); discardImpl(); } -bool ToolChainConfigWidget::isDirty() const +bool ToolchainConfigWidget::isDirty() const { return m_nameLineEdit->text() != m_toolChain->displayName() || isDirtyImpl(); } -ToolChain *ToolChainConfigWidget::toolChain() const +ToolChain *ToolchainConfigWidget::toolChain() const { return m_toolChain; } -void ToolChainConfigWidget::makeReadOnly() +void ToolchainConfigWidget::makeReadOnly() { m_nameLineEdit->setEnabled(false); makeReadOnlyImpl(); } -void ToolChainConfigWidget::addErrorLabel() +void ToolchainConfigWidget::addErrorLabel() { if (!m_errorLabel) { m_errorLabel = new QLabel; @@ -86,7 +86,7 @@ void ToolChainConfigWidget::addErrorLabel() m_mainLayout->addRow(m_errorLabel); } -void ToolChainConfigWidget::setErrorMessage(const QString &m) +void ToolchainConfigWidget::setErrorMessage(const QString &m) { QTC_ASSERT(m_errorLabel, return); if (m.isEmpty()) { @@ -98,7 +98,7 @@ void ToolChainConfigWidget::setErrorMessage(const QString &m) } } -void ToolChainConfigWidget::clearErrorMessage() +void ToolchainConfigWidget::clearErrorMessage() { QTC_ASSERT(m_errorLabel, return); m_errorLabel->clear(); @@ -106,7 +106,7 @@ void ToolChainConfigWidget::clearErrorMessage() m_errorLabel->setVisible(false); } -QStringList ToolChainConfigWidget::splitString(const QString &s) +QStringList ToolchainConfigWidget::splitString(const QString &s) { ProcessArgs::SplitError splitError; const OsType osType = HostOsInfo::hostOs(); diff --git a/src/plugins/projectexplorer/toolchainconfigwidget.h b/src/plugins/projectexplorer/toolchainconfigwidget.h index 84e5fc67185..5735cddac9b 100644 --- a/src/plugins/projectexplorer/toolchainconfigwidget.h +++ b/src/plugins/projectexplorer/toolchainconfigwidget.h @@ -21,12 +21,12 @@ class ToolChain; // ToolChainConfigWidget // -------------------------------------------------------------------------- -class PROJECTEXPLORER_EXPORT ToolChainConfigWidget : public QScrollArea +class PROJECTEXPLORER_EXPORT ToolchainConfigWidget : public QScrollArea { Q_OBJECT public: - explicit ToolChainConfigWidget(ToolChain *tc); + explicit ToolchainConfigWidget(ToolChain *tc); ToolChain *toolChain() const; diff --git a/src/plugins/projectexplorer/toolchainoptionspage.cpp b/src/plugins/projectexplorer/toolchainoptionspage.cpp index 3585050f6dc..a4efa921634 100644 --- a/src/plugins/projectexplorer/toolchainoptionspage.cpp +++ b/src/plugins/projectexplorer/toolchainoptionspage.cpp @@ -82,7 +82,7 @@ public: return {}; } - ToolChainConfigWidget *widget() + ToolchainConfigWidget *widget() { if (!m_widget) { m_widget = toolChain->createConfigurationWidget().release(); @@ -90,7 +90,7 @@ public: m_parentWidget->addWidget(m_widget); if (toolChain->isAutoDetected()) m_widget->makeReadOnly(); - QObject::connect(m_widget, &ToolChainConfigWidget::dirty, + QObject::connect(m_widget, &ToolchainConfigWidget::dirty, [this] { changed = true; update(); @@ -104,7 +104,7 @@ public: bool changed; private: - ToolChainConfigWidget *m_widget = nullptr; + ToolchainConfigWidget *m_widget = nullptr; QStackedWidget *m_parentWidget = nullptr; }; diff --git a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp index 1683e8b9c89..9af52f0bf9c 100644 --- a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp +++ b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp @@ -319,7 +319,7 @@ public: void addToEnvironment(Environment &env) const override { Q_UNUSED(env) } FilePath makeCommand(const Environment &) const override { return "make"; } QList createOutputParsers() const override { return {}; } - std::unique_ptr createConfigurationWidget() override { return nullptr; } + std::unique_ptr createConfigurationWidget() override { return nullptr; } bool operator ==(const ToolChain &other) const override { if (!ToolChain::operator==(other)) return false; diff --git a/src/plugins/qnx/qnxtoolchain.cpp b/src/plugins/qnx/qnxtoolchain.cpp index c3bdad566ba..cfafd7dfcb9 100644 --- a/src/plugins/qnx/qnxtoolchain.cpp +++ b/src/plugins/qnx/qnxtoolchain.cpp @@ -24,7 +24,7 @@ namespace Qnx::Internal { // QnxToolChainConfigWidget -class QnxToolChainConfigWidget : public ToolChainConfigWidget +class QnxToolChainConfigWidget : public ToolchainConfigWidget { public: QnxToolChainConfigWidget(QnxToolChain *tc); @@ -116,7 +116,7 @@ QnxToolChain::QnxToolChain() }); } -std::unique_ptr QnxToolChain::createConfigurationWidget() +std::unique_ptr QnxToolChain::createConfigurationWidget() { return std::make_unique(this); } @@ -167,7 +167,7 @@ bool QnxToolChain::operator ==(const ToolChain &other) const //--------------------------------------------------------------------------------- QnxToolChainConfigWidget::QnxToolChainConfigWidget(QnxToolChain *tc) - : ToolChainConfigWidget(tc) + : ToolchainConfigWidget(tc) , m_compilerCommand(new PathChooser) , m_sdpPath(new PathChooser) , m_abiWidget(new AbiWidget) @@ -191,10 +191,10 @@ QnxToolChainConfigWidget::QnxToolChainConfigWidget(QnxToolChain *tc) m_mainLayout->addRow(Tr::tr("SDP path:"), m_sdpPath); m_mainLayout->addRow(Tr::tr("&ABI:"), m_abiWidget); - connect(m_compilerCommand, &PathChooser::rawPathChanged, this, &ToolChainConfigWidget::dirty); + connect(m_compilerCommand, &PathChooser::rawPathChanged, this, &ToolchainConfigWidget::dirty); connect(m_sdpPath, &PathChooser::rawPathChanged, this, &QnxToolChainConfigWidget::handleSdpPathChange); - connect(m_abiWidget, &AbiWidget::abiChanged, this, &ToolChainConfigWidget::dirty); + connect(m_abiWidget, &AbiWidget::abiChanged, this, &ToolchainConfigWidget::dirty); } void QnxToolChainConfigWidget::applyImpl() diff --git a/src/plugins/qnx/qnxtoolchain.h b/src/plugins/qnx/qnxtoolchain.h index 4c028f057cb..96a1ff91051 100644 --- a/src/plugins/qnx/qnxtoolchain.h +++ b/src/plugins/qnx/qnxtoolchain.h @@ -12,7 +12,7 @@ class QnxToolChain : public ProjectExplorer::GccToolChain public: QnxToolChain(); - std::unique_ptr createConfigurationWidget() override; + std::unique_ptr createConfigurationWidget() override; void addToEnvironment(Utils::Environment &env) const override; QStringList suggestedMkspecList() const override; From 2d4867e73f77dca01cbf0bbbd8708750dc3c6db1 Mon Sep 17 00:00:00 2001 From: hjk Date: Wed, 22 Nov 2023 14:39:32 +0100 Subject: [PATCH 0374/1546] ProjectExplorer: Rename Tool{C,h}ainFactory Also adapt derived classes. Change-Id: Iebf654c974730333c42b6994269ad1a4d5f7f428 Reviewed-by: Christian Kandeler --- src/plugins/android/androidconfigurations.cpp | 4 +- src/plugins/android/androidtoolchain.cpp | 8 +-- src/plugins/android/androidtoolchain.h | 6 +-- src/plugins/baremetal/iarewtoolchain.cpp | 18 +++---- src/plugins/baremetal/keiltoolchain.cpp | 14 ++--- src/plugins/baremetal/sdcctoolchain.cpp | 16 +++--- src/plugins/docker/kitdetector.cpp | 4 +- src/plugins/ios/iosconfigurations.cpp | 4 +- src/plugins/ios/iosconfigurations.h | 4 +- src/plugins/ios/iosplugin.cpp | 2 +- src/plugins/mcusupport/mcupackage.cpp | 12 ++--- src/plugins/mcusupport/test/unittest.cpp | 8 +-- src/plugins/nim/nimplugin.cpp | 2 +- src/plugins/nim/project/nimtoolchain.cpp | 10 ++-- src/plugins/nim/project/nimtoolchain.h | 4 +- .../projectexplorer/customtoolchain.cpp | 2 +- src/plugins/projectexplorer/customtoolchain.h | 4 +- src/plugins/projectexplorer/gcctoolchain.cpp | 2 +- src/plugins/projectexplorer/gcctoolchain.h | 2 +- src/plugins/projectexplorer/msvctoolchain.cpp | 4 +- .../projectexplorer/projectexplorer.cpp | 2 +- .../projectexplorer/projectimporter.cpp | 2 +- src/plugins/projectexplorer/toolchain.cpp | 54 +++++++++---------- src/plugins/projectexplorer/toolchain.h | 17 +++--- .../projectexplorer/toolchainoptionspage.cpp | 16 +++--- .../toolchainsettingsaccessor.cpp | 16 +++--- src/plugins/qnx/qnxtoolchain.cpp | 8 +-- src/plugins/webassembly/webassemblyplugin.cpp | 2 +- .../webassembly/webassemblytoolchain.cpp | 4 +- .../webassembly/webassemblytoolchain.h | 4 +- 30 files changed, 127 insertions(+), 128 deletions(-) diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index 37e9c148c59..b91da03e8ea 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -1149,7 +1149,7 @@ void AndroidConfigurations::registerNewToolChains() const Toolchains existingAndroidToolChains = ToolChainManager::toolchains(Utils::equal(&ToolChain::typeId, Id(Constants::ANDROID_TOOLCHAIN_TYPEID))); - const Toolchains newToolchains = AndroidToolChainFactory::autodetectToolChains( + const Toolchains newToolchains = AndroidToolchainFactory::autodetectToolChains( existingAndroidToolChains); for (ToolChain *tc : newToolchains) @@ -1311,7 +1311,7 @@ void AndroidConfigurations::registerCustomToolChainsAndDebuggers() const FilePaths customNdks = FileUtils::toFilePathList(currentConfig().getCustomNdkList()); const Toolchains customToolchains - = AndroidToolChainFactory::autodetectToolChainsFromNdks(existingAndroidToolChains, + = AndroidToolchainFactory::autodetectToolChainsFromNdks(existingAndroidToolChains, customNdks, true); for (ToolChain *tc : customToolchains) { diff --git a/src/plugins/android/androidtoolchain.cpp b/src/plugins/android/androidtoolchain.cpp index e2c9bfd59d8..cf1a79da15d 100644 --- a/src/plugins/android/androidtoolchain.cpp +++ b/src/plugins/android/androidtoolchain.cpp @@ -137,7 +137,7 @@ GccToolChain::DetectedAbisResult AndroidToolChain::detectSupportedAbis() const // ToolChainFactory // -------------------------------------------------------------------------- -AndroidToolChainFactory::AndroidToolChainFactory() +AndroidToolchainFactory::AndroidToolchainFactory() { setDisplayName(Tr::tr("Android Clang")); setSupportedToolChainType(Constants::ANDROID_TOOLCHAIN_TYPEID); @@ -169,13 +169,13 @@ static FilePaths uniqueNdksForCurrentQtVersions() return uniqueNdks; } -ToolChainList AndroidToolChainFactory::autodetectToolChains(const ToolChainList &alreadyKnown) +ToolChainList AndroidToolchainFactory::autodetectToolChains(const ToolChainList &alreadyKnown) { const QList uniqueNdks = uniqueNdksForCurrentQtVersions(); return autodetectToolChainsFromNdks(alreadyKnown, uniqueNdks); } -ToolChainList AndroidToolChainFactory::autodetectToolChainsFromNdks( +ToolChainList AndroidToolchainFactory::autodetectToolChainsFromNdks( const ToolChainList &alreadyKnown, const QList &ndkLocations, const bool isCustom) @@ -253,7 +253,7 @@ ToolChainList AndroidToolChainFactory::autodetectToolChainsFromNdks( void setupAndroidToolchain() { - static AndroidToolChainFactory theAndroidToolchainFactory; + static AndroidToolchainFactory theAndroidToolchainFactory; } } // Android::Internal diff --git a/src/plugins/android/androidtoolchain.h b/src/plugins/android/androidtoolchain.h index 1d5bdf5af86..f11efa316cb 100644 --- a/src/plugins/android/androidtoolchain.h +++ b/src/plugins/android/androidtoolchain.h @@ -32,15 +32,15 @@ protected: private: explicit AndroidToolChain(); - friend class AndroidToolChainFactory; + friend class AndroidToolchainFactory; mutable Utils::FilePath m_ndkLocation; }; -class AndroidToolChainFactory : public ProjectExplorer::ToolChainFactory +class AndroidToolchainFactory : public ProjectExplorer::ToolchainFactory { public: - AndroidToolChainFactory(); + AndroidToolchainFactory(); class AndroidToolChainInformation { diff --git a/src/plugins/baremetal/iarewtoolchain.cpp b/src/plugins/baremetal/iarewtoolchain.cpp index e4fba3c3e62..d7bd066ca09 100644 --- a/src/plugins/baremetal/iarewtoolchain.cpp +++ b/src/plugins/baremetal/iarewtoolchain.cpp @@ -314,7 +314,7 @@ public: private: StringListAspect m_extraCodeModelFlags{this}; - friend class IarToolChainFactory; + friend class IarToolchainFactory; friend class IarToolChainConfigWidget; }; @@ -405,12 +405,12 @@ bool IarToolChain::operator==(const ToolChain &other) const } -// IarToolChainFactory +// IarToolchainFactory -class IarToolChainFactory final : public ToolChainFactory +class IarToolchainFactory final : public ToolchainFactory { public: - IarToolChainFactory() + IarToolchainFactory() { setDisplayName(Tr::tr("IAREW")); setSupportedToolChainType(Constants::IAREW_TOOLCHAIN_TYPEID); @@ -431,10 +431,10 @@ private: void setupIarToolChain() { - static IarToolChainFactory theIarToolChainFactory; + static IarToolchainFactory theIarToolChainFactory; } -Toolchains IarToolChainFactory::autoDetect(const ToolchainDetector &detector) const +Toolchains IarToolchainFactory::autoDetect(const ToolchainDetector &detector) const { Candidates candidates; @@ -507,12 +507,12 @@ Toolchains IarToolChainFactory::autoDetect(const ToolchainDetector &detector) co return autoDetectToolchains(candidates, detector.alreadyKnown); } -Toolchains IarToolChainFactory::detectForImport(const ToolChainDescription &tcd) const +Toolchains IarToolchainFactory::detectForImport(const ToolChainDescription &tcd) const { return { autoDetectToolchain({tcd.compilerPath, {}}, tcd.language) }; } -Toolchains IarToolChainFactory::autoDetectToolchains( +Toolchains IarToolchainFactory::autoDetectToolchains( const Candidates &candidates, const Toolchains &alreadyKnown) const { Toolchains result; @@ -538,7 +538,7 @@ Toolchains IarToolChainFactory::autoDetectToolchains( return result; } -Toolchains IarToolChainFactory::autoDetectToolchain(const Candidate &candidate, Id languageId) const +Toolchains IarToolchainFactory::autoDetectToolchain(const Candidate &candidate, Id languageId) const { if (ToolChainManager::isBadToolchain(candidate.compilerPath)) return {}; diff --git a/src/plugins/baremetal/keiltoolchain.cpp b/src/plugins/baremetal/keiltoolchain.cpp index ff3ec22dd56..6b53281bb64 100644 --- a/src/plugins/baremetal/keiltoolchain.cpp +++ b/src/plugins/baremetal/keiltoolchain.cpp @@ -454,7 +454,7 @@ public: private: StringListAspect m_extraCodeModelFlags{this}; - friend class KeilToolChainFactory; + friend class KeilToolchainFactory; friend class KeilToolChainConfigWidget; }; @@ -538,10 +538,10 @@ QStringList KeilToolChain::extraCodeModelFlags() const // KeilToolchainFactory -class KeilToolChainFactory final : public ToolChainFactory +class KeilToolchainFactory final : public ToolchainFactory { public: - KeilToolChainFactory() + KeilToolchainFactory() { setDisplayName(Tr::tr("KEIL")); setSupportedToolChainType(Constants::KEIL_TOOLCHAIN_TYPEID); @@ -562,7 +562,7 @@ private: void setupKeilToolChain() { - static KeilToolChainFactory theKeilToolChainFactory; + static KeilToolchainFactory theKeilToolChainFactory; } // Parse the 'tools.ini' file to fetch a toolchain version. @@ -609,7 +609,7 @@ static QString extractVersion(const QString &toolsFile, const QString §ion) return {}; } -Toolchains KeilToolChainFactory::autoDetect(const ToolchainDetector &detector) const +Toolchains KeilToolchainFactory::autoDetect(const ToolchainDetector &detector) const { #ifdef Q_OS_WIN64 static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\" \ @@ -660,7 +660,7 @@ Toolchains KeilToolChainFactory::autoDetect(const ToolchainDetector &detector) c return autoDetectToolchains(candidates, detector.alreadyKnown); } -Toolchains KeilToolChainFactory::autoDetectToolchains( +Toolchains KeilToolchainFactory::autoDetectToolchains( const Candidates &candidates, const Toolchains &alreadyKnown) const { Toolchains result; @@ -687,7 +687,7 @@ Toolchains KeilToolChainFactory::autoDetectToolchains( return result; } -Toolchains KeilToolChainFactory::autoDetectToolchain(const Candidate &candidate, Id language) const +Toolchains KeilToolchainFactory::autoDetectToolchain(const Candidate &candidate, Id language) const { if (ToolChainManager::isBadToolchain(candidate.compilerPath)) return {}; diff --git a/src/plugins/baremetal/sdcctoolchain.cpp b/src/plugins/baremetal/sdcctoolchain.cpp index 082688ff3bf..b682400edf6 100644 --- a/src/plugins/baremetal/sdcctoolchain.cpp +++ b/src/plugins/baremetal/sdcctoolchain.cpp @@ -225,7 +225,7 @@ public: FilePath makeCommand(const Environment &) const final { return {}; } private: - friend class SdccToolChainFactory; + friend class SdccToolchainFactory; friend class SdccToolChainConfigWidget; }; @@ -298,12 +298,12 @@ bool SdccToolChain::operator==(const ToolChain &other) const && targetAbi() == customTc->targetAbi(); } -// SdccToolChainFactory +// SdccToolchainFactory -class SdccToolChainFactory final : public ToolChainFactory +class SdccToolchainFactory final : public ToolchainFactory { public: - SdccToolChainFactory() + SdccToolchainFactory() { setDisplayName(Tr::tr("SDCC")); setSupportedToolChainType(Constants::SDCC_TOOLCHAIN_TYPEID); @@ -322,10 +322,10 @@ private: void setupSdccToolChain() { - static SdccToolChainFactory theSdccToolChainFactory; + static SdccToolchainFactory theSdccToolChainFactory; } -Toolchains SdccToolChainFactory::autoDetect(const ToolchainDetector &detector) const +Toolchains SdccToolchainFactory::autoDetect(const ToolchainDetector &detector) const { Candidates candidates; @@ -382,7 +382,7 @@ Toolchains SdccToolChainFactory::autoDetect(const ToolchainDetector &detector) c return autoDetectToolchains(candidates, detector.alreadyKnown); } -Toolchains SdccToolChainFactory::autoDetectToolchains( +Toolchains SdccToolchainFactory::autoDetectToolchains( const Candidates &candidates, const Toolchains &alreadyKnown) const { Toolchains result; @@ -406,7 +406,7 @@ Toolchains SdccToolChainFactory::autoDetectToolchains( return result; } -Toolchains SdccToolChainFactory::autoDetectToolchain(const Candidate &candidate, Id language) const +Toolchains SdccToolchainFactory::autoDetectToolchain(const Candidate &candidate, Id language) const { const auto env = Environment::systemEnvironment(); diff --git a/src/plugins/docker/kitdetector.cpp b/src/plugins/docker/kitdetector.cpp index 2408d366dc1..b443b3ef5b0 100644 --- a/src/plugins/docker/kitdetector.cpp +++ b/src/plugins/docker/kitdetector.cpp @@ -249,13 +249,13 @@ QtVersions KitDetectorPrivate::autoDetectQtVersions() const Toolchains KitDetectorPrivate::autoDetectToolChains() { - const QList factories = ToolChainFactory::allToolChainFactories(); + const QList factories = ToolchainFactory::allToolchainFactories(); Toolchains alreadyKnown = ToolChainManager::toolchains(); Toolchains allNewToolChains; QApplication::processEvents(); emit q->logOutput('\n' + ProjectExplorer::Tr::tr("Searching toolchains...")); - for (ToolChainFactory *factory : factories) { + for (ToolchainFactory *factory : factories) { emit q->logOutput(ProjectExplorer::Tr::tr("Searching toolchains of type %1").arg(factory->displayName())); const ToolchainDetector detector(alreadyKnown, m_device, m_searchPaths); const Toolchains newToolChains = factory->autoDetect(detector); diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp index 105ba236eaa..b7ec36f883f 100644 --- a/src/plugins/ios/iosconfigurations.cpp +++ b/src/plugins/ios/iosconfigurations.cpp @@ -570,13 +570,13 @@ ProvisioningProfilePtr IosConfigurations::provisioningProfile(const QString &pro equal(&ProvisioningProfile::identifier, profileID)); } -IosToolChainFactory::IosToolChainFactory() +IosToolchainFactory::IosToolchainFactory() { setSupportedLanguages({ProjectExplorer::Constants::C_LANGUAGE_ID, ProjectExplorer::Constants::CXX_LANGUAGE_ID}); } -Toolchains IosToolChainFactory::autoDetect(const ToolchainDetector &detector) const +Toolchains IosToolchainFactory::autoDetect(const ToolchainDetector &detector) const { if (detector.device->type() != ProjectExplorer::Constants::DESKTOP_DEVICE_TYPE) return {}; diff --git a/src/plugins/ios/iosconfigurations.h b/src/plugins/ios/iosconfigurations.h index 3b77c6d1959..90a98d862bf 100644 --- a/src/plugins/ios/iosconfigurations.h +++ b/src/plugins/ios/iosconfigurations.h @@ -69,10 +69,10 @@ private: using DevelopmentTeamPtr = std::shared_ptr; using DevelopmentTeams = QList; -class IosToolChainFactory : public ProjectExplorer::ToolChainFactory +class IosToolchainFactory : public ProjectExplorer::ToolchainFactory { public: - IosToolChainFactory(); + IosToolchainFactory(); ProjectExplorer::Toolchains autoDetect( const ProjectExplorer::ToolchainDetector &detector) const final; diff --git a/src/plugins/ios/iosplugin.cpp b/src/plugins/ios/iosplugin.cpp index 9f790aa17f9..0be01955dd0 100644 --- a/src/plugins/ios/iosplugin.cpp +++ b/src/plugins/ios/iosplugin.cpp @@ -47,7 +47,7 @@ class IosPluginPrivate public: IosQmakeBuildConfigurationFactory qmakeBuildConfigurationFactory; IosCMakeBuildConfigurationFactory cmakeBuildConfigurationFactory; - IosToolChainFactory toolChainFactory; + IosToolchainFactory toolChainFactory; IosRunConfigurationFactory runConfigurationFactory; IosSettingsPage settingsPage; IosQtVersionFactory qtVersionFactory; diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp index 84c9d7d2d5c..26f6b80a6c5 100644 --- a/src/plugins/mcusupport/mcupackage.cpp +++ b/src/plugins/mcusupport/mcupackage.cpp @@ -414,9 +414,9 @@ static ToolChain *armGccToolChain(const FilePath &path, Id language) return t->compilerCommand() == path && t->language() == language; }); if (!toolChain) { - ToolChainFactory *gccFactory - = Utils::findOrDefault(ToolChainFactory::allToolChainFactories(), - [](ToolChainFactory *f) { + ToolchainFactory *gccFactory + = Utils::findOrDefault(ToolchainFactory::allToolchainFactories(), + [](ToolchainFactory *f) { return f->supportedToolChainType() == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID; }); @@ -441,9 +441,9 @@ static ToolChain *iarToolChain(const FilePath &path, Id language) && t->language() == language; }); if (!toolChain) { - ToolChainFactory *iarFactory - = Utils::findOrDefault(ToolChainFactory::allToolChainFactories(), - [](ToolChainFactory *f) { + ToolchainFactory *iarFactory + = Utils::findOrDefault(ToolchainFactory::allToolchainFactories(), + [](ToolchainFactory *f) { return f->supportedToolChainType() == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID; }); diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index 13ed66f8035..379395a2933 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -212,9 +212,9 @@ auto expandTargetsAndPackages = [](Targets &targets, Packages &packages) { void verifyIarToolchain(const McuToolChainPackagePtr &iarToolchainPackage) { - ProjectExplorer::ToolChainFactory toolchainFactory; + ProjectExplorer::ToolchainFactory toolchainFactory; Id iarId{BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID}; - ToolChain *iarToolchain{ProjectExplorer::ToolChainFactory::createToolChain(iarId)}; + ToolChain *iarToolchain{ProjectExplorer::ToolchainFactory::createToolChain(iarId)}; iarToolchain->setLanguage(cxxLanguageId); ToolChainManager::registerToolChain(iarToolchain); @@ -235,10 +235,10 @@ void verifyIarToolchain(const McuToolChainPackagePtr &iarToolchainPackage) void verifyArmGccToolchain(const McuToolChainPackagePtr &armGccPackage, const QStringList &versions) { //Fake register and fake detect compiler. - ProjectExplorer::ToolChainFactory toolchainFactory; + ProjectExplorer::ToolchainFactory toolchainFactory; Id armGccId{ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID}; - ToolChain *armToolchain{ProjectExplorer::ToolChainFactory::createToolChain(armGccId)}; + ToolChain *armToolchain{ProjectExplorer::ToolchainFactory::createToolChain(armGccId)}; armToolchain->setLanguage(cxxLanguageId); ToolChainManager::registerToolChain(armToolchain); diff --git a/src/plugins/nim/nimplugin.cpp b/src/plugins/nim/nimplugin.cpp index 1b435ae0ebd..d3495f0a24a 100644 --- a/src/plugins/nim/nimplugin.cpp +++ b/src/plugins/nim/nimplugin.cpp @@ -54,7 +54,7 @@ public: NimCompilerCleanStepFactory cleanStepFactory; NimCodeStyleSettingsPage codeStyleSettingsPage; NimCodeStylePreferencesFactory codeStylePreferencesPage; - NimToolChainFactory toolChainFactory; + NimToolchainFactory toolChainFactory; NimProjectFactory nimProjectFactory; NimbleProjectFactory nimbleProjectFactory; diff --git a/src/plugins/nim/project/nimtoolchain.cpp b/src/plugins/nim/project/nimtoolchain.cpp index a128846f9a0..05efffbb9df 100644 --- a/src/plugins/nim/project/nimtoolchain.cpp +++ b/src/plugins/nim/project/nimtoolchain.cpp @@ -118,7 +118,7 @@ bool NimToolChain::parseVersion(const FilePath &path, std::tuple return true; } -// NimToolChainConfigWidget +// NimToolchainConfigWidget class NimToolChainConfigWidget : public ToolchainConfigWidget { @@ -201,9 +201,9 @@ std::unique_ptr NimToolChain::createConfigurationWidget() return std::make_unique(this); } -// NimToolChainFactory +// NimToolchainFactory -NimToolChainFactory::NimToolChainFactory() +NimToolchainFactory::NimToolchainFactory() { setDisplayName(Tr::tr("Nim")); setSupportedToolChainType(Constants::C_NIMTOOLCHAIN_TYPEID); @@ -212,7 +212,7 @@ NimToolChainFactory::NimToolChainFactory() setUserCreatable(true); } -Toolchains NimToolChainFactory::autoDetect(const ToolchainDetector &detector) const +Toolchains NimToolchainFactory::autoDetect(const ToolchainDetector &detector) const { Toolchains result; @@ -235,7 +235,7 @@ Toolchains NimToolChainFactory::autoDetect(const ToolchainDetector &detector) co return result; } -Toolchains NimToolChainFactory::detectForImport(const ToolChainDescription &tcd) const +Toolchains NimToolchainFactory::detectForImport(const ToolChainDescription &tcd) const { Toolchains result; if (tcd.language == Constants::C_NIMLANGUAGE_ID) { diff --git a/src/plugins/nim/project/nimtoolchain.h b/src/plugins/nim/project/nimtoolchain.h index eb6d950d556..992c2084f10 100644 --- a/src/plugins/nim/project/nimtoolchain.h +++ b/src/plugins/nim/project/nimtoolchain.h @@ -34,10 +34,10 @@ private: std::tuple m_version; }; -class NimToolChainFactory : public ProjectExplorer::ToolChainFactory +class NimToolchainFactory : public ProjectExplorer::ToolchainFactory { public: - NimToolChainFactory(); + NimToolchainFactory(); ProjectExplorer::Toolchains autoDetect(const ProjectExplorer::ToolchainDetector &detector) const final; ProjectExplorer::Toolchains detectForImport(const ProjectExplorer::ToolChainDescription &tcd) const final; diff --git a/src/plugins/projectexplorer/customtoolchain.cpp b/src/plugins/projectexplorer/customtoolchain.cpp index a619ed2b897..8300fcf49f7 100644 --- a/src/plugins/projectexplorer/customtoolchain.cpp +++ b/src/plugins/projectexplorer/customtoolchain.cpp @@ -558,7 +558,7 @@ std::unique_ptr CustomToolChain::createConfigurationWidge // CustomToolChainFactory // -------------------------------------------------------------------------- -CustomToolChainFactory::CustomToolChainFactory() +CustomToolchainFactory::CustomToolchainFactory() { setDisplayName(Tr::tr("Custom")); setSupportedToolChainType(Constants::CUSTOM_TOOLCHAIN_TYPEID); diff --git a/src/plugins/projectexplorer/customtoolchain.h b/src/plugins/projectexplorer/customtoolchain.h index a8d8616efb9..2263eec5413 100644 --- a/src/plugins/projectexplorer/customtoolchain.h +++ b/src/plugins/projectexplorer/customtoolchain.h @@ -7,10 +7,10 @@ namespace ProjectExplorer::Internal { -class CustomToolChainFactory : public ToolChainFactory +class CustomToolchainFactory : public ToolchainFactory { public: - CustomToolChainFactory(); + CustomToolchainFactory(); }; } // ProjectExplorer::Interna; diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index c4a2dcd6b23..5ffb9314c43 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -1276,7 +1276,7 @@ static ToolChain *constructLinuxIccToolchain() namespace Internal { -class GccToolchainFactory final : public ToolChainFactory +class GccToolchainFactory final : public ToolchainFactory { public: explicit GccToolchainFactory(GccToolChain::SubType subType) diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h index d701a8db320..50000a27e76 100644 --- a/src/plugins/projectexplorer/gcctoolchain.h +++ b/src/plugins/projectexplorer/gcctoolchain.h @@ -150,7 +150,7 @@ private: friend class Internal::GccToolChainConfigWidget; friend class Internal::GccToolchainFactory; - friend class ToolChainFactory; + friend class ToolchainFactory; // "resolved" on macOS from /usr/bin/clang(++) etc to /usr/bin/clang(++) // which is used for comparison with matchesCompilerCommand diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index cbe7673d7f6..8e8482e3584 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -1866,7 +1866,7 @@ ClangClToolChain::BuiltInHeaderPathsRunner ClangClToolChain::createBuiltInHeader // MsvcToolchainFactory // -------------------------------------------------------------------------- -class MsvcToolchainFactory : public ToolChainFactory +class MsvcToolchainFactory : public ToolchainFactory { public: MsvcToolchainFactory() @@ -2237,7 +2237,7 @@ bool MsvcToolChain::WarningFlagAdder::triggered() const // ClangClToolchainFactory // -------------------------------------------------------------------------- -class ClangClToolchainFactory : public ToolChainFactory +class ClangClToolchainFactory : public ToolchainFactory { public: ClangClToolchainFactory() diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index e925ed66d2c..f6c61bded15 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -645,7 +645,7 @@ public: WinDebugInterface m_winDebugInterface; #endif - CustomToolChainFactory m_customToolChainFactory; + CustomToolchainFactory m_customToolChainFactory; DesktopDeviceFactory m_desktopDeviceFactory; diff --git a/src/plugins/projectexplorer/projectimporter.cpp b/src/plugins/projectexplorer/projectimporter.cpp index fec26598c33..9507a7e36b9 100644 --- a/src/plugins/projectexplorer/projectimporter.cpp +++ b/src/plugins/projectexplorer/projectimporter.cpp @@ -370,7 +370,7 @@ static ProjectImporter::ToolChainData createToolChains(const ToolChainDescriptio { ProjectImporter::ToolChainData data; - for (ToolChainFactory *factory : ToolChainFactory::allToolChainFactories()) { + for (ToolchainFactory *factory : ToolchainFactory::allToolchainFactories()) { data.tcs = factory->detectForImport(tcd); if (data.tcs.isEmpty()) continue; diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp index 5d51c501715..2d367cd5eb3 100644 --- a/src/plugins/projectexplorer/toolchain.cpp +++ b/src/plugins/projectexplorer/toolchain.cpp @@ -28,9 +28,9 @@ const char LANGUAGE_KEY_V1[] = "ProjectExplorer.ToolChain.Language"; // For QtCr const char LANGUAGE_KEY_V2[] = "ProjectExplorer.ToolChain.LanguageV2"; // For QtCreator > 4.2 const char CODE_MODEL_TRIPLE_KEY[] = "ExplicitCodeModelTargetTriple"; -QList &toolChainFactories() +QList &toolchainFactories() { - static QList theToolChainFactories; + static QList theToolChainFactories; return theToolChainFactories; } @@ -219,7 +219,7 @@ bool ToolChain::operator == (const ToolChain &tc) const ToolChain *ToolChain::clone() const { - for (ToolChainFactory *f : std::as_const(toolChainFactories())) { + for (ToolchainFactory *f : std::as_const(toolchainFactories())) { if (f->supportedToolChainType() == d->m_typeId) { ToolChain *tc = f->create(); QTC_ASSERT(tc, return nullptr); @@ -557,44 +557,44 @@ void ToolChain::setExplicitCodeModelTargetTriple(const QString &triple) Used by the tool chain manager to restore user-generated tool chains. */ -ToolChainFactory::ToolChainFactory() +ToolchainFactory::ToolchainFactory() { - toolChainFactories().append(this); + toolchainFactories().append(this); } -ToolChainFactory::~ToolChainFactory() +ToolchainFactory::~ToolchainFactory() { - toolChainFactories().removeOne(this); + toolchainFactories().removeOne(this); } -const QList ToolChainFactory::allToolChainFactories() +const QList ToolchainFactory::allToolchainFactories() { - return toolChainFactories(); + return toolchainFactories(); } -Toolchains ToolChainFactory::autoDetect(const ToolchainDetector &detector) const +Toolchains ToolchainFactory::autoDetect(const ToolchainDetector &detector) const { Q_UNUSED(detector) return {}; } -Toolchains ToolChainFactory::detectForImport(const ToolChainDescription &tcd) const +Toolchains ToolchainFactory::detectForImport(const ToolChainDescription &tcd) const { Q_UNUSED(tcd) return {}; } -bool ToolChainFactory::canCreate() const +bool ToolchainFactory::canCreate() const { return m_userCreatable; } -ToolChain *ToolChainFactory::create() const +ToolChain *ToolchainFactory::create() const { return m_toolchainConstructor ? m_toolchainConstructor() : nullptr; } -ToolChain *ToolChainFactory::restore(const Store &data) +ToolChain *ToolchainFactory::restore(const Store &data) { if (!m_toolchainConstructor) return nullptr; @@ -618,24 +618,24 @@ static QPair rawIdData(const Store &data) return {raw.mid(0, pos), raw.mid(pos + 1)}; } -QByteArray ToolChainFactory::idFromMap(const Store &data) +QByteArray ToolchainFactory::idFromMap(const Store &data) { return rawIdData(data).second.toUtf8(); } -Id ToolChainFactory::typeIdFromMap(const Store &data) +Id ToolchainFactory::typeIdFromMap(const Store &data) { return Id::fromString(rawIdData(data).first); } -void ToolChainFactory::autoDetectionToMap(Store &data, bool detected) +void ToolchainFactory::autoDetectionToMap(Store &data, bool detected) { data.insert(AUTODETECT_KEY, detected); } -ToolChain *ToolChainFactory::createToolChain(Id toolChainType) +ToolChain *ToolchainFactory::createToolChain(Id toolChainType) { - for (ToolChainFactory *factory : std::as_const(toolChainFactories())) { + for (ToolchainFactory *factory : std::as_const(toolchainFactories())) { if (factory->m_supportedToolChainType == toolChainType) { if (ToolChain *tc = factory->create()) { tc->d->m_typeId = toolChainType; @@ -646,42 +646,42 @@ ToolChain *ToolChainFactory::createToolChain(Id toolChainType) return nullptr; } -QList ToolChainFactory::supportedLanguages() const +QList ToolchainFactory::supportedLanguages() const { return m_supportsAllLanguages ? ToolChainManager::allLanguages() : m_supportedLanguages; } -Id ToolChainFactory::supportedToolChainType() const +Id ToolchainFactory::supportedToolChainType() const { return m_supportedToolChainType; } -void ToolChainFactory::setSupportedToolChainType(const Id &supportedToolChain) +void ToolchainFactory::setSupportedToolChainType(const Id &supportedToolChain) { m_supportedToolChainType = supportedToolChain; } -void ToolChainFactory::setSupportedLanguages(const QList &supportedLanguages) +void ToolchainFactory::setSupportedLanguages(const QList &supportedLanguages) { m_supportedLanguages = supportedLanguages; } -void ToolChainFactory::setSupportsAllLanguages(bool supportsAllLanguages) +void ToolchainFactory::setSupportsAllLanguages(bool supportsAllLanguages) { m_supportsAllLanguages = supportsAllLanguages; } -void ToolChainFactory::setToolchainConstructor(const ToolChainConstructor &toolchainContructor) +void ToolchainFactory::setToolchainConstructor(const ToolChainConstructor &toolchainContructor) { m_toolchainConstructor = toolchainContructor; } -ToolChainFactory::ToolChainConstructor ToolChainFactory::toolchainConstructor() const +ToolchainFactory::ToolChainConstructor ToolchainFactory::toolchainConstructor() const { return m_toolchainConstructor; } -void ToolChainFactory::setUserCreatable(bool userCreatable) +void ToolchainFactory::setUserCreatable(bool userCreatable) { m_userCreatable = userCreatable; } diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index df711d7a9e2..3c4ea73c53b 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -42,7 +42,6 @@ QString languageId(Language l); class GccToolChain; class ToolchainConfigWidget; -class ToolChainFactory; class Kit; namespace Internal { class ToolChainSettingsAccessor; } @@ -198,7 +197,7 @@ private: const std::unique_ptr d; friend class Internal::ToolChainSettingsAccessor; - friend class ToolChainFactory; + friend class ToolchainFactory; }; using Toolchains = QList; @@ -242,16 +241,16 @@ public: const Utils::FilePaths searchPaths; // If empty use device path and/or magic. }; -class PROJECTEXPLORER_EXPORT ToolChainFactory +class PROJECTEXPLORER_EXPORT ToolchainFactory { - ToolChainFactory(const ToolChainFactory &) = delete; - ToolChainFactory &operator=(const ToolChainFactory &) = delete; + ToolchainFactory(const ToolchainFactory &) = delete; + ToolchainFactory &operator=(const ToolchainFactory &) = delete; public: - ToolChainFactory(); - virtual ~ToolChainFactory(); + ToolchainFactory(); + virtual ~ToolchainFactory(); - static const QList allToolChainFactories(); + static const QList allToolchainFactories(); QString displayName() const { return m_displayName; } Utils::Id supportedToolChainType() const; @@ -288,7 +287,7 @@ protected: Utils::FilePath compilerPath; QString compilerVersion; - bool operator==(const ToolChainFactory::Candidate &other) const { + bool operator==(const ToolchainFactory::Candidate &other) const { return compilerPath == other.compilerPath && compilerVersion == other.compilerVersion; } diff --git a/src/plugins/projectexplorer/toolchainoptionspage.cpp b/src/plugins/projectexplorer/toolchainoptionspage.cpp index a4efa921634..fcd59e46b08 100644 --- a/src/plugins/projectexplorer/toolchainoptionspage.cpp +++ b/src/plugins/projectexplorer/toolchainoptionspage.cpp @@ -155,8 +155,8 @@ public: ToolChainOptionsWidget() { m_detectionSettings = ToolChainManager::detectionSettings(); - m_factories = Utils::filtered(ToolChainFactory::allToolChainFactories(), - [](ToolChainFactory *factory) { return factory->canCreate();}); + m_factories = Utils::filtered(ToolchainFactory::allToolchainFactories(), + [](ToolchainFactory *factory) { return factory->canCreate();}); m_model.setHeader({Tr::tr("Name"), Tr::tr("Type")}); auto autoRoot = new StaticTreeItem({ProjectExplorer::Constants::msgAutoDetected()}, @@ -194,7 +194,7 @@ public: m_addButton = new QPushButton(Tr::tr("Add"), this); auto addMenu = new QMenu; - for (ToolChainFactory *factory : std::as_const(m_factories)) { + for (ToolchainFactory *factory : std::as_const(m_factories)) { QList languages = factory->supportedLanguages(); if (languages.isEmpty()) continue; @@ -295,7 +295,7 @@ public: void toolChainSelectionChanged(); void updateState(); - void createToolChain(ToolChainFactory *factory, const Utils::Id &language); + void createToolChain(ToolchainFactory *factory, const Utils::Id &language); void cloneToolChain(); ToolChainTreeItem *currentTreeItem(); @@ -305,7 +305,7 @@ public: void removeToolChain(ProjectExplorer::ToolChain *); StaticTreeItem *parentForToolChain(ToolChain *tc); - QAction *createAction(const QString &name, ToolChainFactory *factory, Utils::Id language) + QAction *createAction(const QString &name, ToolchainFactory *factory, Utils::Id language) { auto action = new QAction(name, nullptr); connect(action, &QAction::triggered, this, @@ -320,7 +320,7 @@ public: private: TreeModel m_model; KitSettingsSortModel m_sortModel; - QList m_factories; + QList m_factories; QTreeView *m_toolChainView; DetailsWidget *m_container; QStackedWidget *m_widgetStack; @@ -414,7 +414,7 @@ void ToolChainOptionsWidget::redetectToolchains() Toolchains toAdd; QSet toDelete; ToolChainManager::resetBadToolchains(); - for (ToolChainFactory *f : ToolChainFactory::allToolChainFactories()) { + for (ToolchainFactory *f : ToolchainFactory::allToolchainFactories()) { const ToolchainDetector detector(knownTcs, DeviceManager::defaultDesktopDevice(), {}); // FIXME: Pass search paths for (ToolChain * const tc : f->autoDetect(detector)) { if (knownTcs.contains(tc) || toDelete.contains(tc)) @@ -508,7 +508,7 @@ void ToolChainOptionsWidget::apply() ToolChainManager::setDetectionSettings(m_detectionSettings); } -void ToolChainOptionsWidget::createToolChain(ToolChainFactory *factory, const Utils::Id &language) +void ToolChainOptionsWidget::createToolChain(ToolchainFactory *factory, const Utils::Id &language) { QTC_ASSERT(factory, return); QTC_ASSERT(factory->canCreate(), return); diff --git a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp index 9af52f0bf9c..fcc66e6e956 100644 --- a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp +++ b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp @@ -57,7 +57,7 @@ struct ToolChainOperations static Toolchains autoDetectToolChains(const ToolchainDetector &detector) { Toolchains result; - for (ToolChainFactory *f : ToolChainFactory::allToolChainFactories()) { + for (ToolchainFactory *f : ToolchainFactory::allToolchainFactories()) { NANOTRACE_SCOPE_ARGS("ProjectExplorer", "ToolChainSettingsAccessor::autoDetectToolChains", {"factory", f->displayName().toStdString()}); @@ -243,7 +243,7 @@ void ToolChainSettingsAccessor::saveToolChains(const Toolchains &toolchains, QWi Toolchains ToolChainSettingsAccessor::toolChains(const Store &data) const { Toolchains result; - const QList factories = ToolChainFactory::allToolChainFactories(); + const QList factories = ToolchainFactory::allToolchainFactories(); const int count = data.value(TOOLCHAIN_COUNT_KEY, 0).toInt(); for (int i = 0; i < count; ++i) { @@ -254,9 +254,9 @@ Toolchains ToolChainSettingsAccessor::toolChains(const Store &data) const const Store tcMap = storeFromVariant(data.value(key)); bool restored = false; - const Utils::Id tcType = ToolChainFactory::typeIdFromMap(tcMap); + const Utils::Id tcType = ToolchainFactory::typeIdFromMap(tcMap); if (tcType.isValid()) { - for (ToolChainFactory *f : factories) { + for (ToolchainFactory *f : factories) { if (f->supportedToolChainType() == tcType) { if (ToolChain *tc = f->restore(tcMap)) { result.append(tc); @@ -269,7 +269,7 @@ Toolchains ToolChainSettingsAccessor::toolChains(const Store &data) const if (!restored) qWarning("Warning: Unable to restore compiler type '%s' for tool chain %s.", qPrintable(tcType.toString()), - qPrintable(QString::fromUtf8(ToolChainFactory::idFromMap(tcMap)))); + qPrintable(QString::fromUtf8(ToolchainFactory::idFromMap(tcMap)))); } return result; @@ -356,16 +356,16 @@ namespace ProjectExplorer { void ProjectExplorerPlugin::testToolChainMerging_data() { - class TestToolChainFactory : ToolChainFactory + class TestToolchainFactory : ToolchainFactory { public: - TestToolChainFactory() { + TestToolchainFactory() { setSupportedToolChainType(TestToolChainType); setToolchainConstructor([] { return new TTC; }); } }; - TestToolChainFactory factory; + TestToolchainFactory factory; QTest::addColumn("system"); QTest::addColumn("user"); diff --git a/src/plugins/qnx/qnxtoolchain.cpp b/src/plugins/qnx/qnxtoolchain.cpp index cfafd7dfcb9..9f278ae7083 100644 --- a/src/plugins/qnx/qnxtoolchain.cpp +++ b/src/plugins/qnx/qnxtoolchain.cpp @@ -251,12 +251,12 @@ void QnxToolChainConfigWidget::handleSdpPathChange() emit dirty(); } -// QnxToolChainFactory +// QnxToolchainFactory -class QnxToolChainFactory : public ToolChainFactory +class QnxToolchainFactory : public ToolchainFactory { public: - QnxToolChainFactory() + QnxToolchainFactory() { setDisplayName(Tr::tr("QCC")); setSupportedToolChainType(Constants::QNX_TOOLCHAIN_ID); @@ -279,7 +279,7 @@ public: void setupQnxToolChain() { - static QnxToolChainFactory theQnxToolChainFactory; + static QnxToolchainFactory theQnxToolChainFactory; } } // Qnx::Internal diff --git a/src/plugins/webassembly/webassemblyplugin.cpp b/src/plugins/webassembly/webassemblyplugin.cpp index 87b4283e291..d66ae5c9ca8 100644 --- a/src/plugins/webassembly/webassemblyplugin.cpp +++ b/src/plugins/webassembly/webassemblyplugin.cpp @@ -34,7 +34,7 @@ namespace WebAssembly::Internal { class WebAssemblyPluginPrivate { public: - WebAssemblyToolChainFactory toolChainFactory; + WebAssemblyToolchainFactory toolChainFactory; WebAssemblyDeviceFactory deviceFactory; WebAssemblyQtVersionFactory qtVersionFactory; EmrunRunConfigurationFactory emrunRunConfigurationFactory; diff --git a/src/plugins/webassembly/webassemblytoolchain.cpp b/src/plugins/webassembly/webassemblytoolchain.cpp index 925b7f5dbfb..e518699d33e 100644 --- a/src/plugins/webassembly/webassemblytoolchain.cpp +++ b/src/plugins/webassembly/webassemblytoolchain.cpp @@ -168,7 +168,7 @@ bool WebAssemblyToolChain::areToolChainsRegistered() return !ToolChainManager::findToolChains(toolChainAbi()).isEmpty(); } -WebAssemblyToolChainFactory::WebAssemblyToolChainFactory() +WebAssemblyToolchainFactory::WebAssemblyToolchainFactory() { setDisplayName(Tr::tr("Emscripten")); setSupportedToolChainType(Constants::WEBASSEMBLY_TOOLCHAIN_TYPEID); @@ -178,7 +178,7 @@ WebAssemblyToolChainFactory::WebAssemblyToolChainFactory() setUserCreatable(true); } -Toolchains WebAssemblyToolChainFactory::autoDetect(const ToolchainDetector &detector) const +Toolchains WebAssemblyToolchainFactory::autoDetect(const ToolchainDetector &detector) const { return doAutoDetect(detector); } diff --git a/src/plugins/webassembly/webassemblytoolchain.h b/src/plugins/webassembly/webassemblytoolchain.h index c6c9683597c..2b78a2cbf29 100644 --- a/src/plugins/webassembly/webassemblytoolchain.h +++ b/src/plugins/webassembly/webassemblytoolchain.h @@ -25,10 +25,10 @@ public: static bool areToolChainsRegistered(); }; -class WebAssemblyToolChainFactory : public ProjectExplorer::ToolChainFactory +class WebAssemblyToolchainFactory : public ProjectExplorer::ToolchainFactory { public: - WebAssemblyToolChainFactory(); + WebAssemblyToolchainFactory(); ProjectExplorer::Toolchains autoDetect( const ProjectExplorer::ToolchainDetector &detector) const final; From c28fb1fdbe7eb943b5156f99c61e7baef7592b31 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Nov 2023 15:53:31 +0100 Subject: [PATCH 0375/1546] ProjectExplorer: Rename ToolChain to Toolchain Change-Id: Ibb520f14ff3e2a6147ca5d419b9351c50c141063 Reviewed-by: Christian Kandeler --- src/plugins/android/androidconfigurations.cpp | 28 ++--- .../androidpackageinstallationstep.cpp | 2 +- src/plugins/android/androidtoolchain.cpp | 10 +- src/plugins/android/androidtoolchain.h | 2 +- src/plugins/autotest/autotestunittests.cpp | 2 +- src/plugins/autotest/loadprojectscenario.cpp | 2 +- src/plugins/baremetal/iarewtoolchain.cpp | 24 ++-- src/plugins/baremetal/keiltoolchain.cpp | 22 ++-- src/plugins/baremetal/sdcctoolchain.cpp | 22 ++-- .../clangtoolspreconfiguredsessiontests.cpp | 2 +- .../clangtools/clangtoolsunittests.cpp | 2 +- .../cmakebuildconfiguration.cpp | 4 +- .../cmakeprojectmanager/cmakebuildstep.cpp | 2 +- .../cmakeprojectmanager/cmakekitaspect.cpp | 6 +- .../cmakeprojectimporter.cpp | 16 +-- .../compilationdatabaseproject.cpp | 10 +- .../compilationdatabasetests.cpp | 2 +- src/plugins/conan/conaninstallstep.cpp | 4 +- .../cppeditor/compileroptionsbuilder_test.cpp | 2 +- src/plugins/cppeditor/cppmodelmanager.cpp | 6 +- src/plugins/cppeditor/projectinfo_test.cpp | 8 +- src/plugins/cppeditor/projectpart.cpp | 4 +- src/plugins/cppeditor/projectpart.h | 2 +- src/plugins/docker/kitdetector.cpp | 12 +- .../incredibuild/makecommandbuilder.cpp | 2 +- src/plugins/ios/iosbuildstep.cpp | 4 +- src/plugins/ios/iosconfigurations.cpp | 6 +- src/plugins/mcusupport/mcupackage.cpp | 30 ++--- src/plugins/mcusupport/mcupackage.h | 8 +- src/plugins/mcusupport/mcusupportoptions.h | 2 +- src/plugins/mcusupport/mcusupportsdk.cpp | 8 +- src/plugins/mcusupport/mcutarget.h | 2 +- src/plugins/mcusupport/test/unittest.cpp | 8 +- .../mesonprojectparser.cpp | 6 +- .../mesonprojectmanager/mesonprojectparser.h | 8 +- src/plugins/nim/project/nimtoolchain.cpp | 18 +-- src/plugins/nim/project/nimtoolchain.h | 2 +- .../projectexplorer/customtoolchain.cpp | 20 ++-- src/plugins/projectexplorer/gcctoolchain.cpp | 68 +++++------ src/plugins/projectexplorer/gcctoolchain.h | 4 +- src/plugins/projectexplorer/kitaspects.cpp | 86 +++++++------- src/plugins/projectexplorer/kitaspects.h | 14 +-- src/plugins/projectexplorer/kitmanager.cpp | 16 +-- src/plugins/projectexplorer/makestep.cpp | 14 +-- src/plugins/projectexplorer/msvctoolchain.cpp | 44 +++---- src/plugins/projectexplorer/msvctoolchain.h | 6 +- .../projectexplorer/projectimporter.cpp | 14 +-- src/plugins/projectexplorer/projectimporter.h | 4 +- .../projectexplorer/rawprojectpart.cpp | 4 +- src/plugins/projectexplorer/rawprojectpart.h | 12 +- src/plugins/projectexplorer/toolchain.cpp | 112 +++++++++--------- src/plugins/projectexplorer/toolchain.h | 28 ++--- .../projectexplorer/toolchainconfigwidget.cpp | 4 +- .../projectexplorer/toolchainconfigwidget.h | 8 +- .../projectexplorer/toolchainmanager.cpp | 22 ++-- .../projectexplorer/toolchainmanager.h | 22 ++-- .../projectexplorer/toolchainoptionspage.cpp | 38 +++--- .../toolchainsettingsaccessor.cpp | 94 +++++++-------- .../toolchainsettingsaccessor.h | 8 +- .../defaultpropertyprovider.cpp | 12 +- src/plugins/qbsprojectmanager/qbsproject.cpp | 12 +- .../qbsprojectmanager/qbsprojectimporter.cpp | 4 +- .../qmakebuildconfiguration.cpp | 2 +- .../qmakebuildconfiguration.h | 2 +- .../qmakeprojectmanager/qmakemakestep.cpp | 2 +- .../qmakeprojectmanager/qmakeproject.cpp | 8 +- .../qmakeprojectmanager/qmakeproject.h | 2 +- .../qmakeprojectimporter.cpp | 12 +- src/plugins/qmakeprojectmanager/qmakestep.cpp | 2 +- src/plugins/qnx/qnxsettingspage.cpp | 14 +-- src/plugins/qnx/qnxsettingspage.h | 6 +- src/plugins/qnx/qnxtoolchain.cpp | 2 +- src/plugins/qnx/qnxtoolchain.h | 2 +- src/plugins/qtsupport/baseqtversion.cpp | 8 +- src/plugins/qtsupport/baseqtversion.h | 4 +- src/plugins/qtsupport/qtkitaspect.cpp | 10 +- src/plugins/qtsupport/qtoptionspage.cpp | 12 +- .../webassembly/webassemblytoolchain.cpp | 8 +- 78 files changed, 533 insertions(+), 533 deletions(-) diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index b91da03e8ea..0016cd3f6bf 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -1130,7 +1130,7 @@ void AndroidConfigurations::setConfig(const AndroidConfig &devConfigs) emit m_instance->updated(); } -static bool matchToolChain(const ToolChain *atc, const ToolChain *btc) +static bool matchToolChain(const Toolchain *atc, const Toolchain *btc) { if (atc == btc) return true; @@ -1147,12 +1147,12 @@ static bool matchToolChain(const ToolChain *atc, const ToolChain *btc) void AndroidConfigurations::registerNewToolChains() { const Toolchains existingAndroidToolChains - = ToolChainManager::toolchains(Utils::equal(&ToolChain::typeId, Id(Constants::ANDROID_TOOLCHAIN_TYPEID))); + = ToolChainManager::toolchains(Utils::equal(&Toolchain::typeId, Id(Constants::ANDROID_TOOLCHAIN_TYPEID))); const Toolchains newToolchains = AndroidToolchainFactory::autodetectToolChains( existingAndroidToolChains); - for (ToolChain *tc : newToolchains) + for (Toolchain *tc : newToolchains) ToolChainManager::registerToolChain(tc); registerCustomToolChainsAndDebuggers(); @@ -1160,9 +1160,9 @@ void AndroidConfigurations::registerNewToolChains() void AndroidConfigurations::removeOldToolChains() { - const auto tcs = ToolChainManager::toolchains(Utils::equal(&ToolChain::typeId, + const auto tcs = ToolChainManager::toolchains(Utils::equal(&Toolchain::typeId, Id(Constants::ANDROID_TOOLCHAIN_TYPEID))); - for (ToolChain *tc : tcs) { + for (Toolchain *tc : tcs) { if (!tc->isValid()) ToolChainManager::deregisterToolChain(tc); } @@ -1241,7 +1241,7 @@ static const Debugger::DebuggerItem *existingDebugger(const FilePath &command, return nullptr; } -static QVariant findOrRegisterDebugger(ToolChain *tc, +static QVariant findOrRegisterDebugger(Toolchain *tc, const QStringList &abisList, bool customDebugger = false) { @@ -1307,14 +1307,14 @@ static QVariant findOrRegisterDebugger(ToolChain *tc, void AndroidConfigurations::registerCustomToolChainsAndDebuggers() { const Toolchains existingAndroidToolChains = ToolChainManager::toolchains( - Utils::equal(&ToolChain::typeId, Utils::Id(Constants::ANDROID_TOOLCHAIN_TYPEID))); + Utils::equal(&Toolchain::typeId, Utils::Id(Constants::ANDROID_TOOLCHAIN_TYPEID))); const FilePaths customNdks = FileUtils::toFilePathList(currentConfig().getCustomNdkList()); const Toolchains customToolchains = AndroidToolchainFactory::autodetectToolChainsFromNdks(existingAndroidToolChains, customNdks, true); - for (ToolChain *tc : customToolchains) { + for (Toolchain *tc : customToolchains) { ToolChainManager::registerToolChain(tc); const auto androidToolChain = static_cast(tc); QString abiStr; @@ -1359,12 +1359,12 @@ void AndroidConfigurations::updateAutomaticKitList() } // register new kits - const Toolchains toolchains = ToolChainManager::toolchains([](const ToolChain *tc) { + const Toolchains toolchains = ToolChainManager::toolchains([](const Toolchain *tc) { return tc->isAutoDetected() && tc->typeId() == Constants::ANDROID_TOOLCHAIN_TYPEID && tc->isValid(); }); QList unhandledKits = existingKits; - for (ToolChain *tc : toolchains) { + for (Toolchain *tc : toolchains) { if (tc->language() != ProjectExplorer::Constants::CXX_LANGUAGE_ID) continue; @@ -1374,13 +1374,13 @@ void AndroidConfigurations::updateAutomaticKitList() continue; const Toolchains allLanguages - = Utils::filtered(toolchains, [tc, tcNdk](ToolChain *otherTc) { + = Utils::filtered(toolchains, [tc, tcNdk](Toolchain *otherTc) { FilePath otherNdk = static_cast(otherTc)->ndkLocation(); return tc->targetAbi() == otherTc->targetAbi() && tcNdk == otherNdk; }); - QHash toolChainForLanguage; - for (ToolChain *tc : allLanguages) + QHash toolChainForLanguage; + for (Toolchain *tc : allLanguages) toolChainForLanguage[tc->language()] = tc; Kit *existingKit = Utils::findOrDefault(existingKits, [&](const Kit *b) { @@ -1396,7 +1396,7 @@ void AndroidConfigurations::updateAutomaticKitList() k->setAutoDetected(true); k->setAutoDetectionSource("AndroidConfiguration"); DeviceTypeKitAspect::setDeviceTypeId(k, Constants::ANDROID_DEVICE_TYPE); - for (ToolChain *tc : allLanguages) + for (Toolchain *tc : allLanguages) ToolChainKitAspect::setToolChain(k, tc); QtKitAspect::setQtVersion(k, qt); QStringList abis = static_cast(qt)->androidAbis(); diff --git a/src/plugins/android/androidpackageinstallationstep.cpp b/src/plugins/android/androidpackageinstallationstep.cpp index dc5b8ffc478..a67c4c425f0 100644 --- a/src/plugins/android/androidpackageinstallationstep.cpp +++ b/src/plugins/android/androidpackageinstallationstep.cpp @@ -73,7 +73,7 @@ bool AndroidPackageInstallationStep::init() return false; } - ToolChain *tc = ToolChainKitAspect::cxxToolChain(kit()); + Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit()); QTC_ASSERT(tc, reportWarningOrError(Tr::tr("\"%1\" step has an invalid C++ toolchain.") .arg(displayName()), Task::TaskType::Error); return false); diff --git a/src/plugins/android/androidtoolchain.cpp b/src/plugins/android/androidtoolchain.cpp index cf1a79da15d..a71f43528b4 100644 --- a/src/plugins/android/androidtoolchain.cpp +++ b/src/plugins/android/androidtoolchain.cpp @@ -34,10 +34,10 @@ Q_GLOBAL_STATIC_WITH_ARGS(ClangTargetsType, ClangTargets, ({ Abi(Abi::ArmArchitecture, Abi::LinuxOS, Abi::AndroidLinuxFlavor, Abi::ElfFormat, 64)}} )); -static ToolChain *findToolChain(FilePath &compilerPath, Id lang, const QString &target, +static Toolchain *findToolChain(FilePath &compilerPath, Id lang, const QString &target, const ToolChainList &alreadyKnown) { - ToolChain *tc = Utils::findOrDefault(alreadyKnown, [target, compilerPath, lang](ToolChain *tc) { + Toolchain *tc = Utils::findOrDefault(alreadyKnown, [target, compilerPath, lang](Toolchain *tc) { return tc->typeId() == Constants::ANDROID_TOOLCHAIN_TYPEID && tc->language() == lang && tc->targetAbi() == ClangTargets->value(target) @@ -180,7 +180,7 @@ ToolChainList AndroidToolchainFactory::autodetectToolChainsFromNdks( const QList &ndkLocations, const bool isCustom) { - QList result; + QList result; const AndroidConfig config = AndroidConfigurations::currentConfig(); const Id LanguageIds[] { @@ -211,7 +211,7 @@ ToolChainList AndroidToolchainFactory::autodetectToolChainsFromNdks( while (targetItr != ClangTargets->constEnd()) { const Abi &abi = targetItr.value(); const QString target = targetItr.key(); - ToolChain *tc = findToolChain(compilerCommand, lang, target, alreadyKnown); + Toolchain *tc = findToolChain(compilerCommand, lang, target, alreadyKnown); QLatin1String customStr = isCustom ? QLatin1String("Custom ") : QLatin1String(); const QString displayName(customStr + QString("Android Clang (%1, %2, NDK %3)") @@ -241,7 +241,7 @@ ToolChainList AndroidToolchainFactory::autodetectToolChainsFromNdks( if (auto gccTc = dynamic_cast(tc)) gccTc->resetToolChain(compilerCommand); - tc->setDetection(ToolChain::AutoDetection); + tc->setDetection(Toolchain::AutoDetection); result << tc; ++targetItr; } diff --git a/src/plugins/android/androidtoolchain.h b/src/plugins/android/androidtoolchain.h index f11efa316cb..1e966b0ec7a 100644 --- a/src/plugins/android/androidtoolchain.h +++ b/src/plugins/android/androidtoolchain.h @@ -9,7 +9,7 @@ namespace Android::Internal { -using ToolChainList = QList; +using ToolChainList = QList; class AndroidToolChain : public ProjectExplorer::GccToolChain { diff --git a/src/plugins/autotest/autotestunittests.cpp b/src/plugins/autotest/autotestunittests.cpp index 0ce52721e3f..7f3a55d577c 100644 --- a/src/plugins/autotest/autotestunittests.cpp +++ b/src/plugins/autotest/autotestunittests.cpp @@ -59,7 +59,7 @@ void AutoTestUnitTests::initTestCase() m_isQt4 = qtVersion->qtVersionString().startsWith('4'); else QSKIP("Could not figure out which Qt version is used for default kit."); - const ToolChain * const toolchain = ToolChainKitAspect::cxxToolChain(m_kit); + const Toolchain * const toolchain = ToolChainKitAspect::cxxToolChain(m_kit); if (!toolchain) QSKIP("This test requires that there is a kit with a toolchain."); diff --git a/src/plugins/autotest/loadprojectscenario.cpp b/src/plugins/autotest/loadprojectscenario.cpp index 9dc136f4e49..0b18eaab518 100644 --- a/src/plugins/autotest/loadprojectscenario.cpp +++ b/src/plugins/autotest/loadprojectscenario.cpp @@ -56,7 +56,7 @@ bool LoadProjectScenario::init() return false; } - const ToolChain * const toolchain = ToolChainKitAspect::cxxToolChain(m_kit); + const Toolchain * const toolchain = ToolChainKitAspect::cxxToolChain(m_kit); if (!toolchain) { qWarning() << "This test requires that there is a kit with a toolchain."; return false; diff --git a/src/plugins/baremetal/iarewtoolchain.cpp b/src/plugins/baremetal/iarewtoolchain.cpp index d7bd066ca09..bfc851fb654 100644 --- a/src/plugins/baremetal/iarewtoolchain.cpp +++ b/src/plugins/baremetal/iarewtoolchain.cpp @@ -280,10 +280,10 @@ private: // IarToolChain -class IarToolChain final : public ToolChain +class IarToolChain final : public Toolchain { public: - IarToolChain() : ToolChain(Constants::IAREW_TOOLCHAIN_TYPEID) + IarToolChain() : Toolchain(Constants::IAREW_TOOLCHAIN_TYPEID) { setTypeDisplayName(Tr::tr("IAREW")); setTargetAbiKey("TargetAbi"); @@ -305,7 +305,7 @@ public: std::unique_ptr createConfigurationWidget() final; - bool operator==(const ToolChain &other) const final; + bool operator==(const Toolchain &other) const final; QStringList extraCodeModelFlags() const final { return m_extraCodeModelFlags(); } @@ -318,7 +318,7 @@ private: friend class IarToolChainConfigWidget; }; -ToolChain::MacroInspectionRunner IarToolChain::createMacroInspectionRunner() const +Toolchain::MacroInspectionRunner IarToolChain::createMacroInspectionRunner() const { Environment env = Environment::systemEnvironment(); addToEnvironment(env); @@ -340,7 +340,7 @@ ToolChain::MacroInspectionRunner IarToolChain::createMacroInspectionRunner() con macros.append({"__spec_string", "", MacroType::Define}); macros.append({"__constrange(__a,__b)", "", MacroType::Define}); - const auto languageVersion = ToolChain::languageVersion(languageId, macros); + const auto languageVersion = Toolchain::languageVersion(languageId, macros); const auto report = MacroInspectionReport{macros, languageVersion}; macrosCache->insert({}, report); @@ -359,7 +359,7 @@ WarningFlags IarToolChain::warningFlags(const QStringList &cxxflags) const return WarningFlags::Default; } -ToolChain::BuiltInHeaderPathsRunner IarToolChain::createBuiltInHeaderPathsRunner( +Toolchain::BuiltInHeaderPathsRunner IarToolChain::createBuiltInHeaderPathsRunner( const Environment &) const { Environment env = Environment::systemEnvironment(); @@ -394,9 +394,9 @@ std::unique_ptr IarToolChain::createConfigurationWidget() return std::make_unique(this); } -bool IarToolChain::operator==(const ToolChain &other) const +bool IarToolChain::operator==(const Toolchain &other) const { - if (!ToolChain::operator==(other)) + if (!Toolchain::operator==(other)) return false; const auto customTc = static_cast(&other); @@ -518,7 +518,7 @@ Toolchains IarToolchainFactory::autoDetectToolchains( Toolchains result; for (const Candidate &candidate : std::as_const(candidates)) { - const Toolchains filtered = Utils::filtered(alreadyKnown, [candidate](ToolChain *tc) { + const Toolchains filtered = Utils::filtered(alreadyKnown, [candidate](Toolchain *tc) { return tc->typeId() == Constants::IAREW_TOOLCHAIN_TYPEID && tc->compilerCommand() == candidate.compilerPath && (tc->language() == ProjectExplorer::Constants::C_LANGUAGE_ID @@ -551,14 +551,14 @@ Toolchains IarToolchainFactory::autoDetectToolchain(const Candidate &candidate, const Abi abi = guessAbi(macros); const auto tc = new IarToolChain; - tc->setDetection(ToolChain::AutoDetection); + tc->setDetection(Toolchain::AutoDetection); tc->setLanguage(languageId); tc->setCompilerCommand(candidate.compilerPath); tc->setTargetAbi(abi); tc->setDisplayName(buildDisplayName(abi.architecture(), languageId, candidate.compilerVersion)); - const auto languageVersion = ToolChain::languageVersion(languageId, macros); + const auto languageVersion = Toolchain::languageVersion(languageId, macros); tc->predefinedMacrosCache()->insert({}, {macros, languageVersion}); return {tc}; } @@ -608,7 +608,7 @@ void IarToolChainConfigWidget::applyImpl() if (m_macros.isEmpty()) return; - const auto languageVersion = ToolChain::languageVersion(tc->language(), m_macros); + const auto languageVersion = Toolchain::languageVersion(tc->language(), m_macros); tc->predefinedMacrosCache()->insert({}, {m_macros, languageVersion}); setFromToolchain(); diff --git a/src/plugins/baremetal/keiltoolchain.cpp b/src/plugins/baremetal/keiltoolchain.cpp index 6b53281bb64..0db09bf7d92 100644 --- a/src/plugins/baremetal/keiltoolchain.cpp +++ b/src/plugins/baremetal/keiltoolchain.cpp @@ -418,11 +418,11 @@ private: // KeilToolChain -class KeilToolChain final : public ToolChain +class KeilToolChain final : public Toolchain { public: KeilToolChain() : - ToolChain(Constants::KEIL_TOOLCHAIN_TYPEID) + Toolchain(Constants::KEIL_TOOLCHAIN_TYPEID) { setTypeDisplayName(Tr::tr("KEIL")); setTargetAbiKey("TargetAbi"); @@ -445,7 +445,7 @@ public: std::unique_ptr createConfigurationWidget() final; - bool operator==(const ToolChain &other) const final; + bool operator==(const Toolchain &other) const final; QStringList extraCodeModelFlags() const final; @@ -458,7 +458,7 @@ private: friend class KeilToolChainConfigWidget; }; -ToolChain::MacroInspectionRunner KeilToolChain::createMacroInspectionRunner() const +Toolchain::MacroInspectionRunner KeilToolChain::createMacroInspectionRunner() const { Environment env = Environment::systemEnvironment(); addToEnvironment(env); @@ -491,7 +491,7 @@ WarningFlags KeilToolChain::warningFlags(const QStringList &cxxflags) const return WarningFlags::Default; } -ToolChain::BuiltInHeaderPathsRunner KeilToolChain::createBuiltInHeaderPathsRunner( +Toolchain::BuiltInHeaderPathsRunner KeilToolChain::createBuiltInHeaderPathsRunner( const Environment &) const { const FilePath compiler = compilerCommand(); @@ -520,9 +520,9 @@ std::unique_ptr KeilToolChain::createConfigurationWidget( return std::make_unique(this); } -bool KeilToolChain::operator ==(const ToolChain &other) const +bool KeilToolChain::operator ==(const Toolchain &other) const { - if (!ToolChain::operator ==(other)) + if (!Toolchain::operator ==(other)) return false; const auto customTc = static_cast(&other); @@ -667,7 +667,7 @@ Toolchains KeilToolchainFactory::autoDetectToolchains( for (const Candidate &candidate : std::as_const(candidates)) { const Toolchains filtered = Utils::filtered( - alreadyKnown, [candidate](ToolChain *tc) { + alreadyKnown, [candidate](Toolchain *tc) { return tc->typeId() == Constants::IAREW_TOOLCHAIN_TYPEID && tc->compilerCommand() == candidate.compilerPath && (tc->language() == ProjectExplorer::Constants::C_LANGUAGE_ID @@ -710,14 +710,14 @@ Toolchains KeilToolchainFactory::autoDetectToolchain(const Candidate &candidate, } const auto tc = new KeilToolChain; - tc->setDetection(ToolChain::AutoDetection); + tc->setDetection(Toolchain::AutoDetection); tc->setLanguage(language); tc->setCompilerCommand(candidate.compilerPath); tc->m_extraCodeModelFlags.setValue(extraArgs); tc->setTargetAbi(abi); tc->setDisplayName(buildDisplayName(abi.architecture(), language, candidate.compilerVersion)); - const auto languageVersion = ToolChain::languageVersion(language, macros); + const auto languageVersion = Toolchain::languageVersion(language, macros); tc->predefinedMacrosCache()->insert({}, {macros, languageVersion}); return {tc}; } @@ -765,7 +765,7 @@ void KeilToolChainConfigWidget::applyImpl() if (m_macros.isEmpty()) return; - const auto languageVersion = ToolChain::languageVersion(tc->language(), m_macros); + const auto languageVersion = Toolchain::languageVersion(tc->language(), m_macros); tc->predefinedMacrosCache()->insert({}, {m_macros, languageVersion}); setFromToolChain(); diff --git a/src/plugins/baremetal/sdcctoolchain.cpp b/src/plugins/baremetal/sdcctoolchain.cpp index b682400edf6..24e34d48a67 100644 --- a/src/plugins/baremetal/sdcctoolchain.cpp +++ b/src/plugins/baremetal/sdcctoolchain.cpp @@ -199,10 +199,10 @@ private: // SdccToolChain -class SdccToolChain final : public ToolChain +class SdccToolChain final : public Toolchain { public: - SdccToolChain() : ToolChain(Constants::SDCC_TOOLCHAIN_TYPEID) + SdccToolChain() : Toolchain(Constants::SDCC_TOOLCHAIN_TYPEID) { setTypeDisplayName(Tr::tr("SDCC")); setTargetAbiKey("TargetAbi"); @@ -220,7 +220,7 @@ public: std::unique_ptr createConfigurationWidget() final; - bool operator==(const ToolChain &other) const final; + bool operator==(const Toolchain &other) const final; FilePath makeCommand(const Environment &) const final { return {}; } @@ -229,7 +229,7 @@ private: friend class SdccToolChainConfigWidget; }; -ToolChain::MacroInspectionRunner SdccToolChain::createMacroInspectionRunner() const +Toolchain::MacroInspectionRunner SdccToolChain::createMacroInspectionRunner() const { Environment env = Environment::systemEnvironment(); addToEnvironment(env); @@ -263,7 +263,7 @@ WarningFlags SdccToolChain::warningFlags(const QStringList &cxxflags) const return WarningFlags::Default; } -ToolChain::BuiltInHeaderPathsRunner SdccToolChain::createBuiltInHeaderPathsRunner( +Toolchain::BuiltInHeaderPathsRunner SdccToolChain::createBuiltInHeaderPathsRunner( const Environment &) const { Environment env = Environment::systemEnvironment(); @@ -288,9 +288,9 @@ std::unique_ptr SdccToolChain::createConfigurationWidget( return std::make_unique(this); } -bool SdccToolChain::operator==(const ToolChain &other) const +bool SdccToolChain::operator==(const Toolchain &other) const { - if (!ToolChain::operator==(other)) + if (!Toolchain::operator==(other)) return false; const auto customTc = static_cast(&other); @@ -388,7 +388,7 @@ Toolchains SdccToolchainFactory::autoDetectToolchains( Toolchains result; for (const Candidate &candidate : std::as_const(candidates)) { - const Toolchains filtered = Utils::filtered(alreadyKnown, [candidate](ToolChain *tc) { + const Toolchains filtered = Utils::filtered(alreadyKnown, [candidate](Toolchain *tc) { return tc->typeId() == Constants::SDCC_TOOLCHAIN_TYPEID && tc->compilerCommand() == candidate.compilerPath && (tc->language() == ProjectExplorer::Constants::C_LANGUAGE_ID); @@ -429,14 +429,14 @@ Toolchains SdccToolchainFactory::autoDetectToolchain(const Candidate &candidate, continue; const auto tc = new SdccToolChain; - tc->setDetection(ToolChain::AutoDetection); + tc->setDetection(Toolchain::AutoDetection); tc->setLanguage(language); tc->setCompilerCommand(candidate.compilerPath); tc->setTargetAbi(abi); tc->setDisplayName(buildDisplayName(abi.architecture(), language, candidate.compilerVersion)); - const auto languageVersion = ToolChain::languageVersion(language, macros); + const auto languageVersion = Toolchain::languageVersion(language, macros); tc->predefinedMacrosCache()->insert({}, {macros, languageVersion}); tcs.push_back(tc); @@ -482,7 +482,7 @@ void SdccToolChainConfigWidget::applyImpl() if (m_macros.isEmpty()) return; - const auto languageVersion = ToolChain::languageVersion(tc->language(), m_macros); + const auto languageVersion = Toolchain::languageVersion(tc->language(), m_macros); tc->predefinedMacrosCache()->insert({}, {m_macros, languageVersion}); setFromToolchain(); diff --git a/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp b/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp index ce5c7a52549..d08a68633b5 100644 --- a/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp +++ b/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp @@ -148,7 +148,7 @@ static QList validTargets(Project *project) return false; } - const ToolChain * const toolchain = ToolChainKitAspect::cxxToolChain(kit); + const Toolchain * const toolchain = ToolChainKitAspect::cxxToolChain(kit); QTC_ASSERT(toolchain, return false); if (Core::ICore::clangExecutable(CLANG_BINDIR).isEmpty()) { diff --git a/src/plugins/clangtools/clangtoolsunittests.cpp b/src/plugins/clangtools/clangtoolsunittests.cpp index 2ea61b7acd6..086afe118f0 100644 --- a/src/plugins/clangtools/clangtoolsunittests.cpp +++ b/src/plugins/clangtools/clangtoolsunittests.cpp @@ -50,7 +50,7 @@ void ClangToolsUnitTests::initTestCase() if (!m_kit) QSKIP("This test requires at least one valid kit with a valid Qt"); - const ToolChain *const toolchain = ToolChainKitAspect::cxxToolChain(m_kit); + const Toolchain * const toolchain = ToolChainKitAspect::cxxToolChain(m_kit); if (!toolchain) QSKIP("This test requires that there is a kit with a toolchain."); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index c00d8f4f510..27b9c6348df 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -1091,7 +1091,7 @@ static bool isQnx(const Kit *k) static bool isWindowsARM64(const Kit *k) { - ToolChain *toolchain = ToolChainKitAspect::cxxToolChain(k); + Toolchain *toolchain = ToolChainKitAspect::cxxToolChain(k); if (!toolchain) return false; const Abi targetAbi = toolchain->targetAbi(); @@ -1124,7 +1124,7 @@ static CommandLine defaultInitialCMakeCommand(const Kit *k, const QString &build const QString sysRoot = SysRootKitAspect::sysRoot(k).path(); if (!sysRoot.isEmpty()) { cmd.addArg("-DCMAKE_SYSROOT:PATH=" + sysRoot); - if (ToolChain *tc = ToolChainKitAspect::cxxToolChain(k)) { + if (Toolchain *tc = ToolChainKitAspect::cxxToolChain(k)) { const QString targetTriple = tc->originalTargetTriple(); cmd.addArg("-DCMAKE_C_COMPILER_TARGET:STRING=" + targetTriple); cmd.addArg("-DCMAKE_CXX_COMPILER_TARGET:STRING=" + targetTriple); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp index e1330280f74..e2c3e963f6c 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp @@ -335,7 +335,7 @@ void CMakeBuildStep::setupOutputFormatter(Utils::OutputFormatter *formatter) formatter->addLineParser(progressParser); cmakeParser->setSourceDirectory(project()->projectDirectory()); formatter->addLineParsers({cmakeParser, new GnuMakeParser}); - ToolChain *tc = ToolChainKitAspect::cxxToolChain(kit()); + Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit()); OutputTaskParser *xcodeBuildParser = nullptr; if (tc && tc->targetAbi().os() == Abi::DarwinOS) { xcodeBuildParser = new XcodebuildParser; diff --git a/src/plugins/cmakeprojectmanager/cmakekitaspect.cpp b/src/plugins/cmakeprojectmanager/cmakekitaspect.cpp index a39b9d70123..bca89be9b18 100644 --- a/src/plugins/cmakeprojectmanager/cmakekitaspect.cpp +++ b/src/plugins/cmakeprojectmanager/cmakekitaspect.cpp @@ -681,7 +681,7 @@ QVariant CMakeGeneratorKitAspectFactory::defaultValue(const Kit *k) const if (tool->filePath().osType() == OsTypeWindows) { // *sigh* Windows with its zoo of incompatible stuff again... - ToolChain *tc = ToolChainKitAspect::cxxToolChain(k); + Toolchain *tc = ToolChainKitAspect::cxxToolChain(k); if (tc && tc->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID) { it = std::find_if(known.constBegin(), known.constEnd(), @@ -1135,8 +1135,8 @@ Tasks CMakeConfigurationKitAspectFactory::validate(const Kit *k) const return Tasks(); const QtSupport::QtVersion *const version = QtSupport::QtKitAspect::qtVersion(k); - const ToolChain *const tcC = ToolChainKitAspect::cToolChain(k); - const ToolChain *const tcCxx = ToolChainKitAspect::cxxToolChain(k); + const Toolchain *const tcC = ToolChainKitAspect::cToolChain(k); + const Toolchain *const tcCxx = ToolChainKitAspect::cxxToolChain(k); const CMakeConfig config = CMakeConfigurationKitAspect::configuration(k); const bool isQt4 = version && version->qtVersion() < QVersionNumber(5, 0, 0); diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index b8748bc6f98..de05b51d2a0 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -585,7 +585,7 @@ void updateConfigWithDirectoryData(CMakeConfig &config, const std::unique_ptrqt.qt->qmakeFilePath().toString().toUtf8()); } -ToolChain *findExternalToolchain(const QString &presetArchitecture, const QString &presetToolset) +Toolchain *findExternalToolchain(const QString &presetArchitecture, const QString &presetToolset) { // A compiler path example. Note that the compiler version is not the same version from MsvcToolChain // ... \MSVC\14.29.30133\bin\Hostx64\x64\cl.exe @@ -601,16 +601,16 @@ ToolChain *findExternalToolchain(const QString &presetArchitecture, const QStrin // "strategy": "external" // } - auto msvcToolchains = ToolChainManager::toolchains([](const ToolChain *tc) { + auto msvcToolchains = ToolChainManager::toolchains([](const Toolchain *tc) { return tc->typeId() == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID; }); - const QSet msvcFlavors = Utils::toSet(Utils::transform(msvcToolchains, [](const ToolChain *tc) { + const QSet msvcFlavors = Utils::toSet(Utils::transform(msvcToolchains, [](const Toolchain *tc) { return tc->targetAbi().osFlavor(); })); return ToolChainManager::toolChain( - [presetArchitecture, presetToolset, msvcFlavors](const ToolChain *tc) -> bool { + [presetArchitecture, presetToolset, msvcFlavors](const Toolchain *tc) -> bool { if (tc->typeId() != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) return false; @@ -732,7 +732,7 @@ QList CMakeProjectImporter::examineDirectory(const FilePath &importPath, data->toolset = configurePreset.toolset.value().value.value(); if (architectureExternalStrategy && toolsetExternalStrategy) { - const ToolChain *tc + const Toolchain *tc = findExternalToolchain(configurePreset.architecture->value.value_or(QString()), configurePreset.toolset->value.value_or(QString())); if (tc) @@ -937,7 +937,7 @@ bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const if (!Utils::contains(allLanguages, [&tcd](const Id &language) { return language == tcd.language; })) continue; - ToolChain *tc = ToolChainKitAspect::toolChain(k, tcd.language); + Toolchain *tc = ToolChainKitAspect::toolChain(k, tcd.language); if ((!tc || !tc->matchesCompilerCommand(tcd.compilerPath))) { return false; } @@ -950,7 +950,7 @@ bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const if (!Utils::contains(allLanguages, [&tcd](const Id &language) { return language == tcd.language; })) continue; - ToolChain *tc = ToolChainKitAspect::toolChain(k, tcd.language); + Toolchain *tc = ToolChainKitAspect::toolChain(k, tcd.language); if (tc && tc->matchesCompilerCommand(tcd.compilerPath)) { return false; } @@ -1000,7 +1000,7 @@ Kit *CMakeProjectImporter::createKit(void *directoryData) const QTC_ASSERT(!tcd.tcs.isEmpty(), continue); if (tcd.areTemporary) { - for (ToolChain *tc : tcd.tcs) + for (Toolchain *tc : tcd.tcs) addTemporaryData(ToolChainKitAspect::id(), tc->id(), k); } diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp index 99d0e89ae17..f1cda0f9411 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp @@ -75,9 +75,9 @@ Utils::Id getCompilerId(QString compilerName) return ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID; } -ToolChain *toolchainFromCompilerId(const Utils::Id &compilerId, const Utils::Id &language) +Toolchain *toolchainFromCompilerId(const Utils::Id &compilerId, const Utils::Id &language) { - return ToolChainManager::toolChain([&compilerId, &language](const ToolChain *tc) { + return ToolChainManager::toolChain([&compilerId, &language](const Toolchain *tc) { if (!tc->isValid() || tc->language() != language) return false; return tc->typeId() == compilerId; @@ -105,14 +105,14 @@ QString compilerPath(QString pathFlag) return QDir::fromNativeSeparators(pathFlag); } -ToolChain *toolchainFromFlags(const Kit *kit, const QStringList &flags, const Utils::Id &language) +Toolchain *toolchainFromFlags(const Kit *kit, const QStringList &flags, const Utils::Id &language) { if (flags.empty()) return ToolChainKitAspect::toolChain(kit, language); // Try exact compiler match. const Utils::FilePath compiler = Utils::FilePath::fromUserInput(compilerPath(flags.front())); - ToolChain *toolchain = ToolChainManager::toolChain([&compiler, &language](const ToolChain *tc) { + Toolchain *toolchain = ToolChainManager::toolChain([&compiler, &language](const Toolchain *tc) { return tc->isValid() && tc->language() == language && tc->compilerCommand() == compiler; }); if (toolchain) @@ -136,7 +136,7 @@ ToolChain *toolchainFromFlags(const Kit *kit, const QStringList &flags, const Ut return toolchain; } -void addDriverModeFlagIfNeeded(const ToolChain *toolchain, +void addDriverModeFlagIfNeeded(const Toolchain *toolchain, QStringList &flags, const QStringList &originalFlags) { diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp index 96b7e423d42..24882d045f1 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp @@ -39,7 +39,7 @@ void CompilationDatabaseTests::initTestCase() if (allKits.empty()) QSKIP("This test requires at least one kit to be present."); - ToolChain *toolchain = ToolChainManager::toolChain([](const ToolChain *tc) { + Toolchain *toolchain = ToolChainManager::toolChain([](const Toolchain *tc) { return tc->isValid() && tc->language() == ProjectExplorer::Constants::CXX_LANGUAGE_ID; }); if (!toolchain) diff --git a/src/plugins/conan/conaninstallstep.cpp b/src/plugins/conan/conaninstallstep.cpp index 0a1182eced2..ae28bfb1b47 100644 --- a/src/plugins/conan/conaninstallstep.cpp +++ b/src/plugins/conan/conaninstallstep.cpp @@ -104,7 +104,7 @@ ConanInstallStep::ConanInstallStep(BuildStepList *bsl, Id id) }); setSummaryUpdater([this]() -> QString { - QList tcList = ToolChainKitAspect::toolChains(target()->kit()); + QList tcList = ToolChainKitAspect::toolChains(target()->kit()); if (tcList.isEmpty()) return "" + ToolChainKitAspect::msgNoToolChainInTarget() + ""; ProcessParameters param; @@ -124,7 +124,7 @@ bool ConanInstallStep::init() if (!AbstractProcessStep::init()) return false; - const QList tcList = ToolChainKitAspect::toolChains(target()->kit()); + const QList tcList = ToolChainKitAspect::toolChains(target()->kit()); if (tcList.isEmpty()) { emit addTask(Task::compilerMissingTask()); emitFaultyConfigurationMessage(); diff --git a/src/plugins/cppeditor/compileroptionsbuilder_test.cpp b/src/plugins/cppeditor/compileroptionsbuilder_test.cpp index 8e142fcc86e..b297b78c5d7 100644 --- a/src/plugins/cppeditor/compileroptionsbuilder_test.cpp +++ b/src/plugins/cppeditor/compileroptionsbuilder_test.cpp @@ -46,7 +46,7 @@ public: tcInfo.isMsvc2015ToolChain = isMsvc2015; tcInfo.extraCodeModelFlags = extraFlags; tcInfo.macroInspectionRunner = [this](const QStringList &) { - return ToolChain::MacroInspectionReport{toolchainMacros, languageVersion}; + return Toolchain::MacroInspectionReport{toolchainMacros, languageVersion}; }; RawProjectPartFlags rppFlags; rppFlags.commandLineFlags = flags; diff --git a/src/plugins/cppeditor/cppmodelmanager.cpp b/src/plugins/cppeditor/cppmodelmanager.cpp index 2aa13841f96..ee94f84ee57 100644 --- a/src/plugins/cppeditor/cppmodelmanager.cpp +++ b/src/plugins/cppeditor/cppmodelmanager.cpp @@ -409,7 +409,7 @@ void CppModelManager::showPreprocessedFile(bool inNextSplit) return; } - const ToolChain * tc = nullptr; + const Toolchain * tc = nullptr; const ProjectFile classifier(filePath, ProjectFile::classify(filePath.toString())); if (classifier.isC()) { tc = ToolChainKitAspect::cToolChain(project->activeTarget()->kit()); @@ -1964,7 +1964,7 @@ void CppModelManager::setupFallbackProjectPart() // TODO: Use different fallback toolchain for different kinds of files? const Kit * const defaultKit = KitManager::isLoaded() ? KitManager::defaultKit() : nullptr; - const ToolChain * const defaultTc = defaultKit + const Toolchain * const defaultTc = defaultKit ? ToolChainKitAspect::cxxToolChain(defaultKit) : nullptr; if (defaultKit && defaultTc) { FilePath sysroot = SysRootKitAspect::sysRoot(defaultKit); @@ -1974,7 +1974,7 @@ void CppModelManager::setupFallbackProjectPart() tcInfo = ToolChainInfo(defaultTc, sysroot, env); const auto macroInspectionWrapper = [runner = tcInfo.macroInspectionRunner]( const QStringList &flags) { - ToolChain::MacroInspectionReport report = runner(flags); + Toolchain::MacroInspectionReport report = runner(flags); report.languageVersion = LanguageVersion::LatestCxx; return report; }; diff --git a/src/plugins/cppeditor/projectinfo_test.cpp b/src/plugins/cppeditor/projectinfo_test.cpp index 4fb40cc44ab..5e6f921d55a 100644 --- a/src/plugins/cppeditor/projectinfo_test.cpp +++ b/src/plugins/cppeditor/projectinfo_test.cpp @@ -69,7 +69,7 @@ public: // Create project part for C tcInfo.macroInspectionRunner = [](const QStringList &) { - return ToolChain::MacroInspectionReport{{}, Utils::LanguageVersion::C11}; + return Toolchain::MacroInspectionReport{{}, Utils::LanguageVersion::C11}; }; const ProjectPart::ConstPtr cprojectpart = ProjectPart::create({}, {}, {}, {}, {}, {}, {}, tcInfo); @@ -77,7 +77,7 @@ public: // Create project part for CXX tcInfo.macroInspectionRunner = [](const QStringList &) { - return ToolChain::MacroInspectionReport{{}, Utils::LanguageVersion::CXX98}; + return Toolchain::MacroInspectionReport{{}, Utils::LanguageVersion::CXX98}; }; const ProjectPart::ConstPtr cxxprojectpart = ProjectPart::create({}, {}, {}, {}, {}, {}, {}, tcInfo); @@ -330,10 +330,10 @@ void ProjectPartChooserTest::testDoNotIndicateFromDependencies() } namespace { -class TestToolchain : public ToolChain +class TestToolchain : public Toolchain { public: - TestToolchain() : ToolChain("dummy") {} + TestToolchain() : Toolchain("dummy") {} private: MacroInspectionRunner createMacroInspectionRunner() const override { return {}; } diff --git a/src/plugins/cppeditor/projectpart.cpp b/src/plugins/cppeditor/projectpart.cpp index bea37f91ab4..455132db97a 100644 --- a/src/plugins/cppeditor/projectpart.cpp +++ b/src/plugins/cppeditor/projectpart.cpp @@ -96,10 +96,10 @@ static HeaderPaths getHeaderPaths(const RawProjectPart &rpp, return headerPaths; } -static ToolChain::MacroInspectionReport getToolchainMacros( +static Toolchain::MacroInspectionReport getToolchainMacros( const RawProjectPartFlags &flags, const ToolChainInfo &tcInfo, Utils::Language language) { - ToolChain::MacroInspectionReport report; + Toolchain::MacroInspectionReport report; if (tcInfo.macroInspectionRunner) { report = tcInfo.macroInspectionRunner(flags.commandLineFlags); } else if (language == Utils::Language::C) { // No compiler set in kit. diff --git a/src/plugins/cppeditor/projectpart.h b/src/plugins/cppeditor/projectpart.h index f49296d0877..a8e6bdb5d1b 100644 --- a/src/plugins/cppeditor/projectpart.h +++ b/src/plugins/cppeditor/projectpart.h @@ -110,7 +110,7 @@ private: CPlusPlus::LanguageFeatures deriveLanguageFeatures() const; - const ProjectExplorer::ToolChain::MacroInspectionReport m_macroReport; + const ProjectExplorer::Toolchain::MacroInspectionReport m_macroReport; public: // Must come last due to initialization order. diff --git a/src/plugins/docker/kitdetector.cpp b/src/plugins/docker/kitdetector.cpp index b443b3ef5b0..405ea76032b 100644 --- a/src/plugins/docker/kitdetector.cpp +++ b/src/plugins/docker/kitdetector.cpp @@ -46,7 +46,7 @@ public: private: QtVersions autoDetectQtVersions() const; - QList autoDetectToolChains(); + QList autoDetectToolChains(); void autoDetectPython(); QList autoDetectCMake(); void autoDetectDebugger(); @@ -107,7 +107,7 @@ void KitDetectorPrivate::undoAutoDetect() const emit q->logOutput('\n' + ProjectExplorer::Tr::tr("Removing toolchain entries...")); const Toolchains toolchains = ToolChainManager::toolchains(); - for (ToolChain *toolChain : toolchains) { + for (Toolchain *toolChain : toolchains) { if (toolChain && toolChain->detectionSource() == m_sharedId) { emit q->logOutput(ProjectExplorer::Tr::tr("Removed \"%1\"").arg(toolChain->displayName())); ToolChainManager::deregisterToolChain(toolChain); @@ -164,7 +164,7 @@ void KitDetectorPrivate::listAutoDetected() const } emit q->logOutput('\n' + ProjectExplorer::Tr::tr("Toolchains:")); - for (ToolChain *toolChain : ToolChainManager::toolchains()) { + for (Toolchain *toolChain : ToolChainManager::toolchains()) { if (toolChain->detectionSource() == m_sharedId) emit q->logOutput(toolChain->displayName()); } @@ -259,7 +259,7 @@ Toolchains KitDetectorPrivate::autoDetectToolChains() emit q->logOutput(ProjectExplorer::Tr::tr("Searching toolchains of type %1").arg(factory->displayName())); const ToolchainDetector detector(alreadyKnown, m_device, m_searchPaths); const Toolchains newToolChains = factory->autoDetect(detector); - for (ToolChain *toolChain : newToolChains) { + for (Toolchain *toolChain : newToolChains) { emit q->logOutput(ProjectExplorer::Tr::tr("Found \"%1\"").arg(toolChain->compilerCommand().toUserOutput())); toolChain->setDetectionSource(m_sharedId); ToolChainManager::registerToolChain(toolChain); @@ -359,11 +359,11 @@ void KitDetectorPrivate::autoDetect() QtSupport::QtKitAspect::setQtVersion(k, qt); } Toolchains toolchainsToSet; - toolchainsToSet = ToolChainManager::toolchains([qt, this](const ToolChain *tc) { + toolchainsToSet = ToolChainManager::toolchains([qt, this](const Toolchain *tc) { return tc->detectionSource() == m_sharedId && (!qt || qt->qtAbis().contains(tc->targetAbi())); }); - for (ToolChain *toolChain : toolchainsToSet) + for (Toolchain *toolChain : toolchainsToSet) ToolChainKitAspect::setToolChain(k, toolChain); if (cmakeId.isValid()) diff --git a/src/plugins/incredibuild/makecommandbuilder.cpp b/src/plugins/incredibuild/makecommandbuilder.cpp index 0d5caa548ec..9e16c7fe1fd 100644 --- a/src/plugins/incredibuild/makecommandbuilder.cpp +++ b/src/plugins/incredibuild/makecommandbuilder.cpp @@ -37,7 +37,7 @@ FilePath MakeCommandBuilder::defaultCommand() const { if (BuildConfiguration *buildConfig = buildStep()->buildConfiguration()) { if (Target *target = buildStep()->target()) { - if (ToolChain *toolChain = ToolChainKitAspect::cxxToolChain(target->kit())) + if (Toolchain *toolChain = ToolChainKitAspect::cxxToolChain(target->kit())) return toolChain->makeCommand(buildConfig->environment()); } } diff --git a/src/plugins/ios/iosbuildstep.cpp b/src/plugins/ios/iosbuildstep.cpp index b6612336058..02ab577216c 100644 --- a/src/plugins/ios/iosbuildstep.cpp +++ b/src/plugins/ios/iosbuildstep.cpp @@ -148,7 +148,7 @@ bool IosBuildStep::init() if (!AbstractProcessStep::init()) return false; - ToolChain *tc = ToolChainKitAspect::cxxToolChain(kit()); + Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit()); if (!tc) { emit addTask(Task::compilerMissingTask()); emitFaultyConfigurationMessage(); @@ -195,7 +195,7 @@ QStringList IosBuildStep::defaultArguments() const { QStringList res; Kit *kit = target()->kit(); - ToolChain *tc = ToolChainKitAspect::cxxToolChain(kit); + Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit); switch (buildConfiguration()->buildType()) { case BuildConfiguration::Debug : res << "-configuration" << "Debug"; diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp index b7ec36f883f..b59aae15f84 100644 --- a/src/plugins/ios/iosconfigurations.cpp +++ b/src/plugins/ios/iosconfigurations.cpp @@ -101,7 +101,7 @@ static bool isSimulatorDeviceId(const Id &id) static QList clangToolChains(const Toolchains &toolChains) { QList clangToolChains; - for (ToolChain *toolChain : toolChains) + for (Toolchain *toolChain : toolChains) if (toolChain->typeId() == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID) clangToolChains.append(static_cast(toolChain)); return clangToolChains; @@ -593,8 +593,8 @@ Toolchains IosToolchainFactory::autoDetect(const ToolchainDetector &detector) co if (!toolChain) { toolChain = new GccToolChain(ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID, GccToolChain::Clang); - toolChain->setPriority(ToolChain::PriorityHigh); - toolChain->setDetection(ToolChain::AutoDetection); + toolChain->setPriority(Toolchain::PriorityHigh); + toolChain->setDetection(Toolchain::AutoDetection); toolChain->setLanguage(l); toolChain->setDisplayName(target.name); toolChain->setPlatformCodeGenFlags(target.backendFlags); diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp index 26f6b80a6c5..619efa18902 100644 --- a/src/plugins/mcusupport/mcupackage.cpp +++ b/src/plugins/mcusupport/mcupackage.cpp @@ -364,9 +364,9 @@ bool McuToolChainPackage::isDesktopToolchain() const || m_type == ToolChainType::MinGW; } -ToolChain *McuToolChainPackage::msvcToolChain(Id language) +Toolchain *McuToolChainPackage::msvcToolChain(Id language) { - ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) { + Toolchain *toolChain = ToolChainManager::toolChain([language](const Toolchain *t) { const Abi abi = t->targetAbi(); return abi.osFlavor() == Abi::WindowsMsvc2019Flavor && abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64 @@ -376,9 +376,9 @@ ToolChain *McuToolChainPackage::msvcToolChain(Id language) return toolChain; } -ToolChain *McuToolChainPackage::gccToolChain(Id language) +Toolchain *McuToolChainPackage::gccToolChain(Id language) { - ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) { + Toolchain *toolChain = ToolChainManager::toolChain([language](const Toolchain *t) { const Abi abi = t->targetAbi(); return abi.os() != Abi::WindowsOS && abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64 && t->language() == language; @@ -386,9 +386,9 @@ ToolChain *McuToolChainPackage::gccToolChain(Id language) return toolChain; } -static ToolChain *mingwToolChain(const FilePath &path, Id language) +static Toolchain *mingwToolChain(const FilePath &path, Id language) { - ToolChain *toolChain = ToolChainManager::toolChain([&path, language](const ToolChain *t) { + Toolchain *toolChain = ToolChainManager::toolChain([&path, language](const Toolchain *t) { // find a MinGW toolchain having the same path from registered toolchains const Abi abi = t->targetAbi(); return t->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID @@ -398,7 +398,7 @@ static ToolChain *mingwToolChain(const FilePath &path, Id language) if (!toolChain) { // if there's no MinGW toolchain having the same path, // a proper MinGW would be selected from the registered toolchains. - toolChain = ToolChainManager::toolChain([language](const ToolChain *t) { + toolChain = ToolChainManager::toolChain([language](const Toolchain *t) { const Abi abi = t->targetAbi(); return t->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID && abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64 @@ -408,9 +408,9 @@ static ToolChain *mingwToolChain(const FilePath &path, Id language) return toolChain; } -static ToolChain *armGccToolChain(const FilePath &path, Id language) +static Toolchain *armGccToolChain(const FilePath &path, Id language) { - ToolChain *toolChain = ToolChainManager::toolChain([&path, language](const ToolChain *t) { + Toolchain *toolChain = ToolChainManager::toolChain([&path, language](const Toolchain *t) { return t->compilerCommand() == path && t->language() == language; }); if (!toolChain) { @@ -421,10 +421,10 @@ static ToolChain *armGccToolChain(const FilePath &path, Id language) == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID; }); if (gccFactory) { - const QList detected = gccFactory->detectForImport({path, language}); + const QList detected = gccFactory->detectForImport({path, language}); if (!detected.isEmpty()) { toolChain = detected.first(); - toolChain->setDetection(ToolChain::ManualDetection); + toolChain->setDetection(Toolchain::ManualDetection); toolChain->setDisplayName("Arm GCC"); ToolChainManager::registerToolChain(toolChain); } @@ -434,9 +434,9 @@ static ToolChain *armGccToolChain(const FilePath &path, Id language) return toolChain; } -static ToolChain *iarToolChain(const FilePath &path, Id language) +static Toolchain *iarToolChain(const FilePath &path, Id language) { - ToolChain *toolChain = ToolChainManager::toolChain([language](const ToolChain *t) { + Toolchain *toolChain = ToolChainManager::toolChain([language](const Toolchain *t) { return t->typeId() == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID && t->language() == language; }); @@ -455,7 +455,7 @@ static ToolChain *iarToolChain(const FilePath &path, Id language) for (auto tc : detected) { if (tc->language() == language) { toolChain = tc; - toolChain->setDetection(ToolChain::ManualDetection); + toolChain->setDetection(Toolchain::ManualDetection); toolChain->setDisplayName("IAREW"); ToolChainManager::registerToolChain(toolChain); } @@ -466,7 +466,7 @@ static ToolChain *iarToolChain(const FilePath &path, Id language) return toolChain; } -ToolChain *McuToolChainPackage::toolChain(Id language) const +Toolchain *McuToolChainPackage::toolChain(Id language) const { switch (m_type) { case ToolChainType::MSVC: diff --git a/src/plugins/mcusupport/mcupackage.h b/src/plugins/mcusupport/mcupackage.h index 7008b2c499d..eab3b34c91f 100644 --- a/src/plugins/mcusupport/mcupackage.h +++ b/src/plugins/mcusupport/mcupackage.h @@ -13,7 +13,7 @@ #include namespace ProjectExplorer { -class ToolChain; +class Toolchain; } namespace Utils { @@ -116,12 +116,12 @@ public: ToolChainType toolchainType() const; bool isDesktopToolchain() const; - ProjectExplorer::ToolChain *toolChain(Utils::Id language) const; + ProjectExplorer::Toolchain *toolChain(Utils::Id language) const; QString toolChainName() const; QVariant debuggerId() const; - static ProjectExplorer::ToolChain *msvcToolChain(Utils::Id language); - static ProjectExplorer::ToolChain *gccToolChain(Utils::Id language); + static ProjectExplorer::Toolchain *msvcToolChain(Utils::Id language); + static ProjectExplorer::Toolchain *gccToolChain(Utils::Id language); private: const ToolChainType m_type; diff --git a/src/plugins/mcusupport/mcusupportoptions.h b/src/plugins/mcusupport/mcusupportoptions.h index 5823bed4529..d8a5c3fdbf4 100644 --- a/src/plugins/mcusupport/mcusupportoptions.h +++ b/src/plugins/mcusupport/mcusupportoptions.h @@ -21,7 +21,7 @@ class InfoLabel; namespace ProjectExplorer { class Kit; -class ToolChain; +class Toolchain; } // namespace ProjectExplorer namespace McuSupport { diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index a3eb731ea2a..ff7d20b3f82 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -184,7 +184,7 @@ McuToolChainPackagePtr createUnsupportedToolChainPackage(const SettingsHandler:: McuToolChainPackagePtr createMsvcToolChainPackage(const SettingsHandler::Ptr &settingsHandler, const QStringList &versions) { - ToolChain *toolChain = McuToolChainPackage::msvcToolChain( + Toolchain *toolChain = McuToolChainPackage::msvcToolChain( ProjectExplorer::Constants::CXX_LANGUAGE_ID); const FilePath detectionPath = FilePath("cl").withExecutableSuffix(); @@ -209,7 +209,7 @@ McuToolChainPackagePtr createMsvcToolChainPackage(const SettingsHandler::Ptr &se McuToolChainPackagePtr createGccToolChainPackage(const SettingsHandler::Ptr &settingsHandler, const QStringList &versions) { - ToolChain *toolChain = McuToolChainPackage::gccToolChain( + Toolchain *toolChain = McuToolChainPackage::gccToolChain( ProjectExplorer::Constants::CXX_LANGUAGE_ID); const FilePath detectionPath = FilePath("bin/g++").withExecutableSuffix(); @@ -328,8 +328,8 @@ McuToolChainPackagePtr createIarToolChainPackage(const SettingsHandler::Ptr &set if (qtcEnvironmentVariableIsSet(envVar)) defaultPath = FilePath::fromUserInput(qtcEnvironmentVariable(envVar)); else { - const ProjectExplorer::ToolChain *tc = ProjectExplorer::ToolChainManager::toolChain( - [](const ProjectExplorer::ToolChain *t) { + const ProjectExplorer::Toolchain *tc = ProjectExplorer::ToolChainManager::toolChain( + [](const ProjectExplorer::Toolchain *t) { return t->typeId() == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID; }); if (tc) { diff --git a/src/plugins/mcusupport/mcutarget.h b/src/plugins/mcusupport/mcutarget.h index ce715c8c6f7..0d87f739ff5 100644 --- a/src/plugins/mcusupport/mcutarget.h +++ b/src/plugins/mcusupport/mcutarget.h @@ -9,7 +9,7 @@ #include namespace ProjectExplorer { -class ToolChain; +class Toolchain; } namespace Utils { diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index 379395a2933..ea16af2cd96 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -70,7 +70,7 @@ using Legacy::Constants::TOOLCHAIN_FILE_CMAKE_VARIABLE; using CMakeProjectManager::CMakeConfigurationKitAspect; using ProjectExplorer::Kit; using ProjectExplorer::KitManager; -using ProjectExplorer::ToolChain; +using ProjectExplorer::Toolchain; using ProjectExplorer::ToolChainManager; using testing::_; @@ -214,7 +214,7 @@ void verifyIarToolchain(const McuToolChainPackagePtr &iarToolchainPackage) { ProjectExplorer::ToolchainFactory toolchainFactory; Id iarId{BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID}; - ToolChain *iarToolchain{ProjectExplorer::ToolchainFactory::createToolChain(iarId)}; + Toolchain *iarToolchain{ProjectExplorer::ToolchainFactory::createToolChain(iarId)}; iarToolchain->setLanguage(cxxLanguageId); ToolChainManager::registerToolChain(iarToolchain); @@ -229,7 +229,7 @@ void verifyIarToolchain(const McuToolChainPackagePtr &iarToolchainPackage) iarToolchain = iarToolchainPackage->toolChain(cxxLanguageId); QVERIFY(iarToolchain != nullptr); QCOMPARE(iarToolchain->displayName(), "IAREW"); - QCOMPARE(iarToolchain->detection(), ToolChain::UninitializedDetection); + QCOMPARE(iarToolchain->detection(), Toolchain::UninitializedDetection); } void verifyArmGccToolchain(const McuToolChainPackagePtr &armGccPackage, const QStringList &versions) @@ -238,7 +238,7 @@ void verifyArmGccToolchain(const McuToolChainPackagePtr &armGccPackage, const QS ProjectExplorer::ToolchainFactory toolchainFactory; Id armGccId{ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID}; - ToolChain *armToolchain{ProjectExplorer::ToolchainFactory::createToolChain(armGccId)}; + Toolchain *armToolchain{ProjectExplorer::ToolchainFactory::createToolChain(armGccId)}; armToolchain->setLanguage(cxxLanguageId); ToolChainManager::registerToolChain(armToolchain); diff --git a/src/plugins/mesonprojectmanager/mesonprojectparser.cpp b/src/plugins/mesonprojectmanager/mesonprojectparser.cpp index 5fb39a5f845..9c34a3714de 100644 --- a/src/plugins/mesonprojectmanager/mesonprojectparser.cpp +++ b/src/plugins/mesonprojectmanager/mesonprojectparser.cpp @@ -254,8 +254,8 @@ void MesonProjectParser::update(const QFuture RawProjectPart MesonProjectParser::buildRawPart( const Target &target, const Target::SourceGroup &sources, - const ToolChain *cxxToolChain, - const ToolChain *cToolChain) + const Toolchain *cxxToolChain, + const Toolchain *cToolChain) { RawProjectPart part; part.setDisplayName(target.name); @@ -274,7 +274,7 @@ RawProjectPart MesonProjectParser::buildRawPart( } RawProjectParts MesonProjectParser::buildProjectParts( - const ToolChain *cxxToolChain, const ToolChain *cToolChain) + const Toolchain *cxxToolChain, const Toolchain *cToolChain) { RawProjectParts parts; for_each_source_group(m_parserResult.targets, diff --git a/src/plugins/mesonprojectmanager/mesonprojectparser.h b/src/plugins/mesonprojectmanager/mesonprojectparser.h index e21fe5ec476..415a9d660b2 100644 --- a/src/plugins/mesonprojectmanager/mesonprojectparser.h +++ b/src/plugins/mesonprojectmanager/mesonprojectparser.h @@ -57,8 +57,8 @@ public: QList appsTargets() const; ProjectExplorer::RawProjectParts buildProjectParts( - const ProjectExplorer::ToolChain *cxxToolChain, - const ProjectExplorer::ToolChain *cToolChain); + const ProjectExplorer::Toolchain *cxxToolChain, + const ProjectExplorer::Toolchain *cToolChain); void setEnvironment(const Utils::Environment &environment) { m_env = environment; } @@ -78,8 +78,8 @@ private: void update(const QFuture &data); ProjectExplorer::RawProjectPart buildRawPart(const Target &target, const Target::SourceGroup &sources, - const ProjectExplorer::ToolChain *cxxToolChain, - const ProjectExplorer::ToolChain *cToolChain); + const ProjectExplorer::Toolchain *cxxToolChain, + const ProjectExplorer::Toolchain *cToolChain); MesonOutputParser m_outputParser; Utils::Environment m_env; diff --git a/src/plugins/nim/project/nimtoolchain.cpp b/src/plugins/nim/project/nimtoolchain.cpp index 05efffbb9df..aa1a87a48d8 100644 --- a/src/plugins/nim/project/nimtoolchain.cpp +++ b/src/plugins/nim/project/nimtoolchain.cpp @@ -32,7 +32,7 @@ NimToolChain::NimToolChain() {} NimToolChain::NimToolChain(Utils::Id typeId) - : ToolChain(typeId) + : Toolchain(typeId) , m_version(std::make_tuple(-1,-1,-1)) { setLanguage(Constants::C_NIMLANGUAGE_ID); @@ -41,9 +41,9 @@ NimToolChain::NimToolChain(Utils::Id typeId) setCompilerCommandKey("Nim.NimToolChain.CompilerCommand"); } -ToolChain::MacroInspectionRunner NimToolChain::createMacroInspectionRunner() const +Toolchain::MacroInspectionRunner NimToolChain::createMacroInspectionRunner() const { - return ToolChain::MacroInspectionRunner(); + return Toolchain::MacroInspectionRunner(); } LanguageExtensions NimToolChain::languageExtensions(const QStringList &) const @@ -56,10 +56,10 @@ WarningFlags NimToolChain::warningFlags(const QStringList &) const return WarningFlags::NoWarnings; } -ToolChain::BuiltInHeaderPathsRunner NimToolChain::createBuiltInHeaderPathsRunner( +Toolchain::BuiltInHeaderPathsRunner NimToolChain::createBuiltInHeaderPathsRunner( const Environment &) const { - return ToolChain::BuiltInHeaderPathsRunner(); + return Toolchain::BuiltInHeaderPathsRunner(); } void NimToolChain::addToEnvironment(Environment &env) const @@ -91,7 +91,7 @@ QString NimToolChain::compilerVersion() const void NimToolChain::fromMap(const Store &data) { - ToolChain::fromMap(data); + Toolchain::fromMap(data); if (hasError()) return; parseVersion(compilerCommand(), m_version); @@ -220,7 +220,7 @@ Toolchains NimToolchainFactory::autoDetect(const ToolchainDetector &detector) co if (compilerPath.isEmpty()) return result; - result = Utils::filtered(detector.alreadyKnown, [compilerPath](ToolChain *tc) { + result = Utils::filtered(detector.alreadyKnown, [compilerPath](Toolchain *tc) { return tc->typeId() == Constants::C_NIMTOOLCHAIN_TYPEID && tc->compilerCommand() == compilerPath; }); @@ -229,7 +229,7 @@ Toolchains NimToolchainFactory::autoDetect(const ToolchainDetector &detector) co return result; auto tc = new NimToolChain; - tc->setDetection(ToolChain::AutoDetection); + tc->setDetection(Toolchain::AutoDetection); tc->setCompilerCommand(compilerPath); result.append(tc); return result; @@ -240,7 +240,7 @@ Toolchains NimToolchainFactory::detectForImport(const ToolChainDescription &tcd) Toolchains result; if (tcd.language == Constants::C_NIMLANGUAGE_ID) { auto tc = new NimToolChain; - tc->setDetection(ToolChain::ManualDetection); // FIXME: sure? + tc->setDetection(Toolchain::ManualDetection); // FIXME: sure? tc->setCompilerCommand(tcd.compilerPath); result.append(tc); } diff --git a/src/plugins/nim/project/nimtoolchain.h b/src/plugins/nim/project/nimtoolchain.h index 992c2084f10..b016676412d 100644 --- a/src/plugins/nim/project/nimtoolchain.h +++ b/src/plugins/nim/project/nimtoolchain.h @@ -8,7 +8,7 @@ namespace Nim { -class NimToolChain : public ProjectExplorer::ToolChain +class NimToolChain : public ProjectExplorer::Toolchain { public: NimToolChain(); diff --git a/src/plugins/projectexplorer/customtoolchain.cpp b/src/plugins/projectexplorer/customtoolchain.cpp index 8300fcf49f7..44e97f5281b 100644 --- a/src/plugins/projectexplorer/customtoolchain.cpp +++ b/src/plugins/projectexplorer/customtoolchain.cpp @@ -44,11 +44,11 @@ const char outputParserKeyC[] = "ProjectExplorer.CustomToolChain.OutputParser"; // CustomToolChain // -------------------------------------------------------------------------- -class CustomToolChain : public ToolChain +class CustomToolChain : public Toolchain { public: CustomToolChain() - : ToolChain(Constants::CUSTOM_TOOLCHAIN_TYPEID) + : Toolchain(Constants::CUSTOM_TOOLCHAIN_TYPEID) , m_outputParserId(GccParser::id()) { setTypeDisplayName(Tr::tr("Custom")); @@ -82,7 +82,7 @@ public: std::unique_ptr createConfigurationWidget() override; - bool operator ==(const ToolChain &) const override; + bool operator ==(const Toolchain &) const override; void setMakeCommand(const FilePath &); FilePath makeCommand(const Environment &environment) const override; @@ -123,7 +123,7 @@ bool CustomToolChain::isValid() const return true; } -ToolChain::MacroInspectionRunner CustomToolChain::createMacroInspectionRunner() const +Toolchain::MacroInspectionRunner CustomToolChain::createMacroInspectionRunner() const { const Macros theMacros = m_predefinedMacros; const Id lang = language(); @@ -138,7 +138,7 @@ ToolChain::MacroInspectionRunner CustomToolChain::createMacroInspectionRunner() macros.append({cxxFlag.mid(2).trimmed().toUtf8(), MacroType::Undefine}); } - return MacroInspectionReport{macros, ToolChain::languageVersion(lang, macros)}; + return MacroInspectionReport{macros, Toolchain::languageVersion(lang, macros)}; }; } @@ -166,7 +166,7 @@ void CustomToolChain::setPredefinedMacros(const Macros ¯os) toolChainUpdated(); } -ToolChain::BuiltInHeaderPathsRunner CustomToolChain::createBuiltInHeaderPathsRunner( +Toolchain::BuiltInHeaderPathsRunner CustomToolChain::createBuiltInHeaderPathsRunner( const Environment &) const { const HeaderPaths builtInHeaderPaths = m_builtInHeaderPaths; @@ -273,7 +273,7 @@ QString CustomToolChain::mkspecs() const void CustomToolChain::toMap(Store &data) const { - ToolChain::toMap(data); + Toolchain::toMap(data); data.insert(makeCommandKeyC, m_makeCommand.toString()); QStringList macros = Utils::transform(m_predefinedMacros, [](const Macro &m) { return QString::fromUtf8(m.toByteArray()); }); data.insert(predefinedMacrosKeyC, macros); @@ -285,7 +285,7 @@ void CustomToolChain::toMap(Store &data) const void CustomToolChain::fromMap(const Store &data) { - ToolChain::fromMap(data); + Toolchain::fromMap(data); if (hasError()) return; @@ -298,9 +298,9 @@ void CustomToolChain::fromMap(const Store &data) setOutputParserId(Id::fromSetting(data.value(outputParserKeyC))); } -bool CustomToolChain::operator ==(const ToolChain &other) const +bool CustomToolChain::operator ==(const Toolchain &other) const { - if (!ToolChain::operator ==(other)) + if (!Toolchain::operator ==(other)) return false; auto customTc = static_cast(&other); diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 5ffb9314c43..1989e322143 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -363,7 +363,7 @@ static Id idForSubType(GccToolChain::SubType subType) } GccToolChain::GccToolChain(Id typeId, SubType subType) - : ToolChain(typeId.isValid() ? typeId : idForSubType(subType)), m_subType(subType) + : Toolchain(typeId.isValid() ? typeId : idForSubType(subType)), m_subType(subType) { setTypeDisplayName(Tr::tr("GCC")); setTargetAbiKey(targetAbiKeyC); @@ -437,7 +437,7 @@ LanguageExtensions GccToolChain::defaultLanguageExtensions() const static const Toolchains mingwToolChains() { - return ToolChainManager::toolchains([](const ToolChain *tc) -> bool { + return ToolChainManager::toolchains([](const Toolchain *tc) -> bool { return tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID; }); } @@ -447,7 +447,7 @@ static const GccToolChain *mingwToolChainFromId(const QByteArray &id) if (id.isEmpty()) return nullptr; - for (const ToolChain *tc : mingwToolChains()) { + for (const Toolchain *tc : mingwToolChains()) { if (tc->id() == id) return static_cast(tc); } @@ -546,7 +546,7 @@ static QStringList filteredFlags(const QStringList &allFlags, bool considerSysro return filtered; } -ToolChain::MacroInspectionRunner GccToolChain::createMacroInspectionRunner() const +Toolchain::MacroInspectionRunner GccToolChain::createMacroInspectionRunner() const { // Using a clean environment breaks ccache/distcc/etc. Environment env = compilerCommand().deviceEnvironment(); @@ -702,7 +702,7 @@ WarningFlags GccToolChain::warningFlags(const QStringList &cflags) const FilePaths GccToolChain::includedFiles(const QStringList &flags, const FilePath &directoryPath) const { - return ToolChain::includedFiles("-include", flags, directoryPath, PossiblyConcatenatedFlag::No); + return Toolchain::includedFiles("-include", flags, directoryPath, PossiblyConcatenatedFlag::No); } static QStringList gccPrepareArguments(const QStringList &flags, @@ -770,7 +770,7 @@ HeaderPaths GccToolChain::builtInHeaderPaths(const Environment &env, return paths; } -ToolChain::BuiltInHeaderPathsRunner GccToolChain::createBuiltInHeaderPathsRunner( +Toolchain::BuiltInHeaderPathsRunner GccToolChain::createBuiltInHeaderPathsRunner( const Environment &env) const { // Using a clean environment breaks ccache/distcc/etc. @@ -866,7 +866,7 @@ QStringList GccToolChain::suggestedMkspecList() const } if (m_subType == Clang) { - if (const ToolChain * const parentTc = ToolChainManager::findToolChain(m_parentToolChainId)) + if (const Toolchain * const parentTc = ToolChainManager::findToolChain(m_parentToolChainId)) return parentTc->suggestedMkspecList(); const Abi abi = targetAbi(); if (abi.os() == Abi::DarwinOS) @@ -1014,7 +1014,7 @@ QStringList GccToolChain::platformLinkerFlags() const void GccToolChain::toMap(Store &data) const { - ToolChain::toMap(data); + Toolchain::toMap(data); data.insert(compilerPlatformCodeGenFlagsKeyC, m_platformCodeGenFlags); data.insert(compilerPlatformLinkerFlagsKeyC, m_platformLinkerFlags); data.insert(originalTargetTripleKeyC, m_originalTargetTriple); @@ -1028,7 +1028,7 @@ void GccToolChain::toMap(Store &data) const void GccToolChain::fromMap(const Store &data) { - ToolChain::fromMap(data); + Toolchain::fromMap(data); if (hasError()) return; @@ -1051,9 +1051,9 @@ void GccToolChain::fromMap(const Store &data) } } -bool GccToolChain::operator ==(const ToolChain &other) const +bool GccToolChain::operator ==(const Toolchain &other) const { - if (!ToolChain::operator ==(other)) + if (!Toolchain::operator ==(other)) return false; auto gccTc = static_cast(&other); @@ -1254,22 +1254,22 @@ static Utils::FilePaths renesasRl78SearchPathsFromRegistry() return searchPaths; } -static ToolChain *constructRealGccToolchain() +static Toolchain *constructRealGccToolchain() { return new GccToolChain(Constants::GCC_TOOLCHAIN_TYPEID, GccToolChain::RealGcc); } -static ToolChain *constructClangToolchain() +static Toolchain *constructClangToolchain() { return new GccToolChain(Constants::CLANG_TOOLCHAIN_TYPEID, GccToolChain::Clang); } -static ToolChain *constructMinGWToolchain() +static Toolchain *constructMinGWToolchain() { return new GccToolChain(Constants::MINGW_TOOLCHAIN_TYPEID, GccToolChain::MinGW); } -static ToolChain *constructLinuxIccToolchain() +static Toolchain *constructLinuxIccToolchain() { return new GccToolChain(Constants::LINUXICC_TOOLCHAIN_TYPEID, GccToolChain::LinuxIcc); } @@ -1557,7 +1557,7 @@ Toolchains GccToolchainFactory::autoDetectSdkClangToolchain(const Toolchains &kn if (compilerPath.isEmpty()) return {}; - for (ToolChain * const existingTc : known) { + for (Toolchain * const existingTc : known) { if (existingTc->compilerCommand() == compilerPath) return {existingTc}; } @@ -1572,12 +1572,12 @@ Toolchains GccToolchainFactory::autoDetectToolchains(const FilePaths &compilerPa const GccToolChain::SubType subType) { Toolchains existingCandidates = filtered(known, - [language](const ToolChain *tc) { return tc->language() == language; }); + [language](const Toolchain *tc) { return tc->language() == language; }); Toolchains result; for (const FilePath &compilerPath : std::as_const(compilerPaths)) { bool alreadyExists = false; - for (ToolChain * const existingTc : existingCandidates) { + for (Toolchain * const existingTc : existingCandidates) { // We have a match if the existing toolchain ultimately refers to the same file // as the candidate path, either directly or via a hard or soft link. // Exceptions: @@ -1644,11 +1644,11 @@ Toolchains GccToolchainFactory::autoDetectToolChain(const ToolChainDescription & auto tc = new GccToolChain({}, detectedSubType); tc->setLanguage(tcd.language); - tc->setDetection(ToolChain::AutoDetection); + tc->setDetection(Toolchain::AutoDetection); tc->predefinedMacrosCache() ->insert(QStringList(), - ToolChain::MacroInspectionReport{macros, - ToolChain::languageVersion(tcd.language, macros)}); + Toolchain::MacroInspectionReport{macros, + Toolchain::languageVersion(tcd.language, macros)}); tc->setCompilerCommand(tcd.compilerPath); tc->setSupportedAbis(detectedAbis.supportedAbis); tc->setTargetAbi(abi); @@ -1656,7 +1656,7 @@ Toolchains GccToolchainFactory::autoDetectToolChain(const ToolChainDescription & tc->setDisplayName(tc->defaultDisplayName()); // reset displayname // lower priority of g++/gcc on macOS - usually just a frontend to clang if (detectedSubType == GccToolChain::RealGcc && abi.binaryFormat() == Abi::MachOFormat) - tc->setPriority(ToolChain::PriorityLow); + tc->setPriority(Toolchain::PriorityLow); result.append(tc); } return result; @@ -1671,7 +1671,7 @@ class TargetTripleWidget : public QWidget Q_OBJECT public: - TargetTripleWidget(const ToolChain *toolchain) + TargetTripleWidget(const Toolchain *toolchain) { const auto layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); @@ -1759,17 +1759,17 @@ GccToolChainConfigWidget::GccToolChainConfigWidget(GccToolChain *tc) : ToolChainManager *tcManager = ToolChainManager::instance(); m_parentToolChainConnections.append( - connect(tcManager, &ToolChainManager::toolChainUpdated, this, [this](ToolChain *tc) { + connect(tcManager, &ToolChainManager::toolChainUpdated, this, [this](Toolchain *tc) { if (tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID) updateParentToolChainComboBox(); })); m_parentToolChainConnections.append( - connect(tcManager, &ToolChainManager::toolChainAdded, this, [this](ToolChain *tc) { + connect(tcManager, &ToolChainManager::toolChainAdded, this, [this](Toolchain *tc) { if (tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID) updateParentToolChainComboBox(); })); m_parentToolChainConnections.append( - connect(tcManager, &ToolChainManager::toolChainRemoved, this, [this](ToolChain *tc) { + connect(tcManager, &ToolChainManager::toolChainRemoved, this, [this](Toolchain *tc) { if (tc->id() == toolChain()->id()) { for (QMetaObject::Connection &connection : m_parentToolChainConnections) QObject::disconnect(connection); @@ -1808,8 +1808,8 @@ void GccToolChainConfigWidget::applyImpl() tc->predefinedMacrosCache() ->insert(tc->platformCodeGenFlags(), - ToolChain::MacroInspectionReport{m_macros, - ToolChain::languageVersion(tc->language(), + Toolchain::MacroInspectionReport{m_macros, + Toolchain::languageVersion(tc->language(), m_macros)}); if (m_subType == GccToolChain::Clang && m_parentToolchainCombo) { @@ -1818,7 +1818,7 @@ void GccToolChainConfigWidget::applyImpl() const QByteArray parentId = m_parentToolchainCombo->currentData().toByteArray(); if (!parentId.isEmpty()) { - for (const ToolChain *mingwTC : mingwToolChains()) { + for (const Toolchain *mingwTC : mingwToolChains()) { if (parentId == mingwTC->id()) { tc->m_parentToolChainId = mingwTC->id(); tc->setTargetAbi(mingwTC->targetAbi()); @@ -1959,7 +1959,7 @@ void GccToolChain::syncAutodetectedWithParentToolchains() if (!ToolChainManager::isLoaded()) { connect(ToolChainManager::instance(), &ToolChainManager::toolChainsLoaded, this, [id = id()] { - if (ToolChain * const tc = ToolChainManager::findToolChain(id)) { + if (Toolchain * const tc = ToolChainManager::findToolChain(id)) { if (tc->typeId() == Constants::CLANG_TOOLCHAIN_TYPEID) static_cast(tc)->syncAutodetectedWithParentToolchains(); } @@ -1975,14 +1975,14 @@ void GccToolChain::syncAutodetectedWithParentToolchains() // Subscribe only autodetected toolchains. ToolChainManager *tcManager = ToolChainManager::instance(); m_mingwToolchainAddedConnection - = connect(tcManager, &ToolChainManager::toolChainAdded, this, [this](ToolChain *tc) { + = connect(tcManager, &ToolChainManager::toolChainAdded, this, [this](Toolchain *tc) { if (tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID && !mingwToolChainFromId(m_parentToolChainId)) { m_parentToolChainId = tc->id(); } }); m_thisToolchainRemovedConnection - = connect(tcManager, &ToolChainManager::toolChainRemoved, this, [this](ToolChain *tc) { + = connect(tcManager, &ToolChainManager::toolChainRemoved, this, [this](Toolchain *tc) { if (tc == this) { QObject::disconnect(m_thisToolchainRemovedConnection); QObject::disconnect(m_mingwToolchainAddedConnection); @@ -2012,7 +2012,7 @@ bool GccToolChain::matchesCompilerCommand(const FilePath &command) const && m_resolvedCompilerCommand->isSameExecutable(command)) return true; } - return ToolChain::matchesCompilerCommand(command); + return Toolchain::matchesCompilerCommand(command); } QString GccToolChain::sysRoot() const @@ -2044,7 +2044,7 @@ void GccToolChainConfigWidget::updateParentToolChainComboBox() if (tc->isAutoDetected()) return; - for (const ToolChain *mingwTC : mingwToolChains()) { + for (const Toolchain *mingwTC : mingwToolChains()) { if (mingwTC->id() == parentId) continue; if (mingwTC->language() != tc->language()) diff --git a/src/plugins/projectexplorer/gcctoolchain.h b/src/plugins/projectexplorer/gcctoolchain.h index 50000a27e76..a46595c7358 100644 --- a/src/plugins/projectexplorer/gcctoolchain.h +++ b/src/plugins/projectexplorer/gcctoolchain.h @@ -26,7 +26,7 @@ const QStringList gccPredefinedMacrosOptions(Utils::Id languageId); // GccToolChain // -------------------------------------------------------------------------- -class PROJECTEXPLORER_EXPORT GccToolChain : public ToolChain +class PROJECTEXPLORER_EXPORT GccToolChain : public Toolchain { public: enum SubType { RealGcc, Clang, MinGW, LinuxIcc }; @@ -57,7 +57,7 @@ public: std::unique_ptr createConfigurationWidget() override; - bool operator ==(const ToolChain &) const override; + bool operator ==(const Toolchain &) const override; void resetToolChain(const Utils::FilePath &); void setPlatformCodeGenFlags(const QStringList &); diff --git a/src/plugins/projectexplorer/kitaspects.cpp b/src/plugins/projectexplorer/kitaspects.cpp index 78aecdba6ba..6fd9808ab7c 100644 --- a/src/plugins/projectexplorer/kitaspects.cpp +++ b/src/plugins/projectexplorer/kitaspects.cpp @@ -160,7 +160,7 @@ FilePath SysRootKitAspect::sysRoot(const Kit *k) if (!k->value(SysRootKitAspect::id()).toString().isEmpty()) return FilePath::fromSettings(k->value(SysRootKitAspect::id())); - for (ToolChain *tc : ToolChainKitAspect::toolChains(k)) { + for (Toolchain *tc : ToolChainKitAspect::toolChains(k)) { if (!tc->sysRoot().isEmpty()) return FilePath::fromString(tc->sysRoot()); } @@ -172,7 +172,7 @@ void SysRootKitAspect::setSysRoot(Kit *k, const FilePath &v) if (!k) return; - for (ToolChain *tc : ToolChainKitAspect::toolChains(k)) { + for (Toolchain *tc : ToolChainKitAspect::toolChains(k)) { if (!tc->sysRoot().isEmpty()) { // It's the sysroot from toolchain, don't set it. if (tc->sysRoot() == v.toString()) @@ -249,26 +249,26 @@ private: const GuardLocker locker(m_ignoreChanges); const QList keys = m_languageComboboxMap.keys(); for (const Id l : keys) { - const Toolchains ltcList = ToolChainManager::toolchains(equal(&ToolChain::language, l)); + const Toolchains ltcList = ToolChainManager::toolchains(equal(&Toolchain::language, l)); QComboBox *cb = m_languageComboboxMap.value(l); cb->clear(); cb->addItem(Tr::tr(""), QByteArray()); - const QList same = Utils::filtered(ltcList, [device](ToolChain *tc) { + const QList same = Utils::filtered(ltcList, [device](Toolchain *tc) { return tc->compilerCommand().isSameDevice(device->rootPath()); }); - const QList other = Utils::filtered(ltcList, [device](ToolChain *tc) { + const QList other = Utils::filtered(ltcList, [device](Toolchain *tc) { return !tc->compilerCommand().isSameDevice(device->rootPath()); }); - for (ToolChain *item : same) + for (Toolchain *item : same) cb->addItem(item->displayName(), item->id()); if (!same.isEmpty() && !other.isEmpty()) cb->insertSeparator(cb->count()); - for (ToolChain *item : other) + for (Toolchain *item : other) cb->addItem(item->displayName(), item->id()); cb->setEnabled(cb->count() > 1 && !m_isReadOnly); @@ -292,7 +292,7 @@ private: return; const QByteArray id = m_languageComboboxMap.value(language)->itemData(idx).toByteArray(); - ToolChain *tc = ToolChainManager::findToolChain(id); + Toolchain *tc = ToolChainManager::findToolChain(id); QTC_ASSERT(!tc || tc->language() == language, return); if (tc) ToolChainKitAspect::setToolChain(m_kit, tc); @@ -300,7 +300,7 @@ private: ToolChainKitAspect::clearToolChain(m_kit, language); } - int indexOf(QComboBox *cb, const ToolChain *tc) + int indexOf(QComboBox *cb, const Toolchain *tc) { const QByteArray id = tc ? tc->id() : QByteArray(); for (int i = 0; i < cb->count(); ++i) { @@ -342,8 +342,8 @@ private: void onKitsLoaded() override; - void toolChainUpdated(ToolChain *tc); - void toolChainRemoved(ToolChain *tc); + void toolChainUpdated(Toolchain *tc); + void toolChainRemoved(Toolchain *tc); }; ToolChainKitAspectFactory::ToolChainKitAspectFactory() @@ -361,10 +361,10 @@ static QMap defaultToolChainIds() { QMap toolChains; const Abi abi = Abi::hostAbi(); - const Toolchains tcList = ToolChainManager::toolchains(equal(&ToolChain::targetAbi, abi)); + const Toolchains tcList = ToolChainManager::toolchains(equal(&Toolchain::targetAbi, abi)); const QList languages = ToolChainManager::allLanguages(); for (Id l : languages) { - ToolChain *tc = findOrDefault(tcList, equal(&ToolChain::language, l)); + Toolchain *tc = findOrDefault(tcList, equal(&Toolchain::language, l)); toolChains.insert(l, tc ? tc->id() : QByteArray()); } return toolChains; @@ -384,12 +384,12 @@ Tasks ToolChainKitAspectFactory::validate(const Kit *k) const { Tasks result; - const QList tcList = ToolChainKitAspect::toolChains(k); + const QList tcList = ToolChainKitAspect::toolChains(k); if (tcList.isEmpty()) { result << BuildSystemTask(Task::Warning, ToolChainKitAspect::msgNoToolChainInTarget()); } else { QSet targetAbis; - for (const ToolChain *tc : tcList) { + for (const Toolchain *tc : tcList) { targetAbis.insert(tc->targetAbi()); result << tc->validateKit(k); } @@ -443,18 +443,18 @@ void ToolChainKitAspectFactory::setup(Kit *k) } const QByteArray id = i.value().toByteArray(); - ToolChain *tc = ToolChainManager::findToolChain(id); + Toolchain *tc = ToolChainManager::findToolChain(id); if (tc) continue; // ID is not found: Might be an ABI string... lockToolchains = false; const QString abi = QString::fromUtf8(id); - const Toolchains possibleTcs = ToolChainManager::toolchains([abi, l](const ToolChain *t) { + const Toolchains possibleTcs = ToolChainManager::toolchains([abi, l](const Toolchain *t) { return t->targetAbi().toString() == abi && t->language() == l; }); - ToolChain *bestTc = nullptr; - for (ToolChain *tc : possibleTcs) { + Toolchain *bestTc = nullptr; + for (Toolchain *tc : possibleTcs) { if (!bestTc || tc->priority() > bestTc->priority()) bestTc = tc; } @@ -475,19 +475,19 @@ KitAspect *ToolChainKitAspectFactory::createKitAspect(Kit *k) const QString ToolChainKitAspectFactory::displayNamePostfix(const Kit *k) const { - ToolChain *tc = ToolChainKitAspect::cxxToolChain(k); + Toolchain *tc = ToolChainKitAspect::cxxToolChain(k); return tc ? tc->displayName() : QString(); } KitAspectFactory::ItemList ToolChainKitAspectFactory::toUserOutput(const Kit *k) const { - ToolChain *tc = ToolChainKitAspect::cxxToolChain(k); + Toolchain *tc = ToolChainKitAspect::cxxToolChain(k); return {{Tr::tr("Compiler"), tc ? tc->displayName() : Tr::tr("None")}}; } void ToolChainKitAspectFactory::addToBuildEnvironment(const Kit *k, Environment &env) const { - ToolChain *tc = ToolChainKitAspect::cxxToolChain(k); + Toolchain *tc = ToolChainKitAspect::cxxToolChain(k); if (tc) tc->addToEnvironment(env); } @@ -499,25 +499,25 @@ void ToolChainKitAspectFactory::addToMacroExpander(Kit *kit, MacroExpander *expa // Compatibility with Qt Creator < 4.2: expander->registerVariable("Compiler:Name", Tr::tr("Compiler"), [kit] { - const ToolChain *tc = ToolChainKitAspect::cxxToolChain(kit); + const Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit); return tc ? tc->displayName() : Tr::tr("None"); }); expander->registerVariable("Compiler:Executable", Tr::tr("Path to the compiler executable"), [kit] { - const ToolChain *tc = ToolChainKitAspect::cxxToolChain(kit); + const Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit); return tc ? tc->compilerCommand().path() : QString(); }); // After 4.2 expander->registerPrefix("Compiler:Name", Tr::tr("Compiler for different languages"), [kit](const QString &ls) { - const ToolChain *tc = ToolChainKitAspect::toolChain(kit, findLanguage(ls)); + const Toolchain *tc = ToolChainKitAspect::toolChain(kit, findLanguage(ls)); return tc ? tc->displayName() : Tr::tr("None"); }); expander->registerPrefix("Compiler:Executable", Tr::tr("Compiler executable for different languages"), [kit](const QString &ls) { - const ToolChain *tc = ToolChainKitAspect::toolChain(kit, findLanguage(ls)); + const Toolchain *tc = ToolChainKitAspect::toolChain(kit, findLanguage(ls)); return tc ? tc->compilerCommand().path() : QString(); }); } @@ -525,7 +525,7 @@ void ToolChainKitAspectFactory::addToMacroExpander(Kit *kit, MacroExpander *expa QList ToolChainKitAspectFactory::createOutputParsers(const Kit *k) const { for (const Id langId : {Constants::CXX_LANGUAGE_ID, Constants::C_LANGUAGE_ID}) { - if (const ToolChain * const tc = ToolChainKitAspect::toolChain(k, langId)) + if (const Toolchain * const tc = ToolChainKitAspect::toolChain(k, langId)) return tc->createOutputParsers(); } return {}; @@ -534,7 +534,7 @@ QList ToolChainKitAspectFactory::createOutputParsers(const K QSet ToolChainKitAspectFactory::availableFeatures(const Kit *k) const { QSet result; - for (ToolChain *tc : ToolChainKitAspect::toolChains(k)) + for (Toolchain *tc : ToolChainKitAspect::toolChains(k)) result.insert(tc->typeId().withPrefix("ToolChain.")); return result; } @@ -555,35 +555,35 @@ QByteArray ToolChainKitAspect::toolChainId(const Kit *k, Id language) return value.value(language.toKey(), QByteArray()).toByteArray(); } -ToolChain *ToolChainKitAspect::toolChain(const Kit *k, Id language) +Toolchain *ToolChainKitAspect::toolChain(const Kit *k, Id language) { return ToolChainManager::findToolChain(toolChainId(k, language)); } -ToolChain *ToolChainKitAspect::cToolChain(const Kit *k) +Toolchain *ToolChainKitAspect::cToolChain(const Kit *k) { return ToolChainManager::findToolChain(toolChainId(k, ProjectExplorer::Constants::C_LANGUAGE_ID)); } -ToolChain *ToolChainKitAspect::cxxToolChain(const Kit *k) +Toolchain *ToolChainKitAspect::cxxToolChain(const Kit *k) { return ToolChainManager::findToolChain(toolChainId(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID)); } -QList ToolChainKitAspect::toolChains(const Kit *k) +QList ToolChainKitAspect::toolChains(const Kit *k) { QTC_ASSERT(k, return {}); const Store value = storeFromVariant(k->value(ToolChainKitAspect::id())); - const QList tcList + const QList tcList = transform(ToolChainManager::allLanguages(), [&value](Id l) { return ToolChainManager::findToolChain(value.value(l.toKey()).toByteArray()); }); - return filtered(tcList, [](ToolChain *tc) { return tc; }); + return filtered(tcList, [](Toolchain *tc) { return tc; }); } -void ToolChainKitAspect::setToolChain(Kit *k, ToolChain *tc) +void ToolChainKitAspect::setToolChain(Kit *k, Toolchain *tc) { QTC_ASSERT(tc, return); QTC_ASSERT(k, return); @@ -603,7 +603,7 @@ void ToolChainKitAspect::setToolChain(Kit *k, ToolChain *tc) * @param k The kit to set up * @param tc The toolchain to match other languages for. */ -void ToolChainKitAspect::setAllToolChainsToMatch(Kit *k, ToolChain *tc) +void ToolChainKitAspect::setAllToolChainsToMatch(Kit *k, Toolchain *tc) { QTC_ASSERT(tc, return); QTC_ASSERT(k, return); @@ -618,9 +618,9 @@ void ToolChainKitAspect::setAllToolChainsToMatch(Kit *k, ToolChain *tc) if (l == tc->language()) continue; - ToolChain *match = nullptr; - ToolChain *bestMatch = nullptr; - for (ToolChain *other : allTcList) { + Toolchain *match = nullptr; + Toolchain *bestMatch = nullptr; + for (Toolchain *other : allTcList) { if (!other->isValid() || other->language() != l) continue; if (other->targetAbi() == tc->targetAbi()) @@ -654,11 +654,11 @@ void ToolChainKitAspect::clearToolChain(Kit *k, Id language) Abi ToolChainKitAspect::targetAbi(const Kit *k) { - const QList tcList = toolChains(k); + const QList tcList = toolChains(k); // Find the best possible ABI for all the tool chains... Abi cxxAbi; QHash abiCount; - for (ToolChain *tc : tcList) { + for (Toolchain *tc : tcList) { Abi ta = tc->targetAbi(); if (tc->language() == Id(Constants::CXX_LANGUAGE_ID)) cxxAbi = tc->targetAbi(); @@ -701,7 +701,7 @@ void ToolChainKitAspectFactory::onKitsLoaded() this, &ToolChainKitAspectFactory::toolChainUpdated); } -void ToolChainKitAspectFactory::toolChainUpdated(ToolChain *tc) +void ToolChainKitAspectFactory::toolChainUpdated(Toolchain *tc) { for (Kit *k : KitManager::kits()) { if (ToolChainKitAspect::toolChain(k, tc->language()) == tc) @@ -709,7 +709,7 @@ void ToolChainKitAspectFactory::toolChainUpdated(ToolChain *tc) } } -void ToolChainKitAspectFactory::toolChainRemoved(ToolChain *tc) +void ToolChainKitAspectFactory::toolChainRemoved(Toolchain *tc) { Q_UNUSED(tc) for (Kit *k : KitManager::kits()) diff --git a/src/plugins/projectexplorer/kitaspects.h b/src/plugins/projectexplorer/kitaspects.h index 049116a21ee..7b8270d7d42 100644 --- a/src/plugins/projectexplorer/kitaspects.h +++ b/src/plugins/projectexplorer/kitaspects.h @@ -12,7 +12,7 @@ namespace ProjectExplorer { -class ToolChain; +class Toolchain; // SysRootKitAspect @@ -31,12 +31,12 @@ class PROJECTEXPLORER_EXPORT ToolChainKitAspect public: static Utils::Id id(); static QByteArray toolChainId(const Kit *k, Utils::Id language); - static ToolChain *toolChain(const Kit *k, Utils::Id language); - static ToolChain *cToolChain(const Kit *k); - static ToolChain *cxxToolChain(const Kit *k); - static QList toolChains(const Kit *k); - static void setToolChain(Kit *k, ToolChain *tc); - static void setAllToolChainsToMatch(Kit *k, ToolChain *tc); + static Toolchain *toolChain(const Kit *k, Utils::Id language); + static Toolchain *cToolChain(const Kit *k); + static Toolchain *cxxToolChain(const Kit *k); + static QList toolChains(const Kit *k); + static void setToolChain(Kit *k, Toolchain *tc); + static void setAllToolChainsToMatch(Kit *k, Toolchain *tc); static void clearToolChain(Kit *k, Utils::Id language); static Abi targetAbi(const Kit *k); diff --git a/src/plugins/projectexplorer/kitmanager.cpp b/src/plugins/projectexplorer/kitmanager.cpp index 25987985edc..213d53f1b1e 100644 --- a/src/plugins/projectexplorer/kitmanager.cpp +++ b/src/plugins/projectexplorer/kitmanager.cpp @@ -151,8 +151,8 @@ void KitManager::destroy() static bool kitMatchesAbiList(const Kit *kit, const Abis &abis) { - const QList toolchains = ToolChainKitAspect::toolChains(kit); - for (const ToolChain * const tc : toolchains) { + const QList toolchains = ToolChainKitAspect::toolChains(kit); + for (const Toolchain * const tc : toolchains) { const Abi tcAbi = tc->targetAbi(); for (const Abi &abi : abis) { if (tcAbi.os() == abi.os() && tcAbi.architecture() == abi.architecture() @@ -183,8 +183,8 @@ static Id deviceTypeForKit(const Kit *kit) { if (isHostKit(kit)) return Constants::DESKTOP_DEVICE_TYPE; - const QList toolchains = ToolChainKitAspect::toolChains(kit); - for (const ToolChain * const tc : toolchains) { + const QList toolchains = ToolChainKitAspect::toolChains(kit); + for (const Toolchain * const tc : toolchains) { const Abi tcAbi = tc->targetAbi(); switch (tcAbi.os()) { case Abi::BareMetalOS: @@ -298,7 +298,7 @@ void KitManager::restoreKits() if (resultList.empty() || !haveKitForBinary) { // No kits exist yet, so let's try to autoconfigure some from the toolchains we know. - QHash> uniqueToolchains; + QHash> uniqueToolchains; // On Linux systems, we usually detect a plethora of same-ish toolchains. The following // algorithm gives precedence to icecc and ccache and otherwise simply chooses the one with @@ -306,8 +306,8 @@ void KitManager::restoreKits() // TODO: This should not need to be done here. Instead, it should be a convenience // operation on some lower level, e.g. in the toolchain class(es). // Also, we shouldn't detect so many doublets in the first place. - for (ToolChain * const tc : ToolChainManager::toolchains()) { - ToolChain *&bestTc = uniqueToolchains[tc->targetAbi()][tc->language()]; + for (Toolchain * const tc : ToolChainManager::toolchains()) { + Toolchain *&bestTc = uniqueToolchains[tc->targetAbi()][tc->language()]; if (!bestTc) { bestTc = tc; continue; @@ -346,7 +346,7 @@ void KitManager::restoreKits() auto kit = std::make_unique(); kit->setSdkProvided(false); kit->setAutoDetected(false); // TODO: Why false? What does autodetected mean here? - for (ToolChain * const tc : it.value()) + for (Toolchain * const tc : it.value()) ToolChainKitAspect::setToolChain(kit.get(), tc); if (contains(resultList, [&kit](const std::unique_ptr &existingKit) { return ToolChainKitAspect::toolChains(kit.get()) diff --git a/src/plugins/projectexplorer/makestep.cpp b/src/plugins/projectexplorer/makestep.cpp index 7929f2e325e..e14f2b8a932 100644 --- a/src/plugins/projectexplorer/makestep.cpp +++ b/src/plugins/projectexplorer/makestep.cpp @@ -127,10 +127,10 @@ QString MakeStep::defaultDisplayName() return Tr::tr("Make"); } -static const QList preferredToolChains(const Kit *kit) +static const QList preferredToolChains(const Kit *kit) { // prefer CXX, then C, then others - return Utils::sorted(ToolChainKitAspect::toolChains(kit), [](ToolChain *tcA, ToolChain *tcB) { + return Utils::sorted(ToolChainKitAspect::toolChains(kit), [](Toolchain *tcA, Toolchain *tcB) { if (tcA->language() == tcB->language()) return false; if (tcA->language() == Constants::CXX_LANGUAGE_ID) @@ -146,7 +146,7 @@ static const QList preferredToolChains(const Kit *kit) FilePath MakeStep::defaultMakeCommand() const { const Environment env = makeEnvironment(); - for (const ToolChain *tc : preferredToolChains(kit())) { + for (const Toolchain *tc : preferredToolChains(kit())) { FilePath make = tc->makeCommand(env); if (!make.isEmpty()) { IDevice::ConstPtr dev = BuildDeviceKitAspect::device(kit()); @@ -169,8 +169,8 @@ Task MakeStep::makeCommandMissingTask() bool MakeStep::isJobCountSupported() const { - const QList tcs = preferredToolChains(kit()); - const ToolChain *tc = tcs.isEmpty() ? nullptr : tcs.constFirst(); + const QList tcs = preferredToolChains(kit()); + const Toolchain *tc = tcs.isEmpty() ? nullptr : tcs.constFirst(); return tc && tc->isJobCountSupported(); } @@ -236,8 +236,8 @@ Environment MakeStep::makeEnvironment() const env.setupEnglishOutput(); if (makeCommand().isEmpty()) { // We also prepend "L" to the MAKEFLAGS, so that nmake / jom are less verbose - const QList tcs = preferredToolChains(target()->kit()); - const ToolChain *tc = tcs.isEmpty() ? nullptr : tcs.constFirst(); + const QList tcs = preferredToolChains(target()->kit()); + const Toolchain *tc = tcs.isEmpty() ? nullptr : tcs.constFirst(); if (tc && tc->targetAbi().os() == Abi::WindowsOS && tc->targetAbi().osFlavor() != Abi::WindowsMSysFlavor) { env.set(MAKEFLAGS, 'L' + env.expandedValueForKey(MAKEFLAGS)); diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index 8e8482e3584..1279a92272f 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -709,7 +709,7 @@ Utils::LanguageVersion MsvcToolChain::msvcLanguageVersion(const QStringList & /* if (language == Constants::CXX_LANGUAGE_ID) { if (!msvcLang.isEmpty()) // >= Visual Studio 2015 Update 3 - return ToolChain::cxxLanguageVersion(msvcLang); + return Toolchain::cxxLanguageVersion(msvcLang); if (mscVer >= 1800) // >= Visual Studio 2013 (12.0) return LanguageVersion::CXX14; if (mscVer >= 1600) // >= Visual Studio 2010 (10.0) @@ -854,7 +854,7 @@ static void addToAvailableMsvcToolchains(const MsvcToolChain *toolchain) } MsvcToolChain::MsvcToolChain(Utils::Id typeId) - : ToolChain(typeId) + : Toolchain(typeId) { setDisplayName("Microsoft Visual C++ Compiler"); setTypeDisplayName(Tr::tr("MSVC")); @@ -979,7 +979,7 @@ Abis MsvcToolChain::supportedAbis() const void MsvcToolChain::toMap(Store &data) const { - ToolChain::toMap(data); + Toolchain::toMap(data); data.insert(varsBatKeyC, m_vcvarsBat); if (!m_varsBatArg.isEmpty()) data.insert(varsBatArgKeyC, m_varsBatArg); @@ -989,7 +989,7 @@ void MsvcToolChain::toMap(Store &data) const void MsvcToolChain::fromMap(const Store &data) { - ToolChain::fromMap(data); + Toolchain::fromMap(data); if (hasError()) { g_availableMsvcToolchains.removeOne(this); return; @@ -1029,7 +1029,7 @@ bool static hasFlagEffectOnMacros(const QString &flag) return true; } -ToolChain::MacroInspectionRunner MsvcToolChain::createMacroInspectionRunner() const +Toolchain::MacroInspectionRunner MsvcToolChain::createMacroInspectionRunner() const { Utils::Environment env(m_lastEnvironment); addToEnvironment(env); @@ -1120,10 +1120,10 @@ WarningFlags MsvcToolChain::warningFlags(const QStringList &cflags) const FilePaths MsvcToolChain::includedFiles(const QStringList &flags, const FilePath &directoryPath) const { - return ToolChain::includedFiles("/FI", flags, directoryPath, PossiblyConcatenatedFlag::Yes); + return Toolchain::includedFiles("/FI", flags, directoryPath, PossiblyConcatenatedFlag::Yes); } -ToolChain::BuiltInHeaderPathsRunner MsvcToolChain::createBuiltInHeaderPathsRunner( +Toolchain::BuiltInHeaderPathsRunner MsvcToolChain::createBuiltInHeaderPathsRunner( const Environment &env) const { Utils::Environment fullEnv = env; @@ -1266,7 +1266,7 @@ static QString msvcVarsToDisplay(const MsvcToolChain &tc) class MsvcBasedToolChainConfigWidget : public ToolchainConfigWidget { public: - explicit MsvcBasedToolChainConfigWidget(ToolChain *tc) + explicit MsvcBasedToolChainConfigWidget(Toolchain *tc) : ToolchainConfigWidget(tc) , m_nameDisplayLabel(new QLabel(this)) , m_varsBatDisplayLabel(new QLabel(this)) @@ -1303,7 +1303,7 @@ protected: class MsvcToolChainConfigWidget final : public MsvcBasedToolChainConfigWidget { public: - explicit MsvcToolChainConfigWidget(ToolChain *tc) + explicit MsvcToolChainConfigWidget(Toolchain *tc) : MsvcBasedToolChainConfigWidget(tc) , m_varsBatPathCombo(new QComboBox(this)) , m_varsBatArchCombo(new QComboBox(this)) @@ -1515,7 +1515,7 @@ std::unique_ptr MsvcToolChain::createConfigurationWidget( class ClangClToolChainConfigWidget final : public MsvcBasedToolChainConfigWidget { public: - explicit ClangClToolChainConfigWidget(ToolChain *tc) + explicit ClangClToolChainConfigWidget(Toolchain *tc) : MsvcBasedToolChainConfigWidget(tc) , m_varsBatDisplayCombo(new QComboBox(this)) { @@ -1669,7 +1669,7 @@ static Toolchains detectClangClToolChainInPath(const FilePath &clangClPath, .arg(Abi::toString(targetAbi.osFlavor()).toUpper()); for (auto language : {Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}) { ClangClToolChain *tc = static_cast( - Utils::findOrDefault(alreadyKnown, [&](ToolChain *tc) -> bool { + Utils::findOrDefault(alreadyKnown, [&](Toolchain *tc) -> bool { if (tc->typeId() != Constants::CLANG_CL_TOOLCHAIN_TYPEID) return false; if (tc->targetAbi() != targetAbi) @@ -1684,7 +1684,7 @@ static Toolchains detectClangClToolChainInPath(const FilePath &clangClPath, auto cltc = new ClangClToolChain; cltc->setClangPath(clangClPath); cltc->setDisplayName(name); - cltc->setDetection(ToolChain::AutoDetection); + cltc->setDetection(Toolchain::AutoDetection); cltc->setLanguage(language); cltc->setupVarsBat(toolChain->targetAbi(), toolChain->varsBat(), toolChain->varsBatArg()); res << cltc; @@ -1711,7 +1711,7 @@ void ClangClToolChainConfigWidget::applyImpl() if (results.isEmpty()) { clangClToolChain->resetVarsBat(); } else { - for (const ToolChain *toolchain : results) { + for (const Toolchain *toolchain : results) { if (toolchain->language() == clangClToolChain->language()) { auto mstc = static_cast(toolchain); clangClToolChain->setupVarsBat(mstc->targetAbi(), mstc->varsBat(), mstc->varsBatArg()); @@ -1805,7 +1805,7 @@ std::unique_ptr ClangClToolChain::createConfigurationWidg return std::make_unique(this); } -bool ClangClToolChain::operator==(const ToolChain &other) const +bool ClangClToolChain::operator==(const Toolchain &other) const { if (!MsvcToolChain::operator==(other)) return false; @@ -1847,7 +1847,7 @@ LanguageVersion ClangClToolChain::msvcLanguageVersion(const QStringList &cxxflag const Macros ¯os) const { if (cxxflags.contains("--driver-mode=g++")) - return ToolChain::languageVersion(language, macros); + return Toolchain::languageVersion(language, macros); return MsvcToolChain::msvcLanguageVersion(cxxflags, language, macros); } @@ -1910,7 +1910,7 @@ static Toolchains findOrCreateToolchains(const ToolchainDetector &detector, { Toolchains res; for (auto language : {Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}) { - ToolChain *tc = Utils::findOrDefault(detector.alreadyKnown, [&](ToolChain *tc) -> bool { + Toolchain *tc = Utils::findOrDefault(detector.alreadyKnown, [&](Toolchain *tc) -> bool { if (tc->typeId() != Constants::MSVC_TOOLCHAIN_TYPEID) return false; if (tc->targetAbi() != abi) @@ -1966,7 +1966,7 @@ static void detectCppBuildTools2015(Toolchains *list) auto tc = new MsvcToolChain(Constants::MSVC_TOOLCHAIN_TYPEID); tc->setupVarsBat(abi, vcVarsBat, QLatin1String(e.varsBatArg)); tc->setDisplayName(name + QLatin1String(e.postFix)); - tc->setDetection(ToolChain::AutoDetection); + tc->setDetection(Toolchain::AutoDetection); tc->setLanguage(language); list->append(tc); } @@ -2005,7 +2005,7 @@ Toolchains MsvcToolchainFactory::autoDetect(const ToolchainDetector &detector) c if (!fi.exists()) continue; - QList tmp; + QList tmp; const QVector> platforms = { {MsvcToolChain::x86, "x86"}, {MsvcToolChain::amd64, "x64"}, @@ -2069,15 +2069,15 @@ Toolchains MsvcToolchainFactory::autoDetect(const ToolchainDetector &detector) c detectCppBuildTools2015(&results); - for (ToolChain *tc : std::as_const(results)) - tc->setDetection(ToolChain::AutoDetection); + for (Toolchain *tc : std::as_const(results)) + tc->setDetection(Toolchain::AutoDetection); return results; } -bool MsvcToolChain::operator==(const ToolChain &other) const +bool MsvcToolChain::operator==(const Toolchain &other) const { - if (!ToolChain::operator==(other)) + if (!Toolchain::operator==(other)) return false; const auto *msvcTc = dynamic_cast(&other); diff --git a/src/plugins/projectexplorer/msvctoolchain.h b/src/plugins/projectexplorer/msvctoolchain.h index 7d560bc0395..511ae6eb21a 100644 --- a/src/plugins/projectexplorer/msvctoolchain.h +++ b/src/plugins/projectexplorer/msvctoolchain.h @@ -20,7 +20,7 @@ namespace ProjectExplorer::Internal { // MsvcToolChain // -------------------------------------------------------------------------- -class MsvcToolChain : public ToolChain +class MsvcToolChain : public Toolchain { public: enum Type { WindowsSDK, VS }; @@ -61,7 +61,7 @@ public: void resetVarsBat(); Platform platform() const; - bool operator==(const ToolChain &) const override; + bool operator==(const Toolchain &) const override; bool isJobCountSupported() const override { return false; } @@ -153,7 +153,7 @@ public: const Utils::Id &language, const Macros ¯os) const override; - bool operator==(const ToolChain &) const override; + bool operator==(const Toolchain &) const override; int priority() const override; diff --git a/src/plugins/projectexplorer/projectimporter.cpp b/src/plugins/projectexplorer/projectimporter.cpp index 9507a7e36b9..31498c14879 100644 --- a/src/plugins/projectexplorer/projectimporter.cpp +++ b/src/plugins/projectexplorer/projectimporter.cpp @@ -310,7 +310,7 @@ bool ProjectImporter::findTemporaryHandler(Utils::Id id) const return Utils::contains(m_temporaryHandlers, [id](const TemporaryInformationHandler &ch) { return ch.id == id; }); } -static ToolChain *toolChainFromVariant(const QVariant &v) +static Toolchain *toolChainFromVariant(const QVariant &v) { const QByteArray tcId = v.toByteArray(); return ToolChainManager::findToolChain(tcId); @@ -319,7 +319,7 @@ static ToolChain *toolChainFromVariant(const QVariant &v) void ProjectImporter::cleanupTemporaryToolChains(Kit *k, const QVariantList &vl) { for (const QVariant &v : vl) { - ToolChain *tc = toolChainFromVariant(v); + Toolchain *tc = toolChainFromVariant(v); QTC_ASSERT(tc, continue); ToolChainManager::deregisterToolChain(tc); ToolChainKitAspect::setToolChain(k, nullptr); @@ -329,9 +329,9 @@ void ProjectImporter::cleanupTemporaryToolChains(Kit *k, const QVariantList &vl) void ProjectImporter::persistTemporaryToolChains(Kit *k, const QVariantList &vl) { for (const QVariant &v : vl) { - ToolChain *tmpTc = toolChainFromVariant(v); + Toolchain *tmpTc = toolChainFromVariant(v); QTC_ASSERT(tmpTc, continue); - ToolChain *actualTc = ToolChainKitAspect::toolChain(k, tmpTc->language()); + Toolchain *actualTc = ToolChainKitAspect::toolChain(k, tmpTc->language()); if (tmpTc && actualTc != tmpTc) ToolChainManager::deregisterToolChain(tmpTc); } @@ -375,7 +375,7 @@ static ProjectImporter::ToolChainData createToolChains(const ToolChainDescriptio if (data.tcs.isEmpty()) continue; - for (ToolChain *tc : std::as_const(data.tcs)) + for (Toolchain *tc : std::as_const(data.tcs)) ToolChainManager::registerToolChain(tc); data.areTemporary = true; @@ -389,10 +389,10 @@ ProjectImporter::ToolChainData ProjectImporter::findOrCreateToolChains(const ToolChainDescription &tcd) const { ToolChainData result; - result.tcs = ToolChainManager::toolchains([&tcd](const ToolChain *tc) { + result.tcs = ToolChainManager::toolchains([&tcd](const Toolchain *tc) { return tc->language() == tcd.language && tc->matchesCompilerCommand(tcd.compilerPath); }); - for (const ToolChain *tc : std::as_const(result.tcs)) { + for (const Toolchain *tc : std::as_const(result.tcs)) { const QByteArray tcId = tc->id(); result.areTemporary = result.areTemporary ? true : hasKitWithTemporaryData(ToolChainKitAspect::id(), tcId); } diff --git a/src/plugins/projectexplorer/projectimporter.h b/src/plugins/projectexplorer/projectimporter.h index cb03f84245d..a7d5496b8ae 100644 --- a/src/plugins/projectexplorer/projectimporter.h +++ b/src/plugins/projectexplorer/projectimporter.h @@ -15,7 +15,7 @@ class BuildInfo; class Kit; class Project; class Target; -class ToolChain; +class Toolchain; // Documentation inside. class PROJECTEXPLORER_EXPORT ProjectImporter : public QObject @@ -23,7 +23,7 @@ class PROJECTEXPLORER_EXPORT ProjectImporter : public QObject Q_OBJECT public: struct ToolChainData { - QList tcs; + QList tcs; bool areTemporary = false; }; diff --git a/src/plugins/projectexplorer/rawprojectpart.cpp b/src/plugins/projectexplorer/rawprojectpart.cpp index 4ac7f3947a8..53290cef8ea 100644 --- a/src/plugins/projectexplorer/rawprojectpart.cpp +++ b/src/plugins/projectexplorer/rawprojectpart.cpp @@ -16,7 +16,7 @@ namespace ProjectExplorer { -RawProjectPartFlags::RawProjectPartFlags(const ToolChain *toolChain, +RawProjectPartFlags::RawProjectPartFlags(const Toolchain *toolChain, const QStringList &commandLineFlags, const Utils::FilePath &includeFileBaseDir) { @@ -155,7 +155,7 @@ bool KitInfo::isValid() const return kit; } -ToolChainInfo::ToolChainInfo(const ToolChain *toolChain, +ToolChainInfo::ToolChainInfo(const Toolchain *toolChain, const Utils::FilePath &sysRootPath, const Utils::Environment &env) { diff --git a/src/plugins/projectexplorer/rawprojectpart.h b/src/plugins/projectexplorer/rawprojectpart.h index ca210ed43e2..419b23c951a 100644 --- a/src/plugins/projectexplorer/rawprojectpart.h +++ b/src/plugins/projectexplorer/rawprojectpart.h @@ -36,7 +36,7 @@ class PROJECTEXPLORER_EXPORT RawProjectPartFlags { public: RawProjectPartFlags() = default; - RawProjectPartFlags(const ToolChain *toolChain, const QStringList &commandLineFlags, + RawProjectPartFlags(const Toolchain *toolChain, const QStringList &commandLineFlags, const Utils::FilePath &includeFileBaseDir); public: @@ -119,8 +119,8 @@ public: bool isValid() const; Kit *kit = nullptr; - ToolChain *cToolChain = nullptr; - ToolChain *cxxToolChain = nullptr; + Toolchain *cToolChain = nullptr; + Toolchain *cxxToolChain = nullptr; Utils::QtMajorVersion projectPartQtVersion = Utils::QtMajorVersion::None; @@ -131,7 +131,7 @@ class PROJECTEXPLORER_EXPORT ToolChainInfo { public: ToolChainInfo() = default; - ToolChainInfo(const ProjectExplorer::ToolChain *toolChain, + ToolChainInfo(const ProjectExplorer::Toolchain *toolChain, const Utils::FilePath &sysRootPath, const Utils::Environment &env); @@ -148,8 +148,8 @@ public: QStringList extraCodeModelFlags; Utils::FilePath sysRootPath; // For headerPathsRunner. - ProjectExplorer::ToolChain::BuiltInHeaderPathsRunner headerPathsRunner; - ProjectExplorer::ToolChain::MacroInspectionRunner macroInspectionRunner; + ProjectExplorer::Toolchain::BuiltInHeaderPathsRunner headerPathsRunner; + ProjectExplorer::Toolchain::MacroInspectionRunner macroInspectionRunner; }; class PROJECTEXPLORER_EXPORT ProjectUpdateInfo diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp index 2d367cd5eb3..30eb101ef44 100644 --- a/src/plugins/projectexplorer/toolchain.cpp +++ b/src/plugins/projectexplorer/toolchain.cpp @@ -41,13 +41,13 @@ QList &toolchainFactories() class ToolChainPrivate { public: - using Detection = ToolChain::Detection; + using Detection = Toolchain::Detection; explicit ToolChainPrivate(Id typeId) : m_id(QUuid::createUuid().toByteArray()), m_typeId(typeId), - m_predefinedMacrosCache(new ToolChain::MacrosCache::element_type()), - m_headerPathsCache(new ToolChain::HeaderPathsCache::element_type()) + m_predefinedMacrosCache(new Toolchain::MacrosCache::element_type()), + m_headerPathsCache(new Toolchain::HeaderPathsCache::element_type()) { QTC_ASSERT(m_typeId.isValid(), return); QTC_ASSERT(!m_typeId.name().contains(':'), return); @@ -63,12 +63,12 @@ public: QString m_typeDisplayName; Id m_typeId; Id m_language; - Detection m_detection = ToolChain::UninitializedDetection; + Detection m_detection = Toolchain::UninitializedDetection; QString m_detectionSource; QString m_explicitCodeModelTargetTriple; - ToolChain::MacrosCache m_predefinedMacrosCache; - ToolChain::HeaderPathsCache m_headerPathsCache; + Toolchain::MacrosCache m_predefinedMacrosCache; + Toolchain::HeaderPathsCache m_headerPathsCache; std::optional m_isValid; bool m_hasError = false; }; @@ -119,12 +119,12 @@ using namespace Internal; // -------------------------------------------------------------------------- -ToolChain::ToolChain(Id typeId) : +Toolchain::Toolchain(Id typeId) : d(std::make_unique(typeId)) { } -void ToolChain::setLanguage(Id language) +void Toolchain::setLanguage(Id language) { QTC_ASSERT(!d->m_language.isValid() || isAutoDetected(), return); QTC_ASSERT(language.isValid(), return); @@ -133,16 +133,16 @@ void ToolChain::setLanguage(Id language) d->m_language = language; } -ToolChain::~ToolChain() = default; +Toolchain::~Toolchain() = default; -QString ToolChain::displayName() const +QString Toolchain::displayName() const { if (d->m_displayName.isEmpty()) return typeDisplayName(); return d->m_displayName; } -void ToolChain::setDisplayName(const QString &name) +void Toolchain::setDisplayName(const QString &name) { if (d->m_displayName == name) return; @@ -151,42 +151,42 @@ void ToolChain::setDisplayName(const QString &name) toolChainUpdated(); } -bool ToolChain::isAutoDetected() const +bool Toolchain::isAutoDetected() const { return detection() == AutoDetection || detection() == AutoDetectionFromSdk; } -ToolChain::Detection ToolChain::detection() const +Toolchain::Detection Toolchain::detection() const { return d->m_detection; } -QString ToolChain::detectionSource() const +QString Toolchain::detectionSource() const { return d->m_detectionSource; } -QByteArray ToolChain::id() const +QByteArray Toolchain::id() const { return d->m_id; } -QStringList ToolChain::suggestedMkspecList() const +QStringList Toolchain::suggestedMkspecList() const { return {}; } -Id ToolChain::typeId() const +Id Toolchain::typeId() const { return d->m_typeId; } -Abis ToolChain::supportedAbis() const +Abis Toolchain::supportedAbis() const { return {targetAbi()}; } -bool ToolChain::isValid() const +bool Toolchain::isValid() const { if (!d->m_isValid.has_value()) d->m_isValid = !compilerCommand().isEmpty() && compilerCommand().isExecutableFile(); @@ -194,19 +194,19 @@ bool ToolChain::isValid() const return d->m_isValid.value_or(false); } -FilePaths ToolChain::includedFiles(const QStringList &flags, const FilePath &directory) const +FilePaths Toolchain::includedFiles(const QStringList &flags, const FilePath &directory) const { Q_UNUSED(flags) Q_UNUSED(directory) return {}; } -Id ToolChain::language() const +Id Toolchain::language() const { return d->m_language; } -bool ToolChain::operator == (const ToolChain &tc) const +bool Toolchain::operator == (const Toolchain &tc) const { if (this == &tc) return true; @@ -217,11 +217,11 @@ bool ToolChain::operator == (const ToolChain &tc) const && language() == tc.language(); } -ToolChain *ToolChain::clone() const +Toolchain *Toolchain::clone() const { for (ToolchainFactory *f : std::as_const(toolchainFactories())) { if (f->supportedToolChainType() == d->m_typeId) { - ToolChain *tc = f->create(); + Toolchain *tc = f->create(); QTC_ASSERT(tc, return nullptr); Store data; toMap(data); @@ -241,7 +241,7 @@ ToolChain *ToolChain::clone() const Make sure to call this function when deriving. */ -void ToolChain::toMap(Store &result) const +void Toolchain::toMap(Store &result) const { AspectContainer::toMap(result); @@ -267,7 +267,7 @@ void ToolChain::toMap(Store &result) const result.insert(d->m_compilerCommandKey, d->m_compilerCommand.toSettings()); } -void ToolChain::toolChainUpdated() +void Toolchain::toolChainUpdated() { d->m_predefinedMacrosCache->invalidate(); d->m_headerPathsCache->invalidate(); @@ -275,27 +275,27 @@ void ToolChain::toolChainUpdated() ToolChainManager::notifyAboutUpdate(this); } -void ToolChain::setDetection(ToolChain::Detection de) +void Toolchain::setDetection(Toolchain::Detection de) { d->m_detection = de; } -void ToolChain::setDetectionSource(const QString &source) +void Toolchain::setDetectionSource(const QString &source) { d->m_detectionSource = source; } -QString ToolChain::typeDisplayName() const +QString Toolchain::typeDisplayName() const { return d->m_typeDisplayName; } -Abi ToolChain::targetAbi() const +Abi Toolchain::targetAbi() const { return d->m_targetAbi; } -void ToolChain::setTargetAbi(const Abi &abi) +void Toolchain::setTargetAbi(const Abi &abi) { if (abi == d->m_targetAbi) return; @@ -304,22 +304,22 @@ void ToolChain::setTargetAbi(const Abi &abi) toolChainUpdated(); } -void ToolChain::setTargetAbiNoSignal(const Abi &abi) +void Toolchain::setTargetAbiNoSignal(const Abi &abi) { d->m_targetAbi = abi; } -void ToolChain::setTargetAbiKey(const Key &abiKey) +void Toolchain::setTargetAbiKey(const Key &abiKey) { d->m_targetAbiKey = abiKey; } -FilePath ToolChain::compilerCommand() const +FilePath Toolchain::compilerCommand() const { return d->m_compilerCommand; } -void ToolChain::setCompilerCommand(const FilePath &command) +void Toolchain::setCompilerCommand(const FilePath &command) { d->m_isValid.reset(); @@ -329,17 +329,17 @@ void ToolChain::setCompilerCommand(const FilePath &command) toolChainUpdated(); } -bool ToolChain::matchesCompilerCommand(const FilePath &command) const +bool Toolchain::matchesCompilerCommand(const FilePath &command) const { return compilerCommand().isSameExecutable(command); } -void ToolChain::setCompilerCommandKey(const Key &commandKey) +void Toolchain::setCompilerCommandKey(const Key &commandKey) { d->m_compilerCommandKey = commandKey; } -void ToolChain::setTypeDisplayName(const QString &typeName) +void Toolchain::setTypeDisplayName(const QString &typeName) { d->m_typeDisplayName = typeName; } @@ -350,7 +350,7 @@ void ToolChain::setTypeDisplayName(const QString &typeName) Make sure to call this function when deriving. */ -void ToolChain::fromMap(const Store &data) +void Toolchain::fromMap(const Store &data) { AspectContainer::fromMap(data); @@ -392,22 +392,22 @@ void ToolChain::fromMap(const Store &data) d->m_isValid.reset(); } -void ToolChain::reportError() +void Toolchain::reportError() { d->m_hasError = true; } -bool ToolChain::hasError() const +bool Toolchain::hasError() const { return d->m_hasError; } -const ToolChain::HeaderPathsCache &ToolChain::headerPathsCache() const +const Toolchain::HeaderPathsCache &Toolchain::headerPathsCache() const { return d->m_headerPathsCache; } -const ToolChain::MacrosCache &ToolChain::predefinedMacrosCache() const +const Toolchain::MacrosCache &Toolchain::predefinedMacrosCache() const { return d->m_predefinedMacrosCache; } @@ -424,7 +424,7 @@ static long toLanguageVersionAsLong(QByteArray dateAsByteArray) return result; } -LanguageVersion ToolChain::cxxLanguageVersion(const QByteArray &cplusplusMacroValue) +LanguageVersion Toolchain::cxxLanguageVersion(const QByteArray &cplusplusMacroValue) { const long version = toLanguageVersionAsLong(cplusplusMacroValue); @@ -440,7 +440,7 @@ LanguageVersion ToolChain::cxxLanguageVersion(const QByteArray &cplusplusMacroVa return LanguageVersion::CXX03; } -LanguageVersion ToolChain::languageVersion(const Id &language, const Macros ¯os) +LanguageVersion Toolchain::languageVersion(const Id &language, const Macros ¯os) { if (language == Constants::CXX_LANGUAGE_ID) { for (const ProjectExplorer::Macro ¯o : macros) { @@ -477,7 +477,7 @@ LanguageVersion ToolChain::languageVersion(const Id &language, const Macros &mac } } -FilePaths ToolChain::includedFiles(const QString &option, +FilePaths Toolchain::includedFiles(const QString &option, const QStringList &flags, const FilePath &directoryPath, PossiblyConcatenatedFlag possiblyConcatenated) @@ -506,22 +506,22 @@ FilePaths ToolChain::includedFiles(const QString &option, Used by the tool chain kit information to validate the kit. */ -Tasks ToolChain::validateKit(const Kit *) const +Tasks Toolchain::validateKit(const Kit *) const { return {}; } -QString ToolChain::sysRoot() const +QString Toolchain::sysRoot() const { return {}; } -QString ToolChain::explicitCodeModelTargetTriple() const +QString Toolchain::explicitCodeModelTargetTriple() const { return d->m_explicitCodeModelTargetTriple; } -QString ToolChain::effectiveCodeModelTargetTriple() const +QString Toolchain::effectiveCodeModelTargetTriple() const { const QString overridden = explicitCodeModelTargetTriple(); if (!overridden.isEmpty()) @@ -529,7 +529,7 @@ QString ToolChain::effectiveCodeModelTargetTriple() const return originalTargetTriple(); } -void ToolChain::setExplicitCodeModelTargetTriple(const QString &triple) +void Toolchain::setExplicitCodeModelTargetTriple(const QString &triple) { d->m_explicitCodeModelTargetTriple = triple; } @@ -589,17 +589,17 @@ bool ToolchainFactory::canCreate() const return m_userCreatable; } -ToolChain *ToolchainFactory::create() const +Toolchain *ToolchainFactory::create() const { return m_toolchainConstructor ? m_toolchainConstructor() : nullptr; } -ToolChain *ToolchainFactory::restore(const Store &data) +Toolchain *ToolchainFactory::restore(const Store &data) { if (!m_toolchainConstructor) return nullptr; - ToolChain *tc = m_toolchainConstructor(); + Toolchain *tc = m_toolchainConstructor(); QTC_ASSERT(tc, return nullptr); tc->fromMap(data); @@ -633,11 +633,11 @@ void ToolchainFactory::autoDetectionToMap(Store &data, bool detected) data.insert(AUTODETECT_KEY, detected); } -ToolChain *ToolchainFactory::createToolChain(Id toolChainType) +Toolchain *ToolchainFactory::createToolChain(Id toolChainType) { for (ToolchainFactory *factory : std::as_const(toolchainFactories())) { if (factory->m_supportedToolChainType == toolChainType) { - if (ToolChain *tc = factory->create()) { + if (Toolchain *tc = factory->create()) { tc->d->m_typeId = toolChainType; return tc; } diff --git a/src/plugins/projectexplorer/toolchain.h b/src/plugins/projectexplorer/toolchain.h index 3c4ea73c53b..607208f6e21 100644 --- a/src/plugins/projectexplorer/toolchain.h +++ b/src/plugins/projectexplorer/toolchain.h @@ -57,7 +57,7 @@ public: // ToolChain (documentation inside) // -------------------------------------------------------------------------- -class PROJECTEXPLORER_EXPORT ToolChain : public Utils::AspectContainer +class PROJECTEXPLORER_EXPORT Toolchain : public Utils::AspectContainer { public: enum Detection { @@ -67,9 +67,9 @@ public: UninitializedDetection, }; - using Predicate = std::function; + using Predicate = std::function; - virtual ~ToolChain(); + virtual ~Toolchain(); QString displayName() const; void setDisplayName(const QString &name); @@ -113,7 +113,7 @@ public: Utils::LanguageVersion languageVersion; }; - using MacrosCache = std::shared_ptr>; + using MacrosCache = std::shared_ptr>; using HeaderPathsCache = std::shared_ptr, HeaderPaths>>; // A MacroInspectionRunner is created in the ui thread and runs in another thread. @@ -135,10 +135,10 @@ public: virtual QList createOutputParsers() const = 0; - virtual bool operator ==(const ToolChain &) const; + virtual bool operator ==(const Toolchain &) const; virtual std::unique_ptr createConfigurationWidget() = 0; - ToolChain *clone() const; + Toolchain *clone() const; // Used by the toolchainmanager to save user-generated tool chains. // Make sure to call this function when deriving! @@ -164,7 +164,7 @@ public: virtual GccToolChain *asGccToolChain() { return nullptr; } protected: - explicit ToolChain(Utils::Id typeId); + explicit Toolchain(Utils::Id typeId); void setTypeDisplayName(const QString &typeName); @@ -191,8 +191,8 @@ protected: PossiblyConcatenatedFlag possiblyConcatenated); private: - ToolChain(const ToolChain &) = delete; - ToolChain &operator=(const ToolChain &) = delete; + Toolchain(const Toolchain &) = delete; + Toolchain &operator=(const Toolchain &) = delete; const std::unique_ptr d; @@ -200,7 +200,7 @@ private: friend class ToolchainFactory; }; -using Toolchains = QList; +using Toolchains = QList; class PROJECTEXPLORER_EXPORT BadToolchain { @@ -259,15 +259,15 @@ public: virtual Toolchains detectForImport(const ToolChainDescription &tcd) const; virtual bool canCreate() const; - ToolChain *create() const; + Toolchain *create() const; - ToolChain *restore(const Utils::Store &data); + Toolchain *restore(const Utils::Store &data); static QByteArray idFromMap(const Utils::Store &data); static Utils::Id typeIdFromMap(const Utils::Store &data); static void autoDetectionToMap(Utils::Store &data, bool detected); - static ToolChain *createToolChain(Utils::Id toolChainType); + static Toolchain *createToolChain(Utils::Id toolChainType); QList supportedLanguages() const; @@ -278,7 +278,7 @@ protected: void setSupportedToolChainType(const Utils::Id &supportedToolChainType); void setSupportedLanguages(const QList &supportedLanguages); void setSupportsAllLanguages(bool supportsAllLanguages); - using ToolChainConstructor = std::function; + using ToolChainConstructor = std::function; void setToolchainConstructor(const ToolChainConstructor &constructor); ToolChainConstructor toolchainConstructor() const; diff --git a/src/plugins/projectexplorer/toolchainconfigwidget.cpp b/src/plugins/projectexplorer/toolchainconfigwidget.cpp index 6fca4890b3a..9ba30dc2aff 100644 --- a/src/plugins/projectexplorer/toolchainconfigwidget.cpp +++ b/src/plugins/projectexplorer/toolchainconfigwidget.cpp @@ -20,7 +20,7 @@ using namespace Utils; namespace ProjectExplorer { -ToolchainConfigWidget::ToolchainConfigWidget(ToolChain *tc) : +ToolchainConfigWidget::ToolchainConfigWidget(Toolchain *tc) : m_toolChain(tc) { Q_ASSERT(tc); @@ -66,7 +66,7 @@ bool ToolchainConfigWidget::isDirty() const return m_nameLineEdit->text() != m_toolChain->displayName() || isDirtyImpl(); } -ToolChain *ToolchainConfigWidget::toolChain() const +Toolchain *ToolchainConfigWidget::toolChain() const { return m_toolChain; } diff --git a/src/plugins/projectexplorer/toolchainconfigwidget.h b/src/plugins/projectexplorer/toolchainconfigwidget.h index 5735cddac9b..6ab8cb15813 100644 --- a/src/plugins/projectexplorer/toolchainconfigwidget.h +++ b/src/plugins/projectexplorer/toolchainconfigwidget.h @@ -15,7 +15,7 @@ QT_END_NAMESPACE namespace ProjectExplorer { -class ToolChain; +class Toolchain; // -------------------------------------------------------------------------- // ToolChainConfigWidget @@ -26,9 +26,9 @@ class PROJECTEXPLORER_EXPORT ToolchainConfigWidget : public QScrollArea Q_OBJECT public: - explicit ToolchainConfigWidget(ToolChain *tc); + explicit ToolchainConfigWidget(Toolchain *tc); - ToolChain *toolChain() const; + Toolchain *toolChain() const; void apply(); void discard(); @@ -53,7 +53,7 @@ protected: QLineEdit *m_nameLineEdit; private: - ToolChain *m_toolChain; + Toolchain *m_toolChain; QLabel *m_errorLabel = nullptr; }; diff --git a/src/plugins/projectexplorer/toolchainmanager.cpp b/src/plugins/projectexplorer/toolchainmanager.cpp index d04510679ed..f3b507aee68 100644 --- a/src/plugins/projectexplorer/toolchainmanager.cpp +++ b/src/plugins/projectexplorer/toolchainmanager.cpp @@ -106,7 +106,7 @@ void ToolChainManager::restoreToolChains() QTC_ASSERT(!d->m_accessor, return); d->m_accessor = std::make_unique(); - for (ToolChain *tc : d->m_accessor->restoreToolChains(Core::ICore::dialogParent())) + for (Toolchain *tc : d->m_accessor->restoreToolChains(Core::ICore::dialogParent())) registerToolChain(tc); d->m_loaded = true; @@ -131,13 +131,13 @@ const Toolchains &ToolChainManager::toolchains() return d->m_toolChains; } -Toolchains ToolChainManager::toolchains(const ToolChain::Predicate &predicate) +Toolchains ToolChainManager::toolchains(const Toolchain::Predicate &predicate) { QTC_ASSERT(predicate, return {}); return Utils::filtered(d->m_toolChains, predicate); } -ToolChain *ToolChainManager::toolChain(const ToolChain::Predicate &predicate) +Toolchain *ToolChainManager::toolChain(const Toolchain::Predicate &predicate) { QTC_CHECK(d->m_loaded); return Utils::findOrDefault(d->m_toolChains, predicate); @@ -147,7 +147,7 @@ Toolchains ToolChainManager::findToolChains(const Abi &abi) { QTC_CHECK(d->m_loaded); Toolchains result; - for (ToolChain *tc : std::as_const(d->m_toolChains)) { + for (Toolchain *tc : std::as_const(d->m_toolChains)) { bool isCompatible = Utils::anyOf(tc->supportedAbis(), [abi](const Abi &supportedAbi) { return supportedAbi.isCompatibleWith(abi); }); @@ -158,13 +158,13 @@ Toolchains ToolChainManager::findToolChains(const Abi &abi) return result; } -ToolChain *ToolChainManager::findToolChain(const QByteArray &id) +Toolchain *ToolChainManager::findToolChain(const QByteArray &id) { QTC_CHECK(d->m_loaded); if (id.isEmpty()) return nullptr; - ToolChain *tc = Utils::findOrDefault(d->m_toolChains, Utils::equal(&ToolChain::id, id)); + Toolchain *tc = Utils::findOrDefault(d->m_toolChains, Utils::equal(&Toolchain::id, id)); // Compatibility with versions 3.5 and earlier: if (!tc) { @@ -174,7 +174,7 @@ ToolChain *ToolChainManager::findToolChain(const QByteArray &id) const QByteArray shortId = id.mid(pos + 1); - tc = Utils::findOrDefault(d->m_toolChains, Utils::equal(&ToolChain::id, shortId)); + tc = Utils::findOrDefault(d->m_toolChains, Utils::equal(&Toolchain::id, shortId)); } return tc; } @@ -184,14 +184,14 @@ bool ToolChainManager::isLoaded() return d->m_loaded; } -void ToolChainManager::notifyAboutUpdate(ToolChain *tc) +void ToolChainManager::notifyAboutUpdate(Toolchain *tc) { if (!tc || !d->m_toolChains.contains(tc)) return; emit m_instance->toolChainUpdated(tc); } -bool ToolChainManager::registerToolChain(ToolChain *tc) +bool ToolChainManager::registerToolChain(Toolchain *tc) { QTC_ASSERT(tc, return false); QTC_ASSERT(isLanguageSupported(tc->language()), @@ -203,7 +203,7 @@ bool ToolChainManager::registerToolChain(ToolChain *tc) if (d->m_toolChains.contains(tc)) return true; - for (const ToolChain *current : std::as_const(d->m_toolChains)) { + for (const Toolchain *current : std::as_const(d->m_toolChains)) { if (*tc == *current && !tc->isAutoDetected()) return false; QTC_ASSERT(current->id() != tc->id(), return false); @@ -214,7 +214,7 @@ bool ToolChainManager::registerToolChain(ToolChain *tc) return true; } -void ToolChainManager::deregisterToolChain(ToolChain *tc) +void ToolChainManager::deregisterToolChain(Toolchain *tc) { QTC_CHECK(d->m_loaded); if (!tc || !d->m_toolChains.contains(tc)) diff --git a/src/plugins/projectexplorer/toolchainmanager.h b/src/plugins/projectexplorer/toolchainmanager.h index f3410be441e..c43c029c015 100644 --- a/src/plugins/projectexplorer/toolchainmanager.h +++ b/src/plugins/projectexplorer/toolchainmanager.h @@ -40,16 +40,16 @@ public: ~ToolChainManager() override; static const Toolchains &toolchains(); - static Toolchains toolchains(const ToolChain::Predicate &predicate); + static Toolchains toolchains(const Toolchain::Predicate &predicate); - static ToolChain *toolChain(const ToolChain::Predicate &predicate); - static QList findToolChains(const Abi &abi); - static ToolChain *findToolChain(const QByteArray &id); + static Toolchain *toolChain(const Toolchain::Predicate &predicate); + static QList findToolChains(const Abi &abi); + static Toolchain *findToolChain(const QByteArray &id); static bool isLoaded(); - static bool registerToolChain(ToolChain *tc); - static void deregisterToolChain(ToolChain *tc); + static bool registerToolChain(Toolchain *tc); + static void deregisterToolChain(Toolchain *tc); static QList allLanguages(); static bool registerLanguage(const Utils::Id &language, const QString &displayName); @@ -68,11 +68,11 @@ public: void saveToolChains(); signals: - void toolChainAdded(ProjectExplorer::ToolChain *); + void toolChainAdded(ProjectExplorer::Toolchain *); // Tool chain is still valid when this call happens! - void toolChainRemoved(ProjectExplorer::ToolChain *); + void toolChainRemoved(ProjectExplorer::Toolchain *); // Tool chain was updated. - void toolChainUpdated(ProjectExplorer::ToolChain *); + void toolChainUpdated(ProjectExplorer::Toolchain *); // Something changed. void toolChainsChanged(); // @@ -84,10 +84,10 @@ private: // Make sure the this is only called after all toolchain factories are registered! static void restoreToolChains(); - static void notifyAboutUpdate(ToolChain *); + static void notifyAboutUpdate(Toolchain *); friend class ProjectExplorerPlugin; // for constructor - friend class ToolChain; + friend class Toolchain; }; } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/toolchainoptionspage.cpp b/src/plugins/projectexplorer/toolchainoptionspage.cpp index fcd59e46b08..822b386b372 100644 --- a/src/plugins/projectexplorer/toolchainoptionspage.cpp +++ b/src/plugins/projectexplorer/toolchainoptionspage.cpp @@ -48,7 +48,7 @@ namespace Internal { class ToolChainTreeItem : public TreeItem { public: - ToolChainTreeItem(QStackedWidget *parentWidget, ToolChain *tc, bool c) : + ToolChainTreeItem(QStackedWidget *parentWidget, Toolchain *tc, bool c) : toolChain(tc), changed(c), m_parentWidget(parentWidget) {} @@ -100,7 +100,7 @@ public: return m_widget; } - ToolChain *toolChain; + Toolchain *toolChain; bool changed; private: @@ -253,7 +253,7 @@ public: m_widgetStack = new QStackedWidget; m_container->setWidget(m_widgetStack); - for (ToolChain *tc : ToolChainManager::toolchains()) + for (Toolchain *tc : ToolChainManager::toolchains()) insertToolChain(tc); auto buttonLayout = new QVBoxLayout; @@ -300,11 +300,11 @@ public: ToolChainTreeItem *currentTreeItem(); void markForRemoval(ToolChainTreeItem *item); - ToolChainTreeItem *insertToolChain(ProjectExplorer::ToolChain *tc, bool changed = false); // Insert directly into model - void addToolChain(ProjectExplorer::ToolChain *); - void removeToolChain(ProjectExplorer::ToolChain *); + ToolChainTreeItem *insertToolChain(ProjectExplorer::Toolchain *tc, bool changed = false); // Insert directly into model + void addToolChain(ProjectExplorer::Toolchain *); + void removeToolChain(ProjectExplorer::Toolchain *); - StaticTreeItem *parentForToolChain(ToolChain *tc); + StaticTreeItem *parentForToolChain(Toolchain *tc); QAction *createAction(const QString &name, ToolchainFactory *factory, Utils::Id language) { auto action = new QAction(name, nullptr); @@ -352,7 +352,7 @@ void ToolChainOptionsWidget::markForRemoval(ToolChainTreeItem *item) } } -ToolChainTreeItem *ToolChainOptionsWidget::insertToolChain(ToolChain *tc, bool changed) +ToolChainTreeItem *ToolChainOptionsWidget::insertToolChain(Toolchain *tc, bool changed) { StaticTreeItem *parent = parentForToolChain(tc); auto item = new ToolChainTreeItem(m_widgetStack, tc, changed); @@ -361,7 +361,7 @@ ToolChainTreeItem *ToolChainOptionsWidget::insertToolChain(ToolChain *tc, bool c return item; } -void ToolChainOptionsWidget::addToolChain(ToolChain *tc) +void ToolChainOptionsWidget::addToolChain(Toolchain *tc) { if (Utils::eraseOne(m_toAddList, [tc](const ToolChainTreeItem *item) { return item->toolChain == tc; })) { @@ -373,7 +373,7 @@ void ToolChainOptionsWidget::addToolChain(ToolChain *tc) updateState(); } -void ToolChainOptionsWidget::removeToolChain(ToolChain *tc) +void ToolChainOptionsWidget::removeToolChain(Toolchain *tc) { if (auto it = std::find_if(m_toRemoveList.begin(), m_toRemoveList.end(), [tc](const ToolChainTreeItem *item) { return item->toolChain == tc; }); @@ -392,7 +392,7 @@ void ToolChainOptionsWidget::removeToolChain(ToolChain *tc) updateState(); } -StaticTreeItem *ToolChainOptionsWidget::parentForToolChain(ToolChain *tc) +StaticTreeItem *ToolChainOptionsWidget::parentForToolChain(Toolchain *tc) { QPair nodes = m_languageMap.value(tc->language()); return tc->isAutoDetected() ? nodes.first : nodes.second; @@ -412,11 +412,11 @@ void ToolChainOptionsWidget::redetectToolchains() knownTcs << tcItem->toolChain; }); Toolchains toAdd; - QSet toDelete; + QSet toDelete; ToolChainManager::resetBadToolchains(); for (ToolchainFactory *f : ToolchainFactory::allToolchainFactories()) { const ToolchainDetector detector(knownTcs, DeviceManager::defaultDesktopDevice(), {}); // FIXME: Pass search paths - for (ToolChain * const tc : f->autoDetect(detector)) { + for (Toolchain * const tc : f->autoDetect(detector)) { if (knownTcs.contains(tc) || toDelete.contains(tc)) continue; const auto matchItem = [tc](const ToolChainTreeItem *item) { @@ -434,7 +434,7 @@ void ToolChainOptionsWidget::redetectToolchains() } for (ToolChainTreeItem * const tcItem : std::as_const(itemsToRemove)) markForRemoval(tcItem); - for (ToolChain * const newTc : std::as_const(toAdd)) + for (Toolchain * const newTc : std::as_const(toAdd)) m_toAddList.append(insertToolChain(newTc, true)); qDeleteAll(toDelete); } @@ -514,11 +514,11 @@ void ToolChainOptionsWidget::createToolChain(ToolchainFactory *factory, const Ut QTC_ASSERT(factory->canCreate(), return); QTC_ASSERT(language.isValid(), return); - ToolChain *tc = factory->create(); + Toolchain *tc = factory->create(); if (!tc) return; - tc->setDetection(ToolChain::ManualDetection); + tc->setDetection(Toolchain::ManualDetection); tc->setLanguage(language); auto item = insertToolChain(tc, true); @@ -533,11 +533,11 @@ void ToolChainOptionsWidget::cloneToolChain() if (!current) return; - ToolChain *tc = current->toolChain->clone(); + Toolchain *tc = current->toolChain->clone(); if (!tc) return; - tc->setDetection(ToolChain::ManualDetection); + tc->setDetection(Toolchain::ManualDetection); tc->setDisplayName(Tr::tr("Clone of %1").arg(current->toolChain->displayName())); auto item = insertToolChain(tc, true); @@ -551,7 +551,7 @@ void ToolChainOptionsWidget::updateState() bool canCopy = false; bool canDelete = false; if (ToolChainTreeItem *item = currentTreeItem()) { - ToolChain *tc = item->toolChain; + Toolchain *tc = item->toolChain; canCopy = tc->isValid(); canDelete = !tc->isSdkProvided(); } diff --git a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp index fcc66e6e956..dda3801fe2d 100644 --- a/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp +++ b/src/plugins/projectexplorer/toolchainsettingsaccessor.cpp @@ -68,14 +68,14 @@ static Toolchains autoDetectToolChains(const ToolchainDetector &detector) } // Remove invalid toolchains that might have sneaked in. - return Utils::filtered(result, [](const ToolChain *tc) { return tc->isValid(); }); + return Utils::filtered(result, [](const Toolchain *tc) { return tc->isValid(); }); } static Toolchains makeUniqueByEqual(const Toolchains &a) { Toolchains result; - for (ToolChain *tc : a) { - if (!Utils::contains(result, [tc](ToolChain *rtc) { return *tc == *rtc; })) + for (Toolchain *tc : a) { + if (!Utils::contains(result, [tc](Toolchain *rtc) { return *tc == *rtc; })) result.append(tc); } return result; @@ -88,26 +88,26 @@ static Toolchains makeUniqueByPointerEqual(const Toolchains &a) static Toolchains subtractById(const Toolchains &a, const Toolchains &b) { - return Utils::filtered(a, [&b](ToolChain *atc) { - return !Utils::anyOf(b, Utils::equal(&ToolChain::id, atc->id())); + return Utils::filtered(a, [&b](Toolchain *atc) { + return !Utils::anyOf(b, Utils::equal(&Toolchain::id, atc->id())); }); } -static bool containsByEqual(const Toolchains &a, const ToolChain *atc) +static bool containsByEqual(const Toolchains &a, const Toolchain *atc) { - return Utils::anyOf(a, [atc](ToolChain *btc) { return *atc == *btc; }); + return Utils::anyOf(a, [atc](Toolchain *btc) { return *atc == *btc; }); } static Toolchains subtractByEqual(const Toolchains &a, const Toolchains &b) { - return Utils::filtered(a, [&b](ToolChain *atc) { - return !Utils::anyOf(b, [atc](ToolChain *btc) { return *atc == *btc; }); + return Utils::filtered(a, [&b](Toolchain *atc) { + return !Utils::anyOf(b, [atc](Toolchain *btc) { return *atc == *btc; }); }); } static Toolchains subtractByPointerEqual(const Toolchains &a, const Toolchains &b) { - return Utils::filtered(a, [&b](ToolChain *atc) { return !b.contains(atc); }); + return Utils::filtered(a, [&b](Toolchain *atc) { return !b.contains(atc); }); } static Toolchains stabilizeOrder(const Toolchains &toRegister, @@ -121,7 +121,7 @@ static Toolchains stabilizeOrder(const Toolchains &toRegister, for (int i = 0; i < userFileTcs.count(); ++i) { const QByteArray userId = userFileTcs.at(i)->id(); const int handlePos = Utils::indexOf(toHandle, - [&userId](const ToolChain *htc) { return htc->id() == userId; }); + [&userId](const Toolchain *htc) { return htc->id() == userId; }); if (handlePos < 0) continue; @@ -140,7 +140,7 @@ static ToolChainOperations mergeToolChainLists(const Toolchains &systemFileTcs, Toolchains manualUserFileTcs; Toolchains autodetectedUserFileTcs; std::tie(autodetectedUserFileTcs, manualUserFileTcs) - = Utils::partition(uniqueUserFileTcs, &ToolChain::isAutoDetected); + = Utils::partition(uniqueUserFileTcs, &Toolchain::isAutoDetected); const Toolchains autodetectedUserTcs = subtractById(autodetectedUserFileTcs, systemFileTcs); // Calculate a set of Tcs that were detected before (and saved to userFile) and that @@ -149,14 +149,14 @@ static ToolChainOperations mergeToolChainLists(const Toolchains &systemFileTcs, Toolchains notRedetectedUserTcs; std::tie(redetectedUserTcs, notRedetectedUserTcs) = Utils::partition(autodetectedUserTcs, - [&autodetectedTcs](ToolChain *tc) { return containsByEqual(autodetectedTcs, tc); }); + [&autodetectedTcs](Toolchain *tc) { return containsByEqual(autodetectedTcs, tc); }); // Remove redetected tcs from autodetectedTcs: const Toolchains newlyAutodetectedTcs = subtractByEqual(autodetectedTcs, redetectedUserTcs); const Toolchains notRedetectedButValidUserTcs - = Utils::filtered(notRedetectedUserTcs, &ToolChain::isValid); + = Utils::filtered(notRedetectedUserTcs, &Toolchain::isValid); ToolChainOperations result; result.toDemote = notRedetectedButValidUserTcs; @@ -188,15 +188,15 @@ Toolchains ToolChainSettingsAccessor::restoreToolChains(QWidget *parent) const // read all tool chains from SDK const Toolchains systemFileTcs = toolChains( restoreSettings(Core::ICore::installerResourcePath(TOOLCHAIN_FILENAME), parent)); - for (ToolChain * const systemTc : systemFileTcs) - systemTc->setDetection(ToolChain::AutoDetectionFromSdk); + for (Toolchain * const systemTc : systemFileTcs) + systemTc->setDetection(Toolchain::AutoDetectionFromSdk); // read all tool chains from user file. const Toolchains userFileTcs = toolChains(restoreSettings(parent)); // Autodetect: Pass autodetected toolchains from user file so the information can be reused: const Toolchains autodetectedUserFileTcs - = Utils::filtered(userFileTcs, &ToolChain::isAutoDetected); + = Utils::filtered(userFileTcs, &Toolchain::isAutoDetected); // Autodect from system paths on the desktop device. // The restriction is intentional to keep startup and automatic validation a limited effort @@ -207,10 +207,10 @@ Toolchains ToolChainSettingsAccessor::restoreToolChains(QWidget *parent) const const ToolChainOperations ops = mergeToolChainLists(systemFileTcs, userFileTcs, autodetectedTcs); // Process ops: - for (ToolChain *tc : ops.toDemote) { + for (Toolchain *tc : ops.toDemote) { // FIXME: We currently only demote local toolchains, as they are not redetected. if (tc->detectionSource().isEmpty()) - tc->setDetection(ToolChain::ManualDetection); + tc->setDetection(Toolchain::ManualDetection); } qDeleteAll(ops.toDelete); @@ -223,7 +223,7 @@ void ToolChainSettingsAccessor::saveToolChains(const Toolchains &toolchains, QWi Store data; int count = 0; - for (const ToolChain *tc : toolchains) { + for (const Toolchain *tc : toolchains) { if (!tc || (!tc->isValid() && tc->isAutoDetected())) continue; Store tmp; @@ -258,7 +258,7 @@ Toolchains ToolChainSettingsAccessor::toolChains(const Store &data) const if (tcType.isValid()) { for (ToolchainFactory *f : factories) { if (f->supportedToolChainType() == tcType) { - if (ToolChain *tc = f->restore(tcMap)) { + if (Toolchain *tc = f->restore(tcMap)) { result.append(tc); restored = true; break; @@ -293,11 +293,11 @@ const char TestTokenKey[] = "TestTokenKey"; const char TestToolChainType[] = "TestToolChainType"; -class TTC : public ToolChain +class TTC : public Toolchain { public: TTC(const QByteArray &t = {}, bool v = true) : - ToolChain(TestToolChainType), + Toolchain(TestToolChainType), token(t), m_valid(v) { @@ -320,21 +320,21 @@ public: FilePath makeCommand(const Environment &) const override { return "make"; } QList createOutputParsers() const override { return {}; } std::unique_ptr createConfigurationWidget() override { return nullptr; } - bool operator ==(const ToolChain &other) const override { - if (!ToolChain::operator==(other)) + bool operator ==(const Toolchain &other) const override { + if (!Toolchain::operator==(other)) return false; return static_cast(&other)->token == token; } void fromMap(const Store &data) final { - ToolChain::fromMap(data); + Toolchain::fromMap(data); token = data.value(TestTokenKey).toByteArray(); } void toMap(Store &data) const final { - ToolChain::toMap(data); + Toolchain::toMap(data); data[TestTokenKey] = token; } @@ -350,7 +350,7 @@ QList TTC::m_toolChains; } // namespace ProjectExplorer -Q_DECLARE_METATYPE(ProjectExplorer::ToolChain *) +Q_DECLARE_METATYPE(ProjectExplorer::Toolchain *) namespace ProjectExplorer { @@ -374,43 +374,43 @@ void ProjectExplorerPlugin::testToolChainMerging_data() QTest::addColumn("toRegister"); TTC *system1 = nullptr; - ToolChain *system1c = nullptr; + Toolchain *system1c = nullptr; TTC *system2 = nullptr; TTC *system3i = nullptr; TTC *user1 = nullptr; - ToolChain *user1c = nullptr; + Toolchain *user1c = nullptr; TTC *user3i = nullptr; TTC *user2 = nullptr; TTC *auto1 = nullptr; - ToolChain *auto1c = nullptr; + Toolchain *auto1c = nullptr; TTC *auto1_2 = nullptr; TTC *auto2 = nullptr; TTC *auto3i = nullptr; if (!TTC::hasToolChains()) { system1 = new TTC("system1"); - system1->setDetection(ToolChain::AutoDetection); + system1->setDetection(Toolchain::AutoDetection); system1c = system1->clone(); Q_UNUSED(system1c) system2 = new TTC("system2"); - system2->setDetection(ToolChain::AutoDetection); + system2->setDetection(Toolchain::AutoDetection); system3i = new TTC("system3", false); - system3i->setDetection(ToolChain::AutoDetection); + system3i->setDetection(Toolchain::AutoDetection); user1 = new TTC("user1"); - user1->setDetection(ToolChain::ManualDetection); + user1->setDetection(Toolchain::ManualDetection); user1c = user1->clone(); Q_UNUSED(user1c) user2 = new TTC("user2"); - user2->setDetection(ToolChain::ManualDetection); + user2->setDetection(Toolchain::ManualDetection); user3i = new TTC("user3", false); - user3i->setDetection(ToolChain::ManualDetection); + user3i->setDetection(Toolchain::ManualDetection); auto1 = new TTC("auto1"); - auto1->setDetection(ToolChain::AutoDetection); + auto1->setDetection(Toolchain::AutoDetection); auto1c = auto1->clone(); auto1_2 = new TTC("auto1"); - auto1_2->setDetection(ToolChain::AutoDetection); + auto1_2->setDetection(Toolchain::AutoDetection); auto2 = new TTC("auto2"); - auto2->setDetection(ToolChain::AutoDetection); + auto2->setDetection(Toolchain::AutoDetection); auto3i = new TTC("auto3", false); - auto3i->setDetection(ToolChain::AutoDetection); + auto3i->setDetection(Toolchain::AutoDetection); } QTest::newRow("no toolchains") @@ -468,18 +468,18 @@ void ProjectExplorerPlugin::testToolChainMerging() Internal::ToolChainOperations ops = Internal::mergeToolChainLists(system, user, autodetect); - QSet expToRegister = Utils::toSet(toRegister); - QSet expToDemote = Utils::toSet(toDemote); + QSet expToRegister = Utils::toSet(toRegister); + QSet expToDemote = Utils::toSet(toDemote); - QSet actToRegister = Utils::toSet(ops.toRegister); - QSet actToDemote = Utils::toSet(ops.toDemote); - QSet actToDelete = Utils::toSet(ops.toDelete); + QSet actToRegister = Utils::toSet(ops.toRegister); + QSet actToDemote = Utils::toSet(ops.toDemote); + QSet actToDelete = Utils::toSet(ops.toDelete); QCOMPARE(actToRegister.count(), ops.toRegister.count()); // no dups! QCOMPARE(actToDemote.count(), ops.toDemote.count()); // no dups! QCOMPARE(actToDelete.count(), ops.toDelete.count()); // no dups! - QSet tmp = actToRegister; + QSet tmp = actToRegister; tmp.intersect(actToDemote); QCOMPARE(tmp, actToDemote); // all toDemote are in toRegister diff --git a/src/plugins/projectexplorer/toolchainsettingsaccessor.h b/src/plugins/projectexplorer/toolchainsettingsaccessor.h index aa2b44bc650..b7fe2afffd0 100644 --- a/src/plugins/projectexplorer/toolchainsettingsaccessor.h +++ b/src/plugins/projectexplorer/toolchainsettingsaccessor.h @@ -9,7 +9,7 @@ namespace ProjectExplorer { -class ToolChain; +class Toolchain; namespace Internal { @@ -18,12 +18,12 @@ class ToolChainSettingsAccessor : public Utils::UpgradingSettingsAccessor public: ToolChainSettingsAccessor(); - QList restoreToolChains(QWidget *parent) const; + QList restoreToolChains(QWidget *parent) const; - void saveToolChains(const QList &toolchains, QWidget *parent); + void saveToolChains(const QList &toolchains, QWidget *parent); private: - QList toolChains(const Utils::Store &data) const; + QList toolChains(const Utils::Store &data) const; }; } // namespace Internal diff --git a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp index 4f755b1f1a3..658e6650c19 100644 --- a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp +++ b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp @@ -102,7 +102,7 @@ static QString targetPlatform(const ProjectExplorer::Abi &abi, const ProjectExpl return QString(); } -static QStringList toolchainList(const ProjectExplorer::ToolChain *tc) +static QStringList toolchainList(const ProjectExplorer::Toolchain *tc) { const Utils::Id type = tc->typeId(); if (type == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID @@ -174,14 +174,14 @@ static QString architecture(const ProjectExplorer::Abi &targetAbi) return QString(); } -static bool isMultiTargetingToolchain(const ProjectExplorer::ToolChain *tc) +static bool isMultiTargetingToolchain(const ProjectExplorer::Toolchain *tc) { // Clang and QCC are multi-targeting compilers; others (GCC/MinGW, MSVC, ICC) are not return tc->targetAbi().os() == ProjectExplorer::Abi::QnxOS || tc->typeId() == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID; } -static QStringList architectures(const ProjectExplorer::ToolChain *tc) +static QStringList architectures(const ProjectExplorer::Toolchain *tc) { // For platforms which can have builds for multiple architectures in a single configuration // (Darwin, Android), regardless of whether the toolchain is multi-targeting or not (Clang @@ -238,12 +238,12 @@ QVariantMap DefaultPropertyProvider::autoGeneratedProperties(const ProjectExplor if (!sysroot.isEmpty()) data.insert(QLatin1String(QBS_SYSROOT), sysroot); - ToolChain *tcC = ToolChainKitAspect::cToolChain(k); - ToolChain *tcCxx = ToolChainKitAspect::cxxToolChain(k); + Toolchain *tcC = ToolChainKitAspect::cToolChain(k); + Toolchain *tcCxx = ToolChainKitAspect::cxxToolChain(k); if (!tcC && !tcCxx) return data; - ToolChain *mainTc = tcCxx ? tcCxx : tcC; + Toolchain *mainTc = tcCxx ? tcCxx : tcC; Abi targetAbi = mainTc->targetAbi(); diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index a10a2e739d8..53cee96b20d 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -827,8 +827,8 @@ static void getExpandedCompilerFlags(QStringList &cFlags, QStringList &cxxFlags, static RawProjectPart generateProjectPart( const QJsonObject &product, const QJsonObject &group, - const std::shared_ptr &cToolChain, - const std::shared_ptr &cxxToolChain, + const std::shared_ptr &cToolChain, + const std::shared_ptr &cxxToolChain, QtMajorVersion qtVersion, QString cPch, QString cxxPch, @@ -952,8 +952,8 @@ static RawProjectPart generateProjectPart( static RawProjectParts generateProjectParts( const QJsonObject &projectData, - const std::shared_ptr &cToolChain, - const std::shared_ptr &cxxToolChain, + const std::shared_ptr &cToolChain, + const std::shared_ptr &cxxToolChain, QtMajorVersion qtVersion ) { @@ -1005,9 +1005,9 @@ void QbsBuildSystem::updateCppCodeModel() const QtSupport::CppKitInfo kitInfo(kit()); QTC_ASSERT(kitInfo.isValid(), return); - const auto cToolchain = std::shared_ptr(kitInfo.cToolChain + const auto cToolchain = std::shared_ptr(kitInfo.cToolChain ? kitInfo.cToolChain->clone() : nullptr); - const auto cxxToolchain = std::shared_ptr(kitInfo.cxxToolChain + const auto cxxToolchain = std::shared_ptr(kitInfo.cxxToolChain ? kitInfo.cxxToolChain->clone() : nullptr); m_cppCodeModelUpdater->update({project(), kitInfo, activeParseEnvironment(), {}, diff --git a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp index d9d2d4c921b..0d5afda8f36 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp +++ b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp @@ -145,8 +145,8 @@ bool QbsProjectImporter::matchKit(void *directoryData, const Kit *k) const && bgData->cxxCompilerPath.isEmpty()) { return true; } - const ToolChain * const cToolchain = ToolChainKitAspect::cToolChain(k); - const ToolChain * const cxxToolchain = ToolChainKitAspect::cxxToolChain(k); + const Toolchain * const cToolchain = ToolChainKitAspect::cToolChain(k); + const Toolchain * const cxxToolchain = ToolChainKitAspect::cxxToolChain(k); if (!bgData->cCompilerPath.isEmpty()) { if (!cToolchain) return false; diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp index 53f08114fa8..9bd50ff3c10 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp @@ -781,7 +781,7 @@ QmakeBuildConfiguration::LastKitState::LastKitState(Kit *k) m_sysroot(SysRootKitAspect::sysRoot(k).toString()), m_mkspec(QmakeKitAspect::mkspec(k)) { - ToolChain *tc = ToolChainKitAspect::cxxToolChain(k); + Toolchain *tc = ToolChainKitAspect::cxxToolChain(k); m_toolchain = tc ? tc->id() : QByteArray(); } diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h index 05ccbb29836..f83c8228ce0 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.h @@ -106,7 +106,7 @@ private: void restrictNextBuild(const ProjectExplorer::RunConfiguration *rc) override; void kitChanged(); - void toolChainUpdated(ProjectExplorer::ToolChain *tc); + void toolChainUpdated(ProjectExplorer::Toolchain *tc); void qtVersionsChanged(const QList &, const QList &, const QList &changed); void updateProblemLabel(); diff --git a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp index 15f356700a4..0cd032b4991 100644 --- a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp @@ -179,7 +179,7 @@ bool QmakeMakeStep::init() void QmakeMakeStep::setupOutputFormatter(OutputFormatter *formatter) { formatter->addLineParser(new GnuMakeParser()); - ToolChain *tc = ToolChainKitAspect::cxxToolChain(kit()); + Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit()); OutputTaskParser *xcodeBuildParser = nullptr; if (tc && tc->targetAbi().os() == Abi::DarwinOS) { xcodeBuildParser = new XcodebuildParser; diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index c9d58b7dcde..4ddc7ae410b 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -237,7 +237,7 @@ QmakeBuildSystem::QmakeBuildSystem(QmakeBuildConfiguration *bc) this, &QmakeBuildSystem::scheduleUpdateAllNowOrLater); connect(ToolChainManager::instance(), &ToolChainManager::toolChainUpdated, - this, [this](ToolChain *tc) { + this, [this](Toolchain *tc) { if (ToolChainKitAspect::cxxToolChain(kit()) == tc) scheduleUpdateAllNowOrLater(); }); @@ -1308,7 +1308,7 @@ static FilePath destDirFor(const TargetInformation &ti) FilePaths QmakeBuildSystem::allLibraryTargetFiles(const QmakeProFile *file) const { - const ToolChain *const toolchain = ToolChainKitAspect::cxxToolChain(kit()); + const Toolchain *const toolchain = ToolChainKitAspect::cxxToolChain(kit()); if (!toolchain) return {}; @@ -1423,7 +1423,7 @@ static FilePath getFullPathOf(const QmakeProFile *pro, Variable variable, return bc->environment().searchInPath(exe); } -void QmakeBuildSystem::testToolChain(ToolChain *tc, const FilePath &path) const +void QmakeBuildSystem::testToolChain(Toolchain *tc, const FilePath &path) const { if (!tc || path.isEmpty()) return; @@ -1474,7 +1474,7 @@ void QmakeBuildSystem::warnOnToolChainMismatch(const QmakeProFile *pro) const FilePath QmakeBuildSystem::executableFor(const QmakeProFile *file) { - const ToolChain *const tc = ToolChainKitAspect::cxxToolChain(kit()); + const Toolchain *const tc = ToolChainKitAspect::cxxToolChain(kit()); if (!tc) return {}; diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.h b/src/plugins/qmakeprojectmanager/qmakeproject.h index 62cd3c01b2c..398799a10a7 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.h +++ b/src/plugins/qmakeprojectmanager/qmakeproject.h @@ -115,7 +115,7 @@ public: void startAsyncTimer(QmakeProFile::AsyncUpdateDelay delay); void warnOnToolChainMismatch(const QmakeProFile *pro) const; - void testToolChain(ProjectExplorer::ToolChain *tc, const Utils::FilePath &path) const; + void testToolChain(ProjectExplorer::Toolchain *tc, const Utils::FilePath &path) const; QString deviceRoot() const; diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp index ccd78c243a2..a2f20fe4eeb 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp @@ -160,7 +160,7 @@ bool QmakeProjectImporter::matchKit(void *directoryData, const Kit *k) const QtVersion *kitVersion = QtKitAspect::qtVersion(k); QString kitSpec = QmakeKitAspect::mkspec(k); - ToolChain *tc = ToolChainKitAspect::cxxToolChain(k); + Toolchain *tc = ToolChainKitAspect::cxxToolChain(k); if (kitSpec.isEmpty() && kitVersion) kitSpec = kitVersion->mkspecFor(tc); QMakeStepConfig::OsType kitOsType = QMakeStepConfig::NoOsType; @@ -217,17 +217,17 @@ static const Toolchains preferredToolChains(QtVersion *qtVersion, const QString const Toolchains toolchains = ToolChainManager::toolchains(); const Abis qtAbis = qtVersion->qtAbis(); - const auto matcher = [&](const ToolChain *tc) { + const auto matcher = [&](const Toolchain *tc) { return qtAbis.contains(tc->targetAbi()) && tc->suggestedMkspecList().contains(spec); }; - ToolChain * const cxxToolchain = findOrDefault(toolchains, [matcher](const ToolChain *tc) { + Toolchain * const cxxToolchain = findOrDefault(toolchains, [matcher](const Toolchain *tc) { return tc->language() == ProjectExplorer::Constants::CXX_LANGUAGE_ID && matcher(tc); }); - ToolChain * const cToolchain = findOrDefault(toolchains, [matcher](const ToolChain *tc) { + Toolchain * const cToolchain = findOrDefault(toolchains, [matcher](const Toolchain *tc) { return tc->language() == ProjectExplorer::Constants::C_LANGUAGE_ID && matcher(tc); }); Toolchains chosenToolchains; - for (ToolChain * const tc : {cxxToolchain, cToolchain}) { + for (Toolchain * const tc : {cxxToolchain, cToolchain}) { if (tc) chosenToolchains << tc; }; @@ -240,7 +240,7 @@ Kit *QmakeProjectImporter::createTemporaryKit(const QtProjectImporter::QtVersion { Q_UNUSED(osType) // TODO use this to select the right toolchain? return QtProjectImporter::createTemporaryKit(data, [&data, parsedSpec](Kit *k) -> void { - for (ToolChain *const tc : preferredToolChains(data.qt, parsedSpec)) + for (Toolchain *const tc : preferredToolChains(data.qt, parsedSpec)) ToolChainKitAspect::setToolChain(k, tc); if (parsedSpec != data.qt->mkspec()) QmakeKitAspect::setMkspec(k, parsedSpec, QmakeKitAspect::MkspecSource::Code); diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 632905961b4..019429805a9 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -149,7 +149,7 @@ QMakeStepConfig QMakeStep::deducedArguments() const Kit *kit = target()->kit(); QMakeStepConfig config; Abi targetAbi; - if (ToolChain *tc = ToolChainKitAspect::cxxToolChain(kit)) { + if (Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit)) { targetAbi = tc->targetAbi(); if (HostOsInfo::isWindowsHost() && tc->typeId() == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID) { diff --git a/src/plugins/qnx/qnxsettingspage.cpp b/src/plugins/qnx/qnxsettingspage.cpp index e888857c4cb..e3dd7e7acbd 100644 --- a/src/plugins/qnx/qnxsettingspage.cpp +++ b/src/plugins/qnx/qnxsettingspage.cpp @@ -99,7 +99,7 @@ public: bool isActive() const { - const bool hasToolChain = ToolChainManager::toolChain(Utils::equal(&ToolChain::compilerCommand, + const bool hasToolChain = ToolChainManager::toolChain(Utils::equal(&Toolchain::compilerCommand, m_qccCompiler)); const bool hasDebugger = Utils::contains(DebuggerItemManager::debuggers(), [this](const DebuggerItem &di) { return findTargetByDebuggerPath(di.command()); @@ -169,7 +169,7 @@ void QnxConfiguration::deactivate() QTC_ASSERT(isActive(), return); const Toolchains toolChainsToRemove = - ToolChainManager::toolchains(Utils::equal(&ToolChain::compilerCommand, m_qccCompiler)); + ToolChainManager::toolchains(Utils::equal(&Toolchain::compilerCommand, m_qccCompiler)); QList debuggersToRemove; const QList debuggerItems = DebuggerItemManager::debuggers(); @@ -187,7 +187,7 @@ void QnxConfiguration::deactivate() } } - for (ToolChain *tc : toolChainsToRemove) + for (Toolchain *tc : toolChainsToRemove) ToolChainManager::deregisterToolChain(tc); for (const DebuggerItem &debuggerItem : std::as_const(debuggersToRemove)) @@ -232,7 +232,7 @@ Toolchains QnxConfiguration::createToolChains(const QnxTarget &target) for (const Id language : {ProjectExplorer::Constants::C_LANGUAGE_ID, ProjectExplorer::Constants::CXX_LANGUAGE_ID}) { auto toolChain = new QnxToolChain; - toolChain->setDetection(ToolChain::ManualDetection); + toolChain->setDetection(Toolchain::ManualDetection); toolChain->setLanguage(language); toolChain->setTargetAbi(target.m_abi); toolChain->setDisplayName(Tr::tr("QCC for %1 (%2)") @@ -755,13 +755,13 @@ QnxSettingsPage::QnxSettingsPage(QObject *guard) this, &QnxSettingsPage::restoreConfigurations); } -QList autoDetectHelper(const QList &alreadyKnown) +QList autoDetectHelper(const QList &alreadyKnown) { - QList result; + QList result; for (const QnxConfiguration &config : std::as_const(m_configurations)) { config.ensureContents(); for (const QnxTarget &target : std::as_const(config.m_targets)) { - result += Utils::filtered(alreadyKnown, [config, target](ToolChain *tc) { + result += Utils::filtered(alreadyKnown, [config, target](Toolchain *tc) { return tc->typeId() == Constants::QNX_TOOLCHAIN_ID && tc->targetAbi() == target.m_abi && tc->compilerCommand() == config.m_qccCompiler; diff --git a/src/plugins/qnx/qnxsettingspage.h b/src/plugins/qnx/qnxsettingspage.h index 1c40e23c43d..75c1f4d7f8f 100644 --- a/src/plugins/qnx/qnxsettingspage.h +++ b/src/plugins/qnx/qnxsettingspage.h @@ -5,12 +5,12 @@ #include -namespace ProjectExplorer { class ToolChain; } +namespace ProjectExplorer { class Toolchain; } namespace Qnx::Internal { -QList autoDetectHelper( - const QList &alreadyKnown); +QList autoDetectHelper( + const QList &alreadyKnown); void setupQnxSettingsPage(QObject *guard); diff --git a/src/plugins/qnx/qnxtoolchain.cpp b/src/plugins/qnx/qnxtoolchain.cpp index 9f278ae7083..1095f07d3f3 100644 --- a/src/plugins/qnx/qnxtoolchain.cpp +++ b/src/plugins/qnx/qnxtoolchain.cpp @@ -152,7 +152,7 @@ GccToolChain::DetectedAbisResult QnxToolChain::detectSupportedAbis() const return GccToolChain::DetectedAbisResult{detectTargetAbis(sdpPath()), "unknown-qnx-gnu"}; } -bool QnxToolChain::operator ==(const ToolChain &other) const +bool QnxToolChain::operator ==(const Toolchain &other) const { if (!GccToolChain::operator ==(other)) return false; diff --git a/src/plugins/qnx/qnxtoolchain.h b/src/plugins/qnx/qnxtoolchain.h index 96a1ff91051..02e8690e5f5 100644 --- a/src/plugins/qnx/qnxtoolchain.h +++ b/src/plugins/qnx/qnxtoolchain.h @@ -20,7 +20,7 @@ public: Utils::FilePathAspect sdpPath{this}; Utils::StringAspect cpuDir{this}; - bool operator ==(const ToolChain &) const override; + bool operator ==(const Toolchain &) const override; protected: DetectedAbisResult detectSupportedAbis() const override; diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index 5e5d29c30d9..8f461eed641 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -542,7 +542,7 @@ Tasks QtVersion::validateKit(const Kit *k) result << BuildSystemTask(Task::Warning, Tr::tr("Device type is not supported by Qt version.")); } - if (ToolChain *tc = ToolChainKitAspect::cxxToolChain(k)) { + if (Toolchain *tc = ToolChainKitAspect::cxxToolChain(k)) { Abi targetAbi = tc->targetAbi(); Abis supportedAbis = tc->supportedAbis(); bool fuzzyMatch = false; @@ -1291,7 +1291,7 @@ QString QtVersion::mkspec() const return d->m_mkspec.toFSPathString(); } -QString QtVersion::mkspecFor(ToolChain *tc) const +QString QtVersion::mkspecFor(Toolchain *tc) const { QString versionSpec = mkspec(); if (!tc) @@ -1866,10 +1866,10 @@ bool QtVersionPrivate::queryQMakeVariables(const FilePath &binary, const Environ // This is required to make non-static qmakes work on windows where every tool chain // tries to be incompatible with any other. const Abis abiList = Abi::abisOfBinary(binary); - const Toolchains tcList = ToolChainManager::toolchains([&abiList](const ToolChain *t) { + const Toolchains tcList = ToolChainManager::toolchains([&abiList](const Toolchain *t) { return abiList.contains(t->targetAbi()); }); - for (ToolChain *tc : tcList) { + for (Toolchain *tc : tcList) { Environment realEnv = env; tc->addToEnvironment(realEnv); output = runQmakeQuery(binary, realEnv, error); diff --git a/src/plugins/qtsupport/baseqtversion.h b/src/plugins/qtsupport/baseqtversion.h index 796d76aa3e9..dc811b87211 100644 --- a/src/plugins/qtsupport/baseqtversion.h +++ b/src/plugins/qtsupport/baseqtversion.h @@ -28,7 +28,7 @@ class FileInProjectFinder; namespace ProjectExplorer { class Kit; -class ToolChain; +class Toolchain; class Target; } // ProjectExplorer @@ -114,7 +114,7 @@ public: /// @returns the name of the mkspec QString mkspec() const; - QString mkspecFor(ProjectExplorer::ToolChain *tc) const; + QString mkspecFor(ProjectExplorer::Toolchain *tc) const; /// @returns the full path to the default directory /// specifally not the directory the symlink/ORIGINAL_QMAKESPEC points to Utils::FilePath mkspecPath() const; diff --git a/src/plugins/qtsupport/qtkitaspect.cpp b/src/plugins/qtsupport/qtkitaspect.cpp index cd384a01e82..c53cb537c2a 100644 --- a/src/plugins/qtsupport/qtkitaspect.cpp +++ b/src/plugins/qtsupport/qtkitaspect.cpp @@ -230,7 +230,7 @@ void QtKitAspectFactory::fix(Kit *k) return; const QString spec = version->mkspec(); - Toolchains possibleTcs = ToolChainManager::toolchains([version](const ToolChain *t) { + Toolchains possibleTcs = ToolChainManager::toolchains([version](const Toolchain *t) { if (!t->isValid() || t->language() != ProjectExplorer::Constants::CXX_LANGUAGE_ID) return false; return Utils::anyOf(version->qtAbis(), [t](const Abi &qtAbi) { @@ -244,7 +244,7 @@ void QtKitAspectFactory::fix(Kit *k) // TODO: We should probably prefer the compiler with the highest version number instead, // but this information is currently not exposed by the ToolChain class. const FilePaths envPathVar = Environment::systemEnvironment().path(); - sort(possibleTcs, [version, &envPathVar](const ToolChain *tc1, const ToolChain *tc2) { + sort(possibleTcs, [version, &envPathVar](const Toolchain *tc1, const Toolchain *tc2) { const QVector &qtAbis = version->qtAbis(); const bool tc1ExactMatch = qtAbis.contains(tc1->targetAbi()); const bool tc2ExactMatch = qtAbis.contains(tc2->targetAbi()); @@ -278,11 +278,11 @@ void QtKitAspectFactory::fix(Kit *k) }); // TODO: Why is this not done during sorting? - const Toolchains goodTcs = Utils::filtered(possibleTcs, [&spec](const ToolChain *t) { + const Toolchains goodTcs = Utils::filtered(possibleTcs, [&spec](const Toolchain *t) { return t->suggestedMkspecList().contains(spec); }); - if (ToolChain * const bestTc = goodTcs.isEmpty() ? possibleTcs.first() : goodTcs.first()) + if (Toolchain * const bestTc = goodTcs.isEmpty() ? possibleTcs.first() : goodTcs.first()) ToolChainKitAspect::setAllToolChainsToMatch(k, bestTc); } } @@ -405,7 +405,7 @@ void QtKitAspect::setQtVersion(Kit *k, const QtVersion *v) void QtKitAspect::addHostBinariesToPath(const Kit *k, Environment &env) { - if (const ToolChain *tc = ToolChainKitAspect::cxxToolChain(k)) + if (const Toolchain *tc = ToolChainKitAspect::cxxToolChain(k)) env.prependOrSetPath(tc->compilerCommand().parentDir()); if (const QtVersion *qt = qtVersion(k)) diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp index 99a237d7960..15da26a439a 100644 --- a/src/plugins/qtsupport/qtoptionspage.cpp +++ b/src/plugins/qtsupport/qtoptionspage.cpp @@ -190,7 +190,7 @@ private: QIcon icon; }; ValidityInfo validInformation(const QtVersion *version); - QList toolChains(const QtVersion *version); + QList toolChains(const QtVersion *version); QByteArray defaultToolChainId(const QtVersion *version); bool isNameUnique(const QtVersion *version); @@ -487,7 +487,7 @@ QtOptionsPageWidget::ValidityInfo QtOptionsPageWidget::validInformation(const Qt const Abis qtAbis = version->qtAbis(); for (const Abi &abi : qtAbis) { - const auto abiCompatePred = [&abi] (const ToolChain *tc) + const auto abiCompatePred = [&abi] (const Toolchain *tc) { return Utils::contains(tc->supportedAbis(), [&abi](const Abi &sabi) { return sabi.isCompatibleWith(abi); }); @@ -530,9 +530,9 @@ QtOptionsPageWidget::ValidityInfo QtOptionsPageWidget::validInformation(const Qt return info; } -QList QtOptionsPageWidget::toolChains(const QtVersion *version) +QList QtOptionsPageWidget::toolChains(const QtVersion *version) { - QList toolChains; + QList toolChains; if (!version) return toolChains; @@ -540,7 +540,7 @@ QList QtOptionsPageWidget::toolChains(const QtVersion *version) const Abis abis = version->qtAbis(); for (const Abi &a : abis) { const Toolchains tcList = ToolChainManager::findToolChains(a); - for (ToolChain *tc : tcList) { + for (Toolchain *tc : tcList) { if (Utils::insert(ids, tc->id())) toolChains.append(tc); } @@ -551,7 +551,7 @@ QList QtOptionsPageWidget::toolChains(const QtVersion *version) QByteArray QtOptionsPageWidget::defaultToolChainId(const QtVersion *version) { - QList possibleToolChains = toolChains(version); + QList possibleToolChains = toolChains(version); if (!possibleToolChains.isEmpty()) return possibleToolChains.first()->id(); return QByteArray(); diff --git a/src/plugins/webassembly/webassemblytoolchain.cpp b/src/plugins/webassembly/webassemblytoolchain.cpp index e518699d33e..42855145881 100644 --- a/src/plugins/webassembly/webassemblytoolchain.cpp +++ b/src/plugins/webassembly/webassemblytoolchain.cpp @@ -48,7 +48,7 @@ static void addRegisteredMinGWToEnvironment(Environment &env) return; } - const ToolChain *toolChain = ToolChainManager::toolChain([](const ToolChain *t){ + const Toolchain *toolChain = ToolChainManager::toolChain([](const Toolchain *t){ return t->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID; }); if (toolChain) @@ -121,7 +121,7 @@ static Toolchains doAutoDetect(const ToolchainDetector &detector) ProjectExplorer::Constants::CXX_LANGUAGE_ID}) { auto toolChain = new WebAssemblyToolChain; toolChain->setLanguage(languageId); - toolChain->setDetection(ToolChain::AutoDetection); + toolChain->setDetection(Toolchain::AutoDetection); const bool cLanguage = languageId == ProjectExplorer::Constants::C_LANGUAGE_ID; const QString script = QLatin1String(cLanguage ? "emcc" : "em++") + QLatin1String(sdk.osType() == OsTypeWindows ? ".bat" : ""); @@ -140,8 +140,8 @@ static Toolchains doAutoDetect(const ToolchainDetector &detector) void WebAssemblyToolChain::registerToolChains() { // Remove old toolchains - for (ToolChain *tc : ToolChainManager::findToolChains(toolChainAbi())) { - if (tc->detection() != ToolChain::AutoDetection) + for (Toolchain *tc : ToolChainManager::findToolChains(toolChainAbi())) { + if (tc->detection() != Toolchain::AutoDetection) continue; ToolChainManager::deregisterToolChain(tc); }; From 73ddecd723f81a1b8102afc79f4f91a647c49438 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Fri, 24 Nov 2023 14:34:05 +0100 Subject: [PATCH 0376/1546] Scripts: Update compression algorithm for makedmg bzip2 has been marked as deprecated by hdutil. Change-Id: I647f1895c6b0d6456806d2ce3768fabcfdcfabc3 Reviewed-by: Eike Ziller Reviewed-by: Qt CI Bot Reviewed-by: --- scripts/makedmg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/makedmg.py b/scripts/makedmg.py index 9d7fd7f5f57..f77f03ad263 100755 --- a/scripts/makedmg.py +++ b/scripts/makedmg.py @@ -40,7 +40,7 @@ def main(): license_file = arguments.license_replacement shutil.copy(license_file, tempdir) dmg_cmd = ['hdiutil', 'create', '-srcfolder', tempdir, '-volname', arguments.dmg_volumename, - '-format', 'UDBZ', arguments.target_diskimage, '-ov', '-scrub', '-size', arguments.dmg_size, '-verbose'] + '-format', 'ULMO', arguments.target_diskimage, '-ov', '-scrub', '-size', arguments.dmg_size, '-verbose'] subprocess.check_call(dmg_cmd) # sleep a few seconds to make sure disk image is fully unmounted etc time.sleep(5) From 22f5ec4c874fd8664a6a29d31e762f7d5afbd67d Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 16 Nov 2023 08:34:02 +0100 Subject: [PATCH 0377/1546] Widget Designer: Adapt after dock widget redesign Before the redesign, the dock widgets didn't have a "tool bar" at the top, so we had the designer tool bar with the document dropdown and form related tool buttons spanning the whole design mode width (to have a continuous styled bar at the top of the window). Now the dock widgets' title widget is a styled bar, so we would have the designer tool bar, and below that the styled bar from the dock widgets, which unnecessarily creates a big blog of styled bars. Instead, move the designer tool bar inside the central form widget. The title bars from the dock widgets complete the top styled bar now. This is also more consistent with Edit mode. Change-Id: I7d322a75a8a34120763b4dd85c44ddf674930e36 Reviewed-by: Christian Stenger Reviewed-by: Marcus Tillmanns --- src/plugins/designer/editorwidget.cpp | 20 ++++++++++++++++---- src/plugins/designer/editorwidget.h | 8 ++++++-- src/plugins/designer/formeditor.cpp | 19 +++++++------------ 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/src/plugins/designer/editorwidget.cpp b/src/plugins/designer/editorwidget.cpp index 664e953b3bc..271bdadbcb1 100644 --- a/src/plugins/designer/editorwidget.cpp +++ b/src/plugins/designer/editorwidget.cpp @@ -2,10 +2,15 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 #include "editorwidget.h" + #include "formeditor.h" #include "formeditorstack.h" +#include "formwindoweditor.h" + +#include #include +#include #include #include @@ -17,12 +22,18 @@ namespace Internal { // ---------- EditorWidget -EditorWidget::EditorWidget(QWidget *parent) : - Utils::FancyMainWindow(parent), - m_stack(new FormEditorStack) +EditorWidget::EditorWidget(Core::EditorToolBar *toolBar, QWidget *parent) + : Utils::FancyMainWindow(parent) + , m_stack(new FormEditorStack) + , m_toolBar(toolBar) { + using namespace Layouting; + QWidget *centralWidget = Layouting::Column{noMargin, spacing(0), m_toolBar, m_stack}.emerge(); + centralWidget->setMinimumHeight(100); + centralWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + setObjectName("EditorWidget"); - setCentralWidget(m_stack); + setCentralWidget(centralWidget); setDocumentMode(true); setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::South); setCorner(Qt::BottomLeftCorner, Qt::LeftDockWidgetArea); @@ -79,6 +90,7 @@ void EditorWidget::add(SharedTools::WidgetHost *widgetHost, FormWindowEditor *fo data.formWindowEditor = formWindowEditor; data.widgetHost = widgetHost; m_stack->add(data); + m_toolBar->addEditor(formWindowEditor); } void EditorWidget::removeFormWindowEditor(Core::IEditor *xmlEditor) diff --git a/src/plugins/designer/editorwidget.h b/src/plugins/designer/editorwidget.h index fe1d17bdc12..b367def96f9 100644 --- a/src/plugins/designer/editorwidget.h +++ b/src/plugins/designer/editorwidget.h @@ -12,7 +12,10 @@ class QDesignerFormWindowInterface; QT_END_NAMESPACE namespace SharedTools { class WidgetHost; } -namespace Core { class IEditor; } +namespace Core { +class EditorToolBar; +class IEditor; +} // namespace Core namespace Designer { @@ -29,7 +32,7 @@ class EditorWidget : public Utils::FancyMainWindow Q_OBJECT public: - explicit EditorWidget(QWidget *parent = nullptr); + explicit EditorWidget(Core::EditorToolBar *toolBar, QWidget *parent = nullptr); QDockWidget* const* designerDockWidgets() const; @@ -46,6 +49,7 @@ public: private: FormEditorStack *m_stack = nullptr; QDockWidget *m_designerDockWidgets[Designer::Constants::DesignerSubWindowCount]; + Core::EditorToolBar *m_toolBar = nullptr; }; } // namespace Internal diff --git a/src/plugins/designer/formeditor.cpp b/src/plugins/designer/formeditor.cpp index cbd405c3d57..1588aa89140 100644 --- a/src/plugins/designer/formeditor.cpp +++ b/src/plugins/designer/formeditor.cpp @@ -200,9 +200,6 @@ public: QWidget *m_modeWidget = nullptr; EditorWidget *m_editorWidget = nullptr; - QWidget *m_editorToolBar = nullptr; - EditorToolBar *m_toolBar = nullptr; - QMap m_commandToDesignerAction; FormWindowEditorFactory *m_xmlEditorFactory = nullptr; }; @@ -392,25 +389,24 @@ void FormEditorData::fullInit() m_editorWidget->removeFormWindowEditor(editor); }); + QWidget *editorToolBar = createEditorToolBar(); + auto toolBar = new EditorToolBar; + toolBar->setToolbarCreationFlags(EditorToolBar::FlagsStandalone); + toolBar->setNavigationVisible(false); + toolBar->addCenterToolBar(editorToolBar); + // Nest toolbar and editor widget - m_editorWidget = new EditorWidget; + m_editorWidget = new EditorWidget(toolBar); QtcSettings *settings = ICore::settings(); settings->beginGroup(settingsGroupC); m_editorWidget->restoreSettings(settings); settings->endGroup(); - m_editorToolBar = createEditorToolBar(); - m_toolBar = new EditorToolBar; - m_toolBar->setToolbarCreationFlags(EditorToolBar::FlagsStandalone); - m_toolBar->setNavigationVisible(false); - m_toolBar->addCenterToolBar(m_editorToolBar); - m_modeWidget = new QWidget; m_modeWidget->setObjectName("DesignerModeWidget"); auto layout = new QVBoxLayout(m_modeWidget); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); - layout->addWidget(m_toolBar); // Avoid mode switch to 'Edit' mode when the application started by // 'Run' in 'Design' mode emits output. auto splitter = new MiniSplitter(Qt::Vertical); @@ -772,7 +768,6 @@ IEditor *FormEditorData::createEditor() FormWindowEditor *formWindowEditor = m_xmlEditorFactory->create(form); m_editorWidget->add(widgetHost, formWindowEditor); - m_toolBar->addEditor(formWindowEditor); if (formWindowEditor) { Utils::InfoBarEntry info(Id(Constants::INFO_READ_ONLY), From 7c729529679daf7411030b41ee661a2b36be0aaf Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 23 Nov 2023 12:24:17 +0100 Subject: [PATCH 0378/1546] FancyMainWindow: Improve positioning of docks when (un)collapsing This is not foolproof, but we try to find the dock widgets that are vertically arranged with the one that is (un)collapsed, and try to set the sizes such that the title widget does not move. Change-Id: I14fd799396a41420b041a89d43fd65d47672a831 Reviewed-by: Christian Stenger Reviewed-by: Reviewed-by: Marcus Tillmanns --- src/libs/utils/fancymainwindow.cpp | 111 ++++++++++++++++++++++++----- 1 file changed, 92 insertions(+), 19 deletions(-) diff --git a/src/libs/utils/fancymainwindow.cpp b/src/libs/utils/fancymainwindow.cpp index 0e26d5bfc0b..1c241b432e6 100644 --- a/src/libs/utils/fancymainwindow.cpp +++ b/src/libs/utils/fancymainwindow.cpp @@ -54,6 +54,7 @@ public: FancyMainWindow *q; QWidget *m_hiddenInnerWidget = nullptr; + int m_hiddenInnerWidgetHeight = 0; private: QPoint m_startPos; @@ -135,19 +136,10 @@ public: m_collapseButton = new DockWidgetTitleButton(this); updateCollapse(); - connect(m_collapseButton, &DockWidgetTitleButton::clicked, this, [this] { - if (supportsCollapse()) { - if (!q->m_hiddenInnerWidget) { - q->m_hiddenInnerWidget = q->widget(); - auto w = new QWidget; - w->setMaximumHeight(0); - q->setWidget(w); - } else { - ensureWidgetShown(); - } - } - updateCollapse(); - }); + connect(m_collapseButton, + &DockWidgetTitleButton::clicked, + this, + &TitleBarWidget::toggleCollapse); connect(q->q, &FancyMainWindow::dockWidgetsChanged, this, &TitleBarWidget::updateCollapse); m_floatButton = new DockWidgetTitleButton(this); @@ -225,6 +217,13 @@ public: : QSize(titleMinWidth, titleInactiveHeight); } + QList docksInArea() const + { + return filtered(q->q->dockWidgets(), [this, area = q->q->dockWidgetArea(q)](QDockWidget *w) { + return w->isVisible() && q->q->dockWidgetArea(w) == area; + }); + } + bool supportsCollapse() const { // not if floating @@ -235,19 +234,39 @@ public: return w->isVisible(); }).isEmpty()) return false; - const QList docksInArea - = filtered(q->q->dockWidgets(), [this, area = q->q->dockWidgetArea(q)](QDockWidget *w) { - return w != q && w->isVisible() && q->q->dockWidgetArea(w) == area; - }); + const QList inArea = docksInArea(); // not if only dock in area - if (docksInArea.isEmpty()) + if (inArea.size() <= 1) return false; // not if in horizontal layout - if (anyOf(docksInArea, [y = q->y()](QDockWidget *w) { return w->y() == y; })) + // - This is just a workaround. There could be two columns and a dock widget in the other + // column at the same height as this one. In that case we wrongly return false here. + if (anyOf(inArea, [this, y = q->y()](QDockWidget *w) { return w->y() == y && w != q; })) return false; return true; } + struct DocksAndSizes + { + QList docks; + QList sizes; + }; + + DocksAndSizes verticallyArrangedDocks() const + { + DocksAndSizes result; + const QList inArea = docksInArea(); + // This is just a workaround. There could be two rows and a dock widget in the other row + // exactly below this one. In that case we include widgets here that are not in a + // vertical layout together. + result.docks = filtered(inArea, [this](QDockWidget *w) { + return w->x() == q->x() && w->width() == q->width(); + }); + Utils::sort(result.docks, [](QDockWidget *a, QDockWidget *b) { return a->y() < b->y(); }); + result.sizes = transform(result.docks, [](QDockWidget *w) { return w->height(); }); + return result; + } + void ensureWidgetShown() { if (q->m_hiddenInnerWidget) { @@ -257,6 +276,60 @@ public: } } + void toggleCollapse() + { + if (supportsCollapse()) { + // save dock widget sizes before the change + DocksAndSizes verticalDocks = verticallyArrangedDocks(); + if (!q->m_hiddenInnerWidget) { + q->m_hiddenInnerWidgetHeight = q->height() - sizeHint().height(); + q->m_hiddenInnerWidget = q->widget(); + auto w = new QWidget; + w->setMaximumHeight(0); + q->setWidget(w); + + if (verticalDocks.docks.size() > 1) { // not only this dock + // fixup dock sizes, so the dock below this one gets the space if possible + const int selfIndex = indexOf(verticalDocks.docks, + [this](QDockWidget *w) { return w == q; }); + if (QTC_GUARD(0 <= selfIndex && selfIndex < verticalDocks.docks.size())) { + verticalDocks.sizes[selfIndex] = sizeHint().height(); + if (selfIndex + 1 < verticalDocks.sizes.size()) + verticalDocks.sizes[selfIndex + 1] += q->m_hiddenInnerWidgetHeight; + else + verticalDocks.sizes[selfIndex - 1] += q->m_hiddenInnerWidgetHeight; + q->q->resizeDocks(verticalDocks.docks, verticalDocks.sizes, Qt::Vertical); + } + } + } else { + ensureWidgetShown(); + + if (verticalDocks.docks.size() > 1) { // not only this dock + // steal space from dock below if possible + const int selfIndex = indexOf(verticalDocks.docks, + [this](QDockWidget *w) { return w == q; }); + if (QTC_GUARD(0 <= selfIndex && selfIndex < verticalDocks.docks.size())) { + verticalDocks.sizes[selfIndex] = sizeHint().height() + + q->m_hiddenInnerWidgetHeight; + if (selfIndex + 1 < verticalDocks.sizes.size()) { + verticalDocks.sizes[selfIndex + 1] + = std::max(1, + verticalDocks.sizes[selfIndex + 1] + - q->m_hiddenInnerWidgetHeight); + } else { + verticalDocks.sizes[selfIndex - 1] + = std::max(1, + verticalDocks.sizes[selfIndex - 1] + - q->m_hiddenInnerWidgetHeight); + } + q->q->resizeDocks(verticalDocks.docks, verticalDocks.sizes, Qt::Vertical); + } + } + } + } + updateCollapse(); + } + void updateCollapse() { const bool supported = m_active && supportsCollapse(); From b76c054961585e9716feb2ecdeed691b6cc9c267 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 24 Nov 2023 14:22:26 +0100 Subject: [PATCH 0379/1546] Widget Designer: Hide the toggle action for the central widget It doesn't really make sense to toggle the central widget (= form editor) for widget designer Change-Id: I6ebcc9e1c2a57f1377c16a791b27b44f081042c3 Reviewed-by: Christian Stenger Reviewed-by: --- src/plugins/designer/formeditor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/designer/formeditor.cpp b/src/plugins/designer/formeditor.cpp index 1588aa89140..205c6120a82 100644 --- a/src/plugins/designer/formeditor.cpp +++ b/src/plugins/designer/formeditor.cpp @@ -397,6 +397,7 @@ void FormEditorData::fullInit() // Nest toolbar and editor widget m_editorWidget = new EditorWidget(toolBar); + m_editorWidget->showCentralWidgetAction()->setVisible(false); QtcSettings *settings = ICore::settings(); settings->beginGroup(settingsGroupC); m_editorWidget->restoreSettings(settings); From cdee6e263dca7c9b9b7585d397c27cb2d6bd6eed Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Mon, 27 Nov 2023 11:54:39 +0100 Subject: [PATCH 0380/1546] README: Fix markdown rendering in Qt Creator The <> break the rendering and looks weird. Change-Id: Ib3ce7763127623d1ac0bbd0c133b71b7ef41fd29 Reviewed-by: Eike Ziller --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b72234370ea..78681344560 100644 --- a/README.md +++ b/README.md @@ -594,14 +594,14 @@ SQLite (https://www.sqlite.org) is in the Public Domain. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of the nor the + * Neither the name of the <organization> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND From 2da12ddc6076f561586d45a58a52dcb9779ab008 Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Mon, 27 Nov 2023 07:13:24 +0100 Subject: [PATCH 0381/1546] Terminal: Add select all action Fixes: QTCREATORBUG-29922 Change-Id: I565f2f9f570610e1bb7f528cd874a0dd9c47dbe8 Reviewed-by: Cristian Adam Reviewed-by: --- src/libs/solutions/terminal/terminalview.cpp | 5 +++++ src/libs/solutions/terminal/terminalview.h | 1 + src/plugins/terminal/terminalconstants.h | 1 + src/plugins/terminal/terminalwidget.cpp | 9 +++++++++ src/plugins/terminal/terminalwidget.h | 1 + 5 files changed, 17 insertions(+) diff --git a/src/libs/solutions/terminal/terminalview.cpp b/src/libs/solutions/terminal/terminalview.cpp index 2244ea62d73..4b1b0159c99 100644 --- a/src/libs/solutions/terminal/terminalview.cpp +++ b/src/libs/solutions/terminal/terminalview.cpp @@ -324,6 +324,11 @@ void TerminalView::clearSelection() //d->m_surface->sendKey(Qt::Key_Escape); } +void TerminalView::selectAll() +{ + setSelection(Selection{0, d->m_surface->fullSize().width() * d->m_surface->fullSize().height()}); +} + void TerminalView::zoomIn() { QFont f = font(); diff --git a/src/libs/solutions/terminal/terminalview.h b/src/libs/solutions/terminal/terminalview.h index 4745c63ee15..4079eb7ddca 100644 --- a/src/libs/solutions/terminal/terminalview.h +++ b/src/libs/solutions/terminal/terminalview.h @@ -75,6 +75,7 @@ public: std::optional selection() const; void clearSelection(); + void selectAll(); void zoomIn(); void zoomOut(); diff --git a/src/plugins/terminal/terminalconstants.h b/src/plugins/terminal/terminalconstants.h index 67b618c62de..a55bd05f2c3 100644 --- a/src/plugins/terminal/terminalconstants.h +++ b/src/plugins/terminal/terminalconstants.h @@ -16,5 +16,6 @@ constexpr char MOVECURSORWORDLEFT[] = "Terminal.MoveCursorWordLeft"; constexpr char MOVECURSORWORDRIGHT[] = "Terminal.MoveCursorWordRight"; constexpr char CLEAR_TERMINAL[] = "Terminal.ClearTerminal"; constexpr char TOGGLE_KEYBOARD_LOCK[] = "Terminal.ToggleKeyboardLock"; +constexpr char SELECTALL[] = "Terminal.SelectAll"; } // namespace Terminal::Constants diff --git a/src/plugins/terminal/terminalwidget.cpp b/src/plugins/terminal/terminalwidget.cpp index bc19decf5ec..a3e70b77217 100644 --- a/src/plugins/terminal/terminalwidget.cpp +++ b/src/plugins/terminal/terminalwidget.cpp @@ -278,11 +278,13 @@ void TerminalWidget::setupActions() m_clearSelection = registerAction(Constants::CLEARSELECTION, m_context); m_moveCursorWordLeft = registerAction(Constants::MOVECURSORWORDLEFT, m_context); m_moveCursorWordRight = registerAction(Constants::MOVECURSORWORDRIGHT, m_context); + m_selectAll = registerAction(Constants::SELECTALL, m_context); connect(m_copy.get(), &QAction::triggered, this, &TerminalWidget::copyToClipboard); connect(m_paste.get(), &QAction::triggered, this, &TerminalWidget::pasteFromClipboard); connect(m_close.get(), &QAction::triggered, this, &TerminalWidget::closeTerminal); connect(m_clearTerminal.get(), &QAction::triggered, this, &TerminalWidget::clearContents); + connect(m_selectAll.get(), &QAction::triggered, this, &TerminalWidget::selectAll); connect(m_clearSelection.get(), &QAction::triggered, this, &TerminalWidget::clearSelection); connect(m_moveCursorWordLeft.get(), &QAction::triggered, @@ -503,6 +505,7 @@ void TerminalWidget::contextMenuRequested(const QPoint &pos) contextMenu->addAction(ActionManager::command(Constants::COPY)->action()); contextMenu->addAction(ActionManager::command(Constants::PASTE)->action()); + contextMenu->addAction(ActionManager::command(Constants::SELECTALL)->action()); contextMenu->addSeparator(); contextMenu->addAction(ActionManager::command(Constants::CLEAR_TERMINAL)->action()); contextMenu->addSeparator(); @@ -612,6 +615,7 @@ void TerminalWidget::initActions() static QAction paste; static QAction clearSelection; static QAction clearTerminal; + static QAction selectAll; static QAction moveCursorWordLeft; static QAction moveCursorWordRight; static QAction close; @@ -620,24 +624,29 @@ void TerminalWidget::initActions() paste.setText(Tr::tr("Paste")); clearSelection.setText(Tr::tr("Clear Selection")); clearTerminal.setText(Tr::tr("Clear Terminal")); + selectAll.setText(Tr::tr("Select All")); moveCursorWordLeft.setText(Tr::tr("Move Cursor Word Left")); moveCursorWordRight.setText(Tr::tr("Move Cursor Word Right")); close.setText(Tr::tr("Close Terminal")); auto copyCmd = ActionManager::registerAction(©, Constants::COPY, context); auto pasteCmd = ActionManager::registerAction(&paste, Constants::PASTE, context); + auto selectAllCmd = ActionManager::registerAction(&selectAll, Constants::SELECTALL, context); if (HostOsInfo::isMacHost()) { copyCmd->setDefaultKeySequence(QKeySequence(QLatin1String("Ctrl+C"))); pasteCmd->setDefaultKeySequence(QKeySequence(QLatin1String("Ctrl+V"))); + selectAllCmd->setDefaultKeySequence(QKeySequence(QLatin1String("Ctrl+A"))); } else if (HostOsInfo::isLinuxHost()) { copyCmd->setDefaultKeySequence(QKeySequence(QLatin1String("Ctrl+Shift+C"))); pasteCmd->setDefaultKeySequence(QKeySequence(QLatin1String("Ctrl+Shift+V"))); + selectAllCmd->setDefaultKeySequence(QKeySequence(QLatin1String("Ctrl+Shift+A"))); } else if (HostOsInfo::isWindowsHost()) { copyCmd->setDefaultKeySequences( {QKeySequence(QLatin1String("Ctrl+C")), QKeySequence(QLatin1String("Ctrl+Shift+C"))}); pasteCmd->setDefaultKeySequences( {QKeySequence(QLatin1String("Ctrl+V")), QKeySequence(QLatin1String("Ctrl+Shift+V"))}); + selectAllCmd->setDefaultKeySequence(QKeySequence(QLatin1String("Ctrl+Shift+A"))); } ActionManager::registerAction(&clearSelection, Constants::CLEARSELECTION, context); diff --git a/src/plugins/terminal/terminalwidget.h b/src/plugins/terminal/terminalwidget.h index fa1b20e8f97..55822b2c7cd 100644 --- a/src/plugins/terminal/terminalwidget.h +++ b/src/plugins/terminal/terminalwidget.h @@ -105,6 +105,7 @@ private: RegisteredAction m_paste; RegisteredAction m_clearSelection; RegisteredAction m_clearTerminal; + RegisteredAction m_selectAll; RegisteredAction m_moveCursorWordLeft; RegisteredAction m_moveCursorWordRight; RegisteredAction m_close; From ba249a35141892168f16fd3c6e4613f7b0f67131 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 23 Oct 2023 15:32:53 +0200 Subject: [PATCH 0382/1546] QbsProjectManager: Add a language client ... and use it to follow symbols that QmlJSEditor does not know about. For now, the only implemented case on the server side is getting to a product or module via a Depends item. More functionality will follow. Change-Id: I597c7ab10f4bf6962684ed26357dfc0eef3a6c15 Reviewed-by: Reviewed-by: David Schulz --- src/plugins/qbsprojectmanager/CMakeLists.txt | 4 +- src/plugins/qbsprojectmanager/qbseditor.cpp | 60 +++++++++++++ src/plugins/qbsprojectmanager/qbseditor.h | 16 ++++ .../qbsprojectmanager/qbslanguageclient.cpp | 90 +++++++++++++++++++ .../qbsprojectmanager/qbslanguageclient.h | 25 ++++++ .../qbsprojectmanager/qbsprojectmanager.qbs | 13 ++- .../qbsprojectmanagerplugin.cpp | 2 + src/plugins/qbsprojectmanager/qbssession.cpp | 12 ++- src/plugins/qbsprojectmanager/qbssession.h | 3 +- src/plugins/qmljseditor/qmljseditor.cpp | 1 - 10 files changed, 219 insertions(+), 7 deletions(-) create mode 100644 src/plugins/qbsprojectmanager/qbseditor.cpp create mode 100644 src/plugins/qbsprojectmanager/qbseditor.h create mode 100644 src/plugins/qbsprojectmanager/qbslanguageclient.cpp create mode 100644 src/plugins/qbsprojectmanager/qbslanguageclient.h diff --git a/src/plugins/qbsprojectmanager/CMakeLists.txt b/src/plugins/qbsprojectmanager/CMakeLists.txt index f039198419e..6102be41254 100644 --- a/src/plugins/qbsprojectmanager/CMakeLists.txt +++ b/src/plugins/qbsprojectmanager/CMakeLists.txt @@ -2,7 +2,7 @@ add_qtc_plugin(QbsProjectManager DEPENDS Qt::Qml Qt::Widgets QmlJS DEFINES IDE_LIBRARY_BASENAME="${IDE_LIBRARY_BASE_PATH}" - PLUGIN_DEPENDS Core ProjectExplorer CppEditor QtSupport QmlJSTools + PLUGIN_DEPENDS Core CppEditor LanguageClient ProjectExplorer QmlJSTools QmlJSEditor QtSupport SOURCES customqbspropertiesdialog.cpp customqbspropertiesdialog.h defaultpropertyprovider.cpp defaultpropertyprovider.h @@ -10,8 +10,10 @@ add_qtc_plugin(QbsProjectManager qbsbuildconfiguration.cpp qbsbuildconfiguration.h qbsbuildstep.cpp qbsbuildstep.h qbscleanstep.cpp qbscleanstep.h + qbseditor.cpp qbseditor.h qbsinstallstep.cpp qbsinstallstep.h qbskitaspect.cpp qbskitaspect.h + qbslanguageclient.cpp qbslanguageclient.h qbsnodes.cpp qbsnodes.h qbsnodetreebuilder.cpp qbsnodetreebuilder.h qbspmlogging.cpp qbspmlogging.h diff --git a/src/plugins/qbsprojectmanager/qbseditor.cpp b/src/plugins/qbsprojectmanager/qbseditor.cpp new file mode 100644 index 00000000000..7eed6977a2c --- /dev/null +++ b/src/plugins/qbsprojectmanager/qbseditor.cpp @@ -0,0 +1,60 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "qbseditor.h" + +#include "qbslanguageclient.h" +#include "qbsprojectmanagertr.h" + +#include +#include + +#include + +using namespace LanguageClient; +using namespace QmlJSEditor; +using namespace Utils; + +namespace QbsProjectManager::Internal { + +class QbsEditorWidget : public QmlJSEditorWidget +{ +private: + void findLinkAt(const QTextCursor &cursor, + const LinkHandler &processLinkCallback, + bool resolveTarget = true, + bool inNextSplit = false) override; +}; + +QbsEditorFactory::QbsEditorFactory() : QmlJSEditorFactory("QbsEditor.QbsEditor") +{ + setDisplayName(Tr::tr("Qbs Editor")); + setMimeTypes({Utils::Constants::QBS_MIMETYPE}); + setEditorWidgetCreator([] { return new QbsEditorWidget; }); +} + +void QbsEditorWidget::findLinkAt(const QTextCursor &cursor, const LinkHandler &processLinkCallback, + bool resolveTarget, bool inNextSplit) +{ + const LinkHandler extendedCallback = [self = QPointer(this), cursor, processLinkCallback, + resolveTarget](const Link &link) { + if (link.hasValidTarget()) + return processLinkCallback(link); + if (!self) + return; + const auto doc = self->textDocument(); + if (!doc) + return; + const QList &candidates = LanguageClientManager::clientsSupportingDocument(doc); + for (Client * const candidate : candidates) { + const auto qbsClient = qobject_cast(candidate); + if (!qbsClient || !qbsClient->isActive() || !qbsClient->documentOpen(doc)) + continue; + qbsClient->findLinkAt(doc, cursor, processLinkCallback, resolveTarget, + LinkTarget::SymbolDef); + } + }; + QmlJSEditorWidget::findLinkAt(cursor, extendedCallback, resolveTarget, inNextSplit); +} + +} // namespace QbsProjectManager::Internal diff --git a/src/plugins/qbsprojectmanager/qbseditor.h b/src/plugins/qbsprojectmanager/qbseditor.h new file mode 100644 index 00000000000..e1f7805ea02 --- /dev/null +++ b/src/plugins/qbsprojectmanager/qbseditor.h @@ -0,0 +1,16 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +namespace QbsProjectManager::Internal { + +class QbsEditorFactory : public QmlJSEditor::QmlJSEditorFactory +{ +public: + QbsEditorFactory(); +}; + +} // namespace QbsProjectManager::Internal diff --git a/src/plugins/qbsprojectmanager/qbslanguageclient.cpp b/src/plugins/qbsprojectmanager/qbslanguageclient.cpp new file mode 100644 index 00000000000..e067d4ae37f --- /dev/null +++ b/src/plugins/qbsprojectmanager/qbslanguageclient.cpp @@ -0,0 +1,90 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "qbslanguageclient.h" + +#include "qbsproject.h" +#include "qbssettings.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +using namespace Core; +using namespace LanguageClient; +using namespace TextEditor; +using namespace Utils; + +namespace QbsProjectManager::Internal { + +class QbsLanguageClientInterface : public LocalSocketClientInterface +{ +public: + QbsLanguageClientInterface(const QString &serverPath) + : LocalSocketClientInterface(serverPath), + m_qbsExecutable(QbsSettings::qbsExecutableFilePath()) {} + +private: + Utils::FilePath serverDeviceTemplate() const override{ return m_qbsExecutable; }; + + const FilePath m_qbsExecutable; +}; + +class QbsLanguageClient::Private +{ +public: + Private(QbsLanguageClient * q) : q(q) {} + + void checkDocument(IDocument *document); + + QbsLanguageClient * const q; + QPointer buildSystem; +}; + + +QbsLanguageClient::QbsLanguageClient(const QString &serverPath, QbsBuildSystem *buildSystem) + : Client(new QbsLanguageClientInterface(serverPath)), d(new Private(this)) +{ + d->buildSystem = buildSystem; + setName(QString::fromLatin1("qbs@%1").arg(serverPath)); + setCurrentProject(buildSystem->project()); + LanguageFilter langFilter; + langFilter.mimeTypes << Utils::Constants::QBS_MIMETYPE; + setSupportedLanguage(langFilter); + connect(EditorManager::instance(), &EditorManager::documentOpened, + this, [this](IDocument *document) { d->checkDocument(document); }); + const QList &allDocuments = DocumentModel::openedDocuments(); + for (IDocument * const document : allDocuments) + d->checkDocument(document); + start(); +} + +QbsLanguageClient::~QbsLanguageClient() { delete d; } + +bool QbsLanguageClient::isActive() const +{ + if (!d->buildSystem) + return false; + if (!d->buildSystem->target()->activeBuildConfiguration()) + return false; + if (d->buildSystem->target()->activeBuildConfiguration()->buildSystem() != d->buildSystem) + return false; + if (d->buildSystem->project()->activeTarget() != d->buildSystem->target()) + return false; + return true; +} + +void QbsLanguageClient::Private::checkDocument(IDocument *document) +{ + if (const auto doc = qobject_cast(document)) + q->openDocument(doc); +} + +} // namespace QbsProjectManager::Internal diff --git a/src/plugins/qbsprojectmanager/qbslanguageclient.h b/src/plugins/qbsprojectmanager/qbslanguageclient.h new file mode 100644 index 00000000000..8421dbfbfd2 --- /dev/null +++ b/src/plugins/qbsprojectmanager/qbslanguageclient.h @@ -0,0 +1,25 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +namespace QbsProjectManager::Internal { +class QbsBuildSystem; + +class QbsLanguageClient : public LanguageClient::Client +{ + Q_OBJECT +public: + QbsLanguageClient(const QString &serverPath, QbsBuildSystem *buildSystem); + ~QbsLanguageClient() override; + + bool isActive() const; + +private: + class Private; + Private * const d; +}; + +} // namespace QbsProjectManager::Internal diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs index dec42fd8902..709043df235 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs +++ b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs @@ -11,11 +11,13 @@ QtcPlugin { Depends { name: "QmlJS" } Depends { name: "Utils" } - Depends { name: "ProjectExplorer" } Depends { name: "Core" } Depends { name: "CppEditor" } - Depends { name: "QtSupport" } + Depends { name: "LanguageClient" } + Depends { name: "ProjectExplorer" } + Depends { name: "QmlJSEditor" } Depends { name: "QmlJSTools" } + Depends { name: "QtSupport" } files: [ "customqbspropertiesdialog.h", @@ -29,10 +31,14 @@ QtcPlugin { "qbsbuildstep.h", "qbscleanstep.cpp", "qbscleanstep.h", + "qbseditor.cpp", + "qbseditor.h", "qbsinstallstep.cpp", "qbsinstallstep.h", "qbskitaspect.cpp", "qbskitaspect.h", + "qbslanguageclient.cpp", + "qbslanguageclient.h", "qbsnodes.cpp", "qbsnodes.h", "qbsnodetreebuilder.cpp", @@ -48,7 +54,8 @@ QtcPlugin { "qbsprojectimporter.cpp", "qbsprojectimporter.h", "qbsprojectmanager.qrc", - "qbsprojectmanager_global.h", "qbsprojectmanagertr.h", + "qbsprojectmanager_global.h", + "qbsprojectmanagertr.h", "qbsprojectmanagerconstants.h", "qbsprojectmanagerplugin.cpp", "qbsprojectmanagerplugin.h", diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp index 546634d7926..ea8c9217ccc 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp +++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp @@ -6,6 +6,7 @@ #include "qbsbuildconfiguration.h" #include "qbsbuildstep.h" #include "qbscleanstep.h" +#include "qbseditor.h" #include "qbsinstallstep.h" #include "qbsnodes.h" #include "qbsprofilessettingspage.h" @@ -68,6 +69,7 @@ public: QbsInstallStepFactory installStepFactory; QbsSettingsPage settingsPage; QbsProfilesSettingsPage profilesSetttingsPage; + QbsEditorFactory editorFactory; }; QbsProjectManagerPlugin::~QbsProjectManagerPlugin() diff --git a/src/plugins/qbsprojectmanager/qbssession.cpp b/src/plugins/qbsprojectmanager/qbssession.cpp index 999e83d2d79..bde6f907f92 100644 --- a/src/plugins/qbsprojectmanager/qbssession.cpp +++ b/src/plugins/qbsprojectmanager/qbssession.cpp @@ -3,7 +3,9 @@ #include "qbssession.h" +#include "qbslanguageclient.h" #include "qbspmlogging.h" +#include "qbsproject.h" #include "qbsprojectmanagerconstants.h" #include "qbsprojectmanagertr.h" #include "qbssettings.h" @@ -130,6 +132,7 @@ class QbsSession::Private { public: Process *qbsProcess = nullptr; + QbsLanguageClient *languageClient = nullptr; PacketReader *packetReader = nullptr; QJsonObject currentRequest; QJsonObject projectData; @@ -140,7 +143,7 @@ public: State state = State::Inactive; }; -QbsSession::QbsSession(QObject *parent) : QObject(parent), d(new Private) +QbsSession::QbsSession(QbsBuildSystem *buildSystem) : QObject(buildSystem), d(new Private) { initialize(); } @@ -449,6 +452,12 @@ void QbsSession::handlePacket(const QJsonObject &packet) setError(Error::VersionMismatch); return; } + if (packet.value("api-level").toInt() > 4) { + const QString lspSocket = packet.value("lsp-socket").toString(); + if (!lspSocket.isEmpty()) + d->languageClient = new QbsLanguageClient(lspSocket, + static_cast(parent())); + } d->state = State::Active; sendQueuedRequest(); } else if (type == "project-resolved") { @@ -567,6 +576,7 @@ void QbsSession::setInactive() if (d->qbsProcess->state() == QProcess::Running) sendQuitPacket(); d->qbsProcess = nullptr; + d->languageClient = nullptr; // Owned by LanguageClientManager } FileChangeResult QbsSession::updateFileList(const char *action, const QStringList &files, diff --git a/src/plugins/qbsprojectmanager/qbssession.h b/src/plugins/qbsprojectmanager/qbssession.h index 1a20213f9d6..670388a5bbb 100644 --- a/src/plugins/qbsprojectmanager/qbssession.h +++ b/src/plugins/qbsprojectmanager/qbssession.h @@ -19,6 +19,7 @@ namespace ProjectExplorer { class Target; } namespace QbsProjectManager { namespace Internal { +class QbsBuildSystem; class ErrorInfoItem { @@ -96,7 +97,7 @@ class QbsSession : public QObject { Q_OBJECT public: - explicit QbsSession(QObject *parent = nullptr); + explicit QbsSession(QbsBuildSystem *buildSystem); ~QbsSession() override; enum class State { Initializing, Active, Inactive }; diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index a590c0fd834..a8cdb569269 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -1134,7 +1134,6 @@ QmlJSEditorFactory::QmlJSEditorFactory(Utils::Id _id) using namespace Utils::Constants; addMimeType(QML_MIMETYPE); addMimeType(QMLPROJECT_MIMETYPE); - addMimeType(QBS_MIMETYPE); addMimeType(QMLTYPES_MIMETYPE); addMimeType(JS_MIMETYPE); From 3bbda8f9daf2d18fe6f973c7a7854ff81ffbdb85 Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 24 Nov 2023 17:55:50 +0100 Subject: [PATCH 0383/1546] ProjectExplorer: Rename Tool{C,c}hainKitAspect Change-Id: I74460b6402ab00f972c208023f03fac617982a11 Reviewed-by: Christian Kandeler Reviewed-by: --- src/plugins/android/androidconfigurations.cpp | 6 +- src/plugins/android/androidmanager.cpp | 2 +- .../androidpackageinstallationstep.cpp | 2 +- src/plugins/autotest/autotestunittests.cpp | 2 +- src/plugins/autotest/loadprojectscenario.cpp | 2 +- src/plugins/clangtools/clangtool.cpp | 2 +- .../clangtoolspreconfiguredsessiontests.cpp | 2 +- .../clangtools/clangtoolsunittests.cpp | 4 +- .../cmakebuildconfiguration.cpp | 4 +- .../cmakeprojectmanager/cmakebuildstep.cpp | 2 +- .../cmakeprojectmanager/cmakekitaspect.cpp | 6 +- .../cmakeprojectmanager/cmakeproject.cpp | 2 +- .../cmakeprojectimporter.cpp | 8 +- .../cmakeprojectmanager.cpp | 4 +- .../compilationdatabaseproject.cpp | 4 +- src/plugins/conan/conaninstallstep.cpp | 6 +- src/plugins/cppcheck/cppcheckplugin.cpp | 2 +- src/plugins/cppeditor/cppmodelmanager.cpp | 6 +- src/plugins/debugger/debuggerkitaspect.cpp | 4 +- src/plugins/debugger/debuggerplugin.cpp | 8 +- src/plugins/debugger/debuggerruncontrol.cpp | 2 +- .../debugger/unstartedappwatcherdialog.cpp | 2 +- src/plugins/docker/kitdetector.cpp | 4 +- .../incredibuild/makecommandbuilder.cpp | 2 +- src/plugins/ios/iosbuildstep.cpp | 4 +- src/plugins/ios/iosconfigurations.cpp | 14 +- src/plugins/mcusupport/mcukitmanager.cpp | 4 +- .../mesonprojectmanager/mesonproject.cpp | 2 +- src/plugins/nim/project/nimbuildsystem.cpp | 2 +- .../nim/project/nimcompilerbuildstep.cpp | 2 +- src/plugins/nim/project/nimproject.cpp | 2 +- src/plugins/perfprofiler/perfdatareader.cpp | 2 +- src/plugins/projectexplorer/kitaspects.cpp | 124 +++++++++--------- src/plugins/projectexplorer/kitaspects.h | 2 +- src/plugins/projectexplorer/kitmanager.cpp | 10 +- src/plugins/projectexplorer/makestep.cpp | 2 +- src/plugins/projectexplorer/project.cpp | 4 +- .../projectexplorer/projectimporter.cpp | 8 +- .../projectexplorer/rawprojectpart.cpp | 4 +- .../defaultpropertyprovider.cpp | 4 +- .../qbsprojectmanager/qbsprojectimporter.cpp | 8 +- .../qmakebuildconfiguration.cpp | 2 +- .../qmakeprojectmanager/qmakekitaspect.cpp | 2 +- .../qmakeprojectmanager/qmakemakestep.cpp | 2 +- .../qmakeprojectmanager/qmakeproject.cpp | 12 +- .../qmakeprojectimporter.cpp | 4 +- src/plugins/qmakeprojectmanager/qmakestep.cpp | 2 +- src/plugins/qnx/qnxsettingspage.cpp | 8 +- src/plugins/qtsupport/baseqtversion.cpp | 4 +- src/plugins/qtsupport/qtkitaspect.cpp | 10 +- src/plugins/valgrind/memchecktool.cpp | 2 +- 51 files changed, 167 insertions(+), 167 deletions(-) diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index 0016cd3f6bf..8cf6d186a1e 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -1387,9 +1387,9 @@ void AndroidConfigurations::updateAutomaticKitList() if (qt != QtKitAspect::qtVersion(b)) return false; return matchToolChain(toolChainForLanguage[ProjectExplorer::Constants::CXX_LANGUAGE_ID], - ToolChainKitAspect::cxxToolChain(b)) + ToolchainKitAspect::cxxToolChain(b)) && matchToolChain(toolChainForLanguage[ProjectExplorer::Constants::C_LANGUAGE_ID], - ToolChainKitAspect::cToolChain(b)); + ToolchainKitAspect::cToolChain(b)); }); const auto initializeKit = [allLanguages, tc, qt](Kit *k) { @@ -1397,7 +1397,7 @@ void AndroidConfigurations::updateAutomaticKitList() k->setAutoDetectionSource("AndroidConfiguration"); DeviceTypeKitAspect::setDeviceTypeId(k, Constants::ANDROID_DEVICE_TYPE); for (Toolchain *tc : allLanguages) - ToolChainKitAspect::setToolChain(k, tc); + ToolchainKitAspect::setToolChain(k, tc); QtKitAspect::setQtVersion(k, qt); QStringList abis = static_cast(qt)->androidAbis(); Debugger::DebuggerKitAspect::setDebugger(k, findOrRegisterDebugger(tc, abis)); diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index aa8e3fe43aa..cf665d2d15e 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -183,7 +183,7 @@ QJsonObject deploymentSettings(const Target *target) if (!qt) return {}; - auto tc = ToolChainKitAspect::cxxToolChain(target->kit()); + auto tc = ToolchainKitAspect::cxxToolChain(target->kit()); if (!tc || tc->typeId() != Constants::ANDROID_TOOLCHAIN_TYPEID) return {}; QJsonObject settings; diff --git a/src/plugins/android/androidpackageinstallationstep.cpp b/src/plugins/android/androidpackageinstallationstep.cpp index a67c4c425f0..fecc3db998f 100644 --- a/src/plugins/android/androidpackageinstallationstep.cpp +++ b/src/plugins/android/androidpackageinstallationstep.cpp @@ -73,7 +73,7 @@ bool AndroidPackageInstallationStep::init() return false; } - Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit()); + Toolchain *tc = ToolchainKitAspect::cxxToolChain(kit()); QTC_ASSERT(tc, reportWarningOrError(Tr::tr("\"%1\" step has an invalid C++ toolchain.") .arg(displayName()), Task::TaskType::Error); return false); diff --git a/src/plugins/autotest/autotestunittests.cpp b/src/plugins/autotest/autotestunittests.cpp index 7f3a55d577c..e016afbbb85 100644 --- a/src/plugins/autotest/autotestunittests.cpp +++ b/src/plugins/autotest/autotestunittests.cpp @@ -59,7 +59,7 @@ void AutoTestUnitTests::initTestCase() m_isQt4 = qtVersion->qtVersionString().startsWith('4'); else QSKIP("Could not figure out which Qt version is used for default kit."); - const Toolchain * const toolchain = ToolChainKitAspect::cxxToolChain(m_kit); + const Toolchain * const toolchain = ToolchainKitAspect::cxxToolChain(m_kit); if (!toolchain) QSKIP("This test requires that there is a kit with a toolchain."); diff --git a/src/plugins/autotest/loadprojectscenario.cpp b/src/plugins/autotest/loadprojectscenario.cpp index 0b18eaab518..50d62d22b0f 100644 --- a/src/plugins/autotest/loadprojectscenario.cpp +++ b/src/plugins/autotest/loadprojectscenario.cpp @@ -56,7 +56,7 @@ bool LoadProjectScenario::init() return false; } - const Toolchain * const toolchain = ToolChainKitAspect::cxxToolChain(m_kit); + const Toolchain * const toolchain = ToolchainKitAspect::cxxToolChain(m_kit); if (!toolchain) { qWarning() << "This test requires that there is a kit with a toolchain."; return false; diff --git a/src/plugins/clangtools/clangtool.cpp b/src/plugins/clangtools/clangtool.cpp index 7d9d13b4c65..27cc59bb60b 100644 --- a/src/plugins/clangtools/clangtool.cpp +++ b/src/plugins/clangtools/clangtool.cpp @@ -1034,7 +1034,7 @@ static bool canAnalyzeProject(Project *project) || project->projectLanguages().contains(cxx); return projectSupportsLanguage && CppModelManager::projectInfo(project) - && ToolChainKitAspect::cxxToolChain(target->kit()); + && ToolchainKitAspect::cxxToolChain(target->kit()); } return false; } diff --git a/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp b/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp index d08a68633b5..fdadc30451b 100644 --- a/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp +++ b/src/plugins/clangtools/clangtoolspreconfiguredsessiontests.cpp @@ -148,7 +148,7 @@ static QList validTargets(Project *project) return false; } - const Toolchain * const toolchain = ToolChainKitAspect::cxxToolChain(kit); + const Toolchain * const toolchain = ToolchainKitAspect::cxxToolChain(kit); QTC_ASSERT(toolchain, return false); if (Core::ICore::clangExecutable(CLANG_BINDIR).isEmpty()) { diff --git a/src/plugins/clangtools/clangtoolsunittests.cpp b/src/plugins/clangtools/clangtoolsunittests.cpp index 086afe118f0..b985f0503af 100644 --- a/src/plugins/clangtools/clangtoolsunittests.cpp +++ b/src/plugins/clangtools/clangtoolsunittests.cpp @@ -50,7 +50,7 @@ void ClangToolsUnitTests::initTestCase() if (!m_kit) QSKIP("This test requires at least one valid kit with a valid Qt"); - const Toolchain * const toolchain = ToolChainKitAspect::cxxToolChain(m_kit); + const Toolchain * const toolchain = ToolchainKitAspect::cxxToolChain(m_kit); if (!toolchain) QSKIP("This test requires that there is a kit with a toolchain."); @@ -87,7 +87,7 @@ void ClangToolsUnitTests::testProject() QFETCH(int, expectedDiagCountClazy); QFETCH(ClangDiagnosticConfig, diagnosticConfig); if (projectFilePath.contains("mingw")) { - const auto toolchain = ToolChainKitAspect::cxxToolChain(m_kit); + const auto toolchain = ToolchainKitAspect::cxxToolChain(m_kit); if (toolchain->typeId() != ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID) QSKIP("This test is mingw specific, does not run for other toolchains"); } diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 27b9c6348df..a9634eccf0e 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -1091,7 +1091,7 @@ static bool isQnx(const Kit *k) static bool isWindowsARM64(const Kit *k) { - Toolchain *toolchain = ToolChainKitAspect::cxxToolChain(k); + Toolchain *toolchain = ToolchainKitAspect::cxxToolChain(k); if (!toolchain) return false; const Abi targetAbi = toolchain->targetAbi(); @@ -1124,7 +1124,7 @@ static CommandLine defaultInitialCMakeCommand(const Kit *k, const QString &build const QString sysRoot = SysRootKitAspect::sysRoot(k).path(); if (!sysRoot.isEmpty()) { cmd.addArg("-DCMAKE_SYSROOT:PATH=" + sysRoot); - if (Toolchain *tc = ToolChainKitAspect::cxxToolChain(k)) { + if (Toolchain *tc = ToolchainKitAspect::cxxToolChain(k)) { const QString targetTriple = tc->originalTargetTriple(); cmd.addArg("-DCMAKE_C_COMPILER_TARGET:STRING=" + targetTriple); cmd.addArg("-DCMAKE_CXX_COMPILER_TARGET:STRING=" + targetTriple); diff --git a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp index e2c3e963f6c..8bd3b378499 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildstep.cpp @@ -335,7 +335,7 @@ void CMakeBuildStep::setupOutputFormatter(Utils::OutputFormatter *formatter) formatter->addLineParser(progressParser); cmakeParser->setSourceDirectory(project()->projectDirectory()); formatter->addLineParsers({cmakeParser, new GnuMakeParser}); - Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit()); + Toolchain *tc = ToolchainKitAspect::cxxToolChain(kit()); OutputTaskParser *xcodeBuildParser = nullptr; if (tc && tc->targetAbi().os() == Abi::DarwinOS) { xcodeBuildParser = new XcodebuildParser; diff --git a/src/plugins/cmakeprojectmanager/cmakekitaspect.cpp b/src/plugins/cmakeprojectmanager/cmakekitaspect.cpp index bca89be9b18..9a9e09c65c6 100644 --- a/src/plugins/cmakeprojectmanager/cmakekitaspect.cpp +++ b/src/plugins/cmakeprojectmanager/cmakekitaspect.cpp @@ -681,7 +681,7 @@ QVariant CMakeGeneratorKitAspectFactory::defaultValue(const Kit *k) const if (tool->filePath().osType() == OsTypeWindows) { // *sigh* Windows with its zoo of incompatible stuff again... - Toolchain *tc = ToolChainKitAspect::cxxToolChain(k); + Toolchain *tc = ToolchainKitAspect::cxxToolChain(k); if (tc && tc->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID) { it = std::find_if(known.constBegin(), known.constEnd(), @@ -1135,8 +1135,8 @@ Tasks CMakeConfigurationKitAspectFactory::validate(const Kit *k) const return Tasks(); const QtSupport::QtVersion *const version = QtSupport::QtKitAspect::qtVersion(k); - const Toolchain *const tcC = ToolChainKitAspect::cToolChain(k); - const Toolchain *const tcCxx = ToolChainKitAspect::cxxToolChain(k); + const Toolchain *const tcC = ToolchainKitAspect::cToolChain(k); + const Toolchain *const tcCxx = ToolchainKitAspect::cxxToolChain(k); const CMakeConfig config = CMakeConfigurationKitAspect::configuration(k); const bool isQt4 = version && version->qtVersion() < QVersionNumber(5, 0, 0); diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 084925c8fc1..3a79e4a376e 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -58,7 +58,7 @@ Tasks CMakeProject::projectIssues(const Kit *k) const if (!CMakeKitAspect::cmakeTool(k)) result.append(createProjectTask(Task::TaskType::Error, Tr::tr("No cmake tool set."))); - if (ToolChainKitAspect::toolChains(k).isEmpty()) + if (ToolchainKitAspect::toolChains(k).isEmpty()) result.append(createProjectTask(Task::TaskType::Warning, Tr::tr("No compilers set in kit."))); result.append(m_issues); diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index de05b51d2a0..c38dc44054f 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -937,7 +937,7 @@ bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const if (!Utils::contains(allLanguages, [&tcd](const Id &language) { return language == tcd.language; })) continue; - Toolchain *tc = ToolChainKitAspect::toolChain(k, tcd.language); + Toolchain *tc = ToolchainKitAspect::toolChain(k, tcd.language); if ((!tc || !tc->matchesCompilerCommand(tcd.compilerPath))) { return false; } @@ -950,7 +950,7 @@ bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const if (!Utils::contains(allLanguages, [&tcd](const Id &language) { return language == tcd.language; })) continue; - Toolchain *tc = ToolChainKitAspect::toolChain(k, tcd.language); + Toolchain *tc = ToolchainKitAspect::toolChain(k, tcd.language); if (tc && tc->matchesCompilerCommand(tcd.compilerPath)) { return false; } @@ -1001,10 +1001,10 @@ Kit *CMakeProjectImporter::createKit(void *directoryData) const if (tcd.areTemporary) { for (Toolchain *tc : tcd.tcs) - addTemporaryData(ToolChainKitAspect::id(), tc->id(), k); + addTemporaryData(ToolchainKitAspect::id(), tc->id(), k); } - ToolChainKitAspect::setToolChain(k, tcd.tcs.at(0)); + ToolchainKitAspect::setToolChain(k, tcd.tcs.at(0)); } if (!data->cmakePresetDisplayname.isEmpty()) { diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp index 886caa47f51..2637d05d63b 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp @@ -407,8 +407,8 @@ void CMakeManager::buildFile(Node *node) return extension; const auto toolchain = ProjectFile::isCxx(sourceKind) - ? ToolChainKitAspect::cxxToolChain(target->kit()) - : ToolChainKitAspect::cToolChain(target->kit()); + ? ToolchainKitAspect::cxxToolChain(target->kit()) + : ToolchainKitAspect::cToolChain(target->kit()); using namespace ProjectExplorer::Constants; static QSet objIds{ CLANG_CL_TOOLCHAIN_TYPEID, diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp index f1cda0f9411..67fcd19d2c4 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp @@ -108,7 +108,7 @@ QString compilerPath(QString pathFlag) Toolchain *toolchainFromFlags(const Kit *kit, const QStringList &flags, const Utils::Id &language) { if (flags.empty()) - return ToolChainKitAspect::toolChain(kit, language); + return ToolchainKitAspect::toolChain(kit, language); // Try exact compiler match. const Utils::FilePath compiler = Utils::FilePath::fromUserInput(compilerPath(flags.front())); @@ -131,7 +131,7 @@ Toolchain *toolchainFromFlags(const Kit *kit, const QStringList &flags, const Ut return toolchain; } - toolchain = ToolChainKitAspect::toolChain(kit, language); + toolchain = ToolchainKitAspect::toolChain(kit, language); qWarning() << "No matching toolchain found, use the default."; return toolchain; } diff --git a/src/plugins/conan/conaninstallstep.cpp b/src/plugins/conan/conaninstallstep.cpp index ae28bfb1b47..30d4f09697e 100644 --- a/src/plugins/conan/conaninstallstep.cpp +++ b/src/plugins/conan/conaninstallstep.cpp @@ -104,9 +104,9 @@ ConanInstallStep::ConanInstallStep(BuildStepList *bsl, Id id) }); setSummaryUpdater([this]() -> QString { - QList tcList = ToolChainKitAspect::toolChains(target()->kit()); + QList tcList = ToolchainKitAspect::toolChains(target()->kit()); if (tcList.isEmpty()) - return "" + ToolChainKitAspect::msgNoToolChainInTarget() + ""; + return "" + ToolchainKitAspect::msgNoToolChainInTarget() + ""; ProcessParameters param; setupProcessParameters(¶m); return param.summary(displayName()); @@ -124,7 +124,7 @@ bool ConanInstallStep::init() if (!AbstractProcessStep::init()) return false; - const QList tcList = ToolChainKitAspect::toolChains(target()->kit()); + const QList tcList = ToolchainKitAspect::toolChains(target()->kit()); if (tcList.isEmpty()) { emit addTask(Task::compilerMissingTask()); emitFaultyConfigurationMessage(); diff --git a/src/plugins/cppcheck/cppcheckplugin.cpp b/src/plugins/cppcheck/cppcheckplugin.cpp index 44381c235ee..4ec26eb73a3 100644 --- a/src/plugins/cppcheck/cppcheckplugin.cpp +++ b/src/plugins/cppcheck/cppcheckplugin.cpp @@ -135,7 +135,7 @@ void CppcheckPluginPrivate::updateManualRunAction() const Target *target = ProjectManager::startupTarget(); const Utils::Id cxx = ProjectExplorer::Constants::CXX_LANGUAGE_ID; const bool canRun = target && project->projectLanguages().contains(cxx) - && ToolChainKitAspect::cxxToolChain(target->kit()); + && ToolchainKitAspect::cxxToolChain(target->kit()); manualRunAction->setEnabled(canRun); } diff --git a/src/plugins/cppeditor/cppmodelmanager.cpp b/src/plugins/cppeditor/cppmodelmanager.cpp index ee94f84ee57..ac5c76ba0a7 100644 --- a/src/plugins/cppeditor/cppmodelmanager.cpp +++ b/src/plugins/cppeditor/cppmodelmanager.cpp @@ -412,9 +412,9 @@ void CppModelManager::showPreprocessedFile(bool inNextSplit) const Toolchain * tc = nullptr; const ProjectFile classifier(filePath, ProjectFile::classify(filePath.toString())); if (classifier.isC()) { - tc = ToolChainKitAspect::cToolChain(project->activeTarget()->kit()); + tc = ToolchainKitAspect::cToolChain(project->activeTarget()->kit()); } else if (classifier.isCxx() || classifier.isHeader()) { - tc = ToolChainKitAspect::cxxToolChain(project->activeTarget()->kit()); + tc = ToolchainKitAspect::cxxToolChain(project->activeTarget()->kit()); } else { showFallbackWarning(Tr::tr("Could not determine which compiler to invoke.")); useBuiltinPreprocessor(); @@ -1965,7 +1965,7 @@ void CppModelManager::setupFallbackProjectPart() // TODO: Use different fallback toolchain for different kinds of files? const Kit * const defaultKit = KitManager::isLoaded() ? KitManager::defaultKit() : nullptr; const Toolchain * const defaultTc = defaultKit - ? ToolChainKitAspect::cxxToolChain(defaultKit) : nullptr; + ? ToolchainKitAspect::cxxToolChain(defaultKit) : nullptr; if (defaultKit && defaultTc) { FilePath sysroot = SysRootKitAspect::sysRoot(defaultKit); if (sysroot.isEmpty()) diff --git a/src/plugins/debugger/debuggerkitaspect.cpp b/src/plugins/debugger/debuggerkitaspect.cpp index fdc6f776902..02f21c582a2 100644 --- a/src/plugins/debugger/debuggerkitaspect.cpp +++ b/src/plugins/debugger/debuggerkitaspect.cpp @@ -148,7 +148,7 @@ DebuggerKitAspect::ConfigurationErrors DebuggerKitAspect::configurationErrors(co if (!debugger.isExecutableFile()) result |= DebuggerNotExecutable; - const Abi tcAbi = ToolChainKitAspect::targetAbi(k); + const Abi tcAbi = ToolchainKitAspect::targetAbi(k); if (item->matchTarget(tcAbi) == DebuggerItem::DoesNotMatch) { // currently restricting the check to desktop devices, may be extended to all device types const IDevice::ConstPtr device = DeviceKitAspect::device(k); @@ -303,7 +303,7 @@ public: // const QVariant rawId = k->value(DebuggerKitAspectFactory::id()); - const Abi tcAbi = ToolChainKitAspect::targetAbi(k); + const Abi tcAbi = ToolchainKitAspect::targetAbi(k); // Get the best of the available debugger matching the kit's toolchain. // The general idea is to find an item that exactly matches what diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index ecb655f6c0e..cbfe4b7b2b6 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -533,7 +533,7 @@ static Kit::Predicate cdbPredicate(char wordWidth = 0) return false; } if (wordWidth) - return ToolChainKitAspect::targetAbi(k).wordWidth() == wordWidth; + return ToolchainKitAspect::targetAbi(k).wordWidth() == wordWidth; return true; }; } @@ -1308,13 +1308,13 @@ static Kit *guessKitFromAbis(const Abis &abis) if (!abis.isEmpty()) { // Try exact abis. kit = KitManager::kit([abis](const Kit *k) { - const Abi tcAbi = ToolChainKitAspect::targetAbi(k); + const Abi tcAbi = ToolchainKitAspect::targetAbi(k); return abis.contains(tcAbi) && !DebuggerKitAspect::configurationErrors(k); }); if (!kit) { // Or something compatible. kit = KitManager::kit([abis](const Kit *k) { - const Abi tcAbi = ToolChainKitAspect::targetAbi(k); + const Abi tcAbi = ToolchainKitAspect::targetAbi(k); return !DebuggerKitAspect::configurationErrors(k) && Utils::contains(abis, [tcAbi](const Abi &a) { return a.isCompatibleWith(tcAbi); }); }); @@ -1764,7 +1764,7 @@ RunControl *DebuggerPluginPrivate::attachToRunningProcess(Kit *kit, return nullptr; } - const Abi tcAbi = ToolChainKitAspect::targetAbi(kit); + const Abi tcAbi = ToolchainKitAspect::targetAbi(kit); const bool isWindows = (tcAbi.os() == Abi::WindowsOS); if (isWindows && isWinProcessBeingDebugged(processInfo.processId)) { AsynchronousMessageBox::warning( diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index a12c8cec40d..ed4968cdd93 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -900,7 +900,7 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm m_runParameters.projectSourceFiles.clear(); } - m_runParameters.toolChainAbi = ToolChainKitAspect::targetAbi(kit); + m_runParameters.toolChainAbi = ToolchainKitAspect::targetAbi(kit); bool ok = false; const int nativeMixedOverride = qtcEnvironmentVariableIntValue("QTC_DEBUGGER_NATIVE_MIXED", &ok); diff --git a/src/plugins/debugger/unstartedappwatcherdialog.cpp b/src/plugins/debugger/unstartedappwatcherdialog.cpp index e120571839e..9a657c4fadd 100644 --- a/src/plugins/debugger/unstartedappwatcherdialog.cpp +++ b/src/plugins/debugger/unstartedappwatcherdialog.cpp @@ -72,7 +72,7 @@ UnstartedAppWatcherDialog::UnstartedAppWatcherDialog(QWidget *parent) m_kitChooser = new KitChooser(this); m_kitChooser->setKitPredicate([](const Kit *k) { - return ToolChainKitAspect::targetAbi(k).os() == Abi::hostAbi().os(); + return ToolchainKitAspect::targetAbi(k).os() == Abi::hostAbi().os(); }); m_kitChooser->setShowIcons(true); m_kitChooser->populate(); diff --git a/src/plugins/docker/kitdetector.cpp b/src/plugins/docker/kitdetector.cpp index 405ea76032b..d2176760fad 100644 --- a/src/plugins/docker/kitdetector.cpp +++ b/src/plugins/docker/kitdetector.cpp @@ -364,12 +364,12 @@ void KitDetectorPrivate::autoDetect() && (!qt || qt->qtAbis().contains(tc->targetAbi())); }); for (Toolchain *toolChain : toolchainsToSet) - ToolChainKitAspect::setToolChain(k, toolChain); + ToolchainKitAspect::setToolChain(k, toolChain); if (cmakeId.isValid()) k->setSticky(CMakeProjectManager::Constants::TOOL_ID, true); - k->setSticky(ToolChainKitAspect::id(), true); + k->setSticky(ToolchainKitAspect::id(), true); k->setSticky(QtSupport::QtKitAspect::id(), true); k->setSticky(DeviceKitAspect::id(), true); k->setSticky(DeviceTypeKitAspect::id(), true); diff --git a/src/plugins/incredibuild/makecommandbuilder.cpp b/src/plugins/incredibuild/makecommandbuilder.cpp index 9e16c7fe1fd..60b88f981f6 100644 --- a/src/plugins/incredibuild/makecommandbuilder.cpp +++ b/src/plugins/incredibuild/makecommandbuilder.cpp @@ -37,7 +37,7 @@ FilePath MakeCommandBuilder::defaultCommand() const { if (BuildConfiguration *buildConfig = buildStep()->buildConfiguration()) { if (Target *target = buildStep()->target()) { - if (Toolchain *toolChain = ToolChainKitAspect::cxxToolChain(target->kit())) + if (Toolchain *toolChain = ToolchainKitAspect::cxxToolChain(target->kit())) return toolChain->makeCommand(buildConfig->environment()); } } diff --git a/src/plugins/ios/iosbuildstep.cpp b/src/plugins/ios/iosbuildstep.cpp index 02ab577216c..8b692d493fd 100644 --- a/src/plugins/ios/iosbuildstep.cpp +++ b/src/plugins/ios/iosbuildstep.cpp @@ -148,7 +148,7 @@ bool IosBuildStep::init() if (!AbstractProcessStep::init()) return false; - Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit()); + Toolchain *tc = ToolchainKitAspect::cxxToolChain(kit()); if (!tc) { emit addTask(Task::compilerMissingTask()); emitFaultyConfigurationMessage(); @@ -195,7 +195,7 @@ QStringList IosBuildStep::defaultArguments() const { QStringList res; Kit *kit = target()->kit(); - Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit); + Toolchain *tc = ToolchainKitAspect::cxxToolChain(kit); switch (buildConfiguration()->buildType()) { case BuildConfiguration::Debug : res << "-configuration" << "Debug"; diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp index b59aae15f84..c205f3a6d59 100644 --- a/src/plugins/ios/iosconfigurations.cpp +++ b/src/plugins/ios/iosconfigurations.cpp @@ -171,13 +171,13 @@ static void setupKit(Kit *kit, Id pDeviceType, const ToolChainPair& toolChains, { DeviceTypeKitAspect::setDeviceTypeId(kit, pDeviceType); if (toolChains.first) - ToolChainKitAspect::setToolChain(kit, toolChains.first); + ToolchainKitAspect::setToolChain(kit, toolChains.first); else - ToolChainKitAspect::clearToolChain(kit, ProjectExplorer::Constants::C_LANGUAGE_ID); + ToolchainKitAspect::clearToolChain(kit, ProjectExplorer::Constants::C_LANGUAGE_ID); if (toolChains.second) - ToolChainKitAspect::setToolChain(kit, toolChains.second); + ToolchainKitAspect::setToolChain(kit, toolChains.second); else - ToolChainKitAspect::clearToolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID); + ToolchainKitAspect::clearToolChain(kit, ProjectExplorer::Constants::CXX_LANGUAGE_ID); QtKitAspect::setQtVersion(kit, qtVersion); // only replace debugger with the default one if we find an unusable one here @@ -190,7 +190,7 @@ static void setupKit(Kit *kit, Id pDeviceType, const ToolChainPair& toolChains, kit->setMutable(DeviceKitAspect::id(), true); kit->setSticky(QtKitAspect::id(), true); - kit->setSticky(ToolChainKitAspect::id(), true); + kit->setSticky(ToolchainKitAspect::id(), true); kit->setSticky(DeviceTypeKitAspect::id(), true); kit->setSticky(SysRootKitAspect::id(), true); kit->setSticky(DebuggerKitAspect::id(), false); @@ -274,8 +274,8 @@ void IosConfigurations::updateAutomaticKitList() // we do not compare the sdk (thus automatically upgrading it in place if a // new Xcode is used). Change? return DeviceTypeKitAspect::deviceTypeId(kit) == pDeviceType - && ToolChainKitAspect::cxxToolChain(kit) == platformToolchains.second - && ToolChainKitAspect::cToolChain(kit) == platformToolchains.first + && ToolchainKitAspect::cxxToolChain(kit) == platformToolchains.second + && ToolchainKitAspect::cToolChain(kit) == platformToolchains.first && QtKitAspect::qtVersion(kit) == qtVersion; }); QTC_ASSERT(!resultingKits.contains(kit), continue); diff --git a/src/plugins/mcusupport/mcukitmanager.cpp b/src/plugins/mcusupport/mcukitmanager.cpp index 2cc2311e693..f777b77f8e8 100644 --- a/src/plugins/mcusupport/mcukitmanager.cpp +++ b/src/plugins/mcusupport/mcukitmanager.cpp @@ -86,10 +86,10 @@ public: case McuToolChainPackage::ToolChainType::GCC: case McuToolChainPackage::ToolChainType::MinGW: case McuToolChainPackage::ToolChainType::ArmGcc: - ToolChainKitAspect::setToolChain(k, + ToolchainKitAspect::setToolChain(k, tcPackage->toolChain( ProjectExplorer::Constants::C_LANGUAGE_ID)); - ToolChainKitAspect::setToolChain(k, + ToolchainKitAspect::setToolChain(k, tcPackage->toolChain( ProjectExplorer::Constants::CXX_LANGUAGE_ID)); return; diff --git a/src/plugins/mesonprojectmanager/mesonproject.cpp b/src/plugins/mesonprojectmanager/mesonproject.cpp index 1566aa25533..5c3b77e54d5 100644 --- a/src/plugins/mesonprojectmanager/mesonproject.cpp +++ b/src/plugins/mesonprojectmanager/mesonproject.cpp @@ -39,7 +39,7 @@ Tasks MesonProject::projectIssues(const Kit *k) const if (!NinjaToolKitAspect::isValid(k)) result.append( createProjectTask(Task::TaskType::Error, Tr::tr("No Ninja tool set."))); - if (ToolChainKitAspect::toolChains(k).isEmpty()) + if (ToolchainKitAspect::toolChains(k).isEmpty()) result.append(createProjectTask(Task::TaskType::Warning, Tr::tr("No compilers set in kit."))); return result; diff --git a/src/plugins/nim/project/nimbuildsystem.cpp b/src/plugins/nim/project/nimbuildsystem.cpp index f07d8f607f3..ebfce4b9adc 100644 --- a/src/plugins/nim/project/nimbuildsystem.cpp +++ b/src/plugins/nim/project/nimbuildsystem.cpp @@ -169,7 +169,7 @@ void NimBuildSystem::triggerParsing() FilePath nimPathFromKit(Kit *kit) { - auto tc = ToolChainKitAspect::toolChain(kit, Constants::C_NIMLANGUAGE_ID); + auto tc = ToolchainKitAspect::toolChain(kit, Constants::C_NIMLANGUAGE_ID); QTC_ASSERT(tc, return {}); const FilePath command = tc->compilerCommand(); return command.isEmpty() ? FilePath() : command.absolutePath(); diff --git a/src/plugins/nim/project/nimcompilerbuildstep.cpp b/src/plugins/nim/project/nimcompilerbuildstep.cpp index eecd7d442c0..aa0eb6f2984 100644 --- a/src/plugins/nim/project/nimcompilerbuildstep.cpp +++ b/src/plugins/nim/project/nimcompilerbuildstep.cpp @@ -159,7 +159,7 @@ CommandLine NimCompilerBuildStep::commandLine() auto bc = qobject_cast(buildConfiguration()); QTC_ASSERT(bc, return {}); - auto tc = ToolChainKitAspect::toolChain(kit(), Constants::C_NIMLANGUAGE_ID); + auto tc = ToolchainKitAspect::toolChain(kit(), Constants::C_NIMLANGUAGE_ID); QTC_ASSERT(tc, return {}); CommandLine cmd{tc->compilerCommand()}; diff --git a/src/plugins/nim/project/nimproject.cpp b/src/plugins/nim/project/nimproject.cpp index 215820818b2..bfca6a92fa9 100644 --- a/src/plugins/nim/project/nimproject.cpp +++ b/src/plugins/nim/project/nimproject.cpp @@ -52,7 +52,7 @@ NimProject::NimProject(const FilePath &filePath) : Project(Constants::C_NIM_MIME Tasks NimProject::projectIssues(const Kit *k) const { Tasks result = Project::projectIssues(k); - auto tc = ToolChainKitAspect::toolChain(k, Constants::C_NIMLANGUAGE_ID); + auto tc = ToolchainKitAspect::toolChain(k, Constants::C_NIMLANGUAGE_ID); if (!tc) { result.append(createProjectTask(Task::TaskType::Error, Tr::tr("No Nim compiler set."))); return result; diff --git a/src/plugins/perfprofiler/perfdatareader.cpp b/src/plugins/perfprofiler/perfdatareader.cpp index 222e1c9788e..80b53b5cba8 100644 --- a/src/plugins/perfprofiler/perfdatareader.cpp +++ b/src/plugins/perfprofiler/perfdatareader.cpp @@ -288,7 +288,7 @@ void PerfDataReader::collectArguments(CommandLine *cmd, const QString &exe, cons .arg(cmd->executable().osType() == OsTypeWindows ? u';' : u':')); } - if (auto toolChain = ToolChainKitAspect::cxxToolChain(kit)) { + if (auto toolChain = ToolchainKitAspect::cxxToolChain(kit)) { Abi::Architecture architecture = toolChain->targetAbi().architecture(); if (architecture == Abi::ArmArchitecture && toolChain->targetAbi().wordWidth() == 64) { cmd->addArg("--arch"); diff --git a/src/plugins/projectexplorer/kitaspects.cpp b/src/plugins/projectexplorer/kitaspects.cpp index 6fd9808ab7c..218deea329c 100644 --- a/src/plugins/projectexplorer/kitaspects.cpp +++ b/src/plugins/projectexplorer/kitaspects.cpp @@ -160,7 +160,7 @@ FilePath SysRootKitAspect::sysRoot(const Kit *k) if (!k->value(SysRootKitAspect::id()).toString().isEmpty()) return FilePath::fromSettings(k->value(SysRootKitAspect::id())); - for (Toolchain *tc : ToolChainKitAspect::toolChains(k)) { + for (Toolchain *tc : ToolchainKitAspect::toolChains(k)) { if (!tc->sysRoot().isEmpty()) return FilePath::fromString(tc->sysRoot()); } @@ -172,7 +172,7 @@ void SysRootKitAspect::setSysRoot(Kit *k, const FilePath &v) if (!k) return; - for (Toolchain *tc : ToolChainKitAspect::toolChains(k)) { + for (Toolchain *tc : ToolchainKitAspect::toolChains(k)) { if (!tc->sysRoot().isEmpty()) { // It's the sysroot from toolchain, don't set it. if (tc->sysRoot() == v.toString()) @@ -188,14 +188,14 @@ void SysRootKitAspect::setSysRoot(Kit *k, const FilePath &v) const SysRootKitAspectFactory theSyRootKitAspectFactory; // -------------------------------------------------------------------------- -// ToolChainKitAspect: +// ToolchainKitAspect: // -------------------------------------------------------------------------- namespace Internal { -class ToolChainKitAspectImpl final : public KitAspect +class ToolchainKitAspectImpl final : public KitAspect { public: - ToolChainKitAspectImpl(Kit *k, const KitAspectFactory *factory) : KitAspect(k, factory) + ToolchainKitAspectImpl(Kit *k, const KitAspectFactory *factory) : KitAspect(k, factory) { m_mainWidget = createSubWidget(); m_mainWidget->setContentsMargins(0, 0, 0, 0); @@ -230,7 +230,7 @@ public: setManagingPage(Constants::TOOLCHAIN_SETTINGS_PAGE_ID); } - ~ToolChainKitAspectImpl() override + ~ToolchainKitAspectImpl() override { delete m_mainWidget; } @@ -272,7 +272,7 @@ private: cb->addItem(item->displayName(), item->id()); cb->setEnabled(cb->count() > 1 && !m_isReadOnly); - const int index = indexOf(cb, ToolChainKitAspect::toolChain(m_kit, l)); + const int index = indexOf(cb, ToolchainKitAspect::toolChain(m_kit, l)); cb->setCurrentIndex(index); } } @@ -295,9 +295,9 @@ private: Toolchain *tc = ToolChainManager::findToolChain(id); QTC_ASSERT(!tc || tc->language() == language, return); if (tc) - ToolChainKitAspect::setToolChain(m_kit, tc); + ToolchainKitAspect::setToolChain(m_kit, tc); else - ToolChainKitAspect::clearToolChain(m_kit, language); + ToolchainKitAspect::clearToolChain(m_kit, language); } int indexOf(QComboBox *cb, const Toolchain *tc) @@ -317,10 +317,10 @@ private: }; } // namespace Internal -class ToolChainKitAspectFactory : public KitAspectFactory +class ToolchainKitAspectFactory : public KitAspectFactory { public: - ToolChainKitAspectFactory(); + ToolchainKitAspectFactory(); private: Tasks validate(const Kit *k) const override; @@ -346,9 +346,9 @@ private: void toolChainRemoved(Toolchain *tc); }; -ToolChainKitAspectFactory::ToolChainKitAspectFactory() +ToolchainKitAspectFactory::ToolchainKitAspectFactory() { - setId(ToolChainKitAspect::id()); + setId(ToolchainKitAspect::id()); setDisplayName(Tr::tr("Compiler")); setDescription(Tr::tr("The compiler to use for building.
" "Make sure the compiler will produce binaries compatible " @@ -380,13 +380,13 @@ static Store defaultToolChainValue() return result; } -Tasks ToolChainKitAspectFactory::validate(const Kit *k) const +Tasks ToolchainKitAspectFactory::validate(const Kit *k) const { Tasks result; - const QList tcList = ToolChainKitAspect::toolChains(k); + const QList tcList = ToolchainKitAspect::toolChains(k); if (tcList.isEmpty()) { - result << BuildSystemTask(Task::Warning, ToolChainKitAspect::msgNoToolChainInTarget()); + result << BuildSystemTask(Task::Warning, ToolchainKitAspect::msgNoToolChainInTarget()); } else { QSet targetAbis; for (const Toolchain *tc : tcList) { @@ -402,17 +402,17 @@ Tasks ToolChainKitAspectFactory::validate(const Kit *k) const return result; } -void ToolChainKitAspectFactory::fix(Kit *k) +void ToolchainKitAspectFactory::fix(Kit *k) { QTC_ASSERT(ToolChainManager::isLoaded(), return); const QList languages = ToolChainManager::allLanguages(); for (const Id l : languages) { - const QByteArray tcId = ToolChainKitAspect::toolChainId(k, l); + const QByteArray tcId = ToolchainKitAspect::toolChainId(k, l); if (!tcId.isEmpty() && !ToolChainManager::findToolChain(tcId)) { qWarning("Tool chain set up in kit \"%s\" for \"%s\" not found.", qPrintable(k->displayName()), qPrintable(ToolChainManager::displayNameOfLanguageId(l))); - ToolChainKitAspect::clearToolChain(k, l); // make sure to clear out no longer known tool chains + ToolchainKitAspect::clearToolChain(k, l); // make sure to clear out no longer known tool chains } } } @@ -424,7 +424,7 @@ static Id findLanguage(const QString &ls) [lsUpper](Id l) { return lsUpper == l.toString().toUpper(); }); } -void ToolChainKitAspectFactory::setup(Kit *k) +void ToolchainKitAspectFactory::setup(Kit *k) { QTC_ASSERT(ToolChainManager::isLoaded(), return); QTC_ASSERT(k, return); @@ -459,123 +459,123 @@ void ToolChainKitAspectFactory::setup(Kit *k) bestTc = tc; } if (bestTc) - ToolChainKitAspect::setToolChain(k, bestTc); + ToolchainKitAspect::setToolChain(k, bestTc); else - ToolChainKitAspect::clearToolChain(k, l); + ToolchainKitAspect::clearToolChain(k, l); } k->setSticky(id(), lockToolchains); } -KitAspect *ToolChainKitAspectFactory::createKitAspect(Kit *k) const +KitAspect *ToolchainKitAspectFactory::createKitAspect(Kit *k) const { QTC_ASSERT(k, return nullptr); - return new Internal::ToolChainKitAspectImpl(k, this); + return new Internal::ToolchainKitAspectImpl(k, this); } -QString ToolChainKitAspectFactory::displayNamePostfix(const Kit *k) const +QString ToolchainKitAspectFactory::displayNamePostfix(const Kit *k) const { - Toolchain *tc = ToolChainKitAspect::cxxToolChain(k); + Toolchain *tc = ToolchainKitAspect::cxxToolChain(k); return tc ? tc->displayName() : QString(); } -KitAspectFactory::ItemList ToolChainKitAspectFactory::toUserOutput(const Kit *k) const +KitAspectFactory::ItemList ToolchainKitAspectFactory::toUserOutput(const Kit *k) const { - Toolchain *tc = ToolChainKitAspect::cxxToolChain(k); + Toolchain *tc = ToolchainKitAspect::cxxToolChain(k); return {{Tr::tr("Compiler"), tc ? tc->displayName() : Tr::tr("None")}}; } -void ToolChainKitAspectFactory::addToBuildEnvironment(const Kit *k, Environment &env) const +void ToolchainKitAspectFactory::addToBuildEnvironment(const Kit *k, Environment &env) const { - Toolchain *tc = ToolChainKitAspect::cxxToolChain(k); + Toolchain *tc = ToolchainKitAspect::cxxToolChain(k); if (tc) tc->addToEnvironment(env); } -void ToolChainKitAspectFactory::addToMacroExpander(Kit *kit, MacroExpander *expander) const +void ToolchainKitAspectFactory::addToMacroExpander(Kit *kit, MacroExpander *expander) const { QTC_ASSERT(kit, return); // Compatibility with Qt Creator < 4.2: expander->registerVariable("Compiler:Name", Tr::tr("Compiler"), [kit] { - const Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit); + const Toolchain *tc = ToolchainKitAspect::cxxToolChain(kit); return tc ? tc->displayName() : Tr::tr("None"); }); expander->registerVariable("Compiler:Executable", Tr::tr("Path to the compiler executable"), [kit] { - const Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit); + const Toolchain *tc = ToolchainKitAspect::cxxToolChain(kit); return tc ? tc->compilerCommand().path() : QString(); }); // After 4.2 expander->registerPrefix("Compiler:Name", Tr::tr("Compiler for different languages"), [kit](const QString &ls) { - const Toolchain *tc = ToolChainKitAspect::toolChain(kit, findLanguage(ls)); + const Toolchain *tc = ToolchainKitAspect::toolChain(kit, findLanguage(ls)); return tc ? tc->displayName() : Tr::tr("None"); }); expander->registerPrefix("Compiler:Executable", Tr::tr("Compiler executable for different languages"), [kit](const QString &ls) { - const Toolchain *tc = ToolChainKitAspect::toolChain(kit, findLanguage(ls)); + const Toolchain *tc = ToolchainKitAspect::toolChain(kit, findLanguage(ls)); return tc ? tc->compilerCommand().path() : QString(); }); } -QList ToolChainKitAspectFactory::createOutputParsers(const Kit *k) const +QList ToolchainKitAspectFactory::createOutputParsers(const Kit *k) const { for (const Id langId : {Constants::CXX_LANGUAGE_ID, Constants::C_LANGUAGE_ID}) { - if (const Toolchain * const tc = ToolChainKitAspect::toolChain(k, langId)) + if (const Toolchain * const tc = ToolchainKitAspect::toolChain(k, langId)) return tc->createOutputParsers(); } return {}; } -QSet ToolChainKitAspectFactory::availableFeatures(const Kit *k) const +QSet ToolchainKitAspectFactory::availableFeatures(const Kit *k) const { QSet result; - for (Toolchain *tc : ToolChainKitAspect::toolChains(k)) + for (Toolchain *tc : ToolchainKitAspect::toolChains(k)) result.insert(tc->typeId().withPrefix("ToolChain.")); return result; } -Id ToolChainKitAspect::id() +Id ToolchainKitAspect::id() { // "PE.Profile.ToolChain" until 4.2 // "PE.Profile.ToolChains" temporarily before 4.3 (May 2017) return "PE.Profile.ToolChainsV3"; } -QByteArray ToolChainKitAspect::toolChainId(const Kit *k, Id language) +QByteArray ToolchainKitAspect::toolChainId(const Kit *k, Id language) { QTC_ASSERT(ToolChainManager::isLoaded(), return nullptr); if (!k) return {}; - Store value = storeFromVariant(k->value(ToolChainKitAspect::id())); + Store value = storeFromVariant(k->value(ToolchainKitAspect::id())); return value.value(language.toKey(), QByteArray()).toByteArray(); } -Toolchain *ToolChainKitAspect::toolChain(const Kit *k, Id language) +Toolchain *ToolchainKitAspect::toolChain(const Kit *k, Id language) { return ToolChainManager::findToolChain(toolChainId(k, language)); } -Toolchain *ToolChainKitAspect::cToolChain(const Kit *k) +Toolchain *ToolchainKitAspect::cToolChain(const Kit *k) { return ToolChainManager::findToolChain(toolChainId(k, ProjectExplorer::Constants::C_LANGUAGE_ID)); } -Toolchain *ToolChainKitAspect::cxxToolChain(const Kit *k) +Toolchain *ToolchainKitAspect::cxxToolChain(const Kit *k) { return ToolChainManager::findToolChain(toolChainId(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID)); } -QList ToolChainKitAspect::toolChains(const Kit *k) +QList ToolchainKitAspect::toolChains(const Kit *k) { QTC_ASSERT(k, return {}); - const Store value = storeFromVariant(k->value(ToolChainKitAspect::id())); + const Store value = storeFromVariant(k->value(ToolchainKitAspect::id())); const QList tcList = transform(ToolChainManager::allLanguages(), [&value](Id l) { return ToolChainManager::findToolChain(value.value(l.toKey()).toByteArray()); @@ -583,11 +583,11 @@ QList ToolChainKitAspect::toolChains(const Kit *k) return filtered(tcList, [](Toolchain *tc) { return tc; }); } -void ToolChainKitAspect::setToolChain(Kit *k, Toolchain *tc) +void ToolchainKitAspect::setToolChain(Kit *k, Toolchain *tc) { QTC_ASSERT(tc, return); QTC_ASSERT(k, return); - Store result = storeFromVariant(k->value(ToolChainKitAspect::id())); + Store result = storeFromVariant(k->value(ToolchainKitAspect::id())); result.insert(tc->language().toKey(), tc->id()); k->setValue(id(), variantFromStore(result)); @@ -603,7 +603,7 @@ void ToolChainKitAspect::setToolChain(Kit *k, Toolchain *tc) * @param k The kit to set up * @param tc The toolchain to match other languages for. */ -void ToolChainKitAspect::setAllToolChainsToMatch(Kit *k, Toolchain *tc) +void ToolchainKitAspect::setAllToolChainsToMatch(Kit *k, Toolchain *tc) { QTC_ASSERT(tc, return); QTC_ASSERT(k, return); @@ -611,7 +611,7 @@ void ToolChainKitAspect::setAllToolChainsToMatch(Kit *k, Toolchain *tc) const Toolchains allTcList = ToolChainManager::toolchains(); QTC_ASSERT(allTcList.contains(tc), return); - Store result = storeFromVariant(k->value(ToolChainKitAspect::id())); + Store result = storeFromVariant(k->value(ToolchainKitAspect::id())); result.insert(tc->language().toKey(), tc->id()); for (const Id l : ToolChainManager::allLanguages()) { @@ -642,17 +642,17 @@ void ToolChainKitAspect::setAllToolChainsToMatch(Kit *k, Toolchain *tc) k->setValue(id(), variantFromStore(result)); } -void ToolChainKitAspect::clearToolChain(Kit *k, Id language) +void ToolchainKitAspect::clearToolChain(Kit *k, Id language) { QTC_ASSERT(language.isValid(), return); QTC_ASSERT(k, return); - Store result = storeFromVariant(k->value(ToolChainKitAspect::id())); + Store result = storeFromVariant(k->value(ToolchainKitAspect::id())); result.insert(language.toKey(), QByteArray()); k->setValue(id(), variantFromStore(result)); } -Abi ToolChainKitAspect::targetAbi(const Kit *k) +Abi ToolchainKitAspect::targetAbi(const Kit *k) { const QList tcList = toolChains(k); // Find the best possible ABI for all the tool chains... @@ -685,38 +685,38 @@ Abi ToolChainKitAspect::targetAbi(const Kit *k) return candidates.at(0); // Use basically a random Abi... } -QString ToolChainKitAspect::msgNoToolChainInTarget() +QString ToolchainKitAspect::msgNoToolChainInTarget() { return Tr::tr("No compiler set in kit."); } -void ToolChainKitAspectFactory::onKitsLoaded() +void ToolchainKitAspectFactory::onKitsLoaded() { for (Kit *k : KitManager::kits()) fix(k); connect(ToolChainManager::instance(), &ToolChainManager::toolChainRemoved, - this, &ToolChainKitAspectFactory::toolChainRemoved); + this, &ToolchainKitAspectFactory::toolChainRemoved); connect(ToolChainManager::instance(), &ToolChainManager::toolChainUpdated, - this, &ToolChainKitAspectFactory::toolChainUpdated); + this, &ToolchainKitAspectFactory::toolChainUpdated); } -void ToolChainKitAspectFactory::toolChainUpdated(Toolchain *tc) +void ToolchainKitAspectFactory::toolChainUpdated(Toolchain *tc) { for (Kit *k : KitManager::kits()) { - if (ToolChainKitAspect::toolChain(k, tc->language()) == tc) + if (ToolchainKitAspect::toolChain(k, tc->language()) == tc) notifyAboutUpdate(k); } } -void ToolChainKitAspectFactory::toolChainRemoved(Toolchain *tc) +void ToolchainKitAspectFactory::toolChainRemoved(Toolchain *tc) { Q_UNUSED(tc) for (Kit *k : KitManager::kits()) fix(k); } -const ToolChainKitAspectFactory thsToolChainKitAspectFactory; +const ToolchainKitAspectFactory thsToolChainKitAspectFactory; // -------------------------------------------------------------------------- // DeviceTypeKitAspect: diff --git a/src/plugins/projectexplorer/kitaspects.h b/src/plugins/projectexplorer/kitaspects.h index 7b8270d7d42..8c303c7d187 100644 --- a/src/plugins/projectexplorer/kitaspects.h +++ b/src/plugins/projectexplorer/kitaspects.h @@ -26,7 +26,7 @@ public: // ToolChainKitAspect -class PROJECTEXPLORER_EXPORT ToolChainKitAspect +class PROJECTEXPLORER_EXPORT ToolchainKitAspect { public: static Utils::Id id(); diff --git a/src/plugins/projectexplorer/kitmanager.cpp b/src/plugins/projectexplorer/kitmanager.cpp index 213d53f1b1e..b228ea7c698 100644 --- a/src/plugins/projectexplorer/kitmanager.cpp +++ b/src/plugins/projectexplorer/kitmanager.cpp @@ -151,7 +151,7 @@ void KitManager::destroy() static bool kitMatchesAbiList(const Kit *kit, const Abis &abis) { - const QList toolchains = ToolChainKitAspect::toolChains(kit); + const QList toolchains = ToolchainKitAspect::toolChains(kit); for (const Toolchain * const tc : toolchains) { const Abi tcAbi = tc->targetAbi(); for (const Abi &abi : abis) { @@ -183,7 +183,7 @@ static Id deviceTypeForKit(const Kit *kit) { if (isHostKit(kit)) return Constants::DESKTOP_DEVICE_TYPE; - const QList toolchains = ToolChainKitAspect::toolChains(kit); + const QList toolchains = ToolchainKitAspect::toolChains(kit); for (const Toolchain * const tc : toolchains) { const Abi tcAbi = tc->targetAbi(); switch (tcAbi.os()) { @@ -347,10 +347,10 @@ void KitManager::restoreKits() kit->setSdkProvided(false); kit->setAutoDetected(false); // TODO: Why false? What does autodetected mean here? for (Toolchain * const tc : it.value()) - ToolChainKitAspect::setToolChain(kit.get(), tc); + ToolchainKitAspect::setToolChain(kit.get(), tc); if (contains(resultList, [&kit](const std::unique_ptr &existingKit) { - return ToolChainKitAspect::toolChains(kit.get()) - == ToolChainKitAspect::toolChains(existingKit.get()); + return ToolchainKitAspect::toolChains(kit.get()) + == ToolchainKitAspect::toolChains(existingKit.get()); })) { continue; } diff --git a/src/plugins/projectexplorer/makestep.cpp b/src/plugins/projectexplorer/makestep.cpp index e14f2b8a932..1a1a8fae413 100644 --- a/src/plugins/projectexplorer/makestep.cpp +++ b/src/plugins/projectexplorer/makestep.cpp @@ -130,7 +130,7 @@ QString MakeStep::defaultDisplayName() static const QList preferredToolChains(const Kit *kit) { // prefer CXX, then C, then others - return Utils::sorted(ToolChainKitAspect::toolChains(kit), [](Toolchain *tcA, Toolchain *tcB) { + return Utils::sorted(ToolchainKitAspect::toolChains(kit), [](Toolchain *tcA, Toolchain *tcB) { if (tcA->language() == tcB->language()) return false; if (tcA->language() == Constants::CXX_LANGUAGE_ID) diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 84c8fb2e103..711a934d5f9 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -1551,12 +1551,12 @@ void ProjectExplorerPlugin::testSourceToBinaryMapping() { // Find suitable kit. Kit * const kit = findOr(KitManager::kits(), nullptr, [](const Kit *k) { - return k->isValid() && ToolChainKitAspect::cxxToolChain(k); + return k->isValid() && ToolchainKitAspect::cxxToolChain(k); }); if (!kit) QSKIP("The test requires at least one kit with a toolchain."); - const auto toolchain = ToolChainKitAspect::cxxToolChain(kit); + const auto toolchain = ToolchainKitAspect::cxxToolChain(kit); QVERIFY(toolchain); if (const auto msvcToolchain = dynamic_cast(toolchain)) { while (!msvcToolchain->environmentInitialized()) { diff --git a/src/plugins/projectexplorer/projectimporter.cpp b/src/plugins/projectexplorer/projectimporter.cpp index 31498c14879..b55888159b2 100644 --- a/src/plugins/projectexplorer/projectimporter.cpp +++ b/src/plugins/projectexplorer/projectimporter.cpp @@ -53,7 +53,7 @@ static bool hasOtherUsers(Utils::Id id, const QVariant &v, Kit *k) ProjectImporter::ProjectImporter(const Utils::FilePath &path) : m_projectPath(path) { - useTemporaryKitAspect(ToolChainKitAspect::id(), + useTemporaryKitAspect(ToolchainKitAspect::id(), [this](Kit *k, const QVariantList &vl) { cleanupTemporaryToolChains(k, vl); }, [this](Kit *k, const QVariantList &vl) { persistTemporaryToolChains(k, vl); }); } @@ -322,7 +322,7 @@ void ProjectImporter::cleanupTemporaryToolChains(Kit *k, const QVariantList &vl) Toolchain *tc = toolChainFromVariant(v); QTC_ASSERT(tc, continue); ToolChainManager::deregisterToolChain(tc); - ToolChainKitAspect::setToolChain(k, nullptr); + ToolchainKitAspect::setToolChain(k, nullptr); } } @@ -331,7 +331,7 @@ void ProjectImporter::persistTemporaryToolChains(Kit *k, const QVariantList &vl) for (const QVariant &v : vl) { Toolchain *tmpTc = toolChainFromVariant(v); QTC_ASSERT(tmpTc, continue); - Toolchain *actualTc = ToolChainKitAspect::toolChain(k, tmpTc->language()); + Toolchain *actualTc = ToolchainKitAspect::toolChain(k, tmpTc->language()); if (tmpTc && actualTc != tmpTc) ToolChainManager::deregisterToolChain(tmpTc); } @@ -394,7 +394,7 @@ ProjectImporter::findOrCreateToolChains(const ToolChainDescription &tcd) const }); for (const Toolchain *tc : std::as_const(result.tcs)) { const QByteArray tcId = tc->id(); - result.areTemporary = result.areTemporary ? true : hasKitWithTemporaryData(ToolChainKitAspect::id(), tcId); + result.areTemporary = result.areTemporary ? true : hasKitWithTemporaryData(ToolchainKitAspect::id(), tcId); } if (!result.tcs.isEmpty()) return result; diff --git a/src/plugins/projectexplorer/rawprojectpart.cpp b/src/plugins/projectexplorer/rawprojectpart.cpp index 53290cef8ea..369321cd80e 100644 --- a/src/plugins/projectexplorer/rawprojectpart.cpp +++ b/src/plugins/projectexplorer/rawprojectpart.cpp @@ -142,8 +142,8 @@ KitInfo::KitInfo(Kit *kit) { // Toolchains if (kit) { - cToolChain = ToolChainKitAspect::cToolChain(kit); - cxxToolChain = ToolChainKitAspect::cxxToolChain(kit); + cToolChain = ToolchainKitAspect::cToolChain(kit); + cxxToolChain = ToolchainKitAspect::cxxToolChain(kit); } // Sysroot diff --git a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp index 658e6650c19..97b17346552 100644 --- a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp +++ b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp @@ -238,8 +238,8 @@ QVariantMap DefaultPropertyProvider::autoGeneratedProperties(const ProjectExplor if (!sysroot.isEmpty()) data.insert(QLatin1String(QBS_SYSROOT), sysroot); - Toolchain *tcC = ToolChainKitAspect::cToolChain(k); - Toolchain *tcCxx = ToolChainKitAspect::cxxToolChain(k); + Toolchain *tcC = ToolchainKitAspect::cToolChain(k); + Toolchain *tcCxx = ToolchainKitAspect::cxxToolChain(k); if (!tcC && !tcCxx) return data; diff --git a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp index 0d5afda8f36..a8612d5e71e 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp +++ b/src/plugins/qbsprojectmanager/qbsprojectimporter.cpp @@ -141,12 +141,12 @@ bool QbsProjectImporter::matchKit(void *directoryData, const Kit *k) const const auto * const bgData = static_cast(directoryData); qCDebug(qbsPmLog) << "matching kit" << k->displayName() << "against imported build" << bgData->bgFilePath.toUserOutput(); - if (ToolChainKitAspect::toolChains(k).isEmpty() && bgData->cCompilerPath.isEmpty() + if (ToolchainKitAspect::toolChains(k).isEmpty() && bgData->cCompilerPath.isEmpty() && bgData->cxxCompilerPath.isEmpty()) { return true; } - const Toolchain * const cToolchain = ToolChainKitAspect::cToolChain(k); - const Toolchain * const cxxToolchain = ToolChainKitAspect::cxxToolChain(k); + const Toolchain * const cToolchain = ToolchainKitAspect::cToolChain(k); + const Toolchain * const cxxToolchain = ToolchainKitAspect::cxxToolChain(k); if (!bgData->cCompilerPath.isEmpty()) { if (!cToolchain) return false; @@ -190,7 +190,7 @@ Kit *QbsProjectImporter::createKit(void *directoryData) const tcData << findOrCreateToolChains({bgData->cCompilerPath, PEConstants::C_LANGUAGE_ID}); for (const ToolChainData &tc : std::as_const(tcData)) { if (!tc.tcs.isEmpty()) - ToolChainKitAspect::setToolChain(k, tc.tcs.first()); + ToolchainKitAspect::setToolChain(k, tc.tcs.first()); } SysRootKitAspect::setSysRoot(k, bgData->sysroot); }); diff --git a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp index 9bd50ff3c10..2039b0ec21e 100644 --- a/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp +++ b/src/plugins/qmakeprojectmanager/qmakebuildconfiguration.cpp @@ -781,7 +781,7 @@ QmakeBuildConfiguration::LastKitState::LastKitState(Kit *k) m_sysroot(SysRootKitAspect::sysRoot(k).toString()), m_mkspec(QmakeKitAspect::mkspec(k)) { - Toolchain *tc = ToolChainKitAspect::cxxToolChain(k); + Toolchain *tc = ToolchainKitAspect::cxxToolChain(k); m_toolchain = tc ? tc->id() : QByteArray(); } diff --git a/src/plugins/qmakeprojectmanager/qmakekitaspect.cpp b/src/plugins/qmakeprojectmanager/qmakekitaspect.cpp index 18033f9dfc1..d0263bf0943 100644 --- a/src/plugins/qmakeprojectmanager/qmakekitaspect.cpp +++ b/src/plugins/qmakeprojectmanager/qmakekitaspect.cpp @@ -98,7 +98,7 @@ QString QmakeKitAspect::defaultMkspec(const Kit *k) if (!version) // No version, so no qmake return {}; - return version->mkspecFor(ToolChainKitAspect::cxxToolChain(k)); + return version->mkspecFor(ToolchainKitAspect::cxxToolChain(k)); } // QmakeKitAspectFactory diff --git a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp index 0cd032b4991..6a22f89eb38 100644 --- a/src/plugins/qmakeprojectmanager/qmakemakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakemakestep.cpp @@ -179,7 +179,7 @@ bool QmakeMakeStep::init() void QmakeMakeStep::setupOutputFormatter(OutputFormatter *formatter) { formatter->addLineParser(new GnuMakeParser()); - Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit()); + Toolchain *tc = ToolchainKitAspect::cxxToolChain(kit()); OutputTaskParser *xcodeBuildParser = nullptr; if (tc && tc->targetAbi().os() == Abi::DarwinOS) { xcodeBuildParser = new XcodebuildParser; diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 4ddc7ae410b..2daf3c31d45 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -238,7 +238,7 @@ QmakeBuildSystem::QmakeBuildSystem(QmakeBuildConfiguration *bc) connect(ToolChainManager::instance(), &ToolChainManager::toolChainUpdated, this, [this](Toolchain *tc) { - if (ToolChainKitAspect::cxxToolChain(kit()) == tc) + if (ToolchainKitAspect::cxxToolChain(kit()) == tc) scheduleUpdateAllNowOrLater(); }); @@ -757,7 +757,7 @@ Tasks QmakeProject::projectIssues(const Kit *k) const result.append(createProjectTask(Task::TaskType::Error, Tr::tr("No Qt version set in kit."))); else if (!qtFromKit->isValid()) result.append(createProjectTask(Task::TaskType::Error, Tr::tr("Qt version is invalid."))); - if (!ToolChainKitAspect::cxxToolChain(k)) + if (!ToolchainKitAspect::cxxToolChain(k)) result.append(createProjectTask(Task::TaskType::Error, Tr::tr("No C++ compiler set in kit."))); // A project can be considered part of more than one Qt version, for instance if it is an @@ -1308,7 +1308,7 @@ static FilePath destDirFor(const TargetInformation &ti) FilePaths QmakeBuildSystem::allLibraryTargetFiles(const QmakeProFile *file) const { - const Toolchain *const toolchain = ToolChainKitAspect::cxxToolChain(kit()); + const Toolchain *const toolchain = ToolchainKitAspect::cxxToolChain(kit()); if (!toolchain) return {}; @@ -1467,14 +1467,14 @@ QString QmakeBuildSystem::deviceRoot() const void QmakeBuildSystem::warnOnToolChainMismatch(const QmakeProFile *pro) const { const BuildConfiguration *bc = buildConfiguration(); - testToolChain(ToolChainKitAspect::cToolChain(kit()), getFullPathOf(pro, Variable::QmakeCc, bc)); - testToolChain(ToolChainKitAspect::cxxToolChain(kit()), + testToolChain(ToolchainKitAspect::cToolChain(kit()), getFullPathOf(pro, Variable::QmakeCc, bc)); + testToolChain(ToolchainKitAspect::cxxToolChain(kit()), getFullPathOf(pro, Variable::QmakeCxx, bc)); } FilePath QmakeBuildSystem::executableFor(const QmakeProFile *file) { - const Toolchain *const tc = ToolChainKitAspect::cxxToolChain(kit()); + const Toolchain *const tc = ToolchainKitAspect::cxxToolChain(kit()); if (!tc) return {}; diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp index a2f20fe4eeb..711b30bcf32 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp @@ -160,7 +160,7 @@ bool QmakeProjectImporter::matchKit(void *directoryData, const Kit *k) const QtVersion *kitVersion = QtKitAspect::qtVersion(k); QString kitSpec = QmakeKitAspect::mkspec(k); - Toolchain *tc = ToolChainKitAspect::cxxToolChain(k); + Toolchain *tc = ToolchainKitAspect::cxxToolChain(k); if (kitSpec.isEmpty() && kitVersion) kitSpec = kitVersion->mkspecFor(tc); QMakeStepConfig::OsType kitOsType = QMakeStepConfig::NoOsType; @@ -241,7 +241,7 @@ Kit *QmakeProjectImporter::createTemporaryKit(const QtProjectImporter::QtVersion Q_UNUSED(osType) // TODO use this to select the right toolchain? return QtProjectImporter::createTemporaryKit(data, [&data, parsedSpec](Kit *k) -> void { for (Toolchain *const tc : preferredToolChains(data.qt, parsedSpec)) - ToolChainKitAspect::setToolChain(k, tc); + ToolchainKitAspect::setToolChain(k, tc); if (parsedSpec != data.qt->mkspec()) QmakeKitAspect::setMkspec(k, parsedSpec, QmakeKitAspect::MkspecSource::Code); }); diff --git a/src/plugins/qmakeprojectmanager/qmakestep.cpp b/src/plugins/qmakeprojectmanager/qmakestep.cpp index 019429805a9..db2d8da91af 100644 --- a/src/plugins/qmakeprojectmanager/qmakestep.cpp +++ b/src/plugins/qmakeprojectmanager/qmakestep.cpp @@ -149,7 +149,7 @@ QMakeStepConfig QMakeStep::deducedArguments() const Kit *kit = target()->kit(); QMakeStepConfig config; Abi targetAbi; - if (Toolchain *tc = ToolChainKitAspect::cxxToolChain(kit)) { + if (Toolchain *tc = ToolchainKitAspect::cxxToolChain(kit)) { targetAbi = tc->targetAbi(); if (HostOsInfo::isWindowsHost() && tc->typeId() == ProjectExplorer::Constants::CLANG_TOOLCHAIN_TYPEID) { diff --git a/src/plugins/qnx/qnxsettingspage.cpp b/src/plugins/qnx/qnxsettingspage.cpp index e3dd7e7acbd..86da2f4c176 100644 --- a/src/plugins/qnx/qnxsettingspage.cpp +++ b/src/plugins/qnx/qnxsettingspage.cpp @@ -182,7 +182,7 @@ void QnxConfiguration::deactivate() for (Kit *kit : kits) { if (kit->isAutoDetected() && DeviceTypeKitAspect::deviceTypeId(kit) == Constants::QNX_QNX_OS_TYPE - && toolChainsToRemove.contains(ToolChainKitAspect::cxxToolChain(kit))) { + && toolChainsToRemove.contains(ToolchainKitAspect::cxxToolChain(kit))) { KitManager::deregisterKit(kit); } } @@ -258,8 +258,8 @@ void QnxConfiguration::createKit(const QnxTarget &target) const auto init = [&](Kit *k) { QtKitAspect::setQtVersion(k, qnxQt); - ToolChainKitAspect::setToolChain(k, toolChains[0]); - ToolChainKitAspect::setToolChain(k, toolChains[1]); + ToolchainKitAspect::setToolChain(k, toolChains[0]); + ToolchainKitAspect::setToolChain(k, toolChains[1]); if (debugger.isValid()) DebuggerKitAspect::setDebugger(k, debugger); @@ -275,7 +275,7 @@ void QnxConfiguration::createKit(const QnxTarget &target) k->setAutoDetectionSource(m_envFile.toString()); k->setMutable(DeviceKitAspect::id(), true); - k->setSticky(ToolChainKitAspect::id(), true); + k->setSticky(ToolchainKitAspect::id(), true); k->setSticky(DeviceTypeKitAspect::id(), true); k->setSticky(SysRootKitAspect::id(), true); k->setSticky(DebuggerKitAspect::id(), true); diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index 8f461eed641..b74d9c25b32 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -542,7 +542,7 @@ Tasks QtVersion::validateKit(const Kit *k) result << BuildSystemTask(Task::Warning, Tr::tr("Device type is not supported by Qt version.")); } - if (Toolchain *tc = ToolChainKitAspect::cxxToolChain(k)) { + if (Toolchain *tc = ToolchainKitAspect::cxxToolChain(k)) { Abi targetAbi = tc->targetAbi(); Abis supportedAbis = tc->supportedAbis(); bool fuzzyMatch = false; @@ -576,7 +576,7 @@ Tasks QtVersion::validateKit(const Kit *k) version->displayName(), qtAbiString); result << BuildSystemTask(fuzzyMatch ? Task::Warning : Task::Error, message); } - } else if (ToolChainKitAspect::cToolChain(k)) { + } else if (ToolchainKitAspect::cToolChain(k)) { const QString message = Tr::tr("The kit has a Qt version, but no C++ compiler."); result << BuildSystemTask(Task::Warning, message); } diff --git a/src/plugins/qtsupport/qtkitaspect.cpp b/src/plugins/qtsupport/qtkitaspect.cpp index c53cb537c2a..e2591d9260e 100644 --- a/src/plugins/qtsupport/qtkitaspect.cpp +++ b/src/plugins/qtsupport/qtkitaspect.cpp @@ -175,7 +175,7 @@ void QtKitAspectFactory::setup(Kit *k) { if (!k || k->hasValue(id())) return; - const Abi tcAbi = ToolChainKitAspect::targetAbi(k); + const Abi tcAbi = ToolchainKitAspect::targetAbi(k); const Id deviceType = DeviceTypeKitAspect::deviceTypeId(k); const QtVersions matches @@ -226,7 +226,7 @@ void QtKitAspectFactory::fix(Kit *k) } // Set a matching toolchain if we don't have one. - if (ToolChainKitAspect::cxxToolChain(k)) + if (ToolchainKitAspect::cxxToolChain(k)) return; const QString spec = version->mkspec(); @@ -283,7 +283,7 @@ void QtKitAspectFactory::fix(Kit *k) }); if (Toolchain * const bestTc = goodTcs.isEmpty() ? possibleTcs.first() : goodTcs.first()) - ToolChainKitAspect::setAllToolChainsToMatch(k, bestTc); + ToolchainKitAspect::setAllToolChainsToMatch(k, bestTc); } } @@ -405,7 +405,7 @@ void QtKitAspect::setQtVersion(Kit *k, const QtVersion *v) void QtKitAspect::addHostBinariesToPath(const Kit *k, Environment &env) { - if (const Toolchain *tc = ToolChainKitAspect::cxxToolChain(k)) + if (const Toolchain *tc = ToolchainKitAspect::cxxToolChain(k)) env.prependOrSetPath(tc->compilerCommand().parentDir()); if (const QtVersion *qt = qtVersion(k)) @@ -479,7 +479,7 @@ int QtKitAspectFactory::weight(const Kit *k) const return 0; if (!qt->targetDeviceTypes().contains(DeviceTypeKitAspect::deviceTypeId(k))) return 0; - const Abi tcAbi = ToolChainKitAspect::targetAbi(k); + const Abi tcAbi = ToolchainKitAspect::targetAbi(k); if (qt->qtAbis().contains(tcAbi)) return 2; return Utils::contains(qt->qtAbis(), [&tcAbi](const Abi &qtAbi) { diff --git a/src/plugins/valgrind/memchecktool.cpp b/src/plugins/valgrind/memchecktool.cpp index 5a23bac90ea..3467550886f 100644 --- a/src/plugins/valgrind/memchecktool.cpp +++ b/src/plugins/valgrind/memchecktool.cpp @@ -714,7 +714,7 @@ void MemcheckToolPrivate::heobAction() if (RunConfiguration *rc = target->activeRunConfiguration()) { kit = target->kit(); if (kit) { - abi = ToolChainKitAspect::targetAbi(kit); + abi = ToolchainKitAspect::targetAbi(kit); sr = rc->runnable(); const IDevice::ConstPtr device = DeviceManager::deviceForPath(sr.command.executable()); From f98934ef731fc75fe6647ec494494452e8577e2c Mon Sep 17 00:00:00 2001 From: Marcus Tillmanns Date: Tue, 14 Nov 2023 15:53:33 +0100 Subject: [PATCH 0384/1546] Core: Simplify ActionManager::setOnTriggered Allows the same functionality as QObject::connect Change-Id: I4416d991dc8bcdf24893435c30b530a6b4d3fda4 Reviewed-by: Qt CI Bot Reviewed-by: Eike Ziller --- .../coreplugin/actionmanager/actionmanager.cpp | 10 ---------- .../coreplugin/actionmanager/actionmanager.h | 15 +++++++++++++-- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.cpp b/src/plugins/coreplugin/actionmanager/actionmanager.cpp index 90c52f16ef3..0c5c36f8d0c 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.cpp +++ b/src/plugins/coreplugin/actionmanager/actionmanager.cpp @@ -146,16 +146,6 @@ void ActionBuilder::setOnTriggered(const std::function &func) QObject::connect(d->action, &QAction::triggered, d->action, func); } -void ActionBuilder::setOnTriggered(QObject *guard, const std::function &func) -{ - QObject::connect(d->action, &QAction::triggered, guard, func); -} - -void ActionBuilder::setOnTriggered(QObject *guard, const std::function &func) -{ - QObject::connect(d->action, &QAction::triggered, guard, func); -} - void ActionBuilder::setOnToggled(QObject *guard, const std::function &func) { QObject::connect(d->action, &QAction::toggled, guard, func); diff --git a/src/plugins/coreplugin/actionmanager/actionmanager.h b/src/plugins/coreplugin/actionmanager/actionmanager.h index ce6f12a4938..564d7202546 100644 --- a/src/plugins/coreplugin/actionmanager/actionmanager.h +++ b/src/plugins/coreplugin/actionmanager/actionmanager.h @@ -44,9 +44,20 @@ public: void setCommandDescription(const QString &desc); void setContainer(Utils::Id containerId, Utils::Id groupId = {}, bool needsToExist = true); void setOnTriggered(const std::function &func); - void setOnTriggered(QObject *guard, const std::function &func); - void setOnTriggered(QObject *guard, const std::function &func); void setOnToggled(QObject *guard, const std::function &func); + + template + void setOnTriggered(T *guard, + F &&function, + Qt::ConnectionType connectionType = Qt::AutoConnection) + { + QObject::connect(commandAction(), + &QAction::triggered, + guard, + std::forward(function), + connectionType); + } + void setDefaultKeySequence(const QKeySequence &seq); void setDefaultKeySequences(const QList &seqs); void setDefaultKeySequence(const QString &mac, const QString &nonMac); From bd849b615e119b7e3237f725445a974d30913f55 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Mon, 27 Nov 2023 14:34:01 +0100 Subject: [PATCH 0385/1546] QbsPM: Fix qbs build Amends ba249a35141892168f16fd3c6e4613f7b0f67131. Change-Id: Ieda665923434510ab5fe6b17776dbac07262d2a8 Reviewed-by: Christian Kandeler --- src/plugins/qbsprojectmanager/qbsprojectmanager.qbs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs index 709043df235..e2b00b89440 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs +++ b/src/plugins/qbsprojectmanager/qbsprojectmanager.qbs @@ -18,6 +18,7 @@ QtcPlugin { Depends { name: "QmlJSEditor" } Depends { name: "QmlJSTools" } Depends { name: "QtSupport" } + Depends { name: "TextEditor" } files: [ "customqbspropertiesdialog.h", From b5937836f43d7d244ad803b27caddb0e7c2e5f46 Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 27 Nov 2023 16:42:42 +0100 Subject: [PATCH 0386/1546] ProjectExplorer: Rename ToolChainManager to ToolchainManager Plus the private and some comments. Change-Id: I95d72d77f25cb1c969a1a6148e7186150a697d1f Reviewed-by: Christian Kandeler --- src/plugins/android/androidconfigurations.cpp | 14 ++-- src/plugins/android/androidtoolchain.cpp | 2 +- src/plugins/baremetal/iarewtoolchain.cpp | 6 +- src/plugins/baremetal/keiltoolchain.cpp | 6 +- src/plugins/baremetal/sdcctoolchain.cpp | 2 +- .../cmakeprojectimporter.cpp | 8 +- .../compilationdatabaseproject.cpp | 4 +- .../compilationdatabasetests.cpp | 2 +- src/plugins/docker/kitdetector.cpp | 12 +-- src/plugins/ios/iosconfigurations.cpp | 2 +- src/plugins/mcusupport/mcupackage.cpp | 16 ++-- src/plugins/mcusupport/mcusupportsdk.cpp | 2 +- src/plugins/mcusupport/test/unittest.cpp | 6 +- src/plugins/nim/nimplugin.cpp | 2 +- src/plugins/projectexplorer/gcctoolchain.cpp | 32 ++++---- src/plugins/projectexplorer/kitaspects.cpp | 52 ++++++------- src/plugins/projectexplorer/kitmanager.cpp | 2 +- src/plugins/projectexplorer/project.cpp | 4 +- .../projectexplorer/projectexplorer.cpp | 12 +-- .../projectexplorer/projectimporter.cpp | 10 +-- src/plugins/projectexplorer/toolchain.cpp | 12 +-- .../projectexplorer/toolchainmanager.cpp | 74 +++++++++---------- .../projectexplorer/toolchainmanager.h | 10 +-- .../projectexplorer/toolchainoptionspage.cpp | 26 +++---- .../qmakeprojectmanager/qmakeproject.cpp | 2 +- .../qmakeprojectimporter.cpp | 2 +- src/plugins/qnx/qnxsettingspage.cpp | 8 +- src/plugins/qtsupport/baseqtversion.cpp | 2 +- src/plugins/qtsupport/qtkitaspect.cpp | 2 +- src/plugins/qtsupport/qtoptionspage.cpp | 6 +- src/plugins/qtsupport/qtversionmanager.cpp | 6 +- .../webassembly/webassemblytoolchain.cpp | 14 ++-- 32 files changed, 180 insertions(+), 180 deletions(-) diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index 8cf6d186a1e..afbdb7f322d 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -1147,24 +1147,24 @@ static bool matchToolChain(const Toolchain *atc, const Toolchain *btc) void AndroidConfigurations::registerNewToolChains() { const Toolchains existingAndroidToolChains - = ToolChainManager::toolchains(Utils::equal(&Toolchain::typeId, Id(Constants::ANDROID_TOOLCHAIN_TYPEID))); + = ToolchainManager::toolchains(Utils::equal(&Toolchain::typeId, Id(Constants::ANDROID_TOOLCHAIN_TYPEID))); const Toolchains newToolchains = AndroidToolchainFactory::autodetectToolChains( existingAndroidToolChains); for (Toolchain *tc : newToolchains) - ToolChainManager::registerToolChain(tc); + ToolchainManager::registerToolChain(tc); registerCustomToolChainsAndDebuggers(); } void AndroidConfigurations::removeOldToolChains() { - const auto tcs = ToolChainManager::toolchains(Utils::equal(&Toolchain::typeId, + const auto tcs = ToolchainManager::toolchains(Utils::equal(&Toolchain::typeId, Id(Constants::ANDROID_TOOLCHAIN_TYPEID))); for (Toolchain *tc : tcs) { if (!tc->isValid()) - ToolChainManager::deregisterToolChain(tc); + ToolchainManager::deregisterToolChain(tc); } } @@ -1306,7 +1306,7 @@ static QVariant findOrRegisterDebugger(Toolchain *tc, void AndroidConfigurations::registerCustomToolChainsAndDebuggers() { - const Toolchains existingAndroidToolChains = ToolChainManager::toolchains( + const Toolchains existingAndroidToolChains = ToolchainManager::toolchains( Utils::equal(&Toolchain::typeId, Utils::Id(Constants::ANDROID_TOOLCHAIN_TYPEID))); const FilePaths customNdks = FileUtils::toFilePathList(currentConfig().getCustomNdkList()); @@ -1315,7 +1315,7 @@ void AndroidConfigurations::registerCustomToolChainsAndDebuggers() customNdks, true); for (Toolchain *tc : customToolchains) { - ToolChainManager::registerToolChain(tc); + ToolchainManager::registerToolChain(tc); const auto androidToolChain = static_cast(tc); QString abiStr; if (androidToolChain) @@ -1359,7 +1359,7 @@ void AndroidConfigurations::updateAutomaticKitList() } // register new kits - const Toolchains toolchains = ToolChainManager::toolchains([](const Toolchain *tc) { + const Toolchains toolchains = ToolchainManager::toolchains([](const Toolchain *tc) { return tc->isAutoDetected() && tc->typeId() == Constants::ANDROID_TOOLCHAIN_TYPEID && tc->isValid(); }); diff --git a/src/plugins/android/androidtoolchain.cpp b/src/plugins/android/androidtoolchain.cpp index a71f43528b4..90142293b42 100644 --- a/src/plugins/android/androidtoolchain.cpp +++ b/src/plugins/android/androidtoolchain.cpp @@ -215,7 +215,7 @@ ToolChainList AndroidToolchainFactory::autodetectToolChainsFromNdks( QLatin1String customStr = isCustom ? QLatin1String("Custom ") : QLatin1String(); const QString displayName(customStr + QString("Android Clang (%1, %2, NDK %3)") - .arg(ToolChainManager::displayNameOfLanguageId(lang), + .arg(ToolchainManager::displayNameOfLanguageId(lang), AndroidConfig::displayName(abi), config.ndkVersion(ndkLocation).toString())); if (tc) { diff --git a/src/plugins/baremetal/iarewtoolchain.cpp b/src/plugins/baremetal/iarewtoolchain.cpp index bfc851fb654..b66b5ab230e 100644 --- a/src/plugins/baremetal/iarewtoolchain.cpp +++ b/src/plugins/baremetal/iarewtoolchain.cpp @@ -249,7 +249,7 @@ static QString buildDisplayName(Abi::Architecture arch, Utils::Id language, const QString &version) { const auto archName = Abi::toString(arch); - const auto langName = ToolChainManager::displayNameOfLanguageId(language); + const auto langName = ToolchainManager::displayNameOfLanguageId(language); return Tr::tr("IAREW %1 (%2, %3)").arg(version, langName, archName); } @@ -540,12 +540,12 @@ Toolchains IarToolchainFactory::autoDetectToolchains( Toolchains IarToolchainFactory::autoDetectToolchain(const Candidate &candidate, Id languageId) const { - if (ToolChainManager::isBadToolchain(candidate.compilerPath)) + if (ToolchainManager::isBadToolchain(candidate.compilerPath)) return {}; const auto env = Environment::systemEnvironment(); const Macros macros = dumpPredefinedMacros(candidate.compilerPath, {}, languageId, env); if (macros.isEmpty()) { - ToolChainManager::addBadToolchain(candidate.compilerPath); + ToolchainManager::addBadToolchain(candidate.compilerPath); return {}; } const Abi abi = guessAbi(macros); diff --git a/src/plugins/baremetal/keiltoolchain.cpp b/src/plugins/baremetal/keiltoolchain.cpp index 0db09bf7d92..164638cc134 100644 --- a/src/plugins/baremetal/keiltoolchain.cpp +++ b/src/plugins/baremetal/keiltoolchain.cpp @@ -373,7 +373,7 @@ static QString buildDisplayName(Abi::Architecture arch, Utils::Id language, const QString &version) { const QString archName = Abi::toString(arch); - const QString langName = ToolChainManager::displayNameOfLanguageId(language); + const QString langName = ToolchainManager::displayNameOfLanguageId(language); return Tr::tr("KEIL %1 (%2, %3)").arg(version, langName, archName); } @@ -689,7 +689,7 @@ Toolchains KeilToolchainFactory::autoDetectToolchains( Toolchains KeilToolchainFactory::autoDetectToolchain(const Candidate &candidate, Id language) const { - if (ToolChainManager::isBadToolchain(candidate.compilerPath)) + if (ToolchainManager::isBadToolchain(candidate.compilerPath)) return {}; const auto env = Environment::systemEnvironment(); @@ -697,7 +697,7 @@ Toolchains KeilToolchainFactory::autoDetectToolchain(const Candidate &candidate, addDefaultCpuArgs(candidate.compilerPath, extraArgs); const Macros macros = dumpPredefinedMacros(candidate.compilerPath, extraArgs, env); if (macros.isEmpty()) { - ToolChainManager::addBadToolchain(candidate.compilerPath); + ToolchainManager::addBadToolchain(candidate.compilerPath); return {}; } diff --git a/src/plugins/baremetal/sdcctoolchain.cpp b/src/plugins/baremetal/sdcctoolchain.cpp index 24e34d48a67..dc0d998dc33 100644 --- a/src/plugins/baremetal/sdcctoolchain.cpp +++ b/src/plugins/baremetal/sdcctoolchain.cpp @@ -164,7 +164,7 @@ static Abi guessAbi(const Macros ¯os) static QString buildDisplayName(Abi::Architecture arch, Id language, const QString &version) { const QString archName = Abi::toString(arch); - const QString langName = ToolChainManager::displayNameOfLanguageId(language); + const QString langName = ToolchainManager::displayNameOfLanguageId(language); return Tr::tr("SDCC %1 (%2, %3)").arg(version, langName, archName); } diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index c38dc44054f..162b60102d0 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -601,7 +601,7 @@ Toolchain *findExternalToolchain(const QString &presetArchitecture, const QStrin // "strategy": "external" // } - auto msvcToolchains = ToolChainManager::toolchains([](const Toolchain *tc) { + auto msvcToolchains = ToolchainManager::toolchains([](const Toolchain *tc) { return tc->typeId() == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID; }); @@ -609,7 +609,7 @@ Toolchain *findExternalToolchain(const QString &presetArchitecture, const QStrin return tc->targetAbi().osFlavor(); })); - return ToolChainManager::toolChain( + return ToolchainManager::toolChain( [presetArchitecture, presetToolset, msvcFlavors](const Toolchain *tc) -> bool { if (tc->typeId() != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) return false; @@ -932,7 +932,7 @@ bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const return false; const bool compilersMatch = [k, data] { - const QList allLanguages = ToolChainManager::allLanguages(); + const QList allLanguages = ToolchainManager::allLanguages(); for (const ToolChainDescription &tcd : data->toolChains) { if (!Utils::contains(allLanguages, [&tcd](const Id &language) { return language == tcd.language; })) @@ -945,7 +945,7 @@ bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const return true; }(); const bool noCompilers = [k, data] { - const QList allLanguages = ToolChainManager::allLanguages(); + const QList allLanguages = ToolchainManager::allLanguages(); for (const ToolChainDescription &tcd : data->toolChains) { if (!Utils::contains(allLanguages, [&tcd](const Id &language) { return language == tcd.language; })) diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp index 67fcd19d2c4..bf92e71e779 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp @@ -77,7 +77,7 @@ Utils::Id getCompilerId(QString compilerName) Toolchain *toolchainFromCompilerId(const Utils::Id &compilerId, const Utils::Id &language) { - return ToolChainManager::toolChain([&compilerId, &language](const Toolchain *tc) { + return ToolchainManager::toolChain([&compilerId, &language](const Toolchain *tc) { if (!tc->isValid() || tc->language() != language) return false; return tc->typeId() == compilerId; @@ -112,7 +112,7 @@ Toolchain *toolchainFromFlags(const Kit *kit, const QStringList &flags, const Ut // Try exact compiler match. const Utils::FilePath compiler = Utils::FilePath::fromUserInput(compilerPath(flags.front())); - Toolchain *toolchain = ToolChainManager::toolChain([&compiler, &language](const Toolchain *tc) { + Toolchain *toolchain = ToolchainManager::toolChain([&compiler, &language](const Toolchain *tc) { return tc->isValid() && tc->language() == language && tc->compilerCommand() == compiler; }); if (toolchain) diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp index 24882d045f1..46a81a0b18f 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp @@ -39,7 +39,7 @@ void CompilationDatabaseTests::initTestCase() if (allKits.empty()) QSKIP("This test requires at least one kit to be present."); - Toolchain *toolchain = ToolChainManager::toolChain([](const Toolchain *tc) { + Toolchain *toolchain = ToolchainManager::toolChain([](const Toolchain *tc) { return tc->isValid() && tc->language() == ProjectExplorer::Constants::CXX_LANGUAGE_ID; }); if (!toolchain) diff --git a/src/plugins/docker/kitdetector.cpp b/src/plugins/docker/kitdetector.cpp index d2176760fad..fa6172541e8 100644 --- a/src/plugins/docker/kitdetector.cpp +++ b/src/plugins/docker/kitdetector.cpp @@ -106,11 +106,11 @@ void KitDetectorPrivate::undoAutoDetect() const }; emit q->logOutput('\n' + ProjectExplorer::Tr::tr("Removing toolchain entries...")); - const Toolchains toolchains = ToolChainManager::toolchains(); + const Toolchains toolchains = ToolchainManager::toolchains(); for (Toolchain *toolChain : toolchains) { if (toolChain && toolChain->detectionSource() == m_sharedId) { emit q->logOutput(ProjectExplorer::Tr::tr("Removed \"%1\"").arg(toolChain->displayName())); - ToolChainManager::deregisterToolChain(toolChain); + ToolchainManager::deregisterToolChain(toolChain); } }; @@ -164,7 +164,7 @@ void KitDetectorPrivate::listAutoDetected() const } emit q->logOutput('\n' + ProjectExplorer::Tr::tr("Toolchains:")); - for (Toolchain *toolChain : ToolChainManager::toolchains()) { + for (Toolchain *toolChain : ToolchainManager::toolchains()) { if (toolChain->detectionSource() == m_sharedId) emit q->logOutput(toolChain->displayName()); } @@ -251,7 +251,7 @@ Toolchains KitDetectorPrivate::autoDetectToolChains() { const QList factories = ToolchainFactory::allToolchainFactories(); - Toolchains alreadyKnown = ToolChainManager::toolchains(); + Toolchains alreadyKnown = ToolchainManager::toolchains(); Toolchains allNewToolChains; QApplication::processEvents(); emit q->logOutput('\n' + ProjectExplorer::Tr::tr("Searching toolchains...")); @@ -262,7 +262,7 @@ Toolchains KitDetectorPrivate::autoDetectToolChains() for (Toolchain *toolChain : newToolChains) { emit q->logOutput(ProjectExplorer::Tr::tr("Found \"%1\"").arg(toolChain->compilerCommand().toUserOutput())); toolChain->setDetectionSource(m_sharedId); - ToolChainManager::registerToolChain(toolChain); + ToolchainManager::registerToolChain(toolChain); alreadyKnown.append(toolChain); } allNewToolChains.append(newToolChains); @@ -359,7 +359,7 @@ void KitDetectorPrivate::autoDetect() QtSupport::QtKitAspect::setQtVersion(k, qt); } Toolchains toolchainsToSet; - toolchainsToSet = ToolChainManager::toolchains([qt, this](const Toolchain *tc) { + toolchainsToSet = ToolchainManager::toolchains([qt, this](const Toolchain *tc) { return tc->detectionSource() == m_sharedId && (!qt || qt->qtAbis().contains(tc->targetAbi())); }); diff --git a/src/plugins/ios/iosconfigurations.cpp b/src/plugins/ios/iosconfigurations.cpp index c205f3a6d59..a999fa82b1c 100644 --- a/src/plugins/ios/iosconfigurations.cpp +++ b/src/plugins/ios/iosconfigurations.cpp @@ -109,7 +109,7 @@ static QList clangToolChains(const Toolchains &toolChains) static QList autoDetectedIosToolChains() { - const QList toolChains = clangToolChains(ToolChainManager::toolchains()); + const QList toolChains = clangToolChains(ToolchainManager::toolchains()); return filtered(toolChains, [](GccToolChain *toolChain) { return toolChain->isAutoDetected() && (toolChain->displayName().startsWith("iphone") diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp index 619efa18902..350c89c8715 100644 --- a/src/plugins/mcusupport/mcupackage.cpp +++ b/src/plugins/mcusupport/mcupackage.cpp @@ -366,7 +366,7 @@ bool McuToolChainPackage::isDesktopToolchain() const Toolchain *McuToolChainPackage::msvcToolChain(Id language) { - Toolchain *toolChain = ToolChainManager::toolChain([language](const Toolchain *t) { + Toolchain *toolChain = ToolchainManager::toolChain([language](const Toolchain *t) { const Abi abi = t->targetAbi(); return abi.osFlavor() == Abi::WindowsMsvc2019Flavor && abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64 @@ -378,7 +378,7 @@ Toolchain *McuToolChainPackage::msvcToolChain(Id language) Toolchain *McuToolChainPackage::gccToolChain(Id language) { - Toolchain *toolChain = ToolChainManager::toolChain([language](const Toolchain *t) { + Toolchain *toolChain = ToolchainManager::toolChain([language](const Toolchain *t) { const Abi abi = t->targetAbi(); return abi.os() != Abi::WindowsOS && abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64 && t->language() == language; @@ -388,7 +388,7 @@ Toolchain *McuToolChainPackage::gccToolChain(Id language) static Toolchain *mingwToolChain(const FilePath &path, Id language) { - Toolchain *toolChain = ToolChainManager::toolChain([&path, language](const Toolchain *t) { + Toolchain *toolChain = ToolchainManager::toolChain([&path, language](const Toolchain *t) { // find a MinGW toolchain having the same path from registered toolchains const Abi abi = t->targetAbi(); return t->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID @@ -398,7 +398,7 @@ static Toolchain *mingwToolChain(const FilePath &path, Id language) if (!toolChain) { // if there's no MinGW toolchain having the same path, // a proper MinGW would be selected from the registered toolchains. - toolChain = ToolChainManager::toolChain([language](const Toolchain *t) { + toolChain = ToolchainManager::toolChain([language](const Toolchain *t) { const Abi abi = t->targetAbi(); return t->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID && abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64 @@ -410,7 +410,7 @@ static Toolchain *mingwToolChain(const FilePath &path, Id language) static Toolchain *armGccToolChain(const FilePath &path, Id language) { - Toolchain *toolChain = ToolChainManager::toolChain([&path, language](const Toolchain *t) { + Toolchain *toolChain = ToolchainManager::toolChain([&path, language](const Toolchain *t) { return t->compilerCommand() == path && t->language() == language; }); if (!toolChain) { @@ -426,7 +426,7 @@ static Toolchain *armGccToolChain(const FilePath &path, Id language) toolChain = detected.first(); toolChain->setDetection(Toolchain::ManualDetection); toolChain->setDisplayName("Arm GCC"); - ToolChainManager::registerToolChain(toolChain); + ToolchainManager::registerToolChain(toolChain); } } } @@ -436,7 +436,7 @@ static Toolchain *armGccToolChain(const FilePath &path, Id language) static Toolchain *iarToolChain(const FilePath &path, Id language) { - Toolchain *toolChain = ToolChainManager::toolChain([language](const Toolchain *t) { + Toolchain *toolChain = ToolchainManager::toolChain([language](const Toolchain *t) { return t->typeId() == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID && t->language() == language; }); @@ -457,7 +457,7 @@ static Toolchain *iarToolChain(const FilePath &path, Id language) toolChain = tc; toolChain->setDetection(Toolchain::ManualDetection); toolChain->setDisplayName("IAREW"); - ToolChainManager::registerToolChain(toolChain); + ToolchainManager::registerToolChain(toolChain); } } } diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index ff7d20b3f82..589fa27e1d5 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -328,7 +328,7 @@ McuToolChainPackagePtr createIarToolChainPackage(const SettingsHandler::Ptr &set if (qtcEnvironmentVariableIsSet(envVar)) defaultPath = FilePath::fromUserInput(qtcEnvironmentVariable(envVar)); else { - const ProjectExplorer::Toolchain *tc = ProjectExplorer::ToolChainManager::toolChain( + const ProjectExplorer::Toolchain *tc = ProjectExplorer::ToolchainManager::toolChain( [](const ProjectExplorer::Toolchain *t) { return t->typeId() == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID; }); diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index ea16af2cd96..2175f3ab653 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -71,7 +71,7 @@ using CMakeProjectManager::CMakeConfigurationKitAspect; using ProjectExplorer::Kit; using ProjectExplorer::KitManager; using ProjectExplorer::Toolchain; -using ProjectExplorer::ToolChainManager; +using ProjectExplorer::ToolchainManager; using testing::_; using testing::Return; @@ -216,7 +216,7 @@ void verifyIarToolchain(const McuToolChainPackagePtr &iarToolchainPackage) Id iarId{BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID}; Toolchain *iarToolchain{ProjectExplorer::ToolchainFactory::createToolChain(iarId)}; iarToolchain->setLanguage(cxxLanguageId); - ToolChainManager::registerToolChain(iarToolchain); + ToolchainManager::registerToolChain(iarToolchain); QVERIFY(iarToolchainPackage != nullptr); QCOMPARE(iarToolchainPackage->cmakeVariableName(), TOOLCHAIN_DIR_CMAKE_VARIABLE); @@ -240,7 +240,7 @@ void verifyArmGccToolchain(const McuToolChainPackagePtr &armGccPackage, const QS Toolchain *armToolchain{ProjectExplorer::ToolchainFactory::createToolChain(armGccId)}; armToolchain->setLanguage(cxxLanguageId); - ToolChainManager::registerToolChain(armToolchain); + ToolchainManager::registerToolChain(armToolchain); QVERIFY(armGccPackage != nullptr); QCOMPARE(armGccPackage->cmakeVariableName(), TOOLCHAIN_DIR_CMAKE_VARIABLE); diff --git a/src/plugins/nim/nimplugin.cpp b/src/plugins/nim/nimplugin.cpp index d3495f0a24a..6cca4f90057 100644 --- a/src/plugins/nim/nimplugin.cpp +++ b/src/plugins/nim/nimplugin.cpp @@ -69,7 +69,7 @@ void NimPlugin::initialize() { d = new NimPluginPrivate; - ToolChainManager::registerLanguage(Constants::C_NIMLANGUAGE_ID, Constants::C_NIMLANGUAGE_NAME); + ToolchainManager::registerLanguage(Constants::C_NIMLANGUAGE_ID, Constants::C_NIMLANGUAGE_NAME); TextEditor::SnippetProvider::registerGroup(Constants::C_NIMSNIPPETSGROUP_ID, Tr::tr("Nim", "SnippetProvider"), diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index 1989e322143..c8a4cbf7060 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -283,7 +283,7 @@ static Abis guessGccAbi(const QString &m, const ProjectExplorer::Macros ¯os) } else if (arch == Abi::X86Architecture && (width == 0 || width == 64)) { abiList << Abi(arch, os, flavor, format, 64); if (width != 64 || (!m.contains("mingw") - && ToolChainManager::detectionSettings().detectX64AsX32)) { + && ToolchainManager::detectionSettings().detectX64AsX32)) { abiList << Abi(arch, os, flavor, format, 32); } } else { @@ -424,7 +424,7 @@ QString GccToolChain::defaultDisplayName() const if (abi.architecture() == Abi::UnknownArchitecture || abi.wordWidth() == 0) return type; return Tr::tr("%1 (%2, %3 %4 at %5)").arg(type, - ToolChainManager::displayNameOfLanguageId(language()), + ToolchainManager::displayNameOfLanguageId(language()), Abi::toString(abi.architecture()), Abi::toString(abi.wordWidth()), compilerCommand().toUserOutput()); @@ -437,7 +437,7 @@ LanguageExtensions GccToolChain::defaultLanguageExtensions() const static const Toolchains mingwToolChains() { - return ToolChainManager::toolchains([](const Toolchain *tc) -> bool { + return ToolchainManager::toolchains([](const Toolchain *tc) -> bool { return tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID; }); } @@ -866,7 +866,7 @@ QStringList GccToolChain::suggestedMkspecList() const } if (m_subType == Clang) { - if (const Toolchain * const parentTc = ToolChainManager::findToolChain(m_parentToolChainId)) + if (const Toolchain * const parentTc = ToolchainManager::findToolChain(m_parentToolChainId)) return parentTc->suggestedMkspecList(); const Abi abi = targetAbi(); if (abi.os() == Abi::DarwinOS) @@ -1624,13 +1624,13 @@ Toolchains GccToolchainFactory::autoDetectToolChain(const ToolChainDescription & Environment systemEnvironment = tcd.compilerPath.deviceEnvironment(); GccToolChain::addCommandPathToEnvironment(tcd.compilerPath, systemEnvironment); const FilePath localCompilerPath = findLocalCompiler(tcd.compilerPath, systemEnvironment); - if (ToolChainManager::isBadToolchain(localCompilerPath)) + if (ToolchainManager::isBadToolchain(localCompilerPath)) return result; Macros macros = gccPredefinedMacros(localCompilerPath, gccPredefinedMacrosOptions(tcd.language), systemEnvironment); if (macros.isEmpty()) { - ToolChainManager::addBadToolchain(localCompilerPath); + ToolchainManager::addBadToolchain(localCompilerPath); return result; } const GccToolChain::DetectedAbisResult detectedAbis = guessGccAbi(localCompilerPath, @@ -1757,19 +1757,19 @@ GccToolChainConfigWidget::GccToolChainConfigWidget(GccToolChain *tc) : Tr::tr("Parent toolchain:"), m_parentToolchainCombo); - ToolChainManager *tcManager = ToolChainManager::instance(); + ToolchainManager *tcManager = ToolchainManager::instance(); m_parentToolChainConnections.append( - connect(tcManager, &ToolChainManager::toolChainUpdated, this, [this](Toolchain *tc) { + connect(tcManager, &ToolchainManager::toolChainUpdated, this, [this](Toolchain *tc) { if (tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID) updateParentToolChainComboBox(); })); m_parentToolChainConnections.append( - connect(tcManager, &ToolChainManager::toolChainAdded, this, [this](Toolchain *tc) { + connect(tcManager, &ToolchainManager::toolChainAdded, this, [this](Toolchain *tc) { if (tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID) updateParentToolChainComboBox(); })); m_parentToolChainConnections.append( - connect(tcManager, &ToolChainManager::toolChainRemoved, this, [this](Toolchain *tc) { + connect(tcManager, &ToolchainManager::toolChainRemoved, this, [this](Toolchain *tc) { if (tc->id() == toolChain()->id()) { for (QMetaObject::Connection &connection : m_parentToolChainConnections) QObject::disconnect(connection); @@ -1956,10 +1956,10 @@ void GccToolChain::syncAutodetectedWithParentToolchains() QObject::disconnect(m_thisToolchainRemovedConnection); QObject::disconnect(m_mingwToolchainAddedConnection); - if (!ToolChainManager::isLoaded()) { - connect(ToolChainManager::instance(), &ToolChainManager::toolChainsLoaded, this, + if (!ToolchainManager::isLoaded()) { + connect(ToolchainManager::instance(), &ToolchainManager::toolChainsLoaded, this, [id = id()] { - if (Toolchain * const tc = ToolChainManager::findToolChain(id)) { + if (Toolchain * const tc = ToolchainManager::findToolChain(id)) { if (tc->typeId() == Constants::CLANG_TOOLCHAIN_TYPEID) static_cast(tc)->syncAutodetectedWithParentToolchains(); } @@ -1973,16 +1973,16 @@ void GccToolChain::syncAutodetectedWithParentToolchains() } // Subscribe only autodetected toolchains. - ToolChainManager *tcManager = ToolChainManager::instance(); + ToolchainManager *tcManager = ToolchainManager::instance(); m_mingwToolchainAddedConnection - = connect(tcManager, &ToolChainManager::toolChainAdded, this, [this](Toolchain *tc) { + = connect(tcManager, &ToolchainManager::toolChainAdded, this, [this](Toolchain *tc) { if (tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID && !mingwToolChainFromId(m_parentToolChainId)) { m_parentToolChainId = tc->id(); } }); m_thisToolchainRemovedConnection - = connect(tcManager, &ToolChainManager::toolChainRemoved, this, [this](Toolchain *tc) { + = connect(tcManager, &ToolchainManager::toolChainRemoved, this, [this](Toolchain *tc) { if (tc == this) { QObject::disconnect(m_thisToolchainRemovedConnection); QObject::disconnect(m_mingwToolchainAddedConnection); diff --git a/src/plugins/projectexplorer/kitaspects.cpp b/src/plugins/projectexplorer/kitaspects.cpp index 218deea329c..068c663c2c0 100644 --- a/src/plugins/projectexplorer/kitaspects.cpp +++ b/src/plugins/projectexplorer/kitaspects.cpp @@ -204,14 +204,14 @@ public: layout->setContentsMargins(0, 0, 0, 0); layout->setColumnStretch(1, 2); - const QList languageList = sorted(ToolChainManager::allLanguages(), [](Id l1, Id l2) { - return ToolChainManager::displayNameOfLanguageId(l1) - < ToolChainManager::displayNameOfLanguageId(l2); + const QList languageList = sorted(ToolchainManager::allLanguages(), [](Id l1, Id l2) { + return ToolchainManager::displayNameOfLanguageId(l1) + < ToolchainManager::displayNameOfLanguageId(l2); }); QTC_ASSERT(!languageList.isEmpty(), return); int row = 0; for (Id l : std::as_const(languageList)) { - layout->addWidget(new QLabel(ToolChainManager::displayNameOfLanguageId(l) + ':'), row, 0); + layout->addWidget(new QLabel(ToolchainManager::displayNameOfLanguageId(l) + ':'), row, 0); auto cb = new QComboBox; cb->setSizePolicy(QSizePolicy::Ignored, cb->sizePolicy().verticalPolicy()); cb->setToolTip(factory->description()); @@ -249,7 +249,7 @@ private: const GuardLocker locker(m_ignoreChanges); const QList keys = m_languageComboboxMap.keys(); for (const Id l : keys) { - const Toolchains ltcList = ToolChainManager::toolchains(equal(&Toolchain::language, l)); + const Toolchains ltcList = ToolchainManager::toolchains(equal(&Toolchain::language, l)); QComboBox *cb = m_languageComboboxMap.value(l); cb->clear(); @@ -292,7 +292,7 @@ private: return; const QByteArray id = m_languageComboboxMap.value(language)->itemData(idx).toByteArray(); - Toolchain *tc = ToolChainManager::findToolChain(id); + Toolchain *tc = ToolchainManager::findToolChain(id); QTC_ASSERT(!tc || tc->language() == language, return); if (tc) ToolchainKitAspect::setToolChain(m_kit, tc); @@ -361,8 +361,8 @@ static QMap defaultToolChainIds() { QMap toolChains; const Abi abi = Abi::hostAbi(); - const Toolchains tcList = ToolChainManager::toolchains(equal(&Toolchain::targetAbi, abi)); - const QList languages = ToolChainManager::allLanguages(); + const Toolchains tcList = ToolchainManager::toolchains(equal(&Toolchain::targetAbi, abi)); + const QList languages = ToolchainManager::allLanguages(); for (Id l : languages) { Toolchain *tc = findOrDefault(tcList, equal(&Toolchain::language, l)); toolChains.insert(l, tc ? tc->id() : QByteArray()); @@ -404,14 +404,14 @@ Tasks ToolchainKitAspectFactory::validate(const Kit *k) const void ToolchainKitAspectFactory::fix(Kit *k) { - QTC_ASSERT(ToolChainManager::isLoaded(), return); - const QList languages = ToolChainManager::allLanguages(); + QTC_ASSERT(ToolchainManager::isLoaded(), return); + const QList languages = ToolchainManager::allLanguages(); for (const Id l : languages) { const QByteArray tcId = ToolchainKitAspect::toolChainId(k, l); - if (!tcId.isEmpty() && !ToolChainManager::findToolChain(tcId)) { + if (!tcId.isEmpty() && !ToolchainManager::findToolChain(tcId)) { qWarning("Tool chain set up in kit \"%s\" for \"%s\" not found.", qPrintable(k->displayName()), - qPrintable(ToolChainManager::displayNameOfLanguageId(l))); + qPrintable(ToolchainManager::displayNameOfLanguageId(l))); ToolchainKitAspect::clearToolChain(k, l); // make sure to clear out no longer known tool chains } } @@ -420,13 +420,13 @@ void ToolchainKitAspectFactory::fix(Kit *k) static Id findLanguage(const QString &ls) { QString lsUpper = ls.toUpper(); - return Utils::findOrDefault(ToolChainManager::allLanguages(), + return Utils::findOrDefault(ToolchainManager::allLanguages(), [lsUpper](Id l) { return lsUpper == l.toString().toUpper(); }); } void ToolchainKitAspectFactory::setup(Kit *k) { - QTC_ASSERT(ToolChainManager::isLoaded(), return); + QTC_ASSERT(ToolchainManager::isLoaded(), return); QTC_ASSERT(k, return); Store value = storeFromVariant(k->value(id())); @@ -443,14 +443,14 @@ void ToolchainKitAspectFactory::setup(Kit *k) } const QByteArray id = i.value().toByteArray(); - Toolchain *tc = ToolChainManager::findToolChain(id); + Toolchain *tc = ToolchainManager::findToolChain(id); if (tc) continue; // ID is not found: Might be an ABI string... lockToolchains = false; const QString abi = QString::fromUtf8(id); - const Toolchains possibleTcs = ToolChainManager::toolchains([abi, l](const Toolchain *t) { + const Toolchains possibleTcs = ToolchainManager::toolchains([abi, l](const Toolchain *t) { return t->targetAbi().toString() == abi && t->language() == l; }); Toolchain *bestTc = nullptr; @@ -548,7 +548,7 @@ Id ToolchainKitAspect::id() QByteArray ToolchainKitAspect::toolChainId(const Kit *k, Id language) { - QTC_ASSERT(ToolChainManager::isLoaded(), return nullptr); + QTC_ASSERT(ToolchainManager::isLoaded(), return nullptr); if (!k) return {}; Store value = storeFromVariant(k->value(ToolchainKitAspect::id())); @@ -557,17 +557,17 @@ QByteArray ToolchainKitAspect::toolChainId(const Kit *k, Id language) Toolchain *ToolchainKitAspect::toolChain(const Kit *k, Id language) { - return ToolChainManager::findToolChain(toolChainId(k, language)); + return ToolchainManager::findToolChain(toolChainId(k, language)); } Toolchain *ToolchainKitAspect::cToolChain(const Kit *k) { - return ToolChainManager::findToolChain(toolChainId(k, ProjectExplorer::Constants::C_LANGUAGE_ID)); + return ToolchainManager::findToolChain(toolChainId(k, ProjectExplorer::Constants::C_LANGUAGE_ID)); } Toolchain *ToolchainKitAspect::cxxToolChain(const Kit *k) { - return ToolChainManager::findToolChain(toolChainId(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID)); + return ToolchainManager::findToolChain(toolChainId(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID)); } @@ -577,8 +577,8 @@ QList ToolchainKitAspect::toolChains(const Kit *k) const Store value = storeFromVariant(k->value(ToolchainKitAspect::id())); const QList tcList - = transform(ToolChainManager::allLanguages(), [&value](Id l) { - return ToolChainManager::findToolChain(value.value(l.toKey()).toByteArray()); + = transform(ToolchainManager::allLanguages(), [&value](Id l) { + return ToolchainManager::findToolChain(value.value(l.toKey()).toByteArray()); }); return filtered(tcList, [](Toolchain *tc) { return tc; }); } @@ -608,13 +608,13 @@ void ToolchainKitAspect::setAllToolChainsToMatch(Kit *k, Toolchain *tc) QTC_ASSERT(tc, return); QTC_ASSERT(k, return); - const Toolchains allTcList = ToolChainManager::toolchains(); + const Toolchains allTcList = ToolchainManager::toolchains(); QTC_ASSERT(allTcList.contains(tc), return); Store result = storeFromVariant(k->value(ToolchainKitAspect::id())); result.insert(tc->language().toKey(), tc->id()); - for (const Id l : ToolChainManager::allLanguages()) { + for (const Id l : ToolchainManager::allLanguages()) { if (l == tc->language()) continue; @@ -695,9 +695,9 @@ void ToolchainKitAspectFactory::onKitsLoaded() for (Kit *k : KitManager::kits()) fix(k); - connect(ToolChainManager::instance(), &ToolChainManager::toolChainRemoved, + connect(ToolchainManager::instance(), &ToolchainManager::toolChainRemoved, this, &ToolchainKitAspectFactory::toolChainRemoved); - connect(ToolChainManager::instance(), &ToolChainManager::toolChainUpdated, + connect(ToolchainManager::instance(), &ToolchainManager::toolChainUpdated, this, &ToolchainKitAspectFactory::toolChainUpdated); } diff --git a/src/plugins/projectexplorer/kitmanager.cpp b/src/plugins/projectexplorer/kitmanager.cpp index b228ea7c698..1778c560892 100644 --- a/src/plugins/projectexplorer/kitmanager.cpp +++ b/src/plugins/projectexplorer/kitmanager.cpp @@ -306,7 +306,7 @@ void KitManager::restoreKits() // TODO: This should not need to be done here. Instead, it should be a convenience // operation on some lower level, e.g. in the toolchain class(es). // Also, we shouldn't detect so many doublets in the first place. - for (Toolchain * const tc : ToolChainManager::toolchains()) { + for (Toolchain * const tc : ToolchainManager::toolchains()) { Toolchain *&bestTc = uniqueToolchains[tc->targetAbi()][tc->language()]; if (!bestTc) { bestTc = tc; diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 711a934d5f9..cfd3e55910a 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -1560,8 +1560,8 @@ void ProjectExplorerPlugin::testSourceToBinaryMapping() QVERIFY(toolchain); if (const auto msvcToolchain = dynamic_cast(toolchain)) { while (!msvcToolchain->environmentInitialized()) { - QSignalSpy parsingFinishedSpy(ToolChainManager::instance(), - &ToolChainManager::toolChainUpdated); + QSignalSpy parsingFinishedSpy(ToolchainManager::instance(), + &ToolchainManager::toolChainUpdated); QVERIFY(parsingFinishedSpy.wait(10000)); } } diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index f6c61bded15..1b8ac5f4971 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -632,7 +632,7 @@ public: bool m_shouldHaveRunConfiguration = false; Id m_runMode = Constants::NO_RUN_MODE; - ToolChainManager *m_toolChainManager = nullptr; + ToolchainManager *m_toolChainManager = nullptr; #ifdef WITH_JOURNALD JournaldWatcher m_journalWatcher; @@ -826,11 +826,11 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er handleCommandLineArguments(arguments); - dd->m_toolChainManager = new ToolChainManager; + dd->m_toolChainManager = new ToolchainManager; // Register languages - ToolChainManager::registerLanguage(Constants::C_LANGUAGE_ID, Tr::tr("C")); - ToolChainManager::registerLanguage(Constants::CXX_LANGUAGE_ID, Tr::tr("C++")); + ToolchainManager::registerLanguage(Constants::C_LANGUAGE_ID, Tr::tr("C")); + ToolchainManager::registerLanguage(Constants::CXX_LANGUAGE_ID, Tr::tr("C++")); IWizardFactory::registerFeatureProvider(new KitFeatureProvider); IWizardFactory::registerFactoryCreator([] { return new SimpleProjectWizard; }); @@ -2118,7 +2118,7 @@ bool ProjectExplorerPlugin::delayedInitialize() { NANOTRACE_SCOPE("ProjectExplorer", "ProjectExplorerPlugin::restoreKits"); ExtraAbi::load(); // Load this before Toolchains! - ToolChainManager::restoreToolChains(); + ToolchainManager::restoreToolChains(); KitManager::restoreKits(); return true; } @@ -2133,7 +2133,7 @@ IPlugin::ShutdownFlag ProjectExplorerPlugin::aboutToShutdown() disconnect(ModeManager::instance(), &ModeManager::currentModeChanged, dd, &ProjectExplorerPluginPrivate::currentModeChanged); ProjectTree::aboutToShutDown(); - ToolChainManager::aboutToShutdown(); + ToolchainManager::aboutToShutdown(); ProjectManager::closeAllProjects(); // Attempt to synchronously shutdown all run controls. diff --git a/src/plugins/projectexplorer/projectimporter.cpp b/src/plugins/projectexplorer/projectimporter.cpp index b55888159b2..4bf718348fd 100644 --- a/src/plugins/projectexplorer/projectimporter.cpp +++ b/src/plugins/projectexplorer/projectimporter.cpp @@ -313,7 +313,7 @@ bool ProjectImporter::findTemporaryHandler(Utils::Id id) const static Toolchain *toolChainFromVariant(const QVariant &v) { const QByteArray tcId = v.toByteArray(); - return ToolChainManager::findToolChain(tcId); + return ToolchainManager::findToolChain(tcId); } void ProjectImporter::cleanupTemporaryToolChains(Kit *k, const QVariantList &vl) @@ -321,7 +321,7 @@ void ProjectImporter::cleanupTemporaryToolChains(Kit *k, const QVariantList &vl) for (const QVariant &v : vl) { Toolchain *tc = toolChainFromVariant(v); QTC_ASSERT(tc, continue); - ToolChainManager::deregisterToolChain(tc); + ToolchainManager::deregisterToolChain(tc); ToolchainKitAspect::setToolChain(k, nullptr); } } @@ -333,7 +333,7 @@ void ProjectImporter::persistTemporaryToolChains(Kit *k, const QVariantList &vl) QTC_ASSERT(tmpTc, continue); Toolchain *actualTc = ToolchainKitAspect::toolChain(k, tmpTc->language()); if (tmpTc && actualTc != tmpTc) - ToolChainManager::deregisterToolChain(tmpTc); + ToolchainManager::deregisterToolChain(tmpTc); } } @@ -376,7 +376,7 @@ static ProjectImporter::ToolChainData createToolChains(const ToolChainDescriptio continue; for (Toolchain *tc : std::as_const(data.tcs)) - ToolChainManager::registerToolChain(tc); + ToolchainManager::registerToolChain(tc); data.areTemporary = true; break; @@ -389,7 +389,7 @@ ProjectImporter::ToolChainData ProjectImporter::findOrCreateToolChains(const ToolChainDescription &tcd) const { ToolChainData result; - result.tcs = ToolChainManager::toolchains([&tcd](const Toolchain *tc) { + result.tcs = ToolchainManager::toolchains([&tcd](const Toolchain *tc) { return tc->language() == tcd.language && tc->matchesCompilerCommand(tcd.compilerPath); }); for (const Toolchain *tc : std::as_const(result.tcs)) { diff --git a/src/plugins/projectexplorer/toolchain.cpp b/src/plugins/projectexplorer/toolchain.cpp index 30eb101ef44..6407f393933 100644 --- a/src/plugins/projectexplorer/toolchain.cpp +++ b/src/plugins/projectexplorer/toolchain.cpp @@ -112,9 +112,9 @@ QString languageId(Language l) using namespace Internal; /*! - \class ProjectExplorer::ToolChain - \brief The ToolChain class represents a tool chain. - \sa ProjectExplorer::ToolChainManager + \class ProjectExplorer::Toolchain + \brief The Toolchain class represents a tool chain. + \sa ProjectExplorer::ToolchainManager */ // -------------------------------------------------------------------------- @@ -128,7 +128,7 @@ void Toolchain::setLanguage(Id language) { QTC_ASSERT(!d->m_language.isValid() || isAutoDetected(), return); QTC_ASSERT(language.isValid(), return); - QTC_ASSERT(ToolChainManager::isLanguageSupported(language), return); + QTC_ASSERT(ToolchainManager::isLanguageSupported(language), return); d->m_language = language; } @@ -272,7 +272,7 @@ void Toolchain::toolChainUpdated() d->m_predefinedMacrosCache->invalidate(); d->m_headerPathsCache->invalidate(); - ToolChainManager::notifyAboutUpdate(this); + ToolchainManager::notifyAboutUpdate(this); } void Toolchain::setDetection(Toolchain::Detection de) @@ -648,7 +648,7 @@ Toolchain *ToolchainFactory::createToolChain(Id toolChainType) QList ToolchainFactory::supportedLanguages() const { - return m_supportsAllLanguages ? ToolChainManager::allLanguages() : m_supportedLanguages; + return m_supportsAllLanguages ? ToolchainManager::allLanguages() : m_supportedLanguages; } Id ToolchainFactory::supportedToolChainType() const diff --git a/src/plugins/projectexplorer/toolchainmanager.cpp b/src/plugins/projectexplorer/toolchainmanager.cpp index f3b507aee68..6c8242c936e 100644 --- a/src/plugins/projectexplorer/toolchainmanager.cpp +++ b/src/plugins/projectexplorer/toolchainmanager.cpp @@ -24,7 +24,7 @@ namespace ProjectExplorer { namespace Internal { // -------------------------------------------------------------------------- -// ToolChainManagerPrivate +// ToolchainManagerPrivate // -------------------------------------------------------------------------- struct LanguageDisplayPair @@ -33,10 +33,10 @@ struct LanguageDisplayPair QString displayName; }; -class ToolChainManagerPrivate +class ToolchainManagerPrivate { public: - ~ToolChainManagerPrivate(); + ~ToolchainManagerPrivate(); std::unique_ptr m_accessor; @@ -47,14 +47,14 @@ public: bool m_loaded = false; }; -ToolChainManagerPrivate::~ToolChainManagerPrivate() +ToolchainManagerPrivate::~ToolchainManagerPrivate() { qDeleteAll(m_toolChains); m_toolChains.clear(); } -static ToolChainManager *m_instance = nullptr; -static ToolChainManagerPrivate *d = nullptr; +static ToolchainManager *m_instance = nullptr; +static ToolchainManagerPrivate *d = nullptr; } // namespace Internal @@ -65,22 +65,22 @@ const char DETECT_X64_AS_X32_KEY[] = "ProjectExplorer/Toolchains/DetectX64AsX32" static Key badToolchainsKey() { return "BadToolChains"; } // -------------------------------------------------------------------------- -// ToolChainManager +// ToolchainManager // -------------------------------------------------------------------------- -ToolChainManager::ToolChainManager(QObject *parent) : +ToolchainManager::ToolchainManager(QObject *parent) : QObject(parent) { Q_ASSERT(!m_instance); m_instance = this; - d = new ToolChainManagerPrivate; + d = new ToolchainManagerPrivate; connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested, - this, &ToolChainManager::saveToolChains); - connect(this, &ToolChainManager::toolChainAdded, this, &ToolChainManager::toolChainsChanged); - connect(this, &ToolChainManager::toolChainRemoved, this, &ToolChainManager::toolChainsChanged); - connect(this, &ToolChainManager::toolChainUpdated, this, &ToolChainManager::toolChainsChanged); + this, &ToolchainManager::saveToolChains); + connect(this, &ToolchainManager::toolChainAdded, this, &ToolchainManager::toolChainsChanged); + connect(this, &ToolchainManager::toolChainRemoved, this, &ToolchainManager::toolChainsChanged); + connect(this, &ToolchainManager::toolChainUpdated, this, &ToolchainManager::toolChainsChanged); QtcSettings * const s = Core::ICore::settings(); d->m_detectionSettings.detectX64AsX32 @@ -88,21 +88,21 @@ ToolChainManager::ToolChainManager(QObject *parent) : d->m_badToolchains = BadToolchains::fromVariant(s->value(badToolchainsKey())); } -ToolChainManager::~ToolChainManager() +ToolchainManager::~ToolchainManager() { m_instance = nullptr; delete d; d = nullptr; } -ToolChainManager *ToolChainManager::instance() +ToolchainManager *ToolchainManager::instance() { return m_instance; } -void ToolChainManager::restoreToolChains() +void ToolchainManager::restoreToolChains() { - NANOTRACE_SCOPE("ProjectExplorer", "ToolChainManager::restoreToolChains"); + NANOTRACE_SCOPE("ProjectExplorer", "ToolchainManager::restoreToolChains"); QTC_ASSERT(!d->m_accessor, return); d->m_accessor = std::make_unique(); @@ -113,7 +113,7 @@ void ToolChainManager::restoreToolChains() emit m_instance->toolChainsLoaded(); } -void ToolChainManager::saveToolChains() +void ToolchainManager::saveToolChains() { QTC_ASSERT(d->m_accessor, return); @@ -125,25 +125,25 @@ void ToolChainManager::saveToolChains() s->setValue(badToolchainsKey(), d->m_badToolchains.toVariant()); } -const Toolchains &ToolChainManager::toolchains() +const Toolchains &ToolchainManager::toolchains() { QTC_CHECK(d->m_loaded); return d->m_toolChains; } -Toolchains ToolChainManager::toolchains(const Toolchain::Predicate &predicate) +Toolchains ToolchainManager::toolchains(const Toolchain::Predicate &predicate) { QTC_ASSERT(predicate, return {}); return Utils::filtered(d->m_toolChains, predicate); } -Toolchain *ToolChainManager::toolChain(const Toolchain::Predicate &predicate) +Toolchain *ToolchainManager::toolChain(const Toolchain::Predicate &predicate) { QTC_CHECK(d->m_loaded); return Utils::findOrDefault(d->m_toolChains, predicate); } -Toolchains ToolChainManager::findToolChains(const Abi &abi) +Toolchains ToolchainManager::findToolChains(const Abi &abi) { QTC_CHECK(d->m_loaded); Toolchains result; @@ -158,7 +158,7 @@ Toolchains ToolChainManager::findToolChains(const Abi &abi) return result; } -Toolchain *ToolChainManager::findToolChain(const QByteArray &id) +Toolchain *ToolchainManager::findToolChain(const QByteArray &id) { QTC_CHECK(d->m_loaded); if (id.isEmpty()) @@ -179,19 +179,19 @@ Toolchain *ToolChainManager::findToolChain(const QByteArray &id) return tc; } -bool ToolChainManager::isLoaded() +bool ToolchainManager::isLoaded() { return d->m_loaded; } -void ToolChainManager::notifyAboutUpdate(Toolchain *tc) +void ToolchainManager::notifyAboutUpdate(Toolchain *tc) { if (!tc || !d->m_toolChains.contains(tc)) return; emit m_instance->toolChainUpdated(tc); } -bool ToolChainManager::registerToolChain(Toolchain *tc) +bool ToolchainManager::registerToolChain(Toolchain *tc) { QTC_ASSERT(tc, return false); QTC_ASSERT(isLanguageSupported(tc->language()), @@ -214,7 +214,7 @@ bool ToolChainManager::registerToolChain(Toolchain *tc) return true; } -void ToolChainManager::deregisterToolChain(Toolchain *tc) +void ToolchainManager::deregisterToolChain(Toolchain *tc) { QTC_CHECK(d->m_loaded); if (!tc || !d->m_toolChains.contains(tc)) @@ -224,12 +224,12 @@ void ToolChainManager::deregisterToolChain(Toolchain *tc) delete tc; } -QList ToolChainManager::allLanguages() +QList ToolchainManager::allLanguages() { return Utils::transform(d->m_languages, &LanguageDisplayPair::id); } -bool ToolChainManager::registerLanguage(const Utils::Id &language, const QString &displayName) +bool ToolchainManager::registerLanguage(const Utils::Id &language, const QString &displayName) { QTC_ASSERT(language.isValid(), return false); QTC_ASSERT(!isLanguageSupported(language), return false); @@ -238,7 +238,7 @@ bool ToolChainManager::registerLanguage(const Utils::Id &language, const QString return true; } -QString ToolChainManager::displayNameOfLanguageId(const Utils::Id &id) +QString ToolchainManager::displayNameOfLanguageId(const Utils::Id &id) { QTC_ASSERT(id.isValid(), return Tr::tr("None")); auto entry = Utils::findOrDefault(d->m_languages, Utils::equal(&LanguageDisplayPair::id, id)); @@ -246,38 +246,38 @@ QString ToolChainManager::displayNameOfLanguageId(const Utils::Id &id) return entry.displayName; } -bool ToolChainManager::isLanguageSupported(const Utils::Id &id) +bool ToolchainManager::isLanguageSupported(const Utils::Id &id) { return Utils::contains(d->m_languages, Utils::equal(&LanguageDisplayPair::id, id)); } -void ToolChainManager::aboutToShutdown() +void ToolchainManager::aboutToShutdown() { if (HostOsInfo::isWindowsHost()) MsvcToolChain::cancelMsvcToolChainDetection(); } -ToolchainDetectionSettings ToolChainManager::detectionSettings() +ToolchainDetectionSettings ToolchainManager::detectionSettings() { return d->m_detectionSettings; } -void ToolChainManager::setDetectionSettings(const ToolchainDetectionSettings &settings) +void ToolchainManager::setDetectionSettings(const ToolchainDetectionSettings &settings) { d->m_detectionSettings = settings; } -void ToolChainManager::resetBadToolchains() +void ToolchainManager::resetBadToolchains() { d->m_badToolchains.toolchains.clear(); } -bool ToolChainManager::isBadToolchain(const Utils::FilePath &toolchain) +bool ToolchainManager::isBadToolchain(const Utils::FilePath &toolchain) { return d->m_badToolchains.isBadToolchain(toolchain); } -void ToolChainManager::addBadToolchain(const Utils::FilePath &toolchain) +void ToolchainManager::addBadToolchain(const Utils::FilePath &toolchain) { d->m_badToolchains.toolchains << toolchain; } diff --git a/src/plugins/projectexplorer/toolchainmanager.h b/src/plugins/projectexplorer/toolchainmanager.h index c43c029c015..a85ff96de0f 100644 --- a/src/plugins/projectexplorer/toolchainmanager.h +++ b/src/plugins/projectexplorer/toolchainmanager.h @@ -28,16 +28,16 @@ public: }; // -------------------------------------------------------------------------- -// ToolChainManager +// ToolchainManager // -------------------------------------------------------------------------- -class PROJECTEXPLORER_EXPORT ToolChainManager : public QObject +class PROJECTEXPLORER_EXPORT ToolchainManager : public QObject { Q_OBJECT public: - static ToolChainManager *instance(); - ~ToolChainManager() override; + static ToolchainManager *instance(); + ~ToolchainManager() override; static const Toolchains &toolchains(); static Toolchains toolchains(const Toolchain::Predicate &predicate); @@ -79,7 +79,7 @@ signals: void toolChainsLoaded(); private: - explicit ToolChainManager(QObject *parent = nullptr); + explicit ToolchainManager(QObject *parent = nullptr); // Make sure the this is only called after all toolchain factories are registered! static void restoreToolChains(); diff --git a/src/plugins/projectexplorer/toolchainoptionspage.cpp b/src/plugins/projectexplorer/toolchainoptionspage.cpp index 822b386b372..e1a857bcf48 100644 --- a/src/plugins/projectexplorer/toolchainoptionspage.cpp +++ b/src/plugins/projectexplorer/toolchainoptionspage.cpp @@ -154,7 +154,7 @@ class ToolChainOptionsWidget final : public Core::IOptionsPageWidget public: ToolChainOptionsWidget() { - m_detectionSettings = ToolChainManager::detectionSettings(); + m_detectionSettings = ToolchainManager::detectionSettings(); m_factories = Utils::filtered(ToolchainFactory::allToolchainFactories(), [](ToolchainFactory *factory) { return factory->canCreate();}); @@ -163,9 +163,9 @@ public: {ProjectExplorer::Constants::msgAutoDetectedToolTip()}); auto manualRoot = new StaticTreeItem(ProjectExplorer::Constants::msgManual()); - const QList languages = ToolChainManager::allLanguages(); + const QList languages = ToolchainManager::allLanguages(); for (const Utils::Id &l : languages) { - const QString dn = ToolChainManager::displayNameOfLanguageId(l); + const QString dn = ToolchainManager::displayNameOfLanguageId(l); auto autoNode = new StaticTreeItem(dn); auto manualNode = new StaticTreeItem(dn); @@ -203,11 +203,11 @@ public: addMenu->addAction(createAction(factory->displayName(), factory, languages.at(0))); } else { Utils::sort(languages, [](const Utils::Id &l1, const Utils::Id &l2) { - return ToolChainManager::displayNameOfLanguageId(l1) < ToolChainManager::displayNameOfLanguageId(l2); + return ToolchainManager::displayNameOfLanguageId(l1) < ToolchainManager::displayNameOfLanguageId(l2); }); auto subMenu = addMenu->addMenu(factory->displayName()); for (const Utils::Id &l : std::as_const(languages)) - subMenu->addAction(createAction(ToolChainManager::displayNameOfLanguageId(l), factory, l)); + subMenu->addAction(createAction(ToolchainManager::displayNameOfLanguageId(l), factory, l)); } } m_addButton->setMenu(addMenu); @@ -253,7 +253,7 @@ public: m_widgetStack = new QStackedWidget; m_container->setWidget(m_widgetStack); - for (Toolchain *tc : ToolChainManager::toolchains()) + for (Toolchain *tc : ToolchainManager::toolchains()) insertToolChain(tc); auto buttonLayout = new QVBoxLayout; @@ -275,14 +275,14 @@ public: horizontalLayout->addLayout(verticalLayout); horizontalLayout->addLayout(buttonLayout); - connect(ToolChainManager::instance(), &ToolChainManager::toolChainAdded, + connect(ToolchainManager::instance(), &ToolchainManager::toolChainAdded, this, &ToolChainOptionsWidget::addToolChain); - connect(ToolChainManager::instance(), &ToolChainManager::toolChainRemoved, + connect(ToolchainManager::instance(), &ToolchainManager::toolChainRemoved, this, &ToolChainOptionsWidget::removeToolChain); connect(m_toolChainView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ToolChainOptionsWidget::toolChainSelectionChanged); - connect(ToolChainManager::instance(), &ToolChainManager::toolChainsChanged, + connect(ToolchainManager::instance(), &ToolchainManager::toolChainsChanged, this, &ToolChainOptionsWidget::toolChainSelectionChanged); connect(m_delButton, &QAbstractButton::clicked, this, [this] { @@ -413,7 +413,7 @@ void ToolChainOptionsWidget::redetectToolchains() }); Toolchains toAdd; QSet toDelete; - ToolChainManager::resetBadToolchains(); + ToolchainManager::resetBadToolchains(); for (ToolchainFactory *f : ToolchainFactory::allToolchainFactories()) { const ToolchainDetector detector(knownTcs, DeviceManager::defaultDesktopDevice(), {}); // FIXME: Pass search paths for (Toolchain * const tc : f->autoDetect(detector)) { @@ -455,7 +455,7 @@ void ToolChainOptionsWidget::apply() // Remove unused tool chains: QList nodes = m_toRemoveList; for (const ToolChainTreeItem *n : std::as_const(nodes)) - ToolChainManager::deregisterToolChain(n->toolChain); + ToolchainManager::deregisterToolChain(n->toolChain); Q_ASSERT(m_toRemoveList.isEmpty()); @@ -479,7 +479,7 @@ void ToolChainOptionsWidget::apply() QStringList removedTcs; nodes = m_toAddList; for (const ToolChainTreeItem *n : std::as_const(nodes)) { - if (!ToolChainManager::registerToolChain(n->toolChain)) + if (!ToolchainManager::registerToolChain(n->toolChain)) removedTcs << n->toolChain->displayName(); } // @@ -505,7 +505,7 @@ void ToolChainOptionsWidget::apply() "They were not configured again.") .arg(removedTcs.join(QLatin1String(",
 ")))); } - ToolChainManager::setDetectionSettings(m_detectionSettings); + ToolchainManager::setDetectionSettings(m_detectionSettings); } void ToolChainOptionsWidget::createToolChain(ToolchainFactory *factory, const Utils::Id &language) diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 2daf3c31d45..5c88a53e103 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -236,7 +236,7 @@ QmakeBuildSystem::QmakeBuildSystem(QmakeBuildConfiguration *bc) connect(bc, &BuildConfiguration::environmentChanged, this, &QmakeBuildSystem::scheduleUpdateAllNowOrLater); - connect(ToolChainManager::instance(), &ToolChainManager::toolChainUpdated, + connect(ToolchainManager::instance(), &ToolchainManager::toolChainUpdated, this, [this](Toolchain *tc) { if (ToolchainKitAspect::cxxToolChain(kit()) == tc) scheduleUpdateAllNowOrLater(); diff --git a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp index 711b30bcf32..3e32bc822ea 100644 --- a/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeprojectimporter.cpp @@ -215,7 +215,7 @@ static const Toolchains preferredToolChains(QtVersion *qtVersion, const QString { const QString spec = ms.isEmpty() ? qtVersion->mkspec() : ms; - const Toolchains toolchains = ToolChainManager::toolchains(); + const Toolchains toolchains = ToolchainManager::toolchains(); const Abis qtAbis = qtVersion->qtAbis(); const auto matcher = [&](const Toolchain *tc) { return qtAbis.contains(tc->targetAbi()) && tc->suggestedMkspecList().contains(spec); diff --git a/src/plugins/qnx/qnxsettingspage.cpp b/src/plugins/qnx/qnxsettingspage.cpp index 86da2f4c176..4e96e7aefab 100644 --- a/src/plugins/qnx/qnxsettingspage.cpp +++ b/src/plugins/qnx/qnxsettingspage.cpp @@ -99,7 +99,7 @@ public: bool isActive() const { - const bool hasToolChain = ToolChainManager::toolChain(Utils::equal(&Toolchain::compilerCommand, + const bool hasToolChain = ToolchainManager::toolChain(Utils::equal(&Toolchain::compilerCommand, m_qccCompiler)); const bool hasDebugger = Utils::contains(DebuggerItemManager::debuggers(), [this](const DebuggerItem &di) { return findTargetByDebuggerPath(di.command()); @@ -169,7 +169,7 @@ void QnxConfiguration::deactivate() QTC_ASSERT(isActive(), return); const Toolchains toolChainsToRemove = - ToolChainManager::toolchains(Utils::equal(&Toolchain::compilerCommand, m_qccCompiler)); + ToolchainManager::toolchains(Utils::equal(&Toolchain::compilerCommand, m_qccCompiler)); QList debuggersToRemove; const QList debuggerItems = DebuggerItemManager::debuggers(); @@ -188,7 +188,7 @@ void QnxConfiguration::deactivate() } for (Toolchain *tc : toolChainsToRemove) - ToolChainManager::deregisterToolChain(tc); + ToolchainManager::deregisterToolChain(tc); for (const DebuggerItem &debuggerItem : std::as_const(debuggersToRemove)) DebuggerItemManager::deregisterDebugger(debuggerItem.id()); @@ -241,7 +241,7 @@ Toolchains QnxConfiguration::createToolChains(const QnxTarget &target) toolChain->sdpPath.setValue(m_envFile.parentDir()); toolChain->cpuDir.setValue(target.cpuDir()); toolChain->resetToolChain(m_qccCompiler); - ToolChainManager::registerToolChain(toolChain); + ToolchainManager::registerToolChain(toolChain); toolChains.append(toolChain); } diff --git a/src/plugins/qtsupport/baseqtversion.cpp b/src/plugins/qtsupport/baseqtversion.cpp index b74d9c25b32..abb7e36de9f 100644 --- a/src/plugins/qtsupport/baseqtversion.cpp +++ b/src/plugins/qtsupport/baseqtversion.cpp @@ -1866,7 +1866,7 @@ bool QtVersionPrivate::queryQMakeVariables(const FilePath &binary, const Environ // This is required to make non-static qmakes work on windows where every tool chain // tries to be incompatible with any other. const Abis abiList = Abi::abisOfBinary(binary); - const Toolchains tcList = ToolChainManager::toolchains([&abiList](const Toolchain *t) { + const Toolchains tcList = ToolchainManager::toolchains([&abiList](const Toolchain *t) { return abiList.contains(t->targetAbi()); }); for (Toolchain *tc : tcList) { diff --git a/src/plugins/qtsupport/qtkitaspect.cpp b/src/plugins/qtsupport/qtkitaspect.cpp index e2591d9260e..560149a0663 100644 --- a/src/plugins/qtsupport/qtkitaspect.cpp +++ b/src/plugins/qtsupport/qtkitaspect.cpp @@ -230,7 +230,7 @@ void QtKitAspectFactory::fix(Kit *k) return; const QString spec = version->mkspec(); - Toolchains possibleTcs = ToolChainManager::toolchains([version](const Toolchain *t) { + Toolchains possibleTcs = ToolchainManager::toolchains([version](const Toolchain *t) { if (!t->isValid() || t->language() != ProjectExplorer::Constants::CXX_LANGUAGE_ID) return false; return Utils::anyOf(version->qtAbis(), [t](const Abi &qtAbi) { diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp index 15da26a439a..249f8aca943 100644 --- a/src/plugins/qtsupport/qtoptionspage.cpp +++ b/src/plugins/qtsupport/qtoptionspage.cpp @@ -369,7 +369,7 @@ QtOptionsPageWidget::QtOptionsPageWidget() connect(QtVersionManager::instance(), &QtVersionManager::qtVersionsChanged, this, &QtOptionsPageWidget::updateQtVersions); - connect(ProjectExplorer::ToolChainManager::instance(), &ToolChainManager::toolChainsChanged, + connect(ProjectExplorer::ToolchainManager::instance(), &ToolchainManager::toolChainsChanged, this, &QtOptionsPageWidget::toolChainsUpdated); auto chooser = new VariableChooser(this); @@ -493,7 +493,7 @@ QtOptionsPageWidget::ValidityInfo QtOptionsPageWidget::validInformation(const Qt [&abi](const Abi &sabi) { return sabi.isCompatibleWith(abi); }); }; - if (!ToolChainManager::toolChain(abiCompatePred)) + if (!ToolchainManager::toolChain(abiCompatePred)) missingToolChains.append(abi); } @@ -539,7 +539,7 @@ QList QtOptionsPageWidget::toolChains(const QtVersion *version) QSet ids; const Abis abis = version->qtAbis(); for (const Abi &a : abis) { - const Toolchains tcList = ToolChainManager::findToolChains(a); + const Toolchains tcList = ToolchainManager::findToolChains(a); for (Toolchain *tc : tcList) { if (Utils::insert(ids, tc->id())) toolChains.append(tc); diff --git a/src/plugins/qtsupport/qtversionmanager.cpp b/src/plugins/qtsupport/qtversionmanager.cpp index 88c88ae15a0..8f3a7753c06 100644 --- a/src/plugins/qtsupport/qtversionmanager.cpp +++ b/src/plugins/qtsupport/qtversionmanager.cpp @@ -97,7 +97,7 @@ public: m_fileWatcherTimer.setInterval(2000); connect(&m_fileWatcherTimer, &QTimer::timeout, this, [this] { updateFromInstaller(); }); - connect(ToolChainManager::instance(), &ToolChainManager::toolChainsLoaded, + connect(ToolchainManager::instance(), &ToolchainManager::toolChainsLoaded, this, &QtVersionManagerImpl::triggerQtVersionRestore); } @@ -143,8 +143,8 @@ QtVersionManagerImpl &qtVersionManagerImpl() void QtVersionManagerImpl::triggerQtVersionRestore() { NANOTRACE_SCOPE("QtSupport", "QtVersionManagerImpl::triggerQtVersionRestore"); - disconnect(ToolChainManager::instance(), - &ToolChainManager::toolChainsLoaded, + disconnect(ToolchainManager::instance(), + &ToolchainManager::toolChainsLoaded, this, &QtVersionManagerImpl::triggerQtVersionRestore); diff --git a/src/plugins/webassembly/webassemblytoolchain.cpp b/src/plugins/webassembly/webassemblytoolchain.cpp index 42855145881..ae55fbeface 100644 --- a/src/plugins/webassembly/webassemblytoolchain.cpp +++ b/src/plugins/webassembly/webassemblytoolchain.cpp @@ -42,13 +42,13 @@ static const Abi &toolChainAbi() static void addRegisteredMinGWToEnvironment(Environment &env) { - if (!ToolChainManager::isLoaded()) { - // Avoid querying the ToolChainManager before it is loaded, which is the case during + if (!ToolchainManager::isLoaded()) { + // Avoid querying the ToolchainManager before it is loaded, which is the case during // toolchain restoration. The compiler version can be determined without MinGW in path. return; } - const Toolchain *toolChain = ToolChainManager::toolChain([](const Toolchain *t){ + const Toolchain *toolChain = ToolchainManager::toolChain([](const Toolchain *t){ return t->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID; }); if (toolChain) @@ -140,17 +140,17 @@ static Toolchains doAutoDetect(const ToolchainDetector &detector) void WebAssemblyToolChain::registerToolChains() { // Remove old toolchains - for (Toolchain *tc : ToolChainManager::findToolChains(toolChainAbi())) { + for (Toolchain *tc : ToolchainManager::findToolChains(toolChainAbi())) { if (tc->detection() != Toolchain::AutoDetection) continue; - ToolChainManager::deregisterToolChain(tc); + ToolchainManager::deregisterToolChain(tc); }; // Create new toolchains and register them ToolchainDetector detector({}, {}, {}); const Toolchains toolchains = doAutoDetect(detector); for (auto toolChain : toolchains) - ToolChainManager::registerToolChain(toolChain); + ToolchainManager::registerToolChain(toolChain); // Let kits pick up the new toolchains for (Kit *kit : KitManager::kits()) { @@ -165,7 +165,7 @@ void WebAssemblyToolChain::registerToolChains() bool WebAssemblyToolChain::areToolChainsRegistered() { - return !ToolChainManager::findToolChains(toolChainAbi()).isEmpty(); + return !ToolchainManager::findToolChains(toolChainAbi()).isEmpty(); } WebAssemblyToolchainFactory::WebAssemblyToolchainFactory() From c463f944e9b7120eab26c283476f134ef2df914a Mon Sep 17 00:00:00 2001 From: hjk Date: Mon, 27 Nov 2023 16:54:38 +0100 Subject: [PATCH 0387/1546] ProjectExplorer: Rename ToolchainManager signals and members Change-Id: I5195cb785f91dbaafdeeb8bb8c71939a6e3ff9e5 Reviewed-by: Christian Kandeler --- src/plugins/android/androidconfigurations.cpp | 6 ++-- .../cmakeprojectimporter.cpp | 2 +- .../compilationdatabaseproject.cpp | 4 +-- .../compilationdatabasetests.cpp | 2 +- src/plugins/docker/kitdetector.cpp | 4 +-- src/plugins/mcusupport/mcupackage.cpp | 16 +++++----- src/plugins/mcusupport/mcusupportsdk.cpp | 2 +- src/plugins/mcusupport/test/unittest.cpp | 4 +-- src/plugins/projectexplorer/gcctoolchain.cpp | 16 +++++----- src/plugins/projectexplorer/kitaspects.cpp | 18 +++++------ src/plugins/projectexplorer/project.cpp | 2 +- .../projectexplorer/projectexplorer.cpp | 2 +- .../projectexplorer/projectimporter.cpp | 8 ++--- .../projectexplorer/toolchainmanager.cpp | 32 +++++++++---------- .../projectexplorer/toolchainmanager.h | 28 ++++++++-------- .../projectexplorer/toolchainoptionspage.cpp | 10 +++--- .../qmakeprojectmanager/qmakeproject.cpp | 2 +- src/plugins/qnx/qnxsettingspage.cpp | 6 ++-- src/plugins/qtsupport/qtoptionspage.cpp | 6 ++-- src/plugins/qtsupport/qtversionmanager.cpp | 4 +-- .../webassembly/webassemblytoolchain.cpp | 10 +++--- 21 files changed, 92 insertions(+), 92 deletions(-) diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index afbdb7f322d..3bc788817e3 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -1153,7 +1153,7 @@ void AndroidConfigurations::registerNewToolChains() existingAndroidToolChains); for (Toolchain *tc : newToolchains) - ToolchainManager::registerToolChain(tc); + ToolchainManager::registerToolchain(tc); registerCustomToolChainsAndDebuggers(); } @@ -1164,7 +1164,7 @@ void AndroidConfigurations::removeOldToolChains() Id(Constants::ANDROID_TOOLCHAIN_TYPEID))); for (Toolchain *tc : tcs) { if (!tc->isValid()) - ToolchainManager::deregisterToolChain(tc); + ToolchainManager::deregisterToolchain(tc); } } @@ -1315,7 +1315,7 @@ void AndroidConfigurations::registerCustomToolChainsAndDebuggers() customNdks, true); for (Toolchain *tc : customToolchains) { - ToolchainManager::registerToolChain(tc); + ToolchainManager::registerToolchain(tc); const auto androidToolChain = static_cast(tc); QString abiStr; if (androidToolChain) diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index 162b60102d0..654f9d6143d 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -609,7 +609,7 @@ Toolchain *findExternalToolchain(const QString &presetArchitecture, const QStrin return tc->targetAbi().osFlavor(); })); - return ToolchainManager::toolChain( + return ToolchainManager::toolchain( [presetArchitecture, presetToolset, msvcFlavors](const Toolchain *tc) -> bool { if (tc->typeId() != ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) return false; diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp index bf92e71e779..8112f1aba5f 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseproject.cpp @@ -77,7 +77,7 @@ Utils::Id getCompilerId(QString compilerName) Toolchain *toolchainFromCompilerId(const Utils::Id &compilerId, const Utils::Id &language) { - return ToolchainManager::toolChain([&compilerId, &language](const Toolchain *tc) { + return ToolchainManager::toolchain([&compilerId, &language](const Toolchain *tc) { if (!tc->isValid() || tc->language() != language) return false; return tc->typeId() == compilerId; @@ -112,7 +112,7 @@ Toolchain *toolchainFromFlags(const Kit *kit, const QStringList &flags, const Ut // Try exact compiler match. const Utils::FilePath compiler = Utils::FilePath::fromUserInput(compilerPath(flags.front())); - Toolchain *toolchain = ToolchainManager::toolChain([&compiler, &language](const Toolchain *tc) { + Toolchain *toolchain = ToolchainManager::toolchain([&compiler, &language](const Toolchain *tc) { return tc->isValid() && tc->language() == language && tc->compilerCommand() == compiler; }); if (toolchain) diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp index 46a81a0b18f..06bd741d475 100644 --- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp +++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabasetests.cpp @@ -39,7 +39,7 @@ void CompilationDatabaseTests::initTestCase() if (allKits.empty()) QSKIP("This test requires at least one kit to be present."); - Toolchain *toolchain = ToolchainManager::toolChain([](const Toolchain *tc) { + Toolchain *toolchain = ToolchainManager::toolchain([](const Toolchain *tc) { return tc->isValid() && tc->language() == ProjectExplorer::Constants::CXX_LANGUAGE_ID; }); if (!toolchain) diff --git a/src/plugins/docker/kitdetector.cpp b/src/plugins/docker/kitdetector.cpp index fa6172541e8..37639c93bfb 100644 --- a/src/plugins/docker/kitdetector.cpp +++ b/src/plugins/docker/kitdetector.cpp @@ -110,7 +110,7 @@ void KitDetectorPrivate::undoAutoDetect() const for (Toolchain *toolChain : toolchains) { if (toolChain && toolChain->detectionSource() == m_sharedId) { emit q->logOutput(ProjectExplorer::Tr::tr("Removed \"%1\"").arg(toolChain->displayName())); - ToolchainManager::deregisterToolChain(toolChain); + ToolchainManager::deregisterToolchain(toolChain); } }; @@ -262,7 +262,7 @@ Toolchains KitDetectorPrivate::autoDetectToolChains() for (Toolchain *toolChain : newToolChains) { emit q->logOutput(ProjectExplorer::Tr::tr("Found \"%1\"").arg(toolChain->compilerCommand().toUserOutput())); toolChain->setDetectionSource(m_sharedId); - ToolchainManager::registerToolChain(toolChain); + ToolchainManager::registerToolchain(toolChain); alreadyKnown.append(toolChain); } allNewToolChains.append(newToolChains); diff --git a/src/plugins/mcusupport/mcupackage.cpp b/src/plugins/mcusupport/mcupackage.cpp index 350c89c8715..1f734b950fc 100644 --- a/src/plugins/mcusupport/mcupackage.cpp +++ b/src/plugins/mcusupport/mcupackage.cpp @@ -366,7 +366,7 @@ bool McuToolChainPackage::isDesktopToolchain() const Toolchain *McuToolChainPackage::msvcToolChain(Id language) { - Toolchain *toolChain = ToolchainManager::toolChain([language](const Toolchain *t) { + Toolchain *toolChain = ToolchainManager::toolchain([language](const Toolchain *t) { const Abi abi = t->targetAbi(); return abi.osFlavor() == Abi::WindowsMsvc2019Flavor && abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64 @@ -378,7 +378,7 @@ Toolchain *McuToolChainPackage::msvcToolChain(Id language) Toolchain *McuToolChainPackage::gccToolChain(Id language) { - Toolchain *toolChain = ToolchainManager::toolChain([language](const Toolchain *t) { + Toolchain *toolChain = ToolchainManager::toolchain([language](const Toolchain *t) { const Abi abi = t->targetAbi(); return abi.os() != Abi::WindowsOS && abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64 && t->language() == language; @@ -388,7 +388,7 @@ Toolchain *McuToolChainPackage::gccToolChain(Id language) static Toolchain *mingwToolChain(const FilePath &path, Id language) { - Toolchain *toolChain = ToolchainManager::toolChain([&path, language](const Toolchain *t) { + Toolchain *toolChain = ToolchainManager::toolchain([&path, language](const Toolchain *t) { // find a MinGW toolchain having the same path from registered toolchains const Abi abi = t->targetAbi(); return t->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID @@ -398,7 +398,7 @@ static Toolchain *mingwToolChain(const FilePath &path, Id language) if (!toolChain) { // if there's no MinGW toolchain having the same path, // a proper MinGW would be selected from the registered toolchains. - toolChain = ToolchainManager::toolChain([language](const Toolchain *t) { + toolChain = ToolchainManager::toolchain([language](const Toolchain *t) { const Abi abi = t->targetAbi(); return t->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID && abi.architecture() == Abi::X86Architecture && abi.wordWidth() == 64 @@ -410,7 +410,7 @@ static Toolchain *mingwToolChain(const FilePath &path, Id language) static Toolchain *armGccToolChain(const FilePath &path, Id language) { - Toolchain *toolChain = ToolchainManager::toolChain([&path, language](const Toolchain *t) { + Toolchain *toolChain = ToolchainManager::toolchain([&path, language](const Toolchain *t) { return t->compilerCommand() == path && t->language() == language; }); if (!toolChain) { @@ -426,7 +426,7 @@ static Toolchain *armGccToolChain(const FilePath &path, Id language) toolChain = detected.first(); toolChain->setDetection(Toolchain::ManualDetection); toolChain->setDisplayName("Arm GCC"); - ToolchainManager::registerToolChain(toolChain); + ToolchainManager::registerToolchain(toolChain); } } } @@ -436,7 +436,7 @@ static Toolchain *armGccToolChain(const FilePath &path, Id language) static Toolchain *iarToolChain(const FilePath &path, Id language) { - Toolchain *toolChain = ToolchainManager::toolChain([language](const Toolchain *t) { + Toolchain *toolChain = ToolchainManager::toolchain([language](const Toolchain *t) { return t->typeId() == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID && t->language() == language; }); @@ -457,7 +457,7 @@ static Toolchain *iarToolChain(const FilePath &path, Id language) toolChain = tc; toolChain->setDetection(Toolchain::ManualDetection); toolChain->setDisplayName("IAREW"); - ToolchainManager::registerToolChain(toolChain); + ToolchainManager::registerToolchain(toolChain); } } } diff --git a/src/plugins/mcusupport/mcusupportsdk.cpp b/src/plugins/mcusupport/mcusupportsdk.cpp index 589fa27e1d5..d2326949c02 100644 --- a/src/plugins/mcusupport/mcusupportsdk.cpp +++ b/src/plugins/mcusupport/mcusupportsdk.cpp @@ -328,7 +328,7 @@ McuToolChainPackagePtr createIarToolChainPackage(const SettingsHandler::Ptr &set if (qtcEnvironmentVariableIsSet(envVar)) defaultPath = FilePath::fromUserInput(qtcEnvironmentVariable(envVar)); else { - const ProjectExplorer::Toolchain *tc = ProjectExplorer::ToolchainManager::toolChain( + const ProjectExplorer::Toolchain *tc = ProjectExplorer::ToolchainManager::toolchain( [](const ProjectExplorer::Toolchain *t) { return t->typeId() == BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID; }); diff --git a/src/plugins/mcusupport/test/unittest.cpp b/src/plugins/mcusupport/test/unittest.cpp index 2175f3ab653..0e6c9da8a30 100644 --- a/src/plugins/mcusupport/test/unittest.cpp +++ b/src/plugins/mcusupport/test/unittest.cpp @@ -216,7 +216,7 @@ void verifyIarToolchain(const McuToolChainPackagePtr &iarToolchainPackage) Id iarId{BareMetal::Constants::IAREW_TOOLCHAIN_TYPEID}; Toolchain *iarToolchain{ProjectExplorer::ToolchainFactory::createToolChain(iarId)}; iarToolchain->setLanguage(cxxLanguageId); - ToolchainManager::registerToolChain(iarToolchain); + ToolchainManager::registerToolchain(iarToolchain); QVERIFY(iarToolchainPackage != nullptr); QCOMPARE(iarToolchainPackage->cmakeVariableName(), TOOLCHAIN_DIR_CMAKE_VARIABLE); @@ -240,7 +240,7 @@ void verifyArmGccToolchain(const McuToolChainPackagePtr &armGccPackage, const QS Toolchain *armToolchain{ProjectExplorer::ToolchainFactory::createToolChain(armGccId)}; armToolchain->setLanguage(cxxLanguageId); - ToolchainManager::registerToolChain(armToolchain); + ToolchainManager::registerToolchain(armToolchain); QVERIFY(armGccPackage != nullptr); QCOMPARE(armGccPackage->cmakeVariableName(), TOOLCHAIN_DIR_CMAKE_VARIABLE); diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index c8a4cbf7060..1a901a952db 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -866,7 +866,7 @@ QStringList GccToolChain::suggestedMkspecList() const } if (m_subType == Clang) { - if (const Toolchain * const parentTc = ToolchainManager::findToolChain(m_parentToolChainId)) + if (const Toolchain * const parentTc = ToolchainManager::findToolchain(m_parentToolChainId)) return parentTc->suggestedMkspecList(); const Abi abi = targetAbi(); if (abi.os() == Abi::DarwinOS) @@ -1759,17 +1759,17 @@ GccToolChainConfigWidget::GccToolChainConfigWidget(GccToolChain *tc) : ToolchainManager *tcManager = ToolchainManager::instance(); m_parentToolChainConnections.append( - connect(tcManager, &ToolchainManager::toolChainUpdated, this, [this](Toolchain *tc) { + connect(tcManager, &ToolchainManager::toolchainUpdated, this, [this](Toolchain *tc) { if (tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID) updateParentToolChainComboBox(); })); m_parentToolChainConnections.append( - connect(tcManager, &ToolchainManager::toolChainAdded, this, [this](Toolchain *tc) { + connect(tcManager, &ToolchainManager::toolhainAdded, this, [this](Toolchain *tc) { if (tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID) updateParentToolChainComboBox(); })); m_parentToolChainConnections.append( - connect(tcManager, &ToolchainManager::toolChainRemoved, this, [this](Toolchain *tc) { + connect(tcManager, &ToolchainManager::toolchainRemoved, this, [this](Toolchain *tc) { if (tc->id() == toolChain()->id()) { for (QMetaObject::Connection &connection : m_parentToolChainConnections) QObject::disconnect(connection); @@ -1957,9 +1957,9 @@ void GccToolChain::syncAutodetectedWithParentToolchains() QObject::disconnect(m_mingwToolchainAddedConnection); if (!ToolchainManager::isLoaded()) { - connect(ToolchainManager::instance(), &ToolchainManager::toolChainsLoaded, this, + connect(ToolchainManager::instance(), &ToolchainManager::toolchainsLoaded, this, [id = id()] { - if (Toolchain * const tc = ToolchainManager::findToolChain(id)) { + if (Toolchain * const tc = ToolchainManager::findToolchain(id)) { if (tc->typeId() == Constants::CLANG_TOOLCHAIN_TYPEID) static_cast(tc)->syncAutodetectedWithParentToolchains(); } @@ -1975,14 +1975,14 @@ void GccToolChain::syncAutodetectedWithParentToolchains() // Subscribe only autodetected toolchains. ToolchainManager *tcManager = ToolchainManager::instance(); m_mingwToolchainAddedConnection - = connect(tcManager, &ToolchainManager::toolChainAdded, this, [this](Toolchain *tc) { + = connect(tcManager, &ToolchainManager::toolhainAdded, this, [this](Toolchain *tc) { if (tc->typeId() == Constants::MINGW_TOOLCHAIN_TYPEID && !mingwToolChainFromId(m_parentToolChainId)) { m_parentToolChainId = tc->id(); } }); m_thisToolchainRemovedConnection - = connect(tcManager, &ToolchainManager::toolChainRemoved, this, [this](Toolchain *tc) { + = connect(tcManager, &ToolchainManager::toolchainRemoved, this, [this](Toolchain *tc) { if (tc == this) { QObject::disconnect(m_thisToolchainRemovedConnection); QObject::disconnect(m_mingwToolchainAddedConnection); diff --git a/src/plugins/projectexplorer/kitaspects.cpp b/src/plugins/projectexplorer/kitaspects.cpp index 068c663c2c0..c165fd72fb7 100644 --- a/src/plugins/projectexplorer/kitaspects.cpp +++ b/src/plugins/projectexplorer/kitaspects.cpp @@ -292,7 +292,7 @@ private: return; const QByteArray id = m_languageComboboxMap.value(language)->itemData(idx).toByteArray(); - Toolchain *tc = ToolchainManager::findToolChain(id); + Toolchain *tc = ToolchainManager::findToolchain(id); QTC_ASSERT(!tc || tc->language() == language, return); if (tc) ToolchainKitAspect::setToolChain(m_kit, tc); @@ -408,7 +408,7 @@ void ToolchainKitAspectFactory::fix(Kit *k) const QList languages = ToolchainManager::allLanguages(); for (const Id l : languages) { const QByteArray tcId = ToolchainKitAspect::toolChainId(k, l); - if (!tcId.isEmpty() && !ToolchainManager::findToolChain(tcId)) { + if (!tcId.isEmpty() && !ToolchainManager::findToolchain(tcId)) { qWarning("Tool chain set up in kit \"%s\" for \"%s\" not found.", qPrintable(k->displayName()), qPrintable(ToolchainManager::displayNameOfLanguageId(l))); @@ -443,7 +443,7 @@ void ToolchainKitAspectFactory::setup(Kit *k) } const QByteArray id = i.value().toByteArray(); - Toolchain *tc = ToolchainManager::findToolChain(id); + Toolchain *tc = ToolchainManager::findToolchain(id); if (tc) continue; @@ -557,17 +557,17 @@ QByteArray ToolchainKitAspect::toolChainId(const Kit *k, Id language) Toolchain *ToolchainKitAspect::toolChain(const Kit *k, Id language) { - return ToolchainManager::findToolChain(toolChainId(k, language)); + return ToolchainManager::findToolchain(toolChainId(k, language)); } Toolchain *ToolchainKitAspect::cToolChain(const Kit *k) { - return ToolchainManager::findToolChain(toolChainId(k, ProjectExplorer::Constants::C_LANGUAGE_ID)); + return ToolchainManager::findToolchain(toolChainId(k, ProjectExplorer::Constants::C_LANGUAGE_ID)); } Toolchain *ToolchainKitAspect::cxxToolChain(const Kit *k) { - return ToolchainManager::findToolChain(toolChainId(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID)); + return ToolchainManager::findToolchain(toolChainId(k, ProjectExplorer::Constants::CXX_LANGUAGE_ID)); } @@ -578,7 +578,7 @@ QList ToolchainKitAspect::toolChains(const Kit *k) const Store value = storeFromVariant(k->value(ToolchainKitAspect::id())); const QList tcList = transform(ToolchainManager::allLanguages(), [&value](Id l) { - return ToolchainManager::findToolChain(value.value(l.toKey()).toByteArray()); + return ToolchainManager::findToolchain(value.value(l.toKey()).toByteArray()); }); return filtered(tcList, [](Toolchain *tc) { return tc; }); } @@ -695,9 +695,9 @@ void ToolchainKitAspectFactory::onKitsLoaded() for (Kit *k : KitManager::kits()) fix(k); - connect(ToolchainManager::instance(), &ToolchainManager::toolChainRemoved, + connect(ToolchainManager::instance(), &ToolchainManager::toolchainRemoved, this, &ToolchainKitAspectFactory::toolChainRemoved); - connect(ToolchainManager::instance(), &ToolchainManager::toolChainUpdated, + connect(ToolchainManager::instance(), &ToolchainManager::toolchainUpdated, this, &ToolchainKitAspectFactory::toolChainUpdated); } diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index cfd3e55910a..a17b528a59a 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -1561,7 +1561,7 @@ void ProjectExplorerPlugin::testSourceToBinaryMapping() if (const auto msvcToolchain = dynamic_cast(toolchain)) { while (!msvcToolchain->environmentInitialized()) { QSignalSpy parsingFinishedSpy(ToolchainManager::instance(), - &ToolchainManager::toolChainUpdated); + &ToolchainManager::toolchainUpdated); QVERIFY(parsingFinishedSpy.wait(10000)); } } diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 1b8ac5f4971..73f16f6e95a 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -2118,7 +2118,7 @@ bool ProjectExplorerPlugin::delayedInitialize() { NANOTRACE_SCOPE("ProjectExplorer", "ProjectExplorerPlugin::restoreKits"); ExtraAbi::load(); // Load this before Toolchains! - ToolchainManager::restoreToolChains(); + ToolchainManager::restoreToolchains(); KitManager::restoreKits(); return true; } diff --git a/src/plugins/projectexplorer/projectimporter.cpp b/src/plugins/projectexplorer/projectimporter.cpp index 4bf718348fd..126a5ed84a1 100644 --- a/src/plugins/projectexplorer/projectimporter.cpp +++ b/src/plugins/projectexplorer/projectimporter.cpp @@ -313,7 +313,7 @@ bool ProjectImporter::findTemporaryHandler(Utils::Id id) const static Toolchain *toolChainFromVariant(const QVariant &v) { const QByteArray tcId = v.toByteArray(); - return ToolchainManager::findToolChain(tcId); + return ToolchainManager::findToolchain(tcId); } void ProjectImporter::cleanupTemporaryToolChains(Kit *k, const QVariantList &vl) @@ -321,7 +321,7 @@ void ProjectImporter::cleanupTemporaryToolChains(Kit *k, const QVariantList &vl) for (const QVariant &v : vl) { Toolchain *tc = toolChainFromVariant(v); QTC_ASSERT(tc, continue); - ToolchainManager::deregisterToolChain(tc); + ToolchainManager::deregisterToolchain(tc); ToolchainKitAspect::setToolChain(k, nullptr); } } @@ -333,7 +333,7 @@ void ProjectImporter::persistTemporaryToolChains(Kit *k, const QVariantList &vl) QTC_ASSERT(tmpTc, continue); Toolchain *actualTc = ToolchainKitAspect::toolChain(k, tmpTc->language()); if (tmpTc && actualTc != tmpTc) - ToolchainManager::deregisterToolChain(tmpTc); + ToolchainManager::deregisterToolchain(tmpTc); } } @@ -376,7 +376,7 @@ static ProjectImporter::ToolChainData createToolChains(const ToolChainDescriptio continue; for (Toolchain *tc : std::as_const(data.tcs)) - ToolchainManager::registerToolChain(tc); + ToolchainManager::registerToolchain(tc); data.areTemporary = true; break; diff --git a/src/plugins/projectexplorer/toolchainmanager.cpp b/src/plugins/projectexplorer/toolchainmanager.cpp index 6c8242c936e..96ccc843c61 100644 --- a/src/plugins/projectexplorer/toolchainmanager.cpp +++ b/src/plugins/projectexplorer/toolchainmanager.cpp @@ -77,10 +77,10 @@ ToolchainManager::ToolchainManager(QObject *parent) : d = new ToolchainManagerPrivate; connect(Core::ICore::instance(), &Core::ICore::saveSettingsRequested, - this, &ToolchainManager::saveToolChains); - connect(this, &ToolchainManager::toolChainAdded, this, &ToolchainManager::toolChainsChanged); - connect(this, &ToolchainManager::toolChainRemoved, this, &ToolchainManager::toolChainsChanged); - connect(this, &ToolchainManager::toolChainUpdated, this, &ToolchainManager::toolChainsChanged); + this, &ToolchainManager::saveToolchains); + connect(this, &ToolchainManager::toolhainAdded, this, &ToolchainManager::toolchainsChanged); + connect(this, &ToolchainManager::toolchainRemoved, this, &ToolchainManager::toolchainsChanged); + connect(this, &ToolchainManager::toolchainUpdated, this, &ToolchainManager::toolchainsChanged); QtcSettings * const s = Core::ICore::settings(); d->m_detectionSettings.detectX64AsX32 @@ -100,20 +100,20 @@ ToolchainManager *ToolchainManager::instance() return m_instance; } -void ToolchainManager::restoreToolChains() +void ToolchainManager::restoreToolchains() { NANOTRACE_SCOPE("ProjectExplorer", "ToolchainManager::restoreToolChains"); QTC_ASSERT(!d->m_accessor, return); d->m_accessor = std::make_unique(); for (Toolchain *tc : d->m_accessor->restoreToolChains(Core::ICore::dialogParent())) - registerToolChain(tc); + registerToolchain(tc); d->m_loaded = true; - emit m_instance->toolChainsLoaded(); + emit m_instance->toolchainsLoaded(); } -void ToolchainManager::saveToolChains() +void ToolchainManager::saveToolchains() { QTC_ASSERT(d->m_accessor, return); @@ -137,13 +137,13 @@ Toolchains ToolchainManager::toolchains(const Toolchain::Predicate &predicate) return Utils::filtered(d->m_toolChains, predicate); } -Toolchain *ToolchainManager::toolChain(const Toolchain::Predicate &predicate) +Toolchain *ToolchainManager::toolchain(const Toolchain::Predicate &predicate) { QTC_CHECK(d->m_loaded); return Utils::findOrDefault(d->m_toolChains, predicate); } -Toolchains ToolchainManager::findToolChains(const Abi &abi) +Toolchains ToolchainManager::findToolchains(const Abi &abi) { QTC_CHECK(d->m_loaded); Toolchains result; @@ -158,7 +158,7 @@ Toolchains ToolchainManager::findToolChains(const Abi &abi) return result; } -Toolchain *ToolchainManager::findToolChain(const QByteArray &id) +Toolchain *ToolchainManager::findToolchain(const QByteArray &id) { QTC_CHECK(d->m_loaded); if (id.isEmpty()) @@ -188,10 +188,10 @@ void ToolchainManager::notifyAboutUpdate(Toolchain *tc) { if (!tc || !d->m_toolChains.contains(tc)) return; - emit m_instance->toolChainUpdated(tc); + emit m_instance->toolchainUpdated(tc); } -bool ToolchainManager::registerToolChain(Toolchain *tc) +bool ToolchainManager::registerToolchain(Toolchain *tc) { QTC_ASSERT(tc, return false); QTC_ASSERT(isLanguageSupported(tc->language()), @@ -210,17 +210,17 @@ bool ToolchainManager::registerToolChain(Toolchain *tc) } d->m_toolChains.append(tc); - emit m_instance->toolChainAdded(tc); + emit m_instance->toolhainAdded(tc); return true; } -void ToolchainManager::deregisterToolChain(Toolchain *tc) +void ToolchainManager::deregisterToolchain(Toolchain *tc) { QTC_CHECK(d->m_loaded); if (!tc || !d->m_toolChains.contains(tc)) return; d->m_toolChains.removeOne(tc); - emit m_instance->toolChainRemoved(tc); + emit m_instance->toolchainRemoved(tc); delete tc; } diff --git a/src/plugins/projectexplorer/toolchainmanager.h b/src/plugins/projectexplorer/toolchainmanager.h index a85ff96de0f..563539847d9 100644 --- a/src/plugins/projectexplorer/toolchainmanager.h +++ b/src/plugins/projectexplorer/toolchainmanager.h @@ -42,14 +42,14 @@ public: static const Toolchains &toolchains(); static Toolchains toolchains(const Toolchain::Predicate &predicate); - static Toolchain *toolChain(const Toolchain::Predicate &predicate); - static QList findToolChains(const Abi &abi); - static Toolchain *findToolChain(const QByteArray &id); + static Toolchain *toolchain(const Toolchain::Predicate &predicate); + static QList findToolchains(const Abi &abi); + static Toolchain *findToolchain(const QByteArray &id); static bool isLoaded(); - static bool registerToolChain(Toolchain *tc); - static void deregisterToolChain(Toolchain *tc); + static bool registerToolchain(Toolchain *tc); + static void deregisterToolchain(Toolchain *tc); static QList allLanguages(); static bool registerLanguage(const Utils::Id &language, const QString &displayName); @@ -65,24 +65,24 @@ public: static bool isBadToolchain(const Utils::FilePath &toolchain); static void addBadToolchain(const Utils::FilePath &toolchain); - void saveToolChains(); + void saveToolchains(); signals: - void toolChainAdded(ProjectExplorer::Toolchain *); - // Tool chain is still valid when this call happens! - void toolChainRemoved(ProjectExplorer::Toolchain *); - // Tool chain was updated. - void toolChainUpdated(ProjectExplorer::Toolchain *); + void toolhainAdded(ProjectExplorer::Toolchain *); + // Toolchain is still valid when this call happens! + void toolchainRemoved(ProjectExplorer::Toolchain *); + // Toolchain was updated. + void toolchainUpdated(ProjectExplorer::Toolchain *); // Something changed. - void toolChainsChanged(); + void toolchainsChanged(); // - void toolChainsLoaded(); + void toolchainsLoaded(); private: explicit ToolchainManager(QObject *parent = nullptr); // Make sure the this is only called after all toolchain factories are registered! - static void restoreToolChains(); + static void restoreToolchains(); static void notifyAboutUpdate(Toolchain *); diff --git a/src/plugins/projectexplorer/toolchainoptionspage.cpp b/src/plugins/projectexplorer/toolchainoptionspage.cpp index e1a857bcf48..914356d7495 100644 --- a/src/plugins/projectexplorer/toolchainoptionspage.cpp +++ b/src/plugins/projectexplorer/toolchainoptionspage.cpp @@ -275,14 +275,14 @@ public: horizontalLayout->addLayout(verticalLayout); horizontalLayout->addLayout(buttonLayout); - connect(ToolchainManager::instance(), &ToolchainManager::toolChainAdded, + connect(ToolchainManager::instance(), &ToolchainManager::toolhainAdded, this, &ToolChainOptionsWidget::addToolChain); - connect(ToolchainManager::instance(), &ToolchainManager::toolChainRemoved, + connect(ToolchainManager::instance(), &ToolchainManager::toolchainRemoved, this, &ToolChainOptionsWidget::removeToolChain); connect(m_toolChainView->selectionModel(), &QItemSelectionModel::currentChanged, this, &ToolChainOptionsWidget::toolChainSelectionChanged); - connect(ToolchainManager::instance(), &ToolchainManager::toolChainsChanged, + connect(ToolchainManager::instance(), &ToolchainManager::toolchainsChanged, this, &ToolChainOptionsWidget::toolChainSelectionChanged); connect(m_delButton, &QAbstractButton::clicked, this, [this] { @@ -455,7 +455,7 @@ void ToolChainOptionsWidget::apply() // Remove unused tool chains: QList nodes = m_toRemoveList; for (const ToolChainTreeItem *n : std::as_const(nodes)) - ToolchainManager::deregisterToolChain(n->toolChain); + ToolchainManager::deregisterToolchain(n->toolChain); Q_ASSERT(m_toRemoveList.isEmpty()); @@ -479,7 +479,7 @@ void ToolChainOptionsWidget::apply() QStringList removedTcs; nodes = m_toAddList; for (const ToolChainTreeItem *n : std::as_const(nodes)) { - if (!ToolchainManager::registerToolChain(n->toolChain)) + if (!ToolchainManager::registerToolchain(n->toolChain)) removedTcs << n->toolChain->displayName(); } // diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 5c88a53e103..6ca7289fbd3 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -236,7 +236,7 @@ QmakeBuildSystem::QmakeBuildSystem(QmakeBuildConfiguration *bc) connect(bc, &BuildConfiguration::environmentChanged, this, &QmakeBuildSystem::scheduleUpdateAllNowOrLater); - connect(ToolchainManager::instance(), &ToolchainManager::toolChainUpdated, + connect(ToolchainManager::instance(), &ToolchainManager::toolchainUpdated, this, [this](Toolchain *tc) { if (ToolchainKitAspect::cxxToolChain(kit()) == tc) scheduleUpdateAllNowOrLater(); diff --git a/src/plugins/qnx/qnxsettingspage.cpp b/src/plugins/qnx/qnxsettingspage.cpp index 4e96e7aefab..2f12989c666 100644 --- a/src/plugins/qnx/qnxsettingspage.cpp +++ b/src/plugins/qnx/qnxsettingspage.cpp @@ -99,7 +99,7 @@ public: bool isActive() const { - const bool hasToolChain = ToolchainManager::toolChain(Utils::equal(&Toolchain::compilerCommand, + const bool hasToolChain = ToolchainManager::toolchain(Utils::equal(&Toolchain::compilerCommand, m_qccCompiler)); const bool hasDebugger = Utils::contains(DebuggerItemManager::debuggers(), [this](const DebuggerItem &di) { return findTargetByDebuggerPath(di.command()); @@ -188,7 +188,7 @@ void QnxConfiguration::deactivate() } for (Toolchain *tc : toolChainsToRemove) - ToolchainManager::deregisterToolChain(tc); + ToolchainManager::deregisterToolchain(tc); for (const DebuggerItem &debuggerItem : std::as_const(debuggersToRemove)) DebuggerItemManager::deregisterDebugger(debuggerItem.id()); @@ -241,7 +241,7 @@ Toolchains QnxConfiguration::createToolChains(const QnxTarget &target) toolChain->sdpPath.setValue(m_envFile.parentDir()); toolChain->cpuDir.setValue(target.cpuDir()); toolChain->resetToolChain(m_qccCompiler); - ToolchainManager::registerToolChain(toolChain); + ToolchainManager::registerToolchain(toolChain); toolChains.append(toolChain); } diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp index 249f8aca943..d129eaaf865 100644 --- a/src/plugins/qtsupport/qtoptionspage.cpp +++ b/src/plugins/qtsupport/qtoptionspage.cpp @@ -369,7 +369,7 @@ QtOptionsPageWidget::QtOptionsPageWidget() connect(QtVersionManager::instance(), &QtVersionManager::qtVersionsChanged, this, &QtOptionsPageWidget::updateQtVersions); - connect(ProjectExplorer::ToolchainManager::instance(), &ToolchainManager::toolChainsChanged, + connect(ProjectExplorer::ToolchainManager::instance(), &ToolchainManager::toolchainsChanged, this, &QtOptionsPageWidget::toolChainsUpdated); auto chooser = new VariableChooser(this); @@ -493,7 +493,7 @@ QtOptionsPageWidget::ValidityInfo QtOptionsPageWidget::validInformation(const Qt [&abi](const Abi &sabi) { return sabi.isCompatibleWith(abi); }); }; - if (!ToolchainManager::toolChain(abiCompatePred)) + if (!ToolchainManager::toolchain(abiCompatePred)) missingToolChains.append(abi); } @@ -539,7 +539,7 @@ QList QtOptionsPageWidget::toolChains(const QtVersion *version) QSet ids; const Abis abis = version->qtAbis(); for (const Abi &a : abis) { - const Toolchains tcList = ToolchainManager::findToolChains(a); + const Toolchains tcList = ToolchainManager::findToolchains(a); for (Toolchain *tc : tcList) { if (Utils::insert(ids, tc->id())) toolChains.append(tc); diff --git a/src/plugins/qtsupport/qtversionmanager.cpp b/src/plugins/qtsupport/qtversionmanager.cpp index 8f3a7753c06..664eb8234d0 100644 --- a/src/plugins/qtsupport/qtversionmanager.cpp +++ b/src/plugins/qtsupport/qtversionmanager.cpp @@ -97,7 +97,7 @@ public: m_fileWatcherTimer.setInterval(2000); connect(&m_fileWatcherTimer, &QTimer::timeout, this, [this] { updateFromInstaller(); }); - connect(ToolchainManager::instance(), &ToolchainManager::toolChainsLoaded, + connect(ToolchainManager::instance(), &ToolchainManager::toolchainsLoaded, this, &QtVersionManagerImpl::triggerQtVersionRestore); } @@ -144,7 +144,7 @@ void QtVersionManagerImpl::triggerQtVersionRestore() { NANOTRACE_SCOPE("QtSupport", "QtVersionManagerImpl::triggerQtVersionRestore"); disconnect(ToolchainManager::instance(), - &ToolchainManager::toolChainsLoaded, + &ToolchainManager::toolchainsLoaded, this, &QtVersionManagerImpl::triggerQtVersionRestore); diff --git a/src/plugins/webassembly/webassemblytoolchain.cpp b/src/plugins/webassembly/webassemblytoolchain.cpp index ae55fbeface..85812cd0546 100644 --- a/src/plugins/webassembly/webassemblytoolchain.cpp +++ b/src/plugins/webassembly/webassemblytoolchain.cpp @@ -48,7 +48,7 @@ static void addRegisteredMinGWToEnvironment(Environment &env) return; } - const Toolchain *toolChain = ToolchainManager::toolChain([](const Toolchain *t){ + const Toolchain *toolChain = ToolchainManager::toolchain([](const Toolchain *t){ return t->typeId() == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID; }); if (toolChain) @@ -140,17 +140,17 @@ static Toolchains doAutoDetect(const ToolchainDetector &detector) void WebAssemblyToolChain::registerToolChains() { // Remove old toolchains - for (Toolchain *tc : ToolchainManager::findToolChains(toolChainAbi())) { + for (Toolchain *tc : ToolchainManager::findToolchains(toolChainAbi())) { if (tc->detection() != Toolchain::AutoDetection) continue; - ToolchainManager::deregisterToolChain(tc); + ToolchainManager::deregisterToolchain(tc); }; // Create new toolchains and register them ToolchainDetector detector({}, {}, {}); const Toolchains toolchains = doAutoDetect(detector); for (auto toolChain : toolchains) - ToolchainManager::registerToolChain(toolChain); + ToolchainManager::registerToolchain(toolChain); // Let kits pick up the new toolchains for (Kit *kit : KitManager::kits()) { @@ -165,7 +165,7 @@ void WebAssemblyToolChain::registerToolChains() bool WebAssemblyToolChain::areToolChainsRegistered() { - return !ToolchainManager::findToolChains(toolChainAbi()).isEmpty(); + return !ToolchainManager::findToolchains(toolChainAbi()).isEmpty(); } WebAssemblyToolchainFactory::WebAssemblyToolchainFactory() From 40d5a90bbcc2b7c48f2f27759f9aaac584bed5d5 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 23 Nov 2023 12:27:08 +0100 Subject: [PATCH 0388/1546] ProjectExplorer: Compress folder nodes bottom-up That's the conceptually correct way to do this operation. Fixes lots of randomness and results in simpler code. Fixes: QTCREATORBUG-29923 Change-Id: I1f391c323ecdeeb5b8def9b4c56ad5206661edcb Reviewed-by: Reviewed-by: Christian Stenger Reviewed-by: Qt CI Bot --- src/plugins/projectexplorer/projectnodes.cpp | 41 +++++++++++--------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index 3a09b97b4c1..b0d1484abae 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -677,28 +677,31 @@ void FolderNode::addNestedNodes(std::vector > &&files, // files. void FolderNode::compress() { - if (auto subFolder = m_nodes.size() == 1 ? m_nodes.at(0)->asFolderNode() : nullptr) { - const bool sameType = (isFolderNodeType() && subFolder->isFolderNodeType()) - || (isProjectNodeType() && subFolder->isProjectNodeType()) - || (isVirtualFolderType() && subFolder->isVirtualFolderType()); - if (!sameType) - return; + // Child nodes need to be compressed first. + forEachFolderNode([&](FolderNode *fn) { fn->compress(); }); - // Only one subfolder: Compress! - setDisplayName(QDir::toNativeSeparators(displayName() + "/" + subFolder->displayName())); - for (Node *n : subFolder->nodes()) { - std::unique_ptr toMove = subFolder->takeNode(n); - toMove->setParentFolderNode(nullptr); - addNode(std::move(toMove)); - } - setAbsoluteFilePathAndLine(subFolder->filePath(), -1); + // There must be exactly one child node, which has to be of the same type as this node. + if (m_nodes.size() != 1) + return; + const auto subFolder = m_nodes.front()->asFolderNode(); + if (!subFolder) + return; + const bool sameType = (isFolderNodeType() && subFolder->isFolderNodeType()) + || (isProjectNodeType() && subFolder->isProjectNodeType()) + || (isVirtualFolderType() && subFolder->isVirtualFolderType()); + if (!sameType) + return; - takeNode(subFolder); - - compress(); - } else { - forEachFolderNode([&](FolderNode *fn) { fn->compress(); }); + // Now do the compression by moving the child node's children into this node + // and removing the child node. + for (Node *n : subFolder->nodes()) { + std::unique_ptr toMove = subFolder->takeNode(n); + toMove->setParentFolderNode(nullptr); + addNode(std::move(toMove)); } + setDisplayName(QDir::toNativeSeparators(displayName() + "/" + subFolder->displayName())); + setAbsoluteFilePathAndLine(subFolder->filePath(), -1); + takeNode(subFolder); } bool FolderNode::replaceSubtree(Node *oldNode, std::unique_ptr &&newNode) From 12428bf1d67bd282c5276383c91d968451b44036 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 28 Nov 2023 10:40:52 +0100 Subject: [PATCH 0389/1546] Aggregation: Fix crash when components are in parent-child relationship and the child is deleted first. Change-Id: Idea3b4a3410bda99a8727551e2cbeab3a7b95d85 Reviewed-by: Christian Stenger Reviewed-by: --- src/libs/aggregation/aggregate.cpp | 3 +++ tests/auto/aggregation/tst_aggregate.cpp | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/libs/aggregation/aggregate.cpp b/src/libs/aggregation/aggregate.cpp index 7be6437ae2f..11d13907f33 100644 --- a/src/libs/aggregation/aggregate.cpp +++ b/src/libs/aggregation/aggregate.cpp @@ -193,6 +193,9 @@ void Aggregate::deleteSelf(QObject *obj) QWriteLocker locker(&lock()); aggregateMap().remove(obj); m_components.removeAll(obj); + // Avoid issues if obj was child of another component of the aggregate. + // The parent is deleted in ~Aggregate and might still have a reference on obj + obj->setParent({}); } delete this; } diff --git a/tests/auto/aggregation/tst_aggregate.cpp b/tests/auto/aggregation/tst_aggregate.cpp index eef9a32400c..fe865be59e7 100644 --- a/tests/auto/aggregation/tst_aggregate.cpp +++ b/tests/auto/aggregation/tst_aggregate.cpp @@ -78,6 +78,24 @@ void tst_Aggregate::deleteAggregation() component1 = new Interface1; delete component1; QVERIFY(component1 == 0); + + // do not crash if components are in a child/parent relationship + // parent deleted first + aggregation = new Aggregation::Aggregate; + component1 = new Interface1; + component2 = new Interface2; + component2->setParent(component1); + aggregation->add(component1); + aggregation->add(component2); + delete component1; + // child deleted first + aggregation = new Aggregation::Aggregate; + component1 = new Interface1; + component2 = new Interface2; + component2->setParent(component1); + aggregation->add(component1); + aggregation->add(component2); + delete component2; } void tst_Aggregate::queryAggregation() From 09e94ae4ac040ad313b7b86e62489dee7cd3804a Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 1 Nov 2023 15:05:03 +0100 Subject: [PATCH 0390/1546] Python: use kits page in python wizards Change-Id: I1f7aaf145443481546abb868c8c167186600b848 Reviewed-by: Christian Stenger --- .../qtforpythonapplication/empty/wizard.json | 12 +- .../mainwindow/wizard.json | 12 +- .../qtquickapplication/wizard.json | 12 +- .../qtforpythonapplication/widget/wizard.json | 12 +- src/plugins/debugger/debuggerruncontrol.cpp | 4 +- src/plugins/python/CMakeLists.txt | 2 +- src/plugins/python/pyside.cpp | 14 +- src/plugins/python/pyside.h | 10 + .../python/pysidebuildconfiguration.cpp | 108 ----- src/plugins/python/pysidebuildconfiguration.h | 37 -- src/plugins/python/python.qbs | 4 +- .../python/pythonbuildconfiguration.cpp | 415 ++++++++++++++++++ src/plugins/python/pythonbuildconfiguration.h | 86 ++++ src/plugins/python/pythonbuildsystem.cpp | 21 +- src/plugins/python/pythonbuildsystem.h | 5 +- src/plugins/python/pythonconstants.h | 3 + src/plugins/python/pythoneditor.cpp | 289 ++++++------ src/plugins/python/pythoneditor.h | 14 + src/plugins/python/pythonkitaspect.cpp | 7 + src/plugins/python/pythonlanguageclient.cpp | 24 +- src/plugins/python/pythonlanguageclient.h | 2 + src/plugins/python/pythonplugin.cpp | 9 +- src/plugins/python/pythonplugin.h | 2 + src/plugins/python/pythonproject.cpp | 6 +- src/plugins/python/pythonproject.h | 2 - src/plugins/python/pythonrunconfiguration.cpp | 249 +---------- src/plugins/python/pythonrunconfiguration.h | 3 - src/plugins/python/pythonsettings.cpp | 37 +- src/plugins/python/pythonsettings.h | 8 +- src/plugins/python/pythonutils.cpp | 22 +- src/plugins/python/pythonutils.h | 2 + src/plugins/python/pythonwizardpage.cpp | 108 +---- src/plugins/python/pythonwizardpage.h | 9 - 33 files changed, 870 insertions(+), 680 deletions(-) delete mode 100644 src/plugins/python/pysidebuildconfiguration.cpp delete mode 100644 src/plugins/python/pysidebuildconfiguration.h create mode 100644 src/plugins/python/pythonbuildconfiguration.cpp create mode 100644 src/plugins/python/pythonbuildconfiguration.h diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json index 8ca7c0cdcc5..ac4141dfcc5 100644 --- a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/empty/wizard.json @@ -13,7 +13,8 @@ "options": [ { "key": "SrcFileName", "value": "main.py" }, - { "key": "PyProjectFile", "value": "%{JS: Util.fileName('%{ProjectName}', 'pyproject')}" } + { "key": "PyProjectFile", "value": "%{JS: Util.fileName('%{ProjectName}', 'pyproject')}" }, + { "key": "ProjectFilePath", "value": "%{ProjectDirectory}/%{PyProjectFile}" } ], "pages": @@ -49,6 +50,15 @@ ] } }, + { + "trDisplayName": "Kit Selection", + "trShortTitle": "Kits", + "typeId": "Kits", + "data": { + "projectFilePath": "%{ProjectFilePath}", + "requiredFeatures": [ "Python.Interpreter" ] + } + }, { "trDisplayName": "Project Management", "trShortTitle": "Summary", diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json index 7ed2498faf8..b20193fac38 100644 --- a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/mainwindow/wizard.json @@ -13,7 +13,8 @@ "options": [ { "key": "MainPyFileName", "value": "%{ProjectDirectory}/%{SrcFileName}" }, - { "key": "PyProjectFile", "value": "%{ProjectDirectory}/%{ProjectFileName}" } + { "key": "PyProjectFile", "value": "%{ProjectFileName}" }, + { "key": "ProjectFilePath", "value": "%{ProjectDirectory}/%{PyProjectFile}" } ], "pages": @@ -93,6 +94,15 @@ ] } }, + { + "trDisplayName": "Kit Selection", + "trShortTitle": "Kits", + "typeId": "Kits", + "data": { + "projectFilePath": "%{ProjectFilePath}", + "requiredFeatures": [ "Python.Interpreter" ] + } + }, { "trDisplayName": "Project Management", "trShortTitle": "Summary", diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/qtquickapplication/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/qtquickapplication/wizard.json index b1b75fc0885..4650fe1afb5 100644 --- a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/qtquickapplication/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/qtquickapplication/wizard.json @@ -17,7 +17,8 @@ { "key": "PyProjectFile", "value": "%{JS: Util.fileName('%{ProjectName}', 'pyproject')}" }, { "key": "QtQuickVersion", "value": "%{JS: value('QtVersion').QtQuickVersion}" }, { "key": "QtQuickWindowVersion", "value": "%{JS: value('QtVersion').QtQuickWindowVersion}" }, - { "key": "PySideVersion", "value": "%{JS: value('QtVersion').PySideVersion}" } + { "key": "PySideVersion", "value": "%{JS: value('QtVersion').PySideVersion}" }, + { "key": "ProjectFilePath", "value": "%{ProjectDirectory}/%{PyProjectFile}" } ], "pages": @@ -84,6 +85,15 @@ ] } }, + { + "trDisplayName": "Kit Selection", + "trShortTitle": "Kits", + "typeId": "Kits", + "data": { + "projectFilePath": "%{ProjectFilePath}", + "requiredFeatures": [ "Python.Interpreter" ] + } + }, { "trDisplayName": "Project Management", "trShortTitle": "Summary", diff --git a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/widget/wizard.json b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/widget/wizard.json index a2005335668..15cf5db0f81 100644 --- a/share/qtcreator/templates/wizards/projects/qtforpythonapplication/widget/wizard.json +++ b/share/qtcreator/templates/wizards/projects/qtforpythonapplication/widget/wizard.json @@ -13,7 +13,8 @@ "options": [ { "key": "SrcFileName", "value": "%{MainFileName}" }, - { "key": "PyProjectFile", "value": "%{ProjectFileName}" } + { "key": "PyProjectFile", "value": "%{ProjectFileName}" }, + { "key": "ProjectFilePath", "value": "%{ProjectDirectory}/%{PyProjectFile}" } ], "pages": @@ -93,6 +94,15 @@ ] } }, + { + "trDisplayName": "Kit Selection", + "trShortTitle": "Kits", + "typeId": "Kits", + "data": { + "projectFilePath": "%{ProjectFilePath}", + "requiredFeatures": [ "Python.Interpreter" ] + } + }, { "trDisplayName": "Project Management", "trShortTitle": "Summary", diff --git a/src/plugins/debugger/debuggerruncontrol.cpp b/src/plugins/debugger/debuggerruncontrol.cpp index ed4968cdd93..5c67d0d138a 100644 --- a/src/plugins/debugger/debuggerruncontrol.cpp +++ b/src/plugins/debugger/debuggerruncontrol.cpp @@ -908,10 +908,10 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, AllowTerminal allowTerm m_runParameters.nativeMixedEnabled = bool(nativeMixedOverride); - if (auto interpreterAspect = runControl->aspect()) { + if (auto interpreterAspect = runControl->aspect()) { if (auto mainScriptAspect = runControl->aspect()) { const FilePath mainScript = mainScriptAspect->filePath; - const FilePath interpreter = interpreterAspect->interpreter.command; + const FilePath interpreter = interpreterAspect->filePath; if (!interpreter.isEmpty() && mainScript.endsWith(".py")) { m_runParameters.mainScript = mainScript; m_runParameters.interpreter = interpreter; diff --git a/src/plugins/python/CMakeLists.txt b/src/plugins/python/CMakeLists.txt index 25861c9ceed..0673c669df5 100644 --- a/src/plugins/python/CMakeLists.txt +++ b/src/plugins/python/CMakeLists.txt @@ -4,7 +4,7 @@ add_qtc_plugin(Python SOURCES pipsupport.cpp pipsupport.h pyside.cpp pyside.h - pysidebuildconfiguration.cpp pysidebuildconfiguration.h + pythonbuildconfiguration.cpp pythonbuildconfiguration.h pysideuicextracompiler.cpp pysideuicextracompiler.h python.qrc pythonbuildsystem.cpp pythonbuildsystem.h diff --git a/src/plugins/python/pyside.cpp b/src/plugins/python/pyside.cpp index b2483c7cac6..c117203b33e 100644 --- a/src/plugins/python/pyside.cpp +++ b/src/plugins/python/pyside.cpp @@ -46,6 +46,10 @@ void PySideInstaller::checkPySideInstallation(const FilePath &python, TextEditor::TextDocument *document) { document->infoBar()->removeInfo(installPySideInfoBarId); + if (QPointer> watcher = instance()->m_futureWatchers.value(document)) + watcher->cancel(); + if (!python.exists()) + return; const QString pySide = importedPySide(document->plainText()); if (pySide == "PySide2" || pySide == "PySide6") instance()->runPySideChecker(python, pySide, document); @@ -186,10 +190,8 @@ void PySideInstaller::runPySideChecker(const FilePath &python, // cancel and delete watcher after a 10 second timeout QTimer::singleShot(10000, this, [watcher]() { - if (watcher) { + if (watcher) watcher->cancel(); - watcher->deleteLater(); - } }); connect(watcher, &CheckPySideWatcher::resultReadyAt, @@ -197,9 +199,13 @@ void PySideInstaller::runPySideChecker(const FilePath &python, [=, document = QPointer(document)]() { if (watcher->result()) handlePySideMissing(python, pySide, document); - watcher->deleteLater(); }); + connect(watcher, &CheckPySideWatcher::finished, watcher, &CheckPySideWatcher::deleteLater); + connect(watcher, &CheckPySideWatcher::finished, this, [this, document]{ + m_futureWatchers.remove(document); + }); watcher->setFuture(Utils::asyncRun(&missingPySideInstallation, python, pySide)); + m_futureWatchers[document] = watcher; } } // Python::Internal diff --git a/src/plugins/python/pyside.h b/src/plugins/python/pyside.h index 3b4f99974a5..a0f2e23bedc 100644 --- a/src/plugins/python/pyside.h +++ b/src/plugins/python/pyside.h @@ -6,6 +6,8 @@ #include #include +#include +#include #include namespace TextEditor { class TextDocument; } @@ -13,6 +15,13 @@ namespace ProjectExplorer { class RunConfiguration; } namespace Python::Internal { +class PySideTools +{ +public: + Utils::FilePath pySideProjectPath; + Utils::FilePath pySideUicPath; +}; + class PySideInstaller : public QObject { Q_OBJECT @@ -41,6 +50,7 @@ private: static QString importedPySide(const QString &text); QHash> m_infoBarEntries; + QHash>> m_futureWatchers; }; } // Python::Internal diff --git a/src/plugins/python/pysidebuildconfiguration.cpp b/src/plugins/python/pysidebuildconfiguration.cpp deleted file mode 100644 index 9aa87316562..00000000000 --- a/src/plugins/python/pysidebuildconfiguration.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (C) 2022 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#include "pysidebuildconfiguration.h" - -#include "pythonconstants.h" -#include "pythonproject.h" -#include "pythontr.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -using namespace ProjectExplorer; -using namespace Utils; - -namespace Python::Internal { - -const char pySideBuildStep[] = "Python.PysideBuildStep"; - -PySideBuildStepFactory::PySideBuildStepFactory() -{ - registerStep(pySideBuildStep); - setSupportedProjectType(PythonProjectId); - setDisplayName(Tr::tr("Run PySide6 project tool")); - setFlags(BuildStep::UniqueStep); -} - -PySideBuildStep::PySideBuildStep(BuildStepList *bsl, Id id) - : AbstractProcessStep(bsl, id) -{ - m_pysideProject.setSettingsKey("Python.PySideProjectTool"); - m_pysideProject.setLabelText(Tr::tr("PySide project tool:")); - m_pysideProject.setToolTip(Tr::tr("Enter location of PySide project tool.")); - m_pysideProject.setExpectedKind(PathChooser::Command); - m_pysideProject.setHistoryCompleter("Python.PySideProjectTool.History"); - - const FilePath pySideProjectPath = FilePath("pyside6-project").searchInPath(); - if (pySideProjectPath.isExecutableFile()) - m_pysideProject.setValue(pySideProjectPath); - - setCommandLineProvider([this] { return CommandLine(m_pysideProject(), {"build"}); }); - setWorkingDirectoryProvider([this] { - return m_pysideProject().withNewMappedPath(project()->projectDirectory()); // FIXME: new path needed? - }); - setEnvironmentModifier([this](Environment &env) { - env.prependOrSetPath(m_pysideProject().parentDir()); - }); -} - -void PySideBuildStep::updatePySideProjectPath(const FilePath &pySideProjectPath) -{ - m_pysideProject.setValue(pySideProjectPath); -} - -Tasking::GroupItem PySideBuildStep::runRecipe() -{ - using namespace Tasking; - - const auto onSetup = [this] { - if (!processParameters()->effectiveCommand().isExecutableFile()) - return SetupResult::StopWithSuccess; - return SetupResult::Continue; - }; - - return Group { onGroupSetup(onSetup), defaultProcessTask() }; -} - -// PySideBuildConfiguration - -class PySideBuildConfiguration : public BuildConfiguration -{ -public: - PySideBuildConfiguration(Target *target, Id id) - : BuildConfiguration(target, id) - { - setConfigWidgetDisplayName(Tr::tr("General")); - - setInitializer([this](const BuildInfo &) { - buildSteps()->appendStep(pySideBuildStep); - updateCacheAndEmitEnvironmentChanged(); - }); - - updateCacheAndEmitEnvironmentChanged(); - } -}; - -PySideBuildConfigurationFactory::PySideBuildConfigurationFactory() -{ - registerBuildConfiguration("Python.PySideBuildConfiguration"); - setSupportedProjectType(PythonProjectId); - setSupportedProjectMimeTypeName(Constants::C_PY_MIMETYPE); - setBuildGenerator([](const Kit *, const FilePath &projectPath, bool) { - BuildInfo info; - info.displayName = "build"; - info.typeName = "build"; - info.buildDirectory = projectPath.parentDir(); - return QList{info}; - }); -} - -} // Python::Internal diff --git a/src/plugins/python/pysidebuildconfiguration.h b/src/plugins/python/pysidebuildconfiguration.h deleted file mode 100644 index 58ae930ea87..00000000000 --- a/src/plugins/python/pysidebuildconfiguration.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2022 The Qt Company Ltd. -// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 - -#pragma once - -#include -#include -#include - -namespace Python::Internal { - -class PySideBuildStep : public ProjectExplorer::AbstractProcessStep -{ - Q_OBJECT -public: - PySideBuildStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id); - void updatePySideProjectPath(const Utils::FilePath &pySideProjectPath); - -private: - Tasking::GroupItem runRecipe() final; - - Utils::FilePathAspect m_pysideProject{this}; -}; - -class PySideBuildStepFactory : public ProjectExplorer::BuildStepFactory -{ -public: - PySideBuildStepFactory(); -}; - -class PySideBuildConfigurationFactory : public ProjectExplorer::BuildConfigurationFactory -{ -public: - PySideBuildConfigurationFactory(); -}; - -} // Python::Internal diff --git a/src/plugins/python/python.qbs b/src/plugins/python/python.qbs index eee19bb0c7f..a41f8390242 100644 --- a/src/plugins/python/python.qbs +++ b/src/plugins/python/python.qbs @@ -22,8 +22,8 @@ QtcPlugin { "pipsupport.h", "pyside.cpp", "pyside.h", - "pysidebuildconfiguration.cpp", - "pysidebuildconfiguration.h", + "pythonbuildconfiguration.cpp", + "pythonbuildconfiguration.h", "pysideuicextracompiler.cpp", "pysideuicextracompiler.h", "python.qrc", diff --git a/src/plugins/python/pythonbuildconfiguration.cpp b/src/plugins/python/pythonbuildconfiguration.cpp new file mode 100644 index 00000000000..f320dce3cc2 --- /dev/null +++ b/src/plugins/python/pythonbuildconfiguration.cpp @@ -0,0 +1,415 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "pythonbuildconfiguration.h" + +#include "pipsupport.h" +#include "pyside.h" +#include "pysideuicextracompiler.h" +#include "pythonconstants.h" +#include "pythoneditor.h" +#include "pythonkitaspect.h" +#include "pythonlanguageclient.h" +#include "pythonproject.h" +#include "pythonsettings.h" +#include "pythontr.h" +#include "pythonutils.h" + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +using namespace ProjectExplorer; +using namespace Utils; + +namespace Python::Internal { + +PySideBuildStepFactory::PySideBuildStepFactory() +{ + registerStep(PySideBuildStep::id()); + setSupportedProjectType(PythonProjectId); + setDisplayName(Tr::tr("Run PySide6 project tool")); + setFlags(BuildStep::UniqueStep); +} + +PySideBuildStep::PySideBuildStep(BuildStepList *bsl, Id id) + : AbstractProcessStep(bsl, id) +{ + m_pysideProject.setSettingsKey("Python.PySideProjectTool"); + m_pysideProject.setLabelText(Tr::tr("PySide project tool:")); + m_pysideProject.setToolTip(Tr::tr("Enter location of PySide project tool.")); + m_pysideProject.setExpectedKind(PathChooser::Command); + m_pysideProject.setHistoryCompleter("Python.PySideProjectTool.History"); + m_pysideProject.setReadOnly(true); + + m_pysideUic.setSettingsKey("Python.PySideUic"); + m_pysideUic.setLabelText(Tr::tr("PySide uic tool:")); + m_pysideUic.setToolTip(Tr::tr("Enter location of PySide uic tool.")); + m_pysideUic.setExpectedKind(PathChooser::Command); + m_pysideUic.setHistoryCompleter("Python.PySideUic.History"); + m_pysideUic.setReadOnly(true); + + setCommandLineProvider([this] { return CommandLine(m_pysideProject(), {"build"}); }); + setWorkingDirectoryProvider([this] { + return m_pysideProject().withNewMappedPath(project()->projectDirectory()); // FIXME: new path needed? + }); + setEnvironmentModifier([this](Environment &env) { + env.prependOrSetPath(m_pysideProject().parentDir()); + }); + + connect(target(), &Target::buildSystemUpdated, this, &PySideBuildStep::updateExtraCompilers); + connect(&m_pysideUic, &BaseAspect::changed, this, &PySideBuildStep::updateExtraCompilers); +} + +PySideBuildStep::~PySideBuildStep() +{ + qDeleteAll(m_extraCompilers); +} + +void PySideBuildStep::checkForPySide(const FilePath &python) +{ + PySideTools tools; + if (python.isEmpty() || !python.isExecutableFile()) { + m_pysideProject.setValue(FilePath()); + m_pysideUic.setValue(FilePath()); + return; + } + const FilePath dir = python.parentDir(); + tools.pySideProjectPath = dir.pathAppended("pyside6-project").withExecutableSuffix(); + tools.pySideUicPath = dir.pathAppended("pyside6-uic").withExecutableSuffix(); + + if (tools.pySideProjectPath.isExecutableFile() && tools.pySideUicPath.isExecutableFile()) { + m_pysideProject.setValue(tools.pySideProjectPath.toUserOutput()); + m_pysideUic.setValue(tools.pySideUicPath.toUserOutput()); + } else { + checkForPySide(python, "PySide6-Essentials"); + } +} + +void PySideBuildStep::checkForPySide(const FilePath &python, const QString &pySidePackageName) +{ + const PipPackage package(pySidePackageName); + QObject::disconnect(m_watcherConnection); + m_watcher.reset(new QFutureWatcher()); + m_watcherConnection = QObject::connect(m_watcher.get(), &QFutureWatcherBase::finished, this, [=] { + handlePySidePackageInfo(m_watcher->result(), python, pySidePackageName); + }); + const auto future = Pip::instance(python)->info(package); + m_watcher->setFuture(future); + ExtensionSystem::PluginManager::futureSynchronizer()->addFuture(future); +} + +void PySideBuildStep::handlePySidePackageInfo(const PipPackageInfo &pySideInfo, + const FilePath &python, + const QString &requestedPackageName) +{ + const auto findPythonTools = [](const FilePaths &files, + const FilePath &location, + const FilePath &python) -> PySideTools { + PySideTools result; + const QString pySide6ProjectName + = OsSpecificAspects::withExecutableSuffix(python.osType(), "pyside6-project"); + const QString pySide6UicName + = OsSpecificAspects::withExecutableSuffix(python.osType(), "pyside6-uic"); + for (const FilePath &file : files) { + if (file.fileName() == pySide6ProjectName) { + result.pySideProjectPath = python.withNewMappedPath(location.resolvePath(file)); + result.pySideProjectPath = result.pySideProjectPath.cleanPath(); + if (!result.pySideUicPath.isEmpty()) + return result; + } else if (file.fileName() == pySide6UicName) { + result.pySideUicPath = python.withNewMappedPath(location.resolvePath(file)); + result.pySideUicPath = result.pySideUicPath.cleanPath(); + if (!result.pySideProjectPath.isEmpty()) + return result; + } + } + return {}; + }; + + PySideTools tools = findPythonTools(pySideInfo.files, pySideInfo.location, python); + if (!tools.pySideProjectPath.isExecutableFile() && requestedPackageName != "PySide6") { + checkForPySide(python, "PySide6"); + return; + } + + m_pysideProject.setValue(tools.pySideProjectPath.toUserOutput()); + m_pysideUic.setValue(tools.pySideUicPath.toUserOutput()); +} + +Tasking::GroupItem PySideBuildStep::runRecipe() +{ + using namespace Tasking; + + const auto onSetup = [this] { + if (!processParameters()->effectiveCommand().isExecutableFile()) + return SetupResult::StopWithSuccess; + return SetupResult::Continue; + }; + + return Group { onGroupSetup(onSetup), defaultProcessTask() }; +} + +void PySideBuildStep::updateExtraCompilers() +{ + QList oldCompilers = m_extraCompilers; + m_extraCompilers.clear(); + + if (m_pysideUic().isExecutableFile()) { + auto uiMatcher = [](const Node *node) { + if (const FileNode *fileNode = node->asFileNode()) + return fileNode->fileType() == FileType::Form; + return false; + }; + const FilePaths uiFiles = project()->files(uiMatcher); + for (const FilePath &uiFile : uiFiles) { + FilePath generated = uiFile.parentDir(); + generated = generated.pathAppended("/ui_" + uiFile.baseName() + ".py"); + int index = Utils::indexOf(oldCompilers, [&](PySideUicExtraCompiler *oldCompiler) { + return oldCompiler->pySideUicPath() == m_pysideUic() + && oldCompiler->project() == project() && oldCompiler->source() == uiFile + && oldCompiler->targets() == FilePaths{generated}; + }); + if (index < 0) { + m_extraCompilers << new PySideUicExtraCompiler(m_pysideUic(), + project(), + uiFile, + {generated}, + this); + } else { + m_extraCompilers << oldCompilers.takeAt(index); + } + } + } + for (LanguageClient::Client *client : LanguageClient::LanguageClientManager::clients()) { + if (auto pylsClient = qobject_cast(client)) + pylsClient->updateExtraCompilers(project(), m_extraCompilers); + } + qDeleteAll(oldCompilers); +} + +QList PySideBuildStep::extraCompilers() const +{ + return m_extraCompilers; +} + +Id PySideBuildStep::id() +{ + return Id("Python.PysideBuildStep"); +} + +class PythonBuildSettingsWidget : public NamedWidget +{ +public: + PythonBuildSettingsWidget(PythonBuildConfiguration *bc) + : NamedWidget(Tr::tr("Python")) + { + using namespace Layouting; + m_configureDetailsWidget = new DetailsWidget; + m_configureDetailsWidget->setSummaryText(bc->python().toUserOutput()); + + if (const std::optional venv = bc->venv()) { + auto details = new QWidget(); + Form{Tr::tr("Effective venv:"), venv->toUserOutput(), br}.attachTo(details); + m_configureDetailsWidget->setWidget(details); + } else { + m_configureDetailsWidget->setState(DetailsWidget::OnlySummary); + } + + Column{ + m_configureDetailsWidget, + noMargin + }.attachTo(this); + } +private: + DetailsWidget *m_configureDetailsWidget; +}; + +PythonBuildConfiguration::PythonBuildConfiguration(Target *target, const Id &id) + : BuildConfiguration(target, id) + , m_buildSystem(std::make_unique(this)) +{ + setInitializer([this](const BuildInfo &info) { initialize(info); }); + + updateCacheAndEmitEnvironmentChanged(); + + connect(PySideInstaller::instance(), + &PySideInstaller::pySideInstalled, + this, + &PythonBuildConfiguration::handlePythonUpdated); + + auto update = [this]() { + if (isActive()) { + m_buildSystem->emitBuildSystemUpdated(); + const FilePaths files = project()->files(Project::AllFiles); + for (const FilePath &file : files) { + if (auto doc = qobject_cast( + Core::DocumentModel::documentForFilePath(file))) { + doc->updatePython(m_python); + } + } + } + }; + connect(target, &Target::activeBuildConfigurationChanged, this, update); + connect(project(), &Project::activeTargetChanged, this, update); + connect(ProjectExplorerPlugin::instance(), + &ProjectExplorerPlugin::fileListChanged, + this, + update); + connect(PythonSettings::instance(), + &PythonSettings::virtualEnvironmentCreated, + this, + &PythonBuildConfiguration::handlePythonUpdated); +} + +NamedWidget *PythonBuildConfiguration::createConfigWidget() +{ + return new PythonBuildSettingsWidget(this); +} + +static QString venvTypeName() +{ + static QString name = Tr::tr("New Virtual Environment"); + return name; +} + +void PythonBuildConfiguration::initialize(const BuildInfo &info) +{ + buildSteps()->appendStep(PySideBuildStep::id()); + if (info.typeName == venvTypeName()) { + m_venv = info.buildDirectory; + const FilePath venvInterpreterPath = info.buildDirectory.resolvePath( + HostOsInfo::isWindowsHost() ? FilePath::fromUserInput("Scripts/python.exe") + : FilePath::fromUserInput("bin/python")); + + updatePython(venvInterpreterPath); + + if (info.extraInfo.toMap().value("createVenv", false).toBool() + && !info.buildDirectory.exists()) { + if (std::optional python = PythonKitAspect::python(target()->kit())) + PythonSettings::createVirtualEnvironment(python->command, info.buildDirectory); + } + } else { + updateInterpreter(PythonKitAspect::python(target()->kit())); + } + + updateCacheAndEmitEnvironmentChanged(); +} + +void PythonBuildConfiguration::updateInterpreter(const std::optional &python) +{ + updatePython(python ? python->command : FilePath()); +} + +void PythonBuildConfiguration::updatePython(const FilePath &python) +{ + m_python = python; + if (auto buildStep = buildSteps()->firstOfType()) + buildStep->checkForPySide(python); + if (isActive()) { + const FilePaths files = project()->files(Project::AllFiles); + for (const FilePath &file : files) { + if (auto doc = qobject_cast( + Core::DocumentModel::documentForFilePath(file))) { + doc->updatePython(m_python); + } + } + } + m_buildSystem->requestParse(); +} + +void PythonBuildConfiguration::handlePythonUpdated(const FilePath &python) +{ + if (!m_python.isEmpty() && python == m_python) + updatePython(python); // retrigger pyside check +} + +static const char pythonKey[] = "python"; +static const char venvKey[] = "venv"; + +void PythonBuildConfiguration::fromMap(const Store &map) +{ + BuildConfiguration::fromMap(map); + if (map.contains(venvKey)) + m_venv = FilePath::fromSettings(map[venvKey]); + updatePython(FilePath::fromSettings(map[pythonKey])); +} + +void PythonBuildConfiguration::toMap(Store &map) const +{ + BuildConfiguration::toMap(map); + map[pythonKey] = m_python.toSettings(); + if (m_venv) + map[venvKey] = m_venv->toSettings(); +} + +BuildSystem *PythonBuildConfiguration::buildSystem() const +{ + return m_buildSystem.get(); +} + +FilePath PythonBuildConfiguration::python() const +{ + return m_python; +} + +std::optional PythonBuildConfiguration::venv() const +{ + return m_venv; +} + +PythonBuildConfigurationFactory::PythonBuildConfigurationFactory() +{ + registerBuildConfiguration("Python.PySideBuildConfiguration"); + setSupportedProjectType(PythonProjectId); + setSupportedProjectMimeTypeName(Constants::C_PY_PROJECT_MIME_TYPE); + setBuildGenerator([](const Kit *k, const FilePath &projectPath, bool forSetup) { + if (std::optional python = PythonKitAspect::python(k)) { + BuildInfo base; + base.buildDirectory = projectPath.parentDir(); + base.displayName = python->name; + base.typeName = Tr::tr("Global Python"); + base.showBuildDirConfigWidget = false; + + if (isVenvPython(python->command)) + return QList{base}; + + base.enabledByDefault = false; + + BuildInfo venv; + const FilePath venvBase = projectPath.parentDir() / ".qtcreator" + / FileUtils::fileSystemFriendlyName(python->name + "venv"); + venv.buildDirectory = venvBase; + int i = 2; + while (venv.buildDirectory.exists()) + venv.buildDirectory = venvBase.stringAppended('_' + QString::number(i++)); + venv.displayName = python->name + Tr::tr(" Virtual Environment"); + venv.typeName = venvTypeName(); + venv.extraInfo = QVariantMap{{"createVenv", forSetup}}; + return QList{base, venv}; + } + return QList{}; + }); +} + +} // Python::Internal diff --git a/src/plugins/python/pythonbuildconfiguration.h b/src/plugins/python/pythonbuildconfiguration.h new file mode 100644 index 00000000000..a4d9440bdb1 --- /dev/null +++ b/src/plugins/python/pythonbuildconfiguration.h @@ -0,0 +1,86 @@ +// Copyright (C) 2022 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include "pythonbuildsystem.h" + +#include +#include +#include + + +namespace ProjectExplorer { class Interpreter; } +namespace Python::Internal { + +class PipPackageInfo; +class PySideUicExtraCompiler; + +class PySideBuildStep : public ProjectExplorer::AbstractProcessStep +{ + Q_OBJECT +public: + PySideBuildStep(ProjectExplorer::BuildStepList *bsl, Utils::Id id); + ~PySideBuildStep(); + + void checkForPySide(const Utils::FilePath &python); + + QList extraCompilers() const; + + static Utils::Id id(); + +private: + void checkForPySide(const Utils::FilePath &python, const QString &pySidePackageName); + void handlePySidePackageInfo(const PipPackageInfo &pySideInfo, + const Utils::FilePath &python, + const QString &requestedPackageName); + + Tasking::GroupItem runRecipe() final; + void updateExtraCompilers(); + + std::unique_ptr> m_watcher; + QMetaObject::Connection m_watcherConnection; + + Utils::FilePathAspect m_pysideProject{this}; + Utils::FilePathAspect m_pysideUic{this}; + QList m_extraCompilers; +}; + +class PySideBuildStepFactory : public ProjectExplorer::BuildStepFactory +{ +public: + PySideBuildStepFactory(); +}; + +class PythonBuildConfiguration : public ProjectExplorer::BuildConfiguration +{ + Q_OBJECT +public: + PythonBuildConfiguration(ProjectExplorer::Target *target, const Utils::Id &id); + + ProjectExplorer::NamedWidget *createConfigWidget() override; + void fromMap(const Utils::Store &map) override; + void toMap(Utils::Store &map) const override; + ProjectExplorer::BuildSystem *buildSystem() const override; + + Utils::FilePath python() const; + std::optional venv() const; + +private: + void initialize(const ProjectExplorer::BuildInfo &info); + void updateInterpreter(const std::optional &python); + void updatePython(const Utils::FilePath &python); + void handlePythonUpdated(const Utils::FilePath &python); + + Utils::FilePath m_python; + std::optional m_venv; + std::unique_ptr m_buildSystem; +}; + +class PythonBuildConfigurationFactory : public ProjectExplorer::BuildConfigurationFactory +{ +public: + PythonBuildConfigurationFactory(); +}; + +} // namespace Python::Internal diff --git a/src/plugins/python/pythonbuildsystem.cpp b/src/plugins/python/pythonbuildsystem.cpp index 5754063d858..e46e33497bc 100644 --- a/src/plugins/python/pythonbuildsystem.cpp +++ b/src/plugins/python/pythonbuildsystem.cpp @@ -3,7 +3,9 @@ #include "pythonbuildsystem.h" +#include "pythonbuildconfiguration.h" #include "pythonconstants.h" +#include "pythonkitaspect.h" #include "pythonproject.h" #include "pythontr.h" @@ -116,11 +118,15 @@ static QStringList readImportPathsJson(const FilePath &projectFile, QString *err return importPaths; } -PythonBuildSystem::PythonBuildSystem(Target *target) - : BuildSystem(target) +PythonBuildSystem::PythonBuildSystem(PythonBuildConfiguration *buildConfig) + : BuildSystem(buildConfig) { - connect(target->project(), &Project::projectFileIsDirty, this, [this] { triggerParsing(); }); - triggerParsing(); + connect(project(), + &Project::projectFileIsDirty, + this, + &PythonBuildSystem::requestDelayedParse); + m_buildConfig = buildConfig; + requestParse(); } bool PythonBuildSystem::supportsAction(Node *context, ProjectAction action, const Node *node) const @@ -159,6 +165,12 @@ void PythonBuildSystem::triggerParsing() auto newRoot = std::make_unique(projectDirectory()); + FilePath python; + if (m_buildConfig) + python = m_buildConfig->python(); + else if (auto kitPython = PythonKitAspect::python(kit())) + python = kitPython->command; + const FilePath projectFile = projectFilePath(); const QString displayName = projectFile.relativePathFrom(projectDirectory()).toUserOutput(); newRoot->addNestedNode( @@ -178,6 +190,7 @@ void PythonBuildSystem::triggerParsing() bti.targetFilePath = entry.filePath; bti.projectFilePath = projectFile; bti.isQtcRunnable = entry.filePath.fileName() == "main.py"; + bti.additionalData = QVariantMap{{"python", python.toSettings()}}; appTargets.append(bti); } } diff --git a/src/plugins/python/pythonbuildsystem.h b/src/plugins/python/pythonbuildsystem.h index 8bd79391dc2..9729ac3fe50 100644 --- a/src/plugins/python/pythonbuildsystem.h +++ b/src/plugins/python/pythonbuildsystem.h @@ -7,10 +7,12 @@ namespace Python::Internal { +class PythonBuildConfiguration; + class PythonBuildSystem : public ProjectExplorer::BuildSystem { public: - explicit PythonBuildSystem(ProjectExplorer::Target *target); + explicit PythonBuildSystem(PythonBuildConfiguration *buildConfig); bool supportsAction(ProjectExplorer::Node *context, ProjectExplorer::ProjectAction action, @@ -44,6 +46,7 @@ private: QList m_files; QList m_qmlImportPaths; + PythonBuildConfiguration *m_buildConfig = nullptr; }; diff --git a/src/plugins/python/pythonconstants.h b/src/plugins/python/pythonconstants.h index add9d6b6d64..ce7d93fb0bb 100644 --- a/src/plugins/python/pythonconstants.h +++ b/src/plugins/python/pythonconstants.h @@ -32,6 +32,9 @@ const char C_PY_MIMETYPE[] = "text/x-python"; const char C_PY_GUI_MIMETYPE[] = "text/x-python-gui"; const char C_PY3_MIMETYPE[] = "text/x-python3"; const char C_PY_MIME_ICON[] = "text-x-python"; +const char C_PY_PROJECT_MIME_TYPE[] = "text/x-python-project"; +const char C_PY_PROJECT_MIME_TYPE_LEGACY[] = "text/x-pyqt-project"; + } // namespace Constants } // namespace Python diff --git a/src/plugins/python/pythoneditor.cpp b/src/plugins/python/pythoneditor.cpp index 6a6a377ba0a..58635d1a69b 100644 --- a/src/plugins/python/pythoneditor.cpp +++ b/src/plugins/python/pythoneditor.cpp @@ -4,10 +4,13 @@ #include "pythoneditor.h" #include "pyside.h" +#include "pythonbuildconfiguration.h" #include "pythonconstants.h" #include "pythonhighlighter.h" #include "pythonindenter.h" +#include "pythonkitaspect.h" #include "pythonlanguageclient.h" +#include "pythonplugin.h" #include "pythonsettings.h" #include "pythontr.h" #include "pythonutils.h" @@ -17,12 +20,14 @@ #include #include +#include +#include +#include #include #include #include #include -#include #include #include @@ -73,37 +78,6 @@ static void registerReplAction(QObject *parent) Constants::PYTHON_OPEN_REPL_IMPORT_TOPLEVEL); } -class PythonDocument : public TextDocument -{ - Q_OBJECT -public: - PythonDocument() : TextDocument(Constants::C_PYTHONEDITOR_ID) - { - connect(PythonSettings::instance(), - &PythonSettings::pylsEnabledChanged, - this, - [this](const bool enabled) { - if (!enabled) - return; - const FilePath &python = detectPython(filePath()); - if (python.exists()) - PyLSConfigureAssistant::openDocumentWithPython(python, this); - }); - connect(this, &PythonDocument::openFinishedSuccessfully, - this, &PythonDocument::checkForPyls); - } - - void checkForPyls() - { - const FilePath &python = detectPython(filePath()); - if (!python.exists()) - return; - - PyLSConfigureAssistant::openDocumentWithPython(python, this); - PySideInstaller::checkPySideInstallation(python, this); - } -}; - class PythonEditorWidget : public TextEditorWidget { public: @@ -111,12 +85,10 @@ public: protected: void finalizeInitialization() override; - void setUserDefinedPython(const Interpreter &interpreter); void updateInterpretersSelector(); private: QToolButton *m_interpreters = nullptr; - QList m_projectConnections; }; PythonEditorWidget::PythonEditorWidget(QWidget *parent) : TextEditorWidget(parent) @@ -142,31 +114,15 @@ void PythonEditorWidget::finalizeInitialization() { connect(textDocument(), &TextDocument::filePathChanged, this, &PythonEditorWidget::updateInterpretersSelector); - connect(PythonSettings::instance(), &PythonSettings::interpretersChanged, - this, &PythonEditorWidget::updateInterpretersSelector); connect(ProjectExplorerPlugin::instance(), &ProjectExplorerPlugin::fileListChanged, this, &PythonEditorWidget::updateInterpretersSelector); -} - -void PythonEditorWidget::setUserDefinedPython(const Interpreter &interpreter) -{ - const auto pythonDocument = qobject_cast(textDocument()); - QTC_ASSERT(pythonDocument, return); - FilePath documentPath = pythonDocument->filePath(); - QTC_ASSERT(!documentPath.isEmpty(), return); - if (Project *project = ProjectManager::projectForFile(documentPath)) { - if (Target *target = project->activeTarget()) { - if (RunConfiguration *rc = target->activeRunConfiguration()) { - if (auto interpretersAspect= rc->aspect()) { - interpretersAspect->setCurrentInterpreter(interpreter); - return; - } - } - } + connect(KitManager::instance(), &KitManager::kitsChanged, + this, &PythonEditorWidget::updateInterpretersSelector); + auto pythonDocument = qobject_cast(textDocument()); + if (QTC_GUARD(pythonDocument)) { + connect(pythonDocument, &PythonDocument::pythonUpdated, + this, &PythonEditorWidget::updateInterpretersSelector); } - definePythonForDocument(textDocument()->filePath(), interpreter.command); - updateInterpretersSelector(); - pythonDocument->checkForPyls(); } void PythonEditorWidget::updateInterpretersSelector() @@ -183,30 +139,6 @@ void PythonEditorWidget::updateInterpretersSelector() QMenu *menu = m_interpreters->menu(); QTC_ASSERT(menu, return); menu->clear(); - for (const QMetaObject::Connection &connection : m_projectConnections) - disconnect(connection); - m_projectConnections.clear(); - const FilePath documentPath = textDocument()->filePath(); - if (Project *project = ProjectManager::projectForFile(documentPath)) { - m_projectConnections << connect(project, - &Project::activeTargetChanged, - this, - &PythonEditorWidget::updateInterpretersSelector); - if (Target *target = project->activeTarget()) { - m_projectConnections << connect(target, - &Target::activeRunConfigurationChanged, - this, - &PythonEditorWidget::updateInterpretersSelector); - if (RunConfiguration *rc = target->activeRunConfiguration()) { - if (auto interpreterAspect = rc->aspect()) { - m_projectConnections << connect(interpreterAspect, - &InterpreterAspect::changed, - this, - &PythonEditorWidget::updateInterpretersSelector); - } - } - } - } auto setButtonText = [this](QString text) { constexpr int maxTextLength = 25; @@ -215,50 +147,130 @@ void PythonEditorWidget::updateInterpretersSelector() m_interpreters->setText(text); }; - const FilePath currentInterpreterPath = detectPython(textDocument()->filePath()); - const QList configuredInterpreters = PythonSettings::interpreters(); - auto interpretersGroup = new QActionGroup(menu); - interpretersGroup->setExclusive(true); - std::optional currentInterpreter; - for (const Interpreter &interpreter : configuredInterpreters) { - QAction *action = interpretersGroup->addAction(interpreter.name); - connect(action, &QAction::triggered, this, [this, interpreter]() { - setUserDefinedPython(interpreter); - }); - action->setCheckable(true); - if (!currentInterpreter && interpreter.command == currentInterpreterPath) { - currentInterpreter = interpreter; - action->setChecked(true); - setButtonText(interpreter.name); - m_interpreters->setToolTip(interpreter.command.toUserOutput()); + const FilePath documentPath = textDocument()->filePath(); + Project *project = Utils::findOrDefault(ProjectManager::projects(), + [documentPath](Project *project) { + return project->mimeType() + == Constants::C_PY_PROJECT_MIME_TYPE + && project->isKnownFile(documentPath); + }); + + if (project) { + auto interpretersGroup = new QActionGroup(menu); + interpretersGroup->setExclusive(true); + for (Target *target : project->targets()) { + QTC_ASSERT(target, continue); + for (auto buildConfiguration : target->buildConfigurations()) { + QTC_ASSERT(buildConfiguration, continue); + const QString name = buildConfiguration->displayName(); + QAction *action = interpretersGroup->addAction(buildConfiguration->displayName()); + action->setCheckable(true); + if (target == project->activeTarget() + && target->activeBuildConfiguration() == buildConfiguration) { + action->setChecked(true); + setButtonText(name); + if (auto pbc = qobject_cast(buildConfiguration)) + m_interpreters->setToolTip(pbc->python().toUserOutput()); + } + connect(action, + &QAction::triggered, + project, + [project, target, buildConfiguration]() { + target->setActiveBuildConfiguration(buildConfiguration, + SetActive::NoCascade); + if (target != project->activeTarget()) + project->setActiveTarget(target, SetActive::NoCascade); + }); + } } - } - menu->addActions(interpretersGroup->actions()); - if (!currentInterpreter) { - if (currentInterpreterPath.exists()) - setButtonText(currentInterpreterPath.toUserOutput()); - else - setButtonText(Tr::tr("No Python Selected")); - } - if (!interpretersGroup->actions().isEmpty()) { + + menu->addActions(interpretersGroup->actions()); + + QMenu *addMenu = menu->addMenu("Add new Interpreter"); + for (auto kit : KitManager::kits()) { + if (std::optional python = PythonKitAspect::python(kit)) { + if (auto buildConficurationFactory + = ProjectExplorer::BuildConfigurationFactory::find(kit, + project->projectFilePath())) { + const QString name = kit->displayName(); + QMenu *interpreterAddMenu = addMenu->addMenu(name); + const QList buildInfos + = buildConficurationFactory->allAvailableSetups(kit, + project->projectFilePath()); + for (const BuildInfo &buildInfo : buildInfos) { + QAction *action = interpreterAddMenu->addAction(buildInfo.displayName); + connect(action, &QAction::triggered, project, [project, buildInfo]() { + if (BuildConfiguration *buildConfig = project->setup(buildInfo)) { + buildConfig->target() + ->setActiveBuildConfiguration(buildConfig, SetActive::NoCascade); + project->setActiveTarget(buildConfig->target(), + SetActive::NoCascade); + } + }); + } + } + } + } + menu->addSeparator(); - auto venvAction = menu->addAction(Tr::tr("Create Virtual Environment")); - connect(venvAction, - &QAction::triggered, - this, - [self = QPointer(this), currentInterpreter]() { - if (!currentInterpreter) - return; - auto callback = [self](const std::optional &venvInterpreter) { - if (self && venvInterpreter) - self->setUserDefinedPython(*venvInterpreter); - }; - PythonSettings::createVirtualEnvironmentInteractive(self->textDocument() - ->filePath() - .parentDir(), - *currentInterpreter, - callback); - }); + } else { + auto setUserDefinedPython = [this](const FilePath &interpreter){ + const auto pythonDocument = qobject_cast(textDocument()); + QTC_ASSERT(pythonDocument, return); + const FilePath documentPath = pythonDocument->filePath(); + QTC_ASSERT(!documentPath.isEmpty(), return); + definePythonForDocument(documentPath, interpreter); + updateInterpretersSelector(); + pythonDocument->updateCurrentPython(); + }; + const FilePath currentInterpreterPath = detectPython(documentPath); + const QList configuredInterpreters = PythonSettings::interpreters(); + auto interpretersGroup = new QActionGroup(menu); + interpretersGroup->setExclusive(true); + std::optional currentInterpreter; + for (const Interpreter &interpreter : configuredInterpreters) { + QAction *action = interpretersGroup->addAction(interpreter.name); + connect(action, &QAction::triggered, this, [interpreter, setUserDefinedPython]() { + setUserDefinedPython(interpreter.command); + }); + action->setCheckable(true); + if (!currentInterpreter && interpreter.command == currentInterpreterPath) { + currentInterpreter = interpreter; + action->setChecked(true); + setButtonText(interpreter.name); + m_interpreters->setToolTip(interpreter.command.toUserOutput()); + } + } + menu->addActions(interpretersGroup->actions()); + if (!currentInterpreter) { + if (currentInterpreterPath.exists()) + setButtonText(currentInterpreterPath.toUserOutput()); + else + setButtonText(Tr::tr("No Python Selected")); + } + if (!interpretersGroup->actions().isEmpty()) { + menu->addSeparator(); + auto venvAction = menu->addAction(Tr::tr("Create Virtual Environment")); + connect(venvAction, + &QAction::triggered, + this, + [self = QPointer(this), + currentInterpreter, + setUserDefinedPython]() { + if (!currentInterpreter) + return; + auto callback = [self, setUserDefinedPython]( + const std::optional &venvInterpreter) { + if (self && venvInterpreter) + setUserDefinedPython(*venvInterpreter); + }; + PythonSettings::createVirtualEnvironmentInteractive(self->textDocument() + ->filePath() + .parentDir(), + *currentInterpreter, + callback); + }); + } } auto settingsAction = menu->addAction(Tr::tr("Manage Python Interpreters")); connect(settingsAction, &QAction::triggered, this, []() { @@ -288,6 +300,35 @@ PythonEditorFactory::PythonEditorFactory() setCodeFoldingSupported(true); } -} // Python::Internal +PythonDocument::PythonDocument() + : TextDocument(Constants::C_PYTHONEDITOR_ID) +{ + connect(PythonSettings::instance(), + &PythonSettings::pylsEnabledChanged, + this, + [this](const bool enabled) { + if (!enabled) + return; + const FilePath &python = detectPython(filePath()); + if (python.exists()) + PyLSConfigureAssistant::openDocumentWithPython(python, this); + }); + connect(this, + &PythonDocument::openFinishedSuccessfully, + this, + &PythonDocument::updateCurrentPython); +} -#include "pythoneditor.moc" +void PythonDocument::updateCurrentPython() +{ + updatePython(detectPython(filePath())); +} + +void PythonDocument::updatePython(const FilePath &python) +{ + PyLSConfigureAssistant::openDocumentWithPython(python, this); + PySideInstaller::checkPySideInstallation(python, this); + emit pythonUpdated(python); +} + +} // Python::Internal diff --git a/src/plugins/python/pythoneditor.h b/src/plugins/python/pythoneditor.h index e2eef32b88d..6f6b30c1c3e 100644 --- a/src/plugins/python/pythoneditor.h +++ b/src/plugins/python/pythoneditor.h @@ -3,6 +3,7 @@ #pragma once +#include #include namespace Python::Internal { @@ -15,4 +16,17 @@ private: QObject m_guard; }; +class PythonDocument : public TextEditor::TextDocument +{ + Q_OBJECT +public: + PythonDocument(); + + void updateCurrentPython(); + void updatePython(const Utils::FilePath &python); + +signals: + void pythonUpdated(const Utils::FilePath &python); +}; + } // Python::Internal diff --git a/src/plugins/python/pythonkitaspect.cpp b/src/plugins/python/pythonkitaspect.cpp index ec3609c8cd9..97dd87f6d11 100644 --- a/src/plugins/python/pythonkitaspect.cpp +++ b/src/plugins/python/pythonkitaspect.cpp @@ -119,6 +119,13 @@ public: } KitAspect *createKitAspect(Kit *k) const override { return new PythonKitAspectImpl(k, this); } + + QSet availableFeatures(const Kit *k) const override + { + if (k->isAspectRelevant(PythonKitAspect::id()) && PythonKitAspect::python(k)) + return {PythonKitAspect::id()}; + return {}; + } }; std::optional PythonKitAspect::python(const Kit *kit) diff --git a/src/plugins/python/pythonlanguageclient.cpp b/src/plugins/python/pythonlanguageclient.cpp index b13aef42077..b059401dd35 100644 --- a/src/plugins/python/pythonlanguageclient.cpp +++ b/src/plugins/python/pythonlanguageclient.cpp @@ -4,6 +4,7 @@ #include "pythonlanguageclient.h" #include "pipsupport.h" +#include "pythonbuildconfiguration.h" #include "pysideuicextracompiler.h" #include "pythonconstants.h" #include "pythonplugin.h" @@ -22,6 +23,8 @@ #include #include +#include +#include #include #include #include @@ -207,12 +210,13 @@ void PyLSClient::openDocument(TextEditor::TextDocument *document) const FilePath documentPath = document->filePath(); if (PythonProject *project = pythonProjectForFile(documentPath)) { if (Target *target = project->activeTarget()) { - if (RunConfiguration *rc = target->activeRunConfiguration()) - if (auto aspect = rc->aspect()) { - updateExtraCompilers(project, - static_cast(aspect) - ->extraCompilers()); + if (BuildConfiguration *buildConfig = target->activeBuildConfiguration()) { + if (BuildStepList *buildSteps = buildConfig->buildSteps()) { + BuildStep *buildStep = buildSteps->firstStepWithId(PySideBuildStep::id()); + if (auto *pythonBuildStep = qobject_cast(buildStep)) + updateExtraCompilers(project, pythonBuildStep->extraCompilers()); } + } } } else if (isSupportedDocument(document)) { const FilePath workspacePath = documentPath.parentDir(); @@ -321,7 +325,7 @@ void PyLSConfigureAssistant::openDocumentWithPython(const FilePath &python, TextEditor::TextDocument *document) { instance()->resetEditorInfoBar(document); - if (!PythonSettings::pylsEnabled()) + if (!PythonSettings::pylsEnabled() || !python.exists()) return; if (auto client = pythonClients().value(python)) { @@ -347,9 +351,13 @@ void PyLSConfigureAssistant::openDocumentWithPython(const FilePath &python, if (!document || !watcher) return; instance()->handlePyLSState(python, watcher->result(), document); - watcher->deleteLater(); }); + connect(watcher, &CheckPylsWatcher::finished, watcher, &CheckPylsWatcher::deleteLater); + connect(watcher, &CheckPylsWatcher::finished, instance(), [document](){ + instance()->m_runningChecks.remove(document); + }); watcher->setFuture(Utils::asyncRun(&checkPythonLanguageServer, python)); + instance()->m_runningChecks[document] = watcher; } void PyLSConfigureAssistant::handlePyLSState(const FilePath &python, @@ -383,6 +391,8 @@ void PyLSConfigureAssistant::resetEditorInfoBar(TextEditor::TextDocument *docume for (QList &documents : m_infoBarEntries) documents.removeAll(document); document->infoBar()->removeInfo(installPylsInfoBarId); + if (auto watcher = m_runningChecks.value(document)) + watcher->cancel(); } PyLSConfigureAssistant::PyLSConfigureAssistant(QObject *parent) diff --git a/src/plugins/python/pythonlanguageclient.h b/src/plugins/python/pythonlanguageclient.h index 41b559a0427..d3c88f046f2 100644 --- a/src/plugins/python/pythonlanguageclient.h +++ b/src/plugins/python/pythonlanguageclient.h @@ -67,6 +67,8 @@ private: QPointer document); QHash> m_infoBarEntries; + QHash>> + m_runningChecks; }; } // Python::Internal diff --git a/src/plugins/python/pythonplugin.cpp b/src/plugins/python/pythonplugin.cpp index fdfc0095554..d74c45b7784 100644 --- a/src/plugins/python/pythonplugin.cpp +++ b/src/plugins/python/pythonplugin.cpp @@ -3,7 +3,8 @@ #include "pythonplugin.h" -#include "pysidebuildconfiguration.h" +#include "pythonbuildconfiguration.h" +#include "pythonconstants.h" #include "pythoneditor.h" #include "pythonkitaspect.h" #include "pythonproject.h" @@ -36,7 +37,7 @@ public: PythonOutputFormatterFactory outputFormatterFactory; PythonRunConfigurationFactory runConfigFactory; PySideBuildStepFactory buildStepFactory; - PySideBuildConfigurationFactory buildConfigFactory; + PythonBuildConfigurationFactory buildConfigFactory; SimpleTargetRunnerFactory runWorkerFactory{{runConfigFactory.runConfigurationId()}}; PythonSettings settings; PythonWizardPageFactory pythonWizardPageFactory; @@ -65,8 +66,8 @@ void PythonPlugin::initialize() KitManager::setIrrelevantAspects(KitManager::irrelevantAspects() + QSet{PythonKitAspect::id()}); - ProjectManager::registerProjectType(PythonMimeType); - ProjectManager::registerProjectType(PythonMimeTypeLegacy); + ProjectManager::registerProjectType(Constants::C_PY_PROJECT_MIME_TYPE); + ProjectManager::registerProjectType(Constants::C_PY_PROJECT_MIME_TYPE_LEGACY); } void PythonPlugin::extensionsInitialized() diff --git a/src/plugins/python/pythonplugin.h b/src/plugins/python/pythonplugin.h index ef0860bbca4..aefe24d2406 100644 --- a/src/plugins/python/pythonplugin.h +++ b/src/plugins/python/pythonplugin.h @@ -7,6 +7,8 @@ namespace Python::Internal { +class PythonBuildConfigurationFactory; + class PythonPlugin final : public ExtensionSystem::IPlugin { Q_OBJECT diff --git a/src/plugins/python/pythonproject.cpp b/src/plugins/python/pythonproject.cpp index c259b088406..316e35d2620 100644 --- a/src/plugins/python/pythonproject.cpp +++ b/src/plugins/python/pythonproject.cpp @@ -9,6 +9,7 @@ #include #include +#include using namespace Core; using namespace ProjectExplorer; @@ -17,16 +18,13 @@ using namespace Utils; namespace Python::Internal { PythonProject::PythonProject(const FilePath &fileName) - : Project(Constants::C_PY_MIMETYPE, fileName) + : Project(Constants::C_PY_PROJECT_MIME_TYPE, fileName) { setId(PythonProjectId); setProjectLanguages(Context(ProjectExplorer::Constants::PYTHON_LANGUAGE_ID)); setDisplayName(fileName.completeBaseName()); - - setBuildSystemCreator([](Target *t) { return new PythonBuildSystem(t); }); } - Project::RestoreResult PythonProject::fromMap(const Store &map, QString *errorMessage) { Project::RestoreResult res = Project::fromMap(map, errorMessage); diff --git a/src/plugins/python/pythonproject.h b/src/plugins/python/pythonproject.h index 39e1da8bc73..f59b2b831bc 100644 --- a/src/plugins/python/pythonproject.h +++ b/src/plugins/python/pythonproject.h @@ -10,8 +10,6 @@ namespace Utils { class FilePath; } namespace Python::Internal { -const char PythonMimeType[] = "text/x-python-project"; -const char PythonMimeTypeLegacy[] = "text/x-pyqt-project"; const char PythonProjectId[] = "PythonProject"; const char PythonErrorTaskCategory[] = "Task.Category.Python"; diff --git a/src/plugins/python/pythonrunconfiguration.cpp b/src/plugins/python/pythonrunconfiguration.cpp index f5e16ae15dc..be7ceb0a5da 100644 --- a/src/plugins/python/pythonrunconfiguration.cpp +++ b/src/plugins/python/pythonrunconfiguration.cpp @@ -3,24 +3,21 @@ #include "pythonrunconfiguration.h" -#include "pipsupport.h" #include "pyside.h" -#include "pysidebuildconfiguration.h" -#include "pysideuicextracompiler.h" +#include "pythonbuildconfiguration.h" #include "pythonconstants.h" +#include "pythoneditor.h" #include "pythonkitaspect.h" #include "pythonlanguageclient.h" #include "pythonproject.h" #include "pythonsettings.h" #include "pythontr.h" -#include #include +#include #include -#include - #include #include #include @@ -36,6 +33,7 @@ #include #include #include +#include #include #include @@ -118,229 +116,6 @@ private: bool m_inTraceBack; }; -//////////////////////////////////////////////////////////////// - -class PythonInterpreterAspectPrivate : public QObject -{ -public: - PythonInterpreterAspectPrivate(PythonInterpreterAspect *parent, RunConfiguration *rc) - : q(parent), rc(rc) - { - connect(q, &InterpreterAspect::changed, - this, &PythonInterpreterAspectPrivate::currentInterpreterChanged); - - connect(PySideInstaller::instance(), &PySideInstaller::pySideInstalled, this, - [this](const FilePath &python) { - if (python == q->currentInterpreter().command) - checkForPySide(python); - } - ); - - connect(rc->target(), &Target::buildSystemUpdated, - this, &PythonInterpreterAspectPrivate::updateExtraCompilers); - } - - ~PythonInterpreterAspectPrivate() { qDeleteAll(m_extraCompilers); } - - void checkForPySide(const FilePath &python); - void checkForPySide(const FilePath &python, const QString &pySidePackageName); - void handlePySidePackageInfo(const PipPackageInfo &pySideInfo, - const FilePath &python, - const QString &requestedPackageName); - void updateExtraCompilers(); - void currentInterpreterChanged(); - - struct PySideTools - { - FilePath pySideProjectPath; - FilePath pySideUicPath; - }; - void updateTools(const PySideTools &tools); - - FilePath m_pySideUicPath; - - PythonInterpreterAspect *q; - RunConfiguration *rc; - QList m_extraCompilers; - QFutureWatcher *m_watcher = nullptr; - QMetaObject::Connection m_watcherConnection; -}; - -PythonInterpreterAspect::PythonInterpreterAspect(AspectContainer *container, RunConfiguration *rc) - : InterpreterAspect(container), d(new PythonInterpreterAspectPrivate(this, rc)) -{ - setSettingsKey("PythonEditor.RunConfiguation.Interpreter"); - setSettingsDialogId(Constants::C_PYTHONOPTIONS_PAGE_ID); - - updateInterpreters(PythonSettings::interpreters()); - - const QList interpreters = PythonSettings::detectPythonVenvs( - rc->project()->projectDirectory()); - Interpreter defaultInterpreter = interpreters.isEmpty() ? PythonSettings::defaultInterpreter() - : interpreters.first(); - if (!defaultInterpreter.command.isExecutableFile()) - defaultInterpreter = PythonSettings::interpreters().value(0); - if (defaultInterpreter.command.isExecutableFile()) { - const IDeviceConstPtr device = DeviceKitAspect::device(rc->kit()); - if (device && !device->handlesFile(defaultInterpreter.command)) { - defaultInterpreter = Utils::findOr(PythonSettings::interpreters(), - defaultInterpreter, - [device](const Interpreter &interpreter) { - return device->handlesFile(interpreter.command); - }); - } - } - setDefaultInterpreter(defaultInterpreter); - - connect(PythonSettings::instance(), &PythonSettings::interpretersChanged, - this, &InterpreterAspect::updateInterpreters); -} - -PythonInterpreterAspect::~PythonInterpreterAspect() -{ - delete d; -} - -void PythonInterpreterAspectPrivate::checkForPySide(const FilePath &python) -{ - PySideTools tools; - const FilePath dir = python.parentDir(); - tools.pySideProjectPath = dir.pathAppended("pyside6-project").withExecutableSuffix(); - tools.pySideUicPath = dir.pathAppended("pyside6-uic").withExecutableSuffix(); - - if (tools.pySideProjectPath.isExecutableFile() && tools.pySideUicPath.isExecutableFile()) - updateTools(tools); - else - checkForPySide(python, "PySide6-Essentials"); -} - -void PythonInterpreterAspectPrivate::checkForPySide(const FilePath &python, - const QString &pySidePackageName) -{ - const PipPackage package(pySidePackageName); - QObject::disconnect(m_watcherConnection); - delete m_watcher; - m_watcher = new QFutureWatcher(this); - m_watcherConnection = QObject::connect(m_watcher, &QFutureWatcherBase::finished, q, [=] { - handlePySidePackageInfo(m_watcher->result(), python, pySidePackageName); - }); - const auto future = Pip::instance(python)->info(package); - m_watcher->setFuture(future); - ExtensionSystem::PluginManager::futureSynchronizer()->addFuture(future); -} - -void PythonInterpreterAspectPrivate::handlePySidePackageInfo(const PipPackageInfo &pySideInfo, - const FilePath &python, - const QString &requestedPackageName) -{ - const auto findPythonTools = [](const FilePaths &files, - const FilePath &location, - const FilePath &python) -> PySideTools { - PySideTools result; - const QString pySide6ProjectName - = OsSpecificAspects::withExecutableSuffix(python.osType(), "pyside6-project"); - const QString pySide6UicName - = OsSpecificAspects::withExecutableSuffix(python.osType(), "pyside6-uic"); - for (const FilePath &file : files) { - if (file.fileName() == pySide6ProjectName) { - result.pySideProjectPath = python.withNewMappedPath(location.resolvePath(file)); - result.pySideProjectPath = result.pySideProjectPath.cleanPath(); - if (!result.pySideUicPath.isEmpty()) - return result; - } else if (file.fileName() == pySide6UicName) { - result.pySideUicPath = python.withNewMappedPath(location.resolvePath(file)); - result.pySideUicPath = result.pySideUicPath.cleanPath(); - if (!result.pySideProjectPath.isEmpty()) - return result; - } - } - return {}; - }; - - PySideTools tools = findPythonTools(pySideInfo.files, pySideInfo.location, python); - if (!tools.pySideProjectPath.isExecutableFile() && requestedPackageName != "PySide6") { - checkForPySide(python, "PySide6"); - return; - } - - updateTools(tools); -} - -void PythonInterpreterAspectPrivate::currentInterpreterChanged() -{ - const FilePath python = q->currentInterpreter().command; - checkForPySide(python); - - for (FilePath &file : rc->project()->files(Project::AllFiles)) { - if (auto document = TextEditor::TextDocument::textDocumentForFilePath(file)) { - if (document->mimeType() == Constants::C_PY_MIMETYPE - || document->mimeType() == Constants::C_PY3_MIMETYPE) { - PyLSConfigureAssistant::openDocumentWithPython(python, document); - PySideInstaller::checkPySideInstallation(python, document); - } - } - } -} - -void PythonInterpreterAspectPrivate::updateTools(const PySideTools &tools) -{ - m_pySideUicPath = tools.pySideUicPath; - - updateExtraCompilers(); - - if (Target *target = rc->target()) { - if (BuildConfiguration *buildConfiguration = target->activeBuildConfiguration()) { - if (BuildStepList *buildSteps = buildConfiguration->buildSteps()) { - if (auto buildStep = buildSteps->firstOfType()) - buildStep->updatePySideProjectPath(tools.pySideProjectPath); - } - } - } -} - -QList PythonInterpreterAspect::extraCompilers() const -{ - return d->m_extraCompilers; -} - -void PythonInterpreterAspectPrivate::updateExtraCompilers() -{ - QList oldCompilers = m_extraCompilers; - m_extraCompilers.clear(); - - if (m_pySideUicPath.isExecutableFile()) { - auto uiMatcher = [](const Node *node) { - if (const FileNode *fileNode = node->asFileNode()) - return fileNode->fileType() == FileType::Form; - return false; - }; - const FilePaths uiFiles = rc->project()->files(uiMatcher); - for (const FilePath &uiFile : uiFiles) { - FilePath generated = uiFile.parentDir(); - generated = generated.pathAppended("/ui_" + uiFile.baseName() + ".py"); - int index = Utils::indexOf(oldCompilers, [&](PySideUicExtraCompiler *oldCompiler) { - return oldCompiler->pySideUicPath() == m_pySideUicPath - && oldCompiler->project() == rc->project() && oldCompiler->source() == uiFile - && oldCompiler->targets() == FilePaths{generated}; - }); - if (index < 0) { - m_extraCompilers << new PySideUicExtraCompiler(m_pySideUicPath, - rc->project(), - uiFile, - {generated}, - this); - } else { - m_extraCompilers << oldCompilers.takeAt(index); - } - } - } - for (LanguageClient::Client *client : LanguageClient::LanguageClientManager::clients()) { - if (auto pylsClient = qobject_cast(client)) - pylsClient->updateExtraCompilers(rc->project(), m_extraCompilers); - } - qDeleteAll(oldCompilers); -} - // RunConfiguration class PythonRunConfiguration : public RunConfiguration @@ -368,11 +143,14 @@ public: x11Forwarding.setMacroExpander(macroExpander()); x11Forwarding.setVisible(HostOsInfo::isAnyUnixHost()); - if (const std::optional kitPython = PythonKitAspect::python(target->kit())) - interpreter.setCurrentInterpreter(*kitPython); + interpreter.setLabelText(Tr::tr("Python:")); + interpreter.setReadOnly(true); setCommandLineGetter([this] { - CommandLine cmd{interpreter.currentInterpreter().command}; + CommandLine cmd; + cmd.setExecutable(interpreter()); + if (interpreter().isEmpty()) + return cmd; if (!buffered()) cmd.addArg("-u"); cmd.addArg(mainScript().fileName()); @@ -382,6 +160,9 @@ public: setUpdater([this] { const BuildTargetInfo bti = buildTargetInfo(); + const auto python = FilePath::fromSettings(bti.additionalData.toMap().value("python")); + interpreter.setValue(python); + setDefaultDisplayName(Tr::tr("Run %1").arg(bti.targetFilePath.toUserOutput())); mainScript.setValue(bti.targetFilePath); workingDir.setDefaultWorkingDirectory(bti.targetFilePath.parentDir()); @@ -390,7 +171,7 @@ public: connect(target, &Target::buildSystemUpdated, this, &RunConfiguration::update); } - PythonInterpreterAspect interpreter{this, this}; + FilePathAspect interpreter{this}; BoolAspect buffered{this}; MainScriptAspect mainScript{this}; EnvironmentAspect environment{this}; @@ -411,7 +192,7 @@ PythonRunConfigurationFactory::PythonRunConfigurationFactory() PythonOutputFormatterFactory::PythonOutputFormatterFactory() { setFormatterCreator([](Target *t) -> QList { - if (t && t->project()->mimeType() == Constants::C_PY_MIMETYPE) + if (t && t->project()->mimeType() == Constants::C_PY_PROJECT_MIME_TYPE) return {new PythonOutputLineParser}; return {}; }); diff --git a/src/plugins/python/pythonrunconfiguration.h b/src/plugins/python/pythonrunconfiguration.h index b4eb54b12f8..76bbca99b0f 100644 --- a/src/plugins/python/pythonrunconfiguration.h +++ b/src/plugins/python/pythonrunconfiguration.h @@ -10,7 +10,6 @@ namespace Python::Internal { class PySideUicExtraCompiler; -class PythonRunConfiguration; class PythonInterpreterAspect final : public ProjectExplorer::InterpreterAspect { @@ -18,8 +17,6 @@ public: PythonInterpreterAspect(Utils::AspectContainer *container, ProjectExplorer::RunConfiguration *rc); ~PythonInterpreterAspect() final; - QList extraCompilers() const; - private: friend class PythonRunConfiguration; class PythonInterpreterAspectPrivate *d = nullptr; diff --git a/src/plugins/python/pythonsettings.cpp b/src/plugins/python/pythonsettings.cpp index fdd49f9842d..26f6b8de4db 100644 --- a/src/plugins/python/pythonsettings.cpp +++ b/src/plugins/python/pythonsettings.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -813,7 +814,7 @@ void PythonSettings::addKitsForInterpreter(const Interpreter &interpreter) const Id kitId = Id::fromString(interpreter.id); if (Kit *k = KitManager::kit(kitId)) { setRelevantAspectsToKit(k); - } else { + } else if (!isVenvPython(interpreter.command)) { KitManager::registerKit( [interpreter](Kit *k) { k->setAutoDetected(true); @@ -821,6 +822,7 @@ void PythonSettings::addKitsForInterpreter(const Interpreter &interpreter) k->setUnexpandedDisplayName(interpreter.name); setRelevantAspectsToKit(k); PythonKitAspect::setPython(k, interpreter.id); + k->setSticky(PythonKitAspect::id(), true); }, kitId); } @@ -914,7 +916,7 @@ PythonSettings *PythonSettings::instance() void PythonSettings::createVirtualEnvironmentInteractive( const FilePath &startDirectory, const Interpreter &defaultInterpreter, - const std::function)> &callback) + const std::function &callback) { QDialog dialog; dialog.setModal(true); @@ -954,26 +956,37 @@ void PythonSettings::createVirtualEnvironmentInteractive( interpreters->currentData().toString()); auto venvDir = pathChooser->filePath(); - createVirtualEnvironment(venvDir, interpreter, callback); + createVirtualEnvironment(interpreter.command, venvDir, callback); } void PythonSettings::createVirtualEnvironment( + const FilePath &python, const FilePath &directory, - const Interpreter &interpreter, - const std::function)> &callback, - const QString &nameSuffix) + const std::function &callback) { - createVenv(interpreter.command, directory, [directory, callback, nameSuffix](bool success) { - std::optional result; - if (success) { + QTC_ASSERT(python.isExecutableFile(), return); + QTC_ASSERT(!directory.exists() || directory.isDir(), return); + + const CommandLine command(python, QStringList{"-m", "venv", directory.toUserOutput()}); + + auto process = new Process; + auto progress = new Core::ProcessProgress(process); + progress->setDisplayName(Tr::tr("Create Python venv")); + QObject::connect(process, &Process::done, [directory, process, callback](){ + if (process->result() == ProcessResult::FinishedWithSuccess) { FilePath venvPython = directory.osType() == Utils::OsTypeWindows ? directory / "Scripts" : directory / "bin"; venvPython = venvPython.pathAppended("python").withExecutableSuffix(); - if (venvPython.exists()) - result = PythonSettings::addInterpreter(venvPython, false, nameSuffix); + if (venvPython.exists()) { + if (callback) + callback(venvPython); + emit instance()->virtualEnvironmentCreated(venvPython); + } } - callback(result); + process->deleteLater(); }); + process->setCommand(command); + process->start(); } QList PythonSettings::detectPythonVenvs(const FilePath &path) diff --git a/src/plugins/python/pythonsettings.h b/src/plugins/python/pythonsettings.h index 827748ee3b9..99ca4f02b00 100644 --- a/src/plugins/python/pythonsettings.h +++ b/src/plugins/python/pythonsettings.h @@ -35,12 +35,11 @@ public: static void createVirtualEnvironmentInteractive( const Utils::FilePath &startDirectory, const Interpreter &defaultInterpreter, - const std::function)> &callback); + const std::function &callback); static void createVirtualEnvironment( + const Utils::FilePath &interpreter, const Utils::FilePath &directory, - const Interpreter &interpreter, - const std::function)> &callback, - const QString &nameSuffix = {}); + const std::function &callback = {}); static QList detectPythonVenvs(const Utils::FilePath &path); static void addKitsForInterpreter(const Interpreter &interpreter); static void removeKitsForInterpreter(const Interpreter &interpreter); @@ -49,6 +48,7 @@ signals: void interpretersChanged(const QList &interpreters, const QString &defaultId); void pylsConfigurationChanged(const QString &configuration); void pylsEnabledChanged(const bool enabled); + void virtualEnvironmentCreated(const Utils::FilePath &venvPython); public slots: void detectPythonOnDevice(const Utils::FilePaths &searchPaths, diff --git a/src/plugins/python/pythonutils.cpp b/src/plugins/python/pythonutils.cpp index 43d23a256bc..97d118f1229 100644 --- a/src/plugins/python/pythonutils.cpp +++ b/src/plugins/python/pythonutils.cpp @@ -3,6 +3,9 @@ #include "pythonutils.h" +#include "pythonbuildconfiguration.h" +#include "pythonconstants.h" +#include "pythonkitaspect.h" #include "pythonproject.h" #include "pythonsettings.h" #include "pythontr.h" @@ -38,14 +41,12 @@ FilePath detectPython(const FilePath &documentPath) FilePaths dirs = Environment::systemEnvironment().path(); - if (project) { - if (auto target = project->activeTarget()) { - if (auto runConfig = target->activeRunConfiguration()) { - if (auto interpreter = runConfig->aspect()) - return interpreter->currentInterpreter().command; - if (auto environmentAspect = runConfig->aspect()) - dirs = environmentAspect->environment().path(); - } + if (project && project->mimeType() == Constants::C_PY_PROJECT_MIME_TYPE) { + if (const Target *target = project->activeTarget()) { + if (auto bc = qobject_cast(target->activeBuildConfiguration())) + return bc->python(); + if (const std::optional python = PythonKitAspect::python(target->kit())) + return python->command; } } @@ -186,4 +187,9 @@ void createVenv(const Utils::FilePath &python, process->start(); } +bool isVenvPython(const Utils::FilePath &python) +{ + return python.parentDir().parentDir().contains("pyvenv.cfg"); +} + } // Python::Internal diff --git a/src/plugins/python/pythonutils.h b/src/plugins/python/pythonutils.h index f3e685b4ae0..69fa7969f67 100644 --- a/src/plugins/python/pythonutils.h +++ b/src/plugins/python/pythonutils.h @@ -20,4 +20,6 @@ void createVenv(const Utils::FilePath &python, const Utils::FilePath &venvPath, const std::function &callback); +bool isVenvPython(const Utils::FilePath &python); + } // Python::Internal diff --git a/src/plugins/python/pythonwizardpage.cpp b/src/plugins/python/pythonwizardpage.cpp index 8b631e2c414..dc4895eb3e0 100644 --- a/src/plugins/python/pythonwizardpage.cpp +++ b/src/plugins/python/pythonwizardpage.cpp @@ -4,6 +4,7 @@ #include "pythonwizardpage.h" #include "pythonconstants.h" +#include "pythonkitaspect.h" #include "pythonsettings.h" #include "pythontr.h" @@ -14,6 +15,7 @@ #include #include +#include #include #include #include @@ -86,11 +88,6 @@ PythonWizardPage::PythonWizardPage(const QList> &pySide const int defaultPyside) { using namespace Layouting; - m_interpreter.setSettingsDialogId(Constants::C_PYTHONOPTIONS_PAGE_ID); - connect(PythonSettings::instance(), - &PythonSettings::interpretersChanged, - this, - &PythonWizardPage::updateInterpreters); m_pySideVersion.setLabelText(Tr::tr("PySide version:")); m_pySideVersion.setDisplayStyle(SelectionAspect::DisplayStyle::ComboBox); @@ -99,49 +96,13 @@ PythonWizardPage::PythonWizardPage(const QList> &pySide if (defaultPyside >= 0) m_pySideVersion.setDefaultValue(defaultPyside); - m_createVenv.setLabelText(Tr::tr("Create new virtual environment")); - - m_venvPath.setLabelText(Tr::tr("Path to virtual environment:")); - m_venvPath.setEnabler(&m_createVenv); - m_venvPath.setExpectedKind(PathChooser::Directory); - - m_stateLabel = new InfoLabel(); - m_stateLabel->setWordWrap(true); - m_stateLabel->setFilled(true); - m_stateLabel->setType(InfoLabel::Error); - connect(&m_venvPath, &FilePathAspect::validChanged, this, &PythonWizardPage::updateStateLabel); - connect(&m_createVenv, &BaseAspect::changed, this, &PythonWizardPage::updateStateLabel); - Form { m_pySideVersion, st, br, - m_interpreter, st, br, - m_createVenv, st, br, - m_venvPath, br, - m_stateLabel, br }.attachTo(this); } -void PythonWizardPage::initializePage() -{ - auto wiz = qobject_cast(wizard()); - QTC_ASSERT(wiz, return); - connect(wiz, &JsonWizard::filesPolished, - this, &PythonWizardPage::setupProject, - Qt::UniqueConnection); - - const FilePath projectDir = FilePath::fromString(wiz->property("ProjectDirectory").toString()); - m_createVenv.setValue(!projectDir.isEmpty()); - if (m_venvPath().isEmpty()) - m_venvPath.setValue(projectDir.isEmpty() ? FilePath{} : projectDir / "venv"); - - updateInterpreters(); - updateStateLabel(); -} - bool PythonWizardPage::validatePage() { - if (m_createVenv() && !m_venvPath.pathChooser()->isValid()) - return false; auto wiz = qobject_cast(wizard()); const QMap data = m_pySideVersion.itemValue().toMap(); for (auto it = data.begin(), end = data.end(); it != end; ++it) @@ -149,70 +110,5 @@ bool PythonWizardPage::validatePage() return true; } -void PythonWizardPage::setupProject(const JsonWizard::GeneratorFiles &files) -{ - for (const JsonWizard::GeneratorFile &f : files) { - if (f.file.attributes() & Core::GeneratedFile::OpenProjectAttribute) { - Interpreter interpreter = m_interpreter.currentInterpreter(); - Project *project = ProjectManager::openProject(Utils::mimeTypeForFile(f.file.filePath()), - f.file.filePath().absoluteFilePath()); - if (m_createVenv()) { - auto openProjectWithInterpreter = [f](const std::optional &interpreter) { - if (!interpreter) - return; - Project *project = ProjectManager::projectWithProjectFilePath(f.file.filePath()); - if (!project) - return; - if (Target *target = project->activeTarget()) { - if (RunConfiguration *rc = target->activeRunConfiguration()) { - if (auto interpreters = rc->aspect()) - interpreters->setCurrentInterpreter(*interpreter); - } - } - }; - PythonSettings::createVirtualEnvironment(m_venvPath(), - interpreter, - openProjectWithInterpreter, - project ? project->displayName() - : QString{}); - } - - if (project) { - project->addTargetForDefaultKit(); - if (Target *target = project->activeTarget()) { - if (RunConfiguration *rc = target->activeRunConfiguration()) { - if (auto interpreters = rc->aspect()) { - interpreters->setCurrentInterpreter(interpreter); - project->saveSettings(); - } - } - } - delete project; - } - } - } -} - -void PythonWizardPage::updateInterpreters() -{ - m_interpreter.setDefaultInterpreter(PythonSettings::defaultInterpreter()); - m_interpreter.updateInterpreters(PythonSettings::interpreters()); -} - -void PythonWizardPage::updateStateLabel() -{ - QTC_ASSERT(m_stateLabel, return); - if (m_createVenv()) { - if (PathChooser *pathChooser = m_venvPath.pathChooser()) { - if (!pathChooser->isValid()) { - m_stateLabel->show(); - m_stateLabel->setText(pathChooser->errorMessage()); - return; - } - } - } - m_stateLabel->hide(); -} - } // namespace Python::Internal diff --git a/src/plugins/python/pythonwizardpage.h b/src/plugins/python/pythonwizardpage.h index 9691e767524..d68ea4b8544 100644 --- a/src/plugins/python/pythonwizardpage.h +++ b/src/plugins/python/pythonwizardpage.h @@ -27,19 +27,10 @@ class PythonWizardPage : public Utils::WizardPage { public: PythonWizardPage(const QList> &pySideAndData, const int defaultPyside); - void initializePage() override; bool validatePage() override; private: - void setupProject(const ProjectExplorer::JsonWizard::GeneratorFiles &files); - void updateInterpreters(); - void updateStateLabel(); - - ProjectExplorer::InterpreterAspect m_interpreter; Utils::SelectionAspect m_pySideVersion; - Utils::BoolAspect m_createVenv; - Utils::FilePathAspect m_venvPath; - Utils::InfoLabel *m_stateLabel = nullptr; }; } // namespace Python::Internal From a35deb15323bc60a921e2787590670272baa5960 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 24 Nov 2023 09:26:31 +0100 Subject: [PATCH 0391/1546] Use sidebar buttons for hiding/showing dock areas So far, if a mode includes navigation widget placeholders, these are used for the sidebar toggle buttons, otherwise the buttons are disabled. Now, if a mode does not include navigation widget placeholders, but the mode has a FancyMainWindow attached, use the buttons to hide or show the corresponding dock widget area (left or right). Since QMainWindow does not really support "hiding a dock widget area", the FancyMainWindow needs to track that state manually, by tracking the dock widgets that were visible before "hiding the dock widget area". Also, if a dock widget is dragged into a "hidden" area, or a widget is made visible or "unfloated" into that area, show the other widgets in the area again as well, "unhiding" the area. Since the mode widgets that have a mainwindow somewhere usually wrap that into a splitter for the output panes, and the Design mode is actually a stack widget, IMode needs another method that returns the appropriate FancyMainWindow if available. The patch implements this for Widget Designer. Change-Id: I03531f4d5130c846ff5d65831b1c9be210e1c561 Reviewed-by: Christian Stenger Reviewed-by: Qt CI Bot --- src/libs/utils/fancymainwindow.cpp | 119 ++++++++++++++++---- src/libs/utils/fancymainwindow.h | 5 + src/plugins/coreplugin/designmode.cpp | 9 ++ src/plugins/coreplugin/designmode.h | 2 + src/plugins/coreplugin/icore.cpp | 3 +- src/plugins/coreplugin/imode.cpp | 9 ++ src/plugins/coreplugin/imode.h | 6 + src/plugins/coreplugin/navigationwidget.cpp | 110 ++++++++++++++---- src/plugins/coreplugin/navigationwidget.h | 8 +- src/plugins/designer/formeditor.cpp | 6 + 10 files changed, 230 insertions(+), 47 deletions(-) diff --git a/src/libs/utils/fancymainwindow.cpp b/src/libs/utils/fancymainwindow.cpp index 1c241b432e6..c3f79374cba 100644 --- a/src/libs/utils/fancymainwindow.cpp +++ b/src/libs/utils/fancymainwindow.cpp @@ -25,6 +25,7 @@ static const char ShowCentralWidgetKey[] = "ShowCentralWidget"; static const char StateKey[] = "State"; +static const char HiddenDockAreasKey[] = "HiddenDockAreas"; static const int settingsVersion = 2; static const char dockWidgetActiveState[] = "DockWidgetActiveState"; @@ -37,12 +38,16 @@ struct FancyMainWindowPrivate { FancyMainWindowPrivate(FancyMainWindow *parent); + QVariantHash hiddenDockAreasToHash() const; + void restoreHiddenDockAreasFromHash(const QVariantHash &hash); + FancyMainWindow *q; bool m_handleDockVisibilityChanges; QAction m_showCentralWidget; QAction m_menuSeparator1; QAction m_resetLayoutAction; + QHash> m_hiddenAreas; // Qt::DockWidgetArea -> dock widgets }; class DockWidget : public QDockWidget @@ -217,12 +222,7 @@ public: : QSize(titleMinWidth, titleInactiveHeight); } - QList docksInArea() const - { - return filtered(q->q->dockWidgets(), [this, area = q->q->dockWidgetArea(q)](QDockWidget *w) { - return w->isVisible() && q->q->dockWidgetArea(w) == area; - }); - } + QList docksInArea() const { return q->q->docksInArea(q->q->dockWidgetArea(q)); } bool supportsCollapse() const { @@ -428,11 +428,50 @@ FancyMainWindowPrivate::FancyMainWindowPrivate(FancyMainWindow *parent) }); } +QVariantHash FancyMainWindowPrivate::hiddenDockAreasToHash() const +{ + QHash hash; + for (auto it = m_hiddenAreas.constKeyValueBegin(); it != m_hiddenAreas.constKeyValueEnd(); + ++it) { + hash.insert(QString::number(it->first), + transform(it->second, [](QDockWidget *w) { return w->objectName(); })); + } + return hash; +} + +void FancyMainWindowPrivate::restoreHiddenDockAreasFromHash(const QVariantHash &hash) +{ + m_hiddenAreas.clear(); + const QList docks = q->dockWidgets(); + for (auto it = hash.constKeyValueBegin(); it != hash.constKeyValueEnd(); ++it) { + bool ok; + const int area = it->first.toInt(&ok); + if (!ok + || (area != Qt::LeftDockWidgetArea && area != Qt::TopDockWidgetArea + && area != Qt::RightDockWidgetArea && area != Qt::BottomDockWidgetArea)) { + continue; + } + QList hiddenDocks; + const QStringList names = it->second.toStringList(); + for (const QString &name : names) { + QDockWidget *dock = findOrDefault(docks, [name](QDockWidget *w) { + return w->objectName() == name; + }); + if (dock) + hiddenDocks.append(dock); + } + if (!hiddenDocks.isEmpty()) + m_hiddenAreas.insert(area, hiddenDocks); + } +} + FancyMainWindow::FancyMainWindow(QWidget *parent) : QMainWindow(parent), d(new FancyMainWindowPrivate(this)) { - connect(&d->m_resetLayoutAction, &QAction::triggered, - this, &FancyMainWindow::resetLayout); + connect(&d->m_resetLayoutAction, &QAction::triggered, this, [this] { + d->m_hiddenAreas.clear(); + emit resetLayout(); + }); } FancyMainWindow::~FancyMainWindow() @@ -462,18 +501,18 @@ QDockWidget *FancyMainWindow::addDockForWidget(QWidget *widget, bool immutable) dockWidget->setProperty(dockWidgetActiveState, true); - connect(dockWidget, - &QDockWidget::dockLocationChanged, - this, - &FancyMainWindow::dockWidgetsChanged); - connect(dockWidget, - &QDockWidget::topLevelChanged, - this, - &FancyMainWindow::dockWidgetsChanged); - connect(dockWidget, - &QDockWidget::visibilityChanged, - this, - &FancyMainWindow::dockWidgetsChanged); + const auto handleDockWidgetChanged = [this, dockWidget] { + // If the dock moved to an area that was hidden, unhide the area. + const Qt::DockWidgetArea area = dockWidgetArea(dockWidget); + if (dockWidget->isVisible() && !dockWidget->isFloating() + && d->m_hiddenAreas.contains(area)) { + setDockAreaVisible(area, true); + } + emit dockWidgetsChanged(); + }; + connect(dockWidget, &QDockWidget::dockLocationChanged, this, handleDockWidgetChanged); + connect(dockWidget, &QDockWidget::topLevelChanged, this, handleDockWidgetChanged); + connect(dockWidget, &QDockWidget::visibilityChanged, this, handleDockWidgetChanged); } return dockWidget; @@ -547,6 +586,7 @@ QHash FancyMainWindow::saveSettings() const settings.insert(keyFromString(dockWidget->objectName()), dockWidget->property(dockWidgetActiveState)); } + settings.insert(HiddenDockAreasKey, d->hiddenDockAreasToHash()); return settings; } @@ -562,6 +602,7 @@ void FancyMainWindow::restoreSettings(const QHash &settings) widget->setProperty(dockWidgetActiveState, settings.value(keyFromString(widget->objectName()), false)); } + d->restoreHiddenDockAreasFromHash(settings.value(HiddenDockAreasKey).toHash()); } bool FancyMainWindow::restoreFancyState(const QByteArray &state, int version) @@ -592,6 +633,13 @@ const QList FancyMainWindow::dockWidgets() const return result; } +QList FancyMainWindow::docksInArea(Qt::DockWidgetArea area) const +{ + return filtered(dockWidgets(), [this, area](QDockWidget *w) { + return w->isVisible() && !w->isFloating() && dockWidgetArea(w) == area; + }); +} + bool FancyMainWindow::isCentralWidgetShown() const { return d->m_showCentralWidget.isChecked(); @@ -602,6 +650,37 @@ void FancyMainWindow::showCentralWidget(bool on) d->m_showCentralWidget.setChecked(on); } +void FancyMainWindow::setDockAreaVisible(Qt::DockWidgetArea area, bool visible) +{ + if (visible) { + const QList docks = d->m_hiddenAreas.value(area); + for (QDockWidget *w : docks) + w->setVisible(true); + d->m_hiddenAreas.remove(area); + } else { + const QList docks = docksInArea(area); + if (!docks.isEmpty()) { + d->m_hiddenAreas.insert(area, docks); + for (QDockWidget *w : docks) + w->setVisible(false); + } + } +} + +bool FancyMainWindow::isDockAreaVisible(Qt::DockWidgetArea area) const +{ + if (d->m_hiddenAreas.contains(area)) + return false; + return !docksInArea(area).isEmpty(); +} + +bool FancyMainWindow::isDockAreaAvailable(Qt::DockWidgetArea area) const +{ + if (d->m_hiddenAreas.contains(area)) + return true; + return !docksInArea(area).isEmpty(); +} + void FancyMainWindow::addDockActionsToMenu(QMenu *menu) { QList actions; diff --git a/src/libs/utils/fancymainwindow.h b/src/libs/utils/fancymainwindow.h index df9f2c1281e..3762b7b6e5e 100644 --- a/src/libs/utils/fancymainwindow.h +++ b/src/libs/utils/fancymainwindow.h @@ -26,6 +26,7 @@ public: * which will then be used as key for QSettings. */ QDockWidget *addDockForWidget(QWidget *widget, bool immutable = false); const QList dockWidgets() const; + QList docksInArea(Qt::DockWidgetArea area) const; void setTrackingEnabled(bool enabled); @@ -44,6 +45,10 @@ public: bool isCentralWidgetShown() const; void showCentralWidget(bool on); + void setDockAreaVisible(Qt::DockWidgetArea area, bool visible); + bool isDockAreaVisible(Qt::DockWidgetArea area) const; + bool isDockAreaAvailable(Qt::DockWidgetArea area) const; + signals: // Emitted by resetLayoutAction(). Connect to a slot // restoring the default layout. diff --git a/src/plugins/coreplugin/designmode.cpp b/src/plugins/coreplugin/designmode.cpp index 3b5e5fa41f7..728edc25dc0 100644 --- a/src/plugins/coreplugin/designmode.cpp +++ b/src/plugins/coreplugin/designmode.cpp @@ -14,6 +14,10 @@ #include +#include + +#include + #include #include #include @@ -198,6 +202,11 @@ void DesignMode::setActiveContext(const Context &context) d->m_activeContext = context; } +Utils::FancyMainWindow *DesignMode::mainWindow() +{ + return Aggregation::query(d->m_stackWidget->currentWidget()); +} + void DesignMode::createModeIfRequired() { if (d) { diff --git a/src/plugins/coreplugin/designmode.h b/src/plugins/coreplugin/designmode.h index da9a6f70ab6..82b00abb2b6 100644 --- a/src/plugins/coreplugin/designmode.h +++ b/src/plugins/coreplugin/designmode.h @@ -44,6 +44,8 @@ private: void currentEditorChanged(IEditor *editor); void updateContext(Utils::Id newMode, Utils::Id oldMode); void setActiveContext(const Context &context); + + Utils::FancyMainWindow *mainWindow() override; }; } // namespace Core diff --git a/src/plugins/coreplugin/icore.cpp b/src/plugins/coreplugin/icore.cpp index 354ce144e13..ca92b3b9c6c 100644 --- a/src/plugins/coreplugin/icore.cpp +++ b/src/plugins/coreplugin/icore.cpp @@ -1343,8 +1343,7 @@ NavigationWidget *ICorePrivate::navigationWidget(Side side) const void ICorePrivate::setSidebarVisible(bool visible, Side side) { - if (NavigationWidgetPlaceHolder::current(side)) - navigationWidget(side)->setShown(visible); + navigationWidget(side)->setShown(visible); } ICorePrivate::~ICorePrivate() diff --git a/src/plugins/coreplugin/imode.cpp b/src/plugins/coreplugin/imode.cpp index 4cd530280ca..f143459cf6b 100644 --- a/src/plugins/coreplugin/imode.cpp +++ b/src/plugins/coreplugin/imode.cpp @@ -5,6 +5,10 @@ #include "modemanager.h" +#include + +#include + namespace Core { /*! @@ -111,6 +115,11 @@ void IMode::setEnabled(bool enabled) emit enabledStateChanged(m_isEnabled); } +Utils::FancyMainWindow *IMode::mainWindow() +{ + return Aggregation::query(widget()); +} + bool IMode::isEnabled() const { return m_isEnabled; diff --git a/src/plugins/coreplugin/imode.h b/src/plugins/coreplugin/imode.h index 0cdedd9bacf..339d0ccf84a 100644 --- a/src/plugins/coreplugin/imode.h +++ b/src/plugins/coreplugin/imode.h @@ -10,6 +10,10 @@ #include #include +namespace Utils { +class FancyMainWindow; +} + namespace Core { class CORE_EXPORT IMode : public IContext @@ -39,6 +43,8 @@ public: void setId(Utils::Id id) { m_id = id; } void setMenu(QMenu *menu) { m_menu = menu; } + virtual Utils::FancyMainWindow *mainWindow(); + signals: void enabledStateChanged(bool enabled); diff --git a/src/plugins/coreplugin/navigationwidget.cpp b/src/plugins/coreplugin/navigationwidget.cpp index d2b1dafcd51..b6961f8612a 100644 --- a/src/plugins/coreplugin/navigationwidget.cpp +++ b/src/plugins/coreplugin/navigationwidget.cpp @@ -7,16 +7,22 @@ #include "coreplugintr.h" #include "icontext.h" #include "icore.h" +#include "imode.h" #include "inavigationwidgetfactory.h" #include "modemanager.h" #include "navigationsubwidget.h" +#include +#include #include #include +#include + #include #include #include +#include #include #include #include @@ -107,7 +113,7 @@ void NavigationWidgetPlaceHolder::currentModeAboutToChange(Id mode) setCurrent(m_side, nullptr); navigationWidget->setParent(nullptr); navigationWidget->hide(); - navigationWidget->placeHolderChanged(nullptr); + navigationWidget->placeHolderChanged(); } if (m_mode == mode) { @@ -118,7 +124,7 @@ void NavigationWidgetPlaceHolder::currentModeAboutToChange(Id mode) applyStoredSize(); setVisible(navigationWidget->isShown()); - navigationWidget->placeHolderChanged(this); + navigationWidget->placeHolderChanged(); } } @@ -142,6 +148,7 @@ struct NavigationWidgetPrivate QHash m_actionMap; QHash m_commandMap; QStandardItemModel *m_factoryModel; + FancyMainWindow *m_mainWindow = nullptr; bool m_shown; int m_width; @@ -185,6 +192,11 @@ NavigationWidget::NavigationWidget(QAction *toggleSideBarAction, Side side) : NavigationWidgetPrivate::s_instanceLeft = this; else NavigationWidgetPrivate::s_instanceRight = this; + + connect(ModeManager::instance(), + &ModeManager::currentModeChanged, + this, + &NavigationWidget::updateMode); } NavigationWidget::~NavigationWidget() @@ -243,7 +255,7 @@ void NavigationWidget::setFactories(const QList &fac d->m_factoryModel->appendRow(newRow); } d->m_factoryModel->sort(0); - updateToggleText(); + updateToggleAction(); } Key NavigationWidget::settingsGroup() const @@ -261,23 +273,41 @@ QAbstractItemModel *NavigationWidget::factoryModel() const return d->m_factoryModel; } -void NavigationWidget::updateToggleText() +void NavigationWidget::updateMode() { - bool haveData = d->m_factoryModel->rowCount(); - d->m_toggleSideBarAction->setVisible(haveData); - d->m_toggleSideBarAction->setEnabled(haveData && NavigationWidgetPlaceHolder::current(d->m_side)); + IMode *currentMode = ModeManager::currentMode(); + FancyMainWindow *mainWindow = currentMode ? currentMode->mainWindow() : nullptr; + if (d->m_mainWindow == mainWindow) + return; + if (d->m_mainWindow) + disconnect(d->m_mainWindow, nullptr, this, nullptr); + d->m_mainWindow = mainWindow; + if (d->m_mainWindow) + connect(d->m_mainWindow, + &FancyMainWindow::dockWidgetsChanged, + this, + &NavigationWidget::updateToggleAction); + updateToggleAction(); +} - const char *trToolTip = d->m_side == Side::Left - ? (isShown() ? Constants::TR_HIDE_LEFT_SIDEBAR : Constants::TR_SHOW_LEFT_SIDEBAR) - : (isShown() ? Constants::TR_HIDE_RIGHT_SIDEBAR : Constants::TR_SHOW_RIGHT_SIDEBAR); +void NavigationWidget::updateToggleAction() +{ + d->m_toggleSideBarAction->setVisible(toggleActionVisible()); + d->m_toggleSideBarAction->setEnabled(toggleActionEnabled()); + d->m_toggleSideBarAction->setChecked(toggleActionChecked()); + const char *trToolTip = d->m_side == Side::Left ? (d->m_toggleSideBarAction->isChecked() + ? Constants::TR_HIDE_LEFT_SIDEBAR + : Constants::TR_SHOW_LEFT_SIDEBAR) + : (d->m_toggleSideBarAction->isChecked() + ? Constants::TR_HIDE_RIGHT_SIDEBAR + : Constants::TR_SHOW_RIGHT_SIDEBAR); d->m_toggleSideBarAction->setToolTip(Tr::tr(trToolTip)); } -void NavigationWidget::placeHolderChanged(NavigationWidgetPlaceHolder *holder) +void NavigationWidget::placeHolderChanged() { - d->m_toggleSideBarAction->setChecked(holder && isShown()); - updateToggleText(); + updateToggleAction(); } void NavigationWidget::resizeEvent(QResizeEvent *re) @@ -376,6 +406,37 @@ void NavigationWidget::closeSubWidget(Internal::NavigationSubWidget *subWidget) } } +bool NavigationWidget::toggleActionVisible() const +{ + const bool haveData = d->m_factoryModel->rowCount(); + return haveData || d->m_mainWindow; +} + +static Qt::DockWidgetArea dockAreaForSide(Side side) +{ + return side == Side::Left ? Qt::LeftDockWidgetArea : Qt::RightDockWidgetArea; +} + +bool NavigationWidget::toggleActionEnabled() const +{ + const bool haveData = d->m_factoryModel->rowCount(); + if (haveData && NavigationWidgetPlaceHolder::current(d->m_side)) + return true; + if (!d->m_mainWindow) + return false; + return d->m_mainWindow->isDockAreaAvailable(dockAreaForSide(d->m_side)); +} + +bool NavigationWidget::toggleActionChecked() const +{ + const bool haveData = d->m_factoryModel->rowCount(); + if (haveData && NavigationWidgetPlaceHolder::current(d->m_side)) + return d->m_shown; + if (!d->m_mainWindow) + return false; + return d->m_mainWindow->isDockAreaVisible(dockAreaForSide(d->m_side)); +} + static QString defaultFirstView(Side side) { return side == Side::Left ? QString("Projects") : QString("Outline"); @@ -498,19 +559,22 @@ void NavigationWidget::closeSubWidgets() void NavigationWidget::setShown(bool b) { - if (d->m_shown == b) - return; - bool haveData = d->m_factoryModel->rowCount(); - d->m_shown = b; NavigationWidgetPlaceHolder *current = NavigationWidgetPlaceHolder::current(d->m_side); - if (current) { - bool visible = d->m_shown && haveData; - current->setVisible(visible); - d->m_toggleSideBarAction->setChecked(visible); + if (!current && d->m_mainWindow) { + // mode without placeholder but with main window + d->m_mainWindow->setDockAreaVisible(dockAreaForSide(d->m_side), b); } else { - d->m_toggleSideBarAction->setChecked(false); + // mode with navigation widget placeholder or e.g. during startup/settings restore + if (d->m_shown == b) + return; + const bool haveData = d->m_factoryModel->rowCount(); + d->m_shown = b; + if (current) { + const bool visible = d->m_shown && haveData; + current->setVisible(visible); + } } - updateToggleText(); + updateToggleAction(); } bool NavigationWidget::isShown() const diff --git a/src/plugins/coreplugin/navigationwidget.h b/src/plugins/coreplugin/navigationwidget.h index 40ea1a5fa0c..c043456b6ae 100644 --- a/src/plugins/coreplugin/navigationwidget.h +++ b/src/plugins/coreplugin/navigationwidget.h @@ -86,7 +86,7 @@ public: int storedWidth(); // Called from the place holders - void placeHolderChanged(NavigationWidgetPlaceHolder *holder); + void placeHolderChanged(); QHash commandMap() const; QAbstractItemModel *factoryModel() const; @@ -96,7 +96,11 @@ protected: private: void closeSubWidget(Internal::NavigationSubWidget *subWidget); - void updateToggleText(); + bool toggleActionVisible() const; + bool toggleActionEnabled() const; + bool toggleActionChecked() const; + void updateMode(); + void updateToggleAction(); Internal::NavigationSubWidget *insertSubItem(int position, int factoryIndex, bool updateActivationsMap = true); diff --git a/src/plugins/designer/formeditor.cpp b/src/plugins/designer/formeditor.cpp index 205c6120a82..57075e7ecc2 100644 --- a/src/plugins/designer/formeditor.cpp +++ b/src/plugins/designer/formeditor.cpp @@ -33,6 +33,8 @@ #include #include +#include + #include #include #include @@ -405,6 +407,10 @@ void FormEditorData::fullInit() m_modeWidget = new QWidget; m_modeWidget->setObjectName("DesignerModeWidget"); + // make the editor widget (the dockable widget) accessible via the mode widget + auto agg = new Aggregation::Aggregate; + agg->add(m_modeWidget); + agg->add(m_editorWidget); auto layout = new QVBoxLayout(m_modeWidget); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); From 48a77b5b09f9dcc8bb62f6f3df5d1c824ffbf10f Mon Sep 17 00:00:00 2001 From: David Schulz Date: Tue, 28 Nov 2023 15:36:43 +0100 Subject: [PATCH 0392/1546] Revert "Aggregation: Fix crash when components are in parent-child relationship" This reverts commit 12428bf1d67bd282c5276383c91d968451b44036 because it triggers a qassert in QObject::setParent when the object is a widget. Change-Id: Ib9b76192f548cd3201fcb78a19ea88ccb5782ba2 Reviewed-by: Eike Ziller --- src/libs/aggregation/aggregate.cpp | 3 --- tests/auto/aggregation/tst_aggregate.cpp | 18 ------------------ 2 files changed, 21 deletions(-) diff --git a/src/libs/aggregation/aggregate.cpp b/src/libs/aggregation/aggregate.cpp index 11d13907f33..7be6437ae2f 100644 --- a/src/libs/aggregation/aggregate.cpp +++ b/src/libs/aggregation/aggregate.cpp @@ -193,9 +193,6 @@ void Aggregate::deleteSelf(QObject *obj) QWriteLocker locker(&lock()); aggregateMap().remove(obj); m_components.removeAll(obj); - // Avoid issues if obj was child of another component of the aggregate. - // The parent is deleted in ~Aggregate and might still have a reference on obj - obj->setParent({}); } delete this; } diff --git a/tests/auto/aggregation/tst_aggregate.cpp b/tests/auto/aggregation/tst_aggregate.cpp index fe865be59e7..eef9a32400c 100644 --- a/tests/auto/aggregation/tst_aggregate.cpp +++ b/tests/auto/aggregation/tst_aggregate.cpp @@ -78,24 +78,6 @@ void tst_Aggregate::deleteAggregation() component1 = new Interface1; delete component1; QVERIFY(component1 == 0); - - // do not crash if components are in a child/parent relationship - // parent deleted first - aggregation = new Aggregation::Aggregate; - component1 = new Interface1; - component2 = new Interface2; - component2->setParent(component1); - aggregation->add(component1); - aggregation->add(component2); - delete component1; - // child deleted first - aggregation = new Aggregation::Aggregate; - component1 = new Interface1; - component2 = new Interface2; - component2->setParent(component1); - aggregation->add(component1); - aggregation->add(component2); - delete component2; } void tst_Aggregate::queryAggregation() From 78a4dbd2afc3ad34b9da29514393a8b2ecc1ffb9 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 22 Nov 2023 12:48:30 +0100 Subject: [PATCH 0393/1546] ProjectExplorer: only show relevant Aspects in tooltip Change-Id: I7dd1aafe980724c6a950533bf0055f37c47e68fe Reviewed-by: Christian Kandeler --- src/plugins/projectexplorer/kit.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/projectexplorer/kit.cpp b/src/plugins/projectexplorer/kit.cpp index 5478860979d..7922b3f3a65 100644 --- a/src/plugins/projectexplorer/kit.cpp +++ b/src/plugins/projectexplorer/kit.cpp @@ -586,6 +586,8 @@ QString Kit::toHtml(const Tasks &additional, const QString &extraText) const str << "
"; for (KitAspectFactory *factory : KitManager::kitAspectFactories()) { + if (!isAspectRelevant(factory->id())) + continue; const KitAspectFactory::ItemList list = factory->toUserOutput(this); for (const KitAspectFactory::Item &j : list) { QString contents = j.second; From a149c52e9993cfbad3cf41e4850dbe88867767fb Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Thu, 23 Nov 2023 13:19:48 +0100 Subject: [PATCH 0394/1546] SquishTests: Start expecting Python kits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Python kits will be new in QC13. Do not let the squish tests fail in case it stumbles over one. Change-Id: Ic0af56f49321f6d5800d11398d2e73b21c25e51a Reviewed-by: Robert Löhning --- tests/system/shared/qtcreator.py | 4 ++++ tests/system/shared/utils.py | 7 +++++-- .../system/suite_general/tst_default_settings/test.py | 3 +++ tests/system/suite_general/tst_remove_kits/test.py | 10 ++++++---- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/tests/system/shared/qtcreator.py b/tests/system/shared/qtcreator.py index bb52497774b..e97c0b025ff 100644 --- a/tests/system/shared/qtcreator.py +++ b/tests/system/shared/qtcreator.py @@ -24,6 +24,10 @@ tmpSettingsDir = '' testSettings.logScreenshotOnFail = True testSettings.logScreenshotOnError = True +# internally used +__PYKIT__ = "__SQUISH_MARKER_PYKIT__" +# end of internally used + source("../../shared/classes.py") source("../../shared/utils.py") source("../../shared/fs_utils.py") diff --git a/tests/system/shared/utils.py b/tests/system/shared/utils.py index 77b493b32a0..bd827d5351f 100644 --- a/tests/system/shared/utils.py +++ b/tests/system/shared/utils.py @@ -334,7 +334,10 @@ def __checkParentAccess__(filePath): def getConfiguredKits(): def __setQtVersionForKit__(kit, kitName, kitsQtVersionName): mouseClick(waitForObjectItem(":BuildAndRun_QTreeView", kit)) - qtVersionStr = str(waitForObjectExists(":Kits_QtVersion_QComboBox").currentText) + if "Python" in kitName: + qtVersionStr = __PYKIT__ + else: + qtVersionStr = str(waitForObjectExists(":Kits_QtVersion_QComboBox").currentText) invalid = qtVersionStr.endswith(" (invalid)") if invalid: qtVersionStr = qtVersionStr[:-10] @@ -351,7 +354,7 @@ def getConfiguredKits(): for kit, qtVersion in kitsWithQtVersionName.items(): if qtVersion in qtVersionNames: result.append(kit) - else: + elif qtVersion != __PYKIT__: # ignore e.g. Python kits test.fail("Qt version '%s' for kit '%s' can't be found in qtVersionNames." % (qtVersion, kit)) clickButton(waitForObject(":Options.Cancel_QPushButton")) diff --git a/tests/system/suite_general/tst_default_settings/test.py b/tests/system/suite_general/tst_default_settings/test.py index 95391864c24..6a7faeffb2d 100644 --- a/tests/system/suite_general/tst_default_settings/test.py +++ b/tests/system/suite_general/tst_default_settings/test.py @@ -156,6 +156,9 @@ def __qtFunc__(it, foundQt, qmakePath): def __kitFunc__(it, foundQt, foundCompNames): global currentSelectedTreeItem, warningOrError + if 'Python' in it: # skip Python kits + return + qtVersionStr = str(waitForObjectExists(":Kits_QtVersion_QComboBox").currentText) # The following may fail if Creator doesn't find a Qt version in PATH. It will then create one # Qt-less kit for each available toolchain instead of just one default Desktop kit. diff --git a/tests/system/suite_general/tst_remove_kits/test.py b/tests/system/suite_general/tst_remove_kits/test.py index 19041c7e04c..365f4b217f9 100644 --- a/tests/system/suite_general/tst_remove_kits/test.py +++ b/tests/system/suite_general/tst_remove_kits/test.py @@ -7,10 +7,10 @@ def verifyProjectsMode(expectedKits): treeView = waitForObject(":Projects.ProjectNavigationTreeView") bAndRIndex = getQModelIndexStr("text='Build & Run'", ":Projects.ProjectNavigationTreeView") - test.compare(len(dumpItems(treeView.model(), waitForObject(bAndRIndex))), - len(expectedKits), "Verify number of listed kits.") - test.compare(set(dumpItems(treeView.model(), waitForObject(bAndRIndex))), - set(expectedKits), "Verify if expected kits are listed.") + foundKits = dumpItems(treeView.model(), waitForObject(bAndRIndex)) + relevantKits = list(filter(lambda x: 'Python' not in x,foundKits)) # ignore Python kits + test.compare(len(relevantKits), len(expectedKits), "Verify number of listed kits.") + test.compare(set(relevantKits), set(expectedKits), "Verify if expected kits are listed.") hasKits = len(expectedKits) > 0 test.verify(checkIfObjectExists(":scrollArea.Edit build configuration:_QLabel", hasKits), "Verify if build settings are being displayed.") @@ -22,6 +22,8 @@ kitNameTemplate = "Manual.%s" def __removeKit__(_, kitName): global kitNameTemplate + if 'Python' in kitName: # ignore Python kits + return item = kitNameTemplate % kitName.replace(".", "\\.") if kitName == Targets.getStringForTarget(Targets.getDefaultKit()): item += " (default)" From 8d851fab0baf04a3602444eea89f29cc089fb81f Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 28 Nov 2023 15:49:43 +0100 Subject: [PATCH 0395/1546] IMode: Create private class Change-Id: I64bafc4b8f73b78b7c775192c247ed635a367a39 Reviewed-by: Marcus Tillmanns --- src/plugins/coreplugin/imode.cpp | 79 ++++++++++++++++++++++++++++++-- src/plugins/coreplugin/imode.h | 34 +++++++------- 2 files changed, 92 insertions(+), 21 deletions(-) diff --git a/src/plugins/coreplugin/imode.cpp b/src/plugins/coreplugin/imode.cpp index f143459cf6b..af68e12db34 100644 --- a/src/plugins/coreplugin/imode.cpp +++ b/src/plugins/coreplugin/imode.cpp @@ -11,6 +11,21 @@ namespace Core { +namespace Internal { + +class IModePrivate +{ +public: + QString m_displayName; + QIcon m_icon; + QMenu *m_menu = nullptr; + int m_priority = -1; + Utils::Id m_id; + bool m_isEnabled = true; +}; + +} // namespace Internal + /*! \class Core::IMode \inheaderfile coreplugin/imode.h @@ -102,17 +117,66 @@ namespace Core { Registers the mode in \QC. */ -IMode::IMode(QObject *parent) : IContext(parent) +IMode::IMode(QObject *parent) + : IContext(parent) + , m_d(new Internal::IModePrivate) { ModeManager::addMode(this); } +IMode::~IMode() = default; + +QString IMode::displayName() const +{ + return m_d->m_displayName; +} + +QIcon IMode::icon() const +{ + return m_d->m_icon; +} + +int IMode::priority() const +{ + return m_d->m_priority; +} + +Utils::Id IMode::id() const +{ + return m_d->m_id; +} + void IMode::setEnabled(bool enabled) { - if (m_isEnabled == enabled) + if (m_d->m_isEnabled == enabled) return; - m_isEnabled = enabled; - emit enabledStateChanged(m_isEnabled); + m_d->m_isEnabled = enabled; + emit enabledStateChanged(m_d->m_isEnabled); +} + +void IMode::setDisplayName(const QString &displayName) +{ + m_d->m_displayName = displayName; +} + +void IMode::setIcon(const QIcon &icon) +{ + m_d->m_icon = icon; +} + +void IMode::setPriority(int priority) +{ + m_d->m_priority = priority; +} + +void IMode::setId(Utils::Id id) +{ + m_d->m_id = id; +} + +void IMode::setMenu(QMenu *menu) +{ + m_d->m_menu = menu; } Utils::FancyMainWindow *IMode::mainWindow() @@ -122,7 +186,12 @@ Utils::FancyMainWindow *IMode::mainWindow() bool IMode::isEnabled() const { - return m_isEnabled; + return m_d->m_isEnabled; +} + +QMenu *IMode::menu() const +{ + return m_d->m_menu; } } // namespace Core diff --git a/src/plugins/coreplugin/imode.h b/src/plugins/coreplugin/imode.h index 339d0ccf84a..728a128f9c2 100644 --- a/src/plugins/coreplugin/imode.h +++ b/src/plugins/coreplugin/imode.h @@ -10,12 +10,18 @@ #include #include +#include + namespace Utils { class FancyMainWindow; } namespace Core { +namespace Internal { +class IModePrivate; +} + class CORE_EXPORT IMode : public IContext { Q_OBJECT @@ -28,20 +34,21 @@ class CORE_EXPORT IMode : public IContext public: IMode(QObject *parent = nullptr); + ~IMode(); - QString displayName() const { return m_displayName; } - QIcon icon() const { return m_icon; } - int priority() const { return m_priority; } - Utils::Id id() const { return m_id; } + QString displayName() const; + QIcon icon() const; + int priority() const; + Utils::Id id() const; bool isEnabled() const; - QMenu *menu() const { return m_menu; } + QMenu *menu() const; void setEnabled(bool enabled); - void setDisplayName(const QString &displayName) { m_displayName = displayName; } - void setIcon(const QIcon &icon) { m_icon = icon; } - void setPriority(int priority) { m_priority = priority; } - void setId(Utils::Id id) { m_id = id; } - void setMenu(QMenu *menu) { m_menu = menu; } + void setDisplayName(const QString &displayName); + void setIcon(const QIcon &icon); + void setPriority(int priority); + void setId(Utils::Id id); + void setMenu(QMenu *menu); virtual Utils::FancyMainWindow *mainWindow(); @@ -49,12 +56,7 @@ signals: void enabledStateChanged(bool enabled); private: - QString m_displayName; - QIcon m_icon; - QMenu *m_menu = nullptr; - int m_priority = -1; - Utils::Id m_id; - bool m_isEnabled = true; + std::unique_ptr m_d; }; } // namespace Core From 1f34461088946ac710c163c3aa4678360f06062b Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 28 Nov 2023 16:10:37 +0100 Subject: [PATCH 0396/1546] IMode: Make main window an (optional) property Un-virtualize IMode::mainWindow. If the mode widget is a main window directly, that is handled automatically, otherwise provide a setter. It is better to have a central point for setting it, in case that it isn't the mode widget in the first place. Also, using Aggregation::query for this is actually a misuse of Aggregate, which is supposed to combine _independent_ objects, not objects that are in the same hierarchy (which can crash if the child object is deleted first). Change-Id: I35381e0a05645022aac72501492ea6347953cd55 Reviewed-by: Marcus Tillmanns Reviewed-by: --- src/plugins/coreplugin/designmode.cpp | 18 +++++++++--------- src/plugins/coreplugin/designmode.h | 9 ++++++--- src/plugins/coreplugin/imode.cpp | 10 +++++++++- src/plugins/coreplugin/imode.h | 3 ++- src/plugins/designer/formeditor.cpp | 9 ++++----- 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/src/plugins/coreplugin/designmode.cpp b/src/plugins/coreplugin/designmode.cpp index 728edc25dc0..cb5a6129df5 100644 --- a/src/plugins/coreplugin/designmode.cpp +++ b/src/plugins/coreplugin/designmode.cpp @@ -23,14 +23,17 @@ #include #include +using namespace Utils; + namespace Core { struct DesignEditorInfo { - int widgetIndex; + int widgetIndex = -1; QStringList mimeTypes; Context context; - QWidget *widget; + QWidget *widget = nullptr; + FancyMainWindow *mainWindow = nullptr; }; class DesignModePrivate @@ -107,16 +110,17 @@ void DesignMode::setDesignModeIsRequired() */ void DesignMode::registerDesignWidget(QWidget *widget, const QStringList &mimeTypes, - const Context &context) + const Context &context, + Utils::FancyMainWindow *mainWindow) { setDesignModeIsRequired(); int index = d->m_stackWidget->addWidget(widget); - auto info = new DesignEditorInfo; info->mimeTypes = mimeTypes; info->context = context; info->widgetIndex = index; info->widget = widget; + info->mainWindow = mainWindow; d->m_editors.append(info); } @@ -147,6 +151,7 @@ void DesignMode::currentEditorChanged(IEditor *editor) for (const QString &mime : editorInfo->mimeTypes) { if (mime == mimeType) { d->m_stackWidget->setCurrentIndex(editorInfo->widgetIndex); + setMainWindow(editorInfo->mainWindow); setActiveContext(editorInfo->context); mimeEditorAvailable = true; setEnabled(true); @@ -202,11 +207,6 @@ void DesignMode::setActiveContext(const Context &context) d->m_activeContext = context; } -Utils::FancyMainWindow *DesignMode::mainWindow() -{ - return Aggregation::query(d->m_stackWidget->currentWidget()); -} - void DesignMode::createModeIfRequired() { if (d) { diff --git a/src/plugins/coreplugin/designmode.h b/src/plugins/coreplugin/designmode.h index 82b00abb2b6..1f90d08dc5a 100644 --- a/src/plugins/coreplugin/designmode.h +++ b/src/plugins/coreplugin/designmode.h @@ -5,6 +5,10 @@ #include "imode.h" +namespace Utils { +class FancyMainWindow; +} + namespace Core { class IEditor; @@ -26,7 +30,8 @@ public: static void registerDesignWidget(QWidget *widget, const QStringList &mimeTypes, - const Context &context); + const Context &context, + Utils::FancyMainWindow *mainWindow = nullptr); static void unregisterDesignWidget(QWidget *widget); static void createModeIfRequired(); @@ -44,8 +49,6 @@ private: void currentEditorChanged(IEditor *editor); void updateContext(Utils::Id newMode, Utils::Id oldMode); void setActiveContext(const Context &context); - - Utils::FancyMainWindow *mainWindow() override; }; } // namespace Core diff --git a/src/plugins/coreplugin/imode.cpp b/src/plugins/coreplugin/imode.cpp index af68e12db34..81190327c98 100644 --- a/src/plugins/coreplugin/imode.cpp +++ b/src/plugins/coreplugin/imode.cpp @@ -19,6 +19,7 @@ public: QString m_displayName; QIcon m_icon; QMenu *m_menu = nullptr; + Utils::FancyMainWindow *m_mainWindow = nullptr; int m_priority = -1; Utils::Id m_id; bool m_isEnabled = true; @@ -181,7 +182,14 @@ void IMode::setMenu(QMenu *menu) Utils::FancyMainWindow *IMode::mainWindow() { - return Aggregation::query(widget()); + if (m_d->m_mainWindow) + return m_d->m_mainWindow; + return qobject_cast(widget()); +} + +void IMode::setMainWindow(Utils::FancyMainWindow *mw) +{ + m_d->m_mainWindow = mw; } bool IMode::isEnabled() const diff --git a/src/plugins/coreplugin/imode.h b/src/plugins/coreplugin/imode.h index 728a128f9c2..af22b9c5d0b 100644 --- a/src/plugins/coreplugin/imode.h +++ b/src/plugins/coreplugin/imode.h @@ -50,7 +50,8 @@ public: void setId(Utils::Id id); void setMenu(QMenu *menu); - virtual Utils::FancyMainWindow *mainWindow(); + Utils::FancyMainWindow *mainWindow(); + void setMainWindow(Utils::FancyMainWindow *mw); signals: void enabledStateChanged(bool enabled); diff --git a/src/plugins/designer/formeditor.cpp b/src/plugins/designer/formeditor.cpp index 57075e7ecc2..57bb78f5a5a 100644 --- a/src/plugins/designer/formeditor.cpp +++ b/src/plugins/designer/formeditor.cpp @@ -407,10 +407,6 @@ void FormEditorData::fullInit() m_modeWidget = new QWidget; m_modeWidget->setObjectName("DesignerModeWidget"); - // make the editor widget (the dockable widget) accessible via the mode widget - auto agg = new Aggregation::Aggregate; - agg->add(m_modeWidget); - agg->add(m_editorWidget); auto layout = new QVBoxLayout(m_modeWidget); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); @@ -427,7 +423,10 @@ void FormEditorData::fullInit() designerContexts.add(Core::Constants::C_EDITORMANAGER); ICore::addContextObject(new DesignerContext(designerContexts, m_modeWidget, this)); - DesignMode::registerDesignWidget(m_modeWidget, QStringList(Utils::Constants::FORM_MIMETYPE), m_contexts); + DesignMode::registerDesignWidget(m_modeWidget, + QStringList(Utils::Constants::FORM_MIMETYPE), + m_contexts, + m_editorWidget); setupViewActions(); From 711b976294007275dd3b1327b1ddc3f4dce8c2b4 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Wed, 22 Nov 2023 18:05:06 +0100 Subject: [PATCH 0397/1546] CppEditor: Also rename function comments for declarations ... that are not definitions. Amends 0a058bb65717cddb3e01a44f3241c029253a1eea. Change-Id: I4ba19f915d653d05570f8cd244ea50ab40d4b9dd Reviewed-by: Qt CI Bot Reviewed-by: David Schulz --- src/libs/cplusplus/CppDocument.cpp | 8 +++++++- src/plugins/clangcodemodel/test/clangdtests.cpp | 4 +++- .../test/data/local-references/references.cpp | 7 +++++++ 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/libs/cplusplus/CppDocument.cpp b/src/libs/cplusplus/CppDocument.cpp index 6dc59bf1bf1..a45d3669d9c 100644 --- a/src/libs/cplusplus/CppDocument.cpp +++ b/src/libs/cplusplus/CppDocument.cpp @@ -128,7 +128,6 @@ protected: bool visit(UsingNamespaceDirective *) override { return false; } bool visit(UsingDeclaration *) override { return false; } bool visit(NamespaceAlias *) override { return false; } - bool visit(Declaration *) override { return false; } bool visit(Argument *) override { return false; } bool visit(TypenameArgument *) override { return false; } bool visit(BaseClass *) override { return false; } @@ -158,6 +157,13 @@ protected: return true; } + bool visit(Declaration *decl) override + { + if (const auto func = decl->type().type()->asFunctionType()) + return process(func); + return false; + } + // Objective-C bool visit(ObjCBaseClass *) override { return false; } bool visit(ObjCBaseProtocol *) override { return false; } diff --git a/src/plugins/clangcodemodel/test/clangdtests.cpp b/src/plugins/clangcodemodel/test/clangdtests.cpp index 3978a42d1af..1919d5cfdb7 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.cpp +++ b/src/plugins/clangcodemodel/test/clangdtests.cpp @@ -537,8 +537,10 @@ void ClangdTestLocalReferences::test_data() QTest::newRow("overloaded operators arguments from outside") << 171 << 7 << QList{{171, 6, 1}, {172, 6, 1}, {172, 11, 1}, {173, 6, 1}, {173, 9, 1}}; - QTest::newRow("documented function parameter") << 181 << 32 + QTest::newRow("documented function parameter (impl)") << 181 << 32 << QList{{177, 10, 6}, {179, 9, 6}, {181, 31, 6}, {183, 6, 6}, {184, 17, 6}}; + QTest::newRow("documented function parameter (decl)") << 192 << 33 + << QList{{188, 10, 6}, {190, 9, 6}, {192, 32, 6}}; } void ClangdTestLocalReferences::test() diff --git a/src/plugins/clangcodemodel/test/data/local-references/references.cpp b/src/plugins/clangcodemodel/test/data/local-references/references.cpp index 1c8556581d9..693fcb0bafb 100644 --- a/src/plugins/clangcodemodel/test/data/local-references/references.cpp +++ b/src/plugins/clangcodemodel/test/data/local-references/references.cpp @@ -183,3 +183,10 @@ void funcWithParamComments(int param1, int param2) if (param1 != param2) param2 = param1; } + +/* + * @param param1 + * @param param2 + * @note param1 and param2 should be the same. + */ +void funcWithParamComments2(int param1, int param2); From e0a06cda2868e6cb35f00f650499a6ab348e4d77 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 20 Nov 2023 17:07:16 +0100 Subject: [PATCH 0398/1546] CppEditor: Allow tests to run with ClangCodeModel enabled So that in the CI we can simply run: $ qtcreator -test CppEditor -load ClangCodeModel There are some failures left, which we will tackle one by one in follow- up patches. Change-Id: Ic4ebcb82f6439b344ae055889a6a16d56b2e3206 Reviewed-by: Christian Stenger --- .../clangcodemodel/clangdquickfixes.cpp | 4 +- src/plugins/clangcodemodel/clangdquickfixes.h | 4 +- .../clangtools/documentquickfixfactory.cpp | 4 +- .../clangtools/documentquickfixfactory.h | 4 +- .../cppeditor/cppinsertvirtualmethods.cpp | 4 +- .../cppeditor/cppinsertvirtualmethods.h | 3 +- src/plugins/cppeditor/cppquickfix.h | 20 ++- src/plugins/cppeditor/cppquickfix_test.cpp | 7 +- src/plugins/cppeditor/cppquickfixes.cpp | 131 +++++++++--------- src/plugins/cppeditor/cppquickfixes.h | 96 +++++++------ .../followsymbol_switchmethoddecldef_test.cpp | 2 - 11 files changed, 150 insertions(+), 129 deletions(-) diff --git a/src/plugins/clangcodemodel/clangdquickfixes.cpp b/src/plugins/clangcodemodel/clangdquickfixes.cpp index 04911c8b08e..e993ecd909c 100644 --- a/src/plugins/clangcodemodel/clangdquickfixes.cpp +++ b/src/plugins/clangcodemodel/clangdquickfixes.cpp @@ -17,8 +17,8 @@ namespace Internal { ClangdQuickFixFactory::ClangdQuickFixFactory() = default; -void ClangdQuickFixFactory::match(const CppEditor::Internal::CppQuickFixInterface &interface, - QuickFixOperations &result) +void ClangdQuickFixFactory::doMatch(const CppEditor::Internal::CppQuickFixInterface &interface, + QuickFixOperations &result) { const auto client = ClangModelManagerSupport::clientForFile(interface.filePath()); if (!client) diff --git a/src/plugins/clangcodemodel/clangdquickfixes.h b/src/plugins/clangcodemodel/clangdquickfixes.h index dfcb6aa0585..cdd22692667 100644 --- a/src/plugins/clangcodemodel/clangdquickfixes.h +++ b/src/plugins/clangcodemodel/clangdquickfixes.h @@ -15,8 +15,8 @@ class ClangdQuickFixFactory : public CppEditor::CppQuickFixFactory public: ClangdQuickFixFactory(); - void match(const CppEditor::Internal::CppQuickFixInterface &interface, - QuickFixOperations &result) override; + void doMatch(const CppEditor::Internal::CppQuickFixInterface &interface, + QuickFixOperations &result) override; }; class ClangdQuickFixProvider : public LanguageClient::LanguageClientQuickFixProvider diff --git a/src/plugins/clangtools/documentquickfixfactory.cpp b/src/plugins/clangtools/documentquickfixfactory.cpp index 41a570126f1..864f0c9ee20 100644 --- a/src/plugins/clangtools/documentquickfixfactory.cpp +++ b/src/plugins/clangtools/documentquickfixfactory.cpp @@ -65,8 +65,8 @@ DocumentQuickFixFactory::DocumentQuickFixFactory(DocumentQuickFixFactory::Runner : m_runnerCollector(runnerCollector) {} -void DocumentQuickFixFactory::match(const CppEditor::Internal::CppQuickFixInterface &interface, - QuickFixOperations &result) +void DocumentQuickFixFactory::doMatch(const CppEditor::Internal::CppQuickFixInterface &interface, + QuickFixOperations &result) { QTC_ASSERT(m_runnerCollector, return ); if (DocumentClangToolRunner *runner = m_runnerCollector(interface.filePath())) { diff --git a/src/plugins/clangtools/documentquickfixfactory.h b/src/plugins/clangtools/documentquickfixfactory.h index 75556aaa2f7..98f45af46e3 100644 --- a/src/plugins/clangtools/documentquickfixfactory.h +++ b/src/plugins/clangtools/documentquickfixfactory.h @@ -16,8 +16,8 @@ public: using RunnerCollector = std::function; DocumentQuickFixFactory(RunnerCollector runnerCollector); - void match(const CppEditor::Internal::CppQuickFixInterface &interface, - QuickFixOperations &result) override; + void doMatch(const CppEditor::Internal::CppQuickFixInterface &interface, + QuickFixOperations &result) override; private: RunnerCollector m_runnerCollector; diff --git a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp index 754042d168d..fd76b8522a1 100644 --- a/src/plugins/cppeditor/cppinsertvirtualmethods.cpp +++ b/src/plugins/cppeditor/cppinsertvirtualmethods.cpp @@ -1236,8 +1236,8 @@ InsertVirtualMethods::~InsertVirtualMethods() m_dialog->deleteLater(); } -void InsertVirtualMethods::match(const CppQuickFixInterface &interface, - QuickFixOperations &result) +void InsertVirtualMethods::doMatch(const CppQuickFixInterface &interface, + QuickFixOperations &result) { QSharedPointer op(new InsertVirtualMethodsOp(interface, m_dialog)); if (op->isValid()) diff --git a/src/plugins/cppeditor/cppinsertvirtualmethods.h b/src/plugins/cppeditor/cppinsertvirtualmethods.h index 50467c6e975..7116efde1d3 100644 --- a/src/plugins/cppeditor/cppinsertvirtualmethods.h +++ b/src/plugins/cppeditor/cppinsertvirtualmethods.h @@ -16,7 +16,8 @@ class InsertVirtualMethods : public CppQuickFixFactory public: InsertVirtualMethods(InsertVirtualMethodsDialog *dialog = nullptr); ~InsertVirtualMethods() override; - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, + TextEditor::QuickFixOperations &result) override; #ifdef WITH_TESTS static InsertVirtualMethods *createTestFactory(); #endif diff --git a/src/plugins/cppeditor/cppquickfix.h b/src/plugins/cppeditor/cppquickfix.h index be445f2ea99..eab753ad6bd 100644 --- a/src/plugins/cppeditor/cppquickfix.h +++ b/src/plugins/cppeditor/cppquickfix.h @@ -48,14 +48,22 @@ public: using QuickFixOperations = TextEditor::QuickFixOperations; - /*! - Implement this function to match and create the appropriate - CppQuickFixOperation objects. - */ - virtual void match(const Internal::CppQuickFixInterface &interface, - QuickFixOperations &result) = 0; + void match(const Internal::CppQuickFixInterface &interface, QuickFixOperations &result); static const QList &cppQuickFixFactories(); + + bool hasClangdReplacement() const { return m_hasClangdReplacement; } + void setHasClangdReplacement() { m_hasClangdReplacement = true; } + +private: + /*! + Implement this function to doMatch and create the appropriate + CppQuickFixOperation objects. + */ + virtual void doMatch(const Internal::CppQuickFixInterface &interface, + QuickFixOperations &result) = 0; + + bool m_hasClangdReplacement = false; }; } // namespace CppEditor diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index bc563134756..7244636c98c 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -192,6 +192,9 @@ QuickFixOperationTest::QuickFixOperationTest(const QList &testD const QByteArray &clangFormatSettings) : BaseQuickFixTestCase(testDocuments, headerPaths, clangFormatSettings) { + if (factory->hasClangdReplacement() && CppModelManager::isClangCodeModelActive()) + return; + QVERIFY(succeededSoFar()); // Perform operation if there is one @@ -268,7 +271,7 @@ public: AddIncludeForUndefinedIdentifierTestFactory(const QString &include) : m_include(include) {} - void match(const CppQuickFixInterface &cppQuickFixInterface, QuickFixOperations &result) override + void doMatch(const CppQuickFixInterface &cppQuickFixInterface, QuickFixOperations &result) override { result << new AddIncludeForUndefinedIdentifierOp(cppQuickFixInterface, 0, m_include); } @@ -283,7 +286,7 @@ public: AddForwardDeclForUndefinedIdentifierTestFactory(const QString &className, int symbolPos) : m_className(className), m_symbolPos(symbolPos) {} - void match(const CppQuickFixInterface &cppQuickFixInterface, QuickFixOperations &result) override + void doMatch(const CppQuickFixInterface &cppQuickFixInterface, QuickFixOperations &result) override { result << new AddForwardDeclForUndefinedIdentifierOp(cppQuickFixInterface, 0, m_className, m_symbolPos); diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp index 02d5dbb903d..54f48f4b53f 100644 --- a/src/plugins/cppeditor/cppquickfixes.cpp +++ b/src/plugins/cppeditor/cppquickfixes.cpp @@ -101,6 +101,17 @@ CppQuickFixFactory::~CppQuickFixFactory() g_cppQuickFixFactories.removeOne(this); } +void CppQuickFixFactory::match(const Internal::CppQuickFixInterface &interface, + QuickFixOperations &result) +{ + if (m_hasClangdReplacement + && CppModelManager::usesClangd(interface.currentFile()->editor()->textDocument())) { + return; + } + + doMatch(interface, result); +} + const QList &CppQuickFixFactory::cppQuickFixFactories() { return g_cppQuickFixFactories; @@ -431,8 +442,8 @@ private: } // anonymous namespace -void InverseLogicalComparison::match(const CppQuickFixInterface &interface, - QuickFixOperations &result) +void InverseLogicalComparison::doMatch(const CppQuickFixInterface &interface, + QuickFixOperations &result) { CppRefactoringFilePtr file = interface.currentFile(); @@ -517,7 +528,7 @@ private: } // anonymous namespace -void FlipLogicalOperands::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void FlipLogicalOperands::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); if (path.isEmpty()) @@ -605,7 +616,7 @@ public: } // anonymous namespace -void RewriteLogicalAnd::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void RewriteLogicalAnd::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { BinaryExpressionAST *expression = nullptr; const QList &path = interface.path(); @@ -707,8 +718,8 @@ private: } // anonymous namespace -void SplitSimpleDeclaration::match(const CppQuickFixInterface &interface, - QuickFixOperations &result) +void SplitSimpleDeclaration::doMatch(const CppQuickFixInterface &interface, + QuickFixOperations &result) { CoreDeclaratorAST *core_declarator = nullptr; const QList &path = interface.path(); @@ -781,7 +792,7 @@ private: } // anonymous namespace -void AddBracesToIf::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void AddBracesToIf::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); if (path.isEmpty()) @@ -857,8 +868,8 @@ public: } // anonymous namespace -void MoveDeclarationOutOfIf::match(const CppQuickFixInterface &interface, - QuickFixOperations &result) +void MoveDeclarationOutOfIf::doMatch(const CppQuickFixInterface &interface, + QuickFixOperations &result) { const QList &path = interface.path(); using Ptr = QSharedPointer; @@ -932,8 +943,8 @@ public: } // anonymous namespace -void MoveDeclarationOutOfWhile::match(const CppQuickFixInterface &interface, - QuickFixOperations &result) +void MoveDeclarationOutOfWhile::doMatch(const CppQuickFixInterface &interface, + QuickFixOperations &result) { const QList &path = interface.path(); QSharedPointer op(new MoveDeclarationOutOfWhileOp(interface)); @@ -1045,7 +1056,7 @@ private: } // anonymous namespace -void SplitIfStatement::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void SplitIfStatement::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { IfStatementAST *pattern = nullptr; const QList &path = interface.path(); @@ -1287,7 +1298,7 @@ private: } // anonymous namespace -void WrapStringLiteral::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void WrapStringLiteral::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { StringLiteralType type = TypeNone; QByteArray enclosingFunction; @@ -1343,8 +1354,8 @@ void WrapStringLiteral::match(const CppQuickFixInterface &interface, QuickFixOpe } } -void TranslateStringLiteral::match(const CppQuickFixInterface &interface, - QuickFixOperations &result) +void TranslateStringLiteral::doMatch(const CppQuickFixInterface &interface, + QuickFixOperations &result) { // Initialize StringLiteralType type = TypeNone; @@ -1446,8 +1457,8 @@ private: } // anonymous namespace -void ConvertCStringToNSString::match(const CppQuickFixInterface &interface, - QuickFixOperations &result) +void ConvertCStringToNSString::doMatch(const CppQuickFixInterface &interface, + QuickFixOperations &result) { CppRefactoringFilePtr file = interface.currentFile(); @@ -1500,7 +1511,7 @@ private: } // anonymous namespace -void ConvertNumericLiteral::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void ConvertNumericLiteral::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); CppRefactoringFilePtr file = interface.currentFile(); @@ -1734,7 +1745,7 @@ private: } // anonymous namespace -void ConvertToCamelCase::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void ConvertToCamelCase::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); @@ -2034,8 +2045,8 @@ QList matchName(const Name *name, QString *className) } // anonymous namespace -void AddIncludeForUndefinedIdentifier::match(const CppQuickFixInterface &interface, - QuickFixOperations &result) +void AddIncludeForUndefinedIdentifier::doMatch(const CppQuickFixInterface &interface, + QuickFixOperations &result) { const NameAST *nameAst = nameUnderCursor(interface.path()); if (!nameAst || !nameAst->name) @@ -2168,7 +2179,7 @@ private: } // anonymous namespace -void RearrangeParamDeclarationList::match(const CppQuickFixInterface &interface, +void RearrangeParamDeclarationList::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList path = interface.path(); @@ -2290,7 +2301,7 @@ private: } // anonymous namespace -void ReformatPointerDeclaration::match(const CppQuickFixInterface &interface, +void ReformatPointerDeclaration::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); @@ -2457,12 +2468,9 @@ Enum *conditionEnum(const CppQuickFixInterface &interface, SwitchStatementAST *s } // anonymous namespace -void CompleteSwitchCaseStatement::match(const CppQuickFixInterface &interface, - QuickFixOperations &result) +void CompleteSwitchCaseStatement::doMatch(const CppQuickFixInterface &interface, + QuickFixOperations &result) { - if (CppModelManager::usesClangd(interface.currentFile()->editor()->textDocument())) - return; - const QList &path = interface.path(); if (path.isEmpty()) @@ -2577,7 +2585,7 @@ private: } // anonymous namespace -void InsertDeclFromDef::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void InsertDeclFromDef::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); CppRefactoringFilePtr file = interface.currentFile(); @@ -2841,7 +2849,7 @@ private: } // anonymous namespace -void InsertDefFromDecl::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void InsertDefFromDecl::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); @@ -2992,8 +3000,8 @@ private: const bool m_makeConst; }; -void AddDeclarationForUndeclaredIdentifier::match(const CppQuickFixInterface &interface, - QuickFixOperations &result) +void AddDeclarationForUndeclaredIdentifier::doMatch(const CppQuickFixInterface &interface, + QuickFixOperations &result) { // Are we on a name? const QList &path = interface.path(); @@ -3569,7 +3577,7 @@ private: }; -void InsertDefsFromDecls::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void InsertDefsFromDecls::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const auto op = QSharedPointer::create(interface); op->setMode(m_mode); @@ -4503,7 +4511,7 @@ QList getMemberFunctions(const Class *clazz) } // anonymous namespace -void GenerateGetterSetter::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void GenerateGetterSetter::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { ExistingGetterSetterData existing; @@ -4962,8 +4970,8 @@ private: bool m_hasData = false; }; -void GenerateGettersSettersForClass::match(const CppQuickFixInterface &interface, - QuickFixOperations &result) +void GenerateGettersSettersForClass::doMatch(const CppQuickFixInterface &interface, + QuickFixOperations &result) { const auto op = QSharedPointer::create(interface); if (!op->isApplicable()) @@ -5453,7 +5461,7 @@ ExtractFunction::ExtractFunction(FunctionNameGetter functionNameGetter) { } -void ExtractFunction::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void ExtractFunction::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const CppRefactoringFilePtr file = interface.currentFile(); @@ -5861,7 +5869,7 @@ private: } // anonymous namespace -void ExtractLiteralAsParameter::match(const CppQuickFixInterface &interface, +void ExtractLiteralAsParameter::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); @@ -6186,8 +6194,8 @@ private: } // anonymous namespace -void ConvertFromAndToPointer::match(const CppQuickFixInterface &interface, - QuickFixOperations &result) +void ConvertFromAndToPointer::doMatch(const CppQuickFixInterface &interface, + QuickFixOperations &result) { const QList &path = interface.path(); if (path.count() < 2) @@ -6288,7 +6296,7 @@ void extractNames(const CppRefactoringFilePtr &file, } // anonymous namespace -void InsertQtPropertyMembers::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void InsertQtPropertyMembers::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { using Flag = GenerateGetterSetterOp::GenerateFlag; ExistingGetterSetterData existing; @@ -6448,8 +6456,8 @@ private: } // anonymous namespace -void ApplyDeclDefLinkChanges::match(const CppQuickFixInterface &interface, - QuickFixOperations &result) +void ApplyDeclDefLinkChanges::doMatch(const CppQuickFixInterface &interface, + QuickFixOperations &result) { QSharedPointer link = interface.editor()->declDefLink(); if (!link || !link->isMarkerVisible()) @@ -6626,7 +6634,7 @@ private: } // anonymous namespace -void MoveFuncDefOutside::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void MoveFuncDefOutside::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); SimpleDeclarationAST *classAST = nullptr; @@ -6725,7 +6733,7 @@ private: } // anonymous namespace -void MoveAllFuncDefOutside::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void MoveAllFuncDefOutside::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { ClassSpecifierAST * const classAST = astForClassOperations(interface); if (!classAST) @@ -6854,7 +6862,7 @@ private: } // anonymous namespace -void MoveFuncDefToDeclPush::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void MoveFuncDefToDeclPush::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); AST *completeDefAST = nullptr; @@ -6973,8 +6981,8 @@ void MoveFuncDefToDeclPush::match(const CppQuickFixInterface &interface, QuickFi defRange, declRange, MoveFuncDefToDeclOp::Push); } -void MoveFuncDefToDeclPull::match(const CppQuickFixInterface &interface, - QuickFixOperations &result) +void MoveFuncDefToDeclPull::doMatch(const CppQuickFixInterface &interface, + QuickFixOperations &result) { const QList &path = interface.path(); for (auto it = std::rbegin(path); it != std::rend(path); ++it) { @@ -7117,7 +7125,7 @@ private: } // anonymous namespace -void AssignToLocalVariable::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void AssignToLocalVariable::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); AST *outerAST = nullptr; @@ -7337,7 +7345,7 @@ private: } // anonymous namespace -void OptimizeForLoop::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void OptimizeForLoop::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList path = interface.path(); ForStatementAST *forAst = nullptr; @@ -7566,7 +7574,7 @@ private: } // anonymous namespace -void EscapeStringLiteral::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void EscapeStringLiteral::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); if (path.isEmpty()) @@ -7883,7 +7891,7 @@ bool collectConnectArguments(const ExpressionListAST *arguments, } // anonynomous namespace -void ConvertQt4Connect::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void ConvertQt4Connect::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const QList &path = interface.path(); @@ -7923,8 +7931,8 @@ void ConvertQt4Connect::match(const CppQuickFixInterface &interface, QuickFixOpe } } -void ExtraRefactoringOperations::match(const CppQuickFixInterface &interface, - QuickFixOperations &result) +void ExtraRefactoringOperations::doMatch(const CppQuickFixInterface &interface, + QuickFixOperations &result) { const auto processor = CppModelManager::cppEditorDocumentProcessor(interface.filePath()); if (processor) { @@ -8465,11 +8473,8 @@ private: }; } // namespace -void RemoveUsingNamespace::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void RemoveUsingNamespace::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { - if (CppModelManager::usesClangd(interface.currentFile()->editor()->textDocument())) - return; - const QList &path = interface.path(); // We expect something like // [0] TranslationUnitAST @@ -9392,7 +9397,7 @@ private: bool m_test = false; }; } // namespace -void GenerateConstructor::match(const CppQuickFixInterface &interface, QuickFixOperations &result) +void GenerateConstructor::doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) { const auto op = QSharedPointer::create(interface); if (!op->isApplicable()) @@ -9596,8 +9601,8 @@ private: }; } // namespace -void ConvertCommentStyle::match(const CppQuickFixInterface &interface, - TextEditor::QuickFixOperations &result) +void ConvertCommentStyle::doMatch(const CppQuickFixInterface &interface, + TextEditor::QuickFixOperations &result) { // If there's a selection, then it must entirely consist of comment tokens. // If there's no selection, the cursor must be on a comment. @@ -9785,8 +9790,8 @@ private: }; } // namespace -void MoveFunctionComments::match(const CppQuickFixInterface &interface, - TextEditor::QuickFixOperations &result) +void MoveFunctionComments::doMatch(const CppQuickFixInterface &interface, + TextEditor::QuickFixOperations &result) { const QList &astPath = interface.path(); if (astPath.isEmpty()) diff --git a/src/plugins/cppeditor/cppquickfixes.h b/src/plugins/cppeditor/cppquickfixes.h index 4598c2951bd..953cfa5468e 100644 --- a/src/plugins/cppeditor/cppquickfixes.h +++ b/src/plugins/cppeditor/cppquickfixes.h @@ -10,7 +10,7 @@ /// /// Adding New Quick Fixes /// -/// When adding new Quick Fixes, make sure that the match() function is "cheap". +/// When adding new Quick Fixes, make sure that the doMatch() function is "cheap". /// Otherwise, since the match() functions are also called to generate context menu /// entries, the user might experience a delay opening the context menu. /// @@ -25,7 +25,7 @@ void destroyCppQuickFixes(); class ExtraRefactoringOperations : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -36,7 +36,7 @@ public: class AddIncludeForUndefinedIdentifier : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; // Exposed for tests @@ -77,7 +77,7 @@ private: class FlipLogicalOperands: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -91,7 +91,7 @@ public: class InverseLogicalComparison: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -106,7 +106,7 @@ public: class RewriteLogicalAnd: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -123,7 +123,7 @@ public: class ConvertCStringToNSString: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -148,7 +148,7 @@ public: class ConvertNumericLiteral: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -167,7 +167,7 @@ public: class TranslateStringLiteral: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -189,7 +189,7 @@ public: class WrapStringLiteral: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -203,7 +203,7 @@ class ConvertToCamelCase : public CppQuickFixFactory public: ConvertToCamelCase(bool test = false) : CppQuickFixFactory(), m_test(test) {} - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; private: const bool m_test; @@ -222,7 +222,7 @@ private: class MoveDeclarationOutOfIf: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -238,7 +238,7 @@ public: class MoveDeclarationOutOfWhile: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -267,7 +267,7 @@ public: class SplitIfStatement: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -283,7 +283,7 @@ public: class SplitSimpleDeclaration: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -302,7 +302,7 @@ public: class AddBracesToIf: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -314,7 +314,7 @@ public: class RearrangeParamDeclarationList : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -329,7 +329,7 @@ public: class ReformatPointerDeclaration : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -338,7 +338,10 @@ public: class CompleteSwitchCaseStatement: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, QuickFixOperations &result) override; + CompleteSwitchCaseStatement() { setHasClangdReplacement(); } + +private: + void doMatch(const CppQuickFixInterface &interface, QuickFixOperations &result) override; }; /*! @@ -347,7 +350,7 @@ public: class InsertDeclFromDef: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; /*! @@ -356,14 +359,14 @@ public: class InsertDefFromDecl: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; bool m_defPosOutsideClass = false; }; class AddDeclarationForUndeclaredIdentifier : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; #ifdef WITH_TESTS @@ -398,8 +401,8 @@ private: class InsertDefsFromDecls : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, - TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, + TextEditor::QuickFixOperations &result) override; enum class Mode { Off, // Testing: simulates user canceling the dialog @@ -422,7 +425,7 @@ public: using FunctionNameGetter = std::function; ExtractFunction(FunctionNameGetter functionNameGetter = FunctionNameGetter()); - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; private: FunctionNameGetter m_functionNameGetter; // For tests to avoid GUI pop-up. @@ -436,7 +439,7 @@ private: class ExtractLiteralAsParameter : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; /*! @@ -447,7 +450,7 @@ public: class ConvertFromAndToPointer : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; /*! @@ -456,7 +459,7 @@ public: class GenerateGetterSetter : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; /*! @@ -468,8 +471,8 @@ protected: void setTest() { m_test = true; } private: - void match(const CppQuickFixInterface &interface, - TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, + TextEditor::QuickFixOperations &result) override; bool m_test = false; }; @@ -480,7 +483,7 @@ private: class InsertQtPropertyMembers : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; /*! @@ -489,7 +492,7 @@ public: class ConvertQt4Connect : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; /*! @@ -498,7 +501,7 @@ public: class ApplyDeclDefLinkChanges: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; /*! @@ -508,7 +511,7 @@ public: class MoveFuncDefOutside: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; /*! @@ -517,7 +520,7 @@ public: class MoveAllFuncDefOutside: public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; /*! @@ -526,7 +529,7 @@ public: class MoveFuncDefToDeclPush : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; /*! @@ -535,7 +538,7 @@ public: class MoveFuncDefToDeclPull : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; /*! @@ -544,7 +547,7 @@ public: class AssignToLocalVariable : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; /*! @@ -554,7 +557,7 @@ public: class OptimizeForLoop : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; /*! @@ -567,7 +570,7 @@ public: class EscapeStringLiteral : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; /*! @@ -577,7 +580,10 @@ public: class RemoveUsingNamespace : public CppQuickFixFactory { public: - void match(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; + RemoveUsingNamespace() { setHasClangdReplacement(); } + +private: + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; /*! @@ -589,7 +595,7 @@ protected: void setTest() { m_test = true; } private: - void match(const CppQuickFixInterface &interface, + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; bool m_test = false; @@ -599,7 +605,7 @@ private: class ConvertCommentStyle : public CppQuickFixFactory { private: - void match(const CppQuickFixInterface &interface, + void doMatch(const CppQuickFixInterface &interface, TextEditor::QuickFixOperations &result) override; }; @@ -607,8 +613,8 @@ private: class MoveFunctionComments : public CppQuickFixFactory { private: - void match(const CppQuickFixInterface &interface, - TextEditor::QuickFixOperations &result) override; + void doMatch(const CppQuickFixInterface &interface, + TextEditor::QuickFixOperations &result) override; }; } // namespace Internal diff --git a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp index 21664ea1402..0c4d85d8871 100644 --- a/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp +++ b/src/plugins/cppeditor/followsymbol_switchmethoddecldef_test.cpp @@ -369,8 +369,6 @@ F2TestCase::F2TestCase(CppEditorAction action, } if (useClangd) { - QEXPECT_FAIL("infiniteLoopLocalTypedef_QTCREATORBUG-11999", - "clangd bug: Go to definition does not return", Abort); if (expectedVirtualFunctionProposal.size() <= 1) { QVERIFY(CppEditor::Tests::waitForSignalOrTimeout(EditorManager::instance(), &EditorManager::linkOpened, 10000)); From d7ce872f8063a4f4728a4b370051e1188bce763f Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Tue, 28 Nov 2023 16:30:17 +0100 Subject: [PATCH 0399/1546] Fix state of side bar buttons when switching different design widgets When switching between different editors in Design mode (e.g. ui and qml), the side bar buttons must update. So far they reacted on mode switches, but not on changes of the main window while staying in the same mode. Change-Id: I85635f12bb8613e90ec81056d8763431c04fea2e Reviewed-by: Reviewed-by: Marcus Tillmanns Reviewed-by: Christian Stenger --- src/plugins/coreplugin/imode.cpp | 1 + src/plugins/coreplugin/modemanager.cpp | 1 + src/plugins/coreplugin/modemanager.h | 2 ++ src/plugins/coreplugin/navigationwidget.cpp | 2 +- 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/coreplugin/imode.cpp b/src/plugins/coreplugin/imode.cpp index 81190327c98..dce4d4a7574 100644 --- a/src/plugins/coreplugin/imode.cpp +++ b/src/plugins/coreplugin/imode.cpp @@ -190,6 +190,7 @@ Utils::FancyMainWindow *IMode::mainWindow() void IMode::setMainWindow(Utils::FancyMainWindow *mw) { m_d->m_mainWindow = mw; + emit ModeManager::instance()->currentMainWindowChanged(); } bool IMode::isEnabled() const diff --git a/src/plugins/coreplugin/modemanager.cpp b/src/plugins/coreplugin/modemanager.cpp index cebc5f8422d..424ec4b555c 100644 --- a/src/plugins/coreplugin/modemanager.cpp +++ b/src/plugins/coreplugin/modemanager.cpp @@ -322,6 +322,7 @@ void ModeManager::currentTabChanged(int index) oldMode = d->m_modes.at(d->m_oldCurrent); d->m_oldCurrent = index; emit currentModeChanged(mode->id(), oldMode ? oldMode->id() : Id()); + emit currentMainWindowChanged(); } /*! diff --git a/src/plugins/coreplugin/modemanager.h b/src/plugins/coreplugin/modemanager.h index 96b8b252c23..09a33566f06 100644 --- a/src/plugins/coreplugin/modemanager.h +++ b/src/plugins/coreplugin/modemanager.h @@ -57,6 +57,8 @@ signals: // the default argument '=0' is important for connects without the oldMode argument. void currentModeChanged(Utils::Id mode, Utils::Id oldMode = {}); + void currentMainWindowChanged(); + private: explicit ModeManager(Internal::FancyTabWidget *modeStack); ~ModeManager() override; diff --git a/src/plugins/coreplugin/navigationwidget.cpp b/src/plugins/coreplugin/navigationwidget.cpp index b6961f8612a..4fc33544fcd 100644 --- a/src/plugins/coreplugin/navigationwidget.cpp +++ b/src/plugins/coreplugin/navigationwidget.cpp @@ -194,7 +194,7 @@ NavigationWidget::NavigationWidget(QAction *toggleSideBarAction, Side side) : NavigationWidgetPrivate::s_instanceRight = this; connect(ModeManager::instance(), - &ModeManager::currentModeChanged, + &ModeManager::currentMainWindowChanged, this, &NavigationWidget::updateMode); } From 09144e7a7fc2458b6d027b81d7fb724564ce6360 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Wed, 29 Nov 2023 12:06:22 +0100 Subject: [PATCH 0400/1546] Doc: Describe how to get Qt Creator Fixes: QTCREATORBUG-29594 Change-Id: Ic05329223cd32307b8474fc71c622c9f96d9d25b Reviewed-by: Cristian Adam --- .../creator-only/creator-how-to-install.qdoc | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 doc/qtcreator/src/howto/creator-only/creator-how-to-install.qdoc diff --git a/doc/qtcreator/src/howto/creator-only/creator-how-to-install.qdoc b/doc/qtcreator/src/howto/creator-only/creator-how-to-install.qdoc new file mode 100644 index 00000000000..818f0c8ce71 --- /dev/null +++ b/doc/qtcreator/src/howto/creator-only/creator-how-to-install.qdoc @@ -0,0 +1,88 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \page creator-how-to-install.html + \previouspage creator-how-tos.html + + \ingroup creator-how-to-use + + \title Install \QC + + You can install either a \e commercial or \e {open source} version of \QC in + many ways: + + \list + \li As a part of a Qt installation with \l{Get and Install Qt}{\QOI}. + \li As a stand-alone tool. + \endlist + + You can install and run several \QC versions on the same system and use + them in parallel. + + \section1 \QOI + + \QOI has both the latest released version of \QC and a beta version or a + release candidate of the upcoming release, depending on the release cycle. + + \note You need a Qt Account to use \QOI. + + \section1 Standalone \QC + + You can get the open source version of \QC in the following ways: + + \list + \li Use a package manager + \li Download an installation package + \li Build \QC from sources + \endlist + + Start the \QC installer in the usual way for your system and follow its + instructions to install \QC. + + To develop with Qt, you also need a Qt version. You can register Qt versions + in the stand-alone \QC to use them in \l{Kits}{kits}. + + \section2 Use package managers + + On Windows you can use \c chocolatey, and on \macos you can use \c brew. + These package managers install the latest \QC releases available online. + That is, they pick up the 7zip archives and extract them on your system. + + For example, on Windows, enter: + + \badcode + choco install qtcreator + \endcode + + And on \macos, enter: + + \badcode + brew install --cask qt-creator + \endcode + + Linux distributions might have old \QC versions, so you might want to + download and install the latest version. + + \section2 Download installation packages + + You can download \QC installation packages from: + + \list + \li \l{https://download.qt.io/official_releases/qtcreator/} + {official releases} + \li \l{https://download.qt.io/snapshots/qtcreator/} + {snapshots of the current and upcoming release} + \li \l{https://github.com/qt-creator/qt-creator/releases}{GitHub} + \endlist + + \section2 Build from sources + + To test the very latest \QC version, maybe with your own changes, + you can build it from sources. For more information, see + \l{https://github.com/qt-creator/qt-creator/#compiling-qt-creator} + {Compiling \QC} and \l{https://wiki.qt.io/Building_Qt_Creator_from_Git} + {Building Qt Creator from Git}. + + \sa {Register installed Qt versions} +*/ From 7fd20e98d704b75103de1b3f8ebcf101955eaae6 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Mon, 27 Nov 2023 16:38:38 +0100 Subject: [PATCH 0401/1546] Doc: Edit info about state chart editor - Convert paragraphs and lists into tables with icons to allow users to browse easier - Move the info about using the wizard into a how-to topic - Add subtitles - Move the topic to Reference Task-number: QTCREATORBUG-29361 Fixes: QTCREATORBUG-29766 Change-Id: Id9c1aabd8f3a7bfb0659898dd329cedbcbb5f697 Reviewed-by: Eike Ziller --- doc/qtcreator/images/icons/final.png | Bin 0 -> 290 bytes doc/qtcreator/images/icons/history.png | Bin 0 -> 198 bytes doc/qtcreator/images/icons/parallel.png | Bin 0 -> 204 bytes doc/qtcreator/images/icons/state.png | Bin 0 -> 166 bytes doc/qtcreator/images/icons/transition.png | Bin 0 -> 273 bytes .../qtcreator-scxml-editor-state-toolbar.webp | Bin 0 -> 1136 bytes .../images/qtcreator-scxml-editor.png | Bin 37102 -> 0 bytes .../images/qtcreator-scxml-editor.webp | Bin 0 -> 32822 bytes doc/qtcreator/src/editors/creator-coding.qdoc | 10 - .../editors/creator-only/creator-scxml.qdoc | 289 +++++++++++------- doc/qtcreator/src/qtcreator-toc.qdoc | 2 - doc/qtcreator/src/qtcreator.qdoc | 1 - 12 files changed, 179 insertions(+), 123 deletions(-) create mode 100644 doc/qtcreator/images/icons/final.png create mode 100644 doc/qtcreator/images/icons/history.png create mode 100644 doc/qtcreator/images/icons/parallel.png create mode 100644 doc/qtcreator/images/icons/state.png create mode 100644 doc/qtcreator/images/icons/transition.png create mode 100644 doc/qtcreator/images/qtcreator-scxml-editor-state-toolbar.webp delete mode 100644 doc/qtcreator/images/qtcreator-scxml-editor.png create mode 100644 doc/qtcreator/images/qtcreator-scxml-editor.webp diff --git a/doc/qtcreator/images/icons/final.png b/doc/qtcreator/images/icons/final.png new file mode 100644 index 0000000000000000000000000000000000000000..b6adfc546076820e1522ac6cb6c9ef4c88832061 GIT binary patch literal 290 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4i*LmhONKMUokK+y!3Q&4ABVgJ#X#BoG9V; z@TNoA1F1Jm?+)_bxOp=&;^vZy66P?oWg^^xP3B2QxF?#h^|*+bxF!W~D|0ZGsu@o` z%CS@OL(NmmJ%8#2{>W#ai`CFR)q9$i|5TUWRN0lQPw~C7)W5d(wdWBf-^zZYzYoIh zO^?tJ=~B7(M*GY2_qLvOrB$6>Z7WS~gnZJK;;ORB61$vmz44xhz)P#Gv)FF;wI*}R zubOsQVfnJf=AYWEd5tqCT->5AccY{BR^ZF};-i~|7rN+7dvWVimf4GB=i3W+ZJVa8 vs_T8w;Mv@jt9O+xPO$nReX}!5$X@U7Ns-iB!V4J~7#KWV{an^LB{Ts5BhGqS literal 0 HcmV?d00001 diff --git a/doc/qtcreator/images/icons/history.png b/doc/qtcreator/images/icons/history.png new file mode 100644 index 0000000000000000000000000000000000000000..e1636abfb87b3accc092e116b24515099b4082eb GIT binary patch literal 198 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd7G?$phPQVgfdoVYd_r6q7#JEb0N?#9Uljy&T+my%*p)rkg(|1%hy({QAzt3cXj%N`{i3T)579vUuIufapZD%ymZ+P jLH^rKZ!NeP82&|9vj2U`xo0&40|SGntDnm{r-UW|!vae@ literal 0 HcmV?d00001 diff --git a/doc/qtcreator/images/icons/parallel.png b/doc/qtcreator/images/icons/parallel.png new file mode 100644 index 0000000000000000000000000000000000000000..b6760c394827431965c491dc5c1d0d1163b0f761 GIT binary patch literal 204 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd7G?$phPQVgfdoVYd_r6q7#JEb0N?#9UlQUK^DWMpJ#XXoYR)z#HCG&D3dH8nRkcXf63^z=-cG-=kXS*up9+O%oY_U+pb z9XfRQ@ZlpzjvPC7?DXl=XU?3tbm`LN%a?E7ym|Zf?fdudzj*QD{rmT(-%DpPFfcHd z1o;IsI6S+N#=yW3*NvEcEqnFqd>bNmy$SI>Cgx%{j1c`*P0 literal 0 HcmV?d00001 diff --git a/doc/qtcreator/images/qtcreator-scxml-editor-state-toolbar.webp b/doc/qtcreator/images/qtcreator-scxml-editor-state-toolbar.webp new file mode 100644 index 0000000000000000000000000000000000000000..7be3f366c2782c17180e3048ed409f89193e2015 GIT binary patch literal 1136 zcmWIYbaTsKVPFV%bqWXzu<(gtVPMc-@4(8y&u+OX_v)#r=XQVlcqJ?MEpZW2d8qeY zPKDEBl8R-J(x&RKdLJel{;Pj{M%h4a!Pa$6GB>xa%351|&bY*l;fXxMLxb(__0s>H zf4~s3QfXm4Z^-2`Hm=rJX@M?5E9y)gIDG;*9XO_P2y%%Cawsw=x^P@v|HVF_K_D?e z@z4T>i%k>mz6kgq`oFIBU)`-39|x`pUabNv|7CLtv=}u^YVcjcuu^0}qOF!^N1lp^ zlS8+IgZDzFl{_H|j9#iU_`4T7ceH%Z;d$+7&%XBb4nL+T3a$#FZ%^*{DXbO5!eZFO zkfPB2blrk1-bt6vvne}v)zt-f1W7ntVp}_V>Fj2sAW21`QyyBPOLJ6I*&Ghef8!Q4 zA!L;ai$|!#{-1%*+PqBPiyi)U^p#Fbd~D6%f1XnB(|7;p&WO~_Tzl*L`~Lp-`fHvF1bEjB-m1*xNFREY> zu)HbFo4PEx$l^s?@Sjzy_P(1V_PuR2vl=I>>7pM>hjKfkIa^N2Xq_vPdC?YJ{VjA_ z?u=iLcD5Z)a@haA^}vN?&7RVYDsnFKWFm!Lv<2>7RX+WS{QqAM@22pv`-P_q$$gYG z-SRT)_|xp`^0uy3H?EyyV#kc=h``hP@?LD+YgKypUo!8_c)R^22MBa?Aa&*wVDi*V^t(UT?R5W7}Po2km^}FETg& znI5-lp=^@egPhxiS~`<1t=M@4pTH4Q?C%HvICzPC~eVnjo>lL97CO3GMEY`01m*IS_@^#>4 z`+a8ZcU2@_9Ow~Yv-s!oKw(3w zs$0J$%@)jN@l%$);Ue2A+GYPoD(~9_F~f4^fbFVs9I-x`68)Q9rtSSWYt@13v$j); zFXpbRz_go#nSp`f^+#qu1_q|T0X`wFA3l8e|NsA! zCr@6#e*NXkmp_00{P^+n+qZ8oUc7kt@ZqOVpSEq=cJt;<$Fo6~E?v5I?b?Hn7vKE3 zd+qtLef##m`gQx(>r?mNpZE3kefss<%OAIHygYH|?b+M6Z(n(Ogpq-vprGLK=gW^i zUcUS8+?RJJ-u=D*{o|Q;&-dNEd-weL^B-Ow{QrO3vu`&xZQeBD_W!>>uB9-f4=n-|WQ*C($aKV#Ok`OBug`}bh^$|b6*sofw*UVpPMTI5fu<^$6D?1n%QWwtexqkh9a!T^1 zz02<2eIK**`P&!A!ouD@d$y#cv_xA++lnELfgz&n^7j|Zqm3CD+S*#}?d^{B81?q` z-kxA}`~Uy;b07Eb|G53?)kAyd9ceHrFMqdg`_j{G3ER>bEG#Xotoj)ktc~|NE?TrG zC@7F2X2IdZ4NO)O`Yjov85kHCOitd~ck$;9lZFG0CJeW3eTZdKGo;*IhZCiOfgUQlcYmyi&7DO_v_;sgp>qQfW=<8huZ8z_2zH}wJ>+FP04M_}^ z+pc}x{PohiKl74PjdtJqIrs8H%l>}TjuR87B%3iXOuBse)0N7bfB#NfXEJHhx1~oL zRwXiAetD(M%q)J%=Kc5n&YSn~`K5&Vxmzahz5eQCvq56g(zxg?`G)%*%*`u~JKt$m zAI;F;Z!~w&(QChcpLzGLuxHV_PSErw=n_FCV?#>J#Teb|xz(u1l>O(r#~K zt7nj|lg*xyUeGM@?!hdk2^_1Ycg<>j5PmV+QN%S)gtt)3#I|EGQ{tg3r6NZe`{EMb zo#T0ya^tQ^=~gwB#SzWbpI$Cgwz?JA81#za_(n-So`nAQ?*(_inA*5ko5#{<%YMmO zzXb&@9ez-1Bk+NBUv-;9x8Q;N2Cq`z%co!QKP}as&>^naWp`xdhWR#?-=3U&`@Bbe z-Hm6Tcdrf?cYG#rwbUl1lCS>Fxp%u?Yjtr)9%budt~r1BNX&ot-pB85?TKLRdC&Py zX|u0(bguAGDaBc(6M2=cW{KupcDl=TMB}OzBSU@ogDZ!vZu8j4T`@YHwezOafd`4! zo0b}wUH^YB_Mr;TT0P%0c{!6Av{q`H9xrB|Q>i$SIa`r)-8zf6+v-iyo_^aLw!8NC zxw+Qj2Ip-zp52{&eO_Mc8O0Ue!97QnBVr%v{$%^&{Yo!xQ^|{8%E#H7gg5P#wX*Ta z_}Q{yw?L!A&Cr~tf3^NKn|#Uy7E4^yVF=+otzgQ;&Qinp;DztjQ};zJ7Rq1hy<(cW zKeLfPtk^!`h{1`6NyiWS2Z;2s-$oKT%yGC7M^ z@yYxU@hKPH?CH%e~r++2%naDMX?7GOihH0_$8EYKQMCGlkS$lgm z)A5fDLgwKi)0eu+KZ?jTV$Smnw%oQ=^qt;k=CwIyuU}M`-Yo1sxP`NL#V?krv*rpd z`+05o>y+jacX!%FErFz0?@W7qkNZg+D~z$&_0U99 z_g<@aw|$LC-aLbCjJ=1yDYt#hIq7`(#qcx`t)DE?o0LR zw?1YLI>crk9+%j+>p)@Xf+J@{ucT%Me)4|1MyD*~0mrLVcVeF%KecVy*4Ih;p+yhY zW_7a*|G2v5^!?%=QK6@{u9G&1naU9VFv_UZ({}nawlK$4%PikHscL+eYQGb zv*MN1Vs??8UFSBv`}_L(dj0EnIW#mQukW+8{rm6c=JfJ;p_8xd?J*ZUAv9?h)3-U6 ztz`=x#8>b8d;QU8>4*1@?Mt!dXVS~H-zm6ZzP|Yzn_Y>|mn}7^`*p3Z2qjJ_Zisui`NKPa4~T@#_pPa#dY0# ztB=cKVvh^@8H8?Md2xw;bX4oBf>&X)#qt8OF2$&|Ir2oy&cD2|;nU>PA&kM{b_~nb z1x#AKK*?--)7iUsR`1ytD>}dT@%60Ty;mJ3u3q49edDg{`GMEmFJ1OXPJ2}*)%)&C z?wj|YPX>pFrk18Bmfn1;xbEFIWot90K!I-0B6YoqO&cHo5{gRWU)j3mn$Q}(+n2MX zBjszmJ(=wI{+4aIx8g(Nqn3ZcFQ$)!fIGMK51@dg9e7g|o@e-bKFH7q^3pE%@cttkS~~9Gwd5-l?xkd^DqT zSM;*kU#rTie(^mko3ty`Ci7h1KKrokM%iLv;UC3+obs_#(~>jeU4Cj`afs79`QFp7 zHVM3cTxDPA{i<)umh9NRnzh=KR^=tky61H@r#daz%i7Fh#`~*l`DYkxzPU-A?cwp$ zAxqcgUpspthGWW<4}H=ooV`F^ADvt$Aa&CJ`#6h zcc!LZuKgz7q*s@I7#hinUES-ynlaDe_Y5`Dgx@DOuQ&U!tiHH)=HxAhbQD&5>w8!Gh7sQJ{X#ZZ?sGJ@ZWh)sv^Q?HX8Ds-L+_!;gdDo&T9<#v-1ws z#`Y~)S0bjeW0$9d(BbfhFSf7PJs%u=sy@d5xJ#u!KYO_6wKL-%C+1CFkMe_gJy-3D zJ!+=Q(48LJH>dP*$E&W^FOOIL_T^Qnh)8;nAAEG;mEO<(D^{PlzUyT2y1TXV?u<=8 zx+m~|SoZPV-K*sjL_2n!{F0VXesgQyLiWhiC-Y?{wI;hPll=O<@yZtdB}zXhSJ{Lu z<}k9+IsA@$sgcVy(d8$N7KdH`?P3}1XCeC1=f-jVeT!XJteloAx?1;y*5VLz-Xmu9 zt@}TpTqtOmRT}t!)$zgCvuEwUOrJb?vS3lE@$o+{3eWA8!p)1Hym}_^Y5(ClmXofA z7X4E`Hl_5dq~(6EO}mW$@oi3g7xL!e9!=Sze|Eyl-rcBQld6{Avvb#fmgLa#tS#}G z_Sb@iKTcirZoYj>%-#Ctk1J2d{q;QUQ7>nAtdz&@*pbPz((iJn)V%7mab2>)+A#C` z?48Tc#T}eetKIWapJ(z)>#3`){f@1C_rmzdlr`&SOjK*me>HEer{z|^9U4DApEuAP2va6&sVO5tb4aZ;&;nW?&{~CADIXo z{kUXto=JA~iA4QLa?vJAic@xRckL~4+o|1Ejjc5?V1G26@%nq-HDw0#6Wb(_oY8JS-%iGkR;q`z`Ws_38TY{MU$_ukNH%&NO9eb3wzhE zdbRnChSGG63sYAv{_m1hzy76*ctDzYmwcIA#gWQre~$%SPS=fg?SEN6@6rDm9I+mG zi^DB>8Jxb)p33lr-QCcM(M`4u7ixKg_ttKc`?srEFEF7*{QKgrC4CCTv41-3 zT0U1NCntAvJ#6sg46*EeH*Lq=)a&b##oV?VFPHT4J@{f@%VqR-!FgN=eTuWw6%QE{%!7oVyPYLYCCVpoUz!r zY5G?ARV$AwD$Y77xo$;e!u8H~EiNlxX#6@S^0VcM@v*;h%LI09GuZWh;qA6yiM!i` zCmp<#QgPxOTb1-ZyE{DZ!+xKAeB7G#Qu~WK2R8Avw(37Q6Zmhg+rJ=iimzm2r~brf zzO*TGZVKOh9B}vrlj5cc8rc);@^bcwEZ^lU=IO!Jv^y&y&`rE#=GNB{_nV(j>-qi4 z_>iXOf6oi8OXr@Mo*lmE(lUh-!}b^4{|r3dyJgvQ6&{^_LYMusn%6m*Bd>%e9O{lx zsoJ#Lb)hw*oU!fow@iiIU5l#y>>tHnZ&ka>9-CLV*zNo6uM969c^`R}aO~tv<};<5 z+!984OfxDKqQ2Z&Chm7Y<;Y5n5_1N_T|I|o&i5aed-h%;XwHM{tA3rVNt7;sIG4rN zdR@l_)x=f4Z>0DaW?P@BE%AQhG{>YY>Zr{B*T_Scu%gqb{rwep_bD>L4CEG&&)}ggBwJzq{&=z=<3j4q)8}|J-RFIqQz5A2 zZk46K__Owlv7cF|KP#NF_?trS?NtGsZa;er zn@+FI+oWNtoQnA$-=x#y+;uv4 z$ALxG&-dDQ#07Cp2+RAU!j{4E(D0msXjOA*u4*Kb^S`d!PZ%`dLmF7`Sj{O`r3 zEsv#^ENrZAVq2uVeS5>b!)Gq?F7tH0zS33fu2^cg5yMDi9|BanB+^RNBAi;6g(m6bB(u_+k_Zt+KFlSD>AZr)1>)A7d z>dC9Ze_82rZgpJF({gFSV#b3KB`FL~9FKc6DBDCSUuZJnHOOq2Q{0=e=H0_&ch`0G z8ZTc2%}TwvwqkuSm#^=}R4J#sFUqYM#OVzg&z8;J;HJM;TqrT9R*KOt zHNb3gPq0Fpq+<91_SmJ0zq%H`USzV6`^E8vi3R6Fy8nNeE`52Dis-4QKW}bQG%?<3 zG)3p^HHY9+i~1CGU(DR5a@FUuiOR_{zOyGSiI_V{#gr?va5ke>jrfwt#i#$2bqHSi z(rqAJe!gShqZhk0Y+r2pw#0LC^}49F)$3Dly~w)tNXEtdcI3*)RVM`QuIaS0WnCCO zN8BZGTg%0@Ur*)cI&Qzn$|SMh`OkT_l{Ml^UWR>16aUe^Qeo$D&RzNOD_*&V+^gBB zqG!Lq;LYREuaBHVV;{X(CK-E;S!Ye~i@23xtFtA`7k6K5ePzniu}-Hu;6TfZtS${b zv(vwyEAHAkk0Ug)@x`mD%T}$L8z;7iyJbm4*s6!D^X_ZEd{D4ua%@aO<>KxWr3-e~ z__qAfi+uXfeE+>Uwl)8LE>6AL^y6A&U*4*VsWtniN_v@UR{uHEl)a(2AWdrhit?-}s`S)RD$zC-_1bummGeVKt#r|Lq2t0TsH9bfTk#pIH&T$^?k zaW0C!93{5%=caoaOVV4XcZ&b4x~{j)=nO|D%e_e-3r;>XC@zU~ZGIXXdPUd?!B5+p-Xz9_U5!pZdiZ(aj8_jobIZg= zO=ADds|uL4*FvTI*{!Gl z9!O7HB6LtZF%i(dNa0R@9x(}7b;{& zUo2U}>b&B5Npu?Tm9P7(s+MJjYO}rBQhYf#LRvfQ;*sLJEfLoY1k zSNtd2GxayEKVPs|WzcZ`&FOP_lTwq{Y+CWLQ{ZNR(84JfmdN#94=diHIV)_opF{7r zO%d-`Y}~lD%RM=>J6AKbJIUsw!z#15j5SlkR#qg42#Wp}((Vxd)&65|jtrFYZT_$s`^<2y4`G5B_y*ECa z1>9uIXSGbJeD>{+hUNJ?nZ1+3ikIL0VP5mG;l!>(I@iqR_H$c19Z7ssd7=HL_7vk+ z&vqX@VHVi`JDF$dyjbNKLj@7CR+9 zM|M@Va2adT@{POKdq0f%FZej_C~L6wZQlJ4l3V{pn|W@?t=;)U+58jtv7@=+ue7Fa zYzPWiY0B53=FF#}jjFzPH(g0m^4Sp>SaYeS{NS=(m)@EdntQtiC7=0aOEbz>YnKM*^~~Aokvsc$+iKs^{6LZUCii1E1cW=>v6Ja)HT9LYFY5UG zt75ZQfXc%e!lm1nzF_FkHe7Q#R5AQjk~Zr#+ZT;LWpxV;5)VF|Q2&d~Io3XQ!%DrA za}BhYXp|~XJaxF;=a@31>m!f5S3~5z6n+J5QGMbT+w^L-Q^b?4cOGVizS?qH|L=RQ zG$)OFSKl!2+V@1w!#8TLvL<@`=?M5mnj#XZi?w758 zusC@|Tl}59@77$EEY;SM>f4i7v_px1L7r=aDBqP_KhENbySu$78GLTzJ^K9U#bfV| zWZs_oOmvk#$7;LgE$$!h2mTAHXpKBGN3hxN(}H)38@>rd%db1-eBOBWYNjra$e)ro=1Tf*b8SY3F!R|n)~SCo zaEQLEdd8(C>PgNuv3u)sLTiQ2-w6HnH0mbPk@QHuq64C7(#5U2L|fKad|GufaniHL ztnsz~Pc`xL<^B87n$0P>`{lKXXP;b~xZjPlQ8(ia>pkZiY71D_9`d{EcWe5I_Ir`)~Y2?|M{YQ-JW0rDmHV@I&x z^ZRmES~2?HXJwvxRVh(y#~WYK)k-Pn%AM{OPI~z7U0~7wNr4}}sxkdqmMbegcY&UD z>Hl{Qv3{aK;S;Ax)hbM!u6S$KU&*5jcijk0TpqgA%PuVV?edCgVdcVSq#u?Zh+CG& zrX;n>Kzvo6iPW!~Cf`p~m>fQCA9J`a;j!MX-?KDkoT|&axBFA@GCg|(kC%)UoC#0D zr%!M@G5zymePx^PV)KjE=*37B1HJ68RbIcU4tG+O6r6?~*Mu4cbr7i(15*7RcSc z{Y(4d*>aWQC8?W@Thssl{*wB-j=A*qx;O7@pWMAUy|!5O?k$$O4L6Un=f#WY{SJNH zs(z-TN;>?Nny66G(aqZD`B@oUJRhw%EnOcw$?L|2xm=#}H8fsvX{UZj5Vcu%XLDe= zx4i`CzPw1jXHCZ@D4yTP^G)&9w%DB}IV-rsns0uv3)mxmu2Nv4!Qz*%yWSu6(YpCt zJz{;xM>g*K(3g)N9k(es7Uy+6_OyM7>E>{+sX?BfrmvjFqmm=x)!L;M{P5%B3Mm!F ze_=Z7)_p%Tbz#zNfA`tn-o|9TIC<#9oBG)ihyEzeICHi2%FeeR)ec8RRGPjzb#Isd z48}=4tW%m)0=?I*3(9DXT=Q{7{%b2y?-_d~OAnsB_jLBO^L0E-`S$#WGfOpR=&a<< zsM)jzT>1ciya#|B*g z9e91!A(<7?aXE|DZLW^(RMI+gBS5Bw^~mGzyB_MY|Eny&KRJHG?Fh@nxLe-Se`&rd z>X^*6IeV4$bLo;}R~XWttTNy>yA?h|I8dn|ZrP+oYeUb7K3a4;;l0|KhjFK}&LphV z2wr-XH~-cxlfc+*h0px*SIy25;oMx?dQ*3GTI)}@t8F{88g#z}md~5~e3y})))|%a zAMWN%w3R7c*vIp4Q@j16hXQX3{I~DZypo!~H2VIRHM>^m&n|7fsk-pohLcjJ41qg# zZJd&uzv^?$3h#iHtuGGtO!-!HC`Q0$^*05lyP6&|q@T6;K3hHGL39^anE93tuIxF-bh@S7IaJgn~KJ(v?IE{pz`xzMugys?t+zhI!mAP z?$U`bi%mS1-13S4!Q42`&F-G7yN?%7RZDCO+%svH;N+fNA13&QR?F{Xf5jN^;_<6P zX0faCB3DUS+pjd1^1SOIv~fn+^VzD4Rj0YQ$b`>W%X>8V+{wM`mbo8#lX{8MSkGdL zORPb7(Dv1bj`Zx>`&TRCl*-%Kb5~QF*Du(^u3ptX{qXj@)y7iRrOAh{X%^34civZQ z?Ygfn6Ry?HOns&^N7x`T=ywEu^j^p^gOxx4MQxZ&*E za{HdY(B^+{X>nNig-)sAS#fR5>RyYQ7hZ(@a#t#QzkL9e0!CYrhD=0JI+tvc$dEju%1(}P|rwY zrcTY&BTqY8B0ql=y0)kCZ_pu~tKXM@ihg@L?bqELy9v9(w(z|Sc`ujri?4BeNrLm5 zb6a=q*sd(cnISs2^3a=y2cG7e2$lx&9tv!|Y5Th@Z|+OYLc0mOu9>WV_j)!`F#shsVQ%gi^EIKY^T^S>7m?hx2hSJtTWvh@zus{PUY*UyF4oG z+rrK{P5y1L`G4}$^)G#PvvI#Voa4k)y0>vn-Wm~+lJ(kQD+E$+iwj-hmG-{ib^DOg zt49Z<&rEtKxasQJ;@uWu(-$-!dA8d}W%Fgu;+xu5mrFOkIBZi|9L#E*ek0)1is*2M zE2PaoKY{rOW; zub~YffwxORn#Li=0ezhfS;kuf*nhEQfOJi4ff4K5OLTRP$+XXF=nfAAx=U9b*R&U#@ zl=#d;YIE`p@{D-UpuBTo(T7Sv)u-4%o`Jr%yYbo$vC)J9cr%LLnbt`Db^G(>v667A*IA$#|prx=$#Vi|DJg zx#IFIUw!;%tl#&@&ivJ*pQl)USo?m6T=Q;CvA*Go{TZH27H?O1pE}j7c=mk5t}xrA zWh$>0%{1m>KeS=}>j1MGtE<1pe(Bq8yy;UIQ|ZQSVGpM%%+%F7b2YQ{x{AeZeT|6i zf0gx}v?uQJlsl}n;nUeeQt?+mwnYBh{c`iiUD3-@^|k!A?fMwgus9<+Cuz>g?i|;) zM}nd?Sr1)ZtIz3kx8s?;%b}jUqNkNJ_O5-mZ|;;|zaRGV zdfc5Qwew(-%dPX8wLf2Jue;^_Qa$`m`IJj{&l{KCth~at*5I_$qvRbdz3)qvm+ewt z?>{3)WBV?icutvW&Wo=4W8K|$@gzl^XhKzjn z^IH68Rc=&DJZHE(UM1i<_ktDO(=4uw#`%;!{5IWaV)5R)l~;}`^G#T)QGYCTRma7a zUFp6d-z%yQzl+<+&XPKB-{(Wc4|KD4U%SSC@1u;y?)oRf7Q453l-7!uD8F&<+okb^ zZF5Qmt92>kl6S%OHs`-TvbUrty|6bl`E0}L>ccLj{^hfjo3{xx zT>m6{VVm5S)(D#&j}^-nc$6y3=sprQ+4m?#D9z-0?F55r7WdRu(-#;?^;=z z+Vq3-lCGYeGX3;?PV3B~rIvFIxNDmw6>Z!0?t1g^g0^JoYP^p0)CwW?E+;qHCa!B0-ykMa zCS1CcKlOc9;%<*eZVdAb9v^?5l66&euHw~s4tH0EhKC8=e{sw1SL&;*pes-36kN+a zJ#FpIQwx&{!lR>=Htf3aN3d!st7|ONS{>16*Z$wM{(fWGDuagm-%4^{N}alFBw4P| z=NoxK?U31YfzD`ei5sFve@3LMux$@2WSgXWBxixKTZvRwO~WyXJMmINz872;tGu%R z^H5oU_v1%)L#bpQyGP0rrXP3jy=!az`(38L{POSH?!LeGZC}-9z8@cJzwiD&=dpsI z{oO0KFH85n%$)r*JKxuK`k!wL7luJ-QkD5+Q!jU)xTyQ`{FbE=geu2<#(e^nOV+- zm6tGP>d9EGs z?ARrGxyJriOKobNAAWlG=@f$ndZ{&A78bZ2pBf{aHf8F@ z^HtY>QDKQ@w=Tcl=2X{nb??XL`Ky;Cu)dlmQB%wjACkCy;zf(ZJkOX^^<97F6&*Vt zGJ|t@^v+B7t}lK2a;y05w11wpqKiK5?R#~=s!SI=?e zG_L(T#aUl+YX8;iyIQI*diN)-?p(O;_zZ{G0JgN(@eW?G{*wL+^zwpj@4q^D zEcV$a9$TZg)=vI6vfZJ#sq4Vnx^1$EtI(W9J?f({J?JbxpN6>_p9#t*mF7CkW>I zKCDna#P2jq+~DWlJwn^2_xxO;UARaz?b)*3YlWV5$!>^a+4hsM@Hf|SU$>*DL!R+l zKZ?6tC}nH@>Q><0qGR`yqH;F`x9%)rUnAa_`z8FbHk;|Ay(tAudiD0L>+@vKgz0Jr z#V%s__Bw1`6Z;zRrqFOrwxm~&HgvxZ-SJ&|S8i0|GPbK5y*n4khlgvvlH%O_&F{?w zgV)Memq*_T|IqN2DWSBMDR|o9N3WPFL}Ga!PT4qNSEyMbQ$k{VY4p5 zQqEJ;EEgv|ZdW`joYuEfy5ZW(ms_QuFuXezxc%>st3i=6VVhLXeAyplZFBg{s_28v z*SHnrN>85q5u$O;+|W>v`)l783+}#MJ51%1HTD;{UO#fhc2(=0mkTGpcrlN+=*Hv; zi}IqAHl|Fw-sKiMOYkDs=B1p*5m8`s*1X%eFJi_1ZTB7*T+zws`@V9o^S!34OSL}n zs%Gdf$W-Rab3f!K0HR)zc?IF>$1HZU7+XdC`I$F!hAEDo{ zU>CDvY0~0H1_kEdSJ%#UU1@MxvcI5tX`AX~gWqYFlUBW(#O}CZVM5oxW`(G#Sr2cm z_s_9d`t{(N+&Q<>-z>M*T>C6IdHT*>`wrdMXU8vDUSFHE(Sl#^!$$|vG-;JHeC|v8 zL-hM*>^knWaKob&oF&KHC!KteQE?#j@w&MI?Q>dJbsxN&8c;a#)T~{4$&Xg-ewvZ} z`b)>UJfn+N(}V55%-`|)=(TI5>QRv&{CsZRJ^Q=z)h@0XHP+YkPtQF3;q{YGH#~&D zADU48(;ohl_8*zFB<*0pgv6Be-rpU!9_l*8hTYLQZ(_W=^P+cK z!j-!=Q~q7MY;x<}ZQlQU^ZtGN@@~E3UE}WuqF$%JpMQ(}cl_VCp*N}p%jB%){=1>S zs_I3tMbWOSJ#McTzk67_JHF}tkGI($Uh4=iw@$utR5UHA_K;2ghF!Cr65ctu7x0~w zzVq&3#F7Y3WBW%!Ulii{0>9@?&|X+yAF=e+wmN2|y2UHGU+<2$EtfJYDfQ2;=FhhF zmzHlfp0MlE;=H*A?ccA~{)&>_^WgeQ;pNdLuP*Hul(sz_^E4&+`fc&3h|R{5M_TTB z8Ejj*fy;Pqp;gbdi%vSPmeu&0l&Jg;&JMY2{C!1x-PKJA9BWo?O^>?#>d?gBVVTzc z%k95CwB6}`_ua3^cs~Z2((ors^m+=*UU>f~Eef74UwV_Pc;*-1P~S6w;x|PCv$Oxm zIvU@~7HgRlwN>uQ=+VChGGwo-29 zD^qz^%=T`bIpxQ*fVX|pL2o`-KRdYLmD0>V8<%*$k|qWxIVfR zdb#E2k1FA9clKJQZ&`ik>?4zR@%c{M_w!s?`~4%w0Z+da%@)&lS*o7d6ggWr@!t!EBR7sskDF1$wCq^8 zdD4k53#T5n>V@mitG8*0=KWqFE;O7efxyZ z&kG&ujHL%-J2r}||My<`dbh>PYK|*^#jl;eQ~2;nYOb}_%^#OpXVmVCe6=o8QQEMS zbF-4+t2~+4OQp{;TdtbD_CC)QgN28#sCNCkB>uQoPF3p3Rhv%)iJy6!aOJB+KyqchgW7MwSKeK(_F#xKSyDVNw2%X^LQuT&`&wK^Pa z@@l0&+s`f4eXVm^F3ixDE6ub?O|M(Y^;S>3^k>FCxd&l0#Me&f&1jvery4fnV2s<{ zxq8gbv3qaIuTSRLd!J{qG_S=pyM#H*O!d9y&%70WPFW;XFWB|C?b(AoZ$4~k+@*6U zaJqG#?Ybbrb1S}`>D(3^uGwR-Vt3RlmRDLfOgF1qbk^%Eg;ewOpfN^aiC)!P2CuJhBc zl&1FW(u<94J$L9;P()?m+nYKMCe2y&E^6iEW$#u^3zqst8Q=>zdf?ebkj+hQc16SSMJ$9Qpq%ve6{TN$p>XU z3%}2v_|C0)mG$o}?el9@O8MTbUSlMBdZJzYGp^0qCNIufC$jzc-XgH$P|u=wT*3~q zGc&&V9Zw2w?pWD*u!-aAw{5FV^YLkS%H^rStur;4MAK$Ix#{oLTDE>-WNiNNDUW11i#+&#JX*M{=IYgh zj~<29vwVM)JG&(^y!>dF%ckWwUbThmP4b;?Uwo)1D*tBYnT1*GD^C~cY`eVO^n~I% zi{Fb>@=I4v`{Nz`X1(s>cU)eESNA%Z&Aj?F^~}4UaYk<(#7h4z4Pg?XF9oDN%lIh=fs^wChb;#d^!3j>{`>? zp~G7tzoX>kx6SGM1%kd;-HcK8y!+H+tI(?3e~vDVw%f7f`iz^$Z$G=bmHpc{bzGoUYs)EtlA)P}Pe4k<9np^DkD^tlPEvqe}eU*AB5?lDikZ3*B^b!Mpii z{BNX*KC5)O!fMv4_Qy-QYxl{uT$vrMvpH5iMts(=Gq&7c^J;0u<5Op* z-D{~^_Sfd}sk&vl7h}I?o&76wwV`8|!*drMF`oRKPgQ$o-&(9#nsX;Ue#5Sa(989g zW75pIH!t7CDj2sZ#%$5|(wnCx_8!V{yfW8xj_sZqVc&i+#p&O#d3!%puw>${7&Bh} zZ>uiMV!e0FEqmpT88X^u{%ky05V44RiJqo%Y3C%yprX>wB%^a54~cyVZ*1e%{<>9f zwO&^0`t2`w3rk%NXZ47+tEMN#%aBH7&6Rx_IB)78q@%j5#{Nm^$zZr=qn%6Hl{6$@@yuMy&+J?#oIhCznHA~k|;hk+DJjdYi;*ur% zFWtYs)c3_!@!O~1{l;7x@~g_L0k&+i>UH({f4Q8+Q3rwl9BYb+f0}cjjvE z9g{!3yl3nm`{M_1?waO)g-><6zCS+w#k|n(NY!NLlc64_oUepFd-~5fz42+lRFRcM zJ-b3499pawCUTlvAoytKM1#vqq^`s!J9%E|^*t(_{cM5ynK_?6-I}kL@v83oktavL z*Y8@8oAv5a{8dT0o})q_^Dez#A)&o%*93#j^`fbU9?yIIL)|ByI<#VT?gaZXalh4> zSA5UQl&-(C-_NYywZFW-MXhc7nLzRH?-M%~Ik2C39#p$(eeFvbm)IT8Y#nr?Ze6gx zDlcWX&&4cJ{qJVg64lschwA0G)wlhe`ux<+#XDj)=)FqPFI?DV+u|F=W&EM?q z7oCVRc(v=#(F3Y+iDHsR<>VK08VhTelnPcaNk3z&eVK8ex`bC=bl>82W`-{{zS{*R zR4m$_s2up}xKh{V^v;xBx6@{xt~|?0N_SZ3bzAU!fUadFw_ja8m3p+beDa)#( zi{3fBik8gJ@Z7#-`scP3jmk5gX~H+IeO+MkFa7Yk3mLfZ1`3<5IMD1kKfvkB zK^Ma;5qXok1%^_lAMe~eJ!h|Nad~>#x4iW2fA8O%X;0=r_F9H8NInx>{IE3EYGUs$`z3cK@yu9SpVP3;Y2#MzlFX~`K8CE`Wi6~;t@UyB z!9KZ-gY0B=2SQ#r7w$ z^>*8?CH|>HZ?Sjd!WRK?S`Om>H*#K|`zpx9`)j3d_XDx>396H4s;20@yLV$}+BOBw zgGYsHUAvwwWj>r8E5aSwwsXg|72j7Ux=d#|u&VD&Ns2z(nMsu^W6D=OTO<(kde-%C zN8i7YP-j#U46@&$9B9qBbLxq!9C}-$i#8aa`E=j?gwdI!Tiy1?^Q!L>S}r+#OL~#^ zF1<+%FWNjC^iITFk(htQZraWr?^tCg1ng^Cx=VZEw9J|%PCY;EF1o}_|Cl?&_)L;w zmEog(U{}1kxcB+C_U1+1b1toXDzb62&dt)p9qV`xN1Tu~k4yicWn{FiHfT@b#FG=! ziq>}X?&?#>ai}po+*2>P@Wo-BYgc{xcIa<1ef9U0^setY+jO!Y__ml@?ApR#{Oqdt z22tj;5RHqrs|#hn$wsTC=tMDv#h9yPPN{cY;^mUHg*old*LJ0ZXMZObK7IWtYVp1O zDJ9ymtTVK3t%~tl>RvK2Flc$6PwV&6$y}Pd&Rt*KQWtbuYe7<&PIvxID?dlxU+YRP z6dy5G%wZ{MkK4ghFP|oP7i7$Oja{Lkm)KkrxPDL1|9xfCy%jczk-OtI-(D5dy`IOo zqi@}E8RJPygk*DiE5pUQL3dS|}pqGI2@JY0zq*%cRxTyCohFz=f5ux%l~G20oL z8(>p8b}_8l^RdV*p|0|?^i=!1#|{6ze7WF-SL4R24|+=8XCk>~9Ijc*&E9^u_v4Ra zrkgca7aR$H{amd7$3deb&dh0IU3O`Ivy?L6 zE@{7;Gnw_`Q=@g+J@%&gYhsV9SswRU9I?b}yV94*b9s#KMesYyKU)+t$1eM)`}eQm zIt3s-XYiRPVT!a9klbzq=Sd9wpT9cULYM)_uIg@ zQETChXDc>@DZDuM@b8S*Gj|_(d#~Wq>?S>K@3zX2hYsPUBGWsn)^W@@-1n~QU9a?R z@pOfh3HRTbM!uNBGvnxbYaPjFfvqgDCJ{;NN)&}{#M}<-*_O{ff7P+(A8+sdV-qu) z*dUp0WpqaL?dP1W{oQ?Dnx?y+S~_mOt%Uya8gzu)s?z-^xa@D(z`-bOt zPdEG0J+VF{`E|+3^aE>5eXrUsREgA-pCc?Q8p>Ak`}n3`50a99?_Jm(bf9a?r00KF z&z$9s7QeT~v)pb&-l8=T+CHI|rJA#2<&Az;{C4~_t?OH>@2oEwx3`wgWJ2!-x!>-OO+M?q(+w|9N?bR;_rV49lk1{qk}Ve@|u|+ZHYF+&e#ads(UH_Uf~@ta~_j zpTD|hrS6%KDOG0-CjZ{G)1my_F_w8()}OH7^;|<#mxot+mx;+SEnjo*^&iCzu5USa zW$m+fQq@8yN+m3{W5vbTeshIM{Hl?EaO=j=>0FQdkMHW+uXz7mZe^CI_nVlzS;kk^ zt^V_Wi%CVB+wo>q`MdomXL2^LkN>|fl{L<(T;#693!_UukJHx# zRTkg9`#P=inxjO-#^dY0Bq{fJRz`*B|7M!E^cEv?(=V|we`n3ua^{577yrI{t+#EZ z;54qsx;>mFt;Xu=YrFDi)~w50yE-ZBI_pcREdD26FZARdpK!b``KWyN3{K}a`8&hU zsENBQe!=E2ePy`yf+Lsm!c-2garu5Oa&y|GN2{KmKRe4bnLqRG+|oxLlitWrdt3PP z@G~{DydGcYrKPd^Zd_2~=$Eg##&o@P^LMk8>rOv3)!O#0bX`nj@w~jwhrS_731!|U z8y>tUDoQOmEz4Ol_u}Uboih!7$cbO!T^3l1?tR3%A^P6#FNc-O9v8dk7nk03SJR#GtV!>yQKMe*^a@U!9^Kk#?N_(- zzPHT(dsTkZyf)>38gUoDKH6opW9JEj?6>;|)=3h~}rBd?K!+xW@Yx$3hs_#yT z)XJ@#@q6n#5%aaB&gC!nZJ$=R@p;1gAc^izNA#zeeu&gJnQKw>Oqjz)Znv;@@dAQ?_T&lei2kV(?z^*4`0~n zi><{s4!@i}pK;foti`vv)3W!UQ{R>5u+`V@ez%?HB5wB;hnY3*v9tR}t@tx3s7Y~AU-r4MxHO|zQea=lJ8=C$7T_|Mudi~e0mUB_z1f7E!FJOAf~o#K5T z79V(QJpYB!btj`U5!`bUm#upJE@Si6%fVf1t)3roDDjuIV6iILwcz607wdS}z2ozL z5hTwVm=*YC(v9}l=cab8-Tr@qflAQ+taUMecIk1y*cI|Y)ib)_dMS5zM4UTc=3L>! zAMflv`FU?^Po95!q)<#+`}V#G8b@ZRt=D)YVNhLq*E^=<%ZCHeOD^7D9UyJ8^WBw` zaV0gM53HWNImGI^=;c!vuQ*5AUASta-q!N&-QESktvz}6+PeJff}UmmU}T+?bY@Cr z#?se8x-aS+c4uwfk(ax=tkir-d92&@$(qw5je;)NZYh3#?$Ew#Yjrixw|d#|{yHtA zV*LHNK-T(o*5TWiWf$G;*1N8&e|?whu6=o2yUw0HUN(Q{>J1lrpE$)`T)Nq2mB2EF z%RI#z7kMA;s&q6DZi{@kDk@}i3eV1Ky4J^keZO?jz&Gj>MA8J+1q?($hvrCj|)hn!YPN$i##wVkWy#RwiKHNJN^^@-*h zZKh|TSMyGB@46bY)A75~+@rw<&KwD>Zu_~*Rp*uC&Zxcj6u&#%+?f2~WOX;+-NIV2 zGdG-AwO_1RvzEJI-6J_Yx!4PC>-j`?g%_7Z%b&H~CH^ujSgl0z-OOh^pG()=?MMrI zcd_?CZ zOIDu@KG3tjZ0!rT$m13^Pi3d&_jWaYUAg$p+pBL98U7v6-|l4pTxWOmNyg9j_OjN; zPgh8@6V2D?)CvjOSj2hSbyn9coxHA{*Z%H!_vNM4&Q|-sujZ+KJQ%T#`PsK44?^yG zwd-+Keo33bcy~poS)%@;-;bsyCG0gh_3ur@qNm?KiEdgP+2!2Txr#~N@=4RX$zkrC z2Ct$P)LzKqtXO+`ity>cH78ljb>%Ly?)$>|@55j1@MFdLKa5u&&kl1dd8(2m7i*sS zvZ}&k@teu)6?+OUr`D%u?s7GIah~;VYV;|uODk&J>$knQbnUEAt>#cH|TjI77C4A(>Es&=k(H0PNS8)mC_xqhwpg`C4xaMt={~(9C;U|eTib0;{ri|A z8uRmB#xyOj59hGj=k0q(Js7+#eCa^QlbmF1XiMM;0O4MIXTh3$5 z{no4gruxb*q1Y)7+e5T2txG9nxIXoXn3nMJqh0>j_qwGod=Yg0tB%ROJqu=EERCG; z+u(EO^GzX!i%z#Kh}N1>+P9-wmt&XDtw~AFou%y4f9|@r*KNCA=mP10+^d&Mw2Rv$ z|C=4U*8X#8y21jvgOe`kruMi-boIE@t`unSIvP8D#g+Z9CwYbl1U==hJdh)??BR;k z(B9dfn(}x3i$GY#ubU+7nw zrMmcm>f+OuE;W%X7eh~!-R-FO;XM81hqP_6OzYq73OKT?DE9A*a{)WnF)#dhs_Mgy zzvth-Vp?AN#&qAk3-;z`=Ch=KzW*cT>!0$52jK@Q7yb%AHTzc9vKL{ON`0sM^87j+ zyOH;ocE!#e>kcm}xVvfL(lu*BLRwxQdUm^1G)W|QR_n2bn@5D4O3sRu9ZcT;?$>!Y zajj!&4&USZ-aWU!XRv?$>(|%o_8h#ye|7%{-%6+JCHh4N&P@6pSmLbG`npSYK{Q(j zm)~41IVmBY`;WO}i`Gx;`>gz75|43Ih}8AHGZ#!Nzkc`sp3?jN*XB=qyKDBE{)D{? zCtq7PdE4u}O>5i?o=kqQ>-JC84R3Z`jpB9>KdARDQ7q}ch;?f(2dI$8ZWfItyaP_<<8>O^K51LE1E)_5AtjdcIwbe47Z#3>PE|pW2;KF zdtWCV(7BlxXMCo~+D3RoU1jjB@+Eo?EjL~0eQ@le?BuWpy?yK#Rhd_E?Aju~#OSck z&!Y{JqFyDA%MPoAEj2EUc9*-bHvGPfQulUGS;dK=F3A3*yJTJVj7^tMRV1yJKCHGNdU5Cv)t71)N>AE7(M))j zEnjnl{i?hCb8CsH|3~fy2zCoR^!TG)Xs|CL=8Rn3d!6S0?@lb;mkw?$?tv1f`n=-62{r;v2(u=-tt~7WKfp>dmBy-+7FC7MJS;^T;+e z-~C=F-Qz8w{BfaY&;Igj2c9qJPW|w9+oHEcQ}2}?KbAgy`Bj$k>$asjQfE8#xNa^{ zU()rXs6>!!>+5qDbWC@NMA-<6203?F>#aGdv3H$!_1P!dhk4p6cRQ5tWL@!T)@Bd0 zkOGVK6>Q>{+Lj+N`fu=0h!{!NP2iDq4+U;APKcfZezLmV|5cRbhF z^)L4OI^*SKRmHI>lXwgl#CiWVP-gcm$@b_p-G1)E+O6i7{GYuzwLr+}XyD9sRYkcz z+oN7zS?A6C?9aDEHkPAPwOx)`7_-G3a&qlC;$Grfpu>As{wCw+E{`a|64_L@>540i zj=l1kddFd1X>!Pc3(UXMUtC?tVFCXI+}T;-(-5)kU*+vHde!F!%YE1-U9qSAJ?;Cooyw$9Aqv=2G+a zq;*kC|0ZoWUFKlEz)G*@<<;KJ#tTlzSgmN=uB^g8*}YGtOT#xAQ(fGmJ9lu}&ht|GV zna_Qno}K+}uAlGqlwbGfdWL@OnUY+$@A~@tt9KQDaPoaomX?2Sb?|f_lMgReNl(9W zL~U*n|DRuh9wocA-KXD*yyf2Wk=6C$(;KpTo?7Kf?cq6bwNY^(b5 z>XfJNNdt{`%P@tK+x@b_C)U|q*=A9_XLC@AV8p9QoLgOGGS4NNc{b$fo-Uqovc9om zDo?P>g;3MiJPBQ!ytT_7F25hC_TrJBUT|aB$p!uVGYuC>#PT|o%+$U8DAb5&Vprbp zu+pbumz*>oii(w~8)d(IR30AiWx2(vDUn8x=9)IVQ?+KgE42E~alXxxi(agHH9O`- zwvI%sz^w?@S^RCS-gMc=k#{BTW<2fJTd{P>11FA>nLmUZ z!!uX%73Y+i%B?!A^K@%+3Gc+NJa3Cop=FDnO^I8mefntFbdSYXMQ16Wnc%0mx+QM+ zy`8V(W-fRWcKxwN&yi2=+ii~&s=X*miRwA;Q^wZwzO*zt_Rl&~_ZfRP{nD1(|2}HL zms^(k+OaZg*XwAy{aT}!<^N&r#?U&=9VL-pjRc>`ZN9Mf@AF;j4*NU~x!tEX?P|6C z&sV?xyC*M~Typc(w)vd9zBJk|oe|BsW5T3~I$__}R{I8RvyD8hwb5+q1@Xjhr(W%y zUsJl*T556krL0oM`wLzK9X@qM(6E$KZr4%0dq=BzFMaGydE%Gv(LU2Fquana(st48 z_3O&rlS^!WF4(;~)q0Dz#;y#Hmr?6V3@v32$vj)Kh;j0ncL`RJmy2Z69=&`~0P>1b z$>*zI-(~dZ2{z|t|4=sAwMD{1acY8hRKvO?jY-Pe<91x z?%cR`UBbLSQ@RX2pb6fbS@L@|?gOSkaFYM%ttTDG%I zo4Q)xwN>xosvW@O|BH;J;nW^(#udc3-vP~-O|FWgjeSP1* zPuH&(anIlNY8|KP_phdA>(<%*xc5p+mqGA$bKZ9+HtUz260wVn-KNV-3U3IXr1idv z|31I&&4PDT((A(B8LU32E;aj6bI5|Lrc96oN&jEccSc{ zO24z0eY4v+^_0C&>5J%>y8DY>oZtS?^y|UIn^u3Htkw)mpXTeTs~bCg<~3f%T|olr zW)J?9CBD4h{PezYNxP>oUrE)Atdoh;o~(LdCff3XX=ZZ_gdR7|M0>o!mDk` zgK6JiPM3LJdq6yD-RnPI8YQ6xnGIagCEc-GcDXOIcg=g85WjByo9Z?@(~Lun=R&va zT5`p%q@_}gIqFDV)%?&48_d-bzm}cpy~x{?R}uQifcsFE<@%cj?K|Hu*jf^Iepaa8 z%=^5v3YPM1-uHahTH7$kxCb{~!>!I<=#ovlZN?RwRF>J$bvNnz3F{#HNH>j4UDN2f zVV1go@-DUfRb7+5ms7YuGQ*+#`$e{gne&_0y*9khaXRBjqSoXKOU-vbUCq#X=}6fX zb&d;9mp@u$op_;zdCr=ac{0z=y?nD_^~{-f%XGBtOJ;9ly}Rs`(wP#6fE_3AZjk(R z;ptRqyV7;{ z>6!H%-T!(54R;xz=JkDeb%RZCW=kaNluKD_ZnBnC<}AIoEA{pQ$Xs zL42#leZjcT-C?bQX$u`rJvha(&~*u~!}RB3XE#|2>s?RaGJG6VeYoYttLgPEkq10^ z3L?1`dJ+;jd$jo1wXbWq%wbR~eT4H+*&d}OhFyHIO!{2yES!;&FDshtW8&D)8=pSR zuN0_dr17Y9hHv1K7mHXl8NWOh>Fl$4H`#sr8?*NG?-BQ+eP?XA@45e*#i5*ei=3t# z?_#PoD{9r_$?Q`7>|TCg_9{i;Zxa`2|9jbQ(EoN*^3=(OFSH(fDol=&?l@G}!YHeF zG553M_lWqDf2CU(w{P9z__!go)8KnAhjqiFOLtFP{CYRCWBoRD#}^s@wtSp!ze{?W zRx|TCll-+-g3s&>ZzcTJb~CRkIh~sFz(V$GoX@8jwHM#MHBXq<=puZ)^XApob-J5$ zZ%n;;I-GG?zSTL#?dIhxZ#TY*^~i3s`m?)k=c#Rp_Wry5Qe9eRUN~<5;c3%_TmFAm zvfTZc`1G&Z(uBt+?{$T%9^!d%t9SFX>xHXZ6DHp+Uf=MDx#61b&f|U2K_zc{xBdMP zTDI5A(cJp3VBF=K2`_@!b_R&_&I!4Fujql@mPbo9R=@D`_1*Yl)qFF*MIk@txy|?* z9lPSn)P$u`G<7* zgZ4-E+>V_Zv8Q9N)}7ZvC8_7bE>4|&?|$`xb}#eh+V66?Oe652mgEVeZc_6- zGFx^fyT0(7yXEMwUsIa$*sr9_`P@@%kze|7a(%<$H;cL_n<-t)dObb6jIUUheI>^( z--rDNUVQo z7ZZQ+2DxUI{yhHg#`C|4S!G-Aef;DRSh9cnTYbM= z>;85Aip$L7-lck0WBG=#>1oF=*}dm94%CY+48NrOV$uGZhgOc|RvRw%^2O}Su!>VX z?7+HVSMuV=s#^^OPrc$wy7VHyZHiX)nLGb=KAiDY*!6n$wi_bf^ghfGynFNICrN=r z9Q~0$)m{ed@oEeF8JiXxv+NS#TX#p=@}OR_c8N-$;a3w4(Yq^s zZ(mI_+|?~Bqx(ZBu})OCdqH4Z#Z;cdPulaWj9;oQ7wr6bGG_HWj?E8*6+;WYrWsB4 zEK*&=ee}h@Ux&E$WwuM#slM3s{rpA!txFG_ww+|Ge< zq6>m)d)y44{Y{N^E&1|3LST8q!qc0k*qjiKepj0Q?egr1DrxypS%t~Qe$O)^T6XSx z+Wf9!?oF6>{IlO%u6fhdrdWnqA9@q|Ea`mn*U#QF`5%0pyZ+M)v$Qnfkh$*F zj?9}Z=L_E!N<4OdO}o!K;lJg69QCV|K2&{jFRz$meCNs**9~=3jaa{Fs|h~ixKR7A za}#Gs!QMQfHK!Keo-orR!1VbNtCY>w!G^m+zHAf-E?Zw#b1Lhw*MpO}%y0VNy|7?x zk|+{NU%xD)W#&hNRVk&7j>jv*#jf7wKP|4YwmxK;;b|cyfv`vO`;Y!8^4|ETG}XIi z&87R1sctN>jmurkmpa^@G)>B_MBV6!U5HSkm`K#GlBNeoX1UsWhTKq|9OLnO!R`C2 zYh-5Mxph3$Z&6a2*HV%2w{hXuE>?$K*Oo1+Hv0ZCZiV*;t&fQ(R`36A_DLt^xbDa9 zRbR@d$iGc4WxRX0RoQUjY3_@%+^MCkoNlb2lxN;fEK2=7X~mVF7t)^De>jB=jT=D3GDJ;Gg-c2_T`A?rf7|WYH3O3(Mo3$wE4A4_(d69Gag3Wyl~*zTQ zcGZvV^g83`E!}@PD=O4E+@oZ(!h>s}nN?|ASKcnvUVp@4xd~RP}*pDY2 zZ6A}$oFzNo32(Y;r)#?Yg6b)^9s}-UJ2o!bC%bdCa%WfZV^@w6_j2RNn;MsH9#hfE zD*t)^YuQ5XH&y4}y=*^deC(9OgRf4^>5o=hpGwrbe_ZwB!wB&gRy!Qs7v5&^+8tKz zQFi%g zho11f?W%`(@{AlfCcjdQ`})~muWQrudjWx(45Al9weRQO0o%gPXS|4;cgwEq*9(|; zi|kTRoVu<<@6EysshgLrDDLuYvdHf@RS68$RI$GIC?tG+yPmwvqOiK(TzQ=HvaMtf zK9PAg@poB>%&JuyyC&`9Et-1uY^Fm>tyDVRvx2q7^GVQEpN$ca^yWWHq&-mF? zG(|nfSRlh=(Ier{jCWtvW&U%l>ze%Ls>%tU`qhjN>k=#YK6maqu_$O!*!AtqyLQfz zj}2HazHHLje}yWwk7dMS?ZT8L@~2A0)|K*3ED#cXFU}Gj+p6ap_IAz1t2(d#u}jAW z7teV5{DAfA!}A#gOa5lvXn&!{!>8w0&foOxe}CTNX@^6uuq2vK`T98K?GH;&jae%_ z@-<2dkCc3QtA6s$F|GTlvoEc>!6Bc#@a&1iZCsss^PQ$^+3jljsWEZV$%?{~Q{G9I zo+2qZ0f&x9Yxgl9zhvKgJ<@*aZ^12H+@DvP)y_KjzVx*>ODuc2_}vn#w+pSOo%i?E zf9A+7w<~i(`?|-s7rV{ioYJ)5(2l&T&gT~_nY3bsbhmA*9`Er*zogWc&pjEY_nJxd zg=e*p=;PE4^~-Xm@;Hm6lnUNGSz={xJB5u`Vb{hrddVF-F8CI-NWScxI{8SwvtE13 z{6mux6KV^~BIn2?O>X+>B>IaxkMr1%q-Fz|>#v@vx5fCHEMFsW)a82Og}1w(I$ntI zDS3HCu}|cc_vc`5O~#LtSL~2c-m`1{%$2^6SMFF}Uh~ND;4IT;vtN3xezbXMg}u8< zxN7n~+sCG}!n`!K-3r&fTUT2dzHFFpyc)>*CXpuj?l} ziMPBswwLR7h9%qXYiC{hRopS3Y`~o-}vHnWuFUYKItynCH3ji zoWSDyb%Cb)O{7f^#YD*+_ba@%$a{%w?1_dFQ(aSG;aIiME^Re0Wp~@fn$A-)&n_vO zG)H~K%A;W+tGS=VJ#{t@zxMw^?eA-c9M^ASy|#bH!w-GBg@W;QCB?S0uRL1Ros~Cn z)(`t#XKiOs?UqP%`=}Y>p%W*4hRMV&C+Nwf{pqIy4(IazSk)n)$W~PQ!f)AWr;_{+ z%f20C*<19t+kC;9D}B0!j!T4NuP`i%?rPNgdw?}@*~&9dio7+GmwGq%e$hQG_S(R^ z=E|K_;9Z1DAvjqdWh%;(tbY4(m0 zQ0>jT{%cpj6^=U-3^)FEIDhTp(#r*!8~!Y54k|tt6YBImCa8Ymo@&oke8sOB>M|`q z@XXt!RW1u|1#0E=)}5+&`S^cL%D(@1;!~Cd zNJXnI{^xQ*Rcl?0Xz*VV-59eP!eDCU+ zW2TF*t~(U6MP%OENr_!e7gOI!wuKTuPej)$eH4}Fqf9~9VcXH8;{kDYx zW`cKb@lU?bc=uGj{o7UFo}K8=D;DY!NPMPkwUA@at2Jx#t{q6eR@&>Y?XuV4>h=$o z?bSciTh|FHudQ(@(N;T}k~@`0cnjym>tT%i<{o1o+Z|ejeo3=@U%4;h^ zUR;uzd+XZuty7JeQYT$ao%Z99awXd~+mfqE9+Hpy6jR>Z*n5$AS54)wBNw+$HEv3s zbyanuR#~fk)G^KrQ%^}$oM~aa-Z62~;_{#uU0&WhROA!4fs{?Vx;9|JocM?RQI9vS zbkvTGIyrep-6HQ~|7F1%`-v8h#Z^5td$_mF^W zEP3(^u1PIf&sKd?_p_g~%KhiX+?y&6o1b2{mRAjDy!)wk(Feh2U1HNay(Zpn$P?S< z%U<1A8YaEq^g7k7kf}Z5^R+}?ZQb@Ott2}7D&Oq(XZq*sKU6OKa3*{E{Xbv-u2Q|o z+RUTdx$bw#ox=-XFQ4etv&d{`&$_94Q@cc;*WFn8jqPOrx+9@)i;6G)y|Z=Ke!I%w z8@E5ui59x6KkvUoWc*K?JBJsYUb{fsmHF%ygXog292cL4{oMXymQqq_Av538>R5&A zww^xbQ5zf=7yQ3{>eVALx!9W20zaeIn ztCME$QGPF6q-=Gj;!&>N+N9KrS62%KJH4xm*1i!!uTkZJGL7hB?-8Z%U~`>dF(l z^;+}vzAOvgsWDqIneWFnX})4!8#DvFPgC)BJC)FS++^ z-4?O4-}>HNUvlqXo5SkY^{_mN+-S(1Z%ls{G9?X;cVsAu)w$d{>X za@gZi+3A^AKPEL?RsApjOX)(}@r{7=8KE|rdc6XV}h1@Qw zL@~zV|0ni#@D=}?v~AnA&thq5V(quTWaMXGdeQeT^YWU6wsB z$mQ3;(!#%=$ZCtUzq_Ot*rUHOJCj>5&GArh-EQwa+djN7>pjT*_0Y__3z%o!kUgjF zlXv)P?yl0?DYFC@d4CG{>M}!h+q^dtJE7F{&d&N(nRGvd4IGRuOqHp^xm0gD$)~&uR!Se3UI?(dl2Yw*FWQ}6%Z%$CRmf9_rDj@Lx^ zu5agbwEv%SQTMb#$xM#T2~EK)A3Va!{kOZnyO_v!SGl3tg@Nb#>H9XH-P*7Jdi->= zd7V7dUGJ~av0dw|Lu9t^ablA@{%TUt4Qbn4%QM@~6)oU#EH_?T(RglydPBSW_Ma8$ z>CbIn>+QN;7Iy8`#B=fjcl{4csx+uk<9xw0g{{PTHRr{ng{QRx+2k7Z%s&gQUFW); z&4?}b+?!9rZ#GJD#wLizJY(*P(fXi2|BcS#>L-Wy@Bhg0N)r6)!X1b?>J!%dYBmmwVQ=HO33| z=rw77NDP_UQx$gh!qS>YtcSKJRCIg1$cvPh+xD8rlaXZ3IxBE&MIo$1ies5RJx1H_vtflAezF#|&&D(Of(fRwTwEGcz zS9n`ly)rseeD`3{(&AKu1uNNQIc9EbdbiQ&^E#t5UovAKegC#7@5u+*RXb~)q)Iz? zN!Ql~eP?GceIIa^Ik|L^UR!kfJ;%mf&s;Vfa&idf|Mi2ByL6ZOk!g2RW^4=;D%mbs z8ohKK&kvdB_5st&XSD7*U(5IIn&R@9yVdd;IHe!0Nri};%_O$qZ?^BBwQ@V@`*m-pT3fV*uU8h4eOEYT~TSFti-r$NB=jjL>3 z*B8e7#~$W(h@CE(=6T2UhS}A<-fx#V#a^{9R(^G9_Bj#VOEWLO656&pZ~1TDtEH0@ z(~_3|ciY0tC($ctT{At)Ce-|R|I*zd!NGS6oP-K_We&f2dg;c_Z(O3K+TFivvko7T zO!~)@abVl0SKlgl`wiYKD*ZpjC01NA%|>96>GNr!)7PH$`Q;S*N$%KbzG8(0U5Tlu zkEBGmu6@-sr}22=tJ&>Z{7gx=YvuR-@?cnB4!Q=zJ@)Xc7xt$*XS6-Edv(hAObMsq zD|7ADr(eB~xw|`b^A^Jg3wO`F^5wy$yQ>&WpMKZzu|9L7;Z>Dbsk*hcK7Q4=EXc1`5P0LE zlk)bX<>?6ztq%J{uehi5%52k7zWd8&+}_-}wWnQ2{8RDvmCHm*Q>DYh9gGCHjLvLa z5||jbr7)1We}BuYY0u8z*mdl0cR%Zgs`By~t0%qQ*xk%l7pP&Fo9-TxHp6pXm*7n4 z!0jbWrJ==%w@hr5w^_`a7qiRPlwU^Fyd&>M;<~cOfwAZ9uJh{7@-YYroPJ)nTy(3> z`S}||@0!QgK7Dw~w5HWB*fPR@>7|%E51xtfv>kG-_WShumDS;%RbI?S!m?>$uLWGW zuiQ0m6xwlbQ*EL0b)nLux{KNau1~xuZlIbx<8krKlFpw$0}k*C%q%~>=Pd6E>wIzc zCYEg({Ik1^&Y1WgePPdD>Uw3ubfs7K)=33S-#K;rrrAsR+w;PC`*&TkW`A|5ai#fD zuX_D`pK=n)1LE%*|Kt^0o^JQjE=@MH}{k-MJytAuM zKM=6Kz*MR)^Yngj(ep!J7Ve+@pfYww@40)n-KtkY%QaNbsJ1-&EU7A)_H$Dr2Xkrm zss>l@E3Ths*?f4t@Rm~P(eI1P`Px%1G#XY-`uZCTUAEv!uu&&~ga&rHQ69(Or+M@oHJH-lS zq%v`reqXgr`|LaY93F$7y=SL8-QBzDX2^8~w#BXgRYMGE| z7;3ROTyn)a#mdu+ue|=_=*jStK;{`^_{z@bA-JFKT_t$7p3vqGEk>e1Wx|Ja;KdLm+U zXS1iFu)v3zdK=n~=GCihk1UmZect`at8ItxZ8O{Zl-ajuSKjl)V_YYv{P4SL!o6O! zeMb5j{r9&Q&sd(d+Iw1d_NU@lqd3VXyla=g+z|(?R}gptQB7{m)>SA zHWo9U6EFHHYZ}k2M@PEeUr7y1n^1Y|33oNe+A#6hQe%GOO0SGswyS5$SU95Ys$DIu zJ7Hm3+Pv!o@2hpoeU67GTq!kelWbk8^n2ssIcamE{bKh#uE;6oF|IT-zuYV${M77t zj>LOgm1*1S1-;hhP0n1ka;o%IT`n&371jr?mI{5!;xP`}c({${nN-+!zpEMn-~Fzd zEYNGd`}Wta6t|vExs=@C%sDTa=5sft?LD+kyY#k}Y+BqFM$g;l99x~Qn%+s9k!f>G z%I(RfU15LMroM{0bhb0JK6~n}Pw)Gg6*KE+=6c6kDZ71RD|KEZ*!tAk?$Gy1Vdc`V zq;@p#%AMV?YiZDm-I462vhhqiP8yt^{z_!2{^Gpww=1g4rpXsPJ9<{6l=s%lgFMB> z?@JkL)?07ZnYC&acmMmnKU>4L-(0afFmU_&UAr%g^gJb8-ui9k7*!K6ff7D&I z#d(+d%D5cvp4AEu59xhlQvAs7aLU)1uw+qRq@@xyfoN+>fQ65E6c?BN^d`I z>Dim-;kl$uxzK6%Yo5&|Q`pQhN=2Ql&os**_0jEWNwf@XQy{ zoC~j3E#3c0Y3{ko8C!Q*bA(Penxf^_vueY>8Y{iP>!%IRR28DVV@wX%$y};{FCDNW{OtYzzpJ!sailOvmdQp{JTK&V2?c1d$PIRiXd?uruna1^V zYDRwOt=O~~8>j5kxN`Sn-BaD&$!#|${#x zrTnVx#=fcvzlvk+9j{Ck?rfPnXT^uGw$nVuY~i2mxVaauQ5&M8zv#55E7gwvwat<=*SbGyWb9E3Lkpw_x4$%_$dZrcQ`+i9LO# zqBk^b`pfozHNDpZ#qX3(PCUjHxm0-lm*=}y6_(8C+#3>mmT$x4!0Bl-G;^|J`A=rB zZZbSGiD&c5Ok1u+>$-W2l`n>0@t7XDdbPkCgU6i{&zEl9W!)8gcUy<}7SoA|%kHMz zTwEDeawU{EJlx^GHpqzy-Mb9=w{251IwKLwxvBl1!(G0;nzveZl_Xi7F~}}0pCa48 zD?>YSF-x{zZs{y9%NvQy5~si9+w6a1<_d4)Ge_dxds$*-OQVHKCEx15{=Ta&arvTk zIjM?4UDsFadAN|TSF2?g%Q61BiQicLN|WO*TuW(_R6RQBERFGA5?)CfxT@eYNYP!Q~U)`bTH_ zzNyIBmAd`KjGUYvox^|5y;kR&R)6$I;-^=q+4-{i1+TyQB)sWy;B*eI3!ADs`qq|b zOc9vB;l!;ukAkKp%Kd%3JhFXP!NRMqQF5jIw!dub_nzi1jFcCbe5Q44(FWWxDt%71NU*8l%eU1wX!wx3M(sb3^_n1$#5 zZn?HYjh(NruHety?fr*&t!rzxlo<2d{k`RWq5tQ(ZT_<^oXKApeD{UefzZN3-cC8E zuhq28ocPi}Mxb)-yNzFeo8Buju~d-^J@+Je#{Hj3-!gyX3I&#bnK^mS;Xle1Rgaz) z3BOr>&*EIPy+vMK?VT%E9`rt59jxyExAyHH&*HB#cg}puZ59rhZ^wA{g2NTouUghQ zPO%-k?l-*f|6o7&_yhfeQuJ6A7{~tR;^IJJ>Gap@Abo8ey;u6qiYZIZ;r43cKU_>;tJ;ZjkDF>t+2SfLi(_* z-viBpM|a)t|NZXu<+XOgr>~!IdrMy*b)t1e#ChB|Z z$sXR5#Vr1M1-I!rP2GIiu>F62AG$q%-X6!h%=hQ4_W1pqbLOt3Vz;~5&;8>&KY8CP zdUL4L|>J z+0{$h%g@b!B02r^p7PwREQ4Q{T|d9M@@8dFd*mO>Jtc*~ceCx!Ukf#l3KZ{pt*}1$ z?u(`G@9%JG&YLWmw*1r%WuN2Gl39oK$geUoiU1H6JcOa15W-*q#z?pB_L?^pZk=bx3G1&)4vS-Whu;Sc^>p&bQ9 zBK3{J)iZXknb6U4#5cvIX?1*Ofx<`QO)gFr9xUqic}_BSVvh88cXJnhUbXzp>u(|7 z&-A?u&$?H>Yj@oAyKiTi&ab_Cf91+u<}Tl#Ex-CZ{?5(6k5|4mNZ$L>FaD77<%k!b zmYn{PDwDk{*Y4$|m348~m1Ql>&GmNOyzg~p^R;ECUh$p@UU2%D>gIovS6|rXO=jA? zdCTg}DHRKEYpNx;y>t1s>$}|gIoA@~4mJLqy=7)>^DicwPaGvYo6Tpj#hR>K<~V(M z>~`zWp1&2j?NSS5)-60Y>EUFFUBTI2?K7>z1CGq`GhLy~z!h*O;XP;^6H)xj?3#|yam+GoDHtFLw_yxEHB`kOfq zie`kbniVd0xAyomtIOH%ZtN?(@KnXA^pZO5FZ2j%{}qfS?LPHIhu)cdDf(_2 zQ=MC=*=wy`lQk7eWId-VmCj&gir&SW7P96=l|o?2!93N|ubQmR@Uq3Q=vT*!i`?xL z5!iJg+j6Z&>5SPNKWgTbrOPTs6kUtmpWJVmcPr!kfB6#sZyzq0uifr{fVp#_x6iFZ zTi-QWo#|yMDf!a8BF1Xh?0x6|&wr72W!@a~g^ONCcy!$Vyy~#dl#-nX-;~XGykqYk z+3?Kg&A*r5e^@A>@B2*3XjffD^`6h4zUiEs*Rbc->8I9b`t0AnGU#S`x6trRqTV9w z>4{T!@M(OWRe#O+_>ah0?+jJ!J)hrSmdSs!Vv?ML(WyG7*u@WJxBfg-bLYPB|Ge)E z=D|18y0@&fRi9nzD4Ukwl*IX_+$ZpjgZaVs&l6H!@NKV(%*<;GTHyyt-Rrd0i zGY448j=xF$G;{Xt9OLU73`~QAF0Y@z??;kA|E;sLd!v=#ZWI?jzia=&koKG1)pz!* z-u)=^>`21Y5YG5FC!cZa%kzA=R`|KQ(Q>PGm`doPY>tf2+CVAr8AB)Ps_}8)GD39c~|t=*DXEvIjL>$ z);2aiIFoR?^~>pYkVBYyZO=dY{<(eUF@r7b^&z(!vNDbPeL8X`1?=AV{7;wZ?KC7b40V*P*1n+I-F%@)k!ys~ol7uLIB-m+;w87dCV zy^;8?L}0bwU8Cy(k(}i-9A%$P+jIELrM%X|YhL_P__$^@-{u%Yz_-8-57ulXtqsbmhf4E|lJPm}lvWUl*KsywavW-ulF#xMX|m%?@|7;}vIL z+~R(8b?=N@dt4SSur~f|AiRp3JN>+#$OTsadFKqumc;&eJb&_}HQEj9%wG$JXiAi% zA53gx+BIK%yIuXhA9am4L*#t+`&8@_GgUj3nZcKO2y!o;Vwf~o_ ziJ9`!kSosj<(c}Yqy(+b zeKHF@!Dsxgbxrl#TU(E6{F>t~{$~c~CV}Q;iIkzkeH@?-9cb>|MpWIM>Fy)xN<{&vWt z&&M4n`hDAfXp)}g8KoC-wHtqYe$;Ee-2chNyMwpU(K@PAj`A=Yg+)neb7 zg+=#IO&i2K*WNVN=lZy1OWfXqy7abnxh=Os>OGDd=qqYW*!}gdlU%HT z|89rbx)%FHirZ&iDD}uNnflV7U6N6Je+M){?TPfxd2 zw!b_1S$)xht5+*$Wb-xLyB^zPbn&cS?N*QYn|bfHcsJFAKC<2wuD|4E?*MogGpVk}P)&A>RKfUhHgY8aE!qI6Lrz))%*O4 zW{BQBDI&6KVSl38DkpK948`9Q8ku7X^u?FG2-A`&Nl%nZyL0@N0e8e%k()Q%blw)J zcCBN7wd!z8GDEUo0drB9vHfFD^Zh%+e|7H=xx0tS$^1vP^wJ4G$Fyq$f?ro2Uw*JrPh{vnZ8 z74>wssLB65ced{`o0qcG{_L*(H>{IomNy!39seVk_kgRK$E(kQRkWAeORvF#C2xW2 zvPR`K8Jyt@7B6g&(`!&(^T)+se=7<<*`&-}|5q=~YnaaQnTxmM{uG_h zwLcrbOzE$mW1wBCAMCm^x?VOdBHUH#-nnVpD()ua^=&WmnK5-&`2K(YudFTS{d}=@ zNl*67@W8}LRsEN`6@6DqJ6(?mFP#y|+&hCWSi8{rhW)<^y%=THE8p+U+RCzI_4i}@ z_fFa67_|MB)tSzPc50EGT9RdXFXUoP!`dsiUE94~fBR-W-Tfb)9QIzCm%B1rHL;Cb zh2^11F#pcN!avO$Z%@8bx-0V^PfFV zij`BG_4=Rx%IH$rw9nU88o0(x-LImuyyeHqsf>wiukGr#&Ha9BcJ$}#k8aqjR~4<8 zb!F`izRx#XB=a?cck=vsU2t--V9wFCuiL&}E4%0N&3A=-V3L z7mRhEF?E+=aCl2)^A-)^tYeyMwtK!i zK4yM-_GV$_WPZj=)_-$_gIvUE*{-HD~$$$>07w zzapD2|E}!)a>td@3Z<*pAD*LfM&tAy=Y*3D3oc&ES-w9sxV&b^oBUN*cqi>rIul@H z`#j;N$LZ3B2!mWj>%VJf?mC=%{l4GjFTpFNl}fj^Nv3nnOqy=*)Ur80UsB*%%u4Hb zyS^`ewkr^vIMRjFww!pidPRX>_q4BOTTb}ZuU_`8vTJJ8KRdzQm zOJ)6wunUa_``?#6wn%=~Txy-U*y_wgj^eg0sny08&dri67H{U*AntHdn zD_Ki0t>X5r;uyE@{jt7beIg!rBM)CWzx@6Fd(%tBWAkILCdM@y=toKFJhor3J>vY? zwebgbZEpMc+=TCYYV7n^2IdYkc$e+IU|V4GS9z|%^G)l#ui0uiyy`M|u5e~gZbj3( zZ|i=?gkRIu2|bz7Xb^2w@{uPzU2jrpvPbre*Xm~!-mvw?&R9_)n-;l!i4xBY*BRl; zXMQ;Bov6qspU7Mp_KI!dD}(FaGZZUdO0czCF8}uPUFuzqOH$9OI5#^MOlrPpF26IX z#d3<-s>3m+iQ7c{%!E$M?2?o;@Kz6(;48k{a`OYv zp3aS@Pi|hHIIUDaDE8V_sb@SbGnpNm^{ozkEY~VsyyC~_T}o$`avJ~cpS-T`P3m0^ zp~SqI28SQ-R(Jls!>esg^~|hI>s}eSE1U@sn)GJ<`YXL^p(itD8l2~Sl(A*wvt0+b zT$Fm2#<_WZ!kb@#EtV@l;rz^~MN-08#qdYO{MT(kANku|W+)4#S^c>fW8UL3Lt5>O zz^=N9JoPR!9ssLoz-}XMBay{?9$qm6kE{*)GQ|fwIroIF0{% zOh3MEwRmFRf=4sFS}fHQk6k$0ee7kk-F4n2+G|!@oe3346aV%*L}~UKY3Egk@2Di2 z-4Hu-UO2k4%YZ%b;}y|FJ%<^bK5gD@hB}92TvtuHsF9eq@bz`W&AzKwGI?gth*mrE zL|tOHo^T@HqEF0eg3p9nENz*OJ^c62d!@A7s>64T64my1wHAEYlV_93TRgdCW-fbM zaCCF$Mvh{h+>rL2zK7-*SjWv<>i$;Qvt?)Cp&a-7KavafaugeYWJ3?}*gH;^|Ew+e z?Eag(fq9P&cw7S+Z~dRQ{8);TKdWSJy~niYOuln&IDS6tv2WSD;DzlwmnYi!B+bj7 zmw3+QM^$W_jnB+Xm=P`YO!xW6FZO}cz>tvqYYWw+9 zy!d*!km6^>_MJ-;|9x9<+F-eI&6U&{&c!pH|EjjSDylu5UsJM|_j6+Jg_m9%cHdg= z#9y3zc+cDWWp57a9iG$rgVXr1OzMp9pX^Q_ep!}ybHd>}cMZWn>(Y5zzm3#KC z?PsRn-m_A7Uh4BZ^A%Sg{xj$Bp1$%}b5Wk+>ce~1{<8L)Gxv2`(uu^h8RGtJm3O6P zC!TANOKbaCdSY|pwjvGbhp$T|pA{VbbL+>X#A%ZzvbD`j{8!C!IHpIjeP-gmgc++9 zRTu9~+&53{a7^DqkkAaCVndLJZ5{<1J==QL;JOkhJm)B=K29<^vo&GHZ0Tq9)n5(5 zmFo_jF>sfBb~I(i>w^a0P0ws+4CgPlZIelB`}sJKzt|FFh)l+e>(Ny+PJjG-Y3kuW z);ynIJJ_DNI^po0n+Ekc9w%3L{aA6@pk3lwt=nM(ac3{L_``oHxegmlcj7lbT=V{H z!i>}4*eaHIc3tgo46EfCp3n7%^$y3d+MeP0{G0V~Oee@2ai&(1&x{Pt@O-YYH#pNO zQ8YvH*>|zSF&rROTjwY0xq}m0YhqpPgv52shtC+?k2gA#Dp53JxAe2$ljWXSd7RA1 zpYcAvBXQl~3y1IAGw^TQsq}DGS0bPJndZcG9zTvMw#`g*+j%Kq+%=Y=1YIo_Af7aY9MZY=3MFj4drZ> zz08gxxo5W*9E&_>n%1mjb}zNnm`b%rSi{K z38y_MlKSrdYFC_8Q22F&>vIj5AO91)5O>`(_|+@BGgsBlycS}2Fq}HQ?MmpOnEXS3 z{wX(KDZMyh*Dn6zy_}mltDRr{%J7bjJ$z=Gf$~nFXC@wZ3l7DvU)?fOJF!hYQ7&xP z!sv;+5=#&7XGVugc99+4$L~5|)>jXVzFJ{%gFfac$k& zli&V`PvJDSQz*4HS^Tc~qWzuwCEGM!PS?8s^8MkoeXj9y>gO3BU9^3p?FQR_$@d?W z8Qrcv$~o0P|KrQsGjrlCrh3G(pIz}gI;8u`QU$NO@!GqWPCM)susK>?fme2k9&6w$ zrz`ET4T`0a9HHfrPi~4eO-ng$v_wz1@YS-d1&%=zuUq-P+7;8XayEnX=Zf88c7NDI zzJ@05V+fkwabsQg&!_7%XLCy}IsELW2~*JY_8T*@toF;DxwT~7>FDd`mv`8E#40uI ze)san^VsXEFZ893?zmq0f5p1fE??rl->+Ah93DG;OM&!x|68wv1m_t%UzhFuww$v) z)UMBK#!ilRyUg;Rt@^y_YUu4H`(J+&yjALZvnFG|w`I{&W!2JHtw;IV(?11WIiOIQ z*%4Ciu}JSs%t~*jv#0sXnnXlAV)=v)+Up5URW6nFxVydV?ES5|3SEy2qBXYscd+P< z`@^ons(3*r!zS}&mSu_P3V|oF7f#-I(BQQ2NC1!IEz9Ty$;}I+mrYp`Z2gS?g{`eJ z=V{w})4KosZK#udfA8)D{`c>a9>@iRGhAVP$5_hh5R1WaNWT)gz}g{}F+h9=`xQ}! z(#C3BocWXYdYXJttLAdJ`<(sNshiecf2sd{A@a^Cmc1bA?$M(mf;WE#7}g1BDSlF! zdCk*$+u0+pXIAUa($Ka!pvPFsTH+I1zhF`NuCB<==|0%0^6Nkn8+)^X|^j*7IKIpTG0k;tNykE=_4F(#wA~ z`ReYydLdye=45@_wfkD9{FzhBH9M}{pVlJv$H-#t>|(^i!DiT2-HA#m?lrDNTcaI;Vr`%g(9)4z)73Fm#r&NrjZcmyp|Bj|fzRjjv9e1DPx>Vo&`(lFq^jk;PgsxW$nwIUi$9k&xE3Ox_ zb~&E-{%hAR!|x?|SqYa__(F14|9@exr?)@mSWIks==aD2?`z_3PG))X=GQ^x<8N=M z{g!7FoNKT@e@?z{Cfk;f48N8<>#Z4WyO_#cVqHIN^2`wwKX~-JqJHRl;jbS*2Ya-K z)?Enu{=Oqx$1~?uQO@l<%ljvW-(h~m)v)V;Eu8bBXV-d%@`hdK h8v?}{J}~`cSJ|ZF&6%F@g@J*A!PC{xWt~$(695BB-9G>T diff --git a/doc/qtcreator/images/qtcreator-scxml-editor.webp b/doc/qtcreator/images/qtcreator-scxml-editor.webp new file mode 100644 index 0000000000000000000000000000000000000000..d57a50dfb7609f0c8b0302f71d89cd2fb43a8cb7 GIT binary patch literal 32822 zcmWIYbaT^dU|X{`ux&64~(CHUyGuZ_vtm1eKCXWg5)b=Ct;>$LDwTXl?dL)T4RdV}4= zdw$NP##@$7Q4w#{rz-w+oOE@M;=;7Mb5?h=6bXG&c|FNxQb71}Gfy?K`>XaPyej7@ zZMamQ`uvmcfm+LXKN2TZ)GqhZPCoHRP%EtH z{ip|2aMLddrVoUAHDYZN8z1$ zJQ;51qw3BW@66rlT=i9I`(y=!a~jOA56+yoqn5Fd6gcQlE^^p@& zxHC;>2k^_yVl7_0VmkNn;(7yz-~Z#hv=@0SQD2Z*_Hys{)};{{-ud1ezq6Gc)%$i& zd+&{j_Z*j+hrijIz_Zuu?yAG@@7L9zySdqY$7Jq}I>(KaKUNfdhBp!m_9XH z;Msf`BfA0vzF(()LH4`EuD83`5A99=B>Q)|>+Nk*&9WJlV*h6g-jovgNgyr% z_9oqv(m9V0ZuvN6k7U{w_x;Z&&U5eoGTC?e?J2K&-c6g$I``Zgg`FaPWlkq|G_T`X z{xS1J#-W`vV>$K8Q`^6pEIz%w#BtZoCA&qJYTqtNE7+VT&c4gz_UV@j-&5`~@A&q= zc!}Ay_0_vp&1Lp{ec%MQhg86gf-Ox?0}BpS=}b86xqX+_`v$o!`3F8$eZG70d53|r zyX2H&2DJ%^X&rrU%0i#7d)2^u``^}FoxK}nm(Q>`ld{~#C%w|(tx;W4TG~DTsnaYs z^EhwxKE2zw-Fo>;pCIQ+av4bzzWo2+x=p27#d>4v3wvFUZBMtI?ddgA5V9*<#M&t) zxA*tg?jUYAR8xevgBv_6vNrIU2#pwQT>{ZA~Jx4wz=26k}1$+BWO#)n6)_E=EU% z4jvE+e6g6%)%(c5?xVuV3tz9CEx{$$Xz;`}d_sp5$LSnC`@0TB)gPKKOlPmXooAge zW71E1*FfDB%<6Ljc(o3$_v*=;->%x|-jyIGct*)-?&cF0B8)g>w7Hn%MOoQ2dOw(M zPFwdu@maBM$ReGm8lEeE%?+FM_l7_>^X+^Mixml8`y-a@EcvC>{QgPYxu;&Xy2WeH zSkLI3`gWysYu%Q}>8y(V*JqtoyjCSsR4&|YX|(m?sr}Zz^I1Q76s@Vy&iT2PiM#ef zqisn?!0n06+t+M9wby%l^s$d6hhES6*Eu`SF<-_Qo97m>2J~cLnp5ws6E{hP`{b_rS{*b+yAe zeHpKu_PKwG^gh+|XhZSarm$(tC7cB}U-pV@w--ikV3*}{-{LhrdHX4$h1-;y|9jn98pk+C z{G`@duU%yqzW+V`OMY&mUh7$vzJ0em;(j&EkSNRbPVir#y1{JrK1s8L$OKDP5PQ$i#u$>7Kw{*&a5o+KO@g7-p$0_dT^0;a@keS z-L0GlAMH5&X~yMKD^B0)czw&`V?O)wzNQ^JUOjNgc->yk7sOll>zJsTT5q-JX>ZQT zC9Pgp7OBNP-4z+wwR910mto_r^&xlnM2m-f`nMz6^6j>zd1e92Tei(TkXiU+Zh399 zz^hi9-9NkA->6K=j$feg;IHBJQ#(Jc{o|cAr$+bbk$@J@FSE8f&$V6L%l4#t$-%oj z#XD}?vC+Qnm*m)E@w@A(L-6)it>^FZFk?Fy*?Gn z!Rsb!UOsbYljY3x9Zw8PelNMRFs?bo`q1?RrrrCGe0lTdS?5v_9ey3r@1k*XoAvx} zhNx@l^clWZe&g1%S8(Ghe(~RB1v!!mJhl7FbetX)zg+5_IDhHI+}r#9X20$~x5&51 zfzhqr%Bkz*g+0Qz%A9ULR%~UezkhdkeX~IP*TBcDR&weNXN`}o`53@*;oNJ_f}oEP z3)5duUDN#X&;BX?8@OVYh`qTr<805JrOQ)u%?h`Ro_*irEaJ+#_D!~<`XU9#ScyFf z=ZaPo&pExrWA8QFL^+ucdGf7{VG|X`}S{xS-f}ONa~vKI4el^#huEDX=T0j_jpUzK3gK_ z=l9p7+nH~v+h(zc*#`S$^}ZG8ZLhSMe@lD8mrts-tkaLJp1v$QWSNBY#G|PP9N3C;%t_l@a8u??+6tbQE~%q$gQn!H zn5*TOuJ-6a)0Xp_>NpFhF+aD+`g(QQSqZ}{&4y8Fo+>%D=1&(LaAZ&0STem-H`Hy# zTaO3obD7t){hXFkaG2rcY>o@xRHk|@H0snpv2C*U#foOGc=z zByjdoFV7RTv!2Q-Y4<-)_^{|g>CK-kJ^8KSRR-IC{BgPW%V4qH zri$Dd*4DA5Rok*Mt0t~pC>pB6A8_&a?0o=dths)DLTT^L)Wedif|NS8sej00P!kp{-O3rfH+7ZXcD>c* zD>6SD8$L8Vot!u?>{?_(>yfK$Y`QLg_BJk%{O*^qnfLVUL&6^zS~#X2?Myl~VP{cS ze_ipHyRxN#TC zmz-9LtX{QhV_4<{*;)F6?=liE=5fDwbmnTku_Kmw`P5#of^AVpLiOJU-uzb4Fn5i} z)EzumMM^sL8Poh$`mw&dvA>inP3E)O1<}sES3ez%T^c8Nc;A!cOUD|rH{B?GDQwi+ zve)F1;j#6e31)K(Tm-eh>s7JJ-V9LT2>&~QJJI0OhR^cc-O;n94?ghBTa|wMUAi>M@811%>GQm&-%i|OQmFa<{A8p0KS#dre_t(d zPH)}Mvz6-3Z5D#}}~SO*E7$tGv58_&y%KTXYPDn-7Ur^;v}Q@ z30C%SJWB8T|NlORZ9V5{u^`t#h9k)y+Dfl%vy|MnJ=WOKaHX&Bams^w{-nRT3zvpG z{Swl3yg6F&@4*JWkE#vN4jfKgROqL* z0e{zV;h$$`#XeIN`&e<|?2L1K&GVPs_YF__c=x^ie1Rw3COY$W1YU}|x3?jo$gu0y zva;yAO~=#!TK)~*^UIaR{G6$6uHjy#@DH;BfA#SBi!D_9%Vn8+;Q7;OwzpYyS8qsV z{8%UVdy36OrekS8!x#U5yuWT|ulj*GfpL#_&H7O#H}&UlcK!eMg{q(ceYH+xyx1U^2@ zyF=M*x^L^MHQIN2_#=*-pJcvpS(ty$XDM5Oc}xF>CkM>>e9Xai%8kiUkx!i0Jyp%I ze_G97J+=SQi)$&580L1oXW7*MaGJXD`%^@S$%h(}{%p{=_U~oW+V`Q> zU)Kg@*I#ztU$-Gg>}rVUfdvv-nq3Dca!%Q@--(O0V88U=3bDO0OkHb(R0FvaJY_Gk zA5@KCdc?8(#Z4>4J1jd*1$P``Qf+#2U1fV?x+;4k&^plcQ zKEooHUzf|Ry_Vfc>#*~Gvi^(if|+L9cFuj&GvB3V-{y)Q&5RutYtz1|^}gY4>$W(S zFQ40^cYMb5WLEhz`o9bEe!jdpRqpJp`;i*8<#E3jANrEBbmmQ`)r*rm7c_}v|4&)? zVE3@M%*Q|J53NG)S3iyTwd)?U$Tnx)1sSKOY5vvU zea?UO58l(W7kETz?@)=&uPuCSrlWUFs3cEPGEgRFtF5F)Q_<91@yZ>s)n7ydWs<6_ z!u`#s$!j%Z>EMnP;SeY&*i!wlj3*O?!+D$ z<9#xwJH?*H#hdNknNnDN@zXh{o7JD6zCRyYV-a3ZnX|^Ad+L5#`-l7ZL4%4;_R2NsUk^H`78(YM=XI$HACjHh zr2Zy*xqP0{+oE^xIKqEDaF?A>HSLR|7%$IxRk2{1s*hY88$RCrdi8uv&WsF6`IqkB zzg4zepI@Ar)VK3xadGJKZS#uriq`#Hxl>&2laAk+?IvdbKiz23Ud+9&_vszUnhcR6 z-{mTQF5;QG5TiSGb!$;(WxFsP^|A+Z9s}JMT4YOV&p9Tm143`E_Z!R?M%YprA{o z`g3C9-de>q7b)!B-rrE_Znom<^B<*IYk#eFwls?Wdxp`=YEtO>Aa}_dJE!j3z0vUS zgu{GCrOn*tf7&24b8p`BFrF~`_2x&;TVDK<@@DnL>r#QQ64qbn)=gOQ`0R_nzeO%} zs?W1%{gG+1V)nh;$4#S7&wS|Qdbec#O0m+4sEE%i62JP|ZDPEk)B7?oplha|)mDb8 zbVfsi{ZlS2J^eq2(c_2I&Gqp&vhMFFd|_o6vNt>=>G{)HT}Q%{Oe1z>DJ4y{;FVJ8 zs`Pc9wvt=G;{Mv3J5I(|Fuyl{7rfs`>#9$Ks%%eSmv!UcKko1EO|(jQUSw9&@G^fA zhxPSS8x6c}SS*-pzHISNuGFF}o_Fn7D^=fKF}!yFn%sVSvGw}}75~2S6cgJVcI_(r zLjP^1>5>oY=DbT>m{Xvh*Pi({HE-9+;)Z$8JN4^t2A9->jP2M_?ofJar&YPxKZgmQ z1P%Y)6#Z}5w`+C1)8Y^p?j4$YT($Y{Os!nAFKwfPcDPy5Cew>d+xH*+<$QCF=#FIj zJKs%L_L>~(+c1BU=nm%%H;q>crj`WHS?7OlYZ~uI>8@sX71avajfJgg#aYS6kGQSu z5L*B;Ge_B6_P?>uo%G7Gq_VcXG7-Y2kH2ldvBTw3-W${CnFnlB)vHw8mHJQa>^c5{ z!~V0%--ZjHEbeJEL~ZI6+u|d*t@x{H_taa47tb}_zQ3hT+f?D7nAZi-1^JBoXNu0- z!XtY&>EYTKPbSwJ?RzWCQ!jRWSduEy_9I%u{lqk%jS&{&>Dml>Y;r95^O?BQx?C2n zUz{5_d$rZ;y3zHrNL}u)Sx1@lTO#eFP71WCusAK)w(Z-pDUQmGKYq96 z%eFpydR)pbxc;kw@`2zicS$MBgs{%jV*7=HCmo%0y<_H0`H9O#+b?8rZ!_0TnBBgoKaR2xZ$!mP3|<~<{7i4 z@=WIZ?_-QKh+g39V-U8ajnghKg=K!5&cr4g{=%(184^F1g#6gQrg_SuubX%uez%;j z@7Bv(5Fe%KI-&D`0%IIB6LbXoqLmsMo`=in9N#}~V3%?-!x z*Hk)RcYVC`DB;7Q#Cz8s+%CVZo#!6V_VvQHi}M7_f4HoedoNirVeLe&A3qp5&h{5} zWz5)aXtCOU?@PnY;lD4gd+7H{}&}hvtI`)>!TvfG?@%N=a=N1|(@9Wfj z;IrSDSWUoQ6#WSaBQ{C~~-$0=TdN1h$GNYTH| zf8D9h#MI&UBiZWaes%?o?)Ytv3LT3-_+I!`-hSyeUvs4K)!zxJs`DS8^R9ZbBbf6P zm#5{rP%x`Ig;!4$_uh5uxxV7l)!!dkSr||B9Ba*QI`*G! zu0=fO375~Bj{Bs4bT2qi@wHE4zFscR=if7SC#i;A3}X6rc+TPd_qY7}kbi2N)v@-B+2%Q_}oqaQrS537@%6DU_e%WXSnqsouv& z-c}r_mR)jG_Go6=_WFIQ^Y?!He*2I;Nb({P%XPQ*N6pK&*O1$gyo0UuT6;9xPmcDVQuS5Ai&uV`zCG)#-4&Mq zDRpl?TDPpxoH-$FA1Bwl^c_V@j?U z@RZ4Q-+$*Q^ zu~%iDJ^KE^9Mv^JlX|ATV%WY_RCj}&gr43KLHSkR{hE|of^O?h$`smp#W?lngMTk( z82A;w(ydv3Fn)f_eyy+l*?2hqRlWVWXxFgJ zZLR+_8-y(4gn5*`o7?9sOLS%wg{My3pE1;Y-`MGcAFSulinT37q+2e^XxQ5%Y~7?WP7QU+KEIYN;RB zww?$2Uw0HuxU}Wwm7wi8{SA^XGjEk#w@GaBZ@v@4;La2&_@pRi^`-b@|L)(kTxVH@3hmFJCW@6N)A6v0pcrU-+w5e|z=yi);6o z3B9V3o_Fv~!(``lJG~dzE-N+N+3#MH%pO}?$Fj39#m#krV35n>HaUSwDgweq6SsT_ zNUM7~^-R+4d={VYcjTEXo-AbFm=~kT$|SR#Nq(K*t1Xw5F0;Gw9ewTm+ql!?&#uhymRdKw@r)w%Pmp@VMy7o=2-T7}kCkR$?t?lDn_*;JB z^JROC?Ke97RR5b)JB77utE#-k=_eDO7qY*}cq>xz&Y!iexcdA&{)bZ=EWf?GS^RGK zyblXsGCuhF>%gASvdiiX?eawhY#R^j$;uZ^U@ZRsJgvkxv@HMjQRxG%XTRsO+U>m; zGyksj_hsreww^|b4=&E1@;J(qWBKIg$E9pT=T*F0&@Qv^xnR~s`3>dg=UN^6ekW0U zzL%bm^MM40B36rhjt>matPg41FW76`eD`;R?dS4|)=9fV#r2kV@NMtk7&I%tLi0f% zcl#F^gYQ~9cYIfLw=hn4cSteA$5g1`_~DNooCz+vKPGTq5ZGeoFp14>{!`<6TbG=# z4~r)8ZGXH*IN;iOo*C6Y6xri%=5hQobT8>~pR-eTM!c%Hg0e()^M3JH^@?Rh4-1ql zZ5D21?)s8=zUG7=+nc?YTjo_+(L_}ewk;i=%7yZF6p zsYAo=(E6k6KK&@ZxOs~ix2BW1!5#j_CkA`B%--g=<@n2#iK$E}+2*od+e4!GEnXaS zcUUSd^5*cKxcA4Sgfndq{8m%)kg&U7KI7|w0(+KAuAdA26n4Lo`n^S5;@I1U{zyKa z@6HJerY&7_AyiGch|eS9ClD>GAQs zzFePKtK+XJ%I-eIGHa^E1#e^a--;eDY@e8$UOHTxRrUCaU%v5< zTpM5imRa1DnaE!zUEjiOyQ|9<2>|1x&JtnLr@;@bH?|4PZPl}&cO(fugg>3QO|iJSMzzq8?U;7Q-Q zR6O|ocEvZQ2iuBg9j?Dq^6%NY+QP%{9?4$+ByKW`ZFjugv9<+YTTM&*w&(F>Svw1J zE|y7WS;e$Appzr%aqT`nPs?>vj|MTsN_|{Z&eeD4cyo4gfxPzTm#^2l3e2*SZdDX?aWUgnjl`O_JhO^bw<^zU=yS4EI?=ni@`mJ|>x*M~14`^ea}B?8NgraFFPM;< z?prh0$U5~`j$F89|Ns5Zzr?Mb+0JY_OKSh0YW?4h*Y3>novYq+>WXU^OPR}p#Ik0PBeOM zI&-L;O@Hf@s88bivp)PfUHb3akxAYw56b_&|F})tjysL7Rcy;amwqn26$#pc)3RKz znrjG{hH{?En5|?Sn=0!5@Wt0o@tHIE)H?OPv)|^KwIW(ytR?-`wVNur@K%EB;#X@Q?BQbLTzXk+MzPW2S8odc7S&u>eK;t!{J-M~uZf3~uh0J} z5j#0=X-D6*n5!x)ROOW;PQGZotR(n9;`$ASJ&!o=FXHQeAGKaTTYd9yzw6;O0rjj) zG6IBG%qu%}Y+vM?)$*s^byqKW&FH{>RccC<-iD(1U*2EjZG;X^Fa3Bk{pC@;pab>M zNA@kw|7~&9AX@nLtY3ji*>Qe>55i9!-k8wS zs3n-LO8F#X#%%5OamCFhV@Z{5QD?Vz`CiMDUmq@~dslhOnO5Fky{wbhX*S$6m28qa z7UW&}Jh7!sg)?;bpU0&#fkyATudu9fo9e^;p#F)AzTX6friM$0s&$exey+2uzQS_< zPxEsB$zPsJ>n@+s^=$jwip0P**+yaS7WcoGYM7eR{9qr4?}4Q0oB6U%ithc9!MQ*& zL2_5ds-NFfUYx4&*Ll`s8@#aT>viVO2d{h9maKkPsGc34boSZvl3;nmCshS+>+*^^3NLK@Qq_%Gb7*-d%Fn`IxtMOwN`PIqj{F-ltf6UvvEi!;RndSA!Bn z-pqPa?zUk0M5SxD>p9+Khl(GVFxhiO*~;3Q>ofF=gf~RSu1PuKyC~$#BH_NDe=L~_ z)hoExnQHh|nlY#!iJ5Tc*)#`(kGh{1N66*0P4(=0)~Lg4c7$t5^SsQXl1k3ks!tS( zU5_-+=}TJ@_UG;6y~hqEXjzbIswv{kaPR4;<}-_y^_A4CbxE&JXhQCM!bX`{HZ+nqgPvm`x_b_llqbS?Yh z)}!ITU$wkb)qnbrPaJA{qBA_z{wam&)8XUHDJ%|KhE| zchbK#EdP^WAMqeCDL|(9h`i#ScITUO-TgXF|C3nntz{I*ctkpAlil)HUp?HcrBBLp z86~mj{pdTZzFTCWZ))GsBPs4i#mBFoZQoxe;9I7saPLNsdVOI$fAOxZj0ut!YbBW7 zic@bLneJ}(CF{0Z`lBs>a&4Z+?_X8?d`|wq&%5SEZ`|JhU5dBdZvBD(cD(P}-=tc! zms(eEJz^|VT~@1dsdDF}cQa$3?NhH!6JNGUp!)S8&w%Hr&hEa-Y5iPG)XYRyx zZga(p)p^11oL_8WSL;|_?zmxH>Y=&Qr^uXJoW^l`@o}qb^~RN#k38wLb$s!;yK^J! zeEVneq6?~{jJ9pCnR0x~M){;nmP_`BcfQXvJr%WayYc(@T+_o=`#&1T?k?LaaaP(` z=J&g>#XMgpJ?x$N_^SQWn&RbNKOcngM^@TjzkGN3DU+{a`;z1LEdCg|{LlG!a|+uI zAIaU#|IaPu!$-AO_UfLEaw5AwUDEk-(Rs6K>WwG1Ykc_|jr-60;C!p)_5W|J{rEMi&v3#*)q3m0JJYlJ zTMx=<9qyYZuJF&D>2J43h<1vM0#@ zTE0Ip;B?!(Gs&GZ)vaFnYow?5O*eX<|Bdnc*#bV+f8RAN*A#F0lDR@%)MDd2%e;BU zCCiyU{_0qGN8yj5@@$oFM|pk!zAxFIYx=`|bDZy{-{)ulv9Z^PW63(UN%(iuqJI)C zcFI0cx~FW}CyI;g_h{n$aD_YY?3!)$n^^C2i{B6CD0Qgsi(jZR*Z07BHQ(KBhq6yS z{dZ(n^11zWs;^2CzR%8>z$5v=M_$FdE&2SHz~!HtKOFDLnPlOA@2bMFQ`_#=-xZRm z`NOeyvWkVw8LK&MKkhgxygA$L!S;`zt6AZv%Kw8(G5_zZ)KEEmd2-{GC&!|k?r%x) zag&dZw_KwuB7081pQ~-%+-x<0+;istZhrc&ueM@~%b6E5CT{#OX$EJ!(4T+3v$k)O zU1s-l$=|8xk9);G-dm6``FW`1-$1rU&es2Znj-dS9CR*XsTJgRZ&JAUnmea_6-(=q zySCGpx+pm+XU^=f+a*-xK2KM|Tj9xOIQCN?5-1lkiaBIMPNn6|Z5Hw!P)Xq%eRldQ?} z^4hP4)`Dcq;Pi9i)&Kr3G;0dysy}n0WiR^ywJ}#N;EhZSmoqcv`|F4jr zhaR;h%xHeH_v*=sQy#jye-mbDdzLQVG5cuKEUVA6Jo7^z@adgXl+0hX&RLCN{VgAh zohchTKT4g@y_=U?E-&&vQ9b_byYn6L3k41TicQ_wlAhtL`;F=J_UDSt%<~GO3znVZ z>9)OeK&MYqGJDC?0MD5rGba@kopkE|z`M`+sGwiO4FNH8t^R@s!B3CZ&o~<|kjbWH zyp~}a@8u@LQZ>QN7HKIrJha0+Bbg7KRORMcx%SUxwq6-d?wmzDF4uHfl3n*3ne;r* zj#_i}ak<8}56ZJrrU~Ad?`)K_WNL`#%#f`!3yMze64;?OJ<~<X!je0aycg-37Qsq0TFwqNF%7PTcIWbR4DH|G^4^Ou-5Uo;^!+n{AHk=bXEaQyV=LS(VRP9?qPww92CGgf{10 zA(mZMuJ+O1ccKiRZ?@xn*e^LVNqMbWv!;urhCt++J+jFbTG5KL&#N8EOgZe}vE6U? zv%+p!Q*RgFLv!WodlqGgsM)Lyyz=DO+AL3Vjs(x7%EZqB>n3ViX3lC}=DfheSSPV? zQPF~>s|;k!FJV`9fS<30Kd%sr9x@V?y{*8+YQ+?E(yfgW2S?(`Wj3QrEdWDys z&2$w^;`OOMx>z~>HpjNB5qjoZQ#^8xrEXkXW!=`f=KkCdS4~3r54bNXj9Ir@^K1u8 z_r;bCft+O_MGs{XMN8%8{EUz&SjA+mebO&dPd~ZX$Z)|a zhY9~$J$#<8cUmZaKqyZ8n8M~yDN9!#3g2I)Rd;QUZrj7wyy9aYBEoKzc3zs|C9tz7 zCihsxET&l;PiDn@YT@5%_gH0X*^;AeD^m6qN96?@KHbJwHdBp%Wxhetqp)P}cl@)t zcO)3}GU}JiGVXG&_ts_KtSOp!X=cXqrCJMCD!K-;aiuTy-TKrvaANa?4JrnzyHj=V z^{h`~=`j$E^LATUeDdO@&yo+HNtkuro6=zr89w=RTUoXizvbB-wLV9S1m!Ff?yS1JbT$U9W;I#oK>MhNN@@`!ch26R<7zG{F3p?E&VDV8{rXc)T4|kyY4K|X z-i>WpM=Vx3w7x3ym^Mj+*>r8n)ALLx7*96*y?udqt!c{CMwi8w$wyvYoOD4r_-Fi@ zlzZQ^J{ul;?fqiv-ak*5pZo1vXWwe|FL>`Kk@b@kzZeeWc9fip($9Z?X^=XeYsW5wKcC(%3=a2TYuWrld?a?eV z`kl0N^1DYnB5l|0{$V4u?4#(#2RWbmB|e_3p7iQPhBBApk%(#EgBMd9zkbhyNTd`ZG>Hm*Yj#t!Y{d@fMS@M+Y(;xK4dF0OC zZ*!zr{zd1>Kh?nxEb{%6?uP6&-}8N`P)?F5@8ji<($C%y$`2@Itg#Tg&e>YB+3&HoQ*u@K_XU$ZXTHAhI%Wdv&2N`$?;BQ_ zaULqM5Si*`CO2!}iD@Q9U$%Ug3gDP1k`(uPJ@3bWlZT9Sjl_bD;%3>0_pi9BxPLO^ z)vH@tG?;z;rv{%&W11K6#P#I0gX?~A@zj`kUDIR4uAgI>&y*QW0t z@7ld~_wB?d7D5ZJ$Fb~oda_5|&hDPY#-2w7EsK|#sWmap;yreDUq|f1-}4@uoxEf6 zY*}K#miX(ch|HXE4$eeeMwm*QAXr#{99p#M~A*Frl%7-^{{2{>DYovxhNky3`CNJz zHZjfOQ}x;3Bm3Z%>~%Yv{98BD*35ggaCM*ImMPyJiYKq**!4cOB=mVm?$@KMtLFUb zD?ggU_4an7O>?aIBaa!(0huX}R$dNukFTH0$SUl4mT_Ot@hLrppPxlcwvmc(oYE*$ zI3ae2O-e?Z+`EO<+TrU`%8pQO>3C`$tm=dFt4H{chFUx z2dj8gZX7tac~+6znrF2qWkmJcZy2tR`>|t_>yhJ|4;ZbOk>=y>8#u{({;xwWTYtH{ zTD)|-_*8*wZkM@^_f<8Yvs7umrpUV`K5x&@;sTXtcD<7WwlU37mEz^wSTG?eT}s8U zJtj^_*4R1F{M+dZmA^k`Me?q^&|@ewi#1gF>MF;Q8Ea--oZfS{SM-92TgK5TX99jd zJvQ6EeVU1%(@mj>xms^7IyrV#tnJcVuzT?f<+oZtp9*+4p4-K|UCUWZIs3tdW5%v7 zy^EN9*n~P&-Fk3$1K#eayw14% zx8i|YhS%@b?fm%ceB)NXi`I)(=Cy266}YCgU7t_ksJvF;x9q0RZnhF%mfux#GFZ^O z|I3k{AORuONn#t8@T<;UzKc2J27}fi*7WBS&bV4Xi)=63yh?+)(rI~2H=`sE_ouh2 zxkhi*{v0@Enk-S8yKkBFuH^At`ic)ImhqJH#xUz z5l_nWy%!=mja-&X?A>$mbHT^X#M!%Uc5XSlN%L*rY(p*o7yF*g3iIj_zkFh*#NU^F z=if*ieqn5FXP(yN)*|s-+V!E%)UEWXHE&wcGJVPVP{w%GBa!-N zG@3bn8SYG1Nz#5lCHnjfUQ6H7V;92MPuiL;=Y8bD@z!J0b%|TAEN=yDx~{fYDWi@j za&4_$q-w4UYg)=`cNLve4t0Ve>D!q7C2oao5Z$qN?}?BnX&Yv*TKd%cVoyPTY;wq{ zDSPwY1r%wrgeQi`{kB+Ybnrv)l>IMP7(dOMT*WW%SDCy0d%@MKN8;bzp5C;-R%PG+ zXA(;v|DNKwBQAkIcJbO-yU))Ql+`bn-Tip}{rP)LoKCBp>}#{SJZJ8sSNng<{=7T) zYW?y_zg{Q3){IRps+P0<^@hbpJK&p$W!Sk(p*7RQ^j!_RPHSxQJn82$^#y-uc$vUk zYq`3g+h*+76+3o(y~vS%O~yvG_RBVUhhHAAm)#cIzC~IQi&+ z()qe6>5@6h(rykS$`^L-n6a1jSbmG}_ru+hACi+F9#21zt#+VrS%YN);}o`24F8J~ zSr;e;NUq=tVPC_L-N1i?F`SD*@I#6E0oDTMET*jt{0GD$EWf-eUaA=WXUC)SPZ{*s z3oU1yUKk@*Y}s>KaE@z{*x88XYCUm9o&8JGeEzg+ovjMtSZ>+zWjT}Mj2m|BDr%=3 zz6!-Xy*WR_;htAk)!UOP%lcOHZ276RL9nMqM>W1LMa1g4(Btc@d2J_RKi;_e;Y#es zlr$Y5CLb0bjvoFmC%Afe=h%pS$apaEz~RPrMt(*)9vcA*4dDrbH(u;JP}@+={GH_; z-yP8%+y&|n$_}i(bT9YvyWC6f)?V11dTVdxt-YDIc6;91Em&pFu#SCA*QZ|x65BJi z*FN2nG-F=7hkdL`*C}6#-~*qo$(svh*=n#p+j^dHW~b4G18=^Za#va4;bUoiYF*93c=l)Li zXZigPA64-Fy>mX2nSG=7%h(0_YhA86+Sfj)(d2R}u;P{xnWL}R+Nb?8e3{DLs&-ZZ z)B6Q}2NO%TA5rgeIe$3CIW{EUr(5D^f6u*(=c41MH2PVdU}=r)ea;!t(KKbLis8oI z(>)>g9cnkt%66NJCN8IoG^(~rn#XB{} zgWDz1>$i*n!_>udx1Z5qwtRZOPG7c0K{Gd3ELHE>h43&nPOgHbt~ajSaawiCLCH|_ zzw}O?km551lM|%#?iD{_{PK1~ZiQ>IxI(SnORtpI_P*B-##be<@un~M5NGwTdtb@Z zH?}Wg+2?G%>QUoxZlSv6cK#pRzhBz@Af~(N@y^X^aXBk>t`*f^Jy z`{pQT`OH{X%R?hKce-Y8SrrF^~2;bG>jwR*gtl=kH zmy~C(DRtd%ZF=sp?!l|u7FaKgx87X%qW8|yHD7;n>+@W_f9ZN(Y=xr7fvES&UwPW| zp0nJoFF!4QZrKLDoYMP&^#)s&JC?>%;1VC zXe!QWUTHL8S9*{(XYNa0gIBVjs%|2m279}}+`BR$p z_0nz?)=7CWu{$4ebxJP(wLCC#MXh9@p@N}#Z*-T{+dS!)f0roFg|J3XYVi8iKDlZ2J_YgX@z$=dI$QG6=bw(6U;WHDGQYm;knwp2&WP6x z$KTJ8z4>A0n(e}C)<6HkKDlYN(8}e%zWKN2)tBgL&H8uil=0N`+NgkzfY;0U+oHr- z=CwkDVXC{NhsXjcht%^z#!VV&v)5dk687A{v*OSytu3Kh)ovAr3OTzR*YZu?^!SmH zXWH4dG6f8;GhR*h5L?Gzw-M{=0{mau3l@u zmDlRd=AdxlxDe0C{2NOjeNy}28O{_v{nNhhnyhvU6|2M~7S)&N6(@HuahtI-d&$#| zebZDdS3St`p3wbz{ZTz--EhxWe4j7f5p;jSKg}sGrQf2d@|l!J!H$1XFJlf~t&U>n z-|zJ5W@6r%*loWau6}!ZPs`zp7yAO{ef`o@mCUsG$3#Q>Tb0_~cexfj<_ImgaYtoq z^_r|Mm1B{*=AOlmL-ZGKUd`Rj`0%s&imTmM?(t-vQ|`14OLUcLxfLxY-r+Nib2HP{ zsB5q0*w>%`d{iy*@8PqyEmL#Xo=ejY`W-jVXPx-UyQiN{{`{Tgp&M^S^SO1^|MJo| z&Y4{;b6AUqVSdR{pMsy?m&`kU@GXmFpu^GAbpF>FF@tik9Q*X$(GXZV| zlBdi(-=5zW<;d#0>Ok1n-$rYkbfyR{&3ymD>-NKJlNPxHDYmoPx!*l_IBSjW#{L)q7sun8R$vlUWCQ9G3n49R2O89m9o{&IPMn?~5}|yf#&p zIc3gkCId+aamfpwk1X`QAMFg%;%%I&AgQ%=QZ$#D>WnS*dD`pe8_s%tzAnjM``4_d zJ2MQIzKPOly{oxl;+z+fs>=HgZxma)cWUV$wONyd_$FTCyj7&Lr%y1uC&77vqF9`G z=G@3K-kc*r6I7Jf<&;1AWAEPgB8KO7%ASbCAO0mqxxTY@dA8Y$7<&hbd|p%IIQ99o zSCL-J_eTi}xqMIDq<2!wE&k8vlv3M|$DXhS9Mxo<$)dJdzP!2XN&nKi+SMV3Y8$q! z@_cUZVO>A-`IL)&wi^!qD>7}ZVS6~a;7vvSd`r>l3JW`h$I`;LRkvB^#7N223Ghz8 z=y_|Y%C8vriO=n?)}HE>RA1-IdHGbNTm7w4r5}E7Pd`dbR+v`YwbS{zVc_RyFYYS7 zyrc9s$T)4mKK{w`st)?h$`5sTxHIEzOLtBEp(Xd{GklqSe}2KqN1R1W(*xOrvM-42 za5OzJCBf*#oin$mos72q-yC%G#h3O?-f_q4dHh{GWafQZ=$@GOqw@*#^NhQZErrd+ z4@*59RTZN%rW=(UWfPmwF8rN!$5o;0x;t+uy46e7JlkWaVXJ%f!g?E(yt^iE*X~*n z)yie3dUeku309H0?Rj6$C-+nx%Shl^FzeWiyFET(mVRCj49m2eCdPT0F!?e~UOFpi z>73~9v#}d$-#s&VG*f2QhDTGTY<#YCVB_Pz-^5!UGk;>N>8*KianJpiZ$Yt^E4o!N zdCE4K#SiyqoSq&$L51O4gF$_6%EH8cwWG;JAsuP-Pc<)Pt9k-bQ+qz%JcAQ!HI7M=!+obFzcUSot zUYMc~oUwB0qGevBy%J$f+xQ59eFeyo$|5U1=((?Q{DcQR^Z~b(ob*}R~ z+_Zk_9otOtuWJmy>Mq?8)Wq?*N9)TM!>r~*_vM$Lv{-5|nbqFs!kV{&)s_cB&GJIa zx)_(SOl0z&X}v*`Ca0Q=apM$_B5woL6`=f&D61 z-pNawIj#rn^XOlvFzdJ6!_3oFY0H+>zTZ-U|4qE(^$RmdL1^8$5|MTe^8cWE5MY zrQ3d`B-!`IuQ=Ue^v_K+Rp0r4>+!J7X-XdoCW-eoa>PDnZ#vy8VG{p)%E9L6vo&w& zHC>!PWl4|im&I3dJ1!q#&+DjDd%(NoYk`LTp0kJFS3S1u|Nm#1)I+IGg2pQGCpA@19frGIwd?{JRs9_OwiJ_Y{$v#1(x?VVA>_70+gHBq!TydU958(op}LXUF&B znR=e>+aLR(Ll87&Zx zmhU+I%SvrOhj)=zi4%qNkBZ!&O3RQ>o*+@T=aQ5f4&Bo+Y$QJ=_@Q?t1Pa z^V-EXB;qTQc=?#UZ8do8`Ry62!<)Y{%ycMRWi{FKjOoSZ$2aS^T&0pVlM{a3-(UBo zqG|So>*r*9(ij&6me_tM5;~mRe7R`1V?gnpe;c!U8qY8q2S^$T&DEUI{Hh^BERRe6 zr{E09X$_@}l7~8tIQeexj+}Mk+QN$mukGC_bm*oQm!`$>9_!+qPtOX&^CgY9xi$Rz zWjp=nCzVa}(_>fs&s4g3(EgeZo7%$Wh)((Tm=Evwv)MDSF62^CGItk<`frPQN^_k)`Zg=`I_m`g#79DH?#dG;ES|t58^UtI z*mJ$YLEgC@ZU$S5OWl3{mml!-PMz~|>NOFs_C-HFujVaZpK@a~slQ!^H zGi;Ptr84)_p~5on-kh`duPrb*a4Bn->%RDn9yNvvhgWuXoJeU&%g*xr_{IIe{{1TQ zdwk7PnJ$MP=I?sR4nIX0D%El7E zJ5C1o`s)APUXar?b;^zB_a*9N>X`dtWiKSuN~V3jz@;j(VNTTDCG4kePF;MLbK%En z^{jUs87dBc&uwn8nauYyevZeF%bDxTC!Jrv2d29dY$(Kyj&`Fu5;`Q481b??tSt$wI~kKrBb zonYwjw)y~nB1Go_^^ebPI=Cq1*j?&xuy;5J+6qsB(Jw7^-mDO=9I za6ei6ar4Kr{QLIr-cFt8=l|)a=yz+&=|<0s9=+B4`HDN^SKW!jpC3J|d6ux){Oh;B zdyDnd=WV}#JJh=H0N1k%uX~x(zBSwNtk}xCxzFfA=64qRfFMnAjji{+{ym;5mOSOh zl8rr=Qk(gC*2%Ro`6zfly07&1CFl85*S1eyzHtkqyY9kWMrV4K*(VmA{8;zwbiP01 z(O;E}55BUQrtgV+U$@}SVx_(_3c3V}PhGp6 z>&L=lQ(3H;<_EF~bw8V6; zv+VC`Nmny1nyIeMx#UR%n3tE;XI$K^Dyw|m#aL^~gx0B5 zWm`5gO9bEFL#u| z)k{psK~wsOk=vdH9NiB;Zb`H}R4n(Rb#hzv<#&%C?&awZPda`h?#O9wnL`}uB7qs1 zo4LM+WtJ~`ap8=nr^MPP65Bm@`)#|X7qECmSZHtO3s;eS%dTI!lK$U#+vR;9uDgEA z|E<0E((?(6#17|5>6Kj2JysxWY*}N)Ggszj@7={ya*rE%?b&nB;{BnYdR6Opzk57u z_u8Ge|9Wmr-okxDIgZKk_4!E0^=sz-`0jP9XThz1j2q*XwAck!ITWv6cQ3QP{@q0> zqZbpFt(x=j6PLWPt|u;+x-F^|gQGu*E9?~J~5a>}-~CWkvSK14q1@t@wi=Kgiviyuo* zsXz>No1)Dl^5xA=r}Uzm7yACbW?HQ`dE;7BS-brDW2cNJ9@PYeF$d3FnSx~g%;LjK z!f%=?8t=CeVVv@SrEkvh879>)bc8~}i`H^&dwB5aq(gicJd%|Tq>J8J_V=0IE?1cu zm#Q0bq+c^!*fC+r>&({^B10y-^EoHEZyrp#*RON{AJ^uBe&;M}s9 zJ^O|6PQSa?|6OOl^=jffIrs3Znd?!Ir-x3Chzh&8><=( zr`Zxkr`$A-REw=`A^$Z0|MEL ze3;bFs7P#T>2)}1^ZVn~*j@40!<6)9pK0A75^1(HWzO~Tkjzk(Z!J86}~AST$sEzDuhOaU93xLiPklY^H5GdwQP&M_*soh-L0QyiQ76J zU$G)>;bNUXE04%}8HDMcay*{8>ifs(J4%k1hECmNaqNW3&iK{?GbL6(*WYbWKK;j} zjHm^B_J5wVZPlAa7JCkT_`GhK+KE86N3PKuj^2BqUH_@7=lX>TeVK^oKPS343+j6m zX8yB&o8b}_sJ_c3)lut}1D|z?YERORxAxnQCY${IarEMBR?+7fcOOY=9rs-Kx|fx6 zZhNF%ymF#VnRejo^Z%a6c+|)4TJnXdE@`{c_w=j%*AG?r3ZGjQ`e{za4CSV32cZi) z9_e)?P5C`L`-@lWq|&+EidFT$a?hQ;uDQ@}rO$=GCgpD=UiqAxdSPjPchZzkuio9R zTd`^ut0})iXV8SQx|usqX0pM!VbG575MD?i39pL0J}*ZxrG*&CZ-JSWFJUcKvR#esv*V|lfWh5M@RNWO1Ap5$xyqww@oca@|x zkBKgJ!B6L=xbreMC!b|_ZTS2~8iS47if>|)Gey!*h|f(-FPL|^T53vMf7x4}c@AB- z&2pwjh|OE$a`^7VpAWJg6nv}q zg-&1bd~SV^S$k4{^Gdl6$%6vo6Thr8ez~asG1n39-rv2~UxsDA{%pg&_OXil@-qt$ zuHZ0Xvj0(dQnAP~O*JI2dsT@3)^GQ7V(

E8jKc@BM_e!Q5uEYc-?4uDJPhuHN1y zeKjwe+jl9m1f5~s5SsLp_kR9MVf!5qWi3*p_6W`RaORk5;f)zfmZ*wvWvF-Xw0M5a zviB(?vqf|CCn@F2?UTM-6@Joe{pC>QO$Rl;wZ$sz>N4xa$}dfv`1@-6>6xFLRVY30hCT<`2iLP1Hzs8$E zO9)n)-e+Ffv!*s<+MJsYYqpjg;(YRb&SrlLMwJI9(}cVW>FYF@IobXN=@_L(Z1CE6BKK$$pVJ=h-f*eIf`2A^=RJD#yXV_B2gw5*8cYF= zI~(U5P&u%;@i+5!_B@6=96Oj7u=cR}uC;u)HU?|uOFMagP1ETJ{PK9= z|5r5=A3JFTJ(}_7UEgJq-UX}yqLN=+%1#}j$UF$37(re#wn`rozE2G{eMc zf%~T&{h}wl`65eyH3YnHsL_zwUbw!nDQ{|@?KXoydseGz&S&U7mZusdQ@E>Z<&mhR zp@&a-MTRYQkM0lK=f-?CfHUAp?)|QyT}j)OB-Xo}xjuW^w4}lZ*M)@+ajC@TTP2%J zPcZwta?2C0>Kay-inn{VZM^8x;7?$Ga~&`_lVT4qxj5Q)%AR z@UROfr|tX9D!_WA(vIV^S5i;gX?D4*} z)A-iG5C+vg1VlMk+COkhZ;UQCqP_|;HLK%VRP!X}GScNMMce3}b*JU<^`(0F$1uRy8a+peyx{o>N$ z-B-kouDnvsd?*@txpb|1o2qM3M`7vGcze$7;J=q&7+g{i+NPO%bdt70?ytrmo!!by zBluq4T()+FgvFBQ-R1U2c33eqy=ck1ZRQbGV540l;C6_^P|qT=lkL3FKl$f#>vKQP z&fQZOde84kY$vOE!k4xL`<-``t@k}_IRE!i!`}TrySH9*dcR=)LnfbB=TfD;H*e_` zS{Hd?^XFez=f0a)me=nWtEHy?zwu76ac0iMtAdkboT5Z;K3T2Mu&pXj_)}2tns+m5 zwodVpHd0>qZ1UvEzHGt@2aj$EE&jeUWZ`xBGV_Z<3L-)$nkFo_DOqx0UdfSFC02_< z@@7N_2~B#i=8geF*UfD+0$mJu^LuUNSUu~)wIiusZ%=dRv$gvEUm9l&0_r^KCa;2O&ittrO) z%0}S${YQWPJY9S9BX70z)wrqe8q{l5^VO%_c-$z_|9(+Gu+P=SmHU@1OWGavIm`FK z-&x_WGqbY7rars+UHjJ6S>NMlaJw<&OpOru(N{OI`~0^z3(A<<3NEdr{kYo2> zffEwd3p_8yEUVMxFK;e%sO`Q5s?OLvIpY1n4->B^R%5JIpDTky&b@2mXU9D2b7B+vKwP(tf*MWvT&mLTsIXY{ak<|9j z5%XJQPfm|X-Wa`d_3DH+m91A=HJ6-u_?Sic#uSCiSC4Z}ZP;EU%(VG1gT}jCjy(>~ z_^x;yD>y#g3J+?4U^p^`&!V^srWbTxEEdSF37v3uuc+Q^?*@;SuCn~SRpzhEu8Zy# z-FU))FRLIlX{A-cYT>@(pMi>IDLE_qc51I-oWYVg`|VAGsY#t(Z?rts=T6#pifgWX zLWEaT=}Lub#UCZ3o2HUY<8`&1ak2*Dn3o#@1T; z`>eJ5d>xy}&JWEc)8*ZtXH;*sS?o4V{6^k|1)r|3ZjSpKvp!Ja_=@hT-amI%1g?L_ z2FQ;_0XzK6<@b72 zEz=8`+1S?6G@+<9QKwA%Z^?fhh4h`1dGGE5RTs<~4oO}6tu>`*ja3N8)#497<;=Y+ zrSjg&@I|y1scBS~YD|A^y+=nwyYa!V*Mbgh(;4--8@vyh1h$JgebuR%wW>`^I7;sN zyH(5^x>Y?4N|%RKcm<0EP4h9BvwG)}10v_x4RtivS}hUq+WaANmBhMjzZ~yO+hkW9 zq+A%-@1^i%8;g&?B5uv4JH>A%SD$J~mTdgCY3&(D*B^FP?lo^786V%tIG0;VH?ZsF zM;FtEo{3s@C6{bf`rr+}l!o`x(dJTl2l% zn1~cEcys*NL)$M-;nRgC@+LjLWUF{|Nt5@R48@B31!q2_q)YZ?`yD9is(sSoE4Cn} z>9*9Yt!qx3JoM&LG~u4F)$?nArsTYc{blC+6uxHjFH%%hl3(&KPJ8X`wmarBz3!4P zT=I*=Vm;;_cQ@?|I3v7IMc#@3!DW$Mr<&GDYihd+-$=JK=xCqP(XycMcEa@LfKD+_ zdykVL-7Z`lDJ+M>e_U|dFt62rUDA#lujcL0&8$6^^8VJT#nZ}l4?Ny`{BeS`nHMXPldKK-pMno=&IHCGiLqN%=|q%h*4hY`r(j z`PaI&I&I9FOwN~i4=icfvM1Bd!@j}4FG=H&c9nyt)vIIs7OrK}OWvL|f5Pwb)!t@| zJqZyun;xbx-`Vwq(}1(>=+d{opBzi%?e0H0G*!7U+UQ%%2ZO`6>?FjdPZQT=dBy(W zWMGN7-uq_Az~v;tJsEZZ_uKvZ7HwU3F!@bb)QMt-_l*l*a!IuEnKhQk+gV-^NxUtw zV(J2m9p^HSaI_u2e(f{kFT0vep@(k<{p*T8wkMcFcV)+}Q0DNUhiqHjmbEP0sPS`x zOv?w6vnPY%8gGBPR?Qmxi(_H*^3~s@cElVrb!UnY?7Fp0?AboW1wt)rW<-@r96j3= zyLrXyBL=GcLQbp?7QN`#jVbavvu9oL_c-6?SAB7&&de{AU*tG^?{;4r{vd5p>5MzPP74Zl`M883bv{%EhdU(4&$Dkt=J@~%jj5McGCZ1IV; z4Ghc&w=h+ePQ0?^!NzFIA19a3n7{4s-P8sh#Q;GK_5+Je3+(cyx9&cy=~9~3G`p*5 z>K*ki-sG#N-#$!RI;ERyd%>&wx8IhvUv)d4l%31J{e)7o$G>|VrUx9f>W&vyb@wmn zv~}$0YPzx2|6%FuMH=j>Eqdm6&z_sOW(t2Si>&6HW!b7z{8U#gP`<6bdg{d+QNLeJ zRO*)cyLg!v>r@Yi;JbAP6t>@fd+EXI%w~p6E{nZa?YVYaw-(F)mQ5GX%G+(tHT7be zi@?SezuLrQB6kSA?_Ixa{i@YGzU|p3dtSV^;96^YrG%;Ig2LwCeg}VMlpmMOzRW2U zBC_O(-Q}k_7HyRlT3M@PrYtM4T<0+HO~|p$qFRouA^PX-j_r6~^GHd_*+z6_pX}s` zVHV*^>y555Zkxs;JbhzyA?t*XZ#KL!*)fOdoZteV#LLUMg-%KJJ+AQWT<*S7W=fyi zRfV-`y<4B$QrYg}x^rvxd?s`2l{-aON8OLGIBs`boa5NktzPe%{w>UkJ-*uPKuJQ2 z-y>6#6{e!5)f_q5wNW$n`Q%NF09 zuAInZD|745tBC#!9^vAw)`9aSmt5O=+|}Uq940S+y%~<{@@r#QHlNd6(3H|9`Q)O^ zg(ufnO^!QbwY-7lb}+-U{@KC`7J5yQ&wcwA=v=p}66op6ojLDpVn)oZa$_$?Wsdpm z%d0LuUdPPR6x(@xYiDAPUw7~_6}$P#F`wq2=x}flzH{UK6mF)*1sbi1IaP-^=l$ei z-ps+o*vsK`sk21=Zl0ygFYjH%T5#LN48q6?Q&ngH}2R!&fB{g)3@$Z66ys_Hj)4M0)0(PAu8w~unJU#tU zr{~Gy=Bo!Cr!>xB6S}S1=KsiGgHqT-fy@q7_4jt)ruEBl?O7E0;xM~;_v-S$vvs9E z9$ap|x}xFkVRhH2bTh>~#|eUWf4)fQERal9=x(cFdn0wDL3vT<+XGz_x8AOObLISW z{lg-Q?(ybti|OOHzq{;FL-eyTYL0hk*MgOjk6c>2kKSEX518*r28Uir>f&UW|xPPpKURSaFKjrkfy42 zVD5s_sf{|X7kzqvXA|QI=_Pe6DSJ0`7zJ4EX_VkDnc6sm$8F6-rR&p59quW7RaSW2 znm45}PcHI>)XsG2ovIlb5vdBVL%#o?wy*Jg`oVx+qky`a2fQ}PT|QGAmo!ehdVsan zXh+)NtT;2aA6i{A7Odhqa^ymusK>i`+w|73tP@}1Ch3tgm1D^^2i?8R8+2A^F&i4* zVO+;>^6vD8MHAT9v@@D991YpP^_FM0SBZ;9#RM(p(7e`5d>y~^CC{GO!1hO^<*@nT z;(C!yG5Qxej4u3Y$$$9bf+CxH)a7N7DN`pbJFsecNx@4Vxfn^QFv$~IrusR*bti}~ zYe{+iFvzKDp)ycWmE$|Zd{)LlHX&KopbMWEzO@(r{3YK!zd_yR=8-9-*Ya{S8h$;U;&Nec zn$!-HMLa6<+D?j~3Wu*M(=Z`p->)@SAFO@0Z0>Ak;a?v5CX0APSVhwL&sUfo$f|7P zk9T_5u->`HMbblpZ|PbopLyqPPt+AQ1!%Zj4%SGCJnGJ|hDAW&y3EFl@(14(npY@K zzE+_!zbVAVBBblXY=#Mo6=QhLxoEMe9k3NmG_K^cIo-B!@nYfW@0rD)NXgE97$&c} z&S=7g4ArKe(r>-kjWho{S1lAuUBF-egC}^&4F`rLryO2u?b&>&c)~VQp;U#$9~zGr z-fWxBEweB7a@);~H?BR)Nen1zuN&>e%luU zi=S70@?3BJKR@67N&UO?>OFN+%^TYPF-mP>Ynu4Q$@G-N{3%D}J0>$ExG@B>P2y#G zw`0T0#uZw-S@A$5&pXV%PQCM`v$+Ryj%RgY~9t_6Be=?PJW&0 zSJdlZe#*iA_H_2|mXeakoj^e>!)72eJEuam{_VDf&f50>{>1#>`*FwGcD}ipdSqOCnwECH z=QdOD6rn=-IX^eoavhzso%4^ag@pE>6D=%%$EF-J|8Zv}JEP4!3N z2Ld-pCaF9)Eu|OZCh0N5F=m!g^|AUX+Ij&|N6*Z$s{N>B#PM2#d8fb!{dt;C_PAZN z_h(C#NmZE6ApfV>z>bO3ZfQ!I>!vj8O20bs z;Rbi{T&X$-*(8C(yE_^RW~`s~{7zo}@BGyXw!h~b|Nnp0abv-@xQi=Z=4bor>=aFZ zb<+1&Z#CbXO`gy1Ifxhi;{4lFBKAM$&cfwqn!X*mSs=Mvw9p_WVVU?;_q7ti$$1yD z&rL7+-Y(_C{^@vUSz$?GXMGOuy|>r4sfGRWE0@0^ZvLjbyyYnG@%sIW20yMjsW>n! zxU@{zYw4D^>DjuL!Rcm_J4!`2sce5RSE@3vw)c3@xlcCgv9U_o&AYP#vK5-PobH+R z=Ea4Oid8u;FX+n2&UDlLzQtWZ^--GexhSJm=VBJ$Uo+*4Pmh*z%$l6+J=a&>@7q=9 zzx?Fxuu4CZGuzufx~Ot&@rhcu?q|Gn=p7I5l~N%xN&DFY*%+6$UT-p-x}hX~&zIKj z6}PA6bx+repE8-rC4f^tBkS|-2Ui_V`s|qUVD70(zvgSjRnzl76q8seBui=TSf2T6;auMW_=&mY07vgj;UwF^O?iIIBdM`AxTM#~5{pE%y z*?WRj&u1>N-X?DTWBy&vJ6lZ+;}$#5;qBiTEhtic;Fx}M>i_&>DYZ9G%quy@y3EVE za#0#fxNyh~qeXHY0&cU6&eq#JHI&OcXZAI2W|rOQ36kvpUS`Cpaz2x*DBd7j`)vK? zx?PpgGdWgNa`*)=<2Tr9$n$V}u1@5t=Q|h7*Xg}{m;LJJKdff+?_SK%>Mz)IWM{ne z=_@Na)`exBKdZU#vF!U3!m_E%0_k1RxA!=gu6;H=n{l>KvOt2)tIktbKDgYfRgyVv z{xxo9kM73#pWO6SUhRGO@y?N5o%XTfdwu^nzp?nea^8oE#p*&A1$m5L&K2VI4~d(z z!sq?{)n^|!RV*m;d0;2KD)-Z#?}r-G5^jEuIXZE5-ctRHq}1K7IMl6quNJ<$-n)h8 zlzLsm(rpQEj$e)8wiR75+n`yCF}&f88AG(Y&Ut>M{Pm|lcP~V5nDX@eb?(^1pC-p%5d1PL=E|vQ+LwRNUNuwEpklTC-jx?U zb|~My{^QL1+Y&La<@Vh8zWwUj?QwP`W{#U@v7RVmF4)-^9IU7tvB{3b`PWOn zIhu7_BRdt1`Enkr86E9zt5a>C!Nkb-SH`0vp~P45Y3zljYRkqm&L0F)tMpHq5gBpQ?Yl?evak9nP!;TRm#(y?wp4<*uYG=&X{;Gu_7U zknKUeKn?4Tm?u{hY^F;vGcLiLXeay|{b2hMWrV+vv8ll=8^ z&F7^O7I7zL>V5e=dj(6&lu5lAdaJkGxhJwTYI%ok-q%Cxr@lJ2w~F(+q4JZT|KhUJ zcTHmYvRpXeN{Fg|)GWy}n|beb9&kA>65f5|`{pZpvAd>xSuMOQHf4(O%SG!>crZ@b z&Y1sUKmYKza^p2twT?-bpG|7`SHiR^;P%c| z%}W=qwK3@0T8H16WB4t-d$#J~TLP>+`)ix_u-=f*VW^w+K-+=gugQdm{W4{0wJ%RS zNSr9}GD32Wv>L0@iM`)mNd4P*d3ye=N0U#9d{ygNY5G1nOEvbm+(h}8e(DM$^|CYE z9TGJ)=Po|js&YnsK`xsw&+2|DPn`wg++NP!vCM|EHnL5VIyo~do>6PzTGkoto+kVD z)H5pjN`z+LJ06lN^i%b(XOwW5^wD2D5m!Q<8h&8sd1cRWMAD;t*R>@ahr_-cx~h_S zeOswv_!Q08=8~6U=BmhTdUj4&WJBJQRgzKZMga?S*H7TLG5VP_wan^uiRP;-ALVj? za=rahKT-VL#a)}G*H!98Bnc=!dENi+7fi@T@8EQl#RVjem?p?v-s4TUB6C*LlG3!GUKjvC=#4M#wQX$}5c+3-KdCJowkpm&b9LFWIl-l z{ehR)uW9kp?9Y8uhcg;35^D?r)xKQ@awPDG%e$JhA*ccPxof$Y1p)S@wq9xLxcAIWSZf( zKjh-Uc>N9r&Kc4(*iUf1U^HgpXIaL!jNu)#4@U~)J02S@js|17@298ubm!kYcl$%1 z@T(tB&Xg-U&yQw){MbEkL(_U&|Jt32*LB`8ty$?94c-_aD&cm~QhtBv!h~F_7Bz+< z#?OqwOv|O1EE~7i*OqWDkVs&d!JKyB;MB%f2h5xfuoke|H2yk}9rs=Rh?PTN4Lg_r za`A&5zlxZXZ%KhxUTNfbW)?g>mK*Qg`q20EYxVfhnT-4YhvYwqzW+bRJOp(YvpfeHu?3XL?BQ&V4Jz${Ek>5UvKVH51Bv^E=8*MOk1+ zRQ^w?f7$FZ2Hf@^4m{yG5WRfcWmiasi z;EJ*Ae4ng&+cEL)iMUAx3Q>O>=Oh?OaZTLve@&g9`KRd#+An@2$k?uFEJ^&w*ve^G`|^Ja`}YJ5NpJ30KDoiJZ%3 ziVstByC5?4IJrAT8osYL(YG^;LV=8Hc1dAu(5; z@>v*ct>Wa--*8R%a1on~M34E0;H|fQ-EJ^V_MiUDQ$UnC{J_gyv72Y`#)ND+G*$R_ z+_a|8y_br&OR%=sD)ef9ihav-hDrNs_Zp2>&m$51KPKN{WEY#>SyIusH2Z{J`hiCN zjLBMQoqL0CZ}IhA7N);#VVH5g6@%Y(!?Zy02bSdzP95sjHu}seVCJ22jOBsUl?FzI z%ghDcx2M^azthz!oKnb8+;h(*?Vic;jJo&cE3a?)u4~kO{ztIcD)Fc<0SUY}&oBCR z?*{YC^asupRAp_4px27o>$20tmt6A|(`Nd7f7Y+0D8)o0% z_hr)laAQ7&tF}3-PTGArAz~RIKYQQwiLczmYzx*a?w(bUn>T=h` zFix2<`ZE%QxgOVhlrbb8lQ#>xo90t$ z&(;+4=JT`lMnQKktXj2!*YMwp87t;5xE8ZJTWl-ix6HM(B{oT>Dj0s;BJzZ3;*_ru z#Vd2Kr^)X1oF%>dm*m`7*_~1>`BSU&%aG3Rf>a*QH{~xJT1qfrqNs7o7)nw_QImJ$Vb;7 z6)n(QY5cnVtm>Zw=MJo6Z!}~HV_)>lzpD3FuW7GlOP1R=A+Fy+m-?qo<}E#@bxh~k ztsl#0rh6ycXg(mp`%uc{g}J?6%QT4{rVI3SE0^DWy0}d}nQ_^YWq+1G_1W8zyWS@w zd%^YQ0~c1wUMZU)$Z{;=$NRo)iC~Vi_K}ftzk)8u%~=uZAy>q-Jmkd+<>&L)+`Gs+ zwPwG2d^Gb~ITkmalY%U2e6}53JDYRgYd76_IysMj)hC8KjHM~TFB~s<6|9kM4B}@B zUMf6$ZPkIYRo6VvHv4(BoNniF>{T#ubL#K8@bOeuZ1LB1C-=^pU8VWjepma?)88DH zvNzW91f{Sv8j4h{S+Jpn`%ruL|HXCt4{n~fuOy?jf7&UvyYAl$Y8@A|H!A-3EpmIl z@oZ=Rsk2c}Bb4P5XW#aYd42KPwG$jn!S`$I+`N}xX+3JX=E-lH)kT;3Lw4{SiRcYu ziDv4RV`(cY%=s9$#&DUbUHn4@Mvoo^gGK>AJwuHz3I?fdOzaG8i)0K;&OZDs>cGU) zAn%xHTBe6yP0Obifw!*Q%yK*Ei|%qi=~pQf^fNzSefvW^LlT#h`N z%u^wlyTP620}Z?;jop&>_Z?+T)?t|S!r=r5lkkkI3q?-IMPK5~<+C)rT-5Pa zRpPKM#~R10*BG|c?`oXUpU)^|vchS)9`BhTt?8=48OB&9fPk+H8%5T(k;LW>+88b4AdOpgrvZfhs6GbWzLD)^aJ7ibl{-}`)S`8}mx`#<-(&OY1o*`aMNV+_-x8#f&K z6%4Gce(p-D36BIR-t4&B;Lk%dGf^H<#tGYR-cZn7;4TosJvS1RUM|1((Kfkk%y2z6 zo$Jqr%%UHEY!u29vbuT{Hi-EKyl_ldb|7%^q}$0G&x$}&u&HcCc7xVk-H?{qH*Z;3=`p3lBDaevG ze}n4#{-u|j4?I}%kb}v(dyTxP{rioIzxGG%mynv2pz&2wZTqItqqOyT)}Kor23x8GBsQAJIwm|RU_0_>j>zL1%oAU5 z8D8SuE61{o?N5f1+9hR<9--@#bNKEqm1V3JxUuqmaB1un?m1;Yv;Au4uN8<3fAQ7z zOlyg90zZ?rXx(kOs@lLyf*aTySE?Vfu3No!8(z<}PP-m% zVsG4f!STS2wGEU1+N@mjp+WeYO<6*CwBnw14?fOeiM^3{VEWsKOV*Xm6fwWBRnUUh zD!%J>7{_|;KgRD4nLXZSxnrp;WAb(q0^jyQjJa9OeE=q9JY}D{?hv6ffS*AJOglp@gaEprULb z8`t8VXWXmvb!HR?d}j={(g;Xdw)&XF3Xfc#)_}A}W{H}bbAPTd{T5&?HshQI^Ui4# zChm9!nyd_y;kDpuhN&-m&jgRB?Kjwfd^JTW4JV+VSRrP;=GS|A(Gd6SYU@5dDA|$ujNp*$7v4%Ulugv$IZtz**>Yqv;O_2aOC!tF(4G%9?JE?Z! zNze-?f2%E*Vp}4XTDf{u9?DU-5*Pfsqh*K5Ht(IEXU%yOz9eyf!=c(IRxStXvzFT| z5q&mmrEG6D-`1u@%ZguK(>xIax~Q$;r!(7zPu)dVf~|%1C3TourW~DS6)W^;eUSax zM}MXre{7i`rFrLdiq2N~VD8kSbw!ti0vnI7u1jeoVL}O_wvTw%-_ME^LlgVE)siq;nR-CDGtvSTEiWca+%mGR;}M=zJWvHLR!w8 zSE72BfnH8Q>vmd+77P2jhPc69eqSwChJ}Q%NvNbD3a0BDC6)TUZs(X1d zxaJ1$Ui)SDOVOQ8*LyCddwK5f*f8BH*m~JvnIzWL4BP#q=3Z;|?KTofPI$ISX~S8! zit8R)lUD8*zvQ*7I>`C*xs?a9e+Tm>B?$5?csVJ7FXndH&ah8gpKyI&^->gc|DC+m&7$^okkJcp2?p?__N?F(Hkap+RzumPwW71PH>=Ll_nQ1q374oTipwe ztLiNZ72Cerr)R~hzl*QN9u&CW#XNua*@T&|R&NnMxWIej`>4Ht*w2{G6V$pIURj-= YlRtBjg=yNx4OLU?U)s-}b%31#01Kbx`v3p{ literal 0 HcmV?d00001 diff --git a/doc/qtcreator/src/editors/creator-coding.qdoc b/doc/qtcreator/src/editors/creator-coding.qdoc index b74b3b627da..7a16271f12c 100644 --- a/doc/qtcreator/src/editors/creator-coding.qdoc +++ b/doc/qtcreator/src/editors/creator-coding.qdoc @@ -101,16 +101,6 @@ You can use the model editor to create Universal Modeling Language (UML) style models with structured and behavioral diagrams that show your system in many ways and store them in XML format. - - \li \l{Editing State Charts} - - You can use \QC to create applications that embed state machines. A - project wizard creates \l{https://www.w3.org/TR/scxml/} - {State Chart XML (SCXML)} files with boilerplate code that you can - edit using an SCXML editor. You can use the classes in - the Qt SCXML module to embed state machines created from the files - in Qt applications. - \endlist \endif */ diff --git a/doc/qtcreator/src/editors/creator-only/creator-scxml.qdoc b/doc/qtcreator/src/editors/creator-only/creator-scxml.qdoc index 93ac2b8de6e..35d67048d75 100644 --- a/doc/qtcreator/src/editors/creator-only/creator-scxml.qdoc +++ b/doc/qtcreator/src/editors/creator-only/creator-scxml.qdoc @@ -1,4 +1,4 @@ -// Copyright (C) 2020 The Qt Company Ltd. +// Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only // ********************************************************************** @@ -8,11 +8,14 @@ // ********************************************************************** /*! - \previouspage creator-modeling.html \page creator-scxml.html - \nextpage creator-building-running.html + \previouspage creator-reference.html - \title Editing State Charts + \ingroup creator-reference + + \title SCXML Editor + + \brief State chart (.scxml) editor. State charts are a graphical way of modeling how a system reacts to stimuli. They define the \e states that the system can @@ -22,121 +25,126 @@ \e event, but also on earlier events. With state charts, you can easily share this information. - With the \QC project wizard you can add \l{https://www.w3.org/TR/scxml/} + With the \QC file wizard, you can add \l{https://www.w3.org/TR/scxml/} {State Chart XML (SCXML)} files with boilerplate code to projects. Edit - the state charts with the SCXML editor to add \e states and \e transitions + the state charts with the SCXML editor to add states and transitions to the files. Then, use the classes in the Qt SCXML module to embed the state machines created from the files in Qt applications. - \image qtcreator-scxml-editor.png SXCML Editor + When you open an .scxml file, it opens in the SCXML editor: - You can drag and drop states from the \uicontrol {Common States} view (1) to + \image qtcreator-scxml-editor.webp {SCXML editor} + + Drag states from the \uicontrol {Common States} view (1) to the state editor (2). Select a state in the state editor and use the tool buttons (3) to create a transition (4) and its \e {target state}. - You can view the state chart structure in the \uicontrol Structure view (5) + View the state chart structure in the \uicontrol Structure view (5) and specify attributes for the selected state or transition in the \uicontrol Attributes view (6). - You can use the toolbar buttons (7) to execute functions such as editing, + \section1 Navigating State Charts + + Use the toolbar buttons to execute functions such as editing, zooming, magnifying, navigating, and panning state charts, as well as taking screenshots and viewing statistics. - To zoom into and out of the whole state chart in the state editor, select - \uicontrol {Zoom In} or \uicontrol {Zoom Out} or press \key Ctrl and use the - mouse wheel. To make - the whole state chart visible in the state editor at a time, select - \inlineimage icons/fittoview.png - (\uicontrol {Fit to View}). + \table + \header + \li Button + \li Name + \li Description + \row + \li \inlineimage icons/snapshot.png + \li \uicontrol {Save Screenshot} + \li Saves the currently visible part of the state chart as an image. + \row + \li \inlineimage icons/icon-export-canvas.png + \li \uicontrol {Export Canvas to Image} + \li Saves the whole state chart as an image. + \row + \li \inlineimage icons/zoom-in.png - To view a particular part of a large state chart in the state editor, select - \inlineimage icons/navigator.png - (\uicontrol {Navigator}) and move the navigator frame on the part you want - to view. + \inlineimage icons/zoom-out.png + \li \uicontrol {Zoom In} - To use the magnifier to zoom into a part of the state chart, select - \inlineimage icons/zoom.png - (\uicontrol {Magnifier Tool}). To move the magnifier tool faster, press down - the \key Alt key. + \uicontrol {Zoom Out} + \li Zooms into or out of the whole state chart in the state editor. - To pan the state chart, select \inlineimage icons/pan.png - (\uicontrol Panning). To increase the pace of panning, press down the - \key Shift key. + You can also press \key Ctrl and use the mouse wheel. + \row + \li \inlineimage icons/pan.png + \li \uicontrol Panning + \li Pans the state chart. To increase the pace of panning, press down the + \key Shift key. + \row + \li \inlineimage icons/fittoview.png + \li \uicontrol {Fit to View} + \li Makes the whole state chart visible in the state editor at a time. + \row + \li \inlineimage icons/zoom.png + \li \uicontrol {Magnifier Tool} + \li Zooms into a part of the state chart. To move the magnifier tool + faster, press down the \key Alt key. + \row + \li \inlineimage icons/navigator.png + \li \uicontrol {Navigator} + \li Shows a particular part of a large state chart in the state editor. + Move the navigator frame on the part you want to view. + \row + \li \inlineimage icons/statistics.png + \li \uicontrol {View Statistics} + \li Shows statistics about the numbers of states and transitions in the + state chart. + \endtable - To view statistics about the numbers of states and transitions in the state - chart, select \inlineimage icons/statistics.png - (\uicontrol {View Statistics}). + To search from the state chart, select \uicontrol {Search} and start typing + in the \uicontrol Filter field. The search checks the whole SCXML tree for + attributes that match the search criteria. - To search from the state chart, use \l {Search Results}. The search - checks the whole SCXML tree for attributes that match the search criteria. - - To save the currently visible part of the state chart as an image, select - \inlineimage icons/snapshot.png - (\uicontrol {Save Screenshot}). To save the whole state chart as an image, - select \inlineimage icons/icon-export-canvas.png - (\uicontrol {Export Canvas to Image}). - - \section1 Creating State Charts - - To create a state chart: - - \list 1 - - \li Select \uicontrol File > \uicontrol {New File} > - \uicontrol {Files and Classes} > \uicontrol Modeling > - \uicontrol {State Chart} > \uicontrol Choose to create an empty - state chart and to open it in the SCXML editor. - - \li Drag and drop a state from the \uicontrol {Common States} view to - the state editor. - - \li Drag and drop child states to the initial state to create a - \e {compound state} or use the tool buttons to create a transition - from the selected state and its target state. - - \li Select a state to edit its attributes in the \uicontrol Attributes - view. - - \li Select the transition line to add edge points to it. - - \li To raise or send events, for example, use the context menu commands - to add executable content to the \c and \c - elements of states or to transitions. - - \endlist - - The following sections describe how to manage states, transitions, and - executable content. - - \section1 Managing States + \section1 States When the state machine enters a state in response to an event, the state that it entered becomes the \e {active state}. - State charts are hierarchical, and therefore states can be nested inside - other states, to create compound states. + State charts are hierarchical, and therefore you can nest states inside + other states to create compound states. - In addition to basic states, you can create the following types of states: + You can create the following types of states: - \list - - \li \e Initial state is the state the state machine enters when it - starts. - - \li \e {Parallel state} has child states that execute in parallel - and are all active simultaneously. Events are processed - independently by each child state and may trigger different - transitions for each child. - - \li \e {Final state} enables a state machine to finish. When the state + \table + \header + \li Button + \li Name + \li Description + \row + \li \inlineimage icons/recordfill.png + \li \uicontrol Initial + \li The state that the state machine enters when it starts. + \row + \li \inlineimage icons/state.png + \li \uicontrol State + \li The basic state. + \row + \li \inlineimage icons/parallel.png + \li \uicontrol Parallel + \li Has child states that execute in parallel and are all active + simultaneously. Each child state processes events independently, + and the events may trigger different transitions for each child. + \row + \li \inlineimage icons/final.png + \li \uicontrol Final + \li Lets a state machine finish. When the state machine enters a top-level final state, it emits the finished signal and halts. You can create final states in compound states to hide the internal details of a compound state. The outside world can only enter the state and get a notification when the state has finished. A parallel state finishes when all its child states reach final states. - - \li \e {History state} is a pseudo-state that represents the child state + \row + \li \inlineimage icons/history.png + \li \uicontrol History + \li A pseudo-state that represents the child state the parent state was in the last time the parent state was exited. Create a history state as a child of the state for which you want to @@ -147,13 +155,18 @@ state that the state machine previously saved. The state machine automatically forwards the transition to the real child state. - \endlist + \endtable + + To create transitions between states, select + \inlineimage icons/transition.png. + + \section1 Adding States You can add new states to the state chart in the following ways: \list - \li Drag and drop states from the \uicontrol {Common States} view to the + \li Drag states from the \uicontrol {Common States} view to the state editor. \li Select a state in the state editor, and then select the @@ -165,13 +178,20 @@ \endlist - You can drag states on top of other states to create compound states, or - you can drag child states out of their parent state. To move child states - within their parent, press down the \key Ctrl key while moving them. + Drag states on top of other states to create compound states. You can also + drag child states out of their parent state. To move child states + within their parent, press down the \key Ctrl key while dragging them. - You can use toolbar buttons to align states in the state editor, to adjust - their size, and to change the default color scheme. Overlapping states are - marked in red color. + \section1 Aligning and Editing States + + Use the toolbar buttons to align states in the state editor, to adjust + their size, color, and fonts, and to change the default color scheme. + + \image qtcreator-scxml-editor-state-toolbar.webp {Buttons for editing states} + + Overlapping states are marked in red color. + + \section1 Viewing State Tree Structure To expand or collapse the state tree structure in the \uicontrol Structure view, double-click a state. @@ -199,9 +219,9 @@ \section1 Managing Transitions - Transitions define how a state reacts to \e events that are generated either - by the state machine or external entities. When events occur, the state - machine checks for a matching transition defined in the active state and + Transitions define how a state reacts to \e events that either the state + machine or external entities generate. When events occur, the state + machine checks for a matching transition in the active state and moves to its target state. To create a transition from the selected state to a new state, drag and @@ -210,24 +230,24 @@ center of the state, but you can also draw a transition to the edge of the state. - To add edge points to transitions, select a transition line. Only two edge - points are permitted for each line, and unnecessary edge points are removed - automatically. To remove the selected edge point, select + The editor center-aligns transition labels, but you can drag them to + other positions. + + To add edge points to transitions, select a transition line. You can add + only two edge points for each line. The editor automatically removes + unnecessary edge points. To remove the selected edge point, select \uicontrol {Remove Point} in the context menu. - To add new edge points with a mouse click, select the \uicontrol Transition - tool button. - - A transition label is automatically center-aligned, but you can drag it to - another position. + To add new edge points with a mouse click, select + \inlineimage icons/transition.png. To remove the selected transition, select \uicontrol Remove in the context menu. \section1 Adding Executable Content - You can add \e {executable content} to a state chart to enable the state - machine to modify its data model and to interact with external entities. + Add \e {executable content} to a state chart to enable the state + machine to change its data model and to interact with external entities. Use the context menu commands to add executable content to the \c and \c elements or to transitions: @@ -236,7 +256,7 @@ \li \c to raise events \li \c to communicate with external entities \li \c