diff options
author | Mahmoud Badri <mahmoud.badri@qt.io> | 2019-06-14 12:54:31 +0300 |
---|---|---|
committer | Mahmoud Badri <mahmoud.badri@qt.io> | 2019-06-17 13:59:08 +0300 |
commit | 57e08e87f7869d035d4b9cc9d1afd867610b5e47 (patch) | |
tree | 17ee74cee2db76c61e4b56951b3c270852e6d52f | |
parent | d2a2918a6c77513cb4f35aaa220dfc62c0a94791 (diff) |
Material duplication improvement
- When duplicating a material, if its name ends with Copy, Copy1, etc,
the Copy counter is incremented instead of adding another Copy word.
- Select newly added/duplicated materials in the project palette.
- other tweaks.
Change-Id: I2ff8def76b523d9f492928fd5879c4074cede058
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
7 files changed, 101 insertions, 99 deletions
diff --git a/src/Authoring/Qt3DStudio/Palettes/Project/ProjectContextMenu.cpp b/src/Authoring/Qt3DStudio/Palettes/Project/ProjectContextMenu.cpp index 5c985359..4d61f886 100644 --- a/src/Authoring/Qt3DStudio/Palettes/Project/ProjectContextMenu.cpp +++ b/src/Authoring/Qt3DStudio/Palettes/Project/ProjectContextMenu.cpp @@ -103,7 +103,7 @@ ProjectContextMenu::ProjectContextMenu(ProjectView *parent, int index) openFileAction->setText(tr("Edit")); action = new QAction(tr("Duplicate")); - connect(action, &QAction::triggered, this, &ProjectContextMenu::handleDuplicate); + connect(action, &QAction::triggered, this, &ProjectContextMenu::handleDuplicateMaterial); addAction(action); } @@ -200,9 +200,9 @@ void ProjectContextMenu::handleAddMaterial() m_view->addMaterial(m_index); } -void ProjectContextMenu::handleDuplicate() +void ProjectContextMenu::handleDuplicateMaterial() { - m_view->duplicate(m_index); + m_view->duplicateMaterial(m_index); } void ProjectContextMenu::handleDuplicatePresentation() diff --git a/src/Authoring/Qt3DStudio/Palettes/Project/ProjectContextMenu.h b/src/Authoring/Qt3DStudio/Palettes/Project/ProjectContextMenu.h index 12cd2367..a89206fe 100644 --- a/src/Authoring/Qt3DStudio/Palettes/Project/ProjectContextMenu.h +++ b/src/Authoring/Qt3DStudio/Palettes/Project/ProjectContextMenu.h @@ -50,7 +50,7 @@ private Q_SLOTS: void handleRefreshImport(); void handleImportAssets(); void handleAddMaterial(); - void handleDuplicate(); + void handleDuplicateMaterial(); void handleDuplicatePresentation(); void handleInitialPresentation(); void handleRenamePresentation(); diff --git a/src/Authoring/Qt3DStudio/Palettes/Project/ProjectFileSystemModel.cpp b/src/Authoring/Qt3DStudio/Palettes/Project/ProjectFileSystemModel.cpp index 4f62cd59..d9e6ecf8 100644 --- a/src/Authoring/Qt3DStudio/Palettes/Project/ProjectFileSystemModel.cpp +++ b/src/Authoring/Qt3DStudio/Palettes/Project/ProjectFileSystemModel.cpp @@ -96,11 +96,10 @@ QVariant ProjectFileSystemModel::data(const QModelIndex &index, int role) const } case IsExpandableRole: { - if (item.index == m_rootIndex) { + if (item.index == m_rootIndex) return false; - } else { - return hasVisibleChildren(item.index); - } + + return hasVisibleChildren(item.index); } case IsDraggableRole: @@ -124,24 +123,19 @@ QVariant ProjectFileSystemModel::data(const QModelIndex &index, int role) const case FileIdRole: { const QString path = item.index.data(QFileSystemModel::FilePathRole).toString(); - EStudioObjectType iconType = getIconType(path); - if (iconType == OBJTYPE_PRESENTATION || iconType == OBJTYPE_QML_STREAM) + if (getIconType(path) & (OBJTYPE_PRESENTATION | OBJTYPE_QML_STREAM)) return presentationId(path); - else - return {}; + + return {}; } case ExtraIconRole: { const QString path = item.index.data(QFileSystemModel::FilePathRole).toString(); - EStudioObjectType iconType = getIconType(path); - if (iconType == OBJTYPE_PRESENTATION || iconType == OBJTYPE_QML_STREAM) { + if (getIconType(path) & (OBJTYPE_PRESENTATION | OBJTYPE_QML_STREAM)) { if (presentationId(path).isEmpty()) return QStringLiteral("warning.png"); - else - return {}; - } else { - return {}; } + return {}; } default: @@ -495,6 +489,12 @@ void ProjectFileSystemModel::setRootPath(const QString &path) }); } +// set a file to be selected upon next layout change (used to auto select newly created files) +void ProjectFileSystemModel::selectFile(const QString &path) +{ + m_selectFile = path; +} + void ProjectFileSystemModel::setRootIndex(const QModelIndex &rootIndex) { if (rootIndex == m_rootIndex) @@ -505,7 +505,7 @@ void ProjectFileSystemModel::setRootIndex(const QModelIndex &rootIndex) m_rootIndex = rootIndex; beginInsertRows({}, 0, 0); - m_items.append({ m_rootIndex, 0, true, nullptr, 0 }); + m_items.append({m_rootIndex, 0, true, nullptr, 0}); endInsertRows(); showModelTopLevelItems(); @@ -558,7 +558,7 @@ void ProjectFileSystemModel::showModelChildItems(const QModelIndex &parentIndex, beginInsertRows({}, startRow, startRow + insertCount - 1); for (auto it = rowsToInsert.rbegin(); it != rowsToInsert.rend(); ++it) - m_items.insert(startRow, { *it, depth, false, parent, 0 }); + m_items.insert(startRow, {*it, depth, false, parent, 0}); for (; parent != nullptr; parent = parent->parent) parent->childCount += insertCount; @@ -614,65 +614,6 @@ bool ProjectFileSystemModel::hasValidUrlsForDropping(const QList<QUrl> &urls) co return false; } -void ProjectFileSystemModel::showInfo(int row) -{ - if (row < 0 || row >= m_items.size()) - row = 0; - - const TreeItem &item = m_items.at(row); - QString path = item.index.data(QFileSystemModel::FilePathRole).toString(); - - QFileInfo fi(path); - - if (fi.suffix() == QLatin1String("materialdef")) { - const auto doc = g_StudioApp.GetCore()->GetDoc(); - bool isDocModified = doc->isModified(); - { // Scope for the ScopedDocumentEditor - Q3DStudio::ScopedDocumentEditor sceneEditor( - Q3DStudio::SCOPED_DOCUMENT_EDITOR(*doc, QString())); - const auto material = sceneEditor->getOrCreateMaterial(path); - QString name; - QMap<QString, QString> values; - QMap<QString, QMap<QString, QString>> textureValues; - sceneEditor->getMaterialInfo(fi.absoluteFilePath(), name, values, textureValues); - sceneEditor->setMaterialValues(fi.absoluteFilePath(), values, textureValues); - if (material.Valid()) - doc->SelectDataModelObject(material); - } - // Several aspects of the editor are not updated correctly - // if the data core is changed without a transaction - // The above scope completes the transaction for creating a new material - // Next the added undo has to be popped from the stack - // and the modified flag has to be restored - // TODO: Find a way to update the editor fully without a transaction - doc->SetModifiedFlag(isDocModified); - g_StudioApp.GetCore()->GetCmdStack()->RemoveLastUndo(); - } -} - -void ProjectFileSystemModel::duplicate(int row) -{ - if (row < 0 || row >= m_items.size()) - row = 0; - - const TreeItem &item = m_items.at(row); - QString path = item.index.data(QFileSystemModel::FilePathRole).toString(); - - QFileInfo srcFile(path); - const QString destPathStart = srcFile.dir().absolutePath() + QLatin1Char('/') - + srcFile.completeBaseName() + QStringLiteral(" Copy"); - const QString destPathEnd = QStringLiteral(".") + srcFile.suffix(); - QString destPath = destPathStart + destPathEnd; - - int i = 1; - while (QFile::exists(destPath)) { - i++; - destPath = destPathStart + QString::number(i) + destPathEnd; - } - - QFile::copy(path, destPath); -} - void ProjectFileSystemModel::importUrls(const QList<QUrl> &urls, int row, bool autoSort) { if (row < 0 || row >= m_items.size()) @@ -1054,11 +995,8 @@ void ProjectFileSystemModel::collapse(int row) int ProjectFileSystemModel::modelIndexRow(const QModelIndex &modelIndex) const { - auto it = std::find_if( - std::begin(m_items), - std::end(m_items), - [&modelIndex](const TreeItem &item) - { + auto it = std::find_if(std::begin(m_items), std::end(m_items), + [&modelIndex](const TreeItem &item) { return item.index == modelIndex; }); @@ -1204,7 +1142,7 @@ void ProjectFileSystemModel::modelLayoutChanged() return; QSet<QPersistentModelIndex> expandedItems; - for (const auto &item : m_items) { + for (const auto &item : qAsConst(m_items)) { if (item.expanded) expandedItems.insert(item.index); } @@ -1222,7 +1160,8 @@ void ProjectFileSystemModel::modelLayoutChanged() const auto &childIndex = m_model->index(i, 0, parentIndex); if (isVisible(childIndex)) { const bool expanded = expandedItems.contains(childIndex); - m_items.append({ childIndex, depth, expanded, parent, 0 }); + m_items.append({childIndex, depth, expanded, parent, 0}); + auto &item = m_items.last(); if (expanded) { item.childCount = insertChildren(childIndex, &item); @@ -1244,6 +1183,14 @@ void ProjectFileSystemModel::modelLayoutChanged() Q_ASSERT(m_items.count() == itemCount); Q_EMIT dataChanged(index(0), index(itemCount - 1)); + + // select m_selectFile (used for auto selecting newly created files) + if (!m_selectFile.isEmpty()) { + int row = rowForPath(m_selectFile); + if (row != -1) + Q_EMIT selectFileChanged(row); + m_selectFile.clear(); + } } void ProjectFileSystemModel::updateDefaultDirMap() diff --git a/src/Authoring/Qt3DStudio/Palettes/Project/ProjectFileSystemModel.h b/src/Authoring/Qt3DStudio/Palettes/Project/ProjectFileSystemModel.h index 8e9cefb8..56d82e41 100644 --- a/src/Authoring/Qt3DStudio/Palettes/Project/ProjectFileSystemModel.h +++ b/src/Authoring/Qt3DStudio/Palettes/Project/ProjectFileSystemModel.h @@ -63,6 +63,7 @@ public: }; void setRootPath(const QString &path); + void selectFile(const QString &path); QHash<int, QByteArray> roleNames() const override; int rowCount(const QModelIndex &parent = {}) const override; @@ -84,14 +85,13 @@ public: Q_INVOKABLE void importUrls(const QList<QUrl> &urls, int row, bool autoSort = true); Q_INVOKABLE bool hasValidUrlsForDropping(const QList<QUrl> &urls) const; - Q_INVOKABLE void showInfo(int row); - Q_INVOKABLE void duplicate(int row); void asyncUpdateReferences(); void onFilesChanged(const Q3DStudio::TFileModificationList &inFileModificationList); Q_SIGNALS: void modelChanged(QAbstractItemModel *model); + void selectFileChanged(int idx); private: void setRootIndex(const QModelIndex &rootIndex); @@ -161,6 +161,7 @@ private: QHash<QString, bool> m_projectReferencesUpdateMap; QTimer m_projectReferencesUpdateTimer; std::shared_ptr<qt3dsdm::ISignalConnection> m_directoryConnection; + QString m_selectFile; // file to be selected on next layout change }; #endif // TREEVIEWADAPTOR_H diff --git a/src/Authoring/Qt3DStudio/Palettes/Project/ProjectView.cpp b/src/Authoring/Qt3DStudio/Palettes/Project/ProjectView.cpp index dadb5895..0be79646 100644 --- a/src/Authoring/Qt3DStudio/Palettes/Project/ProjectView.cpp +++ b/src/Authoring/Qt3DStudio/Palettes/Project/ProjectView.cpp @@ -483,23 +483,70 @@ void ProjectView::addMaterial(int row) const QFile file(path + extension); int i = 1; - while (file.exists()) { - i++; - file.setFileName(path + QString::number(i) + extension); - } + while (file.exists()) + file.setFileName(path + QString::number(i++) + extension); file.open(QIODevice::WriteOnly); file.write("<MaterialData version=\"1.0\">\n</MaterialData>"); + + m_ProjectModel->selectFile(file.fileName()); // select the added material } +// show material properties in the inspector void ProjectView::editMaterial(int row) const { - m_ProjectModel->showInfo(row); -} + QString path = m_ProjectModel->filePath(row); + QFileInfo fi(path); -void ProjectView::duplicate(int row) const -{ - m_ProjectModel->duplicate(row); + const auto doc = g_StudioApp.GetCore()->GetDoc(); + bool isDocModified = doc->isModified(); + { // Scope for the ScopedDocumentEditor + Q3DStudio::ScopedDocumentEditor sceneEditor( + Q3DStudio::SCOPED_DOCUMENT_EDITOR(*doc, QString())); + const auto material = sceneEditor->getOrCreateMaterial(path); + QString name; + QMap<QString, QString> values; + QMap<QString, QMap<QString, QString>> textureValues; + sceneEditor->getMaterialInfo(fi.absoluteFilePath(), name, values, textureValues); + sceneEditor->setMaterialValues(fi.absoluteFilePath(), values, textureValues); + if (material.Valid()) + doc->SelectDataModelObject(material); + } + // Several aspects of the editor are not updated correctly if the data core is changed without + // a transaction. The above scope completes the transaction for creating a new material. Next + // the added undo has to be popped from the stack and the modified flag has to be restored + // TODO: Find a way to update the editor fully without a transaction + doc->SetModifiedFlag(isDocModified); + g_StudioApp.GetCore()->GetCmdStack()->RemoveLastUndo(); +} + +void ProjectView::duplicateMaterial(int row) +{ + QString pathSrc = m_ProjectModel->filePath(row); + QString pathDest = pathSrc; + QRegExp rgxCopy(QLatin1String("Copy\\d*")); + + do { + int copyIdx = rgxCopy.lastIndexIn(pathDest); + if (copyIdx != -1) { // src mat. name ends in Copy (+ a number >= 0) + QString copy = rgxCopy.cap(); + int n = copy.length(); + if (n > 4) { // name ends with a number, increment it + QString oldNumber = copy.mid(4); + QString newNumber = QString::number(oldNumber.toInt() + 1); + copy.replace(oldNumber, newNumber); + } else { // name ends with Copy, make it Copy2 + copy += '2'; + } + + pathDest.replace(copyIdx, n, copy); + } else { // name doesn't end with Copy, add it + pathDest.replace(QLatin1String(".materialdef"), QLatin1String(" Copy.materialdef")); + } + } while (QFile::exists(pathDest)); + + m_ProjectModel->selectFile(pathDest); // select the duplicated material + QFile::copy(pathSrc, pathDest); } void ProjectView::duplicatePresentation(int row) const diff --git a/src/Authoring/Qt3DStudio/Palettes/Project/ProjectView.h b/src/Authoring/Qt3DStudio/Palettes/Project/ProjectView.h index 7533e677..a7d67e29 100644 --- a/src/Authoring/Qt3DStudio/Palettes/Project/ProjectView.h +++ b/src/Authoring/Qt3DStudio/Palettes/Project/ProjectView.h @@ -78,7 +78,7 @@ public: void refreshImport(int row) const; void addMaterial(int row) const; void editMaterial(int row) const; - void duplicate(int row) const; + void duplicateMaterial(int row); void duplicatePresentation(int row) const; void deleteFile(int row) const; @@ -86,6 +86,7 @@ public: Q_INVOKABLE bool isPresentation(int row) const; Q_INVOKABLE bool isQmlStream(int row) const; + bool isCurrentPresentation(int row) const; bool isMaterialFolder(int row) const; bool isInMaterialFolder(int row) const; diff --git a/src/Authoring/Qt3DStudio/Palettes/Project/ProjectView.qml b/src/Authoring/Qt3DStudio/Palettes/Project/ProjectView.qml index 043d9ba2..73c9481c 100644 --- a/src/Authoring/Qt3DStudio/Palettes/Project/ProjectView.qml +++ b/src/Authoring/Qt3DStudio/Palettes/Project/ProjectView.qml @@ -33,9 +33,15 @@ import "../controls" Rectangle { id: root - color: _backgroundColor + Connections { + target: _parentView.projectModel + onSelectFileChanged: { + projectTree.currentIndex = idx; // auto select a newly created file + } + } + ColumnLayout { anchors.fill: parent spacing: 4 |