2 * SomePlayer - An alternate music player for Maemo 5
3 * Copyright (C) 2010 Nikolay (somebody) Tischenko <niktischenko@gmail.com>
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.
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.
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.
20 #include "libraryform.h"
21 #include "ui_libraryform.h"
23 #include <QStandardItemModel>
24 #include <QStandardItem>
25 #include <QModelIndex>
26 #include <QModelIndexList>
32 #include <QMessageBox>
34 #include <QSpacerItem>
36 using namespace SomePlayer::DataObjects;
37 using namespace SomePlayer::Storage;
39 inline QString __format_track_string(TrackMetadata meta) {
40 int minutes = meta.length() / 60;
41 int seconds = meta.length() % 60;
42 QTime time(0, minutes, seconds);
43 return QString("[%1] %2").arg(time.toString("mm:ss")).arg(meta.title());
47 inline void __fill_model(QStandardItemModel *model, QList<QString> data) {
49 int count = data.count();
50 model->setRowCount(count);
51 for (int i = 0; i < count; i++) {
52 model->setItem(i, 0, new QStandardItem(data.at(i)));
56 inline void __fill_model_tracks (QStandardItemModel *model, QList<Track> tracks) {
57 int count = tracks.count();
58 model->setRowCount(count);
60 bool show_lenght = (config.getValue("ui/showtracklenght").toString() != "no");
61 for (int i = 0; i < count; i++) {
62 TrackMetadata meta = tracks.at(i).metadata();
64 model->setItem(i, 0, new QStandardItem(__format_track_string(meta)));
66 model->setItem(i, 0, new QStandardItem(meta.title()));
70 LibraryForm::LibraryForm(Library *lib, QWidget *parent) :
72 ui(new Ui::LibraryForm)
75 _model = new QStandardItemModel(this);
77 _tools_widget = new ToolsWidget(this);
79 ui->toolsLayout->addWidget(_tools_widget);
80 _tools_widget->hide();
81 connect(ui->playerButton, SIGNAL(clicked()), this, SLOT(_player()));
82 connect(ui->viewButton, SIGNAL(clicked()), this, SLOT(_view_button()));
83 connect(ui->playlistsButton, SIGNAL(clicked()), this, SLOT(_playlists_button()));
84 connect(ui->dynamicButton, SIGNAL(clicked()), this, SLOT(_dynamic_button()));
85 connect(ui->listView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(_process_list_click(QModelIndex)));
86 connect(ui->addButton, SIGNAL(clicked()), this, SLOT(_add_button()));
87 connect(ui->selectAllButton, SIGNAL(clicked()), this, SLOT(_toggle_select_all_button()));
88 connect(ui->backButton, SIGNAL(clicked()), this, SLOT(_back_button()));
89 connect(ui->deleteButton, SIGNAL(clicked()), this, SLOT(_delete_button()));
90 connect(ui->useButton, SIGNAL(clicked()), this, SLOT(_use_button()));
91 connect(_tools_widget, SIGNAL(search(QString)), this, SLOT(search(QString)));
92 connect(_tools_widget, SIGNAL(nextSearch()), this, SLOT(nextItem()));
93 connect(_tools_widget, SIGNAL(prevSearch()), this, SLOT(prevItem()));
94 connect(_tools_widget, SIGNAL(toggleFullscreen(bool)), this, SIGNAL(fullscreen(bool)));
95 connect(ui->moreButton, SIGNAL(clicked()), this, SLOT(_more_button()));
97 _current_playlist_changed = true;
100 LibraryForm::~LibraryForm()
102 _lib->saveCurrentPlaylist(_lib->getCurrentPlaylist()); // wtf?
103 _current_playlist_changed = true;
107 void LibraryForm::_player() {
108 emit player(_current_playlist_changed);
109 _current_playlist_changed = false;
112 void LibraryForm::_view_button() {
113 QList<QString> artitst = _lib->getArtists();
114 __fill_model(_model, artitst);
115 ui->listView->setModel(_model);
116 _state = STATE_ARTIST;
117 ui->backButton->setEnabled(false);
118 ui->listLabel->setText("Artists");
119 ui->addButton->setEnabled(true);
120 ui->addButton->setIcon(QIcon(":/icons/white/add.png"));
121 ui->deleteButton->setEnabled(false);
122 ui->deleteButton->setIcon(QIcon());
123 ui->useButton->setEnabled(false);
124 ui->useButton->setIcon(QIcon());
127 void LibraryForm::_dynamic_button() {
128 ui->useButton->setEnabled(false);
129 ui->useButton->setIcon(QIcon());
130 ui->backButton->setEnabled(false);
131 ui->addButton->setEnabled(true);
132 ui->addButton->setIcon(QIcon(":/icons/white/add.png"));
133 ui->deleteButton->setEnabled(false);
134 ui->deleteButton->setIcon(QIcon());
136 _model->setRowCount(4);
137 _model->setItem(0, new QStandardItem("Favorites"));
138 _model->setItem(1, new QStandardItem("Most played"));
139 _model->setItem(2, new QStandardItem("Never played"));
140 _model->setItem(3, new QStandardItem("Recently added"));
141 ui->listLabel->setText("Dynamic playlists");
142 _state = STATE_DYNAMIC;
145 void LibraryForm::_process_list_click(QModelIndex index) {
146 if (_state == STATE_NONE) return;
147 QString data = index.data().toString();
150 __fill_model(_model, _lib->getAlbumsForArtist(data));
151 ui->listView->scrollToTop();
152 _current_artist = data;
153 _state = STATE_ALBUM;
154 ui->backButton->setEnabled(true);
155 ui->listLabel->setText(QString("Albums by \"%1\"").arg(_current_artist));
158 _current_album = data;
159 _current_tracks = _lib->getTracksForAlbum(data, _current_artist);
160 __fill_model_tracks(_model, _current_tracks);
161 ui->listView->scrollToTop();
162 _state = STATE_TRACK;
163 ui->backButton->setEnabled(true);
164 ui->listLabel->setText(QString("Tracks from \"%1\" by \"%2\"").arg(_current_album).arg(_current_artist));
168 _current_playlist = _lib->getPlaylist(data);
169 _current_tracks = _current_playlist.tracks();
170 __fill_model_tracks(_model, _current_tracks);
171 ui->listView->scrollToTop();
172 _state = STATE_PLAYLIST_TRACK;
173 ui->backButton->setEnabled(true);
174 ui->deleteButton->setEnabled(true);
175 ui->deleteButton->setIcon(QIcon(":/icons/white/delete.png"));
176 ui->useButton->setEnabled(true);
177 ui->useButton->setIcon(QIcon(":/icons/white/use.png"));
178 ui->listLabel->setText(QString("Tracks in playlist \"%1\"").arg(data));
183 switch(index.row()) {
185 _current_playlist = _lib->getFavorites();
187 case 1: //most played
188 _current_playlist = _lib->getMostPlayed();
190 case 2: //never played
191 _current_playlist = _lib->getNeverPlayed();
192 case 3: //recently added
193 _current_playlist = _lib->getRecentlyAdded();
198 _current_tracks = _current_playlist.tracks();
199 __fill_model_tracks(_model, _current_tracks);
200 ui->listView->scrollToTop();
201 _state = STATE_PLAYLIST_TRACK;
202 ui->backButton->setEnabled(true);
203 ui->useButton->setEnabled(true);
204 ui->useButton->setIcon(QIcon(":/icons/white/use.png"));
205 ui->addButton->setEnabled(true);
206 ui->addButton->setIcon(QIcon(":/icons/white/add.png"));
207 ui->listLabel->setText(_current_playlist.name());
212 QTimer::singleShot(100, ui->listView, SLOT(clearSelection())); // workaround
215 void LibraryForm::_add_button() {
216 if (_state == STATE_NONE) return;
217 QModelIndexList selected = ui->listView->selectionModel()->selectedIndexes();
218 ui->listView->selectionModel()->clearSelection();
219 emit busy(QString("<H1>Adding... Please wait</H1>"));
222 foreach (QModelIndex id, selected) {
223 _add_artist(id.data().toString());
227 foreach (QModelIndex id, selected) {
228 _add_album(_current_artist, id.data().toString());
232 foreach (QModelIndex id, selected) {
233 _add_track(_current_tracks.at(id.row()));
237 foreach (QModelIndex id, selected) {
238 _add_playlist(id.data().toString());
241 case STATE_PLAYLIST_TRACK:
242 foreach (QModelIndex id, selected) {
243 _add_track(_current_tracks.at(id.row()));
254 void LibraryForm::_add_artist(QString artist) {
255 QList<QString> albums = _lib->getAlbumsForArtist(artist);
256 foreach(QString album, albums) {
257 _add_album(artist, album);
261 void LibraryForm::_add_album(QString artist, QString album) {
262 QList<Track> tracks = _lib->getTracksForAlbum(album, artist);
263 foreach(Track track, tracks) {
268 void LibraryForm::_add_track(Track track) {
269 Playlist current = _lib->getCurrentPlaylist();
270 current.addTrack(track);
271 _lib->saveCurrentPlaylist(current);
272 _current_playlist_changed = true;
275 void LibraryForm::_add_playlist(QString name) {
276 Playlist playlist = _lib->getPlaylist(name);
277 QList<Track> tracks = playlist.tracks();
278 foreach (Track track, tracks) {
283 void LibraryForm::_back_button() {
287 ui->listView->scrollToTop();
290 __fill_model(_model, _lib->getAlbumsForArtist(_current_artist));
291 ui->listView->scrollToTop();
292 _state = STATE_ALBUM;
293 ui->listLabel->setText(QString("Albums by \"%1\"").arg(_current_artist));
295 case STATE_PLAYLIST_TRACK:
297 ui->listView->scrollToTop();
303 void LibraryForm::_playlists_button() {
304 QList<QString> playlists = _lib->getPlaylistsNames();
305 __fill_model(_model, playlists);
306 ui->listView->setModel(_model);
307 _state = STATE_PLAYLIST;
308 ui->backButton->setEnabled(false);
309 ui->listLabel->setText("Playlists");
310 ui->addButton->setEnabled(false);
311 ui->addButton->setIcon(QIcon());
312 ui->deleteButton->setEnabled(true);
313 ui->deleteButton->setIcon(QIcon(":/icons/white/delete.png"));
314 ui->useButton->setEnabled(false);
315 ui->useButton->setIcon(QIcon());
318 void LibraryForm::_delete_button() {
319 if (_state == STATE_PLAYLIST_TRACK) {
320 QModelIndexList selected = ui->listView->selectionModel()->selectedIndexes();
321 ui->listView->selectionModel()->clearSelection();
322 QQueue<int> to_delete;
323 foreach (QModelIndex id, selected) {
324 to_delete.append(id.row());
327 int count = to_delete.count();
328 for (int i = count-1; i >= 0; i--) {
329 _current_playlist.removeTrackAt(to_delete.at(i));
331 _current_tracks = _current_playlist.tracks();
332 _lib->savePlaylist(_current_playlist);
333 _current_playlist_changed = true;
334 __fill_model_tracks(_model, _current_tracks);
335 } else if (_state == STATE_PLAYLIST) {
336 QModelIndexList selected = ui->listView->selectionModel()->selectedIndexes();
337 QQueue<int> to_delete;
338 foreach (QModelIndex id, selected) {
339 to_delete.append(id.row());
342 int count = to_delete.count();
343 for (int i = count-1; i >= 0; i--) {
344 QString name = _model->item(to_delete.at(i))->text();
345 if (name != _CURRENT_PLAYLIST_SUBST_) {
346 _lib->removePlaylist(name);
347 _model->removeRow(to_delete.at(i));
353 void LibraryForm::_delete_track(Track track) {
354 Playlist current = _lib->getCurrentPlaylist();
355 current.removeTrack(track);
356 _lib->saveCurrentPlaylist(current);
357 _current_playlist_changed = true;
360 void LibraryForm::_use_button() {
361 _lib->saveCurrentPlaylist(_current_playlist);
362 _current_playlist_changed = true;
363 _current_playlist = _lib->getCurrentPlaylist();
366 void LibraryForm::search(QString pattern) {
367 _search_pattern = pattern;
368 _search_current_id = -1;
372 void LibraryForm::nextItem() {
373 QString data = _model->index(_search_current_id, 0).data().toString();
374 for (int i = _search_current_id+1; i < _model->rowCount(); i++) {
375 data = _model->index(i, 0).data().toString();
376 if (data.contains(_search_pattern, Qt::CaseInsensitive)) {
377 _search_current_id = i;
381 QModelIndex id = _model->index(_search_current_id, 0);
382 ui->listView->selectionModel()->clearSelection();
383 ui->listView->selectionModel()->select(id, QItemSelectionModel::Select);
384 ui->listView->scrollTo(id);
387 void LibraryForm::prevItem() {
388 QString data = _model->index(_search_current_id, 0).data().toString();
389 for (int i = _search_current_id-1; i >= 0; i--) {
390 data = _model->index(i, 0).data().toString();
391 if (data.contains(_search_pattern, Qt::CaseInsensitive)) {
392 _search_current_id = i;
396 QModelIndex id = _model->index(_search_current_id, 0);
397 ui->listView->selectionModel()->clearSelection();
398 ui->listView->selectionModel()->select(id, QItemSelectionModel::Select);
399 ui->listView->scrollTo(id);
402 void LibraryForm::cancelSearch() {
403 _search_pattern = "";
404 ui->listView->selectionModel()->clearSelection();
407 void LibraryForm::refresh() {
413 __fill_model(_model, _lib->getAlbumsForArtist(_current_artist));
421 case STATE_PLAYLIST_TRACK:
422 _current_playlist = _lib->getPlaylist(_current_playlist.name());
423 _current_tracks = _current_playlist.tracks();
424 __fill_model_tracks(_model, _current_tracks);
427 _current_tracks = _lib->getTracksForAlbum(_current_album, _current_artist);
428 __fill_model_tracks(_model, _current_tracks);
435 void LibraryForm::_toggle_select_all_button() {
436 if (ui->listView->selectionModel()->selectedIndexes().count() == ui->listView->model()->rowCount()) {
437 ui->listView->selectionModel()->clearSelection();
438 ui->selectAllButton->setIcon(QIcon(":/icons/white/select_all.png"));
440 ui->listView->selectAll();
441 ui->selectAllButton->setIcon(QIcon(":/icons/white/deselect_all.png"));
445 void LibraryForm::landscapeMode() {
448 void LibraryForm::portraitMode() {
451 void LibraryForm::_more_button() {
452 if (_tools_widget->isVisible()) {
453 ui->moreButton->setIcon(QIcon(":/icons/white/more.png"));
454 _tools_widget->hide();
455 _tools_widget->reset();
458 ui->moreButton->setIcon(QIcon(":/icons/white/unmore.png"));
459 _tools_widget->show();
460 _tools_widget->setFocus();