searchable: retrieve currently applied search constraint

This commit is contained in:
Andrzej Rybczak
2016-11-11 20:26:42 +01:00
parent cbba364685
commit 60e66b47b6
19 changed files with 168 additions and 84 deletions

View File

@@ -1820,12 +1820,12 @@ void SelectFoundItems::run()
{
auto current_pos = m_list->choice();
myScreen->activeWindow()->scroll(NC::Scroll::Home);
bool found = m_searchable->find(SearchDirection::Forward, false, false);
bool found = m_searchable->search(SearchDirection::Forward, false, false);
if (found)
{
Statusbar::print("Searching for items...");
m_list->currentP()->setSelected(true);
while (m_searchable->find(SearchDirection::Forward, false, true))
while (m_searchable->search(SearchDirection::Forward, false, true))
m_list->currentP()->setSelected(true);
Statusbar::print("Found items selected");
}
@@ -2006,7 +2006,7 @@ void NextFoundItem::run()
{
Searchable *w = dynamic_cast<Searchable *>(myScreen);
assert(w != nullptr);
w->find(SearchDirection::Forward, Config.wrapped_search, true);
w->search(SearchDirection::Forward, Config.wrapped_search, true);
listsChangeFinisher();
}
@@ -2019,7 +2019,7 @@ void PreviousFoundItem::run()
{
Searchable *w = dynamic_cast<Searchable *>(myScreen);
assert(w != nullptr);
w->find(SearchDirection::Backward, Config.wrapped_search, true);
w->search(SearchDirection::Backward, Config.wrapped_search, true);
listsChangeFinisher();
}
@@ -2959,7 +2959,7 @@ void findItem(const SearchDirection direction)
Statusbar::Helpers::FindImmediately(w, direction)
);
Statusbar::put() << (boost::format("Find %1%: ") % direction).str();
constraint = wFooter->prompt();
constraint = wFooter->prompt(w->searchConstraint());
}
try
@@ -2967,7 +2967,7 @@ void findItem(const SearchDirection direction)
if (constraint.empty())
{
Statusbar::printf("Constraint unset");
w->clearConstraint();
w->clearSearchConstraint();
}
else
{

View File

@@ -244,22 +244,27 @@ bool Browser::allowsSearching()
return true;
}
const std::string &Browser::searchConstraint()
{
return m_search_predicate.constraint();
}
void Browser::setSearchConstraint(const std::string &constraint)
{
m_search_predicate = Regex::Filter<MPD::Item>(
Regex::make(constraint, Config.regex_type),
std::bind(browserEntryMatcher, ph::_1, ph::_2, false)
);
constraint,
Config.regex_type,
std::bind(browserEntryMatcher, ph::_1, ph::_2, false));
}
void Browser::clearConstraint()
void Browser::clearSearchConstraint()
{
m_search_predicate.clear();
}
bool Browser::find(SearchDirection direction, bool wrap, bool skip_current)
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);
}
/***********************************************************************/

View File

