forked from qt-creator/qt-creator
PropertyEditor: Forward currentNodes to backend
Since PropertyEditor has introduced `selection locking feature`, it should keep its own selection for the cases that the change should affect multiple nodes. It means that model selected node might be different than the propertyEditor working nodes. Also model selection changes should be notified separately. Change-Id: I692414811369680e16b3e25213bfa4b683576c55 Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -23,6 +23,7 @@ Rectangle {
|
||||
style: StudioTheme.Values.viewBarButtonStyle
|
||||
buttonIcon: StudioTheme.Constants.apply_medium
|
||||
tooltip: qsTr("Apply material to selected model.")
|
||||
enabled: has3DModelSelected
|
||||
onClicked: root.backend.toolBarAction(QmlMaterialNodeProxy.ApplyToSelected)
|
||||
}
|
||||
|
||||
|
@@ -164,7 +164,7 @@ Section {
|
||||
id: toolTipArea
|
||||
enabled: !modelNodeBackend.multiSelection && anchorBackend.hasParent
|
||||
anchors.fill: parent
|
||||
onClicked: toogleExportAlias()
|
||||
onClicked: toggleExportAlias()
|
||||
tooltip: qsTr("Exports this component as an alias property of the root component.")
|
||||
}
|
||||
}
|
||||
|
@@ -222,7 +222,7 @@ void MaterialEditorQmlBackend::setup(const QmlObjectNode &selectedMaterialNode,
|
||||
}
|
||||
|
||||
// model node
|
||||
m_backendModelNode.setup(selectedMaterialNode.modelNode());
|
||||
m_backendModelNode.setup(selectedMaterialNode);
|
||||
context()->setContextProperty("modelNodeBackend", &m_backendModelNode);
|
||||
context()->setContextProperty("hasMaterial", QVariant(true));
|
||||
|
||||
|
@@ -138,7 +138,7 @@ QStringList PropertyEditorContextObject::autoComplete(const QString &text, int p
|
||||
return {};
|
||||
}
|
||||
|
||||
void PropertyEditorContextObject::toogleExportAlias()
|
||||
void PropertyEditorContextObject::toggleExportAlias()
|
||||
{
|
||||
QTC_ASSERT(m_model && m_model->rewriterView(), return);
|
||||
|
||||
@@ -156,13 +156,13 @@ void PropertyEditorContextObject::toogleExportAlias()
|
||||
PropertyName modelNodeId = selectedNode.id().toUtf8();
|
||||
ModelNode rootModelNode = rewriterView->rootModelNode();
|
||||
|
||||
rewriterView->executeInTransaction("PropertyEditorContextObject:toogleExportAlias", [&objectNode, &rootModelNode, modelNodeId](){
|
||||
if (!objectNode.isAliasExported())
|
||||
objectNode.ensureAliasExport();
|
||||
else
|
||||
if (rootModelNode.hasProperty(modelNodeId))
|
||||
rootModelNode.removeProperty(modelNodeId);
|
||||
});
|
||||
rewriterView->executeInTransaction("PropertyEditorContextObject:toggleExportAlias",
|
||||
[&objectNode, &rootModelNode, modelNodeId]() {
|
||||
if (!objectNode.isAliasExported())
|
||||
objectNode.ensureAliasExport();
|
||||
else if (rootModelNode.hasProperty(modelNodeId))
|
||||
rootModelNode.removeProperty(modelNodeId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ void PropertyEditorContextObject::changeTypeName(const QString &typeName)
|
||||
try {
|
||||
auto transaction = RewriterTransaction(rewriterView, "PropertyEditorContextObject:changeTypeName");
|
||||
|
||||
ModelNodes selectedNodes = rewriterView->selectedModelNodes(); // TODO: replace it by PropertyEditorView::currentNodes()
|
||||
ModelNodes selectedNodes = m_editorNodes;
|
||||
for (ModelNode &selectedNode : selectedNodes)
|
||||
changeNodeTypeName(selectedNode);
|
||||
|
||||
@@ -489,9 +489,9 @@ bool PropertyEditorContextObject::hasQuick3DImport() const
|
||||
return m_hasQuick3DImport;
|
||||
}
|
||||
|
||||
void PropertyEditorContextObject::setSelectedNode(const ModelNode &node)
|
||||
void PropertyEditorContextObject::setEditorNodes(const ModelNodes &nodes)
|
||||
{
|
||||
m_selectedNode = node;
|
||||
m_editorNodes = nodes;
|
||||
}
|
||||
|
||||
void PropertyEditorContextObject::setHasQuick3DImport(bool value)
|
||||
@@ -531,18 +531,18 @@ void PropertyEditorContextObject::setIsQt6Project(bool value)
|
||||
emit isQt6ProjectChanged();
|
||||
}
|
||||
|
||||
bool PropertyEditorContextObject::has3DModelSelection() const
|
||||
bool PropertyEditorContextObject::has3DModelSelected() const
|
||||
{
|
||||
return m_has3DModelSelection;
|
||||
return m_has3DModelSelected;
|
||||
}
|
||||
|
||||
void PropertyEditorContextObject::set3DHasModelSelection(bool value)
|
||||
void PropertyEditorContextObject::setHas3DModelSelected(bool value)
|
||||
{
|
||||
if (value == m_has3DModelSelection)
|
||||
if (value == m_has3DModelSelected)
|
||||
return;
|
||||
|
||||
m_has3DModelSelection = value;
|
||||
emit has3DModelSelectionChanged();
|
||||
m_has3DModelSelected = value;
|
||||
emit has3DModelSelectedChanged();
|
||||
}
|
||||
|
||||
void PropertyEditorContextObject::setSpecificsUrl(const QUrl &newSpecificsUrl)
|
||||
|
@@ -57,7 +57,7 @@ class PropertyEditorContextObject : public QObject
|
||||
Q_PROPERTY(bool hasQuick3DImport READ hasQuick3DImport NOTIFY hasQuick3DImportChanged)
|
||||
Q_PROPERTY(bool hasMaterialLibrary READ hasMaterialLibrary NOTIFY hasMaterialLibraryChanged)
|
||||
Q_PROPERTY(bool isQt6Project READ isQt6Project NOTIFY isQt6ProjectChanged)
|
||||
Q_PROPERTY(bool has3DModelSelection READ has3DModelSelection NOTIFY has3DModelSelectionChanged)
|
||||
Q_PROPERTY(bool has3DModelSelected READ has3DModelSelected NOTIFY has3DModelSelectedChanged)
|
||||
|
||||
public:
|
||||
PropertyEditorContextObject(QQuickWidget *widget, QObject *parent = nullptr);
|
||||
@@ -78,7 +78,7 @@ public:
|
||||
|
||||
Q_INVOKABLE QStringList autoComplete(const QString &text, int pos, bool explicitComplete, bool filter);
|
||||
|
||||
Q_INVOKABLE void toogleExportAlias();
|
||||
Q_INVOKABLE void toggleExportAlias();
|
||||
|
||||
Q_INVOKABLE void goIntoComponent();
|
||||
|
||||
@@ -142,10 +142,10 @@ public:
|
||||
bool isQt6Project() const;
|
||||
void setIsQt6Project(bool value);
|
||||
|
||||
bool has3DModelSelection() const;
|
||||
void set3DHasModelSelection(bool value);
|
||||
bool has3DModelSelected() const;
|
||||
void setHas3DModelSelected(bool value);
|
||||
|
||||
void setSelectedNode(const ModelNode &node);
|
||||
void setEditorNodes(const ModelNodes &nodes);
|
||||
|
||||
void setIsSelectionLocked(bool lock);
|
||||
bool isSelectionLocked() const;
|
||||
@@ -169,7 +169,7 @@ signals:
|
||||
void hasMultiSelectionChanged();
|
||||
void hasQuick3DImportChanged();
|
||||
void hasMaterialLibraryChanged();
|
||||
void has3DModelSelectionChanged();
|
||||
void has3DModelSelectedChanged();
|
||||
void isQt6ProjectChanged();
|
||||
void isSelectionLockedChanged();
|
||||
|
||||
@@ -217,7 +217,7 @@ private:
|
||||
|
||||
bool m_hasQuick3DImport = false;
|
||||
bool m_hasMaterialLibrary = false;
|
||||
bool m_has3DModelSelection = false;
|
||||
bool m_has3DModelSelected = false;
|
||||
bool m_isQt6Project = false;
|
||||
|
||||
QQmlComponent *m_qmlComponent;
|
||||
@@ -240,7 +240,7 @@ private:
|
||||
bool m_insightEnabled = false;
|
||||
QStringList m_insightCategories;
|
||||
|
||||
ModelNode m_selectedNode;
|
||||
ModelNodes m_editorNodes; // Nodes that are being edited by PropertyEditor
|
||||
};
|
||||
|
||||
class EasingCurveEditor : public QObject
|
||||
|
@@ -375,6 +375,12 @@ void PropertyEditorQmlBackend::handleModelNodePreviewPixmapChanged(const ModelNo
|
||||
refreshPreview();
|
||||
}
|
||||
|
||||
void PropertyEditorQmlBackend::handleModelSelectedNodesChanged(PropertyEditorView *propertyEditor)
|
||||
{
|
||||
contextObject()->setHas3DModelSelected(!Utils3D::getSelectedModels(propertyEditor).isEmpty());
|
||||
m_backendTextureNode.updateSelectionDetails();
|
||||
}
|
||||
|
||||
void PropertyEditorQmlBackend::createPropertyEditorValue(const QmlObjectNode &qmlObjectNode,
|
||||
PropertyNameView name,
|
||||
const QVariant &value,
|
||||
@@ -566,108 +572,107 @@ void PropertyEditorQmlBackend::updateInstanceImage()
|
||||
refreshPreview();
|
||||
}
|
||||
|
||||
void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const QString &stateName, const QUrl &qmlSpecificsFile, PropertyEditorView *propertyEditor)
|
||||
void PropertyEditorQmlBackend::setup(const ModelNodes &editorNodes,
|
||||
const QString &stateName,
|
||||
const QUrl &qmlSpecificsFile,
|
||||
PropertyEditorView *propertyEditor)
|
||||
{
|
||||
if (qmlObjectNode.isValid()) {
|
||||
m_contextObject->setModel(propertyEditor->model());
|
||||
QmlObjectNode qmlObjectNode(editorNodes.isEmpty() ? ModelNode{} : editorNodes.first());
|
||||
if (!qmlObjectNode.isValid()) {
|
||||
qWarning() << "PropertyEditor: invalid node for setup";
|
||||
return;
|
||||
}
|
||||
|
||||
qCInfo(propertyEditorBenchmark) << Q_FUNC_INFO;
|
||||
m_contextObject->setModel(propertyEditor->model());
|
||||
|
||||
QElapsedTimer time;
|
||||
if (propertyEditorBenchmark().isInfoEnabled())
|
||||
time.start();
|
||||
qCInfo(propertyEditorBenchmark) << Q_FUNC_INFO;
|
||||
|
||||
createPropertyEditorValues(qmlObjectNode, propertyEditor);
|
||||
setupLayoutAttachedProperties(qmlObjectNode, propertyEditor);
|
||||
setupInsightAttachedProperties(qmlObjectNode, propertyEditor);
|
||||
setupAuxiliaryProperties(qmlObjectNode, propertyEditor);
|
||||
QElapsedTimer time;
|
||||
if (propertyEditorBenchmark().isInfoEnabled())
|
||||
time.start();
|
||||
|
||||
// model node
|
||||
m_backendModelNode.setup(qmlObjectNode.modelNode());
|
||||
context()->setContextProperty("modelNodeBackend", &m_backendModelNode);
|
||||
createPropertyEditorValues(qmlObjectNode, propertyEditor);
|
||||
setupLayoutAttachedProperties(qmlObjectNode, propertyEditor);
|
||||
setupInsightAttachedProperties(qmlObjectNode, propertyEditor);
|
||||
setupAuxiliaryProperties(qmlObjectNode, propertyEditor);
|
||||
|
||||
m_backendMaterialNode.setup(qmlObjectNode);
|
||||
m_backendTextureNode.setup(qmlObjectNode);
|
||||
// model node
|
||||
m_backendModelNode.setup(editorNodes);
|
||||
context()->setContextProperty("modelNodeBackend", &m_backendModelNode);
|
||||
|
||||
insertValue(Constants::PROPERTY_EDITOR_CLASSNAME_PROPERTY,
|
||||
m_backendModelNode.simplifiedTypeName(),
|
||||
qmlObjectNode.modelNode());
|
||||
m_backendMaterialNode.setup(editorNodes);
|
||||
m_backendTextureNode.setup(qmlObjectNode);
|
||||
|
||||
insertValue("id"_L1, m_backendModelNode.nodeId());
|
||||
insertValue("objectName"_L1, m_backendModelNode.nodeObjectName());
|
||||
insertValue(Constants::PROPERTY_EDITOR_CLASSNAME_PROPERTY,
|
||||
m_backendModelNode.simplifiedTypeName(),
|
||||
qmlObjectNode.modelNode());
|
||||
|
||||
QmlItemNode itemNode(qmlObjectNode.modelNode());
|
||||
insertValue("id"_L1, m_backendModelNode.nodeId());
|
||||
insertValue("objectName"_L1, m_backendModelNode.nodeObjectName());
|
||||
|
||||
// anchors
|
||||
m_backendAnchorBinding.setup(qmlObjectNode.modelNode());
|
||||
setupContextProperties();
|
||||
QmlItemNode itemNode(qmlObjectNode.modelNode());
|
||||
|
||||
contextObject()->setHasMultiSelection(
|
||||
!qmlObjectNode.view()->singleSelectedModelNode().isValid());
|
||||
// anchors
|
||||
m_backendAnchorBinding.setup(qmlObjectNode.modelNode());
|
||||
setupContextProperties();
|
||||
|
||||
qCInfo(propertyEditorBenchmark) << "anchors:" << time.elapsed();
|
||||
contextObject()->setHasMultiSelection(m_backendModelNode.multiSelection());
|
||||
|
||||
qCInfo(propertyEditorBenchmark) << "context:" << time.elapsed();
|
||||
qCInfo(propertyEditorBenchmark) << "anchors:" << time.elapsed();
|
||||
|
||||
contextObject()->setSpecificsUrl(qmlSpecificsFile);
|
||||
qCInfo(propertyEditorBenchmark) << "context:" << time.elapsed();
|
||||
|
||||
qCInfo(propertyEditorBenchmark) << "specifics:" << time.elapsed();
|
||||
contextObject()->setSpecificsUrl(qmlSpecificsFile);
|
||||
|
||||
contextObject()->setStateName(stateName);
|
||||
if (!qmlObjectNode.isValid())
|
||||
return;
|
||||
qCInfo(propertyEditorBenchmark) << "specifics:" << time.elapsed();
|
||||
|
||||
context()->setContextProperty(QLatin1String("propertyCount"),
|
||||
QVariant(qmlObjectNode.modelNode().properties().size()));
|
||||
contextObject()->setStateName(stateName);
|
||||
|
||||
QStringList stateNames = qmlObjectNode.allStateNames();
|
||||
stateNames.prepend("base state");
|
||||
contextObject()->setAllStateNames(stateNames);
|
||||
context()->setContextProperty(QLatin1String("propertyCount"),
|
||||
QVariant(qmlObjectNode.modelNode().properties().size()));
|
||||
|
||||
contextObject()->setIsBaseState(qmlObjectNode.isInBaseState());
|
||||
QStringList stateNames = qmlObjectNode.allStateNames();
|
||||
stateNames.prepend("base state");
|
||||
contextObject()->setAllStateNames(stateNames);
|
||||
|
||||
contextObject()->setHasAliasExport(qmlObjectNode.isAliasExported());
|
||||
contextObject()->setIsBaseState(qmlObjectNode.isInBaseState());
|
||||
|
||||
contextObject()->setHasActiveTimeline(QmlTimeline::hasActiveTimeline(qmlObjectNode.view()));
|
||||
contextObject()->setHasAliasExport(qmlObjectNode.isAliasExported());
|
||||
|
||||
contextObject()->setSelectionChanged(false);
|
||||
contextObject()->setHasActiveTimeline(QmlTimeline::hasActiveTimeline(qmlObjectNode.view()));
|
||||
|
||||
contextObject()->setSelectionChanged(false);
|
||||
contextObject()->setSelectionChanged(false);
|
||||
|
||||
NodeMetaInfo metaInfo = qmlObjectNode.modelNode().metaInfo();
|
||||
NodeMetaInfo metaInfo = qmlObjectNode.modelNode().metaInfo();
|
||||
|
||||
#ifdef QDS_USE_PROJECTSTORAGE
|
||||
contextObject()->setMajorVersion(-1);
|
||||
contextObject()->setMinorVersion(-1);
|
||||
contextObject()->setMajorQtQuickVersion(-1);
|
||||
contextObject()->setMinorQtQuickVersion(-1);
|
||||
#else
|
||||
if (metaInfo.isValid()) {
|
||||
contextObject()->setMajorVersion(metaInfo.majorVersion());
|
||||
contextObject()->setMinorVersion(metaInfo.minorVersion());
|
||||
} else {
|
||||
contextObject()->setMajorVersion(-1);
|
||||
contextObject()->setMinorVersion(-1);
|
||||
contextObject()->setMajorQtQuickVersion(-1);
|
||||
contextObject()->setMinorQtQuickVersion(-1);
|
||||
#else
|
||||
if (metaInfo.isValid()) {
|
||||
contextObject()->setMajorVersion(metaInfo.majorVersion());
|
||||
contextObject()->setMinorVersion(metaInfo.minorVersion());
|
||||
} else {
|
||||
contextObject()->setMajorVersion(-1);
|
||||
contextObject()->setMinorVersion(-1);
|
||||
contextObject()->setMajorQtQuickVersion(-1);
|
||||
contextObject()->setMinorQtQuickVersion(-1);
|
||||
}
|
||||
#endif
|
||||
contextObject()->setMajorQtQuickVersion(qmlObjectNode.view()->majorQtQuickVersion());
|
||||
contextObject()->setMinorQtQuickVersion(qmlObjectNode.view()->minorQtQuickVersion());
|
||||
|
||||
contextObject()->setHasMaterialLibrary(Utils3D::materialLibraryNode(propertyEditor).isValid());
|
||||
contextObject()->setIsQt6Project(propertyEditor->externalDependencies().isQt6Project());
|
||||
contextObject()->set3DHasModelSelection(!Utils3D::getSelectedModels(propertyEditor).isEmpty());
|
||||
contextObject()->setSelectedNode(qmlObjectNode);
|
||||
contextObject()->setHasQuick3DImport(propertyEditor->model()->hasImport("QtQuick3D"));
|
||||
|
||||
m_view->instanceImageProvider()->setModelNode(propertyEditor->firstSelectedModelNode());
|
||||
updateInstanceImage();
|
||||
|
||||
qCInfo(propertyEditorBenchmark) << "final:" << time.elapsed();
|
||||
} else {
|
||||
qWarning() << "PropertyEditor: invalid node for setup";
|
||||
}
|
||||
#endif
|
||||
contextObject()->setMajorQtQuickVersion(qmlObjectNode.view()->majorQtQuickVersion());
|
||||
contextObject()->setMinorQtQuickVersion(qmlObjectNode.view()->minorQtQuickVersion());
|
||||
|
||||
contextObject()->setHasMaterialLibrary(Utils3D::materialLibraryNode(propertyEditor).isValid());
|
||||
contextObject()->setIsQt6Project(propertyEditor->externalDependencies().isQt6Project());
|
||||
contextObject()->setEditorNodes(editorNodes);
|
||||
contextObject()->setHasQuick3DImport(propertyEditor->model()->hasImport("QtQuick3D"));
|
||||
|
||||
m_view->instanceImageProvider()->setModelNode(m_backendModelNode.singleSelectedNode());
|
||||
updateInstanceImage();
|
||||
|
||||
qCInfo(propertyEditorBenchmark) << "final:" << time.elapsed();
|
||||
}
|
||||
|
||||
QString PropertyEditorQmlBackend::propertyEditorResourcesPath()
|
||||
@@ -960,35 +965,6 @@ QString PropertyEditorQmlBackend::resourcesPath(const QString &dir)
|
||||
return Core::ICore::resourcePath("qmldesigner/" + dir).toUrlishString();
|
||||
}
|
||||
|
||||
static NodeMetaInfo findCommonSuperClass(const NodeMetaInfo &first, const NodeMetaInfo &second)
|
||||
{
|
||||
auto commonBase = first.commonBase(second);
|
||||
|
||||
return commonBase.isValid() ? commonBase : first;
|
||||
}
|
||||
|
||||
NodeMetaInfo PropertyEditorQmlBackend::findCommonAncestor(const ModelNode &node)
|
||||
{
|
||||
if (!node.isValid())
|
||||
return node.metaInfo();
|
||||
|
||||
AbstractView *view = node.view();
|
||||
|
||||
const QList<ModelNode> &selectedNodes = view->selectedModelNodes();
|
||||
if (selectedNodes.size() > 1) {
|
||||
NodeMetaInfo commonClass = node.metaInfo();
|
||||
|
||||
for (const ModelNode &selectedNode : selectedNodes) {
|
||||
const NodeMetaInfo &nodeMetaInfo = selectedNode.metaInfo();
|
||||
if (nodeMetaInfo.isValid() && !nodeMetaInfo.isBasedOn(commonClass))
|
||||
commonClass = findCommonSuperClass(nodeMetaInfo, commonClass);
|
||||
}
|
||||
return commonClass;
|
||||
}
|
||||
|
||||
return node.metaInfo();
|
||||
}
|
||||
|
||||
void PropertyEditorQmlBackend::refreshBackendModel()
|
||||
{
|
||||
m_backendModelNode.refresh();
|
||||
@@ -1064,7 +1040,6 @@ bool PropertyEditorQmlBackend::checkIfUrlExists(const QUrl &url)
|
||||
void PropertyEditorQmlBackend::emitSelectionToBeChanged()
|
||||
{
|
||||
m_backendModelNode.emitSelectionToBeChanged();
|
||||
m_backendTextureNode.updateSelectionDetails();
|
||||
}
|
||||
|
||||
void PropertyEditorQmlBackend::emitSelectionChanged()
|
||||
|
@@ -40,7 +40,10 @@ public:
|
||||
class AsynchronousImageCache &imageCache);
|
||||
~PropertyEditorQmlBackend();
|
||||
|
||||
void setup(const QmlObjectNode &fxObjectNode, const QString &stateName, const QUrl &qmlSpecificsFile, PropertyEditorView *propertyEditor);
|
||||
void setup(const ModelNodes &editorNodes,
|
||||
const QString &stateName,
|
||||
const QUrl &qmlSpecificsFile,
|
||||
PropertyEditorView *propertyEditor);
|
||||
void setValue(const QmlObjectNode &fxObjectNode, PropertyNameView name, const QVariant &value);
|
||||
void setExpression(PropertyNameView propName, const QString &exp);
|
||||
|
||||
@@ -94,8 +97,7 @@ public:
|
||||
void handleModelNodePreviewPixmapChanged(const ModelNode &node,
|
||||
const QPixmap &pixmap,
|
||||
const QByteArray &requestId);
|
||||
|
||||
static NodeMetaInfo findCommonAncestor(const ModelNode &node);
|
||||
void handleModelSelectedNodesChanged(PropertyEditorView *propertyEditor);
|
||||
|
||||
void refreshBackendModel();
|
||||
void refreshPreview();
|
||||
|
@@ -61,6 +61,13 @@ static bool propertyIsAttachedInsightProperty(PropertyNameView propertyName)
|
||||
return propertyName.contains("InsightCategory.");
|
||||
}
|
||||
|
||||
static NodeMetaInfo findCommonSuperClass(const NodeMetaInfo &first, const NodeMetaInfo &second)
|
||||
{
|
||||
auto commonBase = first.commonBase(second);
|
||||
|
||||
return commonBase.isValid() ? commonBase : first;
|
||||
}
|
||||
|
||||
PropertyEditorView::PropertyEditorView(AsynchronousImageCache &imageCache,
|
||||
ExternalDependenciesInterface &externalDependencies)
|
||||
: AbstractView(externalDependencies)
|
||||
@@ -428,6 +435,26 @@ PropertyEditorView *PropertyEditorView::instance()
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
NodeMetaInfo PropertyEditorView::findCommonAncestor(const ModelNode &node)
|
||||
{
|
||||
if (!node.isValid())
|
||||
return node.metaInfo();
|
||||
|
||||
const QList<ModelNode> allNodes = currentNodes();
|
||||
if (allNodes.size() > 1) {
|
||||
NodeMetaInfo commonClass = node.metaInfo();
|
||||
|
||||
for (const ModelNode &selectedNode : allNodes) {
|
||||
const NodeMetaInfo &nodeMetaInfo = selectedNode.metaInfo();
|
||||
if (nodeMetaInfo.isValid() && !nodeMetaInfo.isBasedOn(commonClass))
|
||||
commonClass = findCommonSuperClass(nodeMetaInfo, commonClass);
|
||||
}
|
||||
return commonClass;
|
||||
}
|
||||
|
||||
return node.metaInfo();
|
||||
}
|
||||
|
||||
void PropertyEditorView::updateSize()
|
||||
{
|
||||
if (!m_qmlBackEndForCurrentType)
|
||||
@@ -542,7 +569,7 @@ PropertyEditorQmlBackend *getQmlBackend(QHash<QString, PropertyEditorQmlBackend
|
||||
}
|
||||
|
||||
void setupCurrentQmlBackend(PropertyEditorQmlBackend *currentQmlBackend,
|
||||
const ModelNode &selectedNode,
|
||||
const ModelNodes &editorNodes,
|
||||
const QUrl &qmlSpecificsFile,
|
||||
const QmlModelState ¤tState,
|
||||
PropertyEditorView *propertyEditorView,
|
||||
@@ -551,10 +578,9 @@ void setupCurrentQmlBackend(PropertyEditorQmlBackend *currentQmlBackend,
|
||||
QString currentStateName = currentState.isBaseState() ? QStringLiteral("invalid state")
|
||||
: currentState.name();
|
||||
|
||||
QmlObjectNode qmlObjectNode{selectedNode};
|
||||
if (specificQmlData.isEmpty())
|
||||
currentQmlBackend->contextObject()->setSpecificQmlData(specificQmlData);
|
||||
currentQmlBackend->setup(qmlObjectNode, currentStateName, qmlSpecificsFile, propertyEditorView);
|
||||
currentQmlBackend->setup(editorNodes, currentStateName, qmlSpecificsFile, propertyEditorView);
|
||||
currentQmlBackend->contextObject()->setSpecificQmlData(specificQmlData);
|
||||
}
|
||||
|
||||
@@ -634,7 +660,7 @@ void PropertyEditorView::handleToolBarAction(int action)
|
||||
void PropertyEditorView::setupQmlBackend()
|
||||
{
|
||||
#ifdef QDS_USE_PROJECTSTORAGE
|
||||
const NodeMetaInfo commonAncestor = PropertyEditorQmlBackend::findCommonAncestor(activeNode());
|
||||
const NodeMetaInfo commonAncestor = findCommonAncestor(activeNode());
|
||||
auto selfAndPrototypes = commonAncestor.selfAndPrototypes();
|
||||
bool isEditableComponent = activeNode().isComponent()
|
||||
&& !QmlItemNode(activeNode()).isEffectItem();
|
||||
@@ -648,7 +674,7 @@ void PropertyEditorView::setupQmlBackend()
|
||||
m_stackedWidget,
|
||||
this);
|
||||
setupCurrentQmlBackend(currentQmlBackend,
|
||||
activeNode(),
|
||||
currentNodes(),
|
||||
QUrl::fromLocalFile(QString{specificsPath}),
|
||||
currentStateNode(),
|
||||
this,
|
||||
@@ -660,7 +686,7 @@ void PropertyEditorView::setupQmlBackend()
|
||||
|
||||
setupInsight(rootModelNode(), currentQmlBackend);
|
||||
#else
|
||||
const NodeMetaInfo commonAncestor = PropertyEditorQmlBackend::findCommonAncestor(activeNode());
|
||||
const NodeMetaInfo commonAncestor = findCommonAncestor(activeNode());
|
||||
|
||||
// qmlFileUrl is panel url. and specifics is its metainfo
|
||||
const auto [qmlFileUrl, specificsClassMetaInfo] = PropertyEditorQmlBackend::getQmlUrlForMetaInfo(
|
||||
@@ -681,7 +707,7 @@ void PropertyEditorView::setupQmlBackend()
|
||||
this);
|
||||
|
||||
setupCurrentQmlBackend(currentQmlBackend,
|
||||
activeNode(),
|
||||
currentNodes(),
|
||||
qmlSpecificsFile,
|
||||
currentStateNode(),
|
||||
this,
|
||||
@@ -788,10 +814,12 @@ QList<ModelNode> PropertyEditorView::currentNodes() const
|
||||
void PropertyEditorView::selectedNodesChanged(const QList<ModelNode> &,
|
||||
const QList<ModelNode> &)
|
||||
{
|
||||
if (m_isSelectionLocked)
|
||||
return;
|
||||
if (!m_isSelectionLocked)
|
||||
select();
|
||||
|
||||
select();
|
||||
// Notify model selection changes to backend regardless of being locked
|
||||
if (m_qmlBackEndForCurrentType)
|
||||
m_qmlBackEndForCurrentType->handleModelSelectedNodesChanged(this);
|
||||
}
|
||||
|
||||
bool PropertyEditorView::isNodeOrChildSelected(const ModelNode &node) const
|
||||
|
@@ -143,6 +143,8 @@ private: //functions
|
||||
|
||||
static PropertyEditorView *instance();
|
||||
|
||||
NodeMetaInfo findCommonAncestor(const ModelNode &node);
|
||||
|
||||
private: //variables
|
||||
AsynchronousImageCache &m_imageCache;
|
||||
ModelNode m_activeNode;
|
||||
|
@@ -41,11 +41,13 @@ QmlMaterialNodeProxy::QmlMaterialNodeProxy()
|
||||
|
||||
QmlMaterialNodeProxy::~QmlMaterialNodeProxy() = default;
|
||||
|
||||
void QmlMaterialNodeProxy::setup(const QmlObjectNode &objectNode)
|
||||
void QmlMaterialNodeProxy::setup(const ModelNodes &editorNodes)
|
||||
{
|
||||
QmlObjectNode objectNode = editorNodes.isEmpty() ? ModelNode{} : editorNodes.first();
|
||||
const QmlObjectNode material = objectNode.metaInfo().isQtQuick3DMaterial() ? objectNode
|
||||
: QmlObjectNode{};
|
||||
setMaterialNode(material);
|
||||
setEditorNodes(editorNodes);
|
||||
updatePossibleTypes();
|
||||
updatePreviewModel();
|
||||
}
|
||||
@@ -55,6 +57,11 @@ ModelNode QmlMaterialNodeProxy::materialNode() const
|
||||
return m_materialNode;
|
||||
}
|
||||
|
||||
ModelNodes QmlMaterialNodeProxy::editorNodes() const
|
||||
{
|
||||
return m_editorNodes;
|
||||
}
|
||||
|
||||
void QmlMaterialNodeProxy::setPossibleTypes(const QStringList &types)
|
||||
{
|
||||
if (types == m_possibleTypes)
|
||||
@@ -81,7 +88,7 @@ void QmlMaterialNodeProxy::updatePossibleTypes()
|
||||
}
|
||||
|
||||
const QString &matType = materialNode().simplifiedTypeName();
|
||||
const ModelNodes selectedNodes = materialView()->selectedModelNodes(); // TODO: replace it by PropertyEditorView::currentNodes()
|
||||
const ModelNodes selectedNodes = editorNodes();
|
||||
bool allAreBasic = Utils::allOf(selectedNodes, [&](const ModelNode &node) {
|
||||
return basicTypes.contains(node.simplifiedTypeName());
|
||||
});
|
||||
@@ -275,6 +282,11 @@ void QmlMaterialNodeProxy::setMaterialNode(const QmlObjectNode &material)
|
||||
emit materialNodeChanged();
|
||||
}
|
||||
|
||||
void QmlMaterialNodeProxy::setEditorNodes(const ModelNodes &editorNodes)
|
||||
{
|
||||
m_editorNodes = editorNodes;
|
||||
}
|
||||
|
||||
bool QmlMaterialNodeProxy::hasQuick3DImport() const
|
||||
{
|
||||
return materialNode().isValid() && materialNode().model()->hasImport("QtQuick3D"_L1);
|
||||
|
@@ -35,11 +35,12 @@ public:
|
||||
explicit QmlMaterialNodeProxy();
|
||||
~QmlMaterialNodeProxy() override;
|
||||
|
||||
void setup(const QmlObjectNode &objectNode);
|
||||
void setup(const ModelNodes &editorNodes);
|
||||
|
||||
QStringList possibleTypes() const { return m_possibleTypes; }
|
||||
|
||||
ModelNode materialNode() const;
|
||||
ModelNodes editorNodes() const;
|
||||
|
||||
int possibleTypeIndex() const { return m_possibleTypeIndex; }
|
||||
|
||||
@@ -67,15 +68,15 @@ private: // Methods
|
||||
void updatePossibleTypeIndex();
|
||||
void updatePreviewModel();
|
||||
void setMaterialNode(const QmlObjectNode &material);
|
||||
void setEditorNodes(const ModelNodes &editorNodes);
|
||||
|
||||
bool hasQuick3DImport() const;
|
||||
|
||||
AbstractView *materialView() const;
|
||||
|
||||
private:
|
||||
bool m_has3DModelSelection = false;
|
||||
|
||||
QmlObjectNode m_materialNode;
|
||||
ModelNodes m_editorNodes;
|
||||
|
||||
QStringList m_possibleTypes;
|
||||
int m_possibleTypeIndex = -1;
|
||||
|
@@ -22,9 +22,15 @@ QmlModelNodeProxy::QmlModelNodeProxy(QObject *parent) :
|
||||
{
|
||||
}
|
||||
|
||||
void QmlModelNodeProxy::setup(const QmlObjectNode &objectNode)
|
||||
void QmlModelNodeProxy::setup(const ModelNode &node)
|
||||
{
|
||||
m_qmlObjectNode = objectNode;
|
||||
setup(ModelNodes{node});
|
||||
}
|
||||
|
||||
void QmlModelNodeProxy::setup(const ModelNodes &editorNodes)
|
||||
{
|
||||
m_qmlObjectNode = editorNodes.isEmpty() ? ModelNode{} : editorNodes.first();
|
||||
m_editorNodes = editorNodes;
|
||||
|
||||
m_subselection.clear();
|
||||
|
||||
@@ -61,12 +67,22 @@ ModelNode QmlModelNodeProxy::modelNode() const
|
||||
return m_qmlObjectNode.modelNode();
|
||||
}
|
||||
|
||||
ModelNodes QmlModelNodeProxy::editorNodes() const
|
||||
{
|
||||
return m_editorNodes;
|
||||
}
|
||||
|
||||
ModelNode QmlModelNodeProxy::singleSelectedNode() const
|
||||
{
|
||||
return multiSelection() ? ModelNode{} : modelNode();
|
||||
}
|
||||
|
||||
bool QmlModelNodeProxy::multiSelection() const
|
||||
{
|
||||
if (!m_qmlObjectNode.isValid())
|
||||
return false;
|
||||
|
||||
return m_qmlObjectNode.view()->selectedModelNodes().size() > 1;
|
||||
return editorNodes().size() > 1;
|
||||
}
|
||||
|
||||
QString QmlModelNodeProxy::nodeId() const
|
||||
|
@@ -22,7 +22,8 @@ class QMLDESIGNER_EXPORT QmlModelNodeProxy : public QObject
|
||||
public:
|
||||
explicit QmlModelNodeProxy(QObject *parent = nullptr);
|
||||
|
||||
void setup(const QmlObjectNode &objectNode);
|
||||
void setup(const ModelNode &node);
|
||||
void setup(const ModelNodes &editorNodes);
|
||||
|
||||
static void registerDeclarativeType();
|
||||
|
||||
@@ -33,6 +34,8 @@ public:
|
||||
QmlObjectNode qmlObjectNode() const;
|
||||
|
||||
ModelNode modelNode() const;
|
||||
ModelNodes editorNodes() const;
|
||||
ModelNode singleSelectedNode() const;
|
||||
|
||||
bool multiSelection() const;
|
||||
|
||||
@@ -81,6 +84,7 @@ private:
|
||||
PropertyEditorSubSelectionWrapper *findWrapper(int internalId) const;
|
||||
|
||||
QmlObjectNode m_qmlObjectNode;
|
||||
ModelNodes m_editorNodes;
|
||||
QList<QSharedPointer<PropertyEditorSubSelectionWrapper>> m_subselection;
|
||||
};
|
||||
|
||||
|
@@ -211,7 +211,7 @@ void TextureEditorQmlBackend::setup(const QmlObjectNode &selectedTextureNode, co
|
||||
}
|
||||
|
||||
// model node
|
||||
m_backendModelNode.setup(selectedTextureNode.modelNode());
|
||||
m_backendModelNode.setup(selectedTextureNode);
|
||||
context()->setContextProperty("modelNodeBackend", &m_backendModelNode);
|
||||
context()->setContextProperty("hasTexture", QVariant(true));
|
||||
|
||||
|
Reference in New Issue
Block a user