From 67df868f5c8ffad5f0558e7d6b49f7c7725e9552 Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Sun, 16 Feb 2020 20:46:23 +0200 Subject: [PATCH 01/13] Android: Automatically use the correct NDK for each Qt version Based on change 286266, we can find a correct NDK version for Qt for Andriod version. This change allows Android plugin to get relevant NDK information and registers appropriate toolchains and kits settings. [ChangeLog][Android] Automatically use correct NDK version corresponding to used Qt version. Task-number: QTCREATORBUG-23583 Change-Id: Ic6b0d7a1ae8962c075b77498de88e018a008ac3e Reviewed-by: Alessandro Portale --- src/plugins/android/androidbuildapkstep.cpp | 10 +- src/plugins/android/androidconfigurations.cpp | 193 +++++++++--------- src/plugins/android/androidconfigurations.h | 30 ++- src/plugins/android/androiddebugsupport.cpp | 7 +- src/plugins/android/androidmanager.cpp | 11 +- .../android/androidmanifesteditorwidget.cpp | 8 +- src/plugins/android/androidplugin.cpp | 1 + src/plugins/android/androidqtversion.cpp | 11 +- src/plugins/android/androidrunnerworker.cpp | 5 +- src/plugins/android/androidsettingswidget.cpp | 8 +- src/plugins/android/androidtoolchain.cpp | 149 +++++++++----- src/plugins/android/androidtoolchain.h | 7 + 12 files changed, 254 insertions(+), 186 deletions(-) diff --git a/src/plugins/android/androidbuildapkstep.cpp b/src/plugins/android/androidbuildapkstep.cpp index 194c3c52296..fa7918526ed 100644 --- a/src/plugins/android/androidbuildapkstep.cpp +++ b/src/plugins/android/androidbuildapkstep.cpp @@ -532,10 +532,14 @@ void AndroidBuildApkStep::setBuildTargetSdk(const QString &sdk) QVariant AndroidBuildApkStep::data(Core::Id id) const { - if (id == Constants::AndroidNdkPlatform) - return AndroidConfigurations::currentConfig().bestNdkPlatformMatch(AndroidManager::minimumSDK(target())).mid(8); + QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(target()->kit()); + + if (id == Constants::AndroidNdkPlatform) { + return AndroidConfigurations::currentConfig() + .bestNdkPlatformMatch(AndroidManager::minimumSDK(target()), qtVersion).mid(8); + } if (id == Constants::NdkLocation) - return QVariant::fromValue(AndroidConfigurations::currentConfig().ndkLocation()); + return QVariant::fromValue(AndroidConfigurations::currentConfig().ndkLocation(qtVersion)); if (id == Constants::SdkLocation) return QVariant::fromValue(AndroidConfigurations::currentConfig().sdkLocation()); if (id == Constants::AndroidABIs) diff --git a/src/plugins/android/androidconfigurations.cpp b/src/plugins/android/androidconfigurations.cpp index d8e9b92f5f8..0e794dd6d7e 100644 --- a/src/plugins/android/androidconfigurations.cpp +++ b/src/plugins/android/androidconfigurations.cpp @@ -102,7 +102,6 @@ namespace { const QLatin1String SDKLocationKey("SDKLocation"); const QLatin1String SdkFullyConfiguredKey("AllEssentialsInstalled"); const QLatin1String SDKManagerToolArgsKey("SDKManagerToolArgs"); - const QLatin1String NDKLocationKey("NDKLocation"); const QLatin1String OpenJDKLocationKey("OpenJDKLocation"); const QLatin1String KeystoreLocationKey("KeystoreLocation"); const QLatin1String AutomaticKitCreationKey("AutomatiKitCreation"); @@ -237,10 +236,8 @@ void AndroidConfig::load(const QSettings &settings) m_partitionSize = settings.value(PartitionSizeKey, 1024).toInt(); m_sdkLocation = FilePath::fromString(settings.value(SDKLocationKey).toString()); m_sdkManagerToolArgs = settings.value(SDKManagerToolArgsKey).toStringList(); - m_ndkLocation = FilePath::fromString(settings.value(NDKLocationKey).toString()); m_openJDKLocation = FilePath::fromString(settings.value(OpenJDKLocationKey).toString()); m_keystoreLocation = FilePath::fromString(settings.value(KeystoreLocationKey).toString()); - m_toolchainHost = settings.value(ToolchainHostKey).toString(); m_automaticKitCreation = settings.value(AutomaticKitCreationKey, true).toBool(); m_sdkFullyConfigured = settings.value(SdkFullyConfiguredKey, false).toBool(); @@ -250,16 +247,12 @@ void AndroidConfig::load(const QSettings &settings) // persisten settings m_sdkLocation = FilePath::fromString(reader.restoreValue(SDKLocationKey, m_sdkLocation.toString()).toString()); m_sdkManagerToolArgs = reader.restoreValue(SDKManagerToolArgsKey, m_sdkManagerToolArgs).toStringList(); - m_ndkLocation = FilePath::fromString(reader.restoreValue(NDKLocationKey, m_ndkLocation.toString()).toString()); m_openJDKLocation = FilePath::fromString(reader.restoreValue(OpenJDKLocationKey, m_openJDKLocation.toString()).toString()); - m_keystoreLocation = FilePath::fromString(reader.restoreValue(KeystoreLocationKey, m_keystoreLocation.toString()).toString()); - m_toolchainHost = reader.restoreValue(ToolchainHostKey, m_toolchainHost).toString(); m_automaticKitCreation = reader.restoreValue(AutomaticKitCreationKey, m_automaticKitCreation).toBool(); m_sdkFullyConfigured = reader.restoreValue(SdkFullyConfiguredKey, m_sdkFullyConfigured).toBool(); // persistent settings } parseDependenciesJson(); - m_NdkInformationUpToDate = false; } void AndroidConfig::save(QSettings &settings) const @@ -271,51 +264,13 @@ void AndroidConfig::save(QSettings &settings) const // user settings settings.setValue(SDKLocationKey, m_sdkLocation.toString()); settings.setValue(SDKManagerToolArgsKey, m_sdkManagerToolArgs); - settings.setValue(NDKLocationKey, m_ndkLocation.toString()); settings.setValue(OpenJDKLocationKey, m_openJDKLocation.toString()); settings.setValue(KeystoreLocationKey, m_keystoreLocation.toString()); settings.setValue(PartitionSizeKey, m_partitionSize); settings.setValue(AutomaticKitCreationKey, m_automaticKitCreation); - settings.setValue(ToolchainHostKey, m_toolchainHost); settings.setValue(SdkFullyConfiguredKey, m_sdkFullyConfigured); } -void AndroidConfig::updateNdkInformation() const -{ - if (m_NdkInformationUpToDate) - return; - m_availableNdkPlatforms.clear(); - QDirIterator it(m_ndkLocation.pathAppended("platforms").toString(), QStringList("android-*"), QDir::Dirs); - while (it.hasNext()) { - const QString &fileName = it.next(); - m_availableNdkPlatforms.push_back(fileName.midRef(fileName.lastIndexOf(QLatin1Char('-')) + 1).toInt()); - } - Utils::sort(m_availableNdkPlatforms, std::greater<>()); - - // detect toolchain host - QStringList hostPatterns; - switch (HostOsInfo::hostOs()) { - case OsTypeLinux: - hostPatterns << QLatin1String("linux*"); - break; - case OsTypeWindows: - hostPatterns << QLatin1String("windows*"); - break; - case OsTypeMac: - hostPatterns << QLatin1String("darwin*"); - break; - default: /* unknown host */ return; - } - - QDirIterator jt(m_ndkLocation.pathAppended("prebuilt").toString(), hostPatterns, QDir::Dirs); - if (jt.hasNext()) { - jt.next(); - m_toolchainHost = jt.fileName(); - } - - m_NdkInformationUpToDate = true; -} - void AndroidConfig::parseDependenciesJson() { QString sdkConfigFile(Core::ICore::resourcePath() + JsonFilePath); @@ -382,6 +337,22 @@ void AndroidConfig::parseDependenciesJson() } } +QVector AndroidConfig::availableNdkPlatforms(const BaseQtVersion *qtVersion) const +{ + QVector availableNdkPlatforms; + QDirIterator it(ndkLocation(qtVersion).pathAppended("platforms").toString(), + QStringList("android-*"), + QDir::Dirs); + while (it.hasNext()) { + const QString &fileName = it.next(); + availableNdkPlatforms.push_back( + fileName.midRef(fileName.lastIndexOf(QLatin1Char('-')) + 1).toInt()); + } + Utils::sort(availableNdkPlatforms, std::greater<>()); + + return availableNdkPlatforms; +} + QStringList AndroidConfig::apiLevelNamesFor(const SdkPlatformList &platforms) { return Utils::transform(platforms, AndroidConfig::apiLevelNameFor); @@ -444,9 +415,9 @@ FilePath AndroidConfig::aaptToolPath() const return aaptToolPath.pathAppended(toolPath); } -FilePath AndroidConfig::toolchainPath() const +FilePath AndroidConfig::toolchainPath(const BaseQtVersion *qtVersion) const { - const FilePath toolchainPath = m_ndkLocation.pathAppended("toolchains/llvm/prebuilt/"); + const FilePath toolchainPath = ndkLocation(qtVersion).pathAppended("toolchains/llvm/prebuilt/"); // detect toolchain host QStringList hostPatterns; @@ -472,29 +443,34 @@ FilePath AndroidConfig::toolchainPath() const return {}; } -FilePath AndroidConfig::clangPath() const +FilePath AndroidConfig::clangPath(const BaseQtVersion *qtVersion) const { - const FilePath path = toolchainPath(); + const FilePath path = toolchainPath(qtVersion); if (path.isEmpty()) return {}; return path.pathAppended(HostOsInfo::withExecutableSuffix("bin/clang")); } -FilePath AndroidConfig::gdbPath(const ProjectExplorer::Abi &abi) const +FilePath AndroidConfig::gdbPath(const ProjectExplorer::Abi &abi, const BaseQtVersion *qtVersion) const { - const FilePath path = m_ndkLocation.pathAppended( - QString("prebuilt/%1/bin/gdb%2").arg(toolchainHost(), QTC_HOST_EXE_SUFFIX)); + const FilePath path = ndkLocation(qtVersion).pathAppended( + QString("prebuilt/%1/bin/gdb%2").arg(toolchainHost(qtVersion), QTC_HOST_EXE_SUFFIX)); if (path.exists()) return path; // fallback for old NDKs (e.g. 10e) - return m_ndkLocation.pathAppended(QString("toolchains/%1-4.9/prebuilt/%2/bin/%3-gdb%4") - .arg(toolchainPrefix(abi), toolchainHost(), toolsPrefix(abi), QTC_HOST_EXE_SUFFIX)); + return ndkLocation(qtVersion).pathAppended(QString("toolchains/%1-4.9/prebuilt/%2/bin/%3-gdb%4") + .arg(toolchainPrefix(abi), toolchainHost(qtVersion), toolsPrefix(abi), QTC_HOST_EXE_SUFFIX)); } -FilePath AndroidConfig::makePath() const +FilePath AndroidConfig::makePath(const BaseQtVersion *qtVersion) const { - return m_ndkLocation.pathAppended( - QString("prebuilt/%1/bin/make%2").arg(toolchainHost(), QTC_HOST_EXE_SUFFIX)); + return makePathFromNdk(ndkLocation(qtVersion)); +} + +FilePath AndroidConfig::makePathFromNdk(const FilePath &ndkLocation) const +{ + return ndkLocation.pathAppended( + QString("prebuilt/%1/bin/make%2").arg(toolchainHostFromNdk(ndkLocation), QTC_HOST_EXE_SUFFIX)); } FilePath AndroidConfig::openJDKBinPath() const @@ -757,11 +733,10 @@ bool AndroidConfig::useNativeUiTools() const return !version.isNull() && version <= QVersionNumber(25, 3 ,0); } -QString AndroidConfig::bestNdkPlatformMatch(int target) const +QString AndroidConfig::bestNdkPlatformMatch(int target, const BaseQtVersion *qtVersion) const { target = std::max(AndroidManager::apiLevelRange().first, target); - updateNdkInformation(); - foreach (int apiLevel, m_availableNdkPlatforms) { + foreach (int apiLevel, availableNdkPlatforms(qtVersion)) { if (apiLevel <= target) return QString::fromLatin1("android-%1").arg(apiLevel); } @@ -812,9 +787,9 @@ void AndroidConfig::setSdkManagerToolArgs(const QStringList &args) m_sdkManagerToolArgs = args; } -FilePath AndroidConfig::ndkLocation() const +FilePath AndroidConfig::ndkLocation(const BaseQtVersion *qtVersion) const { - return m_ndkLocation; + return sdkLocation().pathAppended(ndkPathFromQtVersion(*qtVersion)); } FilePath AndroidConfig::defaultNdkLocation() const @@ -837,9 +812,9 @@ static inline QString gdbServerArch(const QString &androidAbi) } } -FilePath AndroidConfig::gdbServer(const QString &androidAbi) const +FilePath AndroidConfig::gdbServer(const QString &androidAbi, const BaseQtVersion *qtVersion) const { - const FilePath path = AndroidConfigurations::currentConfig().ndkLocation() + const FilePath path = AndroidConfigurations::currentConfig().ndkLocation(qtVersion) .pathAppended(QString("prebuilt/android-%1/gdbserver/gdbserver") .arg(gdbServerArch(androidAbi))); if (path.exists()) @@ -847,16 +822,21 @@ FilePath AndroidConfig::gdbServer(const QString &androidAbi) const return {}; } -QVersionNumber AndroidConfig::ndkVersion() const +QVersionNumber AndroidConfig::ndkVersion(const BaseQtVersion *qtVersion) const +{ + return ndkVersion(ndkLocation(qtVersion)); +} + +QVersionNumber AndroidConfig::ndkVersion(const FilePath &ndkPath) const { QVersionNumber version; - if (!m_ndkLocation.exists()) { + if (!ndkPath.exists()) { qCDebug(avdConfigLog) << "Cannot find ndk version. Check NDK path." - << m_ndkLocation.toString(); + << ndkPath.toString(); return version; } - const FilePath ndkPropertiesPath = m_ndkLocation.pathAppended("source.properties"); + const FilePath ndkPropertiesPath = ndkPath.pathAppended("source.properties"); if (ndkPropertiesPath.exists()) { // source.properties files exists in NDK version > 11 QSettings settings(ndkPropertiesPath.toString(), QSettings::IniFormat); @@ -864,7 +844,7 @@ QVersionNumber AndroidConfig::ndkVersion() const version = QVersionNumber::fromString(versionStr); } else { // No source.properties. There should be a file named RELEASE.TXT - const FilePath ndkReleaseTxtPath = m_ndkLocation.pathAppended("RELEASE.TXT"); + const FilePath ndkReleaseTxtPath = ndkPath.pathAppended("RELEASE.TXT"); Utils::FileReader reader; QString errorString; if (reader.fetch(ndkReleaseTxtPath.toString(), &errorString)) { @@ -892,12 +872,6 @@ QVersionNumber AndroidConfig::ndkVersion() const return version; } -void AndroidConfig::setNdkLocation(const FilePath &ndkLocation) -{ - m_ndkLocation = ndkLocation; - m_NdkInformationUpToDate = false; -} - QStringList AndroidConfig::allEssentials() const { QList installedVersions = QtVersionManager::versions( @@ -925,7 +899,7 @@ QStringList AndroidConfig::essentialsFromQtVersion(const BaseQtVersion &version) QString AndroidConfig::ndkPathFromQtVersion(const BaseQtVersion &version) const { - QtVersionNumber qtVersion = version.qtVersion(); + QtVersionNumber qtVersion(version.qtVersionString()); for (const SdkForQtVersions &item : m_specificQtVersions) if (item.containsVersion(qtVersion)) return item.ndkPath; @@ -969,10 +943,39 @@ void AndroidConfig::setKeystoreLocation(const FilePath &keystoreLocation) m_keystoreLocation = keystoreLocation; } -QString AndroidConfig::toolchainHost() const +QString AndroidConfig::toolchainHost(const BaseQtVersion *qtVersion) const { - updateNdkInformation(); - return m_toolchainHost; + return toolchainHostFromNdk(ndkLocation(qtVersion)); +} + +QString AndroidConfig::toolchainHostFromNdk(const FilePath &ndkPath) const +{ + // detect toolchain host + QString toolchainHost; + QStringList hostPatterns; + switch (HostOsInfo::hostOs()) { + case OsTypeLinux: + hostPatterns << QLatin1String("linux*"); + break; + case OsTypeWindows: + hostPatterns << QLatin1String("windows*"); + break; + case OsTypeMac: + hostPatterns << QLatin1String("darwin*"); + break; + default: /* unknown host */ + return toolchainHost; + } + + QDirIterator jt(ndkPath.pathAppended("prebuilt").toString(), + hostPatterns, + QDir::Dirs); + if (jt.hasNext()) { + jt.next(); + toolchainHost = jt.fileName(); + } + + return toolchainHost; } unsigned AndroidConfig::partitionSize() const @@ -1087,9 +1090,9 @@ void AndroidConfigurations::removeOldToolChains() } } -static QVariant findOrRegisterDebugger(ToolChain *tc) +static QVariant findOrRegisterDebugger(ToolChain *tc, const BaseQtVersion *qtVersion) { - const FilePath command = AndroidConfigurations::currentConfig().gdbPath(tc->targetAbi()); + const FilePath command = AndroidConfigurations::currentConfig().gdbPath(tc->targetAbi(), qtVersion); // check if the debugger is already registered, but ignoring the display name const Debugger::DebuggerItem *existing = Debugger::DebuggerItemManager::findByCommand(command); if (existing && existing->engineType() == Debugger::GdbEngineType && existing->isAutoDetected() @@ -1116,7 +1119,7 @@ void AndroidConfigurations::updateAutomaticKitList() for (auto k: androidKits) { if (k->value(Constants::ANDROID_KIT_NDK).isNull() || k->value(Constants::ANDROID_KIT_SDK).isNull()) { - k->setValueSilently(Constants::ANDROID_KIT_NDK, currentConfig().ndkLocation().toString()); + k->setValueSilently(Constants::ANDROID_KIT_NDK, currentConfig().ndkLocation(QtSupport::QtKitAspect::qtVersion(k)).toString()); k->setValue(Constants::ANDROID_KIT_SDK, currentConfig().sdkLocation().toString()); } } @@ -1163,16 +1166,22 @@ void AndroidConfigurations::updateAutomaticKitList() for (ToolChain *tc : toolchains) { if (tc->language() != Core::Id(ProjectExplorer::Constants::CXX_LANGUAGE_ID)) continue; - const QList allLanguages = Utils::filtered(toolchains, - [tc](ToolChain *otherTc) { - return tc->targetAbi() == otherTc->targetAbi(); - }); - - QHash toolChainForLanguage; - for (ToolChain *tc : allLanguages) - toolChainForLanguage[tc->language()] = tc; for (const QtSupport::BaseQtVersion *qt : qtVersionsForArch.value(tc->targetAbi())) { + FilePath tcNdk = static_cast(tc)->ndkLocation(); + if (tcNdk != currentConfig().ndkLocation(qt)) + continue; + + const QList allLanguages + = Utils::filtered(toolchains, [tc, tcNdk](ToolChain *otherTc) { + FilePath otherNdk = static_cast(otherTc)->ndkLocation(); + return tc->targetAbi() == otherTc->targetAbi() && tcNdk == otherNdk; + }); + + QHash toolChainForLanguage; + for (ToolChain *tc : allLanguages) + toolChainForLanguage[tc->language()] = tc; + Kit *existingKit = Utils::findOrDefault(existingKits, [&](const Kit *b) { if (qt != QtSupport::QtKitAspect::qtVersion(b)) return false; @@ -1190,12 +1199,12 @@ void AndroidConfigurations::updateAutomaticKitList() ToolChainKitAspect::setToolChain(k, tc); QtSupport::QtKitAspect::setQtVersion(k, qt); DeviceKitAspect::setDevice(k, device); - Debugger::DebuggerKitAspect::setDebugger(k, findOrRegisterDebugger(tc)); + Debugger::DebuggerKitAspect::setDebugger(k, findOrRegisterDebugger(tc, QtKitAspect::qtVersion(k))); k->makeSticky(); k->setUnexpandedDisplayName(tr("Android for %1 (Clang %2)") .arg(static_cast(qt)->androidAbis().join(",")) .arg(qt->displayName())); - k->setValueSilently(Constants::ANDROID_KIT_NDK, currentConfig().ndkLocation().toString()); + k->setValueSilently(Constants::ANDROID_KIT_NDK, currentConfig().ndkLocation(qt).toString()); k->setValueSilently(Constants::ANDROID_KIT_SDK, currentConfig().sdkLocation().toString()); }; diff --git a/src/plugins/android/androidconfigurations.h b/src/plugins/android/androidconfigurations.h index 93250713aa7..4a4217e3a2c 100644 --- a/src/plugins/android/androidconfigurations.h +++ b/src/plugins/android/androidconfigurations.h @@ -122,11 +122,11 @@ public: QStringList sdkManagerToolArgs() const; void setSdkManagerToolArgs(const QStringList &args); - Utils::FilePath ndkLocation() const; + Utils::FilePath ndkLocation(const QtSupport::BaseQtVersion *qtVersion) const; Utils::FilePath defaultNdkLocation() const; - Utils::FilePath gdbServer(const QString &androidAbi) const; - QVersionNumber ndkVersion() const; - void setNdkLocation(const Utils::FilePath &ndkLocation); + Utils::FilePath gdbServer(const QString &androidAbi, const QtSupport::BaseQtVersion *qtVersion) const; + QVersionNumber ndkVersion(const QtSupport::BaseQtVersion *qtVersion) const; + QVersionNumber ndkVersion(const Utils::FilePath &ndkPath) const; QUrl sdkToolsUrl() const { return m_sdkToolsUrl; }; QByteArray getSdkToolsSha256() const { return m_sdkToolsSha256; }; @@ -143,7 +143,8 @@ public: Utils::FilePath keystoreLocation() const; void setKeystoreLocation(const Utils::FilePath &keystoreLocation); - QString toolchainHost() const; + QString toolchainHost(const QtSupport::BaseQtVersion *qtVersion) const; + QString toolchainHostFromNdk(const Utils::FilePath &ndkPath) const; unsigned partitionSize() const; void setPartitionSize(unsigned partitionSize); @@ -158,18 +159,19 @@ public: Utils::FilePath avdManagerToolPath() const; Utils::FilePath aaptToolPath() const; - Utils::FilePath toolchainPath() const; - Utils::FilePath clangPath() const; + Utils::FilePath toolchainPath(const QtSupport::BaseQtVersion *qtVersion) const; + Utils::FilePath clangPath(const QtSupport::BaseQtVersion *qtVersion) const; - Utils::FilePath gdbPath(const ProjectExplorer::Abi &abi) const; - Utils::FilePath makePath() const; + Utils::FilePath gdbPath(const ProjectExplorer::Abi &abi, const QtSupport::BaseQtVersion *qtVersion) const; + Utils::FilePath makePath(const QtSupport::BaseQtVersion *qtVersion) const; + Utils::FilePath makePathFromNdk(const Utils::FilePath &ndkLocation) const; Utils::FilePath keytoolPath() const; QVector connectedDevices(QString *error = nullptr) const; static QVector connectedDevices(const Utils::FilePath &adbToolPath, QString *error = nullptr); - QString bestNdkPlatformMatch(int target) const; + QString bestNdkPlatformMatch(int target, const QtSupport::BaseQtVersion *qtVersion) const; static ProjectExplorer::Abi abiForToolChainPrefix(const QString &toolchainPrefix); static QLatin1String toolchainPrefix(const ProjectExplorer::Abi &abi); @@ -199,12 +201,12 @@ private: bool isBootToQt(const QString &device) const; static QString getAvdName(const QString &serialnumber); - void updateNdkInformation() const; void parseDependenciesJson(); + QVector availableNdkPlatforms(const QtSupport::BaseQtVersion *qtVersion) const; + Utils::FilePath m_sdkLocation; QStringList m_sdkManagerToolArgs; - Utils::FilePath m_ndkLocation; Utils::FilePath m_openJDKLocation; Utils::FilePath m_keystoreLocation; unsigned m_partitionSize = 1024; @@ -217,10 +219,6 @@ private: bool m_sdkFullyConfigured = false; //caches - mutable bool m_NdkInformationUpToDate = false; - mutable QString m_toolchainHost; - mutable QVector m_availableNdkPlatforms; - mutable QHash m_serialNumberToDeviceName; }; diff --git a/src/plugins/android/androiddebugsupport.cpp b/src/plugins/android/androiddebugsupport.cpp index 1d5737552ef..3ffed5e7ecb 100644 --- a/src/plugins/android/androiddebugsupport.cpp +++ b/src/plugins/android/androiddebugsupport.cpp @@ -122,14 +122,13 @@ void AndroidDebugSupport::start() qCDebug(androidDebugSupportLog) << "Start. Package name: " << packageName << "PID: " << m_runner->pid().pid(); + QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(kit); if (!Utils::HostOsInfo::isWindowsHost() && - AndroidConfigurations::currentConfig().ndkVersion() >= QVersionNumber(11, 0, 0)) { + AndroidConfigurations::currentConfig().ndkVersion(qtVersion) >= QVersionNumber(11, 0, 0)) { qCDebug(androidDebugSupportLog) << "UseTargetAsync: " << true; setUseTargetAsync(true); } - QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitAspect::qtVersion(kit); - if (isCppDebugging()) { qCDebug(androidDebugSupportLog) << "C++ debugging enabled"; const ProjectNode *node = target->project()->findNodeForBuildKey(runControl()->buildKey()); @@ -160,7 +159,7 @@ void AndroidDebugSupport::start() // TODO find a way to use the new sysroot layout // instead ~/android/ndk-bundle/platforms/android-29/arch-arm64 // use ~/android/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/sysroot - Utils::FilePath sysRoot = AndroidConfigurations::currentConfig().ndkLocation() + Utils::FilePath sysRoot = AndroidConfigurations::currentConfig().ndkLocation(qtVersion) .pathAppended("platforms") .pathAppended(QString("android-%1").arg(sdkVersion)) .pathAppended(devicePreferredAbi); diff --git a/src/plugins/android/androidmanager.cpp b/src/plugins/android/androidmanager.cpp index 16a50c48a5f..9b94f3473ce 100644 --- a/src/plugins/android/androidmanager.cpp +++ b/src/plugins/android/androidmanager.cpp @@ -293,22 +293,25 @@ QJsonObject AndroidManager::deploymentSettings(const Target *target) QJsonObject settings; settings["_description"] = qtcSignature; settings["qt"] = qt->prefix().toString(); - settings["ndk"] = AndroidConfigurations::currentConfig().ndkLocation().toString(); + settings["ndk"] = AndroidConfigurations::currentConfig().ndkLocation(qt).toString(); settings["sdk"] = AndroidConfigurations::currentConfig().sdkLocation().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() + settings["stdcpp-path"] = AndroidConfigurations::currentConfig().toolchainPath(qt) .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["stdcpp-path"] = AndroidConfigurations::currentConfig() + .toolchainPath(qt) + .pathAppended("sysroot/usr/lib/") + .toString(); } settings["toolchain-prefix"] = "llvm"; settings["tool-prefix"] = "llvm"; settings["useLLVM"] = true; - settings["ndk-host"] = AndroidConfigurations::currentConfig().toolchainHost(); + settings["ndk-host"] = AndroidConfigurations::currentConfig().toolchainHost(qt); return settings; } diff --git a/src/plugins/android/androidmanifesteditorwidget.cpp b/src/plugins/android/androidmanifesteditorwidget.cpp index 7f98cb2f9d5..6f0bff08bcb 100644 --- a/src/plugins/android/androidmanifesteditorwidget.cpp +++ b/src/plugins/android/androidmanifesteditorwidget.cpp @@ -34,6 +34,8 @@ #include #include +#include + #include #include #include @@ -612,8 +614,10 @@ void AndroidManifestEditorWidget::postSave() const Utils::FilePath docPath = m_textEditorWidget->textDocument()->filePath(); if (Target *target = androidTarget(docPath)) { if (BuildConfiguration *bc = target->activeBuildConfiguration()) { - QString androidNdkPlatform = AndroidConfigurations::currentConfig() - .bestNdkPlatformMatch(AndroidManager::minimumSDK(target)); + QString androidNdkPlatform = AndroidConfigurations::currentConfig().bestNdkPlatformMatch( + AndroidManager::minimumSDK(target), + QtSupport::QtKitAspect::qtVersion( + androidTarget(m_textEditorWidget->textDocument()->filePath())->kit())); if (m_androidNdkPlatform != androidNdkPlatform) { m_androidNdkPlatform = androidNdkPlatform; bc->updateCacheAndEmitEnvironmentChanged(); diff --git a/src/plugins/android/androidplugin.cpp b/src/plugins/android/androidplugin.cpp index 43a50e29e3e..1fcdd9bd720 100644 --- a/src/plugins/android/androidplugin.cpp +++ b/src/plugins/android/androidplugin.cpp @@ -178,6 +178,7 @@ void AndroidPlugin::kitsRestored() } AndroidConfigurations::updateAutomaticKitList(); + AndroidConfigurations::registerNewToolChains(); connect(QtSupport::QtVersionManager::instance(), &QtSupport::QtVersionManager::qtVersionsChanged, AndroidConfigurations::instance(), &AndroidConfigurations::updateAutomaticKitList); disconnect(KitManager::instance(), &KitManager::kitsLoaded, diff --git a/src/plugins/android/androidqtversion.cpp b/src/plugins/android/androidqtversion.cpp index 48aeab8e543..9b6a2df57c5 100644 --- a/src/plugins/android/androidqtversion.cpp +++ b/src/plugins/android/androidqtversion.cpp @@ -70,7 +70,7 @@ QString AndroidQtVersion::invalidReason() const { QString tmp = BaseQtVersion::invalidReason(); if (tmp.isEmpty()) { - if (AndroidConfigurations::currentConfig().ndkLocation().isEmpty()) + if (AndroidConfigurations::currentConfig().ndkLocation(this).isEmpty()) return tr("NDK is not configured in Devices > Android."); if (AndroidConfigurations::currentConfig().sdkLocation().isEmpty()) return tr("SDK is not configured in Devices > Android."); @@ -126,16 +126,17 @@ void AndroidQtVersion::addToEnvironment(const Kit *k, Utils::Environment &env) c { const AndroidConfig &config =AndroidConfigurations::currentConfig(); // this env vars are used by qmake mkspecs to generate makefiles (check QTDIR/mkspecs/android-g++/qmake.conf for more info) - env.set(QLatin1String("ANDROID_NDK_HOST"), config.toolchainHost()); - env.set(QLatin1String("ANDROID_NDK_ROOT"), config.ndkLocation().toUserOutput()); + env.set(QLatin1String("ANDROID_NDK_HOST"), config.toolchainHost(this)); + env.set(QLatin1String("ANDROID_NDK_ROOT"), config.ndkLocation(this).toUserOutput()); env.set(QLatin1String("ANDROID_NDK_PLATFORM"), - config.bestNdkPlatformMatch(qMax(minimumNDK(), AndroidManager::minimumSDK(k)))); + config.bestNdkPlatformMatch(qMax(minimumNDK(), AndroidManager::minimumSDK(k)), this)); } Utils::Environment AndroidQtVersion::qmakeRunEnvironment() const { Utils::Environment env = Utils::Environment::systemEnvironment(); - env.set(QLatin1String("ANDROID_NDK_ROOT"), AndroidConfigurations::currentConfig().ndkLocation().toUserOutput()); + env.set(QLatin1String("ANDROID_NDK_ROOT"), + AndroidConfigurations::currentConfig().ndkLocation(this).toUserOutput()); return env; } diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp index db5e9807e69..1fb878109f6 100644 --- a/src/plugins/android/androidrunnerworker.cpp +++ b/src/plugins/android/androidrunnerworker.cpp @@ -225,10 +225,11 @@ AndroidRunnerWorker::AndroidRunnerWorker(RunWorker *runner, const QString &packa << "Extra Start Args:" << m_amStartExtraArgs << "Before Start ADB cmds:" << m_beforeStartAdbCommands << "After finish ADB cmds:" << m_afterFinishAdbCommands; + QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(target->kit()); QString preferredAbi = AndroidManager::apkDevicePreferredAbi(target); if (!preferredAbi.isEmpty()) - m_gdbserverPath = AndroidConfigurations::instance()->currentConfig().gdbServer(preferredAbi).toString(); - QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(target->kit()); + m_gdbserverPath = AndroidConfigurations::instance() + ->currentConfig().gdbServer(preferredAbi, version).toString(); m_useAppParamsForQmlDebugger = version->qtVersion() >= QtSupport::QtVersionNumber(5, 12); } diff --git a/src/plugins/android/androidsettingswidget.cpp b/src/plugins/android/androidsettingswidget.cpp index bd7b1add50f..e70a7ce34fb 100644 --- a/src/plugins/android/androidsettingswidget.cpp +++ b/src/plugins/android/androidsettingswidget.cpp @@ -336,10 +336,8 @@ Utils::FilePath AndroidSettingsWidget::getDefaultSdkPath() void AndroidSettingsWidget::updateNdkList() { m_ui->ndkListComboBox->clear(); - QString currentNdk = m_androidConfig.ndkLocation().toString(); for (const Ndk *ndk : m_sdkManager->installedNdkPackages()) m_ui->ndkListComboBox->addItem(ndk->installedLocation().toString()); - m_ui->ndkListComboBox->setCurrentText(currentNdk); } AndroidSettingsWidget::AndroidSettingsWidget() @@ -584,7 +582,6 @@ Utils::FilePath AndroidSettingsWidget::findJdkInCommonPaths() void AndroidSettingsWidget::validateNdk() { auto ndkPath = Utils::FilePath::fromUserInput(m_ui->ndkListComboBox->currentText()); - m_androidConfig.setNdkLocation(ndkPath); auto summaryWidget = static_cast(m_ui->androidDetailsWidget->widget()); summaryWidget->setPointValid(NdkPathExistsRow, ndkPath.exists()); @@ -745,9 +742,10 @@ void AndroidSettingsWidget::updateUI() m_ui->sdkManagerTab->setEnabled(sdkToolsOk); m_sdkManagerWidget->setSdkManagerControlsEnabled(!m_androidConfig.useNativeUiTools()); + Utils::FilePath currentNdk = Utils::FilePath::fromString(m_ui->ndkListComboBox->currentText()); auto infoText = tr("(SDK Version: %1, NDK Bundle Version: %2)") - .arg(m_androidConfig.sdkToolsVersion().toString()) - .arg(m_androidConfig.ndkVersion().toString()); + .arg(m_androidConfig.sdkToolsVersion().toString()) + .arg(currentNdk.isEmpty() ? "" : m_androidConfig.ndkVersion(currentNdk).toString()); androidSummaryWidget->setInfoText(androidSetupOk ? infoText : ""); m_ui->javaDetailsWidget->setState(javaSetupOk ? Utils::DetailsWidget::Collapsed : diff --git a/src/plugins/android/androidtoolchain.cpp b/src/plugins/android/androidtoolchain.cpp index b132d0042bd..a9f5aeb2816 100644 --- a/src/plugins/android/androidtoolchain.cpp +++ b/src/plugins/android/androidtoolchain.cpp @@ -27,6 +27,7 @@ #include "androidconstants.h" #include "androidconfigurations.h" +#include #include #include @@ -78,22 +79,36 @@ AndroidToolChain::AndroidToolChain() setTypeDisplayName(AndroidToolChainFactory::tr("Android Clang")); } +Utils::FilePath AndroidToolChain::ndkLocation() const +{ + return m_ndkLocation; +} + +void AndroidToolChain::setNdkLocation(const Utils::FilePath &ndkLocation) +{ + m_ndkLocation = ndkLocation; +} + AndroidToolChain::~AndroidToolChain() = default; bool AndroidToolChain::isValid() const { - return ClangToolChain::isValid() - && typeId() == Constants::ANDROID_TOOLCHAIN_TYPEID - && targetAbi().isValid() - && compilerCommand().isChildOf(AndroidConfigurations::currentConfig().ndkLocation()) - && !originalTargetTriple().isEmpty(); + const bool isChildofNdk = compilerCommand().isChildOf(m_ndkLocation); + // If we're restoring a toolchain we set NDK path ourselves so it's enough to check against SDK + const bool isChildofSdk = compilerCommand().isChildOf( + AndroidConfigurations::currentConfig().sdkLocation()); + + return ClangToolChain::isValid() && typeId() == Constants::ANDROID_TOOLCHAIN_TYPEID + && targetAbi().isValid() + && (isChildofNdk || isChildofSdk) + && !originalTargetTriple().isEmpty(); } void AndroidToolChain::addToEnvironment(Environment &env) const { - env.set(QLatin1String("ANDROID_NDK_HOST"), - AndroidConfigurations::currentConfig().toolchainHost()); - const Utils::FilePath javaHome = AndroidConfigurations::currentConfig().openJDKLocation(); + AndroidConfig config = AndroidConfigurations::currentConfig(); + env.set(QLatin1String("ANDROID_NDK_HOST"), config.toolchainHostFromNdk(m_ndkLocation)); + const Utils::FilePath javaHome = config.openJDKLocation(); if (javaHome.exists()) { env.set(QLatin1String("JAVA_HOME"), javaHome.toString()); const FilePath javaBin = javaHome.pathAppended("bin"); @@ -101,10 +116,8 @@ void AndroidToolChain::addToEnvironment(Environment &env) const if (!currentJavaFilePath.isChildOf(javaBin)) env.prependOrSetPath(javaBin.toUserOutput()); } - env.set(QLatin1String("ANDROID_HOME"), - AndroidConfigurations::currentConfig().sdkLocation().toString()); - env.set(QLatin1String("ANDROID_SDK_ROOT"), - AndroidConfigurations::currentConfig().sdkLocation().toString()); + env.set(QLatin1String("ANDROID_HOME"), config.sdkLocation().toString()); + env.set(QLatin1String("ANDROID_SDK_ROOT"), config.sdkLocation().toString()); } bool AndroidToolChain::fromMap(const QVariantMap &data) @@ -122,7 +135,7 @@ QStringList AndroidToolChain::suggestedMkspecList() const FilePath AndroidToolChain::makeCommand(const Environment &env) const { Q_UNUSED(env) - FilePath makePath = AndroidConfigurations::currentConfig().makePath(); + FilePath makePath = AndroidConfigurations::currentConfig().makePathFromNdk(m_ndkLocation); return makePath.exists() ? makePath : FilePath::fromString("make"); } @@ -160,53 +173,83 @@ static FilePath clangPlusPlusPath(const FilePath &clangPath) QFileInfo(clangPath.toString()).baseName() + "++")); } +static QList androidQtVersionsWithUniqueNdk() +{ + AndroidConfig config = AndroidConfigurations::currentConfig(); + + auto androidQtVersions = QtSupport::QtVersionManager::versions( + [](const QtSupport::BaseQtVersion *v) { + return v->targetDeviceTypes().contains(Android::Constants::ANDROID_DEVICE_TYPE); + }); + + auto shouldRemove = [config](const QtSupport::BaseQtVersion *first, + const QtSupport::BaseQtVersion *second) { + return config.ndkLocation(first) == config.ndkLocation(second); + }; + + QList::iterator it = std::unique(androidQtVersions.begin(), + androidQtVersions.end(), + shouldRemove); + androidQtVersions.erase(it, androidQtVersions.end()); + + return androidQtVersions; +} + ToolChainList AndroidToolChainFactory::autodetectToolChainsForNdk(const ToolChainList &alreadyKnown) { QList result; - FilePath clangPath = AndroidConfigurations::currentConfig().clangPath(); - if (!clangPath.exists()) { - qCDebug(androidTCLog) << "Clang toolchains detection fails. Can not find Clang"<< clangPath; - return result; - } + const QList androidQtVersions = androidQtVersionsWithUniqueNdk(); + const AndroidConfig config = AndroidConfigurations::currentConfig(); - qCDebug(androidTCLog) << "Detecting toolchains from Android NDK:" - << AndroidConfigurations::currentConfig().ndkLocation(); - - for (const Core::Id &lang : LanguageIds) { - FilePath compilerCommand = clangPath; - if (lang == ProjectExplorer::Constants::CXX_LANGUAGE_ID) - compilerCommand = clangPlusPlusPath(clangPath); - - if (!compilerCommand.exists()) { - qCDebug(androidTCLog) << "Skipping Clang toolchain. Can not find compiler" - << compilerCommand; - continue; + for (const QtSupport::BaseQtVersion *qtVersion : androidQtVersions) { + FilePath clangPath = config.clangPath(qtVersion); + if (!clangPath.exists()) { + qCDebug(androidTCLog) << "Clang toolchains detection fails. Can not find Clang" + << clangPath; + return result; } - auto targetItr = ClangTargets.constBegin(); - while (targetItr != ClangTargets.constEnd()) { - const Abi &abi = targetItr.value(); - const QString target = targetItr.key(); - ToolChain *tc = findToolChain(compilerCommand, lang, target, alreadyKnown); - if (tc) { - qCDebug(androidTCLog) << "Tool chain already known" << abi.toString() << lang; - } else { - qCDebug(androidTCLog) << "New Clang toolchain found" << abi.toString() << lang; - auto atc = new AndroidToolChain; - atc->setOriginalTargetTriple(target); - atc->setLanguage(lang); - atc->setTargetAbi(ClangTargets[target]); - atc->setPlatformCodeGenFlags({"-target", target}); - atc->setPlatformLinkerFlags({"-target", target}); - atc->setDetection(ToolChain::AutoDetection); - atc->setDisplayName(QString("Android Clang (%1, %2)") - .arg(ToolChainManager::displayNameOfLanguageId(lang), - AndroidConfig::displayName(abi))); - atc->resetToolChain(compilerCommand); - tc = atc; + qCDebug(androidTCLog) << "Detecting toolchains from Android NDK:" + << config.ndkLocation(qtVersion); + + for (const Core::Id &lang : LanguageIds) { + FilePath compilerCommand = clangPath; + if (lang == ProjectExplorer::Constants::CXX_LANGUAGE_ID) + compilerCommand = clangPlusPlusPath(clangPath); + + if (!compilerCommand.exists()) { + qCDebug(androidTCLog) + << "Skipping Clang toolchain. Can not find compiler" << compilerCommand; + continue; + } + + auto targetItr = ClangTargets.constBegin(); + while (targetItr != ClangTargets.constEnd()) { + const Abi &abi = targetItr.value(); + const QString target = targetItr.key(); + ToolChain *tc = findToolChain(compilerCommand, lang, target, alreadyKnown); + if (tc) { + qCDebug(androidTCLog) << "Tool chain already known" << abi.toString() << lang; + } else { + qCDebug(androidTCLog) << "New Clang toolchain found" << abi.toString() << lang; + auto atc = new AndroidToolChain(); + atc->setNdkLocation(config.ndkLocation(qtVersion)); + atc->setOriginalTargetTriple(target); + atc->setLanguage(lang); + atc->setTargetAbi(ClangTargets[target]); + atc->setPlatformCodeGenFlags({"-target", target}); + atc->setPlatformLinkerFlags({"-target", target}); + atc->setDetection(ToolChain::AutoDetection); + atc->setDisplayName(QString("Android Clang (%1, %2, NDK %3)") + .arg(ToolChainManager::displayNameOfLanguageId(lang), + AndroidConfig::displayName(abi), + config.ndkVersion(qtVersion).toString())); + atc->resetToolChain(compilerCommand); + tc = atc; + } + result << tc; + ++targetItr; } - result << tc; - ++targetItr; } } diff --git a/src/plugins/android/androidtoolchain.h b/src/plugins/android/androidtoolchain.h index 7f620dd9805..26c55f20a13 100644 --- a/src/plugins/android/androidtoolchain.h +++ b/src/plugins/android/androidtoolchain.h @@ -25,6 +25,8 @@ #pragma once +#include + #include namespace Android { @@ -44,6 +46,9 @@ public: Utils::FilePath makeCommand(const Utils::Environment &environment) const override; bool fromMap(const QVariantMap &data) override; + void setNdkLocation(const Utils::FilePath &ndkLocation); + Utils::FilePath ndkLocation() const; + protected: DetectedAbisResult detectSupportedAbis() const override; @@ -51,6 +56,8 @@ private: explicit AndroidToolChain(); friend class AndroidToolChainFactory; + + Utils::FilePath m_ndkLocation; }; class AndroidToolChainFactory : public ProjectExplorer::ToolChainFactory From a854e0daa84af04b319939114fa0b3e56df0685f Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Mon, 17 Feb 2020 17:47:58 +0100 Subject: [PATCH 02/13] QmlDesigner: Fix qbs build Change-Id: I037fe18974e1fcf10c0899c051ebbc1d9142afc4 Reviewed-by: Aleksei German Reviewed-by: Tim Jenssen --- .../components/annotationeditor/annotationeditordialog.cpp | 5 ++--- src/plugins/qmldesigner/qmldesignerplugin.qbs | 5 +++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.cpp b/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.cpp index ec99af6498f..ca91f308ea9 100644 --- a/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.cpp +++ b/src/plugins/qmldesigner/components/annotationeditor/annotationeditordialog.cpp @@ -30,14 +30,13 @@ #include "ui_annotationcommenttab.h" +#include //replace timeline icons with our own? + #include #include #include #include - -#include "timelineicons.h" //replace timeline icons with our own? - namespace QmlDesigner { AnnotationEditorDialog::AnnotationEditorDialog(QWidget *parent, const QString &targetId, const QString &customId, const Annotation &annotation) diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs index b6939808f2a..64644895ffd 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.qbs +++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs @@ -55,7 +55,8 @@ Project { "components/navigator", "components/pluginmanager", "components/stateseditor", - "components/texteditor" + "components/texteditor", + "components/timelineeditor", ]) Properties { @@ -647,7 +648,7 @@ Project { "annotationeditor/annotationeditor.h", "annotationeditor/annotationeditordialog.cpp", "annotationeditor/annotationeditordialog.h", - "annotationeditor/annotationeditordialog.ui + "annotationeditor/annotationeditordialog.ui", "annotationeditor/annotationtool.cpp", "annotationeditor/annotationtool.h", "bindingeditor/bindingeditor.cpp", From e2fad3afa41770977390884e4a30dc99e6f53fe1 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Mon, 17 Feb 2020 16:59:34 +0100 Subject: [PATCH 03/13] doc: Fix qdoc warnings in aggregation Change-Id: Ia9a2e6dcdb8dc82ae600b974e396fd8ac3a42678 Reviewed-by: Leena Miettinen --- .../config/qtcreator-developer.qdocconf | 2 ++ src/libs/aggregation/aggregate.cpp | 18 ++++-------------- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/doc/qtcreatordev/config/qtcreator-developer.qdocconf b/doc/qtcreatordev/config/qtcreator-developer.qdocconf index 63903e0dcd4..72fd0efb2cd 100644 --- a/doc/qtcreatordev/config/qtcreator-developer.qdocconf +++ b/doc/qtcreatordev/config/qtcreator-developer.qdocconf @@ -13,6 +13,8 @@ sourcedirs = . \ ../../../src/libs/aggregation \ ../../../src/libs/extensionsystem +excludedirs = ../../../src/libs/aggregation/examples + # -- Uncomment following option to generate complete documentation # instead of public API documentation only. #showinternal = true diff --git a/src/libs/aggregation/aggregate.cpp b/src/libs/aggregation/aggregate.cpp index 3c2ea217b13..a4cb2dd436d 100644 --- a/src/libs/aggregation/aggregate.cpp +++ b/src/libs/aggregation/aggregate.cpp @@ -104,7 +104,7 @@ */ /*! - \fn T *Aggregate::component() + \fn template T *Aggregation::Aggregate::component() Template function that returns the component with the given type, if there is one. If there are multiple components with that type, a random one is returned. @@ -113,26 +113,16 @@ */ /*! - \fn QList Aggregate::components() + \fn template QList Aggregation::Aggregate::components() Template function that returns all components with the given type, if there are any. \sa Aggregate::component(), add() */ -/*! - \fn T *Aggregation::query(Aggregate *obj) - \internal -*/ - -/*! - \fn QList Aggregation::query_all(Aggregate *obj) - \internal -*/ - /*! \relates Aggregation::Aggregate - \fn T *Aggregation::query(QObject *obj) + \fn template T *Aggregation::query(QObject *obj) Performs a dynamic cast that is aware of a possible aggregate that \a obj might belong to. If \a obj itself is of the requested type, it is simply cast @@ -144,7 +134,7 @@ /*! \relates Aggregation::Aggregate - \fn QList Aggregation::query_all(QObject *obj) + \fn template QList Aggregation::query_all(QObject *obj) If \a obj belongs to an aggregate, all components that can be cast to the given type are returned. Otherwise, \a obj is returned if it is of the requested type. From cde9f31068bed64bc06fd75fc3fc95418bee9f3d Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 13 Feb 2020 14:50:15 +0100 Subject: [PATCH 04/13] macOS: Fix signing issues with notarization Notarization requires signing with hardened runtime, but this added requirements to the additional plugins we copy into Qt Creator for the commercial package. This patch fixes an issue with an absolute RPATH still being left in extra plugins, and avoids copying plugins into an already signed application by not signing the 7zips, but only the contents in the open source disk image (and the installers are signed by the installer jobs anyhow). Change-Id: I8c945a0ad9df610b20a8ee110320875f255c65b4 Reviewed-by: Eike Ziller --- scripts/common.py | 54 +++++++++++++++++++++--------------- scripts/createDistPackage.py | 6 +--- scripts/packagePlugins.py | 9 ++++-- 3 files changed, 40 insertions(+), 29 deletions(-) diff --git a/scripts/common.py b/scripts/common.py index 7c2fb13271d..db97ea35616 100644 --- a/scripts/common.py +++ b/scripts/common.py @@ -91,7 +91,8 @@ def copytree(src, dst, symlinks=False, ignore=None): def get_qt_install_info(qmake_bin): output = subprocess.check_output([qmake_bin, '-query']) - lines = output.decode(encoding).strip().split('\n') + decoded_output = output.decode(encoding) if encoding else output + lines = decoded_output.strip().split('\n') info = {} for line in lines: (var, sep, value) = line.partition(':') @@ -178,28 +179,37 @@ def is_not_debug(path, filenames): files = [fn for fn in filenames if os.path.isfile(os.path.join(path, fn))] return [fn for fn in files if not is_debug_file(os.path.join(path, fn))] -def codesign(app_path): +def codesign_call(): signing_identity = os.environ.get('SIGNING_IDENTITY') - if is_mac_platform() and signing_identity: - codesign_call = ['codesign', '-o', 'runtime', '--force', '-s', signing_identity, - '-v'] - signing_flags = os.environ.get('SIGNING_FLAGS') - if signing_flags: - codesign_call.extend(signing_flags.split()) + if not signing_identity: + return None + codesign_call = ['codesign', '-o', 'runtime', '--force', '-s', signing_identity, + '-v'] + signing_flags = os.environ.get('SIGNING_FLAGS') + if signing_flags: + codesign_call.extend(signing_flags.split()) + return codesign_call - def conditional_sign_recursive(path, filter): - for r, _, fs in os.walk(path): - for f in fs: - ff = os.path.join(r, f) - if filter(ff): - print('codesign "' + ff + '"') - subprocess.check_call(codesign_call + [ff]) +def os_walk(path, filter, function): + for r, _, fs in os.walk(path): + for f in fs: + ff = os.path.join(r, f) + if filter(ff): + function(ff) - # sign all executables in Resources - conditional_sign_recursive(os.path.join(app_path, 'Contents', 'Resources'), - lambda ff: os.access(ff, os.X_OK)) - # sign all libraries in Imports - conditional_sign_recursive(os.path.join(app_path, 'Contents', 'Imports'), - lambda ff: ff.endswith('.dylib')) +def conditional_sign_recursive(path, filter): + codesign = codesign_call() + if is_mac_platform() and codesign: + os_walk(path, filter, lambda fp: subprocess.check_call(codesign + [fp])) + +def codesign(app_path): + # sign all executables in Resources + conditional_sign_recursive(os.path.join(app_path, 'Contents', 'Resources'), + lambda ff: os.access(ff, os.X_OK)) + # sign all libraries in Imports + conditional_sign_recursive(os.path.join(app_path, 'Contents', 'Imports'), + lambda ff: ff.endswith('.dylib')) + codesign = codesign_call() + if is_mac_platform() and codesign: # sign the whole bundle - subprocess.check_call(codesign_call + ['--deep', app_path]) + subprocess.check_call(codesign + ['--deep', app_path]) diff --git a/scripts/createDistPackage.py b/scripts/createDistPackage.py index 41c36f9ee97..ad23a617e38 100755 --- a/scripts/createDistPackage.py +++ b/scripts/createDistPackage.py @@ -33,8 +33,7 @@ import tempfile import common def parse_arguments(): - parser = argparse.ArgumentParser(description="Create Qt Creator package, filtering out debug information files.", - epilog="To sign the contents before packaging on macOS, set the SIGNING_IDENTITY and optionally the SIGNING_FLAGS environment variables.") + parser = argparse.ArgumentParser(description="Create Qt Creator package, filtering out debug information files.") parser.add_argument('--7z', help='path to 7z binary', default='7z.exe' if common.is_windows_platform() else '7z', metavar='<7z_binary>', dest='sevenzip') @@ -53,9 +52,6 @@ def main(): try: common.copytree(arguments.source_directory, tempdir, symlinks=True, ignore=(common.is_not_debug if arguments.debug else common.is_debug)) - # on macOS we might have to codesign (again) to account for removed debug info - if not arguments.debug: - common.codesign(tempdir) # package zip_source = os.path.join(tempdir, '*') if arguments.exclude_toplevel else tempdir subprocess.check_call([arguments.sevenzip, 'a', '-mmt2', diff --git a/scripts/packagePlugins.py b/scripts/packagePlugins.py index d70de8e33db..5cbace790c3 100755 --- a/scripts/packagePlugins.py +++ b/scripts/packagePlugins.py @@ -28,7 +28,6 @@ import argparse import os import subprocess -import sys import common @@ -45,10 +44,16 @@ def parse_arguments(): if __name__ == "__main__": arguments = parse_arguments() + qt_install_info = common.get_qt_install_info(arguments.qmake_binary) if common.is_linux_platform(): - qt_install_info = common.get_qt_install_info(arguments.qmake_binary) common.fix_rpaths(arguments.source_directory, os.path.join(arguments.source_directory, 'lib', 'Qt', 'lib'), qt_install_info) + if common.is_mac_platform(): + # remove Qt rpath + lib_path = qt_install_info['QT_INSTALL_LIBS'] + common.os_walk(arguments.source_directory, + lambda fp: fp.endswith('.dylib'), + lambda fp: subprocess.call(['install_name_tool', '-delete_rpath', lib_path, fp])) subprocess.check_call([arguments.sevenzip, 'a', '-mx9', arguments.target_file, os.path.join(arguments.source_directory, '*')]) From 909cb3859b1b68408cbf71354c95b6bf39d15c12 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 12 Feb 2020 10:36:09 +0100 Subject: [PATCH 05/13] Editor: update proposal widget after editor contents changed Also when text is removed via shortcuts. Fixes: QTCREATORBUG-15038 Change-Id: I1c78b9306594fbf13378a55b27be18769de141a6 Reviewed-by: Christian Stenger --- .../texteditor/codeassist/functionhintproposalwidget.cpp | 2 -- src/plugins/texteditor/codeassist/genericproposalwidget.cpp | 2 -- src/plugins/texteditor/texteditor.cpp | 5 ++--- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp b/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp index 292c46ccccf..6abdeff6087 100644 --- a/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp +++ b/src/plugins/texteditor/codeassist/functionhintproposalwidget.cpp @@ -292,8 +292,6 @@ bool FunctionHintProposalWidget::eventFilter(QObject *obj, QEvent *e) if (d->m_model && d->m_model->size() > 1) return false; } - if (QTC_GUARD(d->m_assistant)) - d->m_assistant->notifyChange(); } break; case QEvent::WindowDeactivate: diff --git a/src/plugins/texteditor/codeassist/genericproposalwidget.cpp b/src/plugins/texteditor/codeassist/genericproposalwidget.cpp index 92f3e9a3b91..241a98951d5 100644 --- a/src/plugins/texteditor/codeassist/genericproposalwidget.cpp +++ b/src/plugins/texteditor/codeassist/genericproposalwidget.cpp @@ -665,8 +665,6 @@ bool GenericProposalWidget::eventFilter(QObject *o, QEvent *e) } QApplication::sendEvent(const_cast(d->m_underlyingWidget), e); - if (isVisible()) - d->m_assistant->notifyChange(); return true; } diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 635acd6e661..361419db7fb 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -741,7 +741,6 @@ public: QTimer m_highlightBlocksTimer; CodeAssistant m_codeAssistant; - bool m_assistRelevantContentAdded = false; QList m_hoverHandlers; // Not owned HoverHandlerRunner m_hoverHandlerRunner; @@ -1502,8 +1501,8 @@ void TextEditorWidgetPrivate::editorContentsChange(int position, int charsRemove snippetCheckCursor(cursor); } - if (charsAdded != 0 && q->document()->characterAt(position + charsAdded - 1).isPrint()) - m_assistRelevantContentAdded = true; + if ((charsAdded != 0 && q->document()->characterAt(position + charsAdded - 1).isPrint()) || charsRemoved != 0) + m_codeAssistant.notifyChange(); int newBlockCount = doc->blockCount(); if (!q->hasFocus() && newBlockCount != m_blockCount) { From b9af9881a9024732e738f05fbaa7375f69eb47e5 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Mon, 17 Feb 2020 12:57:59 +0100 Subject: [PATCH 06/13] LanguageClient: update semantic highlighting only if server supports it Task-number: QTCREATORBUG-23599 Change-Id: I76c804b51362ad6ab2aecf0631a16289a33e4810 Reviewed-by: Christian Stenger --- src/plugins/languageclient/client.cpp | 6 ++++-- .../languageclient/semantichighlightsupport.cpp | 10 ++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/plugins/languageclient/client.cpp b/src/plugins/languageclient/client.cpp index cafad5f89cc..5d62cdfeb9a 100644 --- a/src/plugins/languageclient/client.cpp +++ b/src/plugins/languageclient/client.cpp @@ -392,8 +392,10 @@ void Client::deactivateDocument(TextEditor::TextDocument *document) hideDiagnostics(document); resetAssistProviders(document); document->setFormatter(nullptr); - if (TextEditor::SyntaxHighlighter *highlighter = document->syntaxHighlighter()) - highlighter->clearAllExtraFormats(); + if (m_serverCapabilities.semanticHighlighting().has_value()) { + if (TextEditor::SyntaxHighlighter *highlighter = document->syntaxHighlighter()) + highlighter->clearAllExtraFormats(); + } for (Core::IEditor *editor : Core::DocumentModel::editorsForDocument(document)) { if (auto textEditor = qobject_cast(editor)) textEditor->editorWidget()->removeHoverHandler(&m_hoverHandler); diff --git a/src/plugins/languageclient/semantichighlightsupport.cpp b/src/plugins/languageclient/semantichighlightsupport.cpp index 59b415455f7..8f333ea1838 100644 --- a/src/plugins/languageclient/semantichighlightsupport.cpp +++ b/src/plugins/languageclient/semantichighlightsupport.cpp @@ -151,10 +151,12 @@ void applyHighlight(TextEditor::TextDocument *doc, } } - TextEditor::SemanticHighlighter::setExtraAdditionalFormats( - doc->syntaxHighlighter(), - results, - scopesToFormatHash(highlightScopes(capabilities), doc->fontSettings())); + if (capabilities.semanticHighlighting().has_value()) { + TextEditor::SemanticHighlighter::setExtraAdditionalFormats( + doc->syntaxHighlighter(), + results, + scopesToFormatHash(highlightScopes(capabilities), doc->fontSettings())); + } } } // namespace SemanticHighligtingSupport From 5721ccb03b411db6b0e7673241fbbe284212f236 Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Tue, 18 Feb 2020 09:36:21 +0100 Subject: [PATCH 07/13] QmlDesigner: Fix build with tests Amends c81d672bb0b2ac101f2c864b3933ec532cc750a6 and a854e0daa84af04b319939114fa0b3e56df0685f. Change-Id: I85d293a2abc437613be924084480a173190bda8b Reviewed-by: Aleksei German Reviewed-by: Tim Jenssen --- src/plugins/qmldesigner/CMakeLists.txt | 5 +++-- .../components/annotationeditor/annotationeditor.pri | 2 -- .../components/formeditor/formeditorannotationicon.cpp | 1 - .../components/formeditor/formeditorannotationicon.h | 8 ++------ .../components/formeditor/selectionindicator.cpp | 2 +- src/plugins/qmldesigner/designercore/designercore-lib.pri | 6 ++++-- .../include}/annotation.h | 0 .../model}/annotation.cpp | 0 src/plugins/qmldesigner/designercore/model/modelnode.cpp | 2 +- src/plugins/qmldesigner/qmldesignerplugin.qbs | 4 ++-- 10 files changed, 13 insertions(+), 17 deletions(-) rename src/plugins/qmldesigner/{components/annotationeditor => designercore/include}/annotation.h (100%) rename src/plugins/qmldesigner/{components/annotationeditor => designercore/model}/annotation.cpp (100%) diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt index ca2605877e2..1e8fcdc48aa 100644 --- a/src/plugins/qmldesigner/CMakeLists.txt +++ b/src/plugins/qmldesigner/CMakeLists.txt @@ -386,6 +386,7 @@ extend_qtc_plugin(QmlDesigner include/abstractproperty.h include/abstractview.h include/anchorline.h + include/annotation.h include/basetexteditmodifier.h include/bindingproperty.h include/bytearraymodifier.h @@ -475,6 +476,7 @@ extend_qtc_plugin(QmlDesigner model/abstractproperty.cpp model/abstractview.cpp model/anchorline.cpp + model/annotation.cpp model/basetexteditmodifier.cpp model/bindingproperty.cpp model/componenttextmodifier.cpp @@ -541,8 +543,7 @@ extend_qtc_plugin(QmlDesigner extend_qtc_plugin(QmlDesigner SOURCES_PREFIX components/annotationeditor - SOURCES annotation.cpp annotation.h - annotationcommenttab.cpp annotationcommenttab.h annotationcommenttab.ui + SOURCES annotationcommenttab.cpp annotationcommenttab.h annotationcommenttab.ui annotationeditordialog.cpp annotationeditordialog.h annotationeditordialog.ui annotationeditor.cpp annotationeditor.h annotationtool.cpp annotationtool.h diff --git a/src/plugins/qmldesigner/components/annotationeditor/annotationeditor.pri b/src/plugins/qmldesigner/components/annotationeditor/annotationeditor.pri index 3cc6c6f856b..e221b3bb615 100644 --- a/src/plugins/qmldesigner/components/annotationeditor/annotationeditor.pri +++ b/src/plugins/qmldesigner/components/annotationeditor/annotationeditor.pri @@ -1,10 +1,8 @@ -HEADERS += $$PWD/annotation.h HEADERS += $$PWD/annotationtool.h HEADERS += $$PWD/annotationcommenttab.h HEADERS += $$PWD/annotationeditordialog.h HEADERS += $$PWD/annotationeditor.h -SOURCES += $$PWD/annotation.cpp SOURCES += $$PWD/annotationtool.cpp SOURCES += $$PWD/annotationcommenttab.cpp SOURCES += $$PWD/annotationeditordialog.cpp diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorannotationicon.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorannotationicon.cpp index 367635d59f0..20e2a1dfe6c 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorannotationicon.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorannotationicon.cpp @@ -35,7 +35,6 @@ #include #include #include -#include #include #include diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorannotationicon.h b/src/plugins/qmldesigner/components/formeditor/formeditorannotationicon.h index c11ea5a3b77..4b8c804b2a5 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorannotationicon.h +++ b/src/plugins/qmldesigner/components/formeditor/formeditorannotationicon.h @@ -25,17 +25,13 @@ #pragma once -#include +#include +#include #include #include #include #include -#include - -QT_BEGIN_NAMESPACE -QT_END_NAMESPACE - namespace QmlDesigner { diff --git a/src/plugins/qmldesigner/components/formeditor/selectionindicator.cpp b/src/plugins/qmldesigner/components/formeditor/selectionindicator.cpp index f4af3f481f7..fd8ff4cd560 100644 --- a/src/plugins/qmldesigner/components/formeditor/selectionindicator.cpp +++ b/src/plugins/qmldesigner/components/formeditor/selectionindicator.cpp @@ -25,8 +25,8 @@ #include "selectionindicator.h" +#include "annotation.h" #include -#include "annotationeditor/annotation.h" #include #include diff --git a/src/plugins/qmldesigner/designercore/designercore-lib.pri b/src/plugins/qmldesigner/designercore/designercore-lib.pri index cb636bb70b7..5e99009cdb3 100644 --- a/src/plugins/qmldesigner/designercore/designercore-lib.pri +++ b/src/plugins/qmldesigner/designercore/designercore-lib.pri @@ -82,7 +82,8 @@ SOURCES += $$PWD/model/abstractview.cpp \ $$PWD/model/anchorline.cpp \ $$PWD/instances/puppetdialog.cpp \ $$PWD/model/qmltimeline.cpp \ - $$PWD/model/qmltimelinekeyframegroup.cpp + $$PWD/model/qmltimelinekeyframegroup.cpp \ + $$PWD/model/annotation.cpp HEADERS += $$PWD/include/qmldesignercorelib_global.h \ $$PWD/include/abstractview.h \ @@ -158,7 +159,8 @@ HEADERS += $$PWD/include/qmldesignercorelib_global.h \ $$PWD/include/anchorline.h \ $$PWD/instances/puppetdialog.h \ $$PWD/include/qmltimeline.h \ - $$PWD/include/qmltimelinekeyframegroup.h + $$PWD/include/qmltimelinekeyframegroup.h \ + $$PWD/include/annotation.h FORMS += \ $$PWD/instances/puppetdialog.ui diff --git a/src/plugins/qmldesigner/components/annotationeditor/annotation.h b/src/plugins/qmldesigner/designercore/include/annotation.h similarity index 100% rename from src/plugins/qmldesigner/components/annotationeditor/annotation.h rename to src/plugins/qmldesigner/designercore/include/annotation.h diff --git a/src/plugins/qmldesigner/components/annotationeditor/annotation.cpp b/src/plugins/qmldesigner/designercore/model/annotation.cpp similarity index 100% rename from src/plugins/qmldesigner/components/annotationeditor/annotation.cpp rename to src/plugins/qmldesigner/designercore/model/annotation.cpp diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp index 7a77044e13c..e8283c4b4c6 100644 --- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp @@ -41,7 +41,7 @@ #include "nodelistproperty.h" #include "nodeproperty.h" #include -#include "annotationeditor/annotation.h" +#include "annotation.h" #include diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs index 64644895ffd..477ebd83888 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.qbs +++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs @@ -246,6 +246,7 @@ Project { "include/abstractproperty.h", "include/abstractview.h", "include/anchorline.h", + "include/annotation.h", "include/basetexteditmodifier.h", "include/bindingproperty.h", "include/componenttextmodifier.h", @@ -322,6 +323,7 @@ Project { "model/abstractproperty.cpp", "model/abstractview.cpp", "model/anchorline.cpp", + "model/annotation.cpp", "model/basetexteditmodifier.cpp", "model/bindingproperty.cpp", "model/componenttextmodifier.cpp", @@ -639,8 +641,6 @@ Project { name: "extension" prefix: "components/" files: [ - "annotationeditor/annotation.cpp", - "annotationeditor/annotation.h", "annotationeditor/annotationcommenttab.cpp", "annotationeditor/annotationcommenttab.h", "annotationeditor/annotationcommenttab.ui", From 46e5d522383af67ed50efb60542a36d3f1cf4823 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Tue, 18 Feb 2020 11:31:25 +0100 Subject: [PATCH 08/13] Squish: Update addAndActivateKit Fixes warning in tst_opencreator_qbs Change-Id: I82ba025ebc6befd222dd8f47cabcff08ad2e584e Reviewed-by: Christian Stenger --- tests/system/shared/project_explorer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/shared/project_explorer.py b/tests/system/shared/project_explorer.py index ba022dcfed5..880b37a64d4 100644 --- a/tests/system/shared/project_explorer.py +++ b/tests/system/shared/project_explorer.py @@ -147,9 +147,9 @@ def invokeContextMenuOnProject(projectName, menuItem): return projItem def addAndActivateKit(kit): - clickToActivate = "

Click to activate:

" bAndRIndex = getQModelIndexStr("text='Build & Run'", ":Projects.ProjectNavigationTreeView") kitString = Targets.getStringForTarget(kit) + clickToActivate = "

%s

Click to activate

" % kitString switchViewTo(ViewConstants.PROJECTS) try: waitForObject(":Projects.ProjectNavigationTreeView") From 6e1032f23567cae32be94039f46a9e7f7f69de88 Mon Sep 17 00:00:00 2001 From: Denis Shienkov Date: Fri, 14 Feb 2020 17:36:01 +0300 Subject: [PATCH 09/13] BareMetal: Allow to choose 'tools.ini' for UVSC provider configuration An each Keil installation contains an own 'tools.ini' file. The "tools.ini" file is used to determine the paths to the installed debugger drivers as well as to the device software packs. These drivers and packs are displayed on a UVSC provide configuration widget and are used for debugging. Previously, a path to 'tools.ini' file was detected automatically from the configured Kit of the opened project, using the SessionManager::startupTarget() method (a Kit contains the debugger path, which is the uVision executable). But, in that case the user can't configure the UVSC provider if a project is not opened yet. This issue is solved by adding a path chooser to the UVSC provider configuration widget. That allows to user to choose the desired 'tools.ini' file instance in any time. Change-Id: Ife44d69704c9dd2102baecb0ff1954fa4bc05f1e Reviewed-by: hjk --- .../baremetal/debugservers/uvsc/uvproject.cpp | 22 --------- .../baremetal/debugservers/uvsc/uvproject.h | 5 --- .../debugservers/uvsc/uvscserverprovider.cpp | 45 ++++++++++++++++++- .../debugservers/uvsc/uvscserverprovider.h | 9 ++++ .../debugservers/uvsc/uvtargetdevicemodel.cpp | 13 +++--- .../debugservers/uvsc/uvtargetdevicemodel.h | 5 ++- .../uvsc/uvtargetdeviceviewer.cpp | 38 ++++++++-------- .../debugservers/uvsc/uvtargetdeviceviewer.h | 7 ++- .../debugservers/uvsc/uvtargetdrivermodel.cpp | 5 +-- .../debugservers/uvsc/uvtargetdrivermodel.h | 3 +- .../uvsc/uvtargetdriverviewer.cpp | 38 ++++++++-------- .../debugservers/uvsc/uvtargetdriverviewer.h | 8 +++- 12 files changed, 119 insertions(+), 79 deletions(-) diff --git a/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp b/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp index 2a516281acf..c37090c1658 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvproject.cpp @@ -49,28 +49,6 @@ namespace Uv { const char kProjectSchema[] = "2.1"; -// Helpers - -QString toolsFilePath(const QString &uVisionFilePath) -{ - const QFileInfo fi(uVisionFilePath); - QDir dir = fi.dir(); - if (!dir.cdUp()) - return {}; - return dir.absoluteFilePath("tools.ini"); -} - -QString targetUVisionPath() -{ - if (const Target *target = SessionManager::startupTarget()) { - if (const Kit *kit = target->kit()) { - const Runnable runnable = DebuggerKitAspect::runnable(kit); - return runnable.executable.toString(); - } - } - return {}; -} - static QString buildToolsetNumber(int number) { return QStringLiteral("0x%1").arg(QString::number(number, 16)); diff --git a/src/plugins/baremetal/debugservers/uvsc/uvproject.h b/src/plugins/baremetal/debugservers/uvsc/uvproject.h index a1ac9fe634e..6642cf6cc3c 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvproject.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvproject.h @@ -39,11 +39,6 @@ class UvscServerProvider; namespace Uv { -// Helpers - -QString toolsFilePath(const QString &uVisionFilePath); -QString targetUVisionPath(); - // UvProject class Project final : public Gen::Xml::Project diff --git a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp index cedb22b82d0..bee1f72bad1 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.cpp @@ -39,6 +39,7 @@ #include #include +#include #include #include @@ -57,6 +58,7 @@ namespace Internal { using namespace Uv; // Whole software package selection keys. +constexpr char toolsIniKeyC[] = "BareMetal.UvscServerProvider.ToolsIni"; constexpr char deviceSelectionKeyC[] = "BareMetal.UvscServerProvider.DeviceSelection"; constexpr char driverSelectionKeyC[] = "BareMetal.UvscServerProvider.DriverSelection"; @@ -78,6 +80,16 @@ UvscServerProvider::UvscServerProvider(const UvscServerProvider &other) setEngineType(UvscEngineType); } +void UvscServerProvider::setToolsIniFile(const Utils::FilePath &toolsIniFile) +{ + m_toolsIniFile = toolsIniFile; +} + +Utils::FilePath UvscServerProvider::toolsIniFile() const +{ + return m_toolsIniFile; +} + void UvscServerProvider::setDeviceSelection(const DeviceSelection &deviceSelection) { m_deviceSelection = deviceSelection; @@ -123,7 +135,8 @@ bool UvscServerProvider::operator==(const IDebugServerProvider &other) const if (!IDebugServerProvider::operator==(other)) return false; const auto p = static_cast(&other); - return m_deviceSelection == p->m_deviceSelection + return m_toolsIniFile == p->m_toolsIniFile + && m_deviceSelection == p->m_deviceSelection && m_driverSelection == p->m_driverSelection && m_toolsetNumber == p->m_toolsetNumber; } @@ -147,6 +160,7 @@ FilePath UvscServerProvider::buildOptionsFilePath(DebuggerRunTool *runTool) cons QVariantMap UvscServerProvider::toMap() const { QVariantMap data = IDebugServerProvider::toMap(); + data.insert(toolsIniKeyC, m_toolsIniFile.toVariant()); data.insert(deviceSelectionKeyC, m_deviceSelection.toMap()); data.insert(driverSelectionKeyC, m_driverSelection.toMap()); return data; @@ -217,6 +231,7 @@ bool UvscServerProvider::fromMap(const QVariantMap &data) { if (!IDebugServerProvider::fromMap(data)) return false; + m_toolsIniFile = FilePath::fromVariant(data.value(toolsIniKeyC)); m_deviceSelection.fromMap(data.value(deviceSelectionKeyC).toMap()); m_driverSelection.fromMap(data.value(driverSelectionKeyC).toMap()); return true; @@ -257,6 +272,11 @@ UvscServerProviderConfigWidget::UvscServerProviderConfigWidget(UvscServerProvide { m_hostWidget = new HostWidget; m_mainLayout->addRow(tr("Host:"), m_hostWidget); + m_toolsIniChooser = new PathChooser; + m_toolsIniChooser->setExpectedKind(PathChooser::File); + m_toolsIniChooser->setPromptDialogFilter("tools.ini"); + m_toolsIniChooser->setPromptDialogTitle(tr("Choose a Keil toolset configuration file")); + m_mainLayout->addRow(tr("Tools file path:"), m_toolsIniChooser); m_deviceSelector = new DeviceSelector; m_mainLayout->addRow(tr("Target device:"), m_deviceSelector); m_driverSelector = new DriverSelector(provider->supportedDrivers()); @@ -266,15 +286,27 @@ UvscServerProviderConfigWidget::UvscServerProviderConfigWidget(UvscServerProvide connect(m_hostWidget, &HostWidget::dataChanged, this, &UvscServerProviderConfigWidget::dirty); + connect(m_toolsIniChooser, &PathChooser::pathChanged, + this, &UvscServerProviderConfigWidget::dirty); connect(m_deviceSelector, &DeviceSelector::selectionChanged, this, &UvscServerProviderConfigWidget::dirty); connect(m_driverSelector, &DriverSelector::selectionChanged, this, &UvscServerProviderConfigWidget::dirty); + + auto updateSelectors = [this]() { + const FilePath toolsIniFile = m_toolsIniChooser->fileName(); + m_deviceSelector->setToolsIniFile(toolsIniFile); + m_driverSelector->setToolsIniFile(toolsIniFile); + }; + + connect(m_toolsIniChooser, &PathChooser::pathChanged, updateSelectors); + updateSelectors(); } void UvscServerProviderConfigWidget::apply() { const auto p = static_cast(m_provider); + p->setToolsIniFile(toolsIniFile()); p->setDeviceSelection(deviceSelection()); p->setDriverSelection(driverSelection()); IDebugServerProviderConfigWidget::apply(); @@ -286,6 +318,16 @@ void UvscServerProviderConfigWidget::discard() IDebugServerProviderConfigWidget::discard(); } +void UvscServerProviderConfigWidget::setToolsIniFile(const Utils::FilePath &toolsIniFile) +{ + m_toolsIniChooser->setFileName(toolsIniFile); +} + +Utils::FilePath UvscServerProviderConfigWidget::toolsIniFile() const +{ + return m_toolsIniChooser->fileName(); +} + void UvscServerProviderConfigWidget::setDeviceSelection(const DeviceSelection &deviceSelection) { m_deviceSelector->setSelection(deviceSelection); @@ -310,6 +352,7 @@ void UvscServerProviderConfigWidget::setFromProvider() { const auto p = static_cast(m_provider); m_hostWidget->setChannel(p->channel()); + m_toolsIniChooser->setFileName(p->toolsIniFile()); m_deviceSelector->setSelection(p->deviceSelection()); m_driverSelector->setSelection(p->driverSelection()); } diff --git a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.h b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.h index bab1a6c36d0..f4527f03a4e 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvscserverprovider.h @@ -32,6 +32,8 @@ #include // for RunWorker +namespace Utils { class PathChooser; } + namespace BareMetal { namespace Internal { @@ -54,6 +56,9 @@ public: ArmAdsToolsetNumber = 4 // ARM-ADS toolset }; + void setToolsIniFile(const Utils::FilePath &toolsIniFile); + Utils::FilePath toolsIniFile() const; + void setDeviceSelection(const Uv::DeviceSelection &deviceSelection); Uv::DeviceSelection deviceSelection() const; @@ -91,6 +96,7 @@ protected: virtual Utils::FilePath optionsFilePath(Debugger::DebuggerRunTool *runTool, QString &errorMessage) const = 0; + Utils::FilePath m_toolsIniFile; Uv::DeviceSelection m_deviceSelection; Uv::DriverSelection m_driverSelection; @@ -113,6 +119,8 @@ public: void discard() override; protected: + void setToolsIniFile(const Utils::FilePath &toolsIniFile); + Utils::FilePath toolsIniFile() const; void setDeviceSelection(const Uv::DeviceSelection &deviceSelection); Uv::DeviceSelection deviceSelection() const; void setDriverSelection(const Uv::DriverSelection &driverSelection); @@ -121,6 +129,7 @@ protected: void setFromProvider(); HostWidget *m_hostWidget = nullptr; + Utils::PathChooser *m_toolsIniChooser = nullptr; Uv::DeviceSelector *m_deviceSelector = nullptr; Uv::DriverSelector *m_driverSelector = nullptr; }; diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp index c6807b61095..391b0a4d158 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.cpp @@ -23,7 +23,6 @@ ** ****************************************************************************/ -#include "uvproject.h" // for toolsFilePath() #include "uvtargetdevicemodel.h" #include @@ -37,9 +36,9 @@ namespace BareMetal { namespace Internal { namespace Uv { -static QString extractPacksPath(const QString &uVisionFilePath) +static QString extractPacksPath(const FilePath &toolsIniFile) { - QFile f(toolsFilePath(uVisionFilePath)); + QFile f(toolsIniFile.toString()); if (!f.open(QIODevice::ReadOnly)) return {}; QTextStream in(&f); @@ -258,15 +257,15 @@ DeviceSelectionModel::DeviceSelectionModel(QObject *parent) setHeader({tr("Name"), tr("Version"), tr("Vendor")}); } -void DeviceSelectionModel::fillAllPacks(const QString &uVisionFilePath) +void DeviceSelectionModel::fillAllPacks(const FilePath &toolsIniFile) { - if (m_uVisionFilePath == uVisionFilePath) + if (m_toolsIniFile == toolsIniFile) return; clear(); - m_uVisionFilePath = uVisionFilePath; - const QString packsPath = extractPacksPath(m_uVisionFilePath); + m_toolsIniFile = toolsIniFile; + const QString packsPath = extractPacksPath(m_toolsIniFile); if (packsPath.isEmpty()) return; diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h index 3bd8e857019..c3a510f36e9 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdevicemodel.h @@ -28,6 +28,7 @@ #include "uvtargetdeviceselection.h" #include +#include #include QT_BEGIN_NAMESPACE @@ -47,7 +48,7 @@ class DeviceSelectionModel final : public Utils::TreeModel public: explicit DeviceSelectionModel(QObject *parent = nullptr); - void fillAllPacks(const QString &uVisionFilePath); + void fillAllPacks(const Utils::FilePath &toolsIniFile); private: void parsePackage(const QString &packageFile); @@ -59,7 +60,7 @@ private: DeviceSelection::Cpu &cpu, DeviceSelection::Memories &memories); void parseDeviceVariant(QXmlStreamReader &in, DeviceSelectionItem *parent); - QString m_uVisionFilePath; + Utils::FilePath m_toolsIniFile; }; // DeviceSelectionView diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp index 69cbd30129f..84436d3b651 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.cpp @@ -124,28 +124,30 @@ DeviceSelector::DeviceSelector(QWidget *parent) setWidget(detailsPanel); connect(toolPanel, &DeviceSelectorToolPanel::clicked, this, [this]() { - const QString uVisionPath = targetUVisionPath(); - if (uVisionPath.isEmpty()) { - QMessageBox::warning(this, - tr("uVision path not found"), - tr("Please open a configured project before\n" - "the target device selection."), - QMessageBox::Ok); - } else { - DeviceSelectionDialog dialog(uVisionPath, this); - const int result = dialog.exec(); - if (result != QDialog::Accepted) - return; - DeviceSelection selection; - selection = dialog.selection(); - setSelection(selection); - } + DeviceSelectionDialog dialog(m_toolsIniFile, this); + const int result = dialog.exec(); + if (result != QDialog::Accepted) + return; + DeviceSelection selection; + selection = dialog.selection(); + setSelection(selection); }); connect(detailsPanel, &DeviceSelectorDetailsPanel::selectionChanged, this, &DeviceSelector::selectionChanged); } +void DeviceSelector::setToolsIniFile(const Utils::FilePath &toolsIniFile) +{ + m_toolsIniFile = toolsIniFile; + setEnabled(m_toolsIniFile.exists()); +} + +Utils::FilePath DeviceSelector::toolsIniFile() const +{ + return m_toolsIniFile; +} + void DeviceSelector::setSelection(const DeviceSelection &selection) { m_selection = selection; @@ -167,7 +169,7 @@ DeviceSelection DeviceSelector::selection() const // DeviceSelectionDialog -DeviceSelectionDialog::DeviceSelectionDialog(const QString &uVisionPath, QWidget *parent) +DeviceSelectionDialog::DeviceSelectionDialog(const Utils::FilePath &toolsIniFile, QWidget *parent) : QDialog(parent), m_model(new DeviceSelectionModel(this)), m_view(new DeviceSelectionView(this)) { setWindowTitle(tr("Available target devices")); @@ -187,7 +189,7 @@ DeviceSelectionDialog::DeviceSelectionDialog(const QString &uVisionPath, QWidget m_selection = selection; }); - m_model->fillAllPacks(uVisionPath); + m_model->fillAllPacks(toolsIniFile); m_view->setModel(m_model); } diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.h index eaeb089e790..abc00e9c1c7 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdeviceviewer.h @@ -29,6 +29,7 @@ #include #include +#include #include @@ -55,6 +56,9 @@ class DeviceSelector final : public Utils::DetailsWidget public: explicit DeviceSelector(QWidget *parent = nullptr); + void setToolsIniFile(const Utils::FilePath &toolsIniFile); + Utils::FilePath toolsIniFile() const; + void setSelection(const DeviceSelection &selection); DeviceSelection selection() const; @@ -62,6 +66,7 @@ signals: void selectionChanged(); private: + Utils::FilePath m_toolsIniFile; DeviceSelection m_selection; }; @@ -111,7 +116,7 @@ class DeviceSelectionDialog final : public QDialog Q_OBJECT public: - explicit DeviceSelectionDialog(const QString &uVisionPath, QWidget *parent = nullptr); + explicit DeviceSelectionDialog(const Utils::FilePath &toolsIniFile, QWidget *parent = nullptr); DeviceSelection selection() const; private: diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.cpp index c3a737cbc8a..11199aca526 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.cpp @@ -23,7 +23,6 @@ ** ****************************************************************************/ -#include "uvproject.h" // for toolsFilePath() #include "uvtargetdrivermodel.h" #include @@ -132,12 +131,12 @@ DriverSelectionModel::DriverSelectionModel(QObject *parent) setHeader({tr("Path")}); } -void DriverSelectionModel::fillDrivers(const QString &uVisionFilePath, +void DriverSelectionModel::fillDrivers(const FilePath &toolsIniFile, const QStringList &supportedDrivers) { clear(); - QFile f(toolsFilePath(uVisionFilePath)); + QFile f(toolsIniFile.toString()); if (!f.open(QIODevice::ReadOnly)) return; diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.h index 845681d0c1a..9d9dda37890 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdrivermodel.h @@ -28,6 +28,7 @@ #include "uvtargetdriverselection.h" #include +#include #include namespace BareMetal { @@ -43,7 +44,7 @@ class DriverSelectionModel final : public Utils::TreeModel public: explicit DriverSelectionModel(QObject *parent = nullptr); - void fillDrivers(const QString &uVisionFilePath, const QStringList &supportedDrivers); + void fillDrivers(const Utils::FilePath &toolsIniFile, const QStringList &supportedDrivers); }; // DriverSelectionView diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.cpp b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.cpp index 04e6721e566..10baa3b2741 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.cpp +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.cpp @@ -105,28 +105,30 @@ DriverSelector::DriverSelector(const QStringList &supportedDrivers, QWidget *par setWidget(detailsPanel); connect(toolPanel, &DriverSelectorToolPanel::clicked, this, [=]() { - const QString uVisionPath = targetUVisionPath(); - if (uVisionPath.isEmpty()) { - QMessageBox::warning(this, - tr("uVision path not found"), - tr("Please open a configured project before\n" - "the target driver selection."), - QMessageBox::Ok); - } else { - DriverSelectionDialog dialog(uVisionPath, supportedDrivers, this); - const int result = dialog.exec(); - if (result != QDialog::Accepted) - return; - DriverSelection selection; - selection = dialog.selection(); - setSelection(selection); - } + DriverSelectionDialog dialog(m_toolsIniFile, supportedDrivers, this); + const int result = dialog.exec(); + if (result != QDialog::Accepted) + return; + DriverSelection selection; + selection = dialog.selection(); + setSelection(selection); }); connect(detailsPanel, &DriverSelectorDetailsPanel::selectionChanged, this, &DriverSelector::selectionChanged); } +void DriverSelector::setToolsIniFile(const Utils::FilePath &toolsIniFile) +{ + m_toolsIniFile = toolsIniFile; + setEnabled(m_toolsIniFile.exists()); +} + +Utils::FilePath DriverSelector::toolsIniFile() const +{ + return m_toolsIniFile; +} + void DriverSelector::setSelection(const DriverSelection &selection) { m_selection = selection; @@ -148,7 +150,7 @@ DriverSelection DriverSelector::selection() const // DriverSelectionDialog -DriverSelectionDialog::DriverSelectionDialog(const QString &uVisionPath, +DriverSelectionDialog::DriverSelectionDialog(const Utils::FilePath &toolsIniFile, const QStringList &supportedDrivers, QWidget *parent) : QDialog(parent), m_model(new DriverSelectionModel(this)), @@ -171,7 +173,7 @@ DriverSelectionDialog::DriverSelectionDialog(const QString &uVisionPath, m_selection = selection; }); - m_model->fillDrivers(uVisionPath, supportedDrivers); + m_model->fillDrivers(toolsIniFile, supportedDrivers); m_view->setModel(m_model); } diff --git a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.h b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.h index a72d3baf69f..c8c390318ce 100644 --- a/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.h +++ b/src/plugins/baremetal/debugservers/uvsc/uvtargetdriverviewer.h @@ -29,6 +29,7 @@ #include #include +#include #include @@ -52,6 +53,10 @@ class DriverSelector final : public Utils::DetailsWidget public: explicit DriverSelector(const QStringList &supportedDrivers, QWidget *parent = nullptr); + + void setToolsIniFile(const Utils::FilePath &toolsIniFile); + Utils::FilePath toolsIniFile() const; + void setSelection(const DriverSelection &selection); DriverSelection selection() const; @@ -59,6 +64,7 @@ signals: void selectionChanged(); private: + Utils::FilePath m_toolsIniFile; DriverSelection m_selection; }; @@ -105,7 +111,7 @@ class DriverSelectionDialog final : public QDialog Q_OBJECT public: - explicit DriverSelectionDialog(const QString &uVisionPath, + explicit DriverSelectionDialog(const Utils::FilePath &toolsIniFile, const QStringList &supportedDrivers, QWidget *parent = nullptr); DriverSelection selection() const; From 3e9437d8c55505f9a70bb8dcafbe93118136f330 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Mon, 17 Feb 2020 18:15:19 +0100 Subject: [PATCH 10/13] Squish: Update chooseTargets() Fixes tst_cmake_speedcrunch Change-Id: I154647ca2108676b4184170ef121649547c3fd41 Reviewed-by: Christian Stenger --- tests/system/shared/project.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/shared/project.py b/tests/system/shared/project.py index 48656c38dc8..39cdda43518 100644 --- a/tests/system/shared/project.py +++ b/tests/system/shared/project.py @@ -419,7 +419,7 @@ def __chooseTargets__(targets, availableTargets=None, additionalFunc=None): if additionalFunc: detailsWidget = waitForObject("{type='Utils::DetailsWidget' unnamed='1' " "window=':Qt Creator_Core::Internal::MainWindow' " - "toolTip?='

%s

*' visible='1'}" + "summaryText='%s' visible='1'}" % Targets.getStringForTarget(current)) detailsButton = getChildByClass(detailsWidget, "Utils::DetailsButton") clickButton(detailsButton) From 0b6386d1f8f1353f8812837715558679124565f6 Mon Sep 17 00:00:00 2001 From: Robert Loehning Date: Mon, 17 Feb 2020 19:11:03 +0100 Subject: [PATCH 11/13] Squish: Update QtOptionsPageWidget Fixes error in tst_default_settings Change-Id: I927edb0cab7c73a4830272cf6fb2f655cee4cd8d Reviewed-by: Christian Stenger --- tests/system/objects.map | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system/objects.map b/tests/system/objects.map index 1cc9fc2fd61..1144af6ce21 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -210,7 +210,7 @@ :qdesigner_internal::WidgetBoxCategoryListView {container=':Widget Box_qdesigner_internal::WidgetBoxTreeWidget' occurrence='3' type='qdesigner_internal::WidgetBoxCategoryListView' unnamed='1' visible='1'} :qmakeCallEdit {container=':Qt Creator.scrollArea_QScrollArea' text?='qmake: qmake*' type='QLabel' unnamed='1' visible='1'} :qt_tabwidget_stackedwidget.Core__Internal__GeneralSettings_QWidget {container=':Options.qt_tabwidget_stackedwidget_QStackedWidget' name='Core__Internal__GeneralSettings' type='QWidget' visible='1'} -:qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget {container=':Options.qt_tabwidget_stackedwidget_QStackedWidget' name='QtSupport__Internal__QtVersionManager' type='QtSupport::Internal::QtOptionsPageWidget' visible='1'} +:qt_tabwidget_stackedwidget.QtSupport__Internal__QtVersionManager_QtSupport::Internal::QtOptionsPageWidget {container=':Options.qt_tabwidget_stackedwidget_QStackedWidget' type='QScrollArea' unnamed='1' visible='1'} :qt_tabwidget_stackedwidget_QScrollArea {container=':Options.qt_tabwidget_stackedwidget_QStackedWidget' type='QScrollArea' unnamed='1' visible='1'} :qt_tabwidget_stackedwidget_QWidget {container=':Options.qt_tabwidget_stackedwidget_QStackedWidget' type='QWidget' unnamed='1' visible='1'} :qtdirList_QTreeView {container=':qt_tabwidget_stackedwidget_QScrollArea' name='qtdirList' type='QTreeView' visible='1'} From 5bb6c7f0cfbb2c67cfd6a2f09e152f54cdc90dda Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Tue, 18 Feb 2020 15:55:19 +0100 Subject: [PATCH 12/13] ProjectExplorer: Call RunConfiguration::update() when restoring Otherwise, the executable path will not be set right after cloning a run configuration. This is due to the fact that it's not a stored attribute, but is retrieved from the build system. Change-Id: I948a2765b5b5d7707b44a72fcde7559e2742284c Reviewed-by: hjk --- src/plugins/projectexplorer/runconfiguration.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/plugins/projectexplorer/runconfiguration.cpp b/src/plugins/projectexplorer/runconfiguration.cpp index 5eaf0b19567..03c908a8596 100644 --- a/src/plugins/projectexplorer/runconfiguration.cpp +++ b/src/plugins/projectexplorer/runconfiguration.cpp @@ -561,8 +561,10 @@ RunConfiguration *RunConfigurationFactory::restore(Target *parent, const QVarian const Core::Id id = idFromMap(map); if (id.name().startsWith(factory->m_runConfigBaseId.name())) { RunConfiguration *rc = factory->create(parent); - if (rc->fromMap(map)) + if (rc->fromMap(map)) { + rc->update(); return rc; + } delete rc; return nullptr; } From 937e2b56e7ef63ff55d0c34a4461a795871c330e Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Tue, 18 Feb 2020 01:35:26 +0100 Subject: [PATCH 13/13] VcsOutputFormatter: Fix multiple regexp matches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: QTCREATORBUG-23614 Change-Id: I86e548a1f727113782afbc6b934d6dddc92c92ea Reviewed-by: Orgad Shaneh Reviewed-by: André Hartmann --- src/plugins/vcsbase/vcsoutputformatter.cpp | 37 +++++++++------------- src/plugins/vcsbase/vcsoutputformatter.h | 3 +- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/plugins/vcsbase/vcsoutputformatter.cpp b/src/plugins/vcsbase/vcsoutputformatter.cpp index 2b0aa920295..4b09ed06eb7 100644 --- a/src/plugins/vcsbase/vcsoutputformatter.cpp +++ b/src/plugins/vcsbase/vcsoutputformatter.cpp @@ -31,40 +31,33 @@ namespace VcsBase { VcsOutputFormatter::VcsOutputFormatter() : - m_urlRegexp("https?://\\S*"), - m_referenceRegexp("(v[0-9]+\\.[0-9]+\\.[0-9]+[\\-A-Za-z0-9]*)" // v0.1.2-beta3 - "|([0-9a-f]{6,}(?:\\.\\.[0-9a-f]{6,})?)") // 789acf or 123abc..456cde + m_regexp( + "(https?://\\S*)" // https://codereview.org/c/1234 + "|(v[0-9]+\\.[0-9]+\\.[0-9]+[\\-A-Za-z0-9]*)" // v0.1.2-beta3 + "|([0-9a-f]{6,}(?:\\.\\.[0-9a-f]{6,})?)") // 789acf or 123abc..456cde { } void VcsOutputFormatter::appendMessage(const QString &text, Utils::OutputFormat format) { - const QRegularExpressionMatch urlMatch = m_urlRegexp.match(text); - const QRegularExpressionMatch referenceMatch = m_referenceRegexp.match(text); - - auto append = [this](const QRegularExpressionMatch &match, - QString text, Utils::OutputFormat format) { + QRegularExpressionMatchIterator it = m_regexp.globalMatch(text); + int begin = 0; + while (it.hasNext()) { + const QRegularExpressionMatch match = it.next(); const QTextCharFormat normalFormat = charFormat(format); - OutputFormatter::appendMessage(text.left(match.capturedStart()), format); + OutputFormatter::appendMessage(text.mid(begin, match.capturedStart() - begin), format); QTextCursor tc = plainTextEdit()->textCursor(); QStringView url = match.capturedView(); - int end = match.capturedEnd(); + begin = match.capturedEnd(); while (url.rbegin()->isPunct()) { url.chop(1); - --end; + --begin; } - tc.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); + tc.movePosition(QTextCursor::End); tc.insertText(url.toString(), linkFormat(normalFormat, url.toString())); - tc.movePosition(QTextCursor::End, QTextCursor::MoveAnchor); - OutputFormatter::appendMessage(text.mid(end), format); - }; - - if (urlMatch.hasMatch()) - append(urlMatch, text, format); - else if (referenceMatch.hasMatch()) - append(referenceMatch, text, format); - else - OutputFormatter::appendMessage(text, format); + tc.movePosition(QTextCursor::End); + } + OutputFormatter::appendMessage(text.mid(begin), format); } void VcsOutputFormatter::handleLink(const QString &href) diff --git a/src/plugins/vcsbase/vcsoutputformatter.h b/src/plugins/vcsbase/vcsoutputformatter.h index d1c99b0087f..d1d508b895f 100644 --- a/src/plugins/vcsbase/vcsoutputformatter.h +++ b/src/plugins/vcsbase/vcsoutputformatter.h @@ -42,8 +42,7 @@ signals: void referenceClicked(const QString &reference); private: - const QRegularExpression m_urlRegexp; - const QRegularExpression m_referenceRegexp; + const QRegularExpression m_regexp; }; }