diff options
author | Eike Ziller <eike.ziller@qt.io> | 2020-02-05 10:19:52 +0100 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2020-02-05 11:59:35 +0100 |
commit | 5c121d57911d91f19b066803ad38ca4815255dde (patch) | |
tree | 728e9206d48968ccbc72dafcd284da4c47b2a9e7 | |
parent | aeb7ef6b37030ed4beb8f431167d2ef88172486b (diff) | |
parent | b2ddeacfb5c54d3b0e15c8e6087d21aefaed4d7a (diff) | |
download | qt-creator-5c121d57911d91f19b066803ad38ca4815255dde.tar.gz |
Merge remote-tracking branch 'origin/4.11'
Conflicts:
src/plugins/genericprojectmanager/genericproject.cpp
Change-Id: Ib54f1645ec70a9e6460a888a13190ede130bccca
24 files changed, 363 insertions, 270 deletions
diff --git a/dist/changes-4.11.1.md b/dist/changes-4.11.1.md index 8f2635897b..65fc03b0a9 100644 --- a/dist/changes-4.11.1.md +++ b/dist/changes-4.11.1.md @@ -16,6 +16,10 @@ Editing * Fixed `Visualize Whitespace` for editors without specialized highlighter definition (QTCREATORBUG-23040) +### Language Client + +* Fixed failure when restarting server (QTCREATORBUG-23497) + ### C++ * Fixed wrong warnings about C++98 incompatibility with MSVC (QTCREATORBUG-23118) @@ -37,6 +41,14 @@ Projects * Fixed subdirectory structure in project tree (QTCREATORBUG-23372) +### Qbs + +* Fixed building Android projects (QTCREATORBUG-23489) + +### Generic + +* Fixed crash when updating deployment data (QTCREATORBUG-23501) + Debugging --------- @@ -61,6 +73,10 @@ Platforms * Worked around issue with HiDPI in Qt (QTBUG-80934) +### Remote Linux + +* Fixed that terminal setting was ignored (QTCREATORBUG-23470) + ### WebAssembly * Fixed missing device in kit (QTCREATORBUG-23360) diff --git a/doc/qtcreator/examples/progressbar/main.cpp b/doc/qtcreator/examples/progressbar/main.cpp index d8275e35c2..b418a6c3df 100644 --- a/doc/qtcreator/examples/progressbar/main.cpp +++ b/doc/qtcreator/examples/progressbar/main.cpp @@ -9,7 +9,7 @@ int main(int argc, char *argv[]) QGuiApplication app(argc, argv); QQuickView view; - view.engine->addImportPath("qrc:/qml/imports"); + view.engine()->addImportPath("qrc:/qml/imports"); view.setSource(QUrl("qrc:/qml/ProgressBar.ui.qml")); if (!view.errors().isEmpty()) return -1; diff --git a/doc/qtcreator/src/analyze/creator-clang-static-analyzer.qdoc b/doc/qtcreator/src/analyze/creator-clang-static-analyzer.qdoc index b378553495..b098943269 100644 --- a/doc/qtcreator/src/analyze/creator-clang-static-analyzer.qdoc +++ b/doc/qtcreator/src/analyze/creator-clang-static-analyzer.qdoc @@ -181,4 +181,28 @@ at each level. To include the checks from the lower levels automatically, select the \uicontrol {Enable lower levels automatically} check box. + \section2 Creating Clang-Tidy Configuration Files + + Clang-Tidy reads the configuration for each source file from a .clang-tidy + file located in the closest parent directory of the source file. If any + configuration options have a corresponding command-line option, the + command-line option takes precedence. The effective configuration can be + inspected using \c {-dump-config}. + + \QC creates the configuration for you based on the checks you select. To + store the checks in file format, you can create a .clang-tidy file, as + follows: + + \list 1 + \li Select \uicontrol {Edit Checks as String} and copy the contents of + the field. + \li Pipe the output of \c {clang-tidy -dump-config} into a file named + \c {.clang-tidy}. For example: + \c {clang-tidy -checks=-*,bugprone-*,cppcoreguidelines-avoid-* -dump-config > .clang-tidy} + \li Move the .clang-tidy file to the parent directory of the sources. + \endlist + + To add more checks using \QC later on, copy the checks from your .clang-tidy + file into the \uicontrol {Edit Checks as String} field, select additional + checks, and copy-paste the contents of the field to the .clang-tidy file. */ diff --git a/doc/qtcreator/src/qtquick/qtquick-from-qmlproject-to-pro.qdoc b/doc/qtcreator/src/qtquick/qtquick-from-qmlproject-to-pro.qdoc index ff8d929f9e..73df38d295 100644 --- a/doc/qtcreator/src/qtquick/qtquick-from-qmlproject-to-pro.qdoc +++ b/doc/qtcreator/src/qtquick/qtquick-from-qmlproject-to-pro.qdoc @@ -100,7 +100,7 @@ \skipto QQuickView view; \printuntil view.show() Where \c {qrc:/qml/imports} is the import path and - \c {qrc:qml/ProgressBar.ui.qml} is the path to and the + \c {qrc:/qml/ProgressBar.ui.qml} is the path to and the name of the main QML file in the Qt Quick UI project. \li Select \uicontrol Build > \uicontrol Run to build and run your project. diff --git a/src/libs/languageserverprotocol/servercapabilities.cpp b/src/libs/languageserverprotocol/servercapabilities.cpp index a8e932ad50..a000ad2c89 100644 --- a/src/libs/languageserverprotocol/servercapabilities.cpp +++ b/src/libs/languageserverprotocol/servercapabilities.cpp @@ -162,7 +162,7 @@ bool ServerCapabilities::isValid(QStringList *error) const && checkOptional<bool>(error, documentHighlightProviderKey) && checkOptional<bool>(error, documentSymbolProviderKey) && checkOptional<bool>(error, workspaceSymbolProviderKey) - && checkOptional<bool>(error, codeActionProviderKey) + && checkOptional<bool, CodeActionOptions>(error, codeActionProviderKey) && checkOptional<CodeLensOptions>(error, codeLensProviderKey) && checkOptional<bool>(error, documentFormattingProviderKey) && checkOptional<bool>(error, documentRangeFormattingProviderKey) diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index 0b8281fcb4..027de1edc9 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -226,11 +226,10 @@ bool AndroidBuildApkStep::init() QString outputDir = bc->buildDirectory().pathAppended(Constants::ANDROID_BUILDDIRECTORY).toString(); - QString inputFile; if (node) - inputFile = node->data(Constants::AndroidDeploySettingsFile).toString(); + m_inputFile = node->data(Constants::AndroidDeploySettingsFile).toString(); - if (inputFile.isEmpty()) { + if (m_inputFile.isEmpty()) { m_skipBuilding = true; return true; } @@ -242,7 +241,7 @@ bool AndroidBuildApkStep::init() return false; } - QStringList arguments = {"--input", inputFile, + QStringList arguments = {"--input", m_inputFile, "--output", outputDir, "--android-platform", AndroidManager::buildTargetSDK(target()), "--jdk", AndroidConfigurations::currentConfig().openJDKLocation().toString()}; @@ -358,6 +357,8 @@ bool AndroidBuildApkStep::verifyCertificatePassword() static bool copyFileIfNewer(const QString &sourceFileName, const QString &destinationFileName) { + if (sourceFileName == destinationFileName) + return true; if (QFile::exists(destinationFileName)) { QFileInfo destinationFileInfo(destinationFileName); QFileInfo sourceFileInfo(sourceFileName); @@ -398,48 +399,56 @@ void AndroidBuildApkStep::doRun() if (!node) return false; - FilePath deploymentSettingsFile = FilePath::fromString(node->data(Android::Constants::AndroidDeploySettingsFile).toString()); - if (deploymentSettingsFile.exists()) - return true; // cmake creates this file for us + bool inputExists = QFile::exists(m_inputFile); + if (inputExists && !AndroidManager::isQtCreatorGenerated(FilePath::fromString(m_inputFile))) + return true; // use the generated file if it was not generated by qtcreator auto targets = node->data(Android::Constants::AndroidTargets).toStringList(); if (targets.isEmpty()) - return true; // qmake does this job for us + return inputExists; // qmake does this job for us - QJsonObject deploySettings = Android::AndroidManager::deploymentSettings(target()); - QJsonObject architectures; - // Copy targets to android build folder - QString applicationBinary = target()->activeRunConfiguration()->buildTargetInfo().targetFilePath.toFileInfo().fileName(); - for (const auto &abi : androidAbis) { - QString targetSuffix = QString{"_%1.so"}.arg(abi); - if (applicationBinary.endsWith(targetSuffix)) { - // Keep only TargetName from "lib[TargetName]_abi.so" - applicationBinary.remove(0, 3).chop(targetSuffix.size()); - } + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(target()->kit()); + if (!version) + return false; - Utils::FilePath androidLibsDir = bc->buildDirectory() - .pathAppended("android-build/libs") - .pathAppended(abi); + QJsonObject deploySettings = Android::AndroidManager::deploymentSettings(target()); + QString applicationBinary; + if (version->qtVersion() < QtSupport::QtVersionNumber(5, 14, 0)) { + QTC_ASSERT(androidAbis.size() == 1, return false); + applicationBinary = target()->activeRunConfiguration()->buildTargetInfo().targetFilePath.toString(); + Utils::FilePath androidLibsDir = bc->buildDirectory().pathAppended("android-build/libs").pathAppended(androidAbis.first()); for (const auto &target : targets) { - if (target.endsWith(targetSuffix)) { - if (!copyFileIfNewer(target, androidLibsDir.pathAppended(QFileInfo{target}.fileName()).toString())) - return false; - if (abi == "x86") { - architectures[abi] = "i686-linux-android"; - } else if (abi == "x86_64") { - architectures[abi] = "x86_64-linux-android"; - } else if (abi == "arm64-v8a") { - architectures[abi] = "aarch64-linux-android"; - } else { - architectures[abi] = "arm-linux-androideabi"; + if (!copyFileIfNewer(target, androidLibsDir.pathAppended(QFileInfo{target}.fileName()).toString())) + return false; + } + deploySettings["target-architecture"] = androidAbis.first(); + } else { + applicationBinary = target()->activeRunConfiguration()->buildTargetInfo().targetFilePath.toFileInfo().fileName(); + QJsonObject architectures; + + // Copy targets to android build folder + for (const auto &abi : androidAbis) { + QString targetSuffix = QString{"_%1.so"}.arg(abi); + if (applicationBinary.endsWith(targetSuffix)) { + // Keep only TargetName from "lib[TargetName]_abi.so" + applicationBinary.remove(0, 3).chop(targetSuffix.size()); + } + + Utils::FilePath androidLibsDir = bc->buildDirectory() + .pathAppended("android-build/libs") + .pathAppended(abi); + for (const auto &target : targets) { + if (target.endsWith(targetSuffix)) { + if (!copyFileIfNewer(target, androidLibsDir.pathAppended(QFileInfo{target}.fileName()).toString())) + return false; + architectures[abi] = AndroidManager::archTriplet(abi); } } } + deploySettings["architectures"] = architectures; } - deploySettings["application-binary"] = applicationBinary; - deploySettings["architectures"] = architectures; QString extraLibs = node->data(Android::Constants::AndroidExtraLibs).toString(); if (!extraLibs.isEmpty()) @@ -458,7 +467,7 @@ void AndroidBuildApkStep::doRun() qmlRootPath = target()->project()->rootProjectDirectory().toString(); deploySettings["qml-root-path"] = qmlRootPath; - QFile f{deploymentSettingsFile.toString()}; + QFile f{m_inputFile}; if (!f.open(QIODevice::WriteOnly)) return false; f.write(QJsonDocument{deploySettings}.toJson()); diff --git a/src/plugins/android/androidbuildapkstep.h b/src/plugins/android/androidbuildapkstep.h index e8a04ac1c7..49ef9dc94e 100644 --- a/src/plugins/android/androidbuildapkstep.h +++ b/src/plugins/android/androidbuildapkstep.h @@ -108,6 +108,7 @@ private: QString m_command; QString m_argumentsPasswordConcealed; bool m_skipBuilding = false; + QString m_inputFile; }; namespace Internal { diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index 4ecf2a0480..20be799b02 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -54,17 +54,18 @@ #include <utils/qtcassert.h> #include <utils/synchronousprocess.h> +#include <QApplication> #include <QDir> +#include <QDomDocument> #include <QFileSystemWatcher> +#include <QJsonDocument> #include <QList> #include <QLoggingCategory> +#include <QMessageBox> #include <QProcess> #include <QRegExp> -#include <QMessageBox> -#include <QApplication> -#include <QDomDocument> -#include <QVersionNumber> #include <QRegularExpression> +#include <QVersionNumber> namespace { const QLatin1String AndroidManifestName("AndroidManifest.xml"); @@ -76,6 +77,7 @@ namespace { const QString activityRegEx("(?<token>launchable-activity: )(.*?)(name=)'(?<target>.*?)'"); const QString apkVersionRegEx("(?<token>package: )(.*?)(versionCode=)'(?<target>.*?)'"); const QString versionCodeRegEx("(?<token>versionCode=)(?<version>\\d*)"); + const QString qtcSignature("This file is generated by QtCreator to be read by androiddeployqt and should not be modified by hand."); static Q_LOGGING_CATEGORY(androidManagerLog, "qtc.android.androidManager", QtWarningMsg) @@ -266,6 +268,18 @@ QStringList AndroidManager::applicationAbis(const Target *target) return qt->androidAbis(); } +QString AndroidManager::archTriplet(const QString &abi) +{ + if (abi == "x86") { + return {"i686-linux-android"}; + } else if (abi == "x86_64") { + return {"x86_64-linux-android"}; + } else if (abi == "arm64-v8a") { + return {"aarch64-linux-android"}; + } + return {"arm-linux-androideabi"}; +} + QJsonObject AndroidManager::deploymentSettings(const Target *target) { QtSupport::BaseQtVersion *qt = QtSupport::QtKitAspect::qtVersion(target->kit()); @@ -276,11 +290,20 @@ QJsonObject AndroidManager::deploymentSettings(const Target *target) if (!tc || tc->typeId() != Constants::ANDROID_TOOLCHAIN_TYPEID) return {}; QJsonObject settings; - settings["_description"] = "This file is generated by QtCreator to be read by androiddeployqt and should not be modified by hand."; + settings["_description"] = qtcSignature; settings["qt"] = qt->prefix().toString(); settings["ndk"] = AndroidConfigurations::currentConfig().ndkLocation().toString(); settings["sdk"] = AndroidConfigurations::currentConfig().sdkLocation().toString(); - settings["stdcpp-path"] = AndroidConfigurations::currentConfig().toolchainPath().pathAppended("sysroot/usr/lib/").toString(); + if (qt->qtVersion() < QtSupport::QtVersionNumber(5, 14, 0)) { + const QStringList abis = applicationAbis(target); + QTC_ASSERT(abis.size() == 1, return {}); + settings["stdcpp-path"] = AndroidConfigurations::currentConfig().toolchainPath() + .pathAppended("sysroot/usr/lib/") + .pathAppended(archTriplet(abis.first())) + .pathAppended("libc++_shared.so").toString(); + } else { + settings["stdcpp-path"] = AndroidConfigurations::currentConfig().toolchainPath().pathAppended("sysroot/usr/lib/").toString(); + } settings["toolchain-prefix"] = "llvm"; settings["tool-prefix"] = "llvm"; settings["useLLVM"] = true; @@ -288,6 +311,14 @@ QJsonObject AndroidManager::deploymentSettings(const Target *target) return settings; } +bool AndroidManager::isQtCreatorGenerated(const FilePath &deploymentFile) +{ + QFile f{deploymentFile.toString()}; + if (!f.open(QIODevice::ReadOnly)) + return false; + return QJsonDocument::fromJson(f.readAll()).object()["_description"].toString() == qtcSignature; +} + Utils::FilePath AndroidManager::dirPath(const ProjectExplorer::Target *target) { if (auto *bc = target->activeBuildConfiguration()) diff --git a/src/plugins/android/androidmanager.h b/src/plugins/android/androidmanager.h index 718e518e77..e141636c17 100644 --- a/src/plugins/android/androidmanager.h +++ b/src/plugins/android/androidmanager.h @@ -96,6 +96,7 @@ public: static int minimumSDK(const ProjectExplorer::Kit *kit); static QStringList applicationAbis(const ProjectExplorer::Target *target); + static QString archTriplet(const QString &abi); static Utils::FilePath dirPath(const ProjectExplorer::Target *target); static Utils::FilePath manifestPath(ProjectExplorer::Target *target); @@ -126,6 +127,7 @@ public: static SdkToolResult runAaptCommand(const QStringList &args, int timeoutS = 30); static QJsonObject deploymentSettings(const ProjectExplorer::Target *target); + static bool isQtCreatorGenerated(const Utils::FilePath &deploymentFile); private: static SdkToolResult runCommand(const Utils::CommandLine &command, diff --git a/src/plugins/baremetal/keiltoolchain.cpp b/src/plugins/baremetal/keiltoolchain.cpp index eb6afe8e0e..80ae51240e 100644 --- a/src/plugins/baremetal/keiltoolchain.cpp +++ b/src/plugins/baremetal/keiltoolchain.cpp @@ -401,48 +401,89 @@ KeilToolchainFactory::KeilToolchainFactory() setUserCreatable(true); } +// Parse the 'tools.ini' file to fetch a toolchain version. +// Note: We can't use QSettings here! +static QString extractVersion(const QString &toolsFile, const QString §ion) +{ + QFile f(toolsFile); + if (!f.open(QIODevice::ReadOnly)) + return {}; + QTextStream in(&f); + enum State { Enter, Lookup, Exit } state = Enter; + while (!in.atEnd()) { + const QString line = in.readLine().trimmed(); + // Search for section. + const int firstBracket = line.indexOf('['); + const int lastBracket = line.lastIndexOf(']'); + const bool hasSection = (firstBracket == 0 && lastBracket != -1 + && (lastBracket + 1) == line.size()); + switch (state) { + case Enter: + if (hasSection) { + const auto content = line.midRef(firstBracket + 1, + lastBracket - firstBracket - 1); + if (content == section) + state = Lookup; + } + break; + case Lookup: { + if (hasSection) + return {}; // Next section found. + const int versionIndex = line.indexOf("VERSION="); + if (versionIndex < 0) + continue; + QString version = line.mid(8); + if (version.startsWith('V')) + version.remove(0, 1); + return version; + } + break; + default: + return {}; + } + } + return {}; +} + QList<ToolChain *> KeilToolchainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown) { #ifdef Q_OS_WIN64 - static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Keil\\Products"; + static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\" \ + "Windows\\CurrentVersion\\Uninstall\\Keil µVision4"; #else - static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Keil\\Products"; + static const char kRegistryNode[] = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\" \ + "Windows\\CurrentVersion\\Uninstall\\Keil µVision4"; #endif - struct Entry { - QString productKey; - QString subExePath; - }; - - // Dictionary for know toolchains. - static const std::array<Entry, 2> knowToolchains = {{ - {QString("MDK"), QString("\\ARMCC\\bin\\armcc.exe")}, - {QString("C51"), QString("\\BIN\\c51.exe")}, - }}; - Candidates candidates; QSettings registry(kRegistryNode, QSettings::NativeFormat); const auto productGroups = registry.childGroups(); for (const QString &productKey : productGroups) { - const Entry entry = Utils::findOrDefault(knowToolchains, - [productKey](const Entry &entry) { - return entry.productKey == productKey; }); - - if (entry.productKey.isEmpty()) + if (!productKey.startsWith("App")) continue; - registry.beginGroup(productKey); - QString compilerPath = registry.value("Path").toString(); - if (!compilerPath.isEmpty()) { - // Build full compiler path. - compilerPath += entry.subExePath; - const FilePath fn = FilePath::fromString(compilerPath); - if (compilerExists(fn)) { - QString version = registry.value("Version").toString(); - if (version.startsWith('V')) - version.remove(0, 1); - candidates.push_back({fn, version}); + const FilePath productPath(FilePath::fromString(registry.value("ProductDir") + .toString())); + // Fetch the toolchain executable path. + FilePath compilerPath; + if (productPath.endsWith("ARM")) + compilerPath = productPath.pathAppended("\\ARMCC\\bin\\armcc.exe"); + else if (productPath.endsWith("C51")) + compilerPath = productPath.pathAppended("\\BIN\\c51.exe"); + + if (compilerPath.exists()) { + // Fetch the toolchain version. + const QDir rootDir(registry.value("Directory").toString()); + const QString toolsFilePath = rootDir.absoluteFilePath("tools.ini"); + for (auto index = 1; index <= 2; ++index) { + const QString section = registry.value( + QStringLiteral("Section %1").arg(index)).toString(); + const QString version = extractVersion(toolsFilePath, section); + if (!version.isEmpty()) { + candidates.push_back({compilerPath, version}); + break; + } } } registry.endGroup(); diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index c53e4dfe28..69573db219 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -2286,6 +2286,12 @@ void DebuggerEngine::openDisassemblerView(const Location &location) void DebuggerEngine::raiseWatchersWindow() { if (d->m_watchersView && d->m_watchersWindow) { + auto currentPerspective = DebuggerMainWindow::currentPerspective(); + QTC_ASSERT(currentPerspective, return); + // if a companion engine has taken over - do not raise the watchers + if (currentPerspective->name() != d->m_engine->displayName()) + return; + if (auto dock = qobject_cast<QDockWidget *>(d->m_watchersWindow->parentWidget())) { if (QAction *act = dock->toggleViewAction()) { if (!act->isChecked()) diff --git a/src/plugins/debugger/peripheralregisterhandler.cpp b/src/plugins/debugger/peripheralregisterhandler.cpp index 0e0f035a97..fa9427a6e2 100644 --- a/src/plugins/debugger/peripheralregisterhandler.cpp +++ b/src/plugins/debugger/peripheralregisterhandler.cpp @@ -52,6 +52,8 @@ constexpr char kBitRange[] = "bitRange"; constexpr char kBitWidth[] = "bitWidth"; constexpr char kDerivedFrom[] = "derivedFrom"; constexpr char kDescription[] = "description"; +constexpr char kDevice[] = "device"; +constexpr char kDisplayName[] = "displayName"; constexpr char kField[] = "field"; constexpr char kFields[] = "fields"; constexpr char kGroupName[] = "groupName"; @@ -559,135 +561,147 @@ PeripheralRegisterHandler::PeripheralRegisterHandler(DebuggerEngine *engine) setHeader({tr("Name"), tr("Value"), tr("Access")}); } -static PeripheralRegisterGroups availablePeripheralRegisterGroups( - const QString &filePath) -{ - QFile f(filePath); - if (!f.open(QIODevice::ReadOnly)) - return {}; +static void handleField(QXmlStreamReader &in, PeripheralRegister ®) +{ + PeripheralRegisterField fld; + while (in.readNextStartElement()) { + const auto elementName = in.name(); + if (elementName == kName) { + fld.name = in.readElementText(); + } else if (elementName == kDescription) { + fld.description = in.readElementText(); + } else if (elementName == kAccess) { + fld.access = decodeAccess(in.readElementText()); + } else if (elementName == kBitRange) { + const QString elementText = in.readElementText(); + const int startBracket = elementText.indexOf('['); + const int endBracket = elementText.indexOf(']'); + if (startBracket == -1 || endBracket == -1 || (endBracket - startBracket) <= 0) + continue; + const QString range = elementText.mid(startBracket + 1, endBracket - 1); + const QStringList items = range.split(':'); + enum { MaxBit, MinBit, BitsCount }; + if (items.count() != BitsCount) + continue; + const int from = int(decodeNumeric(items.at(MinBit))); + const int to = int(decodeNumeric(items.at(MaxBit))); + fld.bitOffset = from; + fld.bitWidth = to - from + 1; + } else if (elementName == kBitOffset) { + fld.bitOffset = int(decodeNumeric(in.readElementText())); + } else if (elementName == kBitWidth) { + fld.bitWidth = int(decodeNumeric(in.readElementText())); + } else { + in.skipCurrentElement(); + } + } - QXmlStreamReader in(&f); + // Inherit the field access from the register access if the filed + // has not the access rights description. + if (fld.access == PeripheralRegisterAccess::Unknown) + fld.access = reg.access; + + reg.fields.push_back(fld); +} + +static void handleRegister(QXmlStreamReader &in, PeripheralRegisterGroup &group) +{ + PeripheralRegister reg; + while (in.readNextStartElement()) { + const auto elementName = in.name(); + if (elementName == kName) { + reg.name = in.readElementText(); + } else if (elementName == kDisplayName) { + reg.displayName = in.readElementText(); + } else if (elementName == kDescription) { + reg.description = in.readElementText(); + } else if (elementName == kAddressOffset) { + reg.addressOffset = decodeNumeric(in.readElementText()); + } else if (elementName == kSize) { + reg.size = int(decodeNumeric(in.readElementText())); + } else if (elementName == kAccess) { + reg.access = decodeAccess(in.readElementText()); + } else if (elementName == kResetvalue) { + reg.resetValue = decodeNumeric(in.readElementText()); + } else if (elementName == kFields) { + while (in.readNextStartElement()) { + const auto elementName = in.name(); + if (elementName == kField) + handleField(in, reg); + else + in.skipCurrentElement(); + } + } else { + in.skipCurrentElement(); + } + } + group.registers.push_back(reg); +} + +static void handleGroup(QXmlStreamReader &in, PeripheralRegisterGroups &groups) +{ + PeripheralRegisterGroup group; - PeripheralRegisterGroups foundGroups; + const auto fromGroupName = in.attributes().value(kDerivedFrom); + if (!fromGroupName.isEmpty()) { + const auto groupEnd = groups.cend(); + const auto groupIt = std::find_if(groups.cbegin(), groupEnd, + [fromGroupName](const PeripheralRegisterGroup &group) { + return fromGroupName == group.name; + }); + if (groupIt != groupEnd) + group = *groupIt; + } - while (!in.atEnd()) { - const auto token = in.readNext(); - if (token == QXmlStreamReader::EndElement - && in.name() == QLatin1String(kPeripherals)) { - break; - } else if (token != QXmlStreamReader::StartElement - || in.name() != QLatin1String(kPeripheral)) { - continue; + while (in.readNextStartElement()) { + const auto elementName = in.name(); + if (elementName == kName) { + group.name = in.readElementText(); + } else if (elementName == kDescription) { + group.description = in.readElementText(); + } else if (elementName == kGroupName) { + group.displayName = in.readElementText(); + } else if (elementName == kBaseAddress) { + group.baseAddress = decodeNumeric(in.readElementText()); + } else if (elementName == kSize) { + group.size = int(decodeNumeric(in.readElementText())); + } else if (elementName == kAccess) { + group.access = decodeAccess(in.readElementText()); + } else if (elementName == kRegisters) { + while (in.readNextStartElement()) { + const auto elementName = in.name(); + if (elementName == kRegister) + handleRegister(in, group); + else + in.skipCurrentElement(); + } + } else { + in.skipCurrentElement(); } + } + groups.push_back(group); +} - PeripheralRegisterGroup group; +static PeripheralRegisterGroups availablePeripheralRegisterGroups(const QString &filePath) +{ + QFile f(filePath); + if (!f.open(QIODevice::ReadOnly)) + return {}; - const auto fromGroupName = in.attributes().value( - QLatin1String(kDerivedFrom)); - const auto foundGroupEnd = foundGroups.cend(); - const auto foundGroupIt = std::find_if( - foundGroups.cbegin(), foundGroupEnd, - [fromGroupName](const PeripheralRegisterGroup &foundGroup) { - return fromGroupName == foundGroup.name; - }); - if (foundGroupIt != foundGroupEnd) - group = *foundGroupIt; - - while (!in.atEnd()) { - const auto token = in.readNext(); - if (token == QXmlStreamReader::EndElement - && in.name() == QLatin1String(kPeripheral)) { - foundGroups.push_back(group); - break; - } else if (token == QXmlStreamReader::StartElement) { + QXmlStreamReader in(&f); + PeripheralRegisterGroups groups; + while (in.readNextStartElement()) { + const auto elementName = in.name(); + if (elementName == kDevice) { + while (in.readNextStartElement()) { const auto elementName = in.name(); - if (elementName == QLatin1String(kName)) { - group.name = in.readElementText(); - } else if (elementName == QLatin1String(kDescription)) { - group.description = in.readElementText(); - } else if (elementName == QLatin1String(kGroupName)) { - group.displayName = in.readElementText(); - } else if (elementName == QLatin1String(kBaseAddress)) { - group.baseAddress = decodeNumeric(in.readElementText()); - } else if (elementName == QLatin1String(kSize)) { - group.size = int(decodeNumeric(in.readElementText())); - } else if (elementName == QLatin1String(kAccess)) { - group.access = decodeAccess(in.readElementText()); - } else if (elementName == QLatin1String(kRegisters) - || elementName == QLatin1String(kRegister)) { - PeripheralRegister reg; - while (!in.atEnd()) { - const auto token = in.readNext(); - if (token == QXmlStreamReader::EndElement - && in.name() == QLatin1String(kRegister)) { - group.registers.push_back(reg); - break; - } else if (token == QXmlStreamReader::StartElement) { - const auto elementName = in.name(); - if (elementName == QLatin1String(kRegister)) { - continue; - } else if (elementName == QLatin1String(kName)) { - reg.name = in.readElementText(); - } else if (elementName == QLatin1String(kDescription)) { - reg.description = in.readElementText(); - } else if (elementName == QLatin1String(kAddressOffset)) { - reg.addressOffset = decodeNumeric(in.readElementText()); - } else if (elementName == QLatin1String(kSize)) { - reg.size = int(decodeNumeric(in.readElementText())); - } else if (elementName == QLatin1String(kAccess)) { - reg.access = decodeAccess(in.readElementText()); - } else if (elementName == QLatin1String(kResetvalue)) { - reg.resetValue = decodeNumeric(in.readElementText()); - } else if (elementName == QLatin1String(kFields) - || elementName == QLatin1String(kField)) { - PeripheralRegisterField fld; - while (!in.atEnd()) { - const auto token = in.readNext(); - if (token == QXmlStreamReader::EndElement - && in.name() == QLatin1String(kField)) { - reg.fields.push_back(fld); - break; - } else if (token == QXmlStreamReader::StartElement) { - const auto elementName = in.name(); - if (elementName == QLatin1String(kField)) { - continue; - } else if (elementName == QLatin1String(kName)) { - fld.name = in.readElementText(); - } else if (elementName == QLatin1String(kDescription)) { - fld.description = in.readElementText(); - } else if (elementName == QLatin1String(kAccess)) { - fld.access = decodeAccess(in.readElementText()); - } else if (elementName == QLatin1String(kBitRange)) { - const QString elementText = in.readElementText(); - const int startBracket = elementText.indexOf('['); - const int endBracket = elementText.indexOf(']'); - if (startBracket == -1 || endBracket == -1 - || (endBracket - startBracket) <= 0) { - continue; - } - const QString range = elementText.mid( - startBracket + 1, endBracket - 1); - const QStringList items = range.split(':'); - enum { MaxBit, MinBit, BitsCount }; - if (items.count() != BitsCount) - continue; - const int from = int(decodeNumeric(items.at(MinBit))); - const int to = int(decodeNumeric(items.at(MaxBit))); - fld.bitOffset = from; - fld.bitWidth = to - from + 1; - } else if (elementName == QLatin1String(kBitOffset)) { - fld.bitOffset = int(decodeNumeric(in.readElementText())); - } else if (elementName == QLatin1String(kBitWidth)) { - fld.bitWidth = int(decodeNumeric(in.readElementText())); - } else { - in.skipCurrentElement(); - } - } - } - } else { - in.skipCurrentElement(); - } - } + if (elementName == kPeripherals) { + while (in.readNextStartElement()) { + const auto elementName = in.name(); + if (elementName == kPeripheral) + handleGroup(in, groups); + else + in.skipCurrentElement(); } } else { in.skipCurrentElement(); @@ -695,8 +709,7 @@ static PeripheralRegisterGroups availablePeripheralRegisterGroups( } } } - - return foundGroups; + return groups; } void PeripheralRegisterHandler::updateRegisterGroups() diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index 92470f4617..5c93e8691a 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -587,10 +587,12 @@ void GenericBuildSystem::updateDeploymentData() hasDeploymentData = QFileInfo::exists(deploymentFilePath.toString()); } if (hasDeploymentData) { - DeploymentData deploymentData; - deploymentData.addFilesFromDeploymentFile(deploymentFilePath.toString(), - projectDirectory().toString()); - setDeploymentData(deploymentData); + if (target) { + DeploymentData deploymentData; + deploymentData.addFilesFromDeploymentFile(deploymentFilePath.toString(), + projectDirectory().toString()); + setDeploymentData(deploymentData); + } if (m_deployFileWatcher.files() != QStringList(deploymentFilePath.toString())) { m_deployFileWatcher.removeFiles(m_deployFileWatcher.files()); m_deployFileWatcher.addFile(deploymentFilePath.toString(), diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index 852142c174..50e743f71a 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -913,7 +913,6 @@ bool Client::reset() m_openedDocument.clear(); m_serverCapabilities = ServerCapabilities(); m_dynamicCapabilities.reset(); - m_project = nullptr; for (const DocumentUri &uri : m_diagnostics.keys()) removeDiagnostics(uri); for (TextEditor::TextDocument *document : m_resetAssistProvider.keys()) diff --git a/src/plugins/projectexplorer/sessionmodel.cpp b/src/plugins/projectexplorer/sessionmodel.cpp index 094a7bbc5f..9e92694116 100644 --- a/src/plugins/projectexplorer/sessionmodel.cpp +++ b/src/plugins/projectexplorer/sessionmodel.cpp @@ -234,6 +234,7 @@ void SessionModel::deleteSessions(const QStringList &sessions) return; beginResetModel(); SessionManager::deleteSessions(sessions); + m_sortedSessions = SessionManager::sessions(); endResetModel(); } diff --git a/src/plugins/remotelinux/makeinstallstep.cpp b/src/plugins/remotelinux/makeinstallstep.cpp index 02e1535773..8aa811a944 100644 --- a/src/plugins/remotelinux/makeinstallstep.cpp +++ b/src/plugins/remotelinux/makeinstallstep.cpp @@ -179,7 +179,8 @@ void MakeInstallStep::finish(bool success) if (success) { m_deploymentData = DeploymentData(); m_deploymentData.setLocalInstallRoot(installRoot()); - QDirIterator dit(installRoot().toString(), QDir::Files, QDirIterator::Subdirectories); + QDirIterator dit(installRoot().toString(), QDir::Files | QDir::Hidden, + QDirIterator::Subdirectories); while (dit.hasNext()) { dit.next(); const QFileInfo fi = dit.fileInfo(); diff --git a/tests/system/shared/editor_utils.py b/tests/system/shared/editor_utils.py index b1ea1bb1bd..8410e986ef 100644 --- a/tests/system/shared/editor_utils.py +++ b/tests/system/shared/editor_utils.py @@ -70,13 +70,6 @@ def placeCursorToLine(editor, line, isRegex=False): def menuVisibleAtEditor(editor, menuInList): menuInList[0] = None try: - # Hack for Squish 5.0.1 handling menus of Qt5.2 on Mac (avoids crash) - remove asap - if platform.system() == 'Darwin': - for obj in object.topLevelObjects(): - if className(obj) == "QMenu" and obj.visible and widgetContainsPoint(editor, obj.mapToGlobal(QPoint(0, 0))): - menuInList[0] = obj - return True - return False menu = waitForObject("{type='QMenu' unnamed='1' visible='1'}", 500) topLeft = menu.mapToGlobal(QPoint(0, 0)) bottomLeft = menu.mapToGlobal(QPoint(0, menu.height)) diff --git a/tests/system/shared/project_explorer.py b/tests/system/shared/project_explorer.py index 60b3af9f20..01a2e81c99 100644 --- a/tests/system/shared/project_explorer.py +++ b/tests/system/shared/project_explorer.py @@ -143,11 +143,7 @@ def invokeContextMenuOnProject(projectName, menuItem): return openItemContextMenu(waitForObject(":Qt Creator_Utils::NavigationTreeView"), str(projItem.text).replace("_", "\\_").replace(".", "\\."), 5, 5, 0) - # Hack for Squish 5.0.1 handling menus of Qt5.2 on Mac (avoids crash) - remove asap - if platform.system() == 'Darwin': - waitFor("macHackActivateContextMenuItem(menuItem)", 6000) - else: - activateItem(waitForObjectItem("{name='Project.Menu.Project' type='QMenu' visible='1'}", menuItem)) + activateItem(waitForObjectItem("{name='Project.Menu.Project' type='QMenu' visible='1'}", menuItem)) return projItem def addAndActivateKit(kit): diff --git a/tests/system/shared/workarounds.py b/tests/system/shared/workarounds.py index 697625945f..ab8e338ad7 100644 --- a/tests/system/shared/workarounds.py +++ b/tests/system/shared/workarounds.py @@ -25,33 +25,6 @@ import urllib2 -############ functions not related to issues tracked inside jira ############ - -def __checkWithoutWidget__(*args): - return className(args[0]) == 'QMenu' and args[0].visible - -def __checkWithWidget__(*args): - return (__checkWithoutWidget__(args[0]) - and widgetContainsPoint(waitForObject(args[1]), args[0].mapToGlobal(QPoint(0 ,0)))) - -# hack for activating context menus on Mac because of Squish5/Qt5.2 problems -# param item a string holding the menu item to invoke (just the label) -# param widget an object; if provided there will be an additional check if the menu's top left -# corner is placed on this widget -def macHackActivateContextMenuItem(item, widget=None): - if widget: - func = __checkWithWidget__ - else: - func = __checkWithoutWidget__ - for obj in object.topLevelObjects(): - try: - if func(obj, widget): - activateItem(waitForObjectItem(obj, item)) - return True - except: - pass - return False - ################ workarounds for issues tracked inside jira ################# JIRA_URL='https://bugreports.qt.io/browse' diff --git a/tests/system/suite_general/tst_rename_file/test.py b/tests/system/suite_general/tst_rename_file/test.py index a5568f85b5..5c296973b0 100644 --- a/tests/system/suite_general/tst_rename_file/test.py +++ b/tests/system/suite_general/tst_rename_file/test.py @@ -96,15 +96,11 @@ def renameFile(projectDir, proFile, branch, oldname, newname): itemWithWildcard = addBranchWildcardToRoot(itemText) waitForObjectItem(treeview, itemWithWildcard, 10000) openItemContextMenu(treeview, itemWithWildcard, 5, 5, 0) - # hack for Squish5/Qt5.2 problems of handling menus on Mac - remove asap - if platform.system() == 'Darwin': - waitFor("macHackActivateContextMenuItem('Rename...')", 5000) + if oldname.lower().endswith(".qrc"): + menu = ":Qt Creator.Project.Menu.Folder_QMenu" else: - if oldname.lower().endswith(".qrc"): - menu = ":Qt Creator.Project.Menu.Folder_QMenu" - else: - menu = ":Qt Creator.Project.Menu.File_QMenu" - activateItem(waitForObjectItem(menu, "Rename...")) + menu = ":Qt Creator.Project.Menu.File_QMenu" + activateItem(waitForObjectItem(menu, "Rename...")) replaceEdit = waitForObject(":Qt Creator_Utils::NavigationTreeView::QExpandingLineEdit") test.compare(replaceEdit.selectedText, oldname.rsplit(".", 1)[0], "Only the filename without the extension is selected?") diff --git a/tests/system/suite_general/tst_tasks_handling/test.py b/tests/system/suite_general/tst_tasks_handling/test.py index d7acc4c940..429e711f5c 100644 --- a/tests/system/suite_general/tst_tasks_handling/test.py +++ b/tests/system/suite_general/tst_tasks_handling/test.py @@ -75,12 +75,9 @@ def generateMockTasksFile(): def checkOrUncheckMyTasks(): filterButton = waitForObject(toolButton % 'Filter by categories') clickButton(filterButton) - if platform.system() == 'Darwin': - waitFor("macHackActivateContextMenuItem('My Tasks')", 5000) - else: - activateItem(waitForObjectItem("{type='QMenu' unnamed='1' visible='1' " - "window=':Qt Creator_Core::Internal::MainWindow'}", - "My Tasks")) + activateItem(waitForObjectItem("{type='QMenu' unnamed='1' visible='1' " + "window=':Qt Creator_Core::Internal::MainWindow'}", + "My Tasks")) def getBuildIssuesTypeCounts(model): issueTypes = map(lambda x: x.data(Qt.UserRole + 5).toInt(), dumpIndices(model)) diff --git a/tests/system/suite_tools/tst_designer_autocomplete/test.py b/tests/system/suite_tools/tst_designer_autocomplete/test.py index 0b97efec6a..6e49d7ba48 100644 --- a/tests/system/suite_tools/tst_designer_autocomplete/test.py +++ b/tests/system/suite_tools/tst_designer_autocomplete/test.py @@ -38,11 +38,7 @@ def main(): if buttonName: openContextMenu(waitForObject("{container=':*Qt Creator.FormEditorStack_Designer::Internal::FormEditorStack'" "text='PushButton' type='QPushButton' visible='1'}"), 5, 5, 1) - # hack for Squish5/Qt5.2 problems of handling menus on Mac - remove asap - if platform.system() == 'Darwin': - waitFor("macHackActivateContextMenuItem('Change objectName...')", 6000) - else: - activateItem(waitForObjectItem("{type='QMenu' unnamed='1' visible='1'}", "Change objectName...")) + activateItem(waitForObjectItem("{type='QMenu' unnamed='1' visible='1'}", "Change objectName...")) typeLines(waitForObject(":FormEditorStack_qdesigner_internal::PropertyLineEdit"), buttonName) else: # Verify that everything works without ever changing the name diff --git a/tests/system/suite_tools/tst_designer_goto_slot/test.py b/tests/system/suite_tools/tst_designer_goto_slot/test.py index 11a1b4d671..5e6352454a 100644 --- a/tests/system/suite_tools/tst_designer_goto_slot/test.py +++ b/tests/system/suite_tools/tst_designer_goto_slot/test.py @@ -45,11 +45,7 @@ def main(): selectFromLocator("mainwindow.ui") openContextMenu(waitForObject(con[0]), 5, 5, 0) snooze(1) - # hack for Squish 5/Qt5.2 problems of handling menus on Mac - remove asap - if platform.system() == 'Darwin': - waitFor("macHackActivateContextMenuItem('Go to slot...', con[0])", 6000) - else: - activateItem(waitForObjectItem("{type='QMenu' unnamed='1' visible='1'}", "Go to slot...")) + activateItem(waitForObjectItem("{type='QMenu' unnamed='1' visible='1'}", "Go to slot...")) signalWidgetObject = waitForObject(":Select signal.signalList_QTreeView") signalName = con[1] + "." + con[2] mouseClick(waitForObjectItem(signalWidgetObject, signalName), 5, 5, 0, Qt.LeftButton) diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index 8f7ca8032a..1db48813e8 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -138,7 +138,6 @@ SOURCES += \ clangdocumentprocessors-test.cpp \ clangdocumentprocessor-test.cpp \ clangdocuments-test.cpp \ - clangdocumentsuspenderresumer-test.cpp \ clangdocument-test.cpp \ clangfixitoperation-test.cpp \ clangfollowsymbol-test.cpp \ @@ -146,7 +145,6 @@ SOURCES += \ clangjobqueue-test.cpp \ clangjobs-test.cpp \ clangparsesupportivetranslationunitjob-test.cpp \ - clangreferencescollector-test.cpp \ clangrequestannotationsjob-test.cpp \ clangrequestreferencesjob-test.cpp \ clangresumedocumentjob-test.cpp \ @@ -177,7 +175,6 @@ SOURCES += \ sqlitetable-test.cpp \ sqlstatementbuilder-test.cpp \ token-test.cpp \ - tokenprocessor-test.cpp \ translationunitupdater-test.cpp \ unsavedfiles-test.cpp \ unsavedfile-test.cpp \ @@ -187,9 +184,11 @@ SOURCES += \ !isEmpty(LIBTOOLING_LIBS) { SOURCES += \ gtest-llvm-printing.cpp \ + clangdocumentsuspenderresumer-test.cpp \ clangquerygatherer-test.cpp \ clangqueryprojectfindfilter-test.cpp \ clangquery-test.cpp \ + clangreferencescollector-test.cpp \ gtest-clang-printing.cpp \ pchcreator-test.cpp \ refactoringclientserverinprocess-test.cpp \ @@ -202,7 +201,8 @@ SOURCES += \ symbolscollector-test.cpp \ testclangtool.cpp \ usedmacrocollector-test.cpp \ - builddependencycollector-test.cpp + builddependencycollector-test.cpp \ + tokenprocessor-test.cpp } !isEmpty(CLANGFORMAT_LIBS) { |