forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/6.0'
Conflicts: cmake/QtCreatorIDEBranding.cmake qbs/modules/qtc/qtc.qbs qtcreator_ide_branding.pri Change-Id: Id5e67457e2c8c96cfcd29fb5469b6650ec7bcc94
This commit is contained in:
2
.github/workflows/build_cmake.yml
vendored
2
.github/workflows/build_cmake.yml
vendored
@@ -3,7 +3,7 @@ name: CMake Build Matrix
|
|||||||
on: [push, pull_request]
|
on: [push, pull_request]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
QT_VERSION: 6.2.0
|
QT_VERSION: 6.2.1
|
||||||
CLANG_VERSION: 130
|
CLANG_VERSION: 130
|
||||||
ELFUTILS_VERSION: 0.175
|
ELFUTILS_VERSION: 0.175
|
||||||
CMAKE_VERSION: 3.21.1
|
CMAKE_VERSION: 3.21.1
|
||||||
|
@@ -164,13 +164,13 @@ def fix_rpaths(path, qt_deploy_path, qt_install_info, chrpath=None):
|
|||||||
if len(rpath) <= 0:
|
if len(rpath) <= 0:
|
||||||
return
|
return
|
||||||
# remove previous Qt RPATH
|
# remove previous Qt RPATH
|
||||||
new_rpath = list(filter(lambda path: not path.startswith(qt_install_prefix) and not path.startswith(qt_install_libs),
|
new_rpath = [path for path in rpath if not path.startswith(qt_install_prefix)
|
||||||
rpath))
|
and not path.startswith(qt_install_libs)]
|
||||||
|
|
||||||
# check for Qt linking
|
# check for Qt linking
|
||||||
lddOutput = subprocess.check_output(['ldd', filepath])
|
lddOutput = subprocess.check_output(['ldd', filepath])
|
||||||
lddDecodedOutput = lddOutput.decode(encoding) if encoding else lddOutput
|
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
|
# add Qt RPATH if necessary
|
||||||
relative_path = os.path.relpath(qt_deploy_path, os.path.dirname(filepath))
|
relative_path = os.path.relpath(qt_deploy_path, os.path.dirname(filepath))
|
||||||
if relative_path == '.':
|
if relative_path == '.':
|
||||||
|
@@ -1137,6 +1137,7 @@ class DumperBase():
|
|||||||
'char',
|
'char',
|
||||||
'wchar_t',
|
'wchar_t',
|
||||||
'unsigned char',
|
'unsigned char',
|
||||||
|
'uint8_t',
|
||||||
'signed char',
|
'signed char',
|
||||||
'CHAR',
|
'CHAR',
|
||||||
'WCHAR'
|
'WCHAR'
|
||||||
@@ -1243,7 +1244,7 @@ class DumperBase():
|
|||||||
if innerType.code == TypeCode.Typedef:
|
if innerType.code == TypeCode.Typedef:
|
||||||
targetType = innerType.ltarget
|
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 *.
|
# Use UTF-8 as default for char *.
|
||||||
self.putType(typeName)
|
self.putType(typeName)
|
||||||
(elided, shown, data) = self.readToFirstZero(ptr, 1, limit)
|
(elided, shown, data) = self.readToFirstZero(ptr, 1, limit)
|
||||||
@@ -1406,6 +1407,7 @@ class DumperBase():
|
|||||||
'char',
|
'char',
|
||||||
'signed char',
|
'signed char',
|
||||||
'unsigned char',
|
'unsigned char',
|
||||||
|
'uint8_t',
|
||||||
'wchar_t',
|
'wchar_t',
|
||||||
'CHAR',
|
'CHAR',
|
||||||
'WCHAR'
|
'WCHAR'
|
||||||
@@ -3628,6 +3630,7 @@ class DumperBase():
|
|||||||
'char': 'int:1',
|
'char': 'int:1',
|
||||||
'signed char': 'int:1',
|
'signed char': 'int:1',
|
||||||
'unsigned char': 'uint:1',
|
'unsigned char': 'uint:1',
|
||||||
|
'uint8_t': 'uint:1',
|
||||||
'short': 'int:2',
|
'short': 'int:2',
|
||||||
'unsigned short': 'uint:2',
|
'unsigned short': 'uint:2',
|
||||||
'int': 'int:4',
|
'int': 'int:4',
|
||||||
|
@@ -140,25 +140,6 @@ Section {
|
|||||||
ExpandingSpacer {}
|
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 {
|
PropertyLabel {
|
||||||
text: qsTr("Style name")
|
text: qsTr("Style name")
|
||||||
tooltip: qsTr("Font's style.")
|
tooltip: qsTr("Font's style.")
|
||||||
@@ -267,7 +248,30 @@ Section {
|
|||||||
supportGradient: false
|
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 {
|
FontStyleButtons {
|
||||||
bold: root.boldStyle
|
bold: root.boldStyle
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
<style name="String" foreground="#636363"/>
|
<style name="String" foreground="#636363"/>
|
||||||
<style name="Text" foreground="#000000" background="#ffffff"/>
|
<style name="Text" foreground="#000000" background="#ffffff"/>
|
||||||
<style name="Type"/>
|
<style name="Type"/>
|
||||||
|
<style name="Namespace"/>
|
||||||
<style name="VirtualMethod" italic="true"/>
|
<style name="VirtualMethod" italic="true"/>
|
||||||
<style name="Occurrences.Unused" underlineColor="#8F8F8F" underlineStyle="SingleUnderline"/>
|
<style name="Occurrences.Unused" underlineColor="#8F8F8F" underlineStyle="SingleUnderline"/>
|
||||||
<style name="Warning" underlineColor="#505050" underlineStyle="SingleUnderline"/>
|
<style name="Warning" underlineColor="#505050" underlineStyle="SingleUnderline"/>
|
||||||
|
@@ -632,6 +632,10 @@ LibraryInfo Snapshot::libraryInfo(const QString &path) const
|
|||||||
return _libraries.value(QDir::cleanPath(path));
|
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
|
void ModuleApiInfo::addToHash(QCryptographicHash &hash) const
|
||||||
{
|
{
|
||||||
|
@@ -256,7 +256,8 @@ public:
|
|||||||
|
|
||||||
Document::Ptr document(const QString &fileName) const;
|
Document::Ptr document(const QString &fileName) const;
|
||||||
QList<Document::Ptr> documentsInDirectory(const QString &path) const;
|
QList<Document::Ptr> 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,
|
Document::MutablePtr documentFromSource(const QString &code,
|
||||||
const QString &fileName,
|
const QString &fileName,
|
||||||
|
@@ -684,19 +684,19 @@ void ModelManagerInterface::updateDocument(const Document::Ptr &doc)
|
|||||||
emit documentUpdated(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())
|
if (!info.pluginTypeInfoError().isEmpty())
|
||||||
qCDebug(qmljsLog) << "Dumping errors for " << path << ":" << info.pluginTypeInfoError();
|
qCDebug(qmljsLog) << "Dumping errors for " << path << ":" << info.pluginTypeInfoError();
|
||||||
|
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&m_mutex);
|
QMutexLocker locker(&m_mutex);
|
||||||
m_validSnapshot.insertLibraryInfo(path, info);
|
m_validSnapshot.insertLibraryInfo(path.toString(), info);
|
||||||
m_newestSnapshot.insertLibraryInfo(path, info);
|
m_newestSnapshot.insertLibraryInfo(path.toString(), info);
|
||||||
}
|
}
|
||||||
// only emit if we got new useful information
|
// only emit if we got new useful information
|
||||||
if (info.isValid())
|
if (info.isValid())
|
||||||
emit libraryInfoUpdated(path, info);
|
emit libraryInfoUpdated(path.toString(), info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static QStringList filesInDirectoryForLanguages(const QString &path,
|
static QStringList filesInDirectoryForLanguages(const QString &path,
|
||||||
@@ -773,7 +773,7 @@ enum class LibraryStatus {
|
|||||||
Unknown
|
Unknown
|
||||||
};
|
};
|
||||||
|
|
||||||
static LibraryStatus libraryStatus(const QString &path, const Snapshot &snapshot,
|
static LibraryStatus libraryStatus(const FilePath &path, const Snapshot &snapshot,
|
||||||
QSet<QString> *newLibraries)
|
QSet<QString> *newLibraries)
|
||||||
{
|
{
|
||||||
if (path.isEmpty())
|
if (path.isEmpty())
|
||||||
@@ -782,7 +782,7 @@ static LibraryStatus libraryStatus(const QString &path, const Snapshot &snapshot
|
|||||||
const LibraryInfo &existingInfo = snapshot.libraryInfo(path);
|
const LibraryInfo &existingInfo = snapshot.libraryInfo(path);
|
||||||
if (existingInfo.isValid())
|
if (existingInfo.isValid())
|
||||||
return LibraryStatus::Accepted;
|
return LibraryStatus::Accepted;
|
||||||
if (newLibraries->contains(path))
|
if (newLibraries->contains(path.toString()))
|
||||||
return LibraryStatus::Accepted;
|
return LibraryStatus::Accepted;
|
||||||
// if we looked at the path before, done
|
// if we looked at the path before, done
|
||||||
return existingInfo.wasScanned()
|
return existingInfo.wasScanned()
|
||||||
@@ -790,7 +790,7 @@ static LibraryStatus libraryStatus(const QString &path, const Snapshot &snapshot
|
|||||||
: LibraryStatus::Unknown;
|
: LibraryStatus::Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool findNewQmlApplicationInPath(const QString &path,
|
static bool findNewQmlApplicationInPath(const FilePath &path,
|
||||||
const Snapshot &snapshot,
|
const Snapshot &snapshot,
|
||||||
ModelManagerInterface *modelManager,
|
ModelManagerInterface *modelManager,
|
||||||
QSet<QString> *newLibraries)
|
QSet<QString> *newLibraries)
|
||||||
@@ -803,8 +803,8 @@ static bool findNewQmlApplicationInPath(const QString &path,
|
|||||||
|
|
||||||
QString qmltypesFile;
|
QString qmltypesFile;
|
||||||
|
|
||||||
QDir dir(path);
|
QDir dir(path.toString());
|
||||||
QDirIterator it(path, QStringList { "*.qmltypes" }, QDir::Files);
|
QDirIterator it(path.toString(), QStringList { "*.qmltypes" }, QDir::Files);
|
||||||
|
|
||||||
if (!it.hasNext())
|
if (!it.hasNext())
|
||||||
return false;
|
return false;
|
||||||
@@ -828,7 +828,7 @@ static bool findNewQmlLibraryInPath(const QString &path,
|
|||||||
QSet<QString> *newLibraries,
|
QSet<QString> *newLibraries,
|
||||||
bool ignoreMissing)
|
bool ignoreMissing)
|
||||||
{
|
{
|
||||||
switch (libraryStatus(path, snapshot, newLibraries)) {
|
switch (libraryStatus(FilePath::fromString(path), snapshot, newLibraries)) {
|
||||||
case LibraryStatus::Accepted: return true;
|
case LibraryStatus::Accepted: return true;
|
||||||
case LibraryStatus::Rejected: return false;
|
case LibraryStatus::Rejected: return false;
|
||||||
default: break;
|
default: break;
|
||||||
@@ -839,7 +839,7 @@ static bool findNewQmlLibraryInPath(const QString &path,
|
|||||||
if (!qmldirFile.exists()) {
|
if (!qmldirFile.exists()) {
|
||||||
if (!ignoreMissing) {
|
if (!ignoreMissing) {
|
||||||
LibraryInfo libraryInfo(LibraryInfo::NotFound);
|
LibraryInfo libraryInfo(LibraryInfo::NotFound);
|
||||||
modelManager->updateLibraryInfo(path, libraryInfo);
|
modelManager->updateLibraryInfo(FilePath::fromString(path), libraryInfo);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -858,7 +858,7 @@ static bool findNewQmlLibraryInPath(const QString &path,
|
|||||||
|
|
||||||
const QString libraryPath = QFileInfo(qmldirFile).absolutePath();
|
const QString libraryPath = QFileInfo(qmldirFile).absolutePath();
|
||||||
newLibraries->insert(libraryPath);
|
newLibraries->insert(libraryPath);
|
||||||
modelManager->updateLibraryInfo(libraryPath, LibraryInfo(qmldirParser));
|
modelManager->updateLibraryInfo(FilePath::fromString(libraryPath), LibraryInfo(qmldirParser));
|
||||||
modelManager->loadPluginTypes(QFileInfo(libraryPath).canonicalFilePath(), libraryPath,
|
modelManager->loadPluginTypes(QFileInfo(libraryPath).canonicalFilePath(), libraryPath,
|
||||||
QString(), QString());
|
QString(), QString());
|
||||||
|
|
||||||
@@ -1252,7 +1252,7 @@ void ModelManagerInterface::updateImportPaths()
|
|||||||
for (const Document::Ptr &doc : qAsConst(snapshot))
|
for (const Document::Ptr &doc : qAsConst(snapshot))
|
||||||
findNewLibraryImports(doc, snapshot, this, &importedFiles, &scannedPaths, &newLibraries);
|
findNewLibraryImports(doc, snapshot, this, &importedFiles, &scannedPaths, &newLibraries);
|
||||||
for (const QString &path : qAsConst(allApplicationDirectories))
|
for (const QString &path : qAsConst(allApplicationDirectories))
|
||||||
findNewQmlApplicationInPath(path, snapshot, this, &newLibraries);
|
findNewQmlApplicationInPath(FilePath::fromString(path), snapshot, this, &newLibraries);
|
||||||
|
|
||||||
updateSourceFiles(importedFiles, true);
|
updateSourceFiles(importedFiles, true);
|
||||||
|
|
||||||
@@ -1433,7 +1433,7 @@ LibraryInfo ModelManagerInterface::builtins(const Document::Ptr &doc) const
|
|||||||
{
|
{
|
||||||
const ProjectInfo info = projectInfoForPath(doc->fileName());
|
const ProjectInfo info = projectInfoForPath(doc->fileName());
|
||||||
if (!info.qtQmlPath.isEmpty())
|
if (!info.qtQmlPath.isEmpty())
|
||||||
return m_validSnapshot.libraryInfo(info.qtQmlPath.toString());
|
return m_validSnapshot.libraryInfo(info.qtQmlPath);
|
||||||
return LibraryInfo();
|
return LibraryInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -156,7 +156,7 @@ public:
|
|||||||
void updateProjectInfo(const ProjectInfo &pinfo, ProjectExplorer::Project *p);
|
void updateProjectInfo(const ProjectInfo &pinfo, ProjectExplorer::Project *p);
|
||||||
|
|
||||||
void updateDocument(const QmlJS::Document::Ptr& doc);
|
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 emitDocumentChangedOnDisk(QmlJS::Document::Ptr doc);
|
||||||
void updateQrcFile(const QString &path);
|
void updateQrcFile(const QString &path);
|
||||||
ProjectInfo projectInfoForPath(const QString &path) const;
|
ProjectInfo projectInfoForPath(const QString &path) const;
|
||||||
|
@@ -89,25 +89,23 @@ void PluginDumper::onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::Projec
|
|||||||
if (info.qmlDumpPath.isEmpty() || info.qtQmlPath.isEmpty())
|
if (info.qmlDumpPath.isEmpty() || info.qtQmlPath.isEmpty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// FIXME: This doesn't work for non-local paths.
|
if (m_runningQmldumps.values().contains(info.qmlDumpPath))
|
||||||
const QString importsPath = QDir::cleanPath(info.qtQmlPath.toString());
|
|
||||||
if (m_runningQmldumps.values().contains(importsPath))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LibraryInfo builtinInfo;
|
LibraryInfo builtinInfo;
|
||||||
if (!force) {
|
if (!force) {
|
||||||
const Snapshot snapshot = m_modelManager->snapshot();
|
const Snapshot snapshot = m_modelManager->snapshot();
|
||||||
builtinInfo = snapshot.libraryInfo(info.qtQmlPath.toString());
|
builtinInfo = snapshot.libraryInfo(info.qtQmlPath);
|
||||||
if (builtinInfo.isValid())
|
if (builtinInfo.isValid())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
builtinInfo = LibraryInfo(LibraryInfo::Found);
|
builtinInfo = LibraryInfo(LibraryInfo::Found);
|
||||||
m_modelManager->updateLibraryInfo(info.qtQmlPath.toString(), builtinInfo);
|
m_modelManager->updateLibraryInfo(info.qtQmlPath, builtinInfo);
|
||||||
|
|
||||||
// prefer QTDIR/qml/builtins.qmltypes if available
|
// prefer QTDIR/qml/builtins.qmltypes if available
|
||||||
const QString builtinQmltypesPath = info.qtQmlPath.toString() + QLatin1String("/builtins.qmltypes");
|
const FilePath builtinQmltypesPath = info.qtQmlPath / "builtins.qmltypes";
|
||||||
if (QFile::exists(builtinQmltypesPath)) {
|
if (builtinQmltypesPath.exists()) {
|
||||||
loadQmltypesFile(QStringList(builtinQmltypesPath), info.qtQmlPath.toString(), builtinInfo);
|
loadQmltypesFile({builtinQmltypesPath}, info.qtQmlPath, builtinInfo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,16 +113,9 @@ void PluginDumper::onLoadBuiltinTypes(const QmlJS::ModelManagerInterface::Projec
|
|||||||
m_qtToInfo.insert(info.qtQmlPath.toString(), info);
|
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)
|
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))
|
if (m_runningQmldumps.values().contains(canonicalLibraryPath))
|
||||||
return;
|
return;
|
||||||
const Snapshot snapshot = m_modelManager->snapshot();
|
const Snapshot snapshot = m_modelManager->snapshot();
|
||||||
@@ -135,7 +126,7 @@ void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &
|
|||||||
// avoid inserting the same plugin twice
|
// avoid inserting the same plugin twice
|
||||||
int index;
|
int index;
|
||||||
for (index = 0; index < m_plugins.size(); ++index) {
|
for (index = 0; index < m_plugins.size(); ++index) {
|
||||||
if (m_plugins.at(index).qmldirPath == libraryPath)
|
if (m_plugins.at(index).qmldirPath == canonicalLibraryPath)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (index == m_plugins.size())
|
if (index == m_plugins.size())
|
||||||
@@ -148,10 +139,10 @@ void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &
|
|||||||
plugin.importVersion = importVersion;
|
plugin.importVersion = importVersion;
|
||||||
|
|
||||||
// add default qmltypes file if it exists
|
// 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()) {
|
while (it.hasNext()) {
|
||||||
const QString defaultQmltypesPath = makeAbsolute(it.next(), canonicalLibraryPath);
|
const FilePath defaultQmltypesPath = canonicalLibraryPath.resolvePath(it.next());
|
||||||
|
|
||||||
if (!plugin.typeInfoPaths.contains(defaultQmltypesPath))
|
if (!plugin.typeInfoPaths.contains(defaultQmltypesPath))
|
||||||
plugin.typeInfoPaths += defaultQmltypesPath;
|
plugin.typeInfoPaths += defaultQmltypesPath;
|
||||||
@@ -159,29 +150,29 @@ void PluginDumper::onLoadPluginTypes(const QString &libraryPath, const QString &
|
|||||||
|
|
||||||
// add typeinfo files listed in qmldir
|
// add typeinfo files listed in qmldir
|
||||||
foreach (const QString &typeInfo, libraryInfo.typeInfos()) {
|
foreach (const QString &typeInfo, libraryInfo.typeInfos()) {
|
||||||
QString pathNow = makeAbsolute(typeInfo, canonicalLibraryPath);
|
const FilePath pathNow = canonicalLibraryPath.resolvePath(typeInfo);
|
||||||
if (!plugin.typeInfoPaths.contains(pathNow) && QFile::exists(pathNow))
|
if (!plugin.typeInfoPaths.contains(pathNow) && pathNow.exists())
|
||||||
plugin.typeInfoPaths += pathNow;
|
plugin.typeInfoPaths += pathNow;
|
||||||
}
|
}
|
||||||
|
|
||||||
// watch plugin libraries
|
// watch plugin libraries
|
||||||
foreach (const QmlDirParser::Plugin &plugin, snapshot.libraryInfo(canonicalLibraryPath).plugins()) {
|
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 (!pluginLibrary.isEmpty()) {
|
||||||
if (!pluginWatcher()->watchesFile(pluginLibrary))
|
if (!pluginWatcher()->watchesFile(pluginLibrary))
|
||||||
pluginWatcher()->addFile(pluginLibrary, Utils::FileSystemWatcher::WatchModifiedDate);
|
pluginWatcher()->addFile(pluginLibrary, FileSystemWatcher::WatchModifiedDate);
|
||||||
m_libraryToPluginIndex.insert(pluginLibrary, index);
|
m_libraryToPluginIndex.insert(pluginLibrary, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// watch library qmltypes file
|
// watch library qmltypes file
|
||||||
if (!plugin.typeInfoPaths.isEmpty()) {
|
if (!plugin.typeInfoPaths.isEmpty()) {
|
||||||
foreach (const QString &path, plugin.typeInfoPaths) {
|
for (const FilePath &path : qAsConst(plugin.typeInfoPaths)) {
|
||||||
if (!QFile::exists(path))
|
if (!path.exists())
|
||||||
continue;
|
continue;
|
||||||
if (!pluginWatcher()->watchesFile(path))
|
if (!pluginWatcher()->watchesFile(path.toString()))
|
||||||
pluginWatcher()->addFile(path, Utils::FileSystemWatcher::WatchModifiedDate);
|
pluginWatcher()->addFile(path.toString(), FileSystemWatcher::WatchModifiedDate);
|
||||||
m_libraryToPluginIndex.insert(path, index);
|
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"
|
return PluginDumper::tr("QML module does not contain information about components contained in plugins.\n\n"
|
||||||
"Module path: %1\n"
|
"Module path: %1\n"
|
||||||
"See \"Using QML Modules with Plugins\" in the documentation.").arg(
|
"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").
|
PluginDumper::tr("Automatic type dump of QML module failed.\nErrors:\n%1").
|
||||||
arg(error) + QLatin1Char('\n');
|
arg(error) + QLatin1Char('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
static QString qmldumpFailedMessage(const QString &libraryPath, const QString &error)
|
static QString qmldumpFailedMessage(const FilePath &libraryPath, const QString &error)
|
||||||
{
|
{
|
||||||
QString firstLines =
|
QString firstLines = QStringList(error.split('\n').mid(0, 10)).join('\n');
|
||||||
QStringList(error.split(QLatin1Char('\n')).mid(0, 10)).join(QLatin1Char('\n'));
|
return noTypeinfoError(libraryPath) + "\n\n" +
|
||||||
return noTypeinfoError(libraryPath) + QLatin1String("\n\n") +
|
|
||||||
PluginDumper::tr("Automatic type dump of QML module failed.\n"
|
PluginDumper::tr("Automatic type dump of QML module failed.\n"
|
||||||
"First 10 lines or errors:\n"
|
"First 10 lines or errors:\n"
|
||||||
"\n"
|
"\n"
|
||||||
@@ -224,11 +214,11 @@ static QString qmldumpFailedMessage(const QString &libraryPath, const QString &e
|
|||||||
).arg(firstLines);
|
).arg(firstLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printParseWarnings(const QString &libraryPath, const QString &warning)
|
static void printParseWarnings(const FilePath &libraryPath, const QString &warning)
|
||||||
{
|
{
|
||||||
ModelManagerInterface::writeWarning(
|
ModelManagerInterface::writeWarning(
|
||||||
PluginDumper::tr("Warnings while parsing QML type information of %1:\n"
|
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)
|
static QString qmlPluginDumpErrorMessage(QtcProcess *process)
|
||||||
@@ -269,7 +259,7 @@ void PluginDumper::qmlPluginTypeDumpDone(QtcProcess *process)
|
|||||||
{
|
{
|
||||||
process->deleteLater();
|
process->deleteLater();
|
||||||
|
|
||||||
const QString libraryPath = m_runningQmldumps.take(process);
|
const FilePath libraryPath = m_runningQmldumps.take(process);
|
||||||
if (libraryPath.isEmpty())
|
if (libraryPath.isEmpty())
|
||||||
return;
|
return;
|
||||||
const Snapshot snapshot = m_modelManager->snapshot();
|
const Snapshot snapshot = m_modelManager->snapshot();
|
||||||
@@ -298,7 +288,7 @@ void PluginDumper::qmlPluginTypeDumpDone(QtcProcess *process)
|
|||||||
CppQmlTypesInfo infos;
|
CppQmlTypesInfo infos;
|
||||||
CppQmlTypesLoader::parseQmlTypeDescriptions(output, &infos.objectsList, &infos.moduleApis, &infos.dependencies,
|
CppQmlTypesLoader::parseQmlTypeDescriptions(output, &infos.objectsList, &infos.moduleApis, &infos.dependencies,
|
||||||
&infos.error, &infos.warning,
|
&infos.error, &infos.warning,
|
||||||
QLatin1String("<dump of ") + libraryPath + QLatin1Char('>'));
|
"<dump of " + libraryPath.toUserOutput() + '>');
|
||||||
future.reportFinished(&infos);
|
future.reportFinished(&infos);
|
||||||
});
|
});
|
||||||
m_modelManager->addFuture(future);
|
m_modelManager->addFuture(future);
|
||||||
@@ -338,13 +328,13 @@ void PluginDumper::qmlPluginTypeDumpError(QtcProcess *process)
|
|||||||
{
|
{
|
||||||
process->deleteLater();
|
process->deleteLater();
|
||||||
|
|
||||||
const QString libraryPath = m_runningQmldumps.take(process);
|
const FilePath libraryPath = m_runningQmldumps.take(process);
|
||||||
if (libraryPath.isEmpty())
|
if (libraryPath.isEmpty())
|
||||||
return;
|
return;
|
||||||
const QString errorMessages = qmlPluginDumpErrorMessage(process);
|
const QString errorMessages = qmlPluginDumpErrorMessage(process);
|
||||||
const Snapshot snapshot = m_modelManager->snapshot();
|
const Snapshot snapshot = m_modelManager->snapshot();
|
||||||
LibraryInfo libraryInfo = snapshot.libraryInfo(libraryPath);
|
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));
|
ModelManagerInterface::writeWarning(qmldumpErrorMessage(libraryPath, errorMessages));
|
||||||
libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, qmldumpFailedMessage(libraryPath, errorMessages));
|
libraryInfo.setPluginTypeInfoStatus(LibraryInfo::DumpError, qmldumpFailedMessage(libraryPath, errorMessages));
|
||||||
libraryInfo.updateFingerprint();
|
libraryInfo.updateFingerprint();
|
||||||
@@ -361,14 +351,15 @@ void PluginDumper::pluginChanged(const QString &pluginLibrary)
|
|||||||
dump(plugin);
|
dump(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
QFuture<PluginDumper::QmlTypeDescription> PluginDumper::loadQmlTypeDescription(const QStringList &paths) const {
|
QFuture<PluginDumper::QmlTypeDescription> PluginDumper::loadQmlTypeDescription(const FilePaths &paths) const
|
||||||
|
{
|
||||||
auto future = Utils::runAsync([=](QFutureInterface<PluginDumper::QmlTypeDescription> &future)
|
auto future = Utils::runAsync([=](QFutureInterface<PluginDumper::QmlTypeDescription> &future)
|
||||||
{
|
{
|
||||||
PluginDumper::QmlTypeDescription result;
|
PluginDumper::QmlTypeDescription result;
|
||||||
|
|
||||||
for (const QString &p: paths) {
|
for (const FilePath &p: paths) {
|
||||||
Utils::FileReader reader;
|
Utils::FileReader reader;
|
||||||
if (!reader.fetch(Utils::FilePath::fromString(p), QFile::Text)) {
|
if (!reader.fetch(p, QFile::Text)) {
|
||||||
result.errors += reader.errorString();
|
result.errors += reader.errorString();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -378,9 +369,9 @@ QFuture<PluginDumper::QmlTypeDescription> PluginDumper::loadQmlTypeDescription(c
|
|||||||
QList<ModuleApiInfo> apis;
|
QList<ModuleApiInfo> apis;
|
||||||
QStringList deps;
|
QStringList deps;
|
||||||
CppQmlTypesLoader::parseQmlTypeDescriptions(reader.data(), &objs, &apis, &deps,
|
CppQmlTypesLoader::parseQmlTypeDescriptions(reader.data(), &objs, &apis, &deps,
|
||||||
&error, &warning, p);
|
&error, &warning, p.toString());
|
||||||
if (!error.isEmpty()) {
|
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 {
|
} else {
|
||||||
result.objects += objs.values();
|
result.objects += objs.values();
|
||||||
result.moduleApis += apis;
|
result.moduleApis += apis;
|
||||||
@@ -444,27 +435,26 @@ QString PluginDumper::buildQmltypesPath(const QString &name) const
|
|||||||
* Recursively load type descriptions of dependencies, collecting results
|
* Recursively load type descriptions of dependencies, collecting results
|
||||||
* in \a objects.
|
* in \a objects.
|
||||||
*/
|
*/
|
||||||
QFuture<PluginDumper::DependencyInfo> PluginDumper::loadDependencies(const QStringList &dependencies,
|
QFuture<PluginDumper::DependencyInfo> PluginDumper::loadDependencies(const FilePaths &dependencies,
|
||||||
QSharedPointer<QSet<QString>> visited) const
|
QSharedPointer<QSet<FilePath>> visited) const
|
||||||
{
|
{
|
||||||
auto iface = QSharedPointer<QFutureInterface<PluginDumper::DependencyInfo>>(new QFutureInterface<PluginDumper::DependencyInfo>);
|
auto iface = QSharedPointer<QFutureInterface<PluginDumper::DependencyInfo>>(new QFutureInterface<PluginDumper::DependencyInfo>);
|
||||||
|
|
||||||
if (visited.isNull()) {
|
if (visited.isNull())
|
||||||
visited = QSharedPointer<QSet<QString>>(new QSet<QString>());
|
visited = QSharedPointer<QSet<FilePath>>(new QSet<FilePath>());
|
||||||
}
|
|
||||||
|
|
||||||
QStringList dependenciesPaths;
|
FilePaths dependenciesPaths;
|
||||||
QString path;
|
QString path;
|
||||||
for (const QString &name: dependencies) {
|
for (const FilePath &name : dependencies) {
|
||||||
path = buildQmltypesPath(name);
|
path = buildQmltypesPath(name.toString());
|
||||||
if (!path.isNull())
|
if (!path.isNull())
|
||||||
dependenciesPaths << path;
|
dependenciesPaths << FilePath::fromString(path);
|
||||||
visited->insert(name);
|
visited->insert(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::onFinished(loadQmlTypeDescription(dependenciesPaths), const_cast<PluginDumper*>(this), [=] (const QFuture<PluginDumper::QmlTypeDescription> &typesFuture) {
|
Utils::onFinished(loadQmlTypeDescription(dependenciesPaths), const_cast<PluginDumper*>(this), [=] (const QFuture<PluginDumper::QmlTypeDescription> &typesFuture) {
|
||||||
PluginDumper::QmlTypeDescription typesResult = typesFuture.result();
|
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());
|
newDependencies = Utils::toList(Utils::toSet(newDependencies) - *visited.data());
|
||||||
if (!newDependencies.isEmpty()) {
|
if (!newDependencies.isEmpty()) {
|
||||||
Utils::onFinished(loadDependencies(newDependencies, visited),
|
Utils::onFinished(loadDependencies(newDependencies, visited),
|
||||||
@@ -564,7 +554,7 @@ static void applyQt515MissingImportWorkaround(const QString &path, LibraryInfo &
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PluginDumper::prepareLibraryInfo(LibraryInfo &libInfo,
|
void PluginDumper::prepareLibraryInfo(LibraryInfo &libInfo,
|
||||||
const QString &libraryPath,
|
const FilePath &libraryPath,
|
||||||
const QStringList &deps,
|
const QStringList &deps,
|
||||||
const QStringList &errors,
|
const QStringList &errors,
|
||||||
const QStringList &warnings,
|
const QStringList &warnings,
|
||||||
@@ -588,13 +578,13 @@ void PluginDumper::prepareLibraryInfo(LibraryInfo &libInfo,
|
|||||||
if (!warnings.isEmpty())
|
if (!warnings.isEmpty())
|
||||||
printParseWarnings(libraryPath, warnings.join(QLatin1String("\n")));
|
printParseWarnings(libraryPath, warnings.join(QLatin1String("\n")));
|
||||||
|
|
||||||
applyQt515MissingImportWorkaround(libraryPath, libInfo);
|
applyQt515MissingImportWorkaround(libraryPath.toString(), libInfo);
|
||||||
|
|
||||||
libInfo.updateFingerprint();
|
libInfo.updateFingerprint();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginDumper::loadQmltypesFile(const QStringList &qmltypesFilePaths,
|
void PluginDumper::loadQmltypesFile(const FilePaths &qmltypesFilePaths,
|
||||||
const QString &libraryPath,
|
const FilePath &libraryPath,
|
||||||
QmlJS::LibraryInfo libraryInfo)
|
QmlJS::LibraryInfo libraryInfo)
|
||||||
{
|
{
|
||||||
Utils::onFinished(loadQmlTypeDescription(qmltypesFilePaths), this, [=](const QFuture<PluginDumper::QmlTypeDescription> &typesFuture)
|
Utils::onFinished(loadQmlTypeDescription(qmltypesFilePaths), this, [=](const QFuture<PluginDumper::QmlTypeDescription> &typesFuture)
|
||||||
@@ -602,7 +592,8 @@ void PluginDumper::loadQmltypesFile(const QStringList &qmltypesFilePaths,
|
|||||||
PluginDumper::QmlTypeDescription typesResult = typesFuture.result();
|
PluginDumper::QmlTypeDescription typesResult = typesFuture.result();
|
||||||
if (!typesResult.dependencies.isEmpty())
|
if (!typesResult.dependencies.isEmpty())
|
||||||
{
|
{
|
||||||
Utils::onFinished(loadDependencies(typesResult.dependencies, QSharedPointer<QSet<QString>>()), this,
|
Utils::onFinished(loadDependencies(Utils::transform(typesResult.dependencies, &FilePath::fromString),
|
||||||
|
QSharedPointer<QSet<FilePath>>()), this,
|
||||||
[typesResult, libraryInfo, libraryPath, this] (const QFuture<PluginDumper::DependencyInfo> &loadFuture)
|
[typesResult, libraryInfo, libraryPath, this] (const QFuture<PluginDumper::DependencyInfo> &loadFuture)
|
||||||
{
|
{
|
||||||
PluginDumper::DependencyInfo loadResult = loadFuture.result();
|
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::finished, this, [this, process] { qmlPluginTypeDumpDone(process); });
|
||||||
connect(process, &QtcProcess::errorOccurred, this, [this, process] { qmlPluginTypeDumpError(process); });
|
connect(process, &QtcProcess::errorOccurred, this, [this, process] { qmlPluginTypeDumpError(process); });
|
||||||
process->start();
|
process->start();
|
||||||
m_runningQmldumps.insert(process, importPath.toString());
|
m_runningQmldumps.insert(process, importPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginDumper::dump(const Plugin &plugin)
|
void PluginDumper::dump(const Plugin &plugin)
|
||||||
@@ -686,7 +677,7 @@ void PluginDumper::dump(const Plugin &plugin)
|
|||||||
args << plugin.importUri;
|
args << plugin.importUri;
|
||||||
args << plugin.importVersion;
|
args << plugin.importVersion;
|
||||||
args << (plugin.importPath.isEmpty() ? QLatin1String(".") : plugin.importPath);
|
args << (plugin.importPath.isEmpty() ? QLatin1String(".") : plugin.importPath);
|
||||||
runQmlDump(info, args, FilePath::fromString(plugin.qmldirPath));
|
runQmlDump(info, args, plugin.qmldirPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@@ -65,11 +65,11 @@ private:
|
|||||||
private:
|
private:
|
||||||
class Plugin {
|
class Plugin {
|
||||||
public:
|
public:
|
||||||
QString qmldirPath;
|
Utils::FilePath qmldirPath;
|
||||||
QString importPath;
|
QString importPath;
|
||||||
QString importUri;
|
QString importUri;
|
||||||
QString importVersion;
|
QString importVersion;
|
||||||
QStringList typeInfoPaths;
|
Utils::FilePaths typeInfoPaths;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QmlTypeDescription {
|
class QmlTypeDescription {
|
||||||
@@ -91,14 +91,14 @@ private:
|
|||||||
void runQmlDump(const QmlJS::ModelManagerInterface::ProjectInfo &info, const QStringList &arguments,
|
void runQmlDump(const QmlJS::ModelManagerInterface::ProjectInfo &info, const QStringList &arguments,
|
||||||
const Utils::FilePath &importPath);
|
const Utils::FilePath &importPath);
|
||||||
void dump(const Plugin &plugin);
|
void dump(const Plugin &plugin);
|
||||||
QFuture<QmlTypeDescription> loadQmlTypeDescription(const QStringList &path) const;
|
QFuture<QmlTypeDescription> loadQmlTypeDescription(const Utils::FilePaths &path) const;
|
||||||
QString buildQmltypesPath(const QString &name) const;
|
QString buildQmltypesPath(const QString &name) const;
|
||||||
|
|
||||||
QFuture<PluginDumper::DependencyInfo> loadDependencies(const QStringList &dependencies,
|
QFuture<PluginDumper::DependencyInfo> loadDependencies(const Utils::FilePaths &dependencies,
|
||||||
QSharedPointer<QSet<QString>> visited) const;
|
QSharedPointer<QSet<Utils::FilePath> > visited) const;
|
||||||
|
|
||||||
void loadQmltypesFile(const QStringList &qmltypesFilePaths,
|
void loadQmltypesFile(const Utils::FilePaths &qmltypesFilePaths,
|
||||||
const QString &libraryPath,
|
const Utils::FilePath &libraryPath,
|
||||||
QmlJS::LibraryInfo libraryInfo);
|
QmlJS::LibraryInfo libraryInfo);
|
||||||
QString resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
|
QString resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
|
||||||
const QString &baseName);
|
const QString &baseName);
|
||||||
@@ -109,7 +109,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
Utils::FileSystemWatcher *pluginWatcher();
|
Utils::FileSystemWatcher *pluginWatcher();
|
||||||
void prepareLibraryInfo(LibraryInfo &libInfo,
|
void prepareLibraryInfo(LibraryInfo &libInfo,
|
||||||
const QString &libraryPath,
|
const Utils::FilePath &libraryPath,
|
||||||
const QStringList &deps,
|
const QStringList &deps,
|
||||||
const QStringList &errors,
|
const QStringList &errors,
|
||||||
const QStringList &warnings,
|
const QStringList &warnings,
|
||||||
@@ -118,7 +118,7 @@ private:
|
|||||||
|
|
||||||
ModelManagerInterface *m_modelManager;
|
ModelManagerInterface *m_modelManager;
|
||||||
Utils::FileSystemWatcher *m_pluginWatcher;
|
Utils::FileSystemWatcher *m_pluginWatcher;
|
||||||
QHash<Utils::QtcProcess *, QString> m_runningQmldumps;
|
QHash<Utils::QtcProcess *, Utils::FilePath> m_runningQmldumps;
|
||||||
QList<Plugin> m_plugins;
|
QList<Plugin> m_plugins;
|
||||||
QHash<QString, int> m_libraryToPluginIndex;
|
QHash<QString, int> m_libraryToPluginIndex;
|
||||||
QHash<QString, QmlJS::ModelManagerInterface::ProjectInfo> m_qtToInfo;
|
QHash<QString, QmlJS::ModelManagerInterface::ProjectInfo> m_qtToInfo;
|
||||||
|
@@ -440,7 +440,7 @@ FilePath FilePath::fromFileInfo(const QFileInfo &info)
|
|||||||
QFileInfo FilePath::toFileInfo() const
|
QFileInfo FilePath::toFileInfo() const
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!needsDevice(), return QFileInfo());
|
QTC_ASSERT(!needsDevice(), return QFileInfo());
|
||||||
return QFileInfo(m_data);
|
return QFileInfo(cleanPath().path());
|
||||||
}
|
}
|
||||||
|
|
||||||
FilePath FilePath::fromUrl(const QUrl &url)
|
FilePath FilePath::fromUrl(const QUrl &url)
|
||||||
|
@@ -125,7 +125,9 @@ bool MultiTextCursor::hasSelection() const
|
|||||||
QString MultiTextCursor::selectedText() const
|
QString MultiTextCursor::selectedText() const
|
||||||
{
|
{
|
||||||
QString text;
|
QString text;
|
||||||
for (const QTextCursor &cursor : m_cursors) {
|
QList<QTextCursor> cursors = m_cursors;
|
||||||
|
Utils::sort(cursors);
|
||||||
|
for (const QTextCursor &cursor : cursors) {
|
||||||
const QString &cursorText = cursor.selectedText();
|
const QString &cursorText = cursor.selectedText();
|
||||||
if (cursorText.isEmpty())
|
if (cursorText.isEmpty())
|
||||||
continue;
|
continue;
|
||||||
@@ -169,7 +171,9 @@ void MultiTextCursor::insertText(const QString &text, bool selectNewText)
|
|||||||
lines.pop_back();
|
lines.pop_back();
|
||||||
int index = 0;
|
int index = 0;
|
||||||
if (lines.count() == m_cursors.count()) {
|
if (lines.count() == m_cursors.count()) {
|
||||||
for (QTextCursor &cursor : m_cursors)
|
QList<QTextCursor> cursors = m_cursors;
|
||||||
|
Utils::sort(cursors);
|
||||||
|
for (QTextCursor &cursor : cursors)
|
||||||
insertAndSelect(cursor, lines.at(index++), selectNewText);
|
insertAndSelect(cursor, lines.at(index++), selectNewText);
|
||||||
m_cursors.last().endEditBlock();
|
m_cursors.last().endEditBlock();
|
||||||
return;
|
return;
|
||||||
|
@@ -90,7 +90,8 @@ AndroidDeviceWidget::AndroidDeviceWidget(const IDevice::Ptr &device)
|
|||||||
formLayout->addRow(AndroidDevice::tr("Device type:"), new QLabel(dev->deviceTypeName()));
|
formLayout->addRow(AndroidDevice::tr("Device type:"), new QLabel(dev->deviceTypeName()));
|
||||||
|
|
||||||
const QString serialNumber = dev->serialNumber();
|
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));
|
formLayout->addRow(AndroidDevice::tr("Serial number:"), new QLabel(printableSerialNumber));
|
||||||
|
|
||||||
const QString abis = dev->supportedAbis().join(", ");
|
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));
|
formLayout->addRow(AndroidDevice::tr("OS version:"), new QLabel(osString));
|
||||||
|
|
||||||
if (dev->machineType() == IDevice::Hardware) {
|
if (dev->machineType() == IDevice::Hardware) {
|
||||||
const QString authorizedStr = dev->deviceState() == IDevice::DeviceReadyToUse ? tr("Yes")
|
const QString authorizedStr = dev->deviceState() == IDevice::DeviceReadyToUse
|
||||||
: tr("No");
|
? AndroidDevice::tr("Yes")
|
||||||
|
: AndroidDevice::tr("No");
|
||||||
formLayout->addRow(AndroidDevice::tr("Authorized:"), new QLabel(authorizedStr));
|
formLayout->addRow(AndroidDevice::tr("Authorized:"), new QLabel(authorizedStr));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,7 +119,7 @@ AndroidDeviceWidget::AndroidDeviceWidget(const IDevice::Ptr &device)
|
|||||||
|
|
||||||
QString AndroidDeviceWidget::dialogTitle()
|
QString AndroidDeviceWidget::dialogTitle()
|
||||||
{
|
{
|
||||||
return tr("Android Device Manager");
|
return AndroidDevice::tr("Android Device Manager");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidDeviceWidget::criticalDialog(const QString &error, QWidget *parent)
|
bool AndroidDeviceWidget::criticalDialog(const QString &error, QWidget *parent)
|
||||||
@@ -480,7 +482,8 @@ void AndroidDeviceManager::eraseAvd(const IDevice::Ptr &device, QWidget *parent)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
const QString name = static_cast<const AndroidDevice *>(device.data())->avdName();
|
const QString name = static_cast<const AndroidDevice *>(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))
|
if (!AndroidDeviceWidget::questionDialog(question, parent))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -515,9 +518,10 @@ void AndroidDeviceManager::setEmulatorArguments(QWidget *parent)
|
|||||||
"https://developer.android.com/studio/run/emulator-commandline#startup-options";
|
"https://developer.android.com/studio/run/emulator-commandline#startup-options";
|
||||||
|
|
||||||
QInputDialog dialog(parent ? parent : Core::ICore::dialogParent());
|
QInputDialog dialog(parent ? parent : Core::ICore::dialogParent());
|
||||||
dialog.setWindowTitle(tr("Emulator Command-line Startup Options"));
|
dialog.setWindowTitle(AndroidDevice::tr("Emulator Command-line Startup Options"));
|
||||||
dialog.setLabelText(tr("Emulator command-line startup options "
|
dialog.setLabelText(AndroidDevice::tr("Emulator command-line startup options "
|
||||||
"(<a href=\"%1\">Help Web Page</a>):").arg(helpUrl));
|
"(<a href=\"%1\">Help Web Page</a>):")
|
||||||
|
.arg(helpUrl));
|
||||||
dialog.setTextValue(m_androidConfig.emulatorArgs().join(' '));
|
dialog.setTextValue(m_androidConfig.emulatorArgs().join(' '));
|
||||||
|
|
||||||
if (auto label = dialog.findChild<QLabel*>()) {
|
if (auto label = dialog.findChild<QLabel*>()) {
|
||||||
|
@@ -327,7 +327,7 @@ AndroidRunnerWorker::~AndroidRunnerWorker()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidRunnerWorker::runAdb(const QStringList &args, QString *stdOut,
|
bool AndroidRunnerWorker::runAdb(const QStringList &args, QString *stdOut,
|
||||||
const QByteArray &writeData)
|
QString *stdErr, const QByteArray &writeData)
|
||||||
{
|
{
|
||||||
QStringList adbArgs = selector() + args;
|
QStringList adbArgs = selector() + args;
|
||||||
SdkToolResult result = AndroidManager::runAdbCommand(adbArgs, writeData);
|
SdkToolResult result = AndroidManager::runAdbCommand(adbArgs, writeData);
|
||||||
@@ -335,6 +335,8 @@ bool AndroidRunnerWorker::runAdb(const QStringList &args, QString *stdOut,
|
|||||||
emit remoteErrorOutput(result.stdErr());
|
emit remoteErrorOutput(result.stdErr());
|
||||||
if (stdOut)
|
if (stdOut)
|
||||||
*stdOut = result.stdOut();
|
*stdOut = result.stdOut();
|
||||||
|
if (stdErr)
|
||||||
|
*stdErr = result.stdErr();
|
||||||
return result.success();
|
return result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -651,10 +653,17 @@ void AndroidRunnerWorker::asyncStartHelper()
|
|||||||
.toUtf8().toBase64());
|
.toUtf8().toBase64());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!runAdb(args)) {
|
QString stdErr;
|
||||||
|
const bool startResult = runAdb(args, nullptr, &stdErr);
|
||||||
|
if (!startResult) {
|
||||||
emit remoteProcessFinished(tr("Failed to start the activity."));
|
emit remoteProcessFinished(tr("Failed to start the activity."));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!stdErr.isEmpty()) {
|
||||||
|
emit remoteErrorOutput(tr("Activity Manager threw the error: %1").arg(stdErr));
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AndroidRunnerWorker::startDebuggerServer(const QString &packageDir,
|
bool AndroidRunnerWorker::startDebuggerServer(const QString &packageDir,
|
||||||
|
@@ -47,7 +47,8 @@ public:
|
|||||||
AndroidRunnerWorker(ProjectExplorer::RunWorker *runner, const QString &packageName);
|
AndroidRunnerWorker(ProjectExplorer::RunWorker *runner, const QString &packageName);
|
||||||
~AndroidRunnerWorker() override;
|
~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);
|
void adbKill(qint64 pid);
|
||||||
QStringList selector() const;
|
QStringList selector() const;
|
||||||
void forceStop();
|
void forceStop();
|
||||||
|
@@ -1302,15 +1302,25 @@ void ClangdClient::findUsages(TextDocument *document, const QTextCursor &cursor,
|
|||||||
const Utils::optional<QString> &replacement)
|
const Utils::optional<QString> &replacement)
|
||||||
{
|
{
|
||||||
// Quick check: Are we even on anything searchable?
|
// Quick check: Are we even on anything searchable?
|
||||||
if (d->searchTermFromCursor(cursor).isEmpty())
|
const QString searchTerm = d->searchTermFromCursor(cursor);
|
||||||
|
if (searchTerm.isEmpty())
|
||||||
return;
|
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.
|
// search widget.
|
||||||
const TextDocumentIdentifier docId(DocumentUri::fromFilePath(document->filePath()));
|
const TextDocumentIdentifier docId(DocumentUri::fromFilePath(document->filePath()));
|
||||||
const TextDocumentPositionParams params(docId, Range(cursor).start());
|
const TextDocumentPositionParams params(docId, Range(cursor).start());
|
||||||
SymbolInfoRequest symReq(params);
|
SymbolInfoRequest symReq(params);
|
||||||
const bool categorize = CppEditor::codeModelSettings()->categorizeFindReferences();
|
|
||||||
symReq.setResponseCallback([this, doc = QPointer(document), cursor, replacement, categorize]
|
symReq.setResponseCallback([this, doc = QPointer(document), cursor, replacement, categorize]
|
||||||
(const SymbolInfoRequest::Response &response) {
|
(const SymbolInfoRequest::Response &response) {
|
||||||
if (!doc)
|
if (!doc)
|
||||||
@@ -2442,7 +2452,7 @@ static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
|
|||||||
} else if (token.type == "comment") { // "comment" means code disabled via the preprocessor
|
} else if (token.type == "comment") { // "comment" means code disabled via the preprocessor
|
||||||
styles.mainStyle = C_DISABLED_CODE;
|
styles.mainStyle = C_DISABLED_CODE;
|
||||||
} else if (token.type == "namespace") {
|
} else if (token.type == "namespace") {
|
||||||
styles.mainStyle = C_TYPE;
|
styles.mainStyle = C_NAMESPACE;
|
||||||
} else if (token.type == "property") {
|
} else if (token.type == "property") {
|
||||||
styles.mainStyle = C_FIELD;
|
styles.mainStyle = C_FIELD;
|
||||||
} else if (token.type == "enum") {
|
} else if (token.type == "enum") {
|
||||||
@@ -2463,6 +2473,8 @@ static void semanticHighlighter(QFutureInterface<HighlightingResult> &future,
|
|||||||
}
|
}
|
||||||
if (token.modifiers.contains("declaration"))
|
if (token.modifiers.contains("declaration"))
|
||||||
styles.mixinStyles.push_back(C_DECLARATION);
|
styles.mixinStyles.push_back(C_DECLARATION);
|
||||||
|
if (token.modifiers.contains("static"))
|
||||||
|
styles.mixinStyles.push_back(C_STATIC_MEMBER);
|
||||||
if (isOutputParameter(token))
|
if (isOutputParameter(token))
|
||||||
styles.mixinStyles.push_back(C_OUTPUT_ARGUMENT);
|
styles.mixinStyles.push_back(C_OUTPUT_ARGUMENT);
|
||||||
qCDebug(clangdLogHighlight) << "adding highlighting result"
|
qCDebug(clangdLogHighlight) << "adding highlighting result"
|
||||||
|
@@ -764,12 +764,12 @@ void ClangdTestHighlighting::test_data()
|
|||||||
QTest::newRow("struct declaration") << 50 << 8 << 50 << 11
|
QTest::newRow("struct declaration") << 50 << 8 << 50 << 11
|
||||||
<< QList<int>{C_TYPE, C_DECLARATION} << 0;
|
<< QList<int>{C_TYPE, C_DECLARATION} << 0;
|
||||||
QTest::newRow("namespace declaration") << 160 << 11 << 160 << 20
|
QTest::newRow("namespace declaration") << 160 << 11 << 160 << 20
|
||||||
<< QList<int>{C_TYPE, C_DECLARATION} << 0;
|
<< QList<int>{C_NAMESPACE, C_DECLARATION} << 0;
|
||||||
QTest::newRow("namespace alias declaration") << 164 << 11 << 164 << 25
|
QTest::newRow("namespace alias declaration") << 164 << 11 << 164 << 25
|
||||||
<< QList<int>{C_TYPE, C_DECLARATION} << 0;
|
<< QList<int>{C_NAMESPACE, C_DECLARATION} << 0;
|
||||||
QTest::newRow("struct in namespaced using declaration") << 165 << 18 << 165 << 35
|
QTest::newRow("struct in namespaced using declaration") << 165 << 18 << 165 << 35
|
||||||
<< QList<int>{C_TYPE} << 0;
|
<< QList<int>{C_TYPE} << 0;
|
||||||
QTest::newRow("namespace reference") << 166 << 1 << 166 << 10 << QList<int>{C_TYPE} << 0;
|
QTest::newRow("namespace reference") << 166 << 1 << 166 << 10 << QList<int>{C_NAMESPACE} << 0;
|
||||||
QTest::newRow("namespaced struct in global variable declaration") << 166 << 12 << 166 << 29
|
QTest::newRow("namespaced struct in global variable declaration") << 166 << 12 << 166 << 29
|
||||||
<< QList<int>{C_TYPE} << 0;
|
<< QList<int>{C_TYPE} << 0;
|
||||||
QTest::newRow("virtual function declaration") << 170 << 18 << 170 << 33
|
QTest::newRow("virtual function declaration") << 170 << 18 << 170 << 33
|
||||||
@@ -992,7 +992,8 @@ void ClangdTestHighlighting::test_data()
|
|||||||
<< QList<int>{C_PUNCTUATION} << int(CppEditor::SemanticHighlighter::AngleBracketOpen);
|
<< QList<int>{C_PUNCTUATION} << int(CppEditor::SemanticHighlighter::AngleBracketOpen);
|
||||||
QTest::newRow("class template instantiation (closing angle bracket)") << 384 << 22 << 384 << 23
|
QTest::newRow("class template instantiation (closing angle bracket)") << 384 << 22 << 384 << 23
|
||||||
<< QList<int>{C_PUNCTUATION} << int(CppEditor::SemanticHighlighter::AngleBracketClose);
|
<< QList<int>{C_PUNCTUATION} << int(CppEditor::SemanticHighlighter::AngleBracketClose);
|
||||||
QTest::newRow("namespace in declaration") << 413 << 4 << 413 << 26 << QList<int>{C_TYPE} << 0;
|
QTest::newRow("namespace in declaration") << 413 << 4 << 413 << 26
|
||||||
|
<< QList<int>{C_NAMESPACE} << 0;
|
||||||
QTest::newRow("namespaced class in declaration") << 413 << 28 << 413 << 41
|
QTest::newRow("namespaced class in declaration") << 413 << 28 << 413 << 41
|
||||||
<< QList<int>{C_TYPE} << 0;
|
<< QList<int>{C_TYPE} << 0;
|
||||||
QTest::newRow("class as template argument in declaration") << 413 << 42 << 413 << 52
|
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
|
QTest::newRow("local variable captured by lambda") << 442 << 24 << 442 << 27
|
||||||
<< QList<int>{C_LOCAL} << 0;
|
<< QList<int>{C_LOCAL} << 0;
|
||||||
QTest::newRow("static protected member") << 693 << 16 << 693 << 30
|
QTest::newRow("static protected member") << 693 << 16 << 693 << 30
|
||||||
<< QList<int>{C_FIELD, C_DECLARATION} << 0;
|
<< QList<int>{C_FIELD, C_DECLARATION, C_STATIC_MEMBER} << 0;
|
||||||
QTest::newRow("static private member") << 696 << 16 << 696 << 28
|
QTest::newRow("static private member") << 696 << 16 << 696 << 28
|
||||||
<< QList<int>{C_FIELD, C_DECLARATION} << 0;
|
<< QList<int>{C_FIELD, C_DECLARATION, C_STATIC_MEMBER} << 0;
|
||||||
QTest::newRow("alias template declaration (opening angle bracket)") << 700 << 10 << 700 << 11
|
QTest::newRow("alias template declaration (opening angle bracket)") << 700 << 10 << 700 << 11
|
||||||
<< QList<int>{C_PUNCTUATION} << int(CppEditor::SemanticHighlighter::AngleBracketOpen);
|
<< QList<int>{C_PUNCTUATION} << int(CppEditor::SemanticHighlighter::AngleBracketOpen);
|
||||||
QTest::newRow("alias template declaration (closing angle bracket)") << 700 << 16 << 700 << 17
|
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
|
QTest::newRow("reference to global variable") << 764 << 5 << 764 << 14
|
||||||
<< QList<int>{C_GLOBAL} << 0;
|
<< QList<int>{C_GLOBAL} << 0;
|
||||||
QTest::newRow("nested template instantiation (namespace 1)") << 773 << 8 << 773 << 11
|
QTest::newRow("nested template instantiation (namespace 1)") << 773 << 8 << 773 << 11
|
||||||
<< QList<int>{C_TYPE} << 0;
|
<< QList<int>{C_NAMESPACE} << 0;
|
||||||
QTest::newRow("nested template instantiation (type 1)") << 773 << 13 << 773 << 19
|
QTest::newRow("nested template instantiation (type 1)") << 773 << 13 << 773 << 19
|
||||||
<< QList<int>{C_TYPE} << 0;
|
<< QList<int>{C_TYPE} << 0;
|
||||||
QTest::newRow("nested template instantiation (opening angle bracket 1)")
|
QTest::newRow("nested template instantiation (opening angle bracket 1)")
|
||||||
<< 773 << 19 << 773 << 20
|
<< 773 << 19 << 773 << 20
|
||||||
<< QList<int>{C_PUNCTUATION} << int(CppEditor::SemanticHighlighter::AngleBracketOpen);
|
<< QList<int>{C_PUNCTUATION} << int(CppEditor::SemanticHighlighter::AngleBracketOpen);
|
||||||
QTest::newRow("nested template instantiation (namespace 2)") << 773 << 20 << 773 << 23
|
QTest::newRow("nested template instantiation (namespace 2)") << 773 << 20 << 773 << 23
|
||||||
<< QList<int>{C_TYPE} << 0;
|
<< QList<int>{C_NAMESPACE} << 0;
|
||||||
QTest::newRow("nested template instantiation (type 2)") << 773 << 25 << 773 << 29
|
QTest::newRow("nested template instantiation (type 2)") << 773 << 25 << 773 << 29
|
||||||
<< QList<int>{C_TYPE} << 0;
|
<< QList<int>{C_TYPE} << 0;
|
||||||
QTest::newRow("nested template instantiation (opening angle bracket 2)")
|
QTest::newRow("nested template instantiation (opening angle bracket 2)")
|
||||||
|
@@ -575,11 +575,11 @@ void ExternalToolConfig::updateItem(const QModelIndex &index)
|
|||||||
if (!tool)
|
if (!tool)
|
||||||
return;
|
return;
|
||||||
tool->setDescription(m_ui.description->text());
|
tool->setDescription(m_ui.description->text());
|
||||||
QStringList executables = tool->executables();
|
FilePaths executables = tool->executables();
|
||||||
if (executables.size() > 0)
|
if (executables.size() > 0)
|
||||||
executables[0] = m_ui.executable->rawPath();
|
executables[0] = m_ui.executable->rawFilePath();
|
||||||
else
|
else
|
||||||
executables << m_ui.executable->rawPath();
|
executables << m_ui.executable->rawFilePath();
|
||||||
tool->setExecutables(executables);
|
tool->setExecutables(executables);
|
||||||
tool->setArguments(m_ui.arguments->text());
|
tool->setArguments(m_ui.arguments->text());
|
||||||
tool->setWorkingDirectory(m_ui.workingDirectory->rawFilePath());
|
tool->setWorkingDirectory(m_ui.workingDirectory->rawFilePath());
|
||||||
@@ -607,8 +607,8 @@ void ExternalToolConfig::showInfoForItem(const QModelIndex &index)
|
|||||||
}
|
}
|
||||||
m_ui.infoWidget->setEnabled(true);
|
m_ui.infoWidget->setEnabled(true);
|
||||||
m_ui.description->setText(tool->description());
|
m_ui.description->setText(tool->description());
|
||||||
m_ui.executable->setPath(tool->executables().isEmpty() ? QString()
|
m_ui.executable->setFilePath(tool->executables().isEmpty() ? FilePath()
|
||||||
: tool->executables().constFirst());
|
: tool->executables().constFirst());
|
||||||
m_ui.arguments->setText(tool->arguments());
|
m_ui.arguments->setText(tool->arguments());
|
||||||
m_ui.workingDirectory->setFilePath(tool->workingDirectory());
|
m_ui.workingDirectory->setFilePath(tool->workingDirectory());
|
||||||
m_ui.outputBehavior->setCurrentIndex(int(tool->outputHandling()));
|
m_ui.outputBehavior->setCurrentIndex(int(tool->outputHandling()));
|
||||||
|
@@ -154,7 +154,7 @@ int ExternalTool::order() const
|
|||||||
return m_order;
|
return m_order;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList ExternalTool::executables() const
|
FilePaths ExternalTool::executables() const
|
||||||
{
|
{
|
||||||
return m_executables;
|
return m_executables;
|
||||||
}
|
}
|
||||||
@@ -250,43 +250,36 @@ void ExternalTool::setDescription(const QString &description)
|
|||||||
m_description = description;
|
m_description = description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ExternalTool::setOutputHandling(OutputHandling handling)
|
void ExternalTool::setOutputHandling(OutputHandling handling)
|
||||||
{
|
{
|
||||||
m_outputHandling = handling;
|
m_outputHandling = handling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ExternalTool::setErrorHandling(OutputHandling handling)
|
void ExternalTool::setErrorHandling(OutputHandling handling)
|
||||||
{
|
{
|
||||||
m_errorHandling = handling;
|
m_errorHandling = handling;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ExternalTool::setModifiesCurrentDocument(bool modifies)
|
void ExternalTool::setModifiesCurrentDocument(bool modifies)
|
||||||
{
|
{
|
||||||
m_modifiesCurrentDocument = modifies;
|
m_modifiesCurrentDocument = modifies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExternalTool::setExecutables(const FilePaths &executables)
|
||||||
void ExternalTool::setExecutables(const QStringList &executables)
|
|
||||||
{
|
{
|
||||||
m_executables = executables;
|
m_executables = executables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ExternalTool::setArguments(const QString &arguments)
|
void ExternalTool::setArguments(const QString &arguments)
|
||||||
{
|
{
|
||||||
m_arguments = arguments;
|
m_arguments = arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ExternalTool::setInput(const QString &input)
|
void ExternalTool::setInput(const QString &input)
|
||||||
{
|
{
|
||||||
m_input = input;
|
m_input = input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ExternalTool::setWorkingDirectory(const FilePath &workingDirectory)
|
void ExternalTool::setWorkingDirectory(const FilePath &workingDirectory)
|
||||||
{
|
{
|
||||||
m_workingDirectory = workingDirectory;
|
m_workingDirectory = workingDirectory;
|
||||||
@@ -417,7 +410,7 @@ ExternalTool * ExternalTool::createFromXml(const QByteArray &xml, QString *error
|
|||||||
}
|
}
|
||||||
while (reader.readNextStartElement()) {
|
while (reader.readNextStartElement()) {
|
||||||
if (reader.name() == QLatin1String(kPath)) {
|
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)) {
|
} else if (reader.name() == QLatin1String(kArguments)) {
|
||||||
if (!tool->m_arguments.isEmpty()) {
|
if (!tool->m_arguments.isEmpty()) {
|
||||||
reader.raiseError("only one <arguments> element allowed");
|
reader.raiseError("only one <arguments> element allowed");
|
||||||
@@ -519,8 +512,8 @@ bool ExternalTool::save(QString *errorMessage) const
|
|||||||
out.writeAttribute(kOutput, stringForOutputHandling(m_outputHandling));
|
out.writeAttribute(kOutput, stringForOutputHandling(m_outputHandling));
|
||||||
out.writeAttribute(kError, stringForOutputHandling(m_errorHandling));
|
out.writeAttribute(kError, stringForOutputHandling(m_errorHandling));
|
||||||
out.writeAttribute(kModifiesDocument, QLatin1String(m_modifiesCurrentDocument ? kYes : kNo));
|
out.writeAttribute(kModifiesDocument, QLatin1String(m_modifiesCurrentDocument ? kYes : kNo));
|
||||||
foreach (const QString &executable, m_executables)
|
for (const FilePath &executable : m_executables)
|
||||||
out.writeTextElement(kPath, executable);
|
out.writeTextElement(kPath, executable.toString());
|
||||||
if (!m_arguments.isEmpty())
|
if (!m_arguments.isEmpty())
|
||||||
out.writeTextElement(kArguments, m_arguments);
|
out.writeTextElement(kArguments, m_arguments);
|
||||||
if (!m_input.isEmpty())
|
if (!m_input.isEmpty())
|
||||||
@@ -608,11 +601,12 @@ bool ExternalToolRunner::resolve()
|
|||||||
|
|
||||||
{
|
{
|
||||||
// executable
|
// executable
|
||||||
QStringList expandedExecutables; /* for error message */
|
FilePaths expandedExecutables; /* for error message */
|
||||||
foreach (const QString &executable, m_tool->executables()) {
|
const FilePaths executables = m_tool->executables();
|
||||||
QString expanded = expander->expand(executable);
|
for (const FilePath &executable : executables) {
|
||||||
|
FilePath expanded = expander->expand(executable);
|
||||||
expandedExecutables.append(expanded);
|
expandedExecutables.append(expanded);
|
||||||
m_resolvedExecutable = m_resolvedEnvironment.searchInPath(expanded);
|
m_resolvedExecutable = m_resolvedEnvironment.searchInPath(expanded.path());
|
||||||
if (!m_resolvedExecutable.isEmpty())
|
if (!m_resolvedExecutable.isEmpty())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -620,7 +614,8 @@ bool ExternalToolRunner::resolve()
|
|||||||
m_hasError = true;
|
m_hasError = true;
|
||||||
for (int i = 0; i < expandedExecutables.size(); ++i) {
|
for (int i = 0; i < expandedExecutables.size(); ++i) {
|
||||||
m_errorString += tr("Could not find executable for \"%1\" (expanded \"%2\")")
|
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');
|
m_errorString += QLatin1Char('\n');
|
||||||
}
|
}
|
||||||
if (!m_errorString.isEmpty())
|
if (!m_errorString.isEmpty())
|
||||||
|
@@ -64,7 +64,7 @@ public:
|
|||||||
OutputHandling errorHandling() const;
|
OutputHandling errorHandling() const;
|
||||||
bool modifiesCurrentDocument() const;
|
bool modifiesCurrentDocument() const;
|
||||||
|
|
||||||
QStringList executables() const;
|
Utils::FilePaths executables() const;
|
||||||
QString arguments() const;
|
QString arguments() const;
|
||||||
QString input() const;
|
QString input() const;
|
||||||
Utils::FilePath workingDirectory() const;
|
Utils::FilePath workingDirectory() const;
|
||||||
@@ -95,7 +95,7 @@ public:
|
|||||||
void setOutputHandling(OutputHandling handling);
|
void setOutputHandling(OutputHandling handling);
|
||||||
void setErrorHandling(OutputHandling handling);
|
void setErrorHandling(OutputHandling handling);
|
||||||
void setModifiesCurrentDocument(bool modifies);
|
void setModifiesCurrentDocument(bool modifies);
|
||||||
void setExecutables(const QStringList &executables);
|
void setExecutables(const Utils::FilePaths &executables);
|
||||||
void setArguments(const QString &arguments);
|
void setArguments(const QString &arguments);
|
||||||
void setInput(const QString &input);
|
void setInput(const QString &input);
|
||||||
void setWorkingDirectory(const Utils::FilePath &workingDirectory);
|
void setWorkingDirectory(const Utils::FilePath &workingDirectory);
|
||||||
@@ -108,7 +108,7 @@ private:
|
|||||||
QString m_displayName;
|
QString m_displayName;
|
||||||
QString m_displayCategory;
|
QString m_displayCategory;
|
||||||
int m_order = -1;
|
int m_order = -1;
|
||||||
QStringList m_executables;
|
Utils::FilePaths m_executables;
|
||||||
QString m_arguments;
|
QString m_arguments;
|
||||||
QString m_input;
|
QString m_input;
|
||||||
Utils::FilePath m_workingDirectory;
|
Utils::FilePath m_workingDirectory;
|
||||||
|
@@ -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
|
// documentation, that we only return the Qt5 link even though the Qt5 and Qt4 URLs look
|
||||||
// different.
|
// different.
|
||||||
QVersionNumber highestVersion;
|
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) {
|
for (const HelpItem::Link &link : links) {
|
||||||
const QVersionNumber version = extractVersion(link.second).second;
|
const QVersionNumber version = extractVersion(link.second).second;
|
||||||
if (version > highestVersion) {
|
if (version > highestVersion) {
|
||||||
|
@@ -477,7 +477,7 @@ bool CheckSymbols::visit(NamespaceAST *ast)
|
|||||||
if (!tok.generated()) {
|
if (!tok.generated()) {
|
||||||
int line, column;
|
int line, column;
|
||||||
getTokenStartPosition(ast->identifier_token, &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);
|
addUse(use);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1221,7 +1221,15 @@ void CheckSymbols::addType(ClassOrNamespace *b, NameAST *ast)
|
|||||||
int line, column;
|
int line, column;
|
||||||
getTokenStartPosition(startToken, &line, &column);
|
getTokenStartPosition(startToken, &line, &column);
|
||||||
const unsigned length = tok.utf16chars();
|
const unsigned length = tok.utf16chars();
|
||||||
const Result use(line, column, length, SemanticHighlighter::TypeUse);
|
Kind kind = SemanticHighlighter::TypeUse;
|
||||||
|
const QList<Symbol *> &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);
|
addUse(use);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1266,6 +1274,8 @@ bool CheckSymbols::maybeAddTypeOrStatic(const QList<LookupItem> &candidates, Nam
|
|||||||
Kind kind = SemanticHighlighter::TypeUse;
|
Kind kind = SemanticHighlighter::TypeUse;
|
||||||
if (c->enclosingEnum() != nullptr)
|
if (c->enclosingEnum() != nullptr)
|
||||||
kind = SemanticHighlighter::EnumerationUse;
|
kind = SemanticHighlighter::EnumerationUse;
|
||||||
|
else if (c->isNamespace())
|
||||||
|
kind = SemanticHighlighter::NamespaceUse;
|
||||||
else if (c->isStatic())
|
else if (c->isStatic())
|
||||||
// treat static variable as a field(highlighting)
|
// treat static variable as a field(highlighting)
|
||||||
kind = SemanticHighlighter::FieldUse;
|
kind = SemanticHighlighter::FieldUse;
|
||||||
@@ -1305,7 +1315,8 @@ bool CheckSymbols::maybeAddField(const QList<LookupItem> &candidates, NameAST *a
|
|||||||
getTokenStartPosition(startToken, &line, &column);
|
getTokenStartPosition(startToken, &line, &column);
|
||||||
const unsigned length = tok.utf16chars();
|
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);
|
addUse(use);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -1359,12 +1370,15 @@ bool CheckSymbols::maybeAddFunction(const QList<LookupItem> &candidates, NameAST
|
|||||||
continue; // TODO: add diagnostic messages and color call-operators calls too?
|
continue; // TODO: add diagnostic messages and color call-operators calls too?
|
||||||
|
|
||||||
const bool isVirtual = funTy->isVirtual();
|
const bool isVirtual = funTy->isVirtual();
|
||||||
|
const bool isStaticMember = funTy->isStatic() && funTy->enclosingClass();
|
||||||
Kind matchingKind;
|
Kind matchingKind;
|
||||||
if (functionKind == FunctionDeclaration) {
|
if (functionKind == FunctionDeclaration) {
|
||||||
matchingKind = isVirtual ? SemanticHighlighter::VirtualFunctionDeclarationUse
|
matchingKind = isVirtual ? SemanticHighlighter::VirtualFunctionDeclarationUse
|
||||||
|
: isStaticMember ? SemanticHighlighter::StaticMethodDeclarationUse
|
||||||
: SemanticHighlighter::FunctionDeclarationUse;
|
: SemanticHighlighter::FunctionDeclarationUse;
|
||||||
} else {
|
} else {
|
||||||
matchingKind = isVirtual ? SemanticHighlighter::VirtualMethodUse
|
matchingKind = isVirtual ? SemanticHighlighter::VirtualMethodUse
|
||||||
|
: isStaticMember ? SemanticHighlighter::StaticMethodUse
|
||||||
: SemanticHighlighter::FunctionUse;
|
: SemanticHighlighter::FunctionUse;
|
||||||
}
|
}
|
||||||
if (argumentCount < funTy->minimumArgumentCount()) {
|
if (argumentCount < funTy->minimumArgumentCount()) {
|
||||||
|
@@ -326,6 +326,20 @@ void DoxygenTest::testBasic_data()
|
|||||||
"};\n"
|
"};\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
QTest::newRow("classTemplate") << _(
|
||||||
|
"bool preventFolding;\n"
|
||||||
|
"/**|\n"
|
||||||
|
"template<typename T> class C {\n"
|
||||||
|
"};\n"
|
||||||
|
) << _(
|
||||||
|
"bool preventFolding;\n"
|
||||||
|
"/**\n"
|
||||||
|
" * @brief The C class\n"
|
||||||
|
" */\n"
|
||||||
|
"template<typename T> class C {\n"
|
||||||
|
"};\n"
|
||||||
|
);
|
||||||
|
|
||||||
QTest::newRow("continuation_after_text_in_first_line") << _(
|
QTest::newRow("continuation_after_text_in_first_line") << _(
|
||||||
"bool preventFolding;\n"
|
"bool preventFolding;\n"
|
||||||
"/*! leading comment|\n"
|
"/*! leading comment|\n"
|
||||||
|
@@ -141,6 +141,9 @@ QString DoxygenGenerator::generate(QTextCursor cursor,
|
|||||||
|
|
||||||
QString DoxygenGenerator::generate(QTextCursor cursor, DeclarationAST *decl)
|
QString DoxygenGenerator::generate(QTextCursor cursor, DeclarationAST *decl)
|
||||||
{
|
{
|
||||||
|
if (const TemplateDeclarationAST * const templDecl = decl->asTemplateDeclaration())
|
||||||
|
decl = templDecl->declaration;
|
||||||
|
|
||||||
SpecifierAST *spec = nullptr;
|
SpecifierAST *spec = nullptr;
|
||||||
DeclaratorAST *decltr = nullptr;
|
DeclaratorAST *decltr = nullptr;
|
||||||
if (SimpleDeclarationAST *simpleDecl = decl->asSimpleDeclaration()) {
|
if (SimpleDeclarationAST *simpleDecl = decl->asSimpleDeclaration()) {
|
||||||
|
@@ -316,6 +316,7 @@ void SemanticHighlighter::updateFormatMapFromFontSettings()
|
|||||||
const FontSettings &fs = m_baseTextDocument->fontSettings();
|
const FontSettings &fs = m_baseTextDocument->fontSettings();
|
||||||
|
|
||||||
m_formatMap[TypeUse] = fs.toTextCharFormat(C_TYPE);
|
m_formatMap[TypeUse] = fs.toTextCharFormat(C_TYPE);
|
||||||
|
m_formatMap[NamespaceUse] = fs.toTextCharFormat(C_NAMESPACE);
|
||||||
m_formatMap[LocalUse] = fs.toTextCharFormat(C_LOCAL);
|
m_formatMap[LocalUse] = fs.toTextCharFormat(C_LOCAL);
|
||||||
m_formatMap[FieldUse] = fs.toTextCharFormat(C_FIELD);
|
m_formatMap[FieldUse] = fs.toTextCharFormat(C_FIELD);
|
||||||
m_formatMap[EnumerationUse] = fs.toTextCharFormat(C_ENUMERATION);
|
m_formatMap[EnumerationUse] = fs.toTextCharFormat(C_ENUMERATION);
|
||||||
@@ -328,6 +329,12 @@ void SemanticHighlighter::updateFormatMapFromFontSettings()
|
|||||||
m_formatMap[VirtualFunctionDeclarationUse] =
|
m_formatMap[VirtualFunctionDeclarationUse] =
|
||||||
fs.toTextCharFormat(TextStyles::mixinStyle(C_VIRTUAL_METHOD, C_DECLARATION));
|
fs.toTextCharFormat(TextStyles::mixinStyle(C_VIRTUAL_METHOD, C_DECLARATION));
|
||||||
m_formatMap[PseudoKeywordUse] = fs.toTextCharFormat(C_KEYWORD);
|
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
|
} // namespace CppEditor
|
||||||
|
@@ -48,6 +48,7 @@ public:
|
|||||||
enum Kind {
|
enum Kind {
|
||||||
Unknown = 0,
|
Unknown = 0,
|
||||||
TypeUse,
|
TypeUse,
|
||||||
|
NamespaceUse,
|
||||||
LocalUse,
|
LocalUse,
|
||||||
FieldUse,
|
FieldUse,
|
||||||
EnumerationUse,
|
EnumerationUse,
|
||||||
@@ -58,6 +59,9 @@ public:
|
|||||||
PseudoKeywordUse,
|
PseudoKeywordUse,
|
||||||
FunctionDeclarationUse,
|
FunctionDeclarationUse,
|
||||||
VirtualFunctionDeclarationUse,
|
VirtualFunctionDeclarationUse,
|
||||||
|
StaticFieldUse,
|
||||||
|
StaticMethodUse,
|
||||||
|
StaticMethodDeclarationUse,
|
||||||
AngleBracketOpen,
|
AngleBracketOpen,
|
||||||
AngleBracketClose,
|
AngleBracketClose,
|
||||||
DoubleAngleBracketClose,
|
DoubleAngleBracketClose,
|
||||||
|
@@ -57,8 +57,11 @@
|
|||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/messagebox.h>
|
#include <coreplugin/messagebox.h>
|
||||||
#include <projectexplorer/taskhub.h>
|
#include <projectexplorer/taskhub.h>
|
||||||
|
#include <qtsupport/baseqtversion.h>
|
||||||
|
#include <qtsupport/qtversionmanager.h>
|
||||||
#include <texteditor/texteditor.h>
|
#include <texteditor/texteditor.h>
|
||||||
|
|
||||||
|
#include <utils/checkablemessagebox.h>
|
||||||
#include <utils/consoleprocess.h>
|
#include <utils/consoleprocess.h>
|
||||||
#include <utils/fileutils.h>
|
#include <utils/fileutils.h>
|
||||||
#include <utils/hostosinfo.h>
|
#include <utils/hostosinfo.h>
|
||||||
@@ -2243,6 +2246,60 @@ static inline bool checkCommandToken(const QString &tokenPrefix, const QString &
|
|||||||
return ok;
|
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)
|
void CdbEngine::parseOutputLine(QString line)
|
||||||
{
|
{
|
||||||
// The hooked output callback in the extension suppresses prompts,
|
// 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
|
// 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 QRegularExpression moduleRegExp("[0-9a-fA-F]+(`[0-9a-fA-F]+)? [0-9a-fA-F]+(`[0-9a-fA-F]+)? (.*)");
|
||||||
const QRegularExpressionMatch match = moduleRegExp.match(line);
|
const QRegularExpressionMatch match = moduleRegExp.match(line);
|
||||||
if (match.hasMatch())
|
if (match.hasMatch()) {
|
||||||
showStatusMessage(tr("Module loaded: %1").arg(match.captured(3).trimmed()), 3000);
|
const QString module = match.captured(3).trimmed();
|
||||||
|
showStatusMessage(tr("Module loaded: %1").arg(module), 3000);
|
||||||
|
checkQtSdkPdbFiles(module);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
showMessage(line, LogMisc);
|
showMessage(line, LogMisc);
|
||||||
}
|
}
|
||||||
|
@@ -194,6 +194,7 @@ private:
|
|||||||
int elapsedLogTime();
|
int elapsedLogTime();
|
||||||
unsigned parseStackTrace(const GdbMi &data, bool sourceStepInto);
|
unsigned parseStackTrace(const GdbMi &data, bool sourceStepInto);
|
||||||
void mergeStartParametersSourcePathMap();
|
void mergeStartParametersSourcePathMap();
|
||||||
|
void checkQtSdkPdbFiles(const QString &module);
|
||||||
|
|
||||||
const QString m_tokenPrefix;
|
const QString m_tokenPrefix;
|
||||||
void handleSetupFailure(const QString &errorMessage);
|
void handleSetupFailure(const QString &errorMessage);
|
||||||
|
@@ -74,6 +74,7 @@
|
|||||||
#include <texteditor/fontsettings.h>
|
#include <texteditor/fontsettings.h>
|
||||||
|
|
||||||
#include <utils/basetreeview.h>
|
#include <utils/basetreeview.h>
|
||||||
|
#include <utils/checkablemessagebox.h>
|
||||||
#include <utils/macroexpander.h>
|
#include <utils/macroexpander.h>
|
||||||
#include <utils/processhandle.h>
|
#include <utils/processhandle.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -1096,7 +1097,7 @@ void DebuggerEngine::gotoLocation(const Location &loc)
|
|||||||
showMessage("CANNOT GO TO THIS LOCATION");
|
showMessage("CANNOT GO TO THIS LOCATION");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const QString file = loc.fileName().toString();
|
const FilePath file = loc.fileName();
|
||||||
const int line = loc.lineNumber();
|
const int line = loc.lineNumber();
|
||||||
bool newEditor = false;
|
bool newEditor = false;
|
||||||
IEditor *editor = EditorManager::openEditor(file,
|
IEditor *editor = EditorManager::openEditor(file,
|
||||||
@@ -2729,27 +2730,34 @@ Context CppDebuggerEngine::languageContext() const
|
|||||||
|
|
||||||
void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp)
|
void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp)
|
||||||
{
|
{
|
||||||
|
static const QString warnOnInappropriateDebuggerKey = "DebuggerWarnOnInappropriateDebugger";
|
||||||
|
QtcSettings *coreSettings = Core::ICore::settings();
|
||||||
|
|
||||||
const bool warnOnRelease = debuggerSettings()->warnOnReleaseBuilds.value()
|
const bool warnOnRelease = debuggerSettings()->warnOnReleaseBuilds.value()
|
||||||
&& rp.toolChainAbi.osFlavor() != Abi::AndroidLinuxFlavor;
|
&& rp.toolChainAbi.osFlavor() != Abi::AndroidLinuxFlavor;
|
||||||
bool warnOnInappropriateDebugger = false;
|
bool warnOnInappropriateDebugger = false;
|
||||||
QString detailedWarning;
|
QString detailedWarning;
|
||||||
switch (rp.toolChainAbi.binaryFormat()) {
|
switch (rp.toolChainAbi.binaryFormat()) {
|
||||||
case Abi::PEFormat: {
|
case Abi::PEFormat: {
|
||||||
QString preferredDebugger;
|
if (CheckableMessageBox::shouldAskAgain(coreSettings, warnOnInappropriateDebuggerKey)) {
|
||||||
if (rp.toolChainAbi.osFlavor() == Abi::WindowsMSysFlavor) {
|
QString preferredDebugger;
|
||||||
if (rp.cppEngineType == CdbEngineType)
|
if (rp.toolChainAbi.osFlavor() == Abi::WindowsMSysFlavor) {
|
||||||
preferredDebugger = "GDB";
|
if (rp.cppEngineType == CdbEngineType)
|
||||||
} else if (rp.cppEngineType != CdbEngineType) {
|
preferredDebugger = "GDB";
|
||||||
// osFlavor() is MSVC, so the recommended debugger is CDB
|
} else if (rp.cppEngineType != CdbEngineType && rp.cppEngineType != LldbEngineType) {
|
||||||
preferredDebugger = "CDB";
|
// osFlavor() is MSVC, so the recommended debugger is still CDB,
|
||||||
}
|
// but don't warn for LLDB which starts to be usable, too.
|
||||||
if (!preferredDebugger.isEmpty()) {
|
preferredDebugger = "CDB";
|
||||||
warnOnInappropriateDebugger = true;
|
}
|
||||||
detailedWarning = DebuggerEngine::tr(
|
if (!preferredDebugger.isEmpty()) {
|
||||||
"The inferior is in the Portable Executable format.\n"
|
warnOnInappropriateDebugger = true;
|
||||||
"Selecting %1 as debugger would improve the debugging "
|
detailedWarning = DebuggerEngine::tr(
|
||||||
"experience for this binary format.").arg(preferredDebugger);
|
"The inferior is in the Portable Executable format.\n"
|
||||||
break;
|
"Selecting %1 as debugger would improve the debugging "
|
||||||
|
"experience for this binary format.")
|
||||||
|
.arg(preferredDebugger);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (warnOnRelease
|
if (warnOnRelease
|
||||||
&& rp.cppEngineType == CdbEngineType
|
&& rp.cppEngineType == CdbEngineType
|
||||||
@@ -2771,13 +2779,15 @@ void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Abi::ElfFormat: {
|
case Abi::ElfFormat: {
|
||||||
if (rp.cppEngineType == CdbEngineType) {
|
if (CheckableMessageBox::shouldAskAgain(coreSettings, warnOnInappropriateDebuggerKey)) {
|
||||||
warnOnInappropriateDebugger = true;
|
if (rp.cppEngineType == CdbEngineType) {
|
||||||
detailedWarning = DebuggerEngine::tr(
|
warnOnInappropriateDebugger = true;
|
||||||
"The inferior is in the ELF format.\n"
|
detailedWarning = DebuggerEngine::tr(
|
||||||
"Selecting GDB or LLDB as debugger would improve the debugging "
|
"The inferior is in the ELF format.\n"
|
||||||
"experience for this binary format.");
|
"Selecting GDB or LLDB as debugger would improve the debugging "
|
||||||
break;
|
"experience for this binary format.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ElfReader reader(rp.symbolFile);
|
ElfReader reader(rp.symbolFile);
|
||||||
@@ -2876,11 +2886,16 @@ void CppDebuggerEngine::validateRunParameters(DebuggerRunParameters &rp)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (warnOnInappropriateDebugger) {
|
if (warnOnInappropriateDebugger) {
|
||||||
AsynchronousMessageBox::information(DebuggerEngine::tr("Warning"),
|
CheckableMessageBox::doNotShowAgainInformation(
|
||||||
DebuggerEngine::tr("The selected debugger may be inappropriate for the inferior.\n"
|
Core::ICore::dialogParent(),
|
||||||
"Examining symbols and setting breakpoints by file name and line number "
|
DebuggerEngine::tr("Warning"),
|
||||||
"may fail.\n")
|
DebuggerEngine::tr(
|
||||||
+ '\n' + detailedWarning);
|
"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) {
|
} else if (warnOnRelease) {
|
||||||
AsynchronousMessageBox::information(DebuggerEngine::tr("Warning"),
|
AsynchronousMessageBox::information(DebuggerEngine::tr("Warning"),
|
||||||
DebuggerEngine::tr("This does not seem to be a \"Debug\" build.\n"
|
DebuggerEngine::tr("This does not seem to be a \"Debug\" build.\n"
|
||||||
|
@@ -150,7 +150,8 @@ void DebuggerItem::reinitializeFromFile(const Environment &sysEnv, QString *erro
|
|||||||
// except for the experimental LLDB-MI which insists on --version.
|
// except for the experimental LLDB-MI which insists on --version.
|
||||||
QString version = "-version";
|
QString version = "-version";
|
||||||
m_lastModified = m_command.lastModified();
|
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";
|
version = "--version";
|
||||||
|
|
||||||
// We don't need to start the uVision executable to
|
// 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.
|
//! \note If unable to determine the GDB ABI, no ABI is appended to m_abis here.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (output.startsWith("lldb") || output.startsWith("LLDB")) {
|
if (output.contains("lldb") || output.startsWith("LLDB")) {
|
||||||
m_engineType = LldbEngineType;
|
m_engineType = LldbEngineType;
|
||||||
m_abis = Abi::abisOfBinary(m_command);
|
m_abis = Abi::abisOfBinary(m_command);
|
||||||
|
|
||||||
// Version
|
// Version
|
||||||
// Self-build binaries also emit clang and llvm revision.
|
// Self-build binaries also emit clang and llvm revision.
|
||||||
const QString line = output.split('\n')[0];
|
const QString line = output.split('\n')[0];
|
||||||
if (line.startsWith(("lldb version "))) { // Linux typically.
|
const QString nonMacOSPrefix = "lldb version ";
|
||||||
int pos1 = int(strlen("lldb version "));
|
if (line.contains(nonMacOSPrefix)) { // Linux typically, or some Windows builds.
|
||||||
|
int pos1 = line.indexOf(nonMacOSPrefix) + nonMacOSPrefix.length();
|
||||||
int pos2 = line.indexOf(' ', pos1);
|
int pos2 = line.indexOf(' ', pos1);
|
||||||
m_version = line.mid(pos1, pos2 - pos1);
|
m_version = line.mid(pos1, pos2 - pos1);
|
||||||
} else if (line.startsWith("lldb-") || line.startsWith("LLDB-")) { // Mac typically.
|
} else if (line.startsWith("lldb-") || line.startsWith("LLDB-")) { // Mac typically.
|
||||||
|
@@ -58,11 +58,12 @@
|
|||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
PdbEngine::PdbEngine()
|
PdbEngine::PdbEngine() : m_proc(ProcessMode::Writer)
|
||||||
{
|
{
|
||||||
setObjectName("PdbEngine");
|
setObjectName("PdbEngine");
|
||||||
setDebuggerName("PDB");
|
setDebuggerName("PDB");
|
||||||
@@ -117,13 +118,10 @@ void PdbEngine::setupEngine()
|
|||||||
m_interpreter = runParameters().interpreter;
|
m_interpreter = runParameters().interpreter;
|
||||||
QString bridge = ICore::resourcePath("debugger/pdbbridge.py").toString();
|
QString bridge = ICore::resourcePath("debugger/pdbbridge.py").toString();
|
||||||
|
|
||||||
connect(&m_proc, &QProcess::errorOccurred, this, &PdbEngine::handlePdbError);
|
connect(&m_proc, &QtcProcess::errorOccurred, this, &PdbEngine::handlePdbError);
|
||||||
connect(&m_proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
|
connect(&m_proc, &QtcProcess::finished, this, &PdbEngine::handlePdbFinished);
|
||||||
this, &PdbEngine::handlePdbFinished);
|
connect(&m_proc, &QtcProcess::readyReadStandardOutput, this, &PdbEngine::readPdbStandardOutput);
|
||||||
connect(&m_proc, &QProcess::readyReadStandardOutput,
|
connect(&m_proc, &QtcProcess::readyReadStandardError, this, &PdbEngine::readPdbStandardError);
|
||||||
this, &PdbEngine::readPdbStandardOutput);
|
|
||||||
connect(&m_proc, &QProcess::readyReadStandardError,
|
|
||||||
this, &PdbEngine::readPdbStandardError);
|
|
||||||
|
|
||||||
QFile scriptFile(runParameters().mainScript);
|
QFile scriptFile(runParameters().mainScript);
|
||||||
if (!scriptFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
|
if (!scriptFile.open(QIODevice::ReadOnly|QIODevice::Text)) {
|
||||||
@@ -134,10 +132,11 @@ void PdbEngine::setupEngine()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QStringList args = {bridge, scriptFile.fileName()};
|
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(' '));
|
showMessage("STARTING " + m_interpreter + ' ' + args.join(' '));
|
||||||
m_proc.setEnvironment(runParameters().debugger.environment.toStringList());
|
m_proc.setEnvironment(runParameters().debugger.environment);
|
||||||
m_proc.start(m_interpreter, args);
|
m_proc.setCommand({ FilePath::fromString(m_interpreter), args });
|
||||||
|
m_proc.start();
|
||||||
|
|
||||||
if (!m_proc.waitForStarted()) {
|
if (!m_proc.waitForStarted()) {
|
||||||
const QString msg = tr("Unable to start pdb \"%1\": %2")
|
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)
|
void PdbEngine::refreshLocation(const GdbMi &reportedLocation)
|
||||||
{
|
{
|
||||||
StackFrame frame;
|
StackFrame frame;
|
||||||
frame.file = Utils::FilePath::fromString(reportedLocation["file"].data());
|
frame.file = FilePath::fromString(reportedLocation["file"].data());
|
||||||
frame.line = reportedLocation["line"].toInt();
|
frame.line = reportedLocation["line"].toInt();
|
||||||
frame.usable = frame.file.isReadableFile();
|
frame.usable = frame.file.isReadableFile();
|
||||||
if (state() == InferiorRunOk) {
|
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();
|
notifyEngineSpontaneousShutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,10 +495,9 @@ void PdbEngine::handleOutput2(const QString &data)
|
|||||||
const QString bpnr = line.mid(11, pos1 - 11);
|
const QString bpnr = line.mid(11, pos1 - 11);
|
||||||
const int pos2 = line.lastIndexOf(':');
|
const int pos2 = line.lastIndexOf(':');
|
||||||
QTC_ASSERT(pos2 != -1, continue);
|
QTC_ASSERT(pos2 != -1, continue);
|
||||||
const Utils::FilePath fileName = Utils::FilePath::fromString(
|
const FilePath fileName = FilePath::fromString(line.mid(pos1 + 4, pos2 - pos1 - 4));
|
||||||
line.mid(pos1 + 4, pos2 - pos1 - 4));
|
|
||||||
const int lineNumber = line.mid(pos2 + 1).toInt();
|
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())
|
return bp->parameters().isLocatedAt(fileName, lineNumber, bp->markerFileName())
|
||||||
|| bp->requestedParameters().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"]) {
|
for (const GdbMi &item : stack["frames"]) {
|
||||||
StackFrame frame;
|
StackFrame frame;
|
||||||
frame.level = item["level"].data();
|
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.function = item["function"].data();
|
||||||
frame.module = item["function"].data();
|
frame.module = item["function"].data();
|
||||||
frame.line = item["line"].toInt();
|
frame.line = item["line"].toInt();
|
||||||
|
@@ -26,8 +26,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <debugger/debuggerengine.h>
|
#include <debugger/debuggerengine.h>
|
||||||
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
#include <QProcess>
|
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
@@ -100,7 +100,7 @@ private:
|
|||||||
QString errorMessage(QProcess::ProcessError error) const;
|
QString errorMessage(QProcess::ProcessError error) const;
|
||||||
bool hasCapability(unsigned cap) const override;
|
bool hasCapability(unsigned cap) const override;
|
||||||
|
|
||||||
void handlePdbFinished(int, QProcess::ExitStatus status);
|
void handlePdbFinished();
|
||||||
void handlePdbError(QProcess::ProcessError error);
|
void handlePdbError(QProcess::ProcessError error);
|
||||||
void readPdbStandardOutput();
|
void readPdbStandardOutput();
|
||||||
void readPdbStandardError();
|
void readPdbStandardError();
|
||||||
@@ -111,7 +111,7 @@ private:
|
|||||||
void updateLocals() override;
|
void updateLocals() override;
|
||||||
|
|
||||||
QString m_inbuffer;
|
QString m_inbuffer;
|
||||||
QProcess m_proc;
|
Utils::QtcProcess m_proc;
|
||||||
QString m_interpreter;
|
QString m_interpreter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -50,7 +50,12 @@ bool isIntType(const QString &type)
|
|||||||
case 'c':
|
case 'c':
|
||||||
return type == "char";
|
return type == "char";
|
||||||
case 'i':
|
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':
|
case 'l':
|
||||||
return type == "long"
|
return type == "long"
|
||||||
|| type == "long int"
|
|| type == "long int"
|
||||||
@@ -86,7 +91,12 @@ bool isIntType(const QString &type)
|
|||||||
|| type == "unsigned long"
|
|| type == "unsigned long"
|
||||||
|| type == "unsigned long int"
|
|| type == "unsigned long int"
|
||||||
|| type == "unsigned long long"
|
|| 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:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -718,10 +718,10 @@ static QString formattedValue(const WatchItem *item)
|
|||||||
|
|
||||||
// Append quoted, printable character also for decimal.
|
// Append quoted, printable character also for decimal.
|
||||||
// FIXME: This is unreliable.
|
// FIXME: This is unreliable.
|
||||||
if (item->type.endsWith("char")) {
|
if (item->type.endsWith("char") || item->type.endsWith("int8_t")) {
|
||||||
bool ok;
|
bool ok;
|
||||||
const int code = item->value.toInt(&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)
|
if (ok)
|
||||||
return reformatCharacter(code, 1, !isUnsigned);
|
return reformatCharacter(code, 1, !isUnsigned);
|
||||||
} else if (item->type.endsWith("wchar_t")) {
|
} else if (item->type.endsWith("wchar_t")) {
|
||||||
|
@@ -59,12 +59,12 @@
|
|||||||
#include "fakevimtr.h"
|
#include "fakevimtr.h"
|
||||||
|
|
||||||
#include <utils/optional.h>
|
#include <utils/optional.h>
|
||||||
|
#include <utils/qtcprocess.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QProcess>
|
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
@@ -866,17 +866,10 @@ static QString fromLocalEncoding(const QByteArray &data)
|
|||||||
|
|
||||||
static QString getProcessOutput(const QString &command, const QString &input)
|
static QString getProcessOutput(const QString &command, const QString &input)
|
||||||
{
|
{
|
||||||
QProcess proc;
|
Utils::QtcProcess proc;
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5,15,0)
|
proc.setCommand(Utils::CommandLine::fromUserInput(command));
|
||||||
QStringList arguments = QProcess::splitCommand(command);
|
proc.setWriteData(toLocalEncoding(input));
|
||||||
QString executable = arguments.takeFirst();
|
proc.start();
|
||||||
proc.start(executable, arguments);
|
|
||||||
#else
|
|
||||||
proc.start(command);
|
|
||||||
#endif
|
|
||||||
proc.waitForStarted();
|
|
||||||
proc.write(toLocalEncoding(input));
|
|
||||||
proc.closeWriteChannel();
|
|
||||||
|
|
||||||
// FIXME: Process should be interruptable by user.
|
// FIXME: Process should be interruptable by user.
|
||||||
// Solution is to create a QObject for each process and emit finished state.
|
// Solution is to create a QObject for each process and emit finished state.
|
||||||
|
@@ -412,12 +412,20 @@ void SemanticTokenSupport::handleSemanticTokensDelta(
|
|||||||
|
|
||||||
auto it = data.begin();
|
auto it = data.begin();
|
||||||
const auto end = data.end();
|
const auto end = data.end();
|
||||||
|
qCDebug(LOGLSPHIGHLIGHT) << "Edit Tokens for " << filePath;
|
||||||
|
qCDebug(LOGLSPHIGHLIGHT) << "Data before edit " << data;
|
||||||
for (const SemanticTokensEdit &edit : qAsConst(edits)) {
|
for (const SemanticTokensEdit &edit : qAsConst(edits)) {
|
||||||
if (edit.start() > data.size()) // prevent edits after the previously reported data
|
if (edit.start() > data.size()) // prevent edits after the previously reported data
|
||||||
return;
|
return;
|
||||||
for (const auto start = data.begin() + edit.start(); it < start; ++it)
|
for (const auto start = data.begin() + edit.start(); it < start; ++it)
|
||||||
newData.append(*it);
|
newData.append(*it);
|
||||||
newData.append(edit.data().value_or(QList<int>()));
|
const Utils::optional<QList<int>> 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();
|
int deleteCount = edit.deleteCount();
|
||||||
if (deleteCount > std::distance(it, end)) {
|
if (deleteCount > std::distance(it, end)) {
|
||||||
qCDebug(LOGLSPHIGHLIGHT)
|
qCDebug(LOGLSPHIGHLIGHT)
|
||||||
@@ -434,6 +442,7 @@ void SemanticTokenSupport::handleSemanticTokensDelta(
|
|||||||
for (; it != end; ++it)
|
for (; it != end; ++it)
|
||||||
newData.append(*it);
|
newData.append(*it);
|
||||||
|
|
||||||
|
qCDebug(LOGLSPHIGHLIGHT) << "New Data " << newData;
|
||||||
tokens.setData(newData);
|
tokens.setData(newData);
|
||||||
tokens.setResultId(tokensDelta->resultId());
|
tokens.setResultId(tokensDelta->resultId());
|
||||||
} else {
|
} else {
|
||||||
@@ -478,6 +487,14 @@ void SemanticTokenSupport::highlight(const Utils::FilePath &filePath)
|
|||||||
expandedToken.length = token.length;
|
expandedToken.length = token.length;
|
||||||
expandedTokens << expandedToken;
|
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);
|
m_tokensHandler(doc, expandedTokens, versionedTokens.version);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@@ -134,7 +134,6 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
modelnodeoperations.cpp modelnodeoperations.h
|
modelnodeoperations.cpp modelnodeoperations.h
|
||||||
formatoperation.cpp formatoperation.h
|
formatoperation.cpp formatoperation.h
|
||||||
navigation2d.cpp navigation2d.h
|
navigation2d.cpp navigation2d.h
|
||||||
gestures.cpp gestures.h
|
|
||||||
qmldesignericonprovider.cpp qmldesignericonprovider.h
|
qmldesignericonprovider.cpp qmldesignericonprovider.h
|
||||||
selectioncontext.cpp selectioncontext.h
|
selectioncontext.cpp selectioncontext.h
|
||||||
theme.cpp theme.h
|
theme.cpp theme.h
|
||||||
|
@@ -5,7 +5,6 @@ SOURCES += addimagesdialog.cpp
|
|||||||
SOURCES += changestyleaction.cpp
|
SOURCES += changestyleaction.cpp
|
||||||
SOURCES += theme.cpp
|
SOURCES += theme.cpp
|
||||||
SOURCES += findimplementation.cpp
|
SOURCES += findimplementation.cpp
|
||||||
SOURCES += gestures.cpp
|
|
||||||
SOURCES += addsignalhandlerdialog.cpp
|
SOURCES += addsignalhandlerdialog.cpp
|
||||||
SOURCES += layoutingridlayout.cpp
|
SOURCES += layoutingridlayout.cpp
|
||||||
SOURCES += abstractactiongroup.cpp
|
SOURCES += abstractactiongroup.cpp
|
||||||
@@ -27,7 +26,6 @@ HEADERS += addimagesdialog.h
|
|||||||
HEADERS += changestyleaction.h
|
HEADERS += changestyleaction.h
|
||||||
HEADERS += theme.h
|
HEADERS += theme.h
|
||||||
HEADERS += findimplementation.h
|
HEADERS += findimplementation.h
|
||||||
HEADERS += gestures.h
|
|
||||||
HEADERS += addsignalhandlerdialog.h
|
HEADERS += addsignalhandlerdialog.h
|
||||||
HEADERS += layoutingridlayout.h
|
HEADERS += layoutingridlayout.h
|
||||||
HEADERS += abstractactiongroup.h
|
HEADERS += abstractactiongroup.h
|
||||||
|
@@ -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 <QWidget>
|
|
||||||
|
|
||||||
namespace QmlDesigner {
|
|
||||||
|
|
||||||
Qt::GestureType TwoFingerSwipe::m_type = static_cast<Qt::GestureType>(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<QWidget *>(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<TwoFingerSwipe *>(gesture);
|
|
||||||
QTouchEvent *touch = static_cast<QTouchEvent *>(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<TwoFingerSwipe *>(gesture);
|
|
||||||
swipe->reset();
|
|
||||||
}
|
|
||||||
QGestureRecognizer::reset(gesture);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // End namespace QmlDesigner.
|
|
@@ -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 <QGesture>
|
|
||||||
#include <QGestureRecognizer>
|
|
||||||
#include <QLineF>
|
|
||||||
|
|
||||||
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
|
|
@@ -23,44 +23,38 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include "navigation2d.h"
|
#include "navigation2d.h"
|
||||||
#include "gestures.h"
|
|
||||||
|
|
||||||
#include <QGestureEvent>
|
#include <QGestureEvent>
|
||||||
|
#include <QScrollBar>
|
||||||
#include <QWheelEvent>
|
#include <QWheelEvent>
|
||||||
|
#include <QMetaMethod>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
Navigation2dScrollBar::Navigation2dScrollBar(QWidget *parent)
|
void Navigation2dFilter::scroll(const QPointF &direction, QScrollBar *sbx, QScrollBar *sby)
|
||||||
: QScrollBar(parent)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool Navigation2dScrollBar::postEvent(QEvent *event)
|
|
||||||
{
|
{
|
||||||
if (event->type() == QEvent::Wheel) {
|
auto doScroll = [](QScrollBar *sb, float distance) {
|
||||||
wheelEvent(static_cast<QWheelEvent *>(event));
|
if (sb) {
|
||||||
return true;
|
// max - min + pageStep = sceneRect.size * scale
|
||||||
}
|
float d1 = sb->maximum() - sb->minimum();
|
||||||
return false;
|
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)
|
Navigation2dFilter::Navigation2dFilter(QWidget *parent)
|
||||||
{
|
|
||||||
if (!event->angleDelta().isNull())
|
|
||||||
QScrollBar::wheelEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Navigation2dFilter::Navigation2dFilter(QWidget *parent, Navigation2dScrollBar *scrollbar)
|
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_scrollbar(scrollbar)
|
|
||||||
{
|
{
|
||||||
if (parent) {
|
if (parent)
|
||||||
parent->grabGesture(Qt::PinchGesture);
|
parent->grabGesture(Qt::PinchGesture);
|
||||||
if (!scrollbar)
|
|
||||||
parent->grabGesture(TwoFingerSwipe::type());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Navigation2dFilter::eventFilter(QObject *object, QEvent *event)
|
bool Navigation2dFilter::eventFilter(QObject *object, QEvent *event)
|
||||||
@@ -82,34 +76,39 @@ bool Navigation2dFilter::gestureEvent(QGestureEvent *event)
|
|||||||
event->accept();
|
event->accept();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (TwoFingerSwipe *swipe = static_cast<TwoFingerSwipe *>(
|
|
||||||
event->gesture(TwoFingerSwipe::type()))) {
|
|
||||||
emit panChanged(swipe->direction());
|
|
||||||
event->accept();
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Navigation2dFilter::wheelEvent(QWheelEvent *event)
|
bool Navigation2dFilter::wheelEvent(QWheelEvent *event)
|
||||||
{
|
{
|
||||||
if (m_scrollbar) {
|
if (event->source() == Qt::MouseEventSynthesizedBySystem) {
|
||||||
if (m_scrollbar->postEvent(event))
|
emit panChanged(QPointF(event->pixelDelta()));
|
||||||
event->ignore();
|
event->accept();
|
||||||
|
return true;
|
||||||
} else if (event->source() == Qt::MouseEventNotSynthesized) {
|
} else if (event->source() == Qt::MouseEventNotSynthesized) {
|
||||||
if (event->modifiers().testFlag(Qt::ControlModifier)) {
|
|
||||||
if (QPointF angle = event->angleDelta(); !angle.isNull()) {
|
auto zoomInSignal = QMetaMethod::fromSignal(&Navigation2dFilter::zoomIn);
|
||||||
double delta = std::abs(angle.x()) > std::abs(angle.y()) ? angle.x() : angle.y();
|
bool zoomInConnected = QObject::isSignalConnected(zoomInSignal);
|
||||||
if (delta > 0)
|
|
||||||
emit zoomIn();
|
auto zoomOutSignal = QMetaMethod::fromSignal(&Navigation2dFilter::zoomOut);
|
||||||
else
|
bool zoomOutConnected = QObject::isSignalConnected(zoomOutSignal);
|
||||||
emit zoomOut();
|
|
||||||
event->accept();
|
if (zoomInConnected && zoomOutConnected) {
|
||||||
return true;
|
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.
|
} // End namespace QmlDesigner.
|
||||||
|
@@ -24,27 +24,14 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QScrollBar>
|
#include <QObject>
|
||||||
|
|
||||||
QT_FORWARD_DECLARE_CLASS(QGestureEvent)
|
QT_FORWARD_DECLARE_CLASS(QGestureEvent)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QScrollBar)
|
||||||
QT_FORWARD_DECLARE_CLASS(QWheelEvent)
|
QT_FORWARD_DECLARE_CLASS(QWheelEvent)
|
||||||
|
|
||||||
namespace QmlDesigner {
|
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
|
class Navigation2dFilter : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -57,7 +44,9 @@ signals:
|
|||||||
void zoomOut();
|
void zoomOut();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Navigation2dFilter(QWidget *parent = nullptr, Navigation2dScrollBar *scrollbar = nullptr);
|
static void scroll(const QPointF &direction, QScrollBar *sbx, QScrollBar *sby);
|
||||||
|
|
||||||
|
Navigation2dFilter(QWidget *parent);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *obj, QEvent *event) override;
|
bool eventFilter(QObject *obj, QEvent *event) override;
|
||||||
@@ -65,7 +54,6 @@ protected:
|
|||||||
private:
|
private:
|
||||||
bool gestureEvent(QGestureEvent *event);
|
bool gestureEvent(QGestureEvent *event);
|
||||||
bool wheelEvent(QWheelEvent *event);
|
bool wheelEvent(QWheelEvent *event);
|
||||||
Navigation2dScrollBar *m_scrollbar = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
#include <QDoubleSpinBox>
|
#include <QDoubleSpinBox>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
#include <QScrollArea>
|
||||||
#include <QSplitter>
|
#include <QSplitter>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
@@ -40,16 +41,20 @@ namespace QmlDesigner {
|
|||||||
CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent)
|
CurveEditor::CurveEditor(CurveEditorModel *model, QWidget *parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
, m_tree(new TreeView(model, this))
|
, m_tree(new TreeView(model, this))
|
||||||
, m_view(new GraphicsView(model))
|
, m_view(new GraphicsView(model, this))
|
||||||
{
|
{
|
||||||
auto *splitter = new QSplitter;
|
auto *splitter = new QSplitter;
|
||||||
splitter->addWidget(m_tree);
|
splitter->addWidget(m_tree);
|
||||||
splitter->addWidget(m_view);
|
splitter->addWidget(m_view);
|
||||||
splitter->setStretchFactor(1, 2);
|
splitter->setStretchFactor(1, 2);
|
||||||
|
|
||||||
|
QScrollArea* area = new QScrollArea;
|
||||||
|
area->setWidget(splitter);
|
||||||
|
area->setWidgetResizable(true);
|
||||||
|
|
||||||
auto *box = new QVBoxLayout;
|
auto *box = new QVBoxLayout;
|
||||||
box->addWidget(createToolBar(model));
|
box->addWidget(createToolBar(model));
|
||||||
box->addWidget(splitter);
|
box->addWidget(area);
|
||||||
setLayout(box);
|
setLayout(box);
|
||||||
|
|
||||||
connect(m_tree, &TreeView::treeItemLocked, model, &CurveEditorModel::setLocked);
|
connect(m_tree, &TreeView::treeItemLocked, model, &CurveEditorModel::setLocked);
|
||||||
|
@@ -45,6 +45,18 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
template< typename T >
|
||||||
|
T* nextParentOfType(QWidget* widget)
|
||||||
|
{
|
||||||
|
auto* p = widget->parent();
|
||||||
|
while (p) {
|
||||||
|
if (T* w = qobject_cast<T*>(p))
|
||||||
|
return w;
|
||||||
|
p = p->parent();
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent)
|
GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent)
|
||||||
: QGraphicsView(parent)
|
: QGraphicsView(parent)
|
||||||
, m_dragging(false)
|
, m_dragging(false)
|
||||||
@@ -65,7 +77,7 @@ GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent)
|
|||||||
setResizeAnchor(QGraphicsView::NoAnchor);
|
setResizeAnchor(QGraphicsView::NoAnchor);
|
||||||
setRenderHint(QPainter::Antialiasing, true);
|
setRenderHint(QPainter::Antialiasing, true);
|
||||||
setTransformationAnchor(QGraphicsView::NoAnchor);
|
setTransformationAnchor(QGraphicsView::NoAnchor);
|
||||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||||
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
|
setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
|
||||||
|
|
||||||
@@ -78,12 +90,19 @@ GraphicsView::GraphicsView(CurveEditorModel *model, QWidget *parent)
|
|||||||
|
|
||||||
connect(m_scene, &GraphicsScene::curveChanged, itemSlot);
|
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;
|
auto zoomChanged = &QmlDesigner::Navigation2dFilter::zoomChanged;
|
||||||
connect(filter, zoomChanged, [this](double scale, const QPointF &pos) {
|
connect(filter, zoomChanged, [this](double scale, const QPointF &pos) {
|
||||||
applyZoom(m_zoomX + scale, m_zoomY, mapToGlobal(pos.toPoint()));
|
applyZoom(m_zoomX + scale, m_zoomY, mapToGlobal(pos.toPoint()));
|
||||||
});
|
});
|
||||||
installEventFilter(filter);
|
viewport()->installEventFilter(filter);
|
||||||
|
|
||||||
applyZoom(m_zoomX, m_zoomY);
|
applyZoom(m_zoomX, m_zoomY);
|
||||||
update();
|
update();
|
||||||
|
@@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
#include <nodeinstanceview.h>
|
#include <nodeinstanceview.h>
|
||||||
#include <designeractionmanager.h>
|
#include <designeractionmanager.h>
|
||||||
#include <qmldesignerplugin.h>
|
|
||||||
#include <designersettings.h>
|
#include <designersettings.h>
|
||||||
#include <qmldesignerconstants.h>
|
#include <qmldesignerconstants.h>
|
||||||
#include <viewmanager.h>
|
#include <viewmanager.h>
|
||||||
@@ -324,10 +323,6 @@ void Edit3DView::addQuick3DImport()
|
|||||||
} else {
|
} else {
|
||||||
model()->changeImports({import}, {});
|
model()->changeImports({import}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subcomponent manager update needed to make item library entries appear
|
|
||||||
QmlDesignerPlugin::instance()->currentDesignDocument()
|
|
||||||
->updateSubcomponentManagerImport(import);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -177,18 +177,22 @@ void Edit3DWidget::dropEvent(QDropEvent *dropEvent)
|
|||||||
->viewManager().designerActionManager();
|
->viewManager().designerActionManager();
|
||||||
QHash<QString, QStringList> addedAssets = actionManager.handleExternalAssetsDrop(dropEvent->mimeData());
|
QHash<QString, QStringList> addedAssets = actionManager.handleExternalAssetsDrop(dropEvent->mimeData());
|
||||||
|
|
||||||
// add 3D assets to 3d editor (QtQuick3D import will be added if missing)
|
view()->executeInTransaction("Edit3DWidget::dropEvent", [&] {
|
||||||
ItemLibraryInfo *itemLibInfo = m_view->model()->metaInfo().itemLibraryInfo();
|
// 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);
|
const QStringList added3DAssets = addedAssets.value(ComponentCoreConstants::add3DAssetsDisplayString);
|
||||||
for (const QString &assetPath : added3DAssets) {
|
for (const QString &assetPath : added3DAssets) {
|
||||||
QString fileName = QFileInfo(assetPath).baseName();
|
QString fileName = QFileInfo(assetPath).baseName();
|
||||||
fileName = fileName.at(0).toUpper() + fileName.mid(1); // capitalize first letter
|
fileName = fileName.at(0).toUpper() + fileName.mid(1); // capitalize first letter
|
||||||
QString type = QString("Quick3DAssets.%1.%1").arg(fileName);
|
QString type = QString("Quick3DAssets.%1.%1").arg(fileName);
|
||||||
QList<ItemLibraryEntry> entriesForType = itemLibInfo->entriesForType(type.toLatin1());
|
QList<ItemLibraryEntry> entriesForType = itemLibInfo->entriesForType(type.toLatin1());
|
||||||
if (!entriesForType.isEmpty()) // should always be true, but just in case
|
if (!entriesForType.isEmpty()) { // should always be true, but just in case
|
||||||
QmlVisualNode::createQml3DNode(view(), entriesForType.at(0), m_canvas->activeScene()).modelNode();
|
QmlVisualNode::createQml3DNode(view(), entriesForType.at(0),
|
||||||
}
|
m_canvas->activeScene(), {}, false).modelNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -62,28 +62,12 @@ FormEditorGraphicsView::FormEditorGraphicsView(QWidget *parent)
|
|||||||
// eventFilter method so it works also for the space scrolling case as expected
|
// eventFilter method so it works also for the space scrolling case as expected
|
||||||
QCoreApplication::instance()->installEventFilter(this);
|
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::zoomIn, this, &FormEditorGraphicsView::zoomIn);
|
||||||
connect(filter, &Navigation2dFilter::zoomOut, this, &FormEditorGraphicsView::zoomOut);
|
connect(filter, &Navigation2dFilter::zoomOut, this, &FormEditorGraphicsView::zoomOut);
|
||||||
|
|
||||||
auto panChanged = &Navigation2dFilter::panChanged;
|
connect(filter, &Navigation2dFilter::panChanged, [this](const QPointF &direction) {
|
||||||
connect(filter, panChanged, [this](const QPointF &direction) {
|
Navigation2dFilter::scroll(direction, horizontalScrollBar(), verticalScrollBar());
|
||||||
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());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
auto zoomChanged = &Navigation2dFilter::zoomChanged;
|
auto zoomChanged = &Navigation2dFilter::zoomChanged;
|
||||||
@@ -93,7 +77,7 @@ FormEditorGraphicsView::FormEditorGraphicsView(QWidget *parent)
|
|||||||
emit this->zoomChanged(transform().m11());
|
emit this->zoomChanged(transform().m11());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
installEventFilter(filter);
|
viewport()->installEventFilter(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FormEditorGraphicsView::eventFilter(QObject *watched, QEvent *event)
|
bool FormEditorGraphicsView::eventFilter(QObject *watched, QEvent *event)
|
||||||
@@ -123,8 +107,8 @@ void FormEditorGraphicsView::wheelEvent(QWheelEvent *event)
|
|||||||
{
|
{
|
||||||
if (event->modifiers().testFlag(Qt::ControlModifier))
|
if (event->modifiers().testFlag(Qt::ControlModifier))
|
||||||
event->ignore();
|
event->ignore();
|
||||||
else if (event->source() == Qt::MouseEventNotSynthesized)
|
|
||||||
QGraphicsView::wheelEvent(event);
|
QGraphicsView::wheelEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FormEditorGraphicsView::mousePressEvent(QMouseEvent *event)
|
void FormEditorGraphicsView::mousePressEvent(QMouseEvent *event)
|
||||||
|
@@ -599,20 +599,24 @@ void FormEditorWidget::dropEvent(QDropEvent *dropEvent)
|
|||||||
->viewManager().designerActionManager();
|
->viewManager().designerActionManager();
|
||||||
QHash<QString, QStringList> addedAssets = actionManager.handleExternalAssetsDrop(dropEvent->mimeData());
|
QHash<QString, QStringList> addedAssets = actionManager.handleExternalAssetsDrop(dropEvent->mimeData());
|
||||||
|
|
||||||
// Create Image components for added image assets
|
m_formEditorView->executeInTransaction("FormEditorWidget::dropEvent", [&] {
|
||||||
const QStringList addedImages = addedAssets.value(ComponentCoreConstants::addImagesDisplayString);
|
// Create Image components for added image assets
|
||||||
for (const QString &imgPath : addedImages) {
|
const QStringList addedImages = addedAssets.value(ComponentCoreConstants::addImagesDisplayString);
|
||||||
QmlItemNode::createQmlItemNodeFromImage(m_formEditorView, imgPath, {},
|
for (const QString &imgPath : addedImages) {
|
||||||
m_formEditorView->scene()->rootFormEditorItem()->qmlItemNode());
|
QmlItemNode::createQmlItemNodeFromImage(m_formEditorView, imgPath, {},
|
||||||
}
|
m_formEditorView->scene()->rootFormEditorItem()->qmlItemNode(),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
// Create Text components for added font assets
|
// Create Text components for added font assets
|
||||||
const QStringList addedFonts = addedAssets.value(ComponentCoreConstants::addFontsDisplayString);
|
const QStringList addedFonts = addedAssets.value(ComponentCoreConstants::addFontsDisplayString);
|
||||||
for (const QString &fontPath : addedFonts) {
|
for (const QString &fontPath : addedFonts) {
|
||||||
QString fontFamily = QFileInfo(fontPath).baseName();
|
QString fontFamily = QFileInfo(fontPath).baseName();
|
||||||
QmlItemNode::createQmlItemNodeFromFont(m_formEditorView, fontFamily, rootItemRect().center(),
|
QmlItemNode::createQmlItemNodeFromFont(m_formEditorView, fontFamily, rootItemRect().center(),
|
||||||
m_formEditorView->scene()->rootFormEditorItem()->qmlItemNode());
|
m_formEditorView->scene()->rootFormEditorItem()->qmlItemNode(),
|
||||||
}
|
false);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -388,9 +388,9 @@ void DesignDocument::updateSubcomponentManager()
|
|||||||
currentModel()->imports() + currentModel()->possibleImports());
|
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()
|
void DesignDocument::deleteSelected()
|
||||||
|
@@ -69,7 +69,7 @@ public:
|
|||||||
void attachRewriterToModel();
|
void attachRewriterToModel();
|
||||||
void close();
|
void close();
|
||||||
void updateSubcomponentManager();
|
void updateSubcomponentManager();
|
||||||
void updateSubcomponentManagerImport(const Import &import);
|
void addSubcomponentManagerImport(const Import &import);
|
||||||
|
|
||||||
bool isUndoAvailable() const;
|
bool isUndoAvailable() const;
|
||||||
bool isRedoAvailable() const;
|
bool isRedoAvailable() const;
|
||||||
|
@@ -686,8 +686,6 @@ void ItemLibraryAssetImporter::finalizeQuick3DImport()
|
|||||||
|
|
||||||
model->changeImports(newImportsToAdd, {});
|
model->changeImports(newImportsToAdd, {});
|
||||||
transaction.commit();
|
transaction.commit();
|
||||||
for (const Import &import : qAsConst(newImportsToAdd))
|
|
||||||
doc->updateSubcomponentManagerImport(import);
|
|
||||||
}
|
}
|
||||||
} catch (const RewritingException &e) {
|
} catch (const RewritingException &e) {
|
||||||
addError(tr("Failed to update imports: %1").arg(e.description()));
|
addError(tr("Failed to update imports: %1").arg(e.description()));
|
||||||
|
@@ -132,6 +132,10 @@ void ItemLibraryView::modelAboutToBeDetached(Model *model)
|
|||||||
|
|
||||||
void ItemLibraryView::importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports)
|
void ItemLibraryView::importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports)
|
||||||
{
|
{
|
||||||
|
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||||
|
for (const auto &import : addedImports)
|
||||||
|
document->addSubcomponentManagerImport(import);
|
||||||
|
|
||||||
updateImports();
|
updateImports();
|
||||||
|
|
||||||
// TODO: generalize the logic below to allow adding/removing any Qml component when its import is added/removed
|
// 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<Import> &addedImports, const QL
|
|||||||
|
|
||||||
void ItemLibraryView::possibleImportsChanged(const QList<Import> &possibleImports)
|
void ItemLibraryView::possibleImportsChanged(const QList<Import> &possibleImports)
|
||||||
{
|
{
|
||||||
|
DesignDocument *document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||||
|
for (const auto &import : possibleImports)
|
||||||
|
document->addSubcomponentManagerImport(import);
|
||||||
|
|
||||||
m_widget->updatePossibleImports(possibleImports);
|
m_widget->updatePossibleImports(possibleImports);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -357,7 +357,6 @@ void ItemLibraryWidget::handleAddImport(int index)
|
|||||||
|
|
||||||
auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
|
||||||
document->documentModel()->changeImports({import}, {});
|
document->documentModel()->changeImports({import}, {});
|
||||||
document->updateSubcomponentManagerImport(import);
|
|
||||||
|
|
||||||
m_stackedWidget->setCurrentIndex(0); // switch to the Components view after import is added
|
m_stackedWidget->setCurrentIndex(0); // switch to the Components view after import is added
|
||||||
updateSearch();
|
updateSearch();
|
||||||
|
@@ -316,7 +316,12 @@ QList<ModelNode> filteredList(const NodeListProperty &property, bool filter, boo
|
|||||||
|
|
||||||
if (filter) {
|
if (filter) {
|
||||||
list.append(Utils::filtered(property.toModelNodeList(), [] (const ModelNode &arg) {
|
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 {
|
} else {
|
||||||
list = property.toModelNodeList();
|
list = property.toModelNodeList();
|
||||||
@@ -879,7 +884,6 @@ void NavigatorTreeModel::addImport(const QString &importName)
|
|||||||
if (possImport.url() == import.url()) {
|
if (possImport.url() == import.url()) {
|
||||||
import = possImport;
|
import = possImport;
|
||||||
m_view->model()->changeImports({import}, {});
|
m_view->model()->changeImports({import}, {});
|
||||||
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManagerImport(import);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -118,7 +118,7 @@ TimelineWidget::TimelineWidget(TimelineView *view)
|
|||||||
, m_toolbar(new TimelineToolBar(this))
|
, m_toolbar(new TimelineToolBar(this))
|
||||||
, m_rulerView(new QGraphicsView(this))
|
, m_rulerView(new QGraphicsView(this))
|
||||||
, m_graphicsView(new QGraphicsView(this))
|
, m_graphicsView(new QGraphicsView(this))
|
||||||
, m_scrollbar(new Navigation2dScrollBar(this))
|
, m_scrollbar(new QScrollBar(this))
|
||||||
, m_statusBar(new QLabel(this))
|
, m_statusBar(new QLabel(this))
|
||||||
, m_timelineView(view)
|
, m_timelineView(view)
|
||||||
, m_graphicsScene(new TimelineGraphicsScene(this))
|
, m_graphicsScene(new TimelineGraphicsScene(this))
|
||||||
@@ -160,7 +160,6 @@ TimelineWidget::TimelineWidget(TimelineView *view)
|
|||||||
m_graphicsView->setFrameShape(QFrame::NoFrame);
|
m_graphicsView->setFrameShape(QFrame::NoFrame);
|
||||||
m_graphicsView->setFrameShadow(QFrame::Plain);
|
m_graphicsView->setFrameShadow(QFrame::Plain);
|
||||||
m_graphicsView->setLineWidth(0);
|
m_graphicsView->setLineWidth(0);
|
||||||
m_graphicsView->setVerticalScrollBar(new Navigation2dScrollBar);
|
|
||||||
m_graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
m_graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||||
m_graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
m_graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
|
||||||
@@ -274,13 +273,19 @@ TimelineWidget::TimelineWidget(TimelineView *view)
|
|||||||
m_timelineView->addNewTimelineDialog();
|
m_timelineView->addNewTimelineDialog();
|
||||||
});
|
});
|
||||||
|
|
||||||
Navigation2dFilter *filter = new Navigation2dFilter(this, m_scrollbar);
|
Navigation2dFilter *filter = new Navigation2dFilter(m_graphicsView->viewport());
|
||||||
connect(filter, &Navigation2dFilter::zoomChanged, [this](double scale, const QPointF& pos) {
|
connect(filter, &Navigation2dFilter::panChanged, [this](const QPointF &direction) {
|
||||||
int s = static_cast<int>(std::round(scale*100.));
|
Navigation2dFilter::scroll(direction, m_scrollbar, m_graphicsView->verticalScrollBar());
|
||||||
double ps = m_graphicsScene->mapFromScene(pos.x());
|
|
||||||
m_graphicsScene->setZoom(std::clamp(m_graphicsScene->zoom() + s, 0, 100), ps);
|
|
||||||
});
|
});
|
||||||
installEventFilter(filter);
|
|
||||||
|
connect(filter, &Navigation2dFilter::zoomChanged, [this](double scale, const QPointF &pos) {
|
||||||
|
int s = static_cast<int>(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();
|
m_playbackAnimation->stop();
|
||||||
auto playAnimation = [this](QVariant frame) { graphicsScene()->setCurrentFrame(qRound(frame.toDouble())); };
|
auto playAnimation = [this](QVariant frame) { graphicsScene()->setCurrentFrame(qRound(frame.toDouble())); };
|
||||||
|
@@ -40,6 +40,7 @@ QT_FORWARD_DECLARE_CLASS(QShowEvent)
|
|||||||
QT_FORWARD_DECLARE_CLASS(QString)
|
QT_FORWARD_DECLARE_CLASS(QString)
|
||||||
QT_FORWARD_DECLARE_CLASS(QPushButton)
|
QT_FORWARD_DECLARE_CLASS(QPushButton)
|
||||||
QT_FORWARD_DECLARE_CLASS(QVariantAnimation)
|
QT_FORWARD_DECLARE_CLASS(QVariantAnimation)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QScrollBar)
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
@@ -97,7 +98,7 @@ private:
|
|||||||
|
|
||||||
QGraphicsView *m_graphicsView = nullptr;
|
QGraphicsView *m_graphicsView = nullptr;
|
||||||
|
|
||||||
Navigation2dScrollBar *m_scrollbar = nullptr;
|
QScrollBar *m_scrollbar = nullptr;
|
||||||
|
|
||||||
QLabel *m_statusBar = nullptr;
|
QLabel *m_statusBar = nullptr;
|
||||||
|
|
||||||
|
@@ -90,7 +90,7 @@ TransitionEditorWidget::TransitionEditorWidget(TransitionEditorView *view)
|
|||||||
, m_toolbar(new TransitionEditorToolBar(this))
|
, m_toolbar(new TransitionEditorToolBar(this))
|
||||||
, m_rulerView(new QGraphicsView(this))
|
, m_rulerView(new QGraphicsView(this))
|
||||||
, m_graphicsView(new QGraphicsView(this))
|
, m_graphicsView(new QGraphicsView(this))
|
||||||
, m_scrollbar(new Navigation2dScrollBar(this))
|
, m_scrollbar(new QScrollBar(this))
|
||||||
, m_statusBar(new QLabel(this))
|
, m_statusBar(new QLabel(this))
|
||||||
, m_transitionEditorView(view)
|
, m_transitionEditorView(view)
|
||||||
, m_graphicsScene(new TransitionEditorGraphicsScene(this))
|
, m_graphicsScene(new TransitionEditorGraphicsScene(this))
|
||||||
@@ -129,7 +129,6 @@ TransitionEditorWidget::TransitionEditorWidget(TransitionEditorView *view)
|
|||||||
m_graphicsView->setFrameShape(QFrame::NoFrame);
|
m_graphicsView->setFrameShape(QFrame::NoFrame);
|
||||||
m_graphicsView->setFrameShadow(QFrame::Plain);
|
m_graphicsView->setFrameShadow(QFrame::Plain);
|
||||||
m_graphicsView->setLineWidth(0);
|
m_graphicsView->setLineWidth(0);
|
||||||
m_graphicsView->setVerticalScrollBar(new Navigation2dScrollBar);
|
|
||||||
m_graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
m_graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||||
m_graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
m_graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
|
||||||
@@ -223,13 +222,19 @@ TransitionEditorWidget::TransitionEditorWidget(TransitionEditorView *view)
|
|||||||
m_transitionEditorView->addNewTransition();
|
m_transitionEditorView->addNewTransition();
|
||||||
});
|
});
|
||||||
|
|
||||||
Navigation2dFilter *filter = new Navigation2dFilter(this, m_scrollbar);
|
Navigation2dFilter *filter = new Navigation2dFilter(m_graphicsView->viewport());
|
||||||
connect(filter, &Navigation2dFilter::zoomChanged, [this](double scale, const QPointF& pos) {
|
connect(filter, &Navigation2dFilter::panChanged, [this](const QPointF &direction) {
|
||||||
int s = static_cast<int>(std::round(scale*100.));
|
Navigation2dFilter::scroll(direction, m_scrollbar, m_graphicsView->verticalScrollBar());
|
||||||
double ps = m_graphicsScene->mapFromScene(pos.x());
|
|
||||||
m_graphicsScene->setZoom(std::clamp(m_graphicsScene->zoom() + s, 0, 100), ps);
|
|
||||||
});
|
});
|
||||||
installEventFilter(filter);
|
|
||||||
|
connect(filter, &Navigation2dFilter::zoomChanged, [this](double scale, const QPointF &pos) {
|
||||||
|
int s = static_cast<int>(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)
|
void TransitionEditorWidget::setTransitionActive(bool b)
|
||||||
|
@@ -40,6 +40,7 @@ QT_FORWARD_DECLARE_CLASS(QResizeEvent)
|
|||||||
QT_FORWARD_DECLARE_CLASS(QShowEvent)
|
QT_FORWARD_DECLARE_CLASS(QShowEvent)
|
||||||
QT_FORWARD_DECLARE_CLASS(QString)
|
QT_FORWARD_DECLARE_CLASS(QString)
|
||||||
QT_FORWARD_DECLARE_CLASS(QPushButton)
|
QT_FORWARD_DECLARE_CLASS(QPushButton)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QScrollBar)
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
@@ -47,7 +48,6 @@ class TransitionEditorView;
|
|||||||
class TransitionEditorToolBar;
|
class TransitionEditorToolBar;
|
||||||
class TransitionEditorGraphicsScene;
|
class TransitionEditorGraphicsScene;
|
||||||
class ModelNode;
|
class ModelNode;
|
||||||
class Navigation2dScrollBar;
|
|
||||||
|
|
||||||
class TransitionEditorWidget : public QWidget
|
class TransitionEditorWidget : public QWidget
|
||||||
{
|
{
|
||||||
@@ -88,7 +88,7 @@ private:
|
|||||||
|
|
||||||
QGraphicsView *m_graphicsView = nullptr;
|
QGraphicsView *m_graphicsView = nullptr;
|
||||||
|
|
||||||
Navigation2dScrollBar *m_scrollbar = nullptr;
|
QScrollBar *m_scrollbar = nullptr;
|
||||||
|
|
||||||
QLabel *m_statusBar = nullptr;
|
QLabel *m_statusBar = nullptr;
|
||||||
|
|
||||||
|
@@ -62,11 +62,14 @@ public:
|
|||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void handleOriginalTextChanged();
|
||||||
|
|
||||||
TextModifier *m_originalModifier;
|
TextModifier *m_originalModifier;
|
||||||
int m_componentStartOffset;
|
int m_componentStartOffset;
|
||||||
int m_componentEndOffset;
|
int m_componentEndOffset;
|
||||||
int m_rootStartOffset;
|
int m_rootStartOffset;
|
||||||
int m_startLength;
|
int m_startLength;
|
||||||
|
QString m_originalText;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -101,8 +101,9 @@ public:
|
|||||||
bool createInTransaction = true);
|
bool createInTransaction = true);
|
||||||
|
|
||||||
static QmlVisualNode createQml3DNode(AbstractView *view,
|
static QmlVisualNode createQml3DNode(AbstractView *view,
|
||||||
const ItemLibraryEntry &itemLibraryEntry,
|
const ItemLibraryEntry &itemLibraryEntry,
|
||||||
qint32 sceneRootId = -1, const QVector3D &position = {});
|
qint32 sceneRootId = -1, const QVector3D &position = {},
|
||||||
|
bool createInTransaction = true);
|
||||||
|
|
||||||
static NodeListProperty findSceneNodeProperty(AbstractView *view, qint32 sceneRootId);
|
static NodeListProperty findSceneNodeProperty(AbstractView *view, qint32 sceneRootId);
|
||||||
|
|
||||||
|
@@ -49,7 +49,7 @@ public:
|
|||||||
explicit SubComponentManager(Model *model, QObject *parent = nullptr);
|
explicit SubComponentManager(Model *model, QObject *parent = nullptr);
|
||||||
|
|
||||||
void update(const QUrl &fileUrl, const QList<Import> &imports);
|
void update(const QUrl &fileUrl, const QList<Import> &imports);
|
||||||
void updateImport(const Import &import);
|
void addAndParseImport(const Import &import);
|
||||||
|
|
||||||
QStringList qmlFiles() const;
|
QStringList qmlFiles() const;
|
||||||
QStringList directories() const;
|
QStringList directories() const;
|
||||||
@@ -59,7 +59,7 @@ private: // functions
|
|||||||
void parseFile(const QString &canonicalFilePath, bool addToLibrary, const QString&);
|
void parseFile(const QString &canonicalFilePath, bool addToLibrary, const QString&);
|
||||||
void parseFile(const QString &canonicalFilePath);
|
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 removeImport(int index);
|
||||||
void parseDirectories();
|
void parseDirectories();
|
||||||
QFileInfoList watchedFiles(const QString &canonicalDirPath);
|
QFileInfoList watchedFiles(const QString &canonicalDirPath);
|
||||||
|
@@ -69,16 +69,18 @@ SubComponentManager::SubComponentManager(Model *model, QObject *parent)
|
|||||||
this, [this](const QString &path) { parseDirectory(path); });
|
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)
|
if (debug)
|
||||||
qDebug() << Q_FUNC_INFO << index << import.file().toUtf8();
|
qDebug() << Q_FUNC_INFO << index << import.file().toUtf8();
|
||||||
|
|
||||||
|
bool importExists = false;
|
||||||
if (import.isFileImport()) {
|
if (import.isFileImport()) {
|
||||||
QFileInfo dirInfo = QFileInfo(m_filePath.resolved(import.file()).toLocalFile());
|
QFileInfo dirInfo = QFileInfo(m_filePath.resolved(import.file()).toLocalFile());
|
||||||
if (dirInfo.exists() && dirInfo.isDir()) {
|
if (dirInfo.exists() && dirInfo.isDir()) {
|
||||||
const QString canonicalDirPath = dirInfo.canonicalFilePath();
|
const QString canonicalDirPath = dirInfo.canonicalFilePath();
|
||||||
m_watcher.addPath(canonicalDirPath);
|
m_watcher.addPath(canonicalDirPath);
|
||||||
|
importExists = true;
|
||||||
//m_dirToQualifier.insertMulti(canonicalDirPath, import.qualifier()); ### todo: proper support for import as
|
//m_dirToQualifier.insertMulti(canonicalDirPath, import.qualifier()); ### todo: proper support for import as
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -91,16 +93,21 @@ void SubComponentManager::addImport(const Import &import, int index)
|
|||||||
if (dirInfo.exists() && dirInfo.isDir()) {
|
if (dirInfo.exists() && dirInfo.isDir()) {
|
||||||
const QString canonicalDirPath = dirInfo.canonicalFilePath();
|
const QString canonicalDirPath = dirInfo.canonicalFilePath();
|
||||||
m_watcher.addPath(canonicalDirPath);
|
m_watcher.addPath(canonicalDirPath);
|
||||||
|
importExists = true;
|
||||||
//m_dirToQualifier.insertMulti(canonicalDirPath, import.qualifier()); ### todo: proper support for import as
|
//m_dirToQualifier.insertMulti(canonicalDirPath, import.qualifier()); ### todo: proper support for import as
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// TODO: QDeclarativeDomImport::Library
|
// TODO: QDeclarativeDomImport::Library
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index == -1)
|
if (importExists) {
|
||||||
m_imports.append(import);
|
if (index == -1)
|
||||||
else
|
m_imports.append(import);
|
||||||
m_imports.insert(index, import);
|
else
|
||||||
|
m_imports.insert(index, import);
|
||||||
|
}
|
||||||
|
|
||||||
|
return importExists;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubComponentManager::removeImport(int index)
|
void SubComponentManager::removeImport(int index)
|
||||||
@@ -544,9 +551,15 @@ void SubComponentManager::update(const QUrl &filePath, const QList<Import> &impo
|
|||||||
parseDirectories();
|
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()) {
|
if (import.isFileImport()) {
|
||||||
QFileInfo dirInfo = QFileInfo(m_filePath.resolved(import.file()).toLocalFile());
|
QFileInfo dirInfo = QFileInfo(m_filePath.resolved(import.file()).toLocalFile());
|
||||||
|
@@ -33,10 +33,13 @@ ComponentTextModifier::ComponentTextModifier(TextModifier *originalModifier, int
|
|||||||
m_componentEndOffset(componentEndOffset),
|
m_componentEndOffset(componentEndOffset),
|
||||||
m_rootStartOffset(rootStartOffset)
|
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::replaced, this, &TextModifier::replaced);
|
||||||
connect(m_originalModifier, &TextModifier::moved, this, &TextModifier::moved);
|
connect(m_originalModifier, &TextModifier::moved, this, &TextModifier::moved);
|
||||||
|
|
||||||
|
m_originalText = m_originalModifier->text();
|
||||||
}
|
}
|
||||||
|
|
||||||
ComponentTextModifier::~ComponentTextModifier() = default;
|
ComponentTextModifier::~ComponentTextModifier() = default;
|
||||||
@@ -146,3 +149,45 @@ void ComponentTextModifier::reactivateChangeSignals()
|
|||||||
{
|
{
|
||||||
m_originalModifier->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();
|
||||||
|
}
|
||||||
|
@@ -74,8 +74,13 @@ void ModelToTextMerger::nodeRemoved(const ModelNode &removedNode, const NodeAbst
|
|||||||
void ModelToTextMerger::propertiesRemoved(const QList<AbstractProperty>& propertyList)
|
void ModelToTextMerger::propertiesRemoved(const QList<AbstractProperty>& propertyList)
|
||||||
{
|
{
|
||||||
foreach (const AbstractProperty &property, 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));
|
schedule(new RemovePropertyRewriteAction(property));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -174,7 +174,7 @@ QmlItemNode QmlItemNode::createQmlItemNodeFromFont(AbstractView *view,
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (executeInTransaction)
|
if (executeInTransaction)
|
||||||
view->executeInTransaction("QmlItemNode::createQmlItemNodeFromImage", doCreateQmlItemNodeFromFont);
|
view->executeInTransaction("QmlItemNode::createQmlItemNodeFromFont", doCreateQmlItemNodeFromFont);
|
||||||
else
|
else
|
||||||
doCreateQmlItemNodeFromFont();
|
doCreateQmlItemNodeFromFont();
|
||||||
|
|
||||||
|
@@ -365,14 +365,15 @@ QmlObjectNode QmlVisualNode::createQmlObjectNode(AbstractView *view,
|
|||||||
|
|
||||||
QmlVisualNode QmlVisualNode::createQml3DNode(AbstractView *view,
|
QmlVisualNode QmlVisualNode::createQml3DNode(AbstractView *view,
|
||||||
const ItemLibraryEntry &itemLibraryEntry,
|
const ItemLibraryEntry &itemLibraryEntry,
|
||||||
qint32 sceneRootId, const QVector3D &position)
|
qint32 sceneRootId, const QVector3D &position,
|
||||||
|
bool createInTransaction)
|
||||||
{
|
{
|
||||||
NodeAbstractProperty sceneNodeProperty = sceneRootId != -1 ? findSceneNodeProperty(view, sceneRootId)
|
NodeAbstractProperty sceneNodeProperty = sceneRootId != -1 ? findSceneNodeProperty(view, sceneRootId)
|
||||||
: view->rootModelNode().defaultNodeAbstractProperty();
|
: view->rootModelNode().defaultNodeAbstractProperty();
|
||||||
|
|
||||||
QTC_ASSERT(sceneNodeProperty.isValid(), return {});
|
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)
|
NodeListProperty QmlVisualNode::findSceneNodeProperty(AbstractView *view, qint32 sceneRootId)
|
||||||
|
@@ -173,14 +173,27 @@ void RewriterView::propertiesAboutToBeRemoved(const QList<AbstractProperty> &pro
|
|||||||
if (textToModelMerger()->isActive())
|
if (textToModelMerger()->isActive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
for (const AbstractProperty &property : propertyList) {
|
||||||
|
if (!property.isDefaultProperty())
|
||||||
|
continue;
|
||||||
|
|
||||||
foreach (const AbstractProperty &property, propertyList) {
|
if (!m_removeDefaultPropertyTransaction.isValid()) {
|
||||||
if (property.isDefaultProperty() && property.isNodeListProperty()) {
|
m_removeDefaultPropertyTransaction = beginRewriterTransaction(
|
||||||
m_removeDefaultPropertyTransaction = beginRewriterTransaction(QByteArrayLiteral("RewriterView::propertiesAboutToBeRemoved"));
|
QByteArrayLiteral("RewriterView::propertiesAboutToBeRemoved"));
|
||||||
|
}
|
||||||
|
|
||||||
foreach (const ModelNode &node, property.toNodeListProperty().toModelNodeList()) {
|
if (property.isNodeListProperty()) {
|
||||||
modelToTextMerger()->nodeRemoved(node, property.toNodeAbstractProperty(), AbstractView::NoAdditionalChanges);
|
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});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,7 +33,6 @@
|
|||||||
#include "generateresource.h"
|
#include "generateresource.h"
|
||||||
#include "generatecmakelists.h"
|
#include "generatecmakelists.h"
|
||||||
#include "nodeinstanceview.h"
|
#include "nodeinstanceview.h"
|
||||||
#include "gestures.h"
|
|
||||||
|
|
||||||
#include <metainfo.h>
|
#include <metainfo.h>
|
||||||
#include <connectionview.h>
|
#include <connectionview.h>
|
||||||
@@ -232,8 +231,6 @@ bool QmlDesignerPlugin::initialize(const QStringList & /*arguments*/, QString *e
|
|||||||
if (QFontDatabase::addApplicationFont(fontPath) < 0)
|
if (QFontDatabase::addApplicationFont(fontPath) < 0)
|
||||||
qCWarning(qmldesignerLog) << "Could not add font " << fontPath << "to font database";
|
qCWarning(qmldesignerLog) << "Could not add font " << fontPath << "to font database";
|
||||||
|
|
||||||
TwoFingerSwipe::registerRecognizer();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -461,8 +461,6 @@ Project {
|
|||||||
"componentcore/findimplementation.h",
|
"componentcore/findimplementation.h",
|
||||||
"componentcore/formatoperation.cpp",
|
"componentcore/formatoperation.cpp",
|
||||||
"componentcore/formatoperation.h",
|
"componentcore/formatoperation.h",
|
||||||
"componentcore/gestures.cpp",
|
|
||||||
"componentcore/gestures.h",
|
|
||||||
"componentcore/layoutingridlayout.cpp",
|
"componentcore/layoutingridlayout.cpp",
|
||||||
"componentcore/layoutingridlayout.h",
|
"componentcore/layoutingridlayout.h",
|
||||||
"componentcore/theme.cpp",
|
"componentcore/theme.cpp",
|
||||||
|
@@ -177,7 +177,7 @@ public:
|
|||||||
QtOptionsPageWidget();
|
QtOptionsPageWidget();
|
||||||
~QtOptionsPageWidget();
|
~QtOptionsPageWidget();
|
||||||
|
|
||||||
static void linkWithQt();
|
static bool linkWithQt();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void apply() final;
|
void apply() final;
|
||||||
@@ -857,7 +857,16 @@ void QtOptionsPageWidget::setupLinkWithQtButton()
|
|||||||
QString tip;
|
QString tip;
|
||||||
canLinkWithQt(&tip);
|
canLinkWithQt(&tip);
|
||||||
m_ui.linkWithQtButton->setToolTip(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<QDialog *>(w))
|
||||||
|
dialog->accept();
|
||||||
|
else
|
||||||
|
window()->close();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtOptionsPageWidget::updateCurrentQtName()
|
void QtOptionsPageWidget::updateCurrentQtName()
|
||||||
@@ -950,7 +959,7 @@ static FilePath defaultQtInstallationPath()
|
|||||||
return FileUtils::homePath() / "Qt";
|
return FileUtils::homePath() / "Qt";
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtOptionsPageWidget::linkWithQt()
|
bool QtOptionsPageWidget::linkWithQt()
|
||||||
{
|
{
|
||||||
const QString title = tr("Choose Qt Installation");
|
const QString title = tr("Choose Qt Installation");
|
||||||
const QString restartText = tr("The change will take effect after restart.");
|
const QString restartText = tr("The change will take effect after restart.");
|
||||||
@@ -1019,8 +1028,9 @@ void QtOptionsPageWidget::linkWithQt()
|
|||||||
}
|
}
|
||||||
if (askForRestart) {
|
if (askForRestart) {
|
||||||
Core::RestartDialog restartDialog(Core::ICore::dialogParent(), restartText);
|
Core::RestartDialog restartDialog(Core::ICore::dialogParent(), restartText);
|
||||||
restartDialog.exec();
|
return restartDialog.exec() == QDialog::Accepted;
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// QtOptionsPage
|
// QtOptionsPage
|
||||||
|
@@ -337,6 +337,7 @@ void CodeAssistantPrivate::displayProposal(IAssistProposal *newProposal, AssistR
|
|||||||
if (!newProposal->hasItemsToPropose(prefix, reason)) {
|
if (!newProposal->hasItemsToPropose(prefix, reason)) {
|
||||||
if (newProposal->isCorrective(m_editorWidget))
|
if (newProposal->isCorrective(m_editorWidget))
|
||||||
newProposal->makeCorrection(m_editorWidget);
|
newProposal->makeCorrection(m_editorWidget);
|
||||||
|
destroyContext();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -417,6 +417,10 @@ bool FontSettings::loadColorScheme(const QString &fileName,
|
|||||||
foreach (const FormatDescription &desc, descriptions) {
|
foreach (const FormatDescription &desc, descriptions) {
|
||||||
const TextStyle id = desc.id();
|
const TextStyle id = desc.id();
|
||||||
if (!m_scheme.contains(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;
|
Format format;
|
||||||
const Format &descFormat = desc.format();
|
const Format &descFormat = desc.format();
|
||||||
// Default fallback for background and foreground is C_TEXT, which is set through
|
// Default fallback for background and foreground is C_TEXT, which is set through
|
||||||
|
@@ -835,7 +835,7 @@ void TextDocument::cleanWhitespace(const QTextCursor &cursor)
|
|||||||
void TextDocument::cleanWhitespace(QTextCursor &cursor, bool inEntireDocument,
|
void TextDocument::cleanWhitespace(QTextCursor &cursor, bool inEntireDocument,
|
||||||
bool cleanIndentation)
|
bool cleanIndentation)
|
||||||
{
|
{
|
||||||
const QString fileName(filePath().fileName());
|
const bool removeTrailingWhitespace = d->m_storageSettings.removeTrailingWhitespace(filePath().fileName());
|
||||||
|
|
||||||
auto documentLayout = qobject_cast<TextDocumentLayout*>(d->m_document.documentLayout());
|
auto documentLayout = qobject_cast<TextDocumentLayout*>(d->m_document.documentLayout());
|
||||||
Q_ASSERT(cursor.visualNavigation() == false);
|
Q_ASSERT(cursor.visualNavigation() == false);
|
||||||
@@ -862,7 +862,7 @@ void TextDocument::cleanWhitespace(QTextCursor &cursor, bool inEntireDocument,
|
|||||||
foreach (block, blocks) {
|
foreach (block, blocks) {
|
||||||
QString blockText = block.text();
|
QString blockText = block.text();
|
||||||
|
|
||||||
if (d->m_storageSettings.removeTrailingWhitespace(fileName))
|
if (removeTrailingWhitespace)
|
||||||
TabSettings::removeTrailingWhitespace(cursor, block);
|
TabSettings::removeTrailingWhitespace(cursor, block);
|
||||||
|
|
||||||
const int indent = indentations[block.blockNumber()];
|
const int indent = indentations[block.blockNumber()];
|
||||||
|
@@ -1572,6 +1572,7 @@ void TextEditorWidgetPrivate::slotSelectionChanged()
|
|||||||
m_selectBlockAnchor = QTextCursor();
|
m_selectBlockAnchor = QTextCursor();
|
||||||
// Clear any link which might be showing when the selection changes
|
// Clear any link which might be showing when the selection changes
|
||||||
clearLink();
|
clearLink();
|
||||||
|
setClipboardSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEditorWidget::gotoBlockStart()
|
void TextEditorWidget::gotoBlockStart()
|
||||||
@@ -5244,7 +5245,6 @@ void TextEditorWidget::mouseReleaseEvent(QMouseEvent *e)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
QPlainTextEdit::mouseReleaseEvent(e);
|
QPlainTextEdit::mouseReleaseEvent(e);
|
||||||
d->setClipboardSelection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEditorWidget::mouseDoubleClickEvent(QMouseEvent *e)
|
void TextEditorWidget::mouseDoubleClickEvent(QMouseEvent *e)
|
||||||
@@ -5259,7 +5259,6 @@ void TextEditorWidget::mouseDoubleClickEvent(QMouseEvent *e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
QPlainTextEdit::mouseDoubleClickEvent(e);
|
QPlainTextEdit::mouseDoubleClickEvent(e);
|
||||||
d->setClipboardSelection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextEditorWidgetPrivate::setClipboardSelection()
|
void TextEditorWidgetPrivate::setClipboardSelection()
|
||||||
|
@@ -54,6 +54,7 @@ const char *nameForStyle(TextStyle style)
|
|||||||
case C_NUMBER: return "Number";
|
case C_NUMBER: return "Number";
|
||||||
case C_STRING: return "String";
|
case C_STRING: return "String";
|
||||||
case C_TYPE: return "Type";
|
case C_TYPE: return "Type";
|
||||||
|
case C_NAMESPACE: return "Namespace";
|
||||||
case C_LOCAL: return "Local";
|
case C_LOCAL: return "Local";
|
||||||
case C_PARAMETER: return "Parameter";
|
case C_PARAMETER: return "Parameter";
|
||||||
case C_GLOBAL: return "Global";
|
case C_GLOBAL: return "Global";
|
||||||
@@ -114,6 +115,7 @@ const char *nameForStyle(TextStyle style)
|
|||||||
case C_DECLARATION: return "Declaration";
|
case C_DECLARATION: return "Declaration";
|
||||||
case C_FUNCTION_DEFINITION: return "FunctionDefinition";
|
case C_FUNCTION_DEFINITION: return "FunctionDefinition";
|
||||||
case C_OUTPUT_ARGUMENT: return "OutputArgument";
|
case C_OUTPUT_ARGUMENT: return "OutputArgument";
|
||||||
|
case C_STATIC_MEMBER: return "StaticMember";
|
||||||
|
|
||||||
case C_LAST_STYLE_SENTINEL: return "LastStyleSentinel";
|
case C_LAST_STYLE_SENTINEL: return "LastStyleSentinel";
|
||||||
}
|
}
|
||||||
|
@@ -54,6 +54,7 @@ enum TextStyle : quint8 {
|
|||||||
C_NUMBER,
|
C_NUMBER,
|
||||||
C_STRING,
|
C_STRING,
|
||||||
C_TYPE,
|
C_TYPE,
|
||||||
|
C_NAMESPACE,
|
||||||
C_LOCAL,
|
C_LOCAL,
|
||||||
C_PARAMETER,
|
C_PARAMETER,
|
||||||
C_GLOBAL,
|
C_GLOBAL,
|
||||||
@@ -114,6 +115,7 @@ enum TextStyle : quint8 {
|
|||||||
C_DECLARATION,
|
C_DECLARATION,
|
||||||
C_FUNCTION_DEFINITION,
|
C_FUNCTION_DEFINITION,
|
||||||
C_OUTPUT_ARGUMENT,
|
C_OUTPUT_ARGUMENT,
|
||||||
|
C_STATIC_MEMBER,
|
||||||
|
|
||||||
C_LAST_STYLE_SENTINEL
|
C_LAST_STYLE_SENTINEL
|
||||||
};
|
};
|
||||||
|
@@ -160,6 +160,8 @@ FormatDescriptions TextEditorSettingsPrivate::initialFormats()
|
|||||||
tr("Name of a primitive data type."), Qt::darkYellow);
|
tr("Name of a primitive data type."), Qt::darkYellow);
|
||||||
formatDescr.emplace_back(C_TYPE, tr("Type"), tr("Name of a type."),
|
formatDescr.emplace_back(C_TYPE, tr("Type"), tr("Name of a type."),
|
||||||
Qt::darkMagenta);
|
Qt::darkMagenta);
|
||||||
|
formatDescr.emplace_back(C_NAMESPACE, tr("Namespace"), tr("Name of a namespace."),
|
||||||
|
Qt::darkGreen);
|
||||||
formatDescr.emplace_back(C_LOCAL, tr("Local"),
|
formatDescr.emplace_back(C_LOCAL, tr("Local"),
|
||||||
tr("Local variables."), QColor(9, 46, 100));
|
tr("Local variables."), QColor(9, 46, 100));
|
||||||
formatDescr.emplace_back(C_PARAMETER, tr("Parameter"),
|
formatDescr.emplace_back(C_PARAMETER, tr("Parameter"),
|
||||||
@@ -361,6 +363,10 @@ FormatDescriptions TextEditorSettingsPrivate::initialFormats()
|
|||||||
tr("Writable arguments of a function call."),
|
tr("Writable arguments of a function call."),
|
||||||
outputArgumentFormat,
|
outputArgumentFormat,
|
||||||
FormatDescription::ShowAllControls);
|
FormatDescription::ShowAllControls);
|
||||||
|
formatDescr.emplace_back(C_STATIC_MEMBER,
|
||||||
|
tr("Static Member"),
|
||||||
|
tr("Names of static fields or member functions."),
|
||||||
|
FormatDescription::ShowAllControls);
|
||||||
|
|
||||||
return formatDescr;
|
return formatDescr;
|
||||||
}
|
}
|
||||||
|
@@ -36,14 +36,20 @@ struct TextStyles {
|
|||||||
TextStyle mainStyle;
|
TextStyle mainStyle;
|
||||||
MixinTextStyles mixinStyles;
|
MixinTextStyles mixinStyles;
|
||||||
|
|
||||||
static TextStyles mixinStyle(TextStyle main, TextStyle mixin)
|
static TextStyles mixinStyle(TextStyle main, const QList<TextStyle> &mixins)
|
||||||
{
|
{
|
||||||
TextStyles res;
|
TextStyles res;
|
||||||
res.mainStyle = main;
|
res.mainStyle = main;
|
||||||
res.mixinStyles.initializeElements();
|
res.mixinStyles.initializeElements();
|
||||||
res.mixinStyles.push_back(mixin);
|
for (TextStyle mixin : mixins)
|
||||||
|
res.mixinStyles.push_back(mixin);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TextStyles mixinStyle(TextStyle main, TextStyle mixin)
|
||||||
|
{
|
||||||
|
return mixinStyle(main, QList<TextStyle>{mixin});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace TextEditor
|
} // namespace TextEditor
|
||||||
|
Submodule src/shared/qbs updated: 966689ab49...38f233502e
@@ -62,6 +62,7 @@ static QString useKindToString(UseKind useKind)
|
|||||||
switch (useKind) {
|
switch (useKind) {
|
||||||
CASE_STR(Unknown);
|
CASE_STR(Unknown);
|
||||||
CASE_STR(TypeUse);
|
CASE_STR(TypeUse);
|
||||||
|
CASE_STR(NamespaceUse);
|
||||||
CASE_STR(LocalUse);
|
CASE_STR(LocalUse);
|
||||||
CASE_STR(FieldUse);
|
CASE_STR(FieldUse);
|
||||||
CASE_STR(EnumerationUse);
|
CASE_STR(EnumerationUse);
|
||||||
@@ -72,6 +73,9 @@ static QString useKindToString(UseKind useKind)
|
|||||||
CASE_STR(FunctionUse);
|
CASE_STR(FunctionUse);
|
||||||
CASE_STR(FunctionDeclarationUse);
|
CASE_STR(FunctionDeclarationUse);
|
||||||
CASE_STR(PseudoKeywordUse);
|
CASE_STR(PseudoKeywordUse);
|
||||||
|
CASE_STR(StaticFieldUse);
|
||||||
|
CASE_STR(StaticMethodUse);
|
||||||
|
CASE_STR(StaticMethodDeclarationUse);
|
||||||
default:
|
default:
|
||||||
QTest::qFail("Unknown UseKind", __FILE__, __LINE__);
|
QTest::qFail("Unknown UseKind", __FILE__, __LINE__);
|
||||||
return QLatin1String("Unknown UseKind");
|
return QLatin1String("Unknown UseKind");
|
||||||
@@ -246,8 +250,8 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
<< _("namespace N {}\n"
|
<< _("namespace N {}\n"
|
||||||
"using namespace N;\n")
|
"using namespace N;\n")
|
||||||
<< (UseList()
|
<< (UseList()
|
||||||
<< Use(1, 11, 1, Highlighting::TypeUse)
|
<< Use(1, 11, 1, Highlighting::NamespaceUse)
|
||||||
<< Use(2, 17, 1, Highlighting::TypeUse));
|
<< Use(2, 17, 1, Highlighting::NamespaceUse));
|
||||||
|
|
||||||
QTest::newRow("LocalUse")
|
QTest::newRow("LocalUse")
|
||||||
<< _("int f()\n"
|
<< _("int f()\n"
|
||||||
@@ -361,21 +365,21 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
"}\n")
|
"}\n")
|
||||||
<< (UseList()
|
<< (UseList()
|
||||||
<< Use(1, 8, 5, Highlighting::TypeUse)
|
<< 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(4, 12, 5, Highlighting::TypeUse)
|
||||||
<< Use(6, 9, 5, Highlighting::TypeUse)
|
<< Use(6, 9, 5, Highlighting::TypeUse)
|
||||||
<< Use(6, 16, 5, Highlighting::FieldUse)
|
<< Use(6, 16, 5, Highlighting::FieldUse)
|
||||||
<< Use(7, 14, 3, Highlighting::FunctionDeclarationUse)
|
<< Use(7, 14, 3, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(11, 5, 5, Highlighting::TypeUse)
|
<< 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, 6, 5, Highlighting::TypeUse)
|
||||||
<< Use(13, 13, 5, Highlighting::TypeUse)
|
<< Use(13, 13, 5, Highlighting::TypeUse)
|
||||||
<< Use(13, 20, 3, Highlighting::FunctionDeclarationUse)
|
<< 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, 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, 5, 5, Highlighting::FieldUse)
|
||||||
<< Use(17, 12, 3, Highlighting::FieldUse));
|
<< Use(17, 12, 3, Highlighting::StaticFieldUse));
|
||||||
|
|
||||||
QTest::newRow("VariableHasTheSameNameAsEnumUse")
|
QTest::newRow("VariableHasTheSameNameAsEnumUse")
|
||||||
<< _("struct Foo\n"
|
<< _("struct Foo\n"
|
||||||
@@ -443,11 +447,11 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
"}\n")
|
"}\n")
|
||||||
<< (UseList()
|
<< (UseList()
|
||||||
<< Use(1, 8, 3, Highlighting::TypeUse)
|
<< 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, 6, 3, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(8, 9, 3, Highlighting::LocalUse)
|
<< Use(8, 9, 3, Highlighting::LocalUse)
|
||||||
<< Use(8, 15, 3, Highlighting::TypeUse)
|
<< Use(8, 15, 3, Highlighting::TypeUse)
|
||||||
<< Use(8, 20, 3, Highlighting::FunctionUse));
|
<< Use(8, 20, 3, Highlighting::StaticMethodUse));
|
||||||
|
|
||||||
QTest::newRow("8902_staticFunctionHighlightingAsMember_functionArgument")
|
QTest::newRow("8902_staticFunctionHighlightingAsMember_functionArgument")
|
||||||
<< _("struct Foo\n"
|
<< _("struct Foo\n"
|
||||||
@@ -461,11 +465,11 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
"}\n")
|
"}\n")
|
||||||
<< (UseList()
|
<< (UseList()
|
||||||
<< Use(1, 8, 3, Highlighting::TypeUse)
|
<< 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, 6, 3, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(6, 14, 3, Highlighting::LocalUse)
|
<< Use(6, 14, 3, Highlighting::LocalUse)
|
||||||
<< Use(8, 5, 3, Highlighting::TypeUse)
|
<< Use(8, 5, 3, Highlighting::TypeUse)
|
||||||
<< Use(8, 10, 3, Highlighting::FunctionUse));
|
<< Use(8, 10, 3, Highlighting::StaticMethodUse));
|
||||||
|
|
||||||
QTest::newRow("8902_staticFunctionHighlightingAsMember_templateParameter")
|
QTest::newRow("8902_staticFunctionHighlightingAsMember_templateParameter")
|
||||||
<< _("struct Foo\n"
|
<< _("struct Foo\n"
|
||||||
@@ -480,11 +484,11 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
"}\n")
|
"}\n")
|
||||||
<< (UseList()
|
<< (UseList()
|
||||||
<< Use(1, 8, 3, Highlighting::TypeUse)
|
<< 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(6, 17, 3, Highlighting::TypeUse)
|
||||||
<< Use(7, 6, 3, Highlighting::FunctionDeclarationUse)
|
<< Use(7, 6, 3, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(9, 5, 3, Highlighting::TypeUse)
|
<< Use(9, 5, 3, Highlighting::TypeUse)
|
||||||
<< Use(9, 10, 3, Highlighting::FunctionUse));
|
<< Use(9, 10, 3, Highlighting::StaticMethodUse));
|
||||||
|
|
||||||
QTest::newRow("staticFunctionHighlightingAsMember_struct")
|
QTest::newRow("staticFunctionHighlightingAsMember_struct")
|
||||||
<< _("struct Foo\n"
|
<< _("struct Foo\n"
|
||||||
@@ -499,11 +503,11 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
"}\n")
|
"}\n")
|
||||||
<< (UseList()
|
<< (UseList()
|
||||||
<< Use(1, 8, 3, Highlighting::TypeUse)
|
<< 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(6, 8, 3, Highlighting::TypeUse)
|
||||||
<< Use(7, 6, 3, Highlighting::FunctionDeclarationUse)
|
<< Use(7, 6, 3, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(9, 5, 3, Highlighting::TypeUse)
|
<< Use(9, 5, 3, Highlighting::TypeUse)
|
||||||
<< Use(9, 10, 3, Highlighting::FunctionUse));
|
<< Use(9, 10, 3, Highlighting::StaticMethodUse));
|
||||||
|
|
||||||
QTest::newRow("QTCREATORBUG8890_danglingPointer")
|
QTest::newRow("QTCREATORBUG8890_danglingPointer")
|
||||||
<< _("template<class T> class QList {\n"
|
<< _("template<class T> class QList {\n"
|
||||||
@@ -569,13 +573,13 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
<< Use(1, 17, 1, Highlighting::TypeUse)
|
<< Use(1, 17, 1, Highlighting::TypeUse)
|
||||||
<< Use(2, 7, 9, Highlighting::TypeUse)
|
<< Use(2, 7, 9, Highlighting::TypeUse)
|
||||||
<< Use(5, 12, 1, 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(8, 6, 3, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(10, 6, 3, Highlighting::FunctionDeclarationUse);
|
<< Use(10, 6, 3, Highlighting::FunctionDeclarationUse);
|
||||||
for (int i = 0; i < 250; ++i) {
|
for (int i = 0; i < 250; ++i) {
|
||||||
excessiveUses
|
excessiveUses
|
||||||
<< Use(12 + i, 5, 9, Highlighting::TypeUse)
|
<< 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")
|
QTest::newRow("QTCREATORBUG8974_danglingPointer")
|
||||||
<< excessive
|
<< excessive
|
||||||
@@ -710,11 +714,11 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
<< Use(1, 14, 4, Highlighting::FieldUse)
|
<< Use(1, 14, 4, Highlighting::FieldUse)
|
||||||
<< Use(2, 6, 4, Highlighting::FunctionDeclarationUse)
|
<< Use(2, 6, 4, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(4, 8, 4, Highlighting::FieldUse)
|
<< 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(7, 16, 4, Highlighting::FieldUse)
|
||||||
<< Use(8, 8, 4, Highlighting::FunctionDeclarationUse)
|
<< Use(8, 8, 4, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(10, 10, 4, Highlighting::FieldUse)
|
<< 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(15, 27, 4, Highlighting::FieldUse)
|
||||||
<< Use(16, 10, 4, Highlighting::FunctionDeclarationUse)
|
<< Use(16, 10, 4, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(16, 19, 4, Highlighting::FieldUse)
|
<< Use(16, 19, 4, Highlighting::FieldUse)
|
||||||
@@ -792,9 +796,9 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
" Foo foo;\n"
|
" Foo foo;\n"
|
||||||
"}\n")
|
"}\n")
|
||||||
<< (UseList()
|
<< (UseList()
|
||||||
<< Use(1, 11, 2, Highlighting::TypeUse)
|
<< Use(1, 11, 2, Highlighting::NamespaceUse)
|
||||||
<< Use(2, 7, 3, Highlighting::TypeUse)
|
<< 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(4, 11, 3, Highlighting::TypeUse)
|
||||||
<< Use(5, 6, 3, Highlighting::FunctionDeclarationUse)
|
<< Use(5, 6, 3, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(7, 5, 3, Highlighting::TypeUse)
|
<< Use(7, 5, 3, Highlighting::TypeUse)
|
||||||
@@ -812,10 +816,10 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
"}\n"
|
"}\n"
|
||||||
"}\n")
|
"}\n")
|
||||||
<< (UseList()
|
<< (UseList()
|
||||||
<< Use(1, 11, 2, Highlighting::TypeUse)
|
<< Use(1, 11, 2, Highlighting::NamespaceUse)
|
||||||
<< Use(2, 7, 3, Highlighting::TypeUse)
|
<< Use(2, 7, 3, Highlighting::TypeUse)
|
||||||
<< Use(4, 11, 3, Highlighting::TypeUse)
|
<< Use(4, 11, 3, Highlighting::NamespaceUse)
|
||||||
<< Use(5, 7, 2, Highlighting::TypeUse)
|
<< Use(5, 7, 2, Highlighting::NamespaceUse)
|
||||||
<< Use(5, 11, 3, Highlighting::TypeUse)
|
<< Use(5, 11, 3, Highlighting::TypeUse)
|
||||||
<< Use(6, 6, 3, Highlighting::FunctionDeclarationUse)
|
<< Use(6, 6, 3, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(8, 5, 3, Highlighting::TypeUse)
|
<< Use(8, 5, 3, Highlighting::TypeUse)
|
||||||
@@ -831,10 +835,10 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
" Foo foo;\n"
|
" Foo foo;\n"
|
||||||
"}\n")
|
"}\n")
|
||||||
<< (UseList()
|
<< (UseList()
|
||||||
<< Use(1, 11, 2, Highlighting::TypeUse)
|
<< Use(1, 11, 2, Highlighting::NamespaceUse)
|
||||||
<< Use(2, 7, 3, Highlighting::TypeUse)
|
<< Use(2, 7, 3, Highlighting::TypeUse)
|
||||||
<< Use(4, 6, 3, Highlighting::FunctionDeclarationUse)
|
<< 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(6, 15, 3, Highlighting::TypeUse)
|
||||||
<< Use(7, 5, 3, Highlighting::TypeUse)
|
<< Use(7, 5, 3, Highlighting::TypeUse)
|
||||||
<< Use(7, 9, 3, Highlighting::LocalUse));
|
<< Use(7, 9, 3, Highlighting::LocalUse));
|
||||||
@@ -849,7 +853,7 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
" Foo foo;\n"
|
" Foo foo;\n"
|
||||||
"}\n")
|
"}\n")
|
||||||
<< (UseList()
|
<< (UseList()
|
||||||
<< Use(1, 11, 2, Highlighting::TypeUse)
|
<< Use(1, 11, 2, Highlighting::NamespaceUse)
|
||||||
<< Use(2, 7, 3, Highlighting::TypeUse)
|
<< Use(2, 7, 3, Highlighting::TypeUse)
|
||||||
<< Use(5, 6, 3, Highlighting::FunctionDeclarationUse)
|
<< Use(5, 6, 3, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(7, 9, 3, Highlighting::LocalUse));
|
<< Use(7, 9, 3, Highlighting::LocalUse));
|
||||||
@@ -866,9 +870,9 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
"}\n"
|
"}\n"
|
||||||
"}\n")
|
"}\n")
|
||||||
<< (UseList()
|
<< (UseList()
|
||||||
<< Use(1, 11, 2, Highlighting::TypeUse)
|
<< Use(1, 11, 2, Highlighting::NamespaceUse)
|
||||||
<< Use(2, 7, 3, Highlighting::TypeUse)
|
<< 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(6, 6, 3, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(8, 9, 3, Highlighting::LocalUse));
|
<< Use(8, 9, 3, Highlighting::LocalUse));
|
||||||
|
|
||||||
@@ -882,7 +886,7 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
" Foo foo;\n"
|
" Foo foo;\n"
|
||||||
"}\n")
|
"}\n")
|
||||||
<< (UseList()
|
<< (UseList()
|
||||||
<< Use(1, 11, 2, Highlighting::TypeUse)
|
<< Use(1, 11, 2, Highlighting::NamespaceUse)
|
||||||
<< Use(2, 7, 3, Highlighting::TypeUse)
|
<< Use(2, 7, 3, Highlighting::TypeUse)
|
||||||
<< Use(4, 6, 3, Highlighting::FunctionDeclarationUse)
|
<< Use(4, 6, 3, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(7, 9, 3, Highlighting::LocalUse));
|
<< Use(7, 9, 3, Highlighting::LocalUse));
|
||||||
@@ -944,14 +948,14 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
"}\n")
|
"}\n")
|
||||||
<< (UseList()
|
<< (UseList()
|
||||||
<< Use(1, 8, 1, Highlighting::TypeUse)
|
<< 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, 24, 1, Highlighting::TypeUse)
|
||||||
<< Use(4, 34, 10, Highlighting::TypeUse)
|
<< Use(4, 34, 10, Highlighting::TypeUse)
|
||||||
<< Use(6, 11, 2, Highlighting::TypeUse)
|
<< Use(6, 11, 2, Highlighting::NamespaceUse)
|
||||||
<< Use(8, 11, 3, Highlighting::TypeUse)
|
<< Use(8, 11, 3, Highlighting::NamespaceUse)
|
||||||
<< Use(8, 16, 10, Highlighting::TypeUse)
|
<< Use(8, 16, 10, Highlighting::TypeUse)
|
||||||
<< Use(10, 6, 3, Highlighting::FunctionDeclarationUse)
|
<< 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, 9, 10, Highlighting::TypeUse)
|
||||||
<< Use(12, 20, 1, Highlighting::TypeUse)
|
<< Use(12, 20, 1, Highlighting::TypeUse)
|
||||||
<< Use(12, 23, 1, Highlighting::LocalUse));
|
<< Use(12, 23, 1, Highlighting::LocalUse));
|
||||||
@@ -967,9 +971,9 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
" Foo foo;\n"
|
" Foo foo;\n"
|
||||||
"}\n")
|
"}\n")
|
||||||
<< (QList<Use>()
|
<< (QList<Use>()
|
||||||
<< Use(3, 15, 2, Highlighting::TypeUse)
|
<< Use(3, 15, 2, Highlighting::NamespaceUse)
|
||||||
<< Use(3, 27, 3, Highlighting::TypeUse)
|
<< Use(3, 27, 3, Highlighting::TypeUse)
|
||||||
<< Use(4, 11, 2, Highlighting::TypeUse)
|
<< Use(4, 11, 2, Highlighting::NamespaceUse)
|
||||||
<< Use(4, 15, 3, Highlighting::TypeUse)
|
<< Use(4, 15, 3, Highlighting::TypeUse)
|
||||||
<< Use(6, 6, 3, Highlighting::FunctionDeclarationUse)
|
<< Use(6, 6, 3, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(8, 5, 3, Highlighting::TypeUse)
|
<< Use(8, 5, 3, Highlighting::TypeUse)
|
||||||
@@ -991,12 +995,12 @@ void tst_CheckSymbols::test_checksymbols_data()
|
|||||||
"}\n"
|
"}\n"
|
||||||
)
|
)
|
||||||
<< (QList<Use>()
|
<< (QList<Use>()
|
||||||
<< Use(1, 11, 3, Highlighting::TypeUse)
|
<< Use(1, 11, 3, Highlighting::NamespaceUse)
|
||||||
<< Use(3, 15, 2, Highlighting::TypeUse)
|
<< Use(3, 15, 2, Highlighting::NamespaceUse)
|
||||||
<< Use(3, 27, 3, Highlighting::TypeUse)
|
<< Use(3, 27, 3, Highlighting::TypeUse)
|
||||||
<< Use(4, 11, 2, Highlighting::TypeUse)
|
<< Use(4, 11, 2, Highlighting::NamespaceUse)
|
||||||
<< Use(4, 15, 3, Highlighting::TypeUse)
|
<< Use(4, 15, 3, Highlighting::TypeUse)
|
||||||
<< Use(6, 11, 3, Highlighting::TypeUse)
|
<< Use(6, 11, 3, Highlighting::NamespaceUse)
|
||||||
<< Use(8, 10, 3, Highlighting::FunctionDeclarationUse)
|
<< Use(8, 10, 3, Highlighting::FunctionDeclarationUse)
|
||||||
<< Use(10, 13, 3, Highlighting::LocalUse)
|
<< Use(10, 13, 3, Highlighting::LocalUse)
|
||||||
);
|
);
|
||||||
|
@@ -121,8 +121,8 @@ void ExternaltoolTest::testRead1()
|
|||||||
QCOMPARE(tool->displayCategory(), QString::fromLatin1("Linguist"));
|
QCOMPARE(tool->displayCategory(), QString::fromLatin1("Linguist"));
|
||||||
QCOMPARE(tool->order(), 1);
|
QCOMPARE(tool->order(), 1);
|
||||||
QCOMPARE(tool->executables().size(), 2);
|
QCOMPARE(tool->executables().size(), 2);
|
||||||
QCOMPARE(tool->executables().at(0), QString::fromLatin1("%{QT_INSTALL_BINS}/lupdate"));
|
QCOMPARE(tool->executables().at(0), FilePath::fromString("%{QT_INSTALL_BINS}/lupdate"));
|
||||||
QCOMPARE(tool->executables().at(1), QString::fromLatin1("lupdate"));
|
QCOMPARE(tool->executables().at(1), FilePath::fromString("lupdate"));
|
||||||
QCOMPARE(tool->arguments(), QString::fromLatin1("%{CurrentProjectFilePath}"));
|
QCOMPARE(tool->arguments(), QString::fromLatin1("%{CurrentProjectFilePath}"));
|
||||||
QCOMPARE(tool->input(), QString());
|
QCOMPARE(tool->input(), QString());
|
||||||
QCOMPARE(tool->workingDirectory(), FilePath::fromString("%{CurrentProjectPath}"));
|
QCOMPARE(tool->workingDirectory(), FilePath::fromString("%{CurrentProjectPath}"));
|
||||||
@@ -143,7 +143,7 @@ void ExternaltoolTest::testRead2()
|
|||||||
QCOMPARE(tool->displayCategory(), QString::fromLatin1("Text"));
|
QCOMPARE(tool->displayCategory(), QString::fromLatin1("Text"));
|
||||||
QCOMPARE(tool->order(), -1);
|
QCOMPARE(tool->order(), -1);
|
||||||
QCOMPARE(tool->executables().size(), 1);
|
QCOMPARE(tool->executables().size(), 1);
|
||||||
QCOMPARE(tool->executables().at(0), QString::fromLatin1("sort"));
|
QCOMPARE(tool->executables().at(0), FilePath::fromString("sort"));
|
||||||
QCOMPARE(tool->arguments(), QString());
|
QCOMPARE(tool->arguments(), QString());
|
||||||
QCOMPARE(tool->input(), QString::fromLatin1("%{CurrentSelection}"));
|
QCOMPARE(tool->input(), QString::fromLatin1("%{CurrentSelection}"));
|
||||||
QCOMPARE(tool->workingDirectory(), FilePath::fromString("%{CurrentPath}"));
|
QCOMPARE(tool->workingDirectory(), FilePath::fromString("%{CurrentPath}"));
|
||||||
@@ -164,7 +164,7 @@ void ExternaltoolTest::testRead3()
|
|||||||
QCOMPARE(tool->displayCategory(), QString::fromLatin1("Text"));
|
QCOMPARE(tool->displayCategory(), QString::fromLatin1("Text"));
|
||||||
QCOMPARE(tool->order(), -1);
|
QCOMPARE(tool->order(), -1);
|
||||||
QCOMPARE(tool->executables().size(), 1);
|
QCOMPARE(tool->executables().size(), 1);
|
||||||
QCOMPARE(tool->executables().at(0), QString::fromLatin1("xterm"));
|
QCOMPARE(tool->executables().at(0), FilePath::fromString("xterm"));
|
||||||
QVERIFY(tool->arguments().startsWith(QLatin1String("-geom %{")));
|
QVERIFY(tool->arguments().startsWith(QLatin1String("-geom %{")));
|
||||||
QCOMPARE(tool->input(), QString());
|
QCOMPARE(tool->input(), QString());
|
||||||
QCOMPARE(tool->workingDirectory(), FilePath::fromString("%{CurrentPath}"));
|
QCOMPARE(tool->workingDirectory(), FilePath::fromString("%{CurrentPath}"));
|
||||||
|
@@ -214,7 +214,7 @@ def verifyBuildAndRun():
|
|||||||
appOutput = logApplicationOutput()
|
appOutput = logApplicationOutput()
|
||||||
if appOutput:
|
if appOutput:
|
||||||
test.verify((re.search(".* exited with code \d+", str(appOutput)) or
|
test.verify((re.search(".* exited with code \d+", str(appOutput)) or
|
||||||
re.search("The program has unexpectedly finished\.", str(appOutput))) and
|
re.search(".* crashed\.", str(appOutput))) and
|
||||||
re.search('[Ss]tarting.*', str(appOutput)),
|
re.search('[Ss]tarting.*', str(appOutput)),
|
||||||
"Verifying if built app started and closed successfully.")
|
"Verifying if built app started and closed successfully.")
|
||||||
|
|
||||||
|
@@ -190,22 +190,19 @@ def invokeMenuItem(menu, item, *subItems):
|
|||||||
itemObject = waitForObjectItem(objectMap.realName(menuObject), item)
|
itemObject = waitForObjectItem(objectMap.realName(menuObject), item)
|
||||||
waitFor("itemObject.enabled", 2000)
|
waitFor("itemObject.enabled", 2000)
|
||||||
activateItem(itemObject)
|
activateItem(itemObject)
|
||||||
numberedPrefix = "(&\\d \| )?"
|
numberedPrefix = "%d | "
|
||||||
for subItem in subItems:
|
for subItem in subItems:
|
||||||
# we might have numbered sub items (e.g. "Recent Files") - these have this special prefix
|
# we might have numbered sub items (e.g. "Recent Files") - these have this special prefix
|
||||||
if subItem.startswith(numberedPrefix):
|
if subItem.startswith(numberedPrefix):
|
||||||
# TODO: Find fix for Qt 6
|
|
||||||
actions = sub.actions()
|
|
||||||
triggered = False
|
triggered = False
|
||||||
for i in range(actions.count()):
|
for i in range(1, 10):
|
||||||
current = actions.at(i)
|
try:
|
||||||
nonPrefix = subItem[len(numberedPrefix):]
|
itemObject = waitForObjectItem(itemObject, subItem % i, 1000)
|
||||||
matcher = re.match("%s(.*)" % numberedPrefix, str(current.text))
|
|
||||||
if matcher and matcher.group(2) == nonPrefix:
|
|
||||||
itemObject = current
|
|
||||||
activateItem(itemObject)
|
activateItem(itemObject)
|
||||||
triggered = True
|
triggered = True
|
||||||
break
|
break
|
||||||
|
except:
|
||||||
|
continue
|
||||||
if not triggered:
|
if not triggered:
|
||||||
test.fail("Could not trigger '%s' - item missing or code wrong?" % subItem,
|
test.fail("Could not trigger '%s' - item missing or code wrong?" % subItem,
|
||||||
"Function arguments: '%s', '%s', %s" % (menu, item, str(subItems)))
|
"Function arguments: '%s', '%s', %s" % (menu, item, str(subItems)))
|
||||||
|
@@ -199,7 +199,7 @@ def main():
|
|||||||
recentFile = os.path.join(folder, current)
|
recentFile = os.path.join(folder, current)
|
||||||
if recentFile.startswith(home) and platform.system() in ('Linux', 'Darwin'):
|
if recentFile.startswith(home) and platform.system() in ('Linux', 'Darwin'):
|
||||||
recentFile = recentFile.replace(home, "~", 1)
|
recentFile = recentFile.replace(home, "~", 1)
|
||||||
invokeMenuItem("File", "Recent Files", "(&\\d \| )?%s" % recentFile)
|
invokeMenuItem("File", "Recent Files", "%d | " + recentFile)
|
||||||
editor = getEditorForFileSuffix(current)
|
editor = getEditorForFileSuffix(current)
|
||||||
display = displayHintForHighlighterDefinition(current, patterns, lPatterns,
|
display = displayHintForHighlighterDefinition(current, patterns, lPatterns,
|
||||||
addedHaskell, addedLiterateHaskell)
|
addedHaskell, addedLiterateHaskell)
|
||||||
|
Reference in New Issue
Block a user