~jbicha/hud/build-depend-on-valac-not-gir

« back to all changes in this revision

Viewing changes to service/dbusmenu-collector.c

Merging the HUD into indicator-appmenu

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
An object to collect the various DBusmenu objects that exist
 
3
on dbus.
 
4
 
 
5
Copyright 2011 Canonical Ltd.
 
6
 
 
7
Authors:
 
8
    Ted Gould <ted@canonical.com>
 
9
 
 
10
This program is free software: you can redistribute it and/or modify it 
 
11
under the terms of the GNU General Public License version 3, as published 
 
12
by the Free Software Foundation.
 
13
 
 
14
This program is distributed in the hope that it will be useful, but 
 
15
WITHOUT ANY WARRANTY; without even the implied warranties of 
 
16
MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR 
 
17
PURPOSE.  See the GNU General Public License for more details.
 
18
 
 
19
You should have received a copy of the GNU General Public License along 
 
20
with this program.  If not, see <http://www.gnu.org/licenses/>.
 
21
*/
 
22
 
 
23
#ifdef HAVE_CONFIG_H
 
24
#include "config.h"
 
25
#endif
 
26
 
 
27
#include <gio/gio.h>
 
28
#include <glib.h>
 
29
#include <glib/gi18n.h>
 
30
 
 
31
#include <libdbusmenu-glib/client.h>
 
32
 
 
33
#include "dbusmenu-collector.h"
 
34
#include "distance.h"
 
35
#include "indicator-tracker.h"
 
36
#include "shared-values.h"
 
37
 
 
38
#define GENERIC_ICON   "dbusmenu-lens-panel"
 
39
 
 
40
typedef struct _DbusmenuCollectorPrivate DbusmenuCollectorPrivate;
 
41
 
 
42
struct _DbusmenuCollectorPrivate {
 
43
        GDBusConnection * bus;
 
44
        guint signal;
 
45
        GHashTable * hash;
 
46
        IndicatorTracker * tracker;
 
47
};
 
48
 
 
49
struct _DbusmenuCollectorFound {
 
50
        gchar * dbus_addr;
 
51
        gchar * dbus_path;
 
52
        gint dbus_id;
 
53
 
 
54
        gchar * display_string;
 
55
        gchar * db_string;
 
56
 
 
57
        guint distance;
 
58
        DbusmenuMenuitem * item;
 
59
        gchar * indicator;
 
60
};
 
61
 
 
62
typedef struct _menu_key_t menu_key_t;
 
63
struct _menu_key_t {
 
64
        gchar * sender;
 
65
        gchar * path;
 
66
};
 
67
 
 
68
typedef struct _search_item_t search_item_t;
 
69
struct _search_item_t {
 
70
        gchar * string;
 
71
        guint distance;
 
72
};
 
73
 
 
74
static void dbusmenu_collector_class_init (DbusmenuCollectorClass *klass);
 
75
static void dbusmenu_collector_init       (DbusmenuCollector *self);
 
76
static void dbusmenu_collector_dispose    (GObject *object);
 
77
static void dbusmenu_collector_finalize   (GObject *object);
 
78
static void update_layout_cb (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * signal, GVariant * params, gpointer user_data);
 
79
static guint menu_hash_func (gconstpointer key);
 
80
static gboolean menu_equal_func (gconstpointer a, gconstpointer b);
 
81
static void menu_key_destroy (gpointer key);
 
82
static DbusmenuCollectorFound * dbusmenu_collector_found_new (DbusmenuClient * client, DbusmenuMenuitem * item, GStrv strings, guint distance, GStrv usedstrings, const gchar * indicator_name);
 
83
 
 
84
G_DEFINE_TYPE (DbusmenuCollector, dbusmenu_collector, G_TYPE_OBJECT);
 
85
 
 
86
static void
 
87
dbusmenu_collector_class_init (DbusmenuCollectorClass *klass)
 
