diff --git a/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionView.qml b/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionView.qml index beaaad71641..4b2708e96ca 100644 --- a/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionView.qml +++ b/share/qtcreator/qmldesigner/collectionEditorQmlSource/CollectionView.qml @@ -41,6 +41,7 @@ Item { id: newCollection backendValue: root.rootView + sourceModel: root.model anchors.centerIn: parent } diff --git a/share/qtcreator/qmldesigner/collectionEditorQmlSource/NewCollectionDialog.qml b/share/qtcreator/qmldesigner/collectionEditorQmlSource/NewCollectionDialog.qml index b0cf950fd7a..83eb642f79d 100644 --- a/share/qtcreator/qmldesigner/collectionEditorQmlSource/NewCollectionDialog.qml +++ b/share/qtcreator/qmldesigner/collectionEditorQmlSource/NewCollectionDialog.qml @@ -3,23 +3,37 @@ import QtQuick import QtQuick.Controls +import QtQuick.Layouts import QtQuickDesignerTheme 1.0 +import Qt.labs.platform as PlatformWidgets import HelperWidgets 2.0 as HelperWidgets import StudioControls 1.0 as StudioControls import StudioTheme as StudioTheme +import CollectionEditor 1.0 StudioControls.Dialog { id: root + enum SourceType { NewJson, NewCsv, ExistingCollection, NewCollectionToJson } + + required property var backendValue + required property var sourceModel + + readonly property alias collectionType: typeMode.collectionType + readonly property bool isValid: collectionName.isValid + && jsonCollections.isValid + && newCollectionPath.isValid + title: qsTr("Add a new Collection") anchors.centerIn: parent closePolicy: Popup.CloseOnEscape modal: true - required property var backendValue - onOpened: { - collectionName.text = "Collection" + collectionName.text = qsTr("Collection") + updateType() + updateJsonSourceIndex() + updateCollectionExists() } onRejected: { @@ -27,24 +41,197 @@ StudioControls.Dialog { } onAccepted: { - if (collectionName.text !== "") - root.backendValue.addCollection(collectionName.text) + if (root.isValid) { + root.backendValue.addCollection(collectionName.text, + root.collectionType, + newCollectionPath.text, + jsonCollections.currentValue) + + } } - contentItem: Column { + function updateType() { + newCollectionPath.text = "" + if (typeMode.currentValue === NewCollectionDialog.SourceType.NewJson) { + newCollectionFileDialog.nameFilters = ["Json Files (*.json)"] + newCollectionFileDialog.fileMode = PlatformWidgets.FileDialog.SaveFile + newCollectionPath.enabled = true + jsonCollections.enabled = false + typeMode.collectionType = "json" + } else if (typeMode.currentValue === NewCollectionDialog.SourceType.NewCsv) { + newCollectionFileDialog.nameFilters = ["Comma-Separated Values (*.csv)"] + newCollectionFileDialog.fileMode = PlatformWidgets.FileDialog.SaveFile + newCollectionPath.enabled = true + jsonCollections.enabled = false + typeMode.collectionType = "csv" + } else if (typeMode.currentValue === NewCollectionDialog.SourceType.ExistingCollection) { + newCollectionFileDialog.nameFilters = ["All Collection Files (*.json *.csv)", + "Json Files (*.json)", + "Comma-Separated Values (*.csv)"] + newCollectionFileDialog.fileMode = PlatformWidgets.FileDialog.OpenFile + newCollectionPath.enabled = true + jsonCollections.enabled = false + typeMode.collectionType = "existing" + } else if (typeMode.currentValue === NewCollectionDialog.SourceType.NewCollectionToJson) { + newCollectionFileDialog.nameFilters = [""] + newCollectionPath.enabled = false + jsonCollections.enabled = true + typeMode.collectionType = "json" + } + } + + function updateJsonSourceIndex() { + if (!jsonCollections.enabled) { + jsonCollections.currentIndex = -1 + return + } + + if (jsonCollections.currentIndex === -1 && jsonCollections.model.rowCount()) + jsonCollections.currentIndex = 0 + } + + function updateCollectionExists() { + collectionName.alreadyExists = sourceModel.collectionExists(jsonCollections.currentValue, + collectionName.text) + } + + component NameField: Text { + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + horizontalAlignment: Qt.AlignRight + verticalAlignment: Qt.AlignCenter + color: StudioTheme.Values.themeTextColor + font.family: StudioTheme.Constants.font.family + font.pixelSize: StudioTheme.Values.baseIconFontSize + } + + component ErrorField: Text { + Layout.columnSpan: 2 + color: StudioTheme.Values.themeError + text: qsTr("Collection name can not be empty") + font.family: StudioTheme.Constants.font.family + font.pixelSize: StudioTheme.Values.baseIconFontSize + } + + contentItem: ColumnLayout { spacing: 10 - Row { - spacing: 10 - Text { - text: qsTr("Collection name: ") - anchors.verticalCenter: parent.verticalCenter - color: StudioTheme.Values.themeTextColor + GridLayout { + columns: 2 + rowSpacing: 10 + + NameField { + text: qsTr("Type") + } + + StudioControls.ComboBox { + id: typeMode + + property string collectionType + + Layout.minimumWidth: 300 + Layout.fillWidth: true + + model: ListModel { + ListElement { text: qsTr("New Json collection"); value: NewCollectionDialog.SourceType.NewJson} + ListElement { text: qsTr("New CSV collection"); value: NewCollectionDialog.SourceType.NewCsv} + ListElement { text: qsTr("Import an existing collection"); value: NewCollectionDialog.SourceType.ExistingCollection} + ListElement { text: qsTr("Add collection to an available JSON"); value: NewCollectionDialog.SourceType.NewCollectionToJson} + } + + textRole: "text" + valueRole: "value" + actionIndicatorVisible: false + + onCurrentValueChanged: root.updateType() + } + + NameField { + text: qsTr("File location") + visible: newCollectionPath.enabled + } + + RowLayout { + visible: newCollectionPath.enabled + + Text { + id: newCollectionPath + + readonly property bool isValid: !enabled || text !== "" + + Layout.fillWidth: true + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter + elide: Text.ElideRight + font.family: StudioTheme.Constants.font.family + font.pixelSize: StudioTheme.Values.baseIconFontSize + color: StudioTheme.Values.themePlaceholderTextColor + } + + HelperWidgets.Button { + Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter + text: qsTr("Select") + + onClicked: newCollectionFileDialog.open() + + PlatformWidgets.FileDialog { + id: newCollectionFileDialog + + title: "Select source file" + fileMode: PlatformWidgets.FileDialog.OpenFile + acceptLabel: fileMode === PlatformWidgets.FileDialog.OpenFile ? qsTr("Open") : qsTr("Add") + + onAccepted: newCollectionPath.text = newCollectionFileDialog.currentFile + } + } + } + + ErrorField { + visible: !newCollectionPath.isValid + text: qsTr("Select a file to continue") + } + + NameField { + text: qsTr("Json Collection") + visible: jsonCollections.enabled + } + + StudioControls.ComboBox { + id: jsonCollections + + readonly property bool isValid: !enabled || currentIndex !== -1 + + implicitWidth: 300 + textRole: "sourceName" + valueRole: "sourceNode" + visible: enabled + actionIndicatorVisible: false + + model: CollectionJsonSourceFilterModel { + sourceModel: root.sourceModel + onRowsInserted: root.updateJsonSourceIndex() + onModelReset: root.updateJsonSourceIndex() + onRowsRemoved: root.updateJsonSourceIndex() + } + + onEnabledChanged: root.updateJsonSourceIndex() + onCurrentValueChanged: root.updateCollectionExists() + } + + ErrorField { + visible: !jsonCollections.isValid + text: qsTr("Add a json resource to continue") + } + + NameField { + text: qsTr("Collection name") + visible: collectionName.enabled } StudioControls.TextField { id: collectionName - anchors.verticalCenter: parent.verticalCenter + readonly property bool isValid: !enabled || (text !== "" && !alreadyExists) + property bool alreadyExists + + visible: enabled actionIndicator.visible: false translationIndicator.visible: false validator: HelperWidgets.RegExpValidator { @@ -54,38 +241,42 @@ StudioControls.Dialog { Keys.onEnterPressed: btnCreate.onClicked() Keys.onReturnPressed: btnCreate.onClicked() Keys.onEscapePressed: root.reject() + + onTextChanged: root.updateCollectionExists() + } + + ErrorField { + text: qsTr("Collection name can not be empty") + visible: collectionName.enabled && collectionName.text === "" + } + + ErrorField { + text: qsTr("Collection name already exists %1").arg(collectionName.text) + visible: collectionName.enabled && collectionName.alreadyExists } } - Text { - id: fieldErrorText - color: StudioTheme.Values.themeTextColor - anchors.right: parent.right - text: qsTr("Collection name can not be empty") - visible: collectionName.text === "" - } - Item { // spacer - width: 1 - height: 20 + Layout.fillHeight: true + Layout.preferredWidth: 1 } - Row { - anchors.right: parent.right + RowLayout { spacing: 10 + Layout.alignment: Qt.AlignRight | Qt.AlignBottom HelperWidgets.Button { id: btnCreate - anchors.verticalCenter: parent.verticalCenter + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter text: qsTr("Create") - enabled: collectionName.text !== "" + enabled: root.isValid onClicked: root.accept() } HelperWidgets.Button { + Layout.alignment: Qt.AlignRight | Qt.AlignVCenter text: qsTr("Cancel") - anchors.verticalCenter: parent.verticalCenter onClicked: root.reject() } } diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp index b8596f81928..e082a54cc3f 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp @@ -485,7 +485,6 @@ void CollectionDetailsModel::loadJsonCollection(const QString &source, const QSt } if (collectionNodes.isEmpty()) { - closeCurrentCollectionIfSaved(); endResetModel(); return; }; diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionlistmodel.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectionlistmodel.cpp index 4c49d5e4954..2d7952c1021 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectionlistmodel.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectionlistmodel.cpp @@ -94,6 +94,11 @@ QString CollectionListModel::sourceAddress() const return m_sourceNode.variantProperty(CollectionEditor::SOURCEFILE_PROPERTY).value().toString(); } +bool CollectionListModel::contains(const QString &collectionName) const +{ + return stringList().contains(collectionName); +} + void CollectionListModel::selectCollectionIndex(int idx, bool selectAtLeastOne) { int collectionCount = stringList().size(); @@ -108,6 +113,13 @@ void CollectionListModel::selectCollectionIndex(int idx, bool selectAtLeastOne) setSelectedIndex(preferredIndex); } +void CollectionListModel::selectCollectionName(const QString &collectionName) +{ + int idx = stringList().indexOf(collectionName); + if (idx > -1) + selectCollectionIndex(idx); +} + QString CollectionListModel::collectionNameAt(int idx) const { return index(idx).data(NameRole).toString(); diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionlistmodel.h b/src/plugins/qmldesigner/components/collectioneditor/collectionlistmodel.h index e30b16a5ff7..8450ee62b74 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectionlistmodel.h +++ b/src/plugins/qmldesigner/components/collectioneditor/collectionlistmodel.h @@ -28,13 +28,16 @@ public: Q_INVOKABLE int selectedIndex() const; Q_INVOKABLE ModelNode sourceNode() const; Q_INVOKABLE QString sourceAddress() const; + Q_INVOKABLE bool contains(const QString &collectionName) const; void selectCollectionIndex(int idx, bool selectAtLeastOne = false); + void selectCollectionName(const QString &collectionName); QString collectionNameAt(int idx) const; signals: void selectedIndexChanged(int idx); void isEmptyChanged(bool); + void collectionNameChanged(const QString &oldName, const QString &newName); private: void setSelectedIndex(int idx); diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.cpp index 19dce052852..a33aff95787 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.cpp @@ -9,8 +9,11 @@ #include "variantproperty.h" #include +#include #include +#include +#include #include #include #include @@ -58,11 +61,26 @@ QSharedPointer loadCollection( } return collectionsList; } + +QString getSourceCollectionType(const QmlDesigner::ModelNode &node) +{ + using namespace QmlDesigner; + if (node.type() == CollectionEditor::JSONCOLLECTIONMODEL_TYPENAME) + return "json"; + + if (node.type() == CollectionEditor::CSVCOLLECTIONMODEL_TYPENAME) + return "csv"; + + return {}; +} + } // namespace namespace QmlDesigner { -CollectionSourceModel::CollectionSourceModel() {} +CollectionSourceModel::CollectionSourceModel(QObject *parent) + : Super(parent) +{} int CollectionSourceModel::rowCount(const QModelIndex &) const { @@ -80,6 +98,10 @@ QVariant CollectionSourceModel::data(const QModelIndex &index, int role) const return collectionSource->id(); case NameRole: return collectionSource->variantProperty("objectName").value(); + case NodeRole: + return QVariant::fromValue(*collectionSource); + case CollectionTypeRole: + return getSourceCollectionType(*collectionSource); case SourceRole: return collectionSource->variantProperty(CollectionEditor::SOURCEFILE_PROPERTY).value(); case SelectedRole: @@ -188,6 +210,8 @@ QHash CollectionSourceModel::roleNames() const roles.insert(Super::roleNames()); roles.insert({{IdRole, "sourceId"}, {NameRole, "sourceName"}, + {NodeRole, "sourceNode"}, + {CollectionTypeRole, "sourceCollectionType"}, {SelectedRole, "sourceIsSelected"}, {SourceRole, "sourceAddress"}, {CollectionsRole, "collections"}}); @@ -265,6 +289,83 @@ void CollectionSourceModel::selectSource(const ModelNode &node) selectSourceIndex(nodePlace, true); } +bool CollectionSourceModel::collectionExists(const ModelNode &node, const QString &collectionName) const +{ + int idx = sourceIndex(node); + if (idx < 0) + return false; + + auto collections = m_collectionList.at(idx); + if (collections.isNull()) + return false; + + return collections->contains(collectionName); +} + +bool CollectionSourceModel::addCollectionToSource(const ModelNode &node, + const QString &collectionName, + QString *errorString) +{ + auto returnError = [errorString](const QString &msg) -> bool { + if (errorString) + *errorString = msg; + return false; + }; + + int idx = sourceIndex(node); + if (idx < 0) + return returnError(tr("Node is not indexed in the collections model.")); + + if (node.type() != CollectionEditor::JSONCOLLECTIONMODEL_TYPENAME) + return returnError(tr("Node should be a json collection model.")); + + if (collectionExists(node, collectionName)) + return returnError(tr("Collection does not exist.")); + + QString sourceFileAddress = node.variantProperty(CollectionEditor::SOURCEFILE_PROPERTY) + .value() + .toString(); + + QFileInfo sourceFileInfo(sourceFileAddress); + if (!sourceFileInfo.isFile()) + return returnError(tr("Selected node should have a valid source file address")); + + QFile jsonFile(sourceFileAddress); + if (!jsonFile.open(QFile::ReadWrite)) + return returnError(tr("Can't open the file to read.\n") + jsonFile.errorString()); + + QJsonParseError parseError; + QJsonDocument document = QJsonDocument::fromJson(jsonFile.readAll(), &parseError); + if (parseError.error != QJsonParseError::NoError) + return returnError(tr("Saved json file is messy.\n") + parseError.errorString()); + + if (document.isObject()) { + QJsonObject sourceObject = document.object(); + sourceObject.insert(collectionName, QJsonArray{}); + document.setObject(sourceObject); + if (!jsonFile.resize(0)) + return returnError(tr("Can't clean the json file.")); + + QByteArray jsonData = document.toJson(); + auto writtenBytes = jsonFile.write(jsonData); + jsonFile.close(); + + if (writtenBytes != jsonData.size()) + return returnError(tr("Can't write to the json file.")); + + updateCollectionList(index(idx)); + + auto collections = m_collectionList.at(idx); + if (collections.isNull()) + return returnError(tr("No collection is available for the json file.")); + + collections->selectCollectionName(collectionName); + return true; + } else { + return returnError(tr("Json document type should be an object containing collections.")); + } +} + QmlDesigner::ModelNode CollectionSourceModel::sourceNodeAt(int idx) { QModelIndex data = index(idx); @@ -309,6 +410,11 @@ void CollectionSourceModel::updateSelectedSource(bool selectAtLeastOne) selectSourceIndex(idx, selectAtLeastOne); } +bool CollectionSourceModel::collectionExists(const QVariant &node, const QString &collectionName) const +{ + return collectionExists(node.value(), collectionName); +} + void CollectionSourceModel::updateNodeName(const ModelNode &node) { QModelIndex index = indexOfNode(node); @@ -412,4 +518,21 @@ QModelIndex CollectionSourceModel::indexOfNode(const ModelNode &node) const { return index(m_sourceIndexHash.value(node.internalId(), -1)); } + +void CollectionJsonSourceFilterModel::registerDeclarativeType() +{ + qmlRegisterType("CollectionEditor", + 1, + 0, + "CollectionJsonSourceFilterModel"); +} + +bool CollectionJsonSourceFilterModel::filterAcceptsRow(int source_row, const QModelIndex &) const +{ + if (!sourceModel()) + return false; + QModelIndex sourceItem = sourceModel()->index(source_row, 0, {}); + return sourceItem.data(CollectionSourceModel::Roles::CollectionTypeRole).toString() == "json"; +} + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.h b/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.h index 5a71635c874..447df5d5dea 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.h +++ b/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.h @@ -7,9 +7,13 @@ #include #include +#include namespace QmlDesigner { + +class CollectionJsonSourceFilterModel; class CollectionListModel; + class CollectionSourceModel : public QAbstractListModel { Q_OBJECT @@ -18,9 +22,17 @@ class CollectionSourceModel : public QAbstractListModel Q_PROPERTY(bool isEmpty MEMBER m_isEmpty NOTIFY isEmptyChanged) public: - enum Roles { IdRole = Qt::UserRole + 1, NameRole, SourceRole, SelectedRole, CollectionsRole }; + enum Roles { + IdRole = Qt::UserRole + 1, + NameRole, + NodeRole, + CollectionTypeRole, + SourceRole, + SelectedRole, + CollectionsRole + }; - explicit CollectionSourceModel(); + explicit CollectionSourceModel(QObject *parent = nullptr); virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override; virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; @@ -40,12 +52,19 @@ public: void addSource(const ModelNode &node); void selectSource(const ModelNode &node); + bool collectionExists(const ModelNode &node, const QString &collectionName) const; + bool addCollectionToSource(const ModelNode &node, + const QString &collectionName, + QString *errorString = nullptr); + ModelNode sourceNodeAt(int idx); CollectionListModel *selectedCollectionList(); Q_INVOKABLE void selectSourceIndex(int idx, bool selectAtLeastOne = false); Q_INVOKABLE void deselect(); Q_INVOKABLE void updateSelectedSource(bool selectAtLeastOne = false); + Q_INVOKABLE bool collectionExists(const QVariant &node, const QString &collectionName) const; + void updateNodeName(const ModelNode &node); void updateNodeSource(const ModelNode &node); void updateNodeId(const ModelNode &node); @@ -64,10 +83,10 @@ private: void setSelectedIndex(int idx); void updateEmpty(); void updateCollectionList(QModelIndex index); + QModelIndex indexOfNode(const ModelNode &node) const; using Super = QAbstractListModel; - QModelIndex indexOfNode(const ModelNode &node) const; ModelNodes m_collectionSources; QHash m_sourceIndexHash; // internalId -> index QList> m_collectionList; @@ -76,4 +95,15 @@ private: bool m_isEmpty = true; }; +class CollectionJsonSourceFilterModel : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + static void registerDeclarativeType(); + +protected: + bool filterAcceptsRow(int source_row, const QModelIndex &) const override; +}; + } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionview.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectionview.cpp index 6b0d063081f..c3ab244177a 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectionview.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectionview.cpp @@ -156,6 +156,7 @@ void CollectionView::addResource(const QUrl &url, const QString &name, const QSt void CollectionView::registerDeclarativeType() { CollectionDetails::registerDeclarativeType(); + CollectionJsonSourceFilterModel::registerDeclarativeType(); } void CollectionView::refreshModel() diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp index 12e9e9ee856..7811ee622cd 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp @@ -16,7 +16,9 @@ #include #include +#include #include +#include #include #include #include @@ -25,6 +27,7 @@ #include namespace { + QString collectionViewResourcesPath() { #ifdef SHARE_QML_PATH @@ -33,6 +36,22 @@ QString collectionViewResourcesPath() #endif return Core::ICore::resourcePath("qmldesigner/collectionEditorQmlSource").toString(); } + +static QString urlToLocalPath(const QUrl &url) +{ + QString localPath; + + if (url.isLocalFile()) + localPath = url.toLocalFile(); + + if (url.scheme() == QLatin1String("qrc")) { + const QString &path = url.path(); + localPath = QStringLiteral(":") + path; + } + + return localPath; +} + } // namespace namespace QmlDesigner { @@ -161,9 +180,65 @@ bool CollectionWidget::isCsvFile(const QString &csvFileAddress) const return true; } -bool CollectionWidget::addCollection([[maybe_unused]] const QString &collectionName) const +bool CollectionWidget::addCollection(const QString &collectionName, + const QString &collectionType, + const QString &sourceAddress, + const QVariant &sourceNode) { - // TODO + const ModelNode node = sourceNode.value(); + bool isNewCollection = !node.isValid(); + + if (isNewCollection) { + QString sourcePath = ::urlToLocalPath(sourceAddress); + if (collectionType == "json") { + QJsonObject jsonObject; + jsonObject.insert(collectionName, QJsonArray()); + + QFile sourceFile(sourcePath); + if (!sourceFile.open(QFile::WriteOnly)) { + warn(tr("File error"), + tr("Can not open the file to write.\n") + sourceFile.errorString()); + return false; + } + + sourceFile.write(QJsonDocument(jsonObject).toJson()); + sourceFile.close(); + + bool loaded = loadJsonFile(sourcePath); + if (!loaded) + sourceFile.remove(); + + return loaded; + } else if (collectionType == "csv") { + QFile sourceFile(sourcePath); + if (!sourceFile.open(QFile::WriteOnly)) { + warn(tr("File error"), + tr("Can not open the file to write.\n") + sourceFile.errorString()); + return false; + } + + sourceFile.close(); + + bool loaded = loadCsvFile(collectionName, sourcePath); + if (!loaded) + sourceFile.remove(); + + return loaded; + } else if (collectionType == "existing") { + QFileInfo fileInfo(sourcePath); + if (fileInfo.suffix() == "json") + return loadJsonFile(sourcePath); + else if (fileInfo.suffix() == "csv") + return loadCsvFile(collectionName, sourcePath); + } + } else if (collectionType == "json") { + QString errorMsg; + bool added = m_sourceModel->addCollectionToSource(node, collectionName, &errorMsg); + if (!added) + warn(tr("Can not add a collection to the json file"), errorMsg); + return added; + } + return false; } diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.h b/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.h index 21fddc0092b..f1e3e232e89 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.h +++ b/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.h @@ -15,6 +15,7 @@ class CollectionDetailsModel; class CollectionDetailsSortFilterModel; class CollectionSourceModel; class CollectionView; +class ModelNode; class CollectionWidget : public QFrame { @@ -33,7 +34,10 @@ public: Q_INVOKABLE bool loadCsvFile(const QString &collectionName, const QString &csvFileAddress); Q_INVOKABLE bool isJsonFile(const QString &jsonFileAddress) const; Q_INVOKABLE bool isCsvFile(const QString &csvFileAddress) const; - Q_INVOKABLE bool addCollection(const QString &collectionName) const; + Q_INVOKABLE bool addCollection(const QString &collectionName, + const QString &collectionType, + const QString &sourceAddress, + const QVariant &sourceNode); void warn(const QString &title, const QString &body);