@@ -63,9 +63,10 @@ struct Browser: Screen<BrowserWindow>, HasSongs, Searchable, Tabbable
// Searchable implementation
virtual bool allowsSearching() OVERRIDE;
virtual const std::string &searchConstraint() OVERRIDE;
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
virtual void clearConstraint() OVERRIDE;
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
virtual void clearSearchConstraint() OVERRIDE;
virtual bool search(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
// HasSongs implementation
virtual bool itemAvailable() OVERRIDE;

View File

@@ -54,7 +54,7 @@ Iterator wrappedSearch(Iterator begin, Iterator current, Iterator end,
template <typename ItemT, typename PredicateT>
bool search(NC::Menu<ItemT> &m, const PredicateT &pred,
SearchDirection direction, bool wrap, bool skip_current)
SearchDirection direction, bool wrap, bool skip_current)
{
bool result = false;
if (pred.defined())

View File

@@ -32,9 +32,11 @@
struct Searchable
{
virtual bool allowsSearching() = 0;
virtual const std::string &searchConstraint() = 0;
virtual void setSearchConstraint(const std::string &constraint) = 0;
virtual void clearConstraint() = 0;
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) = 0;
virtual void clearSearchConstraint() = 0;
virtual bool search(SearchDirection direction, bool wrap, bool skip_current) = 0;
};
struct HasActions

View File

@@ -538,32 +538,43 @@ bool MediaLibrary::allowsSearching()
return true;
}
const std::string &MediaLibrary::searchConstraint()
{
if (isActiveWindow(Tags))
return m_tags_search_predicate.constraint();
else if (isActiveWindow(Albums))
return m_albums_search_predicate.constraint();
else if (isActiveWindow(Songs))
return m_songs_search_predicate.constraint();
throw std::runtime_error("no active window");
}
void MediaLibrary::setSearchConstraint(const std::string &constraint)
{
if (isActiveWindow(Tags))
{
m_tags_search_predicate = Regex::Filter<PrimaryTag>(
Regex::make(constraint, Config.regex_type),
TagEntryMatcher
);
constraint,
Config.regex_type,
TagEntryMatcher);
}
else if (isActiveWindow(Albums))
{
m_albums_search_predicate = Regex::ItemFilter<AlbumEntry>(
Regex::make(constraint, Config.regex_type),
std::bind(AlbumEntryMatcher, ph::_1, ph::_2, false)
);
constraint,
Config.regex_type,
std::bind(AlbumEntryMatcher, ph::_1, ph::_2, false));
}
else if (isActiveWindow(Songs))
{
m_songs_search_predicate = Regex::Filter<MPD::Song>(
Regex::make(constraint, Config.regex_type),
SongEntryMatcher
);
constraint,
Config.regex_type,
SongEntryMatcher);
}
}
void MediaLibrary::clearConstraint()
void MediaLibrary::clearSearchConstraint()
{
if (isActiveWindow(Tags))
m_tags_search_predicate.clear();
@@ -573,15 +584,15 @@ void MediaLibrary::clearConstraint()
m_songs_search_predicate.clear();
}
bool MediaLibrary::find(SearchDirection direction, bool wrap, bool skip_current)
bool MediaLibrary::search(SearchDirection direction, bool wrap, bool skip_current)
{
bool result = false;
if (isActiveWindow(Tags))
result = search(Tags, m_tags_search_predicate, direction, wrap, skip_current);
result = ::search(Tags, m_tags_search_predicate, direction, wrap, skip_current);
else if (isActiveWindow(Albums))
result = search(Albums, m_albums_search_predicate, direction, wrap, skip_current);
result = ::search(Albums, m_albums_search_predicate, direction, wrap, skip_current);
else if (isActiveWindow(Songs))
result = search(Songs, m_songs_search_predicate, direction, wrap, skip_current);
result = ::search(Songs, m_songs_search_predicate, direction, wrap, skip_current);
return result;
}

View File

@@ -50,9 +50,10 @@ struct MediaLibrary: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, Tab
// Searchable implementation
virtual bool allowsSearching() OVERRIDE;
virtual const std::string &searchConstraint() OVERRIDE;
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
virtual void clearConstraint() OVERRIDE;
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
virtual void clearSearchConstraint() OVERRIDE;
virtual bool search(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
// HasSongs implementation
virtual bool itemAvailable() OVERRIDE;

View File

@@ -153,21 +153,27 @@ bool Playlist::allowsSearching()
return true;
}
const std::string &Playlist::searchConstraint()
{
return m_search_predicate.constraint();
}
void Playlist::setSearchConstraint(const std::string &constraint)
{
m_search_predicate = Regex::Filter<MPD::Song>(
Regex::make(constraint, Config.regex_type), playlistEntryMatcher
);
constraint,
Config.regex_type,
playlistEntryMatcher);
}
void Playlist::clearConstraint()
void Playlist::clearSearchConstraint()
{
m_search_predicate.clear();
}
bool Playlist::find(SearchDirection direction, bool wrap, bool skip_current)
bool Playlist::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);
}
/***********************************************************************/

View File

