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)
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}"

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_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!)

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
const char IDE_SETTINGSVARIANT_STR[] = "${IDE_SETTINGSVARIANT}";
const char IDE_COPY_SETTINGS_FROM_VARIANT_STR[] = "${IDE_COPY_SETTINGSVARIANT}";
} // Constants
} // Core

View File

@@ -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

View File

@@ -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,

View File

@@ -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

View File

@@ -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.

View File

@@ -35,11 +35,14 @@
#include <QDebug>
#include <QDir>
#include <QFileInfo>
#include <QLoggingCategory>
#include <QMap>
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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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(),
@@ -296,7 +301,7 @@ int forceIndentWithExtraText(QByteArray &buffer,
const int prevEndOffset = Utils::Text::utf8NthLineOffset(block.document(), buffer,
block.blockNumber()) + block.previous().text().length();
buffer.insert(prevEndOffset, " //");
extraLength += 2;
extraLength += 3;
}
}
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
{
Q_DECLARE_TR_FUNCTIONS(Docker::Internal::DockerDevice)
@@ -255,14 +298,6 @@ public:
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();
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<DockerDevice>();
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<BaseQtVersion *> DockerDevicePrivate::autoDetectQtVersions(QTextBrowser *log) const
QList<BaseQtVersion *> KitDetectorPrivate::autoDetectQtVersions() const
{
QList<BaseQtVersion *> 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<ToolChain *> DockerDevicePrivate::autoDetectToolChains(QTextBrowser *log)
QList<ToolChain *> KitDetectorPrivate::autoDetectToolChains()
{
const QList<ToolChainFactory *> factories = ToolChainFactory::allToolChainFactories();
QList<ToolChain *> toolChains;
QApplication::processEvents();
log->append('\n' + tr("Searching tool chains..."));
emit q->logOutput('\n' + tr("Searching tool chains..."));
for (ToolChainFactory *factory : factories) {
const QList<ToolChain *> newToolChains = factory->autoDetect(toolChains, q->sharedFromThis());
log->append(tr("Searching tool chains of type %1").arg(factory->displayName()));
const QList<ToolChain *> newToolChains = factory->autoDetect(toolChains, m_device.constCast<IDevice>());
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<ToolChain *> toolChains = autoDetectToolChains();
QList<BaseQtVersion *> qtVersions = autoDetectQtVersions();
QList<ToolChain *> toolChains = autoDetectToolChains(log);
QList<BaseQtVersion *> 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<FilePath> DockerDevice::directoryEntries(const FilePath &filePath,
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()

View File

@@ -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:

View File

@@ -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<QList<QString>> 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<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;
}
for (const auto end = data.end(); it != end; ++it)
it += deleteCount;
}
for (; it != end; ++it)
newData.append(*it);
tokens.setData(newData);

View File

@@ -28,6 +28,8 @@
#include "nimconstants.h"
#include "nimtoolchain.h"
#include <projectexplorer/devicesupport/devicemanager.h>
#include <utils/algorithm.h>
#include <utils/environment.h>
#include <utils/pathchooser.h>
@@ -52,11 +54,10 @@ NimToolChainFactory::NimToolChainFactory()
QList<ToolChain *> NimToolChainFactory::autoDetect(const QList<ToolChain *> &alreadyKnown,
const IDevice::Ptr &device)
{
Q_UNUSED(device);
QList<ToolChain *> 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;

View File

@@ -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);
}

View File

@@ -104,7 +104,7 @@ Runnable CustomExecutableRunConfiguration::runnable() const
r.setCommandLine(commandLine());
r.environment = aspect<EnvironmentAspect>()->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());

View File

@@ -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);

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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,

View File

@@ -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);

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()) {
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)

View File

@@ -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;

View File

@@ -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<QProcess *>(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()));

View File

@@ -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<Connection> &connections() { return m_connections; }
quint32 &writeCommandCounter() { return m_writeCommandCounter; }

View File

@@ -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

View File

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

View File

@@ -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();
});
}

View File

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

View File

@@ -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