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>
5  *
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.
10  *
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.
15  *
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.
19  *
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.
28  */
29 
30 #include "preferences.h"
31 
32 #include <chrono>
33 
34 #ifdef Q_OS_MACOS
35 #include <CoreServices/CoreServices.h>
36 #endif
37 #ifdef Q_OS_WIN
38 #include <shlobj.h>
39 #endif
40 
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>
51 
52 #ifdef Q_OS_WIN
53 #include <QRegularExpression>
54 #endif
55 
56 #include "algorithm.h"
57 #include "global.h"
58 #include "settingsstorage.h"
59 #include "utils/fs.h"
60 
61 Preferences *Preferences::m_instance = nullptr;
62 
63 Preferences::Preferences() = default;
64 
instance()65 Preferences *Preferences::instance()
66 {
67     return m_instance;
68 }
69 
initInstance()70 void Preferences::initInstance()
71 {
72     if (!m_instance)
73         m_instance = new Preferences;
74 }
75 
freeInstance()76 void Preferences::freeInstance()
77 {
78     delete m_instance;
79     m_instance = nullptr;
80 }
81 
value(const QString & key,const QVariant & defaultValue) const82 const QVariant Preferences::value(const QString &key, const QVariant &defaultValue) const
83 {
84     return SettingsStorage::instance()->loadValue(key, defaultValue);
85 }
86 
setValue(const QString & key,const QVariant & value)87 void Preferences::setValue(const QString &key, const QVariant &value)
88 {
89     SettingsStorage::instance()->storeValue(key, value);
90 }
91 
92 // General options
getLocale() const93 QString Preferences::getLocale() const
94 {
95     const QString localeName = value("Preferences/General/Locale").toString();
96     return (localeName.isEmpty() ? QLocale::system().name() : localeName);
97 }
98 
setLocale(const QString & locale)99 void Preferences::setLocale(const QString &locale)
100 {
101     setValue("Preferences/General/Locale", locale);
102 }
103 
useCustomUITheme() const104 bool Preferences::useCustomUITheme() const
105 {
106     return value("Preferences/General/UseCustomUITheme", false).toBool()
107            && !customUIThemePath().isEmpty();
108 }
109 
setUseCustomUITheme(const bool use)110 void Preferences::setUseCustomUITheme(const bool use)
111 {
112     setValue("Preferences/General/UseCustomUITheme", use);
113 }
114 
customUIThemePath() const115 QString Preferences::customUIThemePath() const
116 {
117     return value("Preferences/General/CustomUIThemePath").toString();
118 }
119 
setCustomUIThemePath(const QString & path)120 void Preferences::setCustomUIThemePath(const QString &path)
121 {
122     setValue("Preferences/General/CustomUIThemePath", path);
123 }
124 
deleteTorrentFilesAsDefault() const125 bool Preferences::deleteTorrentFilesAsDefault() const
126 {
127     return value("Preferences/General/DeleteTorrentsFilesAsDefault", false).toBool();
128 }
129 
setDeleteTorrentFilesAsDefault(const bool del)130 void Preferences::setDeleteTorrentFilesAsDefault(const bool del)
131 {
132     setValue("Preferences/General/DeleteTorrentsFilesAsDefault", del);
133 }
134 
confirmOnExit() const135 bool Preferences::confirmOnExit() const
136 {
137     return value("Preferences/General/ExitConfirm", true).toBool();
138 }
139 
setConfirmOnExit(const bool confirm)140 void Preferences::setConfirmOnExit(const bool confirm)
141 {
142     setValue("Preferences/General/ExitConfirm", confirm);
143 }
144 
speedInTitleBar() const145 bool Preferences::speedInTitleBar() const
146 {
147     return value("Preferences/General/SpeedInTitleBar", false).toBool();
148 }
149 
showSpeedInTitleBar(const bool show)150 void Preferences::showSpeedInTitleBar(const bool show)
151 {
152     setValue("Preferences/General/SpeedInTitleBar", show);
153 }
154 
useAlternatingRowColors() const155 bool Preferences::useAlternatingRowColors() const
156 {
157     return value("Preferences/General/AlternatingRowColors", true).toBool();
158 }
159 
setAlternatingRowColors(const bool b)160 void Preferences::setAlternatingRowColors(const bool b)
161 {
162     setValue("Preferences/General/AlternatingRowColors", b);
163 }
164 
getHideZeroValues() const165 bool Preferences::getHideZeroValues() const
166 {
167     return value("Preferences/General/HideZeroValues", false).toBool();
168 }
169 
setHideZeroValues(const bool b)170 void Preferences::setHideZeroValues(const bool b)
171 {
172     setValue("Preferences/General/HideZeroValues", b);
173 }
174 
getHideZeroComboValues() const175 int Preferences::getHideZeroComboValues() const
176 {
177     return value("Preferences/General/HideZeroComboValues", 0).toInt();
178 }
179 
setHideZeroComboValues(const int n)180 void Preferences::setHideZeroComboValues(const int n)
181 {
182     setValue("Preferences/General/HideZeroComboValues", n);
183 }
184 
185 // In Mac OS X the dock is sufficient for our needs so we disable the sys tray functionality.
186 // See extensive discussion in https://github.com/qbittorrent/qBittorrent/pull/3018
187 #ifndef Q_OS_MACOS
systrayIntegration() const188 bool Preferences::systrayIntegration() const
189 {
190     return value("Preferences/General/SystrayEnabled", true).toBool();
191 }
192 
setSystrayIntegration(const bool enabled)193 void Preferences::setSystrayIntegration(const bool enabled)
194 {
195     setValue("Preferences/General/SystrayEnabled", enabled);
196 }
197 
minimizeToTray() const198 bool Preferences::minimizeToTray() const
199 {
200     return value("Preferences/General/MinimizeToTray", false).toBool();
201 }
202 
setMinimizeToTray(const bool b)203 void Preferences::setMinimizeToTray(const bool b)
204 {
205     setValue("Preferences/General/MinimizeToTray", b);
206 }
207 
minimizeToTrayNotified() const208 bool Preferences::minimizeToTrayNotified() const
209 {
210     return value("Preferences/General/MinimizeToTrayNotified", false).toBool();
211 }
212 
setMinimizeToTrayNotified(const bool b)213 void Preferences::setMinimizeToTrayNotified(const bool b)
214 {
215     setValue("Preferences/General/MinimizeToTrayNotified", b);
216 }
217 
closeToTray() const218 bool Preferences::closeToTray() const
219 {
220     return value("Preferences/General/CloseToTray", true).toBool();
221 }
222 
setCloseToTray(const bool b)223 void Preferences::setCloseToTray(const bool b)
224 {
225     setValue("Preferences/General/CloseToTray", b);
226 }
227 
closeToTrayNotified() const228 bool Preferences::closeToTrayNotified() const
229 {
230     return value("Preferences/General/CloseToTrayNotified", false).toBool();
231 }
232 
setCloseToTrayNotified(const bool b)233 void Preferences::setCloseToTrayNotified(const bool b)
234 {
235     setValue("Preferences/General/CloseToTrayNotified", b);
236 }
237 
iconsInMenusEnabled() const238 bool Preferences::iconsInMenusEnabled() const
239 {
240     return value("Preferences/Advanced/EnableIconsInMenus", true).toBool();
241 }
242 
setIconsInMenusEnabled(const bool enable)243 void Preferences::setIconsInMenusEnabled(const bool enable)
244 {
245     setValue("Preferences/Advanced/EnableIconsInMenus", enable);
246 }
247 #endif // Q_OS_MACOS
248 
isToolbarDisplayed() const249 bool Preferences::isToolbarDisplayed() const
250 {
251     return value("Preferences/General/ToolbarDisplayed", true).toBool();
252 }
253 
setToolbarDisplayed(const bool displayed)254 void Preferences::setToolbarDisplayed(const bool displayed)
255 {
256     setValue("Preferences/General/ToolbarDisplayed", displayed);
257 }
258 
isStatusbarDisplayed() const259 bool Preferences::isStatusbarDisplayed() const
260 {
261     return value("Preferences/General/StatusbarDisplayed", true).toBool();
262 }
263 
setStatusbarDisplayed(const bool displayed)264 void Preferences::setStatusbarDisplayed(const bool displayed)
265 {
266     setValue("Preferences/General/StatusbarDisplayed", displayed);
267 }
268 
startMinimized() const269 bool Preferences::startMinimized() const
270 {
271     return value("Preferences/General/StartMinimized", false).toBool();
272 }
273 
setStartMinimized(const bool b)274 void Preferences::setStartMinimized(const bool b)
275 {
276     setValue("Preferences/General/StartMinimized", b);
277 }
278 
isSplashScreenDisabled() const279 bool Preferences::isSplashScreenDisabled() const
280 {
281     return value("Preferences/General/NoSplashScreen", true).toBool();
282 }
283 
setSplashScreenDisabled(const bool b)284 void Preferences::setSplashScreenDisabled(const bool b)
285 {
286     setValue("Preferences/General/NoSplashScreen", b);
287 }
288 
289 // Preventing from system suspend while active torrents are presented.
preventFromSuspendWhenDownloading() const290 bool Preferences::preventFromSuspendWhenDownloading() const
291 {
292     return value("Preferences/General/PreventFromSuspendWhenDownloading", false).toBool();
293 }
294 
setPreventFromSuspendWhenDownloading(const bool b)295 void Preferences::setPreventFromSuspendWhenDownloading(const bool b)
296 {
297     setValue("Preferences/General/PreventFromSuspendWhenDownloading", b);
298 }
299 
preventFromSuspendWhenSeeding() const300 bool Preferences::preventFromSuspendWhenSeeding() const
301 {
302     return value("Preferences/General/PreventFromSuspendWhenSeeding", false).toBool();
303 }
304 
setPreventFromSuspendWhenSeeding(const bool b)305 void Preferences::setPreventFromSuspendWhenSeeding(const bool b)
306 {
307     setValue("Preferences/General/PreventFromSuspendWhenSeeding", b);
308 }
309 
310 #ifdef Q_OS_WIN
WinStartup() const311 bool Preferences::WinStartup() const
312 {
313     QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
314     return settings.contains("qBittorrent");
315 }
316 
setWinStartup(const bool b)317 void Preferences::setWinStartup(const bool b)
318 {
319     QSettings settings("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);
320     if (b)
321     {
322         const QString binPath = '"' + Utils::Fs::toNativePath(qApp->applicationFilePath()) + '"';
323         settings.setValue("qBittorrent", binPath);
324     }
325     else
326     {
327         settings.remove("qBittorrent");
328     }
329 }
330 #endif // Q_OS_WIN
331 
332 // Downloads
lastLocationPath() const333 QString Preferences::lastLocationPath() const
334 {
335     return Utils::Fs::toUniformPath(value("Preferences/Downloads/LastLocationPath").toString());
336 }
337 
setLastLocationPath(const QString & path)338 void Preferences::setLastLocationPath(const QString &path)
339 {
340     setValue("Preferences/Downloads/LastLocationPath", Utils::Fs::toUniformPath(path));
341 }
342 
getScanDirsLastPath() const343 QString Preferences::getScanDirsLastPath() const
344 {
345     return Utils::Fs::toUniformPath(value("Preferences/Downloads/ScanDirsLastPath").toString());
346 }
347 
setScanDirsLastPath(const QString & path)348 void Preferences::setScanDirsLastPath(const QString &path)
349 {
350     setValue("Preferences/Downloads/ScanDirsLastPath", Utils::Fs::toUniformPath(path));
351 }
352 
isMailNotificationEnabled() const353 bool Preferences::isMailNotificationEnabled() const
354 {
355     return value("Preferences/MailNotification/enabled", false).toBool();
356 }
357 
setMailNotificationEnabled(const bool enabled)358 void Preferences::setMailNotificationEnabled(const bool enabled)
359 {
360     setValue("Preferences/MailNotification/enabled", enabled);
361 }
362 
getMailNotificationSender() const363 QString Preferences::getMailNotificationSender() const
364 {
365     return value("Preferences/MailNotification/sender", "qBittorrent_notification@example.com").toString();
366 }
367 
setMailNotificationSender(const QString & mail)368 void Preferences::setMailNotificationSender(const QString &mail)
369 {
370     setValue("Preferences/MailNotification/sender", mail);
371 }
372 
getMailNotificationEmail() const373 QString Preferences::getMailNotificationEmail() const
374 {
375     return value("Preferences/MailNotification/email").toString();
376 }
377 
setMailNotificationEmail(const QString & mail)378 void Preferences::setMailNotificationEmail(const QString &mail)
379 {
380     setValue("Preferences/MailNotification/email", mail);
381 }
382 
getMailNotificationSMTP() const383 QString Preferences::getMailNotificationSMTP() const
384 {
385     return value("Preferences/MailNotification/smtp_server", "smtp.changeme.com").toString();
386 }
387 
setMailNotificationSMTP(const QString & smtp_server)388 void Preferences::setMailNotificationSMTP(const QString &smtp_server)
389 {
390     setValue("Preferences/MailNotification/smtp_server", smtp_server);
391 }
392 
getMailNotificationSMTPSSL() const393 bool Preferences::getMailNotificationSMTPSSL() const
394 {
395     return value("Preferences/MailNotification/req_ssl", false).toBool();
396 }
397 
setMailNotificationSMTPSSL(const bool use)398 void Preferences::setMailNotificationSMTPSSL(const bool use)
399 {
400     setValue("Preferences/MailNotification/req_ssl", use);
401 }
402 
getMailNotificationSMTPAuth() const403 bool Preferences::getMailNotificationSMTPAuth() const
404 {
405     return value("Preferences/MailNotification/req_auth", false).toBool();
406 }
407 
setMailNotificationSMTPAuth(const bool use)408 void Preferences::setMailNotificationSMTPAuth(const bool use)
409 {
410     setValue("Preferences/MailNotification/req_auth", use);
411 }
412 
getMailNotificationSMTPUsername() const413 QString Preferences::getMailNotificationSMTPUsername() const
414 {
415     return value("Preferences/MailNotification/username").toString();
416 }
417 
setMailNotificationSMTPUsername(const QString & username)418 void Preferences::setMailNotificationSMTPUsername(const QString &username)
419 {
420     setValue("Preferences/MailNotification/username", username);
421 }
422 
getMailNotificationSMTPPassword() const423 QString Preferences::getMailNotificationSMTPPassword() const
424 {
425     return value("Preferences/MailNotification/password").toString();
426 }
427 
setMailNotificationSMTPPassword(const QString & password)428 void Preferences::setMailNotificationSMTPPassword(const QString &password)
429 {
430     setValue("Preferences/MailNotification/password", password);
431 }
432 
getActionOnDblClOnTorrentDl() const433 int Preferences::getActionOnDblClOnTorrentDl() const
434 {
435     return value("Preferences/Downloads/DblClOnTorDl", 0).toInt();
436 }
437 
setActionOnDblClOnTorrentDl(const int act)438 void Preferences::setActionOnDblClOnTorrentDl(const int act)
439 {
440     setValue("Preferences/Downloads/DblClOnTorDl", act);
441 }
442 
getActionOnDblClOnTorrentFn() const443 int Preferences::getActionOnDblClOnTorrentFn() const
444 {
445     return value("Preferences/Downloads/DblClOnTorFn", 1).toInt();
446 }
447 
setActionOnDblClOnTorrentFn(const int act)448 void Preferences::setActionOnDblClOnTorrentFn(const int act)
449 {
450     setValue("Preferences/Downloads/DblClOnTorFn", act);
451 }
452 
getSchedulerStartTime() const453 QTime Preferences::getSchedulerStartTime() const
454 {
455     return value("Preferences/Scheduler/start_time", QTime(8,0)).toTime();
456 }
457 
setSchedulerStartTime(const QTime & time)458 void Preferences::setSchedulerStartTime(const QTime &time)
459 {
460     setValue("Preferences/Scheduler/start_time", time);
461 }
462 
getSchedulerEndTime() const463 QTime Preferences::getSchedulerEndTime() const
464 {
465     return value("Preferences/Scheduler/end_time", QTime(20,0)).toTime();
466 }
467 
setSchedulerEndTime(const QTime & time)468 void Preferences::setSchedulerEndTime(const QTime &time)
469 {
470     setValue("Preferences/Scheduler/end_time", time);
471 }
472 
getSchedulerDays() const473 SchedulerDays Preferences::getSchedulerDays() const
474 {
475     return static_cast<SchedulerDays>(value("Preferences/Scheduler/days", EVERY_DAY).toInt());
476 }
477 
setSchedulerDays(const SchedulerDays days)478 void Preferences::setSchedulerDays(const SchedulerDays days)
479 {
480     setValue("Preferences/Scheduler/days", static_cast<int>(days));
481 }
482 
483 // Search
isSearchEnabled() const484 bool Preferences::isSearchEnabled() const
485 {
486     return value("Preferences/Search/SearchEnabled", false).toBool();
487 }
488 
setSearchEnabled(const bool enabled)489 void Preferences::setSearchEnabled(const bool enabled)
490 {
491     setValue("Preferences/Search/SearchEnabled", enabled);
492 }
493 
isWebUiEnabled() const494 bool Preferences::isWebUiEnabled() const
495 {
496 #ifdef DISABLE_GUI
497     return true;
498 #else
499     return value("Preferences/WebUI/Enabled", false).toBool();
500 #endif
501 }
502 
setWebUiEnabled(const bool enabled)503 void Preferences::setWebUiEnabled(const bool enabled)
504 {
505     setValue("Preferences/WebUI/Enabled", enabled);
506 }
507 
isWebUiLocalAuthEnabled() const508 bool Preferences::isWebUiLocalAuthEnabled() const
509 {
510     return value("Preferences/WebUI/LocalHostAuth", true).toBool();
511 }
512 
setWebUiLocalAuthEnabled(const bool enabled)513 void Preferences::setWebUiLocalAuthEnabled(const bool enabled)
514 {
515     setValue("Preferences/WebUI/LocalHostAuth", enabled);
516 }
517 
isWebUiAuthSubnetWhitelistEnabled() const518 bool Preferences::isWebUiAuthSubnetWhitelistEnabled() const
519 {
520     return value("Preferences/WebUI/AuthSubnetWhitelistEnabled", false).toBool();
521 }
522 
setWebUiAuthSubnetWhitelistEnabled(const bool enabled)523 void Preferences::setWebUiAuthSubnetWhitelistEnabled(const bool enabled)
524 {
525     setValue("Preferences/WebUI/AuthSubnetWhitelistEnabled", enabled);
526 }
527 
getWebUiAuthSubnetWhitelist() const528 QVector<Utils::Net::Subnet> Preferences::getWebUiAuthSubnetWhitelist() const
529 {
530     const QStringList subnets = value("Preferences/WebUI/AuthSubnetWhitelist").toStringList();
531 
532     QVector<Utils::Net::Subnet> ret;
533     ret.reserve(subnets.size());
534 
535     for (const QString &rawSubnet : subnets)
536     {
537         bool ok = false;
538         const Utils::Net::Subnet subnet = Utils::Net::parseSubnet(rawSubnet.trimmed(), &ok);
539         if (ok)
540             ret.append(subnet);
541     }
542 
543     return ret;
544 }
545 
setWebUiAuthSubnetWhitelist(QStringList subnets)546 void Preferences::setWebUiAuthSubnetWhitelist(QStringList subnets)
547 {
548     Algorithm::removeIf(subnets, [](const QString &subnet)
549     {
550         bool ok = false;
551         Utils::Net::parseSubnet(subnet.trimmed(), &ok);
552         return !ok;
553     });
554 
555     setValue("Preferences/WebUI/AuthSubnetWhitelist", subnets);
556 }
557 
getServerDomains() const558 QString Preferences::getServerDomains() const
559 {
560     return value("Preferences/WebUI/ServerDomains", QChar('*')).toString();
561 }
562 
setServerDomains(const QString & str)563 void Preferences::setServerDomains(const QString &str)
564 {
565     setValue("Preferences/WebUI/ServerDomains", str);
566 }
567 
getWebUiAddress() const568 QString Preferences::getWebUiAddress() const
569 {
570     return value("Preferences/WebUI/Address", QChar('*')).toString().trimmed();
571 }
572 
setWebUiAddress(const QString & addr)573 void Preferences::setWebUiAddress(const QString &addr)
574 {
575     setValue("Preferences/WebUI/Address", addr.trimmed());
576 }
577 
getWebUiPort() const578 quint16 Preferences::getWebUiPort() const
579 {
580     return value("Preferences/WebUI/Port", 8080).toInt();
581 }
582 
setWebUiPort(const quint16 port)583 void Preferences::setWebUiPort(const quint16 port)
584 {
585     setValue("Preferences/WebUI/Port", port);
586 }
587 
useUPnPForWebUIPort() const588 bool Preferences::useUPnPForWebUIPort() const
589 {
590 #ifdef DISABLE_GUI
591     return value("Preferences/WebUI/UseUPnP", true).toBool();
592 #else
593     return value("Preferences/WebUI/UseUPnP", false).toBool();
594 #endif
595 }
596 
setUPnPForWebUIPort(const bool enabled)597 void Preferences::setUPnPForWebUIPort(const bool enabled)
598 {
599     setValue("Preferences/WebUI/UseUPnP", enabled);
600 }
601 
getWebUiUsername() const602 QString Preferences::getWebUiUsername() const
603 {
604     return value("Preferences/WebUI/Username", "admin").toString();
605 }
606 
setWebUiUsername(const QString & username)607 void Preferences::setWebUiUsername(const QString &username)
608 {
609     setValue("Preferences/WebUI/Username", username);
610 }
611 
getWebUIPassword() const612 QByteArray Preferences::getWebUIPassword() const
613 {
614     // default: adminadmin
615     const QByteArray defaultValue = "ARQ77eY1NUZaQsuDHbIMCA==:0WMRkYTUWVT9wVvdDtHAjU9b3b7uB8NR1Gur2hmQCvCDpm39Q+PsJRJPaCU51dEiz+dTzh8qbPsL8WkFljQYFQ==";
616     return value("Preferences/WebUI/Password_PBKDF2", defaultValue).toByteArray();
617 }
618 
setWebUIPassword(const QByteArray & password)619 void Preferences::setWebUIPassword(const QByteArray &password)
620 {
621     setValue("Preferences/WebUI/Password_PBKDF2", password);
622 }
623 
getWebUIMaxAuthFailCount() const624 int Preferences::getWebUIMaxAuthFailCount() const
625 {
626     return value("Preferences/WebUI/MaxAuthenticationFailCount", 5).toInt();
627 }
628 
setWebUIMaxAuthFailCount(const int count)629 void Preferences::setWebUIMaxAuthFailCount(const int count)
630 {
631     setValue("Preferences/WebUI/MaxAuthenticationFailCount", count);
632 }
633 
getWebUIBanDuration() const634 std::chrono::seconds Preferences::getWebUIBanDuration() const
635 {
636     return std::chrono::seconds {value("Preferences/WebUI/BanDuration", 3600).toInt()};
637 }
638 
setWebUIBanDuration(const std::chrono::seconds duration)639 void Preferences::setWebUIBanDuration(const std::chrono::seconds duration)
640 {
641     setValue("Preferences/WebUI/BanDuration", static_cast<int>(duration.count()));
642 }
643 
getWebUISessionTimeout() const644 int Preferences::getWebUISessionTimeout() const
645 {
646     return value("Preferences/WebUI/SessionTimeout", 3600).toInt();
647 }
648 
setWebUISessionTimeout(const int timeout)649 void Preferences::setWebUISessionTimeout(const int timeout)
650 {
651     setValue("Preferences/WebUI/SessionTimeout", timeout);
652 }
653 
isWebUiClickjackingProtectionEnabled() const654 bool Preferences::isWebUiClickjackingProtectionEnabled() const
655 {
656     return value("Preferences/WebUI/ClickjackingProtection", true).toBool();
657 }
658 
setWebUiClickjackingProtectionEnabled(const bool enabled)659 void Preferences::setWebUiClickjackingProtectionEnabled(const bool enabled)
660 {
661     setValue("Preferences/WebUI/ClickjackingProtection", enabled);
662 }
663 
isWebUiCSRFProtectionEnabled() const664 bool Preferences::isWebUiCSRFProtectionEnabled() const
665 {
666     return value("Preferences/WebUI/CSRFProtection", true).toBool();
667 }
668 
setWebUiCSRFProtectionEnabled(const bool enabled)669 void Preferences::setWebUiCSRFProtectionEnabled(const bool enabled)
670 {
671     setValue("Preferences/WebUI/CSRFProtection", enabled);
672 }
673 
isWebUiSecureCookieEnabled() const674 bool Preferences::isWebUiSecureCookieEnabled() const
675 {
676     return value("Preferences/WebUI/SecureCookie", true).toBool();
677 }
678 
setWebUiSecureCookieEnabled(const bool enabled)679 void Preferences::setWebUiSecureCookieEnabled(const bool enabled)
680 {
681     setValue("Preferences/WebUI/SecureCookie", enabled);
682 }
683 
isWebUIHostHeaderValidationEnabled() const684 bool Preferences::isWebUIHostHeaderValidationEnabled() const
685 {
686     return value("Preferences/WebUI/HostHeaderValidation", true).toBool();
687 }
688 
setWebUIHostHeaderValidationEnabled(const bool enabled)689 void Preferences::setWebUIHostHeaderValidationEnabled(const bool enabled)
690 {
691     setValue("Preferences/WebUI/HostHeaderValidation", enabled);
692 }
693 
isWebUiHttpsEnabled() const694 bool Preferences::isWebUiHttpsEnabled() const
695 {
696     return value("Preferences/WebUI/HTTPS/Enabled", false).toBool();
697 }
698 
setWebUiHttpsEnabled(const bool enabled)699 void Preferences::setWebUiHttpsEnabled(const bool enabled)
700 {
701     setValue("Preferences/WebUI/HTTPS/Enabled", enabled);
702 }
703 
getWebUIHttpsCertificatePath() const704 QString Preferences::getWebUIHttpsCertificatePath() const
705 {
706     return value("Preferences/WebUI/HTTPS/CertificatePath").toString();
707 }
708 
setWebUIHttpsCertificatePath(const QString & path)709 void Preferences::setWebUIHttpsCertificatePath(const QString &path)
710 {
711     setValue("Preferences/WebUI/HTTPS/CertificatePath", path);
712 }
713 
getWebUIHttpsKeyPath() const714 QString Preferences::getWebUIHttpsKeyPath() const
715 {
716     return value("Preferences/WebUI/HTTPS/KeyPath").toString();
717 }
718 
setWebUIHttpsKeyPath(const QString & path)719 void Preferences::setWebUIHttpsKeyPath(const QString &path)
720 {
721     setValue("Preferences/WebUI/HTTPS/KeyPath", path);
722 }
723 
isAltWebUiEnabled() const724 bool Preferences::isAltWebUiEnabled() const
725 {
726     return value("Preferences/WebUI/AlternativeUIEnabled", false).toBool();
727 }
728 
setAltWebUiEnabled(const bool enabled)729 void Preferences::setAltWebUiEnabled(const bool enabled)
730 {
731     setValue("Preferences/WebUI/AlternativeUIEnabled", enabled);
732 }
733 
getWebUiRootFolder() const734 QString Preferences::getWebUiRootFolder() const
735 {
736     return value("Preferences/WebUI/RootFolder").toString();
737 }
738 
setWebUiRootFolder(const QString & path)739 void Preferences::setWebUiRootFolder(const QString &path)
740 {
741     setValue("Preferences/WebUI/RootFolder", path);
742 }
743 
isWebUICustomHTTPHeadersEnabled() const744 bool Preferences::isWebUICustomHTTPHeadersEnabled() const
745 {
746     return value("Preferences/WebUI/CustomHTTPHeadersEnabled", false).toBool();
747 }
748 
setWebUICustomHTTPHeadersEnabled(const bool enabled)749 void Preferences::setWebUICustomHTTPHeadersEnabled(const bool enabled)
750 {
751     setValue("Preferences/WebUI/CustomHTTPHeadersEnabled", enabled);
752 }
753 
getWebUICustomHTTPHeaders() const754 QString Preferences::getWebUICustomHTTPHeaders() const
755 {
756     return value("Preferences/WebUI/CustomHTTPHeaders").toString();
757 }
758 
setWebUICustomHTTPHeaders(const QString & headers)759 void Preferences::setWebUICustomHTTPHeaders(const QString &headers)
760 {
761     setValue("Preferences/WebUI/CustomHTTPHeaders", headers);
762 }
763 
isDynDNSEnabled() const764 bool Preferences::isDynDNSEnabled() const
765 {
766     return value("Preferences/DynDNS/Enabled", false).toBool();
767 }
768 
setDynDNSEnabled(const bool enabled)769 void Preferences::setDynDNSEnabled(const bool enabled)
770 {
771     setValue("Preferences/DynDNS/Enabled", enabled);
772 }
773 
getDynDNSService() const774 DNS::Service Preferences::getDynDNSService() const
775 {
776     return DNS::Service(value("Preferences/DynDNS/Service", DNS::DYNDNS).toInt());
777 }
778 
setDynDNSService(const int service)779 void Preferences::setDynDNSService(const int service)
780 {
781     setValue("Preferences/DynDNS/Service", service);
782 }
783 
getDynDomainName() const784 QString Preferences::getDynDomainName() const
785 {
786     return value("Preferences/DynDNS/DomainName", "changeme.dyndns.org").toString();
787 }
788 
setDynDomainName(const QString & name)789 void Preferences::setDynDomainName(const QString &name)
790 {
791     setValue("Preferences/DynDNS/DomainName", name);
792 }
793 
getDynDNSUsername() const794 QString Preferences::getDynDNSUsername() const
795 {
796     return value("Preferences/DynDNS/Username").toString();
797 }
798 
setDynDNSUsername(const QString & username)799 void Preferences::setDynDNSUsername(const QString &username)
800 {
801     setValue("Preferences/DynDNS/Username", username);
802 }
803 
getDynDNSPassword() const804 QString Preferences::getDynDNSPassword() const
805 {
806     return value("Preferences/DynDNS/Password").toString();
807 }
808 
setDynDNSPassword(const QString & password)809 void Preferences::setDynDNSPassword(const QString &password)
810 {
811     setValue("Preferences/DynDNS/Password", password);
812 }
813 
814 // Advanced settings
getUILockPassword() const815 QByteArray Preferences::getUILockPassword() const
816 {
817     return value("Locking/password_PBKDF2").toByteArray();
818 }
819 
setUILockPassword(const QByteArray & password)820 void Preferences::setUILockPassword(const QByteArray &password)
821 {
822     setValue("Locking/password_PBKDF2", password);
823 }
824 
isUILocked() const825 bool Preferences::isUILocked() const
826 {
827     return value("Locking/locked", false).toBool();
828 }
829 
setUILocked(const bool locked)830 void Preferences::setUILocked(const bool locked)
831 {
832     setValue("Locking/locked", locked);
833 }
834 
isAutoRunEnabled() const835 bool Preferences::isAutoRunEnabled() const
836 {
837     return value("AutoRun/enabled", false).toBool();
838 }
839 
setAutoRunEnabled(const bool enabled)840 void Preferences::setAutoRunEnabled(const bool enabled)
841 {
842     setValue("AutoRun/enabled", enabled);
843 }
844 
getAutoRunProgram() const845 QString Preferences::getAutoRunProgram() const
846 {
847     return value("AutoRun/program").toString();
848 }
849 
setAutoRunProgram(const QString & program)850 void Preferences::setAutoRunProgram(const QString &program)
851 {
852     setValue("AutoRun/program", program);
853 }
854 
855 #if defined(Q_OS_WIN)
isAutoRunConsoleEnabled() const856 bool Preferences::isAutoRunConsoleEnabled() const
857 {
858     return value("AutoRun/ConsoleEnabled", false).toBool();
859 }
860 
setAutoRunConsoleEnabled(const bool enabled)861 void Preferences::setAutoRunConsoleEnabled(const bool enabled)
862 {
863     setValue("AutoRun/ConsoleEnabled", enabled);
864 }
865 #endif
866 
shutdownWhenDownloadsComplete() const867 bool Preferences::shutdownWhenDownloadsComplete() const
868 {
869     return value("Preferences/Downloads/AutoShutDownOnCompletion", false).toBool();
870 }
871 
setShutdownWhenDownloadsComplete(const bool shutdown)872 void Preferences::setShutdownWhenDownloadsComplete(const bool shutdown)
873 {
874     setValue("Preferences/Downloads/AutoShutDownOnCompletion", shutdown);
875 }
876 
suspendWhenDownloadsComplete() const877 bool Preferences::suspendWhenDownloadsComplete() const
878 {
879     return value("Preferences/Downloads/AutoSuspendOnCompletion", false).toBool();
880 }
881 
setSuspendWhenDownloadsComplete(const bool suspend)882 void Preferences::setSuspendWhenDownloadsComplete(const bool suspend)
883 {
884     setValue("Preferences/Downloads/AutoSuspendOnCompletion", suspend);
885 }
886 
hibernateWhenDownloadsComplete() const887 bool Preferences::hibernateWhenDownloadsComplete() const
888 {
889     return value("Preferences/Downloads/AutoHibernateOnCompletion", false).toBool();
890 }
891 
setHibernateWhenDownloadsComplete(const bool hibernate)892 void Preferences::setHibernateWhenDownloadsComplete(const bool hibernate)
893 {
894     setValue("Preferences/Downloads/AutoHibernateOnCompletion", hibernate);
895 }
896 
shutdownqBTWhenDownloadsComplete() const897 bool Preferences::shutdownqBTWhenDownloadsComplete() const
898 {
899     return value("Preferences/Downloads/AutoShutDownqBTOnCompletion", false).toBool();
900 }
901 
setShutdownqBTWhenDownloadsComplete(const bool shutdown)902 void Preferences::setShutdownqBTWhenDownloadsComplete(const bool shutdown)
903 {
904     setValue("Preferences/Downloads/AutoShutDownqBTOnCompletion", shutdown);
905 }
906 
dontConfirmAutoExit() const907 bool Preferences::dontConfirmAutoExit() const
908 {
909     return value("ShutdownConfirmDlg/DontConfirmAutoExit", false).toBool();
910 }
911 
setDontConfirmAutoExit(const bool dontConfirmAutoExit)912 void Preferences::setDontConfirmAutoExit(const bool dontConfirmAutoExit)
913 {
914     setValue("ShutdownConfirmDlg/DontConfirmAutoExit", dontConfirmAutoExit);
915 }
916 
recheckTorrentsOnCompletion() const917 bool Preferences::recheckTorrentsOnCompletion() const
918 {
919     return value("Preferences/Advanced/RecheckOnCompletion", false).toBool();
920 }
921 
recheckTorrentsOnCompletion(const bool recheck)922 void Preferences::recheckTorrentsOnCompletion(const bool recheck)
923 {
924     setValue("Preferences/Advanced/RecheckOnCompletion", recheck);
925 }
926 
resolvePeerCountries() const927 bool Preferences::resolvePeerCountries() const
928 {
929     return value("Preferences/Connection/ResolvePeerCountries", true).toBool();
930 }
931 
resolvePeerCountries(const bool resolve)932 void Preferences::resolvePeerCountries(const bool resolve)
933 {
934     setValue("Preferences/Connection/ResolvePeerCountries", resolve);
935 }
936 
resolvePeerHostNames() const937 bool Preferences::resolvePeerHostNames() const
938 {
939     return value("Preferences/Connection/ResolvePeerHostNames", false).toBool();
940 }
941 
resolvePeerHostNames(const bool resolve)942 void Preferences::resolvePeerHostNames(const bool resolve)
943 {
944     setValue("Preferences/Connection/ResolvePeerHostNames", resolve);
945 }
946 
947 #if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS))
useSystemIconTheme() const948 bool Preferences::useSystemIconTheme() const
949 {
950     return value("Preferences/Advanced/useSystemIconTheme", true).toBool();
951 }
952 
useSystemIconTheme(const bool enabled)953 void Preferences::useSystemIconTheme(const bool enabled)
954 {
955     setValue("Preferences/Advanced/useSystemIconTheme", enabled);
956 }
957 #endif
958 
recursiveDownloadDisabled() const959 bool Preferences::recursiveDownloadDisabled() const
960 {
961     return value("Preferences/Advanced/DisableRecursiveDownload", false).toBool();
962 }
963 
disableRecursiveDownload(const bool disable)964 void Preferences::disableRecursiveDownload(const bool disable)
965 {
966     setValue("Preferences/Advanced/DisableRecursiveDownload", disable);
967 }
968 
969 #ifdef Q_OS_WIN
neverCheckFileAssoc() const970 bool Preferences::neverCheckFileAssoc() const
971 {
972     return value("Preferences/Win32/NeverCheckFileAssocation", false).toBool();
973 }
974 
setNeverCheckFileAssoc(const bool check)975 void Preferences::setNeverCheckFileAssoc(const bool check)
976 {
977     setValue("Preferences/Win32/NeverCheckFileAssocation", check);
978 }
979 
isTorrentFileAssocSet()980 bool Preferences::isTorrentFileAssocSet()
981 {
982     const QSettings settings("HKEY_CURRENT_USER\\Software\\Classes", QSettings::NativeFormat);
983     if (settings.value(".torrent/Default").toString() != "qBittorrent")
984     {
985         qDebug(".torrent != qBittorrent");
986         return false;
987     }
988 
989     return true;
990 }
991 
isMagnetLinkAssocSet()992 bool Preferences::isMagnetLinkAssocSet()
993 {
994     const QSettings settings("HKEY_CURRENT_USER\\Software\\Classes", QSettings::NativeFormat);
995 
996     // Check magnet link assoc
997     const QString shellCommand = Utils::Fs::toNativePath(settings.value("magnet/shell/open/command/Default", "").toString());
998 
999     const QRegularExpressionMatch exeRegMatch = QRegularExpression("\"([^\"]+)\".*").match(shellCommand);
1000     if (!exeRegMatch.hasMatch())
1001         return false;
1002 
1003     const QString assocExe = exeRegMatch.captured(1);
1004     if (assocExe.compare(Utils::Fs::toNativePath(qApp->applicationFilePath()), Qt::CaseInsensitive) != 0)
1005         return false;
1006 
1007     return true;
1008 }
1009 
setTorrentFileAssoc(const bool set)1010 void Preferences::setTorrentFileAssoc(const bool set)
1011 {
1012     QSettings settings("HKEY_CURRENT_USER\\Software\\Classes", QSettings::NativeFormat);
1013 
1014     // .Torrent association
1015     if (set)
1016     {
1017         const QString oldProgId = settings.value(".torrent/Default").toString();
1018         if (!oldProgId.isEmpty() && (oldProgId != "qBittorrent"))
1019             settings.setValue(".torrent/OpenWithProgids/" + oldProgId, "");
1020         settings.setValue(".torrent/Default", "qBittorrent");
1021     }
1022     else if (isTorrentFileAssocSet())
1023     {
1024         settings.setValue(".torrent/Default", "");
1025     }
1026 
1027     SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
1028 }
1029 
setMagnetLinkAssoc(const bool set)1030 void Preferences::setMagnetLinkAssoc(const bool set)
1031 {
1032     QSettings settings("HKEY_CURRENT_USER\\Software\\Classes", QSettings::NativeFormat);
1033 
1034     // Magnet association
1035     if (set)
1036     {
1037         const QString commandStr = '"' + qApp->applicationFilePath() + "\" \"%1\"";
1038         const QString iconStr = '"' + qApp->applicationFilePath() + "\",1";
1039 
1040         settings.setValue("magnet/Default", "URL:Magnet link");
1041         settings.setValue("magnet/Content Type", "application/x-magnet");
1042         settings.setValue("magnet/URL Protocol", "");
1043         settings.setValue("magnet/DefaultIcon/Default", Utils::Fs::toNativePath(iconStr));
1044         settings.setValue("magnet/shell/Default", "open");
1045         settings.setValue("magnet/shell/open/command/Default", Utils::Fs::toNativePath(commandStr));
1046     }
1047     else if (isMagnetLinkAssocSet())
1048     {
1049         settings.remove("magnet");
1050     }
1051 
1052     SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, 0, 0);
1053 }
1054 #endif // Q_OS_WIN
1055 
1056 #ifdef Q_OS_MACOS
1057 namespace
1058 {
1059     const CFStringRef torrentExtension = CFSTR("torrent");
1060     const CFStringRef magnetUrlScheme = CFSTR("magnet");
1061 }
1062 
isTorrentFileAssocSet()1063 bool Preferences::isTorrentFileAssocSet()
1064 {
1065     bool isSet = false;
1066     const CFStringRef torrentId = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, torrentExtension, NULL);
1067     if (torrentId != NULL)
1068     {
1069         const CFStringRef defaultHandlerId = LSCopyDefaultRoleHandlerForContentType(torrentId, kLSRolesViewer);
1070         if (defaultHandlerId != NULL)
1071         {
1072             const CFStringRef myBundleId = CFBundleGetIdentifier(CFBundleGetMainBundle());
1073             isSet = CFStringCompare(myBundleId, defaultHandlerId, 0) == kCFCompareEqualTo;
1074             CFRelease(defaultHandlerId);
1075         }
1076         CFRelease(torrentId);
1077     }
1078     return isSet;
1079 }
1080 
isMagnetLinkAssocSet()1081 bool Preferences::isMagnetLinkAssocSet()
1082 {
1083     bool isSet = false;
1084     const CFStringRef defaultHandlerId = LSCopyDefaultHandlerForURLScheme(magnetUrlScheme);
1085     if (defaultHandlerId != NULL)
1086     {
1087         const CFStringRef myBundleId = CFBundleGetIdentifier(CFBundleGetMainBundle());
1088         isSet = CFStringCompare(myBundleId, defaultHandlerId, 0) == kCFCompareEqualTo;
1089         CFRelease(defaultHandlerId);
1090     }
1091     return isSet;
1092 }
1093 
setTorrentFileAssoc()1094 void Preferences::setTorrentFileAssoc()
1095 {
1096     if (isTorrentFileAssocSet())
1097         return;
1098     const CFStringRef torrentId = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, torrentExtension, NULL);
1099     if (torrentId != NULL)
1100     {
1101         const CFStringRef myBundleId = CFBundleGetIdentifier(CFBundleGetMainBundle());
1102         LSSetDefaultRoleHandlerForContentType(torrentId, kLSRolesViewer, myBundleId);
1103         CFRelease(torrentId);
1104     }
1105 }
1106 
setMagnetLinkAssoc()1107 void Preferences::setMagnetLinkAssoc()
1108 {
1109     if (isMagnetLinkAssocSet())
1110         return;
1111     const CFStringRef myBundleId = CFBundleGetIdentifier(CFBundleGetMainBundle());
1112     LSSetDefaultHandlerForURLScheme(magnetUrlScheme, myBundleId);
1113 }
1114 #endif // Q_OS_MACOS
1115 
getTrackerPort() const1116 int Preferences::getTrackerPort() const
1117 {
1118     return value("Preferences/Advanced/trackerPort", 9000).toInt();
1119 }
1120 
setTrackerPort(const int port)1121 void Preferences::setTrackerPort(const int port)
1122 {
1123     setValue("Preferences/Advanced/trackerPort", port);
1124 }
1125 
1126 #if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
isUpdateCheckEnabled() const1127 bool Preferences::isUpdateCheckEnabled() const
1128 {
1129     return value("Preferences/Advanced/updateCheck", true).toBool();
1130 }
1131 
setUpdateCheckEnabled(const bool enabled)1132 void Preferences::setUpdateCheckEnabled(const bool enabled)
1133 {
1134     setValue("Preferences/Advanced/updateCheck", enabled);
1135 }
1136 #endif
1137 
confirmTorrentDeletion() const1138 bool Preferences::confirmTorrentDeletion() const
1139 {
1140     return value("Preferences/Advanced/confirmTorrentDeletion", true).toBool();
1141 }
1142 
setConfirmTorrentDeletion(const bool enabled)1143 void Preferences::setConfirmTorrentDeletion(const bool enabled)
1144 {
1145     setValue("Preferences/Advanced/confirmTorrentDeletion", enabled);
1146 }
1147 
confirmTorrentRecheck() const1148 bool Preferences::confirmTorrentRecheck() const
1149 {
1150     return value("Preferences/Advanced/confirmTorrentRecheck", true).toBool();
1151 }
1152 
setConfirmTorrentRecheck(const bool enabled)1153 void Preferences::setConfirmTorrentRecheck(const bool enabled)
1154 {
1155     setValue("Preferences/Advanced/confirmTorrentRecheck", enabled);
1156 }
1157 
confirmRemoveAllTags() const1158 bool Preferences::confirmRemoveAllTags() const
1159 {
1160     return value("Preferences/Advanced/confirmRemoveAllTags", true).toBool();
1161 }
1162 
setConfirmRemoveAllTags(const bool enabled)1163 void Preferences::setConfirmRemoveAllTags(const bool enabled)
1164 {
1165     setValue("Preferences/Advanced/confirmRemoveAllTags", enabled);
1166 }
1167 
1168 #ifndef Q_OS_MACOS
trayIconStyle() const1169 TrayIcon::Style Preferences::trayIconStyle() const
1170 {
1171     return TrayIcon::Style(value("Preferences/Advanced/TrayIconStyle", TrayIcon::NORMAL).toInt());
1172 }
1173 
setTrayIconStyle(const TrayIcon::Style style)1174 void Preferences::setTrayIconStyle(const TrayIcon::Style style)
1175 {
1176     setValue("Preferences/Advanced/TrayIconStyle", style);
1177 }
1178 #endif
1179 
1180 // Stuff that don't appear in the Options GUI but are saved
1181 // in the same file.
1182 
getDNSLastUpd() const1183 QDateTime Preferences::getDNSLastUpd() const
1184 {
1185     return value("DNSUpdater/lastUpdateTime").toDateTime();
1186 }
1187 
setDNSLastUpd(const QDateTime & date)1188 void Preferences::setDNSLastUpd(const QDateTime &date)
1189 {
1190     setValue("DNSUpdater/lastUpdateTime", date);
1191 }
1192 
getDNSLastIP() const1193 QString Preferences::getDNSLastIP() const
1194 {
1195     return value("DNSUpdater/lastIP").toString();
1196 }
1197 
setDNSLastIP(const QString & ip)1198 void Preferences::setDNSLastIP(const QString &ip)
1199 {
1200     setValue("DNSUpdater/lastIP", ip);
1201 }
1202 
getAcceptedLegal() const1203 bool Preferences::getAcceptedLegal() const
1204 {
1205     return value("LegalNotice/Accepted", false).toBool();
1206 }
1207 
setAcceptedLegal(const bool accepted)1208 void Preferences::setAcceptedLegal(const bool accepted)
1209 {
1210     setValue("LegalNotice/Accepted", accepted);
1211 }
1212 
getMainGeometry() const1213 QByteArray Preferences::getMainGeometry() const
1214 {
1215     return value("MainWindow/geometry").toByteArray();
1216 }
1217 
setMainGeometry(const QByteArray & geometry)1218 void Preferences::setMainGeometry(const QByteArray &geometry)
1219 {
1220     setValue("MainWindow/geometry", geometry);
1221 }
1222 
getMainVSplitterState() const1223 QByteArray Preferences::getMainVSplitterState() const
1224 {
1225     return value("MainWindow/qt5/vsplitterState").toByteArray();
1226 }
1227 
setMainVSplitterState(const QByteArray & state)1228 void Preferences::setMainVSplitterState(const QByteArray &state)
1229 {
1230     setValue("MainWindow/qt5/vsplitterState", state);
1231 }
1232 
getMainLastDir() const1233 QString Preferences::getMainLastDir() const
1234 {
1235     return value("MainWindowLastDir", QDir::homePath()).toString();
1236 }
1237 
setMainLastDir(const QString & path)1238 void Preferences::setMainLastDir(const QString &path)
1239 {
1240     setValue("MainWindowLastDir", path);
1241 }
1242 
getPeerListState() const1243 QByteArray Preferences::getPeerListState() const
1244 {
1245     return value("TorrentProperties/Peers/qt5/PeerListState").toByteArray();
1246 }
1247 
setPeerListState(const QByteArray & state)1248 void Preferences::setPeerListState(const QByteArray &state)
1249 {
1250     setValue("TorrentProperties/Peers/qt5/PeerListState", state);
1251 }
1252 
getPropSplitterSizes() const1253 QString Preferences::getPropSplitterSizes() const
1254 {
1255     return value("TorrentProperties/SplitterSizes").toString();
1256 }
1257 
setPropSplitterSizes(const QString & sizes)1258 void Preferences::setPropSplitterSizes(const QString &sizes)
1259 {
1260     setValue("TorrentProperties/SplitterSizes", sizes);
1261 }
1262 
getPropFileListState() const1263 QByteArray Preferences::getPropFileListState() const
1264 {
1265     return value("TorrentProperties/qt5/FilesListState").toByteArray();
1266 }
1267 
setPropFileListState(const QByteArray & state)1268 void Preferences::setPropFileListState(const QByteArray &state)
1269 {
1270     setValue("TorrentProperties/qt5/FilesListState", state);
1271 }
1272 
getPropCurTab() const1273 int Preferences::getPropCurTab() const
1274 {
1275     return value("TorrentProperties/CurrentTab", -1).toInt();
1276 }
1277 
setPropCurTab(const int tab)1278 void Preferences::setPropCurTab(const int tab)
1279 {
1280     setValue("TorrentProperties/CurrentTab", tab);
1281 }
1282 
getPropVisible() const1283 bool Preferences::getPropVisible() const
1284 {
1285     return value("TorrentProperties/Visible", false).toBool();
1286 }
1287 
setPropVisible(const bool visible)1288 void Preferences::setPropVisible(const bool visible)
1289 {
1290     setValue("TorrentProperties/Visible", visible);
1291 }
1292 
getPropTrackerListState() const1293 QByteArray Preferences::getPropTrackerListState() const
1294 {
1295     return value("TorrentProperties/Trackers/qt5/TrackerListState").toByteArray();
1296 }
1297 
setPropTrackerListState(const QByteArray & state)1298 void Preferences::setPropTrackerListState(const QByteArray &state)
1299 {
1300     setValue("TorrentProperties/Trackers/qt5/TrackerListState", state);
1301 }
1302 
getRssGeometrySize() const1303 QSize Preferences::getRssGeometrySize() const
1304 {
1305     return value("RssFeedDownloader/geometrySize").toSize();
1306 }
1307 
setRssGeometrySize(const QSize & geometry)1308 void Preferences::setRssGeometrySize(const QSize &geometry)
1309 {
1310     setValue("RssFeedDownloader/geometrySize", geometry);
1311 }
1312 
getRssHSplitterSizes() const1313 QByteArray Preferences::getRssHSplitterSizes() const
1314 {
1315     return value("RssFeedDownloader/qt5/hsplitterSizes").toByteArray();
1316 }
1317 
setRssHSplitterSizes(const QByteArray & sizes)1318 void Preferences::setRssHSplitterSizes(const QByteArray &sizes)
1319 {
1320     setValue("RssFeedDownloader/qt5/hsplitterSizes", sizes);
1321 }
1322 
getRssOpenFolders() const1323 QStringList Preferences::getRssOpenFolders() const
1324 {
1325     return value("GUI/RSSWidget/OpenedFolders").toStringList();
1326 }
1327 
setRssOpenFolders(const QStringList & folders)1328 void Preferences::setRssOpenFolders(const QStringList &folders)
1329 {
1330     setValue("GUI/RSSWidget/OpenedFolders", folders);
1331 }
1332 
getRssSideSplitterState() const1333 QByteArray Preferences::getRssSideSplitterState() const
1334 {
1335     return value("GUI/RSSWidget/qt5/splitter_h").toByteArray();
1336 }
1337 
setRssSideSplitterState(const QByteArray & state)1338 void Preferences::setRssSideSplitterState(const QByteArray &state)
1339 {
1340     setValue("GUI/RSSWidget/qt5/splitter_h", state);
1341 }
1342 
getRssMainSplitterState() const1343 QByteArray Preferences::getRssMainSplitterState() const
1344 {
1345     return value("GUI/RSSWidget/qt5/splitterMain").toByteArray();
1346 }
1347 
setRssMainSplitterState(const QByteArray & state)1348 void Preferences::setRssMainSplitterState(const QByteArray &state)
1349 {
1350     setValue("GUI/RSSWidget/qt5/splitterMain", state);
1351 }
1352 
getSearchTabHeaderState() const1353 QByteArray Preferences::getSearchTabHeaderState() const
1354 {
1355     return value("SearchTab/qt5/HeaderState").toByteArray();
1356 }
1357 
setSearchTabHeaderState(const QByteArray & state)1358 void Preferences::setSearchTabHeaderState(const QByteArray &state)
1359 {
1360     setValue("SearchTab/qt5/HeaderState", state);
1361 }
1362 
getRegexAsFilteringPatternForSearchJob() const1363 bool Preferences::getRegexAsFilteringPatternForSearchJob() const
1364 {
1365     return value("SearchTab/UseRegexAsFilteringPattern", false).toBool();
1366 }
1367 
setRegexAsFilteringPatternForSearchJob(const bool checked)1368 void Preferences::setRegexAsFilteringPatternForSearchJob(const bool checked)
1369 {
1370     setValue("SearchTab/UseRegexAsFilteringPattern", checked);
1371 }
1372 
getSearchEngDisabled() const1373 QStringList Preferences::getSearchEngDisabled() const
1374 {
1375     return value("SearchEngines/disabledEngines").toStringList();
1376 }
1377 
setSearchEngDisabled(const QStringList & engines)1378 void Preferences::setSearchEngDisabled(const QStringList &engines)
1379 {
1380     setValue("SearchEngines/disabledEngines", engines);
1381 }
1382 
getTorImportLastContentDir() const1383 QString Preferences::getTorImportLastContentDir() const
1384 {
1385     return value("TorrentImport/LastContentDir", QDir::homePath()).toString();
1386 }
1387 
setTorImportLastContentDir(const QString & path)1388 void Preferences::setTorImportLastContentDir(const QString &path)
1389 {
1390     setValue("TorrentImport/LastContentDir", path);
1391 }
1392 
getTorImportGeometry() const1393 QByteArray Preferences::getTorImportGeometry() const
1394 {
1395     return value("TorrentImportDlg/dimensions").toByteArray();
1396 }
1397 
setTorImportGeometry(const QByteArray & geometry)1398 void Preferences::setTorImportGeometry(const QByteArray &geometry)
1399 {
1400     setValue("TorrentImportDlg/dimensions", geometry);
1401 }
1402 
getStatusFilterState() const1403 bool Preferences::getStatusFilterState() const
1404 {
1405     return value("TransferListFilters/statusFilterState", true).toBool();
1406 }
1407 
setStatusFilterState(const bool checked)1408 void Preferences::setStatusFilterState(const bool checked)
1409 {
1410     setValue("TransferListFilters/statusFilterState", checked);
1411 }
1412 
getCategoryFilterState() const1413 bool Preferences::getCategoryFilterState() const
1414 {
1415     return value("TransferListFilters/CategoryFilterState", true).toBool();
1416 }
1417 
setCategoryFilterState(const bool checked)1418 void Preferences::setCategoryFilterState(const bool checked)
1419 {
1420     setValue("TransferListFilters/CategoryFilterState", checked);
1421 }
1422 
getTagFilterState() const1423 bool Preferences::getTagFilterState() const
1424 {
1425     return value("TransferListFilters/TagFilterState", true).toBool();
1426 }
1427 
setTagFilterState(const bool checked)1428 void Preferences::setTagFilterState(const bool checked)
1429 {
1430     setValue("TransferListFilters/TagFilterState", checked);
1431 }
1432 
getTrackerFilterState() const1433 bool Preferences::getTrackerFilterState() const
1434 {
1435     return value("TransferListFilters/trackerFilterState", true).toBool();
1436 }
1437 
setTrackerFilterState(const bool checked)1438 void Preferences::setTrackerFilterState(const bool checked)
1439 {
1440     setValue("TransferListFilters/trackerFilterState", checked);
1441 }
1442 
getTransSelFilter() const1443 int Preferences::getTransSelFilter() const
1444 {
1445     return value("TransferListFilters/selectedFilterIndex", 0).toInt();
1446 }
1447 
setTransSelFilter(const int index)1448 void Preferences::setTransSelFilter(const int index)
1449 {
1450     setValue("TransferListFilters/selectedFilterIndex", index);
1451 }
1452 
getTransHeaderState() const1453 QByteArray Preferences::getTransHeaderState() const
1454 {
1455     return value("TransferList/qt5/HeaderState").toByteArray();
1456 }
1457 
setTransHeaderState(const QByteArray & state)1458 void Preferences::setTransHeaderState(const QByteArray &state)
1459 {
1460     setValue("TransferList/qt5/HeaderState", state);
1461 }
1462 
getRegexAsFilteringPatternForTransferList() const1463 bool Preferences::getRegexAsFilteringPatternForTransferList() const
1464 {
1465     return value("TransferList/UseRegexAsFilteringPattern", false).toBool();
1466 }
1467 
setRegexAsFilteringPatternForTransferList(const bool checked)1468 void Preferences::setRegexAsFilteringPatternForTransferList(const bool checked)
1469 {
1470     setValue("TransferList/UseRegexAsFilteringPattern", checked);
1471 }
1472 
1473 // From old RssSettings class
isRSSWidgetEnabled() const1474 bool Preferences::isRSSWidgetEnabled() const
1475 {
1476     return value("GUI/RSSWidget/Enabled", false).toBool();
1477 }
1478 
setRSSWidgetVisible(const bool enabled)1479 void Preferences::setRSSWidgetVisible(const bool enabled)
1480 {
1481     setValue("GUI/RSSWidget/Enabled", enabled);
1482 }
1483 
getToolbarTextPosition() const1484 int Preferences::getToolbarTextPosition() const
1485 {
1486     return value("Toolbar/textPosition", -1).toInt();
1487 }
1488 
setToolbarTextPosition(const int position)1489 void Preferences::setToolbarTextPosition(const int position)
1490 {
1491     setValue("Toolbar/textPosition", position);
1492 }
1493 
getNetworkCookies() const1494 QList<QNetworkCookie> Preferences::getNetworkCookies() const
1495 {
1496     QList<QNetworkCookie> cookies;
1497     const QStringList rawCookies = value("Network/Cookies").toStringList();
1498     for (const QString &rawCookie : rawCookies)
1499         cookies << QNetworkCookie::parseCookies(rawCookie.toUtf8());
1500 
1501     return cookies;
1502 }
1503 
setNetworkCookies(const QList<QNetworkCookie> & cookies)1504 void Preferences::setNetworkCookies(const QList<QNetworkCookie> &cookies)
1505 {
1506     QStringList rawCookies;
1507     for (const QNetworkCookie &cookie : cookies)
1508         rawCookies << cookie.toRawForm();
1509 
1510     setValue("Network/Cookies", rawCookies);
1511 }
1512 
isSpeedWidgetEnabled() const1513 bool Preferences::isSpeedWidgetEnabled() const
1514 {
1515     return value("SpeedWidget/Enabled", true).toBool();
1516 }
1517 
setSpeedWidgetEnabled(const bool enabled)1518 void Preferences::setSpeedWidgetEnabled(const bool enabled)
1519 {
1520     setValue("SpeedWidget/Enabled", enabled);
1521 }
1522 
getSpeedWidgetPeriod() const1523 int Preferences::getSpeedWidgetPeriod() const
1524 {
1525     return value("SpeedWidget/period", 1).toInt();
1526 }
1527 
setSpeedWidgetPeriod(const int period)1528 void Preferences::setSpeedWidgetPeriod(const int period)
1529 {
1530     setValue("SpeedWidget/period", period);
1531 }
1532 
getSpeedWidgetGraphEnable(const int id) const1533 bool Preferences::getSpeedWidgetGraphEnable(const int id) const
1534 {
1535     // UP and DOWN graphs enabled by default
1536     return value("SpeedWidget/graph_enable_" + QString::number(id), (id == 0 || id == 1)).toBool();
1537 }
1538 
setSpeedWidgetGraphEnable(const int id,const bool enable)1539 void Preferences::setSpeedWidgetGraphEnable(const int id, const bool enable)
1540 {
1541     setValue("SpeedWidget/graph_enable_" + QString::number(id), enable);
1542 }
1543 
apply()1544 void Preferences::apply()
1545 {
1546     if (SettingsStorage::instance()->save())
1547         emit changed();
1548 }
1549