@@ -50,9 +50,10 @@ struct Playlist: Screen<SongMenu>, HasSongs, Searchable, Tabbable
// Searchable implementation
virtual bool allowsSearching() OVERRIDE;
virtual const std::string &searchConstraint() OVERRIDE;
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
virtual void clearConstraint() OVERRIDE;
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
virtual void clearSearchConstraint() OVERRIDE;
virtual bool search(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
// HasSongs implementation
virtual bool itemAvailable() OVERRIDE;

View File

@@ -283,25 +283,34 @@ bool PlaylistEditor::allowsSearching()
return true;
}
const std::string &PlaylistEditor::searchConstraint()
{
if (isActiveWindow(Playlists))
return m_playlists_search_predicate.constraint();
else if (isActiveWindow(Content))
return m_content_search_predicate.constraint();
throw std::runtime_error("no active window");
}
void PlaylistEditor::setSearchConstraint(const std::string &constraint)
{
if (isActiveWindow(Playlists))
{
m_playlists_search_predicate = Regex::Filter<MPD::Playlist>(
Regex::make(constraint, Config.regex_type),
PlaylistEntryMatcher
);
constraint,
Config.regex_type,
PlaylistEntryMatcher);
}
else if (isActiveWindow(Content))
{
m_content_search_predicate = Regex::Filter<MPD::Song>(
Regex::make(constraint, Config.regex_type),
SongEntryMatcher
);
constraint,
Config.regex_type,
SongEntryMatcher);
}
}
void PlaylistEditor::clearConstraint()
void PlaylistEditor::clearSearchConstraint()
{
if (isActiveWindow(Playlists))
m_playlists_search_predicate.clear();
@@ -309,13 +318,13 @@ void PlaylistEditor::clearConstraint()
m_content_search_predicate.clear();
}
bool PlaylistEditor::find(SearchDirection direction, bool wrap, bool skip_current)
bool PlaylistEditor::search(SearchDirection direction, bool wrap, bool skip_current)
{
bool result = false;
if (isActiveWindow(Playlists))
result = search(Playlists, m_playlists_search_predicate, direction, wrap, skip_current);
result = ::search(Playlists, m_playlists_search_predicate, direction, wrap, skip_current);
else if (isActiveWindow(Content))
result = search(Content, m_content_search_predicate, direction, wrap, skip_current);
result = ::search(Content, m_content_search_predicate, direction, wrap, skip_current);
return result;
}

View File

@@ -50,9 +50,10 @@ struct PlaylistEditor: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, T
// Searchable implementation
virtual bool allowsSearching() OVERRIDE;
virtual const std::string &searchConstraint() OVERRIDE;
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
virtual void clearConstraint() OVERRIDE;
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
virtual void clearSearchConstraint() OVERRIDE;
virtual bool search(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
// HasSongs implementation
virtual bool itemAvailable() OVERRIDE;

View File

@@ -80,14 +80,25 @@ struct Filter
typedef std::function<bool(const Regex &, const T &)> FilterFunction;
Filter() { }
Filter(Regex rx, FilterFunction filter)
: m_rx(std::move(rx)), m_filter(std::move(filter)) { }
template <typename FilterT>
Filter(const std::string &constraint,
boost::regex_constants::syntax_option_type flags,
FilterT &&filter)
: m_rx(make(constraint, flags))
, m_constraint(constraint)
, m_filter(std::forward<FilterT>(filter))
{ }
void clear()
{
m_filter = nullptr;
}
const std::string &constraint() const {
return m_constraint;
}
bool operator()(const Item &item) const {
assert(defined());
return m_filter(m_rx, item.value());
@@ -100,6 +111,7 @@ struct Filter
private:
Regex m_rx;
std::string m_constraint;
FilterFunction m_filter;
};
@@ -110,14 +122,25 @@ template <typename T> struct ItemFilter
typedef std::function<bool(const Regex &, const Item &)> FilterFunction;
ItemFilter() { }
ItemFilter(Regex rx, FilterFunction filter)
: m_rx(std::move(rx)), m_filter(std::move(filter)) { }
template <typename FilterT>
ItemFilter(const std::string &constraint,
boost::regex_constants::syntax_option_type flags,
FilterT &&filter)
: m_rx(make(constraint, flags))
, m_constraint(constraint)
, m_filter(std::forward<FilterT>(filter))
{ }
void clear()
{
m_filter = nullptr;
}
const std::string &constraint() const {
return m_constraint;
}
bool operator()(const Item &item) {
return m_filter(m_rx, item);
}
@@ -129,6 +152,7 @@ template <typename T> struct ItemFilter
private:
Regex m_rx;
std::string m_constraint;
FilterFunction m_filter;
};

View File

@@ -246,22 +246,27 @@ bool SearchEngine::allowsSearching()
return w.rbegin()->value().isSong();
}
const std::string &SearchEngine::searchConstraint()
{
return m_search_predicate.constraint();
}
void SearchEngine::setSearchConstraint(const std::string &constraint)
{
m_search_predicate = Regex::ItemFilter<SEItem>(
Regex::make(constraint, Config.regex_type),
std::bind(SEItemEntryMatcher, ph::_1, ph::_2, false)
);
constraint,
Config.regex_type,
std::bind(SEItemEntryMatcher, ph::_1, ph::_2, false));
}
void SearchEngine::clearConstraint()
void SearchEngine::clearSearchConstraint()
{
m_search_predicate.clear();
}
bool SearchEngine::find(SearchDirection direction, bool wrap, bool skip_current)
bool SearchEngine::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);
}
/***********************************************************************/

View File

