summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/ustring.cpp55
-rw-r--r--core/ustring.h9
-rw-r--r--editor/editor_file_dialog.cpp4
-rw-r--r--editor/editor_file_system.cpp4
-rw-r--r--scene/gui/file_dialog.cpp4
5 files changed, 67 insertions, 9 deletions
diff --git a/core/ustring.cpp b/core/ustring.cpp
index dcb6545bd1..7a5129962b 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 <class C>
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 9ee3c2042c..d00bfa59b5 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 1f97aba221..c2e829e312 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<NoCaseComparator>();
- files.sort_custom<NoCaseComparator>();
+ dirs.sort_custom<NaturalNoCaseComparator>();
+ files.sort_custom<NaturalNoCaseComparator>();
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 b7070ab5f6..64a9d5df82 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<NaturalNoCaseComparator>();
+ files.sort_custom<NaturalNoCaseComparator>();
int total = dirs.size() + files.size();
int idx = 0;
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 2f1af318e9..391b39443d 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<NoCaseComparator>();
- files.sort_custom<NoCaseComparator>();
+ dirs.sort_custom<NaturalNoCaseComparator>();
+ files.sort_custom<NaturalNoCaseComparator>();
while (!dirs.empty()) {
String &dir_name = dirs.front()->get();