Skip to content

Commit 8b95625

Browse files
committed
[UPD] : update of code for reflect change in new regex filter format
New filter rules : 0) a filter must have 2 chars mini and the first must be a . 1) a regex must be in (( and )) 2) a , will separate filters except if between a ( and ) 3) name{filter1, filter2} is a spetial form for collection filters 3.1) the name can be composed of what you want except { and } 3.2) the filter can be a regex 4) the filters cannot integrate these chars '(' ')' '{' '}' ' ' except for a regex with respect to rule 1) 5) the filters cannot integrate a ','
1 parent 7380fdb commit 8b95625

1 file changed

Lines changed: 129 additions & 51 deletions

File tree

ImGuiFileDialog.cpp

Lines changed: 129 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -796,69 +796,147 @@ void IGFD::FilterManager::ParseFilters(const char* vFilters) {
796796
puDLGFilters.clear(); // directory mode
797797

798798
if (!puDLGFilters.empty()) {
799-
// ".*,.cpp,.h,.hpp" => simple filters
800-
// "Source files{.cpp,.h,.hpp},Image files{.png,.gif,.jpg,.jpeg},.md" => collection filters
801-
// "([.][0-9]{3}),.cpp,.h,.hpp" => simple filters with regex
802-
// "frames files{([.][0-9]{3}),.frames}" => collection filters with regex
803-
804-
bool currentFilterFound = false;
805-
806-
size_t nan = std::string::npos;
807-
size_t p = 0, lp = 0;
808-
while ((p = puDLGFilters.find_first_of("{,", p)) != nan) {
809-
FilterInfos infos;
810-
811-
if (puDLGFilters[p] == '{') // {
812-
{
813-
infos.filter = puDLGFilters.substr(lp, p - lp);
814-
infos.filter_optimized = Utils::LowerCaseString(infos.filter);
815-
p++;
816-
lp = puDLGFilters.find('}', p);
817-
if (lp != nan) {
818-
std::string fs = puDLGFilters.substr(p, lp - p);
819-
auto arr = IGFD::Utils::SplitStringToVector(fs, ',', false);
820-
for (auto a : arr) {
821-
infos.collectionfilters.emplace(a);
822-
infos.collectionfilters_optimized.emplace(Utils::LowerCaseString(a));
823-
824-
// a regex
825-
if (a.find('(') != std::string::npos) {
826-
if (a.find(')') != std::string::npos) { infos.collectionfilters_regex.push_back(std::regex(a)); }
799+
/* Rules
800+
0) a filter must have 2 chars mini and the first must be a .
801+
1) a regex must be in (( and ))
802+
2) a , will separate filters except if between a ( and )
803+
3) name{filter1, filter2} is a spetial form for collection filters
804+
3.1) the name can be composed of what you want except { and }
805+
3.2) the filter can be a regex
806+
4) the filters cannot integrate these chars '(' ')' '{' '}' ' ' except for a regex with respect to rule 1)
807+
5) the filters cannot integrate a ','
808+
*/
809+
810+
bool collection_started = false;
811+
bool regex_started = false;
812+
bool parenthesis_started = false;
813+
814+
std::string word;
815+
std::string filter_name;
816+
817+
char last_split_char = 0;
818+
for (char c : puDLGFilters) {
819+
if (c == '{') {
820+
if (regex_started) {
821+
word += c;
822+
} else {
823+
collection_started = true;
824+
prParsedFilters.emplace_back();
825+
prParsedFilters.back().filter = filter_name;
826+
filter_name.clear();
827+
word.clear();
828+
}
829+
last_split_char = c;
830+
} else if (c == '}') {
831+
if (regex_started) {
832+
word += c;
833+
} else {
834+
if (collection_started) {
835+
if (word.size() > 1U && word[0] == '.') {
836+
if (prParsedFilters.empty()) { prParsedFilters.emplace_back(); }
837+
prParsedFilters.back().collectionfilters.emplace(word);
827838
}
839+
word.clear();
840+
filter_name.clear();
841+
collection_started = false;
828842
}
829843
}
830-
p = lp + 1;
831-
} else // ,
832-
{
833-
infos.filter = puDLGFilters.substr(lp, p - lp);
834-
infos.filter_optimized = Utils::LowerCaseString(infos.filter);
835-
836-
// a regex
837-
if (infos.filter.find('(') != std::string::npos) {
838-
if (infos.filter.find(')') != std::string::npos) { infos.filter_regex = std::regex(infos.filter); }
844+
last_split_char = c;
845+
} else if (c == '(') {
846+
word += c;
847+
if (last_split_char == '(') { regex_started = true; }
848+
parenthesis_started = true;
849+
if (!collection_started) { filter_name += c; }
850+
last_split_char = c;
851+
} else if (c == ')') {
852+
word += c;
853+
if (last_split_char == ')') {
854+
if (regex_started) {
855+
try {
856+
auto rx = std::regex(word); // cant thrwo an exception so if first, prevent emplace if failed
857+
if (collection_started) {
858+
prParsedFilters.back().collectionfilters.emplace(word);
859+
prParsedFilters.back().collectionfilters_regex.emplace_back(rx);
860+
} else {
861+
prParsedFilters.emplace_back();
862+
prParsedFilters.back().filter = word;
863+
prParsedFilters.back().filter_regex = rx;
864+
}
865+
} catch (std::exception&) {}
866+
word.clear();
867+
filter_name.clear();
868+
regex_started = false;
869+
} else {
870+
if (!collection_started) {
871+
if (!prParsedFilters.empty()) {
872+
prParsedFilters.erase(prParsedFilters.begin() + prParsedFilters.size() - 1U);
873+
} else {
874+
prParsedFilters.clear();
875+
}
876+
}
877+
word.clear();
878+
filter_name.clear();
879+
}
839880
}
840-
841-
p++;
881+
parenthesis_started = false;
882+
if (!collection_started) { filter_name += c; }
883+
last_split_char = c;
884+
} else if (c == '.') {
885+
word += c;
886+
if (!collection_started) { filter_name += c; }
887+
last_split_char = c;
888+
} else if (c == ',') {
889+
if (regex_started) {
890+
regex_started = false;
891+
word.clear();
892+
filter_name.clear();
893+
} else {
894+
if (collection_started) {
895+
if (word.size() > 1U && word[0] == '.') {
896+
prParsedFilters.back().collectionfilters.emplace(word);
897+
word.clear();
898+
filter_name.clear();
899+
}
900+
} else {
901+
if (word.size() > 1U && word[0] == '.') {
902+
prParsedFilters.emplace_back();
903+
prParsedFilters.back().filter = word;
904+
word.clear();
905+
filter_name.clear();
906+
}
907+
if (parenthesis_started) { filter_name += c; }
908+
}
909+
}
910+
} else {
911+
if (c != ' ') { word += c; }
912+
if (!collection_started) { filter_name += c; }
842913
}
914+
}
843915

844-
if (!currentFilterFound && prSelectedFilter.filter == infos.filter) {
845-
currentFilterFound = true;
846-
prSelectedFilter = infos;
916+
if (collection_started) {
917+
if (!prParsedFilters.empty()) {
918+
prParsedFilters.erase(prParsedFilters.begin() + prParsedFilters.size() - 1U);
919+
} else {
920+
prParsedFilters.clear();
847921
}
848-
849-
lp = p;
850-
if (!infos.empty()) prParsedFilters.emplace_back(infos);
922+
} else if (word.size() > 1U && word[0] == '.') {
923+
prParsedFilters.emplace_back();
924+
prParsedFilters.back().filter = word;
925+
word.clear();
851926
}
852927

853-
std::string token = puDLGFilters.substr(lp);
854-
if (!token.empty()) {
855-
FilterInfos infos;
856-
infos.filter = std::move(token);
857-
prParsedFilters.emplace_back(infos);
928+
bool currentFilterFound = false;
929+
930+
for (const auto& it : prParsedFilters) {
931+
if (it.filter == prSelectedFilter.filter) {
932+
currentFilterFound = true;
933+
prSelectedFilter = it;
934+
}
858935
}
859936

860-
if (!currentFilterFound)
937+
if (!currentFilterFound) {
861938
if (!prParsedFilters.empty()) prSelectedFilter = *prParsedFilters.begin();
939+
}
862940
}
863941
}
864942

0 commit comments

Comments
 (0)