[UI] Restore the playing queue when creating the session

This commit is contained in:
emeric
2015-04-04 22:33:08 +02:00
parent 0378c242b6
commit c14da64d56
7 changed files with 86 additions and 21 deletions
+2 -1
View File
@@ -71,7 +71,8 @@ _isAdmin(false),
_audioBitrate(defaultAudioBitrate), _audioBitrate(defaultAudioBitrate),
_audioEncoding(AudioEncoding::AUTO), _audioEncoding(AudioEncoding::AUTO),
_videoBitrate(defaultVideoBitrate), _videoBitrate(defaultVideoBitrate),
_videoEncoding(VideoEncoding::AUTO) _videoEncoding(VideoEncoding::AUTO),
_curPlayingTrackPos(0)
{ {
} }
+7
View File
@@ -78,6 +78,7 @@ class User
void setVideoEncoding(VideoEncoding encoding) { _videoEncoding = encoding; } void setVideoEncoding(VideoEncoding encoding) { _videoEncoding = encoding; }
void setMaxAudioBitrate(std::size_t bitrate); void setMaxAudioBitrate(std::size_t bitrate);
void setMaxVideoBitrate(std::size_t bitrate); void setMaxVideoBitrate(std::size_t bitrate);
void setCurPlayingTrackPos(std::size_t pos) { _curPlayingTrackPos = pos; }
// read // read
bool isAdmin() const {return _isAdmin;} bool isAdmin() const {return _isAdmin;}
@@ -87,6 +88,7 @@ class User
VideoEncoding getVideoEncoding() const { return _videoEncoding;} VideoEncoding getVideoEncoding() const { return _videoEncoding;}
std::size_t getMaxAudioBitrate() const; std::size_t getMaxAudioBitrate() const;
std::size_t getMaxVideoBitrate() const; std::size_t getMaxVideoBitrate() const;
std::size_t getCurPlayingTrackPos() const { return _curPlayingTrackPos; }
template<class Action> template<class Action>
void persist(Action& a) void persist(Action& a)
@@ -98,6 +100,8 @@ class User
Wt::Dbo::field(a, _audioEncoding, "audio_encoding"); Wt::Dbo::field(a, _audioEncoding, "audio_encoding");
Wt::Dbo::field(a, _videoBitrate, "video_bitrate"); Wt::Dbo::field(a, _videoBitrate, "video_bitrate");
Wt::Dbo::field(a, _videoEncoding, "video_encoding"); Wt::Dbo::field(a, _videoEncoding, "video_encoding");
// User's dynamic data
Wt::Dbo::field(a, _curPlayingTrackPos, "cur_playing_track_pos");
Wt::Dbo::hasMany(a, _playlists, Wt::Dbo::ManyToOne, "user"); Wt::Dbo::hasMany(a, _playlists, Wt::Dbo::ManyToOne, "user");
} }
@@ -120,6 +124,9 @@ class User
int _videoBitrate; int _videoBitrate;
VideoEncoding _videoEncoding; VideoEncoding _videoEncoding;
// User's dynamic data
int _curPlayingTrackPos; // Current track position in queue
Wt::Dbo::collection< Wt::Dbo::ptr<Playlist> > _playlists; Wt::Dbo::collection< Wt::Dbo::ptr<Playlist> > _playlists;
}; };
+35 -9
View File
@@ -51,6 +51,10 @@ void WPopupMenuClear(Wt::WPopupMenu* menu)
namespace UserInterface { namespace UserInterface {
namespace Desktop { namespace Desktop {
// Special playlist generated each time the playque gets changed
// Restored at the beginning of the session
static const std::string CurrentQueuePlaylistName = "__current__";
Audio::Audio(SessionData& sessionData, Wt::WContainerWidget* parent) Audio::Audio(SessionData& sessionData, Wt::WContainerWidget* parent)
: UserInterface::Audio(parent), : UserInterface::Audio(parent),
_db(sessionData.getDatabaseHandler()), _db(sessionData.getDatabaseHandler()),
@@ -180,6 +184,11 @@ _playQueue(nullptr)
playQueueLayout->addLayout(playlistControls); playQueueLayout->addLayout(playlistControls);
mainLayout->addWidget(playQueueContainer, 0, 0, 2, 1); mainLayout->addWidget(playQueueContainer, 0, 0, 2, 1);
// Load the last known queue
playlistLoadToPlayqueue(CurrentQueuePlaylistName);
// Select the last known playing track
_playQueue->select(user->getCurPlayingTrackPos());
} }
mainLayout->setRowStretch(1, 1); mainLayout->setRowStretch(1, 1);
@@ -212,6 +221,13 @@ _playQueue(nullptr)
_mediaPlayer->shuffle().connect(boost::bind(&PlayQueue::setShuffle, _playQueue, _1)); _mediaPlayer->shuffle().connect(boost::bind(&PlayQueue::setShuffle, _playQueue, _1));
_mediaPlayer->loop().connect(boost::bind(&PlayQueue::setLoop,_playQueue, _1)); _mediaPlayer->loop().connect(boost::bind(&PlayQueue::setLoop,_playQueue, _1));
_playQueue->tracksUpdated().connect(std::bind([=] () {
LMS_LOG(MOD_UI, SEV_INFO) << "Playqueue updated!";
playlistSaveFromPlayqueue(CurrentQueuePlaylistName);
}));
playlistRefreshMenus(); playlistRefreshMenus();
} }
@@ -337,17 +353,21 @@ Audio::playlistLoadToPlayqueue(std::string playlistName)
{ {
LMS_LOG(MOD_UI, SEV_DEBUG) << "Loading playlist '" << playlistName << "' to playqueue"; LMS_LOG(MOD_UI, SEV_DEBUG) << "Loading playlist '" << playlistName << "' to playqueue";
Wt::Dbo::Transaction transaction(_db.getSession()); std::vector<Database::Track::id_type> entries;
Database::User::pointer user = _db.getCurrentUser(); {
if (!user) Wt::Dbo::Transaction transaction(_db.getSession());
return;
Database::Playlist::pointer playlist = Database::Playlist::get(_db.getSession(), playlistName, user); Database::User::pointer user = _db.getCurrentUser();
if (!playlist) if (!user)
return; return;
std::vector<Database::Track::id_type> entries = Database::PlaylistEntry::getEntries(_db.getSession(), playlist); Database::Playlist::pointer playlist = Database::Playlist::get(_db.getSession(), playlistName, user);
if (!playlist)
return;
entries = Database::PlaylistEntry::getEntries(_db.getSession(), playlist);
}
_playQueue->clear(); _playQueue->clear();
_playQueue->addTracks(entries); _playQueue->addTracks(entries);
@@ -414,6 +434,9 @@ Audio::playlistRefreshMenus()
BOOST_FOREACH(Database::Playlist::pointer playlist, playlists) BOOST_FOREACH(Database::Playlist::pointer playlist, playlists)
{ {
if (playlist->getName() == CurrentQueuePlaylistName)
continue;
// Add playlists in each menu // Add playlists in each menu
_popupMenuDelete->addItem(playlist->getName())->triggered().connect(std::bind([=] () _popupMenuDelete->addItem(playlist->getName())->triggered().connect(std::bind([=] ()
{ {
@@ -496,7 +519,7 @@ Audio::playSelectedTracks(PlayQueueAddType addType)
} }
void void
Audio::playTrack(boost::filesystem::path p) Audio::playTrack(boost::filesystem::path p, int pos)
{ {
LMS_LOG(MOD_UI, SEV_DEBUG) << "play track '" << p << "'"; LMS_LOG(MOD_UI, SEV_DEBUG) << "play track '" << p << "'";
try { try {
@@ -508,7 +531,10 @@ Audio::playTrack(boost::filesystem::path p)
Wt::Dbo::Transaction transaction(_db.getSession()); Wt::Dbo::Transaction transaction(_db.getSession());
Database::User::pointer user = _db.getCurrentUser(); Database::User::pointer user = _db.getCurrentUser();
if (user) if (user)
{
bitrate = user->getAudioBitrate(); bitrate = user->getAudioBitrate();
user.modify()->setCurPlayingTrackPos(pos);
}
else else
{ {
LMS_LOG(MOD_UI, SEV_ERROR) << "Can't play: user does not exists!"; LMS_LOG(MOD_UI, SEV_ERROR) << "Can't play: user does not exists!";
+1 -1
View File
@@ -55,7 +55,7 @@ class Audio : public UserInterface::Audio
void playlistShowDeleteDialog(std::string name); void playlistShowDeleteDialog(std::string name);
void playlistRefreshMenus(); void playlistRefreshMenus();
void playTrack(boost::filesystem::path p); void playTrack(boost::filesystem::path p, int pos);
enum PlayQueueAddType enum PlayQueueAddType
{ {
+24 -3
View File
@@ -357,14 +357,25 @@ PlayQueue::play(int rowId)
playNext(); playNext();
} }
void
PlayQueue::select(int rowId)
{
// Update the track selector to use the requested track as current position
_trackSelector->setPosByRowId(rowId);
Wt::WTableView::select(_model->index(_trackSelector->getCurrent(), 0));
this->scrollTo( _model->index(_trackSelector->getCurrent(), 0));
}
void void
PlayQueue::addTracks(const std::vector<Database::Track::id_type>& trackIds) PlayQueue::addTracks(const std::vector<Database::Track::id_type>& trackIds)
{ {
// Add tracks to model // Add tracks to model
Wt::Dbo::Transaction transaction(_db.getSession()); //
BOOST_FOREACH(Database::Track::id_type trackId, trackIds) BOOST_FOREACH(Database::Track::id_type trackId, trackIds)
{ {
Wt::Dbo::Transaction transaction(_db.getSession());
Database::Track::pointer track (Database::Track::getById(_db.getSession(), trackId)); Database::Track::pointer track (Database::Track::getById(_db.getSession(), trackId));
if (track) if (track)
@@ -391,6 +402,8 @@ PlayQueue::addTracks(const std::vector<Database::Track::id_type>& trackIds)
} }
_trackSelector->setSize( _model->rowCount() ); _trackSelector->setSize( _model->rowCount() );
_sigTracksUpdated.emit();
} }
void void
@@ -401,6 +414,8 @@ PlayQueue::clear(void)
// Reset play id // Reset play id
_curPlayedTrackPos = trackPosInvalid; _curPlayedTrackPos = trackPosInvalid;
_trackSelector->setSize( 0 ); _trackSelector->setSize( 0 );
_sigTracksUpdated.emit();
} }
void void
@@ -458,7 +473,7 @@ PlayQueue::readTrack(int rowPos)
{ {
setPlayingTrackPos(rowPos); setPlayingTrackPos(rowPos);
_sigTrackPlay.emit(track->getPath()); _sigTrackPlay.emit(track->getPath(), rowPos);
this->scrollTo( _model->index(_trackSelector->getCurrent(), 0)); this->scrollTo( _model->index(_trackSelector->getCurrent(), 0));
@@ -504,6 +519,7 @@ PlayQueue::delSelected(void)
_trackSelector->setSize(_model->rowCount()); _trackSelector->setSize(_model->rowCount());
renumber(minId, _model->rowCount() - 1); renumber(minId, _model->rowCount() - 1);
_sigTracksUpdated.emit();
} }
void void
@@ -511,6 +527,7 @@ PlayQueue::delAll(void)
{ {
_model->removeRows(0, _model->rowCount()); _model->removeRows(0, _model->rowCount());
_trackSelector->setSize(0); _trackSelector->setSize(0);
_sigTracksUpdated.emit();
} }
void void
@@ -551,6 +568,8 @@ PlayQueue::moveSelectedUp(void)
this->setSelectedIndexes( newIndexSet ); this->setSelectedIndexes( newIndexSet );
renumber(minId, maxId); renumber(minId, maxId);
_sigTracksUpdated.emit();
} }
@@ -592,6 +611,8 @@ PlayQueue::moveSelectedDown(void)
this->setSelectedIndexes( newIndexSet ); this->setSelectedIndexes( newIndexSet );
renumber(minId, maxId); renumber(minId, maxId);
_sigTracksUpdated.emit();
} }
void void
+7 -2
View File
@@ -49,6 +49,7 @@ class PlayQueue : public Wt::WTableView
// Play functions // Play functions
void play(void); // Play the queue from the beginning void play(void); // Play the queue from the beginning
void play(int rowId); // Play the queue from the given rowId void play(int rowId); // Play the queue from the given rowId
void select(int rowId); // Select the given rowId
void playNext(void); // Play the next track void playNext(void); // Play the next track
void playPrevious(void); // Play the previous track void playPrevious(void); // Play the previous track
@@ -59,7 +60,10 @@ class PlayQueue : public Wt::WTableView
void moveSelectedDown(void); void moveSelectedDown(void);
// Signals // Signals
Wt::Signal< boost::filesystem::path >& playTrack() { return _sigTrackPlay; } // Emitted when a song has to be played
Wt::Signal< boost::filesystem::path, int >& playTrack() { return _sigTrackPlay; }
// Emitted when the list has changed
Wt::Signal< void >& tracksUpdated() { return _sigTracksUpdated; }
// Slots // Slots
void handlePlaybackComplete(void); void handlePlaybackComplete(void);
@@ -72,7 +76,8 @@ class PlayQueue : public Wt::WTableView
void setPlayingTrackPos(int newRowPos); void setPlayingTrackPos(int newRowPos);
void renumber(int firstId, int lastId); void renumber(int firstId, int lastId);
Wt::Signal< boost::filesystem::path > _sigTrackPlay; Wt::Signal< boost::filesystem::path, int > _sigTrackPlay;
Wt::Signal< void > _sigTracksUpdated;
Database::Handler& _db; Database::Handler& _db;
+10 -5
View File
@@ -59,12 +59,17 @@ _sessionData(sessionData)
hLayout->addWidget(menu); hLayout->addWidget(menu);
hLayout->addWidget(contents, 1); hLayout->addWidget(contents, 1);
Wt::Dbo::Transaction transaction( sessionData.getDatabaseHandler().getSession()); std::string userId;
bool userIsAdmin;
::Database::User::pointer user = sessionData.getDatabaseHandler().getCurrentUser(); {
Wt::Dbo::Transaction transaction( sessionData.getDatabaseHandler().getSession());
::Database::User::pointer user = sessionData.getDatabaseHandler().getCurrentUser();
userId = Database::User::getId(user);
userIsAdmin = user->isAdmin();
}
menu->addItem("Audio", new AudioFormView(sessionData)); menu->addItem("Audio", new AudioFormView(sessionData));
if (user->isAdmin()) if (userIsAdmin)
{ {
MediaDirectories* mediaDirectory = new MediaDirectories(sessionData); MediaDirectories* mediaDirectory = new MediaDirectories(sessionData);
mediaDirectory->changed().connect(this, &Settings::handleDatabaseDirectoriesChanged); mediaDirectory->changed().connect(this, &Settings::handleDatabaseDirectoriesChanged);
@@ -78,7 +83,7 @@ _sessionData(sessionData)
} }
else else
{ {
menu->addItem("Account", new AccountFormView(sessionData, Database::User::getId(user))); menu->addItem("Account", new AccountFormView(sessionData, userId));
} }
} }