[geary] Clean up the ConversationViewer::highlight_search_terms method.



commit fd5b451024eb3cf267928d9810e15601d484a639
Author: Michael James Gratton <mike vee net>
Date:   Sun Jun 19 19:16:32 2016 +1000

    Clean up the ConversationViewer::highlight_search_terms method.
    
    * src/client/conversation-viewer/conversation-viewer.vala
      (ConversationViewer::highlight_search_terms): Only do the highlight if
      the current folder is a search folder and it has a query. Cache the
      fetch cancellable so we can avoid setting the highlight on the web view
      if cancelled. Import ::add_literal_matches method impl and remove that
      method since it only gets used here.

 .../conversation-viewer/conversation-viewer.vala   |   98 +++++++++++---------
 1 files changed, 54 insertions(+), 44 deletions(-)
---
diff --git a/src/client/conversation-viewer/conversation-viewer.vala 
b/src/client/conversation-viewer/conversation-viewer.vala
index a573a7b..f2a72f0 100644
--- a/src/client/conversation-viewer/conversation-viewer.vala
+++ b/src/client/conversation-viewer/conversation-viewer.vala
@@ -531,63 +531,73 @@ public class ConversationViewer : Gtk.Box {
             debug("Unable to select conversation: %s", err.message);
         }
     }
-    
-    // This applies a fudge-factor set of matches when the database results
-    // aren't entirely satisfactory, such as when you search for an email
-    // address and the database tokenizes out the @ and ., etc.  It's not meant
-    // to be comprehensive, just a little extra highlighting applied to make
-    // the results look a little closer to what you typed.
-    private void add_literal_matches(string raw_query, Gee.Set<string>? search_matches) {
-        foreach (string word in raw_query.split(" ")) {
-            if (word.has_suffix("\""))
-                word = word.substring(0, word.length - 1);
-            if (word.has_prefix("\""))
-                word = word.substring(1);
-            
-            if (!Geary.String.is_empty_or_whitespace(word))
-                search_matches.add(word);
-        }
-    }
-    
+
     private async void highlight_search_terms() {
-        if (search_folder == null)
+        Geary.SearchQuery? query = (this.search_folder != null)
+            ? search_folder.search_query
+            : null;
+        if (query == null)
             return;
-        
+
         // Remove existing highlights.
         web_view.unmark_text_matches();
-        
+
         // List all IDs of emails we're viewing.
         Gee.Collection<Geary.EmailIdentifier> ids = new Gee.ArrayList<Geary.EmailIdentifier>();
         foreach (Geary.Email email in messages)
             ids.add(email.id);
-        
+
+        // Using the fetch cancellable here is appropriate since each
+        // time the search results change, the old fetch will be
+        // cancelled and we should also cancel the highlighting. Store
+        // it here for use later in the method.
+        Cancellable cancellable = this.cancellable_fetch;
+
+        Gee.Set<string>? search_matches = null;
         try {
-            Gee.Set<string>? search_matches = yield search_folder.get_search_matches_async(
-                ids, cancellable_fetch);
-            if (search_matches == null)
-                search_matches = new Gee.HashSet<string>();
-            
-            if (search_folder.search_query != null)
-                add_literal_matches(search_folder.search_query.raw, search_matches);
-            
-            // Webkit's highlighting is ... weird.  In order to actually see
-            // all the highlighting you're applying, it seems necessary to
-            // start with the shortest string and work up.  If you don't, it
-            // seems that shorter strings will overwrite longer ones, and
-            // you're left with incomplete highlighting.
-            Gee.ArrayList<string> ordered_matches = new Gee.ArrayList<string>();
-            ordered_matches.add_all(search_matches);
-            ordered_matches.sort((a, b) => a.length - b.length);
-            
-            foreach(string match in ordered_matches)
-                web_view.mark_text_matches(match, false, 0);
+            search_matches = yield search_folder.get_search_matches_async(
+                ids, cancellable);
         } catch (Error e) {
             debug("Error highlighting search results: %s", e.message);
+            // Continue on here since if nothing else we have the
+            // fudging to fall back on immediately below.
+        }
+
+        if (search_matches == null)
+            search_matches = new Gee.HashSet<string>();
+
+        // This applies a fudge-factor set of matches when the database results
+        // aren't entirely satisfactory, such as when you search for an email
+        // address and the database tokenizes out the @ and ., etc.  It's not meant
+        // to be comprehensive, just a little extra highlighting applied to make
+        // the results look a little closer to what you typed.
+        foreach (string word in query.raw.split(" ")) {
+            if (word.has_suffix("\""))
+                word = word.substring(0, word.length - 1);
+            if (word.has_prefix("\""))
+                word = word.substring(1);
+
+            if (!Geary.String.is_empty_or_whitespace(word))
+                search_matches.add(word);
+        }
+
+        // Webkit's highlighting is ... weird.  In order to actually
+        // see all the highlighting you're applying, it seems
+        // necessary to start with the shortest string and work up.
+        // If you don't, it seems that shorter strings will overwrite
+        // longer ones, and you're left with incomplete highlighting.
+        Gee.ArrayList<string> ordered_matches = new Gee.ArrayList<string>();
+        ordered_matches.add_all(search_matches);
+        ordered_matches.sort((a, b) => a.length - b.length);
+
+        if (!cancellable.is_cancelled()) {
+            foreach(string match in ordered_matches)
+                web_view.mark_text_matches(match, false, 0);
+
+            web_view.set_highlight_text_matches(true);
         }
-        
-        web_view.set_highlight_text_matches(true);
     }
-    
+
     // Given some emails, fetch the full versions with all required fields.
     private async Gee.Collection<Geary.Email>? list_full_messages_async(
         Gee.Collection<Geary.Email> emails, Cancellable? cancellable) throws Error {


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