88
{
 
89
        GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
90
 
 
91
        g_type_class_add_private (klass, sizeof (DbusmenuCollectorPrivate));
 
92
 
 
93
        object_class->dispose = dbusmenu_collector_dispose;
 
94
        object_class->finalize = dbusmenu_collector_finalize;
 
95
 
 
96
        return;
 
97
}
 
98
 
 
99
static void
 
100
dbusmenu_collector_init (DbusmenuCollector *self)
 
101
{
 
102
        self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), DBUSMENU_COLLECTOR_TYPE, DbusmenuCollectorPrivate);
 
103
 
 
104
        self->priv->bus = NULL;
 
105
        self->priv->signal = 0;
 
106
        self->priv->hash = NULL;
 
107
        self->priv->tracker = NULL;
 
108
 
 
109
        self->priv->hash = g_hash_table_new_full(menu_hash_func, menu_equal_func,
 
110
                                                 menu_key_destroy, g_object_unref /* DbusmenuClient */);
 
111
 
 
112
        self->priv->bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
 
113
        self->priv->signal = g_dbus_connection_signal_subscribe(self->priv->bus,
 
114
                                                                NULL, /* sender */
 
115
                                                                "com.canonical.dbusmenu", /* interface */
 
116
                                                                "LayoutUpdated", /* member */
 
117
                                                                NULL, /* object path */
 
118
                                                                NULL, /* arg0 */
 
119
                                                                G_DBUS_SIGNAL_FLAGS_NONE, /* flags */
 
120
                                                                update_layout_cb, /* cb */
 
121
                                                                self, /* data */
 
122
                                                                NULL); /* free func */
 
123
 
 
124
        GError * error = NULL;
 
125
        g_dbus_connection_emit_signal(self->priv->bus,
 
126
                                      NULL, /* destination */
 
127
                                      "/", /* object */
 
128
                                      "com.canonical.dbusmenu",
 
129
                                      "FindServers",
 
130
                                      NULL, /* params */
 
131
                                      &error);
 
132
        if (error != NULL) {
 
133
                g_warning("Unable to emit 'FindServers': %s", error->message);
 
134
                g_error_free(error);
 
135
        }
 
136
 
 
137
        self->priv->tracker = indicator_tracker_new();
 
138
 
 
139
        return;
 
140
}
 
141
 
 
142
static void
 
143
dbusmenu_collector_dispose (GObject *object)
 
144
{
 
145
        DbusmenuCollector * collector = DBUSMENU_COLLECTOR(object);
 
146
 
 
147
        if (collector->priv->signal != 0) {
 
148
                g_dbus_connection_signal_unsubscribe(collector->priv->bus, collector->priv->signal);
 
149
                collector->priv->signal = 0;
 
150
        }
 
151
 
 
152
        if (collector->priv->hash != NULL) {
 
153
                g_hash_table_destroy(collector->priv->hash);
 
154
                collector->priv->hash = NULL;
 
155
        }
 
156
 
 
157
        if (collector->priv->tracker != NULL) {
 
158
                g_object_unref(collector->priv->tracker);
 
159
                collector->priv->tracker = NULL;
 
160
        }
 
161
 
 
162
        G_OBJECT_CLASS (dbusmenu_collector_parent_class)->dispose (object);
 
163
        return;
 
164
}
 
165
 
 
166
static void
 
167
dbusmenu_collector_finalize (GObject *object)
 
168
{
 
169
 
 
170
        G_OBJECT_CLASS (dbusmenu_collector_parent_class)->finalize (object);
 
171
        return;
 
172
}
 
173
 
 
174
DbusmenuCollector *
 
175
dbusmenu_collector_new (void)
 
176
{
 
177
        return DBUSMENU_COLLECTOR(g_object_new(DBUSMENU_COLLECTOR_TYPE, NULL));
 
178
}
 
179
 
 
180
static void
 
181
update_layout_cb (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * signal, GVariant * params, gpointer user_data)
 
