diff options
author | Lars Uebernickel <lars.uebernickel@canonical.com> | 2012-11-27 15:14:26 +0100 |
---|---|---|
committer | Lars Uebernickel <lars.uebernickel@canonical.com> | 2012-11-27 15:14:26 +0100 |
commit | e8e99703ef0c565f07a9d1eba03c1003d82ff697 (patch) | |
tree | 465e749b6a501187c25981c103125bf7abdaa32f | |
parent | c9ddfbead428ec96459cd80b57aba6ad6ed0492a (diff) | |
download | ayatana-indicator-messages-e8e99703ef0c565f07a9d1eba03c1003d82ff697.tar.gz ayatana-indicator-messages-e8e99703ef0c565f07a9d1eba03c1003d82ff697.tar.bz2 ayatana-indicator-messages-e8e99703ef0c565f07a9d1eba03c1003d82ff697.zip |
Allow adding actions to MessagingMenuMessage
-rw-r--r-- | common/com.canonical.indicator.messages.application.xml | 4 | ||||
-rw-r--r-- | libmessaging-menu/messaging-menu-app.c | 28 | ||||
-rw-r--r-- | libmessaging-menu/messaging-menu-message.c | 160 | ||||
-rw-r--r-- | libmessaging-menu/messaging-menu-message.h | 6 | ||||
-rw-r--r-- | src/im-application-list.c | 6 |
5 files changed, 176 insertions, 28 deletions
diff --git a/common/com.canonical.indicator.messages.application.xml b/common/com.canonical.indicator.messages.application.xml index 552b6a4..f37cd25 100644 --- a/common/com.canonical.indicator.messages.application.xml +++ b/common/com.canonical.indicator.messages.application.xml @@ -5,7 +5,7 @@ <arg type="a(sssuxsb)" name="sources" direction="out" /> </method> <method name="ListMessages"> - <arg type="a(sssssxb)" name="message" direction="out" /> + <arg type="a(sssssxa(ssgav)b)" name="message" direction="out" /> </method> <method name="ActivateSource"> <arg type="s" name="source_id" direction="in" /> @@ -28,7 +28,7 @@ <arg type="s" name="source_id" direction="in" /> </signal> <signal name="MessageAdded"> - <arg type="(sssssxb)" name="message" direction="in" /> + <arg type="(sssssxa(ssgav)b)" name="message" direction="in" /> </signal> <signal name="MessageRemoved"> <arg type="s" name="message_id" direction="in" /> 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); +} + +/*<internal> + * 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 diff --git a/src/im-application-list.c b/src/im-application-list.c index d766f24..4eaaed0 100644 --- a/src/im-application-list.c +++ b/src/im-application-list.c @@ -509,13 +509,14 @@ im_application_list_message_added (Application *app, const gchar *subtitle; const gchar *body; gint64 time; + GVariantIter *action_iter; gboolean draws_attention; GSimpleAction *action; GIcon *app_icon; gchar *app_iconstr; - g_variant_get (message, "(&s&s&s&s&sxb)", - &id, &iconstr, &title, &subtitle, &body, &time, &draws_attention); + g_variant_get (message, "(&s&s&s&s&sxa(ssgav)b)", + &id, &iconstr, &title, &subtitle, &body, &time, &action_iter, &draws_attention); app_icon = g_app_info_get_icon (G_APP_INFO (app->info)); app_iconstr = app_icon ? g_icon_to_string (app_icon) : NULL; @@ -528,6 +529,7 @@ im_application_list_message_added (Application *app, g_signal_emit (app->list, signals[MESSAGE_ADDED], 0, app->id, app_iconstr, id, iconstr, title, subtitle, body, time, draws_attention); + g_variant_iter_free (action_iter); g_free (app_iconstr); g_object_unref (action); } |