[gnome-boxes] search-provider: learn to return results



commit 3c1201e5e3f292cd277bb16d41dc6a5563823ed6
Author: Marc-Andrà Lureau <marcandre lureau gmail com>
Date:   Sat Aug 4 15:14:13 2012 +0200

    search-provider: learn to return results
    
    https://bugzilla.gnome.org/show_bug.cgi?id=681246

 src/Makefile.am                      |    4 +
 src/collection-source.vala           |   13 ++++
 src/gnome-boxes-search-provider.vala |  130 ++++++++++++++++++++++++++++++---
 3 files changed, 135 insertions(+), 12 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index ef10c80..2320c46 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -85,7 +85,11 @@ MAINTAINERCLEANFILES += $(gnome_boxes_SOURCES:.vala=.c)
 libexec_PROGRAMS = gnome-boxes-search-provider
 
 gnome_boxes_search_provider_SOURCES =		\
+	collection-source.vala			\
+	display-config.vala			\
+	display-properties.vala			\
 	gnome-boxes-search-provider.vala	\
+	util.vala				\
 	$(NULL)
 
 gnome_boxes_search_provider_LDADD = $(BOXES_SEARCH_LIBS)
diff --git a/src/collection-source.vala b/src/collection-source.vala
index 43de3e3..9017945 100644
--- a/src/collection-source.vala
+++ b/src/collection-source.vala
@@ -48,6 +48,19 @@ private interface Boxes.IConfig {
             return null;
         }
     }
+
+    public string[] get_groups (string with_prefix = "") {
+        string[] groups = {};
+
+        foreach (var group in keyfile.get_groups ()) {
+            if (!group.has_prefix (with_prefix))
+                continue;
+
+            groups += group;
+        }
+
+        return groups;
+    }
 }
 
 private class Boxes.CollectionSource: GLib.Object, Boxes.IConfig {
diff --git a/src/gnome-boxes-search-provider.vala b/src/gnome-boxes-search-provider.vala
index e0c5f85..5d61427 100644
--- a/src/gnome-boxes-search-provider.vala
+++ b/src/gnome-boxes-search-provider.vala
@@ -1,40 +1,146 @@
 // This file is part of GNOME Boxes. License: LGPLv2+
 
 [DBus (name = "org.gnome.Shell.SearchProvider")]
-public class Boxes.SearchProvider: Object {
-    SearchProviderApp app;
+private class Boxes.SearchProvider: Object {
+    private SearchProviderApp app;
+    private bool loading;
+    public bool loaded { get; set; }
+    private HashTable<string, DisplayProperties> boxes;
+    private uint next_id;
 
     public SearchProvider (SearchProviderApp app) {
         this.app = app;
+        boxes = new HashTable<string, DisplayProperties> (str_hash, str_equal);
     }
 
-    private string[] search (string[] terms) {
-        string[] result = {};
+    private void add_box (DisplayProperties box) {
+        var id = next_id++.to_string ();
+        box.set_data ("search-id", id);
+
+        boxes.insert (id, box);
+    }
+
+    private async void load () {
+        // avoid reentering load () from a different request
+        while (!loaded && loading) {
+            var wait = notify["loaded"].connect (() => {
+                load.callback ();
+            });
+
+            yield;
+
+            disconnect (wait);
+            if (loaded)
+                return;
+        }
+
+        loading = true;
+        var dir = File.new_for_path (get_user_pkgconfig_source ());
+        yield foreach_filename_from_dir (dir, (filename) => {
+            var source = new CollectionSource.with_file (filename);
+            if (!source.enabled)
+                return false;
+
+            foreach (var group in source.get_groups ("display")) {
+                var config = new DisplayConfig.with_group (source, group);
+                var box = new DisplayProperties.with_config (config);
+                add_box (box);
+            }
+
+            return false;
+        });
+
+        loaded = true;
+        loading = false;
+    }
+
+    private static int compare_boxes (DisplayProperties a, DisplayProperties b) {
+        // sort first by last time used
+        if (a.access_last_time > b.access_last_time)
+            return -1;
+
+        var a_name = a.config.last_seen_name;
+        var b_name = b.config.last_seen_name;
+
+        // then by name
+        if (is_set (a_name) && is_set (b_name))
+            return a_name.collate (b_name);
+
+        // Sort empty names last
+        if (is_set (a_name))
+            return -1;
+        if (is_set (b_name))
+            return -1;
+
+        return 0;
+    }
+
+    private async string[] search (string[] terms) {
         app.hold ();
+        string[] normalized_terms = canonicalize_for_search (string.joinv(" ", terms)).split(" ");
+        var matches = new GenericArray<DisplayProperties> ();
 
         debug ("search (%s)", string.joinv (", ", terms));
+        if (!loaded)
+            yield load ();
+
+        foreach (var box in boxes.get_values ()) {
+            if (box.contains_strings (normalized_terms))
+                matches.add (box);
+        }
+
+        matches.sort((CompareFunc<DisplayProperties>) compare_boxes);
+        var results = new string[matches.length];
+        for (int i = 0; i < matches.length; i++)
+            results[i] = matches[i].get_data ("search-id");
 
         app.release ();
-        return result;
+        return results;
     }
 
-    public string[] GetInitialResultSet (string[] terms) {
-        return search (terms);
+    public async string[] GetInitialResultSet (string[] terms) {
+        return yield search (terms);
     }
 
-    public string[] GetSubsearchResultSet (string[] previous_results,
+    public async string[] GetSubsearchResultSet (string[] previous_results,
                                            string[] new_terms) {
-        return search (new_terms);
+        return yield search (new_terms);
     }
 
-    public HashTable<string, Variant>[] GetResultMetas (string[] ids) {
-        HashTable<string, Variant>[] result = {};
+    public async HashTable<string, Variant>[] GetResultMetas (string[] ids) {
+        var metas = new HashTable<string, Variant>[ids.length];
         app.hold ();
 
         debug ("GetResultMetas (%s)", string.joinv (", ", ids));
+        uint n = 0;
+        foreach (var id in ids) {
+            var box = boxes.lookup (id);
+            if (box == null)
+                continue;
+
+            var meta = new HashTable<string, Variant> (str_hash, str_equal);
+            metas[n] = meta;
+            n++;
+
+            meta.insert ("id", new Variant.string (id));
+            meta.insert ("name", new Variant.string (box.config.last_seen_name));
+
+            var file = File.new_for_path (Boxes.get_screenshot_filename (box.config.uuid));
+            FileInfo? info = null;
+            try {
+                info = yield file.query_info_async (FileAttribute.STANDARD_TYPE, FileQueryInfoFlags.NONE);
+            } catch (GLib.Error error) { }
+
+            if (info != null) {
+                var icon = new FileIcon (file);
+                meta.insert ("gicon", new Variant.string (icon.to_string ()));
+            } else {
+                meta.insert ("gicon", new Variant.string (new ThemedIcon ("gnome-boxes").to_string ()));
+            }
+        }
 
         app.release ();
-        return result;
+        return metas[0:n];
     }
 
     public void ActivateResult (string search_id) {



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