~larsu/ido/center-user-avatar

« back to all changes in this revision

Viewing changes to src/idousermenuitem.c

  • Committer: Tarmac
  • Author(s): Charles Kerr
  • Date: 2013-06-24 02:34:25 UTC
  • mfrom: (134.1.5 trunk)
  • Revision ID: tarmac-20130624023425-o5mx92dwt4xvkyfx
Adds support for the guest menuitem.

A guest menuitem is the same as a user menuitem except for how it uses its action's state, so instead of adding a new class, this patch adds a new factory method (ido_guest_menu_item_new_from_model) and private action state handler.

Approved by Ted Gould, PS Jenkins bot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
{
35
35
  PROP_0,
36
36
  PROP_LABEL,
37
 
  PROP_ICON_FILENAME,
 
37
  PROP_ICON,
38
38
  PROP_IS_LOGGED_IN,
39
39
  PROP_IS_CURRENT_USER,
40
40
  PROP_LAST
51
51
  gboolean is_logged_in;
52
52
  gboolean is_current_user;
53
53
  gchar * label;
54
 
  gchar * icon_filename;
 
54
  GIcon * icon;
55
55
};
56
56
 
57
57
G_DEFINE_TYPE (IdoUserMenuItem, ido_user_menu_item, GTK_TYPE_MENU_ITEM);
76
76
        g_value_set_string (value, self->priv->label);
77
77
        break;
78
78
 
79
 
      case PROP_ICON_FILENAME:
80
 
        g_value_set_string (value, self->priv->icon_filename);
 
79
      case PROP_ICON:
 
80
        g_value_set_object (value, self->priv->icon);
81
81
        break;
82
82
 
83
83
      case PROP_IS_LOGGED_IN:
108
108
        ido_user_menu_item_set_label (self, g_value_get_string (value));
109
109
        break;
110
110
 
111
 
      case PROP_ICON_FILENAME:
112
 
        ido_user_menu_item_set_icon (self, g_value_get_string (value));
 
111
      case PROP_ICON:
 
112
        ido_user_menu_item_set_icon (self, g_value_get_object (value));
113
113
        break;
114
114
 
115
115
      case PROP_IS_LOGGED_IN:
130
130
static void
131
131
my_dispose (GObject *object)
132
132
{
 
133
  IdoUserMenuItem * self = IDO_USER_MENU_ITEM (object);
 
134
 
 
135
  g_clear_object (&self->priv->icon);
 
136
 
133
137
  G_OBJECT_CLASS (ido_user_menu_item_parent_class)->dispose (object);
134
138
}
135
139
 
139
143
  IdoUserMenuItem * self = IDO_USER_MENU_ITEM (object);
140
144
 
141
145
  g_free (self->priv->label);
142
 
  g_free (self->priv->icon_filename);
143
146
 
144
147
  G_OBJECT_CLASS (ido_user_menu_item_parent_class)->finalize (object);
145
148
}
167
170
                                                "J. Random User",
168
171
                                                prop_flags);
169
172
 
170
 
  properties[PROP_ICON_FILENAME] = g_param_spec_string ("icon-filename",
171
 
                                                        "The icon's filename",
172
 
                                                        "The icon to display",
173
 
                                                        NULL,
174
 
                                                        prop_flags);
 
173
  properties[PROP_ICON] = g_param_spec_object ("icon",
 
174
                                               "Icon",
 
175
                                               "The user's GIcon",
 
176
                                               G_TYPE_OBJECT,
 
177
                                               prop_flags);
175
178
 
