Handle JumpToPlayingSong action in playlist editor

This commit is contained in:
Hugh Wang
2017-01-10 19:38:28 +08:00
committed by Andrzej Rybczak
parent 4ad10fb4c2
commit 0cdbe31ecb
5 changed files with 104 additions and 2 deletions

View File

@@ -1207,6 +1207,7 @@ bool JumpToPlayingSong::canBeRun()
m_song = myPlaylist->nowPlayingSong();
return !m_song.empty()
&& (myScreen == myPlaylist
|| myScreen == myPlaylistEditor
|| myScreen == myBrowser
|| myScreen == myLibrary);
}
@@ -1217,6 +1218,10 @@ void JumpToPlayingSong::run()
{
myPlaylist->locateSong(m_song);
}
else if (myScreen == myPlaylistEditor)
{
myPlaylistEditor->locateSong(m_song);
}
else if (myScreen == myBrowser)
{
myBrowser->locateSong(m_song);

View File

@@ -268,7 +268,7 @@ void write_bindings(NC::Scrollpad &w)
key(w, Type::EditPlaylistName, "Edit playlist name");
key(w, Type::ChangeBrowseMode, "Browse MPD database/local filesystem");
key(w, Type::ToggleBrowserSortMode, "Toggle sort mode");
key(w, Type::JumpToPlayingSong, "Locate playing song");
key(w, Type::JumpToPlayingSong, "Locate current song");
key(w, Type::JumpToParentDirectory, "Jump to parent directory");
key(w, Type::DeleteBrowserItems, "Delete selected items from disk");
key(w, Type::JumpToPlaylistEditor, "Jump to playlist editor (playlists only)");
@@ -289,6 +289,7 @@ void write_bindings(NC::Scrollpad &w)
key(w, Type::NextColumn, "Next column");
key(w, Type::PlayItem, "Add item to playlist and play it");
key(w, Type::AddItemToPlaylist, "Add item to playlist");
key(w, Type::JumpToPlayingSong, "Locate current song");
# ifdef HAVE_TAGLIB_H
key(w, Type::EditSong, "Edit song");
# endif // HAVE_TAGLIB_H
@@ -301,6 +302,7 @@ void write_bindings(NC::Scrollpad &w)
key(w, Type::NextColumn, "Next column");
key(w, Type::PlayItem, "Add item to playlist and play it");
key(w, Type::AddItemToPlaylist, "Add item to playlist");
key(w, Type::JumpToPlayingSong, "Locate current song");
# ifdef HAVE_TAGLIB_H
key(w, Type::EditSong, "Edit song");
# endif // HAVE_TAGLIB_H

View File

@@ -20,6 +20,7 @@
#include <algorithm>
#include <boost/lambda/bind.hpp>
#include <boost/optional.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <cassert>
@@ -57,7 +58,7 @@ size_t RightColumnWidth;
std::string SongToString(const MPD::Song &s);
bool PlaylistEntryMatcher(const Regex::Regex &rx, const MPD::Playlist &playlist);
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::Song &s);
boost::optional<size_t> GetSongIndexInPlaylist(MPD::Playlist playlist, const MPD::Song &song);
}
PlaylistEditor::PlaylistEditor()
@@ -481,6 +482,81 @@ void PlaylistEditor::locatePlaylist(const MPD::Playlist &playlist)
}
}
void PlaylistEditor::gotoSong(size_t playlist_index, size_t song_index)
{
Playlists.highlight(playlist_index);
Content.clear();
update();
Content.highlight(song_index);
if (isActiveWindow(Playlists))
nextColumn();
else
Playlists.refresh();
}
void PlaylistEditor::locateSong(const MPD::Song &s)
{
Content.clearFilter();
Playlists.clearFilter();
if (!Content.empty())
{
auto song_it = std::find(Content.currentV() + 1, Content.endV(), s);
if (song_it != Content.endV())
{
Content.highlight(song_it - Content.beginV());
nextColumn();
return;
}
}
if (!Playlists.empty())
{
Statusbar::print("Jumping to song...");
auto locate_and_switch_playlist = [this, &s](auto pl_it) -> bool {
if (auto song_index = GetSongIndexInPlaylist(*pl_it, s))
{
this->gotoSong(pl_it - Playlists.beginV(), *song_index);
return true;
}
return false;
};
for (auto pl_it = Playlists.currentV() + 1; pl_it != Playlists.endV(); ++pl_it)
if (locate_and_switch_playlist(pl_it))
return;
for (auto pl_it = Playlists.beginV(); pl_it != Playlists.currentV(); ++pl_it)
if (locate_and_switch_playlist(pl_it))
return;
}
if (!Content.empty())
{
auto song_it = std::find(Content.beginV(), Content.currentV(), s);
if (song_it != Content.currentV())
{
Content.highlight(song_it - Content.beginV());
nextColumn();
return;
}
}
// Wrap back to the beginning of current playlist
if (Content.size() != 0)
{
auto song_it = std::find(Content.beginV(), Content.currentV(), s);
if (song_it != Content.currentV())
{
Content.highlight(song_it - Content.beginV());
nextColumn();
return;
}
}
Statusbar::print("Song is not from playlists");
}
namespace {
std::string SongToString(const MPD::Song &s)
@@ -508,4 +584,20 @@ bool SongEntryMatcher(const Regex::Regex &rx, const MPD::Song &s)
return Regex::search(SongToString(s), rx);
}
boost::optional<size_t> GetSongIndexInPlaylist(MPD::Playlist playlist, const MPD::Song &song)
{
size_t index = 0;
MPD::SongIterator it = Mpd.GetPlaylistContentNoInfo(playlist.path()), end;
for (;;)
{
if (it == end)
return boost::none;
if (*it == song)
return index;
++it, ++index;
}
}
}

View File

@@ -79,6 +79,8 @@ struct PlaylistEditor: Screen<NC::Window *>, Filterable, HasColumns, HasSongs, S
void requestContentsUpdate() { m_content_update_requested = true; }
void locatePlaylist(const MPD::Playlist &playlist);
void locateSong(const MPD::Song &s);
void gotoSong(size_t playlist_index, size_t song_index);
NC::Menu<MPD::Playlist> Playlists;
SongMenu Content;