182
{
 
183
        g_debug("Client updating %s:%s", sender, path);
 
184
        DbusmenuCollector * collector = DBUSMENU_COLLECTOR(user_data);
 
185
        g_return_if_fail(collector != NULL);
 
186
 
 
187
        menu_key_t search_key = {
 
188
                sender: (gchar *)sender,
 
189
                path:   (gchar *)path
 
190
        };
 
191
 
 
192
        gpointer found = g_hash_table_lookup(collector->priv->hash, &search_key);
 
193
        if (found == NULL) {
 
194
                /* Build one becasue we don't have it */
 
195
                menu_key_t * built_key = g_new0(menu_key_t, 1);
 
196
                built_key->sender = g_strdup(sender);
 
197
                built_key->path = g_strdup(path);
 
198
 
 
199
                DbusmenuClient * client = dbusmenu_client_new(sender, path);
 
200
 
 
201
                g_hash_table_insert(collector->priv->hash, built_key, client);
 
202
        }
 
203
 
 
204
        /* Assume that dbusmenu client is doing this for us */
 
205
        return;
 
206
}
 
207
 
 
208
static guint
 
209
menu_hash_func (gconstpointer key)
 
210
{
 
211
        const menu_key_t * mk = (const menu_key_t*)key;
 
212
 
 
213
        return g_str_hash(mk->sender) + g_str_hash(mk->path) - 5381;
 
214
}
 
215
 
 
216
static gboolean
 
217
menu_equal_func (gconstpointer a, gconstpointer b)
 
218
{
 
219
        const menu_key_t * ak = (const menu_key_t *)a;
 
220
        const menu_key_t * bk = (const menu_key_t *)b;
 
221
 
 
222
        if (g_strcmp0(ak->sender, bk->sender) == 0) {
 
223
                return TRUE;
 
224
        }
 
225
 
 
226
        if (g_strcmp0(ak->path, bk->path) == 0) {
 
227
                return TRUE;
 
228
        }
 
229
 
 
230
        return FALSE;
 
231
}
 
232
 
 
233
static void
 
234
menu_key_destroy (gpointer key)
 
235
{
 
236
        menu_key_t * ikey = (menu_key_t *)key;
 
237
 
 
238
        g_free(ikey->sender);
 
239
        g_free(ikey->path);
 
240
 
 
241
        g_free(ikey);
 
242
        return;
 
243
}
 
244
 
 
245
gchar *
 
246
remove_underline (const gchar * input)
 
247
{
 
248
        const gchar * in = input;
 
249
        gchar * output = g_new0(gchar, g_utf8_strlen(input, -1) + 1);
 
250
        gchar * out = output;
 
251
 
 
252
        while (in[0] != '\0') {
 
253
                if (in[0] == '_') {
 
254
                        in++;
 
255
                } else {
 
256
                        out[0] = in[0];
 
257
                        in++;
 
258
                        out++;
 
259
                }
 
260
        }
 
261
 
 
262
        return output;
 
263
}
 
264
 
 
265
static GList *
 
266
tokens_to_children (DbusmenuMenuitem * rootitem, const gchar * search, GList * results, GStrv label_prefix, DbusmenuClient * client, const gchar * indicator_name)
 
