Autoresuming
authorNikolay Tischenko <niktischenko@gmail.com>
Sun, 12 Dec 2010 16:56:44 +0000 (22:56 +0600)
committerNikolay Tischenko <niktischenko@gmail.com>
Sun, 12 Dec 2010 16:56:44 +0000 (22:56 +0600)
src/filestorage.cpp
src/filestorage.h
src/library.cpp
src/library.h
src/player/player.cpp
src/player/player.h
src/playerform.cpp
src/playerform.h
src/playlist.h

index 1ddb878..1938143 100644 (file)
@@ -221,3 +221,62 @@ void FileStorage::saveCurrentPlaylist(Playlist playlist) {
        playlist.setName(_CURRENT_PLAYLIST_NAME_);
        savePlaylist(playlist);
 }
+
+LastPlayed FileStorage::getLastPlayedForCurPlaylist() {
+       QFile playlistFile (_path_prefix + "/" + _CURRENT_PLAYLIST_NAME_ + "." + _PLAYLIST_FILE_EXTENSION_);
+       int trackId = 0;
+       int position = 0;
+       if (playlistFile.exists()) {
+               QDomDocument doc;
+               playlistFile.open(QFile::ReadOnly);
+               doc.setContent(&playlistFile);
+               playlistFile.close();
+               QDomElement eplaylist = doc.documentElement();
+               if (eplaylist.tagName() == "playlist") {
+                       QDomElement eextension = eplaylist.firstChildElement("extension");
+                       if (!eextension.isNull()) {
+                               QDomElement elastplay = eextension.firstChildElement("lastplay");
+                               if (!elastplay.isNull()) {
+                                       trackId = elastplay.attribute("track_id").toInt();
+                                       position = elastplay.attribute("position").toInt();
+                               }
+                       }
+               }
+       }
+       LastPlayed lp = {trackId, position};
+       return lp;
+}
+
+void FileStorage::saveLastPlayedForCurPlaylist(LastPlayed lastplayed) {
+       QFile playlistFile (_path_prefix + "/" + _CURRENT_PLAYLIST_NAME_ + "." + _PLAYLIST_FILE_EXTENSION_);
+       QDomDocument doc;
+       if (playlistFile.exists()) {
+               playlistFile.open(QFile::ReadOnly);
+               doc.setContent(&playlistFile);
+               playlistFile.close();
+               QDomElement eplaylist = doc.documentElement();
+               if (eplaylist.tagName() == "playlist") {
+                       QDomElement eextension = eplaylist.firstChildElement("extension");
+                       if (eextension.isNull()) {
+                               eextension = doc.createElement("extension");
+                               eextension.setAttribute("application", "http://example.com");
+                               QDomElement elastplay = doc.createElement("lastplay");
+                               elastplay.setAttribute("track_id", lastplayed.trackId);
+                               elastplay.setAttribute("position", lastplayed.position);
+                               eextension.appendChild(elastplay);
+                               eplaylist.appendChild(eextension);
+                       } else {
+                               QDomElement elastplay = eextension.firstChildElement("lastplay");
+                               if (elastplay.isNull()) {
+                                       elastplay = doc.createElement("lastplay");
+                                       eextension.appendChild(elastplay);
+                               }
+                               elastplay.setAttribute("track_id", lastplayed.trackId);
+                               elastplay.setAttribute("position", lastplayed.position);
+                       }
+               }
+       }
+       playlistFile.open(QFile::WriteOnly);
+       QTextStream stream(&playlistFile);
+       stream << doc.toString();
+}
index 79311d6..f6dad99 100644 (file)
@@ -41,6 +41,7 @@
 // it store data into separate files (e.g. playlist)
 
 using SomePlayer::DataObjects::Playlist;