176
179
  properties[PROP_IS_LOGGED_IN] = g_param_spec_boolean ("is-logged-in",
177
180
                                                        "is logged in",
287
290
***/
288
291
 
289
292
void
290
 
ido_user_menu_item_set_icon (IdoUserMenuItem * self, const char * icon_filename)
 
293
ido_user_menu_item_set_icon (IdoUserMenuItem * self, GIcon * icon)
291
294
{
292
 
  gboolean updated = FALSE;
293
295
  IdoUserMenuItemPrivate * p = self->priv;
294
296
  GtkImage * image = GTK_IMAGE (p->user_image);
295
297
 
296
 
  /* make a private copy of the icon name */
297
 
  g_free (p->icon_filename);
298
 
  self->priv->icon_filename = g_strdup (icon_filename);
299
 
 
300
 
  /* now try to use it */
301
 
  if (icon_filename && *icon_filename)
302
 
    {
303
 
      int width = 18; /* arbitrary default values */
304
 
      int height = 18;
305
 
      GError * err = NULL;
306
 
      GdkPixbuf * pixbuf = NULL;
307
 
 
308
 
      /* load the image */
309
 
      gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height);
310
 
      pixbuf = gdk_pixbuf_new_from_file_at_size (icon_filename,
311
 
                                                 width, height, &err);
312
 
      if (err == NULL)
313
 
        {
314
 
          gtk_image_set_from_pixbuf (image, pixbuf);
315
 
          g_object_unref (pixbuf);
316
 
          updated = TRUE;
317
 
        }
318
 
      else
319
 
        {
320
 
          g_warning ("Couldn't load the image \"%s\": %s",
321
 
                     icon_filename, err->message);
322
 
          g_clear_error (&err);
323
 
        }
324
 
    }
325
 
 
326
 
  /* as a fallback, use the default user icon */
327
 
  if (!updated)
328
 
    {
329
 
      gtk_image_set_from_icon_name (image,
330
 
                                    FALLBACK_ICON_NAME,
331
 
                                    GTK_ICON_SIZE_MENU);
332
 
    }
 
298
  g_clear_object (&p->icon);
 
299
 
 
300
  if (icon != NULL)
 
301
    g_object_ref (icon);
 
302
  else
 
303
    icon = g_themed_icon_new_with_default_fallbacks (FALLBACK_ICON_NAME);
 
304
 
 
305
  gtk_image_set_from_gicon (image, icon, GTK_ICON_SIZE_MENU);
 
306
}
 
307
 
 
308
void
 
309
ido_user_menu_item_set_icon_from_file (IdoUserMenuItem * self, const char * filename)
 
310
{
 
311
  GFile * file = filename ? g_file_new_for_path (filename) : NULL;
 
312
  GIcon * icon = file ? g_file_icon_new (file) : NULL;
 
313
 
 
314
  ido_user_menu_item_set_icon (self, icon);
 
315
 
 
316
  g_clear_object (&icon);
 
317
  g_clear_object (&file);
333
318
}
334
319
 
335
320
void
357
342
  return GTK_WIDGET (g_object_new (IDO_USER_MENU_ITEM_TYPE, NULL));
358
343
}
359
344
 
 
345
/***
 
346
****
 
347
***/
 
348
 
 
349
/**
 
350
 * This is a helper function for creating user menuitems for both
 
351
 * "indicator.user-menu-item" and "indicator.guest-menu-item",
 
352
 * since they only differ in how they use their action's state.
 
353
 */
 
354
static GtkMenuItem *
 
355
user_menu_item_new_from_model (GMenuItem    * menuitem,
 
356
                               GActionGroup * actions,
 
357
                               GCallback      state_changed_callback)
 
