Implement filtering in playlist editor
This commit is contained in:
@@ -878,10 +878,11 @@ bool MoveSelectedItemsUp::canBeRun()
|
|||||||
|
|
||||||
void MoveSelectedItemsUp::run()
|
void MoveSelectedItemsUp::run()
|
||||||
{
|
{
|
||||||
|
const char *filteredMsg = "Moving items up is disabled in filtered playlist";
|
||||||
if (myScreen == myPlaylist)
|
if (myScreen == myPlaylist)
|
||||||
{
|
{
|
||||||
if (myPlaylist->main().isFiltered())
|
if (myPlaylist->main().isFiltered())
|
||||||
Statusbar::print("Moving items up is disabled in filtered playlist");
|
Statusbar::print(filteredMsg);
|
||||||
else
|
else
|
||||||
moveSelectedItemsUp(
|
moveSelectedItemsUp(
|
||||||
myPlaylist->main(),
|
myPlaylist->main(),
|
||||||
@@ -889,10 +890,15 @@ void MoveSelectedItemsUp::run()
|
|||||||
}
|
}
|
||||||
else if (myScreen == myPlaylistEditor)
|
else if (myScreen == myPlaylistEditor)
|
||||||
{
|
{
|
||||||
assert(!myPlaylistEditor->Playlists.empty());
|
if (myPlaylistEditor->Content.isFiltered())
|
||||||
std::string playlist = myPlaylistEditor->Playlists.current()->value().path();
|
Statusbar::print(filteredMsg);
|
||||||
auto move_fun = std::bind(&MPD::Connection::PlaylistMove, ph::_1, playlist, ph::_2, ph::_3);
|
else
|
||||||
moveSelectedItemsUp(myPlaylistEditor->Content, move_fun);
|
{
|
||||||
|
auto playlist = myPlaylistEditor->Playlists.current()->value().path();
|
||||||
|
moveSelectedItemsUp(
|
||||||
|
myPlaylistEditor->Content,
|
||||||
|
std::bind(&MPD::Connection::PlaylistMove, ph::_1, playlist, ph::_2, ph::_3));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -906,10 +912,11 @@ bool MoveSelectedItemsDown::canBeRun()
|
|||||||
|
|
||||||
void MoveSelectedItemsDown::run()
|
void MoveSelectedItemsDown::run()
|
||||||
{
|
{
|
||||||
|
const char *filteredMsg = "Moving items down is disabled in filtered playlist";
|
||||||
if (myScreen == myPlaylist)
|
if (myScreen == myPlaylist)
|
||||||
{
|
{
|
||||||
if (myPlaylist->main().isFiltered())
|
if (myPlaylist->main().isFiltered())
|
||||||
Statusbar::print("Moving items down is disabled in filtered playlist");
|
Statusbar::print(filteredMsg);
|
||||||
else
|
else
|
||||||
moveSelectedItemsDown(
|
moveSelectedItemsDown(
|
||||||
myPlaylist->main(),
|
myPlaylist->main(),
|
||||||
@@ -917,10 +924,15 @@ void MoveSelectedItemsDown::run()
|
|||||||
}
|
}
|
||||||
else if (myScreen == myPlaylistEditor)
|
else if (myScreen == myPlaylistEditor)
|
||||||
{
|
{
|
||||||
assert(!myPlaylistEditor->Playlists.empty());
|
if (myPlaylistEditor->Content.isFiltered())
|
||||||
std::string playlist = myPlaylistEditor->Playlists.current()->value().path();
|
Statusbar::print(filteredMsg);
|
||||||
auto move_fun = std::bind(&MPD::Connection::PlaylistMove, ph::_1, playlist, ph::_2, ph::_3);
|
else
|
||||||
moveSelectedItemsDown(myPlaylistEditor->Content, move_fun);
|
{
|
||||||
|
auto playlist = myPlaylistEditor->Playlists.current()->value().path();
|
||||||
|
moveSelectedItemsDown(
|
||||||
|
myPlaylistEditor->Content,
|
||||||
|
std::bind(&MPD::Connection::PlaylistMove, ph::_1, playlist, ph::_2, ph::_3));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1622,7 +1634,7 @@ bool JumpToPlaylistEditor::canBeRun()
|
|||||||
|
|
||||||
void JumpToPlaylistEditor::run()
|
void JumpToPlaylistEditor::run()
|
||||||
{
|
{
|
||||||
myPlaylistEditor->Locate(myBrowser->main().current()->value().playlist());
|
myPlaylistEditor->locatePlaylist(myBrowser->main().current()->value().playlist());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToggleScreenLock::run()
|
void ToggleScreenLock::run()
|
||||||
|
|||||||
@@ -63,56 +63,6 @@ MPD::SongIterator getDatabaseIterator(MPD::Connection &mpd)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef std::vector<MPD::Song>::const_iterator VectorSongIterator;
|
|
||||||
bool addSongsToPlaylist(VectorSongIterator first, VectorSongIterator last, bool play, int position)
|
|
||||||
{
|
|
||||||
bool result = true;
|
|
||||||
auto addSongNoError = [&](VectorSongIterator song) -> int {
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return Mpd.AddSong(*song, position);
|
|
||||||
}
|
|
||||||
catch (MPD::ServerError &e)
|
|
||||||
{
|
|
||||||
Status::handleServerError(e);
|
|
||||||
result = false;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (last-first >= 1)
|
|
||||||
{
|
|
||||||
int id;
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
id = addSongNoError(first);
|
|
||||||
if (id >= 0)
|
|
||||||
break;
|
|
||||||
++first;
|
|
||||||
if (first == last)
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (position == -1)
|
|
||||||
{
|
|
||||||
++first;
|
|
||||||
for(; first != last; ++first)
|
|
||||||
addSongNoError(first);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
++position;
|
|
||||||
--last;
|
|
||||||
for (; first != last; --last)
|
|
||||||
addSongNoError(last);
|
|
||||||
}
|
|
||||||
if (play)
|
|
||||||
Mpd.PlayID(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void removeSongFromPlaylist(const SongMenu &playlist, const MPD::Song &s)
|
void removeSongFromPlaylist(const SongMenu &playlist, const MPD::Song &s)
|
||||||
{
|
{
|
||||||
Mpd.StartCommandsList();
|
Mpd.StartCommandsList();
|
||||||
|
|||||||
@@ -369,7 +369,8 @@ void cropPlaylist(NC::Menu<MPD::Song> &m, F delete_fun)
|
|||||||
deleteSelectedSongs(m, delete_fun);
|
deleteSelectedSongs(m, delete_fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Iterator> std::string getSharedDirectory(Iterator first, Iterator last)
|
template <typename Iterator>
|
||||||
|
std::string getSharedDirectory(Iterator first, Iterator last)
|
||||||
{
|
{
|
||||||
assert(first != last);
|
assert(first != last);
|
||||||
std::string result = first->getDirectory();
|
std::string result = first->getDirectory();
|
||||||
@@ -395,6 +396,56 @@ void markSongsInPlaylist(ListT &list)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Iterator>
|
||||||
|
bool addSongsToPlaylist(Iterator first, Iterator last, bool play, int position)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
auto addSongNoError = [&](Iterator it) -> int {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return Mpd.AddSong(*it, position);
|
||||||
|
}
|
||||||
|
catch (MPD::ServerError &e)
|
||||||
|
{
|
||||||
|
Status::handleServerError(e);
|
||||||
|
result = false;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (last-first >= 1)
|
||||||
|
{
|
||||||
|
int id;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
id = addSongNoError(first);
|
||||||
|
if (id >= 0)
|
||||||
|
break;
|
||||||
|
++first;
|
||||||
|
if (first == last)
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (position == -1)
|
||||||
|
{
|
||||||
|
++first;
|
||||||
|
for(; first != last; ++first)
|
||||||
|
addSongNoError(first);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++position;
|
||||||
|
--last;
|
||||||
|
for (; first != last; --last)
|
||||||
|
addSongNoError(last);
|
||||||
|
}
|
||||||
|
if (play)
|
||||||
|
Mpd.PlayID(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T> void ShowTime(T &buf, size_t length, bool short_names)
|
template <typename T> void ShowTime(T &buf, size_t length, bool short_names)
|
||||||
{
|
{
|
||||||
const unsigned MINUTE = 60;
|
const unsigned MINUTE = 60;
|
||||||
@@ -451,11 +502,6 @@ inline const char *withErrors(bool success)
|
|||||||
return success ? "" : " " "(with errors)";
|
return success ? "" : " " "(with errors)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool addSongsToPlaylist(std::vector<MPD::Song>::const_iterator first,
|
|
||||||
std::vector<MPD::Song>::const_iterator last,
|
|
||||||
bool play, int position);
|
|
||||||
|
|
||||||
bool addSongToPlaylist(const MPD::Song &s, bool play, int position = -1);
|
bool addSongToPlaylist(const MPD::Song &s, bool play, int position = -1);
|
||||||
|
|
||||||
const MPD::Song *currentSong(const BaseScreen *screen);
|
const MPD::Song *currentSong(const BaseScreen *screen);
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ PlaylistEditor::PlaylistEditor()
|
|||||||
menu << Charset::utf8ToLocale(menu.drawn()->value().path());
|
menu << Charset::utf8ToLocale(menu.drawn()->value().path());
|
||||||
});
|
});
|
||||||
|
|
||||||
Content = NC::Menu<MPD::Song>(RightColumnStartX, MainStartY, RightColumnWidth, MainHeight, Config.titles_visibility ? "Playlist content" : "", Config.main_color, NC::Border());
|
Content = NC::Menu<MPD::Song>(RightColumnStartX, MainStartY, RightColumnWidth, MainHeight, Config.titles_visibility ? "Content" : "", Config.main_color, NC::Border());
|
||||||
Content.setHighlightColor(Config.main_highlight_color);
|
Content.setHighlightColor(Config.main_highlight_color);
|
||||||
Content.cyclicScrolling(Config.use_cyclic_scrolling);
|
Content.cyclicScrolling(Config.use_cyclic_scrolling);
|
||||||
Content.centeredCursor(Config.centered_cursor);
|
Content.centeredCursor(Config.centered_cursor);
|
||||||
@@ -143,42 +143,45 @@ void PlaylistEditor::switchTo()
|
|||||||
|
|
||||||
void PlaylistEditor::update()
|
void PlaylistEditor::update()
|
||||||
{
|
{
|
||||||
if (Playlists.empty() || m_playlists_update_requested)
|
|
||||||
{
|
{
|
||||||
m_playlists_update_requested = false;
|
ScopedUnfilteredMenu<MPD::Playlist> sunfilter_playlists(ReapplyFilter::No, Playlists);
|
||||||
size_t idx = 0;
|
if (Playlists.empty() || m_playlists_update_requested)
|
||||||
try
|
|
||||||
{
|
{
|
||||||
for (MPD::PlaylistIterator it = Mpd.GetPlaylists(), end; it != end; ++it, ++idx)
|
m_playlists_update_requested = false;
|
||||||
|
sunfilter_playlists.set(ReapplyFilter::Yes, true);
|
||||||
|
size_t idx = 0;
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (idx < Playlists.size())
|
for (MPD::PlaylistIterator it = Mpd.GetPlaylists(), end; it != end; ++it, ++idx)
|
||||||
Playlists[idx].value() = std::move(*it);
|
{
|
||||||
|
if (idx < Playlists.size())
|
||||||
|
Playlists[idx].value() = std::move(*it);
|
||||||
|
else
|
||||||
|
Playlists.addItem(std::move(*it));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch (MPD::ServerError &e)
|
||||||
|
{
|
||||||
|
if (e.code() == MPD_SERVER_ERROR_SYSTEM) // no playlists directory
|
||||||
|
Statusbar::print(e.what());
|
||||||
else
|
else
|
||||||
Playlists.addItem(std::move(*it));
|
throw;
|
||||||
};
|
}
|
||||||
|
if (idx < Playlists.size())
|
||||||
|
Playlists.resizeList(idx);
|
||||||
|
std::sort(Playlists.beginV(), Playlists.endV(),
|
||||||
|
LocaleBasedSorting(std::locale(), Config.ignore_leading_the));
|
||||||
}
|
}
|
||||||
catch (MPD::ServerError &e)
|
|
||||||
{
|
|
||||||
if (e.code() == MPD_SERVER_ERROR_SYSTEM) // no playlists directory
|
|
||||||
Statusbar::print(e.what());
|
|
||||||
else
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
if (idx < Playlists.size())
|
|
||||||
Playlists.resizeList(idx);
|
|
||||||
std::sort(Playlists.beginV(), Playlists.endV(),
|
|
||||||
LocaleBasedSorting(std::locale(), Config.ignore_leading_the));
|
|
||||||
Playlists.refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Content.empty() && Global::Timer - m_timer > m_fetching_delay)
|
|
||||||
|| m_content_update_requested)
|
|
||||||
{
|
{
|
||||||
m_content_update_requested = false;
|
ScopedUnfilteredMenu<MPD::Song> sunfilter_content(ReapplyFilter::No, Content);
|
||||||
if (Playlists.empty())
|
if (!Playlists.empty()
|
||||||
Content.clear();
|
&& ((Content.empty() && Global::Timer - m_timer > m_fetching_delay)
|
||||||
else
|
|| m_content_update_requested))
|
||||||
{
|
{
|
||||||
|
m_content_update_requested = false;
|
||||||
|
sunfilter_content.set(ReapplyFilter::Yes, true);
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
MPD::SongIterator s = Mpd.GetPlaylistContent(Playlists.current()->value().path()), end;
|
MPD::SongIterator s = Mpd.GetPlaylistContent(Playlists.current()->value().path()), end;
|
||||||
for (; s != end; ++s, ++idx)
|
for (; s != end; ++s, ++idx)
|
||||||
@@ -202,33 +205,20 @@ void PlaylistEditor::update()
|
|||||||
std::string wtitle;
|
std::string wtitle;
|
||||||
if (Config.titles_visibility)
|
if (Config.titles_visibility)
|
||||||
{
|
{
|
||||||
wtitle = (boost::format("Playlist content (%1%) %2%")
|
wtitle = (boost::format("Content (%1% %2%)")
|
||||||
% boost::lexical_cast<std::string>(Content.size())
|
% boost::lexical_cast<std::string>(Content.size())
|
||||||
% (Content.size() == 1 ? "item" : "items")
|
% (Content.size() == 1 ? "item" : "items")).str();
|
||||||
).str();
|
|
||||||
wtitle.resize(Content.getWidth());
|
wtitle.resize(Content.getWidth());
|
||||||
}
|
}
|
||||||
Content.setTitle(wtitle);
|
Content.setTitle(wtitle);
|
||||||
|
Content.refreshBorder();
|
||||||
}
|
}
|
||||||
Content.display();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isActiveWindow(Content) && Content.empty())
|
|
||||||
{
|
|
||||||
Content.setHighlightColor(Config.main_highlight_color);
|
|
||||||
Playlists.setHighlightColor(Config.active_column_color);
|
|
||||||
w = &Playlists;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Playlists.empty() && Content.empty())
|
|
||||||
{
|
|
||||||
Content.Window::clear();
|
|
||||||
Content.Window::display();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int PlaylistEditor::windowTimeout()
|
int PlaylistEditor::windowTimeout()
|
||||||
{
|
{
|
||||||
|
ScopedUnfilteredMenu<MPD::Song> sunfilter_content(ReapplyFilter::No, Content);
|
||||||
if (Content.empty())
|
if (Content.empty())
|
||||||
return m_window_timeout;
|
return m_window_timeout;
|
||||||
else
|
else
|
||||||
@@ -328,6 +318,51 @@ bool PlaylistEditor::search(SearchDirection direction, bool wrap, bool skip_curr
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string PlaylistEditor::currentFilter()
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
if (isActiveWindow(Playlists))
|
||||||
|
{
|
||||||
|
if (auto pred = Playlists.filterPredicate<Regex::Filter<MPD::Playlist>>())
|
||||||
|
result = pred->constraint();
|
||||||
|
}
|
||||||
|
else if (isActiveWindow(Content))
|
||||||
|
{
|
||||||
|
if (auto pred = Content.filterPredicate<Regex::Filter<MPD::Song>>())
|
||||||
|
result = pred->constraint();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlaylistEditor::applyFilter(const std::string &constraint)
|
||||||
|
{
|
||||||
|
if (isActiveWindow(Playlists))
|
||||||
|
{
|
||||||
|
if (!constraint.empty())
|
||||||
|
{
|
||||||
|
Playlists.applyFilter(Regex::Filter<MPD::Playlist>(
|
||||||
|
constraint,
|
||||||
|
Config.regex_type,
|
||||||
|
PlaylistEntryMatcher));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Playlists.clearFilter();
|
||||||
|
}
|
||||||
|
else if (isActiveWindow(Content))
|
||||||
|
{
|
||||||
|
if (!constraint.empty())
|
||||||
|
{
|
||||||
|
Content.applyFilter(Regex::Filter<MPD::Song>(
|
||||||
|
constraint,
|
||||||
|
Config.regex_type,
|
||||||
|
SongEntryMatcher));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Content.clearFilter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
bool PlaylistEditor::itemAvailable()
|
bool PlaylistEditor::itemAvailable()
|
||||||
@@ -344,14 +379,10 @@ bool PlaylistEditor::addItemToPlaylist(bool play)
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
if (isActiveWindow(Playlists))
|
if (isActiveWindow(Playlists))
|
||||||
{
|
{
|
||||||
std::vector<MPD::Song> list(
|
ScopedUnfilteredMenu<MPD::Song> sunfilter_content(ReapplyFilter::No, Content);
|
||||||
std::make_move_iterator(Mpd.GetPlaylistContent(Playlists.current()->value().path())),
|
result = addSongsToPlaylist(Content.beginV(), Content.endV(), play, -1);
|
||||||
std::make_move_iterator(MPD::SongIterator())
|
|
||||||
);
|
|
||||||
result = addSongsToPlaylist(list.begin(), list.end(), play, -1);
|
|
||||||
Statusbar::printf("Playlist \"%1%\" loaded%2%",
|
Statusbar::printf("Playlist \"%1%\" loaded%2%",
|
||||||
Playlists.current()->value().path(), withErrors(result)
|
Playlists.current()->value().path(), withErrors(result));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
else if (isActiveWindow(Content))
|
else if (isActiveWindow(Content))
|
||||||
result = addSongToPlaylist(Content.current()->value(), play);
|
result = addSongToPlaylist(Content.current()->value(), play);
|
||||||
@@ -372,19 +403,13 @@ std::vector<MPD::Song> PlaylistEditor::getSelectedSongs()
|
|||||||
std::copy(
|
std::copy(
|
||||||
std::make_move_iterator(Mpd.GetPlaylistContent(e.value().path())),
|
std::make_move_iterator(Mpd.GetPlaylistContent(e.value().path())),
|
||||||
std::make_move_iterator(MPD::SongIterator()),
|
std::make_move_iterator(MPD::SongIterator()),
|
||||||
std::back_inserter(result)
|
std::back_inserter(result));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if no item is selected, add songs from right column
|
// if no item is selected, add songs from right column
|
||||||
|
ScopedUnfilteredMenu<MPD::Song> sunfilter_content(ReapplyFilter::No, Content);
|
||||||
if (!any_selected && !Playlists.empty())
|
if (!any_selected && !Playlists.empty())
|
||||||
{
|
std::copy(Content.beginV(), Content.endV(), std::back_inserter(result));
|
||||||
std::copy(
|
|
||||||
std::make_move_iterator(Mpd.GetPlaylistContent(Playlists.current()->value().path())),
|
|
||||||
std::make_move_iterator(MPD::SongIterator()),
|
|
||||||
std::back_inserter(result)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (isActiveWindow(Content))
|
else if (isActiveWindow(Content))
|
||||||
result = Content.getSelectedSongs();
|
result = Content.getSelectedSongs();
|
||||||
@@ -397,6 +422,7 @@ bool PlaylistEditor::previousColumnAvailable()
|
|||||||
{
|
{
|
||||||
if (isActiveWindow(Content))
|
if (isActiveWindow(Content))
|
||||||
{
|
{
|
||||||
|
ScopedUnfilteredMenu<MPD::Playlist> sunfilter_playlists(ReapplyFilter::No, Playlists);
|
||||||
if (!Playlists.empty())
|
if (!Playlists.empty())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -418,6 +444,7 @@ bool PlaylistEditor::nextColumnAvailable()
|
|||||||
{
|
{
|
||||||
if (isActiveWindow(Playlists))
|
if (isActiveWindow(Playlists))
|
||||||
{
|
{
|
||||||
|
ScopedUnfilteredMenu<MPD::Song> sunfilter_content(ReapplyFilter::No, Content);
|
||||||
if (!Content.empty())
|
if (!Content.empty())
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -442,15 +469,17 @@ void PlaylistEditor::updateTimer()
|
|||||||
m_timer = Global::Timer;
|
m_timer = Global::Timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaylistEditor::Locate(const MPD::Playlist &playlist)
|
void PlaylistEditor::locatePlaylist(const MPD::Playlist &playlist)
|
||||||
{
|
{
|
||||||
update();
|
update();
|
||||||
auto begin = Playlists.beginV(), end = Playlists.endV();
|
Playlists.clearFilter();
|
||||||
auto it = std::find(begin, end, playlist);
|
auto first = Playlists.beginV(), last = Playlists.endV();
|
||||||
if (it != end)
|
auto it = std::find(first, last, playlist);
|
||||||
|
if (it != last)
|
||||||
{
|
{
|
||||||
Playlists.highlight(it-begin);
|
Playlists.highlight(it - first);
|
||||||
Content.clear();
|
Content.clear();
|
||||||
|
Content.clearFilter();
|
||||||
switchTo();
|
switchTo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,9 @@ struct PlaylistEditor: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, T
|
|||||||
virtual void clearSearchConstraint() OVERRIDE;
|
virtual void clearSearchConstraint() OVERRIDE;
|
||||||
virtual bool search(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
virtual bool search(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
||||||
|
|
||||||
|
virtual std::string currentFilter() OVERRIDE;
|
||||||
|
virtual void applyFilter(const std::string &filter) OVERRIDE;
|
||||||
|
|
||||||
// HasSongs implementation
|
// HasSongs implementation
|
||||||
virtual bool itemAvailable() OVERRIDE;
|
virtual bool itemAvailable() OVERRIDE;
|
||||||
virtual bool addItemToPlaylist(bool play) OVERRIDE;
|
virtual bool addItemToPlaylist(bool play) OVERRIDE;
|
||||||
@@ -73,7 +76,7 @@ struct PlaylistEditor: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, T
|
|||||||
void requestPlaylistsUpdate() { m_playlists_update_requested = true; }
|
void requestPlaylistsUpdate() { m_playlists_update_requested = true; }
|
||||||
void requestContentsUpdate() { m_content_update_requested = true; }
|
void requestContentsUpdate() { m_content_update_requested = true; }
|
||||||
|
|
||||||
virtual void Locate(const MPD::Playlist &playlist);
|
void locatePlaylist(const MPD::Playlist &playlist);
|
||||||
|
|
||||||
NC::Menu<MPD::Playlist> Playlists;
|
NC::Menu<MPD::Playlist> Playlists;
|
||||||
SongMenu Content;
|
SongMenu Content;
|
||||||
|
|||||||
@@ -372,6 +372,9 @@ struct Window
|
|||||||
/// @see refresh()
|
/// @see refresh()
|
||||||
void display();
|
void display();
|
||||||
|
|
||||||
|
/// Refreshes window's border
|
||||||
|
void refreshBorder() const;
|
||||||
|
|
||||||
/// Refreshes whole window, but not the border
|
/// Refreshes whole window, but not the border
|
||||||
/// @see display()
|
/// @see display()
|
||||||
virtual void refresh();
|
virtual void refresh();
|
||||||
@@ -437,10 +440,6 @@ protected:
|
|||||||
///
|
///
|
||||||
void setColor(Color c);
|
void setColor(Color c);
|
||||||
|
|
||||||
/// Refreshes window's border
|
|
||||||
///
|
|
||||||
void refreshBorder() const;
|
|
||||||
|
|
||||||
/// Changes dimensions of window, called from resize()
|
/// Changes dimensions of window, called from resize()
|
||||||
/// @param width new window's width
|
/// @param width new window's width
|
||||||
/// @param height new window's height
|
/// @param height new window's height
|
||||||
|
|||||||
Reference in New Issue
Block a user