[geary/wip/create-folders-713492] Case-insensitive, normalized path matching



commit 53a4e0e2e7dfad33a65f24358c26f325d57b0555
Author: Charles Lindsay <chaz yorba org>
Date:   Wed Feb 5 18:06:43 2014 -0800

    Case-insensitive, normalized path matching

 src/engine/api/geary-folder-path.vala              |   53 +++++++++++++-------
 .../imap-engine/imap-engine-generic-account.vala   |   21 +++++---
 2 files changed, 49 insertions(+), 25 deletions(-)
---
diff --git a/src/engine/api/geary-folder-path.vala b/src/engine/api/geary-folder-path.vala
index 195adc0..c83cc44 100644
--- a/src/engine/api/geary-folder-path.vala
+++ b/src/engine/api/geary-folder-path.vala
@@ -221,22 +221,7 @@ public class Geary.FolderPath : BaseObject, Gee.Hashable<Geary.FolderPath>,
         return case_sensitive ? str_hash(basename) : str_hash(basename.down());
     }
     
-    /**
-     * { inheritDoc}
-     *
-     * Comparisons for Geary.FolderPath is defined as (a) empty paths are less-than non-empty paths
-     * and (b) each element is compared to the corresponding path element of the other FolderPath
-     * following collation rules for casefolded (case-insensitive) compared, and (c) shorter paths
-     * are less-than longer paths, assuming the path elements are equal up to the shorter path's
-     * length.
-     *
-     * Note that the { link FolderRoot.default_separator} has no bearing on comparisons, although
-     * { link FolderPath.case_sensitive} does.
-     *
-     * Returns -1 if this path is lexiographically before the other, 1 if its after, and 0 if they
-     * are equal.
-     */
-    public int compare_to(Geary.FolderPath other) {
+    private int compare_internal(Geary.FolderPath other, bool allow_case_sensitive, bool normalize) {
         if (this == other)
             return 0;
         
@@ -251,8 +236,13 @@ public class Geary.FolderPath : BaseObject, Gee.Hashable<Geary.FolderPath>,
             string this_element = this_list[ctr];
             string other_element = other_list[ctr];
             
-            // if either case-sensitive, then comparison is CS
-            if (!get_folder_at(ctr).case_sensitive && !other.get_folder_at(ctr).case_sensitive) {
+            if (normalize) {
+                this_element = this_element.normalize();
+                other_element = other_element.normalize();
+            }
+            if (!allow_case_sensitive
+                // if either case-sensitive, then comparison is CS
+                || (!get_folder_at(ctr).case_sensitive && !other.get_folder_at(ctr).case_sensitive)) {
                 this_element = this_element.casefold();
                 other_element = other_element.casefold();
             }
@@ -268,6 +258,33 @@ public class Geary.FolderPath : BaseObject, Gee.Hashable<Geary.FolderPath>,
     }
     
     /**
+     * Does a Unicode-normalized, case insensitive match.  Useful for getting a rough idea if
+     * a folder matches a name, but shouldn't be used to determine strict equality.
+     */
+    public int compare_normalized_ci(Geary.FolderPath other) {
+        return compare_internal(other, false, true);
+    }
+    
+    /**
+     * { inheritDoc}
+     *
+     * Comparisons for Geary.FolderPath is defined as (a) empty paths are less-than non-empty paths
+     * and (b) each element is compared to the corresponding path element of the other FolderPath
+     * following collation rules for casefolded (case-insensitive) compared, and (c) shorter paths
+     * are less-than longer paths, assuming the path elements are equal up to the shorter path's
+     * length.
+     *
+     * Note that the { link FolderRoot.default_separator} has no bearing on comparisons, although
+     * { link FolderPath.case_sensitive} does.
+     *
+     * Returns -1 if this path is lexiographically before the other, 1 if its after, and 0 if they
+     * are equal.
+     */
+    public int compare_to(Geary.FolderPath other) {
+        return compare_internal(other, true, false);
+    }
+    
+    /**
      * { inheritDoc}
      *
      * As with { link compare_to}, the { link FolderRoot.default_separator} has no bearing on the
diff --git a/src/engine/imap-engine/imap-engine-generic-account.vala 
b/src/engine/imap-engine/imap-engine-generic-account.vala
index bd0d93f..2f2c880 100644
--- a/src/engine/imap-engine/imap-engine-generic-account.vala
+++ b/src/engine/imap-engine/imap-engine-generic-account.vala
@@ -481,20 +481,27 @@ private abstract class Geary.ImapEngine.GenericAccount : Geary.AbstractAccount {
             Gee.ArrayList<string> search_names = get_mailbox_search_names().get(special);
             foreach (string search_name in search_names) {
                 Geary.FolderPath search_path = new Imap.FolderRoot(search_name, null);
-                // TODO: normalize strings before searching...
-                if (search_path in folder_map.keys) {
-                    path = search_path;
-                    break;
+                foreach (Geary.FolderPath test_path in folder_map.keys) {
+                    if (test_path.compare_normalized_ci(search_path) == 0) {
+                        path = search_path;
+                        break;
+                    }
                 }
+                if (path != null)
+                    break;
             }
             if (path == null) {
                 foreach (string search_name in search_names) {
                     Geary.FolderPath search_path = new Imap.FolderRoot(
                         Imap.MailboxSpecifier.CANONICAL_INBOX_NAME, null).get_child(search_name);
-                    if (search_path in folder_map.keys) {
-                        path = search_path;
-                        break;
+                    foreach (Geary.FolderPath test_path in folder_map.keys) {
+                        if (test_path.compare_normalized_ci(search_path) == 0) {
+                            path = search_path;
+                            break;
+                        }
                     }
+                    if (path != null)
+                        break;
                 }
             }
             


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]