diff --git a/CMakeLists.txt b/CMakeLists.txt index 187fccd493c..4da4284a495 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,10 +68,14 @@ if (Qt5_VERSION VERSION_LESS 6.0.0) endif() if (CMAKE_CXX_COMPILER_ID STREQUAL GNU) add_compile_options(-Wno-missing-field-initializers) -endif() + endif() else() # Common intermediate directory for QML modules which are defined via qt_add_qml_module() set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml_modules") + + # This includes the code that will enable higher compiler warnings level (/W3 for MSVC, -Wall -Wextra for GCC) + # This is controlled by QT_COMPILE_OPTIONS_DISABLE_WARNINGS target property. + include(QtCompilerFlags) endif() find_package(Qt5 COMPONENTS LinguistTools QUIET) find_package(Qt5 COMPONENTS Quick QuickWidgets Designer DesignerComponents Help SerialPort Svg Tools QUIET) diff --git a/cmake/QtCreatorAPI.cmake b/cmake/QtCreatorAPI.cmake index 3a056ee7844..c4f8d1f0a6c 100644 --- a/cmake/QtCreatorAPI.cmake +++ b/cmake/QtCreatorAPI.cmake @@ -233,6 +233,7 @@ function(add_qtc_library name) RUNTIME_OUTPUT_DIRECTORY "${_output_binary_dir}/${_DESTINATION}" LIBRARY_OUTPUT_DIRECTORY "${_output_binary_dir}/${IDE_LIBRARY_PATH}" ARCHIVE_OUTPUT_DIRECTORY "${_output_binary_dir}/${IDE_LIBRARY_ARCHIVE_PATH}" + QT_COMPILE_OPTIONS_DISABLE_WARNINGS OFF ${_arg_PROPERTIES} ) @@ -485,6 +486,7 @@ function(add_qtc_plugin target_name) RUNTIME_OUTPUT_DIRECTORY "${_output_binary_dir}/${plugin_dir}" OUTPUT_NAME "${name}" QT_SKIP_TRANSLATION "${skip_translation}" + QT_COMPILE_OPTIONS_DISABLE_WARNINGS OFF ${_arg_PROPERTIES} ) @@ -667,6 +669,7 @@ function(add_qtc_executable name) CXX_EXTENSIONS OFF CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON + QT_COMPILE_OPTIONS_DISABLE_WARNINGS OFF ${_arg_PROPERTIES} ) if (NOT _arg_SKIP_PCH) diff --git a/doc/qtcreator/src/howto/creator-only/creator-cli.qdoc b/doc/qtcreator/src/howto/creator-only/creator-cli.qdoc index f8356b86d5b..3fd118a9a5b 100644 --- a/doc/qtcreator/src/howto/creator-only/creator-cli.qdoc +++ b/doc/qtcreator/src/howto/creator-only/creator-cli.qdoc @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2022 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Creator documentation. @@ -113,6 +113,10 @@ \li Open files in editors in a running \QC instance and block the command line until the first editor is closed. + \row + \li -nocrashcheck + \li Disable the startup check for a previously crashed \QC instance. + \row \li -load \li Enable the specified plugin and all plugins that it depends on. @@ -122,7 +126,7 @@ \row \li -load all - \li Enables all plugins. + \li Enable all plugins. \row \li -noload @@ -130,11 +134,11 @@ \row \li -noload all - \li Disables all plugins. + \li Disable all plugins. \row \li -profile - \li Output plugin start up and shut down profiling data. + \li Output profiling data about plugin startup and shutdown. \row \li -pluginpath @@ -151,10 +155,28 @@ (for example written by the installer). \row - \li -temporarycleansettings + \li -temporarycleansettings, -tcs \li Use clean settings for debug or testing reasons. The settings will be deleted when \QC exits. + \row + \li -test [,testfunction[:testdata]] ... + \li For \QC plugin developers: run the plugin's tests using a + separate settings path by default. + + \row + \li -test all + \li For \QC plugin developers: run tests from all plugins. + + \row + \li -notest + \li For \QC plugin developers: exclude all of the plugin's + tests from the test run. + + \row + \li -scenario + \li For \QC plugin developers: run the specified scenario. + \row \li -color \li Core plugin: override the selected UI color. @@ -171,7 +193,7 @@ \row \li -notour - \li Welcome plugin: Skip the UI tour on startup. + \li Welcome plugin: skip the UI tour on startup. \row \li -debug @@ -208,9 +230,13 @@ \row \li -wincrashevent - \li Debugger plugin: Attach to crashed processes by using the + \li Debugger plugin: attach to crashed processes by using the specified event handle and process ID. + \row + \li -git-show + \li Git plugin: show the specified commit hash. + \row \li -customwizard-verbose \li ProjectExplorer plugin: display additional information when 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 44fe1cc1f56..baa3e32c566 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 @@ -176,7 +176,7 @@ "trDescription": "Creates a C++ header and a source file for a new class that you can add to a C++ project.", "trDisplayName": "C++ Class", "trDisplayCategory": "C++", - "icon": "../../global/genericfilewizard.png", + "iconText": "h/cpp", "enabled": "%{JS: value('Plugins').indexOf('CppEditor') >= 0}", \endcode @@ -203,7 +203,13 @@ \li \c icon appears next to the \c trDisplayName in the middle panel when \c trDisplayCategory is selected. We recommend that you specify the path relative to the wizard.json file, - but you can also use an absolute path. + but you can also use an absolute path. Omit this value to + use the default icon for the wizard type. + + \li \c iconText determines the text overlay for the default + file icon. + + \li \c iconKind determines whether the icon is themed. \li \c image specifies a path to an image (for example a screenshot) that appears below the \c trDescription. @@ -281,8 +287,12 @@ "trDisplayName": "Class name:", "mandatory": true, "type": "LineEdit", - "data": { "validator": "(?:(?:[a-zA-Z_][a-zA-Z_0-9]*::)+[a-zA-Z_][a-zA-Z_0-9]*|)" } - }, + "data": { + "trPlaceholder": "Fully qualified name, including namespaces", + "validator": "(?:(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*|)", + "completion": "namespaces" + } + }, ... ] \endcode @@ -335,11 +345,19 @@ "source": "file.h", "target": "%{HdrPath}", "openInEditor": true + "options": [ + { "key": "Cpp:License:FileName", "value": "%{HdrFileName}" }, + { "key": "Cpp:License:ClassName", "value": "%{CN}" } + ] }, { "source": "file.cpp", "target": "%{SrcPath}", "openInEditor": true + "options": [ + { "key": "Cpp:License:FileName", "value": "%{SrcFileName}" }, + { "key": "Cpp:License:ClassName", "value": "%{CN}" } + ] } ] \endcode @@ -410,7 +428,11 @@ "trDisplayName": "Class name:", "mandatory": true, "type": "LineEdit", - "data": { "validator": "(?:(?:[a-zA-Z_][a-zA-Z_0-9]*::)+[a-zA-Z_][a-zA-Z_0-9]*|)" } + "data": { + "trPlaceholder": "Fully qualified name, including namespaces", + "validator": "(?:(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*|)", + "completion": "namespaces" + } }, ... ], @@ -776,7 +798,11 @@ "trDisplayName": "Class name:", "mandatory": true, "type": "LineEdit", - "data": { "validator": "(?:(?:[a-zA-Z_][a-zA-Z_0-9]*::)+[a-zA-Z_][a-zA-Z_0-9]*|)" } + "data": { + "trPlaceholder": "Fully qualified name, including namespaces", + "validator": "(?:(?:[a-zA-Z_][a-zA-Z_0-9]*::)*[a-zA-Z_][a-zA-Z_0-9]*|)", + "completion": "namespaces" + } }, { "name": "BaseEdit", @@ -787,8 +813,7 @@ { "trText": "%{BaseCB}", "trDisabledText": "%{BaseCB}", - "historyId": "EditValues", - "restoreLastHistoryItem": false + "completion": "classes" } }, \endcode @@ -799,6 +824,11 @@ \li \c trDisabledText specifies the text to display in a disabled field. + \li \c completion lists existing \c namespaces for the class name line + edit and existing \c classes for the base class line edit. This + value replaces the history completer that is usually available for + such fields. + \li \c trPlaceholder specifies the placeholder text. \li \c validator specifies a QRegularExpression to validate the line @@ -812,7 +842,8 @@ contains a password, which will be masked. \li \c historyId is a key that specifies the name for a list of items - for the history completer. + for the history completer. This value and \c completion are + mutually exclusive, so do not set both of them at the same time. \li \c restoreLastHistoryItem is a boolean that specifies that the last history item is automatically set as the default text in diff --git a/scripts/uichanges.py b/scripts/uichanges.py index 126cbfc9a31..74343fafa6e 100755 --- a/scripts/uichanges.py +++ b/scripts/uichanges.py @@ -37,6 +37,7 @@ Usage: """ import os, sys, string +import platform import subprocess from xml.sax import saxutils, handler, make_parser diff --git a/src/app/main.cpp b/src/app/main.cpp index a4ef3eea329..e17ef27e209 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -56,6 +56,8 @@ #include #include +#include + #include #include @@ -410,6 +412,11 @@ QStringList lastSessionArgument() #ifdef ENABLE_CRASHPAD bool startCrashpad(const QString &libexecPath, bool crashReportingEnabled) { + if (QSysInfo::currentCpuArchitecture() == "arm64") { + qDebug() << "The crashpad_handler binary does not work on arm64 properly. So it is disabled for now."; + return false; + } + using namespace crashpad; // Cache directory that will store crashpad information and minidumps diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp index 4ec1d026f75..18fc4be7c46 100644 --- a/src/libs/utils/filepath.cpp +++ b/src/libs/utils/filepath.cpp @@ -454,14 +454,21 @@ FilePath FilePath::fromUrl(const QUrl &url) return fn; } +static QString hostEncoded(QString host) +{ + host.replace('%', "%25"); + host.replace('/', "%2f"); + return host; +} + /// \returns a QString for passing on to QString based APIs QString FilePath::toString() const { if (m_scheme.isEmpty()) return m_data; if (m_data.startsWith('/')) - return m_scheme + "://" + m_host + m_data; - return m_scheme + "://" + m_host + "/./" + m_data; + return m_scheme + "://" + hostEncoded(m_host) + m_data; + return m_scheme + "://" + hostEncoded(m_host) + "/./" + m_data; } QUrl FilePath::toUrl() const @@ -595,7 +602,6 @@ void FilePath::setScheme(const QString &scheme) void FilePath::setHost(const QString &host) { - QTC_CHECK(!host.contains('/')); m_host = host; } @@ -943,6 +949,8 @@ void FilePath::setFromString(const QString &filename) m_data = filename.mid(pos1); } else { m_host = filename.mid(pos1, pos2 - pos1); + m_host.replace("%2f", "/"); + m_host.replace("%25", "%"); m_data = filename.mid(pos2); } if (m_data.startsWith("/./")) diff --git a/src/libs/utils/filepath.h b/src/libs/utils/filepath.h index 501feff17b0..b3c035ea870 100644 --- a/src/libs/utils/filepath.h +++ b/src/libs/utils/filepath.h @@ -105,7 +105,6 @@ public: bool endsWith(const QString &s) const; bool exists() const; - bool needsDevice() const; FilePath parentDir() const; bool isChildOf(const FilePath &s) const; @@ -191,6 +190,13 @@ public: qint64 maxSize = -1, qint64 offset = 0) const; void asyncWriteFileContents(const Continuation &cont, const QByteArray &data) const; + // Prefer not to use + // Using needsDevice() in "user" code is likely to result in code that + // makes a local/remote distinction which should be avoided in general. + // There are usually other means available. E.g. distinguishing based + // on FilePath::osType(). + bool needsDevice() const; + // Deprecated. [[nodiscard]] static FilePath fromFileInfo(const QFileInfo &info); // Avoid. [[nodiscard]] QFileInfo toFileInfo() const; // Avoid. @@ -205,7 +211,7 @@ private: [[nodiscard]] QString mapToDevicePath() const; QString m_scheme; - QString m_host; + QString m_host; // May contain raw slashes. QString m_data; }; diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp index cbc9536f405..dc8e5d32663 100644 --- a/src/plugins/clangcodemodel/clangdclient.cpp +++ b/src/plugins/clangcodemodel/clangdclient.cpp @@ -1410,10 +1410,10 @@ ClangdClient::ClangdClient(Project *project, const Utils::FilePath &jsonDbDir) setDocumentChangeUpdateThreshold(d->settings.documentUpdateThreshold); const auto textMarkCreator = [this](const Utils::FilePath &filePath, - const Diagnostic &diag) { + const Diagnostic &diag, bool isProjectFile) { if (d->isTesting) emit textMarkCreated(filePath); - return new ClangdTextMark(filePath, diag, this); + return new ClangdTextMark(filePath, diag, isProjectFile, this); }; const auto hideDiagsHandler = []{ ClangDiagnosticManager::clearTaskHubIssues(); }; setDiagnosticsHandlers(textMarkCreator, hideDiagsHandler); @@ -2652,6 +2652,7 @@ private: int posForNodeStart(const AstNode &node) const; int posForNodeEnd(const AstNode &node) const; void insertResult(const HighlightingResult &result); + void insertResult(const AstNode &node, TextStyle style); void insertAngleBracketInfo(int searchStart1, int searchEnd1, int searchStart2, int searchEnd2); void setResultPosFromRange(HighlightingResult &result, const Range &range); void collectFromNode(const AstNode &node); @@ -3619,6 +3620,16 @@ void ExtraHighlightingResultsCollector::insertResult(const HighlightingResult &r } } +void ExtraHighlightingResultsCollector::insertResult(const AstNode &node, TextStyle style) +{ + HighlightingResult result; + result.useTextSyles = true; + result.textStyles.mainStyle = style; + setResultPosFromRange(result, node.range()); + insertResult(result); + return; +} + // For matching the "<" and ">" brackets of template declarations, specializations // and instantiations. void ExtraHighlightingResultsCollector::insertAngleBracketInfo(int searchStart1, int searchEnd1, @@ -3673,37 +3684,30 @@ void ExtraHighlightingResultsCollector::collectFromNode(const AstNode &node) if (node.kind() == "UserDefinedLiteral") return; if (node.kind().endsWith("Literal")) { - HighlightingResult result; - result.useTextSyles = true; const bool isKeyword = node.kind() == "CXXBoolLiteral" || node.kind() == "CXXNullPtrLiteral"; const bool isStringLike = !isKeyword && (node.kind().startsWith("String") || node.kind().startsWith("Character")); - result.textStyles.mainStyle = isKeyword ? C_KEYWORD : isStringLike ? C_STRING : C_NUMBER; - setResultPosFromRange(result, node.range()); - insertResult(result); + const TextStyle style = isKeyword ? C_KEYWORD : isStringLike ? C_STRING : C_NUMBER; + insertResult(node, style); return; } if (node.role() == "type" && node.kind() == "Builtin") { - HighlightingResult result; - result.useTextSyles = true; - result.textStyles.mainStyle = C_PRIMITIVE_TYPE; - setResultPosFromRange(result, node.range()); - insertResult(result); + insertResult(node, C_PRIMITIVE_TYPE); return; } if (node.role() == "attribute" && (node.kind() == "Override" || node.kind() == "Final")) { - HighlightingResult result; - result.useTextSyles = true; - result.textStyles.mainStyle = C_KEYWORD; - setResultPosFromRange(result, node.range()); - insertResult(result); + insertResult(node, C_KEYWORD); return; } const bool isExpression = node.role() == "expression"; - const bool isDeclaration = node.role() == "declaration"; + if (isExpression && node.kind() == "Predefined") { + insertResult(node, C_PREPROCESSOR); + return; + } + const bool isDeclaration = node.role() == "declaration"; const int nodeStartPos = posForNodeStart(node); const int nodeEndPos = posForNodeEnd(node); const QList children = node.children().value_or(QList()); diff --git a/src/plugins/clangcodemodel/clangtextmark.cpp b/src/plugins/clangcodemodel/clangtextmark.cpp index 77eabc2f04d..20bef44e3bd 100644 --- a/src/plugins/clangcodemodel/clangtextmark.cpp +++ b/src/plugins/clangcodemodel/clangtextmark.cpp @@ -385,6 +385,7 @@ ClangBackEnd::DiagnosticContainer convertDiagnostic(const ClangdDiagnostic &src, ClangdTextMark::ClangdTextMark(const FilePath &filePath, const Diagnostic &diagnostic, + bool isProjectFile, const Client *client) : TextEditor::TextMark(filePath, int(diagnostic.range().start().line() + 1), client->id()) , m_lspDiagnostic(diagnostic) @@ -399,18 +400,13 @@ ClangdTextMark::ClangdTextMark(const FilePath &filePath, setPriority(isError ? TextEditor::TextMark::HighPriority : TextEditor::TextMark::NormalPriority); setIcon(isError ? Icons::CODEMODEL_ERROR.icon() : Icons::CODEMODEL_WARNING.icon()); - if (client->project()) { + if (isProjectFile) { setLineAnnotation(diagnostic.message()); setColor(isError ? Theme::CodeModel_Error_TextMarkColor : Theme::CodeModel_Warning_TextMarkColor); ClangDiagnosticManager::addTask(m_diagnostic); } - m_clientDeleted = QObject::connect(client, &QObject::destroyed, [this] (){ - QTC_ASSERT_STRING("ClangdClient deleted before TextMark"); - delete this; - }); - // Copy to clipboard action QVector actions; QAction *action = new QAction(); @@ -438,11 +434,6 @@ ClangdTextMark::ClangdTextMark(const FilePath &filePath, setActions(actions); } -ClangdTextMark::~ClangdTextMark() -{ - QObject::disconnect(m_clientDeleted); -} - bool ClangdTextMark::addToolTipContent(QLayout *target) const { const auto canApplyFixIt = [c = m_client, diag = m_lspDiagnostic, fp = fileName()] { diff --git a/src/plugins/clangcodemodel/clangtextmark.h b/src/plugins/clangcodemodel/clangtextmark.h index 8ab892e1bcf..2c08e875900 100644 --- a/src/plugins/clangcodemodel/clangtextmark.h +++ b/src/plugins/clangcodemodel/clangtextmark.h @@ -72,8 +72,8 @@ class ClangdTextMark : public TextEditor::TextMark public: ClangdTextMark(const ::Utils::FilePath &filePath, const LanguageServerProtocol::Diagnostic &diagnostic, + bool isProjectFile, const LanguageClient::Client *client); - ~ClangdTextMark(); private: bool addToolTipContent(QLayout *target) const override; @@ -81,8 +81,6 @@ private: const LanguageServerProtocol::Diagnostic m_lspDiagnostic; const ClangBackEnd::DiagnosticContainer m_diagnostic; const QPointer m_client; - - QMetaObject::Connection m_clientDeleted; }; } // namespace Internal diff --git a/src/plugins/clangcodemodel/test/clangdtests.cpp b/src/plugins/clangcodemodel/test/clangdtests.cpp index 98e720ba25c..adaa705cb85 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.cpp +++ b/src/plugins/clangcodemodel/test/clangdtests.cpp @@ -1302,6 +1302,12 @@ void ClangdTestHighlighting::test_data() << QList{C_FIELD} << 0; QTest::newRow("output arg") << 945 << 20 << 945 << 23 << QList{C_LOCAL, C_OUTPUT_ARGUMENT} << 0; + QTest::newRow("built-in define 1") << 950 << 21 << 950 << 29 + << QList{C_PREPROCESSOR} << 0; + QTest::newRow("built-in define 2") << 951 << 21 << 951 << 33 + << QList{C_PREPROCESSOR} << 0; + QTest::newRow("built-in define 3") << 952 << 21 << 952 << 40 + << QList{C_PREPROCESSOR} << 0; } void ClangdTestHighlighting::test() diff --git a/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp b/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp index 6230e7f0392..2ef28c11ba5 100644 --- a/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp +++ b/src/plugins/clangcodemodel/test/data/highlighting/highlighting.cpp @@ -944,3 +944,10 @@ void inputsAndOutputsFromObject(const WithVector &s) std::vector out; transform(s.v, out, [] {}); } + +void builtinDefines() +{ + const auto f1 = __func__; + const auto f2 = __FUNCTION__; + const auto f3 = __PRETTY_FUNCTION__; +} diff --git a/src/plugins/cppeditor/baseeditordocumentparser.cpp b/src/plugins/cppeditor/baseeditordocumentparser.cpp index f1066bd8380..9dafd423804 100644 --- a/src/plugins/cppeditor/baseeditordocumentparser.cpp +++ b/src/plugins/cppeditor/baseeditordocumentparser.cpp @@ -120,7 +120,7 @@ BaseEditorDocumentParser::Ptr BaseEditorDocumentParser::get(const QString &fileP ProjectPartInfo BaseEditorDocumentParser::determineProjectPart(const QString &filePath, const QString &preferredProjectPartId, const ProjectPartInfo ¤tProjectPartInfo, - const ProjectExplorer::Project *activeProject, + const Utils::FilePath &activeProject, Utils::Language languagePreference, bool projectsUpdated) { diff --git a/src/plugins/cppeditor/baseeditordocumentparser.h b/src/plugins/cppeditor/baseeditordocumentparser.h index 2f48058b8b6..6e7bf4326f8 100644 --- a/src/plugins/cppeditor/baseeditordocumentparser.h +++ b/src/plugins/cppeditor/baseeditordocumentparser.h @@ -30,6 +30,8 @@ #include "cppworkingcopy.h" #include "projectpart.h" +#include + #include #include #include @@ -65,14 +67,14 @@ public: Utils::Language languagePreference, bool projectsUpdated) : workingCopy(workingCopy) - , activeProject(activeProject) + , activeProject(activeProject ? activeProject->projectFilePath() : Utils::FilePath()) , languagePreference(languagePreference) , projectsUpdated(projectsUpdated) { } WorkingCopy workingCopy; - const ProjectExplorer::Project *activeProject = nullptr; + const Utils::FilePath activeProject; Utils::Language languagePreference = Utils::Language::Cxx; bool projectsUpdated = false; }; @@ -104,7 +106,7 @@ protected: static ProjectPartInfo determineProjectPart(const QString &filePath, const QString &preferredProjectPartId, const ProjectPartInfo ¤tProjectPartInfo, - const ProjectExplorer::Project *activeProject, + const Utils::FilePath &activeProject, Utils::Language languagePreference, bool projectsUpdated); diff --git a/src/plugins/cppeditor/cppprojectpartchooser.cpp b/src/plugins/cppeditor/cppprojectpartchooser.cpp index 65911000e71..ca2e5943d77 100644 --- a/src/plugins/cppeditor/cppprojectpartchooser.cpp +++ b/src/plugins/cppeditor/cppprojectpartchooser.cpp @@ -46,7 +46,7 @@ public: ProjectPartPrioritizer(const QList &projectParts, const QString &preferredProjectPartId, - const ProjectExplorer::Project *activeProject, + const Utils::FilePath &activeProject, Language languagePreference, bool areProjectPartsFromDependencies) : m_preferredProjectPartId(preferredProjectPartId) @@ -124,7 +124,7 @@ private: private: const QString m_preferredProjectPartId; - const ProjectExplorer::Project *m_activeProject = nullptr; + const Utils::FilePath m_activeProject; Language m_languagePreference = Language::Cxx; // Results @@ -134,7 +134,7 @@ private: ProjectPartInfo ProjectPartChooser::choose(const QString &filePath, const ProjectPartInfo ¤tProjectPartInfo, const QString &preferredProjectPartId, - const ProjectExplorer::Project *activeProject, + const Utils::FilePath &activeProject, Language languagePreference, bool projectsUpdated) const { diff --git a/src/plugins/cppeditor/cppprojectpartchooser.h b/src/plugins/cppeditor/cppprojectpartchooser.h index 4b8ee2dd1f6..0ffa3dbb773 100644 --- a/src/plugins/cppeditor/cppprojectpartchooser.h +++ b/src/plugins/cppeditor/cppprojectpartchooser.h @@ -50,7 +50,7 @@ public: ProjectPartInfo choose(const QString &filePath, const ProjectPartInfo ¤tProjectPartInfo, const QString &preferredProjectPartId, - const ProjectExplorer::Project *activeProject, + const Utils::FilePath &activeProject, Utils::Language languagePreference, bool projectsUpdated) const; diff --git a/src/plugins/cppeditor/projectinfo_test.cpp b/src/plugins/cppeditor/projectinfo_test.cpp index e12f8329915..825bd88b423 100644 --- a/src/plugins/cppeditor/projectinfo_test.cpp +++ b/src/plugins/cppeditor/projectinfo_test.cpp @@ -60,8 +60,11 @@ public: const ProjectPartInfo choose() { + const Project * const project = projectMap.value(activeProject).get(); + const Utils::FilePath projectFilePath = project ? project->projectFilePath() + : Utils::FilePath(); return chooser.choose(filePath, currentProjectPartInfo, preferredProjectPartId, - projectMap.value(activeProject).get(), + projectFilePath, languagePreference, projectsChanged); } diff --git a/src/plugins/cppeditor/projectpart.cpp b/src/plugins/cppeditor/projectpart.cpp index a0eaf79922b..1d827648fcb 100644 --- a/src/plugins/cppeditor/projectpart.cpp +++ b/src/plugins/cppeditor/projectpart.cpp @@ -57,7 +57,12 @@ QString ProjectPart::projectFileLocation() const bool ProjectPart::belongsToProject(const ProjectExplorer::Project *project) const { - return project ? topLevelProject == project->projectFilePath() : !hasProject(); + return belongsToProject(project ? project->projectFilePath() : Utils::FilePath()); +} + +bool ProjectPart::belongsToProject(const Utils::FilePath &project) const +{ + return topLevelProject == project; } QByteArray ProjectPart::readProjectConfigFile(const QString &projectConfigFile) diff --git a/src/plugins/cppeditor/projectpart.h b/src/plugins/cppeditor/projectpart.h index 2c420c8f870..c65932e6a7a 100644 --- a/src/plugins/cppeditor/projectpart.h +++ b/src/plugins/cppeditor/projectpart.h @@ -75,6 +75,7 @@ public: QString projectFileLocation() const; bool hasProject() const { return !topLevelProject.isEmpty(); } bool belongsToProject(const ProjectExplorer::Project *project) const; + bool belongsToProject(const Utils::FilePath &project) const; static QByteArray readProjectConfigFile(const QString &projectConfigFile); diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index 6aae4df5bf8..8775e2aae4b 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -363,11 +363,11 @@ public: }; connect(autoDetectButton, &QPushButton::clicked, this, - [this, logView, data, dockerDevice, searchPaths] { + [this, logView, dockerDevice, searchPaths] { logView->clear(); dockerDevice->updateContainerAccess(); - m_kitItemDetector.autoDetect(data.autodetectId(), searchPaths()); + m_kitItemDetector.autoDetect(dockerDevice->id().toString(), searchPaths()); if (DockerPlugin::isDaemonRunning().value_or(false) == false) logView->append(tr("Docker daemon appears to be not running.")); @@ -376,14 +376,14 @@ public: updateDaemonStateTexts(); }); - connect(undoAutoDetectButton, &QPushButton::clicked, this, [this, logView, data] { + connect(undoAutoDetectButton, &QPushButton::clicked, this, [this, logView, device] { logView->clear(); - m_kitItemDetector.undoAutoDetect(data.autodetectId()); + m_kitItemDetector.undoAutoDetect(device->id().toString()); }); - connect(listAutoDetectedButton, &QPushButton::clicked, this, [this, logView, data] { + connect(listAutoDetectedButton, &QPushButton::clicked, this, [this, logView, device] { logView->clear(); - m_kitItemDetector.listAutoDetected(data.autodetectId()); + m_kitItemDetector.listAutoDetected(device->id().toString()); }); using namespace Layouting; @@ -458,7 +458,7 @@ Tasks DockerDevice::validate() const // DockerDeviceData -QString DockerDeviceData::dockerId() const +QString DockerDeviceData::repoAndTag() const { if (repo == "") return imageId; @@ -479,7 +479,7 @@ DockerDevice::DockerDevice(const DockerDeviceData &data) setDisplayType(tr("Docker")); setOsType(OsTypeOtherUnix); setDefaultDisplayName(tr("Docker Image"));; - setDisplayName(tr("Docker Image \"%1\" (%2)").arg(data.dockerId()).arg(data.imageId)); + setDisplayName(tr("Docker Image \"%1\" (%2)").arg(data.repoAndTag()).arg(data.imageId)); setAllowEmptyCommand(true); setOpenTerminal([this](const Environment &env, const FilePath &workingDir) { @@ -829,7 +829,7 @@ void DockerDevicePrivate::startContainer() dockerCreate.addArgs({"-v", q->debugDumperPath().toUserOutput() + ':' + dumperPath.path()}); q->setDebugDumperPath(dumperPath); - dockerCreate.addArgs({"--entrypoint", "/bin/sh", m_data.dockerId()}); + dockerCreate.addArgs({"--entrypoint", "/bin/sh", m_data.repoAndTag()}); LOG("RUNNING: " << dockerCreate.toUserOutput()); QtcProcess createProcess; @@ -980,10 +980,20 @@ FilePath DockerDevice::mapToGlobalPath(const FilePath &pathOnDevice) const QTC_CHECK(handlesFile(pathOnDevice)); return pathOnDevice; } + FilePath result; - result.setScheme("docker"); - result.setHost(d->m_data.dockerId()); result.setPath(pathOnDevice.path()); + result.setScheme("docker"); + result.setHost(d->m_data.repoAndTag()); + +// The following would work, but gives no hint on repo and tag +// result.setScheme("docker"); +// result.setHost(d->m_data.imageId); + +// The following would work, but gives no hint on repo, tag and imageid +// result.setScheme("device"); +// result.setHost(id().toString()); + return result; } @@ -1002,7 +1012,13 @@ QString DockerDevice::mapToDevicePath(const Utils::FilePath &globalPath) const bool DockerDevice::handlesFile(const FilePath &filePath) const { - return filePath.scheme() == "docker" && filePath.host() == d->m_data.dockerId(); + if (filePath.scheme() == "device" && filePath.host() == id().toString()) + return true; + if (filePath.scheme() == "docker" && filePath.host() == d->m_data.imageId) + return true; + if (filePath.scheme() == "docker" && filePath.host() == d->m_data.repo + ':' + d->m_data.tag) + return true; + return false; } bool DockerDevice::isExecutableFile(const FilePath &filePath) const @@ -1385,7 +1401,7 @@ Environment DockerDevice::systemEnvironment() const void DockerDevice::aboutToBeRemoved() const { KitDetector detector(sharedFromThis()); - detector.undoAutoDetect(d->m_data.autodetectId()); + detector.undoAutoDetect(id().toString()); } void DockerDevicePrivate::fetchSystemEnviroment() @@ -1589,7 +1605,7 @@ public: QTC_ASSERT(item, return {}); auto device = DockerDevice::create(*item); - device->setupId(IDevice::ManuallyAdded, Id::fromString(item->autodetectId())); + device->setupId(IDevice::ManuallyAdded); device->setType(Constants::DOCKER_DEVICE_TYPE); device->setMachineType(IDevice::Hardware); diff --git a/src/plugins/docker/dockerdevice.h b/src/plugins/docker/dockerdevice.h index 3a5770d6ebc..394d92a0929 100644 --- a/src/plugins/docker/dockerdevice.h +++ b/src/plugins/docker/dockerdevice.h @@ -37,10 +37,8 @@ namespace Internal { class DockerDeviceData { public: - // Used for "docker run" and for host parts of FilePaths - QString dockerId() const; - // Used as autodetection source string - QString autodetectId() const { return "docker:" + dockerId(); } + // Used for "docker run" + QString repoAndTag() const; QString imageId; QString repo; diff --git a/src/plugins/languageclient/diagnosticmanager.cpp b/src/plugins/languageclient/diagnosticmanager.cpp index cdaadb7d4a8..381e0f9fc45 100644 --- a/src/plugins/languageclient/diagnosticmanager.cpp +++ b/src/plugins/languageclient/diagnosticmanager.cpp @@ -28,6 +28,7 @@ #include "client.h" #include +#include #include #include #include @@ -74,7 +75,7 @@ private: DiagnosticManager::DiagnosticManager(Client *client) : m_client(client) { - m_textMarkCreator = [this](const FilePath &filePath, const Diagnostic &diagnostic) { + m_textMarkCreator = [this](const FilePath &filePath, const Diagnostic &diagnostic, bool /*isProjectFile*/) { return createTextMark(filePath, diagnostic); }; } @@ -125,9 +126,11 @@ void DiagnosticManager::showDiagnostics(const DocumentUri &uri, int version) QList extraSelections; const VersionedDiagnostics &versionedDiagnostics = m_diagnostics.value(uri); if (versionedDiagnostics.version.value_or(version) == version) { + const bool isProjectFile = m_client->project() + && m_client->project()->isKnownFile(filePath); for (const Diagnostic &diagnostic : versionedDiagnostics.diagnostics) { extraSelections << toDiagnosticsSelections(diagnostic, doc->document()); - m_marks[filePath].append(m_textMarkCreator(filePath, diagnostic)); + m_marks[filePath].append(m_textMarkCreator(filePath, diagnostic, isProjectFile)); } } diff --git a/src/plugins/languageclient/diagnosticmanager.h b/src/plugins/languageclient/diagnosticmanager.h index a7e2e474852..c4bfabf71a3 100644 --- a/src/plugins/languageclient/diagnosticmanager.h +++ b/src/plugins/languageclient/diagnosticmanager.h @@ -43,7 +43,7 @@ namespace LanguageClient { class Client; using TextMarkCreator = std::function; + const LanguageServerProtocol::Diagnostic &, bool)>; using HideDiagnosticsHandler = std::function; class DiagnosticManager diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp index 368d1a8f755..50b2e876e63 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp @@ -366,6 +366,15 @@ bool DeviceManager::isLoaded() const IDevice::ConstPtr DeviceManager::deviceForPath(const FilePath &path) { const QList devices = instance()->d->deviceList(); + + if (path.scheme() == "device") { + for (const IDevice::Ptr &dev : devices) { + if (path.host() == dev->id().toString()) + return dev; + } + return {}; + } + for (const IDevice::Ptr &dev : devices) { // TODO: ensure handlesFile is thread safe if (dev->handlesFile(path)) diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp index a485f74896a..6840d521d18 100644 --- a/src/plugins/projectexplorer/gcctoolchain.cpp +++ b/src/plugins/projectexplorer/gcctoolchain.cpp @@ -697,7 +697,7 @@ void GccToolChain::addToEnvironment(Environment &env) const { // On Windows gcc invokes cc1plus which is in libexec directory. // cc1plus depends on libwinpthread-1.dll which is in bin, so bin must be in the PATH. - if (HostOsInfo::isWindowsHost()) + if (compilerCommand().osType() == OsTypeWindows) addCommandPathToEnvironment(compilerCommand(), env); } @@ -1229,7 +1229,7 @@ Toolchains GccToolChainFactory::autoDetectToolChain(const ToolChainDescription & { Toolchains result; - Environment systemEnvironment = Environment::systemEnvironment(); + Environment systemEnvironment = tcd.compilerPath.deviceEnvironment(); GccToolChain::addCommandPathToEnvironment(tcd.compilerPath, systemEnvironment); const FilePath localCompilerPath = findLocalCompiler(tcd.compilerPath, systemEnvironment); if (ToolChainManager::isBadToolchain(localCompilerPath)) @@ -1436,7 +1436,7 @@ void GccToolChainConfigWidget::handleCompilerCommandChange() haveCompiler = fi.isExecutable() && fi.isFile(); } if (haveCompiler) { - Environment env = Environment::systemEnvironment(); + Environment env = path.deviceEnvironment(); GccToolChain::addCommandPathToEnvironment(path, env); QStringList args = gccPredefinedMacrosOptions(Constants::CXX_LANGUAGE_ID) + splitString(m_platformCodeGenFlagsLineEdit->text()); diff --git a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp index 4079b0ef56b..19bfdc27b0a 100644 --- a/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp +++ b/src/plugins/qbsprojectmanager/defaultpropertyprovider.cpp @@ -313,22 +313,20 @@ QVariantMap DefaultPropertyProvider::autoGeneratedProperties(const ProjectExplor if (tcCxx) cxxCompilerPath = tcCxx->compilerCommand(); - const QFileInfo cFileInfo = cCompilerPath.toFileInfo(); - const QFileInfo cxxFileInfo = cxxCompilerPath.toFileInfo(); - QString cCompilerName = cFileInfo.fileName(); - QString cxxCompilerName = cxxFileInfo.fileName(); + QString cCompilerName = cCompilerPath.fileName(); + QString cxxCompilerName = cxxCompilerPath.fileName(); const QString cToolchainPrefix = extractToolchainPrefix(&cCompilerName); const QString cxxToolchainPrefix = extractToolchainPrefix(&cxxCompilerName); - QFileInfo mainFileInfo; + Utils::FilePath mainFilePath; QString mainCompilerName; QString mainToolchainPrefix; if (tcCxx) { - mainFileInfo = cxxFileInfo; + mainFilePath = cxxCompilerPath; mainCompilerName = cxxCompilerName; mainToolchainPrefix = cxxToolchainPrefix; } else { - mainFileInfo = cFileInfo; + mainFilePath = cCompilerPath; mainCompilerName = cCompilerName; mainToolchainPrefix = cToolchainPrefix; } @@ -353,11 +351,11 @@ QVariantMap DefaultPropertyProvider::autoGeneratedProperties(const ProjectExplor } if (tcC && tcCxx && !cCompilerPath.isEmpty() && !cxxCompilerPath.isEmpty() - && cFileInfo.absolutePath() != cxxFileInfo.absolutePath()) { + && cCompilerPath.absolutePath() != cxxCompilerPath.absolutePath()) { Core::MessageManager::writeFlashing( tr("C and C++ compiler paths differ. C compiler may not work.")); } - data.insert(QLatin1String(CPP_TOOLCHAINPATH), mainFileInfo.absolutePath()); + data.insert(QLatin1String(CPP_TOOLCHAINPATH), mainFilePath.absolutePath().toString()); if (auto gcc = dynamic_cast(mainTc)) { QStringList compilerFlags = gcc->platformCodeGenFlags(); @@ -372,7 +370,7 @@ QVariantMap DefaultPropertyProvider::autoGeneratedProperties(const ProjectExplor // Reverse engineer the Xcode developer path from the compiler path const QRegularExpression compilerRe( QStringLiteral("^(?.*)/Toolchains/(?:.+)\\.xctoolchain/usr/bin$")); - const QRegularExpressionMatch compilerReMatch = compilerRe.match(cxxFileInfo.absolutePath()); + const QRegularExpressionMatch compilerReMatch = compilerRe.match(cxxCompilerPath.absolutePath().toString()); if (compilerReMatch.hasMatch()) { const QString developerPath = compilerReMatch.captured(QStringLiteral("developerpath")); data.insert(QLatin1String(XCODE_DEVELOPERPATH), developerPath); diff --git a/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp b/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp index 41810655c3a..7909de1981e 100644 --- a/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp +++ b/src/plugins/qbsprojectmanager/qbsprofilemanager.cpp @@ -218,8 +218,7 @@ QString QbsProfileManager::profileNameForKit(const ProjectExplorer::Kit *kit) QString QbsProfileManager::runQbsConfig(QbsConfigOp op, const QString &key, const QVariant &value) { - Utils::QtcProcess qbsConfig; - QStringList args("config"); + QStringList args; if (QbsSettings::useCreatorSettingsDirForQbs()) args << "--settings-dir" << QbsSettings::qbsSettingsBaseDir(); switch (op) { @@ -242,10 +241,11 @@ QString QbsProfileManager::runQbsConfig(QbsConfigOp op, const QString &key, cons break; } } - const Utils::FilePath qbsExe = QbsSettings::qbsExecutableFilePath(); - if (qbsExe.isEmpty() || !qbsExe.exists()) + const Utils::FilePath qbsConfigExe = QbsSettings::qbsConfigFilePath(); + if (qbsConfigExe.isEmpty() || !qbsConfigExe.exists()) return {}; - qbsConfig.setCommand({qbsExe, args}); + Utils::QtcProcess qbsConfig; + qbsConfig.setCommand({qbsConfigExe, args}); qbsConfig.start(); if (!qbsConfig.waitForStarted(3000) || !qbsConfig.waitForFinished(5000)) { Core::MessageManager::writeFlashing( diff --git a/src/plugins/qbsprojectmanager/qbssettings.cpp b/src/plugins/qbsprojectmanager/qbssettings.cpp index 010fad3f73e..55619f73f28 100644 --- a/src/plugins/qbsprojectmanager/qbssettings.cpp +++ b/src/plugins/qbsprojectmanager/qbssettings.cpp @@ -87,6 +87,18 @@ FilePath QbsSettings::qbsExecutableFilePath() return candidate; } +FilePath QbsSettings::qbsConfigFilePath() +{ + const FilePath qbsExe = qbsExecutableFilePath(); + if (!qbsExe.isExecutableFile()) + return {}; + const FilePath qbsConfig = qbsExe.absolutePath().pathAppended("qbs-config") + .withExecutableSuffix(); + if (!qbsConfig.isExecutableFile()) + return {}; + return qbsConfig; +} + QString QbsSettings::defaultInstallDirTemplate() { return instance().m_settings.defaultInstallDirTemplate; diff --git a/src/plugins/qbsprojectmanager/qbssettings.h b/src/plugins/qbsprojectmanager/qbssettings.h index fef663e2063..dd908029e62 100644 --- a/src/plugins/qbsprojectmanager/qbssettings.h +++ b/src/plugins/qbsprojectmanager/qbssettings.h @@ -50,6 +50,7 @@ public: static QbsSettings &instance(); static Utils::FilePath qbsExecutableFilePath(); + static Utils::FilePath qbsConfigFilePath(); static bool hasQbsExecutable(); static QString defaultInstallDirTemplate(); static bool useCreatorSettingsDirForQbs(); diff --git a/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.cpp b/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.cpp index dea4960bc15..e15ff49744e 100644 --- a/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.cpp +++ b/src/plugins/qmldesigner/components/propertyeditor/fileresourcesmodel.cpp @@ -64,7 +64,7 @@ void FileResourcesModel::setModelNodeBackend(const QVariant &modelNodeBackend) if (backendObjectCasted) { QmlDesigner::Model *model = backendObjectCasted->qmlObjectNode().modelNode().model(); m_docPath = QDir{QFileInfo{model->fileUrl().toLocalFile()}.absolutePath()}; - m_path = QUrl::fromLocalFile(QmlDesigner::DocumentManager::currentResourcePath() + m_path = QUrl::fromLocalFile(QmlDesigner::DocumentManager::currentProjectDirPath() .toFileInfo().absoluteFilePath()); } diff --git a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp index ff9f7b196b7..79ef6a64345 100644 --- a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp +++ b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp @@ -862,14 +862,8 @@ ModelNode RewriterView::nodeAtTextCursorPositionHelper(const ModelNode &root, in ModelNode lastNode = root; - int i = 0; for (const myPair &pair : data) { ModelNode node = pair.first; - i++; - if (i >= int(data.size())) { - lastNode = node; - break; - } const int nodeTextOffset = nodeOffset(node); const int nodeTextLength = m_textModifier->text().indexOf("}", nodeTextOffset) - nodeTextOffset - 1; diff --git a/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml b/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml index a145cbcabef..5cff58fad40 100644 --- a/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml +++ b/src/plugins/studiowelcome/qml/splashscreen/Welcome_splash.qml @@ -92,7 +92,7 @@ Rectangle { Text { id: software_for_ui x: 15 - y: 124 + y: 126 width: 300 height: 30 color: "#ffffff" diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 890e8f5fcbe..92de555869f 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -2610,7 +2610,7 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e) if (ro || !isPrintableText(eventText)) { QTextCursor::MoveOperation blockSelectionOperation = QTextCursor::NoMove; - if (e->modifiers() & Qt::AltModifier && !Utils::HostOsInfo::isMacHost()) { + if (e->modifiers() == (Qt::AltModifier | Qt::ShiftModifier) && !Utils::HostOsInfo::isMacHost()) { if (MultiTextCursor::multiCursorAddEvent(e, QKeySequence::MoveToNextLine)) blockSelectionOperation = QTextCursor::Down; else if (MultiTextCursor::multiCursorAddEvent(e, QKeySequence::MoveToPreviousLine)) diff --git a/src/tools/sdktool/addkitoperation.cpp b/src/tools/sdktool/addkitoperation.cpp index d6b3442a701..18ecc4965b2 100644 --- a/src/tools/sdktool/addkitoperation.cpp +++ b/src/tools/sdktool/addkitoperation.cpp @@ -62,6 +62,7 @@ const char DEBUGGER_ENGINE[] = "EngineType"; const char DEBUGGER_BINARY[] = "Binary"; const char DEVICE_TYPE[] = "PE.Profile.DeviceType"; const char DEVICE_ID[] = "PE.Profile.Device"; +const char BUILDDEVICE_ID[] = "PE.Profile.BuildDevice"; const char SYSROOT[] = "PE.Profile.SysRoot"; const char TOOLCHAIN[] = "PE.Profile.ToolChainsV3"; const char MKSPEC[] = "QtPM4.mkSpecInformation"; @@ -90,8 +91,9 @@ QString AddKitOperation::argumentsHelpText() const " (not compatible with --debugger and --debuggerengine)\n" " --debuggerengine debuggerengine of the new kit.\n" " --debugger debugger of the new kit.\n" - " --devicetype device type of the new kit (required).\n" - " --device device id to use (optional).\n" + " --devicetype (run-)device type of the new kit (required).\n" + " --device (run-)device id to use (optional).\n" + " --builddevice build device id to use (optional).\n" " --sysroot sysroot of the new kit.\n" " --toolchain tool chain of the new kit (obsolete!).\n" " --toolchain tool chain for a language.\n" @@ -180,6 +182,14 @@ bool AddKitOperation::setArguments(const QStringList &args) continue; } + if (current == "--builddevice") { + if (next.isNull()) + return false; + ++i; // skip next; + m_buildDevice = next; + continue; + } + if (current == "--sysroot") { if (next.isNull()) return false; @@ -303,7 +313,18 @@ int AddKitOperation::execute() const #ifdef WITH_TESTS bool AddKitOperation::test() const { - AddKitData kitData; + AddKitData baseData; + baseData.m_id ="testId"; + baseData.m_displayName = "Test Kit"; + baseData.m_icon = "/tmp/icon.png"; + baseData.m_debuggerEngine = 1; + baseData.m_debugger = "/usr/bin/gdb-test"; + baseData.m_deviceType = "Desktop"; + baseData.m_device = "{dev-id}"; + baseData.m_qt = "{qt-id}"; + baseData.m_mkspec ="unsupported/mkspec"; + baseData.m_extra = {{"PE.Profile.Data/extraData", QVariant("extraValue")}}; + QVariantMap map = initializeKits(); QVariantMap tcMap = AddToolChainData::initializeToolChains(); @@ -326,22 +347,27 @@ bool AddKitOperation::test() const const QStringList env = {"TEST=1", "PATH"}; - if (map.count() != 3 - || !map.contains(VERSION) || map.value(VERSION).toInt() != 1 - || !map.contains(COUNT) || map.value(COUNT).toInt() != 0 - || !map.contains(DEFAULT) || !map.value(DEFAULT).toString().isEmpty()) + if (map.count() != 3) + return false; + if (!map.contains(VERSION)) + return false; + if (map.value(VERSION).toInt() != 1) + return false; + if (!map.contains(COUNT)) + return false; + if (map.value(COUNT).toInt() != 0) + return false; + if (!map.contains(DEFAULT)) + return false; + if (!map.value(DEFAULT).toString().isEmpty()) return false; QHash tcs; tcs.insert("Cxx", "{tcXX-id}"); // Fail if TC is not there: - kitData = {"testId", "Test Kit", "/tmp/icon.png", QString(), 1, - "/usr/bin/gdb-test", "Desktop", "{dev-id}", QString(), - tcs, "{qt-id}", "unsupported/mkspec", - QString(), QString(), QString(), QString(), QString(), QStringList(), - QStringList(), - {{{"PE.Profile.Data/extraData", QVariant("extraValue")}}}}; + AddKitData kitData = baseData; + kitData.m_tcs = tcs; QVariantMap empty = kitData.addKit(map, tcMap, qtMap, devMap, {}); if (!empty.isEmpty()) @@ -349,21 +375,16 @@ bool AddKitOperation::test() const // Do not fail if TC is an ABI: tcs.clear(); tcs.insert("C", "x86-linux-generic-elf-64bit"); - kitData = {"testId", "Test Kit", "/tmp/icon.png", QString(), 1, - "/usr/bin/gdb-test", "Desktop", "{dev-id}", QString(), - tcs, "{qt-id}", "unsupported/mkspec", - QString(), QString(), QString(), QString(), QString(), QStringList(), env, - {KeyValuePair("PE.Profile.Data/extraData", QVariant("extraValue"))}}; + kitData = baseData; + kitData.m_tcs = tcs; empty = kitData.addKit(map, tcMap, qtMap, devMap, {}); if (empty.isEmpty()) return false; + // QTCREATORBUG-11983, mach_o was not covered by the first attempt to fix this. tcs.insert("D", "x86-macos-generic-mach_o-64bit"); - kitData = {"testId", "Test Kit", "/tmp/icon.png", QString(), 1, - "/usr/bin/gdb-test", "Desktop", "{dev-id}", QString(), - tcs, "{qt-id}", "unsupported/mkspec", - QString(), QString(), QString(), QString(), QString(), QStringList(), env, - {{KeyValuePair("PE.Profile.Data/extraData", QVariant("extraValue"))}}}; + kitData = baseData; + kitData.m_tcs = tcs; empty = kitData.addKit(map, tcMap, qtMap, devMap, {}); if (empty.isEmpty()) return false; @@ -372,153 +393,288 @@ bool AddKitOperation::test() const tcs.insert("Cxx", "{tc-id}"); // Fail if Qt is not there: - kitData = {"testId", "Test Kit", "/tmp/icon.png", QString(), 1, - "/usr/bin/gdb-test", "Desktop", "{dev-id}", QString(), tcs, "{qtXX-id}", - "unsupported/mkspec", - QString(), QString(), QString(), QString(), QString(), QStringList(), env, - {{KeyValuePair("PE.Profile.Data/extraData", QVariant("extraValue"))}}}; + kitData = baseData; + kitData.m_qt = "{qtXX-id}"; empty = kitData.addKit(map, tcMap, qtMap, devMap, {}); if (!empty.isEmpty()) return false; + // Fail if dev is not there: - kitData = {"testId", "Test Kit", "/tmp/icon.png", QString(), 1, - "/usr/bin/gdb-test", "Desktop", "{devXX-id}", QString(), tcs, "{qt-id}", - "unsupported/mkspec", - QString(), QString(), QString(), QString(), QString(), QStringList(), env, - {KeyValuePair("PE.Profile.Data/extraData", QVariant("extraValue"))}}; + kitData = baseData; + kitData.m_device = "{devXX-id}"; empty = kitData.addKit(map, tcMap, qtMap, devMap, {}); if (!empty.isEmpty()) return false; // Profile 0: - kitData = {"testId", "Test Kit", "/tmp/icon.png", QString(), 1, - "/usr/bin/gdb-test", "Desktop", QString(), QString(), tcs, "{qt-id}", - "unsupported/mkspec", - QString(), QString(), QString(), QString(), QString(), QStringList(), env, - {{KeyValuePair("PE.Profile.Data/extraData", QVariant("extraValue"))}}}; + kitData = baseData; + kitData.m_tcs = tcs; map = kitData.addKit(map, tcMap, qtMap, devMap, {}); - if (map.count() != 4 - || !map.contains(VERSION) || map.value(VERSION).toInt() != 1 - || !map.contains(COUNT) || map.value(COUNT).toInt() != 1 - || !map.contains(DEFAULT) || map.value(DEFAULT).toString() != "testId" - || !map.contains("Profile.0")) + if (map.count() != 4) + return false; + if (!map.contains(VERSION)) + return false; + if (map.value(VERSION).toInt() != 1) + return false; + if (!map.contains(COUNT)) + return false; + if (map.value(COUNT).toInt() != 1) + return false; + if (!map.contains(DEFAULT)) + return false; + if (map.value(DEFAULT).toString() != "testId") + return false; + if (!map.contains("Profile.0")) return false; QVariantMap profile0 = map.value("Profile.0").toMap(); - if (profile0.count() != 6 - || !profile0.contains(ID) || profile0.value(ID).toString() != "testId" - || !profile0.contains(DISPLAYNAME) || profile0.value(DISPLAYNAME).toString() != "Test Kit" - || !profile0.contains(ICON) || profile0.value(ICON).toString() != "/tmp/icon.png" - || !profile0.contains(DATA) || profile0.value(DATA).type() != QVariant::Map - || !profile0.contains(AUTODETECTED) || profile0.value(AUTODETECTED).toBool() != true - || !profile0.contains(SDK) || profile0.value(SDK).toBool() != true) + if (profile0.count() != 6) + return false; + + if (!profile0.contains(ID)) + return false; + if (profile0.value(ID).toString() != "testId") + return false; + if (!profile0.contains(DISPLAYNAME)) + return false; + if (profile0.value(DISPLAYNAME).toString() != "Test Kit") + return false; + if (!profile0.contains(ICON)) + return false; + if (profile0.value(ICON).toString() != "/tmp/icon.png") + return false; + if (!profile0.contains(DATA)) + return false; + if (profile0.value(DATA).type() != QVariant::Map) + return false; + if (!profile0.contains(AUTODETECTED)) + return false; + if (profile0.value(AUTODETECTED).toBool() != true) + return false; + if (!profile0.contains(SDK)) + return false; + if (profile0.value(SDK).toBool() != true) return false; QVariantMap data = profile0.value(DATA).toMap(); - if (data.count() != 7 - || !data.contains(DEBUGGER) || data.value(DEBUGGER).type() != QVariant::Map - || !data.contains(DEVICE_TYPE) || data.value(DEVICE_TYPE).toString() != "Desktop" - || !data.contains(TOOLCHAIN) - || !data.contains(QT) || data.value(QT).toString() != "SDK.{qt-id}" - || !data.contains(MKSPEC) || data.value(MKSPEC).toString() != "unsupported/mkspec" - || !data.contains("extraData") || data.value("extraData").toString() != "extraValue") + if (data.count() != 7) return false; - QVariantMap tcOutput = data.value(TOOLCHAIN).toMap(); - if (tcOutput.count() != 1 - || !tcOutput.contains("Cxx") || tcOutput.value("Cxx") != "{tc-id}") + if (!data.contains(DEBUGGER)) + return false; + if (data.value(DEBUGGER).type() != QVariant::Map) + return false; + if (!data.contains(DEVICE_TYPE)) + return false; + if (data.value(DEVICE_TYPE).toString() != "Desktop") + return false; + if (!data.contains(TOOLCHAIN)) + return false; + if (!data.contains(QT)) + return false; + if (data.value(QT).toString() != "SDK.{qt-id}") + return false; + if (!data.contains(MKSPEC)) + return false; + if (data.value(MKSPEC).toString() != "unsupported/mkspec") + return false; + if (!data.contains("extraData")) + return false; + if (data.value("extraData").toString() != "extraValue") return false; - // Ignore existing ids: - kitData = {"testId", "Test Qt Version X", - "/tmp/icon3.png", QString(), 1, "/usr/bin/gdb-test3", "Desktop", - QString(), QString(), tcs, "{qt-id}", "unsupported/mkspec", - QString(), QString(), QString(), QString(), QString(), QStringList(), env, - {{KeyValuePair("PE.Profile.Data/extraData", QVariant("extraValue"))}}}; + QVariantMap tcOutput = data.value(TOOLCHAIN).toMap(); + if (tcOutput.count() != 1) + return false; + if (!tcOutput.contains("Cxx")) + return false; + if (tcOutput.value("Cxx") != "{tc-id}") + return false; + + // Ignore exist ids: + kitData = baseData; + kitData.m_displayName = "Test Qt Version X"; + kitData.m_icon = "/tmp/icon3.png"; + kitData.m_debugger = "/usr/bin/gdb-test3"; + kitData.m_tcs = tcs; QVariantMap result = kitData.addKit(map, tcMap, qtMap, devMap, {}); if (!result.isEmpty()) return false; // Profile 1: Make sure name is unique: - kitData = {"testId2", "Test Kit2", "/tmp/icon2.png", QString(), 1, - "/usr/bin/gdb-test2", "Desktop", "{dev-id}", "/sys/root//", tcs, - "{qt-id}", "unsupported/mkspec", - QString(), QString(), QString(), QString(), QString(), QStringList(), env, - {{KeyValuePair("PE.Profile.Data/extraData", QVariant("extraValue"))}}}; + kitData = baseData; + kitData.m_id = "testId2"; + kitData.m_displayName = "Test Kit2"; + kitData.m_icon = "/tmp/icon2.png"; + kitData.m_debugger = "/usr/bin/gdb-test2"; + kitData.m_sysRoot = "/sys/root//"; + kitData.m_env = env; + kitData.m_tcs = tcs; map = kitData.addKit(map, tcMap, qtMap, devMap, {}); - if (map.count() != 5 - || !map.contains(VERSION) || map.value(VERSION).toInt() != 1 - || !map.contains(COUNT) || map.value(COUNT).toInt() != 2 - || !map.contains(DEFAULT) || map.value(DEFAULT).toInt() != 0 - || !map.contains("Profile.0") - || !map.contains("Profile.1")) + if (map.count() != 5) + return false; + if (!map.contains(VERSION) ) + return false; + if (map.value(VERSION).toInt() != 1) + return false; + if (!map.contains(COUNT) ) + return false; + if (map.value(COUNT).toInt() != 2) + return false; + if (!map.contains(DEFAULT) ) + return false; + if (map.value(DEFAULT).toInt() != 0) + return false; + if (!map.contains("Profile.0")) + return false; + if (!map.contains("Profile.1")) return false; - if (map.value("Profile.0") != profile0) return false; QVariantMap profile1 = map.value("Profile.1").toMap(); - if (profile1.count() != 6 - || !profile1.contains(ID) || profile1.value(ID).toString() != "testId2" - || !profile1.contains(DISPLAYNAME) || profile1.value(DISPLAYNAME).toString() != "Test Kit2" - || !profile1.contains(ICON) || profile1.value(ICON).toString() != "/tmp/icon2.png" - || !profile1.contains(DATA) || profile1.value(DATA).type() != QVariant::Map - || !profile1.contains(AUTODETECTED) || profile1.value(AUTODETECTED).toBool() != true - || !profile1.contains(SDK) || profile1.value(SDK).toBool() != true) + if (profile1.count() != 6) + return false; + if (!profile1.contains(ID) ) + return false; + if (profile1.value(ID).toString() != "testId2") + return false; + if (!profile1.contains(DISPLAYNAME) ) + return false; + if (profile1.value(DISPLAYNAME).toString() != "Test Kit2") + return false; + if (!profile1.contains(ICON) ) + return false; + if (profile1.value(ICON).toString() != "/tmp/icon2.png") + return false; + if (!profile1.contains(DATA) ) + return false; + if (profile1.value(DATA).type() != QVariant::Map) + return false; + if (!profile1.contains(AUTODETECTED) ) + return false; + if (profile1.value(AUTODETECTED).toBool() != true) + return false; + if (!profile1.contains(SDK) ) + return false; + if (profile1.value(SDK).toBool() != true) return false; data = profile1.value(DATA).toMap(); - if (data.count() != 9 - || !data.contains(DEBUGGER) || data.value(DEBUGGER).type() != QVariant::Map - || !data.contains(DEVICE_TYPE) || data.value(DEVICE_TYPE).toString() != "Desktop" - || !data.contains(DEVICE_ID) || data.value(DEVICE_ID).toString() != "{dev-id}" - || !data.contains(SYSROOT) || data.value(SYSROOT).toString() != "/sys/root//" - || !data.contains(TOOLCHAIN) - || !data.contains(QT) || data.value(QT).toString() != "SDK.{qt-id}" - || !data.contains(MKSPEC) || data.value(MKSPEC).toString() != "unsupported/mkspec" - || !data.contains(ENV) || data.value(ENV).toStringList() != env - || !data.contains("extraData") || data.value("extraData").toString() != "extraValue") + if (data.count() != 9) return false; + if (!data.contains(DEBUGGER) ) + return false; + if (data.value(DEBUGGER).type() != QVariant::Map) + return false; + if (!data.contains(DEVICE_TYPE) ) + return false; + if (data.value(DEVICE_TYPE).toString() != "Desktop") + return false; + if (!data.contains(DEVICE_ID) ) + return false; + if (data.value(DEVICE_ID).toString() != "{dev-id}") + return false; + if (!data.contains(SYSROOT) ) + return false; + if (data.value(SYSROOT).toString() != "/sys/root//") + return false; + if (!data.contains(TOOLCHAIN)) + return false; + if (!data.contains(QT) ) + return false; + if (data.value(QT).toString() != "SDK.{qt-id}") + return false; + if (!data.contains(MKSPEC) ) + return false; + if (data.value(MKSPEC).toString() != "unsupported/mkspec") + return false; + if (!data.contains(ENV) ) + return false; + if (data.value(ENV).toStringList() != env) + return false; + if (!data.contains("extraData") ) + return false; + if (data.value("extraData").toString() != "extraValue") + return false; + tcOutput = data.value(TOOLCHAIN).toMap(); - if (tcOutput.count() != 1 - || !tcOutput.contains("Cxx") || tcOutput.value("Cxx") != "{tc-id}") + if (tcOutput.count() != 1) + return false; + if (!tcOutput.contains("Cxx") ) + return false; + if (tcOutput.value("Cxx") != "{tc-id}") return false; // Profile 2: Test debugger id: - kitData = {"test with debugger Id", "Test debugger Id", - "/tmp/icon2.png", "debugger Id", 0, QString(), "Desktop", QString(), QString(), - tcs, "{qt-id}", "unsupported/mkspec", - QString(), QString(), QString(), QString(), QString(), QStringList(), env, - {KeyValuePair("PE.Profile.Data/extraData", QVariant("extraValue"))}}; - map = kitData.addKit(map, tcMap, qtMap, devMap, {}); - if (map.count() != 6 - || !map.contains(VERSION) || map.value(VERSION).toInt() != 1 - || !map.contains(COUNT) || map.value(COUNT).toInt() != 3 - || !map.contains(DEFAULT) || map.value(DEFAULT).toInt() != 0 - || !map.contains("Profile.0") - || !map.contains("Profile.1") - || !map.contains("Profile.2")) - return false; + kitData = baseData; + kitData.m_id = "test with debugger Id"; + kitData.m_displayName = "Test debugger Id"; + kitData.m_icon = "/tmp/icon2.png"; + kitData.m_debuggerId = "debugger Id"; + kitData.m_env = env; + map = kitData.addKit(map, tcMap, qtMap, devMap, {}); + if (map.count() != 6) + return false; + if (!map.contains(VERSION) ) + return false; + if (map.value(VERSION).toInt() != 1) + return false; + if (!map.contains(COUNT) ) + return false; + if (map.value(COUNT).toInt() != 3) + return false; + if (!map.contains(DEFAULT) ) + return false; + if (map.value(DEFAULT).toInt() != 0) + return false; + if (!map.contains("Profile.0")) + return false; + if (!map.contains("Profile.1")) + return false; + if (!map.contains("Profile.2")) + return false; if (map.value("Profile.0") != profile0) return false; if (map.value("Profile.1") != profile1) return false; QVariantMap profile2 = map.value("Profile.2").toMap(); - if (profile2.count() != 6 - || !profile2.contains(ID) || profile2.value(ID).toString() != "test with debugger Id" - || !profile2.contains(DISPLAYNAME) || profile2.value(DISPLAYNAME).toString() != "Test debugger Id" - || !profile2.contains(ICON) || profile2.value(ICON).toString() != "/tmp/icon2.png" - || !profile2.contains(DATA) || profile2.value(DATA).type() != QVariant::Map - || !profile2.contains(AUTODETECTED) || profile2.value(AUTODETECTED).toBool() != true - || !profile2.contains(SDK) || profile2.value(SDK).toBool() != true) + if (profile2.count() != 6) + return false; + if (!profile2.contains(ID) ) + return false; + if (profile2.value(ID).toString() != "test with debugger Id") + return false; + if (!profile2.contains(DISPLAYNAME) ) + return false; + if (profile2.value(DISPLAYNAME).toString() != "Test debugger Id") + return false; + if (!profile2.contains(ICON) ) + return false; + if (profile2.value(ICON).toString() != "/tmp/icon2.png") + return false; + if (!profile2.contains(DATA) ) + return false; + if (profile2.value(DATA).type() != QVariant::Map) + return false; + if (!profile2.contains(AUTODETECTED) ) + return false; + if (profile2.value(AUTODETECTED).toBool() != true) + return false; + if (!profile2.contains(SDK) ) + return false; + if (profile2.value(SDK).toBool() != true) return false; data = profile2.value(DATA).toMap(); - if (data.count() != 7 - || !data.contains(DEBUGGER) || data.value(DEBUGGER).toString() != "debugger Id") + if (data.count() != 7) + return false; + if (!data.contains(DEBUGGER)) + return false; + if (data.value(DEBUGGER).toString() != "debugger Id") return false; return true; @@ -575,6 +731,10 @@ QVariantMap AddKitData::addKit(const QVariantMap &map, const QVariantMap &tcMap, std::cerr << "Error: Device " << qPrintable(m_device) << " does not exist." << std::endl; return QVariantMap(); } + if (!m_buildDevice.isEmpty() && !AddDeviceOperation::exists(devMap, m_buildDevice)) { + std::cerr << "Error: Device " << qPrintable(m_buildDevice) << " does not exist." << std::endl; + return QVariantMap(); + } // Treat a qt that was explicitly set to '' as "no Qt" if (!qtId.isNull() && qtId.isEmpty()) @@ -621,6 +781,8 @@ QVariantMap AddKitData::addKit(const QVariantMap &map, const QVariantMap &tcMap, data << KeyValuePair({kit, DATA, DEVICE_TYPE}, QVariant(m_deviceType)); if (!m_device.isNull()) data << KeyValuePair({kit, DATA, DEVICE_ID}, QVariant(m_device)); + if (!m_buildDevice.isNull()) + data << KeyValuePair({kit, DATA, BUILDDEVICE_ID}, QVariant(m_buildDevice)); if (!m_sysRoot.isNull()) data << KeyValuePair({kit, DATA, SYSROOT}, Utils::FilePath::fromUserInput(m_sysRoot).toVariant()); for (auto i = m_tcs.constBegin(); i != m_tcs.constEnd(); ++i) diff --git a/src/tools/sdktool/addkitoperation.h b/src/tools/sdktool/addkitoperation.h index 89b588e7944..3d3f3b8f5fd 100644 --- a/src/tools/sdktool/addkitoperation.h +++ b/src/tools/sdktool/addkitoperation.h @@ -47,6 +47,7 @@ public: QString m_debugger; QString m_deviceType; QString m_device; + QString m_buildDevice; QString m_sysRoot; QHash m_tcs; QString m_qt; diff --git a/src/tools/sdktool/rmkitoperation.cpp b/src/tools/sdktool/rmkitoperation.cpp index 306cfc3bd75..a2148c86ee9 100644 --- a/src/tools/sdktool/rmkitoperation.cpp +++ b/src/tools/sdktool/rmkitoperation.cpp @@ -116,22 +116,28 @@ bool RmKitOperation::test() const QHash tcs; tcs.insert("Cxx", "{tc-id}"); - QVariantMap map = - AddKitData{"testId", "Test Qt Version", "/tmp/icon.png", QString(), 1, - "/usr/bin/gdb-test", "Desktop", QString(), QString(), tcs, - "{qt-id}", "unsupported/mkspec", - QString(), QString(), QString(), QString(), QString(), QStringList(), QStringList(), - {{"PE.Profile.Data/extraData", QVariant("extraValue")}}} - .addKit(AddKitData::initializeKits(), tcMap, qtMap, devMap, {}); + AddKitData kitData; + kitData.m_id = "testId"; + kitData.m_displayName = "Test Qt Version"; + kitData.m_icon = "/tmp/icon.png"; + kitData.m_debuggerEngine = 1; + kitData.m_debugger = "/usr/bin/gdb-test"; + kitData.m_deviceType = "Desktop"; + kitData.m_tcs = tcs; + kitData.m_qt = "{qt-id}"; + kitData.m_mkspec = "unsupported/mkspec"; + kitData.m_extra = {{"PE.Profile.Data/extraData", QVariant("extraValue")}}; + + QVariantMap map = kitData.addKit(AddKitData::initializeKits(), tcMap, qtMap, devMap, {}); - map = AddKitData{"testId2", "Test Qt Version", - "/tmp/icon2.png", QString(), 1, "/usr/bin/gdb-test2", - "Desktop", QString(), QString(), tcs, "{qt-id}", - "unsupported/mkspec2", - QString(), QString(), QString(), QString(), QString(), QStringList(), QStringList(), - {{"PE.Profile.Data/extraData", QVariant("extraValue2")}}} - .addKit(map, tcMap, qtMap, devMap, {}); + kitData.m_id = "testId2"; + kitData.m_icon = "/tmp/icon2.png"; + kitData.m_icon = "/usr/bin/gdb-test2"; + kitData.m_mkspec = "unsupported/mkspec2"; + kitData.m_extra = {{"PE.Profile.Data/extraData", QVariant("extraValue2")}}; + + map = kitData.addKit(map, tcMap, qtMap, devMap, {}); QVariantMap result = rmKit(map, "testId"); if (result.count() != 4 diff --git a/tests/system/objects.map b/tests/system/objects.map index 60d760a6817..a222860aadc 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -84,7 +84,7 @@ :Go to slot.OK_QPushButton {text='OK' type='QPushButton' unnamed='1' visible='1' window=':Go to slot_QDialog'} :Go to slot.Select signal_QGroupBox {name='groupBox' title='Select signal' type='QGroupBox' visible='1' window=':Go to slot_QDialog'} :Go to slot_QDialog {name='SelectSignalDialog' type='QDialog' visible='1' windowTitle='Go to slot'} -:Help Widget_Help::Internal::HelpWidget {type='Help::Internal::HelpWidget' unnamed='1' visible='1' windowTitle?='Help -*'} +:Help Widget_Help::Internal::HelpWidget {type='Help::Internal::HelpWidget' unnamed='1' visible='1' windowTitle?='Help*'} :Hits_QLabel {text~='\\\\d+ - \\\\d+ of \\\\d+ Hits' type='QLabel' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Hits_QResultWidget {aboveWidget=':Hits_QLabel' type='QResultWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :JsonWizard_ProjectExplorer::JsonFieldPage {type='ProjectExplorer::JsonFieldPage' unnamed='1' visible='1' window=':New_ProjectExplorer::JsonWizard'} diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index 85d8c1d5e6c..e5f4c4bc6b6 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -31,9 +31,9 @@ def openQbsProject(projectPath): def openQmakeProject(projectPath, targets=Targets.desktopTargetClasses(), fromWelcome=False): cleanUpUserFiles(projectPath) if fromWelcome: - wsButtonFrame, wsButtonLabel = getWelcomeScreenMainButton('Open') + wsButtonFrame, wsButtonLabel = getWelcomeScreenSideBarButton('Open Project...') if not all((wsButtonFrame, wsButtonLabel)): - test.fatal("Could not find 'Open' button on Welcome Page.") + test.fatal("Could not find 'Open Project...' button on Welcome Page.") return [] mouseClick(wsButtonLabel) else: @@ -83,10 +83,10 @@ def openCmakeProject(projectPath, buildDir): def __createProjectOrFileSelectType__(category, template, fromWelcome = False, isProject=True): if fromWelcome: if not isProject: - test.fatal("'New' on Welcome screen only handles projects nowadays.") - wsButtonFrame, wsButtonLabel = getWelcomeScreenMainButton("New") + test.fatal("'Create Project...' on Welcome screen only handles projects nowadays.") + wsButtonFrame, wsButtonLabel = getWelcomeScreenSideBarButton("Create Project...") if not all((wsButtonFrame, wsButtonLabel)): - test.fatal("Could not find 'New' button on Welcome Page") + test.fatal("Could not find 'Create Project...' button on Welcome Page") return [] mouseClick(wsButtonLabel) elif isProject: diff --git a/tests/system/shared/welcome.py b/tests/system/shared/welcome.py index 86f773e275a..cb11074b878 100644 --- a/tests/system/shared/welcome.py +++ b/tests/system/shared/welcome.py @@ -41,8 +41,9 @@ def __getWelcomeScreenButtonHelper__(buttonLabel, widgetWithQFrames, isUrlButton return None, None def getWelcomeScreenSideBarButton(buttonLabel, isUrlButton = False): - sideBar = waitForObject("{type='Welcome::Internal::SideBar' unnamed='1' " - "window=':Qt Creator_Core::Internal::MainWindow'}") + sideBar = waitForObject("{container={type='Welcome::Internal::SideArea' unnamed='1' " + "window=':Qt Creator_Core::Internal::MainWindow'} type='QWidget' " + "unnamed='1'}") return __getWelcomeScreenButtonHelper__(buttonLabel, sideBar, isUrlButton) def getWelcomeScreenMainButton(buttonLabel): diff --git a/tests/system/suite_WELP/tst_WELP02/test.py b/tests/system/suite_WELP/tst_WELP02/test.py index d2650081f8d..e3537a573b7 100644 --- a/tests/system/suite_WELP/tst_WELP02/test.py +++ b/tests/system/suite_WELP/tst_WELP02/test.py @@ -75,13 +75,15 @@ def main(): return switchToSubMode('Projects') - typePropDet = (("QPushButton", "Get Started Now", "Get Started Now button"), - ("QTreeView", "Sessions", "Sessions section"), + typePropDet = (("QTreeView", "Sessions", "Sessions section"), ("SessionModelIndex", ("default", False), "default session listed"), ("QTreeView", "Recent Projects", "Projects section") ) checkTypeAndProperties(typePropDet) + getStartedF, getStartedL = getWelcomeScreenSideBarButton("Get Started") + test.verify(getStartedF is not None and getStartedL is not None, "'Get Started' button found") + # select "Create Project" and try to create a new project createNewQtQuickApplication(tempDir(), "SampleApp", fromWelcome = True) test.verify(checkIfObjectExists("{column='0' container=':Qt Creator_Utils::NavigationTreeView'" diff --git a/tests/system/suite_WELP/tst_WELP03/test.py b/tests/system/suite_WELP/tst_WELP03/test.py index 92e09f536a0..bc16fd0e597 100644 --- a/tests/system/suite_WELP/tst_WELP03/test.py +++ b/tests/system/suite_WELP/tst_WELP03/test.py @@ -42,10 +42,10 @@ def handlePackagingMessageBoxes(): def openExample(examplesLineEdit, input, exampleRegex, exampleName): replaceEditorContent(examplesLineEdit, input) - tableView = waitForObject("{type='QTableView' unnamed='1' visible='1' " + listView = waitForObject("{type='QListView' unnamed='1' visible='1' " "window=':Qt Creator_Core::Internal::MainWindow'}") - waitFor('findExampleOrTutorial(tableView, exampleRegex) is not None', 3000) - example = findExampleOrTutorial(tableView, exampleRegex, True) + waitFor('findExampleOrTutorial(listView, exampleRegex) is not None', 3000) + example = findExampleOrTutorial(listView, exampleRegex, True) if test.verify(example is not None, "Verifying: Example (%s) is shown." % exampleName): mouseClick(example) handlePackagingMessageBoxes() @@ -67,7 +67,7 @@ def main(): qchs.extend([os.path.join(p, "qtopengl.qch"), os.path.join(p, "qtwidgets.qch")]) addHelpDocumentation(qchs) setFixedHelpViewer(HelpViewer.HELPMODE) - wsButtonFrame, wsButtonLabel = getWelcomeScreenSideBarButton('Get Started Now') + wsButtonFrame, wsButtonLabel = getWelcomeScreenSideBarButton('Get Started') if not test.verify(all((wsButtonFrame, wsButtonLabel)), "Verifying: Qt Creator displays Welcome Page with Getting Started."): test.fatal("Something's wrong - leaving test.") @@ -75,7 +75,7 @@ def main(): return # select "Examples" topic switchToSubMode('Examples') - expect = (("QTableView", "unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'", + expect = (("QListView", "unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'", "examples list"), ("QLineEdit", "placeholderText='Search in Examples...'", "examples search line edit"), ("QComboBox", "currentText~='.*Qt.*' visible='1'", "Qt version combo box")) @@ -88,9 +88,9 @@ def main(): combo = waitForObject(search % (expect[2][0], expect[2][1])) test.log("Using examples from Kit %s." % str(combo.currentText)) replaceEditorContent(examplesLineEdit, "qwerty") - tableView = waitForObject(search % (expect[0][0], expect[0][1])) - waitFor('findExampleOrTutorial(tableView, ".*") is None', 3000) - example = findExampleOrTutorial(tableView, ".*", True) + listView = waitForObject(search % (expect[0][0], expect[0][1])) + waitFor('findExampleOrTutorial(listView, ".*") is None', 3000) + example = findExampleOrTutorial(listView, ".*", True) test.verify(example is None, "Verifying: No example is shown.") proFiles = map(lambda p: os.path.join(p, "opengl", "2dpainting", "2dpainting.pro"), diff --git a/tests/system/suite_WELP/tst_WELP04/test.py b/tests/system/suite_WELP/tst_WELP04/test.py index f66efba6c57..a5026808b48 100644 --- a/tests/system/suite_WELP/tst_WELP04/test.py +++ b/tests/system/suite_WELP/tst_WELP04/test.py @@ -30,7 +30,7 @@ def main(): startQC() if not startedWithoutPluginError(): return - wsButtonFrame, wsButtonLabel = getWelcomeScreenSideBarButton('Get Started Now') + wsButtonFrame, wsButtonLabel = getWelcomeScreenSideBarButton('Get Started') if not test.verify(all((wsButtonFrame, wsButtonLabel)), "Verifying: Qt Creator displays Welcome Page with Getting Started."): test.fatal("Something's wrong - leaving test.") @@ -44,16 +44,16 @@ def main(): searchTutorials = waitForObject("{type='QLineEdit' placeholderText='Search in Tutorials...'}") mouseClick(searchTutorials) replaceEditorContent(searchTutorials, "qwerty") - tableView = waitForObject("{type='QTableView' unnamed='1' visible='1' " + listView = waitForObject("{type='QListView' unnamed='1' visible='1' " "window=':Qt Creator_Core::Internal::MainWindow'}") - waitFor('findExampleOrTutorial(tableView, ".*") is None', 3000) - tutorial = findExampleOrTutorial(tableView, ".*", True) + waitFor('findExampleOrTutorial(listView, ".*") is None', 3000) + tutorial = findExampleOrTutorial(listView, ".*", True) test.verify(tutorial is None, "Verifying: 'Tutorials' topic is opened and nothing is shown.") bnr = "Help: Building and Running an Example" replaceEditorContent(searchTutorials, bnr.lower()) - waitFor('findExampleOrTutorial(tableView, "%s.*") is not None' % bnr, 3000) - tutorial = findExampleOrTutorial(tableView, "%s.*" % bnr, True) + waitFor('findExampleOrTutorial(listView, "%s.*") is not None' % bnr, 3000) + tutorial = findExampleOrTutorial(listView, "%s.*" % bnr, True) test.verify(tutorial is not None, "Verifying: Expected Text tutorial is shown.") # clicking before documentation was updated will open the tutorial in browser progressBarWait(warn=False) @@ -67,8 +67,9 @@ def main(): # check a demonstration video link mouseClick(searchTutorials) replaceEditorContent(searchTutorials, "embedded device") - waitFor('findExampleOrTutorial(tableView, "Online: Qt for Device Creation.*") is not None', 3000) - tutorial = findExampleOrTutorial(tableView, "Online: Qt for Device Creation.*", True) + embeddedTutorial = "Online: How to install and set up Qt for Device Creation.*" + waitFor('findExampleOrTutorial(listView, embeddedTutorial) is not None', 3000) + tutorial = findExampleOrTutorial(listView, embeddedTutorial, True) test.verify(tutorial is not None, "Verifying: Link to the expected demonstration video exists.") # exit Qt Creator