EditorPreferencesDialog.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "EditorDefs.h"
  9. #include "EditorPreferencesDialog.h"
  10. // AzQtComponents
  11. #include <AzQtComponents/Components/WindowDecorationWrapper.h>
  12. #include <AzQtComponents/Components/StyleManager.h>
  13. #include <AzToolsFramework/Editor/EditorSettingsAPIBus.h>
  14. #include "EditorPreferencesTreeWidgetItemDelegate.h"
  15. // Editor
  16. #include "MainWindow.h"
  17. #include "EditorPreferencesTreeWidgetItem.h"
  18. #include "DisplaySettings.h"
  19. #include "CryEditDoc.h"
  20. #include "Controls/ConsoleSCB.h"
  21. #include "EditorPreferencesPageGeneral.h"
  22. #include "EditorPreferencesPageFiles.h"
  23. #include "EditorPreferencesPageViewportGeneral.h"
  24. #include "EditorPreferencesPageViewportManipulator.h"
  25. #include "EditorPreferencesPageViewportCamera.h"
  26. #include "EditorPreferencesPageViewportDebug.h"
  27. #include "EditorPreferencesPageAWS.h"
  28. #include "LyViewPaneNames.h"
  29. #include "Entity/EditorEntityHelpers.h"
  30. // Editor
  31. #include "EditorPreferencesPageGeneral.h"
  32. #include "EditorPreferencesPageFiles.h"
  33. #include "EditorPreferencesPageViewportGeneral.h"
  34. #include "EditorPreferencesPageViewportManipulator.h"
  35. #include "EditorPreferencesPageViewportCamera.h"
  36. #include "EditorPreferencesPageViewportDebug.h"
  37. #include "EditorPreferencesPageAWS.h"
  38. #include <ui_EditorPreferencesDialog.h>
  39. using namespace AzQtComponents;
  40. EditorPreferencesDialog::EditorPreferencesDialog(QWidget* pParent)
  41. : QDialog(new WindowDecorationWrapper(WindowDecorationWrapper::OptionAutoAttach | WindowDecorationWrapper::OptionAutoTitleBarButtons, pParent))
  42. , ui(new Ui::EditorPreferencesDialog)
  43. , m_currentPageItem(nullptr)
  44. {
  45. ui->setupUi(this);
  46. ui->filter->SetTypeFilterVisible(false);
  47. connect(ui->filter, &FilteredSearchWidget::TextFilterChanged, this, &EditorPreferencesDialog::SetFilter);
  48. AZ::SerializeContext* serializeContext = nullptr;
  49. AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext);
  50. AZ_Assert(serializeContext, "Serialization context not available");
  51. static bool bAlreadyRegistered = false;
  52. if (!bAlreadyRegistered)
  53. {
  54. bAlreadyRegistered = true;
  55. if (serializeContext)
  56. {
  57. CEditorPreferencesPage_General::Reflect(*serializeContext);
  58. CEditorPreferencesPage_Files::Reflect(*serializeContext);
  59. CEditorPreferencesPage_ViewportGeneral::Reflect(*serializeContext);
  60. CEditorPreferencesPage_ViewportManipulator::Reflect(*serializeContext);
  61. CEditorPreferencesPage_ViewportCamera::Reflect(*serializeContext);
  62. CEditorPreferencesPage_ViewportDebug::Reflect(*serializeContext);
  63. CEditorPreferencesPage_AWS::Reflect(*serializeContext);
  64. }
  65. }
  66. ui->propertyEditor->SetAutoResizeLabels(true);
  67. ui->propertyEditor->Setup(serializeContext, this, true, 250);
  68. ui->pageTree->setColumnCount(1);
  69. // There are no expandable categories, so hide the column.
  70. ui->pageTree->setRootIsDecorated(false);
  71. // Set the delegate so we can use the svg icons.
  72. ui->pageTree->setItemDelegate(new EditorPreferencesTreeWidgetItemDelegate(ui->pageTree));
  73. // Shrink the spacer so that the search bar fills the dialog.
  74. ui->horizontalSpacer_2->changeSize(0, 0, QSizePolicy::Maximum);
  75. connect(ui->pageTree, &QTreeWidget::currentItemChanged, this, &EditorPreferencesDialog::OnTreeCurrentItemChanged);
  76. connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &EditorPreferencesDialog::OnAccept);
  77. connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &EditorPreferencesDialog::OnReject);
  78. connect(ui->MANAGE_BTN, &QPushButton::clicked, this, &EditorPreferencesDialog::OnManage);
  79. AzQtComponents::StyleManager::setStyleSheet(this, QStringLiteral("style:EditorPreferencesDialog.qss"));
  80. }
  81. EditorPreferencesDialog::~EditorPreferencesDialog()
  82. {
  83. }
  84. void EditorPreferencesDialog::SetFilterText(const QString& filter)
  85. {
  86. ui->filter->SetTextFilter(filter);
  87. }
  88. void EditorPreferencesDialog::showEvent(QShowEvent* event)
  89. {
  90. origAutoBackup.bEnabled = gSettings.autoBackupEnabled;
  91. origAutoBackup.nTime = gSettings.autoBackupTime;
  92. origAutoBackup.nRemindTime = gSettings.autoRemindTime;
  93. CreateImages();
  94. CreatePages();
  95. ui->pageTree->setCurrentItem(ui->pageTree->topLevelItem(0));
  96. QDialog::showEvent(event);
  97. }
  98. bool WidgetConsumesKeyPressEvent(QKeyEvent* event)
  99. {
  100. // If the enter key is pressed during any text input, the dialog box will close
  101. // making it inconvenient to do multiple edits. This routine captures the
  102. // Key_Enter or Key_Return and clears the focus to give a visible cue that
  103. // editing of that field has finished and then doesn't propagate it.
  104. if (event->key() != Qt::Key::Key_Enter && event->key() != Qt::Key::Key_Return)
  105. {
  106. return false;
  107. }
  108. if (QWidget* editWidget = QApplication::focusWidget())
  109. {
  110. editWidget->clearFocus();
  111. }
  112. return true;
  113. }
  114. void EditorPreferencesDialog::keyPressEvent(QKeyEvent* event)
  115. {
  116. if (!WidgetConsumesKeyPressEvent(event))
  117. {
  118. QDialog::keyPressEvent(event);
  119. }
  120. }
  121. void EditorPreferencesDialog::OnTreeCurrentItemChanged()
  122. {
  123. QTreeWidgetItem* currentItem = ui->pageTree->currentItem();
  124. if (currentItem->type() == EditorPreferencesTreeWidgetItem::EditorPreferencesPage)
  125. {
  126. EditorPreferencesTreeWidgetItem* currentPageItem = static_cast<EditorPreferencesTreeWidgetItem*>(currentItem);
  127. if (currentPageItem != m_currentPageItem)
  128. {
  129. SetActivePage(currentPageItem);
  130. }
  131. }
  132. else
  133. {
  134. if (m_currentPageItem == nullptr || m_currentPageItem->parent() != currentItem)
  135. {
  136. EditorPreferencesTreeWidgetItem* child = (EditorPreferencesTreeWidgetItem*)currentItem->child(0);
  137. SetActivePage(child);
  138. }
  139. }
  140. }
  141. void EditorPreferencesDialog::OnAccept()
  142. {
  143. // Call on OK for all pages.
  144. QTreeWidgetItemIterator it(ui->pageTree);
  145. while (*it)
  146. {
  147. QTreeWidgetItem* item = *it;
  148. if (item->type() == EditorPreferencesTreeWidgetItem::EditorPreferencesPage)
  149. {
  150. EditorPreferencesTreeWidgetItem* pageItem = (EditorPreferencesTreeWidgetItem*)*it;
  151. pageItem->GetPreferencesPage()->OnApply();
  152. }
  153. ++it;
  154. }
  155. // Save settings.
  156. gSettings.Save();
  157. GetIEditor()->GetDisplaySettings()->SaveRegistry();
  158. if (GetIEditor()->GetDocument()->IsDocumentReady() && (
  159. origAutoBackup.bEnabled != gSettings.autoBackupEnabled ||
  160. origAutoBackup.nTime != gSettings.autoBackupTime ||
  161. origAutoBackup.nRemindTime != gSettings.autoRemindTime))
  162. {
  163. // Ensure timers restart with the correct interval.
  164. MainWindow::instance()->ResetAutoSaveTimers();
  165. }
  166. AzToolsFramework::EditorPreferencesNotificationBus::Broadcast(&AzToolsFramework::EditorPreferencesNotifications::OnEditorPreferencesChanged);
  167. accept();
  168. }
  169. void EditorPreferencesDialog::OnReject()
  170. {
  171. // QueryCancel for all pages.
  172. QTreeWidgetItemIterator it(ui->pageTree);
  173. while (*it)
  174. {
  175. QTreeWidgetItem* item = *it;
  176. if (item->type() == EditorPreferencesTreeWidgetItem::EditorPreferencesPage)
  177. {
  178. EditorPreferencesTreeWidgetItem* pageItem = (EditorPreferencesTreeWidgetItem*)*it;
  179. if (!pageItem->GetPreferencesPage()->OnQueryCancel())
  180. {
  181. return;
  182. }
  183. }
  184. ++it;
  185. }
  186. QTreeWidgetItemIterator cancelIt(ui->pageTree);
  187. while (*cancelIt)
  188. {
  189. QTreeWidgetItem* item = *cancelIt;
  190. if (item->type() == EditorPreferencesTreeWidgetItem::EditorPreferencesPage)
  191. {
  192. EditorPreferencesTreeWidgetItem* pageItem = (EditorPreferencesTreeWidgetItem*)*cancelIt;
  193. pageItem->GetPreferencesPage()->OnCancel();
  194. }
  195. ++cancelIt;
  196. }
  197. reject();
  198. }
  199. void EditorPreferencesDialog::OnManage()
  200. {
  201. GetIEditor()->OpenView(LyViewPane::EditorSettingsManager);
  202. OnAccept();
  203. }
  204. void EditorPreferencesDialog::SetActivePage(EditorPreferencesTreeWidgetItem* pageItem)
  205. {
  206. m_currentPageItem = pageItem;
  207. ui->propertyEditor->ClearInstances();
  208. IPreferencesPage* instance = m_currentPageItem->GetPreferencesPage();
  209. const AZ::Uuid& classId = AZ::SerializeTypeInfo<IPreferencesPage>::GetUuid(instance);
  210. ui->propertyEditor->AddInstance(instance, classId);
  211. m_currentPageItem->UpdateEditorFilter(ui->propertyEditor, m_filter);
  212. ui->propertyEditor->show();
  213. // Refresh the Stylesheet - style would break on page load sometimes.
  214. AzQtComponents::StyleManager::repolishStyleSheet(this);
  215. }
  216. void EditorPreferencesDialog::SetFilter(const QString& filter)
  217. {
  218. m_filter = filter;
  219. QTreeWidgetItem* firstVisiblePage = nullptr;
  220. std::function<void(QTreeWidgetItem* item)> filterItem = [&](QTreeWidgetItem* item)
  221. {
  222. // Hide categories that have no pages remaining in them after filtering their pages
  223. if (item->childCount() > 0)
  224. {
  225. bool shouldHide = true;
  226. for (int i = item->childCount() - 1; i >= 0; --i)
  227. {
  228. QTreeWidgetItem* child = item->child(i);
  229. filterItem(child);
  230. shouldHide = shouldHide && child->isHidden();
  231. }
  232. item->setHidden(shouldHide);
  233. }
  234. else
  235. {
  236. EditorPreferencesTreeWidgetItem* pageItem = static_cast<EditorPreferencesTreeWidgetItem*>(item);
  237. pageItem->Filter(filter);
  238. if (!firstVisiblePage && !pageItem->isHidden())
  239. {
  240. firstVisiblePage = pageItem;
  241. }
  242. }
  243. };
  244. filterItem(ui->pageTree->invisibleRootItem());
  245. // If we're searching and we don't have a current selection any more (the old page got filtered)
  246. // go ahead and select the first valid page
  247. if ((!m_currentPageItem || m_currentPageItem->isHidden())
  248. && !filter.isEmpty() && firstVisiblePage)
  249. {
  250. ui->pageTree->setCurrentItem(firstVisiblePage);
  251. }
  252. else if (m_currentPageItem)
  253. {
  254. m_currentPageItem->UpdateEditorFilter(ui->propertyEditor, m_filter);
  255. // Refresh the Stylesheet - when using search functionality.
  256. AzQtComponents::StyleManager::repolishStyleSheet(this);
  257. }
  258. }
  259. void EditorPreferencesDialog::CreateImages()
  260. {
  261. m_selectedPixmap = QPixmap(":/res/Preferences_00.png");
  262. m_unSelectedPixmap = QPixmap(":/res/Preferences_01.png");
  263. }
  264. void EditorPreferencesDialog::CreatePages()
  265. {
  266. auto addPreferencePage = [&](IPreferencesPage* page) {
  267. ui->pageTree->addTopLevelItem(new EditorPreferencesTreeWidgetItem(page, page->GetIcon()));
  268. };
  269. addPreferencePage(new CEditorPreferencesPage_General());
  270. addPreferencePage(new CEditorPreferencesPage_Files());
  271. addPreferencePage(new CEditorPreferencesPage_ViewportGeneral());
  272. addPreferencePage(new CEditorPreferencesPage_ViewportCamera());
  273. addPreferencePage(new CEditorPreferencesPage_ViewportManipulator());
  274. addPreferencePage(new CEditorPreferencesPage_ViewportDebug());
  275. if (AzToolsFramework::IsComponentWithServiceRegistered(AZ_CRC_CE("AWSCoreEditorService")))
  276. {
  277. addPreferencePage(new CEditorPreferencesPage_AWS());
  278. }
  279. }
  280. void EditorPreferencesDialog::AfterPropertyModified([[maybe_unused]] AzToolsFramework::InstanceDataNode* node)
  281. {
  282. // ensure we refresh all the property editor values as it is possible for them to
  283. // change based on other values (e.g. legacy ui and new viewport not being compatible)
  284. ui->propertyEditor->InvalidateValues();
  285. }