358
{
 
359
  guint i;
 
360
  guint n;
 
361
  IdoUserMenuItem * ido_user;
 
362
  gchar * str;
 
363
  gchar * action;
 
364
  GVariant * v;
 
365
  GParameter parameters[4];
 
366
 
 
367
  /* create the ido_user */
 
368
 
 
369
  n = 0;
 
370
 
 
371
  if (g_menu_item_get_attribute (menuitem, G_MENU_ATTRIBUTE_LABEL, "s", &str))
 
372
    {
 
373
      GParameter p = { "label", G_VALUE_INIT };
 
374
      g_value_init (&p.value, G_TYPE_STRING);
 
375
      g_value_take_string (&p.value, str);
 
376
      parameters[n++] = p;
 
377
    }
 
378
 
 
379
  if ((v = g_menu_item_get_attribute_value (menuitem, G_MENU_ATTRIBUTE_ICON, NULL)))
 
380
    {
 
381
      GParameter p = { "icon", G_VALUE_INIT };
 
382
      GIcon * icon = g_icon_deserialize (v);
 
383
      g_value_init (&p.value, G_TYPE_OBJECT);
 
384
      g_value_take_object (&p.value, icon);
 
385
      g_variant_unref (v);
 
386
      parameters[n++] = p;
 
387
    }
 
388
 
 
389
  g_assert (n <= G_N_ELEMENTS (parameters));
 
390
  ido_user = g_object_newv (IDO_USER_MENU_ITEM_TYPE, n, parameters);
 
391
 
 
392
  for (i=0; i<n; i++)
 
393
    g_value_unset (&parameters[i].value);
 
394
 
 
395
  /* gie it an ActionHelper */
 
396
 
 
397
  if (g_menu_item_get_attribute (menuitem, G_MENU_ATTRIBUTE_ACTION, "s", &action))
 
398
    {
 
399
      IdoActionHelper *helper;
 
400
      GVariant *target;
 
401
 
 
402
      target = g_menu_item_get_attribute_value (menuitem, G_MENU_ATTRIBUTE_TARGET, G_VARIANT_TYPE_ANY);
 
403
 
 
404
      helper = ido_action_helper_new (GTK_WIDGET (ido_user), actions, action, target);
 
405
      g_signal_connect (helper, "action-state-changed",
 
406
                        state_changed_callback, NULL);
 
407
 
 
408
      g_signal_connect_object (ido_user, "activate",
 
409
                               G_CALLBACK (ido_action_helper_activate),
 
410
                               helper, G_CONNECT_SWAPPED);
 
411
      g_signal_connect_swapped (ido_user, "destroy", G_CALLBACK (g_object_unref), helper);
 
412
 
 
413
      if (target)
 
414
        g_variant_unref (target);
 
415
      g_free (action);
 
416
    }
 
417
 
 
418
  return GTK_MENU_ITEM (ido_user);
 
419
}
 
420
 
 
421
/***
 
422
****  indicator.user-menu-item handler
 
423
***/
 
424
 
