~indicator-applet-developers/libindicator/trunk.16.10

338.1.1 by Ted Gould
Adding in license headers.
1
/*
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
2
 * A small test loader for loading indicators in test suites
3
 * and during development of them.
4
 *
5
 * Copyright 2009 Canonical Ltd.
6
 *
7
 * Authors:
8
 *   Ted Gould <ted@canonical.com>
9
 *   Lars Uebernickel <lars.uebernickel@canonical.com>
10
 *   Charles Kerr <charles.kerr@canonical.com>
11
 *
12
 * This library is free software; you can redistribute it and/or
13
 * modify it under the terms of the GNU General Public License
14
 * version 3.0 as published by the Free Software Foundation.
15
 *
16
 * This library is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License version 3.0 for more details.
20
 * 
21
 * You should have received a copy of the GNU General Public
22
 * License along with this library. If not, see
23
 * <http://www.gnu.org/licenses/>.
24
 */
333.1.1 by Ted Gould
Adding a small little tool to load an indicator from the command line.
25
26
#include <gtk/gtk.h>
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
27
#include <libido/libido.h>
333.1.1 by Ted Gould
Adding a small little tool to load an indicator from the command line.
28
#include <libindicator/indicator-object.h>
506.1.4 by Charles Kerr
more copyediting. why am I awake?
29
#if GTK_CHECK_VERSION (3,0,0)
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
30
 #include <libindicator/indicator-ng.h>
474.1.2 by Lars Uebernickel
Only build and use IndicatorNg in the gtk3 build
31
#endif
333.1.1 by Ted Gould
Adding a small little tool to load an indicator from the command line.
32
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
33
static GHashTable * entry_to_menu_item = NULL;
34
35
G_DEFINE_QUARK (indicator_loader, entry_data)
333.1.5 by Ted Gould
Adding support for removing entries
36
333.1.1 by Ted Gould
Adding a small little tool to load an indicator from the command line.
37
static void
377.1.4 by Ted Gould
Creating a callback on the loader to signal the event press down to the entry.
38
activate_entry (GtkWidget * widget, gpointer user_data)
39
{
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
40
  gpointer entry;
41
42
  g_return_if_fail (INDICATOR_IS_OBJECT(user_data));
43
44
  entry = g_object_get_qdata (G_OBJECT(widget), entry_data_quark());
45
46
  if (entry == NULL)
47
    {
48
      g_debug("Activation on: (null)");
49
    }
50
  else
51
    {
52
      indicator_object_entry_activate (INDICATOR_OBJECT(user_data),
53
                                       entry,
54
                                       gtk_get_current_event_time());
55
    }
377.1.4 by Ted Gould
Creating a callback on the loader to signal the event press down to the entry.
56
}
57
529.1.1 by Marco Trevisan (Treviño)
IndicatorLoader: add scroll-entry support
58
static void
59
scroll_entry (GtkWidget *widget, GdkEventScroll* event, gpointer user_data)
60
{
61
  gpointer entry;
62
63
  g_return_if_fail (INDICATOR_IS_OBJECT(user_data));
64
65
  entry = g_object_get_qdata (G_OBJECT(widget), entry_data_quark());
529.1.2 by Marco Trevisan (Treviño)
IndicatorLoader: convert gtk scroll events to indicator object events
66
  IndicatorScrollDirection direction = G_MAXINT;
67
68
  switch (event->direction)
69
    {
70
      case GDK_SCROLL_UP:
71
        direction = INDICATOR_OBJECT_SCROLL_UP;
72
        break;
73
      case GDK_SCROLL_DOWN:
74
        direction = INDICATOR_OBJECT_SCROLL_DOWN;
75
        break;
76
      case GDK_SCROLL_LEFT:
77
        direction = INDICATOR_OBJECT_SCROLL_LEFT;
78
        break;
79
      case GDK_SCROLL_RIGHT:
80
        direction = INDICATOR_OBJECT_SCROLL_RIGHT;
81
        break;
82
      default:
83
        break;
84
    }
529.1.1 by Marco Trevisan (Treviño)
IndicatorLoader: add scroll-entry support
85
86
  if (entry == NULL)
87
    {
88
      g_debug("Scroll on: (null)");
89
    }
529.1.2 by Marco Trevisan (Treviño)
IndicatorLoader: convert gtk scroll events to indicator object events
90
  else if (direction == G_MAXINT)
91
    {
92
      g_debug("Scroll direction not supported");
93
    }
529.1.1 by Marco Trevisan (Treviño)
IndicatorLoader: add scroll-entry support
94
  else
95
    {
96
      g_signal_emit_by_name(INDICATOR_OBJECT(user_data),
97
                            INDICATOR_OBJECT_SIGNAL_ENTRY_SCROLLED,
529.1.2 by Marco Trevisan (Treviño)
IndicatorLoader: convert gtk scroll events to indicator object events
98
                            entry, 1, direction);
529.1.1 by Marco Trevisan (Treviño)
IndicatorLoader: add scroll-entry support
99
    }
100
}
101
470.1.1 by Charles Kerr
remove the cloak/decloak widget logic
102
static GtkWidget*
103
create_menu_item (IndicatorObjectEntry * entry)
333.1.1 by Ted Gould
Adding a small little tool to load an indicator from the command line.
104
{
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
105
  GtkWidget * menu_item;
106
  GtkWidget * hbox;
506.1.3 by Charles Kerr
copyediting: fix linewraps
107
  gpointer w;
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
108
109
  menu_item = gtk_menu_item_new();
110
111
#if GTK_CHECK_VERSION (3,0,0)
112
  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
416.1.1 by Ted Gould
Handling the right box for the right version of GTK
113
#else
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
114
  hbox = gtk_hbox_new (FALSE, 3);
416.1.1 by Ted Gould
Handling the right box for the right version of GTK
115
#endif
333.1.3 by Ted Gould
Grabbing the entry added function as well, didn't realize how much it did :)
116
506.1.3 by Charles Kerr
copyediting: fix linewraps
117
  if ((w = entry->image))
506.1.4 by Charles Kerr
more copyediting. why am I awake?
118
    gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET(w), FALSE, FALSE, 0);
