Implement filtering in browser and search engine

This commit is contained in:
Andrzej Rybczak
2016-11-13 02:19:14 +01:00
parent 29b1813c6d
commit 17effe0115
10 changed files with 79 additions and 21 deletions

View File

@@ -1947,8 +1947,7 @@ void ReversePlaylist::run()
bool ApplyFilter::canBeRun()
{
m_searchable = dynamic_cast<Searchable *>(myScreen);
return m_searchable != nullptr
&& myScreen == myPlaylist;
return m_searchable != nullptr;
}
void ApplyFilter::run()

View File

@@ -267,6 +267,28 @@ bool Browser::search(SearchDirection direction, bool wrap, bool skip_current)
return ::search(w, m_search_predicate, direction, wrap, skip_current);
}
std::string Browser::currentFilter()
{
std::string result;
if (auto pred = w.filterPredicate<Regex::Filter<MPD::Item>>())
result = pred->constraint();
return result;
}
void Browser::applyFilter(const std::string &constraint)
{
if (!constraint.empty())
{
w.applyFilter(Regex::Filter<MPD::Item>(
constraint,
Config.regex_type,
std::bind(browserEntryMatcher, ph::_1, ph::_2, true)));
}
else
w.clearFilter();
}
/***********************************************************************/
bool Browser::itemAvailable()
@@ -399,7 +421,9 @@ void Browser::locateSong(const MPD::Song &s)
if (myScreen != this)
switchTo();
w.clearFilter();
// change to relevant directory
if (m_current_directory != s.getDirectory())
{
@@ -432,6 +456,8 @@ bool Browser::enterDirectory()
void Browser::getDirectory(std::string directory)
{
ScopedUnfilteredMenu<MPD::Item, ReapplyFilter::Yes> sunfilter(w);
m_scroll_beginning = 0;
w.clear();

View File

@@ -67,7 +67,10 @@ struct Browser: Screen<BrowserWindow>, HasSongs, Searchable, Tabbable
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
virtual void clearSearchConstraint() 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
virtual bool itemAvailable() OVERRIDE;
virtual bool addItemToPlaylist(bool play) OVERRIDE;

View File

@@ -172,17 +172,6 @@ std::string Timestamp(time_t t)
return result;
}
void markSongsInPlaylist(SongList &list)
{
MPD::Song *s;
for (auto &p : list)
{
s = p.get<Bit::Song>();
if (s != nullptr)
p.get<Bit::Properties>().setBold(myPlaylist->checkForSong(*s));
}
}
std::wstring Scroller(const std::wstring &str, size_t &pos, size_t width)
{
std::wstring s(str);

View File

@@ -23,6 +23,7 @@
#include "interfaces.h"
#include "mpdpp.h"
#include "playlist.h"
#include "screen.h"
#include "settings.h"
#include "song_list.h"
@@ -371,6 +372,21 @@ template <typename Iterator> std::string getSharedDirectory(Iterator first, Iter
return result;
}
template <typename ListT>
void markSongsInPlaylist(ListT &list)
{
ScopedUnfilteredMenu<
typename ListT::Item::Type,
ReapplyFilter::No> sunfilter(list);
MPD::Song *s;
for (auto &p : static_cast<SongList &>(list))
{
s = p.get<Bit::Song>();
if (s != nullptr)
p.get<Bit::Properties>().setBold(myPlaylist->checkForSong(*s));
}
}
template <typename T> void ShowTime(T &buf, size_t length, bool short_names)
{
const unsigned MINUTE = 60;
@@ -442,8 +458,6 @@ std::string timeFormat(const char *format, time_t t);
std::string Timestamp(time_t t);
void markSongsInPlaylist(SongList &list);
std::wstring Scroller(const std::wstring &str, size_t &pos, size_t width);
void writeCyclicBuffer(const NC::WBuffer &buf, NC::Window &w, size_t &start_pos,
size_t width, const std::wstring &separator);

View File

@@ -336,8 +336,10 @@ void Menu<ItemT>::reset()
template <typename ItemT>
void Menu<ItemT>::clear()
{
clearFilter();
m_items->clear();
// Don't clear the filter here.
m_all_items.clear();
m_filtered_items.clear();
m_items = &m_all_items;
}
template <typename ItemT>

View File

@@ -72,7 +72,7 @@ struct Playlist: Screen<SongMenu>, HasSongs, Searchable, Tabbable
void enableHighlighting();
void setSelectedItemsPriority(int prio);
bool checkForSong(const MPD::Song &s);
void registerSong(const MPD::Song &s);
void unregisterSong(const MPD::Song &s);

View File

@@ -269,6 +269,27 @@ bool SearchEngine::search(SearchDirection direction, bool wrap, bool skip_curren
return ::search(w, m_search_predicate, direction, wrap, skip_current);
}
std::string SearchEngine::currentFilter()
{
std::string result;
if (auto pred = w.filterPredicate<Regex::ItemFilter<SEItem>>())
result = pred->constraint();
return result;
}
void SearchEngine::applyFilter(const std::string &constraint)
{
if (!constraint.empty())
{
w.applyFilter(Regex::ItemFilter<SEItem>(
constraint,
Config.regex_type,
std::bind(SEItemEntryMatcher, ph::_1, ph::_2, true)));
}
else
w.clearFilter();
}
/***********************************************************************/
bool SearchEngine::actionRunnable()
@@ -306,6 +327,7 @@ void SearchEngine::runAction()
}
else if (option == SearchButton)
{
w.clearFilter();
Statusbar::print("Searching...");
if (w.size() > StaticOptions)
Prepare();

View File

@@ -116,6 +116,9 @@ struct SearchEngine: Screen<SearchEngineWindow>, HasActions, HasSongs, Searchabl
virtual void clearSearchConstraint() 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;
// HasActions implementation
virtual bool actionRunnable() OVERRIDE;
virtual void runAction() OVERRIDE;

View File

@@ -75,4 +75,4 @@ struct SongMenu: NC::Menu<MPD::Song>, SongList
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
};
#endif // NCMPCPP_SONG_LIST_H
#endif // NCMPCPP_SONG_LIST_H