add support for regular expressions (basic and extended)
it intruduces regex support in search engine and filtering/searching in all screens
This commit is contained in:
@@ -144,6 +144,8 @@
|
|||||||
#
|
#
|
||||||
#clock_display_seconds = "no"
|
#clock_display_seconds = "no"
|
||||||
#
|
#
|
||||||
|
#regular_expressions = "basic" (basic/extended)
|
||||||
|
#
|
||||||
##
|
##
|
||||||
## Note: If below is enabled, ncmpcpp will ignore leading
|
## Note: If below is enabled, ncmpcpp will ignore leading
|
||||||
## "The" word while sorting items in browser, tags in
|
## "The" word while sorting items in browser, tags in
|
||||||
|
|||||||
@@ -279,6 +279,11 @@ void Browser::GetSelectedSongs(MPD::SongList &v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Browser::ApplyFilter(const std::string &s)
|
||||||
|
{
|
||||||
|
w->ApplyFilter(s, itsBrowsedDir == "/" ? 0 : 1, REG_ICASE | Config.regex_type);
|
||||||
|
}
|
||||||
|
|
||||||
bool Browser::hasSupportedExtension(const string &file)
|
bool Browser::hasSupportedExtension(const string &file)
|
||||||
{
|
{
|
||||||
size_t last_dot = file.rfind(".");
|
size_t last_dot = file.rfind(".");
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class Browser : public Screen< Menu<MPD::Item> >
|
|||||||
virtual void ReverseSelection();
|
virtual void ReverseSelection();
|
||||||
virtual void GetSelectedSongs(MPD::SongList &);
|
virtual void GetSelectedSongs(MPD::SongList &);
|
||||||
|
|
||||||
virtual void ApplyFilter(const std::string &s) { w->ApplyFilter(s, itsBrowsedDir == "/" ? 0 : 1); }
|
virtual void ApplyFilter(const std::string &);
|
||||||
|
|
||||||
virtual List *GetList() { return w; }
|
virtual List *GetList() { return w; }
|
||||||
|
|
||||||
|
|||||||
@@ -280,6 +280,11 @@ void MediaLibrary::GetSelectedSongs(MPD::SongList &v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MediaLibrary::ApplyFilter(const std::string &s)
|
||||||
|
{
|
||||||
|
GetList()->ApplyFilter(s, 0, REG_ICASE | Config.regex_type);
|
||||||
|
}
|
||||||
|
|
||||||
void MediaLibrary::NextColumn()
|
void MediaLibrary::NextColumn()
|
||||||
{
|
{
|
||||||
if (w == Artists)
|
if (w == Artists)
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class MediaLibrary : public Screen<Window>
|
|||||||
virtual void ReverseSelection() { Songs->ReverseSelection(); }
|
virtual void ReverseSelection() { Songs->ReverseSelection(); }
|
||||||
virtual void GetSelectedSongs(MPD::SongList &);
|
virtual void GetSelectedSongs(MPD::SongList &);
|
||||||
|
|
||||||
virtual void ApplyFilter(const std::string &s) { GetList()->ApplyFilter(s); }
|
virtual void ApplyFilter(const std::string &);
|
||||||
|
|
||||||
virtual List *GetList();
|
virtual List *GetList();
|
||||||
|
|
||||||
|
|||||||
47
src/menu.h
47
src/menu.h
@@ -21,6 +21,7 @@
|
|||||||
#ifndef _MENU_H
|
#ifndef _MENU_H
|
||||||
#define _MENU_H
|
#define _MENU_H
|
||||||
|
|
||||||
|
#include <regex.h>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include "window.h"
|
#include "window.h"
|
||||||
@@ -54,12 +55,12 @@ namespace NCurses
|
|||||||
void ReverseSelection(size_t = 0);
|
void ReverseSelection(size_t = 0);
|
||||||
bool Deselect();
|
bool Deselect();
|
||||||
|
|
||||||
virtual bool Search(const std::string &, size_t = 0, bool = 0) = 0;
|
virtual bool Search(const std::string &, size_t = 0, int = 0) = 0;
|
||||||
virtual const std::string &GetSearchConstraint() = 0;
|
virtual const std::string &GetSearchConstraint() = 0;
|
||||||
virtual void NextFound(bool) = 0;
|
virtual void NextFound(bool) = 0;
|
||||||
virtual void PrevFound(bool) = 0;
|
virtual void PrevFound(bool) = 0;
|
||||||
|
|
||||||
virtual void ApplyFilter(const std::string &, size_t = 0, bool = 0) = 0;
|
virtual void ApplyFilter(const std::string &, size_t = 0, int = 0) = 0;
|
||||||
virtual const std::string &GetFilter() = 0;
|
virtual const std::string &GetFilter() = 0;
|
||||||
virtual std::string GetOption(size_t) = 0;
|
virtual std::string GetOption(size_t) = 0;
|
||||||
|
|
||||||
@@ -132,12 +133,12 @@ namespace NCurses
|
|||||||
virtual size_t Choice() const;
|
virtual size_t Choice() const;
|
||||||
virtual size_t RealChoice() const;
|
virtual size_t RealChoice() const;
|
||||||
|
|
||||||
virtual bool Search(const std::string &constraint, size_t beginning = 0, bool case_sensitive = 0);
|
virtual bool Search(const std::string &constraint, size_t beginning = 0, int flags = 0);
|
||||||
virtual const std::string &GetSearchConstraint() { return itsSearchConstraint; }
|
virtual const std::string &GetSearchConstraint() { return itsSearchConstraint; }
|
||||||
virtual void NextFound(bool wrap);
|
virtual void NextFound(bool wrap);
|
||||||
virtual void PrevFound(bool wrap);
|
virtual void PrevFound(bool wrap);
|
||||||
|
|
||||||
virtual void ApplyFilter(const std::string &filter, size_t beginning = 0, bool case_sensitive = 0);
|
virtual void ApplyFilter(const std::string &filter, size_t beginning = 0, int flags = 0);
|
||||||
virtual const std::string &GetFilter();
|
virtual const std::string &GetFilter();
|
||||||
virtual std::string GetOption(size_t pos);
|
virtual std::string GetOption(size_t pos);
|
||||||
|
|
||||||
@@ -596,22 +597,23 @@ template <class T> size_t NCurses::Menu<T>::RealChoice() const
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> bool NCurses::Menu<T>::Search(const std::string &constraint, size_t beginning, bool case_sensitive)
|
template <class T> bool NCurses::Menu<T>::Search(const std::string &constraint, size_t beginning, int flags)
|
||||||
{
|
{
|
||||||
itsFound.clear();
|
itsFound.clear();
|
||||||
itsSearchConstraint.clear();
|
itsSearchConstraint.clear();
|
||||||
if (constraint.empty())
|
if (constraint.empty())
|
||||||
return false;
|
return false;
|
||||||
itsSearchConstraint = constraint;
|
itsSearchConstraint = constraint;
|
||||||
std::string option;
|
regex_t rx;
|
||||||
for (size_t i = beginning; i < itsOptionsPtr->size(); i++)
|
if (regcomp(&rx, itsSearchConstraint.c_str(), flags) == 0)
|
||||||
{
|
{
|
||||||
option = GetOption(i);
|
for (size_t i = beginning; i < itsOptionsPtr->size(); i++)
|
||||||
if (!case_sensitive)
|
{
|
||||||
ToLower(option);
|
if (regexec(&rx, GetOption(i).c_str(), 0, 0, 0) == 0)
|
||||||
if (option.find(itsSearchConstraint) != std::string::npos)
|
itsFound.insert(i);
|
||||||
itsFound.insert(i);
|
}
|
||||||
}
|
}
|
||||||
|
regfree(&rx);
|
||||||
return !itsFound.empty();
|
return !itsFound.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,15 +639,13 @@ template <class T> void NCurses::Menu<T>::PrevFound(bool wrap)
|
|||||||
Highlight(*itsFound.rbegin());
|
Highlight(*itsFound.rbegin());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> void NCurses::Menu<T>::ApplyFilter(const std::string &filter, size_t beginning, bool case_sensitive)
|
template <class T> void NCurses::Menu<T>::ApplyFilter(const std::string &filter, size_t beginning, int flags)
|
||||||
{
|
{
|
||||||
if (filter == itsFilter)
|
if (filter == itsFilter)
|
||||||
return;
|
return;
|
||||||
itsFound.clear();
|
itsFound.clear();
|
||||||
ClearFiltered();
|
ClearFiltered();
|
||||||
itsFilter = filter;
|
itsFilter = filter;
|
||||||
if (!case_sensitive)
|
|
||||||
ToLower(itsFilter);
|
|
||||||
if (itsFilter.empty())
|
if (itsFilter.empty())
|
||||||
return;
|
return;
|
||||||
for (size_t i = 0; i < beginning; i++)
|
for (size_t i = 0; i < beginning; i++)
|
||||||
@@ -653,18 +653,19 @@ template <class T> void NCurses::Menu<T>::ApplyFilter(const std::string &filter,
|
|||||||
itsFilteredRealPositions.push_back(i);
|
itsFilteredRealPositions.push_back(i);
|
||||||
itsFilteredOptions.push_back(itsOptions[i]);
|
itsFilteredOptions.push_back(itsOptions[i]);
|
||||||
}
|
}
|
||||||
std::string option;
|
regex_t rx;
|
||||||
for (size_t i = beginning; i < itsOptions.size(); i++)
|
if (regcomp(&rx, itsFilter.c_str(), flags) == 0)
|
||||||
{
|
{
|
||||||
option = GetOption(i);
|
for (size_t i = beginning; i < itsOptions.size(); i++)
|
||||||
if (!case_sensitive)
|
|
||||||
ToLower(option);
|
|
||||||
if (option.find(itsFilter) != std::string::npos)
|
|
||||||
{
|
{
|
||||||
itsFilteredRealPositions.push_back(i);
|
if (regexec(&rx, GetOption(i).c_str(), 0, 0, 0) == 0)
|
||||||
itsFilteredOptions.push_back(itsOptions[i]);
|
{
|
||||||
|
itsFilteredRealPositions.push_back(i);
|
||||||
|
itsFilteredOptions.push_back(itsOptions[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
regfree(&rx);
|
||||||
itsOptionsPtr = &itsFilteredOptions;
|
itsOptionsPtr = &itsFilteredOptions;
|
||||||
if (itsOptionsPtr->empty()) // oops, we didn't find anything
|
if (itsOptionsPtr->empty()) // oops, we didn't find anything
|
||||||
Window::Clear();
|
Window::Clear();
|
||||||
|
|||||||
@@ -1493,7 +1493,7 @@ int main(int argc, char *argv[])
|
|||||||
if (!findme.empty())
|
if (!findme.empty())
|
||||||
ShowMessage("Searching...");
|
ShowMessage("Searching...");
|
||||||
|
|
||||||
bool success = mList->Search(findme, myScreen == mySearcher ? SearchEngine::StaticOptions : 0);
|
bool success = mList->Search(findme, myScreen == mySearcher ? SearchEngine::StaticOptions : 0, REG_ICASE | Config.regex_type);
|
||||||
|
|
||||||
if (findme.empty())
|
if (findme.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -138,6 +138,11 @@ void Playlist::GetSelectedSongs(MPD::SongList &v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Playlist::ApplyFilter(const std::string &s)
|
||||||
|
{
|
||||||
|
w->ApplyFilter(s, 0, REG_ICASE | Config.regex_type);
|
||||||
|
}
|
||||||
|
|
||||||
void Playlist::Sort()
|
void Playlist::Sort()
|
||||||
{
|
{
|
||||||
if (w->GetWidth() < SortDialogWidth || w->GetHeight() < SortDialogHeight)
|
if (w->GetWidth() < SortDialogWidth || w->GetHeight() < SortDialogHeight)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class Playlist : public Screen< Menu<MPD::Song> >
|
|||||||
virtual void ReverseSelection() { w->ReverseSelection(); }
|
virtual void ReverseSelection() { w->ReverseSelection(); }
|
||||||
virtual void GetSelectedSongs(MPD::SongList &);
|
virtual void GetSelectedSongs(MPD::SongList &);
|
||||||
|
|
||||||
virtual void ApplyFilter(const std::string &s) { w->ApplyFilter(s); }
|
virtual void ApplyFilter(const std::string &);
|
||||||
|
|
||||||
virtual List *GetList() { return w; }
|
virtual List *GetList() { return w; }
|
||||||
|
|
||||||
|
|||||||
@@ -287,6 +287,11 @@ void PlaylistEditor::GetSelectedSongs(MPD::SongList &v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlaylistEditor::ApplyFilter(const std::string &s)
|
||||||
|
{
|
||||||
|
GetList()->ApplyFilter(s, 0, REG_ICASE | Config.regex_type);
|
||||||
|
}
|
||||||
|
|
||||||
List *PlaylistEditor::GetList()
|
List *PlaylistEditor::GetList()
|
||||||
{
|
{
|
||||||
if (w == Playlists)
|
if (w == Playlists)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class PlaylistEditor : public Screen<Window>
|
|||||||
virtual void ReverseSelection() { Content->ReverseSelection(); }
|
virtual void ReverseSelection() { Content->ReverseSelection(); }
|
||||||
virtual void GetSelectedSongs(MPD::SongList &);
|
virtual void GetSelectedSongs(MPD::SongList &);
|
||||||
|
|
||||||
virtual void ApplyFilter(const std::string &s) { GetList()->ApplyFilter(s); }
|
virtual void ApplyFilter(const std::string &);
|
||||||
|
|
||||||
virtual List *GetList();
|
virtual List *GetList();
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ using std::string;
|
|||||||
|
|
||||||
SearchEngine *mySearcher = new SearchEngine;
|
SearchEngine *mySearcher = new SearchEngine;
|
||||||
|
|
||||||
const char *SearchEngine::NormalMode = "Match if tag contains searched phrase";
|
const char *SearchEngine::NormalMode = "Match if tag contains searched phrase (regexes supported)";
|
||||||
const char *SearchEngine::StrictMode = "Match only if both values are the same";
|
const char *SearchEngine::StrictMode = "Match only if both values are the same";
|
||||||
|
|
||||||
size_t SearchEngine::StaticOptions = 20;
|
size_t SearchEngine::StaticOptions = 20;
|
||||||
@@ -307,6 +307,11 @@ void SearchEngine::GetSelectedSongs(MPD::SongList &v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SearchEngine::ApplyFilter(const std::string &s)
|
||||||
|
{
|
||||||
|
w->ApplyFilter(s, StaticOptions, REG_ICASE | Config.regex_type);
|
||||||
|
}
|
||||||
|
|
||||||
void SearchEngine::UpdateFoundList()
|
void SearchEngine::UpdateFoundList()
|
||||||
{
|
{
|
||||||
bool bold = 0;
|
bool bold = 0;
|
||||||
@@ -392,7 +397,7 @@ void SearchEngine::Search()
|
|||||||
bool any_found = 1;
|
bool any_found = 1;
|
||||||
bool found = 1;
|
bool found = 1;
|
||||||
|
|
||||||
if (!CaseSensitive)
|
if (!CaseSensitive && !MatchToPattern)
|
||||||
{
|
{
|
||||||
string t;
|
string t;
|
||||||
t = s.Any();
|
t = s.Any();
|
||||||
@@ -434,9 +439,10 @@ void SearchEngine::Search()
|
|||||||
|
|
||||||
for (SongList::const_iterator it = list.begin(); it != list.end(); it++)
|
for (SongList::const_iterator it = list.begin(); it != list.end(); it++)
|
||||||
{
|
{
|
||||||
|
(*it)->CopyPtr(CaseSensitive || MatchToPattern);
|
||||||
Song copy = **it;
|
Song copy = **it;
|
||||||
|
|
||||||
if (!CaseSensitive)
|
if (!CaseSensitive && !MatchToPattern)
|
||||||
{
|
{
|
||||||
string t;
|
string t;
|
||||||
t = copy.GetArtist();
|
t = copy.GetArtist();
|
||||||
@@ -471,41 +477,83 @@ void SearchEngine::Search()
|
|||||||
ToLower(t);
|
ToLower(t);
|
||||||
copy.SetComment(t);
|
copy.SetComment(t);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
copy.SetFile(copy.GetName());
|
|
||||||
|
|
||||||
if (MatchToPattern)
|
if (MatchToPattern)
|
||||||
{
|
{
|
||||||
|
regex_t rx;
|
||||||
|
|
||||||
if (!s.Any().empty())
|
if (!s.Any().empty())
|
||||||
any_found =
|
{
|
||||||
copy.GetArtist().find(s.Any()) != string::npos
|
if (regcomp(&rx, s.Any().c_str(), ((CaseSensitive ? 0 : REG_ICASE) | Config.regex_type) | Config.regex_type) == 0)
|
||||||
|| copy.GetTitle().find(s.Any()) != string::npos
|
{
|
||||||
|| copy.GetAlbum().find(s.Any()) != string::npos
|
any_found =
|
||||||
|| copy.GetFile().find(s.Any()) != string::npos
|
regexec(&rx, copy.GetArtist().c_str(), 0, 0, 0) == 0
|
||||||
|| copy.GetComposer().find(s.Any()) != string::npos
|
|| regexec(&rx, copy.GetTitle().c_str(), 0, 0, 0) == 0
|
||||||
|| copy.GetPerformer().find(s.Any()) != string::npos
|
|| regexec(&rx, copy.GetAlbum().c_str(), 0, 0, 0) == 0
|
||||||
|| copy.GetGenre().find(s.Any()) != string::npos
|
|| regexec(&rx, copy.GetName().c_str(), 0, 0, 0) == 0
|
||||||
|| copy.GetYear().find(s.Any()) != string::npos
|
|| regexec(&rx, copy.GetComposer().c_str(), 0, 0, 0) == 0
|
||||||
|| copy.GetComment().find(s.Any()) != string::npos;
|
|| regexec(&rx, copy.GetPerformer().c_str(), 0, 0, 0) == 0
|
||||||
|
|| regexec(&rx, copy.GetGenre().c_str(), 0, 0, 0) == 0
|
||||||
|
|| regexec(&rx, copy.GetYear().c_str(), 0, 0, 0) == 0
|
||||||
|
|| regexec(&rx, copy.GetComment().c_str(), 0, 0, 0) == 0;
|
||||||
|
}
|
||||||
|
regfree(&rx);
|
||||||
|
}
|
||||||
|
|
||||||
if (found && !s.GetArtist().empty())
|
if (found && !s.GetArtist().empty())
|
||||||
found = copy.GetArtist().find(s.GetArtist()) != string::npos;
|
{
|
||||||
|
if (regcomp(&rx, s.GetArtist().c_str(), (CaseSensitive ? 0 : REG_ICASE) | Config.regex_type) == 0)
|
||||||
|
found = regexec(&rx, copy.GetArtist().c_str(), 0, 0, 0) == 0;
|
||||||
|
regfree(&rx);
|
||||||
|
}
|
||||||
if (found && !s.GetTitle().empty())
|
if (found && !s.GetTitle().empty())
|
||||||
found = copy.GetTitle().find(s.GetTitle()) != string::npos;
|
{
|
||||||
|
if (regcomp(&rx, s.GetTitle().c_str(), (CaseSensitive ? 0 : REG_ICASE) | Config.regex_type) == 0)
|
||||||
|
found = regexec(&rx, copy.GetTitle().c_str(), 0, 0, 0) == 0;
|
||||||
|
regfree(&rx);
|
||||||
|
}
|
||||||
if (found && !s.GetAlbum().empty())
|
if (found && !s.GetAlbum().empty())
|
||||||
found = copy.GetAlbum().find(s.GetAlbum()) != string::npos;
|
{
|
||||||
|
if (regcomp(&rx, s.GetAlbum().c_str(), (CaseSensitive ? 0 : REG_ICASE) | Config.regex_type) == 0)
|
||||||
|
found = regexec(&rx, copy.GetAlbum().c_str(), 0, 0, 0) == 0;
|
||||||
|
regfree(&rx);
|
||||||
|
}
|
||||||
if (found && !s.GetFile().empty())
|
if (found && !s.GetFile().empty())
|
||||||
found = copy.GetFile().find(s.GetFile()) != string::npos;
|
{
|
||||||
|
if (regcomp(&rx, s.GetFile().c_str(), (CaseSensitive ? 0 : REG_ICASE) | Config.regex_type) == 0)
|
||||||
|
found = regexec(&rx, copy.GetName().c_str(), 0, 0, 0) == 0;
|
||||||
|
regfree(&rx);
|
||||||
|
}
|
||||||
if (found && !s.GetComposer().empty())
|
if (found && !s.GetComposer().empty())
|
||||||
found = copy.GetComposer().find(s.GetComposer()) != string::npos;
|
{
|
||||||
|
if (regcomp(&rx, s.GetComposer().c_str(), (CaseSensitive ? 0 : REG_ICASE) | Config.regex_type) == 0)
|
||||||
|
found = regexec(&rx, copy.GetComposer().c_str(), 0, 0, 0) == 0;
|
||||||
|
regfree(&rx);
|
||||||
|
}
|
||||||
if (found && !s.GetPerformer().empty())
|
if (found && !s.GetPerformer().empty())
|
||||||
found = copy.GetPerformer().find(s.GetPerformer()) != string::npos;
|
{
|
||||||
|
if (regcomp(&rx, s.GetPerformer().c_str(), (CaseSensitive ? 0 : REG_ICASE) | Config.regex_type) == 0)
|
||||||
|
found = regexec(&rx, copy.GetPerformer().c_str(), 0, 0, 0) == 0;
|
||||||
|
regfree(&rx);
|
||||||
|
}
|
||||||
if (found && !s.GetGenre().empty())
|
if (found && !s.GetGenre().empty())
|
||||||
found = copy.GetGenre().find(s.GetGenre()) != string::npos;
|
{
|
||||||
|
if (regcomp(&rx, s.GetGenre().c_str(), (CaseSensitive ? 0 : REG_ICASE) | Config.regex_type) == 0)
|
||||||
|
found = regexec(&rx, copy.GetGenre().c_str(), 0, 0, 0) == 0;
|
||||||
|
regfree(&rx);
|
||||||
|
}
|
||||||
if (found && !s.GetYear().empty())
|
if (found && !s.GetYear().empty())
|
||||||
found = copy.GetYear().find(s.GetYear()) != string::npos;
|
{
|
||||||
|
if (regcomp(&rx, s.GetYear().c_str(), (CaseSensitive ? 0 : REG_ICASE) | Config.regex_type) == 0)
|
||||||
|
found = regexec(&rx, copy.GetYear().c_str(), 0, 0, 0) == 0;
|
||||||
|
regfree(&rx);
|
||||||
|
}
|
||||||
if (found && !s.GetComment().empty())
|
if (found && !s.GetComment().empty())
|
||||||
found = copy.GetComment().find(s.GetComment()) != string::npos;
|
{
|
||||||
|
if (regcomp(&rx, s.GetComment().c_str(), (CaseSensitive ? 0 : REG_ICASE) | Config.regex_type) == 0)
|
||||||
|
found = regexec(&rx, copy.GetComment().c_str(), 0, 0, 0) == 0;
|
||||||
|
regfree(&rx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -514,7 +562,7 @@ void SearchEngine::Search()
|
|||||||
copy.GetArtist() == s.Any()
|
copy.GetArtist() == s.Any()
|
||||||
|| copy.GetTitle() == s.Any()
|
|| copy.GetTitle() == s.Any()
|
||||||
|| copy.GetAlbum() == s.Any()
|
|| copy.GetAlbum() == s.Any()
|
||||||
|| copy.GetFile() == s.Any()
|
|| copy.GetName() == s.Any()
|
||||||
|| copy.GetComposer() == s.Any()
|
|| copy.GetComposer() == s.Any()
|
||||||
|| copy.GetPerformer() == s.Any()
|
|| copy.GetPerformer() == s.Any()
|
||||||
|| copy.GetGenre() == s.Any()
|
|| copy.GetGenre() == s.Any()
|
||||||
@@ -528,7 +576,7 @@ void SearchEngine::Search()
|
|||||||
if (found && !s.GetAlbum().empty())
|
if (found && !s.GetAlbum().empty())
|
||||||
found = copy.GetAlbum() == s.GetAlbum();
|
found = copy.GetAlbum() == s.GetAlbum();
|
||||||
if (found && !s.GetFile().empty())
|
if (found && !s.GetFile().empty())
|
||||||
found = copy.GetFile() == s.GetFile();
|
found = copy.GetName() == s.GetFile();
|
||||||
if (found && !s.GetComposer().empty())
|
if (found && !s.GetComposer().empty())
|
||||||
found = copy.GetComposer() == s.GetComposer();
|
found = copy.GetComposer() == s.GetComposer();
|
||||||
if (found && !s.GetPerformer().empty())
|
if (found && !s.GetPerformer().empty())
|
||||||
@@ -541,6 +589,9 @@ void SearchEngine::Search()
|
|||||||
found = copy.GetComment() == s.GetComment();
|
found = copy.GetComment() == s.GetComment();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
copy.NullMe();
|
||||||
|
(*it)->CopyPtr(0);
|
||||||
|
|
||||||
if (found && any_found)
|
if (found && any_found)
|
||||||
{
|
{
|
||||||
Song *ss = Config.search_in_db ? *it : new Song(**it);
|
Song *ss = Config.search_in_db ? *it : new Song(**it);
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class SearchEngine : public Screen< Menu< std::pair<Buffer *, MPD::Song *> > >
|
|||||||
virtual void ReverseSelection() { w->ReverseSelection(StaticOptions); }
|
virtual void ReverseSelection() { w->ReverseSelection(StaticOptions); }
|
||||||
virtual void GetSelectedSongs(MPD::SongList &);
|
virtual void GetSelectedSongs(MPD::SongList &);
|
||||||
|
|
||||||
virtual void ApplyFilter(const std::string &s) { w->ApplyFilter(s, StaticOptions); }
|
virtual void ApplyFilter(const std::string &);
|
||||||
|
|
||||||
virtual List *GetList() { return w->Size() >= StaticOptions ? w : 0; }
|
virtual List *GetList() { return w->Size() >= StaticOptions ? w : 0; }
|
||||||
|
|
||||||
|
|||||||
@@ -276,6 +276,7 @@ void DefaultConfiguration(ncmpcpp_config &conf)
|
|||||||
conf.playlist_disable_highlight_delay = 5;
|
conf.playlist_disable_highlight_delay = 5;
|
||||||
conf.message_delay_time = 4;
|
conf.message_delay_time = 4;
|
||||||
conf.lyrics_db = 0;
|
conf.lyrics_db = 0;
|
||||||
|
conf.regex_type = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadKeys(ncmpcpp_keys &keys)
|
void ReadKeys(ncmpcpp_keys &keys)
|
||||||
@@ -646,6 +647,10 @@ void ReadConfiguration(ncmpcpp_config &conf)
|
|||||||
{
|
{
|
||||||
conf.set_window_title = v == "yes";
|
conf.set_window_title = v == "yes";
|
||||||
}
|
}
|
||||||
|
else if (cl.find("regular_expressions") != string::npos)
|
||||||
|
{
|
||||||
|
conf.regex_type = REG_EXTENDED * (v != "basic");
|
||||||
|
}
|
||||||
else if (cl.find("lyrics_database") != string::npos)
|
else if (cl.find("lyrics_database") != string::npos)
|
||||||
{
|
{
|
||||||
if (!v.empty())
|
if (!v.empty())
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ struct ncmpcpp_config
|
|||||||
int playlist_disable_highlight_delay;
|
int playlist_disable_highlight_delay;
|
||||||
int message_delay_time;
|
int message_delay_time;
|
||||||
int lyrics_db;
|
int lyrics_db;
|
||||||
|
int regex_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ncmpcpp_config Config;
|
extern ncmpcpp_config Config;
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ void Song::SetFile(const string &str)
|
|||||||
if (itsSong->file)
|
if (itsSong->file)
|
||||||
str_pool_put(itsSong->file);
|
str_pool_put(itsSong->file);
|
||||||
itsSong->file = str.empty() ? 0 : str_pool_get(str.c_str());
|
itsSong->file = str.empty() ? 0 : str_pool_get(str.c_str());
|
||||||
|
CountLastSlashPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Song::SetArtist(const string &str)
|
void Song::SetArtist(const string &str)
|
||||||
@@ -544,8 +545,9 @@ string Song::ShowTime(int length)
|
|||||||
|
|
||||||
void Song::CountLastSlashPosition()
|
void Song::CountLastSlashPosition()
|
||||||
{
|
{
|
||||||
|
if (!itsSong->file)
|
||||||
|
return;
|
||||||
char *tmp = strrchr(itsSong->file, '/');
|
char *tmp = strrchr(itsSong->file, '/');
|
||||||
if (tmp)
|
itsSlash = tmp ? tmp-itsSong->file : string::npos;
|
||||||
itsSlash = tmp-itsSong->file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -741,11 +741,11 @@ void TagEditor::GetSelectedSongs(MPD::SongList &v)
|
|||||||
void TagEditor::ApplyFilter(const std::string &s)
|
void TagEditor::ApplyFilter(const std::string &s)
|
||||||
{
|
{
|
||||||
if (w == Dirs)
|
if (w == Dirs)
|
||||||
Dirs->ApplyFilter(s, 1);
|
Dirs->ApplyFilter(s, 1, REG_ICASE | Config.regex_type);
|
||||||
else if (w == Albums)
|
else if (w == Albums)
|
||||||
Albums->ApplyFilter(s);
|
Albums->ApplyFilter(s, 0, REG_ICASE | Config.regex_type);
|
||||||
else if (w == Tags)
|
else if (w == Tags)
|
||||||
Tags->ApplyFilter(s);
|
Tags->ApplyFilter(s, 0, REG_ICASE | Config.regex_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
List *TagEditor::GetList()
|
List *TagEditor::GetList()
|
||||||
|
|||||||
Reference in New Issue
Block a user