forked from qt-creator/qt-creator
QmlDesigner: Import a model to the default JSON model group
Task-number: QDS-11312 Change-Id: Ib97273a15db4c7fb46ed01debf99602b71ec7630 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -24,15 +24,8 @@ Item {
|
||||
warningDialog.open()
|
||||
}
|
||||
|
||||
JsonImport {
|
||||
id: jsonImporter
|
||||
|
||||
backendValue: root.rootView
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
CsvImport {
|
||||
id: csvImporter
|
||||
ImportDialog {
|
||||
id: importDialog
|
||||
|
||||
backendValue: root.rootView
|
||||
anchors.centerIn: parent
|
||||
@@ -82,26 +75,14 @@ Item {
|
||||
leftPadding: 15
|
||||
}
|
||||
|
||||
IconTextButton {
|
||||
HelperWidgets.IconButton {
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
|
||||
icon: StudioTheme.Constants.import_medium
|
||||
text: qsTr("JSON")
|
||||
tooltip: qsTr("Import JSON")
|
||||
tooltip: qsTr("Import a model")
|
||||
radius: StudioTheme.Values.smallRadius
|
||||
|
||||
onClicked: jsonImporter.open()
|
||||
}
|
||||
|
||||
IconTextButton {
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
|
||||
icon: StudioTheme.Constants.import_medium
|
||||
text: qsTr("CSV")
|
||||
tooltip: qsTr("Import CSV")
|
||||
radius: StudioTheme.Values.smallRadius
|
||||
|
||||
onClicked: csvImporter.open()
|
||||
onClicked: importDialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -13,7 +13,7 @@ import StudioTheme as StudioTheme
|
||||
StudioControls.Dialog {
|
||||
id: root
|
||||
|
||||
title: qsTr("Import A CSV File")
|
||||
title: qsTr("Import a model")
|
||||
anchors.centerIn: parent
|
||||
closePolicy: Popup.CloseOnEscape
|
||||
modal: true
|
||||
@@ -23,8 +23,8 @@ StudioControls.Dialog {
|
||||
property bool fileExists: false
|
||||
|
||||
onOpened: {
|
||||
collectionName.text = "Collection_"
|
||||
fileName.text = qsTr("New CSV File")
|
||||
collectionName.text = "Model"
|
||||
fileName.text = qsTr("Model path")
|
||||
fileName.selectAll()
|
||||
fileName.forceActiveFocus()
|
||||
}
|
||||
@@ -40,6 +40,14 @@ StudioControls.Dialog {
|
||||
|
||||
PlatformWidgets.FileDialog {
|
||||
id: fileDialog
|
||||
nameFilters : ["All Model Files (*.json *.csv)",
|
||||
"JSON Files (*.json)",
|
||||
"Comma-Separated Values (*.csv)"]
|
||||
|
||||
title: qsTr("Select a model file")
|
||||
fileMode: PlatformWidgets.FileDialog.OpenFile
|
||||
acceptLabel: qsTr("Open")
|
||||
|
||||
onAccepted: fileName.text = fileDialog.file
|
||||
}
|
||||
|
||||
@@ -61,7 +69,7 @@ StudioControls.Dialog {
|
||||
spacing: 2
|
||||
|
||||
Text {
|
||||
text: qsTr("File name: ")
|
||||
text: qsTr("File name")
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
}
|
||||
|
||||
@@ -80,11 +88,11 @@ StudioControls.Dialog {
|
||||
translationIndicator.visible: false
|
||||
validator: fileNameValidator
|
||||
|
||||
Keys.onEnterPressed: btnCreate.onClicked()
|
||||
Keys.onReturnPressed: btnCreate.onClicked()
|
||||
Keys.onEnterPressed: btnImport.onClicked()
|
||||
Keys.onReturnPressed: btnImport.onClicked()
|
||||
Keys.onEscapePressed: root.reject()
|
||||
|
||||
onTextChanged: root.fileExists = root.backendValue.isCsvFile(fileName.text)
|
||||
onTextChanged: root.fileExists = root.backendValue.isValidUrlToImport(fileName.text)
|
||||
}
|
||||
|
||||
HelperWidgets.Button {
|
||||
@@ -100,7 +108,7 @@ StudioControls.Dialog {
|
||||
Spacer {}
|
||||
|
||||
Text {
|
||||
text: qsTr("The model name: ")
|
||||
text: qsTr("The model name")
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
}
|
||||
|
||||
@@ -115,8 +123,8 @@ StudioControls.Dialog {
|
||||
regularExpression: /^\w+$/
|
||||
}
|
||||
|
||||
Keys.onEnterPressed: btnCreate.onClicked()
|
||||
Keys.onReturnPressed: btnCreate.onClicked()
|
||||
Keys.onEnterPressed: btnImport.onClicked()
|
||||
Keys.onReturnPressed: btnImport.onClicked()
|
||||
Keys.onEscapePressed: root.reject()
|
||||
}
|
||||
|
||||
@@ -179,15 +187,17 @@ StudioControls.Dialog {
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
|
||||
HelperWidgets.Button {
|
||||
id: btnCreate
|
||||
id: btnImport
|
||||
|
||||
text: qsTr("Import")
|
||||
enabled: root.fileExists && collectionName.text !== ""
|
||||
|
||||
onClicked: {
|
||||
let csvLoaded = root.backendValue.loadCsvFile(fileName.text, collectionName.text)
|
||||
let collectionImported = root.backendValue.importCollectionToDataStore(
|
||||
collectionName.text,
|
||||
fileName.text)
|
||||
|
||||
if (csvLoaded)
|
||||
if (collectionImported)
|
||||
root.accept()
|
||||
else
|
||||
creationFailedDialog.open()
|
@@ -1,145 +0,0 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
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
|
||||
|
||||
StudioControls.Dialog {
|
||||
id: root
|
||||
|
||||
title: qsTr("Import Models")
|
||||
anchors.centerIn: parent
|
||||
closePolicy: Popup.CloseOnEscape
|
||||
modal: true
|
||||
|
||||
required property var backendValue
|
||||
property bool fileExists: false
|
||||
|
||||
onOpened: {
|
||||
fileName.text = qsTr("New JSON File")
|
||||
fileName.selectAll()
|
||||
fileName.forceActiveFocus()
|
||||
}
|
||||
|
||||
onRejected: {
|
||||
fileName.text = ""
|
||||
}
|
||||
|
||||
RegularExpressionValidator {
|
||||
id: fileNameValidator
|
||||
regularExpression: /^(\w[^*><?|]*)[^/\\:*><?|]$/
|
||||
}
|
||||
|
||||
PlatformWidgets.FileDialog {
|
||||
id: fileDialog
|
||||
onAccepted: fileName.text = fileDialog.file
|
||||
}
|
||||
|
||||
Message {
|
||||
id: creationFailedDialog
|
||||
|
||||
title: qsTr("Could not load the file")
|
||||
message: qsTr("An error occurred while trying to load the file.")
|
||||
|
||||
onClosed: root.reject()
|
||||
}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 2
|
||||
|
||||
Text {
|
||||
text: qsTr("File name: ")
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: StudioTheme.Values.sectionRowSpacing
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
StudioControls.TextField {
|
||||
id: fileName
|
||||
|
||||
Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
|
||||
actionIndicator.visible: false
|
||||
translationIndicator.visible: false
|
||||
validator: fileNameValidator
|
||||
|
||||
Keys.onEnterPressed: btnCreate.onClicked()
|
||||
Keys.onReturnPressed: btnCreate.onClicked()
|
||||
Keys.onEscapePressed: root.reject()
|
||||
|
||||
onTextChanged: root.fileExists = root.backendValue.isJsonFile(fileName.text)
|
||||
}
|
||||
|
||||
HelperWidgets.Button {
|
||||
id: fileDialogButton
|
||||
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
|
||||
text: qsTr("Open")
|
||||
onClicked: fileDialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
Item { // spacer
|
||||
implicitWidth: 1
|
||||
implicitHeight: StudioTheme.Values.controlLabelGap
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
|
||||
padding: 5
|
||||
text: qsTr("File name cannot be empty.")
|
||||
wrapMode: Label.WordWrap
|
||||
color: StudioTheme.Values.themeTextColor
|
||||
visible: fileName.text === ""
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
border.width: StudioTheme.Values.border
|
||||
border.color: StudioTheme.Values.themeWarning
|
||||
}
|
||||
}
|
||||
|
||||
Item { // spacer
|
||||
implicitWidth: 1
|
||||
implicitHeight: StudioTheme.Values.sectionColumnSpacing
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: StudioTheme.Values.sectionRowSpacing
|
||||
|
||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||
|
||||
HelperWidgets.Button {
|
||||
id: btnCreate
|
||||
|
||||
text: qsTr("Import")
|
||||
enabled: root.fileExists
|
||||
onClicked: {
|
||||
let jsonLoaded = root.backendValue.loadJsonFile(fileName.text)
|
||||
|
||||
if (jsonLoaded)
|
||||
root.accept()
|
||||
else
|
||||
creationFailedDialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
HelperWidgets.Button {
|
||||
text: qsTr("Cancel")
|
||||
onClicked: root.reject()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -839,6 +839,7 @@ extend_qtc_plugin(QmlDesigner
|
||||
collectiondetailssortfiltermodel.cpp collectiondetailssortfiltermodel.h
|
||||
collectioneditorconstants.h
|
||||
collectioneditorutils.cpp collectioneditorutils.h
|
||||
collectionimporttools.cpp collectionimporttools.h
|
||||
collectionlistmodel.cpp collectionlistmodel.h
|
||||
collectionsourcemodel.cpp collectionsourcemodel.h
|
||||
collectionview.cpp collectionview.h
|
||||
|
@@ -72,6 +72,18 @@ bool variantIslessThan(const QVariant &a, const QVariant &b, CollectionDetails::
|
||||
return std::visit(LessThanVisitor{}, valueToVariant(a, type), valueToVariant(b, type));
|
||||
}
|
||||
|
||||
SourceFormat getSourceCollectionFormat(const ModelNode &node)
|
||||
{
|
||||
using namespace QmlDesigner;
|
||||
if (node.type() == CollectionEditor::JSONCOLLECTIONMODEL_TYPENAME)
|
||||
return CollectionEditor::SourceFormat::Json;
|
||||
|
||||
if (node.type() == CollectionEditor::CSVCOLLECTIONMODEL_TYPENAME)
|
||||
return CollectionEditor::SourceFormat::Csv;
|
||||
|
||||
return CollectionEditor::SourceFormat::Unknown;
|
||||
}
|
||||
|
||||
QString getSourceCollectionType(const ModelNode &node)
|
||||
{
|
||||
using namespace QmlDesigner;
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "collectiondetails.h"
|
||||
#include "collectioneditorconstants.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QJsonArray;
|
||||
@@ -13,6 +14,8 @@ namespace QmlDesigner::CollectionEditor {
|
||||
|
||||
bool variantIslessThan(const QVariant &a, const QVariant &b, CollectionDetails::DataType type);
|
||||
|
||||
SourceFormat getSourceCollectionFormat(const QmlDesigner::ModelNode &node);
|
||||
|
||||
QString getSourceCollectionType(const QmlDesigner::ModelNode &node);
|
||||
|
||||
QString getSourceCollectionPath(const QmlDesigner::ModelNode &node);
|
||||
|
@@ -0,0 +1,105 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "collectionimporttools.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonParseError>
|
||||
#include <QJsonValue>
|
||||
#include <QUrl>
|
||||
|
||||
namespace QmlDesigner::CollectionEditor::ImportTools {
|
||||
|
||||
QJsonArray loadAsSingleJsonCollection(const QUrl &url)
|
||||
{
|
||||
QFile file(url.isLocalFile() ? url.toLocalFile() : url.toString());
|
||||
QJsonArray collection;
|
||||
QByteArray jsonData;
|
||||
if (file.open(QFile::ReadOnly))
|
||||
jsonData = file.readAll();
|
||||
|
||||
file.close();
|
||||
if (jsonData.isEmpty())
|
||||
return {};
|
||||
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument document = QJsonDocument::fromJson(jsonData, &parseError);
|
||||
if (parseError.error != QJsonParseError::NoError)
|
||||
return {};
|
||||
|
||||
auto refineJsonArray = [](const QJsonArray &array) -> QJsonArray {
|
||||
QJsonArray resultArray;
|
||||
for (const QJsonValue &collectionData : array) {
|
||||
if (!collectionData.isObject())
|
||||
resultArray.push_back(collectionData);
|
||||
}
|
||||
return resultArray;
|
||||
};
|
||||
|
||||
if (document.isArray()) {
|
||||
collection = refineJsonArray(document.array());
|
||||
} else if (document.isObject()) {
|
||||
QJsonObject documentObject = document.object();
|
||||
const QStringList mainKeys = documentObject.keys();
|
||||
|
||||
bool arrayFound = false;
|
||||
for (const QString &key : mainKeys) {
|
||||
const QJsonValue &value = documentObject.value(key);
|
||||
if (value.isArray()) {
|
||||
arrayFound = true;
|
||||
collection = refineJsonArray(value.toArray());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!arrayFound) {
|
||||
QJsonObject singleObject;
|
||||
for (const QString &key : mainKeys) {
|
||||
const QJsonValue value = documentObject.value(key);
|
||||
|
||||
if (!value.isObject())
|
||||
singleObject.insert(key, value);
|
||||
}
|
||||
collection.push_back(singleObject);
|
||||
}
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
|
||||
QJsonArray loadAsCsvCollection(const QUrl &url)
|
||||
{
|
||||
QFile sourceFile(url.isLocalFile() ? url.toLocalFile() : url.toString());
|
||||
QStringList headers;
|
||||
QJsonArray elements;
|
||||
|
||||
if (sourceFile.open(QFile::ReadOnly)) {
|
||||
QTextStream stream(&sourceFile);
|
||||
|
||||
if (!stream.atEnd())
|
||||
headers = stream.readLine().split(',');
|
||||
|
||||
for (QString &header : headers)
|
||||
header = header.trimmed();
|
||||
|
||||
if (!headers.isEmpty()) {
|
||||
while (!stream.atEnd()) {
|
||||
const QStringList recordDataList = stream.readLine().split(',');
|
||||
int column = -1;
|
||||
QJsonObject recordData;
|
||||
for (const QString &cellData : recordDataList) {
|
||||
if (++column == headers.size())
|
||||
break;
|
||||
recordData.insert(headers.at(column), cellData);
|
||||
}
|
||||
elements.append(recordData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return elements;
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner::CollectionEditor::ImportTools
|
@@ -0,0 +1,16 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#pragma once
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QJsonArray;
|
||||
class QUrl;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace QmlDesigner::CollectionEditor::ImportTools {
|
||||
|
||||
QJsonArray loadAsSingleJsonCollection(const QUrl &url);
|
||||
QJsonArray loadAsCsvCollection(const QUrl &url);
|
||||
|
||||
} // namespace QmlDesigner::CollectionEditor::ImportTools
|
@@ -268,6 +268,7 @@ bool CollectionSourceModel::collectionExists(const ModelNode &node, const QStrin
|
||||
|
||||
bool CollectionSourceModel::addCollectionToSource(const ModelNode &node,
|
||||
const QString &collectionName,
|
||||
const QJsonArray &newCollectionData,
|
||||
QString *errorString)
|
||||
{
|
||||
auto returnError = [errorString](const QString &msg) -> bool {
|
||||
@@ -284,7 +285,7 @@ bool CollectionSourceModel::addCollectionToSource(const ModelNode &node,
|
||||
return returnError(tr("Node should be a JSON model."));
|
||||
|
||||
if (collectionExists(node, collectionName))
|
||||
return returnError(tr("Model does not exist."));
|
||||
return returnError(tr("A model with the identical name already exists."));
|
||||
|
||||
QString sourceFileAddress = CollectionEditor::getSourceCollectionPath(node);
|
||||
|
||||
@@ -305,7 +306,7 @@ bool CollectionSourceModel::addCollectionToSource(const ModelNode &node,
|
||||
|
||||
if (document.isObject()) {
|
||||
QJsonObject sourceObject = document.object();
|
||||
sourceObject.insert(collectionName, CollectionEditor::defaultCollectionArray());
|
||||
sourceObject.insert(collectionName, newCollectionData);
|
||||
document.setObject(sourceObject);
|
||||
if (!jsonFile.resize(0))
|
||||
return returnError(tr("Can't clean \"%1\".").arg(sourceFileInfo.absoluteFilePath()));
|
||||
|
@@ -54,6 +54,7 @@ public:
|
||||
bool collectionExists(const ModelNode &node, const QString &collectionName) const;
|
||||
bool addCollectionToSource(const ModelNode &node,
|
||||
const QString &collectionName,
|
||||
const QJsonArray &newCollectionData,
|
||||
QString *errorString = nullptr);
|
||||
|
||||
ModelNode sourceNodeAt(int idx);
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
namespace {
|
||||
|
||||
inline bool isStudioCollectionModel(const QmlDesigner::ModelNode &node)
|
||||
{
|
||||
using namespace QmlDesigner::CollectionEditor;
|
||||
|
@@ -6,6 +6,7 @@
|
||||
#include "collectiondetailsmodel.h"
|
||||
#include "collectiondetailssortfiltermodel.h"
|
||||
#include "collectioneditorutils.h"
|
||||
#include "collectionimporttools.h"
|
||||
#include "collectionsourcemodel.h"
|
||||
#include "collectionview.h"
|
||||
#include "qmldesignerconstants.h"
|
||||
@@ -188,6 +189,20 @@ bool CollectionWidget::isCsvFile(const QUrl &url) const
|
||||
return file.exists() && file.fileName().endsWith(".csv");
|
||||
}
|
||||
|
||||
bool CollectionWidget::isValidUrlToImport(const QUrl &url) const
|
||||
{
|
||||
using Utils::FilePath;
|
||||
FilePath fileInfo = FilePath::fromUserInput(url.isLocalFile() ? url.toLocalFile()
|
||||
: url.toString());
|
||||
if (fileInfo.suffix() == "json")
|
||||
return isJsonFile(url);
|
||||
|
||||
if (fileInfo.suffix() == "csv")
|
||||
return isCsvFile(url);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CollectionWidget::addCollection(const QString &collectionName,
|
||||
const QString &collectionType,
|
||||
const QUrl &sourceUrl,
|
||||
@@ -243,7 +258,10 @@ bool CollectionWidget::addCollection(const QString &collectionName,
|
||||
}
|
||||
} else if (collectionType == "json") {
|
||||
QString errorMsg;
|
||||
bool added = m_sourceModel->addCollectionToSource(node, collectionName, &errorMsg);
|
||||
bool added = m_sourceModel->addCollectionToSource(node,
|
||||
collectionName,
|
||||
CollectionEditor::defaultCollectionArray(),
|
||||
&errorMsg);
|
||||
if (!added)
|
||||
warn(tr("Can not add a model to the JSON file"), errorMsg);
|
||||
return added;
|
||||
@@ -252,6 +270,50 @@ bool CollectionWidget::addCollection(const QString &collectionName,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CollectionWidget::importToJson(const QVariant &sourceNode,
|
||||
const QString &collectionName,
|
||||
const QUrl &url)
|
||||
{
|
||||
using CollectionEditor::SourceFormat;
|
||||
using Utils::FilePath;
|
||||
const ModelNode node = sourceNode.value<ModelNode>();
|
||||
const SourceFormat nodeFormat = CollectionEditor::getSourceCollectionFormat(node);
|
||||
QTC_ASSERT(node.isValid() && nodeFormat == SourceFormat::Json, return false);
|
||||
|
||||
FilePath fileInfo = FilePath::fromUserInput(url.isLocalFile() ? url.toLocalFile()
|
||||
: url.toString());
|
||||
bool added = false;
|
||||
QString errorMsg;
|
||||
QJsonArray loadedCollection;
|
||||
|
||||
if (fileInfo.suffix() == "json")
|
||||
loadedCollection = CollectionEditor::ImportTools::loadAsSingleJsonCollection(url);
|
||||
else if (fileInfo.suffix() == "csv")
|
||||
loadedCollection = CollectionEditor::ImportTools::loadAsCsvCollection(url);
|
||||
|
||||
if (!loadedCollection.isEmpty()) {
|
||||
const QString newCollectionName = generateUniqueCollectionName(node, collectionName);
|
||||
added = m_sourceModel->addCollectionToSource(node, newCollectionName, loadedCollection, &errorMsg);
|
||||
} else {
|
||||
errorMsg = tr("The imported model is empty or is not supported.");
|
||||
}
|
||||
|
||||
if (!added)
|
||||
warn(tr("Can not add a model to the JSON file"), errorMsg);
|
||||
return added;
|
||||
}
|
||||
|
||||
bool CollectionWidget::importCollectionToDataStore(const QString &collectionName, const QUrl &url)
|
||||
{
|
||||
using Utils::FilePath;
|
||||
const ModelNode node = dataStoreNode();
|
||||
if (node.isValid())
|
||||
return importToJson(QVariant::fromValue(node), collectionName, url);
|
||||
|
||||
warn(tr("Can not import to the main model"), tr("The data store is not available."));
|
||||
return false;
|
||||
}
|
||||
|
||||
void CollectionWidget::assignSourceNodeToSelectedItem(const QVariant &sourceNode)
|
||||
{
|
||||
ModelNode sourceModel = sourceNode.value<ModelNode>();
|
||||
@@ -268,6 +330,16 @@ void CollectionWidget::assignSourceNodeToSelectedItem(const QVariant &sourceNode
|
||||
CollectionEditor::assignCollectionSourceToNode(m_view, targetNode, sourceModel);
|
||||
}
|
||||
|
||||
ModelNode CollectionWidget::dataStoreNode() const
|
||||
{
|
||||
for (int i = 0; i < m_sourceModel->rowCount(); ++i) {
|
||||
const ModelNode node = m_sourceModel->sourceNodeAt(i);
|
||||
if (CollectionEditor::getSourceCollectionFormat(node) == CollectionEditor::SourceFormat::Json)
|
||||
return node;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void CollectionWidget::warn(const QString &title, const QString &body)
|
||||
{
|
||||
QMetaObject::invokeMethod(m_quickWidget->rootObject(),
|
||||
@@ -285,4 +357,20 @@ void CollectionWidget::setTargetNodeSelected(bool selected)
|
||||
emit targetNodeSelectedChanged(m_targetNodeSelected);
|
||||
}
|
||||
|
||||
QString CollectionWidget::generateUniqueCollectionName(const ModelNode &node, const QString &name)
|
||||
{
|
||||
if (!m_sourceModel->collectionExists(node, name))
|
||||
return name;
|
||||
|
||||
static QRegularExpression reg("^(?<mainName>[\\w\\d\\.\\_\\-]+)\\_(?<number>\\d+)$");
|
||||
QRegularExpressionMatch match = reg.match(name);
|
||||
if (match.hasMatch()) {
|
||||
int nextNumber = match.captured("number").toInt() + 1;
|
||||
return generateUniqueCollectionName(
|
||||
node, QString("%1_%2").arg(match.captured("mainName")).arg(nextNumber));
|
||||
} else {
|
||||
return generateUniqueCollectionName(node, QString("%1_1").arg(name));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -38,13 +38,22 @@ public:
|
||||
Q_INVOKABLE bool loadCsvFile(const QUrl &url, const QString &collectionName = {});
|
||||
Q_INVOKABLE bool isJsonFile(const QUrl &url) const;
|
||||
Q_INVOKABLE bool isCsvFile(const QUrl &url) const;
|
||||
Q_INVOKABLE bool isValidUrlToImport(const QUrl &url) const;
|
||||
Q_INVOKABLE bool addCollection(const QString &collectionName,
|
||||
const QString &collectionType,
|
||||
const QUrl &sourceUrl,
|
||||
const QVariant &sourceNode);
|
||||
|
||||
Q_INVOKABLE bool importToJson(const QVariant &sourceNode,
|
||||
const QString &collectionName,
|
||||
const QUrl &url);
|
||||
|
||||
Q_INVOKABLE bool importCollectionToDataStore(const QString &collectionName, const QUrl &url);
|
||||
|
||||
Q_INVOKABLE void assignSourceNodeToSelectedItem(const QVariant &sourceNode);
|
||||
|
||||
Q_INVOKABLE ModelNode dataStoreNode() const;
|
||||
|
||||
void warn(const QString &title, const QString &body);
|
||||
void setTargetNodeSelected(bool selected);
|
||||
|
||||
@@ -52,6 +61,8 @@ signals:
|
||||
void targetNodeSelectedChanged(bool);
|
||||
|
||||
private:
|
||||
QString generateUniqueCollectionName(const ModelNode &node, const QString &name);
|
||||
|
||||
QPointer<CollectionView> m_view;
|
||||
QPointer<CollectionSourceModel> m_sourceModel;
|
||||
QPointer<CollectionDetailsModel> m_collectionDetailsModel;
|
||||
|
Reference in New Issue
Block a user