~3v1n0/ido/parent-signals-disconnection-trusty

126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
1
/*
2
Copyright 2011 Canonical Ltd.
3
4
Authors:
5
    Conor Curran <conor.curran@canonical.com>
6
    Mirco Müller <mirco.mueller@canonical.com>
7
    Charles Kerr <charles.kerr@canonical.com>
8
9
This program is free software: you can redistribute it and/or modify it
10
under the terms of the GNU General Public License version 3, as published
11
by the Free Software Foundation.
12
13
This program is distributed in the hope that it will be useful, but
14
WITHOUT ANY WARRANTY; without even the implied warranties of
15
MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
16
PURPOSE.  See the GNU General Public License for more details.
17
18
You should have received a copy of the GNU General Public License along
19
with this program.  If not, see <http://www.gnu.org/licenses/>.
20
*/
21
22
#ifdef HAVE_CONFIG_H
23
 #include "config.h"
24
#endif
25
26
#include <gtk/gtk.h>
27
126.2.2 by Charles Kerr
rename user-widget.[ch] to idousermenuitem.[ch]. Not building yet, next step is to decouple from dbusmenu.
28
#include "idousermenuitem.h"
126.1.9 by Lars Uebernickel
Move crate_user_menu_item into idousermenuitem.c
29
#include "idoactionhelper.h"
126.2.2 by Charles Kerr
rename user-widget.[ch] to idousermenuitem.[ch]. Not building yet, next step is to decouple from dbusmenu.
30
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
31
#define FALLBACK_ICON_NAME "avatar-default"
32
33
enum
34
{
35
  PROP_0,
36
  PROP_LABEL,
134.1.1 by Charles Kerr
add an 'icon' property to idousermenuitem
37
  PROP_ICON,
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
38
  PROP_IS_LOGGED_IN,
39
  PROP_IS_CURRENT_USER,
40
  PROP_LAST
41
};
42
43
static GParamSpec *properties[PROP_LAST];
126.2.2 by Charles Kerr
rename user-widget.[ch] to idousermenuitem.[ch]. Not building yet, next step is to decouple from dbusmenu.
44
45
struct _IdoUserMenuItemPrivate
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
46
{
47
  GtkWidget* user_image;
48
  GtkWidget* user_name;
49
  GtkWidget* container;
50
  GtkWidget* tick_icon;
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
51
  gboolean is_logged_in;
52
  gboolean is_current_user;
53
  gchar * label;
134.1.1 by Charles Kerr
add an 'icon' property to idousermenuitem
54
  GIcon * icon;
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
55
};
56
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
57
G_DEFINE_TYPE (IdoUserMenuItem, ido_user_menu_item, GTK_TYPE_MENU_ITEM);
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
58
59
/* Prototypes */
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
60
static gboolean ido_user_menu_item_primitive_draw_cb_gtk_3 (GtkWidget * image,
61
                                                            cairo_t   * cr,
62
                                                            gpointer    gself);
63
137.1.2 by Charles Kerr
don't load the icon twice
64
/***
65
****  GObject virtual functions
66
***/
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
67
68
static void
69
my_get_property (GObject     * o,
70
                 guint         property_id,
71
                 GValue      * value,
72
                 GParamSpec  * pspec)
73
{
74
  IdoUserMenuItem * self = IDO_USER_MENU_ITEM (o);
75
76
  switch (property_id)
77
    {
78
      case PROP_LABEL:
79
        g_value_set_string (value, self->priv->label);
80
        break;
81
134.1.1 by Charles Kerr
add an 'icon' property to idousermenuitem
82
      case PROP_ICON:
83
        g_value_set_object (value, self->priv->icon);
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
84
        break;
85
86
      case PROP_IS_LOGGED_IN:
87
        g_value_set_boolean (value, self->priv->is_logged_in);
88
        break;
89
90
      case PROP_IS_CURRENT_USER:
91
        g_value_set_boolean (value, self->priv->is_current_user);
92
        break;
93
94
      default:
95
        G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec);
96
        break;
97
    }
98
}
99
100
static void
101
my_set_property (GObject       * o,
102
                 guint           property_id,
103
                 const GValue  * value,
104
                 GParamSpec    * pspec)
