diff --git a/src/common/bspf.hxx b/src/common/bspf.hxx index 403f8a436..747c83960 100644 --- a/src/common/bspf.hxx +++ b/src/common/bspf.hxx @@ -320,6 +320,10 @@ namespace BSPF } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // Search if string contains pattern including '?' as joker. + // @param str The searched string + // @param pattern The pattern to search for + // @return Position of pattern in string. inline size_t matchWithJoker(const string& str, const string& pattern) { if(str.length() >= pattern.length()) @@ -346,6 +350,11 @@ namespace BSPF } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + // 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. inline bool matchWithWildcards(const string& str, const string& pattern) { string pat = pattern; diff --git a/src/emucore/FSNode.hxx b/src/emucore/FSNode.hxx index 21555e760..aff2986a6 100644 --- a/src/emucore/FSNode.hxx +++ b/src/emucore/FSNode.hxx @@ -302,8 +302,8 @@ class FSNode * and replace the extension (if present) with the given one. If no * extension is present, the given one is appended instead. */ - string getNameWithExt(const string& ext) const; - string getPathWithExt(const string& ext) const; + string getNameWithExt(const string& ext = "") const; + string getPathWithExt(const string& ext = "") const; private: explicit FSNode(const AbstractFSNodePtr& realNode); diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 10c36d4e1..688b88f99 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -561,65 +561,6 @@ string LauncherDialog::getRomDir() return tmpromdir != EmptyString ? tmpromdir : settings.getString("romdir"); } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -size_t LauncherDialog::matchWithJoker(const string& str, const string& pattern) -{ - 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) - { - bool found = true; - - for(size_t i = 0; found && i < pattern.length(); ++i) - if(pattern[i] != str[pos + i] && pattern[i] != '?') - found = false; - - if(found) - return pos; - } - } - else - return str.find(pattern); - } - return string::npos; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool LauncherDialog::matchWithWildcards(const string& str, const string& pattern) -{ - string pat = pattern; - - // remove leading and trailing '*' - size_t i = 0; - while(pat[i++] == '*'); - pat = pat.substr(i - 1); - - i = pat.length(); - while(pat[--i] == '*'); - pat.erase(i + 1); - - // Search for first '*' - const size_t pos = pat.find('*'); - - if(pos != string::npos) - { - // '*' found, split pattern into left and right part, search recursively - const string leftPat = pat.substr(0, pos); - const string rightPat = pat.substr(pos + 1); - const size_t posLeft = matchWithJoker(str, leftPat); - - if(posLeft != string::npos) - return matchWithWildcards(str.substr(pos + posLeft), rightPat); - else - return false; - } - // no further '*' found - return matchWithJoker(str, pat) != string::npos; -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool LauncherDialog::matchWithWildcardsIgnoreCase(const string& str, const string& pattern) { @@ -629,7 +570,7 @@ bool LauncherDialog::matchWithWildcardsIgnoreCase(const string& str, const strin BSPF::toUpperCase(in); BSPF::toUpperCase(pat); - return matchWithWildcards(in, pat); + return BSPF::matchWithWildcards(in, pat); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/LauncherDialog.hxx b/src/gui/LauncherDialog.hxx index 193860676..27c3a0271 100644 --- a/src/gui/LauncherDialog.hxx +++ b/src/gui/LauncherDialog.hxx @@ -141,27 +141,6 @@ class LauncherDialog : public Dialog, CommandSender */ 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. - - @param str The searched string - @param pattern The pattern to search for - - @return Position of pattern in string. - */ - size_t matchWithJoker(const string& str, const string& pattern); - void applyFiltering(); float getRomInfoZoom(int listHeight) const; diff --git a/src/gui/RomImageWidget.cxx b/src/gui/RomImageWidget.cxx index 3d63a4500..df3e0d8c7 100644 --- a/src/gui/RomImageWidget.cxx +++ b/src/gui/RomImageWidget.cxx @@ -165,12 +165,19 @@ bool RomImageWidget::getImageList(const string& filename) FSNode::NameFilter filter = ([&](const FSNode& node) { return (!node.isDirectory() && (node.getPath() == filename + ".png" || - BSPF::matchWithWildcards(node.getPath(), filename + "#*.png"))); + BSPF::matchWithWildcards(node.getPath(), filename + " #*.png"))); }); FSNode node(instance().snapshotLoadDir().getPath()); - node.getChildren(myImageList, FSNode::ListMode::FilesOnly, filter, false, false); + + // Sort again, not considering extensions, else would be at the end of the list + std::sort(myImageList.begin(), myImageList.end(), + [](const FSNode& node1, const FSNode& node2) + { + return BSPF::compareIgnoreCase(node1.getNameWithExt(), node2.getNameWithExt()) < 0; + } + ); return myImageList.size() > 0; } @@ -271,7 +278,7 @@ void RomImageWidget::drawWidget(bool hilite) myNavSurface->invalidate(); if(isHighlighted() && - ((leftArrow && myImageIdx) || (!leftArrow && myImageIdx < myImageList.size() - 1)) || true) + ((leftArrow && myImageIdx) || (!leftArrow && myImageIdx < myImageList.size() - 1))) { const int w = _w / 64; const int w2 = 1; // w / 2;