506.1.3 by Charles Kerr
copyediting: fix linewraps
119
  if ((w = entry->label))
506.1.4 by Charles Kerr
more copyediting. why am I awake?
120
    gtk_box_pack_start (GTK_BOX (hbox), GTK_WIDGET(w), FALSE, FALSE, 0);
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
121
122
  gtk_container_add (GTK_CONTAINER(menu_item), hbox);
123
  gtk_widget_show (hbox);
124
506.1.3 by Charles Kerr
copyediting: fix linewraps
125
  if ((w = entry->menu))
126
    gtk_menu_item_set_submenu (GTK_MENU_ITEM(menu_item), GTK_WIDGET(w));
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
127
128
  return menu_item;
333.1.5 by Ted Gould
Adding support for removing entries
129
}
130
131
static void
506.1.3 by Charles Kerr
copyediting: fix linewraps
132
entry_added (IndicatorObject      * io,
133
             IndicatorObjectEntry * entry,
134
             gpointer               user_data)
333.1.5 by Ted Gould
Adding support for removing entries
135
{
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
136
  GtkWidget * menu_item;
137
138
  g_debug ("Signal: Entry Added");
139
506.1.4 by Charles Kerr
more copyediting. why am I awake?
140
  g_warn_if_fail (entry->parent_object != NULL);
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
141
142
  menu_item = g_hash_table_lookup (entry_to_menu_item, entry);
143
144
  if (menu_item == NULL)
145
    {
506.1.3 by Charles Kerr
copyediting: fix linewraps
146
      g_debug ("creating a menuitem for new entry %p", entry);
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
147
      menu_item = create_menu_item (entry);
148
      g_hash_table_insert (entry_to_menu_item, entry, menu_item);
149
150
      g_object_set_qdata (G_OBJECT(menu_item), entry_data_quark(), entry);
506.1.3 by Charles Kerr
copyediting: fix linewraps
151
      g_signal_connect (menu_item, "activate", G_CALLBACK(activate_entry), io);
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
152
529.1.1 by Marco Trevisan (Treviño)
IndicatorLoader: add scroll-entry support
153
      gtk_widget_set_events (menu_item, gtk_widget_get_events (menu_item) | GDK_SCROLL_MASK);
154
      g_signal_connect (menu_item, "scroll-event", G_CALLBACK(scroll_entry), io);
155
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
156
      gtk_menu_shell_append (GTK_MENU_SHELL(user_data), menu_item);
157
    }
158
159
  gtk_widget_show (menu_item);
333.1.1 by Ted Gould
Adding a small little tool to load an indicator from the command line.
160
}
161
162
static void 
506.1.3 by Charles Kerr
copyediting: fix linewraps
163
entry_removed (IndicatorObject      * io,
164
               IndicatorObjectEntry * entry,
165
               gpointer               user_data)
333.1.1 by Ted Gould
Adding a small little tool to load an indicator from the command line.
166
{
506.1.4 by Charles Kerr
more copyediting. why am I awake?
167
  GtkWidget * w;
168
506.1.3 by Charles Kerr
copyediting: fix linewraps
169
  g_debug ("Signal: Entry Removed");
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
170
506.1.4 by Charles Kerr
more copyediting. why am I awake?
171
  if ((w = g_hash_table_lookup (entry_to_menu_item, entry)))
172
    gtk_widget_hide (w);
333.1.1 by Ted Gould
Adding a small little tool to load an indicator from the command line.
173
}
174
375.1.1 by Ted Gould
Putting a printout in for showing menus.
175
static void
506.1.3 by Charles Kerr
copyediting: fix linewraps
176
menu_show (IndicatorObject      * io,
177
           IndicatorObjectEntry * entry,
178
           guint                  timestamp,
179
           gpointer               user_data)
