QmlDesigner: Refactor PropertyEditorView::setupQmlBackend()

Change-Id: I535785659cdb7ceb108c34c5135769ba01dc78f8
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
This commit is contained in:
Marco Bubke
2023-08-10 10:31:13 +02:00
parent d11f3202a2
commit e010bab8ea
4 changed files with 109 additions and 51 deletions

View File

@@ -955,19 +955,22 @@ void PropertyEditorQmlBackend::setValueforAuxiliaryProperties(const QmlObjectNod
setValue(qmlObjectNode, propertyName, qmlObjectNode.modelNode().auxiliaryDataWithDefault(key)); setValue(qmlObjectNode, propertyName, qmlObjectNode.modelNode().auxiliaryDataWithDefault(key));
} }
QUrl PropertyEditorQmlBackend::getQmlUrlForMetaInfo(const NodeMetaInfo &metaInfo, TypeName &className) std::tuple<QUrl, NodeMetaInfo> PropertyEditorQmlBackend::getQmlUrlForMetaInfo(const NodeMetaInfo &metaInfo)
{ {
QString className;
if (metaInfo.isValid()) { if (metaInfo.isValid()) {
const NodeMetaInfos hierarchy = metaInfo.selfAndPrototypes(); const NodeMetaInfos hierarchy = metaInfo.selfAndPrototypes();
for (const NodeMetaInfo &info : hierarchy) { for (const NodeMetaInfo &info : hierarchy) {
QUrl fileUrl = fileToUrl(locateQmlFile(info, QString::fromUtf8(qmlFileName(info)))); QUrl fileUrl = fileToUrl(locateQmlFile(info, QString::fromUtf8(qmlFileName(info))));
if (fileUrl.isValid()) { if (fileUrl.isValid()) {
className = info.typeName(); return {fileUrl, info};
return fileUrl;
} }
} }
} }
return fileToUrl(QDir(propertyEditorResourcesPath()).filePath(QLatin1String("QtQuick/emptyPane.qml")));
return {fileToUrl(
QDir(propertyEditorResourcesPath()).filePath(QLatin1String("QtQuick/emptyPane.qml"))),
{}};
} }
QString PropertyEditorQmlBackend::locateQmlFile(const NodeMetaInfo &info, const QString &relativePath) QString PropertyEditorQmlBackend::locateQmlFile(const NodeMetaInfo &info, const QString &relativePath)

View File

@@ -51,7 +51,7 @@ public:
static QString templateGeneration(const NodeMetaInfo &type, const NodeMetaInfo &superType, const QmlObjectNode &node); static QString templateGeneration(const NodeMetaInfo &type, const NodeMetaInfo &superType, const QmlObjectNode &node);
static QUrl getQmlFileUrl(const TypeName &relativeTypeName, const NodeMetaInfo &info); static QUrl getQmlFileUrl(const TypeName &relativeTypeName, const NodeMetaInfo &info);
static QUrl getQmlUrlForMetaInfo(const NodeMetaInfo &modelNode, TypeName &className); static std::tuple<QUrl, NodeMetaInfo> getQmlUrlForMetaInfo(const NodeMetaInfo &modelNode);
static bool checkIfUrlExists(const QUrl &url); static bool checkIfUrlExists(const QUrl &url);

View File

