diff --git a/core/ustring.cpp b/core/ustring.cpp index dcb6545bd1a..7a5129962b1 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -53,6 +53,8 @@ #define MAX_DIGITS 6 #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 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 **/ @@ -481,6 +483,56 @@ signed char String::casecmp_to(const String &p_str) const { 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) { *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 }; -#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 static double built_in_strtod(const C *string, /* A decimal ASCII floating-point number, * optionally preceded by white space. Must diff --git a/core/ustring.h b/core/ustring.h index 9ee3c2042ce..d00bfa59b5a 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -98,6 +98,7 @@ public: signed char casecmp_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; /* 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 */ //tool translate diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp index 1f97aba221c..c2e829e312d 100644 --- a/editor/editor_file_dialog.cpp +++ b/editor/editor_file_dialog.cpp @@ -552,8 +552,8 @@ void EditorFileDialog::update_file_list() { dirs.push_back(".."); } - dirs.sort_custom(); - files.sort_custom(); + dirs.sort_custom(); + files.sort_custom(); while (!dirs.empty()) { const String &dir_name = dirs.front()->get(); diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index b7070ab5f60..64a9d5df82c 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -522,8 +522,8 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess da->list_dir_end(); - dirs.sort(); - files.sort(); + dirs.sort_custom(); + files.sort_custom(); int total = dirs.size() + files.size(); int idx = 0; diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 2f1af318e93..391b39443da 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -336,8 +336,8 @@ void FileDialog::update_file_list() { dirs.push_back(".."); } - dirs.sort_custom(); - files.sort_custom(); + dirs.sort_custom(); + files.sort_custom(); while (!dirs.empty()) { String &dir_name = dirs.front()->get();