375.1.1 by Ted Gould
Putting a printout in for showing menus.
180
{
506.1.3 by Charles Kerr
copyediting: fix linewraps
181
  const char * text;
182
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
183
  if (entry == NULL)
506.1.3 by Charles Kerr
copyediting: fix linewraps
184
    text = "(null)";
185
  else if (entry->label == NULL)
186
    text = "(no label)";
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
187
  else
506.1.3 by Charles Kerr
copyediting: fix linewraps
188
    text = gtk_label_get_text (entry->label);
189
190
  g_debug ("Show Menu: %s", text);
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
191
}
192
193
/***
194
****
195
***/
196
197
static IndicatorObject *
198
load_module (const gchar * file_name)
199
{
200
  IndicatorObject * io = NULL;
201
202
  if (file_name && g_str_has_suffix (file_name, G_MODULE_SUFFIX))
203
    {
204
      io = indicator_object_new_from_file (file_name);
205
206
      if (io == NULL)
207
        g_warning ("could not load indicator from '%s'", file_name);
208
    }
209
210
  return io;
211
}
212
213
static IndicatorObject *
214
load_profile (const char * file_name, const char * profile)
215
{
216
  IndicatorObject * io = NULL;
217
506.1.4 by Charles Kerr
more copyediting. why am I awake?
218
#if GTK_CHECK_VERSION (3,0,0)
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
219
220
  GError * error = NULL;
221
506.1.3 by Charles Kerr
copyediting: fix linewraps
222
  io = INDICATOR_OBJECT (indicator_ng_new_for_profile (file_name,
223
                                                       profile,
224
                                                       &error));
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
225
  if (error != NULL)
226
    {
506.1.3 by Charles Kerr
copyediting: fix linewraps
227
      g_warning ("couldn't load profile '%s' from '%s': %s",
228
                 profile, file_name, error->message);
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
229
      g_error_free (error);
230
    }
231
489.2.2 by Lars Uebernickel
IndicatorNg: update indicator file format
232
#endif
333.1.1 by Ted Gould
Adding a small little tool to load an indicator from the command line.
233
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
234
  return io;
235
}
236
237
/***
238
****
239
***/
240
241
static void
242
add_indicator_to_menu (GtkMenuShell * menu_shell, IndicatorObject * io)
243
{
244
  GList * entries;
245
  GList * entry;
246
247
  g_return_if_fail (INDICATOR_IS_OBJECT (io));
248
249
  /* connect to its signals */
506.1.3 by Charles Kerr
copyediting: fix linewraps
250
  g_signal_connect (io, INDICATOR_OBJECT_SIGNAL_ENTRY_ADDED,
251
                    G_CALLBACK(entry_added), menu_shell);
252
  g_signal_connect (io, INDICATOR_OBJECT_SIGNAL_ENTRY_REMOVED,
253
                    G_CALLBACK(entry_removed),  menu_shell);
254
  g_signal_connect (io, INDICATOR_OBJECT_SIGNAL_MENU_SHOW,
255
                    G_CALLBACK(menu_show), NULL);
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
256
257
  /* process the entries */
258
  entries = indicator_object_get_entries(io);
259
  for (entry=entries; entry!=NULL; entry=entry->next)
260
    entry_added (io, entry->data, menu_shell);
261
  g_list_free (entries);
262
}
263
264
static void
506.1.3 by Charles Kerr
copyediting: fix linewraps
265
add_menu_to_grid (GtkGrid    * grid,
266
                  int          top,
267
                  const char * text_,
268
                  GtkWidget  * menu)
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
269
{
270
  gchar * text;
271
  GtkWidget * label;
272
273
  text = g_strdup_printf ("%s:", text_);
274
  label = gtk_label_new (text);
275
  g_free (text);
276
277
  gtk_grid_attach (GTK_GRID(grid), label, 0, top, 1, 1);
278
  gtk_grid_attach (GTK_GRID(grid), menu,  1, top, 1, 1);
279
280
  g_object_set (label, "halign", GTK_ALIGN_START,
281
                       "hexpand", FALSE,
282
                       "margin-right", 6,
283
                       "valign", GTK_ALIGN_CENTER,
284
                       NULL);
285
286
  g_object_set (menu, "halign", GTK_ALIGN_START,
506.1.4 by Charles Kerr
more copyediting. why am I awake?
287
                      "hexpand", TRUE,
288
                      NULL);
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
289
}
290
291
/***
292
****
293
***/
333.1.4 by Ted Gould
Stopping the app when the window closes.
294
333.1.1 by Ted Gould
Adding a small little tool to load an indicator from the command line.
295
int
296
main (int argc, char ** argv)
297
{
506.1.4 by Charles Kerr
more copyediting. why am I awake?
298
  int menu_count = 0;
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
299
  const gchar * file_name;
300
  gchar * base_name;
301
  GtkWidget * grid;
302
506.1.4 by Charles Kerr
more copyediting. why am I awake?
303
  if (argc != 2)
304
    {
305
      base_name = g_path_get_basename (argv[0]);
306
      g_warning ("Use: %s filename", base_name);
307
      g_free (base_name);
308
      return 0;
309
    }
310
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
311
  /* make sure we don't proxy to ourselves */
506.1.5 by Charles Kerr
explicitly set UBUNTU_MENUPROXY to 0
312
  g_setenv ("UBUNTU_MENUPROXY", "0", TRUE);
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
313
314
  gtk_init (&argc, &argv);
315
  ido_init ();
316
506.1.3 by Charles Kerr
copyediting: fix linewraps
317
  entry_to_menu_item = g_hash_table_new (g_direct_hash, g_direct_equal);
318
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
319
  file_name = argv[1];
320
321
  grid = g_object_new (GTK_TYPE_GRID, "margin", 4,
322
                                      "column-spacing", 6,
323
                                      "row-spacing", 12,
324
                                      NULL);
325
326
  /* if it's an old-style indicator... */
327
  if (g_str_has_suffix (file_name, G_MODULE_SUFFIX))
328
    {
329
      IndicatorObject * io = load_module (file_name);
330
      GtkWidget * menu = gtk_menu_bar_new ();
331
      add_indicator_to_menu (GTK_MENU_SHELL(menu), io);
332
      base_name = g_path_get_basename (file_name);
506.1.4 by Charles Kerr
more copyediting. why am I awake?
333
      add_menu_to_grid (GTK_GRID(grid), menu_count++, base_name, menu);
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
334
      g_free (base_name);
335
    }
336
  else /* treat it as a GMenu indicator's keyfile */
337
    {
338
      GError * error;
339
      GKeyFile * key_file;
340
341
      key_file = g_key_file_new ();
342
      error = NULL;
343
      g_key_file_load_from_file (key_file, file_name, G_KEY_FILE_NONE, &error);
344
      if (error != NULL)
345
        {
506.1.3 by Charles Kerr
copyediting: fix linewraps
346
          g_warning ("loading '%s' failed: %s", file_name, error->message);
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
347
          g_error_free (error);
348
        }
506.1.4 by Charles Kerr
more copyediting. why am I awake?
349
      else
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
350
        {
506.1.4 by Charles Kerr
more copyediting. why am I awake?
351
          gchar ** groups;
352
          int i;
353
354
          groups = g_key_file_get_groups (key_file, NULL);
355
          for (i=0; groups && groups[i]; i++)
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
356
            {
506.1.4 by Charles Kerr
more copyediting. why am I awake?
357
              const gchar * const profile = groups[i];
358
              IndicatorObject * io;
359
360
              if (!g_strcmp0 (profile, "Indicator Service"))
361
                continue;
362
363
              if ((io = load_profile (file_name, profile)))
364
                {
365
                  GtkWidget * menu = gtk_menu_bar_new ();
366
                  add_indicator_to_menu (GTK_MENU_SHELL(menu), io);
367
                  add_menu_to_grid (GTK_GRID(grid), menu_count++, profile, menu);
368
                }
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
369
            }
506.1.4 by Charles Kerr
more copyediting. why am I awake?
370
371
          g_strfreev (groups);
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
372
        }
506.1.2 by Charles Kerr
plug a keyfile leak
373
374
      g_key_file_free (key_file);
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
375
    }
376
506.1.4 by Charles Kerr
more copyediting. why am I awake?
377
  if (menu_count > 0)
378
    {
379
      GtkWidget * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
380
      base_name = g_path_get_basename (file_name);
381
      gtk_window_set_title (GTK_WINDOW(window), base_name);
382
      g_free (base_name);
383
      g_signal_connect (window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
384
      gtk_container_add (GTK_CONTAINER(window), grid);
385
      gtk_widget_show_all (window);
386
      gtk_main ();
387
    }
506.1.1 by Charles Kerr
in indicator-loader, show =all= the profiles
388
389
  /* cleanup */
390
  g_hash_table_destroy (entry_to_menu_item);
391
  return 0;
333.1.1 by Ted Gould
Adding a small little tool to load an indicator from the command line.
392
}