@@ -437,80 +437,130 @@ void PropertyEditorView::resetView()
updateSize(); updateSize();
} }
namespace {
void PropertyEditorView::setupQmlBackend() std::tuple<NodeMetaInfo, QUrl> diffType(const NodeMetaInfo &commonAncestor,
const NodeMetaInfo &specificsClassMetaInfo)
{ {
TypeName specificsClassName; NodeMetaInfo diffClassMetaInfo;
const NodeMetaInfo commonAncestor = PropertyEditorQmlBackend::findCommonAncestor(m_selectedNode);
const QUrl qmlFile(PropertyEditorQmlBackend::getQmlUrlForMetaInfo(commonAncestor, specificsClassName));
QUrl qmlSpecificsFile; QUrl qmlSpecificsFile;
TypeName diffClassName;
if (commonAncestor.isValid()) { if (commonAncestor.isValid()) {
diffClassName = commonAncestor.typeName(); diffClassMetaInfo = commonAncestor;
const NodeMetaInfos hierarchy = commonAncestor.selfAndPrototypes(); const NodeMetaInfos hierarchy = commonAncestor.selfAndPrototypes();
for (const NodeMetaInfo &metaInfo : hierarchy) { for (const NodeMetaInfo &metaInfo : hierarchy) {
if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsFile)) if (PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsFile))
break; break;
qmlSpecificsFile = PropertyEditorQmlBackend::getQmlFileUrl(metaInfo.typeName() + "Specifics", metaInfo); qmlSpecificsFile = PropertyEditorQmlBackend::getQmlFileUrl(metaInfo.typeName() + "Specifics",
diffClassName = metaInfo.typeName(); metaInfo);
diffClassMetaInfo = metaInfo;
} }
} }
if (!PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsFile)) if (!PropertyEditorQmlBackend::checkIfUrlExists(qmlSpecificsFile))
diffClassName = specificsClassName; diffClassMetaInfo = specificsClassMetaInfo;
QString specificQmlData; return {diffClassMetaInfo, qmlSpecificsFile};
}
if (commonAncestor.isValid() && m_selectedNode.metaInfo().isValid() && diffClassName != m_selectedNode.type()) QString getSpecificQmlData(const NodeMetaInfo &commonAncestor,
specificQmlData = PropertyEditorQmlBackend::templateGeneration(commonAncestor, model()->metaInfo(diffClassName), m_selectedNode); const ModelNode &selectedNode,
const NodeMetaInfo &diffClassMetaInfo)
{
if (commonAncestor.isValid() && diffClassMetaInfo != selectedNode.metaInfo())
return PropertyEditorQmlBackend::templateGeneration(commonAncestor,
diffClassMetaInfo,
selectedNode);
PropertyEditorQmlBackend *currentQmlBackend = m_qmlBackendHash.value(qmlFile.toString()); return {};
}
QString currentStateName = currentState().isBaseState() ? currentState().name() : QStringLiteral("invalid state"); PropertyEditorQmlBackend *getQmlBackend(QHash<QString, PropertyEditorQmlBackend *> &qmlBackendHash,
const QUrl &qmlFileUrl,
AsynchronousImageCache &imageCache,
PropertyEditorWidget *stackedWidget,
PropertyEditorView *propertyEditorView)
{
auto qmlFileName = qmlFileUrl.toString();
PropertyEditorQmlBackend *currentQmlBackend = qmlBackendHash.value(qmlFileName);
if (!currentQmlBackend) { if (!currentQmlBackend) {
currentQmlBackend = new PropertyEditorQmlBackend(this, m_imageCache); currentQmlBackend = new PropertyEditorQmlBackend(propertyEditorView, imageCache);
m_stackedWidget->addWidget(currentQmlBackend->widget()); stackedWidget->addWidget(currentQmlBackend->widget());
m_qmlBackendHash.insert(qmlFile.toString(), currentQmlBackend); qmlBackendHash.insert(qmlFileName, currentQmlBackend);
if (m_selectedNode.isValid()) { currentQmlBackend->setSource(qmlFileUrl);
QmlObjectNode qmlObjectNode{m_selectedNode};
Q_ASSERT(qmlObjectNode.isValid());
currentQmlBackend->setup(qmlObjectNode, currentStateName, qmlSpecificsFile, this);
} }
return currentQmlBackend;
}
void setupCurrentQmlBackend(PropertyEditorQmlBackend *currentQmlBackend,
const ModelNode &selectedNode,
const QUrl &qmlSpecificsFile,
const QmlModelState &currentState,
PropertyEditorView *propertyEditorView,
const QString &specificQmlData)
{
QString currentStateName = currentState.isBaseState() ? currentState.name()
: QStringLiteral("invalid state");
QmlObjectNode qmlObjectNode{selectedNode};
if (specificQmlData.isEmpty()) if (specificQmlData.isEmpty())
currentQmlBackend->contextObject()->setSpecificQmlData(specificQmlData); currentQmlBackend->contextObject()->setSpecificQmlData(specificQmlData);
currentQmlBackend->setup(qmlObjectNode, currentStateName, qmlSpecificsFile, propertyEditorView);
currentQmlBackend->contextObject()->setSpecificQmlData(specificQmlData);
}
currentQmlBackend->contextObject()->setSpecificQmlData(specificQmlData); void setupInsight(const ModelNode &rootModelNode, PropertyEditorQmlBackend *currentQmlBackend)
currentQmlBackend->setSource(qmlFile); {
} else { if (rootModelNode.hasAuxiliaryData(insightEnabledProperty)) {
QmlObjectNode qmlObjectNode{m_selectedNode}; currentQmlBackend->contextObject()->setInsightEnabled(
rootModelNode.auxiliaryData(insightEnabledProperty)->toBool());
if (specificQmlData.isEmpty())
currentQmlBackend->contextObject()->setSpecificQmlData(specificQmlData);
currentQmlBackend->setup(qmlObjectNode, currentStateName, qmlSpecificsFile, this);
currentQmlBackend->contextObject()->setSpecificQmlData(specificQmlData);
} }
currentQmlBackend->widget()->installEventFilter(this); if (rootModelNode.hasAuxiliaryData(insightCategoriesProperty)) {
m_stackedWidget->setCurrentWidget(currentQmlBackend->widget()); currentQmlBackend->contextObject()->setInsightCategories(
rootModelNode.auxiliaryData(insightCategoriesProperty)->toStringList());
}
}
void setupWidget(PropertyEditorQmlBackend *currentQmlBackend,
PropertyEditorView *propertyEditorView,
QStackedWidget *stackedWidget)
{
currentQmlBackend->widget()->installEventFilter(propertyEditorView);
stackedWidget->setCurrentWidget(currentQmlBackend->widget());
currentQmlBackend->contextObject()->triggerSelectionChanged(); currentQmlBackend->contextObject()->triggerSelectionChanged();
}
} // namespace
void PropertyEditorView::setupQmlBackend()
{
const NodeMetaInfo commonAncestor = PropertyEditorQmlBackend::findCommonAncestor(m_selectedNode);
const auto [qmlFileUrl, specificsClassMetaInfo] = PropertyEditorQmlBackend::getQmlUrlForMetaInfo(
commonAncestor);
auto [diffClassMetaInfo, qmlSpecificsFile] = diffType(commonAncestor, specificsClassMetaInfo);
QString specificQmlData = getSpecificQmlData(commonAncestor, m_selectedNode, diffClassMetaInfo);
PropertyEditorQmlBackend *currentQmlBackend = getQmlBackend(m_qmlBackendHash,
qmlFileUrl,
m_imageCache,
m_stackedWidget,
this);
setupCurrentQmlBackend(
currentQmlBackend, m_selectedNode, qmlSpecificsFile, currentState(), this, specificQmlData);
setupWidget(currentQmlBackend, this, m_stackedWidget);
m_qmlBackEndForCurrentType = currentQmlBackend; m_qmlBackEndForCurrentType = currentQmlBackend;
if (rootModelNode().hasAuxiliaryData(insightEnabledProperty)) setupInsight(rootModelNode(), currentQmlBackend);
m_qmlBackEndForCurrentType->contextObject()->setInsightEnabled(
rootModelNode().auxiliaryData(insightEnabledProperty)->toBool());
if (rootModelNode().hasAuxiliaryData(insightCategoriesProperty))
m_qmlBackEndForCurrentType->contextObject()->setInsightCategories(
rootModelNode().auxiliaryData(insightCategoriesProperty)->toStringList());
} }
void PropertyEditorView::commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value) void PropertyEditorView::commitVariantValueToModel(const PropertyName &propertyName, const QVariant &value)

View File

@@ -204,6 +204,11 @@ public:
return first.m_privateData == second.m_privateData; return first.m_privateData == second.m_privateData;
} }
friend bool operator!=(const NodeMetaInfo &first, const NodeMetaInfo &second)
{
return !(first == second);
}
private: private:
const Storage::Info::Type &typeData() const; const Storage::Info::Type &typeData() const;
bool isSubclassOf(const TypeName &type, int majorVersion = -1, int minorVersion = -1) const; bool isSubclassOf(const TypeName &type, int majorVersion = -1, int minorVersion = -1) const;