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 "playlistsequence.h"
19 #include "ui_playlistsequence.h"
20 #include "ui/iconloader.h"
21
22 #include <QMenu>
23 #include <QActionGroup>
24 #include <QSettings>
25 #include <QtDebug>
26 #include <QPainter>
27
28 const char* PlaylistSequence::kSettingsGroup = "PlaylistSequence";
29
PlaylistSequence(QWidget * parent,SettingsProvider * settings)30 PlaylistSequence::PlaylistSequence(QWidget* parent, SettingsProvider* settings)
31 : QWidget(parent),
32 ui_(new Ui_PlaylistSequence),
33 settings_(settings ? settings : new DefaultSettingsProvider),
34 repeat_menu_(new QMenu(this)),
35 shuffle_menu_(new QMenu(this)),
36 loading_(false),
37 repeat_mode_(Repeat_Off),
38 shuffle_mode_(Shuffle_Off),
39 dynamic_(false) {
40 ui_->setupUi(this);
41
42 // Icons
43 ui_->repeat->setIcon(
44 AddDesaturatedIcon(IconLoader::Load("media-playlist-repeat", IconLoader::Base)));
45 ui_->shuffle->setIcon(
46 AddDesaturatedIcon(IconLoader::Load("media-playlist-shuffle", IconLoader::Base)));
47
48 // Remove arrow indicators
49 ui_->repeat->setStyleSheet("QToolButton::menu-indicator { image: none; }");
50 ui_->shuffle->setStyleSheet("QToolButton::menu-indicator { image: none; }");
51
52 settings_->set_group(kSettingsGroup);
53
54 QActionGroup* repeat_group = new QActionGroup(this);
55 repeat_group->addAction(ui_->action_repeat_off);
56 repeat_group->addAction(ui_->action_repeat_track);
57 repeat_group->addAction(ui_->action_repeat_album);
58 repeat_group->addAction(ui_->action_repeat_playlist);
59 repeat_group->addAction(ui_->action_repeat_onebyone);
60 repeat_group->addAction(ui_->action_repeat_intro);
61 repeat_menu_->addActions(repeat_group->actions());
62 ui_->repeat->setMenu(repeat_menu_);
63
64 QActionGroup* shuffle_group = new QActionGroup(this);
65 shuffle_group->addAction(ui_->action_shuffle_off);
66 shuffle_group->addAction(ui_->action_shuffle_all);
67 shuffle_group->addAction(ui_->action_shuffle_inside_album);
68 shuffle_group->addAction(ui_->action_shuffle_albums);
69 shuffle_menu_->addActions(shuffle_group->actions());
70 ui_->shuffle->setMenu(shuffle_menu_);
71
72 connect(repeat_group, SIGNAL(triggered(QAction*)),
73 SLOT(RepeatActionTriggered(QAction*)));
74 connect(shuffle_group, SIGNAL(triggered(QAction*)),
75 SLOT(ShuffleActionTriggered(QAction*)));
76
77 Load();
78 }
79
~PlaylistSequence()80 PlaylistSequence::~PlaylistSequence() { delete ui_; }
81
Load()82 void PlaylistSequence::Load() {
83 loading_ = true; // Stops these setter functions calling Save()
84 SetShuffleMode(
85 ShuffleMode(settings_->value("shuffle_mode", Shuffle_Off).toInt()));
86 SetRepeatMode(
87 RepeatMode(settings_->value("repeat_mode", Repeat_Off).toInt()));
88 loading_ = false;
89 }
90
Save()91 void PlaylistSequence::Save() {
92 if (loading_) return;
93
94 settings_->setValue("shuffle_mode", shuffle_mode_);
95 settings_->setValue("repeat_mode", repeat_mode_);
96 }
97
AddDesaturatedIcon(const QIcon & icon)98 QIcon PlaylistSequence::AddDesaturatedIcon(const QIcon& icon) {
99 QIcon ret;
100 for (const QSize& size : icon.availableSizes()) {
101 QPixmap on(icon.pixmap(size));
102 QPixmap off(DesaturatedPixmap(on));
103
104 ret.addPixmap(off, QIcon::Normal, QIcon::Off);
105 ret.addPixmap(on, QIcon::Normal, QIcon::On);
106 }
107 return ret;
108 }
109
DesaturatedPixmap(const QPixmap & pixmap)110 QPixmap PlaylistSequence::DesaturatedPixmap(const QPixmap& pixmap) {
111 QPixmap ret(pixmap.size());
112 ret.fill(Qt::transparent);
113
114 QPainter p(&ret);
115 p.setOpacity(0.5);
116 p.drawPixmap(0, 0, pixmap);
117 p.end();
118
119 return ret;
120 }
121
RepeatActionTriggered(QAction * action)122 void PlaylistSequence::RepeatActionTriggered(QAction* action) {
123 RepeatMode mode = Repeat_Off;
124 if (action == ui_->action_repeat_track) mode = Repeat_Track;
125 if (action == ui_->action_repeat_album) mode = Repeat_Album;
126 if (action == ui_->action_repeat_playlist) mode = Repeat_Playlist;
127 if (action == ui_->action_repeat_onebyone) mode = Repeat_OneByOne;
128 if (action == ui_->action_repeat_intro) mode = Repeat_Intro;
129
130 SetRepeatMode(mode);
131 }
132
ShuffleActionTriggered(QAction * action)133 void PlaylistSequence::ShuffleActionTriggered(QAction* action) {
134 ShuffleMode mode = Shuffle_Off;
135 if (action == ui_->action_shuffle_all) mode = Shuffle_All;
136 if (action == ui_->action_shuffle_inside_album) mode = Shuffle_InsideAlbum;
137 if (action == ui_->action_shuffle_albums) mode = Shuffle_Albums;
138
139 SetShuffleMode(mode);
140 }
141
SetRepeatMode(RepeatMode mode)142 void PlaylistSequence::SetRepeatMode(RepeatMode mode) {
143 ui_->repeat->setChecked(mode != Repeat_Off);
144
145 switch (mode) {
146 case Repeat_Off:
147 ui_->action_repeat_off->setChecked(true);
148 break;
149 case Repeat_Track:
150 ui_->action_repeat_track->setChecked(true);
151 break;
152 case Repeat_Album:
153 ui_->action_repeat_album->setChecked(true);
154 break;
155 case Repeat_Playlist:
156 ui_->action_repeat_playlist->setChecked(true);
157 break;
158 case Repeat_OneByOne:
159 ui_->action_repeat_onebyone->setChecked(true);
160 break;
161 case Repeat_Intro:
162 ui_->action_repeat_intro->setChecked(true);
163 break;
164 }
165
166 if (mode != repeat_mode_) {
167 repeat_mode_ = mode;
168 emit RepeatModeChanged(mode);
169 }
170
171 Save();
172 }
173
SetShuffleMode(ShuffleMode mode)174 void PlaylistSequence::SetShuffleMode(ShuffleMode mode) {
175 ui_->shuffle->setChecked(mode != Shuffle_Off);
176
177 switch (mode) {
178 case Shuffle_Off:
179 ui_->action_shuffle_off->setChecked(true);
180 break;
181 case Shuffle_All:
182 ui_->action_shuffle_all->setChecked(true);
183 break;
184 case Shuffle_InsideAlbum:
185 ui_->action_shuffle_inside_album->setChecked(true);
186 break;
187 case Shuffle_Albums:
188 ui_->action_shuffle_albums->setChecked(true);
189 break;
190 }
191
192 if (mode != shuffle_mode_) {
193 shuffle_mode_ = mode;
194 emit ShuffleModeChanged(mode);
195 }
196
197 Save();
198 }
199
SetUsingDynamicPlaylist(bool dynamic)200 void PlaylistSequence::SetUsingDynamicPlaylist(bool dynamic) {
201 dynamic_ = dynamic;
202 const QString not_available(
203 tr("Not available while using a dynamic playlist"));
204
205 setEnabled(!dynamic);
206 ui_->shuffle->setToolTip(dynamic ? not_available : tr("Shuffle"));
207 ui_->repeat->setToolTip(dynamic ? not_available : tr("Repeat"));
208 }
209
shuffle_mode() const210 PlaylistSequence::ShuffleMode PlaylistSequence::shuffle_mode() const {
211 return dynamic_ ? Shuffle_Off : shuffle_mode_;
212 }
213
repeat_mode() const214 PlaylistSequence::RepeatMode PlaylistSequence::repeat_mode() const {
215 return dynamic_ ? Repeat_Off : repeat_mode_;
216 }
217
218 // called from global shortcut
CycleShuffleMode()219 void PlaylistSequence::CycleShuffleMode() {
220 ShuffleMode mode = Shuffle_Off;
221 // we cycle through the shuffle modes
222 switch (shuffle_mode()) {
223 case Shuffle_Off:
224 mode = Shuffle_All;
225 break;
226 case Shuffle_All:
227 mode = Shuffle_InsideAlbum;
228 break;
229 case Shuffle_InsideAlbum:
230 mode = Shuffle_Albums;
231 break;
232 case Shuffle_Albums:
233 break;
234 }
235
236 SetShuffleMode(mode);
237 }
238
239 // called from global shortcut
CycleRepeatMode()240 void PlaylistSequence::CycleRepeatMode() {
241 RepeatMode mode = Repeat_Off;
242 // we cycle through the repeat modes
243 switch (repeat_mode()) {
244 case Repeat_Off:
245 mode = Repeat_Track;
246 break;
247 case Repeat_Track:
248 mode = Repeat_Album;
249 break;
250 case Repeat_Album:
251 mode = Repeat_Playlist;
252 break;
253 case Repeat_Playlist:
254 mode = Repeat_OneByOne;
255 break;
256 case Repeat_OneByOne:
257 mode = Repeat_Intro;
258 break;
259 case Repeat_Intro:
260 break;
261 }
262
263 SetRepeatMode(mode);
264 }
265