Sync Changelog entries between branches
[qBittorrent.git] / src / base / preferences.cpp
blob7bbf961f46623c5ad6e2ec94ef7ef4d238a270ea
1 /*
2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2014 sledgehammer999 <hammered999@gmail.com>
4 * Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * In addition, as a special exception, the copyright holders give permission to
21 * link this program with the OpenSSL project's "OpenSSL" library (or with
22 * modified versions of it that use the same license as the "OpenSSL" library),
23 * and distribute the linked executables. You must obey the GNU General Public
24 * License in all respects for all of the code used other than "OpenSSL". If you
25 * modify file(s), you may extend this exception to your version of the file(s),
26 * but you are not obligated to do so. If you do not wish to do so, delete this
27 * exception statement from your version.
30 #include "preferences.h"
32 #include <chrono>
34 #ifdef Q_OS_MACOS
35 #include <CoreServices/CoreServices.h>
36 #endif
37 #ifdef Q_OS_WIN
38 #include <shlobj.h>
39 #endif
41 #include <QCoreApplication>
42 #include <QDateTime>
43 #include <QDir>
44 #include <QList>
45 #include <QLocale>
46 #include <QNetworkCookie>
47 #include <QSettings>
48 #include <QSize>
49 #include <QTime>
50 #include <QVariant>
52 #ifdef Q_OS_WIN
53 #include <QRegularExpression>
54 #endif
56 #include "algorithm.h"
57 #include "global.h"
58 #include "profile.h"
59 #include "settingsstorage.h"
60 #include "utils/fs.h"
62 namespace
64 #ifdef Q_OS_WIN
65 QString makeProfileID(const QString &profilePath, const QString &profileName)
67 return profilePath.isEmpty()
68 ? profileName
69 : profileName + QLatin1Char('@') + Utils::Fs::toValidFileSystemName(profilePath, false, {});
71 #endif
74 Preferences *Preferences::m_instance = nullptr;
76 Preferences::Preferences() = default;
78 Preferences *Preferences::instance()
80 return m_instance;
83 void Preferences::initInstance()
85 if (!m_instance)
86 m_instance = new Preferences;
89 void Preferences::freeInstance()
91 delete m_instance;
92 m_instance = nullptr;
95 QVariant Preferences::value(const QString &key, const QVariant &defaultValue) const
97 return SettingsStorage::instance()->loadValue(key, defaultValue);
100 void Preferences::setValue(const QString &key, const QVariant &value)
102 SettingsStorage::instance()->storeValue(key, value);
105 // General options
106 QString Preferences::getLocale() const
108 const QString localeName = value("Preferences/General/Locale").toString();
109 return (localeName.isEmpty() ? QLocale::system().name() : localeName);
112 void Preferences::setLocale(const QString &locale)
114 setValue("Preferences/General/Locale", locale);
117 bool Preferences::useCustomUITheme() const
119 return value("Preferences/General/UseCustomUITheme", false).toBool()
120 && !customUIThemePath().isEmpty();
123 void Preferences::setUseCustomUITheme(const bool use)
125 setValue("Preferences/General/UseCustomUITheme", use);
128 QString Preferences::customUIThemePath() const
130 return value("Preferences/General/CustomUIThemePath").toString();
133 void Preferences::setCustomUIThemePath(const QString &path)
135 setValue("Preferences/General/CustomUIThemePath", path);
138 bool Preferences::deleteTorrentFilesAsDefault() const
140 return value("Preferences/General/DeleteTorrentsFilesAsDefault", false).toBool();
143 void Preferences::setDeleteTorrentFilesAsDefault(const bool del)
145 setValue("Preferences/General/DeleteTorrentsFilesAsDefault", del);
148 bool Preferences::confirmOnExit() const
150 return value("Preferences/General/ExitConfirm", true).toBool();
153 void Preferences::setConfirmOnExit(const bool confirm)
155 setValue("Preferences/General/ExitConfirm", confirm);
158 bool Preferences::speedInTitleBar() const
160 return value("Preferences/General/SpeedInTitleBar", false).toBool();
163 void Preferences::showSpeedInTitleBar(const bool show)
165 setValue("Preferences/General/SpeedInTitleBar", show);
168 bool Preferences::useAlternatingRowColors() const
170 return value("Preferences/General/AlternatingRowColors", true).toBool();
173 void Preferences::setAlternatingRowColors(const bool b)
175 setValue("Preferences/General/AlternatingRowColors", b);
178 bool Preferences::getHideZeroValues() const
180 return value("Preferences/General/HideZeroValues", false).toBool();
183 void Preferences::setHideZeroValues(const bool b)
185 setValue("Preferences/General/HideZeroValues", b);
188 int Preferences::getHideZeroComboValues() const
190 return value("Preferences/General/HideZeroComboValues", 0).toInt();
193 void Preferences::setHideZeroComboValues(const int n)
195 setValue("Preferences/General/HideZeroComboValues", n);
198 // In Mac OS X the dock is sufficient for our needs so we disable the sys tray functionality.
199 // See extensive discussion in https://github.com/qbittorrent/qBittorrent/pull/3018
200 #ifndef Q_OS_MACOS
201 bool Preferences::systrayIntegration() const
203 return value("Preferences/General/SystrayEnabled", true).toBool();
206 void Preferences::setSystrayIntegration(const bool enabled)
208 setValue("Preferences/General/SystrayEnabled", enabled);
211 bool Preferences::minimizeToTray() const
213 return value("Preferences/General/MinimizeToTray", false).toBool();
216 void Preferences::setMinimizeToTray(const bool b)
218 setValue("Preferences/General/MinimizeToTray", b);
221 bool Preferences::minimizeToTrayNotified() const
223 return value("Preferences/General/MinimizeToTrayNotified", false).toBool();
226 void Preferences::setMinimizeToTrayNotified(const bool b)
228 setValue("Preferences/General/MinimizeToTrayNotified", b);
231 bool Preferences::closeToTray() const
233 return value("Preferences/General/CloseToTray", true).toBool();
236 void Preferences::setCloseToTray(const bool b)
238 setValue("Preferences/General/CloseToTray", b);
241 bool Preferences::closeToTrayNotified() const
243 return value("Preferences/General/CloseToTrayNotified", false).toBool();
246 void Preferences::setCloseToTrayNotified(const bool b)
248 setValue("Preferences/General/CloseToTrayNotified", b);
251 bool Preferences::iconsInMenusEnabled() const
253 return value("Preferences/Advanced/EnableIconsInMenus", true).toBool();
256 void Preferences::setIconsInMenusEnabled(const bool enable)
258 setValue("Preferences/Advanced/EnableIconsInMenus", enable);
260 #endif // Q_OS_MACOS
262 bool Preferences::isToolbarDisplayed() const
264 return value("Preferences/General/ToolbarDisplayed", true).toBool();
267 void Preferences::setToolbarDisplayed(const bool displayed)
269 setValue("Preferences/General/ToolbarDisplayed", displayed);
272 bool Preferences::isStatusbarDisplayed() const
274 return value("Preferences/General/StatusbarDisplayed", true).toBool();
277 void Preferences::setStatusbarDisplayed(const bool displayed)
279 setValue("Preferences/General/StatusbarDisplayed", displayed);
282 bool Preferences::startMinimized() const
284 return value("Preferences/General/StartMinimized", false).toBool();
287 void Preferences::setStartMinimized(const bool b)
289 setValue("Preferences/General/StartMinimized", b);
292 bool Preferences::isSplashScreenDisabled() const
294 return value("Preferences/General/NoSplashScreen", true).toBool();
297 void Preferences::setSplashScreenDisabled(const bool b)
299 setValue("Preferences/General/NoSplashScreen", b);
302 // Preventing from system suspend while active torrents are presented.
303 bool Preferences::preventFromSuspendWhenDownloading() const
305 return value("Preferences/General/PreventFromSuspendWhenDownloading", false).toBool();
308 void Preferences::setPreventFromSuspendWhenDownloading(const bool b)
310 setValue("Preferences/General/PreventFromSuspendWhenDownloading", b);
313 bool Preferences::preventFromSuspendWhenSeeding() const
315 return value("Preferences/General/PreventFromSuspendWhenSeeding", false).toBool();
318 void Preferences::setPreventFromSuspendWhenSeeding(const bool b)
320 setValue("Preferences/General/PreventFromSuspendWhenSeeding", b);
323 #ifdef Q_OS_WIN
324 bool Preferences::WinStartup() const
326 const QString profileName = Profile::instance()->profileName();
327 const QString profilePath = Profile::instance()->rootPath();
328 const QString profileID = makeProfileID(profilePath, profileName);
329 const QSettings settings {"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat};
331 return settings.contains(profileID);
334 void Preferences::setWinStartup(const bool b)
336 const QString profileName = Profile::instance()->profileName();
337 const QString profilePath = Profile::instance()->rootPath();
338 const QString profileID = makeProfileID(profilePath, profileName);
339 QSettings settings {"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat};
340 if (b)
342 const QString configuration = Profile::instance()->configurationName();
344 const auto cmd = QString::fromLatin1(R"("%1" "--profile=%2" "--configuration=%3")")
345 .arg(Utils::Fs::toNativePath(qApp->applicationFilePath()), profilePath, configuration);
346 settings.setValue(profileID, cmd);
348 else
350 settings.remove(profileID);
353 #endif // Q_OS_WIN
355 // Downloads
356 QString Preferences::lastLocationPath() const
358 return Utils::Fs::toUniformPath(value("Preferences/Downloads/LastLocationPath").toString());
361 void Preferences::setLastLocationPath(const QString &path)
363 setValue("Preferences/Downloads/LastLocationPath", Utils::Fs::toUniformPath(path));
366 QString Preferences::getScanDirsLastPath() const
368 return Utils::Fs::toUniformPath(value("Preferences/Downloads/ScanDirsLastPath").toString());
371 void Preferences::setScanDirsLastPath(const QString &path)
373 setValue("Preferences/Downloads/ScanDirsLastPath", Utils::Fs::toUniformPath(path));
376 bool Preferences::isMailNotificationEnabled() const
378 return value("Preferences/MailNotification/enabled", false).toBool();
381 void Preferences::setMailNotificationEnabled(const bool enabled)
383 setValue("Preferences/MailNotification/enabled", enabled);
386 QString Preferences::getMailNotificationSender() const
388 return value("Preferences/MailNotification/sender", "qBittorrent_notification@example.com").toString();
391 void Preferences::setMailNotificationSender(const QString &mail)
393 setValue("Preferences/MailNotification/sender", mail);
396 QString Preferences::getMailNotificationEmail() const
398 return value("Preferences/MailNotification/email").toString();
401 void Preferences::setMailNotificationEmail(const QString &mail)
403 setValue("Preferences/MailNotification/email", mail);
406 QString Preferences::getMailNotificationSMTP() const
408 return value("Preferences/MailNotification/smtp_server", "smtp.changeme.com").toString();
411 void Preferences::setMailNotificationSMTP(const QString &smtp_server)
413 setValue("Preferences/MailNotification/smtp_server", smtp_server);
416 bool Preferences::getMailNotificationSMTPSSL() const
418 return value("Preferences/MailNotification/req_ssl", false).toBool();
421 void Preferences::setMailNotificationSMTPSSL(const bool use)
423 setValue("Preferences/MailNotification/req_ssl", use);
426 bool Preferences::getMailNotificationSMTPAuth() const
428 return value("Preferences/MailNotification/req_auth", false).toBool();
431 void Preferences::setMailNotificationSMTPAuth(const bool use)
433 setValue("Preferences/MailNotification/req_auth", use);
436 QString Preferences::getMailNotificationSMTPUsername() const
438 return value("Preferences/MailNotification/username").toString();
441 void Preferences::setMailNotificationSMTPUsername(const QString &username)
443 setValue("Preferences/MailNotification/username", username);
446 QString Preferences::getMailNotificationSMTPPassword() const
448 return value("Preferences/MailNotification/password").toString();
451 void Preferences::setMailNotificationSMTPPassword(const QString &password)
453 setValue("Preferences/MailNotification/password", password);
456 int Preferences::getActionOnDblClOnTorrentDl() const
458 return value("Preferences/Downloads/DblClOnTorDl", 0).toInt();
461 void Preferences::setActionOnDblClOnTorrentDl(const int act)
463 setValue("Preferences/Downloads/DblClOnTorDl", act);
466 int Preferences::getActionOnDblClOnTorrentFn() const
468 return value("Preferences/Downloads/DblClOnTorFn", 1).toInt();
471 void Preferences::setActionOnDblClOnTorrentFn(const int act)
473 setValue("Preferences/Downloads/DblClOnTorFn", act);
476 QTime Preferences::getSchedulerStartTime() const
478 return value("Preferences/Scheduler/start_time", QTime(8,0)).toTime();
481 void Preferences::setSchedulerStartTime(const QTime &time)
483 setValue("Preferences/Scheduler/start_time", time);
486 QTime Preferences::getSchedulerEndTime() const
488 return value("Preferences/Scheduler/end_time", QTime(20,0)).toTime();
491 void Preferences::setSchedulerEndTime(const QTime &time)
493 setValue("Preferences/Scheduler/end_time", time);
496 SchedulerDays Preferences::getSchedulerDays() const
498 return static_cast<SchedulerDays>(value("Preferences/Scheduler/days", EVERY_DAY).toInt());
501 void Preferences::setSchedulerDays(const SchedulerDays days)
503 setValue("Preferences/Scheduler/days", static_cast<int>(days));
506 // Search
507 bool Preferences::isSearchEnabled() const
509 return value("Preferences/Search/SearchEnabled", false).toBool();
512 void Preferences::setSearchEnabled(const bool enabled)
514 setValue("Preferences/Search/SearchEnabled", enabled);
517 bool Preferences::isWebUiEnabled() const
519 #ifdef DISABLE_GUI
520 return true;
521 #else
522 return value("Preferences/WebUI/Enabled", false).toBool();
523 #endif
526 void Preferences::setWebUiEnabled(const bool enabled)
528 setValue("Preferences/WebUI/Enabled", enabled);
531 bool Preferences::isWebUiLocalAuthEnabled() const
533 return value("Preferences/WebUI/LocalHostAuth", true).toBool();
536 void Preferences::setWebUiLocalAuthEnabled(const bool enabled)
538 setValue("Preferences/WebUI/LocalHostAuth", enabled);
541 bool Preferences::isWebUiAuthSubnetWhitelistEnabled() const
543 return value("Preferences/WebUI/AuthSubnetWhitelistEnabled", false).toBool();
546 void Preferences::setWebUiAuthSubnetWhitelistEnabled(const bool enabled)
548 setValue("Preferences/WebUI/AuthSubnetWhitelistEnabled", enabled);
551 QVector<Utils::Net::Subnet> Preferences::getWebUiAuthSubnetWhitelist() const
553 const QStringList subnets = value("Preferences/WebUI/AuthSubnetWhitelist").toStringList();
555 QVector<Utils::Net::Subnet> ret;
556 ret.reserve(subnets.size());
558 for (const QString &rawSubnet : subnets)
560 bool ok = false;
561 const Utils::Net::Subnet subnet = Utils::Net::parseSubnet(rawSubnet.trimmed(), &ok);
562 if (ok)
563 ret.append(subnet);
566 return ret;
569 void Preferences::setWebUiAuthSubnetWhitelist(QStringList subnets)
571 Algorithm::removeIf(subnets, [](const QString &subnet)
573 bool ok = false;
574 Utils::Net::parseSubnet(subnet.trimmed(), &ok);
575 return !ok;
578 setValue("Preferences/WebUI/AuthSubnetWhitelist", subnets);
581 QString Preferences::getServerDomains() const
583 return value("Preferences/WebUI/ServerDomains", QChar('*')).toString();
586 void Preferences::setServerDomains(const QString &str)
588 setValue("Preferences/WebUI/ServerDomains", str);
591 QString Preferences::getWebUiAddress() const
593 return value("Preferences/WebUI/Address", QChar('*')).toString().trimmed();
596 void Preferences::setWebUiAddress(const QString &addr)
598 setValue("Preferences/WebUI/Address", addr.trimmed());
601 quint16 Preferences::getWebUiPort() const
603 return value("Preferences/WebUI/Port", 8080).toInt();
606 void Preferences::setWebUiPort(const quint16 port)
608 setValue("Preferences/WebUI/Port", port);
611 bool Preferences::useUPnPForWebUIPort() const
613 #ifdef DISABLE_GUI
614 return value("Preferences/WebUI/UseUPnP", true).toBool();
615 #else
616 return value("Preferences/WebUI/UseUPnP", false).toBool();
617 #endif
620 void Preferences::setUPnPForWebUIPort(const bool enabled)
622 setValue("Preferences/WebUI/UseUPnP", enabled);
625 QString Preferences::getWebUiUsername() const
627 return value("Preferences/WebUI/Username", "admin").toString();
630 void Preferences::setWebUiUsername(const QString &username)
632 setValue("Preferences/WebUI/Username", username);
635 QByteArray Preferences::getWebUIPassword() const
637 // default: adminadmin
638 const QByteArray defaultValue = "ARQ77eY1NUZaQsuDHbIMCA==:0WMRkYTUWVT9wVvdDtHAjU9b3b7uB8NR1Gur2hmQCvCDpm39Q+PsJRJPaCU51dEiz+dTzh8qbPsL8WkFljQYFQ==";
639 return value("Preferences/WebUI/Password_PBKDF2", defaultValue).toByteArray();
642 void Preferences::setWebUIPassword(const QByteArray &password)
644 setValue("Preferences/WebUI/Password_PBKDF2", password);
647 int Preferences::getWebUIMaxAuthFailCount() const
649 return value("Preferences/WebUI/MaxAuthenticationFailCount", 5).toInt();
652 void Preferences::setWebUIMaxAuthFailCount(const int count)
654 setValue("Preferences/WebUI/MaxAuthenticationFailCount", count);
657 std::chrono::seconds Preferences::getWebUIBanDuration() const
659 return std::chrono::seconds {value("Preferences/WebUI/BanDuration", 3600).toInt()};
662 void Preferences::setWebUIBanDuration(const std::chrono::seconds duration)
664 setValue("Preferences/WebUI/BanDuration", static_cast<int>(duration.count()));
667 int Preferences::getWebUISessionTimeout() const
669 return value("Preferences/WebUI/SessionTimeout", 3600).toInt();
672 void Preferences::setWebUISessionTimeout(const int timeout)
674 setValue("Preferences/WebUI/SessionTimeout", timeout);
677 bool Preferences::isWebUiClickjackingProtectionEnabled() const
679 return value("Preferences/WebUI/ClickjackingProtection", true).toBool();
682 void Preferences::setWebUiClickjackingProtectionEnabled(const bool enabled)
684 setValue("Preferences/WebUI/ClickjackingProtection", enabled);
687 bool Preferences::isWebUiCSRFProtectionEnabled() const
689 return value("Preferences/WebUI/CSRFProtection", true).toBool();
692 void Preferences::setWebUiCSRFProtectionEnabled(const bool enabled)
694 setValue("Preferences/WebUI/CSRFProtection", enabled);
697 bool Preferences::isWebUiSecureCookieEnabled() const
699 return value("Preferences/WebUI/SecureCookie", true).toBool();
702 void Preferences::setWebUiSecureCookieEnabled(const bool enabled)
704 setValue("Preferences/WebUI/SecureCookie", enabled);
707 bool Preferences::isWebUIHostHeaderValidationEnabled() const
709 return value("Preferences/WebUI/HostHeaderValidation", true).toBool();
712 void Preferences::setWebUIHostHeaderValidationEnabled(const bool enabled)
714 setValue("Preferences/WebUI/HostHeaderValidation", enabled);
717 bool Preferences::isWebUiHttpsEnabled() const
719 return value("Preferences/WebUI/HTTPS/Enabled", false).toBool();
722 void Preferences::setWebUiHttpsEnabled(const bool enabled)
724 setValue("Preferences/WebUI/HTTPS/Enabled", enabled);
727 QString Preferences::getWebUIHttpsCertificatePath() const
729 return value("Preferences/WebUI/HTTPS/CertificatePath").toString();
732 void Preferences::setWebUIHttpsCertificatePath(const QString &path)
734 setValue("Preferences/WebUI/HTTPS/CertificatePath", path);
737 QString Preferences::getWebUIHttpsKeyPath() const
739 return value("Preferences/WebUI/HTTPS/KeyPath").toString();
742 void Preferences::setWebUIHttpsKeyPath(const QString &path)
744 setValue("Preferences/WebUI/HTTPS/KeyPath", path);
747 bool Preferences::isAltWebUiEnabled() const
749 return value("Preferences/WebUI/AlternativeUIEnabled", false).toBool();
752 void Preferences::setAltWebUiEnabled(const bool enabled)
754 setValue("Preferences/WebUI/AlternativeUIEnabled", enabled);
757 QString Preferences::getWebUiRootFolder() const
759 return value("Preferences/WebUI/RootFolder").toString();
762 void Preferences::setWebUiRootFolder(const QString &path)
764 setValue("Preferences/WebUI/RootFolder", path);
767 bool Preferences::isWebUICustomHTTPHeadersEnabled() const
769 return value("Preferences/WebUI/CustomHTTPHeadersEnabled", false).toBool();
772 void Preferences::setWebUICustomHTTPHeadersEnabled(const bool enabled)
774 setValue("Preferences/WebUI/CustomHTTPHeadersEnabled", enabled);
777 QString Preferences::getWebUICustomHTTPHeaders() const
779 return value("Preferences/WebUI/CustomHTTPHeaders").toString();
782 void Preferences::setWebUICustomHTTPHeaders(const QString &headers)
784 setValue("Preferences/WebUI/CustomHTTPHeaders", headers);
787 bool Preferences::isWebUIReverseProxySupportEnabled() const
789 return value("Preferences/WebUI/ReverseProxySupportEnabled", false).toBool();
792 void Preferences::setWebUIReverseProxySupportEnabled(const bool enabled)
794 setValue("Preferences/WebUI/ReverseProxySupportEnabled", enabled);
797 QString Preferences::getWebUITrustedReverseProxiesList() const
799 return value("Preferences/WebUI/TrustedReverseProxiesList").toString();
802 void Preferences::setWebUITrustedReverseProxiesList(const QString &addr)
804 setValue("Preferences/WebUI/TrustedReverseProxiesList", addr);
807 bool Preferences::isDynDNSEnabled() const
809 return value("Preferences/DynDNS/Enabled", false).toBool();
812 void Preferences::setDynDNSEnabled(const bool enabled)
814 setValue("Preferences/DynDNS/Enabled", enabled);
817 DNS::Service Preferences::getDynDNSService() const
819 return DNS::Service(value("Preferences/DynDNS/Service", DNS::DYNDNS).toInt());
822 void Preferences::setDynDNSService(const int service)
824 setValue("Preferences/DynDNS/Service", service);
827 QString Preferences::getDynDomainName() const
829 return value("Preferences/DynDNS/DomainName", "changeme.dyndns.org").toString();
832 void Preferences::setDynDomainName(const QString &name)
834 setValue("Preferences/DynDNS/DomainName", name);
837 QString Preferences::getDynDNSUsername() const
839 return value("Preferences/DynDNS/Username").toString();
842 void Preferences::setDynDNSUsername(const QString &username)
844 setValue("Preferences/DynDNS/Username", username);
847 QString Preferences::getDynDNSPassword() const
849 return value("Preferences/DynDNS/Password").toString();
852 void Preferences::setDynDNSPassword(const QString &password)
854 setValue("Preferences/DynDNS/Password", password);
857 // Advanced settings
858 QByteArray Preferences::getUILockPassword() const
860 return value("Locking/password_PBKDF2").toByteArray();
863 void Preferences::setUILockPassword(const QByteArray &password)
865 setValue("Locking/password_PBKDF2", password);
868 bool Preferences::isUILocked() const
870 return value("Locking/locked", false).toBool();
873 void Preferences::setUILocked(const bool locked)
875 setValue("Locking/locked", locked);
878 bool Preferences::isAutoRunEnabled() const
880 return value("AutoRun/enabled", false).toBool();
883 void Preferences::setAutoRunEnabled(const bool enabled)
885 setValue("AutoRun/enabled", enabled);
888 QString Preferences::getAutoRunProgram() const
890 return value("AutoRun/program").toString();
893 void Preferences::setAutoRunProgram(const QString &program)
895 setValue("AutoRun/program", program);
898 #if defined(Q_OS_WIN)
899 bool Preferences::isAutoRunConsoleEnabled() const
901 return value("AutoRun/ConsoleEnabled", false).toBool();
904 void Preferences::setAutoRunConsoleEnabled(const bool enabled)
906 setValue("AutoRun/ConsoleEnabled", enabled);
908 #endif
910 bool Preferences::shutdownWhenDownloadsComplete() const
912 return value("Preferences/Downloads/AutoShutDownOnCompletion", false).toBool();
915 void Preferences::setShutdownWhenDownloadsComplete(const bool shutdown)
917 setValue("Preferences/Downloads/AutoShutDownOnCompletion", shutdown);
920 bool Preferences::suspendWhenDownloadsComplete() const
922 return value("Preferences/Downloads/AutoSuspendOnCompletion", false).toBool();
925 void Preferences::setSuspendWhenDownloadsComplete(const bool suspend)
927 setValue("Preferences/Downloads/AutoSuspendOnCompletion", suspend);
930 bool Preferences::hibernateWhenDownloadsComplete() const
932 return value("Preferences/Downloads/AutoHibernateOnCompletion", false).toBool();
935 void Preferences::setHibernateWhenDownloadsComplete(const bool hibernate)
937 setValue("Preferences/Downloads/AutoHibernateOnCompletion", hibernate);
940 bool Preferences::shutdownqBTWhenDownloadsComplete() const
942 return value("Preferences/Downloads/AutoShutDownqBTOnCompletion", false).toBool();
945 void Preferences::setShutdownqBTWhenDownloadsComplete(const bool shutdown)
947 setValue("Preferences/Downloads/AutoShutDownqBTOnCompletion", shutdown);
950 bool Preferences::dontConfirmAutoExit() const
952 return value("ShutdownConfirmDlg/DontConfirmAutoExit", false).toBool();
955 void Preferences::setDontConfirmAutoExit(const bool dontConfirmAutoExit)
957 setValue("ShutdownConfirmDlg/DontConfirmAutoExit", dontConfirmAutoExit);
960 bool Preferences::recheckTorrentsOnCompletion() const
962 return value("Preferences/Advanced/RecheckOnCompletion", false).toBool();
965 void Preferences::recheckTorrentsOnCompletion(const bool recheck)
967 setValue("Preferences/Advanced/RecheckOnCompletion", recheck);
970 bool Preferences::resolvePeerCountries() const
972 return value("Preferences/Connection/ResolvePeerCountries", true).toBool();
975 void Preferences::resolvePeerCountries(const bool resolve)
977 setValue("Preferences/Connection/ResolvePeerCountries", resolve);
980 bool Preferences::resolvePeerHostNames() const
982 return value("Preferences/Connection/ResolvePeerHostNames", false).toBool();
985 void Preferences::resolvePeerHostNames(const bool resolve)
987 setValue("Preferences/Connection/ResolvePeerHostNames", resolve);
990 #if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
991 bool Preferences::useSystemIconTheme() const
993 return value("Preferences/Advanced/useSystemIconTheme", true).toBool();
996 void Preferences::useSystemIconTheme(const bool enabled)
998 setValue("Preferences/Advanced/useSystemIconTheme", enabled);
1000 #endif
1002 bool Preferences::recursiveDownloadDisabled() const
1004 return value("Preferences/Advanced/DisableRecursiveDownload", false).toBool();
1007 void Preferences::disableRecursiveDownload(const bool disable)
1009 setValue("Preferences/Advanced/DisableRecursiveDownload", disable);
1012 #ifdef Q_OS_WIN
1013 bool Preferences::neverCheckFileAssoc() const
1015 return value("Preferences/Win32/NeverCheckFileAssocation", false).toBool();
1018 void Preferences::setNeverCheckFileAssoc(const bool check)
1020 setValue("Preferences/Win32/NeverCheckFileAssocation", check);
1023 bool Preferences::isTorrentFileAssocSet()
1025 const QSettings settings("HKEY_CURRENT_USER\\Software\\Classes", QSettings::NativeFormat);
1026 if (settings.value(".torrent/Default").toString() != "qBittorrent")
1028 qDebug(".torrent != qBittorrent");
1029 return false;
1032 return true;
1035 bool Preferences::isMagnetLinkAssocSet()
1037 const QSettings settings("HKEY_CURRENT_USER\\Software\\Classes", QSettings::NativeFormat);
1039 // Check magnet link assoc
1040 const QString shellCommand = Utils::Fs::toNativePath(settings.value("magnet/shell/open/command/Default", "").toString());
1042 const QRegularExpressionMatch exeRegMatch = QRegularExpression("\"([^\"]+)\".*").match(shellCommand);
1043 if (!exeRegMatch.hasMatch())
1044 return false;
1046 const QString assocExe = exeRegMatch.captured(1);
1047 if (assocExe.compare(Utils::Fs::toNativePath(qApp->applicationFilePath()), Qt::CaseInsensitive) != 0)
1048 return false;
1050 return true;
1053 void Preferences::setTorrentFileAssoc(const bool set)
1055 QSettings settings("HKEY_CURRENT_USER\\Software\\Classes", QSettings::NativeFormat);
1057 // .Torrent association
1058 if (set)
1060 const QString oldProgId = settings.value(".torrent/Default").toString();
1061 if (!oldProgId.isEmpty() && (oldProgId != "qBittorrent"))
1062 settings.setValue(".torrent/OpenWithProgids/" + oldProgId, "");
1063 settings.setValue(".torrent/Default", "qBittorrent");
1065 else if (isTorrentFileAssocSet())
1067 settings.setValue(".torrent/Default", "");
1070 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
1073 void Preferences::setMagnetLinkAssoc(const bool set)
1075 QSettings settings("HKEY_CURRENT_USER\\Software\\Classes", QSettings::NativeFormat);
1077 // Magnet association
1078 if (set)
1080 const QString commandStr = '"' + qApp->applicationFilePath() + "\" \"%1\"";
1081 const QString iconStr = '"' + qApp->applicationFilePath() + "\",1";
1083 settings.setValue("magnet/Default", "URL:Magnet link");
1084 settings.setValue("magnet/Content Type", "application/x-magnet");
1085 settings.setValue("magnet/URL Protocol", "");
1086 settings.setValue("magnet/DefaultIcon/Default", Utils::Fs::toNativePath(iconStr));
1087 settings.setValue("magnet/shell/Default", "open");
1088 settings.setValue("magnet/shell/open/command/Default", Utils::Fs::toNativePath(commandStr));
1090 else if (isMagnetLinkAssocSet())
1092 settings.remove("magnet");
1095 SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
1097 #endif // Q_OS_WIN
1099 #ifdef Q_OS_MACOS
1100 namespace
1102 const CFStringRef torrentExtension = CFSTR("torrent");
1103 const CFStringRef magnetUrlScheme = CFSTR("magnet");
1106 bool Preferences::isTorrentFileAssocSet()
1108 bool isSet = false;
1109 const CFStringRef torrentId = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, torrentExtension, NULL);
1110 if (torrentId != NULL)
1112 const CFStringRef defaultHandlerId = LSCopyDefaultRoleHandlerForContentType(torrentId, kLSRolesViewer);
1113 if (defaultHandlerId != NULL)
1115 const CFStringRef myBundleId = CFBundleGetIdentifier(CFBundleGetMainBundle());
1116 isSet = CFStringCompare(myBundleId, defaultHandlerId, 0) == kCFCompareEqualTo;
1117 CFRelease(defaultHandlerId);
1119 CFRelease(torrentId);
1121 return isSet;
1124 bool Preferences::isMagnetLinkAssocSet()
1126 bool isSet = false;
1127 const CFStringRef defaultHandlerId = LSCopyDefaultHandlerForURLScheme(magnetUrlScheme);
1128 if (defaultHandlerId != NULL)
1130 const CFStringRef myBundleId = CFBundleGetIdentifier(CFBundleGetMainBundle());
1131 isSet = CFStringCompare(myBundleId, defaultHandlerId, 0) == kCFCompareEqualTo;
1132 CFRelease(defaultHandlerId);
1134 return isSet;
1137 void Preferences::setTorrentFileAssoc()
1139 if (isTorrentFileAssocSet())
1140 return;
1141 const CFStringRef torrentId = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, torrentExtension, NULL);
1142 if (torrentId != NULL)
1144 const CFStringRef myBundleId = CFBundleGetIdentifier(CFBundleGetMainBundle());
1145 LSSetDefaultRoleHandlerForContentType(torrentId, kLSRolesViewer, myBundleId);
1146 CFRelease(torrentId);
1150 void Preferences::setMagnetLinkAssoc()
1152 if (isMagnetLinkAssocSet())
1153 return;
1154 const CFStringRef myBundleId = CFBundleGetIdentifier(CFBundleGetMainBundle());
1155 LSSetDefaultHandlerForURLScheme(magnetUrlScheme, myBundleId);
1157 #endif // Q_OS_MACOS
1159 int Preferences::getTrackerPort() const
1161 return value("Preferences/Advanced/trackerPort", 9000).toInt();
1164 void Preferences::setTrackerPort(const int port)
1166 setValue("Preferences/Advanced/trackerPort", port);
1169 #if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
1170 bool Preferences::isUpdateCheckEnabled() const
1172 return value("Preferences/Advanced/updateCheck", true).toBool();
1175 void Preferences::setUpdateCheckEnabled(const bool enabled)
1177 setValue("Preferences/Advanced/updateCheck", enabled);
1179 #endif
1181 bool Preferences::confirmTorrentDeletion() const
1183 return value("Preferences/Advanced/confirmTorrentDeletion", true).toBool();
1186 void Preferences::setConfirmTorrentDeletion(const bool enabled)
1188 setValue("Preferences/Advanced/confirmTorrentDeletion", enabled);
1191 bool Preferences::confirmTorrentRecheck() const
1193 return value("Preferences/Advanced/confirmTorrentRecheck", true).toBool();
1196 void Preferences::setConfirmTorrentRecheck(const bool enabled)
1198 setValue("Preferences/Advanced/confirmTorrentRecheck", enabled);
1201 bool Preferences::confirmRemoveAllTags() const
1203 return value("Preferences/Advanced/confirmRemoveAllTags", true).toBool();
1206 void Preferences::setConfirmRemoveAllTags(const bool enabled)
1208 setValue("Preferences/Advanced/confirmRemoveAllTags", enabled);
1211 #ifndef Q_OS_MACOS
1212 TrayIcon::Style Preferences::trayIconStyle() const
1214 return TrayIcon::Style(value("Preferences/Advanced/TrayIconStyle", TrayIcon::NORMAL).toInt());
1217 void Preferences::setTrayIconStyle(const TrayIcon::Style style)
1219 setValue("Preferences/Advanced/TrayIconStyle", style);
1221 #endif
1223 // Stuff that don't appear in the Options GUI but are saved
1224 // in the same file.
1226 QDateTime Preferences::getDNSLastUpd() const
1228 return value("DNSUpdater/lastUpdateTime").toDateTime();
1231 void Preferences::setDNSLastUpd(const QDateTime &date)
1233 setValue("DNSUpdater/lastUpdateTime", date);
1236 QString Preferences::getDNSLastIP() const
1238 return value("DNSUpdater/lastIP").toString();
1241 void Preferences::setDNSLastIP(const QString &ip)
1243 setValue("DNSUpdater/lastIP", ip);
1246 bool Preferences::getAcceptedLegal() const
1248 return value("LegalNotice/Accepted", false).toBool();
1251 void Preferences::setAcceptedLegal(const bool accepted)
1253 setValue("LegalNotice/Accepted", accepted);
1256 QByteArray Preferences::getMainGeometry() const
1258 return value("MainWindow/geometry").toByteArray();
1261 void Preferences::setMainGeometry(const QByteArray &geometry)
1263 setValue("MainWindow/geometry", geometry);
1266 QByteArray Preferences::getMainVSplitterState() const
1268 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1269 return value("GUI/Qt6/MainWindow/VSplitterState").toByteArray();
1270 #else
1271 return value("MainWindow/qt5/vsplitterState").toByteArray();
1272 #endif
1275 void Preferences::setMainVSplitterState(const QByteArray &state)
1277 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1278 setValue("GUI/Qt6/MainWindow/VSplitterState", state);
1279 #else
1280 setValue("MainWindow/qt5/vsplitterState", state);
1281 #endif
1284 QString Preferences::getMainLastDir() const
1286 return value("MainWindowLastDir", QDir::homePath()).toString();
1289 void Preferences::setMainLastDir(const QString &path)
1291 setValue("MainWindowLastDir", path);
1294 QByteArray Preferences::getPeerListState() const
1296 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1297 return value("GUI/Qt6/TorrentProperties/PeerListState").toByteArray();
1298 #else
1299 return value("TorrentProperties/Peers/qt5/PeerListState").toByteArray();
1300 #endif
1303 void Preferences::setPeerListState(const QByteArray &state)
1305 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1306 setValue("GUI/Qt6/TorrentProperties/PeerListState", state);
1307 #else
1308 setValue("TorrentProperties/Peers/qt5/PeerListState", state);
1309 #endif
1312 QString Preferences::getPropSplitterSizes() const
1314 return value("TorrentProperties/SplitterSizes").toString();
1317 void Preferences::setPropSplitterSizes(const QString &sizes)
1319 setValue("TorrentProperties/SplitterSizes", sizes);
1322 QByteArray Preferences::getPropFileListState() const
1324 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1325 return value("GUI/Qt6/TorrentProperties/FilesListState").toByteArray();
1326 #else
1327 return value("TorrentProperties/qt5/FilesListState").toByteArray();
1328 #endif
1331 void Preferences::setPropFileListState(const QByteArray &state)
1333 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1334 setValue("GUI/Qt6/TorrentProperties/FilesListState", state);
1335 #else
1336 setValue("TorrentProperties/qt5/FilesListState", state);
1337 #endif
1340 int Preferences::getPropCurTab() const
1342 return value("TorrentProperties/CurrentTab", -1).toInt();
1345 void Preferences::setPropCurTab(const int tab)
1347 setValue("TorrentProperties/CurrentTab", tab);
1350 bool Preferences::getPropVisible() const
1352 return value("TorrentProperties/Visible", false).toBool();
1355 void Preferences::setPropVisible(const bool visible)
1357 setValue("TorrentProperties/Visible", visible);
1360 QByteArray Preferences::getPropTrackerListState() const
1362 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1363 return value("GUI/Qt6/TorrentProperties/TrackerListState").toByteArray();
1364 #else
1365 return value("TorrentProperties/Trackers/qt5/TrackerListState").toByteArray();
1366 #endif
1369 void Preferences::setPropTrackerListState(const QByteArray &state)
1371 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1372 setValue("GUI/Qt6/TorrentProperties/TrackerListState", state);
1373 #else
1374 setValue("TorrentProperties/Trackers/qt5/TrackerListState", state);
1375 #endif
1378 QSize Preferences::getRssGeometrySize() const
1380 return value("RssFeedDownloader/geometrySize").toSize();
1383 void Preferences::setRssGeometrySize(const QSize &geometry)
1385 setValue("RssFeedDownloader/geometrySize", geometry);
1388 QByteArray Preferences::getRssHSplitterSizes() const
1390 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1391 return value("GUI/Qt6/RSSFeedDownloader/HSplitterSizes").toByteArray();
1392 #else
1393 return value("RssFeedDownloader/qt5/hsplitterSizes").toByteArray();
1394 #endif
1397 void Preferences::setRssHSplitterSizes(const QByteArray &sizes)
1399 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1400 setValue("GUI/Qt6/RSSFeedDownloader/HSplitterSizes", sizes);
1401 #else
1402 setValue("RssFeedDownloader/qt5/hsplitterSizes", sizes);
1403 #endif
1406 QStringList Preferences::getRssOpenFolders() const
1408 return value("GUI/RSSWidget/OpenedFolders").toStringList();
1411 void Preferences::setRssOpenFolders(const QStringList &folders)
1413 setValue("GUI/RSSWidget/OpenedFolders", folders);
1416 QByteArray Preferences::getRssSideSplitterState() const
1418 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1419 return value("GUI/Qt6/RSSWidget/SideSplitterState").toByteArray();
1420 #else
1421 return value("GUI/RSSWidget/qt5/splitter_h").toByteArray();
1422 #endif
1425 void Preferences::setRssSideSplitterState(const QByteArray &state)
1427 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1428 setValue("GUI/Qt6/RSSWidget/SideSplitterState", state);
1429 #else
1430 setValue("GUI/RSSWidget/qt5/splitter_h", state);
1431 #endif
1434 QByteArray Preferences::getRssMainSplitterState() const
1436 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1437 return value("GUI/Qt6/RSSWidget/MainSplitterState").toByteArray();
1438 #else
1439 return value("GUI/RSSWidget/qt5/splitterMain").toByteArray();
1440 #endif
1443 void Preferences::setRssMainSplitterState(const QByteArray &state)
1445 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1446 setValue("GUI/Qt6/RSSWidget/MainSplitterState", state);
1447 #else
1448 setValue("GUI/RSSWidget/qt5/splitterMain", state);
1449 #endif
1452 QByteArray Preferences::getSearchTabHeaderState() const
1454 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1455 return value("GUI/Qt6/SearchTab/HeaderState").toByteArray();
1456 #else
1457 return value("SearchTab/qt5/HeaderState").toByteArray();
1458 #endif
1461 void Preferences::setSearchTabHeaderState(const QByteArray &state)
1463 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1464 setValue("GUI/Qt6/SearchTab/HeaderState", state);
1465 #else
1466 setValue("SearchTab/qt5/HeaderState", state);
1467 #endif
1470 bool Preferences::getRegexAsFilteringPatternForSearchJob() const
1472 return value("SearchTab/UseRegexAsFilteringPattern", false).toBool();
1475 void Preferences::setRegexAsFilteringPatternForSearchJob(const bool checked)
1477 setValue("SearchTab/UseRegexAsFilteringPattern", checked);
1480 QStringList Preferences::getSearchEngDisabled() const
1482 return value("SearchEngines/disabledEngines").toStringList();
1485 void Preferences::setSearchEngDisabled(const QStringList &engines)
1487 setValue("SearchEngines/disabledEngines", engines);
1490 QString Preferences::getTorImportLastContentDir() const
1492 return value("TorrentImport/LastContentDir", QDir::homePath()).toString();
1495 void Preferences::setTorImportLastContentDir(const QString &path)
1497 setValue("TorrentImport/LastContentDir", path);
1500 QByteArray Preferences::getTorImportGeometry() const
1502 return value("TorrentImportDlg/dimensions").toByteArray();
1505 void Preferences::setTorImportGeometry(const QByteArray &geometry)
1507 setValue("TorrentImportDlg/dimensions", geometry);
1510 bool Preferences::getStatusFilterState() const
1512 return value("TransferListFilters/statusFilterState", true).toBool();
1515 void Preferences::setStatusFilterState(const bool checked)
1517 setValue("TransferListFilters/statusFilterState", checked);
1520 bool Preferences::getCategoryFilterState() const
1522 return value("TransferListFilters/CategoryFilterState", true).toBool();
1525 void Preferences::setCategoryFilterState(const bool checked)
1527 setValue("TransferListFilters/CategoryFilterState", checked);
1530 bool Preferences::getTagFilterState() const
1532 return value("TransferListFilters/TagFilterState", true).toBool();
1535 void Preferences::setTagFilterState(const bool checked)
1537 setValue("TransferListFilters/TagFilterState", checked);
1540 bool Preferences::getTrackerFilterState() const
1542 return value("TransferListFilters/trackerFilterState", true).toBool();
1545 void Preferences::setTrackerFilterState(const bool checked)
1547 setValue("TransferListFilters/trackerFilterState", checked);
1550 int Preferences::getTransSelFilter() const
1552 return value("TransferListFilters/selectedFilterIndex", 0).toInt();
1555 void Preferences::setTransSelFilter(const int index)
1557 setValue("TransferListFilters/selectedFilterIndex", index);
1560 QByteArray Preferences::getTransHeaderState() const
1562 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1563 return value("GUI/Qt6/TransferList/HeaderState").toByteArray();
1564 #else
1565 return value("TransferList/qt5/HeaderState").toByteArray();
1566 #endif
1569 void Preferences::setTransHeaderState(const QByteArray &state)
1571 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
1572 setValue("GUI/Qt6/TransferList/HeaderState", state);
1573 #else
1574 setValue("TransferList/qt5/HeaderState", state);
1575 #endif
1578 bool Preferences::getRegexAsFilteringPatternForTransferList() const
1580 return value("TransferList/UseRegexAsFilteringPattern", false).toBool();
1583 void Preferences::setRegexAsFilteringPatternForTransferList(const bool checked)
1585 setValue("TransferList/UseRegexAsFilteringPattern", checked);
1588 // From old RssSettings class
1589 bool Preferences::isRSSWidgetEnabled() const
1591 return value("GUI/RSSWidget/Enabled", false).toBool();
1594 void Preferences::setRSSWidgetVisible(const bool enabled)
1596 setValue("GUI/RSSWidget/Enabled", enabled);
1599 int Preferences::getToolbarTextPosition() const
1601 return value("Toolbar/textPosition", -1).toInt();
1604 void Preferences::setToolbarTextPosition(const int position)
1606 setValue("Toolbar/textPosition", position);
1609 QList<QNetworkCookie> Preferences::getNetworkCookies() const
1611 QList<QNetworkCookie> cookies;
1612 const QStringList rawCookies = value("Network/Cookies").toStringList();
1613 for (const QString &rawCookie : rawCookies)
1614 cookies << QNetworkCookie::parseCookies(rawCookie.toUtf8());
1616 return cookies;
1619 void Preferences::setNetworkCookies(const QList<QNetworkCookie> &cookies)
1621 QStringList rawCookies;
1622 for (const QNetworkCookie &cookie : cookies)
1623 rawCookies << cookie.toRawForm();
1625 setValue("Network/Cookies", rawCookies);
1628 bool Preferences::isSpeedWidgetEnabled() const
1630 return value("SpeedWidget/Enabled", true).toBool();
1633 void Preferences::setSpeedWidgetEnabled(const bool enabled)
1635 setValue("SpeedWidget/Enabled", enabled);
1638 int Preferences::getSpeedWidgetPeriod() const
1640 return value("SpeedWidget/period", 1).toInt();
1643 void Preferences::setSpeedWidgetPeriod(const int period)
1645 setValue("SpeedWidget/period", period);
1648 bool Preferences::getSpeedWidgetGraphEnable(const int id) const
1650 // UP and DOWN graphs enabled by default
1651 return value("SpeedWidget/graph_enable_" + QString::number(id), (id == 0 || id == 1)).toBool();
1654 void Preferences::setSpeedWidgetGraphEnable(const int id, const bool enable)
1656 setValue("SpeedWidget/graph_enable_" + QString::number(id), enable);
1659 void Preferences::apply()
1661 if (SettingsStorage::instance()->save())
1662 emit changed();