forked from qt-creator/qt-creator
Merge "Merge remote-tracking branch 'origin/qds-1.59' into 4.13" into 4.13
This commit is contained in:
@@ -1,19 +1,3 @@
|
|||||||
# .clang-format for Qt Creator
|
|
||||||
#
|
|
||||||
# This is for clang-format >= 5.0.
|
|
||||||
#
|
|
||||||
# The configuration below follows the Qt Creator Coding Rules [1] as closely as
|
|
||||||
# possible. For documentation of the options, see [2].
|
|
||||||
#
|
|
||||||
# Use ../../tests/manual/clang-format-for-qtc/test.cpp for documenting problems
|
|
||||||
# or testing changes.
|
|
||||||
#
|
|
||||||
# In case you update this configuration please also update the qtcStyle() in src\plugins\clangformat\clangformatutils.cpp
|
|
||||||
#
|
|
||||||
# [1] https://doc-snapshots.qt.io/qtcreator-extending/coding-style.html
|
|
||||||
# [2] https://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
|
||||||
#
|
|
||||||
---
|
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
AccessModifierOffset: -4
|
AccessModifierOffset: -4
|
||||||
AlignAfterOpenBracket: Align
|
AlignAfterOpenBracket: Align
|
||||||
@@ -90,12 +74,12 @@ NamespaceIndentation: None
|
|||||||
ObjCBlockIndentWidth: 4
|
ObjCBlockIndentWidth: 4
|
||||||
ObjCSpaceAfterProperty: false
|
ObjCSpaceAfterProperty: false
|
||||||
ObjCSpaceBeforeProtocolList: true
|
ObjCSpaceBeforeProtocolList: true
|
||||||
PenaltyBreakAssignment: 150
|
PenaltyBreakAssignment: 500
|
||||||
PenaltyBreakBeforeFirstCallParameter: 300
|
PenaltyBreakBeforeFirstCallParameter: 150
|
||||||
PenaltyBreakComment: 500
|
PenaltyBreakComment: 500
|
||||||
PenaltyBreakFirstLessLess: 400
|
PenaltyBreakFirstLessLess: 400
|
||||||
PenaltyBreakString: 600
|
PenaltyBreakString: 600
|
||||||
PenaltyExcessCharacter: 50
|
PenaltyExcessCharacter: 7
|
||||||
PenaltyReturnTypeOnItsOwnLine: 300
|
PenaltyReturnTypeOnItsOwnLine: 300
|
||||||
PointerAlignment: Right
|
PointerAlignment: Right
|
||||||
ReflowComments: false
|
ReflowComments: false
|
||||||
|
@@ -61,4 +61,10 @@ long long FileSystem::lastModified(FilePathId filePathId) const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FileSystem::remove(const FilePathIds &filePathIds)
|
||||||
|
{
|
||||||
|
for (FilePathId filePathId : filePathIds)
|
||||||
|
QFile::remove(QString{m_filePathCache.filePath(filePathId)});
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
@@ -41,6 +41,8 @@ public:
|
|||||||
FilePathIds directoryEntries(const QString &directoryPath) const override;
|
FilePathIds directoryEntries(const QString &directoryPath) const override;
|
||||||
long long lastModified(FilePathId filePathId) const override;
|
long long lastModified(FilePathId filePathId) const override;
|
||||||
|
|
||||||
|
void remove(const FilePathIds &filePathIds) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FilePathCachingInterface &m_filePathCache;
|
FilePathCachingInterface &m_filePathCache;
|
||||||
};
|
};
|
||||||
|
@@ -36,6 +36,7 @@ class FileSystemInterface
|
|||||||
public:
|
public:
|
||||||
virtual FilePathIds directoryEntries(const QString &directoryPath) const = 0;
|
virtual FilePathIds directoryEntries(const QString &directoryPath) const = 0;
|
||||||
virtual long long lastModified(FilePathId filePathId) const = 0;
|
virtual long long lastModified(FilePathId filePathId) const = 0;
|
||||||
|
virtual void remove(const FilePathIds &filePathIds) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~FileSystemInterface() = default;
|
~FileSystemInterface() = default;
|
||||||
|
@@ -1,22 +1,28 @@
|
|||||||
INCLUDEPATH += $$PWD
|
INCLUDEPATH += $$PWD
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/clangactivationsequencecontextprocessor.cpp \
|
|
||||||
$$PWD/clangactivationsequenceprocessor.cpp \
|
|
||||||
$$PWD/clangcompletionchunkstotextconverter.cpp \
|
$$PWD/clangcompletionchunkstotextconverter.cpp \
|
||||||
$$PWD/clangcompletioncontextanalyzer.cpp \
|
|
||||||
$$PWD/clangdiagnosticfilter.cpp \
|
$$PWD/clangdiagnosticfilter.cpp \
|
||||||
$$PWD/clangfixitoperation.cpp \
|
$$PWD/clangfixitoperation.cpp \
|
||||||
$$PWD/clanghighlightingresultreporter.cpp \
|
$$PWD/clanghighlightingresultreporter.cpp \
|
||||||
$$PWD/clanguiheaderondiskmanager.cpp
|
$$PWD/clanguiheaderondiskmanager.cpp
|
||||||
|
|
||||||
|
!isEmpty(QTC_UNITTEST_BUILD_CPP_PARSER):SOURCES+= \
|
||||||
|
$$PWD/clangactivationsequenceprocessor.cpp \
|
||||||
|
$$PWD/clangactivationsequencecontextprocessor.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
$$PWD/clangactivationsequencecontextprocessor.h \
|
|
||||||
$$PWD/clangactivationsequenceprocessor.h \
|
|
||||||
$$PWD/clangcompletionchunkstotextconverter.h \
|
$$PWD/clangcompletionchunkstotextconverter.h \
|
||||||
$$PWD/clangcompletioncontextanalyzer.h \
|
|
||||||
$$PWD/clangdiagnosticfilter.h \
|
$$PWD/clangdiagnosticfilter.h \
|
||||||
$$PWD/clangfixitoperation.h \
|
$$PWD/clangfixitoperation.h \
|
||||||
$$PWD/clanghighlightingresultreporter.h \
|
$$PWD/clanghighlightingresultreporter.h \
|
||||||
$$PWD/clangisdiagnosticrelatedtolocation.h \
|
$$PWD/clangisdiagnosticrelatedtolocation.h \
|
||||||
$$PWD/clanguiheaderondiskmanager.h
|
$$PWD/clanguiheaderondiskmanager.h
|
||||||
|
|
||||||
|
!isEmpty(QTC_UNITTEST_BUILD_CPP_PARSER):SOURCES+= \
|
||||||
|
$$PWD/clangactivationsequencecontextprocessor.h \
|
||||||
|
$$PWD/clangactivationsequenceprocessor.h \
|
||||||
|
$$PWD/clangcompletioncontextanalyzer.cpp \
|
||||||
|
$$PWD/clangcompletioncontextanalyzer.h
|
||||||
|
|
||||||
|
|
||||||
|
@@ -386,6 +386,13 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
texteditorwidget.cpp texteditorwidget.h
|
texteditorwidget.cpp texteditorwidget.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
extend_qtc_plugin(QmlDesigner
|
||||||
|
SOURCES_PREFIX components/listmodeleditor
|
||||||
|
SOURCES
|
||||||
|
listmodeleditordialog.cpp listmodeleditordialog.h
|
||||||
|
listmodeleditordialog.cpp listmodeleditormodel.h
|
||||||
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(QmlDesigner
|
extend_qtc_plugin(QmlDesigner
|
||||||
SOURCES_PREFIX designercore
|
SOURCES_PREFIX designercore
|
||||||
SOURCES
|
SOURCES
|
||||||
|
@@ -35,6 +35,7 @@
|
|||||||
#include "utils/fileutils.h"
|
#include "utils/fileutils.h"
|
||||||
#include "utils/outputformatter.h"
|
#include "utils/outputformatter.h"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QListView>
|
#include <QListView>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
@@ -86,6 +87,15 @@ AssetExportDialog::AssetExportDialog(const Utils::FilePath &exportPath,
|
|||||||
Core::FileUtils::showInGraphicalShell(Core::ICore::mainWindow(), m_ui->exportPath->path());
|
Core::FileUtils::showInGraphicalShell(Core::ICore::mainWindow(), m_ui->exportPath->path());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
auto optionsWidget = new QWidget;
|
||||||
|
m_ui->advancedOptions->setSummaryText(tr("Advanced Options"));
|
||||||
|
m_ui->advancedOptions->setWidget(optionsWidget);
|
||||||
|
auto optionsLayout = new QHBoxLayout(optionsWidget);
|
||||||
|
optionsLayout->setMargin(8);
|
||||||
|
m_exportAssetsCheck = new QCheckBox(tr("Export assets"), this);
|
||||||
|
m_exportAssetsCheck->setChecked(true);
|
||||||
|
optionsLayout->addWidget(m_exportAssetsCheck);
|
||||||
|
|
||||||
m_ui->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false);
|
m_ui->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false);
|
||||||
|
|
||||||
m_ui->stackedWidget->addWidget(m_filesView);
|
m_ui->stackedWidget->addWidget(m_filesView);
|
||||||
@@ -97,6 +107,7 @@ AssetExportDialog::AssetExportDialog(const Utils::FilePath &exportPath,
|
|||||||
switchView(false);
|
switchView(false);
|
||||||
|
|
||||||
connect(m_ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, [this]() {
|
connect(m_ui->buttonBox->button(QDialogButtonBox::Cancel), &QPushButton::clicked, [this]() {
|
||||||
|
m_ui->buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false);
|
||||||
m_assetExporter.cancel();
|
m_assetExporter.cancel();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -137,7 +148,8 @@ void AssetExportDialog::onExport()
|
|||||||
TaskHub::clearTasks(Constants::TASK_CATEGORY_ASSET_EXPORT);
|
TaskHub::clearTasks(Constants::TASK_CATEGORY_ASSET_EXPORT);
|
||||||
m_exportLogs->clear();
|
m_exportLogs->clear();
|
||||||
|
|
||||||
m_assetExporter.exportQml(m_filePathModel.files(), m_ui->exportPath->fileName());
|
m_assetExporter.exportQml(m_filePathModel.files(), m_ui->exportPath->fileName(),
|
||||||
|
m_exportAssetsCheck->isChecked());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetExportDialog::onExportStateChanged(AssetExporter::ParsingState newState)
|
void AssetExportDialog::onExportStateChanged(AssetExporter::ParsingState newState)
|
||||||
|
@@ -34,6 +34,7 @@
|
|||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QPushButton;
|
class QPushButton;
|
||||||
|
class QCheckBox;
|
||||||
class QListView;
|
class QListView;
|
||||||
class QPlainTextEdit;
|
class QPlainTextEdit;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
@@ -74,6 +75,7 @@ private:
|
|||||||
FilePathModel &m_filePathModel;
|
FilePathModel &m_filePathModel;
|
||||||
std::unique_ptr<Ui::AssetExportDialog> m_ui;
|
std::unique_ptr<Ui::AssetExportDialog> m_ui;
|
||||||
QPushButton *m_exportBtn = nullptr;
|
QPushButton *m_exportBtn = nullptr;
|
||||||
|
QCheckBox *m_exportAssetsCheck = nullptr;
|
||||||
QListView *m_filesView = nullptr;
|
QListView *m_filesView = nullptr;
|
||||||
QPlainTextEdit *m_exportLogs = nullptr;
|
QPlainTextEdit *m_exportLogs = nullptr;
|
||||||
Utils::OutputFormatter *m_outputFormatter = nullptr;
|
Utils::OutputFormatter *m_outputFormatter = nullptr;
|
||||||
|
@@ -14,9 +14,6 @@
|
|||||||
<string>Export QML</string>
|
<string>Export QML</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="Utils::PathChooser" name="exportPath" native="true"/>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QLabel" name="label">
|
<widget class="QLabel" name="label">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@@ -30,10 +27,10 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0" colspan="2">
|
<item row="2" column="0" colspan="2">
|
||||||
<widget class="QStackedWidget" name="stackedWidget"/>
|
<widget class="QStackedWidget" name="stackedWidget"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" colspan="2">
|
<item row="3" column="0" colspan="2">
|
||||||
<widget class="QProgressBar" name="exportProgress">
|
<widget class="QProgressBar" name="exportProgress">
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<number>1000</number>
|
<number>1000</number>
|
||||||
@@ -43,13 +40,26 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0" colspan="2">
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="Utils::DetailsWidget" name="advancedOptions" native="true">
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>8</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0" colspan="2">
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="standardButtons">
|
<property name="standardButtons">
|
||||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Close</set>
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Close</set>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="Utils::PathChooser" name="exportPath" native="true"/>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<customwidgets>
|
<customwidgets>
|
||||||
@@ -59,6 +69,12 @@
|
|||||||
<header location="global">utils/pathchooser.h</header>
|
<header location="global">utils/pathchooser.h</header>
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
|
<customwidget>
|
||||||
|
<class>Utils::DetailsWidget</class>
|
||||||
|
<extends>QWidget</extends>
|
||||||
|
<header location="global">utils/detailswidget.h</header>
|
||||||
|
<container>1</container>
|
||||||
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
@@ -25,7 +25,6 @@
|
|||||||
#include "assetexporter.h"
|
#include "assetexporter.h"
|
||||||
#include "componentexporter.h"
|
#include "componentexporter.h"
|
||||||
#include "exportnotification.h"
|
#include "exportnotification.h"
|
||||||
#include "assetexportpluginconstants.h"
|
|
||||||
|
|
||||||
#include "rewriterview.h"
|
#include "rewriterview.h"
|
||||||
#include "qmlitemnode.h"
|
#include "qmlitemnode.h"
|
||||||
@@ -117,21 +116,26 @@ void AssetExporter::exportQml(const Utils::FilePaths &qmlFiles, const Utils::Fil
|
|||||||
ExportNotification::addInfo(tr("Exporting metadata at %1. Export assets: ")
|
ExportNotification::addInfo(tr("Exporting metadata at %1. Export assets: ")
|
||||||
.arg(exportPath.toUserOutput())
|
.arg(exportPath.toUserOutput())
|
||||||
.arg(exportAssets? tr("Yes") : tr("No")));
|
.arg(exportAssets? tr("Yes") : tr("No")));
|
||||||
// TODO Asset export
|
|
||||||
notifyProgress(0.0);
|
notifyProgress(0.0);
|
||||||
Q_UNUSED(exportAssets);
|
|
||||||
m_exportFiles = qmlFiles;
|
m_exportFiles = qmlFiles;
|
||||||
|
m_totalFileCount = m_exportFiles.count();
|
||||||
m_components = QJsonArray();
|
m_components = QJsonArray();
|
||||||
m_exportPath = exportPath;
|
m_exportPath = exportPath;
|
||||||
m_currentState.change(ParsingState::Parsing);
|
m_currentState.change(ParsingState::Parsing);
|
||||||
triggerLoadNextFile();
|
triggerLoadNextFile();
|
||||||
|
if (exportAssets)
|
||||||
m_assetDumper = make_unique<AssetDumper>();
|
m_assetDumper = make_unique<AssetDumper>();
|
||||||
|
else
|
||||||
|
m_assetDumper.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetExporter::cancel()
|
void AssetExporter::cancel()
|
||||||
{
|
{
|
||||||
// TODO Cancel export
|
if (!m_cancelled) {
|
||||||
|
ExportNotification::addInfo(tr("Cancelling export."));
|
||||||
m_assetDumper.reset();
|
m_assetDumper.reset();
|
||||||
|
m_cancelled = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AssetExporter::isBusy() const
|
bool AssetExporter::isBusy() const
|
||||||
@@ -141,12 +145,12 @@ bool AssetExporter::isBusy() const
|
|||||||
m_currentState == AssetExporter::ParsingState::WritingJson;
|
m_currentState == AssetExporter::ParsingState::WritingJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::FilePath AssetExporter::exportAsset(const QmlObjectNode &node)
|
Utils::FilePath AssetExporter::exportAsset(const QmlObjectNode &node, const QString &uuid)
|
||||||
{
|
{
|
||||||
// TODO: Use this hash as UUID and add to the node.
|
if (m_cancelled)
|
||||||
QByteArray hash = addNodeUUID(node.modelNode());
|
return {};
|
||||||
Utils::FilePath assetPath = m_exportPath.pathAppended(QString("assets/%1.png")
|
Utils::FilePath assetPath = m_exportPath.pathAppended(QString("assets/%1.png").arg(uuid));
|
||||||
.arg(QString::fromLatin1(hash)));
|
if (m_assetDumper)
|
||||||
m_assetDumper->dumpAsset(node.toQmlItemNode().instanceRenderPixmap(), assetPath);
|
m_assetDumper->dumpAsset(node.toQmlItemNode().instanceRenderPixmap(), assetPath);
|
||||||
return assetPath;
|
return assetPath;
|
||||||
}
|
}
|
||||||
@@ -157,6 +161,7 @@ void AssetExporter::exportComponent(const ModelNode &rootNode)
|
|||||||
Component exporter(*this, rootNode);
|
Component exporter(*this, rootNode);
|
||||||
exporter.exportComponent();
|
exporter.exportComponent();
|
||||||
m_components.append(exporter.json());
|
m_components.append(exporter.json());
|
||||||
|
notifyProgress((m_totalFileCount - m_exportFiles.count()) * 0.8 / m_totalFileCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetExporter::notifyLoadError(AssetExporterView::LoadState state)
|
void AssetExporter::notifyLoadError(AssetExporterView::LoadState state)
|
||||||
@@ -194,19 +199,13 @@ void AssetExporter::onQmlFileLoaded()
|
|||||||
triggerLoadNextFile();
|
triggerLoadNextFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray AssetExporter::addNodeUUID(ModelNode node)
|
QByteArray AssetExporter::generateUuid(const ModelNode &node)
|
||||||
{
|
{
|
||||||
QByteArray uuid = node.auxiliaryData(Constants::UuidTag).toByteArray();
|
QByteArray uuid;
|
||||||
qDebug() << node.id() << "UUID" << uuid;
|
|
||||||
if (uuid.isEmpty()) {
|
|
||||||
// Assign a new hash.
|
|
||||||
do {
|
do {
|
||||||
uuid = generateHash(node.id());
|
uuid = generateHash(node.id());
|
||||||
} while (m_usedHashes.contains(uuid));
|
} while (m_usedHashes.contains(uuid));
|
||||||
m_usedHashes.insert(uuid);
|
m_usedHashes.insert(uuid);
|
||||||
node.setAuxiliaryData(Constants::UuidAuxTag, QString::fromLatin1(uuid));
|
|
||||||
node.model()->rewriterView()->writeAuxiliaryData();
|
|
||||||
}
|
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -217,7 +216,7 @@ void AssetExporter::triggerLoadNextFile()
|
|||||||
|
|
||||||
void AssetExporter::loadNextFile()
|
void AssetExporter::loadNextFile()
|
||||||
{
|
{
|
||||||
if (m_exportFiles.isEmpty()) {
|
if (m_cancelled || m_exportFiles.isEmpty()) {
|
||||||
notifyProgress(0.8);
|
notifyProgress(0.8);
|
||||||
m_currentState.change(ParsingState::ParsingFinished);
|
m_currentState.change(ParsingState::ParsingFinished);
|
||||||
writeMetadata();
|
writeMetadata();
|
||||||
@@ -233,6 +232,13 @@ void AssetExporter::loadNextFile()
|
|||||||
|
|
||||||
void AssetExporter::writeMetadata() const
|
void AssetExporter::writeMetadata() const
|
||||||
{
|
{
|
||||||
|
if (m_cancelled) {
|
||||||
|
notifyProgress(1.0);
|
||||||
|
ExportNotification::addInfo(tr("Export cancelled."));
|
||||||
|
m_currentState.change(ParsingState::ExportingDone);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Utils::FilePath metadataPath = m_exportPath.pathAppended(m_exportPath.fileName() + ".metadata");
|
Utils::FilePath metadataPath = m_exportPath.pathAppended(m_exportPath.fileName() + ".metadata");
|
||||||
ExportNotification::addInfo(tr("Writing metadata to file %1.").
|
ExportNotification::addInfo(tr("Writing metadata to file %1.").
|
||||||
arg(metadataPath.toUserOutput()));
|
arg(metadataPath.toUserOutput()));
|
||||||
@@ -253,6 +259,7 @@ void AssetExporter::writeMetadata() const
|
|||||||
}
|
}
|
||||||
notifyProgress(1.0);
|
notifyProgress(1.0);
|
||||||
ExportNotification::addInfo(tr("Export finished."));
|
ExportNotification::addInfo(tr("Export finished."));
|
||||||
|
if (m_assetDumper)
|
||||||
m_assetDumper->quitDumper();
|
m_assetDumper->quitDumper();
|
||||||
m_currentState.change(ParsingState::ExportingDone);
|
m_currentState.change(ParsingState::ExportingDone);
|
||||||
}
|
}
|
||||||
|
@@ -70,7 +70,8 @@ public:
|
|||||||
void cancel();
|
void cancel();
|
||||||
bool isBusy() const;
|
bool isBusy() const;
|
||||||
|
|
||||||
Utils::FilePath exportAsset(const QmlObjectNode& node);
|
Utils::FilePath exportAsset(const QmlObjectNode& node, const QString &uuid);
|
||||||
|
QByteArray generateUuid(const ModelNode &node);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void stateChanged(ParsingState);
|
void stateChanged(ParsingState);
|
||||||
@@ -87,8 +88,6 @@ private:
|
|||||||
|
|
||||||
void onQmlFileLoaded();
|
void onQmlFileLoaded();
|
||||||
|
|
||||||
QByteArray addNodeUUID(ModelNode node);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable class State {
|
mutable class State {
|
||||||
public:
|
public:
|
||||||
@@ -101,10 +100,12 @@ private:
|
|||||||
ProjectExplorer::Project *m_project = nullptr;
|
ProjectExplorer::Project *m_project = nullptr;
|
||||||
AssetExporterView *m_view = nullptr;
|
AssetExporterView *m_view = nullptr;
|
||||||
Utils::FilePaths m_exportFiles;
|
Utils::FilePaths m_exportFiles;
|
||||||
|
unsigned int m_totalFileCount = 0;
|
||||||
Utils::FilePath m_exportPath;
|
Utils::FilePath m_exportPath;
|
||||||
QJsonArray m_components;
|
QJsonArray m_components;
|
||||||
QSet<QByteArray> m_usedHashes;
|
QSet<QByteArray> m_usedHashes;
|
||||||
std::unique_ptr<AssetDumper> m_assetDumper;
|
std::unique_ptr<AssetDumper> m_assetDumper;
|
||||||
|
bool m_cancelled = false;
|
||||||
};
|
};
|
||||||
QDebug operator<< (QDebug os, const QmlDesigner::AssetExporter::ParsingState& s);
|
QDebug operator<< (QDebug os, const QmlDesigner::AssetExporter::ParsingState& s);
|
||||||
|
|
||||||
|
@@ -61,6 +61,7 @@ const char AssetDataTag[] = "assetData";
|
|||||||
const char AssetPathTag[] = "assetPath";
|
const char AssetPathTag[] = "assetPath";
|
||||||
const char AssetBoundsTag[] = "assetBounds";
|
const char AssetBoundsTag[] = "assetBounds";
|
||||||
const char OpacityTag[] = "opacity";
|
const char OpacityTag[] = "opacity";
|
||||||
|
const char TypeNameTag[] = "qmlType";
|
||||||
|
|
||||||
const char TextDetailsTag[] = "textDetails";
|
const char TextDetailsTag[] = "textDetails";
|
||||||
const char FontFamilyTag[] = "fontFamily";
|
const char FontFamilyTag[] = "fontFamily";
|
||||||
|
@@ -23,6 +23,9 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include "componentexporter.h"
|
#include "componentexporter.h"
|
||||||
|
#include "assetexporter.h"
|
||||||
|
#include "assetexportpluginconstants.h"
|
||||||
|
#include "exportnotification.h"
|
||||||
#include "parsers/modelnodeparser.h"
|
#include "parsers/modelnodeparser.h"
|
||||||
|
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
@@ -73,6 +76,7 @@ void Component::exportComponent()
|
|||||||
{
|
{
|
||||||
QTC_ASSERT(m_rootNode.isValid(), return);
|
QTC_ASSERT(m_rootNode.isValid(), return);
|
||||||
m_json = nodeToJson(m_rootNode);
|
m_json = nodeToJson(m_rootNode);
|
||||||
|
addImports();
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelNodeParser *Component::createNodeParser(const ModelNode &node) const
|
ModelNodeParser *Component::createNodeParser(const ModelNode &node) const
|
||||||
@@ -102,8 +106,18 @@ QJsonObject Component::nodeToJson(const ModelNode &node)
|
|||||||
{
|
{
|
||||||
QJsonObject jsonObject;
|
QJsonObject jsonObject;
|
||||||
std::unique_ptr<ModelNodeParser> parser(createNodeParser(node));
|
std::unique_ptr<ModelNodeParser> parser(createNodeParser(node));
|
||||||
if (parser)
|
if (parser) {
|
||||||
|
if (parser->uuid().isEmpty()) {
|
||||||
|
// Assign an unique identifier to the node.
|
||||||
|
QByteArray uuid = m_exporter.generateUuid(node);
|
||||||
|
node.setAuxiliaryData(Constants::UuidAuxTag, QString::fromLatin1(uuid));
|
||||||
|
node.model()->rewriterView()->writeAuxiliaryData();
|
||||||
|
}
|
||||||
jsonObject = parser->json(*this);
|
jsonObject = parser->json(*this);
|
||||||
|
} else {
|
||||||
|
ExportNotification::addError(tr("Error exporting component %1. Parser unavailable.")
|
||||||
|
.arg(node.id()));
|
||||||
|
}
|
||||||
|
|
||||||
QJsonArray children;
|
QJsonArray children;
|
||||||
for (const ModelNode &childnode : node.directSubModelNodes())
|
for (const ModelNode &childnode : node.directSubModelNodes())
|
||||||
@@ -115,5 +129,15 @@ QJsonObject Component::nodeToJson(const ModelNode &node)
|
|||||||
return jsonObject;
|
return jsonObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Component::addImports()
|
||||||
|
{
|
||||||
|
QJsonArray importsArray;
|
||||||
|
for (const Import &import : m_rootNode.model()->imports())
|
||||||
|
importsArray.append(import.toString());
|
||||||
|
|
||||||
|
if (!importsArray.empty())
|
||||||
|
m_json.insert(Constants::ImportsTag, importsArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
@@ -24,8 +24,9 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QByteArrayList>
|
#include <QByteArrayList>
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QJsonObject>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -68,6 +69,8 @@ protected:
|
|||||||
|
|
||||||
class Component
|
class Component
|
||||||
{
|
{
|
||||||
|
Q_DECLARE_TR_FUNCTIONS(Component);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Component(AssetExporter& exporter, const ModelNode &rootNode);
|
Component(AssetExporter& exporter, const ModelNode &rootNode);
|
||||||
|
|
||||||
@@ -84,6 +87,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
ModelNodeParser* createNodeParser(const ModelNode &node) const;
|
ModelNodeParser* createNodeParser(const ModelNode &node) const;
|
||||||
QJsonObject nodeToJson(const ModelNode &node);
|
QJsonObject nodeToJson(const ModelNode &node);
|
||||||
|
void addImports();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AssetExporter& m_exporter;
|
AssetExporter& m_exporter;
|
||||||
|
@@ -55,8 +55,7 @@ QJsonObject AssetNodeParser::json(Component &component) const
|
|||||||
QJsonObject jsonObject = ItemNodeParser::json(component);
|
QJsonObject jsonObject = ItemNodeParser::json(component);
|
||||||
|
|
||||||
QPixmap asset = objectNode().toQmlItemNode().instanceRenderPixmap();
|
QPixmap asset = objectNode().toQmlItemNode().instanceRenderPixmap();
|
||||||
Utils::FilePath assetPath = component.exporter().exportAsset(objectNode());
|
Utils::FilePath assetPath = component.exporter().exportAsset(objectNode(), uuid());
|
||||||
|
|
||||||
QJsonObject assetData;
|
QJsonObject assetData;
|
||||||
assetData.insert(AssetPathTag, assetPath.toString());
|
assetData.insert(AssetPathTag, assetPath.toString());
|
||||||
jsonObject.insert(AssetDataTag, assetData);
|
jsonObject.insert(AssetDataTag, assetData);
|
||||||
|
@@ -60,6 +60,10 @@ QJsonObject QmlDesigner::ItemNodeParser::json(QmlDesigner::Component &component)
|
|||||||
jsonObject.insert(WidthTag, size.width());
|
jsonObject.insert(WidthTag, size.width());
|
||||||
jsonObject.insert(HeightTag, size.height());
|
jsonObject.insert(HeightTag, size.height());
|
||||||
|
|
||||||
|
jsonObject.insert(UuidTag, uuid());
|
||||||
|
jsonObject.insert(ExportTypeTag, "child");
|
||||||
|
jsonObject.insert(TypeNameTag, QString::fromLatin1(m_node.type()));
|
||||||
|
|
||||||
return jsonObject;
|
return jsonObject;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -23,6 +23,7 @@
|
|||||||
**
|
**
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include "modelnodeparser.h"
|
#include "modelnodeparser.h"
|
||||||
|
#include "assetexportpluginconstants.h"
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
ModelNodeParser::ModelNodeParser(const QByteArrayList &lineage, const ModelNode &node) :
|
ModelNodeParser::ModelNodeParser(const QByteArrayList &lineage, const ModelNode &node) :
|
||||||
@@ -38,4 +39,9 @@ QVariant ModelNodeParser::propertyValue(const PropertyName &name) const
|
|||||||
return m_objectNode.instanceValue(name);
|
return m_objectNode.instanceValue(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ModelNodeParser::uuid() const
|
||||||
|
{
|
||||||
|
return m_node.auxiliaryData(Constants::UuidAuxTag).toString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -47,6 +47,7 @@ public:
|
|||||||
const QByteArrayList& lineage() const { return m_lineage; }
|
const QByteArrayList& lineage() const { return m_lineage; }
|
||||||
const QmlObjectNode& objectNode() const { return m_objectNode; }
|
const QmlObjectNode& objectNode() const { return m_objectNode; }
|
||||||
QVariant propertyValue(const PropertyName &name) const;
|
QVariant propertyValue(const PropertyName &name) const;
|
||||||
|
QString uuid() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const ModelNode &m_node;
|
const ModelNode &m_node;
|
||||||
|
@@ -181,6 +181,9 @@ const char addFlowActionToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
|
|||||||
const char fitRootToScreenToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Fit the root element inside the available space.");
|
const char fitRootToScreenToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Fit the root element inside the available space.");
|
||||||
const char fitSelectionToScreenToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Fit the selected elements inside the available space.");
|
const char fitSelectionToScreenToolTip[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Fit the selected elements inside the available space.");
|
||||||
|
|
||||||
|
const char editListModelDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu",
|
||||||
|
"Edit List Model...");
|
||||||
|
|
||||||
const int priorityFirst = 280;
|
const int priorityFirst = 280;
|
||||||
const int prioritySelectionCategory = 220;
|
const int prioritySelectionCategory = 220;
|
||||||
const int priorityQmlPreviewCategory = 200;
|
const int priorityQmlPreviewCategory = 200;
|
||||||
|
@@ -41,10 +41,14 @@
|
|||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
#include <viewmanager.h>
|
#include <viewmanager.h>
|
||||||
|
|
||||||
|
#include <listmodeleditor/listmodeleditordialog.h>
|
||||||
|
#include <listmodeleditor/listmodeleditormodel.h>
|
||||||
|
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QGraphicsLinearLayout>
|
#include <QGraphicsLinearLayout>
|
||||||
|
|
||||||
#include <coreplugin/actionmanager/actionmanager.h>
|
#include <coreplugin/actionmanager/actionmanager.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
#include <utils/utilsicons.h>
|
#include <utils/utilsicons.h>
|
||||||
@@ -335,6 +339,64 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class EditListModelAction final : public ModelNodeContextMenuAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EditListModelAction()
|
||||||
|
: ModelNodeContextMenuAction("EditListModel",
|
||||||
|
ComponentCoreConstants::editListModelDisplayName,
|
||||||
|
{},
|
||||||
|
ComponentCoreConstants::rootCategory,
|
||||||
|
QKeySequence("Alt+e"),
|
||||||
|
1001,
|
||||||
|
&openDialog,
|
||||||
|
&isListViewInBaseState,
|
||||||
|
&isListViewInBaseState)
|
||||||
|
{}
|
||||||
|
|
||||||
|
static bool isListViewInBaseState(const SelectionContext &selectionState)
|
||||||
|
{
|
||||||
|
return selectionState.isInBaseState() && selectionState.singleNodeIsSelected()
|
||||||
|
&& selectionState.currentSingleSelectedNode().metaInfo().isSubclassOf(
|
||||||
|
"QtQuick.ListView");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isEnabled(const SelectionContext &) const override { return true; }
|
||||||
|
|
||||||
|
static ModelNode listModelNode(const ModelNode &listViewNode)
|
||||||
|
{
|
||||||
|
if (listViewNode.hasProperty("model")) {
|
||||||
|
if (listViewNode.hasBindingProperty("model"))
|
||||||
|
return listViewNode.bindingProperty("model").resolveToModelNode();
|
||||||
|
else if (listViewNode.hasNodeProperty("model"))
|
||||||
|
return listViewNode.nodeProperty("model").modelNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelNode newModel = listViewNode.view()->createModelNode("QtQml.Models.ListModel", 2, 15);
|
||||||
|
listViewNode.nodeProperty("mode").reparentHere(newModel);
|
||||||
|
|
||||||
|
return newModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void openDialog(const SelectionContext &selectionState)
|
||||||
|
{
|
||||||
|
ListModelEditorModel model;
|
||||||
|
|
||||||
|
ModelNode targetNode = selectionState.targetNode();
|
||||||
|
if (!targetNode.isValid())
|
||||||
|
targetNode = selectionState.currentSingleSelectedNode();
|
||||||
|
if (!targetNode.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
|
model.setListModel(listModelNode(targetNode));
|
||||||
|
|
||||||
|
ListModelEditorDialog dialog{Core::ICore::mainWindow()};
|
||||||
|
dialog.setModel(&model);
|
||||||
|
|
||||||
|
dialog.exec();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
bool flowOptionVisible(const SelectionContext &context)
|
bool flowOptionVisible(const SelectionContext &context)
|
||||||
{
|
{
|
||||||
return QmlFlowViewNode::isValidQmlFlowViewNode(context.rootNode());
|
return QmlFlowViewNode::isValidQmlFlowViewNode(context.rootNode());
|
||||||
@@ -1217,6 +1279,8 @@ void DesignerActionManager::createDefaultDesignerActions()
|
|||||||
priorityGenericToolBar));
|
priorityGenericToolBar));
|
||||||
|
|
||||||
addDesignerAction(new ChangeStyleAction());
|
addDesignerAction(new ChangeStyleAction());
|
||||||
|
|
||||||
|
addDesignerAction(new EditListModelAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerActionManager::createDefaultAddResourceHandler()
|
void DesignerActionManager::createDefaultAddResourceHandler()
|
||||||
|
@@ -0,0 +1,7 @@
|
|||||||
|
SOURCES += \
|
||||||
|
$$PWD/listmodeleditordialog.cpp \
|
||||||
|
$$PWD/listmodeleditormodel.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/listmodeleditordialog.h \
|
||||||
|
$$PWD/listmodeleditormodel.h
|
@@ -0,0 +1,165 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 "listmodeleditordialog.h"
|
||||||
|
#include "listmodeleditormodel.h"
|
||||||
|
|
||||||
|
#include <theme.h>
|
||||||
|
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
#include <utils/stylehelper.h>
|
||||||
|
|
||||||
|
#include <QHeaderView>
|
||||||
|
#include <QInputDialog>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QTableView>
|
||||||
|
#include <QToolBar>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
QIcon getIcon(Theme::Icon icon)
|
||||||
|
{
|
||||||
|
const QString fontName = "qtds_propertyIconFont.ttf";
|
||||||
|
|
||||||
|
return Utils::StyleHelper::getIconFromIconFont(fontName, Theme::getIconUnicode(icon), 30, 30);
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
ListModelEditorDialog::ListModelEditorDialog(QWidget *parent)
|
||||||
|
: QDialog(parent)
|
||||||
|
{
|
||||||
|
resize((Core::ICore::mainWindow()->size() * 8) / 10);
|
||||||
|
|
||||||
|
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||||
|
|
||||||
|
QToolBar *toolBar = new QToolBar();
|
||||||
|
toolBar->setIconSize({30, 30});
|
||||||
|
mainLayout->addWidget(toolBar);
|
||||||
|
m_tableView = new QTableView;
|
||||||
|
mainLayout->addWidget(m_tableView);
|
||||||
|
|
||||||
|
m_addRowAction = toolBar->addAction(getIcon(Theme::Icon::addRowAfter), tr("Add Row"));
|
||||||
|
m_removeRowsAction = toolBar->addAction(getIcon(Theme::Icon::deleteRow), tr("Remove Columns"));
|
||||||
|
m_addColumnAction = toolBar->addAction(getIcon(Theme::Icon::addColumnAfter), tr("Add Column"));
|
||||||
|
m_removeColumnsAction = toolBar->addAction(getIcon(Theme::Icon::deleteColumn),
|
||||||
|
tr("Remove Columns"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ListModelEditorDialog::~ListModelEditorDialog() = default;
|
||||||
|
|
||||||
|
void ListModelEditorDialog::setModel(ListModelEditorModel *model)
|
||||||
|
{
|
||||||
|
m_model = model;
|
||||||
|
|
||||||
|
connect(m_addRowAction, &QAction::triggered, m_model, &ListModelEditorModel::addRow);
|
||||||
|
connect(m_addColumnAction, &QAction::triggered, this, &ListModelEditorDialog::openColumnDialog);
|
||||||
|
connect(m_removeRowsAction, &QAction::triggered, this, &ListModelEditorDialog::removeRows);
|
||||||
|
connect(m_removeColumnsAction, &QAction::triggered, this, &ListModelEditorDialog::removeColumns);
|
||||||
|
connect(m_tableView->horizontalHeader(),
|
||||||
|
&QHeaderView::sectionDoubleClicked,
|
||||||
|
this,
|
||||||
|
&ListModelEditorDialog::changeHeader);
|
||||||
|
|
||||||
|
m_tableView->setModel(model);
|
||||||
|
m_tableView->horizontalHeader()->setMinimumSectionSize(60);
|
||||||
|
m_tableView->verticalHeader()->setMinimumSectionSize(25);
|
||||||
|
m_tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||||
|
m_tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListModelEditorDialog::keyPressEvent(QKeyEvent *event)
|
||||||
|
{
|
||||||
|
if (event->key() == Qt::Key_Backspace || event->key() == Qt::Key_Delete) {
|
||||||
|
for (const QModelIndex index : m_tableView->selectionModel()->selectedIndexes())
|
||||||
|
m_model->setData(index, QVariant(), Qt::EditRole);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListModelEditorDialog::openColumnDialog()
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
QString columnName = QInputDialog::getText(
|
||||||
|
this, tr("Add Property"), tr("Property Name:"), QLineEdit::Normal, "", &ok);
|
||||||
|
if (ok && !columnName.isEmpty())
|
||||||
|
m_model->addColumn(columnName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListModelEditorDialog::removeRows()
|
||||||
|
{
|
||||||
|
const QList<QModelIndex> indices = m_tableView->selectionModel()->selectedRows();
|
||||||
|
std::vector<int> rows;
|
||||||
|
rows.reserve(indices.size());
|
||||||
|
|
||||||
|
for (QModelIndex index : indices)
|
||||||
|
rows.push_back(index.row());
|
||||||
|
|
||||||
|
std::sort(rows.begin(), rows.end());
|
||||||
|
|
||||||
|
rows.erase(std::unique(rows.begin(), rows.end()), rows.end());
|
||||||
|
|
||||||
|
std::reverse(rows.begin(), rows.end());
|
||||||
|
|
||||||
|
for (int row : rows)
|
||||||
|
m_model->removeRow(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListModelEditorDialog::removeColumns()
|
||||||
|
{
|
||||||
|
const QList<QModelIndex> indices = m_tableView->selectionModel()->selectedColumns();
|
||||||
|
std::vector<int> columns;
|
||||||
|
columns.reserve(indices.size());
|
||||||
|
|
||||||
|
for (QModelIndex index : indices)
|
||||||
|
columns.push_back(index.column());
|
||||||
|
|
||||||
|
std::sort(columns.begin(), columns.end());
|
||||||
|
|
||||||
|
columns.erase(std::unique(columns.begin(), columns.end()), columns.end());
|
||||||
|
|
||||||
|
std::reverse(columns.begin(), columns.end());
|
||||||
|
|
||||||
|
for (int row : columns)
|
||||||
|
m_model->removeColumn(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListModelEditorDialog::changeHeader(int column)
|
||||||
|
{
|
||||||
|
const QString propertyName = QString::fromUtf8(m_model->propertyNames()[column]);
|
||||||
|
|
||||||
|
bool ok;
|
||||||
|
QString newPropertyName = QInputDialog::getText(
|
||||||
|
this, tr("Change Propertry"), tr("Column Name:"), QLineEdit::Normal, propertyName, &ok);
|
||||||
|
|
||||||
|
if (ok && !newPropertyName.isEmpty())
|
||||||
|
m_model->renameColumn(column, newPropertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,72 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 <QDialog>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QAbstractItemModel;
|
||||||
|
class QTableView;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ListModelEditorDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class ListModelEditorModel;
|
||||||
|
|
||||||
|
class ListModelEditorDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ListModelEditorDialog(QWidget *parent = nullptr);
|
||||||
|
~ListModelEditorDialog();
|
||||||
|
|
||||||
|
void setModel(ListModelEditorModel *model);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void keyPressEvent(QKeyEvent *) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void addRow();
|
||||||
|
void openColumnDialog();
|
||||||
|
void removeRows();
|
||||||
|
void removeColumns();
|
||||||
|
void changeHeader(int column);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ListModelEditorModel *m_model{};
|
||||||
|
QAction *m_addRowAction{};
|
||||||
|
QAction *m_removeRowsAction{};
|
||||||
|
QAction *m_addColumnAction{};
|
||||||
|
QAction *m_removeColumnsAction{};
|
||||||
|
QTableView *m_tableView{};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,302 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 "listmodeleditormodel.h"
|
||||||
|
|
||||||
|
#include <abstractview.h>
|
||||||
|
#include <nodelistproperty.h>
|
||||||
|
#include <variantproperty.h>
|
||||||
|
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class ListModelItem : public QStandardItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ListModelItem(ModelNode node, PropertyName propertyName)
|
||||||
|
: node(std::move(node))
|
||||||
|
, propertyName(propertyName)
|
||||||
|
{
|
||||||
|
setEditable(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant maybeConvertToNumber(const QVariant &value)
|
||||||
|
{
|
||||||
|
bool canConvert = false;
|
||||||
|
double convertedValue = value.toDouble(&canConvert);
|
||||||
|
if (canConvert) {
|
||||||
|
return convertedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant data(int role) const override
|
||||||
|
{
|
||||||
|
if (role == Qt::BackgroundColorRole && hasInvalidValue)
|
||||||
|
return QColor{Qt::darkYellow};
|
||||||
|
|
||||||
|
return QStandardItem::data(role);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setData(const QVariant &value, int role) override
|
||||||
|
{
|
||||||
|
if (role == Qt::DisplayRole || role == Qt::EditRole)
|
||||||
|
hasInvalidValue = !value.isValid();
|
||||||
|
|
||||||
|
if (role == Qt::EditRole) {
|
||||||
|
const QVariant &convertedValue = maybeConvertToNumber(value);
|
||||||
|
QStandardItem::setData(convertedValue, role);
|
||||||
|
if (value.isValid())
|
||||||
|
node.variantProperty(propertyName).setValue(convertedValue);
|
||||||
|
else
|
||||||
|
node.removeProperty(propertyName);
|
||||||
|
} else {
|
||||||
|
QStandardItem::setData(value, role);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeProperty() { node.removeProperty(propertyName); }
|
||||||
|
|
||||||
|
void renameProperty(const PropertyName &newPropertyName)
|
||||||
|
{
|
||||||
|
if (node.hasProperty(propertyName)) {
|
||||||
|
node.removeProperty(propertyName);
|
||||||
|
node.variantProperty(newPropertyName).setValue(data(Qt::EditRole));
|
||||||
|
}
|
||||||
|
propertyName = newPropertyName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
ModelNode node;
|
||||||
|
PropertyName propertyName;
|
||||||
|
bool hasInvalidValue = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
QList<PropertyName> getPropertyNames(const ModelNode &listElementNode)
|
||||||
|
{
|
||||||
|
auto properties = listElementNode.variantProperties();
|
||||||
|
|
||||||
|
QList<PropertyName> names;
|
||||||
|
names.reserve(properties.size());
|
||||||
|
|
||||||
|
for (const auto &property : properties)
|
||||||
|
names.push_back(property.name());
|
||||||
|
|
||||||
|
std::sort(names.begin(), names.end());
|
||||||
|
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<PropertyName> mergeProperyNames(const QList<PropertyName> &first,
|
||||||
|
const QList<PropertyName> &second)
|
||||||
|
{
|
||||||
|
QList<PropertyName> merged;
|
||||||
|
merged.reserve(first.size() + second.size());
|
||||||
|
|
||||||
|
std::set_union(first.begin(),
|
||||||
|
first.end(),
|
||||||
|
second.begin(),
|
||||||
|
second.end(),
|
||||||
|
std::back_inserter(merged));
|
||||||
|
|
||||||
|
return merged;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ListModelItem> createItem(const ModelNode &listElementNode,
|
||||||
|
const PropertyName &propertyName)
|
||||||
|
{
|
||||||
|
auto item = std::make_unique<ListModelItem>(listElementNode, propertyName);
|
||||||
|
|
||||||
|
QVariant value = listElementNode.variantProperty(propertyName).value();
|
||||||
|
|
||||||
|
item->setData(value, Qt::DisplayRole);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QString> convertToStringList(const QList<PropertyName> &propertyNames)
|
||||||
|
{
|
||||||
|
QList<QString> names;
|
||||||
|
names.reserve(propertyNames.size());
|
||||||
|
|
||||||
|
for (const auto &propertyName : propertyNames)
|
||||||
|
names.push_back(QString::fromUtf8(propertyName));
|
||||||
|
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<PropertyName> createProperyNames(const QList<ModelNode> &listElementNodes)
|
||||||
|
{
|
||||||
|
QList<PropertyName> propertyNames;
|
||||||
|
propertyNames.reserve(10);
|
||||||
|
|
||||||
|
for (const ModelNode &listElementNode : listElementNodes)
|
||||||
|
propertyNames = mergeProperyNames(getPropertyNames(listElementNode), propertyNames);
|
||||||
|
|
||||||
|
return propertyNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QStandardItem *> createColumnItems(const ModelNode &listModelNode,
|
||||||
|
const PropertyName &propertyName)
|
||||||
|
{
|
||||||
|
QList<QStandardItem *> items;
|
||||||
|
const auto listElementNodes = listModelNode.defaultNodeListProperty().toModelNodeList();
|
||||||
|
|
||||||
|
for (const ModelNode &listElementNode : listElementNodes)
|
||||||
|
items.push_back(createItem(listElementNode, propertyName).release());
|
||||||
|
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
void renameProperties(const QStandardItemModel *model,
|
||||||
|
int columnIndex,
|
||||||
|
const PropertyName &newPropertyName)
|
||||||
|
{
|
||||||
|
for (int rowIndex = 0; rowIndex < model->rowCount(); ++rowIndex)
|
||||||
|
static_cast<ListModelItem *>(model->item(rowIndex, columnIndex))->renameProperty(newPropertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void ListModelEditorModel::populateModel()
|
||||||
|
{
|
||||||
|
const auto listElementNodes = m_listModelNode.defaultNodeListProperty().toModelNodeList();
|
||||||
|
|
||||||
|
m_propertyNames = createProperyNames(listElementNodes);
|
||||||
|
|
||||||
|
setHorizontalHeaderLabels(convertToStringList(m_propertyNames));
|
||||||
|
|
||||||
|
createItems(listElementNodes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListModelEditorModel::createItems(const QList<ModelNode> &listElementNodes)
|
||||||
|
{
|
||||||
|
for (const ModelNode &listElementNode : listElementNodes)
|
||||||
|
appendItems(listElementNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListModelEditorModel::appendItems(const ModelNode &listElementNode)
|
||||||
|
{
|
||||||
|
QList<QStandardItem *> row;
|
||||||
|
row.reserve(m_propertyNames.size());
|
||||||
|
for (const PropertyName &propertyName : propertyNames())
|
||||||
|
row.push_back(createItem(listElementNode, propertyName).release());
|
||||||
|
|
||||||
|
appendRow(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListModelEditorModel::addRow()
|
||||||
|
{
|
||||||
|
auto newElement = m_listModelNode.view()->createModelNode("QtQml.Models.ListElement", 2, 15);
|
||||||
|
m_listModelNode.defaultNodeListProperty().reparentHere(newElement);
|
||||||
|
|
||||||
|
appendItems(newElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListModelEditorModel::addColumn(const QString &columnName)
|
||||||
|
{
|
||||||
|
PropertyName propertyName = columnName.toUtf8();
|
||||||
|
|
||||||
|
auto found = std::lower_bound(m_propertyNames.begin(), m_propertyNames.end(), propertyName);
|
||||||
|
|
||||||
|
if (found != m_propertyNames.end() && *found == columnName)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int newIndex = static_cast<int>(std::distance(m_propertyNames.begin(), found));
|
||||||
|
|
||||||
|
m_propertyNames.insert(found, propertyName);
|
||||||
|
|
||||||
|
insertColumn(newIndex, createColumnItems(m_listModelNode, propertyName));
|
||||||
|
|
||||||
|
setHorizontalHeaderItem(newIndex, new QStandardItem(columnName));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ListModelEditorModel::setValue(int row, int column, QVariant value, Qt::ItemDataRole role)
|
||||||
|
{
|
||||||
|
QModelIndex index = createIndex(row, column, invisibleRootItem());
|
||||||
|
bool success = setData(index, value, role);
|
||||||
|
emit dataChanged(index, index);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListModelEditorModel::removeColumn(int column)
|
||||||
|
{
|
||||||
|
QList<QStandardItem *> columnItems = QStandardItemModel::takeColumn(column);
|
||||||
|
m_propertyNames.removeAt(column);
|
||||||
|
|
||||||
|
for (QStandardItem *columnItem : columnItems) {
|
||||||
|
static_cast<ListModelItem *>(columnItem)->removeProperty();
|
||||||
|
delete columnItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListModelEditorModel::removeRow(int row)
|
||||||
|
{
|
||||||
|
QList<QStandardItem *> rowItems = QStandardItemModel::takeRow(row);
|
||||||
|
|
||||||
|
if (rowItems.size())
|
||||||
|
static_cast<ListModelItem *>(rowItems.front())->node.destroy();
|
||||||
|
|
||||||
|
qDeleteAll(rowItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListModelEditorModel::renameColumn(int oldColumn, const QString &newColumnName)
|
||||||
|
{
|
||||||
|
const PropertyName newPropertyName = newColumnName.toUtf8();
|
||||||
|
|
||||||
|
auto found = std::lower_bound(m_propertyNames.begin(), m_propertyNames.end(), newPropertyName);
|
||||||
|
|
||||||
|
if (found != m_propertyNames.end() && *found == newPropertyName)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int newColumn = static_cast<int>(std::distance(m_propertyNames.begin(), found));
|
||||||
|
|
||||||
|
if (oldColumn == newColumn) {
|
||||||
|
*found = newPropertyName;
|
||||||
|
renameProperties(this, newColumn, newPropertyName);
|
||||||
|
} else if (newColumn < oldColumn) {
|
||||||
|
m_propertyNames.insert(found, newPropertyName);
|
||||||
|
m_propertyNames.erase(std::next(m_propertyNames.begin(), oldColumn + 1));
|
||||||
|
insertColumn(newColumn, takeColumn(oldColumn));
|
||||||
|
renameProperties(this, newColumn, newPropertyName);
|
||||||
|
} else {
|
||||||
|
m_propertyNames.insert(found, newPropertyName);
|
||||||
|
m_propertyNames.erase(std::next(m_propertyNames.begin(), oldColumn));
|
||||||
|
insertColumn(newColumn - 1, takeColumn(oldColumn));
|
||||||
|
renameProperties(this, newColumn - 1, newPropertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
setHorizontalHeaderLabels(convertToStringList(m_propertyNames));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,65 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 <modelnode.h>
|
||||||
|
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class ListModelEditorModel : public QStandardItemModel
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
void setListModel(ModelNode node)
|
||||||
|
{
|
||||||
|
m_listModelNode = node;
|
||||||
|
populateModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void addRow();
|
||||||
|
void addColumn(const QString &columnName);
|
||||||
|
|
||||||
|
const QList<QmlDesigner::PropertyName> &propertyNames() const { return m_propertyNames; }
|
||||||
|
|
||||||
|
bool setValue(int row, int column, QVariant value, Qt::ItemDataRole role = Qt::EditRole);
|
||||||
|
|
||||||
|
void removeColumn(int column);
|
||||||
|
void removeRow(int row);
|
||||||
|
void renameColumn(int column, const QString &newColumnName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void populateModel();
|
||||||
|
void createItems(const QList<ModelNode> &listElementNodes);
|
||||||
|
void appendItems(const ModelNode &listElementNode);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ModelNode m_listModelNode;
|
||||||
|
QList<QmlDesigner::PropertyName> m_propertyNames;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -34,8 +34,8 @@
|
|||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
|
||||||
#include <coreplugin/messagebox.h>
|
|
||||||
#ifndef QMLDESIGNER_TEST
|
#ifndef QMLDESIGNER_TEST
|
||||||
|
#include <coreplugin/messagebox.h>
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -160,8 +160,12 @@ QString Exception::description() const
|
|||||||
*/
|
*/
|
||||||
void Exception::showException(const QString &title) const
|
void Exception::showException(const QString &title) const
|
||||||
{
|
{
|
||||||
QString composedTitle = title.isEmpty() ? QCoreApplication::translate("QmlDesigner", "Error") : title;
|
Q_UNUSED(title)
|
||||||
|
#ifndef QMLDESIGNER_TEST
|
||||||
|
QString composedTitle = title.isEmpty() ? QCoreApplication::translate("QmlDesigner", "Error")
|
||||||
|
: title;
|
||||||
Core::AsynchronousMessageBox::warning(composedTitle, description());
|
Core::AsynchronousMessageBox::warning(composedTitle, description());
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@@ -1,2 +1,14 @@
|
|||||||
SOURCES += $$PWD/exception.cpp
|
SOURCES += $$PWD/exception.cpp \
|
||||||
SOURCES += $$PWD/invalidnodeinstanceexception.cpp
|
$$PWD/invalidargumentexception.cpp \
|
||||||
|
$$PWD/invalididexception.cpp \
|
||||||
|
$$PWD/invalidmetainfoexception.cpp \
|
||||||
|
$$PWD/invalidmodelnodeexception.cpp \
|
||||||
|
$$PWD/invalidmodelstateexception.cpp \
|
||||||
|
$$PWD/invalidpropertyexception.cpp \
|
||||||
|
$$PWD/invalidqmlsourceexception.cpp \
|
||||||
|
$$PWD/invalidreparentingexception.cpp \
|
||||||
|
$$PWD/invalidslideindexexception.cpp \
|
||||||
|
$$PWD/notimplementedexception.cpp \
|
||||||
|
$$PWD/removebasestateexception.cpp \
|
||||||
|
$$PWD/rewritingexception.cpp
|
||||||
|
|
||||||
|
@@ -91,9 +91,12 @@ public:
|
|||||||
ModelNode(const Internal::InternalNodePointer &internalNode, Model *model, const AbstractView *view);
|
ModelNode(const Internal::InternalNodePointer &internalNode, Model *model, const AbstractView *view);
|
||||||
ModelNode(const ModelNode &modelNode, AbstractView *view);
|
ModelNode(const ModelNode &modelNode, AbstractView *view);
|
||||||
ModelNode(const ModelNode &other);
|
ModelNode(const ModelNode &other);
|
||||||
|
ModelNode(ModelNode &&other);
|
||||||
~ModelNode();
|
~ModelNode();
|
||||||
|
|
||||||
ModelNode &operator=(const ModelNode &other);
|
ModelNode &operator=(const ModelNode &other);
|
||||||
|
ModelNode &operator=(ModelNode &&other);
|
||||||
|
|
||||||
TypeName type() const;
|
TypeName type() const;
|
||||||
QString simplifiedTypeName() const;
|
QString simplifiedTypeName() const;
|
||||||
QString displayName() const;
|
QString displayName() const;
|
||||||
@@ -226,6 +229,15 @@ public:
|
|||||||
bool isSubclassOf(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1) const;
|
bool isSubclassOf(const TypeName &typeName, int majorVersion = -1, int minorVersion = -1) const;
|
||||||
QIcon typeIcon() const;
|
QIcon typeIcon() const;
|
||||||
|
|
||||||
|
friend void swap(ModelNode &first, ModelNode &second)
|
||||||
|
{
|
||||||
|
using std::swap;
|
||||||
|
|
||||||
|
swap(first.m_internalNode, second.m_internalNode);
|
||||||
|
swap(first.m_model, second.m_model);
|
||||||
|
swap(first.m_view, second.m_view);
|
||||||
|
}
|
||||||
|
|
||||||
private: // functions
|
private: // functions
|
||||||
Internal::InternalNodePointer internalNode() const;
|
Internal::InternalNodePointer internalNode() const;
|
||||||
|
|
||||||
|
@@ -32,9 +32,12 @@
|
|||||||
|
|
||||||
#if defined(DESIGNER_CORE_LIBRARY)
|
#if defined(DESIGNER_CORE_LIBRARY)
|
||||||
#define QMLDESIGNERCORE_EXPORT Q_DECL_EXPORT
|
#define QMLDESIGNERCORE_EXPORT Q_DECL_EXPORT
|
||||||
|
#elif defined(DESIGNER_STATIC_CORE_LIBRARY)
|
||||||
|
#define QMLDESIGNERCORE_EXPORT
|
||||||
#else
|
#else
|
||||||
#define QMLDESIGNERCORE_EXPORT Q_DECL_IMPORT
|
#define QMLDESIGNERCORE_EXPORT Q_DECL_IMPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
using PropertyName = QByteArray;
|
using PropertyName = QByteArray;
|
||||||
using PropertyNameList = QList<PropertyName>;
|
using PropertyNameList = QList<PropertyName>;
|
||||||
|
@@ -42,6 +42,7 @@
|
|||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
|
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
|
#include <QWidget>
|
||||||
#include <QtGui/qimage.h>
|
#include <QtGui/qimage.h>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
@@ -93,7 +93,25 @@ ModelNode::ModelNode(const ModelNode &modelNode, AbstractView *view)
|
|||||||
m_model(modelNode.model()),
|
m_model(modelNode.model()),
|
||||||
m_view(view)
|
m_view(view)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelNode::ModelNode(ModelNode &&other)
|
||||||
|
: m_internalNode(std::move(other.m_internalNode))
|
||||||
|
, m_model(std::move(other.m_model))
|
||||||
|
, m_view(std::move(other.m_view))
|
||||||
|
{
|
||||||
|
other.m_model = {};
|
||||||
|
other.m_view = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelNode &ModelNode::operator=(ModelNode &&other)
|
||||||
|
{
|
||||||
|
ModelNode newNode;
|
||||||
|
|
||||||
|
swap(other, newNode);
|
||||||
|
swap(*this, newNode);
|
||||||
|
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief contructs a invalid model node
|
/*! \brief contructs a invalid model node
|
||||||
@@ -103,7 +121,6 @@ ModelNode::ModelNode(const ModelNode &modelNode, AbstractView *view)
|
|||||||
ModelNode::ModelNode():
|
ModelNode::ModelNode():
|
||||||
m_internalNode(new InternalNode)
|
m_internalNode(new InternalNode)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelNode::ModelNode(const ModelNode &other) = default;
|
ModelNode::ModelNode(const ModelNode &other) = default;
|
||||||
|
@@ -33,7 +33,7 @@ include(components/bindingeditor/bindingeditor.pri)
|
|||||||
include(components/annotationeditor/annotationeditor.pri)
|
include(components/annotationeditor/annotationeditor.pri)
|
||||||
include(components/richtexteditor/richtexteditor.pri)
|
include(components/richtexteditor/richtexteditor.pri)
|
||||||
include(components/transitioneditor/transitioneditor.pri)
|
include(components/transitioneditor/transitioneditor.pri)
|
||||||
|
include(components/listmodeleditor/listmodeleditor.pri)
|
||||||
|
|
||||||
BUILD_PUPPET_IN_CREATOR_BINPATH = $$(BUILD_PUPPET_IN_CREATOR_BINPATH)
|
BUILD_PUPPET_IN_CREATOR_BINPATH = $$(BUILD_PUPPET_IN_CREATOR_BINPATH)
|
||||||
!isEmpty(BUILD_PUPPET_IN_CREATOR_BINPATH) {
|
!isEmpty(BUILD_PUPPET_IN_CREATOR_BINPATH) {
|
||||||
|
@@ -59,6 +59,7 @@ Project {
|
|||||||
"components/stateseditor",
|
"components/stateseditor",
|
||||||
"components/texteditor",
|
"components/texteditor",
|
||||||
"components/timelineeditor",
|
"components/timelineeditor",
|
||||||
|
"compenents/listmodeleditor",
|
||||||
])
|
])
|
||||||
|
|
||||||
Properties {
|
Properties {
|
||||||
@@ -845,6 +846,10 @@ Project {
|
|||||||
"timelineeditor/timelineview.h",
|
"timelineeditor/timelineview.h",
|
||||||
"timelineeditor/timelinewidget.cpp",
|
"timelineeditor/timelinewidget.cpp",
|
||||||
"timelineeditor/timelinewidget.h",
|
"timelineeditor/timelinewidget.h",
|
||||||
|
"listmodeleditor/listmodeleditordialog.cpp ",
|
||||||
|
"listmodeleditor/listmodeleditordialog.h ",
|
||||||
|
"listmodeleditor/listmodeleditormodel.cpp ",
|
||||||
|
"listmodeleditor/listmodeleditordialog.h ",
|
||||||
"transitioneditor/transitioneditorview.cpp",
|
"transitioneditor/transitioneditorview.cpp",
|
||||||
"transitioneditor/transitioneditorview.h",
|
"transitioneditor/transitioneditorview.h",
|
||||||
"transitioneditor/transitioneditorwidget.cpp",
|
"transitioneditor/transitioneditorwidget.cpp",
|
||||||
|
59
src/plugins/qmldesigner/qmldesignerunittestfiles.pri
Normal file
59
src/plugins/qmldesigner/qmldesignerunittestfiles.pri
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
INCLUDEPATH += $$PWD
|
||||||
|
INCLUDEPATH += $$PWD/designercore/include
|
||||||
|
INCLUDEPATH += $$PWD/designercore
|
||||||
|
INCLUDEPATH += $$PWD/../../../share/qtcreator/qml/qmlpuppet/interfaces
|
||||||
|
INCLUDEPATH += $$PWD/../../../share/qtcreator/qml/qmlpuppet/types
|
||||||
|
|
||||||
|
DEFINES += QMLDESIGNER_TEST DESIGNER_STATIC_CORE_LIBRARY
|
||||||
|
|
||||||
|
include($$PWD/designercore/exceptions/exceptions.pri)
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/designercore/model/model.cpp \
|
||||||
|
$$PWD/designercore/model/modelnode.cpp \
|
||||||
|
$$PWD/designercore/model/import.cpp \
|
||||||
|
$$PWD/designercore/model/abstractproperty.cpp \
|
||||||
|
$$PWD/designercore/model/abstractview.cpp \
|
||||||
|
$$PWD/designercore/model/internalproperty.cpp \
|
||||||
|
$$PWD/designercore/model/internalbindingproperty.cpp \
|
||||||
|
$$PWD/designercore/model/internalnodeabstractproperty.cpp \
|
||||||
|
$$PWD/designercore/model/internalnodelistproperty.cpp \
|
||||||
|
$$PWD/designercore/model/internalnodeproperty.cpp \
|
||||||
|
$$PWD/designercore/model/internalsignalhandlerproperty.cpp \
|
||||||
|
$$PWD/designercore/model/internalnode.cpp \
|
||||||
|
$$PWD/designercore/model/internalvariantproperty.cpp \
|
||||||
|
$$PWD/designercore/model/bindingproperty.cpp \
|
||||||
|
$$PWD/designercore/model/nodeabstractproperty.cpp \
|
||||||
|
$$PWD/designercore/model/nodelistproperty.cpp \
|
||||||
|
$$PWD/designercore/model/nodeproperty.cpp \
|
||||||
|
$$PWD/designercore/model/signalhandlerproperty.cpp \
|
||||||
|
$$PWD/designercore/model/variantproperty.cpp\
|
||||||
|
$$PWD/designercore/model/annotation.cpp \
|
||||||
|
$$PWD/designercore/rewritertransaction.cpp \
|
||||||
|
$$PWD/components/listmodeleditor/listmodeleditormodel.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/designercore/include/modelnode.h \
|
||||||
|
$$PWD/designercore/include/model.h \
|
||||||
|
$$PWD/../../../share/qtcreator/qml/qmlpuppet/interfaces/commondefines.h \
|
||||||
|
$$PWD/designercore/include/import.h \
|
||||||
|
$$PWD/designercore/include/abstractproperty.h \
|
||||||
|
$$PWD/designercore/include/abstractview.h \
|
||||||
|
$$PWD/designercore/model/model_p.h \
|
||||||
|
$$PWD/designercore/include/qmldesignercorelib_global.h \
|
||||||
|
$$PWD/designercore/model/internalbindingproperty.h \
|
||||||
|
$$PWD/designercore/model/internalnode_p.h \
|
||||||
|
$$PWD/designercore/model/internalnodeabstractproperty.h \
|
||||||
|
$$PWD/designercore/model/internalnodelistproperty.h \
|
||||||
|
$$PWD/designercore/model/internalnodeproperty.h \
|
||||||
|
$$PWD/designercore/model/internalproperty.h \
|
||||||
|
$$PWD/designercore/model/internalsignalhandlerproperty.h \
|
||||||
|
$$PWD/designercore/model/internalvariantproperty.h \
|
||||||
|
$$PWD/designercore/include/bindingproperty.h \
|
||||||
|
$$PWD/designercore/include/nodeabstractproperty.h \
|
||||||
|
$$PWD/designercore/include/nodelistproperty.h \
|
||||||
|
$$PWD/designercore/include/nodeproperty.h \
|
||||||
|
$$PWD/designercore/include/signalhandlerproperty.h \
|
||||||
|
$$PWD/designercore/include/variantproperty.h \
|
||||||
|
$$PWD/designercore/rewritertransaction.h \
|
||||||
|
$$PWD/components/listmodeleditor/listmodeleditormodel.h
|
@@ -213,7 +213,9 @@ struct Data // because we have a cycle dependency
|
|||||||
pchCreationProgressCounter,
|
pchCreationProgressCounter,
|
||||||
preCompiledHeaderStorage,
|
preCompiledHeaderStorage,
|
||||||
database,
|
database,
|
||||||
environment};
|
environment,
|
||||||
|
fileSystem,
|
||||||
|
filePathCache};
|
||||||
ClangBackEnd::PchTasksMerger pchTaskMerger{pchTaskQueue};
|
ClangBackEnd::PchTasksMerger pchTaskMerger{pchTaskQueue};
|
||||||
ClangBackEnd::BuildDependenciesStorage<> buildDependencyStorage{database};
|
ClangBackEnd::BuildDependenciesStorage<> buildDependencyStorage{database};
|
||||||
ClangBackEnd::BuildDependencyCollector buildDependencyCollector{filePathCache,
|
ClangBackEnd::BuildDependencyCollector buildDependencyCollector{filePathCache,
|
||||||
|
@@ -60,7 +60,6 @@ public:
|
|||||||
diagnosticConsumer);
|
diagnosticConsumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR >= 10
|
|
||||||
std::unique_ptr<clang::FrontendAction> create() override
|
std::unique_ptr<clang::FrontendAction> create() override
|
||||||
{
|
{
|
||||||
return std::make_unique<CollectBuildDependencyAction>(
|
return std::make_unique<CollectBuildDependencyAction>(
|
||||||
@@ -69,15 +68,6 @@ public:
|
|||||||
m_excludedIncludeUIDs,
|
m_excludedIncludeUIDs,
|
||||||
m_alreadyIncludedFileUIDs);
|
m_alreadyIncludedFileUIDs);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
clang::FrontendAction *create() override
|
|
||||||
{
|
|
||||||
return new CollectBuildDependencyAction(m_buildDependency,
|
|
||||||
m_filePathCache,
|
|
||||||
m_excludedIncludeUIDs,
|
|
||||||
m_alreadyIncludedFileUIDs);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
std::vector<uint> generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const
|
std::vector<uint> generateExcludedIncludeFileUIDs(clang::FileManager &fileManager) const
|
||||||
{
|
{
|
||||||
@@ -86,16 +76,12 @@ public:
|
|||||||
|
|
||||||
for (const FilePath &filePath : m_excludedFilePaths) {
|
for (const FilePath &filePath : m_excludedFilePaths) {
|
||||||
NativeFilePath nativeFilePath{filePath};
|
NativeFilePath nativeFilePath{filePath};
|
||||||
const clang::FileEntry *file = fileManager.getFile({nativeFilePath.path().data(),
|
auto file = fileManager.getFile({nativeFilePath.path().data(),
|
||||||
nativeFilePath.path().size()},
|
nativeFilePath.path().size()},
|
||||||
true)
|
true);
|
||||||
#if LLVM_VERSION_MAJOR >= 10
|
|
||||||
.get()
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
|
|
||||||
if (file)
|
if (file)
|
||||||
fileUIDs.push_back(file->getUID());
|
fileUIDs.push_back(file.get()->getUID());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(fileUIDs.begin(), fileUIDs.end());
|
std::sort(fileUIDs.begin(), fileUIDs.end());
|
||||||
|
@@ -61,7 +61,6 @@ public:
|
|||||||
diagnosticConsumer);
|
diagnosticConsumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR >= 10
|
|
||||||
std::unique_ptr<clang::FrontendAction> create() override
|
std::unique_ptr<clang::FrontendAction> create() override
|
||||||
{
|
{
|
||||||
return std::make_unique<CollectUsedMacrosAction>(
|
return std::make_unique<CollectUsedMacrosAction>(
|
||||||
@@ -71,16 +70,6 @@ public:
|
|||||||
m_sourceFiles,
|
m_sourceFiles,
|
||||||
m_fileStatuses);
|
m_fileStatuses);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
clang::FrontendAction *create() override
|
|
||||||
{
|
|
||||||
return new CollectUsedMacrosAction(m_usedMacros,
|
|
||||||
m_filePathCache,
|
|
||||||
m_sourceDependencies,
|
|
||||||
m_sourceFiles,
|
|
||||||
m_fileStatuses);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UsedMacros &m_usedMacros;
|
UsedMacros &m_usedMacros;
|
||||||
|
@@ -203,10 +203,8 @@ public:
|
|||||||
const clang::FileEntry *file,
|
const clang::FileEntry *file,
|
||||||
llvm::StringRef /*searchPath*/,
|
llvm::StringRef /*searchPath*/,
|
||||||
llvm::StringRef /*relativePath*/,
|
llvm::StringRef /*relativePath*/,
|
||||||
const clang::Module * /*imported*/
|
const clang::Module * /*imported*/,
|
||||||
#if LLVM_VERSION_MAJOR >= 7
|
clang::SrcMgr::CharacteristicKind /*fileType*/
|
||||||
, clang::SrcMgr::CharacteristicKind /*fileType*/
|
|
||||||
#endif
|
|
||||||
) override
|
) override
|
||||||
{
|
{
|
||||||
if (!m_skipInclude && file)
|
if (!m_skipInclude && file)
|
||||||
|
@@ -68,17 +68,10 @@ public:
|
|||||||
, m_fileContent(fileContent)
|
, m_fileContent(fileContent)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR >= 10
|
|
||||||
std::unique_ptr<clang::FrontendAction> create() override
|
std::unique_ptr<clang::FrontendAction> create() override
|
||||||
{
|
{
|
||||||
return std::make_unique<GeneratePCHAction>(m_filePath, m_fileContent);
|
return std::make_unique<GeneratePCHAction>(m_filePath, m_fileContent);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
clang::FrontendAction *create() override
|
|
||||||
{
|
|
||||||
return new GeneratePCHAction{m_filePath, m_fileContent};
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
llvm::StringRef m_filePath;
|
llvm::StringRef m_filePath;
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
#include "pchtaskqueue.h"
|
#include "pchtaskqueue.h"
|
||||||
|
|
||||||
#include <environment.h>
|
#include <environment.h>
|
||||||
|
#include <filepathcaching.h>
|
||||||
|
#include <filesystem.h>
|
||||||
#include <pchcreatorinterface.h>
|
#include <pchcreatorinterface.h>
|
||||||
#include <precompiledheaderstorageinterface.h>
|
#include <precompiledheaderstorageinterface.h>
|
||||||
#include <progresscounter.h>
|
#include <progresscounter.h>
|
||||||
@@ -107,36 +109,67 @@ void PchTaskQueue::removePchTasks(const ProjectPartIds &projectsPartIds)
|
|||||||
removePchTasksByProjectPartId(projectsPartIds, m_projectPchTasks);
|
removePchTasksByProjectPartId(projectsPartIds, m_projectPchTasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PchTaskQueue::processProjectPchTasks()
|
int PchTaskQueue::processProjectPchTasks()
|
||||||
{
|
{
|
||||||
uint systemRunningTaskCount = m_systemPchTaskScheduler.slotUsage().used;
|
auto slotUsage = m_projectPchTaskScheduler.slotUsage();
|
||||||
|
uint freeTaskCount = slotUsage.free;
|
||||||
|
|
||||||
if (!systemRunningTaskCount) {
|
int newTaskCount = std::min<int>(int(freeTaskCount), int(m_projectPchTasks.size()));
|
||||||
uint freeTaskCount = m_projectPchTaskScheduler.slotUsage().free;
|
|
||||||
|
|
||||||
auto newEnd = std::prev(m_projectPchTasks.end(),
|
auto newEnd = std::prev(m_projectPchTasks.end(), newTaskCount);
|
||||||
std::min<int>(int(freeTaskCount), int(m_projectPchTasks.size())));
|
|
||||||
m_projectPchTaskScheduler.addTasks(createProjectTasks(
|
m_projectPchTaskScheduler.addTasks(createProjectTasks(
|
||||||
{std::make_move_iterator(newEnd), std::make_move_iterator(m_projectPchTasks.end())}));
|
{std::make_move_iterator(newEnd), std::make_move_iterator(m_projectPchTasks.end())}));
|
||||||
m_projectPchTasks.erase(newEnd, m_projectPchTasks.end());
|
m_projectPchTasks.erase(newEnd, m_projectPchTasks.end());
|
||||||
}
|
|
||||||
|
return newTaskCount + slotUsage.used;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PchTaskQueue::processSystemPchTasks()
|
int PchTaskQueue::processSystemPchTasks()
|
||||||
{
|
{
|
||||||
uint freeTaskCount = m_systemPchTaskScheduler.slotUsage().free;
|
auto slotUsage = m_systemPchTaskScheduler.slotUsage();
|
||||||
|
uint freeTaskCount = slotUsage.free;
|
||||||
|
|
||||||
auto newEnd = std::prev(m_systemPchTasks.end(),
|
int newTaskCount = std::min<int>(int(freeTaskCount), int(m_systemPchTasks.size()));
|
||||||
std::min<int>(int(freeTaskCount), int(m_systemPchTasks.size())));
|
|
||||||
|
auto newEnd = std::prev(m_systemPchTasks.end(), newTaskCount);
|
||||||
m_systemPchTaskScheduler.addTasks(createSystemTasks(
|
m_systemPchTaskScheduler.addTasks(createSystemTasks(
|
||||||
{std::make_move_iterator(newEnd), std::make_move_iterator(m_systemPchTasks.end())}));
|
{std::make_move_iterator(newEnd), std::make_move_iterator(m_systemPchTasks.end())}));
|
||||||
m_systemPchTasks.erase(newEnd, m_systemPchTasks.end());
|
m_systemPchTasks.erase(newEnd, m_systemPchTasks.end());
|
||||||
|
|
||||||
|
return newTaskCount + slotUsage.used;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PchTaskQueue::deleteUnusedPchs()
|
||||||
|
{
|
||||||
|
FilePathIds existingPchFilePathIds = m_fileSystem.directoryEntries(
|
||||||
|
QString{m_environment.pchBuildDirectory()});
|
||||||
|
FilePathIds notAnymoreUsedPchFilePathIds;
|
||||||
|
notAnymoreUsedPchFilePathIds.reserve(existingPchFilePathIds.size());
|
||||||
|
|
||||||
|
FilePathIds usedPchFilePathIds = m_filePathCache.filePathIds(
|
||||||
|
m_precompiledHeaderStorage.fetchAllPchPaths());
|
||||||
|
std::sort(usedPchFilePathIds.begin(), usedPchFilePathIds.end());
|
||||||
|
|
||||||
|
std::set_difference(existingPchFilePathIds.begin(),
|
||||||
|
existingPchFilePathIds.end(),
|
||||||
|
usedPchFilePathIds.begin(),
|
||||||
|
usedPchFilePathIds.end(),
|
||||||
|
std::back_inserter(notAnymoreUsedPchFilePathIds));
|
||||||
|
|
||||||
|
m_fileSystem.remove(notAnymoreUsedPchFilePathIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PchTaskQueue::processEntries()
|
void PchTaskQueue::processEntries()
|
||||||
{
|
{
|
||||||
processSystemPchTasks();
|
int projectTaskCount = 0;
|
||||||
processProjectPchTasks();
|
int systemTaskCount = processSystemPchTasks();
|
||||||
|
if (systemTaskCount == 0)
|
||||||
|
projectTaskCount = processProjectPchTasks();
|
||||||
|
|
||||||
|
int totalTaskCount = projectTaskCount + systemTaskCount;
|
||||||
|
|
||||||
|
if (totalTaskCount == 0)
|
||||||
|
deleteUnusedPchs();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PchTaskQueue::Task> PchTaskQueue::createProjectTasks(PchTasks &&pchTasks) const
|
std::vector<PchTaskQueue::Task> PchTaskQueue::createProjectTasks(PchTasks &&pchTasks) const
|
||||||
|
@@ -37,6 +37,8 @@ class PchCreatorInterface;
|
|||||||
class PrecompiledHeaderStorageInterface;
|
class PrecompiledHeaderStorageInterface;
|
||||||
class ProgressCounter;
|
class ProgressCounter;
|
||||||
class Environment;
|
class Environment;
|
||||||
|
class FileSystemInterface;
|
||||||
|
class FilePathCachingInterface;
|
||||||
|
|
||||||
class PchTaskQueue final : public PchTaskQueueInterface
|
class PchTaskQueue final : public PchTaskQueueInterface
|
||||||
{
|
{
|
||||||
@@ -48,13 +50,17 @@ public:
|
|||||||
ProgressCounter &progressCounter,
|
ProgressCounter &progressCounter,
|
||||||
PrecompiledHeaderStorageInterface &precompiledHeaderStorage,
|
PrecompiledHeaderStorageInterface &precompiledHeaderStorage,
|
||||||
Sqlite::TransactionInterface &transactionsInterface,
|
Sqlite::TransactionInterface &transactionsInterface,
|
||||||
const Environment &environment)
|
const Environment &environment,
|
||||||
|
FileSystemInterface &fileSystem,
|
||||||
|
FilePathCachingInterface &filePathCache)
|
||||||
: m_systemPchTaskScheduler(systemPchTaskScheduler)
|
: m_systemPchTaskScheduler(systemPchTaskScheduler)
|
||||||
, m_projectPchTaskScheduler(projectPchTaskScheduler)
|
, m_projectPchTaskScheduler(projectPchTaskScheduler)
|
||||||
, m_precompiledHeaderStorage(precompiledHeaderStorage)
|
, m_precompiledHeaderStorage(precompiledHeaderStorage)
|
||||||
, m_transactionsInterface(transactionsInterface)
|
, m_transactionsInterface(transactionsInterface)
|
||||||
, m_progressCounter(progressCounter)
|
, m_progressCounter(progressCounter)
|
||||||
, m_environment(environment)
|
, m_environment(environment)
|
||||||
|
, m_fileSystem(fileSystem)
|
||||||
|
, m_filePathCache(filePathCache)
|
||||||
{
|
{
|
||||||
Q_UNUSED(m_transactionsInterface)
|
Q_UNUSED(m_transactionsInterface)
|
||||||
}
|
}
|
||||||
@@ -74,8 +80,9 @@ public:
|
|||||||
private:
|
private:
|
||||||
void addPchTasks(PchTasks &&pchTasks, PchTasks &destination);
|
void addPchTasks(PchTasks &&pchTasks, PchTasks &destination);
|
||||||
void removePchTasksByProjectPartId(const ProjectPartIds &projectsPartIds, PchTasks &destination);
|
void removePchTasksByProjectPartId(const ProjectPartIds &projectsPartIds, PchTasks &destination);
|
||||||
void processProjectPchTasks();
|
int processProjectPchTasks();
|
||||||
void processSystemPchTasks();
|
int processSystemPchTasks();
|
||||||
|
void deleteUnusedPchs();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PchTasks m_systemPchTasks;
|
PchTasks m_systemPchTasks;
|
||||||
@@ -86,6 +93,8 @@ private:
|
|||||||
Sqlite::TransactionInterface &m_transactionsInterface;
|
Sqlite::TransactionInterface &m_transactionsInterface;
|
||||||
ProgressCounter &m_progressCounter;
|
ProgressCounter &m_progressCounter;
|
||||||
const Environment &m_environment;
|
const Environment &m_environment;
|
||||||
|
FileSystemInterface &m_fileSystem;
|
||||||
|
FilePathCachingInterface &m_filePathCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ClangBackEnd
|
} // namespace ClangBackEnd
|
||||||
|
@@ -219,6 +219,22 @@ public:
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FilePaths fetchAllPchPaths() const
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Sqlite::DeferredTransaction transaction{database};
|
||||||
|
|
||||||
|
auto filePaths = fetchAllPchPathsStatement.template values<FilePath>(1024);
|
||||||
|
|
||||||
|
transaction.commit();
|
||||||
|
|
||||||
|
return filePaths;
|
||||||
|
|
||||||
|
} catch (const Sqlite::StatementIsBusy) {
|
||||||
|
return fetchAllPchPaths();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Sqlite::ImmediateNonThrowingDestructorTransaction transaction;
|
Sqlite::ImmediateNonThrowingDestructorTransaction transaction;
|
||||||
Database &database;
|
Database &database;
|
||||||
@@ -262,6 +278,10 @@ public:
|
|||||||
"SELECT projectPchBuildTime, systemPchBuildTime FROM precompiledHeaders WHERE "
|
"SELECT projectPchBuildTime, systemPchBuildTime FROM precompiledHeaders WHERE "
|
||||||
"projectPartId = ?",
|
"projectPartId = ?",
|
||||||
database};
|
database};
|
||||||
|
mutable ReadStatement fetchAllPchPathsStatement{
|
||||||
|
"SELECT DISTINCT systemPchPath FROM precompiledHeaders UNION ALL SELECT "
|
||||||
|
"DISTINCT projectPchPath FROM precompiledHeaders",
|
||||||
|
database};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -60,6 +60,7 @@ public:
|
|||||||
virtual FilePath fetchPrecompiledHeader(ProjectPartId projectPartId) const = 0;
|
virtual FilePath fetchPrecompiledHeader(ProjectPartId projectPartId) const = 0;
|
||||||
virtual PchPaths fetchPrecompiledHeaders(ProjectPartId projectPartId) const = 0;
|
virtual PchPaths fetchPrecompiledHeaders(ProjectPartId projectPartId) const = 0;
|
||||||
virtual PrecompiledHeaderTimeStamps fetchTimeStamps(ProjectPartId projectPartId) const = 0;
|
virtual PrecompiledHeaderTimeStamps fetchTimeStamps(ProjectPartId projectPartId) const = 0;
|
||||||
|
virtual FilePaths fetchAllPchPaths() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~PrecompiledHeaderStorageInterface() = default;
|
~PrecompiledHeaderStorageInterface() = default;
|
||||||
|
@@ -48,11 +48,7 @@ class CollectSymbolsAction : public clang::WrapperFrontendAction
|
|||||||
public:
|
public:
|
||||||
CollectSymbolsAction(std::shared_ptr<IndexDataConsumer> indexDataConsumer)
|
CollectSymbolsAction(std::shared_ptr<IndexDataConsumer> indexDataConsumer)
|
||||||
: clang::WrapperFrontendAction(
|
: clang::WrapperFrontendAction(
|
||||||
clang::index::createIndexingAction(indexDataConsumer, createIndexingOptions()
|
clang::index::createIndexingAction(indexDataConsumer, createIndexingOptions()))
|
||||||
#if LLVM_VERSION_MAJOR < 10
|
|
||||||
, nullptr
|
|
||||||
#endif
|
|
||||||
))
|
|
||||||
, m_indexDataConsumer(indexDataConsumer)
|
, m_indexDataConsumer(indexDataConsumer)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@@ -118,11 +118,7 @@ bool IndexDataConsumer::isAlreadyParsed(clang::FileID fileId, SourcesManager &so
|
|||||||
return sourcesManager.alreadyParsed(filePathId(fileEntry), fileEntry->getModificationTime());
|
return sourcesManager.alreadyParsed(filePathId(fileEntry), fileEntry->getModificationTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR >= 10
|
|
||||||
bool IndexDataConsumer::handleDeclOccurrence(
|
bool IndexDataConsumer::handleDeclOccurrence(
|
||||||
#else
|
|
||||||
bool IndexDataConsumer::handleDeclOccurence(
|
|
||||||
#endif
|
|
||||||
const clang::Decl *declaration,
|
const clang::Decl *declaration,
|
||||||
clang::index::SymbolRoleSet symbolRoles,
|
clang::index::SymbolRoleSet symbolRoles,
|
||||||
llvm::ArrayRef<clang::index::SymbolRelation> /*symbolRelations*/,
|
llvm::ArrayRef<clang::index::SymbolRelation> /*symbolRelations*/,
|
||||||
@@ -180,11 +176,7 @@ SourceLocationKind macroSymbolType(clang::index::SymbolRoleSet roles)
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR >= 10
|
|
||||||
bool IndexDataConsumer::handleMacroOccurrence(
|
bool IndexDataConsumer::handleMacroOccurrence(
|
||||||
#else
|
|
||||||
bool IndexDataConsumer::handleMacroOccurence(
|
|
||||||
#endif
|
|
||||||
const clang::IdentifierInfo *identifierInfo,
|
const clang::IdentifierInfo *identifierInfo,
|
||||||
const clang::MacroInfo *macroInfo,
|
const clang::MacroInfo *macroInfo,
|
||||||
clang::index::SymbolRoleSet roles,
|
clang::index::SymbolRoleSet roles,
|
||||||
|
@@ -57,22 +57,14 @@ public:
|
|||||||
IndexDataConsumer(const IndexDataConsumer &) = delete;
|
IndexDataConsumer(const IndexDataConsumer &) = delete;
|
||||||
IndexDataConsumer &operator=(const IndexDataConsumer &) = delete;
|
IndexDataConsumer &operator=(const IndexDataConsumer &) = delete;
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR >= 10
|
|
||||||
bool handleDeclOccurrence(
|
bool handleDeclOccurrence(
|
||||||
#else
|
|
||||||
bool handleDeclOccurence(
|
|
||||||
#endif
|
|
||||||
const clang::Decl *declaration,
|
const clang::Decl *declaration,
|
||||||
clang::index::SymbolRoleSet symbolRoles,
|
clang::index::SymbolRoleSet symbolRoles,
|
||||||
llvm::ArrayRef<clang::index::SymbolRelation> symbolRelations,
|
llvm::ArrayRef<clang::index::SymbolRelation> symbolRelations,
|
||||||
clang::SourceLocation sourceLocation,
|
clang::SourceLocation sourceLocation,
|
||||||
ASTNodeInfo astNodeInfo) override;
|
ASTNodeInfo astNodeInfo) override;
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR >= 10
|
|
||||||
bool handleMacroOccurrence(
|
bool handleMacroOccurrence(
|
||||||
#else
|
|
||||||
bool handleMacroOccurence(
|
|
||||||
#endif
|
|
||||||
const clang::IdentifierInfo *identifierInfo,
|
const clang::IdentifierInfo *identifierInfo,
|
||||||
const clang::MacroInfo *macroInfo,
|
const clang::MacroInfo *macroInfo,
|
||||||
clang::index::SymbolRoleSet roles,
|
clang::index::SymbolRoleSet roles,
|
||||||
|
@@ -74,11 +74,7 @@ std::unique_ptr<clang::tooling::FrontendActionFactory> newFrontendActionFactory(
|
|||||||
: m_action(consumerFactory)
|
: m_action(consumerFactory)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
#if LLVM_VERSION_MAJOR >= 10
|
|
||||||
std::unique_ptr<clang::FrontendAction> create() override { return std::make_unique<AdaptorAction>(m_action); }
|
std::unique_ptr<clang::FrontendAction> create() override { return std::make_unique<AdaptorAction>(m_action); }
|
||||||
#else
|
|
||||||
clang::FrontendAction *create() override { return new AdaptorAction(m_action); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class AdaptorAction : public clang::ASTFrontendAction
|
class AdaptorAction : public clang::ASTFrontendAction
|
||||||
|
41
tests/unit/mockup/coreplugin/helpitem.h
Normal file
41
tests/unit/mockup/coreplugin/helpitem.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 "core_global.h"
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
|
||||||
|
class HelpItem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HelpItem() {}
|
||||||
|
HelpItem(const QString &) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Core
|
40
tests/unit/mockup/coreplugin/icontext.h
Normal file
40
tests/unit/mockup/coreplugin/icontext.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 <QString>
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
|
||||||
|
class IContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using HelpCallback = std::function<void(const QString &)>;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Core
|
@@ -0,0 +1,70 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 "exception.h"
|
||||||
|
|
||||||
|
#include <qmldesignercorelib_global.h>
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
namespace QmlJS {
|
||||||
|
class DiagnosticMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class DocumentMessage
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Type { NoError = 0, InternalError = 1, ParseError = 2 };
|
||||||
|
|
||||||
|
public:
|
||||||
|
DocumentMessage() {}
|
||||||
|
DocumentMessage(const QString &) {}
|
||||||
|
|
||||||
|
Type type() const { return m_type; }
|
||||||
|
|
||||||
|
int line() const { return m_line; }
|
||||||
|
|
||||||
|
int column() const { return m_column; }
|
||||||
|
|
||||||
|
QString description() const { return m_description; }
|
||||||
|
|
||||||
|
QUrl url() const { return m_url; }
|
||||||
|
|
||||||
|
QString toString() const { return {}; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type m_type;
|
||||||
|
int m_line;
|
||||||
|
int m_column;
|
||||||
|
QString m_description;
|
||||||
|
QUrl m_url;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,56 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 "qmldesignercorelib_global.h"
|
||||||
|
|
||||||
|
#include <QIcon>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class ItemLibraryEntry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString name() const { return {}; }
|
||||||
|
TypeName typeName() const { return {}; }
|
||||||
|
QIcon typeIcon() const { return {}; }
|
||||||
|
QString libraryEntryIconPath() const { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class ItemLibraryInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QList<ItemLibraryEntry> entries() const { return {}; }
|
||||||
|
QList<ItemLibraryEntry> entriesForType(const QByteArray &typeName,
|
||||||
|
int majorVersion,
|
||||||
|
int minorVersion) const
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
ItemLibraryEntry entry(const QString &name) const { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,64 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 <QObject>
|
||||||
|
#include <QSize>
|
||||||
|
#include <QString>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
#include "itemlibraryinfo.h"
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class ItemLibraryItem : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QVariant itemLibraryEntry READ itemLibraryEntry FINAL)
|
||||||
|
Q_PROPERTY(QString itemName READ itemName FINAL)
|
||||||
|
Q_PROPERTY(QString itemLibraryIconPath READ itemLibraryIconPath FINAL)
|
||||||
|
Q_PROPERTY(bool itemVisible READ isVisible NOTIFY visibilityChanged FINAL)
|
||||||
|
|
||||||
|
public:
|
||||||
|
ItemLibraryItem(QObject *) {}
|
||||||
|
~ItemLibraryItem() override {}
|
||||||
|
|
||||||
|
QString itemName() const { return {}; }
|
||||||
|
QString typeName() const { return {}; }
|
||||||
|
QString itemLibraryIconPath() const { return {}; }
|
||||||
|
|
||||||
|
bool setVisible(bool) { return {}; }
|
||||||
|
bool isVisible() const { return {}; }
|
||||||
|
|
||||||
|
void setItemLibraryEntry(const ItemLibraryEntry &) {}
|
||||||
|
QVariant itemLibraryEntry() const { return {}; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void visibilityChanged();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,63 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 "qmldesignercorelib_global.h"
|
||||||
|
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
#include "itemlibraryinfo.h"
|
||||||
|
#include <nodemetainfo.h>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class ModelNode;
|
||||||
|
class AbstractProperty;
|
||||||
|
class ItemLibraryInfo;
|
||||||
|
|
||||||
|
inline bool operator==(const MetaInfo &first, const MetaInfo &second)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
inline bool operator!=(const MetaInfo &first, const MetaInfo &second)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
class QMLDESIGNERCORE_EXPORT MetaInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ItemLibraryInfo *itemLibraryInfo() const { return {}; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
static MetaInfo global() { return {}; }
|
||||||
|
static void clearGlobal() {}
|
||||||
|
|
||||||
|
static void setPluginPaths(const QStringList &paths) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} //namespace QmlDesigner
|
@@ -0,0 +1,91 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 "qmldesignercorelib_global.h"
|
||||||
|
#include "abstractview.h"
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class NodeInstanceView : public AbstractView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
NodeInstanceView(QObject *parent) {}
|
||||||
|
~NodeInstanceView() override {}
|
||||||
|
|
||||||
|
void modelAttached(Model *model) override {}
|
||||||
|
void modelAboutToBeDetached(Model *model) override {}
|
||||||
|
void nodeCreated(const ModelNode &createdNode) override {}
|
||||||
|
void nodeRemoved(const ModelNode &removedNode,
|
||||||
|
const NodeAbstractProperty &parentProperty,
|
||||||
|
PropertyChangeFlags propertyChange) override
|
||||||
|
{}
|
||||||
|
void propertiesAboutToBeRemoved(const QList<AbstractProperty> &propertyList) override {}
|
||||||
|
void propertiesRemoved(const QList<AbstractProperty> &propertyList) override {}
|
||||||
|
void variantPropertiesChanged(const QList<VariantProperty> &propertyList,
|
||||||
|
PropertyChangeFlags propertyChange) override
|
||||||
|
{}
|
||||||
|
void bindingPropertiesChanged(const QList<BindingProperty> &propertyList,
|
||||||
|
PropertyChangeFlags propertyChange) override
|
||||||
|
{}
|
||||||
|
void signalHandlerPropertiesChanged(const QVector<SignalHandlerProperty> &propertyList,
|
||||||
|
PropertyChangeFlags propertyChange) override
|
||||||
|
{}
|
||||||
|
void nodeReparented(const ModelNode &node,
|
||||||
|
const NodeAbstractProperty &newPropertyParent,
|
||||||
|
const NodeAbstractProperty &oldPropertyParent,
|
||||||
|
AbstractView::PropertyChangeFlags propertyChange) override
|
||||||
|
{}
|
||||||
|
void nodeIdChanged(const ModelNode &node, const QString &newId, const QString &oldId) override
|
||||||
|
{}
|
||||||
|
void nodeOrderChanged(const NodeListProperty &listProperty,
|
||||||
|
const ModelNode &movedNode,
|
||||||
|
int oldIndex) override
|
||||||
|
{}
|
||||||
|
void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion) override {}
|
||||||
|
void nodeTypeChanged(const ModelNode &node,
|
||||||
|
const TypeName &type,
|
||||||
|
int majorVersion,
|
||||||
|
int minorVersion) override
|
||||||
|
{}
|
||||||
|
void customNotification(const AbstractView *view,
|
||||||
|
const QString &identifier,
|
||||||
|
const QList<ModelNode> &nodeList,
|
||||||
|
const QList<QVariant> &data) override
|
||||||
|
{}
|
||||||
|
|
||||||
|
void rewriterBeginTransaction() override {}
|
||||||
|
void rewriterEndTransaction() override {}
|
||||||
|
|
||||||
|
void importsChanged(const QList<Import> &addedImports, const QList<Import> &removedImports) override
|
||||||
|
{}
|
||||||
|
|
||||||
|
void sendToken(const QString &token, int number, const QVector<ModelNode> &nodeVector) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,97 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 <QIcon>
|
||||||
|
#include <QList>
|
||||||
|
#include <QString>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
#include "qmldesignercorelib_global.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
class QDeclarativeContext;
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class MetaInfo;
|
||||||
|
class Model;
|
||||||
|
class AbstractProperty;
|
||||||
|
|
||||||
|
class NodeMetaInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NodeMetaInfo() {}
|
||||||
|
NodeMetaInfo(Model *, const TypeName &, int, int) {}
|
||||||
|
|
||||||
|
bool isValid() const { return {}; }
|
||||||
|
bool isFileComponent() const { return {}; }
|
||||||
|
bool hasProperty(const PropertyName &) const { return {}; }
|
||||||
|
PropertyNameList propertyNames() const { return {}; }
|
||||||
|
PropertyNameList signalNames() const { return {}; }
|
||||||
|
PropertyNameList directPropertyNames() const { return {}; }
|
||||||
|
PropertyName defaultPropertyName() const { return "data"; }
|
||||||
|
bool hasDefaultProperty() const { return {}; }
|
||||||
|
TypeName propertyTypeName(const PropertyName &) const { return {}; }
|
||||||
|
bool propertyIsWritable(const PropertyName &) const { return {}; }
|
||||||
|
bool propertyIsListProperty(const PropertyName &) const { return {}; }
|
||||||
|
bool propertyIsEnumType(const PropertyName &) const { return {}; }
|
||||||
|
bool propertyIsPrivate(const PropertyName &) const { return {}; }
|
||||||
|
QString propertyEnumScope(const PropertyName &) const { return {}; }
|
||||||
|
QStringList propertyKeysForEnum(const PropertyName &) const { return {}; }
|
||||||
|
QVariant propertyCastedValue(const PropertyName &, const QVariant &) const { return {}; }
|
||||||
|
|
||||||
|
QList<NodeMetaInfo> classHierarchy() const { return {}; }
|
||||||
|
QList<NodeMetaInfo> superClasses() const { return {}; }
|
||||||
|
NodeMetaInfo directSuperClass() const { return {}; }
|
||||||
|
|
||||||
|
bool defaultPropertyIsComponent() const { return {}; }
|
||||||
|
|
||||||
|
TypeName typeName() const { return {}; }
|
||||||
|
TypeName simplifiedTypeName() const { return {}; }
|
||||||
|
int majorVersion() const { return {}; }
|
||||||
|
int minorVersion() const { return {}; }
|
||||||
|
|
||||||
|
QString componentSource() const { return {}; }
|
||||||
|
QString componentFileName() const { return {}; }
|
||||||
|
|
||||||
|
bool hasCustomParser() const { return {}; }
|
||||||
|
|
||||||
|
bool availableInVersion(int, int) const { return {}; }
|
||||||
|
bool isSubclassOf(const TypeName &, int = -1, int = -1) const { return {}; }
|
||||||
|
|
||||||
|
bool isGraphicalItem() const { return {}; }
|
||||||
|
bool isLayoutable() const { return {}; }
|
||||||
|
bool isView() const { return {}; }
|
||||||
|
bool isTabView() const { return {}; }
|
||||||
|
|
||||||
|
QString importDirectoryPath() const { return {}; }
|
||||||
|
|
||||||
|
static void clearCache() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,56 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 <modelnode.h>
|
||||||
|
#include <qmldesignercorelib_global.h>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class AbstractView;
|
||||||
|
class NodeInstanceView;
|
||||||
|
|
||||||
|
class QmlModelNodeFacade
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
operator ModelNode() const { return {}; }
|
||||||
|
ModelNode modelNode() { return {}; }
|
||||||
|
const ModelNode modelNode() const { return {}; }
|
||||||
|
bool hasModelNode() const { return {}; }
|
||||||
|
static bool isValidQmlModelNodeFacade(const ModelNode &modelNode) { return {}; }
|
||||||
|
virtual bool isValid() const { return {}; }
|
||||||
|
|
||||||
|
AbstractView *view() const { return {}; }
|
||||||
|
static NodeInstanceView *nodeInstanceView(const ModelNode &modelNode) { return {}; }
|
||||||
|
NodeInstanceView *nodeInstanceView() const { return {}; }
|
||||||
|
bool isRootNode() const { return {}; }
|
||||||
|
|
||||||
|
QmlModelNodeFacade(const ModelNode &) {}
|
||||||
|
QmlModelNodeFacade() {}
|
||||||
|
~QmlModelNodeFacade(){};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,42 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 "qmlmodelnodefacade.h"
|
||||||
|
#include <qmldesignercorelib_global.h>
|
||||||
|
|
||||||
|
#include <nodeinstance.h>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class QMLDESIGNERCORE_EXPORT QmlObjectNode : public QmlModelNodeFacade
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QmlObjectNode() {}
|
||||||
|
QmlObjectNode(const ModelNode &modelNode){};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,39 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 "qmlmodelnodefacade.h"
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class QmlModelState : public QmlModelNodeFacade
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QmlModelState();
|
||||||
|
QmlModelState(const ModelNode &) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,46 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 "qmlmodelnodefacade.h"
|
||||||
|
#include <qmldesignercorelib_global.h>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class QmlTimeline : public QmlModelNodeFacade
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QmlTimeline() {}
|
||||||
|
QmlTimeline(const ModelNode &) {}
|
||||||
|
|
||||||
|
bool isValid() const override { return {}; }
|
||||||
|
|
||||||
|
void toogleRecording(bool b) const {}
|
||||||
|
|
||||||
|
void resetGroupRecording() const {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,175 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2016 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 "qmldesignercorelib_global.h"
|
||||||
|
#include "abstractview.h"
|
||||||
|
|
||||||
|
namespace QmlJS {
|
||||||
|
class Document;
|
||||||
|
class ScopeChain;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class TextModifier;
|
||||||
|
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class TextToModelMerger;
|
||||||
|
class ModelToTextMerger;
|
||||||
|
class ModelNodePositionStorage;
|
||||||
|
|
||||||
|
} //Internal
|
||||||
|
|
||||||
|
struct CppTypeData
|
||||||
|
{
|
||||||
|
QString superClassName;
|
||||||
|
QString importUrl;
|
||||||
|
QString versionString;
|
||||||
|
QString cppClassName;
|
||||||
|
QString typeName;
|
||||||
|
bool isSingleton = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RewriterView : public AbstractView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum DifferenceHandling {
|
||||||
|
Validate,
|
||||||
|
Amend
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
RewriterView(DifferenceHandling, QObject *) {}
|
||||||
|
~RewriterView() override {}
|
||||||
|
|
||||||
|
void modelAttached(Model *) override {}
|
||||||
|
void modelAboutToBeDetached(Model *) override {}
|
||||||
|
void nodeCreated(const ModelNode &) override {}
|
||||||
|
void nodeRemoved(const ModelNode &, const NodeAbstractProperty &, PropertyChangeFlags) override
|
||||||
|
{}
|
||||||
|
void propertiesAboutToBeRemoved(const QList<AbstractProperty> &) override {}
|
||||||
|
void propertiesRemoved(const QList<AbstractProperty> &) override {}
|
||||||
|
void variantPropertiesChanged(const QList<VariantProperty> &, PropertyChangeFlags) override {}
|
||||||
|
void bindingPropertiesChanged(const QList<BindingProperty> &, PropertyChangeFlags) override {}
|
||||||
|
void signalHandlerPropertiesChanged(const QVector<SignalHandlerProperty> &,
|
||||||
|
PropertyChangeFlags) override
|
||||||
|
{}
|
||||||
|
void nodeReparented(const ModelNode &,
|
||||||
|
const NodeAbstractProperty &,
|
||||||
|
const NodeAbstractProperty &,
|
||||||
|
AbstractView::PropertyChangeFlags) override
|
||||||
|
{}
|
||||||
|
void nodeIdChanged(const ModelNode &, const QString &, const QString &) override {}
|
||||||
|
void nodeOrderChanged(const NodeListProperty &, const ModelNode &, int) override {}
|
||||||
|
void rootNodeTypeChanged(const QString &, int, int) override {}
|
||||||
|
void nodeTypeChanged(const ModelNode &, const TypeName &, int, int) override {}
|
||||||
|
void customNotification(const AbstractView *,
|
||||||
|
const QString &,
|
||||||
|
const QList<ModelNode> &,
|
||||||
|
const QList<QVariant> &) override
|
||||||
|
{}
|
||||||
|
|
||||||
|
void rewriterBeginTransaction() override {}
|
||||||
|
void rewriterEndTransaction() override {}
|
||||||
|
|
||||||
|
void importsChanged(const QList<Import> &, const QList<Import> &) override {}
|
||||||
|
|
||||||
|
TextModifier *textModifier() const { return {}; }
|
||||||
|
void setTextModifier(TextModifier *) {}
|
||||||
|
QString textModifierContent() const { return {}; }
|
||||||
|
|
||||||
|
void reactivateTextMofifierChangeSignals() {}
|
||||||
|
void deactivateTextMofifierChangeSignals() {}
|
||||||
|
|
||||||
|
void auxiliaryDataChanged(const ModelNode &node, const PropertyName &name, const QVariant &data) override
|
||||||
|
{}
|
||||||
|
|
||||||
|
Internal::ModelNodePositionStorage *positionStorage() const {}
|
||||||
|
|
||||||
|
QList<DocumentMessage> warnings() const { return {}; }
|
||||||
|
QList<DocumentMessage> errors() const { return {}; }
|
||||||
|
void clearErrorAndWarnings() {}
|
||||||
|
void setErrors(const QList<DocumentMessage> &) {}
|
||||||
|
void setWarnings(const QList<DocumentMessage> &) {}
|
||||||
|
void setIncompleteTypeInformation(bool) {}
|
||||||
|
bool hasIncompleteTypeInformation() const { return false; }
|
||||||
|
void addError(const DocumentMessage &) {}
|
||||||
|
|
||||||
|
void enterErrorState(const QString &) {}
|
||||||
|
bool inErrorState() const { return false; }
|
||||||
|
void leaveErrorState() {}
|
||||||
|
void resetToLastCorrectQml() {}
|
||||||
|
|
||||||
|
QMap<ModelNode, QString> extractText(const QList<ModelNode> &) const;
|
||||||
|
int nodeOffset(const ModelNode &) const;
|
||||||
|
int nodeLength(const ModelNode &) const;
|
||||||
|
int firstDefinitionInsideOffset(const ModelNode &) const { return {}; }
|
||||||
|
int firstDefinitionInsideLength(const ModelNode &) const { return {}; }
|
||||||
|
bool modificationGroupActive() { return {}; }
|
||||||
|
ModelNode nodeAtTextCursorPosition(int) const { return {}; }
|
||||||
|
|
||||||
|
bool renameId(const QString &, const QString &) { return {}; }
|
||||||
|
|
||||||
|
const QmlJS::Document *document() const { return {}; }
|
||||||
|
const QmlJS::ScopeChain *scopeChain() const { return {}; }
|
||||||
|
|
||||||
|
QString convertTypeToImportAlias(const QString &) const { return {}; }
|
||||||
|
|
||||||
|
bool checkSemanticErrors() const { return {}; }
|
||||||
|
|
||||||
|
void setCheckSemanticErrors(bool) {}
|
||||||
|
|
||||||
|
QString pathForImport(const Import &) { return {}; }
|
||||||
|
|
||||||
|
QStringList importDirectories() const { return {}; }
|
||||||
|
|
||||||
|
QSet<QPair<QString, QString>> qrcMapping() const { return {}; }
|
||||||
|
|
||||||
|
void moveToComponent(const ModelNode &) {}
|
||||||
|
|
||||||
|
QStringList autoComplete(const QString &, int, bool = true) { return {}; }
|
||||||
|
|
||||||
|
QList<CppTypeData> getCppTypes() { return {}; }
|
||||||
|
|
||||||
|
void setWidgetStatusCallback(std::function<void(bool)> setWidgetStatusCallback);
|
||||||
|
|
||||||
|
void qmlTextChanged() {}
|
||||||
|
void delayedSetup() {}
|
||||||
|
|
||||||
|
void writeAuxiliaryData() {}
|
||||||
|
void restoreAuxiliaryData() {}
|
||||||
|
|
||||||
|
QString getRawAuxiliaryData() const { return {}; }
|
||||||
|
QString auxiliaryDataAsQML() const { return {}; }
|
||||||
|
|
||||||
|
ModelNode getNodeForCanonicalIndex(int) { return {}; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} //QmlDesigner
|
@@ -16,6 +16,7 @@ include($$PWD/../../../src/plugins/clangpchmanager/clangpchmanager-source.pri)
|
|||||||
include($$PWD/../../../src/plugins/cpptools/cpptoolsunittestfiles.pri)
|
include($$PWD/../../../src/plugins/cpptools/cpptoolsunittestfiles.pri)
|
||||||
include($$PWD/../../../src/plugins/debugger/debuggerunittestfiles.pri)
|
include($$PWD/../../../src/plugins/debugger/debuggerunittestfiles.pri)
|
||||||
include($$PWD/../../../src/plugins/compilationdatabaseprojectmanager/compilationdatabaseunittestfiles.pri)
|
include($$PWD/../../../src/plugins/compilationdatabaseprojectmanager/compilationdatabaseunittestfiles.pri)
|
||||||
|
include($$PWD/../../../src/plugins/qmldesigner/qmldesignerunittestfiles.pri)
|
||||||
!isEmpty(QTC_UNITTEST_BUILD_CPP_PARSER):include(cplusplus.pri)
|
!isEmpty(QTC_UNITTEST_BUILD_CPP_PARSER):include(cplusplus.pri)
|
||||||
!isEmpty(LLVM_VERSION) {
|
!isEmpty(LLVM_VERSION) {
|
||||||
include($$PWD/../../../src/plugins/clangtools/clangtoolsunittestfiles.pri)
|
include($$PWD/../../../src/plugins/clangtools/clangtoolsunittestfiles.pri)
|
||||||
|
@@ -65,6 +65,8 @@ using testing::Property;
|
|||||||
using testing::Return;
|
using testing::Return;
|
||||||
using testing::ReturnRef;
|
using testing::ReturnRef;
|
||||||
using testing::SafeMatcherCast;
|
using testing::SafeMatcherCast;
|
||||||
|
using testing::SaveArg;
|
||||||
|
using testing::SaveArgPointee;
|
||||||
using testing::Sequence;
|
using testing::Sequence;
|
||||||
using testing::SizeIs;
|
using testing::SizeIs;
|
||||||
using testing::StrEq;
|
using testing::StrEq;
|
||||||
|
@@ -47,6 +47,7 @@
|
|||||||
#include <filepathview.h>
|
#include <filepathview.h>
|
||||||
#include <filestatus.h>
|
#include <filestatus.h>
|
||||||
#include <includesearchpath.h>
|
#include <includesearchpath.h>
|
||||||
|
#include <modelnode.h>
|
||||||
#include <nativefilepath.h>
|
#include <nativefilepath.h>
|
||||||
#include <pchpaths.h>
|
#include <pchpaths.h>
|
||||||
#include <pchtask.h>
|
#include <pchtask.h>
|
||||||
@@ -68,6 +69,7 @@
|
|||||||
#include <tooltipinfo.h>
|
#include <tooltipinfo.h>
|
||||||
#include <usedmacro.h>
|
#include <usedmacro.h>
|
||||||
#include <utils/link.h>
|
#include <utils/link.h>
|
||||||
|
#include <variantproperty.h>
|
||||||
|
|
||||||
#include <sqlite3ext.h>
|
#include <sqlite3ext.h>
|
||||||
|
|
||||||
@@ -1450,6 +1452,25 @@ std::ostream &operator<<(std::ostream &out, const Diagnostic &diag) {
|
|||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace ClangTools
|
} // namespace ClangTools
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const ModelNode &node)
|
||||||
|
{
|
||||||
|
if (!node.isValid())
|
||||||
|
return out << "(invalid)";
|
||||||
|
|
||||||
|
return out << "(" << node.id() << ")";
|
||||||
|
}
|
||||||
|
std::ostream &operator<<(std::ostream &out, const VariantProperty &property)
|
||||||
|
{
|
||||||
|
if (!property.isValid())
|
||||||
|
return out << "(invalid)";
|
||||||
|
|
||||||
|
return out << "(" << property.parentModelNode() << ", " << property.name() << ", "
|
||||||
|
<< property.value() << ")";
|
||||||
|
}
|
||||||
|
} // namespace QmlDesigner
|
||||||
|
|
||||||
void setFilePathCache(ClangBackEnd::FilePathCaching *cache)
|
void setFilePathCache(ClangBackEnd::FilePathCaching *cache)
|
||||||
{
|
{
|
||||||
filePathCache = cache;
|
filePathCache = cache;
|
||||||
|
@@ -350,4 +350,12 @@ std::ostream &operator<<(std::ostream &out, const Diagnostic &diag);
|
|||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace CppTools
|
} // namespace CppTools
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
class ModelNode;
|
||||||
|
class VariantProperty;
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &out, const ModelNode &node);
|
||||||
|
std::ostream &operator<<(std::ostream &out, const VariantProperty &property);
|
||||||
|
} // namespace QmlDesigner
|
||||||
|
|
||||||
void setFilePathCache(ClangBackEnd::FilePathCaching *filePathCache);
|
void setFilePathCache(ClangBackEnd::FilePathCaching *filePathCache);
|
||||||
|
@@ -59,9 +59,11 @@ std::ostream &operator<<(std::ostream &out, const QVariant &variant)
|
|||||||
QString output;
|
QString output;
|
||||||
QDebug debug(&output);
|
QDebug debug(&output);
|
||||||
|
|
||||||
debug << variant;
|
debug.noquote().nospace() << variant;
|
||||||
|
|
||||||
return out << output;
|
QByteArray utf8Text = output.toUtf8();
|
||||||
|
|
||||||
|
return out.write(utf8Text.data(), utf8Text.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &out, const QTextCharFormat &format)
|
std::ostream &operator<<(std::ostream &out, const QTextCharFormat &format)
|
||||||
@@ -88,4 +90,14 @@ void PrintTo(const QString &text, std::ostream *os)
|
|||||||
*os << text;
|
*os << text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintTo(const QVariant &variant, std::ostream *os)
|
||||||
|
{
|
||||||
|
*os << variant;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintTo(const QByteArray &text, std::ostream *os)
|
||||||
|
{
|
||||||
|
*os << text;
|
||||||
|
}
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@@ -35,10 +35,12 @@ class QVariant;
|
|||||||
class QString;
|
class QString;
|
||||||
class QTextCharFormat;
|
class QTextCharFormat;
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &out, const QVariant &variant);
|
std::ostream &operator<<(std::ostream &out, const QVariant &QVariant);
|
||||||
std::ostream &operator<<(std::ostream &out, const QString &text);
|
std::ostream &operator<<(std::ostream &out, const QString &text);
|
||||||
std::ostream &operator<<(std::ostream &out, const QByteArray &byteArray);
|
std::ostream &operator<<(std::ostream &out, const QByteArray &byteArray);
|
||||||
std::ostream &operator<<(std::ostream &out, const QTextCharFormat &format);
|
std::ostream &operator<<(std::ostream &out, const QTextCharFormat &format);
|
||||||
|
|
||||||
void PrintTo(const QString &text, std::ostream *os);
|
void PrintTo(const QString &text, std::ostream *os);
|
||||||
|
void PrintTo(const QVariant &variant, std::ostream *os);
|
||||||
|
void PrintTo(const QByteArray &text, std::ostream *os);
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
952
tests/unit/unittest/listmodeleditor-test.cpp
Normal file
952
tests/unit/unittest/listmodeleditor-test.cpp
Normal file
@@ -0,0 +1,952 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 "googletest.h"
|
||||||
|
|
||||||
|
#include "mocklistmodeleditorview.h"
|
||||||
|
|
||||||
|
#include <qmldesigner/components/listmodeleditor/listmodeleditormodel.h>
|
||||||
|
#include <qmldesigner/designercore/include/abstractview.h>
|
||||||
|
#include <qmldesigner/designercore/include/model.h>
|
||||||
|
#include <qmldesigner/designercore/include/nodelistproperty.h>
|
||||||
|
#include <qmldesigner/designercore/include/variantproperty.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using QmlDesigner::AbstractProperty;
|
||||||
|
using QmlDesigner::AbstractView;
|
||||||
|
using QmlDesigner::ModelNode;
|
||||||
|
|
||||||
|
MATCHER_P2(HasItem,
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
std::string(negation ? "hasn't " : "has ") + "(" + name + ", " + value + ")")
|
||||||
|
{
|
||||||
|
QStandardItem *item = arg;
|
||||||
|
|
||||||
|
return item->data(Qt::UserRole).toString() == name && item->data(Qt::UserRole).toDouble() == value;
|
||||||
|
}
|
||||||
|
|
||||||
|
MATCHER(IsInvalid, std::string(negation ? "isn't null" : "is null"))
|
||||||
|
{
|
||||||
|
return !arg.isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
MATCHER_P3(IsVariantProperty,
|
||||||
|
node,
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
std::string(negation ? "isn't " : "is ") + "(" + name + ", " + PrintToString(value) + ")")
|
||||||
|
{
|
||||||
|
const QmlDesigner::VariantProperty &property = arg;
|
||||||
|
|
||||||
|
return property.parentModelNode() == node && property.name() == name && property.value() == value;
|
||||||
|
}
|
||||||
|
|
||||||
|
MATCHER_P2(IsVariantProperty,
|
||||||
|
name,
|
||||||
|
value,
|
||||||
|
std::string(negation ? "isn't " : "is ") + "(" + name + ", " + PrintToString(value) + ")")
|
||||||
|
{
|
||||||
|
const QmlDesigner::VariantProperty &property = arg;
|
||||||
|
|
||||||
|
return property.name() == name && property.value() == value;
|
||||||
|
}
|
||||||
|
|
||||||
|
MATCHER_P2(IsAbstractProperty, node, name, std::string(negation ? "isn't " : "is ") + "(" + name + ")")
|
||||||
|
{
|
||||||
|
const QmlDesigner::AbstractProperty &property = arg;
|
||||||
|
|
||||||
|
return property.parentModelNode() == node && property.name() == name;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ListModelEditor : public testing::Test
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ListModelEditor()
|
||||||
|
{
|
||||||
|
designerModel->attachView(&mockView);
|
||||||
|
|
||||||
|
emptyListModelNode = mockView.createModelNode("QtQml.Models.ListModel", 2, 15);
|
||||||
|
|
||||||
|
listModelNode = mockView.createModelNode("QtQml.Models.ListModel", 2, 15);
|
||||||
|
mockView.rootModelNode().defaultNodeListProperty().reparentHere(listModelNode);
|
||||||
|
element1 = createElement({{"name", "foo"}, {"value", 1}, {"value2", 42}});
|
||||||
|
element2 = createElement({{"value", 4}, {"name", "bar"}, {"image", "pic.png"}});
|
||||||
|
element3 = createElement({{"image", "pic.png"}, {"name", "poo"}, {"value", 111}});
|
||||||
|
}
|
||||||
|
|
||||||
|
using Entry = std::pair<QmlDesigner::PropertyName, QVariant>;
|
||||||
|
|
||||||
|
ModelNode createElement(std::initializer_list<Entry> entries)
|
||||||
|
{
|
||||||
|
auto element = mockView.createModelNode("QtQml.Models/ListElement", 2, 15);
|
||||||
|
listModelNode.defaultNodeListProperty().reparentHere(element);
|
||||||
|
|
||||||
|
for (const auto &entry : entries) {
|
||||||
|
element.variantProperty(entry.first).setValue(entry.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QString> headerLabels(const QmlDesigner::ListModelEditorModel &model) const
|
||||||
|
{
|
||||||
|
QList<QString> labels;
|
||||||
|
labels.reserve(model.columnCount());
|
||||||
|
|
||||||
|
for (int i = 0; i < model.columnCount(); ++i)
|
||||||
|
labels.push_back(model.headerData(i, Qt::Horizontal).toString());
|
||||||
|
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QList<QVariant>> displayValues() const
|
||||||
|
{
|
||||||
|
QList<QList<QVariant>> rows;
|
||||||
|
|
||||||
|
for (int rowIndex = 0; rowIndex < model.rowCount(); ++rowIndex) {
|
||||||
|
QList<QVariant> row;
|
||||||
|
|
||||||
|
for (int columnIndex = 0; columnIndex < model.columnCount(); ++columnIndex)
|
||||||
|
row.push_back(model.data(model.index(rowIndex, columnIndex), Qt::DisplayRole));
|
||||||
|
|
||||||
|
rows.push_back(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QList<QColor>> backgroundColors() const
|
||||||
|
{
|
||||||
|
QList<QList<QColor>> rows;
|
||||||
|
|
||||||
|
for (int rowIndex = 0; rowIndex < model.rowCount(); ++rowIndex) {
|
||||||
|
QList<QColor> row;
|
||||||
|
|
||||||
|
for (int columnIndex = 0; columnIndex < model.columnCount(); ++columnIndex)
|
||||||
|
row.push_back(
|
||||||
|
model.data(model.index(rowIndex, columnIndex), Qt::BackgroundColorRole)
|
||||||
|
.value<QColor>());
|
||||||
|
|
||||||
|
rows.push_back(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rows;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QList<QmlDesigner::VariantProperty>> properties() const
|
||||||
|
{
|
||||||
|
QList<QList<QmlDesigner::VariantProperty>> properties;
|
||||||
|
properties.reserve(10);
|
||||||
|
|
||||||
|
auto nodes = listModelNode.defaultNodeListProperty().toModelNodeList();
|
||||||
|
|
||||||
|
for (const ModelNode &node : nodes)
|
||||||
|
properties.push_back(node.variantProperties());
|
||||||
|
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::unique_ptr<QmlDesigner::Model> designerModel{QmlDesigner::Model::create("QtQuick.Item", 1, 1)};
|
||||||
|
NiceMock<MockListModelEditorView> mockView;
|
||||||
|
QmlDesigner::ListModelEditorModel model;
|
||||||
|
ModelNode listModelNode;
|
||||||
|
ModelNode emptyListModelNode;
|
||||||
|
ModelNode element1;
|
||||||
|
ModelNode element2;
|
||||||
|
ModelNode element3;
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, CreatePropertyNameSet)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
ASSERT_THAT(model.propertyNames(), ElementsAre("image", "name", "value", "value2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, CreatePropertyNameSetForEmptyList)
|
||||||
|
{
|
||||||
|
model.setListModel(emptyListModelNode);
|
||||||
|
|
||||||
|
ASSERT_THAT(model.propertyNames(), IsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, HorizontalLabels)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
ASSERT_THAT(headerLabels(model), ElementsAre("image", "name", "value", "value2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, HorizontalLabelsForEmptyList)
|
||||||
|
{
|
||||||
|
model.setListModel(emptyListModelNode);
|
||||||
|
|
||||||
|
ASSERT_THAT(headerLabels(model), IsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, DisplayValues)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(),
|
||||||
|
ElementsAre(ElementsAre(IsInvalid(), "foo", 1, 42),
|
||||||
|
ElementsAre("pic.png", "bar", 4, IsInvalid()),
|
||||||
|
ElementsAre("pic.png", "poo", 111, IsInvalid())));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, ChangeValueChangesDisplayValues)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.setValue(0, 1, "hello");
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(),
|
||||||
|
ElementsAre(ElementsAre(IsInvalid(), "hello", 1, 42),
|
||||||
|
ElementsAre("pic.png", "bar", 4, IsInvalid()),
|
||||||
|
ElementsAre("pic.png", "poo", 111, IsInvalid())));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, EditValueCallVariantPropertiesChanged)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
EXPECT_CALL(mockView,
|
||||||
|
variantPropertiesChanged(ElementsAre(IsVariantProperty(element1, "name", "hello")),
|
||||||
|
Eq(AbstractView::NoAdditionalChanges)));
|
||||||
|
|
||||||
|
model.setValue(0, 1, "hello");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, ChangeDisplayValueCallsVariantPropertiesChanged)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
EXPECT_CALL(mockView,
|
||||||
|
variantPropertiesChanged(ElementsAre(IsVariantProperty(element1, "name", "hello")),
|
||||||
|
Eq(AbstractView::NoAdditionalChanges)))
|
||||||
|
.Times(0);
|
||||||
|
|
||||||
|
model.setValue(0, 1, "hello", Qt::DisplayRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, AddRowAddedInvalidRow)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.addRow();
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(),
|
||||||
|
ElementsAre(ElementsAre(IsInvalid(), "foo", 1, 42),
|
||||||
|
ElementsAre("pic.png", "bar", 4, IsInvalid()),
|
||||||
|
ElementsAre("pic.png", "poo", 111, IsInvalid()),
|
||||||
|
ElementsAre(IsInvalid(), IsInvalid(), IsInvalid(), IsInvalid())));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, AddRowCreatesNewModelNodeAndReparents)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
EXPECT_CALL(mockView, nodeCreated(Property(&ModelNode::type, Eq("QtQml.Models.ListElement"))));
|
||||||
|
EXPECT_CALL(mockView,
|
||||||
|
nodeReparented(Property(&ModelNode::type, Eq("QtQml.Models.ListElement")),
|
||||||
|
Property(&AbstractProperty::parentModelNode, Eq(listModelNode)),
|
||||||
|
_,
|
||||||
|
_));
|
||||||
|
|
||||||
|
model.addRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, ChangeAddedRowPropery)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
model.addRow();
|
||||||
|
|
||||||
|
model.setValue(3, 2, 22);
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(),
|
||||||
|
ElementsAre(ElementsAre(IsInvalid(), "foo", 1, 42),
|
||||||
|
ElementsAre("pic.png", "bar", 4, IsInvalid()),
|
||||||
|
ElementsAre("pic.png", "poo", 111, IsInvalid()),
|
||||||
|
ElementsAre(IsInvalid(), IsInvalid(), 22, IsInvalid())));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, ChangeAddedRowProperyCallsVariantPropertiesChanged)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
ModelNode element4;
|
||||||
|
ON_CALL(mockView, nodeReparented(_, _, _, _)).WillByDefault(SaveArg<0>(&element4));
|
||||||
|
model.addRow();
|
||||||
|
|
||||||
|
EXPECT_CALL(mockView,
|
||||||
|
variantPropertiesChanged(ElementsAre(IsVariantProperty(element4, "value", 22)),
|
||||||
|
Eq(AbstractView::PropertiesAdded)));
|
||||||
|
|
||||||
|
model.setValue(3, 2, 22);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, AddColumnInsertsPropertyName)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.addColumn("other");
|
||||||
|
|
||||||
|
ASSERT_THAT(model.propertyNames(), ElementsAre("image", "name", "other", "value", "value2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, AddColumnInsertsPropertyNameToEmptyModel)
|
||||||
|
{
|
||||||
|
model.setListModel(emptyListModelNode);
|
||||||
|
|
||||||
|
model.addColumn("foo");
|
||||||
|
|
||||||
|
ASSERT_THAT(model.propertyNames(), ElementsAre("foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, AddTwiceColumnInsertsPropertyNameToEmptyModel)
|
||||||
|
{
|
||||||
|
model.setListModel(emptyListModelNode);
|
||||||
|
model.addColumn("foo");
|
||||||
|
|
||||||
|
model.addColumn("foo2");
|
||||||
|
|
||||||
|
ASSERT_THAT(model.propertyNames(), ElementsAre("foo", "foo2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, AddSameColumnInsertsPropertyName)
|
||||||
|
{
|
||||||
|
model.setListModel(emptyListModelNode);
|
||||||
|
model.addColumn("foo");
|
||||||
|
|
||||||
|
model.addColumn("foo");
|
||||||
|
|
||||||
|
ASSERT_THAT(model.propertyNames(), ElementsAre("foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, AddColumnInsertsHeaderLabel)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.addColumn("other");
|
||||||
|
|
||||||
|
ASSERT_THAT(headerLabels(model), ElementsAre("image", "name", "other", "value", "value2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, AddColumnInsertsHeaderLabelToEmptyModel)
|
||||||
|
{
|
||||||
|
model.setListModel(emptyListModelNode);
|
||||||
|
|
||||||
|
model.addColumn("foo");
|
||||||
|
|
||||||
|
ASSERT_THAT(headerLabels(model), ElementsAre("foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, AddTwiceColumnInsertsHeaderLabelToEmptyModel)
|
||||||
|
{
|
||||||
|
model.setListModel(emptyListModelNode);
|
||||||
|
model.addColumn("foo");
|
||||||
|
|
||||||
|
model.addColumn("foo2");
|
||||||
|
|
||||||
|
ASSERT_THAT(headerLabels(model), ElementsAre("foo", "foo2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, AddSameColumnInsertsHeaderLabel)
|
||||||
|
{
|
||||||
|
model.setListModel(emptyListModelNode);
|
||||||
|
model.addColumn("foo");
|
||||||
|
|
||||||
|
model.addColumn("foo");
|
||||||
|
|
||||||
|
ASSERT_THAT(headerLabels(model), ElementsAre("foo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, AddColumnInsertsDisplayValues)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.addColumn("other");
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(),
|
||||||
|
ElementsAre(ElementsAre(IsInvalid(), "foo", IsInvalid(), 1, 42),
|
||||||
|
ElementsAre("pic.png", "bar", IsInvalid(), 4, IsInvalid()),
|
||||||
|
ElementsAre("pic.png", "poo", IsInvalid(), 111, IsInvalid())));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, ChangeAddColumnPropertyDisplayValue)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
model.addColumn("other");
|
||||||
|
|
||||||
|
model.setValue(1, 2, 22);
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(),
|
||||||
|
ElementsAre(ElementsAre(IsInvalid(), "foo", IsInvalid(), 1, 42),
|
||||||
|
ElementsAre("pic.png", "bar", 22, 4, IsInvalid()),
|
||||||
|
ElementsAre("pic.png", "poo", IsInvalid(), 111, IsInvalid())));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, ChangeAddColumnPropertyCallsVariantPropertiesChanged)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
model.addColumn("other");
|
||||||
|
|
||||||
|
EXPECT_CALL(mockView,
|
||||||
|
variantPropertiesChanged(ElementsAre(IsVariantProperty(element2, "other", 434)), _));
|
||||||
|
|
||||||
|
model.setValue(1, 2, 434);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RemoveColumnRemovesDisplayValues)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.removeColumn(2);
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(),
|
||||||
|
ElementsAre(ElementsAre(IsInvalid(), "foo", 42),
|
||||||
|
ElementsAre("pic.png", "bar", IsInvalid()),
|
||||||
|
ElementsAre("pic.png", "poo", IsInvalid())));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RemoveColumnRemovesProperties)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
EXPECT_CALL(mockView, propertiesRemoved(ElementsAre(IsAbstractProperty(element2, "image"))));
|
||||||
|
EXPECT_CALL(mockView, propertiesRemoved(ElementsAre(IsAbstractProperty(element3, "image"))));
|
||||||
|
|
||||||
|
model.removeColumn(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RemoveColumnRemovesPropertyName)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.removeColumn(1);
|
||||||
|
|
||||||
|
ASSERT_THAT(model.propertyNames(), ElementsAre("image", "value", "value2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RemoveRowRemovesDisplayValues)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.removeRow(1);
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(),
|
||||||
|
ElementsAre(ElementsAre(IsInvalid(), "foo", 1, 42),
|
||||||
|
ElementsAre("pic.png", "poo", 111, IsInvalid())));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RemoveRowRemovesElementInListModel)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
EXPECT_CALL(mockView, nodeRemoved(Eq(element2), _, _));
|
||||||
|
|
||||||
|
model.removeRow(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, ConvertStringFloatToFloat)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.setValue(1, 1, "25.5");
|
||||||
|
|
||||||
|
ASSERT_THAT(element2.variantProperty("name").value().value<double>(), 25.5);
|
||||||
|
ASSERT_THAT(element2.variantProperty("name").value().type(), QVariant::Double);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, ConvertStringIntegerToDouble)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.setValue(1, 1, "25");
|
||||||
|
|
||||||
|
ASSERT_THAT(element2.variantProperty("name").value().value<double>(), 25);
|
||||||
|
ASSERT_THAT(element2.variantProperty("name").value().type(), QVariant::Double);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, DontConvertStringToNumber)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.setValue(1, 1, "hello");
|
||||||
|
|
||||||
|
ASSERT_THAT(element2.variantProperty("name").value().value<QString>(), "hello");
|
||||||
|
ASSERT_THAT(element2.variantProperty("name").value().type(), QVariant::String);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, EmptyStringsRemovesProperty)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.setValue(1, 1, "");
|
||||||
|
|
||||||
|
ASSERT_THAT(element2.variantProperty("name").value().value<QString>(), Eq(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, InvalidVariantRemovesProperty)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.setValue(1, 1, QVariant());
|
||||||
|
|
||||||
|
ASSERT_FALSE(element2.hasProperty("name"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, DispayValueIsChangedToDouble)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.setValue(1, 1, "25.5");
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues()[1][1].type(), QVariant::Double);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, StringDispayValueIsNotChanged)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.setValue(1, 1, "25.5a");
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues()[1][1].type(), QVariant::String);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, SetInvalidToDarkYellowBackgroundColor)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
ASSERT_THAT(
|
||||||
|
backgroundColors(),
|
||||||
|
ElementsAre(
|
||||||
|
ElementsAre(Qt::darkYellow, Not(Qt::darkYellow), Not(Qt::darkYellow), Not(Qt::darkYellow)),
|
||||||
|
ElementsAre(Not(Qt::darkYellow), Not(Qt::darkYellow), Not(Qt::darkYellow), Qt::darkYellow),
|
||||||
|
ElementsAre(Not(Qt::darkYellow), Not(Qt::darkYellow), Not(Qt::darkYellow), Qt::darkYellow)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, SettingValueChangesBackgroundColor)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.setValue(0, 0, "foo");
|
||||||
|
|
||||||
|
ASSERT_THAT(
|
||||||
|
backgroundColors(),
|
||||||
|
ElementsAre(
|
||||||
|
ElementsAre(Not(Qt::darkYellow), Not(Qt::darkYellow), Not(Qt::darkYellow), Not(Qt::darkYellow)),
|
||||||
|
ElementsAre(Not(Qt::darkYellow), Not(Qt::darkYellow), Not(Qt::darkYellow), Qt::darkYellow),
|
||||||
|
ElementsAre(Not(Qt::darkYellow), Not(Qt::darkYellow), Not(Qt::darkYellow), Qt::darkYellow)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, SettingValueChangesByDisplayRoleBackgroundColor)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.setValue(0, 0, "foo", Qt::DisplayRole);
|
||||||
|
|
||||||
|
ASSERT_THAT(
|
||||||
|
backgroundColors(),
|
||||||
|
ElementsAre(
|
||||||
|
ElementsAre(Not(Qt::darkYellow), Not(Qt::darkYellow), Not(Qt::darkYellow), Not(Qt::darkYellow)),
|
||||||
|
ElementsAre(Not(Qt::darkYellow), Not(Qt::darkYellow), Not(Qt::darkYellow), Qt::darkYellow),
|
||||||
|
ElementsAre(Not(Qt::darkYellow), Not(Qt::darkYellow), Not(Qt::darkYellow), Qt::darkYellow)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, ResettingValueChangesBackgroundColor)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.setValue(1, 1, QVariant{});
|
||||||
|
|
||||||
|
ASSERT_THAT(
|
||||||
|
backgroundColors(),
|
||||||
|
ElementsAre(
|
||||||
|
ElementsAre(Qt::darkYellow, Not(Qt::darkYellow), Not(Qt::darkYellow), Not(Qt::darkYellow)),
|
||||||
|
ElementsAre(Not(Qt::darkYellow), Qt::darkYellow, Not(Qt::darkYellow), Qt::darkYellow),
|
||||||
|
ElementsAre(Not(Qt::darkYellow), Not(Qt::darkYellow), Not(Qt::darkYellow), Qt::darkYellow)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, ResettingValueChangesByDisplayRoleBackgroundColor)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.setValue(1, 1, QVariant{}, Qt::DisplayRole);
|
||||||
|
|
||||||
|
ASSERT_THAT(
|
||||||
|
backgroundColors(),
|
||||||
|
ElementsAre(
|
||||||
|
ElementsAre(Qt::darkYellow, Not(Qt::darkYellow), Not(Qt::darkYellow), Not(Qt::darkYellow)),
|
||||||
|
ElementsAre(Not(Qt::darkYellow), Qt::darkYellow, Not(Qt::darkYellow), Qt::darkYellow),
|
||||||
|
ElementsAre(Not(Qt::darkYellow), Not(Qt::darkYellow), Not(Qt::darkYellow), Qt::darkYellow)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, SettingNullValueChangesBackgroundColor)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.setValue(0, 0, 0);
|
||||||
|
|
||||||
|
ASSERT_THAT(backgroundColors(),
|
||||||
|
ElementsAre(ElementsAre(_, _, _, _),
|
||||||
|
ElementsAre(_, _, _, Qt::darkYellow),
|
||||||
|
ElementsAre(_, _, _, Qt::darkYellow)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, DontRenamePropertyIfColumnNameExists)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(1, "value2");
|
||||||
|
|
||||||
|
ASSERT_THAT(model.propertyNames(), ElementsAre("image", "name", "value", "value2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, DontRenameColumnIfColumnNameExists)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(1, "value2");
|
||||||
|
|
||||||
|
ASSERT_THAT(headerLabels(model), ElementsAre("image", "name", "value", "value2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, DontRenameColumnIfColumnNameExistsDoesNotChangeDisplayValues)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(1, "value2");
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(),
|
||||||
|
ElementsAre(ElementsAre(IsInvalid(), "foo", 1, 42),
|
||||||
|
ElementsAre("pic.png", "bar", 4, IsInvalid()),
|
||||||
|
ElementsAre("pic.png", "poo", 111, IsInvalid())));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, DontRenameColumnIfColumnNameExistsDoesNotChangeProperties)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(1, "value2");
|
||||||
|
|
||||||
|
ASSERT_THAT(properties(),
|
||||||
|
ElementsAre(UnorderedElementsAre(IsVariantProperty("name", "foo"),
|
||||||
|
IsVariantProperty("value", 1),
|
||||||
|
IsVariantProperty("value2", 42)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("image", "pic.png"),
|
||||||
|
IsVariantProperty("name", "bar"),
|
||||||
|
IsVariantProperty("value", 4)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("image", "pic.png"),
|
||||||
|
IsVariantProperty("name", "poo"),
|
||||||
|
IsVariantProperty("value", 111))));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RenamePropertyButDontChangeOrder)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(1, "mood");
|
||||||
|
|
||||||
|
ASSERT_THAT(model.propertyNames(), ElementsAre("image", "mood", "value", "value2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RenameColumnButDontChangeOrder)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(1, "mood");
|
||||||
|
|
||||||
|
ASSERT_THAT(headerLabels(model), ElementsAre("image", "mood", "value", "value2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RenameColumnButDontChangeOrderDisplayValues)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(1, "mood");
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(),
|
||||||
|
ElementsAre(ElementsAre(IsInvalid(), "foo", 1, 42),
|
||||||
|
ElementsAre("pic.png", "bar", 4, IsInvalid()),
|
||||||
|
ElementsAre("pic.png", "poo", 111, IsInvalid())));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RenameColumnButDontChangeOrderProperies)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(1, "mood");
|
||||||
|
|
||||||
|
ASSERT_THAT(properties(),
|
||||||
|
ElementsAre(UnorderedElementsAre(IsVariantProperty("mood", "foo"),
|
||||||
|
IsVariantProperty("value", 1),
|
||||||
|
IsVariantProperty("value2", 42)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("image", "pic.png"),
|
||||||
|
IsVariantProperty("mood", "bar"),
|
||||||
|
IsVariantProperty("value", 4)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("image", "pic.png"),
|
||||||
|
IsVariantProperty("mood", "poo"),
|
||||||
|
IsVariantProperty("value", 111))));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RemoveColumnAfterRenameColumn)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
model.renameColumn(1, "mood");
|
||||||
|
|
||||||
|
model.removeColumn(1);
|
||||||
|
|
||||||
|
ASSERT_THAT(properties(),
|
||||||
|
ElementsAre(UnorderedElementsAre(IsVariantProperty("value", 1),
|
||||||
|
IsVariantProperty("value2", 42)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("image", "pic.png"),
|
||||||
|
IsVariantProperty("value", 4)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("image", "pic.png"),
|
||||||
|
IsVariantProperty("value", 111))));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, ChangeValueAfterRenameColumn)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
model.renameColumn(1, "mood");
|
||||||
|
|
||||||
|
model.setValue(1, 1, "taaa");
|
||||||
|
|
||||||
|
ASSERT_THAT(properties(),
|
||||||
|
ElementsAre(UnorderedElementsAre(IsVariantProperty("mood", "foo"),
|
||||||
|
IsVariantProperty("value", 1),
|
||||||
|
IsVariantProperty("value2", 42)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("image", "pic.png"),
|
||||||
|
IsVariantProperty("mood", "taaa"),
|
||||||
|
IsVariantProperty("value", 4)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("image", "pic.png"),
|
||||||
|
IsVariantProperty("mood", "poo"),
|
||||||
|
IsVariantProperty("value", 111))));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RemovePropertyAfterRenameColumn)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
model.renameColumn(1, "mood");
|
||||||
|
|
||||||
|
model.setValue(1, 1, {});
|
||||||
|
|
||||||
|
ASSERT_THAT(properties(),
|
||||||
|
ElementsAre(UnorderedElementsAre(IsVariantProperty("mood", "foo"),
|
||||||
|
IsVariantProperty("value", 1),
|
||||||
|
IsVariantProperty("value2", 42)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("image", "pic.png"),
|
||||||
|
IsVariantProperty("value", 4)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("image", "pic.png"),
|
||||||
|
IsVariantProperty("mood", "poo"),
|
||||||
|
IsVariantProperty("value", 111))));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RenameToPrecedingProperty)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(1, "alpha");
|
||||||
|
|
||||||
|
ASSERT_THAT(model.propertyNames(), ElementsAre("alpha", "image", "value", "value2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RenameToPrecedingColumn)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(1, "alpha");
|
||||||
|
|
||||||
|
ASSERT_THAT(headerLabels(model), ElementsAre("alpha", "image", "value", "value2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RenameToPrecedingColumnDisplayValues)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(1, "alpha");
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(),
|
||||||
|
ElementsAre(ElementsAre("foo", IsInvalid(), 1, 42),
|
||||||
|
ElementsAre("bar", "pic.png", 4, IsInvalid()),
|
||||||
|
ElementsAre("poo", "pic.png", 111, IsInvalid())));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RenameToPrecedingColumnProperties)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(1, "alpha");
|
||||||
|
|
||||||
|
ASSERT_THAT(properties(),
|
||||||
|
ElementsAre(UnorderedElementsAre(IsVariantProperty("alpha", "foo"),
|
||||||
|
IsVariantProperty("value", 1),
|
||||||
|
IsVariantProperty("value2", 42)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("image", "pic.png"),
|
||||||
|
IsVariantProperty("alpha", "bar"),
|
||||||
|
IsVariantProperty("value", 4)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("image", "pic.png"),
|
||||||
|
IsVariantProperty("alpha", "poo"),
|
||||||
|
IsVariantProperty("value", 111))));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RenameToFollowingProperty)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(2, "zoo");
|
||||||
|
|
||||||
|
ASSERT_THAT(model.propertyNames(), ElementsAre("image", "name", "value2", "zoo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RenameToFollowingColumn)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(2, "zoo");
|
||||||
|
|
||||||
|
ASSERT_THAT(headerLabels(model), ElementsAre("image", "name", "value2", "zoo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RenameToFollowingColumnDisplayValues)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(2, "zoo");
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(),
|
||||||
|
ElementsAre(ElementsAre(IsInvalid(), "foo", 42, 1),
|
||||||
|
ElementsAre("pic.png", "bar", IsInvalid(), 4),
|
||||||
|
ElementsAre("pic.png", "poo", IsInvalid(), 111)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RenameToFollowingColumnProperties)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(2, "zoo");
|
||||||
|
|
||||||
|
ASSERT_THAT(properties(),
|
||||||
|
ElementsAre(UnorderedElementsAre(IsVariantProperty("name", "foo"),
|
||||||
|
IsVariantProperty("zoo", 1),
|
||||||
|
IsVariantProperty("value2", 42)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("image", "pic.png"),
|
||||||
|
IsVariantProperty("name", "bar"),
|
||||||
|
IsVariantProperty("zoo", 4)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("image", "pic.png"),
|
||||||
|
IsVariantProperty("name", "poo"),
|
||||||
|
IsVariantProperty("zoo", 111))));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RenamePropertiesWithInvalidValue)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
|
||||||
|
model.renameColumn(0, "mood");
|
||||||
|
|
||||||
|
ASSERT_THAT(properties(),
|
||||||
|
ElementsAre(UnorderedElementsAre(IsVariantProperty("name", "foo"),
|
||||||
|
IsVariantProperty("value", 1),
|
||||||
|
IsVariantProperty("value2", 42)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("mood", "pic.png"),
|
||||||
|
IsVariantProperty("name", "bar"),
|
||||||
|
IsVariantProperty("value", 4)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("mood", "pic.png"),
|
||||||
|
IsVariantProperty("name", "poo"),
|
||||||
|
IsVariantProperty("value", 111))));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, ChangeValueAfterRenamePropertiesWithInvalidValue)
|
||||||
|
{
|
||||||
|
model.setListModel(listModelNode);
|
||||||
|
model.renameColumn(0, "mood");
|
||||||
|
|
||||||
|
model.setValue(0, 0, "haaa");
|
||||||
|
|
||||||
|
ASSERT_THAT(properties(),
|
||||||
|
ElementsAre(UnorderedElementsAre(IsVariantProperty("mood", "haaa"),
|
||||||
|
IsVariantProperty("name", "foo"),
|
||||||
|
IsVariantProperty("value", 1),
|
||||||
|
IsVariantProperty("value2", 42)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("mood", "pic.png"),
|
||||||
|
IsVariantProperty("name", "bar"),
|
||||||
|
IsVariantProperty("value", 4)),
|
||||||
|
UnorderedElementsAre(IsVariantProperty("mood", "pic.png"),
|
||||||
|
IsVariantProperty("name", "poo"),
|
||||||
|
IsVariantProperty("value", 111))));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RemoveLastRow)
|
||||||
|
{
|
||||||
|
model.setListModel(emptyListModelNode);
|
||||||
|
model.addColumn("mood");
|
||||||
|
model.addRow();
|
||||||
|
|
||||||
|
model.removeRow(0);
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(), IsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RemoveLastColumn)
|
||||||
|
{
|
||||||
|
model.setListModel(emptyListModelNode);
|
||||||
|
model.addColumn("mood");
|
||||||
|
model.addRow();
|
||||||
|
|
||||||
|
model.removeColumn(0);
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(), ElementsAre(IsEmpty()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RemoveLastEmptyColumn)
|
||||||
|
{
|
||||||
|
model.setListModel(emptyListModelNode);
|
||||||
|
model.addColumn("mood");
|
||||||
|
model.addRow();
|
||||||
|
model.removeRow(0);
|
||||||
|
|
||||||
|
model.removeColumn(0);
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(), IsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(ListModelEditor, RemoveLastEmptyRow)
|
||||||
|
{
|
||||||
|
model.setListModel(emptyListModelNode);
|
||||||
|
model.addColumn("mood");
|
||||||
|
model.addRow();
|
||||||
|
model.removeColumn(0);
|
||||||
|
|
||||||
|
model.removeRow(0);
|
||||||
|
|
||||||
|
ASSERT_THAT(displayValues(), IsEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
@@ -34,4 +34,5 @@ class MockFileSystem : public ClangBackEnd::FileSystemInterface
|
|||||||
public:
|
public:
|
||||||
MOCK_CONST_METHOD1(directoryEntries, ClangBackEnd::FilePathIds(const QString &directoryPath));
|
MOCK_CONST_METHOD1(directoryEntries, ClangBackEnd::FilePathIds(const QString &directoryPath));
|
||||||
MOCK_CONST_METHOD1(lastModified, long long(ClangBackEnd::FilePathId filePathId));
|
MOCK_CONST_METHOD1(lastModified, long long(ClangBackEnd::FilePathId filePathId));
|
||||||
|
MOCK_METHOD1(remove, void(const ClangBackEnd::FilePathIds &filePathIds));
|
||||||
};
|
};
|
||||||
|
59
tests/unit/unittest/mocklistmodeleditorview.h
Normal file
59
tests/unit/unittest/mocklistmodeleditorview.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
**
|
||||||
|
** Copyright (C) 2020 The Qt Company Ltd.
|
||||||
|
** Contact: https://www.qt.io/licensing/
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator.
|
||||||
|
**
|
||||||
|
** 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 <googletest.h>
|
||||||
|
|
||||||
|
#include <qmldesigner/designercore/include/abstractview.h>
|
||||||
|
|
||||||
|
class MockListModelEditorView : public QmlDesigner::AbstractView
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
variantPropertiesChanged,
|
||||||
|
(const QList<QmlDesigner::VariantProperty> &propertyList,
|
||||||
|
PropertyChangeFlags propertyChange),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(void, nodeCreated, (const QmlDesigner::ModelNode &createdNode), (override));
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
nodeReparented,
|
||||||
|
(const QmlDesigner::ModelNode &node,
|
||||||
|
const QmlDesigner::NodeAbstractProperty &newPropertyParent,
|
||||||
|
const QmlDesigner::NodeAbstractProperty &oldPropertyParent,
|
||||||
|
AbstractView::PropertyChangeFlags propertyChange),
|
||||||
|
(override));
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
propertiesRemoved,
|
||||||
|
(const QList<QmlDesigner::AbstractProperty> &propertyList),
|
||||||
|
(override));
|
||||||
|
|
||||||
|
MOCK_METHOD(void,
|
||||||
|
nodeRemoved,
|
||||||
|
(const QmlDesigner::ModelNode &removedNode,
|
||||||
|
const QmlDesigner::NodeAbstractProperty &parentProperty,
|
||||||
|
AbstractView::PropertyChangeFlags propertyChange),
|
||||||
|
(override));
|
||||||
|
};
|
@@ -57,4 +57,5 @@ public:
|
|||||||
MOCK_CONST_METHOD1(
|
MOCK_CONST_METHOD1(
|
||||||
fetchTimeStamps,
|
fetchTimeStamps,
|
||||||
ClangBackEnd::PrecompiledHeaderTimeStamps(ClangBackEnd::ProjectPartId projectPartId));
|
ClangBackEnd::PrecompiledHeaderTimeStamps(ClangBackEnd::ProjectPartId projectPartId));
|
||||||
|
MOCK_CONST_METHOD0(fetchAllPchPaths, ClangBackEnd::FilePaths());
|
||||||
};
|
};
|
||||||
|
@@ -107,6 +107,12 @@ FilePathIds MockSqliteReadStatement::values<ClangBackEnd::FilePathId>(std::size_
|
|||||||
return valuesReturnFilePathIds(reserveSize, projectPartId);
|
return valuesReturnFilePathIds(reserveSize, projectPartId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
ClangBackEnd::FilePaths MockSqliteReadStatement::values<ClangBackEnd::FilePath>(std::size_t reserveSize)
|
||||||
|
{
|
||||||
|
return valuesReturnFilePaths(reserveSize);
|
||||||
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
std::vector<Sources::Directory> MockSqliteReadStatement::values<Sources::Directory, 2>(std::size_t reserveSize)
|
std::vector<Sources::Directory> MockSqliteReadStatement::values<Sources::Directory, 2>(std::size_t reserveSize)
|
||||||
{
|
{
|
||||||
|
@@ -113,6 +113,8 @@ public:
|
|||||||
|
|
||||||
MOCK_METHOD1(valueReturnFilePath, Utils::optional<ClangBackEnd::FilePath>(int));
|
MOCK_METHOD1(valueReturnFilePath, Utils::optional<ClangBackEnd::FilePath>(int));
|
||||||
|
|
||||||
|
MOCK_METHOD1(valuesReturnFilePaths, ClangBackEnd::FilePaths(std::size_t));
|
||||||
|
|
||||||
MOCK_METHOD1(valueReturnSmallString,
|
MOCK_METHOD1(valueReturnSmallString,
|
||||||
Utils::optional<Utils::SmallString>(int));
|
Utils::optional<Utils::SmallString>(int));
|
||||||
|
|
||||||
@@ -233,6 +235,9 @@ template<>
|
|||||||
FilePathIds MockSqliteReadStatement::values<ClangBackEnd::FilePathId>(std::size_t reserveSize,
|
FilePathIds MockSqliteReadStatement::values<ClangBackEnd::FilePathId>(std::size_t reserveSize,
|
||||||
const int &projectPartId);
|
const int &projectPartId);
|
||||||
|
|
||||||
|
template<>
|
||||||
|
ClangBackEnd::FilePaths MockSqliteReadStatement::values<ClangBackEnd::FilePath>(std::size_t reserveSize);
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
std::vector<Sources::Directory> MockSqliteReadStatement::values<Sources::Directory, 2>(std::size_t reserveSize);
|
std::vector<Sources::Directory> MockSqliteReadStatement::values<Sources::Directory, 2>(std::size_t reserveSize);
|
||||||
|
|
||||||
|
@@ -25,14 +25,18 @@
|
|||||||
|
|
||||||
#include "googletest.h"
|
#include "googletest.h"
|
||||||
|
|
||||||
|
#include "mockfilesystem.h"
|
||||||
#include "mockpchcreator.h"
|
#include "mockpchcreator.h"
|
||||||
#include "mockprecompiledheaderstorage.h"
|
#include "mockprecompiledheaderstorage.h"
|
||||||
#include "mocksqlitetransactionbackend.h"
|
#include "mocksqlitetransactionbackend.h"
|
||||||
#include "mocktaskscheduler.h"
|
#include "mocktaskscheduler.h"
|
||||||
#include "testenvironment.h"
|
#include "testenvironment.h"
|
||||||
|
|
||||||
|
#include <filepathcaching.h>
|
||||||
#include <pchtaskqueue.h>
|
#include <pchtaskqueue.h>
|
||||||
#include <progresscounter.h>
|
#include <progresscounter.h>
|
||||||
|
#include <refactoringdatabaseinitializer.h>
|
||||||
|
#include <sqlitedatabase.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@@ -45,9 +49,26 @@ using ClangBackEnd::SlotUsage;
|
|||||||
class PchTaskQueue : public testing::Test
|
class PchTaskQueue : public testing::Test
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
|
ClangBackEnd::FilePathId filePathId(Utils::SmallStringView path)
|
||||||
|
{
|
||||||
|
return filePathCache.filePathId(ClangBackEnd::FilePathView{path});
|
||||||
|
}
|
||||||
|
|
||||||
|
ClangBackEnd::FilePathIds filePathIds(const Utils::PathStringVector &paths)
|
||||||
|
{
|
||||||
|
return filePathCache.filePathIds(Utils::transform(paths, [](const Utils::PathString &path) {
|
||||||
|
return ClangBackEnd::FilePathView(path);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory};
|
||||||
|
ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database};
|
||||||
|
ClangBackEnd::FilePathCaching filePathCache{database};
|
||||||
NiceMock<MockTaskScheduler<ClangBackEnd::PchTaskQueue::Task>> mockSytemPchTaskScheduler;
|
NiceMock<MockTaskScheduler<ClangBackEnd::PchTaskQueue::Task>> mockSytemPchTaskScheduler;
|
||||||
NiceMock<MockTaskScheduler<ClangBackEnd::PchTaskQueue::Task>> mockProjectPchTaskScheduler;
|
NiceMock<MockTaskScheduler<ClangBackEnd::PchTaskQueue::Task>> mockProjectPchTaskScheduler;
|
||||||
NiceMock<MockPrecompiledHeaderStorage> mockPrecompiledHeaderStorage;
|
NiceMock<MockPrecompiledHeaderStorage> mockPrecompiledHeaderStorage;
|
||||||
|
NiceMock<MockFileSystem> mockFileSystem;
|
||||||
MockSqliteTransactionBackend mockSqliteTransactionBackend;
|
MockSqliteTransactionBackend mockSqliteTransactionBackend;
|
||||||
NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback;
|
NiceMock<MockFunction<void(int, int)>> mockSetProgressCallback;
|
||||||
ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()};
|
ClangBackEnd::ProgressCounter progressCounter{mockSetProgressCallback.AsStdFunction()};
|
||||||
@@ -57,7 +78,9 @@ protected:
|
|||||||
progressCounter,
|
progressCounter,
|
||||||
mockPrecompiledHeaderStorage,
|
mockPrecompiledHeaderStorage,
|
||||||
mockSqliteTransactionBackend,
|
mockSqliteTransactionBackend,
|
||||||
testEnvironment};
|
testEnvironment,
|
||||||
|
mockFileSystem,
|
||||||
|
filePathCache};
|
||||||
IncludeSearchPaths systemIncludeSearchPaths{
|
IncludeSearchPaths systemIncludeSearchPaths{
|
||||||
{"/includes", 1, IncludeSearchPathType::BuiltIn},
|
{"/includes", 1, IncludeSearchPathType::BuiltIn},
|
||||||
{"/other/includes", 2, IncludeSearchPathType::System}};
|
{"/other/includes", 2, IncludeSearchPathType::System}};
|
||||||
@@ -390,4 +413,91 @@ TEST_F(PchTaskQueue, DeleteSystemPchEntryInDatabaseIfNoPchIsGenerated)
|
|||||||
tasks.front()(mockPchCreator);
|
tasks.front()(mockPchCreator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PchTaskQueue, DontDeleteUnusedPchsIfSystemTaskAreProcessed)
|
||||||
|
{
|
||||||
|
QString pchsDirectory{testEnvironment.pchBuildDirectory()};
|
||||||
|
ON_CALL(mockSytemPchTaskScheduler, slotUsage()).WillByDefault(Return(SlotUsage{2, 1}));
|
||||||
|
ON_CALL(mockProjectPchTaskScheduler, slotUsage()).WillByDefault(Return(SlotUsage{2, 0}));
|
||||||
|
ON_CALL(mockFileSystem, directoryEntries(Eq(pchsDirectory)))
|
||||||
|
.WillByDefault(Return(filePathIds({"/tmp/foo", "/tmp/bar"})));
|
||||||
|
ON_CALL(mockPrecompiledHeaderStorage, fetchAllPchPaths())
|
||||||
|
.WillByDefault(Return(ClangBackEnd::FilePaths{"/tmp/foo", "/tmp/poo"}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mockFileSystem, remove(_)).Times(0);
|
||||||
|
|
||||||
|
queue.processEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchTaskQueue, DontDeleteUnusedPchsIfProjectTaskAreProcessed)
|
||||||
|
{
|
||||||
|
QString pchsDirectory{testEnvironment.pchBuildDirectory()};
|
||||||
|
ON_CALL(mockSytemPchTaskScheduler, slotUsage()).WillByDefault(Return(SlotUsage{2, 0}));
|
||||||
|
ON_CALL(mockProjectPchTaskScheduler, slotUsage()).WillByDefault(Return(SlotUsage{2, 1}));
|
||||||
|
ON_CALL(mockFileSystem, directoryEntries(Eq(pchsDirectory)))
|
||||||
|
.WillByDefault(Return(filePathIds({"/tmp/foo", "/tmp/bar"})));
|
||||||
|
ON_CALL(mockPrecompiledHeaderStorage, fetchAllPchPaths())
|
||||||
|
.WillByDefault(Return(ClangBackEnd::FilePaths{"/tmp/foo", "/tmp/poo"}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mockFileSystem, remove(_)).Times(0);
|
||||||
|
|
||||||
|
queue.processEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchTaskQueue, DontDeleteUnusedPchsIfSystemTaskIsAdded)
|
||||||
|
{
|
||||||
|
QString pchsDirectory{testEnvironment.pchBuildDirectory()};
|
||||||
|
ON_CALL(mockSytemPchTaskScheduler, slotUsage()).WillByDefault(Return(SlotUsage{2, 0}));
|
||||||
|
ON_CALL(mockProjectPchTaskScheduler, slotUsage()).WillByDefault(Return(SlotUsage{2, 0}));
|
||||||
|
ON_CALL(mockFileSystem, directoryEntries(Eq(pchsDirectory)))
|
||||||
|
.WillByDefault(Return(filePathIds({"/tmp/foo", "/tmp/bar"})));
|
||||||
|
ON_CALL(mockPrecompiledHeaderStorage, fetchAllPchPaths())
|
||||||
|
.WillByDefault(Return(ClangBackEnd::FilePaths{"/tmp/foo", "/tmp/poo"}));
|
||||||
|
queue.addSystemPchTasks({systemTask1});
|
||||||
|
|
||||||
|
EXPECT_CALL(mockFileSystem, remove(_)).Times(0);
|
||||||
|
|
||||||
|
queue.processEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchTaskQueue, DontDeleteUnusedPchsIfProjectTaskIsAdded)
|
||||||
|
{
|
||||||
|
QString pchsDirectory{testEnvironment.pchBuildDirectory()};
|
||||||
|
ON_CALL(mockSytemPchTaskScheduler, slotUsage()).WillByDefault(Return(SlotUsage{2, 0}));
|
||||||
|
ON_CALL(mockProjectPchTaskScheduler, slotUsage()).WillByDefault(Return(SlotUsage{2, 0}));
|
||||||
|
ON_CALL(mockFileSystem, directoryEntries(Eq(pchsDirectory)))
|
||||||
|
.WillByDefault(Return(filePathIds({"/tmp/foo", "/tmp/bar"})));
|
||||||
|
ON_CALL(mockPrecompiledHeaderStorage, fetchAllPchPaths())
|
||||||
|
.WillByDefault(Return(ClangBackEnd::FilePaths{"/tmp/foo", "/tmp/poo"}));
|
||||||
|
queue.addProjectPchTasks({projectTask1});
|
||||||
|
|
||||||
|
EXPECT_CALL(mockFileSystem, remove(_)).Times(0);
|
||||||
|
|
||||||
|
queue.processEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PchTaskQueue, DeleteUnusedPchs)
|
||||||
|
{
|
||||||
|
QString pchsDirectory{testEnvironment.pchBuildDirectory()};
|
||||||
|
ON_CALL(mockSytemPchTaskScheduler, slotUsage()).WillByDefault(Return(SlotUsage{2, 0}));
|
||||||
|
ON_CALL(mockProjectPchTaskScheduler, slotUsage()).WillByDefault(Return(SlotUsage{2, 0}));
|
||||||
|
ON_CALL(mockFileSystem, directoryEntries(Eq(pchsDirectory)))
|
||||||
|
.WillByDefault(Return(filePathIds({
|
||||||
|
"/tmp/foo",
|
||||||
|
"/tmp/bar",
|
||||||
|
"/tmp/hoo",
|
||||||
|
"/tmp/too",
|
||||||
|
})));
|
||||||
|
ON_CALL(mockPrecompiledHeaderStorage, fetchAllPchPaths())
|
||||||
|
.WillByDefault(Return(ClangBackEnd::FilePaths{
|
||||||
|
"/tmp/foo",
|
||||||
|
"/tmp/poo",
|
||||||
|
"/tmp/too",
|
||||||
|
}));
|
||||||
|
|
||||||
|
EXPECT_CALL(mockFileSystem,
|
||||||
|
remove(UnorderedElementsAre(filePathId("/tmp/bar"), filePathId("/tmp/hoo"))));
|
||||||
|
|
||||||
|
queue.processEntries();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -53,6 +53,7 @@ protected:
|
|||||||
MockSqliteReadStatement &fetchPrecompiledHeaderStatement = storage.fetchPrecompiledHeaderStatement;
|
MockSqliteReadStatement &fetchPrecompiledHeaderStatement = storage.fetchPrecompiledHeaderStatement;
|
||||||
MockSqliteReadStatement &fetchPrecompiledHeadersStatement = storage.fetchPrecompiledHeadersStatement;
|
MockSqliteReadStatement &fetchPrecompiledHeadersStatement = storage.fetchPrecompiledHeadersStatement;
|
||||||
MockSqliteReadStatement &fetchTimeStampsStatement = storage.fetchTimeStampsStatement;
|
MockSqliteReadStatement &fetchTimeStampsStatement = storage.fetchTimeStampsStatement;
|
||||||
|
MockSqliteReadStatement &fetchAllPchPathsStatement = storage.fetchAllPchPathsStatement;
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(PrecompiledHeaderStorage, UseTransaction)
|
TEST_F(PrecompiledHeaderStorage, UseTransaction)
|
||||||
@@ -458,6 +459,32 @@ TEST_F(PrecompiledHeaderStorage, FetchTimeStampsBusy)
|
|||||||
storage.fetchTimeStamps(23);
|
storage.fetchTimeStamps(23);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PrecompiledHeaderStorage, FetchAllPchPaths)
|
||||||
|
{
|
||||||
|
InSequence s;
|
||||||
|
|
||||||
|
EXPECT_CALL(database, deferredBegin());
|
||||||
|
EXPECT_CALL(fetchAllPchPathsStatement, valuesReturnFilePaths(_));
|
||||||
|
EXPECT_CALL(database, commit());
|
||||||
|
|
||||||
|
storage.fetchAllPchPaths();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(PrecompiledHeaderStorage, FetchAllPchPathsIsBusy)
|
||||||
|
{
|
||||||
|
InSequence s;
|
||||||
|
|
||||||
|
EXPECT_CALL(database, deferredBegin());
|
||||||
|
EXPECT_CALL(fetchAllPchPathsStatement, valuesReturnFilePaths(_))
|
||||||
|
.WillOnce(Throw(Sqlite::StatementIsBusy{""}));
|
||||||
|
EXPECT_CALL(database, rollback());
|
||||||
|
EXPECT_CALL(database, deferredBegin());
|
||||||
|
EXPECT_CALL(fetchAllPchPathsStatement, valuesReturnFilePaths(_));
|
||||||
|
EXPECT_CALL(database, commit());
|
||||||
|
|
||||||
|
storage.fetchAllPchPaths();
|
||||||
|
}
|
||||||
|
|
||||||
class PrecompiledHeaderStorageSlowTest : public testing::Test
|
class PrecompiledHeaderStorageSlowTest : public testing::Test
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@@ -478,4 +505,18 @@ TEST_F(PrecompiledHeaderStorageSlowTest, NoFetchTimeStamps)
|
|||||||
Field(&ClangBackEnd::PrecompiledHeaderTimeStamps::system, Eq(33))));
|
Field(&ClangBackEnd::PrecompiledHeaderTimeStamps::system, Eq(33))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(PrecompiledHeaderStorageSlowTest, FetchAllPchPaths)
|
||||||
|
{
|
||||||
|
storage.insertProjectPrecompiledHeader(11, "/tmp/yi", 22);
|
||||||
|
storage.insertProjectPrecompiledHeader(12, "/tmp/er", 22);
|
||||||
|
storage.insertSystemPrecompiledHeaders({11, 12}, "/tmp/se", 33);
|
||||||
|
storage.insertSystemPrecompiledHeaders({13}, "/tmp/wu", 33);
|
||||||
|
storage.insertProjectPrecompiledHeader(13, "/tmp/san", 22);
|
||||||
|
|
||||||
|
auto filePathIds = storage.fetchAllPchPaths();
|
||||||
|
|
||||||
|
ASSERT_THAT(filePathIds,
|
||||||
|
UnorderedElementsAre("/tmp/er", "/tmp/san", "/tmp/se", "/tmp/wu", "/tmp/yi"));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
INCLUDEPATH += ../mockup
|
INCLUDEPATH += ../mockup
|
||||||
|
INCLUDEPATH += ../mockup/qmldesigner/designercore/include
|
||||||
|
|
||||||
QT += core network testlib widgets
|
QT += core network testlib widgets
|
||||||
CONFIG += console c++14 testcase
|
CONFIG += console c++14 testcase
|
||||||
@@ -38,8 +39,11 @@ CONFIG(release, debug|release):QMAKE_LFLAGS += -Wl,--strip-debug
|
|||||||
}
|
}
|
||||||
|
|
||||||
gcc:!clang: QMAKE_CXXFLAGS += -Wno-noexcept-type
|
gcc:!clang: QMAKE_CXXFLAGS += -Wno-noexcept-type
|
||||||
msvc: QMAKE_CXXFLAGS += /bigobj /wd4267 /wd4141 /wd4146
|
msvc{
|
||||||
|
QMAKE_CXXFLAGS += /bigobj /wd4267 /wd4141 /wd4146 /wd4624
|
||||||
|
QMAKE_LFLAGS += /INCREMENTAL
|
||||||
|
|
||||||
|
}
|
||||||
# create fake CppTools.json for the mime type definitions
|
# create fake CppTools.json for the mime type definitions
|
||||||
dependencyList = "\"Dependencies\" : []"
|
dependencyList = "\"Dependencies\" : []"
|
||||||
cpptoolsjson.input = $$PWD/../../../src/plugins/cpptools/CppTools.json.in
|
cpptoolsjson.input = $$PWD/../../../src/plugins/cpptools/CppTools.json.in
|
||||||
@@ -65,6 +69,7 @@ SOURCES += \
|
|||||||
gtest-qt-printing.cpp \
|
gtest-qt-printing.cpp \
|
||||||
lastchangedrowid-test.cpp \
|
lastchangedrowid-test.cpp \
|
||||||
lineprefixer-test.cpp \
|
lineprefixer-test.cpp \
|
||||||
|
listmodeleditor-test.cpp \
|
||||||
locatorfilter-test.cpp \
|
locatorfilter-test.cpp \
|
||||||
mimedatabase-utilities.cpp \
|
mimedatabase-utilities.cpp \
|
||||||
pchmanagerclientserverinprocess-test.cpp \
|
pchmanagerclientserverinprocess-test.cpp \
|
||||||
@@ -132,18 +137,15 @@ SOURCES += \
|
|||||||
sqlstatementbuilder-test.cpp \
|
sqlstatementbuilder-test.cpp \
|
||||||
createtablesqlstatementbuilder-test.cpp
|
createtablesqlstatementbuilder-test.cpp
|
||||||
|
|
||||||
!isEmpty(QTC_UNITTEST_BUILD_CPP_PARSER):matchingtext-test.cpp
|
!isEmpty(QTC_UNITTEST_BUILD_CPP_PARSER):SOURCES += matchingtext-test.cpp
|
||||||
|
|
||||||
!isEmpty(LIBCLANG_LIBS) {
|
!isEmpty(LIBCLANG_LIBS) {
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
activationsequencecontextprocessor-test.cpp \
|
|
||||||
activationsequenceprocessor-test.cpp \
|
|
||||||
chunksreportedmonitor.cpp \
|
chunksreportedmonitor.cpp \
|
||||||
clangasyncjob-base.cpp \
|
clangasyncjob-base.cpp \
|
||||||
clangcodecompleteresults-test.cpp \
|
clangcodecompleteresults-test.cpp \
|
||||||
clangcodemodelserver-test.cpp \
|
clangcodemodelserver-test.cpp \
|
||||||
clangcompletecodejob-test.cpp \
|
clangcompletecodejob-test.cpp \
|
||||||
clangcompletioncontextanalyzer-test.cpp \
|
|
||||||
clangdiagnosticfilter-test.cpp \
|
clangdiagnosticfilter-test.cpp \
|
||||||
clangdocumentprocessors-test.cpp \
|
clangdocumentprocessors-test.cpp \
|
||||||
clangdocumentprocessor-test.cpp \
|
clangdocumentprocessor-test.cpp \
|
||||||
@@ -183,6 +185,12 @@ SOURCES += \
|
|||||||
unsavedfile-test.cpp \
|
unsavedfile-test.cpp \
|
||||||
utf8positionfromlinecolumn-test.cpp \
|
utf8positionfromlinecolumn-test.cpp \
|
||||||
readexporteddiagnostics-test.cpp
|
readexporteddiagnostics-test.cpp
|
||||||
|
|
||||||
|
!isEmpty(QTC_UNITTEST_BUILD_CPP_PARSER):SOURCE += \
|
||||||
|
clangcompletioncontextanalyzer-test.cpp \
|
||||||
|
activationsequencecontextprocessor-test.cpp \
|
||||||
|
activationsequenceprocessor-test.cpp
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
!isEmpty(LIBTOOLING_LIBS) {
|
!isEmpty(LIBTOOLING_LIBS) {
|
||||||
@@ -198,7 +206,6 @@ SOURCES += \
|
|||||||
refactoringclientserverinprocess-test.cpp \
|
refactoringclientserverinprocess-test.cpp \
|
||||||
refactoringclient-test.cpp \
|
refactoringclient-test.cpp \
|
||||||
refactoringcompilationdatabase-test.cpp \
|
refactoringcompilationdatabase-test.cpp \
|
||||||
refactoringengine-test.cpp \
|
|
||||||
refactoringserver-test.cpp \
|
refactoringserver-test.cpp \
|
||||||
sourcerangeextractor-test.cpp \
|
sourcerangeextractor-test.cpp \
|
||||||
symbolindexing-test.cpp \
|
symbolindexing-test.cpp \
|
||||||
@@ -207,6 +214,9 @@ SOURCES += \
|
|||||||
usedmacrocollector-test.cpp \
|
usedmacrocollector-test.cpp \
|
||||||
builddependencycollector-test.cpp \
|
builddependencycollector-test.cpp \
|
||||||
tokenprocessor-test.cpp
|
tokenprocessor-test.cpp
|
||||||
|
|
||||||
|
!isEmpty(QTC_UNITTEST_BUILD_CPP_PARSER):SOURCES += refactoringengine-test.cpp
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
!isEmpty(CLANGFORMAT_LIBS) {
|
!isEmpty(CLANGFORMAT_LIBS) {
|
||||||
@@ -237,6 +247,7 @@ HEADERS += \
|
|||||||
mockclangpathwatcher.h \
|
mockclangpathwatcher.h \
|
||||||
mockclangpathwatchernotifier.h \
|
mockclangpathwatchernotifier.h \
|
||||||
mockfilesystem.h \
|
mockfilesystem.h \
|
||||||
|
mocklistmodeleditorview.h \
|
||||||
mockpchcreator.h \
|
mockpchcreator.h \
|
||||||
mockpchmanagerclient.h \
|
mockpchmanagerclient.h \
|
||||||
mockpchmanagernotifier.h \
|
mockpchmanagernotifier.h \
|
||||||
@@ -288,7 +299,11 @@ HEADERS += \
|
|||||||
mockbuilddependencygenerator.h \
|
mockbuilddependencygenerator.h \
|
||||||
mockpchtasksmerger.h \
|
mockpchtasksmerger.h \
|
||||||
mockpchtaskqueue.h \
|
mockpchtaskqueue.h \
|
||||||
mockpchtaskgenerator.h
|
mockpchtaskgenerator.h \
|
||||||
|
../mockup/qmldesigner/designercore/include/nodeinstanceview.h \
|
||||||
|
../mockup/qmldesigner/designercore/include/rewriterview.h \
|
||||||
|
../mockup/qmldesigner/designercore/include/itemlibraryitem.h
|
||||||
|
|
||||||
|
|
||||||
!isEmpty(LIBCLANG_LIBS) {
|
!isEmpty(LIBCLANG_LIBS) {
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
Reference in New Issue
Block a user