diff --git a/dist/changes-4.7.0.md b/dist/changes-4.7.0.md index 84014306a2b..4967dd3472b 100644 --- a/dist/changes-4.7.0.md +++ b/dist/changes-4.7.0.md @@ -29,6 +29,7 @@ Editing * Added `Context Help` to editor context menu (QTCREATORBUG-55) * Added previous and next buttons to bookmarks view, and polished their behavior (QTCREATORBUG-9859, QTCREATORBUG-20061) +* Added support for `WordDetect` in Kate highlighting files * Fixed that extra editor windows were not restored when opening session (QTCREATORBUG-13840) * Fixed that editor could stay busy repainting annotations (QTCREATORBUG-20422) @@ -76,6 +77,7 @@ C++ Support (category `Clang Code Model`) * Added highlighting style for overloaded operators (QTCREATORBUG-19659) * Added option to use `.clang-tidy` configuration file or checks string + * Added default configurations for Clang-Tidy and Clazy checks * Added link to the documentation in tooltip for Clang-Tidy and Clazy diagnostics * Improved reparse performance and memory usage @@ -92,6 +94,7 @@ QML Support * Fixed that reformatting incorrectly removed quotes (QTCREATORBUG-17455) * Fixed that `.pragma` and `.import` were removed when reformatting (QTCREATORBUG-13038) +* Fixed that import completion did not offer `QtWebEngine` (QTCREATORBUG-20723) Python Support @@ -99,8 +102,16 @@ Python Support Debugging +* Fixed updating of memory view * QML * Added support for nested properties (QTBUG-68474) + * Fixed issue with different endianness (QTBUG-68721) + +Qt Quick Designer + +* Fixed crash when adding quotes to text (QTCREATORBUG-20684) +* Fixed that meta data could move in source code even when no changes occurred + (QTCREATORBUG-20686) Clang Static Analyzer @@ -119,6 +130,7 @@ Version Control Systems * Added `-git-show ` command line parameter * Gerrit * Added warning when pushing to wrong branch (QTCREATORBUG-20062) + * Fixed updating after settings change (QTCREATORBUG-20536) Image Viewer @@ -134,6 +146,7 @@ Test Integration (QTCREATORBUG-18725) * Qt Quick * Fixed parsing issue with non-ASCII characters (QTCREATORBUG-20105) + * Fixed detection of test name (QTCREATORBUG-20642) Platform Specific @@ -141,11 +154,15 @@ Windows * Improved parsing of MSVC error messages (QTCREATORBUG-20297) * Fixed that querying MSVC tool chains at startup could block Qt Creator +* Fixed issue with writing to network drives (QTCREATORBUG-20560) * Fixed issue with Clang and Qt 5.8 and later (QTCREATORBUG-20021) +* Fixed handling of Windows debug stream which could lead to freezes + (QTCREATORBUG-20640) Android * Improved behavior when emulator cannot be started (QTCREATORBUG-20160) +* Fixed QML debugger connection issue from macOS client (QTCREATORBUG-20730) Credits for these changes go to: Aaron Barany @@ -172,9 +189,11 @@ Jaroslaw Kobus Jay Gupta José Tomás Tocino Jörg Bornemann +Kai Köhne Kari Oikarinen Kimmo Linnavuo Leena Miettinen +Lorenz Haas Marco Benelli Marco Bubke Mitch Curtis @@ -187,6 +206,7 @@ Przemyslaw Gorszkowski Razi Alavizadeh Robert Löhning Rune Espeseth +Sergey Belyashov Sergey Morozov Tasuku Suzuki Thiago Macieira diff --git a/doc/src/cpp/creator-sidebar-cpp-views.qdocinc b/doc/src/cpp/creator-sidebar-cpp-views.qdocinc new file mode 100644 index 00000000000..5acefba93eb --- /dev/null +++ b/doc/src/cpp/creator-sidebar-cpp-views.qdocinc @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Creator documentation. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** +****************************************************************************/ + +/*! +//! [cpp sidebar views] + +The following views display additional information about C++ code: + + \list + \li \uicontrol {Class View} shows the class hierarchy of the currently + open projects. + \li \uicontrol Tests lists autotests and Qt Quick tests in the project. + For more information, see \l {Running Autotests}. + \li \uicontrol {Type Hierarchy} shows the base classes of a class. + \li \uicontrol {Include Hierarchy} shows which files are included in + the current file and which files include the current file. + \endlist + +//! [cpp sidebar views] + + +//! [class view] + + \section2 Viewing the Class Hierarchy + + The \uicontrol {Class View} shows the class hierarchy of the currently + open projects. To organize the view by subprojects, click + \inlineimage qtcreator-show-subprojects.png + (\uicontrol {Show Subprojects}). + + To visit all parts of a namespace, double-click on the namespace item + multiple times. + +//! [class view] + + +//! [type hierarchy view] + + \section2 Viewing Type Hierarchy + + To view the base classes of a class, right-click the class and select + \uicontrol {Open Type Hierarchy} or press \key {Ctrl+Shift+T}. + +//! [type hierarchy view] + + +//! [include hierarchy view] + + \section2 Viewing Include Hierarchy + + To view which files are included in the current file and which files include + the current file, right-click in the editor and select + \uicontrol {Open Include Hierarchy} or press \key {Ctrl+Shift+I}. + +//! [include hierarchy view] +*/ diff --git a/doc/src/howto/creator-ui.qdoc b/doc/src/howto/creator-ui.qdoc index 5cb7a65a8fa..f753e9054a2 100644 --- a/doc/src/howto/creator-ui.qdoc +++ b/doc/src/howto/creator-ui.qdoc @@ -136,22 +136,13 @@ \li \uicontrol{File System} shows all files in the currently selected directory. - \li \uicontrol {Class View} shows the class hierarchy of the currently - open projects. - - \li \uicontrol Outline shows the symbol hierarchy of a C++ file and the type - hierarchy of a QML file. - - \li \uicontrol Tests lists autotests and Qt Quick tests in the project. - For more information, see \l {Running Autotests}. - - \li \uicontrol {Type Hierarchy} shows the base classes of a class. - - \li \uicontrol {Include Hierarchy} shows which files are included in the current file - and which files include the current file. + \li \uicontrol Outline shows an overview of defined types and other + symbols, as well as their properties and hierarchy in a source file. \endlist + \include creator-sidebar-cpp-views.qdocinc cpp sidebar views + For more information about the sidebar views that are only available when editing QML files in the Design mode, see \l{Editing QML Files in Design Mode}. @@ -326,16 +317,6 @@ \endlist - \section2 Viewing the Class Hierarchy - - The \uicontrol {Class View} shows the class hierarchy of the currently - open projects. To organize the view by subprojects, click - \inlineimage qtcreator-show-subprojects.png - (\uicontrol {Show Subprojects}). - - To visit all parts of a namespace, double-click on the namespace item - multiple times. - \section2 Viewing QML Types The \uicontrol Outline view shows the type hierarchy in a QML file. @@ -350,16 +331,9 @@ \endlist - \section2 Viewing Type Hierarchy - - To view the base classes of a class, right-click the class and select - \uicontrol {Open Type Hierarchy} or press \key {Ctrl+Shift+T}. - - \section2 Viewing Include Hierarchy - - To view which files are included in the current file and which files include - the current file, right-click in the editor and select \uicontrol {Open Include Hierarchy} - or press \key {Ctrl+Shift+I}. + \include creator-sidebar-cpp-views.qdocinc class view + \include creator-sidebar-cpp-views.qdocinc type hierarchy view + \include creator-sidebar-cpp-views.qdocinc include hierarchy view \section1 Viewing Output diff --git a/share/qtcreator/debugger/gdbbridge.py b/share/qtcreator/debugger/gdbbridge.py index 117f5fcfdd8..618c4113ee8 100644 --- a/share/qtcreator/debugger/gdbbridge.py +++ b/share/qtcreator/debugger/gdbbridge.py @@ -1002,7 +1002,12 @@ class Dumper(DumperBase): try: symbols = gdb.execute(cmd, to_string = True) except: - pass + # command syntax depends on gdb version - below is gdb 8+ + cmd = 'maint print msymbols -objfile "%s" -- %s' % (objfile.filename, tmppath) + try: + symbols = gdb.execute(cmd, to_string = True) + except: + pass ns = '' with open(tmppath) as f: for line in f: diff --git a/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt b/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt index 07c1f586086..f28d772a1a4 100644 --- a/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt +++ b/share/qtcreator/templates/wizards/projects/qtquickapplication/CMakeLists.txt @@ -11,5 +11,5 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(Qt5 COMPONENTS Core Quick REQUIRED) add_executable(${PROJECT_NAME} "%{MainCppFileName}" "qml.qrc") - -target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Quick) +target_compile_definitions(${PROJECT_NAME} PRIVATE $<$,$>:QT_QML_DEBUG>) +target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Core Qt5::Quick) diff --git a/share/qtcreator/translations/qtcreator_de.ts b/share/qtcreator/translations/qtcreator_de.ts index 2d4f46b0601..717dd81d3b1 100644 --- a/share/qtcreator/translations/qtcreator_de.ts +++ b/share/qtcreator/translations/qtcreator_de.ts @@ -16812,7 +16812,7 @@ Soll es noch einmal versucht werden? No compiler can produce code for this Qt version. Please define one or more compilers for: %1 - Kein Compiler kann für diese Qt-Version Code erzeugen. Bitte richten Sie einen oder mehrere für "%1" geeignete Compiler ein. + Kein Compiler kann für diese Qt-Version Code erzeugen. Bitte richten Sie einen oder mehrere Compiler ein, geeignet für: %1 The following ABIs are currently not supported: %1 diff --git a/src/libs/clangsupport/clangsupport_global.h b/src/libs/clangsupport/clangsupport_global.h index def7cea41c0..01e9e2c7f40 100644 --- a/src/libs/clangsupport/clangsupport_global.h +++ b/src/libs/clangsupport/clangsupport_global.h @@ -104,7 +104,9 @@ enum class HighlightingType : quint8 ObjectiveCInterface, ObjectiveCImplementation, ObjectiveCProperty, - ObjectiveCMethod + ObjectiveCMethod, + TemplateTypeParameter, + TemplateTemplateParameter }; enum class StorageClass : quint8 diff --git a/src/libs/clangsupport/tokeninfocontainer.cpp b/src/libs/clangsupport/tokeninfocontainer.cpp index 157f93746c7..2744200c60e 100644 --- a/src/libs/clangsupport/tokeninfocontainer.cpp +++ b/src/libs/clangsupport/tokeninfocontainer.cpp @@ -70,6 +70,8 @@ static const char *highlightingTypeToCStringLiteral(HighlightingType type) RETURN_TEXT_FOR_CASE(ObjectiveCMethod); RETURN_TEXT_FOR_CASE(PrimitiveType); RETURN_TEXT_FOR_CASE(Declaration); + RETURN_TEXT_FOR_CASE(TemplateTypeParameter); + RETURN_TEXT_FOR_CASE(TemplateTemplateParameter); default: return "UnhandledHighlightingType"; } } diff --git a/src/libs/clangsupport/tokeninfocontainer.h b/src/libs/clangsupport/tokeninfocontainer.h index 8bd57b9f954..d01d0f92eb0 100644 --- a/src/libs/clangsupport/tokeninfocontainer.h +++ b/src/libs/clangsupport/tokeninfocontainer.h @@ -129,6 +129,13 @@ public: bool isGlobalDeclaration() const { + if (types.mixinHighlightingTypes.contains( + ClangBackEnd::HighlightingType::TemplateTypeParameter) + || types.mixinHighlightingTypes.contains( + ClangBackEnd::HighlightingType::TemplateTemplateParameter)) { + return false; + } + return extraInfo.declaration && types.mainHighlightingType != HighlightingType::LocalVariable && ((types.mainHighlightingType == HighlightingType::Operator) diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index f49296a418d..92a06639e6e 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -416,6 +416,17 @@ FileName AndroidConfig::avdManagerToolPath() const return avdManagerPath; } +FileName AndroidConfig::aaptToolPath() const +{ + Utils::FileName aaptToolPath = m_sdkLocation; + aaptToolPath.appendPath("build-tools"); + QString toolPath = QString("%1/aapt").arg(buildToolsVersion().toString()); + if (HostOsInfo::isWindowsHost()) + toolPath += ANDROID_BAT_SUFFIX; + aaptToolPath.appendPath(toolPath); + return aaptToolPath; +} + FileName AndroidConfig::gccPath(const Abi &abi, Core::Id lang, const QString &ndkToolChainVersion) const { diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index 58dde7479ba..0a7fa4c3b72 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -132,6 +132,7 @@ public: Utils::FileName emulatorToolPath() const; Utils::FileName sdkManagerToolPath() const; Utils::FileName avdManagerToolPath() const; + Utils::FileName aaptToolPath() const; Utils::FileName gccPath(const ProjectExplorer::Abi &abi, Core::Id lang, const QString &ndkToolChainVersion) const; diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp index 0046772f897..bbeb72138ab 100644 --- a/src/plugins/android/androiddebugsupport.cpp +++ b/src/plugins/android/androiddebugsupport.cpp @@ -45,6 +45,7 @@ #include #include +#include namespace { Q_LOGGING_CATEGORY(androidDebugSupportLog, "qtc.android.run.androiddebugsupport") @@ -142,7 +143,10 @@ void AndroidDebugSupport::start() + "/app_process"); setSkipExecutableValidation(true); setUseExtendedRemote(true); - setRemoteChannel(":" + m_runner->gdbServerPort().toString()); + QUrl gdbServer; + gdbServer.setHost(QHostAddress(QHostAddress::LocalHost).toString()); + gdbServer.setPort(m_runner->gdbServerPort().number()); + setRemoteChannel(gdbServer); QString sysRoot = AndroidConfigurations::currentConfig().ndkLocation().appendPath("platforms") .appendPath(QString("android-%1").arg(AndroidManager::minimumSDK(target))) diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index 2d10f766ce6..ac0b01a0520 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -61,17 +61,43 @@ #include #include #include - -namespace { -Q_LOGGING_CATEGORY(androidManagerLog, "qtc.android.androidManager") -} +#include namespace { const QLatin1String AndroidManifestName("AndroidManifest.xml"); const QLatin1String AndroidDefaultPropertiesName("project.properties"); const QLatin1String AndroidDeviceSn("AndroidDeviceSerialNumber"); const QLatin1String ApiLevelKey("AndroidVersion.ApiLevel"); + const QString packageNameRegEx("(package: name=)\\'(([a-z]{1}[a-z\\d_]*\\." + ")*[a-z][a-z\\d_]*)\\'"); + const QString activityRegEx("(launchable-activity: name=)\\'" + "(([a-z]{1}[a-z\\d_]*\\.)*[a-z][a-z\\d_]*)\\'"); + const QString apkVersionRegEx("package: name=([\\=a-z\\d_\\.\\'\\s]*)" + "\\sversionName='([\\d\\.]*)'"); + Q_LOGGING_CATEGORY(androidManagerLog, "qtc.android.androidManager") + + bool runCommand(const QString &executable, const QStringList &args, + QString *output = nullptr, int timeoutS = 30) + { + Utils::SynchronousProcess cmdProc; + cmdProc.setTimeoutS(timeoutS); + qCDebug(androidManagerLog) << executable << args.join(' '); + Utils::SynchronousProcessResponse response = cmdProc.runBlocking(executable, args); + if (output) + *output = response.allOutput(); + return response.result == Utils::SynchronousProcessResponse::Finished; + } + + QString parseAaptOutput(const QString &output, const QString ®Ex) { + const QRegularExpression regRx(regEx, + QRegularExpression::CaseInsensitiveOption | + QRegularExpression::MultilineOption); + QRegularExpressionMatch match = regRx.match(output); + if (match.hasMatch()) + return match.captured(2); + return QString(); + }; } // anonymous namespace @@ -127,6 +153,53 @@ QString AndroidManager::packageName(const Utils::FileName &manifestFile) return manifestElem.attribute(QLatin1String("package")); } +bool AndroidManager::packageInstalled(const QString &deviceSerial, + const QString &packageName) +{ + if (deviceSerial.isEmpty() || packageName.isEmpty()) + return false; + QStringList args = AndroidDeviceInfo::adbSelector(deviceSerial); + args << "shell" << "pm" << "list" << "packages"; + QString output; + runAdbCommand(args, &output); + QStringList lines = output.split(QRegularExpression("[\\n\\r]"), + QString::SkipEmptyParts); + for (const QString &line : lines) { + // Don't want to confuse com.abc.xyz with com.abc.xyz.def so check with + // endsWith + if (line.endsWith(packageName)) + return true; + } + return false; +} + +void AndroidManager::apkInfo(const Utils::FileName &apkPath, + QString *packageName, + QVersionNumber *version, + QString *activityPath) +{ + QString output; + runAaptCommand({"dump", "badging", apkPath.toString()}, &output); + + QString packageStr; + if (activityPath) { + packageStr = parseAaptOutput(output, packageNameRegEx); + QString path = parseAaptOutput(output, activityRegEx); + if (!packageStr.isEmpty() && !path.isEmpty()) + *activityPath = packageStr + '/' + path; + } + + if (packageName) { + *packageName = activityPath ? packageStr : + parseAaptOutput(output, packageNameRegEx); + } + + if (version) { + QString versionStr = parseAaptOutput(output, apkVersionRegEx); + *version = QVersionNumber::fromString(versionStr); + } +} + QString AndroidManager::intentName(ProjectExplorer::Target *target) { return packageName(target) + QLatin1Char('/') + activityName(target); @@ -381,16 +454,9 @@ void AndroidManager::cleanLibsOnDevice(ProjectExplorer::Target *target) Core::MessageManager::write(tr("Starting Android virtual device failed.")); } - QProcess *process = new QProcess(); QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber); arguments << QLatin1String("shell") << QLatin1String("rm") << QLatin1String("-r") << QLatin1String("/data/local/tmp/qt"); - QObject::connect(process, static_cast(&QProcess::finished), - process, &QObject::deleteLater); - const QString adb = AndroidConfigurations::currentConfig().adbToolPath().toString(); - Core::MessageManager::write(adb + QLatin1Char(' ') + arguments.join(QLatin1Char(' '))); - process->start(adb, arguments); - if (!process->waitForStarted(500)) - delete process; + runAdbCommandDetached(arguments); } void AndroidManager::installQASIPackage(ProjectExplorer::Target *target, const QString &packagePath) @@ -410,17 +476,9 @@ void AndroidManager::installQASIPackage(ProjectExplorer::Target *target, const Q Core::MessageManager::write(tr("Starting Android virtual device failed.")); } - QProcess *process = new QProcess(); QStringList arguments = AndroidDeviceInfo::adbSelector(deviceSerialNumber); arguments << QLatin1String("install") << QLatin1String("-r ") << packagePath; - - connect(process, static_cast(&QProcess::finished), - process, &QObject::deleteLater); - const QString adb = AndroidConfigurations::currentConfig().adbToolPath().toString(); - Core::MessageManager::write(adb + QLatin1Char(' ') + arguments.join(QLatin1Char(' '))); - process->start(adb, arguments); - if (!process->waitForStarted(500) && process->state() != QProcess::Running) - delete process; + runAdbCommandDetached(arguments); } bool AndroidManager::checkKeystorePassword(const QString &keystorePath, const QString &keystorePasswd) @@ -603,4 +661,27 @@ int AndroidManager::findApiLevel(const Utils::FileName &platformPath) return apiLevel; } +void AndroidManager::runAdbCommandDetached(const QStringList &args) +{ + QProcess *process = new QProcess(); + connect(process, static_cast(&QProcess::finished), + process, &QObject::deleteLater); + const QString adb = AndroidConfigurations::currentConfig().adbToolPath().toString(); + qCDebug(androidManagerLog) << adb << args.join(' '); + process->start(adb, args); + if (!process->waitForStarted(500) && process->state() != QProcess::Running) + delete process; +} + +bool AndroidManager::runAdbCommand(const QStringList &args, QString *output) +{ + return runCommand(AndroidConfigurations::currentConfig().adbToolPath().toString(), + args, output); +} + +bool AndroidManager::runAaptCommand(const QStringList &args, QString *output) +{ + return runCommand(AndroidConfigurations::currentConfig().aaptToolPath().toString(), + args, output); +} } // namespace Android diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h index 0d35cf2f984..b7bbef922dd 100644 --- a/src/plugins/android/androidmanager.h +++ b/src/plugins/android/androidmanager.h @@ -29,6 +29,7 @@ #include #include +#include namespace ProjectExplorer { class Kit; @@ -48,7 +49,12 @@ class ANDROID_EXPORT AndroidManager : public QObject public: static QString packageName(ProjectExplorer::Target *target); static QString packageName(const Utils::FileName &manifestFile); - + static bool packageInstalled(const QString &deviceSerial, + const QString &packageName); + static void apkInfo(const Utils::FileName &apkPath, + QString *packageName = nullptr, + QVersionNumber *version = nullptr, + QString *activityPath = nullptr); static QString intentName(ProjectExplorer::Target *target); static QString activityName(ProjectExplorer::Target *target); @@ -86,6 +92,10 @@ public: static AndroidQtSupport *androidQtSupport(ProjectExplorer::Target *target); static bool updateGradleProperties(ProjectExplorer::Target *target); static int findApiLevel(const Utils::FileName &platformPath); + + static void runAdbCommandDetached(const QStringList &args); + static bool runAdbCommand(const QStringList &args, QString *output = nullptr); + static bool runAaptCommand(const QStringList &args, QString *output = nullptr); }; } // namespace Android diff --git a/src/plugins/android/androidrunner.cpp b/src/plugins/android/androidrunner.cpp index eb40d07f739..d5ed812ff8b 100644 --- a/src/plugins/android/androidrunner.cpp +++ b/src/plugins/android/androidrunner.cpp @@ -34,6 +34,7 @@ #include "androidavdmanager.h" #include "androidrunnerworker.h" +#include #include #include #include @@ -206,6 +207,7 @@ void AndroidRunner::qmlServerPortReady(Port port) // device side. It only happens to work since we redirect // host port n to target port n via adb. QUrl serverUrl; + serverUrl.setHost(QHostAddress(QHostAddress::LocalHost).toString()); serverUrl.setPort(port.number()); serverUrl.setScheme(urlTcpScheme()); emit qmlServerReady(serverUrl); diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp index a7b39abd728..bffe6e0e78f 100644 --- a/src/plugins/android/androidrunnerworker.cpp +++ b/src/plugins/android/androidrunnerworker.cpp @@ -176,8 +176,7 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa if (m_qmlDebugServices != QmlDebug::NoQmlDebugServices) { qCDebug(androidRunWorkerLog) << "QML debugging enabled"; QTcpServer server; - QTC_ASSERT(server.listen(QHostAddress::LocalHost) - || server.listen(QHostAddress::LocalHostIPv6), + QTC_ASSERT(server.listen(QHostAddress::LocalHost), qDebug() << tr("No free ports available on host for QML debugging.")); m_qmlServer.setScheme(Utils::urlTcpScheme()); m_qmlServer.setHost(server.serverAddress().toString()); diff --git a/src/plugins/clangcodemodel/clanghighlightingresultreporter.cpp b/src/plugins/clangcodemodel/clanghighlightingresultreporter.cpp index ef1b905a8d8..795941f6ec9 100644 --- a/src/plugins/clangcodemodel/clanghighlightingresultreporter.cpp +++ b/src/plugins/clangcodemodel/clanghighlightingresultreporter.cpp @@ -108,6 +108,8 @@ bool ignore(ClangBackEnd::HighlightingType type) case HighlightingType::ObjectiveCImplementation: case HighlightingType::ObjectiveCProperty: case HighlightingType::ObjectiveCMethod: + case HighlightingType::TemplateTypeParameter: + case HighlightingType::TemplateTemplateParameter: return true; } diff --git a/src/plugins/clangcodemodel/clangoverviewmodel.cpp b/src/plugins/clangcodemodel/clangoverviewmodel.cpp index fc6dce919a8..e663eec27a3 100644 --- a/src/plugins/clangcodemodel/clangoverviewmodel.cpp +++ b/src/plugins/clangcodemodel/clangoverviewmodel.cpp @@ -96,6 +96,20 @@ static QString addType(const QString &name, const ClangBackEnd::ExtraInfo &extra return name + QLatin1String(" -> ", 4) + extraInfo.typeSpelling.toString(); } +static QString fullName(const ClangBackEnd::ExtraInfo &extraInfo, TokenTreeItem *parent) +{ + const QString parentType = parent->token.extraInfo.typeSpelling.toString(); + if (extraInfo.semanticParentTypeSpelling.startsWith(parentType)) { + const QString parentQualification = parentType.isEmpty() + ? extraInfo.semanticParentTypeSpelling + : extraInfo.semanticParentTypeSpelling.mid(parentType.length() + 2); + if (!parentQualification.isEmpty()) + return parentQualification + "::" + extraInfo.token.toString(); + } + + return extraInfo.token.toString(); +} + QVariant TokenTreeItem::data(int column, int role) const { Q_UNUSED(column) @@ -109,7 +123,8 @@ QVariant TokenTreeItem::data(int column, int role) const switch (role) { case Qt::DisplayRole: { - QString name = token.extraInfo.token.toString(); + QString name = fullName(token.extraInfo, static_cast(parent())); + ClangBackEnd::HighlightingType mainType = token.types.mainHighlightingType; if (mainType == ClangBackEnd::HighlightingType::VirtualFunction diff --git a/src/plugins/debugger/debuggermainwindow.h b/src/plugins/debugger/debuggermainwindow.h index cc93e7a00fc..08970aaeadc 100644 --- a/src/plugins/debugger/debuggermainwindow.h +++ b/src/plugins/debugger/debuggermainwindow.h @@ -140,6 +140,8 @@ public: void setPerspectiveEnabled(const QByteArray &perspectiveId, bool enabled); private: + void closeEvent(QCloseEvent *) final { saveCurrentPerspective(); } + QDockWidget *registerDockWidget(const QByteArray &dockId, QWidget *widget); void loadPerspectiveHelper(const QByteArray &perspectiveId, bool fromStoredSettings = true); diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index efc17e824cc..06041d474e6 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -2795,7 +2795,6 @@ void DebuggerPluginPrivate::aboutToShutdown() disconnect(SessionManager::instance(), &SessionManager::startupProjectChanged, this, nullptr); - m_mainWindow->saveCurrentPerspective(); m_shutdownTimer.setInterval(0); m_shutdownTimer.setSingleShot(true); connect(&m_shutdownTimer, &QTimer::timeout, this, &DebuggerPluginPrivate::doShutdown); diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index a59b35c3932..ef6d38650f1 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -138,6 +138,12 @@ struct LookupData typedef QHash LookupItems; // id -> (iname, exp) +static void setWatchItemHasChildren(WatchItem *item, bool hasChildren) +{ + item->setHasChildren(hasChildren); + item->valueEditable = !hasChildren; +} + class QmlEnginePrivate : public QmlDebugClient { public: @@ -1311,7 +1317,7 @@ void QmlEnginePrivate::handleEvaluateExpression(const QVariantMap &response, if (success) { item->type = body.type; item->value = body.value.toString(); - item->setHasChildren(body.hasChildren()); + setWatchItemHasChildren(item, body.hasChildren()); } else { //Do not set type since it is unknown item->setError(body.value.toString()); @@ -2156,11 +2162,11 @@ void QmlEnginePrivate::handleFrame(const QVariantMap &response) item->id = objectData.handle; item->type = objectData.type; item->value = objectData.value.toString(); - item->setHasChildren(objectData.hasChildren()); + setWatchItemHasChildren(item, objectData.hasChildren()); // In case of global object, we do not get children // Set children nevertheless and query later. if (item->value == "global") { - item->setHasChildren(true); + setWatchItemHasChildren(item, true); item->id = 0; } watchHandler->insertItem(item); @@ -2244,10 +2250,13 @@ void QmlEnginePrivate::handleScope(const QVariantMap &response) item->id = localData.handle; item->type = localData.type; item->value = localData.value.toString(); - item->setHasChildren(localData.hasChildren()); + setWatchItemHasChildren(item.get(), localData.hasChildren()); if (localData.value.isValid() || item->wantsChildren || localData.expectedProperties == 0) { - engine->watchHandler()->insertItem(item.release()); + WatchHandler *watchHander = engine->watchHandler(); + if (watchHander->isExpandedIName(item->iname)) + itemsToLookup.insert(int(item->id), {item->iname, item->name, item->exp}); + watchHander->insertItem(item.release()); } else { itemsToLookup.insert(int(item->id), {item->iname, item->name, item->exp}); } @@ -2387,7 +2396,7 @@ void QmlEnginePrivate::insertSubItems(WatchItem *parent, const QVariantList &pro item->value = propertyData.value.toString(); if (item->type.isEmpty() || expandedINames.contains(item->iname)) itemsToLookup.insert(propertyData.handle, {item->iname, item->name, item->exp}); - item->setHasChildren(propertyData.hasChildren()); + setWatchItemHasChildren(item.get(), propertyData.hasChildren()); parent->appendChild(item.release()); } @@ -2443,7 +2452,7 @@ void QmlEnginePrivate::handleLookup(const QVariantMap &response) item->type = bodyObjectData.type; item->value = bodyObjectData.value.toString(); - item->setHasChildren(bodyObjectData.hasChildren()); + setWatchItemHasChildren(item, bodyObjectData.hasChildren()); insertSubItems(item, bodyObjectData.properties); engine->watchHandler()->insertItem(item); diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 08e1cdb88dd..e2fa7fe8d53 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -795,7 +795,8 @@ QString GitClient::findGitDirForRepository(const QString &repositoryDir) const bool GitClient::managesFile(const QString &workingDirectory, const QString &fileName) const { - return vcsFullySynchronousExec(workingDirectory, {"ls-files", "--error-unmatch", fileName}).result + return vcsFullySynchronousExec(workingDirectory, {"ls-files", "--error-unmatch", fileName}, + Core::ShellCommand::NoOutput).result == SynchronousProcessResponse::Finished; } diff --git a/src/plugins/projectexplorer/msvctoolchain.cpp b/src/plugins/projectexplorer/msvctoolchain.cpp index 0d535182364..80973d751c4 100644 --- a/src/plugins/projectexplorer/msvctoolchain.cpp +++ b/src/plugins/projectexplorer/msvctoolchain.cpp @@ -1008,6 +1008,32 @@ static const ToolChain *selectMsvcToolChain(const QString &clangClPath, return toolChain; } +static void detectClangClToolChainInPath(const QString &clangClPath, QList *list) +{ + const unsigned char wordWidth = Utils::is64BitWindowsBinary(clangClPath) ? 64 : 32; + const ToolChain *toolChain = selectMsvcToolChain(clangClPath, *list, wordWidth); + + QDir path = QFileInfo(clangClPath).absoluteDir(); // bin folder + path.cdUp(); // cd to LLVM root + const QString rootPath = path.canonicalPath(); + + if (!toolChain) { + qWarning("Unable to find a suitable MSVC version for \"%s\".", + qPrintable(QDir::toNativeSeparators(rootPath))); + return; + } + const MsvcToolChain *msvcToolChain = static_cast(toolChain); + const Abi targetAbi = msvcToolChain->targetAbi(); + const QString name = QStringLiteral("LLVM ") + QString::number(wordWidth) + + QStringLiteral("bit based on ") + + Abi::toString(targetAbi.osFlavor()).toUpper(); + for (auto language: {Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}) { + list->append(new ClangClToolChain(name, rootPath, targetAbi, + msvcToolChain->varsBat(), msvcToolChain->varsBatArg(), + language, ToolChain::AutoDetection)); + } +} + // Detect Clang-cl on top of MSVC2017, MSVC2015 or MSVC2013. static void detectClangClToolChain(QList *list) { @@ -1018,28 +1044,19 @@ static void detectClangClToolChain(QList *list) #endif const QSettings registry(QLatin1String(registryNode), QSettings::NativeFormat); - if (registry.status() != QSettings::NoError) - return; - const QString path = QDir::cleanPath(registry.value(QStringLiteral(".")).toString()); - if (path.isEmpty()) - return; - const QString clangClPath = compilerFromPath(path); - const unsigned char wordWidth = Utils::is64BitWindowsBinary(clangClPath) ? 64 : 32; - const ToolChain *toolChain = selectMsvcToolChain(clangClPath, *list, wordWidth); - if (!toolChain) { - qWarning("Unable to find a suitable MSVC version for \"%s\".", qPrintable(QDir::toNativeSeparators(path))); - return; - } - const MsvcToolChain *msvcToolChain = static_cast(toolChain); - const Abi targetAbi = msvcToolChain->targetAbi(); - const QString name = QStringLiteral("LLVM ") + QString::number(wordWidth) - + QStringLiteral("bit based on ") - + Abi::toString(targetAbi.osFlavor()).toUpper(); - for (auto language: {Constants::C_LANGUAGE_ID, Constants::CXX_LANGUAGE_ID}) { - list->append(new ClangClToolChain(name, path, targetAbi, - msvcToolChain->varsBat(), msvcToolChain->varsBatArg(), - language, ToolChain::AutoDetection)); + if (registry.status() == QSettings::NoError) { + const QString path = QDir::cleanPath(registry.value(QStringLiteral(".")).toString()); + const QString clangClPath = compilerFromPath(path); + if (!path.isEmpty()) { + detectClangClToolChainInPath(path, list); + return; + } } + + const Utils::Environment systemEnvironment = Utils::Environment::systemEnvironment(); + const Utils::FileName clangClPath = systemEnvironment.searchInPath("clang-cl"); + if (!clangClPath.isEmpty()) + detectClangClToolChainInPath(clangClPath.toString(), list); } QList MsvcToolChainFactory::autoDetect(const QList &alreadyKnown) diff --git a/src/plugins/projectexplorer/taskmodel.cpp b/src/plugins/projectexplorer/taskmodel.cpp index 981f85651d3..0b3381fadc2 100644 --- a/src/plugins/projectexplorer/taskmodel.cpp +++ b/src/plugins/projectexplorer/taskmodel.cpp @@ -337,7 +337,10 @@ TaskFilterModel::TaskFilterModel(TaskModel *sourceModel, QObject *parent) : QAbs connect(m_sourceModel, &QAbstractItemModel::rowsRemoved, this, [this](const QModelIndex &parent, int, int) { QTC_ASSERT(!parent.isValid(), return); - endRemoveRows(); + if (m_beginRemoveRowsSent) { + m_beginRemoveRowsSent = false; + endRemoveRows(); + } }); connect(m_sourceModel, &QAbstractItemModel::modelReset, @@ -430,6 +433,7 @@ void TaskFilterModel::handleNewRows(const QModelIndex &index, int first, int las void TaskFilterModel::handleRowsAboutToBeRemoved(const QModelIndex &index, int first, int last) { + m_beginRemoveRowsSent = false; QTC_ASSERT(!index.isValid(), return); const QPair range = findFilteredRange(first, last, m_mapping); @@ -437,6 +441,7 @@ void TaskFilterModel::handleRowsAboutToBeRemoved(const QModelIndex &index, int f return; beginRemoveRows(QModelIndex(), range.first, range.second); + m_beginRemoveRowsSent = true; m_mapping.erase(m_mapping.begin() + range.first, m_mapping.begin() + range.second + 1); const int sourceRemovedCount = (last - first) + 1; for (int i = range.first; i < m_mapping.count(); ++i) diff --git a/src/plugins/projectexplorer/taskmodel.h b/src/plugins/projectexplorer/taskmodel.h index b2b1c933e2b..4b2757c2891 100644 --- a/src/plugins/projectexplorer/taskmodel.h +++ b/src/plugins/projectexplorer/taskmodel.h @@ -165,6 +165,7 @@ private: void updateMapping() const; bool filterAcceptsTask(const Task &task) const; + bool m_beginRemoveRowsSent = false; bool m_includeUnknowns; bool m_includeWarnings; bool m_includeErrors; diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index c5710957da1..1aadaa081ae 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -198,15 +198,15 @@ bool QmlDesignerPlugin::delayedInitialize() d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::TextTool); d->viewManager.registerFormEditorToolTakingOwnership(new QmlDesigner::PathTool); - connect(Core::DesignMode::instance(), &Core::DesignMode::actionsUpdated, - &d->shortCutManager, &ShortCutManager::updateActions); - return true; } void QmlDesignerPlugin::extensionsInitialized() { - integrateIntoQtCreator(&d->mainWidget); + // delay after Core plugin's extensionsInitialized, so the DesignMode is availabe + connect(Core::ICore::instance(), &Core::ICore::coreAboutToOpen, this, [this] { + integrateIntoQtCreator(&d->mainWidget); + }); } static QStringList allUiQmlFilesforCurrentProject(const Utils::FileName &fileName) @@ -255,6 +255,9 @@ void QmlDesignerPlugin::integrateIntoQtCreator(QWidget *modeWidget) Core::DesignMode::registerDesignWidget(modeWidget, mimeTypes, d->context->context()); + connect(Core::DesignMode::instance(), &Core::DesignMode::actionsUpdated, + &d->shortCutManager, &ShortCutManager::updateActions); + connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged, [this] (Core::IEditor *editor) { if (d && checkIfEditorIsQtQuick(editor) && isInDesignerMode()) changeEditor(); diff --git a/src/plugins/welcome/welcomeplugin.cpp b/src/plugins/welcome/welcomeplugin.cpp index b3c70ed984d..aa804bbe6d8 100644 --- a/src/plugins/welcome/welcomeplugin.cpp +++ b/src/plugins/welcome/welcomeplugin.cpp @@ -357,8 +357,12 @@ void WelcomeMode::initPlugins() addPage(page); if (!m_activePage.isValid() && !m_pageButtons.isEmpty()) { - m_activePage = m_pluginList.at(0)->id(); - m_pageButtons.at(0)->click(); + const int welcomeIndex = Utils::indexOf(m_pluginList, + Utils::equal(&IWelcomePage::id, + Core::Id("Examples"))); + const int defaultIndex = welcomeIndex >= 0 ? welcomeIndex : 0; + m_activePage = m_pluginList.at(defaultIndex)->id(); + m_pageButtons.at(defaultIndex)->click(); } } diff --git a/src/shared/qbs b/src/shared/qbs index 872e4b883d7..73d0d3a2471 160000 --- a/src/shared/qbs +++ b/src/shared/qbs @@ -1 +1 @@ -Subproject commit 872e4b883d7732c46e1e5d32b60ce698862e5da6 +Subproject commit 73d0d3a247162b91d6b2c78f5a490e006168a2e4 diff --git a/src/tools/clangbackend/source/tokeninfo.cpp b/src/tools/clangbackend/source/tokeninfo.cpp index a5a2220adad..68877e4032a 100644 --- a/src/tools/clangbackend/source/tokeninfo.cpp +++ b/src/tools/clangbackend/source/tokeninfo.cpp @@ -341,9 +341,13 @@ void TokenInfo::typeKind(const Cursor &cursor) case CXCursor_ObjCCategoryImplDecl: m_types.mixinHighlightingTypes.push_back(HighlightingType::ObjectiveCCategory); return; - case CXCursor_ObjCSuperClassRef: case CXCursor_TemplateTypeParameter: + m_types.mixinHighlightingTypes.push_back(HighlightingType::TemplateTypeParameter); + return; case CXCursor_TemplateTemplateParameter: + m_types.mixinHighlightingTypes.push_back(HighlightingType::TemplateTemplateParameter); + return; + case CXCursor_ObjCSuperClassRef: case CXCursor_CXXStaticCastExpr: case CXCursor_CXXReinterpretCastExpr: break; diff --git a/tests/system/suite_APTW/tst_APTW03/test.py b/tests/system/suite_APTW/tst_APTW03/test.py index 2ceef47b708..905dea914e4 100644 --- a/tests/system/suite_APTW/tst_APTW03/test.py +++ b/tests/system/suite_APTW/tst_APTW03/test.py @@ -100,7 +100,7 @@ def main(): editor = getEditorForFileSuffix("%s.h" % className.lower()) oldContent = str(editor.plainText) placeCursorToLine(editor, "class %s.*" % className, True) - snooze(1) # avoid timing issue with the parser + snooze(4) # avoid timing issue with the parser invokeContextMenuItem(editor, "Refactor", "Insert Virtual Functions of Base Classes") handleInsertVirtualFunctions(["keys() const = 0 : QStringList", "create(const QString &, const QString &) = 0 : QObject *"]) diff --git a/tests/system/suite_CSUP/tst_CSUP01/test.py b/tests/system/suite_CSUP/tst_CSUP01/test.py index 3512630ea45..51c9208797b 100644 --- a/tests/system/suite_CSUP/tst_CSUP01/test.py +++ b/tests/system/suite_CSUP/tst_CSUP01/test.py @@ -77,12 +77,14 @@ def main(): "possible to select one of the suggestions.") # Step 4: Insert text "voi" to new line and press Tab. resetLine(editorWidget) - type(editorWidget, "voi") + type(editorWidget, "unsi") try: - waitForObjectItem(":popupFrame_Proposal_QListView", "void") - type(waitForObject(":popupFrame_Proposal_QListView"), "") - test.compare(str(lineUnderCursor(editorWidget)).strip(), "void", - "Step 4: Verifying if: Word 'void' is completed because only one option is available.") + proposalListView = waitForObject(":popupFrame_Proposal_QListView") + waitForObjectItem(proposalListView, "unsigned") + test.compare(proposalListView.model().rowCount(), 1, 'Only one proposal for "unsi"?') + type(proposalListView, "") + test.compare(str(lineUnderCursor(editorWidget)).strip(), "unsigned", + "Step 4: Verifying if: Word 'unsigned' is completed because only one option is available.") except: test.fail("The expected completion popup was not shown.") # Step 4.5: Insert text "2." to new line and verify that code completion is not triggered (QTCREATORBUG-16188)