105
{
106
  IdoUserMenuItem * self = IDO_USER_MENU_ITEM (o);
107
108
  switch (property_id)
109
    {
110
      case PROP_LABEL:
111
        ido_user_menu_item_set_label (self, g_value_get_string (value));
112
        break;
113
134.1.1 by Charles Kerr
add an 'icon' property to idousermenuitem
114
      case PROP_ICON:
115
        ido_user_menu_item_set_icon (self, g_value_get_object (value));
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
116
        break;
117
118
      case PROP_IS_LOGGED_IN:
119
        ido_user_menu_item_set_logged_in (self, g_value_get_boolean (value));
120
        break;
121
122
      case PROP_IS_CURRENT_USER:
123
        self->priv->is_current_user = g_value_get_boolean (value);
124
        gtk_widget_queue_draw (GTK_WIDGET(self));
125
        break;
126
127
      default:
128
        G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec);
129
        break;
130
    }
131
}
132
133
static void
134
my_dispose (GObject *object)
135
{
134.1.1 by Charles Kerr
add an 'icon' property to idousermenuitem
136
  IdoUserMenuItem * self = IDO_USER_MENU_ITEM (object);
137
138
  g_clear_object (&self->priv->icon);
139
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
140
  G_OBJECT_CLASS (ido_user_menu_item_parent_class)->dispose (object);
141
}
142
143
static void
144
my_finalize (GObject *object)
145
{
146
  IdoUserMenuItem * self = IDO_USER_MENU_ITEM (object);
147
148
  g_free (self->priv->label);
149
150
  G_OBJECT_CLASS (ido_user_menu_item_parent_class)->finalize (object);
151
}
152
153
static void
154
ido_user_menu_item_class_init (IdoUserMenuItemClass *klass)
155
{
156
  GParamFlags prop_flags;
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
157
  GObjectClass * gobject_class = G_OBJECT_CLASS (klass);
158
126.2.2 by Charles Kerr
rename user-widget.[ch] to idousermenuitem.[ch]. Not building yet, next step is to decouple from dbusmenu.
159
  g_type_class_add_private (klass, sizeof (IdoUserMenuItemPrivate));
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
160
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
161
  gobject_class->get_property = my_get_property;
162
  gobject_class->set_property = my_set_property;
163
  gobject_class->dispose = my_dispose;
164
  gobject_class->finalize = my_finalize;
165
166
  prop_flags = G_PARAM_CONSTRUCT
167
             | G_PARAM_READWRITE
168
             | G_PARAM_STATIC_STRINGS;
169
170
  properties[PROP_LABEL] = g_param_spec_string ("label",
171
                                                "The user's name",
172
                                                "The name to display",
173
                                                "J. Random User",
174
                                                prop_flags);
175
134.1.1 by Charles Kerr
add an 'icon' property to idousermenuitem
176
  properties[PROP_ICON] = g_param_spec_object ("icon",
177
                                               "Icon",
178
                                               "The user's GIcon",
179
                                               G_TYPE_OBJECT,
180
                                               prop_flags);
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
181
182
  properties[PROP_IS_LOGGED_IN] = g_param_spec_boolean ("is-logged-in",
183
                                                        "is logged in",
184
                                                        "is user logged in?",
185
                                                        FALSE,
186
                                                        prop_flags);
187
188
  properties[PROP_IS_CURRENT_USER] = g_param_spec_boolean ("is-current-user",
189
                                                           "is current user",
190
                                                           "is user current?",
191
                                                           FALSE,
192
                                                           prop_flags);
193
194
  g_object_class_install_properties (gobject_class, PROP_LAST, properties);
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
195
}
196
197
static void
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
198
ido_user_menu_item_init (IdoUserMenuItem *self)
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
199
{
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
200
  IdoUserMenuItemPrivate * priv;
201
202
  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
203
                                            IDO_USER_MENU_ITEM_TYPE,
204
                                            IdoUserMenuItemPrivate);
205
206
  priv = self->priv;
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
207
208
  // Create the UI elements.
209
  priv->user_image = gtk_image_new ();
153.2.1 by Lars Uebernickel
IdoUserMenuItem: only allow file icons as avatars
210
  gtk_image_set_from_icon_name (GTK_IMAGE (priv->user_image),
211
                                FALLBACK_ICON_NAME,
212
                                GTK_ICON_SIZE_MENU);
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
213
214
  priv->user_name = gtk_label_new (NULL);
215
149.2.1 by Lars Uebernickel
idousermenuitem: center user avatars and adjust spacing
216
  priv->container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
217
218
  priv->tick_icon = gtk_image_new_from_icon_name ("account-logged-in",
219
                                                   GTK_ICON_SIZE_MENU);
