1 /* This file is part of Clementine.
2 Copyright 2010, David Sansome <me@davidsansome.com>
3
4 Clementine is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 Clementine is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with Clementine. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "iconloader.h"
19 #include "notificationssettingspage.h"
20 #include "settingsdialog.h"
21 #include "ui_notificationssettingspage.h"
22 #include "ui/iconloader.h"
23 #include "widgets/osdpretty.h"
24
25 #include <QColorDialog>
26 #include <QFontDialog>
27 #include <QMenu>
28 #include <QToolTip>
29
NotificationsSettingsPage(SettingsDialog * dialog)30 NotificationsSettingsPage::NotificationsSettingsPage(SettingsDialog* dialog)
31 : SettingsPage(dialog),
32 ui_(new Ui_NotificationsSettingsPage),
33 pretty_popup_(new OSDPretty(OSDPretty::Mode_Draggable)) {
34 ui_->setupUi(this);
35 setWindowIcon(IconLoader::Load("help-hint", IconLoader::Base));
36
37 QIcon nocover = IconLoader::Load("nocover", IconLoader::Other);
38 pretty_popup_->SetMessage(tr("OSD Preview"), tr("Drag to reposition"),
39 nocover.pixmap(nocover.availableSizes().last())
40 .toImage());
41
42 ui_->notifications_bg_preset->setItemData(0, QColor(OSDPretty::kPresetBlue),
43 Qt::DecorationRole);
44 ui_->notifications_bg_preset->setItemData(1, QColor(OSDPretty::kPresetOrange),
45 Qt::DecorationRole);
46
47 // Create and populate the helper menus
48 QMenu* menu = new QMenu(this);
49 menu->addAction(ui_->action_artist);
50 menu->addAction(ui_->action_album);
51 menu->addAction(ui_->action_title);
52 menu->addAction(ui_->action_albumartist);
53 menu->addAction(ui_->action_year);
54 menu->addAction(ui_->action_composer);
55 menu->addAction(ui_->action_performer);
56 menu->addAction(ui_->action_grouping);
57 menu->addAction(ui_->action_length);
58 menu->addAction(ui_->action_disc);
59 menu->addAction(ui_->action_track);
60 menu->addAction(ui_->action_genre);
61 menu->addAction(ui_->action_playcount);
62 menu->addAction(ui_->action_skipcount);
63 menu->addAction(ui_->action_filename);
64 menu->addAction(ui_->action_rating);
65 menu->addAction(ui_->action_score);
66 menu->addSeparator();
67 menu->addAction(ui_->action_newline);
68 ui_->notifications_exp_chooser1->setMenu(menu);
69 ui_->notifications_exp_chooser2->setMenu(menu);
70 ui_->notifications_exp_chooser1->setPopupMode(QToolButton::InstantPopup);
71 ui_->notifications_exp_chooser2->setPopupMode(QToolButton::InstantPopup);
72 // We need this because by default menus don't show tooltips
73 connect(menu, SIGNAL(hovered(QAction*)), SLOT(ShowMenuTooltip(QAction*)));
74
75 connect(ui_->notifications_none, SIGNAL(toggled(bool)),
76 SLOT(NotificationTypeChanged()));
77 connect(ui_->notifications_native, SIGNAL(toggled(bool)),
78 SLOT(NotificationTypeChanged()));
79 connect(ui_->notifications_tray, SIGNAL(toggled(bool)),
80 SLOT(NotificationTypeChanged()));
81 connect(ui_->notifications_pretty, SIGNAL(toggled(bool)),
82 SLOT(NotificationTypeChanged()));
83 connect(ui_->notifications_opacity, SIGNAL(valueChanged(int)),
84 SLOT(PrettyOpacityChanged(int)));
85 connect(ui_->notifications_bg_preset, SIGNAL(activated(int)),
86 SLOT(PrettyColorPresetChanged(int)));
87 connect(ui_->notifications_fg_choose, SIGNAL(clicked()),
88 SLOT(ChooseFgColor()));
89 connect(ui_->notifications_font_choose, SIGNAL(clicked()),
90 SLOT(ChooseFont()));
91 connect(ui_->notifications_exp_chooser1, SIGNAL(triggered(QAction*)),
92 SLOT(InsertVariableFirstLine(QAction*)));
93 connect(ui_->notifications_exp_chooser2, SIGNAL(triggered(QAction*)),
94 SLOT(InsertVariableSecondLine(QAction*)));
95 connect(ui_->notifications_disable_duration, SIGNAL(toggled(bool)),
96 ui_->notifications_duration, SLOT(setDisabled(bool)));
97
98 if (!OSD::SupportsNativeNotifications())
99 ui_->notifications_native->setEnabled(false);
100 if (!OSD::SupportsTrayPopups()) ui_->notifications_tray->setEnabled(false);
101
102 connect(ui_->notifications_pretty, SIGNAL(toggled(bool)),
103 SLOT(UpdatePopupVisible()));
104
105 connect(ui_->notifications_custom_text_enabled, SIGNAL(toggled(bool)),
106 SLOT(NotificationCustomTextChanged(bool)));
107 connect(ui_->notifications_preview, SIGNAL(clicked()),
108 SLOT(PrepareNotificationPreview()));
109
110 // Icons
111 ui_->notifications_exp_chooser1->setIcon(IconLoader::Load("list-add", IconLoader::Base));
112 ui_->notifications_exp_chooser2->setIcon(IconLoader::Load("list-add", IconLoader::Base));
113 }
114
~NotificationsSettingsPage()115 NotificationsSettingsPage::~NotificationsSettingsPage() {
116 delete pretty_popup_;
117 delete ui_;
118 }
119
showEvent(QShowEvent *)120 void NotificationsSettingsPage::showEvent(QShowEvent*) { UpdatePopupVisible(); }
121
hideEvent(QHideEvent *)122 void NotificationsSettingsPage::hideEvent(QHideEvent*) { UpdatePopupVisible(); }
123
Load()124 void NotificationsSettingsPage::Load() {
125 QSettings s;
126
127 s.beginGroup(OSD::kSettingsGroup);
128 OSD::Behaviour osd_behaviour =
129 OSD::Behaviour(s.value("Behaviour", OSD::Native).toInt());
130 switch (osd_behaviour) {
131 case OSD::Native:
132 if (OSD::SupportsNativeNotifications()) {
133 ui_->notifications_native->setChecked(true);
134 break;
135 }
136 // Fallthrough
137
138 case OSD::Pretty:
139 ui_->notifications_pretty->setChecked(true);
140 break;
141
142 case OSD::TrayPopup:
143 if (OSD::SupportsTrayPopups()) {
144 ui_->notifications_tray->setChecked(true);
145 break;
146 }
147 // Fallthrough
148
149 case OSD::Disabled:
150 default:
151 ui_->notifications_none->setChecked(true);
152 break;
153 }
154 ui_->notifications_duration->setValue(s.value("Timeout", 5000).toInt() /
155 1000);
156 ui_->notifications_volume->setChecked(
157 s.value("ShowOnVolumeChange", false).toBool());
158 ui_->notifications_play_mode->setChecked(
159 s.value("ShowOnPlayModeChange", true).toBool());
160 ui_->notifications_pause->setChecked(
161 s.value("ShowOnPausePlayback", true).toBool());
162 ui_->notifications_art->setChecked(s.value("ShowArt", true).toBool());
163 ui_->notifications_custom_text_enabled->setChecked(
164 s.value("CustomTextEnabled", false).toBool());
165 ui_->notifications_custom_text1->setText(s.value("CustomText1").toString());
166 ui_->notifications_custom_text2->setText(s.value("CustomText2").toString());
167 s.endGroup();
168
169 #ifdef Q_OS_DARWIN
170 ui_->notifications_options->setEnabled(
171 ui_->notifications_pretty->isChecked());
172 #endif
173
174 // Pretty OSD
175 pretty_popup_->ReloadSettings();
176 ui_->notifications_opacity->setValue(pretty_popup_->background_opacity() *
177 100);
178
179 QRgb color = pretty_popup_->background_color();
180 if (color == OSDPretty::kPresetBlue)
181 ui_->notifications_bg_preset->setCurrentIndex(0);
182 else if (color == OSDPretty::kPresetOrange)
183 ui_->notifications_bg_preset->setCurrentIndex(1);
184 else
185 ui_->notifications_bg_preset->setCurrentIndex(2);
186 ui_->notifications_bg_preset->setItemData(2, QColor(color),
187 Qt::DecorationRole);
188 ui_->notifications_disable_duration->setChecked(
189 pretty_popup_->disable_duration());
190 UpdatePopupVisible();
191 }
192
Save()193 void NotificationsSettingsPage::Save() {
194 QSettings s;
195
196 OSD::Behaviour osd_behaviour = OSD::Disabled;
197 if (ui_->notifications_none->isChecked())
198 osd_behaviour = OSD::Disabled;
199 else if (ui_->notifications_native->isChecked())
200 osd_behaviour = OSD::Native;
201 else if (ui_->notifications_tray->isChecked())
202 osd_behaviour = OSD::TrayPopup;
203 else if (ui_->notifications_pretty->isChecked())
204 osd_behaviour = OSD::Pretty;
205
206 s.beginGroup(OSD::kSettingsGroup);
207 s.setValue("Behaviour", int(osd_behaviour));
208 s.setValue("Timeout", ui_->notifications_duration->value() * 1000);
209 s.setValue("ShowOnVolumeChange", ui_->notifications_volume->isChecked());
210 s.setValue("ShowOnPlayModeChange", ui_->notifications_play_mode->isChecked());
211 s.setValue("ShowOnPausePlayback", ui_->notifications_pause->isChecked());
212 s.setValue("ShowArt", ui_->notifications_art->isChecked());
213 s.setValue("CustomTextEnabled",
214 ui_->notifications_custom_text_enabled->isChecked());
215 s.setValue("CustomText1", ui_->notifications_custom_text1->text());
216 s.setValue("CustomText2", ui_->notifications_custom_text2->text());
217 s.endGroup();
218
219 s.beginGroup(OSDPretty::kSettingsGroup);
220 s.setValue("foreground_color", pretty_popup_->foreground_color());
221 s.setValue("background_color", pretty_popup_->background_color());
222 s.setValue("background_opacity", pretty_popup_->background_opacity());
223 s.setValue("popup_display", pretty_popup_->popup_display());
224 s.setValue("popup_pos", pretty_popup_->popup_pos());
225 s.setValue("font", pretty_popup_->font().toString());
226 s.setValue("disable_duration",
227 ui_->notifications_disable_duration->isChecked());
228 s.endGroup();
229 }
230
PrettyOpacityChanged(int value)231 void NotificationsSettingsPage::PrettyOpacityChanged(int value) {
232 pretty_popup_->set_background_opacity(qreal(value) / 100.0);
233 }
234
UpdatePopupVisible()235 void NotificationsSettingsPage::UpdatePopupVisible() {
236 pretty_popup_->setVisible(isVisible() &&
237 ui_->notifications_pretty->isChecked());
238 }
239
PrettyColorPresetChanged(int index)240 void NotificationsSettingsPage::PrettyColorPresetChanged(int index) {
241 if (dialog()->is_loading_settings()) return;
242
243 switch (index) {
244 case 0:
245 pretty_popup_->set_background_color(OSDPretty::kPresetBlue);
246 break;
247
248 case 1:
249 pretty_popup_->set_background_color(OSDPretty::kPresetOrange);
250 break;
251
252 case 2:
253 default:
254 ChooseBgColor();
255 break;
256 }
257 }
258
ChooseBgColor()259 void NotificationsSettingsPage::ChooseBgColor() {
260 QColor color =
261 QColorDialog::getColor(pretty_popup_->background_color(), this);
262 if (!color.isValid()) return;
263
264 pretty_popup_->set_background_color(color.rgb());
265 ui_->notifications_bg_preset->setItemData(2, color, Qt::DecorationRole);
266 }
267
ChooseFgColor()268 void NotificationsSettingsPage::ChooseFgColor() {
269 QColor color =
270 QColorDialog::getColor(pretty_popup_->foreground_color(), this);
271 if (!color.isValid()) return;
272
273 pretty_popup_->set_foreground_color(color.rgb());
274 }
275
ChooseFont()276 void NotificationsSettingsPage::ChooseFont() {
277 bool ok;
278 QFont font = QFontDialog::getFont(&ok, pretty_popup_->font(), this);
279 if (ok) pretty_popup_->set_font(font);
280 }
281
NotificationCustomTextChanged(bool enabled)282 void NotificationsSettingsPage::NotificationCustomTextChanged(bool enabled) {
283 ui_->notifications_custom_text1->setEnabled(enabled);
284 ui_->notifications_custom_text2->setEnabled(enabled);
285 ui_->notifications_exp_chooser1->setEnabled(enabled);
286 ui_->notifications_exp_chooser2->setEnabled(enabled);
287 ui_->notifications_preview->setEnabled(enabled);
288 ui_->label_19->setEnabled(enabled);
289 ui_->label_20->setEnabled(enabled);
290 }
291
PrepareNotificationPreview()292 void NotificationsSettingsPage::PrepareNotificationPreview() {
293 OSD::Behaviour notificationType = OSD::Disabled;
294 if (ui_->notifications_native->isChecked()) {
295 notificationType = OSD::Native;
296 } else if (ui_->notifications_pretty->isChecked()) {
297 notificationType = OSD::Pretty;
298 } else if (ui_->notifications_tray->isChecked()) {
299 notificationType = OSD::TrayPopup;
300 }
301
302 // If user changes timeout or other options, that won't be reflected in the
303 // preview
304 emit NotificationPreview(notificationType,
305 ui_->notifications_custom_text1->text(),
306 ui_->notifications_custom_text2->text());
307 }
308
InsertVariableFirstLine(QAction * action)309 void NotificationsSettingsPage::InsertVariableFirstLine(QAction* action) {
310 // We use action name, therefore those shouldn't be translatable
311 ui_->notifications_custom_text1->insert(action->text());
312 }
313
InsertVariableSecondLine(QAction * action)314 void NotificationsSettingsPage::InsertVariableSecondLine(QAction* action) {
315 // We use action name, therefore those shouldn't be translatable
316 ui_->notifications_custom_text2->insert(action->text());
317 }
318
ShowMenuTooltip(QAction * action)319 void NotificationsSettingsPage::ShowMenuTooltip(QAction* action) {
320 QToolTip::showText(QCursor::pos(), action->toolTip());
321 }
322
NotificationTypeChanged()323 void NotificationsSettingsPage::NotificationTypeChanged() {
324 bool enabled = !ui_->notifications_none->isChecked();
325 bool pretty = ui_->notifications_pretty->isChecked();
326
327 ui_->notifications_general->setEnabled(enabled);
328 ui_->notifications_pretty_group->setEnabled(pretty);
329 ui_->notifications_custom_text_group->setEnabled(enabled);
330
331 #ifdef Q_OS_DARWIN
332 ui_->notifications_options->setEnabled(pretty);
333 #endif
334 ui_->notifications_duration->setEnabled(
335 !pretty || (pretty && !ui_->notifications_disable_duration->isChecked()));
336 ui_->notifications_disable_duration->setEnabled(pretty);
337 }
338