forked from qt-creator/qt-creator
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:
@@ -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);
|
||||
|
@@ -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));
|
||||
|
@@ -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;
|
||||
|
@@ -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);
|
||||
|
Reference in New Issue
Block a user