forked from qt-creator/qt-creator
QmlDesigner: Use FileSaver instead of file in Model Editor
* Also the warning is removed for internal changes on local files Fixes: QDS-11903 Change-Id: Ic35966888433a2bd9b1cc10a47bb7ed51280ffb1 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io> Reviewed-by: Shrief Gabr <shrief.gabr@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "nodemetainfo.h"
|
||||
#include "propertymetainfo.h"
|
||||
|
||||
#include <coreplugin/documentmanager.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "collectionlistmodel.h"
|
||||
#include "variantproperty.h"
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <qqml.h>
|
||||
|
||||
@@ -27,6 +28,8 @@ QSharedPointer<QmlDesigner::CollectionListModel> loadCollection(
|
||||
{
|
||||
using namespace QmlDesigner::CollectionEditorConstants;
|
||||
using namespace QmlDesigner::CollectionEditorUtils;
|
||||
using Utils::FilePath;
|
||||
using Utils::FileReader;
|
||||
QString sourceFileAddress = getSourceCollectionPath(sourceNode);
|
||||
|
||||
QSharedPointer<QmlDesigner::CollectionListModel> collectionsList;
|
||||
@@ -40,12 +43,12 @@ QSharedPointer<QmlDesigner::CollectionListModel> 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;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
#include <coreplugin/messagebox.h>
|
||||
#include <studioquickwidget.h>
|
||||
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
@@ -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<ModelNode>();
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <qmljstools/qmljscodestylepreferences.h>
|
||||
#include <qmljstools/qmljstoolssettings.h>
|
||||
|
||||
#include <coreplugin/documentmanager.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
#include <projectexplorer/projectmanager.h>
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user