Merge remote-tracking branch 'origin/5.0'

Change-Id: Icea9215204a7247c5fbbc818833132676a3b9e11
This commit is contained in:
Eike Ziller
2021-07-06 16:00:14 +02:00
33 changed files with 222 additions and 187 deletions

View File

@@ -241,6 +241,7 @@ function(add_qtc_library name)
qtc_output_binary_dir(_output_binary_dir) qtc_output_binary_dir(_output_binary_dir)
string(REGEX MATCH "^[0-9]*" IDE_VERSION_MAJOR ${IDE_VERSION}) string(REGEX MATCH "^[0-9]*" IDE_VERSION_MAJOR ${IDE_VERSION})
set_target_properties(${name} PROPERTIES set_target_properties(${name} PROPERTIES
LINK_DEPENDS_NO_SHARED ON
SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}" SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
VERSION "${IDE_VERSION}" VERSION "${IDE_VERSION}"
SOVERSION "${IDE_VERSION_MAJOR}" SOVERSION "${IDE_VERSION_MAJOR}"
@@ -497,6 +498,7 @@ function(add_qtc_plugin target_name)
qtc_output_binary_dir(_output_binary_dir) qtc_output_binary_dir(_output_binary_dir)
set_target_properties(${target_name} PROPERTIES set_target_properties(${target_name} PROPERTIES
LINK_DEPENDS_NO_SHARED ON
SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}" SOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}"
MACHO_CURRENT_VERSION ${IDE_VERSION} MACHO_CURRENT_VERSION ${IDE_VERSION}
MACHO_COMPATIBILITY_VERSION ${IDE_VERSION_COMPAT} MACHO_COMPATIBILITY_VERSION ${IDE_VERSION_COMPAT}
@@ -694,6 +696,7 @@ function(add_qtc_executable name)
qtc_output_binary_dir(_output_binary_dir) qtc_output_binary_dir(_output_binary_dir)
set_target_properties("${name}" PROPERTIES set_target_properties("${name}" PROPERTIES
LINK_DEPENDS_NO_SHARED ON
BUILD_RPATH "${build_rpath}" BUILD_RPATH "${build_rpath}"
INSTALL_RPATH "${install_rpath}" INSTALL_RPATH "${install_rpath}"
RUNTIME_OUTPUT_DIRECTORY "${_output_binary_dir}/${_DESTINATION}" RUNTIME_OUTPUT_DIRECTORY "${_output_binary_dir}/${_DESTINATION}"
@@ -844,6 +847,7 @@ function(add_qtc_test name)
) )
set_target_properties(${name} PROPERTIES set_target_properties(${name} PROPERTIES
LINK_DEPENDS_NO_SHARED ON
CXX_VISIBILITY_PRESET hidden CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON VISIBILITY_INLINES_HIDDEN ON
BUILD_RPATH "${_RPATH_BASE}/${_RPATH}" BUILD_RPATH "${_RPATH_BASE}/${_RPATH}"

View File

@@ -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_COPYRIGHT_YEAR "2021") # The IDE current copyright year.
set(IDE_SETTINGSVARIANT "QtProject") # The IDE settings variation. 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_DISPLAY_NAME "Qt Creator") # The IDE display name.
set(IDE_ID "qtcreator") # The IDE id (no spaces, lowercase!) set(IDE_ID "qtcreator") # The IDE id (no spaces, lowercase!)
set(IDE_CASED_ID "QtCreator") # The cased IDE id (no spaces!) set(IDE_CASED_ID "QtCreator") # The cased IDE id (no spaces!)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -49,7 +49,6 @@ const char IDE_REVISION_URL[] = "${IDE_REVISION_URL}";
// changes the path where the settings are saved to // changes the path where the settings are saved to
const char IDE_SETTINGSVARIANT_STR[] = "${IDE_SETTINGSVARIANT}"; const char IDE_SETTINGSVARIANT_STR[] = "${IDE_SETTINGSVARIANT}";
const char IDE_COPY_SETTINGS_FROM_VARIANT_STR[] = "${IDE_COPY_SETTINGSVARIANT}";
} // Constants } // Constants
} // Core } // Core

View File

@@ -65,12 +65,6 @@ const char IDE_SETTINGSVARIANT_STR[] = STRINGIFY(IDE_SETTINGSVARIANT);
const char IDE_SETTINGSVARIANT_STR[] = \"QtProject\"; const char IDE_SETTINGSVARIANT_STR[] = \"QtProject\";
#endif #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_COMPAT_DEF
#undef IDE_VERSION_DISPLAY_DEF #undef IDE_VERSION_DISPLAY_DEF
#undef IDE_VERSION #undef IDE_VERSION

View File

@@ -290,49 +290,6 @@ static Utils::QtcSettings *createUserSettings()
QLatin1String(Core::Constants::IDE_CASED_ID)); 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() static void setHighDpiEnvironmentVariable()
{ {
@@ -595,7 +552,7 @@ int main(int argc, char **argv)
/*Initialize global settings and resetup install settings with QApplication::applicationDirPath */ /*Initialize global settings and resetup install settings with QApplication::applicationDirPath */
setupInstallSettings(options.installSettingsPath); setupInstallSettings(options.installSettingsPath);
Utils::QtcSettings *settings = userSettings(); Utils::QtcSettings *settings = createUserSettings();
Utils::QtcSettings *globalSettings Utils::QtcSettings *globalSettings
= new Utils::QtcSettings(QSettings::IniFormat, = new Utils::QtcSettings(QSettings::IniFormat,
QSettings::SystemScope, QSettings::SystemScope,

View File

@@ -1089,13 +1089,6 @@ bool ProcessArgs::expandMacros(QString *cmd, AbstractMacroExpander *mx, OsType o
return true; 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() bool ProcessArgs::ArgIterator::next()
{ {
// We delay the setting of m_prev so we can still delete the last argument // We delay the setting of m_prev so we can still delete the last argument

View File

@@ -81,8 +81,6 @@ public:
//! Safely replace the expandos in a shell command //! Safely replace the expandos in a shell command
static bool expandMacros(QString *cmd, AbstractMacroExpander *mx, static bool expandMacros(QString *cmd, AbstractMacroExpander *mx,
OsType osType = HostOsInfo::hostOs()); OsType osType = HostOsInfo::hostOs());
static QString expandMacros(const QString &str, AbstractMacroExpander *mx,
OsType osType = HostOsInfo::hostOs());
/*! Iterate over arguments from a command line. /*! Iterate over arguments from a command line.
* Assumes that the name of the actual command is *not* part of the line. * Assumes that the name of the actual command is *not* part of the line.

View File

@@ -35,11 +35,14 @@
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
#include <QLoggingCategory>
#include <QMap> #include <QMap>
namespace Utils { namespace Utils {
namespace Internal { namespace Internal {
static Q_LOGGING_CATEGORY(expanderLog, "qtc.utils.macroexpander", QtWarningMsg)
const char kFilePathPostfix[] = ":FilePath"; const char kFilePathPostfix[] = ":FilePath";
const char kPathPostfix[] = ":Path"; const char kPathPostfix[] = ":Path";
const char kNativeFilePathPostfix[] = ":NativeFilePath"; const char kNativeFilePathPostfix[] = ":NativeFilePath";
@@ -327,7 +330,10 @@ QVariant MacroExpander::expandVariant(const QVariant &v) const
QString MacroExpander::expandProcessArgs(const QString &argsWithVariables) 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) static QByteArray fullPrefix(const QByteArray &prefix)

View File

@@ -427,11 +427,6 @@ PersistentSettingsWriter::PersistentSettingsWriter(const FilePath &fileName, con
m_fileName(fileName), m_docType(docType) m_fileName(fileName), m_docType(docType)
{ } { }
PersistentSettingsWriter::~PersistentSettingsWriter()
{
write(m_savedData, nullptr);
}
bool PersistentSettingsWriter::save(const QVariantMap &data, QString *errorString) const bool PersistentSettingsWriter::save(const QVariantMap &data, QString *errorString) const
{ {
if (data == m_savedData) if (data == m_savedData)

View File

@@ -52,7 +52,6 @@ class QTCREATOR_UTILS_EXPORT PersistentSettingsWriter
{ {
public: public:
PersistentSettingsWriter(const FilePath &fileName, const QString &docType); PersistentSettingsWriter(const FilePath &fileName, const QString &docType);
~PersistentSettingsWriter();
bool save(const QVariantMap &data, QString *errorString) const; bool save(const QVariantMap &data, QString *errorString) const;
#ifdef QT_GUI_LIB #ifdef QT_GUI_LIB

View File

@@ -92,6 +92,11 @@ clang::tooling::Replacements filteredReplacements(const QByteArray &buffer,
llvm::StringRef text = replacementsToKeep == ReplacementsToKeep::OnlyIndent llvm::StringRef text = replacementsToKeep == ReplacementsToKeep::OnlyIndent
? clearExtraNewline(replacement.getReplacementText()) ? clearExtraNewline(replacement.getReplacementText())
: 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( llvm::Error error = filtered.add(
clang::tooling::Replacement(replacement.getFilePath(), clang::tooling::Replacement(replacement.getFilePath(),
@@ -295,8 +300,8 @@ int forceIndentWithExtraText(QByteArray &buffer,
if (block.previous().isValid()) { if (block.previous().isValid()) {
const int prevEndOffset = Utils::Text::utf8NthLineOffset(block.document(), buffer, const int prevEndOffset = Utils::Text::utf8NthLineOffset(block.document(), buffer,
block.blockNumber()) + block.previous().text().length(); block.blockNumber()) + block.previous().text().length();
buffer.insert(prevEndOffset, "//"); buffer.insert(prevEndOffset, " //");
extraLength += 2; extraLength += 3;
} }
} }
buffer.insert(utf8Offset + extraLength, dummyText); buffer.insert(utf8Offset + extraLength, dummyText);

View File

@@ -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<BaseQtVersion *> autoDetectQtVersions() const;
QList<ToolChain *> 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 class DockerDevicePrivate : public QObject
{ {
Q_DECLARE_TR_FUNCTIONS(Docker::Internal::DockerDevice) Q_DECLARE_TR_FUNCTIONS(Docker::Internal::DockerDevice)
@@ -255,14 +298,6 @@ public:
void tryCreateLocalFileAccess(); void tryCreateLocalFileAccess();
void autoDetect(QTextBrowser *log);
void undoAutoDetect(QTextBrowser *log) const;
QList<BaseQtVersion *> autoDetectQtVersions(QTextBrowser *log) const;
QList<ToolChain *> autoDetectToolChains(QTextBrowser *log);
void autoDetectCMake(QTextBrowser *log);
void autoDetectDebugger(QTextBrowser *log);
void fetchSystemEnviroment(); void fetchSystemEnviroment();
DockerDevice *q; DockerDevice *q;
@@ -283,54 +318,59 @@ class DockerDeviceWidget final : public IDeviceWidget
public: public:
explicit DockerDeviceWidget(const IDevice::Ptr &device) explicit DockerDeviceWidget(const IDevice::Ptr &device)
: IDeviceWidget(device) : IDeviceWidget(device), m_kitItemDetector(device)
{ {
auto dockerDevice = device.dynamicCast<DockerDevice>(); auto dockerDevice = device.dynamicCast<DockerDevice>();
QTC_ASSERT(dockerDevice, return); 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 = new QLineEdit;
m_idLineEdit->setText(dockerDevice->data().imageId); m_idLineEdit->setText(data.imageId);
m_idLineEdit->setEnabled(false); m_idLineEdit->setEnabled(false);
auto repoLabel = new QLabel(tr("Repository:")); auto repoLabel = new QLabel(tr("Repository:"));
m_repoLineEdit = new QLineEdit; m_repoLineEdit = new QLineEdit;
m_repoLineEdit->setText(dockerDevice->data().repo); m_repoLineEdit->setText(data.repo);
m_repoLineEdit->setEnabled(false); m_repoLineEdit->setEnabled(false);
m_runAsOutsideUser = new QCheckBox(tr("Run as outside user")); 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 " m_runAsOutsideUser->setToolTip(tr("Use user ID and group ID of the user running Qt Creator "
"in the Docker container.")); "in the Docker container."));
m_runAsOutsideUser->setChecked(dockerDevice->data().useLocalUidGid); m_runAsOutsideUser->setChecked(data.useLocalUidGid);
m_runAsOutsideUser->setEnabled(HostOsInfo::isLinuxHost()); m_runAsOutsideUser->setEnabled(HostOsInfo::isLinuxHost());
connect(m_runAsOutsideUser, &QCheckBox::toggled, this, [dockerDevice](bool on) { connect(m_runAsOutsideUser, &QCheckBox::toggled, this, [&data](bool on) {
dockerDevice->data().useLocalUidGid = on; data.useLocalUidGid = on;
}); });
m_pathsLineEdit = new QLineEdit; 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 " m_pathsLineEdit->setToolTip(tr("Paths in this semi-colon separated list will be "
"mapped one-to-one into the Docker container.")); "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) { connect(m_pathsLineEdit, &QLineEdit::textChanged, this, [&data](const QString &text) {
dockerDevice->data().mounts = text.split(';'); data.mounts = text.split(';');
}); });
auto logView = new QTextBrowser; auto logView = new QTextBrowser;
connect(&m_kitItemDetector, &KitDetector::logOutput,
logView, &QTextBrowser::append);
auto autoDetectButton = new QPushButton(tr("Auto-detect Kit Items")); auto autoDetectButton = new QPushButton(tr("Auto-detect Kit Items"));
auto undoAutoDetectButton = new QPushButton(tr("Remove Auto-Detected 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(); 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(); logView->clear();
dockerDevice->d->undoAutoDetect(logView); m_kitItemDetector.undoAutoDetect(id);
}); });
using namespace Layouting; using namespace Layouting;
@@ -356,6 +396,8 @@ private:
QLineEdit *m_repoLineEdit; QLineEdit *m_repoLineEdit;
QCheckBox *m_runAsOutsideUser; QCheckBox *m_runAsOutsideUser;
QLineEdit *m_pathsLineEdit; QLineEdit *m_pathsLineEdit;
KitDetector m_kitItemDetector;
}; };
IDeviceWidget *DockerDevice::createWidget() IDeviceWidget *DockerDevice::createWidget()
@@ -424,146 +466,132 @@ DockerDeviceData &DockerDevice::data()
return d->m_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()) { for (Kit *kit : KitManager::kits()) {
if (kit->autoDetectionSource() == id) { if (kit->autoDetectionSource() == m_sharedId) {
if (log) emit q->logOutput(tr("Removing kit: %1").arg(kit->displayName()));
log->append(tr("Removing kit: %1").arg(kit->displayName()));
KitManager::deregisterKit(kit); KitManager::deregisterKit(kit);
} }
}; };
for (BaseQtVersion *qtVersion : QtVersionManager::versions()) { for (BaseQtVersion *qtVersion : QtVersionManager::versions()) {
if (qtVersion->autodetectionSource() == id) { if (qtVersion->autodetectionSource() == m_sharedId) {
if (log) emit q->logOutput(tr("Removing Qt version: %1").arg(qtVersion->displayName()));
log->append(tr("Removing Qt version: %1").arg(qtVersion->displayName()));
QtVersionManager::removeVersion(qtVersion); QtVersionManager::removeVersion(qtVersion);
} }
}; };
if (log) emit q->logOutput(tr("Tool chains not removed."));
log->append(tr("Tool chains not removed."));
// for (ToolChain *toolChain : ToolChainManager::toolChains()) { // for (ToolChain *toolChain : ToolChainManager::toolChains()) {
// if (toolChain->autoDetectionSource() == id.toString()) // if (toolChain->autoDetectionSource() == id.toString())
// // FIXME: Implement // // FIXME: Implement
// }; // };
if (log) emit q->logOutput(tr("Removal of previously auto-detected kit items finished.") + '\n');
log->append(tr("Removal of previously auto-detected kit items finished.") + '\n');
} }
QList<BaseQtVersion *> DockerDevicePrivate::autoDetectQtVersions(QTextBrowser *log) const QList<BaseQtVersion *> KitDetectorPrivate::autoDetectQtVersions() const
{ {
QList<BaseQtVersion *> qtVersions; QList<BaseQtVersion *> qtVersions;
QString error; QString error;
const QStringList candidates = {"qmake-qt6", "qmake-qt5", "qmake"}; const QStringList candidates = {"qmake-qt6", "qmake-qt5", "qmake"};
if (log) emit q->logOutput('\n' + tr("Searching Qt installations..."));
log->append('\n' + tr("Searching Qt installations..."));
for (const QString &candidate : candidates) { for (const QString &candidate : candidates) {
if (log) emit q->logOutput(tr("Searching for %1 executable...").arg(candidate));
log->append(tr("Searching for %1 executable...").arg(candidate)); const FilePath qmake = m_device->searchInPath(FilePath::fromString(candidate));
const FilePath qmake = q->searchInPath(FilePath::fromString(candidate));
if (qmake.isEmpty()) if (qmake.isEmpty())
continue; continue;
BaseQtVersion *qtVersion = QtVersionFactory::createQtVersionFromQMakePath(qmake, false, m_data.id(), &error); BaseQtVersion *qtVersion = QtVersionFactory::createQtVersionFromQMakePath(qmake, false, m_sharedId, &error);
if (!qtVersion) if (!qtVersion)
continue; continue;
qtVersions.append(qtVersion); qtVersions.append(qtVersion);
QtVersionManager::addVersion(qtVersion); QtVersionManager::addVersion(qtVersion);
if (log) emit q->logOutput(tr("Found Qt: %1").arg(qtVersion->qmakeCommand().toUserOutput()));
log->append(tr("Found Qt: %1").arg(qtVersion->qmakeCommand().toUserOutput()));
} }
if (qtVersions.isEmpty() && log) if (qtVersions.isEmpty())
log->append(tr("No Qt installation found.")); emit q->logOutput(tr("No Qt installation found."));
return qtVersions; return qtVersions;
} }
QList<ToolChain *> DockerDevicePrivate::autoDetectToolChains(QTextBrowser *log) QList<ToolChain *> KitDetectorPrivate::autoDetectToolChains()
{ {
const QList<ToolChainFactory *> factories = ToolChainFactory::allToolChainFactories(); const QList<ToolChainFactory *> factories = ToolChainFactory::allToolChainFactories();
QList<ToolChain *> toolChains; QList<ToolChain *> toolChains;
QApplication::processEvents(); QApplication::processEvents();
log->append('\n' + tr("Searching tool chains...")); emit q->logOutput('\n' + tr("Searching tool chains..."));
for (ToolChainFactory *factory : factories) { for (ToolChainFactory *factory : factories) {
const QList<ToolChain *> newToolChains = factory->autoDetect(toolChains, q->sharedFromThis()); const QList<ToolChain *> newToolChains = factory->autoDetect(toolChains, m_device.constCast<IDevice>());
log->append(tr("Searching tool chains of type %1").arg(factory->displayName())); emit q->logOutput(tr("Searching tool chains of type %1").arg(factory->displayName()));
for (ToolChain *toolChain : newToolChains) { 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); ToolChainManager::registerToolChain(toolChain);
toolChains.append(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; return toolChains;
} }
void DockerDevicePrivate::autoDetectCMake(QTextBrowser *log) void KitDetectorPrivate::autoDetectCMake()
{ {
QObject *cmakeManager = ExtensionSystem::PluginManager::getObjectByName("CMakeToolManager"); QObject *cmakeManager = ExtensionSystem::PluginManager::getObjectByName("CMakeToolManager");
if (!cmakeManager) if (!cmakeManager)
return; return;
log->append('\n' + tr("Searching CMake binary...")); emit q->logOutput('\n' + tr("Searching CMake binary..."));
QString error; QString error;
const QStringList candidates = {"cmake"}; const QStringList candidates = {"cmake"};
for (const QString &candidate : candidates) { for (const QString &candidate : candidates) {
const FilePath cmake = q->searchInPath(FilePath::fromString(candidate)); const FilePath cmake = m_device->searchInPath(FilePath::fromString(candidate));
QTC_CHECK(q->hasLocalFileAccess());
if (cmake.isExecutableFile()) { 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, const bool res = QMetaObject::invokeMethod(cmakeManager,
"registerCMakeByPath", "registerCMakeByPath",
Q_ARG(Utils::FilePath, cmake), Q_ARG(Utils::FilePath, cmake),
Q_ARG(QString, m_data.id())); Q_ARG(QString, m_sharedId));
QTC_CHECK(res); QTC_CHECK(res);
} }
} }
} }
void DockerDevicePrivate::autoDetectDebugger(QTextBrowser *log) void KitDetectorPrivate::autoDetectDebugger()
{ {
QObject *debuggerPlugin = ExtensionSystem::PluginManager::getObjectByName("DebuggerPlugin"); QObject *debuggerPlugin = ExtensionSystem::PluginManager::getObjectByName("DebuggerPlugin");
if (!debuggerPlugin) if (!debuggerPlugin)
return; return;
if (log) emit q->logOutput('\n' + tr("Searching debuggers..."));
log->append('\n' + tr("Searching debuggers...")); const FilePath deviceRoot = m_device->mapToGlobalPath({});
const FilePath deviceRoot = q->mapToGlobalPath({});
const bool res = QMetaObject::invokeMethod(debuggerPlugin, const bool res = QMetaObject::invokeMethod(debuggerPlugin,
"autoDetectDebuggersForDevice", "autoDetectDebuggersForDevice",
Q_ARG(Utils::FilePath, deviceRoot)); Q_ARG(Utils::FilePath, deviceRoot));
QTC_CHECK(res); QTC_CHECK(res);
} }
void DockerDevicePrivate::autoDetect(QTextBrowser *log) void KitDetectorPrivate::autoDetect()
{ {
QApplication::setOverrideCursor(Qt::WaitCursor); QApplication::setOverrideCursor(Qt::WaitCursor);
undoAutoDetect(log); undoAutoDetect();
tryCreateLocalFileAccess(); emit q->logOutput(tr("Starting auto-detection. This will take a while..."));
if (log) QList<ToolChain *> toolChains = autoDetectToolChains();
log->append(tr("Starting auto-detection. This will take a while...")); QList<BaseQtVersion *> qtVersions = autoDetectQtVersions();
QList<ToolChain *> toolChains = autoDetectToolChains(log); autoDetectCMake();
QList<BaseQtVersion *> qtVersions = autoDetectQtVersions(log); autoDetectDebugger();
autoDetectCMake(log);
autoDetectDebugger(log);
const auto initializeKit = [this, toolChains, qtVersions](Kit *k) { const auto initializeKit = [this, toolChains, qtVersions](Kit *k) {
k->setAutoDetected(false); k->setAutoDetected(false);
k->setAutoDetectionSource(m_data.id()); k->setAutoDetectionSource(m_sharedId);
k->setUnexpandedDisplayName("%{Device:Name}"); k->setUnexpandedDisplayName("%{Device:Name}");
DeviceTypeKitAspect::setDeviceTypeId(k, Constants::DOCKER_DEVICE_TYPE); DeviceTypeKitAspect::setDeviceTypeId(k, Constants::DOCKER_DEVICE_TYPE);
DeviceKitAspect::setDevice(k, q->sharedFromThis()); DeviceKitAspect::setDevice(k, m_device);
for (ToolChain *tc : toolChains) for (ToolChain *tc : toolChains)
ToolChainKitAspect::setToolChain(k, tc); ToolChainKitAspect::setToolChain(k, tc);
if (!qtVersions.isEmpty()) if (!qtVersions.isEmpty())
@@ -576,8 +604,7 @@ void DockerDevicePrivate::autoDetect(QTextBrowser *log)
}; };
Kit *kit = KitManager::registerKit(initializeKit); Kit *kit = KitManager::registerKit(initializeKit);
if (log) emit q->logOutput('\n' + tr("Registered kit %1").arg(kit->displayName()));
log->append('\n' + tr("Registered kit %1").arg(kit->displayName()));
QApplication::restoreOverrideCursor(); QApplication::restoreOverrideCursor();
} }
@@ -1037,15 +1064,19 @@ FilePath DockerDevice::searchInPath(const FilePath &filePath) const
return mapToGlobalPath(FilePath::fromString(output)); return mapToGlobalPath(FilePath::fromString(output));
} }
QList<FilePath> DockerDevice::directoryEntries(const FilePath &filePath, FilePaths DockerDevice::directoryEntries(const FilePath &filePath,
const QStringList &nameFilters, const QStringList &nameFilters,
QDir::Filters filters, QDir::Filters filters,
QDir::SortFlags sort) const QDir::SortFlags sort) const
{ {
QTC_ASSERT(handlesFile(filePath), return {}); QTC_ASSERT(handlesFile(filePath), return {});
tryCreateLocalFileAccess(); tryCreateLocalFileAccess();
if (hasLocalFileAccess()) if (hasLocalFileAccess()) {
return mapToLocalAccess(filePath).dirEntries(nameFilters, filters, sort); 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 QTC_CHECK(false); // FIXME: Implement
return {}; return {};
@@ -1112,7 +1143,8 @@ Environment DockerDevice::systemEnvironment() const
void DockerDevice::aboutToBeRemoved() const void DockerDevice::aboutToBeRemoved() const
{ {
d->undoAutoDetect(nullptr); KitDetector detector(sharedFromThis());
detector.undoAutoDetect(d->m_data.id());
} }
void DockerDevicePrivate::fetchSystemEnviroment() void DockerDevicePrivate::fetchSystemEnviroment()

View File

@@ -122,6 +122,24 @@ private:
friend class DockerDeviceWidget; 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 class DockerDeviceFactory final : public ProjectExplorer::IDeviceFactory
{ {
public: public:

View File

@@ -1085,7 +1085,7 @@ static QStringList normalLogArguments()
"--pretty=format:" "--pretty=format:"
"commit %C(%1)%H%Creset %C(%2)%d%Creset%n" "commit %C(%1)%H%Creset %C(%2)%d%Creset%n"
"Author: %C(%3)%an <%ae>%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" "%C(%5)%w(0,4,4)%s%Creset%n%n%b"
).arg(commitHash, decoration, authorName, commitDate, commitSubject); ).arg(commitHash, decoration, authorName, commitDate, commitSubject);

View File

@@ -39,10 +39,11 @@ using namespace LanguageServerProtocol;
using namespace TextEditor; using namespace TextEditor;
namespace LanguageClient { namespace LanguageClient {
namespace SemanticHighligtingSupport {
static Q_LOGGING_CATEGORY(LOGLSPHIGHLIGHT, "qtc.languageclient.highlight", QtWarningMsg); static Q_LOGGING_CATEGORY(LOGLSPHIGHLIGHT, "qtc.languageclient.highlight", QtWarningMsg);
namespace SemanticHighligtingSupport {
static const QList<QList<QString>> highlightScopes(const ServerCapabilities &capabilities) static const QList<QList<QString>> highlightScopes(const ServerCapabilities &capabilities)
{ {
return capabilities.semanticHighlighting() return capabilities.semanticHighlighting()
@@ -399,15 +400,27 @@ void SemanticTokenSupport::handleSemanticTokensDelta(
newData.reserve(newDataSize); newData.reserve(newDataSize);
auto it = data.begin(); auto it = data.begin();
const auto end = data.end();
for (const SemanticTokensEdit &edit : qAsConst(edits)) { for (const SemanticTokensEdit &edit : qAsConst(edits)) {
if (edit.start() > data.size()) // prevent edits after the previously reported data if (edit.start() > data.size()) // prevent edits after the previously reported data
return; return;
for (const auto start = data.begin() + edit.start(); it < start; ++it) for (const auto start = data.begin() + edit.start(); it < start; ++it)
newData.append(*it); newData.append(*it);
newData.append(edit.data().value_or(QList<int>())); newData.append(edit.data().value_or(QList<int>()));
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); newData.append(*it);
tokens.setData(newData); tokens.setData(newData);

View File

@@ -28,6 +28,8 @@
#include "nimconstants.h" #include "nimconstants.h"
#include "nimtoolchain.h" #include "nimtoolchain.h"
#include <projectexplorer/devicesupport/devicemanager.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/pathchooser.h> #include <utils/pathchooser.h>
@@ -52,11 +54,10 @@ NimToolChainFactory::NimToolChainFactory()
QList<ToolChain *> NimToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown, QList<ToolChain *> NimToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown,
const IDevice::Ptr &device) const IDevice::Ptr &device)
{ {
Q_UNUSED(device);
QList<ToolChain *> result; QList<ToolChain *> result;
Environment systemEnvironment = Environment::systemEnvironment(); IDevice::ConstPtr dev = device ? device : DeviceManager::defaultDesktopDevice();
const FilePath compilerPath = systemEnvironment.searchInPath("nim"); const FilePath compilerPath = dev->searchInPath(FilePath::fromString("nim"));
if (compilerPath.isEmpty()) if (compilerPath.isEmpty())
return result; return result;

View File

@@ -63,10 +63,8 @@ PerfTracePointDialog::PerfTracePointDialog() :
} }
if (!m_device) { if (!m_device) {
const DeviceManager *deviceManager = DeviceManager::instance();
// There should at least be a desktop device. // 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); QTC_ASSERT(m_device, return);
} }

View File

@@ -104,7 +104,7 @@ Runnable CustomExecutableRunConfiguration::runnable() const
r.setCommandLine(commandLine()); r.setCommandLine(commandLine());
r.environment = aspect<EnvironmentAspect>()->environment(); r.environment = aspect<EnvironmentAspect>()->environment();
r.workingDirectory = workingDirectory.toString(); r.workingDirectory = workingDirectory.toString();
r.device = DeviceManager::instance()->defaultDevice(Constants::DESKTOP_DEVICE_TYPE); r.device = DeviceManager::defaultDesktopDevice();
if (!r.executable.isEmpty()) { if (!r.executable.isEmpty()) {
const QString expanded = macroExpander()->expand(r.executable.toString()); const QString expanded = macroExpander()->expand(r.executable.toString());

View File

@@ -331,6 +331,11 @@ IDevice::ConstPtr DeviceManager::deviceForPath(const FilePath &path)
return {}; return {};
} }
IDevice::ConstPtr DeviceManager::defaultDesktopDevice()
{
return m_instance->defaultDevice(Constants::DESKTOP_DEVICE_TYPE);
}
void DeviceManager::setDefaultDevice(Utils::Id id) void DeviceManager::setDefaultDevice(Utils::Id id)
{ {
QTC_ASSERT(this != instance(), return); QTC_ASSERT(this != instance(), return);

View File

@@ -69,7 +69,9 @@ public:
void setDeviceState(Utils::Id deviceId, IDevice::DeviceState deviceState); void setDeviceState(Utils::Id deviceId, IDevice::DeviceState deviceState);
bool isLoaded() const; bool isLoaded() const;
static IDevice::ConstPtr deviceForPath(const Utils::FilePath &path); static IDevice::ConstPtr deviceForPath(const Utils::FilePath &path);
static IDevice::ConstPtr defaultDesktopDevice();
signals: signals:
void deviceAdded(Utils::Id id); void deviceAdded(Utils::Id id);

View File

@@ -1231,8 +1231,7 @@ BuildDeviceKitAspect::BuildDeviceKitAspect()
QVariant BuildDeviceKitAspect::defaultValue(const Kit *k) const QVariant BuildDeviceKitAspect::defaultValue(const Kit *k) const
{ {
Q_UNUSED(k); Q_UNUSED(k);
IDevice::ConstPtr defaultDevice = IDevice::ConstPtr defaultDevice = DeviceManager::defaultDesktopDevice();
DeviceManager::instance()->defaultDevice(Constants::DESKTOP_DEVICE_TYPE);
return defaultDevice->id().toString(); return defaultDevice->id().toString();
} }

View File

@@ -66,9 +66,9 @@ bool BaseConnectionManager::isActive() const
void BaseConnectionManager::showCannotConnectToPuppetWarningAndSwitchToEditMode() {} 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, void BaseConnectionManager::writeCommandToIODevice(const QVariant &command,

View File

@@ -64,7 +64,7 @@ protected:
void dispatchCommand(const QVariant &command, Connection &connection) override; void dispatchCommand(const QVariant &command, Connection &connection) override;
virtual void showCannotConnectToPuppetWarningAndSwitchToEditMode(); virtual void showCannotConnectToPuppetWarningAndSwitchToEditMode();
using ConnectionManagerInterface::processFinished; using ConnectionManagerInterface::processFinished;
void processFinished(); void processFinished(const QString &reason);
static void writeCommandToIODevice(const QVariant &command, static void writeCommandToIODevice(const QVariant &command,
QIODevice *ioDevice, QIODevice *ioDevice,
unsigned int commandCounter); unsigned int commandCounter);

View File

@@ -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()) { if (m_captureFileForTest.isOpen()) {
m_captureFileForTest.close(); m_captureFileForTest.close();
Core::AsynchronousMessageBox::warning( 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. " tr("You are recording a puppet stream and the emulations layer crashed. "
"It is recommended to reopen the Qt Quick Designer and start again.")); "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) void CapturingConnectionManager::writeCommand(const QVariant &command)

View File

@@ -39,7 +39,7 @@ public:
ProjectExplorer::Target *target, ProjectExplorer::Target *target,
AbstractView *view) override; 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; void writeCommand(const QVariant &command) override;

View File

@@ -69,7 +69,7 @@ void ConnectionManager::setUp(NodeInstanceServerInterface *nodeInstanceServerPro
socketToken, socketToken,
[&] { printProcessOutput(connection.qmlPuppetProcess.get(), connection.name); }, [&] { printProcessOutput(connection.qmlPuppetProcess.get(), connection.name); },
[&](int exitCode, QProcess::ExitStatus exitStatus) { [&](int exitCode, QProcess::ExitStatus exitStatus) {
processFinished(exitCode, exitStatus); processFinished(exitCode, exitStatus, connection.name);
}); });
const int second = 1000; const int second = 1000;
@@ -122,15 +122,10 @@ void ConnectionManager::writeCommand(const QVariant &command)
m_writeCommandCounter++; 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<QProcess *>(sender()); qWarning() << "Process" << connectionName <<(exitStatus == QProcess::CrashExit ? "crashed:" : "finished:")
if (finishedProcess) << "with exitCode:" << exitCode;
qWarning() << "Process" << (exitStatus == QProcess::CrashExit ? "crashed:" : "finished:")
<< finishedProcess->arguments() << "exitCode:" << exitCode;
else
qWarning() << "Process" << (exitStatus == QProcess::CrashExit ? "crashed:" : "finished:")
<< sender() << "exitCode:" << exitCode;
writeCommand(QVariant::fromValue(EndPuppetCommand())); writeCommand(QVariant::fromValue(EndPuppetCommand()));

View File

@@ -58,7 +58,7 @@ public:
protected: protected:
using BaseConnectionManager::processFinished; using BaseConnectionManager::processFinished;
void processFinished(int exitCode, QProcess::ExitStatus exitStatus) override; void processFinished(int exitCode, QProcess::ExitStatus exitStatus, const QString &connectionName) override;
std::vector<Connection> &connections() { return m_connections; } std::vector<Connection> &connections() { return m_connections; }
quint32 &writeCommandCounter() { return m_writeCommandCounter; } quint32 &writeCommandCounter() { return m_writeCommandCounter; }

View File

@@ -79,7 +79,7 @@ public:
protected: protected:
virtual void dispatchCommand(const QVariant &command, Connection &connection) = 0; 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 } // namespace QmlDesigner

View File

@@ -107,7 +107,7 @@ void InteractiveConnectionManager::puppetTimeout(Connection &connection)
return; return;
} }
processFinished(); processFinished(connection.name + "_timeout");
} }
void InteractiveConnectionManager::puppetAlive(Connection &connection) void InteractiveConnectionManager::puppetAlive(Connection &connection)

View File

@@ -452,7 +452,7 @@ static void filterOutQtBaseImportPath(QStringList *stringList)
{ {
Utils::erase(*stringList, [](const QString &string) { Utils::erase(*stringList, [](const QString &string) {
QDir dir(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();
}); });
} }

View File

@@ -18,5 +18,6 @@ RUN apt-get update \
g++ \ g++ \
gdb \ gdb \
ninja-build \ ninja-build \
nim \
&& apt-get clean \ && apt-get clean \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*

View File

@@ -957,6 +957,28 @@ TEST_F(ClangFormat, ChainedMemberFunctionCalls)
" .func();")); " .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 // clang-format on
} // namespace } // namespace