add support for built-in mpd searching in search engine
This commit is contained in:
16
doc/config
16
doc/config
@@ -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.
|
||||||
##
|
##
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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 &);
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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())
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user