improved wildcard handling (addresses #154)

This commit is contained in:
thrust26 2020-11-21 14:59:31 +01:00
parent fc92520fc5
commit 80c32d67f4
3 changed files with 63 additions and 36 deletions

View File

@ -264,7 +264,7 @@ void Dialog::render()
if(!onTop) if(!onTop)
{ {
cerr << " shade " << typeid(*this).name() << endl; //cerr << " shade " << typeid(*this).name() << endl;
_shadeSurface->setDstRect(_surface->dstRect()); _shadeSurface->setDstRect(_surface->dstRect());
_shadeSurface->render(); _shadeSurface->render();

View File

@ -351,6 +351,9 @@ void LauncherDialog::updateUI()
size_t LauncherDialog::matchWithJoker(const string& str, const string& pattern) size_t LauncherDialog::matchWithJoker(const string& str, const string& pattern)
{ {
if(str.length() >= pattern.length()) if(str.length() >= pattern.length())
{
// optimize a bit
if(pattern.find('?') != string::npos)
{ {
for(size_t pos = 0; pos < str.length() - pattern.length() + 1; ++pos) for(size_t pos = 0; pos < str.length() - pattern.length() + 1; ++pos)
{ {
@ -364,42 +367,54 @@ size_t LauncherDialog::matchWithJoker(const string& str, const string& pattern)
return pos; return pos;
} }
} }
else
return str.find(pattern);
}
return string::npos; return string::npos;
} }
bool LauncherDialog::matchWithWildcards(const string& str, const string& pattern) bool LauncherDialog::matchWithWildcards(const string& str, const string& pattern)
{ {
string in = str;
string pat = pattern; string pat = pattern;
size_t pos = string::npos;
BSPF::toUpperCase(in); // remove leading and trailing '*'
BSPF::toUpperCase(pat); size_t i = 0;
while(pat[i++] == '*');
pat = pat.substr(i - 1);
for(size_t i = 0; i < pat.length(); ++i) i = pat.length();
if(pat[i] == '*') while(pat[--i] == '*');
{ pat.erase(i + 1);
pos = i;
break; // Search for first '*'
} size_t pos = pat.find('*');
if(pos != string::npos) if(pos != string::npos)
{ {
// '*' found, split pattern into left and right part, search recursively // '*' found, split pattern into left and right part, search recursively
const string leftPat = pat.substr(0, pos); const string leftPat = pat.substr(0, pos);
const string rightPat = pat.substr(pos + 1); const string rightPat = pat.substr(pos + 1);
size_t posLeft = matchWithJoker(in, leftPat); size_t posLeft = matchWithJoker(str, leftPat);
if(posLeft != string::npos) if(posLeft != string::npos)
return matchWithWildcards(in.substr(pos + posLeft), rightPat); return matchWithWildcards(str.substr(pos + posLeft), rightPat);
else else
return false; return false;
} }
else
{
// no further '*' found // no further '*' found
return matchWithJoker(in, pat) != string::npos; return matchWithJoker(str, pat) != string::npos;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool LauncherDialog::matchWithWildcardsIgnoreCase(const string& str, const string& pattern)
{
string in = str;
string pat = pattern;
BSPF::toUpperCase(in);
BSPF::toUpperCase(pat);
return matchWithWildcards(in, pat);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -415,7 +430,7 @@ void LauncherDialog::applyFiltering()
// Skip over files that don't match the pattern in the 'pattern' textbox // Skip over files that don't match the pattern in the 'pattern' textbox
if(myPattern && myPattern->getText() != "" && if(myPattern && myPattern->getText() != "" &&
!matchWithWildcards(node.getName(), myPattern->getText())) !matchWithWildcardsIgnoreCase(node.getName(), myPattern->getText()))
return false; return false;
} }
return true; return true;

View File

@ -113,6 +113,28 @@ class LauncherDialog : public Dialog
void saveConfig() override; void saveConfig() override;
void updateUI(); void updateUI();
/**
Search if string contains pattern including wildcard '*'
and '?' as joker, ignoring case.
@param str The searched string
@param pattern The pattern to search for
@return True if pattern was found.
*/
bool matchWithWildcardsIgnoreCase(const string& str, const string& pattern);
/**
Search if string contains pattern including wildcard '*'
and '?' as joker.
@param str The searched string
@param pattern The pattern to search for
@return True if pattern was found.
*/
bool matchWithWildcards(const string& str, const string& pattern);
/** /**
Search if string contains pattern including '?' as joker. Search if string contains pattern including '?' as joker.
@ -123,16 +145,6 @@ class LauncherDialog : public Dialog
*/ */
size_t matchWithJoker(const string& str, const string& pattern); size_t matchWithJoker(const string& str, const string& pattern);
/**
Search if string contains pattern including wildcard '*'
and '?' as joker, ignoring case.
@param str The searched string
@param pattern The pattern to search for
@return True if pattern was found.
*/
bool matchWithWildcards(const string& str, const string& pattern);
void applyFiltering(); void applyFiltering();
float getRomInfoZoom(int listHeight) const; float getRomInfoZoom(int listHeight) const;