diff options
author | Jere Tuliniemi <jere.tuliniemi@qt.io> | 2018-11-29 14:02:49 +0200 |
---|---|---|
committer | Jere Tuliniemi <jere.tuliniemi@qt.io> | 2018-11-30 10:34:41 +0000 |
commit | 74ae2a3054f8902f8f45f7cc08854e802085a8a5 (patch) | |
tree | 6ec7a7261a9fb147e98cc75c73f46b7c75f2ae4c | |
parent | 1f226b9786aac4e1210b81ac1e67aed9cad9d948 (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.cpp | 75 | ||||
-rw-r--r-- | src/Authoring/Client/Code/Core/Doc/Doc.h | 4 | ||||
-rw-r--r-- | src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp | 73 |
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; |