aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Uebernickel <lars.uebernickel@canonical.com>2012-11-15 14:00:14 +0100
committerLars Uebernickel <lars.uebernickel@canonical.com>2012-11-15 14:00:14 +0100
commita44f4a7f0d1918809452da175c5b0585ecd6d951 (patch)
treed29334fb80a5fe29ac319771a2f7d856359b5ce2
parente60843df6c318ba7281067d11744e182ff739c72 (diff)
downloadayatana-indicator-messages-a44f4a7f0d1918809452da175c5b0585ecd6d951.tar.gz
ayatana-indicator-messages-a44f4a7f0d1918809452da175c5b0585ecd6d951.tar.bz2
ayatana-indicator-messages-a44f4a7f0d1918809452da175c5b0585ecd6d951.zip
Add support for individual messages to MessagingMenuApp
This is not exposed in the indicator menu yet.
-rw-r--r--common/com.canonical.indicator.messages.application.xml12
-rw-r--r--libmessaging-menu/messaging-menu-app.c144
-rw-r--r--libmessaging-menu/messaging-menu-message.c2
3 files changed, 152 insertions, 6 deletions
diff --git a/common/com.canonical.indicator.messages.application.xml b/common/com.canonical.indicator.messages.application.xml
index ec095dd..33aed7c 100644
--- a/common/com.canonical.indicator.messages.application.xml
+++ b/common/com.canonical.indicator.messages.application.xml
@@ -4,9 +4,15 @@
<method name="ListSources">
<arg type="a(sssuxsb)" name="sources" direction="out" />
</method>
+ <method name="ListMessages">
+ <arg type="a(sssssxb)" name="message" direction="out" />
+ </method>
<method name="ActivateSource">
<arg type="s" name="source_id" direction="in" />
</method>
+ <method name="ActivateMessage">
+ <arg type="s" name="message_id" direction="in" />
+ </method>
<signal name="SourceAdded">
<arg type="u" name="position" direction="in" />
<arg type="(sssuxsb)" name="source" direction="in" />
@@ -17,5 +23,11 @@
<signal name="SourceRemoved">
<arg type="s" name="source_id" direction="in" />
</signal>
+ <signal name="MessageAdded">
+ <arg type="(sssssxb)" name="message" direction="in" />
+ </signal>
+ <signal name="MessageRemoved">
+ <arg type="(sssssxb)" name="message" direction="in" />
+ </signal>
</interface>
</node>
diff --git a/libmessaging-menu/messaging-menu-app.c b/libmessaging-menu/messaging-menu-app.c
index d793d6b..bc7e978 100644
--- a/libmessaging-menu/messaging-menu-app.c
+++ b/libmessaging-menu/messaging-menu-app.c
@@ -106,6 +106,7 @@ struct _MessagingMenuApp
gboolean status_set;
GDBusConnection *bus;
+ GHashTable *messages;
GList *sources;
IndicatorMessagesApplication *app_interface;
@@ -125,6 +126,7 @@ enum {
enum {
ACTIVATE_SOURCE,
+ ACTIVATE_MESSAGE,
STATUS_CHANGED,
N_SIGNALS
};
@@ -186,6 +188,29 @@ 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)
{
@@ -304,7 +329,10 @@ messaging_menu_app_dispose (GObject *object)
g_clear_object (&app->messages_service);
}
+ g_clear_pointer (&app->messages, g_hash_table_unref);
+
g_list_free_full (app->sources, source_free);
+ app->sources = NULL;
g_clear_object (&app->app_interface);
g_clear_object (&app->appinfo);
@@ -358,6 +386,27 @@ messaging_menu_app_class_init (MessagingMenuAppClass *class)
G_TYPE_NONE, 1, G_TYPE_STRING);
/**
+ * MessagingMenuApp::activate-message:
+ * @mmapp: the #MessagingMenuApp
+ * @message: the activated #MessagingMenuMessage
+ *
+ * Emitted when the user has activated a message. The message is
+ * immediately removed from the application's menu, handlers of this
+ * signal do not need to call messaging_menu_app_remove_message().
+ *
+ * To get notified about the activation of a specific message, set the
+ * signal's detail to the message id.
+ */
+ signals[ACTIVATE_MESSAGE] = g_signal_new ("activate-message",
+ MESSAGING_MENU_TYPE_APP,
+ G_SIGNAL_RUN_FIRST |
+ G_SIGNAL_DETAILED,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, MESSAGING_MENU_TYPE_MESSAGE);
+
+ /**
* MessagingMenuApp::status-changed:
* @mmapp: the #MessagingMenuApp
* @status: a #MessagingMenuStatus
@@ -488,6 +537,13 @@ messaging_menu_app_remove_source_internal (MessagingMenuApp *app,
}
static gboolean
+messaging_menu_app_remove_message_internal (MessagingMenuApp *app,
+ const gchar *message_id)
+{
+ return g_hash_table_remove (app->messages, message_id);
+}
+
+static gboolean
messaging_menu_app_activate_source (IndicatorMessagesApplication *app_interface,
GDBusMethodInvocation *invocation,
const gchar *source_id,
@@ -496,7 +552,7 @@ messaging_menu_app_activate_source (IndicatorMessagesApplication *app_interface,
MessagingMenuApp *app = user_data;
GQuark q = g_quark_from_string (source_id);
- /* Activate implies removing the source, no need for SourcesChanged */
+ /* Activate implies removing the source, no need for SourceRemoved */
if (messaging_menu_app_remove_source_internal (app, source_id))
g_signal_emit (app, signals[ACTIVATE_SOURCE], q, source_id);
@@ -505,6 +561,52 @@ messaging_menu_app_activate_source (IndicatorMessagesApplication *app_interface,
return TRUE;
}
+static gboolean
+messaging_menu_app_list_messages (IndicatorMessagesApplication *app_interface,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ MessagingMenuApp *app = user_data;
+ GVariantBuilder builder;
+ GHashTableIter iter;
+ MessagingMenuMessage *message;
+
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(sssssxb)"));
+
+ g_hash_table_iter_init (&iter, app->messages);
+ while (g_hash_table_iter_next (&iter, NULL, (gpointer *) &message))
+ g_variant_builder_add_value (&builder, messaging_menu_message_to_variant (message));
+
+ indicator_messages_application_complete_list_messages (app_interface,
+ invocation,
+ g_variant_builder_end (&builder));
+
+ return TRUE;
+}
+
+static gboolean
+messaging_menu_app_activate_message (IndicatorMessagesApplication *app_interface,
+ GDBusMethodInvocation *invocation,
+ const gchar *message_id,
+ gpointer user_data)
+{
+ MessagingMenuApp *app = user_data;
+ MessagingMenuMessage *msg;
+
+ msg = g_hash_table_lookup (app->messages, message_id);
+ if (msg)
+ {
+ g_signal_emit (app, signals[ACTIVATE_MESSAGE], g_quark_from_string (message_id), msg);
+
+ /* Activate implies removing the message, no need for MessageRemoved */
+ messaging_menu_app_remove_message_internal (app, message_id);
+ }
+
+ indicator_messages_application_complete_activate_message (app_interface, invocation);
+
+ return TRUE;
+}
+
static void
messaging_menu_app_init (MessagingMenuApp *app)
{
@@ -519,8 +621,12 @@ messaging_menu_app_init (MessagingMenuApp *app)
G_CALLBACK (messaging_menu_app_list_sources), app);
g_signal_connect (app->app_interface, "handle-activate-source",
G_CALLBACK (messaging_menu_app_activate_source), app);
+ g_signal_connect (app->app_interface, "handle-list-messages",
+ G_CALLBACK (messaging_menu_app_list_messages), app);
+ g_signal_connect (app->app_interface, "handle-activate-message",
+ G_CALLBACK (messaging_menu_app_activate_message), app);
- app->cancellable = g_cancellable_new ();
+ app->messages = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
app->watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
"com.canonical.indicator.messages",
@@ -1226,8 +1332,34 @@ messaging_menu_app_append_message (MessagingMenuApp *app,
const gchar *source_id,
gboolean notify)
{
+ const gchar *id;
+
g_return_if_fail (MESSAGING_MENU_IS_APP (app));
- g_return_if_fail (MESSAGING_MENU_IS_MESSAGE (app));
+ g_return_if_fail (MESSAGING_MENU_IS_MESSAGE (msg));
+
+ id = messaging_menu_message_get_id (msg);
+
+ if (g_hash_table_lookup (app->messages, id))
+ {
+ g_warning ("a message with id '%s' already exists", id);
+ return;
+ }
+
+ g_hash_table_insert (app->messages, g_strdup (id), g_object_ref (msg));
+ indicator_messages_application_emit_message_added (app->app_interface,
+ messaging_menu_message_to_variant (msg));
+
+ if (source_id)
+ {
+ Source *source;
+
+ source = messaging_menu_app_get_source (app, source_id);
+ if (source && source->count >= 0)
+ {
+ source->count++;
+ messaging_menu_app_notify_source_changed (app, source);
+ }
+ }
}
/**
@@ -1244,8 +1376,7 @@ void
messaging_menu_app_remove_message (MessagingMenuApp *app,
MessagingMenuMessage *msg)
{
- g_return_if_fail (MESSAGING_MENU_IS_APP (app));
- g_return_if_fail (MESSAGING_MENU_IS_MESSAGE (app));
+ messaging_menu_app_remove_message_by_id (app, messaging_menu_message_get_id (msg));
}
/**
@@ -1264,4 +1395,7 @@ messaging_menu_app_remove_message_by_id (MessagingMenuApp *app,
{
g_return_if_fail (MESSAGING_MENU_IS_APP (app));
g_return_if_fail (id != NULL);
+
+ if (messaging_menu_app_remove_message_internal (app, id))
+ indicator_messages_application_emit_source_removed (app->app_interface, id);
}
diff --git a/libmessaging-menu/messaging-menu-message.c b/libmessaging-menu/messaging-menu-message.c
index 631786a..f5cb18c 100644
--- a/libmessaging-menu/messaging-menu-message.c
+++ b/libmessaging-menu/messaging-menu-message.c
@@ -225,7 +225,7 @@ messaging_menu_message_init (MessagingMenuMessage *self)
/**
* messaging_menu_message_new:
* @id: unique id of the message
- * @icon: (transfer full): a #GIcon representing the message
+ * @icon: (transfer full) (allow-none): a #GIcon representing the message
* @title: the title of the message
* @subtitle: (allow-none): the subtitle of the message
* @body: (allow-none): the message body