diff options
Diffstat (limited to 'src/idousermenuitem.c')
-rw-r--r-- | src/idousermenuitem.c | 182 |
1 files changed, 122 insertions, 60 deletions
diff --git a/src/idousermenuitem.c b/src/idousermenuitem.c index 655ae21..ab95d66 100644 --- a/src/idousermenuitem.c +++ b/src/idousermenuitem.c @@ -342,6 +342,86 @@ ido_user_menu_item_new (void) return GTK_WIDGET (g_object_new (IDO_USER_MENU_ITEM_TYPE, NULL)); } +/*** +**** +***/ + +/** + * This is a helper function for creating user menuitems for both + * "indicator.user-menu-item" and "indicator.guest-menu-item", + * since they only differ in how they use their action's state. + */ +static GtkMenuItem * +user_menu_item_new_from_model (GMenuItem * menuitem, + GActionGroup * actions, + GCallback state_changed_callback) +{ + guint i; + guint n; + IdoUserMenuItem * ido_user; + gchar * str; + gchar * action; + GVariant * v; + GParameter parameters[4]; + + /* create the ido_user */ + + n = 0; + + if (g_menu_item_get_attribute (menuitem, G_MENU_ATTRIBUTE_LABEL, "s", &str)) + { + GParameter p = { "label", G_VALUE_INIT }; + g_value_init (&p.value, G_TYPE_STRING); + g_value_take_string (&p.value, str); + parameters[n++] = p; + } + + if ((v = g_menu_item_get_attribute_value (menuitem, G_MENU_ATTRIBUTE_ICON, NULL))) + { + GParameter p = { "icon", G_VALUE_INIT }; + GIcon * icon = g_icon_deserialize (v); + g_value_init (&p.value, G_TYPE_OBJECT); + g_value_take_object (&p.value, icon); + g_variant_unref (v); + parameters[n++] = p; + } + + g_assert (n <= G_N_ELEMENTS (parameters)); + ido_user = g_object_newv (IDO_USER_MENU_ITEM_TYPE, n, parameters); + + for (i=0; i<n; i++) + g_value_unset (¶meters[i].value); + + /* gie it an ActionHelper */ + + if (g_menu_item_get_attribute (menuitem, G_MENU_ATTRIBUTE_ACTION, "s", &action)) + { + IdoActionHelper *helper; + GVariant *target; + + target = g_menu_item_get_attribute_value (menuitem, G_MENU_ATTRIBUTE_TARGET, G_VARIANT_TYPE_ANY); + + helper = ido_action_helper_new (GTK_WIDGET (ido_user), actions, action, target); + g_signal_connect (helper, "action-state-changed", + state_changed_callback, NULL); + + g_signal_connect_object (ido_user, "activate", + G_CALLBACK (ido_action_helper_activate), + helper, G_CONNECT_SWAPPED); + g_signal_connect_swapped (ido_user, "destroy", G_CALLBACK (g_object_unref), helper); + + if (target) + g_variant_unref (target); + g_free (action); + } + + return GTK_MENU_ITEM (ido_user); +} + +/*** +**** indicator.user-menu-item handler +***/ + /** * user_menu_item_state_changed: * @@ -355,22 +435,21 @@ user_menu_item_state_changed (IdoActionHelper *helper, GVariant *state, gpointer user_data) { + gboolean is_logged_in = FALSE; + gboolean is_current_user = FALSE; IdoUserMenuItem *item; GVariant *target; GVariant *v; item = IDO_USER_MENU_ITEM (ido_action_helper_get_widget (helper)); - ido_user_menu_item_set_current_user (item, FALSE); - ido_user_menu_item_set_logged_in (item, FALSE); - target = ido_action_helper_get_action_target (helper); g_return_if_fail (g_variant_is_of_type (target, G_VARIANT_TYPE_STRING)); if ((v = g_variant_lookup_value (state, "active-user", G_VARIANT_TYPE_STRING))) { if (g_variant_equal (v, target)) - ido_user_menu_item_set_current_user (item, TRUE); + is_current_user = TRUE; g_variant_unref (v); } @@ -384,12 +463,16 @@ user_menu_item_state_changed (IdoActionHelper *helper, while ((user = g_variant_iter_next_value (&it))) { if (g_variant_equal (user, target)) - ido_user_menu_item_set_logged_in (item, TRUE); + is_logged_in = TRUE; + g_variant_unref (user); } g_variant_unref (v); } + + ido_user_menu_item_set_logged_in (item, is_logged_in); + ido_user_menu_item_set_current_user (item, is_current_user); } /** @@ -404,65 +487,44 @@ GtkMenuItem * ido_user_menu_item_new_from_model (GMenuItem *menuitem, GActionGroup *actions) { - guint i; - guint n; - IdoUserMenuItem * ido_user; - gchar * str; - gchar * action; - GVariant * v; - GParameter parameters[4]; - - /* create the ido_user */ - - n = 0; - - if (g_menu_item_get_attribute (menuitem, "label", "s", &str)) - { - GParameter p = { "label", G_VALUE_INIT }; - g_value_init (&p.value, G_TYPE_STRING); - g_value_take_string (&p.value, str); - parameters[n++] = p; - } - - if ((v = g_menu_item_get_attribute_value (menuitem, G_MENU_ATTRIBUTE_ICON, NULL))) - { - GParameter p = { "icon", G_VALUE_INIT }; - GIcon * icon = g_icon_deserialize (v); - g_value_init (&p.value, G_TYPE_OBJECT); - g_value_take_object (&p.value, icon); - g_variant_unref (v); - parameters[n++] = p; - } - - g_assert (n <= G_N_ELEMENTS (parameters)); - ido_user = g_object_newv (IDO_USER_MENU_ITEM_TYPE, n, parameters); - - for (i=0; i<n; i++) - g_value_unset (¶meters[i].value); - - /* gie it an ActionHelper */ - - if (g_menu_item_get_attribute (menuitem, "action", "s", &action)) - { - IdoActionHelper *helper; - GVariant *target; + return user_menu_item_new_from_model (menuitem, + actions, + G_CALLBACK(user_menu_item_state_changed)); +} - target = g_menu_item_get_attribute_value (menuitem, "target", G_VARIANT_TYPE_ANY); +/*** +**** indicator.guest-menu-item handler +***/ - helper = ido_action_helper_new (GTK_WIDGET (ido_user), actions, action, target); - g_signal_connect (helper, "action-state-changed", - G_CALLBACK (user_menu_item_state_changed), NULL); +static void +guest_menu_item_state_changed (IdoActionHelper *helper, + GVariant *state, + gpointer user_data) +{ + IdoUserMenuItem * item = IDO_USER_MENU_ITEM (ido_action_helper_get_widget (helper)); + gboolean b; - g_signal_connect_object (ido_user, "activate", - G_CALLBACK (ido_action_helper_activate), - helper, G_CONNECT_SWAPPED); - g_signal_connect_swapped (ido_user, "destroy", G_CALLBACK (g_object_unref), helper); + if ((g_variant_lookup (state, "is-active", "b", &b))) + ido_user_menu_item_set_current_user (item, b); - if (target) - g_variant_unref (target); - g_free (action); - } + if ((g_variant_lookup (state, "is-logged-in", "b", &b))) + ido_user_menu_item_set_current_user (item, b); +} - return GTK_MENU_ITEM (ido_user); +/** + * ido_guest_menu_item_new_from_model: + * + * Creates an #IdoUserMenuItem. If @menuitem contains an action, the + * widget is bound to that action in @actions. + * + * Returns: (transfer full): a new #IdoUserMenuItem + */ +GtkMenuItem * +ido_guest_menu_item_new_from_model (GMenuItem *menuitem, + GActionGroup *actions) +{ + return user_menu_item_new_from_model (menuitem, + actions, + G_CALLBACK(guest_menu_item_state_changed)); } |