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 "interfacesettings.h"
25 #include "settings.h"
26 #include "models/sqllibrarymodel.h"
27 #include "support/utils.h"
28 #include "support/fancytabwidget.h"
29 #include "support/pathrequester.h"
30 #include "widgets/basicitemdelegate.h"
31 #include "widgets/playqueueview.h"
32 #include "widgets/itemview.h"
33 #include "db/librarydb.h"
34 #include <QComboBox>
35 #include <QDir>
36 #include <QMap>
37 #include <QRegExp>
38 #include <QSet>
39 #ifdef QT_QTDBUS_FOUND
40 #include <QDBusConnection>
41 #include <QDBusConnectionInterface>
42 #endif
43 #include <QSystemTrayIcon>
44 #include <QSysInfo>
45 #include <QStyleFactory>
46 #include <algorithm>
47
48 #define REMOVE(w) \
49 w->setVisible(false); \
50 w->deleteLater(); \
51 w=0;
52
viewTypeString(ItemView::Mode mode)53 static QString viewTypeString(ItemView::Mode mode)
54 {
55 switch (mode) {
56 default:
57 case ItemView::Mode_GroupedTree: return QObject::tr("Grouped Albums");
58 case ItemView::Mode_Table: return QObject::tr("Table");
59 }
60 }
61
addViewTypes(QComboBox * box,QList<ItemView::Mode> modes)62 static void addViewTypes(QComboBox *box, QList<ItemView::Mode> modes)
63 {
64 for (ItemView::Mode m: modes) {
65 box->addItem(viewTypeString(m), m);
66 }
67 }
68
cueSupportString(MPDParseUtils::CueSupport cs)69 static QString cueSupportString(MPDParseUtils::CueSupport cs)
70 {
71 switch (cs) {
72 default:
73 case MPDParseUtils::Cue_Parse: return QObject::tr("Parse in Library view, and show in Folders view");
74 case MPDParseUtils::Cue_ListButDontParse: return QObject::tr("Only show in Folders view");
75 case MPDParseUtils::Cue_Ignore: return QObject::tr("Do not list");
76 }
77 }
78
addCueSupportTypes(QComboBox * box)79 static void addCueSupportTypes(QComboBox *box)
80 {
81 for (int i=0; i<MPDParseUtils::Cue_Count; ++i) {
82 box->addItem(cueSupportString((MPDParseUtils::CueSupport)i), i);
83 }
84 }
85
selectEntry(QComboBox * box,int v)86 static void selectEntry(QComboBox *box, int v)
87 {
88 for (int i=1; i<box->count(); ++i) {
89 if (box->itemData(i).toInt()==v) {
90 box->setCurrentIndex(i);
91 return;
92 }
93 }
94 }
95
getValue(QComboBox * box)96 static inline int getValue(QComboBox *box)
97 {
98 return box->itemData(box->currentIndex()).toInt();
99 }
100
getStrValue(QComboBox * box)101 static inline QString getStrValue(QComboBox *box)
102 {
103 return box->itemData(box->currentIndex()).toString();
104 }
105
106 static const char * constValueProperty="value";
107 static const char * constSep=",";
108
109 class CoverNameValidator : public QValidator
110 {
111 public:
112
CoverNameValidator(QObject * parent)113 CoverNameValidator(QObject *parent) : QValidator(parent) { }
114
validate(QString & input,int &) const115 State validate(QString &input, int &) const override
116 {
117 for (int i=0; i<input.length(); ++i) {
118 if (!input[i].isLetterOrNumber() && '%'!=input[i] && ' '!=input[i] && '-'!=input[i]) {
119 return Invalid;
120 }
121 }
122
123 return Acceptable;
124 }
125 };
126
InterfaceSettings(QWidget * p)127 InterfaceSettings::InterfaceSettings(QWidget *p)
128 : QWidget(p)
129 , loaded(false)
130 {
131 bool mprisSettings=false;
132 bool enableTrayItem=Utils::useSystemTray();
133 #ifdef Q_OS_MAC
134 // OSX always displays an entry in the taskbar - and the tray seems to confuse things.
135 bool enableNotifications=QSysInfo::MacintoshVersion >= QSysInfo::MV_10_8;
136 #else
137 #ifdef QT_QTDBUS_FOUND
138 // We have dbus, check that org.freedesktop.Notifications exists
139 bool enableNotifications=QDBusConnection::sessionBus().interface()->isServiceRegistered("org.freedesktop.Notifications");
140 mprisSettings=true;
141 #else // QT_QTDBUS_FOUND
142 bool enableNotifications=true;
143 #endif // QT_QTDBUS_FOUND
144 #endif // Q_MAC_OS
145
146 setupUi(this);
147 addCueSupportTypes(cueSupport);
148 addViewTypes(playQueueView, QList<ItemView::Mode>() << ItemView::Mode_GroupedTree << ItemView::Mode_Table);
149 yearTag->addItem(tr("Use 'Year' tag to display & sort"));
150 yearTag->addItem(tr("Use 'Original Year' tag to display & sort, fallback to 'Year' if not set"));
151
152 addView(tr("Play Queue"), QLatin1String("PlayQueuePage"));
153 addView(tr("Library"), QLatin1String("LibraryPage"));
154 addView(tr("Folders"), QLatin1String("FolderPage"));
155 addView(tr("Playlists"), QLatin1String("PlaylistsPage"));
156 addView(tr("Internet - Streams, Jamendo, Maganatune, SoundCloud, and Podcasts"), QLatin1String("OnlineServicesPage"));
157 #ifdef ENABLE_DEVICES_SUPPORT
158 addView(tr("Devices - UMS, MTP (e.g. Android), and AudioCDs"), QLatin1String("DevicesPage"));
159 #else
160 REMOVE(showDeleteAction)
161 #endif
162 addView(tr("Search (via MPD)"), QLatin1String("SearchPage"));
163 addView(tr("Info - Current song information (artist, album, and lyrics)"), QLatin1String("ContextPage"));
164 connect(playQueueView, SIGNAL(currentIndexChanged(int)), SLOT(playQueueViewChanged()));
165 connect(forceSingleClick, SIGNAL(toggled(bool)), SLOT(forceSingleClickChanged()));
166 connect(views, SIGNAL(itemChanged(QListWidgetItem*)), SLOT(viewItemChanged(QListWidgetItem*)));
167
168 sbStyle->addItem(tr("Large"), FancyTabWidget::Large);
169 sbStyle->addItem(tr("Small"), FancyTabWidget::Small);
170 sbStyle->addItem(tr("Tab-bar"), FancyTabWidget::Tab);
171 sbPosition->addItem(Qt::LeftToRight==layoutDirection() ? tr("Left") : tr("Right"), FancyTabWidget::Side);
172 sbPosition->addItem(tr("Top"), FancyTabWidget::Top);
173 sbPosition->addItem(tr("Bottom"), FancyTabWidget::Bot);
174 connect(sbAutoHide, SIGNAL(toggled(bool)), SLOT(sbAutoHideChanged()));
175 views->setItemDelegate(new BasicItemDelegate(views));
176 playQueueBackground_none->setProperty(constValueProperty, PlayQueueView::BI_None);
177 playQueueBackground_cover->setProperty(constValueProperty, PlayQueueView::BI_Cover);
178 playQueueBackground_custom->setProperty(constValueProperty, PlayQueueView::BI_Custom);
179 playQueueBackgroundFile->setDirMode(false);
180 playQueueBackgroundFile->setFilter(tr("Images (*.png *.jpg)"));
181 int labelWidth=qMax(fontMetrics().horizontalAdvance(QLatin1String("100%")), fontMetrics().horizontalAdvance(tr("10px", "pixels")));
182 playQueueBackgroundOpacityLabel->setFixedWidth(labelWidth);
183 playQueueBackgroundBlurLabel->setFixedWidth(labelWidth);
184 connect(playQueueBackgroundOpacity, SIGNAL(valueChanged(int)), SLOT(setPlayQueueBackgroundOpacityLabel()));
185 connect(playQueueBackgroundBlur, SIGNAL(valueChanged(int)), SLOT(setPlayQueueBackgroundBlurLabel()));
186 connect(playQueueBackground_none, SIGNAL(toggled(bool)), SLOT(enablePlayQueueBackgroundOptions()));
187 connect(playQueueBackground_cover, SIGNAL(toggled(bool)), SLOT(enablePlayQueueBackgroundOptions()));
188 connect(playQueueBackground_custom, SIGNAL(toggled(bool)), SLOT(enablePlayQueueBackgroundOptions()));
189 connect(storeCoversInMpdDir, SIGNAL(toggled(bool)), this, SLOT(storeCoversInMpdDirToggled()));
190 if (!enableNotifications) {
191 REMOVE(systemTrayPopup)
192 }
193 if (enableTrayItem) {
194 connect(systemTrayCheckBox, SIGNAL(toggled(bool)), minimiseOnClose, SLOT(setEnabled(bool)));
195 connect(systemTrayCheckBox, SIGNAL(toggled(bool)), SLOT(enableStartupState()));
196 connect(minimiseOnClose, SIGNAL(toggled(bool)), SLOT(enableStartupState()));
197 } else {
198 REMOVE(systemTrayCheckBox)
199 REMOVE(minimiseOnClose)
200 REMOVE(startupState)
201 }
202
203 if (!enableNotifications && !enableTrayItem && !mprisSettings) {
204 tabWidget->removeTab(3);
205 } else if (!enableTrayItem && enableNotifications && !mprisSettings) {
206 tabWidget->setTabText(3, tr("Notifications"));
207 }
208 if (!mprisSettings) {
209 REMOVE(enableMpris)
210 }
211 #if defined Q_OS_WIN || defined Q_OS_MAC || !defined QT_QTDBUS_FOUND
212 if (systemTrayPopup && systemTrayCheckBox) {
213 connect(systemTrayCheckBox, SIGNAL(toggled(bool)), SLOT(systemTrayCheckBoxToggled()));
214 connect(systemTrayPopup, SIGNAL(toggled(bool)), SLOT(systemTrayPopupToggled()));
215 }
216 #endif
217 coverFilenameLabel->setToolTip(coverFilename->toolTip());
218 coverFilename->setValidator(new CoverNameValidator(this));
219 #ifdef ENABLE_DEVICES_SUPPORT
220 coverNameNoteLabel->setText(tr("If no setting is specified for 'Filename', then Cantata will use a default of "
221 "<code>cover</code>. This filename is used when downloading covers, or when adding "
222 "music to your library from devices. This should be specified <b>without</b> an extension."));
223 #else
224 coverNameNoteLabel->setText(tr("If no setting is specified for 'Filename', then Cantata will use a default of "
225 "<code>cover</code>. This filename is used when downloading covers. This should be specified <b>without</b> an extension."));
226 #endif
227
228 QFont f = Utils::smallFont(ignorePrefixesLabel->font());
229 f.setItalic(true);
230 ignorePrefixesLabel->setFont(f);
231 composerGenresLabel->setFont(f);
232 singleTracksFoldersLabel->setFont(f);
233 setMinimumSize(Utils::scaleForDpi(720), Utils::scaleForDpi(620));
234 }
235
load()236 void InterfaceSettings::load()
237 {
238 ignorePrefixes->setText(QStringList(Settings::self()->ignorePrefixes().toList()).join(QString(constSep)));
239 composerGenres->setText(QStringList(Settings::self()->composerGenres().toList()).join(QString(constSep)));
240 singleTracksFolders->setText(QStringList(Settings::self()->singleTracksFolders().toList()).join(QString(constSep)));
241 selectEntry(cueSupport, Settings::self()->cueSupport());
242 yearTag->setCurrentIndex(Settings::self()->useOriginalYear() ? 1 : 0);
243 #ifdef ENABLE_DEVICES_SUPPORT
244 showDeleteAction->setChecked(Settings::self()->showDeleteAction());
245 #endif
246
247 selectEntry(playQueueView, Settings::self()->playQueueView());
248 playQueueAutoExpand->setChecked(Settings::self()->playQueueAutoExpand());
249 playQueueStartClosed->setChecked(Settings::self()->playQueueStartClosed());
250 playQueueScroll->setChecked(Settings::self()->playQueueScroll());
251
252 int pqBgnd=Settings::self()->playQueueBackground();
253 playQueueBackground_none->setChecked(pqBgnd==playQueueBackground_none->property(constValueProperty).toInt());
254 playQueueBackground_cover->setChecked(pqBgnd==playQueueBackground_cover->property(constValueProperty).toInt());
255 playQueueBackground_custom->setChecked(pqBgnd==playQueueBackground_custom->property(constValueProperty).toInt());
256 playQueueBackgroundOpacity->setValue(Settings::self()->playQueueBackgroundOpacity());
257 playQueueBackgroundBlur->setValue(Settings::self()->playQueueBackgroundBlur());
258 playQueueBackgroundFile->setText(Utils::convertPathForDisplay(Settings::self()->playQueueBackgroundFile(), false));
259
260 playQueueConfirmClear->setChecked(Settings::self()->playQueueConfirmClear());
261 playQueueSearch->setChecked(Settings::self()->playQueueSearch());
262 playQueueViewChanged();
263 forceSingleClick->setChecked(Settings::self()->forceSingleClick());
264 infoTooltips->setChecked(Settings::self()->infoTooltips());
265 showStopButton->setChecked(Settings::self()->showStopButton());
266 showCoverWidget->setChecked(Settings::self()->showCoverWidget());
267 showRatingWidget->setChecked(Settings::self()->showRatingWidget());
268 showTechnicalInfo->setChecked(Settings::self()->showTechnicalInfo());
269 if (systemTrayCheckBox) {
270 systemTrayCheckBox->setChecked(Settings::self()->useSystemTray());
271 if (minimiseOnClose) {
272 minimiseOnClose->setChecked(Settings::self()->minimiseOnClose());
273 minimiseOnClose->setEnabled(systemTrayCheckBox->isChecked());
274 }
275 if (startupState) {
276 switch (Settings::self()->startupState()) {
277 case Settings::SS_ShowMainWindow: startupStateShow->setChecked(true); break;
278 case Settings::SS_HideMainWindow: startupStateHide->setChecked(true); break;
279 case Settings::SS_Previous: startupStateRestore->setChecked(true); break;
280 }
281
282 enableStartupState();
283 }
284 }
285 if (systemTrayPopup) {
286 systemTrayPopup->setChecked(Settings::self()->showPopups());
287 }
288 fetchCovers->setChecked(Settings::self()->fetchCovers());
289 storeCoversInMpdDir->setChecked(Settings::self()->storeCoversInMpdDir());
290 coverFilename->setText(Settings::self()->coverFilename());
291
292 QStringList hiddenPages=Settings::self()->hiddenPages();
293 for (int i=0; i<views->count(); ++i) {
294 QListWidgetItem *v=views->item(i);
295 v->setCheckState(hiddenPages.contains(v->data(Qt::UserRole).toString()) ? Qt::Unchecked : Qt::Checked);
296 }
297 int sidebar=Settings::self()->sidebar();
298 selectEntry(sbStyle, sidebar&FancyTabWidget::Style_Mask);
299 selectEntry(sbPosition, sidebar&FancyTabWidget::Position_Mask);
300 sbIconsOnly->setChecked(sidebar&FancyTabWidget::IconOnly);
301 sbAutoHide->setChecked(Settings::self()->splitterAutoHide());
302 sbAutoHideChanged();
303 responsiveSidebar->setChecked(Settings::self()->responsiveSidebar());
304 viewItemChanged(views->item(0));
305 setPlayQueueBackgroundOpacityLabel();
306 setPlayQueueBackgroundBlurLabel();
307 enablePlayQueueBackgroundOptions();
308 if (enableMpris) {
309 enableMpris->setChecked(Settings::self()->mpris());
310 }
311 }
312
toSet(const QString & str)313 static QSet<QString> toSet(const QString &str)
314 {
315 QStringList parts=str.split(constSep, QString::SkipEmptyParts);
316 QSet<QString> set;
317 for (QString s: parts) {
318 set.insert(s.trimmed());
319 }
320 return set;
321 }
322
save()323 void InterfaceSettings::save()
324 {
325 Settings::self()->saveIgnorePrefixes(toSet(ignorePrefixes->text()));
326 Settings::self()->saveComposerGenres(toSet(composerGenres->text()));
327 Settings::self()->saveSingleTracksFolders(toSet(singleTracksFolders->text()));
328 Settings::self()->saveCueSupport((MPDParseUtils::CueSupport)(cueSupport->itemData(cueSupport->currentIndex()).toInt()));
329 Settings::self()->saveUseOriginalYear(1==yearTag->currentIndex());
330 #ifdef ENABLE_DEVICES_SUPPORT
331 Settings::self()->saveShowDeleteAction(showDeleteAction->isChecked());
332 #endif
333 Settings::self()->savePlayQueueView(getValue(playQueueView));
334 Settings::self()->savePlayQueueAutoExpand(playQueueAutoExpand->isChecked());
335 Settings::self()->savePlayQueueStartClosed(playQueueStartClosed->isChecked());
336 Settings::self()->savePlayQueueScroll(playQueueScroll->isChecked());
337
338 if (playQueueBackground_none->isChecked()) {
339 Settings::self()->savePlayQueueBackground(playQueueBackground_none->property(constValueProperty).toInt());
340 } else if (playQueueBackground_cover->isChecked()) {
341 Settings::self()->savePlayQueueBackground(playQueueBackground_cover->property(constValueProperty).toInt());
342 } else if (playQueueBackground_custom->isChecked()) {
343 Settings::self()->savePlayQueueBackground(playQueueBackground_custom->property(constValueProperty).toInt());
344 }
345 Settings::self()->savePlayQueueBackgroundOpacity(playQueueBackgroundOpacity->value());
346 Settings::self()->savePlayQueueBackgroundBlur(playQueueBackgroundBlur->value());
347 Settings::self()->savePlayQueueBackgroundFile(Utils::convertPathFromDisplay(playQueueBackgroundFile->text(), false));
348
349 Settings::self()->savePlayQueueConfirmClear(playQueueConfirmClear->isChecked());
350 Settings::self()->savePlayQueueSearch(playQueueSearch->isChecked());
351 Settings::self()->saveForceSingleClick(forceSingleClick->isChecked());
352 Settings::self()->saveInfoTooltips(infoTooltips->isChecked());
353 Settings::self()->saveShowStopButton(showStopButton->isChecked());
354 Settings::self()->saveShowCoverWidget(showCoverWidget->isChecked());
355 Settings::self()->saveShowRatingWidget(showRatingWidget->isChecked());
356 Settings::self()->saveShowTechnicalInfo(showTechnicalInfo->isChecked());
357 Settings::self()->saveUseSystemTray(systemTrayCheckBox && systemTrayCheckBox->isChecked());
358 Settings::self()->saveShowPopups(systemTrayPopup && systemTrayPopup->isChecked());
359 Settings::self()->saveMinimiseOnClose(minimiseOnClose && minimiseOnClose->isChecked());
360 if (!startupState || startupStateShow->isChecked()) {
361 Settings::self()->saveStartupState(Settings::SS_ShowMainWindow);
362 } else if (startupStateHide->isChecked()) {
363 Settings::self()->saveStartupState(Settings::SS_HideMainWindow);
364 } else if (startupStateRestore->isChecked()) {
365 Settings::self()->saveStartupState(Settings::SS_Previous);
366 }
367 Settings::self()->saveFetchCovers(fetchCovers->isChecked());
368 Settings::self()->saveStoreCoversInMpdDir(storeCoversInMpdDir->isChecked());
369 Settings::self()->saveCoverFilename(coverFilename->text().trimmed());
370 if (loaded && lang) {
371 Settings::self()->saveLang(lang->itemData(lang->currentIndex()).toString());
372 }
373 if (loaded && styleOption) {
374 Settings::self()->saveStyle(0==styleOption->currentIndex() ? QString() : styleOption->currentText());
375 }
376 QStringList hiddenPages;
377 for (int i=0; i<views->count(); ++i) {
378 QListWidgetItem *v=views->item(i);
379 if (Qt::Unchecked==v->checkState()) {
380 hiddenPages.append(v->data(Qt::UserRole).toString());
381 }
382 }
383 Settings::self()->saveHiddenPages(hiddenPages);
384 int sidebar=getValue(sbStyle)|getValue(sbPosition);
385 if (sbIconsOnly->isChecked()) {
386 sidebar|=FancyTabWidget::IconOnly;
387 }
388 Settings::self()->saveSidebar(sidebar);
389 Settings::self()->saveSplitterAutoHide(sbAutoHide->isChecked());
390 Settings::self()->saveResponsiveSidebar(responsiveSidebar->isChecked());
391 if (enableMpris) {
392 Settings::self()->saveMpris(enableMpris->isChecked());
393 }
394 }
395
localeAwareCompare(const QString & a,const QString & b)396 static bool localeAwareCompare(const QString &a, const QString &b)
397 {
398 return a.localeAwareCompare(b) < 0;
399 }
400
translationCodes(const QString & dir)401 static QSet<QString> translationCodes(const QString &dir)
402 {
403 QSet<QString> codes;
404 QDir d(dir);
405 QStringList installed(d.entryList(QStringList() << "*.qm"));
406 QRegExp langRegExp("^cantata_(.*).qm$");
407 for (const QString &filename: installed) {
408 if (langRegExp.exactMatch(filename)) {
409 codes.insert(langRegExp.cap(1));
410 }
411 }
412 return codes;
413 }
414
showEvent(QShowEvent * e)415 void InterfaceSettings::showEvent(QShowEvent *e)
416 {
417 if (!loaded) {
418 loaded=true;
419
420 QMap<QString, QString> langMap;
421 QSet<QString> transCodes;
422
423 transCodes+=translationCodes(qApp->applicationDirPath()+QLatin1String("/translations"));
424 transCodes+=translationCodes(QDir::currentPath()+QLatin1String("/translations"));
425 #ifndef Q_OS_WIN
426 transCodes+=translationCodes(CANTATA_SYS_TRANS_DIR);
427 #endif
428
429 for (const QString &code: transCodes) {
430 QString langName = QLocale::languageToString(QLocale(code).language());
431 QString nativeName = QLocale(code).nativeLanguageName();
432 if (!nativeName.isEmpty()) {
433 langName = nativeName;
434 }
435 langMap[QString("%1 (%2)").arg(langName, code)] = code;
436 }
437
438 langMap[tr("English (en)")] = "en";
439
440 QString current = Settings::self()->lang();
441 QStringList names = langMap.keys();
442 std::stable_sort(names.begin(), names.end(), localeAwareCompare);
443 lang->addItem(tr("System default"), QString());
444 lang->setCurrentIndex(0);
445 for (const QString &name: names) {
446 lang->addItem(name, langMap[name]);
447 if (langMap[name]==current) {
448 lang->setCurrentIndex(lang->count()-1);
449 }
450 }
451
452 if (lang->count()<3) {
453 REMOVE(lang)
454 REMOVE(langLabel)
455 REMOVE(langNoteLabel)
456 } else {
457 connect(lang, SIGNAL(currentIndexChanged(int)), SLOT(langChanged()));
458 }
459
460 styleOption->addItem(tr("System default"));
461 for (const auto & key: QStyleFactory::keys()) {
462 if (!key.startsWith("bb10") && key!="gtk2") {
463 styleOption->addItem(key);
464 }
465 }
466
467 if (styleOption->count()<3) {
468 REMOVE(styleOption)
469 REMOVE(styleLabel)
470 REMOVE(styleNoteLabel)
471 } else {
472 QString selected = Settings::self()->style();
473 styleOption->setCurrentIndex(0);
474 if (!selected.isEmpty()) {
475 for (int i=1; i<styleOption->count(); ++i) {
476 if (styleOption->itemText(i) == selected) {
477 styleOption->setCurrentIndex(i);
478 break;
479 }
480 }
481 }
482 connect(styleOption, SIGNAL(currentIndexChanged(int)), SLOT(styleChanged()));
483 }
484 }
485 QWidget::showEvent(e);
486 }
487
showPage(const QString & page)488 void InterfaceSettings::showPage(const QString &page)
489 {
490 if (QLatin1String("sidebar")==page) {
491 tabWidget->setCurrentIndex(0);
492 }
493 }
494
sizeHint() const495 QSize InterfaceSettings::sizeHint() const
496 {
497 QSize sz=QWidget::sizeHint();
498 #ifdef Q_OS_MAC
499 sz.setWidth(sz.width()+32);
500 sz.setHeight(qMin(sz.height(), 500));
501 #endif
502 return sz;
503 }
504
addView(const QString & v,const QString & prop)505 void InterfaceSettings::addView(const QString &v, const QString &prop)
506 {
507 QListWidgetItem *item=new QListWidgetItem(v, views);
508 item->setCheckState(Qt::Unchecked);
509 item->setData(Qt::UserRole, prop);
510 }
511
playQueueViewChanged()512 void InterfaceSettings::playQueueViewChanged()
513 {
514 bool grouped=ItemView::Mode_GroupedTree==getValue(playQueueView);
515 playQueueAutoExpand->setEnabled(grouped);
516 playQueueStartClosed->setEnabled(grouped);
517 }
518
forceSingleClickChanged()519 void InterfaceSettings::forceSingleClickChanged()
520 {
521 singleClickLabel->setOn(forceSingleClick->isChecked()!=Settings::self()->forceSingleClick());
522 }
523
enableStartupState()524 void InterfaceSettings::enableStartupState()
525 {
526 if (systemTrayCheckBox && minimiseOnClose && startupState) {
527 startupState->setEnabled(systemTrayCheckBox->isChecked() && minimiseOnClose->isChecked());
528 }
529 }
530
langChanged()531 void InterfaceSettings::langChanged()
532 {
533 langNoteLabel->setOn(lang->itemData(lang->currentIndex()).toString()!=Settings::self()->lang());
534 }
535
styleChanged()536 void InterfaceSettings::styleChanged()
537 {
538 QString st = 0==styleOption->currentIndex() ? QString() : styleOption->currentText();
539 styleNoteLabel->setOn(st!=Settings::self()->style());
540 }
541
viewItemChanged(QListWidgetItem * changedItem)542 void InterfaceSettings::viewItemChanged(QListWidgetItem *changedItem)
543 {
544 // If this is the playqueue that has been toggled, then control auto-hide
545 // i.e. can't auto-hide if playqueue is in sidebar
546 if (Qt::Checked==changedItem->checkState() && changedItem==views->item(0)) {
547 sbAutoHide->setChecked(false);
548 }
549
550 // Ensure we have at least 1 view checked...
551 for (int i=0; i<views->count(); ++i) {
552 QListWidgetItem *v=views->item(i);
553 if (Qt::Checked==v->checkState()) {
554 return;
555 }
556 }
557
558 views->item(1)->setCheckState(Qt::Checked);
559 }
560
sbAutoHideChanged()561 void InterfaceSettings::sbAutoHideChanged()
562 {
563 if (sbAutoHide->isChecked()) {
564 views->item(0)->setCheckState(Qt::Unchecked);
565 }
566 }
567
setPlayQueueBackgroundOpacityLabel()568 void InterfaceSettings::setPlayQueueBackgroundOpacityLabel()
569 {
570 playQueueBackgroundOpacityLabel->setText(tr("%1%", "value%").arg(playQueueBackgroundOpacity->value()));
571 }
572
setPlayQueueBackgroundBlurLabel()573 void InterfaceSettings::setPlayQueueBackgroundBlurLabel()
574 {
575 playQueueBackgroundBlurLabel->setText(tr("%1 px", "pixels").arg(playQueueBackgroundBlur->value()));
576 }
577
enablePlayQueueBackgroundOptions()578 void InterfaceSettings::enablePlayQueueBackgroundOptions()
579 {
580 playQueueBackgroundOpacity->setEnabled(!playQueueBackground_none->isChecked());
581 playQueueBackgroundOpacityLabel->setEnabled(playQueueBackgroundOpacity->isEnabled());
582 playQueueBackgroundBlur->setEnabled(playQueueBackgroundOpacity->isEnabled());
583 playQueueBackgroundBlurLabel->setEnabled(playQueueBackgroundOpacity->isEnabled());
584 }
585
systemTrayCheckBoxToggled()586 void InterfaceSettings::systemTrayCheckBoxToggled()
587 {
588 if (systemTrayCheckBox && systemTrayPopup && !systemTrayCheckBox->isChecked()) {
589 systemTrayPopup->setChecked(false);
590 }
591 }
592
systemTrayPopupToggled()593 void InterfaceSettings::systemTrayPopupToggled()
594 {
595 if (systemTrayCheckBox && systemTrayPopup && systemTrayPopup->isChecked()) {
596 systemTrayCheckBox->setChecked(true);
597 }
598 }
599
storeCoversInMpdDirToggled()600 void InterfaceSettings::storeCoversInMpdDirToggled()
601 {
602 storeCoversInMpdDirLabel->setOn(storeCoversInMpdDir->isChecked() && storeCoversInMpdDir->isChecked()!=Settings::self()->storeCoversInMpdDir());
603 }
604
605 #include "moc_interfacesettings.cpp"
606