220
  gtk_misc_set_alignment(GTK_MISC(priv->tick_icon), 1.0, 0.5);
221
222
  // Pack it together
223
  gtk_box_pack_start (GTK_BOX (priv->container),
224
                      priv->user_image,
225
                      FALSE,
149.2.1 by Lars Uebernickel
idousermenuitem: center user avatars and adjust spacing
226
                      TRUE,
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
227
                      0);
228
  gtk_box_pack_start (GTK_BOX (priv->container),
229
                      priv->user_name,
230
                      FALSE,
231
                      FALSE,
232
                      3);
233
  gtk_box_pack_end (GTK_BOX(priv->container),
234
                    priv->tick_icon,
235
                    FALSE,
236
                    FALSE, 5);
237
238
  gtk_widget_show_all (priv->container);
239
  gtk_container_add (GTK_CONTAINER (self), priv->container);
240
  gtk_widget_show_all (priv->tick_icon);
241
  gtk_widget_set_no_show_all (priv->tick_icon, TRUE);
242
  gtk_widget_hide (priv->tick_icon);
243
244
245
  // Fetch the drawing context.
246
  g_signal_connect_after (GTK_WIDGET(self), "draw",
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
247
                          G_CALLBACK(ido_user_menu_item_primitive_draw_cb_gtk_3),
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
248
                          GTK_WIDGET(self));
249
}
250
251
252
/*****************************************************************/
253
254
static gboolean
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
255
ido_user_menu_item_primitive_draw_cb_gtk_3 (GtkWidget * widget,
256
                                            cairo_t   * cr,
257
                                            gpointer    user_data)
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
258
{
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
259
  IdoUserMenuItemPrivate * priv;
260
261
  g_return_val_if_fail(IS_IDO_USER_MENU_ITEM(user_data), FALSE);
262
263
  priv = IDO_USER_MENU_ITEM(user_data)->priv;
264
265
  /* Draw dot only when user is the current user. */
266
  if (priv->is_current_user)
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
267
    {
126.2.5 by Charles Kerr
in ido_user_menu_item_primitive_draw_cb_gtk_3(), remove deprecated use of gtk_widget_get_style(), gtk_widget_get_state()
268
      GtkStyleContext * style_context;
269
      GtkStateFlags state_flags;
270
      GdkRGBA color;
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
271
      gdouble x, y;
126.2.5 by Charles Kerr
in ido_user_menu_item_primitive_draw_cb_gtk_3(), remove deprecated use of gtk_widget_get_style(), gtk_widget_get_state()
272
273
      /* get the foreground color */
274
      style_context = gtk_widget_get_style_context (widget);
275
      state_flags = gtk_widget_get_state_flags (widget);
276
      gtk_style_context_get_color (style_context, state_flags, &color);
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
277
278
      GtkAllocation allocation;
279
      gtk_widget_get_allocation (widget, &allocation);
280
      x = allocation.x + 13;
281
      y = allocation.height / 2;
282
283
      cairo_arc (cr, x, y, 3.0, 0.0, 2 * G_PI);
284
126.2.5 by Charles Kerr
in ido_user_menu_item_primitive_draw_cb_gtk_3(), remove deprecated use of gtk_widget_get_style(), gtk_widget_get_state()
285
      gdk_cairo_set_source_rgba (cr, &color);
286
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
287
      cairo_fill (cr);
288
    }
289
290
  return FALSE;
291
}
292
293
/***
153.2.1 by Lars Uebernickel
IdoUserMenuItem: only allow file icons as avatars
294
****  Avatar
295
***/
153.2.2 by Lars Uebernickel
Don't export ido_user_menu_item_set_icon_from_file_icon()
296
static gboolean
153.2.1 by Lars Uebernickel
IdoUserMenuItem: only allow file icons as avatars
297
ido_user_menu_item_set_icon_from_file_icon (IdoUserMenuItem *self,
298
                                            GFileIcon       *icon)
299
{
300
  GFile *file;
301
  gchar *path;
153.2.4 by Lars Uebernickel
ido_user_menu_item_set_icon_from_file_icon: don't initialize width and height
302
  gint width;
303
  gint height;
153.2.1 by Lars Uebernickel
IdoUserMenuItem: only allow file icons as avatars
304
  GdkPixbuf *pixbuf;
305
306
  file = g_file_icon_get_file (G_FILE_ICON (icon));
307
  path = g_file_get_path (file);
308
153.2.4 by Lars Uebernickel
ido_user_menu_item_set_icon_from_file_icon: don't initialize width and height
309
  /* width and height will always be set by this function */
153.2.1 by Lars Uebernickel
IdoUserMenuItem: only allow file icons as avatars
310
  gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (GTK_WIDGET (self)),
311
                                     GTK_ICON_SIZE_MENU,
312
                                     &width, &height);