@@ -111,9 +111,10 @@ struct SearchEngine: Screen<SearchEngineWindow>, HasActions, HasSongs, Searchabl
// Searchable implementation
virtual bool allowsSearching() OVERRIDE;
virtual const std::string &searchConstraint() OVERRIDE;
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
virtual void clearConstraint() OVERRIDE;
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
virtual void clearSearchConstraint() OVERRIDE;
virtual bool search(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
// HasActions implementation
virtual bool actionRunnable() OVERRIDE;

View File

@@ -202,21 +202,27 @@ bool SelectedItemsAdder::allowsSearching()
return true;
}
const std::string &SelectedItemsAdder::searchConstraint()
{
return m_search_predicate.constraint();
}
void SelectedItemsAdder::setSearchConstraint(const std::string &constraint)
{
m_search_predicate = Regex::ItemFilter<Entry>(
Regex::make(constraint, Config.regex_type), EntryMatcher
);
constraint,
Config.regex_type,
EntryMatcher);
}
void SelectedItemsAdder::clearConstraint()
void SelectedItemsAdder::clearSearchConstraint()
{
m_search_predicate.clear();
}
bool SelectedItemsAdder::find(SearchDirection direction, bool wrap, bool skip_current)
bool SelectedItemsAdder::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);
}
/***********************************************************************/

View File

@@ -55,9 +55,10 @@ struct SelectedItemsAdder: Screen<NC::Menu<RunnableItem<std::string, void()>> *>
// Searchable implementation
virtual bool allowsSearching() OVERRIDE;
virtual const std::string &searchConstraint() OVERRIDE;
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
virtual void clearConstraint() OVERRIDE;
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
virtual void clearSearchConstraint() OVERRIDE;
virtual bool search(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
private:
void populatePlaylistSelector(BaseScreen *screen);

View File

@@ -228,7 +228,7 @@ bool Statusbar::Helpers::FindImmediately::operator()(const char *s)
if (m_w->allowsSearching() && m_s != s)
{
m_w->setSearchConstraint(s);
m_found = m_w->find(m_direction, Config.wrapped_search, false);
m_found = m_w->search(m_direction, Config.wrapped_search, false);
if (myScreen == myPlaylist)
myPlaylist->enableHighlighting();
myScreen->refreshWindow();

View File

@@ -480,25 +480,34 @@ bool TagEditor::allowsSearching()
return w == Dirs || w == Tags;
}
const std::string &TagEditor::searchConstraint()
{
if (w == Dirs)
return m_directories_search_predicate.constraint();
else if (w == Tags)
return m_songs_search_predicate.constraint();
throw std::runtime_error("shouldn't happen due to condition in allowsSearching");
}
void TagEditor::setSearchConstraint(const std::string &constraint)
{
if (w == Dirs)
{
m_directories_search_predicate = Regex::Filter<std::pair<std::string, std::string>>(
Regex::make(constraint, Config.regex_type),
std::bind(DirEntryMatcher, ph::_1, ph::_2, false)
);
constraint,
Config.regex_type,
std::bind(DirEntryMatcher, ph::_1, ph::_2, false));
}
else if (w == Tags)
{
m_songs_search_predicate = Regex::Filter<MPD::MutableSong>(
Regex::make(constraint, Config.regex_type),
SongEntryMatcher
);
constraint,
Config.regex_type,
SongEntryMatcher);
}
}
void TagEditor::clearConstraint()
void TagEditor::clearSearchConstraint()
{
if (w == Dirs)
m_directories_search_predicate.clear();
@@ -506,13 +515,13 @@ void TagEditor::clearConstraint()
m_songs_search_predicate.clear();
}
bool TagEditor::find(SearchDirection direction, bool wrap, bool skip_current)
bool TagEditor::search(SearchDirection direction, bool wrap, bool skip_current)
{
bool result = false;
if (w == Dirs)
result = search(*Dirs, m_directories_search_predicate, direction, wrap, skip_current);
result = ::search(*Dirs, m_directories_search_predicate, direction, wrap, skip_current);
else if (w == Tags)
result = search(*Tags, m_songs_search_predicate, direction, wrap, skip_current);
result = ::search(*Tags, m_songs_search_predicate, direction, wrap, skip_current);
return result;
}

View File

@@ -69,9 +69,10 @@ struct TagEditor: Screen<NC::Window *>, HasActions, HasColumns, HasSongs, Search
// Searchable implementation
virtual bool allowsSearching() OVERRIDE;
virtual const std::string &searchConstraint() OVERRIDE;
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
virtual void clearConstraint() OVERRIDE;
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
virtual void clearSearchConstraint() OVERRIDE;
virtual bool search(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
// HasActions implementation
virtual bool actionRunnable() OVERRIDE;