summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJere Tuliniemi <jere.tuliniemi@qt.io>2018-11-29 14:02:49 +0200
committerJere Tuliniemi <jere.tuliniemi@qt.io>2018-11-30 10:34:41 +0000
commit74ae2a3054f8902f8f45f7cc08854e802085a8a5 (patch)
tree6ec7a7261a9fb147e98cc75c73f46b7c75f2ae4c
parent1f226b9786aac4e1210b81ac1e67aed9cad9d948 (diff)
Make materialdef rename undoable
A materialdef rename would invalidate the undo stack as previous commands would refer to the old name. Task-number: QT3DS-2781 Change-Id: I9e86e67ce9412629f97c081e6368eb0d3ecc7227 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
-rw-r--r--src/Authoring/Client/Code/Core/Doc/Doc.cpp75
-rw-r--r--src/Authoring/Client/Code/Core/Doc/Doc.h4
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp73
3 files changed, 90 insertions, 62 deletions
diff --git a/src/Authoring/Client/Code/Core/Doc/Doc.cpp b/src/Authoring/Client/Code/Core/Doc/Doc.cpp
index 3457d50a..62de7165 100644
--- a/src/Authoring/Client/Code/Core/Doc/Doc.cpp
+++ b/src/Authoring/Client/Code/Core/Doc/Doc.cpp
@@ -1275,11 +1275,77 @@ void CDoc::onPropertyChanged(qt3dsdm::Qt3DSDMInstanceHandle inInstance,
qt3dsdm::Qt3DSDMPropertyHandle inProperty)
{
using namespace qt3dsdm;
+ const auto bridge = m_StudioSystem->GetClientDataModelBridge();
// Save the material definition upon undo and redo
if (m_Core->GetCmdStack()->isUndoingOrRedoing() &&
- m_StudioSystem->GetClientDataModelBridge()->isInsideMaterialContainer(inInstance)) {
+ bridge->isInsideMaterialContainer(inInstance)) {
getSceneEditor()->saveIfMaterial(inInstance);
}
+
+ // If a material inside the material container is renamed, the file has to be renamed too
+ // and the referenced materials that refer to that renamed material
+ if (inProperty == bridge->GetNameProperty() && bridge->isInsideMaterialContainer(inInstance)) {
+ const auto sceneEditor = getSceneEditor();
+ const auto dirPath = GetDocumentDirectory().toQString();
+
+ const auto renameMaterial = [&](const QPair<QString, QString> &materialRename) {
+ const QString oldFile
+ = sceneEditor->getFilePathFromMaterialName(materialRename.first);
+ const QString newFile
+ = sceneEditor->getFilePathFromMaterialName(materialRename.second);
+ // If the newfile already exists ie. file was renamed manually by the user,
+ // rename the referenced materials regardless
+ if (QFileInfo(newFile).exists() || QFile::rename(oldFile, newFile)) {
+ const QString newRelPath = QDir(dirPath).relativeFilePath(newFile);
+
+ QVector<qt3dsdm::Qt3DSDMInstanceHandle> refMats;
+ getSceneReferencedMaterials(GetSceneInstance(), refMats);
+ for (auto &refMat : qAsConst(refMats)) {
+ const auto origMat = bridge->getMaterialReference(refMat);
+ if (origMat.Valid() && (long)origMat == inInstance) {
+ sceneEditor->setMaterialSourcePath(refMat,
+ Q3DStudio::CString::fromQString(newRelPath));
+ sceneEditor->SetName(refMat, bridge->GetName(inInstance, true));
+ m_StudioSystem->GetFullSystemSignalSender()
+ ->SendInstancePropertyValue(refMat, bridge->GetNameProperty());
+ }
+ }
+ }
+ GetCore()->getProjectFile().renameMaterial(materialRename.first,
+ materialRename.second);
+ m_materialUndoRenames.append(QPair<QString, QString>(materialRename.second,
+ materialRename.first));
+ };
+
+ // After a rename, the opposite rename is saved to an undo list
+ // While doing an undo or redo, this list is checked for renames
+ if (m_Core->GetCmdStack()->isUndoingOrRedoing()) {
+ // Make a copy of the undo list since renameMaterial adds new renames to the same list
+ auto materialUndoRenamesCopy = m_materialUndoRenames;
+ for (int i = 0; i < materialUndoRenamesCopy.size();) {
+ const auto &materialRename = materialUndoRenamesCopy[i];
+ if (sceneEditor->GetName(inInstance).toQString() == materialRename.second) {
+ renameMaterial(materialRename);
+ m_materialUndoRenames.remove(i);
+ materialUndoRenamesCopy.remove(i);
+ } else {
+ ++i;
+ }
+ }
+ }
+
+ // These renames are queued by the user by either renaming the material object
+ // or the .materialdef file.
+ for (int i = 0; i < m_materialRenames.size();) {
+ const auto &materialRename = m_materialRenames[i];
+ if (sceneEditor->GetName(inInstance).toQString() == materialRename.second) {
+ renameMaterial(materialRename);
+ m_materialRenames.remove(i);
+ } else {
+ ++i;
+ }
+ }
+ }
// check if we changed datainput bindings
if (inProperty == m_StudioSystem->GetPropertySystem()
->GetAggregateInstancePropertyByName(inInstance, L"controlledproperty")) {
@@ -1292,6 +1358,10 @@ void CDoc::onPropertyChanged(qt3dsdm::Qt3DSDMInstanceHandle inInstance,
}
}
+void CDoc::queueMaterialRename(const QString &oldName, const QString &newName) {
+ m_materialRenames.append(QPair<QString, QString>(oldName, newName));
+}
+
Q3DStudio::SSelectedValue CDoc::SetupInstanceSelection(qt3dsdm::Qt3DSDMInstanceHandle inInstance)
{
if (m_StudioSystem->IsInstance(inInstance)
@@ -2860,6 +2930,9 @@ void CDoc::AddToGraph(qt3dsdm::Qt3DSDMInstanceHandle inParentInstance,
void CDoc::OnNewPresentation()
{
+ m_materialRenames.clear();
+ m_materialUndoRenames.clear();
+
m_PlaybackClock->Reset();
m_Core->GetDispatch()->FireOnNewPresentation();
diff --git a/src/Authoring/Client/Code/Core/Doc/Doc.h b/src/Authoring/Client/Code/Core/Doc/Doc.h
index d655216a..a85b405d 100644
--- a/src/Authoring/Client/Code/Core/Doc/Doc.h
+++ b/src/Authoring/Client/Code/Core/Doc/Doc.h
@@ -456,6 +456,8 @@ public:
std::shared_ptr<Q3DStudio::IInternalDocumentEditor> getSceneEditor() { return m_SceneEditor; }
QVector<qt3dsdm::Qt3DSDMInstanceHandle> getLayers();
+ void queueMaterialRename(const QString &oldName, const QString &newName);
+
protected:
// Set the active slide, return true if delving
void SetActiveSlideChange(qt3dsdm::Qt3DSDMSlideHandle inNewActiveSlide);
@@ -537,6 +539,8 @@ protected:
Q3DStudio::SSelectedValue m_SelectedValue;
bool m_nudging;
bool m_unnotifiedSelectionChange = false;
+ QVector<QPair<QString, QString>> m_materialRenames;
+ QVector<QPair<QString, QString>> m_materialUndoRenames;
public:
void OnNewPresentation();
diff --git a/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp b/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp
index cfaa17a8..d344eb47 100644
--- a/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp
+++ b/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp
@@ -513,10 +513,7 @@ void InspectorControlModel::setMatDatas(const std::vector<Q3DStudio::CFilePath>
{
m_matDatas.clear();
- const auto studio = g_StudioApp.GetCore()->GetDoc()->GetStudioSystem();
- const auto bridge = studio->GetClientDataModelBridge();
const auto doc = g_StudioApp.GetCore()->GetDoc();
-
bool isDocModified = doc->IsModified();
const auto sceneEditor = doc->getSceneEditor();
if (!sceneEditor)
@@ -557,25 +554,9 @@ void InspectorControlModel::setMatDatas(const std::vector<Q3DStudio::CFilePath>
const QString actualPath = sceneEditor
->getFilePathFromMaterialName(oldName);
if (actualPath == oldPath) {
- sceneEditor->setMaterialNameByPath(instance, relativePath);
-
- QVector<qt3dsdm::Qt3DSDMInstanceHandle> refMats;
- doc->getSceneReferencedMaterials(doc->GetSceneInstance(), refMats);
- for (auto &refMat : qAsConst(refMats)) {
- const auto origMat = bridge->getMaterialReference(refMat);
- if (origMat.Valid() && origMat == instance) {
- sceneEditor->setMaterialSourcePath(
- refMat,
- Q3DStudio::CString::fromQString(relativePath));
- sceneEditor->SetName(refMat, bridge->GetName(instance, true));
- studio->GetFullSystemSignalSender()
- ->SendInstancePropertyValue(refMat,
- bridge->GetNameProperty());
- }
- }
- g_StudioApp.GetCore()->getProjectFile().renameMaterial(
- oldName, newName);
- isDocModified = true;
+ doc->queueMaterialRename(oldName, newName);
+ Q3DStudio::SCOPED_DOCUMENT_EDITOR(*doc, tr("Set Name"))
+ ->setMaterialNameByPath(instance, relativePath);
}
}
}
@@ -1777,56 +1758,26 @@ void InspectorControlModel::setPropertyValue(long instance, int handle, const QV
if (newName != currentName) {
if (bridge->isInsideMaterialContainer(instance)) {
const auto sceneEditor = doc->getSceneEditor();
- Q3DStudio::CString properName = sceneEditor->GetName(instance);
+ const auto properOldName = sceneEditor->GetName(instance).toQString();
const auto dirPath = doc->GetDocumentDirectory().toQString();
for (size_t matIdx = 0, end = m_matDatas.size(); matIdx < end; ++matIdx) {
- if (m_matDatas[matIdx].m_name == properName.toQString()) {
+ if (m_matDatas[matIdx].m_name == properOldName) {
QFileInfo fileInfo(dirPath + QLatin1Char('/')
+ m_matDatas[matIdx].m_relativePath);
- const QString oldFile = fileInfo.absoluteFilePath();
const QString newFile = fileInfo.absolutePath()
+ QLatin1Char('/')
+ newName.toQString()
+ QStringLiteral(".materialdef");
- if (QFile::rename(oldFile, newFile)) {
- const QString newRelPath = QDir(dirPath).relativeFilePath(newFile);
-
- QVector<qt3dsdm::Qt3DSDMInstanceHandle> refMats;
- doc->getSceneReferencedMaterials(doc->GetSceneInstance(), refMats);
- for (auto &refMat : qAsConst(refMats)) {
- const auto origMat = bridge->getMaterialReference(refMat);
- if (origMat.Valid() && (long)origMat == instance) {
- sceneEditor->setMaterialSourcePath(
- refMat,
- Q3DStudio::CString::fromQString(newRelPath));
- sceneEditor->SetName(refMat, newName);
- studio->GetFullSystemSignalSender()
- ->SendInstancePropertyValue(
- refMat,
- bridge->GetNameProperty());
- }
- }
-
- newName = Q3DStudio::CString::fromQString(
- sceneEditor->getMaterialNameFromFilePath(newFile));
- // Not undoable since this causes a file rename
- sceneEditor->SetName(instance, newName, false);
- studio->GetFullSystemSignalSender()
- ->SendInstancePropertyValue(instance,
- bridge->GetNameProperty());
- g_StudioApp.GetCore()->getProjectFile().renameMaterial(
- properName.toQString(), newName.toQString());
- refresh();
- doc->SetModifiedFlag();
- }
- break;
+ const auto properNewName
+ = sceneEditor->getMaterialNameFromFilePath(newFile);
+ newName = Q3DStudio::CString::fromQString(properNewName);
+ doc->queueMaterialRename(properOldName, properNewName);
}
}
- } else {
- Q3DStudio::SCOPED_DOCUMENT_EDITOR(
- *g_StudioApp.GetCore()->GetDoc(),
- QObject::tr("Set Name"))->SetName(instance, newName, false);
}
+ Q3DStudio::SCOPED_DOCUMENT_EDITOR(
+ *g_StudioApp.GetCore()->GetDoc(),
+ QObject::tr("Set Name"))->SetName(instance, newName, false);
}
}
return;