313
314
  pixbuf = gdk_pixbuf_new_from_file_at_scale (path, width, height, TRUE, NULL);
315
  g_free (path);
316
317
  if (pixbuf)
318
    {
319
      gtk_image_set_from_pixbuf (GTK_IMAGE (self->priv->user_image), pixbuf);
320
      g_object_unref (pixbuf);
321
      return TRUE;
322
    }
323
324
  return FALSE;
325
}
326
327
/***
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
328
****  PUBLIC API
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
329
***/
330
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
331
void
134.1.1 by Charles Kerr
add an 'icon' property to idousermenuitem
332
ido_user_menu_item_set_icon (IdoUserMenuItem * self, GIcon * icon)
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
333
{
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
334
  IdoUserMenuItemPrivate * p = self->priv;
335
153.2.1 by Lars Uebernickel
IdoUserMenuItem: only allow file icons as avatars
336
  if (p->icon == icon)
337
    return;
338
339
  g_clear_object (&p->icon);
340
341
  if (icon)
342
    p->icon = g_object_ref (icon);
343
344
  /* Avatars are always loaded from disk. Show the fallback when no icon
345
   * is set, the icon is not a file icon, or the file could not be
346
   * found.
347
   */
348
  if (icon == NULL ||
349
      !G_IS_FILE_ICON (icon) ||
350
      !ido_user_menu_item_set_icon_from_file_icon (self, G_FILE_ICON (icon)))
137.1.1 by Charles Kerr
if a user's avatar icon file doesn't exist or isn't readable, fall back to the default avatar
351
    {
153.2.1 by Lars Uebernickel
IdoUserMenuItem: only allow file icons as avatars
352
      gtk_image_set_from_icon_name (GTK_IMAGE (p->user_image),
353
                                    FALLBACK_ICON_NAME,
354
                                    GTK_ICON_SIZE_MENU);
137.1.1 by Charles Kerr
if a user's avatar icon file doesn't exist or isn't readable, fall back to the default avatar
355
    }
134.1.1 by Charles Kerr
add an 'icon' property to idousermenuitem
356
}
357
358
void
359
ido_user_menu_item_set_icon_from_file (IdoUserMenuItem * self, const char * filename)
360
{
134.1.3 by Charles Kerr
silence console warnings when a NULL filename is passed into ido_user_menu_item_set_icon_from_filename()
361
  GFile * file = filename ? g_file_new_for_path (filename) : NULL;
362
  GIcon * icon = file ? g_file_icon_new (file) : NULL;
134.1.1 by Charles Kerr
add an 'icon' property to idousermenuitem
363
364
  ido_user_menu_item_set_icon (self, icon);
365
366
  g_clear_object (&icon);
367
  g_clear_object (&file);
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
368
}
369
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
370
void
371
ido_user_menu_item_set_logged_in (IdoUserMenuItem * self, gboolean is_logged_in)
372
{
373
  gtk_widget_set_visible (self->priv->tick_icon, is_logged_in);
374
}
375
376
void
377
ido_user_menu_item_set_current_user (IdoUserMenuItem * self, gboolean is_current_user)
378
{
379
  self->priv->is_current_user = is_current_user;
380
  gtk_widget_queue_draw (GTK_WIDGET (self));
381
}
382
383
void
384
ido_user_menu_item_set_label (IdoUserMenuItem * self, const char * label)
385
{
386
  gtk_label_set_label (GTK_LABEL(self->priv->user_name), label);
387
}
388
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
389
GtkWidget*
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
390
ido_user_menu_item_new (void)
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
391
{
126.2.3 by Charles Kerr
add properties to IdoUserMenuItem and remove its dependencies on DbusmenuMenuitem
392
  return GTK_WIDGET (g_object_new (IDO_USER_MENU_ITEM_TYPE, NULL));
126.2.1 by Charles Kerr
add user-widget.[ch] from indicator-session's trunk
393
}
126.1.9 by Lars Uebernickel
Move crate_user_menu_item into idousermenuitem.c
394
134.1.2 by Charles Kerr
add ido_guest_menu_item_new_for_model()
395
/***
396
****
397
***/
398
139.1.1 by Ted Gould
Fixing some small introspection errors
399
/*
134.1.2 by Charles Kerr
add ido_guest_menu_item_new_for_model()
400
 * This is a helper function for creating user menuitems for both
401
 * "indicator.user-menu-item" and "indicator.guest-menu-item",
402
 * since they only differ in how they use their action's state.
403
 */
