diff --git a/Code/Editor/CryEdit.cpp b/Code/Editor/CryEdit.cpp index 9b46f99e16..6e921833cb 100644 --- a/Code/Editor/CryEdit.cpp +++ b/Code/Editor/CryEdit.cpp @@ -736,98 +736,7 @@ void CCryEditApp::OnFileSave() if (usePrefabSystemForLevels) { - auto prefabSystemComponentInterface = AZ::Interface::Get(); - auto prefabEditorEntityOwnershipInterface = AZ::Interface::Get(); - AzToolsFramework::SavePrefabsPreference savePrefabsPreference = prefabEditorEntityOwnershipInterface->GetSavePrefabsPreference(); - - if (savePrefabsPreference == AzToolsFramework::SavePrefabsPreference::SaveAll) - { - prefabSystemComponentInterface->SaveAllDirtyTemplates(); - } - else if (savePrefabsPreference == AzToolsFramework::SavePrefabsPreference::Unspecified) - { - QDialog saveModifiedMessageBox(AzToolsFramework::GetActiveWindow()); - - // Main Content section begins. - saveModifiedMessageBox.setObjectName("SaveAllPrefabsDialog"); - QBoxLayout* contentLayout = new QVBoxLayout(&saveModifiedMessageBox); - QFrame* levelSavedMessageFrame = new QFrame(&saveModifiedMessageBox); - QHBoxLayout* levelSavedMessageLayout = new QHBoxLayout(&saveModifiedMessageBox); - levelSavedMessageFrame->setObjectName("LevelSavedMessageFrame"); - - // Add a checkMark icon next to the level entities saved message. - QPixmap checkMarkIcon(QString(":/Notifications/checkmark.svg")); - QLabel* levelSavedSuccessfullyIconContainer = new QLabel(); - levelSavedSuccessfullyIconContainer->setPixmap(checkMarkIcon); - levelSavedSuccessfullyIconContainer->setFixedWidth(checkMarkIcon.width()); - - // Add a message that level entities are saved successfully. - QLabel* levelSavedSuccessfullyLabel = new QLabel("All entities inside level have been saved successfully."); - levelSavedSuccessfullyLabel->setObjectName("LevelSavedSuccessfullyLabel"); - levelSavedMessageLayout->addWidget(levelSavedSuccessfullyIconContainer); - levelSavedMessageLayout->addWidget(levelSavedSuccessfullyLabel); - levelSavedMessageFrame->setLayout(levelSavedMessageLayout); - - - QFrame* prefabSaveQuestionFrame = new QFrame(&saveModifiedMessageBox); - QHBoxLayout* prefabSaveQuestionLayout = new QHBoxLayout(&saveModifiedMessageBox); - - // Add a warning icon next to prefabs save question. - QLabel* warningIconContainer = new QLabel(); - QPixmap warningIcon(QString(":/Notifications/warning.svg")); - warningIconContainer->setPixmap(warningIcon); - warningIconContainer->setFixedWidth(warningIcon.width()); - prefabSaveQuestionLayout->addWidget(warningIconContainer); - - // Ask if user wants all prefabs saved. - QLabel* prefabSaveQuestionLabel = new QLabel("Do you want to save all unsaved prefabs?"); - prefabSaveQuestionFrame->setObjectName("PrefabSaveQuestionFrame"); - prefabSaveQuestionLayout->addWidget(prefabSaveQuestionLabel); - prefabSaveQuestionFrame->setLayout(prefabSaveQuestionLayout); - contentLayout->addWidget(levelSavedMessageFrame); - contentLayout->addWidget(prefabSaveQuestionFrame); - - // Footer section begins. - QFrame* footerSeparatorLine = new QFrame(); - footerSeparatorLine->setObjectName("FooterSeparatorLine"); - footerSeparatorLine->setFrameShape(QFrame::HLine); - contentLayout->addWidget(footerSeparatorLine); - QHBoxLayout* footerLayout = new QHBoxLayout(&saveModifiedMessageBox); - - // Provide option for user to remember their prefab save preference. - QCheckBox* saveAllPrefabsPreference = new QCheckBox("Remember my preference."); - AzQtComponents::CheckBox::applyToggleSwitchStyle(saveAllPrefabsPreference); - QVBoxLayout* footerPreferenceLayout = new QVBoxLayout(&saveModifiedMessageBox); - footerPreferenceLayout->addWidget(saveAllPrefabsPreference); - QLabel* prefabSavePreferenceHint = new QLabel("You can change this anytime in Edit -> Editor Settings -> GlobalPreferences."); - prefabSavePreferenceHint->setObjectName("PrefabSavePreferenceHint"); - footerPreferenceLayout->addWidget(prefabSavePreferenceHint); - footerLayout->addLayout(footerPreferenceLayout); - QDialogButtonBox* prefabSaveConfirmationButtons = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::No); - footerLayout->addWidget(prefabSaveConfirmationButtons); - contentLayout->addLayout(footerLayout); - connect(prefabSaveConfirmationButtons, &QDialogButtonBox::accepted, &saveModifiedMessageBox, &QDialog::accept); - connect(prefabSaveConfirmationButtons, &QDialogButtonBox::rejected, &saveModifiedMessageBox, &QDialog::reject); - AzQtComponents::StyleManager::setStyleSheet(saveModifiedMessageBox.parentWidget(), QStringLiteral("style:Editor.qss")); - - int prefabSaveSelection = saveModifiedMessageBox.exec(); - switch (prefabSaveSelection) - { - case QDialog::Accepted: - if (saveAllPrefabsPreference->checkState() == Qt::CheckState::Checked) - { - gSettings.SetSavePrefabsPreference(AzToolsFramework::SavePrefabsPreference::SaveAll); - } - prefabSystemComponentInterface->SaveAllDirtyTemplates(); - break; - case QDialog::Rejected: - if (saveAllPrefabsPreference->checkState() == Qt::CheckState::Checked) - { - gSettings.SetSavePrefabsPreference(AzToolsFramework::SavePrefabsPreference::SaveNone); - } - break; - } - } + GetIEditor()->GetDocument()->ExecuteSavePrefabsDialog(); } } @@ -3239,29 +3148,80 @@ bool CCryEditApp::CreateLevel(bool& wasCreateLevelOperationCancelled) bool bIsDocModified = GetIEditor()->GetDocument()->IsModified(); if (GetIEditor()->GetDocument()->IsDocumentReady() && bIsDocModified) { - QString str = QObject::tr("Level %1 has been changed. Save Level?").arg(GetIEditor()->GetGameEngine()->GetLevelName()); - int result = QMessageBox::question(AzToolsFramework::GetActiveWindow(), QObject::tr("Save Level"), str, QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); - if (QMessageBox::Yes == result) + bool usePrefabSystemForLevels = false; + AzFramework::ApplicationRequests::Bus::BroadcastResult( + usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled); + if (!usePrefabSystemForLevels) { - if (!GetIEditor()->GetDocument()->DoFileSave()) + QString str = QObject::tr("Level %1 has been changed. Save Level?").arg(GetIEditor()->GetGameEngine()->GetLevelName()); + int result = QMessageBox::question( + AzToolsFramework::GetActiveWindow(), QObject::tr("Save Level"), str, + QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); + if (QMessageBox::Yes == result) + { + if (!GetIEditor()->GetDocument()->DoFileSave()) + { + // if the file save operation failed, assume that the user was informed of why + // already and treat it as a cancel + wasCreateLevelOperationCancelled = true; + return false; + } + + bIsDocModified = false; + } + else if (QMessageBox::No == result) + { + // Set Modified flag to false to prevent show Save unchanged dialog again + GetIEditor()->GetDocument()->SetModifiedFlag(false); + } + else if (QMessageBox::Cancel == result) { - // if the file save operation failed, assume that the user was informed of why - // already and treat it as a cancel wasCreateLevelOperationCancelled = true; return false; } - - bIsDocModified = false; - } - else if (QMessageBox::No == result) - { - // Set Modified flag to false to prevent show Save unchanged dialog again - GetIEditor()->GetDocument()->SetModifiedFlag(false); } - else if (QMessageBox::Cancel == result) + else { - wasCreateLevelOperationCancelled = true; - return false; + auto prefabSystemComponentInterface = AZ::Interface::Get(); + auto prefabSaveSelectionDialog = GetIEditor()->GetDocument()->ConstructSaveLevelDialog(); + + int prefabSaveSelection = prefabSaveSelectionDialog->exec(); + QCheckBox* saveAllPrefabsPreferenceCheckBox = + prefabSaveSelectionDialog->findChild("SaveAllPrefabsPreferenceCheckBox"); + QCheckBox* saveAllPrefabsCheckBox = prefabSaveSelectionDialog->findChild("SaveAllPrefabsCheckbox"); + AzToolsFramework::SavePrefabsPreference savePrefabsPreference = saveAllPrefabsCheckBox->isChecked() + ? AzToolsFramework::SavePrefabsPreference::SaveAll + : AzToolsFramework::SavePrefabsPreference::SaveNone; + + switch (1 - prefabSaveSelection) + { + case QDialogButtonBox::AcceptRole: + if (!GetIEditor()->GetDocument()->DoFileSave()) + { + // if the file save operation failed, assume that the user was informed of why + // already and treat it as a cancel + wasCreateLevelOperationCancelled = true; + return false; + } + if (saveAllPrefabsPreferenceCheckBox->checkState() == Qt::CheckState::Checked) + { + gSettings.SetSavePrefabsPreference(savePrefabsPreference); + gSettings.Save(); + } + if (savePrefabsPreference == AzToolsFramework::SavePrefabsPreference::SaveAll) + { + prefabSystemComponentInterface->SaveAllDirtyTemplates(); + } + bIsDocModified = prefabSystemComponentInterface->AreDirtyTemplatesPresent(); + break; + case QDialogButtonBox::RejectRole: + wasCreateLevelOperationCancelled = true; + return false; + case QDialogButtonBox::InvalidRole: + // Set Modified flag to false to prevent show Save unchanged dialog again + GetIEditor()->GetDocument()->SetModifiedFlag(false); + break; + } } } diff --git a/Code/Editor/CryEditDoc.cpp b/Code/Editor/CryEditDoc.cpp index 37a5750e1f..3301d2521a 100644 --- a/Code/Editor/CryEditDoc.cpp +++ b/Code/Editor/CryEditDoc.cpp @@ -697,92 +697,34 @@ bool CCryEditDoc::SaveModified() else { auto prefabSystemComponentInterface = AZ::Interface::Get(); - auto prefabEditorEntityOwnershipInterface = AZ::Interface::Get(); - AzToolsFramework::SavePrefabsPreference savePrefabsPreference = prefabEditorEntityOwnershipInterface->GetSavePrefabsPreference(); - - QDialog saveModifiedMessageBox(AzToolsFramework::GetActiveWindow()); - saveModifiedMessageBox.setObjectName("SaveDirtyLevelDialog"); - - // Main Content section begins. - QVBoxLayout* contentLayout = new QVBoxLayout(&saveModifiedMessageBox); - QFrame* levelEntitiesSaveQuestionFrame = new QFrame(&saveModifiedMessageBox); - QHBoxLayout* levelEntitiesSaveQuestionLayout = new QHBoxLayout(&saveModifiedMessageBox); - levelEntitiesSaveQuestionFrame->setObjectName("LevelEntitiesSaveQuestionFrame"); - - // Add a warning icon next to save entities question. - levelEntitiesSaveQuestionFrame->setLayout(levelEntitiesSaveQuestionLayout); - QPixmap warningIcon(QString(":/Notifications/warning.svg")); - QLabel* warningIconContainer = new QLabel(); - warningIconContainer->setPixmap(warningIcon); - warningIconContainer->setFixedWidth(warningIcon.width()); - levelEntitiesSaveQuestionLayout->addWidget(warningIconContainer); - - // Ask user if they want to save entities in level. - QLabel* levelEntitiesSaveQuestionLabel = new QLabel("Do you want to save unsaved entities in the level?"); - levelEntitiesSaveQuestionLayout->addWidget(levelEntitiesSaveQuestionLabel); - contentLayout->addWidget(levelEntitiesSaveQuestionFrame); - - // Ask user if they want to save unsaved prefabs in the level too. - QCheckBox* saveAllPrefabsCheckbox = new QCheckBox("Save all unsaved prefabs in the level too."); - AzQtComponents::CheckBox::applyToggleSwitchStyle(saveAllPrefabsCheckbox); - saveAllPrefabsCheckbox->setObjectName("SaveAllPrefabsCheckbox"); - QObject::connect( - saveAllPrefabsCheckbox, &QCheckBox::stateChanged, - [&savePrefabsPreference](int state) - { - savePrefabsPreference = static_cast(state) == Qt::CheckState::Checked - ? AzToolsFramework::SavePrefabsPreference::SaveAll - : AzToolsFramework::SavePrefabsPreference::SaveNone; - }); - contentLayout->addWidget(saveAllPrefabsCheckbox); - - // Footer section begins. - QFrame* footerSeparatorLine = new QFrame(); - footerSeparatorLine->setObjectName("FooterSeparatorLine"); - footerSeparatorLine->setFrameShape(QFrame::HLine); - contentLayout->addWidget(footerSeparatorLine); - QHBoxLayout* footerLayout = new QHBoxLayout(&saveModifiedMessageBox); - - // Provide option for user to remember their prefab save preference. - QCheckBox* saveAllPrefabsPreferenceCheckBox = new QCheckBox("Remember my preference."); - AzQtComponents::CheckBox::applyToggleSwitchStyle(saveAllPrefabsPreferenceCheckBox); - if (savePrefabsPreference == AzToolsFramework::SavePrefabsPreference::SaveAll) - { - saveAllPrefabsPreferenceCheckBox->setCheckState(Qt::CheckState::Checked); - saveAllPrefabsCheckbox->setCheckState(Qt::CheckState::Checked); - } - QVBoxLayout* footerPreferenceLayout = new QVBoxLayout(&saveModifiedMessageBox); - footerPreferenceLayout->addWidget(saveAllPrefabsPreferenceCheckBox); - QLabel* prefabSavePreferenceHint = new QLabel("You can change this anytime in Edit -> Editor Settings -> GlobalPreferences."); - prefabSavePreferenceHint->setObjectName("PrefabSavePreferenceHint"); - footerPreferenceLayout->addWidget(prefabSavePreferenceHint); - footerLayout->addLayout(footerPreferenceLayout); - QDialogButtonBox* prefabSaveConfirmationButtons = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Cancel); - footerLayout->addWidget(prefabSaveConfirmationButtons); - contentLayout->addLayout(footerLayout); - connect(prefabSaveConfirmationButtons, &QDialogButtonBox::accepted, &saveModifiedMessageBox, &QDialog::accept); - connect(prefabSaveConfirmationButtons, &QDialogButtonBox::rejected, &saveModifiedMessageBox, &QDialog::reject); - AzQtComponents::StyleManager::setStyleSheet(saveModifiedMessageBox.parentWidget(), QStringLiteral("style:Editor.qss")); - - int prefabSaveSelection = saveModifiedMessageBox.exec(); - - if (saveAllPrefabsPreferenceCheckBox->checkState() == Qt::CheckState::Checked) + auto prefabSaveSelectionDialog = ConstructSaveLevelDialog(); + + int prefabSaveSelection = prefabSaveSelectionDialog->exec(); + QCheckBox* saveAllPrefabsPreferenceCheckBox = prefabSaveSelectionDialog->findChild("SaveAllPrefabsPreferenceCheckBox"); + QCheckBox* saveAllPrefabsCheckBox = prefabSaveSelectionDialog->findChild("SaveAllPrefabsCheckbox"); + AzToolsFramework::SavePrefabsPreference savePrefabsPreference = saveAllPrefabsCheckBox->isChecked() + ? AzToolsFramework::SavePrefabsPreference::SaveAll + : AzToolsFramework::SavePrefabsPreference::SaveNone; + + switch (1 - prefabSaveSelection) { - gSettings.SetSavePrefabsPreference(savePrefabsPreference); - prefabEditorEntityOwnershipInterface->SetSavePrefabsPreference(savePrefabsPreference); - } - - switch (prefabSaveSelection) - { - case QDialog::Accepted: + case QDialogButtonBox::AcceptRole: DoFileSave(); + if (saveAllPrefabsPreferenceCheckBox->checkState() == Qt::CheckState::Checked) + { + gSettings.SetSavePrefabsPreference(savePrefabsPreference); + gSettings.Save(); + } if (savePrefabsPreference == AzToolsFramework::SavePrefabsPreference::SaveAll) { prefabSystemComponentInterface->SaveAllDirtyTemplates(); } return true; - case QDialog::Rejected: + case QDialogButtonBox::RejectRole: return false; + case QDialogButtonBox::InvalidRole: + SetModifiedFlag(false); + return true; } Q_UNREACHABLE(); } @@ -799,6 +741,17 @@ void CCryEditDoc::OnFileSaveAs() if (OnSaveDocument(levelFileDialog.GetFileName())) { CCryEditApp::instance()->AddToRecentFileList(levelFileDialog.GetFileName()); + bool usePrefabSystemForLevels = false; + AzFramework::ApplicationRequests::Bus::BroadcastResult( + usePrefabSystemForLevels, &AzFramework::ApplicationRequests::IsPrefabSystemForLevelsEnabled); + if (usePrefabSystemForLevels) + { + auto prefabSystemComponentInterface = AZ::Interface::Get(); + if (prefabSystemComponentInterface->AreDirtyTemplatesPresent()) + { + ExecuteSavePrefabsDialog(); + } + } } } } @@ -2308,6 +2261,194 @@ void CCryEditDoc::OnSliceInstantiationFailed(const AZ::Data::AssetId& sliceAsset } ////////////////////////////////////////////////////////////////////////// +AZStd::shared_ptr CCryEditDoc::ConstructSaveLevelDialog() +{ + auto prefabEditorEntityOwnershipInterface = AZ::Interface::Get(); + AzToolsFramework::SavePrefabsPreference savePrefabsPreference = prefabEditorEntityOwnershipInterface->GetSavePrefabsPreference(); + + AZStd::shared_ptr saveModifiedMessageBox = AZStd::make_shared(AzToolsFramework::GetActiveWindow()); + AZStd::weak_ptr saveModifiedMessageBoxWeakPtr(saveModifiedMessageBox); + // saveModifiedMessageBox.overrideWindowFlags((saveModifiedMessageBox.windowFlags()) & ~Qt::WindowCloseButtonHint); + saveModifiedMessageBox->setObjectName("SaveDirtyLevelDialog"); + + // Main Content section begins. + QVBoxLayout* contentLayout = new QVBoxLayout(saveModifiedMessageBox.get()); + QFrame* levelEntitiesSaveQuestionFrame = new QFrame(saveModifiedMessageBox.get()); + QHBoxLayout* levelEntitiesSaveQuestionLayout = new QHBoxLayout(saveModifiedMessageBox.get()); + levelEntitiesSaveQuestionFrame->setObjectName("LevelEntitiesSaveQuestionFrame"); + + // Add a warning icon next to save entities question. + levelEntitiesSaveQuestionFrame->setLayout(levelEntitiesSaveQuestionLayout); + QPixmap warningIcon(QString(":/Notifications/warning.svg")); + QLabel* warningIconContainer = new QLabel(); + warningIconContainer->setPixmap(warningIcon); + warningIconContainer->setFixedWidth(warningIcon.width()); + levelEntitiesSaveQuestionLayout->addWidget(warningIconContainer); + + // Ask user if they want to save entities in level. + QLabel* levelEntitiesSaveQuestionLabel = new QLabel("Do you want to save unsaved entities in the level?"); + levelEntitiesSaveQuestionLayout->addWidget(levelEntitiesSaveQuestionLabel); + contentLayout->addWidget(levelEntitiesSaveQuestionFrame); + + // Ask user if they want to save unsaved prefabs in the level too. + QCheckBox* saveAllPrefabsCheckbox = new QCheckBox("Save all unsaved prefabs in the level too."); + AzQtComponents::CheckBox::applyToggleSwitchStyle(saveAllPrefabsCheckbox); + saveAllPrefabsCheckbox->setObjectName("SaveAllPrefabsCheckbox"); + if (savePrefabsPreference == AzToolsFramework::SavePrefabsPreference::SaveAll) + { + saveAllPrefabsCheckbox->setCheckState(Qt::CheckState::Checked); + } + QObject::connect( + saveAllPrefabsCheckbox, &QCheckBox::stateChanged, + [&savePrefabsPreference](int state) + { + savePrefabsPreference = static_cast(state) == Qt::CheckState::Checked + ? AzToolsFramework::SavePrefabsPreference::SaveAll + : AzToolsFramework::SavePrefabsPreference::SaveNone; + }); + contentLayout->addWidget(saveAllPrefabsCheckbox); + + // Footer section begins. + QFrame* footerSeparatorLine = new QFrame(); + footerSeparatorLine->setObjectName("FooterSeparatorLine"); + footerSeparatorLine->setFrameShape(QFrame::HLine); + contentLayout->addWidget(footerSeparatorLine); + QHBoxLayout* footerLayout = new QHBoxLayout(saveModifiedMessageBox.get()); + + // Provide option for user to remember their prefab save preference. + QCheckBox* saveAllPrefabsPreferenceCheckBox = new QCheckBox("Remember my preference."); + saveAllPrefabsPreferenceCheckBox->setObjectName("SaveAllPrefabsPreferenceCheckBox"); + AzQtComponents::CheckBox::applyToggleSwitchStyle(saveAllPrefabsPreferenceCheckBox); + if (savePrefabsPreference != AzToolsFramework::SavePrefabsPreference::Unspecified) + { + saveAllPrefabsPreferenceCheckBox->setCheckState(Qt::CheckState::Checked); + } + QVBoxLayout* footerPreferenceLayout = new QVBoxLayout(saveModifiedMessageBox.get()); + footerPreferenceLayout->addWidget(saveAllPrefabsPreferenceCheckBox); + QLabel* prefabSavePreferenceHint = new QLabel("You can change this anytime in Edit -> Editor Settings -> GlobalPreferences."); + prefabSavePreferenceHint->setObjectName("PrefabSavePreferenceHint"); + footerPreferenceLayout->addWidget(prefabSavePreferenceHint); + footerLayout->addLayout(footerPreferenceLayout); + QDialogButtonBox* prefabSaveConfirmationButtons = + new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::Discard | QDialogButtonBox::Cancel); + footerLayout->addWidget(prefabSaveConfirmationButtons); + contentLayout->addLayout(footerLayout); + connect(prefabSaveConfirmationButtons, &QDialogButtonBox::accepted, saveModifiedMessageBox.get(), &QDialog::accept); + connect(prefabSaveConfirmationButtons, &QDialogButtonBox::rejected, saveModifiedMessageBox.get(), &QDialog::reject); + connect( + prefabSaveConfirmationButtons, &QDialogButtonBox::clicked, saveModifiedMessageBox.get(), + [saveModifiedMessageBoxWeakPtr, prefabSaveConfirmationButtons](QAbstractButton* button) + { + int prefabSaveSelection = prefabSaveConfirmationButtons->buttonRole(button); + saveModifiedMessageBoxWeakPtr.lock()->done(prefabSaveSelection); + }); + AzQtComponents::StyleManager::setStyleSheet(saveModifiedMessageBox.get(), QStringLiteral("style:Editor.qss")); + return saveModifiedMessageBox; +} + +void CCryEditDoc::ExecuteSavePrefabsDialog() +{ + auto prefabSystemComponentInterface = AZ::Interface::Get(); + auto prefabEditorEntityOwnershipInterface = AZ::Interface::Get(); + AzToolsFramework::SavePrefabsPreference savePrefabsPreference = prefabEditorEntityOwnershipInterface->GetSavePrefabsPreference(); + + if (savePrefabsPreference == AzToolsFramework::SavePrefabsPreference::SaveAll) + { + prefabSystemComponentInterface->SaveAllDirtyTemplates(); + SetModifiedFlag(false); + } + else if (savePrefabsPreference == AzToolsFramework::SavePrefabsPreference::SaveNone) + { + if (prefabSystemComponentInterface->AreDirtyTemplatesPresent()) + { + SetModifiedFlag(true); + } + } + else // AzToolsFramework::SavePrefabsPreference::Unspecified + { + QDialog saveModifiedMessageBox(AzToolsFramework::GetActiveWindow()); + + // Main Content section begins. + saveModifiedMessageBox.setObjectName("SaveAllPrefabsDialog"); + QBoxLayout* contentLayout = new QVBoxLayout(&saveModifiedMessageBox); + QFrame* levelSavedMessageFrame = new QFrame(&saveModifiedMessageBox); + QHBoxLayout* levelSavedMessageLayout = new QHBoxLayout(&saveModifiedMessageBox); + levelSavedMessageFrame->setObjectName("LevelSavedMessageFrame"); + + // Add a checkMark icon next to the level entities saved message. + QPixmap checkMarkIcon(QString(":/Notifications/checkmark.svg")); + QLabel* levelSavedSuccessfullyIconContainer = new QLabel(); + levelSavedSuccessfullyIconContainer->setPixmap(checkMarkIcon); + levelSavedSuccessfullyIconContainer->setFixedWidth(checkMarkIcon.width()); + + // Add a message that level entities are saved successfully. + QLabel* levelSavedSuccessfullyLabel = new QLabel("All entities inside level have been saved successfully."); + levelSavedSuccessfullyLabel->setObjectName("LevelSavedSuccessfullyLabel"); + levelSavedMessageLayout->addWidget(levelSavedSuccessfullyIconContainer); + levelSavedMessageLayout->addWidget(levelSavedSuccessfullyLabel); + levelSavedMessageFrame->setLayout(levelSavedMessageLayout); + + QFrame* prefabSaveQuestionFrame = new QFrame(&saveModifiedMessageBox); + QHBoxLayout* prefabSaveQuestionLayout = new QHBoxLayout(&saveModifiedMessageBox); + + // Add a warning icon next to prefabs save question. + QLabel* warningIconContainer = new QLabel(); + QPixmap warningIcon(QString(":/Notifications/warning.svg")); + warningIconContainer->setPixmap(warningIcon); + warningIconContainer->setFixedWidth(warningIcon.width()); + prefabSaveQuestionLayout->addWidget(warningIconContainer); + + // Ask if user wants all prefabs saved. + QLabel* prefabSaveQuestionLabel = new QLabel("Do you want to save all unsaved prefabs?"); + prefabSaveQuestionFrame->setObjectName("PrefabSaveQuestionFrame"); + prefabSaveQuestionLayout->addWidget(prefabSaveQuestionLabel); + prefabSaveQuestionFrame->setLayout(prefabSaveQuestionLayout); + contentLayout->addWidget(levelSavedMessageFrame); + contentLayout->addWidget(prefabSaveQuestionFrame); + + // Footer section begins. + QFrame* footerSeparatorLine = new QFrame(); + footerSeparatorLine->setObjectName("FooterSeparatorLine"); + footerSeparatorLine->setFrameShape(QFrame::HLine); + contentLayout->addWidget(footerSeparatorLine); + QHBoxLayout* footerLayout = new QHBoxLayout(&saveModifiedMessageBox); + + // Provide option for user to remember their prefab save preference. + QCheckBox* saveAllPrefabsPreference = new QCheckBox("Remember my preference."); + AzQtComponents::CheckBox::applyToggleSwitchStyle(saveAllPrefabsPreference); + QVBoxLayout* footerPreferenceLayout = new QVBoxLayout(&saveModifiedMessageBox); + footerPreferenceLayout->addWidget(saveAllPrefabsPreference); + QLabel* prefabSavePreferenceHint = new QLabel("You can change this anytime in Edit -> Editor Settings -> GlobalPreferences."); + prefabSavePreferenceHint->setObjectName("PrefabSavePreferenceHint"); + footerPreferenceLayout->addWidget(prefabSavePreferenceHint); + footerLayout->addLayout(footerPreferenceLayout); + QDialogButtonBox* prefabSaveConfirmationButtons = new QDialogButtonBox(QDialogButtonBox::Save | QDialogButtonBox::No); + footerLayout->addWidget(prefabSaveConfirmationButtons); + contentLayout->addLayout(footerLayout); + connect(prefabSaveConfirmationButtons, &QDialogButtonBox::accepted, &saveModifiedMessageBox, &QDialog::accept); + connect(prefabSaveConfirmationButtons, &QDialogButtonBox::rejected, &saveModifiedMessageBox, &QDialog::reject); + AzQtComponents::StyleManager::setStyleSheet(saveModifiedMessageBox.parentWidget(), QStringLiteral("style:Editor.qss")); + + int prefabSaveSelection = saveModifiedMessageBox.exec(); + + if (saveAllPrefabsPreference->checkState() == Qt::CheckState::Checked) + { + gSettings.SetSavePrefabsPreference(savePrefabsPreference); + gSettings.Save(); + } + switch (prefabSaveSelection) + { + case QDialog::Accepted: + prefabSystemComponentInterface->SaveAllDirtyTemplates(); + SetModifiedFlag(false); + break; + case QDialog::Rejected: + SetModifiedFlag(true); + break; + } + } +} + namespace AzToolsFramework { void CryEditDocFuncsHandler::Reflect(AZ::ReflectContext* context) diff --git a/Code/Editor/CryEditDoc.h b/Code/Editor/CryEditDoc.h index a96e9428b6..3a12b461fb 100644 --- a/Code/Editor/CryEditDoc.h +++ b/Code/Editor/CryEditDoc.h @@ -104,6 +104,12 @@ public: // Create from serialization only bool CanCloseFrame(); + //! Returns a Modal containing options to save the current level. + AZStd::shared_ptr ConstructSaveLevelDialog(); + + //! Executes a Modal asking users about their prefabs save preference. + void ExecuteSavePrefabsDialog(); + enum class FetchPolicy { DELETE_FOLDER, diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp index 31f5816bfc..c6f91a422a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp @@ -753,6 +753,18 @@ namespace AzToolsFramework } } + bool PrefabSystemComponent::AreDirtyTemplatesPresent() + { + for (const auto& [id, templateObject] : m_templateIdMap) + { + if (IsTemplateDirty(id)) + { + return true; + } + } + return false; + } + void PrefabSystemComponent::SaveAllDirtyTemplates() { for (auto& [id, templateObject] : m_templateIdMap) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h index 3539a79d54..cb95f9b367 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.h @@ -183,6 +183,8 @@ namespace AzToolsFramework */ void SetTemplateDirtyFlag(const TemplateId& templateId, bool dirty) override; + bool AreDirtyTemplatesPresent() override; + void SaveAllDirtyTemplates() override; ////////////////////////////////////////////////////////////////////////// diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h index bcea8a8b2d..252c8bdb6a 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponentInterface.h @@ -49,6 +49,7 @@ namespace AzToolsFramework virtual bool IsTemplateDirty(const TemplateId& templateId) = 0; virtual void SetTemplateDirtyFlag(const TemplateId& templateId, bool dirty) = 0; + virtual bool AreDirtyTemplatesPresent() = 0; virtual void SaveAllDirtyTemplates() = 0; virtual PrefabDom& FindTemplateDom(TemplateId templateId) = 0;