EditorPreferencesDialog.cpp 11 KB

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