EditorPreferencesDialog.cpp 12 KB

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