360
425
/**
361
426
 * user_menu_item_state_changed:
362
427
 *
370
435
                              GVariant        *state,
371
436
                              gpointer         user_data)
372
437
{
 
438
  gboolean is_logged_in = FALSE;
 
439
  gboolean is_current_user = FALSE;
373
440
  IdoUserMenuItem *item;
374
441
  GVariant *target;
375
442
  GVariant *v;
376
443
 
377
444
  item = IDO_USER_MENU_ITEM (ido_action_helper_get_widget (helper));
378
445
 
379
 
  ido_user_menu_item_set_current_user (item, FALSE);
380
 
  ido_user_menu_item_set_logged_in (item, FALSE);
381
 
 
382
446
  target = ido_action_helper_get_action_target (helper);
383
447
  g_return_if_fail (g_variant_is_of_type (target, G_VARIANT_TYPE_STRING));
384
448
 
385
449
  if ((v = g_variant_lookup_value (state, "active-user", G_VARIANT_TYPE_STRING)))
386
450
    {
387
451
      if (g_variant_equal (v, target))
388
 
        ido_user_menu_item_set_current_user (item, TRUE);
 
452
        is_current_user = TRUE;
389
453
 
390
454
      g_variant_unref (v);
391
455
    }
399
463
      while ((user = g_variant_iter_next_value (&it)))
400
464
        {
401
465
          if (g_variant_equal (user, target))
402
 
            ido_user_menu_item_set_logged_in (item, TRUE);
 
466
            is_logged_in = TRUE;
 
467
 
403
468
          g_variant_unref (user);
404
469
        }
405
470
 
406
471
      g_variant_unref (v);
407
472
    }
 
473
 
 
474
  ido_user_menu_item_set_logged_in (item, is_logged_in);
 
475
  ido_user_menu_item_set_current_user (item, is_current_user);
408
476
}
409
477
 
410
478
/**
419
487
ido_user_menu_item_new_from_model (GMenuItem    *menuitem,
420
488
                                   GActionGroup *actions)
421
489
{
422
 
  IdoUserMenuItem *item;
423
 
  gchar *label;
424
 
  gchar *action;
425
 
 
426
 
  item = IDO_USER_MENU_ITEM (ido_user_menu_item_new ());
427
 
 
428
 
  if (g_menu_item_get_attribute (menuitem, "label", "s", &label))
429
 
    {
430
 
      ido_user_menu_item_set_label (item, label);
431
 
      g_free (label);
432
 
    }
433
 
 
434
 
  if (g_menu_item_get_attribute (menuitem, "action", "s", &action))
435
 
    {
436
 
      IdoActionHelper *helper;
437
 
      GVariant *target;
438
 
 
439
 
      target = g_menu_item_get_attribute_value (menuitem, "target", G_VARIANT_TYPE_ANY);
440
 
 
441
 
      helper = ido_action_helper_new (GTK_WIDGET (item), actions, action, target);
442
 
      g_signal_connect (helper, "action-state-changed",
443
 
                        G_CALLBACK (user_menu_item_state_changed), NULL);
444
 
 
445
 
      g_signal_connect_object (item, "activate",
446
 
                               G_CALLBACK (ido_action_helper_activate),
447
 
                               helper, G_CONNECT_SWAPPED);
448
 
      g_signal_connect_swapped (item, "destroy", G_CALLBACK (g_object_unref), helper);
449
 
 
450
 
      if (target)
451
 
        g_variant_unref (target);
452
 
      g_free (action);
453
 
    }
454
 
 
455
 
  return GTK_MENU_ITEM (item);
 
490
  return user_menu_item_new_from_model (menuitem,
 
491
                                        actions,
 
492
                                        G_CALLBACK(user_menu_item_state_changed));
 
493
}
 
494
 
 
495
/***
 
496
****  indicator.guest-menu-item handler
 
497
***/
 
498
 
 
499
static void
 
500
guest_menu_item_state_changed (IdoActionHelper *helper,
 
501
                               GVariant        *state,
 
502
                               gpointer         user_data)
 
503
{
 
504
  IdoUserMenuItem * item = IDO_USER_MENU_ITEM (ido_action_helper_get_widget (helper));
 
505
  gboolean b;
 
506
 
 
507
  if ((g_variant_lookup (state, "is-active", "b", &b)))
 
508
    ido_user_menu_item_set_current_user (item, b);
 
509
 
 
510
  if ((g_variant_lookup (state, "is-logged-in", "b", &b)))
 
511
    ido_user_menu_item_set_current_user (item, b);
 
512
}
 
513
 
 
514
/**
 
515
 * ido_guest_menu_item_new_from_model:
 
516
 *
 
517
 * Creates an #IdoUserMenuItem. If @menuitem contains an action, the
 
518
 * widget is bound to that action in @actions.
 
519
 *
 
520
 * Returns: (transfer full): a new #IdoUserMenuItem
 
521
 */
 
522
GtkMenuItem *
 
523
ido_guest_menu_item_new_from_model (GMenuItem    *menuitem,
 
524
                                    GActionGroup *actions)
 
525
{
 
526
  return user_menu_item_new_from_model (menuitem,
 
527
                                        actions,
 
528
                                        G_CALLBACK(guest_menu_item_state_changed));
456
529
}
457
530