267
{
 
268
        if (search == NULL) {
 
269
                return results;
 
270
        }
 
271
 
 
272
        if (rootitem == NULL) {
 
273
                return results;
 
274
        }
 
275
 
 
276
        if (!dbusmenu_menuitem_property_get_bool(rootitem, DBUSMENU_MENUITEM_PROP_ENABLED)) {
 
277
                return results;
 
278
        }
 
279
 
 
280
        if (!dbusmenu_menuitem_property_get_bool(rootitem, DBUSMENU_MENUITEM_PROP_VISIBLE)) {
 
281
                return results;
 
282
        }
 
283
 
 
284
        GStrv newstr = NULL;
 
285
        if (dbusmenu_menuitem_property_exist(rootitem, DBUSMENU_MENUITEM_PROP_LABEL) &&
 
286
                        !dbusmenu_menuitem_property_exist(rootitem, DBUSMENU_MENUITEM_PROP_TYPE)) {
 
287
                const gchar * label = dbusmenu_menuitem_property_get(rootitem, DBUSMENU_MENUITEM_PROP_LABEL);
 
288
 
 
289
                if (label_prefix != NULL && label_prefix[0] != NULL) {
 
290
                        gint i;
 
291
                        guint prefix_len = g_strv_length(label_prefix);
 
292
                        newstr = g_new(gchar *, prefix_len + 2);
 
293
 
 
294
                        for (i = 0; i < prefix_len; i++) {
 
295
                                newstr[i] = g_strdup(label_prefix[i]);
 
296
                        }
 
297
 
 
298
                        newstr[prefix_len] = g_strdup(label);
 
299
                        newstr[prefix_len + 1] = NULL;
 
300
                } else {
 
301
                        newstr = g_new0(gchar *, 2);
 
302
                        newstr[0] = g_strdup(label);
 
303
                        newstr[1] = NULL;
 
304
                }
 
305
        }
 
306
 
 
307
        if (!dbusmenu_menuitem_get_root(rootitem) && newstr != NULL) {
 
308
                GStrv used_strings = NULL;
 
309
                guint distance = calculate_distance(search, newstr, &used_strings);
 
310
                if (distance < G_MAXUINT) {
 
311
                        // g_debug("Distance %d for '%s' in \"'%s'\" using \"'%s'\"", distance, search, g_strjoinv("' '", newstr), g_strjoinv("' '", used_strings));
 
312
                        results = g_list_prepend(results, dbusmenu_collector_found_new(client, rootitem, newstr, distance, used_strings, indicator_name));
 
313
                }
 
314
                g_strfreev(used_strings);
 
315
        }
 
316
 
 
317
        if (newstr == NULL) {
 
318
                newstr = g_strdupv(label_prefix);
 
319
        }
 
320
 
 
321
        GList * children = dbusmenu_menuitem_get_children(rootitem);
 
322
        GList * child;
 
323
 
 
324
        for (child = children; child != NULL; child = g_list_next(child)) {
 
325
                DbusmenuMenuitem * item = DBUSMENU_MENUITEM(child->data);
 
326
 
 
327
                results = tokens_to_children(item, search, results, newstr, client, indicator_name);
 
328
        }
 
329
 
 
330
        g_strfreev(newstr);
 
331
        return results;
 
332
}
 
333
 
 
334
static GList *
 
335
process_client (DbusmenuCollector * collector, DbusmenuClient * client, const gchar * search, GList * results, const gchar * indicator_name, GStrv prefix)
 
336
{
 
337
        /* Handle the case where there are no search terms */
 
338
        if (search == NULL || search[0] == '\0') {
 
339
                GList * children = dbusmenu_menuitem_get_children(dbusmenu_client_get_root(client));
 
340
                GList * child;
 
341
 
 
342
                for (child = children; child != NULL; child = g_list_next(child)) {
 
343
                        DbusmenuMenuitem * item = DBUSMENU_MENUITEM(child->data);
 
344
 
 
345
                        if (!dbusmenu_menuitem_property_exist(item, DBUSMENU_MENUITEM_PROP_LABEL)) {
 
346
                                continue;
 
347
                        }
 
348
 
 
349
                        const gchar * label = dbusmenu_menuitem_property_get(item, DBUSMENU_MENUITEM_PROP_LABEL);
 
350
                        const gchar * array[2];
 
351
                        array[0] = label;
 
352
                        array[1] = NULL;
 
353
 
 
354
                        results = g_list_prepend(results, dbusmenu_collector_found_new(client, item, (GStrv)array, calculate_distance(NULL, (GStrv)array, NULL), NULL, indicator_name));
 
355
                }
 
356
 
 
357
                return results;
 
358
        }
 
359
 
 
360
        results = tokens_to_children(dbusmenu_client_get_root(client), search, results, prefix, client, indicator_name);
 
361
        return results;
 
362
}
 
