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