Minor bugfixes
[someplayer] / src / playlistsortform.cpp
1 /*
2  * SomePlayer - An alternate music player for Maemo 5
3  * Copyright (C) 2010 Nikolay (somebody) Tischenko <niktischenko@gmail.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19
20 #include "playlistsortform.h"
21 #include "ui_playlistsortform.h"
22 #include <QTime>
23 #include "track.h"
24 #include <QDebug>
25 #include "config.h"
26
27 using namespace SomePlayer::DataObjects;
28 using namespace SomePlayer::Storage;
29
30 inline void __fill_model(QStandardItemModel *_model, Playlist playlist) {
31         _model->clear();
32         QList<Track> tracks = playlist.tracks();
33         int count = tracks.count();
34         _model->setRowCount(count);
35         _model->setColumnCount(2);
36         QTime time;
37         for (int i = 0; i < count; i++) {
38                 TrackMetadata meta = tracks.at(i).metadata();
39                 time.setHMS(0, meta.length()/60, meta.length() % 60);
40                 QString t = meta.title()+"#_#"+meta.artist()+"#_#"+meta.album()+"#_#"+time.toString("mm:ss");
41                 _model->setItem(i, 1, new QStandardItem(t));
42                 _model->setItem(i, 0, new QStandardItem("##deselect_all.png"));
43         }
44 }
45
46 PlaylistSortForm::PlaylistSortForm(QWidget *parent) :
47                 QWidget(parent),
48                 ui(new Ui::PlaylistSortForm)
49 {
50         ui->setupUi(this);
51         setAttribute(Qt::WA_Maemo5StackedWindow);
52         setWindowFlags(Qt::Window | windowFlags());
53         _track_renderer = new TrackRenderer(this);
54         _track_renderer->setActiveRow(-1);
55         _track_renderer->setSearchRow(-1);
56         ui->playlistView->setItemDelegateForColumn(0, _track_renderer);
57         ui->playlistView->setItemDelegateForColumn(1, _track_renderer);
58         _model = new QStandardItemModel(this);
59         ui->playlistView->setModel(_model);
60         _top_gradient = ui->topWidget->styleSheet();
61         _bottom_gradient = ui->bottomWidget->styleSheet();
62
63         connect(ui->doneButton, SIGNAL(clicked()), this, SLOT(done()));
64         connect(ui->playlistView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
65                 this, SLOT(_process_selection(QItemSelection,QItemSelection)));
66         connect(ui->moveDownButton, SIGNAL(clicked()), this, SLOT(moveDown()));
67         connect(ui->moveTopButton, SIGNAL(clicked()), this, SLOT(moveUp()));
68         connect(ui->sortAlphAscButton, SIGNAL(clicked()), this, SLOT(sortAlphAsc()));
69         connect(ui->sortAlphDescButton, SIGNAL(clicked()), this, SLOT(sortAlphDesc()));
70         connect(ui->shuffleButton, SIGNAL(clicked()), this, SLOT(shuffle()));
71         connect(ui->artistsButton, SIGNAL(clicked()), this, SLOT(sortArtist()));
72 }
73
74 PlaylistSortForm::~PlaylistSortForm()
75 {
76         delete ui;
77 }
78
79 void PlaylistSortForm::done() {
80         emit playlistChanged();
81         hide();
82 }
83
84 void PlaylistSortForm::setPlaylist(Playlist playlist) {
85         _playlist = playlist;
86         updateView();
87 }
88
89 Playlist PlaylistSortForm::getPlaylist() {
90         return _playlist;
91 }
92
93 void PlaylistSortForm::updateView() {
94         __fill_model(_model, _playlist);
95         ui->playlistView->setColumnWidth(0, 50);
96 }
97
98 void PlaylistSortForm::_process_selection(QItemSelection selected, QItemSelection deselected) {
99         foreach (QModelIndex id, selected.indexes()) {
100                 if (id.column() == 0) {
101                         _model->item(id.row(), 0)->setText("##select_all.png");
102                 }
103                 ui->playlistView->selectionModel()->select(id, QItemSelectionModel::Select);
104         }
105         foreach (QModelIndex id, deselected.indexes()) {
106                 if (id.column() == 0) {
107                         _model->item(id.row(), 0)->setText("##deselect_all.png");
108                 }
109                 ui->playlistView->selectionModel()->select(id, QItemSelectionModel::Deselect);
110         }
111 }
112
113 void PlaylistSortForm::moveDown() {
114         QModelIndexList idx = ui->playlistView->selectionModel()->selectedIndexes();
115         if (idx.isEmpty()) {
116                 return;
117         }
118         QList<int> rows;
119         foreach (QModelIndex id, idx) {
120                 if (id.column() == 1) {
121                         rows << id.row();
122                 }
123         }
124         _move(rows, 1);
125 }
126
127 void PlaylistSortForm::moveUp() {
128         QModelIndexList idx = ui->playlistView->selectionModel()->selectedIndexes();
129         if (idx.isEmpty()) {
130                 return;
131         }
132         QList<int> rows;
133         foreach (QModelIndex id, idx) {
134                 if (id.column() == 1) {
135                         rows << id.row();
136                 }
137         }
138         _move(rows, -1);
139 }
140
141 void PlaylistSortForm::sortAlphAsc() {
142         QList<Track> tracks = _playlist.tracks();
143         qSort(tracks);
144         _playlist.setTracks(tracks);
145         updateView();
146 }
147
148 void PlaylistSortForm::sortAlphDesc() {
149         QList<Track> tracks = _playlist.tracks();
150         qSort(tracks);
151         for(int i = 0; i < (tracks.size()/2); i++) {
152                 tracks.swap(i,tracks.size()-(1+i));
153         }
154         _playlist.setTracks(tracks);
155         updateView();
156 }
157
158 void PlaylistSortForm::sortArtist() {
159         QList<Track> tracks = _playlist.tracks();
160         QList<Track> ntracks;
161         // first step: artists
162         QMap<QString, QList<Track> > artists_tracks;
163         foreach (Track t, tracks) {
164                 artists_tracks[t.metadata().artist()].append(t);;
165         }
166         // second step: albums;
167         QMap<QString, QList<Track> > album_tracks;
168         QList<QString> artists = artists_tracks.keys();
169         qSort(artists);
170         foreach (QString artist, artists) {
171                 album_tracks.clear();
172                 foreach (Track t, artists_tracks[artist]) {
173                         album_tracks[t.metadata().album()].append(t);
174                 }
175                 QList<QString> albums = album_tracks.keys();
176                 qSort(albums);
177                 foreach (QString album, albums) {
178                         foreach (Track t, album_tracks[album]) {
179                                 ntracks << t;
180                         }
181                 }
182         }
183         _playlist.setTracks(ntracks);
184         updateView();
185 }
186
187 void PlaylistSortForm::shuffle() {
188         qsrand(QTime::currentTime().msec());
189         QList<Track> tracks = _playlist.tracks();
190         QList<Track> ntracks;
191         int size = tracks.size();
192         int pos = 0;
193         for (int i = 0; i < size; i++) {
194                 pos = qrand() % tracks.count();
195                 ntracks << tracks.at(pos);
196                 tracks.removeAt(pos);
197         }
198         _playlist.setTracks(ntracks);
199         updateView();
200 }
201
202 void PlaylistSortForm::_move(QList<int> rows, int diff) {
203         qSort(rows);
204         QList<Track> tracks = _playlist.tracks();
205         if ((diff > 0 && (rows.last() == tracks.count()-diff)) ||
206             (diff < 0 && (rows.first() == -diff - 1))) {
207                 return;
208         }
209         if (diff > 0) {
210                 for (int i = rows.count()-1; i>=0; i--) {
211                         tracks.swap(rows[i], rows[i]+diff);
212                         rows[i] += diff;
213                 }
214         } else {
215                 for (int i = 0; i < rows.count(); i++) {
216                         tracks.swap(rows[i], rows[i]+diff);
217                         rows[i] += diff;
218                 }
219         }
220         _playlist.setTracks(tracks);
221         updateView();
222         foreach (int i, rows) {
223                 ui->playlistView->selectRow(i);
224         }
225         ui->playlistView->scrollTo(_model->index(rows[rows.count()/2], 0), QAbstractItemView::PositionAtCenter);
226 }
227
228 void PlaylistSortForm::landscapeMode() {
229         ui->topWidget->hide();
230         ui->bottomWidget->hide();
231         ui->bhorWidget->hide();
232
233         ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_0);
234         ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_1);
235         ui->topWidget->layout()->removeWidget(ui->sortAlphAscButton);
236         ui->topWidget->layout()->removeWidget(ui->sortAlphDescButton);
237         ui->topWidget->layout()->removeWidget(ui->artistsButton);
238
239         ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer_0);
240         ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer_1);
241         ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer_2);
242         ui->bottomWidget->layout()->removeWidget(ui->doneButton);
243         ui->bottomWidget->layout()->removeWidget(ui->moveDownButton);
244         ui->bottomWidget->layout()->removeWidget(ui->moveTopButton);
245         ui->bottomWidget->layout()->removeWidget(ui->shuffleButton);
246
247         ui->bhorWidget->layout()->removeWidget(ui->doneButton);
248         ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_0);
249         ui->bhorWidget->layout()->removeWidget(ui->moveTopButton);
250         ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_1);
251         ui->bhorWidget->layout()->removeWidget(ui->sortAlphAscButton);
252         ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_2);
253         ui->bhorWidget->layout()->removeWidget(ui->artistsButton);
254         ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_3);
255         ui->bhorWidget->layout()->removeWidget(ui->sortAlphDescButton);
256         ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_4);
257         ui->bhorWidget->layout()->removeWidget(ui->moveDownButton);
258         ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_5);
259         ui->bhorWidget->layout()->removeWidget(ui->shuffleButton);
260
261         ui->bhorWidget->layout()->addWidget(ui->doneButton);
262         ui->bhorWidget->layout()->addItem(ui->chorizontalSpacer_0);
263         ui->bhorWidget->layout()->addWidget(ui->sortAlphAscButton);
264         ui->bhorWidget->layout()->addItem(ui->chorizontalSpacer_1);
265         ui->bhorWidget->layout()->addWidget(ui->moveTopButton);
266         ui->bhorWidget->layout()->addItem(ui->chorizontalSpacer_2);
267         ui->bhorWidget->layout()->addWidget(ui->artistsButton);
268         ui->bhorWidget->layout()->addItem(ui->chorizontalSpacer_3);
269         ui->bhorWidget->layout()->addWidget(ui->moveDownButton);
270         ui->bhorWidget->layout()->addItem(ui->chorizontalSpacer_4);
271         ui->bhorWidget->layout()->addWidget(ui->sortAlphDescButton);
272         ui->bhorWidget->layout()->addItem(ui->chorizontalSpacer_5);
273         ui->bhorWidget->layout()->addWidget(ui->shuffleButton);
274
275         ui->bhorWidget->show();
276 }
277
278 void PlaylistSortForm::portraitMode() {
279         ui->topWidget->hide();
280         ui->bottomWidget->hide();
281         ui->bhorWidget->hide();
282
283         ui->bhorWidget->layout()->removeWidget(ui->doneButton);
284         ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_0);
285         ui->bhorWidget->layout()->removeWidget(ui->moveTopButton);
286         ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_1);
287         ui->bhorWidget->layout()->removeWidget(ui->sortAlphAscButton);
288         ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_2);
289         ui->bhorWidget->layout()->removeWidget(ui->artistsButton);
290         ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_3);
291         ui->bhorWidget->layout()->removeWidget(ui->sortAlphDescButton);
292         ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_4);
293         ui->bhorWidget->layout()->removeWidget(ui->moveDownButton);
294         ui->bhorWidget->layout()->removeItem(ui->chorizontalSpacer_5);
295         ui->bhorWidget->layout()->removeWidget(ui->shuffleButton);
296
297         ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_0);
298         ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_1);
299         ui->topWidget->layout()->removeWidget(ui->sortAlphAscButton);
300         ui->topWidget->layout()->removeWidget(ui->sortAlphDescButton);
301         ui->topWidget->layout()->removeWidget(ui->artistsButton);
302
303         ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer_0);
304         ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer_1);
305         ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer_2);
306         ui->bottomWidget->layout()->removeWidget(ui->doneButton);
307         ui->bottomWidget->layout()->removeWidget(ui->moveDownButton);
308         ui->bottomWidget->layout()->removeWidget(ui->moveTopButton);
309         ui->bottomWidget->layout()->removeWidget(ui->shuffleButton);
310
311         ui->topWidget->layout()->addWidget(ui->sortAlphAscButton);
312         ui->topWidget->layout()->addItem(ui->thorizontalSpacer_0);
313         ui->topWidget->layout()->addWidget(ui->artistsButton);
314         ui->topWidget->layout()->addItem(ui->thorizontalSpacer_1);
315         ui->topWidget->layout()->addWidget(ui->sortAlphDescButton);
316
317         ui->bottomWidget->layout()->addWidget(ui->doneButton);
318         ui->bottomWidget->layout()->addItem(ui->bhorizontalSpacer_0);
319         ui->bottomWidget->layout()->addWidget(ui->moveDownButton);
320         ui->bottomWidget->layout()->addItem(ui->bhorizontalSpacer_1);
321         ui->bottomWidget->layout()->addWidget(ui->moveTopButton);
322         ui->bottomWidget->layout()->addItem(ui->bhorizontalSpacer_2);
323         ui->bottomWidget->layout()->addWidget(ui->shuffleButton);
324
325         ui->topWidget->show();
326         ui->bottomWidget->show();
327 }
328
329 void PlaylistSortForm::updateTranslations() {
330         ui->retranslateUi(this);
331 }
332
333 void PlaylistSortForm::updateGradiend() {
334         Config config;
335         if (config.getValue("ui/gradient").toString() == "yes") {
336                 ui->bottomWidget->setStyleSheet(_bottom_gradient);
337                 ui->topWidget->setStyleSheet(_top_gradient);
338         } else {
339                 ui->topWidget->setStyleSheet("");
340                 ui->bottomWidget->setStyleSheet("");
341         }
342 }
343
344 void PlaylistSortForm::updateIcons() {
345         Config config;
346         QString icons_theme = config.getValue("ui/iconstheme").toString();
347         ui->doneButton->setIcon(QIcon(":/icons/"+icons_theme+"/use.png"));
348         ui->moveDownButton->setIcon(QIcon(":/icons/"+icons_theme+"/arrow_bottom.png"));
349         ui->moveTopButton->setIcon(QIcon(":/icons/"+icons_theme+"/arrow_top.png"));
350         ui->shuffleButton->setIcon(QIcon(":/icons/"+icons_theme+"/random_on.png"));
351         ui->sortAlphAscButton->setIcon(QIcon(":/icons/"+icons_theme+"/sort_alpha_asc.png"));
352         ui->sortAlphDescButton->setIcon(QIcon(":/icons/"+icons_theme+"/sort_alpha_desc.png"));
353         ui->artistsButton->setIcon(QIcon(":/icons/"+icons_theme+"/artists.png"));
354 }