Fix natural sorting order in EditorFileDialog, FileDialog and EditorFileSystemDirectory
Make EditorFileDialog, FileDialog and EditorFileSystemDirectory alphanumerical sorting more natural Added a new method 'naturalnocasecmp_to' and comparator 'NaturalNoCaseComparator' to String. Fixes #8712.
This commit is contained in:
parent
ed6baffc72
commit
f2564ca97f
|
@ -53,6 +53,8 @@
|
||||||
#define MAX_DIGITS 6
|
#define MAX_DIGITS 6
|
||||||
#define UPPERCASE(m_c) (((m_c) >= 'a' && (m_c) <= 'z') ? ((m_c) - ('a' - 'A')) : (m_c))
|
#define UPPERCASE(m_c) (((m_c) >= 'a' && (m_c) <= 'z') ? ((m_c) - ('a' - 'A')) : (m_c))
|
||||||
#define LOWERCASE(m_c) (((m_c) >= 'A' && (m_c) <= 'Z') ? ((m_c) + ('a' - 'A')) : (m_c))
|
#define LOWERCASE(m_c) (((m_c) >= 'A' && (m_c) <= 'Z') ? ((m_c) + ('a' - 'A')) : (m_c))
|
||||||
|
#define IS_DIGIT(m_d) ((m_d) >= '0' && (m_d) <= '9')
|
||||||
|
#define IS_HEX_DIGIT(m_d) (((m_d) >= '0' && (m_d) <= '9') || ((m_d) >= 'a' && (m_d) <= 'f') || ((m_d) >= 'A' && (m_d) <= 'F'))
|
||||||
|
|
||||||
/** STRING **/
|
/** STRING **/
|
||||||
|
|
||||||
|
@ -481,6 +483,56 @@ signed char String::casecmp_to(const String &p_str) const {
|
||||||
return 0; //should never reach anyway
|
return 0; //should never reach anyway
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signed char String::naturalnocasecmp_to(const String &p_str) const {
|
||||||
|
|
||||||
|
const CharType *this_str = c_str();
|
||||||
|
const CharType *that_str = p_str.c_str();
|
||||||
|
|
||||||
|
if (this_str && that_str) {
|
||||||
|
while (*this_str) {
|
||||||
|
|
||||||
|
if (!*that_str)
|
||||||
|
return 1;
|
||||||
|
else if (IS_DIGIT(*this_str)) {
|
||||||
|
|
||||||
|
int64_t this_int, that_int;
|
||||||
|
|
||||||
|
if (!IS_DIGIT(*that_str))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Compare the numbers */
|
||||||
|
this_int = to_int(this_str);
|
||||||
|
that_int = to_int(that_str);
|
||||||
|
|
||||||
|
if (this_int < that_int)
|
||||||
|
return -1;
|
||||||
|
else if (this_int > that_int)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Skip */
|
||||||
|
while (IS_DIGIT(*this_str))
|
||||||
|
this_str++;
|
||||||
|
while (IS_DIGIT(*that_str))
|
||||||
|
that_str++;
|
||||||
|
} else if (IS_DIGIT(*that_str))
|
||||||
|
return 1;
|
||||||
|
else {
|
||||||
|
if (_find_upper(*this_str) < _find_upper(*that_str)) //more than
|
||||||
|
return -1;
|
||||||
|
else if (_find_upper(*this_str) > _find_upper(*that_str)) //less than
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
this_str++;
|
||||||
|
that_str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*that_str)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void String::erase(int p_pos, int p_chars) {
|
void String::erase(int p_pos, int p_chars) {
|
||||||
|
|
||||||
*this = left(p_pos) + substr(p_pos + p_chars, length() - ((p_pos + p_chars)));
|
*this = left(p_pos) + substr(p_pos + p_chars, length() - ((p_pos + p_chars)));
|
||||||
|
@ -1698,9 +1750,6 @@ bool String::is_numeric() const {
|
||||||
return true; // TODO: Use the parser below for this instead
|
return true; // TODO: Use the parser below for this instead
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IS_DIGIT(m_d) ((m_d) >= '0' && (m_d) <= '9')
|
|
||||||
#define IS_HEX_DIGIT(m_d) (((m_d) >= '0' && (m_d) <= '9') || ((m_d) >= 'a' && (m_d) <= 'f') || ((m_d) >= 'A' && (m_d) <= 'F'))
|
|
||||||
|
|
||||||
template <class C>
|
template <class C>
|
||||||
static double built_in_strtod(const C *string, /* A decimal ASCII floating-point number,
|
static double built_in_strtod(const C *string, /* A decimal ASCII floating-point number,
|
||||||
* optionally preceded by white space. Must
|
* optionally preceded by white space. Must
|
||||||
|
|
|
@ -98,6 +98,7 @@ public:
|
||||||
|
|
||||||
signed char casecmp_to(const String &p_str) const;
|
signed char casecmp_to(const String &p_str) const;
|
||||||
signed char nocasecmp_to(const String &p_str) const;
|
signed char nocasecmp_to(const String &p_str) const;
|
||||||
|
signed char naturalnocasecmp_to(const String &p_str) const;
|
||||||
|
|
||||||
const CharType *c_str() const;
|
const CharType *c_str() const;
|
||||||
/* standard size stuff */
|
/* standard size stuff */
|
||||||
|
@ -256,6 +257,14 @@ struct NoCaseComparator {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NaturalNoCaseComparator {
|
||||||
|
|
||||||
|
bool operator()(const String &p_a, const String &p_b) const {
|
||||||
|
|
||||||
|
return p_a.naturalnocasecmp_to(p_b) < 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* end of namespace */
|
/* end of namespace */
|
||||||
|
|
||||||
//tool translate
|
//tool translate
|
||||||
|
|
|
@ -552,8 +552,8 @@ void EditorFileDialog::update_file_list() {
|
||||||
dirs.push_back("..");
|
dirs.push_back("..");
|
||||||
}
|
}
|
||||||
|
|
||||||
dirs.sort_custom<NoCaseComparator>();
|
dirs.sort_custom<NaturalNoCaseComparator>();
|
||||||
files.sort_custom<NoCaseComparator>();
|
files.sort_custom<NaturalNoCaseComparator>();
|
||||||
|
|
||||||
while (!dirs.empty()) {
|
while (!dirs.empty()) {
|
||||||
const String &dir_name = dirs.front()->get();
|
const String &dir_name = dirs.front()->get();
|
||||||
|
|
|
@ -522,8 +522,8 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
|
||||||
|
|
||||||
da->list_dir_end();
|
da->list_dir_end();
|
||||||
|
|
||||||
dirs.sort();
|
dirs.sort_custom<NaturalNoCaseComparator>();
|
||||||
files.sort();
|
files.sort_custom<NaturalNoCaseComparator>();
|
||||||
|
|
||||||
int total = dirs.size() + files.size();
|
int total = dirs.size() + files.size();
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
|
@ -336,8 +336,8 @@ void FileDialog::update_file_list() {
|
||||||
dirs.push_back("..");
|
dirs.push_back("..");
|
||||||
}
|
}
|
||||||
|
|
||||||
dirs.sort_custom<NoCaseComparator>();
|
dirs.sort_custom<NaturalNoCaseComparator>();
|
||||||
files.sort_custom<NoCaseComparator>();
|
files.sort_custom<NaturalNoCaseComparator>();
|
||||||
|
|
||||||
while (!dirs.empty()) {
|
while (!dirs.empty()) {
|
||||||
String &dir_name = dirs.front()->get();
|
String &dir_name = dirs.front()->get();
|
||||||
|
|
Loading…
Reference in New Issue