add support for built-in mpd searching in search engine

This commit is contained in:
Andrzej Rybczak
2010-01-22 21:35:34 +01:00
parent 45acbfe862
commit 153081158d
8 changed files with 95 additions and 15 deletions

View File

@@ -307,8 +307,22 @@
#enable_window_title = "yes" #enable_window_title = "yes"
# #
## ##
## Note: You can choose default search mode for search
## engine. Available modes are:
##
## - 1 - use mpd built-in searching (no regexes, pattern matching)
## - 2 - use ncmpcpp searching (pattern matching with support for regexes,
## but if your mpd is on a remote machine, downloading big database
## to process it can take a while
## - 3 - match only exact values (this mode uses mpd function for searching
## in database and local one for searching in current playlist)
##
#
#search_engine_default_search_mode = "1"
#
##
## Note: These triggers will allow you to phisically remove ## Note: These triggers will allow you to phisically remove
## files and directories from your hdd in using ncmpcpp's ## files and directories from your hdd using ncmpcpp's
## browser screen. ## browser screen.
## ##
# #

View File

@@ -162,6 +162,9 @@ If enabled, mouse wheel will scroll the whole page of item list at a time, other
.B lines_scrolled = NUMBER .B lines_scrolled = NUMBER
Number of lines that are scrolled with mouse wheel. Number of lines that are scrolled with mouse wheel.
.TP .TP
.B search_engine_default_search_mode = MODE_NUMBER
Number of default mode used in search engine.
.TP
.B playlist_show_remaining_time = yes/no .B playlist_show_remaining_time = yes/no
If enabled, time remaining to end of playlist will be shown after playlist's statistics. If enabled, time remaining to end of playlist will be shown after playlist's statistics.
.TP .TP

View File

