123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <EMotionFX/Source/ActorManager.h>
- #include <EMotionFX/Source/AnimGraphManager.h>
- #include <EMotionFX/Source/MotionManager.h>
- #include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.h>
- #include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/FileManager.h>
- #include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/MainWindow.h>
- #include <Editor/SaveDirtyFilesCallbacks.h>
- #include <QApplication>
- #include <QMessageBox>
- namespace EMStudio
- {
- void SaveDirtyActorFilesCallback::GetDirtyFileNames(
- AZStd::vector<AZStd::string>* outFileNames, AZStd::vector<ObjectPointer>* outObjects)
- {
- const size_t numLeaderActors = EMotionFX::GetActorManager().GetNumActors();
- for (size_t i = 0; i < numLeaderActors; ++i)
- {
- EMotionFX::Actor* actor = EMotionFX::GetActorManager().GetActor(i);
- if (actor->GetDirtyFlag() &&
- !actor->GetIsUsedForVisualization())
- {
- outFileNames->push_back(actor->GetFileName());
- ObjectPointer objPointer;
- objPointer.m_actor = actor;
- outObjects->push_back(objPointer);
- }
- }
- }
- int SaveDirtyActorFilesCallback::SaveDirtyFiles(
- [[maybe_unused]] const AZStd::vector<AZStd::string>& filenamesToSave,
- const AZStd::vector<ObjectPointer>& objects,
- MCore::CommandGroup* commandGroup)
- {
- for (const ObjectPointer& objPointer : objects)
- {
- if (!objPointer.m_actor)
- {
- continue;
- }
- EMotionFX::Actor* actor = objPointer.m_actor;
- if (SaveDirtyActor(actor, commandGroup, false) == DirtyFileManager::CANCELED)
- {
- return DirtyFileManager::CANCELED;
- }
- }
- return DirtyFileManager::FINISHED;
- }
- int SaveDirtyActorFilesCallback::SaveDirtyActor(
- EMotionFX::Actor* actor, [[maybe_unused]] MCore::CommandGroup* commandGroup, bool askBeforeSaving, bool showCancelButton)
- {
- // only process changed files
- if (!actor->GetDirtyFlag())
- {
- return DirtyFileManager::NOFILESTOSAVE;
- }
- // and files that really represent an actor that we take serious in emstudio :)
- if (actor->GetIsUsedForVisualization())
- {
- return DirtyFileManager::NOFILESTOSAVE;
- }
- if (askBeforeSaving)
- {
- EMStudio::GetApp()->setOverrideCursor(QCursor(Qt::ArrowCursor));
- QMessageBox msgBox(GetMainWindow());
- AZStd::string text;
- AZStd::string filename = actor->GetFileNameString();
- AZStd::string extension;
- AzFramework::StringFunc::Path::GetExtension(filename.c_str(), extension, false /* include dot */);
- if (!filename.empty() &&
- !extension.empty())
- {
- text = AZStd::string::format("Save changes to '%s'?", actor->GetFileName());
- }
- else if (!actor->GetNameString().empty())
- {
- text = AZStd::string::format("Save changes to the actor named '%s'?", actor->GetName());
- }
- else
- {
- text = "Save changes to untitled actor?";
- }
- msgBox.setText(text.c_str());
- msgBox.setWindowTitle("Save Changes");
- if (showCancelButton)
- {
- msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
- }
- else
- {
- msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard);
- }
- msgBox.setDefaultButton(QMessageBox::Save);
- msgBox.setIcon(QMessageBox::Question);
- int messageBoxResult = msgBox.exec();
- switch (messageBoxResult)
- {
- case QMessageBox::Save:
- {
- GetMainWindow()->GetFileManager()->SaveActor(actor);
- break;
- }
- case QMessageBox::Discard:
- {
- EMStudio::GetApp()->restoreOverrideCursor();
- return DirtyFileManager::FINISHED;
- }
- case QMessageBox::Cancel:
- {
- EMStudio::GetApp()->restoreOverrideCursor();
- return DirtyFileManager::CANCELED;
- }
- }
- }
- else
- {
- // save without asking first
- GetMainWindow()->GetFileManager()->SaveActor(actor);
- }
- return DirtyFileManager::FINISHED;
- }
- ///////////////////////////////////////////////////////////////////////////
- void SaveDirtyMotionFilesCallback::GetDirtyFileNames(
- AZStd::vector<AZStd::string>* outFileNames, AZStd::vector<ObjectPointer>* outObjects)
- {
- const size_t numMotions = EMotionFX::GetMotionManager().GetNumMotions();
- for (size_t i = 0; i < numMotions; ++i)
- {
- EMotionFX::Motion* motion = EMotionFX::GetMotionManager().GetMotion(i);
- if (motion->GetIsOwnedByRuntime())
- {
- continue;
- }
- if (motion->GetDirtyFlag())
- {
- outFileNames->push_back(motion->GetFileName());
- ObjectPointer objPointer;
- objPointer.m_motion = motion;
- outObjects->push_back(objPointer);
- }
- }
- }
- int SaveDirtyMotionFilesCallback::SaveDirtyFiles(
- [[maybe_unused]] const AZStd::vector<AZStd::string>& filenamesToSave,
- const AZStd::vector<ObjectPointer>& objects,
- MCore::CommandGroup* commandGroup)
- {
- for (const ObjectPointer& objPointer : objects)
- {
- if (!objPointer.m_motion)
- {
- continue;
- }
- EMotionFX::Motion* motion = objPointer.m_motion;
- if (SaveDirtyMotion(motion, commandGroup, false) == DirtyFileManager::CANCELED)
- {
- return DirtyFileManager::CANCELED;
- }
- }
- return DirtyFileManager::FINISHED;
- }
- int SaveDirtyMotionFilesCallback::SaveDirtyMotion(
- EMotionFX::Motion* motion, [[maybe_unused]] MCore::CommandGroup* commandGroup, bool askBeforeSaving, bool showCancelButton)
- {
- // only process changed files
- if (!motion->GetDirtyFlag())
- {
- return DirtyFileManager::NOFILESTOSAVE;
- }
- if (askBeforeSaving)
- {
- EMStudio::GetApp()->setOverrideCursor(QCursor(Qt::ArrowCursor));
- QMessageBox msgBox(GetMainWindow());
- AZStd::string text;
- if (!motion->GetFileNameString().empty())
- {
- text = AZStd::string::format("Save changes to '%s'?", motion->GetFileName());
- }
- else if (!motion->GetNameString().empty())
- {
- text = AZStd::string::format("Save changes to the motion named '%s'?", motion->GetName());
- }
- else
- {
- text = "Save changes to untitled motion?";
- }
- msgBox.setText(text.c_str());
- msgBox.setWindowTitle("Save Changes");
- if (showCancelButton)
- {
- msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
- }
- else
- {
- msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard);
- }
- msgBox.setDefaultButton(QMessageBox::Save);
- msgBox.setIcon(QMessageBox::Question);
- int messageBoxResult = msgBox.exec();
- switch (messageBoxResult)
- {
- case QMessageBox::Save:
- {
- GetMainWindow()->GetFileManager()->SaveMotion(motion->GetID());
- break;
- }
- case QMessageBox::Discard:
- {
- EMStudio::GetApp()->restoreOverrideCursor();
- return DirtyFileManager::FINISHED;
- }
- case QMessageBox::Cancel:
- {
- EMStudio::GetApp()->restoreOverrideCursor();
- return DirtyFileManager::CANCELED;
- }
- }
- }
- else
- {
- // save without asking first
- GetMainWindow()->GetFileManager()->SaveMotion(motion->GetID());
- }
- return DirtyFileManager::FINISHED;
- }
- ///////////////////////////////////////////////////////////////////////////
- void SaveDirtyMotionSetFilesCallback::GetDirtyFileNames(
- AZStd::vector<AZStd::string>* outFileNames, AZStd::vector<ObjectPointer>* outObjects)
- {
- const size_t numMotionSets = EMotionFX::GetMotionManager().GetNumMotionSets();
- for (size_t i = 0; i < numMotionSets; ++i)
- {
- EMotionFX::MotionSet* motionSet = EMotionFX::GetMotionManager().GetMotionSet(i);
- if (motionSet->GetIsOwnedByRuntime())
- {
- continue;
- }
- // only save root motion sets
- if (motionSet->GetParentSet())
- {
- continue;
- }
- if (motionSet->GetDirtyFlag())
- {
- outFileNames->push_back(motionSet->GetFilename());
- ObjectPointer objPointer;
- objPointer.m_motionSet = motionSet;
- outObjects->push_back(objPointer);
- }
- }
- }
- int SaveDirtyMotionSetFilesCallback::SaveDirtyFiles(
- [[maybe_unused]] const AZStd::vector<AZStd::string>& filenamesToSave,
- const AZStd::vector<ObjectPointer>& objects,
- MCore::CommandGroup* commandGroup)
- {
- for (const ObjectPointer& objPointer : objects)
- {
- if (!objPointer.m_motionSet)
- {
- continue;
- }
- EMotionFX::MotionSet* motionSet = objPointer.m_motionSet;
- if (SaveDirtyMotionSet(motionSet, commandGroup, false) == DirtyFileManager::CANCELED)
- {
- return DirtyFileManager::CANCELED;
- }
- }
- return DirtyFileManager::FINISHED;
- }
- int SaveDirtyMotionSetFilesCallback::SaveDirtyMotionSet(
- EMotionFX::MotionSet* motionSet, MCore::CommandGroup* commandGroup, bool askBeforeSaving, bool showCancelButton)
- {
- // only save root motion sets
- if (motionSet->GetParentSet())
- {
- return DirtyFileManager::NOFILESTOSAVE;
- }
- // only process changed files
- if (!motionSet->GetDirtyFlag())
- {
- return DirtyFileManager::NOFILESTOSAVE;
- }
- if (askBeforeSaving)
- {
- EMStudio::GetApp()->setOverrideCursor(QCursor(Qt::ArrowCursor));
- QMessageBox msgBox(GetMainWindow());
- AZStd::string text;
- const AZStd::string& filename = motionSet->GetFilenameString();
- AZStd::string extension;
- AzFramework::StringFunc::Path::GetExtension(filename.c_str(), extension, false /* include dot */);
- if (!filename.empty() && !extension.empty())
- {
- text = AZStd::string::format("Save changes to '%s'?", motionSet->GetFilename());
- }
- else if (!motionSet->GetNameString().empty())
- {
- text = AZStd::string::format("Save changes to the motion set named '%s'?", motionSet->GetName());
- }
- else
- {
- text = "Save changes to untitled motion set?";
- }
- msgBox.setText(text.c_str());
- msgBox.setWindowTitle("Save Changes");
- if (showCancelButton)
- {
- msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
- }
- else
- {
- msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard);
- }
- msgBox.setDefaultButton(QMessageBox::Save);
- msgBox.setIcon(QMessageBox::Question);
- int messageBoxResult = msgBox.exec();
- switch (messageBoxResult)
- {
- case QMessageBox::Save:
- {
- GetMainWindow()->GetFileManager()->SaveMotionSet(GetMainWindow(), motionSet, commandGroup);
- break;
- }
- case QMessageBox::Discard:
- {
- EMStudio::GetApp()->restoreOverrideCursor();
- return DirtyFileManager::FINISHED;
- }
- case QMessageBox::Cancel:
- {
- EMStudio::GetApp()->restoreOverrideCursor();
- return DirtyFileManager::CANCELED;
- }
- }
- }
- else
- {
- // save without asking first
- GetMainWindow()->GetFileManager()->SaveMotionSet(GetMainWindow(), motionSet, commandGroup);
- }
- return DirtyFileManager::FINISHED;
- }
- ///////////////////////////////////////////////////////////////////////////
- void SaveDirtyAnimGraphFilesCallback::GetDirtyFileNames(
- AZStd::vector<AZStd::string>* outFileNames, AZStd::vector<ObjectPointer>* outObjects)
- {
- const size_t numAnimGraphs = EMotionFX::GetAnimGraphManager().GetNumAnimGraphs();
- for (size_t i = 0; i < numAnimGraphs; ++i)
- {
- EMotionFX::AnimGraph* animGraph = EMotionFX::GetAnimGraphManager().GetAnimGraph(i);
- if (animGraph->GetIsOwnedByRuntime())
- {
- continue;
- }
- if (animGraph->GetDirtyFlag())
- {
- outFileNames->push_back(animGraph->GetFileName());
- ObjectPointer objPointer;
- objPointer.m_animGraph = animGraph;
- outObjects->push_back(objPointer);
- }
- }
- }
- int SaveDirtyAnimGraphFilesCallback::SaveDirtyFiles(
- [[maybe_unused]] const AZStd::vector<AZStd::string>& filenamesToSave,
- const AZStd::vector<ObjectPointer>& objects,
- MCore::CommandGroup* commandGroup)
- {
- for (const ObjectPointer& objPointer : objects)
- {
- if (!objPointer.m_animGraph)
- {
- continue;
- }
- EMotionFX::AnimGraph* animGraph = objPointer.m_animGraph;
- if (SaveDirtyAnimGraph(animGraph, commandGroup, false) == DirtyFileManager::CANCELED)
- {
- return DirtyFileManager::CANCELED;
- }
- }
- return DirtyFileManager::FINISHED;
- }
- int SaveDirtyAnimGraphFilesCallback::SaveDirtyAnimGraph(
- EMotionFX::AnimGraph* animGraph, MCore::CommandGroup* commandGroup, bool askBeforeSaving, bool showCancelButton)
- {
- if (!animGraph)
- {
- return QMessageBox::Discard;
- }
- // only process changed files
- if (!animGraph->GetDirtyFlag())
- {
- return DirtyFileManager::NOFILESTOSAVE;
- }
- if (askBeforeSaving)
- {
- EMStudio::GetApp()->setOverrideCursor(QCursor(Qt::ArrowCursor));
- QMessageBox msgBox(GetMainWindow());
- AZStd::string text;
- if (!animGraph->GetFileNameString().empty())
- {
- text = AZStd::string::format("Save changes to '%s'?", animGraph->GetFileName());
- }
- else
- {
- text = "Save changes to untitled anim graph?";
- }
- msgBox.setText(text.c_str());
- msgBox.setWindowTitle("Save Changes");
- if (showCancelButton)
- {
- msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
- }
- else
- {
- msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard);
- }
- msgBox.setDefaultButton(QMessageBox::Save);
- msgBox.setIcon(QMessageBox::Question);
- int messageBoxResult = msgBox.exec();
- switch (messageBoxResult)
- {
- case QMessageBox::Save:
- {
- GetMainWindow()->GetFileManager()->SaveAnimGraph(GetMainWindow(), animGraph, commandGroup);
- break;
- }
- case QMessageBox::Discard:
- {
- EMStudio::GetApp()->restoreOverrideCursor();
- return DirtyFileManager::FINISHED;
- }
- case QMessageBox::Cancel:
- {
- EMStudio::GetApp()->restoreOverrideCursor();
- return DirtyFileManager::CANCELED;
- }
- }
- }
- else
- {
- // save without asking first
- GetMainWindow()->GetFileManager()->SaveAnimGraph(GetMainWindow(), animGraph, commandGroup);
- }
- return DirtyFileManager::FINISHED;
- }
- ///////////////////////////////////////////////////////////////////////////
- void SaveDirtyWorkspaceCallback::GetDirtyFileNames(AZStd::vector<AZStd::string>* outFileNames, AZStd::vector<ObjectPointer>* outObjects)
- {
- Workspace* workspace = GetManager()->GetWorkspace();
- if (workspace->GetDirtyFlag())
- {
- // add the filename to the dirty filenames array
- outFileNames->push_back(workspace->GetFilename());
- // add the link to the actual object
- ObjectPointer objPointer;
- objPointer.m_workspace = workspace;
- outObjects->push_back(objPointer);
- }
- }
- int SaveDirtyWorkspaceCallback::SaveDirtyFiles(
- [[maybe_unused]] const AZStd::vector<AZStd::string>& filenamesToSave,
- const AZStd::vector<ObjectPointer>& objects,
- MCore::CommandGroup* commandGroup)
- {
- for (const ObjectPointer& objPointer : objects)
- {
- if (!objPointer.m_workspace)
- {
- continue;
- }
- Workspace* workspace = objPointer.m_workspace;
- // has the workspace been saved already or is it a new one?
- if (workspace->GetFilenameString().empty())
- {
- // open up save as dialog so that we can choose a filename
- const AZStd::string filename = GetMainWindow()->GetFileManager()->SaveWorkspaceFileDialog(GetMainWindow());
- if (filename.empty())
- {
- return DirtyFileManager::CANCELED;
- }
- // save the workspace using the newly selected filename
- AZStd::string command = AZStd::string::format("SaveWorkspace -filename \"%s\"", filename.c_str());
- commandGroup->AddCommandString(command);
- }
- else
- {
- // save workspace using its filename
- AZStd::string command = AZStd::string::format("SaveWorkspace -filename \"%s\"", workspace->GetFilename());
- commandGroup->AddCommandString(command);
- }
- }
- return DirtyFileManager::FINISHED;
- }
- } // namespace EMStudio
|