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();
+}
// it store data into separate files (e.g. playlist)
using SomePlayer::DataObjects::Playlist;
+using SomePlayer::DataObjects::LastPlayed;
namespace SomePlayer {
namespace Storage {
Playlist getCurrentPlaylist();
void saveCurrentPlaylist(Playlist playlist);
+ LastPlayed getLastPlayedForCurPlaylist();
+ void saveLastPlayedForCurPlaylist(LastPlayed);
private:
QString _path_prefix;
};
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);
+}
Playlist getCurrentPlaylist();
void saveCurrentPlaylist(const Playlist &playlist);
+ LastPlayed getLastPlayedForCurPlaylist();
void updateDirectories(QList<QString> directories);
void updateAll();
void updateTrackCount(Track);
void updateTrackMetadata(Track);
void updatePlaylists();
+ void saveLastPlayedForCurPlaylist(LastPlayed);
};
};
Player::Player(QObject *parent) :
QObject(parent)
{
+ _awaiting_seek = false;
_player = new Phonon::MediaObject(this);
_output = new Phonon::AudioOutput(Phonon::MusicCategory, this);
_player->setTickInterval(1000);
}
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);
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
if (_playlist.tracks().isEmpty())
return;
if (_track.source().isEmpty()) {
- next();
+ emit startPlaylist();
return;
}
_state = PLAYER_PLAYING;
_history.removeLast();
}
}
+
+Player::~Player() {
+ stop();
+}
using SomePlayer::DataObjects::Track;
using SomePlayer::DataObjects::TrackMetadata;
using SomePlayer::DataObjects::Playlist;
+using SomePlayer::DataObjects::LastPlayed;
using SomePlayer::Storage::Config;
namespace SomePlayer {
Q_OBJECT
public:
explicit Player(QObject *parent = 0);
+ ~Player();
bool random() {return _random;}
RepeatRule repeat() {return _repeat;}
Phonon::MediaObject* mediaObject() {return _player;}
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);
void _set_source();
void _to_history(Track t);
void _truncate_history();
+ int _awaiting_seek_pos;
+ bool _awaiting_seek;
};
};
};
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();
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);
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);
+}
void _tools_widget_toggle();
void _display_cover(QImage);
void _toggle_extra_buttons();
+ void _start_playlist();
private:
Ui::PlayerForm *ui;
namespace SomePlayer {
namespace DataObjects {
+
+ struct LastPlayed {
+ int trackId;
+ int position;
+ };
+
class Playlist {
public:
Playlist();