@@ -1042,7 +1042,7 @@ void MPD::Connection::StartFieldSearch(mpd_tag_type item)
} }
} }
void MPD::Connection::AddSearch(mpd_tag_type item, const std::string &str) void MPD::Connection::AddSearch(mpd_tag_type item, const std::string &str) const
{ {
// mpd version < 0.14.* doesn't support empty search constraints // mpd version < 0.14.* doesn't support empty search constraints
if (Version() < 14 && str.empty()) if (Version() < 14 && str.empty())
@@ -1051,6 +1051,20 @@ void MPD::Connection::AddSearch(mpd_tag_type item, const std::string &str)
mpd_search_add_tag_constraint(itsConnection, MPD_OPERATOR_DEFAULT, item, str.c_str()); mpd_search_add_tag_constraint(itsConnection, MPD_OPERATOR_DEFAULT, item, str.c_str());
} }
void MPD::Connection::AddSearchAny(const std::string &str) const
{
assert(!str.empty());
if (itsConnection)
mpd_search_add_any_tag_constraint(itsConnection, MPD_OPERATOR_DEFAULT, str.c_str());
}
void MPD::Connection::AddSearchURI(const std::string &str) const
{
assert(!str.empty());
if (itsConnection)
mpd_search_add_uri_constraint(itsConnection, MPD_OPERATOR_DEFAULT, str.c_str());
}
void MPD::Connection::CommitSearch(SongList &v) void MPD::Connection::CommitSearch(SongList &v)
{ {
if (!itsConnection) if (!itsConnection)

View File

@@ -191,7 +191,9 @@ namespace MPD
void StartSearch(bool); void StartSearch(bool);
void StartFieldSearch(mpd_tag_type); void StartFieldSearch(mpd_tag_type);
void AddSearch(mpd_tag_type, const std::string &); void AddSearch(mpd_tag_type, const std::string &) const;
void AddSearchAny(const std::string &str) const;
void AddSearchURI(const std::string &str) const;
void CommitSearch(SongList &); void CommitSearch(SongList &);
void CommitSearch(TagList &); void CommitSearch(TagList &);

View File

@@ -47,15 +47,18 @@ const char *SearchEngine::ConstraintsNames[] =
"Comment:" "Comment:"
}; };
const char *SearchEngine::NormalMode = "Match if tag contains searched phrase (regexes supported)"; const char *SearchEngine::SearchModes[] =
const char *SearchEngine::StrictMode = "Match only if both values are the same"; {
"Match if tag contains searched phrase (no regexes)",
"Match if tag contains searched phrase (regexes supported)",
"Match only if both values are the same",
0
};
size_t SearchEngine::StaticOptions = 19; size_t SearchEngine::StaticOptions = 19;
size_t SearchEngine::ResetButton = 15; size_t SearchEngine::ResetButton = 15;
size_t SearchEngine::SearchButton = 14; size_t SearchEngine::SearchButton = 14;
bool SearchEngine::MatchToPattern = 1;
void SearchEngine::Init() void SearchEngine::Init()
{ {
w = new Menu< std::pair<Buffer *, MPD::Song *> >(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone); w = new Menu< std::pair<Buffer *, MPD::Song *> >(0, MainStartY, COLS, MainHeight, "", Config.main_color, brNone);
@@ -65,6 +68,7 @@ void SearchEngine::Init()
w->SetSelectPrefix(&Config.selected_item_prefix); w->SetSelectPrefix(&Config.selected_item_prefix);
w->SetSelectSuffix(&Config.selected_item_suffix); w->SetSelectSuffix(&Config.selected_item_suffix);
w->SetGetStringFunction(SearchEngineOptionToString); w->SetGetStringFunction(SearchEngineOptionToString);
SearchMode = &SearchModes[Config.search_engine_default_search_mode];
isInitialized = 1; isInitialized = 1;
} }
@@ -131,8 +135,9 @@ void SearchEngine::EnterPressed()
} }
else if (option == ConstraintsNumber+2) else if (option == ConstraintsNumber+2)
{ {
MatchToPattern = !MatchToPattern; if (!*++SearchMode)
*w->Current().first << fmtBold << "Search mode:" << fmtBoldEnd << ' ' << (MatchToPattern ? NormalMode : StrictMode); SearchMode = &SearchModes[0];
*w->Current().first << fmtBold << "Search mode:" << fmtBoldEnd << ' ' << *SearchMode;
} }
else if (option == SearchButton) else if (option == SearchButton)
{ {
@@ -290,7 +295,7 @@ void SearchEngine::Prepare()
} }
*w->at(ConstraintsNumber+1).first << fmtBold << "Search in:" << fmtBoldEnd << ' ' << (Config.search_in_db ? "Database" : "Current playlist"); *w->at(ConstraintsNumber+1).first << fmtBold << "Search in:" << fmtBoldEnd << ' ' << (Config.search_in_db ? "Database" : "Current playlist");
*w->at(ConstraintsNumber+2).first << fmtBold << "Search mode:" << fmtBoldEnd << ' ' << (MatchToPattern ? NormalMode : StrictMode); *w->at(ConstraintsNumber+2).first << fmtBold << "Search mode:" << fmtBoldEnd << ' ' << *SearchMode;
*w->at(SearchButton).first << "Search"; *w->at(SearchButton).first << "Search";
*w->at(ResetButton).first << "Reset"; *w->at(ResetButton).first << "Reset";
@@ -310,6 +315,36 @@ void SearchEngine::Search()
if (constraints_empty) if (constraints_empty)
return; return;
if (Config.search_in_db && (SearchMode == &SearchModes[0] || SearchMode == &SearchModes[2])) // use built-in mpd searching
{
Mpd.StartSearch(SearchMode == &SearchModes[2]);
if (!itsConstraints[0].empty())
Mpd.AddSearchAny(itsConstraints[0]);
if (!itsConstraints[1].empty())
Mpd.AddSearch(MPD_TAG_ARTIST, itsConstraints[1]);
if (!itsConstraints[2].empty())
Mpd.AddSearch(MPD_TAG_TITLE, itsConstraints[2]);
if (!itsConstraints[3].empty())
Mpd.AddSearch(MPD_TAG_ALBUM, itsConstraints[3]);
if (!itsConstraints[4].empty())
Mpd.AddSearchURI(itsConstraints[4]);
if (!itsConstraints[5].empty())
Mpd.AddSearch(MPD_TAG_COMPOSER, itsConstraints[5]);
if (!itsConstraints[6].empty())
Mpd.AddSearch(MPD_TAG_PERFORMER, itsConstraints[6]);
if (!itsConstraints[7].empty())
Mpd.AddSearch(MPD_TAG_GENRE, itsConstraints[7]);
if (!itsConstraints[8].empty())
Mpd.AddSearch(MPD_TAG_DATE, itsConstraints[8]);
if (!itsConstraints[9].empty())
Mpd.AddSearch(MPD_TAG_COMMENT, itsConstraints[9]);
MPD::SongList results;
Mpd.CommitSearch(results);
for (MPD::SongList::const_iterator it = results.begin(); it != results.end(); ++it)
w->AddOption(std::make_pair(static_cast<Buffer *>(0), *it));
return;
}
MPD::SongList list; MPD::SongList list;
if (Config.search_in_db) if (Config.search_in_db)
Mpd.GetDirectoryRecursive("/", list); Mpd.GetDirectoryRecursive("/", list);
@@ -325,7 +360,7 @@ void SearchEngine::Search()
for (MPD::SongList::const_iterator it = list.begin(); it != list.end(); ++it) for (MPD::SongList::const_iterator it = list.begin(); it != list.end(); ++it)
{ {
if (MatchToPattern) if (SearchMode != &SearchModes[2]) // match to pattern
{ {
regex_t rx; regex_t rx;
if (!itsConstraints[0].empty()) if (!itsConstraints[0].empty())
@@ -401,7 +436,7 @@ void SearchEngine::Search()
regfree(&rx); regfree(&rx);
} }
} }
else else // match only if values are equal
{ {
CaseInsensitiveStringComparison cmp; CaseInsensitiveStringComparison cmp;

View File

@@ -53,9 +53,6 @@ class SearchEngine : public Screen< Menu< std::pair<Buffer *, MPD::Song *> > >
static size_t SearchButton; static size_t SearchButton;
static size_t ResetButton; static size_t ResetButton;
static const char *NormalMode;
static const char *StrictMode;
protected: protected:
virtual void Init(); virtual void Init();
@@ -63,8 +60,12 @@ class SearchEngine : public Screen< Menu< std::pair<Buffer *, MPD::Song *> > >
void Prepare(); void Prepare();
void Search(); void Search();
const char **SearchMode;
static std::string SearchEngineOptionToString(const std::pair<Buffer *, MPD::Song *> &, void *); static std::string SearchEngineOptionToString(const std::pair<Buffer *, MPD::Song *> &, void *);
static const char *SearchModes[];
static const size_t ConstraintsNumber = 10; static const size_t ConstraintsNumber = 10;
static const char *ConstraintsNames[]; static const char *ConstraintsNames[];
std::string itsConstraints[ConstraintsNumber]; std::string itsConstraints[ConstraintsNumber];

View File

@@ -336,6 +336,7 @@ void DefaultConfiguration(ncmpcpp_config &conf)
conf.lyrics_db = 0; conf.lyrics_db = 0;
conf.regex_type = 0; conf.regex_type = 0;
conf.lines_scrolled = 2; conf.lines_scrolled = 2;
conf.search_engine_default_search_mode = 0;
conf.selected_item_suffix_length = 0; conf.selected_item_suffix_length = 0;
# ifdef HAVE_LANGINFO_H # ifdef HAVE_LANGINFO_H
conf.system_encoding = nl_langinfo(CODESET); conf.system_encoding = nl_langinfo(CODESET);
@@ -902,6 +903,15 @@ void ReadConfiguration(ncmpcpp_config &conf)
if (!v.empty()) if (!v.empty())
conf.lines_scrolled = StrToInt(v); conf.lines_scrolled = StrToInt(v);
} }
else if (cl.find("search_engine_default_search_mode") != std::string::npos)
{
if (!v.empty())
{
unsigned mode = StrToInt(v);
if (--mode < 3)
conf.search_engine_default_search_mode = mode;
}
}
else if (cl.find("song_window_title_format") != std::string::npos) else if (cl.find("song_window_title_format") != std::string::npos)
{ {
if (!v.empty()) if (!v.empty())

View File

@@ -229,6 +229,7 @@ struct ncmpcpp_config
int regex_type; int regex_type;
unsigned lines_scrolled; unsigned lines_scrolled;
unsigned search_engine_default_search_mode;
size_t selected_item_suffix_length; size_t selected_item_suffix_length;
}; };