404
static GtkMenuItem *
405
user_menu_item_new_from_model (GMenuItem    * menuitem,
406
                               GActionGroup * actions,
407
                               GCallback      state_changed_callback)
126.1.9 by Lars Uebernickel
Move crate_user_menu_item into idousermenuitem.c
408
{
134.1.1 by Charles Kerr
add an 'icon' property to idousermenuitem
409
  guint i;
410
  guint n;
411
  IdoUserMenuItem * ido_user;
412
  gchar * str;
413
  gchar * action;
414
  GVariant * v;
415
  GParameter parameters[4];
416
417
  /* create the ido_user */
418
419
  n = 0;
420
134.1.2 by Charles Kerr
add ido_guest_menu_item_new_for_model()
421
  if (g_menu_item_get_attribute (menuitem, G_MENU_ATTRIBUTE_LABEL, "s", &str))
134.1.1 by Charles Kerr
add an 'icon' property to idousermenuitem
422
    {
423
      GParameter p = { "label", G_VALUE_INIT };
424
      g_value_init (&p.value, G_TYPE_STRING);
425
      g_value_take_string (&p.value, str);
426
      parameters[n++] = p;
427
    }
428
429
  if ((v = g_menu_item_get_attribute_value (menuitem, G_MENU_ATTRIBUTE_ICON, NULL)))
430
    {
431
      GParameter p = { "icon", G_VALUE_INIT };
432
      GIcon * icon = g_icon_deserialize (v);
433
      g_value_init (&p.value, G_TYPE_OBJECT);
434
      g_value_take_object (&p.value, icon);
435
      g_variant_unref (v);
436
      parameters[n++] = p;
437
    }
438
439
  g_assert (n <= G_N_ELEMENTS (parameters));
440
  ido_user = g_object_newv (IDO_USER_MENU_ITEM_TYPE, n, parameters);
441
442
  for (i=0; i<n; i++)
443
    g_value_unset (&parameters[i].value);
444
445
  /* gie it an ActionHelper */
126.1.9 by Lars Uebernickel
Move crate_user_menu_item into idousermenuitem.c
446
134.1.2 by Charles Kerr
add ido_guest_menu_item_new_for_model()
447
  if (g_menu_item_get_attribute (menuitem, G_MENU_ATTRIBUTE_ACTION, "s", &action))
126.1.9 by Lars Uebernickel
Move crate_user_menu_item into idousermenuitem.c
448
    {
449
      IdoActionHelper *helper;
450
      GVariant *target;
451
134.1.2 by Charles Kerr
add ido_guest_menu_item_new_for_model()
452
      target = g_menu_item_get_attribute_value (menuitem, G_MENU_ATTRIBUTE_TARGET, G_VARIANT_TYPE_ANY);
126.1.9 by Lars Uebernickel
Move crate_user_menu_item into idousermenuitem.c
453
134.1.1 by Charles Kerr
add an 'icon' property to idousermenuitem
454
      helper = ido_action_helper_new (GTK_WIDGET (ido_user), actions, action, target);
126.1.9 by Lars Uebernickel
Move crate_user_menu_item into idousermenuitem.c
455
      g_signal_connect (helper, "action-state-changed",
134.1.2 by Charles Kerr
add ido_guest_menu_item_new_for_model()
456
                        state_changed_callback, NULL);
126.1.9 by Lars Uebernickel
Move crate_user_menu_item into idousermenuitem.c
457
134.1.1 by Charles Kerr
add an 'icon' property to idousermenuitem
458
      g_signal_connect_object (ido_user, "activate",
126.1.9 by Lars Uebernickel
Move crate_user_menu_item into idousermenuitem.c
459
                               G_CALLBACK (ido_action_helper_activate),
460
                               helper, G_CONNECT_SWAPPED);
134.1.1 by Charles Kerr
add an 'icon' property to idousermenuitem
461
      g_signal_connect_swapped (ido_user, "destroy", G_CALLBACK (g_object_unref), helper);
126.1.9 by Lars Uebernickel
Move crate_user_menu_item into idousermenuitem.c
462
463
      if (target)
464
        g_variant_unref (target);
465
      g_free (action);
466
    }
467
134.1.1 by Charles Kerr
add an 'icon' property to idousermenuitem
468
  return GTK_MENU_ITEM (ido_user);
126.1.9 by Lars Uebernickel
Move crate_user_menu_item into idousermenuitem.c
469
}
470
134.1.2 by Charles Kerr
add ido_guest_menu_item_new_for_model()
471
/***
472
****  indicator.user-menu-item handler
473
***/
474
475
/**
476
 * user_menu_item_state_changed:
477
 *
478
 * Updates an IdoUserMenuItem from @state. The state contains a
479
 * dictionary with keys 'active-user' (for the user that the current
480
 * session belongs too) and 'logged-in-users' (a list of all currently
481
 * logged in users).
482
 */