363
 
 
364
static GList *
 
365
just_do_it (DbusmenuCollector * collector, const gchar * dbus_addr, const gchar * dbus_path, const gchar * search, GList * results, const gchar * indicator_name, GStrv prefix)
 
366
{
 
367
        g_return_val_if_fail(IS_DBUSMENU_COLLECTOR(collector), results);
 
368
 
 
369
        menu_key_t search_key = {
 
370
                sender: (gchar *)dbus_addr,
 
371
                path:   (gchar *)dbus_path
 
372
        };
 
373
 
 
374
        gpointer found = g_hash_table_lookup(collector->priv->hash, &search_key);
 
375
        if (found != NULL) {
 
376
                results = process_client(collector, DBUSMENU_CLIENT(found), search, results, indicator_name, prefix);
 
377
        }
 
378
 
 
379
        return results;
 
380
}
 
381
 
 
382
static gint
 
383
dbusmenu_collector_found_sort (gconstpointer a, gconstpointer b)
 
384
{
 
385
        DbusmenuCollectorFound * founda;
 
386
        DbusmenuCollectorFound * foundb;
 
387
 
 
388
        founda = (DbusmenuCollectorFound *)a;
 
389
        foundb = (DbusmenuCollectorFound *)b;
 
390
 
 
391
        return dbusmenu_collector_found_get_distance(founda) - dbusmenu_collector_found_get_distance(foundb);
 
392
}
 
393
 
 
394
GList *
 
395
dbusmenu_collector_search (DbusmenuCollector * collector, const gchar * dbus_addr, const gchar * dbus_path, const gchar * search)
 
396
{
 
397
        GList * items = NULL;
 
398
 
 
399
        if (dbus_addr != NULL && dbus_path != NULL) {
 
400
                items = just_do_it(collector, dbus_addr, dbus_path, search, NULL, NULL, NULL);
 
401
        }
 
402
 
 
403
        /* This is where we'll do the indicators if we're not
 
404
           looking at the null search.  In that case we'll let
 
405
           the client take over. */
 
406
        if (search != NULL && search[0] != '\0') {
 
407
                GArray * indicators = indicator_tracker_get_indicators(collector->priv->tracker);
 
408
                gint indicator_cnt;
 
409
                for (indicator_cnt = 0; indicator_cnt < indicators->len; indicator_cnt++) {
 
410
                        IndicatorTrackerIndicator * indicator = &g_array_index(indicators, IndicatorTrackerIndicator, indicator_cnt);
 
411
 
 
412
                        gchar * array[2];
 
413
                        array[0] = indicator->prefix;
 
414
                        array[1] = NULL;
 
415
 
 
416
                        GList * iitems = just_do_it(collector, indicator->dbus_name, indicator->dbus_object, search, NULL, indicator->name, array);
 
417
 
 
418
                        /* Increase indicator's distance by 50% */
 
419
                        GList * iitem = iitems;
 
420
                        while (iitem != NULL) {
 
421
                                DbusmenuCollectorFound * found = (DbusmenuCollectorFound *)iitem->data;
 
422
                                found->distance = found->distance + (found->distance / 2);
 
423
                                iitem = g_list_next(iitem);
 
424
                        }
 
425
 
 
426
                        items = g_list_concat(items, iitems);
 
427
                }
 
428
        }
 
429
 
 
430
        items = g_list_sort(items, dbusmenu_collector_found_sort);
 
431
 
 
432
        return items;
 
433
}
 
434
 
 
435
void
 
436
dbusmenu_collector_execute (DbusmenuCollector * collector, const gchar * dbus_addr, const gchar * dbus_path, gint id, guint timestamp)
 
