1 /*
2 * Cantata
3 *
4 * Copyright (c) 2011-2020 Craig Drummond <craig.p.drummond@gmail.com>
5 *
6 * ----
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
24 #include "settings.h"
25 #include "models/sqllibrarymodel.h"
26 #include "support/fancytabwidget.h"
27 #include "widgets/itemview.h"
28 #include "mpd-interface/mpdparseutils.h"
29 #include "support/utils.h"
30 #include "support/globalstatic.h"
31 #include "db/librarydb.h"
32 #include <QFile>
33 #include <QDir>
34 #include <qglobal.h>
35
36 GLOBAL_STATIC(Settings, instance)
37
38 struct MpdDefaults
39 {
MpdDefaultsMpdDefaults40 MpdDefaults()
41 : host("localhost")
42 , dir("/var/lib/mpd/music/")
43 , port(6600) {
44 }
45
getValMpdDefaults46 static QString getVal(const QString &line) {
47 QStringList parts=line.split('\"');
48 return parts.count()>1 ? parts[1] : QString();
49 }
50
51 enum Details {
52 DT_DIR = 0x01,
53 DT_ADDR = 0x02,
54 DT_PORT = 0x04,
55 DT_PASSWD = 0x08,
56
57 DT_ALL = DT_DIR|DT_ADDR|DT_PORT|DT_PASSWD
58 };
59
readMpdDefaults60 void read() {
61 QFile f("/etc/mpd.conf");
62
63 if (f.open(QIODevice::ReadOnly|QIODevice::Text)) {
64 int details=0;
65 while (!f.atEnd()) {
66 QString line = QString::fromUtf8(f.readLine()).trimmed();
67 if (line.startsWith('#')) {
68 continue;
69 } else if (!(details&DT_DIR) && line.startsWith(QLatin1String("music_directory"))) {
70 QString val=getVal(line);
71 if (!val.isEmpty() && QDir(val).exists()) {
72 dir=Utils::fixPath(val);
73 details|=DT_DIR;
74 }
75 } else if (!(details&DT_ADDR) && line.startsWith(QLatin1String("bind_to_address"))) {
76 QString val=getVal(line);
77 if (!val.isEmpty() && val!=QLatin1String("any")) {
78 host=val;
79 details|=DT_ADDR;
80 }
81 } else if (!(details&DT_PORT) && line.startsWith(QLatin1String("port"))) {
82 int val=getVal(line).toInt();
83 if (val>0) {
84 port=val;
85 details|=DT_PORT;
86 }
87 } else if (!(details&DT_PASSWD) && line.startsWith(QLatin1String("password"))) {
88 QString val=getVal(line);
89 if (!val.isEmpty()) {
90 QStringList parts=val.split('@');
91 if (!parts.isEmpty()) {
92 passwd=parts[0];
93 details|=DT_PASSWD;
94 }
95 }
96 }
97 if (details==DT_ALL) {
98 break;
99 }
100 }
101 }
102 }
103
104 QString host;
105 QString dir;
106 QString passwd;
107 int port;
108 };
109
110 static MpdDefaults mpdDefaults;
111
getStartupStateStr(Settings::StartupState s)112 static QString getStartupStateStr(Settings::StartupState s)
113 {
114 switch (s) {
115 case Settings::SS_ShowMainWindow: return QLatin1String("show");
116 case Settings::SS_HideMainWindow: return QLatin1String("hide");
117 default:
118 case Settings::SS_Previous: return QLatin1String("prev");
119 }
120 }
121
getStartupState(const QString & str)122 static Settings::StartupState getStartupState(const QString &str)
123 {
124 for (int i=0; i<=Settings::SS_Previous; ++i) {
125 if (getStartupStateStr((Settings::StartupState)i)==str) {
126 return (Settings::StartupState)i;
127 }
128 }
129 return Settings::SS_Previous;
130 }
131
Settings()132 Settings::Settings()
133 : state(AP_Configured)
134 , ver(-1)
135 {
136 // Call 'version' so that it initialises 'ver' and 'state'
137 version();
138 // Only need to read system defaults if we have not previously been configured...
139 if (!cfg.hasGroup(MPDConnectionDetails::configGroupName())) {
140 mpdDefaults.read();
141 }
142 }
143
~Settings()144 Settings::~Settings()
145 {
146 save();
147 }
148
currentConnection()149 QString Settings::currentConnection()
150 {
151 return cfg.get("currentConnection", QString());
152 }
153
connectionDetails(const QString & name)154 MPDConnectionDetails Settings::connectionDetails(const QString &name)
155 {
156 MPDConnectionDetails details;
157 QString n=MPDConnectionDetails::configGroupName(name);
158 details.name=name;
159 if (!cfg.hasGroup(n)) {
160 details.name=QString();
161 n=MPDConnectionDetails::configGroupName(details.name);
162 }
163 if (cfg.hasGroup(n)) {
164 Configuration grp(n);
165 details.hostname=grp.get("host", name.isEmpty() ? mpdDefaults.host : QString());
166 details.port=grp.get("port", name.isEmpty() ? mpdDefaults.port : 6600);
167 details.dir=grp.getDirPath("dir", name.isEmpty() ? mpdDefaults.dir : "/var/lib/mpd/music");
168 details.password=grp.get("passwd", name.isEmpty() ? mpdDefaults.passwd : QString());
169 #ifdef ENABLE_HTTP_STREAM_PLAYBACK
170 details.streamUrl=grp.get("streamUrl", QString());
171 #endif
172 details.replayGain=grp.get("replayGain", QString());
173 details.applyReplayGain=grp.get("applyReplayGain", true);
174 // if the setting hasn't been set before, we set it to true to allow
175 // for easy migration of existing settings
176 details.allowLocalStreaming=grp.get("allowLocalStreaming", true);
177 details.autoUpdate=grp.get("autoUpdate", false);
178 } else {
179 details.hostname=mpdDefaults.host;
180 details.port=mpdDefaults.port;
181 details.dir=mpdDefaults.dir;
182 details.password=mpdDefaults.passwd;
183 #ifdef ENABLE_HTTP_STREAM_PLAYBACK
184 details.streamUrl=QString();
185 #endif
186 details.applyReplayGain=true;
187 details.allowLocalStreaming=true;
188 details.autoUpdate=false;
189 }
190 details.setDirReadable();
191 return details;
192 }
193
allConnections()194 QList<MPDConnectionDetails> Settings::allConnections()
195 {
196 QStringList groups=cfg.childGroups();
197 QList<MPDConnectionDetails> connections;
198 for (const QString &grp: groups) {
199 if (cfg.hasGroup(grp) && grp.startsWith("Connection")) {
200 connections.append(connectionDetails(grp=="Connection" ? QString() : grp.mid(11)));
201 }
202 }
203
204 if (connections.isEmpty()) {
205 // If we are empty, add at lease the default connection...
206 connections.append(connectionDetails());
207 }
208 return connections;
209 }
210
showPlaylist()211 bool Settings::showPlaylist()
212 {
213 return cfg.get("showPlaylist", true);
214 }
215
showFullScreen()216 bool Settings::showFullScreen()
217 {
218 return cfg.get("showFullScreen", false);
219 }
220
headerState(const QString & key)221 QByteArray Settings::headerState(const QString &key)
222 {
223 if (version()<CANTATA_MAKE_VERSION(1, 2, 54)) {
224 return QByteArray();
225 }
226 return cfg.get(key+"HeaderState", QByteArray());
227 }
228
splitterState()229 QByteArray Settings::splitterState()
230 {
231 return cfg.get("splitterState", QByteArray());
232 }
233
splitterAutoHide()234 bool Settings::splitterAutoHide()
235 {
236 return cfg.get("splitterAutoHide", false);
237 }
238
mainWindowSize()239 QSize Settings::mainWindowSize()
240 {
241 return cfg.get("mainWindowSize", QSize());
242 }
243
mainWindowCollapsedSize()244 QSize Settings::mainWindowCollapsedSize()
245 {
246 return cfg.get("mainWindowCollapsedSize", QSize());
247 }
248
maximized()249 bool Settings::maximized()
250 {
251 return cfg.get("maximized", false);
252 }
253
useSystemTray()254 bool Settings::useSystemTray()
255 {
256 return cfg.get("useSystemTray", false);
257 }
258
minimiseOnClose()259 bool Settings::minimiseOnClose()
260 {
261 return cfg.get("minimiseOnClose", true);
262 }
263
showPopups()264 bool Settings::showPopups()
265 {
266 return cfg.get("showPopups", false);
267 }
268
stopOnExit()269 bool Settings::stopOnExit()
270 {
271 return cfg.get("stopOnExit", false);
272 }
273
storeCoversInMpdDir()274 bool Settings::storeCoversInMpdDir()
275 {
276 return cfg.get("storeCoversInMpdDir", false);
277 }
278
storeLyricsInMpdDir()279 bool Settings::storeLyricsInMpdDir()
280 {
281 return cfg.get("storeLyricsInMpdDir", false);
282 }
283
coverFilename()284 QString Settings::coverFilename()
285 {
286 QString name=cfg.get("coverFilename", QString());
287 // name is empty, so for old configs try to get from MPD settings
288 if (name.isEmpty() && version()<CANTATA_MAKE_VERSION(2, 2, 51)) {
289 QStringList groups=cfg.childGroups();
290 QList<MPDConnectionDetails> connections;
291 for (const QString &grp: groups) {
292 if (cfg.hasGroup(grp) && grp.startsWith("Connection")) {
293 Configuration cfg(grp);
294 name=cfg.get("coverName", QString());
295 if (!name.isEmpty()) {
296 // Use 1st non-empty
297 saveCoverFilename(name);
298 return name;
299 }
300 }
301 }
302 }
303 return name;
304 }
305
sidebar()306 int Settings::sidebar()
307 {
308 if (version()<CANTATA_MAKE_VERSION(1, 2, 52)) {
309 return (int)(FancyTabWidget::Side|FancyTabWidget::Large);
310 } else {
311 return cfg.get("sidebar", (int)(FancyTabWidget::Side|FancyTabWidget::Large))&FancyTabWidget::All_Mask;
312 }
313 }
314
composerGenres()315 QSet<QString> Settings::composerGenres()
316 {
317 return cfg.get("composerGenres", Song::composerGenres().toList()).toSet();
318 }
319
singleTracksFolders()320 QSet<QString> Settings::singleTracksFolders()
321 {
322 return cfg.get("singleTracksFolders", QStringList()).toSet();
323 }
324
cueSupport()325 MPDParseUtils::CueSupport Settings::cueSupport()
326 {
327 return MPDParseUtils::toCueSupport(cfg.get("cueSupport", MPDParseUtils::toStr(MPDParseUtils::Cue_Parse)));
328 }
329
lyricProviders()330 QStringList Settings::lyricProviders()
331 {
332 return cfg.get("lyricProviders", QStringList() << "azlyrics.com" << "chartlyrics.com" << "lyrics.wikia.com");
333 }
334
wikipediaLangs()335 QStringList Settings::wikipediaLangs()
336 {
337 return cfg.get("wikipediaLangs", QStringList() << "en:en");
338 }
339
wikipediaIntroOnly()340 bool Settings::wikipediaIntroOnly()
341 {
342 return cfg.get("wikipediaIntroOnly", true);
343 }
344
contextBackdrop()345 int Settings::contextBackdrop()
346 {
347 return getBoolAsInt("contextBackdrop", 0);
348 }
349
contextBackdropOpacity()350 int Settings::contextBackdropOpacity()
351 {
352 return cfg.get("contextBackdropOpacity", 15, 0, 100);
353 }
354
contextBackdropBlur()355 int Settings::contextBackdropBlur()
356 {
357 return cfg.get("contextBackdropBlur", 0, 0, 20);
358 }
359
contextBackdropFile()360 QString Settings::contextBackdropFile()
361 {
362 return cfg.getFilePath("contextBackdropFile", QString());
363 }
364
contextDarkBackground()365 bool Settings::contextDarkBackground()
366 {
367 return cfg.get("contextDarkBackground", false);
368 }
369
contextZoom()370 int Settings::contextZoom()
371 {
372 return cfg.get("contextZoom", 0);
373 }
374
contextSlimPage()375 QString Settings::contextSlimPage()
376 {
377 return cfg.get("contextSlimPage", QString());
378 }
379
contextSplitterState()380 QByteArray Settings::contextSplitterState()
381 {
382 return version()<CANTATA_MAKE_VERSION(1, 3, 51) ? QByteArray() : cfg.get("contextSplitterState", QByteArray());
383 }
384
contextAlwaysCollapsed()385 bool Settings::contextAlwaysCollapsed()
386 {
387 return cfg.get("contextAlwaysCollapsed", false);
388 }
389
contextSwitchTime()390 int Settings::contextSwitchTime()
391 {
392 return cfg.get("contextSwitchTime", 0, 0, 5000);
393 }
394
contextAutoScroll()395 bool Settings::contextAutoScroll()
396 {
397 return cfg.get("contextAutoScroll", false);
398 }
399
contextTrackView()400 int Settings::contextTrackView()
401 {
402 return cfg.get("contextTrackView", 0);
403 }
404
page()405 QString Settings::page()
406 {
407 return cfg.get("page", QString());
408 }
409
hiddenPages()410 QStringList Settings::hiddenPages()
411 {
412 QStringList config=cfg.get("hiddenPages", QStringList() << "PlayQueuePage" << "ContextPage");
413 // If splitter auto-hide is enabled, then playqueue cannot be in sidebar!
414 if (splitterAutoHide() && !config.contains("PlayQueuePage")) {
415 config << "PlayQueuePage";
416 }
417 return config;
418 }
419
420 #ifdef ENABLE_DEVICES_SUPPORT
overwriteSongs()421 bool Settings::overwriteSongs()
422 {
423 return cfg.get("overwriteSongs", false);
424 }
425
showDeleteAction()426 bool Settings::showDeleteAction()
427 {
428 return cfg.get("showDeleteAction", false);
429 }
430 #endif
431
version()432 int Settings::version()
433 {
434 if (-1==ver) {
435 state=cfg.hasEntry("version") ? AP_Configured : AP_FirstRun;
436 QStringList parts=cfg.get("version", QLatin1String(PACKAGE_VERSION_STRING)).split('.');
437 if (3==parts.size()) {
438 ver=CANTATA_MAKE_VERSION(parts.at(0).toInt(), parts.at(1).toInt(), parts.at(2).toInt());
439 } else {
440 ver=PACKAGE_VERSION;
441 cfg.set("version", PACKAGE_VERSION_STRING);
442 }
443 }
444 return ver;
445 }
446
stopFadeDuration()447 int Settings::stopFadeDuration()
448 {
449 return cfg.get("stopFadeDuration", (int)MPDConnection::DefaultFade, (int)MPDConnection::MinFade, (int)MPDConnection::MaxFade);
450 }
451
httpAllocatedPort()452 int Settings::httpAllocatedPort()
453 {
454 return cfg.get("httpAllocatedPort", 0);
455 }
456
httpInterface()457 QString Settings::httpInterface()
458 {
459 return cfg.get("httpInterface", QString());
460 }
461
playQueueView()462 int Settings::playQueueView()
463 {
464 if (version()<CANTATA_MAKE_VERSION(1, 3, 53)) {
465 return cfg.get("playQueueGrouped", true) ? ItemView::Mode_GroupedTree : ItemView::Mode_Table;
466 }
467 return ItemView::toMode(cfg.get("playQueueView", ItemView::modeStr(ItemView::Mode_GroupedTree)));
468 }
469
playQueueAutoExpand()470 bool Settings::playQueueAutoExpand()
471 {
472 return cfg.get("playQueueAutoExpand", true);
473 }
474
playQueueStartClosed()475 bool Settings::playQueueStartClosed()
476 {
477 return cfg.get("playQueueStartClosed", false);
478 }
479
playQueueScroll()480 bool Settings::playQueueScroll()
481 {
482 return cfg.get("playQueueScroll", true);
483 }
484
playQueueBackground()485 int Settings::playQueueBackground()
486 {
487 return getBoolAsInt("playQueueBackground", 0);
488 }
489
playQueueBackgroundOpacity()490 int Settings::playQueueBackgroundOpacity()
491 {
492 return cfg.get("playQueueBackgroundOpacity", 15, 0, 100);
493 }
494
playQueueBackgroundBlur()495 int Settings::playQueueBackgroundBlur()
496 {
497 return cfg.get("playQueueBackgroundBlur", 0, 0, 20);
498 }
499
playQueueBackgroundFile()500 QString Settings::playQueueBackgroundFile()
501 {
502 return cfg.getFilePath("playQueueBackgroundFile", QString());
503 }
504
playQueueConfirmClear()505 bool Settings::playQueueConfirmClear()
506 {
507 return cfg.get("playQueueConfirmClear", false);
508 }
509
playQueueSearch()510 bool Settings::playQueueSearch()
511 {
512 return cfg.get("playQueueSearch", true);
513 }
514
playListsStartClosed()515 bool Settings::playListsStartClosed()
516 {
517 return cfg.get("playListsStartClosed", true);
518 }
519
520 #ifdef ENABLE_HTTP_STREAM_PLAYBACK
playStream()521 bool Settings::playStream()
522 {
523 return cfg.get("playStream", false);
524 }
525 #endif
526
527 #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND
cdAuto()528 bool Settings::cdAuto()
529 {
530 return cfg.get("cdAuto", true);
531 }
532
paranoiaFull()533 bool Settings::paranoiaFull()
534 {
535 return cfg.get("paranoiaFull", true);
536 }
537
paranoiaNeverSkip()538 bool Settings::paranoiaNeverSkip()
539 {
540 return cfg.get("paranoiaNeverSkip", true);
541 }
542
paranoiaOffset()543 int Settings::paranoiaOffset()
544 {
545 return cfg.get("paranoiaOffset", 0);
546 }
547 #endif
548
549 #if defined CDDB_FOUND && defined MUSICBRAINZ5_FOUND
useCddb()550 bool Settings::useCddb()
551 {
552 return cfg.get("useCddb", true);
553 }
554 #endif
555
556 #ifdef CDDB_FOUND
cddbHost()557 QString Settings::cddbHost()
558 {
559 return cfg.get("cddbHost", QString("gnudb.gnudb.org"));
560 }
561
cddbPort()562 int Settings::cddbPort()
563 {
564 return cfg.get("cddbPort", 80);
565 }
566 #endif
567
forceSingleClick()568 bool Settings::forceSingleClick()
569 {
570 return cfg.get("forceSingleClick", true);
571 }
572
startHidden()573 bool Settings::startHidden()
574 {
575 return useSystemTray() ? cfg.get("startHidden", false) : false;
576 }
577
showTimeRemaining()578 bool Settings::showTimeRemaining()
579 {
580 return cfg.get("showTimeRemaining", false);
581 }
582
hiddenStreamCategories()583 QStringList Settings::hiddenStreamCategories()
584 {
585 return cfg.get("hiddenStreamCategories", QStringList());
586 }
587
hiddenOnlineProviders()588 QStringList Settings::hiddenOnlineProviders()
589 {
590 return cfg.get("hiddenOnlineProviders", QStringList());
591 }
592
593 #if (defined Q_OS_LINUX && defined QT_QTDBUS_FOUND) || (defined Q_OS_MAC && defined IOKIT_FOUND)
inhibitSuspend()594 bool Settings::inhibitSuspend()
595 {
596 return cfg.get("inhibitSuspend", false);
597 }
598 #endif
599
rssUpdate()600 int Settings::rssUpdate()
601 {
602 return cfg.get("rssUpdate", 0, 0, 7*24*60);
603 }
604
lastRssUpdate()605 QDateTime Settings::lastRssUpdate()
606 {
607 return cfg.get("lastRssUpdate", QDateTime());
608 }
609
podcastDownloadPath()610 QString Settings::podcastDownloadPath()
611 {
612 return Utils::fixPath(cfg.get("podcastDownloadPath", Utils::fixPath(QDir::homePath())+QLatin1String("Podcasts/")));
613 }
614
podcastAutoDownloadLimit()615 int Settings::podcastAutoDownloadLimit()
616 {
617 if (cfg.hasEntry("podcastAutoDownload")) {
618 return cfg.get("podcastAutoDownload", false) ? 1000 : 0;
619 }
620 return cfg.get("podcastAutoDownloadLimit", 0, 0, 1000);
621 }
622
volumeStep()623 int Settings::volumeStep()
624 {
625 return cfg.get("volumeStep", 5, 1, 20);
626 }
627
startupState()628 Settings::StartupState Settings::startupState()
629 {
630 return getStartupState(cfg.get("startupState", getStartupStateStr(SS_Previous)));
631 }
632
searchCategory()633 QString Settings::searchCategory()
634 {
635 return cfg.get("searchCategory", QString());
636 }
637
fetchCovers()638 bool Settings::fetchCovers()
639 {
640 return cfg.get("fetchCovers", true);
641 }
642
lang()643 QString Settings::lang()
644 {
645 return cfg.get("lang", QString());
646 }
647
showCoverWidget()648 bool Settings::showCoverWidget()
649 {
650 return cfg.get("showCoverWidget", true);
651 }
652
showStopButton()653 bool Settings::showStopButton()
654 {
655 return cfg.get("showStopButton", false);
656 }
657
showRatingWidget()658 bool Settings::showRatingWidget()
659 {
660 return cfg.get("showRatingWidget", false);
661 }
662
showTechnicalInfo()663 bool Settings::showTechnicalInfo()
664 {
665 return cfg.get("showTechnicalInfo", false);
666 }
667
infoTooltips()668 bool Settings::infoTooltips()
669 {
670 return cfg.get("infoTooltips", true);
671 }
672
ignorePrefixes()673 QSet<QString> Settings::ignorePrefixes()
674 {
675 return cfg.get("ignorePrefixes", Song::ignorePrefixes().toList()).toSet();
676 }
677
mpris()678 bool Settings::mpris()
679 {
680 return cfg.get("mpris", true);
681 }
682
style()683 QString Settings::style()
684 {
685 return cfg.get("style", QString());
686 }
687
688 #if !defined Q_OS_WIN && !defined Q_OS_MAC
showMenubar()689 bool Settings::showMenubar()
690 {
691 return cfg.get("showMenubar", false);
692 }
693 #endif
694
useOriginalYear()695 bool Settings::useOriginalYear()
696 {
697 return cfg.get("useOriginalYear", false);
698 }
699
responsiveSidebar()700 bool Settings::responsiveSidebar()
701 {
702 return cfg.get("responsiveSidebar", true);
703 }
704
removeConnectionDetails(const QString & v)705 void Settings::removeConnectionDetails(const QString &v)
706 {
707 if (v==currentConnection()) {
708 saveCurrentConnection(QString());
709 }
710 cfg.removeGroup(MPDConnectionDetails::configGroupName(v));
711 }
712
saveConnectionDetails(const MPDConnectionDetails & v)713 void Settings::saveConnectionDetails(const MPDConnectionDetails &v)
714 {
715 if (v.name.isEmpty()) {
716 cfg.removeEntry("connectionHost");
717 cfg.removeEntry("connectionPasswd");
718 cfg.removeEntry("connectionPort");
719 cfg.removeEntry("mpdDir");
720 }
721
722 QString n=MPDConnectionDetails::configGroupName(v.name);
723 Configuration grp(n);
724 grp.set("host", v.hostname);
725 grp.set("port", (int)v.port);
726 if (v.dir.startsWith("http:", Qt::CaseInsensitive) || v.dir.startsWith("https:", Qt::CaseInsensitive)) {
727 grp.set("dir", v.dir);
728 } else {
729 grp.setDirPath("dir", v.dir);
730 }
731 grp.set("passwd", v.password);
732 #ifdef ENABLE_HTTP_STREAM_PLAYBACK
733 grp.set("streamUrl", v.streamUrl);
734 #endif
735 grp.set("applyReplayGain", v.applyReplayGain);
736 grp.set("allowLocalStreaming", v.allowLocalStreaming);
737 grp.set("autoUpdate", v.autoUpdate);
738 }
739
saveCurrentConnection(const QString & v)740 void Settings::saveCurrentConnection(const QString &v)
741 {
742 cfg.set("currentConnection", v);
743 }
744
saveShowFullScreen(bool v)745 void Settings::saveShowFullScreen(bool v)
746 {
747 cfg.set("showFullScreen", v);
748 }
749
saveShowPlaylist(bool v)750 void Settings::saveShowPlaylist(bool v)
751 {
752 cfg.set("showPlaylist", v);
753 }
754
saveHeaderState(const QString & key,const QByteArray & v)755 void Settings::saveHeaderState(const QString &key, const QByteArray &v)
756 {
757 cfg.set(key+"HeaderState", v);
758 }
759
saveSplitterState(const QByteArray & v)760 void Settings::saveSplitterState(const QByteArray &v)
761 {
762 cfg.set("splitterState", v);
763 }
764
saveSplitterAutoHide(bool v)765 void Settings::saveSplitterAutoHide(bool v)
766 {
767 cfg.set("splitterAutoHide", v);
768 }
769
saveMainWindowSize(const QSize & v)770 void Settings::saveMainWindowSize(const QSize &v)
771 {
772 cfg.set("mainWindowSize", v);
773 }
774
saveMaximized(bool v)775 void Settings::saveMaximized(bool v)
776 {
777 cfg.set("maximized", v);
778 }
779
saveMainWindowCollapsedSize(const QSize & v)780 void Settings::saveMainWindowCollapsedSize(const QSize &v)
781 {
782 if (v.width()>16 && v.height()>16) {
783 cfg.set("mainWindowCollapsedSize", v);
784 }
785 }
786
saveUseSystemTray(bool v)787 void Settings::saveUseSystemTray(bool v)
788 {
789 cfg.set("useSystemTray", v);
790 }
791
saveMinimiseOnClose(bool v)792 void Settings::saveMinimiseOnClose(bool v)
793 {
794 cfg.set("minimiseOnClose", v);
795 }
796
saveShowPopups(bool v)797 void Settings::saveShowPopups(bool v)
798 {
799 cfg.set("showPopups", v);
800 }
801
saveStopOnExit(bool v)802 void Settings::saveStopOnExit(bool v)
803 {
804 cfg.set("stopOnExit", v);
805 }
806
saveStoreCoversInMpdDir(bool v)807 void Settings::saveStoreCoversInMpdDir(bool v)
808 {
809 cfg.set("storeCoversInMpdDir", v);
810 }
811
saveStoreLyricsInMpdDir(bool v)812 void Settings::saveStoreLyricsInMpdDir(bool v)
813 {
814 cfg.set("storeLyricsInMpdDir", v);
815 }
816
saveCoverFilename(const QString & v)817 void Settings::saveCoverFilename(const QString &v)
818 {
819 cfg.set("coverFilename", v);
820 }
821
saveSidebar(int v)822 void Settings::saveSidebar(int v)
823 {
824 cfg.set("sidebar", v);
825 }
826
saveComposerGenres(const QSet<QString> & v)827 void Settings::saveComposerGenres(const QSet<QString> &v)
828 {
829 cfg.set("composerGenres", v.toList());
830 }
831
saveSingleTracksFolders(const QSet<QString> & v)832 void Settings::saveSingleTracksFolders(const QSet<QString> &v)
833 {
834 cfg.set("singleTracksFolders", v.toList());
835 }
836
saveCueSupport(MPDParseUtils::CueSupport v)837 void Settings::saveCueSupport(MPDParseUtils::CueSupport v)
838 {
839 cfg.set("cueSupport", MPDParseUtils::toStr(v));
840 }
841
saveLyricProviders(const QStringList & v)842 void Settings::saveLyricProviders(const QStringList &v)
843 {
844 cfg.set("lyricProviders", v);
845 }
846
saveWikipediaLangs(const QStringList & v)847 void Settings::saveWikipediaLangs(const QStringList &v)
848 {
849 cfg.set("wikipediaLangs", v);
850 }
851
saveWikipediaIntroOnly(bool v)852 void Settings::saveWikipediaIntroOnly(bool v)
853 {
854 cfg.set("wikipediaIntroOnly", v);
855 }
856
saveContextBackdrop(int v)857 void Settings::saveContextBackdrop(int v)
858 {
859 cfg.set("contextBackdrop", v);
860 }
861
saveContextBackdropOpacity(int v)862 void Settings::saveContextBackdropOpacity(int v)
863 {
864 cfg.set("contextBackdropOpacity", v);
865 }
866
saveContextBackdropBlur(int v)867 void Settings::saveContextBackdropBlur(int v)
868 {
869 cfg.set("contextBackdropBlur", v);
870 }
871
saveContextBackdropFile(const QString & v)872 void Settings::saveContextBackdropFile(const QString &v)
873 {
874 cfg.setFilePath("contextBackdropFile", v);
875 }
876
saveContextDarkBackground(bool v)877 void Settings::saveContextDarkBackground(bool v)
878 {
879 cfg.set("contextDarkBackground", v);
880 }
881
saveContextZoom(int v)882 void Settings::saveContextZoom(int v)
883 {
884 cfg.set("contextZoom", v);
885 }
886
saveContextSlimPage(const QString & v)887 void Settings::saveContextSlimPage(const QString &v)
888 {
889 cfg.set("contextSlimPage", v);
890 }
891
saveContextSplitterState(const QByteArray & v)892 void Settings::saveContextSplitterState(const QByteArray &v)
893 {
894 cfg.set("contextSplitterState", v);
895 }
896
saveContextAlwaysCollapsed(bool v)897 void Settings::saveContextAlwaysCollapsed(bool v)
898 {
899 cfg.set("contextAlwaysCollapsed", v);
900 }
901
saveContextSwitchTime(int v)902 void Settings::saveContextSwitchTime(int v)
903 {
904 cfg.set("contextSwitchTime", v);
905 }
906
saveContextAutoScroll(bool v)907 void Settings::saveContextAutoScroll(bool v)
908 {
909 cfg.set("contextAutoScroll", v);
910 }
911
saveContextTrackView(int v)912 void Settings::saveContextTrackView(int v)
913 {
914 cfg.set("contextTrackView", v);
915 }
916
savePage(const QString & v)917 void Settings::savePage(const QString &v)
918 {
919 cfg.set("page", v);
920 }
921
saveHiddenPages(const QStringList & v)922 void Settings::saveHiddenPages(const QStringList &v)
923 {
924 cfg.set("hiddenPages", v);
925 }
926
927 #ifdef ENABLE_DEVICES_SUPPORT
saveOverwriteSongs(bool v)928 void Settings::saveOverwriteSongs(bool v)
929 {
930 cfg.set("overwriteSongs", v);
931 }
932
saveShowDeleteAction(bool v)933 void Settings::saveShowDeleteAction(bool v)
934 {
935 cfg.set("showDeleteAction", v);
936 }
937 #endif
938
saveStopFadeDuration(int v)939 void Settings::saveStopFadeDuration(int v)
940 {
941 cfg.set("stopFadeDuration", v);
942 }
943
saveHttpAllocatedPort(int v)944 void Settings::saveHttpAllocatedPort(int v)
945 {
946 cfg.set("httpAllocatedPort", v);
947 }
948
saveHttpInterface(const QString & v)949 void Settings::saveHttpInterface(const QString &v)
950 {
951 cfg.set("httpInterface", v);
952 }
953
savePlayQueueView(int v)954 void Settings::savePlayQueueView(int v)
955 {
956 cfg.set("playQueueView", ItemView::modeStr((ItemView::Mode)v));
957 }
958
savePlayQueueAutoExpand(bool v)959 void Settings::savePlayQueueAutoExpand(bool v)
960 {
961 cfg.set("playQueueAutoExpand", v);
962 }
963
savePlayQueueStartClosed(bool v)964 void Settings::savePlayQueueStartClosed(bool v)
965 {
966 cfg.set("playQueueStartClosed", v);
967 }
968
savePlayQueueScroll(bool v)969 void Settings::savePlayQueueScroll(bool v)
970 {
971 cfg.set("playQueueScroll", v);
972 }
973
savePlayQueueBackground(int v)974 void Settings::savePlayQueueBackground(int v)
975 {
976 cfg.set("playQueueBackground", v);
977 }
978
savePlayQueueBackgroundOpacity(int v)979 void Settings::savePlayQueueBackgroundOpacity(int v)
980 {
981 cfg.set("playQueueBackgroundOpacity", v);
982 }
983
savePlayQueueBackgroundBlur(int v)984 void Settings::savePlayQueueBackgroundBlur(int v)
985 {
986 cfg.set("playQueueBackgroundBlur", v);
987 }
988
savePlayQueueBackgroundFile(const QString & v)989 void Settings::savePlayQueueBackgroundFile(const QString &v)
990 {
991 cfg.setFilePath("playQueueBackgroundFile", v);
992 }
993
savePlayQueueConfirmClear(bool v)994 void Settings::savePlayQueueConfirmClear(bool v)
995 {
996 cfg.set("playQueueConfirmClear", v);
997 }
998
savePlayQueueSearch(bool v)999 void Settings::savePlayQueueSearch(bool v)
1000 {
1001 cfg.set("playQueueSearch", v);
1002 }
1003
savePlayListsStartClosed(bool v)1004 void Settings::savePlayListsStartClosed(bool v)
1005 {
1006 cfg.set("playListsStartClosed", v);
1007 }
1008
1009 #ifdef ENABLE_HTTP_STREAM_PLAYBACK
savePlayStream(bool v)1010 void Settings::savePlayStream(bool v)
1011 {
1012 cfg.set("playStream", v);
1013 }
1014 #endif
1015
1016 #if defined CDDB_FOUND || defined MUSICBRAINZ5_FOUND
saveCdAuto(bool v)1017 void Settings::saveCdAuto(bool v)
1018 {
1019 cfg.set("cdAuto", v);
1020 }
1021
saveParanoiaFull(bool v)1022 void Settings::saveParanoiaFull(bool v)
1023 {
1024 cfg.set("paranoiaFull", v);
1025 }
1026
saveParanoiaNeverSkip(bool v)1027 void Settings::saveParanoiaNeverSkip(bool v)
1028 {
1029 cfg.set("paranoiaNeverSkip", v);
1030 }
1031
saveParanoiaOffset(int v)1032 void Settings::saveParanoiaOffset(int v)
1033 {
1034 cfg.set("paranoiaOffset", v);
1035 }
1036 #endif
1037
1038 #if defined CDDB_FOUND && defined MUSICBRAINZ5_FOUND
saveUseCddb(bool v)1039 void Settings::saveUseCddb(bool v)
1040 {
1041 cfg.set("useCddb", v);
1042 }
1043 #endif
1044
1045 #ifdef CDDB_FOUND
saveCddbHost(const QString & v)1046 void Settings::saveCddbHost(const QString &v)
1047 {
1048 cfg.set("cddbHost", v);
1049 }
1050
saveCddbPort(int v)1051 void Settings::saveCddbPort(int v)
1052 {
1053 cfg.set("cddbPort", v);
1054 }
1055 #endif
1056
saveForceSingleClick(bool v)1057 void Settings::saveForceSingleClick(bool v)
1058 {
1059 cfg.set("forceSingleClick", v);
1060 }
1061
saveStartHidden(bool v)1062 void Settings::saveStartHidden(bool v)
1063 {
1064 cfg.set("startHidden", v);
1065 }
1066
saveShowTimeRemaining(bool v)1067 void Settings::saveShowTimeRemaining(bool v)
1068 {
1069 cfg.set("showTimeRemaining", v);
1070 }
1071
saveHiddenStreamCategories(const QStringList & v)1072 void Settings::saveHiddenStreamCategories(const QStringList &v)
1073 {
1074 cfg.set("hiddenStreamCategories", v);
1075 }
1076
saveHiddenOnlineProviders(const QStringList & v)1077 void Settings::saveHiddenOnlineProviders(const QStringList &v)
1078 {
1079 cfg.set("hiddenOnlineProviders", v);
1080 }
1081
1082 #if (defined Q_OS_LINUX && defined QT_QTDBUS_FOUND) || (defined Q_OS_MAC && defined IOKIT_FOUND)
saveInhibitSuspend(bool v)1083 void Settings::saveInhibitSuspend(bool v)
1084 {
1085 cfg.set("inhibitSuspend", v);
1086 }
1087 #endif
1088
saveRssUpdate(int v)1089 void Settings::saveRssUpdate(int v)
1090 {
1091 cfg.set("rssUpdate", v);
1092 }
1093
saveLastRssUpdate(const QDateTime & v)1094 void Settings::saveLastRssUpdate(const QDateTime &v)
1095 {
1096 cfg.set("lastRssUpdate", v);
1097 }
1098
savePodcastDownloadPath(const QString & v)1099 void Settings::savePodcastDownloadPath(const QString &v)
1100 {
1101 cfg.set("podcastDownloadPath", v);
1102 }
1103
savePodcastAutoDownloadLimit(int v)1104 void Settings::savePodcastAutoDownloadLimit(int v)
1105 {
1106 if (cfg.hasEntry("podcastAutoDownload")) {
1107 cfg.removeEntry("podcastAutoDownload");
1108 }
1109 cfg.set("podcastAutoDownloadLimit", v);
1110 }
1111
saveVolumeStep(int v)1112 void Settings::saveVolumeStep(int v)
1113 {
1114 cfg.set("volumeStep", v);
1115 }
1116
saveStartupState(int v)1117 void Settings::saveStartupState(int v)
1118 {
1119 cfg.set("startupState", getStartupStateStr((StartupState)v));
1120 }
1121
saveSearchCategory(const QString & v)1122 void Settings::saveSearchCategory(const QString &v)
1123 {
1124 cfg.set("searchCategory", v);
1125 }
1126
saveFetchCovers(bool v)1127 void Settings::saveFetchCovers(bool v)
1128 {
1129 cfg.set("fetchCovers", v);
1130 }
1131
saveLang(const QString & v)1132 void Settings::saveLang(const QString &v)
1133 {
1134 cfg.set("lang", v);
1135 }
1136
saveShowCoverWidget(bool v)1137 void Settings::saveShowCoverWidget(bool v)
1138 {
1139 cfg.set("showCoverWidget", v);
1140 }
1141
saveShowStopButton(bool v)1142 void Settings::saveShowStopButton(bool v)
1143 {
1144 cfg.set("showStopButton", v);
1145 }
1146
saveShowRatingWidget(bool v)1147 void Settings::saveShowRatingWidget(bool v)
1148 {
1149 cfg.set("showRatingWidget", v);
1150 }
1151
saveShowTechnicalInfo(bool v)1152 void Settings::saveShowTechnicalInfo(bool v)
1153 {
1154 cfg.set("showTechnicalInfo", v);
1155 }
1156
saveInfoTooltips(bool v)1157 void Settings::saveInfoTooltips(bool v)
1158 {
1159 cfg.set("infoTooltips", v);
1160 }
1161
saveIgnorePrefixes(const QSet<QString> & v)1162 void Settings::saveIgnorePrefixes(const QSet<QString> &v)
1163 {
1164 cfg.set("ignorePrefixes", v.toList());
1165 }
1166
saveMpris(bool v)1167 void Settings::saveMpris(bool v)
1168 {
1169 cfg.set("mpris", v);
1170 }
1171
saveReplayGain(const QString & conn,const QString & v)1172 void Settings::saveReplayGain(const QString &conn, const QString &v)
1173 {
1174 QString n=MPDConnectionDetails::configGroupName(conn);
1175 Configuration grp(n);
1176 grp.set("replayGain", v);
1177 }
1178
saveStyle(const QString & v)1179 void Settings::saveStyle(const QString &v)
1180 {
1181 cfg.set("style", v);
1182 }
1183
1184 #if !defined Q_OS_WIN && !defined Q_OS_MAC
saveShowMenubar(bool v)1185 void Settings::saveShowMenubar(bool v)
1186 {
1187 cfg.set("showMenubar", v);
1188 }
1189 #endif
1190
saveUseOriginalYear(bool v)1191 void Settings::saveUseOriginalYear(bool v)
1192 {
1193 cfg.set("useOriginalYear", v);
1194 }
1195
saveResponsiveSidebar(bool v)1196 void Settings::saveResponsiveSidebar(bool v)
1197 {
1198 cfg.set("responsiveSidebar", v);
1199 }
1200
save()1201 void Settings::save()
1202 {
1203 if (AP_NotConfigured!=state) {
1204 if (version()!=PACKAGE_VERSION || AP_FirstRun==state) {
1205 cfg.set("version", PACKAGE_VERSION_STRING);
1206 ver=PACKAGE_VERSION;
1207 }
1208 }
1209 cfg.sync();
1210 }
1211
clearVersion()1212 void Settings::clearVersion()
1213 {
1214 cfg.removeEntry("version");
1215 state=AP_NotConfigured;
1216 }
1217
getBoolAsInt(const QString & key,int def)1218 int Settings::getBoolAsInt(const QString &key, int def)
1219 {
1220 // Old config, sometimes bool was used - which has now been converted
1221 // to an int...
1222 QString v=cfg.get(key, QString::number(def));
1223 if (QLatin1String("false")==v) {
1224 return 0;
1225 }
1226 if (QLatin1String("true")==v) {
1227 return 1;
1228 }
1229 return v.toInt();
1230 }
1231