483
static void
484
user_menu_item_state_changed (IdoActionHelper *helper,
485
                              GVariant        *state,
486
                              gpointer         user_data)
487
{
488
  gboolean is_logged_in = FALSE;
489
  gboolean is_current_user = FALSE;
490
  IdoUserMenuItem *item;
491
  GVariant *target;
492
  GVariant *v;
493
494
  item = IDO_USER_MENU_ITEM (ido_action_helper_get_widget (helper));
495
496
  target = ido_action_helper_get_action_target (helper);
497
  g_return_if_fail (g_variant_is_of_type (target, G_VARIANT_TYPE_STRING));
498
499
  if ((v = g_variant_lookup_value (state, "active-user", G_VARIANT_TYPE_STRING)))
500
    {
501
      if (g_variant_equal (v, target))
502
        is_current_user = TRUE;
503
504
      g_variant_unref (v);
505
    }
506
507
  if ((v = g_variant_lookup_value (state, "logged-in-users", G_VARIANT_TYPE_STRING_ARRAY)))
508
    {
509
      GVariantIter it;
510
      GVariant *user;
511
512
      g_variant_iter_init (&it, v);
513
      while ((user = g_variant_iter_next_value (&it)))
514
        {
515
          if (g_variant_equal (user, target))
516
            is_logged_in = TRUE;
517
518
          g_variant_unref (user);
519
        }
520
521
      g_variant_unref (v);
522
    }
523
524
  ido_user_menu_item_set_logged_in (item, is_logged_in);
525
  ido_user_menu_item_set_current_user (item, is_current_user);
526
}
527
528
/**
529
 * ido_user_menu_item_new_from_model:
530
 *
531
 * Creates an #IdoUserMenuItem. If @menuitem contains an action, the
532
 * widget is bound to that action in @actions.
533
 *
534
 * Returns: (transfer full): a new #IdoUserMenuItem
535
 */
536
GtkMenuItem *
537
ido_user_menu_item_new_from_model (GMenuItem    *menuitem,
538
                                   GActionGroup *actions)
539
{
540
  return user_menu_item_new_from_model (menuitem,
541
                                        actions,
542
                                        G_CALLBACK(user_menu_item_state_changed));
543
}
544
545
/***
546
****  indicator.guest-menu-item handler
547
***/
548
549
static void
550
guest_menu_item_state_changed (IdoActionHelper *helper,
551
                               GVariant        *state,
552
                               gpointer         user_data)
553
{
554
  IdoUserMenuItem * item = IDO_USER_MENU_ITEM (ido_action_helper_get_widget (helper));
555
  gboolean b;
556
557
  if ((g_variant_lookup (state, "is-active", "b", &b)))
558
    ido_user_menu_item_set_current_user (item, b);
559
560
  if ((g_variant_lookup (state, "is-logged-in", "b", &b)))
135.1.1 by Charles Kerr
fix a copy-paste bug in the last commit's GuestMenuItem code
561
    ido_user_menu_item_set_logged_in (item, b);
134.1.2 by Charles Kerr
add ido_guest_menu_item_new_for_model()
562
}
563
564
/**
565
 * ido_guest_menu_item_new_from_model:
566
 *
567
 * Creates an #IdoUserMenuItem. If @menuitem contains an action, the
568
 * widget is bound to that action in @actions.
569
 *
570
 * Returns: (transfer full): a new #IdoUserMenuItem
571
 */
572
GtkMenuItem *
573
ido_guest_menu_item_new_from_model (GMenuItem    *menuitem,
574
                                    GActionGroup *actions)
575
{
576
  return user_menu_item_new_from_model (menuitem,
577
                                        actions,
578
                                        G_CALLBACK(guest_menu_item_state_changed));
579
}
580