437
{
 
438
        g_return_if_fail(IS_DBUSMENU_COLLECTOR(collector));
 
439
 
 
440
        menu_key_t search_key = {
 
441
                sender: (gchar *)dbus_addr,
 
442
                path:   (gchar *)dbus_path
 
443
        };
 
444
 
 
445
        gpointer found = g_hash_table_lookup(collector->priv->hash, &search_key);
 
446
        if (found == NULL) {
 
447
                g_warning("Unable to find dbusmenu client: %s:%s", dbus_addr, dbus_path);
 
448
                return;
 
449
        }
 
450
 
 
451
        DbusmenuMenuitem * root = dbusmenu_client_get_root(DBUSMENU_CLIENT(found));
 
452
        if (root == NULL) {
 
453
                g_warning("Dbusmenu Client %s:%s has no menuitems", dbus_addr, dbus_path);
 
454
                return;
 
455
        }
 
456
 
 
457
        DbusmenuMenuitem * item = dbusmenu_menuitem_find_id(root, id);
 
458
        if (item == NULL) {
 
459
                g_warning("Unable to find menuitem %d on client %s:%s", id, dbus_addr, dbus_path);
 
460
                return;
 
461
        }
 
462
 
 
463
        g_debug("Executing menuitem %d: %s", id, dbusmenu_menuitem_property_get(item, DBUSMENU_MENUITEM_PROP_LABEL));
 
464
        dbusmenu_menuitem_handle_event(item, DBUSMENU_MENUITEM_EVENT_ACTIVATED, NULL, timestamp);
 
465
 
 
466
        return;
 
467
}
 
468
 
 
469
guint
 
470
dbusmenu_collector_found_get_distance (DbusmenuCollectorFound * found)
 
471
{
 
472
        g_return_val_if_fail(found != NULL, G_MAXUINT);
 
473
        return found->distance;
 
474
}
 
475
 
 
476
const gchar *
 
477
dbusmenu_collector_found_get_display (DbusmenuCollectorFound * found)
 
478
{
 
479
        g_return_val_if_fail(found != NULL, NULL);
 
480
        return found->display_string;
 
481
}
 
482
 
 
483
const gchar *
 
484
dbusmenu_collector_found_get_db (DbusmenuCollectorFound * found)
 
485
{
 
486
        g_return_val_if_fail(found != NULL, NULL);
 
487
        return found->db_string;
 
488
}
 
489
 
 
490
void
 
491
dbusmenu_collector_found_list_free (GList * found_list)
 
492
{
 
493
        g_list_free_full(found_list, (GDestroyNotify)dbusmenu_collector_found_free);
 
494
        return;
 
495
}
 
496
 
 
497
static DbusmenuCollectorFound *
 
498
dbusmenu_collector_found_new (DbusmenuClient * client, DbusmenuMenuitem * item, GStrv strings, guint distance, GStrv usedstrings, const gchar * indicator_name)
 
