3
[DBus (name = "org.gnome.Shell.SearchProvider")]
4
public class Contacts.SearchProvider : Object {
7
Gee.HashMap<string, Contact> contacts_map;
10
public SearchProvider (SearchProviderApp app) {
12
ensure_eds_accounts ();
14
contacts_map = new Gee.HashMap<string, Contact> ();
17
store.changed.connect ( (c) => {
18
contacts_map.set(c.get_data<string> ("search-id"), c);
20
store.added.connect ( (c) => {
21
var id = next_id++.to_string ();
22
c.set_data ("search-id", id);
23
contacts_map.set(id, c);
25
store.removed.connect ( (c) => {
26
contacts_map.unset(c.get_data<string> ("search-id"));
30
private static int compare_contacts (Contact a, Contact b) {
31
int a_prio = a.is_main ? 0 : -1;
32
int b_prio = b.is_main ? 0 : -1;
39
if (is_set (a.display_name) && is_set (b.display_name))
40
return a.display_name.collate (b.display_name);
42
// Sort empty names last
43
if (is_set (a.display_name))
45
if (is_set (b.display_name))
51
private string[] do_search (string[] terms) {
53
string[] normalized_terms =
54
Utils.canonicalize_for_search (string.joinv(" ", terms)).split(" ");
56
var matches = new ArrayList<Contact> ();
57
foreach (var c in store.get_contacts ()) {
61
if (c.contains_strings (normalized_terms))
65
matches.sort((CompareDataFunc<Contact>) compare_contacts);
67
var results = new string[matches.size];
68
for (int i = 0; i < matches.size; i++)
69
results[i] = matches[i].get_data ("search-id");
74
public string[] GetInitialResultSet (string[] terms) {
75
return do_search (terms);
78
public string[] GetSubsearchResultSet (string[] previous_results,
80
return do_search (new_terms);
83
public HashTable<string, Variant>[] GetResultMetas (string[] ids) {
85
var results = new ArrayList<HashTable> ();
86
foreach (var id in ids) {
87
var contact = contacts_map.get (id);
92
var meta = new HashTable<string, Variant> (str_hash, str_equal);
93
meta.insert ("id", new Variant.string (id));
95
meta.insert ("name", new Variant.string (contact.display_name));
97
if (contact.serializable_avatar_icon != null)
98
meta.insert ("gicon", new Variant.string (contact.serializable_avatar_icon.to_string ()));
99
else if (contact.avatar_icon_data != null)
100
meta.insert ("icon-data", contact.avatar_icon_data);
102
meta.insert ("gicon", new Variant.string (new ThemedIcon ("avatar-default").to_string ()));
106
return results.to_array ();
109
public void ActivateResult (string search_id) {
112
var contact = contacts_map.get (search_id);
114
if (contact == null) {
119
string id = contact.individual.id;
121
if (!Process.spawn_command_line_async ("gnome-contacts -i " + id))
122
stderr.printf ("Failed to launch contact with id '%s'\n", id);
123
} catch (SpawnError e) {
124
stderr.printf ("Failed to launch contact with id '%s'\n", id);
131
public class Contacts.SearchProviderApp : GLib.Application {
132
public SearchProviderApp () {
133
Object (application_id: "org.gnome.Contacts.SearchProvider",
134
flags: ApplicationFlags.IS_SERVICE,
135
inactivity_timeout: 10000);
138
public override bool dbus_register (GLib.DBusConnection connection, string object_path) {
140
connection.register_object (object_path, new SearchProvider (this));
141
} catch (IOError error) {
142
stderr.printf ("Could not register service: %s", error.message);
148
public override void startup () {
149
if (Environment.get_variable ("CONTACTS_SEARCH_PROVIDER_PERSIST") != null)
156
return new Contacts.SearchProviderApp ().run ();