diff --git a/cmake/QtCreatorAPI.cmake b/cmake/QtCreatorAPI.cmake index ed3602e6d6d..fafa5180e74 100644 --- a/cmake/QtCreatorAPI.cmake +++ b/cmake/QtCreatorAPI.cmake @@ -241,6 +241,7 @@ function(add_qtc_library name) qtc_output_binary_dir(_output_binary_dir) string(REGEX MATCH "^[0-9]*" IDE_VERSION_MAJOR ${IDE_VERSION}) set_target_properties(${name} PROPERTIES + LINK_DEPENDS_NO_SHARED ON SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}" VERSION "${IDE_VERSION}" SOVERSION "${IDE_VERSION_MAJOR}" @@ -497,6 +498,7 @@ function(add_qtc_plugin target_name) qtc_output_binary_dir(_output_binary_dir) set_target_properties(${target_name} PROPERTIES + LINK_DEPENDS_NO_SHARED ON SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}" MACHO_CURRENT_VERSION ${IDE_VERSION} MACHO_COMPATIBILITY_VERSION ${IDE_VERSION_COMPAT} @@ -694,6 +696,7 @@ function(add_qtc_executable name) qtc_output_binary_dir(_output_binary_dir) set_target_properties("${name}" PROPERTIES + LINK_DEPENDS_NO_SHARED ON BUILD_RPATH "${build_rpath}" INSTALL_RPATH "${install_rpath}" RUNTIME_OUTPUT_DIRECTORY "${_output_binary_dir}/${_DESTINATION}" @@ -844,6 +847,7 @@ function(add_qtc_test name) ) set_target_properties(${name} PROPERTIES + LINK_DEPENDS_NO_SHARED ON CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON BUILD_RPATH "${_RPATH_BASE}/${_RPATH}" diff --git a/cmake/QtCreatorIDEBranding.cmake b/cmake/QtCreatorIDEBranding.cmake index 13e5bde1b28..626a7230185 100644 --- a/cmake/QtCreatorIDEBranding.cmake +++ b/cmake/QtCreatorIDEBranding.cmake @@ -4,7 +4,6 @@ set(IDE_VERSION_DISPLAY "6.0.0-beta1") # The IDE display version. set(IDE_COPYRIGHT_YEAR "2021") # The IDE current copyright year. set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation. -set(IDE_COPY_SETTINGSVARIANT "Nokia") # The IDE settings to initially import. set(IDE_DISPLAY_NAME "Qt Creator") # The IDE display name. set(IDE_ID "qtcreator") # The IDE id (no spaces, lowercase!) set(IDE_CASED_ID "QtCreator") # The cased IDE id (no spaces!) diff --git a/doc/qtcreator/images/qtcreator-font-colors.png b/doc/qtcreator/images/qtcreator-font-colors.png index ef6653319bf..8dfb7451e5a 100644 Binary files a/doc/qtcreator/images/qtcreator-font-colors.png and b/doc/qtcreator/images/qtcreator-font-colors.png differ diff --git a/src/app/app_version.h.cmakein b/src/app/app_version.h.cmakein index 49abfc4ec88..453ab5875aa 100644 --- a/src/app/app_version.h.cmakein +++ b/src/app/app_version.h.cmakein @@ -49,7 +49,6 @@ const char IDE_REVISION_URL[] = "${IDE_REVISION_URL}"; // changes the path where the settings are saved to const char IDE_SETTINGSVARIANT_STR[] = "${IDE_SETTINGSVARIANT}"; -const char IDE_COPY_SETTINGS_FROM_VARIANT_STR[] = "${IDE_COPY_SETTINGSVARIANT}"; } // Constants } // Core diff --git a/src/app/app_version.h.in b/src/app/app_version.h.in index 7a525bf211f..7c24e9eb9ec 100644 --- a/src/app/app_version.h.in +++ b/src/app/app_version.h.in @@ -65,12 +65,6 @@ const char IDE_SETTINGSVARIANT_STR[] = STRINGIFY(IDE_SETTINGSVARIANT); const char IDE_SETTINGSVARIANT_STR[] = \"QtProject\"; #endif -#ifdef IDE_COPY_SETTINGS_FROM_VARIANT -const char IDE_COPY_SETTINGS_FROM_VARIANT_STR[] = STRINGIFY(IDE_COPY_SETTINGS_FROM_VARIANT); -#else -const char IDE_COPY_SETTINGS_FROM_VARIANT_STR[] = \"\"; -#endif - #undef IDE_VERSION_COMPAT_DEF #undef IDE_VERSION_DISPLAY_DEF #undef IDE_VERSION diff --git a/src/app/main.cpp b/src/app/main.cpp index 77c08cbd088..418f2f7ada6 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -290,49 +290,6 @@ static Utils::QtcSettings *createUserSettings() QLatin1String(Core::Constants::IDE_CASED_ID)); } -static inline Utils::QtcSettings *userSettings() -{ - Utils::QtcSettings *settings = createUserSettings(); - const QString fromVariant = QLatin1String(Core::Constants::IDE_COPY_SETTINGS_FROM_VARIANT_STR); - if (fromVariant.isEmpty()) - return settings; - - // Copy old settings to new ones: - QFileInfo pathFi = QFileInfo(settings->fileName()); - if (pathFi.exists()) // already copied. - return settings; - - QDir destDir = pathFi.absolutePath(); - if (!destDir.exists()) - destDir.mkpath(pathFi.absolutePath()); - - QDir srcDir = destDir; - srcDir.cdUp(); - if (!srcDir.cd(fromVariant)) - return settings; - - if (srcDir == destDir) // Nothing to copy and no settings yet - return settings; - - const QStringList entries = srcDir.entryList(); - for (const QString &file : entries) { - const QString lowerFile = file.toLower(); - if (lowerFile.startsWith(QLatin1String("profiles.xml")) - || lowerFile.startsWith(QLatin1String("toolchains.xml")) - || lowerFile.startsWith(QLatin1String("qtversion.xml")) - || lowerFile.startsWith(QLatin1String("devices.xml")) - || lowerFile.startsWith(QLatin1String("debuggers.xml")) - || lowerFile.startsWith(QLatin1String(Core::Constants::IDE_ID) + ".")) - QFile::copy(srcDir.absoluteFilePath(file), destDir.absoluteFilePath(file)); - if (file == QLatin1String(Core::Constants::IDE_ID)) - copyRecursively(srcDir.absoluteFilePath(file), destDir.absoluteFilePath(file)); - } - - // Make sure to use the copied settings: - delete settings; - return createUserSettings(); -} - static void setHighDpiEnvironmentVariable() { @@ -595,7 +552,7 @@ int main(int argc, char **argv) /*Initialize global settings and resetup install settings with QApplication::applicationDirPath */ setupInstallSettings(options.installSettingsPath); - Utils::QtcSettings *settings = userSettings(); + Utils::QtcSettings *settings = createUserSettings(); Utils::QtcSettings *globalSettings = new Utils::QtcSettings(QSettings::IniFormat, QSettings::SystemScope, diff --git a/src/libs/utils/commandline.cpp b/src/libs/utils/commandline.cpp index 3ae7984275f..da44b02e089 100644 --- a/src/libs/utils/commandline.cpp +++ b/src/libs/utils/commandline.cpp @@ -1089,13 +1089,6 @@ bool ProcessArgs::expandMacros(QString *cmd, AbstractMacroExpander *mx, OsType o return true; } -QString ProcessArgs::expandMacros(const QString &str, AbstractMacroExpander *mx, OsType osType) -{ - QString ret = str; - expandMacros(&ret, mx, osType); - return ret; -} - bool ProcessArgs::ArgIterator::next() { // We delay the setting of m_prev so we can still delete the last argument diff --git a/src/libs/utils/commandline.h b/src/libs/utils/commandline.h index 473c2677206..a2a43a82e16 100644 --- a/src/libs/utils/commandline.h +++ b/src/libs/utils/commandline.h @@ -81,8 +81,6 @@ public: //! Safely replace the expandos in a shell command static bool expandMacros(QString *cmd, AbstractMacroExpander *mx, OsType osType = HostOsInfo::hostOs()); - static QString expandMacros(const QString &str, AbstractMacroExpander *mx, - OsType osType = HostOsInfo::hostOs()); /*! Iterate over arguments from a command line. * Assumes that the name of the actual command is *not* part of the line. diff --git a/src/libs/utils/macroexpander.cpp b/src/libs/utils/macroexpander.cpp index 5e203762132..5cf279660ed 100644 --- a/src/libs/utils/macroexpander.cpp +++ b/src/libs/utils/macroexpander.cpp @@ -35,11 +35,14 @@ #include #include #include +#include #include namespace Utils { namespace Internal { +static Q_LOGGING_CATEGORY(expanderLog, "qtc.utils.macroexpander", QtWarningMsg) + const char kFilePathPostfix[] = ":FilePath"; const char kPathPostfix[] = ":Path"; const char kNativeFilePathPostfix[] = ":NativeFilePath"; @@ -327,7 +330,10 @@ QVariant MacroExpander::expandVariant(const QVariant &v) const QString MacroExpander::expandProcessArgs(const QString &argsWithVariables) const { - return ProcessArgs::expandMacros(argsWithVariables, d); + QString result = argsWithVariables; + const bool ok = ProcessArgs::expandMacros(&result, d); + QTC_ASSERT(ok, qCDebug(expanderLog) << "Expanding failed: " << argsWithVariables); + return result; } static QByteArray fullPrefix(const QByteArray &prefix) diff --git a/src/libs/utils/persistentsettings.cpp b/src/libs/utils/persistentsettings.cpp index eda01977de0..4cebb43c7ca 100644 --- a/src/libs/utils/persistentsettings.cpp +++ b/src/libs/utils/persistentsettings.cpp @@ -427,11 +427,6 @@ PersistentSettingsWriter::PersistentSettingsWriter(const FilePath &fileName, con m_fileName(fileName), m_docType(docType) { } -PersistentSettingsWriter::~PersistentSettingsWriter() -{ - write(m_savedData, nullptr); -} - bool PersistentSettingsWriter::save(const QVariantMap &data, QString *errorString) const { if (data == m_savedData) diff --git a/src/libs/utils/persistentsettings.h b/src/libs/utils/persistentsettings.h index 92dbf0d8c98..20802ea2630 100644 --- a/src/libs/utils/persistentsettings.h +++ b/src/libs/utils/persistentsettings.h @@ -52,7 +52,6 @@ class QTCREATOR_UTILS_EXPORT PersistentSettingsWriter { public: PersistentSettingsWriter(const FilePath &fileName, const QString &docType); - ~PersistentSettingsWriter(); bool save(const QVariantMap &data, QString *errorString) const; #ifdef QT_GUI_LIB diff --git a/src/plugins/clangformat/clangformatbaseindenter.cpp b/src/plugins/clangformat/clangformatbaseindenter.cpp index 4a595dd4116..fa95514ca32 100644 --- a/src/plugins/clangformat/clangformatbaseindenter.cpp +++ b/src/plugins/clangformat/clangformatbaseindenter.cpp @@ -92,6 +92,11 @@ clang::tooling::Replacements filteredReplacements(const QByteArray &buffer, llvm::StringRef text = replacementsToKeep == ReplacementsToKeep::OnlyIndent ? clearExtraNewline(replacement.getReplacementText()) : replacement.getReplacementText(); + if (replacementsToKeep == ReplacementsToKeep::OnlyIndent && int(text.count('\n')) + != buffer.mid(replacementOffset, replacement.getLength()).count('\n')) { + continue; + } + llvm::Error error = filtered.add( clang::tooling::Replacement(replacement.getFilePath(), @@ -295,8 +300,8 @@ int forceIndentWithExtraText(QByteArray &buffer, if (block.previous().isValid()) { const int prevEndOffset = Utils::Text::utf8NthLineOffset(block.document(), buffer, block.blockNumber()) + block.previous().text().length(); - buffer.insert(prevEndOffset, "//"); - extraLength += 2; + buffer.insert(prevEndOffset, " //"); + extraLength += 3; } } buffer.insert(utf8Offset + extraLength, dummyText); diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp index 26950d285fe..b2a7af5c985 100644 --- a/src/plugins/docker/dockerdevice.cpp +++ b/src/plugins/docker/dockerdevice.cpp @@ -232,6 +232,49 @@ class DockerPortsGatheringMethod : public PortsGatheringMethod } }; +class KitDetectorPrivate +{ + Q_DECLARE_TR_FUNCTIONS(ProjectExplorer::KitItemDetector) + +public: + KitDetectorPrivate(KitDetector *parent, const IDevice::ConstPtr &device) + : q(parent), m_device(device) + {} + + void autoDetect(); + void undoAutoDetect() const; + + QList autoDetectQtVersions() const; + QList autoDetectToolChains(); + void autoDetectCMake(); + void autoDetectDebugger(); + + KitDetector *q; + IDevice::ConstPtr m_device; + QString m_sharedId; +}; + +KitDetector::KitDetector(const IDevice::ConstPtr &device) + : d(new KitDetectorPrivate(this, device)) +{} + +KitDetector::~KitDetector() +{ + delete d; +} + +void KitDetector::autoDetect(const QString &sharedId) const +{ + d->m_sharedId = sharedId; + d->autoDetect(); +} + +void KitDetector::undoAutoDetect(const QString &sharedId) const +{ + d->m_sharedId = sharedId; + d->undoAutoDetect(); +} + class DockerDevicePrivate : public QObject { Q_DECLARE_TR_FUNCTIONS(Docker::Internal::DockerDevice) @@ -255,14 +298,6 @@ public: void tryCreateLocalFileAccess(); - void autoDetect(QTextBrowser *log); - void undoAutoDetect(QTextBrowser *log) const; - - QList autoDetectQtVersions(QTextBrowser *log) const; - QList autoDetectToolChains(QTextBrowser *log); - void autoDetectCMake(QTextBrowser *log); - void autoDetectDebugger(QTextBrowser *log); - void fetchSystemEnviroment(); DockerDevice *q; @@ -283,54 +318,59 @@ class DockerDeviceWidget final : public IDeviceWidget public: explicit DockerDeviceWidget(const IDevice::Ptr &device) - : IDeviceWidget(device) + : IDeviceWidget(device), m_kitItemDetector(device) { auto dockerDevice = device.dynamicCast(); QTC_ASSERT(dockerDevice, return); - auto idLabel = new QLabel(tr("Image ID:")); + DockerDeviceData &data = dockerDevice->data(); + + auto idLabel = new QLabel(tr("Image Id:")); m_idLineEdit = new QLineEdit; - m_idLineEdit->setText(dockerDevice->data().imageId); + m_idLineEdit->setText(data.imageId); m_idLineEdit->setEnabled(false); auto repoLabel = new QLabel(tr("Repository:")); m_repoLineEdit = new QLineEdit; - m_repoLineEdit->setText(dockerDevice->data().repo); + m_repoLineEdit->setText(data.repo); m_repoLineEdit->setEnabled(false); m_runAsOutsideUser = new QCheckBox(tr("Run as outside user")); m_runAsOutsideUser->setToolTip(tr("Use user ID and group ID of the user running Qt Creator " "in the Docker container.")); - m_runAsOutsideUser->setChecked(dockerDevice->data().useLocalUidGid); + m_runAsOutsideUser->setChecked(data.useLocalUidGid); m_runAsOutsideUser->setEnabled(HostOsInfo::isLinuxHost()); - connect(m_runAsOutsideUser, &QCheckBox::toggled, this, [dockerDevice](bool on) { - dockerDevice->data().useLocalUidGid = on; + connect(m_runAsOutsideUser, &QCheckBox::toggled, this, [&data](bool on) { + data.useLocalUidGid = on; }); m_pathsLineEdit = new QLineEdit; - m_pathsLineEdit->setText(dockerDevice->data().repo); + m_pathsLineEdit->setText(data.repo); m_pathsLineEdit->setToolTip(tr("Paths in this semi-colon separated list will be " "mapped one-to-one into the Docker container.")); - m_pathsLineEdit->setText(dockerDevice->data().mounts.join(';')); + m_pathsLineEdit->setText(data.mounts.join(';')); - connect(m_pathsLineEdit, &QLineEdit::textChanged, this, [dockerDevice](const QString &text) { - dockerDevice->data().mounts = text.split(';'); + connect(m_pathsLineEdit, &QLineEdit::textChanged, this, [&data](const QString &text) { + data.mounts = text.split(';'); }); auto logView = new QTextBrowser; + connect(&m_kitItemDetector, &KitDetector::logOutput, + logView, &QTextBrowser::append); auto autoDetectButton = new QPushButton(tr("Auto-detect Kit Items")); auto undoAutoDetectButton = new QPushButton(tr("Remove Auto-Detected Kit Items")); - connect(autoDetectButton, &QPushButton::clicked, this, [logView, dockerDevice] { + connect(autoDetectButton, &QPushButton::clicked, this, [this, logView, id = data.id(), dockerDevice] { logView->clear(); - dockerDevice->d->autoDetect(logView); + dockerDevice->tryCreateLocalFileAccess(); + m_kitItemDetector.autoDetect(id); }); - connect(undoAutoDetectButton, &QPushButton::clicked, this, [logView, dockerDevice] { + connect(undoAutoDetectButton, &QPushButton::clicked, this, [this, logView, id = data.id()] { logView->clear(); - dockerDevice->d->undoAutoDetect(logView); + m_kitItemDetector.undoAutoDetect(id); }); using namespace Layouting; @@ -356,6 +396,8 @@ private: QLineEdit *m_repoLineEdit; QCheckBox *m_runAsOutsideUser; QLineEdit *m_pathsLineEdit; + + KitDetector m_kitItemDetector; }; IDeviceWidget *DockerDevice::createWidget() @@ -424,146 +466,132 @@ DockerDeviceData &DockerDevice::data() return d->m_data; } -void DockerDevicePrivate::undoAutoDetect(QTextBrowser *log) const +void KitDetectorPrivate::undoAutoDetect() const { - const QString id = q->id().toString(); - for (Kit *kit : KitManager::kits()) { - if (kit->autoDetectionSource() == id) { - if (log) - log->append(tr("Removing kit: %1").arg(kit->displayName())); + if (kit->autoDetectionSource() == m_sharedId) { + emit q->logOutput(tr("Removing kit: %1").arg(kit->displayName())); KitManager::deregisterKit(kit); } }; for (BaseQtVersion *qtVersion : QtVersionManager::versions()) { - if (qtVersion->autodetectionSource() == id) { - if (log) - log->append(tr("Removing Qt version: %1").arg(qtVersion->displayName())); + if (qtVersion->autodetectionSource() == m_sharedId) { + emit q->logOutput(tr("Removing Qt version: %1").arg(qtVersion->displayName())); QtVersionManager::removeVersion(qtVersion); } }; - if (log) - log->append(tr("Tool chains not removed.")); + emit q->logOutput(tr("Tool chains not removed.")); // for (ToolChain *toolChain : ToolChainManager::toolChains()) { // if (toolChain->autoDetectionSource() == id.toString()) // // FIXME: Implement // }; - if (log) - log->append(tr("Removal of previously auto-detected kit items finished.") + '\n'); + emit q->logOutput(tr("Removal of previously auto-detected kit items finished.") + '\n'); } -QList DockerDevicePrivate::autoDetectQtVersions(QTextBrowser *log) const +QList KitDetectorPrivate::autoDetectQtVersions() const { QList qtVersions; QString error; const QStringList candidates = {"qmake-qt6", "qmake-qt5", "qmake"}; - if (log) - log->append('\n' + tr("Searching Qt installations...")); + emit q->logOutput('\n' + tr("Searching Qt installations...")); for (const QString &candidate : candidates) { - if (log) - log->append(tr("Searching for %1 executable...").arg(candidate)); - const FilePath qmake = q->searchInPath(FilePath::fromString(candidate)); + emit q->logOutput(tr("Searching for %1 executable...").arg(candidate)); + const FilePath qmake = m_device->searchInPath(FilePath::fromString(candidate)); if (qmake.isEmpty()) continue; - BaseQtVersion *qtVersion = QtVersionFactory::createQtVersionFromQMakePath(qmake, false, m_data.id(), &error); + BaseQtVersion *qtVersion = QtVersionFactory::createQtVersionFromQMakePath(qmake, false, m_sharedId, &error); if (!qtVersion) continue; qtVersions.append(qtVersion); QtVersionManager::addVersion(qtVersion); - if (log) - log->append(tr("Found Qt: %1").arg(qtVersion->qmakeCommand().toUserOutput())); + emit q->logOutput(tr("Found Qt: %1").arg(qtVersion->qmakeCommand().toUserOutput())); } - if (qtVersions.isEmpty() && log) - log->append(tr("No Qt installation found.")); + if (qtVersions.isEmpty()) + emit q->logOutput(tr("No Qt installation found.")); return qtVersions; } -QList DockerDevicePrivate::autoDetectToolChains(QTextBrowser *log) +QList KitDetectorPrivate::autoDetectToolChains() { const QList factories = ToolChainFactory::allToolChainFactories(); QList toolChains; QApplication::processEvents(); - log->append('\n' + tr("Searching tool chains...")); + emit q->logOutput('\n' + tr("Searching tool chains...")); for (ToolChainFactory *factory : factories) { - const QList newToolChains = factory->autoDetect(toolChains, q->sharedFromThis()); - log->append(tr("Searching tool chains of type %1").arg(factory->displayName())); + const QList newToolChains = factory->autoDetect(toolChains, m_device.constCast()); + emit q->logOutput(tr("Searching tool chains of type %1").arg(factory->displayName())); for (ToolChain *toolChain : newToolChains) { - log->append(tr("Found tool chain: %1").arg(toolChain->compilerCommand().toUserOutput())); + emit q->logOutput(tr("Found tool chain: %1").arg(toolChain->compilerCommand().toUserOutput())); ToolChainManager::registerToolChain(toolChain); toolChains.append(toolChain); } } - log->append(tr("%1 new tool chains found.").arg(toolChains.size())); + emit q->logOutput(tr("%1 new tool chains found.").arg(toolChains.size())); return toolChains; } -void DockerDevicePrivate::autoDetectCMake(QTextBrowser *log) +void KitDetectorPrivate::autoDetectCMake() { QObject *cmakeManager = ExtensionSystem::PluginManager::getObjectByName("CMakeToolManager"); if (!cmakeManager) return; - log->append('\n' + tr("Searching CMake binary...")); + emit q->logOutput('\n' + tr("Searching CMake binary...")); QString error; const QStringList candidates = {"cmake"}; for (const QString &candidate : candidates) { - const FilePath cmake = q->searchInPath(FilePath::fromString(candidate)); - QTC_CHECK(q->hasLocalFileAccess()); + const FilePath cmake = m_device->searchInPath(FilePath::fromString(candidate)); if (cmake.isExecutableFile()) { - log->append(tr("Found CMake binary: %1").arg(cmake.toUserOutput())); + emit q->logOutput(tr("Found CMake binary: %1").arg(cmake.toUserOutput())); const bool res = QMetaObject::invokeMethod(cmakeManager, "registerCMakeByPath", Q_ARG(Utils::FilePath, cmake), - Q_ARG(QString, m_data.id())); + Q_ARG(QString, m_sharedId)); QTC_CHECK(res); } } } -void DockerDevicePrivate::autoDetectDebugger(QTextBrowser *log) +void KitDetectorPrivate::autoDetectDebugger() { QObject *debuggerPlugin = ExtensionSystem::PluginManager::getObjectByName("DebuggerPlugin"); if (!debuggerPlugin) return; - if (log) - log->append('\n' + tr("Searching debuggers...")); - const FilePath deviceRoot = q->mapToGlobalPath({}); + emit q->logOutput('\n' + tr("Searching debuggers...")); + const FilePath deviceRoot = m_device->mapToGlobalPath({}); const bool res = QMetaObject::invokeMethod(debuggerPlugin, "autoDetectDebuggersForDevice", Q_ARG(Utils::FilePath, deviceRoot)); QTC_CHECK(res); } -void DockerDevicePrivate::autoDetect(QTextBrowser *log) +void KitDetectorPrivate::autoDetect() { QApplication::setOverrideCursor(Qt::WaitCursor); - undoAutoDetect(log); + undoAutoDetect(); - tryCreateLocalFileAccess(); + emit q->logOutput(tr("Starting auto-detection. This will take a while...")); - if (log) - log->append(tr("Starting auto-detection. This will take a while...")); + QList toolChains = autoDetectToolChains(); + QList qtVersions = autoDetectQtVersions(); - QList toolChains = autoDetectToolChains(log); - QList qtVersions = autoDetectQtVersions(log); - - autoDetectCMake(log); - autoDetectDebugger(log); + autoDetectCMake(); + autoDetectDebugger(); const auto initializeKit = [this, toolChains, qtVersions](Kit *k) { k->setAutoDetected(false); - k->setAutoDetectionSource(m_data.id()); + k->setAutoDetectionSource(m_sharedId); k->setUnexpandedDisplayName("%{Device:Name}"); DeviceTypeKitAspect::setDeviceTypeId(k, Constants::DOCKER_DEVICE_TYPE); - DeviceKitAspect::setDevice(k, q->sharedFromThis()); + DeviceKitAspect::setDevice(k, m_device); for (ToolChain *tc : toolChains) ToolChainKitAspect::setToolChain(k, tc); if (!qtVersions.isEmpty()) @@ -576,8 +604,7 @@ void DockerDevicePrivate::autoDetect(QTextBrowser *log) }; Kit *kit = KitManager::registerKit(initializeKit); - if (log) - log->append('\n' + tr("Registered kit %1").arg(kit->displayName())); + emit q->logOutput('\n' + tr("Registered kit %1").arg(kit->displayName())); QApplication::restoreOverrideCursor(); } @@ -1037,15 +1064,19 @@ FilePath DockerDevice::searchInPath(const FilePath &filePath) const return mapToGlobalPath(FilePath::fromString(output)); } -QList DockerDevice::directoryEntries(const FilePath &filePath, - const QStringList &nameFilters, - QDir::Filters filters, - QDir::SortFlags sort) const +FilePaths DockerDevice::directoryEntries(const FilePath &filePath, + const QStringList &nameFilters, + QDir::Filters filters, + QDir::SortFlags sort) const { QTC_ASSERT(handlesFile(filePath), return {}); tryCreateLocalFileAccess(); - if (hasLocalFileAccess()) - return mapToLocalAccess(filePath).dirEntries(nameFilters, filters, sort); + if (hasLocalFileAccess()) { + const FilePaths entries = mapToLocalAccess(filePath).dirEntries(nameFilters, filters, sort); + return Utils::transform(entries, [this](const FilePath &entry) { + return mapFromLocalAccess(entry); + }); + } QTC_CHECK(false); // FIXME: Implement return {}; @@ -1112,7 +1143,8 @@ Environment DockerDevice::systemEnvironment() const void DockerDevice::aboutToBeRemoved() const { - d->undoAutoDetect(nullptr); + KitDetector detector(sharedFromThis()); + detector.undoAutoDetect(d->m_data.id()); } void DockerDevicePrivate::fetchSystemEnviroment() diff --git a/src/plugins/docker/dockerdevice.h b/src/plugins/docker/dockerdevice.h index 1bed2eb9ce4..509bd2deeeb 100644 --- a/src/plugins/docker/dockerdevice.h +++ b/src/plugins/docker/dockerdevice.h @@ -122,6 +122,24 @@ private: friend class DockerDeviceWidget; }; +class KitDetector : public QObject +{ + Q_OBJECT + +public: + explicit KitDetector(const ProjectExplorer::IDevice::ConstPtr &device); + ~KitDetector() override; + + void autoDetect(const QString &sharedId) const; + void undoAutoDetect(const QString &sharedId) const; + +signals: + void logOutput(const QString &msg); + +private: + class KitDetectorPrivate *d = nullptr; +}; + class DockerDeviceFactory final : public ProjectExplorer::IDeviceFactory { public: diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 6c3896a9cc5..c9173666133 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -1085,7 +1085,7 @@ static QStringList normalLogArguments() "--pretty=format:" "commit %C(%1)%H%Creset %C(%2)%d%Creset%n" "Author: %C(%3)%an <%ae>%Creset%n" - "Date: %C(%4)%cD%Creset%n%n" + "Date: %C(%4)%cD %Creset%n%n" "%C(%5)%w(0,4,4)%s%Creset%n%n%b" ).arg(commitHash, decoration, authorName, commitDate, commitSubject); diff --git a/src/plugins/languageclient/semantichighlightsupport.cpp b/src/plugins/languageclient/semantichighlightsupport.cpp index db6cd9f907d..3aafaf5b42f 100644 --- a/src/plugins/languageclient/semantichighlightsupport.cpp +++ b/src/plugins/languageclient/semantichighlightsupport.cpp @@ -39,10 +39,11 @@ using namespace LanguageServerProtocol; using namespace TextEditor; namespace LanguageClient { -namespace SemanticHighligtingSupport { static Q_LOGGING_CATEGORY(LOGLSPHIGHLIGHT, "qtc.languageclient.highlight", QtWarningMsg); +namespace SemanticHighligtingSupport { + static const QList> highlightScopes(const ServerCapabilities &capabilities) { return capabilities.semanticHighlighting() @@ -399,15 +400,27 @@ void SemanticTokenSupport::handleSemanticTokensDelta( newData.reserve(newDataSize); auto it = data.begin(); + const auto end = data.end(); for (const SemanticTokensEdit &edit : qAsConst(edits)) { if (edit.start() > data.size()) // prevent edits after the previously reported data return; for (const auto start = data.begin() + edit.start(); it < start; ++it) newData.append(*it); newData.append(edit.data().value_or(QList())); - it += edit.deleteCount(); + int deleteCount = edit.deleteCount(); + if (deleteCount > std::distance(it, end)) { + qCDebug(LOGLSPHIGHLIGHT) + << "We shall delete more highlight data entries than we actually have, " + "so we are out of sync with the server. " + "Request full semantic tokens again."; + TextDocument *doc = TextDocument::textDocumentForFilePath(filePath); + if (doc && LanguageClientManager::clientForDocument(doc) == m_client) + reloadSemanticTokens(doc); + return; + } + it += deleteCount; } - for (const auto end = data.end(); it != end; ++it) + for (; it != end; ++it) newData.append(*it); tokens.setData(newData); diff --git a/src/plugins/nim/project/nimtoolchainfactory.cpp b/src/plugins/nim/project/nimtoolchainfactory.cpp index c7ff4500f5d..1d11d1bd873 100644 --- a/src/plugins/nim/project/nimtoolchainfactory.cpp +++ b/src/plugins/nim/project/nimtoolchainfactory.cpp @@ -28,6 +28,8 @@ #include "nimconstants.h" #include "nimtoolchain.h" +#include + #include #include #include @@ -52,11 +54,10 @@ NimToolChainFactory::NimToolChainFactory() QList NimToolChainFactory::autoDetect(const QList &alreadyKnown, const IDevice::Ptr &device) { - Q_UNUSED(device); QList result; - Environment systemEnvironment = Environment::systemEnvironment(); - const FilePath compilerPath = systemEnvironment.searchInPath("nim"); + IDevice::ConstPtr dev = device ? device : DeviceManager::defaultDesktopDevice(); + const FilePath compilerPath = dev->searchInPath(FilePath::fromString("nim")); if (compilerPath.isEmpty()) return result; diff --git a/src/plugins/perfprofiler/perftracepointdialog.cpp b/src/plugins/perfprofiler/perftracepointdialog.cpp index c6ca317d913..771471b186f 100644 --- a/src/plugins/perfprofiler/perftracepointdialog.cpp +++ b/src/plugins/perfprofiler/perftracepointdialog.cpp @@ -63,10 +63,8 @@ PerfTracePointDialog::PerfTracePointDialog() : } if (!m_device) { - const DeviceManager *deviceManager = DeviceManager::instance(); - // There should at least be a desktop device. - m_device = deviceManager->defaultDevice(Constants::DESKTOP_DEVICE_TYPE); + m_device = DeviceManager::defaultDesktopDevice(); QTC_ASSERT(m_device, return); } diff --git a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp index 1c8b125b578..b59113d25f6 100644 --- a/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp +++ b/src/plugins/projectexplorer/customexecutablerunconfiguration.cpp @@ -104,7 +104,7 @@ Runnable CustomExecutableRunConfiguration::runnable() const r.setCommandLine(commandLine()); r.environment = aspect()->environment(); r.workingDirectory = workingDirectory.toString(); - r.device = DeviceManager::instance()->defaultDevice(Constants::DESKTOP_DEVICE_TYPE); + r.device = DeviceManager::defaultDesktopDevice(); if (!r.executable.isEmpty()) { const QString expanded = macroExpander()->expand(r.executable.toString()); diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp index 532240b1331..97c700eb2b5 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp +++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp @@ -331,6 +331,11 @@ IDevice::ConstPtr DeviceManager::deviceForPath(const FilePath &path) return {}; } +IDevice::ConstPtr DeviceManager::defaultDesktopDevice() +{ + return m_instance->defaultDevice(Constants::DESKTOP_DEVICE_TYPE); +} + void DeviceManager::setDefaultDevice(Utils::Id id) { QTC_ASSERT(this != instance(), return); diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.h b/src/plugins/projectexplorer/devicesupport/devicemanager.h index ef8047e0a57..466adb36b9b 100644 --- a/src/plugins/projectexplorer/devicesupport/devicemanager.h +++ b/src/plugins/projectexplorer/devicesupport/devicemanager.h @@ -69,7 +69,9 @@ public: void setDeviceState(Utils::Id deviceId, IDevice::DeviceState deviceState); bool isLoaded() const; + static IDevice::ConstPtr deviceForPath(const Utils::FilePath &path); + static IDevice::ConstPtr defaultDesktopDevice(); signals: void deviceAdded(Utils::Id id); diff --git a/src/plugins/projectexplorer/kitinformation.cpp b/src/plugins/projectexplorer/kitinformation.cpp index f6f651b8688..2b1fd0d711b 100644 --- a/src/plugins/projectexplorer/kitinformation.cpp +++ b/src/plugins/projectexplorer/kitinformation.cpp @@ -1231,8 +1231,7 @@ BuildDeviceKitAspect::BuildDeviceKitAspect() QVariant BuildDeviceKitAspect::defaultValue(const Kit *k) const { Q_UNUSED(k); - IDevice::ConstPtr defaultDevice = - DeviceManager::instance()->defaultDevice(Constants::DESKTOP_DEVICE_TYPE); + IDevice::ConstPtr defaultDevice = DeviceManager::defaultDesktopDevice(); return defaultDevice->id().toString(); } diff --git a/src/plugins/qmldesigner/designercore/instances/baseconnectionmanager.cpp b/src/plugins/qmldesigner/designercore/instances/baseconnectionmanager.cpp index 794c1a436c0..39590beadf7 100644 --- a/src/plugins/qmldesigner/designercore/instances/baseconnectionmanager.cpp +++ b/src/plugins/qmldesigner/designercore/instances/baseconnectionmanager.cpp @@ -66,9 +66,9 @@ bool BaseConnectionManager::isActive() const void BaseConnectionManager::showCannotConnectToPuppetWarningAndSwitchToEditMode() {} -void BaseConnectionManager::processFinished() +void BaseConnectionManager::processFinished(const QString &reason) { - processFinished(-1, QProcess::CrashExit); + processFinished(-1, QProcess::CrashExit, reason); } void BaseConnectionManager::writeCommandToIODevice(const QVariant &command, diff --git a/src/plugins/qmldesigner/designercore/instances/baseconnectionmanager.h b/src/plugins/qmldesigner/designercore/instances/baseconnectionmanager.h index fca035682fc..58588542f7f 100644 --- a/src/plugins/qmldesigner/designercore/instances/baseconnectionmanager.h +++ b/src/plugins/qmldesigner/designercore/instances/baseconnectionmanager.h @@ -64,7 +64,7 @@ protected: void dispatchCommand(const QVariant &command, Connection &connection) override; virtual void showCannotConnectToPuppetWarningAndSwitchToEditMode(); using ConnectionManagerInterface::processFinished; - void processFinished(); + void processFinished(const QString &reason); static void writeCommandToIODevice(const QVariant &command, QIODevice *ioDevice, unsigned int commandCounter); diff --git a/src/plugins/qmldesigner/designercore/instances/capturingconnectionmanager.cpp b/src/plugins/qmldesigner/designercore/instances/capturingconnectionmanager.cpp index 90f4226217d..3e68e3342c1 100644 --- a/src/plugins/qmldesigner/designercore/instances/capturingconnectionmanager.cpp +++ b/src/plugins/qmldesigner/designercore/instances/capturingconnectionmanager.cpp @@ -54,17 +54,17 @@ void CapturingConnectionManager::setUp(NodeInstanceServerInterface *nodeInstance } } -void CapturingConnectionManager::processFinished(int exitCode, QProcess::ExitStatus exitStatus) +void CapturingConnectionManager::processFinished(int exitCode, QProcess::ExitStatus exitStatus, const QString &connectionName) { if (m_captureFileForTest.isOpen()) { m_captureFileForTest.close(); Core::AsynchronousMessageBox::warning( - tr("QML Emulation Layer (QML Puppet) Crashed"), + tr("QML Emulation Layer (QML Puppet - %1) Crashed").arg(connectionName), tr("You are recording a puppet stream and the emulations layer crashed. " "It is recommended to reopen the Qt Quick Designer and start again.")); } - InteractiveConnectionManager::processFinished(exitCode, exitStatus); + InteractiveConnectionManager::processFinished(exitCode, exitStatus, connectionName); } void CapturingConnectionManager::writeCommand(const QVariant &command) diff --git a/src/plugins/qmldesigner/designercore/instances/capturingconnectionmanager.h b/src/plugins/qmldesigner/designercore/instances/capturingconnectionmanager.h index 91b73687c80..7552fa27902 100644 --- a/src/plugins/qmldesigner/designercore/instances/capturingconnectionmanager.h +++ b/src/plugins/qmldesigner/designercore/instances/capturingconnectionmanager.h @@ -39,7 +39,7 @@ public: ProjectExplorer::Target *target, AbstractView *view) override; - void processFinished(int exitCode, QProcess::ExitStatus exitStatus) override; + void processFinished(int exitCode, QProcess::ExitStatus exitStatus, const QString &connectionName) override; void writeCommand(const QVariant &command) override; diff --git a/src/plugins/qmldesigner/designercore/instances/connectionmanager.cpp b/src/plugins/qmldesigner/designercore/instances/connectionmanager.cpp index 77ea8706bf1..3f28389b539 100644 --- a/src/plugins/qmldesigner/designercore/instances/connectionmanager.cpp +++ b/src/plugins/qmldesigner/designercore/instances/connectionmanager.cpp @@ -69,7 +69,7 @@ void ConnectionManager::setUp(NodeInstanceServerInterface *nodeInstanceServerPro socketToken, [&] { printProcessOutput(connection.qmlPuppetProcess.get(), connection.name); }, [&](int exitCode, QProcess::ExitStatus exitStatus) { - processFinished(exitCode, exitStatus); + processFinished(exitCode, exitStatus, connection.name); }); const int second = 1000; @@ -122,15 +122,10 @@ void ConnectionManager::writeCommand(const QVariant &command) m_writeCommandCounter++; } -void ConnectionManager::processFinished(int exitCode, QProcess::ExitStatus exitStatus) +void ConnectionManager::processFinished(int exitCode, QProcess::ExitStatus exitStatus, const QString &connectionName) { - auto finishedProcess = qobject_cast(sender()); - if (finishedProcess) - qWarning() << "Process" << (exitStatus == QProcess::CrashExit ? "crashed:" : "finished:") - << finishedProcess->arguments() << "exitCode:" << exitCode; - else - qWarning() << "Process" << (exitStatus == QProcess::CrashExit ? "crashed:" : "finished:") - << sender() << "exitCode:" << exitCode; + qWarning() << "Process" << connectionName <<(exitStatus == QProcess::CrashExit ? "crashed:" : "finished:") + << "with exitCode:" << exitCode; writeCommand(QVariant::fromValue(EndPuppetCommand())); diff --git a/src/plugins/qmldesigner/designercore/instances/connectionmanager.h b/src/plugins/qmldesigner/designercore/instances/connectionmanager.h index c3c2c34afbf..fec3adac060 100644 --- a/src/plugins/qmldesigner/designercore/instances/connectionmanager.h +++ b/src/plugins/qmldesigner/designercore/instances/connectionmanager.h @@ -58,7 +58,7 @@ public: protected: using BaseConnectionManager::processFinished; - void processFinished(int exitCode, QProcess::ExitStatus exitStatus) override; + void processFinished(int exitCode, QProcess::ExitStatus exitStatus, const QString &connectionName) override; std::vector &connections() { return m_connections; } quint32 &writeCommandCounter() { return m_writeCommandCounter; } diff --git a/src/plugins/qmldesigner/designercore/instances/connectionmanagerinterface.h b/src/plugins/qmldesigner/designercore/instances/connectionmanagerinterface.h index 2fc75c61c22..319c7407676 100644 --- a/src/plugins/qmldesigner/designercore/instances/connectionmanagerinterface.h +++ b/src/plugins/qmldesigner/designercore/instances/connectionmanagerinterface.h @@ -79,7 +79,7 @@ public: protected: virtual void dispatchCommand(const QVariant &command, Connection &connection) = 0; - virtual void processFinished(int exitCode, QProcess::ExitStatus exitStatus) = 0; + virtual void processFinished(int exitCode, QProcess::ExitStatus exitStatus, const QString &connectionName) = 0; }; } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/instances/interactiveconnectionmanager.cpp b/src/plugins/qmldesigner/designercore/instances/interactiveconnectionmanager.cpp index a8c1ecd5fee..dd2f47e5558 100644 --- a/src/plugins/qmldesigner/designercore/instances/interactiveconnectionmanager.cpp +++ b/src/plugins/qmldesigner/designercore/instances/interactiveconnectionmanager.cpp @@ -107,7 +107,7 @@ void InteractiveConnectionManager::puppetTimeout(Connection &connection) return; } - processFinished(); + processFinished(connection.name + "_timeout"); } void InteractiveConnectionManager::puppetAlive(Connection &connection) diff --git a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp index 9a40a6a8ced..7051164bb1a 100644 --- a/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp +++ b/src/plugins/qmldesigner/designercore/instances/puppetcreator.cpp @@ -452,7 +452,7 @@ static void filterOutQtBaseImportPath(QStringList *stringList) { Utils::erase(*stringList, [](const QString &string) { QDir dir(string); - return dir.dirName() == "qml" && !dir.entryInfoList(QStringList("QtQuick.2"), QDir::Dirs).isEmpty(); + return dir.dirName() == "qml" && !dir.entryInfoList(QStringList("QtTest"), QDir::Dirs).isEmpty(); }); } diff --git a/tests/manual/docker/Dockerfile-qt-5-ubuntu-20.04-build b/tests/manual/docker/Dockerfile-qt-5-ubuntu-20.04-build index f0d9b9de363..473d3256fc3 100644 --- a/tests/manual/docker/Dockerfile-qt-5-ubuntu-20.04-build +++ b/tests/manual/docker/Dockerfile-qt-5-ubuntu-20.04-build @@ -18,5 +18,6 @@ RUN apt-get update \ g++ \ gdb \ ninja-build \ + nim \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* diff --git a/tests/unit/unittest/clangformat-test.cpp b/tests/unit/unittest/clangformat-test.cpp index 2ce3eba24ab..9aec542edfd 100644 --- a/tests/unit/unittest/clangformat-test.cpp +++ b/tests/unit/unittest/clangformat-test.cpp @@ -957,6 +957,28 @@ TEST_F(ClangFormat, ChainedMemberFunctionCalls) " .func();")); } +TEST_F(ClangFormat, CommentBlock) +{ + insertLines({"/****************************************************************************", + "**", + "** Copyright (C) 2021 The Qt Company Ltd.", + "** Contact: https://www.qt.io/licensing/", + "**", + "** This file is part of Qt Creator.", + "**", + "****************************************************************************/"}); + indenter.indent(cursor, QChar::Null, TextEditor::TabSettings()); + ASSERT_THAT(documentLines(), ElementsAre( + "/****************************************************************************", + "**", + "** Copyright (C) 2021 The Qt Company Ltd.", + "** Contact: https://www.qt.io/licensing/", + "**", + "** This file is part of Qt Creator.", + "**", + "****************************************************************************/")); +} + // clang-format on } // namespace