summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMahmoud Badri <mahmoud.badri@qt.io>2019-06-14 12:54:31 +0300
committerMahmoud Badri <mahmoud.badri@qt.io>2019-06-17 13:59:08 +0300
commit57e08e87f7869d035d4b9cc9d1afd867610b5e47 (patch)
tree17ee74cee2db76c61e4b56951b3c270852e6d52f
parentd2a2918a6c77513cb4f35aaa220dfc62c0a94791 (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>
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Project/ProjectContextMenu.cpp6
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Project/ProjectContextMenu.h2
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Project/ProjectFileSystemModel.cpp111
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Project/ProjectFileSystemModel.h5
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Project/ProjectView.cpp65
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Project/ProjectView.h3
-rw-r--r--src/Authoring/Qt3DStudio/Palettes/Project/ProjectView.qml8
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