QmlDesigner: Apply collection renames to the sources

Task-number: QDS-11071
Change-Id: Ia03c11d3f61e12c1f71aba147d7686787dffb4a1
Reviewed-by: Mats Honkamaa <mats.honkamaa@qt.io>
This commit is contained in:
Ali Kianian
2023-10-31 10:28:03 +02:00
parent 4f2a062977
commit 6eb522f0ca
4 changed files with 133 additions and 17 deletions

View File

@@ -20,6 +20,7 @@ bool containsItem(const std::initializer_list<ValueType> &container, const Value
auto it = std::find(begin, end, value);
return it != end;
}
} // namespace
namespace QmlDesigner {
@@ -52,8 +53,17 @@ bool CollectionListModel::setData(const QModelIndex &index, const QVariant &valu
if (!index.isValid())
return false;
if (containsItem<int>({IdRole, Qt::EditRole, Qt::DisplayRole}, role)) {
return Super::setData(index, value);
if (containsItem<int>({Qt::EditRole, Qt::DisplayRole, NameRole}, role)) {
if (contains(value.toString()))
return false;
QString oldName = collectionNameAt(index.row());
bool nameChanged = Super::setData(index, value);
if (nameChanged) {
QString newName = collectionNameAt(index.row());
emit this->collectionNameChanged(oldName, newName);
}
return nameChanged;
} else if (role == SelectedRole) {
if (value.toBool() != index.data(SelectedRole).toBool()) {
setSelectedIndex(value.toBool() ? index.row() : -1);

View File

@@ -232,11 +232,7 @@ void CollectionSourceModel::setSources(const ModelNodes &sources)
auto loadedCollection = loadCollection(collectionSource);
m_collectionList.append(loadedCollection);
connect(loadedCollection.data(),
&CollectionListModel::selectedIndexChanged,
this,
&CollectionSourceModel::onSelectedCollectionChanged,
Qt::UniqueConnection);
registerCollection(loadedCollection);
}
updateEmpty();
@@ -269,11 +265,7 @@ void CollectionSourceModel::addSource(const ModelNode &node)
auto loadedCollection = loadCollection(node);
m_collectionList.append(loadedCollection);
connect(loadedCollection.data(),
&CollectionListModel::selectedIndexChanged,
this,
&CollectionSourceModel::onSelectedCollectionChanged,
Qt::UniqueConnection);
registerCollection(loadedCollection);
updateEmpty();
endInsertRows();
@@ -328,30 +320,32 @@ bool CollectionSourceModel::addCollectionToSource(const ModelNode &node,
QFileInfo sourceFileInfo(sourceFileAddress);
if (!sourceFileInfo.isFile())
return returnError(tr("Selected node should have a valid source file address"));
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 open the file to read.\n") + jsonFile.errorString());
return returnError(tr("Can't read or write \"%1\".\n%2")
.arg(sourceFileInfo.absoluteFilePath(), 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());
return returnError(tr("\"%1\" is corrupted.\n%2")
.arg(sourceFileInfo.absoluteFilePath(), 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."));
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())
return returnError(tr("Can't write to the json file."));
return returnError(tr("Can't write to \"%1\".").arg(sourceFileInfo.absoluteFilePath()));
updateCollectionList(index(idx));
@@ -456,6 +450,98 @@ void CollectionSourceModel::onSelectedCollectionChanged(int collectionIndex)
}
}
void CollectionSourceModel::onCollectionNameChanged(const QString &oldName, const QString &newName)
{
CollectionListModel *collectionList = qobject_cast<CollectionListModel *>(sender());
QTC_ASSERT(collectionList, return);
auto emitRenameWarning = [this](const QString &msg) -> void {
emit this->warning(tr("Rename Collection"), msg);
};
const ModelNode node = collectionList->sourceNode();
const QModelIndex nodeIndex = indexOfNode(node);
if (!nodeIndex.isValid()) {
emitRenameWarning(tr("Invalid node"));
return;
}
if (node.type() == CollectionEditor::CSVCOLLECTIONMODEL_TYPENAME) {
if (!setData(nodeIndex, newName, NameRole))
emitRenameWarning(tr("Can't rename the node"));
return;
} else if (node.type() != CollectionEditor::JSONCOLLECTIONMODEL_TYPENAME) {
emitRenameWarning(tr("Invalid node type"));
return;
}
QString sourceFileAddress = node.variantProperty(CollectionEditor::SOURCEFILE_PROPERTY)
.value()
.toString();
QFileInfo sourceFileInfo(sourceFileAddress);
if (!sourceFileInfo.isFile()) {
emitRenameWarning(tr("Selected node must have a valid source file address"));
return;
}
QFile jsonFile(sourceFileAddress);
if (!jsonFile.open(QFile::ReadWrite)) {
return emitRenameWarning(tr("Can't read or write \"%1\".\n%2")
.arg(sourceFileInfo.absoluteFilePath(), jsonFile.errorString()));
return;
}
QJsonParseError parseError;
QJsonDocument document = QJsonDocument::fromJson(jsonFile.readAll(), &parseError);
if (parseError.error != QJsonParseError::NoError) {
emitRenameWarning(tr("\"%1\" is corrupted.\n%2")
.arg(sourceFileInfo.absoluteFilePath(), parseError.errorString()));
return;
}
if (document.isObject()) {
QJsonObject rootObject = document.object();
bool collectionContainsOldName = rootObject.contains(oldName);
bool collectionContainsNewName = rootObject.contains(newName);
if (!collectionContainsOldName) {
emitRenameWarning(
tr("Collection doesn't contain the old collection name (%1).").arg(oldName));
return;
}
if (collectionContainsNewName) {
emitRenameWarning(
tr("The collection name \"%1\" already exists in the source file.").arg(newName));
return;
}
QJsonValue oldValue = rootObject.value(oldName);
rootObject.insert(newName, oldValue);
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()) {
emitRenameWarning(tr("Can't write to \"%1\".").arg(sourceFileInfo.absoluteFilePath()));
return;
}
updateCollectionList(nodeIndex);
}
}
void CollectionSourceModel::setSelectedIndex(int idx)
{
idx = (idx > -1 && idx < m_collectionSources.count()) ? idx : -1;
@@ -514,6 +600,21 @@ void CollectionSourceModel::updateCollectionList(QModelIndex index)
}
}
void CollectionSourceModel::registerCollection(const QSharedPointer<CollectionListModel> &collection)
{
connect(collection.data(),
&CollectionListModel::selectedIndexChanged,
this,
&CollectionSourceModel::onSelectedCollectionChanged,
Qt::UniqueConnection);
connect(collection.data(),
&CollectionListModel::collectionNameChanged,
this,
&CollectionSourceModel::onCollectionNameChanged,
Qt::UniqueConnection);
}
QModelIndex CollectionSourceModel::indexOfNode(const ModelNode &node) const
{
return index(m_sourceIndexHash.value(node.internalId(), -1));

View File

@@ -75,14 +75,17 @@ signals:
void selectedIndexChanged(int idx);
void collectionSelected(const ModelNode &sourceNode, const QString &collectionName);
void isEmptyChanged(bool);
void warning(const QString &title, const QString &body);
private slots:
void onSelectedCollectionChanged(int collectionIndex);
void onCollectionNameChanged(const QString &oldName, const QString &newName);
private:
void setSelectedIndex(int idx);
void updateEmpty();
void updateCollectionList(QModelIndex index);
void registerCollection(const QSharedPointer<CollectionListModel> &collection);
QModelIndex indexOfNode(const ModelNode &node) const;
using Super = QAbstractListModel;

View File

@@ -71,6 +71,8 @@ CollectionWidget::CollectionWidget(CollectionView *view)
icontext->setContext(context);
icontext->setWidget(this);
connect(m_sourceModel, &CollectionSourceModel::warning, this, &CollectionWidget::warn);
m_collectionDetailsSortFilterModel->setSourceModel(m_collectionDetailsModel);
m_quickWidget->quickWidget()->setObjectName(Constants::OBJECT_NAME_COLLECTION_EDITOR);