diff options
4 files changed, 96 insertions, 25 deletions
diff --git a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp index fb7d4ce202..e0978df21c 100644 --- a/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp +++ b/src/plugins/qmldesigner/components/componentcore/designeractionmanager.cpp @@ -363,32 +363,30 @@ public: 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)); + AbstractView *view = targetNode.view(); + NodeMetaInfo modelMetaInfo = view->model()->metaInfo("ListModel"); + NodeMetaInfo elementMetaInfo = view->model()->metaInfo("ListElement"); + + ListModelEditorModel model{[&] { + return view->createModelNode(modelMetaInfo.typeName(), + modelMetaInfo.majorVersion(), + modelMetaInfo.minorVersion()); + }, + [&] { + return view->createModelNode(elementMetaInfo.typeName(), + elementMetaInfo.majorVersion(), + elementMetaInfo.minorVersion()); + }}; + + model.setListView(targetNode); ListModelEditorDialog dialog{Core::ICore::mainWindow()}; dialog.setModel(&model); diff --git a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp index 0aeabb8b89..48b1ad6fc9 100644 --- a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp +++ b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.cpp @@ -26,7 +26,9 @@ #include "listmodeleditormodel.h" #include <abstractview.h> +#include <bindingproperty.h> #include <nodelistproperty.h> +#include <nodeproperty.h> #include <variantproperty.h> #include <QVariant> @@ -185,6 +187,22 @@ void renameProperties(const QStandardItemModel *model, static_cast<ListModelItem *>(model->item(rowIndex, columnIndex))->renameProperty(newPropertyName); } +ModelNode listModelNode(const ModelNode &listViewNode, + const std::function<ModelNode()> &createModelCallback) +{ + 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 = createModelCallback(); + listViewNode.nodeProperty("model").reparentHere(newModel); + + return newModel; +} + } // namespace void ListModelEditorModel::populateModel() @@ -214,9 +232,20 @@ void ListModelEditorModel::appendItems(const ModelNode &listElementNode) appendRow(row); } +void ListModelEditorModel::setListModel(ModelNode node) +{ + m_listModelNode = node; + populateModel(); +} + +void ListModelEditorModel::setListView(ModelNode listView) +{ + setListModel(listModelNode(listView, m_createModelCallback)); +} + void ListModelEditorModel::addRow() { - auto newElement = m_listModelNode.view()->createModelNode("QtQml.Models.ListElement", 2, 15); + auto newElement = m_createElementCallback(); m_listModelNode.defaultNodeListProperty().reparentHere(newElement); appendItems(newElement); diff --git a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.h b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.h index 3056d32dbb..97bd9c18d8 100644 --- a/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.h +++ b/src/plugins/qmldesigner/components/listmodeleditor/listmodeleditormodel.h @@ -38,11 +38,15 @@ class ListModelEditorModel : public QStandardItemModel using QStandardItemModel::removeRows; public: - void setListModel(ModelNode node) - { - m_listModelNode = node; - populateModel(); - } + ListModelEditorModel(std::function<ModelNode()> createModelCallback, + std::function<ModelNode()> createElementCallback) + : m_createModelCallback(std::move(createModelCallback)) + , m_createElementCallback(std::move(createElementCallback)) + {} + + void setListModel(ModelNode node); + + void setListView(ModelNode listView); void addRow(); void addColumn(const QString &columnName); @@ -70,6 +74,8 @@ private: private: ModelNode m_listModelNode; QList<QmlDesigner::PropertyName> m_propertyNames; + std::function<ModelNode()> m_createModelCallback; + std::function<ModelNode()> m_createElementCallback; }; } // namespace QmlDesigner diff --git a/tests/unit/unittest/listmodeleditor-test.cpp b/tests/unit/unittest/listmodeleditor-test.cpp index af4009ae9b..0a5a91327a 100644 --- a/tests/unit/unittest/listmodeleditor-test.cpp +++ b/tests/unit/unittest/listmodeleditor-test.cpp @@ -31,8 +31,10 @@ #include <qmldesigner/components/listmodeleditor/listmodeleditormodel.h> #include <qmldesigner/designercore/include/abstractview.h> +#include <qmldesigner/designercore/include/bindingproperty.h> #include <qmldesigner/designercore/include/model.h> #include <qmldesigner/designercore/include/nodelistproperty.h> +#include <qmldesigner/designercore/include/nodeproperty.h> #include <qmldesigner/designercore/include/variantproperty.h> namespace { @@ -94,6 +96,7 @@ public: emptyListModelNode = mockView.createModelNode("QtQml.Models.ListModel", 2, 15); + listViewNode = mockView.createModelNode("QtQuick.ListView", 2, 15); listModelNode = mockView.createModelNode("QtQml.Models.ListModel", 2, 15); mockView.rootModelNode().defaultNodeListProperty().reparentHere(listModelNode); element1 = createElement({{"name", "foo"}, {"value", 1}, {"value2", 42}}); @@ -183,7 +186,10 @@ public: protected: std::unique_ptr<QmlDesigner::Model> designerModel{QmlDesigner::Model::create("QtQuick.Item", 1, 1)}; NiceMock<MockListModelEditorView> mockView; - QmlDesigner::ListModelEditorModel model; + QmlDesigner::ListModelEditorModel model{ + [&] { return mockView.createModelNode("QtQml.Models.ListModel", 2, 15); }, + [&] { return mockView.createModelNode("QtQml.Models.ListElement", 2, 15); }}; + ModelNode listViewNode; ModelNode listModelNode; ModelNode emptyListModelNode; ModelNode element1; @@ -1272,4 +1278,36 @@ TEST_F(ListModelEditor, SelectionAfterMoveRowsUp) index(2, 3))); } +TEST_F(ListModelEditor, ListViewHasNoModel) +{ + model.setListView(listViewNode); + + ASSERT_THAT(listViewNode.nodeProperty("model").modelNode().type(), Eq("QtQml.Models.ListModel")); +} + +TEST_F(ListModelEditor, ListViewHasModelInside) +{ + listViewNode.nodeProperty("model").reparentHere(listModelNode); + + model.setListView(listViewNode); + + ASSERT_THAT(displayValues(), + ElementsAre(ElementsAre(IsInvalid(), "foo", 1, 42), + ElementsAre("pic.png", "bar", 4, IsInvalid()), + ElementsAre("pic.png", "poo", 111, IsInvalid()))); +} + +TEST_F(ListModelEditor, ListViewHasModelBinding) +{ + listModelNode.setIdWithoutRefactoring("listModel"); + listViewNode.bindingProperty("model").setExpression("listModel"); + + model.setListView(listViewNode); + + ASSERT_THAT(displayValues(), + ElementsAre(ElementsAre(IsInvalid(), "foo", 1, 42), + ElementsAre("pic.png", "bar", 4, IsInvalid()), + ElementsAre("pic.png", "poo", 111, IsInvalid()))); +} + } // namespace |