Implemented dynamic playlists
[someplayer] / src / libraryform.cpp
1 #include "libraryform.h"
2 #include "ui_libraryform.h"
3 #include "library.h"
4 #include <QStandardItemModel>
5 #include <QStandardItem>
6 #include <QModelIndex>
7 #include <QModelIndexList>
8 #include "track.h"
9 #include "playlist.h"
10 #include <QDebug>
11 #include <QTime>
12 #include <QQueue>
13
14 using namespace SomePlayer::DataObjects;
15
16 inline QString __format_track_string(TrackMetadata meta) {
17         int minutes = meta.length() / 60;
18         int seconds = meta.length() % 60;
19         QTime time(0, minutes, seconds);
20         return QString("[%1] %2").arg(time.toString("mm:ss")).arg(meta.title());
21
22 }
23
24 inline void __fill_model(QStandardItemModel *model, QList<QString> data) {
25         model->clear();
26         int count = data.count();
27         model->setRowCount(count);
28         for (int i = 0; i < count; i++) {
29                 model->setItem(i, 0, new QStandardItem(data.at(i)));
30         }
31 }
32
33 inline void __fill_model_tracks (QStandardItemModel *model, QList<Track> tracks) {
34         int count = tracks.count();
35         model->setRowCount(count);
36         for (int i = 0; i < count; i++) {
37                 TrackMetadata meta = tracks.at(i).metadata();
38                 model->setItem(i, 0, new QStandardItem(__format_track_string(meta)));
39         }
40 }
41
42 LibraryForm::LibraryForm(Library *lib, QWidget *parent) :
43     QWidget(parent),
44     ui(new Ui::LibraryForm)
45 {
46         _lib = lib;
47         _model = new QStandardItemModel(this);
48         _state = STATE_NONE;
49     ui->setupUi(this);
50         connect(ui->playerButton, SIGNAL(clicked()), this, SLOT(_player()));
51         connect(ui->viewButton, SIGNAL(clicked()), this, SLOT(_view_button()));
52         connect(ui->playlistsButton, SIGNAL(clicked()), this, SLOT(_playlists_button()));
53         connect(ui->dynamicButton, SIGNAL(clicked()), this, SLOT(_dynamic_button()));
54         connect(ui->listView, SIGNAL(clicked(QModelIndex)), this, SLOT(_process_list_click(QModelIndex)));
55         connect(ui->addButton, SIGNAL(clicked()), this, SLOT(_add_button()));
56         connect(ui->backButton, SIGNAL(clicked()), this, SLOT(_back_button()));
57         connect(ui->deleteButton, SIGNAL(clicked()), this, SLOT(_delete_button()));
58         connect(ui->useButton, SIGNAL(clicked()), this, SLOT(_use_button()));
59         _view_button();
60 }
61
62 LibraryForm::~LibraryForm()
63 {
64         _lib->saveCurrentPlaylist(_lib->getCurrentPlaylist());
65     delete ui;
66 }
67
68 void LibraryForm::_player() {
69         emit player();
70 }
71
72 void LibraryForm::_view_button() {
73         QList<QString> artitst = _lib->getArtists();
74         __fill_model(_model, artitst);
75         ui->listView->setModel(_model);
76         _state = STATE_ARTIST;
77         ui->backButton->setEnabled(false);
78         ui->listLabel->setText("Artists");
79         ui->addButton->setEnabled(true);
80         ui->deleteButton->hide();
81         ui->useButton->hide();
82 }
83
84 void LibraryForm::_dynamic_button() {
85         ui->useButton->hide();
86         ui->backButton->setEnabled(false);
87         ui->addButton->setEnabled(true);
88         _model->clear();
89         _model->setRowCount(4);
90         _model->setItem(0, new QStandardItem("Favorites"));
91         _model->setItem(1, new QStandardItem("Most played"));
92         _model->setItem(2, new QStandardItem("Never played"));
93         _model->setItem(3, new QStandardItem("Recently added"));
94         _state = STATE_DYNAMIC;
95 }
96
97 void LibraryForm::_process_list_click(QModelIndex index) {
98         if (_state == STATE_NONE) return;
99         QString data = index.data().toString();
100         switch (_state) {
101         case STATE_ARTIST:
102                 __fill_model(_model, _lib->getAlbumsForArtist(data));
103                 _current_artist = data;
104                 _state = STATE_ALBUM;
105                 ui->backButton->setEnabled(true);
106                 ui->listLabel->setText(QString("Albums by \"%1\"").arg(_current_artist));
107                 break;
108         case STATE_ALBUM:
109                 _current_album = data;
110                 _current_tracks = _lib->getTracksForAlbum(data, _current_artist);
111                 __fill_model_tracks(_model, _current_tracks);
112                 _state = STATE_TRACK;
113                 ui->backButton->setEnabled(true);
114                 ui->listLabel->setText(QString("Tracks from \"%1\" by \"%2\"").arg(_current_album).arg(_current_artist));
115                 break;
116         case STATE_PLAYLIST:
117                 {
118                         _current_playlist = _lib->getPlaylist(data);
119                         _current_tracks = _current_playlist.tracks();
120                         __fill_model_tracks(_model, _current_tracks);
121                         _state = STATE_PLAYLIST_TRACK;
122                         ui->backButton->setEnabled(true);
123                         ui->deleteButton->show();
124                         ui->useButton->show();
125                         ui->listLabel->setText(QString("Tracks in playlist \"%1\"").arg(data));
126                 }
127                 break;
128         case STATE_DYNAMIC:
129                 {
130                         switch(index.row()) {
131                         case 0: //favorites
132                                 _current_playlist = _lib->getFavorites();
133                                 break;
134                         case 1: //most played
135                                 _current_playlist = _lib->getMostPlayed();
136                                 break;
137                         case 2: //never played
138                                 _current_playlist = _lib->getNeverPlayed();
139                         case 3: //recently added
140                                 _current_playlist = _lib->getRecentlyAdded();
141                                 break;
142                         default:
143                                 return;
144                         }
145                         _current_tracks = _current_playlist.tracks();
146                         __fill_model_tracks(_model, _current_tracks);
147                         _state = STATE_PLAYLIST_TRACK;
148                         ui->backButton->setEnabled(true);
149                         ui->useButton->show();
150                         ui->listLabel->setText(_current_playlist.name());
151                 }
152         default:
153                 return;
154         }
155 }
156
157 void LibraryForm::_add_button() {
158         if (_state == STATE_NONE) return;
159         QModelIndexList selected = ui->listView->selectionModel()->selectedIndexes();
160         ui->listView->selectionModel()->clearSelection();
161         emit busy(QString("<H1>Adding... Please wait</H1>"));
162         switch (_state) {
163         case STATE_ARTIST:
164                 foreach (QModelIndex id, selected) {
165                         _add_artist(id.data().toString());
166                 }
167                 break;
168         case STATE_ALBUM:
169                 foreach (QModelIndex id, selected) {
170                         _add_album(_current_artist, id.data().toString());
171                 }
172                 break;
173         case STATE_TRACK:
174                 foreach (QModelIndex id, selected) {
175                         _add_track(_current_tracks.at(id.row()));
176                 }
177                 break;
178         case STATE_PLAYLIST:
179                 foreach (QModelIndex id, selected) {
180                         _add_playlist(id.data().toString());
181                 }
182                 break;
183         case STATE_PLAYLIST_TRACK:
184                 foreach (QModelIndex id, selected) {
185                         _add_track(_current_tracks.at(id.row()));
186                 }
187                 break;
188         default:
189                 emit done();
190                 return;
191         }
192         emit done();
193 }
194
195
196 void LibraryForm::_add_artist(QString artist) {
197         QList<QString> albums = _lib->getAlbumsForArtist(artist);
198         foreach(QString album, albums) {
199                 _add_album(artist, album);
200         }
201 }
202
203 void LibraryForm::_add_album(QString artist, QString album) {
204         QList<Track> tracks = _lib->getTracksForAlbum(album, artist);
205         foreach(Track track, tracks) {
206                 _add_track(track);
207         }
208 }
209
210 void LibraryForm::_add_track(Track track) {
211         Playlist current = _lib->getCurrentPlaylist();
212         current.addTrack(track);
213         _lib->saveCurrentPlaylist(current);
214 }
215
216 void LibraryForm::_add_playlist(QString name) {
217         Playlist playlist = _lib->getPlaylist(name);
218         QList<Track> tracks = playlist.tracks();
219         foreach (Track track, tracks) {
220                 _add_track(track);
221         }
222 }
223
224 void LibraryForm::_back_button() {
225         switch (_state) {
226         case STATE_ALBUM:
227                 _view_button();
228                 break;
229         case STATE_TRACK:
230                 __fill_model(_model, _lib->getAlbumsForArtist(_current_artist));
231                 _state = STATE_ALBUM;
232                 ui->listLabel->setText(QString("Albums by \"%1\"").arg(_current_artist));
233                 break;
234         case STATE_PLAYLIST_TRACK:
235                 _playlists_button();
236         default:
237                 return;
238         }
239 }
240
241 void LibraryForm::_playlists_button() {
242         QList<QString> playlists = _lib->getPlaylistsNames();
243         __fill_model(_model, playlists);
244         ui->listView->setModel(_model);
245         _state = STATE_PLAYLIST;
246         ui->backButton->setEnabled(false);
247         ui->listLabel->setText("Playlists");
248         ui->addButton->setEnabled(false);
249         ui->deleteButton->hide();
250         ui->useButton->hide();
251 }
252
253 void LibraryForm::_delete_button() {
254         if (_state == STATE_PLAYLIST_TRACK) {
255                 QModelIndexList selected = ui->listView->selectionModel()->selectedIndexes();
256                 ui->listView->selectionModel()->clearSelection();
257                 QQueue<int> to_delete;
258                 foreach (QModelIndex id, selected) {
259                         _delete_track(_current_tracks.at(id.row()));
260                         to_delete.append(id.row());
261                 }
262                 qSort(to_delete);
263                 int count = to_delete.count();
264                 for (int i = count-1; i >= 0; i--) {
265                         _current_tracks.removeAt(to_delete.at(i));
266                 }
267                 __fill_model_tracks(_model, _current_tracks);
268         }
269 }
270
271 void LibraryForm::_delete_track(Track track) {
272         Playlist current = _lib->getCurrentPlaylist();
273         current.removeTrack(track);
274         _lib->saveCurrentPlaylist(current);
275 }
276
277 void LibraryForm::_use_button() {
278         _lib->saveCurrentPlaylist(_current_playlist);
279 }