From e8e99703ef0c565f07a9d1eba03c1003d82ff697 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 27 Nov 2012 15:14:26 +0100 Subject: Allow adding actions to MessagingMenuMessage --- libmessaging-menu/messaging-menu-app.c | 28 +---- libmessaging-menu/messaging-menu-message.c | 160 +++++++++++++++++++++++++++++ libmessaging-menu/messaging-menu-message.h | 6 ++ 3 files changed, 170 insertions(+), 24 deletions(-) (limited to 'libmessaging-menu') diff --git a/libmessaging-menu/messaging-menu-app.c b/libmessaging-menu/messaging-menu-app.c index d037da9..491c123 100644 --- a/libmessaging-menu/messaging-menu-app.c +++ b/libmessaging-menu/messaging-menu-app.c @@ -152,6 +152,9 @@ static void global_status_changed (IndicatorMessagesService *service, const gchar *status_str, gpointer user_data); +/* in messaging-menu-message.c */ +GVariant * messaging_menu_message_to_variant (MessagingMenuMessage *msg); + static void source_free (gpointer data) { @@ -188,29 +191,6 @@ source_to_variant (Source *source) return v; } -static GVariant * -messaging_menu_message_to_variant (MessagingMenuMessage *message) -{ - GVariant *v; - GIcon *icon; - gchar *iconstr; - - icon = messaging_menu_message_get_icon (message); - iconstr = icon ? g_icon_to_string (icon) : NULL; - - v = g_variant_new ("(sssssxb)", messaging_menu_message_get_id (message), - iconstr ? iconstr : "", - messaging_menu_message_get_title (message), - messaging_menu_message_get_subtitle (message), - messaging_menu_message_get_body (message), - messaging_menu_message_get_time (message), - messaging_menu_message_get_draws_attention (message)); - - g_free (iconstr); - - return v; -} - static gchar * messaging_menu_app_get_dbus_object_path (MessagingMenuApp *app) { @@ -571,7 +551,7 @@ messaging_menu_app_list_messages (IndicatorMessagesApplication *app_interface, GHashTableIter iter; MessagingMenuMessage *message; - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sssssxb)")); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sssssxa(ssgav)b)")); g_hash_table_iter_init (&iter, app->messages); while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &message)) diff --git a/libmessaging-menu/messaging-menu-message.c b/libmessaging-menu/messaging-menu-message.c index f5cb18c..cf050d3 100644 --- a/libmessaging-menu/messaging-menu-message.c +++ b/libmessaging-menu/messaging-menu-message.c @@ -32,6 +32,8 @@ struct _MessagingMenuMessage gchar *body; gint64 time; gboolean draws_attention; + + GSList *actions; }; G_DEFINE_TYPE (MessagingMenuMessage, messaging_menu_message, G_TYPE_OBJECT); @@ -51,6 +53,31 @@ enum static GParamSpec *properties[NUM_PROPERTIES]; +typedef struct +{ + gchar *id; + gchar *label; + GVariantType *parameter_type; + GVariant *parameter_hint; +} Action; + +static void +action_free (gpointer data) +{ + Action *action = data; + + g_free (action->id); + g_free (action->label); + + if (action->parameter_type) + g_variant_type_free (action->parameter_type); + + if (action->parameter_hint) + g_variant_unref (action->parameter_hint); + + g_slice_free (Action, action); +} + static void messaging_menu_message_dispose (GObject *object) { @@ -71,6 +98,9 @@ messaging_menu_message_finalize (GObject *object) g_free (msg->subtitle); g_free (msg->body); + g_slist_free_full (msg->actions, action_free); + msg->actions = NULL; + G_OBJECT_CLASS (messaging_menu_message_parent_class)->finalize (object); } @@ -370,3 +400,133 @@ messaging_menu_message_set_draws_attention (MessagingMenuMessage *msg, msg->draws_attention = draws_attention; g_object_notify_by_pspec (G_OBJECT (msg), properties[PROP_DRAWS_ATTENTION]); } + +/** + * messaging_menu_message_add_action: + * @msg: a #MessagingMenuMessage + * @id: unique id of the action + * @label: (allow-none): label of the action + * @parameter_type: (allow-none): a #GVariantType + * @parameter_hint: (allow-none): a #GVariant suggesting a valid range + * for parameters + * + * Adds an action with @id and @label to @message. Actions are an + * alternative way for users to activate a message. Note that messages + * can still be activated without an action. + * + * If @parameter_type is non-%NULL, the action is able to receive user + * input in addition to simply activating the action. Currently, only + * string parameters are supported. + * + * A list of predefined parameters can be supplied as a #GVariant array + * of @parameter_type in @parameter_hint. If @parameter_hint is + * floating, it will be consumed. + * + * It is recommended to add at most two actions to a message. + */ +void +messaging_menu_message_add_action (MessagingMenuMessage *msg, + const gchar *id, + const gchar *label, + const GVariantType *parameter_type, + GVariant *parameter_hint) +{ + Action *action; + + g_return_if_fail (MESSAGING_MENU_IS_MESSAGE (msg)); + g_return_if_fail (id != NULL); + + action = g_slice_new (Action); + action->id = g_strdup (id); + action->label = g_strdup (label); + action->parameter_type = parameter_type ? g_variant_type_copy (parameter_type) : NULL; + action->parameter_hint = parameter_hint ? g_variant_ref_sink (parameter_hint) : NULL; + + msg->actions = g_slist_append (msg->actions, action); +} + +static GVariant * +action_to_variant (Action *action) +{ + GVariantBuilder builder; + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ssgav)")); + + g_variant_builder_add (&builder, "s", action->id); + g_variant_builder_add (&builder, "s", action->label ? action->label : ""); + + if (action->parameter_type) + { + gchar *type = g_variant_type_dup_string (action->parameter_type); + g_variant_builder_add (&builder, "g", type); + g_free (type); + } + else + g_variant_builder_add (&builder, "g", ""); + + g_variant_builder_open (&builder, G_VARIANT_TYPE ("av")); + if (action->parameter_hint) + g_variant_builder_add (&builder, "v", action->parameter_hint); + g_variant_builder_close (&builder); + + return g_variant_builder_end (&builder); +} + +/* + * messaging_menu_message_to_variant: + * @msg: a #MessagingMenuMessage + * + * Serializes @msg to a #GVariant of the form (sssssxa(ssgav)b): + * + * id + * icon + * title + * subtitle + * body + * time + * array of actions: id + * label + * parameter_type + * parameter_hint (0 or 1 elements) + * draws_attention + * + * Returns: a new floating #GVariant instance + */ +GVariant * +messaging_menu_message_to_variant (MessagingMenuMessage *msg) +{ + GVariantBuilder builder; + GSList *it; + + g_return_val_if_fail (MESSAGING_MENU_IS_MESSAGE (msg), NULL); + + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(sssssxa(ssgav)b)")); + + g_variant_builder_add (&builder, "s", msg->id); + + if (msg->icon) + { + gchar *iconstr; + + iconstr = g_icon_to_string (msg->icon); + g_variant_builder_add (&builder, "s", iconstr); + + g_free (iconstr); + } + else + g_variant_builder_add (&builder, "s", ""); + + g_variant_builder_add (&builder, "s", msg->title ? msg->title : ""); + g_variant_builder_add (&builder, "s", msg->subtitle ? msg->subtitle : ""); + g_variant_builder_add (&builder, "s", msg->body ? msg->body : ""); + g_variant_builder_add (&builder, "x", msg->time); + + g_variant_builder_open (&builder, G_VARIANT_TYPE ("a(ssgav)")); + for (it = msg->actions; it; it = it->next) + g_variant_builder_add_value (&builder, action_to_variant (it->data)); + g_variant_builder_close (&builder); + + g_variant_builder_add (&builder, "b", msg->draws_attention); + + return g_variant_builder_end (&builder); +} diff --git a/libmessaging-menu/messaging-menu-message.h b/libmessaging-menu/messaging-menu-message.h index 068247b..4708246 100644 --- a/libmessaging-menu/messaging-menu-message.h +++ b/libmessaging-menu/messaging-menu-message.h @@ -59,6 +59,12 @@ gboolean messaging_menu_message_get_draws_attention (MessagingMe void messaging_menu_message_set_draws_attention (MessagingMenuMessage *msg, gboolean draws_attention); +void messaging_menu_message_add_action (MessagingMenuMessage *msg, + const gchar *id, + const gchar *label, + const GVariantType *parameter_type, + GVariant *parameter_hint); + G_END_DECLS #endif -- cgit v1.2.3