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.
|
* Fixed fetching lyrics from justsomelyrics.com.
|
||||||
* Added support for fetching lyrics from jah-lyrics.com and plyrics.com.
|
* Added support for fetching lyrics from jah-lyrics.com and plyrics.com.
|
||||||
* Seek immediately after invoking appropriate action once.
|
* Seek immediately after invoking appropriate action once.
|
||||||
|
* Added support for locating current song in playlist editor.
|
||||||
|
|
||||||
ncmpcpp-0.7.7 (2016-10-31)
|
ncmpcpp-0.7.7 (2016-10-31)
|
||||||
* Fixed compilation on 32bit platforms.
|
* Fixed compilation on 32bit platforms.
|
||||||
|
|||||||
@@ -1207,6 +1207,7 @@ bool JumpToPlayingSong::canBeRun()
|
|||||||
m_song = myPlaylist->nowPlayingSong();
|
m_song = myPlaylist->nowPlayingSong();
|
||||||
return !m_song.empty()
|
return !m_song.empty()
|
||||||
&& (myScreen == myPlaylist
|
&& (myScreen == myPlaylist
|
||||||
|
|| myScreen == myPlaylistEditor
|
||||||
|| myScreen == myBrowser
|
|| myScreen == myBrowser
|
||||||
|| myScreen == myLibrary);
|
|| myScreen == myLibrary);
|
||||||
}
|
}
|
||||||
@@ -1217,6 +1218,10 @@ void JumpToPlayingSong::run()
|
|||||||
{
|
{
|
||||||
myPlaylist->locateSong(m_song);
|
myPlaylist->locateSong(m_song);
|
||||||
}
|
}
|
||||||
|
else if (myScreen == myPlaylistEditor)
|
||||||
|
{
|
||||||
|
myPlaylistEditor->locateSong(m_song);
|
||||||
|
}
|
||||||
else if (myScreen == myBrowser)
|
else if (myScreen == myBrowser)
|
||||||
{
|
{
|
||||||
myBrowser->locateSong(m_song);
|
myBrowser->locateSong(m_song);
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ void write_bindings(NC::Scrollpad &w)
|
|||||||
key(w, Type::EditPlaylistName, "Edit playlist name");
|
key(w, Type::EditPlaylistName, "Edit playlist name");
|
||||||
key(w, Type::ChangeBrowseMode, "Browse MPD database/local filesystem");
|
key(w, Type::ChangeBrowseMode, "Browse MPD database/local filesystem");
|
||||||
key(w, Type::ToggleBrowserSortMode, "Toggle sort mode");
|
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::JumpToParentDirectory, "Jump to parent directory");
|
||||||
key(w, Type::DeleteBrowserItems, "Delete selected items from disk");
|
key(w, Type::DeleteBrowserItems, "Delete selected items from disk");
|
||||||
key(w, Type::JumpToPlaylistEditor, "Jump to playlist editor (playlists only)");
|
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::NextColumn, "Next column");
|
||||||
key(w, Type::PlayItem, "Add item to playlist and play it");
|
key(w, Type::PlayItem, "Add item to playlist and play it");
|
||||||
key(w, Type::AddItemToPlaylist, "Add item to playlist");
|
key(w, Type::AddItemToPlaylist, "Add item to playlist");
|
||||||
|
key(w, Type::JumpToPlayingSong, "Locate current song");
|
||||||
# ifdef HAVE_TAGLIB_H
|
# ifdef HAVE_TAGLIB_H
|
||||||
key(w, Type::EditSong, "Edit song");
|
key(w, Type::EditSong, "Edit song");
|
||||||
# endif // HAVE_TAGLIB_H
|
# endif // HAVE_TAGLIB_H
|
||||||
@@ -301,6 +302,7 @@ void write_bindings(NC::Scrollpad &w)
|
|||||||
key(w, Type::NextColumn, "Next column");
|
key(w, Type::NextColumn, "Next column");
|
||||||
key(w, Type::PlayItem, "Add item to playlist and play it");
|
key(w, Type::PlayItem, "Add item to playlist and play it");
|
||||||
key(w, Type::AddItemToPlaylist, "Add item to playlist");
|
key(w, Type::AddItemToPlaylist, "Add item to playlist");
|
||||||
|
key(w, Type::JumpToPlayingSong, "Locate current song");
|
||||||
# ifdef HAVE_TAGLIB_H
|
# ifdef HAVE_TAGLIB_H
|
||||||
key(w, Type::EditSong, "Edit song");
|
key(w, Type::EditSong, "Edit song");
|
||||||
# endif // HAVE_TAGLIB_H
|
# endif // HAVE_TAGLIB_H
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <boost/lambda/bind.hpp>
|
#include <boost/lambda/bind.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ size_t RightColumnWidth;
|
|||||||
std::string SongToString(const MPD::Song &s);
|
std::string SongToString(const MPD::Song &s);
|
||||||
bool PlaylistEntryMatcher(const Regex::Regex &rx, const MPD::Playlist &playlist);
|
bool PlaylistEntryMatcher(const Regex::Regex &rx, const MPD::Playlist &playlist);
|
||||||
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::Song &s);
|
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::Song &s);
|
||||||
|
boost::optional<size_t> GetSongIndexInPlaylist(MPD::Playlist playlist, const MPD::Song &song);
|
||||||
}
|
}
|
||||||
|
|
||||||
PlaylistEditor::PlaylistEditor()
|
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 {
|
namespace {
|
||||||
|
|
||||||
std::string SongToString(const MPD::Song &s)
|
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);
|
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 requestContentsUpdate() { m_content_update_requested = true; }
|
||||||
|
|
||||||
void locatePlaylist(const MPD::Playlist &playlist);
|
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;
|
NC::Menu<MPD::Playlist> Playlists;
|
||||||
SongMenu Content;
|
SongMenu Content;
|
||||||
|
|||||||
Reference in New Issue
Block a user