Implement filtering in browser and search engine
This commit is contained in:
@@ -1947,8 +1947,7 @@ void ReversePlaylist::run()
|
|||||||
bool ApplyFilter::canBeRun()
|
bool ApplyFilter::canBeRun()
|
||||||
{
|
{
|
||||||
m_searchable = dynamic_cast<Searchable *>(myScreen);
|
m_searchable = dynamic_cast<Searchable *>(myScreen);
|
||||||
return m_searchable != nullptr
|
return m_searchable != nullptr;
|
||||||
&& myScreen == myPlaylist;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyFilter::run()
|
void ApplyFilter::run()
|
||||||
|
|||||||
@@ -267,6 +267,28 @@ bool Browser::search(SearchDirection direction, bool wrap, bool skip_current)
|
|||||||
return ::search(w, m_search_predicate, direction, wrap, 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()
|
bool Browser::itemAvailable()
|
||||||
@@ -399,7 +421,9 @@ void Browser::locateSong(const MPD::Song &s)
|
|||||||
|
|
||||||
if (myScreen != this)
|
if (myScreen != this)
|
||||||
switchTo();
|
switchTo();
|
||||||
|
|
||||||
|
w.clearFilter();
|
||||||
|
|
||||||
// change to relevant directory
|
// change to relevant directory
|
||||||
if (m_current_directory != s.getDirectory())
|
if (m_current_directory != s.getDirectory())
|
||||||
{
|
{
|
||||||
@@ -432,6 +456,8 @@ bool Browser::enterDirectory()
|
|||||||
|
|
||||||
void Browser::getDirectory(std::string directory)
|
void Browser::getDirectory(std::string directory)
|
||||||
{
|
{
|
||||||
|
ScopedUnfilteredMenu<MPD::Item, ReapplyFilter::Yes> sunfilter(w);
|
||||||
|
|
||||||
m_scroll_beginning = 0;
|
m_scroll_beginning = 0;
|
||||||
w.clear();
|
w.clear();
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,10 @@ struct Browser: Screen<BrowserWindow>, HasSongs, Searchable, Tabbable
|
|||||||
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
|
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
|
||||||
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;
|
||||||
|
|||||||
@@ -172,17 +172,6 @@ std::string Timestamp(time_t t)
|
|||||||
return result;
|
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 Scroller(const std::wstring &str, size_t &pos, size_t width)
|
||||||
{
|
{
|
||||||
std::wstring s(str);
|
std::wstring s(str);
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "interfaces.h"
|
#include "interfaces.h"
|
||||||
#include "mpdpp.h"
|
#include "mpdpp.h"
|
||||||
|
#include "playlist.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "song_list.h"
|
#include "song_list.h"
|
||||||
@@ -371,6 +372,21 @@ template <typename Iterator> std::string getSharedDirectory(Iterator first, Iter
|
|||||||
return result;
|
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)
|
template <typename T> void ShowTime(T &buf, size_t length, bool short_names)
|
||||||
{
|
{
|
||||||
const unsigned MINUTE = 60;
|
const unsigned MINUTE = 60;
|
||||||
@@ -442,8 +458,6 @@ std::string timeFormat(const char *format, time_t t);
|
|||||||
|
|
||||||
std::string Timestamp(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);
|
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,
|
void writeCyclicBuffer(const NC::WBuffer &buf, NC::Window &w, size_t &start_pos,
|
||||||
size_t width, const std::wstring &separator);
|
size_t width, const std::wstring &separator);
|
||||||
|
|||||||
@@ -336,8 +336,10 @@ void Menu<ItemT>::reset()
|
|||||||
template <typename ItemT>
|
template <typename ItemT>
|
||||||
void Menu<ItemT>::clear()
|
void Menu<ItemT>::clear()
|
||||||
{
|
{
|
||||||
clearFilter();
|
// Don't clear the filter here.
|
||||||
m_items->clear();
|
m_all_items.clear();
|
||||||
|
m_filtered_items.clear();
|
||||||
|
m_items = &m_all_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ItemT>
|
template <typename ItemT>
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ struct Playlist: Screen<SongMenu>, HasSongs, Searchable, Tabbable
|
|||||||
void enableHighlighting();
|
void enableHighlighting();
|
||||||
|
|
||||||
void setSelectedItemsPriority(int prio);
|
void setSelectedItemsPriority(int prio);
|
||||||
|
|
||||||
bool checkForSong(const MPD::Song &s);
|
bool checkForSong(const MPD::Song &s);
|
||||||
void registerSong(const MPD::Song &s);
|
void registerSong(const MPD::Song &s);
|
||||||
void unregisterSong(const MPD::Song &s);
|
void unregisterSong(const MPD::Song &s);
|
||||||
|
|||||||
@@ -269,6 +269,27 @@ bool SearchEngine::search(SearchDirection direction, bool wrap, bool skip_curren
|
|||||||
return ::search(w, m_search_predicate, direction, wrap, skip_current);
|
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()
|
bool SearchEngine::actionRunnable()
|
||||||
@@ -306,6 +327,7 @@ void SearchEngine::runAction()
|
|||||||
}
|
}
|
||||||
else if (option == SearchButton)
|
else if (option == SearchButton)
|
||||||
{
|
{
|
||||||
|
w.clearFilter();
|
||||||
Statusbar::print("Searching...");
|
Statusbar::print("Searching...");
|
||||||
if (w.size() > StaticOptions)
|
if (w.size() > StaticOptions)
|
||||||
Prepare();
|
Prepare();
|
||||||
|
|||||||
@@ -116,6 +116,9 @@ struct SearchEngine: Screen<SearchEngineWindow>, HasActions, HasSongs, Searchabl
|
|||||||
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;
|
||||||
|
|
||||||
// HasActions implementation
|
// HasActions implementation
|
||||||
virtual bool actionRunnable() OVERRIDE;
|
virtual bool actionRunnable() OVERRIDE;
|
||||||
virtual void runAction() OVERRIDE;
|
virtual void runAction() OVERRIDE;
|
||||||
|
|||||||
@@ -75,4 +75,4 @@ struct SongMenu: NC::Menu<MPD::Song>, SongList
|
|||||||
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
virtual std::vector<MPD::Song> getSelectedSongs() OVERRIDE;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NCMPCPP_SONG_LIST_H
|
#endif // NCMPCPP_SONG_LIST_H
|
||||||
|
|||||||
Reference in New Issue
Block a user