actions: make find forward/backward incremental
This commit is contained in:
2
NEWS
2
NEWS
@@ -6,6 +6,8 @@ ncmpcpp-0.7 (????-??-??)
|
|||||||
* Directories and playlists in browser can now be sorted by modification time.
|
* Directories and playlists in browser can now be sorted by modification time.
|
||||||
* ~ is now expanded to home directory in mpd_host configuration variable.
|
* ~ is now expanded to home directory in mpd_host configuration variable.
|
||||||
* It is now possible to define startup slave screen using -S/--slave-screen command line option or startup_slave_screen configuration variable.
|
* It is now possible to define startup slave screen using -S/--slave-screen command line option or startup_slave_screen configuration variable.
|
||||||
|
* List filtering has been removed due to the major part of its functionality overlapping with find forward/backward.
|
||||||
|
* Find backward/forward function is now incremental.
|
||||||
|
|
||||||
ncmpcpp-0.6.1 (2014-11-06)
|
ncmpcpp-0.6.1 (2014-11-06)
|
||||||
|
|
||||||
|
|||||||
@@ -72,23 +72,6 @@ using Global::myScreen;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
enum class Find { Forward, Backward };
|
|
||||||
|
|
||||||
std::string findToString(Find find)
|
|
||||||
{
|
|
||||||
std::string result;
|
|
||||||
switch (find)
|
|
||||||
{
|
|
||||||
case Find::Forward:
|
|
||||||
result = "forward";
|
|
||||||
break;
|
|
||||||
case Find::Backward:
|
|
||||||
result = "backward";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
boost::array<
|
boost::array<
|
||||||
Actions::BaseAction *, static_cast<size_t>(Actions::Type::_numberOfActions)
|
Actions::BaseAction *, static_cast<size_t>(Actions::Type::_numberOfActions)
|
||||||
> AvailableActions;
|
> AvailableActions;
|
||||||
@@ -96,7 +79,7 @@ boost::array<
|
|||||||
void populateActions();
|
void populateActions();
|
||||||
|
|
||||||
void seek();
|
void seek();
|
||||||
void findItem(const Find direction);
|
void findItem(const SearchDirection direction);
|
||||||
void listsChangeFinisher();
|
void listsChangeFinisher();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1860,7 +1843,7 @@ bool FindItemBackward::canBeRun() const
|
|||||||
|
|
||||||
void FindItemForward::run()
|
void FindItemForward::run()
|
||||||
{
|
{
|
||||||
findItem(::Find::Forward);
|
findItem(SearchDirection::Forward);
|
||||||
listsChangeFinisher();
|
listsChangeFinisher();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1872,7 +1855,7 @@ bool FindItemForward::canBeRun() const
|
|||||||
|
|
||||||
void FindItemBackward::run()
|
void FindItemBackward::run()
|
||||||
{
|
{
|
||||||
findItem(::Find::Backward);
|
findItem(SearchDirection::Backward);
|
||||||
listsChangeFinisher();
|
listsChangeFinisher();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1885,7 +1868,7 @@ void NextFoundItem::run()
|
|||||||
{
|
{
|
||||||
Searchable *w = dynamic_cast<Searchable *>(myScreen);
|
Searchable *w = dynamic_cast<Searchable *>(myScreen);
|
||||||
assert(w != nullptr);
|
assert(w != nullptr);
|
||||||
w->findForward(Config.wrapped_search);
|
w->find(SearchDirection::Forward, Config.wrapped_search, true);
|
||||||
listsChangeFinisher();
|
listsChangeFinisher();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1898,7 +1881,7 @@ void PreviousFoundItem::run()
|
|||||||
{
|
{
|
||||||
Searchable *w = dynamic_cast<Searchable *>(myScreen);
|
Searchable *w = dynamic_cast<Searchable *>(myScreen);
|
||||||
assert(w != nullptr);
|
assert(w != nullptr);
|
||||||
w->findBackward(Config.wrapped_search);
|
w->find(SearchDirection::Backward, Config.wrapped_search, true);
|
||||||
listsChangeFinisher();
|
listsChangeFinisher();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2710,7 +2693,7 @@ void seek()
|
|||||||
wFooter->setTimeout(old_timeout);
|
wFooter->setTimeout(old_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void findItem(const Find direction)
|
void findItem(const SearchDirection direction)
|
||||||
{
|
{
|
||||||
using Global::wFooter;
|
using Global::wFooter;
|
||||||
|
|
||||||
@@ -2721,32 +2704,30 @@ void findItem(const Find direction)
|
|||||||
std::string constraint;
|
std::string constraint;
|
||||||
{
|
{
|
||||||
Statusbar::ScopedLock slock;
|
Statusbar::ScopedLock slock;
|
||||||
Statusbar::put() << "Find " << findToString(direction) << ": ";
|
NC::Window::ScopedPromptHook prompt_hook(*wFooter,
|
||||||
|
Statusbar::Helpers::FindImmediately(w, direction)
|
||||||
|
);
|
||||||
|
Statusbar::put() << (boost::format("Find %1%: ") % direction).str();
|
||||||
constraint = wFooter->prompt();
|
constraint = wFooter->prompt();
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool success = w->setSearchConstraint(constraint);
|
if (constraint.empty())
|
||||||
if (success)
|
{
|
||||||
Statusbar::printf("Using constraint \"%1%\"", constraint);
|
|
||||||
else
|
|
||||||
Statusbar::printf("Constraint unset");
|
Statusbar::printf("Constraint unset");
|
||||||
|
w->clearConstraint();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
w->setSearchConstraint(constraint);
|
||||||
|
Statusbar::printf("Using constraint \"%1%\"", constraint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (boost::bad_expression &e)
|
catch (boost::bad_expression &e)
|
||||||
{
|
{
|
||||||
Statusbar::printf("%1%", e.what());
|
Statusbar::printf("%1%", e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (direction)
|
|
||||||
{
|
|
||||||
case Find::Forward:
|
|
||||||
w->findForward(Config.wrapped_search);
|
|
||||||
break;
|
|
||||||
case Find::Backward:
|
|
||||||
w->findBackward(Config.wrapped_search);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void listsChangeFinisher()
|
void listsChangeFinisher()
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
|
|
||||||
namespace Actions {//
|
namespace Actions {
|
||||||
|
|
||||||
enum class Type
|
enum class Type
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -248,31 +248,22 @@ bool Browser::allowsSearching()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Browser::setSearchConstraint(const std::string &constraint)
|
void Browser::setSearchConstraint(const std::string &constraint)
|
||||||
{
|
{
|
||||||
if (constraint.empty())
|
m_search_predicate = RegexFilter<MPD::Item>(
|
||||||
{
|
boost::regex(constraint, Config.regex_type),
|
||||||
m_search_predicate.clear();
|
boost::bind(browserEntryMatcher, _1, _2, false)
|
||||||
return false;
|
);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_search_predicate = RegexFilter<MPD::Item>(
|
|
||||||
boost::regex(constraint, Config.regex_type),
|
|
||||||
boost::bind(browserEntryMatcher, _1, _2, false)
|
|
||||||
);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Browser::findForward(bool wrap)
|
void Browser::clearConstraint()
|
||||||
{
|
{
|
||||||
searchForward(w, m_search_predicate, wrap);
|
m_search_predicate.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Browser::findBackward(bool wrap)
|
bool Browser::find(SearchDirection direction, bool wrap, bool skip_current)
|
||||||
{
|
{
|
||||||
searchBackward(w, m_search_predicate, wrap);
|
return search(w, m_search_predicate, direction, wrap, skip_current);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|||||||
@@ -47,9 +47,9 @@ struct Browser: Screen<NC::Menu<MPD::Item>>, HasSongs, Searchable, Tabbable
|
|||||||
|
|
||||||
// Searchable implementation
|
// Searchable implementation
|
||||||
virtual bool allowsSearching() OVERRIDE;
|
virtual bool allowsSearching() OVERRIDE;
|
||||||
virtual bool setSearchConstraint(const std::string &constraint) OVERRIDE;
|
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
|
||||||
virtual void findForward(bool wrap) OVERRIDE;
|
virtual void clearConstraint() OVERRIDE;
|
||||||
virtual void findBackward(bool wrap) OVERRIDE;
|
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
||||||
|
|
||||||
// HasSongs implementation
|
// HasSongs implementation
|
||||||
virtual ProxySongList proxySongList() OVERRIDE;
|
virtual ProxySongList proxySongList() OVERRIDE;
|
||||||
|
|||||||
@@ -20,6 +20,33 @@
|
|||||||
|
|
||||||
#include "enums.h"
|
#include "enums.h"
|
||||||
|
|
||||||
|
std::ostream &operator<<(std::ostream &os, SearchDirection sd)
|
||||||
|
{
|
||||||
|
switch (sd)
|
||||||
|
{
|
||||||
|
case SearchDirection::Backward:
|
||||||
|
os << "backward";
|
||||||
|
break;
|
||||||
|
case SearchDirection::Forward:
|
||||||
|
os << "forward";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istream &operator>>(std::istream &is, SearchDirection &sd)
|
||||||
|
{
|
||||||
|
std::string ssd;
|
||||||
|
is >> ssd;
|
||||||
|
if (ssd == "backward")
|
||||||
|
sd = SearchDirection::Backward;
|
||||||
|
else if (ssd == "forward")
|
||||||
|
sd = SearchDirection::Forward;
|
||||||
|
else
|
||||||
|
is.setstate(std::ios::failbit);
|
||||||
|
return is;
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream &operator<<(std::ostream &os, SpaceAddMode sam)
|
std::ostream &operator<<(std::ostream &os, SpaceAddMode sam)
|
||||||
{
|
{
|
||||||
switch (sam)
|
switch (sam)
|
||||||
|
|||||||
@@ -24,6 +24,10 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
enum class SearchDirection { Backward, Forward };
|
||||||
|
std::ostream &operator<<(std::ostream &os, SearchDirection sd);
|
||||||
|
std::istream &operator>>(std::istream &is, SearchDirection &sd);
|
||||||
|
|
||||||
enum class SpaceAddMode { AddRemove, AlwaysAdd };
|
enum class SpaceAddMode { AddRemove, AlwaysAdd };
|
||||||
std::ostream &operator<<(std::ostream &os, SpaceAddMode sam);
|
std::ostream &operator<<(std::ostream &os, SpaceAddMode sam);
|
||||||
std::istream &operator>>(std::istream &is, SpaceAddMode &sam);
|
std::istream &operator>>(std::istream &is, SpaceAddMode &sam);
|
||||||
|
|||||||
@@ -31,9 +31,10 @@
|
|||||||
|
|
||||||
template <typename Iterator, typename PredicateT>
|
template <typename Iterator, typename PredicateT>
|
||||||
Iterator wrappedSearch(Iterator begin, Iterator current, Iterator end,
|
Iterator wrappedSearch(Iterator begin, Iterator current, Iterator end,
|
||||||
const PredicateT &pred, bool wrap)
|
const PredicateT &pred, bool wrap, bool skip_current)
|
||||||
{
|
{
|
||||||
++current;
|
if (skip_current)
|
||||||
|
++current;
|
||||||
auto it = std::find_if(current, end, pred);
|
auto it = std::find_if(current, end, pred);
|
||||||
if (it == end && wrap)
|
if (it == end && wrap)
|
||||||
{
|
{
|
||||||
@@ -45,23 +46,40 @@ Iterator wrappedSearch(Iterator begin, Iterator current, Iterator end,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ItemT, typename PredicateT>
|
template <typename ItemT, typename PredicateT>
|
||||||
void searchForward(NC::Menu<ItemT> &m, const PredicateT &pred, bool wrap)
|
bool search(NC::Menu<ItemT> &m, const PredicateT &pred,
|
||||||
|
SearchDirection direction, bool wrap, bool skip_current)
|
||||||
{
|
{
|
||||||
if (!pred.defined())
|
bool result = false;
|
||||||
return;
|
if (pred.defined())
|
||||||
auto it = wrappedSearch(m.begin(), m.current(), m.end(), pred, wrap);
|
{
|
||||||
if (it != m.end())
|
switch (direction)
|
||||||
m.highlight(it-m.begin());
|
{
|
||||||
}
|
case SearchDirection::Backward:
|
||||||
|
{
|
||||||
template <typename ItemT, typename PredicateT>
|
auto it = wrappedSearch(m.rbegin(), m.rcurrent(), m.rend(),
|
||||||
void searchBackward(NC::Menu<ItemT> &m, const PredicateT &pred, bool wrap)
|
pred, wrap, skip_current
|
||||||
{
|
);
|
||||||
if (!pred.defined())
|
if (it != m.rend())
|
||||||
return;
|
{
|
||||||
auto it = wrappedSearch(m.rbegin(), m.rcurrent(), m.rend(), pred, wrap);
|
m.highlight(it.base()-m.begin()-1);
|
||||||
if (it != m.rend())
|
result = true;
|
||||||
m.highlight(it.base()-m.begin()-1);
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SearchDirection::Forward:
|
||||||
|
{
|
||||||
|
auto it = wrappedSearch(m.begin(), m.current(), m.end(),
|
||||||
|
pred, wrap, skip_current
|
||||||
|
);
|
||||||
|
if (it != m.end())
|
||||||
|
{
|
||||||
|
m.highlight(it-m.begin());
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline HasColumns *hasColumns(BaseScreen *screen)
|
inline HasColumns *hasColumns(BaseScreen *screen)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#define NCMPCPP_INTERFACES_H
|
#define NCMPCPP_INTERFACES_H
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "enums.h"
|
||||||
#include "gcc.h"
|
#include "gcc.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "song.h"
|
#include "song.h"
|
||||||
@@ -30,9 +31,9 @@
|
|||||||
struct Searchable
|
struct Searchable
|
||||||
{
|
{
|
||||||
virtual bool allowsSearching() = 0;
|
virtual bool allowsSearching() = 0;
|
||||||
virtual bool setSearchConstraint(const std::string &constraint) = 0;
|
virtual void setSearchConstraint(const std::string &constraint) = 0;
|
||||||
virtual void findForward(bool wrap) = 0;
|
virtual void clearConstraint() = 0;
|
||||||
virtual void findBackward(bool wrap) = 0;
|
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct HasSongs
|
struct HasSongs
|
||||||
|
|||||||
@@ -574,63 +574,51 @@ bool MediaLibrary::allowsSearching()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MediaLibrary::setSearchConstraint(const std::string &constraint)
|
void MediaLibrary::setSearchConstraint(const std::string &constraint)
|
||||||
{
|
{
|
||||||
if (constraint.empty())
|
if (isActiveWindow(Tags))
|
||||||
{
|
{
|
||||||
if (isActiveWindow(Tags))
|
m_tags_search_predicate = RegexFilter<PrimaryTag>(
|
||||||
m_tags_search_predicate.clear();
|
boost::regex(constraint, Config.regex_type),
|
||||||
else if (isActiveWindow(Albums))
|
TagEntryMatcher
|
||||||
m_albums_search_predicate.clear();
|
);
|
||||||
else if (isActiveWindow(Songs))
|
|
||||||
m_songs_search_predicate.clear();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
else
|
else if (isActiveWindow(Albums))
|
||||||
{
|
{
|
||||||
if (isActiveWindow(Tags))
|
m_albums_search_predicate = RegexItemFilter<AlbumEntry>(
|
||||||
{
|
boost::regex(constraint, Config.regex_type),
|
||||||
m_tags_search_predicate = RegexFilter<PrimaryTag>(
|
boost::bind(AlbumEntryMatcher, _1, _2, false)
|
||||||
boost::regex(constraint, Config.regex_type),
|
);
|
||||||
TagEntryMatcher
|
}
|
||||||
);
|
else if (isActiveWindow(Songs))
|
||||||
}
|
{
|
||||||
else if (isActiveWindow(Albums))
|
m_songs_search_predicate = RegexFilter<MPD::Song>(
|
||||||
{
|
boost::regex(constraint, Config.regex_type),
|
||||||
m_albums_search_predicate = RegexItemFilter<AlbumEntry>(
|
SongEntryMatcher
|
||||||
boost::regex(constraint, Config.regex_type),
|
);
|
||||||
boost::bind(AlbumEntryMatcher, _1, _2, false)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (isActiveWindow(Songs))
|
|
||||||
{
|
|
||||||
m_songs_search_predicate = RegexFilter<MPD::Song>(
|
|
||||||
boost::regex(constraint, Config.regex_type),
|
|
||||||
SongEntryMatcher
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaLibrary::findForward(bool wrap)
|
void MediaLibrary::clearConstraint()
|
||||||
{
|
{
|
||||||
if (isActiveWindow(Tags))
|
if (isActiveWindow(Tags))
|
||||||
searchForward(Tags, m_tags_search_predicate, wrap);
|
m_tags_search_predicate.clear();
|
||||||
else if (isActiveWindow(Albums))
|
else if (isActiveWindow(Albums))
|
||||||
searchForward(Albums, m_albums_search_predicate, wrap);
|
m_albums_search_predicate.clear();
|
||||||
else if (isActiveWindow(Songs))
|
else if (isActiveWindow(Songs))
|
||||||
searchForward(Songs, m_songs_search_predicate, wrap);
|
m_songs_search_predicate.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaLibrary::findBackward(bool wrap)
|
bool MediaLibrary::find(SearchDirection direction, bool wrap, bool skip_current)
|
||||||
{
|
{
|
||||||
|
bool result = false;
|
||||||
if (isActiveWindow(Tags))
|
if (isActiveWindow(Tags))
|
||||||
searchBackward(Tags, m_tags_search_predicate, wrap);
|
result = search(Tags, m_tags_search_predicate, direction, wrap, skip_current);
|
||||||
else if (isActiveWindow(Albums))
|
else if (isActiveWindow(Albums))
|
||||||
searchBackward(Albums, m_albums_search_predicate, wrap);
|
result = search(Albums, m_albums_search_predicate, direction, wrap, skip_current);
|
||||||
else if (isActiveWindow(Songs))
|
else if (isActiveWindow(Songs))
|
||||||
searchBackward(Songs, m_songs_search_predicate, wrap);
|
result = search(Songs, m_songs_search_predicate, direction, wrap, skip_current);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|||||||
@@ -50,9 +50,9 @@ struct MediaLibrary: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, Tab
|
|||||||
|
|
||||||
// Searchable implementation
|
// Searchable implementation
|
||||||
virtual bool allowsSearching() OVERRIDE;
|
virtual bool allowsSearching() OVERRIDE;
|
||||||
virtual bool setSearchConstraint(const std::string &constraint) OVERRIDE;
|
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
|
||||||
virtual void findForward(bool wrap) OVERRIDE;
|
virtual void clearConstraint() OVERRIDE;
|
||||||
virtual void findBackward(bool wrap) OVERRIDE;
|
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
||||||
|
|
||||||
// HasSongs implementation
|
// HasSongs implementation
|
||||||
virtual ProxySongList proxySongList() OVERRIDE;
|
virtual ProxySongList proxySongList() OVERRIDE;
|
||||||
|
|||||||
@@ -155,30 +155,21 @@ bool Playlist::allowsSearching()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Playlist::setSearchConstraint(const std::string &constraint)
|
void Playlist::setSearchConstraint(const std::string &constraint)
|
||||||
{
|
{
|
||||||
if (constraint.empty())
|
m_search_predicate = RegexFilter<MPD::Song>(
|
||||||
{
|
boost::regex(constraint, Config.regex_type), playlistEntryMatcher
|
||||||
m_search_predicate.clear();
|
);
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_search_predicate = RegexFilter<MPD::Song>(
|
|
||||||
boost::regex(constraint, Config.regex_type), playlistEntryMatcher
|
|
||||||
);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Playlist::findForward(bool wrap)
|
void Playlist::clearConstraint()
|
||||||
{
|
{
|
||||||
searchForward(w, m_search_predicate, wrap);
|
m_search_predicate.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Playlist::findBackward(bool wrap)
|
bool Playlist::find(SearchDirection direction, bool wrap, bool skip_current)
|
||||||
{
|
{
|
||||||
searchBackward(w, m_search_predicate, wrap);
|
return search(w, m_search_predicate, direction, wrap, skip_current);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|||||||
@@ -50,9 +50,9 @@ struct Playlist: Screen<NC::Menu<MPD::Song>>, HasSongs, Searchable, Tabbable
|
|||||||
|
|
||||||
// Searchable implementation
|
// Searchable implementation
|
||||||
virtual bool allowsSearching();
|
virtual bool allowsSearching();
|
||||||
virtual bool setSearchConstraint(const std::string &constraint) OVERRIDE;
|
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
|
||||||
virtual void findForward(bool wrap) OVERRIDE;
|
virtual void clearConstraint() OVERRIDE;
|
||||||
virtual void findBackward(bool wrap) OVERRIDE;
|
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
||||||
|
|
||||||
// HasSongs implementation
|
// HasSongs implementation
|
||||||
virtual ProxySongList proxySongList() OVERRIDE;
|
virtual ProxySongList proxySongList() OVERRIDE;
|
||||||
|
|||||||
@@ -328,50 +328,40 @@ bool PlaylistEditor::allowsSearching()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PlaylistEditor::setSearchConstraint(const std::string &constraint)
|
void PlaylistEditor::setSearchConstraint(const std::string &constraint)
|
||||||
{
|
{
|
||||||
if (constraint.empty())
|
if (isActiveWindow(Playlists))
|
||||||
{
|
{
|
||||||
if (isActiveWindow(Playlists))
|
m_playlists_search_predicate = RegexFilter<MPD::Playlist>(
|
||||||
m_playlists_search_predicate.clear();
|
boost::regex(constraint, Config.regex_type),
|
||||||
else if (isActiveWindow(Content))
|
PlaylistEntryMatcher
|
||||||
m_content_search_predicate.clear();
|
);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
else
|
else if (isActiveWindow(Content))
|
||||||
{
|
{
|
||||||
if (isActiveWindow(Playlists))
|
m_content_search_predicate = RegexFilter<MPD::Song>(
|
||||||
{
|
boost::regex(constraint, Config.regex_type),
|
||||||
m_playlists_search_predicate = RegexFilter<MPD::Playlist>(
|
SongEntryMatcher
|
||||||
boost::regex(constraint, Config.regex_type),
|
);
|
||||||
PlaylistEntryMatcher
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (isActiveWindow(Content))
|
|
||||||
{
|
|
||||||
m_content_search_predicate = RegexFilter<MPD::Song>(
|
|
||||||
boost::regex(constraint, Config.regex_type),
|
|
||||||
SongEntryMatcher
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaylistEditor::findForward(bool wrap)
|
void PlaylistEditor::clearConstraint()
|
||||||
{
|
{
|
||||||
if (isActiveWindow(Playlists))
|
if (isActiveWindow(Playlists))
|
||||||
searchForward(Playlists, m_playlists_search_predicate, wrap);
|
m_playlists_search_predicate.clear();
|
||||||
else if (isActiveWindow(Content))
|
else if (isActiveWindow(Content))
|
||||||
searchForward(Content, m_content_search_predicate, wrap);
|
m_content_search_predicate.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlaylistEditor::findBackward(bool wrap)
|
bool PlaylistEditor::find(SearchDirection direction, bool wrap, bool skip_current)
|
||||||
{
|
{
|
||||||
|
bool result = false;
|
||||||
if (isActiveWindow(Playlists))
|
if (isActiveWindow(Playlists))
|
||||||
searchBackward(Playlists, m_playlists_search_predicate, wrap);
|
result = search(Playlists, m_playlists_search_predicate, direction, wrap, skip_current);
|
||||||
else if (isActiveWindow(Content))
|
else if (isActiveWindow(Content))
|
||||||
searchBackward(Content, m_content_search_predicate, wrap);
|
result = search(Content, m_content_search_predicate, direction, wrap, skip_current);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|||||||
@@ -50,9 +50,9 @@ struct PlaylistEditor: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, T
|
|||||||
|
|
||||||
// Searchable implementation
|
// Searchable implementation
|
||||||
virtual bool allowsSearching() OVERRIDE;
|
virtual bool allowsSearching() OVERRIDE;
|
||||||
virtual bool setSearchConstraint(const std::string &constraint) OVERRIDE;
|
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
|
||||||
virtual void findForward(bool wrap) OVERRIDE;
|
virtual void clearConstraint() OVERRIDE;
|
||||||
virtual void findBackward(bool wrap) OVERRIDE;
|
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
||||||
|
|
||||||
// HasSongs implementation
|
// HasSongs implementation
|
||||||
virtual ProxySongList proxySongList() OVERRIDE;
|
virtual ProxySongList proxySongList() OVERRIDE;
|
||||||
|
|||||||
@@ -260,31 +260,22 @@ bool SearchEngine::allowsSearching()
|
|||||||
return w.rbegin()->value().isSong();
|
return w.rbegin()->value().isSong();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SearchEngine::setSearchConstraint(const std::string &constraint)
|
void SearchEngine::setSearchConstraint(const std::string &constraint)
|
||||||
{
|
{
|
||||||
if (constraint.empty())
|
m_search_predicate = RegexItemFilter<SEItem>(
|
||||||
{
|
boost::regex(constraint, Config.regex_type),
|
||||||
m_search_predicate.clear();
|
boost::bind(SEItemEntryMatcher, _1, _2, false)
|
||||||
return false;
|
);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_search_predicate = RegexItemFilter<SEItem>(
|
|
||||||
boost::regex(constraint, Config.regex_type),
|
|
||||||
boost::bind(SEItemEntryMatcher, _1, _2, false)
|
|
||||||
);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchEngine::findForward(bool wrap)
|
void SearchEngine::clearConstraint()
|
||||||
{
|
{
|
||||||
searchForward(w, m_search_predicate, wrap);
|
m_search_predicate.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SearchEngine::findBackward(bool wrap)
|
bool SearchEngine::find(SearchDirection direction, bool wrap, bool skip_current)
|
||||||
{
|
{
|
||||||
searchBackward(w, m_search_predicate, wrap);
|
return search(w, m_search_predicate, direction, wrap, skip_current);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|||||||
@@ -95,9 +95,9 @@ struct SearchEngine: Screen<NC::Menu<SEItem>>, HasSongs, Searchable, Tabbable
|
|||||||
|
|
||||||
// Searchable implementation
|
// Searchable implementation
|
||||||
virtual bool allowsSearching() OVERRIDE;
|
virtual bool allowsSearching() OVERRIDE;
|
||||||
virtual bool setSearchConstraint(const std::string &constraint) OVERRIDE;
|
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
|
||||||
virtual void findForward(bool wrap) OVERRIDE;
|
virtual void clearConstraint() OVERRIDE;
|
||||||
virtual void findBackward(bool wrap) OVERRIDE;
|
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
||||||
|
|
||||||
// HasSongs implementation
|
// HasSongs implementation
|
||||||
virtual ProxySongList proxySongList() OVERRIDE;
|
virtual ProxySongList proxySongList() OVERRIDE;
|
||||||
|
|||||||
@@ -220,6 +220,24 @@ bool Statusbar::Helpers::ImmediatelyReturnOneOf::operator()(const char *s) const
|
|||||||
return !isOneOf(s);
|
return !isOneOf(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Statusbar::Helpers::FindImmediately::operator()(const char *s)
|
||||||
|
{
|
||||||
|
using Global::myScreen;
|
||||||
|
Status::trace();
|
||||||
|
try {
|
||||||
|
if (m_w->allowsSearching() && m_s != s)
|
||||||
|
{
|
||||||
|
m_w->setSearchConstraint(s);
|
||||||
|
m_found = m_w->find(m_direction, Config.wrapped_search, false);
|
||||||
|
if (myScreen == myPlaylist)
|
||||||
|
myPlaylist->EnableHighlighting();
|
||||||
|
myScreen->refreshWindow();
|
||||||
|
m_s = s;
|
||||||
|
}
|
||||||
|
} catch (boost::bad_expression &) { }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Statusbar::Helpers::TryExecuteImmediateCommand::operator()(const char *s)
|
bool Statusbar::Helpers::TryExecuteImmediateCommand::operator()(const char *s)
|
||||||
{
|
{
|
||||||
bool continue_ = true;
|
bool continue_ = true;
|
||||||
|
|||||||
@@ -89,6 +89,21 @@ private:
|
|||||||
std::vector<std::string> m_values;
|
std::vector<std::string> m_values;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FindImmediately
|
||||||
|
{
|
||||||
|
FindImmediately(Searchable *w, SearchDirection direction)
|
||||||
|
: m_w(w), m_direction(direction), m_found(true)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
bool operator()(const char *s);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Searchable *m_w;
|
||||||
|
const SearchDirection m_direction;
|
||||||
|
std::string m_s;
|
||||||
|
bool m_found;
|
||||||
|
};
|
||||||
|
|
||||||
struct TryExecuteImmediateCommand
|
struct TryExecuteImmediateCommand
|
||||||
{
|
{
|
||||||
bool operator()(const char *s);
|
bool operator()(const char *s);
|
||||||
|
|||||||
@@ -721,50 +721,40 @@ bool TagEditor::allowsSearching()
|
|||||||
return w == Dirs || w == Tags;
|
return w == Dirs || w == Tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TagEditor::setSearchConstraint(const std::string &constraint)
|
void TagEditor::setSearchConstraint(const std::string &constraint)
|
||||||
{
|
{
|
||||||
if (constraint.empty())
|
if (w == Dirs)
|
||||||
{
|
{
|
||||||
if (w == Dirs)
|
m_directories_search_predicate = RegexFilter<std::pair<std::string, std::string>>(
|
||||||
m_directories_search_predicate.clear();
|
boost::regex(constraint, Config.regex_type),
|
||||||
else if (w == Tags)
|
boost::bind(DirEntryMatcher, _1, _2, false)
|
||||||
m_songs_search_predicate.clear();
|
);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
else
|
else if (w == Tags)
|
||||||
{
|
{
|
||||||
if (w == Dirs)
|
m_songs_search_predicate = RegexFilter<MPD::MutableSong>(
|
||||||
{
|
boost::regex(constraint, Config.regex_type),
|
||||||
m_directories_search_predicate = RegexFilter<std::pair<std::string, std::string>>(
|
SongEntryMatcher
|
||||||
boost::regex(constraint, Config.regex_type),
|
);
|
||||||
boost::bind(DirEntryMatcher, _1, _2, false)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (w == Tags)
|
|
||||||
{
|
|
||||||
m_songs_search_predicate = RegexFilter<MPD::MutableSong>(
|
|
||||||
boost::regex(constraint, Config.regex_type),
|
|
||||||
SongEntryMatcher
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TagEditor::findForward(bool wrap)
|
void TagEditor::clearConstraint()
|
||||||
{
|
{
|
||||||
if (w == Dirs)
|
if (w == Dirs)
|
||||||
searchForward(*Dirs, m_directories_search_predicate, wrap);
|
m_directories_search_predicate.clear();
|
||||||
else if (w == Tags)
|
else if (w == Tags)
|
||||||
searchForward(*Tags, m_songs_search_predicate, wrap);
|
m_songs_search_predicate.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TagEditor::findBackward(bool wrap)
|
bool TagEditor::find(SearchDirection direction, bool wrap, bool skip_current)
|
||||||
{
|
{
|
||||||
|
bool result = false;
|
||||||
if (w == Dirs)
|
if (w == Dirs)
|
||||||
searchBackward(*Dirs, m_directories_search_predicate, wrap);
|
result = search(*Dirs, m_directories_search_predicate, direction, wrap, skip_current);
|
||||||
else if (w == Tags)
|
else if (w == Tags)
|
||||||
searchBackward(*Tags, m_songs_search_predicate, wrap);
|
result = search(*Tags, m_songs_search_predicate, direction, wrap, skip_current);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|||||||
@@ -53,9 +53,9 @@ struct TagEditor: Screen<NC::Window *>, HasColumns, HasSongs, Searchable, Tabbab
|
|||||||
|
|
||||||
// Searchable implementation
|
// Searchable implementation
|
||||||
virtual bool allowsSearching() OVERRIDE;
|
virtual bool allowsSearching() OVERRIDE;
|
||||||
virtual bool setSearchConstraint(const std::string &constraint) OVERRIDE;
|
virtual void setSearchConstraint(const std::string &constraint) OVERRIDE;
|
||||||
virtual void findForward(bool wrap) OVERRIDE;
|
virtual void clearConstraint() OVERRIDE;
|
||||||
virtual void findBackward(bool wrap) OVERRIDE;
|
virtual bool find(SearchDirection direction, bool wrap, bool skip_current) OVERRIDE;
|
||||||
|
|
||||||
// HasSongs implementation
|
// HasSongs implementation
|
||||||
virtual ProxySongList proxySongList() OVERRIDE;
|
virtual ProxySongList proxySongList() OVERRIDE;
|
||||||
|
|||||||
Reference in New Issue
Block a user