diff --git a/.github/workflows/build_cmake.yml b/.github/workflows/build_cmake.yml
index 3efc8a7b464..94fbb314343 100644
--- a/.github/workflows/build_cmake.yml
+++ b/.github/workflows/build_cmake.yml
@@ -3,7 +3,7 @@ name: CMake Build Matrix
on: [push, pull_request]
env:
- QT_VERSION: 6.2.0
+ QT_VERSION: 6.2.1
CLANG_VERSION: 130
ELFUTILS_VERSION: 0.175
CMAKE_VERSION: 3.21.1
diff --git a/scripts/common.py b/scripts/common.py
index 7b7936a8add..a04beb27efc 100644
--- a/scripts/common.py
+++ b/scripts/common.py
@@ -164,13 +164,13 @@ def fix_rpaths(path, qt_deploy_path, qt_install_info, chrpath=None):
if len(rpath) <= 0:
return
# remove previous Qt RPATH
- new_rpath = list(filter(lambda path: not path.startswith(qt_install_prefix) and not path.startswith(qt_install_libs),
- rpath))
+ new_rpath = [path for path in rpath if not path.startswith(qt_install_prefix)
+ and not path.startswith(qt_install_libs)]
# check for Qt linking
lddOutput = subprocess.check_output(['ldd', filepath])
lddDecodedOutput = lddOutput.decode(encoding) if encoding else lddOutput
- if lddDecodedOutput.find('libQt5') >= 0 or lddDecodedOutput.find('libicu') >= 0:
+ if lddDecodedOutput.find('libQt') >= 0 or lddDecodedOutput.find('libicu') >= 0:
# add Qt RPATH if necessary
relative_path = os.path.relpath(qt_deploy_path, os.path.dirname(filepath))
if relative_path == '.':
diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py
index 97b4544a50d..7bdb028eba3 100644
--- a/share/qtcreator/debugger/dumper.py
+++ b/share/qtcreator/debugger/dumper.py
@@ -1137,6 +1137,7 @@ class DumperBase():
'char',
'wchar_t',
'unsigned char',
+ 'uint8_t',
'signed char',
'CHAR',
'WCHAR'
@@ -1243,7 +1244,7 @@ class DumperBase():
if innerType.code == TypeCode.Typedef:
targetType = innerType.ltarget
- if targetType.name in ('char', 'signed char', 'unsigned char', 'CHAR'):
+ if targetType.name in ('char', 'signed char', 'unsigned char', 'uint8_t', 'CHAR'):
# Use UTF-8 as default for char *.
self.putType(typeName)
(elided, shown, data) = self.readToFirstZero(ptr, 1, limit)
@@ -1406,6 +1407,7 @@ class DumperBase():
'char',
'signed char',
'unsigned char',
+ 'uint8_t',
'wchar_t',
'CHAR',
'WCHAR'
@@ -3628,6 +3630,7 @@ class DumperBase():
'char': 'int:1',
'signed char': 'int:1',
'unsigned char': 'uint:1',
+ 'uint8_t': 'uint:1',
'short': 'int:2',
'unsigned short': 'uint:2',
'int': 'int:4',
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CharacterSection.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CharacterSection.qml
index 8dcee519706..127c7a38324 100644
--- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CharacterSection.qml
+++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/CharacterSection.qml
@@ -140,25 +140,6 @@ Section {
ExpandingSpacer {}
}
- PropertyLabel {
- text: qsTr("Weight")
- tooltip: qsTr("Font's weight.")
- }
-
- SecondColumnLayout {
- ComboBox {
- implicitWidth: StudioTheme.Values.singleControlColumnWidth
- + StudioTheme.Values.actionIndicatorWidth
- width: implicitWidth
- backendValue: getBackendValue("weight")
- model: ["Normal", "Light", "ExtraLight", "Thin", "Medium", "DemiBold", "Bold", "ExtraBold", "Black"]
- scope: "Font"
- enabled: !styleNameComboBox.styleSet
- }
-
- ExpandingSpacer {}
- }
-
PropertyLabel {
text: qsTr("Style name")
tooltip: qsTr("Font's style.")
@@ -267,7 +248,30 @@ Section {
supportGradient: false
}
- PropertyLabel { text: qsTr("Emphasis") }
+ PropertyLabel {
+ text: qsTr("Weight")
+ tooltip: qsTr("Font's weight.")
+ enabled: !styleNameComboBox.styleSet
+ }
+
+ SecondColumnLayout {
+ ComboBox {
+ implicitWidth: StudioTheme.Values.singleControlColumnWidth
+ + StudioTheme.Values.actionIndicatorWidth
+ width: implicitWidth
+ backendValue: getBackendValue("weight")
+ model: ["Normal", "Light", "ExtraLight", "Thin", "Medium", "DemiBold", "Bold", "ExtraBold", "Black"]
+ scope: "Font"
+ enabled: !styleNameComboBox.styleSet
+ }
+
+ ExpandingSpacer {}
+ }
+
+ PropertyLabel {
+ text: qsTr("Emphasis")
+ enabled: !styleNameComboBox.styleSet
+ }
FontStyleButtons {
bold: root.boldStyle
diff --git a/share/qtcreator/styles/grayscale.xml b/share/qtcreator/styles/grayscale.xml
index 39dabbff691..09a09f1ba93 100644
--- a/share/qtcreator/styles/grayscale.xml
+++ b/share/qtcreator/styles/grayscale.xml
@@ -35,6 +35,7 @@
+
diff --git a/src/libs/qmljs/qmljsdocument.cpp b/src/libs/qmljs/qmljsdocument.cpp
index 67087570c2c..e7762e4f9c5 100644
--- a/src/libs/qmljs/qmljsdocument.cpp
+++ b/src/libs/qmljs/qmljsdocument.cpp
@@ -632,6 +632,10 @@ LibraryInfo Snapshot::libraryInfo(const QString &path) const
return _libraries.value(QDir::cleanPath(path));
}
+LibraryInfo Snapshot::libraryInfo(const Utils::FilePath &path) const
+{
+ return _libraries.value(path.cleanPath().toString());
+}
void ModuleApiInfo::addToHash(QCryptographicHash &hash) const
{
diff --git a/src/libs/qmljs/qmljsdocument.h b/src/libs/qmljs/qmljsdocument.h
index c6d4cf7dcea..199b4670502 100644
--- a/src/libs/qmljs/qmljsdocument.h
+++ b/src/libs/qmljs/qmljsdocument.h
@@ -256,7 +256,8 @@ public:
Document::Ptr document(const QString &fileName) const;
QList documentsInDirectory(const QString &path) const;
- LibraryInfo libraryInfo(const QString &path) const;
+ LibraryInfo libraryInfo(const QString &path) const; // FIXME: Remove
+ LibraryInfo libraryInfo(const Utils::FilePath &path) const;
Document::MutablePtr documentFromSource(const QString &code,
const QString &fileName,
diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
index b7ed718a98d..1291b6525aa 100644
--- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
+++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
@@ -684,19 +684,19 @@ void ModelManagerInterface::updateDocument(const Document::Ptr &doc)
emit documentUpdated(doc);
}
-void ModelManagerInterface::updateLibraryInfo(const QString &path, const LibraryInfo &info)
+void ModelManagerInterface::updateLibraryInfo(const FilePath &path, const LibraryInfo &info)
{
if (!info.pluginTypeInfoError().isEmpty())
qCDebug(qmljsLog) << "Dumping errors for " << path << ":" << info.pluginTypeInfoError();
{
QMutexLocker locker(&m_mutex);
- m_validSnapshot.insertLibraryInfo(path, info);
- m_newestSnapshot.insertLibraryInfo(path, info);
+ m_validSnapshot.insertLibraryInfo(path.toString(), info);
+ m_newestSnapshot.insertLibraryInfo(path.toString(), info);
}
// only emit if we got new useful information
if (info.isValid())
- emit libraryInfoUpdated(path, info);
+ emit libraryInfoUpdated(path.toString(), info);
}
static QStringList filesInDirectoryForLanguages(const QString &path,
@@ -773,7 +773,7 @@ enum class LibraryStatus {
Unknown
};
-static LibraryStatus libraryStatus(const QString &path, const Snapshot &snapshot,
+static LibraryStatus libraryStatus(const FilePath &path, const Snapshot &snapshot,
QSet *newLibraries)
{
if (path.isEmpty())
@@ -782,7 +782,7 @@ static LibraryStatus libraryStatus(const QString &path, const Snapshot &snapshot
const LibraryInfo &existingInfo = snapshot.libraryInfo(path);
if (existingInfo.isValid())
return LibraryStatus::Accepted;
- if (newLibraries->contains(path))
+ if (newLibraries->contains(path.toString()))
return LibraryStatus::Accepted;
// if we looked at the path before, done
return existingInfo.wasScanned()
@@ -790,7 +790,7 @@ static LibraryStatus libraryStatus(const QString &path, const Snapshot &snapshot
: LibraryStatus::Unknown;
}
-static bool findNewQmlApplicationInPath(const QString &path,
+static bool findNewQmlApplicationInPath(const FilePath &path,
const Snapshot &snapshot,
ModelManagerInterface *modelManager,
QSet *newLibraries)
@@ -803,8 +803,8 @@ static bool findNewQmlApplicationInPath(const QString &path,
QString qmltypesFile;
- QDir dir(path);
- QDirIterator it(path, QStringList { "*.qmltypes" }, QDir::Files);
+ QDir dir(path.toString());
+ QDirIterator it(path.toString(), QStringList { "*.qmltypes" }, QDir::Files);
if (!it.hasNext())
return false;
@@ -828,7 +828,7 @@ static bool findNewQmlLibraryInPath(const QString &path,
QSet *newLibraries,
bool ignoreMissing)
{
- switch (libraryStatus(path, snapshot, newLibraries)) {
+ switch (libraryStatus(FilePath::fromString(path), snapshot, newLibraries)) {
case LibraryStatus::Accepted: return true;
case LibraryStatus::Rejected: return false;
default: break;
@@ -839,7 +839,7 @@ static bool findNewQmlLibraryInPath(const QString &path,
if (!qmldirFile.exists()) {
if (!ignoreMissing) {
LibraryInfo libraryInfo(LibraryInfo::NotFound);
- modelManager->updateLibraryInfo(path, libraryInfo);
+ modelManager->updateLibraryInfo(FilePath::fromString(path), libraryInfo);
}
return false;
}
@@ -858,7 +858,7 @@ static bool findNewQmlLibraryInPath(const QString &path,
const QString libraryPath = QFileInfo(qmldirFile).absolutePath();
newLibraries->insert(libraryPath);
- modelManager->updateLibraryInfo(libraryPath, LibraryInfo(qmldirParser));
+ modelManager->updateLibraryInfo(FilePath::fromString(libraryPath), LibraryInfo(qmldirParser));
modelManager->loadPluginTypes(QFileInfo(libraryPath).canonicalFilePath(), libraryPath,
QString(), QString());
@@ -1252,7 +1252,7 @@ void ModelManagerInterface::updateImportPaths()
for (const Document::Ptr &doc : qAsConst(snapshot))
findNewLibraryImports(doc, snapshot, this, &importedFiles, &scannedPaths, &newLibraries);
for (const QString &path : qAsConst(allApplicationDirectories))
- findNewQmlApplicationInPath(path, snapshot, this, &newLibraries);
+ findNewQmlApplicationInPath(FilePath::fromString(path), snapshot, this, &newLibraries);
updateSourceFiles(importedFiles, true);
@@ -1433,7 +1433,7 @@ LibraryInfo ModelManagerInterface::builtins(const Document::Ptr &doc) const
{
const ProjectInfo info = projectInfoForPath(doc->fileName());
if (!info.qtQmlPath.isEmpty())
- return m_validSnapshot.libraryInfo(info.qtQmlPath.toString());
+ return m_validSnapshot.libraryInfo(info.qtQmlPath);
return LibraryInfo();
}
diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.h b/src/libs/qmljs/qmljsmodelmanagerinterface.h
index 1fc9260ae94..5a4f711a1be 100644
--- a/src/libs/qmljs/qmljsmodelmanagerinterface.h
+++ b/src/libs/qmljs/qmljsmodelmanagerinterface.h
@@ -156,7 +156,7 @@ public:
void updateProjectInfo(const ProjectInfo &pinfo, ProjectExplorer::Project *p);
void updateDocument(const QmlJS::Document::Ptr& doc);
- void updateLibraryInfo(const QString &path, const QmlJS::LibraryInfo &info);
+ void updateLibraryInfo(const Utils::FilePath &path, const QmlJS::LibraryInfo &info);
void emitDocumentChangedOnDisk(QmlJS::Document::Ptr doc);
void updateQrcFile(const QString &path);
ProjectInfo projectInfoForPath(const QString &path) const;
diff --git a/src/libs/qmljs/qmljsplugindumper.cpp b/src/libs/qmljs/qmljsplugindumper.cpp
index c8b80fafa56..a51929566ba 100644
--- a/src/libs/qmljs/qmljsplugindumper.cpp
+++ b/src/libs/qmljs/qmljsplugindumper.cpp
@@ -89,25 +89,23 @@ void PluginDumper::onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::Projec
if (info.qmlDumpPath.isEmpty() || info.qtQmlPath.isEmpty())
return;
- // FIXME: This doesn't work for non-local paths.
- const QString importsPath = QDir::cleanPath(info.qtQmlPath.toString());
- if (m_runningQmldumps.values().contains(importsPath))
+ if (m_runningQmldumps.values().contains(info.qmlDumpPath))
return;
LibraryInfo builtinInfo;
if (!force) {
const Snapshot snapshot = m_modelManager->snapshot();
- builtinInfo = snapshot.libraryInfo(info.qtQmlPath.toString());
+ builtinInfo = snapshot.libraryInfo(info.qtQmlPath);
if (builtinInfo.isValid())
return;
}
builtinInfo = LibraryInfo(LibraryInfo::Found);
- m_modelManager->updateLibraryInfo(info.qtQmlPath.toString(), builtinInfo);
+ m_modelManager->updateLibraryInfo(info.qtQmlPath, builtinInfo);
// prefer QTDIR/qml/builtins.qmltypes if available
- const QString builtinQmltypesPath = info.qtQmlPath.toString() + QLatin1String("/builtins.qmltypes");
- if (QFile::exists(builtinQmltypesPath)) {
- loadQmltypesFile(QStringList(builtinQmltypesPath), info.qtQmlPath.toString(), builtinInfo);
+ const FilePath builtinQmltypesPath = info.qtQmlPath / "builtins.qmltypes";
+ if (builtinQmltypesPath.exists()) {
+ loadQmltypesFile({builtinQmltypesPath}, info.qtQmlPath, builtinInfo);
return;
}
@@ -115,16 +113,9 @@ void PluginDumper::onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::Projec
m_qtToInfo.insert(info.qtQmlPath.toString(), info);
}
-static QString makeAbsolute(const QString &path, const QString &base)
-{
- if (QFileInfo(path).isAbsolute())
- return path;
- return QString::fromLatin1("%1/%3").arg(base, path);
-}
-
void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &importPath, const QString &importUri, const QString &importVersion)
{
- const QString canonicalLibraryPath = QDir::cleanPath(libraryPath);
+ const FilePath canonicalLibraryPath = FilePath::fromUserInput(libraryPath).cleanPath();
if (m_runningQmldumps.values().contains(canonicalLibraryPath))
return;
const Snapshot snapshot = m_modelManager->snapshot();
@@ -135,7 +126,7 @@ void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &
// avoid inserting the same plugin twice
int index;
for (index = 0; index < m_plugins.size(); ++index) {
- if (m_plugins.at(index).qmldirPath == libraryPath)
+ if (m_plugins.at(index).qmldirPath == canonicalLibraryPath)
break;
}
if (index == m_plugins.size())
@@ -148,10 +139,10 @@ void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &
plugin.importVersion = importVersion;
// add default qmltypes file if it exists
- QDirIterator it(canonicalLibraryPath, QStringList { "*.qmltypes" }, QDir::Files);
+ QDirIterator it(canonicalLibraryPath.toString(), QStringList { "*.qmltypes" }, QDir::Files);
while (it.hasNext()) {
- const QString defaultQmltypesPath = makeAbsolute(it.next(), canonicalLibraryPath);
+ const FilePath defaultQmltypesPath = canonicalLibraryPath.resolvePath(it.next());
if (!plugin.typeInfoPaths.contains(defaultQmltypesPath))
plugin.typeInfoPaths += defaultQmltypesPath;
@@ -159,29 +150,29 @@ void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &
// add typeinfo files listed in qmldir
foreach (const QString &typeInfo, libraryInfo.typeInfos()) {
- QString pathNow = makeAbsolute(typeInfo, canonicalLibraryPath);
- if (!plugin.typeInfoPaths.contains(pathNow) && QFile::exists(pathNow))
+ const FilePath pathNow = canonicalLibraryPath.resolvePath(typeInfo);
+ if (!plugin.typeInfoPaths.contains(pathNow) && pathNow.exists())
plugin.typeInfoPaths += pathNow;
}
// watch plugin libraries
foreach (const QmlDirParser::Plugin &plugin, snapshot.libraryInfo(canonicalLibraryPath).plugins()) {
- const QString pluginLibrary = resolvePlugin(canonicalLibraryPath, plugin.path, plugin.name);
+ const QString pluginLibrary = resolvePlugin(canonicalLibraryPath.toString(), plugin.path, plugin.name);
if (!pluginLibrary.isEmpty()) {
if (!pluginWatcher()->watchesFile(pluginLibrary))
- pluginWatcher()->addFile(pluginLibrary, Utils::FileSystemWatcher::WatchModifiedDate);
+ pluginWatcher()->addFile(pluginLibrary, FileSystemWatcher::WatchModifiedDate);
m_libraryToPluginIndex.insert(pluginLibrary, index);
}
}
// watch library qmltypes file
if (!plugin.typeInfoPaths.isEmpty()) {
- foreach (const QString &path, plugin.typeInfoPaths) {
- if (!QFile::exists(path))
+ for (const FilePath &path : qAsConst(plugin.typeInfoPaths)) {
+ if (!path.exists())
continue;
- if (!pluginWatcher()->watchesFile(path))
- pluginWatcher()->addFile(path, Utils::FileSystemWatcher::WatchModifiedDate);
- m_libraryToPluginIndex.insert(path, index);
+ if (!pluginWatcher()->watchesFile(path.toString()))
+ pluginWatcher()->addFile(path.toString(), FileSystemWatcher::WatchModifiedDate);
+ m_libraryToPluginIndex.insert(path.toString(), index);
}
}
@@ -195,26 +186,25 @@ void PluginDumper::dumpAllPlugins()
}
}
-static QString noTypeinfoError(const QString &libraryPath)
+static QString noTypeinfoError(const FilePath &libraryPath)
{
return PluginDumper::tr("QML module does not contain information about components contained in plugins.\n\n"
"Module path: %1\n"
"See \"Using QML Modules with Plugins\" in the documentation.").arg(
- libraryPath);
+ libraryPath.toUserOutput());
}
-static QString qmldumpErrorMessage(const QString &libraryPath, const QString &error)
+static QString qmldumpErrorMessage(const FilePath &libraryPath, const QString &error)
{
- return noTypeinfoError(libraryPath) + QLatin1String("\n\n") +
+ return noTypeinfoError(libraryPath) + "\n\n" +
PluginDumper::tr("Automatic type dump of QML module failed.\nErrors:\n%1").
arg(error) + QLatin1Char('\n');
}
-static QString qmldumpFailedMessage(const QString &libraryPath, const QString &error)
+static QString qmldumpFailedMessage(const FilePath &libraryPath, const QString &error)
{
- QString firstLines =
- QStringList(error.split(QLatin1Char('\n')).mid(0, 10)).join(QLatin1Char('\n'));
- return noTypeinfoError(libraryPath) + QLatin1String("\n\n") +
+ QString firstLines = QStringList(error.split('\n').mid(0, 10)).join('\n');
+ return noTypeinfoError(libraryPath) + "\n\n" +
PluginDumper::tr("Automatic type dump of QML module failed.\n"
"First 10 lines or errors:\n"
"\n"
@@ -224,11 +214,11 @@ static QString qmldumpFailedMessage(const QString &libraryPath, const QString &e
).arg(firstLines);
}
-static void printParseWarnings(const QString &libraryPath, const QString &warning)
+static void printParseWarnings(const FilePath &libraryPath, const QString &warning)
{
ModelManagerInterface::writeWarning(
PluginDumper::tr("Warnings while parsing QML type information of %1:\n"
- "%2").arg(libraryPath, warning));
+ "%2").arg(libraryPath.toUserOutput(), warning));
}
static QString qmlPluginDumpErrorMessage(QtcProcess *process)
@@ -269,7 +259,7 @@ void PluginDumper::qmlPluginTypeDumpDone(QtcProcess *process)
{
process->deleteLater();
- const QString libraryPath = m_runningQmldumps.take(process);
+ const FilePath libraryPath = m_runningQmldumps.take(process);
if (libraryPath.isEmpty())
return;
const Snapshot snapshot = m_modelManager->snapshot();
@@ -298,7 +288,7 @@ void PluginDumper::qmlPluginTypeDumpDone(QtcProcess *process)
CppQmlTypesInfo infos;
CppQmlTypesLoader::parseQmlTypeDescriptions(output, &infos.objectsList, &infos.moduleApis, &infos.dependencies,
&infos.error, &infos.warning,
- QLatin1String("'));
+ "');
future.reportFinished(&infos);
});
m_modelManager->addFuture(future);
@@ -338,13 +328,13 @@ void PluginDumper::qmlPluginTypeDumpError(QtcProcess *process)
{
process->deleteLater();
- const QString libraryPath = m_runningQmldumps.take(process);
+ const FilePath libraryPath = m_runningQmldumps.take(process);
if (libraryPath.isEmpty())
return;
const QString errorMessages = qmlPluginDumpErrorMessage(process);
const Snapshot snapshot = m_modelManager->snapshot();
LibraryInfo libraryInfo = snapshot.libraryInfo(libraryPath);
- if (!libraryPath.endsWith(QLatin1String("private"), Qt::CaseInsensitive))
+ if (!libraryPath.path().endsWith(QLatin1String("private"), Qt::CaseInsensitive))
ModelManagerInterface::writeWarning(qmldumpErrorMessage(libraryPath, errorMessages));
libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, qmldumpFailedMessage(libraryPath, errorMessages));
libraryInfo.updateFingerprint();
@@ -361,14 +351,15 @@ void PluginDumper::pluginChanged(const QString &pluginLibrary)
dump(plugin);
}
-QFuture PluginDumper::loadQmlTypeDescription(const QStringList &paths) const {
+QFuture PluginDumper::loadQmlTypeDescription(const FilePaths &paths) const
+{
auto future = Utils::runAsync([=](QFutureInterface &future)
{
PluginDumper::QmlTypeDescription result;
- for (const QString &p: paths) {
+ for (const FilePath &p: paths) {
Utils::FileReader reader;
- if (!reader.fetch(Utils::FilePath::fromString(p), QFile::Text)) {
+ if (!reader.fetch(p, QFile::Text)) {
result.errors += reader.errorString();
continue;
}
@@ -378,9 +369,9 @@ QFuture PluginDumper::loadQmlTypeDescription(c
QList apis;
QStringList deps;
CppQmlTypesLoader::parseQmlTypeDescriptions(reader.data(), &objs, &apis, &deps,
- &error, &warning, p);
+ &error, &warning, p.toString());
if (!error.isEmpty()) {
- result.errors += tr("Failed to parse \"%1\".\nError: %2").arg(p, error);
+ result.errors += tr("Failed to parse \"%1\".\nError: %2").arg(p.toUserOutput(), error);
} else {
result.objects += objs.values();
result.moduleApis += apis;
@@ -444,27 +435,26 @@ QString PluginDumper::buildQmltypesPath(const QString &name) const
* Recursively load type descriptions of dependencies, collecting results
* in \a objects.
*/
-QFuture PluginDumper::loadDependencies(const QStringList &dependencies,
- QSharedPointer> visited) const
+QFuture PluginDumper::loadDependencies(const FilePaths &dependencies,
+ QSharedPointer> visited) const
{
auto iface = QSharedPointer>(new QFutureInterface);
- if (visited.isNull()) {
- visited = QSharedPointer>(new QSet());
- }
+ if (visited.isNull())
+ visited = QSharedPointer>(new QSet());
- QStringList dependenciesPaths;
+ FilePaths dependenciesPaths;
QString path;
- for (const QString &name: dependencies) {
- path = buildQmltypesPath(name);
+ for (const FilePath &name : dependencies) {
+ path = buildQmltypesPath(name.toString());
if (!path.isNull())
- dependenciesPaths << path;
+ dependenciesPaths << FilePath::fromString(path);
visited->insert(name);
}
Utils::onFinished(loadQmlTypeDescription(dependenciesPaths), const_cast(this), [=] (const QFuture &typesFuture) {
PluginDumper::QmlTypeDescription typesResult = typesFuture.result();
- QStringList newDependencies = typesResult.dependencies;
+ FilePaths newDependencies = Utils::transform(typesResult.dependencies, &FilePath::fromString);
newDependencies = Utils::toList(Utils::toSet(newDependencies) - *visited.data());
if (!newDependencies.isEmpty()) {
Utils::onFinished(loadDependencies(newDependencies, visited),
@@ -564,7 +554,7 @@ static void applyQt515MissingImportWorkaround(const QString &path, LibraryInfo &
}
void PluginDumper::prepareLibraryInfo(LibraryInfo &libInfo,
- const QString &libraryPath,
+ const FilePath &libraryPath,
const QStringList &deps,
const QStringList &errors,
const QStringList &warnings,
@@ -588,13 +578,13 @@ void PluginDumper::prepareLibraryInfo(LibraryInfo &libInfo,
if (!warnings.isEmpty())
printParseWarnings(libraryPath, warnings.join(QLatin1String("\n")));
- applyQt515MissingImportWorkaround(libraryPath, libInfo);
+ applyQt515MissingImportWorkaround(libraryPath.toString(), libInfo);
libInfo.updateFingerprint();
}
-void PluginDumper::loadQmltypesFile(const QStringList &qmltypesFilePaths,
- const QString &libraryPath,
+void PluginDumper::loadQmltypesFile(const FilePaths &qmltypesFilePaths,
+ const FilePath &libraryPath,
QmlJS::LibraryInfo libraryInfo)
{
Utils::onFinished(loadQmlTypeDescription(qmltypesFilePaths), this, [=](const QFuture &typesFuture)
@@ -602,7 +592,8 @@ void PluginDumper::loadQmltypesFile(const QStringList &qmltypesFilePaths,
PluginDumper::QmlTypeDescription typesResult = typesFuture.result();
if (!typesResult.dependencies.isEmpty())
{
- Utils::onFinished(loadDependencies(typesResult.dependencies, QSharedPointer>()), this,
+ Utils::onFinished(loadDependencies(Utils::transform(typesResult.dependencies, &FilePath::fromString),
+ QSharedPointer>()), this,
[typesResult, libraryInfo, libraryPath, this] (const QFuture &loadFuture)
{
PluginDumper::DependencyInfo loadResult = loadFuture.result();
@@ -640,7 +631,7 @@ void PluginDumper::runQmlDump(const ModelManagerInterface::ProjectInfo &info,
connect(process, &QtcProcess::finished, this, [this, process] { qmlPluginTypeDumpDone(process); });
connect(process, &QtcProcess::errorOccurred, this, [this, process] { qmlPluginTypeDumpError(process); });
process->start();
- m_runningQmldumps.insert(process, importPath.toString());
+ m_runningQmldumps.insert(process, importPath);
}
void PluginDumper::dump(const Plugin &plugin)
@@ -686,7 +677,7 @@ void PluginDumper::dump(const Plugin &plugin)
args << plugin.importUri;
args << plugin.importVersion;
args << (plugin.importPath.isEmpty() ? QLatin1String(".") : plugin.importPath);
- runQmlDump(info, args, FilePath::fromString(plugin.qmldirPath));
+ runQmlDump(info, args, plugin.qmldirPath);
}
/*!
diff --git a/src/libs/qmljs/qmljsplugindumper.h b/src/libs/qmljs/qmljsplugindumper.h
index 98aadfbce40..3503c046810 100644
--- a/src/libs/qmljs/qmljsplugindumper.h
+++ b/src/libs/qmljs/qmljsplugindumper.h
@@ -65,11 +65,11 @@ private:
private:
class Plugin {
public:
- QString qmldirPath;
+ Utils::FilePath qmldirPath;
QString importPath;
QString importUri;
QString importVersion;
- QStringList typeInfoPaths;
+ Utils::FilePaths typeInfoPaths;
};
class QmlTypeDescription {
@@ -91,14 +91,14 @@ private:
void runQmlDump(const QmlJS::ModelManagerInterface::ProjectInfo &info, const QStringList &arguments,
const Utils::FilePath &importPath);
void dump(const Plugin &plugin);
- QFuture loadQmlTypeDescription(const QStringList &path) const;
+ QFuture loadQmlTypeDescription(const Utils::FilePaths &path) const;
QString buildQmltypesPath(const QString &name) const;
- QFuture loadDependencies(const QStringList &dependencies,
- QSharedPointer> visited) const;
+ QFuture loadDependencies(const Utils::FilePaths &dependencies,
+ QSharedPointer > visited) const;
- void loadQmltypesFile(const QStringList &qmltypesFilePaths,
- const QString &libraryPath,
+ void loadQmltypesFile(const Utils::FilePaths &qmltypesFilePaths,
+ const Utils::FilePath &libraryPath,
QmlJS::LibraryInfo libraryInfo);
QString resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
const QString &baseName);
@@ -109,7 +109,7 @@ private:
private:
Utils::FileSystemWatcher *pluginWatcher();
void prepareLibraryInfo(LibraryInfo &libInfo,
- const QString &libraryPath,
+ const Utils::FilePath &libraryPath,
const QStringList &deps,
const QStringList &errors,
const QStringList &warnings,
@@ -118,7 +118,7 @@ private:
ModelManagerInterface *m_modelManager;
Utils::FileSystemWatcher *m_pluginWatcher;
- QHash m_runningQmldumps;
+ QHash m_runningQmldumps;
QList m_plugins;
QHash m_libraryToPluginIndex;
QHash m_qtToInfo;
diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp
index e17f140868d..35af5b94c1d 100644
--- a/src/libs/utils/filepath.cpp
+++ b/src/libs/utils/filepath.cpp
@@ -440,7 +440,7 @@ FilePath FilePath::fromFileInfo(const QFileInfo &info)
QFileInfo FilePath::toFileInfo() const
{
QTC_ASSERT(!needsDevice(), return QFileInfo());
- return QFileInfo(m_data);
+ return QFileInfo(cleanPath().path());
}
FilePath FilePath::fromUrl(const QUrl &url)
diff --git a/src/libs/utils/multitextcursor.cpp b/src/libs/utils/multitextcursor.cpp
index 7a6e20f1b08..c06eb95f186 100644
--- a/src/libs/utils/multitextcursor.cpp
+++ b/src/libs/utils/multitextcursor.cpp
@@ -125,7 +125,9 @@ bool MultiTextCursor::hasSelection() const
QString MultiTextCursor::selectedText() const
{
QString text;
- for (const QTextCursor &cursor : m_cursors) {
+ QList cursors = m_cursors;
+ Utils::sort(cursors);
+ for (const QTextCursor &cursor : cursors) {
const QString &cursorText = cursor.selectedText();
if (cursorText.isEmpty())
continue;
@@ -169,7 +171,9 @@ void MultiTextCursor::insertText(const QString &text, bool selectNewText)
lines.pop_back();
int index = 0;
if (lines.count() == m_cursors.count()) {
- for (QTextCursor &cursor : m_cursors)
+ QList cursors = m_cursors;
+ Utils::sort(cursors);
+ for (QTextCursor &cursor : cursors)
insertAndSelect(cursor, lines.at(index++), selectNewText);
m_cursors.last().endEditBlock();
return;
diff --git a/src/plugins/android/androiddevice.cpp b/src/plugins/android/androiddevice.cpp
index 3d4376a98fd..600c285edf8 100644
--- a/src/plugins/android/androiddevice.cpp
+++ b/src/plugins/android/androiddevice.cpp
@@ -90,7 +90,8 @@ AndroidDeviceWidget::AndroidDeviceWidget(const IDevice::Ptr &device)
formLayout->addRow(AndroidDevice::tr("Device type:"), new QLabel(dev->deviceTypeName()));
const QString serialNumber = dev->serialNumber();
- const QString printableSerialNumber = serialNumber.isEmpty() ? tr("Unknown") : serialNumber;
+ const QString printableSerialNumber = serialNumber.isEmpty() ? AndroidDevice::tr("Unknown")
+ : serialNumber;
formLayout->addRow(AndroidDevice::tr("Serial number:"), new QLabel(printableSerialNumber));
const QString abis = dev->supportedAbis().join(", ");
@@ -100,8 +101,9 @@ AndroidDeviceWidget::AndroidDeviceWidget(const IDevice::Ptr &device)
formLayout->addRow(AndroidDevice::tr("OS version:"), new QLabel(osString));
if (dev->machineType() == IDevice::Hardware) {
- const QString authorizedStr = dev->deviceState() == IDevice::DeviceReadyToUse ? tr("Yes")
- : tr("No");
+ const QString authorizedStr = dev->deviceState() == IDevice::DeviceReadyToUse
+ ? AndroidDevice::tr("Yes")
+ : AndroidDevice::tr("No");
formLayout->addRow(AndroidDevice::tr("Authorized:"), new QLabel(authorizedStr));
}
@@ -117,7 +119,7 @@ AndroidDeviceWidget::AndroidDeviceWidget(const IDevice::Ptr &device)
QString AndroidDeviceWidget::dialogTitle()
{
- return tr("Android Device Manager");
+ return AndroidDevice::tr("Android Device Manager");
}
bool AndroidDeviceWidget::criticalDialog(const QString &error, QWidget *parent)
@@ -480,7 +482,8 @@ void AndroidDeviceManager::eraseAvd(const IDevice::Ptr &device, QWidget *parent)
return;
const QString name = static_cast(device.data())->avdName();
- const QString question = tr("Erase the Android AVD \"%1\"?\nThis cannot be undone.").arg(name);
+ const QString question
+ = AndroidDevice::tr("Erase the Android AVD \"%1\"?\nThis cannot be undone.").arg(name);
if (!AndroidDeviceWidget::questionDialog(question, parent))
return;
@@ -515,9 +518,10 @@ void AndroidDeviceManager::setEmulatorArguments(QWidget *parent)
"https://developer.android.com/studio/run/emulator-commandline#startup-options";
QInputDialog dialog(parent ? parent : Core::ICore::dialogParent());
- dialog.setWindowTitle(tr("Emulator Command-line Startup Options"));
- dialog.setLabelText(tr("Emulator command-line startup options "
- "(Help Web Page):").arg(helpUrl));
+ dialog.setWindowTitle(AndroidDevice::tr("Emulator Command-line Startup Options"));
+ dialog.setLabelText(AndroidDevice::tr("Emulator command-line startup options "
+ "(Help Web Page):")
+ .arg(helpUrl));
dialog.setTextValue(m_androidConfig.emulatorArgs().join(' '));
if (auto label = dialog.findChild()) {
diff --git a/src/plugins/android/androidrunnerworker.cpp b/src/plugins/android/androidrunnerworker.cpp
index 759eba59e46..aa88fdc903c 100644
--- a/src/plugins/android/androidrunnerworker.cpp
+++ b/src/plugins/android/androidrunnerworker.cpp
@@ -327,7 +327,7 @@ AndroidRunnerWorker::~AndroidRunnerWorker()
}
bool AndroidRunnerWorker::runAdb(const QStringList &args, QString *stdOut,
- const QByteArray &writeData)
+ QString *stdErr, const QByteArray &writeData)
{
QStringList adbArgs = selector() + args;
SdkToolResult result = AndroidManager::runAdbCommand(adbArgs, writeData);
@@ -335,6 +335,8 @@ bool AndroidRunnerWorker::runAdb(const QStringList &args, QString *stdOut,
emit remoteErrorOutput(result.stdErr());
if (stdOut)
*stdOut = result.stdOut();
+ if (stdErr)
+ *stdErr = result.stdErr();
return result.success();
}
@@ -651,10 +653,17 @@ void AndroidRunnerWorker::asyncStartHelper()
.toUtf8().toBase64());
}
- if (!runAdb(args)) {
+ QString stdErr;
+ const bool startResult = runAdb(args, nullptr, &stdErr);
+ if (!startResult) {
emit remoteProcessFinished(tr("Failed to start the activity."));
return;
}
+
+ if (!stdErr.isEmpty()) {
+ emit remoteErrorOutput(tr("Activity Manager threw the error: %1").arg(stdErr));
+ return;
+ }
}
bool AndroidRunnerWorker::startDebuggerServer(const QString &packageDir,
diff --git a/src/plugins/android/androidrunnerworker.h b/src/plugins/android/androidrunnerworker.h
index 68b9ca9c0ec..f4ceb9e8caa 100644
--- a/src/plugins/android/androidrunnerworker.h
+++ b/src/plugins/android/androidrunnerworker.h
@@ -47,7 +47,8 @@ public:
AndroidRunnerWorker(ProjectExplorer::RunWorker *runner, const QString &packageName);
~AndroidRunnerWorker() override;
- bool runAdb(const QStringList &args, QString *stdOut = nullptr, const QByteArray &writeData = {});
+ bool runAdb(const QStringList &args, QString *stdOut = nullptr, QString *stdErr = nullptr,
+ const QByteArray &writeData = {});
void adbKill(qint64 pid);
QStringList selector() const;
void forceStop();
diff --git a/src/plugins/clangcodemodel/clangdclient.cpp b/src/plugins/clangcodemodel/clangdclient.cpp
index 0c6b16e2bc9..7c811681556 100644
--- a/src/plugins/clangcodemodel/clangdclient.cpp
+++ b/src/plugins/clangcodemodel/clangdclient.cpp
@@ -1302,15 +1302,25 @@ void ClangdClient::findUsages(TextDocument *document, const QTextCursor &cursor,
const Utils::optional &replacement)
{
// Quick check: Are we even on anything searchable?
- if (d->searchTermFromCursor(cursor).isEmpty())
+ const QString searchTerm = d->searchTermFromCursor(cursor);
+ if (searchTerm.isEmpty())
return;
- // Get the proper spelling of the search term from clang, so we can put it into the
+ const bool categorize = CppEditor::codeModelSettings()->categorizeFindReferences();
+
+ // If it's a "normal" symbol, go right ahead.
+ if (searchTerm != "operator" && Utils::allOf(searchTerm, [](const QChar &c) {
+ return c.isLetterOrNumber() || c == '_';
+ })) {
+ d->findUsages(document, cursor, searchTerm, replacement, categorize);
+ return;
+ }
+
+ // Otherwise get the proper spelling of the search term from clang, so we can put it into the
// search widget.
const TextDocumentIdentifier docId(DocumentUri::fromFilePath(document->filePath()));
const TextDocumentPositionParams params(docId, Range(cursor).start());
SymbolInfoRequest symReq(params);
- const bool categorize = CppEditor::codeModelSettings()->categorizeFindReferences();
symReq.setResponseCallback([this, doc = QPointer(document), cursor, replacement, categorize]
(const SymbolInfoRequest::Response &response) {
if (!doc)
@@ -2442,7 +2452,7 @@ static void semanticHighlighter(QFutureInterface &future,
} else if (token.type == "comment") { // "comment" means code disabled via the preprocessor
styles.mainStyle = C_DISABLED_CODE;
} else if (token.type == "namespace") {
- styles.mainStyle = C_TYPE;
+ styles.mainStyle = C_NAMESPACE;
} else if (token.type == "property") {
styles.mainStyle = C_FIELD;
} else if (token.type == "enum") {
@@ -2463,6 +2473,8 @@ static void semanticHighlighter(QFutureInterface &future,
}
if (token.modifiers.contains("declaration"))
styles.mixinStyles.push_back(C_DECLARATION);
+ if (token.modifiers.contains("static"))
+ styles.mixinStyles.push_back(C_STATIC_MEMBER);
if (isOutputParameter(token))
styles.mixinStyles.push_back(C_OUTPUT_ARGUMENT);
qCDebug(clangdLogHighlight) << "adding highlighting result"
diff --git a/src/plugins/clangcodemodel/test/clangdtests.cpp b/src/plugins/clangcodemodel/test/clangdtests.cpp
index 82e64fad787..ff69d650f39 100644
--- a/src/plugins/clangcodemodel/test/clangdtests.cpp
+++ b/src/plugins/clangcodemodel/test/clangdtests.cpp
@@ -764,12 +764,12 @@ void ClangdTestHighlighting::test_data()
QTest::newRow("struct declaration") << 50 << 8 << 50 << 11
<< QList{C_TYPE, C_DECLARATION} << 0;
QTest::newRow("namespace declaration") << 160 << 11 << 160 << 20
- << QList{C_TYPE, C_DECLARATION} << 0;
+ << QList{C_NAMESPACE, C_DECLARATION} << 0;
QTest::newRow("namespace alias declaration") << 164 << 11 << 164 << 25
- << QList{C_TYPE, C_DECLARATION} << 0;
+ << QList{C_NAMESPACE, C_DECLARATION} << 0;
QTest::newRow("struct in namespaced using declaration") << 165 << 18 << 165 << 35
<< QList{C_TYPE} << 0;
- QTest::newRow("namespace reference") << 166 << 1 << 166 << 10 << QList{C_TYPE} << 0;
+ QTest::newRow("namespace reference") << 166 << 1 << 166 << 10 << QList{C_NAMESPACE} << 0;
QTest::newRow("namespaced struct in global variable declaration") << 166 << 12 << 166 << 29
<< QList{C_TYPE} << 0;
QTest::newRow("virtual function declaration") << 170 << 18 << 170 << 33
@@ -992,7 +992,8 @@ void ClangdTestHighlighting::test_data()
<< QList{C_PUNCTUATION} << int(CppEditor::SemanticHighlighter::AngleBracketOpen);
QTest::newRow("class template instantiation (closing angle bracket)") << 384 << 22 << 384 << 23
<< QList{C_PUNCTUATION} << int(CppEditor::SemanticHighlighter::AngleBracketClose);
- QTest::newRow("namespace in declaration") << 413 << 4 << 413 << 26 << QList{C_TYPE} << 0;
+ QTest::newRow("namespace in declaration") << 413 << 4 << 413 << 26
+ << QList{C_NAMESPACE} << 0;
QTest::newRow("namespaced class in declaration") << 413 << 28 << 413 << 41
<< QList{C_TYPE} << 0;
QTest::newRow("class as template argument in declaration") << 413 << 42 << 413 << 52
@@ -1099,9 +1100,9 @@ void ClangdTestHighlighting::test_data()
QTest::newRow("local variable captured by lambda") << 442 << 24 << 442 << 27
<< QList{C_LOCAL} << 0;
QTest::newRow("static protected member") << 693 << 16 << 693 << 30
- << QList{C_FIELD, C_DECLARATION} << 0;
+ << QList{C_FIELD, C_DECLARATION, C_STATIC_MEMBER} << 0;
QTest::newRow("static private member") << 696 << 16 << 696 << 28
- << QList{C_FIELD, C_DECLARATION} << 0;
+ << QList{C_FIELD, C_DECLARATION, C_STATIC_MEMBER} << 0;
QTest::newRow("alias template declaration (opening angle bracket)") << 700 << 10 << 700 << 11
<< QList{C_PUNCTUATION} << int(CppEditor::SemanticHighlighter::AngleBracketOpen);
QTest::newRow("alias template declaration (closing angle bracket)") << 700 << 16 << 700 << 17
@@ -1163,14 +1164,14 @@ void ClangdTestHighlighting::test_data()
QTest::newRow("reference to global variable") << 764 << 5 << 764 << 14
<< QList{C_GLOBAL} << 0;
QTest::newRow("nested template instantiation (namespace 1)") << 773 << 8 << 773 << 11
- << QList{C_TYPE} << 0;
+ << QList{C_NAMESPACE} << 0;
QTest::newRow("nested template instantiation (type 1)") << 773 << 13 << 773 << 19
<< QList{C_TYPE} << 0;
QTest::newRow("nested template instantiation (opening angle bracket 1)")
<< 773 << 19 << 773 << 20
<< QList{C_PUNCTUATION} << int(CppEditor::SemanticHighlighter::AngleBracketOpen);
QTest::newRow("nested template instantiation (namespace 2)") << 773 << 20 << 773 << 23
- << QList{C_TYPE} << 0;
+ << QList{C_NAMESPACE} << 0;
QTest::newRow("nested template instantiation (type 2)") << 773 << 25 << 773 << 29
<< QList{C_TYPE} << 0;
QTest::newRow("nested template instantiation (opening angle bracket 2)")
diff --git a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp
index 111fcb13a14..d17d02f51b6 100644
--- a/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp
+++ b/src/plugins/coreplugin/dialogs/externaltoolconfig.cpp
@@ -575,11 +575,11 @@ void ExternalToolConfig::updateItem(const QModelIndex &index)
if (!tool)
return;
tool->setDescription(m_ui.description->text());
- QStringList executables = tool->executables();
+ FilePaths executables = tool->executables();
if (executables.size() > 0)
- executables[0] = m_ui.executable->rawPath();
+ executables[0] = m_ui.executable->rawFilePath();
else
- executables << m_ui.executable->rawPath();
+ executables << m_ui.executable->rawFilePath();
tool->setExecutables(executables);
tool->setArguments(m_ui.arguments->text());
tool->setWorkingDirectory(m_ui.workingDirectory->rawFilePath());
@@ -607,8 +607,8 @@ void ExternalToolConfig::showInfoForItem(const QModelIndex &index)
}
m_ui.infoWidget->setEnabled(true);
m_ui.description->setText(tool->description());
- m_ui.executable->setPath(tool->executables().isEmpty() ? QString()
- : tool->executables().constFirst());
+ m_ui.executable->setFilePath(tool->executables().isEmpty() ? FilePath()
+ : tool->executables().constFirst());
m_ui.arguments->setText(tool->arguments());
m_ui.workingDirectory->setFilePath(tool->workingDirectory());
m_ui.outputBehavior->setCurrentIndex(int(tool->outputHandling()));
diff --git a/src/plugins/coreplugin/externaltool.cpp b/src/plugins/coreplugin/externaltool.cpp
index 33368c47971..04ff8c9e0c5 100644
--- a/src/plugins/coreplugin/externaltool.cpp
+++ b/src/plugins/coreplugin/externaltool.cpp
@@ -154,7 +154,7 @@ int ExternalTool::order() const
return m_order;
}
-QStringList ExternalTool::executables() const
+FilePaths ExternalTool::executables() const
{
return m_executables;
}
@@ -250,43 +250,36 @@ void ExternalTool::setDescription(const QString &description)
m_description = description;
}
-
void ExternalTool::setOutputHandling(OutputHandling handling)
{
m_outputHandling = handling;
}
-
void ExternalTool::setErrorHandling(OutputHandling handling)
{
m_errorHandling = handling;
}
-
void ExternalTool::setModifiesCurrentDocument(bool modifies)
{
m_modifiesCurrentDocument = modifies;
}
-
-void ExternalTool::setExecutables(const QStringList &executables)
+void ExternalTool::setExecutables(const FilePaths &executables)
{
m_executables = executables;
}
-
void ExternalTool::setArguments(const QString &arguments)
{
m_arguments = arguments;
}
-
void ExternalTool::setInput(const QString &input)
{
m_input = input;
}
-
void ExternalTool::setWorkingDirectory(const FilePath &workingDirectory)
{
m_workingDirectory = workingDirectory;
@@ -417,7 +410,7 @@ ExternalTool * ExternalTool::createFromXml(const QByteArray &xml, QString *error
}
while (reader.readNextStartElement()) {
if (reader.name() == QLatin1String(kPath)) {
- tool->m_executables.append(reader.readElementText());
+ tool->m_executables.append(FilePath::fromString(reader.readElementText()));
} else if (reader.name() == QLatin1String(kArguments)) {
if (!tool->m_arguments.isEmpty()) {
reader.raiseError("only one element allowed");
@@ -519,8 +512,8 @@ bool ExternalTool::save(QString *errorMessage) const
out.writeAttribute(kOutput, stringForOutputHandling(m_outputHandling));
out.writeAttribute(kError, stringForOutputHandling(m_errorHandling));
out.writeAttribute(kModifiesDocument, QLatin1String(m_modifiesCurrentDocument ? kYes : kNo));
- foreach (const QString &executable, m_executables)
- out.writeTextElement(kPath, executable);
+ for (const FilePath &executable : m_executables)
+ out.writeTextElement(kPath, executable.toString());
if (!m_arguments.isEmpty())
out.writeTextElement(kArguments, m_arguments);
if (!m_input.isEmpty())
@@ -608,11 +601,12 @@ bool ExternalToolRunner::resolve()
{
// executable
- QStringList expandedExecutables; /* for error message */
- foreach (const QString &executable, m_tool->executables()) {
- QString expanded = expander->expand(executable);
+ FilePaths expandedExecutables; /* for error message */
+ const FilePaths executables = m_tool->executables();
+ for (const FilePath &executable : executables) {
+ FilePath expanded = expander->expand(executable);
expandedExecutables.append(expanded);
- m_resolvedExecutable = m_resolvedEnvironment.searchInPath(expanded);
+ m_resolvedExecutable = m_resolvedEnvironment.searchInPath(expanded.path());
if (!m_resolvedExecutable.isEmpty())
break;
}
@@ -620,7 +614,8 @@ bool ExternalToolRunner::resolve()
m_hasError = true;
for (int i = 0; i < expandedExecutables.size(); ++i) {
m_errorString += tr("Could not find executable for \"%1\" (expanded \"%2\")")
- .arg(m_tool->executables().at(i), expandedExecutables.at(i));
+ .arg(m_tool->executables().at(i).toUserOutput(),
+ expandedExecutables.at(i).toUserOutput());
m_errorString += QLatin1Char('\n');
}
if (!m_errorString.isEmpty())
diff --git a/src/plugins/coreplugin/externaltool.h b/src/plugins/coreplugin/externaltool.h
index 36e4a22d813..38fc517bd2d 100644
--- a/src/plugins/coreplugin/externaltool.h
+++ b/src/plugins/coreplugin/externaltool.h
@@ -64,7 +64,7 @@ public:
OutputHandling errorHandling() const;
bool modifiesCurrentDocument() const;
- QStringList executables() const;
+ Utils::FilePaths executables() const;
QString arguments() const;
QString input() const;
Utils::FilePath workingDirectory() const;
@@ -95,7 +95,7 @@ public:
void setOutputHandling(OutputHandling handling);
void setErrorHandling(OutputHandling handling);
void setModifiesCurrentDocument(bool modifies);
- void setExecutables(const QStringList &executables);
+ void setExecutables(const Utils::FilePaths &executables);
void setArguments(const QString &arguments);
void setInput(const QString &input);
void setWorkingDirectory(const Utils::FilePath &workingDirectory);
@@ -108,7 +108,7 @@ private:
QString m_displayName;
QString m_displayCategory;
int m_order = -1;
- QStringList m_executables;
+ Utils::FilePaths m_executables;
QString m_arguments;
QString m_input;
Utils::FilePath m_workingDirectory;
diff --git a/src/plugins/coreplugin/helpitem.cpp b/src/plugins/coreplugin/helpitem.cpp
index 50f84bbf7ab..c2cb6ac54ef 100644
--- a/src/plugins/coreplugin/helpitem.cpp
+++ b/src/plugins/coreplugin/helpitem.cpp
@@ -298,7 +298,8 @@ static const HelpItem::Links getBestLink(const HelpItem::Links &links)
// documentation, that we only return the Qt5 link even though the Qt5 and Qt4 URLs look
// different.
QVersionNumber highestVersion;
- HelpItem::Link bestLink;
+ // Default to first link if version extraction failed, possibly because it is not a Qt doc link
+ HelpItem::Link bestLink = links.front();
for (const HelpItem::Link &link : links) {
const QVersionNumber version = extractVersion(link.second).second;
if (version > highestVersion) {
diff --git a/src/plugins/cppeditor/cppchecksymbols.cpp b/src/plugins/cppeditor/cppchecksymbols.cpp
index ab1baf8d38b..2c75a426ed7 100644
--- a/src/plugins/cppeditor/cppchecksymbols.cpp
+++ b/src/plugins/cppeditor/cppchecksymbols.cpp
@@ -477,7 +477,7 @@ bool CheckSymbols::visit(NamespaceAST *ast)
if (!tok.generated()) {
int line, column;
getTokenStartPosition(ast->identifier_token, &line, &column);
- Result use(line, column, tok.utf16chars(), SemanticHighlighter::TypeUse);
+ Result use(line, column, tok.utf16chars(), SemanticHighlighter::NamespaceUse);
addUse(use);
}
}
@@ -1221,7 +1221,15 @@ void CheckSymbols::addType(ClassOrNamespace *b, NameAST *ast)
int line, column;
getTokenStartPosition(startToken, &line, &column);
const unsigned length = tok.utf16chars();
- const Result use(line, column, length, SemanticHighlighter::TypeUse);
+ Kind kind = SemanticHighlighter::TypeUse;
+ const QList &symbols = b->symbols();
+ for (const Symbol * const s : symbols) {
+ if (s->isNamespace()) {
+ kind = SemanticHighlighter::NamespaceUse;
+ break;
+ }
+ }
+ const Result use(line, column, length, kind);
addUse(use);
}
@@ -1266,6 +1274,8 @@ bool CheckSymbols::maybeAddTypeOrStatic(const QList &candidates, Nam
Kind kind = SemanticHighlighter::TypeUse;
if (c->enclosingEnum() != nullptr)
kind = SemanticHighlighter::EnumerationUse;
+ else if (c->isNamespace())
+ kind = SemanticHighlighter::NamespaceUse;
else if (c->isStatic())
// treat static variable as a field(highlighting)
kind = SemanticHighlighter::FieldUse;
@@ -1305,7 +1315,8 @@ bool CheckSymbols::maybeAddField(const QList &candidates, NameAST *a
getTokenStartPosition(startToken, &line, &column);
const unsigned length = tok.utf16chars();
- const Result use(line, column, length, SemanticHighlighter::FieldUse);
+ const Result use(line, column, length, c->isStatic()
+ ? SemanticHighlighter::StaticFieldUse : SemanticHighlighter::FieldUse);
addUse(use);
return true;
@@ -1359,12 +1370,15 @@ bool CheckSymbols::maybeAddFunction(const QList &candidates, NameAST
continue; // TODO: add diagnostic messages and color call-operators calls too?
const bool isVirtual = funTy->isVirtual();
+ const bool isStaticMember = funTy->isStatic() && funTy->enclosingClass();
Kind matchingKind;
if (functionKind == FunctionDeclaration) {
matchingKind = isVirtual ? SemanticHighlighter::VirtualFunctionDeclarationUse
+ : isStaticMember ? SemanticHighlighter::StaticMethodDeclarationUse
: SemanticHighlighter::FunctionDeclarationUse;
} else {
matchingKind = isVirtual ? SemanticHighlighter::VirtualMethodUse
+ : isStaticMember ? SemanticHighlighter::StaticMethodUse
: SemanticHighlighter::FunctionUse;
}
if (argumentCount < funTy->minimumArgumentCount()) {
diff --git a/src/plugins/cppeditor/cppdoxygen_test.cpp b/src/plugins/cppeditor/cppdoxygen_test.cpp
index c9c40a8dd80..7e2781a6ce4 100644
--- a/src/plugins/cppeditor/cppdoxygen_test.cpp
+++ b/src/plugins/cppeditor/cppdoxygen_test.cpp
@@ -326,6 +326,20 @@ void DoxygenTest::testBasic_data()
"};\n"
);
+ QTest::newRow("classTemplate") << _(
+ "bool preventFolding;\n"
+ "/**|\n"
+ "template class C {\n"
+ "};\n"
+ ) << _(
+ "bool preventFolding;\n"
+ "/**\n"
+ " * @brief The C class\n"
+ " */\n"
+ "template class C {\n"
+ "};\n"
+ );
+
QTest::newRow("continuation_after_text_in_first_line") << _(
"bool preventFolding;\n"
"/*! leading comment|\n"
diff --git a/src/plugins/cppeditor/doxygengenerator.cpp b/src/plugins/cppeditor/doxygengenerator.cpp
index aba3655b811..9ab9e109eb6 100644
--- a/src/plugins/cppeditor/doxygengenerator.cpp
+++ b/src/plugins/cppeditor/doxygengenerator.cpp
@@ -141,6 +141,9 @@ QString DoxygenGenerator::generate(QTextCursor cursor,
QString DoxygenGenerator::generate(QTextCursor cursor, DeclarationAST *decl)
{
+ if (const TemplateDeclarationAST * const templDecl = decl->asTemplateDeclaration())
+ decl = templDecl->declaration;
+
SpecifierAST *spec = nullptr;
DeclaratorAST *decltr = nullptr;
if (SimpleDeclarationAST *simpleDecl = decl->asSimpleDeclaration()) {
diff --git a/src/plugins/cppeditor/semantichighlighter.cpp b/src/plugins/cppeditor/semantichighlighter.cpp
index 6a02566981a..ba8b81e7ff1 100644
--- a/src/plugins/cppeditor/semantichighlighter.cpp
+++ b/src/plugins/cppeditor/semantichighlighter.cpp
@@ -316,6 +316,7 @@ void SemanticHighlighter::updateFormatMapFromFontSettings()
const FontSettings &fs = m_baseTextDocument->fontSettings();
m_formatMap[TypeUse] = fs.toTextCharFormat(C_TYPE);
+ m_formatMap[NamespaceUse] = fs.toTextCharFormat(C_NAMESPACE);
m_formatMap[LocalUse] = fs.toTextCharFormat(C_LOCAL);
m_formatMap[FieldUse] = fs.toTextCharFormat(C_FIELD);
m_formatMap[EnumerationUse] = fs.toTextCharFormat(C_ENUMERATION);
@@ -328,6 +329,12 @@ void SemanticHighlighter::updateFormatMapFromFontSettings()
m_formatMap[VirtualFunctionDeclarationUse] =
fs.toTextCharFormat(TextStyles::mixinStyle(C_VIRTUAL_METHOD, C_DECLARATION));
m_formatMap[PseudoKeywordUse] = fs.toTextCharFormat(C_KEYWORD);
+ m_formatMap[StaticFieldUse]
+ = fs.toTextCharFormat(TextStyles::mixinStyle(C_FIELD, C_STATIC_MEMBER));
+ m_formatMap[StaticMethodUse]
+ = fs.toTextCharFormat(TextStyles::mixinStyle(C_FUNCTION, C_STATIC_MEMBER));
+ m_formatMap[StaticMethodDeclarationUse] = fs.toTextCharFormat(
+ TextStyles::mixinStyle(C_FUNCTION, {C_DECLARATION, C_STATIC_MEMBER}));
}
} // namespace CppEditor
diff --git a/src/plugins/cppeditor/semantichighlighter.h b/src/plugins/cppeditor/semantichighlighter.h
index 1acbabcff96..b46971fbfd1 100644
--- a/src/plugins/cppeditor/semantichighlighter.h
+++ b/src/plugins/cppeditor/semantichighlighter.h
@@ -48,6 +48,7 @@ public:
enum Kind {
Unknown = 0,
TypeUse,
+ NamespaceUse,
LocalUse,
FieldUse,
EnumerationUse,
@@ -58,6 +59,9 @@ public:
PseudoKeywordUse,
FunctionDeclarationUse,
VirtualFunctionDeclarationUse,
+ StaticFieldUse,
+ StaticMethodUse,
+ StaticMethodDeclarationUse,
AngleBracketOpen,
AngleBracketClose,
DoubleAngleBracketClose,
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp
index e1c8be48c31..d685d550d01 100644
--- a/src/plugins/debugger/cdb/cdbengine.cpp
+++ b/src/plugins/debugger/cdb/cdbengine.cpp
@@ -57,8 +57,11 @@
#include
#include
#include
+#include
+#include
#include
+#include
#include
#include
#include
@@ -2243,6 +2246,60 @@ static inline bool checkCommandToken(const QString &tokenPrefix, const QString &
return ok;
}
+// look for Qt Core Debug module to check whether it is sdk provided
+// and the pdb files are installed in a path discoverable by the debugger
+void CdbEngine::checkQtSdkPdbFiles(const QString &module)
+{
+ const QRegularExpression qtCoreModuleRegExp("(Qt\\dCored).dll");
+ const QRegularExpressionMatch match = qtCoreModuleRegExp.match(module);
+ if (!match.hasMatch())
+ return;
+ const FilePath modulePath = FilePath::fromUserInput(module).parentDir();
+ QtSupport::BaseQtVersion *version = QtSupport::QtVersionManager::version(
+ [modulePath](const QtSupport::BaseQtVersion *version) {
+ return version->isAutodetected() && version->binPath() == modulePath;
+ });
+ if (!version)
+ return;
+
+ const QString qtCoreModuleName = match.captured(1);
+ // Check the usual location of pdb files to avoid the more expensive part of asking cdb
+ const FilePath pdbPath = modulePath.pathAppended(qtCoreModuleName + ".pdb");
+ if (pdbPath.exists())
+ return;
+
+ // If there are no pdb files in the usual location, check whether the user has setup the symbol
+ // path in order to find the debug symbols.
+ // But first we need to load the symbols in order to check whether the pdb files can be found
+ runCommand({"ld " + qtCoreModuleName, BuiltinCommand});
+ DebuggerCommand cmd;
+ cmd.function = "lm m " + qtCoreModuleName;
+ cmd.callback = [this, qtName = version->displayName()](const DebuggerResponse &response) {
+ if (response.data.m_data.contains("private pdb symbols"))
+ return;
+
+ const QString message
+ = tr("The installed %1 is missing debug information files.\n"
+ "Locals and Expression might not be able to display all Qt Types in a "
+ "human readable format.\n\n"
+ "Please install the \"Qt Debug Information Files\" Package from the "
+ "Maintenance Tool for this Qt installation to get all relevant "
+ "symbols for the debugger.")
+ .arg(qtName);
+
+ CheckableMessageBox::doNotShowAgainInformation(
+ Core::ICore::dialogParent(),
+ tr("Missing Qt Debug Information"),
+ message,
+ Core::ICore::settings(),
+ "CdbQtSdkPdbHint");
+
+ showMessage("Missing Qt Debug Information Files package for " + qtName, LogMisc);
+ };
+ cmd.flags = BuiltinCommand;
+ runCommand(cmd);
+}
+
void CdbEngine::parseOutputLine(QString line)
{
// The hooked output callback in the extension suppresses prompts,
@@ -2351,8 +2408,11 @@ void CdbEngine::parseOutputLine(QString line)
// output(32): ModLoad: 00007ffb 00007ffb C:\Windows\system32\KERNEL32.DLL
const QRegularExpression moduleRegExp("[0-9a-fA-F]+(`[0-9a-fA-F]+)? [0-9a-fA-F]+(`[0-9a-fA-F]+)? (.*)");
const QRegularExpressionMatch match = moduleRegExp.match(line);
- if (match.hasMatch())
- showStatusMessage(tr("Module loaded: %1").arg(match.captured(3).trimmed()), 3000);
+ if (match.hasMatch()) {
+ const QString module = match.captured(3).trimmed();
+ showStatusMessage(tr("Module loaded: %1").arg(module), 3000);
+ checkQtSdkPdbFiles(module);
+ }
} else {
showMessage(line, LogMisc);
}
diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h
index 6d3f9aa54b4..6488605d09c 100644
--- a/src/plugins/debugger/cdb/cdbengine.h
+++ b/src/plugins/debugger/cdb/cdbengine.h
@@ -194,6 +194,7 @@ private:
int elapsedLogTime();
unsigned parseStackTrace(const GdbMi &data, bool sourceStepInto);
void mergeStartParametersSourcePathMap();
+ void checkQtSdkPdbFiles(const QString &module);
const QString m_tokenPrefix;
void handleSetupFailure(const QString &errorMessage);
diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp
index f2441aff33a..ebe4ac3c04f 100644
--- a/src/plugins/debugger/debuggerengine.cpp
+++ b/src/plugins/debugger/debuggerengine.cpp
@@ -74,6 +74,7 @@
#include
#include
+#include
#include
#include
#include
@@ -1096,7 +1097,7 @@ void DebuggerEngine::gotoLocation(const Location &loc)
showMessage("CANNOT GO TO THIS LOCATION");
return;
}
- const QString file = loc.fileName().toString();
+ const FilePath file = loc.fileName();
const int line = loc.lineNumber();
bool newEditor = false;
IEditor *editor = EditorManager::openEditor(file,
@@ -2729,27 +2730,34 @@ Context CppDebuggerEngine::languageContext() const
void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp)
{
+ static const QString warnOnInappropriateDebuggerKey = "DebuggerWarnOnInappropriateDebugger";
+ QtcSettings *coreSettings = Core::ICore::settings();
+
const bool warnOnRelease = debuggerSettings()->warnOnReleaseBuilds.value()
&& rp.toolChainAbi.osFlavor() != Abi::AndroidLinuxFlavor;
bool warnOnInappropriateDebugger = false;
QString detailedWarning;
switch (rp.toolChainAbi.binaryFormat()) {
case Abi::PEFormat: {
- QString preferredDebugger;
- if (rp.toolChainAbi.osFlavor() == Abi::WindowsMSysFlavor) {
- if (rp.cppEngineType == CdbEngineType)
- preferredDebugger = "GDB";
- } else if (rp.cppEngineType != CdbEngineType) {
- // osFlavor() is MSVC, so the recommended debugger is CDB
- preferredDebugger = "CDB";
- }
- if (!preferredDebugger.isEmpty()) {
- warnOnInappropriateDebugger = true;
- detailedWarning = DebuggerEngine::tr(
- "The inferior is in the Portable Executable format.\n"
- "Selecting %1 as debugger would improve the debugging "
- "experience for this binary format.").arg(preferredDebugger);
- break;
+ if (CheckableMessageBox::shouldAskAgain(coreSettings, warnOnInappropriateDebuggerKey)) {
+ QString preferredDebugger;
+ if (rp.toolChainAbi.osFlavor() == Abi::WindowsMSysFlavor) {
+ if (rp.cppEngineType == CdbEngineType)
+ preferredDebugger = "GDB";
+ } else if (rp.cppEngineType != CdbEngineType && rp.cppEngineType != LldbEngineType) {
+ // osFlavor() is MSVC, so the recommended debugger is still CDB,
+ // but don't warn for LLDB which starts to be usable, too.
+ preferredDebugger = "CDB";
+ }
+ if (!preferredDebugger.isEmpty()) {
+ warnOnInappropriateDebugger = true;
+ detailedWarning = DebuggerEngine::tr(
+ "The inferior is in the Portable Executable format.\n"
+ "Selecting %1 as debugger would improve the debugging "
+ "experience for this binary format.")
+ .arg(preferredDebugger);
+ break;
+ }
}
if (warnOnRelease
&& rp.cppEngineType == CdbEngineType
@@ -2771,13 +2779,15 @@ void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp)
break;
}
case Abi::ElfFormat: {
- if (rp.cppEngineType == CdbEngineType) {
- warnOnInappropriateDebugger = true;
- detailedWarning = DebuggerEngine::tr(
- "The inferior is in the ELF format.\n"
- "Selecting GDB or LLDB as debugger would improve the debugging "
- "experience for this binary format.");
- break;
+ if (CheckableMessageBox::shouldAskAgain(coreSettings, warnOnInappropriateDebuggerKey)) {
+ if (rp.cppEngineType == CdbEngineType) {
+ warnOnInappropriateDebugger = true;
+ detailedWarning = DebuggerEngine::tr(
+ "The inferior is in the ELF format.\n"
+ "Selecting GDB or LLDB as debugger would improve the debugging "
+ "experience for this binary format.");
+ break;
+ }
}
ElfReader reader(rp.symbolFile);
@@ -2876,11 +2886,16 @@ void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp)
return;
}
if (warnOnInappropriateDebugger) {
- AsynchronousMessageBox::information(DebuggerEngine::tr("Warning"),
- DebuggerEngine::tr("The selected debugger may be inappropriate for the inferior.\n"
- "Examining symbols and setting breakpoints by file name and line number "
- "may fail.\n")
- + '\n' + detailedWarning);
+ CheckableMessageBox::doNotShowAgainInformation(
+ Core::ICore::dialogParent(),
+ DebuggerEngine::tr("Warning"),
+ DebuggerEngine::tr(
+ "The selected debugger may be inappropriate for the inferior.\n"
+ "Examining symbols and setting breakpoints by file name and line number "
+ "may fail.\n")
+ + '\n' + detailedWarning,
+ Core::ICore::settings(),
+ warnOnInappropriateDebuggerKey);
} else if (warnOnRelease) {
AsynchronousMessageBox::information(DebuggerEngine::tr("Warning"),
DebuggerEngine::tr("This does not seem to be a \"Debug\" build.\n"
diff --git a/src/plugins/debugger/debuggeritem.cpp b/src/plugins/debugger/debuggeritem.cpp
index 3a5060cbe5c..e759d1889e7 100644
--- a/src/plugins/debugger/debuggeritem.cpp
+++ b/src/plugins/debugger/debuggeritem.cpp
@@ -150,7 +150,8 @@ void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *erro
// except for the experimental LLDB-MI which insists on --version.
QString version = "-version";
m_lastModified = m_command.lastModified();
- if (m_command.baseName().toLower().contains("lldb-mi"))
+ if (m_command.baseName().toLower().contains("lldb-mi")
+ || m_command.baseName().startsWith("LLDBFrontend")) // Comes with Android Studio
version = "--version";
// We don't need to start the uVision executable to
@@ -229,15 +230,16 @@ void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *erro
//! \note If unable to determine the GDB ABI, no ABI is appended to m_abis here.
return;
}
- if (output.startsWith("lldb") || output.startsWith("LLDB")) {
+ if (output.contains("lldb") || output.startsWith("LLDB")) {
m_engineType = LldbEngineType;
m_abis = Abi::abisOfBinary(m_command);
// Version
// Self-build binaries also emit clang and llvm revision.
const QString line = output.split('\n')[0];
- if (line.startsWith(("lldb version "))) { // Linux typically.
- int pos1 = int(strlen("lldb version "));
+ const QString nonMacOSPrefix = "lldb version ";
+ if (line.contains(nonMacOSPrefix)) { // Linux typically, or some Windows builds.
+ int pos1 = line.indexOf(nonMacOSPrefix) + nonMacOSPrefix.length();
int pos2 = line.indexOf(' ', pos1);
m_version = line.mid(pos1, pos2 - pos1);
} else if (line.startsWith("lldb-") || line.startsWith("LLDB-")) { // Mac typically.
diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp
index 57f3383942d..7bf8e951eea 100644
--- a/src/plugins/debugger/pdb/pdbengine.cpp
+++ b/src/plugins/debugger/pdb/pdbengine.cpp
@@ -58,11 +58,12 @@
#include
using namespace Core;
+using namespace Utils;
namespace Debugger {
namespace Internal {
-PdbEngine::PdbEngine()
+PdbEngine::PdbEngine() : m_proc(ProcessMode::Writer)
{
setObjectName("PdbEngine");
setDebuggerName("PDB");
@@ -117,13 +118,10 @@ void PdbEngine::setupEngine()
m_interpreter = runParameters().interpreter;
QString bridge = ICore::resourcePath("debugger/pdbbridge.py").toString();
- connect(&m_proc, &QProcess::errorOccurred, this, &PdbEngine::handlePdbError);
- connect(&m_proc, QOverload::of(&QProcess::finished),
- this, &PdbEngine::handlePdbFinished);
- connect(&m_proc, &QProcess::readyReadStandardOutput,
- this, &PdbEngine::readPdbStandardOutput);
- connect(&m_proc, &QProcess::readyReadStandardError,
- this, &PdbEngine::readPdbStandardError);
+ connect(&m_proc, &QtcProcess::errorOccurred, this, &PdbEngine::handlePdbError);
+ connect(&m_proc, &QtcProcess::finished, this, &PdbEngine::handlePdbFinished);
+ connect(&m_proc, &QtcProcess::readyReadStandardOutput, this, &PdbEngine::readPdbStandardOutput);
+ connect(&m_proc, &QtcProcess::readyReadStandardError, this, &PdbEngine::readPdbStandardError);
QFile scriptFile(runParameters().mainScript);
if (!scriptFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
@@ -134,10 +132,11 @@ void PdbEngine::setupEngine()
}
QStringList args = {bridge, scriptFile.fileName()};
- args.append(Utils::ProcessArgs::splitArgs(runParameters().inferior.workingDirectory.path()));
+ args.append(ProcessArgs::splitArgs(runParameters().inferior.workingDirectory.path()));
showMessage("STARTING " + m_interpreter + ' ' + args.join(' '));
- m_proc.setEnvironment(runParameters().debugger.environment.toStringList());
- m_proc.start(m_interpreter, args);
+ m_proc.setEnvironment(runParameters().debugger.environment);
+ m_proc.setCommand({ FilePath::fromString(m_interpreter), args });
+ m_proc.start();
if (!m_proc.waitForStarted()) {
const QString msg = tr("Unable to start pdb \"%1\": %2")
@@ -346,7 +345,7 @@ void PdbEngine::refreshState(const GdbMi &reportedState)
void PdbEngine::refreshLocation(const GdbMi &reportedLocation)
{
StackFrame frame;
- frame.file = Utils::FilePath::fromString(reportedLocation["file"].data());
+ frame.file = FilePath::fromString(reportedLocation["file"].data());
frame.line = reportedLocation["line"].toInt();
frame.usable = frame.file.isReadableFile();
if (state() == InferiorRunOk) {
@@ -435,9 +434,10 @@ QString PdbEngine::errorMessage(QProcess::ProcessError error) const
}
}
-void PdbEngine::handlePdbFinished(int code, QProcess::ExitStatus type)
+void PdbEngine::handlePdbFinished()
{
- showMessage(QString("PDB PROCESS FINISHED, status %1, code %2").arg(type).arg(code));
+ showMessage(QString("PDB PROCESS FINISHED, status %1, code %2")
+ .arg(m_proc.exitStatus()).arg(m_proc.exitCode()));
notifyEngineSpontaneousShutdown();
}
@@ -495,10 +495,9 @@ void PdbEngine::handleOutput2(const QString &data)
const QString bpnr = line.mid(11, pos1 - 11);
const int pos2 = line.lastIndexOf(':');
QTC_ASSERT(pos2 != -1, continue);
- const Utils::FilePath fileName = Utils::FilePath::fromString(
- line.mid(pos1 + 4, pos2 - pos1 - 4));
+ const FilePath fileName = FilePath::fromString(line.mid(pos1 + 4, pos2 - pos1 - 4));
const int lineNumber = line.mid(pos2 + 1).toInt();
- const Breakpoint bp = Utils::findOrDefault(breakHandler()->breakpoints(), [&](const Breakpoint &bp) {
+ const Breakpoint bp = findOrDefault(breakHandler()->breakpoints(), [&](const Breakpoint &bp) {
return bp->parameters().isLocatedAt(fileName, lineNumber, bp->markerFileName())
|| bp->requestedParameters().isLocatedAt(fileName, lineNumber, bp->markerFileName());
});
@@ -535,7 +534,7 @@ void PdbEngine::refreshStack(const GdbMi &stack)
for (const GdbMi &item : stack["frames"]) {
StackFrame frame;
frame.level = item["level"].data();
- frame.file = Utils::FilePath::fromString(item["file"].data());
+ frame.file = FilePath::fromString(item["file"].data());
frame.function = item["function"].data();
frame.module = item["function"].data();
frame.line = item["line"].toInt();
diff --git a/src/plugins/debugger/pdb/pdbengine.h b/src/plugins/debugger/pdb/pdbengine.h
index 3151a6119a9..0c645de55d3 100644
--- a/src/plugins/debugger/pdb/pdbengine.h
+++ b/src/plugins/debugger/pdb/pdbengine.h
@@ -26,8 +26,8 @@
#pragma once
#include
+#include
-#include
#include
namespace Debugger {
@@ -100,7 +100,7 @@ private:
QString errorMessage(QProcess::ProcessError error) const;
bool hasCapability(unsigned cap) const override;
- void handlePdbFinished(int, QProcess::ExitStatus status);
+ void handlePdbFinished();
void handlePdbError(QProcess::ProcessError error);
void readPdbStandardOutput();
void readPdbStandardError();
@@ -111,7 +111,7 @@ private:
void updateLocals() override;
QString m_inbuffer;
- QProcess m_proc;
+ Utils::QtcProcess m_proc;
QString m_interpreter;
};
diff --git a/src/plugins/debugger/watchdata.cpp b/src/plugins/debugger/watchdata.cpp
index f5173b857c5..49a75cc86f0 100644
--- a/src/plugins/debugger/watchdata.cpp
+++ b/src/plugins/debugger/watchdata.cpp
@@ -50,7 +50,12 @@ bool isIntType(const QString &type)
case 'c':
return type == "char";
case 'i':
- return type == "int";
+ return type.startsWith("int") &&
+ ( type == "int"
+ || type == "int8_t"
+ || type == "int16_t"
+ || type == "int32_t"
+ || type == "int64_t");
case 'l':
return type == "long"
|| type == "long int"
@@ -86,7 +91,12 @@ bool isIntType(const QString &type)
|| type == "unsigned long"
|| type == "unsigned long int"
|| type == "unsigned long long"
- || type == "unsigned long long int"));
+ || type == "unsigned long long int"))
+ || (type.startsWith("uint") &&
+ ( type == "uint8_t"
+ || type == "uint16_t"
+ || type == "uint32_t"
+ || type == "uint64_t"));
default:
return false;
}
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index 20a5c95108b..ed3fb5de9d2 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -718,10 +718,10 @@ static QString formattedValue(const WatchItem *item)
// Append quoted, printable character also for decimal.
// FIXME: This is unreliable.
- if (item->type.endsWith("char")) {
+ if (item->type.endsWith("char") || item->type.endsWith("int8_t")) {
bool ok;
const int code = item->value.toInt(&ok);
- bool isUnsigned = item->type == "unsigned char" || item->type == "uchar";
+ bool isUnsigned = item->type == "unsigned char" || item->type == "uchar" || item->type == "uint8_t";
if (ok)
return reformatCharacter(code, 1, !isUnsigned);
} else if (item->type.endsWith("wchar_t")) {
diff --git a/src/plugins/fakevim/fakevimhandler.cpp b/src/plugins/fakevim/fakevimhandler.cpp
index 38ab02e0a9e..ef39bb54416 100644
--- a/src/plugins/fakevim/fakevimhandler.cpp
+++ b/src/plugins/fakevim/fakevimhandler.cpp
@@ -59,12 +59,12 @@
#include "fakevimtr.h"
#include
+#include
#include
#include
#include
#include
-#include
#include
#include
#include
@@ -866,17 +866,10 @@ static QString fromLocalEncoding(const QByteArray &data)
static QString getProcessOutput(const QString &command, const QString &input)
{
- QProcess proc;
-#if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
- QStringList arguments = QProcess::splitCommand(command);
- QString executable = arguments.takeFirst();
- proc.start(executable, arguments);
-#else
- proc.start(command);
-#endif
- proc.waitForStarted();
- proc.write(toLocalEncoding(input));
- proc.closeWriteChannel();
+ Utils::QtcProcess proc;
+ proc.setCommand(Utils::CommandLine::fromUserInput(command));
+ proc.setWriteData(toLocalEncoding(input));
+ proc.start();
// FIXME: Process should be interruptable by user.
// Solution is to create a QObject for each process and emit finished state.
diff --git a/src/plugins/languageclient/semantichighlightsupport.cpp b/src/plugins/languageclient/semantichighlightsupport.cpp
index a1b43729d4a..11365566bac 100644
--- a/src/plugins/languageclient/semantichighlightsupport.cpp
+++ b/src/plugins/languageclient/semantichighlightsupport.cpp
@@ -412,12 +412,20 @@ void SemanticTokenSupport::handleSemanticTokensDelta(
auto it = data.begin();
const auto end = data.end();
+ qCDebug(LOGLSPHIGHLIGHT) << "Edit Tokens for " << filePath;
+ qCDebug(LOGLSPHIGHLIGHT) << "Data before edit " << data;
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()));
+ const Utils::optional> editData = edit.data();
+ if (editData.has_value()) {
+ newData.append(editData.value());
+ qCDebug(LOGLSPHIGHLIGHT) << edit.start() << edit.deleteCount() << editData.value();
+ } else {
+ qCDebug(LOGLSPHIGHLIGHT) << edit.start() << edit.deleteCount();
+ }
int deleteCount = edit.deleteCount();
if (deleteCount > std::distance(it, end)) {
qCDebug(LOGLSPHIGHLIGHT)
@@ -434,6 +442,7 @@ void SemanticTokenSupport::handleSemanticTokensDelta(
for (; it != end; ++it)
newData.append(*it);
+ qCDebug(LOGLSPHIGHLIGHT) << "New Data " << newData;
tokens.setData(newData);
tokens.setResultId(tokensDelta->resultId());
} else {
@@ -478,6 +487,14 @@ void SemanticTokenSupport::highlight(const Utils::FilePath &filePath)
expandedToken.length = token.length;
expandedTokens << expandedToken;
};
+ if (LOGLSPHIGHLIGHT().isDebugEnabled()) {
+ qCDebug(LOGLSPHIGHLIGHT) << "Expanded Tokens for " << filePath;
+ for (const ExpandedSemanticToken &token : qAsConst(expandedTokens)) {
+ qCDebug(LOGLSPHIGHLIGHT)
+ << token.line << token.column << token.length << token.type << token.modifiers;
+ }
+ }
+
m_tokensHandler(doc, expandedTokens, versionedTokens.version);
return;
}
diff --git a/src/plugins/qmldesigner/CMakeLists.txt b/src/plugins/qmldesigner/CMakeLists.txt
index 467a33b40a3..1aac7a17cd8 100644
--- a/src/plugins/qmldesigner/CMakeLists.txt
+++ b/src/plugins/qmldesigner/CMakeLists.txt
@@ -134,7 +134,6 @@ extend_qtc_plugin(QmlDesigner
modelnodeoperations.cpp modelnodeoperations.h
formatoperation.cpp formatoperation.h
navigation2d.cpp navigation2d.h
- gestures.cpp gestures.h
qmldesignericonprovider.cpp qmldesignericonprovider.h
selectioncontext.cpp selectioncontext.h
theme.cpp theme.h
diff --git a/src/plugins/qmldesigner/components/componentcore/componentcore.pri b/src/plugins/qmldesigner/components/componentcore/componentcore.pri
index a64f61ab466..49d646d4627 100644
--- a/src/plugins/qmldesigner/components/componentcore/componentcore.pri
+++ b/src/plugins/qmldesigner/components/componentcore/componentcore.pri
@@ -5,7 +5,6 @@ SOURCES += addimagesdialog.cpp
SOURCES += changestyleaction.cpp
SOURCES += theme.cpp
SOURCES += findimplementation.cpp
-SOURCES += gestures.cpp
SOURCES += addsignalhandlerdialog.cpp
SOURCES += layoutingridlayout.cpp
SOURCES += abstractactiongroup.cpp
@@ -27,7 +26,6 @@ HEADERS += addimagesdialog.h
HEADERS += changestyleaction.h
HEADERS += theme.h
HEADERS += findimplementation.h
-HEADERS += gestures.h
HEADERS += addsignalhandlerdialog.h
HEADERS += layoutingridlayout.h
HEADERS += abstractactiongroup.h
diff --git a/src/plugins/qmldesigner/components/componentcore/gestures.cpp b/src/plugins/qmldesigner/components/componentcore/gestures.cpp
deleted file mode 100644
index 29ff23c2435..00000000000
--- a/src/plugins/qmldesigner/components/componentcore/gestures.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Design Tooling
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-
-#include "gestures.h"
-
-#include
-
-namespace QmlDesigner {
-
-Qt::GestureType TwoFingerSwipe::m_type = static_cast(0);
-
-TwoFingerSwipe::TwoFingerSwipe() {}
-
-Qt::GestureType TwoFingerSwipe::type()
-{
- return m_type;
-}
-
-void TwoFingerSwipe::registerRecognizer()
-{
- m_type = QGestureRecognizer::registerRecognizer(new TwoFingerSwipeRecognizer());
-}
-
-QPointF TwoFingerSwipe::direction() const
-{
- return m_current.center() - m_last.center();
-}
-
-void TwoFingerSwipe::reset()
-{
- m_start = QLineF();
- m_current = QLineF();
- m_last = QLineF();
-}
-
-QGestureRecognizer::Result TwoFingerSwipe::begin(QTouchEvent *event)
-{
- Q_UNUSED(event);
- return QGestureRecognizer::MayBeGesture;
-}
-
-QGestureRecognizer::Result TwoFingerSwipe::update(QTouchEvent *event)
-{
- if (event->touchPoints().size() != 2) {
- if (state() == Qt::NoGesture)
- return QGestureRecognizer::Ignore;
- else
- return QGestureRecognizer::FinishGesture;
- }
-
- QTouchEvent::TouchPoint p0 = event->touchPoints().at(0);
- QTouchEvent::TouchPoint p1 = event->touchPoints().at(1);
-
- QLineF line(p0.scenePos(), p1.screenPos());
-
- if (m_start.isNull()) {
- m_start = line;
- m_current = line;
- m_last = line;
- } else {
- auto deltaLength = line.length() - m_current.length();
- auto deltaCenter = QLineF(line.center(), m_current.center()).length();
- if (deltaLength > deltaCenter)
- return QGestureRecognizer::CancelGesture;
-
- m_last = m_current;
- m_current = line;
- }
-
- setHotSpot(m_current.center());
-
- return QGestureRecognizer::TriggerGesture;
-}
-
-QGestureRecognizer::Result TwoFingerSwipe::end(QTouchEvent *event)
-{
- Q_UNUSED(event);
- bool finish = state() != Qt::NoGesture;
-
- reset();
-
- if (finish)
- return QGestureRecognizer::FinishGesture;
- else
- return QGestureRecognizer::CancelGesture;
-}
-
-TwoFingerSwipeRecognizer::TwoFingerSwipeRecognizer()
- : QGestureRecognizer()
-{}
-
-QGesture *TwoFingerSwipeRecognizer::create(QObject *target)
-{
- if (target && target->isWidgetType())
- qobject_cast(target)->setAttribute(Qt::WA_AcceptTouchEvents);
-
- return new TwoFingerSwipe;
-}
-
-QGestureRecognizer::Result TwoFingerSwipeRecognizer::recognize(QGesture *gesture,
- QObject *,
- QEvent *event)
-{
- if (gesture->gestureType() != TwoFingerSwipe::type())
- return QGestureRecognizer::Ignore;
-
- TwoFingerSwipe *swipe = static_cast(gesture);
- QTouchEvent *touch = static_cast(event);
-
- switch (event->type()) {
- case QEvent::TouchBegin:
- return swipe->begin(touch);
-
- case QEvent::TouchUpdate:
- return swipe->update(touch);
-
- case QEvent::TouchEnd:
- return swipe->end(touch);
-
- default:
- return QGestureRecognizer::Ignore;
- }
-}
-
-void TwoFingerSwipeRecognizer::reset(QGesture *gesture)
-{
- if (gesture->gestureType() == TwoFingerSwipe::type()) {
- TwoFingerSwipe *swipe = static_cast(gesture);
- swipe->reset();
- }
- QGestureRecognizer::reset(gesture);
-}
-
-} // End namespace QmlDesigner.
diff --git a/src/plugins/qmldesigner/components/componentcore/gestures.h b/src/plugins/qmldesigner/components/componentcore/gestures.h
deleted file mode 100644
index 3100560904b..00000000000
--- a/src/plugins/qmldesigner/components/componentcore/gestures.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Design Tooling
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-****************************************************************************/
-#pragma once
-
-#include
-#include
-#include
-
-QT_FORWARD_DECLARE_CLASS(QTouchEvent)
-
-namespace QmlDesigner {
-
-class TwoFingerSwipe : public QGesture
-{
- Q_OBJECT
-
-public:
- TwoFingerSwipe();
-
- static Qt::GestureType type();
- static void registerRecognizer();
-
- QPointF direction() const;
-
- void reset();
- QGestureRecognizer::Result begin(QTouchEvent *event);
- QGestureRecognizer::Result update(QTouchEvent *event);
- QGestureRecognizer::Result end(QTouchEvent *event);
-
-private:
- static Qt::GestureType m_type;
-
- QLineF m_start;
- QLineF m_current;
- QLineF m_last;
-};
-
-class TwoFingerSwipeRecognizer : public QGestureRecognizer
-{
-public:
- TwoFingerSwipeRecognizer();
-
- QGesture *create(QObject *target) override;
-
- QGestureRecognizer::Result recognize(QGesture *gesture, QObject *watched, QEvent *event) override;
-
- void reset(QGesture *gesture) override;
-};
-
-} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/componentcore/navigation2d.cpp b/src/plugins/qmldesigner/components/componentcore/navigation2d.cpp
index eccd8a517ed..3399c2a8914 100644
--- a/src/plugins/qmldesigner/components/componentcore/navigation2d.cpp
+++ b/src/plugins/qmldesigner/components/componentcore/navigation2d.cpp
@@ -23,44 +23,38 @@
**
****************************************************************************/
#include "navigation2d.h"
-#include "gestures.h"
#include
+#include
#include
+#include
#include
namespace QmlDesigner {
-Navigation2dScrollBar::Navigation2dScrollBar(QWidget *parent)
- : QScrollBar(parent)
-{}
-
-bool Navigation2dScrollBar::postEvent(QEvent *event)
+void Navigation2dFilter::scroll(const QPointF &direction, QScrollBar *sbx, QScrollBar *sby)
{
- if (event->type() == QEvent::Wheel) {
- wheelEvent(static_cast(event));
- return true;
- }
- return false;
+ auto doScroll = [](QScrollBar *sb, float distance) {
+ if (sb) {
+ // max - min + pageStep = sceneRect.size * scale
+ float d1 = sb->maximum() - sb->minimum();
+ float d2 = d1 + sb->pageStep();
+
+ float val = (distance / d2) * d1;
+ sb->setValue(sb->value() - val);
+ }
+ };
+
+ doScroll(sbx, direction.x());
+ doScroll(sby, direction.y());
}
-void Navigation2dScrollBar::wheelEvent(QWheelEvent *event)
-{
- if (!event->angleDelta().isNull())
- QScrollBar::wheelEvent(event);
-}
-
-
-Navigation2dFilter::Navigation2dFilter(QWidget *parent, Navigation2dScrollBar *scrollbar)
+Navigation2dFilter::Navigation2dFilter(QWidget *parent)
: QObject(parent)
- , m_scrollbar(scrollbar)
{
- if (parent) {
+ if (parent)
parent->grabGesture(Qt::PinchGesture);
- if (!scrollbar)
- parent->grabGesture(TwoFingerSwipe::type());
- }
}
bool Navigation2dFilter::eventFilter(QObject *object, QEvent *event)
@@ -82,34 +76,39 @@ bool Navigation2dFilter::gestureEvent(QGestureEvent *event)
event->accept();
return true;
}
- } else if (TwoFingerSwipe *swipe = static_cast(
- event->gesture(TwoFingerSwipe::type()))) {
- emit panChanged(swipe->direction());
- event->accept();
- return true;
}
return false;
}
bool Navigation2dFilter::wheelEvent(QWheelEvent *event)
{
- if (m_scrollbar) {
- if (m_scrollbar->postEvent(event))
- event->ignore();
+ if (event->source() == Qt::MouseEventSynthesizedBySystem) {
+ emit panChanged(QPointF(event->pixelDelta()));
+ event->accept();
+ return true;
} else if (event->source() == Qt::MouseEventNotSynthesized) {
- if (event->modifiers().testFlag(Qt::ControlModifier)) {
- if (QPointF angle = event->angleDelta(); !angle.isNull()) {
- double delta = std::abs(angle.x()) > std::abs(angle.y()) ? angle.x() : angle.y();
- if (delta > 0)
- emit zoomIn();
- else
- emit zoomOut();
- event->accept();
- return true;
+
+ auto zoomInSignal = QMetaMethod::fromSignal(&Navigation2dFilter::zoomIn);
+ bool zoomInConnected = QObject::isSignalConnected(zoomInSignal);
+
+ auto zoomOutSignal = QMetaMethod::fromSignal(&Navigation2dFilter::zoomOut);
+ bool zoomOutConnected = QObject::isSignalConnected(zoomOutSignal);
+
+ if (zoomInConnected && zoomOutConnected) {
+ if (event->modifiers().testFlag(Qt::ControlModifier)) {
+ if (QPointF angle = event->angleDelta(); !angle.isNull()) {
+ double delta = std::abs(angle.x()) > std::abs(angle.y()) ? angle.x() : angle.y();
+ if (delta > 0)
+ emit zoomIn();
+ else
+ emit zoomOut();
+ event->accept();
+ return true;
+ }
}
}
}
- return true;
+ return false;
}
} // End namespace QmlDesigner.
diff --git a/src/plugins/qmldesigner/components/componentcore/navigation2d.h b/src/plugins/qmldesigner/components/componentcore/navigation2d.h
index fe432b4a6b4..8a4513ed821 100644
--- a/src/plugins/qmldesigner/components/componentcore/navigation2d.h
+++ b/src/plugins/qmldesigner/components/componentcore/navigation2d.h
@@ -24,27 +24,14 @@
****************************************************************************/
#pragma once
-#include
+#include
QT_FORWARD_DECLARE_CLASS(QGestureEvent)
+QT_FORWARD_DECLARE_CLASS(QScrollBar)
QT_FORWARD_DECLARE_CLASS(QWheelEvent)
namespace QmlDesigner {
-class Navigation2dScrollBar : public QScrollBar
-{
- Q_OBJECT
-
-public:
- Navigation2dScrollBar(QWidget *parent = nullptr);
-
- bool postEvent(QEvent *event);
-
-protected:
- void wheelEvent(QWheelEvent *event) override;
-};
-
-
class Navigation2dFilter : public QObject
{
Q_OBJECT
@@ -57,7 +44,9 @@ signals:
void zoomOut();
public:
- Navigation2dFilter(QWidget *parent = nullptr, Navigation2dScrollBar *scrollbar = nullptr);
+ static void scroll(const QPointF &direction, QScrollBar *sbx, QScrollBar *sby);
+
+ Navigation2dFilter(QWidget *parent);
protected:
bool eventFilter(QObject *obj, QEvent *event) override;
@@ -65,7 +54,6 @@ protected:
private:
bool gestureEvent(QGestureEvent *event);
bool wheelEvent(QWheelEvent *event);
- Navigation2dScrollBar *m_scrollbar = nullptr;
};
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp b/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp
index acc77acf0a5..534799efcd9 100644
--- a/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/curveeditor.cpp
@@ -32,6 +32,7 @@
#include
#include
#include
+#include
#include
#include
@@ -40,16 +41,20 @@ namespace QmlDesigner {
CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent)
: QWidget(parent)
, m_tree(new TreeView(model, this))
- , m_view(new GraphicsView(model))
+ , m_view(new GraphicsView(model, this))
{
auto *splitter = new QSplitter;
splitter->addWidget(m_tree);
splitter->addWidget(m_view);
splitter->setStretchFactor(1, 2);
+ QScrollArea* area = new QScrollArea;
+ area->setWidget(splitter);
+ area->setWidgetResizable(true);
+
auto *box = new QVBoxLayout;
box->addWidget(createToolBar(model));
- box->addWidget(splitter);
+ box->addWidget(area);
setLayout(box);
connect(m_tree, &TreeView::treeItemLocked, model, &CurveEditorModel::setLocked);
diff --git a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
index 23daabba66e..02a8dcd3a76 100644
--- a/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
+++ b/src/plugins/qmldesigner/components/curveeditor/detail/graphicsview.cpp
@@ -45,6 +45,18 @@
namespace QmlDesigner {
+template< typename T >
+T* nextParentOfType(QWidget* widget)
+{
+ auto* p = widget->parent();
+ while (p) {
+ if (T* w = qobject_cast(p))
+ return w;
+ p = p->parent();
+ }
+ return nullptr;
+}
+
GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent)
: QGraphicsView(parent)
, m_dragging(false)
@@ -65,7 +77,7 @@ GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent)
setResizeAnchor(QGraphicsView::NoAnchor);
setRenderHint(QPainter::Antialiasing, true);
setTransformationAnchor(QGraphicsView::NoAnchor);
- setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
@@ -78,12 +90,19 @@ GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent)
connect(m_scene, &GraphicsScene::curveChanged, itemSlot);
- QmlDesigner::Navigation2dFilter *filter = new QmlDesigner::Navigation2dFilter(this);
+ QmlDesigner::Navigation2dFilter *filter = new QmlDesigner::Navigation2dFilter(viewport());
+ connect(filter, &Navigation2dFilter::panChanged, [this](const QPointF &direction) {
+ QScrollBar* verticalBar = nullptr;
+ if (QScrollArea* area = nextParentOfType< QScrollArea >(this))
+ verticalBar = area->verticalScrollBar();
+ Navigation2dFilter::scroll(direction, horizontalScrollBar(), verticalBar);
+ });
+
auto zoomChanged = &QmlDesigner::Navigation2dFilter::zoomChanged;
connect(filter, zoomChanged, [this](double scale, const QPointF &pos) {
applyZoom(m_zoomX + scale, m_zoomY, mapToGlobal(pos.toPoint()));
});
- installEventFilter(filter);
+ viewport()->installEventFilter(filter);
applyZoom(m_zoomX, m_zoomY);
update();
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
index 175b081a35a..e5a8c1747aa 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dview.cpp
@@ -31,7 +31,6 @@
#include
#include
-#include
#include
#include
#include
@@ -324,10 +323,6 @@ void Edit3DView::addQuick3DImport()
} else {
model()->changeImports({import}, {});
}
-
- // Subcomponent manager update needed to make item library entries appear
- QmlDesignerPlugin::instance()->currentDesignDocument()
- ->updateSubcomponentManagerImport(import);
return;
}
}
diff --git a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp
index 835ba07b5b2..968cab58466 100644
--- a/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp
+++ b/src/plugins/qmldesigner/components/edit3d/edit3dwidget.cpp
@@ -177,18 +177,22 @@ void Edit3DWidget::dropEvent(QDropEvent *dropEvent)
->viewManager().designerActionManager();
QHash addedAssets = actionManager.handleExternalAssetsDrop(dropEvent->mimeData());
- // add 3D assets to 3d editor (QtQuick3D import will be added if missing)
- ItemLibraryInfo *itemLibInfo = m_view->model()->metaInfo().itemLibraryInfo();
+ view()->executeInTransaction("Edit3DWidget::dropEvent", [&] {
+ // add 3D assets to 3d editor (QtQuick3D import will be added if missing)
+ ItemLibraryInfo *itemLibInfo = m_view->model()->metaInfo().itemLibraryInfo();
- const QStringList added3DAssets = addedAssets.value(ComponentCoreConstants::add3DAssetsDisplayString);
- for (const QString &assetPath : added3DAssets) {
- QString fileName = QFileInfo(assetPath).baseName();
- fileName = fileName.at(0).toUpper() + fileName.mid(1); // capitalize first letter
- QString type = QString("Quick3DAssets.%1.%1").arg(fileName);
- QList entriesForType = itemLibInfo->entriesForType(type.toLatin1());
- if (!entriesForType.isEmpty()) // should always be true, but just in case
- QmlVisualNode::createQml3DNode(view(), entriesForType.at(0), m_canvas->activeScene()).modelNode();
- }
+ const QStringList added3DAssets = addedAssets.value(ComponentCoreConstants::add3DAssetsDisplayString);
+ for (const QString &assetPath : added3DAssets) {
+ QString fileName = QFileInfo(assetPath).baseName();
+ fileName = fileName.at(0).toUpper() + fileName.mid(1); // capitalize first letter
+ QString type = QString("Quick3DAssets.%1.%1").arg(fileName);
+ QList entriesForType = itemLibInfo->entriesForType(type.toLatin1());
+ if (!entriesForType.isEmpty()) { // should always be true, but just in case
+ QmlVisualNode::createQml3DNode(view(), entriesForType.at(0),
+ m_canvas->activeScene(), {}, false).modelNode();
+ }
+ }
+ });
}
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorgraphicsview.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorgraphicsview.cpp
index 4cfa6402d56..d98e43ffef9 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorgraphicsview.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorgraphicsview.cpp
@@ -62,28 +62,12 @@ FormEditorGraphicsView::FormEditorGraphicsView(QWidget *parent)
// eventFilter method so it works also for the space scrolling case as expected
QCoreApplication::instance()->installEventFilter(this);
- QmlDesigner::Navigation2dFilter *filter = new QmlDesigner::Navigation2dFilter(this);
+ QmlDesigner::Navigation2dFilter *filter = new QmlDesigner::Navigation2dFilter(viewport());
connect(filter, &Navigation2dFilter::zoomIn, this, &FormEditorGraphicsView::zoomIn);
connect(filter, &Navigation2dFilter::zoomOut, this, &FormEditorGraphicsView::zoomOut);
- auto panChanged = &Navigation2dFilter::panChanged;
- connect(filter, panChanged, [this](const QPointF &direction) {
- QScrollBar *sbx = horizontalScrollBar();
- QScrollBar *sby = verticalScrollBar();
-
- // max - min + pageStep = sceneRect.size * scale
- QPointF min(sbx->minimum(), sby->minimum());
- QPointF max(sbx->maximum(), sby->maximum());
- QPointF step(sbx->pageStep(), sby->pageStep());
-
- QPointF d1 = max - min;
- QPointF d2 = d1 + step;
-
- QPoint val = QPointF((direction.x() / d2.x()) * d1.x(), (direction.y() / d2.y()) * d1.y())
- .toPoint();
-
- sbx->setValue(sbx->value() - val.x());
- sby->setValue(sby->value() - val.y());
+ connect(filter, &Navigation2dFilter::panChanged, [this](const QPointF &direction) {
+ Navigation2dFilter::scroll(direction, horizontalScrollBar(), verticalScrollBar());
});
auto zoomChanged = &Navigation2dFilter::zoomChanged;
@@ -93,7 +77,7 @@ FormEditorGraphicsView::FormEditorGraphicsView(QWidget *parent)
emit this->zoomChanged(transform().m11());
}
});
- installEventFilter(filter);
+ viewport()->installEventFilter(filter);
}
bool FormEditorGraphicsView::eventFilter(QObject *watched, QEvent *event)
@@ -123,8 +107,8 @@ void FormEditorGraphicsView::wheelEvent(QWheelEvent *event)
{
if (event->modifiers().testFlag(Qt::ControlModifier))
event->ignore();
- else if (event->source() == Qt::MouseEventNotSynthesized)
- QGraphicsView::wheelEvent(event);
+
+ QGraphicsView::wheelEvent(event);
}
void FormEditorGraphicsView::mousePressEvent(QMouseEvent *event)
diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp
index e7e3d69d6a3..842dee7e130 100644
--- a/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp
+++ b/src/plugins/qmldesigner/components/formeditor/formeditorwidget.cpp
@@ -599,20 +599,24 @@ void FormEditorWidget::dropEvent(QDropEvent *dropEvent)
->viewManager().designerActionManager();
QHash addedAssets = actionManager.handleExternalAssetsDrop(dropEvent->mimeData());
- // Create Image components for added image assets
- const QStringList addedImages = addedAssets.value(ComponentCoreConstants::addImagesDisplayString);
- for (const QString &imgPath : addedImages) {
- QmlItemNode::createQmlItemNodeFromImage(m_formEditorView, imgPath, {},
- m_formEditorView->scene()->rootFormEditorItem()->qmlItemNode());
- }
+ m_formEditorView->executeInTransaction("FormEditorWidget::dropEvent", [&] {
+ // Create Image components for added image assets
+ const QStringList addedImages = addedAssets.value(ComponentCoreConstants::addImagesDisplayString);
+ for (const QString &imgPath : addedImages) {
+ QmlItemNode::createQmlItemNodeFromImage(m_formEditorView, imgPath, {},
+ m_formEditorView->scene()->rootFormEditorItem()->qmlItemNode(),
+ false);
+ }
- // Create Text components for added font assets
- const QStringList addedFonts = addedAssets.value(ComponentCoreConstants::addFontsDisplayString);
- for (const QString &fontPath : addedFonts) {
- QString fontFamily = QFileInfo(fontPath).baseName();
- QmlItemNode::createQmlItemNodeFromFont(m_formEditorView, fontFamily, rootItemRect().center(),
- m_formEditorView->scene()->rootFormEditorItem()->qmlItemNode());
- }
+ // Create Text components for added font assets
+ const QStringList addedFonts = addedAssets.value(ComponentCoreConstants::addFontsDisplayString);
+ for (const QString &fontPath : addedFonts) {
+ QString fontFamily = QFileInfo(fontPath).baseName();
+ QmlItemNode::createQmlItemNodeFromFont(m_formEditorView, fontFamily, rootItemRect().center(),
+ m_formEditorView->scene()->rootFormEditorItem()->qmlItemNode(),
+ false);
+ }
+ });
}
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/components/integration/designdocument.cpp b/src/plugins/qmldesigner/components/integration/designdocument.cpp
index 0b7d7fa2c92..2659ffbbd75 100644
--- a/src/plugins/qmldesigner/components/integration/designdocument.cpp
+++ b/src/plugins/qmldesigner/components/integration/designdocument.cpp
@@ -388,9 +388,9 @@ void DesignDocument::updateSubcomponentManager()
currentModel()->imports() + currentModel()->possibleImports());
}
-void DesignDocument::updateSubcomponentManagerImport(const Import &import)
+void DesignDocument::addSubcomponentManagerImport(const Import &import)
{
- m_subComponentManager->updateImport(import);
+ m_subComponentManager->addAndParseImport(import);
}
void DesignDocument::deleteSelected()
diff --git a/src/plugins/qmldesigner/components/integration/designdocument.h b/src/plugins/qmldesigner/components/integration/designdocument.h
index 0e73c13e31c..0d80f344de1 100644
--- a/src/plugins/qmldesigner/components/integration/designdocument.h
+++ b/src/plugins/qmldesigner/components/integration/designdocument.h
@@ -69,7 +69,7 @@ public:
void attachRewriterToModel();
void close();
void updateSubcomponentManager();
- void updateSubcomponentManagerImport(const Import &import);
+ void addSubcomponentManagerImport(const Import &import);
bool isUndoAvailable() const;
bool isRedoAvailable() const;
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp
index 69ac3ff3165..90ed6b03821 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp
@@ -686,8 +686,6 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport()
model->changeImports(newImportsToAdd, {});
transaction.commit();
- for (const Import &import : qAsConst(newImportsToAdd))
- doc->updateSubcomponentManagerImport(import);
}
} catch (const RewritingException &e) {
addError(tr("Failed to update imports: %1").arg(e.description()));
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp
index 9c8b4e09f90..95f1fc3faa5 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp
@@ -132,6 +132,10 @@ void ItemLibraryView::modelAboutToBeDetached(Model *model)
void ItemLibraryView::importsChanged(const QList &addedImports, const QList &removedImports)
{
+ DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
+ for (const auto &import : addedImports)
+ document->addSubcomponentManagerImport(import);
+
updateImports();
// TODO: generalize the logic below to allow adding/removing any Qml component when its import is added/removed
@@ -165,6 +169,10 @@ void ItemLibraryView::importsChanged(const QList &addedImports, const QL
void ItemLibraryView::possibleImportsChanged(const QList &possibleImports)
{
+ DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
+ for (const auto &import : possibleImports)
+ document->addSubcomponentManagerImport(import);
+
m_widget->updatePossibleImports(possibleImports);
}
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp
index ef1e85287a7..28b5d9fb947 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp
@@ -357,7 +357,6 @@ void ItemLibraryWidget::handleAddImport(int index)
auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
document->documentModel()->changeImports({import}, {});
- document->updateSubcomponentManagerImport(import);
m_stackedWidget->setCurrentIndex(0); // switch to the Components view after import is added
updateSearch();
diff --git a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp
index 08dfc9fd039..03386b38f1a 100644
--- a/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp
+++ b/src/plugins/qmldesigner/components/navigator/navigatortreemodel.cpp
@@ -316,7 +316,12 @@ QList filteredList(const NodeListProperty &property, bool filter, boo
if (filter) {
list.append(Utils::filtered(property.toModelNodeList(), [] (const ModelNode &arg) {
- return QmlItemNode::isValidQmlItemNode(arg) || NodeHints::fromModelNode(arg).visibleInNavigator();
+ const char auxProp[] = "showInNavigator@Internal";
+ if (arg.hasAuxiliaryData(auxProp))
+ return arg.auxiliaryData(auxProp).toBool();
+ const bool value = QmlItemNode::isValidQmlItemNode(arg) || NodeHints::fromModelNode(arg).visibleInNavigator();
+ arg.setAuxiliaryData(auxProp, value);
+ return value;
}));
} else {
list = property.toModelNodeList();
@@ -879,7 +884,6 @@ void NavigatorTreeModel::addImport(const QString &importName)
if (possImport.url() == import.url()) {
import = possImport;
m_view->model()->changeImports({import}, {});
- QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManagerImport(import);
break;
}
}
diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp
index b583863015f..f4ff114bf62 100644
--- a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp
+++ b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.cpp
@@ -118,7 +118,7 @@ TimelineWidget::TimelineWidget(TimelineView *view)
, m_toolbar(new TimelineToolBar(this))
, m_rulerView(new QGraphicsView(this))
, m_graphicsView(new QGraphicsView(this))
- , m_scrollbar(new Navigation2dScrollBar(this))
+ , m_scrollbar(new QScrollBar(this))
, m_statusBar(new QLabel(this))
, m_timelineView(view)
, m_graphicsScene(new TimelineGraphicsScene(this))
@@ -160,7 +160,6 @@ TimelineWidget::TimelineWidget(TimelineView *view)
m_graphicsView->setFrameShape(QFrame::NoFrame);
m_graphicsView->setFrameShadow(QFrame::Plain);
m_graphicsView->setLineWidth(0);
- m_graphicsView->setVerticalScrollBar(new Navigation2dScrollBar);
m_graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
m_graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@@ -274,13 +273,19 @@ TimelineWidget::TimelineWidget(TimelineView *view)
m_timelineView->addNewTimelineDialog();
});
- Navigation2dFilter *filter = new Navigation2dFilter(this, m_scrollbar);
- connect(filter, &Navigation2dFilter::zoomChanged, [this](double scale, const QPointF& pos) {
- int s = static_cast(std::round(scale*100.));
- double ps = m_graphicsScene->mapFromScene(pos.x());
- m_graphicsScene->setZoom(std::clamp(m_graphicsScene->zoom() + s, 0, 100), ps);
+ Navigation2dFilter *filter = new Navigation2dFilter(m_graphicsView->viewport());
+ connect(filter, &Navigation2dFilter::panChanged, [this](const QPointF &direction) {
+ Navigation2dFilter::scroll(direction, m_scrollbar, m_graphicsView->verticalScrollBar());
});
- installEventFilter(filter);
+
+ connect(filter, &Navigation2dFilter::zoomChanged, [this](double scale, const QPointF &pos) {
+ int s = static_cast(std::round(scale*100.));
+ int scaleFactor = std::clamp(m_graphicsScene->zoom() + s, 0, 100);
+ double ps = m_graphicsScene->mapFromScene(pos.x());
+ m_graphicsScene->setZoom(scaleFactor, ps);
+ m_toolbar->setScaleFactor(scaleFactor);
+ });
+ m_graphicsView->viewport()->installEventFilter(filter);
m_playbackAnimation->stop();
auto playAnimation = [this](QVariant frame) { graphicsScene()->setCurrentFrame(qRound(frame.toDouble())); };
diff --git a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.h b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.h
index 3fa3db1abf9..ebaf00104dc 100644
--- a/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.h
+++ b/src/plugins/qmldesigner/components/timelineeditor/timelinewidget.h
@@ -40,6 +40,7 @@ QT_FORWARD_DECLARE_CLASS(QShowEvent)
QT_FORWARD_DECLARE_CLASS(QString)
QT_FORWARD_DECLARE_CLASS(QPushButton)
QT_FORWARD_DECLARE_CLASS(QVariantAnimation)
+QT_FORWARD_DECLARE_CLASS(QScrollBar)
namespace QmlDesigner {
@@ -97,7 +98,7 @@ private:
QGraphicsView *m_graphicsView = nullptr;
- Navigation2dScrollBar *m_scrollbar = nullptr;
+ QScrollBar *m_scrollbar = nullptr;
QLabel *m_statusBar = nullptr;
diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.cpp b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.cpp
index 1c8c042fdc3..6077c9de28c 100644
--- a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.cpp
+++ b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.cpp
@@ -90,7 +90,7 @@ TransitionEditorWidget::TransitionEditorWidget(TransitionEditorView *view)
, m_toolbar(new TransitionEditorToolBar(this))
, m_rulerView(new QGraphicsView(this))
, m_graphicsView(new QGraphicsView(this))
- , m_scrollbar(new Navigation2dScrollBar(this))
+ , m_scrollbar(new QScrollBar(this))
, m_statusBar(new QLabel(this))
, m_transitionEditorView(view)
, m_graphicsScene(new TransitionEditorGraphicsScene(this))
@@ -129,7 +129,6 @@ TransitionEditorWidget::TransitionEditorWidget(TransitionEditorView *view)
m_graphicsView->setFrameShape(QFrame::NoFrame);
m_graphicsView->setFrameShadow(QFrame::Plain);
m_graphicsView->setLineWidth(0);
- m_graphicsView->setVerticalScrollBar(new Navigation2dScrollBar);
m_graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
m_graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
@@ -223,13 +222,19 @@ TransitionEditorWidget::TransitionEditorWidget(TransitionEditorView *view)
m_transitionEditorView->addNewTransition();
});
- Navigation2dFilter *filter = new Navigation2dFilter(this, m_scrollbar);
- connect(filter, &Navigation2dFilter::zoomChanged, [this](double scale, const QPointF& pos) {
- int s = static_cast(std::round(scale*100.));
- double ps = m_graphicsScene->mapFromScene(pos.x());
- m_graphicsScene->setZoom(std::clamp(m_graphicsScene->zoom() + s, 0, 100), ps);
+ Navigation2dFilter *filter = new Navigation2dFilter(m_graphicsView->viewport());
+ connect(filter, &Navigation2dFilter::panChanged, [this](const QPointF &direction) {
+ Navigation2dFilter::scroll(direction, m_scrollbar, m_graphicsView->verticalScrollBar());
});
- installEventFilter(filter);
+
+ connect(filter, &Navigation2dFilter::zoomChanged, [this](double scale, const QPointF &pos) {
+ int s = static_cast(std::round(scale*100.));
+ int scaleFactor = std::clamp(m_graphicsScene->zoom() + s, 0, 100);
+ double ps = m_graphicsScene->mapFromScene(pos.x());
+ m_graphicsScene->setZoom(scaleFactor, ps);
+ m_toolbar->setScaleFactor(scaleFactor);
+ });
+ m_graphicsView->viewport()->installEventFilter(filter);
}
void TransitionEditorWidget::setTransitionActive(bool b)
diff --git a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.h b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.h
index f1c4174418a..ea4b2a6affa 100644
--- a/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.h
+++ b/src/plugins/qmldesigner/components/transitioneditor/transitioneditorwidget.h
@@ -40,6 +40,7 @@ QT_FORWARD_DECLARE_CLASS(QResizeEvent)
QT_FORWARD_DECLARE_CLASS(QShowEvent)
QT_FORWARD_DECLARE_CLASS(QString)
QT_FORWARD_DECLARE_CLASS(QPushButton)
+QT_FORWARD_DECLARE_CLASS(QScrollBar)
namespace QmlDesigner {
@@ -47,7 +48,6 @@ class TransitionEditorView;
class TransitionEditorToolBar;
class TransitionEditorGraphicsScene;
class ModelNode;
-class Navigation2dScrollBar;
class TransitionEditorWidget : public QWidget
{
@@ -88,7 +88,7 @@ private:
QGraphicsView *m_graphicsView = nullptr;
- Navigation2dScrollBar *m_scrollbar = nullptr;
+ QScrollBar *m_scrollbar = nullptr;
QLabel *m_statusBar = nullptr;
diff --git a/src/plugins/qmldesigner/designercore/include/componenttextmodifier.h b/src/plugins/qmldesigner/designercore/include/componenttextmodifier.h
index d870f29622a..d35a4c149ee 100644
--- a/src/plugins/qmldesigner/designercore/include/componenttextmodifier.h
+++ b/src/plugins/qmldesigner/designercore/include/componenttextmodifier.h
@@ -62,11 +62,14 @@ public:
{ return false; }
private:
+ void handleOriginalTextChanged();
+
TextModifier *m_originalModifier;
int m_componentStartOffset;
int m_componentEndOffset;
int m_rootStartOffset;
int m_startLength;
+ QString m_originalText;
};
} // namespace QmlDesigner
diff --git a/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h b/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h
index 114fef0d63c..af209245479 100644
--- a/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h
+++ b/src/plugins/qmldesigner/designercore/include/qmlvisualnode.h
@@ -101,8 +101,9 @@ public:
bool createInTransaction = true);
static QmlVisualNode createQml3DNode(AbstractView *view,
- const ItemLibraryEntry &itemLibraryEntry,
- qint32 sceneRootId = -1, const QVector3D &position = {});
+ const ItemLibraryEntry &itemLibraryEntry,
+ qint32 sceneRootId = -1, const QVector3D &position = {},
+ bool createInTransaction = true);
static NodeListProperty findSceneNodeProperty(AbstractView *view, qint32 sceneRootId);
diff --git a/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h b/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h
index 66e93abda3a..556a7f5a0d6 100644
--- a/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h
+++ b/src/plugins/qmldesigner/designercore/include/subcomponentmanager.h
@@ -49,7 +49,7 @@ public:
explicit SubComponentManager(Model *model, QObject *parent = nullptr);
void update(const QUrl &fileUrl, const QList &imports);
- void updateImport(const Import &import);
+ void addAndParseImport(const Import &import);
QStringList qmlFiles() const;
QStringList directories() const;
@@ -59,7 +59,7 @@ private: // functions
void parseFile(const QString &canonicalFilePath, bool addToLibrary, const QString&);
void parseFile(const QString &canonicalFilePath);
- void addImport(const Import &import, int index = -1);
+ bool addImport(const Import &import, int index = -1);
void removeImport(int index);
void parseDirectories();
QFileInfoList watchedFiles(const QString &canonicalDirPath);
diff --git a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp b/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp
index 4e1fd500664..63185d8dfb0 100644
--- a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp
+++ b/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp
@@ -69,16 +69,18 @@ SubComponentManager::SubComponentManager(Model *model, QObject *parent)
this, [this](const QString &path) { parseDirectory(path); });
}
-void SubComponentManager::addImport(const Import &import, int index)
+bool SubComponentManager::addImport(const Import &import, int index)
{
if (debug)
qDebug() << Q_FUNC_INFO << index << import.file().toUtf8();
+ bool importExists = false;
if (import.isFileImport()) {
QFileInfo dirInfo = QFileInfo(m_filePath.resolved(import.file()).toLocalFile());
if (dirInfo.exists() && dirInfo.isDir()) {
const QString canonicalDirPath = dirInfo.canonicalFilePath();
m_watcher.addPath(canonicalDirPath);
+ importExists = true;
//m_dirToQualifier.insertMulti(canonicalDirPath, import.qualifier()); ### todo: proper support for import as
}
} else {
@@ -91,16 +93,21 @@ void SubComponentManager::addImport(const Import &import, int index)
if (dirInfo.exists() && dirInfo.isDir()) {
const QString canonicalDirPath = dirInfo.canonicalFilePath();
m_watcher.addPath(canonicalDirPath);
+ importExists = true;
//m_dirToQualifier.insertMulti(canonicalDirPath, import.qualifier()); ### todo: proper support for import as
}
}
// TODO: QDeclarativeDomImport::Library
}
- if (index == -1)
- m_imports.append(import);
- else
- m_imports.insert(index, import);
+ if (importExists) {
+ if (index == -1)
+ m_imports.append(import);
+ else
+ m_imports.insert(index, import);
+ }
+
+ return importExists;
}
void SubComponentManager::removeImport(int index)
@@ -544,9 +551,15 @@ void SubComponentManager::update(const QUrl &filePath, const QList &impo
parseDirectories();
}
-void SubComponentManager::updateImport(const Import &import)
+void SubComponentManager::addAndParseImport(const Import &import)
{
- addImport(import);
+ for (const auto &existingImport : std::as_const(m_imports)) {
+ if (import == existingImport)
+ return;
+ }
+
+ if (!addImport(import))
+ return;
if (import.isFileImport()) {
QFileInfo dirInfo = QFileInfo(m_filePath.resolved(import.file()).toLocalFile());
diff --git a/src/plugins/qmldesigner/designercore/model/componenttextmodifier.cpp b/src/plugins/qmldesigner/designercore/model/componenttextmodifier.cpp
index 5f984a1f348..42dbbdd2a0e 100644
--- a/src/plugins/qmldesigner/designercore/model/componenttextmodifier.cpp
+++ b/src/plugins/qmldesigner/designercore/model/componenttextmodifier.cpp
@@ -33,10 +33,13 @@ ComponentTextModifier::ComponentTextModifier(TextModifier *originalModifier, int
m_componentEndOffset(componentEndOffset),
m_rootStartOffset(rootStartOffset)
{
- connect(m_originalModifier, &TextModifier::textChanged, this, &TextModifier::textChanged);
+ connect(m_originalModifier, &TextModifier::textChanged,
+ this, &ComponentTextModifier::handleOriginalTextChanged);
connect(m_originalModifier, &TextModifier::replaced, this, &TextModifier::replaced);
connect(m_originalModifier, &TextModifier::moved, this, &TextModifier::moved);
+
+ m_originalText = m_originalModifier->text();
}
ComponentTextModifier::~ComponentTextModifier() = default;
@@ -146,3 +149,45 @@ void ComponentTextModifier::reactivateChangeSignals()
{
m_originalModifier->reactivateChangeSignals();
}
+
+void ComponentTextModifier::handleOriginalTextChanged()
+{
+ // Update offsets when original text changes, if necessary
+
+ // Detect and adjust for removal/addition of unrelated text before the subcomponent code,
+ // as that can happen even without user editing the text (e.g. whitespace removal at save time)
+
+ const QString currentText = m_originalModifier->text();
+
+ if (m_originalText.left(m_componentStartOffset) != currentText.left(m_componentStartOffset)) {
+ // Subcomponent item id is the only reliable indicator for adjustment
+ const int idIndex = m_originalText.indexOf("id:", m_componentStartOffset);
+ if (idIndex != -1 && idIndex < m_componentEndOffset) {
+ int newLineIndex = m_originalText.indexOf('\n', idIndex);
+ if (newLineIndex != -1) {
+ const QString checkLine = m_originalText.mid(idIndex, newLineIndex - idIndex);
+ int lineIndex = currentText.indexOf(checkLine);
+ if (lineIndex != -1) {
+ // Paranoia check - This shouldn't happen except when modifying text manually,
+ // but it's possible something was inserted between id and start
+ // of the component, which would throw off the calculation, so check that
+ // the first line is still correct even with new offset.
+ const int diff = idIndex - lineIndex;
+ newLineIndex = m_originalText.indexOf('\n', m_componentStartOffset);
+ if (newLineIndex != -1) {
+ const QString firstLine = m_originalText.mid(m_componentStartOffset,
+ newLineIndex - m_componentStartOffset);
+ const int newStart = m_componentStartOffset - diff;
+ if (firstLine == currentText.mid(newStart, firstLine.size())) {
+ m_componentEndOffset -= diff;
+ m_componentStartOffset = newStart;
+ m_originalText = currentText;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ emit textChanged();
+}
diff --git a/src/plugins/qmldesigner/designercore/model/modeltotextmerger.cpp b/src/plugins/qmldesigner/designercore/model/modeltotextmerger.cpp
index b2f36b54565..5a4276a416f 100644
--- a/src/plugins/qmldesigner/designercore/model/modeltotextmerger.cpp
+++ b/src/plugins/qmldesigner/designercore/model/modeltotextmerger.cpp
@@ -74,8 +74,13 @@ void ModelToTextMerger::nodeRemoved(const ModelNode &removedNode, const NodeAbst
void ModelToTextMerger::propertiesRemoved(const QList& propertyList)
{
foreach (const AbstractProperty &property, propertyList) {
- if (isInHierarchy(property) && !property.isDefaultProperty())
+ // Default property that has actual binding/value should be removed
+ if (isInHierarchy(property) && (!property.isDefaultProperty()
+ || property.isBindingProperty()
+ || property.isVariantProperty()
+ || property.isNodeProperty())) {
schedule(new RemovePropertyRewriteAction(property));
+ }
}
}
diff --git a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp
index 02ecb64efde..c65f281f64a 100644
--- a/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp
+++ b/src/plugins/qmldesigner/designercore/model/qmlitemnode.cpp
@@ -174,7 +174,7 @@ QmlItemNode QmlItemNode::createQmlItemNodeFromFont(AbstractView *view,
};
if (executeInTransaction)
- view->executeInTransaction("QmlItemNode::createQmlItemNodeFromImage", doCreateQmlItemNodeFromFont);
+ view->executeInTransaction("QmlItemNode::createQmlItemNodeFromFont", doCreateQmlItemNodeFromFont);
else
doCreateQmlItemNodeFromFont();
diff --git a/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp b/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp
index 544471b03cc..f26c32ad780 100644
--- a/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp
+++ b/src/plugins/qmldesigner/designercore/model/qmlvisualnode.cpp
@@ -365,14 +365,15 @@ QmlObjectNode QmlVisualNode::createQmlObjectNode(AbstractView *view,
QmlVisualNode QmlVisualNode::createQml3DNode(AbstractView *view,
const ItemLibraryEntry &itemLibraryEntry,
- qint32 sceneRootId, const QVector3D &position)
+ qint32 sceneRootId, const QVector3D &position,
+ bool createInTransaction)
{
NodeAbstractProperty sceneNodeProperty = sceneRootId != -1 ? findSceneNodeProperty(view, sceneRootId)
: view->rootModelNode().defaultNodeAbstractProperty();
QTC_ASSERT(sceneNodeProperty.isValid(), return {});
- return createQmlObjectNode(view, itemLibraryEntry, position, sceneNodeProperty).modelNode();
+ return createQmlObjectNode(view, itemLibraryEntry, position, sceneNodeProperty, createInTransaction).modelNode();
}
NodeListProperty QmlVisualNode::findSceneNodeProperty(AbstractView *view, qint32 sceneRootId)
diff --git a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp
index e33c82b1245..84b3678f5d5 100644
--- a/src/plugins/qmldesigner/designercore/model/rewriterview.cpp
+++ b/src/plugins/qmldesigner/designercore/model/rewriterview.cpp
@@ -173,14 +173,27 @@ void RewriterView::propertiesAboutToBeRemoved(const QList &pro
if (textToModelMerger()->isActive())
return;
+ for (const AbstractProperty &property : propertyList) {
+ if (!property.isDefaultProperty())
+ continue;
- foreach (const AbstractProperty &property, propertyList) {
- if (property.isDefaultProperty() && property.isNodeListProperty()) {
- m_removeDefaultPropertyTransaction = beginRewriterTransaction(QByteArrayLiteral("RewriterView::propertiesAboutToBeRemoved"));
+ if (!m_removeDefaultPropertyTransaction.isValid()) {
+ m_removeDefaultPropertyTransaction = beginRewriterTransaction(
+ QByteArrayLiteral("RewriterView::propertiesAboutToBeRemoved"));
+ }
- foreach (const ModelNode &node, property.toNodeListProperty().toModelNodeList()) {
- modelToTextMerger()->nodeRemoved(node, property.toNodeAbstractProperty(), AbstractView::NoAdditionalChanges);
+ if (property.isNodeListProperty()) {
+ const auto nodeList = property.toNodeListProperty().toModelNodeList();
+ for (const ModelNode &node : nodeList) {
+ modelToTextMerger()->nodeRemoved(node, property.toNodeAbstractProperty(),
+ AbstractView::NoAdditionalChanges);
}
+ } else if (property.isBindingProperty() || property.isVariantProperty()
+ || property.isNodeProperty()) {
+ // Default property that has actual binding/value should be removed.
+ // We need to do it here in propertiesAboutToBeRemoved, because
+ // type is no longer determinable after property is removed from the model.
+ modelToTextMerger()->propertiesRemoved({property});
}
}
}
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp
index b8affa11ff7..f23b43ddd95 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.cpp
+++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp
@@ -33,7 +33,6 @@
#include "generateresource.h"
#include "generatecmakelists.h"
#include "nodeinstanceview.h"
-#include "gestures.h"
#include
#include
@@ -232,8 +231,6 @@ bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *e
if (QFontDatabase::addApplicationFont(fontPath) < 0)
qCWarning(qmldesignerLog) << "Could not add font " << fontPath << "to font database";
- TwoFingerSwipe::registerRecognizer();
-
return true;
}
diff --git a/src/plugins/qmldesigner/qmldesignerplugin.qbs b/src/plugins/qmldesigner/qmldesignerplugin.qbs
index a3b70ec9706..2ff2d3cb2bb 100644
--- a/src/plugins/qmldesigner/qmldesignerplugin.qbs
+++ b/src/plugins/qmldesigner/qmldesignerplugin.qbs
@@ -461,8 +461,6 @@ Project {
"componentcore/findimplementation.h",
"componentcore/formatoperation.cpp",
"componentcore/formatoperation.h",
- "componentcore/gestures.cpp",
- "componentcore/gestures.h",
"componentcore/layoutingridlayout.cpp",
"componentcore/layoutingridlayout.h",
"componentcore/theme.cpp",
diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp
index b026363b34a..0a8d55818a4 100644
--- a/src/plugins/qtsupport/qtoptionspage.cpp
+++ b/src/plugins/qtsupport/qtoptionspage.cpp
@@ -177,7 +177,7 @@ public:
QtOptionsPageWidget();
~QtOptionsPageWidget();
- static void linkWithQt();
+ static bool linkWithQt();
private:
void apply() final;
@@ -857,7 +857,16 @@ void QtOptionsPageWidget::setupLinkWithQtButton()
QString tip;
canLinkWithQt(&tip);
m_ui.linkWithQtButton->setToolTip(tip);
- connect(m_ui.linkWithQtButton, &QPushButton::clicked, this, &QtOptionsPage::linkWithQt);
+ connect(m_ui.linkWithQtButton, &QPushButton::clicked, this, [this] {
+ if (linkWithQt()) {
+ QWidget *w = window();
+ // close options dialog
+ if (QDialog *dialog = qobject_cast(w))
+ dialog->accept();
+ else
+ window()->close();
+ }
+ });
}
void QtOptionsPageWidget::updateCurrentQtName()
@@ -950,7 +959,7 @@ static FilePath defaultQtInstallationPath()
return FileUtils::homePath() / "Qt";
}
-void QtOptionsPageWidget::linkWithQt()
+bool QtOptionsPageWidget::linkWithQt()
{
const QString title = tr("Choose Qt Installation");
const QString restartText = tr("The change will take effect after restart.");
@@ -1019,8 +1028,9 @@ void QtOptionsPageWidget::linkWithQt()
}
if (askForRestart) {
Core::RestartDialog restartDialog(Core::ICore::dialogParent(), restartText);
- restartDialog.exec();
+ return restartDialog.exec() == QDialog::Accepted;
}
+ return false;
}
// QtOptionsPage
diff --git a/src/plugins/texteditor/codeassist/codeassistant.cpp b/src/plugins/texteditor/codeassist/codeassistant.cpp
index 6aa1436c7dd..7224ef6906c 100644
--- a/src/plugins/texteditor/codeassist/codeassistant.cpp
+++ b/src/plugins/texteditor/codeassist/codeassistant.cpp
@@ -337,6 +337,7 @@ void CodeAssistantPrivate::displayProposal(IAssistProposal *newProposal, AssistR
if (!newProposal->hasItemsToPropose(prefix, reason)) {
if (newProposal->isCorrective(m_editorWidget))
newProposal->makeCorrection(m_editorWidget);
+ destroyContext();
return;
}
diff --git a/src/plugins/texteditor/fontsettings.cpp b/src/plugins/texteditor/fontsettings.cpp
index 4c6df391ce2..ef8a36af948 100644
--- a/src/plugins/texteditor/fontsettings.cpp
+++ b/src/plugins/texteditor/fontsettings.cpp
@@ -417,6 +417,10 @@ bool FontSettings::loadColorScheme(const QString &fileName,
foreach (const FormatDescription &desc, descriptions) {
const TextStyle id = desc.id();
if (!m_scheme.contains(id)) {
+ if (id == C_NAMESPACE && m_scheme.contains(C_TYPE)) {
+ m_scheme.setFormatFor(C_NAMESPACE, m_scheme.formatFor(C_TYPE));
+ continue;
+ }
Format format;
const Format &descFormat = desc.format();
// Default fallback for background and foreground is C_TEXT, which is set through
diff --git a/src/plugins/texteditor/textdocument.cpp b/src/plugins/texteditor/textdocument.cpp
index d9b37a1214e..cee8e3cf314 100644
--- a/src/plugins/texteditor/textdocument.cpp
+++ b/src/plugins/texteditor/textdocument.cpp
@@ -835,7 +835,7 @@ void TextDocument::cleanWhitespace(const QTextCursor &cursor)
void TextDocument::cleanWhitespace(QTextCursor &cursor, bool inEntireDocument,
bool cleanIndentation)
{
- const QString fileName(filePath().fileName());
+ const bool removeTrailingWhitespace = d->m_storageSettings.removeTrailingWhitespace(filePath().fileName());
auto documentLayout = qobject_cast(d->m_document.documentLayout());
Q_ASSERT(cursor.visualNavigation() == false);
@@ -862,7 +862,7 @@ void TextDocument::cleanWhitespace(QTextCursor &cursor, bool inEntireDocument,
foreach (block, blocks) {
QString blockText = block.text();
- if (d->m_storageSettings.removeTrailingWhitespace(fileName))
+ if (removeTrailingWhitespace)
TabSettings::removeTrailingWhitespace(cursor, block);
const int indent = indentations[block.blockNumber()];
diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp
index a0ca47c5413..a54732ec39f 100644
--- a/src/plugins/texteditor/texteditor.cpp
+++ b/src/plugins/texteditor/texteditor.cpp
@@ -1572,6 +1572,7 @@ void TextEditorWidgetPrivate::slotSelectionChanged()
m_selectBlockAnchor = QTextCursor();
// Clear any link which might be showing when the selection changes
clearLink();
+ setClipboardSelection();
}
void TextEditorWidget::gotoBlockStart()
@@ -5244,7 +5245,6 @@ void TextEditorWidget::mouseReleaseEvent(QMouseEvent *e)
return;
QPlainTextEdit::mouseReleaseEvent(e);
- d->setClipboardSelection();
}
void TextEditorWidget::mouseDoubleClickEvent(QMouseEvent *e)
@@ -5259,7 +5259,6 @@ void TextEditorWidget::mouseDoubleClickEvent(QMouseEvent *e)
}
QPlainTextEdit::mouseDoubleClickEvent(e);
- d->setClipboardSelection();
}
void TextEditorWidgetPrivate::setClipboardSelection()
diff --git a/src/plugins/texteditor/texteditorconstants.cpp b/src/plugins/texteditor/texteditorconstants.cpp
index 6063b1c5e8b..01459630bb5 100644
--- a/src/plugins/texteditor/texteditorconstants.cpp
+++ b/src/plugins/texteditor/texteditorconstants.cpp
@@ -54,6 +54,7 @@ const char *nameForStyle(TextStyle style)
case C_NUMBER: return "Number";
case C_STRING: return "String";
case C_TYPE: return "Type";
+ case C_NAMESPACE: return "Namespace";
case C_LOCAL: return "Local";
case C_PARAMETER: return "Parameter";
case C_GLOBAL: return "Global";
@@ -114,6 +115,7 @@ const char *nameForStyle(TextStyle style)
case C_DECLARATION: return "Declaration";
case C_FUNCTION_DEFINITION: return "FunctionDefinition";
case C_OUTPUT_ARGUMENT: return "OutputArgument";
+ case C_STATIC_MEMBER: return "StaticMember";
case C_LAST_STYLE_SENTINEL: return "LastStyleSentinel";
}
diff --git a/src/plugins/texteditor/texteditorconstants.h b/src/plugins/texteditor/texteditorconstants.h
index c3f65a54c9e..060c521a400 100644
--- a/src/plugins/texteditor/texteditorconstants.h
+++ b/src/plugins/texteditor/texteditorconstants.h
@@ -54,6 +54,7 @@ enum TextStyle : quint8 {
C_NUMBER,
C_STRING,
C_TYPE,
+ C_NAMESPACE,
C_LOCAL,
C_PARAMETER,
C_GLOBAL,
@@ -114,6 +115,7 @@ enum TextStyle : quint8 {
C_DECLARATION,
C_FUNCTION_DEFINITION,
C_OUTPUT_ARGUMENT,
+ C_STATIC_MEMBER,
C_LAST_STYLE_SENTINEL
};
diff --git a/src/plugins/texteditor/texteditorsettings.cpp b/src/plugins/texteditor/texteditorsettings.cpp
index aad1ac7a62e..4141806679c 100644
--- a/src/plugins/texteditor/texteditorsettings.cpp
+++ b/src/plugins/texteditor/texteditorsettings.cpp
@@ -160,6 +160,8 @@ FormatDescriptions TextEditorSettingsPrivate::initialFormats()
tr("Name of a primitive data type."), Qt::darkYellow);
formatDescr.emplace_back(C_TYPE, tr("Type"), tr("Name of a type."),
Qt::darkMagenta);
+ formatDescr.emplace_back(C_NAMESPACE, tr("Namespace"), tr("Name of a namespace."),
+ Qt::darkGreen);
formatDescr.emplace_back(C_LOCAL, tr("Local"),
tr("Local variables."), QColor(9, 46, 100));
formatDescr.emplace_back(C_PARAMETER, tr("Parameter"),
@@ -361,6 +363,10 @@ FormatDescriptions TextEditorSettingsPrivate::initialFormats()
tr("Writable arguments of a function call."),
outputArgumentFormat,
FormatDescription::ShowAllControls);
+ formatDescr.emplace_back(C_STATIC_MEMBER,
+ tr("Static Member"),
+ tr("Names of static fields or member functions."),
+ FormatDescription::ShowAllControls);
return formatDescr;
}
diff --git a/src/plugins/texteditor/textstyles.h b/src/plugins/texteditor/textstyles.h
index a2151527e50..bf6d04eb995 100644
--- a/src/plugins/texteditor/textstyles.h
+++ b/src/plugins/texteditor/textstyles.h
@@ -36,14 +36,20 @@ struct TextStyles {
TextStyle mainStyle;
MixinTextStyles mixinStyles;
- static TextStyles mixinStyle(TextStyle main, TextStyle mixin)
+ static TextStyles mixinStyle(TextStyle main, const QList &mixins)
{
TextStyles res;
res.mainStyle = main;
res.mixinStyles.initializeElements();
- res.mixinStyles.push_back(mixin);
+ for (TextStyle mixin : mixins)
+ res.mixinStyles.push_back(mixin);
return res;
}
+
+ static TextStyles mixinStyle(TextStyle main, TextStyle mixin)
+ {
+ return mixinStyle(main, QList{mixin});
+ }
};
} // namespace TextEditor
diff --git a/src/shared/qbs b/src/shared/qbs
index 966689ab499..38f233502e3 160000
--- a/src/shared/qbs
+++ b/src/shared/qbs
@@ -1 +1 @@
-Subproject commit 966689ab499725cb7e7ab1157043b968a1a39e60
+Subproject commit 38f233502e32112e15179420da86d6e6afb79b24
diff --git a/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp b/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp
index ae1eefa8d55..3720c64daa4 100644
--- a/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp
+++ b/tests/auto/cplusplus/checksymbols/tst_checksymbols.cpp
@@ -62,6 +62,7 @@ static QString useKindToString(UseKind useKind)
switch (useKind) {
CASE_STR(Unknown);
CASE_STR(TypeUse);
+ CASE_STR(NamespaceUse);
CASE_STR(LocalUse);
CASE_STR(FieldUse);
CASE_STR(EnumerationUse);
@@ -72,6 +73,9 @@ static QString useKindToString(UseKind useKind)
CASE_STR(FunctionUse);
CASE_STR(FunctionDeclarationUse);
CASE_STR(PseudoKeywordUse);
+ CASE_STR(StaticFieldUse);
+ CASE_STR(StaticMethodUse);
+ CASE_STR(StaticMethodDeclarationUse);
default:
QTest::qFail("Unknown UseKind", __FILE__, __LINE__);
return QLatin1String("Unknown UseKind");
@@ -246,8 +250,8 @@ void tst_CheckSymbols::test_checksymbols_data()
<< _("namespace N {}\n"
"using namespace N;\n")
<< (UseList()
- << Use(1, 11, 1, Highlighting::TypeUse)
- << Use(2, 17, 1, Highlighting::TypeUse));
+ << Use(1, 11, 1, Highlighting::NamespaceUse)
+ << Use(2, 17, 1, Highlighting::NamespaceUse));
QTest::newRow("LocalUse")
<< _("int f()\n"
@@ -361,21 +365,21 @@ void tst_CheckSymbols::test_checksymbols_data()
"}\n")
<< (UseList()
<< Use(1, 8, 5, Highlighting::TypeUse)
- << Use(3, 16, 3, Highlighting::FieldUse)
+ << Use(3, 16, 3, Highlighting::StaticFieldUse)
<< Use(4, 12, 5, Highlighting::TypeUse)
<< Use(6, 9, 5, Highlighting::TypeUse)
<< Use(6, 16, 5, Highlighting::FieldUse)
<< Use(7, 14, 3, Highlighting::FunctionDeclarationUse)
<< Use(11, 5, 5, Highlighting::TypeUse)
- << Use(11, 12, 3, Highlighting::FieldUse)
+ << Use(11, 12, 3, Highlighting::FieldUse) // FIXME: Should be StaticField
<< Use(13, 6, 5, Highlighting::TypeUse)
<< Use(13, 13, 5, Highlighting::TypeUse)
<< Use(13, 20, 3, Highlighting::FunctionDeclarationUse)
- << Use(15, 5, 3, Highlighting::FieldUse)
+ << Use(15, 5, 3, Highlighting::StaticFieldUse)
<< Use(16, 5, 5, Highlighting::TypeUse)
- << Use(16, 12, 3, Highlighting::FieldUse)
+ << Use(16, 12, 3, Highlighting::FieldUse) // FIXME: Should be StaticField
<< Use(17, 5, 5, Highlighting::FieldUse)
- << Use(17, 12, 3, Highlighting::FieldUse));
+ << Use(17, 12, 3, Highlighting::StaticFieldUse));
QTest::newRow("VariableHasTheSameNameAsEnumUse")
<< _("struct Foo\n"
@@ -443,11 +447,11 @@ void tst_CheckSymbols::test_checksymbols_data()
"}\n")
<< (UseList()
<< Use(1, 8, 3, Highlighting::TypeUse)
- << Use(3, 16, 3, Highlighting::FunctionDeclarationUse)
+ << Use(3, 16, 3, Highlighting::StaticMethodDeclarationUse)
<< Use(6, 6, 3, Highlighting::FunctionDeclarationUse)
<< Use(8, 9, 3, Highlighting::LocalUse)
<< Use(8, 15, 3, Highlighting::TypeUse)
- << Use(8, 20, 3, Highlighting::FunctionUse));
+ << Use(8, 20, 3, Highlighting::StaticMethodUse));
QTest::newRow("8902_staticFunctionHighlightingAsMember_functionArgument")
<< _("struct Foo\n"
@@ -461,11 +465,11 @@ void tst_CheckSymbols::test_checksymbols_data()
"}\n")
<< (UseList()
<< Use(1, 8, 3, Highlighting::TypeUse)
- << Use(3, 16, 3, Highlighting::FunctionDeclarationUse)
+ << Use(3, 16, 3, Highlighting::StaticMethodDeclarationUse)
<< Use(6, 6, 3, Highlighting::FunctionDeclarationUse)
<< Use(6, 14, 3, Highlighting::LocalUse)
<< Use(8, 5, 3, Highlighting::TypeUse)
- << Use(8, 10, 3, Highlighting::FunctionUse));
+ << Use(8, 10, 3, Highlighting::StaticMethodUse));
QTest::newRow("8902_staticFunctionHighlightingAsMember_templateParameter")
<< _("struct Foo\n"
@@ -480,11 +484,11 @@ void tst_CheckSymbols::test_checksymbols_data()
"}\n")
<< (UseList()
<< Use(1, 8, 3, Highlighting::TypeUse)
- << Use(3, 16, 3, Highlighting::FunctionDeclarationUse)
+ << Use(3, 16, 3, Highlighting::StaticMethodDeclarationUse)
<< Use(6, 17, 3, Highlighting::TypeUse)
<< Use(7, 6, 3, Highlighting::FunctionDeclarationUse)
<< Use(9, 5, 3, Highlighting::TypeUse)
- << Use(9, 10, 3, Highlighting::FunctionUse));
+ << Use(9, 10, 3, Highlighting::StaticMethodUse));
QTest::newRow("staticFunctionHighlightingAsMember_struct")
<< _("struct Foo\n"
@@ -499,11 +503,11 @@ void tst_CheckSymbols::test_checksymbols_data()
"}\n")
<< (UseList()
<< Use(1, 8, 3, Highlighting::TypeUse)
- << Use(3, 16, 3, Highlighting::FunctionDeclarationUse)
+ << Use(3, 16, 3, Highlighting::StaticMethodDeclarationUse)
<< Use(6, 8, 3, Highlighting::TypeUse)
<< Use(7, 6, 3, Highlighting::FunctionDeclarationUse)
<< Use(9, 5, 3, Highlighting::TypeUse)
- << Use(9, 10, 3, Highlighting::FunctionUse));
+ << Use(9, 10, 3, Highlighting::StaticMethodUse));
QTest::newRow("QTCREATORBUG8890_danglingPointer")
<< _("template class QList {\n"
@@ -569,13 +573,13 @@ void tst_CheckSymbols::test_checksymbols_data()
<< Use(1, 17, 1, Highlighting::TypeUse)
<< Use(2, 7, 9, Highlighting::TypeUse)
<< Use(5, 12, 1, Highlighting::TypeUse)
- << Use(5, 15, 8, Highlighting::FunctionDeclarationUse)
+ << Use(5, 15, 8, Highlighting::StaticMethodDeclarationUse)
<< Use(8, 6, 3, Highlighting::FunctionDeclarationUse)
<< Use(10, 6, 3, Highlighting::FunctionDeclarationUse);
for (int i = 0; i < 250; ++i) {
excessiveUses
<< Use(12 + i, 5, 9, Highlighting::TypeUse)
- << Use(12 + i, 28, 8, Highlighting::FunctionUse);
+ << Use(12 + i, 28, 8, Highlighting::StaticMethodUse);
}
QTest::newRow("QTCREATORBUG8974_danglingPointer")
<< excessive
@@ -710,11 +714,11 @@ void tst_CheckSymbols::test_checksymbols_data()
<< Use(1, 14, 4, Highlighting::FieldUse)
<< Use(2, 6, 4, Highlighting::FunctionDeclarationUse)
<< Use(4, 8, 4, Highlighting::FieldUse)
- << Use(6, 11, 3, Highlighting::TypeUse)
+ << Use(6, 11, 3, Highlighting::NamespaceUse)
<< Use(7, 16, 4, Highlighting::FieldUse)
<< Use(8, 8, 4, Highlighting::FunctionDeclarationUse)
<< Use(10, 10, 4, Highlighting::FieldUse)
- << Use(13, 11, 3, Highlighting::TypeUse)
+ << Use(13, 11, 3, Highlighting::NamespaceUse)
<< Use(15, 27, 4, Highlighting::FieldUse)
<< Use(16, 10, 4, Highlighting::FunctionDeclarationUse)
<< Use(16, 19, 4, Highlighting::FieldUse)
@@ -792,9 +796,9 @@ void tst_CheckSymbols::test_checksymbols_data()
" Foo foo;\n"
"}\n")
<< (UseList()
- << Use(1, 11, 2, Highlighting::TypeUse)
+ << Use(1, 11, 2, Highlighting::NamespaceUse)
<< Use(2, 7, 3, Highlighting::TypeUse)
- << Use(4, 7, 2, Highlighting::TypeUse)
+ << Use(4, 7, 2, Highlighting::NamespaceUse)
<< Use(4, 11, 3, Highlighting::TypeUse)
<< Use(5, 6, 3, Highlighting::FunctionDeclarationUse)
<< Use(7, 5, 3, Highlighting::TypeUse)
@@ -812,10 +816,10 @@ void tst_CheckSymbols::test_checksymbols_data()
"}\n"
"}\n")
<< (UseList()
- << Use(1, 11, 2, Highlighting::TypeUse)
+ << Use(1, 11, 2, Highlighting::NamespaceUse)
<< Use(2, 7, 3, Highlighting::TypeUse)
- << Use(4, 11, 3, Highlighting::TypeUse)
- << Use(5, 7, 2, Highlighting::TypeUse)
+ << Use(4, 11, 3, Highlighting::NamespaceUse)
+ << Use(5, 7, 2, Highlighting::NamespaceUse)
<< Use(5, 11, 3, Highlighting::TypeUse)
<< Use(6, 6, 3, Highlighting::FunctionDeclarationUse)
<< Use(8, 5, 3, Highlighting::TypeUse)
@@ -831,10 +835,10 @@ void tst_CheckSymbols::test_checksymbols_data()
" Foo foo;\n"
"}\n")
<< (UseList()
- << Use(1, 11, 2, Highlighting::TypeUse)
+ << Use(1, 11, 2, Highlighting::NamespaceUse)
<< Use(2, 7, 3, Highlighting::TypeUse)
<< Use(4, 6, 3, Highlighting::FunctionDeclarationUse)
- << Use(6, 11, 2, Highlighting::TypeUse)
+ << Use(6, 11, 2, Highlighting::NamespaceUse)
<< Use(6, 15, 3, Highlighting::TypeUse)
<< Use(7, 5, 3, Highlighting::TypeUse)
<< Use(7, 9, 3, Highlighting::LocalUse));
@@ -849,7 +853,7 @@ void tst_CheckSymbols::test_checksymbols_data()
" Foo foo;\n"
"}\n")
<< (UseList()
- << Use(1, 11, 2, Highlighting::TypeUse)
+ << Use(1, 11, 2, Highlighting::NamespaceUse)
<< Use(2, 7, 3, Highlighting::TypeUse)
<< Use(5, 6, 3, Highlighting::FunctionDeclarationUse)
<< Use(7, 9, 3, Highlighting::LocalUse));
@@ -866,9 +870,9 @@ void tst_CheckSymbols::test_checksymbols_data()
"}\n"
"}\n")
<< (UseList()
- << Use(1, 11, 2, Highlighting::TypeUse)
+ << Use(1, 11, 2, Highlighting::NamespaceUse)
<< Use(2, 7, 3, Highlighting::TypeUse)
- << Use(4, 11, 3, Highlighting::TypeUse)
+ << Use(4, 11, 3, Highlighting::NamespaceUse)
<< Use(6, 6, 3, Highlighting::FunctionDeclarationUse)
<< Use(8, 9, 3, Highlighting::LocalUse));
@@ -882,7 +886,7 @@ void tst_CheckSymbols::test_checksymbols_data()
" Foo foo;\n"
"}\n")
<< (UseList()
- << Use(1, 11, 2, Highlighting::TypeUse)
+ << Use(1, 11, 2, Highlighting::NamespaceUse)
<< Use(2, 7, 3, Highlighting::TypeUse)
<< Use(4, 6, 3, Highlighting::FunctionDeclarationUse)
<< Use(7, 9, 3, Highlighting::LocalUse));
@@ -944,14 +948,14 @@ void tst_CheckSymbols::test_checksymbols_data()
"}\n")
<< (UseList()
<< Use(1, 8, 1, Highlighting::TypeUse)
- << Use(2, 11, 3, Highlighting::TypeUse)
+ << Use(2, 11, 3, Highlighting::NamespaceUse)
<< Use(4, 24, 1, Highlighting::TypeUse)
<< Use(4, 34, 10, Highlighting::TypeUse)
- << Use(6, 11, 2, Highlighting::TypeUse)
- << Use(8, 11, 3, Highlighting::TypeUse)
+ << Use(6, 11, 2, Highlighting::NamespaceUse)
+ << Use(8, 11, 3, Highlighting::NamespaceUse)
<< Use(8, 16, 10, Highlighting::TypeUse)
<< Use(10, 6, 3, Highlighting::FunctionDeclarationUse)
- << Use(12, 5, 2, Highlighting::TypeUse)
+ << Use(12, 5, 2, Highlighting::NamespaceUse)
<< Use(12, 9, 10, Highlighting::TypeUse)
<< Use(12, 20, 1, Highlighting::TypeUse)
<< Use(12, 23, 1, Highlighting::LocalUse));
@@ -967,9 +971,9 @@ void tst_CheckSymbols::test_checksymbols_data()
" Foo foo;\n"
"}\n")
<< (QList