Handle JumpToPlayingSong action in playlist editor
This commit is contained in:
committed by
Andrzej Rybczak
parent
4ad10fb4c2
commit
0cdbe31ecb
1
NEWS
1
NEWS
@@ -25,6 +25,7 @@ ncmpcpp-0.8 (????-??-??)
|
||||
* Fixed fetching lyrics from justsomelyrics.com.
|
||||
* Added support for fetching lyrics from jah-lyrics.com and plyrics.com.
|
||||
* Seek immediately after invoking appropriate action once.
|
||||
* Added support for locating current song in playlist editor.
|
||||
|
||||
ncmpcpp-0.7.7 (2016-10-31)
|
||||
* Fixed compilation on 32bit platforms.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user