499
{
 
500
        // g_debug("New Found: '%s', %d, '%s'", string, distance, indicator_name);
 
501
        DbusmenuCollectorFound * found = g_new0(DbusmenuCollectorFound, 1);
 
502
 
 
503
        g_object_get(client,
 
504
                     DBUSMENU_CLIENT_PROP_DBUS_NAME, &found->dbus_addr,
 
505
                     DBUSMENU_CLIENT_PROP_DBUS_OBJECT, &found->dbus_path,
 
506
                     NULL);
 
507
        found->dbus_id = dbusmenu_menuitem_get_id(item);
 
508
 
 
509
        found->db_string = g_strjoinv(DB_SEPARATOR, strings);
 
510
        found->distance = distance;
 
511
        found->item = item;
 
512
        found->indicator = NULL;
 
513
 
 
514
        found->display_string = NULL;
 
515
        if (strings != NULL) {
 
516
                static gchar * connector = NULL;
 
517
 
 
518
                if (connector == NULL) {
 
519
                        /* TRANSLATORS: This string is a printf format string to build
 
520
                           a string representing menu hierarchy in an application.  The
 
521
                           strings are <top> <separator> <bottom>.  So if the separator
 
522
                           is ">" and the item is "Open" in the "File" menu the final
 
523
                           string would be "File > Open" */
 
524
                        connector = g_markup_escape_text(_("%s > %s"), -1);
 
525
                }
 
526
 
 
527
                gchar * firstunderline = remove_underline(strings[0]);
 
528
                found->display_string = g_markup_escape_text(firstunderline, -1);
 
529
                g_free(firstunderline);
 
530
                int i;
 
531
                for (i = 1; strings[i] != NULL; i++) {
 
532
                        gchar * nounder = remove_underline(strings[i]);
 
533
                        gchar * escaped = g_markup_escape_text(nounder, -1);
 
534
                        gchar * tmp = g_strdup_printf(connector, found->display_string, escaped);
 
535
                        g_free(found->display_string);
 
536
                        g_free(escaped);
 
537
                        g_free(nounder);
 
538
                        found->display_string = tmp;
 
539
                }
 
540
 
 
541
                /* NOTE: Should probably find some way to use remalloc here, not sure
 
542
                   how to do that with the escaping and the translated connector
 
543
                   though.  Will take some thinking. */
 
544
        }
 
545
 
 
546
        if (found->display_string != NULL && usedstrings != NULL) {
 
547
                int str;
 
548
                for (str = 0; usedstrings[str] != NULL; str++) {
 
549
                        if (usedstrings[str][0] == '\0') continue; // No NULL strings
 
550
                        gchar * nounder = remove_underline(usedstrings[str]);
 
551
                        GStrv split = g_strsplit(found->display_string, nounder, -1);
 
552
                        gchar * bold = g_strconcat("<b>", nounder, "</b>", NULL);
 
553
                        gchar * tmp = g_strjoinv(bold, split);
 
554
 
 
555
                        g_free(found->display_string);
 
556
                        found->display_string = tmp;
 
557
 
 
558
                        g_strfreev(split);
 
559
                        g_free(bold);
 
560
                        g_free(nounder);
 
561
                }
 
562
        }
 
563
 
 
564
        if (indicator_name != NULL) {
 
565
                found->indicator = g_strdup(indicator_name);
 
566
        }
 
567
 
 
568
        g_object_ref(G_OBJECT(item));
 
569
 
 
570
        return found;
 
571
}
 
572
 
 
573
void
 
574
dbusmenu_collector_found_free (DbusmenuCollectorFound * found)
 
575
{
 
576
        g_return_if_fail(found != NULL);
 
577
        g_free(found->dbus_addr);
 
578
        g_free(found->dbus_path);
 
579
        g_free(found->display_string);
 
580
        g_free(found->db_string);
 
581
        g_free(found->indicator);
 
582
        g_object_unref(found->item);
 
583
        g_free(found);
 
584
        return;
 
585
}
 
586
 
 
587
const gchar *
 
588
dbusmenu_collector_found_get_indicator (DbusmenuCollectorFound * found)
 
589
{
 
590
        // g_debug("Getting indicator for found '%s', indicator: '%s'", found->display_string, found->indicator);
 
591
        g_return_val_if_fail(found != NULL, NULL);
 
592
        return found->indicator;
 
593
}
 
594
 
 
595
const gchar *
 
596
dbusmenu_collector_found_get_dbus_addr (DbusmenuCollectorFound * found)
 
597
{
 
598
        g_return_val_if_fail(found != NULL, NULL);
 
599
        return found->dbus_addr;
 
600
}
 
601
 
 
602
const gchar *
 
603
dbusmenu_collector_found_get_dbus_path (DbusmenuCollectorFound * found)
 
604
{
 
605
        g_return_val_if_fail(found != NULL, NULL);
 
606
        return found->dbus_path;
 
607
}
 
608
 
 
609
gint
 
610
dbusmenu_collector_found_get_dbus_id (DbusmenuCollectorFound * found)
 
611
{
 
612
        g_return_val_if_fail(found != NULL, -1);
 
613
        return found->dbus_id;
 
614
}