Settings.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836
  1. // Copyright 2015 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "DolphinQt/Settings.h"
  4. #include <atomic>
  5. #include <memory>
  6. #include <QApplication>
  7. #include <QColor>
  8. #include <QDir>
  9. #include <QFile>
  10. #include <QFileInfo>
  11. #include <QFontDatabase>
  12. #include <QPalette>
  13. #include <QRadioButton>
  14. #include <QSize>
  15. #include <QStyle>
  16. #include <QWidget>
  17. #ifdef _WIN32
  18. #include <fmt/format.h>
  19. #include <winrt/Windows.UI.ViewManagement.h>
  20. #include <QTabBar>
  21. #include <QToolButton>
  22. #endif
  23. #include "AudioCommon/AudioCommon.h"
  24. #include "Common/Config/Config.h"
  25. #include "Common/FileUtil.h"
  26. #include "Common/StringUtil.h"
  27. #include "Core/AchievementManager.h"
  28. #include "Core/Config/GraphicsSettings.h"
  29. #include "Core/Config/MainSettings.h"
  30. #include "Core/ConfigManager.h"
  31. #include "Core/Core.h"
  32. #include "Core/IOS/IOS.h"
  33. #include "Core/NetPlayClient.h"
  34. #include "Core/NetPlayServer.h"
  35. #include "Core/System.h"
  36. #include "DolphinQt/Host.h"
  37. #include "DolphinQt/QtUtils/QueueOnObject.h"
  38. #include "InputCommon/ControllerInterface/ControllerInterface.h"
  39. #include "InputCommon/InputConfig.h"
  40. #include "VideoCommon/NetPlayChatUI.h"
  41. #include "VideoCommon/NetPlayGolfUI.h"
  42. static bool s_system_dark = false;
  43. static std::unique_ptr<QPalette> s_default_palette;
  44. Settings::Settings()
  45. {
  46. qRegisterMetaType<Core::State>();
  47. Core::AddOnStateChangedCallback([this](Core::State new_state) {
  48. QueueOnObject(this, [this, new_state] {
  49. // Avoid signal spam while continuously frame stepping. Will still send a signal for the first
  50. // and last framestep.
  51. if (!m_continuously_frame_stepping)
  52. emit EmulationStateChanged(new_state);
  53. });
  54. });
  55. Config::AddConfigChangedCallback([this] {
  56. static std::atomic<bool> do_once{true};
  57. if (do_once.exchange(false))
  58. {
  59. // Calling ConfigChanged() with a "delay" can have risks, for example, if from
  60. // code we change some configs that result in Qt greying out some setting, we could
  61. // end up editing that setting before its greyed out, sending out an event,
  62. // which might not be expected or handled by the code, potentially crashing.
  63. // The only safe option would be to wait on the Qt thread to have finished executing this.
  64. QueueOnObject(this, [this] {
  65. do_once = true;
  66. emit ConfigChanged();
  67. });
  68. }
  69. });
  70. m_hotplug_callback_handle = g_controller_interface.RegisterDevicesChangedCallback([this] {
  71. if (Core::IsHostThread())
  72. {
  73. emit DevicesChanged();
  74. }
  75. else
  76. {
  77. // Any device shared_ptr in the host thread needs to be released immediately as otherwise
  78. // they'd continue living until the queued event has run, but some devices can't be recreated
  79. // until they are destroyed.
  80. // This is safe from any thread. Devices will be refreshed and re-acquired and in
  81. // DevicesChanged(). Calling it without queueing shouldn't cause any deadlocks but is slow.
  82. emit ReleaseDevices();
  83. QueueOnObject(this, [this] { emit DevicesChanged(); });
  84. }
  85. });
  86. }
  87. Settings::~Settings() = default;
  88. void Settings::UnregisterDevicesChangedCallback()
  89. {
  90. g_controller_interface.UnregisterDevicesChangedCallback(m_hotplug_callback_handle);
  91. }
  92. Settings& Settings::Instance()
  93. {
  94. static Settings settings;
  95. return settings;
  96. }
  97. QSettings& Settings::GetQSettings()
  98. {
  99. static QSettings settings(
  100. QStringLiteral("%1/Qt.ini").arg(QString::fromStdString(File::GetUserPath(D_CONFIG_IDX))),
  101. QSettings::IniFormat);
  102. return settings;
  103. }
  104. void Settings::TriggerThemeChanged()
  105. {
  106. emit ThemeChanged();
  107. }
  108. QString Settings::GetUserStyleName() const
  109. {
  110. if (GetQSettings().contains(QStringLiteral("userstyle/name")))
  111. return GetQSettings().value(QStringLiteral("userstyle/name")).toString();
  112. // Migration code for the old way of storing this setting
  113. return QFileInfo(GetQSettings().value(QStringLiteral("userstyle/path")).toString()).fileName();
  114. }
  115. void Settings::SetUserStyleName(const QString& stylesheet_name)
  116. {
  117. GetQSettings().setValue(QStringLiteral("userstyle/name"), stylesheet_name);
  118. }
  119. void Settings::InitDefaultPalette()
  120. {
  121. s_default_palette = std::make_unique<QPalette>(qApp->palette());
  122. }
  123. void Settings::UpdateSystemDark()
  124. {
  125. #ifdef _WIN32
  126. // Check if the system is set to dark mode so we can set the default theme and window
  127. // decorations accordingly.
  128. {
  129. using namespace winrt::Windows::UI::ViewManagement;
  130. const UISettings settings;
  131. const auto& color = settings.GetColorValue(UIColorType::Foreground);
  132. const bool is_system_dark = 5 * color.G + 2 * color.R + color.B > 8 * 128;
  133. Settings::Instance().SetSystemDark(is_system_dark);
  134. }
  135. #endif
  136. }
  137. void Settings::SetSystemDark(bool dark)
  138. {
  139. s_system_dark = dark;
  140. }
  141. bool Settings::IsSystemDark()
  142. {
  143. return s_system_dark;
  144. }
  145. bool Settings::IsThemeDark()
  146. {
  147. return qApp->palette().color(QPalette::Base).valueF() < 0.5;
  148. }
  149. // Calling this before the main window has been created breaks the style of some widgets.
  150. void Settings::ApplyStyle()
  151. {
  152. const StyleType style_type = GetStyleType();
  153. const QString stylesheet_name = GetUserStyleName();
  154. QString stylesheet_contents;
  155. // If we haven't found one, we continue with an empty (default) style
  156. if (!stylesheet_name.isEmpty() && style_type == StyleType::User)
  157. {
  158. // Load custom user stylesheet
  159. QDir directory = QDir(QString::fromStdString(File::GetUserPath(D_STYLES_IDX)));
  160. QFile stylesheet(directory.filePath(stylesheet_name));
  161. if (stylesheet.open(QFile::ReadOnly))
  162. stylesheet_contents = QString::fromUtf8(stylesheet.readAll().data());
  163. }
  164. #ifdef _WIN32
  165. if (stylesheet_contents.isEmpty())
  166. {
  167. // No theme selected or found. Usually we would just fallthrough and set an empty stylesheet
  168. // which would select Qt's default theme, but unlike other OSes we don't automatically get a
  169. // default dark theme on Windows when the user has selected dark mode in the Windows settings.
  170. // So manually check if the user wants dark mode and, if yes, load our embedded dark theme.
  171. if (style_type == StyleType::Dark || (style_type != StyleType::Light && IsSystemDark()))
  172. {
  173. QFile file(QStringLiteral(":/dolphin_dark_win/dark.qss"));
  174. if (file.open(QFile::ReadOnly))
  175. stylesheet_contents = QString::fromUtf8(file.readAll().data());
  176. QPalette palette = qApp->style()->standardPalette();
  177. palette.setColor(QPalette::Window, QColor(32, 32, 32));
  178. palette.setColor(QPalette::WindowText, QColor(220, 220, 220));
  179. palette.setColor(QPalette::Base, QColor(32, 32, 32));
  180. palette.setColor(QPalette::AlternateBase, QColor(48, 48, 48));
  181. palette.setColor(QPalette::PlaceholderText, QColor(126, 126, 126));
  182. palette.setColor(QPalette::Text, QColor(220, 220, 220));
  183. palette.setColor(QPalette::Button, QColor(48, 48, 48));
  184. palette.setColor(QPalette::ButtonText, QColor(220, 220, 220));
  185. palette.setColor(QPalette::BrightText, QColor(255, 255, 255));
  186. palette.setColor(QPalette::Highlight, QColor(0, 120, 215));
  187. palette.setColor(QPalette::HighlightedText, QColor(255, 255, 255));
  188. palette.setColor(QPalette::Link, QColor(100, 160, 220));
  189. palette.setColor(QPalette::LinkVisited, QColor(100, 160, 220));
  190. qApp->setPalette(palette);
  191. }
  192. else
  193. {
  194. // reset any palette changes that may exist from a previously set dark mode
  195. if (s_default_palette)
  196. qApp->setPalette(*s_default_palette);
  197. }
  198. }
  199. #endif
  200. // Define tooltips style if not already defined
  201. if (!stylesheet_contents.contains(QStringLiteral("QToolTip"), Qt::CaseSensitive))
  202. {
  203. const QPalette& palette = qApp->palette();
  204. QColor window_color;
  205. QColor text_color;
  206. QColor unused_text_emphasis_color;
  207. QColor border_color;
  208. GetToolTipStyle(window_color, text_color, unused_text_emphasis_color, border_color, palette,
  209. palette);
  210. const auto tooltip_stylesheet =
  211. QStringLiteral("QToolTip { background-color: #%1; color: #%2; padding: 8px; "
  212. "border: 1px; border-style: solid; border-color: #%3; }")
  213. .arg(window_color.rgba(), 0, 16)
  214. .arg(text_color.rgba(), 0, 16)
  215. .arg(border_color.rgba(), 0, 16);
  216. stylesheet_contents.append(QStringLiteral("%1").arg(tooltip_stylesheet));
  217. }
  218. qApp->setStyleSheet(stylesheet_contents);
  219. }
  220. Settings::StyleType Settings::GetStyleType() const
  221. {
  222. if (GetQSettings().contains(QStringLiteral("userstyle/styletype")))
  223. {
  224. bool ok = false;
  225. const int type_int = GetQSettings().value(QStringLiteral("userstyle/styletype")).toInt(&ok);
  226. if (ok && type_int >= static_cast<int>(StyleType::MinValue) &&
  227. type_int <= static_cast<int>(StyleType::MaxValue))
  228. {
  229. return static_cast<StyleType>(type_int);
  230. }
  231. }
  232. // if the style type is unset or invalid, try the old enabled flag instead
  233. const bool enabled = GetQSettings().value(QStringLiteral("userstyle/enabled"), false).toBool();
  234. return enabled ? StyleType::User : StyleType::System;
  235. }
  236. void Settings::SetStyleType(StyleType type)
  237. {
  238. GetQSettings().setValue(QStringLiteral("userstyle/styletype"), static_cast<int>(type));
  239. // also set the old setting so that the config is correctly intepreted by older Dolphin builds
  240. GetQSettings().setValue(QStringLiteral("userstyle/enabled"), type == StyleType::User);
  241. }
  242. void Settings::GetToolTipStyle(QColor& window_color, QColor& text_color,
  243. QColor& emphasis_text_color, QColor& border_color,
  244. const QPalette& palette, const QPalette& high_contrast_palette) const
  245. {
  246. const auto theme_window_color = palette.color(QPalette::Base);
  247. const auto theme_window_hsv = theme_window_color.toHsv();
  248. const auto brightness = theme_window_hsv.value();
  249. const bool brightness_over_threshold = brightness > 128;
  250. const QColor emphasis_text_color_1 = Qt::yellow;
  251. const QColor emphasis_text_color_2 = QColor(QStringLiteral("#0090ff")); // ~light blue
  252. if (Config::Get(Config::MAIN_USE_HIGH_CONTRAST_TOOLTIPS))
  253. {
  254. window_color = brightness_over_threshold ? QColor(72, 72, 72) : Qt::white;
  255. text_color = brightness_over_threshold ? Qt::white : Qt::black;
  256. emphasis_text_color = brightness_over_threshold ? emphasis_text_color_1 : emphasis_text_color_2;
  257. border_color = high_contrast_palette.color(QPalette::Window).darker(160);
  258. }
  259. else
  260. {
  261. window_color = palette.color(QPalette::Window);
  262. text_color = palette.color(QPalette::Text);
  263. emphasis_text_color = brightness_over_threshold ? emphasis_text_color_2 : emphasis_text_color_1;
  264. border_color = palette.color(QPalette::Text);
  265. }
  266. }
  267. QStringList Settings::GetPaths() const
  268. {
  269. QStringList list;
  270. for (const auto& path : Config::GetIsoPaths())
  271. list << QString::fromStdString(path);
  272. return list;
  273. }
  274. void Settings::AddPath(const QString& qpath)
  275. {
  276. std::string path = qpath.toStdString();
  277. std::vector<std::string> paths = Config::GetIsoPaths();
  278. if (std::find(paths.begin(), paths.end(), path) != paths.end())
  279. return;
  280. paths.emplace_back(path);
  281. Config::SetIsoPaths(paths);
  282. emit PathAdded(qpath);
  283. }
  284. void Settings::RemovePath(const QString& qpath)
  285. {
  286. std::string path = qpath.toStdString();
  287. std::vector<std::string> paths = Config::GetIsoPaths();
  288. auto new_end = std::remove(paths.begin(), paths.end(), path);
  289. if (new_end == paths.end())
  290. return;
  291. paths.erase(new_end, paths.end());
  292. Config::SetIsoPaths(paths);
  293. emit PathRemoved(qpath);
  294. }
  295. void Settings::RefreshGameList()
  296. {
  297. emit GameListRefreshRequested();
  298. }
  299. void Settings::NotifyRefreshGameListStarted()
  300. {
  301. emit GameListRefreshStarted();
  302. }
  303. void Settings::NotifyRefreshGameListComplete()
  304. {
  305. emit GameListRefreshCompleted();
  306. }
  307. void Settings::NotifyMetadataRefreshComplete()
  308. {
  309. emit MetadataRefreshCompleted();
  310. }
  311. void Settings::ReloadTitleDB()
  312. {
  313. emit TitleDBReloadRequested();
  314. }
  315. bool Settings::IsAutoRefreshEnabled() const
  316. {
  317. return GetQSettings().value(QStringLiteral("gamelist/autorefresh"), true).toBool();
  318. }
  319. void Settings::SetAutoRefreshEnabled(bool enabled)
  320. {
  321. if (IsAutoRefreshEnabled() == enabled)
  322. return;
  323. GetQSettings().setValue(QStringLiteral("gamelist/autorefresh"), enabled);
  324. emit AutoRefreshToggled(enabled);
  325. }
  326. QString Settings::GetDefaultGame() const
  327. {
  328. return QString::fromStdString(Config::Get(Config::MAIN_DEFAULT_ISO));
  329. }
  330. void Settings::SetDefaultGame(QString path)
  331. {
  332. if (GetDefaultGame() != path)
  333. {
  334. Config::SetBase(Config::MAIN_DEFAULT_ISO, path.toStdString());
  335. emit DefaultGameChanged(path);
  336. }
  337. }
  338. bool Settings::GetPreferredView() const
  339. {
  340. return GetQSettings().value(QStringLiteral("PreferredView"), true).toBool();
  341. }
  342. void Settings::SetPreferredView(bool list)
  343. {
  344. GetQSettings().setValue(QStringLiteral("PreferredView"), list);
  345. }
  346. int Settings::GetStateSlot() const
  347. {
  348. return GetQSettings().value(QStringLiteral("Emulation/StateSlot"), 1).toInt();
  349. }
  350. void Settings::SetStateSlot(int slot)
  351. {
  352. GetQSettings().setValue(QStringLiteral("Emulation/StateSlot"), slot);
  353. }
  354. Config::ShowCursor Settings::GetCursorVisibility() const
  355. {
  356. return Config::Get(Config::MAIN_SHOW_CURSOR);
  357. }
  358. bool Settings::GetLockCursor() const
  359. {
  360. return Config::Get(Config::MAIN_LOCK_CURSOR);
  361. }
  362. void Settings::SetKeepWindowOnTop(bool top)
  363. {
  364. if (IsKeepWindowOnTopEnabled() == top)
  365. return;
  366. emit KeepWindowOnTopChanged(top);
  367. }
  368. bool Settings::IsKeepWindowOnTopEnabled() const
  369. {
  370. return Config::Get(Config::MAIN_KEEP_WINDOW_ON_TOP);
  371. }
  372. bool Settings::GetGraphicModsEnabled() const
  373. {
  374. return Config::Get(Config::GFX_MODS_ENABLE);
  375. }
  376. void Settings::SetGraphicModsEnabled(bool enabled)
  377. {
  378. if (GetGraphicModsEnabled() == enabled)
  379. {
  380. return;
  381. }
  382. Config::SetBaseOrCurrent(Config::GFX_MODS_ENABLE, enabled);
  383. emit EnableGfxModsChanged(enabled);
  384. }
  385. int Settings::GetVolume() const
  386. {
  387. return Config::Get(Config::MAIN_AUDIO_VOLUME);
  388. }
  389. void Settings::SetVolume(int volume)
  390. {
  391. if (GetVolume() != volume)
  392. {
  393. Config::SetBaseOrCurrent(Config::MAIN_AUDIO_VOLUME, volume);
  394. emit VolumeChanged(volume);
  395. }
  396. }
  397. void Settings::IncreaseVolume(int volume)
  398. {
  399. AudioCommon::IncreaseVolume(Core::System::GetInstance(), volume);
  400. emit VolumeChanged(GetVolume());
  401. }
  402. void Settings::DecreaseVolume(int volume)
  403. {
  404. AudioCommon::DecreaseVolume(Core::System::GetInstance(), volume);
  405. emit VolumeChanged(GetVolume());
  406. }
  407. bool Settings::IsLogVisible() const
  408. {
  409. return GetQSettings().value(QStringLiteral("logging/logvisible")).toBool();
  410. }
  411. void Settings::SetLogVisible(bool visible)
  412. {
  413. if (IsLogVisible() != visible)
  414. {
  415. GetQSettings().setValue(QStringLiteral("logging/logvisible"), visible);
  416. emit LogVisibilityChanged(visible);
  417. }
  418. }
  419. bool Settings::IsLogConfigVisible() const
  420. {
  421. return GetQSettings().value(QStringLiteral("logging/logconfigvisible")).toBool();
  422. }
  423. void Settings::SetLogConfigVisible(bool visible)
  424. {
  425. if (IsLogConfigVisible() != visible)
  426. {
  427. GetQSettings().setValue(QStringLiteral("logging/logconfigvisible"), visible);
  428. emit LogConfigVisibilityChanged(visible);
  429. }
  430. }
  431. std::shared_ptr<NetPlay::NetPlayClient> Settings::GetNetPlayClient()
  432. {
  433. return m_client;
  434. }
  435. void Settings::ResetNetPlayClient(NetPlay::NetPlayClient* client)
  436. {
  437. m_client.reset(client);
  438. g_netplay_chat_ui.reset();
  439. g_netplay_golf_ui.reset();
  440. }
  441. std::shared_ptr<NetPlay::NetPlayServer> Settings::GetNetPlayServer()
  442. {
  443. return m_server;
  444. }
  445. void Settings::ResetNetPlayServer(NetPlay::NetPlayServer* server)
  446. {
  447. m_server.reset(server);
  448. }
  449. bool Settings::GetCheatsEnabled() const
  450. {
  451. return Config::Get(Config::MAIN_ENABLE_CHEATS);
  452. }
  453. void Settings::SetDebugModeEnabled(bool enabled)
  454. {
  455. if (AchievementManager::GetInstance().IsHardcoreModeActive())
  456. enabled = false;
  457. if (IsDebugModeEnabled() != enabled)
  458. {
  459. Config::SetBaseOrCurrent(Config::MAIN_ENABLE_DEBUGGING, enabled);
  460. emit DebugModeToggled(enabled);
  461. if (enabled)
  462. SetCodeVisible(true);
  463. }
  464. }
  465. bool Settings::IsDebugModeEnabled() const
  466. {
  467. return Config::Get(Config::MAIN_ENABLE_DEBUGGING);
  468. }
  469. void Settings::SetRegistersVisible(bool enabled)
  470. {
  471. if (IsRegistersVisible() != enabled)
  472. {
  473. GetQSettings().setValue(QStringLiteral("debugger/showregisters"), enabled);
  474. emit RegistersVisibilityChanged(enabled);
  475. }
  476. }
  477. bool Settings::IsThreadsVisible() const
  478. {
  479. return GetQSettings().value(QStringLiteral("debugger/showthreads")).toBool();
  480. }
  481. void Settings::SetThreadsVisible(bool enabled)
  482. {
  483. if (IsThreadsVisible() == enabled)
  484. return;
  485. GetQSettings().setValue(QStringLiteral("debugger/showthreads"), enabled);
  486. emit ThreadsVisibilityChanged(enabled);
  487. }
  488. bool Settings::IsRegistersVisible() const
  489. {
  490. return GetQSettings().value(QStringLiteral("debugger/showregisters")).toBool();
  491. }
  492. void Settings::SetWatchVisible(bool enabled)
  493. {
  494. if (IsWatchVisible() != enabled)
  495. {
  496. GetQSettings().setValue(QStringLiteral("debugger/showwatch"), enabled);
  497. emit WatchVisibilityChanged(enabled);
  498. }
  499. }
  500. bool Settings::IsWatchVisible() const
  501. {
  502. return GetQSettings().value(QStringLiteral("debugger/showwatch")).toBool();
  503. }
  504. void Settings::SetBreakpointsVisible(bool enabled)
  505. {
  506. if (IsBreakpointsVisible() != enabled)
  507. {
  508. GetQSettings().setValue(QStringLiteral("debugger/showbreakpoints"), enabled);
  509. emit BreakpointsVisibilityChanged(enabled);
  510. }
  511. }
  512. bool Settings::IsBreakpointsVisible() const
  513. {
  514. return GetQSettings().value(QStringLiteral("debugger/showbreakpoints")).toBool();
  515. }
  516. void Settings::SetCodeVisible(bool enabled)
  517. {
  518. if (IsCodeVisible() != enabled)
  519. {
  520. GetQSettings().setValue(QStringLiteral("debugger/showcode"), enabled);
  521. emit CodeVisibilityChanged(enabled);
  522. }
  523. }
  524. bool Settings::IsCodeVisible() const
  525. {
  526. return GetQSettings().value(QStringLiteral("debugger/showcode")).toBool();
  527. }
  528. void Settings::SetMemoryVisible(bool enabled)
  529. {
  530. if (IsMemoryVisible() == enabled)
  531. return;
  532. QSettings().setValue(QStringLiteral("debugger/showmemory"), enabled);
  533. emit MemoryVisibilityChanged(enabled);
  534. }
  535. bool Settings::IsMemoryVisible() const
  536. {
  537. return QSettings().value(QStringLiteral("debugger/showmemory")).toBool();
  538. }
  539. void Settings::SetNetworkVisible(bool enabled)
  540. {
  541. if (IsNetworkVisible() == enabled)
  542. return;
  543. GetQSettings().setValue(QStringLiteral("debugger/shownetwork"), enabled);
  544. emit NetworkVisibilityChanged(enabled);
  545. }
  546. bool Settings::IsNetworkVisible() const
  547. {
  548. return GetQSettings().value(QStringLiteral("debugger/shownetwork")).toBool();
  549. }
  550. void Settings::SetJITVisible(bool enabled)
  551. {
  552. if (IsJITVisible() == enabled)
  553. return;
  554. QSettings().setValue(QStringLiteral("debugger/showjit"), enabled);
  555. emit JITVisibilityChanged(enabled);
  556. }
  557. bool Settings::IsJITVisible() const
  558. {
  559. return QSettings().value(QStringLiteral("debugger/showjit")).toBool();
  560. }
  561. void Settings::SetAssemblerVisible(bool enabled)
  562. {
  563. if (IsAssemblerVisible() == enabled)
  564. return;
  565. QSettings().setValue(QStringLiteral("debugger/showassembler"), enabled);
  566. emit AssemblerVisibilityChanged(enabled);
  567. }
  568. bool Settings::IsAssemblerVisible() const
  569. {
  570. return QSettings().value(QStringLiteral("debugger/showassembler")).toBool();
  571. }
  572. void Settings::RefreshWidgetVisibility()
  573. {
  574. emit DebugModeToggled(IsDebugModeEnabled());
  575. emit LogVisibilityChanged(IsLogVisible());
  576. emit LogConfigVisibilityChanged(IsLogConfigVisible());
  577. }
  578. void Settings::SetDebugFont(QFont font)
  579. {
  580. if (GetDebugFont() != font)
  581. {
  582. GetQSettings().setValue(QStringLiteral("debugger/font"), font);
  583. emit DebugFontChanged(font);
  584. }
  585. }
  586. QFont Settings::GetDebugFont() const
  587. {
  588. QFont default_font = QFont(QFontDatabase::systemFont(QFontDatabase::FixedFont).family());
  589. default_font.setPointSizeF(9.0);
  590. return GetQSettings().value(QStringLiteral("debugger/font"), default_font).value<QFont>();
  591. }
  592. void Settings::SetAutoUpdateTrack(const QString& mode)
  593. {
  594. if (mode == GetAutoUpdateTrack())
  595. return;
  596. Config::SetBase(Config::MAIN_AUTOUPDATE_UPDATE_TRACK, mode.toStdString());
  597. emit AutoUpdateTrackChanged(mode);
  598. }
  599. QString Settings::GetAutoUpdateTrack() const
  600. {
  601. return QString::fromStdString(Config::Get(Config::MAIN_AUTOUPDATE_UPDATE_TRACK));
  602. }
  603. void Settings::SetFallbackRegion(const DiscIO::Region& region)
  604. {
  605. if (region == GetFallbackRegion())
  606. return;
  607. Config::SetBase(Config::MAIN_FALLBACK_REGION, region);
  608. emit FallbackRegionChanged(region);
  609. }
  610. DiscIO::Region Settings::GetFallbackRegion() const
  611. {
  612. return Config::Get(Config::MAIN_FALLBACK_REGION);
  613. }
  614. void Settings::SetAnalyticsEnabled(bool enabled)
  615. {
  616. if (enabled == IsAnalyticsEnabled())
  617. return;
  618. Config::SetBase(Config::MAIN_ANALYTICS_ENABLED, enabled);
  619. emit AnalyticsToggled(enabled);
  620. }
  621. bool Settings::IsAnalyticsEnabled() const
  622. {
  623. return Config::Get(Config::MAIN_ANALYTICS_ENABLED);
  624. }
  625. void Settings::SetToolBarVisible(bool visible)
  626. {
  627. if (IsToolBarVisible() == visible)
  628. return;
  629. GetQSettings().setValue(QStringLiteral("toolbar/visible"), visible);
  630. emit ToolBarVisibilityChanged(visible);
  631. }
  632. bool Settings::IsToolBarVisible() const
  633. {
  634. return GetQSettings().value(QStringLiteral("toolbar/visible"), true).toBool();
  635. }
  636. void Settings::SetWidgetsLocked(bool locked)
  637. {
  638. if (AreWidgetsLocked() == locked)
  639. return;
  640. GetQSettings().setValue(QStringLiteral("widgets/locked"), locked);
  641. emit WidgetLockChanged(locked);
  642. }
  643. bool Settings::AreWidgetsLocked() const
  644. {
  645. return GetQSettings().value(QStringLiteral("widgets/locked"), true).toBool();
  646. }
  647. bool Settings::IsBatchModeEnabled() const
  648. {
  649. return m_batch;
  650. }
  651. void Settings::SetBatchModeEnabled(bool batch)
  652. {
  653. m_batch = batch;
  654. }
  655. bool Settings::IsSDCardInserted() const
  656. {
  657. return Config::Get(Config::MAIN_WII_SD_CARD);
  658. }
  659. void Settings::SetSDCardInserted(bool inserted)
  660. {
  661. if (IsSDCardInserted() != inserted)
  662. {
  663. Config::SetBaseOrCurrent(Config::MAIN_WII_SD_CARD, inserted);
  664. emit SDCardInsertionChanged(inserted);
  665. }
  666. }
  667. bool Settings::IsUSBKeyboardConnected() const
  668. {
  669. return Config::Get(Config::MAIN_WII_KEYBOARD);
  670. }
  671. void Settings::SetUSBKeyboardConnected(bool connected)
  672. {
  673. if (IsUSBKeyboardConnected() != connected)
  674. {
  675. Config::SetBaseOrCurrent(Config::MAIN_WII_KEYBOARD, connected);
  676. emit USBKeyboardConnectionChanged(connected);
  677. }
  678. }
  679. void Settings::SetIsContinuouslyFrameStepping(bool is_stepping)
  680. {
  681. m_continuously_frame_stepping = is_stepping;
  682. }
  683. bool Settings::GetIsContinuouslyFrameStepping() const
  684. {
  685. return m_continuously_frame_stepping;
  686. }