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