diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp index 17a26c58c5c..e7a246b68e7 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp @@ -414,7 +414,6 @@ bool CollectionDetailsModel::saveDataStoreCollections() const ModelNode node = m_currentCollection.reference().node; const Utils::FilePath path = CollectionEditorUtils::dataStoreJsonFilePath(); Utils::FileReader fileData; - Utils::FileSaver sourceFile(path); if (!fileData.fetch(path)) { qWarning() << Q_FUNC_INFO << "Cannot read the json file:" << fileData.errorString(); @@ -437,10 +436,8 @@ bool CollectionDetailsModel::saveDataStoreCollections() } document.setObject(obj); - bool saved = sourceFile.write(document.toJson()); - saved &= sourceFile.finalize(); - if (saved) { + if (CollectionEditorUtils::writeToJsonDocument(path, document)) { const CollectionReference currentReference = m_currentCollection.reference(); for (CollectionDetails &collection : collectionsToBeSaved) { collection.markSaved(); diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectioneditorutils.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectioneditorutils.cpp index 9c777249323..d9bbc764156 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectioneditorutils.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectioneditorutils.cpp @@ -7,6 +7,7 @@ #include "nodemetainfo.h" #include "propertymetainfo.h" +#include #include #include #include @@ -393,4 +394,16 @@ QStringList dataTypesStringList() return typesList; } +bool writeToJsonDocument(const Utils::FilePath &path, const QJsonDocument &document, QString *errorString) +{ + Core::FileChangeBlocker fileBlocker(path); + Utils::FileSaver jsonFile(path); + if (jsonFile.write(document.toJson())) + jsonFile.finalize(); + if (errorString) + *errorString = jsonFile.errorString(); + + return !jsonFile.hasError(); +} + } // namespace QmlDesigner::CollectionEditorUtils diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectioneditorutils.h b/src/plugins/qmldesigner/components/collectioneditor/collectioneditorutils.h index 5f59329fc62..35a036c4e32 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectioneditorutils.h +++ b/src/plugins/qmldesigner/components/collectioneditor/collectioneditorutils.h @@ -29,6 +29,10 @@ Utils::FilePath dataStoreJsonFilePath(); Utils::FilePath dataStoreQmlFilePath(); +bool writeToJsonDocument(const Utils::FilePath &path, + const QJsonDocument &document, + QString *errorString = nullptr); + bool isDataStoreNode(const ModelNode &dataStoreNode); bool ensureDataStoreExists(bool &justCreated); diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.cpp index 9378d6871c6..a76d4a0b24e 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectionsourcemodel.cpp @@ -9,6 +9,7 @@ #include "collectionlistmodel.h" #include "variantproperty.h" +#include #include #include @@ -27,6 +28,8 @@ QSharedPointer loadCollection( { using namespace QmlDesigner::CollectionEditorConstants; using namespace QmlDesigner::CollectionEditorUtils; + using Utils::FilePath; + using Utils::FileReader; QString sourceFileAddress = getSourceCollectionPath(sourceNode); QSharedPointer collectionsList; @@ -40,12 +43,12 @@ QSharedPointer loadCollection( }; if (sourceNode.type() == JSONCOLLECTIONMODEL_TYPENAME) { - QFile sourceFile(sourceFileAddress); - if (!sourceFile.open(QFile::ReadOnly)) + FileReader sourceFile; + if (!sourceFile.fetch(FilePath::fromUserInput(sourceFileAddress))) return {}; QJsonParseError parseError; - QJsonDocument document = QJsonDocument::fromJson(sourceFile.readAll(), &parseError); + QJsonDocument document = QJsonDocument::fromJson(sourceFile.data(), &parseError); if (parseError.error != QJsonParseError::NoError) return {}; @@ -273,6 +276,8 @@ bool CollectionSourceModel::addCollectionToSource(const ModelNode &node, const QJsonObject &newCollection, QString *errorString) { + using Utils::FilePath; + using Utils::FileReader; auto returnError = [errorString](const QString &msg) -> bool { if (errorString) *errorString = msg; @@ -295,13 +300,15 @@ bool CollectionSourceModel::addCollectionToSource(const ModelNode &node, if (!sourceFileInfo.isFile()) return returnError(tr("Selected node must have a valid source file address")); - QFile jsonFile(sourceFileAddress); - if (!jsonFile.open(QFile::ReadWrite)) - return returnError(tr("Can't read or write \"%1\".\n%2") - .arg(sourceFileInfo.absoluteFilePath(), jsonFile.errorString())); + FilePath jsonPath = FilePath::fromUserInput(sourceFileAddress); + FileReader jsonFile; + if (!jsonFile.fetch(jsonPath)) { + return returnError( + tr("Can't read \"%1\".\n%2").arg(sourceFileInfo.absoluteFilePath(), jsonFile.errorString())); + } QJsonParseError parseError; - QJsonDocument document = QJsonDocument::fromJson(jsonFile.readAll(), &parseError); + QJsonDocument document = QJsonDocument::fromJson(jsonFile.data(), &parseError); if (parseError.error != QJsonParseError::NoError) return returnError(tr("\"%1\" is corrupted.\n%2") .arg(sourceFileInfo.absoluteFilePath(), parseError.errorString())); @@ -310,14 +317,8 @@ bool CollectionSourceModel::addCollectionToSource(const ModelNode &node, QJsonObject sourceObject = document.object(); sourceObject.insert(collectionName, newCollection); document.setObject(sourceObject); - if (!jsonFile.resize(0)) - return returnError(tr("Can't clean \"%1\".").arg(sourceFileInfo.absoluteFilePath())); - QByteArray jsonData = document.toJson(); - auto writtenBytes = jsonFile.write(jsonData); - jsonFile.close(); - - if (writtenBytes != jsonData.size()) + if (!CollectionEditorUtils::writeToJsonDocument(jsonPath, document)) return returnError(tr("Can't write to \"%1\".").arg(sourceFileInfo.absoluteFilePath())); updateCollectionList(index(idx)); @@ -417,6 +418,10 @@ void CollectionSourceModel::onSelectedCollectionChanged(CollectionListModel *col void CollectionSourceModel::onCollectionNameChanged(CollectionListModel *collectionList, const QString &oldName, const QString &newName) { + using Utils::FilePath; + using Utils::FileReader; + using Utils::FileSaver; + auto emitRenameWarning = [this](const QString &msg) -> void { emit warning(tr("Rename Model"), msg); }; @@ -446,15 +451,16 @@ void CollectionSourceModel::onCollectionNameChanged(CollectionListModel *collect return; } - QFile jsonFile(sourceFileAddress); - if (!jsonFile.open(QFile::ReadWrite)) { - emitRenameWarning(tr("Can't read or write \"%1\".\n%2") - .arg(sourceFileInfo.absoluteFilePath(), jsonFile.errorString())); + FilePath jsonPath = FilePath::fromUserInput(sourceFileAddress); + FileReader jsonFile; + if (!jsonFile.fetch(jsonPath)) { + emitRenameWarning( + tr("Can't read \"%1\".\n%2").arg(sourceFileInfo.absoluteFilePath(), jsonFile.errorString())); return; } QJsonParseError parseError; - QJsonDocument document = QJsonDocument::fromJson(jsonFile.readAll(), &parseError); + QJsonDocument document = QJsonDocument::fromJson(jsonFile.data(), &parseError); if (parseError.error != QJsonParseError::NoError) { emitRenameWarning(tr("\"%1\" is corrupted.\n%2") .arg(sourceFileInfo.absoluteFilePath(), parseError.errorString())); @@ -484,16 +490,8 @@ void CollectionSourceModel::onCollectionNameChanged(CollectionListModel *collect rootObject.remove(oldName); document.setObject(rootObject); - if (!jsonFile.resize(0)) { - emitRenameWarning(tr("Can't clean \"%1\".").arg(sourceFileInfo.absoluteFilePath())); - return; - } - QByteArray jsonData = document.toJson(); - auto writtenBytes = jsonFile.write(jsonData); - jsonFile.close(); - - if (writtenBytes != jsonData.size()) { + if (!CollectionEditorUtils::writeToJsonDocument(jsonPath, document)) { emitRenameWarning(tr("Can't write to \"%1\".").arg(sourceFileInfo.absoluteFilePath())); return; } @@ -519,6 +517,8 @@ void CollectionSourceModel::onCollectionNameChanged(CollectionListModel *collect void CollectionSourceModel::onCollectionsRemoved(CollectionListModel *collectionList, const QStringList &removedCollections) { + using Utils::FilePath; + using Utils::FileReader; auto emitDeleteWarning = [this](const QString &msg) -> void { emit warning(tr("Delete Model"), msg); }; @@ -547,15 +547,16 @@ void CollectionSourceModel::onCollectionsRemoved(CollectionListModel *collection return; } - QFile jsonFile(sourceFileAddress); - if (!jsonFile.open(QFile::ReadWrite)) { + FilePath jsonPath = FilePath::fromUserInput(sourceFileAddress); + FileReader jsonFile; + if (!jsonFile.fetch(jsonPath)) { emitDeleteWarning(tr("Can't read or write \"%1\".\n%2") .arg(sourceFileInfo.absoluteFilePath(), jsonFile.errorString())); return; } QJsonParseError parseError; - QJsonDocument document = QJsonDocument::fromJson(jsonFile.readAll(), &parseError); + QJsonDocument document = QJsonDocument::fromJson(jsonFile.data(), &parseError); if (parseError.error != QJsonParseError::NoError) { emitDeleteWarning(tr("\"%1\" is corrupted.\n%2") .arg(sourceFileInfo.absoluteFilePath(), parseError.errorString())); @@ -578,16 +579,8 @@ void CollectionSourceModel::onCollectionsRemoved(CollectionListModel *collection } document.setObject(rootObject); - if (!jsonFile.resize(0)) { - emitDeleteWarning(tr("Can't clean \"%1\".").arg(sourceFileInfo.absoluteFilePath())); - return; - } - QByteArray jsonData = document.toJson(); - auto writtenBytes = jsonFile.write(jsonData); - jsonFile.close(); - - if (writtenBytes != jsonData.size()) { + if (!CollectionEditorUtils::writeToJsonDocument(jsonPath, document)) { emitDeleteWarning(tr("Can't write to \"%1\".").arg(sourceFileInfo.absoluteFilePath())); return; } diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp index 24fb745ab77..79d3d563a25 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -167,14 +166,14 @@ bool CollectionWidget::loadCsvFile(const QUrl &url, const QString &collectionNam bool CollectionWidget::isJsonFile(const QUrl &url) const { - QString filePath = url.isLocalFile() ? url.toLocalFile() : url.toString(); - QFile file(filePath); - - if (!file.exists() || !file.open(QFile::ReadOnly)) + Utils::FilePath filePath = Utils::FilePath::fromUserInput(url.isLocalFile() ? url.toLocalFile() + : url.toString()); + Utils::FileReader file; + if (!file.fetch(filePath)) return false; QJsonParseError error; - QJsonDocument::fromJson(file.readAll(), &error); + QJsonDocument::fromJson(file.data(), &error); if (error.error) return false; @@ -184,9 +183,8 @@ bool CollectionWidget::isJsonFile(const QUrl &url) const bool CollectionWidget::isCsvFile(const QUrl &url) const { QString filePath = url.isLocalFile() ? url.toLocalFile() : url.toString(); - QFile file(filePath); - - return file.exists() && file.fileName().endsWith(".csv"); + QFileInfo fileInfo(filePath); + return fileInfo.exists() && !fileInfo.suffix().compare("csv", Qt::CaseInsensitive); } bool CollectionWidget::isValidUrlToImport(const QUrl &url) const @@ -203,73 +201,6 @@ bool CollectionWidget::isValidUrlToImport(const QUrl &url) const return false; } -bool CollectionWidget::addCollection(const QString &collectionName, - const QString &collectionType, - const QUrl &sourceUrl, - const QVariant &sourceNode) -{ - const ModelNode node = sourceNode.value(); - bool isNewCollection = !node.isValid(); - - if (isNewCollection) { - QString sourcePath = sourceUrl.isLocalFile() ? sourceUrl.toLocalFile() : sourceUrl.toString(); - - if (collectionType == "json") { - QJsonObject jsonObject; - jsonObject.insert(collectionName, CollectionEditorUtils::defaultCollection()); - - 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, collectionName); - 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.write("Column1\n\n"); - sourceFile.close(); - - bool loaded = loadCsvFile(sourcePath, collectionName); - if (!loaded) - sourceFile.remove(); - - return loaded; - } else if (collectionType == "existing") { - QFileInfo fileInfo(sourcePath); - if (fileInfo.suffix() == "json") - return loadJsonFile(sourcePath, collectionName); - else if (fileInfo.suffix() == "csv") - return loadCsvFile(sourcePath, collectionName); - } - } else if (collectionType == "json") { - QString errorMsg; - bool added = m_sourceModel->addCollectionToSource(node, - collectionName, - CollectionEditorUtils::defaultCollection(), - &errorMsg); - if (!added) - warn(tr("Can not add a model to the JSON file"), errorMsg); - return added; - } - - return false; -} - bool CollectionWidget::importFile(const QString &collectionName, const QUrl &url) { using Utils::FilePath; @@ -289,15 +220,13 @@ bool CollectionWidget::importFile(const QString &collectionName, const QUrl &url QByteArray fileContent; auto loadUrlContent = [&]() -> bool { - QFile file(url.isLocalFile() ? url.toLocalFile() : url.toString()); - - if (file.open(QFile::ReadOnly)) { - fileContent = file.readAll(); - file.close(); + Utils::FileReader file; + if (file.fetch(fileInfo)) { + fileContent = file.data(); return true; } - warn(tr("Import from file"), tr("Cannot import from file \"%1\"").arg(file.fileName())); + warn(tr("Import from file"), tr("Cannot import from file \"%1\"").arg(fileInfo.fileName())); return false; }; diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.h b/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.h index 5a9c45d591d..23f4ad8dbf3 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.h +++ b/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.h @@ -39,10 +39,6 @@ public: 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 importFile(const QString &collectionName, const QUrl &url); Q_INVOKABLE bool addCollectionToDataStore(const QString &collectionName); diff --git a/src/plugins/qmldesigner/components/collectioneditor/datastoremodelnode.cpp b/src/plugins/qmldesigner/components/collectioneditor/datastoremodelnode.cpp index b85c6517857..e5ddb1dd3a0 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/datastoremodelnode.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/datastoremodelnode.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -301,6 +302,7 @@ void DataStoreModelNode::updateSingletonFile() imports += QStringLiteral("import %1\n").arg(import.toString(true)); QString content = pragmaSingleTone + imports + getModelQmlText(); + Core::DocumentManager::expectFileChange(dataStoreQmlFilePath()); FileSaver file(dataStoreQmlFilePath()); file.write(content.toLatin1()); file.finalize();