ef936602e61d6c9931a1e08c78da3ac1196e0296
[someplayer] / src / libraryform.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 "libraryform.h"
21 #include "ui_libraryform.h"
22 #include "library.h"
23 #include <QStandardItemModel>
24 #include <QStandardItem>
25 #include <QModelIndex>
26 #include <QModelIndexList>
27 #include "track.h"
28 #include "playlist.h"
29 #include <QTime>
30 #include <QTimer>
31 #include <QQueue>
32 #include <QMessageBox>
33 #include "config.h"
34 #include <QSpacerItem>
35 #include <QDebug>
36
37 using namespace SomePlayer::DataObjects;
38 using namespace SomePlayer::Storage;
39
40 inline QString __format_track_string(TrackMetadata meta) {
41         int minutes = meta.length() / 60;
42         int seconds = meta.length() % 60;
43         QTime time(0, minutes, seconds);
44         return QString("[%1] %2").arg(time.toString("mm:ss")).arg(meta.title());
45
46 }
47
48 inline void __fill_model(QStandardItemModel *model, QList<QString> data, QString icons_theme) {
49         model->clear();
50         int count = data.count();
51         model->setRowCount(count);
52         for (int i = 0; i < count; i++) {
53                 model->setItem(i, 0, new QStandardItem(QIcon(":/icons/"+icons_theme+"/deselect_all.png"), ""));
54                 model->setItem(i, 1, new QStandardItem(data.at(i)));
55         }
56 }
57
58 inline void __fill_model_album(QStandardItemModel *model, QMap<QString, int> data, QString icons_theme) {
59         model->clear();
60         int count = data.count();
61         model->setRowCount(count+1);
62         int i = 0;
63         Config config;
64         model->setItem(i, 0, new QStandardItem(QIcon(":/icons/"+icons_theme+"/deselect_all.png"), ""));
65         model->setItem(i, 1, new QStandardItem(QObject::tr("All tracks")));
66         i++;
67         if (config.getValue("ui/albumsorting").toString() == "date") {
68                 QMap<int, QList<QString> > years;
69                 foreach (QString name, data.keys()) {
70                         years[data[name]].append(name);
71                 }
72                 QList<int> keys = years.keys();
73                 qSort(keys);
74
75                 foreach (int year, keys) {
76                         foreach (QString name, years[year]) {
77                                 model->setItem(i, 0, new QStandardItem(QIcon(":/icons/"+icons_theme+"/deselect_all.png"), ""));
78                                 model->setItem(i, 1, new QStandardItem(QString("[%1] %2").arg(year).arg(name)));
79                                 i++;
80                         }
81                 }
82         } else {
83                 QList<QString> names = data.keys();
84                 foreach (QString name, names) {
85                         model->setItem(i, 0, new QStandardItem(QIcon(":/icons/"+icons_theme+"/deselect_all.png"), ""));
86                         model->setItem(i, 1, new QStandardItem(QString("[%1] %2").arg(data[name]).arg(name)));
87                         i++;
88                 }
89         }
90 }
91
92 inline void __fill_model_tracks (QStandardItemModel *model, QList<Track> tracks, QString icons_theme) {
93         int count = tracks.count();
94         model->setRowCount(count);
95         Config config;
96         bool show_lenght = (config.getValue("ui/showtracklenght").toString() != "no");
97         for (int i = 0; i < count; i++) {
98                 TrackMetadata meta = tracks.at(i).metadata();
99                 if (show_lenght) {
100                         model->setItem(i, 0, new QStandardItem(QIcon(":/icons/"+icons_theme+"/deselect_all.png"), ""));
101                         model->setItem(i, 1, new QStandardItem(__format_track_string(meta)));
102                 } else {
103                         model->setItem(i, 0, new QStandardItem(QIcon(":/icons/"+icons_theme+"/deselect_all.png"), ""));
104                         model->setItem(i, 1, new QStandardItem(meta.title()));
105                 }
106         }
107 }
108
109 LibraryForm::LibraryForm(Library *lib, QWidget *parent) :
110     QWidget(parent),
111     ui(new Ui::LibraryForm)
112 {
113         _lib = lib;
114         Config config;
115         _icons_theme = config.getValue("ui/iconstheme").toString();
116         _model = new QStandardItemModel(this);
117         _model->setColumnCount(2);
118         _state = STATE_NONE;
119         _tools_widget = new ToolsWidget(this);
120         _search_in_library_button = new QPushButton(QIcon(":/icons/"+_icons_theme+"/search.png"), "", _tools_widget);
121         _search_in_library_button->setFlat(true);
122         _search_in_library_button->setCheckable(true);
123         _tools_widget->layout()->addItem(new QSpacerItem(20, 20));
124         _tools_widget->layout()->addWidget(_search_in_library_button);
125         ui->setupUi(this);
126         ui->listView->setModel(_model);
127         ui->listView->setColumnWidth(0, 70);
128         ui->toolsLayout->addWidget(_tools_widget);
129         _tools_widget->hideFSButton();
130         _tools_widget->hide();
131         connect(ui->viewButton, SIGNAL(clicked()), this, SLOT(_view_button()));
132         connect(ui->playlistsButton, SIGNAL(clicked()), this, SLOT(_playlists_button()));
133         connect(ui->dynamicButton, SIGNAL(clicked()), this, SLOT(_dynamic_button()));
134         connect(ui->listView, SIGNAL(clicked(QModelIndex)), this, SLOT(_process_list_click(QModelIndex)));
135         connect(ui->listView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(_process_dblclick(QModelIndex)));
136         connect(ui->listView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
137                 this, SLOT(_process_selection(QItemSelection,QItemSelection)));
138         connect(ui->addButton, SIGNAL(clicked()), this, SLOT(_add_button()));
139         connect(ui->selectAllButton, SIGNAL(clicked()), this, SLOT(_toggle_select_all_button()));
140         connect(ui->backButton, SIGNAL(clicked()), this, SLOT(_back_button()));
141         connect(ui->deleteButton, SIGNAL(clicked()), this, SLOT(_delete_button()));
142         connect(ui->useButton, SIGNAL(clicked()), this, SLOT(_use_button()));
143         connect(_tools_widget, SIGNAL(search(QString)), this, SLOT(search(QString)));
144         connect(_tools_widget, SIGNAL(nextSearch()), this, SLOT(nextItem()));
145         connect(_tools_widget, SIGNAL(prevSearch()), this, SLOT(prevItem()));
146         connect(ui->moreButton, SIGNAL(clicked()), this, SLOT(_more_button()));
147         connect(_search_in_library_button, SIGNAL(toggled(bool)), this, SLOT(_search_button(bool)));
148         connect(ui->playerButton, SIGNAL(clicked()), this, SLOT(hide()));
149         _view_button();
150         _top_gradient = ui->topWidget->styleSheet();
151         _bottom_gradient = ui->bottomWidget->styleSheet();
152         _is_dynamic = false;
153         _is_favorites = false;
154         setAttribute(Qt::WA_Maemo5StackedWindow);
155         setWindowFlags(Qt::Window | windowFlags());
156         ui->addButton->setEnabled(false);
157         ui->addButton->setIcon(QIcon());
158         ui->deleteButton->setEnabled(false);
159         ui->deleteButton->setIcon(QIcon());
160 }
161
162 LibraryForm::~LibraryForm()
163 {
164         delete ui;
165 }
166
167 void LibraryForm::_view_button() {
168         QList<QString> artitst = _lib->getArtists();
169         __fill_model(_model, artitst, _icons_theme);
170         ui->listView->setColumnWidth(0, 70);
171         _state = STATE_ARTIST;
172         ui->backButton->setEnabled(false);
173         ui->backButton->setIcon(QIcon());
174         ui->listLabel->setText(tr("Artists"));
175         ui->useButton->setEnabled(false);
176         ui->useButton->setIcon(QIcon());
177         ui->addButton->setEnabled(false);
178         ui->addButton->setIcon(QIcon());
179         ui->deleteButton->setEnabled(false);
180         ui->deleteButton->setIcon(QIcon());
181 }
182
183 void LibraryForm::_dynamic_button() {
184         ui->useButton->setEnabled(false);
185         ui->useButton->setIcon(QIcon());
186         ui->backButton->setEnabled(false);
187         ui->backButton->setIcon(QIcon());
188         ui->deleteButton->setEnabled(false);
189         ui->deleteButton->setIcon(QIcon());
190         _model->clear();
191         _model->setRowCount(4);
192         _model->setItem(0, 0, new QStandardItem(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"), ""));
193         _model->setItem(0, 1, new QStandardItem("Favorites"));
194         _model->setItem(1, 0, new QStandardItem(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"), ""));
195         _model->setItem(1, 1, new QStandardItem("Most played"));
196         _model->setItem(2, 0, new QStandardItem(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"), ""));
197         _model->setItem(2, 1, new QStandardItem("Never played"));
198         _model->setItem(3, 0, new QStandardItem(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"), ""));
199         _model->setItem(3, 1, new QStandardItem("Recently added"));
200         ui->listView->setColumnWidth(0, 70);
201         ui->listLabel->setText(tr("Dynamic playlists"));
202         _state = STATE_DYNAMIC;
203         ui->addButton->setEnabled(false);
204         ui->addButton->setIcon(QIcon());
205         ui->deleteButton->setEnabled(false);
206         ui->deleteButton->setIcon(QIcon());
207 }
208
209 void LibraryForm::_process_list_click(QModelIndex index) {
210         if (index.column() == 0) {
211                 return;
212         }
213         if (_state == STATE_NONE) return;
214         QString data = index.data().toString();
215         QRegExp regexp("\\[\\d+\\]\\ (.*)");
216         switch (_state) {
217         case STATE_ARTIST:
218                 __fill_model_album(_model, _lib->getAlbumsForArtist(data), _icons_theme);
219                 ui->listView->setColumnWidth(0, 70);
220                 ui->listView->scrollToTop();
221                 _current_artist = data;
222                 _state = STATE_ALBUM;
223                 ui->backButton->setEnabled(true);
224                 ui->backButton->setIcon(QIcon(":/icons/"+_icons_theme+"/back.png"));
225                 ui->listLabel->setText(QString(tr("Albums by \"%1\"")).arg(_current_artist));
226                 break;
227         case STATE_ALBUM:
228                 if (regexp.indexIn(data) != -1) {
229                         _current_album = regexp.cap(1).trimmed();
230                         _current_tracks = _lib->getTracksForAlbum(_current_album, _current_artist);
231                         __fill_model_tracks(_model, _current_tracks, _icons_theme);
232                         ui->listView->setColumnWidth(0, 70);
233                         ui->listView->scrollToTop();
234                         _state = STATE_TRACK;
235                         ui->backButton->setEnabled(true);
236                         ui->backButton->setIcon(QIcon(":/icons/"+_icons_theme+"/back.png"));
237                         ui->listLabel->setText(QString(tr("Tracks from \"%1\" by \"%2\"")).arg(_current_album).arg(_current_artist));
238                 } else {
239                         if (index.row() == 0) { // all tracks
240                                 _current_tracks = _lib->getAllTracksForArtist(_current_artist);
241                                 __fill_model_tracks(_model, _current_tracks, _icons_theme);
242                                 ui->listView->setColumnWidth(0, 70);
243                                 ui->listView->scrollToTop();
244                                 _state = STATE_TRACK;
245                                 ui->backButton->setEnabled(true);
246                                 ui->backButton->setIcon(QIcon(":/icons/"+_icons_theme+"/back.png"));
247                                 ui->listLabel->setText(QString(tr("All tracks by \"%1\"")).arg(_current_artist));
248                         }
249                 }
250                 break;
251         case STATE_PLAYLIST:
252                 {
253                         _current_playlist = _lib->getPlaylist(data);
254                         _current_tracks = _current_playlist.tracks();
255                         __fill_model_tracks(_model, _current_tracks, _icons_theme);
256                         ui->listView->setColumnWidth(0, 70);
257                         ui->listView->scrollToTop();
258                         _state = STATE_PLAYLIST_TRACK;
259                         _is_dynamic = false;
260                         ui->backButton->setEnabled(true);
261                         ui->backButton->setIcon(QIcon(":/icons/"+_icons_theme+"/back.png"));
262                         ui->useButton->setEnabled(true);
263                         ui->useButton->setIcon(QIcon(":/icons/"+_icons_theme+"/use.png"));
264                         ui->listLabel->setText(QString(tr("Tracks in playlist \"%1\"")).arg(data));
265                 }
266                 break;
267         case STATE_DYNAMIC:
268                 {
269                         switch(index.row()) {
270                         case 0: //favorites
271                                 _current_playlist = _lib->getFavorites();
272                                 _is_favorites = true;
273                                 break;
274                         case 1: //most played
275                                 _current_playlist = _lib->getMostPlayed();
276                                 _is_favorites = false;
277                                 break;
278                         case 2: //never played
279                                 _current_playlist = _lib->getNeverPlayed();
280                                 _is_favorites = false;
281                         case 3: //recently added
282                                 _current_playlist = _lib->getRecentlyAdded();
283                                 _is_favorites = false;
284                                 break;
285                         default:
286                                 return;
287                         }
288                         _current_tracks = _current_playlist.tracks();
289                         __fill_model_tracks(_model, _current_tracks, _icons_theme);
290                         ui->listView->setColumnWidth(0, 70);
291                         ui->listView->scrollToTop();
292                         _state = STATE_PLAYLIST_TRACK;
293                         _is_dynamic = true;
294                         ui->backButton->setEnabled(true);
295                         ui->backButton->setIcon(QIcon(":/icons/"+_icons_theme+"/back.png"));
296                         ui->useButton->setEnabled(true);
297                         ui->useButton->setIcon(QIcon(":/icons/"+_icons_theme+"/use.png"));
298                         ui->listLabel->setText(_current_playlist.name());
299                 }
300         default:
301                 return;
302         }
303         ui->addButton->setEnabled(false);
304         ui->addButton->setIcon(QIcon());
305         ui->deleteButton->setEnabled(false);
306         ui->deleteButton->setIcon(QIcon());
307         QTimer::singleShot(100, ui->listView, SLOT(clearSelection())); // workaround
308 }
309
310 void LibraryForm::_add_button() {
311         if (_state == STATE_NONE) return;
312         QModelIndexList selected = ui->listView->selectionModel()->selectedIndexes();
313         ui->listView->selectionModel()->clearSelection();
314         Playlist cur = _lib->getCurrentPlaylist();
315         QRegExp regexp("\\[\\d+\\]\\ (.*)");
316         switch (_state) {
317         case STATE_ARTIST:
318                 foreach (QModelIndex id, selected) {
319                         _add_artist(&cur, id.data().toString());
320                 }
321                 _lib->saveCurrentPlaylist(cur);
322                 emit refreshPlayer();
323                 break;
324         case STATE_ALBUM:
325                 foreach (QModelIndex id, selected) {
326                         if (regexp.indexIn(id.data().toString()) != -1) {
327                                 _add_album(&cur, _current_artist, regexp.cap(1).trimmed());
328                         }
329                 }
330                 _lib->saveCurrentPlaylist(cur);
331                 emit refreshPlayer();
332                 break;
333         case STATE_TRACK:
334                 foreach (QModelIndex id, selected) {
335                         _add_track(&cur, _current_tracks.at(id.row()));
336                 }
337                 _lib->saveCurrentPlaylist(cur);
338                 emit refreshPlayer();
339                 break;
340         case STATE_PLAYLIST:
341                 foreach (QModelIndex id, selected) {
342                         _add_playlist(&cur, id.data().toString());
343                 }
344                 _lib->saveCurrentPlaylist(cur);
345                 emit refreshPlayer();
346                 break;
347         case STATE_PLAYLIST_TRACK:
348                 foreach (QModelIndex id, selected) {
349                         _add_track(&cur, _current_tracks.at(id.row()));
350                 }
351                 _lib->saveCurrentPlaylist(cur);
352                 emit refreshPlayer();
353                 break;
354         case STATE_SEARCH:
355                 foreach (QModelIndex id, selected) {
356                         _add_track(&cur, _current_tracks.at(id.row()));
357                 }
358                 _lib->saveCurrentPlaylist(cur);
359                 emit refreshPlayer();
360                 break;
361         default:
362                 return;
363         }
364 }
365
366
367 void LibraryForm::_add_artist(Playlist *cur, QString artist) {
368         QMap<QString, int> albums = _lib->getAlbumsForArtist(artist);
369         foreach(QString album, albums.keys()) {
370                 _add_album(cur, artist, album);
371         }
372 }
373
374 void LibraryForm::_add_album(Playlist *cur, QString artist, QString album) {
375         QList<Track> tracks = _lib->getTracksForAlbum(album, artist);
376         foreach(Track track, tracks) {
377                 _add_track(cur, track);
378         }
379 }
380
381 void LibraryForm::_add_track(Playlist *cur, Track track) {
382         cur->addTrack(track);
383 }
384
385 void LibraryForm::_add_playlist(Playlist *cur, QString name) {
386         Playlist playlist = _lib->getPlaylist(name);
387         QList<Track> tracks = playlist.tracks();
388         foreach (Track track, tracks) {
389                 _add_track(cur, track);
390         }
391 }
392
393 void LibraryForm::_back_button() {
394         switch (_state) {
395         case STATE_ALBUM:
396                 _view_button();
397                 ui->listView->scrollToTop();
398                 break;
399         case STATE_TRACK:
400                 __fill_model_album(_model, _lib->getAlbumsForArtist(_current_artist), _icons_theme);
401                 ui->listView->setColumnWidth(0, 70);
402                 ui->listView->scrollToTop();
403                 _state = STATE_ALBUM;
404                 ui->listLabel->setText(QString(tr("Albums by \"%1\"")).arg(_current_artist));
405                 break;
406         case STATE_PLAYLIST_TRACK:
407                 if (_is_dynamic) {
408                         _dynamic_button();
409                         _is_dynamic = false;
410                 } else {
411                         _playlists_button();
412                 }
413                 ui->listView->scrollToTop();
414         default:
415                 return;
416         }
417 }
418
419 void LibraryForm::_playlists_button() {
420         QList<QString> playlists = _lib->getPlaylistsNames();
421         __fill_model(_model, playlists, _icons_theme);
422         ui->listView->setColumnWidth(0, 70);
423         _state = STATE_PLAYLIST;
424         ui->backButton->setEnabled(false);
425         ui->backButton->setIcon(QIcon());
426         ui->listLabel->setText(tr("Playlists"));
427         ui->useButton->setEnabled(false);
428         ui->useButton->setIcon(QIcon());
429         ui->addButton->setEnabled(false);
430         ui->addButton->setIcon(QIcon());
431         ui->deleteButton->setEnabled(false);
432         ui->deleteButton->setIcon(QIcon());
433 }
434
435 void LibraryForm::_delete_button() {
436         if (_state == STATE_PLAYLIST_TRACK) {
437                 QModelIndexList selected = ui->listView->selectionModel()->selectedIndexes();
438                 ui->listView->selectionModel()->clearSelection();
439                 QQueue<int> to_delete;
440                 foreach (QModelIndex id, selected) {
441                         if (!to_delete.contains(id.row()))
442                                 to_delete.append(id.row());
443                 }
444                 qSort(to_delete);
445                 int count = to_delete.count();
446                 if (_is_dynamic && _is_favorites) {
447                         _current_tracks = _lib->getFavorites().tracks();
448                         for (int i = count-1; i >= 0; i--) {
449                                 _lib->removeFromFavorites(_current_tracks.at(to_delete.at(i)));
450                         }
451                         _current_playlist = _lib->getFavorites();
452                         _current_tracks = _current_playlist.tracks();
453                 } else {
454                         for (int i = count-1; i >= 0; i--) {
455                                 _current_playlist.removeTrackAt(to_delete.at(i));
456                         }
457                         _current_tracks = _current_playlist.tracks();
458                         _lib->savePlaylist(_current_playlist);
459                         emit refreshPlayer();
460                 }
461                 __fill_model_tracks(_model, _current_tracks, _icons_theme);
462                 ui->listView->setColumnWidth(0, 70);
463         } else if (_state == STATE_PLAYLIST) {
464                 QModelIndexList selected = ui->listView->selectionModel()->selectedIndexes();
465                 QQueue<int> to_delete;
466                 foreach (QModelIndex id, selected) {
467                         if (!to_delete.contains(id.row()))
468                                 to_delete.append(id.row());
469                 }
470                 qSort(to_delete);
471                 int count = to_delete.count();
472                 for (int i = count-1; i >= 0; i--) {
473                         QString name = _model->item(to_delete.at(i), 1)->text();
474                         if (name != _CURRENT_PLAYLIST_SUBST_) {
475                                 _lib->removePlaylist(name);
476                                 _model->removeRow(to_delete.at(i));
477                         }
478                 }
479         }
480 }
481
482 void LibraryForm::_delete_track(Track track) {
483         Playlist current = _lib->getCurrentPlaylist();
484         current.removeTrack(track);
485         _lib->saveCurrentPlaylist(current);
486         emit refreshPlayer();
487 }
488
489 void LibraryForm::_use_button() {
490         _lib->saveCurrentPlaylist(_current_playlist);
491         emit refreshPlayer();
492         _current_playlist = _lib->getCurrentPlaylist();
493 }
494
495 void LibraryForm::search(QString pattern) {
496         _search_pattern = pattern;
497         _search_current_id = -1;
498         nextItem();
499 }
500
501 void LibraryForm::nextItem() {
502         QString data = _model->index(_search_current_id, 0).data().toString();
503         for (int i = _search_current_id+1; i < _model->rowCount(); i++) {
504                 data = _model->index(i, 1).data().toString();
505                 if (data.contains(_search_pattern, Qt::CaseInsensitive)) {
506                         _search_current_id = i;
507                         break;
508                 }
509         }
510         QModelIndex id = _model->index(_search_current_id, 1);
511         ui->listView->selectionModel()->clearSelection();
512         ui->listView->selectRow(id.row());
513         ui->listView->scrollTo(id);
514 }
515
516 void LibraryForm::prevItem() {
517         QString data = _model->index(_search_current_id, 0).data().toString();
518         for (int i = _search_current_id-1; i >= 0; i--) {
519                 data = _model->index(i, 1).data().toString();
520                 if (data.contains(_search_pattern, Qt::CaseInsensitive)) {
521                         _search_current_id = i;
522                         break;
523                 }
524         }
525         QModelIndex id = _model->index(_search_current_id, 1);
526         ui->listView->selectionModel()->clearSelection();
527         ui->listView->selectRow(id.row());
528         ui->listView->scrollTo(id);
529 }
530
531 void LibraryForm::cancelSearch() {
532         _search_pattern = "";
533         ui->listView->selectionModel()->clearSelection();
534 }
535
536 void LibraryForm::refresh() {
537         switch (_state) {
538         case STATE_ARTIST:
539                 _view_button();
540                 break;
541         case STATE_ALBUM:
542                 __fill_model_album(_model, _lib->getAlbumsForArtist(_current_artist), _icons_theme);
543                 ui->listView->setColumnWidth(0, 70);
544                 break;
545         case STATE_PLAYLIST:
546                 _playlists_button();
547                 break;
548         case STATE_DYNAMIC:
549                 _dynamic_button();
550                 break;
551         case STATE_PLAYLIST_TRACK:
552                 _current_playlist = _lib->getPlaylist(_current_playlist.name());
553                 _current_tracks = _current_playlist.tracks();
554                 __fill_model_tracks(_model, _current_tracks, _icons_theme);
555                 ui->listView->setColumnWidth(0, 70);
556                 break;
557         case STATE_TRACK:
558                 _current_tracks = _lib->getTracksForAlbum(_current_album, _current_artist);
559                 __fill_model_tracks(_model, _current_tracks, _icons_theme);
560                 break;
561         default:
562                 return;
563         }
564 }
565
566 void LibraryForm::_toggle_select_all_button() {
567         if (ui->listView->selectionModel()->selectedIndexes().count() == _model->rowCount() * _model->columnCount()) {
568                 ui->listView->selectionModel()->clearSelection();
569                 ui->selectAllButton->setIcon(QIcon(":/icons/"+_icons_theme+"/select_all.png"));
570         } else {
571                 disconnect(ui->listView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
572                            this, SLOT(_process_selection(QItemSelection,QItemSelection)));
573                 ui->listView->selectAll();
574                 int cnt = _model->rowCount();
575                 for (int i = 0; i < cnt; i++) {
576                         _model->item(i)->setIcon(QIcon(":/icons/"+_icons_theme+"/select_all.png"));
577                 }
578                 connect(ui->listView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
579                            this, SLOT(_process_selection(QItemSelection,QItemSelection)));
580                 ui->selectAllButton->setIcon(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"));
581                 ui->addButton->setIcon(QIcon(":/icons/"+_icons_theme+"/add.png"));
582                 ui->addButton->setEnabled(true);
583                 if (_state == STATE_PLAYLIST || (_state == STATE_PLAYLIST_TRACK && !_is_dynamic)
584                         || (_state == STATE_PLAYLIST_TRACK && _is_favorites)) {
585                         ui->deleteButton->setEnabled(true);
586                         ui->deleteButton->setIcon(QIcon(":/icons/"+_icons_theme+"/delete.png"));
587                 }
588         }
589 }
590
591 void LibraryForm::landscapeMode() {
592         landscape = true;
593         ui->topWidget->hide();
594         ui->bottomWidget->hide();
595
596         ui->lverticalLayout->removeItem(ui->lverticalSpacer_0);
597         ui->lverticalLayout->removeItem(ui->lverticalSpacer_1);
598         ui->lverticalLayout->removeItem(ui->lverticalSpacer_2);
599         ui->lverticalLayout->removeItem(ui->lverticalSpacer_3);
600         ui->lverticalLayout->addWidget(ui->backButton);
601         ui->lverticalLayout->addItem(ui->lverticalSpacer_0);
602         ui->lverticalLayout->addWidget(ui->addButton);
603         ui->lverticalLayout->addItem(ui->lverticalSpacer_1);
604         ui->lverticalLayout->addWidget(ui->deleteButton);
605         ui->lverticalLayout->addItem(ui->lverticalSpacer_2);
606         ui->lverticalLayout->addWidget(ui->useButton);
607         ui->lverticalLayout->addItem(ui->lverticalSpacer_3);
608         ui->lverticalLayout->addWidget(ui->playerButton);
609
610         ui->rverticalLayout->removeItem(ui->rverticalSpacer_0);
611         ui->rverticalLayout->removeItem(ui->rverticalSpacer_1);
612         ui->rverticalLayout->removeItem(ui->rverticalSpacer_2);
613         ui->rverticalLayout->removeItem(ui->rverticalSpacer_3);
614         ui->rverticalLayout->addWidget(ui->moreButton);
615         ui->rverticalLayout->addItem(ui->rverticalSpacer_0);
616         ui->rverticalLayout->addWidget(ui->selectAllButton);
617         ui->rverticalLayout->addItem(ui->rverticalSpacer_1);
618         ui->rverticalLayout->addWidget(ui->viewButton);
619         ui->rverticalLayout->addItem(ui->rverticalSpacer_2);
620         ui->rverticalLayout->addWidget(ui->dynamicButton);
621         ui->rverticalLayout->addItem(ui->rverticalSpacer_3);
622         ui->rverticalLayout->addWidget(ui->playlistsButton);
623
624         if (_tools_widget->isVisible()) {
625                 ui->moreButton->setIcon(QIcon(":/icons/"+_icons_theme+"/more_l.png"));
626         } else {
627                 ui->moreButton->setIcon(QIcon(":/icons/"+_icons_theme+"/unmore_l.png"));
628         }
629 }
630
631 void LibraryForm::portraitMode() {
632         landscape = false;
633
634         ui->topWidget->show();
635         ui->bottomWidget->show();
636
637         ui->lverticalLayout->removeItem(ui->lverticalSpacer_0);
638         ui->lverticalLayout->removeItem(ui->lverticalSpacer_1);
639         ui->lverticalLayout->removeItem(ui->lverticalSpacer_2);
640         ui->lverticalLayout->removeItem(ui->lverticalSpacer_3);
641
642         ui->rverticalLayout->removeItem(ui->rverticalSpacer_0);
643         ui->rverticalLayout->removeItem(ui->rverticalSpacer_1);
644         ui->rverticalLayout->removeItem(ui->rverticalSpacer_2);
645         ui->rverticalLayout->removeItem(ui->rverticalSpacer_3);
646
647         ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_0);
648         ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_1);
649         ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_2);
650         ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_3);
651         ui->topWidget->layout()->removeItem(ui->thorizontalSpacer_4);
652         ui->topWidget->layout()->addWidget(ui->backButton);
653         ui->topWidget->layout()->addItem(ui->thorizontalSpacer_0);
654         ui->topWidget->layout()->addWidget(ui->deleteButton);
655         ui->topWidget->layout()->addItem(ui->thorizontalSpacer_1);
656         ui->topWidget->layout()->addWidget(ui->addButton);
657         ui->topWidget->layout()->addItem(ui->thorizontalSpacer_2);
658         ui->topWidget->layout()->addWidget(ui->useButton);
659         ui->topWidget->layout()->addItem(ui->thorizontalSpacer_3);
660         ui->topWidget->layout()->addWidget(ui->selectAllButton);
661         ui->topWidget->layout()->addItem(ui->thorizontalSpacer_4);
662         ui->topWidget->layout()->addWidget(ui->moreButton);
663
664         ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer_0);
665         ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer_1);
666         ui->bottomWidget->layout()->removeItem(ui->bhorizontalSpacer_2);
667         ui->bottomWidget->layout()->addWidget(ui->playerButton);
668         ui->bottomWidget->layout()->addItem(ui->bhorizontalSpacer_0);
669         ui->bottomWidget->layout()->addWidget(ui->viewButton);
670         ui->bottomWidget->layout()->addItem(ui->bhorizontalSpacer_1);
671         ui->bottomWidget->layout()->addWidget(ui->dynamicButton);
672         ui->bottomWidget->layout()->addItem(ui->bhorizontalSpacer_2);
673         ui->bottomWidget->layout()->addWidget(ui->playlistsButton);
674
675         if (_tools_widget->isVisible()) {
676                 ui->moreButton->setIcon(QIcon(":/icons/"+_icons_theme+"/unmore.png"));
677         } else {
678                 ui->moreButton->setIcon(QIcon(":/icons/"+_icons_theme+"/more.png"));
679         }
680 }
681
682 void LibraryForm::_more_button() {
683         if (_tools_widget->isVisible()) {
684                 ui->moreButton->setIcon(QIcon(landscape ? ":/icons/"+_icons_theme+"/unmore_l.png" : ":/icons/"+_icons_theme+"/more.png"));
685                 _tools_widget->hide();
686                 _tools_widget->reset();
687                 cancelSearch();
688         } else {
689                 ui->moreButton->setIcon(QIcon(landscape ? ":/icons/"+_icons_theme+"/more_l.png" : ":/icons/"+_icons_theme+"/unmore.png"));
690                 _tools_widget->show();
691                 _tools_widget->setFocus();
692         }
693 }
694
695
696 void LibraryForm::updateIcons() {
697         Config config;
698         _icons_theme = config.getValue("ui/iconstheme").toString();
699         _tools_widget->updateIcons();
700         if (!ui->addButton->icon().isNull()) {
701                 ui->addButton->setIcon(QIcon(":/icons/"+_icons_theme+"/add.png"));
702         }
703         if (!ui->deleteButton->icon().isNull()) {
704                 ui->deleteButton->setIcon(QIcon(":/icons/"+_icons_theme+"/delete.png"));
705         }
706         if (!ui->useButton->icon().isNull()) {
707                 ui->useButton->setIcon(QIcon(":/icons/"+_icons_theme+"/use.png"));
708         }
709         if (!ui->backButton->icon().isNull()) {
710                 ui->backButton->setIcon(QIcon(":/icons/"+_icons_theme+"/back.png"));
711         }
712         if (!ui->dynamicButton->icon().isNull()) {
713                 ui->dynamicButton->setIcon(QIcon(":/icons/"+_icons_theme+"/dynamic.png"));
714         }
715         if (_tools_widget->isVisible()) {
716                 ui->moreButton->setIcon(QIcon(landscape ? ":/icons/"+_icons_theme+"/more_l.png" : ":/icons/"+_icons_theme+"/unmore.png"));
717         } else {
718                 ui->moreButton->setIcon(QIcon(landscape ? ":/icons/"+_icons_theme+"/unmore_l.png" : ":/icons/"+_icons_theme+"/more.png"));
719         }
720         if (!ui->playlistsButton->icon().isNull()) {
721                 ui->playlistsButton->setIcon(QIcon(":/icons/"+_icons_theme+"/playlists.png"));
722         }
723         ui->playerButton->setIcon(QIcon(":/icons/"+_icons_theme+"/player.png"));
724         if (!ui->viewButton->icon().isNull()) {
725                 ui->viewButton->setIcon(QIcon(":/icons/"+_icons_theme+"/artists.png"));
726         }
727         if (ui->listView->selectionModel()->selectedRows().count() == _model->rowCount()) {
728                 ui->selectAllButton->setIcon(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"));
729         } else {
730                 ui->selectAllButton->setIcon(QIcon(":/icons/"+_icons_theme+"/select_all.png"));
731         }
732         _search_in_library_button->setIcon(QIcon(":/icons/"+_icons_theme+"/search.png"));
733         refresh();
734 }
735
736 void LibraryForm::checkGradient() {
737         Config config;
738         if (config.getValue("ui/gradient").toString() == "yes") {
739                 ui->bottomWidget->setStyleSheet(_bottom_gradient);
740                 ui->topWidget->setStyleSheet(_top_gradient);
741         } else {
742                 ui->topWidget->setStyleSheet("");
743                 ui->bottomWidget->setStyleSheet("");
744         }
745 }
746
747 void LibraryForm::_process_selection(QItemSelection selected, QItemSelection deselected) {
748         foreach (QModelIndex id, selected.indexes()) {
749                 if (id.column() == 0) {
750                         _model->item(id.row())->setIcon(QIcon(":/icons/"+_icons_theme+"/select_all.png"));
751                 }
752                 ui->listView->selectionModel()->select(id, QItemSelectionModel::Select);
753         }
754         foreach (QModelIndex id, deselected.indexes()) {
755                 if (id.column() == 0) {
756                         _model->item(id.row())->setIcon(QIcon(":/icons/"+_icons_theme+"/deselect_all.png"));
757                 }
758                 ui->listView->selectionModel()->select(id, QItemSelectionModel::Deselect);
759         }
760         if (ui->listView->selectionModel()->selectedRows().count() > 0) {
761                 ui->addButton->setEnabled(true);
762                 ui->addButton->setIcon(QIcon(":/icons/"+_icons_theme+"/add.png"));
763                 if (_state == STATE_PLAYLIST || (_state == STATE_PLAYLIST_TRACK && !_is_dynamic)
764                         || (_state == STATE_PLAYLIST_TRACK && _is_favorites)) {
765                         ui->deleteButton->setEnabled(true);
766                         ui->deleteButton->setIcon(QIcon(":/icons/"+_icons_theme+"/delete.png"));
767                 }
768         } else {
769                 ui->addButton->setEnabled(false);
770                 ui->addButton->setIcon(QIcon());
771                 ui->deleteButton->setEnabled(false);
772                 ui->deleteButton->setIcon(QIcon());
773         }
774 }
775
776 void LibraryForm::_process_dblclick(QModelIndex id) {
777         if (id.column() == 0)
778                 return;
779         if (_state == STATE_TRACK || _state == STATE_PLAYLIST_TRACK || _state == STATE_SEARCH) {
780                 Playlist cur = _lib->getCurrentPlaylist();
781                 Track track = _current_tracks.at(id.row());
782                 cur.addTrack(track);
783                 _lib->saveCurrentPlaylist(cur);
784                 emit refreshPlayer();
785                 emit addAndPlay(track);
786                 ui->listView->clearSelection();
787         }
788 }
789
790 void LibraryForm::_search_button(bool state) {
791         ui->moreButton->setEnabled(!state);
792         _tools_widget->toggleArrows(!state);
793         ui->backButton->setEnabled(!state);
794         ui->backButton->setIcon(state ? QIcon() : QIcon(":/icons/"+_icons_theme+"/back.png"));
795         _tools_widget->setFocus();
796         _tools_widget->reset();
797         if (state) {
798                 ui->listLabel->setText(tr("Search in library"));
799                 ui->deleteButton->setIcon(QIcon());
800                 ui->deleteButton->setEnabled(false);
801                 ui->useButton->setIcon(QIcon());
802                 ui->useButton->setEnabled(false);
803                 ui->viewButton->setIcon(QIcon());
804                 ui->viewButton->setEnabled(false);
805                 ui->dynamicButton->setIcon(QIcon());
806                 ui->dynamicButton->setEnabled(false);
807                 ui->playlistsButton->setIcon(QIcon());
808                 ui->playlistsButton->setEnabled(false);
809                 disconnect(_tools_widget, SIGNAL(search(QString)), this, SLOT(search(QString)));
810                 connect(_tools_widget, SIGNAL(search(QString)), this, SLOT(_search_in_library(QString)));
811                 _model->clear();
812                 _state = STATE_SEARCH;
813         } else {
814                 ui->viewButton->setIcon(QIcon(":/icons/"+_icons_theme+"/artists.png"));
815                 ui->viewButton->setEnabled(true);
816                 ui->dynamicButton->setIcon(QIcon(":/icons/"+_icons_theme+"/dynamic.png"));
817                 ui->dynamicButton->setEnabled(true);
818                 ui->playlistsButton->setIcon(QIcon(":/icons/"+_icons_theme+"/playlists.png"));
819                 ui->playlistsButton->setEnabled(true);
820                 _view_button();
821                 connect(_tools_widget, SIGNAL(search(QString)), this, SLOT(search(QString)));
822                 disconnect(_tools_widget, SIGNAL(search(QString)), this, SLOT(_search_in_library(QString)));
823         }
824 }
825
826 void LibraryForm::_search_in_library(QString pattern) {
827         pattern = pattern.trimmed();
828         if (pattern.isEmpty()) {
829                 _model->clear();
830                 return;
831         }
832         _current_tracks = _lib->searchTracks(pattern);
833         __fill_model_tracks(_model, _current_tracks, _icons_theme);
834         ui->listView->setColumnWidth(0, 70);
835         ui->listView->scrollToTop();
836 }
837
838 void LibraryForm::updateTranslations() {
839         ui->retranslateUi(this);
840 }