+using SomePlayer::DataObjects::LastPlayed;
 
 namespace SomePlayer {
        namespace Storage {
@@ -58,6 +59,8 @@ namespace SomePlayer {
 
                        Playlist getCurrentPlaylist();
                        void saveCurrentPlaylist(Playlist playlist);
+                       LastPlayed getLastPlayedForCurPlaylist();
+                       void saveLastPlayedForCurPlaylist(LastPlayed);
                private:
                        QString _path_prefix;
                };
index ee94569..576440f 100644 (file)
@@ -236,3 +236,11 @@ void Library::removeFromFavorites(Track track) {
 bool Library::isFavorite(Track track) {
        return _library_storage->isFavorite(track);
 }
+
+LastPlayed Library::getLastPlayedForCurPlaylist() {
+       return _playlist_storage->getLastPlayedForCurPlaylist();
+}
+
+void Library::saveLastPlayedForCurPlaylist(LastPlayed lastplayed) {
+       _playlist_storage->saveLastPlayedForCurPlaylist(lastplayed);
+}
index 9fc9a1a..1803c02 100644 (file)
@@ -76,6 +76,7 @@ namespace SomePlayer {
 
                        Playlist getCurrentPlaylist();
                        void saveCurrentPlaylist(const Playlist &playlist);
+                       LastPlayed getLastPlayedForCurPlaylist();
 
                        void updateDirectories(QList<QString> directories);
                        void updateAll();
@@ -108,6 +109,7 @@ namespace SomePlayer {
                        void updateTrackCount(Track);
                        void updateTrackMetadata(Track);
                        void updatePlaylists();
+                       void saveLastPlayedForCurPlaylist(LastPlayed);
                };
 
        };
index 67bf4bc..52f0ad2 100644 (file)
@@ -43,6 +43,7 @@ inline QList<Track> __sub(QList<Track> one, QList<Track> two, Track three) {
 Player::Player(QObject *parent) :
     QObject(parent)
 {
+       _awaiting_seek = false;
        _player = new Phonon::MediaObject(this);
        _output = new Phonon::AudioOutput(Phonon::MusicCategory, this);
        _player->setTickInterval(1000);
@@ -90,6 +91,15 @@ void Player::toggle() {
 }
 
 void Player::stop() {
+       if (_state == PLAYER_STOPPED) {
+               return;
+       }
+       LastPlayed lp;
+       lp.position = _player->currentTime() / 1000 - 2;
+       lp.position = lp.position < 0 ? 0 : lp.position;
+       lp.trackId = _playlist.tracks().indexOf(_track);
+       lp.trackId = lp.trackId < 0 ? 0 : lp.trackId;
+       emit saveLastPlayed(lp);
        _player->stop();
        _state = PLAYER_STOPPED;
        emit stateChanged(_state);
@@ -169,6 +179,10 @@ void Player::_stateChanged(Phonon::State newState, Phonon::State /*oldState*/) {
        case Phonon::PlayingState:
                _state = PLAYER_PLAYING;
                emit stateChanged(_state);
+               if (_awaiting_seek) {
+                       _awaiting_seek = false;
+                       seek(_awaiting_seek_pos);
+               }
                break;
        case Phonon::ErrorState:
                play(); // force
@@ -204,7 +218,7 @@ void Player::play() {
        if (_playlist.tracks().isEmpty())
                return;
        if (_track.source().isEmpty()) {
-               next();
+               emit startPlaylist();
                return;
        }
        _state = PLAYER_PLAYING;
@@ -322,3 +336,7 @@ void Player::_truncate_history() {
                _history.removeLast();
        }
 }
+
+Player::~Player() {
+       stop();
+}
index c2a3c66..838bc40 100644 (file)
@@ -37,6 +37,7 @@
 using SomePlayer::DataObjects::Track;
 using SomePlayer::DataObjects::TrackMetadata;
 using SomePlayer::DataObjects::Playlist;
+using SomePlayer::DataObjects::LastPlayed;
 using SomePlayer::Storage::Config;
 
 namespace SomePlayer {
@@ -50,6 +51,7 @@ namespace SomePlayer {
                        Q_OBJECT
                public:
                        explicit Player(QObject *parent = 0);
+                       ~Player();
                        bool random() {return _random;}
                        RepeatRule repeat() {return _repeat;}
                        Phonon::MediaObject* mediaObject() {return _player;}
@@ -57,12 +59,14 @@ namespace SomePlayer {
                        bool equalizerAvailable() {return _equalizer != NULL;}
                        PlayerState state() {return _state;}
                        Track current();
-
+                       void setAwaitingSeek(int pos) {_awaiting_seek = true; _awaiting_seek_pos = pos;}
                signals:
                        void stateChanged (PlayerState);
                        void trackChanged (Track);
                        void tick (int, int); // played | all (seconds)
                        void trackDone(Track);
+                       void startPlaylist();
+                       void saveLastPlayed(LastPlayed);
 
                public slots:
                        void setTrackId(int id);
@@ -105,6 +109,8 @@ namespace SomePlayer {
                        void _set_source();
                        void _to_history(Track t);
                        void _truncate_history();
+                       int _awaiting_seek_pos;
+                       bool _awaiting_seek;
                };
        };
 };
index d25c3f9..abefa53 100644 (file)
@@ -148,6 +148,8 @@ PlayerForm::PlayerForm(Library* lib, QWidget *parent) :
        connect(ui->cfavButton, SIGNAL(clicked()), this, SLOT(_c_add_to_favorites()));
        connect(ui->ctagButton, SIGNAL(clicked()), this, SLOT(_c_edit_tags()));
        connect(_cover, SIGNAL(clicked()), this, SLOT(_toggle_extra_buttons()));
+       connect(_player, SIGNAL(startPlaylist()), this, SLOT(_start_playlist()));
+       connect(_player, SIGNAL(saveLastPlayed(LastPlayed)), _lib, SLOT(saveLastPlayedForCurPlaylist(LastPlayed)));
        ui->viewButton->setIcon(QIcon(":/icons/"+_icons_theme+"/playback.png"));
        _top_gradient = ui->topWidget->styleSheet();
        _bottom_gradient = ui->bottomWidget->styleSheet();
@@ -209,7 +211,6 @@ void PlayerForm::_toggle_view() {
 void PlayerForm::_process_click(QModelIndex index) {
        if (index.column() == 1) {
                int id = index.row();
-               _player->stop();
                _player->setTrackId(id);
                _player->play();
                _track_renderer->setActiveRow(id);
@@ -769,3 +770,14 @@ QString PlayerForm::playerCaption() {
        TrackMetadata meta = _player->current().metadata();
        return QString("%1 - %2").arg(meta.artist()).arg(meta.title());
 }
+
+void PlayerForm::_start_playlist() {
+       Config config;
+       if (config.getValue("playback/autoresume_off").toBool()) {
+               _player->next();
+               return;
+       }
+       LastPlayed lp = _lib->getLastPlayedForCurPlaylist();
+       _player->setTrackId(lp.trackId);
+       _player->setAwaitingSeek(lp.position);
+}
index fd02bc2..a5fa890 100644 (file)
@@ -115,6 +115,7 @@ private slots:
        void _tools_widget_toggle();
        void _display_cover(QImage);
        void _toggle_extra_buttons();
+       void _start_playlist();
 
 private:
     Ui::PlayerForm *ui;
index 28975db..7b12c41 100644 (file)
 
 namespace SomePlayer {
        namespace DataObjects {
+
+               struct LastPlayed {
+                       int trackId;
+                       int position;
+               };
+
                class Playlist {
                public:
                        Playlist();